Merge "Update to latest catapult (6171fd4d)"
diff --git a/Android.mk b/Android.mk
new file mode 100644
index 0000000..d318e53
--- /dev/null
+++ b/Android.mk
@@ -0,0 +1,2 @@
+# This empty Android.mk prevents ./catapult/systrace/atrace_helper
+# from being built by default
diff --git a/UPSTREAM_REVISION b/UPSTREAM_REVISION
index 43123c5..d19651e 100644
--- a/UPSTREAM_REVISION
+++ b/UPSTREAM_REVISION
@@ -1 +1 @@
-c69b78719398903e6916f572bd7383afbbb2cdb9
+6171fd4dd88d738437b803fbf5374be6bf9c5342
diff --git a/catapult/common/OWNERS b/catapult/common/OWNERS
deleted file mode 100644
index 6720479..0000000
--- a/catapult/common/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-dtu@chromium.org
-eakuefner@chromium.org
-fmeawad@chromium.org
-simonhatch@chromium.org
-sullivan@chromium.org
diff --git a/catapult/common/battor/OWNERS b/catapult/common/battor/OWNERS
deleted file mode 100644
index 7638118..0000000
--- a/catapult/common/battor/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-charliea@chromium.org
-rnephew@chromium.org
diff --git a/catapult/common/battor/battor/__init__.py b/catapult/common/battor/battor/__init__.py
index 866a3d4..f18f330 100644
--- a/catapult/common/battor/battor/__init__.py
+++ b/catapult/common/battor/battor/__init__.py
@@ -24,4 +24,4 @@
 _AddDirToPythonPath(_CATAPULT_DIR, 'common', 'py_utils')
 _AddDirToPythonPath(_CATAPULT_DIR, 'dependency_manager')
 _AddDirToPythonPath(_CATAPULT_DIR, 'devil')
-_AddDirToPythonPath(_CATAPULT_DIR, 'telemetry', 'third_party', 'pyserial')
+_AddDirToPythonPath(_CATAPULT_DIR, 'third_party', 'pyserial')
diff --git a/catapult/common/battor/battor/battor_binary_dependencies.json b/catapult/common/battor/battor/battor_binary_dependencies.json
index a47d7ec..58c203e 100644
--- a/catapult/common/battor/battor/battor_binary_dependencies.json
+++ b/catapult/common/battor/battor/battor_binary_dependencies.json
@@ -60,35 +60,35 @@
       "cloud_storage_bucket": "chromium-telemetry",
       "file_info": {
         "darwin_x86_64": {
-          "cloud_storage_hash": "ea35fa0b56cf1e2e774218498b244be167c2d61c",
+          "cloud_storage_hash": "276b3507a1c617c01734d85a2133ed200f2a477b",
           "download_path": "../bin/darwin/x86_64/battor_agent",
           "local_paths": [
             "../bin/override/battor_agent"
           ]
         },
         "linux2_x86_64": {
-          "cloud_storage_hash": "7280345d3c31e1185c03492082a98b2eb4dccaae",
+          "cloud_storage_hash": "582cfe85971ca84aa75cf078bafb737d0cbdfb31",
           "download_path": "../bin/linux2/x86_64/battor_agent",
           "local_paths": [
             "../bin/override/battor_agent"
           ]
         },
         "win32_AMD64": {
-          "cloud_storage_hash": "e1b3630f94bbacb58b2d254543ee94073f072dc0",
+          "cloud_storage_hash": "609c5f79a03b347ddbfd6e544d229a56851c0f66",
           "download_path": "../bin/win/AMD64/battor_agent.exe",
           "local_paths": [
             "../bin/override/battor_agent.exe"
           ]
         },
         "win32_x86": {
-          "cloud_storage_hash": "e1b3630f94bbacb58b2d254543ee94073f072dc0",
+          "cloud_storage_hash": "609c5f79a03b347ddbfd6e544d229a56851c0f66",
           "download_path": "../bin/win/x86_64/battor_agent.exe",
           "local_paths": [
             "../bin/override/battor_agent.exe"
           ]
         },
         "win_AMD64": {
-          "cloud_storage_hash": "e1b3630f94bbacb58b2d254543ee94073f072dc0",
+          "cloud_storage_hash": "609c5f79a03b347ddbfd6e544d229a56851c0f66",
           "download_path": "../bin/win/AMD64/battor_agent.exe",
           "local_paths": [
             "../bin/override/battor_agent.exe"
diff --git a/catapult/common/battor/battor/battor_wrapper.py b/catapult/common/battor/battor/battor_wrapper.py
index 88b258a..6947f83 100644
--- a/catapult/common/battor/battor/battor_wrapper.py
+++ b/catapult/common/battor/battor/battor_wrapper.py
@@ -37,6 +37,12 @@
 
     if not android_device_map:
       device_tree = find_usb_devices.GetBusNumberToDeviceTreeMap()
+      if device_tree:
+        logging.warning('Device tree:')
+        for _, node in sorted(device_tree.iteritems()):
+          node.Display()
+      else:
+        logging.warning('Empty device tree.')
       if len(battor_device_mapping.GetBattOrList(device_tree)) == 1:
         return True
       if android_device_file:
@@ -45,7 +51,9 @@
       else:
         try:
           android_device_map = battor_device_mapping.GenerateSerialMap()
+          logging.warning('Android device map: %s', android_device_map)
         except battor_error.BattOrError:
+          logging.exception('Error generating serial map')
           return False
 
     # If neither if statement above is triggered, it means that an
@@ -83,7 +91,6 @@
   _RECORD_CLOCKSYNC_CMD = 'RecordClockSyncMarker'
   _SUPPORTED_PLATFORMS = ['android', 'chromeos', 'linux', 'mac', 'win']
 
-  _SUPPORTED_AUTOFLASHING_PLATFORMS = ['linux', 'mac', 'win']
   _BATTOR_PARTNO = 'x192a3u'
   _BATTOR_PROGRAMMER = 'avr109'
   _BATTOR_BAUDRATE = '115200'
@@ -241,6 +248,7 @@
     # The BattOr shell terminates after returning the results.
     if timeout is None:
       timeout = self._stop_tracing_time - self._start_tracing_time
+    py_utils.WaitFor(lambda: self.GetShellReturnCode() != None, timeout)
 
     # TODO(charliea): Once we understand why BattOrs are crashing, only do
     # this on failure.
@@ -379,9 +387,6 @@
        firmware at hex_path.
     """
     assert not self._battor_shell, 'Cannot flash BattOr with open shell'
-    if self._target_platform not in self._SUPPORTED_AUTOFLASHING_PLATFORMS:
-      logging.critical('Flashing firmware on this platform is not supported.')
-      return False
 
     avrdude_binary = self._dm.FetchPath(
         'avrdude_binary', '%s_%s' % (sys.platform, platform.machine()))
diff --git a/catapult/common/battor/battor/battor_wrapper_devicetest.py b/catapult/common/battor/battor/battor_wrapper_devicetest.py
index 9823787..4ca59a7 100644
--- a/catapult/common/battor/battor/battor_wrapper_devicetest.py
+++ b/catapult/common/battor/battor/battor_wrapper_devicetest.py
@@ -16,6 +16,7 @@
 from battor import battor_wrapper
 from devil.utils import battor_device_mapping
 from devil.utils import find_usb_devices
+from py_utils import cloud_storage
 
 
 _SUPPORTED_CQ_PLATFORMS = ['win', 'linux', 'mac']
@@ -49,8 +50,9 @@
 
     battor_path = (None if not self._battor_list
                    else '/dev/%s' % self._battor_list[0])
-    battor = battor_wrapper.BattOrWrapper(self._platform,
-                                          battor_path=battor_path)
+    battor = battor_wrapper.BattOrWrapper(
+        self._platform, battor_path=battor_path,
+        serial_log_bucket=cloud_storage.TELEMETRY_OUTPUT)
     try:
       battor.StartShell()
       self.assertTrue(isinstance(battor.GetFirmwareGitHash(), basestring))
diff --git a/catapult/common/battor/battor/battor_wrapper_unittest.py b/catapult/common/battor/battor/battor_wrapper_unittest.py
index 862c4d3..3e48a33 100644
--- a/catapult/common/battor/battor/battor_wrapper_unittest.py
+++ b/catapult/common/battor/battor/battor_wrapper_unittest.py
@@ -61,7 +61,7 @@
 
     self._get_bus_number_to_device_tree_map = (
         find_usb_devices.GetBusNumberToDeviceTreeMap)
-    find_usb_devices.GetBusNumberToDeviceTreeMap = lambda fast=None: None
+    find_usb_devices.GetBusNumberToDeviceTreeMap = lambda fast=None: {}
 
     self._get_battor_list_return = []
     self._get_battor_list = battor_device_mapping.GetBattOrList
@@ -299,12 +299,6 @@
     with self.assertRaises(battor_wrapper.BattOrFlashError):
       self._battor.FlashFirmware('hex_path', 'config_path')
 
-  def testFlashFirmwarePlatformNotSupported(self):
-    self._battor = battor_wrapper.BattOrWrapper('win')
-    self._DefaultBattOrReplacements()
-    self._battor._target_platform = 'unsupported_platform'
-    self.assertFalse(self._battor.FlashFirmware('hex_path', 'config_path'))
-
   def testFlashFirmwareShellRunning(self):
     self._battor = battor_wrapper.BattOrWrapper('linux')
     self._DefaultBattOrReplacements()
diff --git a/catapult/common/eslint/OWNERS b/catapult/common/eslint/OWNERS
deleted file mode 100644
index 137ed40..0000000
--- a/catapult/common/eslint/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-charliea@chromium.org
-eakuefner@chromium.org
\ No newline at end of file
diff --git a/catapult/common/py_trace_event/py_trace_event/__init__.py b/catapult/common/py_trace_event/py_trace_event/__init__.py
index 637b7c9..b8b6630 100644
--- a/catapult/common/py_trace_event/py_trace_event/__init__.py
+++ b/catapult/common/py_trace_event/py_trace_event/__init__.py
@@ -1,7 +1,9 @@
 # Copyright 2016 The Chromium Authors. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
+import os
 import sys
 
-
-sys.path.append('../../../py_utils')
+SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
+PY_UTILS = os.path.abspath(os.path.join(SCRIPT_DIR, '..', '..', 'py_utils'))
+sys.path.append(PY_UTILS)
diff --git a/catapult/common/py_trace_event/py_trace_event/trace_time.py b/catapult/common/py_trace_event/py_trace_event/trace_time.py
index 1d96242..c5e3fe1 100644
--- a/catapult/common/py_trace_event/py_trace_event/trace_time.py
+++ b/catapult/common/py_trace_event/py_trace_event/trace_time.py
@@ -125,6 +125,8 @@
   info = platform.processor()
   if 'AuthenticAMD' in info and 'Family 15' in info:
     return False
+  if not hasattr(ctypes, 'windll'):
+    return False
   try:  # If anything goes wrong during this, assume QPC isn't available.
     frequency = ctypes.c_int64()
     ctypes.windll.Kernel32.QueryPerformanceFrequency(
diff --git a/catapult/common/py_utils/py_utils/shell_util.py b/catapult/common/py_utils/py_utils/shell_util.py
new file mode 100644
index 0000000..2a529c8
--- /dev/null
+++ b/catapult/common/py_utils/py_utils/shell_util.py
@@ -0,0 +1,40 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Shell scripting helpers (created for Telemetry dependency roll scripts).
+
+import os as _os
+import shutil as _shutil
+import subprocess as _subprocess
+import tempfile as _tempfile
+from contextlib import contextmanager as _contextmanager
+
+@_contextmanager
+def ScopedChangeDir(new_path):
+  old_path = _os.getcwd()
+  _os.chdir(new_path)
+  print '> cd', _os.getcwd()
+  try:
+    yield
+  finally:
+    _os.chdir(old_path)
+    print '> cd', old_path
+
+@_contextmanager
+def ScopedTempDir():
+  temp_dir = _tempfile.mkdtemp()
+  try:
+    with ScopedChangeDir(temp_dir):
+      yield
+  finally:
+    _shutil.rmtree(temp_dir)
+
+def CallProgram(path_parts, *args, **kwargs):
+  '''Call an executable os.path.join(*path_parts) with the arguments specified
+  by *args. Any keyword arguments are passed as environment variables.'''
+  args = [_os.path.join(*path_parts)] + list(args)
+  env = dict(_os.environ)
+  env.update(kwargs)
+  print '>', ' '.join(args)
+  _subprocess.check_call(args, env=env)
diff --git a/catapult/dependency_manager/OWNERS b/catapult/dependency_manager/OWNERS
deleted file mode 100644
index ca5ce3b..0000000
--- a/catapult/dependency_manager/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-aiolos@chromium.org
diff --git a/catapult/dependency_manager/dependency_manager/OWNERS b/catapult/dependency_manager/dependency_manager/OWNERS
deleted file mode 100644
index ca5ce3b..0000000
--- a/catapult/dependency_manager/dependency_manager/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-aiolos@chromium.org
diff --git a/catapult/dependency_manager/dependency_manager/__init__.py b/catapult/dependency_manager/dependency_manager/__init__.py
index 296eb04..68efbdb 100644
--- a/catapult/dependency_manager/dependency_manager/__init__.py
+++ b/catapult/dependency_manager/dependency_manager/__init__.py
@@ -21,6 +21,7 @@
 _AddDirToPythonPath(CATAPULT_PATH, 'common', 'py_utils')
 _AddDirToPythonPath(CATAPULT_THIRD_PARTY_PATH, 'mock')
 _AddDirToPythonPath(CATAPULT_THIRD_PARTY_PATH, 'pyfakefs')
+_AddDirToPythonPath(CATAPULT_THIRD_PARTY_PATH, 'zipfile')
 _AddDirToPythonPath(DEPENDENCY_MANAGER_PATH)
 
 
diff --git a/catapult/dependency_manager/dependency_manager/archive_info.py b/catapult/dependency_manager/dependency_manager/archive_info.py
index 637e7cc..ff13f90 100644
--- a/catapult/dependency_manager/dependency_manager/archive_info.py
+++ b/catapult/dependency_manager/dependency_manager/archive_info.py
@@ -2,7 +2,9 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import glob
 import os
+import shutil
 
 from dependency_manager import exceptions
 from dependency_manager import dependency_manager_util
@@ -10,7 +12,8 @@
 
 class ArchiveInfo(object):
 
-  def __init__(self, archive_file, unzip_path, path_within_archive):
+  def __init__(self, archive_file, unzip_path, path_within_archive,
+               stale_unzip_path_glob=None):
     """ Container for the information needed to unzip a downloaded archive.
 
     Args:
@@ -25,12 +28,16 @@
                 file_path: Unzip the file downloaded from cloud_storage.
                     |file_path| is the path to the expected dependency,
                     relative to the unzipped archive path.
+        stale_unzip_path_glob: Optional argument specifying a glob matching
+            string which matches directories that should be removed before this
+            archive is extracted (if it is extracted at all).
     """
     self._archive_file = archive_file
     self._unzip_path = unzip_path
     self._path_within_archive = path_within_archive
     self._dependency_path = os.path.join(
         self._unzip_path, self._path_within_archive)
+    self._stale_unzip_path_glob = stale_unzip_path_glob
     if not self._has_minimum_data:
       raise ValueError(
           'Not enough information specified to initialize an archive info.'
@@ -38,6 +45,10 @@
 
   def GetUnzippedPath(self):
     if self.ShouldUnzipArchive():
+      # Remove stale unzip results
+      if self._stale_unzip_path_glob:
+        for path in glob.glob(self._stale_unzip_path_glob):
+          shutil.rmtree(path)
       # TODO(aiolos): Replace UnzipFile with zipfile.extractall once python
       # version 2.7.4 or later can safely be assumed.
       dependency_manager_util.UnzipArchive(
diff --git a/catapult/dependency_manager/dependency_manager/base_config.py b/catapult/dependency_manager/dependency_manager/base_config.py
index 840ddf8..c735688 100644
--- a/catapult/dependency_manager/dependency_manager/base_config.py
+++ b/catapult/dependency_manager/dependency_manager/base_config.py
@@ -165,8 +165,13 @@
             unzip_path = os.path.abspath(
                 os.path.join(os.path.dirname(download_path),
                              '%s_%s_%s' % (dependency, platform, cs_hash)))
+            stale_unzip_path_glob = os.path.abspath(
+                os.path.join(os.path.dirname(download_path),
+                             '%s_%s_%s' % (dependency, platform,
+                                           '[0-9a-f]' * 40)))
             zip_info = archive_info.ArchiveInfo(
-                download_path, unzip_path, path_within_archive)
+                download_path, unzip_path, path_within_archive,
+                stale_unzip_path_glob)
 
           cs_info = cloud_storage_info.CloudStorageInfo(
               cs_bucket, cs_hash, download_path, cs_remote_path,
diff --git a/catapult/dependency_manager/dependency_manager/base_config_unittest.py b/catapult/dependency_manager/dependency_manager/base_config_unittest.py
index 2cffbd8..0dc775b 100755
--- a/catapult/dependency_manager/dependency_manager/base_config_unittest.py
+++ b/catapult/dependency_manager/dependency_manager/base_config_unittest.py
@@ -11,6 +11,7 @@
 import mock
 from pyfakefs import fake_filesystem_unittest
 from pyfakefs import fake_filesystem
+from pyfakefs import fake_filesystem_glob
 
 import dependency_manager
 from dependency_manager import uploader
@@ -1383,7 +1384,7 @@
                     'download_path': 'download_path111',
                     'cs_remote_path': 'cs_path111',
                     'version_in_cs': 'version_111',
-                    'path_in_archive': 'path/in/archive',
+                    'path_within_archive': 'path/within/archive',
                     'local_paths': ['local_path1110', 'local_path1111']
                 }
             }
@@ -1486,3 +1487,39 @@
       deps_seen.append(dep_info)
     dep_info_mock.assert_call_args(expected_calls)
     self.assertItemsEqual(expected_dep_info, deps_seen)
+
+  @mock.patch('dependency_manager.base_config.json')
+  @mock.patch('os.path.exists')
+  @mock.patch('__builtin__.open')
+  def testIterDependenciesStaleGlob(self, open_mock, exists_mock, json_mock):
+    json_mock.load.return_value = self.one_dep_dict
+    config = self.config_class('file_path')
+
+    abspath = os.path.abspath
+    should_match = set(map(abspath, [
+        'dep_all_the_variables_0123456789abcdef0123456789abcdef01234567',
+        'dep_all_the_variables_123456789abcdef0123456789abcdef012345678']))
+    # Not testing case changes, because Windows is case-insensitive.
+    should_not_match = set(map(abspath, [
+        # A configuration that doesn't unzip shouldn't clear any stale unzips.
+        'dep_plat1_arch1_0123456789abcdef0123456789abcdef01234567',
+        # "Hash" component less than 40 characters (not a valid SHA1 hash).
+        'dep_all_the_variables_0123456789abcdef0123456789abcdef0123456',
+        # "Hash" component greater than 40 characters (not a valid SHA1 hash).
+        'dep_all_the_variables_0123456789abcdef0123456789abcdef012345678',
+        # "Hash" component not comprised of hex (not a valid SHA1 hash).
+        'dep_all_the_variables_0123456789gggggg0123456789gggggg01234567']))
+
+    # Create a fake filesystem just for glob to use
+    fake_fs = fake_filesystem.FakeFilesystem()
+    fake_glob = fake_filesystem_glob.FakeGlobModule(fake_fs)
+    for stale_dir in set.union(should_match, should_not_match):
+      fake_fs.CreateDirectory(stale_dir)
+      fake_fs.CreateFile(os.path.join(stale_dir, 'some_file'))
+
+    for dep_info in config.IterDependencyInfo():
+      if dep_info.platform == 'all_the_variables':
+        cs_info = dep_info.cloud_storage_info
+        actual_glob = cs_info._archive_info._stale_unzip_path_glob
+        actual_matches = set(fake_glob.glob(actual_glob))
+        self.assertItemsEqual(should_match, actual_matches)
diff --git a/catapult/dependency_manager/dependency_manager/cloud_storage_info_unittest.py b/catapult/dependency_manager/dependency_manager/cloud_storage_info_unittest.py
index be44fc1..699cd50 100644
--- a/catapult/dependency_manager/dependency_manager/cloud_storage_info_unittest.py
+++ b/catapult/dependency_manager/dependency_manager/cloud_storage_info_unittest.py
@@ -170,9 +170,18 @@
       self.fs.CreateFile(os.path.join(unzip_location, 'another_extra_path'))
     unzip_mock.side_effect = _UnzipFileMock
 
+    # Create a stale directory that's expected to get deleted
+    stale_unzip_path_glob = os.path.join(
+        os.path.dirname(self.download_path), 'unzip_dir_*')
+    stale_path = os.path.join(
+        os.path.dirname(self.download_path), 'unzip_dir_stale')
+    self.fs.CreateDirectory(stale_path)
+    self.fs.CreateFile(os.path.join(stale_path, 'some_file'))
+
     self.assertFalse(os.path.exists(dep_path))
     zip_info = archive_info.ArchiveInfo(
-        self.download_path, unzip_path, path_within_archive)
+        self.download_path, unzip_path, path_within_archive,
+        stale_unzip_path_glob)
     self.cs_info = cloud_storage_info.CloudStorageInfo(
         'cs_bucket', 'cs_hash', self.download_path, 'cs_remote_path',
         version_in_cs='1.2.3.4', archive_info=zip_info)
@@ -186,6 +195,9 @@
                     (stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR))
     unzip_mock.assert_called_once_with(self.download_path, unzip_path)
 
+    # Stale directory should have been deleted
+    self.assertFalse(os.path.exists(stale_path))
+
     # Should not need to unzip a second time, but should return the same path.
     unzip_mock.reset_mock()
     self.assertTrue(os.path.exists(dep_path))
diff --git a/catapult/dependency_manager/dependency_manager/dependency_manager_util.py b/catapult/dependency_manager/dependency_manager/dependency_manager_util.py
index ed65db7..7ec2ec6 100644
--- a/catapult/dependency_manager/dependency_manager/dependency_manager_util.py
+++ b/catapult/dependency_manager/dependency_manager/dependency_manager_util.py
@@ -6,7 +6,7 @@
 import shutil
 import stat
 import sys
-import zipfile
+import zipfile_2_7_13 as zipfile
 
 from dependency_manager import exceptions
 
diff --git a/catapult/devil/OWNERS b/catapult/devil/OWNERS
deleted file mode 100644
index fd584fc..0000000
--- a/catapult/devil/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbudorick@chromium.org
-mikecase@chromium.org
-perezju@chromium.org
-rnephew@chromium.org
diff --git a/catapult/devil/devil/OWNERS b/catapult/devil/devil/OWNERS
deleted file mode 100644
index fd584fc..0000000
--- a/catapult/devil/devil/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbudorick@chromium.org
-mikecase@chromium.org
-perezju@chromium.org
-rnephew@chromium.org
diff --git a/catapult/devil/devil/android/battery_utils.py b/catapult/devil/devil/android/battery_utils.py
index 3b225aa..068c187 100644
--- a/catapult/devil/devil/android/battery_utils.py
+++ b/catapult/devil/devil/android/battery_utils.py
@@ -140,6 +140,18 @@
     'voltage': '/sys/class/power_supply/max77843-fuelgauge/voltage_now',
     'current': '/sys/class/power_supply/max77843-charger/current_now',
   },
+  { # Cherry Mobile One
+    'name': ['W6210 (4560MMX_b fingerprint)'],
+    'enable_command': (
+        'echo "0 0" > /proc/mtk_battery_cmd/current_cmd && '
+        'dumpsys battery reset'),
+    'disable_command': (
+        'echo "0 1" > /proc/mtk_battery_cmd/current_cmd && '
+        'dumpsys battery set ac 0 && dumpsys battery set usb 0'),
+    'charge_counter': None,
+    'voltage': None,
+    'current': None,
+},
 ]
 
 # The list of useful dumpsys columns.
diff --git a/catapult/devil/devil/android/device_errors.py b/catapult/devil/devil/android/device_errors.py
index 568e497..57f3615 100644
--- a/catapult/devil/devil/android/device_errors.py
+++ b/catapult/devil/devil/android/device_errors.py
@@ -4,6 +4,22 @@
 
 """
 Exception classes raised by AdbWrapper and DeviceUtils.
+
+The class hierarchy for device exceptions is:
+
+    base_error.BaseError
+     +-- CommandFailedError
+     |    +-- AdbCommandFailedError
+     |    |    +-- AdbShellCommandFailedError
+     |    +-- FastbootCommandFailedError
+     |    +-- DeviceVersionError
+     |    +-- DeviceChargingError
+     +-- CommandTimeoutError
+     +-- DeviceUnreachableError
+     +-- NoDevicesError
+     +-- MultipleDevicesError
+     +-- NoAdbError
+
 """
 
 from devil import base_error
diff --git a/catapult/devil/devil/android/device_test_case.py b/catapult/devil/devil/android/device_test_case.py
index b995fa6..1148b54 100644
--- a/catapult/devil/devil/android/device_test_case.py
+++ b/catapult/devil/devil/android/device_test_case.py
@@ -22,7 +22,8 @@
       d.WaitUntilFullyBooted(timeout=5, retries=0)
       live_devices.append(str(d))
     except (device_errors.CommandFailedError,
-            device_errors.CommandTimeoutError):
+            device_errors.CommandTimeoutError,
+            device_errors.DeviceUnreachableError):
       pass
   with _devices_lock:
     _devices.update(set(live_devices))
@@ -51,4 +52,3 @@
     with _devices_lock:
       _devices.add(self.serial)
       _devices_condition.notify()
-
diff --git a/catapult/devil/devil/android/device_utils.py b/catapult/devil/devil/android/device_utils.py
index 7ba1b51..51f7194 100644
--- a/catapult/devil/devil/android/device_utils.py
+++ b/catapult/devil/devil/android/device_utils.py
@@ -39,7 +39,6 @@
 from devil.android import md5sum
 from devil.android.constants import chrome
 from devil.android.sdk import adb_wrapper
-from devil.android.sdk import gce_adb_wrapper
 from devil.android.sdk import intent
 from devil.android.sdk import keyevent
 from devil.android.sdk import split_select
@@ -131,7 +130,6 @@
     r'\s*mCurrentFocus.*Application (Error|Not Responding): (\S+)}')
 
 _GETPROP_RE = re.compile(r'\[(.*?)\]: \[(.*?)\]')
-_IPV4_ADDRESS_RE = re.compile(r'([0-9]{1,3}\.){3}[0-9]{1,3}\:[0-9]{4,5}')
 
 # Regex to parse the long (-l) output of 'ls' command, c.f.
 # https://github.com/landley/toybox/blob/master/toys/posix/ls.c#L446
@@ -254,18 +252,11 @@
   return ''.join(s for line in lines for s in (line, '\n'))
 
 
-def _IsGceInstance(serial):
-  return _IPV4_ADDRESS_RE.match(serial)
-
-
 def _CreateAdbWrapper(device):
-  if _IsGceInstance(str(device)):
-    return gce_adb_wrapper.GceAdbWrapper(str(device))
+  if isinstance(device, adb_wrapper.AdbWrapper):
+    return device
   else:
-    if isinstance(device, adb_wrapper.AdbWrapper):
-      return device
-    else:
-      return adb_wrapper.AdbWrapper(device)
+    return adb_wrapper.AdbWrapper(device)
 
 
 def _FormatPartialOutputError(output):
@@ -453,13 +444,27 @@
       CommandFailedError if root could not be enabled.
       CommandTimeoutError on timeout.
     """
-    if self.IsUserBuild():
-      raise device_errors.CommandFailedError(
-          'Cannot enable root in user builds.', str(self))
     if 'needs_su' in self._cache:
       del self._cache['needs_su']
-    self.adb.Root()
-    self.WaitUntilFullyBooted()
+
+    try:
+      self.adb.Root()
+    except device_errors.AdbCommandFailedError:
+      if self.IsUserBuild():
+        raise device_errors.CommandFailedError(
+            'Unable to root device with user build.', str(self))
+      else:
+        raise  # Failed probably due to some other reason.
+
+    def device_online_with_root():
+      try:
+        self.adb.WaitForDevice()
+        return self.GetProp('service.adb.root', cache=False) == '1'
+      except (device_errors.AdbCommandFailedError,
+              device_errors.DeviceUnreachableError):
+        return False
+
+    timeout_retry.WaitFor(device_online_with_root, wait_period=1)
 
   @decorators.WithTimeoutAndRetriesFromInstance()
   def IsUserBuild(self, timeout=None, retries=None):
@@ -1190,8 +1195,8 @@
       CommandTimeoutError on timeout.
       DeviceUnreachableError on missing device.
     """
-    cmd = 'p=%s;if [[ "$(ps)" = *$p* ]]; then am force-stop $p; fi'
-    self.RunShellCommand(cmd % package, shell=True, check_return=True)
+    if self.GetPids(package):
+      self.RunShellCommand(['am', 'force-stop', package], check_return=True)
 
   @decorators.WithTimeoutAndRetriesFromInstance()
   def ClearApplicationState(
diff --git a/catapult/devil/devil/android/device_utils_devicetest.py b/catapult/devil/devil/android/device_utils_devicetest.py
index e69cc90..932e278 100755
--- a/catapult/devil/devil/android/device_utils_devicetest.py
+++ b/catapult/devil/devil/android/device_utils_devicetest.py
@@ -224,6 +224,15 @@
     new_adbd_pid = get_adbd_pid()
     self.assertNotEqual(old_adbd_pid, new_adbd_pid)
 
+  def testEnableRoot(self):
+    self.device.SetProp('service.adb.root', '0')
+    self.device.RestartAdbd()
+    self.assertFalse(self.device.HasRoot())
+    self.assertIn(self.device.GetProp('service.adb.root'), ('', '0'))
+    self.device.EnableRoot()
+    self.assertTrue(self.device.HasRoot())
+    self.assertEquals(self.device.GetProp('service.adb.root'), '1')
+
 
 if __name__ == '__main__':
   unittest.main()
diff --git a/catapult/devil/devil/android/device_utils_test.py b/catapult/devil/devil/android/device_utils_test.py
index 2490209..ebd3c62 100755
--- a/catapult/devil/devil/android/device_utils_test.py
+++ b/catapult/devil/devil/android/device_utils_test.py
@@ -315,22 +315,23 @@
 
   def testEnableRoot_succeeds(self):
     with self.assertCalls(
-        (self.call.device.IsUserBuild(), False),
-         self.call.adb.Root(),
-         self.call.device.WaitUntilFullyBooted()):
+        self.call.adb.Root(),
+        self.call.adb.WaitForDevice(),
+        (self.call.device.GetProp('service.adb.root', cache=False), '1')):
       self.device.EnableRoot()
 
   def testEnableRoot_userBuild(self):
     with self.assertCalls(
+        (self.call.adb.Root(), self.AdbCommandError()),
         (self.call.device.IsUserBuild(), True)):
       with self.assertRaises(device_errors.CommandFailedError):
         self.device.EnableRoot()
 
   def testEnableRoot_rootFails(self):
     with self.assertCalls(
-        (self.call.device.IsUserBuild(), False),
-        (self.call.adb.Root(), self.CommandError())):
-      with self.assertRaises(device_errors.CommandFailedError):
+        (self.call.adb.Root(), self.AdbCommandError()),
+        (self.call.device.IsUserBuild(), False)):
+      with self.assertRaises(device_errors.AdbCommandFailedError):
         self.device.EnableRoot()
 
 
@@ -1539,10 +1540,17 @@
 class DeviceUtilsForceStopTest(DeviceUtilsTest):
 
   def testForceStop(self):
+    with self.assertCalls(
+        (self.call.device.GetPids('test.package'), {'test.package': [1111]}),
+        (self.call.device.RunShellCommand(
+            ['am', 'force-stop', 'test.package'],
+            check_return=True),
+         ['Success'])):
+      self.device.ForceStop('test.package')
+
+  def testForceStop_NoProcessFound(self):
     with self.assertCall(
-        self.call.adb.Shell('p=test.package;if [[ "$(ps)" = *$p* ]]; then '
-                            'am force-stop $p; fi'),
-        ''):
+        self.call.device.GetPids('test.package'), {}):
       self.device.ForceStop('test.package')
 
 
diff --git a/catapult/devil/devil/android/forwarder.py b/catapult/devil/devil/android/forwarder.py
index 244f555..76c56ec 100644
--- a/catapult/devil/devil/android/forwarder.py
+++ b/catapult/devil/devil/android/forwarder.py
@@ -46,7 +46,8 @@
     logger.info('Last 50 lines of logcat:')
     for logcat_line in device.adb.Logcat(dump=True)[-50:]:
       logger.info('    %s', logcat_line)
-  except device_errors.CommandFailedError:
+  except (device_errors.CommandFailedError,
+          device_errors.DeviceUnreachableError):
     # Grabbing the device forwarder log is also best-effort. Ignore all errors.
     logger.warning('Failed to get the contents of the logcat.')
 
@@ -57,7 +58,8 @@
     for line in ps_out:
       if 'device_forwarder' in line:
         logger.info('    %s', line)
-  except device_errors.CommandFailedError:
+  except (device_errors.CommandFailedError,
+          device_errors.DeviceUnreachableError):
     logger.warning('Failed to list currently running device_forwarder '
                    'instances.')
 
@@ -154,7 +156,8 @@
         if exit_code != 0:
           try:
             instance._KillDeviceLocked(device, tool)
-          except device_errors.CommandFailedError:
+          except (device_errors.CommandFailedError,
+                  device_errors.DeviceUnreachableError):
             # We don't want the failure to kill the device forwarder to
             # supersede the original failure to map.
             logging.warning(
diff --git a/catapult/devil/devil/android/sdk/adb_wrapper.py b/catapult/devil/devil/android/sdk/adb_wrapper.py
index 7f6b8d9..e2ca013 100644
--- a/catapult/devil/devil/android/sdk/adb_wrapper.py
+++ b/catapult/devil/devil/android/sdk/adb_wrapper.py
@@ -37,6 +37,7 @@
 
 _ADB_VERSION_RE = re.compile(r'Android Debug Bridge version (\d+\.\d+\.\d+)')
 _EMULATOR_RE = re.compile(r'^emulator-[0-9]+$')
+_DEVICE_NOT_FOUND_RE = re.compile(r"error: device '(?P<serial>.+)' not found")
 _READY_STATE = 'device'
 _VERITY_DISABLE_RE = re.compile(r'Verity (already )?disabled')
 _VERITY_ENABLE_RE = re.compile(r'Verity (already )?enabled')
@@ -135,7 +136,7 @@
     Example of use:
     with PersistentShell('123456789') as pshell:
         pshell.RunCommand('which ls')
-        pshell.RunCommandAndClose('echo TEST')
+        pshell.RunCommand('echo TEST', close=True)
     '''
     def __init__(self, serial):
       """Initialization function:
@@ -253,14 +254,17 @@
       else:
         raise
 
-    if status != 0:
-      raise device_errors.AdbCommandFailedError(
-          args, output, status, device_serial)
-    # This catches some errors, including when the device drops offline;
-    # unfortunately adb is very inconsistent with error reporting so many
-    # command failures present differently.
-    if check_error and output.startswith('error:'):
-      raise device_errors.AdbCommandFailedError(args, output)
+    # Best effort to catch errors from adb; unfortunately adb is very
+    # inconsistent with error reporting so many command failures present
+    # differently.
+    if status != 0 or (check_error and output.startswith('error:')):
+      m = _DEVICE_NOT_FOUND_RE.match(output)
+      if m is not None and m.group('serial') == device_serial:
+        raise device_errors.DeviceUnreachableError(device_serial)
+      else:
+        raise device_errors.AdbCommandFailedError(
+            args, output, status, device_serial)
+
     return output
   # pylint: enable=unused-argument
 
@@ -625,7 +629,9 @@
     if not allow_rebind:
       cmd.append('--no-rebind')
     cmd.extend([str(local), str(remote)])
-    self._RunDeviceAdbCmd(cmd, timeout, retries)
+    output = self._RunDeviceAdbCmd(cmd, timeout, retries).strip()
+    if output:
+      logger.warning('Unexpected output from "adb forward": %s', output)
 
   def ForwardRemove(self, local, timeout=DEFAULT_TIMEOUT,
                     retries=DEFAULT_RETRIES):
diff --git a/catapult/devil/devil/android/sdk/adb_wrapper_devicetest.py b/catapult/devil/devil/android/sdk/adb_wrapper_devicetest.py
index d97d56a..b0ccb24 100755
--- a/catapult/devil/devil/android/sdk/adb_wrapper_devicetest.py
+++ b/catapult/devil/devil/android/sdk/adb_wrapper_devicetest.py
@@ -38,6 +38,11 @@
       f.write(contents)
     return path
 
+  def testDeviceUnreachable(self):
+    with self.assertRaises(device_errors.DeviceUnreachableError):
+      bad_adb = adb_wrapper.AdbWrapper('device_gone')
+      bad_adb.Shell('echo test')
+
   def testShell(self):
     output = self._adb.Shell('echo test', expect_status=0)
     self.assertEqual(output.strip(), 'test')
@@ -46,7 +51,6 @@
     with self.assertRaises(device_errors.AdbCommandFailedError):
       self._adb.Shell('echo test', expect_status=1)
 
-  @unittest.skip("https://github.com/catapult-project/catapult/issues/2574")
   def testPersistentShell(self):
     # We need to access the device serial number here in order
     # to create the persistent shell.
@@ -109,7 +113,7 @@
       try:
         self._adb.Shell('start')
         break
-      except device_errors.AdbCommandFailedError:
+      except device_errors.DeviceUnreachableError:
         time.sleep(1)
     self._adb.Remount()
 
diff --git a/catapult/devil/devil/android/settings.py b/catapult/devil/devil/android/settings.py
index 886b266..d053d2a 100644
--- a/catapult/devil/devil/android/settings.py
+++ b/catapult/devil/devil/android/settings.py
@@ -138,31 +138,25 @@
     raise ValueError('Unsupported type %s' % type(value))
 
   def iteritems(self):
-    # Example row:
-    # 'Row: 0 _id=13, name=logging_id2, value=-1fccbaa546705b05'
     for row in self._device.RunShellCommand(
         ['content', 'query', '--uri', 'content://%s' % self._table],
         check_return=True, as_root=True):
-      fields = row.split(', ')
-      key = None
-      value = None
-      for field in fields:
-        k, _, v = field.partition('=')
-        if k == 'name':
-          key = v
-        elif k == 'value':
-          value = v
+      key, value = _ParseContentRow(row)
       if not key:
         continue
-      if not value:
-        value = ''
       yield key, value
 
   def __getitem__(self, key):
-    return self._device.RunShellCommand(
+    query_row = self._device.RunShellCommand(
         ['content', 'query', '--uri', 'content://%s' % self._table,
          '--where', "name='%s'" % key],
-        check_return=True, as_root=True).strip()
+        check_return=True, as_root=True, single_line=True)
+    parsed_key, parsed_value = _ParseContentRow(query_row)
+    if parsed_key is None:
+      raise KeyError('key=%s not found' % key)
+    if parsed_key != key:
+      raise KeyError('Expected key=%s, but got key=%s' % (key, parsed_key))
+    return parsed_value
 
   def __setitem__(self, key, value):
     if key in self:
@@ -271,3 +265,19 @@
         ['sqlite3', db, cmd], check_return=True, as_root=True)
     if output_msg:
       logger.info(' '.join(output_msg))
+
+
+def _ParseContentRow(row):
+  """Parse key, value entries from a row string."""
+  # Example row:
+  # 'Row: 0 _id=13, name=logging_id2, value=-1fccbaa546705b05'
+  fields = row.split(', ')
+  key = None
+  value = ''
+  for field in fields:
+    k, _, v = field.partition('=')
+    if k == 'name':
+      key = v
+    elif k == 'value':
+      value = v
+  return key, value
diff --git a/catapult/devil/devil/android/tools/device_monitor.py b/catapult/devil/devil/android/tools/device_monitor.py
index 49214a9..d0f7521 100755
--- a/catapult/devil/devil/android/tools/device_monitor.py
+++ b/catapult/devil/devil/android/tools/device_monitor.py
@@ -43,20 +43,14 @@
 ]
 
 DEVICE_FILE_VERSION = 1
-# TODO(bpastene): Remove the old file once sysmon has been updated to read the
-# new status file.
-DEVICE_FILES = [
-    os.path.join(os.path.expanduser('~'), 'android_device_status.json'),
-    os.path.join(
-        os.path.expanduser('~'), '.android',
-        '%s__android_device_status.json' % socket.gethostname().split('.')[0]
-    ),
-]
+DEVICE_FILE = os.path.join(
+    os.path.expanduser('~'), '.android',
+    '%s__android_device_status.json' % socket.gethostname().split('.')[0])
 
 MEM_INFO_REGEX = re.compile(r'.*?\:\s*(\d+)\s*kB') # ex: 'MemTotal:   185735 kB'
 
 
-def get_device_status(device):
+def get_device_status_unsafe(device):
   """Polls the given device for various info.
 
     Returns: A dict of the following format:
@@ -159,6 +153,14 @@
   return status
 
 
+def get_device_status(device):
+  try:
+    status = get_device_status_unsafe(device)
+  except device_errors.DeviceUnreachableError:
+    status = {'state': 'offline'}
+  return status
+
+
 def get_all_status(blacklist):
   status_dict = {
       'version': DEVICE_FILE_VERSION,
@@ -220,9 +222,8 @@
   while True:
     start = time.time()
     status_dict = get_all_status(blacklist)
-    for device_file in DEVICE_FILES:
-      with open(device_file, 'wb') as f:
-        json.dump(status_dict, f, indent=2, sort_keys=True)
+    with open(DEVICE_FILE, 'wb') as f:
+      json.dump(status_dict, f, indent=2, sort_keys=True)
     logging.info('Got status of all devices in %.2fs.', time.time() - start)
     time.sleep(60)
 
diff --git a/catapult/devil/devil/android/tools/device_recovery.py b/catapult/devil/devil/android/tools/device_recovery.py
index 57857b1..80c78d2 100755
--- a/catapult/devil/devil/android/tools/device_recovery.py
+++ b/catapult/devil/devil/android/tools/device_recovery.py
@@ -64,7 +64,8 @@
     try:
       device.WaitUntilFullyBooted(retries=0)
     except (device_errors.CommandTimeoutError,
-            device_errors.CommandFailedError):
+            device_errors.CommandFailedError,
+            device_errors.DeviceUnreachableError):
       logger.exception('Failure while waiting for %s. '
                        'Attempting to recover.', str(device))
     try:
@@ -83,7 +84,8 @@
           # exception willbe thrown at that level.
           device.adb.Shell('echo b > /proc/sysrq-trigger', expect_status=None,
                            timeout=5, retries=0)
-    except device_errors.CommandFailedError:
+    except (device_errors.CommandFailedError,
+            device_errors.DeviceUnreachableError):
       logger.exception('Failed to reboot %s.', str(device))
       if blacklist:
         blacklist.Extend([device.adb.GetDeviceSerial()],
@@ -97,7 +99,8 @@
     try:
       device.WaitUntilFullyBooted(
           retries=0, timeout=device.REBOOT_DEFAULT_TIMEOUT)
-    except device_errors.CommandFailedError:
+    except (device_errors.CommandFailedError,
+            device_errors.DeviceUnreachableError):
       logger.exception('Failure while waiting for %s.', str(device))
       if blacklist:
         blacklist.Extend([device.adb.GetDeviceSerial()],
diff --git a/catapult/devil/devil/android/tools/device_status.py b/catapult/devil/devil/android/tools/device_status.py
index 167d66c..159c6c5 100755
--- a/catapult/devil/devil/android/tools/device_status.py
+++ b/catapult/devil/devil/android/tools/device_status.py
@@ -51,7 +51,8 @@
       if blacklist:
         blacklist.Extend([device.adb.GetDeviceSerial()], reason='low_battery')
 
-  except device_errors.CommandFailedError:
+  except (device_errors.CommandFailedError,
+          device_errors.DeviceUnreachableError):
     logger.exception('Failed to get battery information for %s',
                      str(device))
 
@@ -66,7 +67,8 @@
       m = _RE_DEVICE_ID.match(l)
       if m:
         imei_slice = m.group(1)[-6:]
-  except device_errors.CommandFailedError:
+  except (device_errors.CommandFailedError,
+          device_errors.DeviceUnreachableError):
     logger.exception('Failed to get IMEI slice for %s', str(device))
 
   return imei_slice
@@ -143,7 +145,8 @@
             'wifi_ip': wifi_ip,
           })
 
-        except device_errors.CommandFailedError:
+        except (device_errors.CommandFailedError,
+                device_errors.DeviceUnreachableError):
           logger.exception('Failure while getting device status for %s.',
                            str(device))
           if blacklist:
diff --git a/catapult/devil/devil/android/tools/provision_devices.py b/catapult/devil/devil/android/tools/provision_devices.py
index 7374290..9359f11 100755
--- a/catapult/devil/devil/android/tools/provision_devices.py
+++ b/catapult/devil/devil/android/tools/provision_devices.py
@@ -37,7 +37,6 @@
 from devil.android import device_temp_file
 from devil.android import device_utils
 from devil.android import settings
-from devil.android.constants import chrome
 from devil.android.sdk import adb_wrapper
 from devil.android.sdk import intent
 from devil.android.sdk import keyevent
@@ -86,11 +85,13 @@
     reboot_timeout=None,
     remove_system_webview=False,
     system_app_remove_list=None,
+    system_package_remove_list=None,
     wipe=True):
   blacklist = (device_blacklist.Blacklist(blacklist_file)
                if blacklist_file
                else None)
   system_app_remove_list = system_app_remove_list or []
+  system_package_remove_list = system_package_remove_list or []
   try:
     devices = script_common.GetDevices(devices, blacklist)
   except device_errors.NoDevicesError:
@@ -118,7 +119,7 @@
 
   if max_battery_temp:
     steps.append(ProvisionStep(
-        lambda d: WaitForTemperature(d, max_battery_temp)))
+        lambda d: WaitForBatteryTemperature(d, max_battery_temp)))
 
   if min_battery_level:
     steps.append(ProvisionStep(
@@ -127,9 +128,10 @@
   if remove_system_webview:
     system_app_remove_list.extend(_SYSTEM_WEBVIEW_NAMES)
 
-  if system_app_remove_list:
+  if system_app_remove_list or system_package_remove_list:
     steps.append(ProvisionStep(
-        lambda d: RemoveSystemApps(d, system_app_remove_list)))
+        lambda d: RemoveSystemApps(
+            d, system_app_remove_list, system_package_remove_list)))
 
   steps.append(ProvisionStep(SetDate))
   steps.append(ProvisionStep(CheckExternalStorage))
@@ -170,7 +172,8 @@
     if blacklist:
       blacklist.Extend([str(device)], reason='provision_timeout')
 
-  except device_errors.CommandFailedError:
+  except (device_errors.CommandFailedError,
+          device_errors.DeviceUnreachableError):
     logger.exception('Failed to provision device %s. Adding to blacklist.',
                      str(device))
     if blacklist:
@@ -182,9 +185,12 @@
       device.build_version_sdk >= version_codes.MARSHMALLOW):
     WipeChromeData(device)
 
-    package = "com.google.android.gms"
-    version_name = device.GetApplicationVersion(package)
-    logger.info("Version name for %s is %s", package, version_name)
+    package = 'com.google.android.gms'
+    if device.GetApplicationPaths(package):
+      version_name = device.GetApplicationVersion(package)
+      logger.info('Version name for %s is %s', package, version_name)
+    else:
+      logger.info('Package %s is not installed', package)
   else:
     WipeDevice(device, adb_key_files)
 
@@ -208,16 +214,14 @@
   """
   try:
     if device.IsUserBuild():
-      _UninstallIfMatch(device, _CHROME_PACKAGE_REGEX,
-                        chrome.PACKAGE_INFO['chrome_stable'].package)
+      _UninstallIfMatch(device, _CHROME_PACKAGE_REGEX)
       device.RunShellCommand('rm -rf %s/*' % device.GetExternalStoragePath(),
                              shell=True, check_return=True)
       device.RunShellCommand('rm -rf /data/local/tmp/*',
                              shell=True, check_return=True)
     else:
       device.EnableRoot()
-      _UninstallIfMatch(device, _CHROME_PACKAGE_REGEX,
-                        chrome.PACKAGE_INFO['chrome_stable'].package)
+      _UninstallIfMatch(device, _CHROME_PACKAGE_REGEX)
       _WipeUnderDirIfMatch(device, '/data/app-lib/', _CHROME_PACKAGE_REGEX)
       _WipeUnderDirIfMatch(device, '/data/tombstones/', _TOMBSTONE_REGEX)
 
@@ -232,7 +236,7 @@
                      'Attempting to continue.')
 
 
-def _UninstallIfMatch(device, pattern, app_to_keep):
+def _UninstallIfMatch(device, pattern):
   installed_packages = device.RunShellCommand(
       ['pm', 'list', 'packages'], check_return=True)
   installed_system_packages = [
@@ -240,9 +244,8 @@
           ['pm', 'list', 'packages', '-s'], check_return=True)]
   for package_output in installed_packages:
     package = package_output.split(":")[1]
-    if pattern.match(package) and not package == app_to_keep:
-      if not device.IsUserBuild() or package not in installed_system_packages:
-        device.Uninstall(package)
+    if pattern.match(package) and package not in installed_system_packages:
+      device.Uninstall(package)
 
 
 def _WipeUnderDirIfMatch(device, path, pattern):
@@ -349,43 +352,55 @@
 def DisableSystemChrome(device):
   # The system chrome version on the device interferes with some tests.
   device.RunShellCommand(['pm', 'disable', 'com.android.chrome'],
-                         check_return=True)
+                         as_root=True, check_return=True)
 
 
-def _RemoveSystemApp(device, system_app):
+def _FindSystemPackagePaths(device, system_package_list):
   found_paths = []
-  for directory in _SYSTEM_APP_DIRECTORIES:
-    path = os.path.join(directory, system_app)
-    if device.PathExists(path):
-      found_paths.append(path)
-  if not found_paths:
-    logger.warning('Could not find install location for system app %s',
-                   system_app)
-  device.RemovePath(found_paths, force=True, recursive=True)
+  for system_package in system_package_list:
+    found_paths.extend(device.GetApplicationPaths(system_package))
+  return [p for p in found_paths if p.startswith('/system/')]
 
-def RemoveSystemApps(device, system_app_remove_list):
+
+def _FindSystemAppPaths(device, system_app_list):
+  found_paths = []
+  for system_app in system_app_list:
+    for directory in _SYSTEM_APP_DIRECTORIES:
+      path = os.path.join(directory, system_app)
+      if device.PathExists(path):
+        found_paths.append(path)
+  return found_paths
+
+
+def RemoveSystemApps(
+    device, system_app_remove_list, system_package_remove_list):
   """Attempts to remove the provided system apps from the given device.
 
   Arguments:
     device: The device to remove the system apps from.
     system_app_remove_list: A list of app names to remove, e.g.
         ['WebViewGoogle', 'GoogleVrCore']
+    system_package_remove_list: A list of app packages to remove, e.g.
+        ['com.google.android.webview']
   """
   device.EnableRoot()
   if device.HasRoot():
-    # Disable Marshmallow's Verity security feature
-    if device.build_version_sdk >= version_codes.MARSHMALLOW:
-      logger.info('Disabling Verity on %s', device.serial)
-      device.adb.DisableVerity()
-      device.Reboot()
-      device.WaitUntilFullyBooted()
-      device.EnableRoot()
+    system_app_paths = (
+        _FindSystemAppPaths(device, system_app_remove_list) +
+        _FindSystemPackagePaths(device, system_package_remove_list))
+    if system_app_paths:
+      # Disable Marshmallow's Verity security feature
+      if device.build_version_sdk >= version_codes.MARSHMALLOW:
+        logger.info('Disabling Verity on %s', device.serial)
+        device.adb.DisableVerity()
+        device.Reboot()
+        device.WaitUntilFullyBooted()
+        device.EnableRoot()
 
-    device.adb.Remount()
-    device.RunShellCommand(['stop'], check_return=True)
-    for system_app in system_app_remove_list:
-      _RemoveSystemApp(device, system_app)
-    device.RunShellCommand(['start'], check_return=True)
+      device.adb.Remount()
+      device.RunShellCommand(['stop'], check_return=True)
+      device.RemovePath(system_app_paths, force=True, recursive=True)
+      device.RunShellCommand(['start'], check_return=True)
   else:
     raise device_errors.CommandFailedError(
         'Failed to remove system apps from non-rooted device', str(device))
@@ -432,7 +447,7 @@
     battery.ChargeDeviceToLevel(min_battery_level)
 
 
-def WaitForTemperature(device, max_battery_temp):
+def WaitForBatteryTemperature(device, max_battery_temp):
   try:
     battery = battery_utils.BatteryUtils(device)
     battery.LetBatteryCoolToTemperature(max_battery_temp)
@@ -482,8 +497,11 @@
       raise device_errors.CommandFailedError(
           'Failed to set date & time.', device_serial=str(device))
     device.EnableRoot()
+    # The following intent can take a bit to complete when ran shortly after
+    # device boot-up.
     device.BroadcastIntent(
-        intent.Intent(action='android.intent.action.TIME_SET'))
+        intent.Intent(action='android.intent.action.TIME_SET'),
+        timeout=180)
 
 
 def LogDeviceProperties(device):
@@ -550,7 +568,8 @@
       help='disable Java property asserts and JNI checking')
   parser.add_argument(
       '--disable-system-chrome', action='store_true',
-      help='Disable the system chrome from devices.')
+      help='DEPRECATED: use --remove-system-packages com.android.google '
+           'Disable the system chrome from devices.')
   parser.add_argument(
       '--emulators', action='store_true',
       help='provision only emulators and ignore usb devices '
@@ -572,10 +591,16 @@
            '(default: %s)' % _DEFAULT_TIMEOUTS.HELP_TEXT)
   parser.add_argument(
       '--remove-system-apps', nargs='*', dest='system_app_remove_list',
-      help='the names of system apps to remove')
+      help='DEPRECATED: use --remove-system-packages instead. '
+           'The names of system apps to remove. ')
+  parser.add_argument(
+      '--remove-system-packages', nargs='*', dest='system_package_remove_list',
+      help='The names of system packages to remove.')
   parser.add_argument(
       '--remove-system-webview', action='store_true',
-      help='Remove the system webview from devices.')
+      help='DEPRECATED: use --remove-system-packages '
+           'com.google.android.webview com.android.webview '
+           'Remove the system webview from devices.')
   parser.add_argument(
       '--skip-wipe', action='store_true', default=False,
       help='do not wipe device data during provisioning')
@@ -627,6 +652,7 @@
         reboot_timeout=args.reboot_timeout,
         remove_system_webview=args.remove_system_webview,
         system_app_remove_list=args.system_app_remove_list,
+        system_package_remove_list=args.system_package_remove_list,
         wipe=not args.skip_wipe and not args.emulators)
   except (device_errors.DeviceUnreachableError, device_errors.NoDevicesError):
     logging.exception('Unable to provision local devices.')
diff --git a/catapult/devil/devil/devil_dependencies.json b/catapult/devil/devil/devil_dependencies.json
index e552293..bed6fe1 100644
--- a/catapult/devil/devil/devil_dependencies.json
+++ b/catapult/devil/devil/devil_dependencies.json
@@ -66,11 +66,11 @@
       "cloud_storage_bucket": "chromium-telemetry",
       "file_info": {
         "android_arm64-v8a": {
-          "cloud_storage_hash": "90cc60cefb497512d95d774045146754c477b433",
+          "cloud_storage_hash": "f222268d8442979240d1b18de00911a49e548daa",
           "download_path": "../bin/deps/android/arm64-v8a/bin/forwarder_device"
         },
         "android_armeabi-v7a": {
-          "cloud_storage_hash": "3a5ade8fbaffea3b0670bffaa845288db5e4d567",
+          "cloud_storage_hash": "c15267bf01c26eb0aea4f61c780bbba460c5c981",
           "download_path": "../bin/deps/android/armeabi-v7a/bin/forwarder_device"
         }
       }
@@ -80,7 +80,7 @@
       "cloud_storage_bucket": "chromium-telemetry",
       "file_info": {
         "linux2_x86_64": {
-          "cloud_storage_hash": "63653293098d7fe17aa115b147c8d9aa253b0912",
+          "cloud_storage_hash": "8fe69994b670f028484eed475dbffc838c8a57f7",
           "download_path": "../bin/deps/linux2/x86_64/forwarder_host"
         }
       }
@@ -124,4 +124,4 @@
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/catapult/devil/devil/utils/cmd_helper.py b/catapult/devil/devil/utils/cmd_helper.py
index 06c105f..0b6ccd9 100644
--- a/catapult/devil/devil/utils/cmd_helper.py
+++ b/catapult/devil/devil/utils/cmd_helper.py
@@ -15,11 +15,6 @@
 import sys
 import time
 
-# fcntl is not available on Windows.
-try:
-  import fcntl
-except ImportError:
-  fcntl = None
 
 logger = logging.getLogger(__name__)
 
@@ -96,13 +91,15 @@
 def Popen(args, stdout=None, stderr=None, shell=None, cwd=None, env=None):
   # preexec_fn isn't supported on windows.
   if sys.platform == 'win32':
+    close_fds = (stdout is None and stderr is None)
     preexec_fn = None
   else:
+    close_fds = True
     preexec_fn = lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)
 
   return subprocess.Popen(
       args=args, cwd=cwd, stdout=stdout, stderr=stderr,
-      shell=shell, close_fds=True, env=env, preexec_fn=preexec_fn)
+      shell=shell, close_fds=close_fds, env=env, preexec_fn=preexec_fn)
 
 
 def Call(args, stdout=None, stderr=None, shell=None, cwd=None, env=None):
@@ -219,31 +216,11 @@
     return self._output
 
 
-def _IterProcessStdout(process, iter_timeout=None, timeout=None,
-                       buffer_size=4096, poll_interval=1):
-  """Iterate over a process's stdout.
-
-  This is intentionally not public.
-
-  Args:
-    process: The process in question.
-    iter_timeout: An optional length of time, in seconds, to wait in
-      between each iteration. If no output is received in the given
-      time, this generator will yield None.
-    timeout: An optional length of time, in seconds, during which
-      the process must finish. If it fails to do so, a TimeoutError
-      will be raised.
-    buffer_size: The maximum number of bytes to read (and thus yield) at once.
-    poll_interval: The length of time to wait in calls to `select.select`.
-      If iter_timeout is set, the remaining length of time in the iteration
-      may take precedence.
-  Raises:
-    TimeoutError: if timeout is set and the process does not complete.
-  Yields:
-    basestrings of data or None.
-  """
-
-  assert fcntl, 'fcntl module is required'
+def _IterProcessStdoutFcntl(
+    process, iter_timeout=None, timeout=None, buffer_size=4096,
+    poll_interval=1):
+  """An fcntl-based implementation of _IterProcessStdout."""
+  import fcntl
   try:
     # Enable non-blocking reads from the child's stdout.
     child_fd = process.stdout.fileno()
@@ -287,6 +264,86 @@
     process.wait()
 
 
+def _IterProcessStdoutQueue(
+    process, iter_timeout=None, timeout=None, buffer_size=4096,
+    poll_interval=1):
+  """A Queue.Queue-based implementation of _IterProcessStdout.
+
+  TODO(jbudorick): Evaluate whether this is a suitable replacement for
+  _IterProcessStdoutFcntl on all platforms.
+  """
+  # pylint: disable=unused-argument
+  import Queue
+  import threading
+
+  stdout_queue = Queue.Queue()
+
+  def read_process_stdout():
+    # TODO(jbudorick): Pick an appropriate read size here.
+    while True:
+      try:
+        output_chunk = os.read(process.stdout.fileno(), buffer_size)
+      except IOError:
+        break
+      stdout_queue.put(output_chunk, True)
+      if not output_chunk and process.poll() is not None:
+        break
+
+  reader_thread = threading.Thread(target=read_process_stdout)
+  reader_thread.start()
+
+  end_time = (time.time() + timeout) if timeout else None
+
+  try:
+    while True:
+      if end_time and time.time() > end_time:
+        raise TimeoutError()
+      try:
+        s = stdout_queue.get(True, iter_timeout)
+        if not s:
+          break
+        yield s
+      except Queue.Empty:
+        yield None
+  finally:
+    try:
+      if process.returncode is None:
+        # Make sure the process doesn't stick around if we fail with an
+        # exception.
+        process.kill()
+    except OSError:
+      pass
+    process.wait()
+    reader_thread.join()
+
+
+_IterProcessStdout = (
+    _IterProcessStdoutQueue
+    if sys.platform == 'win32'
+    else _IterProcessStdoutFcntl)
+"""Iterate over a process's stdout.
+
+This is intentionally not public.
+
+Args:
+  process: The process in question.
+  iter_timeout: An optional length of time, in seconds, to wait in
+    between each iteration. If no output is received in the given
+    time, this generator will yield None.
+  timeout: An optional length of time, in seconds, during which
+    the process must finish. If it fails to do so, a TimeoutError
+    will be raised.
+  buffer_size: The maximum number of bytes to read (and thus yield) at once.
+  poll_interval: The length of time to wait in calls to `select.select`.
+    If iter_timeout is set, the remaining length of time in the iteration
+    may take precedence.
+Raises:
+  TimeoutError: if timeout is set and the process does not complete.
+Yields:
+  basestrings of data or None.
+"""
+
+
 def GetCmdStatusAndOutputWithTimeout(args, timeout, cwd=None, shell=False,
                                      logfile=None):
   """Executes a subprocess with a timeout.
diff --git a/catapult/devil/devil/utils/cmd_helper_test.py b/catapult/devil/devil/utils/cmd_helper_test.py
index 783c413..b7fc8ee 100755
--- a/catapult/devil/devil/utils/cmd_helper_test.py
+++ b/catapult/devil/devil/utils/cmd_helper_test.py
@@ -7,6 +7,7 @@
 
 import unittest
 import subprocess
+import sys
 import time
 
 from devil import devil_env
@@ -175,11 +176,12 @@
 
     # Set up but *do not start* the mocks.
     self._mocks = [
-      mock.patch('fcntl.fcntl'),
       mock.patch('os.read', new=mock_read),
       mock.patch('select.select', new=mock_select),
       mock.patch('time.time', new=mock_time),
     ]
+    if sys.platform != 'win32':
+      self._mocks.append(mock.patch('fcntl.fcntl'))
 
   def __enter__(self):
     for m in self._mocks:
diff --git a/catapult/devil/devil/utils/find_usb_devices.py b/catapult/devil/devil/utils/find_usb_devices.py
index 0e0f4d5..28a2eb8 100755
--- a/catapult/devil/devil/utils/find_usb_devices.py
+++ b/catapult/devil/devil/utils/find_usb_devices.py
@@ -3,9 +3,15 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import argparse
+import os
 import re
 import sys
-import argparse
+
+if __name__ == '__main__':
+  sys.path.append(
+      os.path.abspath(os.path.join(os.path.dirname(__file__),
+                                   '..', '..')))
 
 from devil.utils import cmd_helper
 from devil.utils import usb_hubs
diff --git a/catapult/devil/devil/utils/usb_hubs.py b/catapult/devil/devil/utils/usb_hubs.py
index 1b9566a..b718694 100644
--- a/catapult/devil/devil/utils/usb_hubs.py
+++ b/catapult/devil/devil/utils/usb_hubs.py
@@ -17,6 +17,11 @@
                  3:3,
                  4:{1:4, 2:5, 3:6, 4:7}}
 
+VIA_LAYOUT = {1:1,
+              2:2,
+              3:3,
+              4:{1:4, 2:5, 3:6, 4:7}}
+
 class HubType(object):
   def __init__(self, id_func, port_mapping):
     """Defines a type of hub.
@@ -139,6 +144,17 @@
     return False
   return '0bda:5411' in node.PortToDevice(4).desc
 
+def _is_via_hub(node):
+  """Check if a node is a Via Labs hub.
+  The topology of this device is a 4-port hub,
+  with another 4-port hub connected on port 4.
+  """
+  if '2109:2812' not in node.desc:
+    return False
+  if not node.HasPort(4):
+    return False
+  return '2109:2812' in node.PortToDevice(4).desc
+
 
 PLUGABLE_7PORT = HubType(_is_plugable_7port_hub, PLUGABLE_7PORT_LAYOUT)
 PLUGABLE_7PORT_USB3_PART2 = HubType(_is_plugable_7port_usb3_part2_hub,
@@ -146,20 +162,23 @@
 PLUGABLE_7PORT_USB3_PART3 = HubType(_is_plugable_7port_usb3_part3_hub,
                                     PLUGABLE_7PORT_USB3_LAYOUT)
 KEEDOX = HubType(_is_keedox_hub, KEEDOX_LAYOUT)
+VIA = HubType(_is_via_hub, VIA_LAYOUT)
 
 ALL_HUBS = [PLUGABLE_7PORT,
             PLUGABLE_7PORT_USB3_PART2,
             PLUGABLE_7PORT_USB3_PART3,
-            KEEDOX]
+            KEEDOX,
+            VIA]
 
 def GetHubType(type_name):
   if type_name == 'plugable_7port':
     return PLUGABLE_7PORT
-  if type_name == 'plugable_7port_usb3_part2':
+  elif type_name == 'plugable_7port_usb3_part2':
     return PLUGABLE_7PORT_USB3_PART2
-  if type_name == 'plugable_7port_usb3_part3':
+  elif type_name == 'plugable_7port_usb3_part3':
     return PLUGABLE_7PORT_USB3_PART3
-  if type_name == 'keedox':
+  elif type_name == 'keedox':
     return KEEDOX
-  else:
-    raise ValueError('Invalid hub type')
+  elif type_name == 'via':
+    return VIA
+  raise ValueError('Invalid hub type')
diff --git a/catapult/systrace/atrace_helper/.gitignore b/catapult/systrace/atrace_helper/.gitignore
new file mode 100644
index 0000000..e0c35b9
--- /dev/null
+++ b/catapult/systrace/atrace_helper/.gitignore
@@ -0,0 +1,2 @@
+obj/
+libs/
diff --git a/catapult/systrace/atrace_helper/Makefile b/catapult/systrace/atrace_helper/Makefile
new file mode 100644
index 0000000..2fd5195
--- /dev/null
+++ b/catapult/systrace/atrace_helper/Makefile
@@ -0,0 +1,24 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+NDK_HOME ?= $(HOME)/tools/android-ndk-r13b
+
+all: build
+
+build:
+	$(NDK_HOME)/ndk-build
+
+install: build
+	adb push libs/armeabi-v7a/atrace_helper /data/local/tmp/atrace_helper
+
+test: install
+	adb shell /data/local/tmp/atrace_helper -c 1
+
+testf: install
+	adb shell /data/local/tmp/atrace_helper -c 1 -m -o /data/local/tmp/dump.json
+	adb pull /data/local/tmp/dump.json /tmp/dump.json
+	python -c 'import json; json.load(open("/tmp/dump.json"))'
+
+benchmark: install
+	adb shell "time /data/local/tmp/atrace_helper -c 1 -m -o /dev/null"
diff --git a/catapult/systrace/atrace_helper/README.md b/catapult/systrace/atrace_helper/README.md
new file mode 100644
index 0000000..b5fd651
--- /dev/null
+++ b/catapult/systrace/atrace_helper/README.md
@@ -0,0 +1,29 @@
+<!-- Copyright 2017 The Chromium Authors. All rights reserved.
+     Use of this source code is governed by a BSD-style license that can be
+     found in the LICENSE file.
+-->
+atrace_helper is an optional binary which can be pushed onto the device running
+systrace in order to enrich the traces with further details (memory, I/O, etc).
+
+Which problem is it solving?
+---------------------------
+Some nice-to-have details are not present in the systrace, specifically:
+ - Memory snapshots of running processes (PSS/RSS).
+ - Periodic snapshotting of processes and thread names.
+ - File paths for filesystem events (today they report only inode numbers).
+
+How is it solving it?
+---------------------
+atrace_helper is a small userspace binary which is meant to be pushed on the
+device and run together with atrace by a dedicated tracing agent. When stopped,
+the helper produces a JSON file which contains all the relevant details
+(see --help). The JSON file is consumed by the TraceViewer importers and the
+extra details are merged into the final model.
+
+Build instructions
+------------------
+Building the binary requires the Android NDK to be installed. See
+[Android NDK page](https://developer.android.com/ndk).
+Once installed the binary can be just built as follows:
+`$(NDK_HOME)/ndk-build`
+The binary will be built in `libs/armeabi-v7a/`
diff --git a/catapult/systrace/atrace_helper/jni/.clang-format b/catapult/systrace/atrace_helper/jni/.clang-format
new file mode 100644
index 0000000..aa7a9f5
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/.clang-format
@@ -0,0 +1,6 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+BasedOnStyle: Chromium
+Standard: Cpp11
diff --git a/catapult/systrace/atrace_helper/jni/Android.mk b/catapult/systrace/atrace_helper/jni/Android.mk
new file mode 100644
index 0000000..a3f0b9b
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/Android.mk
@@ -0,0 +1,21 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+LOCAL_PATH := $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := atrace_helper
+LOCAL_CPPFLAGS := -std=c++11 -Wall -Wextra -Werror -O2
+LOCAL_CPPFLAGS += -fPIE -fno-rtti -fno-exceptions -fstack-protector
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_LDLIBS := -fPIE -pie -llog
+
+LOCAL_SRC_FILES := \
+    main.cc \
+    file_utils.cc \
+    process_info.cc \
+    process_memory_stats.cc
+
+include $(BUILD_EXECUTABLE)
diff --git a/catapult/systrace/atrace_helper/jni/Application.mk b/catapult/systrace/atrace_helper/jni/Application.mk
new file mode 100644
index 0000000..cc2eb67
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/Application.mk
@@ -0,0 +1,7 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+APP_ABI := armeabi-v7a
+APP_PLATFORM := android-21
+APP_STL := c++_static
diff --git a/catapult/systrace/atrace_helper/jni/file_utils.cc b/catapult/systrace/atrace_helper/jni/file_utils.cc
new file mode 100644
index 0000000..9ebec2d
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/file_utils.cc
@@ -0,0 +1,96 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "file_utils.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+namespace {
+
+bool IsNumeric(const char* str) {
+  if (!str[0])
+    return false;
+  for (const char* c = str; *c; c++) {
+    if (!isdigit(*c))
+      return false;
+  }
+  return true;
+}
+
+}  // namespace
+
+namespace file_utils {
+
+void ForEachPidInProcPath(const char* proc_path,
+                          std::function<void(int)> predicate) {
+  DIR* root_dir = opendir(proc_path);
+  ScopedDir autoclose(root_dir);
+  struct dirent* child_dir;
+  while ((child_dir = readdir(root_dir))) {
+    if (child_dir->d_type != DT_DIR || !IsNumeric(child_dir->d_name))
+      continue;
+    predicate(atoi(child_dir->d_name));
+  }
+}
+
+ssize_t ReadFile(const char* path, char* buf, size_t length) {
+  buf[0] = '\0';
+  int fd = open(path, O_RDONLY);
+  if (fd < 0 && errno == ENOENT)
+    return -1;
+  ScopedFD autoclose(fd);
+  size_t tot_read = 0;
+  do {
+    ssize_t rsize = read(fd, buf + tot_read, length - tot_read);
+    if (rsize == 0)
+      break;
+    if (rsize == -1 && errno == EINTR)
+      continue;
+    else if (rsize < 0)
+      return -1;
+    tot_read += static_cast<size_t>(rsize);
+  } while (tot_read < length);
+  buf[tot_read < length ? tot_read : length - 1] = '\0';
+  return tot_read;
+}
+
+bool ReadFileTrimmed(const char* path, char* buf, size_t length) {
+  ssize_t rsize = ReadFile(path, buf, length);
+  if (rsize < 0)
+    return false;
+  for (ssize_t i = 0; i < rsize; i++) {
+    const char c = buf[i];
+    if (c == '\0' || c == '\r' || c == '\n') {
+      buf[i] = '\0';
+      break;
+    }
+    buf[i] = isprint(c) ? c : '?';
+  }
+  return true;
+}
+
+ssize_t ReadProcFile(int pid, const char* proc_file, char* buf, size_t length) {
+  char proc_path[128];
+  snprintf(proc_path, sizeof(proc_path), "/proc/%d/%s", pid, proc_file);
+  return ReadFile(proc_path, buf, length);
+}
+
+// Reads a single-line proc file, stripping out any \0, \r, \n and replacing
+// non-printable charcters with '?'.
+bool ReadProcFileTrimmed(int pid,
+                         const char* proc_file,
+                         char* buf,
+                         size_t length) {
+  char proc_path[128];
+  snprintf(proc_path, sizeof(proc_path), "/proc/%d/%s", pid, proc_file);
+  return ReadFileTrimmed(proc_path, buf, length);
+}
+
+}  // namespace file_utils
diff --git a/catapult/systrace/atrace_helper/jni/file_utils.h b/catapult/systrace/atrace_helper/jni/file_utils.h
new file mode 100644
index 0000000..c6a5527
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/file_utils.h
@@ -0,0 +1,53 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FILE_UTILS_H_
+#define FILE_UTILS_H_
+
+#include <dirent.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <functional>
+#include <map>
+#include <memory>
+
+#include "logging.h"
+
+namespace file_utils {
+
+// RAII classes for auto-releasing fd/dirs.
+template <typename RESOURCE_TYPE, int (*CLOSE_FN)(RESOURCE_TYPE)>
+struct ScopedResource {
+  explicit ScopedResource(RESOURCE_TYPE r) : r_(r) { CHECK(r); }
+  ~ScopedResource() { CLOSE_FN(r_); }
+  RESOURCE_TYPE r_;
+};
+
+using ScopedFD = ScopedResource<int, close>;
+using ScopedDir = ScopedResource<DIR*, closedir>;
+
+// Invokes predicate(pid) for each folder in |proc_path|/[0-9]+ which has
+// a numeric name (typically pids and tids).
+void ForEachPidInProcPath(const char* proc_path,
+                          std::function<void(int)> predicate);
+
+// Reads the contents of |path| fully into |buf| up to |length| chars.
+// |buf| is guaranteed to be null terminated.
+ssize_t ReadFile(const char* path, char* buf, size_t length);
+
+// Reads a single-line file, stripping out any \0, \r, \n and replacing
+// non-printable charcters with '?'. |buf| is guaranteed to be null terminated.
+bool ReadFileTrimmed(int pid, const char* proc_file, char* buf, size_t length);
+
+// Convenience wrappers for /proc/|pid|/|proc_file| paths.
+ssize_t ReadProcFile(int pid, const char* proc_file, char* buf, size_t length);
+bool ReadProcFileTrimmed(int pid,
+                         const char* proc_file,
+                         char* buf,
+                         size_t length);
+
+}  // namespace file_utils
+
+#endif  // FILE_UTILS_H_
diff --git a/catapult/systrace/atrace_helper/jni/logging.h b/catapult/systrace/atrace_helper/jni/logging.h
new file mode 100644
index 0000000..7e130eb
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/logging.h
@@ -0,0 +1,28 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LOGGING_H_
+#define LOGGING_H_
+
+#include <android/log.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CHECK_ARGS(COND, ERR)                                          \
+  "FAILED CHECK(%s) @ %s:%d (errno: %s)\n", #COND, __FILE__, __LINE__, \
+      strerror(ERR)
+
+#define CHECK(x)                                              \
+  do {                                                        \
+    if (!(x)) {                                               \
+      const int e = errno;                                    \
+      __android_log_print(ANDROID_LOG_FATAL, "atrace_helper", \
+                          CHECK_ARGS(x, e));                  \
+      fprintf(stderr, "\n" CHECK_ARGS(x, e));                 \
+      fflush(stderr);                                         \
+      abort();                                                \
+    }                                                         \
+  } while (0)
+
+#endif  // LOGGING_H_
diff --git a/catapult/systrace/atrace_helper/jni/main.cc b/catapult/systrace/atrace_helper/jni/main.cc
new file mode 100644
index 0000000..e6f1fe1
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/main.cc
@@ -0,0 +1,198 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <dirent.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+#include <sys/timerfd.h>
+#include <sys/types.h>
+
+#include <limits>
+#include <memory>
+
+#include "file_utils.h"
+#include "logging.h"
+#include "process_info.h"
+
+namespace {
+
+using ProcessMap = std::map<int, std::unique_ptr<ProcessInfo>>;
+
+int g_timer;
+
+std::unique_ptr<ProcessMap> CollectStatsForAllProcs(bool full_mem_stats) {
+  std::unique_ptr<ProcessMap> procs(new ProcessMap());
+  file_utils::ForEachPidInProcPath("/proc", [&procs, full_mem_stats](int pid) {
+    if (!ProcessInfo::IsProcess(pid))
+      return;
+    CHECK(procs->count(pid) == 0);
+    std::unique_ptr<ProcessInfo> pinfo(new ProcessInfo(pid));
+    if (!(pinfo->ReadProcessName() && pinfo->ReadThreadNames() &&
+          pinfo->ReadOOMStats() && pinfo->ReadPageFaultsAndCPUTimeStats()))
+      return;
+
+    if (full_mem_stats) {
+      if (!pinfo->memory()->ReadFullStats())
+        return;
+    } else {
+      if (!pinfo->memory()->ReadLightStats())
+        return;
+    }
+    (*procs)[pid] = std::move(pinfo);
+  });
+  return procs;
+}
+
+void SerializeSnapshot(const ProcessMap& procs,
+                       FILE* stream,
+                       bool full_mem_stats) {
+  struct timespec ts = {};
+  CHECK(clock_gettime(CLOCK_MONOTONIC_COARSE, &ts) == 0);
+  fprintf(stream, "{\n");
+  fprintf(stream, "  \"ts\": %lu,\n",
+          (ts.tv_sec * 1000 + ts.tv_nsec / 1000000ul));
+  fprintf(stream, "  \"processes\": [\n");
+  for (auto it = procs.begin(); it != procs.end();) {
+    int pid = it->first;
+    const ProcessInfo& pinfo = *it->second;
+    fprintf(stream, "    {\"pid\": %d, \"name\": \"%s\", \"exe\": \"%s\"", pid,
+            pinfo.name(), pinfo.exe());
+    fprintf(stream, ", \"threads\": [");
+    for (auto t = pinfo.threads()->begin(); t != pinfo.threads()->end();) {
+      fprintf(stream, "{\"tid\": %d, \"name\":\"%s\"", t->first,
+              t->second->name);
+      t++;
+      fprintf(stream, t != pinfo.threads()->end() ? "}, " : "}");
+    }
+    fprintf(stream, "]");
+
+    const ProcessMemoryStats* mem_info = pinfo.memory();
+    fprintf(stream, ", \"mem\": {\"vm\": %llu, \"rss\": %llu",
+            mem_info->virt_kb(), mem_info->rss_kb());
+    if (full_mem_stats) {
+      fprintf(stream,
+              ", \"pss\": %llu, \"swp\": %llu, \"pc\": %llu, \"pd\": %llu, "
+              "\"sc\": %llu, \"sd\": %llu",
+              mem_info->rss_kb(), mem_info->swapped_kb(),
+              mem_info->private_clean_kb(), mem_info->private_dirty_kb(),
+              mem_info->shared_clean_kb(), mem_info->shared_dirty_kb());
+    }
+    fprintf(stream, "}");
+
+    fprintf(stream,
+            ", \"oom\": {\"adj\": %d, \"score_adj\": %d, \"score\": %d}",
+            pinfo.oom_adj(), pinfo.oom_score_adj(), pinfo.oom_score());
+    fprintf(stream,
+            ", \"stat\": {\"minflt\": %lu, \"majflt\": %lu, "
+            "\"utime\": %lu, \"stime\": %lu }",
+            pinfo.minflt(), pinfo.majflt(), pinfo.utime(), pinfo.stime());
+    fprintf(stream, "}");
+    it++;
+    fprintf(stream, it != procs.end() ? ",\n" : "\n");
+  }
+  fprintf(stream, "  ]\n");
+  fprintf(stream, "}\n");
+}
+
+}  // namespace
+
+int main(int argc, char** argv) {
+  bool background = false;
+  int dump_interval_ms = 5000;
+  char out_file[PATH_MAX] = {};
+  bool dump_to_file = false;
+  bool full_mem_stats = false;
+  int count = std::numeric_limits<int>::max();
+  int opt;
+  while ((opt = getopt(argc, argv, "bmt:o:c:")) != -1) {
+    switch (opt) {
+      case 'b':
+        background = true;
+        break;
+      case 'm':
+        full_mem_stats = true;
+        break;
+      case 't':
+        dump_interval_ms = atoi(optarg);
+        CHECK(dump_interval_ms > 0);
+        break;
+      case 'c':
+        count = atoi(optarg);
+        CHECK(count > 0);
+        break;
+      case 'o':
+        strncpy(out_file, optarg, sizeof(out_file));
+        dump_to_file = true;
+        break;
+      default:
+        fprintf(stderr,
+                "Usage: %s [-b] [-t dump_interval_ms] [-c dumps_count] "
+                "[-o out.json]\n",
+                argv[0]);
+        exit(EXIT_FAILURE);
+    }
+  }
+
+  if (geteuid()) {
+    fprintf(stderr, "Must run as root\n");
+    exit(EXIT_FAILURE);
+  }
+
+  FILE* out_stream = stdout;
+  char tmp_file[PATH_MAX];
+  if (dump_to_file) {
+    unlink(out_file);
+    sprintf(tmp_file, "%s.tmp", out_file);
+    out_stream = fopen(tmp_file, "w");
+    CHECK(out_stream);
+  }
+
+  if (background) {
+    if (!dump_to_file) {
+      fprintf(stderr, "-b requires -o for output dump path\n");
+      exit(EXIT_FAILURE);
+    }
+    printf("Continuing in background. kill -TERM to terminate the daemon.\n");
+    CHECK(daemon(0 /* nochdir */, 0 /* noclose */) == 0);
+  }
+
+  g_timer = timerfd_create(CLOCK_MONOTONIC, 0);
+  CHECK(g_timer >= 0);
+  struct itimerspec ts = {};
+  ts.it_value.tv_nsec = 1;  // Get the first snapshot immediately.
+  ts.it_interval.tv_nsec = (dump_interval_ms % 1000) * 1000000ul;
+  ts.it_interval.tv_sec = dump_interval_ms / 1000;
+  CHECK(timerfd_settime(g_timer, 0, &ts, nullptr) == 0);
+
+  // Closing the g_timer fd on SIGINT/SIGTERM will cause the read() below to
+  // unblock and fail with EBADF, hence allowing the loop below to finalize
+  // the file and exit.
+  auto on_exit = [](int) { close(g_timer); };
+  signal(SIGINT, on_exit);
+  signal(SIGTERM, on_exit);
+
+  fprintf(out_stream, "{\"snapshots\": [\n");
+  bool is_first_snapshot = true;
+  for (; count > 0; count--) {
+    uint64_t missed = 0;
+    int res = read(g_timer, &missed, sizeof(missed));
+    if (res < 0 && errno == EBADF)
+      break;  // Received SIGINT/SIGTERM signal.
+    CHECK(res > 0);
+    if (!is_first_snapshot)
+      fprintf(out_stream, ",");
+    is_first_snapshot = false;
+
+    std::unique_ptr<ProcessMap> procs = CollectStatsForAllProcs(full_mem_stats);
+    SerializeSnapshot(*procs, out_stream, full_mem_stats);
+    fflush(out_stream);
+  }
+  fprintf(out_stream, "]}\n");
+  fclose(out_stream);
+  if (dump_to_file)
+    rename(tmp_file, out_file);
+}
diff --git a/catapult/systrace/atrace_helper/jni/process_info.cc b/catapult/systrace/atrace_helper/jni/process_info.cc
new file mode 100644
index 0000000..172217b
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/process_info.cc
@@ -0,0 +1,102 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "process_info.h"
+
+#include <ctype.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+
+#include "file_utils.h"
+#include "logging.h"
+
+ProcessInfo::ProcessInfo(int pid) : memory_(pid), pid_(pid) {}
+
+bool ProcessInfo::IsProcess(int pid) {
+  char buf[256];
+  ssize_t rsize = file_utils::ReadProcFile(pid, "status", buf, sizeof(buf));
+  if (rsize <= 0)
+    return false;
+  const char kTgid[] = "\nTgid:";
+  const char* tgid_line = strstr(buf, kTgid);
+  CHECK(tgid_line);
+  int tgid = 0;
+  if (sscanf(tgid_line + strlen(kTgid), "%d", &tgid) != 1)
+    CHECK(false);
+  return tgid == pid;
+}
+
+bool ProcessInfo::ReadProcessName() {
+  if (!file_utils::ReadProcFileTrimmed(pid_, "cmdline", name_, sizeof(name_)))
+    return false;
+
+  // Fallback on "comm" for kernel threads.
+  if (strlen(name_) == 0) {
+    if (!file_utils::ReadProcFileTrimmed(pid_, "comm", name_, sizeof(name_)))
+      return false;
+  }
+
+  // Get also the exe path, to distinguish system vs java apps and bitness.
+  char exe_path[64];
+  sprintf(exe_path, "/proc/%d/exe", pid_);
+  exe_[0] = '\0';
+  ssize_t res = readlink(exe_path, exe_, sizeof(exe_) - 1);
+  if (res >= 0)
+    exe_[res] = '\0';
+
+  return true;
+}
+
+bool ProcessInfo::ReadThreadNames() {
+  char tasks_path[64];
+  sprintf(tasks_path, "/proc/%d/task", pid_);
+  CHECK(threads_.empty());
+  ThreadInfoMap* threads = &threads_;
+  const int pid = pid_;
+  file_utils::ForEachPidInProcPath(tasks_path, [pid, threads](int tid) {
+    char comm[64];
+    std::unique_ptr<ThreadInfo> thread_info(new ThreadInfo());
+    sprintf(comm, "task/%d/comm", tid);
+    if (!file_utils::ReadProcFileTrimmed(pid, comm, thread_info->name,
+                                         sizeof(thread_info->name))) {
+      return;
+    }
+    (*threads)[tid] = std::move(thread_info);
+  });
+  return true;
+}
+
+bool ProcessInfo::ReadOOMStats() {
+  char buf[512];
+  if (file_utils::ReadProcFileTrimmed(pid_, "oom_adj", buf, sizeof(buf)))
+    oom_adj_ = atoi(buf);
+  else
+    return false;
+
+  if (file_utils::ReadProcFileTrimmed(pid_, "oom_score", buf, sizeof(buf)))
+    oom_score_ = atoi(buf);
+  else
+    return false;
+
+  if (file_utils::ReadProcFileTrimmed(pid_, "oom_score_adj", buf, sizeof(buf)))
+    oom_score_adj_ = atoi(buf);
+  else
+    return false;
+
+  return true;
+}
+
+bool ProcessInfo::ReadPageFaultsAndCPUTimeStats() {
+  char buf[512];
+  if (!file_utils::ReadProcFileTrimmed(pid_, "stat", buf, sizeof(buf)))
+    return false;
+  int ret = sscanf(buf,
+                   "%*d (%*[^)]) %*c %*d %*d %*d %*d %*d %*u %lu %*lu "
+                   "%lu %*lu %lu %lu %*ld %*ld %*ld %*ld %*ld %*ld %llu",
+                   &minflt_, &majflt_, &utime_, &stime_, &start_time_);
+  CHECK(ret == 5);
+  return true;
+}
diff --git a/catapult/systrace/atrace_helper/jni/process_info.h b/catapult/systrace/atrace_helper/jni/process_info.h
new file mode 100644
index 0000000..ff05b33
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/process_info.h
@@ -0,0 +1,71 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PROCESS_INFO_H_
+#define PROCESS_INFO_H_
+
+#include <map>
+#include <memory>
+
+#include "process_memory_stats.h"
+
+// Reads various process stats and details from /proc/pid/.
+class ProcessInfo {
+ public:
+  struct ThreadInfo {
+    char name[128] = {};
+  };
+  using ThreadInfoMap = std::map<int, std::unique_ptr<ThreadInfo>>;
+
+  // Returns true if |pid| is a process (|pid| == TGID), false if it's just a
+  // thread of another process, or if |pid| doesn't exist at all.
+  static bool IsProcess(int pid);
+
+  explicit ProcessInfo(int pid);
+
+  bool ReadProcessName();
+  bool ReadThreadNames();
+  bool ReadOOMStats();
+  bool ReadPageFaultsAndCPUTimeStats();
+
+  ProcessMemoryStats* memory() { return &memory_; }
+  const ProcessMemoryStats* memory() const { return &memory_; }
+  const ThreadInfoMap* threads() const { return &threads_; }
+  const char* name() const { return name_; }
+  const char* exe() const { return exe_; }
+
+  int oom_adj() const { return oom_adj_; }
+  int oom_score_adj() const { return oom_score_adj_; }
+  int oom_score() const { return oom_score_; }
+
+  unsigned long minflt() const { return minflt_; }
+  unsigned long majflt() const { return majflt_; }
+  unsigned long utime() const { return utime_; }
+  unsigned long stime() const { return stime_; }
+  unsigned long long start_time() const { return start_time_; }
+
+ private:
+  ProcessInfo(const ProcessInfo&) = delete;
+  void operator=(const ProcessInfo&) = delete;
+
+  ProcessMemoryStats memory_;
+
+  ThreadInfoMap threads_;
+  char name_[128] = {};
+  char exe_[128] = {};
+
+  int oom_adj_ = 0;
+  int oom_score_adj_ = 0;
+  int oom_score_ = 0;
+
+  unsigned long minflt_ = 0;
+  unsigned long majflt_ = 0;
+  unsigned long utime_ = 0;            // CPU time in user mode.
+  unsigned long stime_ = 0;            // CPU time in kernel mode.
+  unsigned long long start_time_ = 0;  // CPU time in kernel mode.
+
+  const int pid_;
+};
+
+#endif  // PROCESS_INFO_H_
diff --git a/catapult/systrace/atrace_helper/jni/process_memory_stats.cc b/catapult/systrace/atrace_helper/jni/process_memory_stats.cc
new file mode 100644
index 0000000..516abea
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/process_memory_stats.cc
@@ -0,0 +1,132 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "process_memory_stats.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <memory>
+
+#include "file_utils.h"
+#include "logging.h"
+
+namespace {
+const int kKbPerPage = 4;
+
+// Takes a C string buffer and chunks it into lines without creating any
+// copies. It modifies the original buffer, by replacing \n with \0.
+class LineReader {
+ public:
+  LineReader(char* buf, size_t size) : ptr_(buf), end_(buf + size) {}
+
+  const char* NextLine() {
+    if (ptr_ >= end_)
+      return nullptr;
+    const char* cur = ptr_;
+    char* next = strchr(ptr_, '\n');
+    if (next) {
+      *next = '\0';
+      ptr_ = next + 1;
+    } else {
+      ptr_ = end_;
+    }
+    return cur;
+  }
+
+ private:
+  char* ptr_;
+  char* end_;
+};
+
+bool ReadSmapsMetric(const char* line, const char* metric, uint64_t* res) {
+  if (strncmp(line, metric, strlen(metric)))
+    return false;
+  line = strchr(line, ':');
+  if (!line)
+    return false;
+  *res = strtoull(line + 1, nullptr, 10);
+  return true;
+}
+
+}  // namespace
+
+ProcessMemoryStats::ProcessMemoryStats(int pid) : pid_(pid) {}
+
+bool ProcessMemoryStats::ReadLightStats() {
+  char buf[64];
+  if (file_utils::ReadProcFile(pid_, "statm", buf, sizeof(buf)) <= 0)
+    return false;
+  uint32_t vm_size_pages;
+  uint32_t rss_pages;
+  int res = sscanf(buf, "%u %u", &vm_size_pages, &rss_pages);
+  CHECK(res == 2);
+  rss_kb_ = rss_pages * kKbPerPage;
+  virt_kb_ = vm_size_pages * kKbPerPage;
+  return true;
+}
+
+bool ProcessMemoryStats::ReadFullStats() {
+  const size_t kBufSize = 32u * 1024 * 1024;
+  std::unique_ptr<char[]> buf(new char[kBufSize]);
+  ssize_t rsize = file_utils::ReadProcFile(pid_, "smaps", &buf[0], kBufSize);
+  if (rsize <= 0)
+    return false;
+  MmapInfo* last_mmap_entry = nullptr;
+  std::unique_ptr<MmapInfo> new_mmap(new MmapInfo());
+  CHECK(mmaps_.empty());
+  CHECK(rss_kb_ == 0);
+
+  // Iterate over all lines in /proc/PID/smaps.
+  LineReader rd(&buf[0], rsize);
+  for (const char* line = rd.NextLine(); line; line = rd.NextLine()) {
+    // Check if the current line is the beginning of a new mmaps entry, e.g.:
+    // be7f7000-be818000 rw-p 00000000 00:00 0          [stack]
+    // Note that the mapped file name ([stack]) is optional and won't be
+    // present
+    // on anonymous memory maps (hence res >= 3 below).
+    int res = sscanf(
+        line, "%llx-%llx %4s %*llx %*[:0-9a-f] %*[0-9a-f]%*[ \t]%128[^\n]",
+        &new_mmap->start_addr, &new_mmap->end_addr, new_mmap->prot_flags,
+        new_mmap->mapped_file);
+    if (res >= 3) {
+      last_mmap_entry = new_mmap.get();
+      CHECK(new_mmap->end_addr >= new_mmap->start_addr);
+      new_mmap->virt_kb = (new_mmap->end_addr - new_mmap->start_addr) / 1024;
+      if (res == 3)
+        new_mmap->mapped_file[0] = '\0';
+      virt_kb_ += new_mmap->virt_kb;
+      mmaps_[new_mmap->start_addr] = std::move(new_mmap);
+      new_mmap.reset(new MmapInfo());
+    } else {
+      // The current line is a metrics line within a mmap entry, e.g.:
+      // Size:   4 kB
+      uint64_t size = 0;
+      CHECK(last_mmap_entry);
+      if (ReadSmapsMetric(line, "Rss:", &size)) {
+        last_mmap_entry->rss_kb = size;
+        rss_kb_ += size;
+      } else if (ReadSmapsMetric(line, "Pss:", &size)) {
+        last_mmap_entry->pss_kb = size;
+        pss_kb_ += size;
+      } else if (ReadSmapsMetric(line, "Swap:", &size)) {
+        last_mmap_entry->swapped_kb = size;
+        swapped_kb_ += size;
+      } else if (ReadSmapsMetric(line, "Shared_Clean:", &size)) {
+        last_mmap_entry->shared_clean_kb = size;
+        shared_clean_kb_ += size;
+      } else if (ReadSmapsMetric(line, "Shared_Dirty:", &size)) {
+        last_mmap_entry->shared_dirty_kb = size;
+        shared_dirty_kb_ += size;
+      } else if (ReadSmapsMetric(line, "Private_Clean:", &size)) {
+        last_mmap_entry->private_clean_kb = size;
+        private_clean_kb_ += size;
+      } else if (ReadSmapsMetric(line, "Private_Dirty:", &size)) {
+        last_mmap_entry->private_dirty_kb = size;
+        private_dirty_kb_ += size;
+      }
+    }
+  }
+  return true;
+}
diff --git a/catapult/systrace/atrace_helper/jni/process_memory_stats.h b/catapult/systrace/atrace_helper/jni/process_memory_stats.h
new file mode 100644
index 0000000..180c41c
--- /dev/null
+++ b/catapult/systrace/atrace_helper/jni/process_memory_stats.h
@@ -0,0 +1,68 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PROCESS_MEMORY_STATS_H_
+#define PROCESS_MEMORY_STATS_H_
+
+#include <stdint.h>
+
+#include <map>
+#include <memory>
+
+// Reads process memory stats from /proc/pid/{statm,smaps}.
+class ProcessMemoryStats {
+ public:
+  struct MmapInfo {
+    char mapped_file[128] = {};
+    char prot_flags[5] = {};
+    uint64_t start_addr = 0;
+    uint64_t end_addr = 0;
+    uint64_t virt_kb = 0;
+    uint64_t pss_kb = 0;  // Proportional Set Size.
+    uint64_t rss_kb = 0;  // Resident Set Size.
+    uint64_t private_clean_kb = 0;
+    uint64_t private_dirty_kb = 0;
+    uint64_t shared_clean_kb = 0;
+    uint64_t shared_dirty_kb = 0;
+    uint64_t swapped_kb = 0;
+  };
+
+  explicit ProcessMemoryStats(int pid);
+
+  bool ReadLightStats();
+  bool ReadFullStats();
+
+  // Available after ReadLightStats().
+  uint64_t virt_kb() const { return virt_kb_; }
+  uint64_t rss_kb() const { return rss_kb_; }
+
+  // Available after ReadFullStats().
+  uint64_t private_clean_kb() const { return private_clean_kb_; }
+  uint64_t private_dirty_kb() const { return private_dirty_kb_; }
+  uint64_t shared_clean_kb() const { return shared_clean_kb_; }
+  uint64_t shared_dirty_kb() const { return shared_dirty_kb_; }
+  uint64_t swapped_kb() const { return swapped_kb_; }
+
+ private:
+  ProcessMemoryStats(const ProcessMemoryStats&) = delete;
+  void operator=(const ProcessMemoryStats&) = delete;
+
+  const int pid_;
+
+  // Light stats.
+  uint64_t virt_kb_ = 0;
+  uint64_t rss_kb_ = 0;
+
+  // Full stats.
+  uint64_t pss_kb_ = 0;
+  uint64_t private_clean_kb_ = 0;
+  uint64_t private_dirty_kb_ = 0;
+  uint64_t shared_clean_kb_ = 0;
+  uint64_t shared_dirty_kb_ = 0;
+  uint64_t swapped_kb_ = 0;
+
+  std::map<uintptr_t, std::unique_ptr<MmapInfo>> mmaps_;
+};
+
+#endif  // PROCESS_MEMORY_STATS_H_
diff --git a/catapult/systrace/bin/OWNERS b/catapult/systrace/bin/OWNERS
deleted file mode 100644
index 374072a..0000000
--- a/catapult/systrace/bin/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-per-file adb_profile_chrome=file://systrace/profile_chrome/OWNERS
-per-file adb_profile_chrome_startup=file://systrace/profile_chrome/OWNERS
-
-per-file systrace=file://systrace/systrace/OWNERS
-
-ccraik@google.com
diff --git a/catapult/systrace/profile_chrome/OWNERS b/catapult/systrace/profile_chrome/OWNERS
deleted file mode 100644
index 51a6670..0000000
--- a/catapult/systrace/profile_chrome/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-skyostil@chromium.org
-zhenw@chromium.org
diff --git a/catapult/systrace/systrace/OWNERS b/catapult/systrace/systrace/OWNERS
deleted file mode 100644
index a007f0a..0000000
--- a/catapult/systrace/systrace/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-ccraik@google.com
diff --git a/catapult/systrace/systrace/__init__.py b/catapult/systrace/systrace/__init__.py
index 34f9e1f..831f774 100644
--- a/catapult/systrace/systrace/__init__.py
+++ b/catapult/systrace/systrace/__init__.py
@@ -25,4 +25,4 @@
 _AddDirToPythonPath(_CATAPULT_DIR, 'common', 'py_trace_event', 'py_trace_event')
 _AddDirToPythonPath(_CATAPULT_DIR, 'devil')
 _AddDirToPythonPath(_CATAPULT_DIR, 'systrace')
-_AddDirToPythonPath(_CATAPULT_DIR, 'telemetry')
+_AddDirToPythonPath(_CATAPULT_DIR, 'tracing')
diff --git a/catapult/systrace/systrace/output_generator.py b/catapult/systrace/systrace/output_generator.py
index f0ff06a..553d5d4 100644
--- a/catapult/systrace/systrace/output_generator.py
+++ b/catapult/systrace/systrace/output_generator.py
@@ -12,6 +12,7 @@
 
 from systrace import tracing_controller
 from systrace import trace_result
+from tracing.trace_data import trace_data
 
 
 # TODO(alexandermont): Current version of trace viewer does not support
@@ -20,6 +21,24 @@
 # trace viewer is working again.
 OUTPUT_CONTROLLER_TRACE_ = False
 CONTROLLER_TRACE_DATA_KEY = 'controllerTraceDataKey'
+_SYSTRACE_TO_TRACE_DATA_NAME_MAPPING = {
+    'androidProcessDump': trace_data.ANDROID_PROCESS_DATA_PART,
+    'systemTraceEvents': trace_data.ATRACE_PART,
+    'powerTraceAsString': trace_data.BATTOR_TRACE_PART,
+    'systraceController': trace_data.TELEMETRY_PART,
+    'traceEvents': trace_data.CHROME_TRACE_PART,
+    'waltTrace': trace_data.WALT_TRACE_PART,
+}
+_SYSTRACE_HEADER = 'Systrace'
+
+
+def NewGenerateHTMLOutput(trace_results, output_file_name):
+  trace_data_builder = trace_data.TraceDataBuilder()
+  for trace in trace_results:
+    trace_data_part = _SYSTRACE_TO_TRACE_DATA_NAME_MAPPING.get(
+        trace.source_name)
+    trace_data_builder.AddTraceFor(trace_data_part, trace.raw_data)
+  trace_data_builder.AsData().Serialize(output_file_name, _SYSTRACE_HEADER)
 
 
 def GenerateHTMLOutput(trace_results, output_file_name):
@@ -33,6 +52,18 @@
   def _ReadAsset(src_dir, filename):
     return open(os.path.join(src_dir, filename)).read()
 
+  # TODO(rnephew): The tracing output formatter is able to handle a single
+  # systrace trace just as well as it handles multiple traces. The obvious thing
+  # to do here would be to use it all for all systrace output: however, we want
+  # to continue using the legacy way of formatting systrace output when a single
+  # systrace and the tracing controller trace are present in order to match the
+  # Java verison of systrace. Java systrace is expected to be deleted at a later
+  # date. We should consolidate this logic when that happens.
+
+  if len(trace_results) > 3:
+    NewGenerateHTMLOutput(trace_results, output_file_name)
+    return os.path.abspath(output_file_name)
+
   systrace_dir = os.path.abspath(os.path.dirname(__file__))
 
   try:
@@ -63,9 +94,6 @@
   # for each tracing agent (including the controller tracing agent).
   html_file.write('<!-- BEGIN TRACE -->\n')
   for result in trace_results:
-    if (result.source_name == tracing_controller.TRACE_DATA_CONTROLLER_NAME and
-        not OUTPUT_CONTROLLER_TRACE_):
-      continue
     html_file.write('  <script class="trace-data" type="application/text">\n')
     html_file.write(_ConvertToHtmlString(result.raw_data))
     html_file.write('  </script>\n')
@@ -102,8 +130,6 @@
   results = _ConvertTraceListToDictionary(trace_results)
   results[CONTROLLER_TRACE_DATA_KEY] = (
       tracing_controller.TRACE_DATA_CONTROLLER_NAME)
-  if not OUTPUT_CONTROLLER_TRACE_:
-    results[tracing_controller.TRACE_DATA_CONTROLLER_NAME] = []
   with open(output_file_name, 'w') as json_file:
     json.dump(results, json_file)
   final_path = os.path.abspath(output_file_name)
diff --git a/catapult/systrace/systrace/output_generator_unittest.py b/catapult/systrace/systrace/output_generator_unittest.py
index 9b74ed1..58e11ac 100644
--- a/catapult/systrace/systrace/output_generator_unittest.py
+++ b/catapult/systrace/systrace/output_generator_unittest.py
@@ -4,6 +4,7 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+import hashlib
 import json
 import os
 import unittest
@@ -13,10 +14,12 @@
 from systrace import trace_result
 from systrace import update_systrace_trace_viewer
 from systrace import util
+from tracing.trace_data import trace_data as trace_data_module
 
 
 TEST_DIR = os.path.join(os.path.dirname(__file__), 'test_data')
 ATRACE_DATA = os.path.join(TEST_DIR, 'atrace_data')
+BATTOR_DATA = os.path.join(TEST_DIR, 'battor_test_data.txt')
 COMBINED_PROFILE_CHROME_DATA = os.path.join(
     TEST_DIR, 'profile-chrome_systrace_perf_chrome_data')
 
@@ -70,30 +73,51 @@
 
   @decorators.HostOnlyTest
   def testHtmlOutputGenerationFormatsMultipleTraces(self):
-    update_systrace_trace_viewer.update(force_update=True)
-    self.assertTrue(os.path.exists(
-        update_systrace_trace_viewer.SYSTRACE_TRACE_VIEWER_HTML_FILE))
-    json_data = open(COMBINED_PROFILE_CHROME_DATA).read()
-    combined_data = json.loads(json_data)
     trace_results = []
-    trace_results_expected = []
-    for (trace_name, data) in combined_data.iteritems():
-      trace_results.append(trace_result.TraceResult(str(trace_name),
-                                                    str(data)))
-      trace_results_expected.append(str(data).replace(" ", "").strip())
-    output_file_name = util.generate_random_filename_for_test()
-    final_path = output_generator.GenerateHTMLOutput(trace_results,
-                                                     output_file_name)
-    with open(output_file_name, 'r') as f:
-      html_output = f.read()
-      for i in range(1, len(trace_results)):
-        trace_data = (html_output.split(
-          '<script class="trace-data" type="application/text">')[i].split(
-          '</script>'))[0].replace(" ", "").strip()
+    trace_data_builder = trace_data_module.TraceDataBuilder()
 
-        # Ensure the trace data written in HTML is located within the
-        # correct place in the HTML document and that the data is not
-        # malformed.
-        self.assertTrue(trace_data in trace_results_expected)
-    os.remove(final_path)
-    os.remove(update_systrace_trace_viewer.SYSTRACE_TRACE_VIEWER_HTML_FILE)
+    with open(BATTOR_DATA) as fp:
+      battor_data = fp.read()
+    trace_results.append(
+        trace_result.TraceResult('powerTraceAsString', battor_data))
+    trace_data_builder.AddTraceFor(
+        trace_data_module.BATTOR_TRACE_PART, battor_data)
+
+    with open(ATRACE_DATA) as fp:
+      atrace_data = fp.read()
+    trace_results.append(
+        trace_result.TraceResult('systemTraceEvents', atrace_data))
+    trace_data_builder.AddTraceFor(trace_data_module.ATRACE_PART, atrace_data)
+
+
+    with open(COMBINED_PROFILE_CHROME_DATA) as fp:
+      chrome_data = fp.read()
+    trace_results.append(
+        trace_result.TraceResult('traceEvents', json.loads(chrome_data)))
+    trace_data_builder.AddTraceFor(
+        trace_data_module.CHROME_TRACE_PART, json.loads(chrome_data))
+
+    trace_results.append(
+        trace_result.TraceResult('systraceController', str({})))
+    trace_data_builder.AddTraceFor(trace_data_module.TELEMETRY_PART, {})
+
+    try:
+      data_builder_out = util.generate_random_filename_for_test()
+      output_generator_out = util.generate_random_filename_for_test()
+      output_generator.GenerateHTMLOutput(trace_results, output_generator_out)
+      trace_data_builder.AsData().Serialize(data_builder_out, 'Systrace')
+
+      output_generator_md5sum = hashlib.md5(
+          open(output_generator_out, 'rb').read()).hexdigest()
+      data_builder_md5sum = hashlib.md5(
+          open(data_builder_out, 'rb').read()).hexdigest()
+
+      self.assertEqual(output_generator_md5sum, data_builder_md5sum)
+    finally:
+      def del_if_exist(path):
+        try:
+          os.remove(path)
+        except IOError:
+          pass
+      del_if_exist(output_generator_out)
+      del_if_exist(data_builder_out)
diff --git a/catapult/systrace/systrace/run_systrace.py b/catapult/systrace/systrace/run_systrace.py
index 1bf9e8d..78673bd 100755
--- a/catapult/systrace/systrace/run_systrace.py
+++ b/catapult/systrace/systrace/run_systrace.py
@@ -45,9 +45,11 @@
 from systrace.tracing_agents import atrace_from_file_agent
 from systrace.tracing_agents import battor_trace_agent
 from systrace.tracing_agents import ftrace_agent
+from systrace.tracing_agents import walt_agent
+
 
 ALL_MODULES = [atrace_agent, atrace_from_file_agent,
-               battor_trace_agent, ftrace_agent]
+               battor_trace_agent, ftrace_agent, walt_agent]
 
 
 def parse_options(argv):
diff --git a/catapult/systrace/systrace/systrace_runner.py b/catapult/systrace/systrace/systrace_runner.py
index c3452d1..d8b9883 100644
--- a/catapult/systrace/systrace/systrace_runner.py
+++ b/catapult/systrace/systrace/systrace_runner.py
@@ -10,15 +10,16 @@
 
 from systrace import output_generator
 from systrace import tracing_controller
+from systrace.tracing_agents import android_process_data_agent
 from systrace.tracing_agents import atrace_agent
 from systrace.tracing_agents import atrace_from_file_agent
 from systrace.tracing_agents import battor_trace_agent
 from systrace.tracing_agents import ftrace_agent
+from systrace.tracing_agents import walt_agent
 
-
-AGENT_MODULES = [atrace_agent, atrace_from_file_agent,
-                 battor_trace_agent, ftrace_agent]
-
+AGENT_MODULES = [android_process_data_agent, atrace_agent,
+                 atrace_from_file_agent, battor_trace_agent,
+                 ftrace_agent, walt_agent]
 
 class SystraceRunner(object):
   def __init__(self, script_dir, options):
diff --git a/catapult/systrace/systrace/systrace_trace_viewer.html b/catapult/systrace/systrace/systrace_trace_viewer.html
index b651314..2b042be 100644
--- a/catapult/systrace/systrace/systrace_trace_viewer.html
+++ b/catapult/systrace/systrace/systrace_trace_viewer.html
@@ -3215,216 +3215,18 @@
       <tr-ui-b-grouping-table id="table"></tr-ui-b-grouping-table>
     </table-container>
   </template>
-</dom-module><dom-module id="tr-v-ui-histogram-set-table-cell">
-  <template>
-    <style>
-    #histogram_container {
-      display: flex;
-      flex-direction: row;
-    }
-
-    #missing, #empty, #unmergeable, #scalar {
-      flex-grow: 1;
-    }
-
-    #open_histogram, #close_histogram {
-      height: 1em;
-    }
-
-    #open_histogram {
-      margin-left: 4px;
-      stroke-width: 0;
-      stroke: blue;
-      fill: blue;
-    }
-    :host(:hover) #open_histogram {
-      background: blue;
-      stroke: white;
-      fill: white;
-    }
-
-    #scalar {
-      flex-grow: 1;
-      white-space: nowrap;
-    }
-
-    #histogram {
-      flex-grow: 1;
-    }
-
-    #close_histogram line {
-      stroke-width: 18;
-      stroke: black;
-    }
-    #close_histogram:hover {
-      background: black;
-    }
-    #close_histogram:hover line {
-      stroke: white;
-    }
-
-    #overview_container {
-      display: none;
-    }
-    </style>
-
-    <div id="histogram_container">
-      <span id="missing">(missing)</span>
-      <span id="empty">(empty)</span>
-      <span id="unmergeable">(unmergeable)</span>
-
-      <tr-v-ui-scalar-span id="scalar" on-click="openHistogram_"></tr-v-ui-scalar-span>
-
-      <svg id="open_histogram" on-click="openHistogram_" viewBox="0 0 128 128">
-        <rect height="16" width="32" x="16" y="24"></rect>
-        <rect height="16" width="96" x="16" y="56"></rect>
-        <rect height="16" width="64" x="16" y="88"></rect>
-      </svg>
-
-      <span id="histogram"></span>
-
-      <svg id="close_histogram" on-click="closeHistogram_" viewBox="0 0 128 128">
-        <line x1="28" x2="100" y1="28" y2="100"></line>
-        <line x1="28" x2="100" y1="100" y2="28"></line>
-      </svg>
-    </div>
-
-    <div id="overview_container">
-    </div>
-  </template>
-</dom-module><dom-module id="tr-v-ui-histogram-set-table-name-cell">
-  <template>
-    <style>
-    #name_container {
-      display: flex;
-    }
-
-    #name {
-      overflow: hidden;
-      white-space: nowrap;
-      text-overflow: ellipsis;
-    }
-
-    #show_overview, #hide_overview {
-      height: 1em;
-      margin-left: 5px;
-    }
-
-    #show_overview {
-      stroke: blue;
-      stroke-width: 16;
-    }
-
-    #show_overview:hover {
-      background: blue;
-      stroke: white;
-    }
-
-    #hide_overview {
-      display: none;
-      stroke-width: 18;
-      stroke: black;
-    }
-
-    #hide_overview:hover {
-      background: black;
-      stroke: white;
-    }
-
-    #open_histograms, #close_histograms {
-      height: 1em;
-    }
-
-    #open_histograms {
-      margin-left: 4px;
-      stroke-width: 0;
-      stroke: blue;
-      fill: blue;
-    }
-    :host(:hover) #open_histograms {
-      background: blue;
-      stroke: white;
-      fill: white;
-    }
-
-    #close_histograms line {
-      stroke-width: 18;
-      stroke: black;
-    }
-    #close_histograms:hover {
-      background: black;
-    }
-    #close_histograms:hover line {
-      stroke: white;
-    }
-
-    #overview_container {
-      display: none;
-    }
-    </style>
-
-    <div id="name_container">
-      <span id="name"></span>
-      <svg id="show_overview" on-click="showOverview_" viewBox="0 0 128 128">
-        <line x1="19" x2="49" y1="109" y2="49"></line>
-        <line x1="49" x2="79" y1="49" y2="79"></line>
-        <line x1="79" x2="109" y1="79" y2="19"></line>
-      </svg>
-
-      <svg id="hide_overview" on-click="hideOverview_" viewBox="0 0 128 128">
-        <line x1="28" x2="100" y1="28" y2="100"></line>
-        <line x1="28" x2="100" y1="100" y2="28"></line>
-      </svg>
-
-      <svg id="open_histograms" on-click="openHistograms_" viewBox="0 0 128 128">
-        <rect height="16" width="32" x="16" y="24"></rect>
-        <rect height="16" width="96" x="16" y="56"></rect>
-        <rect height="16" width="64" x="16" y="88"></rect>
-      </svg>
-
-      <svg id="close_histograms" on-click="closeHistograms_" viewBox="0 0 128 128">
-        <line x1="28" x2="100" y1="28" y2="100"></line>
-        <line x1="28" x2="100" y1="100" y2="28"></line>
-      </svg>
-    </div>
-
-    <div id="overview_container">
-    </div>
-  </template>
-</dom-module><dom-module id="tr-v-ui-histogram-set-table">
+</dom-module><dom-module id="tr-v-ui-histogram-set-controls">
   <template>
     <style>
     :host {
       display: block;
     }
 
-    #container {
-      flex-direction: column;
-      display: none;
-    }
-
-    table-container {
-      margin-top: 5px;
-      display: flex;
-      min-height: 0px;
-      overflow: auto;
-    }
-
-    #help {
+    #help, #feedback {
       display: none;
       margin-left: 20px;
     }
 
-    #zero {
-      color: red;
-      /* histogram-set-table is used by both metrics-side-panel and results2.html.
-       * This font-size rule has no effect in results2.html, but improves
-       * legibility in the metrics-side-panel, which sets font-size in order to
-       * make this table denser.
-       */
-      font-size: initial;
-    }
-
     #search {
       max-width: 20em;
       margin-right: 20px;
@@ -3460,11 +3262,13 @@
       stroke: white;
     }
 
-    #reference_column_container * {
+    #reference_display_label {
+      display: none;
       margin-right: 20px;
     }
 
-    #statistic_container * {
+    #statistic {
+      display: none;
       margin-right: 20px;
     }
 
@@ -3473,51 +3277,278 @@
     }
     </style>
 
-    <div id="zero">zero Histograms</div>
+    <div id="controls">
+      <input id="search" placeholder="Find Histogram name" value="{{searchQuery::keyup}}"/>
 
-    <div id="container">
-      <div id="controls">
-        <input id="search" on-keyup="onSearch_" placeholder="Find Histogram name"/>
+      <svg id="show_overview" on-click="toggleOverviewLineCharts_" viewBox="0 0 128 128">
+        <line x1="19" x2="49" y1="109" y2="49"></line>
+        <line x1="49" x2="79" y1="49" y2="79"></line>
+        <line x1="79" x2="109" y1="79" y2="19"></line>
+      </svg>
+      <svg id="hide_overview" on-click="toggleOverviewLineCharts_" viewBox="0 0 128 128">
+        <line x1="28" x2="100" y1="28" y2="100"></line>
+        <line x1="28" x2="100" y1="100" y2="28"></line>
+      </svg>
 
-        <svg id="show_overview" on-click="showOverview_" viewBox="0 0 128 128">
+      <select id="reference_display_label" value="{{referenceDisplayLabel::change}}">
+        <option value="">Select a reference column</option>
+      </select>
+
+      <select id="statistic" value="{{displayStatisticName::change}}">
+      </select>
+
+      <button id="download_csv" on-click="downloadCSV_">⬇ CSV</button>
+
+      <input checked="{{showAll::change}}" id="show_all" title="When unchecked, less important histograms are hidden." type="checkbox"/>
+      <label for="show_all" title="When unchecked, less important histograms are hidden.">Show all</label>
+
+      <a id="help">Help</a>
+      <a id="feedback">Feedback</a>
+    </div>
+
+    <tr-ui-b-grouping-table-groupby-picker id="picker">
+    </tr-ui-b-grouping-table-groupby-picker>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table-cell">
+  <template>
+    <style>
+    #histogram_container {
+      display: flex;
+      flex-direction: row;
+    }
+
+    #missing, #empty, #unmergeable, #scalar {
+      flex-grow: 1;
+    }
+
+    #open_histogram, #close_histogram, #open_histogram svg, #close_histogram svg {
+      height: 1em;
+    }
+
+    #open_histogram svg {
+      margin-left: 4px;
+      stroke-width: 0;
+      stroke: blue;
+      fill: blue;
+    }
+    :host(:hover) #open_histogram svg {
+      background: blue;
+      stroke: white;
+      fill: white;
+    }
+
+    #scalar {
+      flex-grow: 1;
+      white-space: nowrap;
+    }
+
+    #histogram {
+      flex-grow: 1;
+    }
+
+    #close_histogram svg line {
+      stroke-width: 18;
+      stroke: black;
+    }
+    #close_histogram:hover svg {
+      background: black;
+    }
+    #close_histogram:hover svg line {
+      stroke: white;
+    }
+
+    #overview_container {
+      display: none;
+    }
+    </style>
+
+    <div id="histogram_container">
+      <span id="missing">(missing)</span>
+      <span id="empty">(empty)</span>
+      <span id="unmergeable">(unmergeable)</span>
+
+      <tr-v-ui-scalar-span id="scalar" on-click="openHistogram_"></tr-v-ui-scalar-span>
+
+      <span id="open_histogram" on-click="openHistogram_">
+        <svg viewBox="0 0 128 128">
+          <rect height="16" width="32" x="16" y="24"></rect>
+          <rect height="16" width="96" x="16" y="56"></rect>
+          <rect height="16" width="64" x="16" y="88"></rect>
+        </svg>
+      </span>
+
+      <span id="histogram"></span>
+
+      <span id="close_histogram" on-click="closeHistogram_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+    </div>
+
+    <div id="overview_container">
+    </div>
+  </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table-name-cell">
+  <template>
+    <style>
+    #name_container {
+      display: flex;
+    }
+
+    #name {
+      overflow: hidden;
+      white-space: nowrap;
+      text-overflow: ellipsis;
+    }
+
+    #show_overview, #hide_overview, #show_overview svg, #hide_overview svg {
+      height: 1em;
+      margin-left: 5px;
+    }
+
+    #show_overview svg {
+      stroke: blue;
+      stroke-width: 16;
+    }
+
+    #show_overview:hover svg {
+      background: blue;
+      stroke: white;
+    }
+
+    #hide_overview {
+      display: none;
+    }
+
+    #hide_overview svg {
+      stroke-width: 18;
+      stroke: black;
+    }
+
+    #hide_overview:hover svg {
+      background: black;
+      stroke: white;
+    }
+
+    #open_histograms, #close_histograms, #open_histograms svg, #close_histograms svg {
+      height: 1em;
+    }
+
+    #close_histograms {
+      display: none;
+    }
+
+    #open_histograms svg {
+      margin-left: 4px;
+      stroke-width: 0;
+      stroke: blue;
+      fill: blue;
+    }
+    #open_histograms:hover svg {
+      background: blue;
+      stroke: white;
+      fill: white;
+    }
+
+    #close_histograms line {
+      stroke-width: 18;
+      stroke: black;
+    }
+    #close_histograms:hover {
+      background: black;
+    }
+    #close_histograms:hover line {
+      stroke: white;
+    }
+
+    #overview_container {
+      display: none;
+    }
+    </style>
+
+    <div id="name_container">
+      <span id="name"></span>
+
+      <span id="show_overview" on-click="showOverview_">
+        <svg viewBox="0 0 128 128">
           <line x1="19" x2="49" y1="109" y2="49"></line>
           <line x1="49" x2="79" y1="49" y2="79"></line>
           <line x1="79" x2="109" y1="79" y2="19"></line>
         </svg>
-        <svg id="hide_overview" on-click="hideOverview_" viewBox="0 0 128 128">
+      </span>
+
+      <span id="hide_overview" on-click="hideOverview_">
+        <svg viewBox="0 0 128 128">
           <line x1="28" x2="100" y1="28" y2="100"></line>
           <line x1="28" x2="100" y1="100" y2="28"></line>
         </svg>
+      </span>
 
-        <span id="reference_column_container"></span>
+      <span id="open_histograms" on-click="openHistograms_">
+        <svg viewBox="0 0 128 128">
+          <rect height="16" width="32" x="16" y="24"></rect>
+          <rect height="16" width="96" x="16" y="56"></rect>
+          <rect height="16" width="64" x="16" y="88"></rect>
+        </svg>
+      </span>
 
-        <span id="statistic_container"></span>
+      <span id="close_histograms" on-click="closeHistograms_">
+        <svg viewBox="0 0 128 128">
+          <line x1="28" x2="100" y1="28" y2="100"></line>
+          <line x1="28" x2="100" y1="100" y2="28"></line>
+        </svg>
+      </span>
+    </div>
 
-        <button id="download_csv" on-click="downloadCSV_">⬇ CSV</button>
-
-        <input id="show_all" on-change="onShowAllChange_" title="When unchecked, less important histograms are hidden." type="checkbox"/>
-        <label for="show_all" title="When unchecked, less important histograms are hidden.">Show all</label>
-
-        <a id="help">Help</a>
-      </div>
-
-      <tr-ui-b-grouping-table-groupby-picker id="picker">
-      </tr-ui-b-grouping-table-groupby-picker>
-
-      <table-container>
-        <tr-ui-b-table id="table">
-      </tr-ui-b-table></table-container>
+    <div id="overview_container">
     </div>
   </template>
+</dom-module><dom-module id="tr-v-ui-histogram-set-table">
+  <template>
+    <style>
+    :host {
+      min-height: 0px;
+      overflow: auto;
+    }
+    #table {
+      margin-top: 5px;
+    }
+    </style>
+
+    <tr-ui-b-table id="table">
+  </tr-ui-b-table></template>
 </dom-module><dom-module id="tr-v-ui-histogram-set-view">
   <template>
     <style>
     :host {
       font-family: sans-serif;
     }
+
+    #zero {
+      color: red;
+      /* histogram-set-table is used by both metrics-side-panel and results2.html.
+       * This font-size rule has no effect in results2.html, but improves
+       * legibility in the metrics-side-panel, which sets font-size in order to
+       * make this table denser.
+       */
+      font-size: initial;
+    }
+
+    #container {
+      display: none;
+    }
     </style>
 
-    <tr-v-ui-histogram-set-table id="histograms"></tr-v-ui-histogram-set-table>
+    <div id="zero">zero Histograms</div>
+
+    <div id="container">
+      <tr-v-ui-histogram-set-controls id="controls">
+      </tr-v-ui-histogram-set-controls>
+
+      <tr-v-ui-histogram-set-table id="table"></tr-v-ui-histogram-set-table>
+    </div>
   </template>
 </dom-module><dom-module id="tr-ui-sp-metrics-side-panel">
   <template>
@@ -3574,50 +3605,66 @@
 
 'use strict';if(window.Polymer){throw new Error('Cannot proceed. Polymer already present.');}
 window.Polymer={};window.Polymer.dom='shadow';(function(){function resolve(){document.body.removeAttribute('unresolved');}
-if(window.WebComponents){addEventListener('WebComponentsReady',resolve);}else{if(document.readyState==='interactive'||document.readyState==='complete'){resolve();}else{addEventListener('DOMContentLoaded',resolve);}}}());window.Polymer={Settings:function(){var settings=window.Polymer||{};var parts=location.search.slice(1).split('&');for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split('=');o[0]&&(settings[o[0]]=o[1]||true);}
-settings.wantShadow=settings.dom==='shadow';settings.hasShadow=Boolean(Element.prototype.createShadowRoot);settings.nativeShadow=settings.hasShadow&&!window.ShadowDOMPolyfill;settings.useShadow=settings.wantShadow&&settings.hasShadow;settings.hasNativeImports=Boolean('import'in document.createElement('link'));settings.useNativeImports=settings.hasNativeImports;settings.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;settings.useNativeShadow=settings.useShadow&&settings.nativeShadow;settings.usePolyfillProto=!settings.useNativeCustomElements&&!Object.__proto__;settings.hasNativeCSSProperties=!navigator.userAgent.match('AppleWebKit/601')&&window.CSS&&CSS.supports&&CSS.supports('box-shadow','0 0 0 var(--foo)');settings.useNativeCSSProperties=settings.hasNativeCSSProperties&&settings.lazyRegister&&settings.useNativeCSSProperties;return settings;}()};(function(){var userPolymer=window.Polymer;window.Polymer=function(prototype){if(typeof prototype==='function'){prototype=prototype.prototype;}
+if(window.WebComponents){addEventListener('WebComponentsReady',resolve);}else{if(document.readyState==='interactive'||document.readyState==='complete'){resolve();}else{addEventListener('DOMContentLoaded',resolve);}}}());window.Polymer={Settings:function(){var settings=window.Polymer||{};if(!settings.noUrlSettings){var parts=location.search.slice(1).split('&');for(var i=0,o;i<parts.length&&(o=parts[i]);i++){o=o.split('=');o[0]&&(settings[o[0]]=o[1]||true);}}
+settings.wantShadow=settings.dom==='shadow';settings.hasShadow=Boolean(Element.prototype.createShadowRoot);settings.nativeShadow=settings.hasShadow&&!window.ShadowDOMPolyfill;settings.useShadow=settings.wantShadow&&settings.hasShadow;settings.hasNativeImports=Boolean('import'in document.createElement('link'));settings.useNativeImports=settings.hasNativeImports;settings.useNativeCustomElements=!window.CustomElements||window.CustomElements.useNative;settings.useNativeShadow=settings.useShadow&&settings.nativeShadow;settings.usePolyfillProto=!settings.useNativeCustomElements&&!Object.__proto__;settings.hasNativeCSSProperties=!navigator.userAgent.match('AppleWebKit/601')&&window.CSS&&CSS.supports&&CSS.supports('box-shadow','0 0 0 var(--foo)');settings.useNativeCSSProperties=settings.hasNativeCSSProperties&&settings.lazyRegister&&settings.useNativeCSSProperties;settings.isIE=navigator.userAgent.match('Trident');return settings;}()};(function(){var userPolymer=window.Polymer;window.Polymer=function(prototype){if(typeof prototype==='function'){prototype=prototype.prototype;}
 if(!prototype){prototype={};}
-var factory=desugar(prototype);prototype=factory.prototype;var options={prototype:prototype};if(prototype.extends){options.extends=prototype.extends;}
-Polymer.telemetry._registrate(prototype);document.registerElement(prototype.is,options);return factory;};var desugar=function(prototype){var base=Polymer.Base;if(prototype.extends){base=Polymer.Base._getExtendedPrototype(prototype.extends);}
-prototype=Polymer.Base.chainObject(prototype,base);prototype.registerCallback();return prototype.constructor;};if(userPolymer){for(var i in userPolymer){Polymer[i]=userPolymer[i];}}
-Polymer.Class=desugar;}());Polymer.telemetry={registrations:[],_regLog:function(prototype){console.log('['+prototype.is+']: registered');},_registrate:function(prototype){this.registrations.push(prototype);Polymer.log&&this._regLog(prototype);},dumpRegistrations:function(){this.registrations.forEach(this._regLog);}};Object.defineProperty(window,'currentImport',{enumerable:true,configurable:true,get:function(){return(document._currentScript||document.currentScript).ownerDocument;}});Polymer.RenderStatus={_ready:false,_callbacks:[],whenReady:function(cb){if(this._ready){cb();}else{this._callbacks.push(cb);}},_makeReady:function(){this._ready=true;for(var i=0;i<this._callbacks.length;i++){this._callbacks[i]();}
+prototype=desugar(prototype);var customCtor=prototype===prototype.constructor.prototype?prototype.constructor:null;var options={prototype:prototype};if(prototype.extends){options.extends=prototype.extends;}
+Polymer.telemetry._registrate(prototype);var ctor=document.registerElement(prototype.is,options);return customCtor||ctor;};var desugar=function(prototype){var base=Polymer.Base;if(prototype.extends){base=Polymer.Base._getExtendedPrototype(prototype.extends);}
+prototype=Polymer.Base.chainObject(prototype,base);prototype.registerCallback();return prototype;};if(userPolymer){for(var i in userPolymer){Polymer[i]=userPolymer[i];}}
+Polymer.Class=function(prototype){if(!prototype.factoryImpl){prototype.factoryImpl=function(){};}
+return desugar(prototype).constructor;};}());Polymer.telemetry={registrations:[],_regLog:function(prototype){console.log('['+prototype.is+']: registered');},_registrate:function(prototype){this.registrations.push(prototype);Polymer.log&&this._regLog(prototype);},dumpRegistrations:function(){this.registrations.forEach(this._regLog);}};Object.defineProperty(window,'currentImport',{enumerable:true,configurable:true,get:function(){return(document._currentScript||document.currentScript||{}).ownerDocument;}});Polymer.RenderStatus={_ready:false,_callbacks:[],whenReady:function(cb){if(this._ready){cb();}else{this._callbacks.push(cb);}},_makeReady:function(){this._ready=true;for(var i=0;i<this._callbacks.length;i++){this._callbacks[i]();}
 this._callbacks=[];},_catchFirstRender:function(){requestAnimationFrame(function(){Polymer.RenderStatus._makeReady();});},_afterNextRenderQueue:[],_waitingNextRender:false,afterNextRender:function(element,fn,args){this._watchNextRender();this._afterNextRenderQueue.push([element,fn,args]);},hasRendered:function(){return this._ready;},_watchNextRender:function(){if(!this._waitingNextRender){this._waitingNextRender=true;var fn=function(){Polymer.RenderStatus._flushNextRender();};if(!this._ready){this.whenReady(fn);}else{requestAnimationFrame(fn);}}},_flushNextRender:function(){var self=this;setTimeout(function(){self._flushRenderCallbacks(self._afterNextRenderQueue);self._afterNextRenderQueue=[];self._waitingNextRender=false;});},_flushRenderCallbacks:function(callbacks){for(var i=0,h;i<callbacks.length;i++){h=callbacks[i];h[1].apply(h[0],h[2]||Polymer.nar);}}};if(window.HTMLImports){HTMLImports.whenReady(function(){Polymer.RenderStatus._catchFirstRender();});}else{Polymer.RenderStatus._catchFirstRender();}
-Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;(function(){'use strict';var settings=Polymer.Settings;Polymer.Base={__isPolymerInstance__:true,_addFeature:function(feature){this.extend(this,feature);},registerCallback:function(){this._desugarBehaviors();this._doBehavior('beforeRegister');this._registerFeatures();if(!settings.lazyRegister){this.ensureRegisterFinished();}},createdCallback:function(){if(!this.__hasRegisterFinished){this._ensureRegisterFinished(this.__proto__);}
-Polymer.telemetry.instanceCount++;this.root=this;this._doBehavior('created');this._initFeatures();},ensureRegisterFinished:function(){this._ensureRegisterFinished(this);},_ensureRegisterFinished:function(proto){if(proto.__hasRegisterFinished!==proto.is){proto.__hasRegisterFinished=proto.is;if(proto._finishRegisterFeatures){proto._finishRegisterFeatures();}
-proto._doBehavior('registered');if(settings.usePolyfillProto&&proto!==this){proto.extend(this,proto);}}},attachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=true;self._doBehavior('attached');});},detachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=false;self._doBehavior('detached');});},attributeChangedCallback:function(name,oldValue,newValue){this._attributeChangedImpl(name);this._doBehavior('attributeChanged',[name,oldValue,newValue]);},_attributeChangedImpl:function(name){this._setAttributeToProperty(this,name);},extend:function(prototype,api){if(prototype&&api){var n$=Object.getOwnPropertyNames(api);for(var i=0,n;i<n$.length&&(n=n$[i]);i++){this.copyOwnProperty(n,api,prototype);}}
-return prototype||api;},mixin:function(target,source){for(var i in source){target[i]=source[i];}
+Polymer.ImportStatus=Polymer.RenderStatus;Polymer.ImportStatus.whenLoaded=Polymer.ImportStatus.whenReady;(function(){'use strict';var settings=Polymer.Settings;Polymer.Base={__isPolymerInstance__:true,_addFeature:function(feature){this.mixin(this,feature);},registerCallback:function(){if(settings.lazyRegister==='max'){if(this.beforeRegister){this.beforeRegister();}}else{this._desugarBehaviors();for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.beforeRegister){b.beforeRegister.call(this);}}
+if(this.beforeRegister){this.beforeRegister();}}
+this._registerFeatures();if(!settings.lazyRegister){this.ensureRegisterFinished();}},createdCallback:function(){if(settings.disableUpgradeEnabled){if(this.hasAttribute('disable-upgrade')){this._propertySetter=disableUpgradePropertySetter;this._configValue=null;this.__data__={};return;}else{this.__hasInitialized=true;}}
+this.__initialize();},__initialize:function(){if(!this.__hasRegisterFinished){this._ensureRegisterFinished(this.__proto__);}
+Polymer.telemetry.instanceCount++;this.root=this;for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.created){b.created.call(this);}}
+if(this.created){this.created();}
+this._initFeatures();},ensureRegisterFinished:function(){this._ensureRegisterFinished(this);},_ensureRegisterFinished:function(proto){if(proto.__hasRegisterFinished!==proto.is||!proto.is){if(settings.lazyRegister==='max'){proto._desugarBehaviors();for(var i=0,b;i<proto.behaviors.length;i++){b=proto.behaviors[i];if(b.beforeRegister){b.beforeRegister.call(proto);}}}
+proto.__hasRegisterFinished=proto.is;if(proto._finishRegisterFeatures){proto._finishRegisterFeatures();}
+for(var j=0,pb;j<proto.behaviors.length;j++){pb=proto.behaviors[j];if(pb.registered){pb.registered.call(proto);}}
+if(proto.registered){proto.registered();}
+if(settings.usePolyfillProto&&proto!==this){proto.extend(this,proto);}}},attachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=true;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.attached){b.attached.call(self);}}
+if(self.attached){self.attached();}});},detachedCallback:function(){var self=this;Polymer.RenderStatus.whenReady(function(){self.isAttached=false;for(var i=0,b;i<self.behaviors.length;i++){b=self.behaviors[i];if(b.detached){b.detached.call(self);}}
+if(self.detached){self.detached();}});},attributeChangedCallback:function(name,oldValue,newValue){this._attributeChangedImpl(name);for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.attributeChanged){b.attributeChanged.call(this,name,oldValue,newValue);}}
+if(this.attributeChanged){this.attributeChanged(name,oldValue,newValue);}},_attributeChangedImpl:function(name){this._setAttributeToProperty(this,name);},extend:function(target,source){if(target&&source){var n$=Object.getOwnPropertyNames(source);for(var i=0,n;i<n$.length&&(n=n$[i]);i++){this.copyOwnProperty(n,source,target);}}
+return target||source;},mixin:function(target,source){for(var i in source){target[i]=source[i];}
 return target;},copyOwnProperty:function(name,source,target){var pd=Object.getOwnPropertyDescriptor(source,name);if(pd){Object.defineProperty(target,name,pd);}},_logger:function(level,args){if(args.length===1&&Array.isArray(args[0])){args=args[0];}
 switch(level){case'log':case'warn':case'error':console[level].apply(console,args);break;}},_log:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('log',args);},_warn:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('warn',args);},_error:function(){var args=Array.prototype.slice.call(arguments,0);this._logger('error',args);},_logf:function(){return this._logPrefix.concat(this.is).concat(Array.prototype.slice.call(arguments,0));}};Polymer.Base._logPrefix=function(){var color=window.chrome&&!/edge/i.test(navigator.userAgent)||/firefox/i.test(navigator.userAgent);return color?['%c[%s::%s]:','font-weight: bold; background-color:#EEEE00;']:['[%s::%s]:'];}();Polymer.Base.chainObject=function(object,inherited){if(object&&inherited&&object!==inherited){if(!Object.__proto__){object=Polymer.Base.extend(Object.create(inherited),object);}
 object.__proto__=inherited;}
-return object;};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);if(window.CustomElements){Polymer.instanceof=CustomElements.instanceof;}else{Polymer.instanceof=function(obj,ctor){return obj instanceof ctor;};}
-Polymer.isInstance=function(obj){return Boolean(obj&&obj.__isPolymerInstance__);};Polymer.telemetry.instanceCount=0;}());(function(){var modules={};var lcModules={};var findModule=function(id){return modules[id]||lcModules[id.toLowerCase()];};var DomModule=function(){return document.createElement('dom-module');};DomModule.prototype=Object.create(HTMLElement.prototype);Polymer.Base.extend(DomModule.prototype,{constructor:DomModule,createdCallback:function(){this.register();},register:function(id){id=id||this.id||this.getAttribute('name')||this.getAttribute('is');if(id){this.id=id;modules[id]=this;lcModules[id.toLowerCase()]=this;}},import:function(id,selector){if(id){var m=findModule(id);if(!m){forceDomModulesUpgrade();m=findModule(id);}
+return object;};Polymer.Base=Polymer.Base.chainObject(Polymer.Base,HTMLElement.prototype);Polymer.BaseDescriptors={};var disableUpgradePropertySetter;if(settings.disableUpgradeEnabled){disableUpgradePropertySetter=function(property,value){this.__data__[property]=value;};var origAttributeChangedCallback=Polymer.Base.attributeChangedCallback;Polymer.Base.attributeChangedCallback=function(name,oldValue,newValue){if(!this.__hasInitialized&&name==='disable-upgrade'){this.__hasInitialized=true;this._propertySetter=Polymer.Bind._modelApi._propertySetter;this._configValue=Polymer.Base._configValue;this.__initialize();}
+origAttributeChangedCallback.call(this,name,oldValue,newValue);};}
+if(window.CustomElements){Polymer.instanceof=CustomElements.instanceof;}else{Polymer.instanceof=function(obj,ctor){return obj instanceof ctor;};}
+Polymer.isInstance=function(obj){return Boolean(obj&&obj.__isPolymerInstance__);};Polymer.telemetry.instanceCount=0;}());(function(){var modules={};var lcModules={};var findModule=function(id){return modules[id]||lcModules[id.toLowerCase()];};var DomModule=function(){return document.createElement('dom-module');};DomModule.prototype=Object.create(HTMLElement.prototype);Polymer.Base.mixin(DomModule.prototype,{createdCallback:function(){this.register();},register:function(id){id=id||this.id||this.getAttribute('name')||this.getAttribute('is');if(id){this.id=id;modules[id]=this;lcModules[id.toLowerCase()]=this;}},import:function(id,selector){if(id){var m=findModule(id);if(!m){forceDomModulesUpgrade();m=findModule(id);}
 if(m&&selector){m=m.querySelector(selector);}
-return m;}}});var cePolyfill=window.CustomElements&&!CustomElements.useNative;document.registerElement('dom-module',DomModule);function forceDomModulesUpgrade(){if(cePolyfill){var script=document._currentScript||document.currentScript;var doc=script&&script.ownerDocument||document;var modules=doc.querySelectorAll('dom-module');for(var i=modules.length-1,m;i>=0&&(m=modules[i]);i--){if(m.__upgraded__){return;}else{CustomElements.upgrade(m);}}}}}());Polymer.Base._addFeature({_prepIs:function(){if(!this.is){var module=(document._currentScript||document.currentScript).parentNode;if(module.localName==='dom-module'){var id=module.id||module.getAttribute('name')||module.getAttribute('is');this.is=id;}}
+return m;}}});Object.defineProperty(DomModule.prototype,'constructor',{value:DomModule,configurable:true,writable:true});var cePolyfill=window.CustomElements&&!CustomElements.useNative;document.registerElement('dom-module',DomModule);function forceDomModulesUpgrade(){if(cePolyfill){var script=document._currentScript||document.currentScript;var doc=script&&script.ownerDocument||document;var modules=doc.querySelectorAll('dom-module');for(var i=modules.length-1,m;i>=0&&(m=modules[i]);i--){if(m.__upgraded__){return;}else{CustomElements.upgrade(m);}}}}}());Polymer.Base._addFeature({_prepIs:function(){if(!this.is){var module=(document._currentScript||document.currentScript).parentNode;if(module.localName==='dom-module'){var id=module.id||module.getAttribute('name')||module.getAttribute('is');this.is=id;}}
 if(this.is){this.is=this.is.toLowerCase();}}});Polymer.Base._addFeature({behaviors:[],_desugarBehaviors:function(){if(this.behaviors.length){this.behaviors=this._desugarSomeBehaviors(this.behaviors);}},_desugarSomeBehaviors:function(behaviors){var behaviorSet=[];behaviors=this._flattenBehaviorsList(behaviors);for(var i=behaviors.length-1;i>=0;i--){var b=behaviors[i];if(behaviorSet.indexOf(b)===-1){this._mixinBehavior(b);behaviorSet.unshift(b);}}
 return behaviorSet;},_flattenBehaviorsList:function(behaviors){var flat=[];for(var i=0;i<behaviors.length;i++){var b=behaviors[i];if(b instanceof Array){flat=flat.concat(this._flattenBehaviorsList(b));}else if(b){flat.push(b);}else{this._warn(this._logf('_flattenBehaviorsList','behavior is null, check for missing or 404 import'));}}
-return flat;},_mixinBehavior:function(b){var n$=Object.getOwnPropertyNames(b);for(var i=0,n;i<n$.length&&(n=n$[i]);i++){if(!Polymer.Base._behaviorProperties[n]&&!this.hasOwnProperty(n)){this.copyOwnProperty(n,b,this);}}},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors);},_prepFlattenedBehaviors:function(behaviors){for(var i=0,l=behaviors.length;i<l;i++){this._prepBehavior(behaviors[i]);}
-this._prepBehavior(this);},_doBehavior:function(name,args){for(var i=0;i<this.behaviors.length;i++){this._invokeBehavior(this.behaviors[i],name,args);}
-this._invokeBehavior(this,name,args);},_invokeBehavior:function(b,name,args){var fn=b[name];if(fn){fn.apply(this,args||Polymer.nar);}},_marshalBehaviors:function(){for(var i=0;i<this.behaviors.length;i++){this._marshalBehavior(this.behaviors[i]);}
-this._marshalBehavior(this);}});Polymer.Base._behaviorProperties={hostAttributes:true,beforeRegister:true,registered:true,properties:true,observers:true,listeners:true,created:true,attached:true,detached:true,attributeChanged:true,ready:true};Polymer.Base._addFeature({_getExtendedPrototype:function(tag){return this._getExtendedNativePrototype(tag);},_nativePrototypes:{},_getExtendedNativePrototype:function(tag){var p=this._nativePrototypes[tag];if(!p){var np=this.getNativePrototype(tag);p=this.extend(Object.create(np),Polymer.Base);this._nativePrototypes[tag]=p;}
+return flat;},_mixinBehavior:function(b){var n$=Object.getOwnPropertyNames(b);var useAssignment=b._noAccessors;for(var i=0,n;i<n$.length&&(n=n$[i]);i++){if(!Polymer.Base._behaviorProperties[n]&&!this.hasOwnProperty(n)){if(useAssignment){this[n]=b[n];}else{this.copyOwnProperty(n,b,this);}}}},_prepBehaviors:function(){this._prepFlattenedBehaviors(this.behaviors);},_prepFlattenedBehaviors:function(behaviors){for(var i=0,l=behaviors.length;i<l;i++){this._prepBehavior(behaviors[i]);}
+this._prepBehavior(this);},_marshalBehaviors:function(){for(var i=0;i<this.behaviors.length;i++){this._marshalBehavior(this.behaviors[i]);}
+this._marshalBehavior(this);}});Polymer.Base._behaviorProperties={hostAttributes:true,beforeRegister:true,registered:true,properties:true,observers:true,listeners:true,created:true,attached:true,detached:true,attributeChanged:true,ready:true,_noAccessors:true};Polymer.Base._addFeature({_getExtendedPrototype:function(tag){return this._getExtendedNativePrototype(tag);},_nativePrototypes:{},_getExtendedNativePrototype:function(tag){var p=this._nativePrototypes[tag];if(!p){p=Object.create(this.getNativePrototype(tag));var p$=Object.getOwnPropertyNames(Polymer.Base);for(var i=0,n;i<p$.length&&(n=p$[i]);i++){if(!Polymer.BaseDescriptors[n]){p[n]=Polymer.Base[n];}}
+Object.defineProperties(p,Polymer.BaseDescriptors);this._nativePrototypes[tag]=p;}
 return p;},getNativePrototype:function(tag){return Object.getPrototypeOf(document.createElement(tag));}});Polymer.Base._addFeature({_prepConstructor:function(){this._factoryArgs=this.extends?[this.extends,this.is]:[this.is];var ctor=function(){return this._factory(arguments);};if(this.hasOwnProperty('extends')){ctor.extends=this.extends;}
 Object.defineProperty(this,'constructor',{value:ctor,writable:true,configurable:true});ctor.prototype=this;},_factory:function(args){var elt=document.createElement.apply(document,this._factoryArgs);if(this.factoryImpl){this.factoryImpl.apply(elt,args);}
-return elt;}});Polymer.nob=Object.create(null);Polymer.Base._addFeature({properties:{},getPropertyInfo:function(property){var info=this._getPropertyInfo(property,this.properties);if(!info){for(var i=0;i<this.behaviors.length;i++){info=this._getPropertyInfo(property,this.behaviors[i].properties);if(info){return info;}}}
+return elt;}});Polymer.nob=Object.create(null);Polymer.Base._addFeature({getPropertyInfo:function(property){var info=this._getPropertyInfo(property,this.properties);if(!info){for(var i=0;i<this.behaviors.length;i++){info=this._getPropertyInfo(property,this.behaviors[i].properties);if(info){return info;}}}
 return info||Polymer.nob;},_getPropertyInfo:function(property,properties){var p=properties&&properties[property];if(typeof p==='function'){p=properties[property]={type:p};}
 if(p){p.defined=true;}
 return p;},_prepPropertyInfo:function(){this._propertyInfo={};for(var i=0;i<this.behaviors.length;i++){this._addPropertyInfo(this._propertyInfo,this.behaviors[i].properties);}
 this._addPropertyInfo(this._propertyInfo,this.properties);this._addPropertyInfo(this._propertyInfo,this._propertyEffects);},_addPropertyInfo:function(target,source){if(source){var t,s;for(var i in source){t=target[i];s=source[i];if(i[0]==='_'&&!s.readOnly){continue;}
 if(!target[i]){target[i]={type:typeof s==='function'?s:s.type,readOnly:s.readOnly,attribute:Polymer.CaseMap.camelToDashCase(i)};}else{if(!t.type){t.type=s.type;}
-if(!t.readOnly){t.readOnly=s.readOnly;}}}}}});Polymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(dash){return this._caseMap[dash]||(this._caseMap[dash]=dash.indexOf('-')<0?dash:dash.replace(this._rx.dashToCamel,function(m){return m[1].toUpperCase();}));},camelToDashCase:function(camel){return this._caseMap[camel]||(this._caseMap[camel]=camel.replace(this._rx.camelToDash,'-$1').toLowerCase());}};Polymer.Base._addFeature({_addHostAttributes:function(attributes){if(!this._aggregatedAttributes){this._aggregatedAttributes={};}
+if(!t.readOnly){t.readOnly=s.readOnly;}}}}}});(function(){var propertiesDesc={configurable:true,writable:true,enumerable:true,value:{}};Polymer.BaseDescriptors.properties=propertiesDesc;Object.defineProperty(Polymer.Base,'properties',propertiesDesc);}());Polymer.CaseMap={_caseMap:{},_rx:{dashToCamel:/-[a-z]/g,camelToDash:/([A-Z])/g},dashToCamelCase:function(dash){return this._caseMap[dash]||(this._caseMap[dash]=dash.indexOf('-')<0?dash:dash.replace(this._rx.dashToCamel,function(m){return m[1].toUpperCase();}));},camelToDashCase:function(camel){return this._caseMap[camel]||(this._caseMap[camel]=camel.replace(this._rx.camelToDash,'-$1').toLowerCase());}};Polymer.Base._addFeature({_addHostAttributes:function(attributes){if(!this._aggregatedAttributes){this._aggregatedAttributes={};}
 if(attributes){this.mixin(this._aggregatedAttributes,attributes);}},_marshalHostAttributes:function(){if(this._aggregatedAttributes){this._applyAttributes(this,this._aggregatedAttributes);}},_applyAttributes:function(node,attr$){for(var n in attr$){if(!this.hasAttribute(n)&&n!=='class'){var v=attr$[n];this.serializeValueToAttribute(v,n,this);}}},_marshalAttributes:function(){this._takeAttributesToModel(this);},_takeAttributesToModel:function(model){if(this.hasAttributes()){for(var i in this._propertyInfo){var info=this._propertyInfo[i];if(this.hasAttribute(info.attribute)){this._setAttributeToProperty(model,info.attribute,i,info);}}}},_setAttributeToProperty:function(model,attribute,property,info){if(!this._serializing){property=property||Polymer.CaseMap.dashToCamelCase(attribute);info=info||this._propertyInfo&&this._propertyInfo[property];if(info&&!info.readOnly){var v=this.getAttribute(attribute);model[property]=this.deserialize(v,info.type);}}},_serializing:false,reflectPropertyToAttribute:function(property,attribute,value){this._serializing=true;value=value===undefined?this[property]:value;this.serializeValueToAttribute(value,attribute||Polymer.CaseMap.camelToDashCase(property));this._serializing=false;},serializeValueToAttribute:function(value,attribute,node){var str=this.serialize(value);node=node||this;if(str===undefined){node.removeAttribute(attribute);}else{node.setAttribute(attribute,str);}},deserialize:function(value,type){switch(type){case Number:value=Number(value);break;case Boolean:value=value!=null;break;case Object:try{value=JSON.parse(value);}catch(x){}
 break;case Array:try{value=JSON.parse(value);}catch(x){value=null;console.warn('Polymer::Attributes: couldn`t decode Array as JSON');}
 break;case Date:value=new Date(value);break;case String:default:break;}
 return value;},serialize:function(value){switch(typeof value){case'boolean':return value?'':undefined;case'object':if(value instanceof Date){return value.toString();}else if(value){try{return JSON.stringify(value);}catch(x){return'';}}
-default:return value!=null?value:undefined;}}});Polymer.version='1.6.0';Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_marshalBehavior:function(b){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors();}});Polymer.Base._addFeature({_prepTemplate:function(){if(this._template===undefined){this._template=Polymer.DomModule.import(this.is,'template');}
+default:return value!=null?value:undefined;}}});Polymer.version="1.8.1";Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_marshalBehavior:function(b){},_initFeatures:function(){this._marshalHostAttributes();this._marshalBehaviors();}});Polymer.Base._addFeature({_prepTemplate:function(){if(this._template===undefined){this._template=Polymer.DomModule.import(this.is,'template');}
 if(this._template&&this._template.hasAttribute('is')){this._warn(this._logf('_prepTemplate','top-level Polymer template '+'must not be a type-extension, found',this._template,'Move inside simple <template>.'));}
 if(this._template&&!this._template.content&&window.HTMLTemplateElement&&HTMLTemplateElement.decorate){HTMLTemplateElement.decorate(this._template);}},_stampTemplate:function(){if(this._template){this.root=this.instanceTemplate(this._template);}},instanceTemplate:function(template){var dom=document.importNode(template._content||template.content,true);return dom;}});(function(){var baseAttachedCallback=Polymer.Base.attachedCallback;Polymer.Base._addFeature({_hostStack:[],ready:function(){},_registerHost:function(host){this.dataHost=host=host||Polymer.Base._hostStack[Polymer.Base._hostStack.length-1];if(host&&host._clients){host._clients.push(this);}
 this._clients=null;this._clientsReadied=false;},_beginHosting:function(){Polymer.Base._hostStack.push(this);if(!this._clients){this._clients=[];}},_endHosting:function(){Polymer.Base._hostStack.pop();},_tryReady:function(){this._readied=false;if(this._canReady()){this._ready();}},_canReady:function(){return!this.dataHost||this.dataHost._clientsReadied;},_ready:function(){this._beforeClientsReady();if(this._template){this._setupRoot();this._readyClients();}
 this._clientsReadied=true;this._clients=null;this._afterClientsReady();this._readySelf();},_readyClients:function(){this._beginDistribute();var c$=this._clients;if(c$){for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){c._ready();}}
-this._finishDistribute();},_readySelf:function(){this._doBehavior('ready');this._readied=true;if(this._attachedPending){this._attachedPending=false;this.attachedCallback();}},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){if(this._readied){this._beforeAttached();baseAttachedCallback.call(this);}else{this._attachedPending=true;}}});}());Polymer.ArraySplice=function(){function newSplice(index,removed,addedCount){return{index:index,removed:removed,addedCount:addedCount};}
+this._finishDistribute();},_readySelf:function(){for(var i=0,b;i<this.behaviors.length;i++){b=this.behaviors[i];if(b.ready){b.ready.call(this);}}
+if(this.ready){this.ready();}
+this._readied=true;if(this._attachedPending){this._attachedPending=false;this.attachedCallback();}},_beforeClientsReady:function(){},_afterClientsReady:function(){},_beforeAttached:function(){},attachedCallback:function(){if(this._readied){this._beforeAttached();baseAttachedCallback.call(this);}else{this._attachedPending=true;}}});}());Polymer.ArraySplice=function(){function newSplice(index,removed,addedCount){return{index:index,removed:removed,addedCount:addedCount};}
 var EDIT_LEAVE=0;var EDIT_UPDATE=1;var EDIT_ADD=2;var EDIT_DELETE=3;function ArraySplice(){}
 ArraySplice.prototype={calcEditDistances:function(current,currentStart,currentEnd,old,oldStart,oldEnd){var rowCount=oldEnd-oldStart+1;var columnCount=currentEnd-currentStart+1;var distances=new Array(rowCount);for(var i=0;i<rowCount;i++){distances[i]=new Array(columnCount);distances[i][0]=i;}
 for(var j=0;j<columnCount;j++)
@@ -3680,7 +3727,7 @@
 if(halter&&halter(result)){return result;}
 this._queryElements(TreeApi.Logical.getChildNodes(node),matcher,halter,list);}};var CONTENT=DomApi.CONTENT='content';var dom=DomApi.factory=function(node){node=node||document;if(!node.__domApi){node.__domApi=new DomApi.ctor(node);}
 return node.__domApi;};DomApi.hasApi=function(node){return Boolean(node.__domApi);};DomApi.ctor=DomApi;Polymer.dom=function(obj,patch){if(obj instanceof Event){return Polymer.EventApi.factory(obj);}else{return DomApi.factory(obj,patch);}};var p=Element.prototype;DomApi.matchesSelector=p.matches||p.matchesSelector||p.mozMatchesSelector||p.msMatchesSelector||p.oMatchesSelector||p.webkitMatchesSelector;return DomApi;}();(function(){'use strict';var Settings=Polymer.Settings;var DomApi=Polymer.DomApi;var dom=DomApi.factory;var TreeApi=Polymer.TreeApi;var getInnerHTML=Polymer.domInnerHTML.getInnerHTML;var CONTENT=DomApi.CONTENT;if(Settings.useShadow){return;}
-var nativeCloneNode=Element.prototype.cloneNode;var nativeImportNode=Document.prototype.importNode;Polymer.Base.extend(DomApi.prototype,{_lazyDistribute:function(host){if(host.shadyRoot&&host.shadyRoot._distributionClean){host.shadyRoot._distributionClean=false;Polymer.dom.addDebouncer(host.debounce('_distribute',host._distributeContent));}},appendChild:function(node){return this.insertBefore(node);},insertBefore:function(node,ref_node){if(ref_node&&TreeApi.Logical.getParentNode(ref_node)!==this.node){throw Error('The ref_node to be inserted before is not a child '+'of this node');}
+var nativeCloneNode=Element.prototype.cloneNode;var nativeImportNode=Document.prototype.importNode;Polymer.Base.mixin(DomApi.prototype,{_lazyDistribute:function(host){if(host.shadyRoot&&host.shadyRoot._distributionClean){host.shadyRoot._distributionClean=false;Polymer.dom.addDebouncer(host.debounce('_distribute',host._distributeContent));}},appendChild:function(node){return this.insertBefore(node);},insertBefore:function(node,ref_node){if(ref_node&&TreeApi.Logical.getParentNode(ref_node)!==this.node){throw Error('The ref_node to be inserted before is not a child '+'of this node');}
 if(node.nodeType!==Node.DOCUMENT_FRAGMENT_NODE){var parent=TreeApi.Logical.getParentNode(node);if(parent){if(DomApi.hasApi(parent)){dom(parent).notifyObserver();}
 this._removeNode(node);}else{this._removeOwnerShadyRoot(node);}}
 if(!this._addNode(node,ref_node)){if(ref_node){ref_node=ref_node.localName===CONTENT?this._firstComposedNode(ref_node):ref_node;}
@@ -3711,8 +3758,8 @@
 var activeRoot=dom(active).getOwnerRoot();while(activeRoot&&activeRoot!==this.node){active=activeRoot.host;activeRoot=dom(active).getOwnerRoot();}
 if(this.node===document){return activeRoot?null:active;}else{return activeRoot===this.node?active:null;}},configurable:true},childNodes:{get:function(){var c$=TreeApi.Logical.getChildNodes(this.node);return Array.isArray(c$)?c$:TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){if(TreeApi.Logical.hasChildNodes(this.node)){return Array.prototype.filter.call(this.childNodes,function(n){return n.nodeType===Node.ELEMENT_NODE;});}else{return TreeApi.arrayCopyChildren(this.node);}},configurable:true},parentNode:{get:function(){return TreeApi.Logical.getParentNode(this.node);},configurable:true},firstChild:{get:function(){return TreeApi.Logical.getFirstChild(this.node);},configurable:true},lastChild:{get:function(){return TreeApi.Logical.getLastChild(this.node);},configurable:true},nextSibling:{get:function(){return TreeApi.Logical.getNextSibling(this.node);},configurable:true},previousSibling:{get:function(){return TreeApi.Logical.getPreviousSibling(this.node);},configurable:true},firstElementChild:{get:function(){return TreeApi.Logical.getFirstElementChild(this.node);},configurable:true},lastElementChild:{get:function(){return TreeApi.Logical.getLastElementChild(this.node);},configurable:true},nextElementSibling:{get:function(){return TreeApi.Logical.getNextElementSibling(this.node);},configurable:true},previousElementSibling:{get:function(){return TreeApi.Logical.getPreviousElementSibling(this.node);},configurable:true},textContent:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){return this.node.textContent;}else{var tc=[];for(var i=0,cn=this.childNodes,c;c=cn[i];i++){if(c.nodeType!==Node.COMMENT_NODE){tc.push(c.textContent);}}
 return tc.join('');}},set:function(text){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){this.node.textContent=text;}else{this._clear();if(text){this.appendChild(document.createTextNode(text));}}},configurable:true},innerHTML:{get:function(){var nt=this.node.nodeType;if(nt===Node.TEXT_NODE||nt===Node.COMMENT_NODE){return null;}else{return getInnerHTML(this.node);}},set:function(text){var nt=this.node.nodeType;if(nt!==Node.TEXT_NODE||nt!==Node.COMMENT_NODE){this._clear();var d=document.createElement('div');d.innerHTML=text;var c$=TreeApi.arrayCopyChildNodes(d);for(var i=0;i<c$.length;i++){this.appendChild(c$[i]);}}},configurable:true}});DomApi.hasInsertionPoint=function(root){return Boolean(root&&root._insertionPoints.length);};}());(function(){'use strict';var Settings=Polymer.Settings;var TreeApi=Polymer.TreeApi;var DomApi=Polymer.DomApi;if(!Settings.useShadow){return;}
-Polymer.Base.extend(DomApi.prototype,{querySelectorAll:function(selector){return TreeApi.arrayCopy(this.node.querySelectorAll(selector));},getOwnerRoot:function(){var n=this.node;while(n){if(n.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&n.host){return n;}
-n=n.parentNode;}},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;return doc.importNode(externalNode,deep);},getDestinationInsertionPoints:function(){var n$=this.node.getDestinationInsertionPoints&&this.node.getDestinationInsertionPoints();return n$?TreeApi.arrayCopy(n$):[];},getDistributedNodes:function(){var n$=this.node.getDistributedNodes&&this.node.getDistributedNodes();return n$?TreeApi.arrayCopy(n$):[];}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var node=DomApi.wrap(this.node);var activeElement=node.activeElement;return node.contains(activeElement)?activeElement:null;},configurable:true},childNodes:{get:function(){return TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){return TreeApi.arrayCopyChildren(this.node);},configurable:true},textContent:{get:function(){return this.node.textContent;},set:function(value){return this.node.textContent=value;},configurable:true},innerHTML:{get:function(){return this.node.innerHTML;},set:function(value){return this.node.innerHTML=value;},configurable:true}});var forwardMethods=function(m$){for(var i=0;i<m$.length;i++){forwardMethod(m$[i]);}};var forwardMethod=function(method){DomApi.prototype[method]=function(){return this.node[method].apply(this.node,arguments);};};forwardMethods(['cloneNode','appendChild','insertBefore','removeChild','replaceChild','setAttribute','removeAttribute','querySelector']);var forwardProperties=function(f$){for(var i=0;i<f$.length;i++){forwardProperty(f$[i]);}};var forwardProperty=function(name){Object.defineProperty(DomApi.prototype,name,{get:function(){return this.node[name];},configurable:true});};forwardProperties(['parentNode','firstChild','lastChild','nextSibling','previousSibling','firstElementChild','lastElementChild','nextElementSibling','previousElementSibling']);}());Polymer.Base.extend(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;this._prepareFlush();while(this._debouncers.length&&this._flushGuard<this._FLUSH_MAX){while(this._debouncers.length){this._debouncers.shift().complete();}
+Polymer.Base.mixin(DomApi.prototype,{querySelectorAll:function(selector){return TreeApi.arrayCopy(this.node.querySelectorAll(selector));},getOwnerRoot:function(){var n=this.node;while(n){if(n.nodeType===Node.DOCUMENT_FRAGMENT_NODE&&n.host){return n;}
+n=n.parentNode;}},importNode:function(externalNode,deep){var doc=this.node instanceof Document?this.node:this.node.ownerDocument;return doc.importNode(externalNode,deep);},getDestinationInsertionPoints:function(){var n$=this.node.getDestinationInsertionPoints&&this.node.getDestinationInsertionPoints();return n$?TreeApi.arrayCopy(n$):[];},getDistributedNodes:function(){var n$=this.node.getDistributedNodes&&this.node.getDistributedNodes();return n$?TreeApi.arrayCopy(n$):[];}});Object.defineProperties(DomApi.prototype,{activeElement:{get:function(){var node=DomApi.wrap(this.node);var activeElement=node.activeElement;return node.contains(activeElement)?activeElement:null;},configurable:true},childNodes:{get:function(){return TreeApi.arrayCopyChildNodes(this.node);},configurable:true},children:{get:function(){return TreeApi.arrayCopyChildren(this.node);},configurable:true},textContent:{get:function(){return this.node.textContent;},set:function(value){return this.node.textContent=value;},configurable:true},innerHTML:{get:function(){return this.node.innerHTML;},set:function(value){return this.node.innerHTML=value;},configurable:true}});var forwardMethods=function(m$){for(var i=0;i<m$.length;i++){forwardMethod(m$[i]);}};var forwardMethod=function(method){DomApi.prototype[method]=function(){return this.node[method].apply(this.node,arguments);};};forwardMethods(['cloneNode','appendChild','insertBefore','removeChild','replaceChild','setAttribute','removeAttribute','querySelector']);var forwardProperties=function(f$){for(var i=0;i<f$.length;i++){forwardProperty(f$[i]);}};var forwardProperty=function(name){Object.defineProperty(DomApi.prototype,name,{get:function(){return this.node[name];},configurable:true});};forwardProperties(['parentNode','firstChild','lastChild','nextSibling','previousSibling','firstElementChild','lastElementChild','nextElementSibling','previousElementSibling']);}());Polymer.Base.mixin(Polymer.dom,{_flushGuard:0,_FLUSH_MAX:100,_needsTakeRecords:!Polymer.Settings.useNativeCustomElements,_debouncers:[],_staticFlushList:[],_finishDebouncer:null,flush:function(){this._flushGuard=0;this._prepareFlush();while(this._debouncers.length&&this._flushGuard<this._FLUSH_MAX){while(this._debouncers.length){this._debouncers.shift().complete();}
 if(this._finishDebouncer){this._finishDebouncer.complete();}
 this._prepareFlush();this._flushGuard++;}
 if(this._flushGuard>=this._FLUSH_MAX){console.warn('Polymer.dom.flush aborted. Flush may not be complete.');}},_prepareFlush:function(){if(this._needsTakeRecords){CustomElements.takeRecords();}
@@ -3729,12 +3776,12 @@
 this._debouncer=Polymer.Debounce(this._debouncer,this._notify);this._debouncer.context=this;Polymer.dom.addDebouncer(this._debouncer);},notify:function(){if(this._hasListeners()){this._scheduleNotify();}},_notify:function(){this._beforeCallListeners();this._callListeners();},_beforeCallListeners:function(){this._updateContentElements();},_updateContentElements:function(){this._observeContentElements(this.domApi.childNodes);},_observeContentElements:function(elements){for(var i=0,n;i<elements.length&&(n=elements[i]);i++){if(this._isContent(n)){n.__observeNodesMap=n.__observeNodesMap||new WeakMap();if(!n.__observeNodesMap.has(this)){n.__observeNodesMap.set(this,this._observeContent(n));}}}},_observeContent:function(content){var self=this;var h=Polymer.dom(content).observeNodes(function(){self._scheduleNotify();});h._avoidChangeCalculation=true;return h;},_unobserveContentElements:function(elements){for(var i=0,n,h;i<elements.length&&(n=elements[i]);i++){if(this._isContent(n)){h=n.__observeNodesMap.get(this);if(h){Polymer.dom(n).unobserveNodes(h);n.__observeNodesMap.delete(this);}}}},_isContent:function(node){return node.localName==='content';},_callListeners:function(){var o$=this._listeners;var nodes=this._getEffectiveNodes();for(var i=0,o;i<o$.length&&(o=o$[i]);i++){var info=this._generateListenerInfo(o,nodes);if(info||o._alwaysNotify){this._callListener(o,info);}}},_getEffectiveNodes:function(){return this.domApi.getEffectiveChildNodes();},_generateListenerInfo:function(listener,newNodes){if(listener._avoidChangeCalculation){return true;}
 var oldNodes=listener._nodes;var info={target:this.node,addedNodes:[],removedNodes:[]};var splices=Polymer.ArraySplice.calculateSplices(newNodes,oldNodes);for(var i=0,s;i<splices.length&&(s=splices[i]);i++){for(var j=0,n;j<s.removed.length&&(n=s.removed[j]);j++){info.removedNodes.push(n);}}
 for(i=0,s;i<splices.length&&(s=splices[i]);i++){for(j=s.index;j<s.index+s.addedCount;j++){info.addedNodes.push(newNodes[j]);}}
-listener._nodes=newNodes;if(info.addedNodes.length||info.removedNodes.length){return info;}},_callListener:function(listener,info){return listener.fn.call(this.node,info);},enableShadowAttributeTracking:function(){}};if(Settings.useShadow){var baseSetup=DomApi.EffectiveNodesObserver.prototype._setup;var baseCleanup=DomApi.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.extend(DomApi.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var self=this;this._mutationHandler=function(mxns){if(mxns&&mxns.length){self._scheduleNotify();}};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){self._flush();};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,{childList:true});}
-baseSetup.call(this);},_cleanup:function(){this._observer.disconnect();this._observer=null;this._mutationHandler=null;Polymer.dom.removeStaticFlush(this._boundFlush);baseCleanup.call(this);},_flush:function(){if(this._observer){this._mutationHandler(this._observer.takeRecords());}},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:true,attributes:true,subtree:true});var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host&&Polymer.dom(host).observer){Polymer.dom(host).observer.enableShadowAttributeTracking();}}},_makeContentListenersAlwaysNotify:function(){for(var i=0,h;i<this._listeners.length;i++){h=this._listeners[i];h._alwaysNotify=h._isContentListener;}}});}}());(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.DistributedNodesObserver=function(domApi){DomApi.EffectiveNodesObserver.call(this,domApi);};DomApi.DistributedNodesObserver.prototype=Object.create(DomApi.EffectiveNodesObserver.prototype);Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes();}});if(Settings.useShadow){Polymer.Base.extend(DomApi.DistributedNodesObserver.prototype,{_setup:function(){if(!this._observer){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){var self=this;this._observer=Polymer.dom(host).observeNodes(function(){self._scheduleNotify();});this._observer._isContentListener=true;if(this._hasAttrSelect()){Polymer.dom(host).observer.enableShadowAttributeTracking();}}}},_hasAttrSelect:function(){var select=this.node.getAttribute('select');return select&&select.match(/[[.]+/);},_cleanup:function(){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){Polymer.dom(host).unobserveNodes(this._observer);}
+listener._nodes=newNodes;if(info.addedNodes.length||info.removedNodes.length){return info;}},_callListener:function(listener,info){return listener.fn.call(this.node,info);},enableShadowAttributeTracking:function(){}};if(Settings.useShadow){var baseSetup=DomApi.EffectiveNodesObserver.prototype._setup;var baseCleanup=DomApi.EffectiveNodesObserver.prototype._cleanup;Polymer.Base.mixin(DomApi.EffectiveNodesObserver.prototype,{_setup:function(){if(!this._observer){var self=this;this._mutationHandler=function(mxns){if(mxns&&mxns.length){self._scheduleNotify();}};this._observer=new MutationObserver(this._mutationHandler);this._boundFlush=function(){self._flush();};Polymer.dom.addStaticFlush(this._boundFlush);this._observer.observe(this.node,{childList:true});}
+baseSetup.call(this);},_cleanup:function(){this._observer.disconnect();this._observer=null;this._mutationHandler=null;Polymer.dom.removeStaticFlush(this._boundFlush);baseCleanup.call(this);},_flush:function(){if(this._observer){this._mutationHandler(this._observer.takeRecords());}},enableShadowAttributeTracking:function(){if(this._observer){this._makeContentListenersAlwaysNotify();this._observer.disconnect();this._observer.observe(this.node,{childList:true,attributes:true,subtree:true});var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host&&Polymer.dom(host).observer){Polymer.dom(host).observer.enableShadowAttributeTracking();}}},_makeContentListenersAlwaysNotify:function(){for(var i=0,h;i<this._listeners.length;i++){h=this._listeners[i];h._alwaysNotify=h._isContentListener;}}});}}());(function(){'use strict';var DomApi=Polymer.DomApi.ctor;var Settings=Polymer.Settings;DomApi.DistributedNodesObserver=function(domApi){DomApi.EffectiveNodesObserver.call(this,domApi);};DomApi.DistributedNodesObserver.prototype=Object.create(DomApi.EffectiveNodesObserver.prototype);Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){},_cleanup:function(){},_beforeCallListeners:function(){},_getEffectiveNodes:function(){return this.domApi.getDistributedNodes();}});if(Settings.useShadow){Polymer.Base.mixin(DomApi.DistributedNodesObserver.prototype,{_setup:function(){if(!this._observer){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){var self=this;this._observer=Polymer.dom(host).observeNodes(function(){self._scheduleNotify();});this._observer._isContentListener=true;if(this._hasAttrSelect()){Polymer.dom(host).observer.enableShadowAttributeTracking();}}}},_hasAttrSelect:function(){var select=this.node.getAttribute('select');return select&&select.match(/[[.]+/);},_cleanup:function(){var root=this.domApi.getOwnerRoot();var host=root&&root.host;if(host){Polymer.dom(host).unobserveNodes(this._observer);}
 this._observer=null;}});}}());(function(){var DomApi=Polymer.DomApi;var TreeApi=Polymer.TreeApi;Polymer.Base._addFeature({_prepShady:function(){this._useContent=this._useContent||Boolean(this._template);},_setupShady:function(){this.shadyRoot=null;if(!this.__domApi){this.__domApi=null;}
 if(!this.__dom){this.__dom=null;}
 if(!this._ownerShadyRoot){this._ownerShadyRoot=undefined;}},_poolContent:function(){if(this._useContent){TreeApi.Logical.saveChildNodes(this);}},_setupRoot:function(){if(this._useContent){this._createLocalRoot();if(!this.dataHost){upgradeLogicalChildren(TreeApi.Logical.getChildNodes(this));}}},_createLocalRoot:function(){this.shadyRoot=this.root;this.shadyRoot._distributionClean=false;this.shadyRoot._hasDistributed=false;this.shadyRoot._isShadyRoot=true;this.shadyRoot._dirtyRoots=[];var i$=this.shadyRoot._insertionPoints=!this._notes||this._notes._hasContent?this.shadyRoot.querySelectorAll('content'):[];TreeApi.Logical.saveChildNodes(this.shadyRoot);for(var i=0,c;i<i$.length;i++){c=i$[i];TreeApi.Logical.saveChildNodes(c);TreeApi.Logical.saveChildNodes(c.parentNode);}
-this.shadyRoot.host=this;},get domHost(){var root=Polymer.dom(this).getOwnerRoot();return root&&root.host;},distributeContent:function(updateInsertionPoints){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||updateInsertionPoints;var host=getTopDistributingHost(this);Polymer.dom(this)._lazyDistribute(host);}},_distributeContent:function(){if(this._useContent&&!this.shadyRoot._distributionClean){if(this.shadyRoot._invalidInsertionPoints){Polymer.dom(this)._updateInsertionPoints(this);this.shadyRoot._invalidInsertionPoints=false;}
+this.shadyRoot.host=this;},distributeContent:function(updateInsertionPoints){if(this.shadyRoot){this.shadyRoot._invalidInsertionPoints=this.shadyRoot._invalidInsertionPoints||updateInsertionPoints;var host=getTopDistributingHost(this);Polymer.dom(this)._lazyDistribute(host);}},_distributeContent:function(){if(this._useContent&&!this.shadyRoot._distributionClean){if(this.shadyRoot._invalidInsertionPoints){Polymer.dom(this)._updateInsertionPoints(this);this.shadyRoot._invalidInsertionPoints=false;}
 this._beginDistribute();this._distributeDirtyRoots();this._finishDistribute();}},_beginDistribute:function(){if(this._useContent&&DomApi.hasInsertionPoint(this.shadyRoot)){this._resetDistribution();this._distributePool(this.shadyRoot,this._collectPool());}},_distributeDirtyRoots:function(){var c$=this.shadyRoot._dirtyRoots;for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){c._distributeContent();}
 this.shadyRoot._dirtyRoots=[];},_finishDistribute:function(){if(this._useContent){this.shadyRoot._distributionClean=true;if(DomApi.hasInsertionPoint(this.shadyRoot)){this._composeTree();notifyContentObservers(this.shadyRoot);}else{if(!this.shadyRoot._hasDistributed){TreeApi.Composed.clearChildNodes(this);this.appendChild(this.shadyRoot);}else{var children=this._composeNode(this);this._updateChildNodes(this,children);}}
 if(!this.shadyRoot._hasDistributed){notifyInitialDistribution(this);}
@@ -3751,7 +3798,7 @@
 select=select.trim();if(!select){return true;}
 if(!(node instanceof Element)){return false;}
 var validSelectors=/^(:not\()?[*.#[a-zA-Z_|]/;if(!validSelectors.test(select)){return false;}
-return this.elementMatches(select,node);},_elementAdd:function(){},_elementRemove:function(){}});function distributeNodeInto(child,insertionPoint){insertionPoint._distributedNodes.push(child);var points=child._destinationInsertionPoints;if(!points){child._destinationInsertionPoints=[insertionPoint];}else{points.push(insertionPoint);}}
+return this.elementMatches(select,node);},_elementAdd:function(){},_elementRemove:function(){}});var domHostDesc={get:function(){var root=Polymer.dom(this).getOwnerRoot();return root&&root.host;},configurable:true};Object.defineProperty(Polymer.Base,'domHost',domHostDesc);Polymer.BaseDescriptors.domHost=domHostDesc;function distributeNodeInto(child,insertionPoint){insertionPoint._distributedNodes.push(child);var points=child._destinationInsertionPoints;if(!points){child._destinationInsertionPoints=[insertionPoint];}else{points.push(insertionPoint);}}
 function clearDistributedDestinationInsertionPoints(content){var e$=content._distributedNodes;if(e$){for(var i=0;i<e$.length;i++){var d=e$[i]._destinationInsertionPoints;if(d){d.splice(d.indexOf(content)+1,d.length);}}}}
 function maybeRedistributeParent(content,host){var parent=TreeApi.Logical.getParentNode(content);if(parent&&parent.shadyRoot&&DomApi.hasInsertionPoint(parent.shadyRoot)&&parent.shadyRoot._distributionClean){parent.shadyRoot._distributionClean=false;host.shadyRoot._dirtyRoots.push(parent);}}
 function isFinalDestination(insertionPoint,node){var points=node._destinationInsertionPoints;return points&&points[points.length-1]===insertionPoint;}
@@ -3766,7 +3813,7 @@
 this._callbacks.splice(0,len);this._lastVal+=len;}};new window.MutationObserver(function(){Polymer.Async._atEndOfMicrotask();}).observe(Polymer.Async._twiddle,{characterData:true});Polymer.Debounce=function(){var Async=Polymer.Async;var Debouncer=function(context){this.context=context;var self=this;this.boundComplete=function(){self.complete();};};Debouncer.prototype={go:function(callback,wait){var h;this.finish=function(){Async.cancel(h);};h=Async.run(this.boundComplete,wait);this.callback=callback;},stop:function(){if(this.finish){this.finish();this.finish=null;this.callback=null;}},complete:function(){if(this.finish){var callback=this.callback;this.stop();callback.call(this.context);}}};function debounce(debouncer,callback,wait){if(debouncer){debouncer.stop();}else{debouncer=new Debouncer(this);}
 debouncer.go(callback,wait);return debouncer;}
 return debounce;}();Polymer.Base._addFeature({_setupDebouncers:function(){this._debouncers={};},debounce:function(jobName,callback,wait){return this._debouncers[jobName]=Polymer.Debounce.call(this,this._debouncers[jobName],callback,wait);},isDebouncerActive:function(jobName){var debouncer=this._debouncers[jobName];return!!(debouncer&&debouncer.finish);},flushDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer){debouncer.complete();}},cancelDebouncer:function(jobName){var debouncer=this._debouncers[jobName];if(debouncer){debouncer.stop();}}});Polymer.DomModule=document.createElement('dom-module');Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepBehaviors();this._prepConstructor();this._prepTemplate();this._prepShady();this._prepPropertyInfo();},_prepBehavior:function(b){this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._registerHost();if(this._template){this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();}
-this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady();},_marshalBehavior:function(b){}});Polymer.nar=[];Polymer.Annotations={parseAnnotations:function(template){var list=[];var content=template._content||template.content;this._parseNodeAnnotations(content,list,template.hasAttribute('strip-whitespace'));return list;},_parseNodeAnnotations:function(node,list,stripWhiteSpace){return node.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(node,list):this._parseElementAnnotations(node,list,stripWhiteSpace);},_bindingRegex:function(){var IDENT='(?:'+'[a-zA-Z_$][\\w.:$\\-*]*'+')';var NUMBER='(?:'+'[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?'+')';var SQUOTE_STRING='(?:'+'\'(?:[^\'\\\\]|\\\\.)*\''+')';var DQUOTE_STRING='(?:'+'"(?:[^"\\\\]|\\\\.)*"'+')';var STRING='(?:'+SQUOTE_STRING+'|'+DQUOTE_STRING+')';var ARGUMENT='(?:'+IDENT+'|'+NUMBER+'|'+STRING+'\\s*'+')';var ARGUMENTS='(?:'+ARGUMENT+'(?:,\\s*'+ARGUMENT+')*'+')';var ARGUMENT_LIST='(?:'+'\\(\\s*'+'(?:'+ARGUMENTS+'?'+')'+'\\)\\s*'+')';var BINDING='('+IDENT+'\\s*'+ARGUMENT_LIST+'?'+')';var OPEN_BRACKET='(\\[\\[|{{)'+'\\s*';var CLOSE_BRACKET='(?:]]|}})';var NEGATE='(?:(!)\\s*)?';var EXPRESSION=OPEN_BRACKET+NEGATE+BINDING+CLOSE_BRACKET;return new RegExp(EXPRESSION,'g');}(),_parseBindings:function(text){var re=this._bindingRegex;var parts=[];var lastIndex=0;var m;while((m=re.exec(text))!==null){if(m.index>lastIndex){parts.push({literal:text.slice(lastIndex,m.index)});}
+this._marshalHostAttributes();this._setupDebouncers();this._marshalBehaviors();this._tryReady();},_marshalBehavior:function(b){}});(function(){Polymer.nar=[];var disableUpgradeEnabled=Polymer.Settings.disableUpgradeEnabled;Polymer.Annotations={parseAnnotations:function(template,stripWhiteSpace){var list=[];var content=template._content||template.content;this._parseNodeAnnotations(content,list,stripWhiteSpace||template.hasAttribute('strip-whitespace'));return list;},_parseNodeAnnotations:function(node,list,stripWhiteSpace){return node.nodeType===Node.TEXT_NODE?this._parseTextNodeAnnotation(node,list):this._parseElementAnnotations(node,list,stripWhiteSpace);},_bindingRegex:function(){var IDENT='(?:'+'[a-zA-Z_$][\\w.:$\\-*]*'+')';var NUMBER='(?:'+'[-+]?[0-9]*\\.?[0-9]+(?:[eE][-+]?[0-9]+)?'+')';var SQUOTE_STRING='(?:'+'\'(?:[^\'\\\\]|\\\\.)*\''+')';var DQUOTE_STRING='(?:'+'"(?:[^"\\\\]|\\\\.)*"'+')';var STRING='(?:'+SQUOTE_STRING+'|'+DQUOTE_STRING+')';var ARGUMENT='(?:'+IDENT+'|'+NUMBER+'|'+STRING+'\\s*'+')';var ARGUMENTS='(?:'+ARGUMENT+'(?:,\\s*'+ARGUMENT+')*'+')';var ARGUMENT_LIST='(?:'+'\\(\\s*'+'(?:'+ARGUMENTS+'?'+')'+'\\)\\s*'+')';var BINDING='('+IDENT+'\\s*'+ARGUMENT_LIST+'?'+')';var OPEN_BRACKET='(\\[\\[|{{)'+'\\s*';var CLOSE_BRACKET='(?:]]|}})';var NEGATE='(?:(!)\\s*)?';var EXPRESSION=OPEN_BRACKET+NEGATE+BINDING+CLOSE_BRACKET;return new RegExp(EXPRESSION,'g');}(),_parseBindings:function(text){var re=this._bindingRegex;var parts=[];var lastIndex=0;var m;while((m=re.exec(text))!==null){if(m.index>lastIndex){parts.push({literal:text.slice(lastIndex,m.index)});}
 var mode=m[1][0];var negate=Boolean(m[2]);var value=m[3].trim();var customEvent,notifyEvent,colon;if(mode=='{'&&(colon=value.indexOf('::'))>0){notifyEvent=value.substring(colon+2);value=value.substring(0,colon);customEvent=true;}
 parts.push({compoundIndex:parts.length,value:value,mode:mode,negate:negate,event:notifyEvent,customEvent:customEvent});lastIndex=re.lastIndex;}
 if(lastIndex&&lastIndex<text.length){var literal=text.substring(lastIndex);if(literal){parts.push({literal:literal});}}
@@ -3774,23 +3821,29 @@
 return s;},_parseTextNodeAnnotation:function(node,list){var parts=this._parseBindings(node.textContent);if(parts){node.textContent=this._literalFromParts(parts)||' ';var annote={bindings:[{kind:'text',name:'textContent',parts:parts,isCompound:parts.length!==1}]};list.push(annote);return annote;}},_parseElementAnnotations:function(element,list,stripWhiteSpace){var annote={bindings:[],events:[]};if(element.localName==='content'){list._hasContent=true;}
 this._parseChildNodesAnnotations(element,annote,list,stripWhiteSpace);if(element.attributes){this._parseNodeAttributeAnnotations(element,annote,list);if(this.prepElement){this.prepElement(element);}}
 if(annote.bindings.length||annote.events.length||annote.id){list.push(annote);}
-return annote;},_parseChildNodesAnnotations:function(root,annote,list,stripWhiteSpace){if(root.firstChild){var node=root.firstChild;var i=0;while(node){var next=node.nextSibling;if(node.localName==='template'&&!node.hasAttribute('preserve-content')){this._parseTemplate(node,i,list,annote);}
+return annote;},_parseChildNodesAnnotations:function(root,annote,list,stripWhiteSpace){if(root.firstChild){var node=root.firstChild;var i=0;while(node){var next=node.nextSibling;if(node.localName==='template'&&!node.hasAttribute('preserve-content')){this._parseTemplate(node,i,list,annote,stripWhiteSpace);}
+if(node.localName=='slot'){node=this._replaceSlotWithContent(node);}
 if(node.nodeType===Node.TEXT_NODE){var n=next;while(n&&n.nodeType===Node.TEXT_NODE){node.textContent+=n.textContent;next=n.nextSibling;root.removeChild(n);n=next;}
 if(stripWhiteSpace&&!node.textContent.trim()){root.removeChild(node);i--;}}
 if(node.parentNode){var childAnnotation=this._parseNodeAnnotations(node,list,stripWhiteSpace);if(childAnnotation){childAnnotation.parent=annote;childAnnotation.index=i;}}
-node=next;i++;}}},_parseTemplate:function(node,index,list,parent){var content=document.createDocumentFragment();content._notes=this.parseAnnotations(node);content.appendChild(node.content);list.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:content,parent:parent,index:index});},_parseNodeAttributeAnnotations:function(node,annotation){var attrs=Array.prototype.slice.call(node.attributes);for(var i=attrs.length-1,a;a=attrs[i];i--){var n=a.name;var v=a.value;var b;if(n.slice(0,3)==='on-'){node.removeAttribute(n);annotation.events.push({name:n.slice(3),value:v});}else if(b=this._parseNodeAttributeAnnotation(node,n,v)){annotation.bindings.push(b);}else if(n==='id'){annotation.id=v;}}},_parseNodeAttributeAnnotation:function(node,name,value){var parts=this._parseBindings(value);if(parts){var origName=name;var kind='property';if(name[name.length-1]=='$'){name=name.slice(0,-1);kind='attribute';}
+node=next;i++;}}},_replaceSlotWithContent:function(slot){var content=slot.ownerDocument.createElement('content');while(slot.firstChild){content.appendChild(slot.firstChild);}
+var attrs=slot.attributes;for(var i=0;i<attrs.length;i++){var attr=attrs[i];content.setAttribute(attr.name,attr.value);}
+var name=slot.getAttribute('name');if(name){content.setAttribute('select','[slot=\''+name+'\']');}
+slot.parentNode.replaceChild(content,slot);return content;},_parseTemplate:function(node,index,list,parent,stripWhiteSpace){var content=document.createDocumentFragment();content._notes=this.parseAnnotations(node,stripWhiteSpace);content.appendChild(node.content);list.push({bindings:Polymer.nar,events:Polymer.nar,templateContent:content,parent:parent,index:index});},_parseNodeAttributeAnnotations:function(node,annotation){var attrs=Array.prototype.slice.call(node.attributes);for(var i=attrs.length-1,a;a=attrs[i];i--){var n=a.name;var v=a.value;var b;if(n.slice(0,3)==='on-'){node.removeAttribute(n);annotation.events.push({name:n.slice(3),value:v});}else if(b=this._parseNodeAttributeAnnotation(node,n,v)){annotation.bindings.push(b);}else if(n==='id'){annotation.id=v;}}},_parseNodeAttributeAnnotation:function(node,name,value){var parts=this._parseBindings(value);if(parts){var origName=name;var kind='property';if(name[name.length-1]=='$'){name=name.slice(0,-1);kind='attribute';}
 var literal=this._literalFromParts(parts);if(literal&&kind=='attribute'){node.setAttribute(name,literal);}
 if(node.localName==='input'&&origName==='value'){node.setAttribute(origName,'');}
+if(disableUpgradeEnabled&&origName==='disable-upgrade$'){node.setAttribute(name,'');}
 node.removeAttribute(origName);var propertyName=Polymer.CaseMap.dashToCamelCase(name);if(kind==='property'){name=propertyName;}
-return{kind:kind,name:name,propertyName:propertyName,parts:parts,literal:literal,isCompound:parts.length!==1};}},findAnnotatedNode:function(root,annote){var parent=annote.parent&&Polymer.Annotations.findAnnotatedNode(root,annote.parent);if(parent){for(var n=parent.firstChild,i=0;n;n=n.nextSibling){if(annote.index===i++){return n;}}}else{return root;}}};(function(){function resolveCss(cssText,ownerDocument){return cssText.replace(CSS_URL_RX,function(m,pre,url,post){return pre+'\''+resolve(url.replace(/["']/g,''),ownerDocument)+'\''+post;});}
+return{kind:kind,name:name,propertyName:propertyName,parts:parts,literal:literal,isCompound:parts.length!==1};}},findAnnotatedNode:function(root,annote){var parent=annote.parent&&Polymer.Annotations.findAnnotatedNode(root,annote.parent);if(parent){for(var n=parent.firstChild,i=0;n;n=n.nextSibling){if(annote.index===i++){return n;}}}else{return root;}}};}());(function(){function resolveCss(cssText,ownerDocument){return cssText.replace(CSS_URL_RX,function(m,pre,url,post){return pre+'\''+resolve(url.replace(/["']/g,''),ownerDocument)+'\''+post;});}
 function resolveAttrs(element,ownerDocument){for(var name in URL_ATTRS){var a$=URL_ATTRS[name];for(var i=0,l=a$.length,a,at,v;i<l&&(a=a$[i]);i++){if(name==='*'||element.localName===name){at=element.attributes[a];v=at&&at.value;if(v&&v.search(BINDING_RX)<0){at.value=a==='style'?resolveCss(v,ownerDocument):resolve(v,ownerDocument);}}}}}
-function resolve(url,ownerDocument){if(url&&url[0]==='#'){return url;}
+function resolve(url,ownerDocument){if(url&&ABS_URL.test(url)){return url;}
 var resolver=getUrlResolver(ownerDocument);resolver.href=url;return resolver.href||url;}
 var tempDoc;var tempDocBase;function resolveUrl(url,baseUri){if(!tempDoc){tempDoc=document.implementation.createHTMLDocument('temp');tempDocBase=tempDoc.createElement('base');tempDoc.head.appendChild(tempDocBase);}
 tempDocBase.href=baseUri;return resolve(url,tempDoc);}
-function getUrlResolver(ownerDocument){return ownerDocument.__urlResolver||(ownerDocument.__urlResolver=ownerDocument.createElement('a'));}
-var CSS_URL_RX=/(url\()([^)]*)(\))/g;var URL_ATTRS={'*':['href','src','style','url'],form:['action']};var BINDING_RX=/\{\{|\[\[/;Polymer.ResolveUrl={resolveCss:resolveCss,resolveAttrs:resolveAttrs,resolveUrl:resolveUrl};}());Polymer.Base._addFeature({_prepAnnotations:function(){if(!this._template){this._notes=[];}else{var self=this;Polymer.Annotations.prepElement=function(element){self._prepElement(element);};if(this._template._content&&this._template._content._notes){this._notes=this._template._content._notes;}else{this._notes=Polymer.Annotations.parseAnnotations(this._template);this._processAnnotations(this._notes);}
-Polymer.Annotations.prepElement=null;}},_processAnnotations:function(notes){for(var i=0;i<notes.length;i++){var note=notes[i];for(var j=0;j<note.bindings.length;j++){var b=note.bindings[j];for(var k=0;k<b.parts.length;k++){var p=b.parts[k];if(!p.literal){var signature=this._parseMethod(p.value);if(signature){p.signature=signature;}else{p.model=this._modelForPath(p.value);}}}}
+function getUrlResolver(ownerDocument){return ownerDocument.body.__urlResolver||(ownerDocument.body.__urlResolver=ownerDocument.createElement('a'));}
+var CSS_URL_RX=/(url\()([^)]*)(\))/g;var URL_ATTRS={'*':['href','src','style','url'],form:['action']};var ABS_URL=/(^\/)|(^#)|(^[\w-\d]*:)/;var BINDING_RX=/\{\{|\[\[/;Polymer.ResolveUrl={resolveCss:resolveCss,resolveAttrs:resolveAttrs,resolveUrl:resolveUrl};}());Polymer.Path={root:function(path){var dotIndex=path.indexOf('.');if(dotIndex===-1){return path;}
+return path.slice(0,dotIndex);},isDeep:function(path){return path.indexOf('.')!==-1;},isAncestor:function(base,path){return base.indexOf(path+'.')===0;},isDescendant:function(base,path){return path.indexOf(base+'.')===0;},translate:function(base,newBase,path){return newBase+path.slice(base.length);},matches:function(base,wildcard,path){return base===path||this.isAncestor(base,path)||Boolean(wildcard)&&this.isDescendant(base,path);}};Polymer.Base._addFeature({_prepAnnotations:function(){if(!this._template){this._notes=[];}else{var self=this;Polymer.Annotations.prepElement=function(element){self._prepElement(element);};if(this._template._content&&this._template._content._notes){this._notes=this._template._content._notes;}else{this._notes=Polymer.Annotations.parseAnnotations(this._template);this._processAnnotations(this._notes);}
+Polymer.Annotations.prepElement=null;}},_processAnnotations:function(notes){for(var i=0;i<notes.length;i++){var note=notes[i];for(var j=0;j<note.bindings.length;j++){var b=note.bindings[j];for(var k=0;k<b.parts.length;k++){var p=b.parts[k];if(!p.literal){var signature=this._parseMethod(p.value);if(signature){p.signature=signature;}else{p.model=Polymer.Path.root(p.value);}}}}
 if(note.templateContent){this._processAnnotations(note.templateContent._notes);var pp=note.templateContent._parentProps=this._discoverTemplateParentProps(note.templateContent._notes);var bindings=[];for(var prop in pp){var name='_parent_'+prop;bindings.push({index:note.index,kind:'property',name:name,propertyName:name,parts:[{mode:'{',model:prop,value:prop}]});}
 note.bindings=note.bindings.concat(bindings);}}},_discoverTemplateParentProps:function(notes){var pp={};for(var i=0,n;i<notes.length&&(n=notes[i]);i++){for(var j=0,b$=n.bindings,b;j<b$.length&&(b=b$[j]);j++){for(var k=0,p$=b.parts,p;k<p$.length&&(p=p$[k]);k++){if(p.signature){var args=p.signature.args;for(var kk=0;kk<args.length;kk++){var model=args[kk].model;if(model){pp[model]=true;}}
 if(p.signature.dynamicFn){pp[p.signature.method]=true;}}else{if(p.model){pp[p.model]=true;}}}}
@@ -3801,14 +3854,14 @@
 this.listen(node,name,listeners[eventName]);}},listen:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(!handler){handler=this._createEventHandler(node,eventName,methodName);}
 if(handler._listening){return;}
 this._listen(node,eventName,handler);handler._listening=true;},_boundListenerKey:function(eventName,methodName){return eventName+':'+methodName;},_recordEventHandler:function(host,eventName,target,methodName,handler){var hbl=host.__boundListeners;if(!hbl){hbl=host.__boundListeners=new WeakMap();}
-var bl=hbl.get(target);if(!bl){bl={};hbl.set(target,bl);}
+var bl=hbl.get(target);if(!bl){bl={};if(!Polymer.Settings.isIE||target!=window){hbl.set(target,bl);}}
 var key=this._boundListenerKey(eventName,methodName);bl[key]=handler;},_recallEventHandler:function(host,eventName,target,methodName){var hbl=host.__boundListeners;if(!hbl){return;}
 var bl=hbl.get(target);if(!bl){return;}
-var key=this._boundListenerKey(eventName,methodName);return bl[key];},_createEventHandler:function(node,eventName,methodName){var host=this;var handler=function(e){if(host[methodName]){host[methodName](e,e.detail);}else{host._warn(host._logf('_createEventHandler','listener method `'+methodName+'` not defined'));}};handler._listening=false;this._recordEventHandler(host,eventName,node,methodName,handler);return handler;},unlisten:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(handler){this._unlisten(node,eventName,handler);handler._listening=false;}},_listen:function(node,eventName,handler){node.addEventListener(eventName,handler);},_unlisten:function(node,eventName,handler){node.removeEventListener(eventName,handler);}});(function(){'use strict';var wrap=Polymer.DomApi.wrap;var HAS_NATIVE_TA=typeof document.head.style.touchAction==='string';var GESTURE_KEY='__polymerGestures';var HANDLED_OBJ='__polymerGesturesHandled';var TOUCH_ACTION='__polymerGesturesTouchAction';var TAP_DISTANCE=25;var TRACK_DISTANCE=5;var TRACK_LENGTH=2;var MOUSE_TIMEOUT=2500;var MOUSE_EVENTS=['mousedown','mousemove','mouseup','click'];var MOUSE_WHICH_TO_BUTTONS=[0,1,4,2];var MOUSE_HAS_BUTTONS=function(){try{return new MouseEvent('test',{buttons:1}).buttons===1;}catch(e){return false;}}();var IS_TOUCH_ONLY=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);var mouseCanceller=function(mouseEvent){mouseEvent[HANDLED_OBJ]={skip:true};if(mouseEvent.type==='click'){var path=Polymer.dom(mouseEvent).path;for(var i=0;i<path.length;i++){if(path[i]===POINTERSTATE.mouse.target){return;}}
-mouseEvent.preventDefault();mouseEvent.stopPropagation();}};function setupTeardownMouseCanceller(setup){for(var i=0,en;i<MOUSE_EVENTS.length;i++){en=MOUSE_EVENTS[i];if(setup){document.addEventListener(en,mouseCanceller,true);}else{document.removeEventListener(en,mouseCanceller,true);}}}
-function ignoreMouse(){if(IS_TOUCH_ONLY){return;}
-if(!POINTERSTATE.mouse.mouseIgnoreJob){setupTeardownMouseCanceller(true);}
-var unset=function(){setupTeardownMouseCanceller();POINTERSTATE.mouse.target=null;POINTERSTATE.mouse.mouseIgnoreJob=null;};POINTERSTATE.mouse.mouseIgnoreJob=Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob,unset,MOUSE_TIMEOUT);}
+var key=this._boundListenerKey(eventName,methodName);return bl[key];},_createEventHandler:function(node,eventName,methodName){var host=this;var handler=function(e){if(host[methodName]){host[methodName](e,e.detail);}else{host._warn(host._logf('_createEventHandler','listener method `'+methodName+'` not defined'));}};handler._listening=false;this._recordEventHandler(host,eventName,node,methodName,handler);return handler;},unlisten:function(node,eventName,methodName){var handler=this._recallEventHandler(this,eventName,node,methodName);if(handler){this._unlisten(node,eventName,handler);handler._listening=false;}},_listen:function(node,eventName,handler){node.addEventListener(eventName,handler);},_unlisten:function(node,eventName,handler){node.removeEventListener(eventName,handler);}});(function(){'use strict';var wrap=Polymer.DomApi.wrap;var HAS_NATIVE_TA=typeof document.head.style.touchAction==='string';var GESTURE_KEY='__polymerGestures';var HANDLED_OBJ='__polymerGesturesHandled';var TOUCH_ACTION='__polymerGesturesTouchAction';var TAP_DISTANCE=25;var TRACK_DISTANCE=5;var TRACK_LENGTH=2;var MOUSE_TIMEOUT=2500;var MOUSE_EVENTS=['mousedown','mousemove','mouseup','click'];var MOUSE_WHICH_TO_BUTTONS=[0,1,4,2];var MOUSE_HAS_BUTTONS=function(){try{return new MouseEvent('test',{buttons:1}).buttons===1;}catch(e){return false;}}();var SUPPORTS_PASSIVE=false;(function(){try{var opts=Object.defineProperty({},'passive',{get:function(){SUPPORTS_PASSIVE=true;}});window.addEventListener('test',null,opts);window.removeEventListener('test',null,opts);}catch(e){}}());var IS_TOUCH_ONLY=navigator.userAgent.match(/iP(?:[oa]d|hone)|Android/);var mouseCanceller=function(mouseEvent){var sc=mouseEvent.sourceCapabilities;if(sc&&!sc.firesTouchEvents){return;}
+mouseEvent[HANDLED_OBJ]={skip:true};if(mouseEvent.type==='click'){var path=Polymer.dom(mouseEvent).path;for(var i=0;i<path.length;i++){if(path[i]===POINTERSTATE.mouse.target){return;}}
+mouseEvent.preventDefault();mouseEvent.stopPropagation();}};function setupTeardownMouseCanceller(setup){var events=IS_TOUCH_ONLY?['click']:MOUSE_EVENTS;for(var i=0,en;i<events.length;i++){en=events[i];if(setup){document.addEventListener(en,mouseCanceller,true);}else{document.removeEventListener(en,mouseCanceller,true);}}}
+function ignoreMouse(ev){if(!POINTERSTATE.mouse.mouseIgnoreJob){setupTeardownMouseCanceller(true);}
+var unset=function(){setupTeardownMouseCanceller();POINTERSTATE.mouse.target=null;POINTERSTATE.mouse.mouseIgnoreJob=null;};POINTERSTATE.mouse.target=Polymer.dom(ev).rootTarget;POINTERSTATE.mouse.mouseIgnoreJob=Polymer.Debounce(POINTERSTATE.mouse.mouseIgnoreJob,unset,MOUSE_TIMEOUT);}
 function hasLeftMouseButton(ev){var type=ev.type;if(MOUSE_EVENTS.indexOf(type)===-1){return false;}
 if(type==='mousemove'){var buttons=ev.buttons===undefined?1:ev.buttons;if(ev instanceof window.MouseEvent&&!MOUSE_HAS_BUTTONS){buttons=MOUSE_WHICH_TO_BUTTONS[ev.which]||0;}
 return Boolean(buttons&1);}else{var button=ev.button===undefined?0:ev.button;return button===0;}}
@@ -3819,20 +3872,19 @@
 return ta;}
 function trackDocument(stateObj,movefn,upfn){stateObj.movefn=movefn;stateObj.upfn=upfn;document.addEventListener('mousemove',movefn);document.addEventListener('mouseup',upfn);}
 function untrackDocument(stateObj){document.removeEventListener('mousemove',stateObj.movefn);document.removeEventListener('mouseup',stateObj.upfn);stateObj.movefn=null;stateObj.upfn=null;}
-var Gestures={gestures:{},recognizers:[],deepTargetFind:function(x,y){var node=document.elementFromPoint(x,y);var next=node;while(next&&next.shadowRoot){next=next.shadowRoot.elementFromPoint(x,y);if(next){node=next;}}
+document.addEventListener('touchend',ignoreMouse,SUPPORTS_PASSIVE?{passive:true}:false);var Gestures={gestures:{},recognizers:[],deepTargetFind:function(x,y){var node=document.elementFromPoint(x,y);var next=node;while(next&&next.shadowRoot){next=next.shadowRoot.elementFromPoint(x,y);if(next){node=next;}}
 return node;},findOriginalTarget:function(ev){if(ev.path){return ev.path[0];}
 return ev.target;},handleNative:function(ev){var handled;var type=ev.type;var node=wrap(ev.currentTarget);var gobj=node[GESTURE_KEY];if(!gobj){return;}
 var gs=gobj[type];if(!gs){return;}
 if(!ev[HANDLED_OBJ]){ev[HANDLED_OBJ]={};if(type.slice(0,5)==='touch'){var t=ev.changedTouches[0];if(type==='touchstart'){if(ev.touches.length===1){POINTERSTATE.touch.id=t.identifier;}}
 if(POINTERSTATE.touch.id!==t.identifier){return;}
-if(!HAS_NATIVE_TA){if(type==='touchstart'||type==='touchmove'){Gestures.handleTouchAction(ev);}}
-if(type==='touchend'){POINTERSTATE.mouse.target=Polymer.dom(ev).rootTarget;ignoreMouse();}}}
+if(!HAS_NATIVE_TA){if(type==='touchstart'||type==='touchmove'){Gestures.handleTouchAction(ev);}}}}
 handled=ev[HANDLED_OBJ];if(handled.skip){return;}
 var recognizers=Gestures.recognizers;for(var i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){if(r.flow&&r.flow.start.indexOf(ev.type)>-1&&r.reset){r.reset();}}}
 for(i=0,r;i<recognizers.length;i++){r=recognizers[i];if(gs[r.name]&&!handled[r.name]){handled[r.name]=true;r[type](ev);}}},handleTouchAction:function(ev){var t=ev.changedTouches[0];var type=ev.type;if(type==='touchstart'){POINTERSTATE.touch.x=t.clientX;POINTERSTATE.touch.y=t.clientY;POINTERSTATE.touch.scrollDecided=false;}else if(type==='touchmove'){if(POINTERSTATE.touch.scrollDecided){return;}
 POINTERSTATE.touch.scrollDecided=true;var ta=firstTouchAction(ev);var prevent=false;var dx=Math.abs(POINTERSTATE.touch.x-t.clientX);var dy=Math.abs(POINTERSTATE.touch.y-t.clientY);if(!ev.cancelable){}else if(ta==='none'){prevent=true;}else if(ta==='pan-x'){prevent=dy>dx;}else if(ta==='pan-y'){prevent=dx>dy;}
 if(prevent){ev.preventDefault();}else{Gestures.prevent('track');}}},add:function(node,evType,handler){node=wrap(node);var recognizer=this.gestures[evType];var deps=recognizer.deps;var name=recognizer.name;var gobj=node[GESTURE_KEY];if(!gobj){node[GESTURE_KEY]=gobj={};}
-for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];if(IS_TOUCH_ONLY&&MOUSE_EVENTS.indexOf(dep)>-1){continue;}
+for(var i=0,dep,gd;i<deps.length;i++){dep=deps[i];if(IS_TOUCH_ONLY&&MOUSE_EVENTS.indexOf(dep)>-1&&dep!=='click'){continue;}
 gd=gobj[dep];if(!gd){gobj[dep]=gd={_count:0};}
 if(gd._count===0){node.addEventListener(dep,this.handleNative);}
 gd[name]=(gd[name]||0)+1;gd._count=(gd._count||0)+1;}
@@ -3858,24 +3910,24 @@
 return tc.join('');},queryEffectiveChildren:function(slctr){var e$=Polymer.dom(this).queryDistributedElements(slctr);return e$&&e$[0];},queryAllEffectiveChildren:function(slctr){return Polymer.dom(this).queryDistributedElements(slctr);},getContentChildNodes:function(slctr){var content=Polymer.dom(this.root).querySelector(slctr||'content');return content?Polymer.dom(content).getDistributedNodes():[];},getContentChildren:function(slctr){return this.getContentChildNodes(slctr).filter(function(n){return n.nodeType===Node.ELEMENT_NODE;});},fire:function(type,detail,options){options=options||Polymer.nob;var node=options.node||this;detail=detail===null||detail===undefined?{}:detail;var bubbles=options.bubbles===undefined?true:options.bubbles;var cancelable=Boolean(options.cancelable);var useCache=options._useCache;var event=this._getEvent(type,bubbles,cancelable,useCache);event.detail=detail;if(useCache){this.__eventCache[type]=null;}
 node.dispatchEvent(event);if(useCache){this.__eventCache[type]=event;}
 return event;},__eventCache:{},_getEvent:function(type,bubbles,cancelable,useCache){var event=useCache&&this.__eventCache[type];if(!event||(event.bubbles!=bubbles||event.cancelable!=cancelable)){event=new Event(type,{bubbles:Boolean(bubbles),cancelable:cancelable});}
-return event;},async:function(callback,waitTime){var self=this;return Polymer.Async.run(function(){callback.call(self);},waitTime);},cancelAsync:function(handle){Polymer.Async.cancel(handle);},arrayDelete:function(path,item){var index;if(Array.isArray(path)){index=path.indexOf(item);if(index>=0){return path.splice(index,1);}}else{var arr=this._get(path);index=arr.indexOf(item);if(index>=0){return this.splice(path,index,1);}}},transform:function(transform,node){node=node||this;node.style.webkitTransform=transform;node.style.transform=transform;},translate3d:function(x,y,z,node){node=node||this;this.transform('translate3d('+x+','+y+','+z+')',node);},importHref:function(href,onload,onerror,optAsync){var link=document.createElement('link');link.rel='import';link.href=href;var list=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var cached=list[link.href];var imprt=cached||link;var self=this;if(onload){var loadListener=function(e){e.target.__firedLoad=true;e.target.removeEventListener('load',loadListener);return onload.call(self,e);};imprt.addEventListener('load',loadListener);}
-if(onerror){var errorListener=function(e){e.target.__firedError=true;e.target.removeEventListener('error',errorListener);return onerror.call(self,e);};imprt.addEventListener('error',errorListener);}
+return event;},async:function(callback,waitTime){var self=this;return Polymer.Async.run(function(){callback.call(self);},waitTime);},cancelAsync:function(handle){Polymer.Async.cancel(handle);},arrayDelete:function(path,item){var index;if(Array.isArray(path)){index=path.indexOf(item);if(index>=0){return path.splice(index,1);}}else{var arr=this._get(path);index=arr.indexOf(item);if(index>=0){return this.splice(path,index,1);}}},transform:function(transform,node){node=node||this;node.style.webkitTransform=transform;node.style.transform=transform;},translate3d:function(x,y,z,node){node=node||this;this.transform('translate3d('+x+','+y+','+z+')',node);},importHref:function(href,onload,onerror,optAsync){var link=document.createElement('link');link.rel='import';link.href=href;var list=Polymer.Base.importHref.imported=Polymer.Base.importHref.imported||{};var cached=list[link.href];var imprt=cached||link;var self=this;var loadListener=function(e){e.target.__firedLoad=true;e.target.removeEventListener('load',loadListener);e.target.removeEventListener('error',errorListener);return onload.call(self,e);};var errorListener=function(e){e.target.__firedError=true;e.target.removeEventListener('load',loadListener);e.target.removeEventListener('error',errorListener);return onerror.call(self,e);};if(onload){imprt.addEventListener('load',loadListener);}
+if(onerror){imprt.addEventListener('error',errorListener);}
 if(cached){if(cached.__firedLoad){cached.dispatchEvent(new Event('load'));}
 if(cached.__firedError){cached.dispatchEvent(new Event('error'));}}else{list[link.href]=link;optAsync=Boolean(optAsync);if(optAsync){link.setAttribute('async','');}
 document.head.appendChild(link);}
 return imprt;},create:function(tag,props){var elt=document.createElement(tag);if(props){for(var n in props){elt[n]=props[n];}}
-return elt;},isLightDescendant:function(node){return this!==node&&this.contains(node)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(node).getOwnerRoot();},isLocalDescendant:function(node){return this.root===Polymer.dom(node).getOwnerRoot();}});if(!Polymer.Settings.useNativeCustomElements){var importHref=Polymer.Base.importHref;Polymer.Base.importHref=function(href,onload,onerror,optAsync){CustomElements.ready=false;var loadFn=function(e){CustomElements.upgradeDocumentTree(document);CustomElements.ready=true;if(onload){return onload.call(this,e);}};return importHref.call(this,href,loadFn,onerror,optAsync);};}}());Polymer.Bind={prepareModel:function(model){Polymer.Base.mixin(model,this._modelApi);},_modelApi:{_notifyChange:function(source,event,value){value=value===undefined?this[source]:value;event=event||Polymer.CaseMap.camelToDashCase(source)+'-changed';this.fire(event,{value:value},{bubbles:false,cancelable:false,_useCache:true});},_propertySetter:function(property,value,effects,fromAbove){var old=this.__data__[property];if(old!==value&&(old===old||value===value)){this.__data__[property]=value;if(typeof value=='object'){this._clearPath(property);}
+return elt;},isLightDescendant:function(node){return this!==node&&this.contains(node)&&Polymer.dom(this).getOwnerRoot()===Polymer.dom(node).getOwnerRoot();},isLocalDescendant:function(node){return this.root===Polymer.dom(node).getOwnerRoot();}});if(!Polymer.Settings.useNativeCustomElements){var importHref=Polymer.Base.importHref;Polymer.Base.importHref=function(href,onload,onerror,optAsync){CustomElements.ready=false;var loadFn=function(e){CustomElements.upgradeDocumentTree(document);CustomElements.ready=true;if(onload){return onload.call(this,e);}};return importHref.call(this,href,loadFn,onerror,optAsync);};}}());Polymer.Bind={prepareModel:function(model){Polymer.Base.mixin(model,this._modelApi);},_modelApi:{_notifyChange:function(source,event,value){value=value===undefined?this[source]:value;event=event||Polymer.CaseMap.camelToDashCase(source)+'-changed';this.fire(event,{value:value},{bubbles:false,cancelable:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE});},_propertySetter:function(property,value,effects,fromAbove){var old=this.__data__[property];if(old!==value&&(old===old||value===value)){this.__data__[property]=value;if(typeof value=='object'){this._clearPath(property);}
 if(this._propertyChanged){this._propertyChanged(property,value,old);}
 if(effects){this._effectEffects(property,value,effects,old,fromAbove);}}
-return old;},__setProperty:function(property,value,quiet,node){node=node||this;var effects=node._propertyEffects&&node._propertyEffects[property];if(effects){node._propertySetter(property,value,effects,quiet);}else{node[property]=value;}},_effectEffects:function(property,value,effects,old,fromAbove){for(var i=0,l=effects.length,fx;i<l&&(fx=effects[i]);i++){fx.fn.call(this,property,this[property],fx.effect,old,fromAbove);}},_clearPath:function(path){for(var prop in this.__data__){if(prop.indexOf(path+'.')===0){this.__data__[prop]=undefined;}}}},ensurePropertyEffects:function(model,property){if(!model._propertyEffects){model._propertyEffects={};}
+return old;},__setProperty:function(property,value,quiet,node){node=node||this;var effects=node._propertyEffects&&node._propertyEffects[property];if(effects){node._propertySetter(property,value,effects,quiet);}else if(node[property]!==value){node[property]=value;}},_effectEffects:function(property,value,effects,old,fromAbove){for(var i=0,l=effects.length,fx;i<l&&(fx=effects[i]);i++){fx.fn.call(this,property,this[property],fx.effect,old,fromAbove);}},_clearPath:function(path){for(var prop in this.__data__){if(Polymer.Path.isDescendant(path,prop)){this.__data__[prop]=undefined;}}}},ensurePropertyEffects:function(model,property){if(!model._propertyEffects){model._propertyEffects={};}
 var fx=model._propertyEffects[property];if(!fx){fx=model._propertyEffects[property]=[];}
 return fx;},addPropertyEffect:function(model,property,kind,effect){var fx=this.ensurePropertyEffects(model,property);var propEffect={kind:kind,effect:effect,fn:Polymer.Bind['_'+kind+'Effect']};fx.push(propEffect);return propEffect;},createBindings:function(model){var fx$=model._propertyEffects;if(fx$){for(var n in fx$){var fx=fx$[n];fx.sort(this._sortPropertyEffects);this._createAccessors(model,n,fx);}}},_sortPropertyEffects:function(){var EFFECT_ORDER={'compute':0,'annotation':1,'annotatedComputation':2,'reflect':3,'notify':4,'observer':5,'complexObserver':6,'function':7};return function(a,b){return EFFECT_ORDER[a.kind]-EFFECT_ORDER[b.kind];};}(),_createAccessors:function(model,property,effects){var defun={get:function(){return this.__data__[property];}};var setter=function(value){this._propertySetter(property,value,effects);};var info=model.getPropertyInfo&&model.getPropertyInfo(property);if(info&&info.readOnly){if(!info.computed){model['_set'+this.upper(property)]=setter;}}else{defun.set=setter;}
 Object.defineProperty(model,property,defun);},upper:function(name){return name[0].toUpperCase()+name.substring(1);},_addAnnotatedListener:function(model,index,property,path,event,negated){if(!model._bindListeners){model._bindListeners=[];}
-var fn=this._notedListenerFactory(property,path,this._isStructured(path),negated);var eventName=event||Polymer.CaseMap.camelToDashCase(property)+'-changed';model._bindListeners.push({index:index,property:property,path:path,changedFn:fn,event:eventName});},_isStructured:function(path){return path.indexOf('.')>0;},_isEventBogus:function(e,target){return e.path&&e.path[0]!==target;},_notedListenerFactory:function(property,path,isStructured,negated){return function(target,value,targetPath){if(targetPath){this._notifyPath(this._fixPath(path,property,targetPath),value);}else{value=target[property];if(negated){value=!value;}
-if(!isStructured){this[path]=value;}else{if(this.__data__[path]!=value){this.set(path,value);}}}};},prepareInstance:function(inst){inst.__data__=Object.create(null);},setupBindListeners:function(inst){var b$=inst._bindListeners;for(var i=0,l=b$.length,info;i<l&&(info=b$[i]);i++){var node=inst._nodes[info.index];this._addNotifyListener(node,inst,info.event,info.changedFn);}},_addNotifyListener:function(element,context,event,changedFn){element.addEventListener(event,function(e){return context._notifyListener(changedFn,e);});}};Polymer.Base.extend(Polymer.Bind,{_shouldAddListener:function(effect){return effect.name&&effect.kind!='attribute'&&effect.kind!='text'&&!effect.isCompound&&effect.parts[0].mode==='{';},_annotationEffect:function(source,value,effect){if(source!=effect.value){value=this._get(effect.value);this.__data__[effect.value]=value;}
+var fn=this._notedListenerFactory(property,path,Polymer.Path.isDeep(path),negated);var eventName=event||Polymer.CaseMap.camelToDashCase(property)+'-changed';model._bindListeners.push({index:index,property:property,path:path,changedFn:fn,event:eventName});},_isEventBogus:function(e,target){return e.path&&e.path[0]!==target;},_notedListenerFactory:function(property,path,isStructured,negated){return function(target,value,targetPath){if(targetPath){var newPath=Polymer.Path.translate(property,path,targetPath);this._notifyPath(newPath,value);}else{value=target[property];if(negated){value=!value;}
+if(!isStructured){this[path]=value;}else{if(this.__data__[path]!=value){this.set(path,value);}}}};},prepareInstance:function(inst){inst.__data__=Object.create(null);},setupBindListeners:function(inst){var b$=inst._bindListeners;for(var i=0,l=b$.length,info;i<l&&(info=b$[i]);i++){var node=inst._nodes[info.index];this._addNotifyListener(node,inst,info.event,info.changedFn);}},_addNotifyListener:function(element,context,event,changedFn){element.addEventListener(event,function(e){return context._notifyListener(changedFn,e);});}};Polymer.Base.mixin(Polymer.Bind,{_shouldAddListener:function(effect){return effect.name&&effect.kind!='attribute'&&effect.kind!='text'&&!effect.isCompound&&effect.parts[0].mode==='{';},_annotationEffect:function(source,value,effect){if(source!=effect.value){value=this._get(effect.value);this.__data__[effect.value]=value;}
 this._applyEffectValue(effect,value);},_reflectEffect:function(source,value,effect){this.reflectPropertyToAttribute(source,effect.attribute,value);},_notifyEffect:function(source,value,effect,old,fromAbove){if(!fromAbove){this._notifyChange(source,effect.event,value);}},_functionEffect:function(source,value,fn,old,fromAbove){fn.call(this,source,value,old,fromAbove);},_observerEffect:function(source,value,effect,old){var fn=this[effect.method];if(fn){fn.call(this,value,old);}else{this._warn(this._logf('_observerEffect','observer method `'+effect.method+'` not defined'));}},_complexObserverEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){fn.apply(this,args);}}else if(effect.dynamicFn){}else{this._warn(this._logf('_complexObserverEffect','observer method `'+effect.method+'` not defined'));}},_computeEffect:function(source,value,effect){var fn=this[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(this,args);this.__setProperty(effect.name,computedvalue);}}else if(effect.dynamicFn){}else{this._warn(this._logf('_computeEffect','compute method `'+effect.method+'` not defined'));}},_annotatedComputationEffect:function(source,value,effect){var computedHost=this._rootDataHost||this;var fn=computedHost[effect.method];if(fn){var args=Polymer.Bind._marshalArgs(this.__data__,effect,source,value);if(args){var computedvalue=fn.apply(computedHost,args);this._applyEffectValue(effect,computedvalue);}}else if(effect.dynamicFn){}else{computedHost._warn(computedHost._logf('_annotatedComputationEffect','compute method `'+effect.method+'` not defined'));}},_marshalArgs:function(model,effect,path,value){var values=[];var args=effect.args;var bailoutEarly=args.length>1||effect.dynamicFn;for(var i=0,l=args.length;i<l;i++){var arg=args[i];var name=arg.name;var v;if(arg.literal){v=arg.value;}else if(path===name){v=value;}else{v=model[name];if(v===undefined&&arg.structured){v=Polymer.Base._get(name,model);}}
 if(bailoutEarly&&v===undefined){return;}
-if(arg.wildcard){var matches=path.indexOf(name+'.')===0;values[i]={path:matches?path:name,value:matches?value:v,base:v};}else{values[i]=v;}}
+if(arg.wildcard){var matches=Polymer.Path.isAncestor(path,name);values[i]={path:matches?path:name,value:matches?value:v,base:v};}else{values[i]=v;}}
 return values;}});Polymer.Base._addFeature({_addPropertyEffect:function(property,kind,effect){var prop=Polymer.Bind.addPropertyEffect(this,property,kind,effect);prop.pathFn=this['_'+prop.kind+'PathEffect'];},_prepEffects:function(){Polymer.Bind.prepareModel(this);this._addAnnotationEffects(this._notes);},_prepBindings:function(){Polymer.Bind.createBindings(this);},_addPropertyEffects:function(properties){if(properties){for(var p in properties){var prop=properties[p];if(prop.observer){this._addObserverEffect(p,prop.observer);}
 if(prop.computed){prop.readOnly=true;this._addComputedEffect(p,prop.computed);}
 if(prop.notify){this._addPropertyEffect(p,'notify',{event:Polymer.CaseMap.camelToDashCase(p)+'-changed'});}
@@ -3890,19 +3942,18 @@
 return arg;},this);return sig;},_parseArg:function(rawArg){var arg=rawArg.trim().replace(/&comma;/g,',').replace(/\\(.)/g,'$1');var a={name:arg};var fc=arg[0];if(fc==='-'){fc=arg[1];}
 if(fc>='0'&&fc<='9'){fc='#';}
 switch(fc){case'\'':case'"':a.value=arg.slice(1,-1);a.literal=true;break;case'#':a.value=Number(arg);a.literal=true;break;}
-if(!a.literal){a.model=this._modelForPath(arg);a.structured=arg.indexOf('.')>0;if(a.structured){a.wildcard=arg.slice(-2)=='.*';if(a.wildcard){a.name=arg.slice(0,-2);}}}
-return a;},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);if(this._bindListeners){Polymer.Bind.setupBindListeners(this);}},_applyEffectValue:function(info,value){var node=this._nodes[info.index];var property=info.name;value=this._computeFinalAnnotationValue(node,property,value,info);if(info.customEvent&&node[property]===value){return;}
-if(info.kind=='attribute'){this.serializeValueToAttribute(value,property,node);}else{var pinfo=node._propertyInfo&&node._propertyInfo[property];if(pinfo&&pinfo.readOnly){return;}
-this.__setProperty(property,value,false,node);}},_computeFinalAnnotationValue:function(node,property,value,info){if(info.negate){value=!value;}
+if(!a.literal){a.model=Polymer.Path.root(arg);a.structured=Polymer.Path.isDeep(arg);if(a.structured){a.wildcard=arg.slice(-2)=='.*';if(a.wildcard){a.name=arg.slice(0,-2);}}}
+return a;},_marshalInstanceEffects:function(){Polymer.Bind.prepareInstance(this);if(this._bindListeners){Polymer.Bind.setupBindListeners(this);}},_applyEffectValue:function(info,value){var node=this._nodes[info.index];var property=info.name;value=this._computeFinalAnnotationValue(node,property,value,info);if(info.kind=='attribute'){this.serializeValueToAttribute(value,property,node);}else{var pinfo=node._propertyInfo&&node._propertyInfo[property];if(pinfo&&pinfo.readOnly){return;}
+this.__setProperty(property,value,Polymer.Settings.suppressBindingNotifications,node);}},_computeFinalAnnotationValue:function(node,property,value,info){if(info.negate){value=!value;}
 if(info.isCompound){var storage=node.__compoundStorage__[property];storage[info.compoundIndex]=value;value=storage.join('');}
 if(info.kind!=='attribute'){if(property==='className'){value=this._scopeElementClass(node,value);}
 if(property==='textContent'||node.localName=='input'&&property=='value'){value=value==undefined?'':value;}}
-return value;},_executeStaticEffects:function(){if(this._propertyEffects&&this._propertyEffects.__static__){this._effectEffects('__static__',null,this._propertyEffects.__static__);}}});(function(){var usePolyfillProto=Polymer.Settings.usePolyfillProto;Polymer.Base._addFeature({_setupConfigure:function(initialConfig){this._config={};this._handlers=[];this._aboveConfig=null;if(initialConfig){for(var i in initialConfig){if(initialConfig[i]!==undefined){this._config[i]=initialConfig[i];}}}},_marshalAttributes:function(){this._takeAttributesToModel(this._config);},_attributeChangedImpl:function(name){var model=this._clientsReadied?this:this._config;this._setAttributeToProperty(model,name);},_configValue:function(name,value){var info=this._propertyInfo[name];if(!info||!info.readOnly){this._config[name]=value;}},_beforeClientsReady:function(){this._configure();},_configure:function(){this._configureAnnotationReferences();this._aboveConfig=this.mixin({},this._config);var config={};for(var i=0;i<this.behaviors.length;i++){this._configureProperties(this.behaviors[i].properties,config);}
-this._configureProperties(this.properties,config);this.mixin(config,this._aboveConfig);this._config=config;if(this._clients&&this._clients.length){this._distributeConfig(this._config);}},_configureProperties:function(properties,config){for(var i in properties){var c=properties[i];if(!usePolyfillProto&&this.hasOwnProperty(i)&&this._propertyEffects&&this._propertyEffects[i]){config[i]=this[i];delete this[i];}else if(c.value!==undefined){var value=c.value;if(typeof value=='function'){value=value.call(this,this._config);}
+return value;},_executeStaticEffects:function(){if(this._propertyEffects&&this._propertyEffects.__static__){this._effectEffects('__static__',null,this._propertyEffects.__static__);}}});(function(){var usePolyfillProto=Polymer.Settings.usePolyfillProto;var avoidInstanceProperties=Boolean(Object.getOwnPropertyDescriptor(document.documentElement,'properties'));Polymer.Base._addFeature({_setupConfigure:function(initialConfig){this._config={};this._handlers=[];this._aboveConfig=null;if(initialConfig){for(var i in initialConfig){if(initialConfig[i]!==undefined){this._config[i]=initialConfig[i];}}}},_marshalAttributes:function(){this._takeAttributesToModel(this._config);},_attributeChangedImpl:function(name){var model=this._clientsReadied?this:this._config;this._setAttributeToProperty(model,name);},_configValue:function(name,value){var info=this._propertyInfo[name];if(!info||!info.readOnly){this._config[name]=value;}},_beforeClientsReady:function(){this._configure();},_configure:function(){this._configureAnnotationReferences();this._configureInstanceProperties();this._aboveConfig=this.mixin({},this._config);var config={};for(var i=0;i<this.behaviors.length;i++){this._configureProperties(this.behaviors[i].properties,config);}
+this._configureProperties(avoidInstanceProperties?this.__proto__.properties:this.properties,config);this.mixin(config,this._aboveConfig);this._config=config;if(this._clients&&this._clients.length){this._distributeConfig(this._config);}},_configureInstanceProperties:function(){for(var i in this._propertyEffects){if(!usePolyfillProto&&this.hasOwnProperty(i)){this._configValue(i,this[i]);delete this[i];}}},_configureProperties:function(properties,config){for(var i in properties){var c=properties[i];if(c.value!==undefined){var value=c.value;if(typeof value=='function'){value=value.call(this,this._config);}
 config[i]=value;}}},_distributeConfig:function(config){var fx$=this._propertyEffects;if(fx$){for(var p in config){var fx=fx$[p];if(fx){for(var i=0,l=fx.length,x;i<l&&(x=fx[i]);i++){if(x.kind==='annotation'){var node=this._nodes[x.effect.index];var name=x.effect.propertyName;var isAttr=x.effect.kind=='attribute';var hasEffect=node._propertyEffects&&node._propertyEffects[name];if(node._configValue&&(hasEffect||!isAttr)){var value=p===x.effect.value?config[p]:this._get(x.effect.value,config);value=this._computeFinalAnnotationValue(node,name,value,x.effect);if(isAttr){value=node.deserialize(this.serialize(value),node._propertyInfo[name].type);}
 node._configValue(name,value);}}}}}}},_afterClientsReady:function(){this._executeStaticEffects();this._applyConfig(this._config,this._aboveConfig);this._flushHandlers();},_applyConfig:function(config,aboveConfig){for(var n in config){if(this[n]===undefined){this.__setProperty(n,config[n],n in aboveConfig);}}},_notifyListener:function(fn,e){if(!Polymer.Bind._isEventBogus(e,e.target)){var value,path;if(e.detail){value=e.detail.value;path=e.detail.path;}
 if(!this._clientsReadied){this._queueHandler([fn,e.target,value,path]);}else{return fn.call(this,e.target,value,path);}}},_queueHandler:function(args){this._handlers.push(args);},_flushHandlers:function(){var h$=this._handlers;for(var i=0,l=h$.length,h;i<l&&(h=h$[i]);i++){h[0].call(this,h[1],h[2],h[3]);}
-this._handlers=[];}});}());(function(){'use strict';Polymer.Base._addFeature({notifyPath:function(path,value,fromAbove){var info={};var v=this._get(path,this,info);if(arguments.length===1){value=v;}
+this._handlers=[];}});}());(function(){'use strict';var Path=Polymer.Path;Polymer.Base._addFeature({notifyPath:function(path,value,fromAbove){var info={};var v=this._get(path,this,info);if(arguments.length===1){value=v;}
 if(info.path){this._notifyPath(info.path,value,fromAbove);}},_notifyPath:function(path,value,fromAbove){var old=this._propertySetter(path,value);if(old!==value&&(old===old||value===value)){this._pathEffector(path,value);if(!fromAbove){this._notifyPathUp(path,value);}
 return true;}},_getPathParts:function(path){if(Array.isArray(path)){var parts=[];for(var i=0;i<path.length;i++){var args=path[i].toString().split('.');for(var j=0;j<args.length;j++){parts.push(args[j]);}}
 return parts;}else{return path.toString().split('.');}},set:function(path,value,root){var prop=root||this;var parts=this._getPathParts(path);var array;var last=parts[parts.length-1];if(parts.length>1){for(var i=0;i<parts.length-1;i++){var part=parts[i];if(array&&part[0]=='#'){prop=Polymer.Collection.get(array).getItem(part);}else{prop=prop[part];if(array&&parseInt(part,10)==part){parts[i]=Polymer.Collection.get(array).getKey(prop);}}
@@ -3913,15 +3964,15 @@
 var part=parts[i];if(array&&part[0]=='#'){prop=Polymer.Collection.get(array).getItem(part);}else{prop=prop[part];if(info&&array&&parseInt(part,10)==part){parts[i]=Polymer.Collection.get(array).getKey(prop);}}
 array=Array.isArray(prop)?prop:null;}
 if(info){info.path=parts.join('.');}
-return prop;},_pathEffector:function(path,value){var model=this._modelForPath(path);var fx$=this._propertyEffects&&this._propertyEffects[model];if(fx$){for(var i=0,fx;i<fx$.length&&(fx=fx$[i]);i++){var fxFn=fx.pathFn;if(fxFn){fxFn.call(this,path,value,fx.effect);}}}
-if(this._boundPaths){this._notifyBoundPaths(path,value);}},_annotationPathEffect:function(path,value,effect){if(effect.value===path||effect.value.indexOf(path+'.')===0){Polymer.Bind._annotationEffect.call(this,path,value,effect);}else if(path.indexOf(effect.value+'.')===0&&!effect.negate){var node=this._nodes[effect.index];if(node&&node._notifyPath){var p=this._fixPath(effect.name,effect.value,path);node._notifyPath(p,value,true);}}},_complexObserverPathEffect:function(path,value,effect){if(this._pathMatchesEffect(path,effect)){Polymer.Bind._complexObserverEffect.call(this,path,value,effect);}},_computePathEffect:function(path,value,effect){if(this._pathMatchesEffect(path,effect)){Polymer.Bind._computeEffect.call(this,path,value,effect);}},_annotatedComputationPathEffect:function(path,value,effect){if(this._pathMatchesEffect(path,effect)){Polymer.Bind._annotatedComputationEffect.call(this,path,value,effect);}},_pathMatchesEffect:function(path,effect){var effectArg=effect.trigger.name;return effectArg==path||effectArg.indexOf(path+'.')===0||effect.trigger.wildcard&&path.indexOf(effectArg+'.')===0;},linkPaths:function(to,from){this._boundPaths=this._boundPaths||{};if(from){this._boundPaths[to]=from;}else{this.unlinkPaths(to);}},unlinkPaths:function(path){if(this._boundPaths){delete this._boundPaths[path];}},_notifyBoundPaths:function(path,value){for(var a in this._boundPaths){var b=this._boundPaths[a];if(path.indexOf(a+'.')==0){this._notifyPath(this._fixPath(b,a,path),value);}else if(path.indexOf(b+'.')==0){this._notifyPath(this._fixPath(a,b,path),value);}}},_fixPath:function(property,root,path){return property+path.slice(root.length);},_notifyPathUp:function(path,value){var rootName=this._modelForPath(path);var dashCaseName=Polymer.CaseMap.camelToDashCase(rootName);var eventName=dashCaseName+this._EVENT_CHANGED;this.fire(eventName,{path:path,value:value},{bubbles:false,_useCache:true});},_modelForPath:function(path){var dot=path.indexOf('.');return dot<0?path:path.slice(0,dot);},_EVENT_CHANGED:'-changed',notifySplices:function(path,splices){var info={};var array=this._get(path,this,info);this._notifySplices(array,info.path,splices);},_notifySplices:function(array,path,splices){var change={keySplices:Polymer.Collection.applySplices(array,splices),indexSplices:splices};var splicesPath=path+'.splices';this._notifyPath(splicesPath,change);this._notifyPath(path+'.length',array.length);this.__data__[splicesPath]={keySplices:null,indexSplices:null};},_notifySplice:function(array,path,index,added,removed){this._notifySplices(array,path,[{index:index,addedCount:added,removed:removed,object:array,type:'splice'}]);},push:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var len=array.length;var ret=array.push.apply(array,args);if(args.length){this._notifySplice(array,info.path,len,args.length,[]);}
+return prop;},_pathEffector:function(path,value){var model=Path.root(path);var fx$=this._propertyEffects&&this._propertyEffects[model];if(fx$){for(var i=0,fx;i<fx$.length&&(fx=fx$[i]);i++){var fxFn=fx.pathFn;if(fxFn){fxFn.call(this,path,value,fx.effect);}}}
+if(this._boundPaths){this._notifyBoundPaths(path,value);}},_annotationPathEffect:function(path,value,effect){if(Path.matches(effect.value,false,path)){Polymer.Bind._annotationEffect.call(this,path,value,effect);}else if(!effect.negate&&Path.isDescendant(effect.value,path)){var node=this._nodes[effect.index];if(node&&node._notifyPath){var newPath=Path.translate(effect.value,effect.name,path);node._notifyPath(newPath,value,true);}}},_complexObserverPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._complexObserverEffect.call(this,path,value,effect);}},_computePathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._computeEffect.call(this,path,value,effect);}},_annotatedComputationPathEffect:function(path,value,effect){if(Path.matches(effect.trigger.name,effect.trigger.wildcard,path)){Polymer.Bind._annotatedComputationEffect.call(this,path,value,effect);}},linkPaths:function(to,from){this._boundPaths=this._boundPaths||{};if(from){this._boundPaths[to]=from;}else{this.unlinkPaths(to);}},unlinkPaths:function(path){if(this._boundPaths){delete this._boundPaths[path];}},_notifyBoundPaths:function(path,value){for(var a in this._boundPaths){var b=this._boundPaths[a];if(Path.isDescendant(a,path)){this._notifyPath(Path.translate(a,b,path),value);}else if(Path.isDescendant(b,path)){this._notifyPath(Path.translate(b,a,path),value);}}},_notifyPathUp:function(path,value){var rootName=Path.root(path);var dashCaseName=Polymer.CaseMap.camelToDashCase(rootName);var eventName=dashCaseName+this._EVENT_CHANGED;this.fire(eventName,{path:path,value:value},{bubbles:false,_useCache:Polymer.Settings.eventDataCache||!Polymer.Settings.isIE});},_EVENT_CHANGED:'-changed',notifySplices:function(path,splices){var info={};var array=this._get(path,this,info);this._notifySplices(array,info.path,splices);},_notifySplices:function(array,path,splices){var change={keySplices:Polymer.Collection.applySplices(array,splices),indexSplices:splices};var splicesPath=path+'.splices';this._notifyPath(splicesPath,change);this._notifyPath(path+'.length',array.length);this.__data__[splicesPath]={keySplices:null,indexSplices:null};},_notifySplice:function(array,path,index,added,removed){this._notifySplices(array,path,[{index:index,addedCount:added,removed:removed,object:array,type:'splice'}]);},push:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var len=array.length;var ret=array.push.apply(array,args);if(args.length){this._notifySplice(array,info.path,len,args.length,[]);}
 return ret;},pop:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.pop.apply(array,args);if(hadLength){this._notifySplice(array,info.path,array.length,0,[ret]);}
 return ret;},splice:function(path,start){var info={};var array=this._get(path,this,info);if(start<0){start=array.length-Math.floor(-start);}else{start=Math.floor(start);}
 if(!start){start=0;}
 var args=Array.prototype.slice.call(arguments,1);var ret=array.splice.apply(array,args);var addedCount=Math.max(args.length-2,0);if(addedCount||ret.length){this._notifySplice(array,info.path,start,addedCount,ret);}
 return ret;},shift:function(path){var info={};var array=this._get(path,this,info);var hadLength=Boolean(array.length);var args=Array.prototype.slice.call(arguments,1);var ret=array.shift.apply(array,args);if(hadLength){this._notifySplice(array,info.path,0,0,[ret]);}
 return ret;},unshift:function(path){var info={};var array=this._get(path,this,info);var args=Array.prototype.slice.call(arguments,1);var ret=array.unshift.apply(array,args);if(args.length){this._notifySplice(array,info.path,0,args.length,[]);}
-return ret;},prepareModelNotifyPath:function(model){this.mixin(model,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,notifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_modelForPath:Polymer.Base._modelForPath,_pathMatchesEffect:Polymer.Base._pathMatchesEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,_getPathParts:Polymer.Base._getPathParts});}});}());Polymer.Base._addFeature({resolveUrl:function(url){var module=Polymer.DomModule.import(this.is);var root='';if(module){var assetPath=module.getAttribute('assetpath')||'';root=Polymer.ResolveUrl.resolveUrl(assetPath,module.ownerDocument.baseURI);}
+return ret;},prepareModelNotifyPath:function(model){this.mixin(model,{fire:Polymer.Base.fire,_getEvent:Polymer.Base._getEvent,__eventCache:Polymer.Base.__eventCache,notifyPath:Polymer.Base.notifyPath,_get:Polymer.Base._get,_EVENT_CHANGED:Polymer.Base._EVENT_CHANGED,_notifyPath:Polymer.Base._notifyPath,_notifyPathUp:Polymer.Base._notifyPathUp,_pathEffector:Polymer.Base._pathEffector,_annotationPathEffect:Polymer.Base._annotationPathEffect,_complexObserverPathEffect:Polymer.Base._complexObserverPathEffect,_annotatedComputationPathEffect:Polymer.Base._annotatedComputationPathEffect,_computePathEffect:Polymer.Base._computePathEffect,_notifyBoundPaths:Polymer.Base._notifyBoundPaths,_getPathParts:Polymer.Base._getPathParts});}});}());Polymer.Base._addFeature({resolveUrl:function(url){var module=Polymer.DomModule.import(this.is);var root='';if(module){var assetPath=module.getAttribute('assetpath')||'';root=Polymer.ResolveUrl.resolveUrl(assetPath,module.ownerDocument.baseURI);}
 return Polymer.ResolveUrl.resolveUrl(url,root);}});Polymer.CssParse=function(){return{parse:function(text){text=this._clean(text);return this._parseCss(this._lex(text),text);},_clean:function(cssText){return cssText.replace(this._rx.comments,'').replace(this._rx.port,'');},_lex:function(text){var root={start:0,end:text.length};var n=root;for(var i=0,l=text.length;i<l;i++){switch(text[i]){case this.OPEN_BRACE:if(!n.rules){n.rules=[];}
 var p=n;var previous=p.rules[p.rules.length-1];n={start:i+1,parent:p,previous:previous};p.rules.push(n);break;case this.CLOSE_BRACE:n.end=i+1;n=n.parent||root;break;}}
 return root;},_parseCss:function(node,text){var t=text.substring(node.start,node.end-1);node.parsedCssText=node.cssText=t.trim();if(node.parent){var ss=node.previous?node.previous.end:node.parent.start;t=text.substring(ss,node.start-1);t=this._expandUnicodeEscapes(t);t=t.replace(this._rx.multipleSpaces,' ');t=t.substring(t.lastIndexOf(';')+1);var s=node.parsedSelector=node.selector=t.trim();node.atRule=s.indexOf(this.AT_START)===0;if(node.atRule){if(s.indexOf(this.MEDIA_START)===0){node.type=this.types.MEDIA_RULE;}else if(s.match(this._rx.keyframesRule)){node.type=this.types.KEYFRAMES_RULE;node.keyframesName=node.selector.split(this._rx.multipleSpaces).pop();}}else{if(s.indexOf(this.VAR_START)===0){node.type=this.types.MIXIN_RULE;}else{node.type=this.types.STYLE_RULE;}}}
@@ -3942,54 +3993,74 @@
 style.textContent=cssText;return style;},__lastHeadApplyNode:null,applyStylePlaceHolder:function(moniker){var placeHolder=document.createComment(' Shady DOM styles for '+moniker+' ');var after=this.__lastHeadApplyNode?this.__lastHeadApplyNode.nextSibling:null;var scope=document.head;scope.insertBefore(placeHolder,after||scope.firstChild);this.__lastHeadApplyNode=placeHolder;return placeHolder;},cssFromModules:function(moduleIds,warnIfNotFound){var modules=moduleIds.trim().split(' ');var cssText='';for(var i=0;i<modules.length;i++){cssText+=this.cssFromModule(modules[i],warnIfNotFound);}
 return cssText;},cssFromModule:function(moduleId,warnIfNotFound){var m=Polymer.DomModule.import(moduleId);if(m&&!m._cssText){m._cssText=this.cssFromElement(m);}
 if(!m&&warnIfNotFound){console.warn('Could not find style data in module named',moduleId);}
-return m&&m._cssText||'';},cssFromElement:function(element){var cssText='';var content=element.content||element;var e$=Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));for(var i=0,e;i<e$.length;i++){e=e$[i];if(e.localName==='template'){cssText+=this.cssFromElement(e);}else{if(e.localName==='style'){var include=e.getAttribute(this.INCLUDE_ATTR);if(include){cssText+=this.cssFromModules(include,true);}
+return m&&m._cssText||'';},cssFromElement:function(element){var cssText='';var content=element.content||element;var e$=Polymer.TreeApi.arrayCopy(content.querySelectorAll(this.MODULE_STYLES_SELECTOR));for(var i=0,e;i<e$.length;i++){e=e$[i];if(e.localName==='template'){if(!e.hasAttribute('preserve-content')){cssText+=this.cssFromElement(e);}}else{if(e.localName==='style'){var include=e.getAttribute(this.INCLUDE_ATTR);if(include){cssText+=this.cssFromModules(include,true);}
 e=e.__appliedElement||e;e.parentNode.removeChild(e);cssText+=this.resolveCss(e.textContent,element.ownerDocument);}else if(e.import&&e.import.body){cssText+=this.resolveCss(e.import.body.textContent,e.import);}}}
-return cssText;},isTargetedBuild:function(buildType){return settings.useNativeShadow?buildType==='shadow':buildType==='shady';},cssBuildTypeForModule:function(module){var dm=Polymer.DomModule.import(module);if(dm){return this.getCssBuildType(dm);}},getCssBuildType:function(element){return element.getAttribute('css-build');},rx:{VAR_ASSIGN:/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,MIXIN_MATCH:/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,VAR_MATCH:/(^|\W+)var\([\s]*([^,)]*)[\s]*,?[\s]*((?:[^,()]*)|(?:[^;()]*\([^;)]*\)+))[\s]*?\)/gi,VAR_CONSUMED:/(--[\w-]+)\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\s*:)|(animation-name\s*:)/,MEDIA_MATCH:/@media[^(]*(\([^)]*\))/,IS_VAR:/^--/,BRACKETED:/\{[^}]*\}/g,HOST_PREFIX:'(?:^|[^.#[:])',HOST_SUFFIX:'($|[.:[\\s>+~])'},resolveCss:Polymer.ResolveUrl.resolveCss,parser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types};}();Polymer.StyleTransformer=function(){var styleUtil=Polymer.StyleUtil;var settings=Polymer.Settings;var api={dom:function(node,scope,useAttr,shouldRemoveScope){this._transformDom(node,scope||'',useAttr,shouldRemoveScope);},_transformDom:function(node,selector,useAttr,shouldRemoveScope){if(node.setAttribute){this.element(node,selector,useAttr,shouldRemoveScope);}
-var c$=Polymer.dom(node).childNodes;for(var i=0;i<c$.length;i++){this._transformDom(c$[i],selector,useAttr,shouldRemoveScope);}},element:function(element,scope,useAttr,shouldRemoveScope){if(useAttr){if(shouldRemoveScope){element.removeAttribute(SCOPE_NAME);}else{element.setAttribute(SCOPE_NAME,scope);}}else{if(scope){if(element.classList){if(shouldRemoveScope){element.classList.remove(SCOPE_NAME);element.classList.remove(scope);}else{element.classList.add(SCOPE_NAME);element.classList.add(scope);}}else if(element.getAttribute){var c=element.getAttribute(CLASS);if(shouldRemoveScope){if(c){element.setAttribute(CLASS,c.replace(SCOPE_NAME,'').replace(scope,''));}}else{element.setAttribute(CLASS,(c?c+' ':'')+SCOPE_NAME+' '+scope);}}}}},elementStyles:function(element,callback){var styles=element._styles;var cssText='';var cssBuildType=element.__cssBuild;for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){var rules=styleUtil.rulesForStyle(s);cssText+=settings.useNativeShadow||cssBuildType==='shady'?styleUtil.toCssText(rules,callback):this.css(rules,element.is,element.extends,callback,element._scopeCssViaAttr)+'\n\n';}
+return cssText;},styleIncludesToTemplate:function(targetTemplate){var styles=targetTemplate.content.querySelectorAll('style[include]');for(var i=0,s;i<styles.length;i++){s=styles[i];s.parentNode.insertBefore(this._includesToFragment(s.getAttribute('include')),s);}},_includesToFragment:function(styleIncludes){var includeArray=styleIncludes.trim().split(' ');var frag=document.createDocumentFragment();for(var i=0;i<includeArray.length;i++){var t=Polymer.DomModule.import(includeArray[i],'template');if(t){this._addStylesToFragment(frag,t.content);}}
+return frag;},_addStylesToFragment:function(frag,source){var s$=source.querySelectorAll('style');for(var i=0,s;i<s$.length;i++){s=s$[i];var include=s.getAttribute('include');if(include){frag.appendChild(this._includesToFragment(include));}
+if(s.textContent){frag.appendChild(s.cloneNode(true));}}},isTargetedBuild:function(buildType){return settings.useNativeShadow?buildType==='shadow':buildType==='shady';},cssBuildTypeForModule:function(module){var dm=Polymer.DomModule.import(module);if(dm){return this.getCssBuildType(dm);}},getCssBuildType:function(element){return element.getAttribute('css-build');},_findMatchingParen:function(text,start){var level=0;for(var i=start,l=text.length;i<l;i++){switch(text[i]){case'(':level++;break;case')':if(--level===0){return i;}
+break;}}
+return-1;},processVariableAndFallback:function(str,callback){var start=str.indexOf('var(');if(start===-1){return callback(str,'','','');}
+var end=this._findMatchingParen(str,start+3);var inner=str.substring(start+4,end);var prefix=str.substring(0,start);var suffix=this.processVariableAndFallback(str.substring(end+1),callback);var comma=inner.indexOf(',');if(comma===-1){return callback(prefix,inner.trim(),'',suffix);}
+var value=inner.substring(0,comma).trim();var fallback=inner.substring(comma+1).trim();return callback(prefix,value,fallback,suffix);},rx:{VAR_ASSIGN:/(?:^|[;\s{]\s*)(--[\w-]*?)\s*:\s*(?:([^;{]*)|{([^}]*)})(?:(?=[;\s}])|$)/gi,MIXIN_MATCH:/(?:^|\W+)@apply\s*\(?([^);\n]*)\)?/gi,VAR_CONSUMED:/(--[\w-]+)\s*([:,;)]|$)/gi,ANIMATION_MATCH:/(animation\s*:)|(animation-name\s*:)/,MEDIA_MATCH:/@media[^(]*(\([^)]*\))/,IS_VAR:/^--/,BRACKETED:/\{[^}]*\}/g,HOST_PREFIX:'(?:^|[^.#[:])',HOST_SUFFIX:'($|[.:[\\s>+~])'},resolveCss:Polymer.ResolveUrl.resolveCss,parser:Polymer.CssParse,ruleTypes:Polymer.CssParse.types};}();Polymer.StyleTransformer=function(){var styleUtil=Polymer.StyleUtil;var settings=Polymer.Settings;var api={dom:function(node,scope,useAttr,shouldRemoveScope){this._transformDom(node,scope||'',useAttr,shouldRemoveScope);},_transformDom:function(node,selector,useAttr,shouldRemoveScope){if(node.setAttribute){this.element(node,selector,useAttr,shouldRemoveScope);}
+var c$=Polymer.dom(node).childNodes;for(var i=0;i<c$.length;i++){this._transformDom(c$[i],selector,useAttr,shouldRemoveScope);}},element:function(element,scope,useAttr,shouldRemoveScope){if(useAttr){if(shouldRemoveScope){element.removeAttribute(SCOPE_NAME);}else{element.setAttribute(SCOPE_NAME,scope);}}else{if(scope){if(element.classList){if(shouldRemoveScope){element.classList.remove(SCOPE_NAME);element.classList.remove(scope);}else{element.classList.add(SCOPE_NAME);element.classList.add(scope);}}else if(element.getAttribute){var c=element.getAttribute(CLASS);if(shouldRemoveScope){if(c){element.setAttribute(CLASS,c.replace(SCOPE_NAME,'').replace(scope,''));}}else{element.setAttribute(CLASS,(c?c+' ':'')+SCOPE_NAME+' '+scope);}}}}},elementStyles:function(element,callback){var styles=element._styles;var cssText='';var cssBuildType=element.__cssBuild;var passthrough=settings.useNativeShadow||cssBuildType==='shady';var cb;if(passthrough){var self=this;cb=function(rule){rule.selector=self._slottedToContent(rule.selector);rule.selector=rule.selector.replace(ROOT,':host > *');if(callback){callback(rule);}};}
+for(var i=0,l=styles.length,s;i<l&&(s=styles[i]);i++){var rules=styleUtil.rulesForStyle(s);cssText+=passthrough?styleUtil.toCssText(rules,cb):this.css(rules,element.is,element.extends,callback,element._scopeCssViaAttr)+'\n\n';}
 return cssText.trim();},css:function(rules,scope,ext,callback,useAttr){var hostScope=this._calcHostScope(scope,ext);scope=this._calcElementScope(scope,useAttr);var self=this;return styleUtil.toCssText(rules,function(rule){if(!rule.isScoped){self.rule(rule,scope,hostScope);rule.isScoped=true;}
 if(callback){callback(rule,scope,hostScope);}});},_calcElementScope:function(scope,useAttr){if(scope){return useAttr?CSS_ATTR_PREFIX+scope+CSS_ATTR_SUFFIX:CSS_CLASS_PREFIX+scope;}else{return'';}},_calcHostScope:function(scope,ext){return ext?'[is='+scope+']':scope;},rule:function(rule,scope,hostScope){this._transformRule(rule,this._transformComplexSelector,scope,hostScope);},_transformRule:function(rule,transformer,scope,hostScope){rule.selector=rule.transformedSelector=this._transformRuleCss(rule,transformer,scope,hostScope);},_transformRuleCss:function(rule,transformer,scope,hostScope){var p$=rule.selector.split(COMPLEX_SELECTOR_SEP);if(!styleUtil.isKeyframesSelector(rule)){for(var i=0,l=p$.length,p;i<l&&(p=p$[i]);i++){p$[i]=transformer.call(this,p,scope,hostScope);}}
-return p$.join(COMPLEX_SELECTOR_SEP);},_transformComplexSelector:function(selector,scope,hostScope){var stop=false;var hostContext=false;var self=this;selector=selector.trim();selector=selector.replace(CONTENT_START,HOST+' $1');selector=selector.replace(SIMPLE_SELECTOR_SEP,function(m,c,s){if(!stop){var info=self._transformCompoundSelector(s,c,scope,hostScope);stop=stop||info.stop;hostContext=hostContext||info.hostContext;c=info.combinator;s=info.value;}else{s=s.replace(SCOPE_JUMP,' ');}
+return p$.join(COMPLEX_SELECTOR_SEP);},_transformComplexSelector:function(selector,scope,hostScope){var stop=false;var hostContext=false;var self=this;selector=selector.trim();selector=this._slottedToContent(selector);selector=selector.replace(ROOT,':host > *');selector=selector.replace(CONTENT_START,HOST+' $1');selector=selector.replace(SIMPLE_SELECTOR_SEP,function(m,c,s){if(!stop){var info=self._transformCompoundSelector(s,c,scope,hostScope);stop=stop||info.stop;hostContext=hostContext||info.hostContext;c=info.combinator;s=info.value;}else{s=s.replace(SCOPE_JUMP,' ');}
 return c+s;});if(hostContext){selector=selector.replace(HOST_CONTEXT_PAREN,function(m,pre,paren,post){return pre+paren+' '+hostScope+post+COMPLEX_SELECTOR_SEP+' '+pre+hostScope+paren+post;});}
 return selector;},_transformCompoundSelector:function(selector,combinator,scope,hostScope){var jumpIndex=selector.search(SCOPE_JUMP);var hostContext=false;if(selector.indexOf(HOST_CONTEXT)>=0){hostContext=true;}else if(selector.indexOf(HOST)>=0){selector=this._transformHostSelector(selector,hostScope);}else if(jumpIndex!==0){selector=scope?this._transformSimpleSelector(selector,scope):selector;}
 if(selector.indexOf(CONTENT)>=0){combinator='';}
 var stop;if(jumpIndex>=0){selector=selector.replace(SCOPE_JUMP,' ');stop=true;}
-return{value:selector,combinator:combinator,stop:stop,hostContext:hostContext};},_transformSimpleSelector:function(selector,scope){var p$=selector.split(PSEUDO_PREFIX);p$[0]+=scope;return p$.join(PSEUDO_PREFIX);},_transformHostSelector:function(selector,hostScope){var m=selector.match(HOST_PAREN);var paren=m&&m[2].trim()||'';if(paren){if(!paren[0].match(SIMPLE_SELECTOR_PREFIX)){var typeSelector=paren.split(SIMPLE_SELECTOR_PREFIX)[0];if(typeSelector===hostScope){return paren;}else{return SELECTOR_NO_MATCH;}}else{return selector.replace(HOST_PAREN,function(m,host,paren){return hostScope+paren;});}}else{return selector.replace(HOST,hostScope);}},documentRule:function(rule){rule.selector=rule.parsedSelector;this.normalizeRootSelector(rule);if(!settings.useNativeShadow){this._transformRule(rule,this._transformDocumentSelector);}},normalizeRootSelector:function(rule){if(rule.selector===ROOT){rule.selector='html';}},_transformDocumentSelector:function(selector){return selector.match(SCOPE_JUMP)?this._transformComplexSelector(selector,SCOPE_DOC_SELECTOR):this._transformSimpleSelector(selector.trim(),SCOPE_DOC_SELECTOR);},SCOPE_NAME:'style-scope'};var SCOPE_NAME=api.SCOPE_NAME;var SCOPE_DOC_SELECTOR=':not(['+SCOPE_NAME+'])'+':not(.'+SCOPE_NAME+')';var COMPLEX_SELECTOR_SEP=',';var SIMPLE_SELECTOR_SEP=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g;var SIMPLE_SELECTOR_PREFIX=/[[.:#*]/;var HOST=':host';var ROOT=':root';var HOST_PAREN=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/;var HOST_CONTEXT=':host-context';var HOST_CONTEXT_PAREN=/(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;var CONTENT='::content';var SCOPE_JUMP=/::content|::shadow|\/deep\//;var CSS_CLASS_PREFIX='.';var CSS_ATTR_PREFIX='['+SCOPE_NAME+'~=';var CSS_ATTR_SUFFIX=']';var PSEUDO_PREFIX=':';var CLASS='class';var CONTENT_START=new RegExp('^('+CONTENT+')');var SELECTOR_NO_MATCH='should_not_match';return api;}();Polymer.StyleExtends=function(){var styleUtil=Polymer.StyleUtil;return{hasExtends:function(cssText){return Boolean(cssText.match(this.rx.EXTEND));},transform:function(style){var rules=styleUtil.rulesForStyle(style);var self=this;styleUtil.forEachRule(rules,function(rule){self._mapRuleOntoParent(rule);if(rule.parent){var m;while(m=self.rx.EXTEND.exec(rule.cssText)){var extend=m[1];var extendor=self._findExtendor(extend,rule);if(extendor){self._extendRule(rule,extendor);}}}
+return{value:selector,combinator:combinator,stop:stop,hostContext:hostContext};},_transformSimpleSelector:function(selector,scope){var p$=selector.split(PSEUDO_PREFIX);p$[0]+=scope;return p$.join(PSEUDO_PREFIX);},_transformHostSelector:function(selector,hostScope){var m=selector.match(HOST_PAREN);var paren=m&&m[2].trim()||'';if(paren){if(!paren[0].match(SIMPLE_SELECTOR_PREFIX)){var typeSelector=paren.split(SIMPLE_SELECTOR_PREFIX)[0];if(typeSelector===hostScope){return paren;}else{return SELECTOR_NO_MATCH;}}else{return selector.replace(HOST_PAREN,function(m,host,paren){return hostScope+paren;});}}else{return selector.replace(HOST,hostScope);}},documentRule:function(rule){rule.selector=rule.parsedSelector;this.normalizeRootSelector(rule);if(!settings.useNativeShadow){this._transformRule(rule,this._transformDocumentSelector);}},normalizeRootSelector:function(rule){rule.selector=rule.selector.replace(ROOT,'html');},_transformDocumentSelector:function(selector){return selector.match(SCOPE_JUMP)?this._transformComplexSelector(selector,SCOPE_DOC_SELECTOR):this._transformSimpleSelector(selector.trim(),SCOPE_DOC_SELECTOR);},_slottedToContent:function(cssText){return cssText.replace(SLOTTED_PAREN,CONTENT+'> $1');},SCOPE_NAME:'style-scope'};var SCOPE_NAME=api.SCOPE_NAME;var SCOPE_DOC_SELECTOR=':not(['+SCOPE_NAME+'])'+':not(.'+SCOPE_NAME+')';var COMPLEX_SELECTOR_SEP=',';var SIMPLE_SELECTOR_SEP=/(^|[\s>+~]+)((?:\[.+?\]|[^\s>+~=\[])+)/g;var SIMPLE_SELECTOR_PREFIX=/[[.:#*]/;var HOST=':host';var ROOT=':root';var HOST_PAREN=/(:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/;var HOST_CONTEXT=':host-context';var HOST_CONTEXT_PAREN=/(.*)(?::host-context)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))(.*)/;var CONTENT='::content';var SCOPE_JUMP=/::content|::shadow|\/deep\//;var CSS_CLASS_PREFIX='.';var CSS_ATTR_PREFIX='['+SCOPE_NAME+'~=';var CSS_ATTR_SUFFIX=']';var PSEUDO_PREFIX=':';var CLASS='class';var CONTENT_START=new RegExp('^('+CONTENT+')');var SELECTOR_NO_MATCH='should_not_match';var SLOTTED_PAREN=/(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;return api;}();Polymer.StyleExtends=function(){var styleUtil=Polymer.StyleUtil;return{hasExtends:function(cssText){return Boolean(cssText.match(this.rx.EXTEND));},transform:function(style){var rules=styleUtil.rulesForStyle(style);var self=this;styleUtil.forEachRule(rules,function(rule){self._mapRuleOntoParent(rule);if(rule.parent){var m;while(m=self.rx.EXTEND.exec(rule.cssText)){var extend=m[1];var extendor=self._findExtendor(extend,rule);if(extendor){self._extendRule(rule,extendor);}}}
 rule.cssText=rule.cssText.replace(self.rx.EXTEND,'');});return styleUtil.toCssText(rules,function(rule){if(rule.selector.match(self.rx.STRIP)){rule.cssText='';}},true);},_mapRuleOntoParent:function(rule){if(rule.parent){var map=rule.parent.map||(rule.parent.map={});var parts=rule.selector.split(',');for(var i=0,p;i<parts.length;i++){p=parts[i];map[p.trim()]=rule;}
 return map;}},_findExtendor:function(extend,rule){return rule.parent&&rule.parent.map&&rule.parent.map[extend]||this._findExtendor(extend,rule.parent);},_extendRule:function(target,source){if(target.parent!==source.parent){this._cloneAndAddRuleToParent(source,target.parent);}
 target.extends=target.extends||[];target.extends.push(source);source.selector=source.selector.replace(this.rx.STRIP,'');source.selector=(source.selector&&source.selector+',\n')+target.selector;if(source.extends){source.extends.forEach(function(e){this._extendRule(target,e);},this);}},_cloneAndAddRuleToParent:function(rule,parent){rule=Object.create(rule);rule.parent=parent;if(rule.extends){rule.extends=rule.extends.slice();}
-parent.rules.push(rule);},rx:{EXTEND:/@extends\(([^)]*)\)\s*?;/gim,STRIP:/%[^,]*$/}};}();Polymer.ApplyShim=function(){'use strict';var styleUtil=Polymer.StyleUtil;var MIXIN_MATCH=styleUtil.rx.MIXIN_MATCH;var VAR_ASSIGN=styleUtil.rx.VAR_ASSIGN;var VAR_MATCH=styleUtil.rx.VAR_MATCH;var APPLY_NAME_CLEAN=/;\s*/m;var MIXIN_VAR_SEP='_-_';var mixinMap={};function mapSet(name,prop){name=name.trim();mixinMap[name]=prop;}
+parent.rules.push(rule);},rx:{EXTEND:/@extends\(([^)]*)\)\s*?;/gim,STRIP:/%[^,]*$/}};}();Polymer.ApplyShim=function(){'use strict';var styleUtil=Polymer.StyleUtil;var MIXIN_MATCH=styleUtil.rx.MIXIN_MATCH;var VAR_ASSIGN=styleUtil.rx.VAR_ASSIGN;var BAD_VAR=/var\(\s*(--[^,]*),\s*(--[^)]*)\)/g;var APPLY_NAME_CLEAN=/;\s*/m;var INITIAL_INHERIT=/^\s*(initial)|(inherit)\s*$/;var MIXIN_VAR_SEP='_-_';var mixinMap={};function mapSet(name,props){name=name.trim();mixinMap[name]={properties:props,dependants:{}};}
 function mapGet(name){name=name.trim();return mixinMap[name];}
-function cssTextToMap(text){var props=text.split(';');var out={};for(var i=0,p,sp;i<props.length;i++){p=props[i];if(p){sp=p.split(':');if(sp.length>1){out[sp[0].trim()]=sp.slice(1).join(':');}}}
+function replaceInitialOrInherit(property,value){var match=INITIAL_INHERIT.exec(value);if(match){if(match[1]){value=ApplyShim._getInitialValueForProperty(property);}else{value='apply-shim-inherit';}}
+return value;}
+function cssTextToMap(text){var props=text.split(';');var property,value;var out={};for(var i=0,p,sp;i<props.length;i++){p=props[i];if(p){sp=p.split(':');if(sp.length>1){property=sp[0].trim();value=replaceInitialOrInherit(property,sp.slice(1).join(':'));out[property]=value;}}}
 return out;}
-function produceCssProperties(matchText,propertyName,valueProperty,valueMixin){if(valueProperty){VAR_MATCH.lastIndex=0;var m=VAR_MATCH.exec(valueProperty);if(m){var value=m[2];if(mapGet(value)){valueMixin='@apply '+value+';';}}}
+function invalidateMixinEntry(mixinEntry){var currentProto=ApplyShim.__currentElementProto;var currentElementName=currentProto&&currentProto.is;for(var elementName in mixinEntry.dependants){if(elementName!==currentElementName){mixinEntry.dependants[elementName].__applyShimInvalid=true;}}}
+function produceCssProperties(matchText,propertyName,valueProperty,valueMixin){if(valueProperty){styleUtil.processVariableAndFallback(valueProperty,function(prefix,value){if(value&&mapGet(value)){valueMixin='@apply '+value+';';}});}
 if(!valueMixin){return matchText;}
-var mixinAsProperties=consumeCssProperties(valueMixin);var prefix=matchText.slice(0,matchText.indexOf('--'));var mixinValues=cssTextToMap(mixinAsProperties);var oldProperties=mapGet(propertyName);var combinedProps=mixinValues;if(oldProperties){combinedProps=Polymer.Base.mixin(oldProperties,mixinValues);}else{mapSet(propertyName,combinedProps);}
-var out=[];var p,v;for(p in combinedProps){v=mixinValues[p];if(v===undefined){v='initial';}
+var mixinAsProperties=consumeCssProperties(valueMixin);var prefix=matchText.slice(0,matchText.indexOf('--'));var mixinValues=cssTextToMap(mixinAsProperties);var combinedProps=mixinValues;var mixinEntry=mapGet(propertyName);var oldProps=mixinEntry&&mixinEntry.properties;if(oldProps){combinedProps=Object.create(oldProps);combinedProps=Polymer.Base.mixin(combinedProps,mixinValues);}else{mapSet(propertyName,combinedProps);}
+var out=[];var p,v;var needToInvalidate=false;for(p in combinedProps){v=mixinValues[p];if(v===undefined){v='initial';}
+if(oldProps&&!(p in oldProps)){needToInvalidate=true;}
 out.push(propertyName+MIXIN_VAR_SEP+p+': '+v);}
+if(needToInvalidate){invalidateMixinEntry(mixinEntry);}
+if(mixinEntry){mixinEntry.properties=combinedProps;}
+if(valueProperty){prefix=matchText+';'+prefix;}
 return prefix+out.join('; ')+';';}
-function fixVars(matchText,prefix,value,fallback){if(!fallback||fallback.indexOf('--')!==0){return matchText;}
-return[prefix,'var(',value,', var(',fallback,'));'].join('');}
-function atApplyToCssProperties(mixinName,fallbacks){mixinName=mixinName.replace(APPLY_NAME_CLEAN,'');var vars=[];var mixinProperties=mapGet(mixinName);if(mixinProperties){var p,parts,f;for(p in mixinProperties){f=fallbacks&&fallbacks[p];parts=[p,': var(',mixinName,MIXIN_VAR_SEP,p];if(f){parts.push(',',f);}
+function fixVars(matchText,varA,varB){return'var('+varA+','+'var('+varB+'))';}
+function atApplyToCssProperties(mixinName,fallbacks){mixinName=mixinName.replace(APPLY_NAME_CLEAN,'');var vars=[];var mixinEntry=mapGet(mixinName);if(!mixinEntry){mapSet(mixinName,{});mixinEntry=mapGet(mixinName);}
+if(mixinEntry){var currentProto=ApplyShim.__currentElementProto;if(currentProto){mixinEntry.dependants[currentProto.is]=currentProto;}
+var p,parts,f;for(p in mixinEntry.properties){f=fallbacks&&fallbacks[p];parts=[p,': var(',mixinName,MIXIN_VAR_SEP,p];if(f){parts.push(',',f);}
 parts.push(')');vars.push(parts.join(''));}}
 return vars.join('; ');}
 function consumeCssProperties(text){var m;while(m=MIXIN_MATCH.exec(text)){var matchText=m[0];var mixinName=m[1];var idx=m.index;var applyPos=idx+matchText.indexOf('@apply');var afterApplyPos=idx+matchText.length;var textBeforeApply=text.slice(0,applyPos);var textAfterApply=text.slice(afterApplyPos);var defaults=cssTextToMap(textBeforeApply);var replacement=atApplyToCssProperties(mixinName,defaults);text=[textBeforeApply,replacement,textAfterApply].join('');MIXIN_MATCH.lastIndex=idx+replacement.length;}
 return text;}
-var ApplyShim={_map:mixinMap,_separator:MIXIN_VAR_SEP,transform:function(styles){styleUtil.forRulesInStyles(styles,this._boundTransformRule);},transformRule:function(rule){rule.cssText=this.transformCssText(rule.parsedCssText);if(rule.selector===':root'){rule.selector=':host > *';}},transformCssText:function(cssText){cssText=cssText.replace(VAR_MATCH,fixVars);cssText=cssText.replace(VAR_ASSIGN,produceCssProperties);return consumeCssProperties(cssText);}};ApplyShim._boundTransformRule=ApplyShim.transformRule.bind(ApplyShim);return ApplyShim;}();(function(){var prepElement=Polymer.Base._prepElement;var nativeShadow=Polymer.Settings.useNativeShadow;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var styleExtends=Polymer.StyleExtends;var applyShim=Polymer.ApplyShim;var settings=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(element){if(this._encapsulateStyle&&this.__cssBuild!=='shady'){styleTransformer.element(element,this.is,this._scopeCssViaAttr);}
+var ApplyShim={_measureElement:null,_map:mixinMap,_separator:MIXIN_VAR_SEP,transform:function(styles,elementProto){this.__currentElementProto=elementProto;styleUtil.forRulesInStyles(styles,this._boundFindDefinitions);styleUtil.forRulesInStyles(styles,this._boundFindApplications);if(elementProto){elementProto.__applyShimInvalid=false;}
+this.__currentElementProto=null;},_findDefinitions:function(rule){var cssText=rule.parsedCssText;cssText=cssText.replace(BAD_VAR,fixVars);cssText=cssText.replace(VAR_ASSIGN,produceCssProperties);rule.cssText=cssText;if(rule.selector===':root'){rule.selector=':host > *';}},_findApplications:function(rule){rule.cssText=consumeCssProperties(rule.cssText);},transformRule:function(rule){this._findDefinitions(rule);this._findApplications(rule);},_getInitialValueForProperty:function(property){if(!this._measureElement){this._measureElement=document.createElement('meta');this._measureElement.style.all='initial';document.head.appendChild(this._measureElement);}
+return window.getComputedStyle(this._measureElement).getPropertyValue(property);}};ApplyShim._boundTransformRule=ApplyShim.transformRule.bind(ApplyShim);ApplyShim._boundFindDefinitions=ApplyShim._findDefinitions.bind(ApplyShim);ApplyShim._boundFindApplications=ApplyShim._findApplications.bind(ApplyShim);return ApplyShim;}();(function(){var prepElement=Polymer.Base._prepElement;var nativeShadow=Polymer.Settings.useNativeShadow;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var styleExtends=Polymer.StyleExtends;var applyShim=Polymer.ApplyShim;var settings=Polymer.Settings;Polymer.Base._addFeature({_prepElement:function(element){if(this._encapsulateStyle&&this.__cssBuild!=='shady'){styleTransformer.element(element,this.is,this._scopeCssViaAttr);}
 prepElement.call(this,element);},_prepStyles:function(){if(this._encapsulateStyle===undefined){this._encapsulateStyle=!nativeShadow;}
 if(!nativeShadow){this._scopeStyle=styleUtil.applyStylePlaceHolder(this.is);}
-this.__cssBuild=styleUtil.cssBuildTypeForModule(this.is);},_prepShimStyles:function(){if(this._template){var hasTargetedCssBuild=styleUtil.isTargetedBuild(this.__cssBuild);if(settings.useNativeCSSProperties&&this.__cssBuild==='shadow'&&hasTargetedCssBuild){return;}
-this._styles=this._styles||this._collectStyles();if(settings.useNativeCSSProperties&&!this.__cssBuild){applyShim.transform(this._styles);}
+this.__cssBuild=styleUtil.cssBuildTypeForModule(this.is);},_prepShimStyles:function(){if(this._template){var hasTargetedCssBuild=styleUtil.isTargetedBuild(this.__cssBuild);if(settings.useNativeCSSProperties&&this.__cssBuild==='shadow'&&hasTargetedCssBuild){if(settings.preserveStyleIncludes){styleUtil.styleIncludesToTemplate(this._template);}
+return;}
+this._styles=this._styles||this._collectStyles();if(settings.useNativeCSSProperties&&!this.__cssBuild){applyShim.transform(this._styles,this);}
 var cssText=settings.useNativeCSSProperties&&hasTargetedCssBuild?this._styles.length&&this._styles[0].textContent.trim():styleTransformer.elementStyles(this);this._prepStyleProperties();if(!this._needsStyleProperties()&&cssText){styleUtil.applyCss(cssText,this.is,nativeShadow?this._template.content:null,this._scopeStyle);}}else{this._styles=[];}},_collectStyles:function(){var styles=[];var cssText='',m$=this.styleModules;if(m$){for(var i=0,l=m$.length,m;i<l&&(m=m$[i]);i++){cssText+=styleUtil.cssFromModule(m);}}
 cssText+=styleUtil.cssFromModule(this.is);var p=this._template&&this._template.parentNode;if(this._template&&(!p||p.id.toLowerCase()!==this.is)){cssText+=styleUtil.cssFromElement(this._template);}
 if(cssText){var style=document.createElement('style');style.textContent=cssText;if(styleExtends.hasExtends(style.textContent)){cssText=styleExtends.transform(style);}
 styles.push(style);}
 return styles;},_elementAdd:function(node){if(this._encapsulateStyle){if(node.__styleScoped){node.__styleScoped=false;}else{styleTransformer.dom(node,this.is,this._scopeCssViaAttr);}}},_elementRemove:function(node){if(this._encapsulateStyle){styleTransformer.dom(node,this.is,this._scopeCssViaAttr,true);}},scopeSubtree:function(container,shouldObserve){if(nativeShadow){return;}
-var self=this;var scopify=function(node){if(node.nodeType===Node.ELEMENT_NODE){var className=node.getAttribute('class');node.setAttribute('class',self._scopeElementClass(node,className));var n$=node.querySelectorAll('*');for(var i=0,n;i<n$.length&&(n=n$[i]);i++){className=n.getAttribute('class');n.setAttribute('class',self._scopeElementClass(n,className));}}};scopify(container);if(shouldObserve){var mo=new MutationObserver(function(mxns){for(var i=0,m;i<mxns.length&&(m=mxns[i]);i++){if(m.addedNodes){for(var j=0;j<m.addedNodes.length;j++){scopify(m.addedNodes[j]);}}}});mo.observe(container,{childList:true,subtree:true});return mo;}}});}());Polymer.StyleProperties=function(){'use strict';var matchesSelector=Polymer.DomApi.matchesSelector;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var settings=Polymer.Settings;return{decorateStyles:function(styles,scope){var self=this,props={},keyframes=[],ruleIndex=0;var scopeSelector=styleTransformer._calcHostScope(scope.is,scope.extends);styleUtil.forRulesInStyles(styles,function(rule,style){self.decorateRule(rule);rule.index=ruleIndex++;self.whenHostOrRootRule(scope,rule,style,function(info){if(rule.parent.type===styleUtil.ruleTypes.MEDIA_RULE){scope.__notStyleScopeCacheable=true;}
+var self=this;var scopify=function(node){if(node.nodeType===Node.ELEMENT_NODE){var className=node.getAttribute('class');node.setAttribute('class',self._scopeElementClass(node,className));var n$=node.querySelectorAll('*');for(var i=0,n;i<n$.length&&(n=n$[i]);i++){className=n.getAttribute('class');n.setAttribute('class',self._scopeElementClass(n,className));}}};scopify(container);if(shouldObserve){var mo=new MutationObserver(function(mxns){for(var i=0,m;i<mxns.length&&(m=mxns[i]);i++){if(m.addedNodes){for(var j=0;j<m.addedNodes.length;j++){scopify(m.addedNodes[j]);}}}});mo.observe(container,{childList:true,subtree:true});return mo;}}});}());Polymer.StyleProperties=function(){'use strict';var matchesSelector=Polymer.DomApi.matchesSelector;var styleUtil=Polymer.StyleUtil;var styleTransformer=Polymer.StyleTransformer;var IS_IE=navigator.userAgent.match('Trident');var settings=Polymer.Settings;return{decorateStyles:function(styles,scope){var self=this,props={},keyframes=[],ruleIndex=0;var scopeSelector=styleTransformer._calcHostScope(scope.is,scope.extends);styleUtil.forRulesInStyles(styles,function(rule,style){self.decorateRule(rule);rule.index=ruleIndex++;self.whenHostOrRootRule(scope,rule,style,function(info){if(rule.parent.type===styleUtil.ruleTypes.MEDIA_RULE){scope.__notStyleScopeCacheable=true;}
 if(info.isHost){var hostContextOrFunction=info.selector.split(' ').some(function(s){return s.indexOf(scopeSelector)===0&&s.length!==scopeSelector.length;});scope.__notStyleScopeCacheable=scope.__notStyleScopeCacheable||hostContextOrFunction;}});self.collectPropertiesInCssText(rule.propertyInfo.cssText,props);},function onKeyframesRule(rule){keyframes.push(rule);});styles._keyframes=keyframes;var names=[];for(var i in props){names.push(i);}
 return names;},decorateRule:function(rule){if(rule.propertyInfo){return rule.propertyInfo;}
 var info={},properties={};var hasProperties=this.collectProperties(rule,properties);if(hasProperties){info.properties=properties;rule.rules=null;}
-info.cssText=this.collectCssText(rule);rule.propertyInfo=info;return info;},collectProperties:function(rule,properties){var info=rule.propertyInfo;if(info){if(info.properties){Polymer.Base.mixin(properties,info.properties);return true;}}else{var m,rx=this.rx.VAR_ASSIGN;var cssText=rule.parsedCssText;var any;while(m=rx.exec(cssText)){properties[m[1].trim()]=(m[2]||m[3]).trim();any=true;}
-return any;}},collectCssText:function(rule){return this.collectConsumingCssText(rule.parsedCssText);},collectConsumingCssText:function(cssText){return cssText.replace(this.rx.BRACKETED,'').replace(this.rx.VAR_ASSIGN,'');},collectPropertiesInCssText:function(cssText,props){var m;while(m=this.rx.VAR_CONSUMED.exec(cssText)){var name=m[1];if(m[2]!==':'){props[name]=true;}}},reify:function(props){var names=Object.getOwnPropertyNames(props);for(var i=0,n;i<names.length;i++){n=names[i];props[n]=this.valueForProperty(props[n],props);}},valueForProperty:function(property,props){if(property){if(property.indexOf(';')>=0){property=this.valueForProperties(property,props);}else{var self=this;var fn=function(all,prefix,value,fallback){var propertyValue=self.valueForProperty(props[value],props)||self.valueForProperty(props[fallback]||fallback,props)||fallback;return prefix+(propertyValue||'');};property=property.replace(this.rx.VAR_MATCH,fn);}}
+info.cssText=this.collectCssText(rule);rule.propertyInfo=info;return info;},collectProperties:function(rule,properties){var info=rule.propertyInfo;if(info){if(info.properties){Polymer.Base.mixin(properties,info.properties);return true;}}else{var m,rx=this.rx.VAR_ASSIGN;var cssText=rule.parsedCssText;var value;var any;while(m=rx.exec(cssText)){value=(m[2]||m[3]).trim();if(value!=='inherit'){properties[m[1].trim()]=value;}
+any=true;}
+return any;}},collectCssText:function(rule){return this.collectConsumingCssText(rule.parsedCssText);},collectConsumingCssText:function(cssText){return cssText.replace(this.rx.BRACKETED,'').replace(this.rx.VAR_ASSIGN,'');},collectPropertiesInCssText:function(cssText,props){var m;while(m=this.rx.VAR_CONSUMED.exec(cssText)){var name=m[1];if(m[2]!==':'){props[name]=true;}}},reify:function(props){var names=Object.getOwnPropertyNames(props);for(var i=0,n;i<names.length;i++){n=names[i];props[n]=this.valueForProperty(props[n],props);}},valueForProperty:function(property,props){if(property){if(property.indexOf(';')>=0){property=this.valueForProperties(property,props);}else{var self=this;var fn=function(prefix,value,fallback,suffix){var propertyValue=self.valueForProperty(props[value],props);if(!propertyValue||propertyValue==='initial'){propertyValue=self.valueForProperty(props[fallback]||fallback,props)||fallback;}else if(propertyValue==='apply-shim-inherit'){propertyValue='inherit';}
+return prefix+(propertyValue||'')+suffix;};property=styleUtil.processVariableAndFallback(property,fn);}}
 return property&&property.trim()||'';},valueForProperties:function(property,props){var parts=property.split(';');for(var i=0,p,m;i<parts.length;i++){if(p=parts[i]){this.rx.MIXIN_MATCH.lastIndex=0;m=this.rx.MIXIN_MATCH.exec(p);if(m){p=this.valueForProperty(props[m[1]],props);}else{var colon=p.indexOf(':');if(colon!==-1){var pp=p.substring(colon);pp=pp.trim();pp=this.valueForProperty(pp,props)||pp;p=p.substring(0,colon)+pp;}}
 parts[i]=p&&p.lastIndexOf(';')===p.length-1?p.slice(0,-1):p||'';}}
 return parts.join(';');},applyProperties:function(rule,props){var output='';if(!rule.propertyInfo){this.decorateRule(rule);}
@@ -3998,28 +4069,32 @@
 if(rule.hasAnimations){var transform;if(rule.keyframeNamesToTransform==null){rule.keyframeNamesToTransform=[];for(var keyframe in keyframeTransforms){transform=keyframeTransforms[keyframe];output=transform(input);if(input!==output){input=output;rule.keyframeNamesToTransform.push(keyframe);}}}else{for(var i=0;i<rule.keyframeNamesToTransform.length;++i){transform=keyframeTransforms[rule.keyframeNamesToTransform[i]];input=transform(input);}
 output=input;}}
 rule.cssText=output;},propertyDataFromStyles:function(styles,element){var props={},self=this;var o=[];styleUtil.forActiveRulesInStyles(styles,function(rule){if(!rule.propertyInfo){self.decorateRule(rule);}
-var selectorToMatch=rule.transformedSelector||rule.parsedSelector;if(element&&rule.propertyInfo.properties&&selectorToMatch){if(matchesSelector.call(element,selectorToMatch)){self.collectProperties(rule,props);addToBitMask(rule.index,o);}}});return{properties:props,key:o};},whenHostOrRootRule:function(scope,rule,style,callback){if(!rule.propertyInfo){self.decorateRule(rule);}
+var selectorToMatch=rule.transformedSelector||rule.parsedSelector;if(element&&rule.propertyInfo.properties&&selectorToMatch){if(matchesSelector.call(element,selectorToMatch)){self.collectProperties(rule,props);addToBitMask(rule.index,o);}}});return{properties:props,key:o};},_rootSelector:/:root|:host\s*>\s*\*/,_checkRoot:function(hostScope,selector){return Boolean(selector.match(this._rootSelector))||hostScope==='html'&&selector.indexOf('html')>-1;},whenHostOrRootRule:function(scope,rule,style,callback){if(!rule.propertyInfo){self.decorateRule(rule);}
 if(!rule.propertyInfo.properties){return;}
-var hostScope=scope.is?styleTransformer._calcHostScope(scope.is,scope.extends):'html';var parsedSelector=rule.parsedSelector;var isRoot=parsedSelector===':root';var isHost=parsedSelector.indexOf(':host')===0;var cssBuild=scope.__cssBuild||style.__cssBuild;if(cssBuild==='shady'){isRoot=parsedSelector===hostScope+'> *.'+hostScope||parsedSelector.indexOf('html')!==-1;isHost=!isRoot&&parsedSelector.indexOf(hostScope)===0;}
-if(cssBuild==='shadow'){isRoot=parsedSelector===':host > *'||parsedSelector==='html';isHost=isHost&&!isRoot;}
+var hostScope=scope.is?styleTransformer._calcHostScope(scope.is,scope.extends):'html';var parsedSelector=rule.parsedSelector;var isRoot=this._checkRoot(hostScope,parsedSelector);var isHost=!isRoot&&parsedSelector.indexOf(':host')===0;var cssBuild=scope.__cssBuild||style.__cssBuild;if(cssBuild==='shady'){isRoot=parsedSelector===hostScope+' > *.'+hostScope||parsedSelector.indexOf('html')>-1;isHost=!isRoot&&parsedSelector.indexOf(hostScope)===0;}
 if(!isRoot&&!isHost){return;}
 var selectorToMatch=hostScope;if(isHost){if(settings.useNativeShadow&&!rule.transformedSelector){rule.transformedSelector=styleTransformer._transformRuleCss(rule,styleTransformer._transformComplexSelector,scope.is,hostScope);}
-selectorToMatch=rule.transformedSelector||hostScope;}
+selectorToMatch=rule.transformedSelector||rule.parsedSelector;}
+if(isRoot&&hostScope==='html'){selectorToMatch=rule.transformedSelector||rule.parsedSelector;}
 callback({selector:selectorToMatch,isHost:isHost,isRoot:isRoot});},hostAndRootPropertiesForScope:function(scope){var hostProps={},rootProps={},self=this;styleUtil.forActiveRulesInStyles(scope._styles,function(rule,style){self.whenHostOrRootRule(scope,rule,style,function(info){var element=scope._element||scope;if(matchesSelector.call(element,info.selector)){if(info.isHost){self.collectProperties(rule,hostProps);}else{self.collectProperties(rule,rootProps);}}});});return{rootProps:rootProps,hostProps:hostProps};},transformStyles:function(element,properties,scopeSelector){var self=this;var hostSelector=styleTransformer._calcHostScope(element.is,element.extends);var rxHostSelector=element.extends?'\\'+hostSelector.slice(0,-1)+'\\]':hostSelector;var hostRx=new RegExp(this.rx.HOST_PREFIX+rxHostSelector+this.rx.HOST_SUFFIX);var keyframeTransforms=this._elementKeyframeTransforms(element,scopeSelector);return styleTransformer.elementStyles(element,function(rule){self.applyProperties(rule,properties);if(!settings.useNativeShadow&&!Polymer.StyleUtil.isKeyframesSelector(rule)&&rule.cssText){self.applyKeyframeTransforms(rule,keyframeTransforms);self._scopeSelector(rule,hostRx,hostSelector,element._scopeCssViaAttr,scopeSelector);}});},_elementKeyframeTransforms:function(element,scopeSelector){var keyframesRules=element._styles._keyframes;var keyframeTransforms={};if(!settings.useNativeShadow&&keyframesRules){for(var i=0,keyframesRule=keyframesRules[i];i<keyframesRules.length;keyframesRule=keyframesRules[++i]){this._scopeKeyframes(keyframesRule,scopeSelector);keyframeTransforms[keyframesRule.keyframesName]=this._keyframesRuleTransformer(keyframesRule);}}
 return keyframeTransforms;},_keyframesRuleTransformer:function(keyframesRule){return function(cssText){return cssText.replace(keyframesRule.keyframesNameRx,keyframesRule.transformedKeyframesName);};},_scopeKeyframes:function(rule,scopeId){rule.keyframesNameRx=new RegExp(rule.keyframesName,'g');rule.transformedKeyframesName=rule.keyframesName+'-'+scopeId;rule.transformedSelector=rule.transformedSelector||rule.selector;rule.selector=rule.transformedSelector.replace(rule.keyframesName,rule.transformedKeyframesName);},_scopeSelector:function(rule,hostRx,hostSelector,viaAttr,scopeId){rule.transformedSelector=rule.transformedSelector||rule.selector;var selector=rule.transformedSelector;var scope=viaAttr?'['+styleTransformer.SCOPE_NAME+'~='+scopeId+']':'.'+scopeId;var parts=selector.split(',');for(var i=0,l=parts.length,p;i<l&&(p=parts[i]);i++){parts[i]=p.match(hostRx)?p.replace(hostSelector,scope):scope+' '+p;}
 rule.selector=parts.join(',');},applyElementScopeSelector:function(element,selector,old,viaAttr){var c=viaAttr?element.getAttribute(styleTransformer.SCOPE_NAME):element.getAttribute('class')||'';var v=old?c.replace(old,selector):(c?c+' ':'')+this.XSCOPE_NAME+' '+selector;if(c!==v){if(viaAttr){element.setAttribute(styleTransformer.SCOPE_NAME,v);}else{element.setAttribute('class',v);}}},applyElementStyle:function(element,properties,selector,style){var cssText=style?style.textContent||'':this.transformStyles(element,properties,selector);var s=element._customStyle;if(s&&!settings.useNativeShadow&&s!==style){s._useCount--;if(s._useCount<=0&&s.parentNode){s.parentNode.removeChild(s);}}
-if(settings.useNativeShadow){if(element._customStyle){element._customStyle.textContent=cssText;style=element._customStyle;}else if(cssText){style=styleUtil.applyCss(cssText,selector,element.root,element._scopeStyle);}}else{if(!style){if(cssText){style=styleUtil.applyCss(cssText,selector,null,element._scopeStyle);}}else if(!style.parentNode){styleUtil.applyStyle(style,null,element._scopeStyle);}}
+if(settings.useNativeShadow){if(element._customStyle){element._customStyle.textContent=cssText;style=element._customStyle;}else if(cssText){style=styleUtil.applyCss(cssText,selector,element.root,element._scopeStyle);}}else{if(!style){if(cssText){style=styleUtil.applyCss(cssText,selector,null,element._scopeStyle);}}else if(!style.parentNode){if(IS_IE&&cssText.indexOf('@media')>-1){style.textContent=cssText;}
+styleUtil.applyStyle(style,null,element._scopeStyle);}}
 if(style){style._useCount=style._useCount||0;if(element._customStyle!=style){style._useCount++;}
 element._customStyle=style;}
-return style;},mixinCustomStyle:function(props,customStyle){var v;for(var i in customStyle){v=customStyle[i];if(v||v===0){props[i]=v;}}},updateNativeStyleProperties:function(element,properties){for(var i=0;i<element.style.length;i++){element.style.removeProperty(element.style[i]);}
-for(var p in properties){if(properties[p]!==null){element.style.setProperty(p,properties[p]);}}},rx:styleUtil.rx,XSCOPE_NAME:'x-scope'};function addToBitMask(n,bits){var o=parseInt(n/32);var v=1<<n%32;bits[o]=(bits[o]||0)|v;}}();(function(){Polymer.StyleCache=function(){this.cache={};};Polymer.StyleCache.prototype={MAX:100,store:function(is,data,keyValues,keyStyles){data.keyValues=keyValues;data.styles=keyStyles;var s$=this.cache[is]=this.cache[is]||[];s$.push(data);if(s$.length>this.MAX){s$.shift();}},retrieve:function(is,keyValues,keyStyles){var cache=this.cache[is];if(cache){for(var i=cache.length-1,data;i>=0;i--){data=cache[i];if(keyStyles===data.styles&&this._objectsEqual(keyValues,data.keyValues)){return data;}}}},clear:function(){this.cache={};},_objectsEqual:function(target,source){var t,s;for(var i in target){t=target[i],s=source[i];if(!(typeof t==='object'&&t?this._objectsStrictlyEqual(t,s):t===s)){return false;}}
+return style;},mixinCustomStyle:function(props,customStyle){var v;for(var i in customStyle){v=customStyle[i];if(v||v===0){props[i]=v;}}},updateNativeStyleProperties:function(element,properties){var oldPropertyNames=element.__customStyleProperties;if(oldPropertyNames){for(var i=0;i<oldPropertyNames.length;i++){element.style.removeProperty(oldPropertyNames[i]);}}
+var propertyNames=[];for(var p in properties){if(properties[p]!==null){element.style.setProperty(p,properties[p]);propertyNames.push(p);}}
+element.__customStyleProperties=propertyNames;},rx:styleUtil.rx,XSCOPE_NAME:'x-scope'};function addToBitMask(n,bits){var o=parseInt(n/32);var v=1<<n%32;bits[o]=(bits[o]||0)|v;}}();(function(){Polymer.StyleCache=function(){this.cache={};};Polymer.StyleCache.prototype={MAX:100,store:function(is,data,keyValues,keyStyles){data.keyValues=keyValues;data.styles=keyStyles;var s$=this.cache[is]=this.cache[is]||[];s$.push(data);if(s$.length>this.MAX){s$.shift();}},retrieve:function(is,keyValues,keyStyles){var cache=this.cache[is];if(cache){for(var i=cache.length-1,data;i>=0;i--){data=cache[i];if(keyStyles===data.styles&&this._objectsEqual(keyValues,data.keyValues)){return data;}}}},clear:function(){this.cache={};},_objectsEqual:function(target,source){var t,s;for(var i in target){t=target[i],s=source[i];if(!(typeof t==='object'&&t?this._objectsStrictlyEqual(t,s):t===s)){return false;}}
 if(Array.isArray(target)){return target.length===source.length;}
 return true;},_objectsStrictlyEqual:function(target,source){return this._objectsEqual(target,source)&&this._objectsEqual(source,target);}};}());Polymer.StyleDefaults=function(){var styleProperties=Polymer.StyleProperties;var StyleCache=Polymer.StyleCache;var nativeVariables=Polymer.Settings.useNativeCSSProperties;var api={_styles:[],_properties:null,customStyle:{},_styleCache:new StyleCache(),_element:Polymer.DomApi.wrap(document.documentElement),addStyle:function(style){this._styles.push(style);this._properties=null;},get _styleProperties(){if(!this._properties){styleProperties.decorateStyles(this._styles,this);this._styles._scopeStyleProperties=null;this._properties=styleProperties.hostAndRootPropertiesForScope(this).rootProps;styleProperties.mixinCustomStyle(this._properties,this.customStyle);styleProperties.reify(this._properties);}
 return this._properties;},hasStyleProperties:function(){return Boolean(this._properties);},_needsStyleProperties:function(){},_computeStyleProperties:function(){return this._styleProperties;},updateStyles:function(properties){this._properties=null;if(properties){Polymer.Base.mixin(this.customStyle,properties);}
 this._styleCache.clear();for(var i=0,s;i<this._styles.length;i++){s=this._styles[i];s=s.__importElement||s;s._apply();}
-if(nativeVariables){styleProperties.updateNativeStyleProperties(document.documentElement,this.customStyle);}}};return api;}();(function(){'use strict';var serializeValueToAttribute=Polymer.Base.serializeValueToAttribute;var propertyUtils=Polymer.StyleProperties;var styleTransformer=Polymer.StyleTransformer;var styleDefaults=Polymer.StyleDefaults;var nativeShadow=Polymer.Settings.useNativeShadow;var nativeVariables=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){if(!nativeVariables){this._ownStylePropertyNames=this._styles&&this._styles.length?propertyUtils.decorateStyles(this._styles,this):null;}},customStyle:null,getComputedStyleValue:function(property){return!nativeVariables&&this._styleProperties&&this._styleProperties[property]||getComputedStyle(this).getPropertyValue(property);},_setupStyleProperties:function(){this.customStyle={};this._styleCache=null;this._styleProperties=null;this._scopeSelector=null;this._ownStyleProperties=null;this._customStyle=null;},_needsStyleProperties:function(){return Boolean(!nativeVariables&&this._ownStylePropertyNames&&this._ownStylePropertyNames.length);},_beforeAttached:function(){if((!this._scopeSelector||this.__stylePropertiesInvalid)&&this._needsStyleProperties()){this.__stylePropertiesInvalid=false;this._updateStyleProperties();}},_findStyleHost:function(){var e=this,root;while(root=Polymer.dom(e).getOwnerRoot()){if(Polymer.isInstance(root.host)){return root.host;}
+if(nativeVariables){styleProperties.updateNativeStyleProperties(document.documentElement,this.customStyle);}}};return api;}();(function(){'use strict';var serializeValueToAttribute=Polymer.Base.serializeValueToAttribute;var propertyUtils=Polymer.StyleProperties;var styleTransformer=Polymer.StyleTransformer;var styleDefaults=Polymer.StyleDefaults;var nativeShadow=Polymer.Settings.useNativeShadow;var nativeVariables=Polymer.Settings.useNativeCSSProperties;Polymer.Base._addFeature({_prepStyleProperties:function(){if(!nativeVariables){this._ownStylePropertyNames=this._styles&&this._styles.length?propertyUtils.decorateStyles(this._styles,this):null;}},customStyle:null,getComputedStyleValue:function(property){if(!nativeVariables&&!this._styleProperties){this._computeStyleProperties();}
+return!nativeVariables&&this._styleProperties&&this._styleProperties[property]||getComputedStyle(this).getPropertyValue(property);},_setupStyleProperties:function(){this.customStyle={};this._styleCache=null;this._styleProperties=null;this._scopeSelector=null;this._ownStyleProperties=null;this._customStyle=null;},_needsStyleProperties:function(){return Boolean(!nativeVariables&&this._ownStylePropertyNames&&this._ownStylePropertyNames.length);},_validateApplyShim:function(){if(this.__applyShimInvalid){Polymer.ApplyShim.transform(this._styles,this.__proto__);var cssText=styleTransformer.elementStyles(this);if(nativeShadow){var templateStyle=this._template.content.querySelector('style');if(templateStyle){templateStyle.textContent=cssText;}}else{var shadyStyle=this._scopeStyle&&this._scopeStyle.nextSibling;if(shadyStyle){shadyStyle.textContent=cssText;}}}},_beforeAttached:function(){if((!this._scopeSelector||this.__stylePropertiesInvalid)&&this._needsStyleProperties()){this.__stylePropertiesInvalid=false;this._updateStyleProperties();}},_findStyleHost:function(){var e=this,root;while(root=Polymer.dom(e).getOwnerRoot()){if(Polymer.isInstance(root.host)){return root.host;}
 e=root.host;}
-return styleDefaults;},_updateStyleProperties:function(){var info,scope=this._findStyleHost();if(!scope._styleCache){scope._styleCache=new Polymer.StyleCache();}
+return styleDefaults;},_updateStyleProperties:function(){var info,scope=this._findStyleHost();if(!scope._styleProperties){scope._computeStyleProperties();}
+if(!scope._styleCache){scope._styleCache=new Polymer.StyleCache();}
 var scopeData=propertyUtils.propertyDataFromStyles(scope._styles,this);var scopeCacheable=!this.__notStyleScopeCacheable;if(scopeCacheable){scopeData.key.customStyle=this.customStyle;info=scope._styleCache.retrieve(this.is,scopeData.key,this._styles);}
 var scopeCached=Boolean(info);if(scopeCached){this._styleProperties=info._styleProperties;}else{this._computeStyleProperties(scopeData.properties);}
 this._computeOwnStyleProperties();if(!scopeCached){info=styleCache.retrieve(this.is,this._ownStyleProperties,this._styles);}
@@ -4032,13 +4107,14 @@
 return selector;},updateStyles:function(properties){if(properties){this.mixin(this.customStyle,properties);}
 if(nativeVariables){propertyUtils.updateNativeStyleProperties(this,this.customStyle);}else{if(this.isAttached){if(this._needsStyleProperties()){this._updateStyleProperties();}else{this._styleProperties=null;}}else{this.__stylePropertiesInvalid=true;}
 if(this._styleCache){this._styleCache.clear();}
-this._updateRootStyles();}},_updateRootStyles:function(root){root=root||this.root;var c$=Polymer.dom(root)._query(function(e){return e.shadyRoot||e.shadowRoot;});for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.updateStyles){c.updateStyles();}}}});Polymer.updateStyles=function(properties){styleDefaults.updateStyles(properties);Polymer.Base._updateRootStyles(document);};var styleCache=new Polymer.StyleCache();Polymer.customStyleCache=styleCache;var SCOPE_NAME=styleTransformer.SCOPE_NAME;var XSCOPE_NAME=propertyUtils.XSCOPE_NAME;}());Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();this._prepConstructor();this._prepStyles();},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady();},_prepBehavior:function(b){this._addPropertyEffects(b.properties);this._addComplexObserverEffects(b.observers);this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._setupGestures();this._setupConfigure();this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();if(this._template){this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();this._marshalAnnotationReferences();}
+this._updateRootStyles();}},_updateRootStyles:function(root){root=root||this.root;var c$=Polymer.dom(root)._query(function(e){return e.shadyRoot||e.shadowRoot;});for(var i=0,l=c$.length,c;i<l&&(c=c$[i]);i++){if(c.updateStyles){c.updateStyles();}}}});Polymer.updateStyles=function(properties){styleDefaults.updateStyles(properties);Polymer.Base._updateRootStyles(document);};var styleCache=new Polymer.StyleCache();Polymer.customStyleCache=styleCache;var SCOPE_NAME=styleTransformer.SCOPE_NAME;var XSCOPE_NAME=propertyUtils.XSCOPE_NAME;}());Polymer.Base._addFeature({_registerFeatures:function(){this._prepIs();if(this.factoryImpl){this._prepConstructor();}
+this._prepStyles();},_finishRegisterFeatures:function(){this._prepTemplate();this._prepShimStyles();this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepPropertyInfo();this._prepBindings();this._prepShady();},_prepBehavior:function(b){this._addPropertyEffects(b.properties);this._addComplexObserverEffects(b.observers);this._addHostAttributes(b.hostAttributes);},_initFeatures:function(){this._setupGestures();this._setupConfigure(this.__data__);this._setupStyleProperties();this._setupDebouncers();this._setupShady();this._registerHost();if(this._template){this._validateApplyShim();this._poolContent();this._beginHosting();this._stampTemplate();this._endHosting();this._marshalAnnotationReferences();}
 this._marshalInstanceEffects();this._marshalBehaviors();this._marshalHostAttributes();this._marshalAttributes();this._tryReady();},_marshalBehavior:function(b){if(b.listeners){this._listenListeners(b.listeners);}}});(function(){var propertyUtils=Polymer.StyleProperties;var styleUtil=Polymer.StyleUtil;var cssParse=Polymer.CssParse;var styleDefaults=Polymer.StyleDefaults;var styleTransformer=Polymer.StyleTransformer;var applyShim=Polymer.ApplyShim;var debounce=Polymer.Debounce;var settings=Polymer.Settings;var updateDebouncer;Polymer({is:'custom-style',extends:'style',_template:null,properties:{include:String},ready:function(){this.__appliedElement=this.__appliedElement||this;this.__cssBuild=styleUtil.getCssBuildType(this);if(this.__appliedElement!==this){this.__appliedElement.__cssBuild=this.__cssBuild;}
 this._tryApply();},attached:function(){this._tryApply();},_tryApply:function(){if(!this._appliesToDocument){if(this.parentNode&&this.parentNode.localName!=='dom-module'){this._appliesToDocument=true;var e=this.__appliedElement;if(!settings.useNativeCSSProperties){this.__needsUpdateStyles=styleDefaults.hasStyleProperties();styleDefaults.addStyle(e);}
 if(e.textContent||this.include){this._apply(true);}else{var self=this;var observer=new MutationObserver(function(){observer.disconnect();self._apply(true);});observer.observe(e,{childList:true});}}}},_updateStyles:function(){Polymer.updateStyles();},_apply:function(initialApply){var e=this.__appliedElement;if(this.include){e.textContent=styleUtil.cssFromModules(this.include,true)+e.textContent;}
 if(!e.textContent){return;}
 var buildType=this.__cssBuild;var targetedBuild=styleUtil.isTargetedBuild(buildType);if(settings.useNativeCSSProperties&&targetedBuild){return;}
-var styleRules=styleUtil.rulesForStyle(e);if(!targetedBuild){styleUtil.forEachRule(styleRules,function(rule){styleTransformer.documentRule(rule);if(settings.useNativeCSSProperties&&!buildType){applyShim.transformRule(rule);}});}
+var styleRules=styleUtil.rulesForStyle(e);if(!targetedBuild){styleUtil.forEachRule(styleRules,function(rule){styleTransformer.documentRule(rule);});if(settings.useNativeCSSProperties&&!buildType){applyShim.transform([e]);}}
 if(settings.useNativeCSSProperties){e.textContent=styleUtil.toCssText(styleRules);}else{var self=this;var fn=function fn(){self._flushCustomProperties();};if(initialApply){Polymer.RenderStatus.whenReady(fn);}else{fn();}}},_flushCustomProperties:function(){if(this.__needsUpdateStyles){this.__needsUpdateStyles=false;updateDebouncer=debounce(updateDebouncer,this._updateStyles);}else{this._applyCustomProperties();}},_applyCustomProperties:function(){var element=this.__appliedElement;this._computeStyleProperties();var props=this._styleProperties;var rules=styleUtil.rulesForStyle(element);if(!rules){return;}
 element.textContent=styleUtil.toCssText(rules,function(rule){var css=rule.cssText=rule.parsedCssText;if(rule.propertyInfo&&rule.propertyInfo.cssText){css=cssParse.removeCustomPropAssignment(css);rule.cssText=propertyUtils.valueForProperties(css,props);}});}});}());Polymer.Templatizer={properties:{__hideTemplateChildren__:{observer:'_showHideChildren'}},_instanceProps:Polymer.nob,_parentPropPrefix:'_parent_',templatize:function(template){this._templatized=template;if(!template._content){template._content=template.content;}
 if(template._content._ctor){this.ctor=template._content._ctor;this._prepParentProperties(this.ctor.prototype,template);return;}
@@ -4049,10 +4125,10 @@
 c._notes=Polymer.Annotations.parseAnnotations(template);Polymer.Annotations.prepElement=null;this._processAnnotations(c._notes);}
 archetype._notes=c._notes;archetype._parentProps=c._parentProps;},_prepParentProperties:function(archetype,template){var parentProps=this._parentProps=archetype._parentProps;if(this._forwardParentProp&&parentProps){var proto=archetype._parentPropProto;var prop;if(!proto){for(prop in this._instanceProps){delete parentProps[prop];}
 proto=archetype._parentPropProto=Object.create(null);if(template!=this){Polymer.Bind.prepareModel(proto);Polymer.Base.prepareModelNotifyPath(proto);}
-for(prop in parentProps){var parentProp=this._parentPropPrefix+prop;var effects=[{kind:'function',effect:this._createForwardPropEffector(prop),fn:Polymer.Bind._functionEffect},{kind:'notify',fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(parentProp)+'-changed'}}];Polymer.Bind._createAccessors(proto,parentProp,effects);}}
+for(prop in parentProps){var parentProp=this._parentPropPrefix+prop;var effects=[{kind:'function',effect:this._createForwardPropEffector(prop),fn:Polymer.Bind._functionEffect},{kind:'notify',fn:Polymer.Bind._notifyEffect,effect:{event:Polymer.CaseMap.camelToDashCase(parentProp)+'-changed'}}];proto._propertyEffects=proto._propertyEffects||{};proto._propertyEffects[parentProp]=effects;Polymer.Bind._createAccessors(proto,parentProp,effects);}}
 var self=this;if(template!=this){Polymer.Bind.prepareInstance(template);template._forwardParentProp=function(source,value){self._forwardParentProp(source,value);};}
 this._extendTemplate(template,proto);template._pathEffector=function(path,value,fromAbove){return self._pathEffectorImpl(path,value,fromAbove);};}},_createForwardPropEffector:function(prop){return function(source,value){this._forwardParentProp(prop,value);};},_createHostPropEffector:function(prop){var prefix=this._parentPropPrefix;return function(source,value){this.dataHost._templatized[prefix+prop]=value;};},_createInstancePropEffector:function(prop){return function(source,value,old,fromAbove){if(!fromAbove){this.dataHost._forwardInstanceProp(this,prop,value);}};},_extendTemplate:function(template,proto){var n$=Object.getOwnPropertyNames(proto);if(proto._propertySetter){template._propertySetter=proto._propertySetter;}
-for(var i=0,n;i<n$.length&&(n=n$[i]);i++){var val=template[n];var pd=Object.getOwnPropertyDescriptor(proto,n);Object.defineProperty(template,n,pd);if(val!==undefined){template._propertySetter(n,val);}}},_showHideChildren:function(hidden){},_forwardInstancePath:function(inst,path,value){},_forwardInstanceProp:function(inst,prop,value){},_notifyPathUpImpl:function(path,value){var dataHost=this.dataHost;var dot=path.indexOf('.');var root=dot<0?path:path.slice(0,dot);dataHost._forwardInstancePath.call(dataHost,this,path,value);if(root in dataHost._parentProps){dataHost._templatized._notifyPath(dataHost._parentPropPrefix+path,value);}},_pathEffectorImpl:function(path,value,fromAbove){if(this._forwardParentPath){if(path.indexOf(this._parentPropPrefix)===0){var subPath=path.substring(this._parentPropPrefix.length);var model=this._modelForPath(subPath);if(model in this._parentProps){this._forwardParentPath(subPath,value);}}}
+for(var i=0,n;i<n$.length&&(n=n$[i]);i++){var val=template[n];if(val&&n=='_propertyEffects'){var pe=Polymer.Base.mixin({},val);template._propertyEffects=Polymer.Base.mixin(pe,proto._propertyEffects);}else{var pd=Object.getOwnPropertyDescriptor(proto,n);Object.defineProperty(template,n,pd);if(val!==undefined){template._propertySetter(n,val);}}}},_showHideChildren:function(hidden){},_forwardInstancePath:function(inst,path,value){},_forwardInstanceProp:function(inst,prop,value){},_notifyPathUpImpl:function(path,value){var dataHost=this.dataHost;var root=Polymer.Path.root(path);dataHost._forwardInstancePath.call(dataHost,this,path,value);if(root in dataHost._parentProps){dataHost._templatized._notifyPath(dataHost._parentPropPrefix+path,value);}},_pathEffectorImpl:function(path,value,fromAbove){if(this._forwardParentPath){if(path.indexOf(this._parentPropPrefix)===0){var subPath=path.substring(this._parentPropPrefix.length);var model=Polymer.Path.root(subPath);if(model in this._parentProps){this._forwardParentPath(subPath,value);}}}
 Polymer.Base._pathEffector.call(this._templatized,path,value,fromAbove);},_constructorImpl:function(model,host){this._rootDataHost=host._getRootDataHost();this._setupConfigure(model);this._registerHost(host);this._beginHosting();this.root=this.instanceTemplate(this._template);this.root.__noContent=!this._notes._hasContent;this.root.__styleScoped=true;this._endHosting();this._marshalAnnotatedNodes();this._marshalInstanceEffects();this._marshalAnnotatedListeners();var children=[];for(var n=this.root.firstChild;n;n=n.nextSibling){children.push(n);n._templateInstance=this;}
 this._children=children;if(host.__hideTemplateChildren__){this._showHideChildren(true);}
 this._tryReady();},_listenImpl:function(node,eventName,methodName){var model=this;var host=this._rootDataHost;var handler=host._createEventHandler(node,eventName,methodName);var decorated=function(e){e.model=model;handler(e);};host._listen(node,eventName,decorated);},_scopeElementClassImpl:function(node,value){var host=this._rootDataHost;if(host){return host._scopeElementClass(node,value);}
@@ -4066,12 +4142,13 @@
 for(j=0;j<s.addedCount;j++){var item=this.userArray[s.index+j];key=this.getKey(item);key=key===undefined?this.add(item):key;keyMap[key]=keyMap[key]?null:1;s.addedKeys.push(key);}}
 var removed=[];var added=[];for(key in keyMap){if(keyMap[key]<0){this.removeKey(key);removed.push(key);}
 if(keyMap[key]>0){added.push(key);}}
-return[{removed:removed,added:added}];}};Polymer.Collection.get=function(userArray){return Polymer._collections.get(userArray)||new Polymer.Collection(userArray);};Polymer.Collection.applySplices=function(userArray,splices){var coll=Polymer._collections.get(userArray);return coll?coll._applySplices(splices):null;};Polymer({is:'dom-repeat',extends:'template',_template:null,properties:{items:{type:Array},as:{type:String,value:'item'},indexAs:{type:String,value:'index'},sort:{type:Function,observer:'_sortChanged'},filter:{type:Function,observer:'_filterChanged'},observe:{type:String,observer:'_observeChanged'},delay:Number,renderedItemCount:{type:Number,notify:true,readOnly:true},initialCount:{type:Number,observer:'_initializeChunking'},targetFramerate:{type:Number,value:20},_targetFrameTime:{type:Number,computed:'_computeFrameTime(targetFramerate)'}},behaviors:[Polymer.Templatizer],observers:['_itemsChanged(items.*)'],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var self=this;this._boundRenderChunk=function(){self._renderChunk();};},detached:function(){this.__isDetached=true;for(var i=0;i<this._instances.length;i++){this._detachInstance(i);}},attached:function(){if(this.__isDetached){this.__isDetached=false;var parent=Polymer.dom(Polymer.dom(this).parentNode);for(var i=0;i<this._instances.length;i++){this._attachInstance(i,parent);}}},ready:function(){this._instanceProps={__key__:true};this._instanceProps[this.as]=true;this._instanceProps[this.indexAs]=true;if(!this.ctor){this.templatize(this);}},_sortChanged:function(sort){var dataHost=this._getRootDataHost();this._sortFn=sort&&(typeof sort=='function'?sort:function(){return dataHost[sort].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_filterChanged:function(filter){var dataHost=this._getRootDataHost();this._filterFn=filter&&(typeof filter=='function'?filter:function(){return dataHost[filter].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_computeFrameTime:function(rate){return Math.ceil(1000/rate);},_initializeChunking:function(){if(this.initialCount){this._limit=this.initialCount;this._chunkCount=this.initialCount;this._lastChunkTime=performance.now();}},_tryRenderChunk:function(){if(this.items&&this._limit<this.items.length){this.debounce('renderChunk',this._requestRenderChunk);}},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk);},_renderChunk:function(){var currChunkTime=performance.now();var ratio=this._targetFrameTime/(currChunkTime-this._lastChunkTime);this._chunkCount=Math.round(this._chunkCount*ratio)||1;this._limit+=this._chunkCount;this._lastChunkTime=currChunkTime;this._debounceTemplate(this._render);},_observeChanged:function(){this._observePaths=this.observe&&this.observe.replace('.*','.').split(' ');},_itemsChanged:function(change){if(change.path=='items'){if(Array.isArray(this.items)){this.collection=Polymer.Collection.get(this.items);}else if(!this.items){this.collection=null;}else{this._error(this._logf('dom-repeat','expected array for `items`,'+' found',this.items));}
+return[{removed:removed,added:added}];}};Polymer.Collection.get=function(userArray){return Polymer._collections.get(userArray)||new Polymer.Collection(userArray);};Polymer.Collection.applySplices=function(userArray,splices){var coll=Polymer._collections.get(userArray);return coll?coll._applySplices(splices):null;};Polymer({is:'dom-repeat',extends:'template',_template:null,properties:{items:{type:Array},as:{type:String,value:'item'},indexAs:{type:String,value:'index'},sort:{type:Function,observer:'_sortChanged'},filter:{type:Function,observer:'_filterChanged'},observe:{type:String,observer:'_observeChanged'},delay:Number,renderedItemCount:{type:Number,notify:!Polymer.Settings.suppressTemplateNotifications,readOnly:true},initialCount:{type:Number,observer:'_initializeChunking'},targetFramerate:{type:Number,value:20},notifyDomChange:{type:Boolean},_targetFrameTime:{type:Number,computed:'_computeFrameTime(targetFramerate)'}},behaviors:[Polymer.Templatizer],observers:['_itemsChanged(items.*)'],created:function(){this._instances=[];this._pool=[];this._limit=Infinity;var self=this;this._boundRenderChunk=function(){self._renderChunk();};},detached:function(){this.__isDetached=true;for(var i=0;i<this._instances.length;i++){this._detachInstance(i);}},attached:function(){if(this.__isDetached){this.__isDetached=false;var parent=Polymer.dom(Polymer.dom(this).parentNode);for(var i=0;i<this._instances.length;i++){this._attachInstance(i,parent);}}},ready:function(){this._instanceProps={__key__:true};this._instanceProps[this.as]=true;this._instanceProps[this.indexAs]=true;if(!this.ctor){this.templatize(this);}},_sortChanged:function(sort){var dataHost=this._getRootDataHost();this._sortFn=sort&&(typeof sort=='function'?sort:function(){return dataHost[sort].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_filterChanged:function(filter){var dataHost=this._getRootDataHost();this._filterFn=filter&&(typeof filter=='function'?filter:function(){return dataHost[filter].apply(dataHost,arguments);});this._needFullRefresh=true;if(this.items){this._debounceTemplate(this._render);}},_computeFrameTime:function(rate){return Math.ceil(1000/rate);},_initializeChunking:function(){if(this.initialCount){this._limit=this.initialCount;this._chunkCount=this.initialCount;this._lastChunkTime=performance.now();}},_tryRenderChunk:function(){if(this.items&&this._limit<this.items.length){this.debounce('renderChunk',this._requestRenderChunk);}},_requestRenderChunk:function(){requestAnimationFrame(this._boundRenderChunk);},_renderChunk:function(){var currChunkTime=performance.now();var ratio=this._targetFrameTime/(currChunkTime-this._lastChunkTime);this._chunkCount=Math.round(this._chunkCount*ratio)||1;this._limit+=this._chunkCount;this._lastChunkTime=currChunkTime;this._debounceTemplate(this._render);},_observeChanged:function(){this._observePaths=this.observe&&this.observe.replace('.*','.').split(' ');},_itemsChanged:function(change){if(change.path=='items'){if(Array.isArray(this.items)){this.collection=Polymer.Collection.get(this.items);}else if(!this.items){this.collection=null;}else{this._error(this._logf('dom-repeat','expected array for `items`,'+' found',this.items));}
 this._keySplices=[];this._indexSplices=[];this._needFullRefresh=true;this._initializeChunking();this._debounceTemplate(this._render);}else if(change.path=='items.splices'){this._keySplices=this._keySplices.concat(change.value.keySplices);this._indexSplices=this._indexSplices.concat(change.value.indexSplices);this._debounceTemplate(this._render);}else{var subpath=change.path.slice(6);this._forwardItemPath(subpath,change.value);this._checkObservedPaths(subpath);}},_checkObservedPaths:function(path){if(this._observePaths){path=path.substring(path.indexOf('.')+1);var paths=this._observePaths;for(var i=0;i<paths.length;i++){if(path.indexOf(paths[i])===0){this._needFullRefresh=true;if(this.delay){this.debounce('render',this._render,this.delay);}else{this._debounceTemplate(this._render);}
 return;}}}},render:function(){this._needFullRefresh=true;this._debounceTemplate(this._render);this._flushTemplates();},_render:function(){if(this._needFullRefresh){this._applyFullRefresh();this._needFullRefresh=false;}else if(this._keySplices.length){if(this._sortFn){this._applySplicesUserSort(this._keySplices);}else{if(this._filterFn){this._applyFullRefresh();}else{this._applySplicesArrayOrder(this._indexSplices);}}}else{}
 this._keySplices=[];this._indexSplices=[];var keyToIdx=this._keyToInstIdx={};for(var i=this._instances.length-1;i>=0;i--){var inst=this._instances[i];if(inst.isPlaceholder&&i<this._limit){inst=this._insertInstance(i,inst.__key__);}else if(!inst.isPlaceholder&&i>=this._limit){inst=this._downgradeInstance(i,inst.__key__);}
 keyToIdx[inst.__key__]=i;if(!inst.isPlaceholder){inst.__setProperty(this.indexAs,i,true);}}
-this._pool.length=0;this._setRenderedItemCount(this._instances.length);this.fire('dom-change');this._tryRenderChunk();},_applyFullRefresh:function(){var c=this.collection;var keys;if(this._sortFn){keys=c?c.getKeys():[];}else{keys=[];var items=this.items;if(items){for(var i=0;i<items.length;i++){keys.push(c.getKey(items[i]));}}}
+this._pool.length=0;this._setRenderedItemCount(this._instances.length);if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}
+this._tryRenderChunk();},_applyFullRefresh:function(){var c=this.collection;var keys;if(this._sortFn){keys=c?c.getKeys():[];}else{keys=[];var items=this.items;if(items){for(var i=0;i<items.length;i++){keys.push(c.getKey(items[i]));}}}
 var self=this;if(this._filterFn){keys=keys.filter(function(a){return self._filterFn(c.getItem(a));});}
 if(this._sortFn){keys.sort(function(a,b){return self._sortFn(c.getItem(a),c.getItem(b));});}
 for(i=0;i<keys.length;i++){var key=keys[i];var inst=this._instances[i];if(inst){inst.__key__=key;if(!inst.isPlaceholder&&i<this._limit){inst.__setProperty(this.as,c.getItem(key),true);}}else if(i<this._limit){this._insertInstance(i,key);}else{this._insertPlaceholder(i,key);}}
@@ -4088,157 +4165,162 @@
 return inst;}},_attachInstance:function(idx,parent){var inst=this._instances[idx];if(!inst.isPlaceholder){parent.insertBefore(inst.root,this);}},_detachAndRemoveInstance:function(idx){var inst=this._detachInstance(idx);if(inst){this._pool.push(inst);}
 this._instances.splice(idx,1);},_insertPlaceholder:function(idx,key){this._instances.splice(idx,0,{isPlaceholder:true,__key__:key});},_stampInstance:function(idx,key){var model={__key__:key};model[this.as]=this.collection.getItem(key);model[this.indexAs]=idx;return this.stamp(model);},_insertInstance:function(idx,key){var inst=this._pool.pop();if(inst){inst.__setProperty(this.as,this.collection.getItem(key),true);inst.__setProperty('__key__',key,true);}else{inst=this._stampInstance(idx,key);}
 var beforeRow=this._instances[idx+1];var beforeNode=beforeRow&&!beforeRow.isPlaceholder?beforeRow._children[0]:this;var parentNode=Polymer.dom(this).parentNode;Polymer.dom(parentNode).insertBefore(inst.root,beforeNode);this._instances[idx]=inst;return inst;},_downgradeInstance:function(idx,key){var inst=this._detachInstance(idx);if(inst){this._pool.push(inst);}
-inst={isPlaceholder:true,__key__:key};this._instances[idx]=inst;return inst;},_showHideChildren:function(hidden){for(var i=0;i<this._instances.length;i++){this._instances[i]._showHideChildren(hidden);}},_forwardInstanceProp:function(inst,prop,value){if(prop==this.as){var idx;if(this._sortFn||this._filterFn){idx=this.items.indexOf(this.collection.getItem(inst.__key__));}else{idx=inst[this.indexAs];}
+inst={isPlaceholder:true,__key__:key};this._instances[idx]=inst;return inst;},_showHideChildren:function(hidden){for(var i=0;i<this._instances.length;i++){if(!this._instances[i].isPlaceholder)
+this._instances[i]._showHideChildren(hidden);}},_forwardInstanceProp:function(inst,prop,value){if(prop==this.as){var idx;if(this._sortFn||this._filterFn){idx=this.items.indexOf(this.collection.getItem(inst.__key__));}else{idx=inst[this.indexAs];}
 this.set('items.'+idx,value);}},_forwardInstancePath:function(inst,path,value){if(path.indexOf(this.as+'.')===0){this._notifyPath('items.'+inst.__key__+'.'+path.slice(this.as.length+1),value);}},_forwardParentProp:function(prop,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++){if(!inst.isPlaceholder){inst.__setProperty(prop,value,true);}}},_forwardParentPath:function(path,value){var i$=this._instances;for(var i=0,inst;i<i$.length&&(inst=i$[i]);i++){if(!inst.isPlaceholder){inst._notifyPath(path,value,true);}}},_forwardItemPath:function(path,value){if(this._keyToInstIdx){var dot=path.indexOf('.');var key=path.substring(0,dot<0?path.length:dot);var idx=this._keyToInstIdx[key];var inst=this._instances[idx];if(inst&&!inst.isPlaceholder){if(dot>=0){path=this.as+'.'+path.substring(dot+1);inst._notifyPath(path,value,true);}else{inst.__setProperty(this.as,value,true);}}}},itemForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.as];},keyForElement:function(el){var instance=this.modelForElement(el);return instance&&instance.__key__;},indexForElement:function(el){var instance=this.modelForElement(el);return instance&&instance[this.indexAs];}});Polymer({is:'array-selector',_template:null,properties:{items:{type:Array,observer:'clearSelection'},multi:{type:Boolean,value:false,observer:'clearSelection'},selected:{type:Object,notify:true},selectedItem:{type:Object,notify:true},toggle:{type:Boolean,value:false}},clearSelection:function(){if(Array.isArray(this.selected)){for(var i=0;i<this.selected.length;i++){this.unlinkPaths('selected.'+i);}}else{this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}
 if(this.multi){if(!this.selected||this.selected.length){this.selected=[];this._selectedColl=Polymer.Collection.get(this.selected);}}else{this.selected=null;this._selectedColl=null;}
-this.selectedItem=null;},isSelected:function(item){if(this.multi){return this._selectedColl.getKey(item)!==undefined;}else{return this.selected==item;}},deselect:function(item){if(this.multi){if(this.isSelected(item)){var skey=this._selectedColl.getKey(item);this.arrayDelete('selected',item);this.unlinkPaths('selected.'+skey);}}else{this.selected=null;this.selectedItem=null;this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}},select:function(item){var icol=Polymer.Collection.get(this.items);var key=icol.getKey(item);if(this.multi){if(this.isSelected(item)){if(this.toggle){this.deselect(item);}}else{this.push('selected',item);var skey=this._selectedColl.getKey(item);this.linkPaths('selected.'+skey,'items.'+key);}}else{if(this.toggle&&item==this.selected){this.deselect();}else{this.selected=item;this.selectedItem=item;this.linkPaths('selected','items.'+key);this.linkPaths('selectedItem','items.'+key);}}}});Polymer({is:'dom-if',extends:'template',_template:null,properties:{'if':{type:Boolean,value:false,observer:'_queueRender'},restamp:{type:Boolean,value:false,observer:'_queueRender'}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render);},detached:function(){if(!this.parentNode||this.parentNode.nodeType==Node.DOCUMENT_FRAGMENT_NODE&&(!Polymer.Settings.hasShadow||!(this.parentNode instanceof ShadowRoot))){this._teardownInstance();}},attached:function(){if(this.if&&this.ctor){this.async(this._ensureInstance);}},render:function(){this._flushTemplates();},_render:function(){if(this.if){if(!this.ctor){this.templatize(this);}
+this.selectedItem=null;},isSelected:function(item){if(this.multi){return this._selectedColl.getKey(item)!==undefined;}else{return this.selected==item;}},deselect:function(item){if(this.multi){if(this.isSelected(item)){var skey=this._selectedColl.getKey(item);this.arrayDelete('selected',item);this.unlinkPaths('selected.'+skey);}}else{this.selected=null;this.selectedItem=null;this.unlinkPaths('selected');this.unlinkPaths('selectedItem');}},select:function(item){var icol=Polymer.Collection.get(this.items);var key=icol.getKey(item);if(this.multi){if(this.isSelected(item)){if(this.toggle){this.deselect(item);}}else{this.push('selected',item);var skey=this._selectedColl.getKey(item);this.linkPaths('selected.'+skey,'items.'+key);}}else{if(this.toggle&&item==this.selected){this.deselect();}else{this.selected=item;this.selectedItem=item;this.linkPaths('selected','items.'+key);this.linkPaths('selectedItem','items.'+key);}}}});Polymer({is:'dom-if',extends:'template',_template:null,properties:{'if':{type:Boolean,value:false,observer:'_queueRender'},restamp:{type:Boolean,value:false,observer:'_queueRender'},notifyDomChange:{type:Boolean}},behaviors:[Polymer.Templatizer],_queueRender:function(){this._debounceTemplate(this._render);},detached:function(){if(!this.parentNode||this.parentNode.nodeType==Node.DOCUMENT_FRAGMENT_NODE&&(!Polymer.Settings.hasShadow||!(this.parentNode instanceof ShadowRoot))){this._teardownInstance();}},attached:function(){if(this.if&&this.ctor){this.async(this._ensureInstance);}},render:function(){this._flushTemplates();},_render:function(){if(this.if){if(!this.ctor){this.templatize(this);}
 this._ensureInstance();this._showHideChildren();}else if(this.restamp){this._teardownInstance();}
 if(!this.restamp&&this._instance){this._showHideChildren();}
-if(this.if!=this._lastIf){this.fire('dom-change');this._lastIf=this.if;}},_ensureInstance:function(){var parentNode=Polymer.dom(this).parentNode;if(parentNode){var parent=Polymer.dom(parentNode);if(!this._instance){this._instance=this.stamp();var root=this._instance.root;parent.insertBefore(root,this);}else{var c$=this._instance._children;if(c$&&c$.length){var lastChild=Polymer.dom(this).previousSibling;if(lastChild!==c$[c$.length-1]){for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.insertBefore(n,this);}}}}}},_teardownInstance:function(){if(this._instance){var c$=this._instance._children;if(c$&&c$.length){var parent=Polymer.dom(Polymer.dom(c$[0]).parentNode);for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.removeChild(n);}}
-this._instance=null;}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this.if;if(this._instance){this._instance._showHideChildren(hidden);}},_forwardParentProp:function(prop,value){if(this._instance){this._instance[prop]=value;}},_forwardParentPath:function(path,value){if(this._instance){this._instance._notifyPath(path,value,true);}}});Polymer({is:'dom-bind',extends:'template',_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState=='loading'){document.addEventListener('DOMContentLoaded',function(){self._markImportsReady();});}else{self._markImportsReady();}});},_ensureReady:function(){if(!this._readied){this._readySelf();}},_markImportsReady:function(){this._importsReady=true;this._ensureReady();},_registerFeatures:function(){this._prepConstructor();},_insertChildren:function(){var parentDom=Polymer.dom(Polymer.dom(this).parentNode);parentDom.insertBefore(this.root,this);},_removeChildren:function(){if(this._children){for(var i=0;i<this._children.length;i++){this.root.appendChild(this._children[i]);}}},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost){return this.dataHost._scopeElementClass(element,selector);}else{return selector;}},_prepConfigure:function(){var config={};for(var prop in this._propertyEffects){config[prop]=this[prop];}
+if(this.if!=this._lastIf){if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}
+this._lastIf=this.if;}},_ensureInstance:function(){var parentNode=Polymer.dom(this).parentNode;if(parentNode){var parent=Polymer.dom(parentNode);if(!this._instance){this._instance=this.stamp();var root=this._instance.root;parent.insertBefore(root,this);}else{var c$=this._instance._children;if(c$&&c$.length){var lastChild=Polymer.dom(this).previousSibling;if(lastChild!==c$[c$.length-1]){for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.insertBefore(n,this);}}}}}},_teardownInstance:function(){if(this._instance){var c$=this._instance._children;if(c$&&c$.length){var parent=Polymer.dom(Polymer.dom(c$[0]).parentNode);for(var i=0,n;i<c$.length&&(n=c$[i]);i++){parent.removeChild(n);}}
+this._instance=null;}},_showHideChildren:function(){var hidden=this.__hideTemplateChildren__||!this.if;if(this._instance){this._instance._showHideChildren(hidden);}},_forwardParentProp:function(prop,value){if(this._instance){this._instance.__setProperty(prop,value,true);}},_forwardParentPath:function(path,value){if(this._instance){this._instance._notifyPath(path,value,true);}}});Polymer({is:'dom-bind',properties:{notifyDomChange:{type:Boolean}},extends:'template',_template:null,created:function(){var self=this;Polymer.RenderStatus.whenReady(function(){if(document.readyState=='loading'){document.addEventListener('DOMContentLoaded',function(){self._markImportsReady();});}else{self._markImportsReady();}});},_ensureReady:function(){if(!this._readied){this._readySelf();}},_markImportsReady:function(){this._importsReady=true;this._ensureReady();},_registerFeatures:function(){this._prepConstructor();},_insertChildren:function(){var parentDom=Polymer.dom(Polymer.dom(this).parentNode);parentDom.insertBefore(this.root,this);},_removeChildren:function(){if(this._children){for(var i=0;i<this._children.length;i++){this.root.appendChild(this._children[i]);}}},_initFeatures:function(){},_scopeElementClass:function(element,selector){if(this.dataHost){return this.dataHost._scopeElementClass(element,selector);}else{return selector;}},_configureInstanceProperties:function(){},_prepConfigure:function(){var config={};for(var prop in this._propertyEffects){config[prop]=this[prop];}
 var setupConfigure=this._setupConfigure;this._setupConfigure=function(){setupConfigure.call(this,config);};},attached:function(){if(this._importsReady){this.render();}},detached:function(){this._removeChildren();},render:function(){this._ensureReady();if(!this._children){this._template=this;this._prepAnnotations();this._prepEffects();this._prepBehaviors();this._prepConfigure();this._prepBindings();this._prepPropertyInfo();Polymer.Base._initFeatures.call(this);this._children=Polymer.TreeApi.arrayCopyChildNodes(this.root);}
-this._insertChildren();this.fire('dom-change');}});'use strict';if(!Polymer.Settings.useNativeShadow){tr.b.showPanic('Polymer error','base only works in shadow mode');}'use strict';var global=this.window||this.global;this.tr=(function(){if(global.tr)return global.tr;function exportPath(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
+this._insertChildren();if(!Polymer.Settings.suppressTemplateNotifications||this.notifyDomChange){this.fire('dom-change');}}});'use strict';if(!Polymer.Settings.useNativeShadow){tr.b.showPanic('Polymer error','base only works in shadow mode');}'use strict';const global=this.window||this.global;this.tr=(function(){if(global.tr)return global.tr;function exportPath(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{cur=cur[part]={};}}
 return cur;}
-function isExported(name){var parts=name.split('.');var cur=global;for(var part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
+function isExported(name){const parts=name.split('.');let cur=global;for(let part;parts.length&&(part=parts.shift());){if(part in cur){cur=cur[part];}else{return false;}}
 return true;}
-function isDefined(name){var parts=name.split('.');var curObject=global;for(var i=0;i<parts.length;i++){var partName=parts[i];var nextObject=curObject[partName];if(nextObject===undefined)return false;curObject=nextObject;}
+function isDefined(name){const parts=name.split('.');let curObject=global;for(let i=0;i<parts.length;i++){const partName=parts[i];const nextObject=curObject[partName];if(nextObject===undefined)return false;curObject=nextObject;}
 return true;}
-var panicElement=undefined;var rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)return;var panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='-webkit-flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
+let panicElement=undefined;const rawPanicMessages=[];function showPanicElementIfNeeded(){if(panicElement)return;const panicOverlay=document.createElement('div');panicOverlay.style.backgroundColor='white';panicOverlay.style.border='3px solid red';panicOverlay.style.boxSizing='border-box';panicOverlay.style.color='black';panicOverlay.style.display='-webkit-flex';panicOverlay.style.height='100%';panicOverlay.style.left=0;panicOverlay.style.padding='8px';panicOverlay.style.position='fixed';panicOverlay.style.top=0;panicOverlay.style.webkitFlexDirection='column';panicOverlay.style.width='100%';panicElement=document.createElement('div');panicElement.style.webkitFlex='1 1 auto';panicElement.style.overflow='auto';panicOverlay.appendChild(panicElement);if(!document.body){setTimeout(function(){document.body.appendChild(panicOverlay);},150);}else{document.body.appendChild(panicOverlay);}}
 function showPanic(panicTitle,panicDetails){if(tr.isHeadless){if(panicDetails instanceof Error)throw panicDetails;throw new Error('Panic: '+panicTitle+':\n'+panicDetails);}
 if(panicDetails instanceof Error){panicDetails=panicDetails.stack;}
-showPanicElementIfNeeded();var panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
+showPanicElementIfNeeded();const panicMessageEl=document.createElement('div');panicMessageEl.innerHTML='<h2 id="message"></h2>'+'<pre id="details"></pre>';panicMessageEl.querySelector('#message').textContent=panicTitle;panicMessageEl.querySelector('#details').textContent=panicDetails;panicElement.appendChild(panicMessageEl);rawPanicMessages.push({title:panicTitle,details:panicDetails});}
 function hasPanic(){return rawPanicMessages.length!==0;}
 function getPanicText(){return rawPanicMessages.map(function(msg){return msg.title;}).join(', ');}
-function exportTo(namespace,fn){var obj=exportPath(namespace);var exports=fn();for(var propertyName in exports){var propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor){Object.defineProperty(obj,propertyName,propertyDescriptor);}}}
+function exportTo(namespace,fn){const obj=exportPath(namespace);const exports=fn();for(const propertyName in exports){const propertyDescriptor=Object.getOwnPropertyDescriptor(exports,propertyName);if(propertyDescriptor){Object.defineProperty(obj,propertyName,propertyDescriptor);}}}
 function initialize(){if(global.isVinn){tr.isVinn=true;}else if(global.process&&global.process.versions.node){tr.isNode=true;}else{tr.isVinn=false;tr.isNode=false;tr.doc=document;tr.isMac=/Mac/.test(navigator.platform);tr.isWindows=/Win/.test(navigator.platform);tr.isChromeOS=/CrOS/.test(navigator.userAgent);tr.isLinux=/Linux/.test(navigator.userAgent);}
 tr.isHeadless=tr.isVinn||tr.isNode;}
 return{initialize,exportTo,isExported,isDefined,showPanic,hasPanic,getPanicText,};})();tr.initialize();'use strict';tr.exportTo('tr.b',function(){function EventTarget(){}
-EventTarget.decorate=function(target){for(var k in EventTarget.prototype){if(k==='decorate')continue;var v=EventTarget.prototype[k];if(typeof v!=='function')continue;target[k]=v;}};EventTarget.prototype={addEventListener:function(type,handler){if(!this.listeners_){this.listeners_=Object.create(null);}
-if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{var handlers=this.listeners_[type];if(handlers.indexOf(handler)<0){handlers.push(handler);}}},removeEventListener:function(type,handler){if(!this.listeners_)return;if(type in this.listeners_){var handlers=this.listeners_[type];var index=handlers.indexOf(handler);if(index>=0){if(handlers.length===1){delete this.listeners_[type];}else{handlers.splice(index,1);}}}},dispatchEvent:function(event){if(!this.listeners_)return true;event.__defineGetter__('target',()=>this);var realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};var type=event.type;var prevented=0;if(type in this.listeners_){var handlers=this.listeners_[type].concat();for(var i=0,handler;handler=handlers[i];i++){if(handler.handleEvent){prevented|=handler.handleEvent.call(handler,event)===false;}else{prevented|=handler.call(this,event)===false;}}}
-return!prevented&&event.rawReturnValue;},hasEventListener:function(type){return(this.listeners_!==undefined&&this.listeners_[type]!==undefined);}};return{EventTarget,};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;}
-var BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';var TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';var ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined){throw new Error('Mode is required');}
+EventTarget.decorate=function(target){for(const k in EventTarget.prototype){if(k==='decorate')continue;const v=EventTarget.prototype[k];if(typeof v!=='function')continue;target[k]=v;}};EventTarget.prototype={addEventListener(type,handler){if(!this.listeners_){this.listeners_=Object.create(null);}
+if(!(type in this.listeners_)){this.listeners_[type]=[handler];}else{const handlers=this.listeners_[type];if(handlers.indexOf(handler)<0){handlers.push(handler);}}},removeEventListener(type,handler){if(!this.listeners_)return;if(type in this.listeners_){const handlers=this.listeners_[type];const index=handlers.indexOf(handler);if(index>=0){if(handlers.length===1){delete this.listeners_[type];}else{handlers.splice(index,1);}}}},dispatchEvent(event){if(!this.listeners_)return true;event.__defineGetter__('target',()=>this);const realPreventDefault=event.preventDefault;event.preventDefault=function(){realPreventDefault.call(this);this.rawReturnValue=false;};const type=event.type;let prevented=0;if(type in this.listeners_){const handlers=this.listeners_[type].concat();for(let i=0,handler;handler=handlers[i];i++){if(handler.handleEvent){prevented|=handler.handleEvent.call(handler,event)===false;}else{prevented|=handler.call(this,event)===false;}}}
+return!prevented&&event.rawReturnValue;},async dispatchAsync(event){if(!this.listeners_)return true;const listeners=this.listeners_[event.type];if(listeners===undefined)return;await Promise.all(listeners.slice().map(listener=>{if(listener.handleEvent){return listener.handleEvent.call(listener,event);}
+return listener.call(this,event);}));},hasEventListener(type){return(this.listeners_!==undefined&&this.listeners_[type]!==undefined);}};return{EventTarget,};});'use strict';tr.exportTo('tr.b',function(){function RegisteredTypeInfo(constructor,metadata){this.constructor=constructor;this.metadata=metadata;}
+const BASIC_REGISTRY_MODE='BASIC_REGISTRY_MODE';const TYPE_BASED_REGISTRY_MODE='TYPE_BASED_REGISTRY_MODE';const ALL_MODES={BASIC_REGISTRY_MODE:true,TYPE_BASED_REGISTRY_MODE:true};function ExtensionRegistryOptions(mode){if(mode===undefined){throw new Error('Mode is required');}
 if(!ALL_MODES[mode]){throw new Error('Not a mode.');}
 this.mode_=mode;this.defaultMetadata_={};this.defaultConstructor_=undefined;this.defaultTypeInfo_=undefined;this.frozen_=false;}
-ExtensionRegistryOptions.prototype={freeze:function(){if(this.frozen_){throw new Error('Frozen');}
+ExtensionRegistryOptions.prototype={freeze(){if(this.frozen_){throw new Error('Frozen');}
 this.frozen_=true;},get mode(){return this.mode_;},get defaultMetadata(){return this.defaultMetadata_;},set defaultMetadata(defaultMetadata){if(this.frozen_){throw new Error('Frozen');}
 this.defaultMetadata_=defaultMetadata;this.defaultTypeInfo_=undefined;},get defaultConstructor(){return this.defaultConstructor_;},set defaultConstructor(defaultConstructor){if(this.frozen_){throw new Error('Frozen');}
 this.defaultConstructor_=defaultConstructor;this.defaultTypeInfo_=undefined;},get defaultTypeInfo(){if(this.defaultTypeInfo_===undefined&&this.defaultConstructor_){this.defaultTypeInfo_=new RegisteredTypeInfo(this.defaultConstructor,this.defaultMetadata);}
-return this.defaultTypeInfo_;},validateConstructor:function(constructor){if(!this.mandatoryBaseClass)return;var curProto=constructor.prototype.__proto__;var ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
+return this.defaultTypeInfo_;},validateConstructor(constructor){if(!this.mandatoryBaseClass)return;let curProto=constructor.prototype.__proto__;let ok=false;while(curProto){if(curProto===this.mandatoryBaseClass.prototype){ok=true;break;}
 curProto=curProto.__proto__;}
-if(!ok){throw new Error(constructor+'must be subclass of '+registry);}}};return{BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions,RegisteredTypeInfo,};});'use strict';tr.exportTo('tr.b',function(){var Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;}
-HeadlessEvent.prototype={preventDefault:function(){this.defaultPrevented=true;},stopPropagation:function(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){var e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;}
+if(!ok){throw new Error(constructor+'must be subclass of '+registry);}}};return{BASIC_REGISTRY_MODE,TYPE_BASED_REGISTRY_MODE,ExtensionRegistryOptions,RegisteredTypeInfo,};});'use strict';tr.exportTo('tr.b',function(){let Event;if(tr.isHeadless){function HeadlessEvent(type,opt_bubbles,opt_preventable){this.type=type;this.bubbles=(opt_bubbles!==undefined?!!opt_bubbles:false);this.cancelable=(opt_preventable!==undefined?!!opt_preventable:false);this.defaultPrevented=false;this.cancelBubble=false;}
+HeadlessEvent.prototype={preventDefault(){this.defaultPrevented=true;},stopPropagation(){this.cancelBubble=true;}};Event=HeadlessEvent;}else{function TrEvent(type,opt_bubbles,opt_preventable){const e=tr.doc.createEvent('Event');e.initEvent(type,!!opt_bubbles,!!opt_preventable);e.__proto__=global.Event.prototype;return e;}
 TrEvent.prototype={__proto__:global.Event.prototype};Event=TrEvent;}
-function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable,opt_fields){var e=new tr.b.Event(type,opt_bubbles,opt_cancelable);if(opt_fields){for(var[name,value]of Object.entries(opt_fields)){e[name]=value;}}
-return target.dispatchEvent(e);}
-return{Event,dispatchSimpleEvent,};});'use strict';tr.exportTo('tr.b',function(){var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined){throw new Error('Handler already registered for '+constructor);}
-extensionRegistryOptions.validateConstructor(constructor);var metadata={};for(var k in extensionRegistryOptions.defaultMetadata){metadata[k]=extensionRegistryOptions.defaultMetadata[k];}
-if(opt_metadata){for(var k in opt_metadata){metadata[k]=opt_metadata[k];}}
-var typeInfo=new RegisteredTypeInfo(constructor,metadata);var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(var i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){return i;}}
-return undefined;};registry.unregister=function(constructor){var foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined){throw new Error(constructor+' not registered');}
-registry.registeredTypeInfos_.splice(foundIndex,1);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){var foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined){return this.registeredTypeInfos_[foundIndex];}
-return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(var i=0;i<registry.registeredTypeInfos_.length;++i){var typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo)){return typeInfo;}}
+function dispatchSimpleEvent(target,type,opt_bubbles,opt_cancelable,opt_fields){const e=new tr.b.Event(type,opt_bubbles,opt_cancelable);Object.assign(e,opt_fields);return target.dispatchEvent(e);}
+async function dispatchSimpleEventAsync(target,type,opt_fields){const e=new tr.b.Event(type,false,false);Object.assign(e,opt_fields);return await target.dispatchAsync(e);}
+return{Event,dispatchSimpleEvent,dispatchSimpleEventAsync,};});'use strict';tr.exportTo('tr.b',function(){const RegisteredTypeInfo=tr.b.RegisteredTypeInfo;const ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateBasicExtensionRegistry(registry,extensionRegistryOptions){const savedStateStack=[];registry.registeredTypeInfos_=[];registry.register=function(constructor,opt_metadata){if(registry.findIndexOfRegisteredConstructor(constructor)!==undefined){throw new Error('Handler already registered for '+constructor);}
+extensionRegistryOptions.validateConstructor(constructor);const metadata={};for(const k in extensionRegistryOptions.defaultMetadata){metadata[k]=extensionRegistryOptions.defaultMetadata[k];}
+if(opt_metadata){for(const k in opt_metadata){metadata[k]=opt_metadata[k];}}
+const typeInfo=new RegisteredTypeInfo(constructor,metadata);let e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push(registry.registeredTypeInfos_);registry.registeredTypeInfos_=[];const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){registry.registeredTypeInfos_=savedStateStack[0];savedStateStack.splice(0,1);const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.findIndexOfRegisteredConstructor=function(constructor){for(let i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){return i;}}
+return undefined;};registry.unregister=function(constructor){const foundIndex=registry.findIndexOfRegisteredConstructor(constructor);if(foundIndex===undefined){throw new Error(constructor+' not registered');}
+registry.registeredTypeInfos_.splice(foundIndex,1);const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getAllRegisteredTypeInfos=function(){return registry.registeredTypeInfos_;};registry.findTypeInfo=function(constructor){const foundIndex=this.findIndexOfRegisteredConstructor(constructor);if(foundIndex!==undefined){return this.registeredTypeInfos_[foundIndex];}
+return undefined;};registry.findTypeInfoMatching=function(predicate,opt_this){opt_this=opt_this?opt_this:undefined;for(let i=0;i<registry.registeredTypeInfos_.length;++i){const typeInfo=registry.registeredTypeInfos_[i];if(predicate.call(opt_this,typeInfo)){return typeInfo;}}
 return extensionRegistryOptions.defaultTypeInfo;};registry.findTypeInfoWithName=function(name){if(typeof(name)!=='string'){throw new Error('Name is not a string.');}
-var typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)return typeInfo;return undefined;};}
-return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){var categoryPartsFor={};function getCategoryParts(category){var parts=categoryPartsFor[category];if(parts!==undefined)return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
-return{getCategoryParts,};});'use strict';tr.exportTo('tr.b',function(){var getCategoryParts=tr.b.getCategoryParts;var RegisteredTypeInfo=tr.b.RegisteredTypeInfo;var ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){var savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_=new Map();registry.typeNameToTypeInfoMap_=new Map();registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);var typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName){typeInfo.typeNames.push(metadata.typeName);}
+const typeInfo=registry.findTypeInfoMatching(function(ti){return ti.constructor.name===name;});if(typeInfo)return typeInfo;return undefined;};}
+return{_decorateBasicExtensionRegistry:decorateBasicExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){const categoryPartsFor={};function getCategoryParts(category){let parts=categoryPartsFor[category];if(parts!==undefined)return parts;parts=category.split(',');categoryPartsFor[category]=parts;return parts;}
+return{getCategoryParts,};});'use strict';tr.exportTo('tr.b',function(){const getCategoryParts=tr.b.getCategoryParts;const RegisteredTypeInfo=tr.b.RegisteredTypeInfo;const ExtensionRegistryOptions=tr.b.ExtensionRegistryOptions;function decorateTypeBasedExtensionRegistry(registry,extensionRegistryOptions){const savedStateStack=[];registry.registeredTypeInfos_=[];registry.categoryPartToTypeInfoMap_=new Map();registry.typeNameToTypeInfoMap_=new Map();registry.register=function(constructor,metadata){extensionRegistryOptions.validateConstructor(constructor);const typeInfo=new RegisteredTypeInfo(constructor,metadata||extensionRegistryOptions.defaultMetadata);typeInfo.typeNames=[];typeInfo.categoryParts=[];if(metadata&&metadata.typeName){typeInfo.typeNames.push(metadata.typeName);}
 if(metadata&&metadata.typeNames){typeInfo.typeNames.push.apply(typeInfo.typeNames,metadata.typeNames);}
 if(metadata&&metadata.categoryParts){typeInfo.categoryParts.push.apply(typeInfo.categoryParts,metadata.categoryParts);}
 if(typeInfo.typeNames.length===0&&typeInfo.categoryParts.length===0){throw new Error('typeName or typeNames must be provided');}
-typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_.has(typeName)){throw new Error('typeName '+typeName+' already registered');}});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_.has(categoryPart)){throw new Error('categoryPart '+categoryPart+' already registered');}});var e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.set(typeName,typeInfo);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.set(categoryPart,typeInfo);});registry.registeredTypeInfos_.push(typeInfo);var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_=new Map();registry.categoryPartToTypeInfoMap_=new Map();var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){var state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){var typeInfoIndex=-1;for(var i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){typeInfoIndex=i;break;}}
+typeInfo.typeNames.forEach(function(typeName){if(registry.typeNameToTypeInfoMap_.has(typeName)){throw new Error('typeName '+typeName+' already registered');}});typeInfo.categoryParts.forEach(function(categoryPart){if(registry.categoryPartToTypeInfoMap_.has(categoryPart)){throw new Error('categoryPart '+categoryPart+' already registered');}});let e=new tr.b.Event('will-register');e.typeInfo=typeInfo;registry.dispatchEvent(e);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.set(typeName,typeInfo);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.set(categoryPart,typeInfo);});registry.registeredTypeInfos_.push(typeInfo);e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.pushCleanStateBeforeTest=function(){savedStateStack.push({registeredTypeInfos:registry.registeredTypeInfos_,typeNameToTypeInfoMap:registry.typeNameToTypeInfoMap_,categoryPartToTypeInfoMap:registry.categoryPartToTypeInfoMap_});registry.registeredTypeInfos_=[];registry.typeNameToTypeInfoMap_=new Map();registry.categoryPartToTypeInfoMap_=new Map();const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.popCleanStateAfterTest=function(){const state=savedStateStack[0];savedStateStack.splice(0,1);registry.registeredTypeInfos_=state.registeredTypeInfos;registry.typeNameToTypeInfoMap_=state.typeNameToTypeInfoMap;registry.categoryPartToTypeInfoMap_=state.categoryPartToTypeInfoMap;const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.unregister=function(constructor){let typeInfoIndex=-1;for(let i=0;i<registry.registeredTypeInfos_.length;i++){if(registry.registeredTypeInfos_[i].constructor===constructor){typeInfoIndex=i;break;}}
 if(typeInfoIndex===-1){throw new Error(constructor+' not registered');}
-var typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.delete(typeName);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.delete(categoryPart);});var e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){var categoryParts=getCategoryParts(category);for(var i=0;i<categoryParts.length;i++){var categoryPart=categoryParts[i];var typeInfo=registry.categoryPartToTypeInfoMap_.get(categoryPart);if(typeInfo!==undefined)return typeInfo;}}
-var typeInfo=registry.typeNameToTypeInfoMap_.get(typeName);if(typeInfo!==undefined)return typeInfo;return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){var typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)return typeInfo.constructor;return undefined;};}
-return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){function asArray(x){var values=[];if(x[Symbol.iterator]){for(var value of x){values.push(value);}}else{for(var i=0;i<x.length;i++){values.push(x[i]);}}
+const typeInfo=registry.registeredTypeInfos_[typeInfoIndex];registry.registeredTypeInfos_.splice(typeInfoIndex,1);typeInfo.typeNames.forEach(function(typeName){registry.typeNameToTypeInfoMap_.delete(typeName);});typeInfo.categoryParts.forEach(function(categoryPart){registry.categoryPartToTypeInfoMap_.delete(categoryPart);});const e=new tr.b.Event('registry-changed');registry.dispatchEvent(e);};registry.getTypeInfo=function(category,typeName){if(category){const categoryParts=getCategoryParts(category);for(let i=0;i<categoryParts.length;i++){const categoryPart=categoryParts[i];const typeInfo=registry.categoryPartToTypeInfoMap_.get(categoryPart);if(typeInfo!==undefined)return typeInfo;}}
+const typeInfo=registry.typeNameToTypeInfoMap_.get(typeName);if(typeInfo!==undefined)return typeInfo;return extensionRegistryOptions.defaultTypeInfo;};registry.getConstructor=function(category,typeName){const typeInfo=registry.getTypeInfo(category,typeName);if(typeInfo)return typeInfo.constructor;return undefined;};}
+return{_decorateTypeBasedExtensionRegistry:decorateTypeBasedExtensionRegistry};});'use strict';tr.exportTo('tr.b',function(){function asArray(x){const values=[];if(x[Symbol.iterator]){for(const value of x){values.push(value);}}else{for(let i=0;i<x.length;i++){values.push(x[i]);}}
 return values;}
-function getOnlyElement(iterable){var iterator=iterable[Symbol.iterator]();var firstIteration=iterator.next();if(firstIteration.done){throw new Error('getOnlyElement was passed an empty iterable.');}
-var secondIteration=iterator.next();if(!secondIteration.done){throw new Error('getOnlyElement was passed an iterable with multiple elements.');}
+function getOnlyElement(iterable){const iterator=iterable[Symbol.iterator]();const firstIteration=iterator.next();if(firstIteration.done){throw new Error('getOnlyElement was passed an empty iterable.');}
+const secondIteration=iterator.next();if(!secondIteration.done){throw new Error('getOnlyElement was passed an iterable with multiple elements.');}
 return firstIteration.value;}
-function getFirstElement(iterable){var iterator=iterable[Symbol.iterator]();var result=iterator.next();if(result.done){throw new Error('getFirstElement was passed an empty iterable.');}
+function getFirstElement(iterable){const iterator=iterable[Symbol.iterator]();const result=iterator.next();if(result.done){throw new Error('getFirstElement was passed an empty iterable.');}
 return result.value;}
-function compareArrays(x,y,elementCmp){var minLength=Math.min(x.length,y.length);for(var i=0;i<minLength;i++){var tmp=elementCmp(x[i],y[i]);if(tmp)return tmp;}
+function compareArrays(x,y,elementCmp){const minLength=Math.min(x.length,y.length);let i;for(i=0;i<minLength;i++){const tmp=elementCmp(x[i],y[i]);if(tmp)return tmp;}
 if(x.length===y.length)return 0;if(x[i]===undefined)return-1;return 1;}
 function comparePossiblyUndefinedValues(x,y,cmp,opt_this){if(x!==undefined&&y!==undefined){return cmp.call(opt_this,x,y);}
 if(x!==undefined)return-1;if(y!==undefined)return 1;return 0;}
-function concatenateObjects(){var result={};for(var i=0;i<arguments.length;i++){var object=arguments[i];for(var j in object){result[j]=object[j];}}
+function concatenateObjects(){const result={};for(let i=0;i<arguments.length;i++){const object=arguments[i];for(const j in object){result[j]=object[j];}}
 return result;}
-function dictionaryValues(dict){var values=[];for(var key in dict){values.push(dict[key]);}
-return values;}
-function dictionaryLength(dict){var n=0;for(var key in dict){n++;}
-return n;}
-function dictionaryContainsValue(dict,value){for(var key in dict){if(dict[key]===value){return true;}}
+function dictionaryContainsValue(dict,value){for(const key in dict){if(dict[key]===value){return true;}}
 return false;}
-function group(ary,callback,opt_this,opt_arrayConstructor){var arrayConstructor=opt_arrayConstructor||Array;var results={};for(var element of ary){var key=callback.call(opt_this,element);if(!(key in results)){results[key]=new arrayConstructor();}
-results[key].push(element);}
-return results;}
-function groupIntoMap(ary,callback,opt_this,opt_arrayConstructor){var arrayConstructor=opt_arrayConstructor||Array;var results=new Map();for(var element of ary){var key=callback.call(opt_this,element);var items=results.get(key);if(items===undefined){items=new arrayConstructor();results.set(key,items);}
+function groupIntoMap(ary,callback,opt_this,opt_arrayConstructor){const arrayConstructor=opt_arrayConstructor||Array;const results=new Map();for(const element of ary){const key=callback.call(opt_this,element);let items=results.get(key);if(items===undefined){items=new arrayConstructor();results.set(key,items);}
 items.push(element);}
 return results;}
-function mapItems(dict,fn,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];result[key]=fn.call(opt_this,key,dict[key]);}
+function mapItems(dict,fn,opt_this){opt_this=opt_this||this;const result={};const keys=Object.keys(dict);for(let i=0;i<keys.length;i++){const key=keys[i];result[key]=fn.call(opt_this,key,dict[key]);}
 return result;}
-function filterItems(dict,predicate,opt_this){opt_this=opt_this||this;var result={};var keys=Object.keys(dict);for(var i=0;i<keys.length;i++){var key=keys[i];var value=dict[key];if(predicate.call(opt_this,key,value)){result[key]=value;}}
+function filterItems(dict,predicate,opt_this){opt_this=opt_this||this;const result={};const keys=Object.keys(dict);for(let i=0;i<keys.length;i++){const key=keys[i];const value=dict[key];if(predicate.call(opt_this,key,value)){result[key]=value;}}
 return result;}
-function iterObjectFieldsRecursively(object,func){if(!(object instanceof Object))return;if(object instanceof Array){for(var i=0;i<object.length;i++){func(object,i,object[i]);iterObjectFieldsRecursively(object[i],func);}
+function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;let nextPosition=0;for(let i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))continue;if(nextPosition<i){array[nextPosition]=array[i];}
+nextPosition++;}
+if(nextPosition<array.length){array.length=nextPosition;}}
+function iterObjectFieldsRecursively(object,func){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){func(object,i,object[i]);iterObjectFieldsRecursively(object[i],func);}
 return;}
-for(var key in object){var value=object[key];func(object,key,value);iterObjectFieldsRecursively(value,func);}}
-function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;var result={};for(var i=0;i<array.length;i++){var item=array[i];if(item===undefined)continue;var dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)continue;for(var key in dict){var valueList=result[key];if(valueList===undefined){result[key]=valueList=new Array(array.length);}
+for(const key in object){const value=object[key];func(object,key,value);iterObjectFieldsRecursively(value,func);}}
+function invertArrayOfDicts(array,opt_dictGetter,opt_this){opt_this=opt_this||this;const result={};for(let i=0;i<array.length;i++){const item=array[i];if(item===undefined)continue;const dict=opt_dictGetter?opt_dictGetter.call(opt_this,item):item;if(dict===undefined)continue;for(const key in dict){let valueList=result[key];if(valueList===undefined){result[key]=valueList=new Array(array.length);}
 valueList[i]=dict[key];}}
 return result;}
-function arrayToDict(array,valueToKeyFn,opt_this){opt_this=opt_this||this;var result={};var length=array.length;for(var i=0;i<length;i++){var value=array[i];var key=valueToKeyFn.call(opt_this,value);result[key]=value;}
+function arrayToDict(array,valueToKeyFn,opt_this){opt_this=opt_this||this;const result={};const length=array.length;for(let i=0;i<length;i++){const value=array[i];const key=valueToKeyFn.call(opt_this,value);result[key]=value;}
 return result;}
 function identity(d){return d;}
-function findFirstIndexInArray(ary,opt_func,opt_this){var func=opt_func||identity;for(var i=0;i<ary.length;i++){if(func.call(opt_this,ary[i],i))return i;}
+function findFirstIndexInArray(ary,opt_func,opt_this){const func=opt_func||identity;for(let i=0;i<ary.length;i++){if(func.call(opt_this,ary[i],i))return i;}
 return-1;}
-function findFirstInArray(ary,opt_func,opt_this){var i=findFirstIndexInArray(ary,opt_func,opt_func);if(i===-1)return undefined;return ary[i];}
-function findFirstKeyInDictMatching(dict,opt_func,opt_this){var func=opt_func||identity;for(var key in dict){if(func.call(opt_this,key,dict[key])){return key;}}
+function findFirstInArray(ary,opt_func,opt_this){const i=findFirstIndexInArray(ary,opt_func,opt_func);if(i===-1)return undefined;return ary[i];}
+function findFirstKeyInDictMatching(dict,opt_func,opt_this){const func=opt_func||identity;for(const key in dict){if(func.call(opt_this,key,dict[key])){return key;}}
 return undefined;}
-function mapValues(map){var values=[];for(var value of map.values()){values.push(value);}
+function mapValues(map){const values=[];for(const value of map.values()){values.push(value);}
 return values;}
-function setsEqual(a,b){if(!(a instanceof Set)||!(b instanceof Set))return false;if(a.size!==b.size)return false;return Array.from(a).every(x=>b.has(x));}
-return{asArray,concatenateObjects,compareArrays,comparePossiblyUndefinedValues,dictionaryLength,dictionaryValues,dictionaryContainsValue,getOnlyElement,getFirstElement,group,groupIntoMap,mapItems,filterItems,iterObjectFieldsRecursively,invertArrayOfDicts,arrayToDict,identity,findFirstIndexInArray,findFirstInArray,findFirstKeyInDictMatching,mapValues,setsEqual,};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register){throw new Error('Already has registry');}
+function setsEqual(a,b){if(!(a instanceof Set)||!(b instanceof Set))return false;if(a.size!==b.size)return false;for(const x of a){if(!b.has(x))return false;}
+return true;}
+return{asArray,concatenateObjects,compareArrays,comparePossiblyUndefinedValues,dictionaryContainsValue,getOnlyElement,getFirstElement,groupIntoMap,mapItems,filterItems,inPlaceFilter,iterObjectFieldsRecursively,invertArrayOfDicts,arrayToDict,identity,findFirstIndexInArray,findFirstInArray,findFirstKeyInDictMatching,mapValues,setsEqual,};});'use strict';tr.exportTo('tr.b',function(){function decorateExtensionRegistry(registry,registryOptions){if(registry.register){throw new Error('Already has registry');}
 registryOptions.freeze();if(registryOptions.mode===tr.b.BASIC_REGISTRY_MODE){tr.b._decorateBasicExtensionRegistry(registry,registryOptions);}else if(registryOptions.mode===tr.b.TYPE_BASED_REGISTRY_MODE){tr.b._decorateTypeBasedExtensionRegistry(registry,registryOptions);}else{throw new Error('Unrecognized mode');}
 if(registry.addEventListener===undefined){tr.b.EventTarget.decorate(registry);}}
 return{decorateExtensionRegistry,};});'use strict';tr.exportTo('tr.importer',function(){function Importer(){}
-Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer:function(){return false;},extractSubtraces:function(){return[];},importClockSyncMarkers:function(){},importEvents:function(){},importSampleData:function(){},finalizeImport:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){var typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo){return typeInfo.constructor;}
+Importer.prototype={__proto__:Object.prototype,get importerName(){return'Importer';},isTraceDataContainer(){return false;},extractSubtraces(){return[];},importClockSyncMarkers(){},importEvents(){},importSampleData(){},finalizeImport(){}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Importer;tr.b.decorateExtensionRegistry(Importer,options);Importer.findImporterFor=function(eventData){const typeInfo=Importer.findTypeInfoMatching(function(ti){return ti.constructor.canImport(eventData);});if(typeInfo){return typeInfo.constructor;}
 return undefined;};return{Importer,};});'use strict';tr.exportTo('tr.e.importer.gcloud_trace',function(){function GcloudTraceImporter(model,eventData){this.importPriority=2;this.eventData_=eventData;}
 GcloudTraceImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
-var normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)return false;return normalizedEventData.slice(0,14)==='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces:function(){var traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace:function(){var events=[];var trace=JSON.parse(this.eventData_);var spanLength=trace.spans.length;for(var i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
-return{'traceEvents':events};},createEventForSpan:function(traceId,span){var newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
+const normalizedEventData=eventData.slice(0,20).replace(/\s/g,'');if(normalizedEventData.length<14)return false;return normalizedEventData.slice(0,14)==='{"projectId":"';};GcloudTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GcloudTraceImporter';},extractSubtraces(){const traceEvents=this.createEventsForTrace();return traceEvents?[traceEvents]:[];},createEventsForTrace(){const events=[];const trace=JSON.parse(this.eventData_);const spanLength=trace.spans.length;for(let i=0;i<spanLength;i++){events.push(this.createEventForSpan(trace.traceId,trace.spans[i]));}
+return{'traceEvents':events};},createEventForSpan(traceId,span){let newArgs={};if(span.labels){newArgs=JSON.parse(JSON.stringify(span.labels));}
 newArgs['Span ID']=span.spanId;newArgs['Start Time']=span.startTime;newArgs['End Time']=span.endTime;if(span.parentSpanId){newArgs['Parent Span ID']=span.parentSpanId;}
 return{name:span.name,args:newArgs,pid:traceId,ts:Date.parse(span.startTime)*1000,dur:(Date.parse(span.endTime)-Date.parse(span.startTime))*1000,cat:'tracespan',tid:traceId,ph:'X'};}};tr.importer.Importer.register(GcloudTraceImporter);return{GcloudTraceImporter,};});'use strict';tr.exportTo('tr.b.math',function(){function convertEventsToRanges(events){return events.map(function(event){return tr.b.math.Range.fromExplicitRange(event.start,event.end);});}
-function mergeRanges(inRanges,mergeThreshold,mergeFunction){var remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){var merged=[];if(remainingEvents.length===1){merged.push(mergeFunction(remainingEvents));}
+function mergeRanges(inRanges,mergeThreshold,mergeFunction){const remainingEvents=inRanges.slice();remainingEvents.sort(function(x,y){return x.min-y.min;});if(remainingEvents.length<=1){const merged=[];if(remainingEvents.length===1){merged.push(mergeFunction(remainingEvents));}
 return merged;}
-var mergedEvents=[];var currentMergeBuffer=[];var rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
+const mergedEvents=[];let currentMergeBuffer=[];let rightEdge;function beginMerging(){currentMergeBuffer.push(remainingEvents[0]);remainingEvents.splice(0,1);rightEdge=currentMergeBuffer[0].max;}
 function flushCurrentMergeBuffer(){if(currentMergeBuffer.length===0)return;mergedEvents.push(mergeFunction(currentMergeBuffer));currentMergeBuffer=[];if(remainingEvents.length!==0)beginMerging();}
-beginMerging();while(remainingEvents.length){var currentEvent=remainingEvents[0];var distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
+beginMerging();while(remainingEvents.length){const currentEvent=remainingEvents[0];const distanceFromRightEdge=currentEvent.min-rightEdge;if(distanceFromRightEdge<mergeThreshold){rightEdge=Math.max(rightEdge,currentEvent.max);remainingEvents.splice(0,1);currentMergeBuffer.push(currentEvent);continue;}
 flushCurrentMergeBuffer();}
 flushCurrentMergeBuffer();return mergedEvents;}
-function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)opt_totalRange=undefined;var emptyRanges=[];if(!inRanges.length){if(opt_totalRange)emptyRanges.push(opt_totalRange);return emptyRanges;}
+function findEmptyRangesBetweenRanges(inRanges,opt_totalRange){if(opt_totalRange&&opt_totalRange.isEmpty)opt_totalRange=undefined;const emptyRanges=[];if(!inRanges.length){if(opt_totalRange)emptyRanges.push(opt_totalRange);return emptyRanges;}
 inRanges=inRanges.slice();inRanges.sort(function(x,y){return x.min-y.min;});if(opt_totalRange&&(opt_totalRange.min<inRanges[0].min)){emptyRanges.push(tr.b.math.Range.fromExplicitRange(opt_totalRange.min,inRanges[0].min));}
-inRanges.forEach(function(range,index){for(var otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)continue;var other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,other.min));return;}
+inRanges.forEach(function(range,index){for(let otherIndex=0;otherIndex<inRanges.length;++otherIndex){if(index===otherIndex)continue;const other=inRanges[otherIndex];if(other.min>range.max){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,other.min));return;}
 if(other.max>range.max){return;}}
 if(opt_totalRange&&(range.max<opt_totalRange.max)){emptyRanges.push(tr.b.math.Range.fromExplicitRange(range.max,opt_totalRange.max));}});return emptyRanges;}
-return{convertEventsToRanges,findEmptyRangesBetweenRanges,mergeRanges,};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){var glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');var glMatrixModule=require(glMatrixAbsPath);for(var exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){var PREFERRED_NUMBER_SERIES_MULTIPLIERS=[1,2,5,10];function approximately(x,y,delta){if(delta===undefined)delta=1e-9;return Math.abs(x-y)<delta;}
+return{convertEventsToRanges,findEmptyRangesBetweenRanges,mergeRanges,};});!function(t,n){if("object"==typeof exports&&"object"==typeof module)module.exports=n();else if("function"==typeof define&&define.amd)define(n);else{var r=n();for(var a in r)("object"==typeof exports?exports:t)[a]=r[a]}}(this,function(){return function(t){function n(a){if(r[a])return r[a].exports;var e=r[a]={exports:{},id:a,loaded:!1};return t[a].call(e.exports,e,e.exports,n),e.loaded=!0,e.exports}var r={};return n.m=t,n.c=r,n.p="",n(0)}([function(t,n,r){n.glMatrix=r(1),n.mat2=r(2),n.mat2d=r(3),n.mat3=r(4),n.mat4=r(5),n.quat=r(6),n.vec2=r(9),n.vec3=r(7),n.vec4=r(8)},function(t,n,r){var a={};a.EPSILON=1e-6,a.ARRAY_TYPE="undefined"!=typeof Float32Array?Float32Array:Array,a.RANDOM=Math.random,a.setMatrixArrayType=function(t){GLMAT_ARRAY_TYPE=t};var e=Math.PI/180;a.toRadian=function(t){return t*e},t.exports=a},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1];t[1]=n[2],t[2]=r}else t[0]=n[0],t[1]=n[2],t[2]=n[1],t[3]=n[3];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*u-e*a;return o?(o=1/o,t[0]=u*o,t[1]=-a*o,t[2]=-e*o,t[3]=r*o,t):null},e.adjoint=function(t,n){var r=n[0];return t[0]=n[3],t[1]=-n[1],t[2]=-n[2],t[3]=r,t},e.determinant=function(t){return t[0]*t[3]-t[2]*t[1]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*i+u*c,t[1]=e*i+o*c,t[2]=a*f+u*s,t[3]=e*f+o*s,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+u*i,t[1]=e*c+o*i,t[2]=a*-i+u*c,t[3]=e*-i+o*c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1];return t[0]=a*i,t[1]=e*i,t[2]=u*c,t[3]=o*c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t},e.str=function(t){return"mat2("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2))},e.LDU=function(t,n,r,a){return t[2]=a[2]/a[0],r[0]=a[0],r[1]=a[1],r[3]=a[3]-t[2]*r[1],[t,n,r]},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(6);return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(6);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=0,t[5]=0,t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=r*u-a*e;return c?(c=1/c,t[0]=u*c,t[1]=-a*c,t[2]=-e*c,t[3]=r*c,t[4]=(e*i-u*o)*c,t[5]=(a*o-r*i)*c,t):null},e.determinant=function(t){return t[0]*t[3]-t[1]*t[2]},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1],h=r[2],M=r[3],l=r[4],v=r[5];return t[0]=a*f+u*s,t[1]=e*f+o*s,t[2]=a*h+u*M,t[3]=e*h+o*M,t[4]=a*l+u*v+i,t[5]=e*l+o*v+c,t},e.mul=e.multiply,e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=Math.sin(r),s=Math.cos(r);return t[0]=a*s+u*f,t[1]=e*s+o*f,t[2]=a*-f+u*s,t[3]=e*-f+o*s,t[4]=i,t[5]=c,t},e.scale=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a*f,t[1]=e*f,t[2]=u*s,t[3]=o*s,t[4]=i,t[5]=c,t},e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=r[0],s=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=a*f+u*s+i,t[5]=e*f+o*s+c,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=-r,t[3]=a,t[4]=0,t[5]=0,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=n[1],t[4]=0,t[5]=0,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=1,t[4]=n[0],t[5]=n[1],t},e.str=function(t){return"mat2d("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+1)},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(9);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat4=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[4],t[4]=n[5],t[5]=n[6],t[6]=n[8],t[7]=n[9],t[8]=n[10],t},e.clone=function(t){var n=new a.ARRAY_TYPE(9);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[5];t[1]=n[3],t[2]=n[6],t[3]=r,t[5]=n[7],t[6]=a,t[7]=e}else t[0]=n[0],t[1]=n[3],t[2]=n[6],t[3]=n[1],t[4]=n[4],t[5]=n[7],t[6]=n[2],t[7]=n[5],t[8]=n[8];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=s*o-i*f,M=-s*u+i*c,l=f*u-o*c,v=r*h+a*M+e*l;return v?(v=1/v,t[0]=h*v,t[1]=(-s*a+e*f)*v,t[2]=(i*a-e*o)*v,t[3]=M*v,t[4]=(s*r-e*c)*v,t[5]=(-i*r+e*u)*v,t[6]=l*v,t[7]=(-f*r+a*c)*v,t[8]=(o*r-a*u)*v,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8];return t[0]=o*s-i*f,t[1]=e*f-a*s,t[2]=a*i-e*o,t[3]=i*c-u*s,t[4]=r*s-e*c,t[5]=e*u-r*i,t[6]=u*f-o*c,t[7]=a*c-r*f,t[8]=r*o-a*u,t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8];return n*(f*u-o*c)+r*(-f*e+o*i)+a*(c*e-u*i)},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1],v=r[2],m=r[3],p=r[4],d=r[5],A=r[6],R=r[7],w=r[8];return t[0]=M*a+l*o+v*f,t[1]=M*e+l*i+v*s,t[2]=M*u+l*c+v*h,t[3]=m*a+p*o+d*f,t[4]=m*e+p*i+d*s,t[5]=m*u+p*c+d*h,t[6]=A*a+R*o+w*f,t[7]=A*e+R*i+w*s,t[8]=A*u+R*c+w*h,t},e.mul=e.multiply,e.translate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=r[0],l=r[1];return t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=M*a+l*o+f,t[7]=M*e+l*i+s,t[8]=M*u+l*c+h,t},e.rotate=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=Math.sin(r),l=Math.cos(r);return t[0]=l*a+M*o,t[1]=l*e+M*i,t[2]=l*u+M*c,t[3]=l*o-M*a,t[4]=l*i-M*e,t[5]=l*c-M*u,t[6]=f,t[7]=s,t[8]=h,t},e.scale=function(t,n,r){var a=r[0],e=r[1];return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=e*n[3],t[4]=e*n[4],t[5]=e*n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=n[0],t[7]=n[1],t[8]=1,t},e.fromRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=-r,t[4]=a,t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=n[1],t[5]=0,t[6]=0,t[7]=0,t[8]=1,t},e.fromMat2d=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=0,t[3]=n[2],t[4]=n[3],t[5]=0,t[6]=n[4],t[7]=n[5],t[8]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[3]=s-d,t[6]=M+p,t[1]=s+d,t[4]=1-f-v,t[7]=l-m,t[2]=M-p,t[5]=l+m,t[8]=1-f-h,t},e.normalFromMat4=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(c*P-o*b-f*x)*D,t[2]=(o*T-i*P+f*y)*D,t[3]=(e*T-a*b-u*E)*D,t[4]=(r*b-e*P+u*x)*D,t[5]=(a*P-r*T-u*y)*D,t[6]=(m*g-p*Y+d*q)*D,t[7]=(p*w-v*g-d*R)*D,t[8]=(v*Y-m*w+d*A)*D,t):null},e.str=function(t){return"mat3("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2))},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(16);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.clone=function(t){var n=new a.ARRAY_TYPE(16);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n[4]=t[4],n[5]=t[5],n[6]=t[6],n[7]=t[7],n[8]=t[8],n[9]=t[9],n[10]=t[10],n[11]=t[11],n[12]=t[12],n[13]=t[13],n[14]=t[14],n[15]=t[15],n},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.identity=function(t){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.transpose=function(t,n){if(t===n){var r=n[1],a=n[2],e=n[3],u=n[6],o=n[7],i=n[11];t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=r,t[6]=n[9],t[7]=n[13],t[8]=a,t[9]=u,t[11]=n[14],t[12]=e,t[13]=o,t[14]=i}else t[0]=n[0],t[1]=n[4],t[2]=n[8],t[3]=n[12],t[4]=n[1],t[5]=n[5],t[6]=n[9],t[7]=n[13],t[8]=n[2],t[9]=n[6],t[10]=n[10],t[11]=n[14],t[12]=n[3],t[13]=n[7],t[14]=n[11],t[15]=n[15];return t},e.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15],A=r*i-a*o,R=r*c-e*o,w=r*f-u*o,q=a*c-e*i,Y=a*f-u*i,g=e*f-u*c,y=s*m-h*v,x=s*p-M*v,P=s*d-l*v,E=h*p-M*m,T=h*d-l*m,b=M*d-l*p,D=A*b-R*T+w*E+q*P-Y*x+g*y;return D?(D=1/D,t[0]=(i*b-c*T+f*E)*D,t[1]=(e*T-a*b-u*E)*D,t[2]=(m*g-p*Y+d*q)*D,t[3]=(M*Y-h*g-l*q)*D,t[4]=(c*P-o*b-f*x)*D,t[5]=(r*b-e*P+u*x)*D,t[6]=(p*w-v*g-d*R)*D,t[7]=(s*g-M*w+l*R)*D,t[8]=(o*T-i*P+f*y)*D,t[9]=(a*P-r*T-u*y)*D,t[10]=(v*Y-m*w+d*A)*D,t[11]=(h*w-s*Y-l*A)*D,t[12]=(i*x-o*E-c*y)*D,t[13]=(r*E-a*x+e*y)*D,t[14]=(m*R-v*q-p*A)*D,t[15]=(s*q-h*R+M*A)*D,t):null},e.adjoint=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=n[4],i=n[5],c=n[6],f=n[7],s=n[8],h=n[9],M=n[10],l=n[11],v=n[12],m=n[13],p=n[14],d=n[15];return t[0]=i*(M*d-l*p)-h*(c*d-f*p)+m*(c*l-f*M),t[1]=-(a*(M*d-l*p)-h*(e*d-u*p)+m*(e*l-u*M)),t[2]=a*(c*d-f*p)-i*(e*d-u*p)+m*(e*f-u*c),t[3]=-(a*(c*l-f*M)-i*(e*l-u*M)+h*(e*f-u*c)),t[4]=-(o*(M*d-l*p)-s*(c*d-f*p)+v*(c*l-f*M)),t[5]=r*(M*d-l*p)-s*(e*d-u*p)+v*(e*l-u*M),t[6]=-(r*(c*d-f*p)-o*(e*d-u*p)+v*(e*f-u*c)),t[7]=r*(c*l-f*M)-o*(e*l-u*M)+s*(e*f-u*c),t[8]=o*(h*d-l*m)-s*(i*d-f*m)+v*(i*l-f*h),t[9]=-(r*(h*d-l*m)-s*(a*d-u*m)+v*(a*l-u*h)),t[10]=r*(i*d-f*m)-o*(a*d-u*m)+v*(a*f-u*i),t[11]=-(r*(i*l-f*h)-o*(a*l-u*h)+s*(a*f-u*i)),t[12]=-(o*(h*p-M*m)-s*(i*p-c*m)+v*(i*M-c*h)),t[13]=r*(h*p-M*m)-s*(a*p-e*m)+v*(a*M-e*h),t[14]=-(r*(i*p-c*m)-o*(a*p-e*m)+v*(a*c-e*i)),t[15]=r*(i*M-c*h)-o*(a*M-e*h)+s*(a*c-e*i),t},e.determinant=function(t){var n=t[0],r=t[1],a=t[2],e=t[3],u=t[4],o=t[5],i=t[6],c=t[7],f=t[8],s=t[9],h=t[10],M=t[11],l=t[12],v=t[13],m=t[14],p=t[15],d=n*o-r*u,A=n*i-a*u,R=n*c-e*u,w=r*i-a*o,q=r*c-e*o,Y=a*c-e*i,g=f*v-s*l,y=f*m-h*l,x=f*p-M*l,P=s*m-h*v,E=s*p-M*v,T=h*p-M*m;return d*T-A*E+R*P+w*x-q*y+Y*g},e.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],m=n[12],p=n[13],d=n[14],A=n[15],R=r[0],w=r[1],q=r[2],Y=r[3];return t[0]=R*a+w*i+q*h+Y*m,t[1]=R*e+w*c+q*M+Y*p,t[2]=R*u+w*f+q*l+Y*d,t[3]=R*o+w*s+q*v+Y*A,R=r[4],w=r[5],q=r[6],Y=r[7],t[4]=R*a+w*i+q*h+Y*m,t[5]=R*e+w*c+q*M+Y*p,t[6]=R*u+w*f+q*l+Y*d,t[7]=R*o+w*s+q*v+Y*A,R=r[8],w=r[9],q=r[10],Y=r[11],t[8]=R*a+w*i+q*h+Y*m,t[9]=R*e+w*c+q*M+Y*p,t[10]=R*u+w*f+q*l+Y*d,t[11]=R*o+w*s+q*v+Y*A,R=r[12],w=r[13],q=r[14],Y=r[15],t[12]=R*a+w*i+q*h+Y*m,t[13]=R*e+w*c+q*M+Y*p,t[14]=R*u+w*f+q*l+Y*d,t[15]=R*o+w*s+q*v+Y*A,t},e.mul=e.multiply,e.translate=function(t,n,r){var a,e,u,o,i,c,f,s,h,M,l,v,m=r[0],p=r[1],d=r[2];return n===t?(t[12]=n[0]*m+n[4]*p+n[8]*d+n[12],t[13]=n[1]*m+n[5]*p+n[9]*d+n[13],t[14]=n[2]*m+n[6]*p+n[10]*d+n[14],t[15]=n[3]*m+n[7]*p+n[11]*d+n[15]):(a=n[0],e=n[1],u=n[2],o=n[3],i=n[4],c=n[5],f=n[6],s=n[7],h=n[8],M=n[9],l=n[10],v=n[11],t[0]=a,t[1]=e,t[2]=u,t[3]=o,t[4]=i,t[5]=c,t[6]=f,t[7]=s,t[8]=h,t[9]=M,t[10]=l,t[11]=v,t[12]=a*m+i*p+h*d+n[12],t[13]=e*m+c*p+M*d+n[13],t[14]=u*m+f*p+l*d+n[14],t[15]=o*m+s*p+v*d+n[15]),t},e.scale=function(t,n,r){var a=r[0],e=r[1],u=r[2];return t[0]=n[0]*a,t[1]=n[1]*a,t[2]=n[2]*a,t[3]=n[3]*a,t[4]=n[4]*e,t[5]=n[5]*e,t[6]=n[6]*e,t[7]=n[7]*e,t[8]=n[8]*u,t[9]=n[9]*u,t[10]=n[10]*u,t[11]=n[11]*u,t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15],t},e.rotate=function(t,n,r,e){var u,o,i,c,f,s,h,M,l,v,m,p,d,A,R,w,q,Y,g,y,x,P,E,T,b=e[0],D=e[1],L=e[2],_=Math.sqrt(b*b+D*D+L*L);return Math.abs(_)<a.EPSILON?null:(_=1/_,b*=_,D*=_,L*=_,u=Math.sin(r),o=Math.cos(r),i=1-o,c=n[0],f=n[1],s=n[2],h=n[3],M=n[4],l=n[5],v=n[6],m=n[7],p=n[8],d=n[9],A=n[10],R=n[11],w=b*b*i+o,q=D*b*i+L*u,Y=L*b*i-D*u,g=b*D*i-L*u,y=D*D*i+o,x=L*D*i+b*u,P=b*L*i+D*u,E=D*L*i-b*u,T=L*L*i+o,t[0]=c*w+M*q+p*Y,t[1]=f*w+l*q+d*Y,t[2]=s*w+v*q+A*Y,t[3]=h*w+m*q+R*Y,t[4]=c*g+M*y+p*x,t[5]=f*g+l*y+d*x,t[6]=s*g+v*y+A*x,t[7]=h*g+m*y+R*x,t[8]=c*P+M*E+p*T,t[9]=f*P+l*E+d*T,t[10]=s*P+v*E+A*T,t[11]=h*P+m*E+R*T,n!==t&&(t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t)},e.rotateX=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[4],o=n[5],i=n[6],c=n[7],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[4]=u*e+f*a,t[5]=o*e+s*a,t[6]=i*e+h*a,t[7]=c*e+M*a,t[8]=f*e-u*a,t[9]=s*e-o*a,t[10]=h*e-i*a,t[11]=M*e-c*a,t},e.rotateY=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[8],s=n[9],h=n[10],M=n[11];return n!==t&&(t[4]=n[4],t[5]=n[5],t[6]=n[6],t[7]=n[7],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e-f*a,t[1]=o*e-s*a,t[2]=i*e-h*a,t[3]=c*e-M*a,t[8]=u*a+f*e,t[9]=o*a+s*e,t[10]=i*a+h*e,t[11]=c*a+M*e,t},e.rotateZ=function(t,n,r){var a=Math.sin(r),e=Math.cos(r),u=n[0],o=n[1],i=n[2],c=n[3],f=n[4],s=n[5],h=n[6],M=n[7];return n!==t&&(t[8]=n[8],t[9]=n[9],t[10]=n[10],t[11]=n[11],t[12]=n[12],t[13]=n[13],t[14]=n[14],t[15]=n[15]),t[0]=u*e+f*a,t[1]=o*e+s*a,t[2]=i*e+h*a,t[3]=c*e+M*a,t[4]=f*e-u*a,t[5]=s*e-o*a,t[6]=h*e-i*a,t[7]=M*e-c*a,t},e.fromTranslation=function(t,n){return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=n[0],t[13]=n[1],t[14]=n[2],t[15]=1,t},e.fromScaling=function(t,n){return t[0]=n[0],t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=n[1],t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=n[2],t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotation=function(t,n,r){var e,u,o,i=r[0],c=r[1],f=r[2],s=Math.sqrt(i*i+c*c+f*f);return Math.abs(s)<a.EPSILON?null:(s=1/s,i*=s,c*=s,f*=s,e=Math.sin(n),u=Math.cos(n),o=1-u,t[0]=i*i*o+u,t[1]=c*i*o+f*e,t[2]=f*i*o-c*e,t[3]=0,t[4]=i*c*o-f*e,t[5]=c*c*o+u,t[6]=f*c*o+i*e,t[7]=0,t[8]=i*f*o+c*e,t[9]=c*f*o-i*e,t[10]=f*f*o+u,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t)},e.fromXRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=a,t[6]=r,t[7]=0,t[8]=0,t[9]=-r,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromYRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=0,t[2]=-r,t[3]=0,t[4]=0,t[5]=1,t[6]=0,t[7]=0,t[8]=r,t[9]=0,t[10]=a,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromZRotation=function(t,n){var r=Math.sin(n),a=Math.cos(n);return t[0]=a,t[1]=r,t[2]=0,t[3]=0,t[4]=-r,t[5]=a,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=1,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.fromRotationTranslation=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=a+a,c=e+e,f=u+u,s=a*i,h=a*c,M=a*f,l=e*c,v=e*f,m=u*f,p=o*i,d=o*c,A=o*f;return t[0]=1-(l+m),t[1]=h+A,t[2]=M-d,t[3]=0,t[4]=h-A,t[5]=1-(s+m),t[6]=v+p,t[7]=0,t[8]=M+d,t[9]=v-p,t[10]=1-(s+l),t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScale=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3],c=e+e,f=u+u,s=o+o,h=e*c,M=e*f,l=e*s,v=u*f,m=u*s,p=o*s,d=i*c,A=i*f,R=i*s,w=a[0],q=a[1],Y=a[2];return t[0]=(1-(v+p))*w,t[1]=(M+R)*w,t[2]=(l-A)*w,t[3]=0,t[4]=(M-R)*q,t[5]=(1-(h+p))*q,t[6]=(m+d)*q,t[7]=0,t[8]=(l+A)*Y,t[9]=(m-d)*Y,t[10]=(1-(h+v))*Y,t[11]=0,t[12]=r[0],t[13]=r[1],t[14]=r[2],t[15]=1,t},e.fromRotationTranslationScaleOrigin=function(t,n,r,a,e){var u=n[0],o=n[1],i=n[2],c=n[3],f=u+u,s=o+o,h=i+i,M=u*f,l=u*s,v=u*h,m=o*s,p=o*h,d=i*h,A=c*f,R=c*s,w=c*h,q=a[0],Y=a[1],g=a[2],y=e[0],x=e[1],P=e[2];return t[0]=(1-(m+d))*q,t[1]=(l+w)*q,t[2]=(v-R)*q,t[3]=0,t[4]=(l-w)*Y,t[5]=(1-(M+d))*Y,t[6]=(p+A)*Y,t[7]=0,t[8]=(v+R)*g,t[9]=(p-A)*g,t[10]=(1-(M+m))*g,t[11]=0,t[12]=r[0]+y-(t[0]*y+t[4]*x+t[8]*P),t[13]=r[1]+x-(t[1]*y+t[5]*x+t[9]*P),t[14]=r[2]+P-(t[2]*y+t[6]*x+t[10]*P),t[15]=1,t},e.fromQuat=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r+r,i=a+a,c=e+e,f=r*o,s=a*o,h=a*i,M=e*o,l=e*i,v=e*c,m=u*o,p=u*i,d=u*c;return t[0]=1-h-v,t[1]=s+d,t[2]=M-p,t[3]=0,t[4]=s-d,t[5]=1-f-v,t[6]=l+m,t[7]=0,t[8]=M+p,t[9]=l-m,t[10]=1-f-h,t[11]=0,t[12]=0,t[13]=0,t[14]=0,t[15]=1,t},e.frustum=function(t,n,r,a,e,u,o){var i=1/(r-n),c=1/(e-a),f=1/(u-o);return t[0]=2*u*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=2*u*c,t[6]=0,t[7]=0,t[8]=(r+n)*i,t[9]=(e+a)*c,t[10]=(o+u)*f,t[11]=-1,t[12]=0,t[13]=0,t[14]=o*u*2*f,t[15]=0,t},e.perspective=function(t,n,r,a,e){var u=1/Math.tan(n/2),o=1/(a-e);return t[0]=u/r,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=u,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=(e+a)*o,t[11]=-1,t[12]=0,t[13]=0,t[14]=2*e*a*o,t[15]=0,t},e.perspectiveFromFieldOfView=function(t,n,r,a){var e=Math.tan(n.upDegrees*Math.PI/180),u=Math.tan(n.downDegrees*Math.PI/180),o=Math.tan(n.leftDegrees*Math.PI/180),i=Math.tan(n.rightDegrees*Math.PI/180),c=2/(o+i),f=2/(e+u);return t[0]=c,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=f,t[6]=0,t[7]=0,t[8]=-((o-i)*c*.5),t[9]=(e-u)*f*.5,t[10]=a/(r-a),t[11]=-1,t[12]=0,t[13]=0,t[14]=a*r/(r-a),t[15]=0,t},e.ortho=function(t,n,r,a,e,u,o){var i=1/(n-r),c=1/(a-e),f=1/(u-o);return t[0]=-2*i,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=-2*c,t[6]=0,t[7]=0,t[8]=0,t[9]=0,t[10]=2*f,t[11]=0,t[12]=(n+r)*i,t[13]=(e+a)*c,t[14]=(o+u)*f,t[15]=1,t},e.lookAt=function(t,n,r,u){var o,i,c,f,s,h,M,l,v,m,p=n[0],d=n[1],A=n[2],R=u[0],w=u[1],q=u[2],Y=r[0],g=r[1],y=r[2];return Math.abs(p-Y)<a.EPSILON&&Math.abs(d-g)<a.EPSILON&&Math.abs(A-y)<a.EPSILON?e.identity(t):(M=p-Y,l=d-g,v=A-y,m=1/Math.sqrt(M*M+l*l+v*v),M*=m,l*=m,v*=m,o=w*v-q*l,i=q*M-R*v,c=R*l-w*M,m=Math.sqrt(o*o+i*i+c*c),m?(m=1/m,o*=m,i*=m,c*=m):(o=0,i=0,c=0),f=l*c-v*i,s=v*o-M*c,h=M*i-l*o,m=Math.sqrt(f*f+s*s+h*h),m?(m=1/m,f*=m,s*=m,h*=m):(f=0,s=0,h=0),t[0]=o,t[1]=f,t[2]=M,t[3]=0,t[4]=i,t[5]=s,t[6]=l,t[7]=0,t[8]=c,t[9]=h,t[10]=v,t[11]=0,t[12]=-(o*p+i*d+c*A),t[13]=-(f*p+s*d+h*A),t[14]=-(M*p+l*d+v*A),t[15]=1,t)},e.str=function(t){return"mat4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+", "+t[4]+", "+t[5]+", "+t[6]+", "+t[7]+", "+t[8]+", "+t[9]+", "+t[10]+", "+t[11]+", "+t[12]+", "+t[13]+", "+t[14]+", "+t[15]+")"},e.frob=function(t){return Math.sqrt(Math.pow(t[0],2)+Math.pow(t[1],2)+Math.pow(t[2],2)+Math.pow(t[3],2)+Math.pow(t[4],2)+Math.pow(t[5],2)+Math.pow(t[6],2)+Math.pow(t[7],2)+Math.pow(t[8],2)+Math.pow(t[9],2)+Math.pow(t[10],2)+Math.pow(t[11],2)+Math.pow(t[12],2)+Math.pow(t[13],2)+Math.pow(t[14],2)+Math.pow(t[15],2))},t.exports=e},function(t,n,r){var a=r(1),e=r(4),u=r(7),o=r(8),i={};i.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.rotationTo=function(){var t=u.create(),n=u.fromValues(1,0,0),r=u.fromValues(0,1,0);return function(a,e,o){var c=u.dot(e,o);return-.999999>c?(u.cross(t,n,e),u.length(t)<1e-6&&u.cross(t,r,e),u.normalize(t,t),i.setAxisAngle(a,t,Math.PI),a):c>.999999?(a[0]=0,a[1]=0,a[2]=0,a[3]=1,a):(u.cross(t,e,o),a[0]=t[0],a[1]=t[1],a[2]=t[2],a[3]=1+c,i.normalize(a,a))}}(),i.setAxes=function(){var t=e.create();return function(n,r,a,e){return t[0]=a[0],t[3]=a[1],t[6]=a[2],t[1]=e[0],t[4]=e[1],t[7]=e[2],t[2]=-r[0],t[5]=-r[1],t[8]=-r[2],i.normalize(n,i.fromMat3(n,t))}}(),i.clone=o.clone,i.fromValues=o.fromValues,i.copy=o.copy,i.set=o.set,i.identity=function(t){return t[0]=0,t[1]=0,t[2]=0,t[3]=1,t},i.setAxisAngle=function(t,n,r){r=.5*r;var a=Math.sin(r);return t[0]=a*n[0],t[1]=a*n[1],t[2]=a*n[2],t[3]=Math.cos(r),t},i.add=o.add,i.multiply=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3],i=r[0],c=r[1],f=r[2],s=r[3];return t[0]=a*s+o*i+e*f-u*c,t[1]=e*s+o*c+u*i-a*f,t[2]=u*s+o*f+a*c-e*i,t[3]=o*s-a*i-e*c-u*f,t},i.mul=i.multiply,i.scale=o.scale,i.rotateX=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+o*i,t[1]=e*c+u*i,t[2]=u*c-e*i,t[3]=o*c-a*i,t},i.rotateY=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c-u*i,t[1]=e*c+o*i,t[2]=u*c+a*i,t[3]=o*c-e*i,t},i.rotateZ=function(t,n,r){r*=.5;var a=n[0],e=n[1],u=n[2],o=n[3],i=Math.sin(r),c=Math.cos(r);return t[0]=a*c+e*i,t[1]=e*c-a*i,t[2]=u*c+o*i,t[3]=o*c-u*i,t},i.calculateW=function(t,n){var r=n[0],a=n[1],e=n[2];return t[0]=r,t[1]=a,t[2]=e,t[3]=Math.sqrt(Math.abs(1-r*r-a*a-e*e)),t},i.dot=o.dot,i.lerp=o.lerp,i.slerp=function(t,n,r,a){var e,u,o,i,c,f=n[0],s=n[1],h=n[2],M=n[3],l=r[0],v=r[1],m=r[2],p=r[3];return u=f*l+s*v+h*m+M*p,0>u&&(u=-u,l=-l,v=-v,m=-m,p=-p),1-u>1e-6?(e=Math.acos(u),o=Math.sin(e),i=Math.sin((1-a)*e)/o,c=Math.sin(a*e)/o):(i=1-a,c=a),t[0]=i*f+c*l,t[1]=i*s+c*v,t[2]=i*h+c*m,t[3]=i*M+c*p,t},i.sqlerp=function(){var t=i.create(),n=i.create();return function(r,a,e,u,o,c){return i.slerp(t,a,o,c),i.slerp(n,e,u,c),i.slerp(r,t,n,2*c*(1-c)),r}}(),i.invert=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u,i=o?1/o:0;return t[0]=-r*i,t[1]=-a*i,t[2]=-e*i,t[3]=u*i,t},i.conjugate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=n[3],t},i.length=o.length,i.len=i.length,i.squaredLength=o.squaredLength,i.sqrLen=i.squaredLength,i.normalize=o.normalize,i.fromMat3=function(t,n){var r,a=n[0]+n[4]+n[8];if(a>0)r=Math.sqrt(a+1),t[3]=.5*r,r=.5/r,t[0]=(n[5]-n[7])*r,t[1]=(n[6]-n[2])*r,t[2]=(n[1]-n[3])*r;else{var e=0;n[4]>n[0]&&(e=1),n[8]>n[3*e+e]&&(e=2);var u=(e+1)%3,o=(e+2)%3;r=Math.sqrt(n[3*e+e]-n[3*u+u]-n[3*o+o]+1),t[e]=.5*r,r=.5/r,t[3]=(n[3*u+o]-n[3*o+u])*r,t[u]=(n[3*u+e]+n[3*e+u])*r,t[o]=(n[3*o+e]+n[3*e+o])*r}return t},i.str=function(t){return"quat("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=i},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(3);return t[0]=0,t[1]=0,t[2]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(3);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n},e.fromValues=function(t,n,r){var e=new a.ARRAY_TYPE(3);return e[0]=t,e[1]=n,e[2]=r,e},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t},e.set=function(t,n,r,a){return t[0]=n,t[1]=r,t[2]=a,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return Math.sqrt(r*r+a*a+e*e)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2];return r*r+a*a+e*e},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2];return Math.sqrt(n*n+r*r+a*a)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2];return n*n+r*r+a*a},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=r*r+a*a+e*e;return u>0&&(u=1/Math.sqrt(u),t[0]=n[0]*u,t[1]=n[1]*u,t[2]=n[2]*u),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]},e.cross=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2];return t[0]=e*c-u*i,t[1]=u*o-a*c,t[2]=a*i-e*o,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t},e.hermite=function(t,n,r,a,e,u){var o=u*u,i=o*(2*u-3)+1,c=o*(u-2)+u,f=o*(u-1),s=o*(3-2*u);return t[0]=n[0]*i+r[0]*c+a[0]*f+e[0]*s,t[1]=n[1]*i+r[1]*c+a[1]*f+e[1]*s,t[2]=n[2]*i+r[2]*c+a[2]*f+e[2]*s,t},e.bezier=function(t,n,r,a,e,u){var o=1-u,i=o*o,c=u*u,f=i*o,s=3*u*i,h=3*c*o,M=c*u;return t[0]=n[0]*f+r[0]*s+a[0]*h+e[0]*M,t[1]=n[1]*f+r[1]*s+a[1]*h+e[1]*M,t[2]=n[2]*f+r[2]*s+a[2]*h+e[2]*M,t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI,e=2*a.RANDOM()-1,u=Math.sqrt(1-e*e)*n;return t[0]=Math.cos(r)*u,t[1]=Math.sin(r)*u,t[2]=e*n,t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[3]*a+r[7]*e+r[11]*u+r[15];return o=o||1,t[0]=(r[0]*a+r[4]*e+r[8]*u+r[12])/o,t[1]=(r[1]*a+r[5]*e+r[9]*u+r[13])/o,t[2]=(r[2]*a+r[6]*e+r[10]*u+r[14])/o,t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1],u=n[2];return t[0]=a*r[0]+e*r[3]+u*r[6],t[1]=a*r[1]+e*r[4]+u*r[7],t[2]=a*r[2]+e*r[5]+u*r[8],t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t},e.rotateX=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0],u[1]=e[1]*Math.cos(a)-e[2]*Math.sin(a),u[2]=e[1]*Math.sin(a)+e[2]*Math.cos(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateY=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[2]*Math.sin(a)+e[0]*Math.cos(a),u[1]=e[1],u[2]=e[2]*Math.cos(a)-e[0]*Math.sin(a),t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.rotateZ=function(t,n,r,a){var e=[],u=[];return e[0]=n[0]-r[0],e[1]=n[1]-r[1],e[2]=n[2]-r[2],u[0]=e[0]*Math.cos(a)-e[1]*Math.sin(a),u[1]=e[0]*Math.sin(a)+e[1]*Math.cos(a),u[2]=e[2],t[0]=u[0]+r[0],t[1]=u[1]+r[1],t[2]=u[2]+r[2],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=3),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2];return n}}(),e.angle=function(t,n){var r=e.fromValues(t[0],t[1],t[2]),a=e.fromValues(n[0],n[1],n[2]);e.normalize(r,r),e.normalize(a,a);var u=e.dot(r,a);return u>1?0:Math.acos(u)},e.str=function(t){return"vec3("+t[0]+", "+t[1]+", "+t[2]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(4);return t[0]=0,t[1]=0,t[2]=0,t[3]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(4);return n[0]=t[0],n[1]=t[1],n[2]=t[2],n[3]=t[3],n},e.fromValues=function(t,n,r,e){var u=new a.ARRAY_TYPE(4);return u[0]=t,u[1]=n,u[2]=r,u[3]=e,u},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t[2]=n[2],t[3]=n[3],t},e.set=function(t,n,r,a,e){return t[0]=n,t[1]=r,t[2]=a,t[3]=e,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t[2]=n[2]+r[2],t[3]=n[3]+r[3],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t[2]=n[2]-r[2],t[3]=n[3]-r[3],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t[2]=n[2]*r[2],t[3]=n[3]*r[3],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t[2]=n[2]/r[2],t[3]=n[3]/r[3],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t[2]=Math.min(n[2],r[2]),t[3]=Math.min(n[3],r[3]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t[2]=Math.max(n[2],r[2]),t[3]=Math.max(n[3],r[3]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t[2]=n[2]*r,t[3]=n[3]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t[2]=n[2]+r[2]*a,t[3]=n[3]+r[3]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return Math.sqrt(r*r+a*a+e*e+u*u)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1],e=n[2]-t[2],u=n[3]-t[3];return r*r+a*a+e*e+u*u},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return Math.sqrt(n*n+r*r+a*a+e*e)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1],a=t[2],e=t[3];return n*n+r*r+a*a+e*e},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t[2]=-n[2],t[3]=-n[3],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t[2]=1/n[2],t[3]=1/n[3],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=n[2],u=n[3],o=r*r+a*a+e*e+u*u;return o>0&&(o=1/Math.sqrt(o),t[0]=r*o,t[1]=a*o,t[2]=e*o,t[3]=u*o),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]+t[2]*n[2]+t[3]*n[3]},e.lerp=function(t,n,r,a){var e=n[0],u=n[1],o=n[2],i=n[3];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t[2]=o+a*(r[2]-o),t[3]=i+a*(r[3]-i),t},e.random=function(t,n){return n=n||1,t[0]=a.RANDOM(),t[1]=a.RANDOM(),t[2]=a.RANDOM(),t[3]=a.RANDOM(),e.normalize(t,t),e.scale(t,t,n),t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=n[3];return t[0]=r[0]*a+r[4]*e+r[8]*u+r[12]*o,t[1]=r[1]*a+r[5]*e+r[9]*u+r[13]*o,t[2]=r[2]*a+r[6]*e+r[10]*u+r[14]*o,t[3]=r[3]*a+r[7]*e+r[11]*u+r[15]*o,t},e.transformQuat=function(t,n,r){var a=n[0],e=n[1],u=n[2],o=r[0],i=r[1],c=r[2],f=r[3],s=f*a+i*u-c*e,h=f*e+c*a-o*u,M=f*u+o*e-i*a,l=-o*a-i*e-c*u;return t[0]=s*f+l*-o+h*-c-M*-i,t[1]=h*f+l*-i+M*-o-s*-c,t[2]=M*f+l*-c+s*-i-h*-o,t[3]=n[3],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=4),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],t[2]=n[i+2],t[3]=n[i+3],u(t,t,o),n[i]=t[0],n[i+1]=t[1],n[i+2]=t[2],n[i+3]=t[3];return n}}(),e.str=function(t){return"vec4("+t[0]+", "+t[1]+", "+t[2]+", "+t[3]+")"},t.exports=e},function(t,n,r){var a=r(1),e={};e.create=function(){var t=new a.ARRAY_TYPE(2);return t[0]=0,t[1]=0,t},e.clone=function(t){var n=new a.ARRAY_TYPE(2);return n[0]=t[0],n[1]=t[1],n},e.fromValues=function(t,n){var r=new a.ARRAY_TYPE(2);return r[0]=t,r[1]=n,r},e.copy=function(t,n){return t[0]=n[0],t[1]=n[1],t},e.set=function(t,n,r){return t[0]=n,t[1]=r,t},e.add=function(t,n,r){return t[0]=n[0]+r[0],t[1]=n[1]+r[1],t},e.subtract=function(t,n,r){return t[0]=n[0]-r[0],t[1]=n[1]-r[1],t},e.sub=e.subtract,e.multiply=function(t,n,r){return t[0]=n[0]*r[0],t[1]=n[1]*r[1],t},e.mul=e.multiply,e.divide=function(t,n,r){return t[0]=n[0]/r[0],t[1]=n[1]/r[1],t},e.div=e.divide,e.min=function(t,n,r){return t[0]=Math.min(n[0],r[0]),t[1]=Math.min(n[1],r[1]),t},e.max=function(t,n,r){return t[0]=Math.max(n[0],r[0]),t[1]=Math.max(n[1],r[1]),t},e.scale=function(t,n,r){return t[0]=n[0]*r,t[1]=n[1]*r,t},e.scaleAndAdd=function(t,n,r,a){return t[0]=n[0]+r[0]*a,t[1]=n[1]+r[1]*a,t},e.distance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return Math.sqrt(r*r+a*a)},e.dist=e.distance,e.squaredDistance=function(t,n){var r=n[0]-t[0],a=n[1]-t[1];return r*r+a*a},e.sqrDist=e.squaredDistance,e.length=function(t){var n=t[0],r=t[1];return Math.sqrt(n*n+r*r)},e.len=e.length,e.squaredLength=function(t){var n=t[0],r=t[1];return n*n+r*r},e.sqrLen=e.squaredLength,e.negate=function(t,n){return t[0]=-n[0],t[1]=-n[1],t},e.inverse=function(t,n){return t[0]=1/n[0],t[1]=1/n[1],t},e.normalize=function(t,n){var r=n[0],a=n[1],e=r*r+a*a;return e>0&&(e=1/Math.sqrt(e),t[0]=n[0]*e,t[1]=n[1]*e),t},e.dot=function(t,n){return t[0]*n[0]+t[1]*n[1]},e.cross=function(t,n,r){var a=n[0]*r[1]-n[1]*r[0];return t[0]=t[1]=0,t[2]=a,t},e.lerp=function(t,n,r,a){var e=n[0],u=n[1];return t[0]=e+a*(r[0]-e),t[1]=u+a*(r[1]-u),t},e.random=function(t,n){n=n||1;var r=2*a.RANDOM()*Math.PI;return t[0]=Math.cos(r)*n,t[1]=Math.sin(r)*n,t},e.transformMat2=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e,t[1]=r[1]*a+r[3]*e,t},e.transformMat2d=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[2]*e+r[4],t[1]=r[1]*a+r[3]*e+r[5],t},e.transformMat3=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[3]*e+r[6],t[1]=r[1]*a+r[4]*e+r[7],t},e.transformMat4=function(t,n,r){var a=n[0],e=n[1];return t[0]=r[0]*a+r[4]*e+r[12],t[1]=r[1]*a+r[5]*e+r[13],t},e.forEach=function(){var t=e.create();return function(n,r,a,e,u,o){var i,c;for(r||(r=2),a||(a=0),c=e?Math.min(e*r+a,n.length):n.length,i=a;c>i;i+=r)t[0]=n[i],t[1]=n[i+1],u(t,t,o),n[i]=t[0],n[i+1]=t[1];return n}}(),e.str=function(t){return"vec2("+t[0]+", "+t[1]+")"},t.exports=e}])});'use strict';(function(global){if(tr.isNode){const glMatrixAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/gl-matrix-min.js');const glMatrixModule=require(glMatrixAbsPath);for(const exportName in glMatrixModule){global[exportName]=glMatrixModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){const PREFERRED_NUMBER_SERIES_MULTIPLIERS=[1,2,5,10];function approximately(x,y,delta){if(delta===undefined)delta=1e-9;return Math.abs(x-y)<delta;}
 function clamp(x,lo,hi){return Math.min(Math.max(x,lo),hi);}
-function lerp(percentage,lo,hi){var range=hi-lo;return lo+percentage*range;}
+function lerp(percentage,lo,hi){const range=hi-lo;return lo+percentage*range;}
 function normalize(value,lo,hi){return(value-lo)/(hi-lo);}
 function deg2rad(deg){return(Math.PI*deg)/180.0;}
-function erf(x){var sign=(x>=0)?1:-1;x=Math.abs(x);var a1=0.254829592;var a2=-0.284496736;var a3=1.421413741;var a4=-1.453152027;var a5=1.061405429;var p=0.3275911;var t=1.0/(1.0+p*x);var y=1.0-(((((a5*t+a4)*t)+a3)*t+a2)*t+a1)*t*Math.exp(-x*x);return sign*y;}
-var tmpVec2=vec2.create();var tmpVec2b=vec2.create();var tmpVec4=vec4.create();var tmpMat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!==2)throw new Error('Should be length 2');var v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){var v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmpVec2,u1,scale1);vec2.scale(tmpVec2b,u2,scale2);vec2.add(out,tmpVec2,tmpVec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])return points[0][1];for(var i=1;i<points.length;++i){if(x<points[i][0]){var percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
-return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){var v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.translate(out,out,tmpVec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.scale(out,out,tmpVec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmpVec4,a);vec2.copy(out,tmpVec4);};function logOrLog10(x,base){if(base===10)return Math.log10(x);return Math.log(x)/Math.log(base);}
-function lesserPower(x,opt_base){var base=opt_base||10;return Math.pow(base,Math.floor(logOrLog10(x,base)));}
-function greaterPower(x,opt_base){var base=opt_base||10;return Math.pow(base,Math.ceil(logOrLog10(x,base)));}
+function erf(x){const sign=(x>=0)?1:-1;x=Math.abs(x);const a1=0.254829592;const a2=-0.284496736;const a3=1.421413741;const a4=-1.453152027;const a5=1.061405429;const p=0.3275911;const t=1.0/(1.0+p*x);const y=1.0-(((((a5*t+a4)*t)+a3)*t+a2)*t+a1)*t*Math.exp(-x*x);return sign*y;}
+const tmpVec2=vec2.create();const tmpVec2b=vec2.create();const tmpVec4=vec4.create();const tmpMat2d=mat2d.create();vec2.createFromArray=function(arr){if(arr.length!==2)throw new Error('Should be length 2');const v=vec2.create();vec2.set(v,arr[0],arr[1]);return v;};vec2.createXY=function(x,y){const v=vec2.create();vec2.set(v,x,y);return v;};vec2.toString=function(a){return'['+a[0]+', '+a[1]+']';};vec2.addTwoScaledUnitVectors=function(out,u1,scale1,u2,scale2){vec2.scale(tmpVec2,u1,scale1);vec2.scale(tmpVec2b,u2,scale2);vec2.add(out,tmpVec2,tmpVec2b);};vec2.interpolatePiecewiseFunction=function(points,x){if(x<points[0][0])return points[0][1];for(let i=1;i<points.length;++i){if(x<points[i][0]){const percent=normalize(x,points[i-1][0],points[i][0]);return lerp(percent,points[i-1][1],points[i][1]);}}
+return points[points.length-1][1];};vec3.createXYZ=function(x,y,z){const v=vec3.create();vec3.set(v,x,y,z);return v;};vec3.toString=function(a){return'vec3('+a[0]+', '+a[1]+', '+a[2]+')';};mat2d.translateXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.translate(out,out,tmpVec2);};mat2d.scaleXY=function(out,x,y){vec2.set(tmpVec2,x,y);mat2d.scale(out,out,tmpVec2);};vec4.unitize=function(out,a){out[0]=a[0]/a[3];out[1]=a[1]/a[3];out[2]=a[2]/a[3];out[3]=1;return out;};vec2.copyFromVec4=function(out,a){vec4.unitize(tmpVec4,a);vec2.copy(out,tmpVec4);};function logOrLog10(x,base){if(base===10)return Math.log10(x);return Math.log(x)/Math.log(base);}
+function lesserPower(x,opt_base){const base=opt_base||10;return Math.pow(base,Math.floor(logOrLog10(x,base)));}
+function greaterPower(x,opt_base){const base=opt_base||10;return Math.pow(base,Math.ceil(logOrLog10(x,base)));}
 function lesserWholeNumber(x){if(x===0)return 0;const pow10=(x<0)?-lesserPower(-x):lesserPower(x);return pow10*Math.floor(x/pow10);}
 function greaterWholeNumber(x){if(x===0)return 0;const pow10=(x<0)?-lesserPower(-x):lesserPower(x);return pow10*Math.ceil(x/pow10);}
-function preferredNumberLargerThanMin(min){var absMin=Math.abs(min);var conservativeGuess=tr.b.math.lesserPower(absMin);var minPreferedNumber=undefined;for(var multiplier of PREFERRED_NUMBER_SERIES_MULTIPLIERS){var tightenedGuess=conservativeGuess*multiplier;if(tightenedGuess>=absMin){minPreferedNumber=tightenedGuess;break;}}
+function preferredNumberLargerThanMin(min){const absMin=Math.abs(min);const conservativeGuess=tr.b.math.lesserPower(absMin);let minPreferedNumber=undefined;for(const multiplier of PREFERRED_NUMBER_SERIES_MULTIPLIERS){const tightenedGuess=conservativeGuess*multiplier;if(tightenedGuess>=absMin){minPreferedNumber=tightenedGuess;break;}}
 if(minPreferedNumber===undefined){throw new Error('Could not compute preferred number for '+min);}
 if(min<0)minPreferedNumber*=-1;return minPreferedNumber;}
 return{approximately,clamp,lerp,normalize,deg2rad,erf,lesserPower,greaterPower,lesserWholeNumber,greaterWholeNumber,preferredNumberLargerThanMin,};});'use strict';tr.exportTo('tr.b.math',function(){function Range(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
-Range.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange:function(range){if(range.isEmpty)return;this.addValue(range.min);this.addValue(range.max);},addValue:function(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
-this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)return undefined;return this.min_;},get max(){if(this.isEmpty_)return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)return 0;return this.max_-this.min_;},enclosingPowers(opt_base){if(this.isEmpty)return new Range();return Range.fromExplicitRange(tr.b.math.lesserPower(this.min_,opt_base),tr.b.math.greaterPower(this.max_,opt_base));},normalize:function(x){return tr.b.math.normalize(x,this.min,this.max);},lerp:function(x){return tr.b.math.lerp(x,this.min,this.max);},clamp:function(x){return tr.b.math.clamp(x,this.min,this.max);},equals:function(that){if(this.isEmpty&&that.isEmpty)return true;if(this.isEmpty!==that.isEmpty)return false;return(tr.b.math.approximately(this.min,that.min)&&tr.b.math.approximately(this.max,that.max));},containsExplicitRangeInclusive:function(min,max){if(this.isEmpty)return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive:function(min,max){if(this.isEmpty)return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive:function(min,max){if(this.isEmpty)return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive:function(min,max){if(this.isEmpty)return false;return this.min_<max&&min<this.max_;},containsRangeInclusive:function(range){if(range.isEmpty)return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive:function(range){if(range.isEmpty)return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive:function(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive:function(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findExplicitIntersectionDuration:function(min,max){var min=Math.max(this.min,min);var max=Math.min(this.max,max);if(max<min)return 0;return max-min;},findIntersection:function(range){if(this.isEmpty||range.isEmpty)return new Range();var min=Math.max(this.min,range.min);var max=Math.min(this.max,range.max);if(max<min)return new Range();return Range.fromExplicitRange(min,max);},toJSON:function(){if(this.isEmpty_)return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray:function(array,opt_keyFunc,opt_this){if(this.isEmpty_)return[];function binSearch(test){var i0=0;var i1=array.length;while(i0<i1){var i=Math.trunc((i0+i1)/2);if(test(i)){i1=i;}else{i0=i+1;}}
+Range.prototype={__proto__:Object.prototype,clone(){if(this.isEmpty)return new Range();return Range.fromExplicitRange(this.min_,this.max_);},reset(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addRange(range){if(range.isEmpty)return;this.addValue(range.min);this.addValue(range.max);},addValue(value){if(this.isEmpty_){this.max_=value;this.min_=value;this.isEmpty_=false;return;}
+this.max_=Math.max(this.max_,value);this.min_=Math.min(this.min_,value);},set min(min){this.isEmpty_=false;this.min_=min;},get min(){if(this.isEmpty_)return undefined;return this.min_;},get max(){if(this.isEmpty_)return undefined;return this.max_;},set max(max){this.isEmpty_=false;this.max_=max;},get range(){if(this.isEmpty_)return undefined;return this.max_-this.min_;},get center(){return(this.min_+this.max_)*0.5;},get duration(){if(this.isEmpty_)return 0;return this.max_-this.min_;},enclosingPowers(opt_base){if(this.isEmpty)return new Range();return Range.fromExplicitRange(tr.b.math.lesserPower(this.min_,opt_base),tr.b.math.greaterPower(this.max_,opt_base));},normalize(x){return tr.b.math.normalize(x,this.min,this.max);},lerp(x){return tr.b.math.lerp(x,this.min,this.max);},clamp(x){return tr.b.math.clamp(x,this.min,this.max);},equals(that){if(this.isEmpty&&that.isEmpty)return true;if(this.isEmpty!==that.isEmpty)return false;return(tr.b.math.approximately(this.min,that.min)&&tr.b.math.approximately(this.max,that.max));},containsExplicitRangeInclusive(min,max){if(this.isEmpty)return false;return this.min_<=min&&max<=this.max_;},containsExplicitRangeExclusive(min,max){if(this.isEmpty)return false;return this.min_<min&&max<this.max_;},intersectsExplicitRangeInclusive(min,max){if(this.isEmpty)return false;return this.min_<=max&&min<=this.max_;},intersectsExplicitRangeExclusive(min,max){if(this.isEmpty)return false;return this.min_<max&&min<this.max_;},containsRangeInclusive(range){if(range.isEmpty)return false;return this.containsExplicitRangeInclusive(range.min_,range.max_);},containsRangeExclusive(range){if(range.isEmpty)return false;return this.containsExplicitRangeExclusive(range.min_,range.max_);},intersectsRangeInclusive(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeInclusive(range.min_,range.max_);},intersectsRangeExclusive(range){if(range.isEmpty)return false;return this.intersectsExplicitRangeExclusive(range.min_,range.max_);},findExplicitIntersectionDuration(min,max){min=Math.max(this.min,min);max=Math.min(this.max,max);if(max<min)return 0;return max-min;},findIntersection(range){if(this.isEmpty||range.isEmpty)return new Range();const min=Math.max(this.min,range.min);const max=Math.min(this.max,range.max);if(max<min)return new Range();return Range.fromExplicitRange(min,max);},toJSON(){if(this.isEmpty_)return{isEmpty:true};return{isEmpty:false,max:this.max,min:this.min};},filterArray(array,opt_keyFunc,opt_this){if(this.isEmpty_)return[];function binSearch(test){let i0=0;let i1=array.length;while(i0<i1){const i=Math.trunc((i0+i1)/2);if(test(i)){i1=i;}else{i0=i+1;}}
 return i1;}
-var keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
-var first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));var last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true)return new Range();if(d.isEmpty===false){var range=new Range();range.min=d.min;range.max=d.max;return range;}
-throw new Error('Not a range');};Range.fromExplicitRange=function(min,max){var range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)return-1;if(!a.isEmpty&&b.isEmpty)return 1;return 0;};Range.PERCENT_RANGE=Range.fromExplicitRange(0,1);Object.freeze(Range.PERCENT_RANGE);return{Range,};});'use strict';(function(exports){var rank={standard:function(array,key){array=array.sort(function(a,b){var x=a[key];var y=b[key];return((x<y)?-1:((x>y)?1:0));});for(var i=1;i<array.length+1;i++){array[i-1]['rank']=i;}
+const keyFunc=opt_keyFunc||tr.b.identity;function getValue(index){return keyFunc.call(opt_this,array[index]);}
+const first=binSearch(function(i){return this.min_===undefined||this.min_<=getValue(i);}.bind(this));const last=binSearch(function(i){return this.max_!==undefined&&this.max_<getValue(i);}.bind(this));return array.slice(first,last);}};Range.fromDict=function(d){if(d.isEmpty===true)return new Range();if(d.isEmpty===false){const range=new Range();range.min=d.min;range.max=d.max;return range;}
+throw new Error('Not a range');};Range.fromExplicitRange=function(min,max){const range=new Range();range.min=min;range.max=max;return range;};Range.compareByMinTimes=function(a,b){if(!a.isEmpty&&!b.isEmpty)return a.min_-b.min_;if(a.isEmpty&&!b.isEmpty)return-1;if(!a.isEmpty&&b.isEmpty)return 1;return 0;};Range.findDifference=function(rangeA,rangeB){if(!rangeA||rangeA.duration<0||!rangeB||rangeB.duration<0){throw new Error(`Couldn't subtract ranges`);}
+const resultRanges=[];if(rangeA.isEmpty)return resultRanges;if(rangeB.isEmpty)return[rangeA.clone()];const intersection=rangeA.findIntersection(rangeB);if(intersection.isEmpty){return[rangeA.clone()];}
+if(rangeA.duration===0&&rangeB.duration===0){if(intersection.empty)return[rangeA.clone()];else if(intersection.duration===0)return resultRanges;throw new Error(`Two points' intersection can only be a point or empty`);}
+const leftRange=tr.b.math.Range.fromExplicitRange(rangeA.min,intersection.min);if(leftRange.duration>0){resultRanges.push(leftRange);}
+const rightRange=tr.b.math.Range.fromExplicitRange(intersection.max,rangeA.max);if(rightRange.duration>0){resultRanges.push(rightRange);}
+return resultRanges;};Range.PERCENT_RANGE=Range.fromExplicitRange(0,1);Object.freeze(Range.PERCENT_RANGE);return{Range,};});'use strict';(function(exports){var rank={standard:function(array,key){array=array.sort(function(a,b){var x=a[key];var y=b[key];return((x<y)?-1:((x>y)?1:0));});for(var i=1;i<array.length+1;i++){array[i-1]['rank']=i;}
 return array;},fractional:function(array,key){array=this.standard(array,key);var pos=0;while(pos<array.length){var sum=0;var i=0;for(i=0;array[pos+i+1]&&(array[pos+i][key]===array[pos+i+1][key]);i++){sum+=array[pos+i]['rank'];}
 sum+=array[pos+i]['rank'];var endPos=pos+i+1;for(pos;pos<endPos;pos++){array[pos]['rank']=sum/(i+1);}
 pos=endPos;}
@@ -4256,152 +4338,153 @@
 exports.test=function(x,y,alt,corr){alt=typeof alt!=='undefined'?alt:'two-sided';corr=typeof corr!=='undefined'?corr:true;var nx=x.length,ny=y.length,f=1,u,mu,std,z,p;u=statistic(x,y);if(corr){mu=(nx*ny/2)+0.5;}else{mu=nx*ny/2;}
 std=Math.sqrt(u.tcf*nx*ny*(nx+ny+1)/12);if(alt=='less'){z=(u.ux-mu)/std;}else if(alt=='greater'){z=(u.uy-mu)/std;}else if(alt=='two-sided'){z=Math.abs((u.big-mu)/std);}else{console.log('Unknown alternative argument');}
 if(alt=='two-sided'){f=2;}
-p=dnorm(-z,0,1)*f;return{U:u.small,p:p};}})(typeof exports==='undefined'?this['mannwhitneyu']={}:exports);'use strict';(function(global){if(tr.isNode){var mwuAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/mannwhitneyu.js');var mwuModule=require(mwuAbsPath);for(var exportName in mwuModule){global[exportName]=mwuModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){var identity=x=>x;var Statistics={};Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=0;var i=0;for(var elt of ary){ret+=func.call(opt_this,elt,i++);}
-return ret;};Statistics.mean=function(ary,opt_func,opt_this){var func=opt_func||identity;var sum=0;var i=0;for(var elt of ary){sum+=func.call(opt_this,elt,i++);}
-if(i===0)return undefined;return sum/i;};Statistics.geometricMean=function(ary,opt_func,opt_this){var func=opt_func||identity;var i=0;var logsum=0;for(var elt of ary){var x=func.call(opt_this,elt,i++);if(x<=0)return 0;logsum+=Math.log(Math.abs(x));}
-if(i===0)return 1;return Math.exp(logsum/i);};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){var valueCallback=opt_valueCallback||identity;var numerator=0;var denominator=0;var i=-1;for(var elt of ary){i++;var value=valueCallback.call(opt_this,elt,i);if(value===undefined)continue;var weight=weightCallback.call(opt_this,elt,i,value);numerator+=weight*value;denominator+=weight;}
-if(denominator===0)return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;if(ary.length===1)return 0;var func=opt_func||identity;var mean=Statistics.mean(ary,func,opt_this);var sumOfSquaredDistances=Statistics.sum(ary,function(d,i){var v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=-Infinity;var i=0;for(var elt of ary){ret=Math.max(ret,func.call(opt_this,elt,i++));}
-return ret;};Statistics.min=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=Infinity;var i=0;for(var elt of ary){ret=Math.min(ret,func.call(opt_this,elt,i++));}
-return ret;};Statistics.range=function(ary,opt_func,opt_this){var func=opt_func||identity;var ret=new tr.b.math.Range();var i=0;for(var elt of ary){ret.addValue(func.call(opt_this,elt,i++));}
+p=dnorm(-z,0,1)*f;return{U:u.small,p:p};}})(typeof exports==='undefined'?this['mannwhitneyu']={}:exports);'use strict';(function(global){if(tr.isNode){const mwuAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/mannwhitneyu.js');const mwuModule=require(mwuAbsPath);for(const exportName in mwuModule){global[exportName]=mwuModule[exportName];}}})(this);'use strict';tr.exportTo('tr.b.math',function(){const identity=x=>x;const Statistics={};Statistics.divideIfPossibleOrZero=function(numerator,denominator){if(denominator===0)return 0;return numerator/denominator;};Statistics.sum=function(ary,opt_func,opt_this){const func=opt_func||identity;let ret=0;let i=0;for(const elt of ary){ret+=func.call(opt_this,elt,i++);}
+return ret;};Statistics.mean=function(ary,opt_func,opt_this){const func=opt_func||identity;let sum=0;let i=0;for(const elt of ary){sum+=func.call(opt_this,elt,i++);}
+if(i===0)return undefined;return sum/i;};Statistics.geometricMean=function(ary,opt_func,opt_this){const func=opt_func||identity;let i=0;let logsum=0;for(const elt of ary){const x=func.call(opt_this,elt,i++);if(x<=0)return 0;logsum+=Math.log(Math.abs(x));}
+if(i===0)return 1;return Math.exp(logsum/i);};Statistics.weightedMean=function(ary,weightCallback,opt_valueCallback,opt_this){const valueCallback=opt_valueCallback||identity;let numerator=0;let denominator=0;let i=-1;for(const elt of ary){i++;const value=valueCallback.call(opt_this,elt,i);if(value===undefined)continue;const weight=weightCallback.call(opt_this,elt,i,value);numerator+=weight*value;denominator+=weight;}
+if(denominator===0)return undefined;return numerator/denominator;};Statistics.variance=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;if(ary.length===1)return 0;const func=opt_func||identity;const mean=Statistics.mean(ary,func,opt_this);const sumOfSquaredDistances=Statistics.sum(ary,function(d,i){const v=func.call(this,d,i)-mean;return v*v;},opt_this);return sumOfSquaredDistances/(ary.length-1);};Statistics.stddev=function(ary,opt_func,opt_this){if(ary.length===0)return undefined;return Math.sqrt(Statistics.variance(ary,opt_func,opt_this));};Statistics.max=function(ary,opt_func,opt_this){const func=opt_func||identity;let ret=-Infinity;let i=0;for(const elt of ary){ret=Math.max(ret,func.call(opt_this,elt,i++));}
+return ret;};Statistics.min=function(ary,opt_func,opt_this){const func=opt_func||identity;let ret=Infinity;let i=0;for(const elt of ary){ret=Math.min(ret,func.call(opt_this,elt,i++));}
+return ret;};Statistics.range=function(ary,opt_func,opt_this){const func=opt_func||identity;const ret=new tr.b.math.Range();let i=0;for(const elt of ary){ret.addValue(func.call(opt_this,elt,i++));}
 return ret;};Statistics.percentile=function(ary,percent,opt_func,opt_this){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
-var func=opt_func||identity;var tmp=new Array(ary.length);var i=0;for(var elt of ary){tmp[i]=func.call(opt_this,elt,i++);}
-tmp.sort((a,b)=>a-b);var idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
-samples=samples.slice().sort(function(a,b){return a-b;});var low=Math.min.apply(null,samples);var high=Math.max.apply(null,samples);var newLow=0.5/samples.length;var newHigh=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
-var scale=(newHigh-newLow)/(high-low);for(var i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+newLow;}
-return{normalized_samples:samples,scale:scale};};Statistics.discrepancy=function(samples,opt_locationCount){if(samples.length===0)return 0.0;var maxLocalDiscrepancy=0;var invSampleCount=1.0/samples.length;var locations=[];var countLess=[];var countLessEqual=[];if(opt_locationCount!==undefined){var sampleIndex=0;for(var i=0;i<opt_locationCount;i++){var location=i/(opt_locationCount-1);locations.push(location);while(sampleIndex<samples.length&&samples[sampleIndex]<location){sampleIndex+=1;}
+const func=opt_func||identity;const tmp=new Array(ary.length);let i=0;for(const elt of ary){tmp[i]=func.call(opt_this,elt,i++);}
+tmp.sort((a,b)=>a-b);const idx=Math.floor((ary.length-1)*percent);return tmp[idx];};Statistics.normalizeSamples=function(samples){if(samples.length===0){return{normalized_samples:samples,scale:1.0};}
+samples=samples.slice().sort(function(a,b){return a-b;});const low=Math.min.apply(null,samples);const high=Math.max.apply(null,samples);const newLow=0.5/samples.length;const newHigh=(samples.length-0.5)/samples.length;if(high-low===0.0){samples=Array.apply(null,new Array(samples.length)).map(function(){return 0.5;});return{normalized_samples:samples,scale:1.0};}
+const scale=(newHigh-newLow)/(high-low);for(let i=0;i<samples.length;i++){samples[i]=(samples[i]-low)*scale+newLow;}
+return{normalized_samples:samples,scale};};Statistics.discrepancy=function(samples,opt_locationCount){if(samples.length===0)return 0.0;let maxLocalDiscrepancy=0;const invSampleCount=1.0/samples.length;const locations=[];const countLess=[];const countLessEqual=[];if(opt_locationCount!==undefined){let sampleIndex=0;for(let i=0;i<opt_locationCount;i++){const location=i/(opt_locationCount-1);locations.push(location);while(sampleIndex<samples.length&&samples[sampleIndex]<location){sampleIndex+=1;}
 countLess.push(sampleIndex);while(sampleIndex<samples.length&&samples[sampleIndex]<=location){sampleIndex+=1;}
 countLessEqual.push(sampleIndex);}}else{if(samples[0]>0.0){locations.push(0.0);countLess.push(0);countLessEqual.push(0);}
-for(var i=0;i<samples.length;i++){locations.push(samples[i]);countLess.push(i);countLessEqual.push(i+1);}
+for(let i=0;i<samples.length;i++){locations.push(samples[i]);countLess.push(i);countLessEqual.push(i+1);}
 if(samples[-1]<1.0){locations.push(1.0);countLess.push(samples.length);countLessEqual.push(samples.length);}}
-var maxDiff=0;var minDiff=0;for(var i=1;i<locations.length;i++){var length=locations[i]-locations[i-1];var countClosed=countLessEqual[i]-countLess[i-1];var countOpen=countLess[i]-countLessEqual[i-1];var countClosedIncrement=countLessEqual[i]-countLessEqual[i-1];var countOpenIncrement=countLess[i]-countLess[i-1];maxDiff=Math.max(countClosedIncrement*invSampleCount-length+maxDiff,countClosed*invSampleCount-length);minDiff=Math.min(countOpenIncrement*invSampleCount-length+minDiff,countOpen*invSampleCount-length);maxLocalDiscrepancy=Math.max(maxDiff,-minDiff,maxLocalDiscrepancy);}
-return maxLocalDiscrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_locationCount){if(timestamps.length===0)return 0.0;if(opt_absolute===undefined)opt_absolute=true;if(Array.isArray(timestamps[0])){var rangeDiscrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,rangeDiscrepancies);}
-var s=Statistics.normalizeSamples(timestamps);var samples=s.normalized_samples;var sampleScale=s.scale;var discrepancy=Statistics.discrepancy(samples,opt_locationCount);var invSampleCount=1.0/samples.length;if(opt_absolute===true){discrepancy/=sampleScale;}else{discrepancy=tr.b.math.clamp((discrepancy-invSampleCount)/(1.0-invSampleCount),0.0,1.0);}
-return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_locationCount){if(durations.length===0)return 0.0;var timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_locationCount);};Statistics.uniformlySampleArray=function(samples,count){if(samples.length<=count){return samples;}
-while(samples.length>count){var i=parseInt(Math.random()*samples.length);samples.splice(i,1);}
+let maxDiff=0;let minDiff=0;for(let i=1;i<locations.length;i++){const length=locations[i]-locations[i-1];const countClosed=countLessEqual[i]-countLess[i-1];const countOpen=countLess[i]-countLessEqual[i-1];const countClosedIncrement=countLessEqual[i]-countLessEqual[i-1];const countOpenIncrement=countLess[i]-countLess[i-1];maxDiff=Math.max(countClosedIncrement*invSampleCount-length+maxDiff,countClosed*invSampleCount-length);minDiff=Math.min(countOpenIncrement*invSampleCount-length+minDiff,countOpen*invSampleCount-length);maxLocalDiscrepancy=Math.max(maxDiff,-minDiff,maxLocalDiscrepancy);}
+return maxLocalDiscrepancy;};Statistics.timestampsDiscrepancy=function(timestamps,opt_absolute,opt_locationCount){if(timestamps.length===0)return 0.0;if(opt_absolute===undefined)opt_absolute=true;if(Array.isArray(timestamps[0])){const rangeDiscrepancies=timestamps.map(function(r){return Statistics.timestampsDiscrepancy(r);});return Math.max.apply(null,rangeDiscrepancies);}
+const s=Statistics.normalizeSamples(timestamps);const samples=s.normalized_samples;const sampleScale=s.scale;let discrepancy=Statistics.discrepancy(samples,opt_locationCount);const invSampleCount=1.0/samples.length;if(opt_absolute===true){discrepancy/=sampleScale;}else{discrepancy=tr.b.math.clamp((discrepancy-invSampleCount)/(1.0-invSampleCount),0.0,1.0);}
+return discrepancy;};Statistics.durationsDiscrepancy=function(durations,opt_absolute,opt_locationCount){if(durations.length===0)return 0.0;const timestamps=durations.reduce(function(prev,curr,index,array){prev.push(prev[prev.length-1]+curr);return prev;},[0]);return Statistics.timestampsDiscrepancy(timestamps,opt_absolute,opt_locationCount);};Statistics.uniformlySampleArray=function(samples,count){if(samples.length<=count){return samples;}
+while(samples.length>count){const i=parseInt(Math.random()*samples.length);samples.splice(i,1);}
 return samples;};Statistics.uniformlySampleStream=function(samples,streamLength,newElement,numSamples){if(streamLength<=numSamples){if(samples.length>=streamLength){samples[streamLength-1]=newElement;}else{samples.push(newElement);}
 return;}
-var probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)return;var index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){var nbElements=Math.min(streamLengthB,samplesB.length);for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
+const probToKeep=numSamples/streamLength;if(Math.random()>probToKeep)return;const index=Math.floor(Math.random()*numSamples);samples[index]=newElement;};Statistics.mergeSampledStreams=function(samplesA,streamLengthA,samplesB,streamLengthB,numSamples){if(streamLengthB<numSamples){const nbElements=Math.min(streamLengthB,samplesB.length);for(let i=0;i<nbElements;++i){Statistics.uniformlySampleStream(samplesA,streamLengthA+i+1,samplesB[i],numSamples);}
 return;}
-if(streamLengthA<numSamples){var nbElements=Math.min(streamLengthA,samplesA.length);var tempSamples=samplesB.slice();for(var i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
-for(var i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
+if(streamLengthA<numSamples){const nbElements=Math.min(streamLengthA,samplesA.length);const tempSamples=samplesB.slice();for(let i=0;i<nbElements;++i){Statistics.uniformlySampleStream(tempSamples,streamLengthB+i+1,samplesA[i],numSamples);}
+for(let i=0;i<tempSamples.length;++i){samplesA[i]=tempSamples[i];}
 return;}
-var nbElements=Math.min(numSamples,samplesB.length);var probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(var i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};function Distribution(){}
-Distribution.prototype={computeDensity:function(x){throw Error('Not implemented');},computePercentile:function(x){throw Error('Not implemented');},computeComplementaryPercentile:function(x){return 1-this.computePercentile(x);},get mean(){throw Error('Not implemented');},get mode(){throw Error('Not implemented');},get median(){throw Error('Not implemented');},get standardDeviation(){throw Error('Not implemented');},get variance(){throw Error('Not implemented');}};Statistics.UniformDistribution=function(opt_range){if(!opt_range)opt_range=tr.b.math.Range.fromExplicitRange(0,1);this.range=opt_range;};Statistics.UniformDistribution.prototype={__proto__:Distribution.prototype,computeDensity:function(x){return 1/this.range.range;},computePercentile:function(x){return tr.b.math.normalize(x,this.range.min,this.range.max);},get mean(){return this.range.center;},get mode(){return undefined;},get median(){return this.mean;},get standardDeviation(){return Math.sqrt(this.variance);},get variance(){return Math.pow(this.range.range,2)/12;}};Statistics.NormalDistribution=function(opt_mean,opt_variance){this.mean_=opt_mean||0;this.variance_=opt_variance||1;this.standardDeviation_=Math.sqrt(this.variance_);};Statistics.NormalDistribution.prototype={__proto__:Distribution.prototype,computeDensity:function(x){var scale=(1.0/(this.standardDeviation*Math.sqrt(2.0*Math.PI)));var exponent=-Math.pow(x-this.mean,2)/(2.0*this.variance);return scale*Math.exp(exponent);},computePercentile:function(x){var standardizedX=((x-this.mean)/Math.sqrt(2.0*this.variance));return(1.0+tr.b.math.erf(standardizedX))/2.0;},get mean(){return this.mean_;},get median(){return this.mean;},get mode(){return this.mean;},get standardDeviation(){return this.standardDeviation_;},get variance(){return this.variance_;}};Statistics.LogNormalDistribution=function(opt_location,opt_shape){this.normalDistribution_=new Statistics.NormalDistribution(opt_location,Math.pow(opt_shape||1,2));};Statistics.LogNormalDistribution.prototype={__proto__:Statistics.NormalDistribution.prototype,computeDensity:function(x){return this.normalDistribution_.computeDensity(Math.log(x))/x;},computePercentile:function(x){return this.normalDistribution_.computePercentile(Math.log(x));},get mean(){return Math.exp(this.normalDistribution_.mean+
-(this.normalDistribution_.variance/2));},get variance(){var nm=this.normalDistribution_.mean;var nv=this.normalDistribution_.variance;return(Math.exp(2*(nm+nv))-
+const nbElements=Math.min(numSamples,samplesB.length);const probOfSwapping=streamLengthB/(streamLengthA+streamLengthB);for(let i=0;i<nbElements;++i){if(Math.random()<probOfSwapping){samplesA[i]=samplesB[i];}}};function Distribution(){}
+Distribution.prototype={computeDensity(x){throw Error('Not implemented');},computePercentile(x){throw Error('Not implemented');},computeComplementaryPercentile(x){return 1-this.computePercentile(x);},get mean(){throw Error('Not implemented');},get mode(){throw Error('Not implemented');},get median(){throw Error('Not implemented');},get standardDeviation(){throw Error('Not implemented');},get variance(){throw Error('Not implemented');}};Statistics.UniformDistribution=function(opt_range){if(!opt_range)opt_range=tr.b.math.Range.fromExplicitRange(0,1);this.range=opt_range;};Statistics.UniformDistribution.prototype={__proto__:Distribution.prototype,computeDensity(x){return 1/this.range.range;},computePercentile(x){return tr.b.math.normalize(x,this.range.min,this.range.max);},get mean(){return this.range.center;},get mode(){return undefined;},get median(){return this.mean;},get standardDeviation(){return Math.sqrt(this.variance);},get variance(){return Math.pow(this.range.range,2)/12;}};Statistics.NormalDistribution=function(opt_mean,opt_variance){this.mean_=opt_mean||0;this.variance_=opt_variance||1;this.standardDeviation_=Math.sqrt(this.variance_);};Statistics.NormalDistribution.prototype={__proto__:Distribution.prototype,computeDensity(x){const scale=(1.0/(this.standardDeviation*Math.sqrt(2.0*Math.PI)));const exponent=-Math.pow(x-this.mean,2)/(2.0*this.variance);return scale*Math.exp(exponent);},computePercentile(x){const standardizedX=((x-this.mean)/Math.sqrt(2.0*this.variance));return(1.0+tr.b.math.erf(standardizedX))/2.0;},get mean(){return this.mean_;},get median(){return this.mean;},get mode(){return this.mean;},get standardDeviation(){return this.standardDeviation_;},get variance(){return this.variance_;}};Statistics.LogNormalDistribution=function(opt_location,opt_shape){this.normalDistribution_=new Statistics.NormalDistribution(opt_location,Math.pow(opt_shape||1,2));};Statistics.LogNormalDistribution.prototype={__proto__:Statistics.NormalDistribution.prototype,computeDensity(x){return this.normalDistribution_.computeDensity(Math.log(x))/x;},computePercentile(x){return this.normalDistribution_.computePercentile(Math.log(x));},get mean(){return Math.exp(this.normalDistribution_.mean+
+(this.normalDistribution_.variance/2));},get variance(){const nm=this.normalDistribution_.mean;const nv=this.normalDistribution_.variance;return(Math.exp(2*(nm+nv))-
 Math.exp(2*nm+nv));},get standardDeviation(){return Math.sqrt(this.variance);},get median(){return Math.exp(this.normalDistribution_.mean);},get mode(){return Math.exp(this.normalDistribution_.mean-
-this.normalDistribution_.variance);}};Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns=function(median,diminishingReturns){diminishingReturns=Math.log(diminishingReturns/median);var shape=Math.sqrt(1-3*diminishingReturns-
-Math.sqrt(Math.pow(diminishingReturns-3,2)-8))/2;var location=Math.log(median);return new Statistics.LogNormalDistribution(location,shape);};Statistics.DEFAULT_ALPHA=0.01;Statistics.MAX_SUGGESTED_SAMPLE_SIZE=20;Statistics.Significance={SIGNIFICANT:'REJECT',INSIGNIFICANT:'FAIL_TO_REJECT',NEED_MORE_DATA:'NEED_MORE_DATA',DONT_CARE:'DONT_CARE',};Statistics.mwu=function(a,b,opt_alpha,opt_reqSampleSize){var result=mannwhitneyu.test(a,b);var alpha=opt_alpha||Statistics.DEFAULT_ALPHA;if(result.p<alpha){result.significance=Statistics.Significance.SIGNIFICANT;}else if(opt_reqSampleSize&&(a.length<opt_reqSampleSize||b.length<opt_reqSampleSize)){result.significance=Statistics.Significance.NEED_MORE_DATA;}else{result.significance=Statistics.Significance.INSIGNIFICANT;}
-return result;};return{Statistics,};});'use strict';var GREEK_SMALL_LETTER_MU=String.fromCharCode(956);tr.exportTo('tr.b',function(){var SECONDS_IN_A_MINUTE=60;var SECONDS_IN_AN_HOUR=SECONDS_IN_A_MINUTE*60;var SECONDS_IN_A_DAY=SECONDS_IN_AN_HOUR*24;var SECONDS_IN_A_WEEK=SECONDS_IN_A_DAY*7;var SECONDS_IN_A_YEAR=SECONDS_IN_A_DAY*365.2422;var SECONDS_IN_A_MONTH=SECONDS_IN_A_YEAR/12;var UnitPrefixScale={};var UnitScale={};function defineUnitPrefixScale(name,prefixes){if(UnitPrefixScale[name]!==undefined){throw new Error('Unit prefix scale \''+name+'\' already exists');}
+this.normalDistribution_.variance);}};Statistics.LogNormalDistribution.fromMedianAndDiminishingReturns=function(median,diminishingReturns){diminishingReturns=Math.log(diminishingReturns/median);const shape=Math.sqrt(1-3*diminishingReturns-
+Math.sqrt(Math.pow(diminishingReturns-3,2)-8))/2;const location=Math.log(median);return new Statistics.LogNormalDistribution(location,shape);};Statistics.DEFAULT_ALPHA=0.01;Statistics.MAX_SUGGESTED_SAMPLE_SIZE=20;Statistics.Significance={SIGNIFICANT:'REJECT',INSIGNIFICANT:'FAIL_TO_REJECT',NEED_MORE_DATA:'NEED_MORE_DATA',DONT_CARE:'DONT_CARE',};Statistics.mwu=function(a,b,opt_alpha,opt_reqSampleSize){const result=mannwhitneyu.test(a,b);const alpha=opt_alpha||Statistics.DEFAULT_ALPHA;if(result.p<alpha){result.significance=Statistics.Significance.SIGNIFICANT;}else if(opt_reqSampleSize&&(a.length<opt_reqSampleSize||b.length<opt_reqSampleSize)){result.significance=Statistics.Significance.NEED_MORE_DATA;}else{result.significance=Statistics.Significance.INSIGNIFICANT;}
+return result;};return{Statistics,};});'use strict';const GREEK_SMALL_LETTER_MU=String.fromCharCode(956);tr.exportTo('tr.b',function(){const SECONDS_IN_A_MINUTE=60;const SECONDS_IN_AN_HOUR=SECONDS_IN_A_MINUTE*60;const SECONDS_IN_A_DAY=SECONDS_IN_AN_HOUR*24;const SECONDS_IN_A_WEEK=SECONDS_IN_A_DAY*7;const SECONDS_IN_A_YEAR=SECONDS_IN_A_DAY*365.2422;const SECONDS_IN_A_MONTH=SECONDS_IN_A_YEAR/12;const UnitPrefixScale={};const UnitScale={};function defineUnitPrefixScale(name,prefixes){if(UnitPrefixScale[name]!==undefined){throw new Error('Unit prefix scale \''+name+'\' already exists');}
 if(prefixes.AUTO!==undefined){throw new Error('The \'AUTO\' unit prefix is not supported for unit'+'prefix scales and cannot be added to scale \''+name+'\'');}
 UnitPrefixScale[name]=prefixes;}
 UnitScale.defineUnitScale=function(name,unitScale){if(UnitScale[name]!==undefined){throw new Error('Unit scale \''+name+'\' already exists');}
 if(unitScale.AUTO!==undefined){throw new Error('\'AUTO\' unit scale will be added automatically '+'for unit scale \''+name+'\'');}
-unitScale.AUTO=tr.b.dictionaryValues(unitScale);unitScale.AUTO.sort((a,b)=>a.value-b.value);if(name)UnitScale[name]=unitScale;return unitScale;};UnitScale.defineUnitScaleFromPrefixScale=function(baseSymbol,baseName,prefixScale,opt_scaleName){if(baseSymbol===undefined){throw new Error('Cannot create UnitScale with undefined baseSymbol.');}
+unitScale.AUTO=Object.values(unitScale);unitScale.AUTO.sort((a,b)=>a.value-b.value);if(name)UnitScale[name]=unitScale;return unitScale;};UnitScale.defineUnitScaleFromPrefixScale=function(baseSymbol,baseName,prefixScale,opt_scaleName){if(baseSymbol===undefined){throw new Error('Cannot create UnitScale with undefined baseSymbol.');}
 if(!baseName){throw new Error('Cannot create UnitScale without a baseName.');}
 if(!prefixScale){throw new Error('Cannot create UnitScale without a prefix scale.');}
-var unitScale={};for(var curPrefix of Object.keys(prefixScale)){var curScale=prefixScale[curPrefix];if(curScale.symbol===undefined||!curScale.value){throw new Error(`Cannot convert PrefixScale with malformed prefix ${curScale}.`);}
-var name=curPrefix==='NONE'?baseName:`${curPrefix}_${baseName}`;unitScale[name]={value:curScale.value,symbol:curScale.symbol+baseSymbol,baseSymbol:baseSymbol};}
-return UnitScale.defineUnitScale(opt_scaleName,unitScale);};function convertUnit(value,fromScale,toScale){if(value===undefined)return undefined;var fromScaleBase=fromScale.baseSymbol;var toScaleBase=toScale.baseSymbol;if(fromScaleBase!==undefined&&toScaleBase!==undefined&&fromScaleBase!==toScaleBase){throw new Error('Cannot convert between units with different base symbols.');}
+const unitScale={};for(const curPrefix of Object.keys(prefixScale)){const curScale=prefixScale[curPrefix];if(curScale.symbol===undefined||!curScale.value){throw new Error(`Cannot convert PrefixScale with malformed prefix ${curScale}.`);}
+const name=curPrefix==='NONE'?baseName:`${curPrefix}_${baseName}`;unitScale[name]={value:curScale.value,symbol:curScale.symbol+baseSymbol,baseSymbol};}
+return UnitScale.defineUnitScale(opt_scaleName,unitScale);};function convertUnit(value,fromScale,toScale){if(value===undefined)return undefined;const fromScaleBase=fromScale.baseSymbol;const toScaleBase=toScale.baseSymbol;if(fromScaleBase!==undefined&&toScaleBase!==undefined&&fromScaleBase!==toScaleBase){throw new Error('Cannot convert between units with different base symbols.');}
 return value*(fromScale.value/toScale.value);}
-defineUnitPrefixScale('BINARY',{NONE:{value:Math.pow(1024,0),symbol:''},KIBI:{value:Math.pow(1024,1),symbol:'Ki'},MEBI:{value:Math.pow(1024,2),symbol:'Mi'},GIBI:{value:Math.pow(1024,3),symbol:'Gi'},TEBI:{value:Math.pow(1024,4),symbol:'Ti'}});defineUnitPrefixScale('METRIC',{NANO:{value:1e-9,symbol:'n'},MICRO:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU},MILLI:{value:1e-3,symbol:'m'},NONE:{value:1,symbol:''},KILO:{value:1e3,symbol:'k'},MEGA:{value:1e6,symbol:'M'},GIGA:{value:1e9,symbol:'G'}});UnitScale.defineUnitScale('TIME',{NANO_SEC:{value:1e-9,symbol:'ns',baseSymbol:'s'},MICRO_SEC:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU+'s',baseSymbol:'s'},MILLI_SEC:{value:1e-3,symbol:'ms',baseSymbol:'s'},SEC:{value:1,symbol:'s',baseSymbol:'s'},MINUTE:{value:SECONDS_IN_A_MINUTE,symbol:'min',baseSymbol:'s'},HOUR:{value:SECONDS_IN_AN_HOUR,symbol:'hr',baseSymbol:'s'},DAY:{value:SECONDS_IN_A_DAY,symbol:'days',baseSymbol:'s'},WEEK:{value:SECONDS_IN_A_WEEK,symbol:'weeks',baseSymbol:'s'},MONTH:{value:SECONDS_IN_A_MONTH,symbol:'months',baseSymbol:'s'},YEAR:{value:SECONDS_IN_A_YEAR,symbol:'years',baseSymbol:'s'}});UnitScale.defineUnitScaleFromPrefixScale('B','BYTE',UnitPrefixScale.BINARY,'MEMORY');return{UnitPrefixScale,UnitScale,convertUnit,};});'use strict';tr.exportTo('tr.b',function(){var msDisplayMode={scale:1e-3,suffix:'ms',roundedLess:function(a,b){return Math.round(a*1000)<Math.round(b*1000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.MILLI_SEC],minimumFractionDigits:3,}};var nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess:function(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.NANO_SEC],maximumFractionDigits:0}};var TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes,};});'use strict';tr.exportTo('tr.b',function(){function _iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement&&cb.call(thisArg,element))return true;if(element.root&&element.root!==element&&_iterateElementDeeplyImpl(element.root,cb,thisArg,false)){return true;}
-var children=Polymer.dom(element).children;for(var i=0;i<children.length;i++){if(_iterateElementDeeplyImpl(children[i],cb,thisArg,true)){return true;}}
+defineUnitPrefixScale('BINARY',{NONE:{value:Math.pow(1024,0),symbol:''},KIBI:{value:Math.pow(1024,1),symbol:'Ki'},MEBI:{value:Math.pow(1024,2),symbol:'Mi'},GIBI:{value:Math.pow(1024,3),symbol:'Gi'},TEBI:{value:Math.pow(1024,4),symbol:'Ti'}});defineUnitPrefixScale('METRIC',{NANO:{value:1e-9,symbol:'n'},MICRO:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU},MILLI:{value:1e-3,symbol:'m'},NONE:{value:1,symbol:''},KILO:{value:1e3,symbol:'k'},MEGA:{value:1e6,symbol:'M'},GIGA:{value:1e9,symbol:'G'}});UnitScale.defineUnitScale('TIME',{NANO_SEC:{value:1e-9,symbol:'ns',baseSymbol:'s'},MICRO_SEC:{value:1e-6,symbol:GREEK_SMALL_LETTER_MU+'s',baseSymbol:'s'},MILLI_SEC:{value:1e-3,symbol:'ms',baseSymbol:'s'},SEC:{value:1,symbol:'s',baseSymbol:'s'},MINUTE:{value:SECONDS_IN_A_MINUTE,symbol:'min',baseSymbol:'s'},HOUR:{value:SECONDS_IN_AN_HOUR,symbol:'hr',baseSymbol:'s'},DAY:{value:SECONDS_IN_A_DAY,symbol:'days',baseSymbol:'s'},WEEK:{value:SECONDS_IN_A_WEEK,symbol:'weeks',baseSymbol:'s'},MONTH:{value:SECONDS_IN_A_MONTH,symbol:'months',baseSymbol:'s'},YEAR:{value:SECONDS_IN_A_YEAR,symbol:'years',baseSymbol:'s'}});UnitScale.defineUnitScaleFromPrefixScale('B','BYTE',UnitPrefixScale.BINARY,'MEMORY');return{UnitPrefixScale,UnitScale,convertUnit,};});'use strict';tr.exportTo('tr.b',function(){const msDisplayMode={scale:1e-3,suffix:'ms',roundedLess(a,b){return Math.round(a*1000)<Math.round(b*1000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.MILLI_SEC],minimumFractionDigits:3,}};const nsDisplayMode={scale:1e-9,suffix:'ns',roundedLess(a,b){return Math.round(a*1000000)<Math.round(b*1000000);},formatSpec:{unitScale:[tr.b.UnitScale.TIME.NANO_SEC],maximumFractionDigits:0}};const TimeDisplayModes={ns:nsDisplayMode,ms:msDisplayMode};return{TimeDisplayModes,};});'use strict';tr.exportTo('tr.b',function(){function iterateElementDeeplyImpl(element,cb,thisArg,includeElement){if(includeElement&&cb.call(thisArg,element))return true;if(element.root&&element.root!==element&&iterateElementDeeplyImpl(element.root,cb,thisArg,false)){return true;}
+const children=Polymer.dom(element).children;for(let i=0;i<children.length;i++){if(iterateElementDeeplyImpl(children[i],cb,thisArg,true)){return true;}}
 return false;}
-function iterateElementDeeply(element,cb,thisArg){_iterateElementDeeplyImpl(element,cb,thisArg,false);}
-function findDeepElementMatchingPredicate(element,predicate){var foundElement=undefined;function matches(element){var match=predicate(element);if(!match){return false;}
+function iterateElementDeeply(element,cb,thisArg){iterateElementDeeplyImpl(element,cb,thisArg,false);}
+function findDeepElementMatchingPredicate(element,predicate){let foundElement=undefined;function matches(element){const match=predicate(element);if(!match){return false;}
 foundElement=element;return true;}
 iterateElementDeeply(element,matches);return foundElement;}
-function findDeepElementsMatchingPredicate(element,predicate){var foundElements=[];function matches(element){var match=predicate(element);if(match){foundElements.push(element);}
+function findDeepElementsMatchingPredicate(element,predicate){const foundElements=[];function matches(element){const match=predicate(element);if(match){foundElements.push(element);}
 return false;}
 iterateElementDeeply(element,matches);return foundElements;}
 function findDeepElementMatching(element,selector){return findDeepElementMatchingPredicate(element,function(element){return element.matches(selector);});}
 function findDeepElementsMatching(element,selector){return findDeepElementsMatchingPredicate(element,function(element){return element.matches(selector);});}
 function findDeepElementWithTextContent(element,re){return findDeepElementMatchingPredicate(element,function(element){if(element.children.length!==0)return false;return re.test(Polymer.dom(element).textContent);});}
-return{iterateElementDeeply,findDeepElementMatching,findDeepElementsMatching,findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate,findDeepElementWithTextContent,};});'use strict';tr.exportTo('tr.b',function(){var TimeDisplayModes=tr.b.TimeDisplayModes;var PLUS_MINUS_SIGN=String.fromCharCode(177);var CACHED_FORMATTERS={};function getNumberFormatter(minSpec,maxSpec,minCtx,maxCtx){var key=minSpec+'-'+maxSpec+'-'+minCtx+'-'+maxCtx;var formatter=CACHED_FORMATTERS[key];if(formatter===undefined){var minimumFractionDigits=minCtx!==undefined?minCtx:minSpec;var maximumFractionDigits=maxCtx!==undefined?maxCtx:maxSpec;if(minimumFractionDigits>maximumFractionDigits){if(minCtx!==undefined&&maxCtx===undefined){maximumFractionDigits=minimumFractionDigits;}else if(minCtx===undefined&&maxCtx!==undefined){minimumFractionDigits=maximumFractionDigits;}}
+return{iterateElementDeeply,findDeepElementMatching,findDeepElementsMatching,findDeepElementMatchingPredicate,findDeepElementsMatchingPredicate,findDeepElementWithTextContent,};});'use strict';tr.exportTo('tr.b',function(){const TimeDisplayModes=tr.b.TimeDisplayModes;const PLUS_MINUS_SIGN=String.fromCharCode(177);const CACHED_FORMATTERS={};function getNumberFormatter(minSpec,maxSpec,minCtx,maxCtx){const key=minSpec+'-'+maxSpec+'-'+minCtx+'-'+maxCtx;let formatter=CACHED_FORMATTERS[key];if(formatter===undefined){let minimumFractionDigits=minCtx!==undefined?minCtx:minSpec;let maximumFractionDigits=maxCtx!==undefined?maxCtx:maxSpec;if(minimumFractionDigits>maximumFractionDigits){if(minCtx!==undefined&&maxCtx===undefined){maximumFractionDigits=minimumFractionDigits;}else if(minCtx===undefined&&maxCtx!==undefined){minimumFractionDigits=maximumFractionDigits;}}
 formatter=new Intl.NumberFormat(undefined,{minimumFractionDigits,maximumFractionDigits,});CACHED_FORMATTERS[key]=formatter;}
 return formatter;}
 function max(a,b){if(a===undefined)return b;if(b===undefined)return a;return a.scale>b.scale?a:b;}
-var ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,formatSpec){this.unitName=unitName;this.jsonName=jsonName;this.scaleBaseUnit=scaleBaseUnit;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatSpec_=formatSpec;this.baseUnit=undefined;this.correspondingDeltaUnit=undefined;}
-Unit.prototype={asJSON:function(){return this.jsonName;},getUnitScale_:function(opt_context){var formatSpec=this.formatSpec_;var formatSpecWasFunction=false;if(typeof formatSpec==='function'){formatSpecWasFunction=true;formatSpec=formatSpec();}
-var context=opt_context||{};var scale=undefined;if(context.unitScale){scale=context.unitScale;}else if(context.unitPrefix){var symbol=formatSpec.baseSymbol?formatSpec.baseSymbol:this.scaleBaseUnit.baseSymbol;scale=tr.b.UnitScale.defineUnitScaleFromPrefixScale(symbol,symbol,[context.unitPrefix]).AUTO;}else{scale=formatSpec.unitScale;if(!scale){scale=[{value:1,symbol:formatSpec.baseSymbol||'',baseSymbol:formatSpec.baseSymbol||''}];if(!formatSpecWasFunction)formatSpec.unitScale=scale;}}
+const ImprovementDirection={DONT_CARE:0,BIGGER_IS_BETTER:1,SMALLER_IS_BETTER:2};function Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,formatSpec){this.unitName=unitName;this.jsonName=jsonName;this.scaleBaseUnit=scaleBaseUnit;this.isDelta=isDelta;this.improvementDirection=improvementDirection;this.formatSpec_=formatSpec;this.baseUnit=undefined;this.correspondingDeltaUnit=undefined;}
+Unit.prototype={asJSON(){return this.jsonName;},getUnitScale_(opt_context){let formatSpec=this.formatSpec_;let formatSpecWasFunction=false;if(typeof formatSpec==='function'){formatSpecWasFunction=true;formatSpec=formatSpec();}
+const context=opt_context||{};let scale=undefined;if(context.unitScale){scale=context.unitScale;}else if(context.unitPrefix){const symbol=formatSpec.baseSymbol?formatSpec.baseSymbol:this.scaleBaseUnit.baseSymbol;scale=tr.b.UnitScale.defineUnitScaleFromPrefixScale(symbol,symbol,[context.unitPrefix]).AUTO;}else{scale=formatSpec.unitScale;if(!scale){scale=[{value:1,symbol:formatSpec.baseSymbol||'',baseSymbol:formatSpec.baseSymbol||''}];if(!formatSpecWasFunction)formatSpec.unitScale=scale;}}
 if(!(scale instanceof Array)){throw new Error('Unit has a malformed unit scale.');}
-return scale;},get unitString(){var scale=this.getUnitScale_();if(!scale){throw new Error('A UnitScale could not be found for Unit '+this.unitName);}
-return scale[0].baseSymbol||scale[0].symbol;},format:function(value,opt_context){var signString='';if(value<0){signString='-';value=-value;}else if(this.isDelta){signString=value===0?PLUS_MINUS_SIGN:'+';}
-var context=opt_context||{};var scale=this.getUnitScale_(context);var deltaValue=context.deltaValue===undefined?value:context.deltaValue;deltaValue=Math.abs(deltaValue)*this.scaleBaseUnit.value;var i=0;while(i<scale.length-1&&deltaValue/scale[i+1].value>=1){i++;}
-var selectedSubUnit=scale[i];var formatSpec=this.formatSpec_;if(typeof formatSpec==='function')formatSpec=formatSpec();var unitString='';if(selectedSubUnit.symbol){if(!formatSpec.avoidSpacePrecedingUnit)unitString=' ';unitString+=selectedSubUnit.symbol;}
-value=tr.b.convertUnit(value,this.scaleBaseUnit,selectedSubUnit);var numberString=getNumberFormatter(formatSpec.minimumFractionDigits,formatSpec.maximumFractionDigits,context.minimumFractionDigits,context.maximumFractionDigits).format(value);return signString+numberString+unitString;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return tr.b.convertUnit(us,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);};Object.defineProperty(Unit,'currentTimeDisplayMode',{get:function(){return Unit.currentTimeDisplayMode_;},set:function(value){if(Unit.currentTimeDisplayMode_===value)return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){var largest=undefined;var els=tr.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentTimeDisplayMode=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){var u=Unit.byJSONName[object];if(u){return u;}
-throw new Error('Unrecognized unit');};Unit.define=function(params){var definedUnits=[];for(var improvementDirection of Object.values(ImprovementDirection)){var regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);var deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;definedUnits.push(regularUnit,deltaUnit);}
-var baseUnit=Unit.byName[params.baseUnitName];definedUnits.forEach(u=>u.baseUnit=baseUnit);};Unit.nameSuffixForImprovementDirection=function(improvementDirection){switch(improvementDirection){case ImprovementDirection.DONT_CARE:return'';case ImprovementDirection.BIGGER_IS_BETTER:return'_biggerIsBetter';case ImprovementDirection.SMALLER_IS_BETTER:return'_smallerIsBetter';default:throw new Error('Unknown improvement direction: '+improvementDirection);}};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){var nameSuffix=isDelta?'Delta':'';nameSuffix+=Unit.nameSuffixForImprovementDirection(improvementDirection);var unitName=params.baseUnitName+nameSuffix;var jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined){throw new Error('Unit \''+unitName+'\' already exists');}
+return scale;},get unitString(){const scale=this.getUnitScale_();if(!scale){throw new Error('A UnitScale could not be found for Unit '+this.unitName);}
+return scale[0].baseSymbol||scale[0].symbol;},format(value,opt_context){let signString='';if(value<0){signString='-';value=-value;}else if(this.isDelta){signString=value===0?PLUS_MINUS_SIGN:'+';}
+const context=opt_context||{};const scale=this.getUnitScale_(context);let deltaValue=context.deltaValue===undefined?value:context.deltaValue;deltaValue=Math.abs(deltaValue)*this.scaleBaseUnit.value;let i=0;while(i<scale.length-1&&deltaValue/scale[i+1].value>=1){i++;}
+const selectedSubUnit=scale[i];let formatSpec=this.formatSpec_;if(typeof formatSpec==='function')formatSpec=formatSpec();let unitString='';if(selectedSubUnit.symbol){if(!formatSpec.avoidSpacePrecedingUnit)unitString=' ';unitString+=selectedSubUnit.symbol;}
+value=tr.b.convertUnit(value,this.scaleBaseUnit,selectedSubUnit);const numberString=getNumberFormatter(formatSpec.minimumFractionDigits,formatSpec.maximumFractionDigits,context.minimumFractionDigits,context.maximumFractionDigits).format(value);return signString+numberString+unitString;}};Unit.reset=function(){Unit.currentTimeDisplayMode=TimeDisplayModes.ms;};Unit.timestampFromUs=function(us){return tr.b.convertUnit(us,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);};Object.defineProperty(Unit,'currentTimeDisplayMode',{get(){return Unit.currentTimeDisplayMode_;},set(value){if(Unit.currentTimeDisplayMode_===value)return;Unit.currentTimeDisplayMode_=value;Unit.dispatchEvent(new tr.b.Event('display-mode-changed'));}});Unit.didPreferredTimeDisplayUnitChange=function(){let largest=undefined;const els=tr.b.findDeepElementsMatching(document.body,'tr-v-ui-preferred-display-unit');els.forEach(function(el){largest=max(largest,el.preferredTimeDisplayMode);});Unit.currentTimeDisplayMode=largest===undefined?TimeDisplayModes.ms:largest;};Unit.byName={};Unit.byJSONName={};Unit.fromJSON=function(object){const u=Unit.byJSONName[object];if(u){return u;}
+throw new Error('Unrecognized unit');};Unit.define=function(params){const definedUnits=[];for(const improvementDirection of Object.values(ImprovementDirection)){const regularUnit=Unit.defineUnitVariant_(params,false,improvementDirection);const deltaUnit=Unit.defineUnitVariant_(params,true,improvementDirection);regularUnit.correspondingDeltaUnit=deltaUnit;deltaUnit.correspondingDeltaUnit=deltaUnit;definedUnits.push(regularUnit,deltaUnit);}
+const baseUnit=Unit.byName[params.baseUnitName];definedUnits.forEach(u=>u.baseUnit=baseUnit);};Unit.nameSuffixForImprovementDirection=function(improvementDirection){switch(improvementDirection){case ImprovementDirection.DONT_CARE:return'';case ImprovementDirection.BIGGER_IS_BETTER:return'_biggerIsBetter';case ImprovementDirection.SMALLER_IS_BETTER:return'_smallerIsBetter';default:throw new Error('Unknown improvement direction: '+improvementDirection);}};Unit.defineUnitVariant_=function(params,isDelta,improvementDirection){let nameSuffix=isDelta?'Delta':'';nameSuffix+=Unit.nameSuffixForImprovementDirection(improvementDirection);const unitName=params.baseUnitName+nameSuffix;const jsonName=params.baseJsonName+nameSuffix;if(Unit.byName[unitName]!==undefined){throw new Error('Unit \''+unitName+'\' already exists');}
 if(Unit.byJSONName[jsonName]!==undefined){throw new Error('JSON unit \''+jsonName+'\' alread exists');}
-var scaleBaseUnit=params.scaleBaseUnit;if(!scaleBaseUnit){var formatSpec=params.formatSpec;if(typeof formatSpec==='function')formatSpec=formatSpec();var baseSymbol=formatSpec.unitScale?formatSpec.unitScale[0].baseSymbol:(formatSpec.baseSymbol||'');scaleBaseUnit={value:1,symbol:baseSymbol,baseSymbol:baseSymbol};}
-var unit=new Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,params.formatSpec);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeInMsAutoFormat',baseJsonName:'msBestFitFormat',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec:{unitScale:tr.b.UnitScale.TIME.AUTO,minimumFractionDigits:0,maximumFractionDigits:3}});Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec:function(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec:function(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatSpec:{unitScale:[{value:0.01,symbol:'%'}],avoidSpacePrecedingUnit:true,minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatSpec:{unitScale:tr.b.UnitScale.MEMORY.AUTO,minimumFractionDigits:1,maximumFractionDigits:1}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatSpec:{baseSymbol:'J',minimumFractionDigits:3}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatSpec:{baseSymbol:'W',minimumFractionDigits:3}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatSpec:{minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'count',baseJsonName:'count',formatSpec:{minimumFractionDigits:0,maximumFractionDigits:0}});Unit.define({baseUnitName:'sigma',baseJsonName:'sigma',formatSpec:{baseSymbol:String.fromCharCode(963),minimumFractionDigits:1,maximumFractionDigits:1}});return{ImprovementDirection,Unit,};});'use strict';tr.exportTo('tr.b',function(){class Scalar{constructor(unit,value){if(!(unit instanceof tr.b.Unit)){throw new Error('Expected Unit');}
+let scaleBaseUnit=params.scaleBaseUnit;if(!scaleBaseUnit){let formatSpec=params.formatSpec;if(typeof formatSpec==='function')formatSpec=formatSpec();const baseSymbol=formatSpec.unitScale?formatSpec.unitScale[0].baseSymbol:(formatSpec.baseSymbol||'');scaleBaseUnit={value:1,symbol:baseSymbol,baseSymbol};}
+const unit=new Unit(unitName,jsonName,scaleBaseUnit,isDelta,improvementDirection,params.formatSpec);Unit.byName[unitName]=unit;Unit.byJSONName[jsonName]=unit;return unit;};tr.b.EventTarget.decorate(Unit);Unit.reset();Unit.define({baseUnitName:'timeInMsAutoFormat',baseJsonName:'msBestFitFormat',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec:{unitScale:tr.b.UnitScale.TIME.AUTO,minimumFractionDigits:0,maximumFractionDigits:3}});Unit.define({baseUnitName:'timeDurationInMs',baseJsonName:'ms',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'timeStampInMs',baseJsonName:'tsMs',scaleBaseUnit:tr.b.UnitScale.TIME.MILLI_SEC,formatSpec(){return Unit.currentTimeDisplayMode_.formatSpec;}});Unit.define({baseUnitName:'normalizedPercentage',baseJsonName:'n%',formatSpec:{unitScale:[{value:0.01,symbol:'%'}],avoidSpacePrecedingUnit:true,minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'sizeInBytes',baseJsonName:'sizeInBytes',formatSpec:{unitScale:tr.b.UnitScale.MEMORY.AUTO,minimumFractionDigits:1,maximumFractionDigits:1}});Unit.define({baseUnitName:'energyInJoules',baseJsonName:'J',formatSpec:{baseSymbol:'J',minimumFractionDigits:3}});Unit.define({baseUnitName:'powerInWatts',baseJsonName:'W',formatSpec:{baseSymbol:'W',minimumFractionDigits:3}});Unit.define({baseUnitName:'unitlessNumber',baseJsonName:'unitless',formatSpec:{minimumFractionDigits:3,maximumFractionDigits:3}});Unit.define({baseUnitName:'count',baseJsonName:'count',formatSpec:{minimumFractionDigits:0,maximumFractionDigits:0}});Unit.define({baseUnitName:'sigma',baseJsonName:'sigma',formatSpec:{baseSymbol:String.fromCharCode(963),minimumFractionDigits:1,maximumFractionDigits:1}});return{ImprovementDirection,Unit,};});'use strict';tr.exportTo('tr.b',function(){class Scalar{constructor(unit,value){if(!(unit instanceof tr.b.Unit)){throw new Error('Expected Unit');}
 if(!(typeof(value)==='number')){throw new Error('Expected value to be number');}
 this.unit=unit;this.value=value;}
 asDict(){return{unit:this.unit.asJSON(),value:tr.b.numberToJson(this.value),};}
 toString(){return this.unit.format(this.value);}
 static fromDict(d){return new Scalar(tr.b.Unit.fromJSON(d.unit),tr.b.numberFromJson(d.value));}}
 return{Scalar,};});'use strict';tr.exportTo('tr.c',function(){function Auditor(model){this.model_=model;}
-Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate:function(){},installUserFriendlyCategoryDriverIfNeeded:function(){},runAudit:function(){}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor,};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
+Auditor.prototype={__proto__:Object.prototype,get model(){return this.model_;},runAnnotate(){},installUserFriendlyCategoryDriverIfNeeded(){},runAudit(){}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Auditor;tr.b.decorateExtensionRegistry(Auditor,options);return{Auditor,};});'use strict';tr.exportTo('tr.b',function(){function clamp01(value){return Math.max(0,Math.min(1,value));}
 function Color(opt_r,opt_g,opt_b,opt_a){this.r=Math.floor(opt_r)||0;this.g=Math.floor(opt_g)||0;this.b=Math.floor(opt_b)||0;this.a=opt_a;}
-Color.fromString=function(str){var tmp;var values;if(str.substr(0,4)==='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==3){throw new Error('Malformatted rgb-expression');}
+Color.fromString=function(str){let tmp;let values;if(str.substr(0,4)==='rgb('){tmp=str.substr(4,str.length-5);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==3){throw new Error('Malformatted rgb-expression');}
 return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]));}
 if(str.substr(0,5)==='rgba('){tmp=str.substr(5,str.length-6);values=tmp.split(',').map(function(v){return v.replace(/^\s+/,'','g');});if(values.length!==4){throw new Error('Malformatted rgb-expression');}
 return new Color(parseInt(values[0]),parseInt(values[1]),parseInt(values[2]),parseFloat(values[3]));}
 if(str[0]==='#'&&str.length===7){return new Color(parseInt(str.substr(1,2),16),parseInt(str.substr(3,2),16),parseInt(str.substr(5,2),16));}
 throw new Error('Unrecognized string format.');};Color.lerp=function(a,b,percent){if(a.a!==undefined&&b.a!==undefined){return Color.lerpRGBA(a,b,percent);}
-return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){var r;var g;var b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
-if(s===0){r=g=b=l;}else{var q=l<0.5?l*(1+s):l+s-l*s;var p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
-return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);};Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);};Color.prototype={clone:function(){var c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver:function(bgColor){var oneMinusThisAlpha=1-this.a;var outA=this.a+bgColor.a*oneMinusThisAlpha;var bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten:function(opt_k){var k;k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten:function(k,opt_maxL){var maxL=opt_maxL!==undefined?opt_maxL:1.0;var hsl=this.toHSL();hsl.l=Math.min(hsl.l+k,maxL);return Color.fromHSL(hsl);},darken:function(opt_k){var k;if(opt_k!==undefined){k=opt_k;}else{k=0.45;}
-return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate:function(opt_desaturateFactor){var desaturateFactor;if(opt_desaturateFactor!==undefined){desaturateFactor=opt_desaturateFactor;}else{desaturateFactor=1;}
-var hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha:function(a){return new Color(this.r,this.g,this.b,a);},toString:function(){if(this.a!==undefined){return'rgba('+
+return Color.lerpRGB(a,b,percent);};Color.lerpRGB=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b);};Color.lerpRGBA=function(a,b,percent){return new Color(((b.r-a.r)*percent)+a.r,((b.g-a.g)*percent)+a.g,((b.b-a.b)*percent)+a.b,((b.a-a.a)*percent)+a.a);};Color.fromDict=function(dict){return new Color(dict.r,dict.g,dict.b,dict.a);};Color.fromHSLExplicit=function(h,s,l,a){let r;let g;let b;function hue2rgb(p,q,t){if(t<0)t+=1;if(t>1)t-=1;if(t<1/6)return p+(q-p)*6*t;if(t<1/2)return q;if(t<2/3)return p+(q-p)*(2/3-t)*6;return p;}
+if(s===0){r=g=b=l;}else{const q=l<0.5?l*(1+s):l+s-l*s;const p=2*l-q;r=hue2rgb(p,q,h+1/3);g=hue2rgb(p,q,h);b=hue2rgb(p,q,h-1/3);}
+return new Color(Math.floor(r*255),Math.floor(g*255),Math.floor(b*255),a);};Color.fromHSL=function(hsl){return Color.fromHSLExplicit(hsl.h,hsl.s,hsl.l,hsl.a);};Color.prototype={clone(){const c=new Color();c.r=this.r;c.g=this.g;c.b=this.b;c.a=this.a;return c;},blendOver(bgColor){const oneMinusThisAlpha=1-this.a;const outA=this.a+bgColor.a*oneMinusThisAlpha;const bgBlend=(bgColor.a*oneMinusThisAlpha)/bgColor.a;return new Color(this.r*this.a+bgColor.r*bgBlend,this.g*this.a+bgColor.g*bgBlend,this.b*this.a+bgColor.b*bgBlend,outA);},brighten(opt_k){const k=opt_k||0.45;return new Color(Math.min(255,this.r+Math.floor(this.r*k)),Math.min(255,this.g+Math.floor(this.g*k)),Math.min(255,this.b+Math.floor(this.b*k)),this.a);},lighten(k,opt_maxL){const maxL=opt_maxL!==undefined?opt_maxL:1.0;const hsl=this.toHSL();hsl.l=Math.min(hsl.l+k,maxL);return Color.fromHSL(hsl);},darken(opt_k){let k;if(opt_k!==undefined){k=opt_k;}else{k=0.45;}
+return new Color(Math.min(255,this.r-Math.floor(this.r*k)),Math.min(255,this.g-Math.floor(this.g*k)),Math.min(255,this.b-Math.floor(this.b*k)),this.a);},desaturate(opt_desaturateFactor){let desaturateFactor;if(opt_desaturateFactor!==undefined){desaturateFactor=opt_desaturateFactor;}else{desaturateFactor=1;}
+const hsl=this.toHSL();hsl.s=clamp01(hsl.s*(1-desaturateFactor));return Color.fromHSL(hsl);},withAlpha(a){return new Color(this.r,this.g,this.b,a);},toString(){if(this.a!==undefined){return'rgba('+
 this.r+','+this.g+','+
 this.b+','+this.a+')';}
-return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL:function(){var r=this.r/255;var g=this.g/255;var b=this.b/255;var max=Math.max(r,g,b);var min=Math.min(r,g,b);var h;var s;var l=(max+min)/2;if(min===max){h=0;s=0;}else{var delta=max-min;if(l>0.5){s=delta/(2-max-min);}else{s=delta/(max+min);}
+return'rgb('+this.r+','+this.g+','+this.b+')';},toHSL(){const r=this.r/255;const g=this.g/255;const b=this.b/255;const max=Math.max(r,g,b);const min=Math.min(r,g,b);let h;let s;const l=(max+min)/2;if(min===max){h=0;s=0;}else{const delta=max-min;if(l>0.5){s=delta/(2-max-min);}else{s=delta/(max+min);}
 if(r===max){h=(g-b)/delta;if(g<b)h+=6;}else if(g===max){h=2+((b-r)/delta);}else{h=4+((r-g)/delta);}
 h/=6;}
-return{h:h,s:s,l:l,a:this.a};},toStringWithAlphaOverride:function(alpha){return'rgba('+
+return{h,s,l,a:this.a};},toStringWithAlphaOverride(alpha){return'rgba('+
 this.r+','+this.g+','+
-this.b+','+alpha+')';}};return{Color,};});'use strict';tr.exportTo('tr.b',function(){var generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];var reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),background_memory_dump:new tr.b.Color(0,180,180),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),vsync_highlight_color:new tr.b.Color(0,0,255),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),grey:new tr.b.Color(221,221,221),white:new tr.b.Color(255,255,255),yellow:new tr.b.Color(255,255,0),olive:new tr.b.Color(100,100,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),startup:new tr.b.Color(230,230,0),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),heap_dump_child_node_arrow:new tr.b.Color(204,102,0),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};var numGeneralPurposeColorIds=generalPurposeColors.length;var numReservedColorIds=tr.b.dictionaryLength(reservedColorsByName);var numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
-var paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,tr.b.dictionaryValues(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant,};function pushVariant(func){var variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
-pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.8);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.85);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});var reservedColorNameToIdMap=(function(){var m=new Map();var i=generalPurposeColors.length;for(var key of Object.keys(reservedColorsByName)){m.set(key,i++);}
-return m;})();ColorScheme.getColorIdForReservedName=function(name){var id=reservedColorNameToIdMap.get(name);if(id===undefined){throw new Error('Unrecognized color '+name);}
-return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){var id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){var hash=0;for(var i=0;i<name.length;++i){hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;}
-return hash;};var stringColorIdCache=new Map();ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache.get(string)===undefined){var hash=ColorScheme.getStringHash(string);stringColorIdCache.set(string,hash%numGeneralPurposeColorIds);}
-return stringColorIdCache.get(string);};return{ColorScheme,};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
-return{EventInfo,};});'use strict';tr.exportTo('tr.b',function(){var nextGUID=1;var UUID4_PATTERN='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';var GUID={allocateSimple:function(){return nextGUID++;},getLastSimpleGuid:function(){return nextGUID-1;},allocateUUID4:function(){return UUID4_PATTERN.replace(/[xy]/g,function(c){var r=parseInt(Math.random()*16);if(c==='y')r=(r&3)+8;return r.toString(16);});}};return{GUID,};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.name===undefined){throw new Error('Registered events must provide name metadata');}
+this.b+','+alpha+')';}};return{Color,};});'use strict';tr.exportTo('tr.b',function(){const generalPurposeColors=[new tr.b.Color(122,98,135),new tr.b.Color(150,83,105),new tr.b.Color(44,56,189),new tr.b.Color(99,86,147),new tr.b.Color(104,129,107),new tr.b.Color(130,178,55),new tr.b.Color(87,109,147),new tr.b.Color(111,145,88),new tr.b.Color(81,152,131),new tr.b.Color(142,91,111),new tr.b.Color(81,163,70),new tr.b.Color(148,94,86),new tr.b.Color(144,89,118),new tr.b.Color(83,150,97),new tr.b.Color(105,94,139),new tr.b.Color(89,144,122),new tr.b.Color(105,119,128),new tr.b.Color(96,128,137),new tr.b.Color(145,88,145),new tr.b.Color(88,145,144),new tr.b.Color(90,100,143),new tr.b.Color(121,97,136),new tr.b.Color(111,160,73),new tr.b.Color(112,91,142),new tr.b.Color(86,147,86),new tr.b.Color(63,100,170),new tr.b.Color(81,152,107),new tr.b.Color(60,164,173),new tr.b.Color(143,72,161),new tr.b.Color(159,74,86)];const reservedColorsByName={thread_state_uninterruptible:new tr.b.Color(182,125,143),thread_state_iowait:new tr.b.Color(255,140,0),thread_state_running:new tr.b.Color(126,200,148),thread_state_runnable:new tr.b.Color(133,160,210),thread_state_sleeping:new tr.b.Color(240,240,240),thread_state_unknown:new tr.b.Color(199,155,125),background_memory_dump:new tr.b.Color(0,180,180),light_memory_dump:new tr.b.Color(0,0,180),detailed_memory_dump:new tr.b.Color(180,0,180),vsync_highlight_color:new tr.b.Color(0,0,255),generic_work:new tr.b.Color(125,125,125),good:new tr.b.Color(0,125,0),bad:new tr.b.Color(180,125,0),terrible:new tr.b.Color(180,0,0),black:new tr.b.Color(0,0,0),grey:new tr.b.Color(221,221,221),white:new tr.b.Color(255,255,255),yellow:new tr.b.Color(255,255,0),olive:new tr.b.Color(100,100,0),rail_response:new tr.b.Color(67,135,253),rail_animation:new tr.b.Color(244,74,63),rail_idle:new tr.b.Color(238,142,0),rail_load:new tr.b.Color(13,168,97),startup:new tr.b.Color(230,230,0),heap_dump_stack_frame:new tr.b.Color(128,128,128),heap_dump_object_type:new tr.b.Color(0,0,255),heap_dump_child_node_arrow:new tr.b.Color(204,102,0),cq_build_running:new tr.b.Color(255,255,119),cq_build_passed:new tr.b.Color(153,238,102),cq_build_failed:new tr.b.Color(238,136,136),cq_build_abandoned:new tr.b.Color(187,187,187),cq_build_attempt_runnig:new tr.b.Color(222,222,75),cq_build_attempt_passed:new tr.b.Color(103,218,35),cq_build_attempt_failed:new tr.b.Color(197,81,81)};const numGeneralPurposeColorIds=generalPurposeColors.length;const numReservedColorIds=Object.keys(reservedColorsByName).length;const numColorsPerVariant=numGeneralPurposeColorIds+numReservedColorIds;function ColorScheme(){}
+const paletteBase=[];paletteBase.push.apply(paletteBase,generalPurposeColors);paletteBase.push.apply(paletteBase,Object.values(reservedColorsByName));ColorScheme.colors=[];ColorScheme.properties={};ColorScheme.properties={numColorsPerVariant,};function pushVariant(func){const variantColors=paletteBase.map(func);ColorScheme.colors.push.apply(ColorScheme.colors,variantColors);}
+pushVariant(function(c){return c;});ColorScheme.properties.brightenedOffsets=[];ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.3,0.8);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.48,0.85);});ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.lighten(0.65,0.9);});ColorScheme.properties.dimmedOffsets=[];ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate();});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.5);});ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);pushVariant(function(c){return c.desaturate(0.3);});ColorScheme.colorsAsStrings=ColorScheme.colors.map(function(c){return c.toString();});const reservedColorNameToIdMap=(function(){const m=new Map();let i=generalPurposeColors.length;for(const key of Object.keys(reservedColorsByName)){m.set(key,i++);}
+return m;})();ColorScheme.getColorIdForReservedName=function(name){const id=reservedColorNameToIdMap.get(name);if(id===undefined){throw new Error('Unrecognized color '+name);}
+return id;};ColorScheme.getColorForReservedNameAsString=function(reservedName){const id=ColorScheme.getColorIdForReservedName(reservedName);return ColorScheme.colorsAsStrings[id];};ColorScheme.getStringHash=function(name){let hash=0;for(let i=0;i<name.length;++i){hash=(hash+37*hash+11*name.charCodeAt(i))%0xFFFFFFFF;}
+return hash;};const stringColorIdCache=new Map();ColorScheme.getColorIdForGeneralPurposeString=function(string){if(stringColorIdCache.get(string)===undefined){const hash=ColorScheme.getStringHash(string);stringColorIdCache.set(string,hash%numGeneralPurposeColorIds);}
+return stringColorIdCache.get(string);};ColorScheme.getAnotherColorId=function(colorId,n){return(colorId+n)%numColorsPerVariant;};ColorScheme.getVariantColorId=function(colorId,offset){return colorId+offset;};return{ColorScheme,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;function EventInfo(title,description,docLinks){this.title=title;this.description=description;this.docLinks=docLinks;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(title);}
+return{EventInfo,};});'use strict';tr.exportTo('tr.b',function(){let nextGUID=1;const UUID4_PATTERN='xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx';const GUID={allocateSimple(){return nextGUID++;},getLastSimpleGuid(){return nextGUID-1;},allocateUUID4(){return UUID4_PATTERN.replace(/[xy]/g,function(c){let r=parseInt(Math.random()*16);if(c==='y')r=(r&3)+8;return r.toString(16);});}};return{GUID,};});'use strict';tr.exportTo('tr.model',function(){function EventRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(EventRegistry,options);EventRegistry.addEventListener('will-register',function(e){const metadata=e.typeInfo.metadata;if(metadata.name===undefined){throw new Error('Registered events must provide name metadata');}
 if(metadata.pluralName===undefined){throw new Error('Registered events must provide pluralName metadata');}
-if(metadata.subTypes===undefined){metadata.subTypes={};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=e.typeInfo.constructor;options.defaultConstructor=e.typeInfo.constructor;tr.b.decorateExtensionRegistry(metadata.subTypes,options);}else{if(!metadata.subTypes.register){throw new Error('metadata.subTypes must be an extension registry.');}}
-e.typeInfo.constructor.subTypes=metadata.subTypes;});var eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
-return eventsByTypeName[typeName];};EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){var result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
-EventRegistry.getUserFriendlySingularName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){var typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);var str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry,};});'use strict';tr.exportTo('tr.model',function(){var EventRegistry=tr.model.EventRegistry;var RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_=new tr.b.math.Range();this.events_=new Set();this.guid_=tr.b.GUID.allocateSimple();if(opt_events){if(opt_events instanceof Array){for(var event of opt_events){this.push(event);}}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
-EventSet.prototype={__proto__:Object.prototype,get bounds(){return this.bounds_;},get duration(){if(this.bounds_.isEmpty)return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.events_.size;},get guid(){return this.guid_;},*[Symbol.iterator](){for(var event of this.events_){yield event;}},clear:function(){this.bounds_=new tr.b.math.Range();this.events_.clear();},push:function(...events){var numPushed;for(var event of events){if(event.guid===undefined){throw new Error('Event must have a GUID');}
+if(metadata.subTypes===undefined){metadata.subTypes={};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=e.typeInfo.constructor;options.defaultConstructor=e.typeInfo.constructor;tr.b.decorateExtensionRegistry(metadata.subTypes,options);}else{if(!metadata.subTypes.register){throw new Error('metadata.subTypes must be an extension registry.');}}
+e.typeInfo.constructor.subTypes=metadata.subTypes;});let eventsByTypeName=undefined;EventRegistry.getEventTypeInfoByTypeName=function(typeName){if(eventsByTypeName===undefined){eventsByTypeName={};EventRegistry.getAllRegisteredTypeInfos().forEach(function(typeInfo){eventsByTypeName[typeInfo.metadata.name]=typeInfo;});}
+return eventsByTypeName[typeName];};EventRegistry.addEventListener('registry-changed',function(){eventsByTypeName=undefined;});function convertCamelCaseToTitleCase(name){let result=name.replace(/[A-Z]/g,' $&');result=result.charAt(0).toUpperCase()+result.slice(1);return result;}
+EventRegistry.getUserFriendlySingularName=function(typeName){const typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);const str=typeInfo.metadata.name;return convertCamelCaseToTitleCase(str);};EventRegistry.getUserFriendlyPluralName=function(typeName){const typeInfo=EventRegistry.getEventTypeInfoByTypeName(typeName);const str=typeInfo.metadata.pluralName;return convertCamelCaseToTitleCase(str);};return{EventRegistry,};});'use strict';tr.exportTo('tr.model',function(){const EventRegistry=tr.model.EventRegistry;const RequestSelectionChangeEvent=tr.b.Event.bind(undefined,'requestSelectionChange',true,false);function EventSet(opt_events){this.bounds_=new tr.b.math.Range();this.events_=new Set();this.guid_=tr.b.GUID.allocateSimple();if(opt_events){if(opt_events instanceof Array){for(const event of opt_events){this.push(event);}}else if(opt_events instanceof EventSet){this.addEventSet(opt_events);}else{this.push(opt_events);}}}
+EventSet.prototype={__proto__:Object.prototype,get bounds(){return this.bounds_;},get duration(){if(this.bounds_.isEmpty)return 0;return this.bounds_.max-this.bounds_.min;},get length(){return this.events_.size;},get guid(){return this.guid_;},*[Symbol.iterator](){for(const event of this.events_){yield event;}},clear(){this.bounds_=new tr.b.math.Range();this.events_.clear();},push(...events){let numPushed;for(const event of events){if(event.guid===undefined){throw new Error('Event must have a GUID');}
 if(!this.events_.has(event)){this.events_.add(event);if(event.addBoundsToRange){if(this.bounds_!==undefined){event.addBoundsToRange(this.bounds_);}}}
 numPushed++;}
-return numPushed;},contains:function(event){if(this.events_.has(event))return event;return undefined;},addEventSet:function(eventSet){for(var event of eventSet){this.push(event);}},intersectionIsEmpty:function(otherEventSet){return!this.some(event=>otherEventSet.contains(event));},equals:function(that){if(this.length!==that.length)return false;return this.every(event=>that.contains(event));},sortEvents:function(compare){var ary=this.toArray();ary.sort(compare);this.clear();for(var event of ary){this.push(event);}},getEventsOrganizedByBaseType:function(opt_pruneEmpty){var allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();var events=this.getEventsOrganizedByCallback(function(event){var maxEventIndex=-1;var maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex===-1){throw new Error(`Unrecognized event type:${event.constructor.name}`);}
+return numPushed;},contains(event){if(this.events_.has(event))return event;return undefined;},addEventSet(eventSet){for(const event of eventSet){this.push(event);}},intersectionIsEmpty(otherEventSet){return!this.some(event=>otherEventSet.contains(event));},equals(that){if(this.length!==that.length)return false;return this.every(event=>that.contains(event));},sortEvents(compare){const ary=this.toArray();ary.sort(compare);this.clear();for(const event of ary){this.push(event);}},getEventsOrganizedByBaseType(opt_pruneEmpty){const allTypeInfos=EventRegistry.getAllRegisteredTypeInfos();const events=this.getEventsOrganizedByCallback(function(event){let maxEventIndex=-1;let maxEventTypeInfo=undefined;allTypeInfos.forEach(function(eventTypeInfo,eventIndex){if(!(event instanceof eventTypeInfo.constructor))return;if(eventIndex>maxEventIndex){maxEventIndex=eventIndex;maxEventTypeInfo=eventTypeInfo;}});if(maxEventIndex===-1){throw new Error(`Unrecognized event type: ${event.constructor.name}`);}
 return maxEventTypeInfo.metadata.name;});if(!opt_pruneEmpty){allTypeInfos.forEach(function(eventTypeInfo){if(events[eventTypeInfo.metadata.name]===undefined){events[eventTypeInfo.metadata.name]=new EventSet();}});}
-return events;},getEventsOrganizedByTitle:function(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined){throw new Error('An event didn\'t have a title!');}
-return event.title;});},getEventsOrganizedByCallback:function(cb,opt_this){var groupedEvents=tr.b.group(this,cb,opt_this||this);return tr.b.mapItems(groupedEvents,(_,events)=>new EventSet(events));},enumEventsOfType:function(type,func){for(var event of this){if(event instanceof type){func(event);}}},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
-var eventsByBaseType=this.getEventsOrganizedByBaseType(true);var eventTypeName=Object.keys(eventsByBaseType)[0];if(this.length===1){var tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return tr.b.getOnlyElement(this.events_).userFriendlyName;}
-var numEventTypes=tr.b.dictionaryLength(eventsByBaseType);if(numEventTypes!==1){return this.length+' events of various types';}
-var tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter:function(fn,opt_this){var res=new EventSet();for(var event of this){if(fn.call(opt_this,event)){res.push(event);}}
-return res;},toArray:function(){var ary=[];for(var event of this){ary.push(event);}
-return ary;},forEach:function(fn,opt_this){for(var event of this){fn.call(opt_this,event);}},map:function(fn,opt_this){var res=[];for(var event of this){res.push(fn.call(opt_this,event));}
-return res;},every:function(fn,opt_this){for(var event of this){if(!fn.call(opt_this,event)){return false;}}
-return true;},some:function(fn,opt_this){for(var event of this){if(fn.call(opt_this,event)){return true;}}
-return false;},asDict:function(){var stableIds=[];for(var event of this){stableIds.push(event.stableId);}
-return{'events':stableIds};},asSet:function(){return this.events_;}};EventSet.IMMUTABLE_EMPTY_SET=(function(){var s=new EventSet();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet,RequestSelectionChangeEvent,};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};var brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];};var dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];};return{SelectionState,};});'use strict';tr.exportTo('tr.model',function(){var SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
-SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection:function(selection){var modelItem=this.modelItem_;if(!modelItem)return;selection.push(modelItem);},addToTrackMap:function(eventToTrackMap,track){var modelItem=this.modelItem_;if(!modelItem)return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem,};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;var IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocateSimple();this.selectionState=SelectionState.NONE;this.info=undefined;}
-Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},get range(){var range=new tr.b.math.Range();this.addBoundsToRange(range);return range;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert:function(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET){this.associatedAlerts=new tr.model.EventSet();}
-this.associatedAlerts.push(alert);},addBoundsToRange:function(range){}};return{Event,};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;this.contexts=Object.freeze([]);}
-TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);},bounds:function(that,opt_precisionUnit){if(opt_precisionUnit===undefined){opt_precisionUnit=tr.b.TimeDisplayModes.ms;}
-var startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);var endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent,};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
+return events;},getEventsOrganizedByTitle(){return this.getEventsOrganizedByCallback(function(event){if(event.title===undefined){throw new Error('An event didn\'t have a title!');}
+return event.title;});},getEventsOrganizedByCallback(cb,opt_this){const groupedEvents=tr.b.groupIntoMap(this,cb,opt_this||this);const groupedEventsDict={};for(const[k,events]of groupedEvents){groupedEventsDict[k]=new EventSet(events);}
+return groupedEventsDict;},enumEventsOfType(type,func){for(const event of this){if(event instanceof type){func(event);}}},get userFriendlyName(){if(this.length===0){throw new Error('Empty event set');}
+const eventsByBaseType=this.getEventsOrganizedByBaseType(true);const eventTypeName=Object.keys(eventsByBaseType)[0];if(this.length===1){const tmp=EventRegistry.getUserFriendlySingularName(eventTypeName);return tr.b.getOnlyElement(this.events_).userFriendlyName;}
+const numEventTypes=Object.keys(eventsByBaseType).length;if(numEventTypes!==1){return this.length+' events of various types';}
+const tmp=EventRegistry.getUserFriendlyPluralName(eventTypeName);return this.length+' '+tmp;},filter(fn,opt_this){const res=new EventSet();for(const event of this){if(fn.call(opt_this,event)){res.push(event);}}
+return res;},toArray(){const ary=[];for(const event of this){ary.push(event);}
+return ary;},forEach(fn,opt_this){for(const event of this){fn.call(opt_this,event);}},map(fn,opt_this){const res=[];for(const event of this){res.push(fn.call(opt_this,event));}
+return res;},every(fn,opt_this){for(const event of this){if(!fn.call(opt_this,event)){return false;}}
+return true;},some(fn,opt_this){for(const event of this){if(fn.call(opt_this,event)){return true;}}
+return false;},asDict(){const stableIds=[];for(const event of this){stableIds.push(event.stableId);}
+return{'events':stableIds};},asSet(){return this.events_;}};EventSet.IMMUTABLE_EMPTY_SET=(function(){const s=new EventSet();s.push=function(){throw new Error('Cannot push to an immutable event set');};s.addEventSet=function(){throw new Error('Cannot add to an immutable event set');};Object.freeze(s);return s;})();return{EventSet,RequestSelectionChangeEvent,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const SelectionState={NONE:0,SELECTED:ColorScheme.properties.brightenedOffsets[0],HIGHLIGHTED:ColorScheme.properties.brightenedOffsets[1],DIMMED:ColorScheme.properties.dimmedOffsets[0],BRIGHTENED0:ColorScheme.properties.brightenedOffsets[0],BRIGHTENED1:ColorScheme.properties.brightenedOffsets[1],BRIGHTENED2:ColorScheme.properties.brightenedOffsets[2],DIMMED0:ColorScheme.properties.dimmedOffsets[0],DIMMED1:ColorScheme.properties.dimmedOffsets[1],DIMMED2:ColorScheme.properties.dimmedOffsets[2]};const brighteningLevels=[SelectionState.NONE,SelectionState.BRIGHTENED0,SelectionState.BRIGHTENED1,SelectionState.BRIGHTENED2];SelectionState.getFromBrighteningLevel=function(level){return brighteningLevels[level];};const dimmingLevels=[SelectionState.DIMMED0,SelectionState.DIMMED1,SelectionState.DIMMED2];SelectionState.getFromDimmingLevel=function(level){return dimmingLevels[level];};return{SelectionState,};});'use strict';tr.exportTo('tr.model',function(){const SelectionState=tr.model.SelectionState;function SelectableItem(modelItem){this.modelItem_=modelItem;}
+SelectableItem.prototype={get modelItem(){return this.modelItem_;},get selected(){return this.selectionState===SelectionState.SELECTED;},addToSelection(selection){const modelItem=this.modelItem_;if(!modelItem)return;selection.push(modelItem);},addToTrackMap(eventToTrackMap,track){const modelItem=this.modelItem_;if(!modelItem)return;eventToTrackMap.addEvent(modelItem,track);}};return{SelectableItem,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;const IMMUTABLE_EMPTY_SET=tr.model.EventSet.IMMUTABLE_EMPTY_SET;function Event(){SelectableItem.call(this,this);this.guid_=tr.b.GUID.allocateSimple();this.selectionState=SelectionState.NONE;this.info=undefined;}
+Event.prototype={__proto__:SelectableItem.prototype,get guid(){return this.guid_;},get stableId(){return undefined;},get range(){const range=new tr.b.math.Range();this.addBoundsToRange(range);return range;},associatedAlerts:IMMUTABLE_EMPTY_SET,addAssociatedAlert(alert){if(this.associatedAlerts===IMMUTABLE_EMPTY_SET){this.associatedAlerts=new tr.model.EventSet();}
+this.associatedAlerts.push(alert);},addBoundsToRange(range){}};return{Event,};});'use strict';tr.exportTo('tr.model',function(){function TimedEvent(start){tr.model.Event.call(this);this.start=start;this.duration=0;this.cpuStart=undefined;this.cpuDuration=undefined;this.contexts=Object.freeze([]);}
+TimedEvent.prototype={__proto__:tr.model.Event.prototype,get end(){return this.start+this.duration;},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);},bounds(that,opt_precisionUnit){if(opt_precisionUnit===undefined){opt_precisionUnit=tr.b.TimeDisplayModes.ms;}
+const startsBefore=opt_precisionUnit.roundedLess(that.start,this.start);const endsAfter=opt_precisionUnit.roundedLess(this.end,that.end);return!startsBefore&&!endsAfter;}};return{TimedEvent,};});'use strict';tr.exportTo('tr.model',function(){function Alert(info,start,opt_associatedEvents,opt_args){tr.model.TimedEvent.call(this,start);this.info=info;this.args=opt_args||{};this.associatedEvents=new tr.model.EventSet(opt_associatedEvents);this.associatedEvents.forEach(function(event){event.addAssociatedAlert(this);},this);}
 Alert.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.info.title;},get colorId(){return this.info.colorId;},get userFriendlyName(){return'Alert '+this.title+' at '+
-tr.b.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts'});return{Alert,};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.math.Statistics;var FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;}
-Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward:function(amount){this.start+=amount;this.end+=amount;for(var i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames'});return{Frame,FRAME_PERF_CLASS,};});'use strict';tr.exportTo('tr.b.math',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length===0)return 1;var low=0;var high=ary.length-1;var i;var comparison;var hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
+tr.b.Unit.byName.timeStampInMs.format(this.start);}};tr.model.EventRegistry.register(Alert,{name:'alert',pluralName:'alerts'});return{Alert,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const Statistics=tr.b.math.Statistics;const FRAME_PERF_CLASS={GOOD:'good',BAD:'bad',TERRIBLE:'terrible',NEUTRAL:'generic_work'};function Frame(associatedEvents,threadTimeRanges,opt_args){tr.model.Event.call(this);this.threadTimeRanges=threadTimeRanges;this.associatedEvents=new tr.model.EventSet(associatedEvents);this.args=opt_args||{};this.title='Frame';this.start=Statistics.min(threadTimeRanges,function(x){return x.start;});this.end=Statistics.max(threadTimeRanges,function(x){return x.end;});this.totalDuration=Statistics.sum(threadTimeRanges,function(x){return x.end-x.start;});this.perfClass=FRAME_PERF_CLASS.NEUTRAL;}
+Frame.prototype={__proto__:tr.model.Event.prototype,set perfClass(perfClass){this.colorId=ColorScheme.getColorIdForReservedName(perfClass);this.perfClass_=perfClass;},get perfClass(){return this.perfClass_;},shiftTimestampsForward(amount){this.start+=amount;this.end+=amount;for(let i=0;i<this.threadTimeRanges.length;i++){this.threadTimeRanges[i].start+=amount;this.threadTimeRanges[i].end+=amount;}},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);}};tr.model.EventRegistry.register(Frame,{name:'frame',pluralName:'frames'});return{Frame,FRAME_PERF_CLASS,};});'use strict';tr.exportTo('tr.b.math',function(){function findLowIndexInSortedArray(ary,mapFn,loVal){if(ary.length===0)return 1;let low=0;let high=ary.length-1;let i;let comparison;let hitPos=-1;while(low<=high){i=Math.floor((low+high)/2);comparison=mapFn(ary[i])-loVal;if(comparison<0){low=i+1;continue;}else if(comparison>0){high=i-1;continue;}else{hitPos=i;high=i-1;}}
 return hitPos!==-1?hitPos:low;}
-function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){var lo=loVal||0;var hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){var mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0){lo=mid+1;}else{hi=mid;}}
+function findHighIndexInSortedArray(ary,mapFn,loVal,hiVal){let lo=loVal||0;let hi=hiVal!==undefined?hiVal:ary.length;while(lo<hi){const mid=(lo+hi)>>1;if(mapFn(ary[mid])>=0){lo=mid+1;}else{hi=mid;}}
 return hi;}
-function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){var first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first===0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}
+function findIndexInSortedIntervals(ary,mapLoFn,mapWidthFn,loVal){const first=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(first===0){if(loVal>=mapLoFn(ary[0])&&loVal<mapLoFn(ary[0])+mapWidthFn(ary[0],0)){return 0;}
 return-1;}
 if(first<ary.length){if(loVal>=mapLoFn(ary[first])&&loVal<mapLoFn(ary[first])+mapWidthFn(ary[first],first)){return first;}
 if(loVal>=mapLoFn(ary[first-1])&&loVal<mapLoFn(ary[first-1])+
@@ -4411,7 +4494,7 @@
 mapWidthFn(ary[first-1],first-1)){return first-1;}
 return ary.length;}
 return ary.length;}
-function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){var i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}
+function findIndexInSortedClosedIntervals(ary,mapLoFn,mapHiFn,val){const i=findLowIndexInSortedArray(ary,mapLoFn,val);if(i===0){if(val>=mapLoFn(ary[0],0)&&val<=mapHiFn(ary[0],0)){return 0;}
 return-1;}
 if(i<ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}
 if(val>=mapLoFn(ary[i],i)&&val<=mapHiFn(ary[i],i)){return i;}
@@ -4419,465 +4502,446 @@
 if(i===ary.length){if(val>=mapLoFn(ary[i-1],i-1)&&val<=mapHiFn(ary[i-1],i-1)){return i-1;}
 return ary.length;}
 return ary.length;}
-function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length===0)return;if(loVal>hiVal)return;var i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i===-1){return;}
-if(i>0){var hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
+function iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,cb){if(ary.length===0)return;if(loVal>hiVal)return;let i=findLowIndexInSortedArray(ary,mapLoFn,loVal);if(i===-1){return;}
+if(i>0){const hi=mapLoFn(ary[i-1])+mapWidthFn(ary[i-1],i-1);if(hi>=loVal){cb(ary[i-1],i-1);}}
 if(i===ary.length){return;}
-for(var n=ary.length;i<n;i++){var lo=mapLoFn(ary[i]);if(lo>=hiVal)break;cb(ary[i],i);}}
-function getIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal){var tmp=[];iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,function(d){tmp.push(d);});return tmp;}
-function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)return null;var aftIdx=findLowIndexInSortedArray(ary,mapFn,val);var befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)aftIdx-=1;var befDiff=Math.abs(val-mapFn(ary[befIdx]));var aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)return null;var idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
-function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)return null;var idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)idx-=1;var hiInt=ary[idx];var loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length){loInt=ary[idx+1];}
-var loDiff=Math.abs(val-mapLoFn(loInt));var hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)return null;if(loDiff<hiDiff)return loInt;return hiInt;}
-return{findLowIndexInSortedArray,findHighIndexInSortedArray,findIndexInSortedIntervals,findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals,getIntersectingIntervals,findClosestElementInSortedArray,findClosestIntervalInSortedIntervals,};});'use strict';tr.exportTo('tr.model.helpers',function(){var Frame=tr.model.Frame;var Statistics=tr.b.math.Statistics;var UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};var UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};var RENDER_THREAD_DRAW_NAME='DrawFrame';var RENDER_THREAD_INDEP_DRAW_NAME='doFrame';var RENDER_THREAD_QUEUE_NAME='queueBuffer';var RENDER_THREAD_SWAP_NAME='eglSwapBuffers';var THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){var ret=[];threadTimeRanges.forEach(function(threadTimeRange){var slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
-function makeFrame(threadTimeRanges,surfaceFlinger){var args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){var start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args['deadline']=surfaceFlinger.getFrameDeadline(start);args['frameKickoff']=surfaceFlinger.getFrameKickoff(start);}
-var events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
-function findOverlappingDrawFrame(renderThread,uiDrawSlice){if(!renderThread)return undefined;var overlappingDrawFrame;var slices=tr.b.math.iterateOverIntersectingIntervals(renderThread.sliceGroup.slices,function(range){return range.start;},function(range){return range.end;},uiDrawSlice.start,uiDrawSlice.end,function(rtDrawSlice){if(rtDrawSlice.title===RENDER_THREAD_DRAW_NAME){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice&&rtSyncSlice.start>=uiDrawSlice.start&&rtSyncSlice.end<=uiDrawSlice.end){overlappingDrawFrame=rtDrawSlice;}}});return overlappingDrawFrame;}
-function getPreTraversalWorkRanges(uiThread){if(!uiThread)return[];var preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title==='obtainView'||slice.title==='setupListItem'||slice.title==='deliverInputEvent'||slice.title==='RV Scroll'){preFrameEvents.push(slice);}});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title==='deliverInputEvent'){preFrameEvents.push(slice);}});return tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
-function getFrameStartTime(traversalStart,preTraversalWorkRanges){var preTraversalWorkRange=tr.b.math.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start;},function(range){return range.end;},traversalStart,3);if(preTraversalWorkRange){return preTraversalWorkRange.start;}
+for(let n=ary.length;i<n;i++){const lo=mapLoFn(ary[i]);if(lo>=hiVal)break;cb(ary[i],i);}}
+function getIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal){const tmp=[];iterateOverIntersectingIntervals(ary,mapLoFn,mapWidthFn,loVal,hiVal,function(d){tmp.push(d);});return tmp;}
+function findClosestElementInSortedArray(ary,mapFn,val,maxDiff){if(ary.length===0)return null;let aftIdx=findLowIndexInSortedArray(ary,mapFn,val);const befIdx=aftIdx>0?aftIdx-1:0;if(aftIdx===ary.length)aftIdx-=1;const befDiff=Math.abs(val-mapFn(ary[befIdx]));const aftDiff=Math.abs(val-mapFn(ary[aftIdx]));if(befDiff>maxDiff&&aftDiff>maxDiff)return null;const idx=befDiff<aftDiff?befIdx:aftIdx;return ary[idx];}
+function findClosestIntervalInSortedIntervals(ary,mapLoFn,mapHiFn,val,maxDiff){if(ary.length===0)return null;let idx=findLowIndexInSortedArray(ary,mapLoFn,val);if(idx>0)idx-=1;const hiInt=ary[idx];let loInt=hiInt;if(val>mapHiFn(hiInt)&&idx+1<ary.length){loInt=ary[idx+1];}
+const loDiff=Math.abs(val-mapLoFn(loInt));const hiDiff=Math.abs(val-mapHiFn(hiInt));if(loDiff>maxDiff&&hiDiff>maxDiff)return null;if(loDiff<hiDiff)return loInt;return hiInt;}
+return{findLowIndexInSortedArray,findHighIndexInSortedArray,findIndexInSortedIntervals,findIndexInSortedClosedIntervals,iterateOverIntersectingIntervals,getIntersectingIntervals,findClosestElementInSortedArray,findClosestIntervalInSortedIntervals,};});'use strict';tr.exportTo('tr.model.helpers',function(){const Frame=tr.model.Frame;const Statistics=tr.b.math.Statistics;const UI_DRAW_TYPE={NONE:'none',LEGACY:'legacy',MARSHMALLOW:'marshmallow'};const UI_THREAD_DRAW_NAMES={'performTraversals':UI_DRAW_TYPE.LEGACY,'Choreographer#doFrame':UI_DRAW_TYPE.MARSHMALLOW};const RENDER_THREAD_DRAW_NAME='DrawFrame';const RENDER_THREAD_INDEP_DRAW_NAME='doFrame';const RENDER_THREAD_QUEUE_NAME='queueBuffer';const RENDER_THREAD_SWAP_NAME='eglSwapBuffers';const THREAD_SYNC_NAME='syncFrameState';function getSlicesForThreadTimeRanges(threadTimeRanges){const ret=[];threadTimeRanges.forEach(function(threadTimeRange){const slices=[];threadTimeRange.thread.sliceGroup.iterSlicesInTimeRange(function(slice){slices.push(slice);},threadTimeRange.start,threadTimeRange.end);ret.push.apply(ret,slices);});return ret;}
+function makeFrame(threadTimeRanges,surfaceFlinger){const args={};if(surfaceFlinger&&surfaceFlinger.hasVsyncs){const start=Statistics.min(threadTimeRanges,function(threadTimeRanges){return threadTimeRanges.start;});args.deadline=surfaceFlinger.getFrameDeadline(start);args.frameKickoff=surfaceFlinger.getFrameKickoff(start);}
+const events=getSlicesForThreadTimeRanges(threadTimeRanges);return new Frame(events,threadTimeRanges,args);}
+function findOverlappingDrawFrame(renderThread,uiDrawSlice){if(!renderThread)return undefined;let overlappingDrawFrame;const slices=tr.b.math.iterateOverIntersectingIntervals(renderThread.sliceGroup.slices,function(range){return range.start;},function(range){return range.end;},uiDrawSlice.start,uiDrawSlice.end,function(rtDrawSlice){if(rtDrawSlice.title===RENDER_THREAD_DRAW_NAME){const rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice&&rtSyncSlice.start>=uiDrawSlice.start&&rtSyncSlice.end<=uiDrawSlice.end){overlappingDrawFrame=rtDrawSlice;}}});return overlappingDrawFrame;}
+function getPreTraversalWorkRanges(uiThread){if(!uiThread)return[];const preFrameEvents=[];uiThread.sliceGroup.slices.forEach(function(slice){if(slice.title==='obtainView'||slice.title==='setupListItem'||slice.title==='deliverInputEvent'||slice.title==='RV Scroll'){preFrameEvents.push(slice);}});uiThread.asyncSliceGroup.slices.forEach(function(slice){if(slice.title==='deliverInputEvent'){preFrameEvents.push(slice);}});return tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(preFrameEvents),3,function(events){return{start:events[0].min,end:events[events.length-1].max};});}
+function getFrameStartTime(traversalStart,preTraversalWorkRanges){const preTraversalWorkRange=tr.b.math.findClosestIntervalInSortedIntervals(preTraversalWorkRanges,function(range){return range.start;},function(range){return range.end;},traversalStart,3);if(preTraversalWorkRange){return preTraversalWorkRange.start;}
 return traversalStart;}
-function getRtFrameEndTime(rtDrawSlice){var rtQueueSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_QUEUE_NAME);if(rtQueueSlice){return rtQueueSlice.end;}
-var rtSwapSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_SWAP_NAME);if(rtSwapSlice){return rtSwapSlice.end;}
+function getRtFrameEndTime(rtDrawSlice){const rtQueueSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_QUEUE_NAME);if(rtQueueSlice){return rtQueueSlice.end;}
+const rtSwapSlice=rtDrawSlice.findDescendentSlice(RENDER_THREAD_SWAP_NAME);if(rtSwapSlice){return rtSwapSlice.end;}
 return rtDrawSlice.end;}
-function getUiThreadDrivenFrames(app){if(!app.uiThread)return[];var preTraversalWorkRanges=[];if(app.uiDrawType===UI_DRAW_TYPE.LEGACY){preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);}
-var frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
-var threadTimeRanges=[];var uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);var rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice);if(rtDrawSlice){var rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
+function getUiThreadDrivenFrames(app){if(!app.uiThread)return[];let preTraversalWorkRanges=[];if(app.uiDrawType===UI_DRAW_TYPE.LEGACY){preTraversalWorkRanges=getPreTraversalWorkRanges(app.uiThread);}
+const frames=[];app.uiThread.sliceGroup.slices.forEach(function(slice){if(!(slice.title in UI_THREAD_DRAW_NAMES)){return;}
+const threadTimeRanges=[];const uiThreadTimeRange={thread:app.uiThread,start:getFrameStartTime(slice.start,preTraversalWorkRanges),end:slice.end};threadTimeRanges.push(uiThreadTimeRange);const rtDrawSlice=findOverlappingDrawFrame(app.renderThread,slice);if(rtDrawSlice){const rtSyncSlice=rtDrawSlice.findDescendentSlice(THREAD_SYNC_NAME);if(rtSyncSlice){uiThreadTimeRange.end=Math.min(uiThreadTimeRange.end,rtSyncSlice.start);}
 threadTimeRanges.push({thread:app.renderThread,start:rtDrawSlice.start,end:getRtFrameEndTime(rtDrawSlice)});}
 frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
-function getRenderThreadDrivenFrames(app){if(!app.renderThread)return[];var frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){var threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
+function getRenderThreadDrivenFrames(app){if(!app.renderThread)return[];const frames=[];app.renderThread.sliceGroup.getSlicesOfName(RENDER_THREAD_INDEP_DRAW_NAME).forEach(function(slice){const threadTimeRanges=[{thread:app.renderThread,start:slice.start,end:slice.end}];frames.push(makeFrame(threadTimeRanges,app.surfaceFlinger));});return frames;}
 function getUiDrawType(uiThread){if(!uiThread){return UI_DRAW_TYPE.NONE;}
-var slices=uiThread.sliceGroup.slices;for(var i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
+const slices=uiThread.sliceGroup.slices;for(let i=0;i<slices.length;i++){if(slices[i].title in UI_THREAD_DRAW_NAMES){return UI_THREAD_DRAW_NAMES[slices[i].title];}}
 return UI_DRAW_TYPE.NONE;}
-function getInputSamples(process){var samples=undefined;for(var counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries===1){samples=process.counters[counterName].series[0].samples;break;}}
-if(!samples)return[];var inputSamples=[];var lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
+function getInputSamples(process){let samples=undefined;for(const counterName in process.counters){if(/^android\.aq\:pending/.test(counterName)&&process.counters[counterName].numSeries===1){samples=process.counters[counterName].series[0].samples;break;}}
+if(!samples)return[];const inputSamples=[];let lastValue=0;samples.forEach(function(sample){if(sample.value>lastValue){inputSamples.push(sample);}
 lastValue=sample.value;});return inputSamples;}
-function getAnimationAsyncSlices(uiThread){if(!uiThread)return[];var slices=[];for(var slice of uiThread.asyncSliceGroup.getDescendantEvents()){if(/^animator\:/.test(slice.title)){slices.push(slice);}}
+function getAnimationAsyncSlices(uiThread){if(!uiThread)return[];const slices=[];for(const slice of uiThread.asyncSliceGroup.getDescendantEvents()){if(/^animator\:/.test(slice.title)){slices.push(slice);}}
 return slices;}
 function AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType){this.process=process;this.uiThread=uiThread;this.renderThread=renderThread;this.surfaceFlinger=surfaceFlinger;this.uiDrawType=uiDrawType;this.frames_=undefined;this.inputs_=undefined;}
-AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){var uiThread=process.getThread(process.pid);var uiDrawType=getUiDrawType(uiThread);if(uiDrawType===UI_DRAW_TYPE.NONE){uiThread=undefined;}
-var renderThreads=process.findAllThreadsNamed('RenderThread');var renderThread=(renderThreads.length===1?renderThreads[0]:undefined);if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames:function(){if(!this.frames_){var uiFrames=getUiThreadDrivenFrames(this);var rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end;});}
-return this.frames_;},getInputSamples:function(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
-return this.inputs_;},getAnimationAsyncSlices:function(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
-return this.animations_;}};return{AndroidApp,};});'use strict';tr.exportTo('tr.model.helpers',function(){var findLowIndexInSortedArray=tr.b.math.findLowIndexInSortedArray;var VSYNC_SF_NAME='android.VSYNC-sf';var VSYNC_APP_NAME='android.VSYNC-app';var VSYNC_FALLBACK_NAME='android.VSYNC';var TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){var vsync=process.counters[counterName];if(!vsync){vsync=process.counters[VSYNC_FALLBACK_NAME];}
+AndroidApp.createForProcessIfPossible=function(process,surfaceFlinger){let uiThread=process.getThread(process.pid);const uiDrawType=getUiDrawType(uiThread);if(uiDrawType===UI_DRAW_TYPE.NONE){uiThread=undefined;}
+const renderThreads=process.findAllThreadsNamed('RenderThread');const renderThread=(renderThreads.length===1?renderThreads[0]:undefined);if(uiThread||renderThread){return new AndroidApp(process,uiThread,renderThread,surfaceFlinger,uiDrawType);}};AndroidApp.prototype={getFrames(){if(!this.frames_){const uiFrames=getUiThreadDrivenFrames(this);const rtFrames=getRenderThreadDrivenFrames(this);this.frames_=uiFrames.concat(rtFrames);this.frames_.sort(function(a,b){a.end-b.end;});}
+return this.frames_;},getInputSamples(){if(!this.inputs_){this.inputs_=getInputSamples(this.process);}
+return this.inputs_;},getAnimationAsyncSlices(){if(!this.animations_){this.animations_=getAnimationAsyncSlices(this.uiThread);}
+return this.animations_;}};return{AndroidApp,};});'use strict';tr.exportTo('tr.model.helpers',function(){const findLowIndexInSortedArray=tr.b.math.findLowIndexInSortedArray;const VSYNC_SF_NAME='android.VSYNC-sf';const VSYNC_APP_NAME='android.VSYNC-app';const VSYNC_FALLBACK_NAME='android.VSYNC';const TIMESTAMP_FUDGE_MS=0.01;function getVsyncTimestamps(process,counterName){let vsync=process.counters[counterName];if(!vsync){vsync=process.counters[VSYNC_FALLBACK_NAME];}
 if(vsync&&vsync.numSeries===1&&vsync.numSamples>1){return vsync.series[0].timestamps;}
 return undefined;}
 function AndroidSurfaceFlinger(process,thread){this.process=process;this.thread=thread;this.appVsync_=undefined;this.sfVsync_=undefined;this.appVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_APP_NAME);this.sfVsyncTimestamps_=getVsyncTimestamps(process,VSYNC_SF_NAME);this.deadlineDelayMs_=this.appVsyncTimestamps_!==this.sfVsyncTimestamps_?5:TIMESTAMP_FUDGE_MS;}
-AndroidSurfaceFlinger.createForProcessIfPossible=function(process){var mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name)){return new AndroidSurfaceFlinger(process,mainThread);}
-var primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length===1){return new AndroidSurfaceFlinger(process,primaryThreads[0]);}
-return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff:function(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
-var firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline:function(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
-var firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+this.deadlineDelayMs_);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length){return undefined;}
-return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger,};});'use strict';tr.exportTo('tr.model.helpers',function(){var AndroidApp=tr.model.helpers.AndroidApp;var AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;var IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};var IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};var IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important){callback(slice);}});}
-function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;var processes=model.getAllProcesses();for(var i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
-model.getAllProcesses().forEach(function(process){var app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app){this.apps.push(app);}},this);}
-AndroidModelHelper.guid=tr.b.GUID.allocateSimple();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices:function(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
+AndroidSurfaceFlinger.createForProcessIfPossible=function(process){const mainThread=process.getThread(process.pid);if(mainThread&&mainThread.name&&/surfaceflinger/.test(mainThread.name)){return new AndroidSurfaceFlinger(process,mainThread);}
+const primaryThreads=process.findAllThreadsNamed('SurfaceFlinger');if(primaryThreads.length===1){return new AndroidSurfaceFlinger(process,primaryThreads[0]);}
+return undefined;};AndroidSurfaceFlinger.prototype={get hasVsyncs(){return!!this.appVsyncTimestamps_&&!!this.sfVsyncTimestamps_;},getFrameKickoff(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
+const firstGreaterIndex=findLowIndexInSortedArray(this.appVsyncTimestamps_,function(x){return x;},timestamp+TIMESTAMP_FUDGE_MS);if(firstGreaterIndex<1)return undefined;return this.appVsyncTimestamps_[firstGreaterIndex-1];},getFrameDeadline(timestamp){if(!this.hasVsyncs){throw new Error('cannot query vsync info without vsyncs');}
+const firstGreaterIndex=findLowIndexInSortedArray(this.sfVsyncTimestamps_,function(x){return x;},timestamp+this.deadlineDelayMs_);if(firstGreaterIndex>=this.sfVsyncTimestamps_.length){return undefined;}
+return this.sfVsyncTimestamps_[firstGreaterIndex];}};return{AndroidSurfaceFlinger,};});'use strict';tr.exportTo('tr.model.helpers',function(){const AndroidApp=tr.model.helpers.AndroidApp;const AndroidSurfaceFlinger=tr.model.helpers.AndroidSurfaceFlinger;const IMPORTANT_SURFACE_FLINGER_SLICES={'doComposition':true,'updateTexImage':true,'postFramebuffer':true};const IMPORTANT_UI_THREAD_SLICES={'Choreographer#doFrame':true,'performTraversals':true,'deliverInputEvent':true};const IMPORTANT_RENDER_THREAD_SLICES={'doFrame':true};function iterateImportantThreadSlices(thread,important,callback){if(!thread)return;thread.sliceGroup.slices.forEach(function(slice){if(slice.title in important){callback(slice);}});}
+function AndroidModelHelper(model){this.model=model;this.apps=[];this.surfaceFlinger=undefined;const processes=model.getAllProcesses();for(let i=0;i<processes.length&&!this.surfaceFlinger;i++){this.surfaceFlinger=AndroidSurfaceFlinger.createForProcessIfPossible(processes[i]);}
+model.getAllProcesses().forEach(function(process){const app=AndroidApp.createForProcessIfPossible(process,this.surfaceFlinger);if(app){this.apps.push(app);}},this);}
+AndroidModelHelper.guid=tr.b.GUID.allocateSimple();AndroidModelHelper.supportsModel=function(model){return true;};AndroidModelHelper.prototype={iterateImportantSlices(callback){if(this.surfaceFlinger){iterateImportantThreadSlices(this.surfaceFlinger.thread,IMPORTANT_SURFACE_FLINGER_SLICES,callback);}
 this.apps.forEach(function(app){iterateImportantThreadSlices(app.uiThread,IMPORTANT_UI_THREAD_SLICES,callback);iterateImportantThreadSlices(app.renderThread,IMPORTANT_RENDER_THREAD_SLICES,callback);});}};return{AndroidModelHelper,};});'use strict';tr.exportTo('tr.model',function(){function Slice(category,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){if(new.target){throw new Error('Can\'t instantiate pure virtual class Slice');}
 tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.inFlowEvents=[];this.outFlowEvents=[];this.subSlices=[];this.selfTime=undefined;this.cpuSelfTime=undefined;this.important=false;this.parentContainer=undefined;this.argsStripped=false;this.bind_id_=opt_bindId;this.parentSlice=undefined;this.isTopLevel=false;if(opt_duration!==undefined){this.duration=opt_duration;}
 if(opt_cpuStart!==undefined){this.cpuStart=opt_cpuStart;}
 if(opt_cpuDuration!==undefined){this.cpuDuration=opt_cpuDuration;}
 if(opt_argsStripped!==undefined){this.argsStripped=true;}}
 Slice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get userFriendlyName(){return'Slice '+this.title+' at '+
-tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
-parentSliceGroup.slices.indexOf(this);},get bindId(){return this.bind_id_;},findDescendentSlice:function(targetTitle){if(!this.subSlices){return undefined;}
-for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
-var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},get mostTopLevelSlice(){if(!this.parentSlice)return this;return this.parentSlice.mostTopLevelSlice;},getProcess:function(){var thread=this.parentContainer;if(thread&&thread.getProcess){return thread.getProcess();}
-return undefined;},get model(){var process=this.getProcess();if(process!==undefined){return this.getProcess().model;}
-return undefined;},findTopmostSlicesRelativeToThisSlice:function*(eventPredicate){if(eventPredicate(this)){yield this;return;}
-for(var s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},iterateAllSubsequentSlices:function(callback,opt_this){var parentStack=[];var started=false;var topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){var curSlice=parentStack.pop();if(started){callback.call(opt_this,curSlice);}else{started=(curSlice.guid===this.guid);}
-for(var i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){var res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},enumerateAllAncestors:function*(){let curSlice=this.parentSlice;while(curSlice){yield curSlice;curSlice=curSlice.parentSlice;}},get ancestorSlices(){return Array.from(this.enumerateAllAncestors());},iterateEntireHierarchy:function(callback,opt_this){var mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){var res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){var res=[];res.push(this);for(var aSlice of this.enumerateAllAncestors()){res.push(aSlice);}
-this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},enumerateAllDescendents:function*(){for(var slice of this.subSlices){yield slice;}
-for(var slice of this.subSlices){yield*slice.enumerateAllDescendents();}},get descendentSlices(){var res=[];for(var slice of this.enumerateAllDescendents()){res.push(slice);}
-return res;}};return{Slice,};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;var SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
-ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_:function(state){var getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice:function(){if(!this.cpuOnWhichThreadWasRunning)return undefined;var cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(var i=0;i<cpuSlices.length;i++){var cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)continue;if(cpuSlice.duration!==this.duration)continue;return cpuSlice;}
-return undefined;},getCpuSliceThatTookCpu:function(){if(this.cpuOnWhichThreadWasRunning)return undefined;var curIndex=this.thread.indexOfTimeSlice(this);var cpuSliceWhenLastRunning;while(curIndex>=0){var curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){const parentSliceGroup=this.parentContainer.sliceGroup;return parentSliceGroup.stableId+'.'+
+parentSliceGroup.slices.indexOf(this);},get bindId(){return this.bind_id_;},findDescendentSlice(targetTitle){if(!this.subSlices){return undefined;}
+for(let i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
+const slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},get mostTopLevelSlice(){if(!this.parentSlice)return this;return this.parentSlice.mostTopLevelSlice;},getProcess(){const thread=this.parentContainer;if(thread&&thread.getProcess){return thread.getProcess();}
+return undefined;},get model(){const process=this.getProcess();if(process!==undefined){return this.getProcess().model;}
+return undefined;},*findTopmostSlicesRelativeToThisSlice(eventPredicate){if(eventPredicate(this)){yield this;return;}
+for(const s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},iterateAllSubsequentSlices(callback,opt_this){const parentStack=[];let started=false;const topmostSlice=this.mostTopLevelSlice;parentStack.push(topmostSlice);while(parentStack.length!==0){const curSlice=parentStack.pop();if(started){callback.call(opt_this,curSlice);}else{started=(curSlice.guid===this.guid);}
+for(let i=curSlice.subSlices.length-1;i>=0;i--){parentStack.push(curSlice.subSlices[i]);}}},get subsequentSlices(){const res=[];this.iterateAllSubsequentSlices(function(subseqSlice){res.push(subseqSlice);});return res;},*enumerateAllAncestors(){let curSlice=this.parentSlice;while(curSlice){yield curSlice;curSlice=curSlice.parentSlice;}},get ancestorSlices(){return Array.from(this.enumerateAllAncestors());},iterateEntireHierarchy(callback,opt_this){const mostTopLevelSlice=this.mostTopLevelSlice;callback.call(opt_this,mostTopLevelSlice);mostTopLevelSlice.iterateAllSubsequentSlices(callback,opt_this);},get entireHierarchy(){const res=[];this.iterateEntireHierarchy(function(slice){res.push(slice);});return res;},get ancestorAndSubsequentSlices(){const res=[];res.push(this);for(const aSlice of this.enumerateAllAncestors()){res.push(aSlice);}
+this.iterateAllSubsequentSlices(function(sSlice){res.push(sSlice);});return res;},*enumerateAllDescendents(){for(const slice of this.subSlices){yield slice;}
+for(const slice of this.subSlices){yield*slice.enumerateAllDescendents();}},get descendentSlices(){const res=[];for(const slice of this.enumerateAllDescendents()){res.push(slice);}
+return res;}};return{Slice,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;const SCHEDULING_STATE={DEBUG:'Debug',EXIT_DEAD:'Exit Dead',RUNNABLE:'Runnable',RUNNING:'Running',SLEEPING:'Sleeping',STOPPED:'Stopped',TASK_DEAD:'Task Dead',UNINTR_SLEEP:'Uninterruptible Sleep',UNINTR_SLEEP_WAKE_KILL:'Uninterruptible Sleep | WakeKill',UNINTR_SLEEP_WAKING:'Uninterruptible Sleep | Waking',UNINTR_SLEEP_IO:'Uninterruptible Sleep - Block I/O',UNINTR_SLEEP_WAKE_KILL_IO:'Uninterruptible Sleep | WakeKill - Block I/O',UNINTR_SLEEP_WAKING_IO:'Uninterruptible Sleep | Waking - Block I/O',UNKNOWN:'UNKNOWN',WAKE_KILL:'Wakekill',WAKING:'Waking',ZOMBIE:'Zombie'};function ThreadTimeSlice(thread,schedulingState,cat,start,args,opt_duration){Slice.call(this,cat,schedulingState,this.getColorForState_(schedulingState),start,args,opt_duration);this.thread=thread;this.schedulingState=schedulingState;this.cpuOnWhichThreadWasRunning=undefined;}
+ThreadTimeSlice.prototype={__proto__:Slice.prototype,getColorForState_(state){const getColorIdForReservedName=tr.b.ColorScheme.getColorIdForReservedName;switch(state){case SCHEDULING_STATE.RUNNABLE:return getColorIdForReservedName('thread_state_runnable');case SCHEDULING_STATE.RUNNING:return getColorIdForReservedName('thread_state_running');case SCHEDULING_STATE.SLEEPING:return getColorIdForReservedName('thread_state_sleeping');case SCHEDULING_STATE.DEBUG:case SCHEDULING_STATE.EXIT_DEAD:case SCHEDULING_STATE.STOPPED:case SCHEDULING_STATE.TASK_DEAD:case SCHEDULING_STATE.UNINTR_SLEEP:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:case SCHEDULING_STATE.UNKNOWN:case SCHEDULING_STATE.WAKE_KILL:case SCHEDULING_STATE.WAKING:case SCHEDULING_STATE.ZOMBIE:return getColorIdForReservedName('thread_state_uninterruptible');case SCHEDULING_STATE.UNINTR_SLEEP_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO:case SCHEDULING_STATE.UNINTR_SLEEP_WAKING_IO:return getColorIdForReservedName('thread_state_iowait');default:return getColorIdForReservedName('thread_state_unknown');}},get analysisTypeName(){return'tr.ui.analysis.ThreadTimeSlice';},getAssociatedCpuSlice(){if(!this.cpuOnWhichThreadWasRunning)return undefined;const cpuSlices=this.cpuOnWhichThreadWasRunning.slices;for(let i=0;i<cpuSlices.length;i++){const cpuSlice=cpuSlices[i];if(cpuSlice.start!==this.start)continue;if(cpuSlice.duration!==this.duration)continue;return cpuSlice;}
+return undefined;},getCpuSliceThatTookCpu(){if(this.cpuOnWhichThreadWasRunning)return undefined;let curIndex=this.thread.indexOfTimeSlice(this);let cpuSliceWhenLastRunning;while(curIndex>=0){const curSlice=this.thread.timeSlices[curIndex];if(!curSlice.cpuOnWhichThreadWasRunning){curIndex--;continue;}
 cpuSliceWhenLastRunning=curSlice.getAssociatedCpuSlice();break;}
-if(!cpuSliceWhenLastRunning)return undefined;var cpu=cpuSliceWhenLastRunning.cpu;var indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);var nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001){return nextRunningSlice;}
-return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices'});return{ThreadTimeSlice,SCHEDULING_STATE,};});'use strict';tr.exportTo('tr.model',function(){var CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState,};});'use strict';tr.exportTo('tr.model.um',function(){var CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorType,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorType_=initiatorType;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
-var INITIATOR_TYPE={KEYBOARD:'Keyboard',MOUSE:'Mouse',MOUSE_WHEEL:'MouseWheel',TAP:'Tap',PINCH:'Pinch',FLING:'Fling',TOUCH:'Touch',SCROLL:'Scroll',CSS:'CSS',WEBGL:'WebGL',VIDEO:'Video'};UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState:function(selection){var cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this)){cess|=CompoundEventSelectionState.EVENT_SELECTED;}
+if(!cpuSliceWhenLastRunning)return undefined;const cpu=cpuSliceWhenLastRunning.cpu;const indexOfSliceOnCpuWhenLastRunning=cpu.indexOf(cpuSliceWhenLastRunning);const nextRunningSlice=cpu.slices[indexOfSliceOnCpuWhenLastRunning+1];if(!nextRunningSlice)return undefined;if(Math.abs(nextRunningSlice.start-cpuSliceWhenLastRunning.end)<0.00001){return nextRunningSlice;}
+return undefined;}};tr.model.EventRegistry.register(ThreadTimeSlice,{name:'threadTimeSlice',pluralName:'threadTimeSlices'});return{ThreadTimeSlice,SCHEDULING_STATE,};});'use strict';tr.exportTo('tr.model',function(){const CompoundEventSelectionState={NOT_SELECTED:0,EVENT_SELECTED:0x1,SOME_ASSOCIATED_EVENTS_SELECTED:0x2,ALL_ASSOCIATED_EVENTS_SELECTED:0x4,EVENT_AND_SOME_ASSOCIATED_SELECTED:0x1|0x2,EVENT_AND_ALL_ASSOCIATED_SELECTED:0x1|0x4};return{CompoundEventSelectionState,};});'use strict';tr.exportTo('tr.model.um',function(){const CompoundEventSelectionState=tr.model.CompoundEventSelectionState;function UserExpectation(parentModel,initiatorType,start,duration){tr.model.TimedEvent.call(this,start);this.associatedEvents=new tr.model.EventSet();this.duration=duration;this.initiatorType_=initiatorType;this.parentModel=parentModel;this.typeInfo_=undefined;this.sourceEvents=new tr.model.EventSet();}
+const INITIATOR_TYPE={KEYBOARD:'Keyboard',MOUSE:'Mouse',MOUSE_WHEEL:'MouseWheel',TAP:'Tap',PINCH:'Pinch',FLING:'Fling',TOUCH:'Touch',SCROLL:'Scroll',CSS:'CSS',WEBGL:'WebGL',VIDEO:'Video'};UserExpectation.prototype={__proto__:tr.model.TimedEvent.prototype,computeCompoundEvenSelectionState(selection){let cess=CompoundEventSelectionState.NOT_SELECTED;if(selection.contains(this)){cess|=CompoundEventSelectionState.EVENT_SELECTED;}
 if(this.associatedEvents.intersectionIsEmpty(selection)){return cess;}
-var allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained){cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;}else{cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;}
-return cess;},get associatedSamples(){var samples=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event instanceof tr.model.ThreadSlice){samples.addEventSet(event.overlappingSamples);}});return samples;},get userFriendlyName(){return this.title+' User Expectation at '+
+const allContained=this.associatedEvents.every(function(event){return selection.contains(event);});if(allContained){cess|=CompoundEventSelectionState.ALL_ASSOCIATED_EVENTS_SELECTED;}else{cess|=CompoundEventSelectionState.SOME_ASSOCIATED_EVENTS_SELECTED;}
+return cess;},get associatedSamples(){const samples=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event instanceof tr.model.ThreadSlice){samples.addEventSet(event.overlappingSamples);}});return samples;},get userFriendlyName(){return this.title+' User Expectation at '+
 tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){return('UserExpectation.'+this.guid);},get typeInfo(){if(!this.typeInfo_){this.typeInfo_=UserExpectation.subTypes.findTypeInfo(this.constructor);}
 if(!this.typeInfo_){throw new Error('Unregistered UserExpectation');}
 return this.typeInfo_;},get colorId(){return this.typeInfo.metadata.colorId;},get stageTitle(){return this.typeInfo.metadata.stageTitle;},get initiatorType(){return this.initiatorType_;},get title(){if(!this.initiatorType){return this.stageTitle;}
-return this.initiatorType+' '+this.stageTitle;},get totalCpuMs(){var cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}};var subTypes={};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(subTypes,options);subTypes.addEventListener('will-register',function(e){var metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
-if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'userExpectation',pluralName:'userExpectations',subTypes:subTypes});return{UserExpectation,INITIATOR_TYPE,};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
-ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.subTypes.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation,};});'use strict';tr.exportTo('tr.e.audits',function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var Auditor=tr.c.Auditor;var AndroidModelHelper=tr.model.helpers.AndroidModelHelper;var ColorScheme=tr.b.ColorScheme;var Statistics=tr.b.math.Statistics;var FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;var Alert=tr.model.Alert;var EventInfo=tr.model.EventInfo;var Scalar=tr.b.Scalar;var timeDurationInMs=tr.b.Unit.byName.timeDurationInMs;var EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
+return this.initiatorType+' '+this.stageTitle;},get totalCpuMs(){let cpuMs=0;this.associatedEvents.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}};const subTypes={};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(subTypes,options);subTypes.addEventListener('will-register',function(e){const metadata=e.typeInfo.metadata;if(metadata.stageTitle===undefined){throw new Error('Registered UserExpectations must provide '+'stageTitle');}
+if(metadata.colorId===undefined){throw new Error('Registered UserExpectations must provide '+'colorId');}});tr.model.EventRegistry.register(UserExpectation,{name:'userExpectation',pluralName:'userExpectations',subTypes});return{UserExpectation,INITIATOR_TYPE,};});'use strict';tr.exportTo('tr.model.um',function(){function ResponseExpectation(parentModel,initiatorTitle,start,duration,opt_isAnimationBegin){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.isAnimationBegin=opt_isAnimationBegin||false;}
+ResponseExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:ResponseExpectation};tr.model.um.UserExpectation.subTypes.register(ResponseExpectation,{stageTitle:'Response',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_response')});return{ResponseExpectation,};});'use strict';tr.exportTo('tr.e.audits',function(){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;const Auditor=tr.c.Auditor;const AndroidModelHelper=tr.model.helpers.AndroidModelHelper;const ColorScheme=tr.b.ColorScheme;const Statistics=tr.b.math.Statistics;const FRAME_PERF_CLASS=tr.model.FRAME_PERF_CLASS;const Alert=tr.model.Alert;const EventInfo=tr.model.EventInfo;const Scalar=tr.b.Scalar;const timeDurationInMs=tr.b.Unit.byName.timeDurationInMs;const EXPECTED_FRAME_TIME_MS=16.67;function getStart(e){return e.start;}
 function getDuration(e){return e.duration;}
 function getCpuDuration(e){return(e.cpuDuration!==undefined)?e.cpuDuration:e.duration;}
 function frameIsActivityStart(frame){return frame.associatedEvents.any(x=>x.title==='activityStart');}
-function frameMissedDeadline(frame){return frame.args['deadline']&&frame.args['deadline']<frame.end;}
+function frameMissedDeadline(frame){return frame.args.deadline&&frame.args.deadline<frame.end;}
 function DocLinkBuilder(){this.docLinks=[];}
-DocLinkBuilder.prototype={addAppVideo:function(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef:function(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build:function(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);var helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger){this.helper=helper;}}
-AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){var badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;var saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;var ret=[];var events=[];frame.associatedEvents.forEach(function(slice){var match=badAlphaRegEx.exec(slice.title);if(match){var args={'view name':match[1],'width':parseInt(match[3]),'height':parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title)){events.push(slice);}},this);if(events.length>ret.length){var unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});var clippedSeen=events.length-unclippedSeen;var earliestStart=Statistics.min(events,function(slice){return slice.start;});var args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
-return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){var uploadRegEx=/^Generate Path Texture$/;var events=frame.associatedEvents.filter(function(event){return event.title==='Generate Path Texture';});var start=Statistics.min(events,getStart);var duration=Statistics.sum(events,getDuration);if(duration<3)return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){var uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;var events=[];var start=Number.POSITIVE_INFINITY;var duration=0;var pixelsUploaded=0;frame.associatedEvents.forEach(function(event){var match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length===0||duration<3)return undefined;var mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';var args={'Pixels uploaded':mPixels,'Time spent':new Scalar(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title==='obtainView'||event.title==='setupListItem';});var duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;var hasInflation=false;for(var event of events){if(event.findDescendentSlice('inflate')){hasInflation=true;}}
-var start=Statistics.min(events,getStart);var args={'Time spent':new Scalar(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;var eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title==='measure'||event.title==='layout';});var duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){var slice=undefined;for(var event of frame.associatedEvents){if(event.title==='getDisplayList'||event.title==='Record View#draw()'){slice=event;break;}}
-if(!slice||getCpuDuration(slice)<3)return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new Scalar(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return event.title==='DVM Suspend'||event.title==='GC: Wait For Concurrent';});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){var events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});var blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)return undefined;var start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){var totalDuration=0;var totalStats={};for(var ttr of frame.threadTimeRanges){var stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);for(var[key,value]of Object.entries(stats)){if(!(key in totalStats)){totalStats[key]=0;}
+DocLinkBuilder.prototype={addAppVideo(name,videoId){this.docLinks.push({label:'Video Link',textContent:('Android Performance Patterns: '+name),href:'https://www.youtube.com/watch?list=PLWz5rJ2EKKc9CBxr3BVjPTPoDPLdPIFCE&v='+videoId});return this;},addDacRef(name,link){this.docLinks.push({label:'Doc Link',textContent:(name+' documentation'),href:'https://developer.android.com/reference/'+link});return this;},build(){return this.docLinks;}};function AndroidAuditor(model){Auditor.call(this,model);const helper=model.getOrCreateHelper(AndroidModelHelper);if(helper.apps.length||helper.surfaceFlinger){this.helper=helper;}}
+AndroidAuditor.viewAlphaAlertInfo_=new EventInfo('Inefficient View alpha usage','Setting an alpha between 0 and 1 has significant performance costs, if one of the fast alpha paths is not used.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('View#setAlpha()','android/view/View.html#setAlpha(float)').build());AndroidAuditor.saveLayerAlertInfo_=new EventInfo('Expensive rendering with Canvas#saveLayer()','Canvas#saveLayer() incurs extremely high rendering cost. They disrupt the rendering pipeline when drawn, forcing a flush of drawing content. Instead use View hardware layers, or static Bitmaps. This enables the offscreen buffers to be reused in between frames, and avoids the disruptive render target switch.',new DocLinkBuilder().addAppVideo('Hidden Cost of Transparency','wIy8g8yNhNk').addDacRef('Canvas#saveLayerAlpha()','android/graphics/Canvas.html#saveLayerAlpha(android.graphics.RectF, int, int)').build());AndroidAuditor.getSaveLayerAlerts_=function(frame){const badAlphaRegEx=/^(.+) alpha caused (unclipped )?saveLayer (\d+)x(\d+)$/;const saveLayerRegEx=/^(unclipped )?saveLayer (\d+)x(\d+)$/;const ret=[];const events=[];frame.associatedEvents.forEach(function(slice){const match=badAlphaRegEx.exec(slice.title);if(match){const args={'view name':match[1],'width':parseInt(match[3]),'height':parseInt(match[4])};ret.push(new Alert(AndroidAuditor.viewAlphaAlertInfo_,slice.start,[slice],args));}else if(saveLayerRegEx.test(slice.title)){events.push(slice);}},this);if(events.length>ret.length){const unclippedSeen=Statistics.sum(events,function(slice){return saveLayerRegEx.exec(slice.title)[1]?1:0;});const clippedSeen=events.length-unclippedSeen;const earliestStart=Statistics.min(events,function(slice){return slice.start;});const args={'Unclipped saveLayer count (especially bad!)':unclippedSeen,'Clipped saveLayer count':clippedSeen};events.push(frame);ret.push(new Alert(AndroidAuditor.saveLayerAlertInfo_,earliestStart,events,args));}
+return ret;};AndroidAuditor.pathAlertInfo_=new EventInfo('Path texture churn','Paths are drawn with a mask texture, so when a path is modified / newly drawn, that texture must be generated and uploaded to the GPU. Ensure that you cache paths between frames and do not unnecessarily call Path#reset(). You can cut down on this cost by sharing Path object instances between drawables/views.');AndroidAuditor.getPathAlert_=function(frame){const uploadRegEx=/^Generate Path Texture$/;const events=frame.associatedEvents.filter(function(event){return event.title==='Generate Path Texture';});const start=Statistics.min(events,getStart);const duration=Statistics.sum(events,getDuration);if(duration<3)return undefined;events.push(frame);return new Alert(AndroidAuditor.pathAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.uploadAlertInfo_=new EventInfo('Expensive Bitmap uploads','Bitmaps that have been modified / newly drawn must be uploaded to the GPU. Since this is expensive if the total number of pixels uploaded is large, reduce the amount of Bitmap churn in this animation/context, per frame.');AndroidAuditor.getUploadAlert_=function(frame){const uploadRegEx=/^Upload (\d+)x(\d+) Texture$/;const events=[];let start=Number.POSITIVE_INFINITY;let duration=0;let pixelsUploaded=0;frame.associatedEvents.forEach(function(event){const match=uploadRegEx.exec(event.title);if(match){events.push(event);start=Math.min(start,event.start);duration+=event.duration;pixelsUploaded+=parseInt(match[1])*parseInt(match[2]);}});if(events.length===0||duration<3)return undefined;const mPixels=(pixelsUploaded/1000000).toFixed(2)+' million';const args={'Pixels uploaded':mPixels,'Time spent':new Scalar(timeDurationInMs,duration)};events.push(frame);return new Alert(AndroidAuditor.uploadAlertInfo_,start,events,args);};AndroidAuditor.ListViewInflateAlertInfo_=new EventInfo('Inflation during ListView recycling','ListView item recycling involved inflating views. Ensure your Adapter#getView() recycles the incoming View, instead of constructing a new one.');AndroidAuditor.ListViewBindAlertInfo_=new EventInfo('Inefficient ListView recycling/rebinding','ListView recycling taking too much time per frame. Ensure your Adapter#getView() binds data efficiently.');AndroidAuditor.getListViewAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='obtainView'||event.title==='setupListItem';});const duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;let hasInflation=false;for(const event of events){if(event.findDescendentSlice('inflate')){hasInflation=true;}}
+const start=Statistics.min(events,getStart);const args={'Time spent':new Scalar(timeDurationInMs,duration)};args['ListView items '+(hasInflation?'inflated':'rebound')]=events.length/2;const eventInfo=hasInflation?AndroidAuditor.ListViewInflateAlertInfo_:AndroidAuditor.ListViewBindAlertInfo_;events.push(frame);return new Alert(eventInfo,start,events,args);};AndroidAuditor.measureLayoutAlertInfo_=new EventInfo('Expensive measure/layout pass','Measure/Layout took a significant time, contributing to jank. Avoid triggering layout during animations.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').build());AndroidAuditor.getMeasureLayoutAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='measure'||event.title==='layout';});const duration=Statistics.sum(events,getCpuDuration);if(events.length===0||duration<3)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.measureLayoutAlertInfo_,start,events,{'Time spent':new Scalar(timeDurationInMs,duration)});};AndroidAuditor.viewDrawAlertInfo_=new EventInfo('Long View#draw()','Recording the drawing commands of invalidated Views took a long time. Avoid significant work in View or Drawable custom drawing, especially allocations or drawing to Bitmaps.',new DocLinkBuilder().addAppVideo('Invalidations, Layouts, and Performance','we6poP0kw6E').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getViewDrawAlert_=function(frame){let slice=undefined;for(const event of frame.associatedEvents){if(event.title==='getDisplayList'||event.title==='Record View#draw()'){slice=event;break;}}
+if(!slice||getCpuDuration(slice)<3)return undefined;return new Alert(AndroidAuditor.viewDrawAlertInfo_,slice.start,[slice,frame],{'Time spent':new Scalar(timeDurationInMs,getCpuDuration(slice))});};AndroidAuditor.blockingGcAlertInfo_=new EventInfo('Blocking Garbage Collection','Blocking GCs are caused by object churn, and made worse by having large numbers of objects in the heap. Avoid allocating objects during animations/scrolling, and recycle Bitmaps to avoid triggering garbage collection.',new DocLinkBuilder().addAppVideo('Garbage Collection in Android','pzfzz50W5Uo').addAppVideo('Avoiding Allocations in onDraw()','HAK5acHQ53E').build());AndroidAuditor.getBlockingGcAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return event.title==='DVM Suspend'||event.title==='GC: Wait For Concurrent';});const blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<3)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.blockingGcAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.lockContentionAlertInfo_=new EventInfo('Lock contention','UI thread lock contention is caused when another thread holds a lock that the UI thread is trying to use. UI thread progress is blocked until the lock is released. Inspect locking done within the UI thread, and ensure critical sections are short.');AndroidAuditor.getLockContentionAlert_=function(frame){const events=frame.associatedEvents.filter(function(event){return/^Lock Contention on /.test(event.title);});const blockedDuration=Statistics.sum(events,getDuration);if(blockedDuration<1)return undefined;const start=Statistics.min(events,getStart);events.push(frame);return new Alert(AndroidAuditor.lockContentionAlertInfo_,start,events,{'Blocked duration':new Scalar(timeDurationInMs,blockedDuration)});};AndroidAuditor.schedulingAlertInfo_=new EventInfo('Scheduling delay','Work to produce this frame was descheduled for several milliseconds, contributing to jank. Ensure that code on the UI thread doesn\'t block on work being done on other threads, and that background threads (doing e.g. network or bitmap loading) are running at android.os.Process#THREAD_PRIORITY_BACKGROUND or lower so they are less likely to interrupt the UI thread. These background threads should show up with a priority number of 130 or higher in the scheduling section under the Kernel process.');AndroidAuditor.getSchedulingAlert_=function(frame){let totalDuration=0;const totalStats={};for(const ttr of frame.threadTimeRanges){const stats=ttr.thread.getSchedulingStatsForRange(ttr.start,ttr.end);for(const[key,value]of Object.entries(stats)){if(!(key in totalStats)){totalStats[key]=0;}
 totalStats[key]+=value;totalDuration+=value;}}
 if(!(SCHEDULING_STATE.RUNNING in totalStats)||totalDuration===0||totalDuration-totalStats[SCHEDULING_STATE.RUNNING]<3){return;}
-var args={};for(var[key,value]of Object.entries(totalStats)){if(key===SCHEDULING_STATE.RUNNABLE){key='Not scheduled, but runnable';}else if(key===SCHEDULING_STATE.UNINTR_SLEEP){key='Blocking I/O delay';}
-args[key]=new Scalar(timeDurationInMs,value);}
-return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_:function(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process===this.helper.surfaceFlinger.process){if(!process.name){process.name='SurfaceFlinger';}
+const args={};for(const[key,value]of Object.entries(totalStats)){let newKey=key;if(key===SCHEDULING_STATE.RUNNABLE){newKey='Not scheduled, but runnable';}else if(key===SCHEDULING_STATE.UNINTR_SLEEP){newKey='Blocking I/O delay';}
+args[newKey]=new Scalar(timeDurationInMs,value);}
+return new Alert(AndroidAuditor.schedulingAlertInfo_,frame.start,[frame],args);};AndroidAuditor.prototype={__proto__:Auditor.prototype,renameAndSort_(){this.model.kernel.important=false;this.model.getAllProcesses().forEach(function(process){if(this.helper.surfaceFlinger&&process===this.helper.surfaceFlinger.process){if(!process.name){process.name='SurfaceFlinger';}
 process.sortIndex=Number.NEGATIVE_INFINITY;process.important=false;return;}
-var uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name)){uiThread.name='a'+uiThread.name;}
+const uiThread=process.getThread(process.pid);if(!process.name&&uiThread&&uiThread.name){if(/^ndroid\./.test(uiThread.name)){uiThread.name='a'+uiThread.name;}
 process.name=uiThread.name;uiThread.name='UI Thread';}
-process.sortIndex=0;for(var tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid===thread.parent.pid){thread.sortIndex=-3;}
+process.sortIndex=0;for(const tid in process.threads){process.sortIndex-=process.threads[tid].sliceGroup.slices.length;}},this);this.model.getAllThreads().forEach(function(thread){if(thread.tid===thread.parent.pid){thread.sortIndex=-3;}
 if(thread.name==='RenderThread'){thread.sortIndex=-2;}
-if(/^hwuiTask/.test(thread.name)){thread.sortIndex=-1;}});},pushFramesAndJudgeJank_:function(){var badFramesObserved=0;var framesObserved=0;var surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){var portionBad=badFramesObserved/framesObserved;if(portionBad>0.3){this.model.faviconHue='red';}else if(portionBad>0.05){this.model.faviconHue='yellow';}else{this.model.faviconHue='green';}}},pushEventInfo_:function(){var appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread){appAnnotator.applyEventInfos(app.uiThread.sliceGroup);}
-if(app.renderThread){appAnnotator.applyEventInfos(app.renderThread.sliceGroup);}});},runAnnotate:function(){if(!this.helper)return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit:function(){if(!this.helper)return;var alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass===FRAME_PERF_CLASS.NEUTRAL||frame.perfClass===FRAME_PERF_CLASS.GOOD){return;}
-var alert=AndroidAuditor.getPathAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getUploadAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getListViewAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)alerts.push(alert);var alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords:function(){var events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords:function(){var inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});var mergerFunction=function(events){var ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);var inputRanges=inputSamples.map(function(sample){return tr.b.math.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.math.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup=new Map();this.titleParentLookup=new Map();this.build_();}
-AppAnnotator.prototype={build_:function(){var registerEventInfo=function(dict){this.titleInfoLookup.set(dict.title,new EventInfo(dict.title,dict.description,dict.docLinks));if(dict.parents){this.titleParentLookup.set(dict.title,dict.parents);}}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});var choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});var traversalParents=['Choreographer#doFrame','performTraversals'];var layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});var drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});var recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_:function(parentNames,slice){var checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)return true;return expectedParentNames.some(function(name){return parentNames.has(name);});};if(this.titleInfoLookup.has(slice.title)){if(checkExpectedParentNames(this.titleParentLookup.get(slice.title))){slice.info=this.titleInfoLookup.get(slice.title);}}
+if(/^hwuiTask/.test(thread.name)){thread.sortIndex=-1;}});},pushFramesAndJudgeJank_(){let badFramesObserved=0;let framesObserved=0;const surfaceFlinger=this.helper.surfaceFlinger;this.helper.apps.forEach(function(app){app.process.frames=app.getFrames();app.process.frames.forEach(function(frame){if(frame.totalDuration>EXPECTED_FRAME_TIME_MS*2){badFramesObserved+=2;frame.perfClass=FRAME_PERF_CLASS.TERRIBLE;}else if(frame.totalDuration>EXPECTED_FRAME_TIME_MS||frameMissedDeadline(frame)){badFramesObserved++;frame.perfClass=FRAME_PERF_CLASS.BAD;}else{frame.perfClass=FRAME_PERF_CLASS.GOOD;}});framesObserved+=app.process.frames.length;});if(framesObserved){const portionBad=badFramesObserved/framesObserved;if(portionBad>0.3){this.model.faviconHue='red';}else if(portionBad>0.05){this.model.faviconHue='yellow';}else{this.model.faviconHue='green';}}},pushEventInfo_(){const appAnnotator=new AppAnnotator();this.helper.apps.forEach(function(app){if(app.uiThread){appAnnotator.applyEventInfos(app.uiThread.sliceGroup);}
+if(app.renderThread){appAnnotator.applyEventInfos(app.renderThread.sliceGroup);}});},runAnnotate(){if(!this.helper)return;this.renameAndSort_();this.pushFramesAndJudgeJank_();this.pushEventInfo_();this.helper.iterateImportantSlices(function(slice){slice.important=true;});},runAudit(){if(!this.helper)return;const alerts=this.model.alerts;this.helper.apps.forEach(function(app){app.getFrames().forEach(function(frame){alerts.push.apply(alerts,AndroidAuditor.getSaveLayerAlerts_(frame));if(frame.perfClass===FRAME_PERF_CLASS.NEUTRAL||frame.perfClass===FRAME_PERF_CLASS.GOOD){return;}
+let alert=AndroidAuditor.getPathAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getUploadAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getListViewAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getMeasureLayoutAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getViewDrawAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getBlockingGcAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getLockContentionAlert_(frame);if(alert)alerts.push(alert);alert=AndroidAuditor.getSchedulingAlert_(frame);if(alert)alerts.push(alert);});},this);this.addRenderingInteractionRecords();this.addInputInteractionRecords();},addRenderingInteractionRecords(){const events=[];this.helper.apps.forEach(function(app){events.push.apply(events,app.getAnimationAsyncSlices());events.push.apply(events,app.getFrames());});const mergerFunction=function(events){const ir=new tr.model.um.ResponseExpectation(this.model,'Rendering',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);tr.b.math.mergeRanges(tr.b.math.convertEventsToRanges(events),30,mergerFunction);},addInputInteractionRecords(){const inputSamples=[];this.helper.apps.forEach(function(app){inputSamples.push.apply(inputSamples,app.getInputSamples());});const mergerFunction=function(events){const ir=new tr.model.um.ResponseExpectation(this.model,'Input',events[0].min,events[events.length-1].max-events[0].min);this.model.userModel.expectations.push(ir);}.bind(this);const inputRanges=inputSamples.map(function(sample){return tr.b.math.Range.fromExplicitRange(sample.timestamp,sample.timestamp);});tr.b.math.mergeRanges(inputRanges,30,mergerFunction);}};Auditor.register(AndroidAuditor);function AppAnnotator(){this.titleInfoLookup=new Map();this.titleParentLookup=new Map();this.build_();}
+AppAnnotator.prototype={build_(){const registerEventInfo=function(dict){this.titleInfoLookup.set(dict.title,new EventInfo(dict.title,dict.description,dict.docLinks));if(dict.parents){this.titleParentLookup.set(dict.title,dict.parents);}}.bind(this);registerEventInfo({title:'inflate',description:'Constructing a View hierarchy from pre-processed XML via LayoutInflater#layout. This includes constructing all of the View objects in the hierarchy, and applying styled attributes.'});registerEventInfo({title:'obtainView',description:'Adapter#getView() called to bind content to a recycled View that is being presented.'});registerEventInfo({title:'setupListItem',description:'Attached a newly-bound, recycled View to its parent ListView.'});registerEventInfo({title:'setupGridItem',description:'Attached a newly-bound, recycled View to its parent GridView.'});const choreographerLinks=new DocLinkBuilder().addDacRef('Choreographer','android/view/Choreographer.html').build();registerEventInfo({title:'Choreographer#doFrame',docLinks:choreographerLinks,description:'Choreographer executes frame callbacks for inputs, animations, and rendering traversals. When this work is done, a frame will be presented to the user.'});registerEventInfo({title:'input',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Input callbacks are processed. This generally encompasses dispatching input to Views, as well as any work the Views do to process this input/gesture.'});registerEventInfo({title:'animation',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Animation callbacks are processed. This is generally minimal work, as animations determine progress for the frame, and push new state to animated objects (such as setting View properties).'});registerEventInfo({title:'traversals',parents:['Choreographer#doFrame'],docLinks:choreographerLinks,description:'Primary draw traversals. This is the primary traversal of the View hierarchy, including layout and draw passes.'});const traversalParents=['Choreographer#doFrame','performTraversals'];const layoutLinks=new DocLinkBuilder().addDacRef('View#Layout','android/view/View.html#Layout').build();registerEventInfo({title:'performTraversals',description:'A drawing traversal of the View hierarchy, comprised of all layout and drawing needed to produce the frame.'});registerEventInfo({title:'measure',parents:traversalParents,docLinks:layoutLinks,description:'First of two phases in view hierarchy layout. Views are asked to size themselves according to constraints supplied by their parent. Some ViewGroups may measure a child more than once to help satisfy their own constraints. Nesting ViewGroups that measure children more than once can lead to excessive and repeated work.'});registerEventInfo({title:'layout',parents:traversalParents,docLinks:layoutLinks,description:'Second of two phases in view hierarchy layout, repositioning content and child Views into their new locations.'});const drawString='Draw pass over the View hierarchy. Every invalidated View will have its drawing commands recorded. On Android versions prior to Lollipop, this would also include the issuing of draw commands to the GPU. Starting with Lollipop, it only includes the recording of commands, and syncing that information to the RenderThread.';registerEventInfo({title:'draw',parents:traversalParents,description:drawString});const recordString='Every invalidated View\'s drawing commands are recorded. Each will have View#draw() called, and is passed a Canvas that will record and store its drawing commands until it is next invalidated/rerecorded.';registerEventInfo({title:'getDisplayList',parents:['draw'],description:recordString});registerEventInfo({title:'Record View#draw()',parents:['draw'],description:recordString});registerEventInfo({title:'drawDisplayList',parents:['draw'],description:'Execution of recorded draw commands to generate a frame. This represents the actual formation and issuing of drawing commands to the GPU. On Android L and higher devices, this work is done on a dedicated RenderThread, instead of on the UI Thread.'});registerEventInfo({title:'DrawFrame',description:'RenderThread portion of the standard UI/RenderThread split frame. This represents the actual formation and issuing of drawing commands to the GPU.'});registerEventInfo({title:'doFrame',description:'RenderThread animation frame. Represents drawing work done by the RenderThread on a frame where the UI thread did not produce new drawing content.'});registerEventInfo({title:'syncFrameState',description:'Sync stage between the UI thread and the RenderThread, where the UI thread hands off a frame (including information about modified Views). Time in this method primarily consists of uploading modified Bitmaps to the GPU. After this sync is completed, the UI thread is unblocked, and the RenderThread starts to render the frame.'});registerEventInfo({title:'flush drawing commands',description:'Issuing the now complete drawing commands to the GPU.'});registerEventInfo({title:'eglSwapBuffers',description:'Complete GPU rendering of the frame.'});registerEventInfo({title:'RV Scroll',description:'RecyclerView is calculating a scroll. If there are too many of these in Systrace, some Views inside RecyclerView might be causing it. Try to avoid using EditText, focusable views or handle them with care.'});registerEventInfo({title:'RV OnLayout',description:'OnLayout has been called by the View system. If this shows up too many times in Systrace, make sure the children of RecyclerView do not update themselves directly. This will cause a full re-layout but when it happens via the Adapter notifyItemChanged, RecyclerView can avoid full layout calculation.'});registerEventInfo({title:'RV FullInvalidate',description:'NotifyDataSetChanged or equal has been called. If this is taking a long time, try sending granular notify adapter changes instead of just calling notifyDataSetChanged or setAdapter / swapAdapter. Adding stable ids to your adapter might help.'});registerEventInfo({title:'RV PartialInvalidate',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV OnBindView',description:'RecyclerView is rebinding a View. If this is taking a lot of time, consider optimizing your layout or make sure you are not doing extra operations in onBindViewHolder call.'});registerEventInfo({title:'RV CreateView',description:'RecyclerView is creating a new View. If too many of these are present: 1) There might be a problem in Recycling (e.g. custom Animations that set transient state and prevent recycling or ItemAnimator not implementing the contract properly. See Adapter#onFailedToRecycleView(ViewHolder). 2) There may be too many item view types. Try merging them. 3) There might be too many itemChange animations and not enough space in RecyclerPool. Try increasing your pool size and item cache size.'});registerEventInfo({title:'eglSwapBuffers',description:'The CPU has finished producing drawing commands, and is flushing drawing work to the GPU, and posting that buffer to the consumer (which is often SurfaceFlinger window composition). Once this is completed, the GPU can produce the frame content without any involvement from the CPU.'});},applyEventInfosRecursive_(parentNames,slice){const checkExpectedParentNames=function(expectedParentNames){if(!expectedParentNames)return true;return expectedParentNames.some(function(name){return parentNames.has(name);});};if(this.titleInfoLookup.has(slice.title)){if(checkExpectedParentNames(this.titleParentLookup.get(slice.title))){slice.info=this.titleInfoLookup.get(slice.title);}}
 if(slice.subSlices.length>0){if(!parentNames.has(slice.title)){parentNames.set(slice.title,0);}
-parentNames.set(slice.title,parentNames.get(slice.title)+1);slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames.set(slice.title,parentNames.get(slice.title)-1);if(parentNames.get(slice.title)===0){delete parentNames[slice.title];}}},applyEventInfos:function(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_(new Map(),slice);},this);}};return{AndroidAuditor,};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
-ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize:function(){},initialize:function(){},referencedAt:function(item,object,field){},addBoundsToRange:function(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
+parentNames.set(slice.title,parentNames.get(slice.title)+1);slice.subSlices.forEach(function(subSlice){this.applyEventInfosRecursive_(parentNames,subSlice);},this);parentNames.set(slice.title,parentNames.get(slice.title)-1);if(parentNames.get(slice.title)===0){delete parentNames[slice.title];}}},applyEventInfos(sliceGroup){sliceGroup.topLevelSlices.forEach(function(slice){this.applyEventInfosRecursive_(new Map(),slice);},this);}};return{AndroidAuditor,};});'use strict';tr.exportTo('tr.model',function(){function ObjectSnapshot(objectInstance,ts,args){tr.model.Event.call(this);this.objectInstance=objectInstance;this.ts=ts;this.args=args;}
+ObjectSnapshot.prototype={__proto__:tr.model.Event.prototype,preInitialize(){},initialize(){},referencedAt(item,object,field){},addBoundsToRange(range){range.addValue(this.ts);},get userFriendlyName(){return'Snapshot of '+
 this.objectInstance.typeName+' '+
 this.objectInstance.id+' @ '+
-tr.b.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots'});return{ObjectSnapshot,};});'use strict';tr.exportTo('tr.model',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.math.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
-ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange:function(range){range.addRange(this.bounds);},addSnapshot:function(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs){throw new Error('Snapshots must be >= instance.creationTs');}
+tr.b.Unit.byName.timeStampInMs.format(this.ts);}};tr.model.EventRegistry.register(ObjectSnapshot,{name:'objectSnapshot',pluralName:'objectSnapshots'});return{ObjectSnapshot,};});'use strict';tr.exportTo('tr.model',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectInstance(parent,scopedId,category,name,creationTs,opt_baseTypeName){tr.model.Event.call(this);this.parent=parent;this.scopedId=scopedId;this.category=category;this.baseTypeName=opt_baseTypeName?opt_baseTypeName:name;this.name=name;this.creationTs=creationTs;this.creationTsWasExplicit=false;this.deletionTs=Number.MAX_VALUE;this.deletionTsWasExplicit=false;this.colorId=0;this.bounds=new tr.b.math.Range();this.snapshots=[];this.hasImplicitSnapshots=false;}
+ObjectInstance.prototype={__proto__:tr.model.Event.prototype,get typeName(){return this.name;},addBoundsToRange(range){range.addRange(this.bounds);},addSnapshot(ts,args,opt_name,opt_baseTypeName){if(ts<this.creationTs){throw new Error('Snapshots must be >= instance.creationTs');}
 if(ts>=this.deletionTs){throw new Error('Snapshots cannot be added after '+'an objects deletion timestamp.');}
-var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts===ts){throw new Error('Snapshots already exists at this time!');}
+let lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts===ts){throw new Error('Snapshots already exists at this time!');}
 if(ts<lastSnapshot.ts){throw new Error('Snapshots must be added in increasing timestamp order');}}
 if(opt_name&&(this.name!==opt_name)){if(!opt_baseTypeName){throw new Error('Must provide base type name for name update');}
 if(this.baseTypeName!==opt_baseTypeName){throw new Error('Cannot update type name: base types dont match');}
 this.name=opt_name;}
-var snapshotConstructor=tr.model.ObjectSnapshot.subTypes.getConstructor(this.category,this.name);var snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted:function(ts){var lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts){throw new Error('Instance cannot be deleted at ts='+
+const snapshotConstructor=tr.model.ObjectSnapshot.subTypes.getConstructor(this.category,this.name);const snapshot=new snapshotConstructor(this,ts,args);this.snapshots.push(snapshot);return snapshot;},wasDeleted(ts){let lastSnapshot;if(this.snapshots.length>0){lastSnapshot=this.snapshots[this.snapshots.length-1];if(lastSnapshot.ts>ts){throw new Error('Instance cannot be deleted at ts='+
 ts+'. A snapshot exists that is older.');}}
-this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize:function(){for(var i=0;i<this.snapshots.length;i++){this.snapshots[i].preInitialize();}},initialize:function(){for(var i=0;i<this.snapshots.length;i++){this.snapshots[i].initialize();}},isAliveAt:function(ts){if(ts<this.creationTs&&this.creationTsWasExplicit){return false;}
+this.deletionTs=ts;this.deletionTsWasExplicit=true;},preInitialize(){for(let i=0;i<this.snapshots.length;i++){this.snapshots[i].preInitialize();}},initialize(){for(let i=0;i<this.snapshots.length;i++){this.snapshots[i].initialize();}},isAliveAt(ts){if(ts<this.creationTs&&this.creationTsWasExplicit){return false;}
 if(ts>this.deletionTs){return false;}
-return true;},getSnapshotAt:function(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit){throw new Error('ts must be within lifetime of this instance');}
+return true;},getSnapshotAt(ts){if(ts<this.creationTs){if(this.creationTsWasExplicit){throw new Error('ts must be within lifetime of this instance');}
 return this.snapshots[0];}
 if(ts>this.deletionTs){throw new Error('ts must be within lifetime of this instance');}
-var snapshots=this.snapshots;var i=tr.b.math.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i===snapshots.length-1){return snapshots[i].objectInstance.deletionTs;}
+const snapshots=this.snapshots;const i=tr.b.math.findIndexInSortedIntervals(snapshots,function(snapshot){return snapshot.ts;},function(snapshot,i){if(i===snapshots.length-1){return snapshots[i].objectInstance.deletionTs;}
 return snapshots[i+1].ts-snapshots[i].ts;},ts);if(i<0){return this.snapshots[0];}
 if(i>=this.snapshots.length){return this.snapshots[this.snapshots.length-1];}
-return this.snapshots[i];},updateBounds:function(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!==Number.MAX_VALUE){this.bounds.addValue(this.deletionTs);}else if(this.snapshots.length>0){this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);}},shiftTimestampsForward:function(amount){this.creationTs+=amount;if(this.deletionTs!==Number.MAX_VALUE){this.deletionTs+=amount;}
-this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances'});return{ObjectInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function BlameContextSnapshot(){ObjectSnapshot.apply(this,arguments);}
+return this.snapshots[i];},updateBounds(){this.bounds.reset();this.bounds.addValue(this.creationTs);if(this.deletionTs!==Number.MAX_VALUE){this.bounds.addValue(this.deletionTs);}else if(this.snapshots.length>0){this.bounds.addValue(this.snapshots[this.snapshots.length-1].ts);}},shiftTimestampsForward(amount){this.creationTs+=amount;if(this.deletionTs!==Number.MAX_VALUE){this.deletionTs+=amount;}
+this.snapshots.forEach(function(snapshot){snapshot.ts+=amount;});},get userFriendlyName(){return this.typeName+' object '+this.scopedId;}};tr.model.EventRegistry.register(ObjectInstance,{name:'objectInstance',pluralName:'objectInstances'});return{ObjectInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function BlameContextSnapshot(){ObjectSnapshot.apply(this,arguments);}
 BlameContextSnapshot.prototype={__proto__:ObjectSnapshot.prototype,get parentContext(){if(this.args.parent instanceof BlameContextSnapshot){return this.args.parent;}
 return undefined;},get userFriendlyName(){return'BlameContext';}};function BlameContextInstance(){ObjectInstance.apply(this,arguments);}
-BlameContextInstance.prototype={__proto__:ObjectInstance.prototype,get blameContextType(){throw new Error('Not implemented');}};return{BlameContextSnapshot,BlameContextInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){var BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;var BlameContextInstance=tr.e.chrome.BlameContextInstance;function FrameTreeNodeSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+BlameContextInstance.prototype={__proto__:ObjectInstance.prototype,get blameContextType(){throw new Error('Not implemented');}};return{BlameContextSnapshot,BlameContextInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function FrameTreeNodeSnapshot(){BlameContextSnapshot.apply(this,arguments);}
 FrameTreeNodeSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,get renderFrame(){if(this.args.renderFrame instanceof tr.e.chrome.RenderFrameSnapshot){return this.args.renderFrame;}
 return undefined;},get url(){return this.args.url;},get userFriendlyName(){return'FrameTreeNode';}};tr.model.ObjectSnapshot.subTypes.register(FrameTreeNodeSnapshot,{typeName:'FrameTreeNode'});function FrameTreeNodeInstance(){BlameContextInstance.apply(this,arguments);}
-FrameTreeNodeInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot,FrameTreeNodeInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){var BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;var BlameContextInstance=tr.e.chrome.BlameContextInstance;function RenderFrameSnapshot(){BlameContextSnapshot.apply(this,arguments);}
-RenderFrameSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,referencedAt:function(item,object,field){if(item instanceof tr.e.chrome.FrameTreeNodeSnapshot&&object===item.args&&field==='renderFrame'){this.args.frameTreeNode=item;}},get frameTreeNode(){if(this.args.frameTreeNode instanceof
+FrameTreeNodeInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(FrameTreeNodeInstance,{typeName:'FrameTreeNode'});return{FrameTreeNodeSnapshot,FrameTreeNodeInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function RenderFrameSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+RenderFrameSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,referencedAt(item,object,field){if(item instanceof tr.e.chrome.FrameTreeNodeSnapshot&&object===item.args&&field==='renderFrame'){this.args.frameTreeNode=item;}},get frameTreeNode(){if(this.args.frameTreeNode instanceof
 tr.e.chrome.FrameTreeNodeSnapshot){return this.args.frameTreeNode;}
 return undefined;},get url(){if(this.frameTreeNode){return this.frameTreeNode.url;}
 return undefined;},get userFriendlyName(){return'RenderFrame';}};tr.model.ObjectSnapshot.subTypes.register(RenderFrameSnapshot,{typeName:'RenderFrame'});function RenderFrameInstance(){BlameContextInstance.apply(this,arguments);}
-RenderFrameInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot,RenderFrameInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){var BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;var BlameContextInstance=tr.e.chrome.BlameContextInstance;function TopLevelSnapshot(){BlameContextSnapshot.apply(this,arguments);}
+RenderFrameInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'Frame';}};tr.model.ObjectInstance.subTypes.register(RenderFrameInstance,{typeName:'RenderFrame'});return{RenderFrameSnapshot,RenderFrameInstance,};});'use strict';tr.exportTo('tr.e.chrome',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;function TopLevelSnapshot(){BlameContextSnapshot.apply(this,arguments);}
 TopLevelSnapshot.prototype={__proto__:BlameContextSnapshot.prototype,get userFriendlyName(){return'TopLevel';}};tr.model.ObjectSnapshot.subTypes.register(TopLevelSnapshot,{typeName:'TopLevel'});function TopLevelInstance(){BlameContextInstance.apply(this,arguments);}
 TopLevelInstance.prototype={__proto__:BlameContextInstance.prototype,get blameContextType(){return'TopLevel';}};tr.model.ObjectInstance.subTypes.register(TopLevelInstance,{typeName:'TopLevel'});return{TopLevelSnapshot,TopLevelInstance,};});'use strict';tr.exportTo('tr.model',function(){function AsyncSlice(category,title,colorId,start,args,duration,opt_isTopLevel,opt_cpuStart,opt_cpuDuration,opt_argsStripped){tr.model.TimedEvent.call(this,start);this.category=category||'';this.originalTitle=title;this.title=title;this.colorId=colorId;this.args=args;this.startStackFrame=undefined;this.endStackFrame=undefined;this.didNotFinish=false;this.important=false;this.subSlices=[];this.parentContainer_=undefined;this.id=undefined;this.startThread=undefined;this.endThread=undefined;this.cpuStart=undefined;this.cpuDuration=undefined;this.argsStripped=false;this.startStackFrame=undefined;this.endStackFrame=undefined;this.duration=duration;this.isTopLevel=(opt_isTopLevel===true);if(opt_cpuStart!==undefined){this.cpuStart=opt_cpuStart;}
 if(opt_cpuDuration!==undefined){this.cpuDuration=opt_cpuDuration;}
 if(opt_argsStripped!==undefined){this.argsStripped=opt_argsStripped;}}
-AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(var i=0;i<this.subSlices.length;i++){var subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined){subSlice.parentContainer=parentContainer;}}},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
-tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){var parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
-parentAsyncSliceGroup.slices.indexOf(this);},findTopmostSlicesRelativeToThisSlice:function*(eventPredicate,opt_this){if(eventPredicate(this)){yield this;return;}
-for(var s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},findDescendentSlice:function(targetTitle){if(!this.subSlices)return undefined;for(var i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
-var slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
-return undefined;},enumerateAllDescendents:function*(){for(var slice of this.subSlices){yield slice;}
-for(var slice of this.subSlices){yield*slice.enumerateAllDescendents();}},compareTo:function(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices'});return{AsyncSlice,};});'use strict';tr.exportTo('tr.model.helpers',function(){var MAIN_FRAMETIME_TYPE='main_frametime_type';var IMPL_FRAMETIME_TYPE='impl_frametime_type';var MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';var IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){var slicesInFilterRange=[];for(var i=0;i<slices.length;i++){var slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end)){slicesInFilterRange.push(slice);}}
+AsyncSlice.prototype={__proto__:tr.model.TimedEvent.prototype,get analysisTypeName(){return this.title;},get parentContainer(){return this.parentContainer_;},set parentContainer(parentContainer){this.parentContainer_=parentContainer;for(let i=0;i<this.subSlices.length;i++){const subSlice=this.subSlices[i];if(subSlice.parentContainer===undefined){subSlice.parentContainer=parentContainer;}}},get viewSubGroupTitle(){return this.title;},get userFriendlyName(){return'Async slice '+this.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get stableId(){const parentAsyncSliceGroup=this.parentContainer.asyncSliceGroup;return parentAsyncSliceGroup.stableId+'.'+
+parentAsyncSliceGroup.slices.indexOf(this);},*findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this){if(eventPredicate(this)){yield this;return;}
+for(const s of this.subSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},findDescendentSlice(targetTitle){if(!this.subSlices)return undefined;for(let i=0;i<this.subSlices.length;i++){if(this.subSlices[i].title===targetTitle){return this.subSlices[i];}
+const slice=this.subSlices[i].findDescendentSlice(targetTitle);if(slice)return slice;}
+return undefined;},*enumerateAllDescendents(){for(const slice of this.subSlices){yield slice;}
+for(const slice of this.subSlices){yield*slice.enumerateAllDescendents();}},compareTo(that){return this.title.localeCompare(that.title);}};tr.model.EventRegistry.register(AsyncSlice,{name:'asyncSlice',pluralName:'asyncSlices'});return{AsyncSlice,};});'use strict';tr.exportTo('tr.model.helpers',function(){const MAIN_FRAMETIME_TYPE='main_frametime_type';const IMPL_FRAMETIME_TYPE='impl_frametime_type';const MAIN_RENDERING_STATS='BenchmarkInstrumentation::MainThreadRenderingStats';const IMPL_RENDERING_STATS='BenchmarkInstrumentation::ImplThreadRenderingStats';function getSlicesIntersectingRange(rangeOfInterest,slices){const slicesInFilterRange=[];for(let i=0;i<slices.length;i++){const slice=slices[i];if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end)){slicesInFilterRange.push(slice);}}
 return slicesInFilterRange;}
 function ChromeProcessHelper(modelHelper,process){this.modelHelper=modelHelper;this.process=process;this.telemetryInternalRanges_=undefined;}
-ChromeProcessHelper.prototype={get pid(){return this.process.pid;},isTelemetryInternalEvent:function(slice){if(this.telemetryInternalRanges_===undefined){this.findTelemetryInternalRanges_();}
-for(var range of this.telemetryInternalRanges_){if(range.containsExplicitRangeInclusive(slice.start,slice.end)){return true;}}
-return false;},findTelemetryInternalRanges_:function(){this.telemetryInternalRanges_=[];var start=0;for(var thread of Object.values(this.process.threads)){for(var slice of thread.asyncSliceGroup.getDescendantEvents()){if(/^telemetry\.internal\.[^.]*\.start$/.test(slice.title)){start=slice.start;}else if(/^telemetry\.internal\.[^.]*\.end$/.test(slice.title)&&start!==undefined){this.telemetryInternalRanges_.push(tr.b.math.Range.fromExplicitRange(start,slice.end));start=undefined;}}}},getFrameEventsInRange:function(frametimeType,range){var titleToGet=(frametimeType===MAIN_FRAMETIME_TYPE?MAIN_RENDERING_STATS:IMPL_RENDERING_STATS);var frameEvents=[];for(var event of this.process.getDescendantEvents()){if(event.title===titleToGet){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){frameEvents.push(event);}}}
-frameEvents.sort(function(a,b){return a.start-b.start;});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){var frametimeData=[];for(var i=1;i<frameEvents.length;i++){var diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
+ChromeProcessHelper.prototype={get pid(){return this.process.pid;},isTelemetryInternalEvent(slice){if(this.telemetryInternalRanges_===undefined){this.findTelemetryInternalRanges_();}
+for(const range of this.telemetryInternalRanges_){if(range.containsExplicitRangeInclusive(slice.start,slice.end)){return true;}}
+return false;},findTelemetryInternalRanges_(){this.telemetryInternalRanges_=[];let start=0;for(const thread of Object.values(this.process.threads)){for(const slice of thread.asyncSliceGroup.getDescendantEvents()){if(/^telemetry\.internal\.[^.]*\.start$/.test(slice.title)){start=slice.start;}else if(/^telemetry\.internal\.[^.]*\.end$/.test(slice.title)&&start!==undefined){this.telemetryInternalRanges_.push(tr.b.math.Range.fromExplicitRange(start,slice.end));start=undefined;}}}},getFrameEventsInRange(frametimeType,range){const titleToGet=(frametimeType===MAIN_FRAMETIME_TYPE?MAIN_RENDERING_STATS:IMPL_RENDERING_STATS);const frameEvents=[];for(const event of this.process.getDescendantEvents()){if(event.title===titleToGet){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){frameEvents.push(event);}}}
+frameEvents.sort(function(a,b){return a.start-b.start;});return frameEvents;}};function getFrametimeDataFromEvents(frameEvents){const frametimeData=[];for(let i=1;i<frameEvents.length;i++){const diff=frameEvents[i].start-frameEvents[i-1].start;frametimeData.push({'x':frameEvents[i].start,'frametime':diff});}
 return frametimeData;}
 return{ChromeProcessHelper,MAIN_FRAMETIME_TYPE,IMPL_FRAMETIME_TYPE,MAIN_RENDERING_STATS,IMPL_RENDERING_STATS,getSlicesIntersectingRange,getFrametimeDataFromEvents,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeBrowserHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrBrowserMain');if(!process.name){process.name=ChromeBrowserHelper.PROCESS_NAME;}}
-ChromeBrowserHelper.PROCESS_NAME='Browser';ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get browserName(){var hasInProcessRendererThread=this.process.findAllThreadsNamed('Chrome_InProcRendererThread').length>0;return hasInProcessRendererThread?'webview':'chrome';},get mainThread(){return this.mainThread_;},get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){var hasLatency=false;for(var thread of this.modelHelper.model.getAllThreads()){for(var event of thread.getDescendantEvents()){if(!event.isTopLevel)continue;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){continue;}
+ChromeBrowserHelper.PROCESS_NAME='Browser';ChromeBrowserHelper.isBrowserProcess=function(process){return!!process.findAtMostOneThreadNamed('CrBrowserMain');};ChromeBrowserHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get browserName(){const hasInProcessRendererThread=this.process.findAllThreadsNamed('Chrome_InProcRendererThread').length>0;return hasInProcessRendererThread?'webview':'chrome';},get mainThread(){return this.mainThread_;},get rendererHelpers(){return this.modelHelper.rendererHelpers;},getLoadingEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title.indexOf('WebContentsImpl Loading')===0&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getCommitProvisionalLoadEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return slice.title==='RenderFrameImpl::didCommitProvisionalLoad'&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},get hasLatencyEvents(){let hasLatency=false;for(const thread of this.modelHelper.model.getAllThreads()){for(const event of thread.getDescendantEvents()){if(!event.isTopLevel)continue;if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){continue;}
 hasLatency=true;}}
-return hasLatency;},getLatencyEventsInRange:function(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching:function(pred,opt_this){var events=[];this.iterAllThreads(function(thread){for(var slice of thread.getDescendantEvents()){if(pred.call(opt_this,slice)){events.push(slice);}}});return events;},getAllNetworkEventsInRange:function(rangeOfInterest){let networkEvents=[];for(const thread of
-Object.values(this.modelHelper.model.getAllThreads())){networkEvents=networkEvents.concat(thread.getNetworkEventsInRange(rangeOfInterest));}
-return networkEvents;},iterAllThreads:function(func,opt_this){for(var thread of Object.values(this.process.threads)){func.call(opt_this,thread);}
-for(var rendererHelper of Object.values(this.rendererHelpers)){var rendererProcess=rendererHelper.process;for(var thread of Object.values(rendererProcess.threads)){func.call(opt_this,thread);}}}};return{ChromeBrowserHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrGpuMain');if(!process.name){process.name=ChromeGpuHelper.PROCESS_NAME;}}
+return hasLatency;},getLatencyEventsInRange(rangeOfInterest){return this.getAllAsyncSlicesMatching(function(slice){return(slice.title.indexOf('InputLatency')===0)&&rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end);});},getAllAsyncSlicesMatching(pred,opt_this){const events=[];this.iterAllThreads(function(thread){for(const slice of thread.getDescendantEvents()){if(pred.call(opt_this,slice)){events.push(slice);}}});return events;},iterAllThreads(func,opt_this){for(const thread of Object.values(this.process.threads)){func.call(opt_this,thread);}
+for(const rendererHelper of Object.values(this.rendererHelpers)){const rendererProcess=rendererHelper.process;for(const thread of Object.values(rendererProcess.threads)){func.call(opt_this,thread);}}}};return{ChromeBrowserHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeGpuHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);if(!process.name){process.name=ChromeGpuHelper.PROCESS_NAME;}}
 ChromeGpuHelper.PROCESS_NAME='GPU Process';ChromeGpuHelper.isGpuProcess=function(process){if(process.findAtMostOneThreadNamed('CrBrowserMain')||process.findAtMostOneThreadNamed('CrRendererMain')){return false;}
-return process.findAtMostOneThreadNamed('CrGpuMain');};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;}};return{ChromeGpuHelper,};});'use strict';tr.exportTo('tr.b',function(){function SinebowColorGenerator(opt_a,opt_brightness){this.a_=(opt_a===undefined)?1:opt_a;this.brightness_=(opt_brightness===undefined)?1:opt_brightness;this.colorIndex_=0;this.keyToColor={};}
-SinebowColorGenerator.prototype={colorForKey:function(key){if(!this.keyToColor[key]){this.keyToColor[key]=this.nextColor();}
-return this.keyToColor[key];},nextColor:function(){var components=SinebowColorGenerator.nthColor(this.colorIndex_++);return tr.b.Color.fromString(SinebowColorGenerator.calculateColor(components[0],components[1],components[2],this.a_,this.brightness_));}};SinebowColorGenerator.PHI=(1+Math.sqrt(5))/2;SinebowColorGenerator.sinebow_=function(h){h+=0.5;h=-h;var r=Math.sin(Math.PI*h);var g=Math.sin(Math.PI*(h+1/3));var b=Math.sin(Math.PI*(h+2/3));r*=r;g*=g;b*=b;var y=2*(0.2989*r+0.5870*g+0.1140*b);r/=y;g/=y;b/=y;return[256*r,256*g,256*b];};SinebowColorGenerator.nthColor=function(n){return SinebowColorGenerator.sinebow_(n*this.PHI);};SinebowColorGenerator.calculateColor=function(r,g,b,a,brightness){if(brightness<=1){r*=brightness;g*=brightness;b*=brightness;}else{r=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),r,255);g=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),g,255);b=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),b,255);}
-r=Math.round(r);g=Math.round(g);b=Math.round(b);return'rgba('+r+','+g+','+b+', '+a+')';};return{SinebowColorGenerator,};});'use strict';tr.exportTo('tr.e.chrome',function(){var SAME_AS_PARENT='same-as-parent';var TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::UpdateLayers::CalcDrawProps','UpdateLayerTree'],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers'],iframe_creation:['WebLocalFrameImpl::createChildframe'],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale'],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent'],layout:['FrameView::invalidateTree','FrameView::layout','FrameView::performLayout','FrameView::performPostLayoutTasks','FrameView::performPreLayoutTasks','Layer::updateLayerPositionsAfterLayout','Layout','LayoutView::hitTest','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::layout'],parseHTML:['ParseHTML','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::processParsedChunkFromBackgroundParser','HTMLDocumentParser::processTokenizedChunkFromBackgroundParser',],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory'],record:['ContentLayerDelegate::paintContents','DeprecatedPaintLayerCompositor::updateIfNeededRecursive','DeprecatedPaintLayerCompositor::updateLayerPositionsAfterLayout','Paint','Picture::Record','PictureLayer::Update','RenderLayer::updateLayerPositionsAfterLayout'],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree'],script_parse_and_compile:['v8.parseOnBackground','V8.ScriptCompiler'],script_execute:['V8.Execute','WindowProxy::initialize'],resource_loading:['ResourceFetcher::requestResource','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnRequestComplete','ResourceDispatcher::OnReceivedResponse','Resource::appendData'],renderer_misc:['DecodeFont','ThreadState::completeSweep'],v8_runtime:[],[SAME_AS_PARENT]:['SyncChannel::Send']};var COLOR_FOR_USER_FRIENDLY_CATEGORY=new tr.b.SinebowColorGenerator();var USER_FRIENDLY_CATEGORY_FOR_TITLE=new Map();for(var category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE.set(title,category);});}
-var USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu'};function ChromeUserFriendlyCategoryDriver(){}
-ChromeUserFriendlyCategoryDriver.fromEvent=function(event){var userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE.get(event.title);if(userFriendlyCategory){if(userFriendlyCategory===SAME_AS_PARENT){if(event.parentSlice){return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}}else{return userFriendlyCategory;}}
-var eventCategoryParts=tr.b.getCategoryParts(event.category);for(var i=0;i<eventCategoryParts.length;++i){var eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory){return userFriendlyCategory;}}
-return'other';};ChromeUserFriendlyCategoryDriver.getColor=function(ufc){return COLOR_FOR_USER_FRIENDLY_CATEGORY.colorForKey(ufc);};ChromeUserFriendlyCategoryDriver.ALL_TITLES=['other'];for(var category in TITLES_FOR_USER_FRIENDLY_CATEGORY){if(category===SAME_AS_PARENT)continue;ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
-for(var category of tr.b.dictionaryValues(USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY)){ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
-ChromeUserFriendlyCategoryDriver.ALL_TITLES.sort();for(var category of ChromeUserFriendlyCategoryDriver.ALL_TITLES){ChromeUserFriendlyCategoryDriver.getColor(category);}
-return{ChromeUserFriendlyCategoryDriver,};});'use strict';tr.exportTo('tr.model.helpers',function(){function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain')||process.findAtMostOneThreadNamed('Chrome_InProcRendererThread');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)return false;if(t.name.indexOf('CompositorTileWorker')===0)return true;if(t.name.indexOf('CompositorRasterWorker')===0)return true;return false;});if(!process.name){process.name=ChromeRendererHelper.PROCESS_NAME;}}
-function generateTimeBreakdownTree_(mainThread,rangeStart,rangeEnd,getEventStart,getEventDuration,getEventSelfTime){if(mainThread===null)return;var breakdownTree={};var range=tr.b.math.Range.fromExplicitRange(rangeStart,rangeEnd);for(var title of
-tr.e.chrome.ChromeUserFriendlyCategoryDriver.ALL_TITLES){breakdownTree[title]={total:0,events:{}};}
-for(var event of mainThread.getDescendantEvents()){var eventStart=getEventStart(event);var eventDuration=getEventDuration(event);var eventSelfTime=getEventSelfTime(event);var eventEnd=eventStart+eventDuration;if(!range.intersectsExplicitRangeExclusive(eventStart,eventEnd)){continue;}
-if(eventSelfTime===undefined)continue;var title=tr.e.chrome.ChromeUserFriendlyCategoryDriver.fromEvent(event);var timeIntersectionRatio=0;if(eventDuration>0){timeIntersectionRatio=range.findExplicitIntersectionDuration(eventStart,eventEnd)/eventDuration;}
-var v8Runtime=event.args['runtime-call-stat'];if(v8Runtime!==undefined){var v8RuntimeObject=JSON.parse(v8Runtime);for(var runtimeCall in v8RuntimeObject){if(v8RuntimeObject[runtimeCall].length===2){if(breakdownTree['v8_runtime'].events[runtimeCall]===undefined){breakdownTree['v8_runtime'].events[runtimeCall]=0;}
-var runtimeTime=tr.b.Unit.timestampFromUs(v8RuntimeObject[runtimeCall][1]*timeIntersectionRatio);breakdownTree['v8_runtime'].total+=runtimeTime;breakdownTree['v8_runtime'].events[runtimeCall]+=runtimeTime;}}}
-var approximatedSelfTimeContribution=eventSelfTime*timeIntersectionRatio;breakdownTree[title].total+=approximatedSelfTimeContribution;if(breakdownTree[title].events[event.title]===undefined){breakdownTree[title].events[event.title]=0;}
-breakdownTree[title].events[event.title]+=approximatedSelfTimeContribution;}
-return breakdownTree;}
-ChromeRendererHelper.PROCESS_NAME='Renderer';ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))return true;if(process.findAtMostOneThreadNamed('Compositor'))return true;return false;};ChromeRendererHelper.isTracingProcess=function(process){return process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get isChromeTracingUI(){return ChromeRendererHelper.isTracingProcess(this.process);},generateWallClockTimeBreakdownTree:function(start,end){function getEventStart(e){return e.start;}
-function getEventDuration(e){return e.duration;}
-function getEventSelfTime(e){return e.selfTime;}
-var breakdownTree=generateTimeBreakdownTree_(this.mainThread,start,end,getEventStart,getEventDuration,getEventSelfTime);var idleTotal=end-start;for(let cat in breakdownTree){idleTotal-=breakdownTree[cat].total;}
-breakdownTree['idle']={total:idleTotal,events:{}};return breakdownTree;},generateCpuTimeBreakdownTree:function(cpuStart,cpuEnd){function getEventStart(e){return e.cpuStart;}
-function getEventDuration(e){return e.cpuDuration;}
-function getEventSelfTime(e){return e.cpuSelfTime;}
-return generateTimeBreakdownTree_(this.mainThread,cpuStart,cpuEnd,getEventStart,getEventDuration,getEventSelfTime);},getAllNetworkEventsInRange:function(rangeOfInterest){const networkEvents=[];for(const thread of Object.values(this.process.threads)){const events=thread.getNetworkEventsInRange(rangeOfInterest);for(const event of events){networkEvents.push(event);}}
-return networkEvents;}};return{ChromeRendererHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeBrowserHelper.isBrowserProcess);}
+return process.findAllThreadsNamed('CrGpuMain').length>0;};ChromeGpuHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype};return{ChromeGpuHelper,};});'use strict';tr.exportTo('tr.b',function(){function SinebowColorGenerator(opt_a,opt_brightness){this.a_=(opt_a===undefined)?1:opt_a;this.brightness_=(opt_brightness===undefined)?1:opt_brightness;this.colorIndex_=0;this.keyToColor={};}
+SinebowColorGenerator.prototype={colorForKey(key){if(!this.keyToColor[key]){this.keyToColor[key]=this.nextColor();}
+return this.keyToColor[key];},nextColor(){const components=SinebowColorGenerator.nthColor(this.colorIndex_++);return tr.b.Color.fromString(SinebowColorGenerator.calculateColor(components[0],components[1],components[2],this.a_,this.brightness_));}};SinebowColorGenerator.PHI=(1+Math.sqrt(5))/2;SinebowColorGenerator.sinebow_=function(h){h+=0.5;h=-h;let r=Math.sin(Math.PI*h);let g=Math.sin(Math.PI*(h+1/3));let b=Math.sin(Math.PI*(h+2/3));r*=r;g*=g;b*=b;const y=2*(0.2989*r+0.5870*g+0.1140*b);r/=y;g/=y;b/=y;return[256*r,256*g,256*b];};SinebowColorGenerator.nthColor=function(n){return SinebowColorGenerator.sinebow_(n*this.PHI);};SinebowColorGenerator.calculateColor=function(r,g,b,a,brightness){if(brightness<=1){r*=brightness;g*=brightness;b*=brightness;}else{r=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),r,255);g=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),g,255);b=tr.b.math.lerp(tr.b.math.normalize(brightness,1,2),b,255);}
+r=Math.round(r);g=Math.round(g);b=Math.round(b);return'rgba('+r+','+g+','+b+', '+a+')';};return{SinebowColorGenerator,};});'use strict';tr.exportTo('tr.e.chrome',function(){const SAME_AS_PARENT='same-as-parent';const TITLES_FOR_USER_FRIENDLY_CATEGORY={composite:['CompositingInputsUpdater::update','ThreadProxy::SetNeedsUpdateLayers','LayerTreeHost::UpdateLayers::CalcDrawProps','UpdateLayerTree'],gc:['minorGC','majorGC','MajorGC','MinorGC','V8.GCScavenger','V8.GCIncrementalMarking','V8.GCIdleNotification','V8.GCContext','V8.GCCompactor','V8GCController::traceDOMWrappers'],iframe_creation:['WebLocalFrameImpl::createChildframe'],imageDecode:['Decode Image','ImageFrameGenerator::decode','ImageFrameGenerator::decodeAndScale'],input:['HitTest','ScrollableArea::scrollPositionChanged','EventHandler::handleMouseMoveEvent'],layout:['FrameView::invalidateTree','FrameView::layout','FrameView::performLayout','FrameView::performPostLayoutTasks','FrameView::performPreLayoutTasks','Layer::updateLayerPositionsAfterLayout','Layout','LayoutView::hitTest','ResourceLoadPriorityOptimizer::updateAllImageResourcePriorities','WebViewImpl::layout'],parseHTML:['ParseHTML','HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser','HTMLDocumentParser::processParsedChunkFromBackgroundParser','HTMLDocumentParser::processTokenizedChunkFromBackgroundParser',],raster:['DisplayListRasterSource::PerformSolidColorAnalysis','Picture::Raster','RasterBufferImpl::Playback','RasterTask','RasterizerTaskImpl::RunOnWorkerThread','SkCanvas::drawImageRect()','SkCanvas::drawPicture()','SkCanvas::drawTextBlob()','TileTaskWorkerPool::PlaybackToMemory'],record:['ContentLayerDelegate::paintContents','DeprecatedPaintLayerCompositor::updateIfNeededRecursive','DeprecatedPaintLayerCompositor::updateLayerPositionsAfterLayout','Paint','Picture::Record','PictureLayer::Update','RenderLayer::updateLayerPositionsAfterLayout'],style:['CSSParserImpl::parseStyleSheet.parse','CSSParserImpl::parseStyleSheet.tokenize','Document::updateStyle','Document::updateStyleInvalidationIfNeeded','ParseAuthorStyleSheet','RuleSet::addRulesFromSheet','StyleElement::processStyleSheet','StyleEngine::createResolver','StyleSheetContents::parseAuthorStyleSheet','UpdateLayoutTree'],script_parse_and_compile:['v8.parseOnBackground','V8.ScriptCompiler'],script_execute:['V8.Execute','WindowProxy::initialize'],resource_loading:['ResourceFetcher::requestResource','ResourceDispatcher::OnReceivedData','ResourceDispatcher::OnRequestComplete','ResourceDispatcher::OnReceivedResponse','Resource::appendData'],renderer_misc:['DecodeFont','ThreadState::completeSweep'],v8_runtime:[],[SAME_AS_PARENT]:['SyncChannel::Send']};const COLOR_FOR_USER_FRIENDLY_CATEGORY=new tr.b.SinebowColorGenerator();const USER_FRIENDLY_CATEGORY_FOR_TITLE=new Map();for(const category in TITLES_FOR_USER_FRIENDLY_CATEGORY){TITLES_FOR_USER_FRIENDLY_CATEGORY[category].forEach(function(title){USER_FRIENDLY_CATEGORY_FOR_TITLE.set(title,category);});}
+const USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY={netlog:'net',overhead:'overhead',startup:'startup',gpu:'gpu'};function ChromeUserFriendlyCategoryDriver(){}
+ChromeUserFriendlyCategoryDriver.fromEvent=function(event){let userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_TITLE.get(event.title);if(userFriendlyCategory){if(userFriendlyCategory===SAME_AS_PARENT){if(event.parentSlice){return ChromeUserFriendlyCategoryDriver.fromEvent(event.parentSlice);}}else{return userFriendlyCategory;}}
+const eventCategoryParts=tr.b.getCategoryParts(event.category);for(let i=0;i<eventCategoryParts.length;++i){const eventCategory=eventCategoryParts[i];userFriendlyCategory=USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY[eventCategory];if(userFriendlyCategory){return userFriendlyCategory;}}
+return'other';};ChromeUserFriendlyCategoryDriver.getColor=function(ufc){return COLOR_FOR_USER_FRIENDLY_CATEGORY.colorForKey(ufc);};ChromeUserFriendlyCategoryDriver.ALL_TITLES=['other'];for(const category in TITLES_FOR_USER_FRIENDLY_CATEGORY){if(category===SAME_AS_PARENT)continue;ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
+for(const category of Object.values(USER_FRIENDLY_CATEGORY_FOR_EVENT_CATEGORY)){ChromeUserFriendlyCategoryDriver.ALL_TITLES.push(category);}
+ChromeUserFriendlyCategoryDriver.ALL_TITLES.sort();for(const category of ChromeUserFriendlyCategoryDriver.ALL_TITLES){ChromeUserFriendlyCategoryDriver.getColor(category);}
+return{ChromeUserFriendlyCategoryDriver,};});'use strict';tr.exportTo('tr.model.helpers',function(){const NET_CATEGORIES=new Set(['net','netlog','disabled-by-default-netlog','disabled-by-default-network']);class ChromeThreadHelper{constructor(thread){this.thread=thread;}
+getNetworkEvents(){const networkEvents=[];for(const slice of this.thread.asyncSliceGroup.slices){const categories=tr.b.getCategoryParts(slice.category);const isNetEvent=category=>NET_CATEGORIES.has(category);if(categories.filter(isNetEvent).length===0)continue;networkEvents.push(slice);}
+return networkEvents;}}
+return{ChromeThreadHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){const ChromeThreadHelper=tr.model.helpers.ChromeThreadHelper;function ChromeRendererHelper(modelHelper,process){tr.model.helpers.ChromeProcessHelper.call(this,modelHelper,process);this.mainThread_=process.findAtMostOneThreadNamed('CrRendererMain')||process.findAtMostOneThreadNamed('Chrome_InProcRendererThread');this.compositorThread_=process.findAtMostOneThreadNamed('Compositor');this.rasterWorkerThreads_=process.findAllThreadsMatching(function(t){if(t.name===undefined)return false;if(t.name.indexOf('CompositorTileWorker')===0)return true;if(t.name.indexOf('CompositorRasterWorker')===0)return true;return false;});if(!process.name){process.name=ChromeRendererHelper.PROCESS_NAME;}}
+ChromeRendererHelper.PROCESS_NAME='Renderer';ChromeRendererHelper.isRenderProcess=function(process){if(process.findAtMostOneThreadNamed('CrRendererMain'))return true;if(process.findAtMostOneThreadNamed('Compositor'))return true;return false;};ChromeRendererHelper.isTracingProcess=function(process){return process.labels!==undefined&&process.labels.length===1&&process.labels[0]==='chrome://tracing';};ChromeRendererHelper.prototype={__proto__:tr.model.helpers.ChromeProcessHelper.prototype,get mainThread(){return this.mainThread_;},get compositorThread(){return this.compositorThread_;},get rasterWorkerThreads(){return this.rasterWorkerThreads_;},get isChromeTracingUI(){return ChromeRendererHelper.isTracingProcess(this.process);},};return{ChromeRendererHelper,};});'use strict';tr.exportTo('tr.model.helpers',function(){function findChromeBrowserProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeBrowserHelper.isBrowserProcess);}
 function findChromeRenderProcesses(model){return model.getAllProcesses(tr.model.helpers.ChromeRendererHelper.isRenderProcess);}
-function findChromeGpuProcess(model){var gpuProcesses=model.getAllProcesses(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!==1)return undefined;return gpuProcesses[0];}
-function ChromeModelHelper(model){this.model_=model;var browserProcesses=findChromeBrowserProcesses(model);this.browserHelpers_=browserProcesses.map(p=>new tr.model.helpers.ChromeBrowserHelper(this,p));var gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
-var rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){var rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);this.chromeBounds_=undefined;}
-ChromeModelHelper.guid=tr.b.GUID.allocateSimple();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcesses(model).length)return true;if(findChromeRenderProcesses(model).length)return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){if(this.browserHelper===undefined)return undefined;return this.browserHelper.process;},get browserHelper(){return this.browserHelpers_[0];},get browserHelpers(){return this.browserHelpers_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;},get rendererWithLargestPid(){var largestPid=-1;for(var pid in this.rendererHelpers){var rendererHelper=this.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;if(pid>largestPid)largestPid=pid;}
-if(largestPid===-1)return undefined;return this.rendererHelpers[largestPid];},get chromeBounds(){if(!this.chromeBounds_){this.chromeBounds_=new tr.b.math.Range();for(var browserHelper of
-tr.b.dictionaryValues(this.browserHelpers)){this.chromeBounds_.addRange(browserHelper.process.bounds);}}
+function findChromeGpuProcess(model){const gpuProcesses=model.getAllProcesses(tr.model.helpers.ChromeGpuHelper.isGpuProcess);if(gpuProcesses.length!==1)return undefined;return gpuProcesses[0];}
+function ChromeModelHelper(model){this.model_=model;const browserProcesses=findChromeBrowserProcesses(model);this.browserHelpers_=browserProcesses.map(p=>new tr.model.helpers.ChromeBrowserHelper(this,p));const gpuProcess=findChromeGpuProcess(model);if(gpuProcess){this.gpuHelper_=new tr.model.helpers.ChromeGpuHelper(this,gpuProcess);}else{this.gpuHelper_=undefined;}
+const rendererProcesses_=findChromeRenderProcesses(model);this.rendererHelpers_={};rendererProcesses_.forEach(function(renderProcess){const rendererHelper=new tr.model.helpers.ChromeRendererHelper(this,renderProcess);this.rendererHelpers_[rendererHelper.pid]=rendererHelper;},this);this.chromeBounds_=undefined;}
+ChromeModelHelper.guid=tr.b.GUID.allocateSimple();ChromeModelHelper.supportsModel=function(model){if(findChromeBrowserProcesses(model).length)return true;if(findChromeRenderProcesses(model).length)return true;return false;};ChromeModelHelper.prototype={get pid(){throw new Error('woah');},get process(){throw new Error('woah');},get model(){return this.model_;},get browserProcess(){if(this.browserHelper===undefined)return undefined;return this.browserHelper.process;},get browserHelper(){return this.browserHelpers_[0];},get browserHelpers(){return this.browserHelpers_;},get gpuHelper(){return this.gpuHelper_;},get rendererHelpers(){return this.rendererHelpers_;},get rendererWithLargestPid(){let largestPid=-1;for(const pid in this.rendererHelpers){const rendererHelper=this.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;if(pid>largestPid)largestPid=pid;}
+if(largestPid===-1)return undefined;return this.rendererHelpers[largestPid];},get chromeBounds(){if(!this.chromeBounds_){this.chromeBounds_=new tr.b.math.Range();for(const browserHelper of
+Object.values(this.browserHelpers)){this.chromeBounds_.addRange(browserHelper.process.bounds);}}
 if(this.chromeBounds_.isEmpty){return undefined;}
-return this.chromeBounds_;}};return{ChromeModelHelper,};});'use strict';tr.exportTo('tr.e.cc',function(){var AsyncSlice=tr.model.AsyncSlice;var EventSet=tr.model.EventSet;var UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';var ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';var BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';var END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';var MAIN_RENDERER_THREAD_NAME='CrRendererMain';var COMPOSITOR_THREAD_NAME='Compositor';var POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';var IPC_FLOW_EVENT='disabled-by-default-ipc.flow';var INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent){this.determineModernTypeName_();}}
+return this.chromeBounds_;}};return{ChromeModelHelper,};});'use strict';tr.exportTo('tr.e.cc',function(){const AsyncSlice=tr.model.AsyncSlice;const EventSet=tr.model.EventSet;const UI_COMP_NAME='INPUT_EVENT_LATENCY_UI_COMPONENT';const ORIGINAL_COMP_NAME='INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT';const BEGIN_COMP_NAME='INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT';const END_COMP_NAME='INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT';const MAIN_RENDERER_THREAD_NAME='CrRendererMain';const COMPOSITOR_THREAD_NAME='Compositor';const POSTTASK_FLOW_EVENT='disabled-by-default-toplevel.flow';const IPC_FLOW_EVENT='disabled-by-default-ipc.flow';const INPUT_EVENT_TYPE_NAMES={CHAR:'Char',CLICK:'GestureClick',CONTEXT_MENU:'ContextMenu',FLING_CANCEL:'GestureFlingCancel',FLING_START:'GestureFlingStart',KEY_DOWN:'KeyDown',KEY_DOWN_RAW:'RawKeyDown',KEY_UP:'KeyUp',LATENCY_SCROLL_UPDATE:'ScrollUpdate',MOUSE_DOWN:'MouseDown',MOUSE_ENTER:'MouseEnter',MOUSE_LEAVE:'MouseLeave',MOUSE_MOVE:'MouseMove',MOUSE_UP:'MouseUp',MOUSE_WHEEL:'MouseWheel',PINCH_BEGIN:'GesturePinchBegin',PINCH_END:'GesturePinchEnd',PINCH_UPDATE:'GesturePinchUpdate',SCROLL_BEGIN:'GestureScrollBegin',SCROLL_END:'GestureScrollEnd',SCROLL_UPDATE:'GestureScrollUpdate',SCROLL_UPDATE_RENDERER:'ScrollUpdate',SHOW_PRESS:'GestureShowPress',TAP:'GestureTap',TAP_CANCEL:'GestureTapCancel',TAP_DOWN:'GestureTapDown',TOUCH_CANCEL:'TouchCancel',TOUCH_END:'TouchEnd',TOUCH_MOVE:'TouchMove',TOUCH_START:'TouchStart',UNKNOWN:'UNKNOWN'};function InputLatencyAsyncSlice(){AsyncSlice.apply(this,arguments);this.associatedEvents_=new EventSet();this.typeName_=undefined;if(!this.isLegacyEvent){this.determineModernTypeName_();}}
 InputLatencyAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get isLegacyEvent(){return this.title==='InputLatency';},get typeName(){if(!this.typeName_){this.determineLegacyTypeName_();}
-return this.typeName_;},checkTypeName_:function(){if(!this.typeName_){throw new Error('Unable to determine typeName');}
-var found=false;for(var typeName in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[typeName]){found=true;break;}}
-if(!found){this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;}},determineModernTypeName_:function(){var lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)return;var characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_:function(){for(var subSlice of this.enumerateAllDescendents()){var subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)continue;if(!subSlice.typeName)continue;if(this.typeName_&&subSlice.typeName_){var subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames');}}
+return this.typeName_;},checkTypeName_(){if(!this.typeName_){throw new Error('Unable to determine typeName');}
+let found=false;for(const typeName in INPUT_EVENT_TYPE_NAMES){if(this.typeName===INPUT_EVENT_TYPE_NAMES[typeName]){found=true;break;}}
+if(!found){this.typeName_=INPUT_EVENT_TYPE_NAMES.UNKNOWN;}},determineModernTypeName_(){const lastColonIndex=this.title.lastIndexOf(':');if(lastColonIndex<0)return;const characterAfterLastColonIndex=lastColonIndex+1;this.typeName_=this.title.slice(characterAfterLastColonIndex);this.checkTypeName_();},determineLegacyTypeName_(){for(const subSlice of this.enumerateAllDescendents()){const subSliceIsAInputLatencyAsyncSlice=(subSlice instanceof InputLatencyAsyncSlice);if(!subSliceIsAInputLatencyAsyncSlice)continue;if(!subSlice.typeName)continue;if(this.typeName_&&subSlice.typeName_){const subSliceHasDifferentTypeName=(this.typeName_!==subSlice.typeName_);if(subSliceHasDifferentTypeName){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() '+' found multiple typeNames');}}
 this.typeName_=subSlice.typeName_;}
 if(!this.typeName_){throw new Error('InputLatencyAsyncSlice.determineLegacyTypeName_() failed');}
-this.checkTypeName_();},getRendererHelper:function(sourceSlices){var traceModel=this.startThread.parent.model;var modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)return undefined;var mainThread=undefined;var compositorThread=undefined;for(var i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME){mainThread=sourceSlices[i].parentContainer;}else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME){compositorThread=sourceSlices[i].parentContainer;}
+this.checkTypeName_();},getRendererHelper(sourceSlices){const traceModel=this.startThread.parent.model;const modelHelper=traceModel.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper)return undefined;let mainThread=undefined;let compositorThread=undefined;for(const i in sourceSlices){if(sourceSlices[i].parentContainer.name===MAIN_RENDERER_THREAD_NAME){mainThread=sourceSlices[i].parentContainer;}else if(sourceSlices[i].parentContainer.name===COMPOSITOR_THREAD_NAME){compositorThread=sourceSlices[i].parentContainer;}
 if(mainThread&&compositorThread)break;}
-var rendererHelpers=modelHelper.rendererHelpers;var pids=Object.keys(rendererHelpers);for(var i=0;i<pids.length;i++){var pid=pids[i];var rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread){return rendererHelper;}}
-return undefined;},addEntireSliceHierarchy:function(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents:function(flowEvents){var slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);var newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1){slices.push(newSource);}},this);var lastFlowEvent=flowEvents[flowEvents.length-1];var lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1){slices.push(lastSource);}
-return slices;},addScrollUpdateEvents:function(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread){return;}
-var compositorThread=rendererHelper.compositorThread;var gestureScrollUpdateStart=this.start;var gestureScrollUpdateEnd=this.end;var allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(var i in allCompositorAsyncSlices){var slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')continue;var parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd){continue;}}else{if(parseInt(parentId)!==parseInt(this.id)){continue;}}
-slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs:function(slice,flowEvents){var fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1){fromOtherInputs=true;}}},this);},this);return fromOtherInputs;},triggerOtherInputs:function(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0){return false;}
-var flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice){return false;}
-var endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents)){return true;}
-return false;},followSubsequentSlices:function(event,queue,visited,flowEvents){var stopFollowing=false;var inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)return;if(slice.title==='TaskQueueManager::RunTask')return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame'){return;}
+const rendererHelpers=modelHelper.rendererHelpers;const pids=Object.keys(rendererHelpers);for(let i=0;i<pids.length;i++){const pid=pids[i];const rendererHelper=rendererHelpers[pid];if(rendererHelper.mainThread===mainThread||rendererHelper.compositorThread===compositorThread){return rendererHelper;}}
+return undefined;},addEntireSliceHierarchy(slice){this.associatedEvents_.push(slice);slice.iterateAllSubsequentSlices(function(subsequentSlice){this.associatedEvents_.push(subsequentSlice);},this);},addDirectlyAssociatedEvents(flowEvents){const slices=[];flowEvents.forEach(function(flowEvent){this.associatedEvents_.push(flowEvent);const newSource=flowEvent.startSlice.mostTopLevelSlice;if(slices.indexOf(newSource)===-1){slices.push(newSource);}},this);const lastFlowEvent=flowEvents[flowEvents.length-1];const lastSource=lastFlowEvent.endSlice.mostTopLevelSlice;if(slices.indexOf(lastSource)===-1){slices.push(lastSource);}
+return slices;},addScrollUpdateEvents(rendererHelper){if(!rendererHelper||!rendererHelper.compositorThread){return;}
+const compositorThread=rendererHelper.compositorThread;const gestureScrollUpdateStart=this.start;const gestureScrollUpdateEnd=this.end;const allCompositorAsyncSlices=compositorThread.asyncSliceGroup.slices;for(const i in allCompositorAsyncSlices){const slice=allCompositorAsyncSlices[i];if(slice.title!=='Latency::ScrollUpdate')continue;const parentId=slice.args.data.INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT.sequence_number;if(parentId===undefined){if(slice.start<gestureScrollUpdateStart||slice.start>=gestureScrollUpdateEnd){continue;}}else{if(parseInt(parentId)!==parseInt(this.id)){continue;}}
+slice.associatedEvents.forEach(function(event){this.associatedEvents_.push(event);},this);break;}},belongToOtherInputs(slice,flowEvents){let fromOtherInputs=false;slice.iterateEntireHierarchy(function(subsequentSlice){if(fromOtherInputs)return;subsequentSlice.inFlowEvents.forEach(function(inflow){if(fromOtherInputs)return;if(inflow.category.indexOf('input')>-1){if(flowEvents.indexOf(inflow)===-1){fromOtherInputs=true;}}},this);},this);return fromOtherInputs;},triggerOtherInputs(event,flowEvents){if(event.outFlowEvents===undefined||event.outFlowEvents.length===0){return false;}
+const flow=event.outFlowEvents[0];if(flow.category!==POSTTASK_FLOW_EVENT||!flow.endSlice){return false;}
+const endSlice=flow.endSlice;if(this.belongToOtherInputs(endSlice.mostTopLevelSlice,flowEvents)){return true;}
+return false;},followSubsequentSlices(event,queue,visited,flowEvents){let stopFollowing=false;let inputAck=false;event.iterateAllSubsequentSlices(function(slice){if(stopFollowing)return;if(slice.title==='TaskQueueManager::RunTask')return;if(slice.title==='ThreadProxy::ScheduledActionSendBeginMainFrame'){return;}
 if(slice.title==='Scheduler::ScheduleBeginImplFrameDeadline'){if(this.triggerOtherInputs(slice,flowEvents))return;}
 if(slice.title==='CompositorImpl::PostComposite'){if(this.triggerOtherInputs(slice,flowEvents))return;}
 if(slice.title==='InputRouterImpl::ProcessInputEventAck'){inputAck=true;}
 if(inputAck&&slice.title==='InputRouterImpl::FilterAndSendWebInputEvent'){stopFollowing=true;}
-this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice:function(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);var nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw:function(beginImplFrame,visited){var pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){var nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices:function(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start){return a.start-b.start;}
-return a.guid-b.guid;});},addRasterizationEvents:function(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads){return;}
-var rasterWorkerThreads=rendererHelper.rasterWorkerThreads;var prepareTileId=prepareTiles.args.prepare_tiles_id;var pendingEventQueue=[];if(sortedRasterizerSlices.length===0){this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);}
-var numFinishedTasks=0;var RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';var IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';var FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(var i=0;i<sortedRasterizerSlices.length;i++){var task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepareTileId){this.addEntireSliceHierarchy(task.mostTopLevelSlice);}}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)break;}}}
-while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents:function(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){var pendingEventQueue=[];var visitedEvents=new EventSet();var beginImplFrame=undefined;var prepareTiles=undefined;var sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!==0){var event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);var COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles){this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);}
-var COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame){this.backtraceFromDraw(beginImplFrame,visitedEvents);}}
-var INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU){this.addScrollUpdateEvents(rendererHelper);}},get associatedEvents(){if(this.associatedEvents_.length!==0){return this.associatedEvents_;}
-var modelIndices=this.startThread.parent.model.modelIndices;var flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0){return this.associatedEvents_;}
-var sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);var rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))return undefined;var data=this.args.data;if(!(END_COMP_NAME in data))return undefined;var latency=0;var endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
-return latency;}};var eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];var allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.subTypes.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES,};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr',LOCAL_ID_PHASES:new Set(['N','D','O','(',')'])};});'use strict';tr.exportTo('tr.e.audits',function(){var Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);var modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}}
-ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate:function(){if(!this.modelHelper)return;for(var pid in this.modelHelper.rendererHelpers){var rendererHelper=this.modelHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI){rendererHelper.process.important=false;}}},installUserFriendlyCategoryDriverIfNeeded:function(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit:function(){if(!this.modelHelper)return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();}};Auditor.register(ChromeAuditor);return{ChromeAuditor,};});'use strict';tr.exportTo('tr.e.chrome',function(){var KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.math.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.math.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds){this.needsLayoutReasons_.push('self');}
+this.followCurrentSlice(slice,queue,visited);},this);},followCurrentSlice(event,queue,visited){event.outFlowEvents.forEach(function(outflow){if((outflow.category===POSTTASK_FLOW_EVENT||outflow.category===IPC_FLOW_EVENT)&&outflow.endSlice){this.associatedEvents_.push(outflow);const nextEvent=outflow.endSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);queue.push(nextEvent);}}},this);},backtraceFromDraw(beginImplFrame,visited){const pendingEventQueue=[];pendingEventQueue.push(beginImplFrame.mostTopLevelSlice);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);event.inFlowEvents.forEach(function(inflow){if(inflow.category===POSTTASK_FLOW_EVENT&&inflow.startSlice){const nextEvent=inflow.startSlice.mostTopLevelSlice;if(!visited.contains(nextEvent)){visited.push(nextEvent);pendingEventQueue.push(nextEvent);}}},this);}},sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices){rasterWorkerThreads.forEach(function(rasterizer){Array.prototype.push.apply(sortedRasterizerSlices,rasterizer.sliceGroup.slices);},this);sortedRasterizerSlices.sort(function(a,b){if(a.start!==b.start){return a.start-b.start;}
+return a.guid-b.guid;});},addRasterizationEvents(prepareTiles,rendererHelper,visited,flowEvents,sortedRasterizerSlices){if(!prepareTiles.args.prepare_tiles_id)return;if(!rendererHelper||!rendererHelper.rasterWorkerThreads){return;}
+const rasterWorkerThreads=rendererHelper.rasterWorkerThreads;const prepareTileId=prepareTiles.args.prepare_tiles_id;const pendingEventQueue=[];if(sortedRasterizerSlices.length===0){this.sortRasterizerSlices(rasterWorkerThreads,sortedRasterizerSlices);}
+let numFinishedTasks=0;const RASTER_TASK_TITLE='RasterizerTaskImpl::RunOnWorkerThread';const IMAGEDECODE_TASK_TITLE='ImageDecodeTaskImpl::RunOnWorkerThread';const FINISHED_TASK_TITLE='TaskSetFinishedTaskImpl::RunOnWorkerThread';for(let i=0;i<sortedRasterizerSlices.length;i++){const task=sortedRasterizerSlices[i];if(task.title===RASTER_TASK_TITLE||task.title===IMAGEDECODE_TASK_TITLE){if(task.args.source_prepare_tiles_id===prepareTileId){this.addEntireSliceHierarchy(task.mostTopLevelSlice);}}else if(task.title===FINISHED_TASK_TITLE){if(task.start>prepareTiles.start){pendingEventQueue.push(task.mostTopLevelSlice);if(++numFinishedTasks===3)break;}}}
+while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followSubsequentSlices(event,pendingEventQueue,visited,flowEvents);}},addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents,sortedRasterizerSlices){const pendingEventQueue=[];const visitedEvents=new EventSet();let beginImplFrame=undefined;let prepareTiles=undefined;sortedRasterizerSlices=[];sourceSlices.forEach(function(sourceSlice){if(!visitedEvents.contains(sourceSlice)){visitedEvents.push(sourceSlice);pendingEventQueue.push(sourceSlice);}},this);while(pendingEventQueue.length!==0){const event=pendingEventQueue.pop();this.addEntireSliceHierarchy(event);this.followCurrentSlice(event,pendingEventQueue,visitedEvents);this.followSubsequentSlices(event,pendingEventQueue,visitedEvents,flowEvents);const COMPOSITOR_PREPARE_TILES='TileManager::PrepareTiles';prepareTiles=event.findDescendentSlice(COMPOSITOR_PREPARE_TILES);if(prepareTiles){this.addRasterizationEvents(prepareTiles,rendererHelper,visitedEvents,flowEvents,sortedRasterizerSlices);}
+const COMPOSITOR_ON_BIFD='Scheduler::OnBeginImplFrameDeadline';beginImplFrame=event.findDescendentSlice(COMPOSITOR_ON_BIFD);if(beginImplFrame){this.backtraceFromDraw(beginImplFrame,visitedEvents);}}
+const INPUT_GSU='InputLatency::GestureScrollUpdate';if(this.title===INPUT_GSU){this.addScrollUpdateEvents(rendererHelper);}},get associatedEvents(){if(this.associatedEvents_.length!==0){return this.associatedEvents_;}
+const modelIndices=this.startThread.parent.model.modelIndices;const flowEvents=modelIndices.getFlowEventsWithId(this.id);if(flowEvents.length===0){return this.associatedEvents_;}
+const sourceSlices=this.addDirectlyAssociatedEvents(flowEvents);const rendererHelper=this.getRendererHelper(sourceSlices);this.addOtherCausallyRelatedEvents(rendererHelper,sourceSlices,flowEvents);return this.associatedEvents_;},get inputLatency(){if(!('data'in this.args))return undefined;const data=this.args.data;if(!(END_COMP_NAME in data))return undefined;let latency=0;const endTime=data[END_COMP_NAME].time;if(ORIGINAL_COMP_NAME in data){latency=endTime-data[ORIGINAL_COMP_NAME].time;}else if(UI_COMP_NAME in data){latency=endTime-data[UI_COMP_NAME].time;}else if(BEGIN_COMP_NAME in data){latency=endTime-data[BEGIN_COMP_NAME].time;}else{throw new Error('No valid begin latency component');}
+return latency;}};const eventTypeNames=['Char','ContextMenu','GestureClick','GestureFlingCancel','GestureFlingStart','GestureScrollBegin','GestureScrollEnd','GestureScrollUpdate','GestureShowPress','GestureTap','GestureTapCancel','GestureTapDown','GesturePinchBegin','GesturePinchEnd','GesturePinchUpdate','KeyDown','KeyUp','MouseDown','MouseEnter','MouseLeave','MouseMove','MouseUp','MouseWheel','RawKeyDown','ScrollUpdate','TouchCancel','TouchEnd','TouchMove','TouchStart'];const allTypeNames=['InputLatency'];eventTypeNames.forEach(function(eventTypeName){allTypeNames.push('InputLatency:'+eventTypeName);allTypeNames.push('InputLatency::'+eventTypeName);});AsyncSlice.subTypes.register(InputLatencyAsyncSlice,{typeNames:allTypeNames,categoryParts:['latencyInfo']});return{InputLatencyAsyncSlice,INPUT_EVENT_TYPE_NAMES,};});'use strict';tr.exportTo('tr.model',function(){return{BROWSER_PROCESS_PID_REF:-1,OBJECT_DEFAULT_SCOPE:'ptr',LOCAL_ID_PHASES:new Set(['N','D','O','(',')'])};});'use strict';tr.exportTo('tr.e.audits',function(){const Auditor=tr.c.Auditor;function ChromeAuditor(model){Auditor.call(this,model);const modelHelper=this.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper&&modelHelper.browserHelper){this.modelHelper=modelHelper;}else{this.modelHelper=undefined;}}
+ChromeAuditor.prototype={__proto__:Auditor.prototype,runAnnotate(){if(!this.modelHelper)return;for(const pid in this.modelHelper.rendererHelpers){const rendererHelper=this.modelHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI){rendererHelper.process.important=false;}}},installUserFriendlyCategoryDriverIfNeeded(){this.model.addUserFriendlyCategoryDriver(tr.e.chrome.ChromeUserFriendlyCategoryDriver);},runAudit(){if(!this.modelHelper)return;this.model.replacePIDRefsInPatchups(tr.model.BROWSER_PROCESS_PID_REF,this.modelHelper.browserProcess.pid);this.model.applyObjectRefPatchups();}};Auditor.register(ChromeAuditor);return{ChromeAuditor,};});'use strict';tr.exportTo('tr.e.chrome',function(){const KNOWN_PROPERTIES={absX:1,absY:1,address:1,anonymous:1,childNeeds:1,children:1,classNames:1,col:1,colSpan:1,float:1,height:1,htmlId:1,name:1,posChildNeeds:1,positioned:1,positionedMovement:1,relX:1,relY:1,relativePositioned:1,row:1,rowSpan:1,selfNeeds:1,stickyPositioned:1,tag:1,width:1};function LayoutObject(snapshot,args){this.snapshot_=snapshot;this.id_=args.address;this.name_=args.name;this.childLayoutObjects_=[];this.otherProperties_={};this.tag_=args.tag;this.relativeRect_=tr.b.math.Rect.fromXYWH(args.relX,args.relY,args.width,args.height);this.absoluteRect_=tr.b.math.Rect.fromXYWH(args.absX,args.absY,args.width,args.height);this.isFloat_=args.float;this.isStickyPositioned_=args.stickyPositioned;this.isPositioned_=args.positioned;this.isRelativePositioned_=args.relativePositioned;this.isAnonymous_=args.anonymous;this.htmlId_=args.htmlId;this.classNames_=args.classNames;this.needsLayoutReasons_=[];if(args.selfNeeds){this.needsLayoutReasons_.push('self');}
 if(args.childNeeds){this.needsLayoutReasons_.push('child');}
 if(args.posChildNeeds){this.needsLayoutReasons_.push('positionedChild');}
 if(args.positionedMovement){this.needsLayoutReasons_.push('positionedMovement');}
 this.tableRow_=args.row;this.tableCol_=args.col;this.tableRowSpan_=args.rowSpan;this.tableColSpan_=args.colSpan;if(args.children){args.children.forEach(function(child){this.childLayoutObjects_.push(new LayoutObject(snapshot,child));}.bind(this));}
-for(var property in args){if(!KNOWN_PROPERTIES[property]){this.otherProperties_[property]=args[property];}}}
-LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree:function(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){var names=[];for(var name in this.otherProperties_){names.push(name);}
-return names;},getProperty:function(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject,};});'use strict';tr.exportTo('tr.e.chrome',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
+for(const property in args){if(!KNOWN_PROPERTIES[property]){this.otherProperties_[property]=args[property];}}}
+LayoutObject.prototype={get snapshot(){return this.snapshot_;},get id(){return this.id_;},get name(){return this.name_;},get tag(){return this.tag_;},get relativeRect(){return this.relativeRect_;},get absoluteRect(){return this.absoluteRect_;},get isPositioned(){return this.isPositioned_;},get isFloat(){return this.isFloat_;},get isStickyPositioned(){return this.isStickyPositioned_;},get isRelativePositioned(){return this.isRelativePositioned_;},get isAnonymous(){return this.isAnonymous_;},get tableRow(){return this.tableRow_;},get tableCol(){return this.tableCol_;},get tableRowSpan(){return this.tableRowSpan_;},get tableColSpan(){return this.tableColSpan_;},get htmlId(){return this.htmlId_;},get classNames(){return this.classNames_;},get needsLayoutReasons(){return this.needsLayoutReasons_;},get hasChildLayoutObjects(){return this.childLayoutObjects_.length>0;},get childLayoutObjects(){return this.childLayoutObjects_;},traverseTree(cb,opt_this){cb.call(opt_this,this);if(!this.hasChildLayoutObjects)return;this.childLayoutObjects.forEach(function(child){child.traverseTree(cb,opt_this);});},get otherPropertyNames(){const names=[];for(const name in this.otherProperties_){names.push(name);}
+return names;},getProperty(name){return this.otherProperties_[name];},get previousSnapshotLayoutObject(){if(!this.snapshot.previousSnapshot)return undefined;return this.snapshot.previousSnapshot.getLayoutObjectById(this.id);},get nextSnapshotLayoutObject(){if(!this.snapshot.nextSnapshot)return undefined;return this.snapshot.nextSnapshot.getLayoutObjectById(this.id);}};return{LayoutObject,};});'use strict';tr.exportTo('tr.e.chrome',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function LayoutTreeInstance(){ObjectInstance.apply(this,arguments);}
 LayoutTreeInstance.prototype={__proto__:ObjectInstance.prototype,};ObjectInstance.subTypes.register(LayoutTreeInstance,{typeName:'LayoutTree'});function LayoutTreeSnapshot(){ObjectSnapshot.apply(this,arguments);this.rootLayoutObject=new tr.e.chrome.LayoutObject(this,this.args);}
 LayoutTreeSnapshot.prototype={__proto__:ObjectSnapshot.prototype,};ObjectSnapshot.subTypes.register(LayoutTreeSnapshot,{typeName:'LayoutTree'});return{LayoutTreeInstance,LayoutTreeSnapshot,};});'use strict';tr.exportTo('tr.model',function(){function EventContainer(){this.guid_=tr.b.GUID.allocateSimple();this.important=true;this.bounds_=new tr.b.math.Range();}
-EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds:function(){throw new Error('Not implemented');},shiftTimestampsForward:function(amount){throw new Error('Not implemented');},childEvents:function*(){},getDescendantEvents:function*(){yield*this.childEvents();for(var container of this.childEventContainers()){yield*container.getDescendantEvents();}},childEventContainers:function*(){},getDescendantEventContainers:function*(){yield this;for(var container of this.childEventContainers()){yield*container.getDescendantEventContainers();}},findTopmostSlicesInThisContainer:function*(eventPredicate,opt_this){},findTopmostSlices:function*(eventPredicate){for(var ec of this.getDescendantEventContainers()){yield*ec.findTopmostSlicesInThisContainer(eventPredicate);}},findTopmostSlicesNamed:function*(name){yield*this.findTopmostSlices(e=>e.title===name);}};return{EventContainer,};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;class ResourceUsageSample extends Event{constructor(series,start,usage){super();this.series_=series;this.start_=start;this.usage_=usage;}
+EventContainer.prototype={get guid(){return this.guid_;},get stableId(){throw new Error('Not implemented');},get bounds(){return this.bounds_;},updateBounds(){throw new Error('Not implemented');},shiftTimestampsForward(amount){throw new Error('Not implemented');},*childEvents(){},*getDescendantEvents(){yield*this.childEvents();for(const container of this.childEventContainers()){yield*container.getDescendantEvents();}},*childEventContainers(){},*getDescendantEventContainers(){yield this;for(const container of this.childEventContainers()){yield*container.getDescendantEventContainers();}},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){},*findTopmostSlices(eventPredicate){for(const ec of this.getDescendantEventContainers()){yield*ec.findTopmostSlicesInThisContainer(eventPredicate);}},*findTopmostSlicesNamed(name){yield*this.findTopmostSlices(e=>e.title===name);}};return{EventContainer,};});'use strict';tr.exportTo('tr.model',function(){const Event=tr.model.Event;const EventRegistry=tr.model.EventRegistry;class ResourceUsageSample extends Event{constructor(series,start,usage){super();this.series_=series;this.start_=start;this.usage_=usage;}
 get series(){return this.series_;}
 get start(){return this.start_;}
 set start(value){this.start_=value;}
 get usage(){return this.usage_;}
 set usage(value){this.usage_=value;}
 addBoundsToRange(range){range.addValue(this.start);}}
-EventRegistry.register(ResourceUsageSample,{name:'resourceUsageSample',pluralName:'resourceUsageSamples'});return{ResourceUsageSample,};});'use strict';tr.exportTo('tr.model',function(){var ResourceUsageSample=tr.model.ResourceUsageSample;class ResourceUsageSeries extends tr.model.EventContainer{constructor(device){super();this.device_=device;this.samples_=[];}
+EventRegistry.register(ResourceUsageSample,{name:'resourceUsageSample',pluralName:'resourceUsageSamples'});return{ResourceUsageSample,};});'use strict';tr.exportTo('tr.model',function(){const ResourceUsageSample=tr.model.ResourceUsageSample;class ResourceUsageSeries extends tr.model.EventContainer{constructor(device){super();this.device_=device;this.samples_=[];}
 get device(){return this.device_;}
 get samples(){return this.samples_;}
 get stableId(){return this.device_.stableId+'.ResourceUsageSeries';}
-addUsageSample(ts,val){var sample=new ResourceUsageSample(this,ts,val);this.samples_.push(sample);return sample;}
-computeResourceTimeConsumedInMs(start,end){var measurementRange=tr.b.math.Range.fromExplicitRange(start,end);var resourceTimeInMs=0;var startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;var endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0)startIndex=0;for(var i=startIndex;i<endIndex;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);var intersectionRangeInMs=measurementRange.findIntersection(sampleRange);resourceTimeInMs+=intersectionRangeInMs.duration*sample.usage;}
+addUsageSample(ts,val){const sample=new ResourceUsageSample(this,ts,val);this.samples_.push(sample);return sample;}
+computeResourceTimeConsumedInMs(start,end){const measurementRange=tr.b.math.Range.fromExplicitRange(start,end);let resourceTimeInMs=0;let startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;const endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0)startIndex=0;for(let i=startIndex;i<endIndex;i++){const sample=this.samples[i];const nextSample=this.samples[i+1];const sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);const intersectionRangeInMs=measurementRange.findIntersection(sampleRange);resourceTimeInMs+=intersectionRangeInMs.duration*sample.usage;}
 return resourceTimeInMs;}
-getSamplesWithinRange(start,end){var startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start);var endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);}
-shiftTimestampsForward(amount){for(var i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}}
+getSamplesWithinRange(start,end){const startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start);const endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);}
+shiftTimestampsForward(amount){for(let i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}}
 updateBounds(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);}*childEvents(){yield*this.samples_;}}
 return{ResourceUsageSeries,};});'use strict';tr.exportTo('tr.e.audits',function(){class CpuUsageAuditor extends tr.c.Auditor{constructor(model){super();this.model_=model;}
 runAnnotate(){this.model_.device.cpuUsageSeries=this.computeCpuUsageSeries_(this.model_.bounds.min,this.model_.bounds.max,this.computeCpuUsage_());}
-computeBinSize_(start,end){var MIN_BIN_SIZE_MS=1.0;var MAX_NUM_BINS=100000;var interval=end-start;var binSize=MIN_BIN_SIZE_MS;while(binSize*MAX_NUM_BINS<interval)binSize*=2;return binSize;}
-computeCpuUsageSeries_(start,end,usageRecords){var series=new tr.model.ResourceUsageSeries();if(start===undefined)return series;var binSize=this.computeBinSize_(start,end);var numBins=Math.ceil((end-start)/binSize);var arr=new Array(numBins).fill(0);for(var record of usageRecords){var firstIndex=Math.ceil((record.start-start)/binSize);var lastIndex=Math.floor((record.end-start)/binSize);for(var i=firstIndex;i<=lastIndex;i++)arr[i]+=record.usage;}
-for(var i=0;i<numBins;i++){series.addUsageSample(start+(i*binSize),arr[i]);}
+computeBinSize_(start,end){const MIN_BIN_SIZE_MS=1.0;const MAX_NUM_BINS=100000;const interval=end-start;let binSize=MIN_BIN_SIZE_MS;while(binSize*MAX_NUM_BINS<interval)binSize*=2;return binSize;}
+computeCpuUsageSeries_(start,end,usageRecords){const series=new tr.model.ResourceUsageSeries();if(start===undefined)return series;const binSize=this.computeBinSize_(start,end);const numBins=Math.ceil((end-start)/binSize);const arr=new Array(numBins).fill(0);for(const record of usageRecords){const firstIndex=Math.ceil((record.start-start)/binSize);const lastIndex=Math.floor((record.end-start)/binSize);for(let i=firstIndex;i<=lastIndex;i++)arr[i]+=record.usage;}
+for(let i=0;i<numBins;i++){series.addUsageSample(start+(i*binSize),arr[i]);}
 return series;}
-computeCpuUsage_(){var model=this.model_;var result=[];for(var pid in model.processes){for(var e of model.processes[pid].getDescendantEvents()){if(!(e instanceof tr.model.ThreadSlice)||e.duration===0||e.cpuDuration===undefined){continue;}
+computeCpuUsage_(){const model=this.model_;const result=[];for(const pid in model.processes){for(const e of model.processes[pid].getDescendantEvents()){if(!(e instanceof tr.model.ThreadSlice)||e.duration===0||e.cpuDuration===undefined){continue;}
 if(e.selfTime===0||e.selfTime===undefined||e.cpuSelfTime===undefined){continue;}
-var usage=tr.b.math.clamp(e.cpuSelfTime/e.selfTime,0,1);var lastTime=e.start;for(var subslice of e.subSlices){result.push({usage,start:lastTime,end:subslice.start});lastTime=subslice.end;}
+const usage=tr.b.math.clamp(e.cpuSelfTime/e.selfTime,0,1);let lastTime=e.start;for(const subslice of e.subSlices){result.push({usage,start:lastTime,end:subslice.start});lastTime=subslice.end;}
 result.push({usage,start:lastTime,end:e.end});}}
 return result;}}
-tr.c.Auditor.register(CpuUsageAuditor);return{CpuUsageAuditor:CpuUsageAuditor};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
+tr.c.Auditor.register(CpuUsageAuditor);return{CpuUsageAuditor};});'use strict';tr.exportTo('tr.b',function(){function Base64(){}
 function b64ToUint6(nChr){if(nChr>64&&nChr<91)return nChr-65;if(nChr>96&&nChr<123)return nChr-71;if(nChr>47&&nChr<58)return nChr+4;if(nChr===43)return 62;if(nChr===47)return 63;return 0;}
-Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;};Base64.EncodeArrayBufferToString=function(input){var binary='';var bytes=new Uint8Array(input);var len=bytes.byteLength;for(var i=0;i<len;i++){binary+=String.fromCharCode(bytes[i]);}
-return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){var nInLen=input.length;var nOutLen=nInLen*3+1>>2;var nMod3=0;var nMod4=0;var nUint24=0;var nOutIdx=0;if(nOutLen>output.byteLength){throw new Error('Output buffer too small to decode.');}
-for(var nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
+Base64.getDecodedBufferLength=function(input){return input.length*3+1>>2;};Base64.EncodeArrayBufferToString=function(input){let binary='';const bytes=new Uint8Array(input);const len=bytes.byteLength;for(let i=0;i<len;i++){binary+=String.fromCharCode(bytes[i]);}
+return btoa(binary);};Base64.DecodeToTypedArray=function(input,output){const nInLen=input.length;const nOutLen=nInLen*3+1>>2;let nMod3=0;let nMod4=0;let nUint24=0;let nOutIdx=0;if(nOutLen>output.byteLength){throw new Error('Output buffer too small to decode.');}
+for(let nInIdx=0;nInIdx<nInLen;nInIdx++){nMod4=nInIdx&3;nUint24|=b64ToUint6(input.charCodeAt(nInIdx))<<18-6*nMod4;if(nMod4===3||nInLen-nInIdx===1){for(nMod3=0;nMod3<3&&nOutIdx<nOutLen;nMod3++,nOutIdx++){output.setUint8(nOutIdx,nUint24>>>(16>>>nMod3&24)&255);}
 nUint24=0;}}
 return nOutIdx-1;};Base64.btoa=function(input){return btoa(input);};Base64.atob=function(input){return atob(input);};return{Base64,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';var kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
-EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version!==2){throw new Error('Incompatible EventTrace event version.');}
-var bufferSize=decoder.decodeUInt32();var version=decoder.decodeUInt32();var providerVersion=decoder.decodeUInt32();var numberOfProcessors=decoder.decodeUInt32();var endTime=decoder.decodeUInt64ToString();var timerResolution=decoder.decodeUInt32();var maxFileSize=decoder.decodeUInt32();var logFileMode=decoder.decodeUInt32();var buffersWritten=decoder.decodeUInt32();var startBuffers=decoder.decodeUInt32();var pointerSize=decoder.decodeUInt32();var eventsLost=decoder.decodeUInt32();var cpuSpeed=decoder.decodeUInt32();var loggerName=decoder.decodeUInteger(header.is64);var logFileName=decoder.decodeUInteger(header.is64);var timeZoneInformation=decoder.decodeTimeZoneInformation();var padding=decoder.decodeUInt32();var bootTime=decoder.decodeUInt64ToString();var perfFreq=decoder.decodeUInt64ToString();var startTime=decoder.decodeUInt64ToString();var reservedFlags=decoder.decodeUInt32();var buffersLost=decoder.decodeUInt32();var sessionNameString=decoder.decodeW16String();var logFileNameString=decoder.decodeW16String();return{bufferSize:bufferSize,version:version,providerVersion:providerVersion,numberOfProcessors:numberOfProcessors,endTime:endTime,timerResolution:timerResolution,maxFileSize:maxFileSize,logFileMode:logFileMode,buffersWritten:buffersWritten,startBuffers:startBuffers,pointerSize:pointerSize,eventsLost:eventsLost,cpuSpeed:cpuSpeed,loggerName:loggerName,logFileName:logFileName,timeZoneInformation:timeZoneInformation,bootTime:bootTime,perfFreq:perfFreq,startTime:startTime,reservedFlags:reservedFlags,buffersLost:buffersLost,sessionNameString:sessionNameString,logFileNameString:logFileNameString};},decodeHeader:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';var kProcessStartOpcode=1;var kProcessEndOpcode=2;var kProcessDCStartOpcode=3;var kProcessDCEndOpcode=4;var kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
-ProcessParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>5){throw new Error('Incompatible Process event version.');}
-var pageDirectoryBase;if(header.version===1){pageDirectoryBase=decoder.decodeUInteger(header.is64);}
-var uniqueProcessKey;if(header.version>=2){uniqueProcessKey=decoder.decodeUInteger(header.is64);}
-var processId=decoder.decodeUInt32();var parentId=decoder.decodeUInt32();var sessionId;var exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
-var directoryTableBase;if(header.version>=3){directoryTableBase=decoder.decodeUInteger(header.is64);}
-var flags;if(header.version>=4){flags=decoder.decodeUInt32();}
-var userSID=decoder.decodeSID(header.is64);var imageFileName;if(header.version>=1){imageFileName=decoder.decodeString();}
-var commandLine;if(header.version>=2){commandLine=decoder.decodeW16String();}
-var packageFullName;var applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
-var exitTime;if(header.version===5&&header.opcode===kProcessDefunctOpcode){exitTime=decoder.decodeUInt64ToString();}
-return{pageDirectoryBase:pageDirectoryBase,uniqueProcessKey:uniqueProcessKey,processId:processId,parentId:parentId,sessionId:sessionId,exitStatus:exitStatus,directoryTableBase:directoryTableBase,flags:flags,userSID:userSID,imageFileName:imageFileName,commandLine:commandLine,packageFullName:packageFullName,applicationId:applicationId,exitTime:exitTime};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
-process.name=fields.imageFileName;return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
-process.name=fields.imageFileName;return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);var process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct:function(header,decoder){var fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var Parser=tr.e.importer.etw.Parser;var guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadStartOpcode=1;var kThreadEndOpcode=2;var kThreadDCStartOpcode=3;var kThreadDCEndOpcode=4;var kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
-ThreadParser.prototype={__proto__:Parser.prototype,decodeFields:function(header,decoder){if(header.version>3){throw new Error('Incompatible Thread event version.');}
-var processId=decoder.decodeUInt32();var threadId=decoder.decodeUInt32();var stackBase;var stackLimit;var userStackBase;var userStackLimit;var affinity;var startAddr;var win32StartAddr;var tebBase;var subProcessTag;var basePriority;var pagePriority;var ioPriority;var threadFlags;var waitMode;if(header.version===1){if(header.opcode===kThreadStartOpcode||header.opcode===kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version===2){startAddr=decoder.decodeUInteger(header.is64);}else{affinity=decoder.decodeUInteger(header.is64);}
+Parser.prototype={__proto__:Object.prototype};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='68FDD900-4A3E-11D1-84F4-0000F80464E3';const kEventTraceHeaderOpcode=0;function EventTraceParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kEventTraceHeaderOpcode,EventTraceParser.prototype.decodeHeader.bind(this));}
+EventTraceParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version!==2){throw new Error('Incompatible EventTrace event version.');}
+const bufferSize=decoder.decodeUInt32();const version=decoder.decodeUInt32();const providerVersion=decoder.decodeUInt32();const numberOfProcessors=decoder.decodeUInt32();const endTime=decoder.decodeUInt64ToString();const timerResolution=decoder.decodeUInt32();const maxFileSize=decoder.decodeUInt32();const logFileMode=decoder.decodeUInt32();const buffersWritten=decoder.decodeUInt32();const startBuffers=decoder.decodeUInt32();const pointerSize=decoder.decodeUInt32();const eventsLost=decoder.decodeUInt32();const cpuSpeed=decoder.decodeUInt32();const loggerName=decoder.decodeUInteger(header.is64);const logFileName=decoder.decodeUInteger(header.is64);const timeZoneInformation=decoder.decodeTimeZoneInformation();const padding=decoder.decodeUInt32();const bootTime=decoder.decodeUInt64ToString();const perfFreq=decoder.decodeUInt64ToString();const startTime=decoder.decodeUInt64ToString();const reservedFlags=decoder.decodeUInt32();const buffersLost=decoder.decodeUInt32();const sessionNameString=decoder.decodeW16String();const logFileNameString=decoder.decodeW16String();return{bufferSize,version,providerVersion,numberOfProcessors,endTime,timerResolution,maxFileSize,logFileMode,buffersWritten,startBuffers,pointerSize,eventsLost,cpuSpeed,loggerName,logFileName,timeZoneInformation,bootTime,perfFreq,startTime,reservedFlags,buffersLost,sessionNameString,logFileNameString};},decodeHeader(header,decoder){const fields=this.decodeFields(header,decoder);return true;}};Parser.register(EventTraceParser);return{EventTraceParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C';const kProcessStartOpcode=1;const kProcessEndOpcode=2;const kProcessDCStartOpcode=3;const kProcessDCEndOpcode=4;const kProcessDefunctOpcode=39;function ProcessParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kProcessStartOpcode,ProcessParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kProcessEndOpcode,ProcessParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kProcessDCStartOpcode,ProcessParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kProcessDCEndOpcode,ProcessParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kProcessDefunctOpcode,ProcessParser.prototype.decodeDefunct.bind(this));}
+ProcessParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version>5){throw new Error('Incompatible Process event version.');}
+let pageDirectoryBase;if(header.version===1){pageDirectoryBase=decoder.decodeUInteger(header.is64);}
+let uniqueProcessKey;if(header.version>=2){uniqueProcessKey=decoder.decodeUInteger(header.is64);}
+const processId=decoder.decodeUInt32();const parentId=decoder.decodeUInt32();let sessionId;let exitStatus;if(header.version>=1){sessionId=decoder.decodeUInt32();exitStatus=decoder.decodeInt32();}
+let directoryTableBase;if(header.version>=3){directoryTableBase=decoder.decodeUInteger(header.is64);}
+let flags;if(header.version>=4){flags=decoder.decodeUInt32();}
+const userSID=decoder.decodeSID(header.is64);let imageFileName;if(header.version>=1){imageFileName=decoder.decodeString();}
+let commandLine;if(header.version>=2){commandLine=decoder.decodeW16String();}
+let packageFullName;let applicationId;if(header.version>=4){packageFullName=decoder.decodeW16String();applicationId=decoder.decodeW16String();}
+let exitTime;if(header.version===5&&header.opcode===kProcessDefunctOpcode){exitTime=decoder.decodeUInt64ToString();}
+return{pageDirectoryBase,uniqueProcessKey,processId,parentId,sessionId,exitStatus,directoryTableBase,flags,userSID,imageFileName,commandLine,packageFullName,applicationId,exitTime};},decodeStart(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeEnd(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDCStart(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);if(process.hasOwnProperty('has_ended')){throw new Error('Process clash detected.');}
+process.name=fields.imageFileName;return true;},decodeDCEnd(header,decoder){const fields=this.decodeFields(header,decoder);const process=this.model.getOrCreateProcess(fields.processId);process.has_ended=true;return true;},decodeDefunct(header,decoder){const fields=this.decodeFields(header,decoder);return true;}};Parser.register(ProcessParser);return{ProcessParser,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const Parser=tr.e.importer.etw.Parser;const guid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';const kThreadStartOpcode=1;const kThreadEndOpcode=2;const kThreadDCStartOpcode=3;const kThreadDCEndOpcode=4;const kThreadCSwitchOpcode=36;function ThreadParser(importer){Parser.call(this,importer);importer.registerEventHandler(guid,kThreadStartOpcode,ThreadParser.prototype.decodeStart.bind(this));importer.registerEventHandler(guid,kThreadEndOpcode,ThreadParser.prototype.decodeEnd.bind(this));importer.registerEventHandler(guid,kThreadDCStartOpcode,ThreadParser.prototype.decodeDCStart.bind(this));importer.registerEventHandler(guid,kThreadDCEndOpcode,ThreadParser.prototype.decodeDCEnd.bind(this));importer.registerEventHandler(guid,kThreadCSwitchOpcode,ThreadParser.prototype.decodeCSwitch.bind(this));}
+ThreadParser.prototype={__proto__:Parser.prototype,decodeFields(header,decoder){if(header.version>3){throw new Error('Incompatible Thread event version.');}
+const processId=decoder.decodeUInt32();const threadId=decoder.decodeUInt32();let stackBase;let stackLimit;let userStackBase;let userStackLimit;let affinity;let startAddr;let win32StartAddr;let tebBase;let subProcessTag;let basePriority;let pagePriority;let ioPriority;let threadFlags;let waitMode;if(header.version===1){if(header.opcode===kThreadStartOpcode||header.opcode===kThreadDCStartOpcode){stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);startAddr=decoder.decodeUInteger(header.is64);win32StartAddr=decoder.decodeUInteger(header.is64);waitMode=decoder.decodeInt8();decoder.skip(3);}}else{stackBase=decoder.decodeUInteger(header.is64);stackLimit=decoder.decodeUInteger(header.is64);userStackBase=decoder.decodeUInteger(header.is64);userStackLimit=decoder.decodeUInteger(header.is64);if(header.version===2){startAddr=decoder.decodeUInteger(header.is64);}else{affinity=decoder.decodeUInteger(header.is64);}
 win32StartAddr=decoder.decodeUInteger(header.is64);tebBase=decoder.decodeUInteger(header.is64);subProcessTag=decoder.decodeUInt32();if(header.version===3){basePriority=decoder.decodeUInt8();pagePriority=decoder.decodeUInt8();ioPriority=decoder.decodeUInt8();threadFlags=decoder.decodeUInt8();}}
-return{processId:processId,threadId:threadId,stackBase:stackBase,stackLimit:stackLimit,userStackBase:userStackBase,userStackLimit:userStackLimit,affinity:affinity,startAddr:startAddr,win32StartAddr:win32StartAddr,tebBase:tebBase,subProcessTag:subProcessTag,waitMode:waitMode,basePriority:basePriority,pagePriority:pagePriority,ioPriority:ioPriority,threadFlags:threadFlags};},decodeCSwitchFields:function(header,decoder){if(header.version!==2){throw new Error('Incompatible Thread event version.');}
-var newThreadId=decoder.decodeUInt32();var oldThreadId=decoder.decodeUInt32();var newThreadPriority=decoder.decodeInt8();var oldThreadPriority=decoder.decodeInt8();var previousCState=decoder.decodeUInt8();var spareByte=decoder.decodeInt8();var oldThreadWaitReason=decoder.decodeInt8();var oldThreadWaitMode=decoder.decodeInt8();var oldThreadState=decoder.decodeInt8();var oldThreadWaitIdealProcessor=decoder.decodeInt8();var newThreadWaitTime=decoder.decodeUInt32();var reserved=decoder.decodeUInt32();return{newThreadId:newThreadId,oldThreadId:oldThreadId,newThreadPriority:newThreadPriority,oldThreadPriority:oldThreadPriority,previousCState:previousCState,spareByte:spareByte,oldThreadWaitReason:oldThreadWaitReason,oldThreadWaitMode:oldThreadWaitMode,oldThreadState:oldThreadState,oldThreadWaitIdealProcessor:oldThreadWaitIdealProcessor,newThreadWaitTime:newThreadWaitTime,reserved:reserved};},decodeStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd:function(header,decoder){var fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch:function(header,decoder){var fields=this.decodeCSwitchFields(header,decoder);var cpu=this.importer.getOrCreateCpu(header.cpu);var newThread=this.importer.getThreadFromWindowsTid(fields.newThreadId);var newThreadName;if(newThread&&newThread.userFriendlyName){newThreadName=newThread.userFriendlyName;}else{var newProcessId=this.importer.getPidFromWindowsTid(fields.newThreadId);var newProcess=this.model.getProcess(newProcessId);var newProcessName;if(newProcess){newProcessName=newProcess.name;}else{newProcessName='Unknown process';}
+return{processId,threadId,stackBase,stackLimit,userStackBase,userStackLimit,affinity,startAddr,win32StartAddr,tebBase,subProcessTag,waitMode,basePriority,pagePriority,ioPriority,threadFlags};},decodeCSwitchFields(header,decoder){if(header.version!==2){throw new Error('Incompatible Thread event version.');}
+const newThreadId=decoder.decodeUInt32();const oldThreadId=decoder.decodeUInt32();const newThreadPriority=decoder.decodeInt8();const oldThreadPriority=decoder.decodeInt8();const previousCState=decoder.decodeUInt8();const spareByte=decoder.decodeInt8();const oldThreadWaitReason=decoder.decodeInt8();const oldThreadWaitMode=decoder.decodeInt8();const oldThreadState=decoder.decodeInt8();const oldThreadWaitIdealProcessor=decoder.decodeInt8();const newThreadWaitTime=decoder.decodeUInt32();const reserved=decoder.decodeUInt32();return{newThreadId,oldThreadId,newThreadPriority,oldThreadPriority,previousCState,spareByte,oldThreadWaitReason,oldThreadWaitMode,oldThreadState,oldThreadWaitIdealProcessor,newThreadWaitTime,reserved};},decodeStart(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeEnd(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeDCStart(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.createThreadIfNeeded(fields.processId,fields.threadId);return true;},decodeDCEnd(header,decoder){const fields=this.decodeFields(header,decoder);this.importer.removeThreadIfPresent(fields.threadId);return true;},decodeCSwitch(header,decoder){const fields=this.decodeCSwitchFields(header,decoder);const cpu=this.importer.getOrCreateCpu(header.cpu);const newThread=this.importer.getThreadFromWindowsTid(fields.newThreadId);let newThreadName;if(newThread&&newThread.userFriendlyName){newThreadName=newThread.userFriendlyName;}else{const newProcessId=this.importer.getPidFromWindowsTid(fields.newThreadId);const newProcess=this.model.getProcess(newProcessId);let newProcessName;if(newProcess){newProcessName=newProcess.name;}else{newProcessName='Unknown process';}
 newThreadName=newProcessName+' (tid '+fields.newThreadId+')';}
 cpu.switchActiveThread(header.timestamp,{},fields.newThreadId,newThreadName,fields);return true;}};Parser.register(ThreadParser);return{ThreadParser,};});'use strict';tr.exportTo('tr.b',function(){function max(a,b){if(a===undefined)return b;if(b===undefined)return a;return Math.max(a,b);}
 function IntervalTree(beginPositionCb,endPositionCb){this.beginPositionCb_=beginPositionCb;this.endPositionCb_=endPositionCb;this.root_=undefined;this.size_=0;}
-IntervalTree.prototype={insert:function(datum){var startPosition=this.beginPositionCb_(datum);var endPosition=this.endPositionCb_(datum);var node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_:function(root,node){if(root===undefined)return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed){this.flipNodeColour_(root);}
+IntervalTree.prototype={insert(datum){const startPosition=this.beginPositionCb_(datum);const endPosition=this.endPositionCb_(datum);const node=new IntervalTreeNode(datum,startPosition,endPosition);this.size_++;this.root_=this.insertNode_(this.root_,node);this.root_.colour=Colour.BLACK;return datum;},insertNode_(root,node){if(root===undefined)return node;if(root.leftNode&&root.leftNode.isRed&&root.rightNode&&root.rightNode.isRed){this.flipNodeColour_(root);}
 if(node.key<root.key){root.leftNode=this.insertNode_(root.leftNode,node);}else if(node.key===root.key){root.merge(node);}else{root.rightNode=this.insertNode_(root.rightNode,node);}
 if(root.rightNode&&root.rightNode.isRed&&(root.leftNode===undefined||!root.leftNode.isRed)){root=this.rotateLeft_(root);}
 if(root.leftNode&&root.leftNode.isRed&&root.leftNode.leftNode&&root.leftNode.leftNode.isRed){root=this.rotateRight_(root);}
-return root;},rotateRight_:function(node){var sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_:function(node){var sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_:function(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_:function(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues:function(){this.updateHighValues_(this.root_);},updateHighValues_:function(node){if(node===undefined)return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_:function(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined){throw new Error('queryLow and queryHigh must be defined');}
-if((typeof queryLow!=='number')||(typeof queryHigh!=='number')){throw new Error('queryLow and queryHigh must be numbers');}},findIntersection:function(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)return[];var ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_:function(){if(this.root_===undefined)return[];return this.root_.dump();}};var Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum:datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
-IntervalTreeNode.prototype={appendIntersectionsInto_:function(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
+return root;},rotateRight_(node){const sibling=node.leftNode;node.leftNode=sibling.rightNode;sibling.rightNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},rotateLeft_(node){const sibling=node.rightNode;node.rightNode=sibling.leftNode;sibling.leftNode=node;sibling.colour=node.colour;node.colour=Colour.RED;return sibling;},flipNodeColour_(node){node.colour=this.flipColour_(node.colour);node.leftNode.colour=this.flipColour_(node.leftNode.colour);node.rightNode.colour=this.flipColour_(node.rightNode.colour);},flipColour_(colour){return colour===Colour.RED?Colour.BLACK:Colour.RED;},updateHighValues(){this.updateHighValues_(this.root_);},updateHighValues_(node){if(node===undefined)return undefined;node.maxHighLeft=this.updateHighValues_(node.leftNode);node.maxHighRight=this.updateHighValues_(node.rightNode);return max(max(node.maxHighLeft,node.highValue),node.maxHighRight);},validateFindArguments_(queryLow,queryHigh){if(queryLow===undefined||queryHigh===undefined){throw new Error('queryLow and queryHigh must be defined');}
+if((typeof queryLow!=='number')||(typeof queryHigh!=='number')){throw new Error('queryLow and queryHigh must be numbers');}},findIntersection(queryLow,queryHigh){this.validateFindArguments_(queryLow,queryHigh);if(this.root_===undefined)return[];const ret=[];this.root_.appendIntersectionsInto_(ret,queryLow,queryHigh);return ret;},get size(){return this.size_;},get root(){return this.root_;},dump_(){if(this.root_===undefined)return[];return this.root_.dump();}};const Colour={RED:'red',BLACK:'black'};function IntervalTreeNode(datum,lowValue,highValue){this.lowValue_=lowValue;this.data_=[{datum,high:highValue,low:lowValue}];this.colour_=Colour.RED;this.parentNode_=undefined;this.leftNode_=undefined;this.rightNode_=undefined;this.maxHighLeft_=undefined;this.maxHighRight_=undefined;}
+IntervalTreeNode.prototype={appendIntersectionsInto_(ret,queryLow,queryHigh){if(this.lowValue_>=queryHigh){if(!this.leftNode_)return;return this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
 if(this.maxHighLeft_>queryLow){this.leftNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}
-if(this.highValue>queryLow){for(var i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)break;ret.push(this.data[i].datum);}}
-if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge:function(node){for(var i=0;i<node.data.length;i++){this.data_.push(node.data[i]);}
-this.data_.sort(function(a,b){return a.high-b.high;});},dump:function(){var ret={};if(this.leftNode_){ret['left']=this.leftNode_.dump();}
-ret['data']=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_){ret['right']=this.rightNode_.dump();}
-return ret;}};return{IntervalTree,};});'use strict';tr.exportTo('tr.b.math',function(){var tmpVec2s=[];for(var i=0;i<8;i++){tmpVec2s[i]=vec2.create();}
-var tmpVec2a=vec4.create();var tmpVec4a=vec4.create();var tmpVec4b=vec4.create();var tmpMat4=mat4.create();var tmpMat4b=mat4.create();var p00=vec2.createXY(0,0);var p10=vec2.createXY(1,0);var p01=vec2.createXY(0,1);var p11=vec2.createXY(1,1);var lerpingVecA=vec2.create();var lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
+if(this.highValue>queryLow){for(let i=(this.data.length-1);i>=0;--i){if(this.data[i].high<queryLow)break;ret.push(this.data[i].datum);}}
+if(this.rightNode_){this.rightNode_.appendIntersectionsInto_(ret,queryLow,queryHigh);}},get colour(){return this.colour_;},set colour(colour){this.colour_=colour;},get key(){return this.lowValue_;},get lowValue(){return this.lowValue_;},get highValue(){return this.data_[this.data_.length-1].high;},set leftNode(left){this.leftNode_=left;},get leftNode(){return this.leftNode_;},get hasLeftNode(){return this.leftNode_!==undefined;},set rightNode(right){this.rightNode_=right;},get rightNode(){return this.rightNode_;},get hasRightNode(){return this.rightNode_!==undefined;},set parentNode(parent){this.parentNode_=parent;},get parentNode(){return this.parentNode_;},get isRootNode(){return this.parentNode_===undefined;},set maxHighLeft(high){this.maxHighLeft_=high;},get maxHighLeft(){return this.maxHighLeft_;},set maxHighRight(high){this.maxHighRight_=high;},get maxHighRight(){return this.maxHighRight_;},get data(){return this.data_;},get isRed(){return this.colour_===Colour.RED;},merge(node){for(let i=0;i<node.data.length;i++){this.data_.push(node.data[i]);}
+this.data_.sort(function(a,b){return a.high-b.high;});},dump(){const ret={};if(this.leftNode_){ret.left=this.leftNode_.dump();}
+ret.data=this.data_.map(function(d){return[d.low,d.high];});if(this.rightNode_){ret.right=this.rightNode_.dump();}
+return ret;}};return{IntervalTree,};});'use strict';tr.exportTo('tr.b.math',function(){const tmpVec2s=[];for(let i=0;i<8;i++){tmpVec2s[i]=vec2.create();}
+const tmpVec2a=vec4.create();const tmpVec4a=vec4.create();const tmpVec4b=vec4.create();const tmpMat4=mat4.create();const tmpMat4b=mat4.create();const p00=vec2.createXY(0,0);const p10=vec2.createXY(1,0);const p01=vec2.createXY(0,1);const p11=vec2.createXY(1,1);const lerpingVecA=vec2.create();const lerpingVecB=vec2.create();function lerpVec2(out,a,b,amt){vec2.scale(lerpingVecA,a,amt);vec2.scale(lerpingVecB,b,1-amt);vec2.add(out,lerpingVecA,lerpingVecB);vec2.normalize(out,out);return out;}
 function Quad(){this.p1=vec2.create();this.p2=vec2.create();this.p3=vec2.create();this.p4=vec2.create();}
-Quad.fromXYWH=function(x,y,w,h){var q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;};Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);};Quad.from4Vecs=function(p1,p2,p3,p4){var q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;};Quad.from8Array=function(arr){if(arr.length!==8){throw new Error('Array must be 8 long');}
-var q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside:function(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect:function(){var x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);var x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);var y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.math.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone:function(){var q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale:function(s){var q=new Quad();this.scaleFast(q,s);return q;},scaleFast:function(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle:function(){var bounds=this.boundingRect();return(bounds.x===this.p1[0]&&bounds.y===this.p1[1]&&bounds.width===this.p2[0]-this.p1[0]&&bounds.y===this.p2[1]&&bounds.width===this.p3[0]-this.p1[0]&&bounds.height===this.p3[1]-this.p2[1]&&bounds.x===this.p4[0]&&bounds.height===this.p4[1]-this.p2[1]);},projectUnitRect:function(rect){var q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast:function(dstQuad,rect){var v12=tmpVec2s[0];var v14=tmpVec2s[1];var v23=tmpVec2s[2];var v43=tmpVec2s[3];var l12;var l14;var l23;var l43;vec2.sub(v12,this.p2,this.p1);l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);var b12=tmpVec2s[0];var b14=tmpVec2s[1];var b23=tmpVec2s[2];var b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString:function(){return'Quad('+
+Quad.fromXYWH=function(x,y,w,h){const q=new Quad();vec2.set(q.p1,x,y);vec2.set(q.p2,x+w,y);vec2.set(q.p3,x+w,y+h);vec2.set(q.p4,x,y+h);return q;};Quad.fromRect=function(r){return new Quad.fromXYWH(r.x,r.y,r.width,r.height);};Quad.from4Vecs=function(p1,p2,p3,p4){const q=new Quad();vec2.set(q.p1,p1[0],p1[1]);vec2.set(q.p2,p2[0],p2[1]);vec2.set(q.p3,p3[0],p3[1]);vec2.set(q.p4,p4[0],p4[1]);return q;};Quad.from8Array=function(arr){if(arr.length!==8){throw new Error('Array must be 8 long');}
+const q=new Quad();q.p1[0]=arr[0];q.p1[1]=arr[1];q.p2[0]=arr[2];q.p2[1]=arr[3];q.p3[0]=arr[4];q.p3[1]=arr[5];q.p4[0]=arr[6];q.p4[1]=arr[7];return q;};Quad.prototype={pointInside(point){return pointInImplicitQuad(point,this.p1,this.p2,this.p3,this.p4);},boundingRect(){const x0=Math.min(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);const y0=Math.min(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);const x1=Math.max(this.p1[0],this.p2[0],this.p3[0],this.p4[0]);const y1=Math.max(this.p1[1],this.p2[1],this.p3[1],this.p4[1]);return new tr.b.math.Rect.fromXYWH(x0,y0,x1-x0,y1-y0);},clone(){const q=new Quad();vec2.copy(q.p1,this.p1);vec2.copy(q.p2,this.p2);vec2.copy(q.p3,this.p3);vec2.copy(q.p4,this.p4);return q;},scale(s){const q=new Quad();this.scaleFast(q,s);return q;},scaleFast(dstQuad,s){vec2.copy(dstQuad.p1,this.p1,s);vec2.copy(dstQuad.p2,this.p2,s);vec2.copy(dstQuad.p3,this.p3,s);vec2.copy(dstQuad.p3,this.p3,s);},isRectangle(){const bounds=this.boundingRect();return(bounds.x===this.p1[0]&&bounds.y===this.p1[1]&&bounds.width===this.p2[0]-this.p1[0]&&bounds.y===this.p2[1]&&bounds.width===this.p3[0]-this.p1[0]&&bounds.height===this.p3[1]-this.p2[1]&&bounds.x===this.p4[0]&&bounds.height===this.p4[1]-this.p2[1]);},projectUnitRect(rect){const q=new Quad();this.projectUnitRectFast(q,rect);return q;},projectUnitRectFast(dstQuad,rect){const v12=tmpVec2s[0];const v14=tmpVec2s[1];const v23=tmpVec2s[2];const v43=tmpVec2s[3];vec2.sub(v12,this.p2,this.p1);const l12=vec2.length(v12);vec2.scale(v12,v12,1/l12);vec2.sub(v14,this.p4,this.p1);const l14=vec2.length(v14);vec2.scale(v14,v14,1/l14);vec2.sub(v23,this.p3,this.p2);const l23=vec2.length(v23);vec2.scale(v23,v23,1/l23);vec2.sub(v43,this.p3,this.p4);const l43=vec2.length(v43);vec2.scale(v43,v43,1/l43);const b12=tmpVec2s[0];const b14=tmpVec2s[1];const b23=tmpVec2s[2];const b43=tmpVec2s[3];lerpVec2(b12,v12,v43,rect.y);lerpVec2(b43,v12,v43,1-rect.bottom);lerpVec2(b14,v14,v23,rect.x);lerpVec2(b23,v14,v23,1-rect.right);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*rect.x,b14,l14*rect.y);vec2.add(dstQuad.p1,this.p1,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b12,l12*-(1.0-rect.right),b23,l23*rect.y);vec2.add(dstQuad.p2,this.p2,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*-(1.0-rect.right),b23,l23*-(1.0-rect.bottom));vec2.add(dstQuad.p3,this.p3,tmpVec2a);vec2.addTwoScaledUnitVectors(tmpVec2a,b43,l43*rect.left,b14,l14*-(1.0-rect.bottom));vec2.add(dstQuad.p4,this.p4,tmpVec2a);},toString(){return'Quad('+
 vec2.toString(this.p1)+', '+
 vec2.toString(this.p2)+', '+
 vec2.toString(this.p3)+', '+
 vec2.toString(this.p4)+')';}};function sign(p1,p2,p3){return(p1[0]-p3[0])*(p2[1]-p3[1])-
 (p2[0]-p3[0])*(p1[1]-p3[1]);}
-function pointInTriangle2(pt,p1,p2,p3){var b1=sign(pt,p1,p2)<0.0;var b2=sign(pt,p2,p3)<0.0;var b3=sign(pt,p3,p1)<0.0;return((b1===b2)&&(b2===b3));}
+function pointInTriangle2(pt,p1,p2,p3){const b1=sign(pt,p1,p2)<0.0;const b2=sign(pt,p2,p3)<0.0;const b3=sign(pt,p3,p1)<0.0;return((b1===b2)&&(b2===b3));}
 function pointInImplicitQuad(point,p1,p2,p3,p4){return pointInTriangle2(point,p1,p2,p3)||pointInTriangle2(point,p1,p3,p4);}
 return{pointInTriangle2,pointInImplicitQuad,Quad,};});'use strict';tr.exportTo('tr.b',function(){function addSingletonGetter(ctor){ctor.getInstance=function(){return ctor.instance_||(ctor.instance_=new ctor());};}
 function deepCopy(value){if(!(value instanceof Object)){if(value===undefined||value===null)return value;if(typeof value==='string')return value.substring();if(typeof value==='boolean')return value;if(typeof value==='number')return value;throw new Error('Unrecognized: '+typeof value);}
-var object=value;if(object instanceof Array){var res=new Array(object.length);for(var i=0;i<object.length;i++){res[i]=deepCopy(object[i]);}
+const object=value;if(object instanceof Array){const res=new Array(object.length);for(let i=0;i<object.length;i++){res[i]=deepCopy(object[i]);}
 return res;}
 if(object.__proto__!==Object.prototype){throw new Error('Can only clone simple types');}
-var res={};for(var key in object){res[key]=deepCopy(object[key]);}
+const res={};for(const key in object){res[key]=deepCopy(object[key]);}
 return res;}
 function normalizeException(e){if(e===undefined||e===null){return{typeName:'UndefinedError',message:'Unknown: null or undefined exception',stack:'Unknown'};}
 if(typeof(e)==='string'){return{typeName:'StringError',message:e,stack:[e]};}
-var typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
-var msg=e.message?e.message:'Unknown';return{typeName:typeName,message:msg,stack:e.stack?e.stack:[msg]};}
+let typeName;if(e.name){typeName=e.name;}else if(e.constructor){if(e.constructor.name){typeName=e.constructor.name;}else{typeName='AnonymousError';}}else{typeName='ErrorWithNoConstructor';}
+const msg=e.message?e.message:'Unknown';return{typeName,message:msg,stack:e.stack?e.stack:[msg]};}
 function stackTraceAsString(){return new Error().stack+'';}
-function stackTrace(){var stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
-function getUsingPath(path,fromDict){var parts=path.split('.');var cur=fromDict;for(var part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
+function stackTrace(){let stack=stackTraceAsString();stack=stack.split('\n');return stack.slice(2);}
+function getUsingPath(path,fromDict){const parts=path.split('.');let cur=fromDict;for(let part;parts.length&&(part=parts.shift());){if(!parts.length){return cur[part];}else if(part in cur){cur=cur[part];}else{return undefined;}}
 return undefined;}
 function formatDate(date){return date.toISOString().replace('T',' ').slice(0,19);}
 function numberToJson(n){if(isNaN(n))return'NaN';if(n===Infinity)return'Infinity';if(n===-Infinity)return'-Infinity';return n;}
 function numberFromJson(n){if(n==='NaN'||n===null)return NaN;if(n==='Infinity')return Infinity;if(n==='-Infinity')return-Infinity;return n;}
-function runLengthEncoding(ary){let encodedArray=[];for(let element of ary){if(encodedArray.length===0||encodedArray[encodedArray.length-1].value!==element){encodedArray.push({value:element,count:1,});}else{encodedArray[encodedArray.length-1].count+=1;}}
+function runLengthEncoding(ary){const encodedArray=[];for(const element of ary){if(encodedArray.length===0||encodedArray[encodedArray.length-1].value!==element){encodedArray.push({value:element,count:1,});}else{encodedArray[encodedArray.length-1].count+=1;}}
 return encodedArray;}
-return{addSingletonGetter,deepCopy,normalizeException,stackTrace,stackTraceAsString,formatDate,numberToJson,numberFromJson,getUsingPath,runLengthEncoding,};});'use strict';tr.exportTo('tr.b',function(){var ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;var REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;var recordRAFStacks=false;var pendingPreAFs=[];var pendingRAFs=[];var pendingIdleCallbacks=[];var currentRAFDispatchList=undefined;var rafScheduled=false;var idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{var delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
+return{addSingletonGetter,deepCopy,normalizeException,stackTrace,stackTraceAsString,formatDate,numberToJson,numberFromJson,getUsingPath,runLengthEncoding,};});'use strict';tr.exportTo('tr.b',function(){const ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS=10;const REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS=100;const recordRAFStacks=false;let pendingPreAFs=[];let pendingRAFs=[];const pendingIdleCallbacks=[];let currentRAFDispatchList=undefined;let rafScheduled=false;let idleWorkScheduled=false;function scheduleRAF(){if(rafScheduled)return;rafScheduled=true;if(tr.isHeadless){Promise.resolve().then(function(){processRequests(false,0);},function(e){throw e;});}else{if(window.requestAnimationFrame){window.requestAnimationFrame(processRequests.bind(this,false));}else{const delta=Date.now()-window.performance.now();window.webkitRequestAnimationFrame(function(domTimeStamp){processRequests(false,domTimeStamp-delta);});}}}
 function nativeRequestIdleCallbackSupported(){return!tr.isHeadless&&window.requestIdleCallback;}
 function scheduleIdleWork(){if(idleWorkScheduled)return;if(!nativeRequestIdleCallbackSupported()){scheduleRAF();return;}
 idleWorkScheduled=true;window.requestIdleCallback(function(deadline,didTimeout){processIdleWork(false,deadline);},{timeout:REQUEST_IDLE_CALLBACK_TIMEOUT_MILLISECONDS});}
 function onAnimationFrameError(e,opt_stack){console.log(e.stack);if(tr.isHeadless)throw e;if(opt_stack)console.log(opt_stack);if(e.message){console.error(e.message,e.stack);}else{console.error(e);}}
 function runTask(task,frameBeginTime){try{task.callback.call(task.context,frameBeginTime);}catch(e){tr.b.onAnimationFrameError(e,task.stack);}}
-function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;var currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];var hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(var i=0;i<currentPreAFs.length;i++){runTask(currentPreAFs[i],frameBeginTime);}
+function processRequests(forceAllTasksToRun,frameBeginTime){rafScheduled=false;const currentPreAFs=pendingPreAFs;currentRAFDispatchList=pendingRAFs;pendingPreAFs=[];pendingRAFs=[];const hasRAFTasks=currentPreAFs.length||currentRAFDispatchList.length;for(let i=0;i<currentPreAFs.length;i++){runTask(currentPreAFs[i],frameBeginTime);}
 while(currentRAFDispatchList.length>0){runTask(currentRAFDispatchList.shift(),frameBeginTime);}
-currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){var rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining:function(){return rafCompletionDeadline-window.performance.now();}});}
+currentRAFDispatchList=undefined;if((!hasRAFTasks&&!nativeRequestIdleCallbackSupported())||forceAllTasksToRun){const rafCompletionDeadline=frameBeginTime+ESTIMATED_IDLE_PERIOD_LENGTH_MILLISECONDS;processIdleWork(forceAllTasksToRun,{timeRemaining(){return rafCompletionDeadline-window.performance.now();}});}
 if(pendingIdleCallbacks.length>0)scheduleIdleWork();}
 function processIdleWork(forceAllTasksToRun,deadline){idleWorkScheduled=false;while(pendingIdleCallbacks.length>0){runTask(pendingIdleCallbacks.shift());if(!forceAllTasksToRun&&(tr.isHeadless||deadline.timeRemaining()<=0)){break;}}
 if(pendingIdleCallbacks.length>0)scheduleIdleWork();}
-function getStack_(){if(!recordRAFStacks)return'';var stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
-function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+function getStack_(){if(!recordRAFStacks)return'';const stackLines=tr.b.stackTrace();stackLines.shift();return stackLines.join('\n');}
+function requestPreAnimationFrame(callback,opt_this){pendingPreAFs.push({callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
 function requestAnimationFrameInThisFrameIfPossible(callback,opt_this){if(!currentRAFDispatchList){requestAnimationFrame(callback,opt_this);return;}
-currentRAFDispatchList.push({callback:callback,context:opt_this||global,stack:getStack_()});return;}
-function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
+currentRAFDispatchList.push({callback,context:opt_this||global,stack:getStack_()});return;}
+function requestAnimationFrame(callback,opt_this){pendingRAFs.push({callback,context:opt_this||global,stack:getStack_()});scheduleRAF();}
 function animationFrame(){return new Promise(resolve=>requestAnimationFrame(resolve));}
-function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback:callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
+function requestIdleCallback(callback,opt_this){pendingIdleCallbacks.push({callback,context:opt_this||global,stack:getStack_()});scheduleIdleWork();}
 function forcePendingRAFTasksToRun(frameBeginTime){if(!rafScheduled)return;processRequests(false,frameBeginTime);}
 function forceAllPendingTasksToRunForTest(){if(!rafScheduled&&!idleWorkScheduled)return;processRequests(true,0);}
 function timeout(ms){return new Promise(resolve=>window.setTimeout(resolve,ms));}
 function idle(){return new Promise(resolve=>requestIdleCallback(resolve));}
-return{animationFrame,forceAllPendingTasksToRunForTest,forcePendingRAFTasksToRun,idle,onAnimationFrameError,requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible,requestIdleCallback,requestPreAnimationFrame,timeout,};});'use strict';tr.exportTo('tr.b',function(){var Base64=tr.b.Base64;function computeUserTimingMarkName(groupName,functionName,opt_args){if(groupName===undefined){throw new Error('getMeasureString should have group name');}
-if(functionName===undefined){throw new Error('getMeasureString should have function name');}
-var userTimingMarkName=groupName+':'+functionName;if(opt_args!==undefined){userTimingMarkName+='/';userTimingMarkName+=Base64.btoa(JSON.stringify(opt_args));}
-return userTimingMarkName;}
-function Timing(){}
-Timing.nextMarkNumber=0;Timing.mark=function(groupName,functionName,opt_args){if(tr.isHeadless){return{end:function(){}};}
-var userTimingMarkName=computeUserTimingMarkName(groupName,functionName,opt_args);var markBeginName='tvcm.mark'+Timing.nextMarkNumber++;var markEndName='tvcm.mark'+Timing.nextMarkNumber++;window.performance.mark(markBeginName);return{end:function(){window.performance.mark(markEndName);window.performance.measure(userTimingMarkName,markBeginName,markEndName);}};};Timing.wrap=function(groupName,callback,opt_args){if(groupName===undefined){throw new Error('Timing.wrap should have group name');}
-if(callback.name===''){throw new Error('Anonymous function is not allowed');}
-return Timing.wrapNamedFunction(groupName,callback.name,callback,opt_args);};Timing.wrapNamedFunction=function(groupName,functionName,callback,opt_args){function timedNamedFunction(){var markedTime=Timing.mark(groupName,functionName,opt_args);try{callback.apply(this,arguments);}finally{markedTime.end();}}
-return timedNamedFunction;};function TimedNamedPromise(groupName,name,executor,opt_args){var markedTime=Timing.mark(groupName,name,opt_args);var promise=new Promise(executor);promise.then(function(result){markedTime.end();return result;},function(e){markedTime.end();throw e;});return promise;}
-return{_computeUserTimingMarkName:computeUserTimingMarkName,TimedNamedPromise,Timing,};});'use strict';tr.exportTo('tr.b',function(){var Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined&&runCb.prototype!==undefined){throw new Error('Almost certainly you meant to pass a bound callback '+'or thisArg.');}
+return{animationFrame,forceAllPendingTasksToRunForTest,forcePendingRAFTasksToRun,idle,onAnimationFrameError,requestAnimationFrame,requestAnimationFrameInThisFrameIfPossible,requestIdleCallback,requestPreAnimationFrame,timeout,};});'use strict';tr.exportTo('tr.b',function(){class Mark{constructor(groupName,functionName){if(tr.isHeadless)return;this.groupName_=groupName;this.functionName_=functionName;const guid=tr.b.GUID.allocateSimple();this.measureName_=`${groupName} ${functionName}`;this.startMarkName_=`${this.measureName} ${guid} start`;this.endMarkName_=`${this.measureName} ${guid} end`;window.performance.mark(this.startMarkName_);}
+get groupName(){return this.groupName_;}
+get functionName(){return this.functionName_;}
+get measureName(){return this.measureName_;}
+get startMark(){return tr.b.getOnlyElement(window.performance.getEntriesByName(this.startMarkName_));}
+get endMark(){return tr.b.getOnlyElement(window.performance.getEntriesByName(this.endMarkName_));}
+get durationMs(){return this.endMark.startTime-this.startMark.startTime;}
+end(){if(tr.isHeadless)return;window.performance.mark(this.endMarkName_);window.performance.measure(this.measureName_,this.startMarkName_,this.endMarkName_);if(!(window.ga instanceof Function))return;ga('send',{hitType:'event',eventCategory:this.groupName,eventAction:this.functionName,eventValue:this.durationMs,});}}
+class Timing{static mark(groupName,functionName){return new Mark(groupName,functionName);}
+static instant(groupName,functionName,opt_value){const valueString=opt_value===undefined?'':' '+opt_value;console.timeStamp(`${groupName} ${functionName}${valueString}`);if(!(window.ga instanceof Function))return;ga('send',{hitType:'event',eventCategory:groupName,eventAction:functionName,eventValue:opt_value,});}}
+return{Timing,};});'use strict';tr.exportTo('tr.b',function(){const Timing=tr.b.Timing;function Task(runCb,thisArg){if(runCb!==undefined&&thisArg===undefined&&runCb.prototype!==undefined){throw new Error('Almost certainly you meant to pass a bound callback '+'or thisArg.');}
 this.runCb_=runCb;this.thisArg_=thisArg;this.afterTask_=undefined;this.subTasks_=[];this.updatesUi_=false;}
-Task.prototype={get name(){return this.runCb_.name;},set updatesUi(value){this.updatesUi_=value;},subTask:function(cb,thisArg){if(cb instanceof Task){this.subTasks_.push(cb);}else{this.subTasks_.push(new Task(cb,thisArg));}
-return this.subTasks_[this.subTasks_.length-1];},run:function(){if(this.runCb_!==undefined)this.runCb_.call(this.thisArg_,this);var subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)return this.afterTask_;for(var i=1;i<subTasks.length;i++){subTasks[i-1].afterTask_=subTasks[i];}
-subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after:function(cb,thisArg){if(this.afterTask_){throw new Error('Has an after task already');}
+Task.prototype={get name(){return this.runCb_.name;},set updatesUi(value){this.updatesUi_=value;},subTask(cb,thisArg){if(cb instanceof Task){this.subTasks_.push(cb);}else{this.subTasks_.push(new Task(cb,thisArg));}
+return this.subTasks_[this.subTasks_.length-1];},run(){if(this.runCb_!==undefined)this.runCb_.call(this.thisArg_,this);const subTasks=this.subTasks_;this.subTasks_=undefined;if(!subTasks.length)return this.afterTask_;for(let i=1;i<subTasks.length;i++){subTasks[i-1].afterTask_=subTasks[i];}
+subTasks[subTasks.length-1].afterTask_=this.afterTask_;return subTasks[0];},after(cb,thisArg){if(this.afterTask_){throw new Error('Has an after task already');}
 if(cb instanceof Task){this.afterTask_=cb;}else{this.afterTask_=new Task(cb,thisArg);}
-return this.afterTask_;},timedAfter:function(groupName,cb,thisArg,opt_args){if(cb.name===''){throw new Error('Anonymous Task is not allowed');}
-return this.namedTimedAfter(groupName,cb.name,cb,thisArg,opt_args);},namedTimedAfter:function(groupName,name,cb,thisArg,opt_args){if(this.afterTask_){throw new Error('Has an after task already');}
-var realTask;if(cb instanceof Task){realTask=cb;}else{realTask=new Task(cb,thisArg);}
-this.afterTask_=new Task(function(task){var markedTask=Timing.mark(groupName,name,opt_args);task.subTask(realTask,thisArg);task.subTask(function(){markedTask.end();},thisArg);},thisArg);return this.afterTask_;},enqueue:function(cb,thisArg){if(!this.afterTask_)return this.after(cb,thisArg);return this.afterTask_.enqueue(cb,thisArg);}};Task.RunSynchronously=function(task){var curTask=task;while(curTask){curTask=curTask.run();}};Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){var curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);return;}
+return this.afterTask_;},enqueue(cb,thisArg){if(!this.afterTask_)return this.after(cb,thisArg);return this.afterTask_.enqueue(cb,thisArg);}};Task.RunSynchronously=function(task){let curTask=task;while(curTask){curTask=curTask.run();}};Task.RunWhenIdle=function(task){return new Promise(function(resolve,reject){let curTask=task;function runAnother(){try{curTask=curTask.run();}catch(e){reject(e);return;}
 if(curTask){if(curTask.updatesUi_){tr.b.requestAnimationFrameInThisFrameIfPossible(runAnother);}else{tr.b.requestIdleCallback(runAnother);}
 return;}
 resolve();}
 tr.b.requestIdleCallback(runAnother);});};return{Task,};});'use strict';tr.exportTo('tr.c',function(){function makeCaseInsensitiveRegex(pattern){pattern=pattern.replace(/[.*+?^${}()|[\]\\]/g,'\\$&');return new RegExp(pattern,'i');}
 function Filter(){}
-Filter.prototype={__proto__:Object.prototype,matchCounter:function(counter){return true;},matchCpu:function(cpu){return true;},matchProcess:function(process){return true;},matchSlice:function(slice){return true;},matchThread:function(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length){throw new Error('Filter text is empty.');}}
-TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){if(slice.title===undefined&&slice.category===undefined){return false;}
+Filter.prototype={__proto__:Object.prototype,matchCounter(counter){return true;},matchCpu(cpu){return true;},matchProcess(process){return true;},matchSlice(slice){return true;},matchThread(thread){return true;}};function TitleOrCategoryFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);if(!text.length){throw new Error('Filter text is empty.');}}
+TitleOrCategoryFilter.prototype={__proto__:Filter.prototype,matchSlice(slice){if(slice.title===undefined&&slice.category===undefined){return false;}
 return this.regex_.test(slice.title)||(!!slice.category&&this.regex_.test(slice.category));}};function ExactTitleFilter(text){Filter.call(this);this.text_=text;if(!text.length){throw new Error('Filter text is empty.');}}
-ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice:function(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
-FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_:function(obj){for(var key in obj){if(!obj.hasOwnProperty(key))continue;if(this.regex_.test(key))return true;if(this.regex_.test(obj[key]))return true;}
-return false;},matchSlice:function(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))return true;return this.matchObject_(slice.args);}};return{Filter,TitleOrCategoryFilter,ExactTitleFilter,FullTextFilter,};});'use strict';tr.exportTo('tr.model',function(){var ClockDomainId={BATTOR:'BATTOR',UNKNOWN_CHROME_LEGACY:'UNKNOWN_CHROME_LEGACY',LINUX_CLOCK_MONOTONIC:'LINUX_CLOCK_MONOTONIC',LINUX_FTRACE_GLOBAL:'LINUX_FTRACE_GLOBAL',MAC_MACH_ABSOLUTE_TIME:'MAC_MACH_ABSOLUTE_TIME',WIN_ROLLOVER_PROTECTED_TIME_GET_TIME:'WIN_ROLLOVER_PROTECTED_TIME_GET_TIME',WIN_QPC:'WIN_QPC',TELEMETRY:'TELEMETRY'};var POSSIBLE_CHROME_CLOCK_DOMAINS=new Set([ClockDomainId.UNKNOWN_CHROME_LEGACY,ClockDomainId.LINUX_CLOCK_MONOTONIC,ClockDomainId.MAC_MACH_ABSOLUTE_TIME,ClockDomainId.WIN_ROLLOVER_PROTECTED_TIME_GET_TIME,ClockDomainId.WIN_QPC]);var BATTOR_FAST_SYNC_THRESHOLD_MS=3;function ClockSyncManager(){this.domainsSeen_=new Set();this.markersBySyncId_=new Map();this.transformerMapByDomainId_={};}
-ClockSyncManager.prototype={addClockSyncMarker:function(domainId,syncId,startTs,opt_endTs){this.onDomainSeen_(domainId);if(tr.b.dictionaryValues(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
+ExactTitleFilter.prototype={__proto__:Filter.prototype,matchSlice(slice){return slice.title===this.text_;}};function FullTextFilter(text){Filter.call(this);this.regex_=makeCaseInsensitiveRegex(text);this.titleOrCategoryFilter_=new TitleOrCategoryFilter(text);}
+FullTextFilter.prototype={__proto__:Filter.prototype,matchObject_(obj){for(const key in obj){if(!obj.hasOwnProperty(key))continue;if(this.regex_.test(key))return true;if(this.regex_.test(obj[key]))return true;}
+return false;},matchSlice(slice){if(this.titleOrCategoryFilter_.matchSlice(slice))return true;return this.matchObject_(slice.args);}};return{Filter,TitleOrCategoryFilter,ExactTitleFilter,FullTextFilter,};});'use strict';tr.exportTo('tr.model',function(){const ClockDomainId={BATTOR:'BATTOR',UNKNOWN_CHROME_LEGACY:'UNKNOWN_CHROME_LEGACY',LINUX_CLOCK_MONOTONIC:'LINUX_CLOCK_MONOTONIC',LINUX_FTRACE_GLOBAL:'LINUX_FTRACE_GLOBAL',MAC_MACH_ABSOLUTE_TIME:'MAC_MACH_ABSOLUTE_TIME',WIN_ROLLOVER_PROTECTED_TIME_GET_TIME:'WIN_ROLLOVER_PROTECTED_TIME_GET_TIME',WIN_QPC:'WIN_QPC',SYSTRACE:'SYSTRACE',TELEMETRY:'TELEMETRY'};const POSSIBLE_CHROME_CLOCK_DOMAINS=new Set([ClockDomainId.UNKNOWN_CHROME_LEGACY,ClockDomainId.LINUX_CLOCK_MONOTONIC,ClockDomainId.MAC_MACH_ABSOLUTE_TIME,ClockDomainId.WIN_ROLLOVER_PROTECTED_TIME_GET_TIME,ClockDomainId.WIN_QPC]);const BATTOR_FAST_SYNC_THRESHOLD_MS=3;function ClockSyncManager(){this.domainsSeen_=new Set();this.markersBySyncId_=new Map();this.transformerMapByDomainId_={};}
+ClockSyncManager.prototype={addClockSyncMarker(domainId,syncId,startTs,opt_endTs){this.onDomainSeen_(domainId);if(Object.values(ClockDomainId).indexOf(domainId)<0){throw new Error('"'+domainId+'" is not in the list of known '+'clock domain IDs.');}
 if(this.modelDomainId_){throw new Error('Cannot add new clock sync markers after getting '+'a model time transformer.');}
-var marker=new ClockSyncMarker(domainId,startTs,opt_endTs);if(!this.markersBySyncId_.has(syncId)){this.markersBySyncId_.set(syncId,[marker]);return;}
-var markers=this.markersBySyncId_.get(syncId);if(markers.length===2){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
+const marker=new ClockSyncMarker(domainId,startTs,opt_endTs);if(!this.markersBySyncId_.has(syncId)){this.markersBySyncId_.set(syncId,[marker]);return;}
+const markers=this.markersBySyncId_.get(syncId);if(markers.length===2){throw new Error('Clock sync with ID "'+syncId+'" is already '+'complete - cannot add a third clock sync marker to it.');}
 if(markers[0].domainId===domainId){throw new Error('A clock domain cannot sync with itself.');}
-markers.push(marker);this.onSyncCompleted_(markers[0],marker);},get markersBySyncId(){return this.markersBySyncId_;},get domainsSeen(){return this.domainsSeen_;},getModelTimeTransformer:function(domainId){this.onDomainSeen_(domainId);if(!this.modelDomainId_){this.selectModelDomainId_();}
-return this.getTimeTransformerRaw_(domainId,this.modelDomainId_).fn;},getTimeTransformerError:function(fromDomainId,toDomainId){this.onDomainSeen_(fromDomainId);this.onDomainSeen_(toDomainId);return this.getTimeTransformerRaw_(fromDomainId,toDomainId).error;},getTimeTransformerRaw_:function(fromDomainId,toDomainId){var transformer=this.getTransformerBetween_(fromDomainId,toDomainId);if(!transformer){throw new Error('No clock sync markers exist pairing clock domain "'+
+markers.push(marker);this.onSyncCompleted_(markers[0],marker);},get markersBySyncId(){return this.markersBySyncId_;},get domainsSeen(){return this.domainsSeen_;},getModelTimeTransformer(domainId){this.onDomainSeen_(domainId);if(!this.modelDomainId_){this.selectModelDomainId_();}
+return this.getTimeTransformerRaw_(domainId,this.modelDomainId_).fn;},getTimeTransformerError(fromDomainId,toDomainId){this.onDomainSeen_(fromDomainId);this.onDomainSeen_(toDomainId);return this.getTimeTransformerRaw_(fromDomainId,toDomainId).error;},getTimeTransformerRaw_(fromDomainId,toDomainId){const transformer=this.getTransformerBetween_(fromDomainId,toDomainId);if(!transformer){throw new Error('No clock sync markers exist pairing clock domain "'+
 fromDomainId+'" '+'with target clock domain "'+
 toDomainId+'".');}
-return transformer;},getTransformerBetween_:function(fromDomainId,toDomainId){var visitedDomainIds=new Set();var queue=[{domainId:fromDomainId,transformer:Transformer.IDENTITY}];while(queue.length>0){queue.sort((domain1,domain2)=>domain1.transformer.error-domain2.transformer.error);var current=queue.shift();if(current.domainId===toDomainId){return current.transformer;}
+return transformer;},getTransformerBetween_(fromDomainId,toDomainId){const visitedDomainIds=new Set();const queue=[{domainId:fromDomainId,transformer:Transformer.IDENTITY}];while(queue.length>0){queue.sort((domain1,domain2)=>domain1.transformer.error-domain2.transformer.error);const current=queue.shift();if(current.domainId===toDomainId){return current.transformer;}
 if(visitedDomainIds.has(current.domainId)){continue;}
-visitedDomainIds.add(current.domainId);var outgoingTransformers=this.transformerMapByDomainId_[current.domainId];if(!outgoingTransformers)continue;for(var outgoingDomainId in outgoingTransformers){var toNextDomainTransformer=outgoingTransformers[outgoingDomainId];var toCurrentDomainTransformer=current.transformer;queue.push({domainId:outgoingDomainId,transformer:Transformer.compose(toNextDomainTransformer,toCurrentDomainTransformer)});}}
-return undefined;},selectModelDomainId_:function(){this.ensureAllDomainsAreConnected_();for(var chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(this.domainsSeen_.has(chromeDomainId)){this.modelDomainId_=chromeDomainId;return;}}
-var domainsSeenArray=Array.from(this.domainsSeen_);domainsSeenArray.sort();this.modelDomainId_=domainsSeenArray[0];},ensureAllDomainsAreConnected_:function(){var firstDomainId=undefined;for(var domainId of this.domainsSeen_){if(!firstDomainId){firstDomainId=domainId;continue;}
+visitedDomainIds.add(current.domainId);const outgoingTransformers=this.transformerMapByDomainId_[current.domainId];if(!outgoingTransformers)continue;for(const outgoingDomainId in outgoingTransformers){const toNextDomainTransformer=outgoingTransformers[outgoingDomainId];const toCurrentDomainTransformer=current.transformer;queue.push({domainId:outgoingDomainId,transformer:Transformer.compose(toNextDomainTransformer,toCurrentDomainTransformer)});}}
+return undefined;},selectModelDomainId_(){this.ensureAllDomainsAreConnected_();for(const chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(this.domainsSeen_.has(chromeDomainId)){this.modelDomainId_=chromeDomainId;return;}}
+const domainsSeenArray=Array.from(this.domainsSeen_);domainsSeenArray.sort();this.modelDomainId_=domainsSeenArray[0];},ensureAllDomainsAreConnected_(){let firstDomainId=undefined;for(const domainId of this.domainsSeen_){if(!firstDomainId){firstDomainId=domainId;continue;}
 if(!this.getTransformerBetween_(firstDomainId,domainId)){throw new Error('Unable to select a master clock domain because no '+'path can be found from "'+firstDomainId+'" to "'+domainId+'".');}}
-return true;},onDomainSeen_:function(domainId){if(domainId===ClockDomainId.UNKNOWN_CHROME_LEGACY&&!this.domainsSeen_.has(ClockDomainId.UNKNOWN_CHROME_LEGACY)){for(var chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(chromeDomainId===ClockDomainId.UNKNOWN_CHROME_LEGACY){continue;}
+return true;},onDomainSeen_(domainId){if(domainId===ClockDomainId.UNKNOWN_CHROME_LEGACY&&!this.domainsSeen_.has(ClockDomainId.UNKNOWN_CHROME_LEGACY)){for(const chromeDomainId of POSSIBLE_CHROME_CLOCK_DOMAINS){if(chromeDomainId===ClockDomainId.UNKNOWN_CHROME_LEGACY){continue;}
 this.collapseDomains_(ClockDomainId.UNKNOWN_CHROME_LEGACY,chromeDomainId);}}
-this.domainsSeen_.add(domainId);},onSyncCompleted_:function(marker1,marker2){var forwardTransformer=Transformer.fromMarkers(marker1,marker2);var backwardTransformer=Transformer.fromMarkers(marker2,marker1);var existingTransformer=this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId];if(!existingTransformer||forwardTransformer.error<existingTransformer.error){this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId]=forwardTransformer;this.getOrCreateTransformerMap_(marker2.domainId)[marker1.domainId]=backwardTransformer;}},collapseDomains_:function(domain1Id,domain2Id){this.getOrCreateTransformerMap_(domain1Id)[domain2Id]=this.getOrCreateTransformerMap_(domain2Id)[domain1Id]=Transformer.IDENTITY;},getOrCreateTransformerMap_:function(domainId){if(!this.transformerMapByDomainId_[domainId]){this.transformerMapByDomainId_[domainId]={};}
-return this.transformerMapByDomainId_[domainId];},computeDotGraph:function(){let dotString='graph {\n';const domainsSeen=[...this.domainsSeen_].sort();for(const domainId of domainsSeen){dotString+=`${domainId}[shape=box]\n`;}
-const markersBySyncIdEntries=[...this.markersBySyncId_.entries()].sort(([syncId1,markers1],[syncId2,markers2])=>syncId1.localeCompare(syncId2));for(const[syncId,markers]of markersBySyncIdEntries){const sortedMarkers=markers.sort((a,b)=>a.domainId.localeCompare(b.domainId));for(const m of markers){dotString+=`"${syncId}"--${m.domainId}`;dotString+=`[label="[${m.startTs}, ${m.endTs}]"]\n`;}}
+this.domainsSeen_.add(domainId);},onSyncCompleted_(marker1,marker2){const forwardTransformer=Transformer.fromMarkers(marker1,marker2);const backwardTransformer=Transformer.fromMarkers(marker2,marker1);const existingTransformer=this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId];if(!existingTransformer||forwardTransformer.error<existingTransformer.error){this.getOrCreateTransformerMap_(marker1.domainId)[marker2.domainId]=forwardTransformer;this.getOrCreateTransformerMap_(marker2.domainId)[marker1.domainId]=backwardTransformer;}},collapseDomains_(domain1Id,domain2Id){this.getOrCreateTransformerMap_(domain1Id)[domain2Id]=this.getOrCreateTransformerMap_(domain2Id)[domain1Id]=Transformer.IDENTITY;},getOrCreateTransformerMap_(domainId){if(!this.transformerMapByDomainId_[domainId]){this.transformerMapByDomainId_[domainId]={};}
+return this.transformerMapByDomainId_[domainId];},computeDotGraph(){let dotString='graph {\n';const domainsSeen=[...this.domainsSeen_].sort();for(const domainId of domainsSeen){dotString+=`  ${domainId}[shape=box]\n`;}
+const markersBySyncIdEntries=[...this.markersBySyncId_.entries()].sort(([syncId1,markers1],[syncId2,markers2])=>syncId1.localeCompare(syncId2));for(const[syncId,markers]of markersBySyncIdEntries){const sortedMarkers=markers.sort((a,b)=>a.domainId.localeCompare(b.domainId));for(const m of markers){dotString+=`  "${syncId}" -- ${m.domainId} `;dotString+=`[label="[${m.startTs}, ${m.endTs}]"]\n`;}}
 dotString+='}';return dotString;}};function ClockSyncMarker(domainId,startTs,opt_endTs){this.domainId=domainId;this.startTs=startTs;this.endTs=opt_endTs===undefined?startTs:opt_endTs;}
 ClockSyncMarker.prototype={get duration(){return this.endTs-this.startTs;},get ts(){return this.startTs+this.duration/2;}};function Transformer(fn,error){this.fn=fn;this.error=error;}
-Transformer.IDENTITY=new Transformer(tr.b.identity,0);Transformer.compose=function(aToB,bToC){return new Transformer((ts)=>bToC.fn(aToB.fn(ts)),aToB.error+bToC.error);};Transformer.fromMarkers=function(fromMarker,toMarker){var fromTs=fromMarker.ts;var toTs=toMarker.ts;if(fromMarker.domainId===ClockDomainId.BATTOR&&toMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){toTs=toMarker.startTs;}else if(toMarker.domainId===ClockDomainId.BATTOR&&fromMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){fromTs=fromMarker.startTs;}
-var tsShift=toTs-fromTs;return new Transformer((ts)=>ts+tsShift,fromMarker.duration+toMarker.duration);};return{ClockDomainId,ClockSyncManager,};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
-CounterSample.groupByTimestamp=function(samples){var samplesByTimestamp=tr.b.group(samples,function(sample){return sample.timestamp;});var timestamps=Object.keys(samplesByTimestamp);timestamps.sort();var groups=[];for(var i=0;i<timestamps.length;i++){var ts=timestamps[i];var group=samplesByTimestamp[ts];group.sort(function(x,y){return x.series.seriesIndex-y.series.seriesIndex;});groups.push(group);}
-return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange:function(range){range.addValue(this.timestamp);},getSampleIndex:function(){return tr.b.math.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
-tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples'});return{CounterSample,};});'use strict';tr.exportTo('tr.model',function(){var CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
-CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample:function(idx){return this.samples_[idx];},getTimestamp:function(idx){return this.timestamps_[idx];},addCounterSample:function(ts,val){var sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample:function(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics:function(sampleIndices){var sum=0;var min=Number.MAX_VALUE;var max=-Number.MAX_VALUE;for(var i=0;i<sampleIndices.length;++i){var sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
-return{min:min,max:max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward:function(amount){for(var i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},childEvents:function*(){yield*this.samples_;},childEventContainers:function*(){}};return{CounterSeries,};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
-Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},childEvents:function*(){},childEventContainers:function*(){yield*this.series;},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries:function(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries:function(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)return[];return this.series_[0].timestamps;},getSampleStatistics:function(sampleIndices){sampleIndices.sort();var ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward:function(amount){for(var i=0;i<this.series_.length;++i){this.series_[i].shiftTimestampsForward(amount);}},updateBounds:function(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)return;var firstSeries=this.series_[0];var lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));var numSeries=this.numSeries;this.maxTotal=-Infinity;for(var i=0;i<firstSeries.length;++i){var total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){var tmp=x.parent.compareTo(y.parent);if(tmp!==0)return tmp;var tmp=x.name.localeCompare(y.name);if(tmp===0)return x.tid-y.tid;return tmp;};return{Counter,};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
-CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice:function(){if(!this.threadThatWasRunning){return undefined;}
-var timeSlices=this.threadThatWasRunning.timeSlices;for(var i=0;i<timeSlices.length;i++){var timeSlice=timeSlices[i];if(timeSlice.start!==this.start){continue;}
+Transformer.IDENTITY=new Transformer(tr.b.identity,0);Transformer.compose=function(aToB,bToC){return new Transformer((ts)=>bToC.fn(aToB.fn(ts)),aToB.error+bToC.error);};Transformer.fromMarkers=function(fromMarker,toMarker){let fromTs=fromMarker.ts;let toTs=toMarker.ts;if(fromMarker.domainId===ClockDomainId.BATTOR&&toMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){toTs=toMarker.startTs;}else if(toMarker.domainId===ClockDomainId.BATTOR&&fromMarker.duration>BATTOR_FAST_SYNC_THRESHOLD_MS){fromTs=fromMarker.startTs;}
+const tsShift=toTs-fromTs;return new Transformer((ts)=>ts+tsShift,fromMarker.duration+toMarker.duration);};return{ClockDomainId,ClockSyncManager,};});'use strict';tr.exportTo('tr.model',function(){function CounterSample(series,timestamp,value){tr.model.Event.call(this);this.series_=series;this.timestamp_=timestamp;this.value_=value;}
+CounterSample.groupByTimestamp=function(samples){const samplesByTimestamp=tr.b.groupIntoMap(samples,s=>s.timestamp);const timestamps=Array.from(samplesByTimestamp.keys());timestamps.sort();const groups=[];for(const ts of timestamps){const group=samplesByTimestamp.get(ts);group.sort((x,y)=>x.series.seriesIndex-y.series.seriesIndex);groups.push(group);}
+return groups;};CounterSample.prototype={__proto__:tr.model.Event.prototype,get series(){return this.series_;},get timestamp(){return this.timestamp_;},get value(){return this.value_;},set timestamp(timestamp){this.timestamp_=timestamp;},addBoundsToRange(range){range.addValue(this.timestamp);},getSampleIndex(){return tr.b.math.findLowIndexInSortedArray(this.series.timestamps,function(x){return x;},this.timestamp_);},get userFriendlyName(){return'Counter sample from '+this.series_.title+' at '+
+tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(CounterSample,{name:'counterSample',pluralName:'counterSamples'});return{CounterSample,};});'use strict';tr.exportTo('tr.model',function(){const CounterSample=tr.model.CounterSample;function CounterSeries(name,color){tr.model.EventContainer.call(this);this.name_=name;this.color_=color;this.timestamps_=[];this.samples_=[];this.counter=undefined;this.seriesIndex=undefined;}
+CounterSeries.prototype={__proto__:tr.model.EventContainer.prototype,get length(){return this.timestamps_.length;},get name(){return this.name_;},get color(){return this.color_;},get samples(){return this.samples_;},get timestamps(){return this.timestamps_;},getSample(idx){return this.samples_[idx];},getTimestamp(idx){return this.timestamps_[idx];},addCounterSample(ts,val){const sample=new CounterSample(this,ts,val);this.addSample(sample);return sample;},addSample(sample){this.timestamps_.push(sample.timestamp);this.samples_.push(sample);},getStatistics(sampleIndices){let sum=0;let min=Number.MAX_VALUE;let max=-Number.MAX_VALUE;for(let i=0;i<sampleIndices.length;++i){const sample=this.getSample(sampleIndices[i]).value;sum+=sample;min=Math.min(sample,min);max=Math.max(sample,max);}
+return{min,max,avg:(sum/sampleIndices.length),start:this.getSample(sampleIndices[0]).value,end:this.getSample(sampleIndices.length-1).value};},shiftTimestampsForward(amount){for(let i=0;i<this.timestamps_.length;++i){this.timestamps_[i]+=amount;this.samples_[i].timestamp=this.timestamps_[i];}},*childEvents(){yield*this.samples_;},*childEventContainers(){}};return{CounterSeries,};});'use strict';tr.exportTo('tr.model',function(){function Counter(parent,id,category,name){tr.model.EventContainer.call(this);this.parent_=parent;this.id_=id;this.category_=category||'';this.name_=name;this.series_=[];this.totals=[];}
+Counter.prototype={__proto__:tr.model.EventContainer.prototype,get parent(){return this.parent_;},get id(){return this.id_;},get category(){return this.category_;},get name(){return this.name_;},*childEvents(){},*childEventContainers(){yield*this.series;},set timestamps(arg){throw new Error('Bad counter API. No cookie.');},set seriesNames(arg){throw new Error('Bad counter API. No cookie.');},set seriesColors(arg){throw new Error('Bad counter API. No cookie.');},set samples(arg){throw new Error('Bad counter API. No cookie.');},addSeries(series){series.counter=this;series.seriesIndex=this.series_.length;this.series_.push(series);return series;},getSeries(idx){return this.series_[idx];},get series(){return this.series_;},get numSeries(){return this.series_.length;},get numSamples(){if(this.series_.length===0)return 0;return this.series_[0].length;},get timestamps(){if(this.series_.length===0)return[];return this.series_[0].timestamps;},getSampleStatistics(sampleIndices){sampleIndices.sort();const ret=[];this.series_.forEach(function(series){ret.push(series.getStatistics(sampleIndices));});return ret;},shiftTimestampsForward(amount){for(let i=0;i<this.series_.length;++i){this.series_[i].shiftTimestampsForward(amount);}},updateBounds(){this.totals=[];this.maxTotal=0;this.bounds.reset();if(this.series_.length===0)return;const firstSeries=this.series_[0];const lastSeries=this.series_[this.series_.length-1];this.bounds.addValue(firstSeries.getTimestamp(0));this.bounds.addValue(lastSeries.getTimestamp(lastSeries.length-1));const numSeries=this.numSeries;this.maxTotal=-Infinity;for(let i=0;i<firstSeries.length;++i){let total=0;this.series_.forEach(function(series){total+=series.getSample(i).value;this.totals.push(total);}.bind(this));this.maxTotal=Math.max(total,this.maxTotal);}}};Counter.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp!==0)return tmp;tmp=x.name.localeCompare(y.name);if(tmp===0)return x.tid-y.tid;return tmp;};return{Counter,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;function CpuSlice(cat,title,colorId,start,args,opt_duration){Slice.apply(this,arguments);this.threadThatWasRunning=undefined;this.cpu=undefined;}
+CpuSlice.prototype={__proto__:Slice.prototype,get analysisTypeName(){return'tr.ui.analysis.CpuSlice';},getAssociatedTimeslice(){if(!this.threadThatWasRunning){return undefined;}
+const timeSlices=this.threadThatWasRunning.timeSlices;for(let i=0;i<timeSlices.length;i++){const timeSlice=timeSlices[i];if(timeSlice.start!==this.start){continue;}
 if(timeSlice.duration!==this.duration){continue;}
 return timeSlice;}
 return undefined;}};tr.model.EventRegistry.register(CpuSlice,{name:'cpuSlice',pluralName:'cpuSlices'});return{CpuSlice,};});'use strict';tr.exportTo('tr.model',function(){function TimeToObjectInstanceMap(createObjectInstanceFunction,parent,scopedId){this.createObjectInstanceFunction_=createObjectInstanceFunction;this.parent=parent;this.scopedId=scopedId;this.instances=[];}
-TimeToObjectInstanceMap.prototype={idWasCreated:function(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
-var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
-lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot:function(category,name,ts,args,opt_baseTypeName){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
-var i=tr.b.math.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);var instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
+TimeToObjectInstanceMap.prototype={idWasCreated(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));this.instances[0].creationTsWasExplicit=true;return this.instances[0];}
+let lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.deletionTs){throw new Error('Mutation of the TimeToObjectInstanceMap must be '+'done in ascending timestamp order.');}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);lastInstance.creationTsWasExplicit=true;this.instances.push(lastInstance);return lastInstance;},addSnapshot(category,name,ts,args,opt_baseTypeName){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName));}
+const i=tr.b.math.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);let instance;if(i<0){instance=this.instances[0];if(ts>instance.deletionTs||instance.creationTsWasExplicit){throw new Error('At the provided timestamp, no instance was still alive');}
 if(instance.snapshots.length!==0){throw new Error('Cannot shift creationTs forward, '+'snapshots have been added. First snap was at ts='+
 instance.snapshots[0].ts+' and creationTs was '+
 instance.creationTs);}
-instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{var lastValidIndex;for(var i=this.instances.length-1;i>=0;i--){var tmp=this.instances[i];if(ts>=tmp.deletionTs)break;if(tmp.creationTsWasExplicit===false&&tmp.snapshots.length===0){lastValidIndex=i;}}
+instance.creationTs=ts;}else if(i>=this.instances.length){instance=this.instances[this.instances.length-1];if(ts>=instance.deletionTs){instance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts,opt_baseTypeName);this.instances.push(instance);}else{let lastValidIndex;for(let i=this.instances.length-1;i>=0;i--){const tmp=this.instances[i];if(ts>=tmp.deletionTs)break;if(tmp.creationTsWasExplicit===false&&tmp.snapshots.length===0){lastValidIndex=i;}}
 if(lastValidIndex===undefined){throw new Error('Cannot add snapshot. No instance was alive that was mutable.');}
 instance=this.instances[lastValidIndex];instance.creationTs=ts;}}else{instance=this.instances[i];}
-return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length===0)return undefined;return this.instances[this.instances.length-1];},idWasDeleted:function(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
-var lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs){throw new Error('Cannot delete an id before it was created');}
+return instance.addSnapshot(ts,args,name,opt_baseTypeName);},get lastInstance(){if(this.instances.length===0)return undefined;return this.instances[this.instances.length-1];},idWasDeleted(category,name,ts){if(this.instances.length===0){this.instances.push(this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts));}
+let lastInstance=this.instances[this.instances.length-1];if(ts<lastInstance.creationTs){throw new Error('Cannot delete an id before it was created');}
 if(lastInstance.deletionTs===Number.MAX_VALUE){lastInstance.wasDeleted(ts);return lastInstance;}
 if(ts<lastInstance.deletionTs){throw new Error('id was already deleted earlier.');}
-lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt:function(ts){var i=tr.b.math.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit){return undefined;}
+lastInstance=this.createObjectInstanceFunction_(this.parent,this.scopedId,category,name,ts);this.instances.push(lastInstance);lastInstance.wasDeleted(ts);return lastInstance;},getInstanceAt(ts){const i=tr.b.math.findIndexInSortedIntervals(this.instances,function(inst){return inst.creationTs;},function(inst){return inst.deletionTs-inst.creationTs;},ts);if(i<0){if(this.instances[0].creationTsWasExplicit){return undefined;}
 return this.instances[0];}else if(i>=this.instances.length){return undefined;}
-return this.instances[i];}};return{TimeToObjectInstanceMap,};});'use strict';tr.exportTo('tr.model',function(){var ObjectInstance=tr.model.ObjectInstance;var ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
-ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,childEvents:function*(){for(var instance of this.getAllObjectInstances()){yield instance;yield*instance.snapshots;}},createObjectInstance_:function(parent,scopedId,category,name,creationTs,opt_baseTypeName){var constructor=tr.model.ObjectInstance.subTypes.getConstructor(category,name);var instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);var typeName=instance.typeName;var instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
-instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_:function(scopedId){var dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
-var instanceMap=dict[scopedId.id];if(instanceMap)return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot:function(scopedId,category,name,ts,args,opt_baseTypeName){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!==category){var msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
+return this.instances[i];}};return{TimeToObjectInstanceMap,};});'use strict';tr.exportTo('tr.model',function(){const ObjectInstance=tr.model.ObjectInstance;const ObjectSnapshot=tr.model.ObjectSnapshot;function ObjectCollection(parent){tr.model.EventContainer.call(this);this.parent=parent;this.instanceMapsByScopedId_={};this.instancesByTypeName_={};this.createObjectInstance_=this.createObjectInstance_.bind(this);}
+ObjectCollection.prototype={__proto__:tr.model.EventContainer.prototype,*childEvents(){for(const instance of this.getAllObjectInstances()){yield instance;yield*instance.snapshots;}},createObjectInstance_(parent,scopedId,category,name,creationTs,opt_baseTypeName){const constructor=tr.model.ObjectInstance.subTypes.getConstructor(category,name);const instance=new constructor(parent,scopedId,category,name,creationTs,opt_baseTypeName);const typeName=instance.typeName;let instancesOfTypeName=this.instancesByTypeName_[typeName];if(!instancesOfTypeName){instancesOfTypeName=[];this.instancesByTypeName_[typeName]=instancesOfTypeName;}
+instancesOfTypeName.push(instance);return instance;},getOrCreateInstanceMap_(scopedId){let dict;if(scopedId.scope in this.instanceMapsByScopedId_){dict=this.instanceMapsByScopedId_[scopedId.scope];}else{dict={};this.instanceMapsByScopedId_[scopedId.scope]=dict;}
+let instanceMap=dict[scopedId.id];if(instanceMap)return instanceMap;instanceMap=new tr.model.TimeToObjectInstanceMap(this.createObjectInstance_,this.parent,scopedId);dict[scopedId.id]=instanceMap;return instanceMap;},idWasCreated(scopedId,category,name,ts){const instanceMap=this.getOrCreateInstanceMap_(scopedId);return instanceMap.idWasCreated(category,name,ts);},addSnapshot(scopedId,category,name,ts,args,opt_baseTypeName){const instanceMap=this.getOrCreateInstanceMap_(scopedId);const snapshot=instanceMap.addSnapshot(category,name,ts,args,opt_baseTypeName);if(snapshot.objectInstance.category!==category){const msg='Added snapshot name='+name+' with cat='+category+' impossible. It instance was created/snapshotted with cat='+
 snapshot.objectInstance.category+' name='+
 snapshot.objectInstance.name;throw new Error(msg);}
 if(opt_baseTypeName&&snapshot.objectInstance.baseTypeName!==opt_baseTypeName){throw new Error('Could not add snapshot with baseTypeName='+
@@ -4885,254 +4949,251 @@
 snapshot.objectInstance.baseTypeName);}
 if(snapshot.objectInstance.name!==name){throw new Error('Could not add snapshot with name='+name+'. It '+'was previously created with name='+
 snapshot.objectInstance.name);}
-return snapshot;},idWasDeleted:function(scopedId,category,name,ts){var instanceMap=this.getOrCreateInstanceMap_(scopedId);var deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)return;if(deletedInstance.category!==category){var msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
+return snapshot;},idWasDeleted(scopedId,category,name,ts){const instanceMap=this.getOrCreateInstanceMap_(scopedId);const deletedInstance=instanceMap.idWasDeleted(category,name,ts);if(!deletedInstance)return;if(deletedInstance.category!==category){const msg='Deleting object '+deletedInstance.name+' with a different category '+'than when it was created. It previous had cat='+
 deletedInstance.category+' but the delete command '+'had cat='+category;throw new Error(msg);}
 if(deletedInstance.baseTypeName!==name){throw new Error('Deletion requested for name='+
 name+' could not proceed: '+'An existing object with baseTypeName='+
-deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects:function(maxTimestamp){for(var imapById of Object.values(this.instanceMapsByScopedId_)){for(var i2imap of Object.values(imapById)){var lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!==Number.MAX_VALUE)continue;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;}}},getObjectInstanceAt:function(scopedId,ts){var instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_){instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];}
-if(!instanceMap)return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt:function(scopedId,ts){var instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances:function(iter,opt_this){opt_this=opt_this||this;for(var imapById of Object.values(this.instanceMapsByScopedId_)){for(var i2imap of Object.values(imapById)){i2imap.instances.forEach(iter,opt_this);}}},getAllObjectInstances:function(){var instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed:function(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName:function(){return this.instancesByTypeName_;},preInitializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects:function(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances:function(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds:function(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward:function(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict:function(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection,};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
-AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey:function(){if(!this.name_)return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name_;},push:function(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);var shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)return;for(var sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){var prefix='';if(this.name!==undefined){prefix=this.name+'.';}else{prefix='';}
-var subGroupsByTitle={};for(var i=0;i<this.slices.length;++i){var slice=this.slices[i];var subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
+deletedInstance.baseTypeName+' existed.');}},autoDeleteObjects(maxTimestamp){for(const imapById of Object.values(this.instanceMapsByScopedId_)){for(const i2imap of Object.values(imapById)){const lastInstance=i2imap.lastInstance;if(lastInstance.deletionTs!==Number.MAX_VALUE)continue;i2imap.idWasDeleted(lastInstance.category,lastInstance.name,maxTimestamp);lastInstance.deletionTsWasExplicit=false;}}},getObjectInstanceAt(scopedId,ts){let instanceMap;if(scopedId.scope in this.instanceMapsByScopedId_){instanceMap=this.instanceMapsByScopedId_[scopedId.scope][scopedId.id];}
+if(!instanceMap)return undefined;return instanceMap.getInstanceAt(ts);},getSnapshotAt(scopedId,ts){const instance=this.getObjectInstanceAt(scopedId,ts);if(!instance)return undefined;return instance.getSnapshotAt(ts);},iterObjectInstances(iter,opt_this){opt_this=opt_this||this;for(const imapById of Object.values(this.instanceMapsByScopedId_)){for(const i2imap of Object.values(imapById)){i2imap.instances.forEach(iter,opt_this);}}},getAllObjectInstances(){const instances=[];this.iterObjectInstances(function(i){instances.push(i);});return instances;},getAllInstancesNamed(name){return this.instancesByTypeName_[name];},getAllInstancesByTypeName(){return this.instancesByTypeName_;},preInitializeAllObjects(){this.iterObjectInstances(function(instance){instance.preInitialize();});},initializeAllObjects(){this.iterObjectInstances(function(instance){instance.initialize();});},initializeInstances(){this.iterObjectInstances(function(instance){instance.initialize();});},updateBounds(){this.bounds.reset();this.iterObjectInstances(function(instance){instance.updateBounds();this.bounds.addRange(instance.bounds);},this);},shiftTimestampsForward(amount){this.iterObjectInstances(function(instance){instance.shiftTimestampsForward(amount);});},addCategoriesToDict(categoriesDict){this.iterObjectInstances(function(instance){categoriesDict[instance.category]=true;});}};return{ObjectCollection,};});'use strict';tr.exportTo('tr.model',function(){function AsyncSliceGroup(parentContainer,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;this.slices=[];this.name_=opt_name;this.viewSubGroups_=undefined;}
+AsyncSliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.parent.model;},get stableId(){return this.parentContainer_.stableId+'.AsyncSliceGroup';},getSettingsKey(){if(!this.name_)return undefined;const parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name_;},push(slice){slice.parentContainer=this.parentContainer;this.slices.push(slice);return slice;},get length(){return this.slices.length;},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];slice.start=(slice.start+amount);const shiftSubSlices=function(subSlices){if(subSlices===undefined||subSlices.length===0)return;for(let sJ=0;sJ<subSlices.length;sJ++){subSlices[sJ].start+=amount;shiftSubSlices(subSlices[sJ].subSlices);}};shiftSubSlices(slice.subSlices);}},updateBounds(){this.bounds.reset();for(let i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},get viewSubGroups(){if(this.viewSubGroups_===undefined){let prefix='';if(this.name!==undefined){prefix=this.name+'.';}else{prefix='';}
+const subGroupsByTitle={};for(let i=0;i<this.slices.length;++i){const slice=this.slices[i];const subGroupTitle=slice.viewSubGroupTitle;if(!subGroupsByTitle[subGroupTitle]){subGroupsByTitle[subGroupTitle]=new AsyncSliceGroup(this.parentContainer_,prefix+subGroupTitle);}
 subGroupsByTitle[subGroupTitle].push(slice);}
-this.viewSubGroups_=tr.b.dictionaryValues(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
-return this.viewSubGroups_;},findTopmostSlicesInThisContainer:function*(eventPredicate,opt_this){for(var slice of this.slices){if(slice.isTopLevel){yield*slice.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}}},childEvents:function*(){for(var slice of this.slices){yield slice;if(slice.subSlices){yield*slice.subSlices;}}},childEventContainers:function*(){}};return{AsyncSliceGroup,};});'use strict';tr.exportTo('tr.model',function(){var Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId);this.subSlices=[];}
-ThreadSlice.prototype={__proto__:Slice.prototype,get overlappingSamples(){var samples=new tr.model.EventSet();if(!this.parentContainer||!this.parentContainer.samples){return samples;}
-this.parentContainer.samples.forEach(function(sample){if(this.start<=sample.start&&sample.start<=this.end){samples.push(sample);}},this);return samples;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices'});return{ThreadSlice,};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var ThreadSlice=tr.model.ThreadSlice;function getSliceLo(s){return s.start;}
+this.viewSubGroups_=Object.values(subGroupsByTitle);this.viewSubGroups_.sort(function(a,b){return a.slices[0].compareTo(b.slices[0]);});}
+return this.viewSubGroups_;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){for(const slice of this.slices){if(slice.isTopLevel){yield*slice.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}}},*childEvents(){for(const slice of this.slices){yield slice;if(slice.subSlices){yield*slice.subSlices;}}},*childEventContainers(){}};return{AsyncSliceGroup,};});'use strict';tr.exportTo('tr.model',function(){const Slice=tr.model.Slice;function ThreadSlice(cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId){Slice.call(this,cat,title,colorId,start,args,opt_duration,opt_cpuStart,opt_cpuDuration,opt_argsStripped,opt_bindId);this.subSlices=[];}
+ThreadSlice.prototype={__proto__:Slice.prototype,get overlappingSamples(){const samples=new tr.model.EventSet();if(!this.parentContainer||!this.parentContainer.samples){return samples;}
+this.parentContainer.samples.forEach(function(sample){if(this.start<=sample.start&&sample.start<=this.end){samples.push(sample);}},this);return samples;}};tr.model.EventRegistry.register(ThreadSlice,{name:'slice',pluralName:'slices'});return{ThreadSlice,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const ThreadSlice=tr.model.ThreadSlice;function getSliceLo(s){return s.start;}
 function getSliceHi(s){return s.end;}
-function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;var sliceConstructor=opt_sliceConstructor||ThreadSlice;this.sliceConstructor=sliceConstructor;this.sliceConstructorSubTypes=this.sliceConstructor.subTypes;if(!this.sliceConstructorSubTypes){throw new Error('opt_sliceConstructor must have a subtype registry.');}
+function SliceGroup(parentContainer,opt_sliceConstructor,opt_name){tr.model.EventContainer.call(this);this.parentContainer_=parentContainer;const sliceConstructor=opt_sliceConstructor||ThreadSlice;this.sliceConstructor=sliceConstructor;this.sliceConstructorSubTypes=this.sliceConstructor.subTypes;if(!this.sliceConstructorSubTypes){throw new Error('opt_sliceConstructor must have a subtype registry.');}
 this.openPartialSlices_=[];this.slices=[];this.topLevelSlices=[];this.haveTopLevelSlicesBeenBuilt=false;this.name_=opt_name;if(this.model===undefined){throw new Error('SliceGroup must have model defined.');}}
-SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey:function(){if(!this.name_)return undefined;var parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice:function(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices:function(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice:function(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){var prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start){throw new Error('Slices must be added in increasing timestamp order');}}
-var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var sliceConstructorSubTypes=this.sliceConstructorSubTypes;var sliceType=sliceConstructorSubTypes.getConstructor(category,title);var slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd:function(ts){if(!this.openPartialSlices_.length)return true;var top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice:function(ts,opt_tts,opt_colorId){if(!this.openSliceCount){throw new Error('endSlice called without an open slice');}
-var slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start){throw new Error('Slice '+slice.title+' end time is before its start.');}
+SliceGroup.prototype={__proto__:tr.model.EventContainer.prototype,get parentContainer(){return this.parentContainer_;},get model(){return this.parentContainer_.model;},get stableId(){return this.parentContainer_.stableId+'.SliceGroup';},getSettingsKey(){if(!this.name_)return undefined;const parentKey=this.parentContainer_.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},get length(){return this.slices.length;},pushSlice(slice){this.haveTopLevelSlicesBeenBuilt=false;slice.parentContainer=this.parentContainer_;this.slices.push(slice);return slice;},pushSlices(slices){this.haveTopLevelSlicesBeenBuilt=false;slices.forEach(function(slice){slice.parentContainer=this.parentContainer_;this.slices.push(slice);},this);},beginSlice(category,title,ts,opt_args,opt_tts,opt_argsStripped,opt_colorId){if(this.openPartialSlices_.length){const prevSlice=this.openPartialSlices_[this.openPartialSlices_.length-1];if(ts<prevSlice.start){throw new Error('Slices must be added in increasing timestamp order');}}
+const colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(category,title);const slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},null,opt_tts,undefined,opt_argsStripped);this.openPartialSlices_.push(slice);slice.didNotFinish=true;this.pushSlice(slice);return slice;},isTimestampValidForBeginOrEnd(ts){if(!this.openPartialSlices_.length)return true;const top=this.openPartialSlices_[this.openPartialSlices_.length-1];return ts>=top.start;},get openSliceCount(){return this.openPartialSlices_.length;},get mostRecentlyOpenedPartialSlice(){if(!this.openPartialSlices_.length)return undefined;return this.openPartialSlices_[this.openPartialSlices_.length-1];},endSlice(ts,opt_tts,opt_colorId){if(!this.openSliceCount){throw new Error('endSlice called without an open slice');}
+const slice=this.openPartialSlices_[this.openSliceCount-1];this.openPartialSlices_.splice(this.openSliceCount-1,1);if(ts<slice.start){throw new Error('Slice '+slice.title+' end time is before its start.');}
 slice.duration=ts-slice.start;slice.didNotFinish=false;slice.colorId=opt_colorId||slice.colorId;if(opt_tts&&slice.cpuStart!==undefined){slice.cpuDuration=opt_tts-slice.cpuStart;}
-return slice;},pushCompleteSlice:function(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bindId){var colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);var sliceConstructorSubTypes=this.sliceConstructorSubTypes;var sliceType=sliceConstructorSubTypes.getConstructor(category,title);var slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bindId);if(duration===undefined){slice.didNotFinish=true;}
-this.pushSlice(slice);return slice;},autoCloseOpenSlices:function(){this.updateBounds();var maxTimestamp=this.bounds.max;for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];if(slice.didNotFinish){slice.duration=maxTimestamp-slice.start;}}
-this.openPartialSlices_=[];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){var slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds:function(){this.bounds.reset();for(var i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice:function(slice){var sliceConstructorSubTypes=this.sliceConstructorSubTypes;var sliceType=sliceConstructorSubTypes.getConstructor(slice.category,slice.title);var newSlice=new sliceType(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},findTopmostSlicesInThisContainer:function*(eventPredicate,opt_this){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
-for(var s of this.topLevelSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},childEvents:function*(){yield*this.slices;},childEventContainers:function*(){},getSlicesOfName:function(title){var slices=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].title===title){slices.push(this.slices[i]);}}
-return slices;},iterSlicesInTimeRange:function(callback,start,end){var ret=[];tr.b.math.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);for(var slice of topLevelSlice.enumerateAllDescendents()){callback(slice);}});return ret;},findFirstSlice:function(){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
-if(0===this.slices.length)return undefined;return this.slices[0];},findSliceAtTs:function(ts){if(!this.haveTopLevelSlicesBeenBuilt)throw new Error('Nope');var i=tr.b.math.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===this.topLevelSlices.length){return undefined;}
-var curSlice=this.topLevelSlices[i];while(true){var i=tr.b.math.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===curSlice.subSlices.length){return curSlice;}
-curSlice=curSlice.subSlices[i];}},findNextSliceAfter:function(ts,refGuid){var i=tr.b.math.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length){return undefined;}
-for(;i<this.slices.length;i++){var slice=this.slices[i];if(slice.start>ts)return slice;if(slice.guid<=refGuid)continue;return slice;}
-return undefined;},hasCpuDuration_:function(){if(this.slices.some(function(slice){return slice.cpuDuration!==undefined;}))return true;return false;},createSubSlices:function(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(!this.hasCpuDuration_()&&this.parentContainer.timeSlices){this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);}
-this.slices.forEach(function(slice){var selfTime=slice.duration;for(var i=0;i<slice.subSlices.length;i++){selfTime-=slice.subSlices[i].duration;}
-slice.selfTime=selfTime;if(slice.cpuDuration===undefined)return;var cpuSelfTime=slice.cpuDuration;for(var i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined){cpuSelfTime-=slice.subSlices[i].cpuDuration;}}
-slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_:function(){var precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(parent,child){if(parent.bounds(child,precisionUnit)){child.parentSlice=parent;if(parent.subSlices===undefined){parent.subSlices=[];}
+return slice;},pushCompleteSlice(category,title,ts,duration,tts,cpuDuration,opt_args,opt_argsStripped,opt_colorId,opt_bindId){const colorId=opt_colorId||ColorScheme.getColorIdForGeneralPurposeString(title);const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(category,title);const slice=new sliceType(category,title,colorId,ts,opt_args?opt_args:{},duration,tts,cpuDuration,opt_argsStripped,opt_bindId);if(duration===undefined){slice.didNotFinish=true;}
+this.pushSlice(slice);return slice;},autoCloseOpenSlices(){this.updateBounds();const maxTimestamp=this.bounds.max;for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];if(slice.didNotFinish){slice.duration=maxTimestamp-slice.start;}}
+this.openPartialSlices_=[];},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){const slice=this.slices[sI];slice.start=(slice.start+amount);}},updateBounds(){this.bounds.reset();for(let i=0;i<this.slices.length;i++){this.bounds.addValue(this.slices[i].start);this.bounds.addValue(this.slices[i].end);}},copySlice(slice){const sliceConstructorSubTypes=this.sliceConstructorSubTypes;const sliceType=sliceConstructorSubTypes.getConstructor(slice.category,slice.title);const newSlice=new sliceType(slice.category,slice.title,slice.colorId,slice.start,slice.args,slice.duration,slice.cpuStart,slice.cpuDuration);newSlice.didNotFinish=slice.didNotFinish;return newSlice;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
+for(const s of this.topLevelSlices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate);}},*childEvents(){yield*this.slices;},*childEventContainers(){},getSlicesOfName(title){const slices=[];for(let i=0;i<this.slices.length;i++){if(this.slices[i].title===title){slices.push(this.slices[i]);}}
+return slices;},iterSlicesInTimeRange(callback,start,end){const ret=[];tr.b.math.iterateOverIntersectingIntervals(this.topLevelSlices,function(s){return s.start;},function(s){return s.duration;},start,end,function(topLevelSlice){callback(topLevelSlice);for(const slice of topLevelSlice.enumerateAllDescendents()){callback(slice);}});return ret;},findFirstSlice(){if(!this.haveTopLevelSlicesBeenBuilt){throw new Error('Nope');}
+if(0===this.slices.length)return undefined;return this.slices[0];},findSliceAtTs(ts){if(!this.haveTopLevelSlicesBeenBuilt)throw new Error('Nope');let i=tr.b.math.findIndexInSortedClosedIntervals(this.topLevelSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===this.topLevelSlices.length){return undefined;}
+let curSlice=this.topLevelSlices[i];while(true){i=tr.b.math.findIndexInSortedClosedIntervals(curSlice.subSlices,getSliceLo,getSliceHi,ts);if(i===-1||i===curSlice.subSlices.length){return curSlice;}
+curSlice=curSlice.subSlices[i];}},findNextSliceAfter(ts,refGuid){let i=tr.b.math.findLowIndexInSortedArray(this.slices,getSliceLo,ts);if(i===this.slices.length){return undefined;}
+for(;i<this.slices.length;i++){const slice=this.slices[i];if(slice.start>ts)return slice;if(slice.guid<=refGuid)continue;return slice;}
+return undefined;},hasCpuDuration_(){if(this.slices.some(function(slice){return slice.cpuDuration!==undefined;}))return true;return false;},createSubSlices(){this.haveTopLevelSlicesBeenBuilt=true;this.createSubSlicesImpl_();if(!this.hasCpuDuration_()&&this.parentContainer.timeSlices){this.addCpuTimeToSubslices_(this.parentContainer.timeSlices);}
+this.slices.forEach(function(slice){let selfTime=slice.duration;for(let i=0;i<slice.subSlices.length;i++){selfTime-=slice.subSlices[i].duration;}
+slice.selfTime=selfTime;if(slice.cpuDuration===undefined)return;let cpuSelfTime=slice.cpuDuration;for(let i=0;i<slice.subSlices.length;i++){if(slice.subSlices[i].cpuDuration!==undefined){cpuSelfTime-=slice.subSlices[i].cpuDuration;}}
+slice.cpuSelfTime=cpuSelfTime;});},createSubSlicesImpl_(){const precisionUnit=this.model.intrinsicTimeUnit;function addSliceIfBounds(parent,child){if(parent.bounds(child,precisionUnit)){child.parentSlice=parent;if(parent.subSlices===undefined){parent.subSlices=[];}
 parent.subSlices.push(child);return true;}
 return false;}
-if(!this.slices.length)return;var ops=[];for(var i=0;i<this.slices.length;i++){if(this.slices[i].subSlices){this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);}
+if(!this.slices.length)return;const ops=[];for(let i=0;i<this.slices.length;i++){if(this.slices[i].subSlices){this.slices[i].subSlices.splice(0,this.slices[i].subSlices.length);}
 ops.push(i);}
-var originalSlices=this.slices;ops.sort(function(ix,iy){var x=originalSlices[ix];var y=originalSlices[iy];if(x.start!==y.start){return x.start-y.start;}
-return ix-iy;});var slices=new Array(this.slices.length);for(var i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
-var rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(var i=1;i<slices.length;i++){var slice=slices[i];while(rootSlice!==undefined&&(!addSliceIfBounds(rootSlice,slice))){rootSlice=rootSlice.parentSlice;}
+const originalSlices=this.slices;ops.sort(function(ix,iy){const x=originalSlices[ix];const y=originalSlices[iy];if(x.start!==y.start){return x.start-y.start;}
+return ix-iy;});const slices=new Array(this.slices.length);for(let i=0;i<ops.length;i++){slices[i]=originalSlices[ops[i]];}
+let rootSlice=slices[0];this.topLevelSlices=[];this.topLevelSlices.push(rootSlice);rootSlice.isTopLevel=true;for(let i=1;i<slices.length;i++){const slice=slices[i];while(rootSlice!==undefined&&(!addSliceIfBounds(rootSlice,slice))){rootSlice=rootSlice.parentSlice;}
 if(rootSlice===undefined){this.topLevelSlices.push(slice);slice.isTopLevel=true;}
 rootSlice=slice;}
-this.slices=slices;},addCpuTimeToSubslices_:function(timeSlices){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;var sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState===SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_:function(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start){return slice.end<=timeSlice.end;}
-var duration=timeSlice.duration;if(slice.start>timeSlice.start){duration-=slice.start-timeSlice.start;}
+this.slices=slices;},addCpuTimeToSubslices_(timeSlices){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;let sliceIdx=0;timeSlices.forEach(function(timeSlice){if(timeSlice.schedulingState===SCHEDULING_STATE.RUNNING){while(sliceIdx<this.topLevelSlices.length){if(this.addCpuTimeToSubslice_(this.topLevelSlices[sliceIdx],timeSlice)){sliceIdx++;}else{break;}}}},this);},addCpuTimeToSubslice_(slice,timeSlice){if(slice.start>timeSlice.end||slice.end<timeSlice.start){return slice.end<=timeSlice.end;}
+let duration=timeSlice.duration;if(slice.start>timeSlice.start){duration-=slice.start-timeSlice.start;}
 if(timeSlice.end>slice.end){duration-=timeSlice.end-slice.end;}
 if(slice.cpuDuration){slice.cpuDuration+=duration;}else{slice.cpuDuration=duration;}
-for(var i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
+for(let i=0;i<slice.subSlices.length;i++){this.addCpuTimeToSubslice_(slice.subSlices[i],timeSlice);}
 return slice.end<=timeSlice.end;}};SliceGroup.merge=function(groupA,groupB){if(groupA.openPartialSlices_.length>0){throw new Error('groupA has open partial slices');}
 if(groupB.openPartialSlices_.length>0){throw new Error('groupB has open partial slices');}
 if(groupA.parentContainer!==groupB.parentContainer){throw new Error('Different parent threads. Cannot merge');}
 if(groupA.sliceConstructor!==groupB.sliceConstructor){throw new Error('Different slice constructors. Cannot merge');}
-var result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);var slicesA=groupA.slices;var slicesB=groupB.slices;var idxA=0;var idxB=0;var openA=[];var openB=[];var splitOpenSlices=function(when){for(var i=0;i<openB.length;i++){var oldSlice=openB[i];var oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
-var newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')===-1){newSlice.title+=' (cont.)';}
-oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};var closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){var nextA=openA[openA.length-1];var nextB=openB[openB.length-1];var endA=nextA&&nextA.end;var endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
-if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){var sA=slicesA[idxA];var sB=slicesB[idxB];var nextSlice;var isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
+const result=new SliceGroup(groupA.parentContainer,groupA.sliceConstructor,groupA.name_);const slicesA=groupA.slices;const slicesB=groupB.slices;let idxA=0;let idxB=0;const openA=[];const openB=[];const splitOpenSlices=function(when){for(let i=0;i<openB.length;i++){const oldSlice=openB[i];const oldEnd=oldSlice.end;if(when<oldSlice.start||oldEnd<when){throw new Error('slice should not be split');}
+const newSlice=result.copySlice(oldSlice);newSlice.start=when;newSlice.duration=oldEnd-when;if(newSlice.title.indexOf(' (cont.)')===-1){newSlice.title+=' (cont.)';}
+oldSlice.duration=when-oldSlice.start;openB[i]=newSlice;result.pushSlice(newSlice);}};const closeOpenSlices=function(upTo){while(openA.length>0||openB.length>0){const nextA=openA[openA.length-1];const nextB=openB[openB.length-1];const endA=nextA&&nextA.end;const endB=nextB&&nextB.end;if((endA===undefined||endA>upTo)&&(endB===undefined||endB>upTo)){return;}
+if(endB===undefined||endA<endB){splitOpenSlices(endA);openA.pop();}else{openB.pop();}}};while(idxA<slicesA.length||idxB<slicesB.length){const sA=slicesA[idxA];const sB=slicesB[idxB];let nextSlice;let isFromB;if(sA===undefined||(sB!==undefined&&sA.start>sB.start)){nextSlice=result.copySlice(sB);isFromB=true;idxB++;}else{nextSlice=result.copySlice(sA);isFromB=false;idxA++;}
 closeOpenSlices(nextSlice.start);result.pushSlice(nextSlice);if(isFromB){openB.push(nextSlice);}else{splitOpenSlices(nextSlice.start);openA.push(nextSlice);}}
-closeOpenSlices();return result;};return{SliceGroup,};});'use strict';tr.exportTo('tr.model',function(){var AsyncSlice=tr.model.AsyncSlice;var AsyncSliceGroup=tr.model.AsyncSliceGroup;var SliceGroup=tr.model.SliceGroup;var ThreadSlice=tr.model.ThreadSlice;var ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent){throw new Error('Parent must be provided.');}
+closeOpenSlices();return result;};return{SliceGroup,};});'use strict';tr.exportTo('tr.model',function(){const AsyncSlice=tr.model.AsyncSlice;const AsyncSliceGroup=tr.model.AsyncSliceGroup;const SliceGroup=tr.model.SliceGroup;const ThreadSlice=tr.model.ThreadSlice;const ThreadTimeSlice=tr.model.ThreadTimeSlice;function Thread(parent,tid){if(!parent){throw new Error('Parent must be provided.');}
 tr.model.EventContainer.call(this);this.parent=parent;this.sortIndex=0;this.tid=tid;this.name=undefined;this.samples_=undefined;this.sliceGroup=new SliceGroup(this,ThreadSlice,'slices');this.timeSlices=undefined;this.kernelSliceGroup=new SliceGroup(this,ThreadSlice,'kernel-slices');this.asyncSliceGroup=new AsyncSliceGroup(this,'async-slices');}
-Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo:function(that){return Thread.compare(this,that);},childEventContainers:function*(){if(this.sliceGroup.length){yield this.sliceGroup;}
+Thread.prototype={__proto__:tr.model.EventContainer.prototype,get model(){return this.parent.model;},get stableId(){return this.parent.stableId+'.'+this.tid;},compareTo(that){return Thread.compare(this,that);},*childEventContainers(){if(this.sliceGroup.length){yield this.sliceGroup;}
 if(this.kernelSliceGroup.length){yield this.kernelSliceGroup;}
-if(this.asyncSliceGroup.length){yield this.asyncSliceGroup;}},childEvents:function*(){if(this.timeSlices){yield*this.timeSlices;}},iterateAllPersistableObjects:function(cb){cb(this);if(this.sliceGroup.length){cb(this.sliceGroup);}
-this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward:function(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(var i=0;i<this.timeSlices.length;i++){var slice=this.timeSlices[i];slice.start+=amount;}}
-this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)return false;if(this.sliceGroup.openSliceCount)return false;if(this.timeSlices&&this.timeSlices.length)return false;if(this.kernelSliceGroup.length)return false;if(this.asyncSliceGroup.length)return false;if(this.samples_.length)return false;return true;},updateBounds:function(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
-if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.sliceGroup.length;i++){categoriesDict[this.sliceGroup.slices[i].category]=true;}
-for(var i=0;i<this.kernelSliceGroup.length;i++){categoriesDict[this.kernelSliceGroup.slices[i].category]=true;}
-for(var i=0;i<this.asyncSliceGroup.length;i++){categoriesDict[this.asyncSliceGroup.slices[i].category]=true;}
-if(this.samples_){for(var i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}}},autoCloseOpenSlices:function(){this.sliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland:function(){if(this.kernelSliceGroup.length>0){var newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices:function(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(function(sample){return sample.thread===this;},this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
-(this.name?', name: '+this.name:'');},getSettingsKey:function(){if(!this.name)return undefined;var parentKey=this.parent.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},getProcess:function(){return this.parent;},indexOfTimeSlice:function(timeSlice){var i=tr.b.math.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)return undefined;return i;},getCpuStatsForRange:function(range){var stats={};stats.total=0;if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){var freqRange=tr.b.math.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);var intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState===tr.model.SCHEDULING_STATE.RUNNING){var cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats)){stats[cpu.cpuNumber]=0;}
+if(this.asyncSliceGroup.length){yield this.asyncSliceGroup;}},*childEvents(){if(this.timeSlices){yield*this.timeSlices;}},iterateAllPersistableObjects(cb){cb(this);if(this.sliceGroup.length){cb(this.sliceGroup);}
+this.asyncSliceGroup.viewSubGroups.forEach(cb);},shiftTimestampsForward(amount){this.sliceGroup.shiftTimestampsForward(amount);if(this.timeSlices){for(let i=0;i<this.timeSlices.length;i++){const slice=this.timeSlices[i];slice.start+=amount;}}
+this.kernelSliceGroup.shiftTimestampsForward(amount);this.asyncSliceGroup.shiftTimestampsForward(amount);},get isEmpty(){if(this.sliceGroup.length)return false;if(this.sliceGroup.openSliceCount)return false;if(this.timeSlices&&this.timeSlices.length)return false;if(this.kernelSliceGroup.length)return false;if(this.asyncSliceGroup.length)return false;if(this.samples_.length)return false;return true;},updateBounds(){this.bounds.reset();this.sliceGroup.updateBounds();this.bounds.addRange(this.sliceGroup.bounds);this.kernelSliceGroup.updateBounds();this.bounds.addRange(this.kernelSliceGroup.bounds);this.asyncSliceGroup.updateBounds();this.bounds.addRange(this.asyncSliceGroup.bounds);if(this.timeSlices&&this.timeSlices.length){this.bounds.addValue(this.timeSlices[0].start);this.bounds.addValue(this.timeSlices[this.timeSlices.length-1].end);}
+if(this.samples_&&this.samples_.length){this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].end);}},addCategoriesToDict(categoriesDict){for(let i=0;i<this.sliceGroup.length;i++){categoriesDict[this.sliceGroup.slices[i].category]=true;}
+for(let i=0;i<this.kernelSliceGroup.length;i++){categoriesDict[this.kernelSliceGroup.slices[i].category]=true;}
+for(let i=0;i<this.asyncSliceGroup.length;i++){categoriesDict[this.asyncSliceGroup.slices[i].category]=true;}
+if(this.samples_){for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}}},autoCloseOpenSlices(){this.sliceGroup.autoCloseOpenSlices();this.kernelSliceGroup.autoCloseOpenSlices();},mergeKernelWithUserland(){if(this.kernelSliceGroup.length>0){const newSlices=SliceGroup.merge(this.sliceGroup,this.kernelSliceGroup);this.sliceGroup.slices=newSlices.slices;this.kernelSliceGroup=new SliceGroup(this);this.updateBounds();}},createSubSlices(){this.sliceGroup.createSubSlices();this.samples_=this.parent.model.samples.filter(sample=>sample.thread===this);},get userFriendlyName(){return this.name||this.tid;},get userFriendlyDetails(){return'tid: '+this.tid+
+(this.name?', name: '+this.name:'');},getSettingsKey(){if(!this.name)return undefined;const parentKey=this.parent.getSettingsKey();if(!parentKey)return undefined;return parentKey+'.'+this.name;},getProcess(){return this.parent;},indexOfTimeSlice(timeSlice){const i=tr.b.math.findLowIndexInSortedArray(this.timeSlices,function(slice){return slice.start;},timeSlice.start);if(this.timeSlices[i]!==timeSlice)return undefined;return i;},getCpuStatsForRange(range){const stats={};stats.total=0;if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const freqRange=tr.b.math.Range.fromExplicitRange(threadTimeSlice.start,threadTimeSlice.end);const intersection=freqRange.findIntersection(range);if(threadTimeSlice.schedulingState===tr.model.SCHEDULING_STATE.RUNNING){const cpu=threadTimeSlice.cpuOnWhichThreadWasRunning;if(!(cpu.cpuNumber in stats)){stats[cpu.cpuNumber]=0;}
 stats[cpu.cpuNumber]+=intersection.duration;stats.total+=intersection.duration;}}
-tr.b.math.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange:function(start,end){var stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){var overlapStart=Math.max(threadTimeSlice.start,start);var overlapEnd=Math.min(threadTimeSlice.end,end);var schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
-tr.b.math.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;},getNetworkEventsInRange:function(rangeOfInterest){const networkEvents=[];for(const slice of Object.values(this.asyncSliceGroup.slices)){let match=false;if(slice.category==='net'||slice.category==='disabled-by-default-netlog'||slice.category==='netlog'||slice.category==='disabled-by-default-network'){match=true;}
-if(!match)continue;if(rangeOfInterest.intersectsExplicitRangeInclusive(slice.start,slice.end)){networkEvents.push(slice);}}
-return networkEvents;}};Thread.compare=function(x,y){var tmp=x.parent.compareTo(y.parent);if(tmp)return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;return x.tid-y.tid;};return{Thread,};});'use strict';tr.exportTo('tr.model',function(){var Thread=tr.model.Thread;var Counter=tr.model.Counter;function ProcessBase(model){if(!model){throw new Error('Must provide a model');}
+tr.b.math.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},range.min,range.max,addStatsForSlice);return stats;},getSchedulingStatsForRange(start,end){const stats={};if(!this.timeSlices)return stats;function addStatsForSlice(threadTimeSlice){const overlapStart=Math.max(threadTimeSlice.start,start);const overlapEnd=Math.min(threadTimeSlice.end,end);const schedulingState=threadTimeSlice.schedulingState;if(!(schedulingState in stats))stats[schedulingState]=0;stats[schedulingState]+=overlapEnd-overlapStart;}
+tr.b.math.iterateOverIntersectingIntervals(this.timeSlices,function(x){return x.start;},function(x){return x.end;},start,end,addStatsForSlice);return stats;},get samples(){return this.samples_;},get type(){const re=/^[^0-9|\/]+/;const matches=re.exec(this.name);if(matches&&matches[0])return matches[0];throw new Error('Could not determine thread type for thread name '+
+this.name);}};Thread.compare=function(x,y){let tmp=x.parent.compareTo(y.parent);if(tmp)return tmp;tmp=x.sortIndex-y.sortIndex;if(tmp)return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;return x.tid-y.tid;};return{Thread,};});'use strict';tr.exportTo('tr.model',function(){const Thread=tr.model.Thread;const Counter=tr.model.Counter;function ProcessBase(model){if(!model){throw new Error('Must provide a model');}
 tr.model.EventContainer.call(this);this.model=model;this.threads={};this.counters={};this.objects=new tr.model.ObjectCollection(this);this.sortIndex=0;}
-ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},childEventContainers:function*(){yield*tr.b.dictionaryValues(this.threads);yield*tr.b.dictionaryValues(this.counters);yield this.objects;},iterateAllPersistableObjects:function(cb){cb(this);for(var tid in this.threads){this.threads[tid].iterateAllPersistableObjects(cb);}},get numThreads(){var n=0;for(var p in this.threads){n++;}
-return n;},shiftTimestampsForward:function(amount){for(var child of this.childEventContainers()){child.shiftTimestampsForward(amount);}},autoCloseOpenSlices:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects:function(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects:function(){this.objects.preInitializeAllObjects();},initializeObjects:function(){this.objects.initializeAllObjects();},mergeKernelWithUserland:function(){for(var tid in this.threads){var thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds:function(){this.bounds.reset();for(var tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
-for(var id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
-this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict:function(categoriesDict){for(var tid in this.threads){this.threads[tid].addCategoriesToDict(categoriesDict);}
-for(var id in this.counters){categoriesDict[this.counters[id].category]=true;}
-this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching:function(predicate,opt_this){var threads=[];for(var tid in this.threads){var thread=this.threads[tid];if(predicate.call(opt_this,thread)){threads.push(thread);}}
-return threads;},findAllThreadsNamed:function(name){var threads=this.findAllThreadsMatching(function(thread){if(!thread.name)return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed:function(name){var threads=this.findAllThreadsNamed(name);if(threads.length===0)return undefined;if(threads.length>1){throw new Error('Expected no more than one '+name);}
-return threads[0];},pruneEmptyContainers:function(){var threadsToKeep={};for(var tid in this.threads){var thread=this.threads[tid];if(!thread.isEmpty){threadsToKeep[tid]=thread;}}
-this.threads=threadsToKeep;},getThread:function(tid){return this.threads[tid];},getOrCreateThread:function(tid){if(!this.threads[tid]){this.threads[tid]=new Thread(this,tid);}
-return this.threads[tid];},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
-return this.counters[id];},getSettingsKey:function(){throw new Error('Not implemented');},createSubSlices:function(){for(var tid in this.threads){this.threads[tid].createSubSlices();}}};return{ProcessBase,};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;var Counter=tr.model.Counter;var CpuSlice=tr.model.CpuSlice;function Cpu(kernel,number){if(kernel===undefined||number===undefined){throw new Error('Missing arguments');}
+ProcessBase.compare=function(x,y){return x.sortIndex-y.sortIndex;};ProcessBase.prototype={__proto__:tr.model.EventContainer.prototype,get stableId(){throw new Error('Not implemented');},*childEventContainers(){yield*Object.values(this.threads);yield*Object.values(this.counters);yield this.objects;},iterateAllPersistableObjects(cb){cb(this);for(const tid in this.threads){this.threads[tid].iterateAllPersistableObjects(cb);}},get numThreads(){let n=0;for(const p in this.threads){n++;}
+return n;},shiftTimestampsForward(amount){for(const child of this.childEventContainers()){child.shiftTimestampsForward(amount);}},autoCloseOpenSlices(){for(const tid in this.threads){const thread=this.threads[tid];thread.autoCloseOpenSlices();}},autoDeleteObjects(maxTimestamp){this.objects.autoDeleteObjects(maxTimestamp);},preInitializeObjects(){this.objects.preInitializeAllObjects();},initializeObjects(){this.objects.initializeAllObjects();},mergeKernelWithUserland(){for(const tid in this.threads){const thread=this.threads[tid];thread.mergeKernelWithUserland();}},updateBounds(){this.bounds.reset();for(const tid in this.threads){this.threads[tid].updateBounds();this.bounds.addRange(this.threads[tid].bounds);}
+for(const id in this.counters){this.counters[id].updateBounds();this.bounds.addRange(this.counters[id].bounds);}
+this.objects.updateBounds();this.bounds.addRange(this.objects.bounds);},addCategoriesToDict(categoriesDict){for(const tid in this.threads){this.threads[tid].addCategoriesToDict(categoriesDict);}
+for(const id in this.counters){categoriesDict[this.counters[id].category]=true;}
+this.objects.addCategoriesToDict(categoriesDict);},findAllThreadsMatching(predicate,opt_this){const threads=[];for(const tid in this.threads){const thread=this.threads[tid];if(predicate.call(opt_this,thread)){threads.push(thread);}}
+return threads;},findAllThreadsNamed(name){const threads=this.findAllThreadsMatching(function(thread){if(!thread.name)return false;return thread.name===name;});return threads;},findAtMostOneThreadNamed(name){const threads=this.findAllThreadsNamed(name);if(threads.length===0)return undefined;if(threads.length>1){throw new Error('Expected no more than one '+name);}
+return threads[0];},pruneEmptyContainers(){const threadsToKeep={};for(const tid in this.threads){const thread=this.threads[tid];if(!thread.isEmpty){threadsToKeep[tid]=thread;}}
+this.threads=threadsToKeep;},getThread(tid){return this.threads[tid];},getOrCreateThread(tid){if(!this.threads[tid]){this.threads[tid]=new Thread(this,tid);}
+return this.threads[tid];},getOrCreateCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
+return this.counters[id];},getSettingsKey(){throw new Error('Not implemented');},createSubSlices(){for(const tid in this.threads){this.threads[tid].createSubSlices();}}};return{ProcessBase,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;const Counter=tr.model.Counter;const CpuSlice=tr.model.CpuSlice;function Cpu(kernel,number){if(kernel===undefined||number===undefined){throw new Error('Missing arguments');}
 this.kernel=kernel;this.cpuNumber=number;this.slices=[];this.counters={};this.bounds_=new tr.b.math.Range();this.samples_=undefined;this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;}
-Cpu.prototype={__proto__:tr.model.EventContainer.prototype,get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},findTopmostSlicesInThisContainer:function*(eventPredicate,opt_this){for(var s of this.slices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}},childEvents:function*(){yield*this.slices;if(this.samples_){yield*this.samples_;}},childEventContainers:function*(){yield*tr.b.dictionaryValues(this.counters);},getOrCreateCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
-return this.counters[id];},getCounter:function(cat,name){var id=cat+'.'+name;if(!this.counters[id]){return undefined;}
-return this.counters[id];},shiftTimestampsForward:function(amount){for(var sI=0;sI<this.slices.length;sI++){this.slices[sI].start=(this.slices[sI].start+amount);}
-for(var id in this.counters){this.counters[id].shiftTimestampsForward(amount);}},updateBounds:function(){this.bounds_.reset();if(this.slices.length){this.bounds_.addValue(this.slices[0].start);this.bounds_.addValue(this.slices[this.slices.length-1].end);}
-for(var id in this.counters){this.counters[id].updateBounds();this.bounds_.addRange(this.counters[id].bounds);}
-if(this.samples_&&this.samples_.length){this.bounds_.addValue(this.samples_[0].start);this.bounds_.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices:function(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu===this;},this);},addCategoriesToDict:function(categoriesDict){for(var i=0;i<this.slices.length;i++){categoriesDict[this.slices[i].category]=true;}
-for(var id in this.counters){categoriesDict[this.counters[id].category]=true;}
-for(var i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}},indexOf:function(cpuSlice){var i=tr.b.math.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)return undefined;return i;},closeActiveThread:function(endTimestamp,args){if(this.lastActiveThread_===undefined||this.lastActiveThread_===0){return;}
+Cpu.prototype={__proto__:tr.model.EventContainer.prototype,get samples(){return this.samples_;},get userFriendlyName(){return'CPU '+this.cpuNumber;},*findTopmostSlicesInThisContainer(eventPredicate,opt_this){for(const s of this.slices){yield*s.findTopmostSlicesRelativeToThisSlice(eventPredicate,opt_this);}},*childEvents(){yield*this.slices;if(this.samples_){yield*this.samples_;}},*childEventContainers(){yield*Object.values(this.counters);},getOrCreateCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){this.counters[id]=new Counter(this,id,cat,name);}
+return this.counters[id];},getCounter(cat,name){const id=cat+'.'+name;if(!this.counters[id]){return undefined;}
+return this.counters[id];},shiftTimestampsForward(amount){for(let sI=0;sI<this.slices.length;sI++){this.slices[sI].start=(this.slices[sI].start+amount);}
+for(const id in this.counters){this.counters[id].shiftTimestampsForward(amount);}},updateBounds(){this.bounds_.reset();if(this.slices.length){this.bounds_.addValue(this.slices[0].start);this.bounds_.addValue(this.slices[this.slices.length-1].end);}
+for(const id in this.counters){this.counters[id].updateBounds();this.bounds_.addRange(this.counters[id].bounds);}
+if(this.samples_&&this.samples_.length){this.bounds_.addValue(this.samples_[0].start);this.bounds_.addValue(this.samples_[this.samples_.length-1].end);}},createSubSlices(){this.samples_=this.kernel.model.samples.filter(function(sample){return sample.cpu===this;},this);},addCategoriesToDict(categoriesDict){for(let i=0;i<this.slices.length;i++){categoriesDict[this.slices[i].category]=true;}
+for(const id in this.counters){categoriesDict[this.counters[id].category]=true;}
+for(let i=0;i<this.samples_.length;i++){categoriesDict[this.samples_[i].category]=true;}},indexOf(cpuSlice){const i=tr.b.math.findLowIndexInSortedArray(this.slices,function(slice){return slice.start;},cpuSlice.start);if(this.slices[i]!==cpuSlice)return undefined;return i;},closeActiveThread(endTimestamp,args){if(this.lastActiveThread_===undefined||this.lastActiveThread_===0){return;}
 if(endTimestamp<this.lastActiveTimestamp_){throw new Error('The end timestamp of a thread running on CPU '+
 this.cpuNumber+' is before its start timestamp.');}
-for(var key in args){this.lastActiveArgs_[key]=args[key];}
-var duration=endTimestamp-this.lastActiveTimestamp_;var slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread:function(timestamp,oldThreadArgs,newThreadId,newThreadName,newThreadArgs){this.closeActiveThread(timestamp,oldThreadArgs);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=newThreadId;this.lastActiveName_=newThreadName;this.lastActiveArgs_=newThreadArgs;},getFreqStatsForRange:function(range){var stats={};function addStatsForFreq(freqSample,index){var freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;var freqRange=tr.b.math.Range.fromExplicitRange(freqSample.timestamp,freqEnd);var intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats)){stats[freqSample.value]=0;}
+for(const key in args){this.lastActiveArgs_[key]=args[key];}
+const duration=endTimestamp-this.lastActiveTimestamp_;const slice=new tr.model.CpuSlice('',this.lastActiveName_,ColorScheme.getColorIdForGeneralPurposeString(this.lastActiveName_),this.lastActiveTimestamp_,this.lastActiveArgs_,duration);slice.cpu=this;this.slices.push(slice);this.lastActiveTimestamp_=undefined;this.lastActiveThread_=undefined;this.lastActiveName_=undefined;this.lastActiveArgs_=undefined;},switchActiveThread(timestamp,oldThreadArgs,newThreadId,newThreadName,newThreadArgs){this.closeActiveThread(timestamp,oldThreadArgs);this.lastActiveTimestamp_=timestamp;this.lastActiveThread_=newThreadId;this.lastActiveName_=newThreadName;this.lastActiveArgs_=newThreadArgs;},getFreqStatsForRange(range){const stats={};function addStatsForFreq(freqSample,index){const freqEnd=(index<freqSample.series_.length-1)?freqSample.series_.samples_[index+1].timestamp:range.max;const freqRange=tr.b.math.Range.fromExplicitRange(freqSample.timestamp,freqEnd);const intersection=freqRange.findIntersection(range);if(!(freqSample.value in stats)){stats[freqSample.value]=0;}
 stats[freqSample.value]+=intersection.duration;}
-var freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){var freqSeries=freqCounter.getSeries(0);if(!freqSeries)return;tr.b.math.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){if(index<freqSeries.length-1){return freqSeries.samples_[index+1].timestamp;}
+const freqCounter=this.getCounter('','Clock Frequency');if(freqCounter!==undefined){const freqSeries=freqCounter.getSeries(0);if(!freqSeries)return;tr.b.math.iterateOverIntersectingIntervals(freqSeries.samples_,function(x){return x.timestamp;},function(x,index){if(index<freqSeries.length-1){return freqSeries.samples_[index+1].timestamp;}
 return range.max;},range.min,range.max,addStatsForFreq);}
-return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu,};});'use strict';tr.exportTo('tr.model',function(){var Event=tr.model.Event;var EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,powerInW){Event.call(this);this.series_=series;this.start_=parseFloat(start);this.powerInW_=parseFloat(powerInW);}
-PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get powerInW(){return this.powerInW_;},set powerInW(value){this.powerInW_=value;},addBoundsToRange:function(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples'});return{PowerSample,};});'use strict';tr.exportTo('tr.model',function(){var PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
-PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample:function(ts,val){var sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumedInJ:function(start,end){var measurementRange=tr.b.math.Range.fromExplicitRange(start,end);var energyConsumedInJ=0;var startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;var endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0){startIndex=0;}
-for(var i=startIndex;i<endIndex;i++){var sample=this.samples[i];var nextSample=this.samples[i+1];var sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);var intersectionRangeInMs=measurementRange.findIntersection(sampleRange);var durationInS=tr.b.convertUnit(intersectionRangeInMs.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);energyConsumedInJ+=durationInS*sample.powerInW;}
-return energyConsumedInJ;},getSamplesWithinRange:function(start,end){var startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start);var endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);},shiftTimestampsForward:function(amount){for(var i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}},updateBounds:function(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},childEvents:function*(){yield*this.samples_;},};return{PowerSeries,};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model){throw new Error('Must provide a model.');}
+return stats;}};Cpu.compare=function(x,y){return x.cpuNumber-y.cpuNumber;};return{Cpu,};});'use strict';tr.exportTo('tr.model',function(){const Event=tr.model.Event;const EventRegistry=tr.model.EventRegistry;function PowerSample(series,start,powerInW){Event.call(this);this.series_=series;this.start_=parseFloat(start);this.powerInW_=parseFloat(powerInW);}
+PowerSample.prototype={__proto__:Event.prototype,get series(){return this.series_;},get start(){return this.start_;},set start(value){this.start_=value;},get powerInW(){return this.powerInW_;},set powerInW(value){this.powerInW_=value;},addBoundsToRange(range){range.addValue(this.start);}};EventRegistry.register(PowerSample,{name:'powerSample',pluralName:'powerSamples'});return{PowerSample,};});'use strict';tr.exportTo('tr.model',function(){const PowerSample=tr.model.PowerSample;function PowerSeries(device){tr.model.EventContainer.call(this);this.device_=device;this.samples_=[];}
+PowerSeries.prototype={__proto__:tr.model.EventContainer.prototype,get device(){return this.device_;},get samples(){return this.samples_;},get stableId(){return this.device_.stableId+'.PowerSeries';},addPowerSample(ts,val){const sample=new PowerSample(this,ts,val);this.samples_.push(sample);return sample;},getEnergyConsumedInJ(start,end){const measurementRange=tr.b.math.Range.fromExplicitRange(start,end);let energyConsumedInJ=0;let startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start)-1;const endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);if(startIndex<0){startIndex=0;}
+for(let i=startIndex;i<endIndex;i++){const sample=this.samples[i];const nextSample=this.samples[i+1];const sampleRange=new tr.b.math.Range();sampleRange.addValue(sample.start);sampleRange.addValue(nextSample?nextSample.start:sample.start);const intersectionRangeInMs=measurementRange.findIntersection(sampleRange);const durationInS=tr.b.convertUnit(intersectionRangeInMs.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);energyConsumedInJ+=durationInS*sample.powerInW;}
+return energyConsumedInJ;},getSamplesWithinRange(start,end){const startIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,start);const endIndex=tr.b.math.findLowIndexInSortedArray(this.samples,x=>x.start,end);return this.samples.slice(startIndex,endIndex);},shiftTimestampsForward(amount){for(let i=0;i<this.samples_.length;++i){this.samples_[i].start+=amount;}},updateBounds(){this.bounds.reset();if(this.samples_.length===0)return;this.bounds.addValue(this.samples_[0].start);this.bounds.addValue(this.samples_[this.samples_.length-1].start);},*childEvents(){yield*this.samples_;},};return{PowerSeries,};});'use strict';tr.exportTo('tr.model',function(){function Device(model){if(!model){throw new Error('Must provide a model.');}
 tr.model.EventContainer.call(this);this.powerSeries_=undefined;this.cpuUsageSeries_=undefined;this.vSyncTimestamps_=[];}
-Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo:function(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey:function(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get cpuUsageSeries(){return this.cpuUsageSeries_;},set cpuUsageSeries(cpuUsageSeries){this.cpuUsageSeries_=cpuUsageSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds:function(){this.bounds.reset();for(var child of this.childEventContainers()){child.updateBounds();this.bounds.addRange(child.bounds);}},shiftTimestampsForward:function(amount){for(var child of this.childEventContainers()){child.shiftTimestampsForward(amount);}
-for(var i=0;i<this.vSyncTimestamps_.length;i++){this.vSyncTimestamps_[i]+=amount;}},addCategoriesToDict:function(categoriesDict){},childEventContainers:function*(){if(this.powerSeries_){yield this.powerSeries_;}
+Device.compare=function(x,y){return x.guid-y.guid;};Device.prototype={__proto__:tr.model.EventContainer.prototype,compareTo(that){return Device.compare(this,that);},get userFriendlyName(){return'Device';},get userFriendlyDetails(){return'Device';},get stableId(){return'Device';},getSettingsKey(){return'device';},get powerSeries(){return this.powerSeries_;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;},get cpuUsageSeries(){return this.cpuUsageSeries_;},set cpuUsageSeries(cpuUsageSeries){this.cpuUsageSeries_=cpuUsageSeries;},get vSyncTimestamps(){return this.vSyncTimestamps_;},set vSyncTimestamps(value){this.vSyncTimestamps_=value;},updateBounds(){this.bounds.reset();for(const child of this.childEventContainers()){child.updateBounds();this.bounds.addRange(child.bounds);}},shiftTimestampsForward(amount){for(const child of this.childEventContainers()){child.shiftTimestampsForward(amount);}
+for(let i=0;i<this.vSyncTimestamps_.length;i++){this.vSyncTimestamps_[i]+=amount;}},addCategoriesToDict(categoriesDict){},*childEventContainers(){if(this.powerSeries_){yield this.powerSeries_;}
 if(this.cpuUsageSeries_){yield this.cpuUsageSeries_;}}};return{Device,};});'use strict';tr.exportTo('tr.model',function(){function FlowEvent(category,id,title,colorId,start,args,opt_duration){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.start=start;this.args=args;this.id=id;this.startSlice=undefined;this.endSlice=undefined;this.startStackFrame=undefined;this.endStackFrame=undefined;if(opt_duration!==undefined){this.duration=opt_duration;}}
 FlowEvent.prototype={__proto__:tr.model.TimedEvent.prototype,get userFriendlyName(){return'Flow event named '+this.title+' at '+
 tr.b.Unit.byName.timeStampInMs.format(this.timestamp);}};tr.model.EventRegistry.register(FlowEvent,{name:'flowEvent',pluralName:'flowEvents'});return{FlowEvent,};});'use strict';tr.exportTo('tr.model',function(){function ContainerMemoryDump(start){tr.model.TimedEvent.call(this,start);this.levelOfDetail=undefined;this.memoryAllocatorDumps_=undefined;this.memoryAllocatorDumpsByFullName_=undefined;}
-ContainerMemoryDump.LevelOfDetail={BACKGROUND:0,LIGHT:1,DETAILED:2};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName:function(fullName){if(this.memoryAllocatorDumps_===undefined)return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){var index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});}
+ContainerMemoryDump.LevelOfDetail={BACKGROUND:0,LIGHT:1,DETAILED:2};ContainerMemoryDump.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward(amount){this.start+=amount;},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();},getMemoryAllocatorDumpByFullName(fullName){if(this.memoryAllocatorDumps_===undefined)return undefined;if(this.memoryAllocatorDumpsByFullName_===undefined){const index={};function addDumpsToIndex(dumps){dumps.forEach(function(dump){index[dump.fullName]=dump;addDumpsToIndex(dump.children);});}
 addDumpsToIndex(this.memoryAllocatorDumps_);this.memoryAllocatorDumpsByFullName_=index;}
-return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex:function(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps:function(fn,opt_this){if(this.memoryAllocatorDumps===undefined)return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;}
+return this.memoryAllocatorDumpsByFullName_[fullName];},forceRebuildingMemoryAllocatorDumpByFullNameIndex(){this.memoryAllocatorDumpsByFullName_=undefined;},iterateRootAllocatorDumps(fn,opt_this){if(this.memoryAllocatorDumps===undefined)return;this.memoryAllocatorDumps.forEach(fn,opt_this||this);}};return{ContainerMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){function MemoryAllocatorDump(containerMemoryDump,fullName,opt_guid){this.fullName=fullName;this.parent=undefined;this.children=[];this.numerics={};this.diagnostics={};this.containerMemoryDump=containerMemoryDump;this.owns=undefined;this.ownedBy=[];this.ownedBySiblingSizes=new Map();this.retains=[];this.retainedBy=[];this.weak=false;this.infos=[];this.guid=opt_guid;}
 MemoryAllocatorDump.SIZE_NUMERIC_NAME='size';MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME='effective_size';MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME='resident_size';MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME=MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;MemoryAllocatorDump.prototype={get name(){return this.fullName.substring(this.fullName.lastIndexOf('/')+1);},get quantifiedName(){return'\''+this.fullName+'\' in '+
-this.containerMemoryDump.containerName;},getDescendantDumpByFullName:function(fullName){return this.containerMemoryDump.getMemoryAllocatorDumpByFullName(this.fullName+'/'+fullName);},isDescendantOf:function(otherDump){if(this===otherDump)return true;if(this.parent===undefined)return false;return this.parent.isDescendantOf(otherDump);},addNumeric:function(name,numeric){if(!(numeric instanceof tr.b.Scalar)){throw new Error('Numeric value must be an instance of Scalar.');}
+this.containerMemoryDump.containerName;},getDescendantDumpByFullName(fullName){return this.containerMemoryDump.getMemoryAllocatorDumpByFullName(this.fullName+'/'+fullName);},isDescendantOf(otherDump){if(this===otherDump)return true;if(this.parent===undefined)return false;return this.parent.isDescendantOf(otherDump);},addNumeric(name,numeric){if(!(numeric instanceof tr.b.Scalar)){throw new Error('Numeric value must be an instance of Scalar.');}
 if(name in this.numerics){throw new Error('Duplicate numeric name: '+name+'.');}
-this.numerics[name]=numeric;},addDiagnostic:function(name,text){if(typeof text!=='string'){throw new Error('Diagnostic text must be a string.');}
+this.numerics[name]=numeric;},addDiagnostic(name,text){if(typeof text!=='string'){throw new Error('Diagnostic text must be a string.');}
 if(name in this.diagnostics){throw new Error('Duplicate diagnostic name: '+name+'.');}
-this.diagnostics[name]=text;},aggregateNumericsRecursively:function(opt_model){var numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);for(var[item,value]of Object.entries(child.numerics)){numericNames.add(item,value);}},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
-this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){var shouldLogWarning=!!opt_model;var aggregatedUnit=undefined;var aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)return;var unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
+this.diagnostics[name]=text;},aggregateNumericsRecursively(opt_model){const numericNames=new Set();this.children.forEach(function(child){child.aggregateNumericsRecursively(opt_model);for(const[item,value]of Object.entries(child.numerics)){numericNames.add(item,value);}},this);numericNames.forEach(function(numericName){if(numericName===MemoryAllocatorDump.SIZE_NUMERIC_NAME||numericName===MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME||this.numerics[numericName]!==undefined){return;}
+this.numerics[numericName]=MemoryAllocatorDump.aggregateNumerics(this.children.map(function(child){return child.numerics[numericName];}),opt_model);},this);}};MemoryAllocatorDump.aggregateNumerics=function(numerics,opt_model){let shouldLogWarning=!!opt_model;let aggregatedUnit=undefined;let aggregatedValue=0;numerics.forEach(function(numeric){if(numeric===undefined)return;const unit=numeric.unit;if(aggregatedUnit===undefined){aggregatedUnit=unit;}else if(aggregatedUnit!==unit){if(shouldLogWarning){opt_model.importWarning({type:'numeric_parse_error',message:'Multiple units provided for numeric: \''+
 aggregatedUnit.unitName+'\' and \''+unit.unitName+'\'.'});shouldLogWarning=false;}
 aggregatedUnit=tr.b.Unit.byName.unitlessNumber_smallerIsBetter;}
 aggregatedValue+=numeric.value;},this);if(aggregatedUnit===undefined)return undefined;return new tr.b.Scalar(aggregatedUnit,aggregatedValue);};function MemoryAllocatorDumpLink(source,target,opt_importance){this.source=source;this.target=target;this.importance=opt_importance;this.size=undefined;}
-var MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump,MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType,};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
-var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function inPlaceFilter(array,predicate,opt_this){opt_this=opt_this||this;var nextPosition=0;for(var i=0;i<array.length;i++){if(!predicate.call(opt_this,array[i],i))continue;if(nextPosition<i){array[nextPosition]=array[i];}
-nextPosition++;}
-if(nextPosition<array.length){array.length=nextPosition;}}
-function getSize(dump){var numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;return numeric.value;}
+const MemoryAllocatorDumpInfoType={PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:0,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:1};return{MemoryAllocatorDump,MemoryAllocatorDumpLink,MemoryAllocatorDumpInfoType,};});'use strict';tr.exportTo('tr.model',function(){function GlobalMemoryDump(model,start){tr.model.ContainerMemoryDump.call(this,start);this.model=model;this.processMemoryDumps={};}
+const SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;const EFFECTIVE_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME;const MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;const PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;const PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;function getSize(dump){const numeric=dump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;return numeric.value;}
 function hasSize(dump){return dump.numerics[SIZE_NUMERIC_NAME]!==undefined;}
 function optional(value,defaultValue){if(value===undefined)return defaultValue;return value;}
 GlobalMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Global memory dump at '+
-tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph:function(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps:function(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
-removeWeakDumpsFromListRecursively(dump.children);inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
-this.iterateContainerDumps(function(containerDump){var memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined){removeWeakDumpsFromListRecursively(memoryAllocatorDumps);}});},calculateSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_:function(dump){var shouldDefineSize=false;function getDependencySize(dependencyDump){var numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;shouldDefineSize=true;return numeric.value;}
-var sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];var size=0;var checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.b.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return'global space';},finalizeGraph(){this.removeWeakDumps();this.setUpTracingOverheadOwnership();this.aggregateNumerics();this.calculateSizes();this.calculateEffectiveSizes();this.discountTracingOverheadFromVmRegions();this.forceRebuildingMemoryAllocatorDumpByFullNameIndices();},removeWeakDumps(){this.traverseAllocatorDumpsInDepthFirstPreOrder(function(dump){if(dump.weak)return;if((dump.owns!==undefined&&dump.owns.target.weak)||(dump.parent!==undefined&&dump.parent.weak)){dump.weak=true;}});function removeWeakDumpsFromListRecursively(dumps){tr.b.inPlaceFilter(dumps,function(dump){if(dump.weak){return false;}
+removeWeakDumpsFromListRecursively(dump.children);tr.b.inPlaceFilter(dump.ownedBy,function(ownershipLink){return!ownershipLink.source.weak;});return true;});}
+this.iterateContainerDumps(function(containerDump){const memoryAllocatorDumps=containerDump.memoryAllocatorDumps;if(memoryAllocatorDumps!==undefined){removeWeakDumpsFromListRecursively(memoryAllocatorDumps);}});},calculateSizes(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateMemoryAllocatorDumpSize_.bind(this));},calculateMemoryAllocatorDumpSize_(dump){let shouldDefineSize=false;function getDependencySize(dependencyDump){const numeric=dependencyDump.numerics[SIZE_NUMERIC_NAME];if(numeric===undefined)return 0;shouldDefineSize=true;return numeric.value;}
+const sizeNumeric=dump.numerics[SIZE_NUMERIC_NAME];let size=0;let checkDependencySizeIsConsistent=function(){};if(sizeNumeric!==undefined){size=sizeNumeric.value;shouldDefineSize=true;if(sizeNumeric.unit!==tr.b.Unit.byName.sizeInBytes_smallerIsBetter){this.model.importWarning({type:'memory_dump_parse_error',message:'Invalid unit of \'size\' numeric of memory allocator '+'dump '+dump.quantifiedName+': '+
 sizeNumeric.unit.unitName+'.'});}
 checkDependencySizeIsConsistent=function(dependencySize,dependencyInfoType,dependencyName){if(size>=dependencySize)return;this.model.importWarning({type:'memory_dump_parse_error',message:'Size provided by memory allocator dump \''+
 dump.fullName+'\''+
 tr.b.Unit.byName.sizeInBytes.format(size)+') is less than '+dependencyName+' ('+
-tr.b.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize:dependencySize});}.bind(this);}
-var aggregatedChildrenSize=0;var allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){var ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){var ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump){ownedChildDump=ownedChildDump.parent;}
-if(childDump!==ownedChildDump){var ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){var previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;var updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
+tr.b.Unit.byName.sizeInBytes.format(dependencySize)+').'});dump.infos.push({type:dependencyInfoType,providedSize:size,dependencySize});}.bind(this);}
+let aggregatedChildrenSize=0;const allOverlaps={};dump.children.forEach(function(childDump){function aggregateDescendantDump(descendantDump){const ownedDumpLink=descendantDump.owns;if(ownedDumpLink!==undefined&&ownedDumpLink.target.isDescendantOf(dump)){let ownedChildDump=ownedDumpLink.target;while(ownedChildDump.parent!==dump){ownedChildDump=ownedChildDump.parent;}
+if(childDump!==ownedChildDump){const ownedBySiblingSize=getDependencySize(descendantDump);if(ownedBySiblingSize>0){const previousTotalOwnedBySiblingSize=ownedChildDump.ownedBySiblingSizes.get(childDump)||0;const updatedTotalOwnedBySiblingSize=previousTotalOwnedBySiblingSize+ownedBySiblingSize;ownedChildDump.ownedBySiblingSizes.set(childDump,updatedTotalOwnedBySiblingSize);}}
 return;}
 if(descendantDump.children.length===0){aggregatedChildrenSize+=getDependencySize(descendantDump);return;}
 descendantDump.children.forEach(aggregateDescendantDump);}
-aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');var largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){var owner=ownershipLink.source;var ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
-size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){var virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes:function(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_:function(dump){if(!hasSize(dump))return;if(dump.children===undefined||dump.children.length===0){var size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
-var notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;var notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
-var largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_:function(dump){if(!hasSize(dump))return;if(dump.ownedBy.length===0)return;var owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance){return a.notOwningSubSize-b.notOwningSubSize;}
-return b.importance-a.importance;});var currentImportanceStartPos=0;var alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){var currentImportance=owners[currentImportanceStartPos].importance;var nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
-var attributedNotOwningSubSize=0;for(var pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){var owner=owners[pos];var notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
-var owningCoefficient=0;if(notOwningSubSize!==0){owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;}
+aggregateDescendantDump(childDump);});checkDependencySizeIsConsistent(aggregatedChildrenSize,PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN,'the aggregated size of its children');let largestOwnerSize=0;dump.ownedBy.forEach(function(ownershipLink){const owner=ownershipLink.source;const ownerSize=getDependencySize(owner);largestOwnerSize=Math.max(largestOwnerSize,ownerSize);});checkDependencySizeIsConsistent(largestOwnerSize,PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER,'the size of its largest owner');if(!shouldDefineSize){delete dump.numerics[SIZE_NUMERIC_NAME];return;}
+size=Math.max(size,aggregatedChildrenSize,largestOwnerSize);dump.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size);if(aggregatedChildrenSize<size&&dump.children!==undefined&&dump.children.length>0){const virtualChild=new tr.model.MemoryAllocatorDump(dump.containerMemoryDump,dump.fullName+'/<unspecified>');virtualChild.parent=dump;dump.children.unshift(virtualChild);virtualChild.numerics[SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,size-aggregatedChildrenSize);}},calculateEffectiveSizes(){this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpSubSizes_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPreOrder(this.calculateDumpCumulativeOwnershipCoefficient_.bind(this));this.traverseAllocatorDumpsInDepthFirstPostOrder(this.calculateDumpEffectiveSize_.bind(this));},calculateDumpSubSizes_(dump){if(!hasSize(dump))return;if(dump.children===undefined||dump.children.length===0){const size=getSize(dump);dump.notOwningSubSize_=size;dump.notOwnedSubSize_=size;return;}
+let notOwningSubSize=0;dump.children.forEach(function(childDump){if(childDump.owns!==undefined)return;notOwningSubSize+=optional(childDump.notOwningSubSize_,0);});dump.notOwningSubSize_=notOwningSubSize;let notOwnedSubSize=0;dump.children.forEach(function(childDump){if(childDump.ownedBy.length===0){notOwnedSubSize+=optional(childDump.notOwnedSubSize_,0);return;}
+let largestChildOwnerSize=0;childDump.ownedBy.forEach(function(ownershipLink){largestChildOwnerSize=Math.max(largestChildOwnerSize,getSize(ownershipLink.source));});notOwnedSubSize+=getSize(childDump)-largestChildOwnerSize;});dump.notOwnedSubSize_=notOwnedSubSize;},calculateDumpOwnershipCoefficient_(dump){if(!hasSize(dump))return;if(dump.ownedBy.length===0)return;const owners=dump.ownedBy.map(function(ownershipLink){return{dump:ownershipLink.source,importance:optional(ownershipLink.importance,0),notOwningSubSize:optional(ownershipLink.source.notOwningSubSize_,0)};});owners.sort(function(a,b){if(a.importance===b.importance){return a.notOwningSubSize-b.notOwningSubSize;}
+return b.importance-a.importance;});let currentImportanceStartPos=0;let alreadyAttributedSubSize=0;while(currentImportanceStartPos<owners.length){const currentImportance=owners[currentImportanceStartPos].importance;let nextImportanceStartPos=currentImportanceStartPos+1;while(nextImportanceStartPos<owners.length&&owners[nextImportanceStartPos].importance===currentImportance){nextImportanceStartPos++;}
+let attributedNotOwningSubSize=0;for(let pos=currentImportanceStartPos;pos<nextImportanceStartPos;pos++){const owner=owners[pos];const notOwningSubSize=owner.notOwningSubSize;if(notOwningSubSize>alreadyAttributedSubSize){attributedNotOwningSubSize+=(notOwningSubSize-alreadyAttributedSubSize)/(nextImportanceStartPos-pos);alreadyAttributedSubSize=notOwningSubSize;}
+let owningCoefficient=0;if(notOwningSubSize!==0){owningCoefficient=attributedNotOwningSubSize/notOwningSubSize;}
 owner.dump.owningCoefficient_=owningCoefficient;}
 currentImportanceStartPos=nextImportanceStartPos;}
-var notOwnedSubSize=optional(dump.notOwnedSubSize_,0);var remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;var ownedCoefficient=0;if(notOwnedSubSize!==0){ownedCoefficient=remainderSubSize/notOwnedSubSize;}
-dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_:function(dump){if(!hasSize(dump))return;var cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);var parent=dump.parent;if(dump.parent!==undefined){cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;}
-dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;var cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
-dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_:function(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
-var effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
-dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics:function(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);for(var processMemoryDump of Object.values(this.processMemoryDumps)){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);}},propagateNumericsAndDiagnosticsRecursively:function(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){for(var[name,value]of Object.entries(globalAllocatorDump[field])){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){var processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
-processAllocatorDump[field][name]=value;});}});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership:function(){for(var dump of Object.values(this.processMemoryDumps)){dump.setUpTracingOverheadOwnership(this.model);}},discountTracingOverheadFromVmRegions:function(){for(var dump of Object.values(this.processMemoryDumps)){dump.discountTracingOverheadFromVmRegions(this.model);}},forceRebuildingMemoryAllocatorDumpByFullNameIndices:function(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps:function(fn){fn.call(this,this);for(var processDump of Object.values(this.processMemoryDumps)){fn.call(this,processDump);}},iterateAllRootAllocatorDumps:function(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder:function(fn){var visitedDumps=new WeakSet();var openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(openDumps.has(dump)){throw new Error(dump.userFriendlyName+' contains a cycle');}
+const notOwnedSubSize=optional(dump.notOwnedSubSize_,0);const remainderSubSize=notOwnedSubSize-alreadyAttributedSubSize;let ownedCoefficient=0;if(notOwnedSubSize!==0){ownedCoefficient=remainderSubSize/notOwnedSubSize;}
+dump.ownedCoefficient_=ownedCoefficient;},calculateDumpCumulativeOwnershipCoefficient_(dump){if(!hasSize(dump))return;let cumulativeOwnedCoefficient=optional(dump.ownedCoefficient_,1);const parent=dump.parent;if(dump.parent!==undefined){cumulativeOwnedCoefficient*=dump.parent.cumulativeOwnedCoefficient_;}
+dump.cumulativeOwnedCoefficient_=cumulativeOwnedCoefficient;let cumulativeOwningCoefficient;if(dump.owns!==undefined){cumulativeOwningCoefficient=dump.owningCoefficient_*dump.owns.target.cumulativeOwningCoefficient_;}else if(dump.parent!==undefined){cumulativeOwningCoefficient=dump.parent.cumulativeOwningCoefficient_;}else{cumulativeOwningCoefficient=1;}
+dump.cumulativeOwningCoefficient_=cumulativeOwningCoefficient;},calculateDumpEffectiveSize_(dump){if(!hasSize(dump)){delete dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME];return;}
+let effectiveSize;if(dump.children===undefined||dump.children.length===0){effectiveSize=getSize(dump)*dump.cumulativeOwningCoefficient_*dump.cumulativeOwnedCoefficient_;}else{effectiveSize=0;dump.children.forEach(function(childDump){if(!hasSize(childDump))return;effectiveSize+=childDump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME].value;});}
+dump.numerics[EFFECTIVE_SIZE_NUMERIC_NAME]=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes_smallerIsBetter,effectiveSize);},aggregateNumerics(){this.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);});this.iterateRootAllocatorDumps(this.propagateNumericsAndDiagnosticsRecursively);for(const processMemoryDump of Object.values(this.processMemoryDumps)){processMemoryDump.iterateRootAllocatorDumps(function(dump){dump.aggregateNumericsRecursively(this.model);},this);}},propagateNumericsAndDiagnosticsRecursively(globalAllocatorDump){['numerics','diagnostics'].forEach(function(field){for(const[name,value]of
+Object.entries(globalAllocatorDump[field])){globalAllocatorDump.ownedBy.forEach(function(ownershipLink){const processAllocatorDump=ownershipLink.source;if(processAllocatorDump[field][name]!==undefined){return;}
+processAllocatorDump[field][name]=value;});}});globalAllocatorDump.children.forEach(this.propagateNumericsAndDiagnosticsRecursively,this);},setUpTracingOverheadOwnership(){for(const dump of Object.values(this.processMemoryDumps)){dump.setUpTracingOverheadOwnership(this.model);}},discountTracingOverheadFromVmRegions(){for(const dump of Object.values(this.processMemoryDumps)){dump.discountTracingOverheadFromVmRegions(this.model);}},forceRebuildingMemoryAllocatorDumpByFullNameIndices(){this.iterateContainerDumps(function(containerDump){containerDump.forceRebuildingMemoryAllocatorDumpByFullNameIndex();});},iterateContainerDumps(fn){fn.call(this,this);for(const processDump of Object.values(this.processMemoryDumps)){fn.call(this,processDump);}},iterateAllRootAllocatorDumps(fn){this.iterateContainerDumps(function(containerDump){containerDump.iterateRootAllocatorDumps(fn,this);});},traverseAllocatorDumpsInDepthFirstPostOrder(fn){const visitedDumps=new WeakSet();const openDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(openDumps.has(dump)){throw new Error(dump.userFriendlyName+' contains a cycle');}
 openDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);fn.call(this,dump);visitedDumps.add(dump);openDumps.delete(dump);}
-this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder:function(fn){var visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target)){return;}
+this.iterateAllRootAllocatorDumps(visit);},traverseAllocatorDumpsInDepthFirstPreOrder(fn){const visitedDumps=new WeakSet();function visit(dump){if(visitedDumps.has(dump))return;if(dump.owns!==undefined&&!visitedDumps.has(dump.owns.target)){return;}
 if(dump.parent!==undefined&&!visitedDumps.has(dump.parent)){return;}
 fn.call(this,dump);visitedDumps.add(dump);dump.ownedBy.forEach(function(ownershipLink){visit.call(this,ownershipLink.source);},this);dump.children.forEach(visit,this);}
-this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps'});return{GlobalMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){var InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.type=undefined;}
+this.iterateAllRootAllocatorDumps(visit);}};tr.model.EventRegistry.register(GlobalMemoryDump,{name:'globalMemoryDump',pluralName:'globalMemoryDumps'});return{GlobalMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){const InstantEventType={GLOBAL:1,PROCESS:2};function InstantEvent(category,title,colorId,start,args){tr.model.TimedEvent.call(this,start);this.category=category||'';this.title=title;this.colorId=colorId;this.args=args;this.type=undefined;}
 InstantEvent.prototype={__proto__:tr.model.TimedEvent.prototype};function GlobalInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.GLOBAL;}
 GlobalInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Global instant event '+this.title+' @ '+
 tr.b.Unit.byName.timeStampInMs.format(start);}};function ProcessInstantEvent(category,title,colorId,start,args){InstantEvent.apply(this,arguments);this.type=InstantEventType.PROCESS;}
 ProcessInstantEvent.prototype={__proto__:InstantEvent.prototype,get userFriendlyName(){return'Process-level instant event '+this.title+' @ '+
-tr.b.Unit.byName.timeStampInMs.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents'});return{GlobalInstantEvent,ProcessInstantEvent,InstantEventType,InstantEvent,};});'use strict';tr.exportTo('tr.model',function(){var Cpu=tr.model.Cpu;var ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;}
-Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo:function(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu:function(cpuNumber){if(!this.cpus[cpuNumber]){this.cpus[cpuNumber]=new Cpu(this,cpuNumber);}
+tr.b.Unit.byName.timeStampInMs.format(start);}};tr.model.EventRegistry.register(InstantEvent,{name:'instantEvent',pluralName:'instantEvents'});return{GlobalInstantEvent,ProcessInstantEvent,InstantEventType,InstantEvent,};});'use strict';tr.exportTo('tr.model',function(){const Cpu=tr.model.Cpu;const ProcessBase=tr.model.ProcessBase;function Kernel(model){ProcessBase.call(this,model);this.cpus={};this.softwareMeasuredCpuCount_=undefined;}
+Kernel.compare=function(x,y){return 0;};Kernel.prototype={__proto__:ProcessBase.prototype,compareTo(that){return Kernel.compare(this,that);},get userFriendlyName(){return'Kernel';},get userFriendlyDetails(){return'Kernel';},get stableId(){return'Kernel';},getOrCreateCpu(cpuNumber){if(!this.cpus[cpuNumber]){this.cpus[cpuNumber]=new Cpu(this,cpuNumber);}
 return this.cpus[cpuNumber];},get softwareMeasuredCpuCount(){return this.softwareMeasuredCpuCount_;},set softwareMeasuredCpuCount(softwareMeasuredCpuCount){if(this.softwareMeasuredCpuCount_!==undefined&&this.softwareMeasuredCpuCount_!==softwareMeasuredCpuCount){throw new Error('Cannot change the softwareMeasuredCpuCount once it is set');}
-this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){var realCpuCount=tr.b.dictionaryLength(this.cpus);if(realCpuCount!==0){return realCpuCount;}
-return this.softwareMeasuredCpuCount;},updateBounds:function(){ProcessBase.prototype.updateBounds.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices:function(){ProcessBase.prototype.createSubSlices.call(this);for(var cpuNumber in this.cpus){var cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict:function(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(var cpuNumber in this.cpus){this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);}},getSettingsKey:function(){return'kernel';},childEventContainers:function*(){yield*ProcessBase.prototype.childEventContainers.call(this);yield*tr.b.dictionaryValues(this.cpus);},};return{Kernel,};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=[];}
+this.softwareMeasuredCpuCount_=softwareMeasuredCpuCount;},get bestGuessAtCpuCount(){const realCpuCount=Object.keys(this.cpus).length;if(realCpuCount!==0){return realCpuCount;}
+return this.softwareMeasuredCpuCount;},updateBounds(){ProcessBase.prototype.updateBounds.call(this);for(const cpuNumber in this.cpus){const cpu=this.cpus[cpuNumber];cpu.updateBounds();this.bounds.addRange(cpu.bounds);}},createSubSlices(){ProcessBase.prototype.createSubSlices.call(this);for(const cpuNumber in this.cpus){const cpu=this.cpus[cpuNumber];cpu.createSubSlices();}},addCategoriesToDict(categoriesDict){ProcessBase.prototype.addCategoriesToDict.call(this,categoriesDict);for(const cpuNumber in this.cpus){this.cpus[cpuNumber].addCategoriesToDict(categoriesDict);}},getSettingsKey(){return'kernel';},*childEventContainers(){yield*ProcessBase.prototype.childEventContainers.call(this);yield*Object.values(this.cpus);},};return{Kernel,};});'use strict';tr.exportTo('tr.model',function(){function ModelIndices(model){this.flowEventsById_={};model.flowEvents.forEach(function(fe){if(fe.id!==undefined){if(!this.flowEventsById_.hasOwnProperty(fe.id)){this.flowEventsById_[fe.id]=[];}
 this.flowEventsById_[fe.id].push(fe);}},this);}
-ModelIndices.prototype={addEventWithId:function(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=[];}
-this.flowEventsById_[id].push(event);},getFlowEventsWithId:function(id){if(!this.flowEventsById_.hasOwnProperty(id)){return[];}
+ModelIndices.prototype={addEventWithId(id,event){if(!this.flowEventsById_.hasOwnProperty(id)){this.flowEventsById_[id]=[];}
+this.flowEventsById_[id].push(event);},getFlowEventsWithId(id){if(!this.flowEventsById_.hasOwnProperty(id)){return[];}
 return this.flowEventsById_[id];}};return{ModelIndices,};});'use strict';tr.exportTo('tr.model',function(){function ModelStats(){this.traceEventCountsByKey_=new Map();this.allTraceEventStats_=[];this.traceEventStatsInTimeIntervals_=new Map();this.allTraceEventStatsInTimeIntervals_=[];this.hasEventSizesinBytes_=false;this.traceImportDurationMs_=undefined;}
-ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent:function(phase,category,title,ts,opt_eventSizeinBytes){var key=phase+'/'+category+'/'+title;var eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase:phase,category:category,title:title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
-eventStats.numEvents++;var timeIntervalKey=Math.floor(tr.b.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);var eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
+ModelStats.prototype={TIME_INTERVAL_SIZE_IN_MS:100,willProcessBasicTraceEvent(phase,category,title,ts,opt_eventSizeinBytes){const key=phase+'/'+category+'/'+title;let eventStats=this.traceEventCountsByKey_.get(key);if(eventStats===undefined){eventStats={phase,category,title,numEvents:0,totalEventSizeinBytes:0};this.traceEventCountsByKey_.set(key,eventStats);this.allTraceEventStats_.push(eventStats);}
+eventStats.numEvents++;const timeIntervalKey=Math.floor(tr.b.Unit.timestampFromUs(ts)/this.TIME_INTERVAL_SIZE_IN_MS);let eventStatsByTimeInverval=this.traceEventStatsInTimeIntervals_.get(timeIntervalKey);if(eventStatsByTimeInverval===undefined){eventStatsByTimeInverval={timeInterval:timeIntervalKey,numEvents:0,totalEventSizeinBytes:0};this.traceEventStatsInTimeIntervals_.set(timeIntervalKey,eventStatsByTimeInverval);this.allTraceEventStatsInTimeIntervals_.push(eventStatsByTimeInverval);}
 eventStatsByTimeInverval.numEvents++;if(opt_eventSizeinBytes!==undefined){this.hasEventSizesinBytes_=true;eventStats.totalEventSizeinBytes+=opt_eventSizeinBytes;eventStatsByTimeInverval.totalEventSizeinBytes+=opt_eventSizeinBytes;}},get allTraceEventStats(){return this.allTraceEventStats_;},get allTraceEventStatsInTimeIntervals(){return this.allTraceEventStatsInTimeIntervals_;},get hasEventSizesinBytes(){return this.hasEventSizesinBytes_;},get traceImportDurationMs(){return this.traceImportDurationMs_;},set traceImportDurationMs(traceImportDurationMs){this.traceImportDurationMs_=traceImportDurationMs;}};return{ModelStats,};});'use strict';tr.exportTo('tr.model',function(){function VMRegion(startAddress,sizeInBytes,protectionFlags,mappedFile,byteStats){this.startAddress=startAddress;this.sizeInBytes=sizeInBytes;this.protectionFlags=protectionFlags;this.mappedFile=mappedFile||'';this.byteStats=byteStats||{};}
 VMRegion.PROTECTION_FLAG_READ=4;VMRegion.PROTECTION_FLAG_WRITE=2;VMRegion.PROTECTION_FLAG_EXECUTE=1;VMRegion.PROTECTION_FLAG_MAYSHARE=128;VMRegion.prototype={get uniqueIdWithinProcess(){return this.mappedFile+'#'+this.startAddress;},get protectionFlagsToString(){if(this.protectionFlags===undefined)return undefined;return((this.protectionFlags&VMRegion.PROTECTION_FLAG_READ?'r':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_WRITE?'w':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_EXECUTE?'x':'-')+
 (this.protectionFlags&VMRegion.PROTECTION_FLAG_MAYSHARE?'s':'p'));}};VMRegion.fromDict=function(dict){return new VMRegion(dict.startAddress,dict.sizeInBytes,dict.protectionFlags,dict.mappedFile,dict.byteStats);};function VMRegionClassificationNode(opt_rule){this.rule_=opt_rule||VMRegionClassificationNode.CLASSIFICATION_RULES;this.hasRegions=false;this.sizeInBytes=undefined;this.byteStats={};this.children_=undefined;this.regions_=[];}
-VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){var tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(var i=0;i<regions.length;i++){tree.addStatsFromRegion_(regions[i]);}
+VMRegionClassificationNode.CLASSIFICATION_RULES={name:'Total',children:[{name:'Android',file:/^\/dev\/ashmem(?!\/libc malloc)/,children:[{name:'Java runtime',file:/^\/dev\/ashmem\/dalvik-/,children:[{name:'Spaces',file:/\/dalvik-(alloc|main|large object|non moving|zygote) space/,children:[{name:'Normal',file:/\/dalvik-(alloc|main)/},{name:'Large',file:/\/dalvik-large object/},{name:'Zygote',file:/\/dalvik-zygote/},{name:'Non-moving',file:/\/dalvik-non moving/}]},{name:'Linear Alloc',file:/\/dalvik-LinearAlloc/},{name:'Indirect Reference Table',file:/\/dalvik-indirect.ref/},{name:'Cache',file:/\/dalvik-jit-code-cache/},{name:'Accounting'}]},{name:'Cursor',file:/\/CursorWindow/},{name:'Ashmem'}]},{name:'Native heap',file:/^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|(\[discounted tracing overhead\])|$)/},{name:'Stack',file:/^\[stack/},{name:'Files',file:/\.((((jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex)|(so))/,children:[{name:'so',file:/\.so/},{name:'jar',file:/\.jar$/},{name:'apk',file:/\.apk$/},{name:'ttf',file:/\.ttf$/},{name:'dex',file:/\.((dex)|(odex$))/},{name:'oat',file:/\.oat$/},{name:'art',file:/\.art$/}]},{name:'Devices',file:/(^\/dev\/)|(anon_inode:dmabuf)/,children:[{name:'GPU',file:/\/((nv)|(mali)|(kgsl))/},{name:'DMA',file:/anon_inode:dmabuf/}]}]};VMRegionClassificationNode.OTHER_RULE={name:'Other'};VMRegionClassificationNode.fromRegions=function(regions,opt_rules){const tree=new VMRegionClassificationNode(opt_rules);tree.regions_=regions;for(let i=0;i<regions.length;i++){tree.addStatsFromRegion_(regions[i]);}
 return tree;};VMRegionClassificationNode.prototype={get title(){return this.rule_.name;},get children(){if(this.isLeafNode){return undefined;}
 if(this.children_===undefined){this.buildTree_();}
 return this.children_;},get regions(){if(!this.isLeafNode){return undefined;}
 return this.regions_;},get allRegionsForTesting(){if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
 return this.regions_;}
-var regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){var children=this.rule_.children;return children===undefined||children.length===0;},addRegion:function(region){this.addRegionRecursively_(region,true);},someRegion:function(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
-return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_:function(region,addStatsToThisNode){if(addStatsToThisNode){this.addStatsFromRegion_(region);}
+let regions=[];this.children_.forEach(function(childNode){regions=regions.concat(childNode.allRegionsForTesting);});return regions;},get isLeafNode(){const children=this.rule_.children;return children===undefined||children.length===0;},addRegion(region){this.addRegionRecursively_(region,true);},someRegion(fn,opt_this){if(this.regions_!==undefined){return this.regions_.some(fn,opt_this);}
+return this.children_.some(function(childNode){return childNode.someRegion(fn,opt_this);});},addRegionRecursively_(region,addStatsToThisNode){if(addStatsToThisNode){this.addStatsFromRegion_(region);}
 if(this.regions_!==undefined){if(this.children_!==undefined){throw new Error('Internal error: a VM region classification node '+'cannot have both regions and children');}
 this.regions_.push(region);return;}
-function regionRowMatchesChildNide(child){var fileRegExp=child.rule_.file;if(fileRegExp===undefined)return true;return fileRegExp.test(region.mappedFile);}
-var matchedChild=tr.b.findFirstInArray(this.children_,regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length){throw new Error('Internal error');}
+function regionRowMatchesChildNide(child){const fileRegExp=child.rule_.file;if(fileRegExp===undefined)return true;return fileRegExp.test(region.mappedFile);}
+let matchedChild=tr.b.findFirstInArray(this.children_,regionRowMatchesChildNide);if(matchedChild===undefined){if(this.children_.length!==this.rule_.children.length){throw new Error('Internal error');}
 matchedChild=new VMRegionClassificationNode(VMRegionClassificationNode.OTHER_RULE);this.children_.push(matchedChild);}
-matchedChild.addRegionRecursively_(region,true);},buildTree_:function(){var cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(var i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_:function(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
+matchedChild.addRegionRecursively_(region,true);},buildTree_(){const cachedRegions=this.regions_;this.regions_=undefined;this.buildChildNodesRecursively_();for(let i=0;i<cachedRegions.length;i++){this.addRegionRecursively_(cachedRegions[i],false);}},buildChildNodesRecursively_(){if(this.children_!==undefined){throw new Error('Internal error: Classification node already has children');}
 if(this.regions_!==undefined&&this.regions_.length!==0){throw new Error('Internal error: Classification node should have no regions');}
 if(this.isLeafNode){return;}
-this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){var child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_:function(region){this.hasRegions=true;var regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined){this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;}
-var thisByteStats=this.byteStats;var regionByteStats=region.byteStats;for(var byteStatName in regionByteStats){var regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}}};return{VMRegion,VMRegionClassificationNode,};});'use strict';tr.exportTo('tr.model',function(){var DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];var TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];var SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;var RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){var sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)return 0;return sizeNumeric.value;}
+this.regions_=undefined;this.children_=this.rule_.children.map(function(childRule){const child=new VMRegionClassificationNode(childRule);child.buildChildNodesRecursively_();return child;});},addStatsFromRegion_(region){this.hasRegions=true;const regionSizeInBytes=region.sizeInBytes;if(regionSizeInBytes!==undefined){this.sizeInBytes=(this.sizeInBytes||0)+regionSizeInBytes;}
+const thisByteStats=this.byteStats;const regionByteStats=region.byteStats;for(const byteStatName in regionByteStats){const regionByteStatValue=regionByteStats[byteStatName];if(regionByteStatValue===undefined)continue;thisByteStats[byteStatName]=(thisByteStats[byteStatName]||0)+regionByteStatValue;}}};return{VMRegion,VMRegionClassificationNode,};});'use strict';tr.exportTo('tr.model',function(){const DISCOUNTED_ALLOCATOR_NAMES=['winheap','malloc'];const TRACING_OVERHEAD_PATH=['allocated_objects','tracing_overhead'];const SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME;const RESIDENT_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.RESIDENT_SIZE_NUMERIC_NAME;function getSizeNumericValue(dump,sizeNumericName){const sizeNumeric=dump.numerics[sizeNumericName];if(sizeNumeric===undefined)return 0;return sizeNumeric.value;}
 function ProcessMemoryDump(globalMemoryDump,process,start){tr.model.ContainerMemoryDump.call(this,start);this.process=process;this.globalMemoryDump=globalMemoryDump;this.totals=undefined;this.vmRegions=undefined;this.heapDumps=undefined;this.tracingOverheadOwnershipSetUp_=false;this.tracingOverheadDiscountedFromVmRegions_=false;}
 ProcessMemoryDump.prototype={__proto__:tr.model.ContainerMemoryDump.prototype,get userFriendlyName(){return'Process memory dump at '+
-tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){var dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership:function(opt_model){if(this.tracingOverheadOwnershipSetUp_)return;this.tracingOverheadOwnershipSetUp_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
-if(tracingDump.owns!==undefined)return;var hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){var allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined){return false;}
-var nextPathIndex=0;var currentDump=allocatorDump;var currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
-TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)break;currentDump=childDump;currentFullName=childFullName;}
-for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){var childFullName=currentFullName+'/'+
-TRACING_OVERHEAD_PATH[nextPathIndex];var childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
-var ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps){this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();}},discountTracingOverheadFromVmRegions:function(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)return;this.tracingOverheadDiscountedFromVmRegions_=true;var tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)return;var discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);var discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined){this.totals.residentBytes-=discountedResidentSize;}
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get containerName(){return this.process.userFriendlyName;},get processMemoryDumps(){const dumps={};dumps[this.process.pid]=this;return dumps;},get hasOwnVmRegions(){return this.vmRegions!==undefined;},setUpTracingOverheadOwnership(opt_model){if(this.tracingOverheadOwnershipSetUp_)return;this.tracingOverheadOwnershipSetUp_=true;const tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined||tracingDump.owns!==undefined){return;}
+if(tracingDump.owns!==undefined)return;const hasDiscountedFromAllocatorDumps=DISCOUNTED_ALLOCATOR_NAMES.some(function(allocatorName){const allocatorDump=this.getMemoryAllocatorDumpByFullName(allocatorName);if(allocatorDump===undefined){return false;}
+let nextPathIndex=0;let currentDump=allocatorDump;let currentFullName=allocatorName;for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){const childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];const childDump=this.getMemoryAllocatorDumpByFullName(childFullName);if(childDump===undefined)break;currentDump=childDump;currentFullName=childFullName;}
+for(;nextPathIndex<TRACING_OVERHEAD_PATH.length;nextPathIndex++){const childFullName=currentFullName+'/'+
+TRACING_OVERHEAD_PATH[nextPathIndex];const childDump=new tr.model.MemoryAllocatorDump(currentDump.containerMemoryDump,childFullName);childDump.parent=currentDump;currentDump.children.push(childDump);currentFullName=childFullName;currentDump=childDump;}
+const ownershipLink=new tr.model.MemoryAllocatorDumpLink(tracingDump,currentDump);tracingDump.owns=ownershipLink;currentDump.ownedBy.push(ownershipLink);return true;},this);if(hasDiscountedFromAllocatorDumps){this.forceRebuildingMemoryAllocatorDumpByFullNameIndex();}},discountTracingOverheadFromVmRegions(opt_model){if(this.tracingOverheadDiscountedFromVmRegions_)return;this.tracingOverheadDiscountedFromVmRegions_=true;const tracingDump=this.getMemoryAllocatorDumpByFullName('tracing');if(tracingDump===undefined)return;const discountedSize=getSizeNumericValue(tracingDump,SIZE_NUMERIC_NAME);const discountedResidentSize=getSizeNumericValue(tracingDump,RESIDENT_SIZE_NUMERIC_NAME);if(discountedSize<=0&&discountedResidentSize<=0)return;if(this.totals!==undefined){if(this.totals.residentBytes!==undefined){this.totals.residentBytes-=discountedResidentSize;}
 if(this.totals.peakResidentBytes!==undefined){this.totals.peakResidentBytes-=discountedResidentSize;}}
-if(this.vmRegions!==undefined){var hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;var hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;var hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){var byteStats={};if(hasPrivateDirtyResident){byteStats.privateDirtyResident=-discountedResidentSize;}
+if(this.vmRegions!==undefined){const hasSizeInBytes=this.vmRegions.sizeInBytes!==undefined;const hasPrivateDirtyResident=this.vmRegions.byteStats.privateDirtyResident!==undefined;const hasProportionalResident=this.vmRegions.byteStats.proportionalResident!==undefined;if((hasSizeInBytes&&discountedSize>0)||((hasPrivateDirtyResident||hasProportionalResident)&&discountedResidentSize>0)){const byteStats={};if(hasPrivateDirtyResident){byteStats.privateDirtyResident=-discountedResidentSize;}
 if(hasProportionalResident){byteStats.proportionalResident=-discountedResidentSize;}
-this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats:byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){var mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined){mostRecentVmRegions=processDump.vmRegions;}
-processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps'});return{ProcessMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){var ProcessBase=tr.model.ProcessBase;var ProcessInstantEvent=tr.model.ProcessInstantEvent;var Frame=tr.model.Frame;var ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined){throw new Error('model must be provided');}
+this.vmRegions.addRegion(tr.model.VMRegion.fromDict({mappedFile:'[discounted tracing overhead]',sizeInBytes:hasSizeInBytes?-discountedSize:undefined,byteStats}));}}}};ProcessMemoryDump.hookUpMostRecentVmRegionsLinks=function(processDumps){let mostRecentVmRegions=undefined;processDumps.forEach(function(processDump){if(processDump.vmRegions!==undefined){mostRecentVmRegions=processDump.vmRegions;}
+processDump.mostRecentVmRegions=mostRecentVmRegions;});};tr.model.EventRegistry.register(ProcessMemoryDump,{name:'processMemoryDump',pluralName:'processMemoryDumps'});return{ProcessMemoryDump,};});'use strict';tr.exportTo('tr.model',function(){const ProcessBase=tr.model.ProcessBase;const ProcessInstantEvent=tr.model.ProcessInstantEvent;const Frame=tr.model.Frame;const ProcessMemoryDump=tr.model.ProcessMemoryDump;function Process(model,pid){if(model===undefined){throw new Error('model must be provided');}
 if(pid===undefined){throw new Error('pid must be provided');}
 tr.model.ProcessBase.call(this,model);this.pid=pid;this.name=undefined;this.labels=[];this.uptime_seconds=0;this.instantEvents=[];this.memoryDumps=[];this.frames=[];this.activities=[];}
-Process.compare=function(x,y){var tmp=tr.model.ProcessBase.compare(x,y);if(tmp)return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo:function(that){return Process.compare(this,that);},childEvents:function*(){yield*ProcessBase.prototype.childEvents.call(this);yield*this.instantEvents;yield*this.frames;yield*this.memoryDumps;},addLabelIfNeeded:function(labelName){for(var i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)return;}
-this.labels.push(labelName);},get userFriendlyName(){var res;if(this.name){res=this.name+' (pid '+this.pid+')';}else{res='Process '+this.pid;}
+Process.compare=function(x,y){let tmp=tr.model.ProcessBase.compare(x,y);if(tmp)return tmp;tmp=tr.b.comparePossiblyUndefinedValues(x.name,y.name,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;tmp=tr.b.compareArrays(x.labels,y.labels,function(x,y){return x.localeCompare(y);});if(tmp)return tmp;return x.pid-y.pid;};Process.prototype={__proto__:tr.model.ProcessBase.prototype,get stableId(){return this.pid;},compareTo(that){return Process.compare(this,that);},*childEvents(){yield*ProcessBase.prototype.childEvents.call(this);yield*this.instantEvents;yield*this.frames;yield*this.memoryDumps;},addLabelIfNeeded(labelName){for(let i=0;i<this.labels.length;i++){if(this.labels[i]===labelName)return;}
+this.labels.push(labelName);},get userFriendlyName(){let res;if(this.name){res=this.name+' (pid '+this.pid+')';}else{res='Process '+this.pid;}
 if(this.labels.length){res+=': '+this.labels.join(', ');}
 if(this.uptime_seconds){res+=', uptime:'+this.uptime_seconds+'s';}
 return res;},get userFriendlyDetails(){if(this.name){return this.name+' (pid '+this.pid+')';}
-return'pid: '+this.pid;},getSettingsKey:function(){if(!this.name)return undefined;if(!this.labels.length)return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward:function(amount){for(var i=0;i<this.instantEvents.length;i++){this.instantEvents[i].start+=amount;}
-for(var i=0;i<this.frames.length;i++){this.frames[i].shiftTimestampsForward(amount);}
-for(var i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].shiftTimestampsForward(amount);}
-for(var i=0;i<this.activities.length;i++){this.activities[i].shiftTimestampsForward(amount);}
-tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds:function(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(var i=0;i<this.frames.length;i++){this.frames[i].addBoundsToRange(this.bounds);}
-for(var i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].addBoundsToRange(this.bounds);}
-for(var i=0;i<this.activities.length;i++){this.activities[i].addBoundsToRange(this.bounds);}},sortMemoryDumps:function(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process,};});'use strict';tr.exportTo('tr.model',function(){function Sample(start,title,leafNode,thread,opt_cpu,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.start_=start;this.title_=title;this.leafNode_=leafNode;this.thread_=thread;this.colorId_=leafNode.colorId;this.cpu_=opt_cpu;this.weight_=opt_weight;this.args=opt_args||{};}
+return'pid: '+this.pid;},getSettingsKey(){if(!this.name)return undefined;if(!this.labels.length)return'processes.'+this.name;return'processes.'+this.name+'.'+this.labels.join('.');},shiftTimestampsForward(amount){for(let i=0;i<this.instantEvents.length;i++){this.instantEvents[i].start+=amount;}
+for(let i=0;i<this.frames.length;i++){this.frames[i].shiftTimestampsForward(amount);}
+for(let i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].shiftTimestampsForward(amount);}
+for(let i=0;i<this.activities.length;i++){this.activities[i].shiftTimestampsForward(amount);}
+tr.model.ProcessBase.prototype.shiftTimestampsForward.apply(this,arguments);},updateBounds(){tr.model.ProcessBase.prototype.updateBounds.apply(this);for(let i=0;i<this.frames.length;i++){this.frames[i].addBoundsToRange(this.bounds);}
+for(let i=0;i<this.memoryDumps.length;i++){this.memoryDumps[i].addBoundsToRange(this.bounds);}
+for(let i=0;i<this.activities.length;i++){this.activities[i].addBoundsToRange(this.bounds);}},sortMemoryDumps(){this.memoryDumps.sort(function(x,y){return x.start-y.start;});tr.model.ProcessMemoryDump.hookUpMostRecentVmRegionsLinks(this.memoryDumps);}};return{Process,};});'use strict';tr.exportTo('tr.model',function(){function Sample(start,title,leafNode,thread,opt_cpu,opt_weight,opt_args){tr.model.TimedEvent.call(this,start);this.start_=start;this.title_=title;this.leafNode_=leafNode;this.thread_=thread;this.colorId_=leafNode.colorId;this.cpu_=opt_cpu;this.weight_=opt_weight;this.args=opt_args||{};}
 Sample.prototype={__proto__:tr.model.TimedEvent.prototype,get title(){return this.title_;},get colorId(){return this.colorId_;},get thread(){return this.thread_;},get leafNode(){return this.leafNode_;},get userFriendlyName(){return'Sample at '+
-tr.b.Unit.byName.timeStampInMs.format(this.start);},get userFriendlyStack(){return this.leafNode_.userFriendlyStack;},getNodesAsArray(){var nodes=[];let node=this.leafNode_;while(node!==undefined){nodes.push(node);node=node.parentNode;}
+tr.b.Unit.byName.timeStampInMs.format(this.start);},get userFriendlyStack(){return this.leafNode_.userFriendlyStack;},getNodesAsArray(){const nodes=[];let node=this.leafNode_;while(node!==undefined){nodes.push(node);node=node.parentNode;}
 return nodes;},get cpu(){return this.cpu_;},get weight(){return this.weight_;},};tr.model.EventRegistry.register(Sample,{name:'Sample',pluralName:'Samples'});return{Sample,};});'use strict';tr.exportTo('tr.model',function(){function StackFrame(parentFrame,id,title,colorId,opt_sourceInfo){if(id===undefined){throw new Error('id must be given');}
 this.parentFrame_=parentFrame;this.id=id;this.title_=title;this.colorId=colorId;this.children=[];this.sourceInfo_=opt_sourceInfo;if(this.parentFrame_){this.parentFrame_.addChild(this);}}
-StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){var src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
-return this.title_;},get domain(){var result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain){result=this.sourceInfo_.domain;}
+StackFrame.prototype={get parentFrame(){return this.parentFrame_;},get title(){if(this.sourceInfo_){const src=this.sourceInfo_.toString();return this.title_+(src===''?'':' '+src);}
+return this.title_;},get domain(){let result='unknown';if(this.sourceInfo_&&this.sourceInfo_.domain){result=this.sourceInfo_.domain;}
 if(result==='unknown'&&this.parentFrame){result=this.parentFrame.domain;}
 return result;},get sourceInfo(){return this.sourceInfo_;},set parentFrame(parentFrame){if(this.parentFrame_){Polymer.dom(this.parentFrame_).removeChild(this);}
-this.parentFrame_=parentFrame;if(this.parentFrame_){this.parentFrame_.addChild(this);}},addChild:function(child){this.children.push(child);},removeChild:function(child){var i=this.children.indexOf(child.id);if(i===-1){throw new Error('omg');}
-this.children.splice(i,1);},removeAllChildren:function(){for(var i=0;i<this.children.length;i++){this.children[i].parentFrame_=undefined;}
-this.children.splice(0,this.children.length);},get stackTrace(){var stack=[this];var cur=this.parentFrame;while(cur){stack.push(cur);cur=cur.parentFrame;}
-return stack;},getUserFriendlyStackTrace:function(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame,};});'use strict';tr.exportTo('tr.model.um',function(){class Segment extends tr.model.TimedEvent{constructor(start,duration){super(start);this.duration=duration;this.expectations_=[];}
+this.parentFrame_=parentFrame;if(this.parentFrame_){this.parentFrame_.addChild(this);}},addChild(child){this.children.push(child);},removeChild(child){const i=this.children.indexOf(child.id);if(i===-1){throw new Error('omg');}
+this.children.splice(i,1);},removeAllChildren(){for(let i=0;i<this.children.length;i++){this.children[i].parentFrame_=undefined;}
+this.children.splice(0,this.children.length);},get stackTrace(){const stack=[this];let cur=this.parentFrame;while(cur){stack.push(cur);cur=cur.parentFrame;}
+return stack;},getUserFriendlyStackTrace(){return this.stackTrace.map(function(x){return x.title;});}};return{StackFrame,};});'use strict';tr.exportTo('tr.model.um',function(){class Segment extends tr.model.TimedEvent{constructor(start,duration){super(start);this.duration=duration;this.expectations_=[];}
 get expectations(){return this.expectations_;}
-clone(){var clone=new Segment(this.start,this.duration);clone.expectations.push(...this.expectations);return clone;}
+clone(){const clone=new Segment(this.start,this.duration);clone.expectations.push(...this.expectations);return clone;}
 addSegment(other){this.duration+=other.duration;this.expectations.push(...other.expectations);}}
 return{Segment,};});'use strict';tr.exportTo('tr.model.um',function(){class UserModel extends tr.model.EventContainer{constructor(parentModel){super();this.parentModel_=parentModel;this.expectations_=new tr.model.EventSet();this.segments_=[];}
 get stableId(){return'UserModel';}
@@ -5142,346 +5203,612 @@
 shiftTimestampsForward(amount){}
 addCategoriesToDict(categoriesDict){}
 get segments(){return this.segments_;}*childEvents(){yield*this.expectations;}*childEventContainers(){}
-updateBounds(){this.bounds.reset();for(var expectation of this.expectations){expectation.addBoundsToRange(this.bounds);}}
-resegment(getKeyForSegment){var newSegments=[];var prevKey=undefined;var prevSegment=undefined;for(var i=0;i<this.segments.length;++i){var segment=this.segments[i];var key=getKeyForSegment(segment,i);if(prevSegment!==undefined&&key===prevKey){prevSegment.addSegment(segment);}else{prevSegment=segment.clone();newSegments.push(prevSegment);}
+updateBounds(){this.bounds.reset();for(const expectation of this.expectations){expectation.addBoundsToRange(this.bounds);}}
+resegment(getKeyForSegment){const newSegments=[];let prevKey=undefined;let prevSegment=undefined;for(let i=0;i<this.segments.length;++i){const segment=this.segments[i];const key=getKeyForSegment(segment,i);if(prevSegment!==undefined&&key===prevKey){prevSegment.addSegment(segment);}else{prevSegment=segment.clone();newSegments.push(prevSegment);}
 prevKey=key;}
 return newSegments;}}
-return{UserModel,};});'use strict';tr.exportTo('tr',function(){var Process=tr.model.Process;var Device=tr.model.Device;var Kernel=tr.model.Kernel;var GlobalMemoryDump=tr.model.GlobalMemoryDump;var GlobalInstantEvent=tr.model.GlobalInstantEvent;var FlowEvent=tr.model.FlowEvent;var Alert=tr.model.Alert;var Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=true;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};this.eventsByStableId_=undefined;}
-Model.prototype={__proto__:tr.model.EventContainer.prototype,getEventByStableId:function(stableId){if(this.eventsByStableId_===undefined){this.eventsByStableId_={};for(var event of this.getDescendantEvents()){this.eventsByStableId_[event.stableId]=event;}}
-return this.eventsByStableId_[stableId];},getOrCreateHelper:function(constructor){if(!constructor.guid){throw new Error('Helper constructors must have GUIDs');}
+return{UserModel,};});'use strict';tr.exportTo('tr',function(){const Process=tr.model.Process;const Device=tr.model.Device;const Kernel=tr.model.Kernel;const GlobalMemoryDump=tr.model.GlobalMemoryDump;const GlobalInstantEvent=tr.model.GlobalInstantEvent;const FlowEvent=tr.model.FlowEvent;const Alert=tr.model.Alert;const Sample=tr.model.Sample;function Model(){tr.model.EventContainer.call(this);tr.b.EventTarget.decorate(this);this.timestampShiftToZeroAmount_=0;this.faviconHue='blue';this.device=new Device(this);this.kernel=new Kernel(this);this.processes={};this.metadata=[];this.categories=[];this.instantEvents=[];this.flowEvents=[];this.clockSyncManager=new tr.model.ClockSyncManager();this.intrinsicTimeUnit_=undefined;this.stackFrames={};this.samples=[];this.alerts=[];this.userModel=new tr.model.um.UserModel(this);this.flowIntervalTree=new tr.b.IntervalTree((f)=>f.start,(f)=>f.end);this.globalMemoryDumps=[];this.userFriendlyCategoryDrivers_=[];this.annotationsByGuid_={};this.modelIndices=undefined;this.stats=new tr.model.ModelStats();this.importWarnings_=[];this.reportedImportWarnings_={};this.isTimeHighResolution_=true;this.patchupsToApply_=[];this.doesHelperGUIDSupportThisModel_={};this.helpersByConstructorGUID_={};this.eventsByStableId_=undefined;}
+Model.prototype={__proto__:tr.model.EventContainer.prototype,getEventByStableId(stableId){if(this.eventsByStableId_===undefined){this.eventsByStableId_={};for(const event of this.getDescendantEvents()){this.eventsByStableId_[event.stableId]=event;}}
+return this.eventsByStableId_[stableId];},getOrCreateHelper(constructor){if(!constructor.guid){throw new Error('Helper constructors must have GUIDs');}
 if(this.helpersByConstructorGUID_[constructor.guid]===undefined){if(this.doesHelperGUIDSupportThisModel_[constructor.guid]===undefined){this.doesHelperGUIDSupportThisModel_[constructor.guid]=constructor.supportsModel(this);}
 if(!this.doesHelperGUIDSupportThisModel_[constructor.guid]){return undefined;}
 this.helpersByConstructorGUID_[constructor.guid]=new constructor(this);}
-return this.helpersByConstructorGUID_[constructor.guid];},childEvents:function*(){yield*this.globalMemoryDumps;yield*this.instantEvents;yield*this.flowEvents;yield*this.alerts;yield*this.samples;},childEventContainers:function*(){yield this.userModel;yield this.device;yield this.kernel;yield*tr.b.dictionaryValues(this.processes);},iterateAllPersistableObjects:function(callback){this.kernel.iterateAllPersistableObjects(callback);for(var pid in this.processes){this.processes[pid].iterateAllPersistableObjects(callback);}},updateBounds:function(){this.bounds.reset();var bounds=this.bounds;for(var ec of this.childEventContainers()){ec.updateBounds();bounds.addRange(ec.bounds);}
-for(var event of this.childEvents()){event.addBoundsToRange(bounds);}},shiftWorldToZero:function(){var shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;for(var ec of this.childEventContainers()){ec.shiftTimestampsForward(shiftAmount);}
-for(var event of this.childEvents()){event.start+=shiftAmount;}
-this.updateBounds();},convertTimestampToModelTime:function(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock'){throw new Error('Only traceEventClock is supported.');}
+return this.helpersByConstructorGUID_[constructor.guid];},*childEvents(){yield*this.globalMemoryDumps;yield*this.instantEvents;yield*this.flowEvents;yield*this.alerts;yield*this.samples;},*childEventContainers(){yield this.userModel;yield this.device;yield this.kernel;yield*Object.values(this.processes);},iterateAllPersistableObjects(callback){this.kernel.iterateAllPersistableObjects(callback);for(const pid in this.processes){this.processes[pid].iterateAllPersistableObjects(callback);}},updateBounds(){this.bounds.reset();const bounds=this.bounds;for(const ec of this.childEventContainers()){ec.updateBounds();bounds.addRange(ec.bounds);}
+for(const event of this.childEvents()){event.addBoundsToRange(bounds);}},shiftWorldToZero(){const shiftAmount=-this.bounds.min;this.timestampShiftToZeroAmount_=shiftAmount;for(const ec of this.childEventContainers()){ec.shiftTimestampsForward(shiftAmount);}
+for(const event of this.childEvents()){event.start+=shiftAmount;}
+this.updateBounds();},convertTimestampToModelTime(sourceClockDomainName,ts){if(sourceClockDomainName!=='traceEventClock'){throw new Error('Only traceEventClock is supported.');}
 return tr.b.Unit.timestampFromUs(ts)+
-this.timestampShiftToZeroAmount_;},get numProcesses(){var n=0;for(var p in this.processes){n++;}
-return n;},getProcess:function(pid){return this.processes[pid];},getOrCreateProcess:function(pid){if(!this.processes[pid]){this.processes[pid]=new Process(this,pid);}
-return this.processes[pid];},addStackFrame:function(stackFrame){if(this.stackFrames[stackFrame.id]){throw new Error('Stack frame already exists');}
-this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},updateCategories_:function(){var categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(var pid in this.processes){this.processes[pid].addCategoriesToDict(categoriesDict);}
-this.categories=[];for(var category in categoriesDict){if(category!==''){this.categories.push(category);}}},getAllThreads:function(){var threads=[];for(var tid in this.kernel.threads){threads.push(process.threads[tid]);}
-for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.threads){threads.push(process.threads[tid]);}}
-return threads;},getAllProcesses:function(opt_predicate){var processes=[];for(var pid in this.processes){var process=this.processes[pid];if(opt_predicate===undefined||opt_predicate(process)){processes.push(process);}}
-return processes;},getAllCounters:function(){var counters=[];counters.push.apply(counters,tr.b.dictionaryValues(this.device.counters));counters.push.apply(counters,tr.b.dictionaryValues(this.kernel.counters));for(var pid in this.processes){var process=this.processes[pid];for(var tid in process.counters){counters.push(process.counters[tid]);}}
-return counters;},getAnnotationByGUID:function(guid){return this.annotationsByGuid_[guid];},addAnnotation:function(annotation){if(!annotation.guid){throw new Error('Annotation with undefined guid given');}
-this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation:function(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations:function(){return tr.b.dictionaryValues(this.annotationsByGuid_);},addUserFriendlyCategoryDriver:function(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent:function(event){for(var i=0;i<this.userFriendlyCategoryDrivers_.length;i++){var ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)return ufc;}
-return undefined;},findAllThreadsNamed:function(name){var namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(var pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
+this.timestampShiftToZeroAmount_;},get numProcesses(){let n=0;for(const p in this.processes){n++;}
+return n;},getProcess(pid){return this.processes[pid];},getOrCreateProcess(pid){if(!this.processes[pid]){this.processes[pid]=new Process(this,pid);}
+return this.processes[pid];},addStackFrame(stackFrame){if(this.stackFrames[stackFrame.id]){throw new Error('Stack frame already exists');}
+this.stackFrames[stackFrame.id]=stackFrame;return stackFrame;},updateCategories_(){const categoriesDict={};this.userModel.addCategoriesToDict(categoriesDict);this.device.addCategoriesToDict(categoriesDict);this.kernel.addCategoriesToDict(categoriesDict);for(const pid in this.processes){this.processes[pid].addCategoriesToDict(categoriesDict);}
+this.categories=[];for(const category in categoriesDict){if(category!==''){this.categories.push(category);}}},getAllThreads(){const threads=[];for(const tid in this.kernel.threads){threads.push(process.threads[tid]);}
+for(const pid in this.processes){const process=this.processes[pid];for(const tid in process.threads){threads.push(process.threads[tid]);}}
+return threads;},getAllProcesses(opt_predicate){const processes=[];for(const pid in this.processes){const process=this.processes[pid];if(opt_predicate===undefined||opt_predicate(process)){processes.push(process);}}
+return processes;},getAllCounters(){const counters=[];counters.push.apply(counters,Object.values(this.device.counters||{}));counters.push.apply(counters,Object.values(this.kernel.counters||{}));for(const pid in this.processes){const process=this.processes[pid];for(const tid in process.counters){counters.push(process.counters[tid]);}}
+return counters;},getAnnotationByGUID(guid){return this.annotationsByGuid_[guid];},addAnnotation(annotation){if(!annotation.guid){throw new Error('Annotation with undefined guid given');}
+this.annotationsByGuid_[annotation.guid]=annotation;tr.b.dispatchSimpleEvent(this,'annotationChange');},removeAnnotation(annotation){this.annotationsByGuid_[annotation.guid].onRemove();delete this.annotationsByGuid_[annotation.guid];tr.b.dispatchSimpleEvent(this,'annotationChange');},getAllAnnotations(){return Object.values(this.annotationsByGuid_);},addUserFriendlyCategoryDriver(ufcd){this.userFriendlyCategoryDrivers_.push(ufcd);},getUserFriendlyCategoryFromEvent(event){for(let i=0;i<this.userFriendlyCategoryDrivers_.length;i++){const ufc=this.userFriendlyCategoryDrivers_[i].fromEvent(event);if(ufc!==undefined)return ufc;}
+return undefined;},findAllThreadsNamed(name){const namedThreads=[];namedThreads.push.apply(namedThreads,this.kernel.findAllThreadsNamed(name));for(const pid in this.processes){namedThreads.push.apply(namedThreads,this.processes[pid].findAllThreadsNamed(name));}
 return namedThreads;},get importOptions(){return this.importOptions_;},set importOptions(options){this.importOptions_=options;},get intrinsicTimeUnit(){if(this.intrinsicTimeUnit_===undefined){return tr.b.TimeDisplayModes.ms;}
 return this.intrinsicTimeUnit_;},set intrinsicTimeUnit(value){if(this.intrinsicTimeUnit_===value)return;if(this.intrinsicTimeUnit_!==undefined){throw new Error('Intrinsic time unit already set');}
 this.intrinsicTimeUnit_=value;},get isTimeHighResolution(){return this.isTimeHighResolution_;},set isTimeHighResolution(value){this.isTimeHighResolution_=value;},get canonicalUrl(){return this.canonicalUrl_;},set canonicalUrl(value){if(this.canonicalUrl_===value)return;if(this.canonicalUrl_!==undefined){throw new Error('canonicalUrl already set');}
-this.canonicalUrl_=value;},importWarning:function(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)return;this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices:function(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(var pid in this.processes){this.processes[pid].autoCloseOpenSlices();}},createSubSlices:function(){this.kernel.createSubSlices();for(var pid in this.processes){this.processes[pid].createSubSlices();}},preInitializeObjects:function(){for(var pid in this.processes){this.processes[pid].preInitializeObjects();}},initializeObjects:function(){for(var pid in this.processes){this.processes[pid].initializeObjects();}},pruneEmptyContainers:function(){this.kernel.pruneEmptyContainers();for(var pid in this.processes){this.processes[pid].pruneEmptyContainers();}},mergeKernelWithUserland:function(){for(var pid in this.processes){this.processes[pid].mergeKernelWithUserland();}},computeWorldBounds:function(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero){this.shiftWorldToZero();}},buildFlowEventIntervalTree:function(){for(var i=0;i<this.flowEvents.length;++i){var flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
-this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects:function(){for(var pid in this.processes){this.processes[pid].autoDeleteObjects(this.bounds.max);}},sortMemoryDumps:function(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(var pid in this.processes){this.processes[pid].sortMemoryDumps();}},finalizeMemoryGraphs:function(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices:function(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts:function(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups:function(){var unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){var snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;snapshot.referencedAt(patchup.item,patchup.object,patchup.field);return;}}
-unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups:function(oldPidRef,newPidRef){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===oldPidRef){patchup.pidRef=newPidRef;}});},joinRefs:function(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_:function(){for(var[pid,process]of Object.entries(this.processes)){this.joinObjectRefsForProcess_(pid,process);}},joinObjectRefsForProcess_:function(pid,process){for(var thread of Object.values(process.threads)){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);}
-process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_:function(pid,itemTimestampField,item){if(!item.args&&!item.contexts)return;var patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef)){return;}
-var scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;var idRef=fieldValue.id_ref||fieldValue.idRef;var scopedId=new tr.model.ScopedId(scope,idRef);var pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;var ts=item[itemTimestampField];patchupsToApply.push({item:item,object:object,field:fieldName,pidRef:pidRef,scopedId:scopedId,ts:ts});}
+this.canonicalUrl_=value;},importWarning(data){data.showToUser=!!data.showToUser;this.importWarnings_.push(data);if(this.reportedImportWarnings_[data.type]===true)return;this.reportedImportWarnings_[data.type]=true;},get hasImportWarnings(){return(this.importWarnings_.length>0);},get importWarnings(){return this.importWarnings_;},get importWarningsThatShouldBeShownToUser(){return this.importWarnings_.filter(function(warning){return warning.showToUser;});},autoCloseOpenSlices(){this.samples.sort(function(x,y){return x.start-y.start;});this.updateBounds();this.kernel.autoCloseOpenSlices();for(const pid in this.processes){this.processes[pid].autoCloseOpenSlices();}},createSubSlices(){this.kernel.createSubSlices();for(const pid in this.processes){this.processes[pid].createSubSlices();}},preInitializeObjects(){for(const pid in this.processes){this.processes[pid].preInitializeObjects();}},initializeObjects(){for(const pid in this.processes){this.processes[pid].initializeObjects();}},pruneEmptyContainers(){this.kernel.pruneEmptyContainers();for(const pid in this.processes){this.processes[pid].pruneEmptyContainers();}},mergeKernelWithUserland(){for(const pid in this.processes){this.processes[pid].mergeKernelWithUserland();}},computeWorldBounds(shiftWorldToZero){this.updateBounds();this.updateCategories_();if(shiftWorldToZero){this.shiftWorldToZero();}},buildFlowEventIntervalTree(){for(let i=0;i<this.flowEvents.length;++i){const flowEvent=this.flowEvents[i];this.flowIntervalTree.insert(flowEvent);}
+this.flowIntervalTree.updateHighValues();},cleanupUndeletedObjects(){for(const pid in this.processes){this.processes[pid].autoDeleteObjects(this.bounds.max);}},sortMemoryDumps(){this.globalMemoryDumps.sort(function(x,y){return x.start-y.start;});for(const pid in this.processes){this.processes[pid].sortMemoryDumps();}},finalizeMemoryGraphs(){this.globalMemoryDumps.forEach(function(dump){dump.finalizeGraph();});},buildEventIndices(){this.modelIndices=new tr.model.ModelIndices(this);},sortAlerts(){this.alerts.sort(function(x,y){return x.start-y.start;});},applyObjectRefPatchups(){const unresolved=[];this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef in this.processes){const snapshot=this.processes[patchup.pidRef].objects.getSnapshotAt(patchup.scopedId,patchup.ts);if(snapshot){patchup.object[patchup.field]=snapshot;snapshot.referencedAt(patchup.item,patchup.object,patchup.field);return;}}
+unresolved.push(patchup);},this);this.patchupsToApply_=unresolved;},replacePIDRefsInPatchups(oldPidRef,newPidRef){this.patchupsToApply_.forEach(function(patchup){if(patchup.pidRef===oldPidRef){patchup.pidRef=newPidRef;}});},joinRefs(){this.joinObjectRefs_();this.applyObjectRefPatchups();},joinObjectRefs_(){for(const[pid,process]of Object.entries(this.processes)){this.joinObjectRefsForProcess_(pid,process);}},joinObjectRefsForProcess_(pid,process){for(const thread of Object.values(process.threads)){thread.asyncSliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);thread.sliceGroup.slices.forEach(function(item){this.searchItemForIDRefs_(pid,'start',item);},this);}
+process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(item){this.searchItemForIDRefs_(pid,'ts',item);},this);},this);},searchItemForIDRefs_(pid,itemTimestampField,item){if(!item.args&&!item.contexts)return;const patchupsToApply=this.patchupsToApply_;function handleField(object,fieldName,fieldValue){if(!fieldValue||(!fieldValue.id_ref&&!fieldValue.idRef)){return;}
+const scope=fieldValue.scope||tr.model.OBJECT_DEFAULT_SCOPE;const idRef=fieldValue.id_ref||fieldValue.idRef;const scopedId=new tr.model.ScopedId(scope,idRef);const pidRef=fieldValue.pid_ref||fieldValue.pidRef||pid;const ts=item[itemTimestampField];patchupsToApply.push({item,object,field:fieldName,pidRef,scopedId,ts});}
 function iterObjectFieldsRecursively(object){if(!(object instanceof Object))return;if((object instanceof tr.model.ObjectSnapshot)||(object instanceof Float32Array)||(object instanceof tr.b.math.Quad)){return;}
-if(object instanceof Array){for(var i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
+if(object instanceof Array){for(let i=0;i<object.length;i++){handleField(object,i,object[i]);iterObjectFieldsRecursively(object[i]);}
 return;}
-for(var key in object){var value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
-iterObjectFieldsRecursively(item.args);iterObjectFieldsRecursively(item.contexts);}};return{Model,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){var kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';var kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));}
-Decoder.prototype={__proto__:Object.prototype,reset:function(base64Payload){var decodedSize=tr.b.Base64.getDecodedBufferLength(base64Payload);if(decodedSize>this.payload_.byteLength){this.payload_=new DataView(new ArrayBuffer(decodedSize));}
-tr.b.Base64.DecodeToTypedArray(base64Payload,this.payload_);this.position_=0;},skip:function(length){this.position_+=length;},decodeUInt8:function(){var result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16:function(){var result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32:function(){var result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString:function(){var low=this.decodeUInt32();var high=this.decodeUInt32();var lowStr=('0000000'+low.toString(16)).substr(-8);var highStr=('0000000'+high.toString(16)).substr(-8);var result=highStr+lowStr;return result;},decodeInt8:function(){var result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16:function(){var result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32:function(){var result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString:function(){return this.decodeUInt64ToString();},decodeUInteger:function(is64){if(is64){return this.decodeUInt64ToString();}
-return this.decodeUInt32();},decodeString:function(){var str='';while(true){var c=this.decodeUInt8();if(!c)return str;str=str+String.fromCharCode(c);}},decodeW16String:function(){var str='';while(true){var c=this.decodeUInt16();if(!c)return str;str=str+String.fromCharCode(c);}},decodeFixedW16String:function(length){var oldPosition=this.position_;var str='';for(var i=0;i<length;i++){var c=this.decodeUInt16();if(!c)break;str=str+String.fromCharCode(c);}
-this.position_=oldPosition+2*length;return str;},decodeBytes:function(length){var bytes=[];for(var i=0;i<length;++i){var c=this.decodeUInt8();bytes.push(c);}
-return bytes;},decodeSID:function(is64){var pSid=this.decodeUInteger(is64);var attributes=this.decodeUInt32();if(is64){this.decodeUInt32();}
-var revision=this.decodeUInt8();var subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!==1){throw new Error('Invalid SID revision: could not decode the SID structure.');}
-var sid=this.decodeBytes(4*subAuthorityCount);return{pSid:pSid,attributes:attributes,sid:sid};},decodeSystemTime:function(){var wYear=this.decodeInt16();var wMonth=this.decodeInt16();var wDayOfWeek=this.decodeInt16();var wDay=this.decodeInt16();var wHour=this.decodeInt16();var wMinute=this.decodeInt16();var wSecond=this.decodeInt16();var wMilliseconds=this.decodeInt16();return{wYear:wYear,wMonth:wMonth,wDayOfWeek:wDayOfWeek,wDay:wDay,wHour:wHour,wMinute:wMinute,wSecond:wSecond,wMilliseconds:wMilliseconds};},decodeTimeZoneInformation:function(){var bias=this.decodeUInt32();var standardName=this.decodeFixedW16String(32);var standardDate=this.decodeSystemTime();var standardBias=this.decodeUInt32();var daylightName=this.decodeFixedW16String(32);var daylightDate=this.decodeSystemTime();var daylightBias=this.decodeUInt32();return{bias:bias,standardName:standardName,standardDate:standardDate,standardBias:standardBias,daylightName:daylightName,daylightDate:daylightDate,daylightBias:daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};var allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
+for(const key in object){const value=object[key];handleField(object,key,value);iterObjectFieldsRecursively(value);}}
+iterObjectFieldsRecursively(item.args);iterObjectFieldsRecursively(item.contexts);}};return{Model,};});'use strict';tr.exportTo('tr.e.importer.etw',function(){const kThreadGuid='3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C';const kThreadDCStartOpcode=3;function Decoder(){this.payload_=new DataView(new ArrayBuffer(256));}
+Decoder.prototype={__proto__:Object.prototype,reset(base64Payload){const decodedSize=tr.b.Base64.getDecodedBufferLength(base64Payload);if(decodedSize>this.payload_.byteLength){this.payload_=new DataView(new ArrayBuffer(decodedSize));}
+tr.b.Base64.DecodeToTypedArray(base64Payload,this.payload_);this.position_=0;},skip(length){this.position_+=length;},decodeUInt8(){const result=this.payload_.getUint8(this.position_,true);this.position_+=1;return result;},decodeUInt16(){const result=this.payload_.getUint16(this.position_,true);this.position_+=2;return result;},decodeUInt32(){const result=this.payload_.getUint32(this.position_,true);this.position_+=4;return result;},decodeUInt64ToString(){const low=this.decodeUInt32();const high=this.decodeUInt32();const lowStr=('0000000'+low.toString(16)).substr(-8);const highStr=('0000000'+high.toString(16)).substr(-8);const result=highStr+lowStr;return result;},decodeInt8(){const result=this.payload_.getInt8(this.position_,true);this.position_+=1;return result;},decodeInt16(){const result=this.payload_.getInt16(this.position_,true);this.position_+=2;return result;},decodeInt32(){const result=this.payload_.getInt32(this.position_,true);this.position_+=4;return result;},decodeInt64ToString(){return this.decodeUInt64ToString();},decodeUInteger(is64){if(is64){return this.decodeUInt64ToString();}
+return this.decodeUInt32();},decodeString(){let str='';while(true){const c=this.decodeUInt8();if(!c)return str;str=str+String.fromCharCode(c);}},decodeW16String(){let str='';while(true){const c=this.decodeUInt16();if(!c)return str;str=str+String.fromCharCode(c);}},decodeFixedW16String(length){const oldPosition=this.position_;let str='';for(let i=0;i<length;i++){const c=this.decodeUInt16();if(!c)break;str=str+String.fromCharCode(c);}
+this.position_=oldPosition+2*length;return str;},decodeBytes(length){const bytes=[];for(let i=0;i<length;++i){const c=this.decodeUInt8();bytes.push(c);}
+return bytes;},decodeSID(is64){const pSid=this.decodeUInteger(is64);const attributes=this.decodeUInt32();if(is64){this.decodeUInt32();}
+const revision=this.decodeUInt8();const subAuthorityCount=this.decodeUInt8();this.decodeUInt16();this.decodeUInt32();if(revision!==1){throw new Error('Invalid SID revision: could not decode the SID structure.');}
+const sid=this.decodeBytes(4*subAuthorityCount);return{pSid,attributes,sid};},decodeSystemTime(){const wYear=this.decodeInt16();const wMonth=this.decodeInt16();const wDayOfWeek=this.decodeInt16();const wDay=this.decodeInt16();const wHour=this.decodeInt16();const wMinute=this.decodeInt16();const wSecond=this.decodeInt16();const wMilliseconds=this.decodeInt16();return{wYear,wMonth,wDayOfWeek,wDay,wHour,wMinute,wSecond,wMilliseconds};},decodeTimeZoneInformation(){const bias=this.decodeUInt32();const standardName=this.decodeFixedW16String(32);const standardDate=this.decodeSystemTime();const standardBias=this.decodeUInt32();const daylightName=this.decodeFixedW16String(32);const daylightDate=this.decodeSystemTime();const daylightBias=this.decodeUInt32();return{bias,standardName,standardDate,standardBias,daylightName,daylightDate,daylightBias};}};function EtwImporter(model,events){this.importPriority=3;this.model_=model;this.events_=events;this.handlers_={};this.decoder_=new Decoder();this.walltime_=undefined;this.ticks_=undefined;this.is64bit_=undefined;this.tidsToPid_={};const allTypeInfos=tr.e.importer.etw.Parser.getAllRegisteredTypeInfos();this.parsers_=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);}
 EtwImporter.canImport=function(events){if(!events.hasOwnProperty('name')||!events.hasOwnProperty('content')||events.name!=='ETW'){return false;}
-return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded:function(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent:function(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid:function(tid){if(tid===0)return 0;var pid=this.tidsToPid_[tid];if(pid===undefined){return 0;}
-return pid;},getThreadFromWindowsTid:function(tid){var pid=this.getPidFromWindowsTid(tid);var process=this.model_.getProcess(pid);if(!process)return undefined;return process.getThread(tid);},getOrCreateCpu:function(cpuNumber){var cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents:function(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_===undefined||this.ticks_===undefined){throw Error('Cannot find clock sync information in the system trace.');}
+return true;};EtwImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EtwImporter';},get model(){return this.model_;},createThreadIfNeeded(pid,tid){this.tidsToPid_[tid]=pid;},removeThreadIfPresent(tid){this.tidsToPid_[tid]=undefined;},getPidFromWindowsTid(tid){if(tid===0)return 0;const pid=this.tidsToPid_[tid];if(pid===undefined){return 0;}
+return pid;},getThreadFromWindowsTid(tid){const pid=this.getPidFromWindowsTid(tid);const process=this.model_.getProcess(pid);if(!process)return undefined;return process.getThread(tid);},getOrCreateCpu(cpuNumber){const cpu=this.model_.kernel.getOrCreateCpu(cpuNumber);return cpu;},importEvents(){this.events_.content.forEach(this.parseInfo.bind(this));if(this.walltime_===undefined||this.ticks_===undefined){throw Error('Cannot find clock sync information in the system trace.');}
 if(this.is64bit_===undefined){throw Error('Cannot determine pointer size of the system trace.');}
-this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp:function(timestamp){var ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo:function(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
-if(this.is64bit_===undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op===kThreadDCStartOpcode){var decodedSize=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver===1){if(decodedSize>=52){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===2){if(decodedSize>=64){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===3){if(decodedSize>=60){this.is64bit_=true;}else{this.is64bit_=false;}}}
-return true;},parseEvent:function(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
-var timestamp=this.importTimestamp(event.ts);var header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp:timestamp,is64:this.is64bit_};var decoder=this.decoder_;decoder.reset(event.payload);var handler=this.getEventHandler(header.guid,header.opcode);if(!handler)return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+event.payload+')'});return false;}
-return true;},registerEventHandler:function(guid,opcode,handler){if(this.handlers_[guid]===undefined){this.handlers_[guid]=[];}
-this.handlers_[guid][opcode]=handler;},getEventHandler:function(guid,opcode){if(this.handlers_[guid]===undefined){return undefined;}
-return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter,};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.window={};}'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){var jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');var jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){var GZIP_MEMBER_HEADER_ID_SIZE=3;var GZIP_HEADER_ID1=0x1f;var GZIP_HEADER_ID2=0x8b;var GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else{throw new Error('Unknown gzip data format');}
+this.events_.content.forEach(this.parseEvent.bind(this));},importTimestamp(timestamp){const ts=parseInt(timestamp,16);return(ts-this.walltime_+this.ticks_)/1000.;},parseInfo(event){if(event.hasOwnProperty('guid')&&event.hasOwnProperty('walltime')&&event.hasOwnProperty('tick')&&event.guid==='ClockSync'){this.walltime_=parseInt(event.walltime,16);this.ticks_=parseInt(event.tick,16);}
+if(this.is64bit_===undefined&&event.hasOwnProperty('guid')&&event.hasOwnProperty('op')&&event.hasOwnProperty('ver')&&event.hasOwnProperty('payload')&&event.guid===kThreadGuid&&event.op===kThreadDCStartOpcode){const decodedSize=tr.b.Base64.getDecodedBufferLength(event.payload);if(event.ver===1){if(decodedSize>=52){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===2){if(decodedSize>=64){this.is64bit_=true;}else{this.is64bit_=false;}}else if(event.ver===3){if(decodedSize>=60){this.is64bit_=true;}else{this.is64bit_=false;}}}
+return true;},parseEvent(event){if(!event.hasOwnProperty('guid')||!event.hasOwnProperty('op')||!event.hasOwnProperty('ver')||!event.hasOwnProperty('cpu')||!event.hasOwnProperty('ts')||!event.hasOwnProperty('payload')){return false;}
+const timestamp=this.importTimestamp(event.ts);const header={guid:event.guid,opcode:event.op,version:event.ver,cpu:event.cpu,timestamp,is64:this.is64bit_};const decoder=this.decoder_;decoder.reset(event.payload);const handler=this.getEventHandler(header.guid,header.opcode);if(!handler)return false;if(!handler(header,decoder)){this.model_.importWarning({type:'parse_error',message:'Malformed '+header.guid+' event ('+event.payload+')'});return false;}
+return true;},registerEventHandler(guid,opcode,handler){if(this.handlers_[guid]===undefined){this.handlers_[guid]=[];}
+this.handlers_[guid][opcode]=handler;},getEventHandler(guid,opcode){if(this.handlers_[guid]===undefined){return undefined;}
+return this.handlers_[guid][opcode];}};tr.importer.Importer.register(EtwImporter);return{EtwImporter,};});'use strict';tr.exportTo('tr.b',function(){class TraceStream{static get HEADER_SIZE(){return Math.pow(2,10);}
+static get CHUNK_SIZE(){return Math.pow(2,20);}
+get isBinary(){throw new Error('Not implemented');}
+get hasData(){throw new Error('Not implemented');}
+get header(){throw new Error('Not implemented');}
+readUntilDelimiter(delim){throw new Error('Not implemented');}
+readNumBytes(opt_size){throw new Error('Not implemented');}
+rewind(){throw new Error('Not implemented');}
+substream(offset,opt_length,opt_headerSize){throw new Error('Not implemented');}}
+return{TraceStream,};});'use strict';tr.exportTo('tr.b',function(){const MAX_FUNCTION_ARGS_COUNT=Math.pow(2,15)-1;class InMemoryTraceStream extends tr.b.TraceStream{constructor(buffer,isBinary,opt_headerSize){super();if(!buffer instanceof Uint8Array){throw new Error('buffer should be a Uint8Array');}
+const headerSize=opt_headerSize||tr.b.TraceStream.HEADER_SIZE;this.data_=buffer;this.isBinary_=isBinary;this.header_=InMemoryTraceStream.uint8ArrayToString_(this.data_.subarray(0,headerSize));this.cursor_=0;}
+get isBinary(){return this.isBinary_;}
+get hasData(){return this.cursor_<this.data_.length;}
+get header(){return this.header_;}
+get data(){return this.data_;}
+toString(){this.rewind();return this.readNumBytes(Number.MAX_VALUE);}
+readUntilDelimiter(delim){if(delim.length!==1){throw new Error('delim must be exactly one character');}
+const offset=this.data_.indexOf(delim.charCodeAt(0),this.cursor_)+1;return this.readToOffset_(offset>0?Math.min(offset,this.data_.length):this.data_.length);}
+readNumBytes(opt_size){if(opt_size!==undefined&&opt_size<=0){throw new Error(`readNumBytes expects a positive size (${opt_size} given)`);}
+const size=opt_size||tr.b.TraceStream.CHUNK_SIZE;const offset=Math.min(this.cursor_+size,this.data_.length);return this.readToOffset_(offset);}
+rewind(){this.cursor_=0;}
+substream(startOffset,opt_endOffset,opt_headerSize){return new InMemoryTraceStream(this.data_.subarray(startOffset,opt_endOffset),this.isBinary_,opt_headerSize);}
+readToOffset_(offset){const out=InMemoryTraceStream.uint8ArrayToString_(this.data_.subarray(this.cursor_,offset));this.cursor_=offset;return out;}
+static uint8ArrayToString_(arr){const c=[];for(let i=0;i<arr.length;i+=MAX_FUNCTION_ARGS_COUNT){c.push(String.fromCharCode(...arr.subarray(i,i+MAX_FUNCTION_ARGS_COUNT)));}
+return c.join('');}}
+return{InMemoryTraceStream,};});!function(a){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=a();else if("function"==typeof define&&define.amd)define([],a);else{var b;"undefined"!=typeof window?b=window:"undefined"!=typeof global?b=global:"undefined"!=typeof self&&(b=self),b.JSZip=a()}}(function(){return function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g<d.length;g++)e(d[g]);return e}({1:[function(a,b,c){"use strict";var d="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";c.encode=function(a){for(var b,c,e,f,g,h,i,j="",k=0;k<a.length;)b=a.charCodeAt(k++),c=a.charCodeAt(k++),e=a.charCodeAt(k++),f=b>>2,g=(3&b)<<4|c>>4,h=(15&c)<<2|e>>6,i=63&e,isNaN(c)?h=i=64:isNaN(e)&&(i=64),j=j+d.charAt(f)+d.charAt(g)+d.charAt(h)+d.charAt(i);return j},c.decode=function(a){var b,c,e,f,g,h,i,j="",k=0;for(a=a.replace(/[^A-Za-z0-9\+\/\=]/g,"");k<a.length;)f=d.indexOf(a.charAt(k++)),g=d.indexOf(a.charAt(k++)),h=d.indexOf(a.charAt(k++)),i=d.indexOf(a.charAt(k++)),b=f<<2|g>>4,c=(15&g)<<4|h>>2,e=(3&h)<<6|i,j+=String.fromCharCode(b),64!=h&&(j+=String.fromCharCode(c)),64!=i&&(j+=String.fromCharCode(e));return j}},{}],2:[function(a,b){"use strict";function c(){this.compressedSize=0,this.uncompressedSize=0,this.crc32=0,this.compressionMethod=null,this.compressedContent=null}c.prototype={getContent:function(){return null},getCompressedContent:function(){return null}},b.exports=c},{}],3:[function(a,b,c){"use strict";c.STORE={magic:"\x00\x00",compress:function(a){return a},uncompress:function(a){return a},compressInputType:null,uncompressInputType:null},c.DEFLATE=a("./flate")},{"./flate":8}],4:[function(a,b){"use strict";var c=a("./utils"),d=[0,1996959894,3993919788,2567524794,124634137,1886057615,3915621685,2657392035,249268274,2044508324,3772115230,2547177864,162941995,2125561021,3887607047,2428444049,498536548,1789927666,4089016648,2227061214,450548861,1843258603,4107580753,2211677639,325883990,1684777152,4251122042,2321926636,335633487,1661365465,4195302755,2366115317,997073096,1281953886,3579855332,2724688242,1006888145,1258607687,3524101629,2768942443,901097722,1119000684,3686517206,2898065728,853044451,1172266101,3705015759,2882616665,651767980,1373503546,3369554304,3218104598,565507253,1454621731,3485111705,3099436303,671266974,1594198024,3322730930,2970347812,795835527,1483230225,3244367275,3060149565,1994146192,31158534,2563907772,4023717930,1907459465,112637215,2680153253,3904427059,2013776290,251722036,2517215374,3775830040,2137656763,141376813,2439277719,3865271297,1802195444,476864866,2238001368,4066508878,1812370925,453092731,2181625025,4111451223,1706088902,314042704,2344532202,4240017532,1658658271,366619977,2362670323,4224994405,1303535960,984961486,2747007092,3569037538,1256170817,1037604311,2765210733,3554079995,1131014506,879679996,2909243462,3663771856,1141124467,855842277,2852801631,3708648649,1342533948,654459306,3188396048,3373015174,1466479909,544179635,3110523913,3462522015,1591671054,702138776,2966460450,3352799412,1504918807,783551873,3082640443,3233442989,3988292384,2596254646,62317068,1957810842,3939845945,2647816111,81470997,1943803523,3814918930,2489596804,225274430,2053790376,3826175755,2466906013,167816743,2097651377,4027552580,2265490386,503444072,1762050814,4150417245,2154129355,426522225,1852507879,4275313526,2312317920,282753626,1742555852,4189708143,2394877945,397917763,1622183637,3604390888,2714866558,953729732,1340076626,3518719985,2797360999,1068828381,1219638859,3624741850,2936675148,906185462,1090812512,3747672003,2825379669,829329135,1181335161,3412177804,3160834842,628085408,1382605366,3423369109,3138078467,570562233,1426400815,3317316542,2998733608,733239954,1555261956,3268935591,3050360625,752459403,1541320221,2607071920,3965973030,1969922972,40735498,2617837225,3943577151,1913087877,83908371,2512341634,3803740692,2075208622,213261112,2463272603,3855990285,2094854071,198958881,2262029012,4057260610,1759359992,534414190,2176718541,4139329115,1873836001,414664567,2282248934,4279200368,1711684554,285281116,2405801727,4167216745,1634467795,376229701,2685067896,3608007406,1308918612,956543938,2808555105,3495958263,1231636301,1047427035,2932959818,3654703836,1088359270,936918e3,2847714899,3736837829,1202900863,817233897,3183342108,3401237130,1404277552,615818150,3134207493,3453421203,1423857449,601450431,3009837614,3294710456,1567103746,711928724,3020668471,3272380065,1510334235,755167117];b.exports=function(a,b){if("undefined"==typeof a||!a.length)return 0;var e="string"!==c.getTypeOf(a);"undefined"==typeof b&&(b=0);var f=0,g=0,h=0;b=-1^b;for(var i=0,j=a.length;j>i;i++)h=e?a[i]:a.charCodeAt(i),g=255&(b^h),f=d[g],b=b>>>8^f;return-1^b}},{"./utils":21}],5:[function(a,b){"use strict";function c(){this.data=null,this.length=0,this.index=0}var d=a("./utils");c.prototype={checkOffset:function(a){this.checkIndex(this.index+a)},checkIndex:function(a){if(this.length<a||0>a)throw new Error("End of data reached (data length = "+this.length+", asked index = "+a+"). Corrupted zip ?")},setIndex:function(a){this.checkIndex(a),this.index=a},skip:function(a){this.setIndex(this.index+a)},byteAt:function(){},readInt:function(a){var b,c=0;for(this.checkOffset(a),b=this.index+a-1;b>=this.index;b--)c=(c<<8)+this.byteAt(b);return this.index+=a,c},readString:function(a){return d.transformTo("string",this.readData(a))},readData:function(){},lastIndexOfSignature:function(){},readDate:function(){var a=this.readInt(4);return new Date((a>>25&127)+1980,(a>>21&15)-1,a>>16&31,a>>11&31,a>>5&63,(31&a)<<1)}},b.exports=c},{"./utils":21}],6:[function(a,b,c){"use strict";c.base64=!1,c.binary=!1,c.dir=!1,c.createFolders=!1,c.date=null,c.compression=null,c.comment=null},{}],7:[function(a,b,c){"use strict";var d=a("./utils");c.string2binary=function(a){return d.string2binary(a)},c.string2Uint8Array=function(a){return d.transformTo("uint8array",a)},c.uint8Array2String=function(a){return d.transformTo("string",a)},c.string2Blob=function(a){var b=d.transformTo("arraybuffer",a);return d.arrayBuffer2Blob(b)},c.arrayBuffer2Blob=function(a){return d.arrayBuffer2Blob(a)},c.transformTo=function(a,b){return d.transformTo(a,b)},c.getTypeOf=function(a){return d.getTypeOf(a)},c.checkSupport=function(a){return d.checkSupport(a)},c.MAX_VALUE_16BITS=d.MAX_VALUE_16BITS,c.MAX_VALUE_32BITS=d.MAX_VALUE_32BITS,c.pretty=function(a){return d.pretty(a)},c.findCompression=function(a){return d.findCompression(a)},c.isRegExp=function(a){return d.isRegExp(a)}},{"./utils":21}],8:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,e=a("pako");c.uncompressInputType=d?"uint8array":"array",c.compressInputType=d?"uint8array":"array",c.magic="\b\x00",c.compress=function(a){return e.deflateRaw(a)},c.uncompress=function(a){return e.inflateRaw(a)}},{pako:24}],9:[function(a,b){"use strict";function c(a,b){return this instanceof c?(this.files={},this.comment=null,this.root="",a&&this.load(a,b),void(this.clone=function(){var a=new c;for(var b in this)"function"!=typeof this[b]&&(a[b]=this[b]);return a})):new c(a,b)}var d=a("./base64");c.prototype=a("./object"),c.prototype.load=a("./load"),c.support=a("./support"),c.defaults=a("./defaults"),c.utils=a("./deprecatedPublicUtils"),c.base64={encode:function(a){return d.encode(a)},decode:function(a){return d.decode(a)}},c.compressions=a("./compressions"),b.exports=c},{"./base64":1,"./compressions":3,"./defaults":6,"./deprecatedPublicUtils":7,"./load":10,"./object":13,"./support":17}],10:[function(a,b){"use strict";var c=a("./base64"),d=a("./zipEntries");b.exports=function(a,b){var e,f,g,h;for(b=b||{},b.base64&&(a=c.decode(a)),f=new d(a,b),e=f.files,g=0;g<e.length;g++)h=e[g],this.file(h.fileName,h.decompressed,{binary:!0,optimizedBinaryString:!0,date:h.date,dir:h.dir,comment:h.fileComment.length?h.fileComment:null,createFolders:b.createFolders});return f.zipComment.length&&(this.comment=f.zipComment),this}},{"./base64":1,"./zipEntries":22}],11:[function(a,b){(function(a){"use strict";b.exports=function(b,c){return new a(b,c)},b.exports.test=function(b){return a.isBuffer(b)}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],12:[function(a,b){"use strict";function c(a){this.data=a,this.length=this.data.length,this.index=0}var d=a("./uint8ArrayReader");c.prototype=new d,c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./uint8ArrayReader":18}],13:[function(a,b){"use strict";var c=a("./support"),d=a("./utils"),e=a("./crc32"),f=a("./signature"),g=a("./defaults"),h=a("./base64"),i=a("./compressions"),j=a("./compressedObject"),k=a("./nodeBuffer"),l=a("./utf8"),m=a("./stringWriter"),n=a("./uint8ArrayWriter"),o=function(a){if(a._data instanceof j&&(a._data=a._data.getContent(),a.options.binary=!0,a.options.base64=!1,"uint8array"===d.getTypeOf(a._data))){var b=a._data;a._data=new Uint8Array(b.length),0!==b.length&&a._data.set(b,0)}return a._data},p=function(a){var b=o(a),e=d.getTypeOf(b);return"string"===e?!a.options.binary&&c.nodebuffer?k(b,"utf-8"):a.asBinary():b},q=function(a){var b=o(this);return null===b||"undefined"==typeof b?"":(this.options.base64&&(b=h.decode(b)),b=a&&this.options.binary?A.utf8decode(b):d.transformTo("string",b),a||this.options.binary||(b=d.transformTo("string",A.utf8encode(b))),b)},r=function(a,b,c){this.name=a,this.dir=c.dir,this.date=c.date,this.comment=c.comment,this._data=b,this.options=c,this._initialMetadata={dir:c.dir,date:c.date}};r.prototype={asText:function(){return q.call(this,!0)},asBinary:function(){return q.call(this,!1)},asNodeBuffer:function(){var a=p(this);return d.transformTo("nodebuffer",a)},asUint8Array:function(){var a=p(this);return d.transformTo("uint8array",a)},asArrayBuffer:function(){return this.asUint8Array().buffer}};var s=function(a,b){var c,d="";for(c=0;b>c;c++)d+=String.fromCharCode(255&a),a>>>=8;return d},t=function(){var a,b,c={};for(a=0;a<arguments.length;a++)for(b in arguments[a])arguments[a].hasOwnProperty(b)&&"undefined"==typeof c[b]&&(c[b]=arguments[a][b]);return c},u=function(a){return a=a||{},a.base64!==!0||null!==a.binary&&void 0!==a.binary||(a.binary=!0),a=t(a,g),a.date=a.date||new Date,null!==a.compression&&(a.compression=a.compression.toUpperCase()),a},v=function(a,b,c){var e,f=d.getTypeOf(b);if(c=u(c),c.createFolders&&(e=w(a))&&x.call(this,e,!0),c.dir||null===b||"undefined"==typeof b)c.base64=!1,c.binary=!1,b=null;else if("string"===f)c.binary&&!c.base64&&c.optimizedBinaryString!==!0&&(b=d.string2binary(b));else{if(c.base64=!1,c.binary=!0,!(f||b instanceof j))throw new Error("The data of '"+a+"' is in an unsupported format !");"arraybuffer"===f&&(b=d.transformTo("uint8array",b))}var g=new r(a,b,c);return this.files[a]=g,g},w=function(a){"/"==a.slice(-1)&&(a=a.substring(0,a.length-1));var b=a.lastIndexOf("/");return b>0?a.substring(0,b):""},x=function(a,b){return"/"!=a.slice(-1)&&(a+="/"),b="undefined"!=typeof b?b:!1,this.files[a]||v.call(this,a,null,{dir:!0,createFolders:b}),this.files[a]},y=function(a,b){var c,f=new j;return a._data instanceof j?(f.uncompressedSize=a._data.uncompressedSize,f.crc32=a._data.crc32,0===f.uncompressedSize||a.dir?(b=i.STORE,f.compressedContent="",f.crc32=0):a._data.compressionMethod===b.magic?f.compressedContent=a._data.getCompressedContent():(c=a._data.getContent(),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c)))):(c=p(a),(!c||0===c.length||a.dir)&&(b=i.STORE,c=""),f.uncompressedSize=c.length,f.crc32=e(c),f.compressedContent=b.compress(d.transformTo(b.compressInputType,c))),f.compressedSize=f.compressedContent.length,f.compressionMethod=b.magic,f},z=function(a,b,c,g){var h,i,j,k,m=(c.compressedContent,d.transformTo("string",l.utf8encode(b.name))),n=b.comment||"",o=d.transformTo("string",l.utf8encode(n)),p=m.length!==b.name.length,q=o.length!==n.length,r=b.options,t="",u="",v="";j=b._initialMetadata.dir!==b.dir?b.dir:r.dir,k=b._initialMetadata.date!==b.date?b.date:r.date,h=k.getHours(),h<<=6,h|=k.getMinutes(),h<<=5,h|=k.getSeconds()/2,i=k.getFullYear()-1980,i<<=4,i|=k.getMonth()+1,i<<=5,i|=k.getDate(),p&&(u=s(1,1)+s(e(m),4)+m,t+="up"+s(u.length,2)+u),q&&(v=s(1,1)+s(this.crc32(o),4)+o,t+="uc"+s(v.length,2)+v);var w="";w+="\n\x00",w+=p||q?"\x00\b":"\x00\x00",w+=c.compressionMethod,w+=s(h,2),w+=s(i,2),w+=s(c.crc32,4),w+=s(c.compressedSize,4),w+=s(c.uncompressedSize,4),w+=s(m.length,2),w+=s(t.length,2);var x=f.LOCAL_FILE_HEADER+w+m+t,y=f.CENTRAL_FILE_HEADER+"\x00"+w+s(o.length,2)+"\x00\x00\x00\x00"+(j===!0?"\x00\x00\x00":"\x00\x00\x00\x00")+s(g,4)+m+t+o;return{fileRecord:x,dirRecord:y,compressedObject:c}},A={load:function(){throw new Error("Load method is not defined. Is the file jszip-load.js included ?")},filter:function(a){var b,c,d,e,f=[];for(b in this.files)this.files.hasOwnProperty(b)&&(d=this.files[b],e=new r(d.name,d._data,t(d.options)),c=b.slice(this.root.length,b.length),b.slice(0,this.root.length)===this.root&&a(c,e)&&f.push(e));return f},file:function(a,b,c){if(1===arguments.length){if(d.isRegExp(a)){var e=a;return this.filter(function(a,b){return!b.dir&&e.test(a)})}return this.filter(function(b,c){return!c.dir&&b===a})[0]||null}return a=this.root+a,v.call(this,a,b,c),this},folder:function(a){if(!a)return this;if(d.isRegExp(a))return this.filter(function(b,c){return c.dir&&a.test(b)});var b=this.root+a,c=x.call(this,b),e=this.clone();return e.root=c.name,e},remove:function(a){a=this.root+a;var b=this.files[a];if(b||("/"!=a.slice(-1)&&(a+="/"),b=this.files[a]),b&&!b.dir)delete this.files[a];else for(var c=this.filter(function(b,c){return c.name.slice(0,a.length)===a}),d=0;d<c.length;d++)delete this.files[c[d].name];return this},generate:function(a){a=t(a||{},{base64:!0,compression:"STORE",type:"base64",comment:null}),d.checkSupport(a.type);var b,c,e=[],g=0,j=0,k=d.transformTo("string",this.utf8encode(a.comment||this.comment||""));for(var l in this.files)if(this.files.hasOwnProperty(l)){var o=this.files[l],p=o.options.compression||a.compression.toUpperCase(),q=i[p];if(!q)throw new Error(p+" is not a valid compression method !");var r=y.call(this,o,q),u=z.call(this,l,o,r,g);g+=u.fileRecord.length+r.compressedSize,j+=u.dirRecord.length,e.push(u)}var v="";v=f.CENTRAL_DIRECTORY_END+"\x00\x00\x00\x00"+s(e.length,2)+s(e.length,2)+s(j,4)+s(g,4)+s(k.length,2)+k;var w=a.type.toLowerCase();for(b="uint8array"===w||"arraybuffer"===w||"blob"===w||"nodebuffer"===w?new n(g+j+v.length):new m(g+j+v.length),c=0;c<e.length;c++)b.append(e[c].fileRecord),b.append(e[c].compressedObject.compressedContent);for(c=0;c<e.length;c++)b.append(e[c].dirRecord);b.append(v);var x=b.finalize();switch(a.type.toLowerCase()){case"uint8array":case"arraybuffer":case"nodebuffer":return d.transformTo(a.type.toLowerCase(),x);case"blob":return d.arrayBuffer2Blob(d.transformTo("arraybuffer",x));case"base64":return a.base64?h.encode(x):x;default:return x}},crc32:function(a,b){return e(a,b)},utf8encode:function(a){return d.transformTo("string",l.utf8encode(a))},utf8decode:function(a){return l.utf8decode(a)}};b.exports=A},{"./base64":1,"./compressedObject":2,"./compressions":3,"./crc32":4,"./defaults":6,"./nodeBuffer":11,"./signature":14,"./stringWriter":16,"./support":17,"./uint8ArrayWriter":19,"./utf8":20,"./utils":21}],14:[function(a,b,c){"use strict";c.LOCAL_FILE_HEADER="PK",c.CENTRAL_FILE_HEADER="PK",c.CENTRAL_DIRECTORY_END="PK",c.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",c.ZIP64_CENTRAL_DIRECTORY_END="PK",c.DATA_DESCRIPTOR="PK\b"},{}],15:[function(a,b){"use strict";function c(a,b){this.data=a,b||(this.data=e.string2binary(this.data)),this.length=this.data.length,this.index=0}var d=a("./dataReader"),e=a("./utils");c.prototype=new d,c.prototype.byteAt=function(a){return this.data.charCodeAt(a)},c.prototype.lastIndexOfSignature=function(a){return this.data.lastIndexOf(a)},c.prototype.readData=function(a){this.checkOffset(a);var b=this.data.slice(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5,"./utils":21}],16:[function(a,b){"use strict";var c=a("./utils"),d=function(){this.data=[]};d.prototype={append:function(a){a=c.transformTo("string",a),this.data.push(a)},finalize:function(){return this.data.join("")}},b.exports=d},{"./utils":21}],17:[function(a,b,c){(function(a){"use strict";if(c.base64=!0,c.array=!0,c.string=!0,c.arraybuffer="undefined"!=typeof ArrayBuffer&&"undefined"!=typeof Uint8Array,c.nodebuffer="undefined"!=typeof a,c.uint8array="undefined"!=typeof Uint8Array,"undefined"==typeof ArrayBuffer)c.blob=!1;else{var b=new ArrayBuffer(0);try{c.blob=0===new Blob([b],{type:"application/zip"}).size}catch(d){try{var e=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,f=new e;f.append(b),c.blob=0===f.getBlob("application/zip").size}catch(d){c.blob=!1}}}}).call(this,"undefined"!=typeof Buffer?Buffer:void 0)},{}],18:[function(a,b){"use strict";function c(a){a&&(this.data=a,this.length=this.data.length,this.index=0)}var d=a("./dataReader");c.prototype=new d,c.prototype.byteAt=function(a){return this.data[a]},c.prototype.lastIndexOfSignature=function(a){for(var b=a.charCodeAt(0),c=a.charCodeAt(1),d=a.charCodeAt(2),e=a.charCodeAt(3),f=this.length-4;f>=0;--f)if(this.data[f]===b&&this.data[f+1]===c&&this.data[f+2]===d&&this.data[f+3]===e)return f;return-1},c.prototype.readData=function(a){if(this.checkOffset(a),0===a)return new Uint8Array(0);var b=this.data.subarray(this.index,this.index+a);return this.index+=a,b},b.exports=c},{"./dataReader":5}],19:[function(a,b){"use strict";var c=a("./utils"),d=function(a){this.data=new Uint8Array(a),this.index=0};d.prototype={append:function(a){0!==a.length&&(a=c.transformTo("uint8array",a),this.data.set(a,this.index),this.index+=a.length)},finalize:function(){return this.data}},b.exports=d},{"./utils":21}],20:[function(a,b,c){"use strict";for(var d=a("./utils"),e=a("./support"),f=a("./nodeBuffer"),g=new Array(256),h=0;256>h;h++)g[h]=h>=252?6:h>=248?5:h>=240?4:h>=224?3:h>=192?2:1;g[254]=g[254]=1;var i=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=e.uint8array?new Uint8Array(i):new Array(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},j=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+g[a[c]]>b?c:b},k=function(a){var b,c,e,f,h=a.length,i=new Array(2*h);for(c=0,b=0;h>b;)if(e=a[b++],128>e)i[c++]=e;else if(f=g[e],f>4)i[c++]=65533,b+=f-1;else{for(e&=2===f?31:3===f?15:7;f>1&&h>b;)e=e<<6|63&a[b++],f--;f>1?i[c++]=65533:65536>e?i[c++]=e:(e-=65536,i[c++]=55296|e>>10&1023,i[c++]=56320|1023&e)}return i.length!==c&&(i.subarray?i=i.subarray(0,c):i.length=c),d.applyFromCharCode(i)};c.utf8encode=function(a){return e.nodebuffer?f(a,"utf-8"):i(a)},c.utf8decode=function(a){if(e.nodebuffer)return d.transformTo("nodebuffer",a).toString("utf-8");a=d.transformTo(e.uint8array?"uint8array":"array",a);for(var b=[],c=0,f=a.length,g=65536;f>c;){var h=j(a,Math.min(c+g,f));b.push(e.uint8array?k(a.subarray(c,h)):k(a.slice(c,h))),c=h}return b.join("")}},{"./nodeBuffer":11,"./support":17,"./utils":21}],21:[function(a,b,c){"use strict";function d(a){return a}function e(a,b){for(var c=0;c<a.length;++c)b[c]=255&a.charCodeAt(c);return b}function f(a){var b=65536,d=[],e=a.length,f=c.getTypeOf(a),g=0,h=!0;try{switch(f){case"uint8array":String.fromCharCode.apply(null,new Uint8Array(0));break;case"nodebuffer":String.fromCharCode.apply(null,j(0))}}catch(i){h=!1}if(!h){for(var k="",l=0;l<a.length;l++)k+=String.fromCharCode(a[l]);return k}for(;e>g&&b>1;)try{d.push("array"===f||"nodebuffer"===f?String.fromCharCode.apply(null,a.slice(g,Math.min(g+b,e))):String.fromCharCode.apply(null,a.subarray(g,Math.min(g+b,e)))),g+=b}catch(i){b=Math.floor(b/2)}return d.join("")}function g(a,b){for(var c=0;c<a.length;c++)b[c]=a[c];return b}var h=a("./support"),i=a("./compressions"),j=a("./nodeBuffer");c.string2binary=function(a){for(var b="",c=0;c<a.length;c++)b+=String.fromCharCode(255&a.charCodeAt(c));return b},c.arrayBuffer2Blob=function(a){c.checkSupport("blob");try{return new Blob([a],{type:"application/zip"})}catch(b){try{var d=window.BlobBuilder||window.WebKitBlobBuilder||window.MozBlobBuilder||window.MSBlobBuilder,e=new d;return e.append(a),e.getBlob("application/zip")}catch(b){throw new Error("Bug : can't construct the Blob.")}}},c.applyFromCharCode=f;var k={};k.string={string:d,array:function(a){return e(a,new Array(a.length))},arraybuffer:function(a){return k.string.uint8array(a).buffer},uint8array:function(a){return e(a,new Uint8Array(a.length))},nodebuffer:function(a){return e(a,j(a.length))}},k.array={string:f,array:d,arraybuffer:function(a){return new Uint8Array(a).buffer},uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(a)}},k.arraybuffer={string:function(a){return f(new Uint8Array(a))},array:function(a){return g(new Uint8Array(a),new Array(a.byteLength))},arraybuffer:d,uint8array:function(a){return new Uint8Array(a)},nodebuffer:function(a){return j(new Uint8Array(a))}},k.uint8array={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return a.buffer},uint8array:d,nodebuffer:function(a){return j(a)}},k.nodebuffer={string:f,array:function(a){return g(a,new Array(a.length))},arraybuffer:function(a){return k.nodebuffer.uint8array(a).buffer},uint8array:function(a){return g(a,new Uint8Array(a.length))},nodebuffer:d},c.transformTo=function(a,b){if(b||(b=""),!a)return b;c.checkSupport(a);var d=c.getTypeOf(b),e=k[d][a](b);return e},c.getTypeOf=function(a){return"string"==typeof a?"string":"[object Array]"===Object.prototype.toString.call(a)?"array":h.nodebuffer&&j.test(a)?"nodebuffer":h.uint8array&&a instanceof Uint8Array?"uint8array":h.arraybuffer&&a instanceof ArrayBuffer?"arraybuffer":void 0},c.checkSupport=function(a){var b=h[a.toLowerCase()];if(!b)throw new Error(a+" is not supported by this browser")},c.MAX_VALUE_16BITS=65535,c.MAX_VALUE_32BITS=-1,c.pretty=function(a){var b,c,d="";for(c=0;c<(a||"").length;c++)b=a.charCodeAt(c),d+="\\x"+(16>b?"0":"")+b.toString(16).toUpperCase();return d},c.findCompression=function(a){for(var b in i)if(i.hasOwnProperty(b)&&i[b].magic===a)return i[b];return null},c.isRegExp=function(a){return"[object RegExp]"===Object.prototype.toString.call(a)}},{"./compressions":3,"./nodeBuffer":11,"./support":17}],22:[function(a,b){"use strict";function c(a,b){this.files=[],this.loadOptions=b,a&&this.load(a)}var d=a("./stringReader"),e=a("./nodeBufferReader"),f=a("./uint8ArrayReader"),g=a("./utils"),h=a("./signature"),i=a("./zipEntry"),j=a("./support"),k=a("./object");c.prototype={checkSignature:function(a){var b=this.reader.readString(4);if(b!==a)throw new Error("Corrupted zip or bug : unexpected signature ("+g.pretty(b)+", expected "+g.pretty(a)+")")},readBlockEndOfCentral:function(){this.diskNumber=this.reader.readInt(2),this.diskWithCentralDirStart=this.reader.readInt(2),this.centralDirRecordsOnThisDisk=this.reader.readInt(2),this.centralDirRecords=this.reader.readInt(2),this.centralDirSize=this.reader.readInt(4),this.centralDirOffset=this.reader.readInt(4),this.zipCommentLength=this.reader.readInt(2),this.zipComment=this.reader.readString(this.zipCommentLength),this.zipComment=k.utf8decode(this.zipComment)},readBlockZip64EndOfCentral:function(){this.zip64EndOfCentralSize=this.reader.readInt(8),this.versionMadeBy=this.reader.readString(2),this.versionNeeded=this.reader.readInt(2),this.diskNumber=this.reader.readInt(4),this.diskWithCentralDirStart=this.reader.readInt(4),this.centralDirRecordsOnThisDisk=this.reader.readInt(8),this.centralDirRecords=this.reader.readInt(8),this.centralDirSize=this.reader.readInt(8),this.centralDirOffset=this.reader.readInt(8),this.zip64ExtensibleData={};for(var a,b,c,d=this.zip64EndOfCentralSize-44,e=0;d>e;)a=this.reader.readInt(2),b=this.reader.readInt(4),c=this.reader.readString(b),this.zip64ExtensibleData[a]={id:a,length:b,value:c}},readBlockZip64EndOfCentralLocator:function(){if(this.diskWithZip64CentralDirStart=this.reader.readInt(4),this.relativeOffsetEndOfZip64CentralDir=this.reader.readInt(8),this.disksCount=this.reader.readInt(4),this.disksCount>1)throw new Error("Multi-volumes zip are not supported")},readLocalFiles:function(){var a,b;for(a=0;a<this.files.length;a++)b=this.files[a],this.reader.setIndex(b.localHeaderOffset),this.checkSignature(h.LOCAL_FILE_HEADER),b.readLocalPart(this.reader),b.handleUTF8()},readCentralDir:function(){var a;for(this.reader.setIndex(this.centralDirOffset);this.reader.readString(4)===h.CENTRAL_FILE_HEADER;)a=new i({zip64:this.zip64},this.loadOptions),a.readCentralPart(this.reader),this.files.push(a)},readEndOfCentral:function(){var a=this.reader.lastIndexOfSignature(h.CENTRAL_DIRECTORY_END);if(-1===a)throw new Error("Corrupted zip : can't find end of central directory");if(this.reader.setIndex(a),this.checkSignature(h.CENTRAL_DIRECTORY_END),this.readBlockEndOfCentral(),this.diskNumber===g.MAX_VALUE_16BITS||this.diskWithCentralDirStart===g.MAX_VALUE_16BITS||this.centralDirRecordsOnThisDisk===g.MAX_VALUE_16BITS||this.centralDirRecords===g.MAX_VALUE_16BITS||this.centralDirSize===g.MAX_VALUE_32BITS||this.centralDirOffset===g.MAX_VALUE_32BITS){if(this.zip64=!0,a=this.reader.lastIndexOfSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),-1===a)throw new Error("Corrupted zip : can't find the ZIP64 end of central directory locator");this.reader.setIndex(a),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_LOCATOR),this.readBlockZip64EndOfCentralLocator(),this.reader.setIndex(this.relativeOffsetEndOfZip64CentralDir),this.checkSignature(h.ZIP64_CENTRAL_DIRECTORY_END),this.readBlockZip64EndOfCentral()}},prepareReader:function(a){var b=g.getTypeOf(a);this.reader="string"!==b||j.uint8array?"nodebuffer"===b?new e(a):new f(g.transformTo("uint8array",a)):new d(a,this.loadOptions.optimizedBinaryString)},load:function(a){this.prepareReader(a),this.readEndOfCentral(),this.readCentralDir(),this.readLocalFiles()}},b.exports=c},{"./nodeBufferReader":12,"./object":13,"./signature":14,"./stringReader":15,"./support":17,"./uint8ArrayReader":18,"./utils":21,"./zipEntry":23}],23:[function(a,b){"use strict";function c(a,b){this.options=a,this.loadOptions=b}var d=a("./stringReader"),e=a("./utils"),f=a("./compressedObject"),g=a("./object");c.prototype={isEncrypted:function(){return 1===(1&this.bitFlag)},useUTF8:function(){return 2048===(2048&this.bitFlag)},prepareCompressedContent:function(a,b,c){return function(){var d=a.index;a.setIndex(b);var e=a.readData(c);return a.setIndex(d),e}},prepareContent:function(a,b,c,d,f){return function(){var a=e.transformTo(d.uncompressInputType,this.getCompressedContent()),b=d.uncompress(a);if(b.length!==f)throw new Error("Bug : uncompressed data size mismatch");return b}},readLocalPart:function(a){var b,c;if(a.skip(22),this.fileNameLength=a.readInt(2),c=a.readInt(2),this.fileName=a.readString(this.fileNameLength),a.skip(c),-1==this.compressedSize||-1==this.uncompressedSize)throw new Error("Bug or corrupted zip : didn't get enough informations from the central directory (compressedSize == -1 || uncompressedSize == -1)");if(b=e.findCompression(this.compressionMethod),null===b)throw new Error("Corrupted zip : compression "+e.pretty(this.compressionMethod)+" unknown (inner file : "+this.fileName+")");if(this.decompressed=new f,this.decompressed.compressedSize=this.compressedSize,this.decompressed.uncompressedSize=this.uncompressedSize,this.decompressed.crc32=this.crc32,this.decompressed.compressionMethod=this.compressionMethod,this.decompressed.getCompressedContent=this.prepareCompressedContent(a,a.index,this.compressedSize,b),this.decompressed.getContent=this.prepareContent(a,a.index,this.compressedSize,b,this.uncompressedSize),this.loadOptions.checkCRC32&&(this.decompressed=e.transformTo("string",this.decompressed.getContent()),g.crc32(this.decompressed)!==this.crc32))throw new Error("Corrupted zip : CRC32 mismatch")},readCentralPart:function(a){if(this.versionMadeBy=a.readString(2),this.versionNeeded=a.readInt(2),this.bitFlag=a.readInt(2),this.compressionMethod=a.readString(2),this.date=a.readDate(),this.crc32=a.readInt(4),this.compressedSize=a.readInt(4),this.uncompressedSize=a.readInt(4),this.fileNameLength=a.readInt(2),this.extraFieldsLength=a.readInt(2),this.fileCommentLength=a.readInt(2),this.diskNumberStart=a.readInt(2),this.internalFileAttributes=a.readInt(2),this.externalFileAttributes=a.readInt(4),this.localHeaderOffset=a.readInt(4),this.isEncrypted())throw new Error("Encrypted zip are not supported");this.fileName=a.readString(this.fileNameLength),this.readExtraFields(a),this.parseZIP64ExtraField(a),this.fileComment=a.readString(this.fileCommentLength),this.dir=16&this.externalFileAttributes?!0:!1},parseZIP64ExtraField:function(){if(this.extraFields[1]){var a=new d(this.extraFields[1].value);this.uncompressedSize===e.MAX_VALUE_32BITS&&(this.uncompressedSize=a.readInt(8)),this.compressedSize===e.MAX_VALUE_32BITS&&(this.compressedSize=a.readInt(8)),this.localHeaderOffset===e.MAX_VALUE_32BITS&&(this.localHeaderOffset=a.readInt(8)),this.diskNumberStart===e.MAX_VALUE_32BITS&&(this.diskNumberStart=a.readInt(4))}},readExtraFields:function(a){var b,c,d,e=a.index;for(this.extraFields=this.extraFields||{};a.index<e+this.extraFieldsLength;)b=a.readInt(2),c=a.readInt(2),d=a.readString(c),this.extraFields[b]={id:b,length:c,value:d}},handleUTF8:function(){if(this.useUTF8())this.fileName=g.utf8decode(this.fileName),this.fileComment=g.utf8decode(this.fileComment);else{var a=this.findExtraFieldUnicodePath();null!==a&&(this.fileName=a);var b=this.findExtraFieldUnicodeComment();null!==b&&(this.fileComment=b)}},findExtraFieldUnicodePath:function(){var a=this.extraFields[28789];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileName)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null},findExtraFieldUnicodeComment:function(){var a=this.extraFields[25461];if(a){var b=new d(a.value);return 1!==b.readInt(1)?null:g.crc32(this.fileComment)!==b.readInt(4)?null:g.utf8decode(b.readString(a.length-5))}return null}},b.exports=c},{"./compressedObject":2,"./object":13,"./stringReader":15,"./utils":21}],24:[function(a,b){"use strict";var c=a("./lib/utils/common").assign,d=a("./lib/deflate"),e=a("./lib/inflate"),f=a("./lib/zlib/constants"),g={};c(g,d,e,f),b.exports=g},{"./lib/deflate":25,"./lib/inflate":26,"./lib/utils/common":27,"./lib/zlib/constants":30}],25:[function(a,b,c){"use strict";function d(a,b){var c=new s(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}function f(a,b){return b=b||{},b.gzip=!0,d(a,b)}var g=a("./zlib/deflate.js"),h=a("./utils/common"),i=a("./utils/strings"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=0,m=4,n=0,o=1,p=-1,q=0,r=8,s=function(a){this.options=h.assign({level:p,method:r,chunkSize:16384,windowBits:15,memLevel:8,strategy:q,to:""},a||{});var b=this.options;b.raw&&b.windowBits>0?b.windowBits=-b.windowBits:b.gzip&&b.windowBits>0&&b.windowBits<16&&(b.windowBits+=16),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=g.deflateInit2(this.strm,b.level,b.method,b.windowBits,b.memLevel,b.strategy);if(c!==n)throw new Error(j[c]);b.header&&g.deflateSetHeader(this.strm,b.header)};s.prototype.push=function(a,b){var c,d,e=this.strm,f=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?m:l,e.input="string"==typeof a?i.string2buf(a):a,e.next_in=0,e.avail_in=e.input.length;do{if(0===e.avail_out&&(e.output=new h.Buf8(f),e.next_out=0,e.avail_out=f),c=g.deflate(e,d),c!==o&&c!==n)return this.onEnd(c),this.ended=!0,!1;(0===e.avail_out||0===e.avail_in&&d===m)&&this.onData("string"===this.options.to?i.buf2binstring(h.shrinkBuf(e.output,e.next_out)):h.shrinkBuf(e.output,e.next_out))}while((e.avail_in>0||0===e.avail_out)&&c!==o);return d===m?(c=g.deflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===n):!0},s.prototype.onData=function(a){this.chunks.push(a)},s.prototype.onEnd=function(a){a===n&&(this.result="string"===this.options.to?this.chunks.join(""):h.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Deflate=s,c.deflate=d,c.deflateRaw=e,c.gzip=f},{"./utils/common":27,"./utils/strings":28,"./zlib/deflate.js":32,"./zlib/messages":37,"./zlib/zstream":39}],26:[function(a,b,c){"use strict";function d(a,b){var c=new m(b);if(c.push(a,!0),c.err)throw c.msg;return c.result}function e(a,b){return b=b||{},b.raw=!0,d(a,b)}var f=a("./zlib/inflate.js"),g=a("./utils/common"),h=a("./utils/strings"),i=a("./zlib/constants"),j=a("./zlib/messages"),k=a("./zlib/zstream"),l=a("./zlib/gzheader"),m=function(a){this.options=g.assign({chunkSize:16384,windowBits:0,to:""},a||{});var b=this.options;b.raw&&b.windowBits>=0&&b.windowBits<16&&(b.windowBits=-b.windowBits,0===b.windowBits&&(b.windowBits=-15)),!(b.windowBits>=0&&b.windowBits<16)||a&&a.windowBits||(b.windowBits+=32),b.windowBits>15&&b.windowBits<48&&0===(15&b.windowBits)&&(b.windowBits|=15),this.err=0,this.msg="",this.ended=!1,this.chunks=[],this.strm=new k,this.strm.avail_out=0;var c=f.inflateInit2(this.strm,b.windowBits);if(c!==i.Z_OK)throw new Error(j[c]);this.header=new l,f.inflateGetHeader(this.strm,this.header)};m.prototype.push=function(a,b){var c,d,e,j,k,l=this.strm,m=this.options.chunkSize;if(this.ended)return!1;d=b===~~b?b:b===!0?i.Z_FINISH:i.Z_NO_FLUSH,l.input="string"==typeof a?h.binstring2buf(a):a,l.next_in=0,l.avail_in=l.input.length;do{if(0===l.avail_out&&(l.output=new g.Buf8(m),l.next_out=0,l.avail_out=m),c=f.inflate(l,i.Z_NO_FLUSH),c!==i.Z_STREAM_END&&c!==i.Z_OK)return this.onEnd(c),this.ended=!0,!1;l.next_out&&(0===l.avail_out||c===i.Z_STREAM_END||0===l.avail_in&&d===i.Z_FINISH)&&("string"===this.options.to?(e=h.utf8border(l.output,l.next_out),j=l.next_out-e,k=h.buf2string(l.output,e),l.next_out=j,l.avail_out=m-j,j&&g.arraySet(l.output,l.output,e,j,0),this.onData(k)):this.onData(g.shrinkBuf(l.output,l.next_out)))}while(l.avail_in>0&&c!==i.Z_STREAM_END);return c===i.Z_STREAM_END&&(d=i.Z_FINISH),d===i.Z_FINISH?(c=f.inflateEnd(this.strm),this.onEnd(c),this.ended=!0,c===i.Z_OK):!0},m.prototype.onData=function(a){this.chunks.push(a)},m.prototype.onEnd=function(a){a===i.Z_OK&&(this.result="string"===this.options.to?this.chunks.join(""):g.flattenChunks(this.chunks)),this.chunks=[],this.err=a,this.msg=this.strm.msg},c.Inflate=m,c.inflate=d,c.inflateRaw=e,c.ungzip=d},{"./utils/common":27,"./utils/strings":28,"./zlib/constants":30,"./zlib/gzheader":33,"./zlib/inflate.js":35,"./zlib/messages":37,"./zlib/zstream":39}],27:[function(a,b,c){"use strict";var d="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Int32Array;c.assign=function(a){for(var b=Array.prototype.slice.call(arguments,1);b.length;){var c=b.shift();if(c){if("object"!=typeof c)throw new TypeError(c+"must be non-object");for(var d in c)c.hasOwnProperty(d)&&(a[d]=c[d])}}return a},c.shrinkBuf=function(a,b){return a.length===b?a:a.subarray?a.subarray(0,b):(a.length=b,a)};var e={arraySet:function(a,b,c,d,e){if(b.subarray&&a.subarray)return void a.set(b.subarray(c,c+d),e);for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){var b,c,d,e,f,g;for(d=0,b=0,c=a.length;c>b;b++)d+=a[b].length;for(g=new Uint8Array(d),e=0,b=0,c=a.length;c>b;b++)f=a[b],g.set(f,e),e+=f.length;return g}},f={arraySet:function(a,b,c,d,e){for(var f=0;d>f;f++)a[e+f]=b[c+f]},flattenChunks:function(a){return[].concat.apply([],a)}};c.setTyped=function(a){a?(c.Buf8=Uint8Array,c.Buf16=Uint16Array,c.Buf32=Int32Array,c.assign(c,e)):(c.Buf8=Array,c.Buf16=Array,c.Buf32=Array,c.assign(c,f))},c.setTyped(d)},{}],28:[function(a,b,c){"use strict";function d(a,b){if(65537>b&&(a.subarray&&g||!a.subarray&&f))return String.fromCharCode.apply(null,e.shrinkBuf(a,b));for(var c="",d=0;b>d;d++)c+=String.fromCharCode(a[d]);return c}var e=a("./common"),f=!0,g=!0;try{String.fromCharCode.apply(null,[0])}catch(h){f=!1}try{String.fromCharCode.apply(null,new Uint8Array(1))}catch(h){g=!1}for(var i=new e.Buf8(256),j=0;256>j;j++)i[j]=j>=252?6:j>=248?5:j>=240?4:j>=224?3:j>=192?2:1;i[254]=i[254]=1,c.string2buf=function(a){var b,c,d,f,g,h=a.length,i=0;for(f=0;h>f;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),i+=128>c?1:2048>c?2:65536>c?3:4;for(b=new e.Buf8(i),g=0,f=0;i>g;f++)c=a.charCodeAt(f),55296===(64512&c)&&h>f+1&&(d=a.charCodeAt(f+1),56320===(64512&d)&&(c=65536+(c-55296<<10)+(d-56320),f++)),128>c?b[g++]=c:2048>c?(b[g++]=192|c>>>6,b[g++]=128|63&c):65536>c?(b[g++]=224|c>>>12,b[g++]=128|c>>>6&63,b[g++]=128|63&c):(b[g++]=240|c>>>18,b[g++]=128|c>>>12&63,b[g++]=128|c>>>6&63,b[g++]=128|63&c);return b},c.buf2binstring=function(a){return d(a,a.length)},c.binstring2buf=function(a){for(var b=new e.Buf8(a.length),c=0,d=b.length;d>c;c++)b[c]=a.charCodeAt(c);return b},c.buf2string=function(a,b){var c,e,f,g,h=b||a.length,j=new Array(2*h);for(e=0,c=0;h>c;)if(f=a[c++],128>f)j[e++]=f;else if(g=i[f],g>4)j[e++]=65533,c+=g-1;else{for(f&=2===g?31:3===g?15:7;g>1&&h>c;)f=f<<6|63&a[c++],g--;g>1?j[e++]=65533:65536>f?j[e++]=f:(f-=65536,j[e++]=55296|f>>10&1023,j[e++]=56320|1023&f)}return d(j,e)},c.utf8border=function(a,b){var c;for(b=b||a.length,b>a.length&&(b=a.length),c=b-1;c>=0&&128===(192&a[c]);)c--;return 0>c?b:0===c?b:c+i[a[c]]>b?c:b}},{"./common":27}],29:[function(a,b){"use strict";function c(a,b,c,d){for(var e=65535&a|0,f=a>>>16&65535|0,g=0;0!==c;){g=c>2e3?2e3:c,c-=g;do e=e+b[d++]|0,f=f+e|0;while(--g);e%=65521,f%=65521}return e|f<<16|0}b.exports=c},{}],30:[function(a,b){b.exports={Z_NO_FLUSH:0,Z_PARTIAL_FLUSH:1,Z_SYNC_FLUSH:2,Z_FULL_FLUSH:3,Z_FINISH:4,Z_BLOCK:5,Z_TREES:6,Z_OK:0,Z_STREAM_END:1,Z_NEED_DICT:2,Z_ERRNO:-1,Z_STREAM_ERROR:-2,Z_DATA_ERROR:-3,Z_BUF_ERROR:-5,Z_NO_COMPRESSION:0,Z_BEST_SPEED:1,Z_BEST_COMPRESSION:9,Z_DEFAULT_COMPRESSION:-1,Z_FILTERED:1,Z_HUFFMAN_ONLY:2,Z_RLE:3,Z_FIXED:4,Z_DEFAULT_STRATEGY:0,Z_BINARY:0,Z_TEXT:1,Z_UNKNOWN:2,Z_DEFLATED:8}},{}],31:[function(a,b){"use strict";function c(){for(var a,b=[],c=0;256>c;c++){a=c;for(var d=0;8>d;d++)a=1&a?3988292384^a>>>1:a>>>1;b[c]=a}return b}function d(a,b,c,d){var f=e,g=d+c;a=-1^a;for(var h=d;g>h;h++)a=a>>>8^f[255&(a^b[h])];return-1^a}var e=c();b.exports=d},{}],32:[function(a,b,c){"use strict";function d(a,b){return a.msg=G[b],b}function e(a){return(a<<1)-(a>4?9:0)}function f(a){for(var b=a.length;--b>=0;)a[b]=0}function g(a){var b=a.state,c=b.pending;c>a.avail_out&&(c=a.avail_out),0!==c&&(C.arraySet(a.output,b.pending_buf,b.pending_out,c,a.next_out),a.next_out+=c,b.pending_out+=c,a.total_out+=c,a.avail_out-=c,b.pending-=c,0===b.pending&&(b.pending_out=0))}function h(a,b){D._tr_flush_block(a,a.block_start>=0?a.block_start:-1,a.strstart-a.block_start,b),a.block_start=a.strstart,g(a.strm)}function i(a,b){a.pending_buf[a.pending++]=b}function j(a,b){a.pending_buf[a.pending++]=b>>>8&255,a.pending_buf[a.pending++]=255&b}function k(a,b,c,d){var e=a.avail_in;return e>d&&(e=d),0===e?0:(a.avail_in-=e,C.arraySet(b,a.input,a.next_in,e,c),1===a.state.wrap?a.adler=E(a.adler,b,e,c):2===a.state.wrap&&(a.adler=F(a.adler,b,e,c)),a.next_in+=e,a.total_in+=e,e)}function l(a,b){var c,d,e=a.max_chain_length,f=a.strstart,g=a.prev_length,h=a.nice_match,i=a.strstart>a.w_size-jb?a.strstart-(a.w_size-jb):0,j=a.window,k=a.w_mask,l=a.prev,m=a.strstart+ib,n=j[f+g-1],o=j[f+g];a.prev_length>=a.good_match&&(e>>=2),h>a.lookahead&&(h=a.lookahead);do if(c=b,j[c+g]===o&&j[c+g-1]===n&&j[c]===j[f]&&j[++c]===j[f+1]){f+=2,c++;do;while(j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&j[++f]===j[++c]&&m>f);if(d=ib-(m-f),f=m-ib,d>g){if(a.match_start=b,g=d,d>=h)break;n=j[f+g-1],o=j[f+g]}}while((b=l[b&k])>i&&0!==--e);return g<=a.lookahead?g:a.lookahead}function m(a){var b,c,d,e,f,g=a.w_size;do{if(e=a.window_size-a.lookahead-a.strstart,a.strstart>=g+(g-jb)){C.arraySet(a.window,a.window,g,g,0),a.match_start-=g,a.strstart-=g,a.block_start-=g,c=a.hash_size,b=c;do d=a.head[--b],a.head[b]=d>=g?d-g:0;while(--c);c=g,b=c;do d=a.prev[--b],a.prev[b]=d>=g?d-g:0;while(--c);e+=g}if(0===a.strm.avail_in)break;if(c=k(a.strm,a.window,a.strstart+a.lookahead,e),a.lookahead+=c,a.lookahead+a.insert>=hb)for(f=a.strstart-a.insert,a.ins_h=a.window[f],a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+1])&a.hash_mask;a.insert&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[f+hb-1])&a.hash_mask,a.prev[f&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=f,f++,a.insert--,!(a.lookahead+a.insert<hb)););}while(a.lookahead<jb&&0!==a.strm.avail_in)}function n(a,b){var c=65535;for(c>a.pending_buf_size-5&&(c=a.pending_buf_size-5);;){if(a.lookahead<=1){if(m(a),0===a.lookahead&&b===H)return sb;if(0===a.lookahead)break}a.strstart+=a.lookahead,a.lookahead=0;var d=a.block_start+c;if((0===a.strstart||a.strstart>=d)&&(a.lookahead=a.strstart-d,a.strstart=d,h(a,!1),0===a.strm.avail_out))return sb;if(a.strstart-a.block_start>=a.w_size-jb&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.strstart>a.block_start&&(h(a,!1),0===a.strm.avail_out)?sb:sb}function o(a,b){for(var c,d;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),0!==c&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c)),a.match_length>=hb)if(d=D._tr_tally(a,a.strstart-a.match_start,a.match_length-hb),a.lookahead-=a.match_length,a.match_length<=a.max_lazy_match&&a.lookahead>=hb){a.match_length--;do a.strstart++,a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart;while(0!==--a.match_length);a.strstart++}else a.strstart+=a.match_length,a.match_length=0,a.ins_h=a.window[a.strstart],a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+1])&a.hash_mask;else d=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++;if(d&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function p(a,b){for(var c,d,e;;){if(a.lookahead<jb){if(m(a),a.lookahead<jb&&b===H)return sb;if(0===a.lookahead)break}if(c=0,a.lookahead>=hb&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart),a.prev_length=a.match_length,a.prev_match=a.match_start,a.match_length=hb-1,0!==c&&a.prev_length<a.max_lazy_match&&a.strstart-c<=a.w_size-jb&&(a.match_length=l(a,c),a.match_length<=5&&(a.strategy===S||a.match_length===hb&&a.strstart-a.match_start>4096)&&(a.match_length=hb-1)),a.prev_length>=hb&&a.match_length<=a.prev_length){e=a.strstart+a.lookahead-hb,d=D._tr_tally(a,a.strstart-1-a.prev_match,a.prev_length-hb),a.lookahead-=a.prev_length-1,a.prev_length-=2;do++a.strstart<=e&&(a.ins_h=(a.ins_h<<a.hash_shift^a.window[a.strstart+hb-1])&a.hash_mask,c=a.prev[a.strstart&a.w_mask]=a.head[a.ins_h],a.head[a.ins_h]=a.strstart);while(0!==--a.prev_length);if(a.match_available=0,a.match_length=hb-1,a.strstart++,d&&(h(a,!1),0===a.strm.avail_out))return sb}else if(a.match_available){if(d=D._tr_tally(a,0,a.window[a.strstart-1]),d&&h(a,!1),a.strstart++,a.lookahead--,0===a.strm.avail_out)return sb}else a.match_available=1,a.strstart++,a.lookahead--}return a.match_available&&(d=D._tr_tally(a,0,a.window[a.strstart-1]),a.match_available=0),a.insert=a.strstart<hb-1?a.strstart:hb-1,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function q(a,b){for(var c,d,e,f,g=a.window;;){if(a.lookahead<=ib){if(m(a),a.lookahead<=ib&&b===H)return sb;if(0===a.lookahead)break}if(a.match_length=0,a.lookahead>=hb&&a.strstart>0&&(e=a.strstart-1,d=g[e],d===g[++e]&&d===g[++e]&&d===g[++e])){f=a.strstart+ib;do;while(d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&d===g[++e]&&f>e);a.match_length=ib-(f-e),a.match_length>a.lookahead&&(a.match_length=a.lookahead)}if(a.match_length>=hb?(c=D._tr_tally(a,1,a.match_length-hb),a.lookahead-=a.match_length,a.strstart+=a.match_length,a.match_length=0):(c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++),c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function r(a,b){for(var c;;){if(0===a.lookahead&&(m(a),0===a.lookahead)){if(b===H)return sb;break}if(a.match_length=0,c=D._tr_tally(a,0,a.window[a.strstart]),a.lookahead--,a.strstart++,c&&(h(a,!1),0===a.strm.avail_out))return sb}return a.insert=0,b===K?(h(a,!0),0===a.strm.avail_out?ub:vb):a.last_lit&&(h(a,!1),0===a.strm.avail_out)?sb:tb}function s(a){a.window_size=2*a.w_size,f(a.head),a.max_lazy_match=B[a.level].max_lazy,a.good_match=B[a.level].good_length,a.nice_match=B[a.level].nice_length,a.max_chain_length=B[a.level].max_chain,a.strstart=0,a.block_start=0,a.lookahead=0,a.insert=0,a.match_length=a.prev_length=hb-1,a.match_available=0,a.ins_h=0}function t(){this.strm=null,this.status=0,this.pending_buf=null,this.pending_buf_size=0,this.pending_out=0,this.pending=0,this.wrap=0,this.gzhead=null,this.gzindex=0,this.method=Y,this.last_flush=-1,this.w_size=0,this.w_bits=0,this.w_mask=0,this.window=null,this.window_size=0,this.prev=null,this.head=null,this.ins_h=0,this.hash_size=0,this.hash_bits=0,this.hash_mask=0,this.hash_shift=0,this.block_start=0,this.match_length=0,this.prev_match=0,this.match_available=0,this.strstart=0,this.match_start=0,this.lookahead=0,this.prev_length=0,this.max_chain_length=0,this.max_lazy_match=0,this.level=0,this.strategy=0,this.good_match=0,this.nice_match=0,this.dyn_ltree=new C.Buf16(2*fb),this.dyn_dtree=new C.Buf16(2*(2*db+1)),this.bl_tree=new C.Buf16(2*(2*eb+1)),f(this.dyn_ltree),f(this.dyn_dtree),f(this.bl_tree),this.l_desc=null,this.d_desc=null,this.bl_desc=null,this.bl_count=new C.Buf16(gb+1),this.heap=new C.Buf16(2*cb+1),f(this.heap),this.heap_len=0,this.heap_max=0,this.depth=new C.Buf16(2*cb+1),f(this.depth),this.l_buf=0,this.lit_bufsize=0,this.last_lit=0,this.d_buf=0,this.opt_len=0,this.static_len=0,this.matches=0,this.insert=0,this.bi_buf=0,this.bi_valid=0}function u(a){var b;return a&&a.state?(a.total_in=a.total_out=0,a.data_type=X,b=a.state,b.pending=0,b.pending_out=0,b.wrap<0&&(b.wrap=-b.wrap),b.status=b.wrap?lb:qb,a.adler=2===b.wrap?0:1,b.last_flush=H,D._tr_init(b),M):d(a,O)}function v(a){var b=u(a);return b===M&&s(a.state),b}function w(a,b){return a&&a.state?2!==a.state.wrap?O:(a.state.gzhead=b,M):O}function x(a,b,c,e,f,g){if(!a)return O;var h=1;if(b===R&&(b=6),0>e?(h=0,e=-e):e>15&&(h=2,e-=16),1>f||f>Z||c!==Y||8>e||e>15||0>b||b>9||0>g||g>V)return d(a,O);8===e&&(e=9);var i=new t;return a.state=i,i.strm=a,i.wrap=h,i.gzhead=null,i.w_bits=e,i.w_size=1<<i.w_bits,i.w_mask=i.w_size-1,i.hash_bits=f+7,i.hash_size=1<<i.hash_bits,i.hash_mask=i.hash_size-1,i.hash_shift=~~((i.hash_bits+hb-1)/hb),i.window=new C.Buf8(2*i.w_size),i.head=new C.Buf16(i.hash_size),i.prev=new C.Buf16(i.w_size),i.lit_bufsize=1<<f+6,i.pending_buf_size=4*i.lit_bufsize,i.pending_buf=new C.Buf8(i.pending_buf_size),i.d_buf=i.lit_bufsize>>1,i.l_buf=3*i.lit_bufsize,i.level=b,i.strategy=g,i.method=c,v(a)}function y(a,b){return x(a,b,Y,$,_,W)}function z(a,b){var c,h,k,l;if(!a||!a.state||b>L||0>b)return a?d(a,O):O;if(h=a.state,!a.output||!a.input&&0!==a.avail_in||h.status===rb&&b!==K)return d(a,0===a.avail_out?Q:O);if(h.strm=a,c=h.last_flush,h.last_flush=b,h.status===lb)if(2===h.wrap)a.adler=0,i(h,31),i(h,139),i(h,8),h.gzhead?(i(h,(h.gzhead.text?1:0)+(h.gzhead.hcrc?2:0)+(h.gzhead.extra?4:0)+(h.gzhead.name?8:0)+(h.gzhead.comment?16:0)),i(h,255&h.gzhead.time),i(h,h.gzhead.time>>8&255),i(h,h.gzhead.time>>16&255),i(h,h.gzhead.time>>24&255),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,255&h.gzhead.os),h.gzhead.extra&&h.gzhead.extra.length&&(i(h,255&h.gzhead.extra.length),i(h,h.gzhead.extra.length>>8&255)),h.gzhead.hcrc&&(a.adler=F(a.adler,h.pending_buf,h.pending,0)),h.gzindex=0,h.status=mb):(i(h,0),i(h,0),i(h,0),i(h,0),i(h,0),i(h,9===h.level?2:h.strategy>=T||h.level<2?4:0),i(h,wb),h.status=qb);else{var m=Y+(h.w_bits-8<<4)<<8,n=-1;n=h.strategy>=T||h.level<2?0:h.level<6?1:6===h.level?2:3,m|=n<<6,0!==h.strstart&&(m|=kb),m+=31-m%31,h.status=qb,j(h,m),0!==h.strstart&&(j(h,a.adler>>>16),j(h,65535&a.adler)),a.adler=1}if(h.status===mb)if(h.gzhead.extra){for(k=h.pending;h.gzindex<(65535&h.gzhead.extra.length)&&(h.pending!==h.pending_buf_size||(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending!==h.pending_buf_size));)i(h,255&h.gzhead.extra[h.gzindex]),h.gzindex++;h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),h.gzindex===h.gzhead.extra.length&&(h.gzindex=0,h.status=nb)}else h.status=nb;if(h.status===nb)if(h.gzhead.name){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.name.length?255&h.gzhead.name.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.gzindex=0,h.status=ob)}else h.status=ob;if(h.status===ob)if(h.gzhead.comment){k=h.pending;do{if(h.pending===h.pending_buf_size&&(h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),g(a),k=h.pending,h.pending===h.pending_buf_size)){l=1;break}l=h.gzindex<h.gzhead.comment.length?255&h.gzhead.comment.charCodeAt(h.gzindex++):0,i(h,l)}while(0!==l);h.gzhead.hcrc&&h.pending>k&&(a.adler=F(a.adler,h.pending_buf,h.pending-k,k)),0===l&&(h.status=pb)}else h.status=pb;if(h.status===pb&&(h.gzhead.hcrc?(h.pending+2>h.pending_buf_size&&g(a),h.pending+2<=h.pending_buf_size&&(i(h,255&a.adler),i(h,a.adler>>8&255),a.adler=0,h.status=qb)):h.status=qb),0!==h.pending){if(g(a),0===a.avail_out)return h.last_flush=-1,M}else if(0===a.avail_in&&e(b)<=e(c)&&b!==K)return d(a,Q);if(h.status===rb&&0!==a.avail_in)return d(a,Q);if(0!==a.avail_in||0!==h.lookahead||b!==H&&h.status!==rb){var o=h.strategy===T?r(h,b):h.strategy===U?q(h,b):B[h.level].func(h,b);if((o===ub||o===vb)&&(h.status=rb),o===sb||o===ub)return 0===a.avail_out&&(h.last_flush=-1),M;if(o===tb&&(b===I?D._tr_align(h):b!==L&&(D._tr_stored_block(h,0,0,!1),b===J&&(f(h.head),0===h.lookahead&&(h.strstart=0,h.block_start=0,h.insert=0))),g(a),0===a.avail_out))return h.last_flush=-1,M}return b!==K?M:h.wrap<=0?N:(2===h.wrap?(i(h,255&a.adler),i(h,a.adler>>8&255),i(h,a.adler>>16&255),i(h,a.adler>>24&255),i(h,255&a.total_in),i(h,a.total_in>>8&255),i(h,a.total_in>>16&255),i(h,a.total_in>>24&255)):(j(h,a.adler>>>16),j(h,65535&a.adler)),g(a),h.wrap>0&&(h.wrap=-h.wrap),0!==h.pending?M:N)}function A(a){var b;return a&&a.state?(b=a.state.status,b!==lb&&b!==mb&&b!==nb&&b!==ob&&b!==pb&&b!==qb&&b!==rb?d(a,O):(a.state=null,b===qb?d(a,P):M)):O}var B,C=a("../utils/common"),D=a("./trees"),E=a("./adler32"),F=a("./crc32"),G=a("./messages"),H=0,I=1,J=3,K=4,L=5,M=0,N=1,O=-2,P=-3,Q=-5,R=-1,S=1,T=2,U=3,V=4,W=0,X=2,Y=8,Z=9,$=15,_=8,ab=29,bb=256,cb=bb+1+ab,db=30,eb=19,fb=2*cb+1,gb=15,hb=3,ib=258,jb=ib+hb+1,kb=32,lb=42,mb=69,nb=73,ob=91,pb=103,qb=113,rb=666,sb=1,tb=2,ub=3,vb=4,wb=3,xb=function(a,b,c,d,e){this.good_length=a,this.max_lazy=b,this.nice_length=c,this.max_chain=d,this.func=e};B=[new xb(0,0,0,0,n),new xb(4,4,8,4,o),new xb(4,5,16,8,o),new xb(4,6,32,32,o),new xb(4,4,16,16,p),new xb(8,16,32,32,p),new xb(8,16,128,128,p),new xb(8,32,128,256,p),new xb(32,128,258,1024,p),new xb(32,258,258,4096,p)],c.deflateInit=y,c.deflateInit2=x,c.deflateReset=v,c.deflateResetKeep=u,c.deflateSetHeader=w,c.deflate=z,c.deflateEnd=A,c.deflateInfo="pako deflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./messages":37,"./trees":38}],33:[function(a,b){"use strict";function c(){this.text=0,this.time=0,this.xflags=0,this.os=0,this.extra=null,this.extra_len=0,this.name="",this.comment="",this.hcrc=0,this.done=!1}b.exports=c},{}],34:[function(a,b){"use strict";var c=30,d=12;b.exports=function(a,b){var e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,A,B,C;e=a.state,f=a.next_in,B=a.input,g=f+(a.avail_in-5),h=a.next_out,C=a.output,i=h-(b-a.avail_out),j=h+(a.avail_out-257),k=e.dmax,l=e.wsize,m=e.whave,n=e.wnext,o=e.window,p=e.hold,q=e.bits,r=e.lencode,s=e.distcode,t=(1<<e.lenbits)-1,u=(1<<e.distbits)-1;a:do{15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=r[p&t];b:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,0===w)C[h++]=65535&v;else{if(!(16&w)){if(0===(64&w)){v=r[(65535&v)+(p&(1<<w)-1)];continue b}if(32&w){e.mode=d;break a}a.msg="invalid literal/length code",e.mode=c;break a}x=65535&v,w&=15,w&&(w>q&&(p+=B[f++]<<q,q+=8),x+=p&(1<<w)-1,p>>>=w,q-=w),15>q&&(p+=B[f++]<<q,q+=8,p+=B[f++]<<q,q+=8),v=s[p&u];c:for(;;){if(w=v>>>24,p>>>=w,q-=w,w=v>>>16&255,!(16&w)){if(0===(64&w)){v=s[(65535&v)+(p&(1<<w)-1)];continue c}a.msg="invalid distance code",e.mode=c;break a}if(y=65535&v,w&=15,w>q&&(p+=B[f++]<<q,q+=8,w>q&&(p+=B[f++]<<q,q+=8)),y+=p&(1<<w)-1,y>k){a.msg="invalid distance too far back",e.mode=c;break a}if(p>>>=w,q-=w,w=h-i,y>w){if(w=y-w,w>m&&e.sane){a.msg="invalid distance too far back",e.mode=c;break a}if(z=0,A=o,0===n){if(z+=l-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}else if(w>n){if(z+=l+n-w,w-=n,x>w){x-=w;do C[h++]=o[z++];while(--w);if(z=0,x>n){w=n,x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}}}else if(z+=n-w,x>w){x-=w;do C[h++]=o[z++];while(--w);z=h-y,A=C}for(;x>2;)C[h++]=A[z++],C[h++]=A[z++],C[h++]=A[z++],x-=3;x&&(C[h++]=A[z++],x>1&&(C[h++]=A[z++]))}else{z=h-y;do C[h++]=C[z++],C[h++]=C[z++],C[h++]=C[z++],x-=3;while(x>2);x&&(C[h++]=C[z++],x>1&&(C[h++]=C[z++]))}break}}break}}while(g>f&&j>h);x=q>>3,f-=x,q-=x<<3,p&=(1<<q)-1,a.next_in=f,a.next_out=h,a.avail_in=g>f?5+(g-f):5-(f-g),a.avail_out=j>h?257+(j-h):257-(h-j),e.hold=p,e.bits=q}},{}],35:[function(a,b,c){"use strict";function d(a){return(a>>>24&255)+(a>>>8&65280)+((65280&a)<<8)+((255&a)<<24)}function e(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new r.Buf16(320),this.work=new r.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function f(a){var b;return a&&a.state?(b=a.state,a.total_in=a.total_out=b.total=0,a.msg="",b.wrap&&(a.adler=1&b.wrap),b.mode=K,b.last=0,b.havedict=0,b.dmax=32768,b.head=null,b.hold=0,b.bits=0,b.lencode=b.lendyn=new r.Buf32(ob),b.distcode=b.distdyn=new r.Buf32(pb),b.sane=1,b.back=-1,C):F}function g(a){var b;return a&&a.state?(b=a.state,b.wsize=0,b.whave=0,b.wnext=0,f(a)):F}function h(a,b){var c,d;return a&&a.state?(d=a.state,0>b?(c=0,b=-b):(c=(b>>4)+1,48>b&&(b&=15)),b&&(8>b||b>15)?F:(null!==d.window&&d.wbits!==b&&(d.window=null),d.wrap=c,d.wbits=b,g(a))):F}function i(a,b){var c,d;return a?(d=new e,a.state=d,d.window=null,c=h(a,b),c!==C&&(a.state=null),c):F}function j(a){return i(a,rb)}function k(a){if(sb){var b;for(p=new r.Buf32(512),q=new r.Buf32(32),b=0;144>b;)a.lens[b++]=8;for(;256>b;)a.lens[b++]=9;for(;280>b;)a.lens[b++]=7;for(;288>b;)a.lens[b++]=8;for(v(x,a.lens,0,288,p,0,a.work,{bits:9}),b=0;32>b;)a.lens[b++]=5;v(y,a.lens,0,32,q,0,a.work,{bits:5}),sb=!1}a.lencode=p,a.lenbits=9,a.distcode=q,a.distbits=5}function l(a,b,c,d){var e,f=a.state;return null===f.window&&(f.wsize=1<<f.wbits,f.wnext=0,f.whave=0,f.window=new r.Buf8(f.wsize)),d>=f.wsize?(r.arraySet(f.window,b,c-f.wsize,f.wsize,0),f.wnext=0,f.whave=f.wsize):(e=f.wsize-f.wnext,e>d&&(e=d),r.arraySet(f.window,b,c-d,e,f.wnext),d-=e,d?(r.arraySet(f.window,b,c-d,d,0),f.wnext=d,f.whave=f.wsize):(f.wnext+=e,f.wnext===f.wsize&&(f.wnext=0),f.whave<f.wsize&&(f.whave+=e))),0}function m(a,b){var c,e,f,g,h,i,j,m,n,o,p,q,ob,pb,qb,rb,sb,tb,ub,vb,wb,xb,yb,zb,Ab=0,Bb=new r.Buf8(4),Cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15];if(!a||!a.state||!a.output||!a.input&&0!==a.avail_in)return F;c=a.state,c.mode===V&&(c.mode=W),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,o=i,p=j,xb=C;a:for(;;)switch(c.mode){case K:if(0===c.wrap){c.mode=W;break}for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(2&c.wrap&&35615===m){c.check=0,Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0),m=0,n=0,c.mode=L;break}if(c.flags=0,c.head&&(c.head.done=!1),!(1&c.wrap)||(((255&m)<<8)+(m>>8))%31){a.msg="incorrect header check",c.mode=lb;break}if((15&m)!==J){a.msg="unknown compression method",c.mode=lb;break}if(m>>>=4,n-=4,wb=(15&m)+8,0===c.wbits)c.wbits=wb;else if(wb>c.wbits){a.msg="invalid window size",c.mode=lb;break}c.dmax=1<<wb,a.adler=c.check=1,c.mode=512&m?T:V,m=0,n=0;break;case L:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.flags=m,(255&c.flags)!==J){a.msg="unknown compression method",c.mode=lb;break}if(57344&c.flags){a.msg="unknown header flags set",c.mode=lb;break}c.head&&(c.head.text=m>>8&1),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=M;case M:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.time=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,Bb[2]=m>>>16&255,Bb[3]=m>>>24&255,c.check=t(c.check,Bb,4,0)),m=0,n=0,c.mode=N;case N:for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.head&&(c.head.xflags=255&m,c.head.os=m>>8),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0,c.mode=O;case O:if(1024&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length=m,c.head&&(c.head.extra_len=m),512&c.flags&&(Bb[0]=255&m,Bb[1]=m>>>8&255,c.check=t(c.check,Bb,2,0)),m=0,n=0}else c.head&&(c.head.extra=null);c.mode=P;case P:if(1024&c.flags&&(q=c.length,q>i&&(q=i),q&&(c.head&&(wb=c.head.extra_len-c.length,c.head.extra||(c.head.extra=new Array(c.head.extra_len)),r.arraySet(c.head.extra,e,g,q,wb)),512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,c.length-=q),c.length))break a;c.length=0,c.mode=Q;case Q:if(2048&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.name+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.name=null);c.length=0,c.mode=R;case R:if(4096&c.flags){if(0===i)break a;q=0;do wb=e[g+q++],c.head&&wb&&c.length<65536&&(c.head.comment+=String.fromCharCode(wb));while(wb&&i>q);if(512&c.flags&&(c.check=t(c.check,e,q,g)),i-=q,g+=q,wb)break a}else c.head&&(c.head.comment=null);c.mode=S;case S:if(512&c.flags){for(;16>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(65535&c.check)){a.msg="header crc mismatch",c.mode=lb;break}m=0,n=0}c.head&&(c.head.hcrc=c.flags>>9&1,c.head.done=!0),a.adler=c.check=0,c.mode=V;break;case T:for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}a.adler=c.check=d(m),m=0,n=0,c.mode=U;case U:if(0===c.havedict)return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,E;a.adler=c.check=1,c.mode=V;case V:if(b===A||b===B)break a;case W:if(c.last){m>>>=7&n,n-=7&n,c.mode=ib;break}for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}switch(c.last=1&m,m>>>=1,n-=1,3&m){case 0:c.mode=X;break;case 1:if(k(c),c.mode=bb,b===B){m>>>=2,n-=2;break a}break;case 2:c.mode=$;break;case 3:a.msg="invalid block type",c.mode=lb}m>>>=2,n-=2;break;case X:for(m>>>=7&n,n-=7&n;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if((65535&m)!==(m>>>16^65535)){a.msg="invalid stored block lengths",c.mode=lb;break}if(c.length=65535&m,m=0,n=0,c.mode=Y,b===B)break a;case Y:c.mode=Z;case Z:if(q=c.length){if(q>i&&(q=i),q>j&&(q=j),0===q)break a;r.arraySet(f,e,g,q,h),i-=q,g+=q,j-=q,h+=q,c.length-=q;break}c.mode=V;break;case $:for(;14>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(c.nlen=(31&m)+257,m>>>=5,n-=5,c.ndist=(31&m)+1,m>>>=5,n-=5,c.ncode=(15&m)+4,m>>>=4,n-=4,c.nlen>286||c.ndist>30){a.msg="too many length or distance symbols",c.mode=lb;break}c.have=0,c.mode=_;case _:for(;c.have<c.ncode;){for(;3>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.lens[Cb[c.have++]]=7&m,m>>>=3,n-=3}for(;c.have<19;)c.lens[Cb[c.have++]]=0;if(c.lencode=c.lendyn,c.lenbits=7,yb={bits:c.lenbits},xb=v(w,c.lens,0,19,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid code lengths set",c.mode=lb;break}c.have=0,c.mode=ab;case ab:for(;c.have<c.nlen+c.ndist;){for(;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(16>sb)m>>>=qb,n-=qb,c.lens[c.have++]=sb;else{if(16===sb){for(zb=qb+2;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m>>>=qb,n-=qb,0===c.have){a.msg="invalid bit length repeat",c.mode=lb;break}wb=c.lens[c.have-1],q=3+(3&m),m>>>=2,n-=2}else if(17===sb){for(zb=qb+3;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=3+(7&m),m>>>=3,n-=3}else{for(zb=qb+7;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=qb,n-=qb,wb=0,q=11+(127&m),m>>>=7,n-=7}if(c.have+q>c.nlen+c.ndist){a.msg="invalid bit length repeat",c.mode=lb;break}for(;q--;)c.lens[c.have++]=wb}}if(c.mode===lb)break;if(0===c.lens[256]){a.msg="invalid code -- missing end-of-block",c.mode=lb;break}if(c.lenbits=9,yb={bits:c.lenbits},xb=v(x,c.lens,0,c.nlen,c.lencode,0,c.work,yb),c.lenbits=yb.bits,xb){a.msg="invalid literal/lengths set",c.mode=lb;break}if(c.distbits=6,c.distcode=c.distdyn,yb={bits:c.distbits},xb=v(y,c.lens,c.nlen,c.ndist,c.distcode,0,c.work,yb),c.distbits=yb.bits,xb){a.msg="invalid distances set",c.mode=lb;break}if(c.mode=bb,b===B)break a;case bb:c.mode=cb;case cb:if(i>=6&&j>=258){a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,u(a,p),h=a.next_out,f=a.output,j=a.avail_out,g=a.next_in,e=a.input,i=a.avail_in,m=c.hold,n=c.bits,c.mode===V&&(c.back=-1);break}for(c.back=0;Ab=c.lencode[m&(1<<c.lenbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(rb&&0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.lencode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,c.length=sb,0===rb){c.mode=hb;break}if(32&rb){c.back=-1,c.mode=V;break}if(64&rb){a.msg="invalid literal/length code",c.mode=lb;break}c.extra=15&rb,c.mode=db;case db:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.length+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}c.was=c.length,c.mode=eb;case eb:for(;Ab=c.distcode[m&(1<<c.distbits)-1],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(0===(240&rb)){for(tb=qb,ub=rb,vb=sb;Ab=c.distcode[vb+((m&(1<<tb+ub)-1)>>tb)],qb=Ab>>>24,rb=Ab>>>16&255,sb=65535&Ab,!(n>=tb+qb);){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}m>>>=tb,n-=tb,c.back+=tb}if(m>>>=qb,n-=qb,c.back+=qb,64&rb){a.msg="invalid distance code",c.mode=lb;break}c.offset=sb,c.extra=15&rb,c.mode=fb;case fb:if(c.extra){for(zb=c.extra;zb>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}c.offset+=m&(1<<c.extra)-1,m>>>=c.extra,n-=c.extra,c.back+=c.extra}if(c.offset>c.dmax){a.msg="invalid distance too far back",c.mode=lb;break}c.mode=gb;case gb:if(0===j)break a;if(q=p-j,c.offset>q){if(q=c.offset-q,q>c.whave&&c.sane){a.msg="invalid distance too far back",c.mode=lb;break}q>c.wnext?(q-=c.wnext,ob=c.wsize-q):ob=c.wnext-q,q>c.length&&(q=c.length),pb=c.window}else pb=f,ob=h-c.offset,q=c.length;q>j&&(q=j),j-=q,c.length-=q;do f[h++]=pb[ob++];while(--q);0===c.length&&(c.mode=cb);break;case hb:if(0===j)break a;f[h++]=c.length,j--,c.mode=cb;break;case ib:if(c.wrap){for(;32>n;){if(0===i)break a;i--,m|=e[g++]<<n,n+=8}if(p-=j,a.total_out+=p,c.total+=p,p&&(a.adler=c.check=c.flags?t(c.check,f,p,h-p):s(c.check,f,p,h-p)),p=j,(c.flags?m:d(m))!==c.check){a.msg="incorrect data check",c.mode=lb;break}m=0,n=0}c.mode=jb;case jb:if(c.wrap&&c.flags){for(;32>n;){if(0===i)break a;i--,m+=e[g++]<<n,n+=8}if(m!==(4294967295&c.total)){a.msg="incorrect length check",c.mode=lb;break}m=0,n=0}c.mode=kb;case kb:xb=D;break a;case lb:xb=G;break a;case mb:return H;case nb:default:return F}return a.next_out=h,a.avail_out=j,a.next_in=g,a.avail_in=i,c.hold=m,c.bits=n,(c.wsize||p!==a.avail_out&&c.mode<lb&&(c.mode<ib||b!==z))&&l(a,a.output,a.next_out,p-a.avail_out)?(c.mode=mb,H):(o-=a.avail_in,p-=a.avail_out,a.total_in+=o,a.total_out+=p,c.total+=p,c.wrap&&p&&(a.adler=c.check=c.flags?t(c.check,f,p,a.next_out-p):s(c.check,f,p,a.next_out-p)),a.data_type=c.bits+(c.last?64:0)+(c.mode===V?128:0)+(c.mode===bb||c.mode===Y?256:0),(0===o&&0===p||b===z)&&xb===C&&(xb=I),xb)}function n(a){if(!a||!a.state)return F;var b=a.state;return b.window&&(b.window=null),a.state=null,C}function o(a,b){var c;return a&&a.state?(c=a.state,0===(2&c.wrap)?F:(c.head=b,b.done=!1,C)):F}var p,q,r=a("../utils/common"),s=a("./adler32"),t=a("./crc32"),u=a("./inffast"),v=a("./inftrees"),w=0,x=1,y=2,z=4,A=5,B=6,C=0,D=1,E=2,F=-2,G=-3,H=-4,I=-5,J=8,K=1,L=2,M=3,N=4,O=5,P=6,Q=7,R=8,S=9,T=10,U=11,V=12,W=13,X=14,Y=15,Z=16,$=17,_=18,ab=19,bb=20,cb=21,db=22,eb=23,fb=24,gb=25,hb=26,ib=27,jb=28,kb=29,lb=30,mb=31,nb=32,ob=852,pb=592,qb=15,rb=qb,sb=!0;c.inflateReset=g,c.inflateReset2=h,c.inflateResetKeep=f,c.inflateInit=j,c.inflateInit2=i,c.inflate=m,c.inflateEnd=n,c.inflateGetHeader=o,c.inflateInfo="pako inflate (from Nodeca project)"},{"../utils/common":27,"./adler32":29,"./crc32":31,"./inffast":34,"./inftrees":36}],36:[function(a,b){"use strict";var c=a("../utils/common"),d=15,e=852,f=592,g=0,h=1,i=2,j=[3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258,0,0],k=[16,16,16,16,16,16,16,16,17,17,17,17,18,18,18,18,19,19,19,19,20,20,20,20,21,21,21,21,16,72,78],l=[1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0],m=[16,16,16,16,17,17,18,18,19,19,20,20,21,21,22,22,23,23,24,24,25,25,26,26,27,27,28,28,29,29,64,64];b.exports=function(a,b,n,o,p,q,r,s){var t,u,v,w,x,y,z,A,B,C=s.bits,D=0,E=0,F=0,G=0,H=0,I=0,J=0,K=0,L=0,M=0,N=null,O=0,P=new c.Buf16(d+1),Q=new c.Buf16(d+1),R=null,S=0;for(D=0;d>=D;D++)P[D]=0;for(E=0;o>E;E++)P[b[n+E]]++;for(H=C,G=d;G>=1&&0===P[G];G--);if(H>G&&(H=G),0===G)return p[q++]=20971520,p[q++]=20971520,s.bits=1,0;for(F=1;G>F&&0===P[F];F++);for(F>H&&(H=F),K=1,D=1;d>=D;D++)if(K<<=1,K-=P[D],0>K)return-1;if(K>0&&(a===g||1!==G))return-1;for(Q[1]=0,D=1;d>D;D++)Q[D+1]=Q[D]+P[D];for(E=0;o>E;E++)0!==b[n+E]&&(r[Q[b[n+E]]++]=E);if(a===g?(N=R=r,y=19):a===h?(N=j,O-=257,R=k,S-=257,y=256):(N=l,R=m,y=-1),M=0,E=0,D=F,x=q,I=H,J=0,v=-1,L=1<<H,w=L-1,a===h&&L>e||a===i&&L>f)return 1;for(var T=0;;){T++,z=D-J,r[E]<y?(A=0,B=r[E]):r[E]>y?(A=R[S+r[E]],B=N[O+r[E]]):(A=96,B=0),t=1<<D-J,u=1<<I,F=u;do u-=t,p[x+(M>>J)+u]=z<<24|A<<16|B|0;while(0!==u);for(t=1<<D-1;M&t;)t>>=1;if(0!==t?(M&=t-1,M+=t):M=0,E++,0===--P[D]){if(D===G)break;D=b[n+r[E]]}if(D>H&&(M&w)!==v){for(0===J&&(J=H),x+=F,I=D-J,K=1<<I;G>I+J&&(K-=P[I+J],!(0>=K));)I++,K<<=1;if(L+=1<<I,a===h&&L>e||a===i&&L>f)return 1;v=M&w,p[v]=H<<24|I<<16|x-q|0}}return 0!==M&&(p[x+M]=D-J<<24|64<<16|0),s.bits=H,0}},{"../utils/common":27}],37:[function(a,b){"use strict";b.exports={2:"need dictionary",1:"stream end",0:"","-1":"file error","-2":"stream error","-3":"data error","-4":"insufficient memory","-5":"buffer error","-6":"incompatible version"}},{}],38:[function(a,b,c){"use strict";function d(a){for(var b=a.length;--b>=0;)a[b]=0}function e(a){return 256>a?gb[a]:gb[256+(a>>>7)]}function f(a,b){a.pending_buf[a.pending++]=255&b,a.pending_buf[a.pending++]=b>>>8&255}function g(a,b,c){a.bi_valid>V-c?(a.bi_buf|=b<<a.bi_valid&65535,f(a,a.bi_buf),a.bi_buf=b>>V-a.bi_valid,a.bi_valid+=c-V):(a.bi_buf|=b<<a.bi_valid&65535,a.bi_valid+=c)}function h(a,b,c){g(a,c[2*b],c[2*b+1])}function i(a,b){var c=0;do c|=1&a,a>>>=1,c<<=1;while(--b>0);return c>>>1}function j(a){16===a.bi_valid?(f(a,a.bi_buf),a.bi_buf=0,a.bi_valid=0):a.bi_valid>=8&&(a.pending_buf[a.pending++]=255&a.bi_buf,a.bi_buf>>=8,a.bi_valid-=8)}function k(a,b){var c,d,e,f,g,h,i=b.dyn_tree,j=b.max_code,k=b.stat_desc.static_tree,l=b.stat_desc.has_stree,m=b.stat_desc.extra_bits,n=b.stat_desc.extra_base,o=b.stat_desc.max_length,p=0;for(f=0;U>=f;f++)a.bl_count[f]=0;for(i[2*a.heap[a.heap_max]+1]=0,c=a.heap_max+1;T>c;c++)d=a.heap[c],f=i[2*i[2*d+1]+1]+1,f>o&&(f=o,p++),i[2*d+1]=f,d>j||(a.bl_count[f]++,g=0,d>=n&&(g=m[d-n]),h=i[2*d],a.opt_len+=h*(f+g),l&&(a.static_len+=h*(k[2*d+1]+g)));if(0!==p){do{for(f=o-1;0===a.bl_count[f];)f--;a.bl_count[f]--,a.bl_count[f+1]+=2,a.bl_count[o]--,p-=2}while(p>0);for(f=o;0!==f;f--)for(d=a.bl_count[f];0!==d;)e=a.heap[--c],e>j||(i[2*e+1]!==f&&(a.opt_len+=(f-i[2*e+1])*i[2*e],i[2*e+1]=f),d--)}}function l(a,b,c){var d,e,f=new Array(U+1),g=0;for(d=1;U>=d;d++)f[d]=g=g+c[d-1]<<1;for(e=0;b>=e;e++){var h=a[2*e+1];0!==h&&(a[2*e]=i(f[h]++,h))}}function m(){var a,b,c,d,e,f=new Array(U+1);for(c=0,d=0;O-1>d;d++)for(ib[d]=c,a=0;a<1<<_[d];a++)hb[c++]=d;for(hb[c-1]=d,e=0,d=0;16>d;d++)for(jb[d]=e,a=0;a<1<<ab[d];a++)gb[e++]=d;for(e>>=7;R>d;d++)for(jb[d]=e<<7,a=0;a<1<<ab[d]-7;a++)gb[256+e++]=d;for(b=0;U>=b;b++)f[b]=0;for(a=0;143>=a;)eb[2*a+1]=8,a++,f[8]++;for(;255>=a;)eb[2*a+1]=9,a++,f[9]++;for(;279>=a;)eb[2*a+1]=7,a++,f[7]++;for(;287>=a;)eb[2*a+1]=8,a++,f[8]++;for(l(eb,Q+1,f),a=0;R>a;a++)fb[2*a+1]=5,fb[2*a]=i(a,5);kb=new nb(eb,_,P+1,Q,U),lb=new nb(fb,ab,0,R,U),mb=new nb(new Array(0),bb,0,S,W)}function n(a){var b;for(b=0;Q>b;b++)a.dyn_ltree[2*b]=0;for(b=0;R>b;b++)a.dyn_dtree[2*b]=0;for(b=0;S>b;b++)a.bl_tree[2*b]=0;a.dyn_ltree[2*X]=1,a.opt_len=a.static_len=0,a.last_lit=a.matches=0}function o(a){a.bi_valid>8?f(a,a.bi_buf):a.bi_valid>0&&(a.pending_buf[a.pending++]=a.bi_buf),a.bi_buf=0,a.bi_valid=0}function p(a,b,c,d){o(a),d&&(f(a,c),f(a,~c)),E.arraySet(a.pending_buf,a.window,b,c,a.pending),a.pending+=c}function q(a,b,c,d){var e=2*b,f=2*c;return a[e]<a[f]||a[e]===a[f]&&d[b]<=d[c]}function r(a,b,c){for(var d=a.heap[c],e=c<<1;e<=a.heap_len&&(e<a.heap_len&&q(b,a.heap[e+1],a.heap[e],a.depth)&&e++,!q(b,d,a.heap[e],a.depth));)a.heap[c]=a.heap[e],c=e,e<<=1;a.heap[c]=d}function s(a,b,c){var d,f,i,j,k=0;if(0!==a.last_lit)do d=a.pending_buf[a.d_buf+2*k]<<8|a.pending_buf[a.d_buf+2*k+1],f=a.pending_buf[a.l_buf+k],k++,0===d?h(a,f,b):(i=hb[f],h(a,i+P+1,b),j=_[i],0!==j&&(f-=ib[i],g(a,f,j)),d--,i=e(d),h(a,i,c),j=ab[i],0!==j&&(d-=jb[i],g(a,d,j)));while(k<a.last_lit);h(a,X,b)}function t(a,b){var c,d,e,f=b.dyn_tree,g=b.stat_desc.static_tree,h=b.stat_desc.has_stree,i=b.stat_desc.elems,j=-1;for(a.heap_len=0,a.heap_max=T,c=0;i>c;c++)0!==f[2*c]?(a.heap[++a.heap_len]=j=c,a.depth[c]=0):f[2*c+1]=0;for(;a.heap_len<2;)e=a.heap[++a.heap_len]=2>j?++j:0,f[2*e]=1,a.depth[e]=0,a.opt_len--,h&&(a.static_len-=g[2*e+1]);for(b.max_code=j,c=a.heap_len>>1;c>=1;c--)r(a,f,c);e=i;do c=a.heap[1],a.heap[1]=a.heap[a.heap_len--],r(a,f,1),d=a.heap[1],a.heap[--a.heap_max]=c,a.heap[--a.heap_max]=d,f[2*e]=f[2*c]+f[2*d],a.depth[e]=(a.depth[c]>=a.depth[d]?a.depth[c]:a.depth[d])+1,f[2*c+1]=f[2*d+1]=e,a.heap[1]=e++,r(a,f,1);while(a.heap_len>=2);a.heap[--a.heap_max]=a.heap[1],k(a,b),l(f,j,a.bl_count)}function u(a,b,c){var d,e,f=-1,g=b[1],h=0,i=7,j=4;for(0===g&&(i=138,j=3),b[2*(c+1)+1]=65535,d=0;c>=d;d++)e=g,g=b[2*(d+1)+1],++h<i&&e===g||(j>h?a.bl_tree[2*e]+=h:0!==e?(e!==f&&a.bl_tree[2*e]++,a.bl_tree[2*Y]++):10>=h?a.bl_tree[2*Z]++:a.bl_tree[2*$]++,h=0,f=e,0===g?(i=138,j=3):e===g?(i=6,j=3):(i=7,j=4))}function v(a,b,c){var d,e,f=-1,i=b[1],j=0,k=7,l=4;for(0===i&&(k=138,l=3),d=0;c>=d;d++)if(e=i,i=b[2*(d+1)+1],!(++j<k&&e===i)){if(l>j){do h(a,e,a.bl_tree);while(0!==--j)}else 0!==e?(e!==f&&(h(a,e,a.bl_tree),j--),h(a,Y,a.bl_tree),g(a,j-3,2)):10>=j?(h(a,Z,a.bl_tree),g(a,j-3,3)):(h(a,$,a.bl_tree),g(a,j-11,7));j=0,f=e,0===i?(k=138,l=3):e===i?(k=6,l=3):(k=7,l=4)}}function w(a){var b;for(u(a,a.dyn_ltree,a.l_desc.max_code),u(a,a.dyn_dtree,a.d_desc.max_code),t(a,a.bl_desc),b=S-1;b>=3&&0===a.bl_tree[2*cb[b]+1];b--);return a.opt_len+=3*(b+1)+5+5+4,b}function x(a,b,c,d){var e;for(g(a,b-257,5),g(a,c-1,5),g(a,d-4,4),e=0;d>e;e++)g(a,a.bl_tree[2*cb[e]+1],3);v(a,a.dyn_ltree,b-1),v(a,a.dyn_dtree,c-1)}function y(a){var b,c=4093624447;for(b=0;31>=b;b++,c>>>=1)if(1&c&&0!==a.dyn_ltree[2*b])return G;if(0!==a.dyn_ltree[18]||0!==a.dyn_ltree[20]||0!==a.dyn_ltree[26])return H;for(b=32;P>b;b++)if(0!==a.dyn_ltree[2*b])return H;return G}function z(a){pb||(m(),pb=!0),a.l_desc=new ob(a.dyn_ltree,kb),a.d_desc=new ob(a.dyn_dtree,lb),a.bl_desc=new ob(a.bl_tree,mb),a.bi_buf=0,a.bi_valid=0,n(a)}function A(a,b,c,d){g(a,(J<<1)+(d?1:0),3),p(a,b,c,!0)}function B(a){g(a,K<<1,3),h(a,X,eb),j(a)}function C(a,b,c,d){var e,f,h=0;a.level>0?(a.strm.data_type===I&&(a.strm.data_type=y(a)),t(a,a.l_desc),t(a,a.d_desc),h=w(a),e=a.opt_len+3+7>>>3,f=a.static_len+3+7>>>3,e>=f&&(e=f)):e=f=c+5,e>=c+4&&-1!==b?A(a,b,c,d):a.strategy===F||f===e?(g(a,(K<<1)+(d?1:0),3),s(a,eb,fb)):(g(a,(L<<1)+(d?1:0),3),x(a,a.l_desc.max_code+1,a.d_desc.max_code+1,h+1),s(a,a.dyn_ltree,a.dyn_dtree)),n(a),d&&o(a)}function D(a,b,c){return a.pending_buf[a.d_buf+2*a.last_lit]=b>>>8&255,a.pending_buf[a.d_buf+2*a.last_lit+1]=255&b,a.pending_buf[a.l_buf+a.last_lit]=255&c,a.last_lit++,0===b?a.dyn_ltree[2*c]++:(a.matches++,b--,a.dyn_ltree[2*(hb[c]+P+1)]++,a.dyn_dtree[2*e(b)]++),a.last_lit===a.lit_bufsize-1}var E=a("../utils/common"),F=4,G=0,H=1,I=2,J=0,K=1,L=2,M=3,N=258,O=29,P=256,Q=P+1+O,R=30,S=19,T=2*Q+1,U=15,V=16,W=7,X=256,Y=16,Z=17,$=18,_=[0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0],ab=[0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13],bb=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7],cb=[16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15],db=512,eb=new Array(2*(Q+2));d(eb);var fb=new Array(2*R);d(fb);var gb=new Array(db);d(gb);var hb=new Array(N-M+1);d(hb);var ib=new Array(O);d(ib);var jb=new Array(R);d(jb);var kb,lb,mb,nb=function(a,b,c,d,e){this.static_tree=a,this.extra_bits=b,this.extra_base=c,this.elems=d,this.max_length=e,this.has_stree=a&&a.length},ob=function(a,b){this.dyn_tree=a,this.max_code=0,this.stat_desc=b},pb=!1;c._tr_init=z,c._tr_stored_block=A,c._tr_flush_block=C,c._tr_tally=D,c._tr_align=B},{"../utils/common":27}],39:[function(a,b){"use strict";function c(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}b.exports=c},{}]},{},[9])(9)});'use strict';if(tr.isVinn){global.window={};}'use strict';if(tr.isVinn){global.JSZip=global.window.JSZip;global.window=undefined;}else if(tr.isNode){const jsZipAbsPath=HTMLImportsLoader.hrefToAbsolutePath('/jszip.min.js');const jsZipModule=require(jsZipAbsPath);global.JSZip=jsZipModule;}'use strict';tr.exportTo('tr.e.importer',function(){const GZIP_MEMBER_HEADER_ID_SIZE=3;const GZIP_HEADER_ID1=0x1f;const GZIP_HEADER_ID2=0x8b;const GZIP_DEFLATE_COMPRESSION=8;function GzipImporter(model,eventData){this.inflateAsTraceStream=false;if(typeof(eventData)==='string'||eventData instanceof String){eventData=JSZip.utils.transformTo('uint8array',eventData);}else if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}else if(eventData instanceof tr.b.InMemoryTraceStream){eventData=eventData.data;this.inflateAsTraceStream_=true;}else{throw new Error('Unknown gzip data format');}
 this.model_=model;this.gzipData_=eventData;}
-GzipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));}else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else{return false;}
-return header[0]===GZIP_HEADER_ID1&&header[1]===GZIP_HEADER_ID2&&header[2]===GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){var position=0;function getByte(){if(position>=data.length){throw new Error('Unexpected end of gzip data');}
+GzipImporter.canImport=function(eventData){if(eventData instanceof tr.b.InMemoryTraceStream){eventData=eventData.header;}
+let header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,GZIP_MEMBER_HEADER_ID_SIZE));}else if(typeof(eventData)==='string'||eventData instanceof String){header=eventData.substring(0,GZIP_MEMBER_HEADER_ID_SIZE);header=JSZip.utils.transformTo('uint8array',header);}else{return false;}
+return header[0]===GZIP_HEADER_ID1&&header[1]===GZIP_HEADER_ID2&&header[2]===GZIP_DEFLATE_COMPRESSION;};GzipImporter.inflateGzipData_=function(data){let position=0;function getByte(){if(position>=data.length){throw new Error('Unexpected end of gzip data');}
 return data[position++];}
-function getWord(){var low=getByte();var high=getByte();return(high<<8)+low;}
+function getWord(){const low=getByte();const high=getByte();return(high<<8)+low;}
 function skipBytes(amount){position+=amount;}
 function skipZeroTerminatedString(){while(getByte()!==0){}}
-var id1=getByte();var id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2){throw new Error('Not gzip data');}
-var compressionMethod=getByte();if(compressionMethod!==GZIP_DEFLATE_COMPRESSION){throw new Error('Unsupported compression method: '+compressionMethod);}
-var flags=getByte();var haveHeaderCrc=flags&(1<<1);var haveExtraFields=flags&(1<<2);var haveFileName=flags&(1<<3);var haveComment=flags&(1<<4);skipBytes(4+1+1);if(haveExtraFields){var bytesToSkip=getWord();skipBytes(bytesToSkip);}
-if(haveFileName)skipZeroTerminatedString();if(haveComment)skipZeroTerminatedString();if(haveHeaderCrc)getWord();var inflatedData=JSZip.compressions['DEFLATE'].uncompress(data.subarray(position));var string=GzipImporter.transformToString(inflatedData);if(inflatedData.length>0&&string.length===0){throw new RangeError('Inflated gzip data too long to fit into a string'+' ('+inflatedData.length+').');}
-return string;};GzipImporter.transformToString=function(data){if(typeof TextDecoder==='undefined'){return JSZip.utils.transformTo('string',data);}
-var type=JSZip.utils.getTypeOf(data);if(type==='string'){return data;}
-if(type==='array'){data=new Uint8Array(data);}
-var decoder=new TextDecoder('utf-8');return decoder.decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter,};});'use strict';tr.exportTo('tr.importer',function(){function SimpleLineReader(text){this.lines_=text.split('\n');this.curLine_=0;this.savedLines_=undefined;}
-SimpleLineReader.prototype={advanceToLineMatching:function(regex){for(;this.curLine_<this.lines_.length;this.curLine_++){var line=this.lines_[this.curLine_];if(this.savedLines_!==undefined){this.savedLines_.push(line);}
-if(regex.test(line))return true;}
-return false;},get curLineNumber(){return this.curLine_;},beginSavingLines:function(){this.savedLines_=[];},endSavingLinesAndGetResult:function(){var tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}};return{SimpleLineReader,};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
-Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];var r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$'))){break;}
-r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))return;var rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);var data64=rawEvents.join('\n');var buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));var len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
+const id1=getByte();const id2=getByte();if(id1!==GZIP_HEADER_ID1||id2!==GZIP_HEADER_ID2){throw new Error('Not gzip data');}
+const compressionMethod=getByte();if(compressionMethod!==GZIP_DEFLATE_COMPRESSION){throw new Error('Unsupported compression method: '+compressionMethod);}
+const flags=getByte();const haveHeaderCrc=flags&(1<<1);const haveExtraFields=flags&(1<<2);const haveFileName=flags&(1<<3);const haveComment=flags&(1<<4);skipBytes(4+1+1);if(haveExtraFields){const bytesToSkip=getWord();skipBytes(bytesToSkip);}
+if(haveFileName)skipZeroTerminatedString();if(haveComment)skipZeroTerminatedString();if(haveHeaderCrc)getWord();const inflatedData=JSZip.compressions.DEFLATE.uncompress(data.subarray(position));if(this.inflateAsTraceStream_){return GzipImporter.transformToStream(inflatedData);}
+let string;try{string=GzipImporter.transformToString(inflatedData);}catch(err){return GzipImporter.transformToStream(inflatedData);}
+if(inflatedData.length>0&&string.length===0){throw new RangeError('Inflated gzip data too long to fit into a string'+' ('+inflatedData.length+').');}
+return string;};GzipImporter.transformToStream=function(data){const type=JSZip.utils.getTypeOf(data);if(type==='uint8array')return new tr.b.InMemoryTraceStream(data,false);throw new Error(`Cannot transform ${type} to TraceStream.`);};GzipImporter.transformToString=function(data){if(typeof TextDecoder==='undefined'){return JSZip.utils.transformTo('string',data);}
+const type=JSZip.utils.getTypeOf(data);if(type==='string')return data;if(type==='array'){data=new Uint8Array(data);}
+const decoder=new TextDecoder('utf-8');return decoder.decode(data);};GzipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'GzipImporter';},isTraceDataContainer(){return true;},extractSubtraces(){const eventData=GzipImporter.inflateGzipData_(this.gzipData_);return eventData?[eventData]:[];}};tr.importer.Importer.register(GzipImporter);return{GzipImporter,};});'use strict';tr.exportTo('tr.importer',function(){class SimpleLineReader{constructor(text){this.data_=text instanceof tr.b.TraceStream?text:text.split('\n');this.curLine_=0;this.readLastLine_=false;this.savedLines_=undefined;}*[Symbol.iterator](){let lastLine=undefined;while(this.hasData_){if(this.readLastLine_){this.curLine_++;this.readLastLine_=false;}else if(this.data_ instanceof tr.b.TraceStream){this.curLine_++;const line=this.data_.readUntilDelimiter('\n');lastLine=line.endsWith('\n')?line.slice(0,-1):line;}else{this.curLine_++;lastLine=this.data_[this.curLine_-1];}
+yield lastLine;}}
+get curLineNumber(){return this.curLine_;}
+get hasData_(){if(this.data_ instanceof tr.b.TraceStream)return this.data_.hasData;return this.curLine_<this.data_.length;}
+advanceToLineMatching(regex){for(const line of this){if(this.savedLines_!==undefined)this.savedLines_.push(line);if(regex.test(line)){this.goBack_();return true;}}
+return false;}
+goBack_(){if(this.readLastLine_){throw new Error('There should be at least one nextLine call between '+'any two goBack calls.');}
+if(this.curLine_===0){throw new Error('There should be at least one nextLine call before '+'the first goBack call.');}
+this.readLastLine_=true;this.curLine_--;}
+beginSavingLines(){this.savedLines_=[];}
+endSavingLinesAndGetResult(){const tmp=this.savedLines_;this.savedLines_=undefined;return tmp;}}
+return{SimpleLineReader,};});'use strict';tr.exportTo('tr.e.importer',function(){function Trace2HTMLImporter(model,events){this.importPriority=0;}
+Trace2HTMLImporter.subtraces_=[];function _extractEventsFromHTML(text){Trace2HTMLImporter.subtraces_=[];const r=new tr.importer.SimpleLineReader(text);while(true){if(!r.advanceToLineMatching(new RegExp('^<\s*script id="viewer-data" '+'type="(application\/json|text\/plain)">$'))){break;}
+r.beginSavingLines();if(!r.advanceToLineMatching(/^<\/\s*script>$/))return;let rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);const data64=rawEvents.join('\n');const buffer=new ArrayBuffer(tr.b.Base64.getDecodedBufferLength(data64));const len=tr.b.Base64.DecodeToTypedArray(data64,new DataView(buffer));Trace2HTMLImporter.subtraces_.push(buffer.slice(0,len));}}
 function _canImportFromHTML(text){if(!/^<!DOCTYPE html>/.test(text))return false;_extractEventsFromHTML(text);if(Trace2HTMLImporter.subtraces_.length===0)return false;return true;}
-Trace2HTMLImporter.canImport=function(events){return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){return Trace2HTMLImporter.subtraces_;},importEvents:function(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){}
+Trace2HTMLImporter.canImport=function(events){if(events instanceof tr.b.TraceStream)return false;return _canImportFromHTML(events);};Trace2HTMLImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'Trace2HTMLImporter';},isTraceDataContainer(){return true;},extractSubtraces(){return Trace2HTMLImporter.subtraces_;},importEvents(){}};tr.importer.Importer.register(Trace2HTMLImporter);return{Trace2HTMLImporter,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function SplayTree(){}
 SplayTree.prototype.root_=null;SplayTree.prototype.isEmpty=function(){return!this.root_;};SplayTree.prototype.insert=function(key,value){if(this.isEmpty()){this.root_=new SplayTree.Node(key,value);return;}
 this.splay_(key);if(this.root_.key===key){return;}
-var node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
+const node=new SplayTree.Node(key,value);if(key>this.root_.key){node.left=this.root_;node.right=this.root_.right;this.root_.right=null;}else{node.right=this.root_;node.left=this.root_.left;this.root_.left=null;}
 this.root_=node;};SplayTree.prototype.remove=function(key){if(this.isEmpty()){throw Error('Key not found: '+key);}
 this.splay_(key);if(this.root_.key!==key){throw Error('Key not found: '+key);}
-var removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{var right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
-return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty())return null;this.splay_(key);return this.root_.key===key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty())return null;var current=this.root_;while(current.left){current=current.left;}
-return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty())return null;var current=opt_startNode||this.root_;while(current.right){current=current.right;}
+const removed=this.root_;if(!this.root_.left){this.root_=this.root_.right;}else{const right=this.root_.right;this.root_=this.root_.left;this.splay_(key);this.root_.right=right;}
+return removed;};SplayTree.prototype.find=function(key){if(this.isEmpty())return null;this.splay_(key);return this.root_.key===key?this.root_:null;};SplayTree.prototype.findMin=function(){if(this.isEmpty())return null;let current=this.root_;while(current.left){current=current.left;}
+return current;};SplayTree.prototype.findMax=function(opt_startNode){if(this.isEmpty())return null;let current=opt_startNode||this.root_;while(current.right){current=current.right;}
 return current;};SplayTree.prototype.findGreatestLessThan=function(key){if(this.isEmpty())return null;this.splay_(key);if(this.root_.key<=key){return this.root_;}
 if(this.root_.left){return this.findMax(this.root_.left);}
-return null;};SplayTree.prototype.exportKeysAndValues=function(){var result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){var result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty())return;var dummy;var left;var right;dummy=left=right=new SplayTree.Node(null,null);var current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
-if(key<current.left.key){var tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
+return null;};SplayTree.prototype.exportKeysAndValues=function(){const result=[];this.traverse_(function(node){result.push([node.key,node.value]);});return result;};SplayTree.prototype.exportValues=function(){const result=[];this.traverse_(function(node){result.push(node.value);});return result;};SplayTree.prototype.splay_=function(key){if(this.isEmpty())return;const dummy=new SplayTree.Node(null,null);let left=dummy;let right=dummy;let current=this.root_;while(true){if(key<current.key){if(!current.left){break;}
+if(key<current.left.key){const tmp=current.left;current.left=tmp.right;tmp.right=current;current=tmp;if(!current.left){break;}}
 right.left=current;right=current;current=current.left;}else if(key>current.key){if(!current.right){break;}
-if(key>current.right.key){var tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
+if(key>current.right.key){const tmp=current.right;current.right=tmp.left;tmp.left=current;current=tmp;if(!current.right){break;}}
 left.right=current;left=current;current=current.right;}else{break;}}
-left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){var nodesToVisit=[this.root_];while(nodesToVisit.length>0){var node=nodesToVisit.shift();if(node===null)continue;f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];}
-CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){var removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){var removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(var addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){var toDelete=[];var addr=end-1;while(addr>=start){var node=tree.findGreatestLessThan(addr);if(!node)break;var start2=node.key;var end2=start2+node.value.size;if(start2<end&&start<end2)toDelete.push(start2);addr=start2-1;}
-for(var i=0,l=toDelete.length;i<l;++i)tree.remove(toDelete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){var node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntryInLibraries=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.libraries_,addr);}
-return undefined;};CodeMap.prototype.findEntry=function(addr){var pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
-var min=this.dynamics_.findMin();var max=this.dynamics_.findMax();if(max!==null&&addr<(max.key+max.value.size)&&addr>=min.key){var dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry===null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
+left.right=current.left;right.left=current.right;current.left=dummy.right;current.right=dummy.left;this.root_=current;};SplayTree.prototype.traverse_=function(f){const nodesToVisit=[this.root_];while(nodesToVisit.length>0){const node=nodesToVisit.shift();if(node===null)continue;f(node);nodesToVisit.push(node.left);nodesToVisit.push(node.right);}};SplayTree.Node=function(key,value){this.key=key;this.value=value;};SplayTree.Node.prototype.left=null;SplayTree.Node.prototype.right=null;return{SplayTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CodeMap(){this.dynamics_=new tr.e.importer.v8.SplayTree();this.dynamicsNameGen_=new tr.e.importer.v8.CodeMap.NameGenerator();this.statics_=new tr.e.importer.v8.SplayTree();this.libraries_=new tr.e.importer.v8.SplayTree();this.pages_=[];}
+CodeMap.PAGE_ALIGNMENT=12;CodeMap.PAGE_SIZE=1<<CodeMap.PAGE_ALIGNMENT;CodeMap.prototype.addCode=function(start,codeEntry){this.deleteAllCoveredNodes_(this.dynamics_,start,start+codeEntry.size);this.dynamics_.insert(start,codeEntry);};CodeMap.prototype.moveCode=function(from,to){const removedNode=this.dynamics_.remove(from);this.deleteAllCoveredNodes_(this.dynamics_,to,to+removedNode.value.size);this.dynamics_.insert(to,removedNode.value);};CodeMap.prototype.deleteCode=function(start){const removedNode=this.dynamics_.remove(start);};CodeMap.prototype.addLibrary=function(start,codeEntry){this.markPages_(start,start+codeEntry.size);this.libraries_.insert(start,codeEntry);};CodeMap.prototype.addStaticCode=function(start,codeEntry){this.statics_.insert(start,codeEntry);};CodeMap.prototype.markPages_=function(start,end){for(let addr=start;addr<=end;addr+=CodeMap.PAGE_SIZE){this.pages_[addr>>>CodeMap.PAGE_ALIGNMENT]=1;}};CodeMap.prototype.deleteAllCoveredNodes_=function(tree,start,end){const toDelete=[];let addr=end-1;while(addr>=start){const node=tree.findGreatestLessThan(addr);if(!node)break;const start2=node.key;const end2=start2+node.value.size;if(start2<end&&start<end2)toDelete.push(start2);addr=start2-1;}
+for(let i=0,l=toDelete.length;i<l;++i)tree.remove(toDelete[i]);};CodeMap.prototype.isAddressBelongsTo_=function(addr,node){return addr>=node.key&&addr<(node.key+node.value.size);};CodeMap.prototype.findInTree_=function(tree,addr){const node=tree.findGreatestLessThan(addr);return node&&this.isAddressBelongsTo_(addr,node)?node.value:null;};CodeMap.prototype.findEntryInLibraries=function(addr){const pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.libraries_,addr);}
+return undefined;};CodeMap.prototype.findEntry=function(addr){const pageAddr=addr>>>CodeMap.PAGE_ALIGNMENT;if(pageAddr in this.pages_){return this.findInTree_(this.statics_,addr)||this.findInTree_(this.libraries_,addr);}
+const min=this.dynamics_.findMin();const max=this.dynamics_.findMax();if(max!==null&&addr<(max.key+max.value.size)&&addr>=min.key){const dynaEntry=this.findInTree_(this.dynamics_,addr);if(dynaEntry===null)return null;if(!dynaEntry.nameUpdated_){dynaEntry.name=this.dynamicsNameGen_.getName(dynaEntry.name);dynaEntry.nameUpdated_=true;}
 return dynaEntry;}
-return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){var node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeState={COMPILED:0,OPTIMIZABLE:1,OPTIMIZED:2};CodeMap.CodeEntry=function(size,opt_name,opt_type){this.id=tr.b.GUID.allocateSimple();this.size=size;this.name_=opt_name||'';this.type=opt_type||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype={__proto__:Object.prototype,get name(){return this.name_;},set name(value){this.name_=value;},toString:function(){this.name_+': '+this.size.toString(16);}};CodeMap.CodeEntry.TYPE={SHARED_LIB:'SHARED_LIB',CPP:'CPP'};CodeMap.DynamicFuncCodeEntry=function(size,type,func,state){CodeMap.CodeEntry.call(this,size,'',type);this.func=func;this.state=state;};CodeMap.DynamicFuncCodeEntry.STATE_PREFIX=['','~','*'];CodeMap.DynamicFuncCodeEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){return CodeMap.DynamicFuncCodeEntry.STATE_PREFIX[this.state]+
-this.func.name;},set name(value){this.name_=value;},getRawName:function(){return this.func.getName();},isJSFunction:function(){return true;},toString:function(){return this.type+': '+this.name+': '+this.size.toString(16);}};CodeMap.FunctionEntry=function(name){CodeMap.CodeEntry.call(this,0,name);};CodeMap.FunctionEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){var name=this.name_;if(name.length===0){name='<anonymous>';}else if(name.charAt(0)===' '){name='<anonymous>'+name;}
+return null;};CodeMap.prototype.findDynamicEntryByStartAddress=function(addr){const node=this.dynamics_.find(addr);return node?node.value:null;};CodeMap.prototype.getAllDynamicEntries=function(){return this.dynamics_.exportValues();};CodeMap.prototype.getAllDynamicEntriesWithAddresses=function(){return this.dynamics_.exportKeysAndValues();};CodeMap.prototype.getAllStaticEntries=function(){return this.statics_.exportValues();};CodeMap.prototype.getAllLibrariesEntries=function(){return this.libraries_.exportValues();};CodeMap.CodeState={COMPILED:0,OPTIMIZABLE:1,OPTIMIZED:2};CodeMap.CodeEntry=function(size,opt_name,opt_type){this.id=tr.b.GUID.allocateSimple();this.size=size;this.name_=opt_name||'';this.type=opt_type||'';this.nameUpdated_=false;};CodeMap.CodeEntry.prototype={__proto__:Object.prototype,get name(){return this.name_;},set name(value){this.name_=value;},toString(){this.name_+': '+this.size.toString(16);}};CodeMap.CodeEntry.TYPE={SHARED_LIB:'SHARED_LIB',CPP:'CPP'};CodeMap.DynamicFuncCodeEntry=function(size,type,func,state){CodeMap.CodeEntry.call(this,size,'',type);this.func=func;this.state=state;};CodeMap.DynamicFuncCodeEntry.STATE_PREFIX=['','~','*'];CodeMap.DynamicFuncCodeEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){return CodeMap.DynamicFuncCodeEntry.STATE_PREFIX[this.state]+
+this.func.name;},set name(value){this.name_=value;},getRawName(){return this.func.getName();},isJSFunction(){return true;},toString(){return this.type+': '+this.name+': '+this.size.toString(16);}};CodeMap.FunctionEntry=function(name){CodeMap.CodeEntry.call(this,0,name);};CodeMap.FunctionEntry.prototype={__proto__:CodeMap.CodeEntry.prototype,get name(){let name=this.name_;if(name.length===0){name='<anonymous>';}else if(name.charAt(0)===' '){name='<anonymous>'+name;}
 return name;},set name(value){this.name_=value;}};CodeMap.NameGenerator=function(){this.knownNames_={};};CodeMap.NameGenerator.prototype.getName=function(name){if(!(name in this.knownNames_)){this.knownNames_[name]=0;return name;}
-var count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){}
-CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){var fieldRe=CsvParser.CSV_FIELD_RE_;var doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;var pos=0;var endPos=line.length;var fields=[];if(endPos>0){do{var fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){var field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{var field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
+const count=++this.knownNames_[name];return name+' {'+count+'}';};return{CodeMap,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){function CsvParser(){}
+CsvParser.CSV_FIELD_RE_=/^"((?:[^"]|"")*)"|([^,]*)/;CsvParser.DOUBLE_QUOTE_RE_=/""/g;CsvParser.prototype.parseLine=function(line){const fieldRe=CsvParser.CSV_FIELD_RE_;const doubleQuoteRe=CsvParser.DOUBLE_QUOTE_RE_;let pos=0;const endPos=line.length;const fields=[];if(endPos>0){do{const fieldMatch=fieldRe.exec(line.substr(pos));if(typeof fieldMatch[1]==='string'){const field=fieldMatch[1];pos+=field.length+3;fields.push(field.replace(doubleQuoteRe,'"'));}else{const field=fieldMatch[2];pos+=field.length+1;fields.push(field);}}while(pos<=endPos);}
 return fields;};function LogReader(dispatchTable){this.dispatchTable_=dispatchTable;this.lineNum_=0;this.csvParser_=new CsvParser();}
-LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
-return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){var command=fields[0];if(!(command in this.dispatchTable_))return;var dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
-var parsedFields=[];for(var i=0;i<dispatch.parsers.length;++i){var parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser==='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
-dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(var i=0,n=lines.length;i<n;++i,++this.lineNum_){var line=lines[i];if(!line){continue;}
-try{var fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
+LogReader.prototype.printError=function(str){};LogReader.prototype.processLogChunk=function(chunk){this.processLog_(chunk.split('\n'));};LogReader.prototype.processLogLine=function(line){this.processLog_([line]);};LogReader.prototype.processStack=function(pc,func,stack){const fullStack=func?[pc,func]:[pc];let prevFrame=pc;for(let i=0,n=stack.length;i<n;++i){const frame=stack[i];const firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
+return fullStack;};LogReader.prototype.skipDispatch=function(dispatch){return false;};LogReader.prototype.dispatchLogRow_=function(fields){const command=fields[0];if(!(command in this.dispatchTable_))return;const dispatch=this.dispatchTable_[command];if(dispatch===null||this.skipDispatch(dispatch)){return;}
+const parsedFields=[];for(let i=0;i<dispatch.parsers.length;++i){const parser=dispatch.parsers[i];if(parser===null){parsedFields.push(fields[1+i]);}else if(typeof parser==='function'){parsedFields.push(parser(fields[1+i]));}else{parsedFields.push(fields.slice(1+i));break;}}
+dispatch.processor.apply(this,parsedFields);};LogReader.prototype.processLog_=function(lines){for(let i=0,n=lines.length;i<n;++i,++this.lineNum_){const line=lines[i];if(!line){continue;}
+try{const fields=this.csvParser_.parseLine(line);this.dispatchLogRow_(fields);}catch(e){this.printError('line '+(this.lineNum_+1)+': '+
 (e.message||e));}}};return{LogReader,};});'use strict';tr.exportTo('tr.model',function(){function ProfileNode(id,title,parentNode){this.id_=id;this.title_=title;this.parentNode_=parentNode;this.colorId_=-1;this.userFriendlyStack_=[];}
 ProfileNode.prototype={__proto__:Object.prototype,get title(){return this.title_;},get parentNode(){return this.parentNode_;},set parentNode(value){this.parentNode_=value;},get id(){return this.id_;},get colorId(){return this.colorId_;},set colorId(value){this.colorId_=value;},get userFriendlyName(){return this.title_;},get userFriendlyStack(){if(this.userFriendlyStack_.length===0){this.userFriendlyStack_=[this.userFriendlyName];if(this.parentNode_!==undefined){this.userFriendlyStack_=this.userFriendlyStack_.concat(this.parentNode_.userFriendlyStack);}}
-return this.userFriendlyStack_;},get sampleTitle(){throw new Error('Not implemented.');}};tr.model.EventRegistry.register(ProfileNode,{name:'Node',pluralName:'Nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.model',function(){function ProfileTree(){this.startTime_=undefined;this.endTime_=undefined;this.tree_=new Map();this.pid_=-1;this.tid_=-1;}
-ProfileTree.prototype={__proto__:Object.prototype,get pid(){return this.pid_;},set pid(value){this.pid_=value;},get tid(){return this.tid_;},set tid(value){this.tid_=value;},get tree(){return this.tree_;},get startTime(){return this.startTime_;},set startTime(value){this.startTime_=value;this.endTime_=value;},get endTime(){return this.endTime_;},set endTime(value){this.endTime_=value;},add:function(node){if(this.tree_.has(node.id)){throw new Error('Conflict id in the profile tree.');}
-this.tree_.set(node.id,node);return node;},getNode:function(nodeId){return this.tree_.get(nodeId);}};return{ProfileTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){var CodeEntry=tr.e.importer.v8.CodeMap.CodeEntry;var CodeMap=tr.e.importer.v8.CodeMap;var ColorScheme=tr.b.ColorScheme;var DynamicFuncCodeEntry=tr.e.importer.v8.CodeMap.DynamicFuncCodeEntry;var FunctionEntry=tr.e.importer.v8.CodeMap.FunctionEntry;var ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.profileTree_=new tr.model.ProfileTree();this.profileTree_.add(new ProfileNodeType(-1,{url:'',functionName:'unknown'}));this.v8_stack_timeline_=[];}
-var kV8BinarySuffixes=['/d8','/libv8.so'];var TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
-return eventData.substring(0,11)==='v8-version,'||eventData.substring(0,12)==='timer-event,'||eventData.substring(0,5)==='tick,'||eventData.substring(0,15)==='shared-library,'||eventData.substring(0,9)==='profiler,'||eventData.substring(0,14)==='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_:function(name,startInUs,lengthInUs){var args=TimerEventDefaultArgs[name];if(args===undefined)return;var startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);var lengthInMs=tr.b.convertUnit(lengthInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);var colorId=ColorScheme.getColorIdForGeneralPurposeString(name);var slice=new tr.model.ThreadSlice('v8',name,colorId,startInMs,args,lengthInMs);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_:function(name,startInUs){var args=TimerEventDefaultArgs[name];if(args===undefined)return;var startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,startInMs,args);},processTimerEventEnd_:function(name,endInUs){var endInMs=tr.b.convertUnit(endInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.endSlice(endInMs);},processCodeCreateEvent_:function(type,kind,address,size,name,maybeFunc){function parseState(s){switch(s){case'':return CodeMap.CodeState.COMPILED;case'~':return CodeMap.CodeState.OPTIMIZABLE;case'*':return CodeMap.CodeState.OPTIMIZED;}
+return this.userFriendlyStack_;},get sampleTitle(){throw new Error('Not implemented.');}};tr.model.EventRegistry.register(ProfileNode,{name:'Node',pluralName:'Nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.e.v8',function(){const ProfileNode=tr.model.ProfileNode;function V8CpuProfileNode(id,callFrame,parentNode){ProfileNode.call(this,id,callFrame.functionName,parentNode);this.callFrame_=tr.b.deepCopy(callFrame);this.deoptReason_='';this.colorId_=tr.b.ColorScheme.getColorIdForGeneralPurposeString(callFrame.functionName);}
+V8CpuProfileNode.prototype={__proto__:ProfileNode.prototype,get functionName(){return this.callFrame_.functionName;},get scriptId(){return this.callFrame_.scriptId;},get url(){if(!this.callFrame_.url){return'unknown';}
+let url=this.callFrame_.url;if(this.callFrame_.lineNumber===undefined){return url;}
+url=url+':'+this.callFrame_.lineNumber;if(this.callFrame_.columnNumber===undefined){return url;}
+url=url+':'+this.callFrame_.columnNumber;return url;},get deoptReason(){return this.deoptReason_;},set deoptReason(value){this.deoptReason_=value;},get userFriendlyName(){const name=this.functionName+' url: '+this.url;return!this.deoptReason_?name:name+' Deoptimized reason: '+this.deoptReason_;},get sampleTitle(){return'V8 Sample';}};V8CpuProfileNode.constructFromObject=function(profileTree,node){const nodeId=node.id;if(nodeId===1){return undefined;}
+const parentNode=profileTree.getNode(node.parent);const profileNode=new V8CpuProfileNode(nodeId,node.callFrame,parentNode);if(node.deoptReason!==undefined){profileNode.deoptReason=node.deoptReason;}
+return profileNode;};ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'cpuProfile',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'legacySample',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.model',function(){function ProfileTree(){this.startTime_=undefined;this.endTime_=undefined;this.tree_=new Map();this.pid_=-1;this.tid_=-1;}
+ProfileTree.prototype={__proto__:Object.prototype,get pid(){return this.pid_;},set pid(value){this.pid_=value;},get tid(){return this.tid_;},set tid(value){this.tid_=value;},get tree(){return this.tree_;},get startTime(){return this.startTime_;},set startTime(value){this.startTime_=value;this.endTime_=value;},get endTime(){return this.endTime_;},set endTime(value){this.endTime_=value;},add(node){if(this.tree_.has(node.id)){throw new Error('Conflict id in the profile tree.');}
+this.tree_.set(node.id,node);return node;},getNode(nodeId){return this.tree_.get(nodeId);}};return{ProfileTree,};});'use strict';tr.exportTo('tr.e.importer.v8',function(){const CodeEntry=tr.e.importer.v8.CodeMap.CodeEntry;const CodeMap=tr.e.importer.v8.CodeMap;const ColorScheme=tr.b.ColorScheme;const DynamicFuncCodeEntry=tr.e.importer.v8.CodeMap.DynamicFuncCodeEntry;const FunctionEntry=tr.e.importer.v8.CodeMap.FunctionEntry;const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');function V8LogImporter(model,eventData){this.importPriority=3;this.model_=model;this.logData_=eventData;this.code_map_=new CodeMap();this.v8_timer_thread_=undefined;this.v8_thread_=undefined;this.profileTree_=new tr.model.ProfileTree();this.profileTree_.add(new ProfileNodeType(-1,{url:'',functionName:'unknown'}));this.v8_stack_timeline_=[];}
+const kV8BinarySuffixes=['/d8','/libv8.so'];const TimerEventDefaultArgs={'V8.Execute':{pause:false,no_execution:false},'V8.External':{pause:false,no_execution:true},'V8.CompileFullCode':{pause:true,no_execution:true},'V8.RecompileSynchronous':{pause:true,no_execution:true},'V8.RecompileParallel':{pause:false,no_execution:false},'V8.CompileEval':{pause:true,no_execution:true},'V8.Parse':{pause:true,no_execution:true},'V8.PreParse':{pause:true,no_execution:true},'V8.ParseLazy':{pause:true,no_execution:true},'V8.GCScavenger':{pause:true,no_execution:true},'V8.GCCompactor':{pause:true,no_execution:true},'V8.GCContext':{pause:true,no_execution:true}};V8LogImporter.canImport=function(eventData){if(typeof(eventData)!=='string'&&!(eventData instanceof String)){return false;}
+return eventData.substring(0,11)==='v8-version,'||eventData.substring(0,12)==='timer-event,'||eventData.substring(0,5)==='tick,'||eventData.substring(0,15)==='shared-library,'||eventData.substring(0,9)==='profiler,'||eventData.substring(0,14)==='code-creation,';};V8LogImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'V8LogImporter';},processTimerEvent_(name,startInUs,lengthInUs){const args=TimerEventDefaultArgs[name];if(args===undefined)return;const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);const lengthInMs=tr.b.convertUnit(lengthInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);const colorId=ColorScheme.getColorIdForGeneralPurposeString(name);const slice=new tr.model.ThreadSlice('v8',name,colorId,startInMs,args,lengthInMs);this.v8_timer_thread_.sliceGroup.pushSlice(slice);},processTimerEventStart_(name,startInUs){const args=TimerEventDefaultArgs[name];if(args===undefined)return;const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.beginSlice('v8',name,startInMs,args);},processTimerEventEnd_(name,endInUs){const endInMs=tr.b.convertUnit(endInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);this.v8_timer_thread_.sliceGroup.endSlice(endInMs);},processCodeCreateEvent_(type,kind,address,size,name,maybeFunc){function parseState(s){switch(s){case'':return CodeMap.CodeState.COMPILED;case'~':return CodeMap.CodeState.OPTIMIZABLE;case'*':return CodeMap.CodeState.OPTIMIZED;}
 throw new Error('unknown code state: '+s);}
-if(maybeFunc.length){var funcAddr=parseInt(maybeFunc[0]);var state=parseState(maybeFunc[1]);var func=this.code_map_.findDynamicEntryByStartAddress(funcAddr);if(!func){func=new FunctionEntry(name);func.kind=kind;this.code_map_.addCode(funcAddr,func);}else if(func.name!==name){func.name=name;}
-var entry=this.code_map_.findDynamicEntryByStartAddress(address);if(entry){if(entry.size===size&&entry.func===func){entry.state=state;}}else{entry=new DynamicFuncCodeEntry(size,type,func,state);entry.kind=kind;this.code_map_.addCode(address,entry);}}else{var codeEntry=new CodeEntry(size,name);codeEntry.kind=kind;this.code_map_.addCode(address,codeEntry);}},processCodeMoveEvent_:function(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_:function(address){this.code_map_.deleteCode(address);},processSharedLibrary_:function(name,start,end){var codeEntry=new CodeEntry(end-start,name,CodeEntry.TYPE.SHARED_LIB);codeEntry.kind=-3;for(var i=0;i<kV8BinarySuffixes.length;i++){var suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){codeEntry.kind=-1;break;}}
-this.code_map_.addLibrary(start,codeEntry);},processCppSymbol_:function(address,size,name){var codeEntry=new CodeEntry(size,name,CodeEntry.TYPE.CPP);codeEntry.kind=-1;this.code_map_.addStaticCode(address,codeEntry);},processTickEvent_:function(pc,startInUs,isExternalCallback,tosOrExternalCallback,vmstate,stack){var startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);function findChildWithEntryID(stackFrame,entryID){for(var i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID===entryID){return stackFrame.children[i];}}
+if(maybeFunc.length){const funcAddr=parseInt(maybeFunc[0]);const state=parseState(maybeFunc[1]);let func=this.code_map_.findDynamicEntryByStartAddress(funcAddr);if(!func){func=new FunctionEntry(name);func.kind=kind;this.code_map_.addCode(funcAddr,func);}else if(func.name!==name){func.name=name;}
+let entry=this.code_map_.findDynamicEntryByStartAddress(address);if(entry){if(entry.size===size&&entry.func===func){entry.state=state;}}else{entry=new DynamicFuncCodeEntry(size,type,func,state);entry.kind=kind;this.code_map_.addCode(address,entry);}}else{const codeEntry=new CodeEntry(size,name);codeEntry.kind=kind;this.code_map_.addCode(address,codeEntry);}},processCodeMoveEvent_(from,to){this.code_map_.moveCode(from,to);},processCodeDeleteEvent_(address){this.code_map_.deleteCode(address);},processSharedLibrary_(name,start,end){const codeEntry=new CodeEntry(end-start,name,CodeEntry.TYPE.SHARED_LIB);codeEntry.kind=-3;for(let i=0;i<kV8BinarySuffixes.length;i++){const suffix=kV8BinarySuffixes[i];if(name.indexOf(suffix,name.length-suffix.length)>=0){codeEntry.kind=-1;break;}}
+this.code_map_.addLibrary(start,codeEntry);},processCppSymbol_(address,size,name){const codeEntry=new CodeEntry(size,name,CodeEntry.TYPE.CPP);codeEntry.kind=-1;this.code_map_.addStaticCode(address,codeEntry);},processTickEvent_(pc,startInUs,isExternalCallback,tosOrExternalCallback,vmstate,stack){const startInMs=tr.b.convertUnit(startInUs,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);function findChildWithEntryID(stackFrame,entryID){for(let i=0;i<stackFrame.children.length;i++){if(stackFrame.children[i].entryID===entryID){return stackFrame.children[i];}}
 return undefined;}
-function processStack(pc,func,stack){var fullStack=func?[pc,func]:[pc];var prevFrame=pc;for(var i=0,n=stack.length;i<n;++i){var frame=stack[i];var firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
+function processStack(pc,func,stack){const fullStack=func?[pc,func]:[pc];let prevFrame=pc;for(let i=0,n=stack.length;i<n;++i){const frame=stack[i];const firstChar=frame.charAt(0);if(firstChar==='+'||firstChar==='-'){prevFrame+=parseInt(frame,16);fullStack.push(prevFrame);}else if(firstChar!=='o'){fullStack.push(parseInt(frame,16));}}
 return fullStack;}
-if(isExternalCallback){pc=tosOrExternalCallback;tosOrExternalCallback=0;}else if(tosOrExternalCallback){var funcEntry=this.code_map_.findEntry(tosOrExternalCallback);if(!funcEntry||!funcEntry.isJSFunction||!funcEntry.isJSFunction()){tosOrExternalCallback=0;}}
-var processedStack=processStack(pc,tosOrExternalCallback,stack);var node=undefined;var lastNode=undefined;processedStack=processedStack.reverse();for(var i=0,n=processedStack.length;i<n;i++){var frame=processedStack[i];if(!frame)break;var entry=this.code_map_.findEntry(frame);if(!entry&&i!==0){continue;}
-var sourceInfo=undefined;if(entry&&entry.type===CodeEntry.TYPE.CPP){var libEntry=this.code_map_.findEntryInLibraries(frame);if(libEntry){sourceInfo={file:libEntry.name};}}
-var entryId=entry?entry.id:-1;var node=this.profileTree_.getNode(entryId);if(node===undefined){node=this.profileTree_.add(new ProfileNodeType(entryId,{functionName:entry.name,url:sourceInfo?sourceInfo.file:'',lineNumber:sourceInfo?sourceInfo.line:undefined,columnNumber:sourceInfo?sourceInfo.column:undefined,scriptId:sourceInfo?sourceInfo.scriptId:undefined},lastNode));}
+if(isExternalCallback){pc=tosOrExternalCallback;tosOrExternalCallback=0;}else if(tosOrExternalCallback){const funcEntry=this.code_map_.findEntry(tosOrExternalCallback);if(!funcEntry||!funcEntry.isJSFunction||!funcEntry.isJSFunction()){tosOrExternalCallback=0;}}
+let processedStack=processStack(pc,tosOrExternalCallback,stack);let node=undefined;let lastNode=undefined;processedStack=processedStack.reverse();for(let i=0,n=processedStack.length;i<n;i++){const frame=processedStack[i];if(!frame)break;const entry=this.code_map_.findEntry(frame);if(!entry&&i!==0){continue;}
+let sourceInfo=undefined;if(entry&&entry.type===CodeEntry.TYPE.CPP){const libEntry=this.code_map_.findEntryInLibraries(frame);if(libEntry){sourceInfo={file:libEntry.name};}}
+const entryId=entry?entry.id:-1;node=this.profileTree_.getNode(entryId);if(node===undefined){node=this.profileTree_.add(new ProfileNodeType(entryId,{functionName:entry.name,url:sourceInfo?sourceInfo.file:'',lineNumber:sourceInfo?sourceInfo.line:undefined,columnNumber:sourceInfo?sourceInfo.column:undefined,scriptId:sourceInfo?sourceInfo.scriptId:undefined},lastNode));}
 lastNode=node;}
-this.model_.samples.push(new tr.model.Sample(startInMs,'V8 PC',node,this.v8_thread_,undefined,1));},processDistortion_:function(distortionInPicoseconds){},processPlotRange_:function(start,end){},processV8Version_:function(major,minor,build,patch,candidate){},importEvents:function(){var logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null,'var-args'],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'cpp':{parsers:[parseInt,parseInt,null],processor:this.processCppSymbol_.bind(this)},'tick':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';var lines=this.logData_.split('\n');for(var i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
-function addSlices(slices,thread){for(var i=0;i<slices.length;i++){var duration=slices[i].end-slices[i].start;var slice=new tr.model.ThreadSlice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
+this.model_.samples.push(new tr.model.Sample(startInMs,'V8 PC',node,this.v8_thread_,undefined,1));},processDistortion_(distortionInPicoseconds){},processPlotRange_(start,end){},processV8Version_(major,minor,build,patch,candidate){},importEvents(){const logreader=new tr.e.importer.v8.LogReader({'timer-event':{parsers:[null,parseInt,parseInt],processor:this.processTimerEvent_.bind(this)},'shared-library':{parsers:[null,parseInt,parseInt],processor:this.processSharedLibrary_.bind(this)},'timer-event-start':{parsers:[null,parseInt],processor:this.processTimerEventStart_.bind(this)},'timer-event-end':{parsers:[null,parseInt],processor:this.processTimerEventEnd_.bind(this)},'code-creation':{parsers:[null,parseInt,parseInt,parseInt,null,'var-args'],processor:this.processCodeCreateEvent_.bind(this)},'code-move':{parsers:[parseInt,parseInt],processor:this.processCodeMoveEvent_.bind(this)},'code-delete':{parsers:[parseInt],processor:this.processCodeDeleteEvent_.bind(this)},'cpp':{parsers:[parseInt,parseInt,null],processor:this.processCppSymbol_.bind(this)},'tick':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt,'var-args'],processor:this.processTickEvent_.bind(this)},'distortion':{parsers:[parseInt],processor:this.processDistortion_.bind(this)},'plot-range':{parsers:[parseInt,parseInt],processor:this.processPlotRange_.bind(this)},'v8-version':{parsers:[parseInt,parseInt,parseInt,parseInt,parseInt],processor:this.processV8Version_.bind(this)}});this.v8_timer_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(1);this.v8_timer_thread_.name='V8 Timers';this.v8_thread_=this.model_.getOrCreateProcess(-32).getOrCreateThread(2);this.v8_thread_.name='V8';const lines=this.logData_.split('\n');for(let i=0;i<lines.length;i++){logreader.processLogLine(lines[i]);}
+function addSlices(slices,thread){for(let i=0;i<slices.length;i++){const duration=slices[i].end-slices[i].start;const slice=new tr.model.ThreadSlice('v8',slices[i].name,ColorScheme.getColorIdForGeneralPurposeString(slices[i].name),slices[i].start,{},duration);thread.sliceGroup.pushSlice(slice);addSlices(slices[i].children,thread);}}
 addSlices(this.v8_stack_timeline_,this.v8_thread_);}};tr.importer.Importer.register(V8LogImporter);return{V8LogImporter,};});'use strict';tr.exportTo('tr.e.importer',function(){function ZipImporter(model,eventData){if(eventData instanceof ArrayBuffer){eventData=new Uint8Array(eventData);}
 this.model_=model;this.eventData_=eventData;}
-ZipImporter.canImport=function(eventData){var header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,2));}else if(typeof(eventData)==='string'||eventData instanceof String){header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];}else{return false;}
-return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer:function(){return true;},extractSubtraces:function(){var zip=new JSZip(this.eventData_);var subtraces=[];for(var idx in zip.files){subtraces.push(zip.files[idx].asBinary());}
-return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter,};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size,count){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;this.count=count;}
-function HeapDump(processMemoryDump,allocatorName){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.entries=[];}
-HeapDump.prototype={addEntry:function(leafStackFrame,objectTypeName,size,count){var entry=new HeapEntry(this,leafStackFrame,objectTypeName,size,count);this.entries.push(entry);return entry;}};return{HeapEntry,HeapDump,};});'use strict';tr.exportTo('tr.e.importer',function(){function HeapDumpTraceEventImporter(model,processMemoryDump,processObjectTypeNameMap,idPrefix,dumpId){this.model_=model;this.processObjectTypeNameMap_=processObjectTypeNameMap;this.idPrefix_=idPrefix;this.processMemoryDump_=processMemoryDump;this.pid_=this.processMemoryDump_.process.pid;this.dumpId_=dumpId;}
-HeapDumpTraceEventImporter.prototype={parseRawHeapDump:function(rawHeapDump,allocatorName){var model=this.model_;var processMemoryDump=this.processMemoryDump_;var heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);var entries=rawHeapDump.entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+this.pid_+' and dump ID='+this.dumpId_+'.'});return undefined;}
-var isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&this.processObjectTypeNameMap_===undefined){return undefined;}
-for(var i=0;i<entries.length;i++){var entry=entries[i];var leafStackFrameIndex=entry.bt;var leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{var leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
+ZipImporter.canImport=function(eventData){let header;if(eventData instanceof ArrayBuffer){header=new Uint8Array(eventData.slice(0,2));}else if(typeof(eventData)==='string'||eventData instanceof String){header=[eventData.charCodeAt(0),eventData.charCodeAt(1)];}else{return false;}
+return header[0]==='P'.charCodeAt(0)&&header[1]==='K'.charCodeAt(0);};ZipImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'ZipImporter';},isTraceDataContainer(){return true;},extractSubtraces(){const zip=new JSZip(this.eventData_);const subtraces=[];for(const idx in zip.files){subtraces.push(zip.files[idx].asBinary());}
+return subtraces;}};tr.importer.Importer.register(ZipImporter);return{ZipImporter,};});'use strict';tr.exportTo('tr.model',function(){function HeapEntry(heapDump,leafStackFrame,objectTypeName,size,count,valuesAreTotals){this.heapDump=heapDump;this.leafStackFrame=leafStackFrame;this.objectTypeName=objectTypeName;this.size=size;this.count=count;this.valuesAreTotals=valuesAreTotals;}
+function HeapDump(processMemoryDump,allocatorName,isComplete){this.processMemoryDump=processMemoryDump;this.allocatorName=allocatorName;this.isComplete=isComplete;this.entries=[];}
+HeapDump.prototype={addEntry(leafStackFrame,objectTypeName,size,count,opt_valuesAreTotals){if(opt_valuesAreTotals===undefined)opt_valuesAreTotals=true;const valuesAreTotals=opt_valuesAreTotals;const entry=new HeapEntry(this,leafStackFrame,objectTypeName,size,count,valuesAreTotals);this.entries.push(entry);return entry;}};return{HeapEntry,HeapDump,};});'use strict';tr.exportTo('tr.e.importer',function(){function HeapDumpTraceEventImporter(heapProfileExpander,stackFrames,processMemoryDump,idPrefix,model){this.expander=heapProfileExpander;this.stackFrames=stackFrames;this.processMemoryDump=processMemoryDump;this.idPrefix=idPrefix;this.model=model;}
+HeapDumpTraceEventImporter.prototype={getLeafStackFrame(stackFrameId){if(stackFrameId==='')return undefined;const parentId=this.idPrefix+stackFrameId;const id=parentId+':self';if(!this.stackFrames[id]){const parentStackFrame=this.stackFrames[parentId];const stackFrame=new tr.model.StackFrame(parentStackFrame,id,'<self>',undefined);this.model.addStackFrame(stackFrame);}
+return this.stackFrames[id];},parseEntry(entry,heapDump){const size=entry.size;const count=entry.count;const leafStackFrame=this.getLeafStackFrame(entry.node.id);const objectTypeName=entry.type.name;const valuesAreTotals=false;if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+typeId+')',});}
+heapDump.addEntry(leafStackFrame,objectTypeName,size,count,valuesAreTotals);},parse(){const heapDumps={};const inflated=this.expander.inflated;for(const[allocatorName,entries]of Object.entries(inflated)){const heapDump=new tr.model.HeapDump(this.processMemoryDump,allocatorName);for(const entry of entries){this.parseEntry(entry,heapDump);}
+heapDump.isComplete=true;heapDumps[allocatorName]=heapDump;}
+return heapDumps;},};return{HeapDumpTraceEventImporter,};});'use strict';tr.exportTo('tr.e.importer',function(){function LegacyHeapDumpTraceEventImporter(model,processMemoryDump,processObjectTypeNameMap,idPrefix,dumpId,rawHeapDumps){this.model_=model;this.processObjectTypeNameMap_=processObjectTypeNameMap;this.idPrefix_=idPrefix;this.processMemoryDump_=processMemoryDump;this.pid_=this.processMemoryDump_.process.pid;this.dumpId_=dumpId;this.rawHeapDumps_=rawHeapDumps;}
+LegacyHeapDumpTraceEventImporter.prototype={parseRawHeapDump(rawHeapDump,allocatorName){const model=this.model_;const processMemoryDump=this.processMemoryDump_;const heapDump=new tr.model.HeapDump(processMemoryDump,allocatorName);const entries=rawHeapDump.entries;if(entries===undefined||entries.length===0){this.model_.importWarning({type:'memory_dump_parse_error',message:'No heap entries in a '+allocatorName+' heap dump for PID='+this.pid_+' and dump ID='+this.dumpId_+'.'});return undefined;}
+const isOldFormat=entries[0].bt===undefined;if(!isOldFormat&&this.processObjectTypeNameMap_===undefined){return undefined;}
+for(let i=0;i<entries.length;i++){const entry=entries[i];const size=parseInt(entry.size,16);const leafStackFrameIndex=entry.bt;let leafStackFrame;if(isOldFormat){if(leafStackFrameIndex===undefined){leafStackFrame=undefined;}else{let leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+
 leafStackFrameId+') of heap entry '+i+' (size '+
 size+') in a '+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}
 leafStackFrameId+=':self';if(model.stackFrames[leafStackFrameId]!==undefined){leafStackFrame=model.stackFrames[leafStackFrameId];}else{leafStackFrame=new tr.model.StackFrame(leafStackFrame,leafStackFrameId,'<self>',undefined);model.addStackFrame(leafStackFrame);}}}else{if(leafStackFrameIndex===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing stack frame ID of heap entry '+i+' (size '+size+') in a '+allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}
-var leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
+const leafStackFrameId=this.idPrefix_+leafStackFrameIndex;if(leafStackFrameIndex===''){leafStackFrame=undefined;}else{leafStackFrame=model.stackFrames[leafStackFrameId];if(leafStackFrame===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing leaf stack frame (ID '+leafStackFrameId+') of heap entry '+i+' (size '+size+') in a '+
 allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}}
-var objectTypeId=entry.type;var objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(this.processObjectTypeNameMap_===undefined){continue;}else{objectTypeName=this.processObjectTypeNameMap_[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
+const objectTypeId=entry.type;let objectTypeName;if(objectTypeId===undefined){objectTypeName=undefined;}else if(this.processObjectTypeNameMap_===undefined){continue;}else{objectTypeName=this.processObjectTypeNameMap_[objectTypeId];if(objectTypeName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing object type name (ID '+objectTypeId+') of heap entry '+i+' (size '+size+') in a '+
 allocatorName+' heap dump for PID='+this.pid_+'.'});continue;}}
-var size=parseInt(entry.size,16);var count=entry.count===undefined?undefined:parseInt(entry.count,16);heapDump.addEntry(leafStackFrame,objectTypeName,size,count);}
-return heapDump;},};return{HeapDumpTraceEventImporter,};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
-SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)return undefined;var domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString:function(){var str='';if(this.file_){str+=this.file_;}
+const count=entry.count===undefined?undefined:parseInt(entry.count,16);heapDump.addEntry(leafStackFrame,objectTypeName,size,count);}
+return heapDump;},parse(){const heapDumps={};for(const allocatorName in this.rawHeapDumps_){const rawHeapDump=this.rawHeapDumps_[allocatorName];const heapDump=this.parseRawHeapDump(rawHeapDump,allocatorName);if(heapDump!==undefined&&heapDump.entries.length>0){heapDumps[allocatorName]=heapDump;}}
+return heapDumps;},};return{LegacyHeapDumpTraceEventImporter,};});(function(window,Object,Array,Error,JSON,undefined){var partialComplete=varArgs(function(fn,args){var numBoundArgs=args.length;return varArgs(function(callArgs){for(var i=0;i<callArgs.length;i++){args[numBoundArgs+i]=callArgs[i];}
+args.length=numBoundArgs+callArgs.length;return fn.apply(this,args);});}),compose=varArgs(function(fns){var fnsList=arrayAsList(fns);function next(params,curFn){return[apply(params,curFn)];}
+return varArgs(function(startParams){return foldR(next,startParams,fnsList)[0];});});function compose2(f1,f2){return function(){return f1.call(this,f2.apply(this,arguments));}}
+function attr(key){return function(o){return o[key];};}
+var lazyUnion=varArgs(function(fns){return varArgs(function(params){var maybeValue;for(var i=0;i<len(fns);i++){maybeValue=apply(params,fns[i]);if(maybeValue){return maybeValue;}}});});function apply(args,fn){return fn.apply(undefined,args);}
+function varArgs(fn){var numberOfFixedArguments=fn.length-1,slice=Array.prototype.slice;if(numberOfFixedArguments==0){return function(){return fn.call(this,slice.call(arguments));}}else if(numberOfFixedArguments==1){return function(){return fn.call(this,arguments[0],slice.call(arguments,1));}}
+var argsHolder=Array(fn.length);return function(){for(var i=0;i<numberOfFixedArguments;i++){argsHolder[i]=arguments[i];}
+argsHolder[numberOfFixedArguments]=slice.call(arguments,numberOfFixedArguments);return fn.apply(this,argsHolder);}}
+function flip(fn){return function(a,b){return fn(b,a);}}
+function lazyIntersection(fn1,fn2){return function(param){return fn1(param)&&fn2(param);};}
+function noop(){}
+function always(){return true}
+function functor(val){return function(){return val;}}
+function isOfType(T,maybeSomething){return maybeSomething&&maybeSomething.constructor===T;}
+var len=attr('length'),isString=partialComplete(isOfType,String);function defined(value){return value!==undefined;}
+function hasAllProperties(fieldList,o){return(o instanceof Object)&&all(function(field){return(field in o);},fieldList);}
+function cons(x,xs){return[x,xs];}
+var emptyList=null,head=attr(0),tail=attr(1);function arrayAsList(inputArray){return reverseList(inputArray.reduce(flip(cons),emptyList));}
+var list=varArgs(arrayAsList);function listAsArray(list){return foldR(function(arraySoFar,listItem){arraySoFar.unshift(listItem);return arraySoFar;},[],list);}
+function map(fn,list){return list?cons(fn(head(list)),map(fn,tail(list))):emptyList;}
+function foldR(fn,startValue,list){return list?fn(foldR(fn,startValue,tail(list)),head(list)):startValue;}
+function foldR1(fn,list){return tail(list)?fn(foldR1(fn,tail(list)),head(list)):head(list);}
+function without(list,test,removedFn){return withoutInner(list,removedFn||noop);function withoutInner(subList,removedFn){return subList?(test(head(subList))?(removedFn(head(subList)),tail(subList)):cons(head(subList),withoutInner(tail(subList),removedFn))):emptyList;}}
+function all(fn,list){return!list||(fn(head(list))&&all(fn,tail(list)));}
+function applyEach(fnList,args){if(fnList){head(fnList).apply(null,args);applyEach(tail(fnList),args);}}
+function reverseList(list){function reverseInner(list,reversedAlready){if(!list){return reversedAlready;}
+return reverseInner(tail(list),cons(head(list),reversedAlready))}
+return reverseInner(list,emptyList);}
+function first(test,list){return list&&(test(head(list))?head(list):first(test,tail(list)));}
+function clarinet(eventBus){"use strict";var
+emitSaxKey=eventBus(SAX_KEY).emit,emitValueOpen=eventBus(SAX_VALUE_OPEN).emit,emitValueClose=eventBus(SAX_VALUE_CLOSE).emit,emitFail=eventBus(FAIL_EVENT).emit,MAX_BUFFER_LENGTH=64*1024,stringTokenPattern=/[\\"\n]/g,_n=0,BEGIN=_n++,VALUE=_n++,OPEN_OBJECT=_n++,CLOSE_OBJECT=_n++,OPEN_ARRAY=_n++,CLOSE_ARRAY=_n++,STRING=_n++,OPEN_KEY=_n++,CLOSE_KEY=_n++,TRUE=_n++,TRUE2=_n++,TRUE3=_n++,FALSE=_n++,FALSE2=_n++,FALSE3=_n++,FALSE4=_n++,NULL=_n++,NULL2=_n++,NULL3=_n++,NUMBER_DECIMAL_POINT=_n++,NUMBER_DIGIT=_n,bufferCheckPosition=MAX_BUFFER_LENGTH,latestError,c,p,textNode=undefined,numberNode="",slashed=false,closed=false,state=BEGIN,stack=[],unicodeS=null,unicodeI=0,depth=0,position=0,column=0,line=1;function checkBufferLength(){var maxActual=0;if(textNode!==undefined&&textNode.length>MAX_BUFFER_LENGTH){emitError("Max buffer length exceeded: textNode");maxActual=Math.max(maxActual,textNode.length);}
+if(numberNode.length>MAX_BUFFER_LENGTH){emitError("Max buffer length exceeded: numberNode");maxActual=Math.max(maxActual,numberNode.length);}
+bufferCheckPosition=(MAX_BUFFER_LENGTH-maxActual)
++position;}
+eventBus(STREAM_DATA).on(handleData);eventBus(STREAM_END).on(handleStreamEnd);function emitError(errorString){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+latestError=Error(errorString+"\nLn: "+line+"\nCol: "+column+"\nChr: "+c);emitFail(errorReport(undefined,undefined,latestError));}
+function handleStreamEnd(){if(state==BEGIN){emitValueOpen({});emitValueClose();closed=true;return;}
+if(state!==VALUE||depth!==0)
+emitError("Unexpected end");if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+closed=true;}
+function whitespace(c){return c=='\r'||c=='\n'||c==' '||c=='\t';}
+function handleData(chunk){if(latestError)
+return;if(closed){return emitError("Cannot write after close");}
+var i=0;c=chunk[0];while(c){p=c;c=chunk[i++];if(!c)break;position++;if(c=="\n"){line++;column=0;}else column++;switch(state){case BEGIN:if(c==="{")state=OPEN_OBJECT;else if(c==="[")state=OPEN_ARRAY;else if(!whitespace(c))
+return emitError("Non-whitespace before {[.");continue;case OPEN_KEY:case OPEN_OBJECT:if(whitespace(c))continue;if(state===OPEN_KEY)stack.push(CLOSE_KEY);else{if(c==='}'){emitValueOpen({});emitValueClose();state=stack.pop()||VALUE;continue;}else stack.push(CLOSE_OBJECT);}
+if(c==='"')
+state=STRING;else
+return emitError("Malformed object key should start with \" ");continue;case CLOSE_KEY:case CLOSE_OBJECT:if(whitespace(c))continue;if(c===':'){if(state===CLOSE_OBJECT){stack.push(CLOSE_OBJECT);if(textNode!==undefined){emitValueOpen({});emitSaxKey(textNode);textNode=undefined;}
+depth++;}else{if(textNode!==undefined){emitSaxKey(textNode);textNode=undefined;}}
+state=VALUE;}else if(c==='}'){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+emitValueClose();depth--;state=stack.pop()||VALUE;}else if(c===','){if(state===CLOSE_OBJECT)
+stack.push(CLOSE_OBJECT);if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+state=OPEN_KEY;}else
+return emitError('Bad object');continue;case OPEN_ARRAY:case VALUE:if(whitespace(c))continue;if(state===OPEN_ARRAY){emitValueOpen([]);depth++;state=VALUE;if(c===']'){emitValueClose();depth--;state=stack.pop()||VALUE;continue;}else{stack.push(CLOSE_ARRAY);}}
+if(c==='"')state=STRING;else if(c==='{')state=OPEN_OBJECT;else if(c==='[')state=OPEN_ARRAY;else if(c==='t')state=TRUE;else if(c==='f')state=FALSE;else if(c==='n')state=NULL;else if(c==='-'){numberNode+=c;}else if(c==='0'){numberNode+=c;state=NUMBER_DIGIT;}else if('123456789'.indexOf(c)!==-1){numberNode+=c;state=NUMBER_DIGIT;}else
+return emitError("Bad value");continue;case CLOSE_ARRAY:if(c===','){stack.push(CLOSE_ARRAY);if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+state=VALUE;}else if(c===']'){if(textNode!==undefined){emitValueOpen(textNode);emitValueClose();textNode=undefined;}
+emitValueClose();depth--;state=stack.pop()||VALUE;}else if(whitespace(c))
+continue;else
+return emitError('Bad array');continue;case STRING:if(textNode===undefined){textNode="";}
+var starti=i-1;STRING_BIGLOOP:while(true){while(unicodeI>0){unicodeS+=c;c=chunk.charAt(i++);if(unicodeI===4){textNode+=String.fromCharCode(parseInt(unicodeS,16));unicodeI=0;starti=i-1;}else{unicodeI++;}
+if(!c)break STRING_BIGLOOP;}
+if(c==='"'&&!slashed){state=stack.pop()||VALUE;textNode+=chunk.substring(starti,i-1);break;}
+if(c==='\\'&&!slashed){slashed=true;textNode+=chunk.substring(starti,i-1);c=chunk.charAt(i++);if(!c)break;}
+if(slashed){slashed=false;if(c==='n'){textNode+='\n';}
+else if(c==='r'){textNode+='\r';}
+else if(c==='t'){textNode+='\t';}
+else if(c==='f'){textNode+='\f';}
+else if(c==='b'){textNode+='\b';}
+else if(c==='u'){unicodeI=1;unicodeS='';}else{textNode+=c;}
+c=chunk.charAt(i++);starti=i-1;if(!c)break;else continue;}
+stringTokenPattern.lastIndex=i;var reResult=stringTokenPattern.exec(chunk);if(!reResult){i=chunk.length+1;textNode+=chunk.substring(starti,i-1);break;}
+i=reResult.index+1;c=chunk.charAt(reResult.index);if(!c){textNode+=chunk.substring(starti,i-1);break;}}
+continue;case TRUE:if(!c)continue;if(c==='r')state=TRUE2;else
+return emitError('Invalid true started with t'+c);continue;case TRUE2:if(!c)continue;if(c==='u')state=TRUE3;else
+return emitError('Invalid true started with tr'+c);continue;case TRUE3:if(!c)continue;if(c==='e'){emitValueOpen(true);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid true started with tru'+c);continue;case FALSE:if(!c)continue;if(c==='a')state=FALSE2;else
+return emitError('Invalid false started with f'+c);continue;case FALSE2:if(!c)continue;if(c==='l')state=FALSE3;else
+return emitError('Invalid false started with fa'+c);continue;case FALSE3:if(!c)continue;if(c==='s')state=FALSE4;else
+return emitError('Invalid false started with fal'+c);continue;case FALSE4:if(!c)continue;if(c==='e'){emitValueOpen(false);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid false started with fals'+c);continue;case NULL:if(!c)continue;if(c==='u')state=NULL2;else
+return emitError('Invalid null started with n'+c);continue;case NULL2:if(!c)continue;if(c==='l')state=NULL3;else
+return emitError('Invalid null started with nu'+c);continue;case NULL3:if(!c)continue;if(c==='l'){emitValueOpen(null);emitValueClose();state=stack.pop()||VALUE;}else
+return emitError('Invalid null started with nul'+c);continue;case NUMBER_DECIMAL_POINT:if(c==='.'){numberNode+=c;state=NUMBER_DIGIT;}else
+return emitError('Leading zero not followed by .');continue;case NUMBER_DIGIT:if('0123456789'.indexOf(c)!==-1)numberNode+=c;else if(c==='.'){if(numberNode.indexOf('.')!==-1)
+return emitError('Invalid number has two dots');numberNode+=c;}else if(c==='e'||c==='E'){if(numberNode.indexOf('e')!==-1||numberNode.indexOf('E')!==-1)
+return emitError('Invalid number has two exponential');numberNode+=c;}else if(c==="+"||c==="-"){if(!(p==='e'||p==='E'))
+return emitError('Invalid symbol in number');numberNode+=c;}else{if(numberNode){emitValueOpen(parseFloat(numberNode));emitValueClose();numberNode="";}
+i--;state=stack.pop()||VALUE;}
+continue;default:return emitError("Unknown state: "+state);}}
+if(position>=bufferCheckPosition)
+checkBufferLength();}}
+function ascentManager(oboeBus,handlers){"use strict";var listenerId={},ascent;function stateAfter(handler){return function(param){ascent=handler(ascent,param);}}
+for(var eventName in handlers){oboeBus(eventName).on(stateAfter(handlers[eventName]),listenerId);}
+oboeBus(NODE_SWAP).on(function(newNode){var oldHead=head(ascent),key=keyOf(oldHead),ancestors=tail(ascent),parentNode;if(ancestors){parentNode=nodeOf(head(ancestors));parentNode[key]=newNode;}});oboeBus(NODE_DROP).on(function(){var oldHead=head(ascent),key=keyOf(oldHead),ancestors=tail(ascent),parentNode;if(ancestors){parentNode=nodeOf(head(ancestors));delete parentNode[key];}});oboeBus(ABORTING).on(function(){for(var eventName in handlers){oboeBus(eventName).un(listenerId);}});}
+function parseResponseHeaders(headerStr){var headers={};headerStr&&headerStr.split('\u000d\u000a').forEach(function(headerPair){var index=headerPair.indexOf('\u003a\u0020');headers[headerPair.substring(0,index)]=headerPair.substring(index+2);});return headers;}
+function isCrossOrigin(pageLocation,ajaxHost){function defaultPort(protocol){return{'http:':80,'https:':443}[protocol];}
+function portOf(location){return location.port||defaultPort(location.protocol||pageLocation.protocol);}
+return!!((ajaxHost.protocol&&(ajaxHost.protocol!=pageLocation.protocol))||(ajaxHost.host&&(ajaxHost.host!=pageLocation.host))||(ajaxHost.host&&(portOf(ajaxHost)!=portOf(pageLocation))));}
+function parseUrlOrigin(url){var URL_HOST_PATTERN=/(\w+:)?(?:\/\/)([\w.-]+)?(?::(\d+))?\/?/,urlHostMatch=URL_HOST_PATTERN.exec(url)||[];return{protocol:urlHostMatch[1]||'',host:urlHostMatch[2]||'',port:urlHostMatch[3]||''};}
+function httpTransport(){return new XMLHttpRequest();}
+function streamingHttp(oboeBus,xhr,method,url,data,headers,withCredentials){"use strict";var emitStreamData=oboeBus(STREAM_DATA).emit,emitFail=oboeBus(FAIL_EVENT).emit,numberOfCharsAlreadyGivenToCallback=0,stillToSendStartEvent=true;oboeBus(ABORTING).on(function(){xhr.onreadystatechange=null;xhr.abort();});function handleProgress(){var textSoFar=xhr.responseText,newText=textSoFar.substr(numberOfCharsAlreadyGivenToCallback);if(newText){emitStreamData(newText);}
+numberOfCharsAlreadyGivenToCallback=len(textSoFar);}
+if('onprogress'in xhr){xhr.onprogress=handleProgress;}
+xhr.onreadystatechange=function(){function sendStartIfNotAlready(){try{stillToSendStartEvent&&oboeBus(HTTP_START).emit(xhr.status,parseResponseHeaders(xhr.getAllResponseHeaders()));stillToSendStartEvent=false;}catch(e){}}
+switch(xhr.readyState){case 2:case 3:return sendStartIfNotAlready();case 4:sendStartIfNotAlready();var successful=String(xhr.status)[0]==2;if(successful){handleProgress();oboeBus(STREAM_END).emit();}else{emitFail(errorReport(xhr.status,xhr.responseText));}}};try{xhr.open(method,url,true);for(var headerName in headers){xhr.setRequestHeader(headerName,headers[headerName]);}
+if(!isCrossOrigin(window.location,parseUrlOrigin(url))){xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');}
+xhr.withCredentials=withCredentials;xhr.send(data);}catch(e){window.setTimeout(partialComplete(emitFail,errorReport(undefined,undefined,e)),0);}}
+var jsonPathSyntax=(function(){var
+regexDescriptor=function regexDescriptor(regex){return regex.exec.bind(regex);},jsonPathClause=varArgs(function(componentRegexes){componentRegexes.unshift(/^/);return regexDescriptor(RegExp(componentRegexes.map(attr('source')).join('')));}),possiblyCapturing=/(\$?)/,namedNode=/([\w-_]+|\*)/,namePlaceholder=/()/,nodeInArrayNotation=/\["([^"]+)"\]/,numberedNodeInArrayNotation=/\[(\d+|\*)\]/,fieldList=/{([\w ]*?)}/,optionalFieldList=/(?:{([\w ]*?)})?/
+,jsonPathNamedNodeInObjectNotation=jsonPathClause(possiblyCapturing,namedNode,optionalFieldList),jsonPathNamedNodeInArrayNotation=jsonPathClause(possiblyCapturing,nodeInArrayNotation,optionalFieldList),jsonPathNumberedNodeInArrayNotation=jsonPathClause(possiblyCapturing,numberedNodeInArrayNotation,optionalFieldList),jsonPathPureDuckTyping=jsonPathClause(possiblyCapturing,namePlaceholder,fieldList),jsonPathDoubleDot=jsonPathClause(/\.\./),jsonPathDot=jsonPathClause(/\./),jsonPathBang=jsonPathClause(possiblyCapturing,/!/),emptyString=jsonPathClause(/$/);return function(fn){return fn(lazyUnion(jsonPathNamedNodeInObjectNotation,jsonPathNamedNodeInArrayNotation,jsonPathNumberedNodeInArrayNotation,jsonPathPureDuckTyping),jsonPathDoubleDot,jsonPathDot,jsonPathBang,emptyString);};}());function namedNode(key,node){return{key:key,node:node};}
+var keyOf=attr('key');var nodeOf=attr('node');var ROOT_PATH={};function incrementalContentBuilder(oboeBus){var emitNodeOpened=oboeBus(NODE_OPENED).emit,emitNodeClosed=oboeBus(NODE_CLOSED).emit,emitRootOpened=oboeBus(ROOT_PATH_FOUND).emit,emitRootClosed=oboeBus(ROOT_NODE_FOUND).emit;function arrayIndicesAreKeys(possiblyInconsistentAscent,newDeepestNode){var parentNode=nodeOf(head(possiblyInconsistentAscent));return isOfType(Array,parentNode)?keyFound(possiblyInconsistentAscent,len(parentNode),newDeepestNode):possiblyInconsistentAscent;}
+function nodeOpened(ascent,newDeepestNode){if(!ascent){emitRootOpened(newDeepestNode);return keyFound(ascent,ROOT_PATH,newDeepestNode);}
+var arrayConsistentAscent=arrayIndicesAreKeys(ascent,newDeepestNode),ancestorBranches=tail(arrayConsistentAscent),previouslyUnmappedName=keyOf(head(arrayConsistentAscent));appendBuiltContent(ancestorBranches,previouslyUnmappedName,newDeepestNode);return cons(namedNode(previouslyUnmappedName,newDeepestNode),ancestorBranches);}
+function appendBuiltContent(ancestorBranches,key,node){nodeOf(head(ancestorBranches))[key]=node;}
+function keyFound(ascent,newDeepestName,maybeNewDeepestNode){if(ascent){appendBuiltContent(ascent,newDeepestName,maybeNewDeepestNode);}
+var ascentWithNewPath=cons(namedNode(newDeepestName,maybeNewDeepestNode),ascent);emitNodeOpened(ascentWithNewPath);return ascentWithNewPath;}
+function nodeClosed(ascent){emitNodeClosed(ascent);return tail(ascent)||emitRootClosed(nodeOf(head(ascent)));}
+var contentBuilderHandlers={};contentBuilderHandlers[SAX_VALUE_OPEN]=nodeOpened;contentBuilderHandlers[SAX_VALUE_CLOSE]=nodeClosed;contentBuilderHandlers[SAX_KEY]=keyFound;return contentBuilderHandlers;}
+var jsonPathCompiler=jsonPathSyntax(function(pathNodeSyntax,doubleDotSyntax,dotSyntax,bangSyntax,emptySyntax){var CAPTURING_INDEX=1;var NAME_INDEX=2;var FIELD_LIST_INDEX=3;var headKey=compose2(keyOf,head),headNode=compose2(nodeOf,head);function nameClause(previousExpr,detection){var name=detection[NAME_INDEX],matchesName=(!name||name=='*')?always:function(ascent){return headKey(ascent)==name};return lazyIntersection(matchesName,previousExpr);}
+function duckTypeClause(previousExpr,detection){var fieldListStr=detection[FIELD_LIST_INDEX];if(!fieldListStr)
+return previousExpr;var hasAllrequiredFields=partialComplete(hasAllProperties,arrayAsList(fieldListStr.split(/\W+/))),isMatch=compose2(hasAllrequiredFields,headNode);return lazyIntersection(isMatch,previousExpr);}
+function capture(previousExpr,detection){var capturing=!!detection[CAPTURING_INDEX];if(!capturing)
+return previousExpr;return lazyIntersection(previousExpr,head);}
+function skip1(previousExpr){if(previousExpr==always){return always;}
+function notAtRoot(ascent){return headKey(ascent)!=ROOT_PATH;}
+return lazyIntersection(notAtRoot,compose2(previousExpr,tail));}
+function skipMany(previousExpr){if(previousExpr==always){return always;}
+var
+terminalCaseWhenArrivingAtRoot=rootExpr(),terminalCaseWhenPreviousExpressionIsSatisfied=previousExpr,recursiveCase=skip1(function(ascent){return cases(ascent);}),cases=lazyUnion(terminalCaseWhenArrivingAtRoot,terminalCaseWhenPreviousExpressionIsSatisfied,recursiveCase);return cases;}
+function rootExpr(){return function(ascent){return headKey(ascent)==ROOT_PATH;};}
+function statementExpr(lastClause){return function(ascent){var exprMatch=lastClause(ascent);return exprMatch===true?head(ascent):exprMatch;};}
+function expressionsReader(exprs,parserGeneratedSoFar,detection){return foldR(function(parserGeneratedSoFar,expr){return expr(parserGeneratedSoFar,detection);},parserGeneratedSoFar,exprs);}
+function generateClauseReaderIfTokenFound(tokenDetector,clauseEvaluatorGenerators,jsonPath,parserGeneratedSoFar,onSuccess){var detected=tokenDetector(jsonPath);if(detected){var compiledParser=expressionsReader(clauseEvaluatorGenerators,parserGeneratedSoFar,detected),remainingUnparsedJsonPath=jsonPath.substr(len(detected[0]));return onSuccess(remainingUnparsedJsonPath,compiledParser);}}
+function clauseMatcher(tokenDetector,exprs){return partialComplete(generateClauseReaderIfTokenFound,tokenDetector,exprs);}
+var clauseForJsonPath=lazyUnion(clauseMatcher(pathNodeSyntax,list(capture,duckTypeClause,nameClause,skip1)),clauseMatcher(doubleDotSyntax,list(skipMany)),clauseMatcher(dotSyntax,list()),clauseMatcher(bangSyntax,list(capture,rootExpr)),clauseMatcher(emptySyntax,list(statementExpr)),function(jsonPath){throw Error('"'+jsonPath+'" could not be tokenised')});function returnFoundParser(_remainingJsonPath,compiledParser){return compiledParser}
+function compileJsonPathToFunction(uncompiledJsonPath,parserGeneratedSoFar){var onFind=uncompiledJsonPath?compileJsonPathToFunction:returnFoundParser;return clauseForJsonPath(uncompiledJsonPath,parserGeneratedSoFar,onFind);}
+return function(jsonPath){try{return compileJsonPathToFunction(jsonPath,always);}catch(e){throw Error('Could not compile "'+jsonPath+'" because '+e.message);}}});function singleEventPubSub(eventType,newListener,removeListener){var listenerTupleList,listenerList;function hasId(id){return function(tuple){return tuple.id==id;};}
+return{on:function(listener,listenerId){var tuple={listener:listener,id:listenerId||listener};if(newListener){newListener.emit(eventType,listener,tuple.id);}
+listenerTupleList=cons(tuple,listenerTupleList);listenerList=cons(listener,listenerList);return this;},emit:function(){applyEach(listenerList,arguments);},un:function(listenerId){var removed;listenerTupleList=without(listenerTupleList,hasId(listenerId),function(tuple){removed=tuple;});if(removed){listenerList=without(listenerList,function(listener){return listener==removed.listener;});if(removeListener){removeListener.emit(eventType,removed.listener,removed.id);}}},listeners:function(){return listenerList;},hasListener:function(listenerId){var test=listenerId?hasId(listenerId):always;return defined(first(test,listenerTupleList));}};}
+function pubSub(){var singles={},newListener=newSingle('newListener'),removeListener=newSingle('removeListener');function newSingle(eventName){return singles[eventName]=singleEventPubSub(eventName,newListener,removeListener);}
+function pubSubInstance(eventName){return singles[eventName]||newSingle(eventName);}
+['emit','on','un'].forEach(function(methodName){pubSubInstance[methodName]=varArgs(function(eventName,parameters){apply(parameters,pubSubInstance(eventName)[methodName]);});});return pubSubInstance;}
+var
+_S=1,NODE_OPENED=_S++,NODE_CLOSED=_S++,NODE_SWAP=_S++,NODE_DROP=_S++,FAIL_EVENT='fail',ROOT_NODE_FOUND=_S++,ROOT_PATH_FOUND=_S++,HTTP_START='start',STREAM_DATA='data',STREAM_END='end',ABORTING=_S++,SAX_KEY=_S++,SAX_VALUE_OPEN=_S++,SAX_VALUE_CLOSE=_S++;function errorReport(statusCode,body,error){try{var jsonBody=JSON.parse(body);}catch(e){}
+return{statusCode:statusCode,body:body,jsonBody:jsonBody,thrown:error};}
+function patternAdapter(oboeBus,jsonPathCompiler){var predicateEventMap={node:oboeBus(NODE_CLOSED),path:oboeBus(NODE_OPENED)};function emitMatchingNode(emitMatch,node,ascent){var descent=reverseList(ascent);emitMatch(node,listAsArray(tail(map(keyOf,descent))),listAsArray(map(nodeOf,descent)));}
+function addUnderlyingListener(fullEventName,predicateEvent,compiledJsonPath){var emitMatch=oboeBus(fullEventName).emit;predicateEvent.on(function(ascent){var maybeMatchingMapping=compiledJsonPath(ascent);if(maybeMatchingMapping!==false){emitMatchingNode(emitMatch,nodeOf(maybeMatchingMapping),ascent);}},fullEventName);oboeBus('removeListener').on(function(removedEventName){if(removedEventName==fullEventName){if(!oboeBus(removedEventName).listeners()){predicateEvent.un(fullEventName);}}});}
+oboeBus('newListener').on(function(fullEventName){var match=/(node|path):(.*)/.exec(fullEventName);if(match){var predicateEvent=predicateEventMap[match[1]];if(!predicateEvent.hasListener(fullEventName)){addUnderlyingListener(fullEventName,predicateEvent,jsonPathCompiler(match[2]));}}})}
+function instanceApi(oboeBus,contentSource){var oboeApi,fullyQualifiedNamePattern=/^(node|path):./,rootNodeFinishedEvent=oboeBus(ROOT_NODE_FOUND),emitNodeDrop=oboeBus(NODE_DROP).emit,emitNodeSwap=oboeBus(NODE_SWAP).emit,addListener=varArgs(function(eventId,parameters){if(oboeApi[eventId]){apply(parameters,oboeApi[eventId]);}else{var event=oboeBus(eventId),listener=parameters[0];if(fullyQualifiedNamePattern.test(eventId)){addForgettableCallback(event,listener);}else{event.on(listener);}}
+return oboeApi;}),removeListener=function(eventId,p2,p3){if(eventId=='done'){rootNodeFinishedEvent.un(p2);}else if(eventId=='node'||eventId=='path'){oboeBus.un(eventId+':'+p2,p3);}else{var listener=p2;oboeBus(eventId).un(listener);}
+return oboeApi;};function addProtectedCallback(eventName,callback){oboeBus(eventName).on(protectedCallback(callback),callback);return oboeApi;}
+function addForgettableCallback(event,callback,listenerId){listenerId=listenerId||callback;var safeCallback=protectedCallback(callback);event.on(function(){var discard=false;oboeApi.forget=function(){discard=true;};apply(arguments,safeCallback);delete oboeApi.forget;if(discard){event.un(listenerId);}},listenerId);return oboeApi;}
+function protectedCallback(callback){return function(){try{return callback.apply(oboeApi,arguments);}catch(e){setTimeout(function(){throw new Error(e.message);});}}}
+function fullyQualifiedPatternMatchEvent(type,pattern){return oboeBus(type+':'+pattern);}
+function wrapCallbackToSwapNodeIfSomethingReturned(callback){return function(){var returnValueFromCallback=callback.apply(this,arguments);if(defined(returnValueFromCallback)){if(returnValueFromCallback==oboe.drop){emitNodeDrop();}else{emitNodeSwap(returnValueFromCallback);}}}}
+function addSingleNodeOrPathListener(eventId,pattern,callback){var effectiveCallback;if(eventId=='node'){effectiveCallback=wrapCallbackToSwapNodeIfSomethingReturned(callback);}else{effectiveCallback=callback;}
+addForgettableCallback(fullyQualifiedPatternMatchEvent(eventId,pattern),effectiveCallback,callback);}
+function addMultipleNodeOrPathListeners(eventId,listenerMap){for(var pattern in listenerMap){addSingleNodeOrPathListener(eventId,pattern,listenerMap[pattern]);}}
+function addNodeOrPathListenerApi(eventId,jsonPathOrListenerMap,callback){if(isString(jsonPathOrListenerMap)){addSingleNodeOrPathListener(eventId,jsonPathOrListenerMap,callback);}else{addMultipleNodeOrPathListeners(eventId,jsonPathOrListenerMap);}
+return oboeApi;}
+oboeBus(ROOT_PATH_FOUND).on(function(rootNode){oboeApi.root=functor(rootNode);});oboeBus(HTTP_START).on(function(_statusCode,headers){oboeApi.header=function(name){return name?headers[name]:headers;}});return oboeApi={on:addListener,addListener:addListener,removeListener:removeListener,emit:oboeBus.emit,node:partialComplete(addNodeOrPathListenerApi,'node'),path:partialComplete(addNodeOrPathListenerApi,'path'),done:partialComplete(addForgettableCallback,rootNodeFinishedEvent),start:partialComplete(addProtectedCallback,HTTP_START),fail:oboeBus(FAIL_EVENT).on,abort:oboeBus(ABORTING).emit,write:oboeBus(STREAM_DATA).emit,finish:oboeBus(STREAM_END).emit,header:noop,root:noop,source:contentSource};}
+function wire(httpMethodName,contentSource,body,headers,withCredentials){var oboeBus=pubSub();if(contentSource){streamingHttp(oboeBus,httpTransport(),httpMethodName,contentSource,body,headers,withCredentials);}
+clarinet(oboeBus);ascentManager(oboeBus,incrementalContentBuilder(oboeBus));patternAdapter(oboeBus,jsonPathCompiler);return instanceApi(oboeBus,contentSource);}
+function applyDefaults(passthrough,url,httpMethodName,body,headers,withCredentials,cached){headers=headers?JSON.parse(JSON.stringify(headers)):{};if(body){if(!isString(body)){body=JSON.stringify(body);headers['Content-Type']=headers['Content-Type']||'application/json';}}else{body=null;}
+function modifiedUrl(baseUrl,cached){if(cached===false){if(baseUrl.indexOf('?')==-1){baseUrl+='?';}else{baseUrl+='&';}
+baseUrl+='_='+new Date().getTime();}
+return baseUrl;}
+return passthrough(httpMethodName||'GET',modifiedUrl(url,cached),body,headers,withCredentials||false);}
+function oboe(arg1){var nodeStreamMethodNames=list('resume','pause','pipe'),isStream=partialComplete(hasAllProperties,nodeStreamMethodNames);if(arg1){if(isStream(arg1)||isString(arg1)){return applyDefaults(wire,arg1);}else{return applyDefaults(wire,arg1.url,arg1.method,arg1.body,arg1.headers,arg1.withCredentials,arg1.cached);}}else{return wire();}}
+oboe.drop=function(){return oboe.drop;};if(typeof define==="function"&&define.amd){define("oboe",[],function(){return oboe;});}else if(typeof exports==='object'){module.exports=oboe;}else{window.oboe=oboe;}})((function(){try{return window;}catch(e){return self;}}()),Object,Array,Error,JSON);'use strict';if(tr.isHeadless){global.window={};}'use strict';if(tr.isVinn){global.oboe=global.window.oboe;global.window=undefined;}else if(tr.isNode){global.window=undefined;const path=HTMLImportsLoader.hrefToAbsolutePath('/oboe/dist/oboe-node.js');global.oboe=require(path);}'use strict';tr.exportTo('tr.e.importer',function(){const STRING_ID_SUFFIX='_sid';const PLURAL_STRING_ID_SUFFIX='_sids';function isStringReference(s){return s.endsWith(STRING_ID_SUFFIX)||s.endsWith(PLURAL_STRING_ID_SUFFIX);}
+function getStringReferenceName(name){if(name.endsWith(PLURAL_STRING_ID_SUFFIX)){return name.slice(0,-PLURAL_STRING_ID_SUFFIX.length);}
+return name.slice(0,-STRING_ID_SUFFIX.length);}
+function deferenceStrings(idToString,o){const clone=Object.assign({},o);for(const[key,value]of Object.entries(clone)){if(isStringReference(key)){const name=getStringReferenceName(key);clone[name]=idToString(value);}}
+return clone;}
+function singularize(word){if(word.endsWith('s')){return word.slice(0,-1);}
+return word;}
+function getMetadataPairs(dataJson){const isMetadata=v=>typeof v!=='object'||Array.isArray(v);const pairs=Object.entries(dataJson);const metadataPairs=pairs.filter(([_,v])=>isMetadata(v));return metadataPairs;}
+function getGroupPairs(dataJson){const pairs=Object.entries(dataJson);const nonMapPairs=pairs.filter(([k,_])=>k!=='maps');const groupPairs=nonMapPairs.filter(([_,v])=>typeof v==='object');return groupPairs;}
+function createMap(mapJson){const map=new Map();for(const entry of mapJson){if(entry.id===undefined){throw new Error('Missing required key "id" in streaming event.');}
+map.set(entry.id,entry);}
+return map;}
+function createMaps(mapsJson){const maps=new Map();for(const[name,mapJson]of Object.entries(mapsJson)){maps.set(name,createMap(mapJson));}
+return maps;}
+function createGroup(groupJson,opt_startTime){const entries=[];const n=Object.values(groupJson)[0].length;for(let i=0;i<n;i++){const entry={};for(const name in groupJson){entry[name]=groupJson[name][i];}
+entries.push(entry);}
+const timeDelta=groupJson.timeDelta;if(opt_startTime===undefined&&timeDelta!==undefined){throw new Error('Missing required key "startTime" in streaming event.');}
+if(opt_startTime){let delta=0;for(const entry of entries){delta+=entry.timeDelta?entry.timeDelta:0;entry.time=opt_startTime+delta;}}
+return entries;}
+function createGroups(groupsJson,opt_startTime){const groups=new Map();for(const[name,groupJson]of Object.entries(groupsJson)){groups.set(name,createGroup(groupJson,opt_startTime));}
+return groups;}
+function createMetadata(metadataPairs){const metadata=new Map();for(const[name,value]of metadataPairs){metadata.set(name,value);}
+if(metadata.get('version')===undefined){throw new Error('Missing required key "version" in streaming event.');}
+return metadata;}
+class ProfilingDictionaryReader{constructor(opt_metadata,opt_maps,opt_groups,opt_parent){this.metadata=opt_metadata||new Map();this.maps=opt_maps||new Map();this.groups=opt_groups||new Map();this.parent_=opt_parent||undefined;this.inflated_=undefined;this.raw_=undefined;this.boundGetString_=this.getString.bind(this);this.deferenceStrings_=o=>deferenceStrings(this.boundGetString_,o);}
+static empty(){return new ProfilingDictionaryReader();}
+get parent(){return this.parent_;}
+get raw(){if(this.raw_)return this.raw_;this.raw_={};for(const[name,group]of this.groups.entries()){this.raw_[name]=group;}
+return this.raw_;}
+get inflated(){if(this.inflated_)return this.inflated_;this.inflated_={};for(const[name,group]of this.groups.entries()){this.inflated_[name]=this.inflateGroup(group);}
+return this.inflated_;}
+getNewMap(name){return this.maps.get(name)||new Map();}
+getMapValue(mapName,id){let value=this.getNewMap(mapName).get(id);if(value===undefined&&this.parent){value=this.parent.getMapValue(mapName,id);}
+return value;}
+getString(id){const value=this.getMapValue('strings',id);if(value===undefined)return undefined;return value.string;}
+hasMap(name){if(this.maps.has(name))return true;if(this.parent===undefined)return false;return this.parent.hasMap(name);}
+inflateGroup(group){return group.map(this.inflateEntry.bind(this));}
+inflateEntry(entry){const inflatedEntry={};for(const[name,value]of Object.entries(entry)){let inflatedValue;if(this.hasMap(name)){const id=value;inflatedValue=this.deferenceStrings_(this.getMapValue(name,id));}else{inflatedValue=value;}
+inflatedEntry[singularize(name)]=inflatedValue;}
+return this.deferenceStrings_(inflatedEntry);}
+expandData(data){const mapsJson=data.maps||{};const groupsJson=data.allocators||{};const metadataPairs=getMetadataPairs(data);const metadata=createMetadata(metadataPairs);const opt_startTime=metadata.get('startTime');const maps=createMaps(mapsJson);const groups=createGroups(groupsJson,opt_startTime);return new ProfilingDictionaryReader(metadata,maps,groups,this);}
+expandEvent(event){return this.expandData(event.args.data);}}
+return{ProfilingDictionaryReader,singularize,deferenceStringsForTest:deferenceStrings,};});'use strict';tr.exportTo('tr.model.source_info',function(){function SourceInfo(file,opt_line,opt_column){this.file_=file;this.line_=opt_line||-1;this.column_=opt_column||-1;}
+SourceInfo.prototype={get file(){return this.file_;},get line(){return this.line_;},get column(){return this.column_;},get domain(){if(!this.file_)return undefined;const domain=this.file_.match(/(.*:\/\/[^:\/]*)/i);return domain?domain[1]:undefined;},toString(){let str='';if(this.file_){str+=this.file_;}
 if(this.line_>0){str+=':'+this.line_;}
 if(this.column_>0){str+=':'+this.column_;}
 return str;}};return{SourceInfo,};});'use strict';tr.exportTo('tr.model.source_info',function(){function JSSourceInfo(file,line,column,isNative,scriptId,state){tr.model.source_info.SourceInfo.call(this,file,line,column);this.isNative_=isNative;this.scriptId_=scriptId;this.state_=state;}
-JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString:function(){var str=this.isNative_?'[native v8] ':'';return str+
-tr.model.source_info.SourceInfo.prototype.toString.call(this);}};var JSSourceState={COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown',};return{JSSourceInfo,JSSourceState,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocateSimple();this.address_=address;this.size_=size;var rePrefix=/^(\w*:)?([*~]?)(.*)$/m;var tokens=rePrefix.exec(name);var prefix=tokens[1];var state=tokens[2];var body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{state=tr.model.source_info.JSSourceState.UNKNOWN;}
-var rawName;var rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{var spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
-function splitLineAndColumn(url){var lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;var lineColumnMatch=lineColumnRegEx.exec(url);var lineNumber;var columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
+JSSourceInfo.prototype={__proto__:tr.model.source_info.SourceInfo.prototype,get state(){return this.state_;},get isNative(){return this.isNative_;},get scriptId(){return this.scriptId_;},toString(){const str=this.isNative_?'[native v8] ':'';return str+
+tr.model.source_info.SourceInfo.prototype.toString.call(this);}};const JSSourceState={COMPILED:'compiled',OPTIMIZABLE:'optimizable',OPTIMIZED:'optimized',UNKNOWN:'unknown',};return{JSSourceInfo,JSSourceState,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeEntry(address,size,name,scriptId){this.id_=tr.b.GUID.allocateSimple();this.address_=address;this.size_=size;const rePrefix=/^(\w*:)?([*~]?)(.*)$/m;const tokens=rePrefix.exec(name);const prefix=tokens[1];let state=tokens[2];const body=tokens[3];if(state==='*'){state=tr.model.source_info.JSSourceState.OPTIMIZED;}else if(state==='~'){state=tr.model.source_info.JSSourceState.OPTIMIZABLE;}else if(state===''){state=tr.model.source_info.JSSourceState.COMPILED;}else{state=tr.model.source_info.JSSourceState.UNKNOWN;}
+let rawName;let rawUrl;if(prefix==='Script:'){rawName='';rawUrl=body;}else{const spacePos=body.lastIndexOf(' ');rawName=spacePos!==-1?body.substr(0,spacePos):body;rawUrl=spacePos!==-1?body.substr(spacePos+1):'';}
+function splitLineAndColumn(url){const lineColumnRegEx=/(?::(\d+))?(?::(\d+))?$/;const lineColumnMatch=lineColumnRegEx.exec(url);let lineNumber;let columnNumber;if(typeof(lineColumnMatch[1])==='string'){lineNumber=parseInt(lineColumnMatch[1],10);lineNumber=isNaN(lineNumber)?undefined:lineNumber-1;}
 if(typeof(lineColumnMatch[2])==='string'){columnNumber=parseInt(lineColumnMatch[2],10);columnNumber=isNaN(columnNumber)?undefined:columnNumber-1;}
-return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber:lineNumber,columnNumber:columnNumber};}
-var nativeSuffix=' native';var isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;var urlData=splitLineAndColumn(rawUrl);var url=urlData.url||'';var line=urlData.lineNumber||0;var column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);}
+return{url:url.substring(0,url.length-lineColumnMatch[0].length),lineNumber,columnNumber};}
+const nativeSuffix=' native';const isNative=rawName.endsWith(nativeSuffix);this.name_=isNative?rawName.slice(0,-nativeSuffix.length):rawName;const urlData=splitLineAndColumn(rawUrl);const url=urlData.url||'';const line=urlData.lineNumber||0;const column=urlData.columnNumber||0;this.sourceInfo_=new tr.model.source_info.JSSourceInfo(url,line,column,isNative,scriptId,state);}
 TraceCodeEntry.prototype={get id(){return this.id_;},get sourceInfo(){return this.sourceInfo_;},get name(){return this.name_;},set address(address){this.address_=address;},get address(){return this.address_;},set size(size){this.size_=size;},get size(){return this.size_;}};return{TraceCodeEntry,};});'use strict';tr.exportTo('tr.e.importer',function(){function TraceCodeMap(){this.banks_=new Map();}
-TraceCodeMap.prototype={addEntry:function(addressHex,size,name,scriptId){var entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry:function(oldAddressHex,newAddressHex,size){var entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry:function(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_:function(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_:function(addressHex){var bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_:function(addressHex){addressHex=addressHex.slice(2);var bankSizeHexDigits=13;var maxHexDigits=16;var bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);var bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
+TraceCodeMap.prototype={addEntry(addressHex,size,name,scriptId){const entry=new tr.e.importer.TraceCodeEntry(this.getAddress_(addressHex),size,name,scriptId);this.addEntry_(addressHex,entry);},moveEntry(oldAddressHex,newAddressHex,size){const entry=this.getBank_(oldAddressHex).removeEntry(this.getAddress_(oldAddressHex));if(!entry)return;entry.address=this.getAddress_(newAddressHex);entry.size=size;this.addEntry_(newAddressHex,entry);},lookupEntry(addressHex){return this.getBank_(addressHex).lookupEntry(this.getAddress_(addressHex));},addEntry_(addressHex,entry){this.getBank_(addressHex).addEntry(entry);},getAddress_(addressHex){const bankSizeHexDigits=13;addressHex=addressHex.slice(2);return parseInt(addressHex.slice(-bankSizeHexDigits),16);},getBank_(addressHex){addressHex=addressHex.slice(2);const bankSizeHexDigits=13;const maxHexDigits=16;const bankName=addressHex.slice(-maxHexDigits,-bankSizeHexDigits);let bank=this.banks_.get(bankName);if(!bank){bank=new TraceCodeBank();this.banks_.set(bankName,bank);}
 return bank;}};function TraceCodeBank(){this.entries_=[];}
-TraceCodeBank.prototype={removeEntry:function(address){if(this.entries_.length===0)return undefined;var index=tr.b.math.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);var entry=this.entries_[index];if(!entry||entry.address!==address)return undefined;this.entries_.splice(index,1);return entry;},lookupEntry:function(address){var index=tr.b.math.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;var entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry:function(newEntry){if(this.entries_.length===0){this.entries_.push(newEntry);}
-var endAddress=newEntry.address+newEntry.size;var lastIndex=tr.b.math.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);var index;for(index=lastIndex-1;index>=0;--index){var entry=this.entries_[index];var entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)break;}
+TraceCodeBank.prototype={removeEntry(address){if(this.entries_.length===0)return undefined;const index=tr.b.math.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},address);const entry=this.entries_[index];if(!entry||entry.address!==address)return undefined;this.entries_.splice(index,1);return entry;},lookupEntry(address){const index=tr.b.math.findHighIndexInSortedArray(this.entries_,function(e){return address-e.address;})-1;const entry=this.entries_[index];return entry&&address<entry.address+entry.size?entry:undefined;},addEntry(newEntry){if(this.entries_.length===0){this.entries_.push(newEntry);}
+const endAddress=newEntry.address+newEntry.size;const lastIndex=tr.b.math.findLowIndexInSortedArray(this.entries_,function(entry){return entry.address;},endAddress);let index;for(index=lastIndex-1;index>=0;--index){const entry=this.entries_[index];const entryEndAddress=entry.address+entry.size;if(entryEndAddress<=newEntry.address)break;}
 ++index;this.entries_.splice(index,lastIndex-index,newEntry);}};return{TraceCodeMap,};});'use strict';tr.exportTo('tr.importer',function(){function ContextProcessor(model){this.model_=model;this.activeContexts_=[];this.stackPerType_={};this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.seenSnapshots_={};}
-ContextProcessor.prototype={enterContext:function(contextType,scopedId){var newActiveContexts=[this.getOrCreateContext_(contextType,scopedId)];for(var oldContext of this.activeContexts_){if(oldContext.type===contextType){this.pushContext_(oldContext);}else{newActiveContexts.push(oldContext);}}
-this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},leaveContext:function(contextType,scopedId){this.leaveContextImpl_(context=>context.type===contextType&&context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},destroyContext:function(scopedId){for(var stack of Object.values(this.stackPerType_)){var newLength=0;for(var i=0;i<stack.length;++i){if(stack[i].snapshot.scope!==scopedId.scope||stack[i].snapshot.idRef!==scopedId.id){stack[newLength++]=stack[i];}}
+ContextProcessor.prototype={enterContext(contextType,scopedId){const newActiveContexts=[this.getOrCreateContext_(contextType,scopedId),];for(const oldContext of this.activeContexts_){if(oldContext.type===contextType){this.pushContext_(oldContext);}else{newActiveContexts.push(oldContext);}}
+this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},leaveContext(contextType,scopedId){this.leaveContextImpl_(context=>context.type===contextType&&context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},destroyContext(scopedId){for(const stack of Object.values(this.stackPerType_)){let newLength=0;for(let i=0;i<stack.length;++i){if(stack[i].snapshot.scope!==scopedId.scope||stack[i].snapshot.idRef!==scopedId.id){stack[newLength++]=stack[i];}}
 stack.length=newLength;}
-this.leaveContextImpl_(context=>context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},leaveContextImpl_:function(predicate){var newActiveContexts=[];for(var oldContext of this.activeContexts_){if(predicate(oldContext)){var previousContext=this.popContext_(oldContext.type);if(previousContext){newActiveContexts.push(previousContext);}}else{newActiveContexts.push(oldContext);}}
-this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},getOrCreateContext_:function(contextType,scopedId){var context={type:contextType,snapshot:{scope:scopedId.scope,idRef:scopedId.id}};var key=this.getContextKey_(context);if(key in this.contextCache_){return this.contextCache_[key];}
-this.contextCache_[key]=context;var snapshotKey=this.getSnapshotKey_(scopedId);this.seenSnapshots_[snapshotKey]=true;return context;},pushContext_:function(context){if(!(context.type in this.stackPerType_)){this.stackPerType_[context.type]=[];}
-this.stackPerType_[context.type].push(context);},popContext_:function(contextType){if(!(contextType in this.stackPerType_)){return undefined;}
-return this.stackPerType_[contextType].pop();},getContextKey_:function(context){return[context.type,context.snapshot.scope,context.snapshot.idRef].join('\x00');},getSnapshotKey_:function(scopedId){return[scopedId.scope,scopedId.idRef].join('\x00');},get activeContexts(){if(this.cachedEntryForActiveContexts_===undefined){var key=[];for(var context of this.activeContexts_){key.push(this.getContextKey_(context));}
-key.sort();key=key.join('\x00');if(key in this.contextSetCache_){this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}else{this.activeContexts_.sort(function(a,b){var keyA=this.getContextKey_(a);var keyB=this.getContextKey_(b);if(keyA<keyB){return-1;}
+this.leaveContextImpl_(context=>context.snapshot.scope===scopedId.scope&&context.snapshot.idRef===scopedId.id);},leaveContextImpl_(predicate){const newActiveContexts=[];for(const oldContext of this.activeContexts_){if(predicate(oldContext)){const previousContext=this.popContext_(oldContext.type);if(previousContext){newActiveContexts.push(previousContext);}}else{newActiveContexts.push(oldContext);}}
+this.activeContexts_=newActiveContexts;this.cachedEntryForActiveContexts_=undefined;},getOrCreateContext_(contextType,scopedId){const context={type:contextType,snapshot:{scope:scopedId.scope,idRef:scopedId.id}};const key=this.getContextKey_(context);if(key in this.contextCache_){return this.contextCache_[key];}
+this.contextCache_[key]=context;const snapshotKey=this.getSnapshotKey_(scopedId);this.seenSnapshots_[snapshotKey]=true;return context;},pushContext_(context){if(!(context.type in this.stackPerType_)){this.stackPerType_[context.type]=[];}
+this.stackPerType_[context.type].push(context);},popContext_(contextType){if(!(contextType in this.stackPerType_)){return undefined;}
+return this.stackPerType_[contextType].pop();},getContextKey_(context){return[context.type,context.snapshot.scope,context.snapshot.idRef].join('\x00');},getSnapshotKey_(scopedId){return[scopedId.scope,scopedId.idRef].join('\x00');},get activeContexts(){if(this.cachedEntryForActiveContexts_===undefined){let key=[];for(const context of this.activeContexts_){key.push(this.getContextKey_(context));}
+key.sort();key=key.join('\x00');if(key in this.contextSetCache_){this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}else{this.activeContexts_.sort(function(a,b){const keyA=this.getContextKey_(a);const keyB=this.getContextKey_(b);if(keyA<keyB){return-1;}
 if(keyA>keyB){return 1;}
 return 0;}.bind(this));this.contextSetCache_[key]=Object.freeze(this.activeContexts_);this.cachedEntryForActiveContexts_=this.contextSetCache_[key];}}
-return this.cachedEntryForActiveContexts_;},invalidateContextCacheForSnapshot:function(scopedId){var snapshotKey=this.getSnapshotKey_(scopedId);if(!(snapshotKey in this.seenSnapshots_))return;this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.activeContexts_=this.activeContexts_.map(function(context){if(context.snapshot.scope!==scopedId.scope||context.snapshot.idRef!==scopedId.id){return context;}
+return this.cachedEntryForActiveContexts_;},invalidateContextCacheForSnapshot(scopedId){const snapshotKey=this.getSnapshotKey_(scopedId);if(!(snapshotKey in this.seenSnapshots_))return;this.contextCache_={};this.contextSetCache_={};this.cachedEntryForActiveContexts_=undefined;this.activeContexts_=this.activeContexts_.map(function(context){if(context.snapshot.scope!==scopedId.scope||context.snapshot.idRef!==scopedId.id){return context;}
 return{type:context.type,snapshot:{scope:context.snapshot.scope,idRef:context.snapshot.idRef}};});this.seenSnapshots_={};},};return{ContextProcessor,};});'use strict';tr.exportTo('tr.model',function(){function Annotation(){this.guid_=tr.b.GUID.allocateSimple();this.view_=undefined;}
 Annotation.fromDictIfPossible=function(args){if(args.typeName===undefined){throw new Error('Missing typeName argument');}
-var typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');};Annotation.prototype={get guid(){return this.guid_;},onRemove:function(){},toDict:function(){throw new Error('Not implemented');},getOrCreateView:function(viewport){if(!this.view_){this.view_=this.createView_(viewport);}
-return this.view_;},createView_:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict')){throw new Error('Must have fromDict method');}
+const typeInfo=Annotation.findTypeInfoMatching(function(typeInfo){return typeInfo.metadata.typeName===args.typeName;});if(typeInfo===undefined)return undefined;return typeInfo.constructor.fromDict(args);};Annotation.fromDict=function(){throw new Error('Not implemented');};Annotation.prototype={get guid(){return this.guid_;},onRemove(){},toDict(){throw new Error('Not implemented');},getOrCreateView(viewport){if(!this.view_){this.view_=this.createView_(viewport);}
+return this.view_;},createView_(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(Annotation,options);Annotation.addEventListener('will-register',function(e){if(!e.typeInfo.constructor.hasOwnProperty('fromDict')){throw new Error('Must have fromDict method');}
 if(!e.typeInfo.metadata.typeName){throw new Error('Registered Annotations must provide typeName');}});return{Annotation,};});'use strict';tr.exportTo('tr.model',function(){function YComponent(stableId,yPercentOffset){this.stableId=stableId;this.yPercentOffset=yPercentOffset;}
-YComponent.prototype={toDict:function(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;}
-Location.fromViewCoordinates=function(viewport,viewX,viewY){var dt=viewport.currentDisplayTransform;var xWorld=dt.xViewToWorld(viewX);var yComponents=[];var elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+YComponent.prototype={toDict(){return{stableId:this.stableId,yPercentOffset:this.yPercentOffset};}};function Location(xWorld,yComponents){this.xWorld_=xWorld;this.yComponents_=yComponents;}
+Location.fromViewCoordinates=function(viewport,viewX,viewY){const dt=viewport.currentDisplayTransform;const xWorld=dt.xViewToWorld(viewX);const yComponents=[];let elem=document.elementFromPoint(viewX+viewport.modelTrackContainer.canvas.offsetLeft,viewY+viewport.modelTrackContainer.canvas.offsetTop);while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){const boundRect=elem.getBoundingClientRect();const yPercentOffset=(viewY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
 elem=elem.parentElement;}
-if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){var xWorld=ts;var yComponents=[];var containerToTrack=viewport.containerToTrackMap;var elem=containerToTrack.getTrackByStableId(stableId);if(!elem)return;var firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){var boundRect=elem.getBoundingClientRect();var yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
+if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.fromStableIdAndTimestamp=function(viewport,stableId,ts){const xWorld=ts;const yComponents=[];const containerToTrack=viewport.containerToTrackMap;let elem=containerToTrack.getTrackByStableId(stableId);if(!elem)return;const firstY=elem.getBoundingClientRect().top;while(elem instanceof tr.ui.tracks.Track){if(elem.eventContainer){const boundRect=elem.getBoundingClientRect();const yPercentOffset=(firstY-boundRect.top)/boundRect.height;yComponents.push(new YComponent(elem.eventContainer.stableId,yPercentOffset));}
 elem=elem.parentElement;}
-if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack:function(viewport){var containerToTrack=viewport.containerToTrackMap;for(var i in this.yComponents_){var yComponent=this.yComponents_[i];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)return track;}},toViewCoordinates:function(viewport){var dt=viewport.currentDisplayTransform;var containerToTrack=viewport.containerToTrackMap;var viewX=dt.xWorldToView(this.xWorld_);var viewY=-1;for(var index in this.yComponents_){var yComponent=this.yComponents_[index];var track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){var boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
-return{viewX:viewX,viewY:viewY};},toDict:function(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
-AnnotationView.prototype={draw:function(ctx){throw new Error('Not implemented');}};return{AnnotationView,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);var endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);var startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;var sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
+if(yComponents.length===0)return;return new Location(xWorld,yComponents);};Location.prototype={get xWorld(){return this.xWorld_;},getContainingTrack(viewport){const containerToTrack=viewport.containerToTrackMap;for(const i in this.yComponents_){const yComponent=this.yComponents_[i];const track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined)return track;}},toViewCoordinates(viewport){const dt=viewport.currentDisplayTransform;const containerToTrack=viewport.containerToTrackMap;const viewX=dt.xWorldToView(this.xWorld_);let viewY=-1;for(const index in this.yComponents_){const yComponent=this.yComponents_[index];const track=containerToTrack.getTrackByStableId(yComponent.stableId);if(track!==undefined){const boundRect=track.getBoundingClientRect();viewY=yComponent.yPercentOffset*boundRect.height+boundRect.top;break;}}
+return{viewX,viewY};},toDict(){return{xWorld:this.xWorld_,yComponents:this.yComponents_};}};return{Location,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function AnnotationView(viewport,annotation){}
+AnnotationView.prototype={draw(ctx){throw new Error('Not implemented');}};return{AnnotationView,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function RectAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
+RectAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw(ctx){const dt=this.viewport_.currentDisplayTransform;const startCoords=this.annotation_.startLocation.toViewCoordinates(this.viewport_);const endCoords=this.annotation_.endLocation.toViewCoordinates(this.viewport_);let startY=startCoords.viewY-ctx.canvas.getBoundingClientRect().top;const sizeY=endCoords.viewY-startCoords.viewY;if(startY+sizeY<0){startY=sizeY;}else if(startY<0){startY=0;}
 ctx.fillStyle=this.annotation_.fillStyle;ctx.fillRect(startCoords.viewX,startY,endCoords.viewX-startCoords.viewX,sizeY);}};return{RectAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function RectAnnotation(start,end){tr.model.Annotation.apply(this,arguments);this.startLocation_=start;this.endLocation_=end;this.fillStyle='rgba(255, 180, 0, 0.3)';}
-RectAnnotation.fromDict=function(dict){var args=dict.args;var startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);var endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);};RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict:function(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
-CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea:function(){Polymer.dom(Polymer.dom(this.textArea_).parentNode).removeChild(this.textArea_);},draw:function(ctx){var coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_){this.textArea_.style.visibility='hidden';}
+RectAnnotation.fromDict=function(dict){const args=dict.args;const startLoc=new tr.model.Location(args.start.xWorld,args.start.yComponents);const endLoc=new tr.model.Location(args.end.xWorld,args.end.yComponents);return new tr.model.RectAnnotation(startLoc,endLoc);};RectAnnotation.prototype={__proto__:tr.model.Annotation.prototype,get startLocation(){return this.startLocation_;},get endLocation(){return this.endLocation_;},toDict(){return{typeName:'rect',args:{start:this.startLocation.toDict(),end:this.endLocation.toDict()}};},createView_(viewport){return new tr.ui.annotations.RectAnnotationView(viewport,this);}};tr.model.Annotation.register(RectAnnotation,{typeName:'rect'});return{RectAnnotation,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function CommentBoxAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;this.textArea_=undefined;this.styleWidth=250;this.styleHeight=50;this.fontSize=10;this.rightOffset=50;this.topOffset=25;}
+CommentBoxAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,removeTextArea(){Polymer.dom(Polymer.dom(this.textArea_).parentNode).removeChild(this.textArea_);},draw(ctx){const coords=this.annotation_.location.toViewCoordinates(this.viewport_);if(coords.viewX<0){if(this.textArea_){this.textArea_.style.visibility='hidden';}
 return;}
 if(!this.textArea_){this.textArea_=document.createElement('textarea');this.textArea_.style.position='absolute';this.textArea_.readOnly=true;this.textArea_.value=this.annotation_.text;this.textArea_.style.zIndex=1;Polymer.dom(Polymer.dom(ctx.canvas).parentNode).appendChild(this.textArea_);}
 this.textArea_.style.width=this.styleWidth+'px';this.textArea_.style.height=this.styleHeight+'px';this.textArea_.style.fontSize=this.fontSize+'px';this.textArea_.style.visibility='visible';this.textArea_.style.left=coords.viewX+ctx.canvas.getBoundingClientRect().left+
 this.rightOffset+'px';this.textArea_.style.top=coords.viewY-ctx.canvas.getBoundingClientRect().top-
 this.topOffset+'px';ctx.strokeStyle='rgb(0, 0, 0)';ctx.lineWidth=2;ctx.beginPath();tr.ui.b.drawLine(ctx,coords.viewX,coords.viewY-ctx.canvas.getBoundingClientRect().top,coords.viewX+this.rightOffset,coords.viewY-this.topOffset-
 ctx.canvas.getBoundingClientRect().top);ctx.stroke();}};return{CommentBoxAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function CommentBoxAnnotation(location,text){tr.model.Annotation.apply(this,arguments);this.location=location;this.text=text;}
-CommentBoxAnnotation.fromDict=function(dict){var args=dict.args;var location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove:function(){this.view_.removeTextArea();},toDict:function(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_:function(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation,};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id,pid){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
+CommentBoxAnnotation.fromDict=function(dict){const args=dict.args;const location=new tr.model.Location(args.location.xWorld,args.location.yComponents);return new tr.model.CommentBoxAnnotation(location,args.text);};CommentBoxAnnotation.prototype={__proto__:tr.model.Annotation.prototype,onRemove(){this.view_.removeTextArea();},toDict(){return{typeName:'comment_box',args:{text:this.text,location:this.location.toDict()}};},createView_(viewport){return new tr.ui.annotations.CommentBoxAnnotationView(viewport,this);}};tr.model.Annotation.register(CommentBoxAnnotation,{typeName:'comment_box'});return{CommentBoxAnnotation,};});'use strict';tr.exportTo('tr.model',function(){function ScopedId(scope,id,pid){if(scope===undefined){throw new Error('Scope should be defined. Use \''+
 tr.model.OBJECT_DEFAULT_SCOPE+'\' as the default scope.');}
 this.scope=scope;this.id=id;this.pid=pid;}
-ScopedId.prototype={toString:function(){var pidStr=this.pid===undefined?'':'pid: '+this.pid+', ';return'{'+pidStr+'scope: '+this.scope+', id: '+this.id+'}';},toStringWithDelimiter:function(delim){return(this.pid===undefined?'':this.pid)+delim+
+ScopedId.prototype={toString(){const pidStr=this.pid===undefined?'':'pid: '+this.pid+', ';return'{'+pidStr+'scope: '+this.scope+', id: '+this.id+'}';},toStringWithDelimiter(delim){return(this.pid===undefined?'':this.pid)+delim+
 this.scope+delim+this.id;}};return{ScopedId,};});'use strict';tr.exportTo('tr.ui.annotations',function(){function XMarkerAnnotationView(viewport,annotation){this.viewport_=viewport;this.annotation_=annotation;}
-XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw:function(ctx){var dt=this.viewport_.currentDisplayTransform;var viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
-XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);};XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict:function(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_:function(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation,};});'use strict';tr.exportTo('tr.e.importer',function(){var Base64=tr.b.Base64;var deepCopy=tr.b.deepCopy;var ColorScheme=tr.b.ColorScheme;var HeapDumpTraceEventImporter=tr.e.importer.HeapDumpTraceEventImporter;function getEventColor(event,opt_customName){if(event.cname){return ColorScheme.getColorIdForReservedName(event.cname);}else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
+XMarkerAnnotationView.prototype={__proto__:tr.ui.annotations.AnnotationView.prototype,draw(ctx){const dt=this.viewport_.currentDisplayTransform;const viewX=dt.xWorldToView(this.annotation_.timestamp);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,ctx.canvas.height);ctx.strokeStyle=this.annotation_.strokeStyle;ctx.stroke();}};return{XMarkerAnnotationView,};});'use strict';tr.exportTo('tr.model',function(){function XMarkerAnnotation(timestamp){tr.model.Annotation.apply(this,arguments);this.timestamp=timestamp;this.strokeStyle='rgba(0, 0, 255, 0.5)';}
+XMarkerAnnotation.fromDict=function(dict){return new XMarkerAnnotation(dict.args.timestamp);};XMarkerAnnotation.prototype={__proto__:tr.model.Annotation.prototype,toDict(){return{typeName:'xmarker',args:{timestamp:this.timestamp}};},createView_(viewport){return new tr.ui.annotations.XMarkerAnnotationView(viewport,this);}};tr.model.Annotation.register(XMarkerAnnotation,{typeName:'xmarker'});return{XMarkerAnnotation,};});'use strict';tr.exportTo('tr.e.importer',function(){const Base64=tr.b.Base64;const deepCopy=tr.b.deepCopy;const ColorScheme=tr.b.ColorScheme;const HeapDumpTraceEventImporter=tr.e.importer.HeapDumpTraceEventImporter;const LegacyHeapDumpTraceEventImporter=tr.e.importer.LegacyHeapDumpTraceEventImporter;const StreamingEventExpander=tr.e.importer.StreamingEventExpander;const ProfilingDictionaryReader=tr.e.importer.ProfilingDictionaryReader;function getEventColor(event,opt_customName){if(event.cname){return ColorScheme.getColorIdForReservedName(event.cname);}else if(opt_customName||event.name){return ColorScheme.getColorIdForGeneralPurposeString(opt_customName||event.name);}}
 function isLegacyChromeClockSyncEvent(event){return event.name!==undefined&&event.name.startsWith(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX)&&((event.ph==='S')||(event.ph==='F'));}
-var PRODUCER='producer';var CONSUMER='consumer';var STEP='step';var BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;var MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,BACKGROUND,LIGHT,DETAILED];var GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';var LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX='ClockSyncEvent.';var BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};var WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;var OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];var SUBTRACE_FIELDS=new Set(['powerTraceAsString','systemTraceEvents',]);var NON_METADATA_FIELDS=new Set(['samples','stackFrames','traceAnnotations','traceEvents',...SUBTRACE_FIELDS]);function TraceEventImporter(model,eventData){this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.stackFrameTree_=new tr.model.ProfileTree();this.subtraces_=[];this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.contextProcessorPerThread={};this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.profileTrees_=new Map();this.profileInfo_=new Map();this.legacyChromeClockSyncStartEvent_=undefined;this.legacyChromeClockSyncFinishEvent_=undefined;this.allMemoryDumpEvents_={};this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.UNKNOWN_CHROME_LEGACY;this.toModelTime_=undefined;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']'){eventData=eventData+']';}}
+const PRODUCER='producer';const CONSUMER='consumer';const STEP='step';const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER=[undefined,BACKGROUND,LIGHT,DETAILED];const GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX='global/';const LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX='ClockSyncEvent.';const BYTE_STAT_NAME_MAP={'pc':'privateCleanResident','pd':'privateDirtyResident','sc':'sharedCleanResident','sd':'sharedDirtyResident','pss':'proportionalResident','sw':'swapped'};const WEAK_MEMORY_ALLOCATOR_DUMP_FLAG=1<<0;const OBJECT_TYPE_NAME_PATTERNS=[{prefix:'const char *WTF::getStringWithTypeName() [T = ',suffix:']'},{prefix:'const char* WTF::getStringWithTypeName() [with T = ',suffix:']'},{prefix:'const char *__cdecl WTF::getStringWithTypeName<',suffix:'>(void)'}];const SUBTRACE_FIELDS=new Set(['powerTraceAsString','systemTraceEvents',]);const NON_METADATA_FIELDS=new Set(['displayTimeUnit','samples','stackFrames','traceAnnotations','traceEvents',...SUBTRACE_FIELDS]);function TraceEventImporter(model,eventData){this.hasEvents_=undefined;this.importPriority=1;this.model_=model;this.events_=undefined;this.sampleEvents_=undefined;this.stackFrameEvents_=undefined;this.stackFrameTree_=new tr.model.ProfileTree();this.subtraces_=[];this.eventsWereFromString_=false;this.softwareMeasuredCpuCount_=undefined;this.allAsyncEvents_=[];this.allFlowEvents_=[];this.allObjectEvents_=[];this.contextProcessorPerThread={};this.traceEventSampleStackFramesByName_={};this.v8ProcessCodeMaps_={};this.v8ProcessRootStackFrame_={};this.v8SamplingData_=[];this.profileTrees_=new Map();this.profileInfo_=new Map();this.legacyChromeClockSyncStartEvent_=undefined;this.legacyChromeClockSyncFinishEvent_=undefined;this.allMemoryDumpEvents_={};this.heapProfileExpander=new ProfilingDictionaryReader();this.objectTypeNameMap_={};this.clockDomainId_=tr.model.ClockDomainId.UNKNOWN_CHROME_LEGACY;this.toModelTime_=undefined;if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();if(eventData[0]==='['){eventData=eventData.replace(/\s*,\s*$/,'');if(eventData[eventData.length-1]!==']'){eventData=eventData+']';}}
 this.events_=JSON.parse(eventData);this.eventsWereFromString_=true;}else{this.events_=eventData;}
-this.traceAnnotations_=this.events_.traceAnnotations;if(this.events_.traceEvents){var container=this.events_;this.events_=this.events_.traceEvents;for(var subtraceField of SUBTRACE_FIELDS){if(container[subtraceField]){this.subtraces_.push(container[subtraceField]);}}
-this.sampleEvents_=container.samples;this.stackFrameEvents_=container.stackFrames;if(container.displayTimeUnit){var unitName=container.displayTimeUnit;var unit=tr.b.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
-this.model_.intrinsicTimeUnit=unit;}
-for(var fieldName in container){if(NON_METADATA_FIELDS.has(fieldName))continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName==='metadata'){var metadata=container[fieldName];if(metadata['highres-ticks']){this.model_.isTimeHighResolution=metadata['highres-ticks'];}
-if(metadata['clock-domain']){this.clockDomainId_=metadata['clock-domain'];}}}}}
-TraceEventImporter.canImport=function(eventData){if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
+if(this.events_.traceEvents){const container=this.events_;this.events_=this.events_.traceEvents;for(const subtraceField of SUBTRACE_FIELDS){if(container[subtraceField]){this.storeSubtrace_(container[subtraceField]);}}
+this.storeSamples_(container.samples);this.storeStackFrames_(container.stackFrames);this.storeDisplayTimeUnit_(container.displayTimeUnit);this.storeTraceAnnotations_(container.traceAnnotations);this.storeMetadata_(container);}else if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',function(e){return oboe.drop;}).node('!.powerTraceAsString',this.storeSubtrace_.bind(this)).node('!.systemTraceEvents',this.storeSubtrace_.bind(this)).node('!.samples',this.storeSamples_.bind(this)).node('!.stackFrames',this.storeStackFrames_.bind(this)).node('!.displayTimeUnit',this.storeDisplayTimeUnit_.bind(this)).node('!.traceAnnotations',this.storeTraceAnnotations_.bind(this)).done(this.storeMetadata_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}}
+TraceEventImporter.canImport=function(eventData){if(eventData instanceof tr.b.TraceStream){if(eventData.isBinary)return false;eventData=eventData.header;}
+if(typeof(eventData)==='string'||eventData instanceof String){eventData=eventData.trim();return eventData[0]==='{'||eventData[0]==='[';}
 if(eventData instanceof Array&&eventData.length&&eventData[0].ph){return true;}
 if(eventData.traceEvents){if(eventData.traceEvents instanceof Array){if(eventData.traceEvents.length&&eventData.traceEvents[0].ph){return true;}
-if(eventData.samples.length&&eventData.stackFrames!==undefined){return true;}}}
-return false;};TraceEventImporter.scopedIdForEvent_=function(event){var scope=event.scope||tr.model.OBJECT_DEFAULT_SCOPE;var pid=undefined;if(event.id!==undefined){if(event.id2!==undefined){throw new Error('Event has both id and id2');}
-var pid=tr.model.LOCAL_ID_PHASES.has(event.ph)?event.pid:undefined;return new tr.model.ScopedId(scope,event.id,pid);}else if(event.id2!==undefined){if(event.id2.global!==undefined){return new tr.model.ScopedId(scope,event.id2.global);}else if(event.id2.local!==undefined){return new tr.model.ScopedId(scope,event.id2.local,event.pid);}
+if(eventData.samples&&eventData.samples.length&&eventData.stackFrames!==undefined){return true;}}}
+return false;};TraceEventImporter.scopedIdForEvent_=function(event){const scope=event.scope||tr.model.OBJECT_DEFAULT_SCOPE;let pid=undefined;if(event.id!==undefined){if(event.id2!==undefined){throw new Error('Event has both id and id2');}
+pid=tr.model.LOCAL_ID_PHASES.has(event.ph)?event.pid:undefined;return new tr.model.ScopedId(scope,event.id,pid);}else if(event.id2!==undefined){if(event.id2.global!==undefined){return new tr.model.ScopedId(scope,event.id2.global);}else if(event.id2.local!==undefined){return new tr.model.ScopedId(scope,event.id2.local,event.pid);}
 throw new Error('Event that uses id2 must have either a global or local ID');}
-return undefined;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces:function(){var subtraces=this.subtraces_;this.subtraces_=[];return subtraces;},deepCopyIfNeeded_:function(obj){if(obj===undefined)obj={};if(this.eventsWereFromString_)return obj;return deepCopy(obj);},deepCopyAlways_:function(obj){if(obj===undefined)obj={};return deepCopy(obj);},processAsyncEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event:event,thread:thread});},processFlowEvent:function(event,opt_slice){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastSimpleGuid(),sequenceNumber:this.allFlowEvents_.length,event:event,slice:opt_slice,thread:thread});},processCounterEvent:function(event){var ctrName;if(event.id!==undefined){ctrName=event.name+'['+event.id+']';}else{ctrName=event.name;}
-var ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctrName);var reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(var seriesName in event.args){var colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
+return undefined;};TraceEventImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'TraceEventImporter';},extractSubtraces(){const subtraces=this.subtraces_;this.subtraces_=[];return subtraces;},deepCopyIfNeeded_(obj){if(obj===undefined)obj={};if(this.eventsWereFromString_)return obj;return deepCopy(obj);},deepCopyAlways_(obj){if(obj===undefined)obj={};return deepCopy(obj);},processAsyncEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allAsyncEvents_.push({sequenceNumber:this.allAsyncEvents_.length,event,thread});},processFlowEvent(event,opt_slice){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allFlowEvents_.push({refGuid:tr.b.GUID.getLastSimpleGuid(),sequenceNumber:this.allFlowEvents_.length,event,slice:opt_slice,thread});},processCounterEvent(event){let ctrName;if(event.id!==undefined){ctrName=event.name+'['+event.id+']';}else{ctrName=event.name;}
+const ctr=this.model_.getOrCreateProcess(event.pid).getOrCreateCounter(event.cat,ctrName);const reservedColorId=event.cname?getEventColor(event):undefined;if(ctr.numSeries===0){for(const seriesName in event.args){const colorId=reservedColorId||getEventColor(event,ctr.name+'.'+seriesName);ctr.addSeries(new tr.model.CounterSeries(seriesName,colorId));}
 if(ctr.numSeries===0){this.model_.importWarning({type:'counter_parse_error',message:'Expected counter '+event.name+' to have at least one argument to use as a value.'});delete ctr.parent.counters[ctr.name];return;}}
-var ts=this.toModelTimeFromUs_(event.ts);ctr.series.forEach(function(series){var val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event:event,thread:thread});if(thread.guid in this.contextProcessorPerThread){var processor=this.contextProcessorPerThread[thread.guid];var scopedId=TraceEventImporter.scopedIdForEvent_(event);if(event.ph==='D'){processor.destroyContext(scopedId);}
-processor.invalidateContextCacheForSnapshot(scopedId);}},processContextEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(!(thread.guid in this.contextProcessorPerThread)){this.contextProcessorPerThread[thread.guid]=new tr.importer.ContextProcessor(this.model_);}
-var scopedId=TraceEventImporter.scopedIdForEvent_(event);var contextType=event.name;var processor=this.contextProcessorPerThread[thread.guid];if(event.ph==='('){processor.enterContext(contextType,scopedId);}else if(event.ph===')'){processor.leaveContext(contextType,scopedId);}else{this.model_.importWarning({type:'unknown_context_phase',message:'Unknown context event phase: '+event.ph+'.'});}},setContextsFromThread_:function(thread,slice){if(thread.guid in this.contextProcessorPerThread){slice.contexts=this.contextProcessorPerThread[thread.guid].activeContexts;}},processDurationEvent:function(event){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var ts=this.toModelTimeFromUs_(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
-if(event.ph==='B'){var slice=thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);this.setContextsFromThread_(thread,slice);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t'){throw new Error('This should never happen');}
-thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event));var slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
-var slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts),getEventColor(event));if(event.name&&slice.title!==event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+const ts=this.toModelTimeFromUs_(event.ts);ctr.series.forEach(function(series){const val=event.args[series.name]?event.args[series.name]:0;series.addCounterSample(ts,val);});},processObjectEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.allObjectEvents_.push({sequenceNumber:this.allObjectEvents_.length,event,thread});if(thread.guid in this.contextProcessorPerThread){const processor=this.contextProcessorPerThread[thread.guid];const scopedId=TraceEventImporter.scopedIdForEvent_(event);if(event.ph==='D'){processor.destroyContext(scopedId);}
+processor.invalidateContextCacheForSnapshot(scopedId);}},processContextEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(!(thread.guid in this.contextProcessorPerThread)){this.contextProcessorPerThread[thread.guid]=new tr.importer.ContextProcessor(this.model_);}
+const scopedId=TraceEventImporter.scopedIdForEvent_(event);const contextType=event.name;const processor=this.contextProcessorPerThread[thread.guid];if(event.ph==='('){processor.enterContext(contextType,scopedId);}else if(event.ph===')'){processor.leaveContext(contextType,scopedId);}else{this.model_.importWarning({type:'unknown_context_phase',message:'Unknown context event phase: '+event.ph+'.'});}},setContextsFromThread_(thread,slice){if(thread.guid in this.contextProcessorPerThread){slice.contexts=this.contextProcessorPerThread[thread.guid].activeContexts;}},processDurationEvent(event){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);const ts=this.toModelTimeFromUs_(event.ts);if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'duration_parse_error',message:'Timestamps are moving backward.'});return;}
+if(event.ph==='B'){const slice=thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event));slice.startStackFrame=this.getStackFrameForEvent_(event);this.setContextsFromThread_(thread,slice);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){if(event.s!==undefined&&event.s!=='t'){throw new Error('This should never happen');}
+thread.sliceGroup.beginSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args),this.toModelTimeFromUs_(event.tts),event.argsStripped,getEventColor(event));const slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts));slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=undefined;}else{if(!thread.sliceGroup.openSliceCount){this.model_.importWarning({type:'duration_parse_error',message:'E phase event without a matching B phase event.'});return;}
+const slice=thread.sliceGroup.endSlice(this.toModelTimeFromUs_(event.ts),this.toModelTimeFromUs_(event.tts),getEventColor(event));if(event.name&&slice.title!==event.name){this.model_.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
 slice.title+' in openSlice, and is '+
 event.name+' in endSlice'});}
-slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_:function(dstArgs,srcArgs,eventName){for(var arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
-dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent:function(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1){return undefined;}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in){event.flowPhase=STEP;}else{event.flowPhase=PRODUCER;}}else if(event.flow_in){event.flowPhase=CONSUMER;}
-var slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.maybeToModelTimeFromUs_(event.dur),this.maybeToModelTimeFromUs_(event.tts),this.maybeToModelTimeFromUs_(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);this.setContextsFromThread_(thread,slice);return slice;},processJitCodeEvent:function(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined){this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();}
-var map=this.v8ProcessCodeMaps_[event.pid];var data=event.args.data;if(event.name==='JitCodeMoved'){map.moveEntry(data.code_start,data.new_code_start,data.code_len);}else{map.addEntry(data.code_start,data.code_len,data.name,data.script_id);}},processMetadataEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
-if(event.argsStripped)return;if(event.name==='process_name'){var process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){var process=this.model_.getOrCreateProcess(event.pid);var labels=event.args.labels.split(',');for(var i=0;i<labels.length;i++){process.addLabelIfNeeded(labels[i]);}}else if(event.name==='process_uptime_seconds'){var process=this.model_.getOrCreateProcess(event.pid);process.uptime_seconds=event.args.uptime;}else if(event.name==='process_sort_index'){var process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){var n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined){n=Math.max(n,this.softwareMeasuredCpuCount_);}
-this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){var stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){var objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
-event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else if(event.name==='TraceConfig'){this.model_.metadata.push({name:'TraceConfig',value:event.args.value});}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent:function(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+slice.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(slice.args,event.args,slice.title);}},mergeArgsInto_(dstArgs,srcArgs,eventName){for(const arg in srcArgs){if(dstArgs[arg]!==undefined){this.model_.importWarning({type:'arg_merge_error',message:'Different phases of '+eventName+' provided values for argument '+arg+'.'+' The last provided value will be used.'});}
+dstArgs[arg]=this.deepCopyIfNeeded_(srcArgs[arg]);}},processCompleteEvent(event){if(event.cat!==undefined&&event.cat.indexOf('trace_event_overhead')>-1){return undefined;}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);if(event.flow_out){if(event.flow_in){event.flowPhase=STEP;}else{event.flowPhase=PRODUCER;}}else if(event.flow_in){event.flowPhase=CONSUMER;}
+const slice=thread.sliceGroup.pushCompleteSlice(event.cat,event.name,this.toModelTimeFromUs_(event.ts),this.maybeToModelTimeFromUs_(event.dur),this.maybeToModelTimeFromUs_(event.tts),this.maybeToModelTimeFromUs_(event.tdur),this.deepCopyIfNeeded_(event.args),event.argsStripped,getEventColor(event),event.bind_id);slice.startStackFrame=this.getStackFrameForEvent_(event);slice.endStackFrame=this.getStackFrameForEvent_(event,true);this.setContextsFromThread_(thread,slice);return slice;},processJitCodeEvent(event){if(this.v8ProcessCodeMaps_[event.pid]===undefined){this.v8ProcessCodeMaps_[event.pid]=new tr.e.importer.TraceCodeMap();}
+const map=this.v8ProcessCodeMaps_[event.pid];const data=event.args.data;if(event.name==='JitCodeMoved'){map.moveEntry(data.code_start,data.new_code_start,data.code_len);}else{map.addEntry(data.code_start,data.code_len,data.name,data.script_id);}},processMetadataEvent(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
+if(event.argsStripped)return;if(event.name==='process_name'){const process=this.model_.getOrCreateProcess(event.pid);process.name=event.args.name;}else if(event.name==='process_labels'){const process=this.model_.getOrCreateProcess(event.pid);const labels=event.args.labels.split(',');for(let i=0;i<labels.length;i++){process.addLabelIfNeeded(labels[i]);}}else if(event.name==='process_uptime_seconds'){const process=this.model_.getOrCreateProcess(event.pid);process.uptime_seconds=event.args.uptime;}else if(event.name==='process_sort_index'){const process=this.model_.getOrCreateProcess(event.pid);process.sortIndex=event.args.sort_index;}else if(event.name==='thread_name'){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.name=event.args.name;}else if(event.name==='thread_sort_index'){const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);thread.sortIndex=event.args.sort_index;}else if(event.name==='num_cpus'){let n=event.args.number;if(this.softwareMeasuredCpuCount_!==undefined){n=Math.max(n,this.softwareMeasuredCpuCount_);}
+this.softwareMeasuredCpuCount_=n;}else if(event.name==='stackFrames'){const stackFrames=event.args.stackFrames;if(stackFrames===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No stack frames found in a \''+event.name+'\' metadata event'});}else{this.importStackFrames_(stackFrames,'p'+event.pid+':');}}else if(event.name==='typeNames'){const objectTypeNameMap=event.args.typeNames;if(objectTypeNameMap===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'No mapping from object type IDs to names found in a \''+
+event.name+'\' metadata event'});}else{this.importObjectTypeNameMap_(objectTypeNameMap,event.pid);}}else if(event.name==='TraceConfig'){this.model_.metadata.push({name:'TraceConfig',value:event.args.value});}else{this.model_.importWarning({type:'metadata_parse_error',message:'Unrecognized metadata name: '+event.name});}},processInstantEvent(event){if(event.name==='JitCodeAdded'||event.name==='JitCodeMoved'){this.v8SamplingData_.push(event);return;}
 if(event.s==='t'||event.s===undefined){this.processDurationEvent(event);return;}
-var constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
-var instantEvent=new constructor(event.cat,event.name,getEventColor(event),this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.instantEvents.push(instantEvent);break;case tr.model.InstantEventType.PROCESS:var process=this.model_.getOrCreateProcess(event.pid);process.instantEvents.push(instantEvent);break;default:throw new Error('Unknown instant event type: '+event.s);}},getOrCreateProfileTree_:function(sampleType,id){if(!this.profileTrees_.has(sampleType)){this.profileTrees_.set(sampleType,new Map());}
-var profileTreeMap=this.profileTrees_.get(sampleType);if(profileTreeMap.has(id)){return profileTreeMap.get(id);}
-var profileTree=new tr.model.ProfileTree();profileTreeMap.set(id,profileTree);let info=this.profileInfo_.get(id);if(info!==undefined){profileTree.startTime=info.startTime;profileTree.pid=info.pid;profileTree.tid=info.tid;}
-return profileTree;},processSample:function(event){if(event.args===undefined||event.args.data===undefined){return;}
+let constructor;switch(event.s){case'g':constructor=tr.model.GlobalInstantEvent;break;case'p':constructor=tr.model.ProcessInstantEvent;break;default:this.model_.importWarning({type:'instant_parse_error',message:'I phase event with unknown "s" field value.'});return;}
+const instantEvent=new constructor(event.cat,event.name,getEventColor(event),this.toModelTimeFromUs_(event.ts),this.deepCopyIfNeeded_(event.args));switch(instantEvent.type){case tr.model.InstantEventType.GLOBAL:this.model_.instantEvents.push(instantEvent);break;case tr.model.InstantEventType.PROCESS:{const process=this.model_.getOrCreateProcess(event.pid);process.instantEvents.push(instantEvent);break;}
+default:throw new Error('Unknown instant event type: '+event.s);}},getOrCreateProfileTree_(sampleType,id){if(!this.profileTrees_.has(sampleType)){this.profileTrees_.set(sampleType,new Map());}
+const profileTreeMap=this.profileTrees_.get(sampleType);if(profileTreeMap.has(id)){return profileTreeMap.get(id);}
+const profileTree=new tr.model.ProfileTree();profileTreeMap.set(id,profileTree);const info=this.profileInfo_.get(id);if(info!==undefined){profileTree.startTime=info.startTime;profileTree.pid=info.pid;profileTree.tid=info.tid;}
+return profileTree;},processSample(event){if(event.args===undefined||event.args.data===undefined){return;}
 if(event.id===undefined){throw new Error('No event ID in sample');}
-var data=event.args.data;if(data['startTime']!==undefined){this.profileInfo_.set(event.id,{startTime:data['startTime'],pid:event.pid,tid:event.tid});}
-let timeDeltas=data['timeDeltas'];for(let sampleType in data){if(sampleType==='timeDeltas'||sampleType==='startTime'){continue;}
-if(data[sampleType]['samples']&&timeDeltas&&data[sampleType]['samples'].length!==timeDeltas.length){throw new Error('samples and timeDeltas array should have same length');}
-let profileTree=this.getOrCreateProfileTree_(sampleType,event['id']);let nodes=data[sampleType]['nodes'];let samples=data[sampleType]['samples'];if(nodes!==undefined){for(let node of nodes){var ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);let profileNode=ProfileNodeType.constructFromObject(profileTree,node);if(profileNode===undefined){continue;}
+const data=event.args.data;if(data.startTime!==undefined){this.profileInfo_.set(event.id,{startTime:data.startTime,pid:event.pid,tid:event.tid});}
+const timeDeltas=data.timeDeltas;for(const sampleType in data){if(sampleType==='timeDeltas'||sampleType==='startTime'){continue;}
+if(data[sampleType].samples&&timeDeltas&&data[sampleType].samples.length!==timeDeltas.length){throw new Error('samples and timeDeltas array should have same length');}
+const profileTree=this.getOrCreateProfileTree_(sampleType,event.id);const nodes=data[sampleType].nodes;const samples=data[sampleType].samples;if(nodes!==undefined){for(const node of nodes){const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);const profileNode=ProfileNodeType.constructFromObject(profileTree,node);if(profileNode===undefined){continue;}
 profileTree.add(profileNode);}}
-if(samples!==undefined){let thread=this.model_.getOrCreateProcess(profileTree.pid).getOrCreateThread(profileTree.tid);for(let i=0,len=samples.length;i<len;++i){let node=profileTree.getNode(samples[i]);profileTree.endTime+=timeDeltas[i];let start=this.toModelTimeFromUs_(profileTree.endTime);this.model_.samples.push(new tr.model.Sample(start,node.sampleTitle,node,thread));}}}},processLegacyV8Sample:function(event){var data=event.args.data;var sampleType='legacySample';var ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);if(data.vm_state==='js'&&!data.stack.length)return;var profileTree=this.getOrCreateProfileTree_(sampleType,event.pid);if(profileTree.getNode(-1)===undefined){profileTree.add(new ProfileNodeType(-1,{url:'',scriptId:-1,functionName:'unknown'},undefined));}
-let node=undefined;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){let map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();let parentNode=undefined;for(let i=0;i<data.stack.length;i++){let entry=map.lookupEntry(data.stack[i]);if(entry===undefined){node=profileTree.getNode(-1);}else{node=profileTree.getNode(entry.id);if(node===undefined){let sourceInfo=entry.sourceInfo;node=new ProfileNodeType(entry.id,{functionName:entry.name,url:entry.sourceInfo.file,lineNumber:sourceInfo.line!==-1?sourceInfo.line:undefined,columnNumber:sourceInfo.column!==-1?sourceInfo.column:undefined,scriptid:entry.sourceInfo.scriptId},parentNode);profileTree.add(node);}}
+if(samples!==undefined){const thread=this.model_.getOrCreateProcess(profileTree.pid).getOrCreateThread(profileTree.tid);for(let i=0,len=samples.length;i<len;++i){const node=profileTree.getNode(samples[i]);profileTree.endTime+=timeDeltas[i];const start=this.toModelTimeFromUs_(profileTree.endTime);this.model_.samples.push(new tr.model.Sample(start,node.sampleTitle,node,thread));}}}},processLegacyV8Sample(event){const data=event.args.data;const sampleType='legacySample';const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,sampleType);if(data.vm_state==='js'&&!data.stack.length)return;const profileTree=this.getOrCreateProfileTree_(sampleType,event.pid);if(profileTree.getNode(-1)===undefined){profileTree.add(new ProfileNodeType(-1,{url:'',scriptId:-1,functionName:'unknown'},undefined));}
+let node=undefined;if(data.stack.length>0&&this.v8ProcessCodeMaps_[event.pid]){const map=this.v8ProcessCodeMaps_[event.pid];data.stack.reverse();let parentNode=undefined;for(let i=0;i<data.stack.length;i++){const entry=map.lookupEntry(data.stack[i]);if(entry===undefined){node=profileTree.getNode(-1);}else{node=profileTree.getNode(entry.id);if(node===undefined){const sourceInfo=entry.sourceInfo;node=new ProfileNodeType(entry.id,{functionName:entry.name,url:entry.sourceInfo.file,lineNumber:sourceInfo.line!==-1?sourceInfo.line:undefined,columnNumber:sourceInfo.column!==-1?sourceInfo.column:undefined,scriptid:entry.sourceInfo.scriptId},parentNode);profileTree.add(node);}}
 parentNode=node;}}else{node=profileTree.getNode(data.vm_state);if(node===undefined){node=new ProfileNodeType(data.vm_state,{url:'',functionName:data.vm_state},undefined);profileTree.add(node);}}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.model_.samples.push(new tr.model.Sample(this.toModelTimeFromUs_(event.ts),node.sampleTitle,node,thread));},processTraceSampleEvent:function(event){if(event.name==='V8Sample'||event.name.startsWith('Profile')){this.v8SamplingData_.push(event);return;}
-var node=this.stackFrameTree_.getNode(event.name);if(node===undefined&&event.sf!==undefined){node=this.stackFrameTree_.getNode('g'+event.sf);}
-if(node===undefined){var id=event.name;if(event.sf){id='g'+event.sf;}
-var ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');node=this.stackFrameTree_.add(new ProfileNodeType(id,{functionName:event.name},undefined));}
-var thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);var sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),'Trace Event Sample',node,thread,undefined,1,this.deepCopyIfNeeded_(event.args));this.setContextsFromThread_(thread,sample);this.model_.samples.push(sample);},processMemoryDumpEvent:function(event){if(event.ph!=='v'){throw new Error('Invalid memory dump event phase "'+event.ph+'".');}
-var dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
-var pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);this.model_.samples.push(new tr.model.Sample(this.toModelTimeFromUs_(event.ts),node.sampleTitle,node,thread));},processTraceSampleEvent(event){if(event.name==='V8Sample'||event.name.startsWith('Profile')){this.v8SamplingData_.push(event);return;}
+let node=this.stackFrameTree_.getNode(event.name);if(node===undefined&&event.sf!==undefined){node=this.stackFrameTree_.getNode('g'+event.sf);}
+if(node===undefined){let id=event.name;if(event.sf){id='g'+event.sf;}
+const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');node=this.stackFrameTree_.add(new ProfileNodeType(id,{functionName:event.name},undefined));}
+const thread=this.model_.getOrCreateProcess(event.pid).getOrCreateThread(event.tid);const sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),'Trace Event Sample',node,thread,undefined,1,this.deepCopyIfNeeded_(event.args));this.setContextsFromThread_(thread,sample);this.model_.samples.push(sample);},processMemoryDumpEvent(event){if(event.ph!=='v'){throw new Error('Invalid memory dump event phase "'+event.ph+'".');}
+const dumpId=event.id;if(dumpId===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase \''+event.ph+'\') without a dump ID.'});return;}
+const pid=event.pid;if(pid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory dump event (phase\''+event.ph+'\', dump ID \''+
 dumpId+'\') without a PID.'});return;}
-var allEvents=this.allMemoryDumpEvents_;var dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined){allEvents[dumpId]=dumpIdEvents={};}
-var processEvents=dumpIdEvents[pid];if(processEvents===undefined){dumpIdEvents[pid]=processEvents=[];}
-processEvents.push(event);},processClockSyncEvent:function(event){if(event.ph!=='c'){throw new Error('Invalid clock sync event phase "'+event.ph+'".');}
-var syncId=event.args.sync_id;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+event.ts+' without an ID.'});return;}
-if(event.args&&event.args.issue_ts!==undefined){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.args.issue_ts),tr.b.Unit.timestampFromUs(event.ts));}else{this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.ts));}},processLegacyChromeClockSyncEvent:function(event){if(event.ph==='S'){this.legacyChromeClockSyncStartEvent_=event;}else if(event.ph==='F'){this.legacyChromeClockSyncFinishEvent_=event;}
+const allEvents=this.allMemoryDumpEvents_;let dumpIdEvents=allEvents[dumpId];if(dumpIdEvents===undefined){allEvents[dumpId]=dumpIdEvents={};}
+let processEvents=dumpIdEvents[pid];if(processEvents===undefined){dumpIdEvents[pid]=processEvents=[];}
+processEvents.push(event);},processClockSyncEvent(event){if(event.ph!=='c'){throw new Error('Invalid clock sync event phase "'+event.ph+'".');}
+const syncId=event.args.sync_id;if(syncId===undefined){this.model_.importWarning({type:'clock_sync_parse_error',message:'Clock sync at time '+event.ts+' without an ID.'});return;}
+if(event.args&&event.args.issue_ts!==undefined){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.args.issue_ts),tr.b.Unit.timestampFromUs(event.ts));}else{this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,syncId,tr.b.Unit.timestampFromUs(event.ts));}},processLegacyChromeClockSyncEvent(event){if(event.ph==='S'){this.legacyChromeClockSyncStartEvent_=event;}else if(event.ph==='F'){this.legacyChromeClockSyncFinishEvent_=event;}
 if(this.legacyChromeClockSyncStartEvent_===undefined||this.legacyChromeClockSyncFinishEvent_===undefined){return;}
-var startSyncId=this.legacyChromeClockSyncStartEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);var finishSyncId=this.legacyChromeClockSyncFinishEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);if(startSyncId!==finishSyncId){throw new Error('Inconsistent clock sync ID of legacy Chrome clock sync events');}
-this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,startSyncId,tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncStartEvent_.ts),tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncFinishEvent_.ts));},processV8Events:function(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)return a.ts-b.ts;if(a.ph==='M'||a.ph==='I'){return-1;}else if(b.ph==='M'||b.ph==='I'){return 1;}
-return 0;});var length=this.v8SamplingData_.length;for(var i=0;i<length;++i){var event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){if(event.name.startsWith('Profile')){this.processSample(event);}else{this.processLegacyV8Sample(event);}}}},importClockSyncMarkers:function(){for(var i=0;i<this.events_.length;i++){var event=this.events_[i];var isLegacyChromeClockSync=isLegacyChromeClockSyncEvent(event);if(event.ph!=='c'&&!isLegacyChromeClockSync)continue;var eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);if(isLegacyChromeClockSync){this.processLegacyChromeClockSyncEvent(event);}else{this.processClockSyncEvent(event);}}},importEvents:function(){if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g');}
-if(this.traceAnnotations_){this.importAnnotations_();}
-var importOptions=this.model_.importOptions;var trackDetailedModelStats=importOptions.trackDetailedModelStats;var modelStats=this.model_.stats;var events=this.events_;for(var eI=0;eI<events.length;eI++){var event=events[eI];if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
-var eventSizeInBytes;if(trackDetailedModelStats){eventSizeInBytes=JSON.stringify(event).length;}else{eventSizeInBytes=undefined;}
-if(event.ph==='B'||event.ph==='E'){modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);}else if(event.ph==='X'){modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);var slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined){this.processFlowEvent(event,slice);}}else if(event.ph==='b'||event.ph==='e'||event.ph==='n'||event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);}else if(event.ph==='I'||event.ph==='i'||event.ph==='R'){modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);}else if(event.ph==='P'){modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);}else if(event.ph==='C'){modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);}else if(event.ph==='M'){modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);}else if(event.ph==='N'||event.ph==='D'||event.ph==='O'){modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);}else if(event.ph==='s'||event.ph==='t'||event.ph==='f'){modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);}else if(event.ph==='v'){modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);}else if(event.ph==='('||event.ph===')'){this.processContextEvent(event);}else if(event.ph==='c'){}else{modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
-event.ph+' ('+event.name+')'});}}
-this.processV8Events();for(var frame of Object.values(this.v8ProcessRootStackFrame_)){frame.removeAllChildren();}},importStackFrames_:function(rawStackFrames,idPrefix){var model=this.model_;for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var fullId=idPrefix+id;var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
-for(var id in rawStackFrames){var fullId=idPrefix+id;var stackFrame=model.stackFrames[fullId];if(stackFrame===undefined){throw new Error('Internal error');}
-var rawStackFrame=rawStackFrames[id];var parentId=rawStackFrame.parent;var parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{var parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
+const startSyncId=this.legacyChromeClockSyncStartEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);const finishSyncId=this.legacyChromeClockSyncFinishEvent_.name.substring(LEGACY_CHROME_CLOCK_SYNC_EVENT_NAME_PREFIX.length);if(startSyncId!==finishSyncId){throw new Error('Inconsistent clock sync ID of legacy Chrome clock sync events');}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,startSyncId,tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncStartEvent_.ts),tr.b.Unit.timestampFromUs(this.legacyChromeClockSyncFinishEvent_.ts));},processV8Events(){this.v8SamplingData_.sort(function(a,b){if(a.ts!==b.ts)return a.ts-b.ts;if(a.ph==='M'||a.ph==='I'){return-1;}else if(b.ph==='M'||b.ph==='I'){return 1;}
+return 0;});const length=this.v8SamplingData_.length;for(let i=0;i<length;++i){const event=this.v8SamplingData_[i];if(event.ph==='M'||event.ph==='I'){this.processJitCodeEvent(event);}else if(event.ph==='P'){if(event.name.startsWith('Profile')){this.processSample(event);}else{this.processLegacyV8Sample(event);}}}},importClockSyncMarkers(){if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',this.importClockSyncMarker_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}else{for(let i=0;i<this.events_.length;i++){this.importClockSyncMarker_(this.events_[i]);}}},importClockSyncMarker_(event){const isLegacyChromeClockSync=isLegacyChromeClockSyncEvent(event);if(event.ph!=='c'&&!isLegacyChromeClockSync)return;const eventSizeInBytes=this.model_.importOptions.trackDetailedModelStats?JSON.stringify(event).length:undefined;this.model_.stats.willProcessBasicTraceEvent('clock_sync',event.cat,event.name,event.ts,eventSizeInBytes);if(isLegacyChromeClockSync){this.processLegacyChromeClockSyncEvent(event);}else{this.processClockSyncEvent(event);}},importEvents(){this.hasEvents_=false;if(this.stackFrameEvents_){this.importStackFrames_(this.stackFrameEvents_,'g');}
+if(this.traceAnnotations_)this.importAnnotations_();if(this.events_ instanceof tr.b.TraceStream){const parser=oboe().node('{cat ph}',this.processEvent_.bind(this));this.events_.rewind();while(this.events_.hasData){parser.write(this.events_.readNumBytes());}
+parser.finish();}else{for(let eI=0;eI<this.events_.length;eI++){this.processEvent_(this.events_[eI]);}}
+this.processV8Events();for(const frame of Object.values(this.v8ProcessRootStackFrame_)){frame.removeAllChildren();}},storeSubtrace_(subtrace){this.subtraces_.push(subtrace);return oboe.drop;},storeSamples_(samples){this.sampleEvents_=samples;return oboe.drop;},storeStackFrames_(stackFrames){this.stackFrameEvents_=stackFrames;return oboe.drop;},storeDisplayTimeUnit_(unitName){if(!unitName)return;const unit=tr.b.TimeDisplayModes[unitName];if(unit===undefined){throw new Error('Unit '+unitName+' is not supported.');}
+this.model_.intrinsicTimeUnit=unit;return oboe.drop;},storeTraceAnnotations_(traceAnnotations){this.traceAnnotations_=traceAnnotations;return oboe.drop;},storeMetadata_(container){for(const fieldName of Object.keys(container)){if(NON_METADATA_FIELDS.has(fieldName))continue;this.model_.metadata.push({name:fieldName,value:container[fieldName]});if(fieldName!=='metadata')continue;const metadata=container[fieldName];if(metadata['highres-ticks']){this.model_.isTimeHighResolution=metadata['highres-ticks'];}
+if(metadata['clock-domain']){this.clockDomainId_=metadata['clock-domain'];}}
+return oboe.drop;},processEvent_(event){this.hasEvents_=true;const importOptions=this.model_.importOptions;const trackDetailedModelStats=importOptions.trackDetailedModelStats;const modelStats=this.model_.stats;if(event.args==='__stripped__'){event.argsStripped=true;event.args=undefined;}
+let eventSizeInBytes=undefined;if(trackDetailedModelStats){eventSizeInBytes=JSON.stringify(event).length;}
+switch(event.ph){case'B':case'E':modelStats.willProcessBasicTraceEvent('begin_end (non-compact)',event.cat,event.name,event.ts,eventSizeInBytes);this.processDurationEvent(event);break;case'X':{modelStats.willProcessBasicTraceEvent('begin_end (compact)',event.cat,event.name,event.ts,eventSizeInBytes);const slice=this.processCompleteEvent(event);if(slice!==undefined&&event.bind_id!==undefined){this.processFlowEvent(event,slice);}
+break;}
+case'b':case'e':case'n':case'S':case'F':case'T':case'p':modelStats.willProcessBasicTraceEvent('async',event.cat,event.name,event.ts,eventSizeInBytes);this.processAsyncEvent(event);break;case'I':case'i':case'R':modelStats.willProcessBasicTraceEvent('instant',event.cat,event.name,event.ts,eventSizeInBytes);this.processInstantEvent(event);break;case'P':modelStats.willProcessBasicTraceEvent('samples',event.cat,event.name,event.ts,eventSizeInBytes);this.processTraceSampleEvent(event);break;case'C':modelStats.willProcessBasicTraceEvent('counters',event.cat,event.name,event.ts,eventSizeInBytes);this.processCounterEvent(event);break;case'M':modelStats.willProcessBasicTraceEvent('metadata',event.cat,event.name,event.ts,eventSizeInBytes);this.processMetadataEvent(event);break;case'N':case'D':case'O':modelStats.willProcessBasicTraceEvent('objects',event.cat,event.name,event.ts,eventSizeInBytes);this.processObjectEvent(event);break;case's':case't':case'f':modelStats.willProcessBasicTraceEvent('flows',event.cat,event.name,event.ts,eventSizeInBytes);this.processFlowEvent(event);break;case'v':modelStats.willProcessBasicTraceEvent('memory_dumps',event.cat,event.name,event.ts,eventSizeInBytes);this.processMemoryDumpEvent(event);break;case'(':case')':this.processContextEvent(event);break;case'c':break;default:modelStats.willProcessBasicTraceEvent('unknown',event.cat,event.name,event.ts,eventSizeInBytes);this.model_.importWarning({type:'parse_error',message:'Unrecognized event phase: '+
+event.ph+' ('+event.name+')'});}
+return oboe.drop;},importStackFrames_(rawStackFrames,idPrefix){const model=this.model_;for(const id in rawStackFrames){const rawStackFrame=rawStackFrames[id];const fullId=idPrefix+id;const textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;const stackFrame=new tr.model.StackFrame(undefined,fullId,rawStackFrame.name,ColorScheme.getColorIdForGeneralPurposeString(textForColor));model.addStackFrame(stackFrame);}
+for(const id in rawStackFrames){const fullId=idPrefix+id;const stackFrame=model.stackFrames[fullId];if(stackFrame===undefined){throw new Error('Internal error');}
+const rawStackFrame=rawStackFrames[id];const parentId=rawStackFrame.parent;let parentStackFrame;if(parentId===undefined){parentStackFrame=undefined;}else{const parentFullId=idPrefix+parentId;parentStackFrame=model.stackFrames[parentFullId];if(parentStackFrame===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentFullId+' for stack frame \''+stackFrame.name+'\' (ID '+fullId+').'});}}
 stackFrame.parentFrame=parentStackFrame;}
-var ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');if(idPrefix==='g'){for(var id in rawStackFrames){var rawStackFrame=rawStackFrames[id];var textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;var node=this.stackFrameTree_.add(new ProfileNodeType('g'+id,{functionName:rawStackFrame.name},undefined));node.colorId=ColorScheme.getColorIdForGeneralPurposeString(textForColor);node.parentId=rawStackFrame.parent;}
-for(var id in rawStackFrames){var node=this.stackFrameTree_.getNode('g'+id);var parentId=node.parentId;var parentNode=undefined;if(parentId!==undefined){parentNode=this.stackFrameTree_.getNode('g'+parentId);if(parentNode===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentId+' for stack frame \''+node.name+'\' (ID '+node.id+').'});}
-node.parentNode=parentNode;}}}},importObjectTypeNameMap_:function(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
+const ProfileNodeType=tr.model.ProfileNode.subTypes.getConstructor(undefined,'legacySample');if(idPrefix==='g'){for(const id in rawStackFrames){const rawStackFrame=rawStackFrames[id];const textForColor=rawStackFrame.category?rawStackFrame.category:rawStackFrame.name;const node=this.stackFrameTree_.add(new ProfileNodeType('g'+id,{functionName:rawStackFrame.name},undefined));node.colorId=ColorScheme.getColorIdForGeneralPurposeString(textForColor);node.parentId=rawStackFrame.parent;}
+for(const id in rawStackFrames){const node=this.stackFrameTree_.getNode('g'+id);const parentId=node.parentId;let parentNode=undefined;if(parentId!==undefined){parentNode=this.stackFrameTree_.getNode('g'+parentId);if(parentNode===undefined){this.model_.importWarning({type:'metadata_parse_error',message:'Missing parent frame with ID '+parentId+' for stack frame \''+node.name+'\' (ID '+node.id+').'});}
+node.parentNode=parentNode;}}}},importObjectTypeNameMap_(rawObjectTypeNameMap,pid){if(pid in this.objectTypeNameMap_){this.model_.importWarning({type:'metadata_parse_error',message:'Mapping from object type IDs to names provided for pid='+
 pid+' multiple times.'});return;}
-var objectTypeNamePrefix=undefined;var objectTypeNameSuffix=undefined;var objectTypeNameMap={};for(var objectTypeId in rawObjectTypeNameMap){var rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(var i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){var pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
+let objectTypeNamePrefix=undefined;let objectTypeNameSuffix=undefined;const objectTypeNameMap={};for(const objectTypeId in rawObjectTypeNameMap){const rawObjectTypeName=rawObjectTypeNameMap[objectTypeId];if(objectTypeNamePrefix===undefined){for(let i=0;i<OBJECT_TYPE_NAME_PATTERNS.length;i++){const pattern=OBJECT_TYPE_NAME_PATTERNS[i];if(rawObjectTypeName.startsWith(pattern.prefix)&&rawObjectTypeName.endsWith(pattern.suffix)){objectTypeNamePrefix=pattern.prefix;objectTypeNameSuffix=pattern.suffix;break;}}}
 if(objectTypeNamePrefix!==undefined&&rawObjectTypeName.startsWith(objectTypeNamePrefix)&&rawObjectTypeName.endsWith(objectTypeNameSuffix)){objectTypeNameMap[objectTypeId]=rawObjectTypeName.substring(objectTypeNamePrefix.length,rawObjectTypeName.length-objectTypeNameSuffix.length);}else{objectTypeNameMap[objectTypeId]=rawObjectTypeName;}}
-this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_:function(){for(var id in this.traceAnnotations_){var annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
+this.objectTypeNameMap_[pid]=objectTypeNameMap;},importAnnotations_(){for(const id in this.traceAnnotations_){const annotation=tr.model.Annotation.fromDictIfPossible(this.traceAnnotations_[id]);if(!annotation){this.model_.importWarning({type:'annotation_warning',message:'Unrecognized traceAnnotation typeName \"'+
 this.traceAnnotations_[id].typeName+'\"'});continue;}
-this.model_.addAnnotation(annotation);}},finalizeImport:function(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
-this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_:function(event,opt_lookForEndEvent){var sf;var stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
+this.model_.addAnnotation(annotation);}},finalizeImport(){if(this.softwareMeasuredCpuCount_!==undefined){this.model_.kernel.softwareMeasuredCpuCount=this.softwareMeasuredCpuCount_;}
+this.createAsyncSlices_();this.createFlowSlices_();this.createExplicitObjects_();this.createImplicitObjects_();this.createMemoryDumps_();},getStackFrameForEvent_(event,opt_lookForEndEvent){let sf;let stack;if(opt_lookForEndEvent){sf=event.esf;stack=event.estack;}else{sf=event.sf;stack=event.stack;}
 if(stack!==undefined&&sf!==undefined){this.model_.importWarning({type:'stack_frame_and_stack_error',message:'Event at '+event.ts+' cannot have both a stack and a stackframe.'});return undefined;}
 if(stack!==undefined){return this.model_.resolveStackToStackFrame_(event.pid,stack);}
-if(sf===undefined)return undefined;var stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
-return stackFrame;},resolveStackToStackFrame_:function(pid,stack){return undefined;},importSampleData:function(){if(!this.sampleEvents_)return;var m=this.model_;var events=this.sampleEvents_;if(this.events_.length===0){for(var i=0;i<events.length;i++){var event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
-var threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(var i=0;i<events.length;i++){var event=events[i];var thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
-var cpu;if(event.cpu!==undefined){cpu=m.kernel.getOrCreateCpu(event.cpu);}
-var leafNode=this.stackFrameTree_.getNode('g'+event.sf);var sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),event.name,leafNode,thread,cpu,event.weight);m.samples.push(sample);}},createAsyncSlices_:function(){if(this.allAsyncEvents_.length===0)return;this.allAsyncEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});var legacyEvents=[];var nestableAsyncEventsByKey={};var nestableMeasureAsyncEventsByKey={};for(var i=0;i<this.allAsyncEvents_.length;i++){var asyncEventState=this.allAsyncEvents_[i];var event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
+if(sf===undefined)return undefined;const stackFrame=this.model_.stackFrames['g'+sf];if(stackFrame===undefined){this.model_.importWarning({type:'sample_import_error',message:'No frame for '+sf});return;}
+return stackFrame;},resolveStackToStackFrame_(pid,stack){return undefined;},importSampleData(){if(!this.sampleEvents_)return;const m=this.model_;const events=this.sampleEvents_;if(this.hasEvents_===undefined){throw new Error('importEvents is not run before importSampleData');}else if(!this.hasEvents_){for(let i=0;i<events.length;i++){const event=events[i];m.getOrCreateProcess(event.tid).getOrCreateThread(event.tid);}}
+const threadsByTid={};m.getAllThreads().forEach(function(t){threadsByTid[t.tid]=t;});for(let i=0;i<events.length;i++){const event=events[i];const thread=threadsByTid[event.tid];if(thread===undefined){m.importWarning({type:'sample_import_error',message:'Thread '+events.tid+'not found'});continue;}
+let cpu;if(event.cpu!==undefined){cpu=m.kernel.getOrCreateCpu(event.cpu);}
+const leafNode=this.stackFrameTree_.getNode('g'+event.sf);const sample=new tr.model.Sample(this.toModelTimeFromUs_(event.ts),event.name,leafNode,thread,cpu,event.weight);m.samples.push(sample);}},createAsyncSlices_(){if(this.allAsyncEvents_.length===0)return;this.allAsyncEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const legacyEvents=[];const nestableAsyncEventsByKey={};const nestableMeasureAsyncEventsByKey={};for(let i=0;i<this.allAsyncEvents_.length;i++){const asyncEventState=this.allAsyncEvents_[i];const event=asyncEventState.event;if(event.ph==='S'||event.ph==='F'||event.ph==='T'||event.ph==='p'){legacyEvents.push(asyncEventState);continue;}
 if(event.cat===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'cat parameter.'});continue;}
 if(event.name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require a '+'name parameter.'});continue;}
-var id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
-if(event.cat==='blink.user_timing'){var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name);if(matched!==null){var key=matched[1]+':'+event.cat;event.args=JSON.parse(Base64.atob(matched[3])||'{}');if(nestableMeasureAsyncEventsByKey[key]===undefined){nestableMeasureAsyncEventsByKey[key]=[];}
+const id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async events (ph: b, e, or n) require an '+'id parameter.'});continue;}
+if(event.cat==='blink.user_timing'){const matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(event.name);if(matched!==null){const key=matched[1]+':'+event.cat;event.args=JSON.parse(Base64.atob(matched[3])||'{}');if(nestableMeasureAsyncEventsByKey[key]===undefined){nestableMeasureAsyncEventsByKey[key]=[];}
 nestableMeasureAsyncEventsByKey[key].push(asyncEventState);continue;}}
-var key=event.cat+':'+id.toStringWithDelimiter(':');if(nestableAsyncEventsByKey[key]===undefined){nestableAsyncEventsByKey[key]=[];}
+const key=event.cat+':'+id.toStringWithDelimiter(':');if(nestableAsyncEventsByKey[key]===undefined){nestableAsyncEventsByKey[key]=[];}
 nestableAsyncEventsByKey[key].push(asyncEventState);}
-this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlices_:function(legacyEvents){if(legacyEvents.length===0)return;legacyEvents.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});var asyncEventStatesByNameThenID={};for(var i=0;i<legacyEvents.length;i++){var asyncEventState=legacyEvents[i];var event=asyncEventState.event;var name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
-var id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
-var key=id.toStringWithDelimiter(':');if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined){asyncEventStatesByNameThenID[name]={};}
+this.createLegacyAsyncSlices_(legacyEvents);this.createNestableAsyncSlices_(nestableMeasureAsyncEventsByKey);this.createNestableAsyncSlices_(nestableAsyncEventsByKey);},createLegacyAsyncSlices_(legacyEvents){if(legacyEvents.length===0)return;legacyEvents.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const asyncEventStatesByNameThenID={};for(let i=0;i<legacyEvents.length;i++){const asyncEventState=legacyEvents[i];const event=asyncEventState.event;const name=event.name;if(name===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require a name '+' parameter.'});continue;}
+const id=TraceEventImporter.scopedIdForEvent_(event);if(id===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'Async events (ph: S, T, p, or F) require an id parameter.'});continue;}
+const key=id.toStringWithDelimiter(':');if(event.ph==='S'){if(asyncEventStatesByNameThenID[name]===undefined){asyncEventStatesByNameThenID[name]={};}
 if(asyncEventStatesByNameThenID[name][key]){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', a slice of the same id '+id+' was alrady open.'});continue;}
 asyncEventStatesByNameThenID[name][key]=[];asyncEventStatesByNameThenID[name][key].push(asyncEventState);}else{if(asyncEventStatesByNameThenID[name]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' was open.'});continue;}
 if(asyncEventStatesByNameThenID[name][key]===undefined){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.ts+', no slice named '+name+' with id='+id+' was open.'});continue;}
-var events=asyncEventStatesByNameThenID[name][key];events.push(asyncEventState);if(event.ph==='F'){var asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,name);var slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),this.toModelTimeFromUs_(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),this.toModelTimeFromUs_(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=key;var stepType=events[1].event.ph;var isValid=true;for(var j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)break;}
+const events=asyncEventStatesByNameThenID[name][key];events.push(asyncEventState);if(event.ph==='F'){const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,name);const slice=new asyncSliceConstructor(events[0].event.cat,name,getEventColor(events[0].event),this.toModelTimeFromUs_(events[0].event.ts),tr.b.concatenateObjects(events[0].event.args,events[events.length-1].event.args),this.toModelTimeFromUs_(event.ts-events[0].event.ts),true,undefined,undefined,events[0].event.argsStripped);slice.startThread=events[0].thread;slice.endThread=asyncEventState.thread;slice.id=key;const stepType=events[1].event.ph;let isValid=true;for(let j=1;j<events.length-1;++j){if(events[j].event.ph==='T'||events[j].event.ph==='p'){isValid=this.assertStepTypeMatches_(stepType,events[j]);if(!isValid)break;}
 if(events[j].event.ph==='S'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+events[j].event.ts+', a slice named '+
 name+' with id='+id+' had a step before the start event.'});continue;}
 if(events[j].event.ph==='F'){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+events[j].event.ts+', a slice named '+
 name+' with id='+id+' had a step after the finish event.'});continue;}
-var startIndex=j+(stepType==='T'?0:-1);var endIndex=startIndex+1;var subName=name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p')){subName=subName+':'+events[j].event.args.step;}
-var asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,subName);var subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),this.toModelTimeFromUs_(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),this.toModelTimeFromUs_(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=key;slice.subSlices.push(subSlice);}
+const startIndex=j+(stepType==='T'?0:-1);const endIndex=startIndex+1;let subName=name;if(!events[j].event.argsStripped&&(events[j].event.ph==='T'||events[j].event.ph==='p')){subName=subName+':'+events[j].event.args.step;}
+const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(events[0].event.cat,subName);const subSlice=new asyncSliceConstructor(events[0].event.cat,subName,getEventColor(event,subName+j),this.toModelTimeFromUs_(events[startIndex].event.ts),this.deepCopyIfNeeded_(events[j].event.args),this.toModelTimeFromUs_(events[endIndex].event.ts-events[startIndex].event.ts),undefined,undefined,events[startIndex].event.argsStripped);subSlice.startThread=events[startIndex].thread;subSlice.endThread=events[endIndex].thread;subSlice.id=key;slice.subSlices.push(subSlice);}
 if(isValid){slice.startThread.asyncSliceGroup.push(slice);}
-delete asyncEventStatesByNameThenID[name][key];}}}},createNestableAsyncSlices_:function(nestableEventsByKey){for(var key in nestableEventsByKey){var eventStateEntries=nestableEventsByKey[key];var parentStack=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){var parentIndex=-1;for(var k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
+delete asyncEventStatesByNameThenID[name][key];}}}},createNestableAsyncSlices_(nestableEventsByKey){for(const key in nestableEventsByKey){const eventStateEntries=nestableEventsByKey[key];const parentStack=[];for(let i=0;i<eventStateEntries.length;++i){const eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'){let parentIndex=-1;for(let k=parentStack.length-1;k>=0;--k){if(parentStack[k].event.name===eventStateEntry.event.name){parentIndex=k;break;}}
 if(parentIndex===-1){eventStateEntry.finished=false;}else{parentStack[parentIndex].end=eventStateEntry;while(parentIndex<parentStack.length){parentStack.pop();}}}
 if(parentStack.length>0){eventStateEntry.parentEntry=parentStack[parentStack.length-1];}
 if(eventStateEntry.event.ph==='b'){parentStack.push(eventStateEntry);}}
-var topLevelSlices=[];for(var i=0;i<eventStateEntries.length;++i){var eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
-var startState=undefined;var endState=undefined;var sliceArgs=eventStateEntry.event.args||{};var sliceError=undefined;var id=TraceEventImporter.scopedIdForEvent_(eventStateEntry.event);if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
+const topLevelSlices=[];for(let i=0;i<eventStateEntries.length;++i){const eventStateEntry=eventStateEntries[i];if(eventStateEntry.event.ph==='e'&&eventStateEntry.finished===undefined){continue;}
+let startState=undefined;let endState=undefined;let sliceArgs=eventStateEntry.event.args||{};let sliceError=undefined;const id=TraceEventImporter.scopedIdForEvent_(eventStateEntry.event);if(eventStateEntry.event.ph==='n'){startState=eventStateEntry;endState=eventStateEntry;}else if(eventStateEntry.event.ph==='b'){if(eventStateEntry.end===undefined){eventStateEntry.end=eventStateEntries[eventStateEntries.length-1];sliceError='Slice has no matching END. End time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async BEGIN event at '+
 eventStateEntry.event.ts+' with name='+
 eventStateEntry.event.name+' and id='+id+' was unmatched.'});}else{function concatenateArguments(args1,args2){if(args1.params===undefined||args2.params===undefined){return tr.b.concatenateObjects(args1,args2);}
-var args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
-var endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
+const args3={};args3.params=tr.b.concatenateObjects(args1.params,args2.params);return tr.b.concatenateObjects(args1,args2,args3);}
+const endArgs=eventStateEntry.end.event.args||{};sliceArgs=concatenateArguments(sliceArgs,endArgs);}
 startState=eventStateEntry;endState=eventStateEntry.end;}else{sliceError='Slice has no matching BEGIN. Start time has been adjusted.';this.model_.importWarning({type:'async_slice_parse_error',message:'Nestable async END event at '+
 eventStateEntry.event.ts+' with name='+
 eventStateEntry.event.name+' and id='+id+' was unmatched.'});startState=eventStateEntries[0];endState=eventStateEntry;}
-var isTopLevel=(eventStateEntry.parentEntry===undefined);var asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);var threadStart=undefined;var threadDuration=undefined;if(startState.event.tts&&startState.event.use_async_tts){threadStart=this.toModelTimeFromUs_(startState.event.tts);if(endState.event.tts){var threadEnd=this.toModelTimeFromUs_(endState.event.tts);threadDuration=threadEnd-threadStart;}}
-var slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),this.toModelTimeFromUs_(startState.event.ts),sliceArgs,this.toModelTimeFromUs_(endState.event.ts-startState.event.ts),isTopLevel,threadStart,threadDuration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined){slice.error=sliceError;}
+const isTopLevel=(eventStateEntry.parentEntry===undefined);const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(eventStateEntry.event.cat,eventStateEntry.event.name);let threadStart=undefined;let threadDuration=undefined;if(startState.event.tts&&startState.event.use_async_tts){threadStart=this.toModelTimeFromUs_(startState.event.tts);if(endState.event.tts){const threadEnd=this.toModelTimeFromUs_(endState.event.tts);threadDuration=threadEnd-threadStart;}}
+const slice=new asyncSliceConstructor(eventStateEntry.event.cat,eventStateEntry.event.name,getEventColor(endState.event),this.toModelTimeFromUs_(startState.event.ts),sliceArgs,this.toModelTimeFromUs_(endState.event.ts-startState.event.ts),isTopLevel,threadStart,threadDuration,startState.event.argsStripped);slice.startThread=startState.thread;slice.endThread=endState.thread;slice.startStackFrame=this.getStackFrameForEvent_(startState.event);slice.endStackFrame=this.getStackFrameForEvent_(endState.event);slice.id=key;if(sliceError!==undefined){slice.error=sliceError;}
 eventStateEntry.slice=slice;if(isTopLevel){topLevelSlices.push(slice);}else if(eventStateEntry.parentEntry.slice!==undefined){eventStateEntry.parentEntry.slice.subSlices.push(slice);}}
-for(var si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_:function(stepType,event){if(stepType!==event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
+for(let si=0;si<topLevelSlices.length;si++){topLevelSlices[si].startThread.asyncSliceGroup.push(topLevelSlices[si]);}}},assertStepTypeMatches_(stepType,event){if(stepType!==event.event.ph){this.model_.importWarning({type:'async_slice_parse_error',message:'At '+event.event.ts+', a slice named '+
 event.event.name+' with id='+
 TraceEventImporter.scopedIdForEvent_(event.event)+' had both begin and end steps, which is not allowed.'});return false;}
 return true;},validateFlowEvent_(event){if(event.name===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow events (ph: s, t or f) require a name parameter.'});return false;}
@@ -5489,81 +5816,82 @@
 return true;}
 if(event.bind_id){if(event.flow_in===undefined&&event.flow_out===undefined){this.model_.importWarning({type:'flow_slice_parse_error',message:'Flow producer or consumer require flow_in or flow_out.'});return false;}
 return true;}
-return false;},createFlowSlices_:function(){if(this.allFlowEvents_.length===0)return;var createFlowEvent=function(thread,event,opt_slice){var startSlice;var flowId;var flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=this.toModelTimeFromUs_(event.ts+event.dur);}else{var ts=this.toModelTimeFromUs_(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)return undefined;flowId=event.id;flowStartTs=ts;}
-var flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,this.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=this.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}.bind(this);var finishFlowEventWith=function(flowEvent,thread,event,refGuid,bindToParent,opt_slice){var endSlice;if(event.bind_id){endSlice=opt_slice;}else{var ts=this.toModelTimeFromUs_(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
+return false;},createFlowSlices_(){if(this.allFlowEvents_.length===0)return;const createFlowEvent=function(thread,event,opt_slice){let startSlice;let flowId;let flowStartTs;if(event.bind_id){startSlice=opt_slice;flowId=event.bind_id;flowStartTs=this.toModelTimeFromUs_(event.ts+event.dur);}else{const ts=this.toModelTimeFromUs_(event.ts);startSlice=thread.sliceGroup.findSliceAtTs(ts);if(startSlice===undefined)return undefined;flowId=event.id;flowStartTs=ts;}
+const flowEvent=new tr.model.FlowEvent(event.cat,flowId,event.name,getEventColor(event),flowStartTs,this.deepCopyAlways_(event.args));flowEvent.startSlice=startSlice;flowEvent.startStackFrame=this.getStackFrameForEvent_(event);flowEvent.endStackFrame=undefined;startSlice.outFlowEvents.push(flowEvent);return flowEvent;}.bind(this);const finishFlowEventWith=function(flowEvent,thread,event,refGuid,bindToParent,opt_slice){let endSlice;if(event.bind_id){endSlice=opt_slice;}else{const ts=this.toModelTimeFromUs_(event.ts);if(bindToParent){endSlice=thread.sliceGroup.findSliceAtTs(ts);}else{endSlice=thread.sliceGroup.findNextSliceAfter(ts,refGuid);}
 if(endSlice===undefined)return false;}
-endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=this.toModelTimeFromUs_(event.ts)-flowEvent.start;flowEvent.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}.bind(this);const processFlowConsumer=function(flowIdToEvent,sliceGuidToEvent,event,slice){var flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){var flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
-var ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
+endSlice.inFlowEvents.push(flowEvent);flowEvent.endSlice=endSlice;flowEvent.duration=this.toModelTimeFromUs_(event.ts)-flowEvent.start;flowEvent.endStackFrame=this.getStackFrameForEvent_(event);this.mergeArgsInto_(flowEvent.args,event.args,flowEvent.title);return true;}.bind(this);const processFlowConsumer=function(flowIdToEvent,sliceGuidToEvent,event,slice){let flowEvent=flowIdToEvent[event.bind_id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Flow consumer '+event.bind_id+' does not have '+'a flow producer'});return false;}else if(flowEvent.endSlice){const flowProducer=flowEvent.startSlice;flowEvent=createFlowEvent(undefined,sliceGuidToEvent[flowProducer.guid],flowProducer);}
+const refGuid=undefined;const ok=finishFlowEventWith(flowEvent,undefined,event,refGuid,undefined,slice);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'Flow consumer '+event.bind_id+' does not end '+'at an actual slice, so cannot be created.'});return false;}
 return true;}.bind(this);const processFlowProducer=function(flowIdToEvent,flowStatus,event,slice){if(flowIdToEvent[event.bind_id]&&flowStatus[event.bind_id]){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' already seen'});return false;}
-var flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
-flowIdToEvent[event.bind_id]=flowEvent;}.bind(this);this.allFlowEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});var flowIdToEvent={};var sliceGuidToEvent={};var flowStatus={};for(var i=0;i<this.allFlowEvents_.length;++i){var data=this.allFlowEvents_[i];var refGuid=data.refGuid;var event=data.event;var thread=data.thread;if(!this.validateFlowEvent_(event))continue;if(event.bind_id){var slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
+const flowEvent=createFlowEvent(undefined,event,slice);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'Flow producer '+event.bind_id+' does not start'+'a flow'});return false;}
+flowIdToEvent[event.bind_id]=flowEvent;}.bind(this);this.allFlowEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const flowIdToEvent={};const sliceGuidToEvent={};const flowStatus={};for(let i=0;i<this.allFlowEvents_.length;++i){const data=this.allFlowEvents_[i];const refGuid=data.refGuid;const event=data.event;const thread=data.thread;if(!this.validateFlowEvent_(event))continue;if(event.bind_id){const slice=data.slice;sliceGuidToEvent[slice.guid]=event;if(event.flowPhase===PRODUCER){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
 flowStatus[event.bind_id]=true;}else{if(!processFlowConsumer(flowIdToEvent,sliceGuidToEvent,event,slice)){continue;}
 flowStatus[event.bind_id]=false;if(event.flowPhase===STEP){if(!processFlowProducer(flowIdToEvent,flowStatus,event,slice)){continue;}
 flowStatus[event.bind_id]=true;}}
 continue;}
-var flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
+let flowEvent;if(event.ph==='s'){if(flowIdToEvent[event.id]){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' already seen when '+'encountering start of flow event.'});continue;}
 flowEvent=createFlowEvent(thread,event);if(!flowEvent){this.model_.importWarning({type:'flow_slice_start_error',message:'event id '+event.id+' does not start '+'at an actual slice, so cannot be created.'});continue;}
 flowIdToEvent[event.id]=flowEvent;}else if(event.ph==='t'||event.ph==='f'){flowEvent=flowIdToEvent[event.id];if(flowEvent===undefined){this.model_.importWarning({type:'flow_slice_ordering_error',message:'Found flow phase '+event.ph+' for id: '+event.id+' but no flow start found.'});continue;}
-var bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1){bindToParent=true;}else if(event.cat.indexOf('ipc.flow')>-1){bindToParent=true;}}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
+let bindToParent=event.ph==='t';if(event.ph==='f'){if(event.bp===undefined){if(event.cat.indexOf('input')>-1){bindToParent=true;}else if(event.cat.indexOf('ipc.flow')>-1){bindToParent=true;}}else{if(event.bp!=='e'){this.model_.importWarning({type:'flow_slice_bind_point_error',message:'Flow event with invalid binding point (event.bp).'});continue;}
 bindToParent=true;}}
-var ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
-flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_:function(){if(this.allObjectEvents_.length===0)return;var processEvent=function(objectEventState){var event=objectEventState.event;var scopedId=TraceEventImporter.scopedIdForEvent_(event);var thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
+const ok=finishFlowEventWith(flowEvent,thread,event,refGuid,bindToParent);if(ok){this.model_.flowEvents.push(flowEvent);}else{this.model_.importWarning({type:'flow_slice_end_error',message:'event id '+event.id+' does not end '+'at an actual slice, so cannot be created.'});}
+flowIdToEvent[event.id]=undefined;if(ok&&event.ph==='t'){flowEvent=createFlowEvent(thread,event);flowIdToEvent[event.id]=flowEvent;}}}},createExplicitObjects_(){if(this.allObjectEvents_.length===0)return;const processEvent=function(objectEventState){const event=objectEventState.event;const scopedId=TraceEventImporter.scopedIdForEvent_(event);const thread=objectEventState.thread;if(event.name===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an name parameter.'});}
 if(scopedId===undefined||scopedId.id===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+JSON.stringify(event)+': '+'Object events require an id parameter.'});}
-var process=thread.parent;var ts=this.toModelTimeFromUs_(event.ts);var instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
+const process=thread.parent;const ts=this.toModelTimeFromUs_(event.ts);let instance;if(event.ph==='N'){try{instance=process.objects.idWasCreated(scopedId,event.cat,event.name,ts);}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing create of '+
 scopedId+' at ts='+ts+': '+e});return;}}else if(event.ph==='O'){if(event.args.snapshot===undefined){this.model_.importWarning({type:'object_parse_error',message:'While processing '+scopedId+' at ts='+ts+': '+'Snapshots must have args: {snapshot: ...}'});return;}
-var snapshot;try{var args=this.deepCopyIfNeeded_(event.args.snapshot);var cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
-var baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
+let snapshot;try{const args=this.deepCopyIfNeeded_(event.args.snapshot);let cat;if(args.cat){cat=args.cat;delete args.cat;}else{cat=event.cat;}
+let baseTypename;if(args.base_type){baseTypename=args.base_type;delete args.base_type;}else{baseTypename=undefined;}
 snapshot=process.objects.addSnapshot(scopedId,cat,event.name,ts,args,baseTypename);snapshot.snapshottedOnThread=thread;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing snapshot of '+
 scopedId+' at ts='+ts+': '+e});return;}
-instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);var instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
+instance=snapshot.objectInstance;}else if(event.ph==='D'){try{process.objects.idWasDeleted(scopedId,event.cat,event.name,ts);const instanceMap=process.objects.getOrCreateInstanceMap_(scopedId);instance=instanceMap.lastInstance;}catch(e){this.model_.importWarning({type:'object_parse_error',message:'While processing delete of '+
 scopedId+' at ts='+ts+': '+e});return;}}
-if(instance){instance.colorId=getEventColor(event,instance.typeName);}}.bind(this);this.allObjectEvents_.sort(function(x,y){var d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});var allObjectEvents=this.allObjectEvents_;for(var i=0;i<allObjectEvents.length;i++){var objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_:function(){for(var proc of Object.values(this.model_.processes)){this.createImplicitObjectsForProcess_(proc);}},createImplicitObjectsForProcess_:function(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)return;if(referencingObjectFieldValue instanceof
+if(instance){instance.colorId=getEventColor(event,instance.typeName);}}.bind(this);this.allObjectEvents_.sort(function(x,y){const d=x.event.ts-y.event.ts;if(d!==0)return d;return x.sequenceNumber-y.sequenceNumber;});const allObjectEvents=this.allObjectEvents_;for(let i=0;i<allObjectEvents.length;i++){const objectEventState=allObjectEvents[i];try{processEvent.call(this,objectEventState);}catch(e){this.model_.importWarning({type:'object_parse_error',message:e.message});}}},createImplicitObjects_(){for(const proc of Object.values(this.model_.processes)){this.createImplicitObjectsForProcess_(proc);}},createImplicitObjectsForProcess_(process){function processField(referencingObject,referencingObjectFieldName,referencingObjectFieldValue,containingSnapshot){if(!referencingObjectFieldValue)return;if(referencingObjectFieldValue instanceof
 tr.model.ObjectSnapshot){return null;}
-if(referencingObjectFieldValue.id===undefined)return;var implicitSnapshot=referencingObjectFieldValue;var rawId=implicitSnapshot.id;var m=/(.+)\/(.+)/.exec(rawId);if(!m){throw new Error('Implicit snapshots must have names.');}
-delete implicitSnapshot.id;var name=m[1];var id=m[2];var res;var cat;if(implicitSnapshot.cat!==undefined){cat=implicitSnapshot.cat;}else{cat=containingSnapshot.objectInstance.category;}
-var baseTypename;if(implicitSnapshot.base_type){baseTypename=implicitSnapshot.base_type;}else{baseTypename=undefined;}
-var scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
+if(referencingObjectFieldValue.id===undefined)return;const implicitSnapshot=referencingObjectFieldValue;const rawId=implicitSnapshot.id;const m=/(.+)\/(.+)/.exec(rawId);if(!m){throw new Error('Implicit snapshots must have names.');}
+delete implicitSnapshot.id;const name=m[1];const id=m[2];let res;let cat;if(implicitSnapshot.cat!==undefined){cat=implicitSnapshot.cat;}else{cat=containingSnapshot.objectInstance.category;}
+let baseTypename;if(implicitSnapshot.base_type){baseTypename=implicitSnapshot.base_type;}else{baseTypename=undefined;}
+const scope=containingSnapshot.objectInstance.scopedId.scope;try{res=process.objects.addSnapshot(new tr.model.ScopedId(scope,id),cat,name,containingSnapshot.ts,implicitSnapshot,baseTypename);}catch(e){this.model_.importWarning({type:'object_snapshot_parse_error',message:'While processing implicit snapshot of '+
 rawId+' at ts='+containingSnapshot.ts+': '+e});return;}
 res.objectInstance.hasImplicitSnapshots=true;res.containingSnapshot=containingSnapshot;res.snapshottedOnThread=containingSnapshot.snapshottedOnThread;referencingObject[referencingObjectFieldName]=res;if(!(res instanceof tr.model.ObjectSnapshot)){throw new Error('Created object must be instanceof snapshot');}
 return res.args;}
-function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))return;if(object instanceof Array){for(var i=0;i<object.length;i++){var res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[i],func,containingSnapshot,thisArg);}}
+function iterObject(object,func,containingSnapshot,thisArg){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){const res=func.call(thisArg,object,i,object[i],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[i],func,containingSnapshot,thisArg);}}
 return;}
-for(var key in object){var res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[key],func,containingSnapshot,thisArg);}}}
+for(const key in object){const res=func.call(thisArg,object,key,object[key],containingSnapshot);if(res===null)continue;if(res){iterObject(res,func,containingSnapshot,thisArg);}else{iterObject(object[key],func,containingSnapshot,thisArg);}}}
 process.objects.iterObjectInstances(function(instance){instance.snapshots.forEach(function(snapshot){if(snapshot.args.id!==undefined){throw new Error('args cannot have an id field inside it');}
-iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_:function(){for(var dumpId in this.allMemoryDumpEvents_){this.createGlobalMemoryDump_(this.allMemoryDumpEvents_[dumpId],dumpId);}},createGlobalMemoryDump_:function(dumpIdEvents,dumpId){var globalRange=new tr.b.math.Range();for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++){globalRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}}
+iterObject(snapshot.args,processField,snapshot,this);},this);},this);},createMemoryDumps_(){for(const dumpId in this.allMemoryDumpEvents_){this.createGlobalMemoryDump_(this.allMemoryDumpEvents_[dumpId],dumpId);}},createGlobalMemoryDump_(dumpIdEvents,dumpId){const globalRange=new tr.b.math.Range();for(const pid in dumpIdEvents){const processEvents=dumpIdEvents[pid];for(let i=0;i<processEvents.length;i++){globalRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}}
 if(globalRange.isEmpty){throw new Error('Internal error: Global memory dump without events');}
-var globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);var globalMemoryAllocatorDumpsByFullName={};var levelsOfDetail={};var allMemoryAllocatorDumpsByGuid={};for(var pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
-globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_:function(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){var processRange=new tr.b.math.Range();for(var i=0;i<processEvents.length;i++){processRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}
+const globalMemoryDump=new tr.model.GlobalMemoryDump(this.model_,globalRange.min);globalMemoryDump.duration=globalRange.range;this.model_.globalMemoryDumps.push(globalMemoryDump);const globalMemoryAllocatorDumpsByFullName={};const levelsOfDetail={};const allMemoryAllocatorDumpsByGuid={};for(const pid in dumpIdEvents){this.createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,dumpIdEvents[pid],pid,dumpId);}
+globalMemoryDump.levelOfDetail=levelsOfDetail.global;globalMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(globalMemoryAllocatorDumpsByFullName);this.parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId);},createProcessMemoryDump_(globalMemoryDump,globalMemoryAllocatorDumpsByFullName,levelsOfDetail,allMemoryAllocatorDumpsByGuid,processEvents,pid,dumpId){const processRange=new tr.b.math.Range();for(let i=0;i<processEvents.length;i++){processRange.addValue(this.toModelTimeFromUs_(processEvents[i].ts));}
 if(processRange.isEmpty){throw new Error('Internal error: Process memory dump without events');}
-var process=this.model_.getOrCreateProcess(pid);var processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;var processMemoryAllocatorDumpsByFullName={};for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
+const process=this.model_.getOrCreateProcess(pid);const processMemoryDump=new tr.model.ProcessMemoryDump(globalMemoryDump,process,processRange.min);processMemoryDump.duration=processRange.range;process.memoryDumps.push(processMemoryDump);globalMemoryDump.processMemoryDumps[pid]=processMemoryDump;const processMemoryAllocatorDumpsByFullName={};for(let i=0;i<processEvents.length;i++){const processEvent=processEvents[i];const dumps=processEvent.args.dumps;if(dumps===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'\'dumps\' field not found in a process memory dump'+' event for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
 this.parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId);this.parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId);this.parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId);}
 if(levelsOfDetail.process===undefined){levelsOfDetail.process=processMemoryDump.vmRegions?DETAILED:LIGHT;}
 if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'global',levelsOfDetail.process)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for global memory'+' dump (dump ID='+dumpId+').'});}
-processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_:function(processMemoryDump,dumps,pid,dumpId){var rawTotals=dumps.process_totals;if(rawTotals===undefined)return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var totals={};var platformSpecificTotals=undefined;for(var rawTotalName in rawTotals){var rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
+processMemoryDump.levelOfDetail=levelsOfDetail.process;delete levelsOfDetail.process;processMemoryDump.memoryAllocatorDumps=this.inferMemoryAllocatorDumpTree_(processMemoryAllocatorDumpsByFullName);},parseMemoryDumpTotals_(processMemoryDump,dumps,pid,dumpId){const rawTotals=dumps.process_totals;if(rawTotals===undefined)return;if(processMemoryDump.totals!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Process totals provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+const totals={};let platformSpecificTotals=undefined;for(const rawTotalName in rawTotals){const rawTotalValue=rawTotals[rawTotalName];if(rawTotalValue===undefined)continue;if(rawTotalName==='resident_set_bytes'){totals.residentBytes=parseInt(rawTotalValue,16);continue;}
 if(rawTotalName==='peak_resident_set_bytes'){totals.peakResidentBytes=parseInt(rawTotalValue,16);continue;}
 if(rawTotalName==='is_peak_rss_resetable'){totals.arePeakResidentBytesResettable=!!rawTotalValue;continue;}
 if(platformSpecificTotals===undefined){platformSpecificTotals={};totals.platformSpecific=platformSpecificTotals;}
 platformSpecificTotals[rawTotalName]=parseInt(rawTotalValue,16);}
 if(totals.peakResidentBytes===undefined&&totals.arePeakResidentBytesResettable!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field peak_resident_set_bytes found'+' but is_peak_rss_resetable not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
 if(totals.arePeakResidentBytesResettable!==undefined&&totals.peakResidentBytes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Optional field is_peak_rss_resetable found'+' but peak_resident_set_bytes not found in'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});}
-processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_:function(processMemoryDump,dumps,pid,dumpId){var rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)return;var rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var vmRegions=new Array(rawVmRegions.length);for(var i=0;i<rawVmRegions.length;i++){var rawVmRegion=rawVmRegions[i];var byteStats={};var rawByteStats=rawVmRegion.bs;for(var rawByteStatName in rawByteStats){var rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
+processMemoryDump.totals=totals;},parseMemoryDumpVmRegions_(processMemoryDump,dumps,pid,dumpId){const rawProcessMmaps=dumps.process_mmaps;if(rawProcessMmaps===undefined)return;const rawVmRegions=rawProcessMmaps.vm_regions;if(rawVmRegions===undefined)return;if(processMemoryDump.vmRegions!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'VM regions provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+const vmRegions=new Array(rawVmRegions.length);for(let i=0;i<rawVmRegions.length;i++){const rawVmRegion=rawVmRegions[i];const byteStats={};const rawByteStats=rawVmRegion.bs;for(const rawByteStatName in rawByteStats){const rawByteStatValue=rawByteStats[rawByteStatName];if(rawByteStatValue===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Byte stat \''+rawByteStatName+'\' of VM region '+
 i+' ('+rawVmRegion.mf+') in process memory dump for '+'PID='+pid+' and dump ID='+dumpId+' does not have a value.'});continue;}
-var byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
+const byteStatName=BYTE_STAT_NAME_MAP[rawByteStatName];if(byteStatName===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown byte stat name \''+rawByteStatName+'\' ('+
 rawByteStatValue+') of VM region '+i+' ('+
 rawVmRegion.mf+') in process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});continue;}
-byteStats[byteStatName]=parseInt(rawByteStatValue,16);}
+byteStats[byteStatName]=parseInt(rawByteStatValue,16);if(byteStatName==='proportionalResident'&&byteStats[byteStatName]===0){byteStats[byteStatName]=undefined;}}
 vmRegions[i]=new tr.model.VMRegion(parseInt(rawVmRegion.sa,16),parseInt(rawVmRegion.sz,16),rawVmRegion.pf,rawVmRegion.mf,byteStats);}
-processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_:function(processMemoryDump,dumps,pid,dumpId){var rawHeapDumps=dumps.heaps;if(rawHeapDumps===undefined)return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-var processTypeMap=this.objectTypeNameMap_[pid];if(processTypeMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
-var idPrefix='p'+pid+':';var heapDumps={};var importer=new HeapDumpTraceEventImporter(this.model_,processMemoryDump,processTypeMap,idPrefix,dumpId);for(var allocatorName in rawHeapDumps){var rawHeapDump=rawHeapDumps[allocatorName];var heapDump=importer.parseRawHeapDump(rawHeapDump,allocatorName);if(heapDump!==undefined&&heapDump.entries.length>0){heapDumps[allocatorName]=heapDump;}}
-if(Object.keys(heapDumps).length>0){processMemoryDump.heapDumps=heapDumps;}},parseMemoryDumpLevelOfDetail_:function(levelsOfDetail,dumps,pid,dumpId){var rawLevelOfDetail=dumps.level_of_detail;var level;switch(rawLevelOfDetail){case'background':level=BACKGROUND;break;case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
-if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_:function(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
+processMemoryDump.vmRegions=tr.model.VMRegionClassificationNode.fromRegions(vmRegions);},parseMemoryDumpHeapDumps_(processMemoryDump,dumps,pid,dumpId){const idPrefix='p'+pid+':';let importer;if(dumps.heaps){const processTypeMap=this.objectTypeNameMap_[pid];if(processTypeMap===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Missing mapping from object type IDs to names.'});}
+importer=new LegacyHeapDumpTraceEventImporter(this.model_,processMemoryDump,processTypeMap,idPrefix,dumpId,dumps.heaps);}else if(dumps.heaps_v2){const data=dumps.heaps_v2;this.heapProfileExpander=this.heapProfileExpander.expandData(data);this.addNewStackFramesFromExpander_(this.heapProfileExpander,idPrefix);importer=new HeapDumpTraceEventImporter(this.heapProfileExpander,this.model_.stackFrames,processMemoryDump,idPrefix,this.model_);}
+if(!importer)return;const heapDumps=importer.parse();if(!heapDumps)return;if(processMemoryDump.heapDumps!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Heap dumps provided multiple times for'+' process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(Object.keys(heapDumps).length>0){processMemoryDump.heapDumps=heapDumps;}},addNewStackFramesFromExpander_(expander,idPrefix){const nodeMap=expander.getNewMap('nodes');const newStackFrames={};for(const[id,stackFrame]of nodeMap.entries()){if(!this.model_.stackFrames[idPrefix+id]){newStackFrames[id]={id,name:expander.getString(stackFrame.name_sid),};if(stackFrame.parent)newStackFrames[id].parent=stackFrame.parent;}}
+this.importStackFrames_(newStackFrames,idPrefix);},parseMemoryDumpLevelOfDetail_(levelsOfDetail,dumps,pid,dumpId){const rawLevelOfDetail=dumps.level_of_detail;let level;switch(rawLevelOfDetail){case'background':level=BACKGROUND;break;case'light':level=LIGHT;break;case'detailed':level=DETAILED;break;case undefined:level=undefined;break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'unknown raw level of detail \''+rawLevelOfDetail+'\' of process memory dump for PID='+pid+' and dump ID='+dumpId+'.'});return;}
+if(!this.updateMemoryDumpLevelOfDetail_(levelsOfDetail,'process',level)){this.model_.importWarning({type:'memory_dump_parse_error',message:'diffent levels of detail provided for process memory'+' dump for PID='+pid+' (dump ID='+dumpId+').'});}},updateMemoryDumpLevelOfDetail_(levelsOfDetail,scope,level){if(!(scope in levelsOfDetail)||level===levelsOfDetail[scope]){levelsOfDetail[scope]=level;return true;}
 if(MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(level)>MEMORY_DUMP_LEVEL_OF_DETAIL_ORDER.indexOf(levelsOfDetail[scope])){levelsOfDetail[scope]=level;}
-return false;},parseMemoryDumpAllocatorDumps_:function(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){var rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)return;for(var fullName in rawAllocatorDumps){var rawAllocatorDump=rawAllocatorDumps[fullName];var guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
-var flags=rawAllocatorDump.flags||0;var isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);var containerMemoryDump;var dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
-var allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
+return false;},parseMemoryDumpAllocatorDumps_(processMemoryDump,globalMemoryDump,processMemoryAllocatorDumpsByFullName,globalMemoryAllocatorDumpsByFullName,allMemoryAllocatorDumpsByGuid,dumps,pid,dumpId){const rawAllocatorDumps=dumps.allocators;if(rawAllocatorDumps===undefined)return;for(let fullName in rawAllocatorDumps){const rawAllocatorDump=rawAllocatorDumps[fullName];const guid=rawAllocatorDump.guid;if(guid===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' for PID='+pid+' and dump ID='+dumpId+' does not have a GUID.'});}
+const flags=rawAllocatorDump.flags||0;const isWeakDump=!!(flags&WEAK_MEMORY_ALLOCATOR_DUMP_FLAG);let containerMemoryDump;let dstIndex;if(fullName.startsWith(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX)){fullName=fullName.substring(GLOBAL_MEMORY_ALLOCATOR_DUMP_PREFIX.length);containerMemoryDump=globalMemoryDump;dstIndex=globalMemoryAllocatorDumpsByFullName;}else{containerMemoryDump=processMemoryDump;dstIndex=processMemoryAllocatorDumpsByFullName;}
+let allocatorDump=allMemoryAllocatorDumpsByGuid[guid];if(allocatorDump===undefined){if(fullName in dstIndex){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple GUIDs provided for'+' memory allocator dump '+fullName+': '+
 dstIndex[fullName].guid+', '+guid+' (ignored) for'+' PID='+pid+' and dump ID='+dumpId+'.'});continue;}
 allocatorDump=new tr.model.MemoryAllocatorDump(containerMemoryDump,fullName,guid);allocatorDump.weak=isWeakDump;dstIndex[fullName]=allocatorDump;if(guid!==undefined){allMemoryAllocatorDumpsByGuid[guid]=allocatorDump;}}else{if(allocatorDump.containerMemoryDump!==containerMemoryDump){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
 dumpId+' dumped in different contexts.'});continue;}
@@ -5571,82 +5899,100 @@
 pid+' and dump ID='+dumpId+' has multiple names: '+
 allocatorDump.fullName+', '+fullName+' (ignored).'});continue;}
 if(!isWeakDump){allocatorDump.weak=false;}}
-var attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
-for(var attrName in attributes){var attrArgs=attributes[attrName];var attrType=attrArgs.type;var attrValue=attrArgs.value;switch(attrType){case'scalar':if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
+let attributes=rawAllocatorDump.attrs;if(attributes===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+' does not have attributes.'});attributes={};}
+for(const attrName in attributes){const attrArgs=attributes[attrName];const attrType=attrArgs.type;const attrValue=attrArgs.value;switch(attrType){case'scalar':{if(attrName in allocatorDump.numerics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for scalar attribute '+
 attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
 dumpId+'.'});break;}
-var unit=attrArgs.units==='bytes'?tr.b.Unit.byName.sizeInBytes_smallerIsBetter:tr.b.Unit.byName.unitlessNumber_smallerIsBetter;var value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.b.Scalar(unit,value));break;case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
+const unit=attrArgs.units==='bytes'?tr.b.Unit.byName.sizeInBytes_smallerIsBetter:tr.b.Unit.byName.unitlessNumber_smallerIsBetter;const value=parseInt(attrValue,16);allocatorDump.addNumeric(attrName,new tr.b.Scalar(unit,value));break;}
+case'string':if(attrName in allocatorDump.diagnostics){this.model_.importWarning({type:'memory_dump_parse_error',message:'Multiple values provided for string attribute '+
 attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+
 dumpId+'.'});break;}
 allocatorDump.addDiagnostic(attrName,attrValue);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Unknown type provided for attribute '+attrName+' of memory allocator dump '+fullName+' (GUID='+guid+') for PID='+pid+' and dump ID='+dumpId+': '+
-attrType});break;}}}},inferMemoryAllocatorDumpTree_:function(memoryAllocatorDumpsByFullName){var rootAllocatorDumps=[];var fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(var i=0;i<fullNames.length;i++){var fullName=fullNames[i];var allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){var lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
-var parentFullName=fullName.substring(0,lastSlashIndex);var parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];var parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
+attrType});break;}}}},inferMemoryAllocatorDumpTree_(memoryAllocatorDumpsByFullName){const rootAllocatorDumps=[];const fullNames=Object.keys(memoryAllocatorDumpsByFullName);fullNames.sort();for(let i=0;i<fullNames.length;i++){let fullName=fullNames[i];let allocatorDump=memoryAllocatorDumpsByFullName[fullName];while(true){const lastSlashIndex=fullName.lastIndexOf('/');if(lastSlashIndex===-1){rootAllocatorDumps.push(allocatorDump);break;}
+const parentFullName=fullName.substring(0,lastSlashIndex);let parentAllocatorDump=memoryAllocatorDumpsByFullName[parentFullName];let parentAlreadyExisted=true;if(parentAllocatorDump===undefined){parentAlreadyExisted=false;parentAllocatorDump=new tr.model.MemoryAllocatorDump(allocatorDump.containerMemoryDump,parentFullName);if(allocatorDump.weak!==false){parentAllocatorDump.weak=undefined;}
 memoryAllocatorDumpsByFullName[parentFullName]=parentAllocatorDump;}
 allocatorDump.parent=parentAllocatorDump;parentAllocatorDump.children.push(allocatorDump);if(parentAlreadyExisted){if(!allocatorDump.weak){while(parentAllocatorDump!==undefined&&parentAllocatorDump.weak===undefined){parentAllocatorDump.weak=false;parentAllocatorDump=parentAllocatorDump.parent;}}
 break;}
 fullName=parentFullName;allocatorDump=parentAllocatorDump;}}
-for(var fullName in memoryAllocatorDumpsByFullName){var allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined){allocatorDump.weak=true;}}
-return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_:function(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(var pid in dumpIdEvents){var processEvents=dumpIdEvents[pid];for(var i=0;i<processEvents.length;i++){var processEvent=processEvents[i];var dumps=processEvent.args.dumps;if(dumps===undefined)continue;var rawEdges=dumps.allocators_graph;if(rawEdges===undefined)continue;for(var j=0;j<rawEdges.length;j++){var rawEdge=rawEdges[j];var sourceGuid=rawEdge.source;var sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
+for(const fullName in memoryAllocatorDumpsByFullName){const allocatorDump=memoryAllocatorDumpsByFullName[fullName];if(allocatorDump.weak===undefined){allocatorDump.weak=true;}}
+return rootAllocatorDumps;},parseMemoryDumpAllocatorEdges_(allMemoryAllocatorDumpsByGuid,dumpIdEvents,dumpId){for(const pid in dumpIdEvents){const processEvents=dumpIdEvents[pid];for(let i=0;i<processEvents.length;i++){const processEvent=processEvents[i];const dumps=processEvent.args.dumps;if(dumps===undefined)continue;const rawEdges=dumps.allocators_graph;if(rawEdges===undefined)continue;for(let j=0;j<rawEdges.length;j++){const rawEdge=rawEdges[j];const sourceGuid=rawEdge.source;const sourceDump=allMemoryAllocatorDumpsByGuid[sourceGuid];if(sourceDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing source memory allocator dump (GUID='+
 sourceGuid+').'});continue;}
-var targetGuid=rawEdge.target;var targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
+const targetGuid=rawEdge.target;const targetDump=allMemoryAllocatorDumpsByGuid[targetGuid];if(targetDump===undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Edge for PID='+pid+' and dump ID='+dumpId+' is missing target memory allocator dump (GUID='+
 targetGuid+').'});continue;}
-var importance=rawEdge.importance;var edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
+const importance=rawEdge.importance;const edge=new tr.model.MemoryAllocatorDumpLink(sourceDump,targetDump,importance);switch(rawEdge.type){case'ownership':if(sourceDump.owns!==undefined){this.model_.importWarning({type:'memory_dump_parse_error',message:'Memory allocator dump '+sourceDump.fullName+' (GUID='+sourceGuid+') already owns a memory'+' allocator dump ('+
 sourceDump.owns.target.fullName+').'});}else{sourceDump.owns=edge;targetDump.ownedBy.push(edge);}
-break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}},toModelTimeFromUs_:function(ts){if(!this.toModelTime_){this.toModelTime_=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);}
-return this.toModelTime_(tr.b.Unit.timestampFromUs(ts));},maybeToModelTimeFromUs_:function(ts){if(ts===undefined){return undefined;}
-return this.toModelTimeFromUs_(ts);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter,};});'use strict';tr.exportTo('tr.e.measure',function(){var AsyncSlice=tr.model.AsyncSlice;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';var matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
+break;case'retention':sourceDump.retains.push(edge);targetDump.retainedBy.push(edge);break;default:this.model_.importWarning({type:'memory_dump_parse_error',message:'Invalid edge type: '+rawEdge.type+' (PID='+pid+', dump ID='+dumpId+', source='+sourceGuid+', target='+targetGuid+', importance='+importance+').'});}}}}},toModelTimeFromUs_(ts){if(!this.toModelTime_){this.toModelTime_=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);}
+return this.toModelTime_(tr.b.Unit.timestampFromUs(ts));},maybeToModelTimeFromUs_(ts){if(ts===undefined){return undefined;}
+return this.toModelTimeFromUs_(ts);}};tr.importer.Importer.register(TraceEventImporter);return{TraceEventImporter,};});'use strict';tr.exportTo('tr.e.measure',function(){const AsyncSlice=tr.model.AsyncSlice;function MeasureAsyncSlice(){this.groupTitle_='Ungrouped Measure';const matched=/([^\/:]+):([^\/:]+)\/?(.*)/.exec(arguments[1]);if(matched!==null){arguments[1]=matched[2];this.groupTitle_=matched[1];}
 AsyncSlice.apply(this,arguments);}
-MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.subTypes.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MeasureAsyncSlice,};});'use strict';tr.exportTo('tr.e.net',function(){var AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
+MeasureAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return this.groupTitle_;},get title(){return this.title_;},set title(title){this.title_=title;}};AsyncSlice.subTypes.register(MeasureAsyncSlice,{categoryParts:['blink.user_timing']});return{MeasureAsyncSlice,};});'use strict';tr.exportTo('tr.e.net',function(){const AsyncSlice=tr.model.AsyncSlice;function NetAsyncSlice(){AsyncSlice.apply(this,arguments);this.url_=undefined;this.byteCount_=undefined;this.isTitleComputed_=false;this.isUrlComputed_=false;}
 NetAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){return'NetLog';},get title(){if(this.isTitleComputed_||!this.isTopLevel){return this.title_;}
 if(this.url!==undefined&&this.url.length>0){this.title_=this.url;}else if(this.args!==undefined&&this.args.source_type!==undefined){this.title_=this.args.source_type;}
 this.isTitleComputed_=true;return this.title_;},set title(title){this.title_=title;},get url(){if(this.isUrlComputed_){return this.url_;}
-if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(var i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined){this.url_=this.subSlices[i].url;}}}
+if(this.args!==undefined&&this.args.params!==undefined&&this.args.params.url!==undefined){this.url_=this.args.params.url;}else if(this.subSlices!==undefined&&this.subSlices.length>0){for(let i=0;i<this.subSlices.length&&!this.url_;i++){if(this.subSlices[i].url!==undefined){this.url_=this.subSlices[i].url;}}}
 this.isUrlComputed_=true;return this.url_;},get byteCount(){if(this.byteCount_!==undefined){return this.byteCount_;}
 this.byteCount_=0;if((this.originalTitle==='URL_REQUEST_JOB_FILTERED_BYTES_READ'||this.originalTitle==='URL_REQUEST_JOB_BYTES_READ')&&this.args!==undefined&&this.args.params!==undefined&&this.args.params.byte_count!==undefined){this.byteCount_=this.args.params.byte_count;}
-for(var i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
-return this.byteCount_;}};AsyncSlice.subTypes.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice,};});'use strict';tr.exportTo('tr.model',function(){var ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;}
-Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward:function(amount){this.start+=amount;},addBoundsToRange:function(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity,};});'use strict';tr.exportTo('tr.e.importer.android',function(){var Importer=tr.importer.Importer;var ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};var activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
-var eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');var amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');var amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');var amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');var amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');var amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
-if(/^<!DOCTYPE html>/.test(events))return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName:function(component){var componentSplit=component.split('/');if(componentSplit[1].startsWith('.')){return componentSplit[0]+componentSplit[1];}
-return componentSplit[1];},getProcName:function(component){var componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity:function(activityName){if(activityName in activityMap){return activityMap[activityName];}
-var activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity:function(activityName){delete activityMap[activityName];},handleCreateActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity:function(ts,procName,activityName){var activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled:function(ts,pid,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled:function(ts,activityName){var activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max){this.addActivityToProcess(activity);}},handleLaunchTime:function(ts,activityName,launchTime){var activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity:function(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess:function(activity){if(activity.pid===undefined)return;var process=this.model_.getOrCreateProcess(activity.pid);var range=tr.b.math.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);var newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_:function(line){var match=eventLogActivityRE.exec(line);if(!match)return;var firstRealtimeTs=this.model_.bounds.min-
-this.model_.realtime_to_monotonic_offset_ms;var year=new Date(firstRealtimeTs).getFullYear();var ts=match[1].substring(0,5)+'-'+year+' '+
-match[1].substring(5,match[1].length);var monotonicTs=Date.parse(ts)+
-this.model_.realtime_to_monotonic_offset_ms;var pid=match[2];var action=match[5];var data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonicTs,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2){this.handleOnResumeCalled(monotonicTs,pid,match[1]);}}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2){this.handleOnPauseCalled(monotonicTs,match[1]);}}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonicTs,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length===2){this.handleDestroyActivity(monotonicTs,this.getFullActivityName(match[1]));}}},importEvents:function(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
-this.model_.updateBounds();var lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(var activityName in activityMap){var activity=activityMap[activityName];if(activity.state===ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter,};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.model_=model;this.samples_=[];this.syncTimestampsById_=new Map();this.parseTrace_(events);}
-var battorDataLineRE=new RegExp('^(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');var battorHeaderLineRE=/^# BattOr/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
-return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importClockSyncMarkers:function(){for(var[syncId,ts]of this.syncTimestampsById_){this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.BATTOR,syncId,ts);}},importEvents:function(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
-var modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(tr.model.ClockDomainId.BATTOR);var powerSeries=this.model_.device.powerSeries=new tr.model.PowerSeries(this.model_.device);for(var i=0;i<this.samples_.length;i++){var sample=this.samples_[i];powerSeries.addPowerSample(modelTimeTransformer(sample.ts),sample.powerInW);}},parseTrace_:function(trace){var lines=trace.split('\n');for(var line of lines){line=line.trim();if(line.length===0)continue;if(line.startsWith('#'))continue;var groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line in BattOr trace: '+line});continue;}
-var ts=parseFloat(groups[1]);var voltageInV=tr.b.convertUnit(parseFloat(groups[2]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);var currentInA=tr.b.convertUnit(parseFloat(groups[3]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);var syncId=groups[4];if(syncId){this.syncTimestampsById_.set(syncId,ts);}
+for(let i=0;i<this.subSlices.length;i++){this.byteCount_+=this.subSlices[i].byteCount;}
+return this.byteCount_;}};AsyncSlice.subTypes.register(NetAsyncSlice,{categoryParts:['netlog','disabled-by-default-netlog']});return{NetAsyncSlice,};});'use strict';tr.exportTo('tr.model',function(){const ColorScheme=tr.b.ColorScheme;function Activity(name,category,range,args){tr.model.TimedEvent.call(this,range.min);this.title=name;this.category=category;this.colorId=ColorScheme.getColorIdForGeneralPurposeString(name);this.duration=range.duration;this.args=args;this.name=name;}
+Activity.prototype={__proto__:tr.model.TimedEvent.prototype,shiftTimestampsForward(amount){this.start+=amount;},addBoundsToRange(range){range.addValue(this.start);range.addValue(this.end);}};return{Activity,};});'use strict';tr.exportTo('tr.e.importer.android',function(){const Importer=tr.importer.Importer;const ACTIVITY_STATE={NONE:'none',CREATED:'created',STARTED:'started',RESUMED:'resumed',PAUSED:'paused',STOPPED:'stopped',DESTROYED:'destroyed'};const activityMap={};function EventLogImporter(model,events){this.model_=model;this.events_=events;this.importPriority=3;}
+const eventLogActivityRE=new RegExp('(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d+)'+'\\s+(\\d+)\\s+(\\d+)\\s+([A-Z])\\s*'+'(am_\\w+)\\s*:(.*)');const amCreateRE=new RegExp('\s*\\[.*,.*,.*,(.*),.*,.*,.*,.*\\]');const amFocusedRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amProcStartRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,.*,activity,(.*)\\]');const amOnResumeRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amOnPauseRE=new RegExp('\s*\\[\\d+,(.*)\\]');const amLaunchTimeRE=new RegExp('\s*\\[\\d+,\\d+,(.*),(\\d+),(\\d+)');const amDestroyRE=new RegExp('\s*\\[\\d+,\\d+,\\d+,(.*)\\]');EventLogImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(/^<!DOCTYPE html>/.test(events))return false;return eventLogActivityRE.test(events);};EventLogImporter.prototype={__proto__:Importer.prototype,get importerName(){return'EventLogImporter';},get model(){return this.model_;},getFullActivityName(component){const componentSplit=component.split('/');if(componentSplit[1].startsWith('.')){return componentSplit[0]+componentSplit[1];}
+return componentSplit[1];},getProcName(component){const componentSplit=component.split('/');return componentSplit[0];},findOrCreateActivity(activityName){if(activityName in activityMap){return activityMap[activityName];}
+const activity={state:ACTIVITY_STATE.NONE,name:activityName};activityMap[activityName]=activity;return activity;},deleteActivity(activityName){delete activityMap[activityName];},handleCreateActivity(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.CREATED;activity.createdTs=ts;},handleFocusActivity(ts,procName,activityName){const activity=this.findOrCreateActivity(activityName);activity.lastFocusedTs=ts;},handleProcStartForActivity(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.procStartTs=ts;},handleOnResumeCalled(ts,pid,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.RESUMED;activity.lastResumeTs=ts;activity.pid=pid;},handleOnPauseCalled(ts,activityName){const activity=this.findOrCreateActivity(activityName);activity.state=ACTIVITY_STATE.PAUSED;activity.lastPauseTs=ts;if(ts>this.model_.bounds.min&&ts<this.model_.bounds.max){this.addActivityToProcess(activity);}},handleLaunchTime(ts,activityName,launchTime){const activity=this.findOrCreateActivity(activityName);activity.launchTime=launchTime;},handleDestroyActivity(ts,activityName){this.deleteActivity(activityName);},addActivityToProcess(activity){if(activity.pid===undefined)return;const process=this.model_.getOrCreateProcess(activity.pid);const range=tr.b.math.Range.fromExplicitRange(Math.max(this.model_.bounds.min,activity.lastResumeTs),activity.lastPauseTs);const newActivity=new tr.model.Activity(activity.name,'Android Activity',range,{created:activity.createdTs,procstart:activity.procStartTs,lastfocus:activity.lastFocusedTs});process.activities.push(newActivity);},parseAmLine_(line){let match=eventLogActivityRE.exec(line);if(!match)return;const firstRealtimeTs=this.model_.bounds.min-
+this.model_.realtime_to_monotonic_offset_ms;const year=new Date(firstRealtimeTs).getFullYear();const ts=match[1].substring(0,5)+'-'+year+' '+
+match[1].substring(5,match[1].length);const monotonicTs=Date.parse(ts)+
+this.model_.realtime_to_monotonic_offset_ms;const pid=match[2];const action=match[5];const data=match[6];if(action==='am_create_activity'){match=amCreateRE.exec(data);if(match&&match.length>=2){this.handleCreateActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_focused_activity'){match=amFocusedRE.exec(data);if(match&&match.length>=2){this.handleFocusActivity(monotonicTs,this.getProcName(match[1]),this.getFullActivityName(match[1]));}}else if(action==='am_proc_start'){match=amProcStartRE.exec(data);if(match&&match.length>=2){this.handleProcStartForActivity(monotonicTs,this.getFullActivityName(match[1]));}}else if(action==='am_on_resume_called'){match=amOnResumeRE.exec(data);if(match&&match.length>=2){this.handleOnResumeCalled(monotonicTs,pid,match[1]);}}else if(action==='am_on_paused_called'){match=amOnPauseRE.exec(data);if(match&&match.length>=2){this.handleOnPauseCalled(monotonicTs,match[1]);}}else if(action==='am_activity_launch_time'){match=amLaunchTimeRE.exec(data);this.handleLaunchTime(monotonicTs,this.getFullActivityName(match[1]),match[2]);}else if(action==='am_destroy_activity'){match=amDestroyRE.exec(data);if(match&&match.length===2){this.handleDestroyActivity(monotonicTs,this.getFullActivityName(match[1]));}}},importEvents(){if(isNaN(this.model_.realtime_to_monotonic_offset_ms)){this.model_.importWarning({type:'eveng_log_clock_sync',message:'Need a trace_event_clock_sync to map realtime to import.'});return;}
+this.model_.updateBounds();const lines=this.events_.split('\n');lines.forEach(this.parseAmLine_,this);for(const activityName in activityMap){const activity=activityMap[activityName];if(activity.state===ACTIVITY_STATE.RESUMED){activity.lastPauseTs=this.model_.bounds.max;this.addActivityToProcess(activity);}}}};Importer.register(EventLogImporter);return{EventLogImporter,};});'use strict';tr.exportTo('tr.e.importer.android.process_data',function(){const Importer=tr.importer.Importer;const PROCESS_DUMP_HEADER='PROCESS DUMP';function ProcessDataImporter(model,processData){this.model_=model;this.processDataLines=processData.split('\n');this.importPriority=3;}
+ProcessDataImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(events.split('\n')[0]===PROCESS_DUMP_HEADER){return true;}
+return false;};ProcessDataImporter.prototype={__proto__:Importer.prototype,get importerName(){return'ProcessDataImporter';},get model(){return this.model_;},parseEventData(data){const allDumpedProcesses={};let parseProcesses=false;let parseThreads=false;let legacy=false;for(let i=1;i<data.length;i++){const cols=data[i].split(/\s+/);if(cols[0].startsWith('USER')){if(parseProcesses){parseProcesses=false;parseThreads=true;}else{parseThreads=false;parseProcesses=true;}
+const colCount=cols.length;if(parseProcesses&&colCount===9){legacy=false;}else if(parseProcesses&&colCount===8){legacy=true;}
+continue;}
+if(parseProcesses){const pid=Number(cols[1]);if(allDumpedProcesses[pid]===undefined){allDumpedProcesses[pid]={};}
+allDumpedProcesses[pid]={'name':cols[8],pid,'comm':cols[9]};continue;}
+if(parseThreads){let pid;let tid;let name;if(legacy){pid=Number(cols[1]);if(allDumpedProcesses[pid]!==undefined){tid=pid;}else{tid=pid;pid=Number(cols[2]);}
+name=cols.slice(8).join(' ');}else{pid=Number(cols[1]);tid=Number(cols[2]);name=cols.slice(3).join(' ');}
+if(allDumpedProcesses[pid]===undefined)continue;if(allDumpedProcesses[pid].threads===undefined){allDumpedProcesses[pid].threads={};}
+allDumpedProcesses[pid].threads[tid]={tid,name};continue;}}
+return allDumpedProcesses;},importEvents(){const allDumpedProcesses=this.parseEventData(this.processDataLines);const modelProcesses=this.model_.getAllProcesses();for(let i=0;i<modelProcesses.length;i++){const modelProcess=modelProcesses[i];const pid=modelProcess.pid;const dumpedProcess=allDumpedProcesses[pid];if(dumpedProcess===undefined){continue;}
+modelProcess.name=dumpedProcess.name;const processDumpThreads=dumpedProcess.threads;if(processDumpThreads!==undefined){for(const tid in modelProcess.threads){const modelThread=modelProcess.threads[tid];if(Number(pid)===Number(tid)){modelThread.name='UI thread';}else if(modelThread.name==='<...>'){if(processDumpThreads[tid]!==undefined){modelThread.name=processDumpThreads[tid].name;}}}}}}};Importer.register(ProcessDataImporter);return{ProcessDataImporter,};});'use strict';tr.exportTo('tr.e.importer.battor',function(){function BattorImporter(model,events){this.importPriority=3;this.model_=model;this.samples_=[];this.syncTimestampsById_=new Map();this.parseTrace_(events);}
+const battorDataLineRE=new RegExp('^(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)\\s+(-?\\d+\\.\\d+)'+'(?:\\s+<(\\S+)>)?$');const battorHeaderLineRE=/^# BattOr/;BattorImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+return battorHeaderLineRE.test(events);};BattorImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'BattorImporter';},get model(){return this.model_;},importClockSyncMarkers(){for(const[syncId,ts]of this.syncTimestampsById_){this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.BATTOR,syncId,ts);}},importEvents(){if(this.model_.device.powerSeries){this.model_.importWarning({type:'import_error',message:'Power counter exists, can not import BattOr power trace.'});return;}
+const modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(tr.model.ClockDomainId.BATTOR);const powerSeries=this.model_.device.powerSeries=new tr.model.PowerSeries(this.model_.device);for(let i=0;i<this.samples_.length;i++){const sample=this.samples_[i];powerSeries.addPowerSample(modelTimeTransformer(sample.ts),sample.powerInW);}},parseTrace_(trace){const lines=trace.split('\n');for(let line of lines){line=line.trim();if(line.length===0)continue;if(line.startsWith('#'))continue;const groups=battorDataLineRE.exec(line);if(!groups){this.model_.importWarning({type:'parse_error',message:'Unrecognized line in BattOr trace: '+line});continue;}
+const ts=parseFloat(groups[1]);const voltageInV=tr.b.convertUnit(parseFloat(groups[2]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const currentInA=tr.b.convertUnit(parseFloat(groups[3]),tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);const syncId=groups[4];if(syncId){this.syncTimestampsById_.set(syncId,ts);}
 if(voltageInV<0||currentInA<0){this.model_.importWarning({type:'parse_error',message:'The following line in the BattOr trace has a negative '+'voltage or current, neither of which are allowed: '+line+'. A common cause of this is that the device is charging '+'while the trace is being recorded.'});continue;}
 this.samples_.push(new Sample(ts,voltageInV,currentInA));}}};function Sample(ts,voltageInV,currentInA){this.ts=ts;this.voltageInV=voltageInV;this.currentInA=currentInA;}
-Sample.prototype={get powerInW(){return this.voltageInV*this.currentInA;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter,};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){var kPid=0;var kCategory='java';var kMethodLutEndMarker='\n*end\n';var kThreadsStart='\n*threads\n';var kMethodsStart='\n*methods\n';var kTraceMethodEnter=0x00;var kTraceMethodExit=0x01;var kTraceUnroll=0x02;var kTraceMethodActionMask=0x03;var kTraceHeaderLength=32;var kTraceMagicValue=0x574f4c53;var kTraceVersionSingleClock=2;var kTraceVersionDualClock=3;var kTraceRecordSizeSingleClock=10;var kTraceRecordSizeDualClock=14;function Reader(stringPayload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',stringPayload);}
-Reader.prototype={__proto__:Object.prototype,uint8:function(){var result=this.data_[this.position_];this.position_+=1;return result;},uint16:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32:function(){var result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64:function(){var low=this.uint32();var high=this.uint32();var lowStr=('0000000'+low.toString(16)).substr(-8);var highStr=('0000000'+high.toString(16)).substr(-8);var result=highStr+lowStr;return result;},seekTo:function(position){this.position_=position;},hasMore:function(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
-DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){var header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
-return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents:function(){var divider=this.data_.indexOf(kMethodLutEndMarker)+
-kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();var traceReader=new Reader(this.data_.slice(divider));var magic=traceReader.uint32();if(magic!==kTraceMagicValue){throw Error('Failed to match magic value');}
+Sample.prototype={get powerInW(){return this.voltageInV*this.currentInA;}};tr.importer.Importer.register(BattorImporter);return{BattorImporter,};});'use strict';tr.exportTo('tr.e.importer.ddms',function(){const kPid=0;const kCategory='java';const kMethodLutEndMarker='\n*end\n';const kThreadsStart='\n*threads\n';const kMethodsStart='\n*methods\n';const kTraceMethodEnter=0x00;const kTraceMethodExit=0x01;const kTraceUnroll=0x02;const kTraceMethodActionMask=0x03;const kTraceHeaderLength=32;const kTraceMagicValue=0x574f4c53;const kTraceVersionSingleClock=2;const kTraceVersionDualClock=3;const kTraceRecordSizeSingleClock=10;const kTraceRecordSizeDualClock=14;function Reader(stringPayload){this.position_=0;this.data_=JSZip.utils.transformTo('uint8array',stringPayload);}
+Reader.prototype={__proto__:Object.prototype,uint8(){const result=this.data_[this.position_];this.position_+=1;return result;},uint16(){let result=0;result+=this.uint8();result+=this.uint8()<<8;return result;},uint32(){let result=0;result+=this.uint8();result+=this.uint8()<<8;result+=this.uint8()<<16;result+=this.uint8()<<24;return result;},uint64(){const low=this.uint32();const high=this.uint32();const lowStr=('0000000'+low.toString(16)).substr(-8);const highStr=('0000000'+high.toString(16)).substr(-8);const result=highStr+lowStr;return result;},seekTo(position){this.position_=position;},hasMore(){return this.position_<this.data_.length;}};function DdmsImporter(model,data){this.importPriority=3;this.model_=model;this.data_=data;}
+DdmsImporter.canImport=function(data){if(typeof(data)==='string'||data instanceof String){const header=data.slice(0,1000);return header.startsWith('*version\n')&&header.indexOf('\nvm=')>=0&&header.indexOf(kThreadsStart)>=0;}
+return false;};DdmsImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'DdmsImporter';},get model(){return this.model_;},importEvents(){const divider=this.data_.indexOf(kMethodLutEndMarker)+
+kMethodLutEndMarker.length;this.metadata_=this.data_.slice(0,divider);this.methods_={};this.parseThreads();this.parseMethods();const traceReader=new Reader(this.data_.slice(divider));const magic=traceReader.uint32();if(magic!==kTraceMagicValue){throw Error('Failed to match magic value');}
 this.version_=traceReader.uint16();if(this.version_!==kTraceVersionDualClock){throw Error('Unknown version');}
-var dataOffest=traceReader.uint16();var startDateTime=traceReader.uint64();var recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry:function(reader){var tid=reader.uint16();var methodPacked=reader.uint32();var cpuSinceStart=reader.uint32();var wallClockSinceStart=reader.uint32();var method=methodPacked&~kTraceMethodActionMask;var action=methodPacked&kTraceMethodActionMask;var thread=this.getTid(tid);method=this.getMethodName(method);if(action===kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads:function(){var threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
-kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread:function(threadLine){var tid=threadLine.slice(0,threadLine.indexOf('\t'));var thread=this.getTid(parseInt(tid));thread.name=threadLine.slice(threadLine.indexOf('\t')+1);},getTid:function(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods:function(){var methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
-kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod:function(methodLine){var data=methodLine.split('\t');var methodId=parseInt(data[0]);var methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod:function(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName:function(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
-Parser.prototype={__proto__:Object.prototype};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-function parseArgs(argsString){var args={};if(argsString){var argsArray=argsString.split(';');for(var i=0;i<argsArray.length;++i){var parts=argsArray[i].split('=');if(parts[0]){args[parts.shift()]=parts.join('=');}}}
+const dataOffest=traceReader.uint16();const startDateTime=traceReader.uint64();const recordSize=traceReader.uint16();traceReader.seekTo(dataOffest);while(traceReader.hasMore()){this.parseTraceEntry(traceReader);}},parseTraceEntry(reader){const tid=reader.uint16();const methodPacked=reader.uint32();const cpuSinceStart=reader.uint32();const wallClockSinceStart=reader.uint32();let method=methodPacked&~kTraceMethodActionMask;const action=methodPacked&kTraceMethodActionMask;const thread=this.getTid(tid);method=this.getMethodName(method);if(action===kTraceMethodEnter){thread.sliceGroup.beginSlice(kCategory,method,wallClockSinceStart,undefined,cpuSinceStart);}else if(thread.sliceGroup.openSliceCount){thread.sliceGroup.endSlice(wallClockSinceStart,cpuSinceStart);}},parseThreads(){let threads=this.metadata_.slice(this.metadata_.indexOf(kThreadsStart)+
+kThreadsStart.length);threads=threads.slice(0,threads.indexOf('\n*'));threads=threads.split('\n');threads.forEach(this.parseThread.bind(this));},parseThread(threadLine){const tid=threadLine.slice(0,threadLine.indexOf('\t'));const thread=this.getTid(parseInt(tid));thread.name=threadLine.slice(threadLine.indexOf('\t')+1);},getTid(tid){return this.model_.getOrCreateProcess(kPid).getOrCreateThread(tid);},parseMethods(){let methods=this.metadata_.slice(this.metadata_.indexOf(kMethodsStart)+
+kMethodsStart.length);methods=methods.slice(0,methods.indexOf('\n*'));methods=methods.split('\n');methods.forEach(this.parseMethod.bind(this));},parseMethod(methodLine){const data=methodLine.split('\t');const methodId=parseInt(data[0]);const methodName=data[1]+'.'+data[2]+data[3];this.addMethod(methodId,methodName);},addMethod(methodId,methodName){this.methods_[methodId]=methodName;},getMethodName(methodId){return this.methods_[methodId];}};tr.importer.Importer.register(DdmsImporter);return{DdmsImporter,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){function Parser(importer){this.importer=importer;this.model=importer.model;}
+Parser.prototype={__proto__:Object.prototype};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.mandatoryBaseClass=Parser;tr.b.decorateExtensionRegistry(Parser,options);return{Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function AndroidParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));importer.registerEventHandler('0:android',AndroidParser.prototype.traceMarkWriteAndroidEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+function parseArgs(argsString){const args={};if(argsString){const argsArray=argsString.split(';');for(let i=0;i<argsArray.length;++i){const parts=argsArray[i].split('=');if(parts[0]){args[parts.shift()]=parts.join('=');}}}
 return args;}
-AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(thread,category,name,cookie,ts,args){var asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);var key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
-this.openAsyncSlices[key]=slice;},closeAsyncSlice:function(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
-var key=category+':'+name+':'+cookie;var slice=this.openAsyncSlices[key];if(!slice){return;}
-for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
+AndroidParser.prototype={__proto__:Parser.prototype,openAsyncSlice(thread,category,name,cookie,ts,args){const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);const slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts,args);const key=category+':'+name+':'+cookie;slice.id=cookie;slice.startThread=thread;if(!this.openAsyncSlices){this.openAsyncSlices={};}
+this.openAsyncSlices[key]=slice;},closeAsyncSlice(thread,category,name,cookie,ts,args){if(!this.openAsyncSlices){return;}
+const key=category+':'+name+':'+cookie;const slice=this.openAsyncSlices[key];if(!slice){return;}
+for(const arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the S and F events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the F event will be used.'});}
 slice.args[arg]=args[arg];}
-slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=eventBase.details.split('|');switch(eventData[0]){case'B':var ppid=parseInt(eventData[1]);var title=eventData[2];var args=parseArgs(eventData[3]);var category=eventData[4];if(category===undefined){category='android';}
-var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;case'E':var ppid=this.ppids_[pid];if(ppid===undefined){break;}
-var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
-var slice=thread.sliceGroup.endSlice(ts);var args=parseArgs(eventData[3]);for(var arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
+slice.endThread=thread;slice.duration=ts-slice.start;slice.startThread.asyncSliceGroup.push(slice);delete this.openAsyncSlices[key];},traceMarkWriteAndroidEvent(eventName,cpuNumber,pid,ts,eventBase){const eventData=eventBase.details.split('|');switch(eventData[0]){case'B':{const ppid=parseInt(eventData[1]);const title=eventData[2];const args=parseArgs(eventData[3]);let category=eventData[4];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;if(!thread.sliceGroup.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+this.ppids_[pid]=ppid;thread.sliceGroup.beginSlice(category,title,ts,args);break;}
+case'E':{const ppid=this.ppids_[pid];if(ppid===undefined){break;}
+const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);if(!thread.sliceGroup.openSliceCount){break;}
+const slice=thread.sliceGroup.endSlice(ts);const args=parseArgs(eventData[3]);for(const arg in args){if(slice.args[arg]!==undefined){this.model_.importWarning({type:'parse_error',message:'Both the B and E events of '+slice.title+' provided values for argument '+arg+'.'+' The value of the E event will be used.'});}
 slice.args[arg]=args[arg];}
-break;case'C':var ppid=parseInt(eventData[1]);var name=eventData[2];var value=parseInt(eventData[3]);var category=eventData[4];if(category===undefined)category='android';var ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;case'S':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;case'F':var ppid=parseInt(eventData[1]);var name=eventData[2];var cookie=parseInt(eventData[3]);var args=parseArgs(eventData[4]);var category=eventData[5];if(category===undefined)category='android';var thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;default:return false;}
-return true;}};Parser.register(AndroidParser);return{AndroidParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;var binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');var binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
-var TF_ONE_WAY=0x01;var TF_ROOT_OBJECT=0x04;var TF_STATUS_CODE=0x08;var TF_ACCEPT_FDS=0x10;var NO_FLAGS=0;function binderFlagsToHuman(num){var flag=parseInt(num,16);var str='';if(flag&TF_ONE_WAY){str+='this is a one-way call: async, no return; ';}
+break;}
+case'C':{const ppid=parseInt(eventData[1]);const name=eventData[2];const value=parseInt(eventData[3]);let category=eventData[4];if(category===undefined)category='android';const ctr=this.model_.getOrCreateProcess(ppid).getOrCreateCounter(category,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries(value,ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,value);});break;}
+case'S':{const ppid=parseInt(eventData[1]);const name=eventData[2];const cookie=parseInt(eventData[3]);const args=parseArgs(eventData[4]);let category=eventData[5];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.openAsyncSlice(thread,category,name,cookie,ts,args);break;}
+case'F':{const ppid=parseInt(eventData[1]);const name=eventData[2];const cookie=parseInt(eventData[3]);const args=parseArgs(eventData[4]);let category=eventData[5];if(category===undefined)category='android';const thread=this.model_.getOrCreateProcess(ppid).getOrCreateThread(pid);thread.name=eventBase.threadName;this.ppids_[pid]=ppid;this.closeAsyncSlice(thread,category,name,cookie,ts,args);break;}
+default:return false;}
+return true;}};Parser.register(AndroidParser);return{AndroidParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;const binderTransRE=new RegExp('transaction=(\\d+) dest_node=(\\d+) '+'dest_proc=(\\d+) dest_thread=(\\d+) '+'reply=(\\d+) flags=(0x[0-9a-fA-F]+) '+'code=(0x[0-9a-fA-F]+)');const binderTransReceivedRE=/transaction=(\d+)/;function isBinderThread(name){return(name.indexOf('Binder')>-1);}
+const TF_ONE_WAY=0x01;const TF_ROOT_OBJECT=0x04;const TF_STATUS_CODE=0x08;const TF_ACCEPT_FDS=0x10;const NO_FLAGS=0;function binderFlagsToHuman(num){const flag=parseInt(num,16);let str='';if(flag&TF_ONE_WAY){str+='this is a one-way call: async, no return; ';}
 if(flag&TF_ROOT_OBJECT){str+='contents are the components root object; ';}
 if(flag&TF_STATUS_CODE){str+='contents are a 32-bit status code; ';}
 if(flag&TF_ACCEPT_FDS){str+='allow replies with file descriptors; ';}
@@ -5655,275 +6001,255 @@
 function isReplyToOrigin(calling,called){return(called.dest_proc===calling.calling_pid||called.dest_thread===calling.calling_pid);}
 function binderCodeToHuman(code){return'Java Layer Dependent';}
 function doInternalSlice(trans,slice,ts){if(slice.subSlices.length!==0){slice.subSlices[0].start=ts;return slice.subSlices[0];}
-var kthread=trans.calling_kthread.thread;var internalSlice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internalSlice.title=slice.title;internalSlice.id=slice.id;internalSlice.colorId=slice.colorId;slice.subSlices.push(internalSlice);return internalSlice;}
+const kthread=trans.calling_kthread.thread;const internalSlice=kthread.sliceGroup.pushCompleteSlice('binder',slice.title,ts,.001,0,0,slice.args);internalSlice.title=slice.title;internalSlice.id=slice.id;internalSlice.colorId=slice.colorId;slice.subSlices.push(internalSlice);return internalSlice;}
 function generateBinderArgsForSlice(trans,cThreadName){return{'Transaction Id':trans.transaction_key,'Destination Node':trans.dest_node,'Destination Process':trans.dest_proc,'Destination Thread':trans.dest_thread,'Destination Name':cThreadName,'Reply transaction?':trans.is_reply_transaction,'Flags':trans.flags+' '+
 binderFlagsToHuman(trans.flags),'Code':trans.code+' '+
 binderCodeToHuman(trans.code),'Calling PID':trans.calling_pid,'Calling tgid':trans.calling_kthread.thread.parent.pid};}
 function BinderTransaction(events,callingPid,callingTs,callingKthread){this.transaction_key=parseInt(events[1]);this.dest_node=parseInt(events[2]);this.dest_proc=parseInt(events[3]);this.dest_thread=parseInt(events[4]);this.is_reply_transaction=parseInt(events[5])===1?true:false;this.expect_reply=((this.is_reply_transaction===false)&&(parseInt(events[6],16)&TF_ONE_WAY)===0);this.flags=events[6];this.code=events[7];this.calling_pid=callingPid;this.calling_ts=callingTs;this.calling_kthread=callingKthread;}
 function BinderParser(importer){Parser.call(this,importer);importer.registerEventHandler('binder_locked',BinderParser.prototype.binderLocked.bind(this));importer.registerEventHandler('binder_unlock',BinderParser.prototype.binderUnlock.bind(this));importer.registerEventHandler('binder_lock',BinderParser.prototype.binderLock.bind(this));importer.registerEventHandler('binder_transaction',BinderParser.prototype.binderTransaction.bind(this));importer.registerEventHandler('binder_transaction_received',BinderParser.prototype.binderTransactionReceived.bind(this));this.model_=importer.model;this.kthreadlookup={};this.importer_=importer;this.transWaitingRecv={};this.syncTransWaitingCompletion={};this.recursiveSyncTransWaitingCompletion_ByPID={};this.receivedTransWaitingConversion={};}
-BinderParser.prototype={__proto__:Parser.prototype,binderLock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventName.threadName);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked:function(eventName,cpuNumber,pid,ts,eventBase){var binderThread=isBinderThread(eventBase.threadName);var tgid;var name;var kthread;var rthread;tgid=parseInt(eventBase.tgid);name=eventBase.threadName;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)return false;var args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)return false;var args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransRE.exec(eventBase.details);if(event===undefined)return false;var tgid=parseInt(eventBase.tgid);this.doNameMappings(pid,tgid,eventBase.threadName);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var trans=new BinderTransaction(event,pid,ts,kthread);var args=generateBinderArgsForSlice(trans,eventBase.threadName);var priorReceive=this.getPriorReceiveOnPID(pid);if(priorReceive!==false){return this.modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event);}
-var recursiveTrans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursiveTrans!==false){return this.modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args);}
-var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply){slice.title='binder transaction';}else{slice.title='binder transaction async';}
-this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived:function(eventName,cpuNumber,pid,ts,eventBase){var event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)return false;var transactionkey=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread;kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);var syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){var syncTrans=syncComplete[0];var syncSlice=syncTrans.slice;var responseTrans=syncComplete[1];var responseSlice=responseTrans.slice;syncSlice.duration=ts-syncSlice.start;var syncInternal=doInternalSlice(syncTrans,syncSlice,ts);var responseTs=responseSlice.start+responseSlice.duration;var responseInternal=doInternalSlice(responseTrans,responseSlice,responseTs);if(responseSlice.outFlowEvents.length===0||syncSlice.inFlowEvents.length===0){var flow=this.generateFlow(responseInternal,syncInternal,responseTrans,syncTrans);syncSlice.inFlowEvents.push(flow);responseSlice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
-for(var i=1;i<syncSlice.inFlowEvents.length;i++){syncSlice.inFlowEvents[i].duration=ts-syncSlice.inFlowEvents[i].start;}
+BinderParser.prototype={__proto__:Parser.prototype,binderLock(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;this.doNameMappings(pid,tgid,eventName.threadName);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);kthread.binderAttemptLockTS=ts;kthread.binderOpenTsA=ts;return true;},binderLocked(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const binderThread=isBinderThread(eventBase.threadName);const name=eventBase.threadName;const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);this.doNameMappings(pid,tgid,name);const rthread=kthread.thread;kthread.binderLockAquiredTS=ts;if(kthread.binderAttemptLockTS===undefined)return false;const args=this.generateArgsForSlice(tgid,pid,name,kthread);rthread.sliceGroup.pushCompleteSlice('binder','binder lock waiting',kthread.binderAttemptLockTS,ts-kthread.binderAttemptLockTS,0,0,args);kthread.binderAttemptLockTS=undefined;return true;},binderUnlock(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);if(kthread.binderLockAquiredTS===undefined)return false;const args=this.generateArgsForSlice(tgid,pid,eventBase.threadName,kthread);kthread.thread.sliceGroup.pushCompleteSlice('binder','binder lock held',kthread.binderLockAquiredTS,ts-kthread.binderLockAquiredTS,0,0,args);kthread.binderLockAquiredTS=undefined;return true;},binderTransaction(eventName,cpuNumber,pid,ts,eventBase){const event=binderTransRE.exec(eventBase.details);if(event===undefined)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;this.doNameMappings(pid,tgid,eventBase.threadName);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const trans=new BinderTransaction(event,pid,ts,kthread);const args=generateBinderArgsForSlice(trans,eventBase.threadName);const priorReceive=this.getPriorReceiveOnPID(pid);if(priorReceive!==false){return this.modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event);}
+const recursiveTrans=this.getRecursiveTransactionNeedingCompletion(pid);if(recursiveTrans!==false){return this.modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args);}
+const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);slice.colorId=ColorScheme.getColorIdForGeneralPurposeString(ts.toString());trans.slice=slice;if(trans.expect_reply){slice.title='binder transaction';}else{slice.title='binder transaction async';}
+this.addTransactionWaitingForRecv(trans.transaction_key,trans);return true;},binderTransactionReceived(eventName,cpuNumber,pid,ts,eventBase){const event=binderTransReceivedRE.exec(eventBase.details);if(event===undefined)return false;const tgid=parseInt(eventBase.tgid);if(isNaN(tgid))return false;const transactionkey=parseInt(event[1]);const kthread=this.importer_.getOrCreateBinderKernelThread(eventBase.threadName,tgid,pid);const syncComplete=this.getSyncTransNeedsCompletion(transactionkey);if(syncComplete!==false){const syncTrans=syncComplete[0];const syncSlice=syncTrans.slice;const responseTrans=syncComplete[1];const responseSlice=responseTrans.slice;syncSlice.duration=ts-syncSlice.start;const syncInternal=doInternalSlice(syncTrans,syncSlice,ts);const responseTs=responseSlice.start+responseSlice.duration;const responseInternal=doInternalSlice(responseTrans,responseSlice,responseTs);if(responseSlice.outFlowEvents.length===0||syncSlice.inFlowEvents.length===0){const flow=this.generateFlow(responseInternal,syncInternal,responseTrans,syncTrans);syncSlice.inFlowEvents.push(flow);responseSlice.outFlowEvents.push(flow);this.model_.flowEvents.push(flow);}
+for(let i=1;i<syncSlice.inFlowEvents.length;i++){syncSlice.inFlowEvents[i].duration=ts-syncSlice.inFlowEvents[i].start;}
 return true;}
-var trForRecv=this.getTransactionWaitingForRecv(transactionkey);if(trForRecv!==false){if(!trForRecv.expect_reply){var args=generateBinderArgsForSlice(trForRecv,eventBase.threadName);var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);var fakeEvent=[0,0,0,0,0,0,0];var fakeTrans=new BinderTransaction(fakeEvent,pid,ts,kthread);var flow=this.generateFlow(trForRecv.slice,slice,trForRecv,fakeTrans);this.model_.flowEvents.push(flow);trForRecv.slice.title='binder transaction async';trForRecv.slice.duration=.03;return true;}
+const trForRecv=this.getTransactionWaitingForRecv(transactionkey);if(trForRecv!==false){if(!trForRecv.expect_reply){const args=generateBinderArgsForSlice(trForRecv,eventBase.threadName);const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder Async recv',ts,.03,0,0,args);const fakeEvent=[0,0,0,0,0,0,0];const fakeTrans=new BinderTransaction(fakeEvent,pid,ts,kthread);const flow=this.generateFlow(trForRecv.slice,slice,trForRecv,fakeTrans);this.model_.flowEvents.push(flow);trForRecv.slice.title='binder transaction async';trForRecv.slice.duration=.03;return true;}
 trForRecv.slice.title='binder transaction';this.setCurrentReceiveOnPID(pid,[ts,trForRecv]);return true;}
-return false;},modelRecursiveTransactions:function(recursiveTrans,ts,pid,kthread,trans,args){var recursiveSlice=recursiveTrans[1].slice;var origSlice=recursiveTrans[0].slice;recursiveSlice.duration=ts-recursiveSlice.start;trans.slice=recursiveSlice;if(trans.is_reply_transaction){origSlice.duration=ts-origSlice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursiveTrans);if(isReplyToOrigin(recursiveTrans[0],trans)){this.removeRecursiveTransaction(pid);}}else{var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
-return true;},modelPriorReceive:function(priorReceive,ts,pid,tgid,kthread,trans,args,event){var calleeSlice=priorReceive[1].slice;var calleeTrans=priorReceive[1];var recvTs=priorReceive[0];var slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recvTs,ts-recvTs,0,0,args);var flow=this.generateFlow(calleeSlice,slice,calleeTrans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[calleeTrans,trans]);}else{slice.title='binder reply';var trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recvTs,(ts-recvTs),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
+return false;},modelRecursiveTransactions(recursiveTrans,ts,pid,kthread,trans,args){const recursiveSlice=recursiveTrans[1].slice;const origSlice=recursiveTrans[0].slice;recursiveSlice.duration=ts-recursiveSlice.start;trans.slice=recursiveSlice;if(trans.is_reply_transaction){origSlice.duration=ts-origSlice.start;this.addSyncTransNeedingCompletion(trans.transaction_key,recursiveTrans);if(isReplyToOrigin(recursiveTrans[0],trans)){this.removeRecursiveTransaction(pid);}}else{const slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',ts,.03,0,0,args);trans.slice=slice;this.addTransactionWaitingForRecv(trans.transaction_key,trans);}
+return true;},modelPriorReceive(priorReceive,ts,pid,tgid,kthread,trans,args,event){const calleeSlice=priorReceive[1].slice;const calleeTrans=priorReceive[1];const recvTs=priorReceive[0];let slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','',recvTs,ts-recvTs,0,0,args);const flow=this.generateFlow(calleeSlice,slice,calleeTrans,trans);this.model_.flowEvents.push(flow);trans.slice=slice;if(trans.is_reply_transaction){slice.title='binder reply';this.addSyncTransNeedingCompletion(trans.transaction_key,[calleeTrans,trans]);}else{slice.title='binder reply';const trans1=new BinderTransaction(event,pid,ts,kthread);slice=kthread.thread.sliceGroup.pushCompleteSlice('binder','binder transaction',recvTs,(ts-recvTs),0,0,args);if(!trans.expect_reply){slice.title='binder transaction async';slice.duration=.03;}else{}
 trans1.slice=slice;this.addRecursiveSyncTransNeedingCompletion(pid,[calleeTrans,trans]);this.addTransactionWaitingForRecv(trans.transaction_key,trans1);}
-return true;},getRecursiveTransactionNeedingCompletion:function(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){return false;}
-var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion:function(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];}
-this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction:function(pid){var len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
-this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID:function(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
-this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID:function(pid){if(this.receivedTransWaitingConversion[pid]===undefined){return false;}
-var len=this.receivedTransWaitingConversion[pid].length;if(len===0)return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion:function(transactionkey,tuple){var dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion:function(transactionkey){var ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv:function(transactionkey){var ret=this.transWaitingRecv[transactionkey];if(ret===undefined)return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv:function(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow:function(from,to,fromTrans,toTrans){var title='Transaction from : '+
+return true;},getRecursiveTransactionNeedingCompletion(pid){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){return false;}
+const len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0)return false;return this.recursiveSyncTransWaitingCompletion_ByPID[pid][len-1];},addRecursiveSyncTransNeedingCompletion(pid,tuple){if(this.recursiveSyncTransWaitingCompletion_ByPID[pid]===undefined){this.recursiveSyncTransWaitingCompletion_ByPID[pid]=[];}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].push(tuple);},removeRecursiveTransaction(pid){const len=this.recursiveSyncTransWaitingCompletion_ByPID[pid].length;if(len===0){delete this.recursiveSyncTransWaitingCompletion_ByPID[pid];return;}
+this.recursiveSyncTransWaitingCompletion_ByPID[pid].splice(len-1,1);},setCurrentReceiveOnPID(pid,tuple){if(this.receivedTransWaitingConversion[pid]===undefined){this.receivedTransWaitingConversion[pid]=[];}
+this.receivedTransWaitingConversion[pid].push(tuple);},getPriorReceiveOnPID(pid){if(this.receivedTransWaitingConversion[pid]===undefined){return false;}
+const len=this.receivedTransWaitingConversion[pid].length;if(len===0)return false;return this.receivedTransWaitingConversion[pid].splice(len-1,1)[0];},addSyncTransNeedingCompletion(transactionkey,tuple){const dict=this.syncTransWaitingCompletion;dict[transactionkey]=tuple;},getSyncTransNeedsCompletion(transactionkey){const ret=this.syncTransWaitingCompletion[transactionkey];if(ret===undefined)return false;delete this.syncTransWaitingCompletion[transactionkey];return ret;},getTransactionWaitingForRecv(transactionkey){const ret=this.transWaitingRecv[transactionkey];if(ret===undefined)return false;delete this.transWaitingRecv[transactionkey];return ret;},addTransactionWaitingForRecv(transactionkey,transaction){this.transWaitingRecv[transactionkey]=transaction;},generateFlow(from,to,fromTrans,toTrans){const title='Transaction from : '+
 this.pid2name(fromTrans.calling_pid)+' From PID: '+fromTrans.calling_pid+' to pid: '+
-toTrans.calling_pid+' Thread Name: '+this.pid2name(toTrans.calling_pid);var ts=from.start;var flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice:function(tgid,pid,name,kthread){return{'Thread Name':name,'pid':pid,'gid':tgid};},pid2name:function(pid){return this.kthreadlookup[pid];},doNameMappings:function(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName:function(pid,name){if(this.pid2name(pid)===undefined){this.kthreadlookup[pid]=name;}}};Parser.register(BinderParser);return{BinderParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');var event=re.exec(eventBase.details);var name=event[1];var rwBytes=parseInt(event[2]);var rBytes=parseInt(event[3]);var wBytes=parseInt(event[4]);var cycles=parseInt(event[5]);var ns=parseInt(event[6]);var sec=tr.b.convertUnit(ns,tr.b.UnitPrefixScale.METRIC.NANO,tr.b.UnitPrefixScale.METRIC.NONE);var readBandwidthInBps=rBytes/sec;var readBandwidthInMiBps=tr.b.convertUnit(readBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);var writeBandwidthInBps=wBytes/sec;var writeBandwidthInMiBps=tr.b.convertUnit(writeBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);var ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+toTrans.calling_pid+' Thread Name: '+this.pid2name(toTrans.calling_pid);const ts=from.start;const flow=new tr.model.FlowEvent('binder','binder',title,1,ts,[]);flow.startSlice=from;flow.endSlice=to;flow.start=from.start;flow.duration=to.start-ts;from.outFlowEvents.push(flow);to.inFlowEvents.push(flow);return flow;},generateArgsForSlice(tgid,pid,name,kthread){return{'Thread Name':name,pid,'gid':tgid};},pid2name(pid){return this.kthreadlookup[pid];},doNameMappings(pid,tgid,name){this.registerPidName(pid,name);this.registerPidName(tgid,name);},registerPidName(pid,name){if(this.pid2name(pid)===undefined){this.kthreadlookup[pid]=name;}}};Parser.register(BinderParser);return{BinderParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function BusParser(importer){Parser.call(this,importer);importer.registerEventHandler('memory_bus_usage',BusParser.prototype.traceMarkWriteBusEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+BusParser.prototype={__proto__:Parser.prototype,traceMarkWriteBusEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const re=new RegExp('bus=(\\S+) rw_bytes=(\\d+) r_bytes=(\\d+) '+'w_bytes=(\\d+) cycles=(\\d+) ns=(\\d+)');const event=re.exec(eventBase.details);const name=event[1];const rwBytes=parseInt(event[2]);const rBytes=parseInt(event[3]);const wBytes=parseInt(event[4]);const cycles=parseInt(event[5]);const ns=parseInt(event[6]);const sec=tr.b.convertUnit(ns,tr.b.UnitPrefixScale.METRIC.NANO,tr.b.UnitPrefixScale.METRIC.NONE);const readBandwidthInBps=rBytes/sec;const readBandwidthInMiBps=tr.b.convertUnit(readBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);const writeBandwidthInBps=wBytes/sec;const writeBandwidthInMiBps=tr.b.convertUnit(writeBandwidthInBps,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI);let ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' read');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
 ctr.series.forEach(function(series){series.addCounterSample(ts,readBandwidthInMiBps);});ctr=this.model_.kernel.getOrCreateCounter(null,'bus '+name+' write');if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,writeBandwidthInMiBps);});return true;}};Parser.register(BusParser);return{BusParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent:function(eventName,cpuNumber,pid,ts,eventBase,threadName){var event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);var name=event[1];var rate=parseInt(event[2]);var ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
-ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
-function splitData(input){var data={};var args=input.split(/\s+/);var len=args.length;for(var i=0;i<len;i++){var item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
+ctr.series.forEach(function(series){series.addCounterSample(ts,writeBandwidthInMiBps);});return true;}};Parser.register(BusParser);return{BusParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function ClockParser(importer){Parser.call(this,importer);importer.registerEventHandler('clock_set_rate',ClockParser.prototype.traceMarkWriteClockEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+ClockParser.prototype={__proto__:Parser.prototype,traceMarkWriteClockEvent(eventName,cpuNumber,pid,ts,eventBase,threadName){const event=/(\S+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);const name=event[1];const rate=parseInt(event[2]);const ctr=this.model_.kernel.getOrCreateCounter(null,name);if(ctr.numSeries===0){ctr.addSeries(new tr.model.CounterSeries('value',ColorScheme.getColorIdForGeneralPurposeString(ctr.name+'.'+'value')));}
+ctr.series.forEach(function(series){series.addCounterSample(ts,rate);});return true;}};Parser.register(ClockParser);return{ClockParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function CpufreqParser(importer){Parser.call(this,importer);importer.registerEventHandler('cpufreq_interactive_up',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_down',CpufreqParser.prototype.cpufreqUpDownEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_already',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_notyet',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_setspeed',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_target',CpufreqParser.prototype.cpufreqTargetEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_boost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));importer.registerEventHandler('cpufreq_interactive_unboost',CpufreqParser.prototype.cpufreqBoostUnboostEvent.bind(this));}
+function splitData(input){const data={};const args=input.split(/\s+/);const len=args.length;for(let i=0;i<len;i++){const item=args[i].split('=');data[item[0]]=parseInt(item[1]);}
 return data;}
-CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice:function(ts,eventName,cpu,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent:function(eventName,cpuNumber,pid,ts,eventBase){var data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent:function(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
-DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice:function(ts,category,threadName,pid,key,name){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);var asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);var slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
-kthread.openAsyncSlices[key]=slice;},closeAsyncSlice:function(ts,category,threadName,pid,key,args){var kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){var slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4WriteBeginEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var pos=parseInt(event[3]);var len=parseInt(event[4]);var error=parseInt(event[5])!==len;var key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},f2fsSyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[5]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},ext4SyncFileEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var datasync=(event[4]==='1')||(event[4]===1);var key=device+'-'+inode;var action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)return false;var device=event[1];var inode=parseInt(event[2]);var error=parseInt(event[3]);var key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device:device,inode:inode,error:error});return true;},blockRqIssueEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)return false;var action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
+CpufreqParser.prototype={__proto__:Parser.prototype,cpufreqSlice(ts,eventName,cpu,args){const kthread=this.importer.getOrCreatePseudoThread('cpufreq');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqBoostSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('cpufreq_boost');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},cpufreqUpDownEvent(eventName,cpuNumber,pid,ts,eventBase){const data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqTargetEvent(eventName,cpuNumber,pid,ts,eventBase){const data=splitData(eventBase.details);this.cpufreqSlice(ts,eventName,data.cpu,data);return true;},cpufreqBoostUnboostEvent(eventName,cpuNumber,pid,ts,eventBase){this.cpufreqBoostSlice(ts,eventName,{type:eventBase.details});return true;}};Parser.register(CpufreqParser);return{CpufreqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DiskParser(importer){Parser.call(this,importer);importer.registerEventHandler('f2fs_write_begin',DiskParser.prototype.f2fsWriteBeginEvent.bind(this));importer.registerEventHandler('f2fs_write_end',DiskParser.prototype.f2fsWriteEndEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_enter',DiskParser.prototype.f2fsSyncFileEnterEvent.bind(this));importer.registerEventHandler('f2fs_sync_file_exit',DiskParser.prototype.f2fsSyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_sync_file_enter',DiskParser.prototype.ext4SyncFileEnterEvent.bind(this));importer.registerEventHandler('ext4_sync_file_exit',DiskParser.prototype.ext4SyncFileExitEvent.bind(this));importer.registerEventHandler('ext4_da_write_begin',DiskParser.prototype.ext4WriteBeginEvent.bind(this));importer.registerEventHandler('ext4_da_write_end',DiskParser.prototype.ext4WriteEndEvent.bind(this));importer.registerEventHandler('block_rq_issue',DiskParser.prototype.blockRqIssueEvent.bind(this));importer.registerEventHandler('block_rq_complete',DiskParser.prototype.blockRqCompleteEvent.bind(this));}
+DiskParser.prototype={__proto__:Parser.prototype,openAsyncSlice(ts,category,threadName,pid,key,name){const kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);const asyncSliceConstructor=tr.model.AsyncSlice.subTypes.getConstructor(category,name);const slice=new asyncSliceConstructor(category,name,ColorScheme.getColorIdForGeneralPurposeString(name),ts);slice.startThread=kthread.thread;if(!kthread.openAsyncSlices){kthread.openAsyncSlices={};}
+kthread.openAsyncSlices[key]=slice;},closeAsyncSlice(ts,category,threadName,pid,key,args){const kthread=this.importer.getOrCreateKernelThread(category+':'+threadName,pid);if(kthread.openAsyncSlices){const slice=kthread.openAsyncSlices[key];if(slice){slice.duration=ts-slice.start;slice.args=args;slice.endThread=kthread.thread;slice.subSlices=[new tr.model.AsyncSlice(category,slice.title,slice.colorId,slice.start,slice.args,slice.duration)];kthread.thread.asyncSliceGroup.push(slice);delete kthread.openAsyncSlices[key];}}},f2fsWriteBeginEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), flags = (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'f2fs_write');return true;},f2fsWriteEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev = \((\d+,\d+)\), ino = (\d+), pos = (\d+), len = (\d+), copied = (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const error=parseInt(event[5])!==len;const key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},ext4WriteBeginEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) flags (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const key=device+'-'+inode+'-'+pos+'-'+len;this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,'ext4_write');return true;},ext4WriteEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) pos (\d+) len (\d+) copied (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const pos=parseInt(event[3]);const len=parseInt(event[4]);const error=parseInt(event[5])!==len;const key=device+'-'+inode+'-'+pos+'-'+len;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},f2fsSyncFileEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), pino = (\\d+), i_mode = (\\S+), '+'i_size = (\\d+), i_nlink = (\\d+), i_blocks = (\\d+), i_advise = (\\d+)').exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const key=device+'-'+inode;this.openAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,'fsync');return true;},f2fsSyncFileExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('dev = \\((\\d+,\\d+)\\), ino = (\\d+), checkpoint is (\\S+), '+'datasync = (\\d+), ret = (\\d+)').exec(eventBase.details.replace('not needed','not_needed'));if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const error=parseInt(event[5]);const key=device+'-'+inode;this.closeAsyncSlice(ts,'f2fs',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},ext4SyncFileEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) parent (\d+) datasync (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const datasync=(event[4]==='1')||(event[4]===1);const key=device+'-'+inode;const action=datasync?'fdatasync':'fsync';this.openAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,action);return true;},ext4SyncFileExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev (\d+,\d+) ino (\d+) ret (\d+)/.exec(eventBase.details);if(!event)return false;const device=event[1];const inode=parseInt(event[2]);const error=parseInt(event[3]);const key=device+'-'+inode;this.closeAsyncSlice(ts,'ext4',eventBase.threadName,eventBase.pid,key,{device,inode,error});return true;},blockRqIssueEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\d+ \\(.*\\) (\\d+) \\+ (\\d+) \\[.*\\]').exec(eventBase.details);if(!event)return false;let action;switch(event[3]){case'D':action='discard';break;case'W':action='write';break;case'R':action='read';break;case'N':action='none';break;default:action='unknown';break;}
 if(event[2]){action+=' flush';}
 if(event[4]==='F'){action+=' fua';}
 if(event[5]==='A'){action+=' ahead';}
 if(event[6]==='S'){action+=' sync';}
 if(event[7]==='M'){action+=' meta';}
-var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)return false;var device=event[1];var sector=parseInt(event[8]);var numSectors=parseInt(event[9]);var error=parseInt(event[10]);var key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device:device,sector:sector,numSectors:numSectors,error:error});return true;}};Parser.register(DiskParser);return{DiskParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
-DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)return false;var crtc=parseInt(event[1]);var seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc:crtc,seq:seq});return true;}};Parser.register(DrmParser);return{DrmParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
-ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample:function(name,ts,frequency){var targetCpu=this.importer.getOrCreateCpu(0);var counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
-counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice:function(ts,pipe,fb,state){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice:function(ts,pipe,fb,args){var kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;},pageFlipStateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)return false;var pipe=parseInt(event[1]);var fb=parseInt(event[2]);var state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe:pipe,fb:fb});if(state!=='flipped'){this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);}
-return true;}};Parser.register(ExynosParser);return{ExynosParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
-GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice:function(title,ts,opt_args){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice:function(title,ts){var thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){var slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!==title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
+const device=event[1];const sector=parseInt(event[8]);const numSectors=parseInt(event[9]);const key=device+'-'+sector+'-'+numSectors;this.openAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,action);return true;},blockRqCompleteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=new RegExp('(\\d+,\\d+) (F)?([DWRN])(F)?(A)?(S)?(M)? '+'\\(.*\\) (\\d+) \\+ (\\d+) \\[(.*)\\]').exec(eventBase.details);if(!event)return false;const device=event[1];const sector=parseInt(event[8]);const numSectors=parseInt(event[9]);const error=parseInt(event[10]);const key=device+'-'+sector+'-'+numSectors;this.closeAsyncSlice(ts,'block',eventBase.threadName,eventBase.pid,key,{device,sector,numSectors,error});return true;}};Parser.register(DiskParser);return{DiskParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function DrmParser(importer){Parser.call(this,importer);importer.registerEventHandler('drm_vblank_event',DrmParser.prototype.vblankEvent.bind(this));}
+DrmParser.prototype={__proto__:Parser.prototype,drmVblankSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('drm_vblank');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},vblankEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/crtc=(\d+), seq=(\d+)/.exec(eventBase.details);if(!event)return false;const crtc=parseInt(event[1]);const seq=parseInt(event[2]);this.drmVblankSlice(ts,'vblank:'+crtc,{crtc,seq});return true;}};Parser.register(DrmParser);return{DrmParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function ExynosParser(importer){Parser.call(this,importer);importer.registerEventHandler('exynos_busfreq_target_int',ExynosParser.prototype.busfreqTargetIntEvent.bind(this));importer.registerEventHandler('exynos_busfreq_target_mif',ExynosParser.prototype.busfreqTargetMifEvent.bind(this));importer.registerEventHandler('exynos_page_flip_state',ExynosParser.prototype.pageFlipStateEvent.bind(this));}
+ExynosParser.prototype={__proto__:Parser.prototype,exynosBusfreqSample(name,ts,frequency){const targetCpu=this.importer.getOrCreateCpu(0);const counter=targetCpu.getOrCreateCounter('',name);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries('frequency',ColorScheme.getColorIdForGeneralPurposeString(counter.name+'.'+'frequency')));}
+counter.series.forEach(function(series){series.addCounterSample(ts,frequency);});},busfreqTargetIntEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('INT Frequency',ts,parseInt(event[1]));return true;},busfreqTargetMifEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.exynosBusfreqSample('MIF Frequency',ts,parseInt(event[1]));return true;},exynosPageFlipStateOpenSlice(ts,pipe,fb,state){const kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');kthread.openSliceTS=ts;kthread.openSlice=state;},exynosPageFlipStateCloseSlice(ts,pipe,fb,args){const kthread=this.importer.getOrCreatePseudoThread('exynos_flip_state (pipe:'+pipe+', fb:'+fb+')');if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},pageFlipStateEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/pipe=(\d+), fb=(\d+), state=(.*)/.exec(eventBase.details);if(!event)return false;const pipe=parseInt(event[1]);const fb=parseInt(event[2]);const state=event[3];this.exynosPageFlipStateCloseSlice(ts,pipe,fb,{pipe,fb});if(state!=='flipped'){this.exynosPageFlipStateOpenSlice(ts,pipe,fb,state);}
+return true;}};Parser.register(ExynosParser);return{ExynosParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function GestureParser(importer){Parser.call(this,importer);importer.registerEventHandler('tracing_mark_write:log',GestureParser.prototype.logEvent.bind(this));importer.registerEventHandler('tracing_mark_write:SyncInterpret',GestureParser.prototype.syncEvent.bind(this));importer.registerEventHandler('tracing_mark_write:HandleTimer',GestureParser.prototype.timerEvent.bind(this));}
+GestureParser.prototype={__proto__:Parser.prototype,gestureOpenSlice(title,ts,opt_args){const thread=this.importer.getOrCreatePseudoThread('gesture').thread;thread.sliceGroup.beginSlice('touchpad_gesture',title,ts,opt_args);},gestureCloseSlice(title,ts){const thread=this.importer.getOrCreatePseudoThread('gesture').thread;if(thread.sliceGroup.openSliceCount){const slice=thread.sliceGroup.mostRecentlyOpenedPartialSlice;if(slice.title!==title){this.importer.model.importWarning({type:'title_match_error',message:'Titles do not match. Title is '+
 slice.title+' in openSlice, and is '+
-title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
-return true;},syncEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
-return true;},timerEvent:function(eventName,cpuNumber,pid,ts,eventBase){var innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
-return true;}};Parser.register(GestureParser);return{GestureParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function I2cParser(importer){Parser.call(this,importer);importer.registerEventHandler('i2c_write',I2cParser.prototype.i2cWriteEvent.bind(this));importer.registerEventHandler('i2c_read',I2cParser.prototype.i2cReadEvent.bind(this));importer.registerEventHandler('i2c_reply',I2cParser.prototype.i2cReplyEvent.bind(this));importer.registerEventHandler('i2c_result',I2cParser.prototype.i2cResultEvent.bind(this));}
-var i2cWriteReplyRE=new RegExp('i2c-(\\d+) #(\\d+) a=([\\da-fA-F]+) f=([\\da-fA-F]+) l=(\\d+) '+'(\\[[\\da-fA-F\\-]+\\])');var i2cReadRE=/i2c-(\d+) #(\d+) a=([\da-fA-F]+) f=([\da-fA-F]+) l=(\d+)/;var i2cResultRE=/i2c-(\d+) n=(\d+) ret=(\d+)/;I2cParser.prototype={__proto__:Parser.prototype,i2cWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;var adapterNumber=parseInt(event[1]);var messageNumber=event[2];var address=event[3];var flags=event[4];var dataLength=event[5];var data=event[6];var thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c write';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cReadEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=i2cReadRE.exec(eventBase.details);if(!event)return false;var adapterNumber=parseInt(event[1]);var messageNumber=event[2];var address=event[3];var flags=event[4];var dataLength=event[5];var thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c read';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength};return true;},i2cReplyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;var adapterNumber=parseInt(event[1]);var messageNumber=event[2];var address=event[3];var flags=event[4];var dataLength=event[5];var data=event[6];var thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c reply';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cResultEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=i2cResultRE.exec(eventBase.details);if(!event)return false;var adapterNumber=parseInt(event[1]);var numMessages=event[2];var ret=event[3];var thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);var args=thread.lastEntryArgs;if(args!==undefined){args['Number of messages']=numMessages;args['Return']=ret;}
-pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle=undefined;thread.lastEntryTs=undefined;thread.lastEntryArgs=undefined;return true;},};function pushLastSliceIfNeeded(thread,id,currentTs){if(thread.lastEntryTs!==undefined){var duration=currentTs-thread.lastEntryTs;var slice=new tr.model.ThreadSlice('',thread.lastEntryTitle,ColorScheme.getColorIdForGeneralPurposeString(id),thread.lastEntryTs,thread.lastEntryArgs,duration);thread.thread.sliceGroup.pushSlice(slice);}}
-Parser.register(I2cParser);return{I2cParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
-I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice:function(ts,obj,plane){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice:function(ts,args){var kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;},i915GemObjectSlice:function(ts,eventName,obj,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice:function(ts,eventName,dev,ring,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice:function(ts,eventName,reg,args){var kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice:function(ts,eventName,args){var kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;var obj=event[1];var size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,size:size});return true;},gemObjectBindEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;var obj=event[1];var offset=event[2];var size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj:obj,offset:offset,size:size});return true;},gemObjectChangeDomainEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)return false;var obj=event[1];var read=event[2];var write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,read:read,write:write});return true;},gemObjectPreadWriteEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)return false;var obj=event[1];var offset=parseInt(event[2]);var len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,offset:offset,len:len});return true;},gemObjectFaultEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)return false;var obj=event[1];var type=event[2];var index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj:obj,type:type,index:index});return true;},gemObjectDestroyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/obj=(\w+)/.exec(eventBase.details);if(!event)return false;var obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj:obj});return true;},gemRingDispatchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingFlushEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var invalidate=event[3];var flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,invalidate:invalidate,flush:flush});return true;},gemRequestEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);var seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring,seqno:seqno});return true;},gemRingWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)return false;var dev=parseInt(event[1]);var ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev:dev,ring:ring});return true;},regRWEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)return false;var rw=event[1];var reg=event[2];var len=event[3];var data=event[3];this.i915RegSlice(ts,rw,reg,{rw:rw,reg:reg,len:len,data:data});return true;},flipEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)return false;var plane=parseInt(event[1]);var obj=event[2];if(eventName==='i915_flip_request'){this.i915FlipOpenSlice(ts,obj,plane);}else{this.i915FlipCloseSlice(ts,{obj:obj,plane:plane});}
-return true;},gpuFrequency:function(eventName,cpuNumver,pid,ts,eventBase){var event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)return false;var freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq:freq});return true;}};Parser.register(I915Parser);return{I915Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
-var irqHandlerEntryRE=/irq=(\d+) name=(.+)/;var irqHandlerExitRE=/irq=(\d+) ret=(.+)/;var softirqRE=/vec=(\d+) \[action=(.+)\]/;var ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerEntryRE.exec(eventBase.details);if(!event)return false;var irq=parseInt(event[1]);var name=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=irqHandlerExitRE.exec(eventBase.details);if(!event)return false;var irq=parseInt(event[1]);var ret=event[2];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.ThreadSlice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret:ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent:function(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)return false;var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=softirqRE.exec(eventBase.details);if(!event)return false;var vec=parseInt(event[1]);var action=event[2];var thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.ThreadSlice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec:vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;return true;},ipiEntryEvent:function(eventName,cpuNumber,pid,ts,eventBase){var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=ipiHandlerExitRE.exec(eventBase.details);if(!event)return false;var ipiName=event[1];var thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){var duration=ts-thread.lastEntryTs;var slice=new tr.model.ThreadSlice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
-var TestExports={};var funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent:function(eventName,cpuNumber,pid,ts,eventBase){var eventData=funcEnterRE.exec(eventBase.details);if(!eventData)return false;if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var name=eventData[1];var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-var slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+title+' in endSlice'});}else{thread.sliceGroup.endSlice(ts);}}},logEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('GestureLog',ts,{name:innerEvent[2]});break;case'end':this.gestureCloseSlice('GestureLog',ts);}
+return true;},syncEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('SyncInterpret',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('SyncInterpret',ts);}
+return true;},timerEvent(eventName,cpuNumber,pid,ts,eventBase){const innerEvent=/^\s*(\w+):\s*(\w+)$/.exec(eventBase.details);switch(innerEvent[1]){case'start':this.gestureOpenSlice('HandleTimer',ts,{interpreter:innerEvent[2]});break;case'end':this.gestureCloseSlice('HandleTimer',ts);}
+return true;}};Parser.register(GestureParser);return{GestureParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function I2cParser(importer){Parser.call(this,importer);importer.registerEventHandler('i2c_write',I2cParser.prototype.i2cWriteEvent.bind(this));importer.registerEventHandler('i2c_read',I2cParser.prototype.i2cReadEvent.bind(this));importer.registerEventHandler('i2c_reply',I2cParser.prototype.i2cReplyEvent.bind(this));importer.registerEventHandler('i2c_result',I2cParser.prototype.i2cResultEvent.bind(this));}
+const i2cWriteReplyRE=new RegExp('i2c-(\\d+) #(\\d+) a=([\\da-fA-F]+) f=([\\da-fA-F]+) l=(\\d+) '+'(\\[[\\da-fA-F\\-]+\\])');const i2cReadRE=/i2c-(\d+) #(\d+) a=([\da-fA-F]+) f=([\da-fA-F]+) l=(\d+)/;const i2cResultRE=/i2c-(\d+) n=(\d+) ret=(\d+)/;I2cParser.prototype={__proto__:Parser.prototype,i2cWriteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const data=event[6];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c write';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cReadEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cReadRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c read';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength};return true;},i2cReplyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cWriteReplyRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const messageNumber=event[2];const address=event[3];const flags=event[4];const dataLength=event[5];const data=event[6];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle='i2c reply';thread.lastEntryTs=ts;thread.lastEntryArgs={'Message number':messageNumber,'Address':address,'Flags':flags,'Data Length':dataLength,'Data':data};return true;},i2cResultEvent(eventName,cpuNumber,pid,ts,eventBase){const event=i2cResultRE.exec(eventBase.details);if(!event)return false;const adapterNumber=parseInt(event[1]);const numMessages=event[2];const ret=event[3];const thread=this.importer.getOrCreatePseudoThread('i2c adapter '+adapterNumber);const args=thread.lastEntryArgs;if(args!==undefined){args['Number of messages']=numMessages;args.Return=ret;}
+pushLastSliceIfNeeded(thread,event[1],ts);thread.lastEntryTitle=undefined;thread.lastEntryTs=undefined;thread.lastEntryArgs=undefined;return true;},};function pushLastSliceIfNeeded(thread,id,currentTs){if(thread.lastEntryTs!==undefined){const duration=currentTs-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',thread.lastEntryTitle,ColorScheme.getColorIdForGeneralPurposeString(id),thread.lastEntryTs,thread.lastEntryArgs,duration);thread.thread.sliceGroup.pushSlice(slice);}}
+Parser.register(I2cParser);return{I2cParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function I915Parser(importer){Parser.call(this,importer);importer.registerEventHandler('i915_gem_object_create',I915Parser.prototype.gemObjectCreateEvent.bind(this));importer.registerEventHandler('i915_gem_object_bind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_unbind',I915Parser.prototype.gemObjectBindEvent.bind(this));importer.registerEventHandler('i915_gem_object_change_domain',I915Parser.prototype.gemObjectChangeDomainEvent.bind(this));importer.registerEventHandler('i915_gem_object_pread',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_pwrite',I915Parser.prototype.gemObjectPreadWriteEvent.bind(this));importer.registerEventHandler('i915_gem_object_fault',I915Parser.prototype.gemObjectFaultEvent.bind(this));importer.registerEventHandler('i915_gem_object_clflush',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_object_destroy',I915Parser.prototype.gemObjectDestroyEvent.bind(this));importer.registerEventHandler('i915_gem_ring_dispatch',I915Parser.prototype.gemRingDispatchEvent.bind(this));importer.registerEventHandler('i915_gem_ring_flush',I915Parser.prototype.gemRingFlushEvent.bind(this));importer.registerEventHandler('i915_gem_request',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_add',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_complete',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_retire',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_begin',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_request_wait_end',I915Parser.prototype.gemRequestEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_begin',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_gem_ring_wait_end',I915Parser.prototype.gemRingWaitEvent.bind(this));importer.registerEventHandler('i915_reg_rw',I915Parser.prototype.regRWEvent.bind(this));importer.registerEventHandler('i915_flip_request',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('i915_flip_complete',I915Parser.prototype.flipEvent.bind(this));importer.registerEventHandler('intel_gpu_freq_change',I915Parser.prototype.gpuFrequency.bind(this));}
+I915Parser.prototype={__proto__:Parser.prototype,i915FlipOpenSlice(ts,obj,plane){const kthread=this.importer.getOrCreatePseudoThread('i915_flip');kthread.openSliceTS=ts;kthread.openSlice='flip:'+obj+'/'+plane;},i915FlipCloseSlice(ts,args){const kthread=this.importer.getOrCreatePseudoThread('i915_flip');if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,args,ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;},i915GemObjectSlice(ts,eventName,obj,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gem');kthread.openSlice=eventName+':'+obj;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915GemRingSlice(ts,eventName,dev,ring,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gem_ring');kthread.openSlice=eventName+':'+dev+'.'+ring;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915RegSlice(ts,eventName,reg,args){const kthread=this.importer.getOrCreatePseudoThread('i915_reg');kthread.openSlice=eventName+':'+reg;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},i915FreqChangeSlice(ts,eventName,args){const kthread=this.importer.getOrCreatePseudoThread('i915_gpu_freq');kthread.openSlice=eventName;const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),ts,args,0);kthread.thread.sliceGroup.pushSlice(slice);},gemObjectCreateEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const size=parseInt(event[2]);this.i915GemObjectSlice(ts,eventName,obj,{obj,size});return true;},gemObjectBindEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), offset=(\w+), size=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const offset=event[2];const size=parseInt(event[3]);this.i915ObjectGemSlice(ts,eventName+':'+obj,{obj,offset,size});return true;},gemObjectChangeDomainEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), read=(\w+=>\w+), write=(\w+=>\w+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const read=event[2];const write=event[3];this.i915GemObjectSlice(ts,eventName,obj,{obj,read,write});return true;},gemObjectPreadWriteEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), offset=(\d+), len=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const offset=parseInt(event[2]);const len=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj,offset,len});return true;},gemObjectFaultEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+), (\w+) index=(\d+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];const type=event[2];const index=parseInt(event[3]);this.i915GemObjectSlice(ts,eventName,obj,{obj,type,index});return true;},gemObjectDestroyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/obj=(\w+)/.exec(eventBase.details);if(!event)return false;const obj=event[1];this.i915GemObjectSlice(ts,eventName,obj,{obj});return true;},gemRingDispatchEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,seqno});return true;},gemRingFlushEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\w+), invalidate=(\w+), flush=(\w+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const invalidate=event[3];const flush=event[4];this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,invalidate,flush});return true;},gemRequestEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+), seqno=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);const seqno=parseInt(event[3]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring,seqno});return true;},gemRingWaitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/dev=(\d+), ring=(\d+)/.exec(eventBase.details);if(!event)return false;const dev=parseInt(event[1]);const ring=parseInt(event[2]);this.i915GemRingSlice(ts,eventName,dev,ring,{dev,ring});return true;},regRWEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/(\w+) reg=(\w+), len=(\d+), val=(\(\w+, \w+\))/.exec(eventBase.details);if(!event)return false;const rw=event[1];const reg=event[2];const len=event[3];const data=event[3];this.i915RegSlice(ts,rw,reg,{rw,reg,len,data});return true;},flipEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/plane=(\d+), obj=(\w+)/.exec(eventBase.details);if(!event)return false;const plane=parseInt(event[1]);const obj=event[2];if(eventName==='i915_flip_request'){this.i915FlipOpenSlice(ts,obj,plane);}else{this.i915FlipCloseSlice(ts,{obj,plane});}
+return true;},gpuFrequency(eventName,cpuNumver,pid,ts,eventBase){const event=/new_freq=(\d+)/.exec(eventBase.details);if(!event)return false;const freq=parseInt(event[1]);this.i915FreqChangeSlice(ts,eventName,{freq});return true;}};Parser.register(I915Parser);return{I915Parser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function IrqParser(importer){Parser.call(this,importer);importer.registerEventHandler('irq_handler_entry',IrqParser.prototype.irqHandlerEntryEvent.bind(this));importer.registerEventHandler('irq_handler_exit',IrqParser.prototype.irqHandlerExitEvent.bind(this));importer.registerEventHandler('softirq_raise',IrqParser.prototype.softirqRaiseEvent.bind(this));importer.registerEventHandler('softirq_entry',IrqParser.prototype.softirqEntryEvent.bind(this));importer.registerEventHandler('softirq_exit',IrqParser.prototype.softirqExitEvent.bind(this));importer.registerEventHandler('ipi_entry',IrqParser.prototype.ipiEntryEvent.bind(this));importer.registerEventHandler('ipi_exit',IrqParser.prototype.ipiExitEvent.bind(this));}
+const irqHandlerEntryRE=/irq=(\d+) name=(.+)/;const irqHandlerExitRE=/irq=(\d+) ret=(.+)/;const softirqRE=/vec=(\d+) \[action=(.+)\]/;const ipiHandlerExitRE=/\((.+)\)/;IrqParser.prototype={__proto__:Parser.prototype,irqHandlerEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const event=irqHandlerEntryRE.exec(eventBase.details);if(!event)return false;const irq=parseInt(event[1]);const name=event[2];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;thread.irqName=name;return true;},irqHandlerExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=irqHandlerExitRE.exec(eventBase.details);if(!event)return false;const irq=parseInt(event[1]);const ret=event[2];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('','IRQ ('+thread.irqName+')',ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{ret},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;thread.irqName=undefined;return true;},softirqRaiseEvent(eventName,cpuNumber,pid,ts,eventBase){return true;},softirqEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const event=softirqRE.exec(eventBase.details);if(!event)return false;const action=event[2];const thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},softirqExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=softirqRE.exec(eventBase.details);if(!event)return false;const vec=parseInt(event[1]);const action=event[2];const thread=this.importer.getOrCreatePseudoThread('softirq cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('',action,ColorScheme.getColorIdForGeneralPurposeString(event[1]),thread.lastEntryTs,{vec},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;},ipiEntryEvent(eventName,cpuNumber,pid,ts,eventBase){const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);thread.lastEntryTs=ts;return true;},ipiExitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=ipiHandlerExitRE.exec(eventBase.details);if(!event)return false;const ipiName=event[1];const thread=this.importer.getOrCreatePseudoThread('irqs cpu '+cpuNumber);if(thread.lastEntryTs!==undefined){const duration=ts-thread.lastEntryTs;const slice=new tr.model.ThreadSlice('','IPI ('+ipiName+')',ColorScheme.getColorIdForGeneralPurposeString(ipiName),thread.lastEntryTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastEntryTs=undefined;return true;}};Parser.register(IrqParser);return{IrqParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const LinuxPerfParser=tr.e.importer.linux_perf.Parser;function KernelFuncParser(importer){LinuxPerfParser.call(this,importer);importer.registerEventHandler('graph_ent',KernelFuncParser.prototype.traceKernelFuncEnterEvent.bind(this));importer.registerEventHandler('graph_ret',KernelFuncParser.prototype.traceKernelFuncReturnEvent.bind(this));this.model_=importer.model_;this.ppids_={};}
+const TestExports={};const funcEnterRE=new RegExp('func=(.+)');TestExports.funcEnterRE=funcEnterRE;KernelFuncParser.prototype={__proto__:LinuxPerfParser.prototype,traceKernelFuncEnterEvent(eventName,cpuNumber,pid,ts,eventBase){const eventData=funcEnterRE.exec(eventBase.details);if(!eventData)return false;if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const name=eventData[1];const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const slice=slices.beginSlice(null,name,ts,{});return true;},traceKernelFuncReturnEvent(eventName,cpuNumber,pid,ts,eventBase){if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
 if(slices.openSliceCount>0){slices.endSlice(ts);}
-return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(var i=0;i<7;i++){var jobStr='JS'+i;var jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
+return true;}};LinuxPerfParser.register(KernelFuncParser);return{KernelFuncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function MaliParser(importer){Parser.call(this,importer);importer.registerEventHandler('mali_dvfs_event',MaliParser.prototype.dvfsEventEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_clock',MaliParser.prototype.dvfsSetClockEvent.bind(this));importer.registerEventHandler('mali_dvfs_set_voltage',MaliParser.prototype.dvfsSetVoltageEvent.bind(this));this.addJMCounter('mali_hwc_MESSAGES_SENT','Messages Sent');this.addJMCounter('mali_hwc_MESSAGES_RECEIVED','Messages Received');this.addJMCycles('mali_hwc_GPU_ACTIVE','GPU Active');this.addJMCycles('mali_hwc_IRQ_ACTIVE','IRQ Active');for(let i=0;i<7;i++){const jobStr='JS'+i;const jobHWCStr='mali_hwc_'+jobStr;this.addJMCounter(jobHWCStr+'_JOBS',jobStr+' Jobs');this.addJMCounter(jobHWCStr+'_TASKS',jobStr+' Tasks');this.addJMCycles(jobHWCStr+'_ACTIVE',jobStr+' Active');this.addJMCycles(jobHWCStr+'_WAIT_READ',jobStr+' Wait Read');this.addJMCycles(jobHWCStr+'_WAIT_ISSUE',jobStr+' Wait Issue');this.addJMCycles(jobHWCStr+'_WAIT_DEPEND',jobStr+' Wait Depend');this.addJMCycles(jobHWCStr+'_WAIT_FINISH',jobStr+' Wait Finish');}
 this.addTilerCounter('mali_hwc_TRIANGLES','Triangles');this.addTilerCounter('mali_hwc_QUADS','Quads');this.addTilerCounter('mali_hwc_POLYGONS','Polygons');this.addTilerCounter('mali_hwc_POINTS','Points');this.addTilerCounter('mali_hwc_LINES','Lines');this.addTilerCounter('mali_hwc_VCACHE_HIT','VCache Hit');this.addTilerCounter('mali_hwc_VCACHE_MISS','VCache Miss');this.addTilerCounter('mali_hwc_FRONT_FACING','Front Facing');this.addTilerCounter('mali_hwc_BACK_FACING','Back Facing');this.addTilerCounter('mali_hwc_PRIM_VISIBLE','Prim Visible');this.addTilerCounter('mali_hwc_PRIM_CULLED','Prim Culled');this.addTilerCounter('mali_hwc_PRIM_CLIPPED','Prim Clipped');this.addTilerCounter('mali_hwc_WRBUF_HIT','Wrbuf Hit');this.addTilerCounter('mali_hwc_WRBUF_MISS','Wrbuf Miss');this.addTilerCounter('mali_hwc_WRBUF_LINE','Wrbuf Line');this.addTilerCounter('mali_hwc_WRBUF_PARTIAL','Wrbuf Partial');this.addTilerCounter('mali_hwc_WRBUF_STALL','Wrbuf Stall');this.addTilerCycles('mali_hwc_ACTIVE','Tiler Active');this.addTilerCycles('mali_hwc_INDEX_WAIT','Index Wait');this.addTilerCycles('mali_hwc_INDEX_RANGE_WAIT','Index Range Wait');this.addTilerCycles('mali_hwc_VERTEX_WAIT','Vertex Wait');this.addTilerCycles('mali_hwc_PCACHE_WAIT','Pcache Wait');this.addTilerCycles('mali_hwc_WRBUF_WAIT','Wrbuf Wait');this.addTilerCycles('mali_hwc_BUS_READ','Bus Read');this.addTilerCycles('mali_hwc_BUS_WRITE','Bus Write');this.addTilerCycles('mali_hwc_TILER_UTLB_STALL','Tiler UTLB Stall');this.addTilerCycles('mali_hwc_TILER_UTLB_HIT','Tiler UTLB Hit');this.addFragCycles('mali_hwc_FRAG_ACTIVE','Active');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES','Primitives');this.addFragCounter('mali_hwc_FRAG_PRIMATIVES_DROPPED','Primitives Dropped');this.addFragCycles('mali_hwc_FRAG_CYCLE_DESC','Descriptor Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_PLR','PLR Processing??');this.addFragCycles('mali_hwc_FRAG_CYCLES_VERT','Vertex Processing');this.addFragCycles('mali_hwc_FRAG_CYCLES_TRISETUP','Triangle Setup');this.addFragCycles('mali_hwc_FRAG_CYCLES_RAST','Rasterization???');this.addFragCounter('mali_hwc_FRAG_THREADS','Threads');this.addFragCounter('mali_hwc_FRAG_DUMMY_THREADS','Dummy Threads');this.addFragCounter('mali_hwc_FRAG_QUADS_RAST','Quads Rast');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_TEST','Quads EZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_EZS_KILLED','Quads EZS Killed');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_TEST','Quads LZS Test');this.addFragCounter('mali_hwc_FRAG_QUADS_LZS_KILLED','Quads LZS Killed');this.addFragCycles('mali_hwc_FRAG_CYCLE_NO_TILE','No Tiles');this.addFragCounter('mali_hwc_FRAG_NUM_TILES','Tiles');this.addFragCounter('mali_hwc_FRAG_TRANS_ELIM','Transactions Eliminated');this.addComputeCycles('mali_hwc_COMPUTE_ACTIVE','Active');this.addComputeCounter('mali_hwc_COMPUTE_TASKS','Tasks');this.addComputeCounter('mali_hwc_COMPUTE_THREADS','Threads Started');this.addComputeCycles('mali_hwc_COMPUTE_CYCLES_DESC','Waiting for Descriptors');this.addTripipeCycles('mali_hwc_TRIPIPE_ACTIVE','Active');this.addArithCounter('mali_hwc_ARITH_WORDS','Instructions (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_REG','Reg scheduling stalls (/Pipes)');this.addArithCycles('mali_hwc_ARITH_CYCLES_L0','L0 cache miss stalls (/Pipes)');this.addArithCounter('mali_hwc_ARITH_FRAG_DEPEND','Frag dep check failures (/Pipes)');this.addLSCounter('mali_hwc_LS_WORDS','Instruction Words Completed');this.addLSCounter('mali_hwc_LS_ISSUES','Full Pipeline Issues');this.addLSCounter('mali_hwc_LS_RESTARTS','Restarts (unpairable insts)');this.addLSCounter('mali_hwc_LS_REISSUES_MISS','Pipeline reissue (cache miss/uTLB)');this.addLSCounter('mali_hwc_LS_REISSUES_VD','Pipeline reissue (varying data)');this.addLSCounter('mali_hwc_LS_REISSUE_ATTRIB_MISS','Pipeline reissue (attribute cache miss)');this.addLSCounter('mali_hwc_LS_REISSUE_NO_WB','Writeback not used');this.addTexCounter('mali_hwc_TEX_WORDS','Words');this.addTexCounter('mali_hwc_TEX_BUBBLES','Bubbles');this.addTexCounter('mali_hwc_TEX_WORDS_L0','Words L0');this.addTexCounter('mali_hwc_TEX_WORDS_DESC','Words Desc');this.addTexCounter('mali_hwc_TEX_THREADS','Threads');this.addTexCounter('mali_hwc_TEX_RECIRC_FMISS','Recirc due to Full Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_DESC','Recirc due to Desc Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_MULTI','Recirc due to Multipass');this.addTexCounter('mali_hwc_TEX_RECIRC_PMISS','Recirc due to Partial Cache Miss');this.addTexCounter('mali_hwc_TEX_RECIRC_CONF','Recirc due to Cache Conflict');this.addLSCCounter('mali_hwc_LSC_READ_HITS','Read Hits');this.addLSCCounter('mali_hwc_LSC_READ_MISSES','Read Misses');this.addLSCCounter('mali_hwc_LSC_WRITE_HITS','Write Hits');this.addLSCCounter('mali_hwc_LSC_WRITE_MISSES','Write Misses');this.addLSCCounter('mali_hwc_LSC_ATOMIC_HITS','Atomic Hits');this.addLSCCounter('mali_hwc_LSC_ATOMIC_MISSES','Atomic Misses');this.addLSCCounter('mali_hwc_LSC_LINE_FETCHES','Line Fetches');this.addLSCCounter('mali_hwc_LSC_DIRTY_LINE','Dirty Lines');this.addLSCCounter('mali_hwc_LSC_SNOOPS','Snoops');this.addAXICounter('mali_hwc_AXI_TLB_STALL','Address channel stall');this.addAXICounter('mali_hwc_AXI_TLB_MISS','Cache Miss');this.addAXICounter('mali_hwc_AXI_TLB_TRANSACTION','Transactions');this.addAXICounter('mali_hwc_LS_TLB_MISS','LS Cache Miss');this.addAXICounter('mali_hwc_LS_TLB_HIT','LS Cache Hit');this.addAXICounter('mali_hwc_AXI_BEATS_READ','Read Beats');this.addAXICounter('mali_hwc_AXI_BEATS_WRITE','Write Beats');this.addMMUCounter('mali_hwc_MMU_TABLE_WALK','Page Table Walks');this.addMMUCounter('mali_hwc_MMU_REPLAY_MISS','Cache Miss from Replay Buffer');this.addMMUCounter('mali_hwc_MMU_REPLAY_FULL','Replay Buffer Full');this.addMMUCounter('mali_hwc_MMU_NEW_MISS','Cache Miss on New Request');this.addMMUCounter('mali_hwc_MMU_HIT','Cache Hit');this.addMMUCycles('mali_hwc_UTLB_STALL','UTLB Stalled');this.addMMUCycles('mali_hwc_UTLB_REPLAY_MISS','UTLB Replay Miss');this.addMMUCycles('mali_hwc_UTLB_REPLAY_FULL','UTLB Replay Full');this.addMMUCycles('mali_hwc_UTLB_NEW_MISS','UTLB New Miss');this.addMMUCycles('mali_hwc_UTLB_HIT','UTLB Hit');this.addL2Counter('mali_hwc_L2_READ_BEATS','Read Beats');this.addL2Counter('mali_hwc_L2_WRITE_BEATS','Write Beats');this.addL2Counter('mali_hwc_L2_ANY_LOOKUP','Any Lookup');this.addL2Counter('mali_hwc_L2_READ_LOOKUP','Read Lookup');this.addL2Counter('mali_hwc_L2_SREAD_LOOKUP','Shareable Read Lookup');this.addL2Counter('mali_hwc_L2_READ_REPLAY','Read Replayed');this.addL2Counter('mali_hwc_L2_READ_SNOOP','Read Snoop');this.addL2Counter('mali_hwc_L2_READ_HIT','Read Cache Hit');this.addL2Counter('mali_hwc_L2_CLEAN_MISS','CleanUnique Miss');this.addL2Counter('mali_hwc_L2_WRITE_LOOKUP','Write Lookup');this.addL2Counter('mali_hwc_L2_SWRITE_LOOKUP','Shareable Write Lookup');this.addL2Counter('mali_hwc_L2_WRITE_REPLAY','Write Replayed');this.addL2Counter('mali_hwc_L2_WRITE_SNOOP','Write Snoop');this.addL2Counter('mali_hwc_L2_WRITE_HIT','Write Cache Hit');this.addL2Counter('mali_hwc_L2_EXT_READ_FULL','ExtRD with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_READ_HALF','ExtRD with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_FULL','ExtWR with BIU Full');this.addL2Counter('mali_hwc_L2_EXT_WRITE_HALF','ExtWR with BIU >1/2 Full');this.addL2Counter('mali_hwc_L2_EXT_READ','External Read (ExtRD)');this.addL2Counter('mali_hwc_L2_EXT_READ_LINE','ExtRD (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE','External Write (ExtWR)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_LINE','ExtWR (linefill)');this.addL2Counter('mali_hwc_L2_EXT_WRITE_SMALL','ExtWR (burst size <64B)');this.addL2Counter('mali_hwc_L2_EXT_BARRIER','External Barrier');this.addL2Counter('mali_hwc_L2_EXT_AR_STALL','Address Read stalls');this.addL2Counter('mali_hwc_L2_EXT_R_BUF_FULL','Response Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_RD_BUF_FULL','Read Data Buffer full stalls');this.addL2Counter('mali_hwc_L2_EXT_R_RAW','RAW hazard stalls');this.addL2Counter('mali_hwc_L2_EXT_W_STALL','Write Data stalls');this.addL2Counter('mali_hwc_L2_EXT_W_BUF_FULL','Write Data Buffer full');this.addL2Counter('mali_hwc_L2_EXT_R_W_HAZARD','WAW or WAR hazard stalls');this.addL2Counter('mali_hwc_L2_TAG_HAZARD','Tag hazard replays');this.addL2Cycles('mali_hwc_L2_SNOOP_FULL','Snoop buffer full');this.addL2Cycles('mali_hwc_L2_REPLAY_FULL','Replay buffer full');importer.registerEventHandler('tracing_mark_write:mali_driver',MaliParser.prototype.maliDDKEvent.bind(this));this.model_=importer.model_;}
-MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice:function(pid,tid,ts,func,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);var funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],'blockinfo':blockinfo});},maliDDKCloseSlice:function(pid,tid,ts,args,blockinfo){var thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
-thread.sliceGroup.endSlice(ts);},autoDetectLineRE:function(line){var lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line)){return lineREWithThread;}
-var lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line)){return lineRENoThread;}
-return null;},lineRE:null,maliDDKEvent:function(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE===null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE===null)return false;}
-var maliEvent=this.lineRE.exec(eventBase.details);var tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
-return true;},dvfsSample:function(counterName,seriesName,ts,s){var value=parseInt(s);var counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
-counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/utilization=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/voltage=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample:function(cat,counterName,seriesName,ts,eventBase){var event=/val=(\d+)/.exec(eventBase.details);if(!event)return false;var value=parseInt(event[1]);var counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
-counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample:function(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles:function(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
-this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));}
-var kswapdWakeRE=/nid=(\d+) order=(\d+)/;var kswapdSleepRE=/nid=(\d+)/;var reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;var reclaimEndRE=/nr_reclaimed=(\d+)/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake:function(eventName,cpuNumber,pid,ts,eventBase){var event=kswapdWakeRE.exec(eventBase.details);if(!event)return false;var tgid=parseInt(eventBase.tgid);var nid=parseInt(event[1]);var order=parseInt(event[2]);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
-return true;},kswapdSleep:function(eventName,cpuNumber,pid,ts,eventBase){var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
-kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimBeginRE.exec(eventBase.details);if(!event)return false;var order=parseInt(event[1]);var gfp=event[2];var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd:function(eventName,cpuNumber,pid,ts,eventBase){var event=reclaimEndRE.exec(eventBase.details);if(!event)return false;var nrReclaimed=parseInt(event[1]);var tgid=parseInt(eventBase.tgid);var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nrReclaimed});}
-kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
-PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice:function(ts,targetCpuNumber,eventType,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter;if(eventType!=='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
-powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice:function(ts,targetCpuNumber,cpuState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
-var val=(cpuState!==4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice:function(ts,targetCpuNumber,powerState){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
-powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice:function(ts,targetCpuNumber,minFreq,maxFreq){var targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
+MaliParser.prototype={__proto__:Parser.prototype,maliDDKOpenSlice(pid,tid,ts,func,blockinfo){const thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);const funcArgs=/^([\w\d_]*)(?:\(\))?:?\s*(.*)$/.exec(func);thread.sliceGroup.beginSlice('gpu-driver',funcArgs[1],ts,{'args':funcArgs[2],blockinfo});},maliDDKCloseSlice(pid,tid,ts,args,blockinfo){const thread=this.importer.model_.getOrCreateProcess(pid).getOrCreateThread(tid);if(!thread.sliceGroup.openSliceCount){return;}
+thread.sliceGroup.endSlice(ts);},autoDetectLineRE(line){const lineREWithThread=/^\s*\(([\w\-]*)\)\s*(\w+):\s*([\w\\\/\.\-]*@\d*):?\s*(.*)$/;if(lineREWithThread.test(line)){return lineREWithThread;}
+const lineRENoThread=/^s*()(\w+):\s*([\w\\\/.\-]*):?\s*(.*)$/;if(lineRENoThread.test(line)){return lineRENoThread;}
+return null;},lineRE:null,maliDDKEvent(eventName,cpuNumber,pid,ts,eventBase){if(this.lineRE===null){this.lineRE=this.autoDetectLineRE(eventBase.details);if(this.lineRE===null)return false;}
+const maliEvent=this.lineRE.exec(eventBase.details);const tid=(maliEvent[1]===''?'mali':maliEvent[1]);switch(maliEvent[2]){case'cros_trace_print_enter':this.maliDDKOpenSlice(pid,tid,ts,maliEvent[4],maliEvent[3]);break;case'cros_trace_print_exit':this.maliDDKCloseSlice(pid,tid,ts,[],maliEvent[3]);}
+return true;},dvfsSample(counterName,seriesName,ts,s){const value=parseInt(s);const counter=this.model_.kernel.getOrCreateCounter('DVFS',counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});},dvfsEventEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/utilization=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Utilization','utilization',ts,event[1]);return true;},dvfsSetClockEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/frequency=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Frequency','frequency',ts,event[1]);return true;},dvfsSetVoltageEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/voltage=(\d+)/.exec(eventBase.details);if(!event)return false;this.dvfsSample('DVFS Voltage','voltage',ts,event[1]);return true;},hwcSample(cat,counterName,seriesName,ts,eventBase){const event=/val=(\d+)/.exec(eventBase.details);if(!event)return false;const value=parseInt(event[1]);const counter=this.model_.kernel.getOrCreateCounter(cat,counterName);if(counter.numSeries===0){counter.addSeries(new tr.model.CounterSeries(seriesName,ColorScheme.getColorIdForGeneralPurposeString(counter.name)));}
+counter.series.forEach(function(series){series.addCounterSample(ts,value);});return true;},jmSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:jm','JM: '+ctrName,seriesName,ts,eventBase);},addJMCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addJMCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.jmSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},tilerSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:tiler','Tiler: '+ctrName,seriesName,ts,eventBase);},addTilerCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTilerCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.tilerSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},fragSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:fragment','Fragment: '+ctrName,seriesName,ts,eventBase);},addFragCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addFragCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.fragSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},computeSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:compute','Compute: '+ctrName,seriesName,ts,eventBase);},addComputeCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addComputeCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.computeSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addTripipeCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:shader','Tripipe: '+hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},arithSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:arith','Arith: '+ctrName,seriesName,ts,eventBase);},addArithCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addArithCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.arithSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:ls','LS: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},textureSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:texture','Texture: '+ctrName,seriesName,ts,eventBase);},addTexCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.textureSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addLSCCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:lsc','LSC: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addAXICounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.hwcSample('mali:axi','AXI: '+hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},mmuSample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:mmu','MMU: '+ctrName,seriesName,ts,eventBase);},addMMUCounter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addMMUCycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.mmuSample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},l2Sample(ctrName,seriesName,ts,eventBase){return this.hwcSample('mali:l2','L2: '+ctrName,seriesName,ts,eventBase);},addL2Counter(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'count',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));},addL2Cycles(hwcEventName,hwcTitle){function handler(eventName,cpuNumber,pid,ts,eventBase){return this.l2Sample(hwcTitle,'cycles',ts,eventBase);}
+this.importer.registerEventHandler(hwcEventName,handler.bind(this));}};Parser.register(MaliParser);return{MaliParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function MemReclaimParser(importer){Parser.call(this,importer);importer.registerEventHandler('mm_vmscan_kswapd_wake',MemReclaimParser.prototype.kswapdWake.bind(this));importer.registerEventHandler('mm_vmscan_kswapd_sleep',MemReclaimParser.prototype.kswapdSleep.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_begin',MemReclaimParser.prototype.reclaimBegin.bind(this));importer.registerEventHandler('mm_vmscan_direct_reclaim_end',MemReclaimParser.prototype.reclaimEnd.bind(this));}
+const kswapdWakeRE=/nid=(\d+) order=(\d+)/;const kswapdSleepRE=/nid=(\d+)/;const reclaimBeginRE=/order=(\d+) may_writepage=\d+ gfp_flags=(.+)/;const reclaimEndRE=/nr_reclaimed=(\d+)/;MemReclaimParser.prototype={__proto__:Parser.prototype,kswapdWake(eventName,cpuNumber,pid,ts,eventBase){const event=kswapdWakeRE.exec(eventBase.details);if(!event)return false;const tgid=parseInt(eventBase.tgid);const nid=parseInt(event[1]);const order=parseInt(event[2]);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){if(order>kthread.order){kthread.order=order;}}else{kthread.openSliceTS=ts;kthread.order=order;}
+return true;},kswapdSleep(eventName,cpuNumber,pid,ts,eventBase){const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim',eventBase.threadName,kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order});}
+kthread.openSliceTS=undefined;kthread.order=undefined;return true;},reclaimBegin(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimBeginRE.exec(eventBase.details);if(!event)return false;const order=parseInt(event[1]);const gfp=event[2];const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);kthread.openSliceTS=ts;kthread.order=order;kthread.gfp=gfp;return true;},reclaimEnd(eventName,cpuNumber,pid,ts,eventBase){const event=reclaimEndRE.exec(eventBase.details);if(!event)return false;const nrReclaimed=parseInt(event[1]);const tgid=parseInt(eventBase.tgid);const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,tgid,pid);if(kthread.openSliceTS!==undefined){kthread.thread.sliceGroup.pushCompleteSlice('memreclaim','direct reclaim',kthread.openSliceTS,ts-kthread.openSliceTS,0,0,{order:kthread.order,gfp:kthread.gfp,nr_reclaimed:nrReclaimed});}
+kthread.openSliceTS=undefined;kthread.order=undefined;kthread.gfp=undefined;return true;}};Parser.register(MemReclaimParser);return{MemReclaimParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function PowerParser(importer){Parser.call(this,importer);importer.registerEventHandler('power_start',PowerParser.prototype.powerStartEvent.bind(this));importer.registerEventHandler('power_frequency',PowerParser.prototype.powerFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency',PowerParser.prototype.cpuFrequencyEvent.bind(this));importer.registerEventHandler('cpu_frequency_limits',PowerParser.prototype.cpuFrequencyLimitsEvent.bind(this));importer.registerEventHandler('cpu_idle',PowerParser.prototype.cpuIdleEvent.bind(this));}
+PowerParser.prototype={__proto__:Parser.prototype,cpuStateSlice(ts,targetCpuNumber,eventType,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);if(eventType!=='1'){this.importer.model.importWarning({type:'parse_error',message:'Don\'t understand power_start events of '+'type '+eventType});return;}
+const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,cpuState);});},cpuIdleSlice(ts,targetCpuNumber,cpuState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','C-State');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name)));}
+const val=(cpuState!==4294967295?cpuState+1:0);powerCounter.series.forEach(function(series){series.addCounterSample(ts,val);});},cpuFrequencySlice(ts,targetCpuNumber,powerState){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('state',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'state')));}
+powerCounter.series.forEach(function(series){series.addCounterSample(ts,powerState);});},cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq){const targetCpu=this.importer.getOrCreateCpu(targetCpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Clock Frequency Limits');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('Min Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Min Frequency')));powerCounter.addSeries(new tr.model.CounterSeries('Max Frequency',ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'Max Frequency')));}
 powerCounter.series.forEach(function(series){if(series.name==='Min Frequency'){series.addCounterSample(ts,minFreq);}
-if(series.name==='Max Frequency'){series.addCounterSample(ts,maxFreq);}});},powerStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;var targetCpuNumber=parseInt(event[3]);var cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;var targetCpuNumber=parseInt(event[3]);var powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;var targetCpuNumber=parseInt(event[2]);var powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent:function(eventName,cpu,pid,ts,eventBase){var event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;var targetCpuNumber=parseInt(event[3]);var minFreq=parseInt(event[1]);var maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;var targetCpuNumber=parseInt(event[2]);var cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
-var regulatorEnableRE=/name=(.+)/;var regulatorDisableRE=/name=(.+)/;var regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_:function(ctrName,valueName){var ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
-return ctr;},regulatorEnableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorEnableRE.exec(eventBase.details);if(!event)return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorDisableRE.exec(eventBase.details);if(!event)return false;var name=event[1];var ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent:function(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent:function(eventName,cpuNum,pid,ts,eventBase){var event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)return false;var name=event[1];var voltage=parseInt(event[2]);var ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
-var TestExports={};var schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');var schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;var schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+)(?: success=\d+)? target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedSwitchRE.exec(eventBase.details);if(!event)return false;var prevState=event[4];var nextComm=event[5];var nextPid=parseInt(event[6]);var nextPrio=parseInt(event[7]);if(eventBase.tgid!==undefined){var tgid=parseInt(eventBase.tgid);var process=this.importer.model_.getOrCreateProcess(tgid);if(!process.getThread(pid)){var thread=process.getOrCreateThread(pid);thread.name=eventBase.threadName;}}
-var nextThread=this.importer.threadsByLinuxPid[nextPid];var nextName;if(nextThread){nextName=nextThread.userFriendlyName;}else{nextName=nextComm;}
-var cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedWakeupRE.exec(eventBase.details);if(!event)return false;var fromPid=pid;var comm=event[1];var pid=parseInt(event[2]);var prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)return false;var cpuNumber=event[1];var state=event[2];var targetCpu=this.importer.getOrCreateCpu(cpuNumber);var powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
-powerCounter.series.forEach(function(series){if(series.name==='State'){series.addCounterSample(ts,state.localeCompare('offline')?0:1);}});return true;},schedBlockedEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=schedBlockedRE.exec(eventBase.details);if(!event)return false;var pid=parseInt(event[1]);var iowait=parseInt(event[2]);var caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
-var syncTimelineRE=/name=(\S+) value=(\S*)/;var syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;var syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncTimelineRE.exec(eventBase.details);if(!event)return false;var thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){var duration=ts-thread.lastActiveTs;var value=thread.lastActiveValue;if(value===undefined)value=' ';var slice=new tr.model.ThreadSlice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
-thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=syncWaitRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
-var tgid=parseInt(eventBase.tgid);var thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;var slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
-var name='fence_wait("'+event[2]+'")';if(event[1]==='begin'){var slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]==='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
-return true;},syncPtEvent:function(eventName,cpuNumber,pid,ts,eventBase){return!!syncPtRE.exec(eventBase.details);}};Parser.register(SyncParser);return{SyncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var ColorScheme=tr.b.ColorScheme;var Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
-var workqueueExecuteStartRE=/work struct (.+): function (\S+)/;var workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent:function(eventName,cpuNumber,pid,ts,eventBase){var event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)return false;var kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){var slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
-kthread.openSlice=undefined;return true;},executeQueueWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork:function(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){var MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID='linux_clock_monotonic_to_ftrace_global';function FTraceImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.wakeups_=[];this.blockedReasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};this.haveClockSyncedMonotonicToGlobal_=false;}
-var TestExports={};var lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithTGID=function(line){var groups=lineREWithTGID.exec(line);if(!groups){return groups;}
-var tgid=groups[3];if(tgid[0]==='-')tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid:tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;var lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');var lineParserWithIRQInfo=function(line){var groups=lineREWithIRQInfo.exec(line);if(!groups){return groups;}
-return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;var lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;var lineParserWithLegacyFmt=function(line){var groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
-return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;var traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;var realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;var genericClockSyncRE=/trace_event_clock_sync: name=([\w\-]+)/;var pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]==='{')return false;if(lineREWithTGID.test(line)){return lineParserWithTGID;}
-if(lineREWithIRQInfo.test(line)){return lineParserWithIRQInfo;}
-if(lineREWithLegacyFmt.test(line)){return lineParserWithLegacyFmt;}
-return undefined;}
-TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(!(typeof(events)==='string'||events instanceof String)){return false;}
+if(series.name==='Max Frequency'){series.addCounterSample(ts,maxFreq);}});},powerStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/type=(\d+) state=(\d) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const cpuState=parseInt(event[2]);this.cpuStateSlice(ts,targetCpuNumber,event[1],cpuState);return true;},powerFrequencyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/type=(\d+) state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const powerState=parseInt(event[2]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[2]);const powerState=parseInt(event[1]);this.cpuFrequencySlice(ts,targetCpuNumber,powerState);return true;},cpuFrequencyLimitsEvent(eventName,cpu,pid,ts,eventBase){const event=/min=(\d+) max=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[3]);const minFreq=parseInt(event[1]);const maxFreq=parseInt(event[2]);this.cpuFrequencyLimitsSlice(ts,targetCpuNumber,minFreq,maxFreq);return true;},cpuIdleEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/state=(\d+) cpu_id=(\d+)/.exec(eventBase.details);if(!event)return false;const targetCpuNumber=parseInt(event[2]);const cpuState=parseInt(event[1]);this.cpuIdleSlice(ts,targetCpuNumber,cpuState);return true;}};Parser.register(PowerParser);return{PowerParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function RegulatorParser(importer){Parser.call(this,importer);importer.registerEventHandler('regulator_enable',RegulatorParser.prototype.regulatorEnableEvent.bind(this));importer.registerEventHandler('regulator_enable_delay',RegulatorParser.prototype.regulatorEnableDelayEvent.bind(this));importer.registerEventHandler('regulator_enable_complete',RegulatorParser.prototype.regulatorEnableCompleteEvent.bind(this));importer.registerEventHandler('regulator_disable',RegulatorParser.prototype.regulatorDisableEvent.bind(this));importer.registerEventHandler('regulator_disable_complete',RegulatorParser.prototype.regulatorDisableCompleteEvent.bind(this));importer.registerEventHandler('regulator_set_voltage',RegulatorParser.prototype.regulatorSetVoltageEvent.bind(this));importer.registerEventHandler('regulator_set_voltage_complete',RegulatorParser.prototype.regulatorSetVoltageCompleteEvent.bind(this));this.model_=importer.model_;}
+const regulatorEnableRE=/name=(.+)/;const regulatorDisableRE=/name=(.+)/;const regulatorSetVoltageCompleteRE=/name=(\S+), val=(\d+)/;RegulatorParser.prototype={__proto__:Parser.prototype,getCtr_(ctrName,valueName){const ctr=this.model_.kernel.getOrCreateCounter(null,'vreg '+ctrName+' '+valueName);if(ctr.series[0]===undefined){ctr.addSeries(new tr.model.CounterSeries(valueName,ColorScheme.getColorIdForGeneralPurposeString(ctrName+'.'+valueName)));}
+return ctr;},regulatorEnableEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorEnableRE.exec(eventBase.details);if(!event)return false;const name=event[1];const ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,1);return true;},regulatorEnableDelayEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorEnableCompleteEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorDisableEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorDisableRE.exec(eventBase.details);if(!event)return false;const name=event[1];const ctr=this.getCtr_(name,'enabled');ctr.series[0].addCounterSample(ts,0);return true;},regulatorDisableCompleteEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageEvent(eventName,cpuNum,pid,ts,eventBase){return true;},regulatorSetVoltageCompleteEvent(eventName,cpuNum,pid,ts,eventBase){const event=regulatorSetVoltageCompleteRE.exec(eventBase.details);if(!event)return false;const name=event[1];const voltage=parseInt(event[2]);const ctr=this.getCtr_(name,'voltage');ctr.series[0].addCounterSample(ts,voltage);return true;}};Parser.register(RegulatorParser);return{RegulatorParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const Parser=tr.e.importer.linux_perf.Parser;function SchedParser(importer){Parser.call(this,importer);importer.registerEventHandler('sched_switch',SchedParser.prototype.schedSwitchEvent.bind(this));importer.registerEventHandler('sched_wakeup',SchedParser.prototype.schedWakeupEvent.bind(this));importer.registerEventHandler('sched_blocked_reason',SchedParser.prototype.schedBlockedEvent.bind(this));importer.registerEventHandler('sched_cpu_hotplug',SchedParser.prototype.schedCpuHotplugEvent.bind(this));}
+const TestExports={};const schedSwitchRE=new RegExp('prev_comm=(.+) prev_pid=(\\d+) prev_prio=(\\d+) '+'prev_state=(\\S\\+?|\\S\\|\\S) ==> '+'next_comm=(.+) next_pid=(\\d+) next_prio=(\\d+)');const schedBlockedRE=new RegExp('pid=(\\d+) iowait=(\\d) caller=(.+)');TestExports.schedSwitchRE=schedSwitchRE;const schedWakeupRE=/comm=(.+) pid=(\d+) prio=(\d+)(?: success=\d+)? target_cpu=(\d+)/;TestExports.schedWakeupRE=schedWakeupRE;SchedParser.prototype={__proto__:Parser.prototype,schedSwitchEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedSwitchRE.exec(eventBase.details);if(!event)return false;const prevState=event[4];const nextComm=event[5];const nextPid=parseInt(event[6]);const nextPrio=parseInt(event[7]);if(eventBase.tgid!==undefined){const tgid=parseInt(eventBase.tgid);const process=this.importer.model_.getOrCreateProcess(tgid);if(!process.getThread(pid)){const thread=process.getOrCreateThread(pid);thread.name=eventBase.threadName;}}
+const nextThread=this.importer.threadsByLinuxPid[nextPid];let nextName;if(nextThread){nextName=nextThread.userFriendlyName;}else{nextName=nextComm;}
+const cpu=this.importer.getOrCreateCpu(cpuNumber);cpu.switchActiveThread(ts,{stateWhenDescheduled:prevState},nextPid,nextName,{comm:nextComm,tid:nextPid,prio:nextPrio});return true;},schedWakeupEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedWakeupRE.exec(eventBase.details);if(!event)return false;const fromPid=pid;const comm=event[1];pid=parseInt(event[2]);const prio=parseInt(event[3]);this.importer.markPidRunnable(ts,pid,comm,prio,fromPid);return true;},schedCpuHotplugEvent(eventName,cpuNumber,pid,ts,eventBase){const event=/cpu (\d+) (.+) error=(\d+)/.exec(eventBase.details);if(!event)return false;cpuNumber=event[1];const state=event[2];const targetCpu=this.importer.getOrCreateCpu(cpuNumber);const powerCounter=targetCpu.getOrCreateCounter('','Cpu Hotplug');if(powerCounter.numSeries===0){powerCounter.addSeries(new tr.model.CounterSeries('State',tr.b.ColorScheme.getColorIdForGeneralPurposeString(powerCounter.name+'.'+'State')));}
+powerCounter.series.forEach(function(series){if(series.name==='State'){series.addCounterSample(ts,state.localeCompare('offline')?0:1);}});return true;},schedBlockedEvent(eventName,cpuNumber,pid,ts,eventBase){const event=schedBlockedRE.exec(eventBase.details);if(!event)return false;pid=parseInt(event[1]);const iowait=parseInt(event[2]);const caller=event[3];this.importer.addPidBlockedReason(ts,pid,iowait,caller);return true;}};Parser.register(SchedParser);return{SchedParser,_SchedParserTestExports:TestExports};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function SyncParser(importer){Parser.call(this,importer);importer.registerEventHandler('sync_timeline',SyncParser.prototype.timelineEvent.bind(this));importer.registerEventHandler('sync_wait',SyncParser.prototype.syncWaitEvent.bind(this));importer.registerEventHandler('sync_pt',SyncParser.prototype.syncPtEvent.bind(this));this.model_=importer.model_;}
+const syncTimelineRE=/name=(\S+) value=(\S*)/;const syncWaitRE=/(\S+) name=(\S+) state=(\d+)/;const syncPtRE=/name=(\S+) value=(\S*)/;SyncParser.prototype={__proto__:Parser.prototype,timelineEvent(eventName,cpuNumber,pid,ts,eventBase){const event=syncTimelineRE.exec(eventBase.details);if(!event)return false;const thread=this.importer.getOrCreatePseudoThread(event[1]);if(thread.lastActiveTs!==undefined){const duration=ts-thread.lastActiveTs;let value=thread.lastActiveValue;if(value===undefined)value=' ';const slice=new tr.model.ThreadSlice('',value,ColorScheme.getColorIdForGeneralPurposeString(value),thread.lastActiveTs,{},duration);thread.thread.sliceGroup.pushSlice(slice);}
+thread.lastActiveTs=ts;thread.lastActiveValue=event[2];return true;},syncWaitEvent(eventName,cpuNumber,pid,ts,eventBase){const event=syncWaitRE.exec(eventBase.details);if(!event)return false;if(eventBase.tgid===undefined){return false;}
+const tgid=parseInt(eventBase.tgid);const thread=this.model_.getOrCreateProcess(tgid).getOrCreateThread(pid);thread.name=eventBase.threadName;const slices=thread.kernelSliceGroup;if(!slices.isTimestampValidForBeginOrEnd(ts)){this.model_.importWarning({type:'parse_error',message:'Timestamps are moving backward.'});return false;}
+const name='fence_wait("'+event[2]+'")';if(event[1]==='begin'){const slice=slices.beginSlice(null,name,ts,{'Start state':event[3]});}else if(event[1]==='end'){if(slices.openSliceCount>0){slices.endSlice(ts);}}else{return false;}
+return true;},syncPtEvent(eventName,cpuNumber,pid,ts,eventBase){return!!syncPtRE.exec(eventBase.details);}};Parser.register(SyncParser);return{SyncParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const ColorScheme=tr.b.ColorScheme;const Parser=tr.e.importer.linux_perf.Parser;function WorkqueueParser(importer){Parser.call(this,importer);importer.registerEventHandler('workqueue_execute_start',WorkqueueParser.prototype.executeStartEvent.bind(this));importer.registerEventHandler('workqueue_execute_end',WorkqueueParser.prototype.executeEndEvent.bind(this));importer.registerEventHandler('workqueue_queue_work',WorkqueueParser.prototype.executeQueueWork.bind(this));importer.registerEventHandler('workqueue_activate_work',WorkqueueParser.prototype.executeActivateWork.bind(this));}
+const workqueueExecuteStartRE=/work struct (.+): function (\S+)/;const workqueueExecuteEndRE=/work struct (.+)/;WorkqueueParser.prototype={__proto__:Parser.prototype,executeStartEvent(eventName,cpuNumber,pid,ts,eventBase){const event=workqueueExecuteStartRE.exec(eventBase.details);if(!event)return false;const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);kthread.openSliceTS=ts;kthread.openSlice=event[2];return true;},executeEndEvent(eventName,cpuNumber,pid,ts,eventBase){const event=workqueueExecuteEndRE.exec(eventBase.details);if(!event)return false;const kthread=this.importer.getOrCreateKernelThread(eventBase.threadName,pid,pid);if(kthread.openSlice){const slice=new tr.model.ThreadSlice('',kthread.openSlice,ColorScheme.getColorIdForGeneralPurposeString(kthread.openSlice),kthread.openSliceTS,{},ts-kthread.openSliceTS);kthread.thread.sliceGroup.pushSlice(slice);}
+kthread.openSlice=undefined;return true;},executeQueueWork(eventName,cpuNumber,pid,ts,eventBase){return true;},executeActivateWork(eventName,cpuNumber,pid,ts,eventBase){return true;}};Parser.register(WorkqueueParser);return{WorkqueueParser,};});'use strict';tr.exportTo('tr.e.importer.linux_perf',function(){const MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID='linux_clock_monotonic_to_ftrace_global';function FTraceImporter(model,events){this.importPriority=2;this.model_=model;this.events_=events;this.wakeups_=[];this.blockedReasons_=[];this.kernelThreadStates_={};this.buildMapFromLinuxPidsToThreads_();this.lines_=[];this.pseudoThreadCounter=1;this.parsers_=[];this.eventHandlers_={};this.haveClockSyncedMonotonicToGlobal_=false;this.clockDomainId_=tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL;}
+const TestExports={};const lineREWithTGID=new RegExp('^\\s*(.+)-(\\d+)\\s+\\(\\s*(\\d+|-+)\\)\\s\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');const lineParserWithTGID=function(line){const groups=lineREWithTGID.exec(line);if(!groups)return groups;let tgid=groups[3];if(tgid[0]==='-')tgid=undefined;return{threadName:groups[1],pid:groups[2],tgid,cpuNumber:groups[4],timestamp:groups[5],eventName:groups[6],details:groups[7]};};TestExports.lineParserWithTGID=lineParserWithTGID;const lineREWithIRQInfo=new RegExp('^\\s*(.+)-(\\d+)\\s+\\[(\\d+)\\]'+'\\s+[dX.][Nnp.][Hhs.][0-9a-f.]'+'\\s+(\\d+\\.\\d+):\\s+(\\S+):\\s(.*)$');const lineParserWithIRQInfo=function(line){const groups=lineREWithIRQInfo.exec(line);if(!groups)return groups;return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithIRQInfo=lineParserWithIRQInfo;const lineREWithLegacyFmt=/^\s*(.+)-(\d+)\s+\[(\d+)\]\s*(\d+\.\d+):\s+(\S+):\s(.*)$/;const lineParserWithLegacyFmt=function(line){const groups=lineREWithLegacyFmt.exec(line);if(!groups){return groups;}
+return{threadName:groups[1],pid:groups[2],cpuNumber:groups[3],timestamp:groups[4],eventName:groups[5],details:groups[6]};};TestExports.lineParserWithLegacyFmt=lineParserWithLegacyFmt;const traceEventClockSyncRE=/trace_event_clock_sync: parent_ts=(\d+\.?\d*)/;TestExports.traceEventClockSyncRE=traceEventClockSyncRE;const realTimeClockSyncRE=/trace_event_clock_sync: realtime_ts=(\d+)/;const genericClockSyncRE=/trace_event_clock_sync: name=([\w\-]+)/;const pseudoKernelPID=0;function autoDetectLineParser(line){if(line[0]==='{')return false;if(lineREWithTGID.test(line))return lineParserWithTGID;if(lineREWithIRQInfo.test(line))return lineParserWithIRQInfo;if(lineREWithLegacyFmt.test(line))return lineParserWithLegacyFmt;return undefined;}
+TestExports.autoDetectLineParser=autoDetectLineParser;FTraceImporter.canImport=function(events){if(events instanceof tr.b.TraceStream)events=events.header;if(!(typeof(events)==='string'||events instanceof String)){return false;}
 if(FTraceImporter._extractEventsFromSystraceHTML(events,false).ok){return true;}
 if(FTraceImporter._extractEventsFromSystraceMultiHTML(events,false).ok){return true;}
-if(/^# tracer:/.test(events)){return true;}
-var lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1){events=events.substring(0,lineBreakIndex);}
-if(autoDetectLineParser(events)){return true;}
-return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incomingEvents,produceResult){var failure={ok:false};if(produceResult===undefined){produceResult=true;}
-if(!/^<!DOCTYPE html>/.test(incomingEvents)){return failure;}
-var r=new tr.importer.SimpleLineReader(incomingEvents);if(!r.advanceToLineMatching(/^  <script>$/)){return failure;}
-if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/)){return failure;}
-var eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/)){return failure;}
-var rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);if(!r.advanceToLineMatching(/^<\/body>$/)){return failure;}
-if(!r.advanceToLineMatching(/^<\/html>$/)){return failure;}
-function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
-function stripSuffix(str,suffix){if(!endsWith(str,suffix)){return str;}
-return str.substring(str,str.length-suffix.length);}
-var events=[];if(produceResult){for(var i=0;i<rawEvents.length;i++){var event=rawEvents[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[rawEvents[rawEvents.length-1]];}
-var oldLastEvent=events[events.length-1];var newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent===oldLastEvent){return failure;}
-events[events.length-1]=newLastEvent;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine:eventsBeginAtLine};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incomingEvents,produceResult){var failure={ok:false};if(produceResult===undefined){produceResult=true;}
-if(!(new RegExp('^<!DOCTYPE HTML>','i').test(incomingEvents))){return failure;}
-var r=new tr.importer.SimpleLineReader(incomingEvents);var events=[];while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/)){return failure;}
-var eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
-if(!r.advanceToLineMatching(/^<\/body>$/)){return failure;}
-if(!r.advanceToLineMatching(/^<\/html>$/)){return failure;}
-return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine:eventsBeginAtLine};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importClockSyncMarkers:function(){this.lazyInit_();this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0'){return;}
-if(traceEventClockSyncRE.exec(eventBase.details)||genericClockSyncRE.exec(eventBase.details)){this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}else if(realTimeClockSyncRE.exec(eventBase.details)){var match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}}.bind(this));},importEvents:function(){var modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler:function(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu:function(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread:function(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
-return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread:function(kernelThreadName,pid,tid){var key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){var thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid:pid,thread:thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
-return this.kernelThreadStates_[key];},getOrCreatePseudoThread:function(threadName){var thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
-return thread;},markPidRunnable:function(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts:ts,tid:pid,fromTid:fromPid});},addPidBlockedReason:function(ts,pid,iowait,caller){this.blockedReasons_.push({ts:ts,tid:pid,iowait:iowait,caller:caller});},buildMapFromLinuxPidsToThreads_:function(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_:function(){var SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(var cpuNumber in this.model_.kernel.cpus){var cpu=this.model_.kernel.cpus[cpuNumber];for(var i=0;i<cpu.slices.length;i++){var cpuSlice=cpu.slices[i];var thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices){thread.tempCpuSlices=[];}
+if(/^# tracer:/.test(events))return true;const lineBreakIndex=events.indexOf('\n');if(lineBreakIndex>-1)events=events.substring(0,lineBreakIndex);if(autoDetectLineParser(events))return true;return false;};FTraceImporter._extractEventsFromSystraceHTML=function(incomingEvents,produceResult){const failure={ok:false};if(produceResult===undefined)produceResult=true;const header=incomingEvents instanceof tr.b.TraceStream?incomingEvents.header:incomingEvents;if(!/^<!DOCTYPE html>/.test(header))return failure;const r=new tr.importer.SimpleLineReader(incomingEvents);if(!r.advanceToLineMatching(/^  <script>$/))return failure;if(!r.advanceToLineMatching(/^  var linuxPerfData = "\\$/))return failure;const eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;let rawEvents=r.endSavingLinesAndGetResult();rawEvents=rawEvents.slice(1,rawEvents.length-1);if(!r.advanceToLineMatching(/^<\/body>$/))return failure;if(!r.advanceToLineMatching(/^<\/html>$/))return failure;function endsWith(str,suffix){return str.indexOf(suffix,str.length-suffix.length)!==-1;}
+function stripSuffix(str,suffix){if(!endsWith(str,suffix))return str;return str.substring(str,str.length-suffix.length);}
+let events=[];if(produceResult){for(let i=0;i<rawEvents.length;i++){let event=rawEvents[i];event=stripSuffix(event,'\\n\\');events.push(event);}}else{events=[rawEvents[rawEvents.length-1]];}
+const oldLastEvent=events[events.length-1];const newLastEvent=stripSuffix(oldLastEvent,'\\n";');if(newLastEvent===oldLastEvent)return failure;events[events.length-1]=newLastEvent;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine};};FTraceImporter._extractEventsFromSystraceMultiHTML=function(incomingEvents,produceResult){const failure={ok:false};if(produceResult===undefined)produceResult=true;const header=incomingEvents instanceof tr.b.TraceStream?incomingEvents.header:incomingEvents;if(!(new RegExp('^<!DOCTYPE HTML>','i').test(header)))return failure;const r=new tr.importer.SimpleLineReader(incomingEvents);let events=[];let eventsBeginAtLine;while(!/^# tracer:/.test(events)){if(!r.advanceToLineMatching(/^  <script class="trace-data" type="application\/text">$/)){return failure;}
+eventsBeginAtLine=r.curLineNumber+1;r.beginSavingLines();if(!r.advanceToLineMatching(/^  <\/script>$/))return failure;events=r.endSavingLinesAndGetResult();events=events.slice(1,events.length-1);}
+if(!r.advanceToLineMatching(/^<\/body>$/))return failure;if(!r.advanceToLineMatching(/^<\/html>$/))return failure;return{ok:true,lines:produceResult?events:undefined,eventsBeginAtLine,};};FTraceImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'FTraceImporter';},get model(){return this.model_;},importClockSyncMarkers(){this.lazyInit_();this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){const eventName=eventBase.eventName;if(eventName!=='tracing_mark_write'&&eventName!=='0')return;if(traceEventClockSyncRE.exec(eventBase.details)||genericClockSyncRE.exec(eventBase.details)){this.traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase);}else if(realTimeClockSyncRE.exec(eventBase.details)){const match=realTimeClockSyncRE.exec(eventBase.details);this.model_.realtime_to_monotonic_offset_ms=ts-match[1];}}.bind(this));},importEvents(){const modelTimeTransformer=this.model_.clockSyncManager.getModelTimeTransformer(this.clockDomainId_);this.importCpuData_(modelTimeTransformer);this.buildMapFromLinuxPidsToThreads_();this.buildPerThreadCpuSlicesFromCpuState_();},registerEventHandler(eventName,handler){this.eventHandlers_[eventName]=handler;},getOrCreateCpu(cpuNumber){return this.model_.kernel.getOrCreateCpu(cpuNumber);},getOrCreateKernelThread(kernelThreadName,pid,tid){if(!this.kernelThreadStates_[kernelThreadName]){const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[kernelThreadName]={pid,thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[kernelThreadName];},getOrCreateBinderKernelThread(kernelThreadName,pid,tid){const key=kernelThreadName+pid+tid;if(!this.kernelThreadStates_[key]){const thread=this.model_.getOrCreateProcess(pid).getOrCreateThread(tid);thread.name=kernelThreadName;this.kernelThreadStates_[key]={pid,thread,openSlice:undefined,openSliceTS:undefined};this.threadsByLinuxPid[pid]=thread;}
+return this.kernelThreadStates_[key];},getOrCreatePseudoThread(threadName){let thread=this.kernelThreadStates_[threadName];if(!thread){thread=this.getOrCreateKernelThread(threadName,pseudoKernelPID,this.pseudoThreadCounter);this.pseudoThreadCounter++;}
+return thread;},markPidRunnable(ts,pid,comm,prio,fromPid){this.wakeups_.push({ts,tid:pid,fromTid:fromPid});},addPidBlockedReason(ts,pid,iowait,caller){this.blockedReasons_.push({ts,tid:pid,iowait,caller});},buildMapFromLinuxPidsToThreads_(){this.threadsByLinuxPid={};this.model_.getAllThreads().forEach(function(thread){this.threadsByLinuxPid[thread.tid]=thread;}.bind(this));},buildPerThreadCpuSlicesFromCpuState_(){const SCHEDULING_STATE=tr.model.SCHEDULING_STATE;for(const cpuNumber in this.model_.kernel.cpus){const cpu=this.model_.kernel.cpus[cpuNumber];for(let i=0;i<cpu.slices.length;i++){const cpuSlice=cpu.slices[i];const thread=this.threadsByLinuxPid[cpuSlice.args.tid];if(!thread)continue;cpuSlice.threadThatWasRunning=thread;if(!thread.tempCpuSlices){thread.tempCpuSlices=[];}
 thread.tempCpuSlices.push(cpuSlice);}}
-for(var i in this.wakeups_){var wakeup=this.wakeups_[i];var thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
-for(var i in this.blockedReasons_){var reason=this.blockedReasons_[i];var thread=this.threadsByLinuxPid[reason.tid];if(!thread)continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
-this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)return;var origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});var wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});var reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});var slices=[];if(origSlices.length){var slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){var wakeup=wakeups.shift();var wakeupDuration=slice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
-var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
-var wakeup=undefined;for(var i=1;i<origSlices.length;i++){var prevSlice=origSlices[i-1];var nextSlice=origSlices[i];var midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){var w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
-var blockedReason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){var r=reasons.shift();}
+for(const i in this.wakeups_){const wakeup=this.wakeups_[i];const thread=this.threadsByLinuxPid[wakeup.tid];if(!thread)continue;thread.tempWakeups=thread.tempWakeups||[];thread.tempWakeups.push(wakeup);}
+for(const i in this.blockedReasons_){const reason=this.blockedReasons_[i];const thread=this.threadsByLinuxPid[reason.tid];if(!thread)continue;thread.tempBlockedReasons=thread.tempBlockedReasons||[];thread.tempBlockedReasons.push(reason);}
+this.model_.getAllThreads().forEach(function(thread){if(thread.tempCpuSlices===undefined)return;const origSlices=thread.tempCpuSlices;delete thread.tempCpuSlices;origSlices.sort(function(x,y){return x.start-y.start;});const wakeups=thread.tempWakeups||[];delete thread.tempWakeups;wakeups.sort(function(x,y){return x.ts-y.ts;});const reasons=thread.tempBlockedReasons||[];delete thread.tempBlockedReasons;reasons.sort(function(x,y){return x.ts-y.ts;});const slices=[];if(origSlices.length){const slice=origSlices[0];if(wakeups.length&&wakeups[0].ts<slice.start){const wakeup=wakeups.shift();const wakeupDuration=slice.start-wakeup.ts;const args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));}
+const runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',slice.start,{},slice.duration);runningSlice.cpuOnWhichThreadWasRunning=slice.cpu;slices.push(runningSlice);}
+let wakeup=undefined;for(let i=1;i<origSlices.length;i++){const prevSlice=origSlices[i-1];const nextSlice=origSlices[i];let midDuration=nextSlice.start-prevSlice.end;while(wakeups.length&&wakeups[0].ts<nextSlice.start){const w=wakeups.shift();if(wakeup===undefined&&w.ts>prevSlice.end){wakeup=w;}}
+let blockedReason=undefined;while(reasons.length&&reasons[0].ts<prevSlice.end){const r=reasons.shift();}
 if(wakeup!==undefined&&reasons.length&&reasons[0].ts<wakeup.ts){blockedReason=reasons.shift();}
-var pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
-if(blockedReason!==undefined){var args={'kernel callsite when blocked:':blockedReason.caller};if(blockedReason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
+const pushSleep=function(state){if(wakeup!==undefined){midDuration=wakeup.ts-prevSlice.end;}
+if(blockedReason!==undefined){const args={'kernel callsite when blocked:':blockedReason.caller};if(blockedReason.iowait){switch(state){case SCHEDULING_STATE.UNINTR_SLEEP:state=SCHEDULING_STATE.UNINTR_SLEEP_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;case SCHEDULING_STATE.UNINTR_SLEEP_WAKING:state=SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL_IO;break;default:}}
 slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,args,midDuration));}else{slices.push(new tr.model.ThreadTimeSlice(thread,state,'',prevSlice.end,{},midDuration));}
-if(wakeup!==undefined){var wakeupDuration=nextSlice.start-wakeup.ts;var args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled==='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled==='R'||prevSlice.args.stateWhenDescheduled==='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled==='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled==='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
+if(wakeup!==undefined){const wakeupDuration=nextSlice.start-wakeup.ts;const args={'wakeup from tid':wakeup.fromTid};slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',wakeup.ts,args,wakeupDuration));wakeup=undefined;}};if(prevSlice.args.stateWhenDescheduled==='S'){pushSleep(SCHEDULING_STATE.SLEEPING);}else if(prevSlice.args.stateWhenDescheduled==='R'||prevSlice.args.stateWhenDescheduled==='R+'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNABLE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP);}else if(prevSlice.args.stateWhenDescheduled==='T'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.STOPPED,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='t'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.DEBUG,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='Z'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.ZOMBIE,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='X'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.EXIT_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='x'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.TASK_DEAD,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='K'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKE_KILL,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='W'){slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.WAKING,'',prevSlice.end,{},midDuration));}else if(prevSlice.args.stateWhenDescheduled==='D|K'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKE_KILL);}else if(prevSlice.args.stateWhenDescheduled==='D|W'){pushSleep(SCHEDULING_STATE.UNINTR_SLEEP_WAKING);}else{slices.push(new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.UNKNOWN,'',prevSlice.end,{},midDuration));this.model_.importWarning({type:'parse_error',message:'Unrecognized sleep state: '+
 prevSlice.args.stateWhenDescheduled});}
-var runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
-thread.timeSlices=slices;},this);},createParsers_:function(){var allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();var parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_:function(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_:function(eventName,cpuNumber,pid,ts,eventBase){var event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){var name=event[1];var pieces=event[2].split(' ');var args={perfTs:ts};for(var i=0;i<pieces.length;i++){var parts=pieces[i].split('=');if(parts.length!==2){throw new Error('omgbbq');}
+const runningSlice=new tr.model.ThreadTimeSlice(thread,SCHEDULING_STATE.RUNNING,'',nextSlice.start,{},nextSlice.duration);runningSlice.cpuOnWhichThreadWasRunning=prevSlice.cpu;slices.push(runningSlice);}
+thread.timeSlices=slices;},this);},createParsers_(){const allTypeInfos=tr.e.importer.linux_perf.Parser.getAllRegisteredTypeInfos();const parsers=allTypeInfos.map(function(typeInfo){return new typeInfo.constructor(this);},this);return parsers;},registerDefaultHandlers_(){this.registerEventHandler('tracing_mark_write',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('0',FTraceImporter.prototype.traceMarkingWriteEvent_.bind(this));this.registerEventHandler('tracing_mark_write:trace_event_clock_sync',function(){return true;});this.registerEventHandler('0:trace_event_clock_sync',function(){return true;});},traceClockSyncEvent_(eventName,cpuNumber,pid,ts,eventBase){let event=/name=(\w+?)\s(.+)/.exec(eventBase.details);if(event){const name=event[1];const pieces=event[2].split(' ');const args={perfTs:ts};for(let i=0;i<pieces.length;i++){const parts=pieces[i].split('=');if(parts.length!==2){throw new Error('omgbbq');}
 args[parts[0]]=parts[1];}
-this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL,name,ts);return true;}
-var event=/name=([\w\-]+)/.exec(eventBase.details);if(event){this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL,event[1],ts);return true;}
-event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)return false;var monotonicTs=event[1]*1000;if(monotonicTs===0)monotonicTs=ts;if(this.haveClockSyncedMonotonicToGlobal_){return true;}
-this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_FTRACE_GLOBAL,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,ts);this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,monotonicTs);this.haveClockSyncedMonotonicToGlobal_=true;return true;},traceMarkingWriteEvent_:function(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');var event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){var tag=eventBase.details.substring(0,2);if(tag==='B|'||tag==='E'||tag==='E|'||tag==='X|'||tag==='C|'||tag==='S|'||tag==='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
-var writeEventName=eventName+':'+eventBase.subEventName;var handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
-return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importCpuData_:function(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){var eventName=eventBase.eventName;var handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
-ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_:function(){var lines=[];var extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok){extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);}
-var lines=extractResult.ok?extractResult.lines:this.events_.split('\n');var lineParser=undefined;for(var lineNumber=0;lineNumber<lines.length;++lineNumber){var line=lines[lineNumber].trim();if(line.length===0||/^#/.test(line))continue;if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});continue;}}
-var eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});continue;}
-this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);}},forEachLine_:function(handler){for(var i=0;i<this.lines_.length;++i){var line=this.lines_[i];handler.apply(this,line);}},lazyInit_:function(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter,_FTraceImporterTestExports:TestExports};});'use strict';function filterDuplicateTimestamps(timestamps){var dedupedTimestamps=[];var lastTs=0;for(var ts of timestamps){if(ts-lastTs>=1){dedupedTimestamps.push(ts);lastTs=ts;}}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,name,ts);return true;}
+event=/name=([\w\-]+)/.exec(eventBase.details);if(event){this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,event[1],ts);return true;}
+event=/parent_ts=(\d+\.?\d*)/.exec(eventBase.details);if(!event)return false;let monotonicTs=event[1]*1000;if(monotonicTs===0)monotonicTs=ts;if(this.haveClockSyncedMonotonicToGlobal_){return true;}
+this.model_.clockSyncManager.addClockSyncMarker(this.clockDomainId_,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,ts);this.model_.clockSyncManager.addClockSyncMarker(tr.model.ClockDomainId.LINUX_CLOCK_MONOTONIC,MONOTONIC_TO_FTRACE_GLOBAL_SYNC_ID,monotonicTs);this.haveClockSyncedMonotonicToGlobal_=true;return true;},traceMarkingWriteEvent_(eventName,cpuNumber,pid,ts,eventBase,threadName){eventBase.details=eventBase.details.replace(/\\n.*$/,'');const event=/^\s*(\w+):\s*(.*)$/.exec(eventBase.details);if(!event){const tag=eventBase.details.substring(0,2);if(tag==='B|'||tag==='E'||tag==='E|'||tag==='X|'||tag==='C|'||tag==='S|'||tag==='F|'){eventBase.subEventName='android';}else{return false;}}else{eventBase.subEventName=event[1];eventBase.details=event[2];}
+const writeEventName=eventName+':'+eventBase.subEventName;const handler=this.eventHandlers_[writeEventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown trace_marking_write event '+writeEventName});return true;}
+return handler(writeEventName,cpuNumber,pid,ts,eventBase,threadName);},importCpuData_(modelTimeTransformer){this.forEachLine_(function(text,eventBase,cpuNumber,pid,ts){const eventName=eventBase.eventName;const handler=this.eventHandlers_[eventName];if(!handler){this.model_.importWarning({type:'parse_error',message:'Unknown event '+eventName+' ('+text+')'});return;}
+ts=modelTimeTransformer(ts);if(!handler(eventName,cpuNumber,pid,ts,eventBase)){this.model_.importWarning({type:'parse_error',message:'Malformed '+eventName+' event ('+text+')'});}}.bind(this));},parseLines_(){let extractResult=FTraceImporter._extractEventsFromSystraceHTML(this.events_,true);if(!extractResult.ok){extractResult=FTraceImporter._extractEventsFromSystraceMultiHTML(this.events_,true);}
+let lineParser=undefined;if(extractResult.ok){for(const line of extractResult.lines){lineParser=this.parseLine_(line,lineParser);}}else{const r=new tr.importer.SimpleLineReader(this.events_);for(const line of r){lineParser=this.parseLine_(line,lineParser);}}},parseLine_(line,lineParser){line=line.trim();if(line.length===0)return lineParser;if(/^#/.test(line)){const clockType=/^# clock_type=([A-Z_]+)$/.exec(line);if(clockType){this.clockDomainId_=clockType[1];}
+return lineParser;}
+if(!lineParser){lineParser=autoDetectLineParser(line);if(!lineParser){this.model_.importWarning({type:'parse_error',message:'Cannot parse line: '+line});return lineParser;}}
+const eventBase=lineParser(line);if(!eventBase){this.model_.importWarning({type:'parse_error',message:'Unrecognized line: '+line});return lineParser;}
+this.lines_.push([line,eventBase,parseInt(eventBase.cpuNumber),parseInt(eventBase.pid),parseFloat(eventBase.timestamp)*1000]);return lineParser;},forEachLine_(handler){for(let i=0;i<this.lines_.length;++i){const line=this.lines_[i];handler.apply(this,line);}},lazyInit_(){this.parsers_=this.createParsers_();this.registerDefaultHandlers_();this.parseLines_();}};tr.importer.Importer.register(FTraceImporter);return{FTraceImporter,_FTraceImporterTestExports:TestExports};});'use strict';function filterDuplicateTimestamps(timestamps){const dedupedTimestamps=[];let lastTs=0;for(const ts of timestamps){if(ts-lastTs>=1){dedupedTimestamps.push(ts);lastTs=ts;}}
 return dedupedTimestamps;}
-tr.exportTo('tr.e.audits',function(){var VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};var VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};var BEGIN_FRAME_SLICE_PRECISION={'DisplayScheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);}
-VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate:function(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps:function(model){var times=[];var maxPrecision=Number.NEGATIVE_INFINITY;var maxTitle=undefined;function useInstead(title,precisions){var precision=precisions[title];if(precision===undefined)return false;if(title===maxTitle)return true;if(precision<=maxPrecision){if(precision===maxPrecision){model.importWarning({type:'VSyncAuditor',message:'Encountered two different VSync events ('+
+tr.exportTo('tr.e.audits',function(){const VSYNC_COUNTER_PRECISIONS={'android.VSYNC-app':15,'android.VSYNC':15};const VSYNC_SLICE_PRECISIONS={'RenderWidgetHostViewAndroid::OnVSync':5,'VSYNC':10,'vblank':10,'DisplayLinkMac::GetVSyncParameters':5};const BEGIN_FRAME_SLICE_PRECISION={'DisplayScheduler::BeginFrame':10};function VSyncAuditor(model){tr.c.Auditor.call(this,model);}
+VSyncAuditor.prototype={__proto__:tr.c.Auditor.prototype,runAnnotate(){this.model.device.vSyncTimestamps=this.findVSyncTimestamps(this.model);},findVSyncTimestamps(model){let times=[];let maxPrecision=Number.NEGATIVE_INFINITY;let maxTitle=undefined;function useInstead(title,precisions){const precision=precisions[title];if(precision===undefined)return false;if(title===maxTitle)return true;if(precision<=maxPrecision){if(precision===maxPrecision){model.importWarning({type:'VSyncAuditor',message:'Encountered two different VSync events ('+
 maxTitle+', '+title+') with the same precision, '+'ignoring the newer one ('+title+')',showToUser:false,});}
 return false;}
 maxPrecision=precision;maxTitle=title;times=[];return true;}
-for(var pid in model.processes){var process=model.processes[pid];for(var cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){var counter=process.counters[cid];for(var i=0;i<counter.series.length;i++){var series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
-for(var tid in process.threads){var thread=process.threads[tid];for(var i=0;i<thread.sliceGroup.slices.length;i++){var slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS)){times.push(slice.start);}else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us){times.push(slice.args.args.frame_time_us/1000.0);}}}}
+for(const pid in model.processes){const process=model.processes[pid];for(const cid in process.counters){if(useInstead(cid,VSYNC_COUNTER_PRECISIONS)){const counter=process.counters[cid];for(let i=0;i<counter.series.length;i++){const series=counter.series[i];Array.prototype.push.apply(times,series.timestamps);}}}
+for(const tid in process.threads){const thread=process.threads[tid];for(let i=0;i<thread.sliceGroup.slices.length;i++){const slice=thread.sliceGroup.slices[i];if(useInstead(slice.title,VSYNC_SLICE_PRECISIONS)){times.push(slice.start);}else if(useInstead(slice.title,BEGIN_FRAME_SLICE_PRECISION)&&slice.args.args&&slice.args.args.frame_time_us){times.push(slice.args.args.frame_time_us/1000.0);}}}}
 times.sort(function(x,y){return x-y;});return filterDuplicateTimestamps(times);}};tr.c.Auditor.register(VSyncAuditor);return{VSyncAuditor,};});'use strict';tr.exportTo('tr.importer',function(){function EmptyImporter(events){this.importPriority=0;}
 EmptyImporter.canImport=function(eventData){if(eventData instanceof Array&&eventData.length===0){return true;}
 if(typeof(eventData)==='string'||eventData instanceof String){return eventData.length===0;}
 return false;};EmptyImporter.prototype={__proto__:tr.importer.Importer.prototype,get importerName(){return'EmptyImporter';}};tr.importer.Importer.register(EmptyImporter);return{EmptyImporter,};});'use strict';tr.exportTo('tr.model.um',function(){function AnimationExpectation(parentModel,initiatorTitle,start,duration){tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.frameEvents_=undefined;}
 AnimationExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:AnimationExpectation,get frameEvents(){if(this.frameEvents_){return this.frameEvents_;}
 this.frameEvents_=new tr.model.EventSet();this.associatedEvents.forEach(function(event){if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){this.frameEvents_.push(event);}},this);return this.frameEvents_;}};tr.model.um.UserExpectation.subTypes.register(AnimationExpectation,{stageTitle:'Animation',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_animation')});return{AnimationExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function ProtoExpectation(type,initiatorType){this.type=type;this.initiatorType=initiatorType;this.start=Infinity;this.end=-Infinity;this.associatedEvents=new tr.model.EventSet();this.isAnimationBegin=false;}
-ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';var INITIATOR_HIERARCHY=[tr.model.um.INITIATOR_TYPE.PINCH,tr.model.um.INITIATOR_TYPE.FLING,tr.model.um.INITIATOR_TYPE.MOUSE_WHEEL,tr.model.um.INITIATOR_TYPE.SCROLL,tr.model.um.INITIATOR_TYPE.VIDEO,tr.model.um.INITIATOR_TYPE.WEBGL,tr.model.um.INITIATOR_TYPE.CSS,tr.model.um.INITIATOR_TYPE.MOUSE,tr.model.um.INITIATOR_TYPE.KEYBOARD,tr.model.um.INITIATOR_TYPE.TAP,tr.model.um.INITIATOR_TYPE.TOUCH];function combineInitiatorTypes(title1,title2){for(var item of INITIATOR_HIERARCHY){if(title1===item||title2===item)return item;}
+ProtoExpectation.RESPONSE_TYPE='r';ProtoExpectation.ANIMATION_TYPE='a';ProtoExpectation.IGNORED_TYPE='ignored';const INITIATOR_HIERARCHY=[tr.model.um.INITIATOR_TYPE.PINCH,tr.model.um.INITIATOR_TYPE.FLING,tr.model.um.INITIATOR_TYPE.MOUSE_WHEEL,tr.model.um.INITIATOR_TYPE.SCROLL,tr.model.um.INITIATOR_TYPE.VIDEO,tr.model.um.INITIATOR_TYPE.WEBGL,tr.model.um.INITIATOR_TYPE.CSS,tr.model.um.INITIATOR_TYPE.MOUSE,tr.model.um.INITIATOR_TYPE.KEYBOARD,tr.model.um.INITIATOR_TYPE.TAP,tr.model.um.INITIATOR_TYPE.TOUCH];function combineInitiatorTypes(title1,title2){for(const item of INITIATOR_HIERARCHY){if(title1===item||title2===item)return item;}
 throw new Error('Invalid titles in combineInitiatorTypes');}
-ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames:function(typeNames){return this.associatedEvents.some(x=>typeNames.indexOf(x.typeName)>=0);},containsSliceTitle:function(title){return this.associatedEvents.some(x=>title===x.title);},createInteractionRecord:function(model){if(this.type!==ProtoExpectation.IGNORED_TYPE&&!this.isValid){model.importWarning({type:'ProtoExpectation',message:'Please file a bug with this trace. '+this.debug(),showToUser:true});return undefined;}
-var duration=this.end-this.start;var ir=undefined;switch(this.type){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,this.initiatorType,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,this.initiatorType,this.start,duration);break;}
+ProtoExpectation.prototype={get isValid(){return this.end>this.start;},containsTypeNames(typeNames){return this.associatedEvents.some(x=>typeNames.indexOf(x.typeName)>=0);},containsSliceTitle(title){return this.associatedEvents.some(x=>title===x.title);},createInteractionRecord(model){if(this.type!==ProtoExpectation.IGNORED_TYPE&&!this.isValid){model.importWarning({type:'ProtoExpectation',message:'Please file a bug with this trace. '+this.debug(),showToUser:true});return undefined;}
+const duration=this.end-this.start;let ir=undefined;switch(this.type){case ProtoExpectation.RESPONSE_TYPE:ir=new tr.model.um.ResponseExpectation(model,this.initiatorType,this.start,duration,this.isAnimationBegin);break;case ProtoExpectation.ANIMATION_TYPE:ir=new tr.model.um.AnimationExpectation(model,this.initiatorType,this.start,duration);break;}
 if(!ir)return undefined;ir.sourceEvents.addEventSet(this.associatedEvents);function pushAssociatedEvents(event){ir.associatedEvents.push(event);if(event.associatedEvents){ir.associatedEvents.addEventSet(event.associatedEvents);}}
-this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices){event.subSlices.forEach(pushAssociatedEvents);}});return ir;},merge:function(other){this.initiatorType=combineInitiatorTypes(this.initiatorType,other.initiatorType);this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin){this.isAnimationBegin=true;}},pushEvent:function(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive:function(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects:function(other){return(other.start<this.end)&&(other.end>this.start);},isNear:function(event,threshold){return(this.end+threshold)>event.start;},debug:function(){var debugString=this.type+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation,};});'use strict';tr.exportTo('tr.importer',function(){var ProtoExpectation=tr.importer.ProtoExpectation;var INITIATOR_TYPE=tr.model.um.INITIATOR_TYPE;var INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;var KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];var MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];var MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];var MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];var TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];var PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];var FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];var TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];var SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];var ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);var RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';var PLAYBACK_EVENT_TITLE='VideoPlayback';var CSS_ANIMATION_TITLE='Animation';var INPUT_MERGE_THRESHOLD_MS=200;var ANIMATION_MERGE_THRESHOLD_MS=32;var MOUSE_WHEEL_THRESHOLD_MS=40;var MOUSE_MOVE_THRESHOLD_MS=40;function compareEvents(x,y){if(x.start!==y.start){return x.start-y.start;}
+this.associatedEvents.forEach(function(event){pushAssociatedEvents(event);if(event.subSlices){event.subSlices.forEach(pushAssociatedEvents);}});return ir;},merge(other){this.initiatorType=combineInitiatorTypes(this.initiatorType,other.initiatorType);this.associatedEvents.addEventSet(other.associatedEvents);this.start=Math.min(this.start,other.start);this.end=Math.max(this.end,other.end);if(other.isAnimationBegin){this.isAnimationBegin=true;}},pushEvent(event){this.start=Math.min(this.start,event.start);this.end=Math.max(this.end,event.end);this.associatedEvents.push(event);},containsTimestampInclusive(timestamp){return(this.start<=timestamp)&&(timestamp<=this.end);},intersects(other){return(other.start<this.end)&&(other.end>this.start);},isNear(event,threshold){return(this.end+threshold)>event.start;},debug(){let debugString=this.type+'(';debugString+=parseInt(this.start)+' ';debugString+=parseInt(this.end);this.associatedEvents.forEach(function(event){debugString+=' '+event.typeName;});return debugString+')';}};return{ProtoExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const ProtoExpectation=tr.importer.ProtoExpectation;const INITIATOR_TYPE=tr.model.um.INITIATOR_TYPE;const INPUT_TYPE=tr.e.cc.INPUT_EVENT_TYPE_NAMES;const KEYBOARD_TYPE_NAMES=[INPUT_TYPE.CHAR,INPUT_TYPE.KEY_DOWN_RAW,INPUT_TYPE.KEY_DOWN,INPUT_TYPE.KEY_UP];const MOUSE_RESPONSE_TYPE_NAMES=[INPUT_TYPE.CLICK,INPUT_TYPE.CONTEXT_MENU];const MOUSE_WHEEL_TYPE_NAMES=[INPUT_TYPE.MOUSE_WHEEL];const MOUSE_DRAG_TYPE_NAMES=[INPUT_TYPE.MOUSE_DOWN,INPUT_TYPE.MOUSE_MOVE,INPUT_TYPE.MOUSE_UP];const TAP_TYPE_NAMES=[INPUT_TYPE.TAP,INPUT_TYPE.TAP_CANCEL,INPUT_TYPE.TAP_DOWN];const PINCH_TYPE_NAMES=[INPUT_TYPE.PINCH_BEGIN,INPUT_TYPE.PINCH_END,INPUT_TYPE.PINCH_UPDATE];const FLING_TYPE_NAMES=[INPUT_TYPE.FLING_CANCEL,INPUT_TYPE.FLING_START];const TOUCH_TYPE_NAMES=[INPUT_TYPE.TOUCH_END,INPUT_TYPE.TOUCH_MOVE,INPUT_TYPE.TOUCH_START];const SCROLL_TYPE_NAMES=[INPUT_TYPE.SCROLL_BEGIN,INPUT_TYPE.SCROLL_END,INPUT_TYPE.SCROLL_UPDATE];const ALL_HANDLED_TYPE_NAMES=[].concat(KEYBOARD_TYPE_NAMES,MOUSE_RESPONSE_TYPE_NAMES,MOUSE_WHEEL_TYPE_NAMES,MOUSE_DRAG_TYPE_NAMES,PINCH_TYPE_NAMES,TAP_TYPE_NAMES,FLING_TYPE_NAMES,TOUCH_TYPE_NAMES,SCROLL_TYPE_NAMES);const RENDERER_FLING_TITLE='InputHandlerProxy::HandleGestureFling::started';const PLAYBACK_EVENT_TITLE='VideoPlayback';const CSS_ANIMATION_TITLE='Animation';const INPUT_MERGE_THRESHOLD_MS=200;const ANIMATION_MERGE_THRESHOLD_MS=32;const MOUSE_WHEEL_THRESHOLD_MS=40;const MOUSE_MOVE_THRESHOLD_MS=40;function compareEvents(x,y){if(x.start!==y.start){return x.start-y.start;}
 if(x.end!==y.end){return x.end-y.end;}
 if(x.guid&&y.guid){return x.guid-y.guid;}
 return 0;}
 function forEventTypesIn(events,typeNames,cb,opt_this){events.forEach(function(event){if(typeNames.indexOf(event.typeName)>=0){cb.call(opt_this,event);}});}
 function causedFrame(event){return event.associatedEvents.some(x=>x.title===tr.model.helpers.IMPL_RENDERING_STATS);}
-function getSortedFrameEventsByProcess(modelHelper){var frameEventsByPid={};for(var[pid,rendererHelper]of
+function getSortedFrameEventsByProcess(modelHelper){const frameEventsByPid={};for(const[pid,rendererHelper]of
 Object.entries(modelHelper.rendererHelpers)){frameEventsByPid[pid]=rendererHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds);}
 return frameEventsByPid;}
-function getSortedInputEvents(modelHelper){var inputEvents=[];var browserProcess=modelHelper.browserHelper.process;var mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');for(var slice of mainThread.asyncSliceGroup.getDescendantEvents()){if(!slice.isTopLevel)continue;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))continue;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end)){continue;}
+function getSortedInputEvents(modelHelper){const inputEvents=[];const browserProcess=modelHelper.browserHelper.process;const mainThread=browserProcess.findAtMostOneThreadNamed('CrBrowserMain');for(const slice of mainThread.asyncSliceGroup.getDescendantEvents()){if(!slice.isTopLevel)continue;if(!(slice instanceof tr.e.cc.InputLatencyAsyncSlice))continue;if(isNaN(slice.start)||isNaN(slice.duration)||isNaN(slice.end)){continue;}
 inputEvents.push(slice);}
 return inputEvents.sort(compareEvents);}
-function findProtoExpectations(modelHelper,sortedInputEvents){var protoExpectations=[];var handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations,handleWebGLAnimations,handleVideoAnimations];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents));});protoExpectations.sort(compareEvents);return protoExpectations;}
-function handleKeyboardEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.KEYBOARD);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
-function handleMouseResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
-function handleMouseWheelEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){var prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+function findProtoExpectations(modelHelper,sortedInputEvents){const protoExpectations=[];const handlers=[handleKeyboardEvents,handleMouseResponseEvents,handleMouseWheelEvents,handleMouseDragEvents,handleTapResponseEvents,handlePinchEvents,handleFlingEvents,handleTouchEvents,handleScrollEvents,handleCSSAnimations,handleWebGLAnimations,handleVideoAnimations];handlers.forEach(function(handler){protoExpectations.push.apply(protoExpectations,handler(modelHelper,sortedInputEvents));});protoExpectations.sort(compareEvents);return protoExpectations;}
+function handleKeyboardEvents(modelHelper,sortedInputEvents){const protoExpectations=[];forEventTypesIn(sortedInputEvents,KEYBOARD_TYPE_NAMES,function(event){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.KEYBOARD);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseResponseEvents(modelHelper,sortedInputEvents){const protoExpectations=[];forEventTypesIn(sortedInputEvents,MOUSE_RESPONSE_TYPE_NAMES,function(event){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);});return protoExpectations;}
+function handleMouseWheelEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;let prevEvent_=undefined;forEventTypesIn(sortedInputEvents,MOUSE_WHEEL_TYPE_NAMES,function(event){const prevEvent=prevEvent_;prevEvent_=event;if(currentPE&&(prevEvent.start+MOUSE_WHEEL_THRESHOLD_MS)>=event.start){if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 return;}
 currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE_WHEEL);currentPE.pushEvent(event);protoExpectations.push(currentPE);});return protoExpectations;}
-function handleMouseDragEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
-break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
+function handleMouseDragEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;let mouseDownEvent=undefined;forEventTypesIn(sortedInputEvents,MOUSE_DRAG_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.MOUSE_DOWN:if(causedFrame(event)){const pe=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);}else{mouseDownEvent=event;}
+break;case INPUT_TYPE.MOUSE_MOVE:if(!causedFrame(event)){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}else if(!currentPE||!currentPE.isNear(event,MOUSE_MOVE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);mouseDownEvent=undefined;}
 protoExpectations.push(currentPE);}else{if(currentPE.type===ProtoExpectation.ANIMATION_TYPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.MOUSE);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}
-break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){var pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+break;case INPUT_TYPE.MOUSE_UP:if(!mouseDownEvent){const pe=new ProtoExpectation(causedFrame(event)?ProtoExpectation.RESPONSE_TYPE:ProtoExpectation.IGNORED_TYPE,INITIATOR_TYPE.MOUSE);pe.pushEvent(event);protoExpectations.push(pe);break;}
 if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.MOUSE);if(mouseDownEvent){currentPE.associatedEvents.push(mouseDownEvent);}
 currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 mouseDownEvent=undefined;currentPE=undefined;break;}});if(mouseDownEvent){currentPE=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);currentPE.pushEvent(mouseDownEvent);protoExpectations.push(currentPE);}
 return protoExpectations;}
-function handleTapResponseEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+function handleTapResponseEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;forEventTypesIn(sortedInputEvents,TAP_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TAP_DOWN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;case INPUT_TYPE.TAP:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+currentPE=undefined;break;case INPUT_TYPE.TAP_CANCEL:if(!currentPE){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
 if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TAP);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 currentPE=undefined;break;}});return protoExpectations;}
-function handlePinchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;var modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
+function handlePinchEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;let sawFirstUpdate=false;const modelBounds=modelHelper.model.bounds;forEventTypesIn(sortedInputEvents,PINCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.PINCH_BEGIN:if(currentPE&&currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);break;}
 currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.PINCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.PINCH_UPDATE:if(!currentPE||((currentPE.type===ProtoExpectation.RESPONSE_TYPE)&&sawFirstUpdate)||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.PINCH);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstUpdate=true;}
-break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+break;case INPUT_TYPE.PINCH_END:if(currentPE){currentPE.pushEvent(event);}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
 currentPE=undefined;break;}});return protoExpectations;}
-function handleFlingEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
-var browserHelper=modelHelper.browserHelper;var flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+function handleFlingEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;function isRendererFling(event){return event.title===RENDERER_FLING_TITLE;}
+const browserHelper=modelHelper.browserHelper;const flingEvents=browserHelper.getAllAsyncSlicesMatching(isRendererFling);forEventTypesIn(sortedInputEvents,FLING_TYPE_NAMES,function(event){flingEvents.push(event);});flingEvents.sort(compareEvents);flingEvents.forEach(function(event){if(event.title===RENDERER_FLING_TITLE){if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 return;}
 switch(event.typeName){case INPUT_TYPE.FLING_START:if(currentPE){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: FlingStart',showToUser:true});currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.FLING);currentPE.pushEvent(event);currentPE.end=0;protoExpectations.push(currentPE);}
-break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+break;case INPUT_TYPE.FLING_CANCEL:if(currentPE){currentPE.pushEvent(event);currentPE.end=event.start;currentPE=undefined;}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
 break;}});if(currentPE&&!currentPE.end){currentPE.end=modelHelper.model.bounds.max;}
 return protoExpectations;}
-function handleTouchEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
+function handleTouchEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;let sawFirstMove=false;forEventTypesIn(sortedInputEvents,TOUCH_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.TOUCH_START:if(currentPE){currentPE.pushEvent(event);}else{currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstMove=false;}
 break;case INPUT_TYPE.TOUCH_MOVE:if(!currentPE){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);protoExpectations.push(currentPE);break;}
-if((sawFirstMove&&(currentPE.type===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){var prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
-break;case INPUT_TYPE.TOUCH_END:if(!currentPE){var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
-if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
+if((sawFirstMove&&(currentPE.type===ProtoExpectation.RESPONSE_TYPE))||!currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){const prevEnd=currentPE.end;currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.TOUCH);currentPE.pushEvent(event);currentPE.start=prevEnd;protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);sawFirstMove=true;}
+break;case INPUT_TYPE.TOUCH_END:if(!currentPE){const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)){currentPE.pushEvent(event);}else{const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);}
 currentPE=undefined;break;}});return protoExpectations;}
-function handleScrollEvents(modelHelper,sortedInputEvents){var protoExpectations=[];var currentPE=undefined;var sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.type===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
-break;case INPUT_TYPE.SCROLL_END:if(!currentPE){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: ScrollEnd',showToUser:true});var pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
+function handleScrollEvents(modelHelper,sortedInputEvents){const protoExpectations=[];let currentPE=undefined;let sawFirstUpdate=false;forEventTypesIn(sortedInputEvents,SCROLL_TYPE_NAMES,function(event){switch(event.typeName){case INPUT_TYPE.SCROLL_BEGIN:currentPE=new ProtoExpectation(ProtoExpectation.RESPONSE_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);currentPE.isAnimationBegin=true;protoExpectations.push(currentPE);sawFirstUpdate=false;break;case INPUT_TYPE.SCROLL_UPDATE:if(currentPE){if(currentPE.isNear(event,INPUT_MERGE_THRESHOLD_MS)&&((currentPE.type===ProtoExpectation.ANIMATION_TYPE)||!sawFirstUpdate)){currentPE.pushEvent(event);sawFirstUpdate=true;}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}}else{currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.SCROLL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+break;case INPUT_TYPE.SCROLL_END:if(!currentPE){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: ScrollEnd',showToUser:true});const pe=new ProtoExpectation(ProtoExpectation.IGNORED_TYPE);pe.pushEvent(event);protoExpectations.push(pe);break;}
 currentPE.pushEvent(event);break;}});return protoExpectations;}
-function handleVideoAnimations(modelHelper,sortedInputEvents){var events=[];for(var pid in modelHelper.rendererHelpers){for(var tid in modelHelper.rendererHelpers[pid].process.threads){for(var asyncSlice of
+function handleVideoAnimations(modelHelper,sortedInputEvents){const events=[];for(const pid in modelHelper.rendererHelpers){for(const tid in modelHelper.rendererHelpers[pid].process.threads){for(const asyncSlice of
 modelHelper.rendererHelpers[pid].process.threads[tid].asyncSliceGroup.slices){if(asyncSlice.title===PLAYBACK_EVENT_TITLE){events.push(asyncSlice);}}}}
-events.sort(tr.importer.compareEvents);var protoExpectations=[];for(var event of events){var currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.VIDEO);currentPE.start=event.start;currentPE.end=event.end;currentPE.pushEvent(event);protoExpectations.push(currentPE);}
+events.sort(tr.importer.compareEvents);const protoExpectations=[];for(const event of events){const currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.VIDEO);currentPE.start=event.start;currentPE.end=event.end;currentPE.pushEvent(event);protoExpectations.push(currentPE);}
 return protoExpectations;}
-function handleCSSAnimations(modelHelper,sortedInputEvents){var animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});var animationRanges=[];function pushAnimationRange(start,end,animation){var range=tr.b.math.Range.fromExplicitRange(start,end);range.animation=animation;animationRanges.push(range);}
-animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{var start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.data.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.data.state==='paused')||(sub.args.data.state==='idle')||(sub.args.data.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
-pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined){pushAnimationRange(start,animation.end,animation);}}});return animationRanges.map(function(range){var protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.CSS);protoExpectation.start=range.min;protoExpectation.end=range.max;protoExpectation.associatedEvents.push(range.animation);return protoExpectation;});}
-function findWebGLEvents(modelHelper,mailboxEvents,animationEvents){for(var event of modelHelper.model.getDescendantEvents()){if(event.title==='DrawingBuffer::prepareMailbox'){mailboxEvents.push(event);}else if(event.title==='PageAnimator::serviceScriptedAnimations'){animationEvents.push(event);}}}
-function findMailboxEventsNearAnimationEvents(mailboxEvents,animationEvents){if(animationEvents.length===0)return[];mailboxEvents.sort(compareEvents);animationEvents.sort(compareEvents);var animationIterator=animationEvents[Symbol.iterator]();var animationEvent=animationIterator.next().value;var filteredEvents=[];for(var event of mailboxEvents){while(animationEvent&&(animationEvent.start<(event.start-ANIMATION_MERGE_THRESHOLD_MS))){animationEvent=animationIterator.next().value;}
+function handleCSSAnimations(modelHelper,sortedInputEvents){const animationEvents=modelHelper.browserHelper.getAllAsyncSlicesMatching(function(event){return((event.title===CSS_ANIMATION_TITLE)&&event.isTopLevel&&(event.duration>0));});const animationRanges=[];function pushAnimationRange(start,end,animation){const range=tr.b.math.Range.fromExplicitRange(start,end);range.animation=animation;animationRanges.push(range);}
+animationEvents.forEach(function(animation){if(animation.subSlices.length===0){pushAnimationRange(animation.start,animation.end,animation);}else{let start=undefined;animation.subSlices.forEach(function(sub){if((sub.args.data.state==='running')&&(start===undefined)){start=sub.start;}else if((sub.args.data.state==='paused')||(sub.args.data.state==='idle')||(sub.args.data.state==='finished')){if(start===undefined){start=modelHelper.model.bounds.min;}
+pushAnimationRange(start,sub.start,animation);start=undefined;}});if(start!==undefined){pushAnimationRange(start,animation.end,animation);}}});return animationRanges.map(function(range){const protoExpectation=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.CSS);protoExpectation.start=range.min;protoExpectation.end=range.max;protoExpectation.associatedEvents.push(range.animation);return protoExpectation;});}
+function findWebGLEvents(modelHelper,mailboxEvents,animationEvents){for(const event of modelHelper.model.getDescendantEvents()){if(event.title==='DrawingBuffer::prepareMailbox'){mailboxEvents.push(event);}else if(event.title==='PageAnimator::serviceScriptedAnimations'){animationEvents.push(event);}}}
+function findMailboxEventsNearAnimationEvents(mailboxEvents,animationEvents){if(animationEvents.length===0)return[];mailboxEvents.sort(compareEvents);animationEvents.sort(compareEvents);const animationIterator=animationEvents[Symbol.iterator]();let animationEvent=animationIterator.next().value;const filteredEvents=[];for(const event of mailboxEvents){while(animationEvent&&(animationEvent.start<(event.start-ANIMATION_MERGE_THRESHOLD_MS))){animationEvent=animationIterator.next().value;}
 if(!animationEvent)break;if(animationEvent.start<(event.start+ANIMATION_MERGE_THRESHOLD_MS)){filteredEvents.push(event);}}
 return filteredEvents;}
-function createProtoExpectationsFromMailboxEvents(mailboxEvents){var protoExpectations=[];var currentPE=undefined;for(var event of mailboxEvents){if(currentPE===undefined||!currentPE.isNear(event,ANIMATION_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.WEBGL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);}}
+function createProtoExpectationsFromMailboxEvents(mailboxEvents){const protoExpectations=[];let currentPE=undefined;for(const event of mailboxEvents){if(currentPE===undefined||!currentPE.isNear(event,ANIMATION_MERGE_THRESHOLD_MS)){currentPE=new ProtoExpectation(ProtoExpectation.ANIMATION_TYPE,INITIATOR_TYPE.WEBGL);currentPE.pushEvent(event);protoExpectations.push(currentPE);}else{currentPE.pushEvent(event);}}
 return protoExpectations;}
-function handleWebGLAnimations(modelHelper,sortedInputEvents){var prepareMailboxEvents=[];var scriptedAnimationEvents=[];findWebGLEvents(modelHelper,prepareMailboxEvents,scriptedAnimationEvents);var webGLMailboxEvents=findMailboxEventsNearAnimationEvents(prepareMailboxEvents,scriptedAnimationEvents);return createProtoExpectationsFromMailboxEvents(webGLMailboxEvents);}
+function handleWebGLAnimations(modelHelper,sortedInputEvents){const prepareMailboxEvents=[];const scriptedAnimationEvents=[];findWebGLEvents(modelHelper,prepareMailboxEvents,scriptedAnimationEvents);const webGLMailboxEvents=findMailboxEventsNearAnimationEvents(prepareMailboxEvents,scriptedAnimationEvents);return createProtoExpectationsFromMailboxEvents(webGLMailboxEvents);}
 function postProcessProtoExpectations(modelHelper,protoExpectations){protoExpectations=findFrameEventsForAnimations(modelHelper,protoExpectations);protoExpectations=mergeIntersectingResponses(protoExpectations);protoExpectations=mergeIntersectingAnimations(protoExpectations);protoExpectations=fixResponseAnimationStarts(protoExpectations);protoExpectations=fixTapResponseTouchAnimations(protoExpectations);return protoExpectations;}
-function mergeIntersectingResponses(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.RESPONSE_TYPE)continue;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if(!otherPE.intersects(pe))continue;var typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+function mergeIntersectingResponses(protoExpectations){const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.RESPONSE_TYPE)continue;for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if(!otherPE.intersects(pe))continue;const typeNames=pe.associatedEvents.map(function(event){return event.typeName;});if(otherPE.containsTypeNames(typeNames))continue;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
 return newPEs;}
-function mergeIntersectingAnimations(protoExpectations){var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.ANIMATION_TYPE)continue;var isCSS=pe.initiatorType===INITIATOR_TYPE.CSS;var isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);var isVideo=pe.initiatorType===INITIATOR_TYPE.VIDEO;for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if((isCSS&&otherPE.initiatorType!==INITIATOR_TYPE.CSS)||isFling!==otherPE.containsTypeNames([INPUT_TYPE.FLING_START])||isVideo&&otherPE.initiatorType!==INITIATOR_TYPE.VIDEO){continue;}
+function mergeIntersectingAnimations(protoExpectations){const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);if(pe.type!==ProtoExpectation.ANIMATION_TYPE)continue;const isCSS=pe.initiatorType===INITIATOR_TYPE.CSS;const isFling=pe.containsTypeNames([INPUT_TYPE.FLING_START]);const isVideo=pe.initiatorType===INITIATOR_TYPE.VIDEO;for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(otherPE.type!==pe.type)continue;if((isCSS&&otherPE.initiatorType!==INITIATOR_TYPE.CSS)||isFling!==otherPE.containsTypeNames([INPUT_TYPE.FLING_START])||isVideo&&otherPE.initiatorType!==INITIATOR_TYPE.VIDEO){continue;}
 if(isCSS){if(!pe.isNear(otherPE,ANIMATION_MERGE_THRESHOLD_MS)){continue;}}else if(!otherPE.intersects(pe)){continue;}
 pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
 return newPEs;}
@@ -5934,159 +6260,153 @@
 ape.start=rpe.end;});});return protoExpectations;}
 function fixTapResponseTouchAnimations(protoExpectations){function isTapResponse(pe){return(pe.type===ProtoExpectation.RESPONSE_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TAP]);}
 function isTouchAnimation(pe){return(pe.type===ProtoExpectation.ANIMATION_TYPE)&&pe.containsTypeNames([INPUT_TYPE.TOUCH_MOVE])&&!pe.containsTypeNames([INPUT_TYPE.SCROLL_UPDATE,INPUT_TYPE.PINCH_UPDATE]);}
-var newPEs=[];while(protoExpectations.length){var pe=protoExpectations.shift();newPEs.push(pe);var peIsTapResponse=isTapResponse(pe);var peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation){continue;}
-for(var i=0;i<protoExpectations.length;++i){var otherPE=protoExpectations[i];if(!otherPE.intersects(pe))continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))continue;pe.type=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
+const newPEs=[];while(protoExpectations.length){const pe=protoExpectations.shift();newPEs.push(pe);const peIsTapResponse=isTapResponse(pe);const peIsTouchAnimation=isTouchAnimation(pe);if(!peIsTapResponse&&!peIsTouchAnimation){continue;}
+for(let i=0;i<protoExpectations.length;++i){const otherPE=protoExpectations[i];if(!otherPE.intersects(pe))continue;if(peIsTapResponse&&!isTouchAnimation(otherPE))continue;if(peIsTouchAnimation&&!isTapResponse(otherPE))continue;pe.type=ProtoExpectation.RESPONSE_TYPE;pe.merge(otherPE);protoExpectations.splice(i,1);--i;}}
 return newPEs;}
-function findFrameEventsForAnimations(modelHelper,protoExpectations){var newPEs=[];var frameEventsByPid=getSortedFrameEventsByProcess(modelHelper);for(var pe of protoExpectations){if(pe.type!==ProtoExpectation.ANIMATION_TYPE){newPEs.push(pe);continue;}
-var frameEvents=[];for(var pid of Object.keys(modelHelper.rendererHelpers)){var range=tr.b.math.Range.fromExplicitRange(pe.start,pe.end);frameEvents.push.apply(frameEvents,range.filterArray(frameEventsByPid[pid],e=>e.start));}
+function findFrameEventsForAnimations(modelHelper,protoExpectations){const newPEs=[];const frameEventsByPid=getSortedFrameEventsByProcess(modelHelper);for(const pe of protoExpectations){if(pe.type!==ProtoExpectation.ANIMATION_TYPE){newPEs.push(pe);continue;}
+const frameEvents=[];for(const pid of Object.keys(modelHelper.rendererHelpers)){const range=tr.b.math.Range.fromExplicitRange(pe.start,pe.end);frameEvents.push.apply(frameEvents,range.filterArray(frameEventsByPid[pid],e=>e.start));}
 if(frameEvents.length===0&&!(pe.initiatorType===INITIATOR_TYPE.WEBGL)){pe.type=ProtoExpectation.IGNORED_TYPE;newPEs.push(pe);continue;}
 pe.associatedEvents.addEventSet(frameEvents);newPEs.push(pe);}
 return newPEs;}
-function checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations){var handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0)){return;}
-if((handledEvents.indexOf(event)>=0)&&(event.title!==tr.model.helpers.IMPL_RENDERING_STATS)){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: '+`double-handled event:${event.typeName}@${event.start}`,showToUser:true});return;}
-handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: '+`double-handled event:${event.typeName}@${event.start}`,showToUser:true});}});}
-function findInputExpectations(modelHelper){var sortedInputEvents=getSortedInputEvents(modelHelper);var protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents);protoExpectations=postProcessProtoExpectations(modelHelper,protoExpectations);checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations);var expectations=[];protoExpectations.forEach(function(protoExpectation){var ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir){expectations.push(ir);}});return expectations;}
-return{findInputExpectations,compareEvents,CSS_ANIMATION_TITLE,INITIATOR_TYPE};});'use strict';tr.exportTo('tr.model.um',function(){var LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',};var DOES_LOAD_SUBTYPE_NAME_EXIST={};for(var key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;}
+function checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations){const handledEvents=[];protoExpectations.forEach(function(protoExpectation){protoExpectation.associatedEvents.forEach(function(event){if((event.title===CSS_ANIMATION_TITLE)&&(event.subSlices.length>0)){return;}
+if((handledEvents.indexOf(event)>=0)&&(event.title!==tr.model.helpers.IMPL_RENDERING_STATS)){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: '+`double-handled event: ${event.typeName} @ ${event.start}`,showToUser:true});return;}
+handledEvents.push(event);});});sortedInputEvents.forEach(function(event){if(handledEvents.indexOf(event)<0){modelHelper.model.importWarning({type:'UserModelBuilder',message:'Please file a bug with this trace: '+`double-handled event: ${event.typeName} @ ${event.start}`,showToUser:true});}});}
+function findInputExpectations(modelHelper){const sortedInputEvents=getSortedInputEvents(modelHelper);let protoExpectations=findProtoExpectations(modelHelper,sortedInputEvents);protoExpectations=postProcessProtoExpectations(modelHelper,protoExpectations);checkAllInputEventsHandled(modelHelper,sortedInputEvents,protoExpectations);const expectations=[];protoExpectations.forEach(function(protoExpectation){const ir=protoExpectation.createInteractionRecord(modelHelper.model);if(ir){expectations.push(ir);}});return expectations;}
+return{findInputExpectations,compareEvents,CSS_ANIMATION_TITLE,};});'use strict';tr.exportTo('tr.model.um',function(){const LOAD_SUBTYPE_NAMES={SUCCESSFUL:'Successful',FAILED:'Failed',};const DOES_LOAD_SUBTYPE_NAME_EXIST={};for(const key in LOAD_SUBTYPE_NAMES){DOES_LOAD_SUBTYPE_NAME_EXIST[LOAD_SUBTYPE_NAMES[key]]=true;}
 function LoadExpectation(parentModel,initiatorTitle,start,duration){if(!DOES_LOAD_SUBTYPE_NAME_EXIST[initiatorTitle]){throw new Error(initiatorTitle+' is not in LOAD_SUBTYPE_NAMES');}
 tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);this.renderProcess=undefined;this.renderMainThread=undefined;this.routingId=undefined;this.parentRoutingId=undefined;this.loadFinishedEvent=undefined;}
-LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.subTypes.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES,LoadExpectation,};});'use strict';tr.exportTo('tr.importer',function(){var NAVIGATION_START='NavigationTiming navigationStart';var FIRST_CONTENTFUL_PAINT_TITLE='firstContentfulPaint';function findLoadExpectations(modelHelper){var events=[];for(var event of modelHelper.model.getDescendantEvents()){if((event.title===NAVIGATION_START)||(event.title===FIRST_CONTENTFUL_PAINT_TITLE)){events.push(event);}}
-events.sort(tr.importer.compareEvents);var loads=[];var startEvent=undefined;for(var event of events){if(event.title===NAVIGATION_START){startEvent=event;}else if(event.title===FIRST_CONTENTFUL_PAINT_TITLE){if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,event.start-startEvent.start));startEvent=undefined;}}}
+LoadExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:LoadExpectation};tr.model.um.UserExpectation.subTypes.register(LoadExpectation,{stageTitle:'Load',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_load')});return{LOAD_SUBTYPE_NAMES,LoadExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const NAVIGATION_START='NavigationTiming navigationStart';const FIRST_CONTENTFUL_PAINT_TITLE='firstContentfulPaint';function findLoadExpectations(modelHelper){const events=[];for(const event of modelHelper.model.getDescendantEvents()){if((event.title===NAVIGATION_START)||(event.title===FIRST_CONTENTFUL_PAINT_TITLE)){events.push(event);}}
+events.sort(tr.importer.compareEvents);const loads=[];let startEvent=undefined;for(const event of events){if(event.title===NAVIGATION_START){startEvent=event;}else if(event.title===FIRST_CONTENTFUL_PAINT_TITLE){if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,event.start-startEvent.start));startEvent=undefined;}}}
 if(startEvent){loads.push(new tr.model.um.LoadExpectation(modelHelper.model,tr.model.um.LOAD_SUBTYPE_NAMES.SUCCESSFUL,startEvent.start,modelHelper.model.bounds.max-startEvent.start));}
 return loads;}
 return{findLoadExpectations,};});'use strict';tr.exportTo('tr.model.um',function(){function StartupExpectation(parentModel,start,duration){tr.model.um.UserExpectation.call(this,parentModel,'',start,duration);}
-StartupExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:StartupExpectation};tr.model.um.UserExpectation.subTypes.register(StartupExpectation,{stageTitle:'Startup',colorId:tr.b.ColorScheme.getColorIdForReservedName('startup')});return{StartupExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function getAllFrameEvents(modelHelper){var frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));for(var renderer of Object.values(modelHelper.rendererHelpers)){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));}
+StartupExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:StartupExpectation};tr.model.um.UserExpectation.subTypes.register(StartupExpectation,{stageTitle:'Startup',colorId:tr.b.ColorScheme.getColorIdForReservedName('startup')});return{StartupExpectation,};});'use strict';tr.exportTo('tr.importer',function(){function getAllFrameEvents(modelHelper){const frameEvents=[];frameEvents.push.apply(frameEvents,modelHelper.browserHelper.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));for(const renderer of Object.values(modelHelper.rendererHelpers)){frameEvents.push.apply(frameEvents,renderer.getFrameEventsInRange(tr.model.helpers.IMPL_FRAMETIME_TYPE,modelHelper.model.bounds));}
 return frameEvents.sort(tr.importer.compareEvents);}
 function getStartupEvents(modelHelper){function isStartupSlice(slice){return slice.title==='BrowserMainLoop::CreateThreads';}
-var events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);var deduper=new tr.model.EventSet();events.forEach(function(event){var sliceGroup=event.parentContainer.sliceGroup;var slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice){deduper.push(slice);}});return deduper.toArray();}
-function findStartupExpectations(modelHelper){var openingEvents=getStartupEvents(modelHelper);var closingEvents=getAllFrameEvents(modelHelper);var startups=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)return;if(closingEvent.openingEvent)return;if(closingEvent.start<=openingEvent.start)return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid){return;}
-openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;var se=new tr.model.um.StartupExpectation(modelHelper.model,openingEvent.start,closingEvent.end-openingEvent.start);se.associatedEvents.push(openingEvent);se.associatedEvents.push(closingEvent);startups.push(se);});});return startups;}
-return{findStartupExpectations,};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){var allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
-function getUnassociatedEvents(model,associatedEvents){var unassociatedEvents=new tr.model.EventSet();for(var proc of model.getAllProcesses()){for(var thread of tr.b.dictionaryValues(proc.threads)){for(var event of thread.sliceGroup.getDescendantEvents()){if(!associatedEvents.contains(event)){unassociatedEvents.push(event);}}}}
+const events=modelHelper.browserHelper.getAllAsyncSlicesMatching(isStartupSlice);const deduper=new tr.model.EventSet();events.forEach(function(event){const sliceGroup=event.parentContainer.sliceGroup;const slice=sliceGroup&&sliceGroup.findFirstSlice();if(slice){deduper.push(slice);}});return deduper.toArray();}
+function findStartupExpectations(modelHelper){const openingEvents=getStartupEvents(modelHelper);const closingEvents=getAllFrameEvents(modelHelper);const startups=[];openingEvents.forEach(function(openingEvent){closingEvents.forEach(function(closingEvent){if(openingEvent.closingEvent)return;if(closingEvent.openingEvent)return;if(closingEvent.start<=openingEvent.start)return;if(openingEvent.parentContainer.parent.pid!==closingEvent.parentContainer.parent.pid){return;}
+openingEvent.closingEvent=closingEvent;closingEvent.openingEvent=openingEvent;const se=new tr.model.um.StartupExpectation(modelHelper.model,openingEvent.start,closingEvent.end-openingEvent.start);se.associatedEvents.push(openingEvent);se.associatedEvents.push(closingEvent);startups.push(se);});});return startups;}
+return{findStartupExpectations,};});'use strict';tr.exportTo('tr.model',function(){function getAssociatedEvents(irs){const allAssociatedEvents=new tr.model.EventSet();irs.forEach(function(ir){ir.associatedEvents.forEach(function(event){if(event instanceof tr.model.FlowEvent)return;allAssociatedEvents.push(event);});});return allAssociatedEvents;}
+function getUnassociatedEvents(model,associatedEvents){const unassociatedEvents=new tr.model.EventSet();for(const proc of model.getAllProcesses()){for(const thread of Object.values(proc.threads)){for(const event of thread.sliceGroup.getDescendantEvents()){if(!associatedEvents.contains(event)){unassociatedEvents.push(event);}}}}
 return unassociatedEvents;}
-function getTotalCpuDuration(events){var cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}
-function getIRCoverageFromModel(model){var associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)return undefined;var unassociatedEvents=getUnassociatedEvents(model,associatedEvents);var associatedCpuMs=getTotalCpuDuration(associatedEvents);var unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);var totalEventCount=associatedEvents.length+unassociatedEvents.length;var totalCpuMs=associatedCpuMs+unassociatedCpuMs;var coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0){coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;}
-return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio:coveredEventsCpuTimeRatio};}
-return{getIRCoverageFromModel,getAssociatedEvents,getUnassociatedEvents,};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){var initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
-IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.subTypes.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation,};});'use strict';tr.exportTo('tr.importer',function(){var INSIGNIFICANT_MS=1;class UserModelBuilder{constructor(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}
+function getTotalCpuDuration(events){let cpuMs=0;events.forEach(function(event){if(event.cpuSelfTime){cpuMs+=event.cpuSelfTime;}});return cpuMs;}
+function getIRCoverageFromModel(model){const associatedEvents=getAssociatedEvents(model.userModel.expectations);if(!associatedEvents.length)return undefined;const unassociatedEvents=getUnassociatedEvents(model,associatedEvents);const associatedCpuMs=getTotalCpuDuration(associatedEvents);const unassociatedCpuMs=getTotalCpuDuration(unassociatedEvents);const totalEventCount=associatedEvents.length+unassociatedEvents.length;const totalCpuMs=associatedCpuMs+unassociatedCpuMs;let coveredEventsCpuTimeRatio=undefined;if(totalCpuMs!==0){coveredEventsCpuTimeRatio=associatedCpuMs/totalCpuMs;}
+return{associatedEventsCount:associatedEvents.length,unassociatedEventsCount:unassociatedEvents.length,associatedEventsCpuTimeMs:associatedCpuMs,unassociatedEventsCpuTimeMs:unassociatedCpuMs,coveredEventsCountRatio:associatedEvents.length/totalEventCount,coveredEventsCpuTimeRatio};}
+return{getIRCoverageFromModel,getAssociatedEvents,getUnassociatedEvents,};});'use strict';tr.exportTo('tr.model.um',function(){function IdleExpectation(parentModel,start,duration){const initiatorTitle='';tr.model.um.UserExpectation.call(this,parentModel,initiatorTitle,start,duration);}
+IdleExpectation.prototype={__proto__:tr.model.um.UserExpectation.prototype,constructor:IdleExpectation};tr.model.um.UserExpectation.subTypes.register(IdleExpectation,{stageTitle:'Idle',colorId:tr.b.ColorScheme.getColorIdForReservedName('rail_idle')});return{IdleExpectation,};});'use strict';tr.exportTo('tr.importer',function(){const INSIGNIFICANT_MS=1;class UserModelBuilder{constructor(model){this.model=model;this.modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}
 static supportsModelHelper(modelHelper){return modelHelper.browserHelper!==undefined;}
-buildUserModel(){if(!this.modelHelper||!this.modelHelper.browserHelper)return;try{for(var ue of this.findUserExpectations()){this.model.userModel.expectations.push(ue);}
+buildUserModel(){if(!this.modelHelper||!this.modelHelper.browserHelper)return;try{for(const ue of this.findUserExpectations()){this.model.userModel.expectations.push(ue);}
 this.model.userModel.segments.push(...this.findSegments());}catch(error){this.model.importWarning({type:'UserModelBuilder',message:error,showToUser:true});}}
-findSegments(){var timestamps=new Set();for(var expectation of this.model.userModel.expectations){timestamps.add(expectation.start);timestamps.add(expectation.end);}
-timestamps=[...timestamps];timestamps.sort((x,y)=>x-y);var segments=[];for(var i=0;i<timestamps.length-1;++i){var segment=new tr.model.um.Segment(timestamps[i],timestamps[i+1]-timestamps[i]);segments.push(segment);var segmentRange=tr.b.math.Range.fromExplicitRange(segment.start,segment.end);for(var expectation of this.model.userModel.expectations){var expectationRange=tr.b.math.Range.fromExplicitRange(expectation.start,expectation.end);if(segmentRange.intersectsRangeExclusive(expectationRange)){segment.expectations.push(expectation);}}}
+findSegments(){let timestamps=new Set();for(const expectation of this.model.userModel.expectations){timestamps.add(expectation.start);timestamps.add(expectation.end);}
+timestamps=[...timestamps];timestamps.sort((x,y)=>x-y);const segments=[];for(let i=0;i<timestamps.length-1;++i){const segment=new tr.model.um.Segment(timestamps[i],timestamps[i+1]-timestamps[i]);segments.push(segment);const segmentRange=tr.b.math.Range.fromExplicitRange(segment.start,segment.end);for(const expectation of this.model.userModel.expectations){const expectationRange=tr.b.math.Range.fromExplicitRange(expectation.start,expectation.end);if(segmentRange.intersectsRangeExclusive(expectationRange)){segment.expectations.push(expectation);}}}
 return segments;}
-findUserExpectations(){var expectations=[];expectations.push.apply(expectations,tr.importer.findStartupExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;}
-collectUnassociatedEvents_(expectations){var vacuumUEs=[];for(var expectation of expectations){if(expectation instanceof tr.model.um.IdleExpectation||expectation instanceof tr.model.um.LoadExpectation||expectation instanceof tr.model.um.StartupExpectation){vacuumUEs.push(expectation);}}
-if(vacuumUEs.length===0)return;var allAssociatedEvents=tr.model.getAssociatedEvents(expectations);var unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);for(var event of unassociatedEvents){if(!(event instanceof tr.model.ThreadSlice))continue;if(!event.isTopLevel)continue;for(var index=0;index<vacuumUEs.length;++index){var expectation=vacuumUEs[index];if((event.start>=expectation.start)&&(event.start<expectation.end)){expectation.associatedEvents.addEventSet(event.entireHierarchy);break;}}}}
-findIdleExpectations(otherUEs){if(this.model.bounds.isEmpty)return;var emptyRanges=tr.b.math.findEmptyRangesBetweenRanges(tr.b.math.convertEventsToRanges(otherUEs),this.model.bounds);var expectations=[];var model=this.model;for(var range of emptyRanges){if(range.max<(range.min+INSIGNIFICANT_MS))continue;expectations.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));}
+findUserExpectations(){const expectations=[];expectations.push.apply(expectations,tr.importer.findStartupExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findLoadExpectations(this.modelHelper));expectations.push.apply(expectations,tr.importer.findInputExpectations(this.modelHelper));expectations.push.apply(expectations,this.findIdleExpectations(expectations));this.collectUnassociatedEvents_(expectations);return expectations;}
+collectUnassociatedEvents_(expectations){const vacuumUEs=[];for(const expectation of expectations){if(expectation instanceof tr.model.um.IdleExpectation||expectation instanceof tr.model.um.LoadExpectation||expectation instanceof tr.model.um.StartupExpectation){vacuumUEs.push(expectation);}}
+if(vacuumUEs.length===0)return;const allAssociatedEvents=tr.model.getAssociatedEvents(expectations);const unassociatedEvents=tr.model.getUnassociatedEvents(this.model,allAssociatedEvents);for(const event of unassociatedEvents){if(!(event instanceof tr.model.ThreadSlice))continue;if(!event.isTopLevel)continue;for(let index=0;index<vacuumUEs.length;++index){const expectation=vacuumUEs[index];if((event.start>=expectation.start)&&(event.start<expectation.end)){expectation.associatedEvents.addEventSet(event.entireHierarchy);break;}}}}
+findIdleExpectations(otherUEs){if(this.model.bounds.isEmpty)return;const emptyRanges=tr.b.math.findEmptyRangesBetweenRanges(tr.b.math.convertEventsToRanges(otherUEs),this.model.bounds);const expectations=[];const model=this.model;for(const range of emptyRanges){if(range.max<(range.min+INSIGNIFICANT_MS))continue;expectations.push(new tr.model.um.IdleExpectation(model,range.min,range.max-range.min));}
 return expectations;}}
-function createCustomizeModelLinesFromModel(model){var modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');var typeNames={};for(var typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
-var modelEvents=new tr.model.EventSet();for(var ue of model.userModel.expectations){modelEvents.addEventSet(ue.sourceEvents);}
-modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);for(var event of modelEvents){var startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
+function createCustomizeModelLinesFromModel(model){const modelLines=[];modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {title: \'model start\', start: 0, end: 1});');const typeNames={};for(const typeName in tr.e.cc.INPUT_EVENT_TYPE_NAMES){typeNames[tr.e.cc.INPUT_EVENT_TYPE_NAMES[typeName]]=typeName;}
+let modelEvents=new tr.model.EventSet();for(const ue of model.userModel.expectations){modelEvents.addEventSet(ue.sourceEvents);}
+modelEvents=modelEvents.toArray();modelEvents.sort(tr.importer.compareEvents);for(const event of modelEvents){const startAndEnd='start: '+parseInt(event.start)+', '+'end: '+parseInt(event.end)+'});';if(event instanceof tr.e.cc.InputLatencyAsyncSlice){modelLines.push('      audits.addInputEvent(model, INPUT_TYPE.'+
 typeNames[event.typeName]+',');}else if(event.title==='RenderFrameImpl::didCommitProvisionalLoad'){modelLines.push('      audits.addCommitLoadEvent(model,');}else if(event.title==='InputHandlerProxy::HandleGestureFling::started'){modelLines.push('      audits.addFlingAnimationEvent(model,');}else if(event.title===tr.model.helpers.IMPL_RENDERING_STATS){modelLines.push('      audits.addFrameEvent(model,');}else if(event.title===tr.importer.CSS_ANIMATION_TITLE){modelLines.push('      audits.addEvent(model.rendererMain, {');modelLines.push('        title: \'Animation\', '+startAndEnd);return;}else{throw new Error('You must extend createCustomizeModelLinesFromModel()'+'to support this event:\n'+event.title+'\n');}
 modelLines.push('          {'+startAndEnd);}
 modelLines.push('      audits.addEvent(model.browserMain,');modelLines.push('          {'+'title: \'model end\', '+'start: '+(parseInt(model.bounds.max)-1)+', '+'end: '+parseInt(model.bounds.max)+'});');return modelLines;}
-function createExpectedUELinesFromModel(model){var expectedLines=[];var ueCount=model.userModel.expectations.length;for(var index=0;index<ueCount;++index){var expectation=model.userModel.expectations[index];var ueString='      {';ueString+='title: \''+expectation.title+'\', ';ueString+='start: '+parseInt(expectation.start)+', ';ueString+='end: '+parseInt(expectation.end)+', ';ueString+='eventCount: '+expectation.sourceEvents.length;ueString+='}';if(index<(ueCount-1))ueString+=',';expectedLines.push(ueString);}
+function createExpectedUELinesFromModel(model){const expectedLines=[];const ueCount=model.userModel.expectations.length;for(let index=0;index<ueCount;++index){const expectation=model.userModel.expectations[index];let ueString='      {';ueString+='title: \''+expectation.title+'\', ';ueString+='start: '+parseInt(expectation.start)+', ';ueString+='end: '+parseInt(expectation.end)+', ';ueString+='eventCount: '+expectation.sourceEvents.length;ueString+='}';if(index<(ueCount-1))ueString+=',';expectedLines.push(ueString);}
 return expectedLines;}
-function createUEFinderTestCaseStringFromModel(model){var filename=window.location.hash.substr(1);var testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{var testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    var verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedUEs = [');testLines.push.apply(testLines,createExpectedUELinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
-return{UserModelBuilder,createUEFinderTestCaseStringFromModel,};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){var elements;if(typeof source==='string'){elements=Polymer.dom(tr.doc).querySelectorAll(source);}else{elements=[source];}
-for(var i=0,el;el=elements[i];i++){if(!(el instanceof constr)){constr.decorate(el);}}}
+function createUEFinderTestCaseStringFromModel(model){const filename=window.location.hash.substr(1);let testName=filename.substr(filename.lastIndexOf('/')+1);testName=testName.substr(0,testName.indexOf('.'));try{const testLines=[];testLines.push('  /*');testLines.push('    This test was generated from');testLines.push('    '+filename+'');testLines.push('   */');testLines.push('  test(\''+testName+'\', function() {');testLines.push('    const verifier = new UserExpectationVerifier();');testLines.push('    verifier.customizeModelCallback = function(model) {');testLines.push.apply(testLines,createCustomizeModelLinesFromModel(model));testLines.push('    };');testLines.push('    verifier.expectedUEs = [');testLines.push.apply(testLines,createExpectedUELinesFromModel(model));testLines.push('    ];');testLines.push('    verifier.verify();');testLines.push('  });');return testLines.join('\n');}catch(error){return error;}}
+return{UserModelBuilder,createUEFinderTestCaseStringFromModel,};});'use strict';tr.exportTo('tr.ui.b',function(){function decorate(source,constr){let elements;if(typeof source==='string'){elements=Polymer.dom(tr.doc).querySelectorAll(source);}else{elements=[source];}
+for(let i=0,el;el=elements[i];i++){if(!(el instanceof constr)){constr.decorate(el);}}}
 function define(className,opt_parentConstructor,opt_tagNS){if(typeof className==='function'){throw new Error('Passing functions as className is deprecated. Please '+'use (className, opt_parentConstructor) to subclass');}
-var className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName){throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');}
-var tagName=className;var tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS){throw new Error('Must not specify tagNS if parentConstructor is given');}
-var parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
+className=className.toLowerCase();if(opt_parentConstructor&&!opt_parentConstructor.tagName){throw new Error('opt_parentConstructor was not '+'created by tr.ui.b.define');}
+let tagName=className;let tagNS=undefined;if(opt_parentConstructor){if(opt_tagNS){throw new Error('Must not specify tagNS if parentConstructor is given');}
+let parent=opt_parentConstructor;while(parent&&parent.tagName){tagName=parent.tagName;tagNS=parent.tagNS;parent=parent.parentConstructor;}}else{tagNS=opt_tagNS;}
 function f(){if(opt_parentConstructor&&f.prototype.__proto__!==opt_parentConstructor.prototype){throw new Error(className+' prototye\'s __proto__ field is messed up. '+'It MUST be the prototype of '+opt_parentConstructor.tagName);}
-var el;if(tagNS===undefined){el=tr.doc.createElement(tagName);}else{el=tr.doc.createElementNS(tagNS,tagName);}
+let el;if(tagNS===undefined){el=tr.doc.createElement(tagName);}else{el=tr.doc.createElementNS(tagNS,tagName);}
 f.decorate.call(this,el,arguments);return el;}
 f.decorate=function(el){el.__proto__=f.prototype;el.decorate.apply(el,arguments[1]);el.constructor=f;};f.className=className;f.tagName=tagName;f.tagNS=tagNS;f.parentConstructor=(opt_parentConstructor?opt_parentConstructor:undefined);f.toString=function(){if(!f.parentConstructor){return f.tagName;}
 return f.parentConstructor.toString()+'::'+f.className;};return f;}
-function elementIsChildOf(el,potentialParent){if(el===potentialParent)return false;var cur=el;while(Polymer.dom(cur).parentNode){if(cur===potentialParent)return true;cur=Polymer.dom(cur).parentNode;}
+function elementIsChildOf(el,potentialParent){if(el===potentialParent)return false;let cur=el;while(Polymer.dom(cur).parentNode){if(cur===potentialParent)return true;cur=Polymer.dom(cur).parentNode;}
 return false;}
 return{decorate,define,elementIsChildOf,};});'use strict';tr.exportTo('tr.b.math',function(){function Rect(){this.x=0;this.y=0;this.width=0;this.height=0;}
-Rect.fromXYWH=function(x,y,w,h){var rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;};Rect.fromArray=function(ary){if(ary.length!==4){throw new Error('ary.length must be 4');}
-var rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;};Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString:function(){return'Rect('+this.x+', '+this.y+', '+
-this.width+', '+this.height+')';},toArray:function(){return[this.x,this.y,this.width,this.height];},clone:function(){var rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge:function(pad){var rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast:function(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size:function(){return{width:this.width,height:this.height};},scale:function(s){var rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize:function(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast:function(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate:function(v){var rect=new Rect();this.translateFast(rect,v);return rect;},translateFast:function(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside:function(containingRect){var rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects:function(that){var ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo:function(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect,};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;var el=Polymer.dom(doc).querySelector(selector);if(!el){throw new Error('Element not found');}
+Rect.fromXYWH=function(x,y,w,h){const rect=new Rect();rect.x=x;rect.y=y;rect.width=w;rect.height=h;return rect;};Rect.fromArray=function(ary){if(ary.length!==4){throw new Error('ary.length must be 4');}
+const rect=new Rect();rect.x=ary[0];rect.y=ary[1];rect.width=ary[2];rect.height=ary[3];return rect;};Rect.prototype={__proto__:Object.prototype,get left(){return this.x;},get top(){return this.y;},get right(){return this.x+this.width;},get bottom(){return this.y+this.height;},toString(){return'Rect('+this.x+', '+this.y+', '+
+this.width+', '+this.height+')';},toArray(){return[this.x,this.y,this.width,this.height];},clone(){const rect=new Rect();rect.x=this.x;rect.y=this.y;rect.width=this.width;rect.height=this.height;return rect;},enlarge(pad){const rect=new Rect();this.enlargeFast(rect,pad);return rect;},enlargeFast(out,pad){out.x=this.x-pad;out.y=this.y-pad;out.width=this.width+2*pad;out.height=this.height+2*pad;return out;},size(){return{width:this.width,height:this.height};},scale(s){const rect=new Rect();this.scaleFast(rect,s);return rect;},scaleSize(s){return Rect.fromXYWH(this.x,this.y,this.width*s,this.height*s);},scaleFast(out,s){out.x=this.x*s;out.y=this.y*s;out.width=this.width*s;out.height=this.height*s;return out;},translate(v){const rect=new Rect();this.translateFast(rect,v);return rect;},translateFast(out,v){out.x=this.x+v[0];out.y=this.x+v[1];out.width=this.width;out.height=this.height;return out;},asUVRectInside(containingRect){const rect=new Rect();rect.x=(this.x-containingRect.x)/containingRect.width;rect.y=(this.y-containingRect.y)/containingRect.height;rect.width=this.width/containingRect.width;rect.height=this.height/containingRect.height;return rect;},intersects(that){let ok=true;ok&=this.x<that.right;ok&=this.right>that.x;ok&=this.y<that.bottom;ok&=this.bottom>that.y;return ok;},equalTo(rect){return rect&&(this.x===rect.x)&&(this.y===rect.y)&&(this.width===rect.width)&&(this.height===rect.height);}};return{Rect,};});'use strict';tr.exportTo('tr.ui.b',function(){function instantiateTemplate(selector,doc){doc=doc||document;const el=Polymer.dom(doc).querySelector(selector);if(!el){throw new Error('Element not found');}
 return doc.importNode(el.content,true);}
-function windowRectForElement(element){var position=[element.offsetLeft,element.offsetTop];var size=[element.offsetWidth,element.offsetHeight];var node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
+function windowRectForElement(element){const position=[element.offsetLeft,element.offsetTop];const size=[element.offsetWidth,element.offsetHeight];let node=element.offsetParent;while(node){position[0]+=node.offsetLeft;position[1]+=node.offsetTop;node=node.offsetParent;}
 return tr.b.math.Rect.fromXYWH(position[0],position[1],size[0],size[1]);}
-function scrollIntoViewIfNeeded(el){var pr=el.parentElement.getBoundingClientRect();var cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
-function extractUrlString(url){var extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
+function scrollIntoViewIfNeeded(el){const pr=el.parentElement.getBoundingClientRect();const cr=el.getBoundingClientRect();if(cr.top<pr.top){el.scrollIntoView(true);}else if(cr.bottom>pr.bottom){el.scrollIntoView(false);}}
+function extractUrlString(url){let extracted=url.replace(/url\((.*)\)/,'$1');extracted=extracted.replace(/\"(.*)\"/,'$1');return extracted;}
 function toThreeDigitLocaleString(value){return value.toLocaleString(undefined,{minimumFractionDigits:3,maximumFractionDigits:3});}
 function isUnknownElementName(name){return document.createElement(name)instanceof HTMLUnknownElement;}
-return{isUnknownElementName,toThreeDigitLocaleString,instantiateTemplate,windowRectForElement,scrollIntoViewIfNeeded,extractUrlString,};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)return{};var THIS_DOC=document.currentScript.ownerDocument;var Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){Polymer.dom(this).classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);var createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);Polymer.dom(this.shadow_).appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=Polymer.dom(this.shadow_).querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);Polymer.dom(this.shadow_).querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(Polymer.dom(this.shadow_).querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get:function(){return Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent;},set:function(title){Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return Polymer.dom(this.shadow_).querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)return;this.visible_=newValue;var e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_:function(){this.visible_?this.show_():this.hide_();},show_:function(){Polymer.dom(this.parentEl_).appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));this.closeBtn_.addEventListener('click',this.onClose_);}
-this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;var elList=Polymer.dom(this).querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)return elList[1].focus();}else{return elList[0].focus();}}
-this.focus();},hide_:function(){Polymer.dom(this.parentEl_).removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_){this.closeBtn_.removeEventListener('click',this.onClose_);}
-document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_:function(e){this.visible=false;if((e.type!=='keydown')||(e.type==='keydown'&&e.keyCode===27)){e.stopPropagation();}
-e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_:function(e){if(e.target===this)return;tr.b.timeout(0).then(()=>this.focus());e.preventDefault();e.stopPropagation();},didButtonBarMutate_:function(e){var hasButtons=this.buttons.children.length>0;if(hasButtons){Polymer.dom(this.shadow_).querySelector('button-bar').style.display=undefined;}else{Polymer.dom(this.shadow_).querySelector('button-bar').style.display='none';}},onKeyDown_:function(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
-if(e.keyCode!==27)return;this.onClose_(e);},onClick_:function(e){e.stopPropagation();},onDocumentClick_:function(e){if(!this.userCanClose_)return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){var o=new Overlay();o.title='Error';Polymer.dom(o).textContent=msg;if(opt_err){var e=tr.b.normalizeException(opt_err);var stackDiv=document.createElement('pre');Polymer.dom(stackDiv).textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;Polymer.dom(o).appendChild(stackDiv);}
-var b=document.createElement('button');Polymer.dom(b).textContent='OK';b.addEventListener('click',function(){o.visible=false;});Polymer.dom(o.buttons).appendChild(b);o.visible=true;return o;};return{Overlay,};});'use strict';tr.exportTo('tr.importer',function(){var Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;var auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
+return{isUnknownElementName,toThreeDigitLocaleString,instantiateTemplate,windowRectForElement,scrollIntoViewIfNeeded,extractUrlString,};});'use strict';tr.exportTo('tr.ui.b',function(){if(tr.isHeadless)return{};const THIS_DOC=document.currentScript.ownerDocument;const Overlay=tr.ui.b.define('overlay');Overlay.prototype={__proto__:HTMLDivElement.prototype,decorate(){Polymer.dom(this).classList.add('overlay');this.parentEl_=this.ownerDocument.body;this.visible_=false;this.userCanClose_=true;this.onKeyDown_=this.onKeyDown_.bind(this);this.onClick_=this.onClick_.bind(this);this.onFocusIn_=this.onFocusIn_.bind(this);this.onDocumentClick_=this.onDocumentClick_.bind(this);this.onClose_=this.onClose_.bind(this);this.addEventListener('visible-change',tr.ui.b.Overlay.prototype.onVisibleChange_.bind(this),true);const createShadowRoot=this.createShadowRoot||this.webkitCreateShadowRoot;this.shadow_=createShadowRoot.call(this);Polymer.dom(this.shadow_).appendChild(tr.ui.b.instantiateTemplate('#overlay-template',THIS_DOC));this.closeBtn_=Polymer.dom(this.shadow_).querySelector('close-button');this.closeBtn_.addEventListener('click',this.onClose_);Polymer.dom(this.shadow_).querySelector('overlay-frame').addEventListener('click',this.onClick_);this.observer_=new WebKitMutationObserver(this.didButtonBarMutate_.bind(this));this.observer_.observe(Polymer.dom(this.shadow_).querySelector('button-bar'),{childList:true});Object.defineProperty(this,'title',{get(){return Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent;},set(title){Polymer.dom(Polymer.dom(this.shadow_).querySelector('title')).textContent=title;}});},set userCanClose(userCanClose){this.userCanClose_=userCanClose;this.closeBtn_.style.display=userCanClose?'block':'none';},get buttons(){return Polymer.dom(this.shadow_).querySelector('button-bar');},get visible(){return this.visible_;},set visible(newValue){if(this.visible_===newValue)return;this.visible_=newValue;const e=new tr.b.Event('visible-change');this.dispatchEvent(e);},onVisibleChange_(){this.visible_?this.show_():this.hide_();},show_(){Polymer.dom(this.parentEl_).appendChild(this);if(this.userCanClose_){this.addEventListener('keydown',this.onKeyDown_.bind(this));this.addEventListener('click',this.onDocumentClick_.bind(this));this.closeBtn_.addEventListener('click',this.onClose_);}
+this.parentEl_.addEventListener('focusin',this.onFocusIn_);this.tabIndex=0;const elList=Polymer.dom(this).querySelectorAll('button, input, list, select, a');if(elList.length>0){if(elList[0]===this.closeBtn_){if(elList.length>1)return elList[1].focus();}else{return elList[0].focus();}}
+this.focus();},hide_(){Polymer.dom(this.parentEl_).removeChild(this);this.parentEl_.removeEventListener('focusin',this.onFocusIn_);if(this.closeBtn_){this.closeBtn_.removeEventListener('click',this.onClose_);}
+document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('click',this.onDocumentClick_);},onClose_(e){this.visible=false;if((e.type!=='keydown')||(e.type==='keydown'&&e.keyCode===27)){e.stopPropagation();}
+e.preventDefault();tr.b.dispatchSimpleEvent(this,'closeclick');},onFocusIn_(e){if(e.target===this)return;tr.b.timeout(0).then(()=>this.focus());e.preventDefault();e.stopPropagation();},didButtonBarMutate_(e){const hasButtons=this.buttons.children.length>0;if(hasButtons){Polymer.dom(this.shadow_).querySelector('button-bar').style.display=undefined;}else{Polymer.dom(this.shadow_).querySelector('button-bar').style.display='none';}},onKeyDown_(e){if(e.keyCode===9&&e.shiftKey&&e.target===this){e.preventDefault();return;}
+if(e.keyCode!==27)return;this.onClose_(e);},onClick_(e){e.stopPropagation();},onDocumentClick_(e){if(!this.userCanClose_)return;this.onClose_(e);}};Overlay.showError=function(msg,opt_err){const o=new Overlay();o.title='Error';Polymer.dom(o).textContent=msg;if(opt_err){const e=tr.b.normalizeException(opt_err);const stackDiv=document.createElement('pre');Polymer.dom(stackDiv).textContent=e.stack;stackDiv.style.paddingLeft='8px';stackDiv.style.margin=0;Polymer.dom(o).appendChild(stackDiv);}
+const b=document.createElement('button');Polymer.dom(b).textContent='OK';b.addEventListener('click',function(){o.visible=false;});Polymer.dom(o.buttons).appendChild(b);o.visible=true;return o;};return{Overlay,};});'use strict';tr.exportTo('tr.importer',function(){const Timing=tr.b.Timing;function ImportOptions(){this.shiftWorldToZero=true;this.pruneEmptyContainers=true;this.showImportWarnings=true;this.trackDetailedModelStats=false;this.customizeModelCallback=undefined;const auditorTypes=tr.c.Auditor.getAllRegisteredTypeInfos();this.auditorConstructors=auditorTypes.map(function(typeInfo){return typeInfo.constructor;});}
 function Import(model,opt_options){if(model===undefined){throw new Error('Must provide model to import into.');}
 this.importing_=false;this.importOptions_=opt_options||new ImportOptions();this.model_=model;this.model_.importOptions=this.importOptions_;}
-Import.prototype={__proto__:Object.prototype,importTraces:function(traces){var progressMeter={update:function(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog:function(traces){if(tr.isHeadless){throw new Error('Cannot use this method in headless mode.');}
-var overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');Polymer.dom(overlay).appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){Polymer.dom(this.msgEl).textContent=msg;};overlay.visible=true;var promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask:function(progressMeter,traces){var importStartTimeMs=performance.now();if(this.importing_){throw new Error('Already importing.');}
-this.importing_=true;var importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);var lastTask=importTask;var importers=[];function addImportStage(title,callback){lastTask=lastTask.after(()=>progressMeter.update(title));lastTask.updatesUi=true;lastTask=lastTask.after(callback);}
-function addStageForEachImporter(title,callback){lastTask=lastTask.after((task)=>{importers.forEach((importer,index)=>{var uiSubTask=task.subTask(()=>{progressMeter.update(`${title}${index+1}of ${importers.length}`);});uiSubTask.updatesUi=true;task.subTask(()=>callback(importer));});});}
-addImportStage('Creating importers...',()=>{traces=traces.slice(0);progressMeter.update('Creating importers...');for(var i=0;i<traces.length;++i){importers.push(this.createImporter_(traces[i]));}
-for(var i=0;i<importers.length;i++){var subtraces=importers[i].extractSubtraces();for(var j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){this.model_.importWarning({type:error.name,message:error.message,showToUser:true,});continue;}}}
+Import.prototype={__proto__:Object.prototype,importTraces(traces){const progressMeter={update(msg){}};tr.b.Task.RunSynchronously(this.createImportTracesTask(progressMeter,traces));},importTracesWithProgressDialog(traces){if(tr.isHeadless){throw new Error('Cannot use this method in headless mode.');}
+const overlay=tr.ui.b.Overlay();overlay.title='Importing...';overlay.userCanClose=false;overlay.msgEl=document.createElement('div');Polymer.dom(overlay).appendChild(overlay.msgEl);overlay.msgEl.style.margin='20px';overlay.update=function(msg){Polymer.dom(this.msgEl).textContent=msg;};overlay.visible=true;const promise=tr.b.Task.RunWhenIdle(this.createImportTracesTask(overlay,traces));promise.then(function(){overlay.visible=false;},function(err){overlay.visible=false;});return promise;},createImportTracesTask(progressMeter,traces){const importStartTimeMs=performance.now();if(this.importing_){throw new Error('Already importing.');}
+this.importing_=true;const importTask=new tr.b.Task(function prepareImport(){progressMeter.update('I will now import your traces for you...');},this);let lastTask=importTask;const importers=[];function addImportStage(title,callback){lastTask=lastTask.after(()=>progressMeter.update(title));lastTask.updatesUi=true;lastTask=lastTask.after(callback);}
+function addStageForEachImporter(title,callback){lastTask=lastTask.after((task)=>{importers.forEach((importer,index)=>{const uiSubTask=task.subTask(()=>{progressMeter.update(`${title} ${index + 1} of ${importers.length}`);});uiSubTask.updatesUi=true;task.subTask(()=>callback(importer));});});}
+addImportStage('Creating importers...',()=>{traces=traces.slice(0);progressMeter.update('Creating importers...');for(let i=0;i<traces.length;++i){importers.push(this.createImporter_(traces[i]));}
+for(let i=0;i<importers.length;i++){const subtraces=importers[i].extractSubtraces();for(let j=0;j<subtraces.length;j++){try{traces.push(subtraces[j]);importers.push(this.createImporter_(subtraces[j]));}catch(error){this.model_.importWarning({type:error.name,message:error.message,showToUser:true,});continue;}}}
 if(traces.length&&!this.hasEventDataDecoder_(importers)){throw new Error('Could not find an importer for the provided eventData.');}
 importers.sort(function(x,y){return x.importPriority-y.importPriority;});});addStageForEachImporter('Importing clock sync markers',importer=>importer.importClockSyncMarkers());addStageForEachImporter('Importing',importer=>importer.importEvents());if(this.importOptions_.customizeModelCallback){addImportStage('Customizing',()=>{this.importOptions_.customizeModelCallback(this.model_);});}
 addStageForEachImporter('Importing sample data',importer=>importer.importSampleData());addImportStage('Autoclosing open slices...',()=>{this.model_.autoCloseOpenSlices();this.model_.createSubSlices();});addStageForEachImporter('Finalizing import',importer=>importer.finalizeImport());addImportStage('Initializing objects (step 1/2)...',()=>this.model_.preInitializeObjects());if(this.importOptions_.pruneEmptyContainers){addImportStage('Pruning empty containers...',()=>this.model_.pruneEmptyContainers());}
-addImportStage('Merging kernel with userland...',()=>this.model_.mergeKernelWithUserland());var auditors=[];addImportStage('Adding arbitrary data to model...',()=>{auditors=this.importOptions_.auditorConstructors.map(auditorConstructor=>new auditorConstructor(this.model_));auditors.forEach((auditor)=>{auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});});addImportStage('Computing final world bounds...',()=>{this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);});addImportStage('Building flow event map...',()=>this.model_.buildFlowEventIntervalTree());addImportStage('Joining object refs...',()=>this.model_.joinRefs());addImportStage('Cleaning up undeleted objects...',()=>this.model_.cleanupUndeletedObjects());addImportStage('Sorting memory dumps...',()=>this.model_.sortMemoryDumps());addImportStage('Finalizing memory dump graphs...',()=>this.model_.finalizeMemoryGraphs());addImportStage('Initializing objects (step 2/2)...',()=>this.model_.initializeObjects());addImportStage('Building event indices...',()=>this.model_.buildEventIndices());addImportStage('Building UserModel...',()=>{var userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();});addImportStage('Sorting user expectations...',()=>this.model_.userModel.sortExpectations());addImportStage('Running auditors...',()=>{auditors.forEach(auditor=>auditor.runAudit());});addImportStage('Updating alerts...',()=>this.model_.sortAlerts());addImportStage('Update bounds...',()=>this.model_.updateBounds());addImportStage('Looking for warnings...',()=>{if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:true});}});lastTask.after(()=>{this.importing_=false;this.model_.stats.traceImportDurationMs=performance.now()-importStartTimeMs;});return importTask;},createImporter_:function(eventData){var importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
-return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_:function(importers){for(var i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())return true;}
-return false;}};return{ImportOptions,Import,};});'use strict';tr.exportTo('tr.e.v8',function(){var ProfileNode=tr.model.ProfileNode;function V8CpuProfileNode(id,callFrame,parentNode){ProfileNode.call(this,id,callFrame.functionName,parentNode);this.callFrame_=tr.b.deepCopy(callFrame);this.deoptReason_='';this.colorId_=tr.b.ColorScheme.getColorIdForGeneralPurposeString(callFrame.functionName);}
-V8CpuProfileNode.prototype={__proto__:ProfileNode.prototype,get functionName(){return this.callFrame_.functionName;},get scriptId(){return this.callFrame_.scriptId;},get url(){if(!this.callFrame_.url){return'unknown';}
-var url=this.callFrame_.url;if(this.callFrame_.lineNumber===undefined){return url;}
-url=url+':'+this.callFrame_.lineNumber;if(this.callFrame_.columnNumber===undefined){return url;}
-url=url+':'+this.callFrame_.columnNumber;return url;},get deoptReason(){return this.deoptReason_;},set deoptReason(value){this.deoptReason_=value;},get userFriendlyName(){let name=this.functionName+' url: '+this.url;return!this.deoptReason_?name:name+' Deoptimized reason: '+this.deoptReason_;},get sampleTitle(){return'V8 Sample';}};V8CpuProfileNode.constructFromObject=function(profileTree,node){let nodeId=node['id'];if(nodeId===1){return undefined;}
-var parentNode=profileTree.getNode(node['parent']);var profileNode=new V8CpuProfileNode(nodeId,node['callFrame'],parentNode);if(node['deoptReason']!==undefined){profileNode.deoptReason=node['deoptReason'];}
-return profileNode;};ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'cpuProfile',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});ProfileNode.subTypes.register(V8CpuProfileNode,{typeName:'legacySample',name:'v8 cpu profile node',pluralName:'v8 cpu profile nodes'});return{ProfileNode,};});'use strict';tr.exportTo('tr.e.v8',function(){var ThreadSlice=tr.model.ThreadSlice;function V8GCStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.liveObjects_=JSON.parse(this.args['live']);delete this.args['live'];this.deadObjects_=JSON.parse(this.args['dead']);delete this.args['dead'];}
-V8GCStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get liveObjects(){return this.liveObjects_;},get deadObjects(){return this.deadObjects_;}};ThreadSlice.subTypes.register(V8GCStatsThreadSlice,{categoryParts:['disabled-by-default-v8.gc_stats'],name:'v8 gc stats slice',pluralName:'v8 gc stats slices'});return{V8GCStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){var ThreadSlice=tr.model.ThreadSlice;function V8ICStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.icStats_=undefined;if(this.args['ic-stats']){this.icStats_=this.args['ic-stats']['data'];delete this.args['ic-stats'];}}
-V8ICStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get icStats(){return this.icStats_;}};ThreadSlice.subTypes.register(V8ICStatsThreadSlice,{categoryParts:['disabled-by-default-v8.ic_stats'],name:'v8 ic stats slice',pluralName:'v8 ic stats slices'});return{V8ICStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){var ThreadSlice=tr.model.ThreadSlice;function V8ThreadSlice(){ThreadSlice.apply(this,arguments);this.runtimeCallStats_=undefined;}
+addImportStage('Merging kernel with userland...',()=>this.model_.mergeKernelWithUserland());let auditors=[];addImportStage('Adding arbitrary data to model...',()=>{auditors=this.importOptions_.auditorConstructors.map(auditorConstructor=>new auditorConstructor(this.model_));auditors.forEach((auditor)=>{auditor.runAnnotate();auditor.installUserFriendlyCategoryDriverIfNeeded();});});addImportStage('Computing final world bounds...',()=>{this.model_.computeWorldBounds(this.importOptions_.shiftWorldToZero);});addImportStage('Building flow event map...',()=>this.model_.buildFlowEventIntervalTree());addImportStage('Joining object refs...',()=>this.model_.joinRefs());addImportStage('Cleaning up undeleted objects...',()=>this.model_.cleanupUndeletedObjects());addImportStage('Sorting memory dumps...',()=>this.model_.sortMemoryDumps());addImportStage('Finalizing memory dump graphs...',()=>this.model_.finalizeMemoryGraphs());addImportStage('Initializing objects (step 2/2)...',()=>this.model_.initializeObjects());addImportStage('Building event indices...',()=>this.model_.buildEventIndices());addImportStage('Building UserModel...',()=>{const userModelBuilder=new tr.importer.UserModelBuilder(this.model_);userModelBuilder.buildUserModel();});addImportStage('Sorting user expectations...',()=>this.model_.userModel.sortExpectations());addImportStage('Running auditors...',()=>{auditors.forEach(auditor=>auditor.runAudit());});addImportStage('Updating alerts...',()=>this.model_.sortAlerts());addImportStage('Update bounds...',()=>this.model_.updateBounds());addImportStage('Looking for warnings...',()=>{if(!this.model_.isTimeHighResolution){this.model_.importWarning({type:'low_resolution_timer',message:'Trace time is low resolution, trace may be unusable.',showToUser:true});}});lastTask.after(()=>{this.importing_=false;this.model_.stats.traceImportDurationMs=performance.now()-importStartTimeMs;});return importTask;},createImporter_(eventData){const importerConstructor=tr.importer.Importer.findImporterFor(eventData);if(!importerConstructor){throw new Error('Couldn\'t create an importer for the provided '+'eventData.');}
+return new importerConstructor(this.model_,eventData);},hasEventDataDecoder_(importers){for(let i=0;i<importers.length;++i){if(!importers[i].isTraceDataContainer())return true;}
+return false;}};return{ImportOptions,Import,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8GCStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.liveObjects_=JSON.parse(this.args.live);delete this.args.live;this.deadObjects_=JSON.parse(this.args.dead);delete this.args.dead;}
+V8GCStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get liveObjects(){return this.liveObjects_;},get deadObjects(){return this.deadObjects_;}};ThreadSlice.subTypes.register(V8GCStatsThreadSlice,{categoryParts:['disabled-by-default-v8.gc_stats'],name:'v8 gc stats slice',pluralName:'v8 gc stats slices'});return{V8GCStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8ICStatsThreadSlice(){ThreadSlice.apply(this,arguments);this.icStats_=undefined;if(this.args['ic-stats']){this.icStats_=this.args['ic-stats'].data;delete this.args['ic-stats'];}}
+V8ICStatsThreadSlice.prototype={__proto__:ThreadSlice.prototype,get icStats(){return this.icStats_;}};ThreadSlice.subTypes.register(V8ICStatsThreadSlice,{categoryParts:['disabled-by-default-v8.ic_stats'],name:'v8 ic stats slice',pluralName:'v8 ic stats slices'});return{V8ICStatsThreadSlice,};});'use strict';tr.exportTo('tr.e.v8',function(){const ThreadSlice=tr.model.ThreadSlice;function V8ThreadSlice(){ThreadSlice.apply(this,arguments);this.runtimeCallStats_=undefined;}
 V8ThreadSlice.prototype={__proto__:ThreadSlice.prototype,get runtimeCallStats(){if('runtime-call-stats'in this.args){this.runtimeCallStats_=this.args['runtime-call-stats'];delete this.args['runtime-call-stats'];}
 return this.runtimeCallStats_;}};ThreadSlice.subTypes.register(V8ThreadSlice,{categoryParts:['v8','disabled-by-default-v8.runtime_stats'],name:'v8 slice',pluralName:'v8 slices'});return{V8ThreadSlice,};});'use strict';tr.exportTo('tr.e.cc',function(){function PictureAsImageData(picture,errorOrImageData){this.picture_=picture;if(errorOrImageData instanceof ImageData){this.error_=undefined;this.imageData_=errorOrImageData;}else{this.error_=errorOrImageData;this.imageData_=undefined;}}
-PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending:function(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas:function(){if(!this.imageData_)return;var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData,};});'use strict';tr.exportTo('tr.e.cc',function(){var convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache){return convertedNameCache[name];}
+PictureAsImageData.Pending=function(picture){return new PictureAsImageData(picture,undefined);};PictureAsImageData.prototype={get picture(){return this.picture_;},get error(){return this.error_;},get imageData(){return this.imageData_;},isPending(){return this.error_===undefined&&this.imageData_===undefined;},asCanvas(){if(!this.imageData_)return;const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=this.imageData_.width;canvas.height=this.imageData_.height;ctx.putImageData(this.imageData_,0,0);return canvas;}};return{PictureAsImageData,};});'use strict';tr.exportTo('tr.e.cc',function(){const convertedNameCache={};function convertNameToJSConvention(name){if(name in convertedNameCache){return convertedNameCache[name];}
 if(name[0]==='_'||name[name.length-1]==='_'){convertedNameCache[name]=name;return name;}
-var words=name.split('_');if(words.length===1){convertedNameCache[name]=words[0];return words[0];}
-for(var i=1;i<words.length;i++){words[i]=words[i][0].toUpperCase()+words[i].substring(1);}
+const words=name.split('_');if(words.length===1){convertedNameCache[name]=words[0];return words[0];}
+for(let i=1;i<words.length;i++){words[i]=words[i][0].toUpperCase()+words[i].substring(1);}
 convertedNameCache[name]=words.join('');return convertedNameCache[name];}
 function convertObjectFieldNamesToJSConventions(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){delete object[fieldName];object[newFieldName]=fieldValue;return newFieldName;});}
 function convertQuadSuffixedTypesToQuads(object){tr.b.iterObjectFieldsRecursively(object,function(object,fieldName,fieldValue){});}
 function convertObject(object){convertObjectFieldNamesToJSConventions(object);convertQuadSuffixedTypesToQuads(object);}
-function moveRequiredFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined){throw Error('Expected field '+key+' not found in args');}
+function moveRequiredFieldsFromArgsToToplevel(object,fields){for(let i=0;i<fields.length;i++){const key=fields[i];if(object.args[key]===undefined){throw Error('Expected field '+key+' not found in args');}
 if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
 object[key]=object.args[key];delete object.args[key];}}
-function moveOptionalFieldsFromArgsToToplevel(object,fields){for(var i=0;i<fields.length;i++){var key=fields[i];if(object.args[key]===undefined)continue;if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
+function moveOptionalFieldsFromArgsToToplevel(object,fields){for(let i=0;i<fields.length;i++){const key=fields[i];if(object.args[key]===undefined)continue;if(object[key]!==undefined){throw Error('Field '+key+' already in object');}
 object[key]=object.args[key];delete object.args[key];}}
 function preInitializeObject(object){preInitializeObjectInner(object.args,false);}
-function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))return;if(object instanceof Array){for(var i=0;i<object.length;i++){preInitializeObjectInner(object[i],true);}
+function preInitializeObjectInner(object,hasRecursed){if(!(object instanceof Object))return;if(object instanceof Array){for(let i=0;i<object.length;i++){preInitializeObjectInner(object[i],true);}
 return;}
 if(hasRecursed&&(object instanceof tr.model.ObjectSnapshot||object instanceof tr.model.ObjectInstance)){return;}
-for(var key in object){var newKey=convertNameToJSConvention(key);if(newKey!==key){var value=object[key];delete object[key];object[newKey]=value;key=newKey;}
-if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.math.Quad)){var q;try{q=tr.b.math.Quad.from8Array(object[key]);}catch(e){}
+for(let key in object){const newKey=convertNameToJSConvention(key);if(newKey!==key){const value=object[key];delete object[key];object[newKey]=value;key=newKey;}
+if(/Quad$/.test(key)&&!(object[key]instanceof tr.b.math.Quad)){let q;try{q=tr.b.math.Quad.from8Array(object[key]);}catch(e){}
 object[key]=q;continue;}
-if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.math.Rect)){var r;try{r=tr.b.math.Rect.fromArray(object[key]);}catch(e){}
+if(/Rect$/.test(key)&&!(object[key]instanceof tr.b.math.Rect)){let r;try{r=tr.b.math.Rect.fromArray(object[key]);}catch(e){}
 object[key]=r;}
 preInitializeObjectInner(object[key],true);}}
-return{preInitializeObject:preInitializeObject,convertNameToJSConvention:convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel:moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel:moveOptionalFieldsFromArgsToToplevel,};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;var PictureCount=0;var OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocateSimple();}
-Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){return this.skp64_;},getOps:function(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops){console.error('Failed to get picture ops.');}
-return ops;},getOpTimings:function(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
-var opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings){console.error('Failed to get picture op timings.');}
-return opTimings;},tagOpsWithTimings:function(ops){var opTimings=[];for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}
+return{preInitializeObject,convertNameToJSConvention,moveRequiredFieldsFromArgsToToplevel,moveOptionalFieldsFromArgsToToplevel,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;const PictureCount=0;const OPS_TIMING_ITERATIONS=3;function Picture(skp64,layerRect){this.skp64_=skp64;this.layerRect_=layerRect;this.guid_=tr.b.GUID.allocateSimple();}
+Picture.prototype={get canSave(){return true;},get layerRect(){return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData(){return this.skp64_;},getOps(){if(!PictureSnapshot.CanGetOps()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+const ops=window.chrome.skiaBenchmarking.getOps({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!ops){console.error('Failed to get picture ops.');}
+return ops;},getOpTimings(){if(!PictureSnapshot.CanGetOpTimings()){console.error(PictureSnapshot.HowToEnablePictureDebugging());return undefined;}
+const opTimings=window.chrome.skiaBenchmarking.getOpTimings({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}});if(!opTimings){console.error('Failed to get picture op timings.');}
+return opTimings;},tagOpsWithTimings(ops){const opTimings=[];for(let iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}
 if(opTimings[iteration].cmd_times.length!==ops.length){return ops;}}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
+for(let opIndex=0;opIndex<ops.length;opIndex++){let min=Number.MAX_VALUE;for(let i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
 ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
-var raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;var imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{var error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocateSimple();this.pictures_=pictures;this.layerRect_=undefined;}
+return ops;},rasterize(params,rasterCompleteCallback){if(!PictureSnapshot.CanRasterize()||!PictureSnapshot.CanGetOps()){rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,tr.e.cc.PictureSnapshot.HowToEnablePictureDebugging()));return;}
+const raster=window.chrome.skiaBenchmarking.rasterize({skp64:this.skp64_,params:{layer_rect:this.layerRect_.toArray()}},{stop:params.stopIndex===undefined?-1:params.stopIndex,overdraw:!!params.showOverdraw,params:{}});if(raster){const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=raster.width;canvas.height=raster.height;const imageData=ctx.createImageData(raster.width,raster.height);imageData.data.set(new Uint8ClampedArray(raster.data));rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,imageData));}else{const error='Failed to rasterize picture. '+'Your recording may be from an old Chrome version. '+'The SkPicture format is not backward compatible.';rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,error));}}};function LayeredPicture(pictures){this.guid_=tr.b.GUID.allocateSimple();this.pictures_=pictures;this.layerRect_=undefined;}
 LayeredPicture.prototype={__proto__:Picture.prototype,get canSave(){return false;},get typeName(){return'cc::LayeredPicture';},get layerRect(){if(this.layerRect_!==undefined){return this.layerRect_;}
-this.layerRect_={x:0,y:0,width:0,height:0};for(var i=0;i<this.pictures_.length;++i){var rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
-return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData:function(){throw new Error('Not available with a LayeredPicture.');},getOps:function(){var ops=[];for(var i=0;i<this.pictures_.length;++i){ops=ops.concat(this.pictures_[i].getOps());}
-return ops;},getOpTimings:function(){var opTimings=this.pictures_[0].getOpTimings();for(var i=1;i<this.pictures_.length;++i){var timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
-return opTimings;},tagOpsWithTimings:function(ops){var opTimings=[];for(var iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}}
-for(var opIndex=0;opIndex<ops.length;opIndex++){var min=Number.MAX_VALUE;for(var i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
+this.layerRect_={x:0,y:0,width:0,height:0};for(let i=0;i<this.pictures_.length;++i){const rect=this.pictures_[i].layerRect;this.layerRect_.x=Math.min(this.layerRect_.x,rect.x);this.layerRect_.y=Math.min(this.layerRect_.y,rect.y);this.layerRect_.width=Math.max(this.layerRect_.width,rect.x+rect.width);this.layerRect_.height=Math.max(this.layerRect_.height,rect.y+rect.height);}
+return this.layerRect_;},get guid(){return this.guid_;},getBase64SkpData(){throw new Error('Not available with a LayeredPicture.');},getOps(){let ops=[];for(let i=0;i<this.pictures_.length;++i){ops=ops.concat(this.pictures_[i].getOps());}
+return ops;},getOpTimings(){const opTimings=this.pictures_[0].getOpTimings();for(let i=1;i<this.pictures_.length;++i){const timings=this.pictures_[i].getOpTimings();opTimings.cmd_times=opTimings.cmd_times.concat(timings.cmd_times);opTimings.total_time+=timings.total_time;}
+return opTimings;},tagOpsWithTimings(ops){const opTimings=[];for(let iteration=0;iteration<OPS_TIMING_ITERATIONS;iteration++){opTimings[iteration]=this.getOpTimings();if(!opTimings[iteration]||!opTimings[iteration].cmd_times){return ops;}}
+for(let opIndex=0;opIndex<ops.length;opIndex++){let min=Number.MAX_VALUE;for(let i=0;i<OPS_TIMING_ITERATIONS;i++){min=Math.min(min,opTimings[i].cmd_times[opIndex]);}
 ops[opIndex].cmd_time=min;}
-return ops;},rasterize:function(params,rasterCompleteCallback){this.picturesAsImageData_=[];var rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length){return;}
-var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(var i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
-this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(var i=0;i<this.pictures_.length;++i){this.pictures_[i].rasterize(params,rasterCallback);}}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
+return ops;},rasterize(params,rasterCompleteCallback){this.picturesAsImageData_=[];const rasterCallback=function(pictureAsImageData){this.picturesAsImageData_.push(pictureAsImageData);if(this.picturesAsImageData_.length!==this.pictures_.length){return;}
+const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=this.layerRect.width;canvas.height=this.layerRect.height;for(let i=0;i<this.picturesAsImageData_.length;++i){ctx.putImageData(this.picturesAsImageData_[i].imageData,this.pictures_[i].layerRect.x,this.pictures_[i].layerRect.y);}
+this.picturesAsImageData_=[];rasterCompleteCallback(new tr.e.cc.PictureAsImageData(this,ctx.getImageData(this.layerRect.x,this.layerRect.y,this.layerRect.width,this.layerRect.height)));}.bind(this);for(let i=0;i<this.pictures_.length;++i){this.pictures_[i].rasterize(params,rasterCallback);}}};function PictureSnapshot(){ObjectSnapshot.apply(this,arguments);}
 PictureSnapshot.HasSkiaBenchmarking=function(){return tr.isExported('chrome.skiaBenchmarking');};PictureSnapshot.CanRasterize=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
 if(!window.chrome.skiaBenchmarking.rasterize){return false;}
 return true;};PictureSnapshot.CanGetOps=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
@@ -6096,30 +6416,30 @@
 return true;};PictureSnapshot.CanGetInfo=function(){if(!PictureSnapshot.HasSkiaBenchmarking()){return false;}
 if(!window.chrome.skiaBenchmarking.getInfo){return false;}
 return true;};PictureSnapshot.HowToEnablePictureDebugging=function(){if(tr.isHeadless){return'Pictures only work in chrome';}
-var usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking')){return usualReason;}
+const usualReason=['For pictures to show up, you need to have Chrome running with ','--enable-skia-benchmarking. Please restart chrome with this flag ','and try again.'].join('');if(!tr.isExported('global.chrome.skiaBenchmarking')){return usualReason;}
 if(!global.chrome.skiaBenchmarking.rasterize){return'Your chrome is old';}
 if(!global.chrome.skiaBenchmarking.getOps){return'Your chrome is old: skiaBenchmarking.getOps not found';}
 if(!global.chrome.skiaBenchmarking.getOpTimings){return'Your chrome is old: skiaBenchmarking.getOpTimings not found';}
 if(!global.chrome.skiaBenchmarking.getInfo){return'Your chrome is old: skiaBenchmarking.getInfo not found';}
-return'Rasterizing is on';};PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize:function(){if(this.args.alias){this.args=this.args.alias.args;}
+return'Rasterizing is on';};PictureSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.rasterResult_=undefined;},initialize(){if(this.args.alias){this.args=this.args.alias.args;}
 if(!this.args.params.layerRect){throw new Error('Missing layer rect');}
-this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData:function(){return this.picture_.getBase64SkpData();},getOps:function(){return this.picture_.getOps();},getOpTimings:function(){return this.picture_.getOpTimings();},tagOpsWithTimings:function(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize:function(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.subTypes.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot,Picture,LayeredPicture,};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
+this.layerRect_=this.args.params.layerRect;this.picture_=new Picture(this.args.skp64,this.args.params.layerRect);},set picture(picture){this.picture_=picture;},get canSave(){return this.picture_.canSave;},get layerRect(){return this.layerRect_?this.layerRect_:this.picture_.layerRect;},get guid(){return this.picture_.guid;},getBase64SkpData(){return this.picture_.getBase64SkpData();},getOps(){return this.picture_.getOps();},getOpTimings(){return this.picture_.getOpTimings();},tagOpsWithTimings(ops){return this.picture_.tagOpsWithTimings(ops);},rasterize(params,rasterCompleteCallback){this.picture_.rasterize(params,rasterCompleteCallback);}};ObjectSnapshot.subTypes.register(PictureSnapshot,{typeNames:['cc::Picture']});return{PictureSnapshot,Picture,LayeredPicture,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function DisplayItemList(skp64,layerRect){tr.e.cc.Picture.apply(this,arguments);}
 DisplayItemList.prototype={__proto__:tr.e.cc.Picture.prototype};function DisplayItemListSnapshot(){tr.e.cc.PictureSnapshot.apply(this,arguments);}
-DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize:function(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.subTypes.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot,DisplayItemList,};});'use strict';tr.exportTo('tr.b.math',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
-BBox2.prototype={__proto__:Object.prototype,reset:function(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2:function(bbox2){if(bbox2.isEmpty)return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone:function(){var bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY:function(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2:function(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
-this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad:function(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
-var size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
+DisplayItemListSnapshot.prototype={__proto__:tr.e.cc.PictureSnapshot.prototype,initialize(){tr.e.cc.PictureSnapshot.prototype.initialize.call(this);this.displayItems_=this.args.params.items;},get items(){return this.displayItems_;}};ObjectSnapshot.subTypes.register(DisplayItemListSnapshot,{typeNames:['cc::DisplayItemList']});return{DisplayItemListSnapshot,DisplayItemList,};});'use strict';tr.exportTo('tr.b.math',function(){function BBox2(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;}
+BBox2.prototype={__proto__:Object.prototype,reset(){this.isEmpty_=true;this.min_=undefined;this.max_=undefined;},get isEmpty(){return this.isEmpty_;},addBBox2(bbox2){if(bbox2.isEmpty)return;this.addVec2(bbox2.min_);this.addVec2(bbox2.max_);},clone(){const bbox=new BBox2();bbox.addBBox2(this);return bbox;},addXY(x,y){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,x,y);vec2.set(this.min_,x,y);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],x);this.max_[1]=Math.max(this.max_[1],y);this.min_[0]=Math.min(this.min_[0],x);this.min_[1]=Math.min(this.min_[1],y);},addVec2(value){if(this.isEmpty_){this.max_=vec2.create();this.min_=vec2.create();vec2.set(this.max_,value[0],value[1]);vec2.set(this.min_,value[0],value[1]);this.isEmpty_=false;return;}
+this.max_[0]=Math.max(this.max_[0],value[0]);this.max_[1]=Math.max(this.max_[1],value[1]);this.min_[0]=Math.min(this.min_[0],value[0]);this.min_[1]=Math.min(this.min_[1],value[1]);},addQuad(quad){this.addVec2(quad.p1);this.addVec2(quad.p2);this.addVec2(quad.p3);this.addVec2(quad.p4);},get minVec2(){if(this.isEmpty_)return undefined;return this.min_;},get maxVec2(){if(this.isEmpty_)return undefined;return this.max_;},get sizeAsVec2(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
+const size=vec2.create();vec2.subtract(size,this.max_,this.min_);return size;},get size(){if(this.isEmpty_){throw new Error('Empty BBox2 has no size');}
 return{width:this.max_[0]-this.min_[0],height:this.max_[1]-this.min_[1]};},get width(){if(this.isEmpty_){throw new Error('Empty BBox2 has no width');}
 return this.max_[0]-this.min_[0];},get height(){if(this.isEmpty_){throw new Error('Empty BBox2 has no width');}
-return this.max_[1]-this.min_[1];},toString:function(){if(this.isEmpty_)return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect:function(){return tr.b.math.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2,};});'use strict';tr.exportTo('tr.e.cc',function(){var constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants:constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
+return this.max_[1]-this.min_[1];},toString(){if(this.isEmpty_)return'empty';return'min=('+this.min_[0]+','+this.min_[1]+') '+'max=('+this.max_[0]+','+this.max_[1]+')';},asRect(){return tr.b.math.Rect.fromXYWH(this.min_[0],this.min_[1],this.max_[0]-this.min_[0],this.max_[1]-this.min_[1]);}};return{BBox2,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants={};constants.ACTIVE_TREE=0;constants.PENDING_TREE=1;constants.HIGH_PRIORITY_BIN=0;constants.LOW_PRIORITY_BIN=1;constants.SEND_BEGIN_FRAME_EVENT='ThreadProxy::ScheduledActionSendBeginMainFrame';constants.BEGIN_MAIN_FRAME_EVENT='ThreadProxy::BeginMainFrame';return{constants};});'use strict';tr.exportTo('tr.e.cc',function(){function Region(){this.rects=[];}
 Region.fromArray=function(array){if(array.length%4!==0){throw new Error('Array must consist be a multiple of 4 in length');}
-var r=new Region();for(var i=0;i<array.length;i+=4){r.rects.push(tr.b.math.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
-return r;};Region.fromArrayOrUndefined=function(array){if(array===undefined)return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects:function(r){for(var i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))return true;}
-return false;},addRect:function(r){this.rects.push(r);}};return{Region,};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
-return{TileCoverageRect,};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize:function(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['children','maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.math.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.math.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
-if(this.children){for(var i=0;i<this.children.length;i++){this.children[i].parentLayer=this;}}
+const r=new Region();for(let i=0;i<array.length;i+=4){r.rects.push(tr.b.math.Rect.fromXYWH(array[i],array[i+1],array[i+2],array[i+3]));}
+return r;};Region.fromArrayOrUndefined=function(array){if(array===undefined)return new Region();return Region.fromArray(array);};Region.prototype={__proto__:Region.prototype,rectIntersects(r){for(let i=0;i<this.rects.length;i++){if(this.rects[i].intersects(r))return true;}
+return false;},addRect(r){this.rects.push(r);}};return{Region,};});'use strict';tr.exportTo('tr.e.cc',function(){function TileCoverageRect(rect,tile){this.geometryRect=rect;this.tile=tile;}
+return{TileCoverageRect,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;function LayerImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.layerTreeImpl_=undefined;this.parentLayer=undefined;},initialize(){this.invalidation=new tr.e.cc.Region();this.annotatedInvalidation=new tr.e.cc.Region();this.unrecordedRegion=new tr.e.cc.Region();this.pictures=[];tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['layerId','layerQuad']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['children','maskLayer','replicaLayer','idealContentsScale','geometryContentsScale','layoutRects','usingGpuRasterization']);this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;this.bounds=tr.b.math.Rect.fromXYWH(0,0,this.args.bounds.width,this.args.bounds.height);if(this.args.animationBounds){this.animationBoundsRect=tr.b.math.Rect.fromXYWH(this.args.animationBounds[0],this.args.animationBounds[1],this.args.animationBounds[3],this.args.animationBounds[4]);}
+if(this.children){for(let i=0;i<this.children.length;i++){this.children[i].parentLayer=this;}}
 if(this.maskLayer){this.maskLayer.parentLayer=this;}
 if(this.replicaLayer){this.replicaLayer.parentLayer=this;}
 if(!this.geometryContentsScale){this.geometryContentsScale=1.0;}
@@ -6127,49 +6447,49 @@
 this.touchEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.touchEventHandlerRegion);this.wheelEventHandlerRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.wheelEventHandlerRegion);this.nonFastScrollableRegion=tr.e.cc.Region.fromArrayOrUndefined(this.args.nonFastScrollableRegion);},get layerTreeImpl(){if(this.layerTreeImpl_){return this.layerTreeImpl_;}
 if(this.parentLayer){return this.parentLayer.layerTreeImpl;}
 return undefined;},set layerTreeImpl(layerTreeImpl){this.layerTreeImpl_=layerTreeImpl;},get activeLayer(){if(this.layerTreeImpl.whichTree===constants.ACTIVE_TREE){return this;}
-var activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree===constants.PENDING_TREE){return this;}
-var pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
-PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize:function(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
-if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(var i=0;i<this.args.annotatedInvalidationRects.length;++i){var annotatedRect=this.args.annotatedInvalidationRects[i];var rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
+const activeTree=this.layerTreeImpl.layerTreeHostImpl.activeTree;return activeTree.findLayerWithId(this.layerId);},get pendingLayer(){if(this.layerTreeImpl.whichTree===constants.PENDING_TREE){return this;}
+const pendingTree=this.layerTreeImpl.layerTreeHostImpl.pendingTree;return pendingTree.findLayerWithId(this.layerId);}};function PictureLayerImplSnapshot(){LayerImplSnapshot.apply(this,arguments);}
+PictureLayerImplSnapshot.prototype={__proto__:LayerImplSnapshot.prototype,initialize(){LayerImplSnapshot.prototype.initialize.call(this);if(this.args.invalidation){this.invalidation=tr.e.cc.Region.fromArray(this.args.invalidation);delete this.args.invalidation;}
+if(this.args.annotatedInvalidationRects){this.annotatedInvalidation=new tr.e.cc.Region();for(let i=0;i<this.args.annotatedInvalidationRects.length;++i){const annotatedRect=this.args.annotatedInvalidationRects[i];const rect=annotatedRect.geometryRect;rect.reason=annotatedRect.reason;this.annotatedInvalidation.addRect(rect);}
 delete this.args.annotatedInvalidationRects;}
 if(this.args.unrecordedRegion){this.unrecordedRegion=tr.e.cc.Region.fromArray(this.args.unrecordedRegion);delete this.args.unrecordedRegion;}
 if(this.args.pictures){this.pictures=this.args.pictures;this.pictures.sort(function(a,b){return a.ts-b.ts;});}
-this.tileCoverageRects=[];if(this.args.coverageTiles){for(var i=0;i<this.args.coverageTiles.length;++i){var rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);var tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
-delete this.args.coverageTiles;}}};ObjectSnapshot.subTypes.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.subTypes.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SolidColorScrollbarLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot,PictureLayerImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['renderSurfaceLayerList']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['rootLayer','layers']);if(this.args.sourceFrameNumber){this.sourceFrameNumber=this.args.sourceFrameNumber;}
-if(this.rootLayer){this.rootLayer.layerTreeImpl=this;}else{for(var i=0;i<this.layers.length;i++){this.layers[i].layerTreeImpl=this;}}
-if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];var ownProcess=this.objectInstance.parent;var modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper){this._initializeTracedInputLatencies(modelHelper);}}},_initializeTracedInputLatencies:function(modelHelper){var latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(var i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id){continue;}
+this.tileCoverageRects=[];if(this.args.coverageTiles){for(let i=0;i<this.args.coverageTiles.length;++i){const rect=this.args.coverageTiles[i].geometryRect.scale(this.idealContentsScale);const tile=this.args.coverageTiles[i].tile;this.tileCoverageRects.push(new tr.e.cc.TileCoverageRect(rect,tile));}
+delete this.args.coverageTiles;}}};ObjectSnapshot.subTypes.register(PictureLayerImplSnapshot,{typeName:'cc::PictureLayerImpl'});ObjectSnapshot.subTypes.register(LayerImplSnapshot,{typeNames:['cc::LayerImpl','cc::DelegatedRendererLayerImpl','cc::HeadsUpDisplayLayerImpl','cc::IOSurfaceLayerImpl','cc::NinePatchLayerImpl','cc::PictureImageLayerImpl','cc::ScrollbarLayerImpl','cc::SolidColorLayerImpl','cc::SolidColorScrollbarLayerImpl','cc::SurfaceLayerImpl','cc::TextureLayerImpl','cc::TiledLayerImpl','cc::VideoLayerImpl','cc::PaintedScrollbarLayerImpl','ClankPatchLayer','TabBorderLayer','CounterLayer']});return{LayerImplSnapshot,PictureLayerImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;function LayerTreeImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);this.layerTreeHostImpl=undefined;this.whichTree=undefined;this.sourceFrameNumber=undefined;},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['renderSurfaceLayerList']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['rootLayer','layers']);if(this.args.sourceFrameNumber){this.sourceFrameNumber=this.args.sourceFrameNumber;}
+if(this.rootLayer){this.rootLayer.layerTreeImpl=this;}else{for(let i=0;i<this.layers.length;i++){this.layers[i].layerTreeImpl=this;}}
+if(this.args.swapPromiseTraceIds&&this.args.swapPromiseTraceIds.length){this.tracedInputLatencies=[];const ownProcess=this.objectInstance.parent;const modelHelper=ownProcess.model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper){this._initializeTracedInputLatencies(modelHelper);}}},_initializeTracedInputLatencies(modelHelper){const latencyEvents=modelHelper.browserHelper.getLatencyEventsInRange(modelHelper.model.bounds);latencyEvents.forEach(function(event){for(let i=0;i<this.args.swapPromiseTraceIds.length;i++){if(!event.args.data||!event.args.data.trace_id){continue;}
 if(parseInt(event.args.data.trace_id)===this.args.swapPromiseTraceIds[i]){this.tracedInputLatencies.push(event);}}},this);},get hasSourceFrameBeenDrawnBefore(){if(this.whichTree===tr.e.cc.constants.PENDING_TREE){return false;}
-if(this.sourceFrameNumber===undefined)return;var thisLTHI=this.layerTreeHostImpl;var thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);var prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length){return false;}
-var prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)return;return prevLTHI.activeTree.sourceFrameNumber===this.sourceFrameNumber;},get otherTree(){var other=this.whichTree===constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){var totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined){totalBytes+=layer.gpuMemoryUsageInBytes;}});return totalBytes;},iterLayers:function(func,thisArg){var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(var i=0;i<layer.children.length;i++){visitLayer(layer.children[i],depth+1);}}
+if(this.sourceFrameNumber===undefined)return;const thisLTHI=this.layerTreeHostImpl;const thisLTHIIndex=thisLTHI.objectInstance.snapshots.indexOf(thisLTHI);const prevLTHIIndex=thisLTHIIndex-1;if(prevLTHIIndex<0||prevLTHIIndex>=thisLTHI.objectInstance.snapshots.length){return false;}
+const prevLTHI=thisLTHI.objectInstance.snapshots[prevLTHIIndex];if(!prevLTHI.activeTree)return false;if(prevLTHI.activeTree.sourceFrameNumber===undefined)return;return prevLTHI.activeTree.sourceFrameNumber===this.sourceFrameNumber;},get otherTree(){const other=this.whichTree===constants.ACTIVE_TREE?constants.PENDING_TREE:constants.ACTIVE_TREE;return this.layerTreeHostImpl.getTree(other);},get gpuMemoryUsageInBytes(){let totalBytes=0;this.iterLayers(function(layer){if(layer.gpuMemoryUsageInBytes!==undefined){totalBytes+=layer.gpuMemoryUsageInBytes;}});return totalBytes;},iterLayers(func,thisArg){const visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;func.call(thisArg,layer,depth,isMask,isReplica);if(layer.children){for(let i=0;i<layer.children.length;i++){visitLayer(layer.children[i],depth+1);}}
 if(layer.maskLayer){visitLayer(layer.maskLayer,depth+1,true,false);}
 if(layer.replicaLayer){visitLayer(layer.replicaLayer,depth+1,false,true);}}
-if(this.rootLayer){visitLayer(this.rootLayer,0,false,false);}else{for(var i=0;i<this.layers.length;i++){visitLayer(this.layers[i],0,false,false);}}},findLayerWithId:function(id){var foundLayer=undefined;function visitLayer(layer){if(layer.layerId===id){foundLayer=layer;}}
-this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.subTypes.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){var constants=tr.e.cc.constants;var ObjectSnapshot=tr.model.ObjectSnapshot;var ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
-LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
+if(this.rootLayer){visitLayer(this.rootLayer,0,false,false);}else{for(let i=0;i<this.layers.length;i++){visitLayer(this.layers[i],0,false,false);}}},findLayerWithId(id){let foundLayer=undefined;function visitLayer(layer){if(layer.layerId===id){foundLayer=layer;}}
+this.iterLayers(visitLayer);return foundLayer;}};ObjectSnapshot.subTypes.register(LayerTreeImplSnapshot,{typeName:'cc::LayerTreeImpl'});return{LayerTreeImplSnapshot,};});'use strict';tr.exportTo('tr.e.cc',function(){const constants=tr.e.cc.constants;const ObjectSnapshot=tr.model.ObjectSnapshot;const ObjectInstance=tr.model.ObjectInstance;function LayerTreeHostImplSnapshot(){ObjectSnapshot.apply(this,arguments);}
+LayerTreeHostImplSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['deviceViewportSize','activeTree']);tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['pendingTree']);if(this.args.activeTiles!==undefined){this.activeTiles=this.args.activeTiles;delete this.args.activeTiles;}else if(this.args.tiles!==undefined){this.activeTiles=this.args.tiles;delete this.args.tiles;}
 if(!this.activeTiles){this.activeTiles=[];}
-this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames:function(){var scales={};for(var i=0;i<this.activeTiles.length;++i){var tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
-return scales;},getTree:function(whichTree){if(whichTree===constants.ACTIVE_TREE){return this.activeTree;}
+this.activeTree.layerTreeHostImpl=this;this.activeTree.whichTree=constants.ACTIVE_TREE;if(this.pendingTree){this.pendingTree.layerTreeHostImpl=this;this.pendingTree.whichTree=constants.PENDING_TREE;}},getContentsScaleNames(){const scales={};for(let i=0;i<this.activeTiles.length;++i){const tile=this.activeTiles[i];scales[tile.contentsScale]=tile.resolution;}
+return scales;},getTree(whichTree){if(whichTree===constants.ACTIVE_TREE){return this.activeTree;}
 if(whichTree===constants.PENDING_TREE){return this.pendingTree;}
 throw new Exception('Unknown tree type + '+whichTree);},get tilesHaveGpuMemoryUsageInfo(){if(this.tilesHaveGpuMemoryUsageInfo_!==undefined){return this.tilesHaveGpuMemoryUsageInfo_;}
-for(var i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined){continue;}
+for(let i=0;i<this.activeTiles.length;i++){if(this.activeTiles[i].gpuMemoryUsageInBytes===undefined){continue;}
 this.tilesHaveGpuMemoryUsageInfo_=true;return true;}
-this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)return;var usage=0;for(var i=0;i<this.activeTiles.length;i++){var u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)usage+=u;}
-return usage;},get userFriendlyName(){var frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{frameNumber=this.activeTree.sourceFrameNumber;}}
+this.tilesHaveGpuMemoryUsageInfo_=false;return false;},get gpuMemoryUsageInBytes(){if(!this.tilesHaveGpuMemoryUsageInfo)return;let usage=0;for(let i=0;i<this.activeTiles.length;i++){const u=this.activeTiles[i].gpuMemoryUsageInBytes;if(u!==undefined)usage+=u;}
+return usage;},get userFriendlyName(){let frameNumber;if(!this.activeTree){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{if(this.activeTree.sourceFrameNumber===undefined){frameNumber=this.objectInstance.snapshots.indexOf(this);}else{frameNumber=this.activeTree.sourceFrameNumber;}}
 return'cc::LayerTreeHostImpl frame '+frameNumber;}};ObjectSnapshot.subTypes.register(LayerTreeHostImplSnapshot,{typeName:'cc::LayerTreeHostImpl'});function LayerTreeHostImplInstance(){ObjectInstance.apply(this,arguments);this.allLayersBBox_=undefined;}
 LayerTreeHostImplInstance.prototype={__proto__:ObjectInstance.prototype,get allContentsScales(){if(this.allContentsScales_){return this.allContentsScales_;}
-var scales={};for(var tileID in this.allTileHistories_){var tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
+const scales={};for(const tileID in this.allTileHistories_){const tileHistory=this.allTileHistories_[tileID];scales[tileHistory.contentsScale]=true;}
 this.allContentsScales_=Object.keys(scales);return this.allContentsScales_;},get allLayersBBox(){if(this.allLayersBBox_){return this.allLayersBBox_;}
-var bbox=new tr.b.math.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
-this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree){handleTree(lthi.pendingTree);}});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.subTypes.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot,LayerTreeHostImplInstance,};});'use strict';tr.exportTo('tr.e.cc',function(){var tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};var tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes:tileTypes,tileBorder:tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
-TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
+const bbox=new tr.b.math.BBox2();function handleTree(tree){tree.renderSurfaceLayerList.forEach(function(layer){bbox.addQuad(layer.layerQuad);});}
+this.snapshots.forEach(function(lthi){handleTree(lthi.activeTree);if(lthi.pendingTree){handleTree(lthi.pendingTree);}});this.allLayersBBox_=bbox;return this.allLayersBBox_;}};ObjectInstance.subTypes.register(LayerTreeHostImplInstance,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshot,LayerTreeHostImplInstance,};});'use strict';tr.exportTo('tr.e.cc',function(){const tileTypes={highRes:'highRes',lowRes:'lowRes',extraHighRes:'extraHighRes',extraLowRes:'extraLowRes',missing:'missing',culled:'culled',solidColor:'solidColor',picture:'picture',directPicture:'directPicture',unknown:'unknown'};const tileBorder={highRes:{color:'rgba(80, 200, 200, 0.7)',width:1},lowRes:{color:'rgba(212, 83, 192, 0.7)',width:2},extraHighRes:{color:'rgba(239, 231, 20, 0.7)',width:2},extraLowRes:{color:'rgba(93, 186, 18, 0.7)',width:2},missing:{color:'rgba(255, 0, 0, 0.7)',width:1},culled:{color:'rgba(160, 100, 0, 0.8)',width:1},solidColor:{color:'rgba(128, 128, 128, 0.7)',width:1},picture:{color:'rgba(64, 64, 64, 0.7)',width:1},directPicture:{color:'rgba(127, 255, 0, 1.0)',width:1},unknown:{color:'rgba(0, 0, 0, 1.0)',width:2}};return{tileTypes,tileBorder};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function TileSnapshot(){ObjectSnapshot.apply(this,arguments);}
+TileSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveOptionalFieldsFromArgsToToplevel(this,['layerId','contentsScale','contentRect']);if(this.args.managedState){this.resolution=this.args.managedState.resolution;this.isSolidColor=this.args.managedState.isSolidColor;this.isUsingGpuMemory=this.args.managedState.isUsingGpuMemory;this.hasResource=this.args.managedState.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}else{this.resolution=this.args.resolution;this.isSolidColor=this.args.drawInfo.isSolidColor;this.isUsingGpuMemory=this.args.isUsingGpuMemory;this.hasResource=this.args.hasResource;this.scheduledPriority=this.args.scheduledPriority;this.gpuMemoryUsageInBytes=this.args.gpuMemoryUsage;}
 if(this.contentRect){this.layerRect=this.contentRect.scale(1.0/this.contentsScale);}
-if(this.isSolidColor){this.type_=tr.e.cc.tileTypes.solidColor;}else if(!this.hasResource){this.type_=tr.e.cc.tileTypes.missing;}else if(this.resolution==='HIGH_RESOLUTION'){this.type_=tr.e.cc.tileTypes.highRes;}else if(this.resolution==='LOW_RESOLUTION'){this.type_=tr.e.cc.tileTypes.lowRes;}else{this.type_=tr.e.cc.tileTypes.unknown;}},getTypeForLayer:function(layer){var type=this.type_;if(type===tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale){type=tr.e.cc.tileTypes.extraLowRes;}else if(this.contentsScale>layer.idealContentsScale){type=tr.e.cc.tileTypes.extraHighRes;}}
-return type;}};ObjectSnapshot.subTypes.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){var Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;}
-UIState.fromUserFriendlyString=function(model,viewport,stateString){var navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;var match=navByFinderPattern.exec(stateString);if(!match)return;var timestamp=parseFloat(match[1]);var stableId=match[3];var scaleX=parseFloat(match[4]);if(scaleX<=0){throw new Error('Invalid ScaleX value in UI State string.');}
+if(this.isSolidColor){this.type_=tr.e.cc.tileTypes.solidColor;}else if(!this.hasResource){this.type_=tr.e.cc.tileTypes.missing;}else if(this.resolution==='HIGH_RESOLUTION'){this.type_=tr.e.cc.tileTypes.highRes;}else if(this.resolution==='LOW_RESOLUTION'){this.type_=tr.e.cc.tileTypes.lowRes;}else{this.type_=tr.e.cc.tileTypes.unknown;}},getTypeForLayer(layer){let type=this.type_;if(type===tr.e.cc.tileTypes.unknown){if(this.contentsScale<layer.idealContentsScale){type=tr.e.cc.tileTypes.extraLowRes;}else if(this.contentsScale>layer.idealContentsScale){type=tr.e.cc.tileTypes.extraHighRes;}}
+return type;}};ObjectSnapshot.subTypes.register(TileSnapshot,{typeName:'cc::Tile'});return{TileSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const Location=tr.model.Location;function UIState(location,scaleX){this.location_=location;this.scaleX_=scaleX;}
+UIState.fromUserFriendlyString=function(model,viewport,stateString){const navByFinderPattern=/^(-?\d+(\.\d+)?)@(.+)x(\d+(\.\d+)?)$/g;const match=navByFinderPattern.exec(stateString);if(!match)return;const timestamp=parseFloat(match[1]);const stableId=match[3];const scaleX=parseFloat(match[4]);if(scaleX<=0){throw new Error('Invalid ScaleX value in UI State string.');}
 if(!viewport.containerToTrackMap.getTrackByStableId(stableId)){throw new Error('Invalid StableID given in UI State String.');}
-var loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);};UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString:function(viewport){var timestamp=this.location_.xWorld;var stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;var scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict:function(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState,};});'use strict';tr.exportTo('tr.ui.b',function(){var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocateSimple();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
-BrushingState.prototype={get guid(){return this.guid_;},clone:function(){var that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals:function(that){if(!this.selection_.equals(that.selection_)){return false;}
+const loc=tr.model.Location.fromStableIdAndTimestamp(viewport,stableId,timestamp);return new UIState(loc,scaleX);};UIState.prototype={get location(){return this.location_;},get scaleX(){return this.scaleX_;},toUserFriendlyString(viewport){const timestamp=this.location_.xWorld;const stableId=this.location_.getContainingTrack(viewport).eventContainer.stableId;const scaleX=this.scaleX_;return timestamp.toFixed(5)+'@'+stableId+'x'+scaleX.toFixed(5);},toDict(){return{location:this.location_.toDict(),scaleX:this.scaleX_};}};return{UIState,};});'use strict';tr.exportTo('tr.ui.b',function(){const EventSet=tr.model.EventSet;const SelectionState=tr.model.SelectionState;function BrushingState(){this.guid_=tr.b.GUID.allocateSimple();this.selection_=new EventSet();this.findMatches_=new EventSet();this.analysisViewRelatedEvents_=new EventSet();this.analysisLinkHoveredEvents_=new EventSet();this.appliedToModel_=undefined;this.viewSpecificBrushingStates_={};}
+BrushingState.prototype={get guid(){return this.guid_;},clone(){const that=new BrushingState();that.selection_=this.selection_;that.findMatches_=this.findMatches_;that.analysisViewRelatedEvents_=this.analysisViewRelatedEvents_;that.analysisLinkHoveredEvents_=this.analysisLinkHoveredEvents_;that.viewSpecificBrushingStates_=this.viewSpecificBrushingStates_;return that;},equals(that){if(!this.selection_.equals(that.selection_)){return false;}
 if(!this.findMatches_.equals(that.findMatches_)){return false;}
 if(!this.analysisViewRelatedEvents_.equals(that.analysisViewRelatedEvents_)){return false;}
 if(!this.analysisLinkHoveredEvents_.equals(that.analysisLinkHoveredEvents_)){return false;}
@@ -6185,45 +6505,45 @@
 if(analysisViewRelatedEvents===undefined){analysisViewRelatedEvents=new EventSet();}
 this.analysisViewRelatedEvents_=analysisViewRelatedEvents;},get analysisLinkHoveredEvents(){return this.analysisLinkHoveredEvents_;},set analysisLinkHoveredEvents(analysisLinkHoveredEvents){if(this.appliedToModel_){throw new Error('Cannot mutate this state right now');}
 if(analysisLinkHoveredEvents===undefined){analysisLinkHoveredEvents=new EventSet();}
-this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get dimmedEvents_(){var dimmedEvents=new EventSet();dimmedEvents.addEventSet(this.findMatches);dimmedEvents.addEventSet(this.analysisViewRelatedEvents_);return dimmedEvents;},get brightenedEvents_(){var brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToEventSelectionStates:function(model){this.appliedToModel_=model;var dimmedEvents=this.dimmedEvents_;if(model){var newDefaultState=(dimmedEvents.length?SelectionState.DIMMED0:SelectionState.NONE);var currentDefaultState=tr.b.getFirstElement(model.getDescendantEvents()).selectionState;if(currentDefaultState!==newDefaultState){for(var e of model.getDescendantEvents()){e.selectionState=newDefaultState;}}}
-var score;for(var e of dimmedEvents){score=0;if(this.findMatches_.contains(e)){score++;}
+this.analysisLinkHoveredEvents_=analysisLinkHoveredEvents;},get isAppliedToModel(){return this.appliedToModel_!==undefined;},get viewSpecificBrushingStates(){return this.viewSpecificBrushingStates_;},set viewSpecificBrushingStates(viewSpecificBrushingStates){this.viewSpecificBrushingStates_=viewSpecificBrushingStates;},get dimmedEvents_(){const dimmedEvents=new EventSet();dimmedEvents.addEventSet(this.findMatches);dimmedEvents.addEventSet(this.analysisViewRelatedEvents_);return dimmedEvents;},get brightenedEvents_(){const brightenedEvents=new EventSet();brightenedEvents.addEventSet(this.selection_);brightenedEvents.addEventSet(this.analysisLinkHoveredEvents_);return brightenedEvents;},applyToEventSelectionStates(model){this.appliedToModel_=model;const dimmedEvents=this.dimmedEvents_;if(model){const newDefaultState=(dimmedEvents.length?SelectionState.DIMMED0:SelectionState.NONE);const currentDefaultState=tr.b.getFirstElement(model.getDescendantEvents()).selectionState;if(currentDefaultState!==newDefaultState){for(const e of model.getDescendantEvents()){e.selectionState=newDefaultState;}}}
+let score;for(const e of dimmedEvents){score=0;if(this.findMatches_.contains(e)){score++;}
 if(this.analysisViewRelatedEvents_.contains(e)){score++;}
 e.selectionState=SelectionState.getFromDimmingLevel(score);}
-for(var e of this.brightenedEvents_){score=0;if(this.selection_.contains(e)){score++;}
+for(const e of this.brightenedEvents_){score=0;if(this.selection_.contains(e)){score++;}
 if(this.analysisLinkHoveredEvents_.contains(e)){score++;}
-e.selectionState=SelectionState.getFromBrighteningLevel(score);}},transferModelOwnershipToClone:function(that){if(!this.appliedToModel_){throw new Error('Not applied');}
-that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromEventSelectionStates:function(){if(!this.appliedToModel_){throw new Error('Not applied');}
-var model=this.appliedToModel_;this.appliedToModel_=undefined;var dimmedEvents=this.dimmedEvents_;var defaultState=(dimmedEvents.length?SelectionState.DIMMED0:SelectionState.NONE);for(var e of this.brightenedEvents_){e.selectionState=defaultState;}
-for(var e of dimmedEvents){e.selectionState=defaultState;}
+e.selectionState=SelectionState.getFromBrighteningLevel(score);}},transferModelOwnershipToClone(that){if(!this.appliedToModel_){throw new Error('Not applied');}
+that.appliedToModel_=this.appliedToModel_;this.appliedToModel_=undefined;},unapplyFromEventSelectionStates(){if(!this.appliedToModel_){throw new Error('Not applied');}
+const model=this.appliedToModel_;this.appliedToModel_=undefined;const dimmedEvents=this.dimmedEvents_;const defaultState=(dimmedEvents.length?SelectionState.DIMMED0:SelectionState.NONE);for(const e of this.brightenedEvents_){e.selectionState=defaultState;}
+for(const e of dimmedEvents){e.selectionState=defaultState;}
 return defaultState;}};return{BrushingState,};});'use strict';tr.exportTo('tr.ui.b',function(){function Animation(){}
-Animation.prototype={canTakeOverFor:function(existingAnimation){throw new Error('Not implemented');},takeOverFor:function(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start:function(timestamp,target){throw new Error('Not implemented');},didStopEarly:function(timestamp,target,willBeTakenOverByAnotherAnimation){},tick:function(timestamp,target){throw new Error('Not implemented');}};return{Animation,};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
+Animation.prototype={canTakeOverFor(existingAnimation){throw new Error('Not implemented');},takeOverFor(existingAnimation,newStartTimestamp,target){throw new Error('Not implemented');},start(timestamp,target){throw new Error('Not implemented');},didStopEarly(timestamp,target,willBeTakenOverByAnotherAnimation){},tick(timestamp,target){throw new Error('Not implemented');}};return{Animation,};});'use strict';tr.exportTo('tr.ui.b',function(){function AnimationController(){tr.b.EventTarget.call(this);this.target_=undefined;this.activeAnimation_=undefined;this.tickScheduled_=false;}
 AnimationController.prototype={__proto__:tr.b.EventTarget.prototype,get target(){return this.target_;},set target(target){if(this.activeAnimation_){throw new Error('Cannot change target while animation is running.');}
 if(target.cloneAnimationState===undefined||typeof target.cloneAnimationState!=='function'){throw new Error('target must have a cloneAnimationState function');}
-this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation:function(animation,opt_now){if(this.target_===undefined){throw new Error('Cannot queue animations without a target');}
-var now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
-if(this.activeAnimation_){var done=this.activeAnimation_.tick(now,this.target_);if(done){this.activeAnimation_=undefined;}}
+this.target_=target;},get activeAnimation(){return this.activeAnimation_;},get hasActiveAnimation(){return!!this.activeAnimation_;},queueAnimation(animation,opt_now){if(this.target_===undefined){throw new Error('Cannot queue animations without a target');}
+let now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
+if(this.activeAnimation_){const done=this.activeAnimation_.tick(now,this.target_);if(done){this.activeAnimation_=undefined;}}
 if(this.activeAnimation_){if(animation.canTakeOverFor(this.activeAnimation_)){this.activeAnimation_.didStopEarly(now,this.target_,true);animation.takeOverFor(this.activeAnimation_,now,this.target_);}else{this.activeAnimation_.didStopEarly(now,this.target_,false);}}
-this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation:function(opt_now){if(!this.activeAnimation_)return;var now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
-this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_:function(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
-var oldTargetState=this.target_.cloneAnimationState();var done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done){this.activeAnimation_=undefined;}
+this.activeAnimation_=animation;this.activeAnimation_.start(now,this.target_);if(this.tickScheduled_)return;this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);},cancelActiveAnimation(opt_now){if(!this.activeAnimation_)return;let now;if(opt_now!==undefined){now=opt_now;}else{now=window.performance.now();}
+this.activeAnimation_.didStopEarly(now,this.target_,false);this.activeAnimation_=undefined;},tickActiveAnimation_(frameBeginTime){this.tickScheduled_=false;if(!this.activeAnimation_)return;if(this.target_===undefined){this.activeAnimation_.didStopEarly(frameBeginTime,this.target_,false);return;}
+const oldTargetState=this.target_.cloneAnimationState();const done=this.activeAnimation_.tick(frameBeginTime,this.target_);if(done){this.activeAnimation_=undefined;}
 if(this.activeAnimation_){this.tickScheduled_=true;tr.b.requestAnimationFrame(this.tickActiveAnimation_,this);}
-if(oldTargetState){var e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController,};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;}
-if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless){Settings.setAlternativeStorageInstance(new HeadlessStorage());}else{Settings.setAlternativeStorageInstance(global.sessionStorage);}});}
+if(oldTargetState){const e=new tr.b.Event('didtick');e.oldTargetState=oldTargetState;this.dispatchEvent(e,false,false);}}};return{AnimationController,};});'use strict';tr.exportTo('tr.b',function(){function Settings(){return Settings;}
+if(tr.b.unittest&&tr.b.unittest.TestRunner){tr.b.unittest.TestRunner.addEventListener('tr-unittest-will-run',function(){if(tr.isHeadless){Settings.setAlternativeStorageInstance(new HeadlessStorage());}else{Settings.setAlternativeStorageInstance(global.sessionStorage);global.sessionStorage.clear();}});}
 function SessionSettings(){return SessionSettings;}
-function AddStaticStorageFunctionsToClass_(inputClass,storage){inputClass.storage_=storage;inputClass.get=function(key,opt_default,opt_namespace){key=inputClass.namespace_(key,opt_namespace);var rawVal=inputClass.storage_.getItem(key);if(rawVal===null||rawVal===undefined){return opt_default;}
+function AddStaticStorageFunctionsToClass_(inputClass,storage){inputClass.storage_=storage;inputClass.get=function(key,opt_default,opt_namespace){key=inputClass.namespace_(key,opt_namespace);const rawVal=inputClass.storage_.getItem(key);if(rawVal===null||rawVal===undefined){return opt_default;}
 try{return JSON.parse(rawVal).value;}catch(e){inputClass.storage_.removeItem(key);return opt_default;}};inputClass.set=function(key,value,opt_namespace){if(value===undefined){throw new Error('Settings.set: value must not be undefined');}
-var v=JSON.stringify({value:value});inputClass.storage_.setItem(inputClass.namespace_(key,opt_namespace),v);};inputClass.keys=function(opt_namespace){var result=[];opt_namespace=opt_namespace||'';for(var i=0;i<inputClass.storage_.length;i++){var key=inputClass.storage_.key(i);if(inputClass.isnamespaced_(key,opt_namespace)){result.push(inputClass.unnamespace_(key,opt_namespace));}}
+const v=JSON.stringify({value});inputClass.storage_.setItem(inputClass.namespace_(key,opt_namespace),v);};inputClass.keys=function(opt_namespace){const result=[];opt_namespace=opt_namespace||'';for(let i=0;i<inputClass.storage_.length;i++){const key=inputClass.storage_.key(i);if(inputClass.isnamespaced_(key,opt_namespace)){result.push(inputClass.unnamespace_(key,opt_namespace));}}
 return result;};inputClass.isnamespaced_=function(key,opt_namespace){return key.indexOf(inputClass.normalize_(opt_namespace))===0;};inputClass.namespace_=function(key,opt_namespace){return inputClass.normalize_(opt_namespace)+key;};inputClass.unnamespace_=function(key,opt_namespace){return key.replace(inputClass.normalize_(opt_namespace),'');};inputClass.normalize_=function(opt_namespace){return inputClass.NAMESPACE+(opt_namespace?opt_namespace+'.':'');};inputClass.setAlternativeStorageInstance=function(instance){inputClass.storage_=instance;};inputClass.getAlternativeStorageInstance=function(){if(!tr.isHeadless&&inputClass.storage_===localStorage){return undefined;}
 return inputClass.storage_;};inputClass.NAMESPACE='trace-viewer';}
 function HeadlessStorage(){this.length=0;this.hasItem_={};this.items_={};this.itemsAsArray_=undefined;}
-HeadlessStorage.prototype={key:function(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined){return this.itemsAsArray_;}
-var itemsAsArray=[];for(var k in this.items_){itemsAsArray.push(k);}
-this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem:function(key){if(!this.hasItem_[key]){return null;}
-return this.items_[key];},removeItem:function(key){if(!this.hasItem_[key]){return;}
-var value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem:function(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
+HeadlessStorage.prototype={key(index){return this.itemsAsArray[index];},get itemsAsArray(){if(this.itemsAsArray_!==undefined){return this.itemsAsArray_;}
+const itemsAsArray=[];for(const k in this.items_){itemsAsArray.push(k);}
+this.itemsAsArray_=itemsAsArray;return this.itemsAsArray_;},getItem(key){if(!this.hasItem_[key]){return null;}
+return this.items_[key];},removeItem(key){if(!this.hasItem_[key]){return;}
+const value=this.items_[key];delete this.hasItem_[key];delete this.items_[key];this.length--;this.itemsAsArray_=undefined;return value;},setItem(key,value){if(this.hasItem_[key]){this.items_[key]=value;return;}
 this.items_[key]=value;this.hasItem_[key]=true;this.length++;this.itemsAsArray_=undefined;return value;}};if(tr.isHeadless){AddStaticStorageFunctionsToClass_(Settings,new HeadlessStorage());AddStaticStorageFunctionsToClass_(SessionSettings,new HeadlessStorage());}else{AddStaticStorageFunctionsToClass_(Settings,localStorage);AddStaticStorageFunctionsToClass_(SessionSettings,sessionStorage);}
-return{Settings,SessionSettings,};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){var ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument){ownerDocument=opt_dictionary.ownerDocument;}
-var spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className){spanEl.className=opt_dictionary.className;}
+return{Settings,SessionSettings,};});'use strict';tr.exportTo('tr.ui.b',function(){function createSpan(opt_dictionary){let ownerDocument=document;if(opt_dictionary&&opt_dictionary.ownerDocument){ownerDocument=opt_dictionary.ownerDocument;}
+const spanEl=ownerDocument.createElement('span');if(opt_dictionary){if(opt_dictionary.className){spanEl.className=opt_dictionary.className;}
 if(opt_dictionary.textContent){Polymer.dom(spanEl).textContent=opt_dictionary.textContent;}
 if(opt_dictionary.tooltip){spanEl.title=opt_dictionary.tooltip;}
 if(opt_dictionary.parent){Polymer.dom(opt_dictionary.parent).appendChild(spanEl);}
@@ -6234,99 +6554,99 @@
 if(opt_dictionary.backgroundColor){spanEl.style.backgroundColor=opt_dictionary.backgroundColor;}
 if(opt_dictionary.color){spanEl.style.color=opt_dictionary.color;}}
 return spanEl;}
-function createLink(opt_args){var ownerDocument=document;if(opt_args&&opt_args.ownerDocument){ownerDocument=opt_args.ownerDocument;}
-var linkEl=ownerDocument.createElement('a');if(opt_args){if(opt_args.href)linkEl.href=opt_args.href;if(opt_args.tooltip)linkEl.title=opt_args.tooltip;if(opt_args.color)linkEl.style.color=opt_args.color;if(opt_args.bold)linkEl.style.fontWeight='bold';if(opt_args.italic)linkEl.style.fontStyle='italic';if(opt_args.className)linkEl.className=opt_args.className;if(opt_args.parent)Polymer.dom(opt_args.parent).appendChild(linkEl);if(opt_args.marginLeft)linkEl.style.marginLeft=opt_args.marginLeft;if(opt_args.marginRight)linkEl.style.marginRight=opt_args.marginRight;if(opt_args.backgroundColor){linkEl.style.backgroundColor=opt_args.backgroundColor;}
+function createLink(opt_args){let ownerDocument=document;if(opt_args&&opt_args.ownerDocument){ownerDocument=opt_args.ownerDocument;}
+const linkEl=ownerDocument.createElement('a');if(opt_args){if(opt_args.href)linkEl.href=opt_args.href;if(opt_args.tooltip)linkEl.title=opt_args.tooltip;if(opt_args.color)linkEl.style.color=opt_args.color;if(opt_args.bold)linkEl.style.fontWeight='bold';if(opt_args.italic)linkEl.style.fontStyle='italic';if(opt_args.className)linkEl.className=opt_args.className;if(opt_args.parent)Polymer.dom(opt_args.parent).appendChild(linkEl);if(opt_args.marginLeft)linkEl.style.marginLeft=opt_args.marginLeft;if(opt_args.marginRight)linkEl.style.marginRight=opt_args.marginRight;if(opt_args.backgroundColor){linkEl.style.backgroundColor=opt_args.backgroundColor;}
 if(opt_args.textContent){Polymer.dom(linkEl).textContent=opt_args.textContent;}}
 return linkEl;}
-function createDiv(opt_dictionary){var divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className){divEl.className=opt_dictionary.className;}
+function createDiv(opt_dictionary){const divEl=document.createElement('div');if(opt_dictionary){if(opt_dictionary.className){divEl.className=opt_dictionary.className;}
 if(opt_dictionary.parent){Polymer.dom(opt_dictionary.parent).appendChild(divEl);}
 if(opt_dictionary.textContent){Polymer.dom(divEl).textContent=opt_dictionary.textContent;}
 if(opt_dictionary.maxWidth){divEl.style.maxWidth=opt_dictionary.maxWidth;}}
 return divEl;}
-function createScopedStyle(styleContent){var styleEl=document.createElement('style');styleEl.scoped=true;Polymer.dom(styleEl).innerHTML=styleContent;return styleEl;}
+function createScopedStyle(styleContent){const styleEl=document.createElement('style');styleEl.scoped=true;Polymer.dom(styleEl).innerHTML=styleContent;return styleEl;}
 function valuesEqual(a,b){if(a instanceof Array&&b instanceof Array){return a.length===b.length&&JSON.stringify(a)===JSON.stringify(b);}
 return a===b;}
-function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){var defaultValueIndex;for(var i=0;i<items.length;i++){var item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
+function createSelector(targetEl,targetElProperty,settingsKey,defaultValue,items,opt_namespace){let defaultValueIndex;for(let i=0;i<items.length;i++){const item=items[i];if(valuesEqual(item.value,defaultValue)){defaultValueIndex=i;break;}}
 if(defaultValueIndex===undefined){throw new Error('defaultValue must be in the items list');}
-var selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(var i=0;i<items.length;i++){var item=items[i];var optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
-function onChange(e){var value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
-var oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(var i=0;i<selectorEl.children.length;i++){var value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){var changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;onChange();}
+const selectorEl=document.createElement('select');selectorEl.addEventListener('change',onChange);for(let i=0;i<items.length;i++){const item=items[i];const optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
+function onChange(e){const value=selectorEl.selectedOptions[0].targetPropertyValue;tr.b.Settings.set(settingsKey,value,opt_namespace);targetEl[targetElProperty]=value;}
+const oldSetter=targetEl.__lookupSetter__('selectedIndex');selectorEl.__defineGetter__('selectedValue',function(v){return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(let i=0;i<selectorEl.children.length;i++){const value=selectorEl.children[i].targetPropertyValue;if(valuesEqual(value,v)){const changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;onChange();}
 return;}}
-throw new Error('Not a valid value');});var initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);var didSet=false;for(var i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
+throw new Error('Not a valid value');});const initialValue=tr.b.Settings.get(settingsKey,defaultValue,opt_namespace);let didSet=false;for(let i=0;i<selectorEl.children.length;i++){if(valuesEqual(selectorEl.children[i].targetPropertyValue,initialValue)){didSet=true;targetEl[targetElProperty]=initialValue;selectorEl.selectedIndex=i;break;}}
 if(!didSet){selectorEl.selectedIndex=defaultValueIndex;targetEl[targetElProperty]=defaultValue;}
 return selectorEl;}
-function createEditCategorySpan(optionGroupEl,targetEl){var spanEl=createSpan({className:'edit-categories'});Polymer.dom(spanEl).textContent='Edit categories';Polymer.dom(spanEl).classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
-function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){var value=[];if(this.value.length){value=this.value.split(',');}
+function createEditCategorySpan(optionGroupEl,targetEl){const spanEl=createSpan({className:'edit-categories'});Polymer.dom(spanEl).textContent='Edit categories';Polymer.dom(spanEl).classList.add('labeled-option');spanEl.addEventListener('click',function(){targetEl.onClickEditCategories();});return spanEl;}
+function createOptionGroup(targetEl,targetElProperty,settingsKey,defaultValue,items){function onChange(){let value=[];if(this.value.length){value=this.value.split(',');}
 tr.b.Settings.set(settingsKey,value);targetEl[targetElProperty]=value;}
-var optionGroupEl=createSpan({className:'labeled-option-group'});var initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(var i=0;i<items.length;++i){var item=items[i];var id='category-preset-'+item.label.replace(/ /g,'-');var radioEl=document.createElement('input');radioEl.type='radio';Polymer.dom(radioEl).setAttribute('id',id);Polymer.dom(radioEl).setAttribute('name','category-presets-group');Polymer.dom(radioEl).setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value)){radioEl.checked=true;}
-var labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=item.label;Polymer.dom(labelEl).setAttribute('for',id);var spanEl=createSpan({className:'labeled-option'});Polymer.dom(spanEl).appendChild(radioEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=radioEl.checked!==(!!opt_bool);if(!changed)return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});Polymer.dom(optionGroupEl).appendChild(spanEl);}
+const optionGroupEl=createSpan({className:'labeled-option-group'});const initialValue=tr.b.Settings.get(settingsKey,defaultValue);for(let i=0;i<items.length;++i){const item=items[i];const id='category-preset-'+item.label.replace(/ /g,'-');const radioEl=document.createElement('input');radioEl.type='radio';Polymer.dom(radioEl).setAttribute('id',id);Polymer.dom(radioEl).setAttribute('name','category-presets-group');Polymer.dom(radioEl).setAttribute('value',item.value);radioEl.addEventListener('change',onChange.bind(radioEl,targetEl,targetElProperty,settingsKey));if(valuesEqual(initialValue,item.value)){radioEl.checked=true;}
+const labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=item.label;Polymer.dom(labelEl).setAttribute('for',id);const spanEl=createSpan({className:'labeled-option'});Polymer.dom(spanEl).appendChild(radioEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){const changed=radioEl.checked!==(!!opt_bool);if(!changed)return;radioEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return radioEl.checked;});Polymer.dom(optionGroupEl).appendChild(spanEl);}
 Polymer.dom(optionGroupEl).appendChild(createEditCategorySpan(optionGroupEl,targetEl));if(!initialValue.length){Polymer.dom(optionGroupEl).classList.add('categories-expanded');}
 targetEl[targetElProperty]=initialValue;return optionGroupEl;}
-var nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){var buttonEl=document.createElement('input');buttonEl.type='checkbox';var initialValue=defaultValue;if(settingsKey!==undefined){initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;}
+let nextCheckboxId=1;function createCheckBox(targetEl,targetElProperty,settingsKey,defaultValue,label,opt_changeCb){const buttonEl=document.createElement('input');buttonEl.type='checkbox';let initialValue=defaultValue;if(settingsKey!==undefined){initialValue=tr.b.Settings.get(settingsKey,defaultValue);buttonEl.checked=!!initialValue;}
 if(targetEl){targetEl[targetElProperty]=initialValue;}
 function onChange(){if(settingsKey!==undefined){tr.b.Settings.set(settingsKey,buttonEl.checked);}
 if(targetEl){targetEl[targetElProperty]=buttonEl.checked;}
 if(opt_changeCb){opt_changeCb.call();}}
-buttonEl.addEventListener('change',onChange);var id='#checkbox-'+nextCheckboxId++;var spanEl=createSpan({className:'labeled-checkbox'});Polymer.dom(buttonEl).setAttribute('id',id);var labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=label;Polymer.dom(labelEl).setAttribute('for',id);Polymer.dom(spanEl).appendChild(buttonEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){var changed=buttonEl.checked!==(!!opt_bool);if(!changed)return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
-function createButton(label,opt_callback,opt_this){var buttonEl=document.createElement('input');buttonEl.type='button';buttonEl.value=label;function onClick(){opt_callback.call(opt_this||buttonEl);}
+buttonEl.addEventListener('change',onChange);const id='#checkbox-'+nextCheckboxId++;const spanEl=createSpan({className:'labeled-checkbox'});Polymer.dom(buttonEl).setAttribute('id',id);const labelEl=document.createElement('label');Polymer.dom(labelEl).textContent=label;Polymer.dom(labelEl).setAttribute('for',id);Polymer.dom(spanEl).appendChild(buttonEl);Polymer.dom(spanEl).appendChild(labelEl);spanEl.__defineSetter__('checked',function(opt_bool){const changed=buttonEl.checked!==(!!opt_bool);if(!changed)return;buttonEl.checked=!!opt_bool;onChange();});spanEl.__defineGetter__('checked',function(){return buttonEl.checked;});return spanEl;}
+function createButton(label,opt_callback,opt_this){const buttonEl=document.createElement('input');buttonEl.type='button';buttonEl.value=label;function onClick(){opt_callback.call(opt_this||buttonEl);}
 if(opt_callback){buttonEl.addEventListener('click',onClick);}
 return buttonEl;}
-function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){var initialValue=tr.b.Settings.get(settingsKey,defaultValue);var el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
+function createTextInput(targetEl,targetElProperty,settingsKey,defaultValue){const initialValue=tr.b.Settings.get(settingsKey,defaultValue);const el=document.createElement('input');el.type='text';function onChange(e){tr.b.Settings.set(settingsKey,el.value);targetEl[targetElProperty]=el.value;}
 el.addEventListener('input',onChange);el.value=initialValue;targetEl[targetElProperty]=initialValue;return el;}
-function isElementAttachedToDocument(el){var cur=el;while(Polymer.dom(cur).parentNode){cur=Polymer.dom(cur).parentNode;}
+function isElementAttachedToDocument(el){let cur=el;while(Polymer.dom(cur).parentNode){cur=Polymer.dom(cur).parentNode;}
 return(cur===el.ownerDocument||cur.nodeName==='#document-fragment');}
 function asHTMLOrTextNode(value,opt_ownerDocument){if(value instanceof Node){return value;}
-var ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
-return{createSpan,createLink,createDiv,createScopedStyle,createSelector,createOptionGroup,createCheckBox,createButton,createTextInput,isElementAttachedToDocument,asHTMLOrTextNode,};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCacheDict=new Map();var elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap=new Map();}
-ElidedTitleCache.prototype={get:function(ctx,pixWidth,title,width,sliceDuration){var elidedDict=elidedTitleCacheDict.get(title);if(!elidedDict){elidedDict=new Map();elidedTitleCacheDict.set(title,elidedDict);}
-var elidedDictForPixWidth=elidedDict.get(pixWidth);if(!elidedDictForPixWidth){elidedDict.set(pixWidth,new Map());elidedDictForPixWidth=elidedDict.get(pixWidth);}
-var stringWidthPair=elidedDictForPixWidth.get(sliceDuration);if(stringWidthPair===undefined){var newtitle=title;var elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
+const ownerDocument=opt_ownerDocument||document;return ownerDocument.createTextNode(value);}
+return{createSpan,createLink,createDiv,createScopedStyle,createSelector,createOptionGroup,createCheckBox,createButton,createTextInput,isElementAttachedToDocument,asHTMLOrTextNode,};});'use strict';tr.exportTo('tr.ui.b',function(){const elidedTitleCacheDict=new Map();const elidedTitleCache=new ElidedTitleCache();function ElidedTitleCache(){this.textWidthMap=new Map();}
+ElidedTitleCache.prototype={get(ctx,pixWidth,title,width,sliceDuration){let elidedDict=elidedTitleCacheDict.get(title);if(!elidedDict){elidedDict=new Map();elidedTitleCacheDict.set(title,elidedDict);}
+let elidedDictForPixWidth=elidedDict.get(pixWidth);if(!elidedDictForPixWidth){elidedDict.set(pixWidth,new Map());elidedDictForPixWidth=elidedDict.get(pixWidth);}
+let stringWidthPair=elidedDictForPixWidth.get(sliceDuration);if(stringWidthPair===undefined){let newtitle=title;let elided=false;while(this.labelWidthWorld(ctx,newtitle,pixWidth)>sliceDuration){if(newtitle.length*0.75<1)break;newtitle=newtitle.substring(0,newtitle.length*0.75);elided=true;}
 if(elided&&newtitle.length>3){newtitle=newtitle.substring(0,newtitle.length-3)+'...';}
 stringWidthPair=new ElidedStringWidthPair(newtitle,this.labelWidth(ctx,newtitle));elidedDictForPixWidth.set(sliceDuration,stringWidthPair);}
-return stringWidthPair;},quickMeasureText_:function(ctx,text){var w=this.textWidthMap.get(text);if(!w){w=ctx.measureText(text).width;this.textWidthMap.set(text,w);}
-return w;},labelWidth:function(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld:function(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
-return{ElidedTitleCache,};});'use strict';tr.exportTo('tr.ui.b',function(){var ColorScheme=tr.b.ColorScheme;var colors=ColorScheme.colors;var colorsAsStrings=ColorScheme.colorsAsStrings;var numColorsPerVariant=ColorScheme.properties.numColorsPerVariant;var SelectionState=tr.model.SelectionState;var EventPresenter={getSelectableItemColorAsString:function(item){var colorId=item.colorId+this.getColorIdOffset_(item);return colorsAsStrings[colorId];},getColorIdOffset_:function(event){return event.selectionState;},getTextColor:function(event){if(event.selectionState===SelectionState.DIMMED){return'rgb(60,60,60)';}
-return'rgb(0,0,0)';},getSliceColorId:function(slice){return slice.colorId+this.getColorIdOffset_(slice);},getSliceAlpha:function(slice,async){var alpha=1;if(async){alpha*=0.3;}
-return alpha;},getInstantSliceColor:function(instant){var colorId=instant.colorId+this.getColorIdOffset_(instant);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor:function(instance){var colorId=instance.colorId+this.getColorIdOffset_(instance);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor:function(snapshot){var colorId=snapshot.objectInstance.colorId+this.getColorIdOffset_(snapshot);return colors[colorId];},getCounterSeriesColor:function(colorId,selectionState,opt_alphaMultiplier){var event={selectionState:selectionState};var c=colors[colorId+this.getColorIdOffset_(event)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor:function(snapshot,offset){var colorId=(snapshot.objectInstance.colorId+offset)%numColorsPerVariant;colorId+=this.getColorIdOffset_(snapshot);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter,};});'use strict';tr.exportTo('tr.ui.b',function(){var elidedTitleCache=new tr.ui.b.ElidedTitleCache();var ColorScheme=tr.b.ColorScheme;var colorsAsStrings=ColorScheme.colorsAsStrings;var EventPresenter=tr.ui.b.EventPresenter;var blackColorId=ColorScheme.getColorIdForReservedName('black');var THIN_SLICE_HEIGHT=4;var SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;var SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;var SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
+return stringWidthPair;},quickMeasureText_(ctx,text){let w=this.textWidthMap.get(text);if(!w){w=ctx.measureText(text).width;this.textWidthMap.set(text,w);}
+return w;},labelWidth(ctx,title){return this.quickMeasureText_(ctx,title)+2;},labelWidthWorld(ctx,title,pixWidth){return this.labelWidth(ctx,title)*pixWidth;}};function ElidedStringWidthPair(string,width){this.string=string;this.width=width;}
+return{ElidedTitleCache,};});'use strict';tr.exportTo('tr.ui.b',function(){const ColorScheme=tr.b.ColorScheme;const colors=ColorScheme.colors;const colorsAsStrings=ColorScheme.colorsAsStrings;const SelectionState=tr.model.SelectionState;const EventPresenter={getSelectableItemColorAsString(item){const offset=this.getColorIdOffset_(item);const colorId=ColorScheme.getVariantColorId(item.colorId,offset);return colorsAsStrings[colorId];},getColorIdOffset_(event){return event.selectionState;},getTextColor(event){if(event.selectionState===SelectionState.DIMMED){return'rgb(60,60,60)';}
+return'rgb(0,0,0)';},getSliceColorId(slice){const offset=this.getColorIdOffset_(slice);return ColorScheme.getVariantColorId(slice.colorId,offset);},getSliceAlpha(slice,async){let alpha=1;if(async){alpha*=0.3;}
+return alpha;},getInstantSliceColor(instant){const offset=this.getColorIdOffset_(instant);const colorId=ColorScheme.getVariantColorId(instant.colorId,offset);return colors[colorId].toStringWithAlphaOverride(1.0);},getObjectInstanceColor(instance){const offset=this.getColorIdOffset_(instance);const colorId=ColorScheme.getVariantColorId(instance.colorId,offset);return colors[colorId].toStringWithAlphaOverride(0.25);},getObjectSnapshotColor(snapshot){const offset=this.getColorIdOffset_(snapshot);let colorId=snapshot.objectInstance.colorId;colorId=ColorScheme.getVariantColorId(colorId,offset);return colors[colorId];},getCounterSeriesColor(colorId,selectionState,opt_alphaMultiplier){const event={selectionState};const offset=this.getColorIdOffset_(event);const c=colors[ColorScheme.getVariantColorId(colorId,offset)];return c.toStringWithAlphaOverride(opt_alphaMultiplier!==undefined?opt_alphaMultiplier:1.0);},getBarSnapshotColor(snapshot,offset){const snapshotOffset=this.getColorIdOffset_(snapshot);let colorId=snapshot.objectInstance.colorId;colorId=ColorScheme.getAnotherColorId(colorId,offset);colorId=ColorScheme.getVariantColorId(colorId,snapshotOffset);return colors[colorId].toStringWithAlphaOverride(1.0);}};return{EventPresenter,};});'use strict';tr.exportTo('tr.ui.b',function(){const elidedTitleCache=new tr.ui.b.ElidedTitleCache();const ColorScheme=tr.b.ColorScheme;const colorsAsStrings=ColorScheme.colorsAsStrings;const EventPresenter=tr.ui.b.EventPresenter;const blackColorId=ColorScheme.getColorIdForReservedName('black');const THIN_SLICE_HEIGHT=4;const SLICE_WAITING_WIDTH_DRAW_THRESHOLD=3;const SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD=1;const SHOULD_ELIDE_TEXT=true;function drawLine(ctx,x1,y1,x2,y2){ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);}
 function drawTriangle(ctx,x1,y1,x2,y2,x3,y3){ctx.beginPath();ctx.moveTo(x1,y1);ctx.lineTo(x2,y2);ctx.lineTo(x3,y3);ctx.closePath();}
-function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){var dx=x2-x1;var dy=y2-y1;var len=Math.sqrt(dx*dx+dy*dy);var perc=(len-arrowLength)/len;var bx=x1+perc*dx;var by=y1+perc*dy;var ux=dx/len;var uy=dy/len;var ax=uy*arrowWidth;var ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
-function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);var height=viewHeight*pixelRatio;var darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight){darkRectHeight=0;}
-var lightRectHeight=height-darkRectHeight;ctx.save();dt.applyTransformToCanvas(ctx);var rect=new tr.ui.b.FastRectRenderer(ctx,2*pixWidth,2*pixWidth,colorsAsStrings);rect.setYandH(0,height);var lowSlice=tr.b.math.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var hadTopLevel=false;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)break;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth){w=pixWidth;}}
-var colorId=EventPresenter.getSliceColorId(slice);var alpha=EventPresenter.getSliceAlpha(slice,async);var lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
+function drawArrow(ctx,x1,y1,x2,y2,arrowLength,arrowWidth){const dx=x2-x1;const dy=y2-y1;const len=Math.sqrt(dx*dx+dy*dy);const perc=(len-arrowLength)/len;const bx=x1+perc*dx;const by=y1+perc*dy;const ux=dx/len;const uy=dy/len;const ax=uy*arrowWidth;const ay=-ux*arrowWidth;ctx.beginPath();drawLine(ctx,x1,y1,x2,y2);ctx.stroke();drawTriangle(ctx,bx+ax,by+ay,x2,y2,bx-ax,by-ay);ctx.fill();}
+function drawSlices(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,async){const pixelRatio=window.devicePixelRatio||1;const pixWidth=dt.xViewVectorToWorld(1);const height=viewHeight*pixelRatio;let darkRectHeight=THIN_SLICE_HEIGHT*pixelRatio;if(height<darkRectHeight){darkRectHeight=0;}
+const lightRectHeight=height-darkRectHeight;ctx.save();dt.applyTransformToCanvas(ctx);const rect=new tr.ui.b.FastRectRenderer(ctx,2*pixWidth,2*pixWidth,colorsAsStrings);rect.setYandH(0,height);const lowSlice=tr.b.math.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);let hadTopLevel=false;for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;let w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth){w=pixWidth;}}
+const colorId=EventPresenter.getSliceColorId(slice);const alpha=EventPresenter.getSliceAlpha(slice,async);const lightAlpha=alpha*0.70;if(async&&slice.isTopLevel){rect.setYandH(3,height-3);hadTopLevel=true;}else{rect.setYandH(0,height);}
 if(!slice.cpuDuration){rect.fillRect(x,w,colorId,alpha);continue;}
-var activeWidth=w*(slice.cpuDuration/slice.duration);var waitingWidth=w-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=0;waitingWidth=w;}
+let activeWidth=w*(slice.cpuDuration/slice.duration);let waitingWidth=w-activeWidth;if(activeWidth<SLICE_ACTIVE_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=0;waitingWidth=w;}
 if(waitingWidth<SLICE_WAITING_WIDTH_DRAW_THRESHOLD*pixWidth){activeWidth=w;waitingWidth=0;}
 if(activeWidth>0){rect.fillRect(x,activeWidth,colorId,alpha);}
 if(waitingWidth>0){rect.setYandH(0,lightRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,lightAlpha);rect.setYandH(lightRectHeight,darkRectHeight);rect.fillRect(x+activeWidth-pixWidth,waitingWidth+pixWidth,colorId,alpha);rect.setYandH(0,height);}}
-rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)break;if(!slice.isTopLevel)continue;var w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth){w=pixWidth;}}
+rect.flush();if(async&&hadTopLevel){rect.setYandH(2,1);for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;if(!slice.isTopLevel)continue;let w=pixWidth;if(slice.duration>0){w=Math.max(slice.duration,0.000001);if(w<pixWidth){w=pixWidth;}}
 rect.fillRect(x,w,blackColorId,0.7);}
 rect.flush();}
 ctx.restore();}
-function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.lineWidth=pixWidth*lineWidthInPixels*pixelRatio;dt.applyTransformToCanvas(ctx);ctx.beginPath();var lowSlice=tr.b.math.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];var x=slice.start;if(x>viewRWorld)break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,height);ctx.stroke();}
+function drawInstantSlicesAsLines(ctx,dt,viewLWorld,viewRWorld,viewHeight,slices,lineWidthInPixels){const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;const pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.lineWidth=pixWidth*lineWidthInPixels*pixelRatio;dt.applyTransformToCanvas(ctx);ctx.beginPath();const lowSlice=tr.b.math.findLowIndexInSortedArray(slices,function(slice){return slice.start;},viewLWorld);for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];const x=slice.start;if(x>viewRWorld)break;ctx.strokeStyle=EventPresenter.getInstantSliceColor(slice);ctx.beginPath();ctx.moveTo(x,0);ctx.lineTo(x,height);ctx.stroke();}
 ctx.restore();}
-function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){var pixelRatio=window.devicePixelRatio||1;var pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async){ctx.font='italic '+ctx.font;}
-var cY=yOffset*pixelRatio;var lowSlice=tr.b.math.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);var quickDiscardThresshold=pixWidth*20;for(var i=lowSlice;i<slices.length;++i){var slice=slices[i];if(slice.start>viewRWorld)break;if(slice.duration<=quickDiscardThresshold)continue;var title=slice.title+
-(slice.didNotFinish?' (Did Not Finish)':'');var drawnTitle=title;var drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);var fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>slice.duration){var elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,slice.duration);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
-if(drawnWidth*pixWidth<slice.duration){ctx.fillStyle=EventPresenter.getTextColor(slice);var cX=dt.xWorldToView(slice.start+0.5*slice.duration);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
+function drawLabels(ctx,dt,viewLWorld,viewRWorld,slices,async,fontSize,yOffset){const pixelRatio=window.devicePixelRatio||1;const pixWidth=dt.xViewVectorToWorld(1);ctx.save();ctx.textAlign='center';ctx.textBaseline='top';ctx.font=(fontSize*pixelRatio)+'px sans-serif';if(async){ctx.font='italic '+ctx.font;}
+const cY=yOffset*pixelRatio;const lowSlice=tr.b.math.findLowIndexInSortedArray(slices,function(slice){return slice.start+slice.duration;},viewLWorld);const quickDiscardThresshold=pixWidth*20;for(let i=lowSlice;i<slices.length;++i){const slice=slices[i];if(slice.start>viewRWorld)break;if(slice.duration<=quickDiscardThresshold)continue;const title=slice.title+
+(slice.didNotFinish?' (Did Not Finish)':'');let drawnTitle=title;let drawnWidth=elidedTitleCache.labelWidth(ctx,drawnTitle);const fullLabelWidth=elidedTitleCache.labelWidthWorld(ctx,drawnTitle,pixWidth);if(SHOULD_ELIDE_TEXT&&fullLabelWidth>slice.duration){const elidedValues=elidedTitleCache.get(ctx,pixWidth,drawnTitle,drawnWidth,slice.duration);drawnTitle=elidedValues.string;drawnWidth=elidedValues.width;}
+if(drawnWidth*pixWidth<slice.duration){ctx.fillStyle=EventPresenter.getTextColor(slice);const cX=dt.xWorldToView(slice.start+0.5*slice.duration);ctx.fillText(drawnTitle,cX,cY,drawnWidth);}}
 ctx.restore();}
 return{drawSlices,drawInstantSlicesAsLines,drawLabels,drawLine,drawTriangle,drawArrow,elidedTitleCache_:elidedTitleCache,THIN_SLICE_HEIGHT,};});'use strict';tr.exportTo('tr.ui',function(){function TimelineDisplayTransform(opt_that){if(opt_that){this.set(opt_that);return;}
 this.scaleX=1;this.panX=0;this.panY=0;}
-TimelineDisplayTransform.prototype={set:function(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone:function(){return new TimelineDisplayTransform(this);},equals:function(that){var eq=true;if(that===undefined||that===null){return false;}
-eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals:function(that){var eq=true;if(that===undefined||that===null){return false;}
-eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits:function(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos:function(worldX,viewX,viewWidth){if(typeof viewX==='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
-this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView:function(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0){this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);}else if(this.xWorldToView(worldMax)>viewWidth){this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);}},xSetWorldBounds:function(worldMin,worldMax,viewWidth){var worldWidth=worldMax-worldMin;var scaleX=viewWidth/worldWidth;var panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale:function(p,s){this.scaleX=s;this.panX=p;},xWorldToView:function(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView:function(x){return x*this.scaleX;},xViewToWorld:function(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld:function(x){return x/this.scaleX;},applyTransformToCanvas:function(ctx){ctx.transform(this.scaleX,0,0,1,this.panX*this.scaleX,0);}};return{TimelineDisplayTransform,};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
+TimelineDisplayTransform.prototype={set(that){this.scaleX=that.scaleX;this.panX=that.panX;this.panY=that.panY;},clone(){return new TimelineDisplayTransform(this);},equals(that){let eq=true;if(that===undefined||that===null){return false;}
+eq&=this.panX===that.panX;eq&=this.panY===that.panY;eq&=this.scaleX===that.scaleX;return!!eq;},almostEquals(that){let eq=true;if(that===undefined||that===null){return false;}
+eq&=Math.abs(this.panX-that.panX)<0.001;eq&=Math.abs(this.panY-that.panY)<0.001;eq&=Math.abs(this.scaleX-that.scaleX)<0.001;return!!eq;},incrementPanXInViewUnits(xDeltaView){this.panX+=this.xViewVectorToWorld(xDeltaView);},xPanWorldPosToViewPos(worldX,viewX,viewWidth){if(typeof viewX==='string'){if(viewX==='left'){viewX=0;}else if(viewX==='center'){viewX=viewWidth/2;}else if(viewX==='right'){viewX=viewWidth-1;}else{throw new Error('viewX must be left|center|right or number.');}}
+this.panX=(viewX/this.scaleX)-worldX;},xPanWorldBoundsIntoView(worldMin,worldMax,viewWidth){if(this.xWorldToView(worldMin)<0){this.xPanWorldPosToViewPos(worldMin,'left',viewWidth);}else if(this.xWorldToView(worldMax)>viewWidth){this.xPanWorldPosToViewPos(worldMax,'right',viewWidth);}},xSetWorldBounds(worldMin,worldMax,viewWidth){const worldWidth=worldMax-worldMin;const scaleX=viewWidth/worldWidth;const panX=-worldMin;this.setPanAndScale(panX,scaleX);},setPanAndScale(p,s){this.scaleX=s;this.panX=p;},xWorldToView(x){return(x+this.panX)*this.scaleX;},xWorldVectorToView(x){return x*this.scaleX;},xViewToWorld(x){return(x/this.scaleX)-this.panX;},xViewVectorToWorld(x){return x/this.scaleX;},applyTransformToCanvas(ctx){ctx.transform(this.scaleX,0,0,1,this.panX*this.scaleX,0);}};return{TimelineDisplayTransform,};});'use strict';tr.exportTo('tr.ui',function(){function SnapIndicator(y,height){this.y=y;this.height=height;}
 function TimelineInterestRange(vp){this.viewport_=vp;this.range_=new tr.b.math.Range();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;}
-TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset:function(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set:function(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax:function(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject:function(){var range=new tr.b.math.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_===leftSelected)return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_===rightSelected)return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw:function(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)return;var dt=this.viewport_.currentDisplayTransform;var markerLWorld=this.min;var markerRWorld=this.max;var markerLView=Math.round(dt.xWorldToView(markerLWorld));var markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
+TimelineInterestRange.prototype={get isEmpty(){return this.range_.isEmpty;},reset(){this.range_.reset();this.leftSelected_=false;this.rightSelected_=false;this.leftSnapIndicator_=undefined;this.rightSnapIndicator_=undefined;this.viewport_.dispatchChangeEvent();},get min(){return this.range_.min;},set min(min){this.range_.min=min;this.viewport_.dispatchChangeEvent();},get max(){return this.range_.max;},set max(max){this.range_.max=max;this.viewport_.dispatchChangeEvent();},set(range){this.range_.reset();this.range_.addRange(range);this.viewport_.dispatchChangeEvent();},setMinAndMax(min,max){this.range_.min=min;this.range_.max=max;this.viewport_.dispatchChangeEvent();},get range(){return this.range_.range;},asRangeObject(){const range=new tr.b.math.Range();range.addRange(this.range_);return range;},get leftSelected(){return this.leftSelected_;},set leftSelected(leftSelected){if(this.leftSelected_===leftSelected)return;this.leftSelected_=leftSelected;this.viewport_.dispatchChangeEvent();},get rightSelected(){return this.rightSelected_;},set rightSelected(rightSelected){if(this.rightSelected_===rightSelected)return;this.rightSelected_=rightSelected;this.viewport_.dispatchChangeEvent();},get leftSnapIndicator(){return this.leftSnapIndicator_;},set leftSnapIndicator(leftSnapIndicator){this.leftSnapIndicator_=leftSnapIndicator;this.viewport_.dispatchChangeEvent();},get rightSnapIndicator(){return this.rightSnapIndicator_;},set rightSnapIndicator(rightSnapIndicator){this.rightSnapIndicator_=rightSnapIndicator;this.viewport_.dispatchChangeEvent();},draw(ctx,viewLWorld,viewRWorld){if(this.range_.isEmpty)return;const dt=this.viewport_.currentDisplayTransform;const markerLWorld=this.min;const markerRWorld=this.max;const markerLView=Math.round(dt.xWorldToView(markerLWorld));const markerRView=Math.round(dt.xWorldToView(markerRWorld));ctx.fillStyle='rgba(0, 0, 0, 0.2)';if(markerLWorld>viewLWorld){ctx.fillRect(dt.xWorldToView(viewLWorld),0,markerLView,ctx.canvas.height);}
 if(markerRWorld<viewRWorld){ctx.fillRect(markerRView,0,dt.xWorldToView(viewRWorld),ctx.canvas.height);}
-var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
-ctx.lineWidth=1;},drawLine_:function(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)return;var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected){ctx.strokeStyle='rgb(255, 0, 0)';}else{ctx.strokeStyle='rgb(0, 0, 0)';}
-ctx.stroke();ctx.restore();},drawIndicators:function(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
-if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_:function(ctx,viewLWorld,viewRWorld,xWorld,si,selected){var dt=this.viewport_.currentDisplayTransform;var viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);var pixelRatio=window.devicePixelRatio||1;var viewY=si.y*devicePixelRatio;var viewHeight=si.height*devicePixelRatio;var arrowSize=4*pixelRatio;if(selected){ctx.fillStyle='rgb(255, 0, 0)';}else{ctx.fillStyle='rgb(0, 0, 0)';}
+const pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);if(this.range_.range>0){this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_);this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.max,this.rightSelected_);}else{this.drawLine_(ctx,viewLWorld,viewRWorld,ctx.canvas.height,this.min,this.leftSelected_||this.rightSelected_);}
+ctx.lineWidth=1;},drawLine_(ctx,viewLWorld,viewRWorld,height,ts,selected){if(ts<viewLWorld||ts>=viewRWorld)return;const dt=this.viewport_.currentDisplayTransform;const viewX=Math.round(dt.xWorldToView(ts));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();tr.ui.b.drawLine(ctx,viewX,0,viewX,height);if(selected){ctx.strokeStyle='rgb(255, 0, 0)';}else{ctx.strokeStyle='rgb(0, 0, 0)';}
+ctx.stroke();ctx.restore();},drawIndicators(ctx,viewLWorld,viewRWorld){if(this.leftSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.min,this.leftSnapIndicator_,this.leftSelected_);}
+if(this.rightSnapIndicator_){this.drawIndicator_(ctx,viewLWorld,viewRWorld,this.range_.max,this.rightSnapIndicator_,this.rightSelected_);}},drawIndicator_(ctx,viewLWorld,viewRWorld,xWorld,si,selected){const dt=this.viewport_.currentDisplayTransform;const viewX=Math.round(dt.xWorldToView(xWorld));ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);const pixelRatio=window.devicePixelRatio||1;const viewY=si.y*devicePixelRatio;const viewHeight=si.height*devicePixelRatio;const arrowSize=4*pixelRatio;if(selected){ctx.fillStyle='rgb(255, 0, 0)';}else{ctx.fillStyle='rgb(0, 0, 0)';}
 tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY,viewX+arrowSize*0.75,viewY,viewX,viewY+arrowSize);ctx.fill();tr.ui.b.drawTriangle(ctx,viewX-arrowSize*0.75,viewY+viewHeight,viewX+arrowSize*0.75,viewY+viewHeight,viewX,viewY+viewHeight-arrowSize);ctx.fill();ctx.restore();}};return{SnapIndicator,TimelineInterestRange,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ContainerToTrackMap(){this.stableIdToTrackMap_={};}
-ContainerToTrackMap.prototype={addContainer:function(container,track){if(!track){throw new Error('Must provide a track.');}
-this.stableIdToTrackMap_[container.stableId]=track;},clear:function(){this.stableIdToTrackMap_={};},getTrackByStableId:function(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
-EventToTrackMap.prototype={addEvent:function(event,track){if(!track){throw new Error('Must provide a track.');}
-this[event.guid]=track;}};return{EventToTrackMap,};});'use strict';tr.exportTo('tr.ui',function(){var TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;var TimelineInterestRange=tr.ui.TimelineInterestRange;var IDEAL_MAJOR_MARK_DISTANCE_PX=150;var MAJOR_MARK_ROUNDING_FACTOR=100000;class AnimationControllerProxy{constructor(target){this.target_=target;}
+ContainerToTrackMap.prototype={addContainer(container,track){if(!track){throw new Error('Must provide a track.');}
+this.stableIdToTrackMap_[container.stableId]=track;},clear(){this.stableIdToTrackMap_={};},getTrackByStableId(stableId){return this.stableIdToTrackMap_[stableId];}};return{ContainerToTrackMap,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function EventToTrackMap(){}
+EventToTrackMap.prototype={addEvent(event,track){if(!track){throw new Error('Must provide a track.');}
+this[event.guid]=track;}};return{EventToTrackMap,};});'use strict';tr.exportTo('tr.ui',function(){const TimelineDisplayTransform=tr.ui.TimelineDisplayTransform;const TimelineInterestRange=tr.ui.TimelineInterestRange;const IDEAL_MAJOR_MARK_DISTANCE_PX=150;const MAJOR_MARK_ROUNDING_FACTOR=100000;class AnimationControllerProxy{constructor(target){this.target_=target;}
 get panX(){return this.target_.currentDisplayTransform_.panX;}
 set panX(panX){this.target_.currentDisplayTransform_.panX=panX;}
 get panY(){return this.target_.currentDisplayTransform_.panY;}
@@ -6336,137 +6656,137 @@
 cloneAnimationState(){return this.target_.currentDisplayTransform_.clone();}
 xPanWorldPosToViewPos(xWorld,xView){this.target_.currentDisplayTransform_.xPanWorldPosToViewPos(xWorld,xView,this.target_.modelTrackContainer_.canvas.clientWidth);}}
 function TimelineViewport(parentEl){this.parentEl_=parentEl;this.modelTrackContainer_=undefined;this.currentDisplayTransform_=new TimelineDisplayTransform();this.initAnimationController_();this.showFlowEvents_=false;this.highlightVSync_=false;this.highDetails_=false;this.gridTimebase_=0;this.gridStep_=1000/60;this.gridEnabled_=false;this.hasCalledSetupFunction_=false;this.onResize_=this.onResize_.bind(this);this.onModelTrackControllerScroll_=this.onModelTrackControllerScroll_.bind(this);this.timeMode_=TimelineViewport.TimeMode.TIME_IN_MS;this.majorMarkWorldPositions_=[];this.majorMarkUnit_=undefined;this.interestRange_=new TimelineInterestRange(this);this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.containerToTrackMap=new tr.ui.tracks.ContainerToTrackMap();this.dispatchChangeEvent=this.dispatchChangeEvent.bind(this);}
-TimelineViewport.TimeMode={TIME_IN_MS:0,REVISIONS:1};TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_:function(){this.dispatchChangeEvent();},dispatchChangeEvent:function(){tr.b.dispatchSimpleEvent(this,'change');},detach:function(){window.removeEventListener('resize',this.dispatchChangeEvent);},initAnimationController_:function(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));this.dtAnimationController_.target=new AnimationControllerProxy(this);},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately:function(displayTransform){this.dtAnimationController_.cancelActiveAnimation();var oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation:function(animation){if(!(animation instanceof tr.ui.b.Animation)){throw new Error('animation must be instanceof tr.ui.b.Animation');}
-this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_:function(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.math.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
+TimelineViewport.TimeMode={TIME_IN_MS:0,REVISIONS:1};TimelineViewport.prototype={__proto__:tr.b.EventTarget.prototype,get isAttachedToDocumentOrInTestMode(){if(this.parentEl_===undefined)return;return tr.ui.b.isElementAttachedToDocument(this.parentEl_);},onResize_(){this.dispatchChangeEvent();},dispatchChangeEvent(){tr.b.dispatchSimpleEvent(this,'change');},detach(){window.removeEventListener('resize',this.dispatchChangeEvent);},initAnimationController_(){this.dtAnimationController_=new tr.ui.b.AnimationController();this.dtAnimationController_.addEventListener('didtick',function(e){this.onCurentDisplayTransformChange_(e.oldTargetState);}.bind(this));this.dtAnimationController_.target=new AnimationControllerProxy(this);},get currentDisplayTransform(){return this.currentDisplayTransform_;},setDisplayTransformImmediately(displayTransform){this.dtAnimationController_.cancelActiveAnimation();const oldDisplayTransform=this.dtAnimationController_.target.cloneAnimationState();this.currentDisplayTransform_.set(displayTransform);this.onCurentDisplayTransformChange_(oldDisplayTransform);},queueDisplayTransformAnimation(animation){if(!(animation instanceof tr.ui.b.Animation)){throw new Error('animation must be instanceof tr.ui.b.Animation');}
+this.dtAnimationController_.queueAnimation(animation);},onCurentDisplayTransformChange_(oldDisplayTransform){if(this.modelTrackContainer_){this.currentDisplayTransform.panY=tr.b.math.clamp(this.currentDisplayTransform.panY,0,this.modelTrackContainer_.scrollHeight-
 this.modelTrackContainer_.clientHeight);}
-var changed=!this.currentDisplayTransform.equals(oldDisplayTransform);var yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged){this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;}
-if(changed){this.dispatchChangeEvent();}},onModelTrackControllerScroll_:function(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY){this.dtAnimationController_.cancelActiveAnimation();}
-var panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_){this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);}
-this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_===enabled)return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_===timebase)return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},get majorMarkWorldPositions(){return this.majorMarkWorldPositions_;},get majorMarkUnit(){switch(this.timeMode_){case TimelineViewport.TimeMode.TIME_IN_MS:return tr.b.Unit.byName.timeInMsAutoFormat;case TimelineViewport.TimeMode.REVISIONS:return tr.b.Unit.byName.count;default:throw new Error('Cannot get Unit for unsupported time mode '+this.timeMode_);}},get timeMode(){return this.timeMode_;},set timeMode(mode){this.timeMode_=mode;this.dispatchChangeEvent();},updateMajorMarkData:function(viewLWorld,viewRWorld){var pixelRatio=window.devicePixelRatio||1;var dt=this.currentDisplayTransform;var idealMajorMarkDistancePix=IDEAL_MAJOR_MARK_DISTANCE_PX*pixelRatio;var idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);var majorMarkDistanceWorld=tr.b.math.preferredNumberLargerThanMin(idealMajorMarkDistanceWorld);var firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;this.majorMarkWorldPositions_=[];for(var curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){this.majorMarkWorldPositions_.push(Math.floor(MAJOR_MARK_ROUNDING_FACTOR*curX)/MAJOR_MARK_ROUNDING_FACTOR);}},drawMajorMarkLines:function(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(var majorMark of this.majorMarkWorldPositions_){var x=this.currentDisplayTransform.xWorldToView(majorMark);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
-ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines:function(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)return;var dt=this.currentDisplayTransform;var x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){var vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
+const changed=!this.currentDisplayTransform.equals(oldDisplayTransform);const yChanged=this.currentDisplayTransform.panY!==oldDisplayTransform.panY;if(yChanged){this.modelTrackContainer_.scrollTop=this.currentDisplayTransform.panY;}
+if(changed){this.dispatchChangeEvent();}},onModelTrackControllerScroll_(e){if(this.dtAnimationController_.activeAnimation&&this.dtAnimationController_.activeAnimation.affectsPanY){this.dtAnimationController_.cancelActiveAnimation();}
+const panY=this.modelTrackContainer_.scrollTop;this.currentDisplayTransform_.panY=panY;},get modelTrackContainer(){return this.modelTrackContainer_;},set modelTrackContainer(m){if(this.modelTrackContainer_){this.modelTrackContainer_.removeEventListener('scroll',this.onModelTrackControllerScroll_);}
+this.modelTrackContainer_=m;this.modelTrackContainer_.addEventListener('scroll',this.onModelTrackControllerScroll_);},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;this.dispatchChangeEvent();},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;this.dispatchChangeEvent();},get highDetails(){return this.highDetails_;},set highDetails(highDetails){this.highDetails_=highDetails;this.dispatchChangeEvent();},get gridEnabled(){return this.gridEnabled_;},set gridEnabled(enabled){if(this.gridEnabled_===enabled)return;this.gridEnabled_=enabled&&true;this.dispatchChangeEvent();},get gridTimebase(){return this.gridTimebase_;},set gridTimebase(timebase){if(this.gridTimebase_===timebase)return;this.gridTimebase_=timebase;this.dispatchChangeEvent();},get gridStep(){return this.gridStep_;},get interestRange(){return this.interestRange_;},get majorMarkWorldPositions(){return this.majorMarkWorldPositions_;},get majorMarkUnit(){switch(this.timeMode_){case TimelineViewport.TimeMode.TIME_IN_MS:return tr.b.Unit.byName.timeInMsAutoFormat;case TimelineViewport.TimeMode.REVISIONS:return tr.b.Unit.byName.count;default:throw new Error('Cannot get Unit for unsupported time mode '+this.timeMode_);}},get timeMode(){return this.timeMode_;},set timeMode(mode){this.timeMode_=mode;this.dispatchChangeEvent();},updateMajorMarkData(viewLWorld,viewRWorld){const pixelRatio=window.devicePixelRatio||1;const dt=this.currentDisplayTransform;const idealMajorMarkDistancePix=IDEAL_MAJOR_MARK_DISTANCE_PX*pixelRatio;const idealMajorMarkDistanceWorld=dt.xViewVectorToWorld(idealMajorMarkDistancePix);const majorMarkDistanceWorld=tr.b.math.preferredNumberLargerThanMin(idealMajorMarkDistanceWorld);const firstMajorMark=Math.floor(viewLWorld/majorMarkDistanceWorld)*majorMarkDistanceWorld;this.majorMarkWorldPositions_=[];for(let curX=firstMajorMark;curX<viewRWorld;curX+=majorMarkDistanceWorld){this.majorMarkWorldPositions_.push(Math.floor(MAJOR_MARK_ROUNDING_FACTOR*curX)/MAJOR_MARK_ROUNDING_FACTOR);}},drawMajorMarkLines(ctx){ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();for(const majorMark of this.majorMarkWorldPositions_){const x=this.currentDisplayTransform.xWorldToView(majorMark);tr.ui.b.drawLine(ctx,x,0,x,ctx.canvas.height);}
+ctx.strokeStyle='#ddd';ctx.stroke();ctx.restore();},drawGridLines(ctx,viewLWorld,viewRWorld){if(!this.gridEnabled)return;const dt=this.currentDisplayTransform;let x=this.gridTimebase;ctx.save();ctx.translate((Math.round(ctx.lineWidth)%2)/2,0);ctx.beginPath();while(x<viewRWorld){if(x>=viewLWorld){const vx=Math.floor(dt.xWorldToView(x));tr.ui.b.drawLine(ctx,vx,0,vx,ctx.canvas.height);}
 x+=this.gridStep;}
-ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection:function(selection,offset){var newSelection=new tr.model.EventSet();for(var event of selection){if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
+ctx.strokeStyle='rgba(255, 0, 0, 0.25)';ctx.stroke();ctx.restore();},getShiftedSelection(selection,offset){const newSelection=new tr.model.EventSet();for(const event of selection){if(event instanceof tr.model.FlowEvent){if(offset>0){newSelection.push(event.endSlice);}else if(offset<0){newSelection.push(event.startSlice);}else{}
 continue;}
-var track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
-if(newSelection.length===0)return undefined;return newSelection;},rebuildEventToTrackMap:function(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap:function(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent:function(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport,};});'use strict';tr.exportTo('tr.c',function(){var BrushingState=tr.ui.b.BrushingState;var EventSet=tr.model.EventSet;var SelectionState=tr.model.SelectionState;var Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
-BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_:function(){var e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_){return undefined;}
+const track=this.trackForEvent(event);track.addEventNearToProvidedEventToSelection(event,offset,newSelection);}
+if(newSelection.length===0)return undefined;return newSelection;},rebuildEventToTrackMap(){this.eventToTrackMap_=new tr.ui.tracks.EventToTrackMap();this.modelTrackContainer_.addEventsToTrackMap(this.eventToTrackMap_);},rebuildContainerToTrackMap(){this.containerToTrackMap.clear();this.modelTrackContainer_.addContainersToTrackMap(this.containerToTrackMap);},trackForEvent(event){return this.eventToTrackMap_[event.guid];}};return{TimelineViewport,};});'use strict';tr.exportTo('tr.c',function(){const BrushingState=tr.ui.b.BrushingState;const EventSet=tr.model.EventSet;const SelectionState=tr.model.SelectionState;const Viewport=tr.ui.TimelineViewport;function BrushingStateController(timelineView){tr.b.EventTarget.call(this);this.timelineView_=timelineView;this.currentBrushingState_=new BrushingState();this.onPopState_=this.onPopState_.bind(this);this.historyEnabled_=false;this.selections_={};}
+BrushingStateController.prototype={__proto__:tr.b.EventTarget.prototype,dispatchChangeEvent_(){const e=new tr.b.Event('change',false,false);this.dispatchEvent(e);},get model(){if(!this.timelineView_){return undefined;}
 return this.timelineView_.model;},get trackView(){if(!this.timelineView_){return undefined;}
 return this.timelineView_.trackView;},get viewport(){if(!this.timelineView_){return undefined;}
 if(!this.timelineView_.trackView){return undefined;}
-return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled){window.addEventListener('popstate',this.onPopState_);}else{window.removeEventListener('popstate',this.onPopState_);}},modelWillChange:function(){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}},modelDidChange:function(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToEventSelectionStates(this.model);var e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_:function(){var selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;var state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_:function(e){if(e.state===null)return;var selection=this.selections_[e.state.selection_guid];if(selection){var newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
+return this.timelineView_.trackView.viewport;},get historyEnabled(){return this.historyEnabled_;},set historyEnabled(historyEnabled){this.historyEnabled_=!!historyEnabled;if(historyEnabled){window.addEventListener('popstate',this.onPopState_);}else{window.removeEventListener('popstate',this.onPopState_);}},modelWillChange(){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}},modelDidChange(){this.selections_={};this.currentBrushingState_=new BrushingState();this.currentBrushingState_.applyToEventSelectionStates(this.model);const e=new tr.b.Event('model-changed',false,false);this.dispatchEvent(e);this.dispatchChangeEvent_();},onUserInitiatedSelectionChange_(){const selection=this.selection;if(this.historyEnabled){this.selections_[selection.guid]=selection;const state={selection_guid:selection.guid};window.history.pushState(state,document.title);}},onPopState_(e){if(e.state===null)return;const selection=this.selections_[e.state.selection_guid];if(selection){const newState=this.currentBrushingState_.clone();newState.selection=selection;this.currentBrushingState=newState;}
 e.stopPropagation();},get selection(){return this.currentBrushingState_.selection;},get findMatches(){return this.currentBrushingState_.findMatches;},get selectionOfInterest(){return this.currentBrushingState_.selectionOfInterest;},get currentBrushingState(){return this.currentBrushingState_;},set currentBrushingState(newBrushingState){if(newBrushingState.isAppliedToModel){throw new Error('Cannot apply this state, it is applied');}
-var hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
+const hasValueChanged=!this.currentBrushingState_.equals(newBrushingState);if(newBrushingState!==this.currentBrushingState_&&!hasValueChanged){if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.transferModelOwnershipToClone(newBrushingState);}
 this.currentBrushingState_=newBrushingState;return;}
 if(this.currentBrushingState_.isAppliedToModel){this.currentBrushingState_.unapplyFromEventSelectionStates();}
-this.currentBrushingState_=newBrushingState;this.currentBrushingState_.applyToEventSelectionStates(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var timelineView=this.timelineView_.trackView;if(!timelineView){return new tr.b.Task();}
-return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo:function(allPossibleMatches){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo:function(currentFocus){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared:function(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
+this.currentBrushingState_=newBrushingState;this.currentBrushingState_.applyToEventSelectionStates(this.model);this.dispatchChangeEvent_();},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const timelineView=this.timelineView_.trackView;if(!timelineView){return new tr.b.Task();}
+return timelineView.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);},findTextChangedTo(allPossibleMatches){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.findMatches=allPossibleMatches;this.currentBrushingState=newBrushingState;},findFocusChangedTo(currentFocus){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=currentFocus;this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},findTextCleared(){if(this.xNavStringMarker_!==undefined){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
 if(this.guideLineAnnotation_!==undefined){this.model.removeAnnotation(this.guideLineAnnotation_);this.guideLineAnnotation_=undefined;}
-var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString:function(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition:function(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent:function(selection){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents:function(eventSet){var newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState:function(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState:function(viewId,newState){var oldStates=this.currentBrushingState_.viewSpecificBrushingStates;var newStates={};for(var id in oldStates){newStates[id]=oldStates[id];}
+const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=new EventSet();newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},uiStateFromString(string){return tr.ui.b.UIState.fromUserFriendlyString(this.model,this.viewport,string);},navToPosition(uiState,showNavLine){this.trackView.navToPosition(uiState,showNavLine);},changeSelectionFromTimeline(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},showScriptControlSelection(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;},changeSelectionFromRequestSelectionChangeEvent(selection){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.selection=selection;newBrushingState.findMatches=new EventSet();this.currentBrushingState=newBrushingState;this.onUserInitiatedSelectionChange_();},changeAnalysisViewRelatedEvents(eventSet){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisViewRelatedEvents=eventSet;this.currentBrushingState=newBrushingState;},changeAnalysisLinkHoveredEvents(eventSet){const newBrushingState=this.currentBrushingState_.clone();newBrushingState.analysisLinkHoveredEvents=eventSet;this.currentBrushingState=newBrushingState;},getViewSpecificBrushingState(viewId){return this.currentBrushingState.viewSpecificBrushingStates[viewId];},changeViewSpecificBrushingState(viewId,newState){const oldStates=this.currentBrushingState_.viewSpecificBrushingStates;const newStates={};for(const id in oldStates){newStates[id]=oldStates[id];}
 if(newState===undefined){delete newStates[viewId];}else{newStates[viewId]=newState;}
-var newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless){throw new Error('Unsupported');}
-var currentElement=element;while(currentElement){if(currentElement.brushingStateController){return currentElement.brushingStateController;}
+const newBrushingState=this.currentBrushingState_.clone();newBrushingState.viewSpecificBrushingStates=newStates;this.currentBrushingState=newBrushingState;}};BrushingStateController.getControllerForElement=function(element){if(tr.isHeadless){throw new Error('Unsupported');}
+let currentElement=element;while(currentElement){if(currentElement.brushingStateController){return currentElement.brushingStateController;}
 if(currentElement.parentElement){currentElement=currentElement.parentElement;continue;}
-var currentNode=currentElement;while(Polymer.dom(currentNode).parentNode){currentNode=Polymer.dom(currentNode).parentNode;}
+let currentNode=currentElement;while(Polymer.dom(currentNode).parentNode){currentNode=Polymer.dom(currentNode).parentNode;}
 currentElement=currentNode.host;}
-return undefined;};return{BrushingStateController,};});'use strict';Polymer({is:'tr-ui-a-analysis-link',properties:{href:{type:String}},listeners:{'click':'onClicked_','mouseenter':'onMouseEnter_','mouseleave':'onMouseLeave_'},ready:function(){this.selection_=undefined;},attached:function(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached:function(){this.clearHighlight_();this.controller_=undefined;},set color(c){this.style.color=c;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;Polymer.dom(this).textContent=selection.userFriendlyName;},setSelectionAndContent:function(selection,opt_textContent){this.selection_=selection;if(opt_textContent){Polymer.dom(this).textContent=opt_textContent;}},getCurrentSelection_:function(){if(typeof this.selection_==='function'){return this.selection_();}
-return this.selection_;},setHighlight_:function(opt_eventSet){if(this.controller_){this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);}},clearHighlight_:function(opt_eventSet){this.setHighlight_();},onClicked_:function(clickEvent){if(!this.selection_)return;clickEvent.stopPropagation();var event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_:function(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_:function(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){var TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};TableFormat.ColumnAlignment={LEFT:0,RIGHT:1};return{TableFormat,};});'use strict';(function(){var RIGHT_ARROW=String.fromCharCode(0x25b6);var UNSORTED_ARROW=String.fromCharCode(0x25BF);var ASCENDING_ARROW=String.fromCharCode(0x25B4);var DESCENDING_ARROW=String.fromCharCode(0x25BE);var SelectionMode=tr.ui.b.TableFormat.SelectionMode;var HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;var ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;Polymer({is:'tr-ui-b-table',created:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;this.computedFontSizePx_=undefined;},ready:function(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.$.body.addEventListener('focus',this.onFocus_.bind(this),true);},clear:function(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;Polymer.dom(this).textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;},set zebra(zebra){if(zebra){this.setAttribute('zebra',true);}else{this.removeAttribute('zebra');}},get zebra(){return this.getAttribute('zebra');},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){var previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue){this.scheduleRebuildBody_();}},set tableColumns(columns){var columnsWithExpandButtons=[];for(var i=0;i<columns.length;i++){if(columns[i].showExpandButtons){columnsWithExpandButtons.push(i);}}
+return undefined;};return{BrushingStateController,};});'use strict';Polymer({is:'tr-ui-a-analysis-link',properties:{href:{type:String}},listeners:{'click':'onClicked_','mouseenter':'onMouseEnter_','mouseleave':'onMouseLeave_'},ready(){this.selection_=undefined;},attached(){this.controller_=tr.c.BrushingStateController.getControllerForElement(this);},detached(){this.clearHighlight_();this.controller_=undefined;},set color(c){this.style.color=c;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;Polymer.dom(this).textContent=selection.userFriendlyName;},setSelectionAndContent(selection,opt_textContent){this.selection_=selection;if(opt_textContent){Polymer.dom(this).textContent=opt_textContent;}},getCurrentSelection_(){if(typeof this.selection_==='function'){return this.selection_();}
+return this.selection_;},setHighlight_(opt_eventSet){if(this.controller_){this.controller_.changeAnalysisLinkHoveredEvents(opt_eventSet);}},clearHighlight_(opt_eventSet){this.setHighlight_();},onClicked_(clickEvent){if(!this.selection_)return;clickEvent.stopPropagation();const event=new tr.model.RequestSelectionChangeEvent();event.selection=this.getCurrentSelection_();this.dispatchEvent(event);},onMouseEnter_(){this.setHighlight_(this.getCurrentSelection_());},onMouseLeave_(){this.clearHighlight_();}});'use strict';tr.exportTo('tr.ui.b',function(){const TableFormat={};TableFormat.SelectionMode={NONE:0,ROW:1,CELL:2};TableFormat.HighlightStyle={DEFAULT:0,NONE:1,LIGHT:2,DARK:3};TableFormat.ColumnAlignment={LEFT:0,RIGHT:1};return{TableFormat,};});'use strict';(function(){const RIGHT_ARROW=String.fromCharCode(0x25b6);const UNSORTED_ARROW=String.fromCharCode(0x25BF);const ASCENDING_ARROW=String.fromCharCode(0x25B4);const DESCENDING_ARROW=String.fromCharCode(0x25BE);const SelectionMode=tr.ui.b.TableFormat.SelectionMode;const HighlightStyle=tr.ui.b.TableFormat.HighlightStyle;const ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;Polymer({is:'tr-ui-b-table',created(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.customizeTableRowCallback_=undefined;this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;this.computedFontSizePx_=undefined;},ready(){this.$.body.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.$.body.addEventListener('focus',this.onFocus_.bind(this),true);},clear(){this.selectionMode_=SelectionMode.NONE;this.rowHighlightStyle_=HighlightStyle.DEFAULT;this.cellHighlightStyle_=HighlightStyle.DEFAULT;this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;Polymer.dom(this).textContent='';this.tableColumns_=[];this.tableRows_=[];this.tableRowsInfo_=new WeakMap();this.tableFooterRows_=[];this.tableFooterRowsInfo_=new WeakMap();this.sortColumnIndex_=undefined;this.sortDescending_=false;this.columnsWithExpandButtons_=[];this.headerCells_=[];this.showHeader_=true;this.emptyValue_=undefined;this.subRowsPropertyName_='subRows';this.defaultExpansionStateCallback_=undefined;this.userCanModifySortOrder_=true;},set zebra(zebra){if(zebra){this.setAttribute('zebra',true);}else{this.removeAttribute('zebra');}},get zebra(){return this.getAttribute('zebra');},get showHeader(){return this.showHeader_;},set showHeader(showHeader){this.showHeader_=showHeader;this.scheduleRebuildHeaders_();},set subRowsPropertyName(name){this.subRowsPropertyName_=name;},set defaultExpansionStateCallback(cb){this.defaultExpansionStateCallback_=cb;this.scheduleRebuildBody_();},set customizeTableRowCallback(cb){this.customizeTableRowCallback_=cb;this.scheduleRebuildBody_();},get emptyValue(){return this.emptyValue_;},set emptyValue(emptyValue){const previousEmptyValue=this.emptyValue_;this.emptyValue_=emptyValue;if(this.tableRows_.length===0&&emptyValue!==previousEmptyValue){this.scheduleRebuildBody_();}},set tableColumns(columns){let columnsWithExpandButtons=[];for(let i=0;i<columns.length;i++){if(columns[i].showExpandButtons){columnsWithExpandButtons.push(i);}}
 if(columnsWithExpandButtons.length===0){columnsWithExpandButtons=[0];}
-for(var i=0;i<columns.length;i++){var colInfo=columns[i];if(colInfo.width===undefined)continue;var hasExpandButton=columnsWithExpandButtons.includes(i);var w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
-var sortIndex=undefined;var currentSortColumn=this.tableColumns[this.sortColumnIndex_];if(currentSortColumn){for(var[i,column]of columns.entries()){if(currentSortColumn.title===column.title){sortIndex=i;break;}}}
-this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.scheduleRebuildHeaders_();this.sortColumnIndex=sortIndex;this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},get userCanModifySortOrder(){return this.userCanModifySortOrder_;},set userCanModifySortOrder(userCanModifySortOrder){var newUserCanModifySortOrder=!!userCanModifySortOrder;if(newUserCanModifySortOrder===this.userCanModifySortOrder_){return;}
+for(let i=0;i<columns.length;i++){const colInfo=columns[i];if(colInfo.width===undefined)continue;const hasExpandButton=columnsWithExpandButtons.includes(i);const w=colInfo.width;if(w){if(/\d+px/.test(w)){continue;}else if(/\d+%/.test(w)){if(hasExpandButton){throw new Error('Columns cannot be %-sized and host '+' an expand button');}}else{throw new Error('Unrecognized width string');}}}
+let sortIndex=undefined;const currentSortColumn=this.tableColumns[this.sortColumnIndex_];if(currentSortColumn){for(const[i,column]of columns.entries()){if(currentSortColumn.title===column.title){sortIndex=i;break;}}}
+this.tableColumns_=columns;this.headerCells_=[];this.columnsWithExpandButtons_=columnsWithExpandButtons;this.scheduleRebuildHeaders_();this.sortColumnIndex=sortIndex;this.tableRows=this.tableRows_;},get tableColumns(){return this.tableColumns_;},set tableRows(rows){this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;this.tableRows_=rows;this.tableRowsInfo_=new WeakMap();this.scheduleRebuildBody_();},get tableRows(){return this.tableRows_;},set footerRows(rows){this.tableFooterRows_=rows;this.tableFooterRowsInfo_=new WeakMap();this.scheduleRebuildFooter_();},get footerRows(){return this.tableFooterRows_;},get userCanModifySortOrder(){return this.userCanModifySortOrder_;},set userCanModifySortOrder(userCanModifySortOrder){const newUserCanModifySortOrder=!!userCanModifySortOrder;if(newUserCanModifySortOrder===this.userCanModifySortOrder_){return;}
 this.userCanModifySortOrder_=newUserCanModifySortOrder;this.scheduleRebuildHeaders_();},set sortColumnIndex(number){if(number===this.sortColumnIndex_)return;if(number!==undefined){if(this.tableColumns_.length<=number){throw new Error('Column number '+number+' is out of bounds.');}
 if(!this.tableColumns_[number].cmp){throw new Error('Column '+number+' does not have a comparator.');}}
-this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){var newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_:function(){for(var i=0;i<this.headerCells_.length;i++){var headerCell=this.headerCells_[i];var isColumnCurrentlySorted=i===this.sortColumnIndex_;if(!this.tableColumns_[i].cmp||(!this.userCanModifySortOrder_&&!isColumnCurrentlySorted)){headerCell.sideContent='';continue;}
+this.sortColumnIndex_=number;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();},get sortColumnIndex(){return this.sortColumnIndex_;},set sortDescending(value){const newValue=!!value;if(newValue!==this.sortDescending_){this.sortDescending_=newValue;this.updateHeaderArrows_();this.scheduleRebuildBody_();this.dispatchSortingChangedEvent_();}},get sortDescending(){return this.sortDescending_;},updateHeaderArrows_(){for(let i=0;i<this.headerCells_.length;i++){const headerCell=this.headerCells_[i];const isColumnCurrentlySorted=i===this.sortColumnIndex_;if(!this.tableColumns_[i].cmp||(!this.userCanModifySortOrder_&&!isColumnCurrentlySorted)){headerCell.sideContent='';continue;}
 if(!isColumnCurrentlySorted){headerCell.sideContent=UNSORTED_ARROW;headerCell.sideContentDisabled=false;continue;}
-headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;headerCell.sideContentDisabled=!this.userCanModifySortOrder_;}},generateHeaderColumns_:function(){var selectedTableColumnIndex=this.selectedTableColumnIndex;Polymer.dom(this.$.cols).textContent='';for(var i=0;i<this.tableColumns_.length;++i){var colElement=document.createElement('col');if(i===selectedTableColumnIndex){colElement.setAttribute('selected',true);}
+headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;headerCell.sideContentDisabled=!this.userCanModifySortOrder_;}},generateHeaderColumns_(){const selectedTableColumnIndex=this.selectedTableColumnIndex;Polymer.dom(this.$.cols).textContent='';for(let i=0;i<this.tableColumns_.length;++i){const colElement=document.createElement('col');if(i===selectedTableColumnIndex){colElement.setAttribute('selected',true);}
 Polymer.dom(this.$.cols).appendChild(colElement);}
-this.headerCells_=[];Polymer.dom(this.$.head).textContent='';if(!this.showHeader_)return;var tr=this.appendNewElement_(this.$.head,'tr');for(var i=0;i<this.tableColumns_.length;i++){var td=this.appendNewElement_(tr,'td');var headerCell=document.createElement('tr-ui-b-table-header-cell');headerCell.column=this.tableColumns_[i];if(this.tableColumns_[i].cmp){var isColumnCurrentlySorted=i===this.sortColumnIndex_;if(isColumnCurrentlySorted){headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;if(!this.userCanModifySortOrder_){headerCell.sideContentDisabled=true;}}
+this.headerCells_=[];Polymer.dom(this.$.head).textContent='';if(!this.showHeader_)return;const tr=this.appendNewElement_(this.$.head,'tr');for(let i=0;i<this.tableColumns_.length;i++){const td=this.appendNewElement_(tr,'td');const headerCell=document.createElement('tr-ui-b-table-header-cell');headerCell.column=this.tableColumns_[i];if(this.tableColumns_[i].cmp){const isColumnCurrentlySorted=i===this.sortColumnIndex_;if(isColumnCurrentlySorted){headerCell.sideContent=this.sortDescending_?DESCENDING_ARROW:ASCENDING_ARROW;if(!this.userCanModifySortOrder_){headerCell.sideContentDisabled=true;}}
 if(this.userCanModifySortOrder_){Polymer.dom(td).classList.add('sensitive');if(!isColumnCurrentlySorted){headerCell.sideContent=UNSORTED_ARROW;}
 headerCell.tapCallback=this.createSortCallback_(i);}}
-Polymer.dom(td).appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_:function(){if(this.tableRows_.length===0&&!this.showHeader)return;var rowToRemoveSizing;var rowToSize;if(this.showHeader){rowToSize=Polymer.dom(this.$.head).children[0];rowToRemoveSizing=Polymer.dom(this.$.body).children[0];}else{rowToSize=Polymer.dom(this.$.body).children[0];rowToRemoveSizing=Polymer.dom(this.$.head).children[0];}
-for(var i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&Polymer.dom(rowToRemoveSizing).children[i]){var tdToRemoveSizing=Polymer.dom(rowToRemoveSizing).children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
-var td=Polymer.dom(rowToSize).children[i];var delta;if(this.columnsWithExpandButtons_.includes(i)){td.style.paddingLeft=this.basicIndentation_+'px';delta=this.basicIndentation_+'px';}else{delta=undefined;}
+Polymer.dom(td).appendChild(headerCell);this.headerCells_.push(headerCell);}},applySizes_(){if(this.tableRows_.length===0&&!this.showHeader)return;let rowToRemoveSizing;let rowToSize;if(this.showHeader){rowToSize=Polymer.dom(this.$.head).children[0];rowToRemoveSizing=Polymer.dom(this.$.body).children[0];}else{rowToSize=Polymer.dom(this.$.body).children[0];rowToRemoveSizing=Polymer.dom(this.$.head).children[0];}
+for(let i=0;i<this.tableColumns_.length;i++){if(rowToRemoveSizing&&Polymer.dom(rowToRemoveSizing).children[i]){const tdToRemoveSizing=Polymer.dom(rowToRemoveSizing).children[i];tdToRemoveSizing.style.minWidth='';tdToRemoveSizing.style.width='';}
+const td=Polymer.dom(rowToSize).children[i];let delta;if(this.columnsWithExpandButtons_.includes(i)){td.style.paddingLeft=this.basicIndentation_+'px';delta=this.basicIndentation_+'px';}else{delta=undefined;}
 function calc(base,delta){if(delta){return'calc('+base+' - '+delta+')';}
 return base;}
-var w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_:function(columnNumber){return function(){if(!this.userCanModifySortOrder_)return;var previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber){this.sortDescending=false;}else{this.sortDescending=!this.sortDescending;}}.bind(this);},generateTableRowNodes_:function(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){var c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_){c=-c;}
+const w=this.tableColumns_[i].width;if(w){if(/\d+px/.test(w)){td.style.minWidth=calc(w,delta);}else if(/\d+%/.test(w)){td.style.width=w;}else{throw new Error('Unrecognized width string: '+w);}}}},createSortCallback_(columnNumber){return function(){if(!this.userCanModifySortOrder_)return;const previousIndex=this.sortColumnIndex;this.sortColumnIndex=columnNumber;if(previousIndex!==columnNumber){this.sortDescending=false;}else{this.sortDescending=!this.sortDescending;}}.bind(this);},generateTableRowNodes_(tableSection,userRows,rowInfoMap,indentation,lastAddedRow,parentRowInfo){if(this.sortColumnIndex_!==undefined&&tableSection===this.$.body){userRows=userRows.slice();userRows.sort(function(rowA,rowB){let c=this.tableColumns_[this.sortColumnIndex_].cmp(rowA,rowB);if(this.sortDescending_){c=-c;}
 return c;}.bind(this));}
-for(var i=0;i<userRows.length;i++){var userRow=userRows[i];var rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);var htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){Polymer.dom(tableSection).insertBefore(htmlNode,Polymer.dom(tableSection).firstChild);}else{var nextSiblingOfLastAdded=Polymer.dom(lastAddedRow).nextSibling;Polymer.dom(tableSection).insertBefore(htmlNode,nextSiblingOfLastAdded);}
+for(let i=0;i<userRows.length;i++){const userRow=userRows[i];const rowInfo=this.getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo);const htmlNode=this.getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation);if(lastAddedRow===undefined){Polymer.dom(tableSection).insertBefore(htmlNode,Polymer.dom(tableSection).firstChild);}else{const nextSiblingOfLastAdded=Polymer.dom(lastAddedRow).nextSibling;Polymer.dom(tableSection).insertBefore(htmlNode,nextSiblingOfLastAdded);}
 lastAddedRow=htmlNode;if(!rowInfo.isExpanded)continue;lastAddedRow=this.generateTableRowNodes_(tableSection,userRow[this.subRowsPropertyName_],rowInfoMap,indentation+1,lastAddedRow,rowInfo);}
-return lastAddedRow;},getOrCreateRowInfoFor_:function(rowInfoMap,userRow,parentRowInfo){var rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow:userRow,htmlNode:undefined,parentRowInfo:parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
-rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_:function(userRow,trElement){if(!this.customizeTableRowCallback_)return;this.customizeTableRowCallback_(userRow,trElement);},get basicIndentation_(){if(this.computedFontSizePx_===undefined){this.computedFontSizePx_=parseInt(getComputedStyle(this).fontSize)||16;}
-return this.computedFontSizePx_-2;},getHTMLNodeForRowInfo_:function(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
-var INDENT_SPACE=indentation*16;var INDENT_SPACE_NO_BUTTON=indentation*16+this.basicIndentation_;var trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);var isBodyRow=tableSection===this.$.body;var isExpandableRow=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;for(var i=0;i<this.tableColumns_.length;){var td=this.appendNewElement_(trElement,'td');td.columnIndex=i;var column=this.tableColumns_[i];var value=column.value(rowInfo.userRow);var colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;switch(column.align){case undefined:case ColumnAlignment.LEFT:break;case ColumnAlignment.RIGHT:td.style.textAlign='right';break;default:throw new Error('Invalid alignment of column at index='+i+': '+column.align);}
+return lastAddedRow;},getOrCreateRowInfoFor_(rowInfoMap,userRow,parentRowInfo){let rowInfo=undefined;if(rowInfoMap.has(userRow)){rowInfo=rowInfoMap.get(userRow);}else{rowInfo={userRow,htmlNode:undefined,parentRowInfo};rowInfoMap.set(userRow,rowInfo);}
+rowInfo.isExpanded=this.getExpandedForUserRow_(userRow);return rowInfo;},customizeTableRow_(userRow,trElement){if(!this.customizeTableRowCallback_)return;this.customizeTableRowCallback_(userRow,trElement);},get basicIndentation_(){if(this.computedFontSizePx_===undefined){this.computedFontSizePx_=parseInt(getComputedStyle(this).fontSize)||16;}
+return this.computedFontSizePx_-2;},getHTMLNodeForRowInfo_(tableSection,rowInfo,rowInfoMap,indentation){if(rowInfo.htmlNode){this.customizeTableRow_(rowInfo.userRow,rowInfo.htmlNode);return rowInfo.htmlNode;}
+const INDENT_SPACE=indentation*16;const INDENT_SPACE_NO_BUTTON=indentation*16+this.basicIndentation_;const trElement=this.ownerDocument.createElement('tr');rowInfo.htmlNode=trElement;rowInfo.indentation=indentation;trElement.rowInfo=rowInfo;this.customizeTableRow_(rowInfo.userRow,trElement);const isBodyRow=tableSection===this.$.body;const isExpandableRow=rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length;for(let i=0;i<this.tableColumns_.length;){const td=this.appendNewElement_(trElement,'td');td.columnIndex=i;const column=this.tableColumns_[i];const value=column.value(rowInfo.userRow);const colSpan=column.colSpan?column.colSpan:1;td.style.colSpan=colSpan;switch(column.align){case undefined:case ColumnAlignment.LEFT:break;case ColumnAlignment.RIGHT:td.style.textAlign='right';break;default:throw new Error('Invalid alignment of column at index='+i+': '+column.align);}
 if(this.doesColumnIndexSupportSelection(i)){Polymer.dom(td).classList.add('supports-selection');}
-if(this.columnsWithExpandButtons_.includes(i)){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';td.style.display='flex';var expandButton=this.appendNewElement_(td,'expand-button');Polymer.dom(expandButton).textContent=RIGHT_ARROW;if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');}}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
+if(this.columnsWithExpandButtons_.includes(i)){if(rowInfo.userRow[this.subRowsPropertyName_]&&rowInfo.userRow[this.subRowsPropertyName_].length>0){td.style.paddingLeft=INDENT_SPACE+'px';td.style.display='flex';const expandButton=this.appendNewElement_(td,'expand-button');Polymer.dom(expandButton).textContent=RIGHT_ARROW;if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');}}else{td.style.paddingLeft=INDENT_SPACE_NO_BUTTON+'px';}}
 if(value!==undefined){Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(value,this.ownerDocument));}
 td.addEventListener('click',function(i,clickEvent){clickEvent.preventDefault();if(!isBodyRow&&!isExpandableRow)return;clickEvent.stopPropagation();if(clickEvent.target.tagName==='EXPAND-BUTTON'){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);return;}
-if(isBodyRow&&this.selectionMode_!==SelectionMode.NONE){var shouldSelect=false;var shouldFocus=false;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;shouldFocus=true;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(i)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==i;shouldFocus=true;}
+if(isBodyRow&&this.selectionMode_!==SelectionMode.NONE){let shouldSelect=false;let shouldFocus=false;switch(this.selectionMode_){case SelectionMode.ROW:shouldSelect=this.selectedTableRowInfo_!==rowInfo;shouldFocus=true;break;case SelectionMode.CELL:if(this.doesColumnIndexSupportSelection(i)){shouldSelect=this.selectedTableRowInfo_!==rowInfo||this.selectedColumnIndex_!==i;shouldFocus=true;}
 break;default:throw new Error('Invalid selection mode '+
 this.selectionMode_);}
 if(shouldFocus){this.focus();}
 if(shouldSelect){this.didTableRowInfoGetClicked_(rowInfo,i);return;}}
 if(isExpandableRow){this.setExpandedForUserRow_(tableSection,rowInfoMap,rowInfo.userRow,!rowInfo.isExpanded);}}.bind(this,i));if(isBodyRow){td.addEventListener('dblclick',function(i,e){e.stopPropagation();this.dispatchStepIntoEvent_(rowInfo,i);}.bind(this,i));}
 i+=colSpan;}
-return rowInfo.htmlNode;},removeSubNodes_:function(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)return;for(var i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){var subRow=rowInfo.userRow[this.subRowsPropertyName_][i];var subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)continue;var subNode=subRowInfo.htmlNode;if(subNode&&Polymer.dom(subNode).parentNode===tableSection){Polymer.dom(tableSection).removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_:function(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_:function(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_:function(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_:function(){if(this.rebuildPending_)return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_:function(){this.rebuild();},rebuild:function(){var wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
-if(this.bodyDirty_){Polymer.dom(this.$.body).textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){var trElement=this.ownerDocument.createElement('tr');Polymer.dom(this.$.body).appendChild(trElement);Polymer.dom(trElement).classList.add('empty-row');var td=this.ownerDocument.createElement('td');Polymer.dom(trElement).appendChild(td);td.colSpan=this.tableColumns_.length;var emptyValue=this.emptyValue_;Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
+return rowInfo.htmlNode;},removeSubNodes_(tableSection,rowInfo,rowInfoMap){if(rowInfo.userRow[this.subRowsPropertyName_]===undefined)return;for(let i=0;i<rowInfo.userRow[this.subRowsPropertyName_].length;i++){const subRow=rowInfo.userRow[this.subRowsPropertyName_][i];const subRowInfo=rowInfoMap.get(subRow);if(!subRowInfo)continue;const subNode=subRowInfo.htmlNode;if(subNode&&Polymer.dom(subNode).parentNode===tableSection){Polymer.dom(tableSection).removeChild(subNode);this.removeSubNodes_(tableSection,subRowInfo,rowInfoMap);}}},scheduleRebuildHeaders_(){this.headerDirty_=true;this.scheduleRebuild_();},scheduleRebuildBody_(){this.bodyDirty_=true;this.scheduleRebuild_();},scheduleRebuildFooter_(){this.footerDirty_=true;this.scheduleRebuild_();},scheduleRebuild_(){if(this.rebuildPending_)return;this.rebuildPending_=true;setTimeout(function(){this.rebuildPending_=false;this.rebuild();}.bind(this),0);},rebuildIfNeeded_(){this.rebuild();},rebuild(){const wasBodyOrHeaderDirty=this.headerDirty_||this.bodyDirty_;if(this.headerDirty_){this.generateHeaderColumns_();this.headerDirty_=false;}
+if(this.bodyDirty_){Polymer.dom(this.$.body).textContent='';this.generateTableRowNodes_(this.$.body,this.tableRows_,this.tableRowsInfo_,0,undefined,undefined);if(this.tableRows_.length===0&&this.emptyValue_!==undefined){const trElement=this.ownerDocument.createElement('tr');Polymer.dom(this.$.body).appendChild(trElement);Polymer.dom(trElement).classList.add('empty-row');const td=this.ownerDocument.createElement('td');Polymer.dom(trElement).appendChild(td);td.colSpan=this.tableColumns_.length;const emptyValue=this.emptyValue_;Polymer.dom(td).appendChild(tr.ui.b.asHTMLOrTextNode(emptyValue,this.ownerDocument));}
 this.bodyDirty_=false;}
 if(wasBodyOrHeaderDirty)this.applySizes_();if(this.footerDirty_){Polymer.dom(this.$.foot).textContent='';this.generateTableRowNodes_(this.$.foot,this.tableFooterRows_,this.tableFooterRowsInfo_,0,undefined,undefined);if(this.tableFooterRowsInfo_.length){Polymer.dom(this.$.body).classList.add('has-footer');}else{Polymer.dom(this.$.body).classList.remove('has-footer');}
-this.footerDirty_=false;}},appendNewElement_:function(parent,tagName){var element=parent.ownerDocument.createElement(tagName);Polymer.dom(parent).appendChild(element);return element;},getExpandedForTableRow:function(userRow){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
-return rowInfo.isExpanded;},getExpandedForUserRow_:function(userRow){if(userRow[this.subRowsPropertyName_]===undefined){return false;}
+this.footerDirty_=false;}},appendNewElement_(parent,tagName){const element=parent.ownerDocument.createElement(tagName);Polymer.dom(parent).appendChild(element);return element;},getExpandedForTableRow(userRow){this.rebuildIfNeeded_();const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+return rowInfo.isExpanded;},getExpandedForUserRow_(userRow){if(userRow[this.subRowsPropertyName_]===undefined){return false;}
 if(userRow[this.subRowsPropertyName_].length===0){return false;}
 if(userRow.isExpanded){return true;}
 if((userRow.isExpanded!==undefined)&&(userRow.isExpanded===false)){return false;}
-var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.isExpanded){return true;}
+const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo&&rowInfo.isExpanded){return true;}
 if(this.defaultExpansionStateCallback_===undefined){return false;}
-var parentUserRow=undefined;if(rowInfo&&rowInfo.parentRowInfo){parentUserRow=rowInfo.parentRowInfo.userRow;}
-return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow:function(userRow,expanded){this.rebuildIfNeeded_();var rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
-return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_:function(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();var rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+let parentUserRow=undefined;if(rowInfo&&rowInfo.parentRowInfo){parentUserRow=rowInfo.parentRowInfo.userRow;}
+return this.defaultExpansionStateCallback_(userRow,parentUserRow);},setExpandedForTableRow(userRow,expanded){this.rebuildIfNeeded_();const rowInfo=this.tableRowsInfo_.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
+return this.setExpandedForUserRow_(this.$.body,this.tableRowsInfo_,userRow,expanded);},setExpandedForUserRow_(tableSection,rowInfoMap,userRow,expanded){this.rebuildIfNeeded_();const rowInfo=rowInfoMap.get(userRow);if(rowInfo===undefined){throw new Error('Row has not been seen, must expand its parents');}
 const wasExpanded=rowInfo.isExpanded;rowInfo.isExpanded=!!expanded;if(rowInfo.htmlNode===undefined)return;if(rowInfo.htmlNode.parentElement!==tableSection){return;}
-var expandButton=Polymer.dom(rowInfo.htmlNode).querySelector('expand-button');if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');var lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{Polymer.dom(expandButton).classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
-if(wasExpanded!==rowInfo.isExpanded){let e=new tr.b.Event('row-expanded-changed');e.row=rowInfo.userRow;this.dispatchEvent(e);}
+const expandButton=Polymer.dom(rowInfo.htmlNode).querySelector('expand-button');if(rowInfo.isExpanded){Polymer.dom(expandButton).classList.add('button-expanded');const lastAddedRow=rowInfo.htmlNode;if(rowInfo.userRow[this.subRowsPropertyName_]){this.generateTableRowNodes_(tableSection,rowInfo.userRow[this.subRowsPropertyName_],rowInfoMap,rowInfo.indentation+1,lastAddedRow,rowInfo);}}else{Polymer.dom(expandButton).classList.remove('button-expanded');this.removeSubNodes_(tableSection,rowInfo,rowInfoMap);}
+if(wasExpanded!==rowInfo.isExpanded){const e=new tr.b.Event('row-expanded-changed');e.row=rowInfo.userRow;this.dispatchEvent(e);}
 this.maybeUpdateSelectedRow_();},get selectionMode(){return this.selectionMode_;},set selectionMode(selectionMode){if(!tr.b.dictionaryContainsValue(SelectionMode,selectionMode)){throw new Error('Invalid selection mode '+selectionMode);}
 this.rebuildIfNeeded_();this.selectionMode_=selectionMode;this.didSelectionStateChange_();},get rowHighlightStyle(){return this.rowHighlightStyle_;},set rowHighlightStyle(rowHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,rowHighlightStyle)){throw new Error('Invalid row highlight style '+rowHighlightStyle);}
 this.rebuildIfNeeded_();this.rowHighlightStyle_=rowHighlightStyle;this.didSelectionStateChange_();},get resolvedRowHighlightStyle(){if(this.rowHighlightStyle_!==HighlightStyle.DEFAULT){return this.rowHighlightStyle_;}
 switch(this.selectionMode_){case SelectionMode.NONE:return HighlightStyle.NONE;case SelectionMode.ROW:return HighlightStyle.DARK;case SelectionMode.CELL:return HighlightStyle.LIGHT;default:throw new Error('Invalid selection mode '+selectionMode);}},get cellHighlightStyle(){return this.cellHighlightStyle_;},set cellHighlightStyle(cellHighlightStyle){if(!tr.b.dictionaryContainsValue(HighlightStyle,cellHighlightStyle)){throw new Error('Invalid cell highlight style '+cellHighlightStyle);}
 this.rebuildIfNeeded_();this.cellHighlightStyle_=cellHighlightStyle;this.didSelectionStateChange_();},get resolvedCellHighlightStyle(){if(this.cellHighlightStyle_!==HighlightStyle.DEFAULT){return this.cellHighlightStyle_;}
-switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_:function(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:Polymer.dom(this.$.body).removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
-resolvedHighlightStyle);}},didSelectionStateChange_:function(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);this.removeSelectedState_();switch(this.selectionMode_){case SelectionMode.ROW:Polymer.dom(this.$.body).setAttribute('selection-mode','row');Polymer.dom(this.$.body).setAttribute('tabindex',0);this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:Polymer.dom(this.$.body).setAttribute('selection-mode','cell');Polymer.dom(this.$.body).setAttribute('tabindex',0);if(this.selectedTableRowInfo_&&this.selectedColumnIndex_===undefined){var i=this.getFirstSelectableColumnIndex_();if(i===-1){this.selectedTableRowInfo_=undefined;}else{this.selectedColumnIndex_=i;}}
+switch(this.selectionMode_){case SelectionMode.NONE:case SelectionMode.ROW:return HighlightStyle.NONE;case SelectionMode.CELL:return HighlightStyle.DARK;default:throw new Error('Invalid selection mode '+selectionMode);}},setHighlightStyle_(highlightAttribute,resolvedHighlightStyle){switch(resolvedHighlightStyle){case HighlightStyle.NONE:Polymer.dom(this.$.body).removeAttribute(highlightAttribute);break;case HighlightStyle.LIGHT:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'light');break;case HighlightStyle.DARK:Polymer.dom(this.$.body).setAttribute(highlightAttribute,'dark');break;default:throw new Error('Invalid resolved highlight style '+
+resolvedHighlightStyle);}},didSelectionStateChange_(){this.setHighlightStyle_('row-highlight-style',this.resolvedRowHighlightStyle);this.setHighlightStyle_('cell-highlight-style',this.resolvedCellHighlightStyle);this.removeSelectedState_();switch(this.selectionMode_){case SelectionMode.ROW:Polymer.dom(this.$.body).setAttribute('selection-mode','row');Polymer.dom(this.$.body).setAttribute('tabindex',0);this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:Polymer.dom(this.$.body).setAttribute('selection-mode','cell');Polymer.dom(this.$.body).setAttribute('tabindex',0);if(this.selectedTableRowInfo_&&this.selectedColumnIndex_===undefined){const i=this.getFirstSelectableColumnIndex_();if(i===-1){this.selectedTableRowInfo_=undefined;}else{this.selectedColumnIndex_=i;}}
 break;case SelectionMode.NONE:Polymer.dom(this.$.body).removeAttribute('selection-mode');Polymer.dom(this.$.body).removeAttribute('tabindex');this.$.body.blur();this.selectedTableRowInfo_=undefined;this.selectedColumnIndex_=undefined;break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
-this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_:function(){if(this.selectedTableRowInfo_===undefined)return;function isVisible(rowInfo){if(!rowInfo.htmlNode)return false;return!!rowInfo.htmlNode.parentElement;}
+this.maybeUpdateSelectedRow_();},maybeUpdateSelectedRow_(){if(this.selectedTableRowInfo_===undefined)return;function isVisible(rowInfo){if(!rowInfo.htmlNode)return false;return!!rowInfo.htmlNode.parentElement;}
 if(isVisible(this.selectedTableRowInfo_)){this.updateSelectedState_();return;}
-this.removeSelectedState_();var curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo)){curRowInfo=curRowInfo.parentRowInfo;}
-this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_){this.updateSelectedState_();}else{this.selectedColumnIndex_=undefined;}},didTableRowInfoGetClicked_:function(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex)){return;}
+this.removeSelectedState_();let curRowInfo=this.selectedTableRowInfo_;while(curRowInfo&&!isVisible(curRowInfo)){curRowInfo=curRowInfo.parentRowInfo;}
+this.selectedTableRowInfo_=curRowInfo;if(this.selectedTableRowInfo_){this.updateSelectedState_();}else{this.selectedColumnIndex_=undefined;}},didTableRowInfoGetClicked_(rowInfo,columnIndex){switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.CELL:if(!this.doesColumnIndexSupportSelection(columnIndex)){return;}
 if(this.selectedColumnIndex!==columnIndex){this.selectedColumnIndex=columnIndex;}
-case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo){this.selectedTableRow=rowInfo.userRow;}}},dispatchStepIntoEvent_:function(rowInfo,columnIndex){var e=new tr.b.Event('step-into');e.tableRow=rowInfo.userRow;e.tableColumn=this.tableColumns_[columnIndex];e.columnIndex=columnIndex;this.dispatchEvent(e);},get selectedCell(){var row=this.selectedTableRow;var columnIndex=this.selectedColumnIndex;if(row===undefined||columnIndex===undefined||this.tableColumns_.length<=columnIndex){return undefined;}
-var column=this.tableColumns_[columnIndex];return{row:row,column:column,value:column.value(row)};},get selectedTableColumnIndex(){var cols=Polymer.dom(this.$.cols).children;for(var i=0;i<cols.length;++i){if(cols[i].getAttribute('selected')){return i;}}
-return undefined;},set selectedTableColumnIndex(selectedIndex){var cols=Polymer.dom(this.$.cols).children;for(var i=0;i<cols.length;++i){if(i===selectedIndex){cols[i].setAttribute('selected',true);}else{cols[i].removeAttribute('selected');}}},get selectedTableRow(){if(!this.selectedTableRowInfo_)return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
-var rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo){throw new Error('Row has not been seen, must expand its parents.');}}
-var e=this.prepareToChangeSelection_();if(!rowInfo){this.selectedColumnIndex_=undefined;}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){var i=this.getFirstSelectableColumnIndex_();if(i===-1){throw new Error('Cannot find a selectable column.');}
+case SelectionMode.ROW:if(this.selectedTableRowInfo_!==rowInfo){this.selectedTableRow=rowInfo.userRow;}}},dispatchStepIntoEvent_(rowInfo,columnIndex){const e=new tr.b.Event('step-into');e.tableRow=rowInfo.userRow;e.tableColumn=this.tableColumns_[columnIndex];e.columnIndex=columnIndex;this.dispatchEvent(e);},get selectedCell(){const row=this.selectedTableRow;const columnIndex=this.selectedColumnIndex;if(row===undefined||columnIndex===undefined||this.tableColumns_.length<=columnIndex){return undefined;}
+const column=this.tableColumns_[columnIndex];return{row,column,value:column.value(row)};},get selectedTableColumnIndex(){const cols=Polymer.dom(this.$.cols).children;for(let i=0;i<cols.length;++i){if(cols[i].getAttribute('selected')){return i;}}
+return undefined;},set selectedTableColumnIndex(selectedIndex){const cols=Polymer.dom(this.$.cols).children;for(let i=0;i<cols.length;++i){if(i===selectedIndex){cols[i].setAttribute('selected',true);}else{cols[i].removeAttribute('selected');}}},get selectedTableRow(){if(!this.selectedTableRowInfo_)return undefined;return this.selectedTableRowInfo_.userRow;},set selectedTableRow(userRow){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
+let rowInfo;if(userRow===undefined){rowInfo=undefined;}else{rowInfo=this.tableRowsInfo_.get(userRow);if(!rowInfo){throw new Error('Row has not been seen, must expand its parents.');}}
+const e=this.prepareToChangeSelection_();if(!rowInfo){this.selectedColumnIndex_=undefined;}else{switch(this.selectionMode_){case SelectionMode.ROW:this.selectedColumnIndex_=undefined;break;case SelectionMode.CELL:if(this.selectedColumnIndex_===undefined){const i=this.getFirstSelectableColumnIndex_();if(i===-1){throw new Error('Cannot find a selectable column.');}
 this.selectedColumnIndex_=i;}
 break;default:throw new Error('Invalid selection mode '+this.selectionMode_);}}
-this.selectedTableRowInfo_=rowInfo;this.updateSelectedState_();this.dispatchEvent(e);},prepareToChangeSelection_:function(){var e=new tr.b.Event('selection-changed');var previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo){e.previousSelectedTableRow=previousSelectedRowInfo.userRow;}else{e.previousSelectedTableRow=undefined;}
-this.removeSelectedState_();return e;},removeSelectedState_:function(){this.setSelectedState_(false);},updateSelectedState_:function(){this.setSelectedState_(true);},setSelectedState_:function(select){if(this.selectedTableRowInfo_===undefined)return;var rowNode=this.selectedTableRowInfo_.htmlNode;if(select){Polymer.dom(rowNode).setAttribute('selected',true);}else{Polymer.dom(rowNode).removeAttribute('selected');}
-var cellNode=Polymer.dom(rowNode).children[this.selectedColumnIndex_];if(!cellNode)return;if(select){Polymer.dom(cellNode).setAttribute('selected',true);}else{Polymer.dom(cellNode).removeAttribute('selected');}},doesColumnIndexSupportSelection:function(columnIndex){var columnInfo=this.tableColumns_[columnIndex];var scs=columnInfo.supportsCellSelection;if(scs===false)return false;return true;},getFirstSelectableColumnIndex_:function(){for(var i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){return i;}}
-return-1;},getSelectableNodeGivenTableRowNode_:function(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return Polymer.dom(htmlNode).children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL){return undefined;}
+this.selectedTableRowInfo_=rowInfo;this.updateSelectedState_();this.dispatchEvent(e);},prepareToChangeSelection_(){const e=new tr.b.Event('selection-changed');const previousSelectedRowInfo=this.selectedTableRowInfo_;if(previousSelectedRowInfo){e.previousSelectedTableRow=previousSelectedRowInfo.userRow;}else{e.previousSelectedTableRow=undefined;}
+this.removeSelectedState_();return e;},removeSelectedState_(){this.setSelectedState_(false);},updateSelectedState_(){this.setSelectedState_(true);},setSelectedState_(select){if(this.selectedTableRowInfo_===undefined)return;const rowNode=this.selectedTableRowInfo_.htmlNode;if(select){Polymer.dom(rowNode).setAttribute('selected',true);}else{Polymer.dom(rowNode).removeAttribute('selected');}
+const cellNode=Polymer.dom(rowNode).children[this.selectedColumnIndex_];if(!cellNode)return;if(select){Polymer.dom(cellNode).setAttribute('selected',true);}else{Polymer.dom(cellNode).removeAttribute('selected');}},doesColumnIndexSupportSelection(columnIndex){const columnInfo=this.tableColumns_[columnIndex];const scs=columnInfo.supportsCellSelection;if(scs===false)return false;return true;},getFirstSelectableColumnIndex_(){for(let i=0;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){return i;}}
+return-1;},getSelectableNodeGivenTableRowNode_(htmlNode){switch(this.selectionMode_){case SelectionMode.ROW:return htmlNode;case SelectionMode.CELL:return Polymer.dom(htmlNode).children[this.selectedColumnIndex_];default:throw new Error('Invalid selection mode '+this.selectionMode_);}},get selectedColumnIndex(){if(this.selectionMode_!==SelectionMode.CELL){return undefined;}
 return this.selectedColumnIndex_;},set selectedColumnIndex(selectedColumnIndex){this.rebuildIfNeeded_();if(this.selectionMode_===SelectionMode.NONE){throw new Error('Selection is off.');}
 if(selectedColumnIndex<0||selectedColumnIndex>=this.tableColumns_.length){throw new Error('Invalid index');}
 if(!this.doesColumnIndexSupportSelection(selectedColumnIndex)){throw new Error('Selection is not supported on this column');}
-var e=this.prepareToChangeSelection_();if(this.selectedColumnIndex_===undefined){this.selectedTableRowInfo_=undefined;}else if(!this.selectedTableRowInfo_){if(this.tableRows_.length===0){throw new Error('No available row to be selected');}
+const e=this.prepareToChangeSelection_();if(this.selectedColumnIndex_===undefined){this.selectedTableRowInfo_=undefined;}else if(!this.selectedTableRowInfo_){if(this.tableRows_.length===0){throw new Error('No available row to be selected');}
 this.selectedTableRowInfo_=this.tableRowsInfo_.get(this.tableRows_[0]);}
-this.selectedColumnIndex_=selectedColumnIndex;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_:function(e){if(this.selectionMode_===SelectionMode.NONE)return;var CODE_TO_COMMAND_NAMES={13:'ENTER',32:'SPACE',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};var cmdName=CODE_TO_COMMAND_NAMES[e.keyCode];if(cmdName===undefined)return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},onFocus_:function(e){if(this.selectionMode_===SelectionMode.NONE||this.selectedTableRow||this.tableRows_.length===0){return;}
+this.selectedColumnIndex_=selectedColumnIndex;this.updateSelectedState_();this.dispatchEvent(e);},onKeyDown_(e){if(this.selectionMode_===SelectionMode.NONE)return;const CODE_TO_COMMAND_NAMES={13:'ENTER',32:'SPACE',37:'ARROW_LEFT',38:'ARROW_UP',39:'ARROW_RIGHT',40:'ARROW_DOWN'};const cmdName=CODE_TO_COMMAND_NAMES[e.keyCode];if(cmdName===undefined)return;e.stopPropagation();e.preventDefault();this.performKeyCommand_(cmdName);},onFocus_(e){if(this.selectionMode_===SelectionMode.NONE||this.selectedTableRow||this.tableRows_.length===0){return;}
 if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
-this.selectedTableRow=this.tableRows_[0];},focus:function(){this.$.body.focus();this.onFocus_();},blur:function(){this.$.body.blur();},get isFocused(){return this.root.activeElement===this.$.body;},performKeyCommand_:function(cmdName){this.rebuildIfNeeded_();switch(cmdName){case'ARROW_UP':this.selectPreviousOrFirstRowIfPossible_();return;case'ARROW_DOWN':this.selectNextOrFirstRowIfPossible_();return;case'ARROW_RIGHT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.expandRowAndSelectChildRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheRightIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
+this.selectedTableRow=this.tableRows_[0];},focus(){this.$.body.focus();this.onFocus_();},blur(){this.$.body.blur();},get isFocused(){return this.root.activeElement===this.$.body;},performKeyCommand_(cmdName){this.rebuildIfNeeded_();switch(cmdName){case'ARROW_UP':this.selectPreviousOrFirstRowIfPossible_();return;case'ARROW_DOWN':this.selectNextOrFirstRowIfPossible_();return;case'ARROW_RIGHT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.expandRowAndSelectChildRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheRightIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
 case'ARROW_LEFT':switch(this.selectionMode_){case SelectionMode.NONE:return;case SelectionMode.ROW:this.collapseRowOrSelectParentRowIfPossible_();return;case SelectionMode.CELL:this.selectNextSelectableCellToTheLeftIfPossible_();return;default:throw new Error('Invalid selection mode '+this.selectionMode_);}
-case'SPACE':this.toggleRowExpansionStateIfPossible_();return;case'ENTER':this.stepIntoSelectionIfPossible_();return;default:throw new Error('Unrecognized command '+cmdName);}},selectPreviousOrFirstRowIfPossible_:function(){var prev=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.previousElementSibling:this.$.body.firstChild;if(!prev)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
-tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;},selectNextOrFirstRowIfPossible_:function(){this.getFirstSelectableColumnIndex_;var next=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.nextElementSibling:this.$.body.firstChild;if(!next)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
-tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;},expandRowAndSelectChildRowIfPossible_:function(){var selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
+case'SPACE':this.toggleRowExpansionStateIfPossible_();return;case'ENTER':this.stepIntoSelectionIfPossible_();return;default:throw new Error('Unrecognized command '+cmdName);}},selectPreviousOrFirstRowIfPossible_(){const prev=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.previousElementSibling:this.$.body.firstChild;if(!prev)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+tr.ui.b.scrollIntoViewIfNeeded(prev);this.selectedTableRow=prev.rowInfo.userRow;},selectNextOrFirstRowIfPossible_(){this.getFirstSelectableColumnIndex_;const next=this.selectedTableRowInfo_?this.selectedTableRowInfo_.htmlNode.nextElementSibling:this.$.body.firstChild;if(!next)return;if(this.selectionMode_===SelectionMode.CELL&&this.getFirstSelectableColumnIndex_()===-1){return;}
+tr.ui.b.scrollIntoViewIfNeeded(next);this.selectedTableRow=next.rowInfo.userRow;},expandRowAndSelectChildRowIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
 if(!selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,true);}
-this.selectedTableRow=selectedRowInfo.htmlNode.nextElementSibling.rowInfo.userRow;},collapseRowOrSelectParentRowIfPossible_:function(){var selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo)return;if(selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,false);}else{var parentRowInfo=selectedRowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;}}},selectNextSelectableCellToTheRightIfPossible_:function(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
-for(var i=this.selectedColumnIndex_+1;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},selectNextSelectableCellToTheLeftIfPossible_:function(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
-for(var i=this.selectedColumnIndex_-1;i>=0;i--){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},toggleRowExpansionStateIfPossible_:function(){var selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
-this.setExpandedForTableRow(selectedRowInfo.userRow,!selectedRowInfo.isExpanded);},stepIntoSelectionIfPossible_:function(){if(!this.selectedTableRowInfo_)return;this.dispatchStepIntoEvent_(this.selectedTableRowInfo_,this.selectedColumnIndex_);},dispatchSortingChangedEvent_:function(){var e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';var ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;Polymer({is:'tr-ui-b-table-header-cell',created:function(){this.tapCallback_=undefined;this.cellTitle_='';this.align_=undefined;this.selectable_=false;this.column_=undefined;},ready:function(){this.addEventListener('click',this.onTap_.bind(this));},set column(column){this.column_=column;this.align=column.align;this.cellTitle=column.title;},get column(){return this.column_;},set cellTitle(value){this.cellTitle_=value;var titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';Polymer.dom(this.$.title).appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},set align(align){switch(align){case undefined:case ColumnAlignment.LEFT:this.style.justifyContent='';break;case ColumnAlignment.RIGHT:this.style.justifyContent='flex-end';break;default:throw new Error('Invalid alignment of column (title=\''+
+this.selectedTableRow=selectedRowInfo.htmlNode.nextElementSibling.rowInfo.userRow;},collapseRowOrSelectParentRowIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo)return;if(selectedRowInfo.isExpanded){this.setExpandedForTableRow(selectedRowInfo.userRow,false);}else{const parentRowInfo=selectedRowInfo.parentRowInfo;if(parentRowInfo){this.selectedTableRow=parentRowInfo.userRow;}}},selectNextSelectableCellToTheRightIfPossible_(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
+for(let i=this.selectedColumnIndex_+1;i<this.tableColumns_.length;i++){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},selectNextSelectableCellToTheLeftIfPossible_(){if(!this.selectedTableRowInfo_||this.selectedColumnIndex_===undefined){return;}
+for(let i=this.selectedColumnIndex_-1;i>=0;i--){if(this.doesColumnIndexSupportSelection(i)){this.selectedColumnIndex=i;return;}}},toggleRowExpansionStateIfPossible_(){const selectedRowInfo=this.selectedTableRowInfo_;if(!selectedRowInfo||selectedRowInfo.userRow[this.subRowsPropertyName_]===undefined||selectedRowInfo.userRow[this.subRowsPropertyName_].length===0){return;}
+this.setExpandedForTableRow(selectedRowInfo.userRow,!selectedRowInfo.isExpanded);},stepIntoSelectionIfPossible_(){if(!this.selectedTableRowInfo_)return;this.dispatchStepIntoEvent_(this.selectedTableRowInfo_,this.selectedColumnIndex_);},dispatchSortingChangedEvent_(){const e=new tr.b.Event('sort-column-changed');e.sortColumnIndex=this.sortColumnIndex_;e.sortDescending=this.sortDescending_;this.dispatchEvent(e);}});})();'use strict';const ColumnAlignment=tr.ui.b.TableFormat.ColumnAlignment;Polymer({is:'tr-ui-b-table-header-cell',created(){this.tapCallback_=undefined;this.cellTitle_='';this.align_=undefined;this.selectable_=false;this.column_=undefined;},ready(){this.addEventListener('click',this.onTap_.bind(this));},set column(column){this.column_=column;this.align=column.align;this.cellTitle=column.title;},get column(){return this.column_;},set cellTitle(value){this.cellTitle_=value;const titleNode=tr.ui.b.asHTMLOrTextNode(this.cellTitle_,this.ownerDocument);this.$.title.innerText='';Polymer.dom(this.$.title).appendChild(titleNode);},get cellTitle(){return this.cellTitle_;},set align(align){switch(align){case undefined:case ColumnAlignment.LEFT:this.style.justifyContent='';break;case ColumnAlignment.RIGHT:this.style.justifyContent='flex-end';break;default:throw new Error('Invalid alignment of column (title=\''+
 this.cellTitle_+'\'): '+align);}
-this.align_=align;},get align(){return this.align_;},clearSideContent:function(){Polymer.dom(this.$.side).textContent='';},set sideContent(content){Polymer.dom(this.$.side).textContent=content;this.$.side.style.display=content?'inline':'none';},get sideContent(){return Polymer.dom(this.$.side).textContent;},set sideContentDisabled(sideContentDisabled){this.$.side.classList.toggle('disabled',sideContentDisabled);},get sideContentDisabled(){return this.$.side.classList.contains('disabled');},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_:function(){if(this.tapCallback_){this.tapCallback_();}}});'use strict';tr.exportTo('tr.b.math',function(){class RunningStatistics{constructor(){this.mean_=0;this.count_=0;this.max_=-Infinity;this.min_=Infinity;this.sum_=0;this.variance_=0;this.meanlogs_=0;}
+this.align_=align;},get align(){return this.align_;},clearSideContent(){Polymer.dom(this.$.side).textContent='';},set sideContent(content){Polymer.dom(this.$.side).textContent=content;this.$.side.style.display=content?'inline':'none';},get sideContent(){return Polymer.dom(this.$.side).textContent;},set sideContentDisabled(sideContentDisabled){this.$.side.classList.toggle('disabled',sideContentDisabled);},get sideContentDisabled(){return this.$.side.classList.contains('disabled');},set tapCallback(callback){this.style.cursor='pointer';this.tapCallback_=callback;},get tapCallback(){return this.tapCallback_;},onTap_(){if(this.tapCallback_){this.tapCallback_();}}});'use strict';tr.exportTo('tr.b.math',function(){class RunningStatistics{constructor(){this.mean_=0;this.count_=0;this.max_=-Infinity;this.min_=Infinity;this.sum_=0;this.variance_=0;this.meanlogs_=0;}
 get count(){return this.count_;}
 get geometricMean(){if(this.meanlogs_===undefined)return 0;return Math.exp(this.meanlogs_);}
 get mean(){if(this.count_===0)return undefined;return this.mean_;}
@@ -6476,15 +6796,15 @@
 get variance(){if(this.count_===0)return undefined;if(this.count_===1)return 0;return this.variance_/(this.count_-1);}
 get stddev(){if(this.count_===0)return undefined;return Math.sqrt(this.variance);}
 add(x){this.count_++;this.max_=Math.max(this.max_,x);this.min_=Math.min(this.min_,x);this.sum_+=x;if(x<=0){this.meanlogs_=undefined;}else if(this.meanlogs_!==undefined){this.meanlogs_+=(Math.log(Math.abs(x))-this.meanlogs_)/this.count;}
-if(this.count_===1){this.mean_=x;this.variance_=0;}else{var oldMean=this.mean_;var oldVariance=this.variance_;if(oldMean===Infinity||oldMean===-Infinity){this.mean_=this.sum_/this.count_;}else{this.mean_=oldMean+(x-oldMean)/this.count_;}
+if(this.count_===1){this.mean_=x;this.variance_=0;}else{const oldMean=this.mean_;const oldVariance=this.variance_;if(oldMean===Infinity||oldMean===-Infinity){this.mean_=this.sum_/this.count_;}else{this.mean_=oldMean+(x-oldMean)/this.count_;}
 this.variance_=oldVariance+(x-oldMean)*(x-this.mean_);}}
-merge(other){var result=new RunningStatistics();result.count_=this.count_+other.count_;result.sum_=this.sum_+other.sum_;result.min_=Math.min(this.min_,other.min_);result.max_=Math.max(this.max_,other.max_);if(result.count===0){result.mean_=0;result.variance_=0;result.meanlogs_=0;}else{result.mean_=result.sum/result.count;var deltaMean=(this.mean||0)-(other.mean||0);result.variance_=this.variance_+other.variance_+
+merge(other){const result=new RunningStatistics();result.count_=this.count_+other.count_;result.sum_=this.sum_+other.sum_;result.min_=Math.min(this.min_,other.min_);result.max_=Math.max(this.max_,other.max_);if(result.count===0){result.mean_=0;result.variance_=0;result.meanlogs_=0;}else{result.mean_=result.sum/result.count;const deltaMean=(this.mean||0)-(other.mean||0);result.variance_=this.variance_+other.variance_+
 (this.count*other.count*deltaMean*deltaMean/result.count);if(this.meanlogs_===undefined||other.meanlogs_===undefined){result.meanlogs_=undefined;}else{result.meanlogs_=(this.count*this.meanlogs_+
 other.count*other.meanlogs_)/result.count;}}
 return result;}
 asDict(){if(!this.count){return[];}
 return[this.count_,this.max_,this.meanlogs_,this.mean_,this.min_,this.sum_,this.variance_,];}
-static fromDict(dict){var result=new RunningStatistics();if(dict.length!==7){return result;}
+static fromDict(dict){const result=new RunningStatistics();if(dict.length!==7){return result;}
 [result.count_,result.max_,result.meanlogs_,result.mean_,result.min_,result.sum_,result.variance_,]=dict;return result;}}
 return{RunningStatistics,};});'use strict';tr.exportTo('tr.v.d',function(){class Diagnostic{constructor(){this.guid_=undefined;}
 clone(){return new this.constructor();}
@@ -6496,27 +6816,27 @@
 this.guid_=guid;}
 asDictOrReference(){if(this.guid_!==undefined){return this.guid_;}
 return this.asDict();}
-asDict(){let result={type:this.constructor.name};if(this.guid_!==undefined){result.guid=this.guid_;}
+asDict(){const result={type:this.constructor.name};if(this.guid_!==undefined){result.guid=this.guid_;}
 this.asDictInto_(result);return result;}
 asDictInto_(d){throw new Error('Abstract virtual method: subclasses must override '+'this method if they override canAddDiagnostic');}
-static fromDict(d){let typeInfo=Diagnostic.findTypeInfoWithName(d.type);if(!typeInfo){throw new Error('Unrecognized diagnostic type: '+d.type);}
-return typeInfo.constructor.fromDict(d);}}
-let options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Diagnostic;tr.b.decorateExtensionRegistry(Diagnostic,options);Diagnostic.addEventListener('will-register',function(e){let constructor=e.typeInfo.constructor;if(!(constructor.fromDict instanceof Function)||(constructor.fromDict===Diagnostic.fromDict)||(constructor.fromDict.length!==1)){throw new Error('Diagnostics must define fromDict(d)');}});return{Diagnostic,};});'use strict';tr.exportTo('tr.v.d',function(){class Breakdown extends tr.v.d.Diagnostic{constructor(){super();this.values_=new Map();this.colorScheme=undefined;}
-clone(){let clone=new Breakdown();clone.colorScheme=this.colorScheme;clone.addDiagnostic(this);return clone;}
+static fromDict(d){const typeInfo=Diagnostic.findTypeInfoWithName(d.type);if(!typeInfo){throw new Error('Unrecognized diagnostic type: '+d.type);}
+const diagnostic=typeInfo.constructor.fromDict(d);if(d.guid!==undefined)diagnostic.guid=d.guid;return diagnostic;}}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Diagnostic;tr.b.decorateExtensionRegistry(Diagnostic,options);Diagnostic.addEventListener('will-register',function(e){const constructor=e.typeInfo.constructor;if(!(constructor.fromDict instanceof Function)||(constructor.fromDict===Diagnostic.fromDict)||(constructor.fromDict.length!==1)){throw new Error('Diagnostics must define fromDict(d)');}});return{Diagnostic,};});'use strict';tr.exportTo('tr.v.d',function(){class Breakdown extends tr.v.d.Diagnostic{constructor(){super();this.values_=new Map();this.colorScheme=undefined;}
+clone(){const clone=new Breakdown();clone.colorScheme=this.colorScheme;clone.addDiagnostic(this);return clone;}
 canAddDiagnostic(otherDiagnostic){return((otherDiagnostic instanceof Breakdown)&&(otherDiagnostic.colorScheme===this.colorScheme));}
-addDiagnostic(otherDiagnostic){for(let[name,value]of otherDiagnostic){this.set(name,this.get(name)+value);}
+addDiagnostic(otherDiagnostic){for(const[name,value]of otherDiagnostic){this.set(name,this.get(name)+value);}
 return this;}
 set(name,value){if(typeof name!=='string'||typeof value!=='number'){throw new Error('Breakdown maps from strings to numbers');}
 this.values_.set(name,value);}
-get(name){return this.values_.get(name)||0;}*[Symbol.iterator](){for(let pair of this.values_){yield pair;}}
-asDictInto_(d){d.values={};for(let[name,value]of this){d.values[name]=tr.b.numberToJson(value);}
+get(name){return this.values_.get(name)||0;}*[Symbol.iterator](){for(const pair of this.values_){yield pair;}}
+asDictInto_(d){d.values={};for(const[name,value]of this){d.values[name]=tr.b.numberToJson(value);}
 if(this.colorScheme){d.colorScheme=this.colorScheme;}}
-static fromDict(d){let breakdown=new Breakdown();for(let[name,value]of Object.entries(d.values)){breakdown.set(name,tr.b.numberFromJson(value));}
+static fromDict(d){const breakdown=new Breakdown();for(const[name,value]of Object.entries(d.values)){breakdown.set(name,tr.b.numberFromJson(value));}
 if(d.colorScheme){breakdown.colorScheme=d.colorScheme;}
 return breakdown;}}
 tr.v.d.Diagnostic.register(Breakdown,{elementName:'tr-v-ui-breakdown-span'});return{Breakdown,};});'use strict';tr.exportTo('tr.v.d',function(){class BuildbotInfo extends tr.v.d.Diagnostic{constructor(info){super();this.displayMasterName_=info.displayMasterName||'';this.displayBotName_=info.displayBotName||'';this.buildbotMasterName_=info.buildbotMasterName||'';this.buildbotName_=info.buildbotName||'';this.buildNumber_=info.buildNumber||0;this.logUri_=info.logUri||'';}
 addToHistogram(hist){hist.diagnostics.set(BuildbotInfo.NAME,this);}
-clone(){let clone=new tr.v.d.MergedBuildbotInfo();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.MergedBuildbotInfo();clone.addDiagnostic(this);return clone;}
 asDictInto_(d){d.displayMasterName=this.displayMasterName;d.displayBotName=this.displayBotName;d.buildbotMasterName=this.buildbotMasterName;d.buildbotName=this.buildbotName;d.buildNumber=this.buildNumber;d.logUri=this.logUri;}
 get displayMasterName(){return this.displayMasterName_;}
 get displayBotName(){return this.displayBotName_;}
@@ -6526,31 +6846,31 @@
 get logUri(){return this.logUri_;}
 static fromDict(d){return new BuildbotInfo(d);}
 static getFromHistogram(hist){return hist.diagnostics.get(BuildbotInfo.NAME);}
-static getField(hist,fieldName,defaultValue){let buildbot=BuildbotInfo.getFromHistogram(hist);if(!(buildbot instanceof tr.v.d.BuildbotInfo)||!buildbot[fieldName]){return defaultValue;}
+static getField(hist,fieldName,defaultValue){const buildbot=BuildbotInfo.getFromHistogram(hist);if(!(buildbot instanceof tr.v.d.BuildbotInfo)||!buildbot[fieldName]){return defaultValue;}
 return buildbot[fieldName];}}
 BuildbotInfo.NAME='buildbot';tr.v.d.Diagnostic.register(BuildbotInfo,{elementName:'tr-v-ui-buildbot-info-span'});return{BuildbotInfo,};});'use strict';tr.exportTo('tr.v.d',function(){class Generic extends tr.v.d.Diagnostic{constructor(value){super();this.value=value;}
-clone(){let clone=new tr.v.d.CollectedGeneric();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.CollectedGeneric();clone.addDiagnostic(this);return clone;}
 asDictInto_(d){d.value=this.value;}
 static fromDict(d){return new Generic(d.value);}}
 tr.v.d.Diagnostic.register(Generic,{elementName:'tr-v-ui-generic-diagnostic-span'});return{Generic,};});'use strict';tr.exportTo('tr.v.d',function(){class CollectedGeneric extends tr.v.d.Generic{constructor(){super([]);}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof tr.v.d.Generic;}
 addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof CollectedGeneric){this.value.push(...otherDiagnostic.value);}else{this.value.push(otherDiagnostic.value);}}}
 tr.v.d.Diagnostic.register(CollectedGeneric,{elementName:'tr-v-ui-generic-diagnostic-span'});return{CollectedGeneric,};});'use strict';tr.exportTo('tr.v.d',function(){class CollectedRelatedEventSet extends tr.v.d.Diagnostic{constructor(){super();this.eventSetsByCanonicalUrl_=new Map();}
-asDictInto_(d){d.events={};for(let[canonicalUrl,eventSet]of this){d.events[canonicalUrl]=[];for(let event of eventSet){d.events[canonicalUrl].push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}}
-static fromDict(d){let result=new CollectedRelatedEventSet();for(let[canonicalUrl,events]of Object.entries(d.events)){result.eventSetsByCanonicalUrl_.set(canonicalUrl,events.map(e=>new tr.v.d.EventRef(e)));}
+asDictInto_(d){d.events={};for(const[canonicalUrl,eventSet]of this){d.events[canonicalUrl]=[];for(const event of eventSet){d.events[canonicalUrl].push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}}
+static fromDict(d){const result=new CollectedRelatedEventSet();for(const[canonicalUrl,events]of Object.entries(d.events)){result.eventSetsByCanonicalUrl_.set(canonicalUrl,events.map(e=>new tr.v.d.EventRef(e)));}
 return result;}
 get size(){return this.eventSetsByCanonicalUrl_.size;}
-get(canonicalUrl){return this.eventSetsByCanonicalUrl_.get(canonicalUrl);}*[Symbol.iterator](){for(let[canonicalUrl,eventSet]of this.eventSetsByCanonicalUrl_){yield[canonicalUrl,eventSet];}}
+get(canonicalUrl){return this.eventSetsByCanonicalUrl_.get(canonicalUrl);}*[Symbol.iterator](){for(const[canonicalUrl,eventSet]of this.eventSetsByCanonicalUrl_){yield[canonicalUrl,eventSet];}}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof tr.v.d.RelatedEventSet||otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet;}
 addEventSetForCanonicalUrl(canonicalUrl,events){let myEventSet=this.eventSetsByCanonicalUrl_.get(canonicalUrl);if(myEventSet===undefined){myEventSet=new Set();this.eventSetsByCanonicalUrl_.set(canonicalUrl,myEventSet);}
-for(let event of events){myEventSet.add(event);}}
-addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet){for(let[canonicalUrl,otherEventSet]of otherDiagnostic){this.addEventSetForCanonicalUrl(canonicalUrl,otherEventSet);}
+for(const event of events){myEventSet.add(event);}}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof tr.v.d.CollectedRelatedEventSet){for(const[canonicalUrl,otherEventSet]of otherDiagnostic){this.addEventSetForCanonicalUrl(canonicalUrl,otherEventSet);}
 return;}
 if(!otherDiagnostic.canonicalUrl)return;this.addEventSetForCanonicalUrl(otherDiagnostic.canonicalUrl,otherDiagnostic);}}
-tr.v.d.Diagnostic.register(CollectedRelatedEventSet,{elementName:'tr-v-ui-collected-related-event-set-span'});return{CollectedRelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){class DeviceInfo extends tr.v.d.Diagnostic{constructor(opt_info){super();let info=opt_info||{};this.chromeVersion_=info.chromeVersion||'';this.osName_=info.osName||'';this.osVersion_=info.osVersion||'';this.gpuInfo_=info.gpuInfo||undefined;this.arch_=info.arch||undefined;this.ram_=info.ram||0;}
+tr.v.d.Diagnostic.register(CollectedRelatedEventSet,{elementName:'tr-v-ui-collected-related-event-set-span'});return{CollectedRelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){class DeviceInfo extends tr.v.d.Diagnostic{constructor(opt_info){super();const info=opt_info||{};this.chromeVersion_=info.chromeVersion||'';this.osName_=info.osName||'';this.osVersion_=info.osVersion||'';this.gpuInfo_=info.gpuInfo||undefined;this.arch_=info.arch||undefined;this.ram_=info.ram||0;}
 addToHistogram(hist){hist.diagnostics.set(DeviceInfo.NAME,this);}
 static getFromHistogram(hist){return hist.diagnostics.get(DeviceInfo.NAME);}
-clone(){let clone=new tr.v.d.MergedDeviceInfo();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.MergedDeviceInfo();clone.addDiagnostic(this);return clone;}
 asDictInto_(d){d.chromeVersion=this.chromeVersion;d.osName=this.osName;d.osVersion=this.osVersion;d.gpuInfo=this.gpuInfo;d.arch=this.arch;d.ram=this.ram;}
 static fromDict(d){return new DeviceInfo(d);}
 get chromeVersion(){return this.chromeVersion_;}
@@ -6569,7 +6889,7 @@
 asDictInto_(d){d.groupingPath=this.groupingPath_;}
 static fromDict(d){return new GroupingPath(d.groupingPath);}}
 GroupingPath.NAME='grouping path';tr.v.d.Diagnostic.register(GroupingPath);return{GroupingPath,};});'use strict';tr.exportTo('tr.v.d',function(){class MergedBuildbotInfo extends tr.v.d.Diagnostic{constructor(info){super();this.displayMasterNames_=new Set();this.displayBotNames_=new Set();this.buildbotMasterNames_=new Set();this.buildbotNames_=new Set();this.buildNumbers_=new Set();this.logUris_=new Set();}
-clone(){let clone=new MergedBuildbotInfo();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new MergedBuildbotInfo();clone.addDiagnostic(this);return clone;}
 addToHistogram(hist){hist.diagnostics.set(tr.v.d.BuildbotInfo.NAME,this);}
 equals(other){if(!(other instanceof MergedBuildbotInfo))return false;if(!tr.b.setsEqual(this.displayMasterNames,other.displayMasterNames)){return false;}
 if(!tr.b.setsEqual(this.displayBotNames,other.displayBotNames)){return false;}
@@ -6577,12 +6897,12 @@
 if(!tr.b.setsEqual(this.buildbotNames,other.buildbotNames)){return false;}
 if(!tr.b.setsEqual(this.buildNumbers,other.buildNumbers))return false;if(!tr.b.setsEqual(this.logUris,other.logUris))return false;return true;}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof MergedBuildbotInfo||otherDiagnostic instanceof tr.v.d.BuildbotInfo;}
-addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof MergedBuildbotInfo){for(let name of otherDiagnostic.displayMasterNames){this.displayMasterNames.add(name);}
-for(let name of otherDiagnostic.displayBotNames){this.displayBotNames.add(name);}
-for(let name of otherDiagnostic.buildbotMasterNames){this.buildbotMasterNames.add(name);}
-for(let name of otherDiagnostic.buildbotNames){this.buildbotNames.add(name);}
-for(let name of otherDiagnostic.buildNumbers){this.buildNumbers.add(name);}
-for(let name of otherDiagnostic.logUris){this.logUris.add(name);}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof MergedBuildbotInfo){for(const name of otherDiagnostic.displayMasterNames){this.displayMasterNames.add(name);}
+for(const name of otherDiagnostic.displayBotNames){this.displayBotNames.add(name);}
+for(const name of otherDiagnostic.buildbotMasterNames){this.buildbotMasterNames.add(name);}
+for(const name of otherDiagnostic.buildbotNames){this.buildbotNames.add(name);}
+for(const name of otherDiagnostic.buildNumbers){this.buildNumbers.add(name);}
+for(const name of otherDiagnostic.logUris){this.logUris.add(name);}
 return this;}
 if(otherDiagnostic.displayMasterName){this.displayMasterNames.add(otherDiagnostic.displayMasterName);}
 if(otherDiagnostic.displayBotName){this.displayBotNames.add(otherDiagnostic.displayBotName);}
@@ -6598,20 +6918,20 @@
 get buildbotNames(){return this.buildbotNames_;}
 get buildNumbers(){return this.buildNumbers_;}
 get logUris(){return this.logUris_;}
-static fromDict(d){let info=new MergedBuildbotInfo();for(let name of d.displayMasterNames){info.displayMasterNames.add(name);}
-for(let name of d.displayBotNames){info.displayBotNames.add(name);}
-for(let name of d.buildbotMasterNames){info.buildbotMasterNames.add(name);}
-for(let name of d.buildbotNames){info.buildbotNames.add(name);}
-for(let name of d.buildNumbers){info.buildNumbers.add(name);}
-for(let name of d.logUris){info.logUris.add(name);}
+static fromDict(d){const info=new MergedBuildbotInfo();for(const name of d.displayMasterNames){info.displayMasterNames.add(name);}
+for(const name of d.displayBotNames){info.displayBotNames.add(name);}
+for(const name of d.buildbotMasterNames){info.buildbotMasterNames.add(name);}
+for(const name of d.buildbotNames){info.buildbotNames.add(name);}
+for(const name of d.buildNumbers){info.buildNumbers.add(name);}
+for(const name of d.logUris){info.logUris.add(name);}
 return info;}}
 tr.v.d.Diagnostic.register(MergedBuildbotInfo,{elementName:'tr-v-ui-merged-buildbot-info-span'});return{MergedBuildbotInfo,};});'use strict';tr.exportTo('tr.v.d',function(){class MergedDeviceInfo extends tr.v.d.Diagnostic{constructor(){super();this.chromeVersions_=new Set();this.osNames_=new Set();this.osVersions_=new Set();}
-clone(){let clone=new tr.v.d.MergedDeviceInfo();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.MergedDeviceInfo();clone.addDiagnostic(this);return clone;}
 addToHistogram(hist){hist.diagnostics.set(tr.v.d.DeviceInfo.NAME,this);}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof MergedDeviceInfo||otherDiagnostic instanceof tr.v.d.DeviceInfo;}
-addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof MergedDeviceInfo){for(let name of otherDiagnostic.osNames){this.osNames.add(name);}
-for(let name of otherDiagnostic.osVersions){this.osVersions.add(name);}
-for(let name of otherDiagnostic.chromeVersions){this.chromeVersions.add(name);}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof MergedDeviceInfo){for(const name of otherDiagnostic.osNames){this.osNames.add(name);}
+for(const name of otherDiagnostic.osVersions){this.osVersions.add(name);}
+for(const name of otherDiagnostic.chromeVersions){this.chromeVersions.add(name);}
 return this;}
 if(otherDiagnostic.osName){this.osNames.add(otherDiagnostic.osName);}
 if(otherDiagnostic.osVersion){this.osVersions.add(otherDiagnostic.osVersion);}
@@ -6620,25 +6940,25 @@
 equals(other){if(!(other instanceof MergedDeviceInfo))return false;if(!tr.b.setsEqual(this.chromeVersions,other.chromeVersions)){return false;}
 if(!tr.b.setsEqual(this.osVersions,other.osVersions))return false;if(!tr.b.setsEqual(this.osNames,other.osNames))return false;return true;}
 asDictInto_(d){d.chromeVersions=Array.from(this.chromeVersions);d.osNames=Array.from(this.osNames);d.osVersions=Array.from(this.osVersions);}
-static fromDict(d){let info=new MergedDeviceInfo();for(let chromeVersion of d.chromeVersions){info.chromeVersions.add(chromeVersion);}
-for(let osName of d.osNames){info.osNames.add(osName);}
-for(let osVersion of d.osVersions){info.osVersions.add(osVersion);}
+static fromDict(d){const info=new MergedDeviceInfo();for(const chromeVersion of d.chromeVersions){info.chromeVersions.add(chromeVersion);}
+for(const osName of d.osNames){info.osNames.add(osName);}
+for(const osVersion of d.osVersions){info.osVersions.add(osVersion);}
 return info;}
 get chromeVersions(){return this.chromeVersions_;}
 get osNames(){return this.osNames_;}
 get osVersions(){return this.osVersions_;}}
-tr.v.d.Diagnostic.register(MergedDeviceInfo,{elementName:'tr-v-ui-merged-device-info-span'});return{MergedDeviceInfo,};});'use strict';tr.exportTo('tr.v.d',function(){const REPO_NAMES=['chromium','v8','catapult','angle','skia','webrtc'];class MergedRevisionInfo extends tr.v.d.Diagnostic{constructor(opt_info){super();let info=opt_info||{};this.chromiumCommitPositions_=new Set(info.chromiumCommitPositions||[]);this.v8CommitPositions_=new Set(info.v8CommitPositions||[]);this.chromium_=info.chromium||[];this.v8_=info.v8||[];this.catapult_=info.catapult||[];this.angle_=info.angle||[];this.skia_=info.skia||[];this.webrtc_=info.webrtc||[];}
-clone(){let clone=new MergedRevisionInfo();clone.addDiagnostic(this);return clone;}
+tr.v.d.Diagnostic.register(MergedDeviceInfo,{elementName:'tr-v-ui-merged-device-info-span'});return{MergedDeviceInfo,};});'use strict';tr.exportTo('tr.v.d',function(){const REPO_NAMES=['chromium','v8','catapult','angle','skia','webrtc'];class MergedRevisionInfo extends tr.v.d.Diagnostic{constructor(opt_info){super();const info=opt_info||{};this.chromiumCommitPositions_=new Set(info.chromiumCommitPositions||[]);this.v8CommitPositions_=new Set(info.v8CommitPositions||[]);this.chromium_=info.chromium||[];this.v8_=info.v8||[];this.catapult_=info.catapult||[];this.angle_=info.angle||[];this.skia_=info.skia||[];this.webrtc_=info.webrtc||[];}
+clone(){const clone=new MergedRevisionInfo();clone.addDiagnostic(this);return clone;}
 addToHistogram(hist){hist.diagnostics.set(tr.v.d.RevisionInfo.NAME,this);}
 canAddDiagnostic(otherDiagnostic,name,parentHist,otherParentHist){return otherDiagnostic instanceof tr.v.d.RevisionInfo||otherDiagnostic instanceof MergedRevisionInfo;}
-addDiagnostic(otherDiagnostic,name,parentHist,otherParentHist){if(otherDiagnostic instanceof MergedRevisionInfo){for(let pos of otherDiagnostic.chromiumCommitPositions){this.chromiumCommitPositions.add(pos);}
-for(let pos of otherDiagnostic.v8CommitPositions){this.v8CommitPositions.add(pos);}
-for(let repo of REPO_NAMES){for(let otherRevs of otherDiagnostic[repo]){let found=false;for(let revs of this[repo]){if(otherRevs[0]===revs[0]&&otherRevs[1]===revs[1]){found=true;break;}}
+addDiagnostic(otherDiagnostic,name,parentHist,otherParentHist){if(otherDiagnostic instanceof MergedRevisionInfo){for(const pos of otherDiagnostic.chromiumCommitPositions){this.chromiumCommitPositions.add(pos);}
+for(const pos of otherDiagnostic.v8CommitPositions){this.v8CommitPositions.add(pos);}
+for(const repo of REPO_NAMES){for(const otherRevs of otherDiagnostic[repo]){let found=false;for(const revs of this[repo]){if(otherRevs[0]===revs[0]&&otherRevs[1]===revs[1]){found=true;break;}}
 if(!found){this[repo].push(otherRevs);}}}
 return this;}
 if(otherDiagnostic.chromiumCommitPosition!==undefined){this.chromiumCommitPositions.add(otherDiagnostic.chromiumCommitPosition);}
 if(otherDiagnostic.v8CommitPosition!==undefined){this.v8CommitPositions.add(otherDiagnostic.v8CommitPosition);}
-for(let repo of REPO_NAMES){let otherRevs=otherDiagnostic[repo];let found=false;for(let revs of this[repo]){if(otherRevs[0]===revs[0]&&otherRevs[1]===revs[1]){found=true;break;}}
+for(const repo of REPO_NAMES){const otherRevs=otherDiagnostic[repo];let found=false;for(const revs of this[repo]){if(otherRevs[0]===revs[0]&&otherRevs[1]===revs[1]){found=true;break;}}
 if(!found){this[repo].push(otherRevs);}}
 return this;}
 asDictInto_(d){d.chromiumCommitPositions=this.chromiumCommitPositions;d.v8CommitPositions=this.v8CommitPositions;d.chromium=this.chromium;d.v8=this.v8;d.catapult=this.catapult;d.angle=this.angle;d.skia=this.skia;d.webrtc=this.webrtc;}
@@ -6652,7 +6972,7 @@
 get skia(){return this.skia_;}
 get webrtc(){return this.webrtc_;}}
 tr.v.d.Diagnostic.register(MergedRevisionInfo,{elementName:'tr-v-ui-merged-revision-info-span'});return{MergedRevisionInfo,};});'use strict';tr.exportTo('tr.v.d',function(){class MergedTelemetryInfo extends tr.v.d.Diagnostic{constructor(){super();this.benchmarkNames_=new Set();this.benchmarkStartsMs_=new Set();this.labels_=new Set();this.legacyTIRLabels_=new Set();this.storyDisplayNames_=new Set();this.storyGroupingKeys_=new Map();this.storysetRepeatCounters_=new Set();}
-clone(){let clone=new tr.v.d.MergedTelemetryInfo();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.MergedTelemetryInfo();clone.addDiagnostic(this);return clone;}
 addToHistogram(hist){hist.diagnostics.set(tr.v.d.TelemetryInfo.NAME,this);}
 equals(other){if(!(other instanceof MergedTelemetryInfo))return false;if(!tr.b.setsEqual(this.benchmarkNames,other.benchmarkNames)){return false;}
 if(!tr.b.setsEqual(this.labels,other.labels))return false;if(!tr.b.setsEqual(this.storyDisplayNames,other.storyDisplayNames)){return false;}
@@ -6660,38 +6980,38 @@
 if(!tr.b.setsEqual(this.storysetRepeatCounters,other.storysetRepeatCounters)){return false;}
 if(!tr.b.setsEqual(this.benchmarkStartsMs,other.benchmarkStartsMs)){return false;}
 if(!tr.b.setsEqual(new Set(this.storyGroupingKeys.keys()),new Set(other.storyGroupingKeys.keys()))){return false;}
-for(let[k,vs]of this.storyGroupingKeys){if(!tr.b.setsEqual(vs,other.storyGroupingKeys.get(k))){return false;}}
+for(const[k,vs]of this.storyGroupingKeys){if(!tr.b.setsEqual(vs,other.storyGroupingKeys.get(k))){return false;}}
 return true;}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof MergedTelemetryInfo||otherDiagnostic instanceof tr.v.d.TelemetryInfo;}
-addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof MergedTelemetryInfo){for(let name of otherDiagnostic.benchmarkNames){this.benchmarkNames.add(name);}
-for(let t of otherDiagnostic.benchmarkStartsMs){this.benchmarkStartsMs.add(t);}
-for(let name of otherDiagnostic.labels){this.labels.add(name);}
-for(let name of otherDiagnostic.legacyTIRLabels){this.legacyTIRLabels.add(name);}
-for(let name of otherDiagnostic.storyDisplayNames){this.storyDisplayNames.add(name);}
-for(let name of otherDiagnostic.storysetRepeatCounters){this.storysetRepeatCounters.add(name);}
-for(let[name,value]of otherDiagnostic.storyGroupingKeys){if(this.storyGroupingKeys.has(name)){for(let subValue of value){this.storyGroupingKeys.get(name).add(subValue);}}else{this.storyGroupingKeys.set(name,new Set(value));}}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof MergedTelemetryInfo){for(const name of otherDiagnostic.benchmarkNames){this.benchmarkNames.add(name);}
+for(const t of otherDiagnostic.benchmarkStartsMs){this.benchmarkStartsMs.add(t);}
+for(const name of otherDiagnostic.labels){this.labels.add(name);}
+for(const name of otherDiagnostic.legacyTIRLabels){this.legacyTIRLabels.add(name);}
+for(const name of otherDiagnostic.storyDisplayNames){this.storyDisplayNames.add(name);}
+for(const name of otherDiagnostic.storysetRepeatCounters){this.storysetRepeatCounters.add(name);}
+for(const[name,value]of otherDiagnostic.storyGroupingKeys){if(this.storyGroupingKeys.has(name)){for(const subValue of value){this.storyGroupingKeys.get(name).add(subValue);}}else{this.storyGroupingKeys.set(name,new Set(value));}}
 return;}
 if(otherDiagnostic.benchmarkName){this.benchmarkNames.add(otherDiagnostic.benchmarkName);}
 if(otherDiagnostic.benchmarkStart!==undefined){this.benchmarkStartsMs.add(otherDiagnostic.benchmarkStart.getTime());}
 if(otherDiagnostic.label){this.labels.add(otherDiagnostic.label);}
 if(otherDiagnostic.legacyTIRLabel){this.legacyTIRLabels.add(otherDiagnostic.legacyTIRLabel);}
 if(otherDiagnostic.storyDisplayName){this.storyDisplayNames.add(otherDiagnostic.storyDisplayName);}
-for(let[name,value]of otherDiagnostic.storyGroupingKeys){if(this.storyGroupingKeys.has(name)){this.storyGroupingKeys.get(name).add(value);}else{this.storyGroupingKeys.set(name,new Set([value]));}}
+for(const[name,value]of otherDiagnostic.storyGroupingKeys){if(this.storyGroupingKeys.has(name)){this.storyGroupingKeys.get(name).add(value);}else{this.storyGroupingKeys.set(name,new Set([value]));}}
 if(otherDiagnostic.storysetRepeatCounter!==undefined){this.storysetRepeatCounters.add(otherDiagnostic.storysetRepeatCounter);}}
 asDictInto_(d){if(this.benchmarkNames.size){d.benchmarkNames=Array.from(this.benchmarkNames);}
 if(this.benchmarkStartsMs.size){d.benchmarkStartsMs=Array.from(this.benchmarkStartsMs);}
 if(this.labels.size){d.labels=Array.from(this.labels);}
 if(this.legacyTIRLabels.size){d.legacyTIRLabels=this.legacyTIRLabels;}
 if(this.storyDisplayNames.size){d.storyDisplayNames=Array.from(this.storyDisplayNames);}
-if(this.storyGroupingKeys.size){d.storyGroupingKeys={};for(let[name,values]of this.storyGroupingKeys){d.storyGroupingKeys[name]=Array.from(values);}}
+if(this.storyGroupingKeys.size){d.storyGroupingKeys={};for(const[name,values]of this.storyGroupingKeys){d.storyGroupingKeys[name]=Array.from(values);}}
 if(this.storysetRepeatCounters.size){d.storysetRepeatCounters=Array.from(this.storysetRepeatCounters);}}
-static fromDict(d){let info=new MergedTelemetryInfo();for(let n of d.benchmarkNames||[]){info.benchmarkNames_.add(n);}
-for(let n of d.benchmarkStartsMs||[]){info.benchmarkStartsMs_.add(n);}
-for(let n of d.labels||[]){info.labels_.add(n);}
-for(let n of d.legacyTIRLabels||[]){info.legacyTIRLabels_.add(n);}
-for(let n of d.storyDisplayNames||[]){info.storyDisplayNames_.add(n);}
-for(let[name,values]of Object.entries(d.storyGroupingKeys||{})){info.storyGroupingKeys_.set(name,new Set(values));}
-for(let n of d.storysetRepeatCounters||[]){info.storysetRepeatCounters_.add(n);}
+static fromDict(d){const info=new MergedTelemetryInfo();for(const n of d.benchmarkNames||[]){info.benchmarkNames_.add(n);}
+for(const n of d.benchmarkStartsMs||[]){info.benchmarkStartsMs_.add(n);}
+for(const n of d.labels||[]){info.labels_.add(n);}
+for(const n of d.legacyTIRLabels||[]){info.legacyTIRLabels_.add(n);}
+for(const n of d.storyDisplayNames||[]){info.storyDisplayNames_.add(n);}
+for(const[name,values]of Object.entries(d.storyGroupingKeys||{})){info.storyGroupingKeys_.set(name,new Set(values));}
+for(const n of d.storysetRepeatCounters||[]){info.storysetRepeatCounters_.add(n);}
 return info;}
 get displayLabel(){if(this.labels.size){return Array.from(this.labels).join('\n');}
 return Array.from(this.benchmarkNames).concat(this.benchmarkStartStrings).join('\n');}
@@ -6703,67 +7023,72 @@
 get storysetRepeatCounters(){return this.storysetRepeatCounters_;}
 get storysetRepeatCounterLabel(){return'storyset repeat '+Array.from(this.storysetRepeatCounters).join(',');}
 get benchmarkStartsMs(){return this.benchmarkStartsMs_;}
-get benchmarkStarts(){let startsMs=Array.from(this.benchmarkStartsMs);startsMs.sort((x,y)=>x-y);return startsMs.map(t=>new Date(t));}
+get benchmarkStarts(){const startsMs=Array.from(this.benchmarkStartsMs);startsMs.sort((x,y)=>x-y);return startsMs.map(t=>new Date(t));}
 get benchmarkStartStrings(){return this.benchmarkStarts.map(tr.b.formatDate);}
-static getField(hist,fieldName,defaultValue){let telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.MergedTelemetryInfo)||!telemetry[fieldName]){return defaultValue;}
+static getField(hist,fieldName,defaultValue){const telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.MergedTelemetryInfo)||!telemetry[fieldName]){return defaultValue;}
 return telemetry[fieldName];}
-static getStoryGroupingKeyLabel(hist,storyGroupingKey){let telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.MergedTelemetryInfo)){return storyGroupingKey+': undefined';}
+static getStoryGroupingKeyLabel(hist,storyGroupingKey){const telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.MergedTelemetryInfo)){return storyGroupingKey+': undefined';}
 return storyGroupingKey+': '+
 telemetry.storyGroupingKeys[storyGroupingKey];}
 static makeStoryGroupingKeyLabelGetter(storyGroupingKey){return v=>MergedTelemetryInfo.getStoryGroupingKeyLabel(v,storyGroupingKey);}}
-tr.v.d.Diagnostic.register(MergedTelemetryInfo,{elementName:'tr-v-ui-merged-telemetry-info-span'});return{MergedTelemetryInfo,};});'use strict';tr.exportTo('tr.v.d',function(){class EventRef{constructor(event){this.stableId=event.stableId;this.title=event.title;this.start=event.start;this.duration=event.duration;this.end=this.start+this.duration;this.guid=tr.b.GUID.allocateSimple();}}
-return{EventRef,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedEventSet extends tr.v.d.Diagnostic{constructor(opt_events){super();this.eventsByStableId_=new Map();this.canonicalUrl_=undefined;if(opt_events){if(opt_events instanceof tr.model.EventSet||opt_events instanceof Array){for(let event of opt_events){this.add(event);}}else{this.add(opt_events);}}}
-clone(){let clone=new tr.v.d.CollectedRelatedEventSet();clone.addDiagnostic(this);return clone;}
+tr.v.d.Diagnostic.register(MergedTelemetryInfo,{elementName:'tr-v-ui-merged-telemetry-info-span'});return{MergedTelemetryInfo,};});'use strict';tr.exportTo('tr.v.d.',function(){class Ownership extends tr.v.d.Diagnostic{constructor(emails,component){super();this.emails=emails||[];if(typeof(component)==='string'){this.component=component;}}
+asDictInto_(d){if(this.component!==undefined){d.component=this.component;}
+d.emails=this.emails;}
+clone(){return new Ownership(this.emails,this.component);}
+static fromDict(d){return new Ownership(d.emails,d.component);}}
+tr.v.d.Diagnostic.register(Ownership);return{Ownership,};});'use strict';tr.exportTo('tr.v.d',function(){class EventRef{constructor(event){this.stableId=event.stableId;this.title=event.title;this.start=event.start;this.duration=event.duration;this.end=this.start+this.duration;this.guid=tr.b.GUID.allocateSimple();}}
+return{EventRef,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedEventSet extends tr.v.d.Diagnostic{constructor(opt_events){super();this.eventsByStableId_=new Map();this.canonicalUrl_=undefined;if(opt_events){if(opt_events instanceof tr.model.EventSet||opt_events instanceof Array){for(const event of opt_events){this.add(event);}}else{this.add(opt_events);}}}
+clone(){const clone=new tr.v.d.CollectedRelatedEventSet();clone.addDiagnostic(this);return clone;}
 add(event){this.eventsByStableId_.set(event.stableId,event);}
 has(event){return this.eventsByStableId_.has(event.stableId);}
-get length(){return this.eventsByStableId_.size;}*[Symbol.iterator](){for(let event of this.eventsByStableId_.values()){yield event;}}
+get length(){return this.eventsByStableId_.size;}*[Symbol.iterator](){for(const event of this.eventsByStableId_.values()){yield event;}}
 get canonicalUrl(){return this.canonicalUrl_;}
-resolve(model,opt_required){for(let[stableId,event]of this.eventsByStableId_){if(!(event instanceof tr.v.d.EventRef))continue;event=model.getEventByStableId(stableId);if(event instanceof tr.model.Event){this.eventsByStableId_.set(stableId,event);}else if(opt_required){throw new Error('Unable to find Event '+stableId);}}}
-asDictInto_(d){d.events=[];for(let event of this){d.events.push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}
+resolve(model,opt_required){for(const[stableId,value]of this.eventsByStableId_){if(!(value instanceof tr.v.d.EventRef))continue;const event=model.getEventByStableId(stableId);if(event instanceof tr.model.Event){this.eventsByStableId_.set(stableId,event);}else if(opt_required){throw new Error('Unable to find Event '+stableId);}}}
+asDictInto_(d){d.events=[];for(const event of this){d.events.push({stableId:event.stableId,title:event.title,start:event.start,duration:event.duration});}}
 static fromDict(d){return new RelatedEventSet(d.events.map(event=>new tr.v.d.EventRef(event)));}}
 tr.v.d.Diagnostic.register(RelatedEventSet,{elementName:'tr-v-ui-related-event-set-span'});return{RelatedEventSet,};});'use strict';tr.exportTo('tr.v.d',function(){function HistogramRef(guid){this.guid=guid;}
 return{HistogramRef};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedHistogramMap extends tr.v.d.Diagnostic{constructor(){super();this.histogramsByName_=new Map();}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof RelatedHistogramMap;}
 addDiagnostic(otherDiagnostic){}
-mergeRelationships(otherDiagnostic,parentHist,otherParentHist){let parentGroupingPath=tr.v.d.GroupingPath.getFromHistogram(parentHist);for(let[name,otherRelatedHist]of otherDiagnostic){let mergedTo=otherRelatedHist.diagnostics.get(tr.v.d.MERGED_TO_DIAGNOSTIC_KEY);if(mergedTo===undefined)continue;for(let relatedHist of mergedTo){let relatedGroupingPath=tr.v.d.GroupingPath.getFromHistogram(relatedHist);if(relatedGroupingPath===undefined)continue;if(!parentGroupingPath.equals(relatedGroupingPath))continue;this.set(name,relatedHist);}}}
+mergeRelationships(otherDiagnostic,parentHist,otherParentHist){const parentGroupingPath=tr.v.d.GroupingPath.getFromHistogram(parentHist);for(const[name,otherRelatedHist]of otherDiagnostic){const mergedTo=otherRelatedHist.diagnostics.get(tr.v.d.MERGED_TO_DIAGNOSTIC_KEY);if(mergedTo===undefined)continue;for(const relatedHist of mergedTo){const relatedGroupingPath=tr.v.d.GroupingPath.getFromHistogram(relatedHist);if(relatedGroupingPath===undefined)continue;if(!parentGroupingPath.equals(relatedGroupingPath))continue;this.set(name,relatedHist);}}}
 get(name){return this.histogramsByName_.get(name);}
 set(name,hist){if(!(hist instanceof tr.v.Histogram)&&!(hist instanceof tr.v.d.HistogramRef)){throw new Error('Must be instanceof Histogram or HistogramRef: '+
 hist);}
 this.histogramsByName_.set(name,hist);}
 add(hist){this.set(hist.name,hist);}
-get length(){return this.histogramsByName_.size;}*[Symbol.iterator](){for(let pair of this.histogramsByName_){yield pair;}}
-resolve(histograms,opt_required){for(let[name,hist]of this){if(!(hist instanceof tr.v.d.HistogramRef))continue;let guid=hist.guid;hist=histograms.lookupHistogram(guid);if(hist instanceof tr.v.Histogram){this.histogramsByName_.set(name,hist);}else if(opt_required){throw new Error('Unable to find Histogram '+guid);}}}
-asDictInto_(d){d.values={};for(let[name,hist]of this){d.values[name]=hist.guid;}}
-static fromDict(d){let map=new RelatedHistogramMap();for(let[name,guid]of Object.entries(d.values)){map.set(name,new tr.v.d.HistogramRef(guid));}
+get length(){return this.histogramsByName_.size;}*[Symbol.iterator](){for(const pair of this.histogramsByName_){yield pair;}}
+resolve(histograms,opt_required){for(const[name,value]of this){if(!(value instanceof tr.v.d.HistogramRef))continue;const guid=value.guid;const hist=histograms.lookupHistogram(guid);if(hist instanceof tr.v.Histogram){this.histogramsByName_.set(name,hist);}else if(opt_required){throw new Error('Unable to find Histogram '+guid);}}}
+asDictInto_(d){d.values={};for(const[name,hist]of this){d.values[name]=hist.guid;}}
+static fromDict(d){const map=new RelatedHistogramMap();for(const[name,guid]of Object.entries(d.values)){map.set(name,new tr.v.d.HistogramRef(guid));}
 return map;}}
 tr.v.d.Diagnostic.register(RelatedHistogramMap,{elementName:'tr-v-ui-related-histogram-map-span'});return{RelatedHistogramMap,};});'use strict';tr.exportTo('tr.v.d',function(){const COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER='ChromeUserFriendlyCategory';class RelatedHistogramBreakdown extends tr.v.d.RelatedHistogramMap{constructor(){super();this.colorScheme=undefined;}
-clone(){let clone=new RelatedHistogramBreakdown();clone.colorScheme=this.colorScheme;return clone;}
+clone(){const clone=new RelatedHistogramBreakdown();clone.colorScheme=this.colorScheme;return clone;}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof RelatedHistogramBreakdown&&otherDiagnostic.colorScheme===this.colorScheme;}
 set(name,hist){if(!(hist instanceof tr.v.d.HistogramRef)){if(!(hist instanceof tr.v.Histogram)){throw new Error('RelatedHistogramBreakdown can only contain Histograms');}
 if((this.length>0)&&(hist.unit!==tr.b.getFirstElement(this)[1].unit)){throw new Error('Units mismatch',tr.b.getFirstElement(this)[1].unit,hist.unit);}}
 tr.v.d.RelatedHistogramMap.prototype.set.call(this,name,hist);}
 asDictInto_(d){tr.v.d.RelatedHistogramMap.prototype.asDictInto_.call(this,d);if(this.colorScheme)d.colorScheme=this.colorScheme;}
-static fromDict(d){let diagnostic=new RelatedHistogramBreakdown();for(let[name,guid]of Object.entries(d.values)){diagnostic.set(name,new tr.v.d.HistogramRef(guid));}
+static fromDict(d){const diagnostic=new RelatedHistogramBreakdown();for(const[name,guid]of Object.entries(d.values)){diagnostic.set(name,new tr.v.d.HistogramRef(guid));}
 if(d.colorScheme)diagnostic.colorScheme=d.colorScheme;return diagnostic;}
-static buildFromEvents(histograms,namePrefix,events,categoryForEvent,unit,opt_sampleForEvent,opt_binBoundaries,opt_this){let sampleForEvent=opt_sampleForEvent||((event)=>event.cpuSelfTime);let diagnostic=new RelatedHistogramBreakdown();for(let event of events){let sample=sampleForEvent.call(opt_this,event);if(sample===undefined)continue;let eventCategory=categoryForEvent.call(opt_this,event);let hist=diagnostic.get(eventCategory);if(hist===undefined){hist=new tr.v.Histogram(namePrefix+eventCategory,unit,opt_binBoundaries);histograms.addHistogram(hist);diagnostic.set(eventCategory,hist);}
+static buildFromEvents(histograms,namePrefix,events,categoryForEvent,unit,opt_sampleForEvent,opt_binBoundaries,opt_this){const sampleForEvent=opt_sampleForEvent||((event)=>event.cpuSelfTime);const diagnostic=new RelatedHistogramBreakdown();for(const event of events){const sample=sampleForEvent.call(opt_this,event);if(sample===undefined)continue;const eventCategory=categoryForEvent.call(opt_this,event);let hist=diagnostic.get(eventCategory);if(hist===undefined){hist=new tr.v.Histogram(namePrefix+eventCategory,unit,opt_binBoundaries);histograms.addHistogram(hist);diagnostic.set(eventCategory,hist);}
 hist.addSample(sample,{relatedEvents:new tr.v.d.RelatedEventSet([event])});}
 return diagnostic;}}
-tr.v.d.Diagnostic.register(RelatedHistogramBreakdown,{elementName:'tr-v-ui-breakdown-span'});return{COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER,RelatedHistogramBreakdown,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedHistogramSet extends tr.v.d.Diagnostic{constructor(opt_histograms){super();this.histogramsByGuid_=new Map();if(opt_histograms){for(let hist of opt_histograms){this.add(hist);}}}
+tr.v.d.Diagnostic.register(RelatedHistogramBreakdown,{elementName:'tr-v-ui-breakdown-span'});return{COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER,RelatedHistogramBreakdown,};});'use strict';tr.exportTo('tr.v.d',function(){class RelatedHistogramSet extends tr.v.d.Diagnostic{constructor(opt_histograms){super();this.histogramsByGuid_=new Map();if(opt_histograms){for(const hist of opt_histograms){this.add(hist);}}}
 canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof RelatedHistogramSet;}
 addDiagnostic(otherDiagnostic){}
-mergeRelationships(otherDiagnostic,parentHist,otherParentHist){let parentGroupingPath=tr.v.d.GroupingPath.getFromHistogram(parentHist);for(let otherRelatedHist of otherDiagnostic){let mergedTo=otherRelatedHist.diagnostics.get(tr.v.d.MERGED_TO_DIAGNOSTIC_KEY);if(mergedTo===undefined)continue;for(let relatedHist of mergedTo){if(this.has(relatedHist))continue;let relatedGroupingPath=tr.v.d.GroupingPath.getFromHistogram(relatedHist);if(relatedGroupingPath===undefined)continue;if(!parentGroupingPath.equals(relatedGroupingPath))continue;this.add(relatedHist);}}}
+mergeRelationships(otherDiagnostic,parentHist,otherParentHist){const parentGroupingPath=tr.v.d.GroupingPath.getFromHistogram(parentHist);for(const otherRelatedHist of otherDiagnostic){const mergedTo=otherRelatedHist.diagnostics.get(tr.v.d.MERGED_TO_DIAGNOSTIC_KEY);if(mergedTo===undefined)continue;for(const relatedHist of mergedTo){if(this.has(relatedHist))continue;const relatedGroupingPath=tr.v.d.GroupingPath.getFromHistogram(relatedHist);if(relatedGroupingPath===undefined)continue;if(!parentGroupingPath.equals(relatedGroupingPath))continue;this.add(relatedHist);}}}
 add(hist){if(!(hist instanceof tr.v.Histogram)&&!(hist instanceof tr.v.d.HistogramRef)){throw new Error('Must be instanceof Histogram or HistogramRef: '+
 hist);}
 if(this.histogramsByGuid_.has(hist.guid)){throw new Error('Tried to add same hist twice');}
 this.histogramsByGuid_.set(hist.guid,hist);}
 has(hist){return this.histogramsByGuid_.has(hist.guid);}
-get length(){return this.histogramsByGuid_.size;}*[Symbol.iterator](){for(let[guid,hist]of this.histogramsByGuid_){yield hist;}}
-resolve(histograms,opt_required){for(let[guid,hist]of this.histogramsByGuid_){if(!(hist instanceof tr.v.d.HistogramRef))continue;hist=histograms.lookupHistogram(guid);if(hist instanceof tr.v.Histogram){this.histogramsByGuid_.set(guid,hist);}else if(opt_required){throw new Error('Unable to find Histogram '+guid);}}}
-asDictInto_(d){d.guids=[];for(let hist of this){d.guids.push(hist.guid);}}
+get length(){return this.histogramsByGuid_.size;}*[Symbol.iterator](){for(const[guid,hist]of this.histogramsByGuid_){yield hist;}}
+resolve(histograms,opt_required){for(const[guid,value]of this.histogramsByGuid_){if(!(value instanceof tr.v.d.HistogramRef))continue;const hist=histograms.lookupHistogram(guid);if(hist instanceof tr.v.Histogram){this.histogramsByGuid_.set(guid,hist);}else if(opt_required){throw new Error('Unable to find Histogram '+guid);}}}
+asDictInto_(d){d.guids=[];for(const hist of this){d.guids.push(hist.guid);}}
 static fromDict(d){return new RelatedHistogramSet(d.guids.map(guid=>new tr.v.d.HistogramRef(guid)));}}
 tr.v.d.Diagnostic.register(RelatedHistogramSet,{elementName:'tr-v-ui-related-histogram-set-span'});return{RelatedHistogramSet,};});'use strict';tr.exportTo('tr.v.d',function(){class RevisionInfo extends tr.v.d.Diagnostic{constructor(info){super();this.chromiumCommitPosition_=info.chromiumCommitPosition||undefined;this.v8CommitPosition_=info.v8CommitPosition||undefined;this.chromium_=info.chromium||[];this.v8_=info.v8||[];this.catapult_=info.catapult||[];this.angle_=info.angle||[];this.skia_=info.skia||[];this.webrtc_=info.webrtc||[];}
 addToHistogram(hist){hist.diagnostics.set(RevisionInfo.NAME,this);}
-clone(){let clone=new tr.v.d.MergedRevisionInfo();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.MergedRevisionInfo();clone.addDiagnostic(this);return clone;}
 asDictInto_(d){d.chromiumCommitPosition=this.chromiumCommitPosition;d.v8CommitPosition=this.v8CommitPosition;d.chromium=this.chromium;d.v8=this.v8;d.catapult=this.catapult;d.angle=this.angle;d.skia=this.skia;d.webrtc=this.webrtc;}
 static fromDict(d){return new RevisionInfo(d);}
 get chromiumCommitPosition(){return this.chromiumCommitPosition_;}
@@ -6779,22 +7104,38 @@
 clone(){return new Scalar(this.value);}
 asDictInto_(d){d.value=this.value.asDict();}
 static fromDict(d){return new Scalar(tr.b.Scalar.fromDict(d.value));}}
-tr.v.d.Diagnostic.register(Scalar,{elementName:'tr-v-ui-scalar-diagnostic-span'});return{Scalar,};});'use strict';tr.exportTo('tr.v.d',function(){class TelemetryInfo extends tr.v.d.Diagnostic{constructor(opt_info){super();this.benchmarkName_='';this.benchmarkStart_=undefined;this.label_='';this.legacyTIRLabel_='';this.storyDisplayName_='';this.storyGroupingKeys_=new Map();this.storysetRepeatCounter_=undefined;this.canonicalUrl_='';if(opt_info){this.addInfo(opt_info);}}
-clone(){let clone=new tr.v.d.MergedTelemetryInfo();clone.addDiagnostic(this);return clone;}
+tr.v.d.Diagnostic.register(Scalar,{elementName:'tr-v-ui-scalar-diagnostic-span'});return{Scalar,};});'use strict';tr.exportTo('tr.v.d',function(){class TagMap extends tr.v.d.Diagnostic{constructor(opt_info){super();this.tagsToStoryDisplayNames_=new Map();if(opt_info){for(const[tag,storyDisplayNames]of Object.entries(opt_info.tagsToStoryDisplayNames||{})){this.tagsToStoryDisplayNames.set(tag,new Set(storyDisplayNames));}}}
+clone(){const clone=new TagMap();clone.addDiagnostic(this);return clone;}
+addToHistogram(hist){hist.diagnostics.set(tr.v.d.TagMap.NAME,this);}
+equals(other){if(!(other instanceof TagMap))return false;const keys1=new Set(this.tagsToStoryDisplayNames.keys());const keys2=new Set(other.tagsToStoryDisplayNames.keys());if(!tr.b.setsEqual(keys1,keys2)){return false;}
+for(const key of keys1){if(!tr.b.setsEqual(this.tagsToStoryDisplayNames.get(key),other.tagsToStoryDisplayNames.get(key))){return false;}}
+return true;}
+canAddDiagnostic(otherDiagnostic){return otherDiagnostic instanceof TagMap;}
+addDiagnostic(otherDiagnostic){for(const[name,storyDisplayNames]of
+otherDiagnostic.tagsToStoryDisplayNames){if(!this.tagsToStoryDisplayNames.has(name)){this.tagsToStoryDisplayNames.set(name,new Set());}
+for(const t of storyDisplayNames){this.tagsToStoryDisplayNames.get(name).add(t);}}
+return this;}
+asDictInto_(d){d.tagsToStoryDisplayNames={};for(const[name,value]of this.tagsToStoryDisplayNames){d.tagsToStoryDisplayNames[name]=Array.from(value);}}
+get tagsToStoryDisplayNames(){return this.tagsToStoryDisplayNames_;}
+static fromDict(d){const info=new TagMap();for(const[name,values]of
+Object.entries(d.tagsToStoryDisplayNames||{})){info.tagsToStoryDisplayNames.set(name,new Set(values));}
+return info;}}
+TagMap.NAME='tagmap';tr.v.d.Diagnostic.register(TagMap);return{TagMap,};});'use strict';tr.exportTo('tr.v.d',function(){class TelemetryInfo extends tr.v.d.Diagnostic{constructor(opt_info){super();this.benchmarkName_='';this.benchmarkStart_=undefined;this.label_='';this.legacyTIRLabel_='';this.storyDisplayName_='';this.storyGroupingKeys_=new Map();this.storysetRepeatCounter_=undefined;this.canonicalUrl_='';if(opt_info){this.addInfo(opt_info);}}
+clone(){const clone=new tr.v.d.MergedTelemetryInfo();clone.addDiagnostic(this);return clone;}
 addInfo(info){if(info.benchmarkName){this.benchmarkName_=info.benchmarkName;}
 if(info.benchmarkStartMs!==undefined){this.benchmarkStart_=new Date(info.benchmarkStartMs);}
 if(info.label){this.label_=info.label;}
 if(info.storyDisplayName){this.storyDisplayName_=info.storyDisplayName;}
-for(let[name,value]of Object.entries(info.storyGroupingKeys||{})){this.storyGroupingKeys_.set(name,value);}
+for(const[name,value]of Object.entries(info.storyGroupingKeys||{})){this.storyGroupingKeys_.set(name,value);}
 if(info.storysetRepeatCounter!==undefined){this.storysetRepeatCounter_=info.storysetRepeatCounter;}
 if(info.legacyTIRLabel){this.legacyTIRLabel_=info.legacyTIRLabel;}
 if(info.canonicalUrl){this.canonicalUrl_=info.canonicalUrl;}}
 addToHistogram(hist){hist.diagnostics.set(TelemetryInfo.NAME,this);}
 static getFromHistogram(hist){return hist.diagnostics.get(TelemetryInfo.NAME)||hist.diagnostics.get('iteration');}
 asDictInto_(d){d.benchmarkName=this.benchmarkName;if(this.benchmarkStart){d.benchmarkStartMs=this.benchmarkStart.getTime();}
-d.label=this.label;d.storyDisplayName=this.storyDisplayName;if(this.storyGroupingKeys.size>0){d.storyGroupingKeys={};for(let[name,value]of this.storyGroupingKeys){d.storyGroupingKeys[name]=value;}}
+d.label=this.label;d.storyDisplayName=this.storyDisplayName;if(this.storyGroupingKeys.size>0){d.storyGroupingKeys={};for(const[name,value]of this.storyGroupingKeys){d.storyGroupingKeys[name]=value;}}
 d.storysetRepeatCounter=this.storysetRepeatCounter;d.legacyTIRLabel=this.legacyTIRLabel;d.canonicalUrl=this.canonicalUrl;}
-static fromDict(d){let info=new TelemetryInfo();info.addInfo(d);return info;}
+static fromDict(d){const info=new TelemetryInfo();info.addInfo(d);return info;}
 get displayLabel(){if(this.label)return this.label;return this.benchmarkName+'\n'+this.benchmarkStartString;}
 get benchmarkName(){return this.benchmarkName_;}
 get label(){return this.label_;}
@@ -6807,58 +7148,65 @@
 get canonicalUrl(){return this.canonicalUrl_;}
 get benchmarkStart(){return this.benchmarkStart_;}
 get benchmarkStartString(){if(this.benchmarkStart_===undefined)return'';return tr.b.formatDate(this.benchmarkStart);}
-static getField(hist,fieldName,defaultValue){let telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.TelemetryInfo)||!telemetry[fieldName]){return defaultValue;}
+static getField(hist,fieldName,defaultValue){const telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.TelemetryInfo)||!telemetry[fieldName]){return defaultValue;}
 return telemetry[fieldName];}
-static getStoryGroupingKeyLabel(hist,storyGroupingKey){let telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.TelemetryInfo)){return storyGroupingKey+': undefined';}
+static getStoryGroupingKeyLabel(hist,storyGroupingKey){const telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(!(telemetry instanceof tr.v.d.TelemetryInfo)){return storyGroupingKey+': undefined';}
 return storyGroupingKey+': '+
 telemetry.storyGroupingKeys.get(storyGroupingKey);}
 static makeStoryGroupingKeyLabelGetter(storyGroupingKey){return v=>TelemetryInfo.getStoryGroupingKeyLabel(v,storyGroupingKey);}}
 TelemetryInfo.NAME='telemetry';tr.v.d.Diagnostic.register(TelemetryInfo,{elementName:'tr-v-ui-telemetry-info-span'});return{TelemetryInfo,};});'use strict';tr.exportTo('tr.v.d',function(){class UnmergeableDiagnosticSet extends tr.v.d.Diagnostic{constructor(diagnostics){super();this._diagnostics=diagnostics;}
-clone(){let clone=new tr.v.d.UnmergeableDiagnosticSet();clone.addDiagnostic(this);return clone;}
+clone(){const clone=new tr.v.d.UnmergeableDiagnosticSet();clone.addDiagnostic(this);return clone;}
 canAddDiagnostic(otherDiagnostic){return true;}
-addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(let subOtherDiagnostic of otherDiagnostic){let clone=subOtherDiagnostic.clone();this.addDiagnostic(clone);}
+addDiagnostic(otherDiagnostic){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(const subOtherDiagnostic of otherDiagnostic){const clone=subOtherDiagnostic.clone();this.addDiagnostic(clone);}
 return;}
 for(let i=0;i<this._diagnostics.length;++i){if(this._diagnostics[i].canAddDiagnostic(otherDiagnostic)){this._diagnostics[i].addDiagnostic(otherDiagnostic);return;}}
-let clone=otherDiagnostic.clone();this._diagnostics.push(clone);}
-mergeRelationships(otherDiagnostic,parentHist,otherParentHist){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(let subDiagnostic of otherDiagnostic){this.mergeRelationships(subDiagnostic,parentHist,otherParentHist);}
+const clone=otherDiagnostic.clone();this._diagnostics.push(clone);}
+mergeRelationships(otherDiagnostic,parentHist,otherParentHist){if(otherDiagnostic instanceof UnmergeableDiagnosticSet){for(const subDiagnostic of otherDiagnostic){this.mergeRelationships(subDiagnostic,parentHist,otherParentHist);}
 return;}
-for(let subDiagnostic of this){if(!(subDiagnostic instanceof tr.v.d.RelatedHistogramSet)&&!(subDiagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(subDiagnostic instanceof tr.v.d.RelatedHistogramBreakdown)){continue;}
+for(const subDiagnostic of this){if(!(subDiagnostic instanceof tr.v.d.RelatedHistogramSet)&&!(subDiagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(subDiagnostic instanceof tr.v.d.RelatedHistogramBreakdown)){continue;}
 subDiagnostic.mergeRelationships(otherDiagnostic,parentHist,otherParentHist);}}
-get length(){return this._diagnostics.length;}*[Symbol.iterator](){for(let diagnostic of this._diagnostics)yield diagnostic;}
+get length(){return this._diagnostics.length;}*[Symbol.iterator](){for(const diagnostic of this._diagnostics)yield diagnostic;}
 asDictInto_(d){d.diagnostics=this._diagnostics.map(d=>d.asDictOrReference());}
 static fromDict(d){return new UnmergeableDiagnosticSet(d.diagnostics.map(d=>((typeof d==='string')?new tr.v.d.DiagnosticRef(d):tr.v.d.Diagnostic.fromDict(d))));}}
 tr.v.d.Diagnostic.register(UnmergeableDiagnosticSet,{elementName:'tr-v-ui-unmergeable-diagnostic-set-span'});return{UnmergeableDiagnosticSet,};});'use strict';tr.exportTo('tr.v.d',function(){const MERGED_FROM_DIAGNOSTIC_KEY='merged from';const MERGED_TO_DIAGNOSTIC_KEY='merged to';class DiagnosticMap extends Map{set(name,diagnostic){if(typeof(name)!=='string'){throw new Error('name must be string, not '+name);}
 if(!(diagnostic instanceof tr.v.d.Diagnostic)&&!(diagnostic instanceof tr.v.d.DiagnosticRef)){throw new Error('Must be instanceof Diagnostic: '+diagnostic);}
 Map.prototype.set.call(this,name,diagnostic);}
-addDicts(dict){for(var[name,diagnosticDict]of Object.entries(dict)){if(typeof diagnosticDict==='string'){this.set(name,new tr.v.d.DiagnosticRef(diagnosticDict));}else{this.set(name,tr.v.d.Diagnostic.fromDict(diagnosticDict));}}}
-resolveSharedDiagnostics(histograms,opt_required){for(let[name,diagnostic]of this){if(!(diagnostic instanceof tr.v.d.DiagnosticRef)){continue;}
-let guid=diagnostic.guid;diagnostic=histograms.lookupDiagnostic(guid);if(diagnostic instanceof tr.v.d.Diagnostic){this.set(name,diagnostic);}else if(opt_required){throw new Error('Unable to find shared Diagnostic '+guid);}}}
-asDict(){let dict={};for(let[name,diagnostic]of this){dict[name]=diagnostic.asDictOrReference();}
+addDicts(dict){for(const[name,diagnosticDict]of Object.entries(dict)){if(typeof diagnosticDict==='string'){this.set(name,new tr.v.d.DiagnosticRef(diagnosticDict));}else{this.set(name,tr.v.d.Diagnostic.fromDict(diagnosticDict));}}}
+resolveSharedDiagnostics(histograms,opt_required){for(const[name,value]of this){if(!(value instanceof tr.v.d.DiagnosticRef)){continue;}
+const guid=value.guid;const diagnostic=histograms.lookupDiagnostic(guid);if(diagnostic instanceof tr.v.d.Diagnostic){this.set(name,diagnostic);}else if(opt_required){throw new Error('Unable to find shared Diagnostic '+guid);}}}
+asDict(){const dict={};for(const[name,diagnostic]of this){dict[name]=diagnostic.asDictOrReference();}
 return dict;}
-static fromDict(d){let diagnostics=new DiagnosticMap();diagnostics.addDicts(d);return diagnostics;}
-static fromObject(obj){let diagnostics=new DiagnosticMap();for(let[name,diagnostic]of Object.entries(obj)){diagnostics.set(name,diagnostic);}
+static fromDict(d){const diagnostics=new DiagnosticMap();diagnostics.addDicts(d);return diagnostics;}
+static fromObject(obj){const diagnostics=new DiagnosticMap();for(const[name,diagnostic]of Object.entries(obj)){diagnostics.set(name,diagnostic);}
 return diagnostics;}
-addDiagnostics(other){for(let[name,otherDiagnostic]of other){if(name===MERGED_FROM_DIAGNOSTIC_KEY||name===MERGED_TO_DIAGNOSTIC_KEY||name===tr.v.d.GroupingPath){continue;}
-let myDiagnostic=this.get(name);if(myDiagnostic!==undefined&&myDiagnostic.canAddDiagnostic(otherDiagnostic)){myDiagnostic.addDiagnostic(otherDiagnostic);continue;}
-let clone=otherDiagnostic.clone();if(myDiagnostic===undefined){this.set(name,clone);continue;}
+addDiagnostics(other){for(const[name,otherDiagnostic]of other){if(name===MERGED_FROM_DIAGNOSTIC_KEY||name===MERGED_TO_DIAGNOSTIC_KEY||name===tr.v.d.GroupingPath){continue;}
+const myDiagnostic=this.get(name);if(myDiagnostic!==undefined&&myDiagnostic.canAddDiagnostic(otherDiagnostic)){myDiagnostic.addDiagnostic(otherDiagnostic);continue;}
+const clone=otherDiagnostic.clone();if(myDiagnostic===undefined){this.set(name,clone);continue;}
 this.set(name,new tr.v.d.UnmergeableDiagnosticSet([myDiagnostic,clone]));}}
-mergeRelationships(parentHist){for(let[name,diagnostic]of this){if(!(diagnostic instanceof tr.v.d.RelatedHistogramSet)&&!(diagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(diagnostic instanceof tr.v.d.RelatedHistogramBreakdown)&&!(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)){continue;}
-for(let otherHist of this.get(MERGED_FROM_DIAGNOSTIC_KEY)){let otherDiagnostic=otherHist.diagnostics.get(name);if(!(otherDiagnostic instanceof tr.v.d.RelatedHistogramSet)&&!(otherDiagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(otherDiagnostic instanceof tr.v.d.RelatedHistogramBreakdown)&&!(otherDiagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)){continue;}
+mergeRelationships(parentHist){for(const[name,diagnostic]of this){if(!(diagnostic instanceof tr.v.d.RelatedHistogramSet)&&!(diagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(diagnostic instanceof tr.v.d.RelatedHistogramBreakdown)&&!(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)){continue;}
+for(const otherHist of this.get(MERGED_FROM_DIAGNOSTIC_KEY)){const otherDiagnostic=otherHist.diagnostics.get(name);if(!(otherDiagnostic instanceof tr.v.d.RelatedHistogramSet)&&!(otherDiagnostic instanceof tr.v.d.RelatedHistogramMap)&&!(otherDiagnostic instanceof tr.v.d.RelatedHistogramBreakdown)&&!(otherDiagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)){continue;}
 diagnostic.mergeRelationships(otherDiagnostic,parentHist,otherHist);}}}}
-return{DiagnosticMap,MERGED_FROM_DIAGNOSTIC_KEY,MERGED_TO_DIAGNOSTIC_KEY,};});'use strict';tr.exportTo('tr.v',function(){const MAX_DIAGNOSTIC_MAPS=16;const DEFAULT_SAMPLE_VALUES_PER_BIN=10;const DEFAULT_REBINNED_COUNT=40;const DEFAULT_BOUNDARIES_FOR_UNIT=new Map();const DELTA=String.fromCharCode(916);const Z_SCORE_NAME='z-score';const P_VALUE_NAME='p-value';const U_STATISTIC_NAME='U';function percentToString(percent){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
+return{DiagnosticMap,MERGED_FROM_DIAGNOSTIC_KEY,MERGED_TO_DIAGNOSTIC_KEY,};});'use strict';tr.exportTo('tr.v',function(){const MAX_DIAGNOSTIC_MAPS=16;const DEFAULT_SAMPLE_VALUES_PER_BIN=10;const DEFAULT_REBINNED_COUNT=40;const DEFAULT_BOUNDARIES_FOR_UNIT=new Map();const DELTA=String.fromCharCode(916);const Z_SCORE_NAME='z-score';const P_VALUE_NAME='p-value';const U_STATISTIC_NAME='U';function percentToString(percent,opt_force3){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
 if(percent===0)return'000';if(percent===1)return'100';let str=percent.toString();if(str[1]!=='.'){throw new Error('Unexpected percent');}
-str=str+'0'.repeat(Math.max(4-str.length,0));if(str.length>4)str=str.slice(0,4)+'_'+str.slice(4);return'0'+str.slice(2);}
+str=str+'0'.repeat(Math.max(4-str.length,0));if(str.length>4){if(opt_force3){str=str.slice(0,4);}else{str=str.slice(0,4)+'_'+str.slice(4);}}
+return'0'+str.slice(2);}
 function percentFromString(s){return parseFloat(s[0]+'.'+s.substr(1).replace(/_/g,''));}
 class HistogramBin{constructor(range){this.range=range;this.count=0;this.diagnosticMaps=[];}
 addSample(value){this.count+=1;}
 addDiagnosticMap(diagnostics){tr.b.math.Statistics.uniformlySampleStream(this.diagnosticMaps,this.count,diagnostics,MAX_DIAGNOSTIC_MAPS);}
 addBin(other){if(!this.range.equals(other.range)){throw new Error('Merging incompatible Histogram bins.');}
 tr.b.math.Statistics.mergeSampledStreams(this.diagnosticMaps,this.count,other.diagnosticMaps,other.count,MAX_DIAGNOSTIC_MAPS);this.count+=other.count;}
-fromDict(dict){this.count=dict[0];if(dict.length>1){for(let map of dict[1]){this.diagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}}
+fromDict(dict){this.count=dict[0];if(dict.length>1){for(const map of dict[1]){this.diagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}}
 asDict(){if(!this.diagnosticMaps.length){return[this.count];}
 return[this.count,this.diagnosticMaps.map(d=>d.asDict())];}}
-const DEFAULT_SUMMARY_OPTIONS=new Map([['avg',true],['count',true],['geometricMean',false],['max',true],['min',true],['nans',false],['std',true],['sum',true],]);class Histogram{constructor(name,unit,opt_binBoundaries){let binBoundaries=opt_binBoundaries;if(!binBoundaries){let baseUnit=unit.baseUnit?unit.baseUnit:unit;binBoundaries=DEFAULT_BOUNDARIES_FOR_UNIT.get(baseUnit.unitName);}
-this.guid_=undefined;this.binBoundariesDict_=binBoundaries.asDict();this.allBins=binBoundaries.bins.slice();this.description='';this.diagnostics=new tr.v.d.DiagnosticMap();this.maxNumSampleValues_=this.defaultMaxNumSampleValues_;this.name_=name;this.nanDiagnosticMaps=[];this.numNans=0;this.running_=undefined;this.sampleValues_=[];this.shortName=undefined;this.summaryOptions=new Map(DEFAULT_SUMMARY_OPTIONS);this.summaryOptions.set('percentile',[]);this.unit=unit;}
+const DEFAULT_SUMMARY_OPTIONS=new Map([['avg',true],['count',true],['geometricMean',false],['max',true],['min',true],['nans',false],['std',true],['sum',true],]);class Histogram{constructor(name,unit,opt_binBoundaries){let binBoundaries=opt_binBoundaries;if(!binBoundaries){const baseUnit=unit.baseUnit?unit.baseUnit:unit;binBoundaries=DEFAULT_BOUNDARIES_FOR_UNIT.get(baseUnit.unitName);}
+this.guid_=undefined;this.binBoundariesDict_=binBoundaries.asDict();this.allBins=binBoundaries.bins.slice();this.description='';this.diagnostics=new tr.v.d.DiagnosticMap();this.maxNumSampleValues_=this.defaultMaxNumSampleValues_;this.name_=name;this.nanDiagnosticMaps=[];this.numNans=0;this.running_=undefined;this.sampleValues_=[];this.shortName=undefined;this.summaryOptions=new Map(DEFAULT_SUMMARY_OPTIONS);this.summaryOptions.set('percentile',[]);this.summaryOptions.set('iprs',[]);this.unit=unit;}
+static create(name,unit,samples,opt_options){const options=opt_options||{};const hist=new Histogram(name,unit,options.binBoundaries);if(options.description)hist.description=options.description;if(options.shortName)hist.shortName=options.shortName;if(options.summaryOptions){let summaryOptions=options.summaryOptions;if(!(summaryOptions instanceof Map)){summaryOptions=Object.entries(summaryOptions);}
+for(const[name,value]of summaryOptions){hist.summaryOptions.set(name,value);}}
+if(options.diagnostics!==undefined){let diagnostics=options.diagnostics;if(!(diagnostics instanceof Map)){diagnostics=Object.entries(diagnostics);}
+for(const[name,diagnostic]of diagnostics){hist.diagnostics.set(name,diagnostic);}}
+if(!(samples instanceof Array))samples=[samples];for(const sample of samples){if(typeof sample==='object'){hist.addSample(sample.value,sample.diagnostics);}else{hist.addSample(sample);}}
+return hist;}
 get running(){return this.running_;}
 get maxNumSampleValues(){return this.maxNumSampleValues_;}
 set maxNumSampleValues(n){this.maxNumSampleValues_=n;tr.b.math.Statistics.uniformlySampleArray(this.sampleValues_,this.maxNumSampleValues_);}
@@ -6867,16 +7215,17 @@
 return this.guid_;}
 set guid(guid){if(this.guid_!==undefined){throw new Error('Cannot reset guid');}
 this.guid_=guid;}
-static fromDict(dict){let hist=new Histogram(dict.name,tr.b.Unit.fromJSON(dict.unit),HistogramBinBoundaries.fromDict(dict.binBoundaries));hist.guid=dict.guid;if(dict.shortName){hist.shortName=dict.shortName;}
+static fromDict(dict){const hist=new Histogram(dict.name,tr.b.Unit.fromJSON(dict.unit),HistogramBinBoundaries.fromDict(dict.binBoundaries));hist.guid=dict.guid;if(dict.shortName){hist.shortName=dict.shortName;}
 if(dict.description){hist.description=dict.description;}
 if(dict.diagnostics){hist.diagnostics.addDicts(dict.diagnostics);}
-if(dict.allBins){if(dict.allBins.length!==undefined){for(let i=0;i<dict.allBins.length;++i){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(dict.allBins[i]);}}else{for(var[i,binDict]of Object.entries(dict.allBins)){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(binDict);}}}
+if(dict.allBins){if(dict.allBins.length!==undefined){for(let i=0;i<dict.allBins.length;++i){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(dict.allBins[i]);}}else{for(const[i,binDict]of Object.entries(dict.allBins)){hist.allBins[i]=new HistogramBin(hist.allBins[i].range);hist.allBins[i].fromDict(binDict);}}}
 if(dict.running){hist.running_=tr.b.math.RunningStatistics.fromDict(dict.running);}
-if(dict.summaryOptions){hist.customizeSummaryOptions(dict.summaryOptions);}
+if(dict.summaryOptions){if(dict.summaryOptions.iprs){dict.summaryOptions.iprs=dict.summaryOptions.iprs.map(r=>tr.b.math.Range.fromExplicitRange(r[0],r[1]));}
+hist.customizeSummaryOptions(dict.summaryOptions);}
 if(dict.maxNumSampleValues!==undefined){hist.maxNumSampleValues=dict.maxNumSampleValues;}
 if(dict.sampleValues){hist.sampleValues_=dict.sampleValues;}
 if(dict.numNans){hist.numNans=dict.numNans;}
-if(dict.nanDiagnostics){for(let map of dict.nanDiagnostics){hist.nanDiagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}
+if(dict.nanDiagnostics){for(const map of dict.nanDiagnostics){hist.nanDiagnosticMaps.push(tr.v.d.DiagnosticMap.fromDict(map));}}
 return hist;}
 get numValues(){return this.running_?this.running_.count:0;}
 get average(){return this.running_?this.running_.mean:undefined;}
@@ -6888,11 +7237,10 @@
 getDifferenceSignificance(other,opt_alpha){if(this.unit!==other.unit){throw new Error('Cannot compare Histograms with different units');}
 if(this.unit.improvementDirection===tr.b.ImprovementDirection.DONT_CARE){return tr.b.math.Statistics.Significance.DONT_CARE;}
 if(!(other instanceof Histogram)){throw new Error('Unable to compute a p-value');}
-let testResult=tr.b.math.Statistics.mwu(this.sampleValues,other.sampleValues,opt_alpha);return testResult.significance;}
+const testResult=tr.b.math.Statistics.mwu(this.sampleValues,other.sampleValues,opt_alpha);return testResult.significance;}
 getApproximatePercentile(percent){if(percent<0||percent>1){throw new Error('percent must be in [0,1]');}
-if(this.numValues===0){return 0;}
-if(this.allBins.length===1){let sortedSampleValues=this.sampleValues.slice().sort((x,y)=>x-y);return sortedSampleValues[Math.floor((sortedSampleValues.length-1)*percent)];}
-let valuesToSkip=Math.floor((this.numValues-1)*percent);for(let bin of this.allBins){valuesToSkip-=bin.count;if(valuesToSkip>=0)continue;if(bin.range.min===-Number.MAX_VALUE){return bin.range.max;}
+if(this.numValues===0)return undefined;if(this.allBins.length===1){const sortedSampleValues=this.sampleValues.slice().sort((x,y)=>x-y);return sortedSampleValues[Math.floor((sortedSampleValues.length-1)*percent)];}
+let valuesToSkip=Math.floor((this.numValues-1)*percent);for(const bin of this.allBins){valuesToSkip-=bin.count;if(valuesToSkip>=0)continue;if(bin.range.min===-Number.MAX_VALUE){return bin.range.max;}
 if(bin.range.max===Number.MAX_VALUE){return bin.range.min;}
 return bin.range.center;}
 return this.allBins[this.allBins.length-1].range.min;}
@@ -6903,22 +7251,24 @@
 this.running_.add(value);const binIndex=this.getBinIndexForValue(value);let bin=this.allBins[binIndex];if(bin.count===0){bin=new HistogramBin(bin.range);this.allBins[binIndex]=bin;}
 bin.addSample(value);if(opt_diagnostics){bin.addDiagnosticMap(opt_diagnostics);}}
 tr.b.math.Statistics.uniformlySampleStream(this.sampleValues_,this.numValues+this.numNans,value,this.maxNumSampleValues);}
-sampleValuesInto(samples){for(let sampleValue of this.sampleValues){samples.push(sampleValue);}}
+sampleValuesInto(samples){for(const sampleValue of this.sampleValues){samples.push(sampleValue);}}
 canAddHistogram(other){if(this.unit!==other.unit){return false;}
 if(this.binBoundariesDict_===other.binBoundariesDict_){return true;}
 if(this.binBoundariesDict_.length!==other.binBoundariesDict_.length){return false;}
-for(let i=0;i<this.binBoundariesDict_.length;++i){let slice=this.binBoundariesDict_[i];let otherSlice=other.binBoundariesDict_[i];if(slice instanceof Array){if(!(otherSlice instanceof Array)){return false;}
+for(let i=0;i<this.binBoundariesDict_.length;++i){const slice=this.binBoundariesDict_[i];const otherSlice=other.binBoundariesDict_[i];if(slice instanceof Array){if(!(otherSlice instanceof Array)){return false;}
 if(slice[0]!==otherSlice[0]||!tr.b.math.approximately(slice[1],otherSlice[1])||slice[2]!==otherSlice[2]){return false;}}else{if(otherSlice instanceof Array){return false;}
 if(!tr.b.math.approximately(slice,otherSlice)){return false;}}}
 return true;}
 addHistogram(other){if(!this.canAddHistogram(other)){throw new Error('Merging incompatible Histograms');}
 tr.b.math.Statistics.mergeSampledStreams(this.nanDiagnosticMaps,this.numNans,other.nanDiagnosticMaps,other.numNans,MAX_DIAGNOSTIC_MAPS);tr.b.math.Statistics.mergeSampledStreams(this.sampleValues,this.numValues+this.numNans,other.sampleValues,other.numValues+other.numNans,(this.maxNumSampleValues+other.maxNumSampleValues)/2);this.numNans+=other.numNans;if(other.running_!==undefined){if(this.running_===undefined){this.running_=new tr.b.math.RunningStatistics();}
 this.running_=this.running_.merge(other.running_);}
-for(let i=0;i<this.allBins.length;++i){this.allBins[i].addBin(other.allBins[i]);}
+for(let i=0;i<this.allBins.length;++i){let bin=this.allBins[i];if(bin.count===0){bin=new HistogramBin(bin.range);this.allBins[i]=bin;}
+bin.addBin(other.allBins[i]);}
 let mergedFrom=this.diagnostics.get(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY);if(!mergedFrom){mergedFrom=new tr.v.d.RelatedHistogramSet();this.diagnostics.set(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY,mergedFrom);}
 mergedFrom.add(other);let mergedTo=other.diagnostics.get(tr.v.d.MERGED_TO_DIAGNOSTIC_KEY);if(!mergedTo){mergedTo=new tr.v.d.RelatedHistogramSet();other.diagnostics.set(tr.v.d.MERGED_TO_DIAGNOSTIC_KEY,mergedTo);}
-mergedTo.add(this);this.diagnostics.addDiagnostics(other.diagnostics);for(let[stat,option]of other.summaryOptions){if(stat==='percentile'){for(let percent of option){let percentiles=this.summaryOptions.get(stat);if(percentiles.indexOf(percent)<0){percentiles.push(percent);}}}else if(option&&!this.summaryOptions.get(stat)){this.summaryOptions.set(stat,true);}}}
-customizeSummaryOptions(summaryOptions){for(var[key,value]of Object.entries(summaryOptions)){this.summaryOptions.set(key,value);}}
+mergedTo.add(this);this.diagnostics.addDiagnostics(other.diagnostics);for(const[stat,option]of other.summaryOptions){if(stat==='percentile'){const percentiles=this.summaryOptions.get(stat);for(const percent of option){if(!percentiles.includes(percent))percentiles.push(percent);}}else if(stat==='iprs'){const thisIprs=this.summaryOptions.get(stat);for(const ipr of option){let found=false;for(const thisIpr of thisIprs){found=ipr.equals(thisIpr);if(found)break;}
+if(!found)thisIprs.push(ipr);}}else if(option&&!this.summaryOptions.get(stat)){this.summaryOptions.set(stat,true);}}}
+customizeSummaryOptions(summaryOptions){for(const[key,value]of Object.entries(summaryOptions)){this.summaryOptions.set(key,value);}}
 getStatisticScalar(statName,opt_referenceHistogram,opt_mwu){if(statName==='avg'){if(this.running_===undefined)return undefined;return new tr.b.Scalar(this.unit,this.average);}
 if(statName==='std'){if(this.standardDeviation===undefined)return undefined;return new tr.b.Scalar(this.unit,this.standardDeviation);}
 if(statName==='geometricMean'){return new tr.b.Scalar(this.unit,this.geometricMean);}
@@ -6926,32 +7276,33 @@
 return new tr.b.Scalar(this.unit,this.running_[statName]);}
 if(statName==='nans'){return new tr.b.Scalar(tr.b.Unit.byName.count_smallerIsBetter,this.numNans);}
 if(statName==='count'){return new tr.b.Scalar(tr.b.Unit.byName.count_smallerIsBetter,this.numValues);}
-if(statName.substr(0,4)==='pct_'){let percent=percentFromString(statName.substr(4));let percentile=this.getApproximatePercentile(percent);return new tr.b.Scalar(this.unit,percentile);}
+if(statName.substr(0,4)==='pct_'){const percent=percentFromString(statName.substr(4));if(this.numValues===0)return undefined;const percentile=this.getApproximatePercentile(percent);return new tr.b.Scalar(this.unit,percentile);}
+if(statName.substr(0,4)==='ipr_'){let lower=percentFromString(statName.substr(4,3));let upper=percentFromString(statName.substr(8));if(lower>=upper){throw new Error('Invalid inter-percentile range: '+statName);}
+lower=this.getApproximatePercentile(lower);upper=this.getApproximatePercentile(upper);return new tr.b.Scalar(this.unit,upper-lower);}
 if(!this.canCompare(opt_referenceHistogram)){throw new Error('Cannot compute '+statName+' when histograms are not comparable');}
 const suffix=tr.b.Unit.nameSuffixForImprovementDirection(this.unit.improvementDirection);const deltaIndex=statName.indexOf(DELTA);if(deltaIndex>=0){const baseStatName=statName.substr(deltaIndex+1);const thisStat=this.getStatisticScalar(baseStatName);const otherStat=opt_referenceHistogram.getStatisticScalar(baseStatName);const deltaValue=thisStat.value-otherStat.value;if(statName[0]==='%'){return new tr.b.Scalar(tr.b.Unit.byName['normalizedPercentageDelta'+suffix],deltaValue/otherStat.value);}
 return new tr.b.Scalar(thisStat.unit.correspondingDeltaUnit,deltaValue);}
 if(statName===Z_SCORE_NAME){return new tr.b.Scalar(tr.b.Unit.byName['sigmaDelta'+suffix],(this.average-opt_referenceHistogram.average)/opt_referenceHistogram.standardDeviation);}
-let mwu=opt_mwu||tr.b.math.Statistics.mwu(this.sampleValues,opt_referenceHistogram.sampleValues);if(statName===P_VALUE_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.p);}
+const mwu=opt_mwu||tr.b.math.Statistics.mwu(this.sampleValues,opt_referenceHistogram.sampleValues);if(statName===P_VALUE_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.p);}
 if(statName===U_STATISTIC_NAME){return new tr.b.Scalar(tr.b.Unit.byName.unitlessNumber,mwu.U);}
 throw new Error('Unrecognized statistic name: '+statName);}
-get statisticsNames(){let statisticsNames=new Set();for(let[statName,option]of this.summaryOptions){if(statName==='percentile'){for(let pctile of option){statisticsNames.add('pct_'+tr.v.percentToString(pctile));}}else if(option){statisticsNames.add(statName);}}
+get statisticsNames(){const statisticsNames=new Set();for(const[statName,option]of this.summaryOptions){if(statName==='percentile'){for(const pctile of option){statisticsNames.add('pct_'+tr.v.percentToString(pctile));}}else if(statName==='iprs'){for(const range of option){statisticsNames.add('ipr_'+tr.v.percentToString(range.min,true)+'_'+tr.v.percentToString(range.max,true));}}else if(option){statisticsNames.add(statName);}}
 return statisticsNames;}
 canCompare(other){return other instanceof Histogram&&this.unit===other.unit&&this.numValues>0&&other.numValues>0;}
 getAvailableStatisticName(statName,opt_referenceHist){if(this.canCompare(opt_referenceHist))return statName;if(statName===Z_SCORE_NAME||statName===P_VALUE_NAME||statName===U_STATISTIC_NAME){return'avg';}
 const deltaIndex=statName.indexOf(DELTA);if(deltaIndex<0)return statName;return statName.substr(deltaIndex+1);}
 static getDeltaStatisticsNames(statNames){const deltaNames=[];for(const statName of statNames){deltaNames.push(`${DELTA}${statName}`);deltaNames.push(`%${DELTA}${statName}`);}
 return deltaNames.concat([Z_SCORE_NAME,P_VALUE_NAME,U_STATISTIC_NAME]);}
-get statisticsScalars(){let results=new Map();for(let statName of this.statisticsNames){let scalar=this.getStatisticScalar(statName);if(scalar===undefined)continue;results.set(statName,scalar);}
+get statisticsScalars(){const results=new Map();for(const statName of this.statisticsNames){const scalar=this.getStatisticScalar(statName);if(scalar===undefined)continue;results.set(statName,scalar);}
 return results;}
 get sampleValues(){return this.sampleValues_;}
-clone(){let binBoundaries=HistogramBinBoundaries.fromDict(this.binBoundariesDict_);let hist=new Histogram(this.name,this.unit,binBoundaries);for(let[stat,option]of this.summaryOptions){if(stat==='percentile'){option=Array.from(option);}
-hist.summaryOptions.set(stat,option);}
+clone(){const binBoundaries=HistogramBinBoundaries.fromDict(this.binBoundariesDict_);const hist=new Histogram(this.name,this.unit,binBoundaries);for(const[stat,option]of this.summaryOptions){if(stat==='percentile'||stat==='iprs'){hist.summaryOptions.set(stat,Array.from(option));}else{hist.summaryOptions.set(stat,option);}}
 hist.addHistogram(this);return hist;}
 rebin(newBoundaries){const rebinned=new tr.v.Histogram(this.name,this.unit,newBoundaries);rebinned.description=this.description;for(const sample of this.sampleValues){rebinned.addSample(sample);}
 rebinned.running_=this.running_;for(const[name,diagnostic]of this.diagnostics){rebinned.diagnostics.set(name,diagnostic);}
-for(let[stat,option]of this.summaryOptions){if(stat==='percentile')option=Array.from(option);rebinned.summaryOptions.set(stat,option);}
+for(const[stat,option]of this.summaryOptions){if(stat==='percentile'){rebinned.summaryOptions.set(stat,Array.from(option));}else{rebinned.summaryOptions.set(stat,option);}}
 return rebinned;}
-asDict(){let dict={};dict.name=this.name;dict.unit=this.unit.asJSON();dict.guid=this.guid;if(this.binBoundariesDict_!==undefined){dict.binBoundaries=this.binBoundariesDict_;}
+asDict(){const dict={};dict.name=this.name;dict.unit=this.unit.asJSON();dict.guid=this.guid;if(this.binBoundariesDict_!==undefined){dict.binBoundaries=this.binBoundariesDict_;}
 if(this.shortName){dict.shortName=this.shortName;}
 if(this.description){dict.description=this.description;}
 if(this.diagnostics.size){dict.diagnostics=this.diagnostics.asDict();}
@@ -6959,21 +7310,20 @@
 if(this.numNans){dict.numNans=this.numNans;}
 if(this.nanDiagnosticMaps.length){dict.nanDiagnostics=this.nanDiagnosticMaps.map(dm=>dm.asDict());}
 if(this.numValues){dict.sampleValues=this.sampleValues.slice();dict.running=this.running_.asDict();dict.allBins=this.allBinsAsDict_();}
-let summaryOptions={};let anyOverriddenSummaryOptions=false;for(let[name,option]of this.summaryOptions){if(name==='percentile'){if(option.length===0){continue;}
-option=option.slice();}else if(option===DEFAULT_SUMMARY_OPTIONS.get(name)){continue;}
+const summaryOptions={};let anyOverriddenSummaryOptions=false;for(const[name,value]of this.summaryOptions){let option;if(name==='percentile'){if(value.length===0)continue;option=Array.from(value);}else if(name==='iprs'){if(value.length===0)continue;option=value.map(r=>[r.min,r.max]);}else if(value===DEFAULT_SUMMARY_OPTIONS.get(name)){continue;}else{option=value;}
 summaryOptions[name]=option;anyOverriddenSummaryOptions=true;}
 if(anyOverriddenSummaryOptions){dict.summaryOptions=summaryOptions;}
 return dict;}
-allBinsAsDict_(){let numBins=this.allBins.length;let emptyBins=0;for(let i=0;i<numBins;++i){if(this.allBins[i].count===0){++emptyBins;}}
+allBinsAsDict_(){const numBins=this.allBins.length;let emptyBins=0;for(let i=0;i<numBins;++i){if(this.allBins[i].count===0){++emptyBins;}}
 if(emptyBins===numBins){return undefined;}
-if(emptyBins>(numBins/2)){let allBinsDict={};for(let i=0;i<numBins;++i){let bin=this.allBins[i];if(bin.count>0){allBinsDict[i]=bin.asDict();}}
+if(emptyBins>(numBins/2)){const allBinsDict={};for(let i=0;i<numBins;++i){const bin=this.allBins[i];if(bin.count>0){allBinsDict[i]=bin.asDict();}}
 return allBinsDict;}
-let allBinsArray=[];for(let i=0;i<numBins;++i){allBinsArray.push(this.allBins[i].asDict());}
+const allBinsArray=[];for(let i=0;i<numBins;++i){allBinsArray.push(this.allBins[i].asDict());}
 return allBinsArray;}
 get defaultMaxNumSampleValues_(){return DEFAULT_SAMPLE_VALUES_PER_BIN*Math.max(this.allBins.length,DEFAULT_REBINNED_COUNT);}}
-const HISTOGRAM_BIN_BOUNDARIES_CACHE=new Map();class HistogramBinBoundaries{static createLinear(min,max,numBins){return new HistogramBinBoundaries(min).addLinearBins(max,numBins);}
+Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS={count:false,max:false,min:false,std:false,sum:false,};const HISTOGRAM_BIN_BOUNDARIES_CACHE=new Map();class HistogramBinBoundaries{static createLinear(min,max,numBins){return new HistogramBinBoundaries(min).addLinearBins(max,numBins);}
 static createExponential(min,max,numBins){return new HistogramBinBoundaries(min).addExponentialBins(max,numBins);}
-static createWithBoundaries(binBoundaries){let builder=new HistogramBinBoundaries(binBoundaries[0]);for(let boundary of binBoundaries.slice(1)){builder.addBinBoundary(boundary);}
+static createWithBoundaries(binBoundaries){const builder=new HistogramBinBoundaries(binBoundaries[0]);for(const boundary of binBoundaries.slice(1)){builder.addBinBoundary(boundary);}
 return builder;}
 constructor(minBinBoundary){this.builder_=[minBinBoundary];this.range_=new tr.b.math.Range();this.range_.addValue(minBinBoundary);this.binRanges_=undefined;this.bins_=undefined;}
 get range(){return this.range_;}
@@ -6981,8 +7331,8 @@
 return this.builder_;}
 pushBuilderSlice_(slice){this.builder_.push(slice);this.builder_=this.builder_.slice();}
 static fromDict(dict){if(dict===undefined){return HistogramBinBoundaries.SINGULAR;}
-let cacheKey=JSON.stringify(dict);if(HISTOGRAM_BIN_BOUNDARIES_CACHE.has(cacheKey)){return HISTOGRAM_BIN_BOUNDARIES_CACHE.get(cacheKey);}
-let binBoundaries=new HistogramBinBoundaries(dict[0]);for(let slice of dict.slice(1)){if(!(slice instanceof Array)){binBoundaries.addBinBoundary(slice);continue;}
+const cacheKey=JSON.stringify(dict);if(HISTOGRAM_BIN_BOUNDARIES_CACHE.has(cacheKey)){return HISTOGRAM_BIN_BOUNDARIES_CACHE.get(cacheKey);}
+const binBoundaries=new HistogramBinBoundaries(dict[0]);for(const slice of dict.slice(1)){if(!(slice instanceof Array)){binBoundaries.addBinBoundary(slice);continue;}
 switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:binBoundaries.addLinearBins(slice[1],slice[2]);break;case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:binBoundaries.addExponentialBins(slice[1],slice[2]);break;default:throw new Error('Unrecognized HistogramBinBoundaries slice type');}}
 HISTOGRAM_BIN_BOUNDARIES_CACHE.set(cacheKey,binBoundaries);return binBoundaries;}
 get bins(){if(this.bins_===undefined){this.buildBins_();}
@@ -6992,10 +7342,10 @@
 return this.binRanges_;}
 buildBinRanges_(){if(typeof this.builder_[0]!=='number'){throw new Error('Invalid start of builder_');}
 this.binRanges_=[];let prevBoundary=this.builder_[0];if(prevBoundary>-Number.MAX_VALUE){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(-Number.MAX_VALUE,prevBoundary));}
-for(let slice of this.builder_.slice(1)){if(!(slice instanceof Array)){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,slice));prevBoundary=slice;continue;}
-let nextMaxBinBoundary=slice[1];let binCount=slice[2];let sliceMinBinBoundary=prevBoundary;switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:{let binWidth=(nextMaxBinBoundary-prevBoundary)/binCount;for(let i=1;i<binCount;i++){let boundary=sliceMinBinBoundary+i*binWidth;this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
+for(const slice of this.builder_.slice(1)){if(!(slice instanceof Array)){this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,slice));prevBoundary=slice;continue;}
+const nextMaxBinBoundary=slice[1];const binCount=slice[2];const sliceMinBinBoundary=prevBoundary;switch(slice[0]){case HistogramBinBoundaries.SLICE_TYPE.LINEAR:{const binWidth=(nextMaxBinBoundary-prevBoundary)/binCount;for(let i=1;i<binCount;i++){const boundary=sliceMinBinBoundary+i*binWidth;this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
 break;}
-case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:{let binExponentWidth=Math.log(nextMaxBinBoundary/prevBoundary)/binCount;for(let i=1;i<binCount;i++){let boundary=sliceMinBinBoundary*Math.exp(i*binExponentWidth);this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
+case HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL:{const binExponentWidth=Math.log(nextMaxBinBoundary/prevBoundary)/binCount;for(let i=1;i<binCount;i++){const boundary=sliceMinBinBoundary*Math.exp(i*binExponentWidth);this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,boundary));prevBoundary=boundary;}
 break;}
 default:throw new Error('Unrecognized HistogramBinBoundaries slice type');}
 this.binRanges_.push(tr.b.math.Range.fromExplicitRange(prevBoundary,nextMaxBinBoundary));prevBoundary=nextMaxBinBoundary;}
@@ -7009,23 +7359,23 @@
 if(this.range.max<=0){throw new Error('Current max bin boundary must be positive');}
 if(this.range.max>=nextMaxBinBoundary){throw new Error('The last added max boundary must be greater than '+'the current max boundary boundary');}
 this.binRanges_=undefined;this.bins_=undefined;this.pushBuilderSlice_([HistogramBinBoundaries.SLICE_TYPE.EXPONENTIAL,nextMaxBinBoundary,binCount]);this.range.addValue(nextMaxBinBoundary);return this;}}
-HistogramBinBoundaries.SLICE_TYPE={LINEAR:0,EXPONENTIAL:1,};HistogramBinBoundaries.SINGULAR=new HistogramBinBoundaries(Number.MAX_VALUE);DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeDurationInMs.unitName,HistogramBinBoundaries.createExponential(1e-3,1e6,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeStampInMs.unitName,HistogramBinBoundaries.createLinear(0,1e10,1e3));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.normalizedPercentage.unitName,HistogramBinBoundaries.createLinear(0,1.0,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sizeInBytes.unitName,HistogramBinBoundaries.createExponential(1,1e12,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.energyInJoules.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.powerInWatts.unitName,HistogramBinBoundaries.createExponential(1e-3,1,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.unitlessNumber.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.count.unitName,HistogramBinBoundaries.createExponential(1,1e3,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sigma.unitName,HistogramBinBoundaries.createLinear(-5,5,50));return{DEFAULT_REBINNED_COUNT,DELTA,Histogram,HistogramBinBoundaries,P_VALUE_NAME,U_STATISTIC_NAME,Z_SCORE_NAME,percentFromString,percentToString,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-context-controller',created:function(){this.host_=undefined;this.groupToContext_=new Map();this.dirtyGroups_=new Set();},attached:function(){if(this.host_){throw new Error('Scalar context controller is already attached to a host');}
-let host=findParentOrHost(this);if(host.__scalarContextController){throw new Error('Multiple scalar context controllers attached to this host');}
-host.__scalarContextController=this;this.host_=host;},detached:function(){if(!this.host_){throw new Error('Scalar context controller is not attached to a host');}
+HistogramBinBoundaries.SLICE_TYPE={LINEAR:0,EXPONENTIAL:1,};HistogramBinBoundaries.SINGULAR=new HistogramBinBoundaries(Number.MAX_VALUE);DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeDurationInMs.unitName,HistogramBinBoundaries.createExponential(1e-3,1e6,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.timeStampInMs.unitName,HistogramBinBoundaries.createLinear(0,1e10,1e3));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.normalizedPercentage.unitName,HistogramBinBoundaries.createLinear(0,1.0,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sizeInBytes.unitName,HistogramBinBoundaries.createExponential(1,1e12,1e2));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.energyInJoules.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.powerInWatts.unitName,HistogramBinBoundaries.createExponential(1e-3,1,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.unitlessNumber.unitName,HistogramBinBoundaries.createExponential(1e-3,1e3,50));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.count.unitName,HistogramBinBoundaries.createExponential(1,1e3,20));DEFAULT_BOUNDARIES_FOR_UNIT.set(tr.b.Unit.byName.sigma.unitName,HistogramBinBoundaries.createLinear(-5,5,50));return{DEFAULT_REBINNED_COUNT,DELTA,Histogram,HistogramBinBoundaries,P_VALUE_NAME,U_STATISTIC_NAME,Z_SCORE_NAME,percentFromString,percentToString,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-scalar-context-controller',created(){this.host_=undefined;this.groupToContext_=new Map();this.dirtyGroups_=new Set();},attached(){if(this.host_){throw new Error('Scalar context controller is already attached to a host');}
+const host=findParentOrHost(this);if(host.__scalarContextController){throw new Error('Multiple scalar context controllers attached to this host');}
+host.__scalarContextController=this;this.host_=host;},detached(){if(!this.host_){throw new Error('Scalar context controller is not attached to a host');}
 if(this.host_.__scalarContextController!==this){throw new Error('Scalar context controller is not attached to its host');}
-delete this.host_.__scalarContextController;this.host_=undefined;},getContext:function(group){return this.groupToContext_.get(group);},onScalarSpanAdded:function(group,span){let context=this.groupToContext_.get(group);if(context===undefined){context={spans:new Set(),range:new tr.b.math.Range()};this.groupToContext_.set(group,context);}
+delete this.host_.__scalarContextController;this.host_=undefined;},getContext(group){return this.groupToContext_.get(group);},onScalarSpanAdded(group,span){let context=this.groupToContext_.get(group);if(context===undefined){context={spans:new Set(),range:new tr.b.math.Range()};this.groupToContext_.set(group,context);}
 if(context.spans.has(span)){throw new Error('Scalar span already registered with group: '+group);}
-context.spans.add(span);this._markGroupDirtyAndScheduleUpdate(group);},onScalarSpanRemoved:function(group,span){let context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
-context.spans.delete(span);this._markGroupDirtyAndScheduleUpdate(group);},onScalarSpanUpdated:function(group,span){let context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
-this._markGroupDirtyAndScheduleUpdate(group);},_markGroupDirtyAndScheduleUpdate:function(group){let alreadyDirty=this.dirtyGroups_.size>0;this.dirtyGroups_.add(group);if(!alreadyDirty){tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContext,this);}},updateContext:function(){let groups=this.dirtyGroups_;if(groups.size===0)return;this.dirtyGroups_=new Set();for(let group of groups){this.updateGroup_(group);}
-let event=new tr.b.Event('context-updated');event.groups=groups;this.dispatchEvent(event);},updateGroup_:function(group){let context=this.groupToContext_.get(group);if(context.spans.size===0){this.groupToContext_.delete(group);return;}
-context.range.reset();for(let span of context.spans){context.range.addValue(span.value);}}});function getScalarContextControllerForElement(element){while(element){if(element.__scalarContextController){return element.__scalarContextController;}
+context.spans.add(span);this.markGroupDirtyAndScheduleUpdate_(group);},onScalarSpanRemoved(group,span){const context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
+context.spans.delete(span);this.markGroupDirtyAndScheduleUpdate_(group);},onScalarSpanUpdated(group,span){const context=this.groupToContext_.get(group);if(!context.spans.has(span)){throw new Error('Scalar span not registered with group: '+group);}
+this.markGroupDirtyAndScheduleUpdate_(group);},markGroupDirtyAndScheduleUpdate_(group){const alreadyDirty=this.dirtyGroups_.size>0;this.dirtyGroups_.add(group);if(!alreadyDirty){tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContext,this);}},updateContext(){const groups=this.dirtyGroups_;if(groups.size===0)return;this.dirtyGroups_=new Set();for(const group of groups){this.updateGroup_(group);}
+const event=new tr.b.Event('context-updated');event.groups=groups;this.dispatchEvent(event);},updateGroup_(group){const context=this.groupToContext_.get(group);if(context.spans.size===0){this.groupToContext_.delete(group);return;}
+context.range.reset();for(const span of context.spans){context.range.addValue(span.value);}}});function getScalarContextControllerForElement(element){while(element){if(element.__scalarContextController){return element.__scalarContextController;}
 element=findParentOrHost(element);}
 return undefined;}
 function findParentOrHost(node){if(node.parentElement){return node.parentElement;}
 while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
 return node.host;}
-return{getScalarContextControllerForElement,};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)return'';let config=opt_config||{};let ownerDocument=config.ownerDocument||document;let span=ownerDocument.createElement('tr-v-ui-scalar-span');let numericValue;if(value instanceof tr.b.Scalar){span.value=value;numericValue=value.value;}else if(value instanceof tr.v.Histogram){numericValue=value.average;if(numericValue===undefined)return'';span.setValueAndUnit(numericValue,value.unit);}else{let unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
+return{getScalarContextControllerForElement,};});'use strict';tr.exportTo('tr.v.ui',function(){function createScalarSpan(value,opt_config){if(value===undefined)return'';const config=opt_config||{};const ownerDocument=config.ownerDocument||document;const span=ownerDocument.createElement('tr-v-ui-scalar-span');let numericValue;if(value instanceof tr.b.Scalar){span.value=value;numericValue=value.value;}else if(value instanceof tr.v.Histogram){numericValue=value.average;if(numericValue===undefined)return'';span.setValueAndUnit(numericValue,value.unit);}else{const unit=config.unit;if(unit===undefined){throw new Error('Unit must be provided in config when value is a number');}
 span.setValueAndUnit(value,unit);numericValue=value;}
 if(config.context){span.context=config.context;}
 if(config.customContextRange){span.customContextRange=config.customContextRange;}
@@ -7034,201 +7384,201 @@
 if(config.significance!==undefined){span.significance=config.significance;}
 if(config.contextGroup!==undefined){span.contextGroup=config.contextGroup;}
 return span;}
-return{createScalarSpan,};});'use strict';Polymer({is:'tr-v-ui-scalar-span',properties:{contextGroup:{type:String,reflectToAttribute:true,observer:'contextGroupChanged_'}},created:function(){this.value_=undefined;this.unit_=undefined;this.context_=undefined;this.warning_=undefined;this.significance_=tr.b.math.Statistics.Significance.DONT_CARE;this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;this.onContextUpdated_=this.onContextUpdated_.bind(this);this.customContextRange_=undefined;},get significance(){return this.significance_;},set significance(s){this.significance_=s;this.updateContents_();},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
+return{createScalarSpan,};});'use strict';Polymer({is:'tr-v-ui-scalar-span',properties:{contextGroup:{type:String,reflectToAttribute:true,observer:'contextGroupChanged_'}},created(){this.value_=undefined;this.unit_=undefined;this.context_=undefined;this.warning_=undefined;this.significance_=tr.b.math.Statistics.Significance.DONT_CARE;this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;this.onContextUpdated_=this.onContextUpdated_.bind(this);this.customContextRange_=undefined;},get significance(){return this.significance_;},set significance(s){this.significance_=s;this.updateContents_();},set contentTextDecoration(deco){this.$.content.style.textDecoration=deco;},get value(){return this.value_;},set value(value){if(value instanceof tr.b.Scalar){this.value_=value.value;this.unit_=value.unit;}else{this.value_=value;}
 this.updateContents_();if(this.hasContext_(this.contextGroup)){this.contextController_.onScalarSpanUpdated(this.contextGroup,this);}else{this.updateSparkline_();}},get contextController_(){if(this.shouldSearchForContextController_){this.lazyContextController_=tr.v.ui.getScalarContextControllerForElement(this);this.shouldSearchForContextController_=false;}
-return this.lazyContextController_;},hasContext_:function(contextGroup){return!!(contextGroup&&this.contextController_);},contextGroupChanged_:function(newContextGroup,oldContextGroup){this.detachFromContextControllerIfPossible_(oldContextGroup);if(!this.attachToContextControllerIfPossible_(newContextGroup)){this.onContextUpdated_();}},attachToContextControllerIfPossible_:function(contextGroup){if(!this.hasContext_(contextGroup))return false;this.contextController_.addEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanAdded(contextGroup,this);return true;},detachFromContextControllerIfPossible_:function(contextGroup){if(!this.hasContext_(contextGroup))return;this.contextController_.removeEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanRemoved(contextGroup,this);},attached:function(){tr.b.Unit.addEventListener('display-mode-changed',this.updateContents_.bind(this));this.shouldSearchForContextController_=true;this.attachToContextControllerIfPossible_(this.contextGroup);},detached:function(){tr.b.Unit.removeEventListener('display-mode-changed',this.updateContents_.bind(this));this.detachFromContextControllerIfPossible_(this.contextGroup);this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;},onContextUpdated_:function(){this.updateSparkline_();},get context(){return this.context_;},set context(context){this.context_=context;this.updateContents_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContents_();this.updateSparkline_();},setValueAndUnit:function(value,unit){this.value_=value;this.unit_=unit;this.updateContents_();},get customContextRange(){return this.customContextRange_;},set customContextRange(customContextRange){this.customContextRange_=customContextRange;this.updateSparkline_();},get inline(){return Polymer.dom(this).classList.contains('inline');},set inline(inline){if(inline){Polymer.dom(this).classList.add('inline');}else{Polymer.dom(this).classList.remove('inline');}},get leftAlign(){return Polymer.dom(this).classList.contains('left-align');},set leftAlign(leftAlign){if(leftAlign){Polymer.dom(this).classList.add('left-align');}else{Polymer.dom(this).classList.remove('left-align');}},updateSparkline_:function(){Polymer.dom(this.$.sparkline).classList.remove('positive');Polymer.dom(this.$.sparkline).classList.remove('better');Polymer.dom(this.$.sparkline).classList.remove('worse');Polymer.dom(this.$.sparkline).classList.remove('same');this.$.sparkline.style.display='none';this.$.sparkline.style.left='0';this.$.sparkline.style.width='0';let range=this.customContextRange_;if(!range&&this.hasContext_(this.contextGroup)){let context=this.contextController_.getContext(this.contextGroup);if(context){range=context.range;}}
-if(!range||range.isEmpty)return;let leftPoint=Math.min(range.min,0);let rightPoint=Math.max(range.max,0);let pointDistance=rightPoint-leftPoint;if(pointDistance===0){return;}
+return this.lazyContextController_;},hasContext_(contextGroup){return!!(contextGroup&&this.contextController_);},contextGroupChanged_(newContextGroup,oldContextGroup){this.detachFromContextControllerIfPossible_(oldContextGroup);if(!this.attachToContextControllerIfPossible_(newContextGroup)){this.onContextUpdated_();}},attachToContextControllerIfPossible_(contextGroup){if(!this.hasContext_(contextGroup))return false;this.contextController_.addEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanAdded(contextGroup,this);return true;},detachFromContextControllerIfPossible_(contextGroup){if(!this.hasContext_(contextGroup))return;this.contextController_.removeEventListener('context-updated',this.onContextUpdated_);this.contextController_.onScalarSpanRemoved(contextGroup,this);},attached(){tr.b.Unit.addEventListener('display-mode-changed',this.updateContents_.bind(this));this.shouldSearchForContextController_=true;this.attachToContextControllerIfPossible_(this.contextGroup);},detached(){tr.b.Unit.removeEventListener('display-mode-changed',this.updateContents_.bind(this));this.detachFromContextControllerIfPossible_(this.contextGroup);this.shouldSearchForContextController_=false;this.lazyContextController_=undefined;},onContextUpdated_(){this.updateSparkline_();},get context(){return this.context_;},set context(context){this.context_=context;this.updateContents_();},get unit(){return this.unit_;},set unit(unit){this.unit_=unit;this.updateContents_();this.updateSparkline_();},setValueAndUnit(value,unit){this.value_=value;this.unit_=unit;this.updateContents_();},get customContextRange(){return this.customContextRange_;},set customContextRange(customContextRange){this.customContextRange_=customContextRange;this.updateSparkline_();},get inline(){return Polymer.dom(this).classList.contains('inline');},set inline(inline){if(inline){Polymer.dom(this).classList.add('inline');}else{Polymer.dom(this).classList.remove('inline');}},get leftAlign(){return Polymer.dom(this).classList.contains('left-align');},set leftAlign(leftAlign){if(leftAlign){Polymer.dom(this).classList.add('left-align');}else{Polymer.dom(this).classList.remove('left-align');}},updateSparkline_(){Polymer.dom(this.$.sparkline).classList.remove('positive');Polymer.dom(this.$.sparkline).classList.remove('better');Polymer.dom(this.$.sparkline).classList.remove('worse');Polymer.dom(this.$.sparkline).classList.remove('same');this.$.sparkline.style.display='none';this.$.sparkline.style.left='0';this.$.sparkline.style.width='0';let range=this.customContextRange_;if(!range&&this.hasContext_(this.contextGroup)){const context=this.contextController_.getContext(this.contextGroup);if(context){range=context.range;}}
+if(!range||range.isEmpty)return;const leftPoint=Math.min(range.min,0);const rightPoint=Math.max(range.max,0);const pointDistance=rightPoint-leftPoint;if(pointDistance===0){return;}
 this.$.sparkline.style.display='block';let left;let width;if(this.value>0){width=Math.min(this.value,rightPoint);left=-leftPoint;Polymer.dom(this.$.sparkline).classList.add('positive');}else if(this.value<=0){width=-Math.max(this.value,leftPoint);left=(-leftPoint)-width;}
-this.$.sparkline.style.left=this.buildSparklineStyle_(left/pointDistance,false);this.$.sparkline.style.width=this.buildSparklineStyle_(width/pointDistance,true);let changeClass=this.changeClassName_;if(changeClass){Polymer.dom(this.$.sparkline).classList.add(changeClass);}},buildSparklineStyle_:function(ratio,isWidth){let position='calc('+ratio+' * (100% - 1px)';if(isWidth){position+=' + 1px';}
-position+=')';return position;},updateContents_:function(){Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).classList.remove('better');Polymer.dom(this.$.content).classList.remove('worse');Polymer.dom(this.$.content).classList.remove('same');this.$.insignificant.style.display='';this.$.significantly_better.style.display='';this.$.significantly_worse.style.display='';if(this.unit_===undefined)return;this.$.content.title='';Polymer.dom(this.$.content).textContent=this.unit_.format(this.value,this.context);this.updateDelta_();},updateDelta_:function(){let changeClass=this.changeClassName_;if(!changeClass){this.$.significance.style.display='none';return;}
+this.$.sparkline.style.left=this.buildSparklineStyle_(left/pointDistance,false);this.$.sparkline.style.width=this.buildSparklineStyle_(width/pointDistance,true);const changeClass=this.changeClassName_;if(changeClass){Polymer.dom(this.$.sparkline).classList.add(changeClass);}},buildSparklineStyle_(ratio,isWidth){let position='calc('+ratio+' * (100% - 1px)';if(isWidth){position+=' + 1px';}
+position+=')';return position;},updateContents_(){Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).classList.remove('better');Polymer.dom(this.$.content).classList.remove('worse');Polymer.dom(this.$.content).classList.remove('same');this.$.insignificant.style.display='';this.$.significantly_better.style.display='';this.$.significantly_worse.style.display='';if(this.unit_===undefined)return;this.$.content.title='';Polymer.dom(this.$.content).textContent=this.unit_.format(this.value,this.context);this.updateDelta_();},updateDelta_(){let changeClass=this.changeClassName_;if(!changeClass){this.$.significance.style.display='none';return;}
 this.$.significance.style.display='inline';let title;switch(changeClass){case'better':title='improvement';break;case'worse':title='regression';break;case'same':title='no change';break;default:throw new Error('Unknown change class: '+changeClass);}
 Polymer.dom(this.$.content).classList.add(changeClass);switch(this.significance){case tr.b.math.Statistics.Significance.DONT_CARE:break;case tr.b.math.Statistics.Significance.INSIGNIFICANT:if(changeClass!=='same')title='insignificant '+title;this.$.insignificant.style.display='inline';changeClass='same';break;case tr.b.math.Statistics.Significance.SIGNIFICANT:if(changeClass==='same'){throw new Error('How can no change be significant?');}
 this.$['significantly_'+changeClass].style.display='inline';title='significant '+title;break;default:throw new Error('Unknown significance '+this.significance);}
 this.$.significance.title=title;this.$.content.title=title;},get changeClassName_(){if(!this.unit_||!this.unit_.isDelta)return undefined;switch(this.unit_.improvementDirection){case tr.b.ImprovementDirection.DONT_CARE:return undefined;case tr.b.ImprovementDirection.BIGGER_IS_BETTER:if(this.value===0)return'same';return this.value>0?'better':'worse';case tr.b.ImprovementDirection.SMALLER_IS_BETTER:if(this.value===0)return'same';return this.value<0?'better':'worse';default:throw new Error('Unknown improvement direction: '+
-this.unit_.improvementDirection);}},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;let warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='inline';}else{warningEl.title='';warningEl.style.display='';}},get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
+this.unit_.improvementDirection);}},get warning(){return this.warning_;},set warning(warning){this.warning_=warning;const warningEl=this.$.warning;if(this.warning_){warningEl.title=warning;warningEl.style.display='inline';}else{warningEl.title='';warningEl.style.display='';}},get timestamp(){return this.value;},set timestamp(timestamp){if(timestamp instanceof tr.b.u.TimeStamp){this.value=timestamp;return;}
 this.setValueAndUnit(timestamp,tr.b.u.Units.timeStampInMs);},get duration(){return this.value;},set duration(duration){if(duration instanceof tr.b.u.TimeDuration){this.value=duration;return;}
-this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';var URL_REGEX=/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(var colName in object[0]){if(typeof colName!=='string')return false;}
-for(var i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(var colName in object[i]){if(i&&(object[0][colName]===undefined))return false;var cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!=='number')return false;}
-if(i){for(var colName in object[0]){if(object[i][colName]===undefined)return false;}}}
+this.setValueAndUnit(duration,tr.b.u.Units.timeDurationInMs);}});'use strict';const URL_REGEX=/^https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)$/;function isTable(object){if(!(object instanceof Array)||(object.length<2))return false;for(const colName in object[0]){if(typeof colName!=='string')return false;}
+for(let i=0;i<object.length;++i){if(!(object[i]instanceof Object))return false;for(const colName in object[i]){if(i&&(object[0][colName]===undefined))return false;const cellType=typeof object[i][colName];if(cellType!=='string'&&cellType!=='number')return false;}
+if(i){for(const colName in object[0]){if(object[i][colName]===undefined)return false;}}}
 return true;}
-Polymer({is:'tr-ui-a-generic-object-view',ready:function(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_:function(){Polymer.dom(this.$.content).textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_:function(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
+Polymer({is:'tr-ui-a-generic-object-view',ready(){this.object_=undefined;},get object(){return this.object_;},set object(object){this.object_=object;this.updateContents_();},updateContents_(){Polymer.dom(this.$.content).textContent='';this.appendElementsForType_('',this.object_,0,0,5,'');},appendElementsForType_(label,object,indent,depth,maxDepth,suffix){if(depth>maxDepth){this.appendSimpleText_(label,indent,'<recursion limit reached>',suffix);return;}
 if(object===undefined){this.appendSimpleText_(label,indent,'undefined',suffix);return;}
 if(object===null){this.appendSimpleText_(label,indent,'null',suffix);return;}
-if(!(object instanceof Object)){var type=typeof object;if(type!=='string'){return this.appendSimpleText_(label,indent,object,suffix);}
-var objectReplaced=false;if((object[0]==='{'&&object[object.length-1]==='}')||(object[0]==='['&&object[object.length-1]===']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
-if(!objectReplaced){if(object.includes('\n')){var lines=object.split('\n');lines.forEach(function(line,i){var text;var ioff;var ll;var ss;if(i===0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
-var el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}
-if(object.match(URL_REGEX)){var link=document.createElement('a');link.href=object;link.textContent=object;this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(!(object instanceof Object)){const type=typeof object;if(type!=='string'){return this.appendSimpleText_(label,indent,object,suffix);}
+let objectReplaced=false;if((object[0]==='{'&&object[object.length-1]==='}')||(object[0]==='['&&object[object.length-1]===']')){try{object=JSON.parse(object);objectReplaced=true;}catch(e){}}
+if(!objectReplaced){if(object.includes('\n')){const lines=object.split('\n');lines.forEach(function(line,i){let text;let ioff;let ll;let ss;if(i===0){text='"'+line;ioff=0;ll=label;ss='';}else if(i<lines.length-1){text=line;ioff=1;ll='';ss='';}else{text=line+'"';ioff=1;ll='';ss=suffix;}
+const el=this.appendSimpleText_(ll,indent+ioff*label.length+ioff,text,ss);el.style.whiteSpace='pre';return el;},this);return;}
+if(object.match(URL_REGEX)){const link=document.createElement('a');link.href=object;link.textContent=object;this.appendElementWithLabel_(label,indent,link,suffix);return;}
 this.appendSimpleText_(label,indent,'"'+object+'"',suffix);return;}}
-if(object instanceof tr.model.ObjectSnapshot){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
-if(object instanceof tr.model.ObjectInstance){var link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.model.ObjectSnapshot){const link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
+if(object instanceof tr.model.ObjectInstance){const link=document.createElement('tr-ui-a-analysis-link');link.selection=new tr.model.EventSet(object);this.appendElementWithLabel_(label,indent,link,suffix);return;}
 if(object instanceof tr.b.math.Rect){this.appendSimpleText_(label,indent,object.toString(),suffix);return;}
-if(object instanceof tr.b.Scalar){var el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;el.inline=true;this.appendElementWithLabel_(label,indent,el,suffix);return;}
+if(object instanceof tr.b.Scalar){const el=this.ownerDocument.createElement('tr-v-ui-scalar-span');el.value=object;el.inline=true;this.appendElementWithLabel_(label,indent,el,suffix);return;}
 if(object instanceof Array){this.appendElementsForArray_(label,object,indent,depth,maxDepth,suffix);return;}
-this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_:function(label,object,indent,depth,maxDepth,suffix){if(object.length===0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
-if(isTable(object)){var table=document.createElement('tr-ui-b-table');var columns=[];for(let colName of Object.keys(object[0])){var allStrings=true;var allNumbers=true;for(var i=0;i<object.length;++i){if(typeof(object[i][colName])!=='string'){allStrings=false;}
+this.appendElementsForObject_(label,object,indent,depth,maxDepth,suffix);},appendElementsForArray_(label,object,indent,depth,maxDepth,suffix){if(object.length===0){this.appendSimpleText_(label,indent,'[]',suffix);return;}
+if(isTable(object)){const table=document.createElement('tr-ui-b-table');const columns=[];for(const colName of Object.keys(object[0])){let allStrings=true;let allNumbers=true;for(let i=0;i<object.length;++i){if(typeof(object[i][colName])!=='string'){allStrings=false;}
 if(typeof(object[i][colName])!=='number'){allNumbers=false;}
 if(!allStrings&&!allNumbers)break;}
-var column={title:colName};column.value=function(row){return row[colName];};if(allStrings){column.cmp=function(x,y){return x[colName].localeCompare(y[colName]);};}else if(allNumbers){column.cmp=function(x,y){return x[colName]-y[colName];};}
+const column={title:colName};column.value=function(row){return row[colName];};if(allStrings){column.cmp=function(x,y){return x[colName].localeCompare(y[colName]);};}else if(allNumbers){column.cmp=function(x,y){return x[colName]-y[colName];};}
 columns.push(column);}
 table.tableColumns=columns;table.tableRows=object;this.appendElementWithLabel_(label,indent,table,suffix);table.rebuild();return;}
-this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(var i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
-return;},appendElementsForObject_:function(label,object,indent,depth,maxDepth,suffix){var keys=Object.keys(object);if(keys.length===0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
-this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(var i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_:function(label,indent,dataElement,suffix){var row=document.createElement('div');var indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(var i=0;i<indent;i++){Polymer.dom(indentSpan).textContent+=' ';}
-Polymer.dom(row).appendChild(indentSpan);var labelSpan=document.createElement('span');Polymer.dom(labelSpan).textContent=label;Polymer.dom(row).appendChild(labelSpan);Polymer.dom(row).appendChild(dataElement);var suffixSpan=document.createElement('span');Polymer.dom(suffixSpan).textContent=suffix;Polymer.dom(row).appendChild(suffixSpan);row.dataElement=dataElement;Polymer.dom(this.$.content).appendChild(row);},appendSimpleText_:function(label,indent,text,suffix){var el=this.ownerDocument.createElement('span');Polymer.dom(el).textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer({is:'tr-ui-a-generic-object-view-with-label',ready:function(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');Polymer.dom(this.root).appendChild(this.labelEl_);Polymer.dom(this.root).appendChild(this.genericObjectView_);},get label(){return Polymer.dom(this.labelEl_).textContent;},set label(label){Polymer.dom(this.labelEl_).textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView,};});'use strict';Polymer({is:'tr-ui-b-drag-handle',created:function(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className===''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_){this.className='horizontal-drag-handle';}else{this.className='vertical-drag-handle';}},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_:function(){var records=this.observer_.takeRecords();if(records.length){this.didTargetMutate_(records);}},didTargetMutate_:function(e){var modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
-this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_:function(){var targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
-var size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_:function(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;tr.b.dispatchSimpleEvent(this,'drag-handle-resize',true,false);},applyDelta_:function(delta){var curSize=this.getTargetSize_();var newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
-this.setTargetSize_(newSize);},onMouseMove_:function(e){var curMousePos=this.horizontal_?e.clientY:e.clientX;var delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_:function(e){if(!this.target_)return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined){throw new Error('eventType must be given');}
+this.appendElementsForType_(label+'[',object[0],indent,depth+1,maxDepth,object.length>1?',':']'+suffix);for(let i=1;i<object.length;i++){this.appendElementsForType_('',object[i],indent+label.length+1,depth+1,maxDepth,i<object.length-1?',':']'+suffix);}
+return;},appendElementsForObject_(label,object,indent,depth,maxDepth,suffix){const keys=Object.keys(object);if(keys.length===0){this.appendSimpleText_(label,indent,'{}',suffix);return;}
+this.appendElementsForType_(label+'{'+keys[0]+': ',object[keys[0]],indent,depth,maxDepth,keys.length>1?',':'}'+suffix);for(let i=1;i<keys.length;i++){this.appendElementsForType_(keys[i]+': ',object[keys[i]],indent+label.length+1,depth+1,maxDepth,i<keys.length-1?',':'}'+suffix);}},appendElementWithLabel_(label,indent,dataElement,suffix){const row=document.createElement('div');const indentSpan=document.createElement('span');indentSpan.style.whiteSpace='pre';for(let i=0;i<indent;i++){Polymer.dom(indentSpan).textContent+=' ';}
+Polymer.dom(row).appendChild(indentSpan);const labelSpan=document.createElement('span');Polymer.dom(labelSpan).textContent=label;Polymer.dom(row).appendChild(labelSpan);Polymer.dom(row).appendChild(dataElement);const suffixSpan=document.createElement('span');Polymer.dom(suffixSpan).textContent=suffix;Polymer.dom(row).appendChild(suffixSpan);row.dataElement=dataElement;Polymer.dom(this.$.content).appendChild(row);},appendSimpleText_(label,indent,text,suffix){const el=this.ownerDocument.createElement('span');Polymer.dom(el).textContent=text;this.appendElementWithLabel_(label,indent,el,suffix);return el;}});'use strict';Polymer({is:'tr-ui-a-generic-object-view-with-label',ready(){this.labelEl_=document.createElement('div');this.genericObjectView_=document.createElement('tr-ui-a-generic-object-view');Polymer.dom(this.root).appendChild(this.labelEl_);Polymer.dom(this.root).appendChild(this.genericObjectView_);},get label(){return Polymer.dom(this.labelEl_).textContent;},set label(label){Polymer.dom(this.labelEl_).textContent=label;},get object(){return this.genericObjectView_.object;},set object(object){this.genericObjectView_.object=object;}});'use strict';tr.exportTo('tr.ui.analysis',function(){const ObjectSnapshotView=tr.ui.b.define('object-snapshot-view');ObjectSnapshotView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.objectSnapshot_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectSnapshot=obj;},get modelEvent(){return this.objectSnapshot;},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(i){this.objectSnapshot_=i;this.updateContents();},updateContents(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectSnapshotView;options.defaultMetadata={showInstances:true,showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectSnapshotView,options);return{ObjectSnapshotView,};});'use strict';Polymer({is:'tr-ui-b-drag-handle',created(){this.lastMousePos_=0;this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.target_=undefined;this.horizontal=true;this.observer_=new WebKitMutationObserver(this.didTargetMutate_.bind(this));this.targetSizesByModeKey_={};},get modeKey_(){return this.target_.className===''?'.':this.target_.className;},get target(){return this.target_;},set target(target){this.observer_.disconnect();this.target_=target;if(!this.target_)return;this.observer_.observe(this.target_,{attributes:true,attributeFilter:['class']});},get horizontal(){return this.horizontal_;},set horizontal(h){this.horizontal_=h;if(this.horizontal_){this.className='horizontal-drag-handle';}else{this.className='vertical-drag-handle';}},get vertical(){return!this.horizontal_;},set vertical(v){this.horizontal=!v;},forceMutationObserverFlush_(){const records=this.observer_.takeRecords();if(records.length){this.didTargetMutate_(records);}},didTargetMutate_(e){const modeSize=this.targetSizesByModeKey_[this.modeKey_];if(modeSize!==undefined){this.setTargetSize_(modeSize);return;}
+this.target_.style[this.targetStyleKey_]='';},get targetStyleKey_(){return this.horizontal_?'height':'width';},getTargetSize_(){const targetStyleKey=this.targetStyleKey_;if(!this.target_.style[targetStyleKey]){this.target_.style[targetStyleKey]=window.getComputedStyle(this.target_)[targetStyleKey];}
+const size=parseInt(this.target_.style[targetStyleKey]);this.targetSizesByModeKey_[this.modeKey_]=size;return size;},setTargetSize_(s){this.target_.style[this.targetStyleKey_]=s+'px';this.targetSizesByModeKey_[this.modeKey_]=s;tr.b.dispatchSimpleEvent(this,'drag-handle-resize',true,false);},applyDelta_(delta){const curSize=this.getTargetSize_();let newSize;if(this.target_===this.nextElementSibling){newSize=curSize+delta;}else{newSize=curSize-delta;}
+this.setTargetSize_(newSize);},onMouseMove_(e){const curMousePos=this.horizontal_?e.clientY:e.clientX;const delta=this.lastMousePos_-curMousePos;this.applyDelta_(delta);this.lastMousePos_=curMousePos;e.preventDefault();return true;},onMouseDown_(e){if(!this.target_)return;this.forceMutationObserverFlush_();this.lastMousePos_=this.horizontal_?e.clientY:e.clientX;document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);e.preventDefault();return true;},onMouseUp_(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);e.preventDefault();}});'use strict';tr.exportTo('tr.ui.b',function(){function HotKey(dict){if(dict.eventType===undefined){throw new Error('eventType must be given');}
 if(dict.keyCode===undefined&&dict.keyCodes===undefined){throw new Error('keyCode or keyCodes must be given');}
 if(dict.keyCode!==undefined&&dict.keyCodes!==undefined){throw new Error('Only keyCode or keyCodes can be given');}
 if(dict.callback===undefined){throw new Error('callback must be given');}
 this.eventType_=dict.eventType;this.keyCodes_=[];if(dict.keyCode){this.pushKeyCode_(dict.keyCode);}else if(dict.keyCodes){dict.keyCodes.forEach(this.pushKeyCode_,this);}
 this.useCapture_=!!dict.useCapture;this.callback_=dict.callback;this.thisArg_=dict.thisArg!==undefined?dict.thisArg:undefined;this.helpText_=dict.helpText!==undefined?dict.helpText:undefined;}
-HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call:function(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_:function(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey,};});'use strict';Polymer({is:'tv-ui-b-hotkey-controller',created:function(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached:function(){this.isAttached_=true;var host=this.findHost_();if(host.__hotkeyController){throw new Error('Multiple hotkey controllers attached to this host');}
-host.__hotkeyController=this;this.curHost_=host;var parentElement;if(host.parentElement){parentElement=host.parentElement;}else{parentElement=Polymer.dom(host).parentNode.host;}
-var parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
-host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached:function(){this.isAttached_=false;var host=this.curHost_;if(!host)return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
-host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i!==-1){throw new Error('Controller already registered');}
-this.childControllers_.push(controller);},removeChildController_:function(controller){var i=this.childControllers_.indexOf(controller);if(i===-1){throw new Error('Controller not registered');}
-this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_:function(eventType,useCapture){if(eventType==='keydown'){if(!useCapture){return this.bubblingKeyDownHotKeys_;}
+HotKey.prototype={get eventType(){return this.eventType_;},get keyCodes(){return this.keyCodes_;},get helpText(){return this.helpText_;},call(e){this.callback_.call(this.thisArg_,e);},pushKeyCode_(keyCode){this.keyCodes_.push(keyCode);}};return{HotKey,};});'use strict';Polymer({is:'tv-ui-b-hotkey-controller',created(){this.isAttached_=false;this.globalMode_=false;this.slavedToParentController_=undefined;this.curHost_=undefined;this.childControllers_=[];this.bubblingKeyDownHotKeys_={};this.capturingKeyDownHotKeys_={};this.bubblingKeyPressHotKeys_={};this.capturingKeyPressHotKeys_={};this.onBubblingKeyDown_=this.onKey_.bind(this,false);this.onCapturingKeyDown_=this.onKey_.bind(this,true);this.onBubblingKeyPress_=this.onKey_.bind(this,false);this.onCapturingKeyPress_=this.onKey_.bind(this,true);},attached(){this.isAttached_=true;const host=this.findHost_();if(host.__hotkeyController){throw new Error('Multiple hotkey controllers attached to this host');}
+host.__hotkeyController=this;this.curHost_=host;let parentElement;if(host.parentElement){parentElement=host.parentElement;}else{parentElement=Polymer.dom(host).parentNode.host;}
+const parentController=tr.b.getHotkeyControllerForElement(parentElement);if(parentController){this.slavedToParentController_=parentController;parentController.addChildController_(this);return;}
+host.addEventListener('keydown',this.onBubblingKeyDown_,false);host.addEventListener('keydown',this.onCapturingKeyDown_,true);host.addEventListener('keypress',this.onBubblingKeyPress_,false);host.addEventListener('keypress',this.onCapturingKeyPress_,true);},detached(){this.isAttached_=false;const host=this.curHost_;if(!host)return;delete host.__hotkeyController;this.curHost_=undefined;if(this.slavedToParentController_){this.slavedToParentController_.removeChildController_(this);this.slavedToParentController_=undefined;return;}
+host.removeEventListener('keydown',this.onBubblingKeyDown_,false);host.removeEventListener('keydown',this.onCapturingKeyDown_,true);host.removeEventListener('keypress',this.onBubblingKeyPress_,false);host.removeEventListener('keypress',this.onCapturingKeyPress_,true);},addChildController_(controller){const i=this.childControllers_.indexOf(controller);if(i!==-1){throw new Error('Controller already registered');}
+this.childControllers_.push(controller);},removeChildController_(controller){const i=this.childControllers_.indexOf(controller);if(i===-1){throw new Error('Controller not registered');}
+this.childControllers_.splice(i,1);return controller;},getKeyMapForEventType_(eventType,useCapture){if(eventType==='keydown'){if(!useCapture){return this.bubblingKeyDownHotKeys_;}
 return this.capturingKeyDownHotKeys_;}
 if(eventType==='keypress'){if(!useCapture){return this.bubblingKeyPressHotKeys_;}
 return this.capturingKeyPressHotKeys_;}
-throw new Error('Unsupported key event');},addHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
-var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(keyMap[keyCode]){throw new Error('Key is already bound for keyCode='+keyCode);}}
-for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
-return hotKey;},removeHotKey:function(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
-var keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode]){throw new Error('Key is not bound for keyCode='+keyCode);}
+throw new Error('Unsupported key event');},addHotKey(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
+const keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];if(keyMap[keyCode]){throw new Error('Key is already bound for keyCode='+keyCode);}}
+for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];keyMap[keyCode]=hotKey;}
+return hotKey;},removeHotKey(hotKey){if(!(hotKey instanceof tr.ui.b.HotKey)){throw new Error('hotKey must be a tr.ui.b.HotKey');}
+const keyMap=this.getKeyMapForEventType_(hotKey.eventType,hotKey.useCapture);for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];if(!keyMap[keyCode]){throw new Error('Key is not bound for keyCode='+keyCode);}
 keyMap[keyCode]=hotKey;}
-for(var i=0;i<hotKey.keyCodes.length;i++){var keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
-return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){var wasAttached=this.isAttached_;if(wasAttached){this.detached();}
+for(let i=0;i<hotKey.keyCodes.length;i++){const keyCode=hotKey.keyCodes[i];delete keyMap[keyCode];}
+return hotKey;},get globalMode(){return this.globalMode_;},set globalMode(globalMode){const wasAttached=this.isAttached_;if(wasAttached){this.detached();}
 this.globalMode_=!!globalMode;if(wasAttached){this.attached();}},get topmostConroller_(){if(this.slavedToParentController_){return this.slavedToParentController_.topmostConroller_;}
-return this;},childRequestsGeneralFocus:function(child){var topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement){document.activeElement.blur();}}}else{if(document.activeElement){document.activeElement.blur();}}},childRequestsBlur:function(child){child.blur();var topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_:function(){if(this.globalMode_)return document.body;if(this.parentElement)return this.parentElement;if(!Polymer.dom(this).parentNode)return this.host;let node=this.parentNode;while(Polymer.dom(node).parentNode)node=Polymer.dom(node).parentNode;return node.host;},appendMatchingHotKeysTo_:function(matchedHotKeys,useCapture,e){var localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);var localHotKey=localKeyMap[e.keyCode];if(localHotKey){matchedHotKeys.push(localHotKey);}
-for(var i=0;i<this.childControllers_.length;i++){var controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_:function(useCapture,e){if(!useCapture&&e.path[0].tagName==='INPUT')return;var sortedControllers;var matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
-var hotKey=matchedHotKeys[0];var prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){var curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller'){return curElement;}
+return this;},childRequestsGeneralFocus(child){const topmost=this.topmostConroller_;if(topmost.curHost_){if(topmost.curHost_.hasAttribute('tabIndex')){topmost.curHost_.focus();}else{if(document.activeElement){document.activeElement.blur();}}}else{if(document.activeElement){document.activeElement.blur();}}},childRequestsBlur(child){child.blur();const topmost=this.topmostConroller_;if(topmost.curHost_){topmost.curHost_.focus();}},findHost_(){if(this.globalMode_)return document.body;if(this.parentElement)return this.parentElement;if(!Polymer.dom(this).parentNode)return this.host;let node=this.parentNode;while(Polymer.dom(node).parentNode)node=Polymer.dom(node).parentNode;return node.host;},appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e){const localKeyMap=this.getKeyMapForEventType_(e.type,useCapture);const localHotKey=localKeyMap[e.keyCode];if(localHotKey){matchedHotKeys.push(localHotKey);}
+for(let i=0;i<this.childControllers_.length;i++){const controller=this.childControllers_[i];controller.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);}},onKey_(useCapture,e){if(!useCapture&&e.path[0].tagName==='INPUT')return;let sortedControllers;const matchedHotKeys=[];this.appendMatchingHotKeysTo_(matchedHotKeys,useCapture,e);if(matchedHotKeys.length===0)return false;if(matchedHotKeys.length>1){throw new Error('More than one hotKey is currently unsupported');}
+const hotKey=matchedHotKeys[0];let prevented=0;prevented|=hotKey.call(e);return!prevented&&e.defaultPrevented;}});'use strict';tr.exportTo('tr.b',function(){function getHotkeyControllerForElement(refElement){let curElement=refElement;while(curElement){if(curElement.tagName==='tv-ui-b-hotkey-controller'){return curElement;}
 if(curElement.__hotkeyController){return curElement.__hotkeyController;}
 if(curElement.parentElement){curElement=curElement.parentElement;continue;}
 curElement=findHost(curElement);}
 return undefined;}
-function findHost(initialNode){var node=initialNode;while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
+function findHost(initialNode){let node=initialNode;while(Polymer.dom(node).parentNode){node=Polymer.dom(node).parentNode;}
 return node.host;}
-return{getHotkeyControllerForElement,};});'use strict';Polymer({is:'tr-ui-b-info-bar',ready:function(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';},get message(){return Polymer.dom(this.messageEl_).textContent;},set message(message){Polymer.dom(this.messageEl_).textContent=message;},get visible(){return!this.hidden;},set visible(visible){this.hidden=!visible;},removeAllButtons:function(){Polymer.dom(this.buttonsEl_).textContent='';},addButton:function(text,clickCallback){var button=document.createElement('button');Polymer.dom(button).textContent=text;button.addEventListener('click',clickCallback);Polymer.dom(this.buttonsEl_).appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){var ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild:function(x){HTMLDivElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore:function(x,y){HTMLDivElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild:function(x){HTMLDivElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild:function(x,y){HTMLDivElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_:function(textContent){if(textContent!==''){throw new Error('textContent can only be set to \'\'.');}
-this.clear();},clear:function(){while(Polymer.dom(this).lastChild){HTMLDivElement.prototype.removeChild.call(this,Polymer.dom(this).lastChild);}
-this.didMutate_(this.observer_.takeRecords());},didMutate_:function(records){this.beginDecorating_();for(var i=0;i<records.length;i++){var addedNodes=records[i].addedNodes;if(addedNodes){for(var j=0;j<addedNodes.length;j++){this.decorateChild_(addedNodes[j]);}}
-var removedNodes=records[i].removedNodes;if(removedNodes){for(var j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
-this.doneDecoratingForNow_();},decorateChild_:function(child){throw new Error('Not implemented');},undecorateChild_:function(child){throw new Error('Not implemented');},beginDecorating_:function(){},doneDecoratingForNow_:function(){}};return{ContainerThatDecoratesItsChildren,};});'use strict';tr.exportTo('tr.ui.b',function(){var ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);Polymer.dom(this).classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_:function(item){Polymer.dom(item).classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);Object.defineProperty(item,'selected',{configurable:true,get:()=>item.hasAttribute('selected'),set:value=>{const oldSelection=this.selectedElement;if(oldSelection&&oldSelection!==item&&value){Polymer.dom(this.selectedElement).removeAttribute('selected');}
+return{getHotkeyControllerForElement,};});'use strict';Polymer({is:'tr-ui-b-info-bar',ready(){this.messageEl_=this.$.message;this.buttonsEl_=this.$.buttons;this.message='';},get message(){return Polymer.dom(this.messageEl_).textContent;},set message(message){Polymer.dom(this.messageEl_).textContent=message;},get visible(){return!this.hidden;},set visible(visible){this.hidden=!visible;},removeAllButtons(){Polymer.dom(this.buttonsEl_).textContent='';},addButton(text,clickCallback){const button=document.createElement('button');Polymer.dom(button).textContent=text;button.addEventListener('click',clickCallback);Polymer.dom(this.buttonsEl_).appendChild(button);return button;}});'use strict';tr.exportTo('tr.ui.b',function(){const ContainerThatDecoratesItsChildren=tr.ui.b.define('div');ContainerThatDecoratesItsChildren.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.observer_=new WebKitMutationObserver(this.didMutate_.bind(this));this.observer_.observe(this,{childList:true});Object.defineProperty(this,'textContent',{get:undefined,set:this.onSetTextContent_});},appendChild(x){HTMLDivElement.prototype.appendChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},insertBefore(x,y){HTMLDivElement.prototype.insertBefore.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},removeChild(x){HTMLDivElement.prototype.removeChild.call(this,x);this.didMutate_(this.observer_.takeRecords());},replaceChild(x,y){HTMLDivElement.prototype.replaceChild.call(this,x,y);this.didMutate_(this.observer_.takeRecords());},onSetTextContent_(textContent){if(textContent!==''){throw new Error('textContent can only be set to \'\'.');}
+this.clear();},clear(){while(Polymer.dom(this).lastChild){HTMLDivElement.prototype.removeChild.call(this,Polymer.dom(this).lastChild);}
+this.didMutate_(this.observer_.takeRecords());},didMutate_(records){this.beginDecorating_();for(let i=0;i<records.length;i++){const addedNodes=records[i].addedNodes;if(addedNodes){for(let j=0;j<addedNodes.length;j++){this.decorateChild_(addedNodes[j]);}}
+const removedNodes=records[i].removedNodes;if(removedNodes){for(let j=0;j<removedNodes.length;j++){this.undecorateChild_(removedNodes[j]);}}}
+this.doneDecoratingForNow_();},decorateChild_(child){throw new Error('Not implemented');},undecorateChild_(child){throw new Error('Not implemented');},beginDecorating_(){},doneDecoratingForNow_(){}};return{ContainerThatDecoratesItsChildren,};});'use strict';tr.exportTo('tr.ui.b',function(){const ListView=tr.ui.b.define('x-list-view',tr.ui.b.ContainerThatDecoratesItsChildren);ListView.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate(){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);Polymer.dom(this).classList.add('x-list-view');this.onItemClicked_=this.onItemClicked_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.tabIndex=0;this.addEventListener('keydown',this.onKeyDown_);this.selectionChanged_=false;},decorateChild_(item){Polymer.dom(item).classList.add('list-item');item.addEventListener('click',this.onItemClicked_,true);Object.defineProperty(item,'selected',{configurable:true,get:()=>item.hasAttribute('selected'),set:value=>{const oldSelection=this.selectedElement;if(oldSelection&&oldSelection!==item&&value){Polymer.dom(this.selectedElement).removeAttribute('selected');}
 if(value){Polymer.dom(item).setAttribute('selected','selected');}else{Polymer.dom(item).removeAttribute('selected');}
-const newSelection=this.selectedElement;if(newSelection!==oldSelection){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},});},undecorateChild_:function(item){this.selectionChanged_|=item.selected;Polymer.dom(item).classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_:function(){this.selectionChanged_=false;},doneDecoratingForNow_:function(){if(this.selectionChanged_){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},get selectedElement(){var el=Polymer.dom(this).querySelector('.list-item[selected]');if(!el)return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement){this.selectedElement.selected=false;}
+const newSelection=this.selectedElement;if(newSelection!==oldSelection){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},});},undecorateChild_(item){this.selectionChanged_|=item.selected;Polymer.dom(item).classList.remove('list-item');item.removeEventListener('click',this.onItemClicked_);delete item.selected;},beginDecorating_(){this.selectionChanged_=false;},doneDecoratingForNow_(){if(this.selectionChanged_){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},get selectedElement(){const el=Polymer.dom(this).querySelector('.list-item[selected]');if(!el)return undefined;return el;},set selectedElement(el){if(!el){if(this.selectedElement){this.selectedElement.selected=false;}
 return;}
 if(el.parentElement!==this){throw new Error('Can only select elements that are children of this list view');}
-el.selected=true;},getElementByIndex:function(index){return Polymer.dom(this).querySelector('.list-item:nth-child('+index+')');},clear:function(){var changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},onItemClicked_:function(e){var currentSelectedElement=this.selectedElement;if(currentSelectedElement){Polymer.dom(currentSelectedElement).removeAttribute('selected');}
-var element=e.target;while(element.parentElement!==this){element=element.parentElement;}
+el.selected=true;},getElementByIndex(index){return Polymer.dom(this).querySelector('.list-item:nth-child('+index+')');},clear(){const changed=this.selectedElement!==undefined;tr.ui.b.ContainerThatDecoratesItsChildren.prototype.clear.call(this);if(changed){tr.b.dispatchSimpleEvent(this,'selection-changed',false);}},onItemClicked_(e){const currentSelectedElement=this.selectedElement;if(currentSelectedElement){Polymer.dom(currentSelectedElement).removeAttribute('selected');}
+let element=e.target;while(element.parentElement!==this){element=element.parentElement;}
 if(element!==currentSelectedElement){Polymer.dom(element).setAttribute('selected','selected');}
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_:function(e){if(this.selectedElement===undefined)return;if(e.keyCode===38){var prev=Polymer.dom(this.selectedElement).previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode===40){var next=Polymer.dom(this.selectedElement).nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem:function(textContent){var item=document.createElement('div');Polymer.dom(item).textContent=textContent;Polymer.dom(this).appendChild(item);return item;}};return{ListView,};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;var MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE,};});'use strict';Polymer({is:'tr-ui-b-mouse-mode-icon',properties:{modeName:{type:String,reflectToAttribute:true,observer:'modeNameChanged'},},created:function(){this.active_=false;this.acceleratorKey_=undefined;},ready:function(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];var modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined){throw new Error('Unknown mode');}
-this.modeName=modeName;},modeNameChanged:function(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_){Polymer.dom(this).classList.add('active');}else{Polymer.dom(this).classList.remove('active');}
-this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_:function(){if(this.modeName===undefined)return;var mode=this.mode;if(mode===undefined){throw new Error('Invalid mode');}
-var modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo){throw new Error('Invalid mode');}
-var title=modeInfo.title;if(this.acceleratorKey_){title=title+' ('+this.acceleratorKey_+')';}
-this.title=title;var bp;if(this.active_){bp=modeInfo.activeBackgroundPosition;}else{bp=modeInfo.defaultBackgroundPosition;}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onKeyDown_(e){if(this.selectedElement===undefined)return;if(e.keyCode===38){const prev=Polymer.dom(this.selectedElement).previousSibling;if(prev){prev.selected=true;tr.ui.b.scrollIntoViewIfNeeded(prev);e.preventDefault();return true;}}else if(e.keyCode===40){const next=Polymer.dom(this.selectedElement).nextSibling;if(next){next.selected=true;tr.ui.b.scrollIntoViewIfNeeded(next);e.preventDefault();return true;}}},addItem(textContent){const item=document.createElement('div');Polymer.dom(item).textContent=textContent;Polymer.dom(this).appendChild(item);return item;}};return{ListView,};});'use strict';tr.exportTo('tr.ui.b',function(){const MOUSE_SELECTOR_MODE={};MOUSE_SELECTOR_MODE.SELECTION=0x1;MOUSE_SELECTOR_MODE.PANSCAN=0x2;MOUSE_SELECTOR_MODE.ZOOM=0x4;MOUSE_SELECTOR_MODE.TIMING=0x8;MOUSE_SELECTOR_MODE.ROTATE=0x10;MOUSE_SELECTOR_MODE.ALL_MODES=0x1F;const MOUSE_SELECTOR_MODE_INFOS={};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.PANSCAN]={mode:MOUSE_SELECTOR_MODE.PANSCAN,title:'pan',eventNames:{enter:'enterpan',begin:'beginpan',update:'updatepan',end:'endpan',exit:'exitpan'},activeBackgroundPosition:'-30px -10px',defaultBackgroundPosition:'0 -10px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION]={mode:MOUSE_SELECTOR_MODE.SELECTION,title:'selection',eventNames:{enter:'enterselection',begin:'beginselection',update:'updateselection',end:'endselection',exit:'exitselection'},activeBackgroundPosition:'-30px -40px',defaultBackgroundPosition:'0 -40px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ZOOM]={mode:MOUSE_SELECTOR_MODE.ZOOM,title:'zoom',eventNames:{enter:'enterzoom',begin:'beginzoom',update:'updatezoom',end:'endzoom',exit:'exitzoom'},activeBackgroundPosition:'-30px -70px',defaultBackgroundPosition:'0 -70px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.TIMING]={mode:MOUSE_SELECTOR_MODE.TIMING,title:'timing',eventNames:{enter:'entertiming',begin:'begintiming',update:'updatetiming',end:'endtiming',exit:'exittiming'},activeBackgroundPosition:'-30px -100px',defaultBackgroundPosition:'0 -100px'};MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.ROTATE]={mode:MOUSE_SELECTOR_MODE.ROTATE,title:'rotate',eventNames:{enter:'enterrotate',begin:'beginrotate',update:'updaterotate',end:'endrotate',exit:'exitrotate'},activeBackgroundPosition:'-30px -130px',defaultBackgroundPosition:'0 -130px'};return{MOUSE_SELECTOR_MODE_INFOS,MOUSE_SELECTOR_MODE,};});'use strict';Polymer({is:'tr-ui-b-mouse-mode-icon',properties:{modeName:{type:String,reflectToAttribute:true,observer:'modeNameChanged'},},created(){this.active_=false;this.acceleratorKey_=undefined;},ready(){this.updateContents_();},get mode(){return tr.ui.b.MOUSE_SELECTOR_MODE[this.modeName];},set mode(mode){const modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];const modeName=tr.b.findFirstKeyInDictMatching(tr.ui.b.MOUSE_SELECTOR_MODE,function(modeName,candidateMode){return candidateMode===mode;});if(modeName===undefined){throw new Error('Unknown mode');}
+this.modeName=modeName;},modeNameChanged(){this.updateContents_();},get active(){return this.active_;},set active(active){this.active_=!!active;if(this.active_){Polymer.dom(this).classList.add('active');}else{Polymer.dom(this).classList.remove('active');}
+this.updateContents_();},get acceleratorKey(){return this.acceleratorKey_;},set acceleratorKey(acceleratorKey){this.acceleratorKey_=acceleratorKey;this.updateContents_();},updateContents_(){if(this.modeName===undefined)return;const mode=this.mode;if(mode===undefined){throw new Error('Invalid mode');}
+const modeInfo=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS[mode];if(!modeInfo){throw new Error('Invalid mode');}
+let title=modeInfo.title;if(this.acceleratorKey_){title=title+' ('+this.acceleratorKey_+')';}
+this.title=title;let bp;if(this.active_){bp=modeInfo.activeBackgroundPosition;}else{bp=modeInfo.defaultBackgroundPosition;}
 this.style.backgroundPosition=bp;}});'use strict';tr.exportTo('tr.ui.b',function(){function MouseTracker(opt_targetElement){this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.targetElement=opt_targetElement;}
 MouseTracker.prototype={get targetElement(){return this.targetElement_;},set targetElement(targetElement){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
-this.targetElement_=targetElement;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},onMouseDown_:function(e){if(e.button!==0)return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_:function(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_:function(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_:function(e,newType){var remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.removeEventListener('keyup',opt_keyUpHandler);}
+this.targetElement_=targetElement;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},onMouseDown_(e){if(e.button!==0)return true;e=this.remakeEvent_(e,'mouse-tracker-start');this.targetElement_.dispatchEvent(e);document.addEventListener('mousemove',this.onMouseMove_);document.addEventListener('mouseup',this.onMouseUp_);this.targetElement_.addEventListener('blur',this.onMouseUp_);this.savePreviousUserSelect_=document.body.style['-webkit-user-select'];document.body.style['-webkit-user-select']='none';e.preventDefault();return true;},onMouseMove_(e){e=this.remakeEvent_(e,'mouse-tracker-move');this.targetElement_.dispatchEvent(e);},onMouseUp_(e){document.removeEventListener('mousemove',this.onMouseMove_);document.removeEventListener('mouseup',this.onMouseUp_);this.targetElement_.removeEventListener('blur',this.onMouseUp_);document.body.style['-webkit-user-select']=this.savePreviousUserSelect_;e=this.remakeEvent_(e,'mouse-tracker-end');this.targetElement_.dispatchEvent(e);},remakeEvent_(e,newType){const remade=new tr.b.Event(newType,true,true);remade.x=e.x;remade.y=e.y;remade.offsetX=e.offsetX;remade.offsetY=e.offsetY;remade.clientX=e.clientX;remade.clientY=e.clientY;return remade;}};function trackMouseMovesUntilMouseUp(mouseMoveHandler,opt_mouseUpHandler,opt_keyUpHandler){function cleanupAndDispatchToMouseUp(e){document.removeEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.removeEventListener('keyup',opt_keyUpHandler);}
 document.removeEventListener('mouseup',cleanupAndDispatchToMouseUp);if(opt_mouseUpHandler){opt_mouseUpHandler(e);}}
 document.addEventListener('mousemove',mouseMoveHandler);if(opt_keyUpHandler){document.addEventListener('keyup',opt_keyUpHandler);}
 document.addEventListener('mouseup',cleanupAndDispatchToMouseUp);}
-return{MouseTracker,trackMouseMovesUntilMouseUp,};});'use strict';tr.exportTo('tr.ui.b',function(){var MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;var MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;var MIN_MOUSE_SELECTION_DISTANCE=4;var MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)return event.metaKey;return event.ctrlKey;}
-Polymer({is:'tr-ui-b-mouse-mode-selector',created:function(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready:function(){this.buttonsEl_=Polymer.dom(this.root).querySelector('.buttons');this.dragHandleEl_=Polymer.dom(this.root).querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached:function(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached:function(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
-this.targetElement_=target;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)return;var mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined){mode=undefined;}
+return{MouseTracker,trackMouseMovesUntilMouseUp,};});'use strict';tr.exportTo('tr.ui.b',function(){const MOUSE_SELECTOR_MODE=tr.ui.b.MOUSE_SELECTOR_MODE;const MOUSE_SELECTOR_MODE_INFOS=tr.ui.b.MOUSE_SELECTOR_MODE_INFOS;const MIN_MOUSE_SELECTION_DISTANCE=4;const MODIFIER={SHIFT:0x1,SPACE:0x2,CMD_OR_CTRL:0x4};function isCmdOrCtrlPressed(event){if(tr.isMac)return event.metaKey;return event.ctrlKey;}
+Polymer({is:'tr-ui-b-mouse-mode-selector',created(){this.supportedModeMask_=MOUSE_SELECTOR_MODE.ALL_MODES;this.initialRelativeMouseDownPos_={x:0,y:0};this.defaultMode_=MOUSE_SELECTOR_MODE.PANSCAN;this.settingsKey_=undefined;this.mousePos_={x:0,y:0};this.mouseDownPos_={x:0,y:0};this.onMouseDown_=this.onMouseDown_.bind(this);this.onMouseMove_=this.onMouseMove_.bind(this);this.onMouseUp_=this.onMouseUp_.bind(this);this.onKeyDown_=this.onKeyDown_.bind(this);this.onKeyUp_=this.onKeyUp_.bind(this);this.mode_=undefined;this.modeToKeyCodeMap_={};this.modifierToModeMap_={};this.targetElement_=undefined;this.modeBeforeAlternativeModeActivated_=null;this.isInteracting_=false;this.isClick_=false;},ready(){this.buttonsEl_=Polymer.dom(this.root).querySelector('.buttons');this.dragHandleEl_=Polymer.dom(this.root).querySelector('.drag-handle');this.supportedModeMask=MOUSE_SELECTOR_MODE.ALL_MODES;this.dragHandleEl_.addEventListener('mousedown',this.onDragHandleMouseDown_.bind(this));this.buttonsEl_.addEventListener('mouseup',this.onButtonMouseUp_);this.buttonsEl_.addEventListener('mousedown',this.onButtonMouseDown_);this.buttonsEl_.addEventListener('click',this.onButtonPress_.bind(this));},attached(){document.addEventListener('keydown',this.onKeyDown_);document.addEventListener('keyup',this.onKeyUp_);},detached(){document.removeEventListener('keydown',this.onKeyDown_);document.removeEventListener('keyup',this.onKeyUp_);},get targetElement(){return this.targetElement_;},set targetElement(target){if(this.targetElement_){this.targetElement_.removeEventListener('mousedown',this.onMouseDown_);}
+this.targetElement_=target;if(this.targetElement_){this.targetElement_.addEventListener('mousedown',this.onMouseDown_);}},get defaultMode(){return this.defaultMode_;},set defaultMode(defaultMode){this.defaultMode_=defaultMode;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(!this.settingsKey_)return;let mode=tr.b.Settings.get(this.settingsKey_+'.mode',undefined);if(MOUSE_SELECTOR_MODE_INFOS[mode]===undefined){mode=undefined;}
 if((mode&this.supportedModeMask_)===0){mode=undefined;}
-if(!mode)mode=this.defaultMode_;this.mode=mode;var pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0){throw new Error('supportedModeMask must include current mode.');}
+if(!mode)mode=this.defaultMode_;this.mode=mode;const pos=tr.b.Settings.get(this.settingsKey_+'.pos',undefined);if(pos)this.pos=pos;},get supportedModeMask(){return this.supportedModeMask_;},set supportedModeMask(supportedModeMask){if(this.mode&&(supportedModeMask&this.mode)===0){throw new Error('supportedModeMask must include current mode.');}
 function createButtonForMode(mode){return button;}
-this.supportedModeMask_=supportedModeMask;Polymer.dom(this.buttonsEl_).textContent='';for(var modeName in MOUSE_SELECTOR_MODE){if(modeName==='ALL_MODES')continue;var mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)continue;var button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;Polymer.dom(button).classList.add('tool-button');Polymer.dom(this.buttonsEl_).appendChild(button);}},getButtonForMode_:function(mode){for(var i=0;i<this.buttonsEl_.children.length;i++){var buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode){return buttonEl;}}
+this.supportedModeMask_=supportedModeMask;Polymer.dom(this.buttonsEl_).textContent='';for(const modeName in MOUSE_SELECTOR_MODE){if(modeName==='ALL_MODES')continue;const mode=MOUSE_SELECTOR_MODE[modeName];if((this.supportedModeMask_&mode)===0)continue;const button=document.createElement('tr-ui-b-mouse-mode-icon');button.mode=mode;Polymer.dom(button).classList.add('tool-button');Polymer.dom(this.buttonsEl_).appendChild(button);}},getButtonForMode_(mode){for(let i=0;i<this.buttonsEl_.children.length;i++){const buttonEl=this.buttonsEl_.children[i];if(buttonEl.mode===mode){return buttonEl;}}
 return undefined;},get mode(){return this.currentMode_;},set mode(newMode){if(newMode!==undefined){if(typeof newMode!=='number'){throw new Error('Mode must be a number');}
 if((newMode&this.supportedModeMask_)===0){throw new Error('Cannot switch to this mode, it is not supported');}
 if(MOUSE_SELECTOR_MODE_INFOS[newMode]===undefined){throw new Error('Unrecognized mode');}}
-var modeInfo;if(this.currentMode_===newMode)return;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=false;if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
+let modeInfo;if(this.currentMode_===newMode)return;if(this.currentMode_){const buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=false;if(this.isInteracting_){const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end);this.dispatchEvent(mouseEvent);}
 modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.exit,true);}
-this.currentMode_=newMode;if(this.currentMode_){var buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_){tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);}
-if(this.isInteracting_){var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
-if(this.settingsKey_&&!this.isInAlternativeMode_){tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);}},setKeyCodeForMode:function(mode,keyCode){if((mode&this.supportedModeMask_)===0){throw new Error('Mode not supported');}
-this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)return;var buttonEl=this.getButtonForMode_(mode);if(buttonEl){buttonEl.acceleratorKey=String.fromCharCode(keyCode);}},setCurrentMousePosFromEvent_:function(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_:function(eventName,sourceEvent){var event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent){sourceEvent.preventDefault();}};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_:function(e){if(e.button!==0)return;this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION){mouseEvent.appendSelection=isCmdOrCtrlPressed(e);}
-this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_:function(e){this.setCurrentMousePosFromEvent_(e);var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_){this.checkIsClick_(e);}},onMouseUp_:function(e){if(e.button!==0)return;var mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault){this.dispatchClickEvents_(e);}
-this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_:function(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_:function(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_:function(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=true;}
-this.updateAlternativeModeState_(e);},onKeyUp_:function(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=false;}
-var didHandleKey=false;for(var[modeStr,keyCode]of Object.entries(this.modeToKeyCodeMap_)){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;var mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}}
+this.currentMode_=newMode;if(this.currentMode_){const buttonEl=this.getButtonForMode_(this.currentMode_);if(buttonEl)buttonEl.active=true;this.mouseDownPos_.x=this.mousePos_.x;this.mouseDownPos_.y=this.mousePos_.y;modeInfo=MOUSE_SELECTOR_MODE_INFOS[this.currentMode_];if(!this.isInAlternativeMode_){tr.b.dispatchSimpleEvent(this,modeInfo.eventNames.enter,true);}
+if(this.isInteracting_){const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin);this.dispatchEvent(mouseEvent);}}
+if(this.settingsKey_&&!this.isInAlternativeMode_){tr.b.Settings.set(this.settingsKey_+'.mode',this.mode);}},setKeyCodeForMode(mode,keyCode){if((mode&this.supportedModeMask_)===0){throw new Error('Mode not supported');}
+this.modeToKeyCodeMap_[mode]=keyCode;if(!this.buttonsEl_)return;const buttonEl=this.getButtonForMode_(mode);if(buttonEl){buttonEl.acceleratorKey=String.fromCharCode(keyCode);}},setCurrentMousePosFromEvent_(e){this.mousePos_.x=e.clientX;this.mousePos_.y=e.clientY;},createEvent_(eventName,sourceEvent){const event=new tr.b.Event(eventName,true);event.clientX=this.mousePos_.x;event.clientY=this.mousePos_.y;event.deltaX=this.mousePos_.x-this.mouseDownPos_.x;event.deltaY=this.mousePos_.y-this.mouseDownPos_.y;event.mouseDownX=this.mouseDownPos_.x;event.mouseDownY=this.mouseDownPos_.y;event.didPreventDefault=false;event.preventDefault=function(){event.didPreventDefault=true;if(sourceEvent){sourceEvent.preventDefault();}};event.stopPropagation=function(){sourceEvent.stopPropagation();};event.stopImmediatePropagation=function(){throw new Error('Not implemented');};return event;},onMouseDown_(e){if(e.button!==0)return;this.setCurrentMousePosFromEvent_(e);const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.begin,e);if(this.mode===MOUSE_SELECTOR_MODE.SELECTION){mouseEvent.appendSelection=isCmdOrCtrlPressed(e);}
+this.dispatchEvent(mouseEvent);this.isInteracting_=true;this.isClick_=true;tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_,this.onMouseUp_);},onMouseMove_(e){this.setCurrentMousePosFromEvent_(e);const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.update,e);this.dispatchEvent(mouseEvent);if(this.isInteracting_){this.checkIsClick_(e);}},onMouseUp_(e){if(e.button!==0)return;const mouseEvent=this.createEvent_(MOUSE_SELECTOR_MODE_INFOS[this.mode].eventNames.end,e);mouseEvent.isClick=this.isClick_;this.dispatchEvent(mouseEvent);if(this.isClick_&&!mouseEvent.didPreventDefault){this.dispatchClickEvents_(e);}
+this.isInteracting_=false;this.updateAlternativeModeState_(e);},onButtonMouseDown_(e){e.preventDefault();e.stopImmediatePropagation();},onButtonMouseUp_(e){e.preventDefault();e.stopImmediatePropagation();},onButtonPress_(e){this.modeBeforeAlternativeModeActivated_=undefined;this.mode=e.target.mode;e.preventDefault();},onKeyDown_(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=true;}
+this.updateAlternativeModeState_(e);},onKeyUp_(e){if(e.path[0].tagName==='INPUT')return;if(e.keyCode===' '.charCodeAt(0)){this.spacePressed_=false;}
+let didHandleKey=false;for(const[modeStr,keyCode]of Object.entries(this.modeToKeyCodeMap_)){if(e.keyCode===keyCode){this.modeBeforeAlternativeModeActivated_=undefined;const mode=parseInt(modeStr);this.mode=mode;didHandleKey=true;}}
 if(didHandleKey){e.preventDefault();e.stopPropagation();return;}
-this.updateAlternativeModeState_(e);},updateAlternativeModeState_:function(e){var shiftPressed=e.shiftKey;var spacePressed=this.spacePressed_;var cmdOrCtrlPressed=isCmdOrCtrlPressed(e);var smm=this.supportedModeMask_;var newMode;var isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
+this.updateAlternativeModeState_(e);},updateAlternativeModeState_(e){const shiftPressed=e.shiftKey;const spacePressed=this.spacePressed_;const cmdOrCtrlPressed=isCmdOrCtrlPressed(e);const smm=this.supportedModeMask_;let newMode;let isNewModeAnAlternativeMode=false;if(shiftPressed&&(this.modifierToModeMap_[MODIFIER.SHIFT]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SHIFT];isNewModeAnAlternativeMode=true;}else if(spacePressed&&(this.modifierToModeMap_[MODIFIER.SPACE]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.SPACE];isNewModeAnAlternativeMode=true;}else if(cmdOrCtrlPressed&&(this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL]&smm)!==0){newMode=this.modifierToModeMap_[MODIFIER.CMD_OR_CTRL];isNewModeAnAlternativeMode=true;}else{if(this.isInAlternativeMode_){newMode=this.modeBeforeAlternativeModeActivated_;isNewModeAnAlternativeMode=false;}else{newMode=undefined;}}
 if(this.mode===newMode||newMode===undefined)return;if(isNewModeAnAlternativeMode){this.modeBeforeAlternativeModeActivated_=this.mode;}
-this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode:function(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_){tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);}},constrainPositionToBounds_:function(pos){var parent=this.offsetParent||document.body;var parentRect=tr.ui.b.windowRectForElement(parent);var top=0;var bottom=parentRect.height-this.offsetHeight;var left=0;var right=parentRect.width-this.offsetWidth;var res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_:function(e){e.preventDefault();e.stopImmediatePropagation();var mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){var pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_:function(e){if(!this.isInteracting_||!this.isClick_)return;var deltaX=this.mousePos_.x-this.mouseDownPos_.x;var deltaY=this.mousePos_.y-this.mouseDownPos_.y;var minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist){this.isClick_=false;}},dispatchClickEvents_:function(e){if(!this.isClick_)return;var modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];var eventNames=modeInfo.eventNames;var mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE,MODIFIER,};});'use strict';(function(){var DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer({is:'tr-ui-e-chrome-cc-display-item-list-item',created:function(){Polymer.dom(this).setAttribute('name','');Polymer.dom(this).setAttribute('rawDetails','');Polymer.dom(this).setAttribute('richDetails',undefined);Polymer.dom(this).setAttribute('data_',undefined);},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){var match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation:function(e){e.stopPropagation();},_computeIf:function(richDetails){return richDetails&&richDetails.skp64;},_computeHref:function(richDetails){return'data:application/octet-stream;base64,'+richDetails.skp64;}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;}
-Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis:function(){throw new Error('Not implemented');},findEquivalent:function(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined)){throw new Error('Render pass (with id) is required');}
+this.mode=newMode;},get isInAlternativeMode_(){return!!this.modeBeforeAlternativeModeActivated_;},setModifierForAlternateMode(mode,modifier){this.modifierToModeMap_[modifier]=mode;},get pos(){return{x:parseInt(this.style.left),y:parseInt(this.style.top)};},set pos(pos){pos=this.constrainPositionToBounds_(pos);this.style.left=pos.x+'px';this.style.top=pos.y+'px';if(this.settingsKey_){tr.b.Settings.set(this.settingsKey_+'.pos',this.pos);}},constrainPositionToBounds_(pos){const parent=this.offsetParent||document.body;const parentRect=tr.ui.b.windowRectForElement(parent);const top=0;const bottom=parentRect.height-this.offsetHeight;const left=0;const right=parentRect.width-this.offsetWidth;const res={};res.x=Math.max(pos.x,left);res.x=Math.min(res.x,right);res.y=Math.max(pos.y,top);res.y=Math.min(res.y,bottom);return res;},onDragHandleMouseDown_(e){e.preventDefault();e.stopImmediatePropagation();const mouseDownPos={x:e.clientX-this.offsetLeft,y:e.clientY-this.offsetTop};tr.ui.b.trackMouseMovesUntilMouseUp(function(e){const pos={};pos.x=e.clientX-mouseDownPos.x;pos.y=e.clientY-mouseDownPos.y;this.pos=pos;}.bind(this));},checkIsClick_(e){if(!this.isInteracting_||!this.isClick_)return;const deltaX=this.mousePos_.x-this.mouseDownPos_.x;const deltaY=this.mousePos_.y-this.mouseDownPos_.y;const minDist=MIN_MOUSE_SELECTION_DISTANCE;if(deltaX*deltaX+deltaY*deltaY>minDist*minDist){this.isClick_=false;}},dispatchClickEvents_(e){if(!this.isClick_)return;const modeInfo=MOUSE_SELECTOR_MODE_INFOS[MOUSE_SELECTOR_MODE.SELECTION];const eventNames=modeInfo.eventNames;let mouseEvent=this.createEvent_(eventNames.begin);mouseEvent.appendSelection=isCmdOrCtrlPressed(e);this.dispatchEvent(mouseEvent);mouseEvent=this.createEvent_(eventNames.end);this.dispatchEvent(mouseEvent);}});return{MIN_MOUSE_SELECTION_DISTANCE,MODIFIER,};});'use strict';(function(){const DETAILS_SPLIT_REGEX=/^(\S*)\s*([\S\s]*)$/;Polymer({is:'tr-ui-e-chrome-cc-display-item-list-item',created(){Polymer.dom(this).setAttribute('name','');Polymer.dom(this).setAttribute('rawDetails','');Polymer.dom(this).setAttribute('richDetails',undefined);Polymer.dom(this).setAttribute('data_',undefined);},get data(){return this.data_;},set data(data){this.data_=data;if(!data){this.name='DATA MISSING';this.rawDetails='';this.richDetails=undefined;}else if(typeof data==='string'){const match=data.match(DETAILS_SPLIT_REGEX);this.name=match[1];this.rawDetails=match[2];this.richDetails=undefined;}else{this.name=data.name;this.rawDetails='';this.richDetails=data;}},stopPropagation(e){e.stopPropagation();},_computeIf(richDetails){return richDetails&&richDetails.skp64;},_computeHref(richDetails){return'data:application/octet-stream;base64,'+richDetails.skp64;}});})();'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function Selection(){this.selectionToSetIfClicked=undefined;}
+Selection.prototype={get specicifity(){throw new Error('Not implemented');},get associatedLayerId(){throw new Error('Not implemented');},get associatedRenderPassId(){throw new Error('Not implemented');},get highlightsByLayerId(){return{};},createAnalysis(){throw new Error('Not implemented');},findEquivalent(lthi){throw new Error('Not implemented');}};function RenderPassSelection(renderPass,renderPassId){if(!renderPass||(renderPassId===undefined)){throw new Error('Render pass (with id) is required');}
 this.renderPass_=renderPass;this.renderPassId_=renderPassId;}
-RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer){throw new Error('Layer is required');}
+RenderPassSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return undefined;},get associatedRenderPassId(){return this.renderPassId_;},get renderPass(){return this.renderPass_;},createAnalysis(){const dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='RenderPass '+this.renderPassId_;dataView.object=this.renderPass_.args;return dataView;},get title(){return this.renderPass_.objectInstance.typeName;}};function LayerSelection(layer){if(!layer){throw new Error('Layer is required');}
 this.layer_=layer;}
-LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis:function(){var dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization){dataView.label+=' (GPU-rasterized)';}
-dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent:function(lthi){var layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
-TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
+LayerSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 1;},get associatedLayerId(){return this.layer_.layerId;},get associatedRenderPassId(){return undefined;},get layer(){return this.layer_;},createAnalysis(){const dataView=document.createElement('tr-ui-a-generic-object-view-with-label');dataView.label='Layer '+this.layer_.layerId;if(this.layer_.usingGpuRasterization){dataView.label+=' (GPU-rasterized)';}
+dataView.object=this.layer_.args;return dataView;},get title(){return this.layer_.objectInstance.typeName;},findEquivalent(lthi){const layer=lthi.activeTree.findLayerWithId(this.layer_.layerId)||lthi.pendingTree.findLayerWithId(this.layer_.layerId);if(!layer)return undefined;return new LayerSelection(layer);}};function TileSelection(tile,opt_data){this.tile_=tile;this.data_=opt_data||{};}
+TileSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.tile_.layerId;},get highlightsByLayerId(){const highlights={};highlights[this.tile_.layerId]=[{colorKey:this.tile_.objectInstance.typeName,rect:this.tile_.layerRect}];return highlights;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Tile '+this.tile_.objectInstance.id+' on layer '+
 this.tile_.layerId;if(this.data_){analysis.object={moreInfo:this.data_,tileArgs:this.tile_.args};}else{analysis.object=this.tile_.args;}
-return analysis;},findEquivalent:function(lthi){var tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs){return undefined;}
-var tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
-LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){var highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent:function(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
-AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis:function(){var analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection,RenderPassSelection,LayerSelection,TileSelection,LayerRectSelection,AnimationRectSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var ANNOTATION='Comment';var BEGIN_ANNOTATION='BeginCommentGroup';var END_ANNOTATION='EndCommentGroup';var ANNOTATION_ID='ID: ';var ANNOTATION_CLASS='CLASS: ';var ANNOTATION_TAG='TAG: ';var constants=tr.e.cc.constants;var PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.opsList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_:function(){this.opsList_.clear();if(!this.picture_)return;var ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(var i=0;i<ops.length;i++){var op=ops[i];var item=document.createElement('div');item.opIndex=op.opIndex;Polymer.dom(item).textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){var elementInfo=document.createElement('span');Polymer.dom(elementInfo).classList.add('elementInfo');var tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';var id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;var className=op.elementInfo.class?'class='+
+return analysis;},findEquivalent(lthi){const tileInstance=this.tile_.tileInstance;if(lthi.ts<tileInstance.creationTs||lthi.ts>=tileInstance.deletionTs){return undefined;}
+const tileSnapshot=tileInstance.getSnapshotAt(lthi.ts);if(!tileSnapshot)return undefined;return new TileSelection(tileSnapshot);}};function LayerRectSelection(layer,rectType,rect,opt_data){this.layer_=layer;this.rectType_=rectType;this.rect_=rect;this.data_=opt_data!==undefined?opt_data:rect;}
+LayerRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 2;},get associatedLayerId(){return this.layer_.layerId;},get highlightsByLayerId(){const highlights={};highlights[this.layer_.layerId]=[{colorKey:this.rectType_,rect:this.rect_}];return highlights;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label=this.rectType_+' on layer '+this.layer_.layerId;analysis.object=this.data_;return analysis;},findEquivalent(lthi){return undefined;}};function AnimationRectSelection(layer,rect){this.layer_=layer;this.rect_=rect;}
+AnimationRectSelection.prototype={__proto__:Selection.prototype,get specicifity(){return 0;},get associatedLayerId(){return this.layer_.layerId;},createAnalysis(){const analysis=document.createElement('tr-ui-a-generic-object-view-with-label');analysis.label='Animation Bounds of layer '+this.layer_.layerId;analysis.object=this.rect_;return analysis;}};return{Selection,RenderPassSelection,LayerSelection,TileSelection,LayerRectSelection,AnimationRectSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const OPS_TIMING_ITERATIONS=3;const ANNOTATION='Comment';const BEGIN_ANNOTATION='BeginCommentGroup';const END_ANNOTATION='EndCommentGroup';const ANNOTATION_ID='ID: ';const ANNOTATION_CLASS='CLASS: ';const ANNOTATION_TAG='TAG: ';const constants=tr.e.cc.constants;const PictureOpsListView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-list-view');PictureOpsListView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.opsList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.opsList_);this.selectedOp_=undefined;this.selectedOpIndex_=undefined;this.opsList_.addEventListener('selection-changed',this.onSelectionChanged_.bind(this));this.picture_=undefined;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.updateContents_();},updateContents_(){this.opsList_.clear();if(!this.picture_)return;let ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);ops=this.opsTaggedWithAnnotations_(ops);for(let i=0;i<ops.length;i++){const op=ops[i];const item=document.createElement('div');item.opIndex=op.opIndex;Polymer.dom(item).textContent=i+') '+op.cmd_string;if(op.elementInfo.tag||op.elementInfo.id||op.elementInfo.class){const elementInfo=document.createElement('span');Polymer.dom(elementInfo).classList.add('elementInfo');const tag=op.elementInfo.tag?op.elementInfo.tag:'unknown';const id=op.elementInfo.id?'id='+op.elementInfo.id:undefined;const className=op.elementInfo.class?'class='+
 op.elementInfo.class:undefined;Polymer.dom(elementInfo).textContent='<'+tag+(id?' ':'')+
 (id?id:'')+(className?' ':'')+
 (className?className:'')+'>';Polymer.dom(item).appendChild(elementInfo);}
-if(op.info.length>0){var infoItem=document.createElement('div');Polymer.dom(infoItem).textContent=JSON.stringify(op.info);Polymer.dom(item).appendChild(infoItem);}
-if(op.cmd_time&&op.cmd_time>=0.0001){var time=document.createElement('span');Polymer.dom(time).classList.add('time');var rounded=op.cmd_time.toFixed(4);Polymer.dom(time).textContent='('+rounded+'ms)';Polymer.dom(item).appendChild(time);}
-Polymer.dom(this.opsList_).appendChild(item);}},onSelectionChanged_:function(e){var beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
-this.selectedOp_=this.opsList_.selectedElement;var ops=this.opsList_.children;for(var i=0;i<ops.length;i++){var op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){Polymer.dom(op).setAttribute('beforeSelection','beforeSelection');}else{Polymer.dom(op).removeAttribute('beforeSelection');}}
-tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_:function(ops){var annotationGroups=[];var opsWithoutAnnotations=[];for(var opIndex=0;opIndex<ops.length;opIndex++){var op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push([]);break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:var annotations=[];var elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.includes(ANNOTATION_TAG)){elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
+if(op.info.length>0){const infoItem=document.createElement('div');Polymer.dom(infoItem).textContent=JSON.stringify(op.info);Polymer.dom(item).appendChild(infoItem);}
+if(op.cmd_time&&op.cmd_time>=0.0001){const time=document.createElement('span');Polymer.dom(time).classList.add('time');const rounded=op.cmd_time.toFixed(4);Polymer.dom(time).textContent='('+rounded+'ms)';Polymer.dom(item).appendChild(time);}
+Polymer.dom(this.opsList_).appendChild(item);}},onSelectionChanged_(e){let beforeSelectedOp=true;if(this.opsList_.selectedElement===this.selectedOp_){this.opsList_.selectedElement=undefined;beforeSelectedOp=false;this.selectedOpIndex_=undefined;}
+this.selectedOp_=this.opsList_.selectedElement;const ops=this.opsList_.children;for(let i=0;i<ops.length;i++){const op=ops[i];if(op===this.selectedOp_){beforeSelectedOp=false;this.selectedOpIndex_=op.opIndex;}else if(beforeSelectedOp){Polymer.dom(op).setAttribute('beforeSelection','beforeSelection');}else{Polymer.dom(op).removeAttribute('beforeSelection');}}
+tr.b.dispatchSimpleEvent(this,'selection-changed',false);},get numOps(){return this.opsList_.children.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(s){this.selectedOpIndex_=s;if(s===undefined){this.opsList_.selectedElement=this.selectedOp_;this.onSelectionChanged_();}else{if(s<0)throw new Error('Invalid index');if(s>=this.numOps)throw new Error('Invalid index');this.opsList_.selectedElement=this.opsList_.getElementByIndex(s+1);tr.ui.b.scrollIntoViewIfNeeded(this.opsList_.selectedElement);}},opsTaggedWithAnnotations_(ops){const annotationGroups=[];const opsWithoutAnnotations=[];for(let opIndex=0;opIndex<ops.length;opIndex++){const op=ops[opIndex];op.opIndex=opIndex;switch(op.cmd_string){case BEGIN_ANNOTATION:annotationGroups.push([]);break;case END_ANNOTATION:annotationGroups.pop();break;case ANNOTATION:annotationGroups[annotationGroups.length-1].push(op);break;default:{const annotations=[];let elementInfo={};annotationGroups.forEach(function(annotationGroup){elementInfo={};annotationGroup.forEach(function(annotation){annotation.info.forEach(function(info){if(info.includes(ANNOTATION_TAG)){elementInfo.tag=info.substring(info.indexOf(ANNOTATION_TAG)+
 ANNOTATION_TAG.length).toLowerCase();}else if(info.includes(ANNOTATION_ID)){elementInfo.id=info.substring(info.indexOf(ANNOTATION_ID)+
 ANNOTATION_ID.length);}else if(info.includes(ANNOTATION_CLASS)){elementInfo.class=info.substring(info.indexOf(ANNOTATION_CLASS)+
 ANNOTATION_CLASS.length);}
-annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}
-return opsWithoutAnnotations;}};return{PictureOpsListView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=Polymer.dom(this).querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));Polymer.dom(this.displayItemInfo_).appendChild(this.displayItemListView_);this.displayListFilename_=Polymer.dom(this).querySelector('.dlfilename');this.displayListExportButton_=Polymer.dom(this).querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=Polymer.dom(this).querySelector('.skpfilename');this.skpExportButton_=Polymer.dom(this).querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));var leftPanel=Polymer.dom(this).querySelector('left-panel');var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=Polymer.dom(this).querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).insertBefore(this.infoBar_,this.rasterCanvas_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();Polymer.dom(rightPanel).insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;Polymer.dom(rightPanel).insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){var listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;Polymer.dom(this.displayItemListView_).appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;var showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
-var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=parseInt(style.width);var height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
-return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
+annotations.push(info);});});});op.annotations=annotations;op.elementInfo=elementInfo;opsWithoutAnnotations.push(op);}}}
+return opsWithoutAnnotations;}};return{PictureOpsListView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const THIS_DOC=document.currentScript.ownerDocument;const DisplayItemDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-debugger');DisplayItemDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate(){const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-display-item-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.pictureAsImageData_=undefined;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.trackMouse_();this.displayItemInfo_=Polymer.dom(this).querySelector('display-item-info');this.displayItemInfo_.addEventListener('click',this.onDisplayItemInfoClick_.bind(this),false);this.displayItemListView_=new tr.ui.b.ListView();this.displayItemListView_.addEventListener('selection-changed',this.onDisplayItemListSelection_.bind(this));Polymer.dom(this.displayItemInfo_).appendChild(this.displayItemListView_);this.displayListFilename_=Polymer.dom(this).querySelector('.dlfilename');this.displayListExportButton_=Polymer.dom(this).querySelector('.dlexport');this.displayListExportButton_.addEventListener('click',this.onExportDisplayListClicked_.bind(this));this.skpFilename_=Polymer.dom(this).querySelector('.skpfilename');this.skpExportButton_=Polymer.dom(this).querySelector('.skpexport');this.skpExportButton_.addEventListener('click',this.onExportSkPictureClicked_.bind(this));const leftPanel=Polymer.dom(this).querySelector('left-panel');const middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;const rightPanel=Polymer.dom(this).querySelector('right-panel');this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).insertBefore(this.infoBar_,this.rasterCanvas_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;this.pictureOpsListView_=new tr.ui.e.chrome.cc.PictureOpsListView();Polymer.dom(rightPanel).insertBefore(this.pictureOpsListView_,this.rasterArea_);this.pictureOpsListDragHandle_=document.createElement('tr-ui-b-drag-handle');this.pictureOpsListDragHandle_.horizontal=false;this.pictureOpsListDragHandle_.target=this.pictureOpsListView_;Polymer.dom(rightPanel).insertBefore(this.pictureOpsListDragHandle_,this.rasterArea_);},get picture(){return this.picture_;},set displayItemList(displayItemList){this.displayItemList_=displayItemList;this.picture=this.displayItemList_;this.displayItemListView_.clear();this.displayItemList_.items.forEach(function(item){const listItem=document.createElement('tr-ui-e-chrome-cc-display-item-list-item');listItem.data=item;Polymer.dom(this.displayItemListView_).appendChild(listItem);}.bind(this));},set picture(picture){this.picture_=picture;const showOpsList=picture&&picture!==this.displayItemList_;this.updateDrawOpsList_(showOpsList);if(picture){const size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+const bounds=this.rasterArea_.getBoundingClientRect();const selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_(){const style=window.getComputedStyle(this.rasterArea_);let width=parseInt(style.width);let height=parseInt(style.height);if(this.picture_){width=Math.max(width,this.picture_.layerRect.width);height=Math.max(height,this.picture_.layerRect.height);}
+return{width,height};},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
 this.picture_.layerRect.width+' x '+
 this.picture_.layerRect.height+')';}
-if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
-this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
+if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_(){const size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
 if(size.height!==this.rasterCanvas_.height){this.rasterCanvas_.height=size.height;}
-this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_:function(e){var selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
-var index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);var displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64){this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);}else{this.picture=undefined;}},onDisplayItemInfoClick_:function(e){if(e&&e.target===this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_:function(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){Polymer.dom(this.pictureOpsListView_).classList.add('hasPictureOps');Polymer.dom(this.pictureOpsListDragHandle_).classList.add('hasPictureOps');}}else{Polymer.dom(this.pictureOpsListView_).classList.remove('hasPictureOps');Polymer.dom(this.pictureOpsListDragHandle_).classList.remove('hasPictureOps');}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_:function(filename,rawData){if(!rawData)return;var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
-var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.URL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_:function(){var rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();Polymer.dom(this).appendChild(this.displayItemDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.displayItemDebugger_){this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;var LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));Polymer.dom(this.controls_).appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;var showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');Polymer.dom(showPureTransformLayers).classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';Polymer.dom(this.controls_).appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree===RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_:function(){if(!this.lthiSnapshot_)return[];var renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses){return renderPassInfo;}
-var renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(var i=0;i<renderPasses.length;++i){var info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
-return renderPassInfo;},getLayerInfos_:function(){if(!this.lthiSnapshot_)return[];var tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)return[];var layerInfos=[];var showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!==1&&layer.args.compositingReasons[0]!=='No reasons given'){return false;}
+this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.picture_||!this.pictureAsImageData_.imageData)return;const imgCanvas=this.pictureAsImageData_.asCanvas();const w=imgCanvas.width;const h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_(){if(this.picture_){this.picture_.rasterize({showOverdraw:false},this.onRasterComplete_.bind(this));}},onRasterComplete_(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},onDisplayItemListSelection_(e){const selected=this.displayItemListView_.selectedElement;if(!selected){this.picture=this.displayItemList_;return;}
+const index=Array.prototype.indexOf.call(this.displayItemListView_.children,selected);const displayItem=this.displayItemList_.items[index];if(displayItem&&displayItem.skp64){this.picture=new tr.e.cc.Picture(displayItem.skp64,this.displayItemList_.layerRect);}else{this.picture=undefined;}},onDisplayItemInfoClick_(e){if(e&&e.target===this.displayItemInfo_){this.displayItemListView_.selectedElement=undefined;}},updateDrawOpsList_(showOpsList){if(showOpsList){this.pictureOpsListView_.picture=this.picture_;if(this.pictureOpsListView_.numOps>0){Polymer.dom(this.pictureOpsListView_).classList.add('hasPictureOps');Polymer.dom(this.pictureOpsListDragHandle_).classList.add('hasPictureOps');}}else{Polymer.dom(this.pictureOpsListView_).classList.remove('hasPictureOps');Polymer.dom(this.pictureOpsListDragHandle_).classList.remove('hasPictureOps');}},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};},saveFile_(filename,rawData){if(!rawData)return;const length=rawData.length;const arrayBuffer=new ArrayBuffer(length);const uint8Array=new Uint8Array(arrayBuffer);for(let c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
+const blob=new Blob([uint8Array],{type:'application/octet-binary'});const blobUrl=window.URL.createObjectURL(blob);const link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=filename;const event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},onExportDisplayListClicked_(){const rawData=JSON.stringify(this.displayItemList_.items);this.saveFile_(this.displayListFilename_.value,rawData);},onExportSkPictureClicked_(){const rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());this.saveFile_(this.skpFilename_.value,rawData);}};return{DisplayItemDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const DisplayItemSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-display-item-list-view',tr.ui.analysis.ObjectSnapshotView);DisplayItemSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-display-item-list-view');this.displayItemDebugger_=new tr.ui.e.chrome.cc.DisplayItemDebugger();Polymer.dom(this).appendChild(this.displayItemDebugger_);},updateContents(){if(this.objectSnapshot_&&this.displayItemDebugger_){this.displayItemDebugger_.displayItemList=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(DisplayItemSnapshotView,{typeNames:['cc::DisplayItemList'],showInstances:false});return{DisplayItemSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const constants=tr.e.cc.constants;const RENDER_PASS_QUADS=Math.max(constants.ACTIVE_TREE,constants.PENDING_TREE)+1;const LayerPicker=tr.ui.b.define('tr-ui-e-chrome-cc-layer-picker');LayerPicker.prototype={__proto__:HTMLUnknownElement.prototype,decorate(){this.lthi_=undefined;this.controls_=document.createElement('top-controls');this.renderPassQuads_=false;this.itemList_=new tr.ui.b.ListView();Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.itemList_);this.itemList_.addEventListener('selection-changed',this.onItemSelectionChanged_.bind(this));Polymer.dom(this.controls_).appendChild(tr.ui.b.createSelector(this,'whichTree','layerPicker.whichTree',constants.ACTIVE_TREE,[{label:'Active tree',value:constants.ACTIVE_TREE},{label:'Pending tree',value:constants.PENDING_TREE},{label:'Render pass quads',value:RENDER_PASS_QUADS}]));this.showPureTransformLayers_=false;const showPureTransformLayers=tr.ui.b.createCheckBox(this,'showPureTransformLayers','layerPicker.showPureTransformLayers',false,'Transform layers');Polymer.dom(showPureTransformLayers).classList.add('show-transform-layers');showPureTransformLayers.title='When checked, pure transform layers are shown';Polymer.dom(this.controls_).appendChild(showPureTransformLayers);},get lthiSnapshot(){return this.lthiSnapshot_;},set lthiSnapshot(lthiSnapshot){this.lthiSnapshot_=lthiSnapshot;this.updateContents_();},get whichTree(){return this.renderPassQuads_?constants.ACTIVE_TREE:this.whichTree_;},set whichTree(whichTree){this.whichTree_=whichTree;this.renderPassQuads_=(whichTree===RENDER_PASS_QUADS);this.updateContents_();tr.b.dispatchSimpleEvent(this,'selection-change',false);},get layerTreeImpl(){if(this.lthiSnapshot===undefined)return undefined;return this.lthiSnapshot.getTree(this.whichTree);},get isRenderPassQuads(){return this.renderPassQuads_;},get showPureTransformLayers(){return this.showPureTransformLayers_;},set showPureTransformLayers(show){if(this.showPureTransformLayers_===show)return;this.showPureTransformLayers_=show;this.updateContents_();},getRenderPassInfos_(){if(!this.lthiSnapshot_)return[];const renderPassInfo=[];if(!this.lthiSnapshot_.args.frame||!this.lthiSnapshot_.args.frame.renderPasses){return renderPassInfo;}
+const renderPasses=this.lthiSnapshot_.args.frame.renderPasses;for(let i=0;i<renderPasses.length;++i){const info={renderPass:renderPasses[i],depth:0,id:i,name:'cc::RenderPass'};renderPassInfo.push(info);}
+return renderPassInfo;},getLayerInfos_(){if(!this.lthiSnapshot_)return[];const tree=this.lthiSnapshot_.getTree(this.whichTree_);if(!tree)return[];const layerInfos=[];const showPureTransformLayers=this.showPureTransformLayers_;function isPureTransformLayer(layer){if(layer.args.compositingReasons&&layer.args.compositingReasons.length!==1&&layer.args.compositingReasons[0]!=='No reasons given'){return false;}
 if(layer.args.drawsContent)return false;return true;}
-var visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;var info={layer:layer,depth:depth};if(layer.args.drawsContent){info.name=layer.objectInstance.name;}else{info.name='cc::LayerImpl';}
+const visitedLayers={};function visitLayer(layer,depth,isMask,isReplica){if(visitedLayers[layer.layerId])return;visitedLayers[layer.layerId]=true;const info={layer,depth};if(layer.args.drawsContent){info.name=layer.objectInstance.name;}else{info.name='cc::LayerImpl';}
 if(layer.usingGpuRasterization){info.name+=' (G)';}
 info.isMaskLayer=isMask;info.replicaLayer=isReplica;if(showPureTransformLayers||!isPureTransformLayer(layer)){layerInfos.push(info);}}
-tree.iterLayers(visitLayer);return layerInfos;},updateContents_:function(){if(this.renderPassQuads_){this.updateRenderPassContents_();}else{this.updateLayerContents_();}},updateRenderPassContents_:function(){this.itemList_.clear();var selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId){selectedRenderPassId=this.selection_.associatedRenderPassId;}
-var renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){var renderPass=renderPassInfo.renderPass;var id=renderPassInfo.id;var item=this.createElementWithDepth_(renderPassInfo.depth);var labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;Polymer.dom(this.itemList_).appendChild(item);if(id===selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_:function(){this.changingItemSelection_=true;try{this.itemList_.clear();var selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId){selectedLayerId=this.selection_.associatedLayerId;}
-var layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){var layer=layerInfo.layer;var id=layer.layerId;var item=this.createElementWithDepth_(layerInfo.depth);var labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=layerInfo.name+' '+id;var notesEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer){Polymer.dom(notesEl).textContent+='(mask)';}
+tree.iterLayers(visitLayer);return layerInfos;},updateContents_(){if(this.renderPassQuads_){this.updateRenderPassContents_();}else{this.updateLayerContents_();}},updateRenderPassContents_(){this.itemList_.clear();let selectedRenderPassId;if(this.selection_&&this.selection_.associatedRenderPassId){selectedRenderPassId=this.selection_.associatedRenderPassId;}
+const renderPassInfos=this.getRenderPassInfos_();renderPassInfos.forEach(function(renderPassInfo){const renderPass=renderPassInfo.renderPass;const id=renderPassInfo.id;const item=this.createElementWithDepth_(renderPassInfo.depth);const labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=renderPassInfo.name+' '+id;item.renderPass=renderPass;item.renderPassId=id;Polymer.dom(this.itemList_).appendChild(item);if(id===selectedRenderPassId){renderPass.selectionState=tr.model.SelectionState.SELECTED;}},this);},updateLayerContents_(){this.changingItemSelection_=true;try{this.itemList_.clear();let selectedLayerId;if(this.selection_&&this.selection_.associatedLayerId){selectedLayerId=this.selection_.associatedLayerId;}
+const layerInfos=this.getLayerInfos_();layerInfos.forEach(function(layerInfo){const layer=layerInfo.layer;const id=layer.layerId;const item=this.createElementWithDepth_(layerInfo.depth);const labelEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());Polymer.dom(labelEl).textContent=layerInfo.name+' '+id;const notesEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());if(layerInfo.isMaskLayer){Polymer.dom(notesEl).textContent+='(mask)';}
 if(layerInfo.isReplicaLayer){Polymer.dom(notesEl).textContent+='(replica)';}
-if((layer.gpuMemoryUsageInBytes!==undefined)&&(layer.gpuMemoryUsageInBytes>0)){var gpuUsageStr=tr.b.Unit.byName.sizeInBytes.format(layer.gpuMemoryUsageInBytes);Polymer.dom(notesEl).textContent+=' ('+gpuUsageStr+' MiB)';}
-item.layer=layer;Polymer.dom(this.itemList_).appendChild(item);if(layer.layerId===selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_:function(depth){var item=document.createElement('div');var indentEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(var i=0;i<depth;i++){Polymer.dom(indentEl).textContent=Polymer.dom(indentEl).textContent+' ';}
-return item;},onItemSelectionChanged_:function(e){if(this.changingItemSelection_)return;if(this.renderPassQuads_){this.onRenderPassSelected_(e);}else{this.onLayerSelected_(e);}
-tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_:function(e){var selectedRenderPass;var selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
-if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_:function(e){var selectedLayer;if(this.itemList_.selectedElement){selectedLayer=this.itemList_.selectedElement.layer;}
-if(selectedLayer){this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);}else{this.selection_=undefined;}},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.updateContents_();}};return{LayerPicker,};});'use strict';tr.exportTo('tr.e.cc',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
-RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){tr.e.cc.preInitializeObject(this);},initialize:function(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.subTypes.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){let deg2rad=tr.b.math.deg2rad;var constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};var Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate:function(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){var mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var aspectRatio=rect.width/rect.height;var matrix=mat4.create();mat4.perspective(matrix,deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){var gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings:function(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings:function(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera:function(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];var settings=tr.b.SessionSettings();var keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
-if(this.deviceRect_){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
-this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta:function(delta){var rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);var eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];var length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);var halfFov=constants.FOV/2;var multiplier=2.0*length*Math.tan(deg2rad(halfFov))/rect.height;var up=[0,1,0];var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);var right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(var i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
-if(Math.abs(this.gazeTarget_[2])>1e-6){var gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];var newLength=tr.b.math.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(var i=0;i<3;++i){this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}}
-this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta:function(delta){var deltaY=delta[1];deltaY=tr.b.math.clamp(deltaY,-50,50);var scale=1.0-deltaY/100.0;var eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE){scale=constants.MINIMUM_DISTANCE/length;}else if(length*scale>constants.MAXIMUM_DISTANCE){scale=constants.MAXIMUM_DISTANCE/length;}
-vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta:function(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT){return;}
+if((layer.gpuMemoryUsageInBytes!==undefined)&&(layer.gpuMemoryUsageInBytes>0)){const gpuUsageStr=tr.b.Unit.byName.sizeInBytes.format(layer.gpuMemoryUsageInBytes);Polymer.dom(notesEl).textContent+=' ('+gpuUsageStr+' MiB)';}
+item.layer=layer;Polymer.dom(this.itemList_).appendChild(item);if(layer.layerId===selectedLayerId){layer.selectionState=tr.model.SelectionState.SELECTED;item.selected=true;}},this);}finally{this.changingItemSelection_=false;}},createElementWithDepth_(depth){const item=document.createElement('div');const indentEl=Polymer.dom(item).appendChild(tr.ui.b.createSpan());indentEl.style.whiteSpace='pre';for(let i=0;i<depth;i++){Polymer.dom(indentEl).textContent=Polymer.dom(indentEl).textContent+' ';}
+return item;},onItemSelectionChanged_(e){if(this.changingItemSelection_)return;if(this.renderPassQuads_){this.onRenderPassSelected_(e);}else{this.onLayerSelected_(e);}
+tr.b.dispatchSimpleEvent(this,'selection-change',false);},onRenderPassSelected_(e){let selectedRenderPass;let selectedRenderPassId;if(this.itemList_.selectedElement){selectedRenderPass=this.itemList_.selectedElement.renderPass;selectedRenderPassId=this.itemList_.selectedElement.renderPassId;}
+if(selectedRenderPass){this.selection_=new tr.ui.e.chrome.cc.RenderPassSelection(selectedRenderPass,selectedRenderPassId);}else{this.selection_=undefined;}},onLayerSelected_(e){let selectedLayer;if(this.itemList_.selectedElement){selectedLayer=this.itemList_.selectedElement.layer;}
+if(selectedLayer){this.selection_=new tr.ui.e.chrome.cc.LayerSelection(selectedLayer);}else{this.selection_=undefined;}},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.updateContents_();}};return{LayerPicker,};});'use strict';tr.exportTo('tr.e.cc',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function RenderPassSnapshot(){ObjectSnapshot.apply(this,arguments);}
+RenderPassSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){tr.e.cc.preInitializeObject(this);},initialize(){tr.e.cc.moveRequiredFieldsFromArgsToToplevel(this,['quadList']);}};ObjectSnapshot.subTypes.register(RenderPassSnapshot,{typeName:'cc::RenderPass'});return{RenderPassSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const deg2rad=tr.b.math.deg2rad;const constants={DEFAULT_SCALE:0.5,DEFAULT_EYE_DISTANCE:10000,MINIMUM_DISTANCE:1000,MAXIMUM_DISTANCE:100000,FOV:15,RESCALE_TIMEOUT_MS:200,MAXIMUM_TILT:80,SETTINGS_NAMESPACE:'tr.ui_camera'};const Camera=tr.ui.b.define('camera');Camera.prototype={__proto__:HTMLUnknownElement.prototype,decorate(eventSource){this.eventSource_=eventSource;this.eventSource_.addEventListener('beginpan',this.onPanBegin_.bind(this));this.eventSource_.addEventListener('updatepan',this.onPanUpdate_.bind(this));this.eventSource_.addEventListener('endpan',this.onPanEnd_.bind(this));this.eventSource_.addEventListener('beginzoom',this.onZoomBegin_.bind(this));this.eventSource_.addEventListener('updatezoom',this.onZoomUpdate_.bind(this));this.eventSource_.addEventListener('endzoom',this.onZoomEnd_.bind(this));this.eventSource_.addEventListener('beginrotate',this.onRotateBegin_.bind(this));this.eventSource_.addEventListener('updaterotate',this.onRotateUpdate_.bind(this));this.eventSource_.addEventListener('endrotate',this.onRotateEnd_.bind(this));this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];this.pixelRatio_=window.devicePixelRatio||1;},get modelViewMatrix(){const mvMatrix=mat4.create();mat4.lookAt(mvMatrix,this.eye_,this.gazeTarget_,[0,1,0]);return mvMatrix;},get projectionMatrix(){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);const aspectRatio=rect.width/rect.height;const matrix=mat4.create();mat4.perspective(matrix,deg2rad(constants.FOV),aspectRatio,1,100000);return matrix;},set canvas(c){this.canvas_=c;},set deviceRect(rect){this.deviceRect_=rect;},get stackingDistanceDampening(){const gazeVector=[this.gazeTarget_[0]-this.eye_[0],this.gazeTarget_[1]-this.eye_[1],this.gazeTarget_[2]-this.eye_[2]];vec3.normalize(gazeVector,gazeVector);return 1+gazeVector[2];},loadCameraFromSettings(settings){this.eye_=settings.get('eye',this.eye_,constants.SETTINGS_NAMESPACE);this.gazeTarget_=settings.get('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);this.rotation_=settings.get('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);this.dispatchRenderEvent_();},saveCameraToSettings(settings){settings.set('eye',this.eye_,constants.SETTINGS_NAMESPACE);settings.set('gaze_target',this.gazeTarget_,constants.SETTINGS_NAMESPACE);settings.set('rotation',this.rotation_,constants.SETTINGS_NAMESPACE);},resetCamera(){this.eye_=[0,0,constants.DEFAULT_EYE_DISTANCE];this.gazeTarget_=[0,0,0];this.rotation_=[0,0];const settings=tr.b.SessionSettings();const keys=settings.keys(constants.SETTINGS_NAMESPACE);if(keys.length!==0){this.loadCameraFromSettings(settings);return;}
+if(this.deviceRect_){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);this.eye_[0]=this.deviceRect_.width/2;this.eye_[1]=this.deviceRect_.height/2;this.gazeTarget_[0]=this.deviceRect_.width/2;this.gazeTarget_[1]=this.deviceRect_.height/2;}
+this.saveCameraToSettings(settings);this.dispatchRenderEvent_();},updatePanByDelta(delta){const rect=tr.ui.b.windowRectForElement(this.canvas_).scaleSize(this.pixelRatio_);const eyeVector=[this.eye_[0]-this.gazeTarget_[0],this.eye_[1]-this.gazeTarget_[1],this.eye_[2]-this.gazeTarget_[2]];const length=vec3.length(eyeVector);vec3.normalize(eyeVector,eyeVector);const halfFov=constants.FOV/2;const multiplier=2.0*length*Math.tan(deg2rad(halfFov))/rect.height;const up=[0,1,0];const rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec3.transformMat4(up,up,rotMatrix);const right=[0,0,0];vec3.cross(right,eyeVector,up);vec3.normalize(right,right);for(let i=0;i<3;++i){this.gazeTarget_[i]+=delta[0]*multiplier*right[i]-delta[1]*multiplier*up[i];this.eye_[i]=this.gazeTarget_[i]+length*eyeVector[i];}
+if(Math.abs(this.gazeTarget_[2])>1e-6){const gazeVector=[-eyeVector[0],-eyeVector[1],-eyeVector[2]];const newLength=tr.b.math.clamp(-this.eye_[2]/gazeVector[2],constants.MINIMUM_DISTANCE,constants.MAXIMUM_DISTANCE);for(let i=0;i<3;++i){this.gazeTarget_[i]=this.eye_[i]+newLength*gazeVector[i];}}
+this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateZoomByDelta(delta){let deltaY=delta[1];deltaY=tr.b.math.clamp(deltaY,-50,50);let scale=1.0-deltaY/100.0;const eyeVector=[0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);const length=vec3.length(eyeVector);if(length*scale<constants.MINIMUM_DISTANCE){scale=constants.MINIMUM_DISTANCE/length;}else if(length*scale>constants.MAXIMUM_DISTANCE){scale=constants.MAXIMUM_DISTANCE/length;}
+vec3.scale(eyeVector,eyeVector,scale);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},updateRotateByDelta(delta){delta[0]*=0.5;delta[1]*=0.5;if(Math.abs(this.rotation_[0]+delta[1])>constants.MAXIMUM_TILT){return;}
 if(Math.abs(this.rotation_[1]-delta[0])>constants.MAXIMUM_TILT){return;}
-var eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);var rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_:function(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_:function(e){if(!this.panning_)return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_:function(e){this.panning_=false;},onZoomBegin_:function(e){this.zooming_=true;var p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_:function(e){if(!this.zooming_)return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_:function(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_:function(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_:function(e){if(!this.rotating_)return;var delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_:function(e){this.rotating_=false;},getMousePosition_:function(e){var rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_:function(e,p){var newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_:function(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera,};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;var constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){var tmpP0=[p0[0],p0[1]];var tmpP1=[p1[0],p1[1]];var tmpP2=[p2[0],p2[1]];var tmpT0=[t0[0],t0[1]];var tmpT1=[t1[0],t1[1]];var tmpT2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmpP0[0],tmpP0[1]);ctx.lineTo(tmpP1[0],tmpP1[1]);ctx.lineTo(tmpP2[0],tmpP2[1]);ctx.closePath();tmpP1[0]-=tmpP0[0];tmpP1[1]-=tmpP0[1];tmpP2[0]-=tmpP0[0];tmpP2[1]-=tmpP0[1];tmpT1[0]-=tmpT0[0];tmpT1[1]-=tmpT0[1];tmpT2[0]-=tmpT0[0];tmpT2[1]-=tmpT0[1];var det=1/(tmpT1[0]*tmpT2[1]-tmpT2[0]*tmpT1[1]);var a=(tmpT2[1]*tmpP1[0]-tmpT1[1]*tmpP2[0])*det;var b=(tmpT2[1]*tmpP1[1]-tmpT1[1]*tmpP2[1])*det;var c=(tmpT1[0]*tmpP2[0]-tmpT2[0]*tmpP1[0])*det;var d=(tmpT1[0]*tmpP2[1]-tmpT2[0]*tmpP1[1])*det;var e=tmpP0[0]-a*tmpT0[0]-c*tmpT0[1];var f=tmpP0[1]-b*tmpT0[0]-d*tmpT0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
-function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursionDepth){var depth=opt_recursionDepth||0;var subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=1;}
+const eyeVector=[0,0,0,0];vec3.subtract(eyeVector,this.eye_,this.gazeTarget_);const rotMatrix=mat4.create();mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[0]),[1,0,0]);mat4.rotate(rotMatrix,rotMatrix,-deg2rad(this.rotation_[1]),[0,1,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);this.rotation_[0]+=delta[1];this.rotation_[1]-=delta[0];mat4.identity(rotMatrix);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[1]),[0,1,0]);mat4.rotate(rotMatrix,rotMatrix,deg2rad(this.rotation_[0]),[1,0,0]);vec4.transformMat4(eyeVector,eyeVector,rotMatrix);vec3.add(this.eye_,this.gazeTarget_,eyeVector);this.saveCameraToSettings(tr.b.SessionSettings());this.dispatchRenderEvent_();},onPanBegin_(e){this.panning_=true;this.lastMousePosition_=this.getMousePosition_(e);},onPanUpdate_(e){if(!this.panning_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updatePanByDelta(delta);},onPanEnd_(e){this.panning_=false;},onZoomBegin_(e){this.zooming_=true;const p=this.getMousePosition_(e);this.lastMousePosition_=p;this.zoomPoint_=p;},onZoomUpdate_(e){if(!this.zooming_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateZoomByDelta(delta);},onZoomEnd_(e){this.zooming_=false;this.zoomPoint_=undefined;},onRotateBegin_(e){this.rotating_=true;this.lastMousePosition_=this.getMousePosition_(e);},onRotateUpdate_(e){if(!this.rotating_)return;const delta=this.getMouseDelta_(e,this.lastMousePosition_);this.lastMousePosition_=this.getMousePosition_(e);this.updateRotateByDelta(delta);},onRotateEnd_(e){this.rotating_=false;},getMousePosition_(e){const rect=tr.ui.b.windowRectForElement(this.canvas_);return[(e.clientX-rect.x)*this.pixelRatio_,(e.clientY-rect.y)*this.pixelRatio_];},getMouseDelta_(e,p){const newP=this.getMousePosition_(e);return[newP[0]-p[0],newP[1]-p[1]];},dispatchRenderEvent_(){tr.b.dispatchSimpleEvent(this,'renderrequired',false,false);}};return{Camera,};});'use strict';tr.exportTo('tr.ui.b',function(){const THIS_DOC=document.currentScript.ownerDocument;const constants={};constants.IMAGE_LOAD_RETRY_TIME_MS=500;constants.SUBDIVISION_MINIMUM=1;constants.SUBDIVISION_RECURSION_DEPTH=3;constants.SUBDIVISION_DEPTH_THRESHOLD=100;constants.FAR_PLANE_DISTANCE=10000;function drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2){const tmpP0=[p0[0],p0[1]];const tmpP1=[p1[0],p1[1]];const tmpP2=[p2[0],p2[1]];const tmpT0=[t0[0],t0[1]];const tmpT1=[t1[0],t1[1]];const tmpT2=[t2[0],t2[1]];ctx.beginPath();ctx.moveTo(tmpP0[0],tmpP0[1]);ctx.lineTo(tmpP1[0],tmpP1[1]);ctx.lineTo(tmpP2[0],tmpP2[1]);ctx.closePath();tmpP1[0]-=tmpP0[0];tmpP1[1]-=tmpP0[1];tmpP2[0]-=tmpP0[0];tmpP2[1]-=tmpP0[1];tmpT1[0]-=tmpT0[0];tmpT1[1]-=tmpT0[1];tmpT2[0]-=tmpT0[0];tmpT2[1]-=tmpT0[1];const det=1/(tmpT1[0]*tmpT2[1]-tmpT2[0]*tmpT1[1]);const a=(tmpT2[1]*tmpP1[0]-tmpT1[1]*tmpP2[0])*det;const b=(tmpT2[1]*tmpP1[1]-tmpT1[1]*tmpP2[1])*det;const c=(tmpT1[0]*tmpP2[0]-tmpT2[0]*tmpP1[0])*det;const d=(tmpT1[0]*tmpP2[1]-tmpT2[0]*tmpP1[1])*det;const e=tmpP0[0]-a*tmpT0[0]-c*tmpT0[1];const f=tmpP0[1]-b*tmpT0[0]-d*tmpT0[1];ctx.save();ctx.transform(a,b,c,d,e,f);ctx.clip();ctx.drawImage(img,0,0);ctx.restore();}
+function drawTriangleSub(ctx,img,p0,p1,p2,t0,t1,t2,opt_recursionDepth){const depth=opt_recursionDepth||0;let subdivisionIndex=0;if(depth<constants.SUBDIVISION_MINIMUM){subdivisionIndex=7;}else if(depth<constants.SUBDIVISION_RECURSION_DEPTH){if(Math.abs(p0[2]-p1[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=1;}
 if(Math.abs(p0[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=2;}
 if(Math.abs(p1[2]-p2[2])>constants.SUBDIVISION_DEPTH_THRESHOLD){subdivisionIndex+=4;}}
-var p01=vec4.create();var p02=vec4.create();var p12=vec4.create();var t01=vec2.create();var t02=vec2.create();var t12=vec2.create();for(var i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
-for(var i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
-for(var i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
-for(var i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
+const p01=vec4.create();const p02=vec4.create();const p12=vec4.create();const t01=vec2.create();const t02=vec2.create();const t12=vec2.create();for(let i=0;i<2;++i){p0[i]*=p0[2];p1[i]*=p1[2];p2[i]*=p2[2];}
+for(let i=0;i<4;++i){p01[i]=(p0[i]+p1[i])/2;p02[i]=(p0[i]+p2[i])/2;p12[i]=(p1[i]+p2[i])/2;}
+for(let i=0;i<2;++i){p0[i]/=p0[2];p1[i]/=p1[2];p2[i]/=p2[2];p01[i]/=p01[2];p02[i]/=p02[2];p12[i]/=p12[2];}
+for(let i=0;i<2;++i){t01[i]=(t0[i]+t1[i])/2;t02[i]=(t0[i]+t2[i])/2;t12[i]=(t1[i]+t2[i])/2;}
 switch(subdivisionIndex){case 1:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 2:drawTriangleSub(ctx,img,p0,p1,p02,t0,t1,t02,depth+1);drawTriangleSub(ctx,img,p1,p02,p2,t1,t02,t2,depth+1);break;case 3:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p02,p01,p2,t02,t01,t2,depth+1);drawTriangleSub(ctx,img,p01,p1,p2,t01,t1,t2,depth+1);break;case 4:drawTriangleSub(ctx,img,p0,p12,p2,t0,t12,t2,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);break;case 5:drawTriangleSub(ctx,img,p0,p01,p2,t0,t01,t2,depth+1);drawTriangleSub(ctx,img,p2,p01,p12,t2,t01,t12,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);break;case 6:drawTriangleSub(ctx,img,p0,p12,p02,t0,t12,t02,depth+1);drawTriangleSub(ctx,img,p0,p1,p12,t0,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;case 7:drawTriangleSub(ctx,img,p0,p01,p02,t0,t01,t02,depth+1);drawTriangleSub(ctx,img,p01,p12,p02,t01,t12,t02,depth+1);drawTriangleSub(ctx,img,p01,p1,p12,t01,t1,t12,depth+1);drawTriangleSub(ctx,img,p02,p12,p2,t02,t12,t2,depth+1);break;default:drawTexturedTriangle(ctx,img,p0,p1,p2,t0,t1,t2);break;}}
-var tmpVec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmpVec4,point[0],point[1],0,1);vec4.transformMat4(tmpVec4,tmpVec4,matrix);var w=tmpVec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmpVec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmpVec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
-function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);var quadBBox=new tr.b.math.BBox2();quadBBox.addQuad(quad);var iw=quadCanvas.width;var ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
+const tmpVec4=vec4.create();function transform(transformed,point,matrix,viewport){vec4.set(tmpVec4,point[0],point[1],0,1);vec4.transformMat4(tmpVec4,tmpVec4,matrix);let w=tmpVec4[3];if(w<1e-6)w=1e-6;transformed[0]=((tmpVec4[0]/w)+1)*viewport.width/2;transformed[1]=((tmpVec4[1]/w)+1)*viewport.height/2;transformed[2]=w;}
+function drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(quad.imageData){quadCanvas.width=quad.imageData.width;quadCanvas.height=quad.imageData.height;quadCanvas.getContext('2d').putImageData(quad.imageData,0,0);const quadBBox=new tr.b.math.BBox2();quadBBox.addQuad(quad);const iw=quadCanvas.width;const ih=quadCanvas.height;drawTriangleSub(ctx,quadCanvas,p1,p2,p4,[0,0],[iw,0],[0,ih]);drawTriangleSub(ctx,quadCanvas,p2,p3,p4,[iw,0],[iw,ih],[0,ih]);}
 if(quad.backgroundColor){ctx.fillStyle=quad.backgroundColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.fill();}}
 function drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.save();if(quad.borderColor){ctx.strokeStyle=quad.borderColor;}else{ctx.strokeStyle='rgb(128,128,128)';}
 if(quad.shadowOffset){ctx.shadowColor='rgb(0, 0, 0)';ctx.shadowOffsetX=quad.shadowOffset[0];ctx.shadowOffsetY=quad.shadowOffset[1];if(quad.shadowBlur){ctx.shadowBlur=quad.shadowBlur;}}
@@ -7236,66 +7586,66 @@
 ctx.stroke();ctx.restore();}
 function drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas){if(!quad.upperBorderColor)return;ctx.lineWidth=8;ctx.strokeStyle=quad.upperBorderColor;ctx.beginPath();ctx.moveTo(p1[0],p1[1]);ctx.lineTo(p2[0],p2[1]);ctx.lineTo(p3[0],p3[1]);ctx.lineTo(p4[0],p4[1]);ctx.closePath();ctx.stroke();}
 function drawProjectedQuadToContext(passNumber,quad,p1,p2,p3,p4,ctx,quadCanvas){if(passNumber===0){drawProjectedQuadBackgroundToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===1){drawProjectedQuadOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else if(passNumber===2){drawProjectedQuadSelectionOutlineToContext(quad,p1,p2,p3,p4,ctx,quadCanvas);}else{throw new Error('Invalid pass number');}}
-var tmpP1=vec3.create();var tmpP2=vec3.create();var tmpP3=vec3.create();var tmpP4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(var passNumber=0;passNumber<numPasses;passNumber++){for(var i=0;i<quads.length;i++){var quad=quads[i];transform(tmpP1,quad.p1,matrix,viewport);transform(tmpP2,quad.p2,matrix,viewport);transform(tmpP3,quad.p3,matrix,viewport);transform(tmpP4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmpP1,tmpP2,tmpP3,tmpP4,opt_arg1,opt_arg2);}}}
-var QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.className='quad-stack-view';var node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.updateHeaderVisibility_();this.canvas_=Polymer.dom(this).querySelector('#canvas');this.chromeImages_={left:Polymer.dom(this).querySelector('#chrome-left'),mid:Polymer.dom(this).querySelector('#chrome-mid'),right:Polymer.dom(this).querySelector('#chrome-right')};var stackingDistanceSlider=Polymer.dom(this).querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.math.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_:function(){if(this.headerText){Polymer.dom(this).querySelector('#header').style.display='';}else{Polymer.dom(this).querySelector('#header').style.display='none';}},get headerText(){return Polymer.dom(this).querySelector('#header').textContent;},set headerText(headerText){Polymer.dom(this).querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_:function(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return Polymer.dom(this).querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize:function(){if(!this.offsetParent)return true;var width=parseInt(window.getComputedStyle(this.offsetParent).width);var height=parseInt(window.getComputedStyle(this.offsetParent).height);var rect=tr.b.math.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
-return true;},readyToDraw:function(){if(!this.chromeImages_.left.src){var leftContent=window.getComputedStyle(this.chromeImages_.left).backgroundImage;leftContent=tr.ui.b.extractUrlString(leftContent);var midContent=window.getComputedStyle(this.chromeImages_.mid).backgroundImage;midContent=tr.ui.b.extractUrlString(midContent);var rightContent=window.getComputedStyle(this.chromeImages_.right).backgroundImage;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
-return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)return this.chromeQuad_;var chromeCanvas=document.createElement('canvas');var offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;var leftWidth=this.chromeImages_.left.width;var midWidth=this.chromeImages_.mid.width;var rightWidth=this.chromeImages_.right.width;var chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);var s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);var chromeRect=tr.b.math.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);var chromeQuad=tr.b.math.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender:function(){if(this.redrawScheduled_)return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_:function(e){this.scheduleRender();},stackTransformAndProcessQuads_:function(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){var mv=this.camera_.modelViewMatrix;var p=this.camera_.projectionMatrix;var viewport=tr.b.math.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);var quadStacks=[];for(var i=0;i<this.quads_.length;++i){var quad=this.quads_[i];var stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length){quadStacks.push([]);}
+const tmpP1=vec3.create();const tmpP2=vec3.create();const tmpP3=vec3.create();const tmpP4=vec3.create();function transformAndProcessQuads(matrix,viewport,quads,numPasses,handleQuadFunc,opt_arg1,opt_arg2){for(let passNumber=0;passNumber<numPasses;passNumber++){for(let i=0;i<quads.length;i++){const quad=quads[i];transform(tmpP1,quad.p1,matrix,viewport);transform(tmpP2,quad.p2,matrix,viewport);transform(tmpP3,quad.p3,matrix,viewport);transform(tmpP4,quad.p4,matrix,viewport);handleQuadFunc(passNumber,quad,tmpP1,tmpP2,tmpP3,tmpP4,opt_arg1,opt_arg2);}}}
+const QuadStackView=tr.ui.b.define('quad-stack-view');QuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.className='quad-stack-view';const node=tr.ui.b.instantiateTemplate('#quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.updateHeaderVisibility_();this.canvas_=Polymer.dom(this).querySelector('#canvas');this.chromeImages_={left:Polymer.dom(this).querySelector('#chrome-left'),mid:Polymer.dom(this).querySelector('#chrome-mid'),right:Polymer.dom(this).querySelector('#chrome-right')};const stackingDistanceSlider=Polymer.dom(this).querySelector('#stacking-distance-slider');stackingDistanceSlider.value=tr.b.Settings.get('quadStackView.stackingDistance',45);stackingDistanceSlider.addEventListener('change',this.onStackingDistanceChange_.bind(this));stackingDistanceSlider.addEventListener('input',this.onStackingDistanceChange_.bind(this));this.trackMouse_();this.camera_=new tr.ui.b.Camera(this.mouseModeSelector_);this.camera_.addEventListener('renderrequired',this.onRenderRequired_.bind(this));this.cameraWasReset_=false;this.camera_.canvas=this.canvas_;this.viewportRect_=tr.b.math.Rect.fromXYWH(0,0,0,0);this.pixelRatio_=window.devicePixelRatio||1;},updateHeaderVisibility_(){if(this.headerText){Polymer.dom(this).querySelector('#header').style.display='';}else{Polymer.dom(this).querySelector('#header').style.display='none';}},get headerText(){return Polymer.dom(this).querySelector('#header').textContent;},set headerText(headerText){Polymer.dom(this).querySelector('#header').textContent=headerText;this.updateHeaderVisibility_();},onStackingDistanceChange_(e){tr.b.Settings.set('quadStackView.stackingDistance',this.stackingDistance);this.scheduleRender();e.stopPropagation();},get stackingDistance(){return Polymer.dom(this).querySelector('#stacking-distance-slider').value;},get mouseModeSelector(){return this.mouseModeSelector_;},get camera(){return this.camera_;},set quads(q){this.quads_=q;this.scheduleRender();},set deviceRect(rect){if(!rect||rect.equalTo(this.deviceRect_))return;this.deviceRect_=rect;this.camera_.deviceRect=rect;this.chromeQuad_=undefined;},resize(){if(!this.offsetParent)return true;const width=parseInt(window.getComputedStyle(this.offsetParent).width);const height=parseInt(window.getComputedStyle(this.offsetParent).height);const rect=tr.b.math.Rect.fromXYWH(0,0,width,height);if(rect.equalTo(this.viewportRect_))return false;this.viewportRect_=rect;this.style.width=width+'px';this.style.height=height+'px';this.canvas_.style.width=width+'px';this.canvas_.style.height=height+'px';this.canvas_.width=this.pixelRatio_*width;this.canvas_.height=this.pixelRatio_*height;if(!this.cameraWasReset_){this.camera_.resetCamera();this.cameraWasReset_=true;}
+return true;},readyToDraw(){if(!this.chromeImages_.left.src){let leftContent=window.getComputedStyle(this.chromeImages_.left).backgroundImage;leftContent=tr.ui.b.extractUrlString(leftContent);let midContent=window.getComputedStyle(this.chromeImages_.mid).backgroundImage;midContent=tr.ui.b.extractUrlString(midContent);let rightContent=window.getComputedStyle(this.chromeImages_.right).backgroundImage;rightContent=tr.ui.b.extractUrlString(rightContent);this.chromeImages_.left.src=leftContent;this.chromeImages_.mid.src=midContent;this.chromeImages_.right.src=rightContent;}
+return(this.chromeImages_.left.height>0)&&(this.chromeImages_.mid.height>0)&&(this.chromeImages_.right.height>0);},get chromeQuad(){if(this.chromeQuad_)return this.chromeQuad_;const chromeCanvas=document.createElement('canvas');const offsetY=this.chromeImages_.left.height;chromeCanvas.width=this.deviceRect_.width;chromeCanvas.height=this.deviceRect_.height+offsetY;const leftWidth=this.chromeImages_.left.width;const midWidth=this.chromeImages_.mid.width;const rightWidth=this.chromeImages_.right.width;const chromeCtx=chromeCanvas.getContext('2d');chromeCtx.drawImage(this.chromeImages_.left,0,0);chromeCtx.save();chromeCtx.translate(leftWidth,0);const s=(this.deviceRect_.width-leftWidth-rightWidth)/midWidth;chromeCtx.scale(s,1);chromeCtx.drawImage(this.chromeImages_.mid,0,0);chromeCtx.restore();chromeCtx.drawImage(this.chromeImages_.right,leftWidth+s*midWidth,0);const chromeRect=tr.b.math.Rect.fromXYWH(this.deviceRect_.x,this.deviceRect_.y-offsetY,this.deviceRect_.width,this.deviceRect_.height+offsetY);const chromeQuad=tr.b.math.Quad.fromRect(chromeRect);chromeQuad.stackingGroupId=this.maxStackingGroupId_+1;chromeQuad.imageData=chromeCtx.getImageData(0,0,chromeCanvas.width,chromeCanvas.height);chromeQuad.shadowOffset=[0,0];chromeQuad.shadowBlur=5;chromeQuad.borderWidth=3;this.chromeQuad_=chromeQuad;return this.chromeQuad_;},scheduleRender(){if(this.redrawScheduled_)return false;this.redrawScheduled_=true;tr.b.requestAnimationFrame(this.render,this);},onRenderRequired_(e){this.scheduleRender();},stackTransformAndProcessQuads_(numPasses,handleQuadFunc,includeChromeQuad,opt_arg1,opt_arg2){const mv=this.camera_.modelViewMatrix;const p=this.camera_.projectionMatrix;const viewport=tr.b.math.Rect.fromXYWH(0,0,this.canvas_.width,this.canvas_.height);const quadStacks=[];for(let i=0;i<this.quads_.length;++i){const quad=this.quads_[i];const stackingId=quad.stackingGroupId||0;while(stackingId>=quadStacks.length){quadStacks.push([]);}
 quadStacks[stackingId].push(quad);}
-var mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;var effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(var i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
-if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render:function(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
-if(!this.quads_)return;var canvasCtx=this.canvas_.getContext('2d');if(!this.resize()){canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);}
-var quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_:function(e){var br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_:function(e){var mousePos=this.extractRelativeMousePosition_(e);var res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.math.pointInImplicitQuad(mousePos,p1,p2,p3,p4)){res.push(quad);}}
-this.stackTransformAndProcessQuads_(1,handleQuad,false);var e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var ColorScheme=tr.b.ColorScheme;var THIS_DOC=document.currentScript.ownerDocument;var TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';var cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
-var LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;var m=tr.ui.b.MOUSE_SELECTOR_MODE;var mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.infoBar_);Polymer.dom(this).appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());Polymer.dom(this.controls_).appendChild(this.tileRectsSelector_);var tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});Polymer.dom(this.controls_).appendChild(tileHeatmapText);var tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);Polymer.dom(this.controls_).appendChild(tileHeatmapSelector);var showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';Polymer.dom(this.controls_).appendChild(showOtherLayersCheckbox);var showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';Polymer.dom(this.controls_).appendChild(showInvalidationsCheckbox);var showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';Polymer.dom(this.controls_).appendChild(showUnrecordedRegionCheckbox);var showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';Polymer.dom(this.controls_).appendChild(showBottlenecksCheckbox);var showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';Polymer.dom(this.controls_).appendChild(showLayoutRectsCheckbox);var showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';Polymer.dom(this.controls_).appendChild(showContentsCheckbox);var showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';Polymer.dom(this.controls_).appendChild(showAnimationBoundsCheckbox);var showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';Polymer.dom(this.controls_).appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');Polymer.dom(this.whatRasterizedLink_).classList.add('what-rasterized');Polymer.dom(this.whatRasterizedLink_).textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));Polymer.dom(this).appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){if(val!=='none'&&val!=='coverage'&&isNaN(parseFloat(val))){throw new Error('howToShowTiles requires "none" or "coverage" or a number');}
-this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent:function(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_:function(image,callback){var imageContent=window.getComputedStyle(image).backgroundImage;image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){var canvas=document.createElement('canvas');var ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);var imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);};},onQuadStackViewSelectionChange_:function(e){var selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length===0){this.selection=undefined;return;}
-selectableQuads.sort(function(x,y){var z=x.stackingGroupId-y.stackingGroupId;if(z!==0)return z;return x.selectionToSetIfClicked.specicifity-
-y.selectionToSetIfClicked.specicifity;});var quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_:function(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_:function(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
-var status=this.computePictureLoadingStatus_();if(!status.picturesComplete)return;var lthi=this.layerTreeImpl_.layerTreeHostImpl;var lthiInstance=lthi.objectInstance;var worldViewportRect=tr.b.math.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_){this.quadStackView_.quads=this.generateRenderPassQuads();}else{this.quadStackView_.quads=this.generateLayerQuads();}
-this.updateWhatRasterizedLinkState_();var message='';if(lthi.tilesHaveGpuMemoryUsageInfo){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;var otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
+const mvp=mat4.create();this.maxStackingGroupId_=quadStacks.length;const effectiveStackingDistance=this.stackingDistance*this.camera_.stackingDistanceDampening;mat4.multiply(mvp,p,mv);for(let i=0;i<quadStacks.length;++i){transformAndProcessQuads(mvp,viewport,quadStacks[i],numPasses,handleQuadFunc,opt_arg1,opt_arg2);mat4.translate(mv,mv,[0,0,effectiveStackingDistance]);mat4.multiply(mvp,p,mv);}
+if(includeChromeQuad&&this.deviceRect_){transformAndProcessQuads(mvp,viewport,[this.chromeQuad],numPasses,drawProjectedQuadToContext,opt_arg1,opt_arg2);}},render(){this.redrawScheduled_=false;if(!this.readyToDraw()){setTimeout(this.scheduleRender.bind(this),constants.IMAGE_LOAD_RETRY_TIME_MS);return;}
+if(!this.quads_)return;const canvasCtx=this.canvas_.getContext('2d');if(!this.resize()){canvasCtx.clearRect(0,0,this.canvas_.width,this.canvas_.height);}
+const quadCanvas=document.createElement('canvas');this.stackTransformAndProcessQuads_(3,drawProjectedQuadToContext,true,canvasCtx,quadCanvas);quadCanvas.width=0;},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.canvas_;this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION|tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN|tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM|tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN;this.mouseModeSelector_.pos={x:0,y:100};Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.settingsKey='quadStackView.mouseModeSelector';this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ROTATE,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.PANSCAN,tr.ui.b.MODIFIER.SPACE);this.mouseModeSelector_.setModifierForAlternateMode(tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM,tr.ui.b.MODIFIER.CMD_OR_CTRL);this.mouseModeSelector_.addEventListener('updateselection',this.onSelectionUpdate_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onSelectionUpdate_.bind(this));},extractRelativeMousePosition_(e){const br=this.canvas_.getBoundingClientRect();return[this.pixelRatio_*(e.clientX-this.canvas_.offsetLeft-br.left),this.pixelRatio_*(e.clientY-this.canvas_.offsetTop-br.top)];},onSelectionUpdate_(e){const mousePos=this.extractRelativeMousePosition_(e);const res=[];function handleQuad(passNumber,quad,p1,p2,p3,p4){if(tr.b.math.pointInImplicitQuad(mousePos,p1,p2,p3,p4)){res.push(quad);}}
+this.stackTransformAndProcessQuads_(1,handleQuad,false);e=new tr.b.Event('selectionchange');e.quads=res;this.dispatchEvent(e);}};return{QuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const ColorScheme=tr.b.ColorScheme;const THIS_DOC=document.currentScript.ownerDocument;const TILE_HEATMAP_TYPE={};TILE_HEATMAP_TYPE.NONE='none';TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY='scheduledPriority';TILE_HEATMAP_TYPE.USING_GPU_MEMORY='usingGpuMemory';const cc=tr.ui.e.chrome.cc;function createTileRectsSelectorBaseOptions(){return[{label:'None',value:'none'},{label:'Coverage Rects',value:'coverage'}];}
+const LayerTreeQuadStackView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-quad-stack-view');LayerTreeQuadStackView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.isRenderPassQuads_=false;this.pictureAsImageData_={};this.messages_=[];this.controls_=document.createElement('top-controls');this.infoBar_=document.createElement('tr-ui-b-info-bar');this.quadStackView_=new tr.ui.b.QuadStackView();this.quadStackView_.addEventListener('selectionchange',this.onQuadStackViewSelectionChange_.bind(this));this.extraHighlightsByLayerId_=undefined;this.inputEventImageData_=undefined;const m=tr.ui.b.MOUSE_SELECTOR_MODE;const mms=this.quadStackView_.mouseModeSelector;mms.settingsKey='tr.e.cc.layerTreeQuadStackView.mouseModeSelector';mms.setKeyCodeForMode(m.SELECTION,'Z'.charCodeAt(0));mms.setKeyCodeForMode(m.PANSCAN,'X'.charCodeAt(0));mms.setKeyCodeForMode(m.ZOOM,'C'.charCodeAt(0));mms.setKeyCodeForMode(m.ROTATE,'V'.charCodeAt(0));const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-layer-tree-quad-stack-view-template',THIS_DOC);Polymer.dom(this).appendChild(node);Polymer.dom(this).appendChild(this.controls_);Polymer.dom(this).appendChild(this.infoBar_);Polymer.dom(this).appendChild(this.quadStackView_);this.tileRectsSelector_=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',createTileRectsSelectorBaseOptions());Polymer.dom(this.controls_).appendChild(this.tileRectsSelector_);const tileHeatmapText=tr.ui.b.createSpan({textContent:'Tile heatmap:'});Polymer.dom(this.controls_).appendChild(tileHeatmapText);const tileHeatmapSelector=tr.ui.b.createSelector(this,'tileHeatmapType','layerView.tileHeatmapType',TILE_HEATMAP_TYPE.NONE,[{label:'None',value:TILE_HEATMAP_TYPE.NONE},{label:'Scheduled Priority',value:TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY},{label:'Is using GPU memory',value:TILE_HEATMAP_TYPE.USING_GPU_MEMORY}]);Polymer.dom(this.controls_).appendChild(tileHeatmapSelector);const showOtherLayersCheckbox=tr.ui.b.createCheckBox(this,'showOtherLayers','layerView.showOtherLayers',true,'Other layers/passes');showOtherLayersCheckbox.title='When checked, show all layers, selected or not.';Polymer.dom(this.controls_).appendChild(showOtherLayersCheckbox);const showInvalidationsCheckbox=tr.ui.b.createCheckBox(this,'showInvalidations','layerView.showInvalidations',true,'Invalidations');showInvalidationsCheckbox.title='When checked, compositing invalidations are highlighted in red';Polymer.dom(this.controls_).appendChild(showInvalidationsCheckbox);const showUnrecordedRegionCheckbox=tr.ui.b.createCheckBox(this,'showUnrecordedRegion','layerView.showUnrecordedRegion',true,'Unrecorded area');showUnrecordedRegionCheckbox.title='When checked, unrecorded areas are highlighted in yellow';Polymer.dom(this.controls_).appendChild(showUnrecordedRegionCheckbox);const showBottlenecksCheckbox=tr.ui.b.createCheckBox(this,'showBottlenecks','layerView.showBottlenecks',true,'Bottlenecks');showBottlenecksCheckbox.title='When checked, scroll bottlenecks are highlighted';Polymer.dom(this.controls_).appendChild(showBottlenecksCheckbox);const showLayoutRectsCheckbox=tr.ui.b.createCheckBox(this,'showLayoutRects','layerView.showLayoutRects',false,'Layout rects');showLayoutRectsCheckbox.title='When checked, shows rects for regions where layout happened';Polymer.dom(this.controls_).appendChild(showLayoutRectsCheckbox);const showContentsCheckbox=tr.ui.b.createCheckBox(this,'showContents','layerView.showContents',true,'Contents');showContentsCheckbox.title='When checked, show the rendered contents inside the layer outlines';Polymer.dom(this.controls_).appendChild(showContentsCheckbox);const showAnimationBoundsCheckbox=tr.ui.b.createCheckBox(this,'showAnimationBounds','layerView.showAnimationBounds',false,'Animation Bounds');showAnimationBoundsCheckbox.title='When checked, show a border around'+' a layer showing the extent of its animation.';Polymer.dom(this.controls_).appendChild(showAnimationBoundsCheckbox);const showInputEventsCheckbox=tr.ui.b.createCheckBox(this,'showInputEvents','layerView.showInputEvents',true,'Input events');showInputEventsCheckbox.title='When checked, input events are '+'displayed as circles.';Polymer.dom(this.controls_).appendChild(showInputEventsCheckbox);this.whatRasterizedLink_=document.createElement('a');Polymer.dom(this.whatRasterizedLink_).classList.add('what-rasterized');Polymer.dom(this.whatRasterizedLink_).textContent='What rasterized?';this.whatRasterizedLink_.addEventListener('click',this.onWhatRasterizedLinkClicked_.bind(this));Polymer.dom(this).appendChild(this.whatRasterizedLink_);},get layerTreeImpl(){return this.layerTreeImpl_;},set isRenderPassQuads(newValue){this.isRenderPassQuads_=newValue;},set layerTreeImpl(layerTreeImpl){if(this.layerTreeImpl_===layerTreeImpl)return;this.layerTreeImpl_=layerTreeImpl;this.selection=undefined;},get extraHighlightsByLayerId(){return this.extraHighlightsByLayerId_;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.extraHighlightsByLayerId_=extraHighlightsByLayerId;this.scheduleUpdateContents_();},get showOtherLayers(){return this.showOtherLayers_;},set showOtherLayers(show){this.showOtherLayers_=show;this.updateContents_();},get showAnimationBounds(){return this.showAnimationBounds_;},set showAnimationBounds(show){this.showAnimationBounds_=show;this.updateContents_();},get showInputEvents(){return this.showInputEvents_;},set showInputEvents(show){this.showInputEvents_=show;this.updateContents_();},get showContents(){return this.showContents_;},set showContents(show){this.showContents_=show;this.updateContents_();},get showInvalidations(){return this.showInvalidations_;},set showInvalidations(show){this.showInvalidations_=show;this.updateContents_();},get showUnrecordedRegion(){return this.showUnrecordedRegion_;},set showUnrecordedRegion(show){this.showUnrecordedRegion_=show;this.updateContents_();},get showBottlenecks(){return this.showBottlenecks_;},set showBottlenecks(show){this.showBottlenecks_=show;this.updateContents_();},get showLayoutRects(){return this.showLayoutRects_;},set showLayoutRects(show){this.showLayoutRects_=show;this.updateContents_();},get howToShowTiles(){return this.howToShowTiles_;},set howToShowTiles(val){if(val!=='none'&&val!=='coverage'&&isNaN(parseFloat(val))){throw new Error('howToShowTiles requires "none" or "coverage" or a number');}
+this.howToShowTiles_=val;this.updateContents_();},get tileHeatmapType(){return this.tileHeatmapType_;},set tileHeatmapType(val){this.tileHeatmapType_=val;this.updateContents_();},get selection(){return this.selection_;},set selection(selection){if(this.selection===selection)return;this.selection_=selection;tr.b.dispatchSimpleEvent(this,'selection-change');this.updateContents_();},regenerateContent(){this.updateTilesSelector_();this.updateContents_();},loadDataForImageElement_(image,callback){const imageContent=window.getComputedStyle(image).backgroundImage;image.src=tr.ui.b.extractUrlString(imageContent);image.onload=function(){const canvas=document.createElement('canvas');const ctx=canvas.getContext('2d');canvas.width=image.width;canvas.height=image.height;ctx.drawImage(image,0,0);const imageData=ctx.getImageData(0,0,canvas.width,canvas.height);callback(imageData);};},onQuadStackViewSelectionChange_(e){const selectableQuads=e.quads.filter(function(q){return q.selectionToSetIfClicked!==undefined;});if(selectableQuads.length===0){this.selection=undefined;return;}
+selectableQuads.sort(function(x,y){const z=x.stackingGroupId-y.stackingGroupId;if(z!==0)return z;return x.selectionToSetIfClicked.specicifity-
+y.selectionToSetIfClicked.specicifity;});const quadToSelect=selectableQuads[selectableQuads.length-1];this.selection=quadToSelect.selectionToSetIfClicked;},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_,this);},updateContents_(){if(!this.layerTreeImpl_){this.quadStackView_.headerText='No tree';this.quadStackView_.quads=[];return;}
+const status=this.computePictureLoadingStatus_();if(!status.picturesComplete)return;const lthi=this.layerTreeImpl_.layerTreeHostImpl;const lthiInstance=lthi.objectInstance;const worldViewportRect=tr.b.math.Rect.fromXYWH(0,0,lthi.deviceViewportSize.width,lthi.deviceViewportSize.height);this.quadStackView_.deviceRect=worldViewportRect;if(this.isRenderPassQuads_){this.quadStackView_.quads=this.generateRenderPassQuads();}else{this.quadStackView_.quads=this.generateLayerQuads();}
+this.updateWhatRasterizedLinkState_();let message='';if(lthi.tilesHaveGpuMemoryUsageInfo){const thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;const otherTreeUsageInBytes=lthi.gpuMemoryUsageInBytes-
 thisTreeUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(otherTreeUsageInBytes){message+=', '+
-tr.b.convertUnit(otherTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on the other tree';}}else{if(this.layerTreeImpl_){var thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ??? MiB on other tree. ';}}}
-if(lthi.args.tileManagerBasicState){var tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
+tr.b.convertUnit(otherTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on the other tree';}}else{if(this.layerTreeImpl_){const thisTreeUsageInBytes=this.layerTreeImpl_.gpuMemoryUsageInBytes;message+=tr.b.convertUnit(thisTreeUsageInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB on this tree';if(this.layerTreeImpl_.otherTree){message+=', ??? MiB on other tree. ';}}}
+if(lthi.args.tileManagerBasicState){const tmgs=lthi.args.tileManagerBasicState.globalState;message+=' (softMax='+
 tr.b.convertUnit(tmgs.softMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, hardMax='+
 tr.b.convertUnit(tmgs.hardMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, '+
-tmgs.memoryLimitPolicy+')';}else{var thread=lthi.snapshottedOnThread;var didManageTilesSlices=thread.sliceGroup.slices.filter(function(s){if(s.category!=='tr.e.cc')return false;if(s.title!=='DidManage')return false;if(s.end>lthi.ts)return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){var newest=didManageTilesSlices[didManageTilesSlices.length-1];var tmgs=newest.args.state.global_state;message+=' (softMax='+
+tmgs.memoryLimitPolicy+')';}else{const thread=lthi.snapshottedOnThread;const didManageTilesSlices=thread.sliceGroup.slices.filter(s=>{if(s.category!=='tr.e.cc')return false;if(s.title!=='DidManage')return false;if(s.end>lthi.ts)return false;return true;});didManageTilesSlices.sort(function(x,y){return x.end-y.end;});if(didManageTilesSlices.length>0){const newest=didManageTilesSlices[didManageTilesSlices.length-1];const tmgs=newest.args.state.global_state;message+=' (softMax='+
 tr.b.convertUnit(tmgs.softMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, hardMax='+
 tr.b.convertUnit(tmgs.hardMemoryLimitInBytes,tr.b.UnitPrefixScale.BINARY.NONE,tr.b.UnitPrefixScale.BINARY.MEBI).toFixed(1)+' MiB, '+
 tmgs.memoryLimitPolicy+')';}}
 if(this.layerTreeImpl_.otherTree){message+=' (Another tree exists)';}
 if(message.length){this.quadStackView_.headerText=message;}else{this.quadStackView_.headerText=undefined;}
-this.updateInfoBar_(status.messages);},updateTilesSelector_:function(){var data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var scaleNames=lthi.getContentsScaleNames();for(var scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
-var newSelector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(newSelector,this.tileRectsSelector_);this.tileRectsSelector_=newSelector;},computePictureLoadingStatus_:function(){var layers=this.layers;var status={messages:[],picturesComplete:true};if(this.showContents){var hasPendingRasterizeImage=false;var firstPictureError=undefined;var hasMissingLayerRect=false;var hasUnresolvedPictureRef=false;for(var i=0;i<layers.length;i++){var layer=layers[i];for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
+this.updateInfoBar_(status.messages);},updateTilesSelector_(){const data=createTileRectsSelectorBaseOptions();if(this.layerTreeImpl_){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const scaleNames=lthi.getContentsScaleNames();for(const scale in scaleNames){data.push({label:'Scale '+scale+' ('+scaleNames[scale]+')',value:scale});}}
+const newSelector=tr.ui.b.createSelector(this,'howToShowTiles','layerView.howToShowTiles','none',data);this.controls_.replaceChild(newSelector,this.tileRectsSelector_);this.tileRectsSelector_=newSelector;},computePictureLoadingStatus_(){const layers=this.layers;const status={messages:[],picturesComplete:true};if(this.showContents){let hasPendingRasterizeImage=false;let firstPictureError=undefined;let hasMissingLayerRect=false;let hasUnresolvedPictureRef=false;for(let i=0;i<layers.length;i++){const layer=layers[i];for(let ir=0;ir<layer.pictures.length;++ir){const picture=layer.pictures[ir];if(picture.idRef){hasUnresolvedPictureRef=true;continue;}
 if(!picture.layerRect){hasMissingLayerRect=true;continue;}
-var pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){var picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
+const pictureAsImageData=this.pictureAsImageData_[picture.guid];if(!pictureAsImageData){hasPendingRasterizeImage=true;this.pictureAsImageData_[picture.guid]=tr.e.cc.PictureAsImageData.Pending(this);picture.rasterize({stopIndex:undefined},function(pictureImageData){const picture_=pictureImageData.picture;this.pictureAsImageData_[picture_.guid]=pictureImageData;this.scheduleUpdateContents_();}.bind(this));continue;}
 if(pictureAsImageData.isPending()){hasPendingRasterizeImage=true;continue;}
 if(pictureAsImageData.error){if(!firstPictureError){firstPictureError=pictureAsImageData.error;}
 break;}}}
 if(hasPendingRasterizeImage){status.picturesComplete=false;}else{if(hasUnresolvedPictureRef){status.messages.push({header:'Missing picture',details:'Your trace didn\'t have pictures for every layer. '+'Old chrome versions had this problem'});}
 if(hasMissingLayerRect){status.messages.push({header:'Missing layer rect',details:'Your trace may be corrupt or from a very old '+'Chrome revision.'});}
 if(firstPictureError){status.messages.push({header:'Cannot rasterize',details:firstPictureError});}}}
-if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){var image=Polymer.dom(this).querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
+if(this.showInputEvents&&this.layerTreeImpl.tracedInputLatencies&&this.inputEventImageData_===undefined){const image=Polymer.dom(this).querySelector('#input-event');if(!image.src){this.loadDataForImageElement_(image,function(imageData){this.inputEventImageData_=imageData;this.updateContentsPending_=false;this.scheduleUpdateContents_();}.bind(this));}
 status.picturesComplete=false;}
-return status;},get selectedRenderPass(){if(this.selection){return this.selection.renderPass_;}},get selectedLayer(){if(this.selection){var selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){var renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){var selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass){renderPasses=[selectedRenderPass];}}
-return renderPasses;},get layers(){var layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){var selectedLayer=this.selectedLayer;if(selectedLayer){layers=[selectedLayer];}}
-return layers;},appendImageQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.pictures.length;++ir){var picture=layer.pictures[ir];if(!picture.layerRect)continue;var unitRect=picture.layerRect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);var pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
-iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_:function(quads,layer,layerQuad){if(!layer.animationBoundsRect)return;var rect=layer.animationBoundsRect;var abq=tr.b.math.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_:function(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)return;for(var ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){var rect=layer.annotatedInvalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion'){iq.backgroundColor='rgba(0, 255, 128, 0.1)';}
+return status;},get selectedRenderPass(){if(this.selection){return this.selection.renderPass_;}},get selectedLayer(){if(this.selection){const selectedLayerId=this.selection.associatedLayerId;return this.layerTreeImpl_.findLayerWithId(selectedLayerId);}},get renderPasses(){let renderPasses=this.layerTreeImpl.layerTreeHostImpl.args.frame.renderPasses;if(!this.showOtherLayers){const selectedRenderPass=this.selectedRenderPass;if(selectedRenderPass){renderPasses=[selectedRenderPass];}}
+return renderPasses;},get layers(){let layers=this.layerTreeImpl.renderSurfaceLayerList;if(!this.showOtherLayers){const selectedLayer=this.selectedLayer;if(selectedLayer){layers=[selectedLayer];}}
+return layers;},appendImageQuads_(quads,layer,layerQuad){for(let ir=0;ir<layer.pictures.length;++ir){const picture=layer.pictures[ir];if(!picture.layerRect)continue;const unitRect=picture.layerRect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);const pictureData=this.pictureAsImageData_[picture.guid];if(this.showContents&&pictureData&&pictureData.imageData){iq.imageData=pictureData.imageData;iq.borderColor='rgba(0,0,0,0)';}else{iq.imageData=undefined;}
+iq.stackingGroupId=layerQuad.stackingGroupId;quads.push(iq);}},appendAnimationQuads_(quads,layer,layerQuad){if(!layer.animationBoundsRect)return;const rect=layer.animationBoundsRect;const abq=tr.b.math.Quad.fromRect(rect);abq.backgroundColor='rgba(164,191,48,0.5)';abq.borderColor='rgba(205,255,0,0.75)';abq.borderWidth=3.0;abq.stackingGroupId=layerQuad.stackingGroupId;abq.selectionToSetIfClicked=new cc.AnimationRectSelection(layer,rect);quads.push(abq);},appendInvalidationQuads_(quads,layer,layerQuad){if(layer.layerTreeImpl.hasSourceFrameBeenDrawnBefore)return;for(let ir=0;ir<layer.annotatedInvalidation.rects.length;ir++){const rect=layer.annotatedInvalidation.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';if(rect.reason==='renderer insertion'){iq.backgroundColor='rgba(0, 255, 128, 0.1)';}
 iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect ('+rect.reason+')',rect,rect);quads.push(iq);}
-if(layer.annotatedInvalidation.rects.length===0){for(var ir=0;ir<layer.invalidation.rects.length;ir++){var rect=layer.invalidation.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_:function(quads,layer,layerQuad){for(var ir=0;ir<layer.unrecordedRegion.rects.length;ir++){var rect=layer.unrecordedRegion.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_:function(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){var backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)return;for(var ir=0;ir<region.rects.length;ir++){var rect=region.rects[ir];var unitRect=rect.asUVRectInside(layer.bounds);var iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
-processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_:function(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)return;var tiles=[];for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)tiles.push(tile);}
-var lthi=this.layerTreeImpl_.layerTreeHostImpl;var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);var heatIndex=0;for(var ct=0;ct<layer.tileCoverageRects.length;++ct){var rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var tile=layer.tileCoverageRects[ct].tile;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
-quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;var label;if(tile){label='coverageRect';}else{label='checkerboard coverageRect';}
-quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_:function(quads,layer,layerQuad){if(!layer.layoutRects){return;}
-for(var ct=0;ct<layer.layoutRects.length;++ct){var rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;var label;label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_:function(tile,heatmapType){if(heatmapType===TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority===0?undefined:tile.scheduledPriority;}else if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_:function(tiles,heatmapType){var range=new tr.b.math.Range();if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
-for(var i=0;i<tiles.length;++i){var value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)continue;range.addValue(value);}
+if(layer.annotatedInvalidation.rects.length===0){for(let ir=0;ir<layer.invalidation.rects.length;ir++){const rect=layer.invalidation.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(0, 255, 0, 0.1)';iq.borderColor='rgba(0, 255, 0, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Invalidation rect',rect,rect);quads.push(iq);}}},appendUnrecordedRegionQuads_(quads,layer,layerQuad){for(let ir=0;ir<layer.unrecordedRegion.rects.length;ir++){const rect=layer.unrecordedRegion.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor='rgba(240, 230, 140, 0.3)';iq.borderColor='rgba(240, 230, 140, 1)';iq.stackingGroupId=layerQuad.stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,'Unrecorded area',rect,rect);quads.push(iq);}},appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId){function processRegion(region,label,borderColor){const backgroundColor=borderColor.clone();backgroundColor.a=0.4*(borderColor.a||1.0);if(!region||!region.rects)return;for(let ir=0;ir<region.rects.length;ir++){const rect=region.rects[ir];const unitRect=rect.asUVRectInside(layer.bounds);const iq=layerQuad.projectUnitRect(unitRect);iq.backgroundColor=backgroundColor.toString();iq.borderColor=borderColor.toString();iq.borderWidth=4.0;iq.stackingGroupId=stackingGroupId;iq.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,rect);quads.push(iq);}}
+processRegion(layer.touchEventHandlerRegion,'Touch listener',tr.b.Color.fromString('rgb(228, 226, 27)'));processRegion(layer.wheelEventHandlerRegion,'Wheel listener',tr.b.Color.fromString('rgb(176, 205, 29)'));processRegion(layer.nonFastScrollableRegion,'Repaints on scroll',tr.b.Color.fromString('rgb(213, 134, 32)'));},appendTileCoverageRectQuads_(quads,layer,layerQuad,heatmapType){if(!layer.tileCoverageRects)return;const tiles=[];for(let ct=0;ct<layer.tileCoverageRects.length;++ct){const tile=layer.tileCoverageRects[ct].tile;if(tile!==undefined)tiles.push(tile);}
+const lthi=this.layerTreeImpl_.layerTreeHostImpl;const minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);const heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);let heatIndex=0;for(let ct=0;ct<layer.tileCoverageRects.length;++ct){let rect=layer.tileCoverageRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);const tile=layer.tileCoverageRects[ct].tile;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;let type=tr.e.cc.tileTypes.missing;if(tile){type=tile.getTypeForLayer(layer);quad.backgroundColor=heatmapResult[heatIndex].color;++heatIndex;}
+quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;let label;if(tile){label='coverageRect';}else{label='checkerboard coverageRect';}
+quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect,layer.tileCoverageRects[ct]);quads.push(quad);}},appendLayoutRectQuads_(quads,layer,layerQuad){if(!layer.layoutRects){return;}
+for(let ct=0;ct<layer.layoutRects.length;++ct){let rect=layer.layoutRects[ct].geometryRect;rect=rect.scale(1.0/layer.geometryContentsScale);const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;quad.borderColor='rgba(0, 0, 200, 0.7)';quad.borderWidth=2;const label='Layout rect';quad.selectionToSetIfClicked=new cc.LayerRectSelection(layer,label,rect);quads.push(quad);}},getValueForHeatmap_(tile,heatmapType){if(heatmapType===TILE_HEATMAP_TYPE.SCHEDULED_PRIORITY){return tile.scheduledPriority===0?undefined:tile.scheduledPriority;}else if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){if(tile.isSolidColor)return 0.5;return tile.isUsingGpuMemory?0:1;}},getMinMaxForHeatmap_(tiles,heatmapType){const range=new tr.b.math.Range();if(heatmapType===TILE_HEATMAP_TYPE.USING_GPU_MEMORY){range.addValue(0);range.addValue(1);return range;}
+for(let i=0;i<tiles.length;++i){const value=this.getValueForHeatmap_(tiles[i],heatmapType);if(value===undefined)continue;range.addValue(value);}
 if(range.range===0){range.addValue(1);}
-return range;},computeHeatmapColors_:function(tiles,minMax,heatmapType){var min=minMax.min;var max=minMax.max;var color=function(value){var hue=120*(1-(value-min)/(max-min));if(hue<0)hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};var values=[];for(var i=0;i<tiles.length;++i){var tile=tiles[i];var value=this.getValueForHeatmap_(tile,heatmapType);var res={value:value,color:value!==undefined?color(value):undefined};values.push(res);}
-return values;},appendTilesWithScaleQuads_:function(quads,layer,layerQuad,scale,heatmapType){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var tiles=[];for(var i=0;i<lthi.activeTiles.length;++i){var tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6){continue;}
+return range;},computeHeatmapColors_(tiles,minMax,heatmapType){const min=minMax.min;const max=minMax.max;const color=function(value){let hue=120*(1-(value-min)/(max-min));if(hue<0)hue=0;return'hsla('+hue+', 100%, 50%, 0.5)';};const values=[];for(let i=0;i<tiles.length;++i){const tile=tiles[i];const value=this.getValueForHeatmap_(tile,heatmapType);const res={value,color:value!==undefined?color(value):undefined};values.push(res);}
+return values;},appendTilesWithScaleQuads_(quads,layer,layerQuad,scale,heatmapType){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const tiles=[];for(let i=0;i<lthi.activeTiles.length;++i){const tile=lthi.activeTiles[i];if(Math.abs(tile.contentsScale-scale)>1e-6){continue;}
 if(layer.layerId!==tile.layerId)continue;tiles.push(tile);}
-var minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);var heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(var i=0;i<tiles.length;++i){var tile=tiles[i];var rect=tile.layerRect;if(!tile.layerRect)continue;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;var type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;var data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE){data[heatmapType]=heatmapResult[i].value;}
-quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_:function(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){var rect=highlight.rect;var unitRect=rect.asUVRectInside(layer.bounds);var quad=layerQuad.projectUnitRect(unitRect);var colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);colorId+=ColorScheme.properties.brightenedOffsets[0];var color=ColorScheme.colors[colorId];var quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads:function(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)return[];var renderPasses=this.renderPasses;if(!renderPasses)return[];var quads=[];for(var i=0;i<renderPasses.length;++i){var quadList=renderPasses[i].quadList;for(var j=0;j<quadList.length;++j){var drawQuad=quadList[j];var quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
-return quads;},generateLayerQuads:function(){this.updateContentsPending_=false;var layers=this.layers;var quads=[];var nextStackingGroupId=0;var alreadyVisitedLayerIds={};var selectionHighlightsByLayerId;if(this.selection){selectionHighlightsByLayerId=this.selection.highlightsByLayerId;}else{selectionHighlightsByLayerId={};}
-var extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(var i=1;i<=layers.length;i++){var layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name==='cc::NinePatchLayerImpl'){continue;}
-var layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){var pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
+const minMax=this.getMinMaxForHeatmap_(lthi.activeTiles,heatmapType);const heatmapResult=this.computeHeatmapColors_(tiles,minMax,heatmapType);for(let i=0;i<tiles.length;++i){const tile=tiles[i];const rect=tile.layerRect;if(!tile.layerRect)continue;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);quad.backgroundColor='rgba(0, 0, 0, 0)';quad.stackingGroupId=layerQuad.stackingGroupId;const type=tile.getTypeForLayer(layer);quad.borderColor=tr.e.cc.tileBorder[type].color;quad.borderWidth=tr.e.cc.tileBorder[type].width;quad.backgroundColor=heatmapResult[i].color;const data={tileType:type};if(heatmapType!==TILE_HEATMAP_TYPE.NONE){data[heatmapType]=heatmapResult[i].value;}
+quad.selectionToSetIfClicked=new cc.TileSelection(tile,data);quads.push(quad);}},appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights){highlights.forEach(function(highlight){const rect=highlight.rect;const unitRect=rect.asUVRectInside(layer.bounds);const quad=layerQuad.projectUnitRect(unitRect);let colorId=ColorScheme.getColorIdForGeneralPurposeString(highlight.colorKey);const offset=ColorScheme.properties.brightenedOffsets[0];colorId=ColorScheme.getVariantColorId(colorId,offset);const color=ColorScheme.colors[colorId];const quadForDrawing=quad.clone();quadForDrawing.backgroundColor=color.withAlpha(0.5).toString();quadForDrawing.borderColor=color.withAlpha(1.0).darken().toString();quadForDrawing.stackingGroupId=layerQuad.stackingGroupId;quads.push(quadForDrawing);},this);},generateRenderPassQuads(){if(!this.layerTreeImpl.layerTreeHostImpl.args.frame)return[];const renderPasses=this.renderPasses;if(!renderPasses)return[];const quads=[];for(let i=0;i<renderPasses.length;++i){const quadList=renderPasses[i].quadList;for(let j=0;j<quadList.length;++j){const drawQuad=quadList[j];const quad=drawQuad.rectAsTargetSpaceQuad.clone();quad.borderColor='rgb(170, 204, 238)';quad.borderWidth=2;quad.stackingGroupId=i;quads.push(quad);}}
+return quads;},generateLayerQuads(){this.updateContentsPending_=false;const layers=this.layers;const quads=[];let nextStackingGroupId=0;const alreadyVisitedLayerIds={};let selectionHighlightsByLayerId;if(this.selection){selectionHighlightsByLayerId=this.selection.highlightsByLayerId;}else{selectionHighlightsByLayerId={};}
+const extraHighlightsByLayerId=this.extraHighlightsByLayerId||{};for(let i=1;i<=layers.length;i++){const layer=layers[layers.length-i];alreadyVisitedLayerIds[layer.layerId]=true;if(layer.objectInstance.name==='cc::NinePatchLayerImpl'){continue;}
+const layerQuad=layer.layerQuad.clone();if(layer.usingGpuRasterization){const pixelRatio=window.devicePixelRatio||1;layerQuad.borderWidth=2.0*pixelRatio;layerQuad.borderColor='rgba(154,205,50,0.75)';}else{layerQuad.borderColor='rgba(0,0,0,0.75)';}
 layerQuad.stackingGroupId=nextStackingGroupId++;layerQuad.selectionToSetIfClicked=new cc.LayerSelection(layer);layerQuad.layer=layer;if(this.showOtherLayers&&this.selectedLayer===layer){layerQuad.upperBorderColor='rgb(156,189,45)';}
 if(this.showAnimationBounds){this.appendAnimationQuads_(quads,layer,layerQuad);}
 this.appendImageQuads_(quads,layer,layerQuad);quads.push(layerQuad);if(this.showInvalidations){this.appendInvalidationQuads_(quads,layer,layerQuad);}
@@ -7303,253 +7653,253 @@
 if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,layerQuad.stackingGroupId);}
 if(this.showLayoutRects){this.appendLayoutRectQuads_(quads,layer,layerQuad);}
 if(this.howToShowTiles==='coverage'){this.appendTileCoverageRectQuads_(quads,layer,layerQuad,this.tileHeatmapType);}else if(this.howToShowTiles!=='none'){this.appendTilesWithScaleQuads_(quads,layer,layerQuad,this.howToShowTiles,this.tileHeatmapType);}
-var highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
+let highlights;highlights=extraHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}
 highlights=selectionHighlightsByLayerId[layer.layerId];if(highlights){this.appendHighlightQuadsForLayer_(quads,layer,layerQuad,highlights);}}
-this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!==layer)return;if(alreadyVisitedLayerIds[layer.layerId])return;var layerQuad=layer.layerQuad;var stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);}},this);var tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(var i=0;i<tracedInputLatencies.length;i++){var coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(var j=0;j<coordinatesArray.length;j++){var inputQuad=tr.b.math.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
-return quads;},updateInfoBar_:function(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent='';infoBarMessages.forEach(function(message){var title=document.createElement('h3');Polymer.dom(title).textContent=message.header;var details=document.createElement('div');Polymer.dom(details).textContent=message.details;Polymer.dom(overlay).appendChild(title);Polymer.dom(overlay).appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_:function(){var lthi=this.layerTreeImpl_.layerTreeHostImpl;var renderProcess=lthi.objectInstance.parent;var tasks=[];for(var event of renderProcess.getDescendantEvents()){if(!(event instanceof tr.model.Slice))continue;var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)continue;if(tile.containingSnapshot===lthi){tasks.push(event);}}
-return tasks;},updateWhatRasterizedLinkState_:function(){var tasks=this.getWhatRasterized_();if(tasks.length){Polymer.dom(this.whatRasterizedLink_).textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{Polymer.dom(this.whatRasterizedLink_).textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_:function(){var tasks=this.getWhatRasterized_();var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var constants=tr.e.cc.constants;var LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;Polymer.dom(this).appendChild(this.layerTreeQuadStackView_);Polymer.dom(this).appendChild(this.dragBar_);Polymer.dom(this).appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent:function(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_:function(){var selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';Polymer.dom(this.analysisEl_).textContent='';var layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){Polymer.dom(this.analysisEl_).appendChild(this.createPictureBtn_(layer.args.pictures));}
-var analysis=selection.createAnalysis();Polymer.dom(this.analysisEl_).appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';var analysis=Polymer.dom(this.analysisEl_).firstChild;if(analysis){Polymer.dom(this.analysisEl_).removeChild(analysis);}
+this.layerTreeImpl.iterLayers(function(layer,depth,isMask,isReplica){if(!this.showOtherLayers&&this.selectedLayer!==layer)return;if(alreadyVisitedLayerIds[layer.layerId])return;const layerQuad=layer.layerQuad;const stackingGroupId=nextStackingGroupId++;if(this.showBottlenecks){this.appendBottleneckQuads_(quads,layer,layerQuad,stackingGroupId);}},this);const tracedInputLatencies=this.layerTreeImpl.tracedInputLatencies;if(this.showInputEvents&&tracedInputLatencies){for(let i=0;i<tracedInputLatencies.length;i++){const coordinatesArray=tracedInputLatencies[i].args.data.coordinates;for(let j=0;j<coordinatesArray.length;j++){const inputQuad=tr.b.math.Quad.fromXYWH(coordinatesArray[j].x-25,coordinatesArray[j].y-25,50,50);inputQuad.borderColor='rgba(0, 0, 0, 0)';inputQuad.imageData=this.inputEventImageData_;quads.push(inputQuad);}}}
+return quads;},updateInfoBar_(infoBarMessages){if(infoBarMessages.length){this.infoBar_.removeAllButtons();this.infoBar_.message='Some problems were encountered...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent='';infoBarMessages.forEach(function(message){const title=document.createElement('h3');Polymer.dom(title).textContent=message.header;const details=document.createElement('div');Polymer.dom(details).textContent=message.details;Polymer.dom(overlay).appendChild(title);Polymer.dom(overlay).appendChild(details);});overlay.visible=true;e.stopPropagation();return false;});this.infoBar_.visible=true;}else{this.infoBar_.removeAllButtons();this.infoBar_.message='';this.infoBar_.visible=false;}},getWhatRasterized_(){const lthi=this.layerTreeImpl_.layerTreeHostImpl;const renderProcess=lthi.objectInstance.parent;const tasks=[];for(const event of renderProcess.getDescendantEvents()){if(!(event instanceof tr.model.Slice))continue;const tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined)continue;if(tile.containingSnapshot===lthi){tasks.push(event);}}
+return tasks;},updateWhatRasterizedLinkState_(){const tasks=this.getWhatRasterized_();if(tasks.length){Polymer.dom(this.whatRasterizedLink_).textContent=tasks.length+' raster tasks';this.whatRasterizedLink_.style.display='';}else{Polymer.dom(this.whatRasterizedLink_).textContent='';this.whatRasterizedLink_.style.display='none';}},onWhatRasterizedLinkClicked_(){const tasks=this.getWhatRasterized_();const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(tasks);this.dispatchEvent(event);}};return{LayerTreeQuadStackView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const constants=tr.e.cc.constants;const LayerView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-view');LayerView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.layerTreeQuadStackView_=new tr.ui.e.chrome.cc.LayerTreeQuadStackView();this.dragBar_=document.createElement('tr-ui-b-drag-handle');this.analysisEl_=document.createElement('tr-ui-e-chrome-cc-layer-view-analysis');this.analysisEl_.addEventListener('requestSelectionChange',this.onRequestSelectionChangeFromAnalysisEl_.bind(this));this.dragBar_.target=this.analysisEl_;Polymer.dom(this).appendChild(this.layerTreeQuadStackView_);Polymer.dom(this).appendChild(this.dragBar_);Polymer.dom(this).appendChild(this.analysisEl_);this.layerTreeQuadStackView_.addEventListener('selection-change',function(){this.layerTreeQuadStackViewSelectionChanged_();}.bind(this));this.layerTreeQuadStackViewSelectionChanged_();},get layerTreeImpl(){return this.layerTreeQuadStackView_.layerTreeImpl;},set layerTreeImpl(newValue){return this.layerTreeQuadStackView_.layerTreeImpl=newValue;},set isRenderPassQuads(newValue){return this.layerTreeQuadStackView_.isRenderPassQuads=newValue;},get selection(){return this.layerTreeQuadStackView_.selection;},set selection(newValue){this.layerTreeQuadStackView_.selection=newValue;},regenerateContent(){this.layerTreeQuadStackView_.regenerateContent();},layerTreeQuadStackViewSelectionChanged_(){const selection=this.layerTreeQuadStackView_.selection;if(selection){this.dragBar_.style.display='';this.analysisEl_.style.display='';Polymer.dom(this.analysisEl_).textContent='';const layer=selection.layer;if(layer&&layer.args&&layer.args.pictures){Polymer.dom(this.analysisEl_).appendChild(this.createPictureBtn_(layer.args.pictures));}
+const analysis=selection.createAnalysis();Polymer.dom(this.analysisEl_).appendChild(analysis);}else{this.dragBar_.style.display='none';this.analysisEl_.style.display='none';const analysis=Polymer.dom(this.analysisEl_).firstChild;if(analysis){Polymer.dom(this.analysisEl_).removeChild(analysis);}
 this.layerTreeQuadStackView_.style.height=window.getComputedStyle(this).height;}
-tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_:function(pictures){if(!(pictures instanceof Array)){pictures=[pictures];}
-var link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){var layeredPicture=new tr.e.cc.LayeredPicture(pictures);var snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;var selection=new tr.model.EventSet();selection.push(snapshot);return selection;};Polymer.dom(link).textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_:function(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection)){return;}
-e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;Polymer.dom(this).appendChild(this.layerPicker_);Polymer.dom(this).appendChild(this.dragHandle_);Polymer.dom(this).appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;var lthi=this.objectSnapshot;var layerTreeImpl;if(lthi){layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);}
-this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_:function(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_:function(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var OPS_TIMING_ITERATIONS=3;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=40;var AXIS_PADDING_LEFT=60;var AXIS_PADDING_RIGHT=35;var AXIS_PADDING_TOP=25;var AXIS_PADDING_BOTTOM=45;var AXIS_LABEL_PADDING=5;var AXIS_TICK_SIZE=10;var LABEL_PADDING=5;var LABEL_INTERLEAVE_OFFSET=15;var BAR_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(Polymer.dom(this).classList.contains('hidden'))return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide:function(){Polymer.dom(this).classList.add('hidden');},show:function(){Polymer.dom(this).classList.remove('hidden');if(this.pictureDataProcessed_)return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;var x=e.offsetX;var y=e.offsetY;var chartLeft=CHART_PADDING_LEFT;var chartRight=this.chartWidth_-CHART_PADDING_RIGHT;var chartTop=AXIS_PADDING_TOP;var chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;var chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.math.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
-if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)return;this.drawChartContents_();},updateChartContents:function(){if(this.requiresRedraw){this.updateChartDimensions_();}
-this.drawChartContents_();},updateChartDimensions_:function(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_:function(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)return;var ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_:function(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
-this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)return;this.drawTooltip_();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_:function(){var tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var tooltipWidth=110;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
-CHART_PADDING_LEFT;var barWidth=chartInnerWidth/this.opsTimingData_.length;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var barWidth=Math.floor(width/len);var opData;var opTiming;var opHeight;var opLabel;var barLeft;for(var b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
-height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_:function(opName){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_:function(){var len=this.opsTimingData_.length;var max=this.opsTimingData_[0].cmd_time;var min=this.opsTimingData_[len-1].cmd_time;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
-CHART_PADDING_RIGHT;var barWidth=Math.floor(totalBarWidth/len);var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
-this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';var labelTickLeft;var labelTickBottom;for(var l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
-this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_:function(ops){var opsTimingDataIndexHash_={};var timingData=this.opsTimingData_;var op;var opIndex;for(var i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
+tr.b.dispatchSimpleEvent(this,'selection-change');},createPictureBtn_(pictures){if(!(pictures instanceof Array)){pictures=[pictures];}
+const link=document.createElement('tr-ui-a-analysis-link');link.selection=function(){const layeredPicture=new tr.e.cc.LayeredPicture(pictures);const snapshot=new tr.e.cc.PictureSnapshot(layeredPicture);snapshot.picture=layeredPicture;const selection=new tr.model.EventSet();selection.push(snapshot);return selection;};Polymer.dom(link).textContent='View in Picture Debugger';return link;},onRequestSelectionChangeFromAnalysisEl_(e){if(!(e.selection instanceof tr.ui.e.chrome.cc.Selection)){return;}
+e.stopPropagation();this.selection=e.selection;},get extraHighlightsByLayerId(){return this.layerTreeQuadStackView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerTreeQuadStackView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};return{LayerView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const LayerTreeHostImplSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-layer-tree-host-impl-snapshot-view',tr.ui.analysis.ObjectSnapshotView);LayerTreeHostImplSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-lthi-s-view');this.selection_=undefined;this.layerPicker_=new tr.ui.e.chrome.cc.LayerPicker();this.layerPicker_.addEventListener('selection-change',this.onLayerPickerSelectionChanged_.bind(this));this.layerView_=new tr.ui.e.chrome.cc.LayerView();this.layerView_.addEventListener('selection-change',this.onLayerViewSelectionChanged_.bind(this));this.dragHandle_=document.createElement('tr-ui-b-drag-handle');this.dragHandle_.horizontal=false;this.dragHandle_.target=this.layerView_;Polymer.dom(this).appendChild(this.layerPicker_);Polymer.dom(this).appendChild(this.dragHandle_);Polymer.dom(this).appendChild(this.layerView_);this.onLayerViewSelectionChanged_();this.onLayerPickerSelectionChanged_();},get objectSnapshot(){return this.objectSnapshot_;},set objectSnapshot(objectSnapshot){this.objectSnapshot_=objectSnapshot;const lthi=this.objectSnapshot;let layerTreeImpl;if(lthi){layerTreeImpl=lthi.getTree(this.layerPicker_.whichTree);}
+this.layerPicker_.lthiSnapshot=lthi;this.layerView_.layerTreeImpl=layerTreeImpl;this.layerView_.regenerateContent();if(!this.selection_)return;this.selection=this.selection_.findEquivalent(lthi);},get selection(){return this.selection_;},set selection(selection){if(this.selection_===selection)return;this.selection_=selection;this.layerPicker_.selection=selection;this.layerView_.selection=selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerPickerSelectionChanged_(){this.selection_=this.layerPicker_.selection;this.layerView_.selection=this.selection;this.layerView_.layerTreeImpl=this.layerPicker_.layerTreeImpl;this.layerView_.isRenderPassQuads=this.layerPicker_.isRenderPassQuads;this.layerView_.regenerateContent();tr.b.dispatchSimpleEvent(this,'cc-selection-change');},onLayerViewSelectionChanged_(){this.selection_=this.layerView_.selection;this.layerPicker_.selection=this.selection;tr.b.dispatchSimpleEvent(this,'cc-selection-change');},get extraHighlightsByLayerId(){return this.layerView_.extraHighlightsByLayerId;},set extraHighlightsByLayerId(extraHighlightsByLayerId){this.layerView_.extraHighlightsByLayerId=extraHighlightsByLayerId;}};tr.ui.analysis.ObjectSnapshotView.register(LayerTreeHostImplSnapshotView,{typeName:'cc::LayerTreeHostImpl'});return{LayerTreeHostImplSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const OPS_TIMING_ITERATIONS=3;const CHART_PADDING_LEFT=65;const CHART_PADDING_RIGHT=40;const AXIS_PADDING_LEFT=60;const AXIS_PADDING_RIGHT=35;const AXIS_PADDING_TOP=25;const AXIS_PADDING_BOTTOM=45;const AXIS_LABEL_PADDING=5;const AXIS_TICK_SIZE=10;const LABEL_PADDING=5;const LABEL_INTERLEAVE_OFFSET=15;const BAR_PADDING=5;const VERTICAL_TICKS=5;const HUE_CHAR_CODE_ADJUSTMENT=5.7;const PictureOpsChartSummaryView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-summary-view');PictureOpsChartSummaryView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.picture_=undefined;this.pictureDataProcessed_=false;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.opsTimingData_=[];this.chartWidth_=0;this.chartHeight_=0;this.requiresRedraw_=true;this.currentBarMouseOverTarget_=null;this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));},get requiresRedraw(){return this.requiresRedraw_;},set requiresRedraw(requiresRedraw){this.requiresRedraw_=requiresRedraw;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureDataProcessed_=false;if(Polymer.dom(this).classList.contains('hidden'))return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},hide(){Polymer.dom(this).classList.add('hidden');},show(){Polymer.dom(this).classList.remove('hidden');if(this.pictureDataProcessed_)return;this.processPictureData_();this.requiresRedraw=true;this.updateChartContents();},onMouseMove_(e){const lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=null;const x=e.offsetX;const y=e.offsetY;const chartLeft=CHART_PADDING_LEFT;const chartRight=this.chartWidth_-CHART_PADDING_RIGHT;const chartTop=AXIS_PADDING_TOP;const chartBottom=this.chartHeight_-AXIS_PADDING_BOTTOM;const chartInnerWidth=chartRight-chartLeft;if(x>chartLeft&&x<chartRight&&y>chartTop&&y<chartBottom){this.currentBarMouseOverTarget_=Math.floor((x-chartLeft)/chartInnerWidth*this.opsTimingData_.length);this.currentBarMouseOverTarget_=tr.b.math.clamp(this.currentBarMouseOverTarget_,0,this.opsTimingData_.length-1);}
+if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget)return;this.drawChartContents_();},updateChartContents(){if(this.requiresRedraw){this.updateChartDimensions_();}
+this.drawChartContents_();},updateChartDimensions_(){this.chartWidth_=this.offsetWidth;this.chartHeight_=this.offsetHeight;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);},processPictureData_(){this.resetOpsTimingData_();this.pictureDataProcessed_=true;if(!this.picture_)return;let ops=this.picture_.getOps();if(!ops)return;ops=this.picture_.tagOpsWithTimings(ops);if(ops[0].cmd_time===undefined)return;this.collapseOpsToTimingBuckets_(ops);},drawChartContents_(){this.clearChartContents_();if(this.opsTimingData_.length===0){this.showNoTimingDataMessage_();return;}
+this.drawChartAxes_();this.drawBars_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===null)return;this.drawTooltip_();},drawLineAtBottomOfChart_(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();},drawTooltip_(){const tooltipData=this.opsTimingData_[this.currentBarMouseOverTarget_];const tooltipTitle=tooltipData.cmd_string;const tooltipTime=tooltipData.cmd_time.toFixed(4);const tooltipWidth=110;const tooltipHeight=40;const chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;const barWidth=chartInnerWidth/this.opsTimingData_.length;const tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);const left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;const top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.textBaseline='top';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText('Total: '+tooltipTime+'ms',left+8,top+22);},drawBars_(){const len=this.opsTimingData_.length;const max=this.opsTimingData_[0].cmd_time;const min=this.opsTimingData_[len-1].cmd_time;const width=this.chartWidth_-CHART_PADDING_LEFT-CHART_PADDING_RIGHT;const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const barWidth=Math.floor(width/len);let opData;let opTiming;let opHeight;let opLabel;let barLeft;for(let b=0;b<len;b++){opData=this.opsTimingData_[b];opTiming=opData.cmd_time/max;opHeight=Math.round(Math.max(1,opTiming*height));opLabel=opData.cmd_string;barLeft=CHART_PADDING_LEFT+b*barWidth;this.chartCtx_.fillStyle=this.getOpColor_(opLabel);this.chartCtx_.fillRect(barLeft+BAR_PADDING,AXIS_PADDING_TOP+
+height-opHeight,barWidth-2*BAR_PADDING,opHeight);}},getOpColor_(opName){const characters=opName.split('');const hue=characters.reduce(this.reduceNameToHue,0)%360;return'hsl('+hue+', 30%, 50%)';},reduceNameToHue(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},drawChartAxes_(){const len=this.opsTimingData_.length;const max=this.opsTimingData_[0].cmd_time;const min=this.opsTimingData_[len-1].cmd_time;const width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const totalBarWidth=this.chartWidth_-CHART_PADDING_LEFT-
+CHART_PADDING_RIGHT;const barWidth=Math.floor(totalBarWidth/len);const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;const tickValInterval=(max-min)/(VERTICAL_TICKS-1);let tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.moveTo(0,0);this.chartCtx_.lineTo(0,height);this.chartCtx_.lineTo(width,height);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.save();this.chartCtx_.translate(CHART_PADDING_LEFT+Math.round(barWidth*0.5),AXIS_PADDING_TOP+height+LABEL_PADDING);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='top';let labelTickLeft;let labelTickBottom;for(let l=0;l<len;l++){labelTickLeft=Math.round(l*barWidth);labelTickBottom=l%2*LABEL_INTERLEAVE_OFFSET;this.chartCtx_.save();this.chartCtx_.moveTo(labelTickLeft,-LABEL_PADDING);this.chartCtx_.lineTo(labelTickLeft,labelTickBottom);this.chartCtx_.stroke();this.chartCtx_.restore();this.chartCtx_.fillText(this.opsTimingData_[l].cmd_string,labelTickLeft,labelTickBottom);}
+this.chartCtx_.restore();this.chartCtx_.restore();},clearChartContents_(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);},collapseOpsToTimingBuckets_(ops){const opsTimingDataIndexHash_={};const timingData=this.opsTimingData_;let op;let opIndex;for(let i=0;i<ops.length;i++){op=ops[i];if(op.cmd_time===undefined)continue;opIndex=opsTimingDataIndexHash_[op.cmd_string]||null;if(opIndex===null){timingData.push({cmd_time:0,cmd_string:op.cmd_string});opIndex=timingData.length-1;opsTimingDataIndexHash_[op.cmd_string]=opIndex;}
 timingData[opIndex].cmd_time+=op.cmd_time;}
-timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_:function(count){var timingData=this.opsTimingData_;var otherSource=timingData.splice(count,timingData.length-count);var otherDestination=null;if(!otherSource.length)return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(var i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_:function(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_:function(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var BAR_PADDING=1;var BAR_WIDTH=5;var CHART_PADDING_LEFT=65;var CHART_PADDING_RIGHT=30;var CHART_PADDING_BOTTOM=35;var CHART_PADDING_TOP=20;var AXIS_PADDING_LEFT=55;var AXIS_PADDING_RIGHT=30;var AXIS_PADDING_BOTTOM=35;var AXIS_PADDING_TOP=20;var AXIS_TICK_SIZE=5;var AXIS_LABEL_PADDING=5;var VERTICAL_TICKS=5;var HUE_CHAR_CODE_ADJUSTMENT=5.7;var PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');Polymer.dom(this.usePercentileScaleCheckbox_).classList.add('use-percentile-scale');Polymer.dom(this).appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_:function(){if(this.pictureOps_===undefined)return;var totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();var ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_:function(e){var index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0){return index;}
-var x=e.offsetX;var y=e.offsetY;var totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;var chartLeft=CHART_PADDING_LEFT;var chartTop=0;var chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;var chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom){return index;}
-index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.math.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_:function(e){var barClicked=this.extractBarIndex_(e);if(barClicked===undefined)return;if(barClicked===this.selectedOpIndex){this.selectedOpIndex=undefined;}else{this.selectedOpIndex=barClicked;}
-e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_:function(e){var lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget){return;}
-this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary:function(){if(this.selectedOpIndex===undefined){return;}
-var width=this.offsetWidth;var left=this.scrollLeft;var right=left+width;var targetLeft=CHART_PADDING_LEFT+
+timingData.sort(this.sortTimingBucketsByOpTimeDescending_);this.collapseTimingBucketsToOther_(4);},collapseTimingBucketsToOther_(count){const timingData=this.opsTimingData_;const otherSource=timingData.splice(count,timingData.length-count);let otherDestination=null;if(!otherSource.length)return;timingData.push({cmd_time:0,cmd_string:'Other'});otherDestination=timingData[timingData.length-1];for(let i=0;i<otherSource.length;i++){otherDestination.cmd_time+=otherSource[i].cmd_time;}},sortTimingBucketsByOpTimeDescending_(a,b){return b.cmd_time-a.cmd_time;},resetOpsTimingData_(){this.opsTimingData_.length=0;}};return{PictureOpsChartSummaryView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const BAR_PADDING=1;const BAR_WIDTH=5;const CHART_PADDING_LEFT=65;const CHART_PADDING_RIGHT=30;const CHART_PADDING_BOTTOM=35;const CHART_PADDING_TOP=20;const AXIS_PADDING_LEFT=55;const AXIS_PADDING_RIGHT=30;const AXIS_PADDING_BOTTOM=35;const AXIS_PADDING_TOP=20;const AXIS_TICK_SIZE=5;const AXIS_LABEL_PADDING=5;const VERTICAL_TICKS=5;const HUE_CHAR_CODE_ADJUSTMENT=5.7;const PictureOpsChartView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-ops-chart-view');PictureOpsChartView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.picture_=undefined;this.pictureOps_=undefined;this.opCosts_=undefined;this.chartScale_=window.devicePixelRatio;this.chart_=document.createElement('canvas');this.chartCtx_=this.chart_.getContext('2d');Polymer.dom(this).appendChild(this.chart_);this.selectedOpIndex_=undefined;this.chartWidth_=0;this.chartHeight_=0;this.dimensionsHaveChanged_=true;this.currentBarMouseOverTarget_=undefined;this.ninetyFifthPercentileCost_=0;this.totalOpCost_=0;this.chart_.addEventListener('click',this.onClick_.bind(this));this.chart_.addEventListener('mousemove',this.onMouseMove_.bind(this));this.usePercentileScale_=false;this.usePercentileScaleCheckbox_=tr.ui.b.createCheckBox(this,'usePercentileScale','PictureOpsChartView.usePercentileScale',false,'Limit to 95%-ile');Polymer.dom(this.usePercentileScaleCheckbox_).classList.add('use-percentile-scale');Polymer.dom(this).appendChild(this.usePercentileScaleCheckbox_);},get dimensionsHaveChanged(){return this.dimensionsHaveChanged_;},set dimensionsHaveChanged(dimensionsHaveChanged){this.dimensionsHaveChanged_=dimensionsHaveChanged;},get usePercentileScale(){return this.usePercentileScale_;},set usePercentileScale(usePercentileScale){this.usePercentileScale_=usePercentileScale;this.drawChartContents_();},get numOps(){return this.opCosts_.length;},get selectedOpIndex(){return this.selectedOpIndex_;},set selectedOpIndex(selectedOpIndex){if(selectedOpIndex<0)throw new Error('Invalid index');if(selectedOpIndex>=this.numOps)throw new Error('Invalid index');this.selectedOpIndex_=selectedOpIndex;},get picture(){return this.picture_;},set picture(picture){this.picture_=picture;this.pictureOps_=picture.tagOpsWithTimings(picture.getOps());this.currentBarMouseOverTarget_=undefined;this.processPictureData_();this.dimensionsHaveChanged=true;},processPictureData_(){if(this.pictureOps_===undefined)return;let totalOpCost=0;this.opCosts_=this.pictureOps_.map(function(op){totalOpCost+=op.cmd_time;return op.cmd_time;});this.opCosts_.sort();const ninetyFifthPercentileCostIndex=Math.floor(this.opCosts_.length*0.95);this.ninetyFifthPercentileCost_=this.opCosts_[ninetyFifthPercentileCostIndex];this.maxCost_=this.opCosts_[this.opCosts_.length-1];this.totalOpCost_=totalOpCost;},extractBarIndex_(e){let index=undefined;if(this.pictureOps_===undefined||this.pictureOps_.length===0){return index;}
+const x=e.offsetX;const y=e.offsetY;const totalBarWidth=(BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length;const chartLeft=CHART_PADDING_LEFT;const chartTop=0;const chartBottom=this.chartHeight_-CHART_PADDING_BOTTOM;const chartRight=chartLeft+totalBarWidth;if(x<chartLeft||x>chartRight||y<chartTop||y>chartBottom){return index;}
+index=Math.floor((x-chartLeft)/totalBarWidth*this.pictureOps_.length);index=tr.b.math.clamp(index,0,this.pictureOps_.length-1);return index;},onClick_(e){const barClicked=this.extractBarIndex_(e);if(barClicked===undefined)return;if(barClicked===this.selectedOpIndex){this.selectedOpIndex=undefined;}else{this.selectedOpIndex=barClicked;}
+e.preventDefault();tr.b.dispatchSimpleEvent(this,'selection-changed',false);},onMouseMove_(e){const lastBarMouseOverTarget=this.currentBarMouseOverTarget_;this.currentBarMouseOverTarget_=this.extractBarIndex_(e);if(this.currentBarMouseOverTarget_===lastBarMouseOverTarget){return;}
+this.drawChartContents_();},scrollSelectedItemIntoViewIfNecessary(){if(this.selectedOpIndex===undefined){return;}
+const width=this.offsetWidth;const left=this.scrollLeft;const right=left+width;const targetLeft=CHART_PADDING_LEFT+
 (BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;if(targetLeft>left&&targetLeft<right){return;}
-this.scrollLeft=(targetLeft-width*0.5);},updateChartContents:function(){if(this.dimensionsHaveChanged){this.updateChartDimensions_();}
-this.drawChartContents_();},updateChartDimensions_:function(){if(!this.pictureOps_)return;var width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
+this.scrollLeft=(targetLeft-width*0.5);},updateChartContents(){if(this.dimensionsHaveChanged){this.updateChartDimensions_();}
+this.drawChartContents_();},updateChartDimensions_(){if(!this.pictureOps_)return;let width=CHART_PADDING_LEFT+CHART_PADDING_RIGHT+
 ((BAR_WIDTH+BAR_PADDING)*this.pictureOps_.length);if(width<this.offsetWidth){width=this.offsetWidth;}
-this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_:function(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
+this.chartWidth_=width;this.chartHeight_=this.getBoundingClientRect().height;this.chart_.width=this.chartWidth_*this.chartScale_;this.chart_.height=this.chartHeight_*this.chartScale_;this.chart_.style.width=this.chartWidth_+'px';this.chart_.style.height=this.chartHeight_+'px';this.chartCtx_.scale(this.chartScale_,this.chartScale_);this.dimensionsHaveChanged=false;},drawChartContents_(){this.clearChartContents_();if(this.pictureOps_===undefined||this.pictureOps_.length===0||this.pictureOps_[0].cmd_time===undefined){this.showNoTimingDataMessage_();return;}
 this.drawSelection_();this.drawBars_();this.drawChartAxes_();this.drawLinesAtTickMarks_();this.drawLineAtBottomOfChart_();if(this.currentBarMouseOverTarget_===undefined){return;}
-this.drawTooltip_();},drawSelection_:function(){if(this.selectedOpIndex===undefined){return;}
-var width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_:function(){var min=this.opCosts_[0];var max=this.opCosts_[this.opCosts_.length-1];var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;var tickValInterval=(max-min)/(VERTICAL_TICKS-1);var tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
-AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
-this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_:function(){var height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;var width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;var tickYInterval=height/(VERTICAL_TICKS-1);var tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(var t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
-this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_:function(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_:function(){var tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];var tooltipTitle=tooltipData.cmd_string;var tooltipTime=tooltipData.cmd_time.toFixed(4);var toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);var tooltipWidth=120;var tooltipHeight=40;var chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
-CHART_PADDING_LEFT;var barWidth=BAR_WIDTH+BAR_PADDING;var tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);var left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;var top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
-toolTipTimePercentage+'%)',left+8,top+22);},drawBars_:function(){var op;var opColor=0;var opHeight=0;var opWidth=BAR_WIDTH+BAR_PADDING;var opHover=false;var bottom=this.chartHeight_-CHART_PADDING_BOTTOM;var maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
-CHART_PADDING_TOP;var maxValue;if(this.usePercentileScale){maxValue=this.ninetyFifthPercentileCost_;}else{maxValue=this.maxCost_;}
-for(var b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex){this.chartCtx_.fillStyle='#FFFF00';}else{this.chartCtx_.fillStyle=opColor;}
-this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_:function(opName,hover){var characters=opName.split('');var hue=characters.reduce(this.reduceNameToHue,0)%360;var saturation=30;var lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue:function(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_:function(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_:function(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var THIS_DOC=document.currentScript.ownerDocument;var PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){var node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=Polymer.dom(this).querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=Polymer.dom(this).querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();var overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');var chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');var pictureInfo=Polymer.dom(this).querySelector('picture-info');Polymer.dom(pictureInfo).appendChild(overdrawCheckbox);Polymer.dom(pictureInfo).appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));var leftPanel=Polymer.dom(this).querySelector('left-panel');Polymer.dom(leftPanel).appendChild(this.drawOpsChartSummaryView_);Polymer.dom(leftPanel).appendChild(this.drawOpsView_);var middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;var rightPanel=Polymer.dom(this).querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,Polymer.dom(rightPanel).querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).appendChild(this.infoBar_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;var hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback:function(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));Polymer.dom(this).appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_:function(mutations){for(var m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_:function(){var rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());var length=rawData.length;var arrayBuffer=new ArrayBuffer(length);var uint8Array=new Uint8Array(arrayBuffer);for(var c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
-var blob=new Blob([uint8Array],{type:'application/octet-binary'});var blobUrl=window.webkitURL.createObjectURL(blob);var link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;var event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){var size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
-var bounds=this.rasterArea_.getBoundingClientRect();var selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_:function(){var style=window.getComputedStyle(this.rasterArea_);var width=Math.max(parseInt(style.width),this.picture_.layerRect.width);var height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width:width,height:height};},scheduleUpdateContents_:function(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_:function(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
+this.drawTooltip_();},drawSelection_(){if(this.selectedOpIndex===undefined){return;}
+const width=(BAR_WIDTH+BAR_PADDING)*this.selectedOpIndex;this.chartCtx_.fillStyle='rgb(223, 235, 230)';this.chartCtx_.fillRect(CHART_PADDING_LEFT,CHART_PADDING_TOP,width,this.chartHeight_-CHART_PADDING_TOP-CHART_PADDING_BOTTOM);},drawChartAxes_(){const min=this.opCosts_[0];const max=this.opCosts_[this.opCosts_.length-1];const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;const tickValInterval=(max-min)/(VERTICAL_TICKS-1);let tickVal=0;this.chartCtx_.fillStyle='#333';this.chartCtx_.strokeStyle='#777';this.chartCtx_.save();this.chartCtx_.translate(0.5,0.5);this.chartCtx_.beginPath();this.chartCtx_.moveTo(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.lineTo(AXIS_PADDING_LEFT,this.chartHeight_-
+AXIS_PADDING_BOTTOM);this.chartCtx_.lineTo(this.chartWidth_-AXIS_PADDING_RIGHT,this.chartHeight_-AXIS_PADDING_BOTTOM);this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.translate(AXIS_PADDING_LEFT,AXIS_PADDING_TOP);this.chartCtx_.font='10px Arial';this.chartCtx_.textAlign='right';this.chartCtx_.textBaseline='middle';this.chartCtx_.beginPath();for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);tickVal=(max-t*tickValInterval).toFixed(4);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(-AXIS_TICK_SIZE,tickYPosition);this.chartCtx_.fillText(tickVal,-AXIS_TICK_SIZE-AXIS_LABEL_PADDING,tickYPosition);}
+this.chartCtx_.stroke();this.chartCtx_.closePath();this.chartCtx_.restore();},drawLinesAtTickMarks_(){const height=this.chartHeight_-AXIS_PADDING_TOP-AXIS_PADDING_BOTTOM;const width=this.chartWidth_-AXIS_PADDING_LEFT-AXIS_PADDING_RIGHT;const tickYInterval=height/(VERTICAL_TICKS-1);let tickYPosition=0;this.chartCtx_.save();this.chartCtx_.translate(AXIS_PADDING_LEFT+0.5,AXIS_PADDING_TOP+0.5);this.chartCtx_.beginPath();this.chartCtx_.strokeStyle='rgba(0,0,0,0.05)';for(let t=0;t<VERTICAL_TICKS;t++){tickYPosition=Math.round(t*tickYInterval);this.chartCtx_.moveTo(0,tickYPosition);this.chartCtx_.lineTo(width,tickYPosition);this.chartCtx_.stroke();}
+this.chartCtx_.restore();this.chartCtx_.closePath();},drawLineAtBottomOfChart_(){this.chartCtx_.strokeStyle='#AAA';this.chartCtx_.beginPath();this.chartCtx_.moveTo(0,this.chartHeight_-0.5);this.chartCtx_.lineTo(this.chartWidth_,this.chartHeight_-0.5);this.chartCtx_.stroke();this.chartCtx_.closePath();},drawTooltip_(){const tooltipData=this.pictureOps_[this.currentBarMouseOverTarget_];const tooltipTitle=tooltipData.cmd_string;const tooltipTime=tooltipData.cmd_time.toFixed(4);const toolTipTimePercentage=((tooltipData.cmd_time/this.totalOpCost_)*100).toFixed(2);const tooltipWidth=120;const tooltipHeight=40;const chartInnerWidth=this.chartWidth_-CHART_PADDING_RIGHT-
+CHART_PADDING_LEFT;const barWidth=BAR_WIDTH+BAR_PADDING;const tooltipOffset=Math.round((tooltipWidth-barWidth)*0.5);const left=CHART_PADDING_LEFT+this.currentBarMouseOverTarget_*barWidth-tooltipOffset;const top=Math.round((this.chartHeight_-tooltipHeight)*0.5);this.chartCtx_.save();this.chartCtx_.shadowOffsetX=0;this.chartCtx_.shadowOffsetY=5;this.chartCtx_.shadowBlur=4;this.chartCtx_.shadowColor='rgba(0,0,0,0.4)';this.chartCtx_.strokeStyle='#888';this.chartCtx_.fillStyle='#EEE';this.chartCtx_.fillRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.shadowColor='transparent';this.chartCtx_.translate(0.5,0.5);this.chartCtx_.strokeRect(left,top,tooltipWidth,tooltipHeight);this.chartCtx_.restore();this.chartCtx_.fillStyle='#222';this.chartCtx_.textAlign='left';this.chartCtx_.textBaseline='top';this.chartCtx_.font='800 12px Arial';this.chartCtx_.fillText(tooltipTitle,left+8,top+8);this.chartCtx_.fillStyle='#555';this.chartCtx_.font='400 italic 10px Arial';this.chartCtx_.fillText(tooltipTime+'ms ('+
+toolTipTimePercentage+'%)',left+8,top+22);},drawBars_(){let op;let opColor=0;let opHeight=0;const opWidth=BAR_WIDTH+BAR_PADDING;let opHover=false;const bottom=this.chartHeight_-CHART_PADDING_BOTTOM;const maxHeight=this.chartHeight_-CHART_PADDING_BOTTOM-
+CHART_PADDING_TOP;let maxValue;if(this.usePercentileScale){maxValue=this.ninetyFifthPercentileCost_;}else{maxValue=this.maxCost_;}
+for(let b=0;b<this.pictureOps_.length;b++){op=this.pictureOps_[b];opHeight=Math.round((op.cmd_time/maxValue)*maxHeight);opHeight=Math.max(opHeight,1);opHover=(b===this.currentBarMouseOverTarget_);opColor=this.getOpColor_(op.cmd_string,opHover);if(b===this.selectedOpIndex){this.chartCtx_.fillStyle='#FFFF00';}else{this.chartCtx_.fillStyle=opColor;}
+this.chartCtx_.fillRect(CHART_PADDING_LEFT+b*opWidth,bottom-opHeight,BAR_WIDTH,opHeight);}},getOpColor_(opName,hover){const characters=opName.split('');const hue=characters.reduce(this.reduceNameToHue,0)%360;const saturation=30;const lightness=hover?'75%':'50%';return'hsl('+hue+', '+saturation+'%, '+lightness+'%)';},reduceNameToHue(previousValue,currentValue,index,array){return Math.round(previousValue+currentValue.charCodeAt(0)*HUE_CHAR_CODE_ADJUSTMENT);},clearChartContents_(){this.chartCtx_.clearRect(0,0,this.chartWidth_,this.chartHeight_);},showNoTimingDataMessage_(){this.chartCtx_.font='800 italic 14px Arial';this.chartCtx_.fillStyle='#333';this.chartCtx_.textAlign='center';this.chartCtx_.textBaseline='middle';this.chartCtx_.fillText('No timing data available.',this.chartWidth_*0.5,this.chartHeight_*0.5);}};return{PictureOpsChartView,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const THIS_DOC=document.currentScript.ownerDocument;const PictureDebugger=tr.ui.b.define('tr-ui-e-chrome-cc-picture-debugger');PictureDebugger.prototype={__proto__:HTMLDivElement.prototype,decorate(){const node=tr.ui.b.instantiateTemplate('#tr-ui-e-chrome-cc-picture-debugger-template',THIS_DOC);Polymer.dom(this).appendChild(node);this.pictureAsImageData_=undefined;this.showOverdraw_=false;this.zoomScaleValue_=1;this.sizeInfo_=Polymer.dom(this).querySelector('.size');this.rasterArea_=Polymer.dom(this).querySelector('raster-area');this.rasterCanvas_=Polymer.dom(this.rasterArea_).querySelector('canvas');this.rasterCtx_=this.rasterCanvas_.getContext('2d');this.filename_=Polymer.dom(this).querySelector('.filename');this.drawOpsChartSummaryView_=new tr.ui.e.chrome.cc.PictureOpsChartSummaryView();this.drawOpsChartView_=new tr.ui.e.chrome.cc.PictureOpsChartView();this.drawOpsChartView_.addEventListener('selection-changed',this.onChartBarClicked_.bind(this));this.exportButton_=Polymer.dom(this).querySelector('.export');this.exportButton_.addEventListener('click',this.onSaveAsSkPictureClicked_.bind(this));this.trackMouse_();const overdrawCheckbox=tr.ui.b.createCheckBox(this,'showOverdraw','pictureView.showOverdraw',false,'Show overdraw');const chartCheckbox=tr.ui.b.createCheckBox(this,'showSummaryChart','pictureView.showSummaryChart',false,'Show timing summary');const pictureInfo=Polymer.dom(this).querySelector('picture-info');Polymer.dom(pictureInfo).appendChild(overdrawCheckbox);Polymer.dom(pictureInfo).appendChild(chartCheckbox);this.drawOpsView_=new tr.ui.e.chrome.cc.PictureOpsListView();this.drawOpsView_.addEventListener('selection-changed',this.onChangeDrawOps_.bind(this));const leftPanel=Polymer.dom(this).querySelector('left-panel');Polymer.dom(leftPanel).appendChild(this.drawOpsChartSummaryView_);Polymer.dom(leftPanel).appendChild(this.drawOpsView_);const middleDragHandle=document.createElement('tr-ui-b-drag-handle');middleDragHandle.horizontal=false;middleDragHandle.target=leftPanel;const rightPanel=Polymer.dom(this).querySelector('right-panel');rightPanel.replaceChild(this.drawOpsChartView_,Polymer.dom(rightPanel).querySelector('tr-ui-e-chrome-cc-picture-ops-chart-view'));this.infoBar_=document.createElement('tr-ui-b-info-bar');Polymer.dom(this.rasterArea_).appendChild(this.infoBar_);Polymer.dom(this).insertBefore(middleDragHandle,rightPanel);this.picture_=undefined;const hkc=document.createElement('tv-ui-b-hotkey-controller');hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'h'.charCodeAt(0),callback(e){this.moveSelectedOpBy(-1);e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',thisArg:this,keyCode:'l'.charCodeAt(0),callback(e){this.moveSelectedOpBy(1);e.stopPropagation();}}));Polymer.dom(this).appendChild(hkc);this.mutationObserver_=new MutationObserver(this.onMutation_.bind(this));this.mutationObserver_.observe(leftPanel,{attributes:true});},onMutation_(mutations){for(let m=0;m<mutations.length;m++){if(mutations[m].attributeName==='style'){this.drawOpsChartSummaryView_.requiresRedraw=true;this.drawOpsChartSummaryView_.updateChartContents();this.drawOpsChartView_.dimensionsHaveChanged=true;this.drawOpsChartView_.updateChartContents();break;}}},onSaveAsSkPictureClicked_(){const rawData=tr.b.Base64.atob(this.picture_.getBase64SkpData());const length=rawData.length;const arrayBuffer=new ArrayBuffer(length);const uint8Array=new Uint8Array(arrayBuffer);for(let c=0;c<length;c++){uint8Array[c]=rawData.charCodeAt(c);}
+const blob=new Blob([uint8Array],{type:'application/octet-binary'});const blobUrl=window.webkitURL.createObjectURL(blob);const link=document.createElementNS('http://www.w3.org/1999/xhtml','a');link.href=blobUrl;link.download=this.filename_.value;const event=document.createEvent('MouseEvents');event.initMouseEvent('click',true,false,window,0,0,0,0,0,false,false,false,false,0,null);link.dispatchEvent(event);},get picture(){return this.picture_;},set picture(picture){this.drawOpsView_.picture=picture;this.drawOpsChartView_.picture=picture;this.drawOpsChartSummaryView_.picture=picture;this.picture_=picture;this.exportButton_.disabled=!this.picture_.canSave;if(picture){const size=this.getRasterCanvasSize_();this.rasterCanvas_.width=size.width;this.rasterCanvas_.height=size.height;}
+const bounds=this.rasterArea_.getBoundingClientRect();const selectorBounds=this.mouseModeSelector_.getBoundingClientRect();this.mouseModeSelector_.pos={x:(bounds.right-selectorBounds.width-10),y:bounds.top};this.rasterize_();this.scheduleUpdateContents_();},getRasterCanvasSize_(){const style=window.getComputedStyle(this.rasterArea_);const width=Math.max(parseInt(style.width),this.picture_.layerRect.width);const height=Math.max(parseInt(style.height),this.picture_.layerRect.height);return{width,height};},scheduleUpdateContents_(){if(this.updateContentsPending_)return;this.updateContentsPending_=true;tr.b.requestAnimationFrameInThisFrameIfPossible(this.updateContents_.bind(this));},updateContents_(){this.updateContentsPending_=false;if(this.picture_){Polymer.dom(this.sizeInfo_).textContent='('+
 this.picture_.layerRect.width+' x '+
 this.picture_.layerRect.height+')';}
-this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){var overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
-this.drawPicture_();},drawPicture_:function(){var size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
+this.drawOpsChartView_.updateChartContents();this.drawOpsChartView_.scrollSelectedItemIntoViewIfNecessary();if(!this.pictureAsImageData_)return;this.infoBar_.visible=false;this.infoBar_.removeAllButtons();if(this.pictureAsImageData_.error){this.infoBar_.message='Cannot rasterize...';this.infoBar_.addButton('More info...',function(e){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=this.pictureAsImageData_.error;overlay.visible=true;e.stopPropagation();return false;}.bind(this));this.infoBar_.visible=true;}
+this.drawPicture_();},drawPicture_(){const size=this.getRasterCanvasSize_();if(size.width!==this.rasterCanvas_.width){this.rasterCanvas_.width=size.width;}
 if(size.height!==this.rasterCanvas_.height){this.rasterCanvas_.height=size.height;}
-this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)return;var imgCanvas=this.pictureAsImageData_.asCanvas();var w=imgCanvas.width;var h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_:function(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_:function(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy:function(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
-this.selectedOpIndex=tr.b.math.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_:function(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_:function(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible){this.drawOpsChartSummaryView_.show();}else{this.drawOpsChartSummaryView_.hide();}},trackMouse_:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_:function(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)return;var currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_:function(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_:function(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();Polymer.dom(this).appendChild(this.pictureDebugger_);},updateContents:function(){if(this.objectSnapshot_&&this.pictureDebugger_){this.pictureDebugger_.picture=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView,};});'use strict';tr.exportTo('tr.e.cc',function(){var knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];var knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice))){return undefined;}
-var tileData;if(slice.args.data){tileData=slice.args.data;}else{tileData=slice.args.tileData;}
-if(tileData===undefined)return undefined;if(tileData.tile_id)return tileData.tile_id;var tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot)){return undefined;}
+this.rasterCtx_.clearRect(0,0,size.width,size.height);if(!this.pictureAsImageData_.imageData)return;const imgCanvas=this.pictureAsImageData_.asCanvas();const w=imgCanvas.width;const h=imgCanvas.height;this.rasterCtx_.drawImage(imgCanvas,0,0,w,h,0,0,w*this.zoomScaleValue_,h*this.zoomScaleValue_);},rasterize_(){if(this.picture_){this.picture_.rasterize({stopIndex:this.drawOpsView_.selectedOpIndex,showOverdraw:this.showOverdraw_},this.onRasterComplete_.bind(this));}},onRasterComplete_(pictureAsImageData){this.pictureAsImageData_=pictureAsImageData;this.scheduleUpdateContents_();},moveSelectedOpBy(increment){if(this.selectedOpIndex===undefined){this.selectedOpIndex=0;return;}
+this.selectedOpIndex=tr.b.math.clamp(this.selectedOpIndex+increment,0,this.numOps);},get numOps(){return this.drawOpsView_.numOps;},get selectedOpIndex(){return this.drawOpsView_.selectedOpIndex;},set selectedOpIndex(index){this.drawOpsView_.selectedOpIndex=index;this.drawOpsChartView_.selectedOpIndex=index;},onChartBarClicked_(e){this.drawOpsView_.selectedOpIndex=this.drawOpsChartView_.selectedOpIndex;},onChangeDrawOps_(e){this.rasterize_();this.scheduleUpdateContents_();this.drawOpsChartView_.selectedOpIndex=this.drawOpsView_.selectedOpIndex;},set showOverdraw(v){this.showOverdraw_=v;this.rasterize_();},set showSummaryChart(chartShouldBeVisible){if(chartShouldBeVisible){this.drawOpsChartSummaryView_.show();}else{this.drawOpsChartSummaryView_.hide();}},trackMouse_(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this.rasterArea_;Polymer.dom(this.rasterArea_).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.supportedModeMask=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.mode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.defaultMode=tr.ui.b.MOUSE_SELECTOR_MODE.ZOOM;this.mouseModeSelector_.settingsKey='pictureDebugger.mouseModeSelector';this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));},onBeginZoom_(e){this.isZooming_=true;this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const currentMouseViewPos=this.extractRelativeMousePosition_(e);this.zoomScaleValue_+=((this.lastMouseViewPos_.y-currentMouseViewPos.y)*0.001);this.zoomScaleValue_=Math.max(this.zoomScaleValue_,0.1);this.drawPicture_();this.lastMouseViewPos_=currentMouseViewPos;},onEndZoom_(e){this.lastMouseViewPos_=undefined;this.isZooming_=false;e.preventDefault();},extractRelativeMousePosition_(e){return{x:e.clientX-this.rasterArea_.offsetLeft,y:e.clientY-this.rasterArea_.offsetTop};}};return{PictureDebugger,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const PictureSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-picture-snapshot-view',tr.ui.analysis.ObjectSnapshotView);PictureSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-picture-snapshot-view');this.pictureDebugger_=new tr.ui.e.chrome.cc.PictureDebugger();Polymer.dom(this).appendChild(this.pictureDebugger_);},updateContents(){if(this.objectSnapshot_&&this.pictureDebugger_){this.pictureDebugger_.picture=this.objectSnapshot_;}}};tr.ui.analysis.ObjectSnapshotView.register(PictureSnapshotView,{typeNames:['cc::Picture','cc::LayeredPicture'],showInstances:false});return{PictureSnapshotView,};});'use strict';tr.exportTo('tr.e.cc',function(){const knownRasterTaskNames=['TileManager::RunRasterTask','RasterWorkerPoolTaskImpl::RunRasterOnThread','RasterWorkerPoolTaskImpl::Raster','RasterTaskImpl::Raster','cc::RasterTask','RasterTask'];const knownAnalysisTaskNames=['TileManager::RunAnalyzeTask','RasterWorkerPoolTaskImpl::RunAnalysisOnThread','RasterWorkerPoolTaskImpl::Analyze','RasterTaskImpl::Analyze','cc::AnalyzeTask','AnalyzeTask'];function getTileFromRasterTaskSlice(slice){if(!(isSliceDoingRasterization(slice)||isSliceDoingAnalysis(slice))){return undefined;}
+let tileData;if(slice.args.data){tileData=slice.args.data;}else{tileData=slice.args.tileData;}
+if(tileData===undefined)return undefined;if(tileData.tile_id)return tileData.tile_id;const tile=tileData.tileId;if(!(tile instanceof tr.e.cc.TileSnapshot)){return undefined;}
 return tileData.tileId;}
 function isSliceDoingRasterization(slice){return knownRasterTaskNames.includes(slice.title);}
 function isSliceDoingAnalysis(slice){return knownAnalysisTaskNames.includes(slice.title);}
-return{getTileFromRasterTaskSlice:getTileFromRasterTaskSlice,isSliceDoingRasterization:isSliceDoingRasterization,isSliceDoingAnalysis:isSliceDoingAnalysis};});'use strict';tr.exportTo('tr.ui.analysis',function(){var AnalysisSubView={set tabLabel(label){Polymer.dom(this).setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}};var allTypeInfosByEventProto=new Map();var onlyRootTypeInfosByEventProto=undefined;var eventProtoToRootTypeInfoMap=undefined;function AnalysisSubViewTypeInfo(eventConstructor,options){if(options.multi===undefined){throw new Error('missing field: multi');}
+return{getTileFromRasterTaskSlice,isSliceDoingRasterization,isSliceDoingAnalysis};});'use strict';tr.exportTo('tr.ui.analysis',function(){const AnalysisSubView={set tabLabel(label){Polymer.dom(this).setAttribute('tab-label',label);},get tabLabel(){return this.getAttribute('tab-label');},get requiresTallView(){return false;},get relatedEventsToHighlight(){return undefined;},set selection(selection){throw new Error('Not implemented!');},get selection(){throw new Error('Not implemented!');}};const allTypeInfosByEventProto=new Map();let onlyRootTypeInfosByEventProto=undefined;let eventProtoToRootTypeInfoMap=undefined;function AnalysisSubViewTypeInfo(eventConstructor,options){if(options.multi===undefined){throw new Error('missing field: multi');}
 if(options.title===undefined){throw new Error('missing field: title');}
 this.eventConstructor=eventConstructor;this.singleTagName=undefined;this.singleTitle=undefined;this.multiTagName=undefined;this.multiTitle=undefined;this.childrenTypeInfos_=undefined;}
-AnalysisSubViewTypeInfo.prototype={get childrenTypeInfos(){return this.childrenTypeInfos_;},resetchildrenTypeInfos:function(){this.childrenTypeInfos_=[];}};AnalysisSubView.register=function(tagName,eventConstructor,options){var typeInfo=allTypeInfosByEventProto.get(eventConstructor.prototype);if(typeInfo===undefined){typeInfo=new AnalysisSubViewTypeInfo(eventConstructor,options);allTypeInfosByEventProto.set(typeInfo.eventConstructor.prototype,typeInfo);onlyRootTypeInfosByEventProto=undefined;}
+AnalysisSubViewTypeInfo.prototype={get childrenTypeInfos(){return this.childrenTypeInfos_;},resetchildrenTypeInfos(){this.childrenTypeInfos_=[];}};AnalysisSubView.register=function(tagName,eventConstructor,options){let typeInfo=allTypeInfosByEventProto.get(eventConstructor.prototype);if(typeInfo===undefined){typeInfo=new AnalysisSubViewTypeInfo(eventConstructor,options);allTypeInfosByEventProto.set(typeInfo.eventConstructor.prototype,typeInfo);onlyRootTypeInfosByEventProto=undefined;}
 if(!options.multi){if(typeInfo.singleTagName!==undefined){throw new Error('SingleTagName already set');}
 typeInfo.singleTagName=tagName;typeInfo.singleTitle=options.title;}else{if(typeInfo.multiTagName!==undefined){throw new Error('MultiTagName already set');}
 typeInfo.multiTagName=tagName;typeInfo.multiTitle=options.title;}
-return typeInfo;};function rebuildRootSubViewTypeInfos(){onlyRootTypeInfosByEventProto=new Map();allTypeInfosByEventProto.forEach(function(typeInfo){typeInfo.resetchildrenTypeInfos();});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){var eventPrototype=typeInfo.eventConstructor.prototype;var lastEventProto=eventPrototype;var curEventProto=eventPrototype.__proto__;while(true){if(!allTypeInfosByEventProto.has(curEventProto)){var rootTypeInfo=allTypeInfosByEventProto.get(lastEventProto);var rootEventProto=lastEventProto;var isNew=onlyRootTypeInfosByEventProto.has(rootEventProto);onlyRootTypeInfosByEventProto.set(rootEventProto,rootTypeInfo);break;}
-lastEventProto=curEventProto;curEventProto=curEventProto.__proto__;}});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){var eventPrototype=typeInfo.eventConstructor.prototype;var parentEventProto=eventPrototype.__proto__;var parentTypeInfo=allTypeInfosByEventProto.get(parentEventProto);if(!parentTypeInfo)return;parentTypeInfo.childrenTypeInfos.push(typeInfo);});eventProtoToRootTypeInfoMap=new Map();allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){var eventPrototype=typeInfo.eventConstructor.prototype;var curEventProto=eventPrototype;while(true){if(onlyRootTypeInfosByEventProto.has(curEventProto)){var rootTypeInfo=onlyRootTypeInfosByEventProto.get(curEventProto);eventProtoToRootTypeInfoMap.set(eventPrototype,rootTypeInfo);break;}
+return typeInfo;};function rebuildRootSubViewTypeInfos(){onlyRootTypeInfosByEventProto=new Map();allTypeInfosByEventProto.forEach(function(typeInfo){typeInfo.resetchildrenTypeInfos();});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;let lastEventProto=eventPrototype;let curEventProto=eventPrototype.__proto__;while(true){if(!allTypeInfosByEventProto.has(curEventProto)){const rootTypeInfo=allTypeInfosByEventProto.get(lastEventProto);const rootEventProto=lastEventProto;const isNew=onlyRootTypeInfosByEventProto.has(rootEventProto);onlyRootTypeInfosByEventProto.set(rootEventProto,rootTypeInfo);break;}
+lastEventProto=curEventProto;curEventProto=curEventProto.__proto__;}});allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;const parentEventProto=eventPrototype.__proto__;const parentTypeInfo=allTypeInfosByEventProto.get(parentEventProto);if(!parentTypeInfo)return;parentTypeInfo.childrenTypeInfos.push(typeInfo);});eventProtoToRootTypeInfoMap=new Map();allTypeInfosByEventProto.forEach(function(typeInfo,eventProto){const eventPrototype=typeInfo.eventConstructor.prototype;let curEventProto=eventPrototype;while(true){if(onlyRootTypeInfosByEventProto.has(curEventProto)){const rootTypeInfo=onlyRootTypeInfosByEventProto.get(curEventProto);eventProtoToRootTypeInfoMap.set(eventPrototype,rootTypeInfo);break;}
 curEventProto=curEventProto.__proto__;}});}
-function findLowestTypeInfoForEvents(thisTypeInfo,events){if(events.length===0)return thisTypeInfo;var event0=tr.b.getFirstElement(events);var candidateSubTypeInfo;for(var i=0;i<thisTypeInfo.childrenTypeInfos.length;i++){var childTypeInfo=thisTypeInfo.childrenTypeInfos[i];if(event0 instanceof childTypeInfo.eventConstructor){candidateSubTypeInfo=childTypeInfo;break;}}
-if(!candidateSubTypeInfo)return thisTypeInfo;var allMatch=true;for(var event of events){if(event instanceof candidateSubTypeInfo.eventConstructor)continue;allMatch=false;break;}
+function findLowestTypeInfoForEvents(thisTypeInfo,events){if(events.length===0)return thisTypeInfo;const event0=tr.b.getFirstElement(events);let candidateSubTypeInfo;for(let i=0;i<thisTypeInfo.childrenTypeInfos.length;i++){const childTypeInfo=thisTypeInfo.childrenTypeInfos[i];if(event0 instanceof childTypeInfo.eventConstructor){candidateSubTypeInfo=childTypeInfo;break;}}
+if(!candidateSubTypeInfo)return thisTypeInfo;let allMatch=true;for(const event of events){if(event instanceof candidateSubTypeInfo.eventConstructor)continue;allMatch=false;break;}
 if(!allMatch){return thisTypeInfo;}
 return findLowestTypeInfoForEvents(candidateSubTypeInfo,events);}
-var primaryEventProtoToTypeInfoMap=new Map();function getRootTypeInfoForEvent(event){var curProto=event.__proto__;var typeInfo=primaryEventProtoToTypeInfoMap.get(curProto);if(typeInfo)return typeInfo;return getRootTypeInfoForEventSlow(event);}
-function getRootTypeInfoForEventSlow(event){var typeInfo;var curProto=event.__proto__;while(true){if(curProto===Object.prototype){throw new Error('No view registered for '+event.toString());}
+const primaryEventProtoToTypeInfoMap=new Map();function getRootTypeInfoForEvent(event){const curProto=event.__proto__;const typeInfo=primaryEventProtoToTypeInfoMap.get(curProto);if(typeInfo)return typeInfo;return getRootTypeInfoForEventSlow(event);}
+function getRootTypeInfoForEventSlow(event){let typeInfo;let curProto=event.__proto__;while(true){if(curProto===Object.prototype){throw new Error('No view registered for '+event.toString());}
 typeInfo=onlyRootTypeInfosByEventProto.get(curProto);if(typeInfo){primaryEventProtoToTypeInfoMap.set(event.__proto__,typeInfo);return typeInfo;}
 curProto=curProto.__proto__;}}
 AnalysisSubView.getEventsOrganizedByTypeInfo=function(selection){if(onlyRootTypeInfosByEventProto===undefined){rebuildRootSubViewTypeInfos();}
-var eventsByRootTypeInfo=tr.b.groupIntoMap(selection,function(event){return getRootTypeInfoForEvent(event);},this,tr.model.EventSet);var eventsByLowestTypeInfo=new Map();eventsByRootTypeInfo.forEach(function(events,typeInfo){var lowestTypeInfo=findLowestTypeInfoForEvents(typeInfo,events);eventsByLowestTypeInfo.set(lowestTypeInfo,events);});return eventsByLowestTypeInfo;};return{AnalysisSubView,AnalysisSubViewTypeInfo,};});Polymer({is:'tr-ui-a-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView]});'use strict';Polymer({is:'tr-ui-a-stack-frame',ready:function(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){var table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
-var hasName=false;var hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});var cols=[];if(hasName){cols.push({title:'Name',value:function(row){return row.name;}});}
-if(hasTitle){cols.push({title:'Title',value:function(row){return row.title;}});}
-table.tableColumns=cols;table.rebuild();},tableForTesting:function(){return this.$.table;}});'use strict';Polymer({is:'tr-ui-a-single-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],properties:{isFlow:{type:Boolean,value:false}},ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
-this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks:function(selection){this.currentSelection_=selection;this.updateContents_();},getFlowEventRows_:function(event){var rows=this.getEventRowsHelper_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});Polymer.dom(linkEl).textContent=slice.userFriendlyName;return linkEl;}
-rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;},getEventRowsHelper_:function(event){var rows=[];if(event.error){rows.push({name:'Error',value:event.error});}
+const eventsByRootTypeInfo=tr.b.groupIntoMap(selection,function(event){return getRootTypeInfoForEvent(event);},this,tr.model.EventSet);const eventsByLowestTypeInfo=new Map();eventsByRootTypeInfo.forEach(function(events,typeInfo){const lowestTypeInfo=findLowestTypeInfoForEvents(typeInfo,events);eventsByLowestTypeInfo.set(lowestTypeInfo,events);});return eventsByLowestTypeInfo;};return{AnalysisSubView,AnalysisSubViewTypeInfo,};});Polymer({is:'tr-ui-a-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView]});'use strict';Polymer({is:'tr-ui-a-stack-frame',ready(){this.stackFrame_=undefined;this.$.table.tableColumns=[];this.$.table.showHeader=true;},get stackFrame(){return this.stackFrame_;},set stackFrame(stackFrame){const table=this.$.table;this.stackFrame_=stackFrame;if(stackFrame===undefined){table.tableColumns=[];table.tableRows=[];table.rebuild();return;}
+let hasName=false;let hasTitle=false;table.tableRows=stackFrame.stackTrace;table.tableRows.forEach(function(row){hasName|=row.name!==undefined;hasTitle|=row.title!==undefined;});const cols=[];if(hasName){cols.push({title:'Name',value(row){return row.name;}});}
+if(hasTitle){cols.push({title:'Title',value(row){return row.title;}});}
+table.tableColumns=cols;table.rebuild();},tableForTesting(){return this.$.table;}});'use strict';Polymer({is:'tr-ui-a-single-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],properties:{isFlow:{type:Boolean,value:false}},ready(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
+this.setSelectionWithoutErrorChecks(selection);},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;this.updateContents_();},getFlowEventRows_(event){const rows=this.getEventRowsHelper_(event);rows.splice(0,0,{name:'ID',value:event.id});function createLinkTo(slice){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(slice);});Polymer.dom(linkEl).textContent=slice.userFriendlyName;return linkEl;}
+rows.push({name:'From',value:createLinkTo(event.startSlice)});rows.push({name:'To',value:createLinkTo(event.endSlice)});return rows;},getEventRowsHelper_(event){const rows=[];if(event.error){rows.push({name:'Error',value:event.error});}
 if(event.title){rows.push({name:'Title',value:event.title});}
 if(event.category){rows.push({name:'Category',value:event.category});}
-if(event.model!==undefined){var ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined){rows.push({name:'User Friendly Category',value:ufc});}}
+if(event.model!==undefined){const ufc=event.model.getUserFriendlyCategoryFromEvent(event);if(ufc!==undefined){rows.push({name:'User Friendly Category',value:ufc});}}
 if(event.name){rows.push({name:'Name',value:event.name});}
 rows.push({name:'Start',value:tr.v.ui.createScalarSpan(event.start,{unit:tr.b.Unit.byName.timeStampInMs})});if(event.duration){rows.push({name:'Wall Duration',value:tr.v.ui.createScalarSpan(event.duration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
 if(event.cpuDuration){rows.push({name:'CPU Duration',value:tr.v.ui.createScalarSpan(event.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs})});}
 if(event.subSlices!==undefined&&event.subSlices.length!==0){if(event.selfTime){rows.push({name:'Self Time',value:tr.v.ui.createScalarSpan(event.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
-if(event.cpuSelfTime){var cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
+if(event.cpuSelfTime){const cpuSelfTimeEl=tr.v.ui.createScalarSpan(event.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs});if(event.cpuSelfTime>event.selfTime){cpuSelfTimeEl.warning=' Note that CPU Self Time is larger than Self Time. '+'This is a known limitation of this system, which occurs '+'due to several subslices, rounding issues, and imprecise '+'time at which we get cpu- and real-time.';}
 rows.push({name:'CPU Self Time',value:cpuSelfTimeEl});}}
 if(event.durationInUserTime){rows.push({name:'Duration (U)',value:tr.v.ui.createScalarSpan(event.durationInUserTime,{unit:tr.b.Unit.byName.timeDurationInMs})});}
-function createStackFrameEl(sf){var sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
+function createStackFrameEl(sf){const sfEl=document.createElement('tr-ui-a-stack-frame');sfEl.stackFrame=sf;return sfEl;}
 if(event.startStackFrame&&event.endStackFrame){if(event.startStackFrame===event.endStackFrame){rows.push({name:'Start+End Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else{rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}}else if(event.startStackFrame){rows.push({name:'Start Stack Trace',value:createStackFrameEl(event.startStackFrame)});}else if(event.endStackFrame){rows.push({name:'End Stack Trace',value:createStackFrameEl(event.endStackFrame)});}
-if(event.info){var descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}}
-if(event.associatedAlerts.length){var alertSubRows=[];event.associatedAlerts.forEach(function(alert){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
-return rows;},getEventRows_:function(event){if(this.isFlow){return this.getFlowEventRows_(event);}
-return this.getEventRowsHelper_(event);},addArgsToRows_:function(rows,args){var n=0;for(var argName in args){n+=1;}
-if(n>0){var subRows=[];for(var argName in args){n+=1;}
-if(n>0){var subRows=[];for(var argName in args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
-rows.push({name:'Args',value:'',isExpanded:true,subRows:subRows});}}},addContextsToRows_:function(rows,contexts){if(contexts.length){var subRows=contexts.map(function(context){var contextView=document.createElement('tr-ui-a-generic-object-view');contextView.object=context;return{name:'Context',value:contextView};});rows.push({name:'Contexts',value:'',isExpanded:true,subRows:subRows});}},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var event=tr.b.getOnlyElement(this.currentSelection_);var rows=this.getEventRows_(event);if(event.argsStripped){rows.push({name:'Args',value:'Stripped'});}else{this.addArgsToRows_(rows,event.args);}
-this.addContextsToRows_(rows,event.contexts);var customizeRowsEvent=new tr.b.Event('customize-rows');customizeRowsEvent.rows=rows;this.dispatchEvent(customizeRowsEvent);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-e-chrome-cc-raster-task-view',created:function(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_:function(hadCpuDurations){var timeSpanConfig={unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};var columns=[{title:'Layer',value:function(row){if(row.isTotals)return'Totals';if(row.layer){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}
-return'Layer '+row.layerId;},width:'250px'},{title:'Num Tiles',value:function(row){return row.numTiles;},cmp:function(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value:function(row){return row.numAnalysisTasks;},cmp:function(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value:function(row){return row.numRasterTasks;},cmp:function(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp:function(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp:function(a,b){return a.cpuDuration-b.cpuDuration;}});}
-var colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
-for(var i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
-this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_:function(){var table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
-var lthi=tr.e.cc.getTileFromRasterTaskSlice(tr.b.getFirstElement(this.selection_)).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);var costsByLayerId={};function getCurrentCostsForLayerId(tile){var layerId=tile.layerId;var lthi=tile.containingSnapshot;var layer;if(lthi.activeTree){layer=lthi.activeTree.findLayerWithId(layerId);}
+if(event.info){const descriptionEl=tr.ui.b.createDiv({textContent:event.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(event.info.docLinks){event.info.docLinks.forEach(function(linkObject){const linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}}
+if(event.associatedAlerts.length){const alertSubRows=[];event.associatedAlerts.forEach(function(alert){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(alert);},alert.info.description);alertSubRows.push({name:alert.title,value:linkEl});});rows.push({name:'Alerts',value:'',isExpanded:true,subRows:alertSubRows});}
+return rows;},getEventRows_(event){if(this.isFlow){return this.getFlowEventRows_(event);}
+return this.getEventRowsHelper_(event);},addArgsToRows_(rows,args){let n=0;for(const argName in args){n+=1;}
+if(n>0){const subRows=[];for(const argName in args){n+=1;}
+if(n>0){const subRows=[];for(const argName in args){const argView=document.createElement('tr-ui-a-generic-object-view');argView.object=args[argName];subRows.push({name:argName,value:argView});}
+rows.push({name:'Args',value:'',isExpanded:true,subRows});}}},addContextsToRows_(rows,contexts){if(contexts.length){const subRows=contexts.map(function(context){const contextView=document.createElement('tr-ui-a-generic-object-view');contextView.object=context;return{name:'Context',value:contextView};});rows.push({name:'Contexts',value:'',isExpanded:true,subRows});}},updateContents_(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+const event=tr.b.getOnlyElement(this.currentSelection_);const rows=this.getEventRows_(event);if(event.argsStripped){rows.push({name:'Args',value:'Stripped'});}else{this.addArgsToRows_(rows,event.args);}
+this.addContextsToRows_(rows,event.contexts);const customizeRowsEvent=new tr.b.Event('customize-rows');customizeRowsEvent.rows=rows;this.dispatchEvent(customizeRowsEvent);this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-e-chrome-cc-raster-task-view',created(){this.selection_=undefined;},set selection(selection){this.selection_=selection;this.updateContents_();},updateColumns_(hadCpuDurations){const timeSpanConfig={unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument};const columns=[{title:'Layer',value(row){if(row.isTotals)return'Totals';if(row.layer){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.ui.e.chrome.cc.LayerSelection(costs.layer);},'Layer '+row.layerId);return linkEl;}
+return'Layer '+row.layerId;},width:'250px'},{title:'Num Tiles',value(row){return row.numTiles;},cmp(a,b){return a.numTiles-b.numTiles;}},{title:'Num Analysis Tasks',value(row){return row.numAnalysisTasks;},cmp(a,b){return a.numAnalysisTasks-b.numAnalysisTasks;}},{title:'Num Raster Tasks',value(row){return row.numRasterTasks;},cmp(a,b){return a.numRasterTasks-b.numRasterTasks;}},{title:'Wall Duration (ms)',value(row){return tr.v.ui.createScalarSpan(row.duration,timeSpanConfig);},cmp(a,b){return a.duration-b.duration;}}];if(hadCpuDurations){columns.push({title:'CPU Duration (ms)',value(row){return tr.v.ui.createScalarSpan(row.cpuDuration,timeSpanConfig);},cmp(a,b){return a.cpuDuration-b.cpuDuration;}});}
+let colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
+for(let i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
+this.$.content.tableColumns=columns;this.$.content.sortColumnIndex=columns.length-1;},updateContents_(){const table=this.$.content;if(this.selection_.length===0){this.$.link.setSelectionAndContent(undefined,'');table.tableRows=[];table.footerRows=[];table.rebuild();return;}
+const lthi=tr.e.cc.getTileFromRasterTaskSlice(tr.b.getFirstElement(this.selection_)).containingSnapshot;this.$.link.setSelectionAndContent(function(){return new tr.model.EventSet(lthi);},lthi.userFriendlyName);const costsByLayerId={};function getCurrentCostsForLayerId(tile){const layerId=tile.layerId;const lthi=tile.containingSnapshot;let layer;if(lthi.activeTree){layer=lthi.activeTree.findLayerWithId(layerId);}
 if(layer===undefined&&lthi.pendingTree){layer=lthi.pendingTree.findLayerWithId(layerId);}
-if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId:layerId,layer:layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
+if(costsByLayerId[layerId]===undefined){costsByLayerId[layerId]={layerId,layer,numTiles:0,numAnalysisTasks:0,numRasterTasks:0,duration:0,cpuDuration:0};}
 return costsByLayerId[layerId];}
-var totalDuration=0;var totalCpuDuration=0;var totalNumAnalyzeTasks=0;var totalNumRasterizeTasks=0;var hadCpuDurations=false;var tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);var curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
+let totalDuration=0;let totalCpuDuration=0;let totalNumAnalyzeTasks=0;let totalNumRasterizeTasks=0;let hadCpuDurations=false;const tilesThatWeHaveSeen={};this.selection_.forEach(function(slice){const tile=tr.e.cc.getTileFromRasterTaskSlice(slice);const curCosts=getCurrentCostsForLayerId(tile);if(!tilesThatWeHaveSeen[tile.objectInstance.id]){tilesThatWeHaveSeen[tile.objectInstance.id]=true;curCosts.numTiles+=1;}
 if(tr.e.cc.isSliceDoingAnalysis(slice)){curCosts.numAnalysisTasks+=1;totalNumAnalyzeTasks+=1;}else{curCosts.numRasterTasks+=1;totalNumRasterizeTasks+=1;}
-curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=tr.b.dictionaryValues(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:tr.b.dictionaryLength(tilesThatWeHaveSeen),numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);var whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok){throw new Error('Fail: '+whySupported.why);}
-this.slices_=tr.b.asArray(selection);this.tiles_=this.slices_.map(function(slice){var tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined){throw new Error('This should never happen due to .supports check.');}
+curCosts.duration+=slice.duration;totalDuration+=slice.duration;if(slice.cpuDuration!==undefined){curCosts.cpuDuration+=slice.cpuDuration;totalCpuDuration+=slice.cpuDuration;hadCpuDurations=true;}});this.updateColumns_(hadCpuDurations);table.tableRows=Object.values(costsByLayerId);table.rebuild();table.footerRows=[{isTotals:true,numTiles:Object.keys(tilesThatWeHaveSeen).length,numAnalysisTasks:totalNumAnalyzeTasks,numRasterTasks:totalNumRasterizeTasks,duration:totalDuration,cpuDuration:totalCpuDuration}];}});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){function RasterTaskSelection(selection){tr.ui.e.chrome.cc.Selection.call(this);const whySupported=RasterTaskSelection.whySuported(selection);if(!whySupported.ok){throw new Error('Fail: '+whySupported.why);}
+this.slices_=tr.b.asArray(selection);this.tiles_=this.slices_.map(function(slice){const tile=tr.e.cc.getTileFromRasterTaskSlice(slice);if(tile===undefined){throw new Error('This should never happen due to .supports check.');}
 return tile;});}
 RasterTaskSelection.whySuported=function(selection){if(!(selection instanceof tr.model.EventSet)){return{ok:false,why:'Must be selection'};}
 if(selection.length===0){return{ok:false,why:'Selection must be non empty'};}
-var referenceSnapshot=undefined;for(var event of selection){if(!(event instanceof tr.model.Slice)){return{ok:false,why:'Not a slice'};}
-var tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined){return{ok:false,why:'No tile found'};}
+let referenceSnapshot=undefined;for(const event of selection){if(!(event instanceof tr.model.Slice)){return{ok:false,why:'Not a slice'};}
+const tile=tr.e.cc.getTileFromRasterTaskSlice(event);if(tile===undefined){return{ok:false,why:'No tile found'};}
 if(!referenceSnapshot){referenceSnapshot=tile.containingSnapshot;}else{if(tile.containingSnapshot!==referenceSnapshot){return{ok:false,why:'Raster tasks are from different compositor instances'};}}}
-return{ok:true};};RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){var tile0=this.tiles_[0];var allSameLayer=this.tiles_.every(function(tile){tile.layerId===tile0.layerId;});if(allSameLayer){return tile0.layerId;}
-return undefined;},get extraHighlightsByLayerId(){var highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined){highlights[tile.layerId]=[];}
-var slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis:function(){var sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});var analysis;if(sel.length===1){analysis=document.createElement('tr-ui-a-single-event-sub-view');}else{analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');}
-analysis.selection=sel;return analysis;},findEquivalent:function(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){var TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();Polymer.dom(this).appendChild(this.layerTreeView_);},updateContents:function(){var tile=this.objectSnapshot_;var layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView,};});'use strict';tr.exportTo('tr.e.gpu',function(){var AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
+return{ok:true};};RasterTaskSelection.supports=function(selection){return RasterTaskSelection.whySuported(selection).ok;};RasterTaskSelection.prototype={__proto__:tr.ui.e.chrome.cc.Selection.prototype,get specicifity(){return 3;},get associatedLayerId(){const tile0=this.tiles_[0];const allSameLayer=this.tiles_.every(function(tile){tile.layerId===tile0.layerId;});if(allSameLayer){return tile0.layerId;}
+return undefined;},get extraHighlightsByLayerId(){const highlights={};this.tiles_.forEach(function(tile,i){if(highlights[tile.layerId]===undefined){highlights[tile.layerId]=[];}
+const slice=this.slices_[i];highlights[tile.layerId].push({colorKey:slice.title,rect:tile.layerRect});},this);return highlights;},createAnalysis(){const sel=new tr.model.EventSet();this.slices_.forEach(function(slice){sel.push(slice);});let analysis;if(sel.length===1){analysis=document.createElement('tr-ui-a-single-event-sub-view');}else{analysis=document.createElement('tr-ui-e-chrome-cc-raster-task-view');}
+analysis.selection=sel;return analysis;},findEquivalent(lthi){return undefined;},get containingSnapshot(){return this.tiles_[0].containingSnapshot;}};return{RasterTaskSelection,};});'use strict';tr.exportTo('tr.ui.e.chrome.cc',function(){const TileSnapshotView=tr.ui.b.define('tr-ui-e-chrome-cc-tile-snapshot-view',tr.ui.analysis.ObjectSnapshotView);TileSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-cc-tile-snapshot-view');this.layerTreeView_=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();Polymer.dom(this).appendChild(this.layerTreeView_);},updateContents(){const tile=this.objectSnapshot_;const layerTreeHostImpl=tile.containingSnapshot;if(!layerTreeHostImpl)return;this.layerTreeView_.objectSnapshot=layerTreeHostImpl;this.layerTreeView_.selection=new tr.ui.e.chrome.cc.TileSelection(tile);}};tr.ui.analysis.ObjectSnapshotView.register(TileSnapshotView,{typeName:'cc::Tile',showInTrackView:false});return{TileSnapshotView,};});'use strict';tr.exportTo('tr.e.gpu',function(){const AsyncSlice=tr.model.AsyncSlice;function GpuAsyncSlice(){AsyncSlice.apply(this,arguments);}
 GpuAsyncSlice.prototype={__proto__:AsyncSlice.prototype,get viewSubGroupTitle(){if(this.args.channel){if(this.category==='disabled-by-default-gpu.device'){return'Device.'+this.args.channel;}
 return'Service.'+this.args.channel;}
-return this.title;}};AsyncSlice.subTypes.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice,};});'use strict';tr.exportTo('tr.e.gpu',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
-StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize:function(){this.screenshot_=undefined;},initialize:function(){if(this.args.screenshot){this.screenshot_=this.args.screenshot;}},get screenshot(){return this.screenshot_;}};ObjectSnapshot.subTypes.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot,};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){var StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){Polymer.dom(this).classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');Polymer.dom(this).appendChild(this.screenshotImage_);},updateContents:function(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
-this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-layout-tree-sub-view',behaviors:['tr-ui-a-sub-view'],set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_:function(){this.set('$.content.textContent','');if(!this.currentSelection_)return;var columns=[{title:'Tag/Name',value:function(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value:function(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value:function(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value:function(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value:function(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value:function(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value:function(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value:function(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value:function(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value:function(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value:function(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value:function(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value:function(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value:function(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value:function(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value:function(layoutObject){if(layoutObject.tableRow===undefined){return'';}
-return layoutObject.tableRow;}},{title:'col',value:function(layoutObject){if(layoutObject.tableCol===undefined){return'';}
-return layoutObject.tableCol;}},{title:'rowSpan',value:function(layoutObject){if(layoutObject.tableRowSpan===undefined){return'';}
-return layoutObject.tableRowSpan;}},{title:'colSpan',value:function(layoutObject){if(layoutObject.tableColSpan===undefined){return'';}
-return layoutObject.tableColSpan;}},{title:'address',value:function(layoutObject){return layoutObject.id.toString(16);}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();Polymer.dom(this.$.content).appendChild(table);},});return{};});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:false,title:'Layout Tree',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:true,title:'Layout Trees',});'use strict';tr.exportTo('tr.ui.behaviors',function(){var SidePanel={get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel:function(m){throw new Error('Not implemented');}};return{SidePanel,};});'use strict';tr.exportTo('tr.ui.side_panel',function(){function SidePanelRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(SidePanelRegistry,options);return{SidePanelRegistry,};});'use strict';tr.exportTo('tr.ui.e.s',function(){var BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;var FrameTreeNodeSnapshot=tr.e.chrome.FrameTreeNodeSnapshot;var RenderFrameSnapshot=tr.e.chrome.RenderFrameSnapshot;var TopLevelSnapshot=tr.e.chrome.TopLevelSnapshot;var BlameContextInstance=tr.e.chrome.BlameContextInstance;var FrameTreeNodeInstance=tr.e.chrome.FrameTreeNodeInstance;var RenderFrameInstance=tr.e.chrome.RenderFrameInstance;var TopLevelInstance=tr.e.chrome.TopLevelInstance;function Row(context){this.subRows=undefined;this.contexts=[];this.type=undefined;this.renderer='N/A';this.url=undefined;this.time=0;this.eventsOfInterest=new tr.model.EventSet();if(context===undefined)return;this.type=context.objectInstance.blameContextType;this.contexts.push(context);if(context instanceof FrameTreeNodeSnapshot){if(context.renderFrame){this.contexts.push(context.renderFrame);this.renderer=context.renderFrame.objectInstance.parent.pid;}}else if(context instanceof RenderFrameSnapshot){if(context.frameTreeNode){this.contexts.push(context.frameTreeNode);}
+return this.title;}};AsyncSlice.subTypes.register(GpuAsyncSlice,{categoryParts:['disabled-by-default-gpu.device','disabled-by-default-gpu.service']});return{GpuAsyncSlice,};});'use strict';tr.exportTo('tr.e.gpu',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function StateSnapshot(){ObjectSnapshot.apply(this,arguments);}
+StateSnapshot.prototype={__proto__:ObjectSnapshot.prototype,preInitialize(){this.screenshot_=undefined;},initialize(){if(this.args.screenshot){this.screenshot_=this.args.screenshot;}},get screenshot(){return this.screenshot_;}};ObjectSnapshot.subTypes.register(StateSnapshot,{typeName:'gpu::State'});return{StateSnapshot,};});'use strict';tr.exportTo('tr.ui.e.chrome.gpu',function(){const StateSnapshotView=tr.ui.b.define('tr-ui-e-chrome-gpu-state-snapshot-view',tr.ui.analysis.ObjectSnapshotView);StateSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-chrome-gpu-state-snapshot-view');this.screenshotImage_=document.createElement('img');Polymer.dom(this).appendChild(this.screenshotImage_);},updateContents(){if(this.objectSnapshot_&&this.objectSnapshot_.screenshot){this.screenshotImage_.src='data:image/png;base64,'+
+this.objectSnapshot_.screenshot;}}};tr.ui.analysis.ObjectSnapshotView.register(StateSnapshotView,{typeName:'gpu::State'});return{StateSnapshotView,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-layout-tree-sub-view',behaviors:['tr-ui-a-sub-view'],set selection(selection){this.currentSelection_=selection;this.updateContents_();},get selection(){return this.currentSelection_;},updateContents_(){this.set('$.content.textContent','');if(!this.currentSelection_)return;const columns=[{title:'Tag/Name',value(layoutObject){return layoutObject.tag||':'+layoutObject.name;}},{title:'htmlId',value(layoutObject){return layoutObject.htmlId||'';}},{title:'classNames',value(layoutObject){return layoutObject.classNames||'';}},{title:'reasons',value(layoutObject){return layoutObject.needsLayoutReasons.join(', ');}},{title:'width',value(layoutObject){return layoutObject.absoluteRect.width;}},{title:'height',value(layoutObject){return layoutObject.absoluteRect.height;}},{title:'absX',value(layoutObject){return layoutObject.absoluteRect.left;}},{title:'absY',value(layoutObject){return layoutObject.absoluteRect.top;}},{title:'relX',value(layoutObject){return layoutObject.relativeRect.left;}},{title:'relY',value(layoutObject){return layoutObject.relativeRect.top;}},{title:'float',value(layoutObject){return layoutObject.isFloat?'float':'';}},{title:'positioned',value(layoutObject){return layoutObject.isPositioned?'positioned':'';}},{title:'relative',value(layoutObject){return layoutObject.isRelativePositioned?'relative':'';}},{title:'sticky',value(layoutObject){return layoutObject.isStickyPositioned?'sticky':'';}},{title:'anonymous',value(layoutObject){return layoutObject.isAnonymous?'anonymous':'';}},{title:'row',value(layoutObject){if(layoutObject.tableRow===undefined){return'';}
+return layoutObject.tableRow;}},{title:'col',value(layoutObject){if(layoutObject.tableCol===undefined){return'';}
+return layoutObject.tableCol;}},{title:'rowSpan',value(layoutObject){if(layoutObject.tableRowSpan===undefined){return'';}
+return layoutObject.tableRowSpan;}},{title:'colSpan',value(layoutObject){if(layoutObject.tableColSpan===undefined){return'';}
+return layoutObject.tableColSpan;}},{title:'address',value(layoutObject){return layoutObject.id.toString(16);}}];const table=this.ownerDocument.createElement('tr-ui-b-table');table.defaultExpansionStateCallback=function(layoutObject,parentLayoutObject){return true;};table.subRowsPropertyName='childLayoutObjects';table.tableColumns=columns;table.tableRows=this.currentSelection_.map(function(snapshot){return snapshot.rootLayoutObject;});table.rebuild();Polymer.dom(this.$.content).appendChild(table);},});return{};});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:false,title:'Layout Tree',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-layout-tree-sub-view',tr.e.chrome.LayoutTreeSnapshot,{multi:true,title:'Layout Trees',});'use strict';tr.exportTo('tr.ui.behaviors',function(){const SidePanel={get rangeOfInterest(){throw new Error('Not implemented');},set rangeOfInterest(rangeOfInterest){throw new Error('Not implemented');},get selection(){throw new Error('Not implemented');},set selection(selection){throw new Error('Not implemented');},get model(){throw new Error('Not implemented');},set model(model){throw new Error('Not implemented');},supportsModel(m){throw new Error('Not implemented');}};return{SidePanel,};});'use strict';tr.exportTo('tr.ui.side_panel',function(){function SidePanelRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(SidePanelRegistry,options);return{SidePanelRegistry,};});'use strict';tr.exportTo('tr.ui.e.s',function(){const BlameContextSnapshot=tr.e.chrome.BlameContextSnapshot;const FrameTreeNodeSnapshot=tr.e.chrome.FrameTreeNodeSnapshot;const RenderFrameSnapshot=tr.e.chrome.RenderFrameSnapshot;const TopLevelSnapshot=tr.e.chrome.TopLevelSnapshot;const BlameContextInstance=tr.e.chrome.BlameContextInstance;const FrameTreeNodeInstance=tr.e.chrome.FrameTreeNodeInstance;const RenderFrameInstance=tr.e.chrome.RenderFrameInstance;const TopLevelInstance=tr.e.chrome.TopLevelInstance;function Row(context){this.subRows=undefined;this.contexts=[];this.type=undefined;this.renderer='N/A';this.url=undefined;this.time=0;this.eventsOfInterest=new tr.model.EventSet();if(context===undefined)return;this.type=context.objectInstance.blameContextType;this.contexts.push(context);if(context instanceof FrameTreeNodeSnapshot){if(context.renderFrame){this.contexts.push(context.renderFrame);this.renderer=context.renderFrame.objectInstance.parent.pid;}}else if(context instanceof RenderFrameSnapshot){if(context.frameTreeNode){this.contexts.push(context.frameTreeNode);}
 this.renderer=context.objectInstance.parent.pid;}else if(context instanceof TopLevelSnapshot){this.renderer=context.objectInstance.parent.pid;}else{throw new Error('Unknown context type');}
 this.eventsOfInterest.addEventSet(this.contexts);this.url=context.url;}
-var groupFunctions={none:rows=>rows,tree:function(rows,rowMap){var getParentRow=function(row){var pivot;row.contexts.forEach(function(context){if(context instanceof tr.e.chrome.FrameTreeNodeSnapshot){pivot=context;}});if(pivot&&pivot.parentContext){return rowMap[pivot.parentContext.guid];}
-return undefined;};var rootRows=[];rows.forEach(function(row){var parentRow=getParentRow(row);if(parentRow===undefined){rootRows.push(row);return;}
+const groupFunctions={none:rows=>rows,tree(rows,rowMap){const getParentRow=function(row){let pivot;row.contexts.forEach(function(context){if(context instanceof tr.e.chrome.FrameTreeNodeSnapshot){pivot=context;}});if(pivot&&pivot.parentContext){return rowMap[pivot.parentContext.guid];}
+return undefined;};const rootRows=[];rows.forEach(function(row){const parentRow=getParentRow(row);if(parentRow===undefined){rootRows.push(row);return;}
 if(parentRow.subRows===undefined){parentRow.subRows=[];}
-parentRow.subRows.push(row);});var aggregateAllDescendants=function(row){if(!row.subRows){if(getParentRow(row)){row.type='Subframe';}
+parentRow.subRows.push(row);});const aggregateAllDescendants=function(row){if(!row.subRows){if(getParentRow(row)){row.type='Subframe';}
 return row;}
-var result=new Row();result.type='Frame Tree';result.renderer=row.renderer;result.url=row.url;result.subRows=[row];row.subRows.forEach(subRow=>result.subRows.push(aggregateAllDescendants(subRow)));result.subRows.forEach(function(subRow){result.time+=subRow.time;result.eventsOfInterest.addEventSet(subRow.eventsOfInterest);});row.subRows=undefined;return result;};return rootRows.map(rootRow=>aggregateAllDescendants(rootRow));}};Polymer({is:'tr-ui-e-s-frame-data-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready:function(){this.model_=undefined;this.rangeOfInterest_=new tr.b.math.Range();this.$.table.showHeader=true;this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=this.createFrameDataTableColumns_();this.$.table.addEventListener('selection-changed',function(e){this.selectEventSet_(this.$.table.selectedTableRow.eventsOfInterest);}.bind(this));this.$.select.addEventListener('change',function(e){this.updateContents_();}.bind(this));},selectEventSet_:function(eventSet){var event=new tr.model.RequestSelectionChangeEvent();event.selection=eventSet;this.dispatchEvent(event);},createFrameDataTableColumns_:function(){return[{title:'Renderer',value:row=>row.renderer,cmp:(a,b)=>a.renderer-b.renderer},{title:'Type',value:row=>row.type},{title:'Time',value:row=>tr.v.ui.createScalarSpan(row.time,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}),cmp:(a,b)=>a.time-b.time},{title:'URL',value:row=>row.url,cmp:(a,b)=>(a.url||'').localeCompare(b.url||'')}];},createFrameDataTableRows_:function(){if(!this.model_)return[];var rows=[];var rowMap={};for(var proc of Object.values(this.model_.processes)){proc.objects.iterObjectInstances(function(objectInstance){if(!(objectInstance instanceof BlameContextInstance)){return;}
-objectInstance.snapshots.forEach(function(snapshot){if(rowMap[snapshot.guid])return;var row=new Row(snapshot);row.contexts.forEach(context=>rowMap[context.guid]=row);rows.push(row);},this);},this);}
-for(var proc of Object.values(this.model_.processes)){for(var thread of Object.values(proc.threads)){thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice){topLevelSlice.contexts.forEach(function(context){if(!context.snapshot.guid||!rowMap[context.snapshot.guid]){return;}
-var row=rowMap[context.snapshot.guid];row.eventsOfInterest.push(topLevelSlice);row.time+=topLevelSlice.selfTime||0;});},this.currentRangeOfInterest.min,this.currentRangeOfInterest.max);}}
-var select=this.$.select;var groupOption=select.options[select.selectedIndex].value;var groupFunction=groupFunctions[groupOption];return groupFunction(rows,rowMap);},updateContents_:function(){this.$.table.tableRows=this.createFrameDataTableRows_();this.$.table.rebuild();},supportsModel:function(m){if(!m){return{supported:false,reason:'No model available.'};}
-var ans={supported:false};for(var proc of Object.values(m.processes)){proc.objects.iterObjectInstances(function(instance){if(instance instanceof BlameContextInstance){ans.supported=true;}});}
+const result=new Row();result.type='Frame Tree';result.renderer=row.renderer;result.url=row.url;result.subRows=[row];row.subRows.forEach(subRow=>result.subRows.push(aggregateAllDescendants(subRow)));result.subRows.forEach(function(subRow){result.time+=subRow.time;result.eventsOfInterest.addEventSet(subRow.eventsOfInterest);});row.subRows=undefined;return result;};return rootRows.map(rootRow=>aggregateAllDescendants(rootRow));}};Polymer({is:'tr-ui-e-s-frame-data-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.rangeOfInterest_=new tr.b.math.Range();this.$.table.showHeader=true;this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=this.createFrameDataTableColumns_();this.$.table.addEventListener('selection-changed',function(e){this.selectEventSet_(this.$.table.selectedTableRow.eventsOfInterest);}.bind(this));this.$.select.addEventListener('change',function(e){this.updateContents_();}.bind(this));},selectEventSet_(eventSet){const event=new tr.model.RequestSelectionChangeEvent();event.selection=eventSet;this.dispatchEvent(event);},createFrameDataTableColumns_(){return[{title:'Renderer',value:row=>row.renderer,cmp:(a,b)=>a.renderer-b.renderer},{title:'Type',value:row=>row.type},{title:'Time',value:row=>tr.v.ui.createScalarSpan(row.time,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}),cmp:(a,b)=>a.time-b.time},{title:'URL',value:row=>row.url,cmp:(a,b)=>(a.url||'').localeCompare(b.url||'')}];},createFrameDataTableRows_(){if(!this.model_)return[];const rows=[];const rowMap={};for(const proc of Object.values(this.model_.processes)){proc.objects.iterObjectInstances(function(objectInstance){if(!(objectInstance instanceof BlameContextInstance)){return;}
+objectInstance.snapshots.forEach(function(snapshot){if(rowMap[snapshot.guid])return;const row=new Row(snapshot);row.contexts.forEach(context=>rowMap[context.guid]=row);rows.push(row);},this);},this);}
+for(const proc of Object.values(this.model_.processes)){for(const thread of Object.values(proc.threads)){thread.sliceGroup.iterSlicesInTimeRange(function(topLevelSlice){topLevelSlice.contexts.forEach(function(context){if(!context.snapshot.guid||!rowMap[context.snapshot.guid]){return;}
+const row=rowMap[context.snapshot.guid];row.eventsOfInterest.push(topLevelSlice);row.time+=topLevelSlice.selfTime||0;});},this.currentRangeOfInterest.min,this.currentRangeOfInterest.max);}}
+const select=this.$.select;const groupOption=select.options[select.selectedIndex].value;const groupFunction=groupFunctions[groupOption];return groupFunction(rows,rowMap);},updateContents_(){this.$.table.tableRows=this.createFrameDataTableRows_();this.$.table.rebuild();},supportsModel(m){if(!m){return{supported:false,reason:'No model available.'};}
+const ans={supported:false};for(const proc of Object.values(m.processes)){proc.objects.iterObjectInstances(function(instance){if(instance instanceof BlameContextInstance){ans.supported=true;}});}
 if(!ans.supported){ans.reason='No frame data available';}
 return ans;},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
-return this.rangeOfInterest_;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},get selection(){},set selection(_){},get textLabel(){return'Frame Data';},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-frame-data-side-panel');});});'use strict';Polymer({is:'tr-ui-b-chart-legend-key',ready:function(){this.$.checkbox.addEventListener('change',this.onCheckboxChange_.bind(this));},onCheckboxChange_:function(){tr.b.dispatchSimpleEvent(this,tr.ui.b.DataSeriesEnableChangeEventType,true,false,{key:Polymer.dom(this).textContent,enabled:this.enabled});},set textContent(t){Polymer.dom(this.$.label).textContent=t;Polymer.dom(this.$.link).textContent=t;this.updateContents_();},set width(w){w-=20;this.$.link.style.width=w+'px';this.$.label.style.width=w+'px';},get textContent(){return Polymer.dom(this.$.label).textContent;},set optional(optional){this.$.checkbox.style.visibility=optional?'visible':'hidden';},get optional(){return this.$.checkbox.style.visibility==='visible';},set enabled(enabled){this.$.checkbox.checked=enabled?'checked':'';},get enabled(){return this.$.checkbox.checked;},set color(c){this.$.label.style.color=c;this.$.link.color=c;},set target(target){this.$.link.setSelectionAndContent(target,Polymer.dom(this.$.label).textContent);this.updateContents_();},get target(){return this.$.link.selection;},set title(title){this.$.link.title=title;},updateContents_:function(){this.$.link.style.display=this.target?'':'none';this.$.label.style.display=this.target?'none':'';this.$.label.htmlFor=this.optional?'checkbox':'';}});'use strict';(function(window){window.define=function(x){window.d3=x;};window.define.amd=true;})(this);!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';(function(window){window.define=undefined;}).call(this,this);'use strict';tr.exportTo('tr.ui.b',function(){var DataSeriesEnableChangeEventType='data-series-enabled-change';var THIS_DOC=document.currentScript.ownerDocument;var svgNS='http://www.w3.org/2000/svg';var ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){var id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected){id+=ColorScheme.properties.brightenedOffsets[0];}
+return this.rangeOfInterest_;},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},get selection(){},set selection(_){},get textLabel(){return'Frame Data';},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-frame-data-side-panel');});});'use strict';Polymer({is:'tr-ui-b-chart-legend-key',ready(){this.$.checkbox.addEventListener('change',this.onCheckboxChange_.bind(this));},onCheckboxChange_(){tr.b.dispatchSimpleEvent(this,tr.ui.b.DataSeriesEnableChangeEventType,true,false,{key:Polymer.dom(this).textContent,enabled:this.enabled});},set textContent(t){Polymer.dom(this.$.label).textContent=t;Polymer.dom(this.$.link).textContent=t;this.updateContents_();},set width(w){w-=20;this.$.link.style.width=w+'px';this.$.label.style.width=w+'px';},get textContent(){return Polymer.dom(this.$.label).textContent;},set optional(optional){this.$.checkbox.style.visibility=optional?'visible':'hidden';},get optional(){return this.$.checkbox.style.visibility==='visible';},set enabled(enabled){this.$.checkbox.checked=enabled?'checked':'';},get enabled(){return this.$.checkbox.checked;},set color(c){this.$.label.style.color=c;this.$.link.color=c;},set target(target){this.$.link.setSelectionAndContent(target,Polymer.dom(this.$.label).textContent);this.updateContents_();},get target(){return this.$.link.selection;},set title(title){this.$.link.title=title;},updateContents_(){this.$.link.style.display=this.target?'':'none';this.$.label.style.display=this.target?'none':'';this.$.label.htmlFor=this.optional?'checkbox':'';}});'use strict';(function(window){window.define=function(x){window.d3=x;};window.define.amd=true;})(this);!function(){function n(n){return null!=n&&!isNaN(n)}function t(n){return n.length}function e(n){for(var t=1;n*t%1;)t*=10;return t}function r(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function u(){}function i(n){return aa+n in this}function o(n){return n=aa+n,n in this&&delete this[n]}function a(){var n=[];return this.forEach(function(t){n.push(t)}),n}function c(){var n=0;for(var t in this)t.charCodeAt(0)===ca&&++n;return n}function s(){for(var n in this)if(n.charCodeAt(0)===ca)return!1;return!0}function l(){}function f(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function h(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=sa.length;r>e;++e){var u=sa[e]+t;if(u in n)return u}}function g(){}function p(){}function v(n){function t(){for(var t,r=e,u=-1,i=r.length;++u<i;)(t=r[u].on)&&t.apply(this,arguments);return n}var e=[],r=new u;return t.on=function(t,u){var i,o=r.get(t);return arguments.length<2?o&&o.on:(o&&(o.on=null,e=e.slice(0,i=e.indexOf(o)).concat(e.slice(i+1)),r.remove(t)),u&&e.push(r.set(t,{on:u})),n)},t}function d(){Xo.event.preventDefault()}function m(){for(var n,t=Xo.event;n=t.sourceEvent;)t=n;return t}function y(n){for(var t=new p,e=0,r=arguments.length;++e<r;)t[arguments[e]]=v(t);return t.of=function(e,r){return function(u){try{var i=u.sourceEvent=Xo.event;u.target=n,Xo.event=u,t[u.type].apply(e,r)}finally{Xo.event=i}}},t}function x(n){return fa(n,da),n}function M(n){return"function"==typeof n?n:function(){return ha(n,this)}}function _(n){return"function"==typeof n?n:function(){return ga(n,this)}}function b(n,t){function e(){this.removeAttribute(n)}function r(){this.removeAttributeNS(n.space,n.local)}function u(){this.setAttribute(n,t)}function i(){this.setAttributeNS(n.space,n.local,t)}function o(){var e=t.apply(this,arguments);null==e?this.removeAttribute(n):this.setAttribute(n,e)}function a(){var e=t.apply(this,arguments);null==e?this.removeAttributeNS(n.space,n.local):this.setAttributeNS(n.space,n.local,e)}return n=Xo.ns.qualify(n),null==t?n.local?r:e:"function"==typeof t?n.local?a:o:n.local?i:u}function w(n){return n.trim().replace(/\s+/g," ")}function S(n){return new RegExp("(?:^|\\s+)"+Xo.requote(n)+"(?:\\s+|$)","g")}function k(n){return n.trim().split(/^|\s+/)}function E(n,t){function e(){for(var e=-1;++e<u;)n[e](this,t)}function r(){for(var e=-1,r=t.apply(this,arguments);++e<u;)n[e](this,r)}n=k(n).map(A);var u=n.length;return"function"==typeof t?r:e}function A(n){var t=S(n);return function(e,r){if(u=e.classList)return r?u.add(n):u.remove(n);var u=e.getAttribute("class")||"";r?(t.lastIndex=0,t.test(u)||e.setAttribute("class",w(u+" "+n))):e.setAttribute("class",w(u.replace(t," ")))}}function C(n,t,e){function r(){this.style.removeProperty(n)}function u(){this.style.setProperty(n,t,e)}function i(){var r=t.apply(this,arguments);null==r?this.style.removeProperty(n):this.style.setProperty(n,r,e)}return null==t?r:"function"==typeof t?i:u}function N(n,t){function e(){delete this[n]}function r(){this[n]=t}function u(){var e=t.apply(this,arguments);null==e?delete this[n]:this[n]=e}return null==t?e:"function"==typeof t?u:r}function L(n){return"function"==typeof n?n:(n=Xo.ns.qualify(n)).local?function(){return this.ownerDocument.createElementNS(n.space,n.local)}:function(){return this.ownerDocument.createElementNS(this.namespaceURI,n)}}function T(n){return{__data__:n}}function q(n){return function(){return va(this,n)}}function z(n){return arguments.length||(n=Xo.ascending),function(t,e){return t&&e?n(t.__data__,e.__data__):!t-!e}}function R(n,t){for(var e=0,r=n.length;r>e;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function D(n){return fa(n,ya),n}function P(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t<c;);return o}}function U(){var n=this.__transition__;n&&++n.active}function j(n,t,e){function r(){var t=this[o];t&&(this.removeEventListener(n,t,t.$),delete this[o])}function u(){var u=c(t,Bo(arguments));r.call(this),this.addEventListener(n,this[o]=u,u.$=e),u._=t}function i(){var t,e=new RegExp("^__on([^.]+)"+Xo.requote(n)+"$");for(var r in this)if(t=r.match(e)){var u=this[r];this.removeEventListener(t[1],u,u.$),delete this[r]}}var o="__on"+n,a=n.indexOf("."),c=H;a>0&&(n=n.substring(0,a));var s=Ma.get(n);return s&&(n=s,c=F),a?t?u:r:t?g:i}function H(n,t){return function(e){var r=Xo.event;Xo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Xo.event=r}}}function F(n,t){var e=H(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function O(){var n=".dragsuppress-"+ ++ba,t="click"+n,e=Xo.select(Go).on("touchmove"+n,d).on("dragstart"+n,d).on("selectstart"+n,d);if(_a){var r=Jo.style,u=r[_a];r[_a]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),_a&&(r[_a]=u),i&&(e.on(t,function(){d(),o()},!0),setTimeout(o,0))}}function Y(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>wa&&(Go.scrollX||Go.scrollY)){e=Xo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();wa=!(u.f||u.e),e.remove()}return wa?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function I(n){return n>0?1:0>n?-1:0}function Z(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function V(n){return n>1?0:-1>n?Sa:Math.acos(n)}function X(n){return n>1?Ea:-1>n?-Ea:Math.asin(n)}function $(n){return((n=Math.exp(n))-1/n)/2}function B(n){return((n=Math.exp(n))+1/n)/2}function W(n){return((n=Math.exp(2*n))-1)/(n+1)}function J(n){return(n=Math.sin(n/2))*n}function G(){}function K(n,t,e){return new Q(n,t,e)}function Q(n,t,e){this.h=n,this.s=t,this.l=e}function nt(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,gt(u(n+120),u(n),u(n-120))}function tt(n,t,e){return new et(n,t,e)}function et(n,t,e){this.h=n,this.c=t,this.l=e}function rt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),ut(e,Math.cos(n*=Na)*t,Math.sin(n)*t)}function ut(n,t,e){return new it(n,t,e)}function it(n,t,e){this.l=n,this.a=t,this.b=e}function ot(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=ct(u)*Fa,r=ct(r)*Oa,i=ct(i)*Ya,gt(lt(3.2404542*u-1.5371385*r-.4985314*i),lt(-.969266*u+1.8760108*r+.041556*i),lt(.0556434*u-.2040259*r+1.0572252*i))}function at(n,t,e){return n>0?tt(Math.atan2(e,t)*La,Math.sqrt(t*t+e*e),n):tt(0/0,0/0,n)}function ct(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function st(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function lt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function ft(n){return gt(n>>16,255&n>>8,255&n)}function ht(n){return ft(n)+""}function gt(n,t,e){return new pt(n,t,e)}function pt(n,t,e){this.r=n,this.g=t,this.b=e}function vt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function dt(n,t,e){var r,u,i,o,a=0,c=0,s=0;if(u=/([a-z]+)\((.*)\)/i.exec(n))switch(i=u[2].split(","),u[1]){case"hsl":return e(parseFloat(i[0]),parseFloat(i[1])/100,parseFloat(i[2])/100);case"rgb":return t(Mt(i[0]),Mt(i[1]),Mt(i[2]))}return(o=Va.get(n))?t(o.r,o.g,o.b):(null!=n&&"#"===n.charAt(0)&&(r=parseInt(n.substring(1),16),isNaN(r)||(4===n.length?(a=(3840&r)>>4,a=a>>4|a,c=240&r,c=c>>4|c,s=15&r,s=s<<4|s):7===n.length&&(a=(16711680&r)>>16,c=(65280&r)>>8,s=255&r))),t(a,c,s))}function mt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),K(r,u,c)}function yt(n,t,e){n=xt(n),t=xt(t),e=xt(e);var r=st((.4124564*n+.3575761*t+.1804375*e)/Fa),u=st((.2126729*n+.7151522*t+.072175*e)/Oa),i=st((.0193339*n+.119192*t+.9503041*e)/Ya);return ut(116*u-16,500*(r-u),200*(u-i))}function xt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function Mt(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function _t(n){return"function"==typeof n?n:function(){return n}}function bt(n){return n}function wt(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),St(t,e,n,r)}}function St(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Xo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Go.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Xo.event;Xo.event=n;try{o.progress.call(i,c)}finally{Xo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Bo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Xo.rebind(i,o,"on"),null==r?i:i.get(kt(r))}function kt(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function Et(){var n=At(),t=Ct()-n;t>24?(isFinite(t)&&(clearTimeout(Wa),Wa=setTimeout(Et,t)),Ba=0):(Ba=1,Ga(Et))}function At(){var n=Date.now();for(Ja=Xa;Ja;)n>=Ja.t&&(Ja.f=Ja.c(n-Ja.t)),Ja=Ja.n;return n}function Ct(){for(var n,t=Xa,e=1/0;t;)t.f?t=n?n.n=t.n:Xa=t.n:(t.t<e&&(e=t.t),t=(n=t).n);return $a=n,e}function Nt(n,t){return t-(n?Math.ceil(Math.log(n)/Math.LN10):1)}function Lt(n,t){var e=Math.pow(10,3*oa(8-t));return{scale:t>8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:bt;return function(n){var e=Qa.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=nc.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Xo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function zt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Rt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new ec(e-1)),1),e}function i(n,e){return t(n=new ec(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{ec=zt;var r=new zt;return r._=n,o(r,t,e)}finally{ec=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Dt(n);return c.floor=c,c.round=Dt(r),c.ceil=Dt(u),c.offset=Dt(i),c.range=a,n}function Dt(n){return function(t,e){try{ec=zt;var r=new zt;return r._=t,n(r,e)._}finally{ec=Date}}}function Pt(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++a<r;)37===n.charCodeAt(a)&&(o.push(n.substring(c,a)),null!=(u=uc[e=n.charAt(++a)])&&(e=n.charAt(++a)),(i=C[e])&&(e=i(t,null==u?"e"===e?" ":"0":u)),o.push(e),c=a+1);return o.push(n.substring(c,a)),o.join("")}var r=n.length;return t.parse=function(t){var r={y:1900,m:0,d:1,H:0,M:0,S:0,L:0,Z:null},u=e(r,n,t,0);if(u!=t.length)return null;"p"in r&&(r.H=r.H%12+12*r.p);var i=null!=r.Z&&ec!==zt,o=new(i?zt:ec);return"j"in r?o.setFullYear(r.y,0,r.j):"w"in r&&("W"in r||"U"in r)?(o.setFullYear(r.y,0,1),o.setFullYear(r.y,0,"W"in r?(r.w+6)%7+7*r.W-(o.getDay()+5)%7:r.w+7*r.U-(o.getDay()+6)%7)):o.setFullYear(r.y,r.m,r.d),o.setHours(r.H+Math.floor(r.Z/100),r.M+r.Z%100,r.S,r.L),i?o._:o},t.toString=function(){return n},t}function e(n,t,e,r){for(var u,i,o,a=0,c=t.length,s=e.length;c>a;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in uc?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{ec=zt;var t=new ec;return t._=n,r(t)}finally{ec=Date}}var r=t(n);return e.parse=function(n){try{ec=zt;var t=r.parse(n);return t&&t._}finally{ec=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ee;var x=Xo.map(),M=jt(v),_=Ht(v),b=jt(d),w=Ht(d),S=jt(m),k=Ht(m),E=jt(y),A=Ht(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return Ut(n.getDate(),t,2)},e:function(n,t){return Ut(n.getDate(),t,2)},H:function(n,t){return Ut(n.getHours(),t,2)},I:function(n,t){return Ut(n.getHours()%12||12,t,2)},j:function(n,t){return Ut(1+tc.dayOfYear(n),t,3)},L:function(n,t){return Ut(n.getMilliseconds(),t,3)},m:function(n,t){return Ut(n.getMonth()+1,t,2)},M:function(n,t){return Ut(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Ut(n.getSeconds(),t,2)},U:function(n,t){return Ut(tc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Ut(tc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Ut(n.getFullYear()%100,t,2)},Y:function(n,t){return Ut(n.getFullYear()%1e4,t,4)},Z:ne,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Bt,e:Bt,H:Jt,I:Jt,j:Wt,L:Qt,m:$t,M:Gt,p:l,S:Kt,U:Ot,w:Ft,W:Yt,x:c,X:s,y:Zt,Y:It,Z:Vt,"%":te};return t}function Ut(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function jt(n){return new RegExp("^(?:"+n.map(Xo.requote).join("|")+")","i")}function Ht(n){for(var t=new u,e=-1,r=n.length;++e<r;)t.set(n[e].toLowerCase(),e);return t}function Ft(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+1));return r?(n.w=+r[0],e+r[0].length):-1}function Ot(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.U=+r[0],e+r[0].length):-1}function Yt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e));return r?(n.W=+r[0],e+r[0].length):-1}function It(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+4));return r?(n.y=+r[0],e+r[0].length):-1}function Zt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.y=Xt(+r[0]),e+r[0].length):-1}function Vt(n,t,e){return/^[+-]\d{4}$/.test(t=t.substring(e,e+5))?(n.Z=+t,e+5):-1}function Xt(n){return n+(n>68?1900:2e3)}function $t(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Bt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Wt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Jt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Gt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Kt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function Qt(n,t,e){ic.lastIndex=0;var r=ic.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ne(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(oa(t)/60),u=oa(t)%60;return e+Ut(r,"0",2)+Ut(u,"0",2)}function te(n,t,e){oc.lastIndex=0;var r=oc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function ee(n){for(var t=n.length,e=-1;++e<t;)n[e][0]=this(n[e][0]);return function(t){for(var e=0,r=n[e];!r[1](t);)r=n[++e];return r[0](t)}}function re(){}function ue(n,t,e){var r=e.s=n+t,u=r-n,i=r-u;e.t=n-i+(t-u)}function ie(n,t){n&&lc.hasOwnProperty(n.type)&&lc[n.type](n,t)}function oe(n,t,e){var r,u=-1,i=n.length-e;for(t.lineStart();++u<i;)r=n[u],t.point(r[0],r[1],r[2]);t.lineEnd()}function ae(n,t){var e=-1,r=n.length;for(t.polygonStart();++e<r;)oe(n[e],t,1);t.polygonEnd()}function ce(){function n(n,t){n*=Na,t=t*Na/2+Sa/4;var e=n-r,o=e>=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);hc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;gc.point=function(o,a){gc.point=n,r=(t=o)*Na,u=Math.cos(a=(e=a)*Na/2+Sa/4),i=Math.sin(a)},gc.lineEnd=function(){n(t,e)}}function se(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function le(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function fe(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function he(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ge(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function pe(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function ve(n){return[Math.atan2(n[1],n[0]),X(n[2])]}function de(n,t){return oa(n[0]-t[0])<Aa&&oa(n[1]-t[1])<Aa}function me(n,t){n*=Na;var e=Math.cos(t*=Na);ye(e*Math.cos(n),e*Math.sin(n),Math.sin(t))}function ye(n,t,e){++pc,dc+=(n-dc)/pc,mc+=(t-mc)/pc,yc+=(e-yc)/pc}function xe(){function n(n,u){n*=Na;var i=Math.cos(u*=Na),o=i*Math.cos(n),a=i*Math.sin(n),c=Math.sin(u),s=Math.atan2(Math.sqrt((s=e*c-r*a)*s+(s=r*o-t*c)*s+(s=t*a-e*o)*s),t*o+e*a+r*c);vc+=s,xc+=s*(t+(t=o)),Mc+=s*(e+(e=a)),_c+=s*(r+(r=c)),ye(t,e,r)}var t,e,r;kc.point=function(u,i){u*=Na;var o=Math.cos(i*=Na);t=o*Math.cos(u),e=o*Math.sin(u),r=Math.sin(i),kc.point=n,ye(t,e,r)}}function Me(){kc.point=me}function _e(){function n(n,t){n*=Na;var e=Math.cos(t*=Na),o=e*Math.cos(n),a=e*Math.sin(n),c=Math.sin(t),s=u*c-i*a,l=i*o-r*c,f=r*a-u*o,h=Math.sqrt(s*s+l*l+f*f),g=r*o+u*a+i*c,p=h&&-V(g)/h,v=Math.atan2(h,g);bc+=p*s,wc+=p*l,Sc+=p*f,vc+=v,xc+=v*(r+(r=o)),Mc+=v*(u+(u=a)),_c+=v*(i+(i=c)),ye(r,u,i)}var t,e,r,u,i;kc.point=function(o,a){t=o,e=a,kc.point=n,o*=Na;var c=Math.cos(a*=Na);r=c*Math.cos(o),u=c*Math.sin(o),i=Math.sin(a),ye(r,u,i)},kc.lineEnd=function(){n(t,e),kc.lineEnd=Me,kc.point=me}}function be(){return!0}function we(n,t,e,r,u){var i=[],o=[];if(n.forEach(function(n){if(!((t=n.length-1)<=0)){var t,e=n[0],r=n[t];if(de(e,r)){u.lineStart();for(var a=0;t>a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new ke(e,n,null,!0),s=new ke(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new ke(r,n,null,!1),s=new ke(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),Se(i),Se(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function Se(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r<t;)u.n=e=n[r],e.p=u,u=e;u.n=e=n[0],e.p=u}}function ke(n,t,e,r){this.x=n,this.z=t,this.o=e,this.e=r,this.v=!1,this.n=this.p=null}function Ee(n,t,e,r){return function(u,i){function o(t,e){var r=u(t,e);n(t=r[0],e=r[1])&&i.point(t,e)}function a(n,t){var e=u(n,t);d.point(e[0],e[1])}function c(){y.point=a,d.lineStart()}function s(){y.point=o,d.lineEnd()}function l(n,t){v.push([n,t]);var e=u(n,t);M.point(e[0],e[1])}function f(){M.lineStart(),v=[]}function h(){l(v[0][0],v[0][1]),M.lineEnd();var n,t=M.clean(),e=x.buffer(),r=e.length;if(v.pop(),p.push(v),v=null,r){if(1&t){n=e[0];var u,r=n.length-1,o=-1;for(i.lineStart();++o<r;)i.point((u=n[o])[0],u[1]);return i.lineEnd(),void 0}r>1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ae))}}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[],i.polygonStart()},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Xo.merge(g);var n=Le(m,p);g.length?we(g,Ne,n,e,i):n&&(i.lineStart(),e(null,null,1,i),i.lineEnd()),i.polygonEnd(),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ce(),M=t(x);return y}}function Ae(n){return n.length>1}function Ce(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:g,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function Ne(n,t){return((n=n.x)[0]<0?n[1]-Ea-Aa:Ea-n[1])-((t=t.x)[0]<0?t[1]-Ea-Aa:Ea-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;hc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+Sa/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+Sa/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>Sa,k=p*x;if(hc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*ka:_,S^h>=e^m>=e){var E=fe(se(f),se(n));pe(E);var A=fe(u,E);pe(A);var C=(S^_>=0?-1:1)*X(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-Aa>i||Aa>i&&0>hc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?Sa:-Sa,c=oa(i-e);oa(c-Sa)<Aa?(n.point(e,r=(r+o)/2>0?Ea:-Ea),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Sa&&(oa(e-u)<Aa&&(e-=u*Aa),oa(i-a)<Aa&&(i-=a*Aa),r=qe(e,r,i,o),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),t=0),n.point(e=i,r=o),u=a},lineEnd:function(){n.lineEnd(),e=r=0/0},clean:function(){return 2-t}}}function qe(n,t,e,r){var u,i,o=Math.sin(n-e);return oa(o)>Aa?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function ze(n,t,e,r){var u;if(null==n)u=e*Ea,r.point(-Sa,u),r.point(0,u),r.point(Sa,u),r.point(Sa,0),r.point(Sa,-u),r.point(0,-u),r.point(-Sa,-u),r.point(-Sa,0),r.point(-Sa,u);else if(oa(n[0]-t[0])>Aa){var i=n[0]<t[0]?Sa:-Sa;u=e*i/2,r.point(-i,u),r.point(0,u),r.point(i,u)}else r.point(t[0],t[1])}function Re(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?Sa:-Sa),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(de(e,g)||de(p,g))&&(p[0]+=Aa,p[1]+=Aa,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&de(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=se(n),u=se(t),o=[1,0,0],a=fe(r,u),c=le(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=fe(o,a),p=ge(o,f),v=ge(a,h);he(p,v);var d=g,m=le(p,d),y=le(d,d),x=m*m-y*(le(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=ge(d,(-m-M)/y);if(he(_,p),_=ve(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=oa(A-Sa)<Aa,N=C||Aa>A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(oa(_[0]-w)<Aa?k:E):k<=_[1]&&_[1]<=E:A>Sa^(w<=_[0]&&_[0]<=S)){var L=ge(d,(-m+M)/y);return he(L,p),[_,ve(L)]}}}function u(t,e){var r=o?n:Sa-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=oa(i)>Aa,c=cr(n,6*Na);return Ee(t,e,c,o?[0,-n]:[-Sa,n-Sa])}function De(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Pe(n,t,e,r){function u(r,u){return oa(r[0]-n)<Aa?u>0?0:3:oa(r[0]-e)<Aa?u>0?2:1:oa(r[1]-t)<Aa?u>0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&Z(s,i,n)>0&&++t:i[1]<=r&&Z(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Ac,Math.min(Ac,n)),t=Math.max(-Ac,Math.min(Ac,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ce(),C=De(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Xo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&we(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function Ue(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function je(n){var t=0,e=Sa/3,r=nr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Sa/180,e=n[1]*Sa/180):[180*(t/Sa),180*(e/Sa)]},u}function He(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,X((i-(n*n+e*e)*u*u)/(2*u))]},e}function Fe(){function n(n,t){Nc+=u*n-r*t,r=n,u=t}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,t=r=i,e=u=o},Rc.lineEnd=function(){n(t,e)}}function Oe(n,t){Lc>n&&(Lc=n),n>qc&&(qc=n),Tc>t&&(Tc=t),t>zc&&(zc=t)}function Ye(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ie(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ie(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ie(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ze(n,t){dc+=n,mc+=t,++yc}function Ve(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);xc+=o*(t+n)/2,Mc+=o*(e+r)/2,_c+=o,Ze(t=n,e=r)}var t,e;Pc.point=function(r,u){Pc.point=n,Ze(t=r,e=u)}}function Xe(){Pc.point=Ze}function $e(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);xc+=o*(r+n)/2,Mc+=o*(u+t)/2,_c+=o,o=u*n-r*t,bc+=o*(r+n),wc+=o*(u+t),Sc+=3*o,Ze(r=n,u=t)}var t,e,r,u;Pc.point=function(i,o){Pc.point=n,Ze(t=r=i,e=u=o)},Pc.lineEnd=function(){n(t,e)}}function Be(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,ka)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:g};return a}function We(n){function t(n){return(a?r:e)(n)}function e(t){return Ke(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=se([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=oa(oa(w)-1)<Aa||oa(r-h)<Aa?(r+h)/2:Math.atan2(b,_),A=n(E,k),C=A[0],N=A[1],L=C-t,T=N-e,q=x*L-y*T;(q*q/M>i||oa((y*L+x*T)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Na),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Je(n){var t=We(function(t,e){return n([t*La,e*La])});return function(n){return tr(t(n))}}function Ge(n){this.stream=n}function Ke(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function Qe(n){return nr(function(){return n})()}function nr(n){function t(n){return n=a(n[0]*Na,n[1]*Na),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*La,n[1]*La]}function r(){a=Ue(o=ur(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=We(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Ec,_=bt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=tr(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Ec):Re((b=+n)*Na),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Pe(n[0][0],n[0][1],n[1][0],n[1][1]):bt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Na,d=n[1]%360*Na,r()):[v*La,d*La]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Na,y=n[1]%360*Na,x=n.length>2?n[2]%360*Na:0,r()):[m*La,y*La,x*La]},Xo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function tr(n){return Ke(n,function(t,e){n.point(t*Na,e*Na)})}function er(n,t){return[n,t]}function rr(n,t){return[n>Sa?n-ka:-Sa>n?n+ka:n,t]}function ur(n,t,e){return n?t||e?Ue(or(n),ar(t,e)):or(n):t||e?ar(t,e):rr}function ir(n){return function(t,e){return t+=n,[t>Sa?t-ka:-Sa>t?t+ka:t,e]}}function or(n){var t=ir(n);return t.invert=ir(-n),t}function ar(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),X(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),X(l*r-a*u)]},e}function cr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=sr(e,u),i=sr(e,i),(o>0?i>u:u>i)&&(u+=o*ka)):(u=n+o*ka,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=ve([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function sr(n,t){var e=se(t);e[0]-=n,pe(e);var r=V(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Aa)%(2*Math.PI)}function lr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function fr(n,t,e){var r=Xo.range(n,t-Aa,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function hr(n){return n.source}function gr(n){return n.target}function pr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(J(r-t)+u*o*J(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*La,Math.atan2(o,Math.sqrt(r*r+u*u))*La]}:function(){return[n*La,t*La]};return p.distance=h,p}function vr(){function n(n,u){var i=Math.sin(u*=Na),o=Math.cos(u),a=oa((n*=Na)-t),c=Math.cos(a);Uc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;jc.point=function(u,i){t=u*Na,e=Math.sin(i*=Na),r=Math.cos(i),jc.point=n},jc.lineEnd=function(){jc.point=jc.lineEnd=g}}function dr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function mr(n,t){function e(n,t){var e=oa(oa(t)-Ea)<Aa?0:o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(Sa/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=I(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Ea]},e):xr}function yr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return oa(u)<Aa?er:(e.invert=function(n,t){var e=i-t;return[Math.atan2(n,e)/u,i-I(u)*Math.sqrt(n*n+e*e)]},e)}function xr(n,t){return[n,Math.log(Math.tan(Sa/4+t/2))]}function Mr(n){var t,e=Qe(n),r=e.scale,u=e.translate,i=e.clipExtent;return e.scale=function(){var n=r.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.translate=function(){var n=u.apply(e,arguments);return n===e?t?e.clipExtent(null):e:n},e.clipExtent=function(n){var o=i.apply(e,arguments);if(o===e){if(t=null==n){var a=Sa*r(),c=u();i([[c[0]-a,c[1]-a],[c[0]+a,c[1]+a]])}}else t&&(o=null);return o},e.clipExtent(null)}function _r(n,t){return[Math.log(Math.tan(Sa/4+t/2)),-n]}function br(n){return n[0]}function wr(n){return n[1]}function Sr(n){for(var t=n.length,e=[0,1],r=2,u=2;t>u;u++){for(;r>1&&Z(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function kr(n,t){return n[0]-t[0]||n[1]-t[1]}function Er(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Ar(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Cr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Nr(){Jr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Jc.pop()||new Nr;return t.site=n,t}function Tr(n){Or(n),$c.remove(n),Jc.push(n),Jr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&oa(e-c.circle.x)<Aa&&oa(r-c.circle.cy)<Aa;)i=c.P,a.unshift(c),Tr(c),c=i;a.unshift(c),Or(c);for(var s=o;s.circle&&oa(e-s.circle.x)<Aa&&oa(r-s.circle.cy)<Aa;)o=s.N,a.push(s),Tr(s),s=o;a.push(s),Or(s);var l,f=a.length;for(l=1;f>l;++l)s=a[l],c=a[l-1],$r(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Vr(c.site,s.site,null,u),Fr(c),Fr(s)}function zr(n){for(var t,e,r,u,i=n.x,o=n.y,a=$c._;a;)if(r=Rr(a,o)-i,r>Aa)a=a.L;else{if(u=i-Dr(a,o),!(u>Aa)){r>-Aa?(t=a.P,e=a):u>-Aa?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if($c.insert(t,c),t||e){if(t===e)return Or(t),e=Lr(t.site),$c.insert(c,e),c.edge=e.edge=Vr(t.site,c.site),Fr(t),Fr(e),void 0;if(!e)return c.edge=Vr(t.site,c.site),void 0;Or(t),Or(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};$r(e.edge,s,p,M),c.edge=Vr(s,n,null,M),e.edge=Vr(n,p,null,M),Fr(t),Fr(e)}}function Rr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Dr(n,t){var e=n.N;if(e)return Rr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Pr(n){this.site=n,this.edges=[]}function Ur(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Xc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(oa(r-t)>Aa||oa(u-e)>Aa)&&(a.splice(o,0,new Br(Xr(i.site,l,oa(r-f)<Aa&&p-u>Aa?{x:f,y:oa(t-f)<Aa?e:p}:oa(u-p)<Aa&&h-r>Aa?{x:oa(e-p)<Aa?t:h,y:p}:oa(r-h)<Aa&&u-g>Aa?{x:h,y:oa(t-h)<Aa?e:g}:oa(u-g)<Aa&&r-f>Aa?{x:oa(e-g)<Aa?t:f,y:g}:null),i.site,null)),++c)}function jr(n,t){return t.angle-n.angle}function Hr(){Jr(this),this.x=this.y=this.arc=this.site=this.cy=null}function Fr(n){var t=n.P,e=n.N;if(t&&e){var r=t.site,u=n.site,i=e.site;if(r!==i){var o=u.x,a=u.y,c=r.x-o,s=r.y-a,l=i.x-o,f=i.y-a,h=2*(c*f-s*l);if(!(h>=-Ca)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Gc.pop()||new Hr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=Wc._;x;)if(m.y<x.y||m.y===x.y&&m.x<=x.x){if(!x.L){y=x.P;break}x=x.L}else{if(!x.R){y=x;break}x=x.R}Wc.insert(y,m),y||(Bc=m)}}}}function Or(n){var t=n.circle;t&&(t.P||(Bc=t.N),Wc.remove(t),Gc.push(t),Jr(t),n.circle=null)}function Yr(n){for(var t,e=Vc,r=De(n[0][0],n[0][1],n[1][0],n[1][1]),u=e.length;u--;)t=e[u],(!Ir(t,n)||!r(t)||oa(t.a.x-t.b.x)<Aa&&oa(t.a.y-t.b.y)<Aa)&&(t.a=t.b=null,e.splice(u,1))}function Ir(n,t){var e=n.b;if(e)return!0;var r,u,i=n.a,o=t[0][0],a=t[1][0],c=t[0][1],s=t[1][1],l=n.l,f=n.r,h=l.x,g=l.y,p=f.x,v=f.y,d=(h+p)/2,m=(g+v)/2;if(v===g){if(o>d||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.y<c)return}else i={x:d,y:s};e={x:d,y:c}}}else if(r=(h-p)/(v-g),u=m-r*d,-1>r||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.y<c)return}else i={x:(s-u)/r,y:s};e={x:(c-u)/r,y:c}}else if(v>g){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.x<o)return}else i={x:a,y:r*a+u};e={x:o,y:r*o+u}}return n.a=i,n.b=e,!0}function Zr(n,t){this.l=n,this.r=t,this.a=this.b=null}function Vr(n,t,e,r){var u=new Zr(n,t);return Vc.push(u),e&&$r(u,n,t,e),r&&$r(u,t,n,r),Xc[n.i].edges.push(new Br(u,n,t)),Xc[t.i].edges.push(new Br(u,t,n)),u}function Xr(n,t,e){var r=new Zr(n,null);return r.a=t,r.b=e,Vc.push(r),r}function $r(n,t,e,r){n.a||n.b?n.l===e?n.b=r:n.a=r:(n.a=r,n.l=t,n.r=e)}function Br(n,t,e){var r=n.a,u=n.b;this.edge=n,this.site=t,this.angle=e?Math.atan2(e.y-t.y,e.x-t.x):n.l===t?Math.atan2(u.x-r.x,r.y-u.y):Math.atan2(r.x-u.x,u.y-r.y)}function Wr(){this._=null}function Jr(n){n.U=n.C=n.L=n.R=n.P=n.N=null}function Gr(n,t){var e=t,r=t.R,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.R=r.L,e.R&&(e.R.U=e),r.L=e}function Kr(n,t){var e=t,r=t.L,u=e.U;u?u.L===e?u.L=r:u.R=r:n._=r,r.U=u,e.U=r,e.L=r.R,e.L&&(e.L.U=e),r.R=e}function Qr(n){for(;n.L;)n=n.L;return n}function nu(n,t){var e,r,u,i=n.sort(tu).pop();for(Vc=[],Xc=new Array(n.length),$c=new Wr,Wc=new Wr;;)if(u=Bc,i&&(!u||i.y<u.y||i.y===u.y&&i.x<u.x))(i.x!==e||i.y!==r)&&(Xc[i.i]=new Pr(i),zr(i),e=i.x,r=i.y),i=n.pop();else{if(!u)break;qr(u.arc)}t&&(Yr(t),Ur(t));var o={cells:Xc,edges:Vc};return $c=Wc=Vc=Xc=null,o}function tu(n,t){return t.y-n.y||t.x-n.x}function eu(n,t,e){return(n.x-e.x)*(t.y-n.y)-(n.x-t.x)*(e.y-n.y)}function ru(n){return n.x}function uu(n){return n.y}function iu(){return{leaf:!0,nodes:[],point:null,x:null,y:null}}function ou(n,t,e,r,u,i){if(!n(t,e,r,u,i)){var o=.5*(e+u),a=.5*(r+i),c=t.nodes;c[0]&&ou(n,c[0],e,r,o,a),c[1]&&ou(n,c[1],o,r,u,a),c[2]&&ou(n,c[2],e,a,o,i),c[3]&&ou(n,c[3],o,a,u,i)}}function au(n,t){n=Xo.rgb(n),t=Xo.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+vt(Math.round(e+i*n))+vt(Math.round(r+o*n))+vt(Math.round(u+a*n))}}function cu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=fu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function su(n,t){return t-=n=+n,function(e){return n+t*e}}function lu(n,t){var e,r,u,i,o,a=0,c=0,s=[],l=[];for(n+="",t+="",Qc.lastIndex=0,r=0;e=Qc.exec(t);++r)e.index&&s.push(t.substring(a,c=e.index)),l.push({i:s.length,x:e[0]}),s.push(null),a=Qc.lastIndex;for(a<t.length&&s.push(t.substring(a)),r=0,i=l.length;(e=Qc.exec(n))&&i>r;++r)if(o=l[r],o.x==e[0]){if(o.i)if(null==s[o.i+1])for(s[o.i-1]+=o.x,s.splice(o.i,1),u=r+1;i>u;++u)l[u].i--;else for(s[o.i-1]+=o.x+s[o.i+1],s.splice(o.i,2),u=r+1;i>u;++u)l[u].i-=2;else if(null==s[o.i+1])s[o.i]=o.x;else for(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1),u=r+1;i>u;++u)l[u].i--;l.splice(r,1),i--,r--}else o.x=su(parseFloat(e[0]),parseFloat(o.x));for(;i>r;)o=l.pop(),null==s[o.i+1]?s[o.i]=o.x:(s[o.i]=o.x+s[o.i+1],s.splice(o.i+1,1)),i--;return 1===s.length?null==s[0]?(o=l[0].x,function(n){return o(n)+""}):function(){return t}:function(n){for(r=0;i>r;++r)s[(o=l[r]).i]=o.x(n);return s.join("")}}function fu(n,t){for(var e,r=Xo.interpolators.length;--r>=0&&!(e=Xo.interpolators[r](n,t)););return e}function hu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(fu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function gu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function pu(n){return function(t){return 1-n(1-t)}}function vu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function du(n){return n*n}function mu(n){return n*n*n}function yu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function xu(n){return function(t){return Math.pow(t,n)}}function Mu(n){return 1-Math.cos(n*Ea)}function _u(n){return Math.pow(2,10*(n-1))}function bu(n){return 1-Math.sqrt(1-n*n)}function wu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/ka*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*ka/t)}}function Su(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function ku(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Eu(n,t){n=Xo.hcl(n),t=Xo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return rt(e+i*n,r+o*n,u+a*n)+""}}function Au(n,t){n=Xo.hsl(n),t=Xo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return nt(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Xo.lab(n),t=Xo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(zu(e,t,-u))||0;t[0]*e[1]<e[0]*t[1]&&(t[0]*=-1,t[1]*=-1,r*=-1,u*=-1),this.rotate=(r?Math.atan2(t[1],t[0]):Math.atan2(-e[0],e[1]))*La,this.translate=[n.e,n.f],this.scale=[r,i],this.skew=i?Math.atan2(u,i)*La:0}function Tu(n,t){return n[0]*t[0]+n[1]*t[1]}function qu(n){var t=Math.sqrt(Tu(n,n));return t&&(n[0]/=t,n[1]/=t),t}function zu(n,t,e){return n[0]+=e*t[0],n[1]+=e*t[1],n}function Ru(n,t){var e,r=[],u=[],i=Xo.transform(n),o=Xo.transform(t),a=i.translate,c=o.translate,s=i.rotate,l=o.rotate,f=i.skew,h=o.skew,g=i.scale,p=o.scale;return a[0]!=c[0]||a[1]!=c[1]?(r.push("translate(",null,",",null,")"),u.push({i:1,x:su(a[0],c[0])},{i:3,x:su(a[1],c[1])})):c[0]||c[1]?r.push("translate("+c+")"):r.push(""),s!=l?(s-l>180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:su(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:su(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:su(g[0],p[0])},{i:e-2,x:su(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i<e;)r[(t=u[i]).i]=t.x(n);return r.join("")}}function Du(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return(e-n)*t}}function Pu(n,t){return t=t-(n=+n)?1/(t-n):0,function(e){return Math.max(0,Math.min(1,(e-n)*t))}}function Uu(n){for(var t=n.source,e=n.target,r=Hu(t,e),u=[t];t!==r;)t=t.parent,u.push(t);for(var i=u.length;e!==r;)u.splice(i,0,e),e=e.parent;return u}function ju(n){for(var t=[],e=n.parent;null!=e;)t.push(n),n=e,e=e.parent;return t.push(n),t}function Hu(n,t){if(n===t)return n;for(var e=ju(n),r=ju(t),u=e.pop(),i=r.pop(),o=null;u===i;)o=u,u=e.pop(),i=r.pop();return o}function Fu(n){n.fixed|=2}function Ou(n){n.fixed&=-7}function Yu(n){n.fixed|=4,n.px=n.x,n.py=n.y}function Iu(n){n.fixed&=-5}function Zu(n,t,e){var r=0,u=0;if(n.charge=0,!n.leaf)for(var i,o=n.nodes,a=o.length,c=-1;++c<a;)i=o[c],null!=i&&(Zu(i,t,e),n.charge+=i.charge,r+=i.charge*i.cx,u+=i.charge*i.cy);if(n.point){n.leaf||(n.point.x+=Math.random()-.5,n.point.y+=Math.random()-.5);var s=t*e[n.point.index];n.charge+=n.pointCharge=s,r+=s*n.point.x,u+=s*n.point.y}n.cx=r/n.charge,n.cy=u/n.charge}function Vu(n,t){return Xo.rebind(n,t,"sort","children","value"),n.nodes=n,n.links=Wu,n}function Xu(n){return n.children}function $u(n){return n.value}function Bu(n,t){return t.value-n.value}function Wu(n){return Xo.merge(n.map(function(n){return(n.children||[]).map(function(t){return{source:n,target:t}})}))}function Ju(n){return n.x}function Gu(n){return n.y}function Ku(n,t,e){n.y0=t,n.y=e}function Qu(n){return Xo.range(n.length)}function ni(n){for(var t=-1,e=n[0].length,r=[];++t<e;)r[t]=0;return r}function ti(n){for(var t,e=1,r=0,u=n[0][1],i=n.length;i>e;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ei(n){return n.reduce(ri,0)}function ri(n,t){return n+t[1]}function ui(n,t){return ii(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ii(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function oi(n){return[Xo.min(n),Xo.max(n)]}function ai(n,t){return n.parent==t.parent?1:2}function ci(n){var t=n.children;return t&&t.length?t[0]:n._tree.thread}function si(n){var t,e=n.children;return e&&(t=e.length)?e[t-1]:n._tree.thread}function li(n,t){var e=n.children;if(e&&(u=e.length))for(var r,u,i=-1;++i<u;)t(r=li(e[i],t),n)>0&&(n=r);return n}function fi(n,t){return n.x-t.x}function hi(n,t){return t.x-n.x}function gi(n,t){return n.depth-t.depth}function pi(n,t){function e(n,r){var u=n.children;if(u&&(o=u.length))for(var i,o,a=null,c=-1;++c<o;)i=u[c],e(i,a),a=i;t(n,r)}e(n,null)}function vi(n){for(var t,e=0,r=0,u=n.children,i=u.length;--i>=0;)t=u[i]._tree,t.prelim+=e,t.mod+=e,e+=t.shift+(r+=t.change)}function di(n,t,e){n=n._tree,t=t._tree;var r=e/(t.number-n.number);n.change+=r,t.change-=r,t.shift+=e,t.prelim+=e,t.mod+=e}function mi(n,t,e){return n._tree.ancestor.parent==t.parent?n._tree.ancestor:e}function yi(n,t){return n.value-t.value}function xi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function Mi(n,t){n._pack_next=t,t._pack_prev=n}function _i(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function bi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(wi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],Ei(r,u,i),t(i),xi(r,i),r._pack_prev=i,xi(i,u),u=r._pack_next,o=3;s>o;o++){Ei(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(_i(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!_i(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.r<r.r?Mi(r,u=a):Mi(r=c,u),o--):(xi(r,i),u=i,t(i))}var m=(l+f)/2,y=(h+g)/2,x=0;for(o=0;s>o;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(Si)}}function wi(n){n._pack_next=n._pack_prev=n}function Si(n){delete n._pack_next,delete n._pack_prev}function ki(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i<o;)ki(u[i],t,e,r)}function Ei(n,t,e){var r=n.r+e.r,u=t.x-n.x,i=t.y-n.y;if(r&&(u||i)){var o=t.r+e.r,a=u*u+i*i;o*=o,r*=r;var c=.5+(r-o)/(2*a),s=Math.sqrt(Math.max(0,2*o*(r+a)-(r-=a)*r-o*o))/(2*a);e.x=n.x+c*u+s*i,e.y=n.y+c*i-s*u}else e.x=n.x+r,e.y=n.y}function Ai(n){return 1+Xo.max(n,function(n){return n.y})}function Ci(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ni(n){var t=n.children;return t&&t.length?Ni(t[0]):n}function Li(n){var t,e=n.children;return e&&(t=e.length)?Li(e[t-1]):n}function Ti(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function qi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function zi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ri(n){return n.rangeExtent?n.rangeExtent():zi(n.range())}function Di(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Pi(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Ui(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ls}function ji(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]<n[0]&&(n=n.slice().reverse(),t=t.slice().reverse());++o<=a;)u.push(e(n[o-1],n[o])),i.push(r(t[o-1],t[o]));return function(t){var e=Xo.bisect(n,t,1,a)-1;return i[e](u[e](t))}}function Hi(n,t,e,r){function u(){var u=Math.min(n.length,t.length)>2?ji:Di,c=r?Pu:Du;return o=u(n,t,c,e),a=u(t,n,c,fu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(Nu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Ii(n,t)},i.tickFormat=function(t,e){return Zi(n,t,e)},i.nice=function(t){return Oi(n,t),u()},i.copy=function(){return Hi(n,t,e,r)},u()}function Fi(n,t){return Xo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Oi(n,t){return Pi(n,Ui(Yi(n,t)[2]))}function Yi(n,t){null==t&&(t=10);var e=zi(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Ii(n,t){return Xo.range.apply(Xo,Yi(n,t))}function Zi(n,t,e){var r=Yi(n,t);return Xo.format(e?e.replace(Qa,function(n,t,e,u,i,o,a,c,s,l){return[t,e,u,i,o,a,c,s||"."+Xi(l,r),l].join("")}):",."+Vi(r[2])+"f")}function Vi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Xi(n,t){var e=Vi(t[2]);return n in fs?Math.abs(e-Vi(Math.max(Math.abs(t[0]),Math.abs(t[1]))))+ +("e"!==n):e-2*("%"===n)}function $i(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Pi(r.map(u),e?Math:gs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=zi(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++<l;)for(var h=f-1;h>0;h--)o.push(i(s)*h);for(s=0;o[s]<a;s++);for(l=o.length;o[l-1]>c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return hs;arguments.length<2?t=hs:"function"!=typeof t&&(t=Xo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return $i(n.copy(),t,e,r)},Fi(o,n)}function Bi(n,t,e){function r(t){return n(u(t))}var u=Wi(t),i=Wi(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Ii(e,n)},r.tickFormat=function(n,t){return Zi(e,n,t)},r.nice=function(n){return r.domain(Oi(e,n))},r.exponent=function(o){return arguments.length?(u=Wi(t=o),i=Wi(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Bi(n.copy(),t,e)},Fi(r,n)}function Wi(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Ji(n,t){function e(e){return o[((i.get(e)||"range"===t.t&&i.set(e,n.push(e)))-1)%o.length]}function r(t,e){return Xo.range(n.length).map(function(n){return t+e*n})}var i,o,a;return e.domain=function(r){if(!arguments.length)return n;n=[],i=new u;for(var o,a=-1,c=r.length;++a<c;)i.has(o=r[a])||i.set(o,n.push(o));return e[t.t].apply(e,t.a)},e.range=function(n){return arguments.length?(o=n,a=0,t={t:"range",a:arguments},e):o},e.rangePoints=function(u,i){arguments.length<2&&(i=0);var c=u[0],s=u[1],l=(s-c)/(Math.max(1,n.length-1)+i);return o=r(n.length<2?(c+s)/2:c+l*i/2,l),a=0,t={t:"rangePoints",a:arguments},e},e.rangeBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=(f-l)/(n.length-i+2*c);return o=r(l+h*c,h),s&&o.reverse(),a=h*(1-i),t={t:"rangeBands",a:arguments},e},e.rangeRoundBands=function(u,i,c){arguments.length<2&&(i=0),arguments.length<3&&(c=i);var s=u[1]<u[0],l=u[s-0],f=u[1-s],h=Math.floor((f-l)/(n.length-i+2*c)),g=f-l-(n.length-i)*h;return o=r(l+Math.round(g/2),h),s&&o.reverse(),a=Math.round(h*(1-i)),t={t:"rangeRoundBands",a:arguments},e},e.rangeBand=function(){return a},e.rangeExtent=function(){return zi(t.a[0])},e.copy=function(){return Ji(n,t)},e.domain(n)}function Gi(n,t){function e(){var e=0,i=t.length;for(u=[];++e<i;)u[e-1]=Xo.quantile(n,e/i);return r}function r(n){return isNaN(n=+n)?void 0:t[Xo.bisect(u,n)]}var u;return r.domain=function(t){return arguments.length?(n=t.filter(function(n){return!isNaN(n)}).sort(Xo.ascending),e()):n},r.range=function(n){return arguments.length?(t=n,e()):t},r.quantiles=function(){return u},r.invertExtent=function(e){return e=t.indexOf(e),0>e?[0/0,0/0]:[e>0?u[e-1]:n[0],e<u.length?u[e]:n[n.length-1]]},r.copy=function(){return Gi(n,t)},e()}function Ki(n,t,e){function r(t){return e[Math.max(0,Math.min(o,Math.floor(i*(t-n))))]}function u(){return i=e.length/(t-n),o=e.length-1,r}var i,o;return r.domain=function(e){return arguments.length?(n=+e[0],t=+e[e.length-1],u()):[n,t]},r.range=function(n){return arguments.length?(e=n,u()):e},r.invertExtent=function(t){return t=e.indexOf(t),t=0>t?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ki(n,t,e)},u()}function Qi(n,t){function e(e){return e>=e?t[Xo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Qi(n,t)},e}function no(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Ii(n,t)},t.tickFormat=function(t,e){return Zi(n,t,e)},t.copy=function(){return no(n)},t}function to(n){return n.innerRadius}function eo(n){return n.outerRadius}function ro(n){return n.startAngle}function uo(n){return n.endAngle}function io(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=_t(e),p=_t(r);++f<h;)u.call(this,c=t[f],f)?l.push([+g.call(this,c,f),+p.call(this,c,f)]):l.length&&(o(),l=[]);return l.length&&o(),s.length?s.join(""):null}var e=br,r=wr,u=be,i=oo,o=i.key,a=.7;return t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t.defined=function(n){return arguments.length?(u=n,t):u},t.interpolate=function(n){return arguments.length?(o="function"==typeof n?i=n:(i=Ms.get(n)||oo).key,t):o},t.tension=function(n){return arguments.length?(a=n,t):a},t}function oo(n){return n.join("L")}function ao(n){return oo(n)+"Z"}function co(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r[0]+(r=n[t])[0])/2,"V",r[1]);return e>1&&u.push("H",r[0]),u.join("")}function so(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("V",(r=n[t])[1],"H",r[0]);return u.join("")}function lo(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t<e;)u.push("H",(r=n[t])[0],"V",r[1]);return u.join("")}function fo(n,t){return n.length<4?oo(n):n[1]+po(n.slice(1,n.length-1),vo(n,t))}function ho(n,t){return n.length<3?oo(n):n[0]+po((n.push(n[0]),n),vo([n[n.length-2]].concat(n,[n[1]]),t))}function go(n,t){return n.length<3?oo(n):n[0]+po(n,vo(n,t))}function po(n,t){if(t.length<1||n.length!=t.length&&n.length!=t.length+2)return oo(n);var e=n.length!=t.length,r="",u=n[0],i=n[1],o=t[0],a=o,c=1;if(e&&(r+="Q"+(i[0]-2*o[0]/3)+","+(i[1]-2*o[1]/3)+","+i[0]+","+i[1],u=n[1],c=2),t.length>1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s<t.length;s++,c++)i=n[c],a=t[s],r+="S"+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1]}if(e){var l=n[c];r+="Q"+(i[0]+2*a[0]/3)+","+(i[1]+2*a[1]/3)+","+l[0]+","+l[1]}return r}function vo(n,t){for(var e,r=[],u=(1-t)/2,i=n[0],o=n[1],a=1,c=n.length;++a<c;)e=i,i=o,o=n[a],r.push([u*(o[0]-e[0]),u*(o[1]-e[1])]);return r}function mo(n){if(n.length<3)return oo(n);var t=1,e=n.length,r=n[0],u=r[0],i=r[1],o=[u,u,u,(r=n[1])[0]],a=[i,i,i,r[1]],c=[u,",",i,"L",_o(ws,o),",",_o(ws,a)];for(n.push(n[e-1]);++t<=e;)r=n[t],o.shift(),o.push(r[0]),a.shift(),a.push(r[1]),bo(c,o,a);return n.pop(),c.push("L",r),c.join("")}function yo(n){if(n.length<4)return oo(n);for(var t,e=[],r=-1,u=n.length,i=[0],o=[0];++r<3;)t=n[r],i.push(t[0]),o.push(t[1]);for(e.push(_o(ws,i)+","+_o(ws,o)),--r;++r<u;)t=n[r],i.shift(),i.push(t[0]),o.shift(),o.push(t[1]),bo(e,i,o);return e.join("")}function xo(n){for(var t,e,r=-1,u=n.length,i=u+4,o=[],a=[];++r<4;)e=n[r%u],o.push(e[0]),a.push(e[1]);for(t=[_o(ws,o),",",_o(ws,a)],--r;++r<i;)e=n[r%u],o.shift(),o.push(e[0]),a.shift(),a.push(e[1]),bo(t,o,a);return t.join("")}function Mo(n,t){var e=n.length-1;if(e)for(var r,u,i=n[0][0],o=n[0][1],a=n[e][0]-i,c=n[e][1]-o,s=-1;++s<=e;)r=n[s],u=s/e,r[0]=t*r[0]+(1-t)*(i+u*a),r[1]=t*r[1]+(1-t)*(o+u*c);return mo(n)}function _o(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]+n[3]*t[3]}function bo(n,t,e){n.push("C",_o(_s,t),",",_o(_s,e),",",_o(bs,t),",",_o(bs,e),",",_o(ws,t),",",_o(ws,e))}function wo(n,t){return(t[1]-n[1])/(t[0]-n[0])}function So(n){for(var t=0,e=n.length-1,r=[],u=n[0],i=n[1],o=r[0]=wo(u,i);++t<e;)r[t]=(o+(o=wo(u=i,i=n[t+1])))/2;return r[t]=o,r}function ko(n){for(var t,e,r,u,i=[],o=So(n),a=-1,c=n.length-1;++a<c;)t=wo(n[a],n[a+1]),oa(t)<Aa?o[a]=o[a+1]=0:(e=o[a]/t,r=o[a+1]/t,u=e*e+r*r,u>9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function Eo(n){return n.length<3?oo(n):n[0]+po(n,ko(n))}function Ao(n){for(var t,e,r,u=-1,i=n.length;++u<i;)t=n[u],e=t[0],r=t[1]+ys,t[0]=e*Math.cos(r),t[1]=e*Math.sin(r);return n}function Co(n){function t(t){function c(){v.push("M",a(n(m),f),l,s(n(d.reverse()),f),"Z")}for(var h,g,p,v=[],d=[],m=[],y=-1,x=t.length,M=_t(e),_=_t(u),b=e===r?function(){return g}:_t(r),w=u===i?function(){return p}:_t(i);++y<x;)o.call(this,h=t[y],y)?(d.push([g=+M.call(this,h,y),p=+_.call(this,h,y)]),m.push([+b.call(this,h,y),+w.call(this,h,y)])):d.length&&(c(),d=[],m=[]);return d.length&&c(),v.length?v.join(""):null}var e=br,r=br,u=0,i=wr,o=be,a=oo,c=a.key,s=a,l="L",f=.7;return t.x=function(n){return arguments.length?(e=r=n,t):r},t.x0=function(n){return arguments.length?(e=n,t):e},t.x1=function(n){return arguments.length?(r=n,t):r},t.y=function(n){return arguments.length?(u=i=n,t):i},t.y0=function(n){return arguments.length?(u=n,t):u},t.y1=function(n){return arguments.length?(i=n,t):i},t.defined=function(n){return arguments.length?(o=n,t):o},t.interpolate=function(n){return arguments.length?(c="function"==typeof n?a=n:(a=Ms.get(n)||oo).key,s=a.reverse||a,l=a.closed?"M":"L",t):c},t.tension=function(n){return arguments.length?(f=n,t):f},t}function No(n){return n.radius}function Lo(n){return[n.x,n.y]}function To(n){return function(){var t=n.apply(this,arguments),e=t[0],r=t[1]+ys;return[e*Math.cos(r),e*Math.sin(r)]}}function qo(){return 64}function zo(){return"circle"}function Ro(n){var t=Math.sqrt(n/Sa);return"M0,"+t+"A"+t+","+t+" 0 1,1 0,"+-t+"A"+t+","+t+" 0 1,1 0,"+t+"Z"}function Do(n,t){return fa(n,Ns),n.id=t,n}function Po(n,t,e,r){var u=n.id;return R(n,"function"==typeof e?function(n,i,o){n.__transition__[u].tween.set(t,r(e.call(n,n.__data__,i,o)))}:(e=r(e),function(n){n.__transition__[u].tween.set(t,e)}))}function Uo(n){return null==n&&(n=""),function(){this.textContent=n}}function jo(n,t,e,r){var i=n.__transition__||(n.__transition__={active:0,count:0}),o=i[e];if(!o){var a=r.time;o=i[e]={tween:new u,time:a,ease:r.ease,delay:r.delay,duration:r.duration},++i.count,Xo.timer(function(r){function u(r){return i.active>e?s():(i.active=e,o.event&&o.event.start.call(n,l,t),o.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Xo.timer(function(){return p.c=c(r||1)?be:c,1},0,a),void 0)}function c(r){if(i.active!==e)return s();for(var u=r/g,a=f(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,l,t),s()):void 0}function s(){return--i.count?delete i[e]:delete n.__transition__,1}var l=n.__data__,f=o.ease,h=o.delay,g=o.duration,p=Ja,v=[];return p.t=h+a,r>=h?u(r-h):(p.c=u,void 0)},0,a)}}function Ho(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function Fo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Oo(n){return n.toISOString()}function Yo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Xo.bisect(js,u);return i==js.length?[t.year,Yi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/js[i-1]<js[i]/u?i-1:i]:[Os,Yi(n,e)[2]]}return r.invert=function(t){return Io(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain(t),r):n.domain().map(Io)},r.nice=function(n,t){function e(e){return!isNaN(e)&&!n.range(e,Io(+e+1),t).length}var i=r.domain(),o=zi(i),a=null==n?u(o,10):"number"==typeof n&&u(o,n);return a&&(n=a[0],t=a[1]),r.domain(Pi(i,t>1?{floor:function(t){for(;e(t=n.floor(t));)t=Io(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Io(+t+1);return t}}:n))},r.ticks=function(n,t){var e=zi(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Io(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Yo(n.copy(),t,e)},Fi(r,n)}function Io(n){return new Date(n)}function Zo(n){return JSON.parse(n.responseText)}function Vo(n){var t=Wo.createRange();return t.selectNode(Wo.body),t.createContextualFragment(n.responseText)}var Xo={version:"3.4.3"};Date.now||(Date.now=function(){return+new Date});var $o=[].slice,Bo=function(n){return $o.call(n)},Wo=document,Jo=Wo.documentElement,Go=window;try{Bo(Jo.childNodes)[0].nodeType}catch(Ko){Bo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{Wo.createElement("div").style.setProperty("opacity",0,"")}catch(Qo){var na=Go.Element.prototype,ta=na.setAttribute,ea=na.setAttributeNS,ra=Go.CSSStyleDeclaration.prototype,ua=ra.setProperty;na.setAttribute=function(n,t){ta.call(this,n,t+"")},na.setAttributeNS=function(n,t,e){ea.call(this,n,t,e+"")},ra.setProperty=function(n,t,e){ua.call(this,n,t+"",e)}}Xo.ascending=function(n,t){return t>n?-1:n>t?1:n>=t?0:0/0},Xo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Xo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&e>r&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&e>r&&(e=r)}return e},Xo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u<i&&!(null!=(e=n[u])&&e>=e);)e=void 0;for(;++u<i;)null!=(r=n[u])&&r>e&&(e=r)}else{for(;++u<i&&!(null!=(e=t.call(n,n[u],u))&&e>=e);)e=void 0;for(;++u<i;)null!=(r=t.call(n,n[u],u))&&r>e&&(e=r)}return e},Xo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i<o&&!(null!=(e=u=n[i])&&e>=e);)e=u=void 0;for(;++i<o;)null!=(r=n[i])&&(e>r&&(e=r),r>u&&(u=r))}else{for(;++i<o&&!(null!=(e=u=t.call(n,n[i],i))&&e>=e);)e=void 0;for(;++i<o;)null!=(r=t.call(n,n[i],i))&&(e>r&&(e=r),r>u&&(u=r))}return[e,u]},Xo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i<u;)isNaN(e=+n[i])||(r+=e);else for(;++i<u;)isNaN(e=+t.call(n,n[i],i))||(r+=e);return r},Xo.mean=function(t,e){var r,u=t.length,i=0,o=-1,a=0;if(1===arguments.length)for(;++o<u;)n(r=t[o])&&(i+=(r-i)/++a);else for(;++o<u;)n(r=e.call(t,t[o],o))&&(i+=(r-i)/++a);return a?i:void 0},Xo.quantile=function(n,t){var e=(n.length-1)*t+1,r=Math.floor(e),u=+n[r-1],i=e-r;return i?u+i*(n[r]-u):u},Xo.median=function(t,e){return arguments.length>1&&(t=t.map(e)),t=t.filter(n),t.length?Xo.quantile(t.sort(Xo.ascending),.5):void 0},Xo.bisector=function(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n.call(t,t[i],i)<e?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;e<n.call(t,t[i],i)?u=i:r=i+1}return r}}};var ia=Xo.bisector(function(n){return n});Xo.bisectLeft=ia.left,Xo.bisect=Xo.bisectRight=ia.right,Xo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Xo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Xo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Xo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,e=Xo.min(arguments,t),r=new Array(e);++n<e;)for(var u,i=-1,o=r[n]=new Array(u);++i<u;)o[i]=arguments[i][n];return r},Xo.transpose=function(n){return Xo.zip.apply(Xo,n)},Xo.keys=function(n){var t=[];for(var e in n)t.push(e);return t},Xo.values=function(n){var t=[];for(var e in n)t.push(n[e]);return t},Xo.entries=function(n){var t=[];for(var e in n)t.push({key:e,value:n[e]});return t},Xo.merge=function(n){for(var t,e,r,u=n.length,i=-1,o=0;++i<u;)o+=n[i].length;for(e=new Array(o);--u>=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var oa=Math.abs;Xo.range=function(n,t,r){if(arguments.length<3&&(r=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/r)throw new Error("infinite range");var u,i=[],o=e(oa(r)),a=-1;if(n*=o,t*=o,r*=o,0>r)for(;(u=n+r*++a)>t;)i.push(u/o);else for(;(u=n+r*++a)<t;)i.push(u/o);return i},Xo.map=function(n){var t=new u;if(n instanceof u)n.forEach(function(n,e){t.set(n,e)});else for(var e in n)t.set(e,n[e]);return t},r(u,{has:i,get:function(n){return this[aa+n]},set:function(n,t){return this[aa+n]=t},remove:o,keys:a,values:function(){var n=[];return this.forEach(function(t,e){n.push(e)}),n},entries:function(){var n=[];return this.forEach(function(t,e){n.push({key:t,value:e})}),n},size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1),this[t])}});var aa="\x00",ca=aa.charCodeAt(0);Xo.nest=function(){function n(t,a,c){if(c>=o.length)return r?r.call(i,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=o[c++],d=new u;++g<p;)(h=d.get(s=v(l=a[g])))?h.push(l):d.set(s,[l]);return t?(l=t(),f=function(e,r){l.set(e,n(t,r,c))}):(l={},f=function(e,r){l[e]=n(t,r,c)}),d.forEach(f),l}function t(n,e){if(e>=o.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,i={},o=[],a=[];return i.map=function(t,e){return n(e,t,0)},i.entries=function(e){return t(n(Xo.map,e,0),0)},i.key=function(n){return o.push(n),i},i.sortKeys=function(n){return a[o.length-1]=n,i},i.sortValues=function(n){return e=n,i},i.rollup=function(n){return r=n,i},i},Xo.set=function(n){var t=new l;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},r(l,{has:i,add:function(n){return this[aa+n]=!0,n},remove:function(n){return n=aa+n,n in this&&delete this[n]},values:a,size:c,empty:s,forEach:function(n){for(var t in this)t.charCodeAt(0)===ca&&n.call(this,t.substring(1))}}),Xo.behavior={},Xo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r<u;)n[e=arguments[r]]=f(n,t,t[e]);return n};var sa=["webkit","ms","moz","Moz","o","O"];Xo.dispatch=function(){for(var n=new p,t=-1,e=arguments.length;++t<e;)n[arguments[t]]=v(n);return n},p.prototype.on=function(n,t){var e=n.indexOf("."),r="";if(e>=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Xo.event=null,Xo.requote=function(n){return n.replace(la,"\\$&")};var la=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,fa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ha=function(n,t){return t.querySelector(n)},ga=function(n,t){return t.querySelectorAll(n)},pa=Jo[h(Jo,"matchesSelector")],va=function(n,t){return pa.call(n,t)};"function"==typeof Sizzle&&(ha=function(n,t){return Sizzle(n,t)[0]||null},ga=Sizzle,va=Sizzle.matchesSelector),Xo.selection=function(){return xa};var da=Xo.selection.prototype=[];da.select=function(n){var t,e,r,u,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]),t.parentNode=(r=this[o]).parentNode;for(var c=-1,s=r.length;++c<s;)(u=r[c])?(t.push(e=n.call(u,u.__data__,c,o)),e&&"__data__"in u&&(e.__data__=u.__data__)):t.push(null)}return x(i)},da.selectAll=function(n){var t,e,r=[];n=_(n);for(var u=-1,i=this.length;++u<i;)for(var o=this[u],a=-1,c=o.length;++a<c;)(e=o[a])&&(r.push(t=Bo(n.call(e,e.__data__,a,u))),t.parentNode=e);return x(r)};var ma={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};Xo.ns={prefix:ma,qualify:function(n){var t=n.indexOf(":"),e=n;return t>=0&&(e=n.substring(0,t),n=n.substring(t+1)),ma.hasOwnProperty(e)?{space:ma[e],local:n}:n}},da.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Xo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(b(t,n[t]));return this}return this.each(b(n,t))},da.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=k(n)).length,u=-1;if(t=e.classList){for(;++u<r;)if(!t.contains(n[u]))return!1}else for(t=e.getAttribute("class");++u<r;)if(!S(n[u]).test(t))return!1;return!0}for(t in n)this.each(E(t,n[t]));return this}return this.each(E(n,t))},da.style=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(C(e,n[e],t));return this}if(2>r)return Go.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(C(n,t,e))},da.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(N(t,n[t]));return this}return this.each(N(n,t))},da.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},da.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},da.append=function(n){return n=L(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},da.insert=function(n,t){return n=L(n),t=M(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},da.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},da.data=function(n,t){function e(n,e){var r,i,o,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new u,y=new u,x=[];for(r=-1;++r<a;)d=t.call(i=n[r],i.__data__,r),m.has(d)?v[r]=i:m.set(d,i),x.push(d);for(r=-1;++r<f;)d=t.call(e,o=e[r],r),(i=m.get(d))?(g[r]=i,i.__data__=o):y.has(d)||(p[r]=T(o)),y.set(d,o),m.remove(d);for(r=-1;++r<a;)m.has(x[r])&&(v[r]=n[r])}else{for(r=-1;++r<h;)i=n[r],o=e[r],i?(i.__data__=o,g[r]=i):p[r]=T(o);for(;f>r;++r)p[r]=T(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,i,o=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++o<a;)(i=r[o])&&(n[o]=i.__data__);return n}var c=D([]),s=x([]),l=x([]);if("function"==typeof n)for(;++o<a;)e(r=this[o],n.call(r,r.parentNode.__data__,o));else for(;++o<a;)e(r=this[o],n);return s.enter=function(){return c},s.exit=function(){return l},s},da.datum=function(n){return arguments.length?this.property("__data__",n):this.property("__data__")},da.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return x(u)},da.order=function(){for(var n=-1,t=this.length;++n<t;)for(var e,r=this[n],u=r.length-1,i=r[u];--u>=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},da.sort=function(n){n=z.apply(this,arguments);for(var t=-1,e=this.length;++t<e;)this[t].sort(n);return this.order()},da.each=function(n){return R(this,function(t,e,r){n.call(t,t.__data__,e,r)})},da.call=function(n){var t=Bo(arguments);return n.apply(t[0]=this,t),this},da.empty=function(){return!this.node()},da.node=function(){for(var n=0,t=this.length;t>n;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},da.size=function(){var n=0;return this.each(function(){++n}),n};var ya=[];Xo.selection.enter=D,Xo.selection.enter.prototype=ya,ya.append=da.append,ya.empty=da.empty,ya.node=da.node,ya.call=da.call,ya.size=da.size,ya.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++a<c;){r=(u=this[a]).update,o.push(t=[]),t.parentNode=u.parentNode;for(var s=-1,l=u.length;++s<l;)(i=u[s])?(t.push(r[s]=e=n.call(u.parentNode,i.__data__,s,a)),e.__data__=i.__data__):t.push(null)}return x(o)},ya.insert=function(n,t){return arguments.length<2&&(t=P(this)),da.insert.call(this,n,t)},da.transition=function(){for(var n,t,e=ks||++Ls,r=[],u=Es||{time:Date.now(),ease:yu,delay:0,duration:250},i=-1,o=this.length;++i<o;){r.push(n=[]);for(var a=this[i],c=-1,s=a.length;++c<s;)(t=a[c])&&jo(t,c,e,u),n.push(t)}return Do(r,e)},da.interrupt=function(){return this.each(U)},Xo.select=function(n){var t=["string"==typeof n?ha(n,Wo):n];return t.parentNode=Jo,x([t])},Xo.selectAll=function(n){var t=Bo("string"==typeof n?ga(n,Wo):n);return t.parentNode=Jo,x([t])};var xa=Xo.select(Jo);da.on=function(n,t,e){var r=arguments.length;if(3>r){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(j(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(j(n,t,e))};var Ma=Xo.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ma.forEach(function(n){"on"+n in Wo&&Ma.remove(n)});var _a="onselectstart"in Wo?null:h(Jo.style,"userSelect"),ba=0;Xo.mouse=function(n){return Y(n,m())};var wa=/WebKit/.test(Go.navigator.userAgent)?-1:0;Xo.touches=function(n,t){return arguments.length<2&&(t=m().touches),t?Bo(t).map(function(t){var e=Y(n,t);return e.identifier=t.identifier,e}):[]},Xo.behavior.drag=function(){function n(){this.on("mousedown.drag",o).on("touchstart.drag",a)}function t(){return Xo.event.changedTouches[0].identifier}function e(n,t){return Xo.touches(n).filter(function(n){return n.identifier===t})[0]}function r(n,t,e,r){return function(){function o(){var n=t(l,g),e=n[0]-v[0],r=n[1]-v[1];d|=e|r,v=n,f({type:"drag",x:n[0]+c[0],y:n[1]+c[1],dx:e,dy:r})}function a(){m.on(e+"."+p,null).on(r+"."+p,null),y(d&&Xo.event.target===h),f({type:"dragend"})}var c,s=this,l=s.parentNode,f=u.of(s,arguments),h=Xo.event.target,g=n(),p=null==g?"drag":"drag-"+g,v=t(l,g),d=0,m=Xo.select(Go).on(e+"."+p,o).on(r+"."+p,a),y=O();i?(c=i.apply(s,arguments),c=[c.x-v[0],c.y-v[1]]):c=[0,0],f({type:"dragstart"})}}var u=y(n,"drag","dragstart","dragend"),i=null,o=r(g,Xo.mouse,"mousemove","mouseup"),a=r(t,e,"touchmove","touchend");return n.origin=function(t){return arguments.length?(i=t,n):i},Xo.rebind(n,u,"on")};var Sa=Math.PI,ka=2*Sa,Ea=Sa/2,Aa=1e-6,Ca=Aa*Aa,Na=Sa/180,La=180/Sa,Ta=Math.SQRT2,qa=2,za=4;Xo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=B(v),o=i/(qa*h)*(e*W(Ta*t+v)-$(v));return[r+o*s,u+o*l,i*e/B(Ta*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Ta*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+za*f)/(2*i*qa*h),p=(c*c-i*i-za*f)/(2*c*qa*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Ta;return e.duration=1e3*y,e},Xo.behavior.zoom=function(){function n(n){n.on(A,s).on(Pa+".zoom",f).on(C,h).on("dblclick.zoom",g).on(L,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(M.range().map(function(n){return(n-S.x)/S.k}).map(M.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Xo.mouse(r),g),a(i)}function e(){f.on(C,Go===r?h:null).on(N,null),p(l&&Xo.event.target===s),c(i)}var r=this,i=T.of(r,arguments),s=Xo.event.target,l=0,f=Xo.select(Go).on(C,n).on(N,e),g=t(Xo.mouse(r)),p=O();U.call(r),o(i)}function l(){function n(){var n=Xo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){for(var t=Xo.event.changedTouches,e=0,i=t.length;i>e;++e)v[t[e].identifier]=null;var o=n(),c=Date.now();if(1===o.length){if(500>c-x){var s=o[0],l=v[s.identifier];r(2*S.k),u(s,l),d(),a(p)}x=c}else if(o.length>1){var s=o[0],f=o[1],h=s[0]-f[0],g=s[1]-f[1];m=h*h+g*g}}function i(){for(var n,t,e,i,o=Xo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=m&&Math.sqrt(l/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}x=null,u(n,t),a(p)}function f(){if(Xo.event.touches.length){for(var t=Xo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}b.on(M,null).on(_,null),w.on(A,s).on(L,l),k(),c(p)}var h,g=this,p=T.of(g,arguments),v={},m=0,y=Xo.event.changedTouches[0].identifier,M="touchmove.zoom-"+y,_="touchend.zoom-"+y,b=Xo.select(Go).on(M,i).on(_,f),w=Xo.select(g).on(A,null).on(L,e),k=O();U.call(g),e(),o(p)}function f(){var n=T.of(this,arguments);m?clearTimeout(m):(U.call(this),o(n)),m=setTimeout(function(){m=null,c(n)},50),d();var e=v||Xo.mouse(this);p||(p=t(e)),r(Math.pow(2,.002*Ra())*S.k),u(e,p),a(n)}function h(){p=null}function g(){var n=T.of(this,arguments),e=Xo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Xo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var p,v,m,x,M,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=Da,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",L="touchstart.zoom",T=y(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=T.of(this,arguments),t=S;ks?Xo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Xo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?Da:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,M=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Xo.rebind(n,T,"on")};var Ra,Da=[0,1/0],Pa="onwheel"in Wo?(Ra=function(){return-Xo.event.deltaY*(Xo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in Wo?(Ra=function(){return Xo.event.wheelDelta},"mousewheel"):(Ra=function(){return-Xo.event.detail},"MozMousePixelScroll");G.prototype.toString=function(){return this.rgb()+""},Xo.hsl=function(n,t,e){return 1===arguments.length?n instanceof Q?K(n.h,n.s,n.l):dt(""+n,mt,K):K(+n,+t,+e)};var Ua=Q.prototype=new G;Ua.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,this.l/n)},Ua.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),K(this.h,this.s,n*this.l)},Ua.rgb=function(){return nt(this.h,this.s,this.l)},Xo.hcl=function(n,t,e){return 1===arguments.length?n instanceof et?tt(n.h,n.c,n.l):n instanceof it?at(n.l,n.a,n.b):at((n=yt((n=Xo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):tt(+n,+t,+e)};var ja=et.prototype=new G;ja.brighter=function(n){return tt(this.h,this.c,Math.min(100,this.l+Ha*(arguments.length?n:1)))},ja.darker=function(n){return tt(this.h,this.c,Math.max(0,this.l-Ha*(arguments.length?n:1)))},ja.rgb=function(){return rt(this.h,this.c,this.l).rgb()},Xo.lab=function(n,t,e){return 1===arguments.length?n instanceof it?ut(n.l,n.a,n.b):n instanceof et?rt(n.l,n.c,n.h):yt((n=Xo.rgb(n)).r,n.g,n.b):ut(+n,+t,+e)};var Ha=18,Fa=.95047,Oa=1,Ya=1.08883,Ia=it.prototype=new G;Ia.brighter=function(n){return ut(Math.min(100,this.l+Ha*(arguments.length?n:1)),this.a,this.b)},Ia.darker=function(n){return ut(Math.max(0,this.l-Ha*(arguments.length?n:1)),this.a,this.b)},Ia.rgb=function(){return ot(this.l,this.a,this.b)},Xo.rgb=function(n,t,e){return 1===arguments.length?n instanceof pt?gt(n.r,n.g,n.b):dt(""+n,gt,nt):gt(~~n,~~t,~~e)};var Za=pt.prototype=new G;Za.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),gt(Math.min(255,~~(t/n)),Math.min(255,~~(e/n)),Math.min(255,~~(r/n)))):gt(u,u,u)},Za.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),gt(~~(n*this.r),~~(n*this.g),~~(n*this.b))},Za.hsl=function(){return mt(this.r,this.g,this.b)},Za.toString=function(){return"#"+vt(this.r)+vt(this.g)+vt(this.b)};var Va=Xo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Va.forEach(function(n,t){Va.set(n,ft(t))}),Xo.functor=_t,Xo.xhr=wt(bt),Xo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=St(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++<s;)if(34===n.charCodeAt(e)){if(34!==n.charCodeAt(e+1))break;++e}l=e+2;var r=n.charCodeAt(e+1);return 13===r?(u=!0,10===n.charCodeAt(e+2)&&++l):10===r&&(u=!0),n.substring(t+1,e).replace(/""/g,'"')}for(;s>l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new l,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Xo.csv=Xo.dsv(",","text/csv"),Xo.tsv=Xo.dsv("	","text/tab-separated-values");var Xa,$a,Ba,Wa,Ja,Ga=Go[h(Go,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Xo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};$a?$a.n=i:Xa=i,$a=i,Ba||(Wa=clearTimeout(Wa),Ba=1,Ga(Et))},Xo.timer.flush=function(){At(),Ct()},Xo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ka=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Xo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Xo.round(n,Nt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((0>=e?e+1:e-1)/3)))),Ka[8+e/3]};var Qa=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,nc=Xo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Xo.round(n,Nt(n,t))).toFixed(Math.max(0,Math.min(20,Nt(n*(1+1e-15),t))))}}),tc=Xo.time={},ec=Date;zt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){rc.setUTCDate.apply(this._,arguments)},setDay:function(){rc.setUTCDay.apply(this._,arguments)},setFullYear:function(){rc.setUTCFullYear.apply(this._,arguments)},setHours:function(){rc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){rc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){rc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){rc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){rc.setUTCSeconds.apply(this._,arguments)},setTime:function(){rc.setTime.apply(this._,arguments)}};var rc=Date.prototype;tc.year=Rt(function(n){return n=tc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),tc.years=tc.year.range,tc.years.utc=tc.year.utc.range,tc.day=Rt(function(n){var t=new ec(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),tc.days=tc.day.range,tc.days.utc=tc.day.utc.range,tc.dayOfYear=function(n){var t=tc.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=tc[n]=Rt(function(n){return(n=tc.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});tc[n+"s"]=e.range,tc[n+"s"].utc=e.utc.range,tc[n+"OfYear"]=function(n){var e=tc.year(n).getDay();return Math.floor((tc.dayOfYear(n)+(e+t)%7)/7)}}),tc.week=tc.sunday,tc.weeks=tc.sunday.range,tc.weeks.utc=tc.sunday.utc.range,tc.weekOfYear=tc.sundayOfYear;var uc={"-":"",_:" ",0:"0"},ic=/^\s*\d+/,oc=/^%/;Xo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Pt(n)}};var ac=Xo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Xo.format=ac.numberFormat,Xo.geo={},re.prototype={s:0,t:0,add:function(n){ue(n,this.t,cc),ue(cc.s,this.s,this),this.s?this.t+=cc.t:this.s=cc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var cc=new re;Xo.geo.stream=function(n,t){n&&sc.hasOwnProperty(n.type)?sc[n.type](n,t):ie(n,t)};var sc={Feature:function(n,t){ie(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++r<u;)ie(e[r].geometry,t)}},lc={Sphere:function(n,t){t.sphere()},Point:function(n,t){n=n.coordinates,t.point(n[0],n[1],n[2])},MultiPoint:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)n=e[r],t.point(n[0],n[1],n[2])},LineString:function(n,t){oe(n.coordinates,t,0)},MultiLineString:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)oe(e[r],t,0)},Polygon:function(n,t){ae(n.coordinates,t)},MultiPolygon:function(n,t){for(var e=n.coordinates,r=-1,u=e.length;++r<u;)ae(e[r],t)},GeometryCollection:function(n,t){for(var e=n.geometries,r=-1,u=e.length;++r<u;)ie(e[r],t)}};Xo.geo.area=function(n){return fc=0,Xo.geo.stream(n,gc),fc};var fc,hc=new re,gc={sphere:function(){fc+=4*Sa},point:g,lineStart:g,lineEnd:g,polygonStart:function(){hc.reset(),gc.lineStart=ce},polygonEnd:function(){var n=2*hc;fc+=0>n?4*Sa+n:n,gc.lineStart=gc.lineEnd=gc.point=g}};Xo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=se([t*Na,e*Na]);if(m){var u=fe(m,r),i=[u[1],-u[0],0],o=fe(i,u);pe(o),o=ve(o);var c=t-p,s=c>0?1:-1,v=o[0]*La*s,d=oa(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*La;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*La;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=oa(r)>180?r+(r>0?360:-360):r}else v=n,d=e;gc.point(n,e),t(n,e)}function i(){gc.lineStart()}function o(){u(v,d),gc.lineEnd(),oa(y)>Aa&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n<t[0]||t[1]<n}var l,f,h,g,p,v,d,m,y,x,M,_={point:n,lineStart:e,lineEnd:r,polygonStart:function(){_.point=u,_.lineStart=i,_.lineEnd=o,y=0,gc.polygonStart()},polygonEnd:function(){gc.polygonEnd(),_.point=n,_.lineStart=e,_.lineEnd=r,0>hc?(l=-(h=180),f=-(g=90)):y>Aa?g=90:-Aa>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Xo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e);for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Xo.geo.centroid=function(n){pc=vc=dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,kc);var t=bc,e=wc,r=Sc,u=t*t+e*e+r*r;return Ca>u&&(t=xc,e=Mc,r=_c,Aa>vc&&(t=dc,e=mc,r=yc),u=t*t+e*e+r*r,Ca>u)?[0/0,0/0]:[Math.atan2(e,t)*La,X(r/Math.sqrt(u))*La]};var pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc,Sc,kc={sphere:g,point:me,lineStart:xe,lineEnd:Me,polygonStart:function(){kc.lineStart=_e},polygonEnd:function(){kc.lineStart=xe}},Ec=Ee(be,Te,ze,[-Sa,-Sa/2]),Ac=1e9;Xo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Pe(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Xo.geo.conicEqualArea=function(){return je(He)}).raw=He,Xo.geo.albers=function(){return Xo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Xo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Xo.geo.albers(),o=Xo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Xo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+Aa,f+.12*s+Aa],[l-.214*s-Aa,f+.234*s-Aa]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+Aa,f+.166*s+Aa],[l-.115*s-Aa,f+.234*s-Aa]]).stream(c).point,n},n.scale(1070)};var Cc,Nc,Lc,Tc,qc,zc,Rc={point:g,lineStart:g,lineEnd:g,polygonStart:function(){Nc=0,Rc.lineStart=Fe},polygonEnd:function(){Rc.lineStart=Rc.lineEnd=Rc.point=g,Cc+=oa(Nc/2)}},Dc={point:Oe,lineStart:g,lineEnd:g,polygonStart:g,polygonEnd:g},Pc={point:Ze,lineStart:Ve,lineEnd:Xe,polygonStart:function(){Pc.lineStart=$e},polygonEnd:function(){Pc.point=Ze,Pc.lineStart=Ve,Pc.lineEnd=Xe}};Xo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Xo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Cc=0,Xo.geo.stream(n,u(Rc)),Cc},n.centroid=function(n){return dc=mc=yc=xc=Mc=_c=bc=wc=Sc=0,Xo.geo.stream(n,u(Pc)),Sc?[bc/Sc,wc/Sc]:_c?[xc/_c,Mc/_c]:yc?[dc/yc,mc/yc]:[0/0,0/0]},n.bounds=function(n){return qc=zc=-(Lc=Tc=1/0),Xo.geo.stream(n,u(Dc)),[[Lc,Tc],[qc,zc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Je(n):bt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ye:new Be(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Xo.geo.albersUsa()).context(null)},Xo.geo.transform=function(n){return{stream:function(t){var e=new Ge(t);for(var r in n)e[r]=n[r];return e}}},Ge.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Xo.geo.projection=Qe,Xo.geo.projectionMutator=nr,(Xo.geo.equirectangular=function(){return Qe(er)}).raw=er.invert=er,Xo.geo.rotation=function(n){function t(t){return t=n(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t}return n=ur(n[0]%360*Na,n[1]*Na,n.length>2?n[2]*Na:0),t.invert=function(t){return t=n.invert(t[0]*Na,t[1]*Na),t[0]*=La,t[1]*=La,t},t},rr.invert=er,Xo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ur(-n[0]*Na,-n[1]*Na,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=La,n[1]*=La}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=cr((t=+r)*Na,u*Na),n):t},n.precision=function(r){return arguments.length?(e=cr(t*Na,(u=+r)*Na),n):u},n.angle(90)},Xo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Na,u=n[1]*Na,i=t[1]*Na,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Xo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Xo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Xo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Xo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return oa(n%d)>Aa}).map(l)).concat(Xo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return oa(n%m)>Aa}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=lr(a,o,90),f=fr(r,e,y),h=lr(s,c,90),g=fr(i,u,y),n):y},n.majorExtent([[-180,-90+Aa],[180,90-Aa]]).minorExtent([[-180,-80-Aa],[180,80+Aa]])},Xo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=hr,u=gr;return n.distance=function(){return Xo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Xo.geo.interpolate=function(n,t){return pr(n[0]*Na,n[1]*Na,t[0]*Na,t[1]*Na)},Xo.geo.length=function(n){return Uc=0,Xo.geo.stream(n,jc),Uc};var Uc,jc={sphere:g,point:g,lineStart:vr,lineEnd:g,polygonStart:g,polygonEnd:g},Hc=dr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Xo.geo.azimuthalEqualArea=function(){return Qe(Hc)}).raw=Hc;var Fc=dr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},bt);(Xo.geo.azimuthalEquidistant=function(){return Qe(Fc)}).raw=Fc,(Xo.geo.conicConformal=function(){return je(mr)}).raw=mr,(Xo.geo.conicEquidistant=function(){return je(yr)}).raw=yr;var Oc=dr(function(n){return 1/n},Math.atan);(Xo.geo.gnomonic=function(){return Qe(Oc)}).raw=Oc,xr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Ea]},(Xo.geo.mercator=function(){return Mr(xr)}).raw=xr;var Yc=dr(function(){return 1},Math.asin);(Xo.geo.orthographic=function(){return Qe(Yc)}).raw=Yc;var Ic=dr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Xo.geo.stereographic=function(){return Qe(Ic)}).raw=Ic,_r.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Ea]},(Xo.geo.transverseMercator=function(){var n=Mr(_r),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[-n[1],n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},n.rotate([0,0])}).raw=_r,Xo.geom={},Xo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=_t(e),i=_t(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(kr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=Sr(a),l=Sr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t<l.length-h;++t)g.push(n[a[l[t]][2]]);return g}var e=br,r=wr;return arguments.length?t(n):(t.x=function(n){return arguments.length?(e=n,t):e},t.y=function(n){return arguments.length?(r=n,t):r},t)},Xo.geom.polygon=function(n){return fa(n,Zc),n};var Zc=Xo.geom.polygon.prototype=[];Zc.area=function(){for(var n,t=-1,e=this.length,r=this[e-1],u=0;++t<e;)n=r,r=this[t],u+=n[1]*r[0]-n[0]*r[1];return.5*u},Zc.centroid=function(n){var t,e,r=-1,u=this.length,i=0,o=0,a=this[u-1];for(arguments.length||(n=-1/(6*this.area()));++r<u;)t=a,a=this[r],e=t[0]*a[1]-a[0]*t[1],i+=(t[0]+a[0])*e,o+=(t[1]+a[1])*e;return[i*n,o*n]},Zc.clip=function(n){for(var t,e,r,u,i,o,a=Cr(n),c=-1,s=this.length-Cr(this),l=this[s-1];++c<s;){for(t=n.slice(),n.length=0,u=this[c],i=t[(r=t.length-a)-1],e=-1;++e<r;)o=t[e],Er(o,l,u)?(Er(i,l,u)||n.push(Ar(i,o,l,u)),n.push(o)):Er(i,l,u)&&n.push(Ar(i,o,l,u)),i=o;a&&n.push(n[0]),l=u}return n};var Vc,Xc,$c,Bc,Wc,Jc=[],Gc=[];Pr.prototype.prepare=function(){for(var n,t=this.edges,e=t.length;e--;)n=t[e].edge,n.b&&n.a||t.splice(e,1);return t.sort(jr),t.length},Br.prototype={start:function(){return this.edge.l===this.site?this.edge.a:this.edge.b},end:function(){return this.edge.l===this.site?this.edge.b:this.edge.a}},Wr.prototype={insert:function(n,t){var e,r,u;if(n){if(t.P=n,t.N=n.N,n.N&&(n.N.P=t),n.N=t,n.R){for(n=n.R;n.L;)n=n.L;n.L=t}else n.R=t;e=n}else this._?(n=Qr(this._),t.P=null,t.N=n,n.P=n.L=t,e=n):(t.P=t.N=null,this._=t,e=null);for(t.L=t.R=null,t.U=e,t.C=!0,n=t;e&&e.C;)r=e.U,e===r.L?(u=r.R,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.R&&(Gr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Kr(this,r))):(u=r.L,u&&u.C?(e.C=u.C=!1,r.C=!0,n=r):(n===e.L&&(Kr(this,e),n=e,e=n.U),e.C=!1,r.C=!0,Gr(this,r))),e=n.U;this._.C=!1},remove:function(n){n.N&&(n.N.P=n.P),n.P&&(n.P.N=n.N),n.N=n.P=null;var t,e,r,u=n.U,i=n.L,o=n.R;if(e=i?o?Qr(o):i:o,u?u.L===n?u.L=e:u.R=e:this._=e,i&&o?(r=e.C,e.C=n.C,e.L=i,i.U=e,e!==o?(u=e.U,e.U=n.U,n=e.R,u.L=n,e.R=o,o.U=e):(e.U=u,u=e,n=e.R)):(r=n.C,n=e),n&&(n.U=u),!r){if(n&&n.C)return n.C=!1,void 0;do{if(n===this._)break;if(n===u.L){if(t=u.R,t.C&&(t.C=!1,u.C=!0,Gr(this,u),t=u.R),t.L&&t.L.C||t.R&&t.R.C){t.R&&t.R.C||(t.L.C=!1,t.C=!0,Kr(this,t),t=u.R),t.C=u.C,u.C=t.R.C=!1,Gr(this,u),n=this._;break}}else if(t=u.L,t.C&&(t.C=!1,u.C=!0,Kr(this,u),t=u.L),t.L&&t.L.C||t.R&&t.R.C){t.L&&t.L.C||(t.R.C=!1,t.C=!0,Gr(this,t),t=u.L),t.C=u.C,u.C=t.L.C=!1,Kr(this,u),n=this._;break}t.C=!0,n=u,u=u.U}while(!n.C);n&&(n.C=!1)}}},Xo.geom.voronoi=function(n){function t(n){var t=new Array(n.length),r=a[0][0],u=a[0][1],i=a[1][0],o=a[1][1];return nu(e(n),a).cells.forEach(function(e,a){var c=e.edges,s=e.site,l=t[a]=c.length?c.map(function(n){var t=n.start();return[t.x,t.y]}):s.x>=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Aa)*Aa,y:Math.round(o(n,t)/Aa)*Aa,i:t}})}var r=br,u=wr,i=r,o=u,a=Kc;return n?t(n):(t.links=function(n){return nu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return nu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(jr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c<s;)u=l,i=f,l=a[c].edge,f=l.l===o?l.r:l.l,r<i.i&&r<f.i&&eu(o,i,f)<0&&t.push([n[r],n[i.i],n[f.i]])}),t},t.x=function(n){return arguments.length?(i=_t(r=n),t):r},t.y=function(n){return arguments.length?(o=_t(u=n),t):u},t.clipExtent=function(n){return arguments.length?(a=null==n?Kc:n,t):a===Kc?null:a},t.size=function(n){return arguments.length?t.clipExtent(n&&[[0,0],n]):a===Kc?null:a&&a[1]},t)};var Kc=[[-1e6,-1e6],[1e6,1e6]];Xo.geom.delaunay=function(n){return Xo.geom.voronoi().triangles(n)},Xo.geom.quadtree=function(n,t,e,r,u){function i(n){function i(n,t,e,r,u,i,o,a){if(!isNaN(e)&&!isNaN(r))if(n.leaf){var c=n.x,l=n.y;if(null!=c)if(oa(c-e)+oa(l-r)<.01)s(n,t,e,r,u,i,o,a);else{var f=n.point;n.x=n.y=n.point=null,s(n,f,c,l,u,i,o,a),s(n,t,e,r,u,i,o,a)}else n.x=e,n.y=r,n.point=t}else s(n,t,e,r,u,i,o,a)}function s(n,t,e,r,u,o,a,c){var s=.5*(u+a),l=.5*(o+c),f=e>=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=iu()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=_t(a),M=_t(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.x<v&&(v=l.x),l.y<d&&(d=l.y),l.x>m&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=iu();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){ou(n,k,v,d,m,y)},g=-1,null==t){for(;++g<p;)i(k,n[g],f[g],h[g],v,d,m,y);--g}else n.forEach(k.add);return f=h=n=l=null,k}var o,a=br,c=wr;return(o=arguments.length)?(a=ru,c=uu,3===o&&(u=e,r=t,e=t=0),i(n)):(i.x=function(n){return arguments.length?(a=n,i):a},i.y=function(n){return arguments.length?(c=n,i):c},i.extent=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=+n[0][0],e=+n[0][1],r=+n[1][0],u=+n[1][1]),i):null==t?null:[[t,e],[r,u]]},i.size=function(n){return arguments.length?(null==n?t=e=r=u=null:(t=e=0,r=+n[0],u=+n[1]),i):null==t?null:[r-t,u-e]},i)},Xo.interpolateRgb=au,Xo.interpolateObject=cu,Xo.interpolateNumber=su,Xo.interpolateString=lu;var Qc=/[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g;Xo.interpolate=fu,Xo.interpolators=[function(n,t){var e=typeof t;return("string"===e?Va.has(t)||/^(#|rgb\(|hsl\()/.test(t)?au:lu:t instanceof G?au:"object"===e?Array.isArray(t)?hu:cu:su)(n,t)}],Xo.interpolateArray=hu;var ns=function(){return bt},ts=Xo.map({linear:ns,poly:xu,quad:function(){return du},cubic:function(){return mu},sin:function(){return Mu},exp:function(){return _u},circle:function(){return bu},elastic:wu,back:Su,bounce:function(){return ku}}),es=Xo.map({"in":bt,out:pu,"in-out":vu,"out-in":function(n){return vu(pu(n))}});Xo.ease=function(n){var t=n.indexOf("-"),e=t>=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ts.get(e)||ns,r=es.get(r)||bt,gu(r(e.apply(null,$o.call(arguments,1))))},Xo.interpolateHcl=Eu,Xo.interpolateHsl=Au,Xo.interpolateLab=Cu,Xo.interpolateRound=Nu,Xo.transform=function(n){var t=Wo.createElementNS(Xo.ns.prefix.svg,"g");return(Xo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:rs)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var rs={a:1,b:0,c:0,d:1,e:0,f:0};Xo.interpolateTransform=Ru,Xo.layout={},Xo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++e<r;)t.push(Uu(n[e]));return t}},Xo.layout.chord=function(){function n(){var n,s,f,h,g,p={},v=[],d=Xo.range(i),m=[];for(e=[],r=[],n=0,h=-1;++h<i;){for(s=0,g=-1;++g<i;)s+=u[h][g];v.push(s),m.push(Xo.range(i)),n+=s}for(o&&d.sort(function(n,t){return o(v[n],v[t])}),a&&m.forEach(function(n,t){n.sort(function(n,e){return a(u[t][n],u[t][e])})}),n=(ka-l*i)/n,s=0,h=-1;++h<i;){for(f=s,g=-1;++g<i;){var y=d[h],x=m[y][g],M=u[y][x],_=s,b=s+=M*n;p[y+"-"+x]={index:y,subindex:x,startAngle:_,endAngle:b,value:M}}r[y]={index:y,startAngle:f,endAngle:s,value:(s-f)/n},s+=l}for(h=-1;++h<i;)for(g=h-1;++g<i;){var w=p[h+"-"+g],S=p[g+"-"+h];(w.value||S.value)&&e.push(w.value<S.value?{source:S,target:w}:{source:w,target:S})}c&&t()}function t(){e.sort(function(n,t){return c((n.source.value+n.target.value)/2,(t.source.value+t.target.value)/2)})}var e,r,u,i,o,a,c,s={},l=0;return s.matrix=function(n){return arguments.length?(i=(u=n)&&u.length,e=r=null,s):u},s.padding=function(n){return arguments.length?(l=n,e=r=null,s):l},s.sortGroups=function(n){return arguments.length?(o=n,e=r=null,s):o},s.sortSubgroups=function(n){return arguments.length?(a=n,e=null,s):a},s.sortChords=function(n){return arguments.length?(c=n,e&&t(),s):c},s.chords=function(){return e||n(),e},s.groups=function(){return r||n(),r},s},Xo.layout.force=function(){function n(n){return function(t,e,r,u){if(t.point!==n){var i=t.cx-n.x,o=t.cy-n.y,a=u-e,c=i*i+o*o;if(c>a*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Xo.event.x,n.py=Xo.event.y,a.resume()}var e,r,u,i,o,a={},c=Xo.dispatch("start","tick","end"),s=[1,1],l=.9,f=us,h=is,g=-30,p=os,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Zu(t=Xo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Xo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++a<s;)if(!isNaN(i=o[a][n]))return i;return Math.random()*r}var t,e,r,c=m.length,l=y.length,p=s[0],v=s[1];for(t=0;c>t;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Xo.behavior.drag().origin(bt).on("dragstart.force",Fu).on("drag.force",t).on("dragend.force",Ou)),arguments.length?(this.on("mouseover.force",Yu).on("mouseout.force",Iu).call(e),void 0):e},Xo.rebind(a,c,"on")};var us=20,is=1,os=1/0;Xo.layout.hierarchy=function(){function n(t,o,a){var c=u.call(e,t,o);if(t.depth=o,a.push(t),c&&(s=c.length)){for(var s,l,f=-1,h=t.children=new Array(s),g=0,p=o+1;++f<s;)l=h[f]=n(c[f],p,a),l.parent=t,g+=l.value;r&&h.sort(r),i&&(t.value=g)}else delete t.children,i&&(t.value=+i.call(e,t,o)||0);return t}function t(n,r){var u=n.children,o=0;if(u&&(a=u.length))for(var a,c=-1,s=r+1;++c<a;)o+=t(u[c],s);else i&&(o=+i.call(e,n,r)||0);return i&&(n.value=o),o}function e(t){var e=[];return n(t,0,e),e}var r=Bu,u=Xu,i=$u;return e.sort=function(n){return arguments.length?(r=n,e):r},e.children=function(n){return arguments.length?(u=n,e):u},e.value=function(n){return arguments.length?(i=n,e):i},e.revalue=function(n){return t(n,0),n},e},Xo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++s<o;)n(a=i[s],e,c=a.value*r,u),e+=c}}function t(n){var e=n.children,r=0;if(e&&(u=e.length))for(var u,i=-1;++i<u;)r=Math.max(r,t(e[i]));return 1+r}function e(e,i){var o=r.call(this,e,i);return n(o[0],0,u[0],u[1]/t(o[0])),o}var r=Xo.layout.hierarchy(),u=[1,1];return e.size=function(n){return arguments.length?(u=n,e):u},Vu(e,r)},Xo.layout.pie=function(){function n(i){var o=i.map(function(e,r){return+t.call(n,e,r)}),a=+("function"==typeof r?r.apply(this,arguments):r),c=(("function"==typeof u?u.apply(this,arguments):u)-a)/Xo.sum(o),s=Xo.range(i.length);null!=e&&s.sort(e===as?function(n,t){return o[t]-o[n]}:function(n,t){return e(i[n],i[t])});var l=[];return s.forEach(function(n){var t;l[n]={data:i[n],value:t=o[n],startAngle:a,endAngle:a+=t*c}}),l}var t=Number,e=as,r=0,u=ka;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n};var as={};Xo.layout.stack=function(){function n(a,c){var s=a.map(function(e,r){return t.call(n,e,r)}),l=s.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,l,c);s=Xo.permute(s,f),l=Xo.permute(l,f);var h,g,p,v=r.call(n,l,c),d=s.length,m=s[0].length;for(g=0;m>g;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=bt,e=Qu,r=ni,u=Ku,i=Ju,o=Gu;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:cs.get(t)||Qu,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:ss.get(t)||ni,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var cs=Xo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ti),i=n.map(ei),o=Xo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Xo.range(n.length).reverse()},"default":Qu}),ss=Xo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ni});Xo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i<g;)o=c[i]=[],o.dx=f[i+1]-(o.x=f[i]),o.y=0;if(g>0)for(i=-1;++i<h;)a=s[i],a>=l[0]&&a<=l[1]&&(o=c[Xo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=oi,u=ui;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=_t(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ii(n,t)}:_t(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Xo.layout.tree=function(){function n(n,i){function o(n,t){var r=n.children,u=n._tree;if(r&&(i=r.length)){for(var i,a,s,l=r[0],f=l,h=-1;++h<i;)s=r[h],o(s,a),f=c(s,a,f),a=s;vi(n);var g=.5*(l._tree.prelim+s._tree.prelim);t?(u.prelim=t._tree.prelim+e(n,t),u.mod=u.prelim-g):u.prelim=g}else t&&(u.prelim=t._tree.prelim+e(n,t))}function a(n,t){n.x=n._tree.prelim+t;var e=n.children;if(e&&(r=e.length)){var r,u=-1;for(t+=n._tree.mod;++u<r;)a(e[u],t)}}function c(n,t,r){if(t){for(var u,i=n,o=n,a=t,c=n.parent.children[0],s=i._tree.mod,l=o._tree.mod,f=a._tree.mod,h=c._tree.mod;a=si(a),i=ci(i),a&&i;)c=ci(c),o=si(o),o._tree.ancestor=n,u=a._tree.prelim+f-i._tree.prelim-s+e(a,i),u>0&&(di(mi(a,n,r),n,u),s+=u,l+=u),f+=a._tree.mod,s+=i._tree.mod,h+=c._tree.mod,l+=o._tree.mod;a&&!si(o)&&(o._tree.thread=a,o._tree.mod+=f-l),i&&!ci(c)&&(c._tree.thread=i,c._tree.mod+=s-h,r=n)}return r}var s=t.call(this,n,i),l=s[0];pi(l,function(n,t){n._tree={ancestor:n,prelim:0,mod:0,change:0,shift:0,number:t?t._tree.number+1:0}}),o(l),a(l,-l._tree.prelim);var f=li(l,hi),h=li(l,fi),g=li(l,gi),p=f.x-e(f,h)/2,v=h.x+e(h,f)/2,d=g.depth||1;return pi(l,u?function(n){n.x*=r[0],n.y=n.depth*r[1],delete n._tree}:function(n){n.x=(n.x-p)/(v-p)*r[0],n.y=n.depth/d*r[1],delete n._tree}),s}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,pi(a,function(n){n.r=+l(n.value)}),pi(a,bi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;pi(a,function(n){n.r+=f}),pi(a,bi),pi(a,function(n){n.r-=f})}return ki(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Xo.layout.hierarchy().sort(yi),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Vu(n,e)},Xo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;pi(c,function(n){var t=n.children;t&&t.length?(n.x=Ci(t),n.y=Ai(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ni(c),f=Li(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return pi(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Xo.layout.hierarchy().sort(null).value(null),e=ai,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Vu(n,t)},Xo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++u<i;)r=(e=n[u]).value*(0>t?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++o<a;)(e=n[o].area)&&(i>e&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++i<o;)u=n[i],u.x=a,u.y=s,u.dy=l,a+=u.dx=Math.min(e.x+e.dx-a,l?c(u.area/l):0);u.z=!0,u.dx+=e.x+e.dx-a,e.y+=l,e.dy-=l}else{for((r||l>e.dx)&&(l=e.dx);++i<o;)u=n[i],u.x=a,u.y=s,u.dx=l,s+=u.dy=Math.min(e.y+e.dy-s,l?c(u.area/l):0);u.z=!1,u.dy+=e.y+e.dy-s,e.x+=l,e.dx-=l}}function i(r){var u=o||a(r),i=u[0];return i.x=0,i.y=0,i.dx=s[0],i.dy=s[1],o&&a.revalue(i),n([i],i.dx*i.dy/i.value),(o?e:t)(i),h&&(o=u),u}var o,a=Xo.layout.hierarchy(),c=Math.round,s=[1,1],l=null,f=Ti,h=!1,g="squarify",p=.5*(1+Math.sqrt(5));return i.size=function(n){return arguments.length?(s=n,i):s},i.padding=function(n){function t(t){var e=n.call(i,t,t.depth);return null==e?Ti(t):qi(t,"number"==typeof e?[e,e,e,e]:e)}function e(t){return qi(t,n)}if(!arguments.length)return l;var r;return f=null==(l=n)?Ti:"function"==(r=typeof n)?t:"number"===r?(n=[n,n,n,n],e):e,i},i.round=function(n){return arguments.length?(c=n?Math.round:Number,i):c!=Number},i.sticky=function(n){return arguments.length?(h=n,o=null,i):h},i.ratio=function(n){return arguments.length?(p=n,i):p},i.mode=function(n){return arguments.length?(g=n+"",i):g},Vu(i,a)},Xo.random={normal:function(n,t){var e=arguments.length;return 2>e&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Xo.random.normal.apply(Xo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Xo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Xo.scale={};var ls={floor:bt,ceil:bt};Xo.scale.linear=function(){return Hi([0,1],[0,1],fu,!1)};var fs={s:1,g:1,p:1,r:1,e:1};Xo.scale.log=function(){return $i(Xo.scale.linear().domain([0,1]),10,!0,[1,10])};var hs=Xo.format(".0e"),gs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Xo.scale.pow=function(){return Bi(Xo.scale.linear(),1,[0,1])},Xo.scale.sqrt=function(){return Xo.scale.pow().exponent(.5)},Xo.scale.ordinal=function(){return Ji([],{t:"range",a:[[]]})},Xo.scale.category10=function(){return Xo.scale.ordinal().range(ps)},Xo.scale.category20=function(){return Xo.scale.ordinal().range(vs)},Xo.scale.category20b=function(){return Xo.scale.ordinal().range(ds)},Xo.scale.category20c=function(){return Xo.scale.ordinal().range(ms)};var ps=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(ht),vs=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(ht),ds=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(ht),ms=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(ht);Xo.scale.quantile=function(){return Gi([],[])},Xo.scale.quantize=function(){return Ki(0,1,[0,1])},Xo.scale.threshold=function(){return Qi([.5],[0,1])},Xo.scale.identity=function(){return no([0,1])},Xo.svg={},Xo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ys,a=u.apply(this,arguments)+ys,c=(o>a&&(c=o,o=a,a=c),a-o),s=Sa>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a);return c>=xs?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=to,e=eo,r=ro,u=uo;return n.innerRadius=function(e){return arguments.length?(t=_t(e),n):t},n.outerRadius=function(t){return arguments.length?(e=_t(t),n):e},n.startAngle=function(t){return arguments.length?(r=_t(t),n):r},n.endAngle=function(t){return arguments.length?(u=_t(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ys;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ys=-Ea,xs=ka-Aa;Xo.svg.line=function(){return io(bt)};var Ms=Xo.map({linear:oo,"linear-closed":ao,step:co,"step-before":so,"step-after":lo,basis:mo,"basis-open":yo,"basis-closed":xo,bundle:Mo,cardinal:go,"cardinal-open":fo,"cardinal-closed":ho,monotone:Eo});Ms.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var _s=[0,2/3,1/3,0],bs=[0,1/3,2/3,0],ws=[0,1/6,2/3,1/6];Xo.svg.line.radial=function(){var n=io(Ao);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},so.reverse=lo,lo.reverse=so,Xo.svg.area=function(){return Co(bt)},Xo.svg.area.radial=function(){var n=Co(Ao);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Xo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ys,l=s.call(n,u,r)+ys;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Sa)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=hr,o=gr,a=No,c=ro,s=uo;return n.radius=function(t){return arguments.length?(a=_t(t),n):a},n.source=function(t){return arguments.length?(i=_t(t),n):i},n.target=function(t){return arguments.length?(o=_t(t),n):o},n.startAngle=function(t){return arguments.length?(c=_t(t),n):c},n.endAngle=function(t){return arguments.length?(s=_t(t),n):s},n},Xo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=hr,e=gr,r=Lo;return n.source=function(e){return arguments.length?(t=_t(e),n):t},n.target=function(t){return arguments.length?(e=_t(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Xo.svg.diagonal.radial=function(){var n=Xo.svg.diagonal(),t=Lo,e=n.projection;return n.projection=function(n){return arguments.length?e(To(t=n)):t},n},Xo.svg.symbol=function(){function n(n,r){return(Ss.get(t.call(this,n,r))||Ro)(e.call(this,n,r))}var t=zo,e=qo;return n.type=function(e){return arguments.length?(t=_t(e),n):t},n.size=function(t){return arguments.length?(e=_t(t),n):e},n};var Ss=Xo.map({circle:Ro,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*Cs)),e=t*Cs;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/As),e=t*As/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Xo.svg.symbolTypes=Ss.keys();var ks,Es,As=Math.sqrt(3),Cs=Math.tan(30*Na),Ns=[],Ls=0;Ns.call=da.call,Ns.empty=da.empty,Ns.node=da.node,Ns.size=da.size,Xo.transition=function(n){return arguments.length?ks?n.transition():n:xa.transition()},Xo.transition.prototype=Ns,Ns.select=function(n){var t,e,r,u=this.id,i=[];n=M(n);for(var o=-1,a=this.length;++o<a;){i.push(t=[]);for(var c=this[o],s=-1,l=c.length;++s<l;)(r=c[s])&&(e=n.call(r,r.__data__,s,o))?("__data__"in r&&(e.__data__=r.__data__),jo(e,s,u,r.__transition__[u]),t.push(e)):t.push(null)}return Do(i,u)},Ns.selectAll=function(n){var t,e,r,u,i,o=this.id,a=[];n=_(n);for(var c=-1,s=this.length;++c<s;)for(var l=this[c],f=-1,h=l.length;++f<h;)if(r=l[f]){i=r.__transition__[o],e=n.call(r,r.__data__,f,c),a.push(t=[]);for(var g=-1,p=e.length;++g<p;)(u=e[g])&&jo(u,g,o,i),t.push(u)}return Do(a,o)},Ns.filter=function(n){var t,e,r,u=[];"function"!=typeof n&&(n=q(n));for(var i=0,o=this.length;o>i;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return Do(u,this.id)},Ns.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):R(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Ns.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Ru:fu,a=Xo.ns.qualify(n);return Po(this,"attr."+n,t,a.local?i:u)},Ns.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Xo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Ns.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Go.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=fu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Po(this,"style."+n,t,u)},Ns.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Go.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Ns.text=function(n){return Po(this,"text",n,Uo)},Ns.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Ns.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Xo.ease.apply(Xo,arguments)),R(this,function(e){e.__transition__[t].ease=n}))},Ns.delay=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Ns.duration=function(n){var t=this.id;return R(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Ns.each=function(n,t){var e=this.id;if(arguments.length<2){var r=Es,u=ks;ks=e,R(this,function(t,r,u){Es=t.__transition__[e],n.call(t,t.__data__,r,u)}),Es=r,ks=u}else R(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Xo.dispatch("start","end"))).on(n,t)});return this},Ns.transition=function(){for(var n,t,e,r,u=this.id,i=++Ls,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,jo(e,s,i,r)),n.push(e)}return Do(o,i)},Xo.svg.axis=function(){function n(n){n.each(function(){var n,s=Xo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):bt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Aa),d=Xo.transition(p.exit()).style("opacity",Aa).remove(),m=Xo.transition(p).style("opacity",1),y=Ri(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Xo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Ho,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Ho,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=Fo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=Fo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Xo.scale.linear(),r=Ts,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in qs?t+"":Ts,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var Ts="bottom",qs={top:1,right:1,bottom:1,left:1};Xo.svg.brush=function(){function n(i){i.each(function(){var i=Xo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,bt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return zs[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Xo.transition(i),h=Xo.transition(o);c&&(l=Ri(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ri(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Xo.event.keyCode&&(C||(x=null,L[0]-=l[1],L[1]-=f[1],C=2),d())}function p(){32==Xo.event.keyCode&&2==C&&(L[0]+=l[1],L[1]+=f[1],C=0,d())}function v(){var n=Xo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Xo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),L[0]=l[+(n[0]<x[0])],L[1]=f[+(n[1]<x[1])]):x=null),E&&m(n,c,0)&&(e(S),u=!0),A&&m(n,s,1)&&(r(S),u=!0),u&&(t(S),w({type:"brush",mode:C?"move":"resize"}))}function m(n,t,e){var r,u,a=Ri(t),c=a[0],s=a[1],p=L[e],v=e?f:l,d=v[1]-v[0];return C&&(c-=p,s-=d+p),r=(e?g:h)?Math.max(c,Math.min(s,n[e])):n[e],C?u=(r+=p)+d:(x&&(p=Math.max(c,Math.min(s,2*x[e]-r))),r>p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function y(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Xo.select("body").style("cursor",null),T.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Xo.select(Xo.event.target),w=a.of(_,arguments),S=Xo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=O(),L=Xo.mouse(_),T=Xo.select(Go).on("keydown.brush",u).on("keyup.brush",p);if(Xo.event.changedTouches?T.on("touchmove.brush",v).on("touchend.brush",y):T.on("mousemove.brush",v).on("mouseup.brush",y),S.interrupt().selectAll("*").interrupt(),C)L[0]=l[0]-L[0],L[1]=f[0]-L[1];else if(k){var q=+/w$/.test(k),z=+/^n/.test(k);M=[l[1-q]-L[0],f[1-z]-L[1]],L[0]=l[q],L[1]=f[z]}else Xo.event.altKey&&(x=L.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Xo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=y(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=Rs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,ks?Xo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=hu(l,t.x),r=hu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=Rs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=Rs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Xo.rebind(n,a,"on")};var zs={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Rs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Ds=tc.format=ac.timeFormat,Ps=Ds.utc,Us=Ps("%Y-%m-%dT%H:%M:%S.%LZ");Ds.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Oo:Us,Oo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Oo.toString=Us.toString,tc.second=Rt(function(n){return new ec(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),tc.seconds=tc.second.range,tc.seconds.utc=tc.second.utc.range,tc.minute=Rt(function(n){return new ec(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),tc.minutes=tc.minute.range,tc.minutes.utc=tc.minute.utc.range,tc.hour=Rt(function(n){var t=n.getTimezoneOffset()/60;return new ec(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),tc.hours=tc.hour.range,tc.hours.utc=tc.hour.utc.range,tc.month=Rt(function(n){return n=tc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),tc.months=tc.month.range,tc.months.utc=tc.month.utc.range;var js=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Hs=[[tc.second,1],[tc.second,5],[tc.second,15],[tc.second,30],[tc.minute,1],[tc.minute,5],[tc.minute,15],[tc.minute,30],[tc.hour,1],[tc.hour,3],[tc.hour,6],[tc.hour,12],[tc.day,1],[tc.day,2],[tc.week,1],[tc.month,1],[tc.month,3],[tc.year,1]],Fs=Ds.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",be]]),Os={range:function(n,t,e){return Xo.range(Math.ceil(n/e)*e,+t,e).map(Io)},floor:bt,ceil:bt};Hs.year=tc.year,tc.scale=function(){return Yo(Xo.scale.linear(),Hs,Fs)};var Ys=Hs.map(function(n){return[n[0].utc,n[1]]}),Is=Ps.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",be]]);Ys.year=tc.year.utc,tc.scale.utc=function(){return Yo(Xo.scale.linear(),Ys,Is)},Xo.text=wt(function(n){return n.responseText}),Xo.json=function(n,t){return St(n,"application/json",Zo,t)},Xo.html=function(n,t){return St(n,"text/html",Vo,t)},Xo.xml=wt(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Xo):"object"==typeof module&&module.exports?module.exports=Xo:this.d3=Xo}();'use strict';(function(window){window.define=undefined;}).call(this,this);'use strict';tr.exportTo('tr.ui.b',function(){const DataSeriesEnableChangeEventType='data-series-enabled-change';const THIS_DOC=document.currentScript.ownerDocument;const svgNS='http://www.w3.org/2000/svg';const ColorScheme=tr.b.ColorScheme;function getColorOfKey(key,selected){let id=ColorScheme.getColorIdForGeneralPurposeString(key);if(selected){id+=ColorScheme.properties.brightenedOffsets[0];}
 return ColorScheme.colorsAsStrings[id];}
-function getSVGTextSize(parentNode,text,opt_callback,opt_this){var textNode=document.createElementNS('http://www.w3.org/2000/svg','text');textNode.setAttributeNS(null,'x',0);textNode.setAttributeNS(null,'y',0);textNode.setAttributeNS(null,'fill','black');textNode.appendChild(document.createTextNode(text));parentNode.appendChild(textNode);if(opt_callback){opt_callback.call(opt_this||parentNode,textNode);}
-var width=textNode.getComputedTextLength();var height=textNode.getBBox().height;parentNode.removeChild(textNode);return{width,height};}
+function getSVGTextSize(parentNode,text,opt_callback,opt_this){const textNode=document.createElementNS('http://www.w3.org/2000/svg','text');textNode.setAttributeNS(null,'x',0);textNode.setAttributeNS(null,'y',0);textNode.setAttributeNS(null,'fill','black');textNode.appendChild(document.createTextNode(text));parentNode.appendChild(textNode);if(opt_callback){opt_callback.call(opt_this||parentNode,textNode);}
+const width=textNode.getComputedTextLength();const height=textNode.getBBox().height;parentNode.removeChild(textNode);return{width,height};}
 function DataSeries(key){this.key_=key;this.target_=undefined;this.title_='';this.optional_=false;this.enabled_=true;this.color_=getColorOfKey(key,false);this.highlightedColor_=getColorOfKey(key,true);}
 DataSeries.prototype={get key(){return this.key_;},get title(){return this.title_;},set title(t){this.title_=t;},get color(){return this.color_;},set color(c){this.color_=c;},get highlightedColor(){return this.highlightedColor_;},set highlightedColor(c){this.highlightedColor_=c;},get optional(){return this.optional_;},set optional(optional){this.optional_=optional;},get enabled(){return this.enabled_;},set enabled(enabled){if(!this.optional&&!enabled){this.optional=true;}
-this.enabled_=enabled;},get target(){return this.target_;},set target(t){this.target_=t;}};var ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,getDataSeries(key){if(!this.seriesByKey_.has(key)){this.seriesByKey_.set(key,new DataSeries(key));}
-return this.seriesByKey_.get(key);},decorate(){Polymer.dom(this).classList.add('chart-base');this.chartTitle_=undefined;this.seriesByKey_=new Map();this.graphWidth_=undefined;this.graphHeight_=undefined;this.margin={top:0,right:0,bottom:0,left:0,};this.hideLegend_=false;var template=Polymer.dom(THIS_DOC).querySelector('#chart-base-template');var svgEl=Polymer.dom(template.content).querySelector('svg');for(var i=0;i<Polymer.dom(svgEl).children.length;i++){Polymer.dom(this).appendChild(Polymer.dom(svgEl.children[i]).cloneNode(true));}
-this.addEventListener(DataSeriesEnableChangeEventType,this.onDataSeriesEnableChange_.bind(this));},get hideLegend(){return this.hideLegend_;},set hideLegend(h){this.hideLegend_=h;this.updateContents_();},isSeriesEnabled(key){return this.getDataSeries(key).enabled;},onDataSeriesEnableChange_(event){this.getDataSeries(event.key).enabled=event.enabled;this.updateContents_();},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return Polymer.dom(this).querySelector('#chart-area');},get graphWidth(){if(this.graphWidth_===undefined)return this.defaultGraphWidth;return this.graphWidth_;},set graphWidth(width){this.graphWidth_=width;this.updateContents_();},get defaultGraphWidth(){return 0;},get graphHeight(){if(this.graphHeight_===undefined)return this.defaultGraphHeight;return this.graphHeight_;},set graphHeight(height){this.graphHeight_=height;this.updateContents_();},get defaultGraphHeight(){return 0;},get totalWidth(){return this.margin.left+this.graphWidth+this.margin.right;},get totalHeight(){return this.margin.top+this.graphHeight+this.margin.bottom;},updateMargins_(){var legendSize=this.computeLegendSize_();this.margin.right=Math.max(this.margin.right,legendSize.width);this.margin.bottom=Math.max(this.margin.bottom,legendSize.height-this.graphHeight);if(this.chartTitle_){var titleSize=getSVGTextSize(this,this.chartTitle_,textNode=>{textNode.style.fontSize='16pt';});this.margin.top=Math.max(this.margin.top,titleSize.height+15);var horizontalOverhangPx=(titleSize.width-this.graphWidth)/2;this.margin.left=Math.max(this.margin.left,horizontalOverhangPx);this.margin.right=Math.max(this.margin.right,horizontalOverhangPx);}},computeLegendSize_(){var width=0;var height=0;if(this.hideLegend)return{width,height};for(var series of this.seriesByKey_.values()){var textSize=getSVGTextSize(this,series.key);width=Math.max(width,textSize.width+20);height+=textSize.height;}
-return{width,height};},updateDimensions_(){var thisSel=d3.select(this);thisSel.attr('width',this.totalWidth);thisSel.attr('height',this.totalHeight);d3.select(this.chartAreaElement).attr('transform','translate('+this.margin.left+', '+this.margin.top+')');},updateContents_(){this.updateMargins_();this.updateDimensions_();this.updateTitle_();this.updateLegend_();},updateTitle_(){var titleSel=d3.select(this.chartAreaElement).select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
-titleSel.attr('transform','translate('+this.graphWidth*0.5+',-15)').style('display',undefined).style('text-anchor','middle').style('font-size','16pt').attr('class','title').attr('width',this.graphWidth).text(this.chartTitle_);},updateLegend_(){var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.legend').remove();if(this.hideLegend)return;var series=[...this.seriesByKey_.values()].reverse();var legendEntriesSel=chartAreaSel.selectAll('.legend').data(series);legendEntriesSel.enter().append('foreignObject').attr('class','legend').attr('x',this.graphWidth+2).attr('width',this.margin.right).attr('height',18).attr('transform',(series,i)=>'translate(0,'+i*18+')').append('xhtml:body').style('margin',0).append('tr-ui-b-chart-legend-key').property('color',series=>((this.currentHighlightedLegendKey===series.key)?series.highlightedColor:series.color)).property('width',this.margin.right).property('target',series=>series.target).property('title',series=>series.title).property('optional',series=>series.optional).property('enabled',series=>series.enabled).text(series=>series.key);legendEntriesSel.exit().remove();},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_){return this.tempHighlightedLegendKey_;}
+this.enabled_=enabled;},get target(){return this.target_;},set target(t){this.target_=t;}};const ChartBase=tr.ui.b.define('svg',undefined,svgNS);ChartBase.prototype={__proto__:HTMLUnknownElement.prototype,getDataSeries(key){if(!this.seriesByKey_.has(key)){this.seriesByKey_.set(key,new DataSeries(key));}
+return this.seriesByKey_.get(key);},decorate(){Polymer.dom(this).classList.add('chart-base');this.chartTitle_=undefined;this.seriesByKey_=new Map();this.graphWidth_=undefined;this.graphHeight_=undefined;this.margin={top:0,right:0,bottom:0,left:0,};this.hideLegend_=false;const template=Polymer.dom(THIS_DOC).querySelector('#chart-base-template');const svgEl=Polymer.dom(template.content).querySelector('svg');for(let i=0;i<Polymer.dom(svgEl).children.length;i++){Polymer.dom(this).appendChild(Polymer.dom(svgEl.children[i]).cloneNode(true));}
+this.addEventListener(DataSeriesEnableChangeEventType,this.onDataSeriesEnableChange_.bind(this));},get hideLegend(){return this.hideLegend_;},set hideLegend(h){this.hideLegend_=h;this.updateContents_();},isSeriesEnabled(key){return this.getDataSeries(key).enabled;},onDataSeriesEnableChange_(event){this.getDataSeries(event.key).enabled=event.enabled;this.updateContents_();},get chartTitle(){return this.chartTitle_;},set chartTitle(chartTitle){this.chartTitle_=chartTitle;this.updateContents_();},get chartAreaElement(){return Polymer.dom(this).querySelector('#chart-area');},get graphWidth(){if(this.graphWidth_===undefined)return this.defaultGraphWidth;return this.graphWidth_;},set graphWidth(width){this.graphWidth_=width;this.updateContents_();},get defaultGraphWidth(){return 0;},get graphHeight(){if(this.graphHeight_===undefined)return this.defaultGraphHeight;return this.graphHeight_;},set graphHeight(height){this.graphHeight_=height;this.updateContents_();},get defaultGraphHeight(){return 0;},get totalWidth(){return this.margin.left+this.graphWidth+this.margin.right;},get totalHeight(){return this.margin.top+this.graphHeight+this.margin.bottom;},updateMargins_(){const legendSize=this.computeLegendSize_();this.margin.right=Math.max(this.margin.right,legendSize.width);this.margin.bottom=Math.max(this.margin.bottom,legendSize.height-this.graphHeight);if(this.chartTitle_){const titleSize=getSVGTextSize(this,this.chartTitle_,textNode=>{textNode.style.fontSize='16pt';});this.margin.top=Math.max(this.margin.top,titleSize.height+15);const horizontalOverhangPx=(titleSize.width-this.graphWidth)/2;this.margin.left=Math.max(this.margin.left,horizontalOverhangPx);this.margin.right=Math.max(this.margin.right,horizontalOverhangPx);}},computeLegendSize_(){let width=0;let height=0;if(this.hideLegend)return{width,height};for(const series of this.seriesByKey_.values()){const textSize=getSVGTextSize(this,series.key);width=Math.max(width,textSize.width+20);height+=textSize.height;}
+return{width,height};},updateDimensions_(){const thisSel=d3.select(this);thisSel.attr('width',this.totalWidth);thisSel.attr('height',this.totalHeight);d3.select(this.chartAreaElement).attr('transform','translate('+this.margin.left+', '+this.margin.top+')');},updateContents_(){this.updateMargins_();this.updateDimensions_();this.updateTitle_();this.updateLegend_();},updateTitle_(){const titleSel=d3.select(this.chartAreaElement).select('#title');if(!this.chartTitle_){titleSel.style('display','none');return;}
+titleSel.attr('transform','translate('+this.graphWidth*0.5+',-15)').style('display',undefined).style('text-anchor','middle').style('font-size','16pt').attr('class','title').attr('width',this.graphWidth).text(this.chartTitle_);},updateLegend_(){const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.legend').remove();if(this.hideLegend)return;const series=[...this.seriesByKey_.values()].reverse();const legendEntriesSel=chartAreaSel.selectAll('.legend').data(series);legendEntriesSel.enter().append('foreignObject').attr('class','legend').attr('x',this.graphWidth+2).attr('width',this.margin.right).attr('height',18).attr('transform',(series,i)=>'translate(0,'+i*18+')').append('xhtml:body').style('margin',0).append('tr-ui-b-chart-legend-key').property('color',series=>((this.currentHighlightedLegendKey===series.key)?series.highlightedColor:series.color)).property('width',this.margin.right).property('target',series=>series.target).property('title',series=>series.title).property('optional',series=>series.optional).property('enabled',series=>series.enabled).text(series=>series.key);legendEntriesSel.exit().remove();},get highlightedLegendKey(){return this.highlightedLegendKey_;},set highlightedLegendKey(highlightedLegendKey){this.highlightedLegendKey_=highlightedLegendKey;this.updateHighlight_();},get currentHighlightedLegendKey(){if(this.tempHighlightedLegendKey_){return this.tempHighlightedLegendKey_;}
 return this.highlightedLegendKey_;},pushTempHighlightedLegendKey(key){if(this.tempHighlightedLegendKey_){throw new Error('push cannot nest');}
 this.tempHighlightedLegendKey_=key;this.updateHighlight_();},popTempHighlightedLegendKey(key){if(this.tempHighlightedLegendKey_!==key){throw new Error('pop cannot happen');}
-this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_(){const chartAreaSel=d3.select(this.chartAreaElement);const legendEntriesSel=chartAreaSel.selectAll('.legend');const getDataSeries=chart.getDataSeries.bind(chart);const currentHighlightedLegendKey=chart.currentHighlightedLegendKey;legendEntriesSel.each(function(key){var dataSeries=getDataSeries(key);if(key===currentHighlightedLegendKey){this.style.fill=dataSeries.highlightedColor;this.style.fontWeight='bold';}else{this.style.fill=dataSeries.color;this.style.fontWeight='';}});}};return{ChartBase,DataSeriesEnableChangeEventType,getColorOfKey,getSVGTextSize,};});'use strict';tr.exportTo('tr.ui.b',function(){var D3_Y_AXIS_WIDTH_PX=9;var D3_X_AXIS_HEIGHT_PX=23;function sanitizePower(x,defaultValue){if(!isNaN(x)&&isFinite(x)&&(x!==0))return x;return defaultValue;}
-var ChartBase2D=tr.ui.b.define('chart-base-2d',tr.ui.b.ChartBase);ChartBase2D.prototype={__proto__:tr.ui.b.ChartBase.prototype,decorate(){super.decorate();Polymer.dom(this).classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleMin_=undefined;this.autoDataRange_=new tr.b.math.Range();this.overrideDataRange_=undefined;this.hideXAxis_=false;this.hideYAxis_=false;this.data_=[];this.xAxisLabel_='';this.yAxisLabel_='';this.textHeightPx_=0;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get xAxisLabel(){return this.xAxisLabel_;},set xAxisLabel(label){this.xAxisLabel_=label;},get yAxisLabel(){return this.yAxisLabel_;},set yAxisLabel(label){this.yAxisLabel_=label;},get hideXAxis(){return this.hideXAxis_;},set hideXAxis(h){this.hideXAxis_=h;this.updateContents_();},get hideYAxis(){return this.hideYAxis_;},set hideYAxis(h){this.hideYAxis_=h;this.updateContents_();},get data(){return this.data_;},set data(data){if(data===undefined){throw new Error('data must be an Array');}
+this.tempHighlightedLegendKey_=undefined;this.updateHighlight_();},updateHighlight_(){const chartAreaSel=d3.select(this.chartAreaElement);const legendEntriesSel=chartAreaSel.selectAll('.legend');const getDataSeries=chart.getDataSeries.bind(chart);const currentHighlightedLegendKey=chart.currentHighlightedLegendKey;legendEntriesSel.each(function(key){const dataSeries=getDataSeries(key);if(key===currentHighlightedLegendKey){this.style.fill=dataSeries.highlightedColor;this.style.fontWeight='bold';}else{this.style.fill=dataSeries.color;this.style.fontWeight='';}});}};return{ChartBase,DataSeriesEnableChangeEventType,getColorOfKey,getSVGTextSize,};});'use strict';tr.exportTo('tr.ui.b',function(){const D3_Y_AXIS_WIDTH_PX=9;const D3_X_AXIS_HEIGHT_PX=23;function sanitizePower(x,defaultValue){if(!isNaN(x)&&isFinite(x)&&(x!==0))return x;return defaultValue;}
+const ChartBase2D=tr.ui.b.define('chart-base-2d',tr.ui.b.ChartBase);ChartBase2D.prototype={__proto__:tr.ui.b.ChartBase.prototype,decorate(){super.decorate();Polymer.dom(this).classList.add('chart-base-2d');this.xScale_=d3.scale.linear();this.yScale_=d3.scale.linear();this.isYLogScale_=false;this.yLogScaleMin_=undefined;this.autoDataRange_=new tr.b.math.Range();this.overrideDataRange_=undefined;this.hideXAxis_=false;this.hideYAxis_=false;this.data_=[];this.xAxisLabel_='';this.yAxisLabel_='';this.textHeightPx_=0;d3.select(this.chartAreaElement).append('g').attr('id','brushes');d3.select(this.chartAreaElement).append('g').attr('id','series');this.addEventListener('mousedown',this.onMouseDown_.bind(this));},get xAxisLabel(){return this.xAxisLabel_;},set xAxisLabel(label){this.xAxisLabel_=label;},get yAxisLabel(){return this.yAxisLabel_;},set yAxisLabel(label){this.yAxisLabel_=label;},get hideXAxis(){return this.hideXAxis_;},set hideXAxis(h){this.hideXAxis_=h;this.updateContents_();},get hideYAxis(){return this.hideYAxis_;},set hideYAxis(h){this.hideYAxis_=h;this.updateContents_();},get data(){return this.data_;},set data(data){if(data===undefined){throw new Error('data must be an Array');}
 this.data_=data;this.updateSeriesKeys_();this.updateDataRange_();this.updateContents_();},set isYLogScale(logScale){if(logScale){this.yScale_=d3.scale.log(10);}else{this.yScale_=d3.scale.linear();}
 this.isYLogScale_=logScale;},getYScaleMin_(){return this.isYLogScale_?this.yLogScaleMin_:0;},getYScaleDomain_(minValue,maxValue){if(this.overrideDataRange_!==undefined){return[this.dataRange.min,this.dataRange.max];}
 if(this.isYLogScale_){return[this.getYScaleMin_(),maxValue];}
-return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_(data,index,leftSide){var leftIndex;var rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
-var leftWidth=this.getXForDatum_(data[index],index)-
-this.getXForDatum_(data[leftIndex],leftIndex);var rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
+return[Math.min(minValue,this.getYScaleMin_()),maxValue];},getSampleWidth_(data,index,leftSide){let leftIndex;let rightIndex;if(leftSide){leftIndex=Math.max(index-1,0);rightIndex=index;}else{leftIndex=index;rightIndex=Math.min(index+1,data.length-1);}
+const leftWidth=this.getXForDatum_(data[index],index)-
+this.getXForDatum_(data[leftIndex],leftIndex);const rightWidth=this.getXForDatum_(data[rightIndex],rightIndex)-
 this.getXForDatum_(data[index],index);return tr.b.math.Statistics.mean([leftWidth,rightWidth]);},updateSeriesKeys_(){this.data_.forEach(function(datum){Object.keys(datum).forEach(function(key){if(this.isDatumFieldSeries_(key)){this.getDataSeries(key);}},this);},this);},isDatumFieldSeries_(fieldName){return fieldName!=='x';},getXForDatum_(datum,index){return datum.x;},updateMargins_(){this.margin.left=this.hideYAxis?0:this.yAxisWidth;this.margin.bottom=this.hideXAxis?0:this.xAxisHeight;if(this.hideXAxis&&!this.hideYAxis){this.margin.bottom=10;}
 if(this.hideYAxis&&!this.hideXAxis){this.margin.left=10;}
 this.margin.top=this.hideYAxis?0:10;if(this.yAxisLabel){this.margin.top+=this.textHeightPx_;}
 if(this.xAxisLabel){this.margin.right=Math.max(this.margin.right,16+tr.ui.b.getSVGTextSize(this,this.xAxisLabel).width);}
-super.updateMargins_();},get xAxisHeight(){return D3_X_AXIS_HEIGHT_PX;},computeScaleTickWidth_(scale){if(this.data.length===0)return 0;var tickValues=scale.ticks();var format=scale.tickFormat();if(this.isYLogScale_){var enclosingPowers=this.dataRange.enclosingPowers();tickValues=[sanitizePower(enclosingPowers.min,1),sanitizePower(enclosingPowers.max,10),];format=v=>v.toString();}
-return D3_Y_AXIS_WIDTH_PX+Math.max(tr.ui.b.getSVGTextSize(this,format(tickValues[0])).width,tr.ui.b.getSVGTextSize(this,format(tickValues[tickValues.length-1])).width);},get yAxisWidth(){return this.computeScaleTickWidth_(this.yScale_);},updateScales_(){if(this.data_.length===0)return;this.xScale_.range([0,this.graphWidth]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));this.yScale_.range([this.graphHeight,0]);this.yScale_.domain([this.dataRange.min,this.dataRange.max]);},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();},updateXAxis_(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;if(this.hideXAxis)return;this.drawXAxis_(xAxis);var label=xAxis.append('text').attr('class','label');this.drawXAxisTicks_(xAxis);this.drawXAxisLabel_(label);xAxis[0][0].style.opacity=1;},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));},drawXAxisLabel_(label){label.attr('x',this.graphWidth+16).attr('y',8).text(this.xAxisLabel);},drawXAxisTicks_(xAxis){var previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){var currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){var currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});},set overrideDataRange(range){this.overrideDataRange_=range;},get dataRange(){if(this.overrideDataRange_!==undefined){return this.overrideDataRange_;}
-return this.autoDataRange_;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;var dataBySeriesKey=this.getDataBySeriesKey_();this.autoDataRange_.reset();for(var[series,values]of Object.entries(dataBySeriesKey)){for(var i=0;i<values.length;i++){this.autoDataRange_.addValue(values[i][series]);}}
-this.yLogScaleMin_=undefined;if(this.autoDataRange_.min!==undefined){var minValue=this.autoDataRange_.min;if(minValue===0){minValue=1;}
-var onePowerLess=tr.b.math.lesserPower(minValue/10);this.yLogScaleMin_=onePowerLess;}},updateYAxis_(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;if(this.hideYAxis)return;this.drawYAxis_(yAxis);this.drawYAxisTicks_(yAxis);var label=yAxis.append('text').attr('class','label');this.drawYAxisLabel_(label);},drawYAxis_(yAxis){var axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)return;var tickValues=[];var enclosingPowers=this.dataRange.enclosingPowers();var maxPower=sanitizePower(enclosingPowers.max,10);for(var power=sanitizePower(enclosingPowers.min,1);power<=maxPower;power*=10){tickValues.push(power);}
+super.updateMargins_();},get xAxisHeight(){return D3_X_AXIS_HEIGHT_PX;},computeScaleTickWidth_(scale){if(this.data.length===0)return 0;let tickValues=scale.ticks();let format=scale.tickFormat();if(this.isYLogScale_){const enclosingPowers=this.dataRange.enclosingPowers();tickValues=[sanitizePower(enclosingPowers.min,1),sanitizePower(enclosingPowers.max,10),];format=v=>v.toString();}
+return D3_Y_AXIS_WIDTH_PX+Math.max(tr.ui.b.getSVGTextSize(this,format(tickValues[0])).width,tr.ui.b.getSVGTextSize(this,format(tickValues[tickValues.length-1])).width);},get yAxisWidth(){return this.computeScaleTickWidth_(this.yScale_);},updateScales_(){if(this.data_.length===0)return;this.xScale_.range([0,this.graphWidth]);this.xScale_.domain(d3.extent(this.data_,this.getXForDatum_.bind(this)));this.yScale_.range([this.graphHeight,0]);this.yScale_.domain([this.dataRange.min,this.dataRange.max]);},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();},updateXAxis_(xAxis){xAxis.selectAll('*').remove();xAxis[0][0].style.opacity=0;if(this.hideXAxis)return;this.drawXAxis_(xAxis);const label=xAxis.append('text').attr('class','label');this.drawXAxisTicks_(xAxis);this.drawXAxisLabel_(label);xAxis[0][0].style.opacity=1;},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.xScale_).orient('bottom'));},drawXAxisLabel_(label){label.attr('x',this.graphWidth+16).attr('y',8).text(this.xAxisLabel);},drawXAxisTicks_(xAxis){let previousRight=undefined;xAxis.selectAll('.tick')[0].forEach(function(tick){const currentLeft=tick.transform.baseVal[0].matrix.e;if((previousRight===undefined)||(currentLeft>(previousRight+3))){const currentWidth=tick.getBBox().width;previousRight=currentLeft+currentWidth;}else{tick.style.opacity=0;}});},set overrideDataRange(range){this.overrideDataRange_=range;},get dataRange(){if(this.overrideDataRange_!==undefined){return this.overrideDataRange_;}
+return this.autoDataRange_;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;const dataBySeriesKey=this.getDataBySeriesKey_();this.autoDataRange_.reset();for(const[series,values]of Object.entries(dataBySeriesKey)){for(let i=0;i<values.length;i++){this.autoDataRange_.addValue(values[i][series]);}}
+this.yLogScaleMin_=undefined;if(this.autoDataRange_.min!==undefined){let minValue=this.autoDataRange_.min;if(minValue===0){minValue=1;}
+const onePowerLess=tr.b.math.lesserPower(minValue/10);this.yLogScaleMin_=onePowerLess;}},updateYAxis_(yAxis){yAxis.selectAll('*').remove();yAxis[0][0].style.opacity=0;if(this.hideYAxis)return;this.drawYAxis_(yAxis);this.drawYAxisTicks_(yAxis);const label=yAxis.append('text').attr('class','label');this.drawYAxisLabel_(label);},drawYAxis_(yAxis){let axisModifier=d3.svg.axis().scale(this.yScale_).orient('left');if(this.isYLogScale_){if(this.yLogScaleMin_===undefined)return;const tickValues=[];const enclosingPowers=this.dataRange.enclosingPowers();const maxPower=sanitizePower(enclosingPowers.max,10);for(let power=sanitizePower(enclosingPowers.min,1);power<=maxPower;power*=10){tickValues.push(power);}
 axisModifier=axisModifier.tickValues(tickValues).tickFormat(v=>v.toString());}
-yAxis.call(axisModifier);},drawYAxisLabel_(label){var labelWidthPx=Math.ceil(tr.ui.b.getSVGTextSize(this.chartAreaElement,this.yAxisLabel).width);label.attr('x',-labelWidthPx).attr('y',-8).text(this.yAxisLabel);},drawYAxisTicks_(yAxis){var previousTop=undefined;yAxis.selectAll('.tick')[0].forEach(function(tick){var bbox=tick.getBBox();var currentTop=tick.transform.baseVal[0].matrix.f;var currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});yAxis[0][0].style.opacity=1;},updateContents_(){if(this.textHeightPx_===0){this.textHeightPx_=tr.ui.b.getSVGTextSize(this,'Ay').height;}
-this.updateScales_();super.updateContents_();var chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_(){var dataBySeriesKey={};for(var[key,series]of this.seriesByKey_){dataBySeriesKey[key]=[];}
-this.data_.forEach(function(multiSeriesDatum,index){var x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')return;if(multiSeriesDatum[seriesKey]===undefined)return;if(!this.isDatumFieldSeries_(seriesKey))return;var singleSeriesDatum={x:x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getChartPointAtClientPoint_(clientPoint){var rect=this.getBoundingClientRect();return{x:clientPoint.x-rect.left-this.margin.left,y:clientPoint.y-rect.top-this.margin.top};},getDataPointAtChartPoint_(chartPoint){return{x:tr.b.math.clamp(this.xScale_.invert(chartPoint.x),this.xScale_.domain()[0],this.xScale_.domain()[1]),y:tr.b.math.clamp(this.yScale_.invert(chartPoint.y),this.yScale_.domain()[0],this.yScale_.domain()[1])};},getDataPointAtClientPoint_(clientX,clientY){var chartPoint=this.getChartPointAtClientPoint_({x:clientX,y:clientY});return this.getDataPointAtChartPoint_(chartPoint);},prepareDataEvent_(mouseEvent,dataEvent){var dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;Polymer.dom(this).classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
-var dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();var dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);Polymer.dom(this).classList.remove('updating-brushing-state');}};return{ChartBase2D,};});'use strict';tr.exportTo('tr.ui.b',function(){var ChartBase2D=tr.ui.b.ChartBase2D;var ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate(){super.decorate();this.brushedRange_=new tr.b.math.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},get brushedRange(){return tr.b.math.Range.fromDict(this.brushedRange_.toJSON());},computeBrushRangeFromIndices(indexA,indexB){indexA=tr.b.math.clamp(indexA,0,this.data_.length-1);indexB=tr.b.math.clamp(indexB,0,this.data_.length-1);var leftIndex=Math.min(indexA,indexB);var rightIndex=Math.max(indexA,indexB);var brushRange=new tr.b.math.Range();brushRange.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
+yAxis.call(axisModifier);},drawYAxisLabel_(label){const labelWidthPx=Math.ceil(tr.ui.b.getSVGTextSize(this.chartAreaElement,this.yAxisLabel).width);label.attr('x',-labelWidthPx).attr('y',-8).text(this.yAxisLabel);},drawYAxisTicks_(yAxis){let previousTop=undefined;yAxis.selectAll('.tick')[0].forEach(function(tick){const bbox=tick.getBBox();const currentTop=tick.transform.baseVal[0].matrix.f;const currentBottom=currentTop+bbox.height;if((previousTop===undefined)||(previousTop>(currentBottom+3))){previousTop=currentTop;}else{tick.style.opacity=0;}});yAxis[0][0].style.opacity=1;},updateContents_(){if(this.textHeightPx_===0){this.textHeightPx_=tr.ui.b.getSVGTextSize(this,'Ay').height;}
+this.updateScales_();super.updateContents_();const chartAreaSel=d3.select(this.chartAreaElement);this.updateXAxis_(chartAreaSel.select('.x.axis'));this.updateYAxis_(chartAreaSel.select('.y.axis'));this.updateBrushContents_(chartAreaSel.select('#brushes'));this.updateDataContents_(chartAreaSel.select('#series'));},updateDataContents_(seriesSel){throw new Error('Not implemented');},getDataBySeriesKey_(){const dataBySeriesKey={};for(const[key,series]of this.seriesByKey_){dataBySeriesKey[key]=[];}
+this.data_.forEach(function(multiSeriesDatum,index){const x=this.getXForDatum_(multiSeriesDatum,index);d3.keys(multiSeriesDatum).forEach(function(seriesKey){if(seriesKey==='x')return;if(multiSeriesDatum[seriesKey]===undefined)return;if(!this.isDatumFieldSeries_(seriesKey))return;const singleSeriesDatum={x};singleSeriesDatum[seriesKey]=multiSeriesDatum[seriesKey];dataBySeriesKey[seriesKey].push(singleSeriesDatum);},this);},this);return dataBySeriesKey;},getChartPointAtClientPoint_(clientPoint){const rect=this.getBoundingClientRect();return{x:clientPoint.x-rect.left-this.margin.left,y:clientPoint.y-rect.top-this.margin.top};},getDataPointAtChartPoint_(chartPoint){return{x:tr.b.math.clamp(this.xScale_.invert(chartPoint.x),this.xScale_.domain()[0],this.xScale_.domain()[1]),y:tr.b.math.clamp(this.yScale_.invert(chartPoint.y),this.yScale_.domain()[0],this.yScale_.domain()[1])};},getDataPointAtClientPoint_(clientX,clientY){const chartPoint=this.getChartPointAtClientPoint_({x:clientX,y:clientY});return this.getDataPointAtChartPoint_(chartPoint);},prepareDataEvent_(mouseEvent,dataEvent){const dataPoint=this.getDataPointAtClientPoint_(mouseEvent.clientX,mouseEvent.clientY);dataEvent.x=dataPoint.x;dataEvent.y=dataPoint.y;},onMouseDown_(mouseEvent){tr.ui.b.trackMouseMovesUntilMouseUp(this.onMouseMove_.bind(this,mouseEvent.button),this.onMouseUp_.bind(this,mouseEvent.button));mouseEvent.preventDefault();mouseEvent.stopPropagation();const dataEvent=new tr.b.Event('item-mousedown');dataEvent.button=mouseEvent.button;Polymer.dom(this).classList.add('updating-brushing-state');this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseMove_(button,mouseEvent){if(mouseEvent.buttons!==undefined){mouseEvent.preventDefault();mouseEvent.stopPropagation();}
+const dataEvent=new tr.b.Event('item-mousemove');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);},onMouseUp_(button,mouseEvent){mouseEvent.preventDefault();mouseEvent.stopPropagation();const dataEvent=new tr.b.Event('item-mouseup');dataEvent.button=button;this.prepareDataEvent_(mouseEvent,dataEvent);this.dispatchEvent(dataEvent);Polymer.dom(this).classList.remove('updating-brushing-state');}};return{ChartBase2D,};});'use strict';tr.exportTo('tr.ui.b',function(){const ChartBase2D=tr.ui.b.ChartBase2D;const ChartBase2DBrushX=tr.ui.b.define('chart-base-2d-brush-1d',ChartBase2D);ChartBase2DBrushX.prototype={__proto__:ChartBase2D.prototype,decorate(){super.decorate();this.brushedRange_=new tr.b.math.Range();},set brushedRange(range){this.brushedRange_.reset();this.brushedRange_.addRange(range);this.updateContents_();},get brushedRange(){return tr.b.math.Range.fromDict(this.brushedRange_.toJSON());},computeBrushRangeFromIndices(indexA,indexB){indexA=tr.b.math.clamp(indexA,0,this.data_.length-1);indexB=tr.b.math.clamp(indexB,0,this.data_.length-1);const leftIndex=Math.min(indexA,indexB);const rightIndex=Math.max(indexA,indexB);const brushRange=new tr.b.math.Range();brushRange.addValue(this.getXForDatum_(this.data_[leftIndex],leftIndex)-
 this.getSampleWidth_(this.data_,leftIndex,true));brushRange.addValue(this.getXForDatum_(this.data_[rightIndex],rightIndex)+
-this.getSampleWidth_(this.data_,rightIndex,false));return brushRange;},getDataIndex_(dataX){if(this.data.length===0)return undefined;var bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined){dataEvent.data=this.data_[dataEvent.index];}},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();var brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];var brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();this.drawBrush_(brushRectsSel);},drawBrush_(brushRectsSel){brushRectsSel.attr('x',d=>this.xScale_(d.min)).attr('y',0).attr('width',d=>this.xScale_(d.max)-this.xScale_(d.min)).attr('height',this.graphHeight);}};return{ChartBase2DBrushX,};});'use strict';tr.exportTo('tr.ui.b',function(){var LineChart=tr.ui.b.define('line-chart',tr.ui.b.ChartBase2DBrushX);LineChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,get defaultGraphWidth(){return 20*this.data_.length;},get defaultGraphHeight(){return 100;},updateDataContents_(dataSel){dataSel.selectAll('*').remove();var dataBySeriesKey=this.getDataBySeriesKey_();var seriesKeys=[...this.seriesByKey_.keys()];var pathsSel=dataSel.selectAll('path').data(seriesKeys);pathsSel.enter().append('path').style('fill','none').style('stroke-width','1.5px').style('stroke',key=>this.getDataSeries(key).color).attr('d',key=>{var line=d3.svg.line().x(d=>this.xScale_(d.x)).y(d=>this.yScale_(this.dataRange.clamp(d[key])));return line(dataBySeriesKey[key]);});pathsSel.exit().remove();}};return{LineChart,};});'use strict';Polymer({is:'tr-ui-e-s-input-latency-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready:function(){this.rangeOfInterest_=new tr.b.math.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
-this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices:function(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_:function(){if(this.latencyChart_===undefined)return;var r=new tr.b.math.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
-r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;var latencySlices=[];for(var thread of this.model_.getAllThreads()){for(var event of thread.getDescendantEvents()){if(event.title.indexOf('InputLatency:')===0){latencySlices.push(event);}}}
-latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_:function(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button===undefined)return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_:function(){var browserProcess=this.modelHelper_.browserProcess;var labels=[];if(browserProcess!==undefined){var labelStr='Browser: '+browserProcess.pid;labels.push({label:labelStr,value:browserProcess.pid});}
-for(var rendererHelper of
-Object.values(this.modelHelper_.rendererHelpers)){var rendererProcess=rendererHelper.process;var labelStr='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:labelStr,value:rendererProcess.userFriendlyName});}
-if(labels.length===0)return;this.selectedProcessId_=labels[0].value;var toolbarEl=this.$.toolbar;Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
-return this.rangeOfInterest_;},createLatencyLineChart:function(data,title,parentNode){var chart=new tr.ui.b.LineChart();Polymer.dom(parentNode).appendChild(chart);var width=600;if(document.body.clientWidth!==undefined){width=document.body.clientWidth*0.5;}
-chart.graphWidth=width;chart.chartTitle=title;chart.data=data;return chart;},updateContents_:function(){var resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;Polymer.dom(resultArea).textContent='';if(this.modelHelper_===undefined)return;var rangeOfInterest=this.currentRangeOfInterest;var chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_]){chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];}else{chromeProcess=this.modelHelper_.browserHelper;}
-var frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);var frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);var averageFrametime=tr.b.math.Statistics.mean(frametimeData,d=>d.frametime);var latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);var latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});var averageLatency=tr.b.math.Statistics.mean(latencyData,function(d){return d.latency;});var latencySummaryText=document.createElement('div');Polymer.dom(latencySummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));Polymer.dom(resultArea).appendChild(latencySummaryText);var frametimeSummaryText=document.createElement('div');Polymer.dom(frametimeSummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));Polymer.dom(resultArea).appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time',resultArea);this.registerMouseEventForLatencyChart_();}
-if(frametimeData.length!==0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times',resultArea);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel:function(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
+this.getSampleWidth_(this.data_,rightIndex,false));return brushRange;},getDataIndex_(dataX){if(this.data.length===0)return undefined;const bisect=d3.bisector(this.getXForDatum_.bind(this)).right;return bisect(this.data_,dataX)-1;},prepareDataEvent_(mouseEvent,dataEvent){ChartBase2D.prototype.prepareDataEvent_.call(this,mouseEvent,dataEvent);dataEvent.index=this.getDataIndex_(dataEvent.x);if(dataEvent.index!==undefined){dataEvent.data=this.data_[dataEvent.index];}},updateBrushContents_(brushSel){brushSel.selectAll('*').remove();const brushes=this.brushedRange_.isEmpty?[]:[this.brushedRange_];const brushRectsSel=brushSel.selectAll('rect').data(brushes);brushRectsSel.enter().append('rect');brushRectsSel.exit().remove();this.drawBrush_(brushRectsSel);},drawBrush_(brushRectsSel){brushRectsSel.attr('x',d=>this.xScale_(d.min)).attr('y',0).attr('width',d=>this.xScale_(d.max)-this.xScale_(d.min)).attr('height',this.graphHeight);}};return{ChartBase2DBrushX,};});'use strict';tr.exportTo('tr.ui.b',function(){const LineChart=tr.ui.b.define('line-chart',tr.ui.b.ChartBase2DBrushX);LineChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,get defaultGraphWidth(){return 20*this.data_.length;},get defaultGraphHeight(){return 100;},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const dataBySeriesKey=this.getDataBySeriesKey_();const seriesKeys=[...this.seriesByKey_.keys()];const pathsSel=dataSel.selectAll('path').data(seriesKeys);pathsSel.enter().append('path').style('fill','none').style('stroke-width','1.5px').style('stroke',key=>this.getDataSeries(key).color).attr('d',key=>{const line=d3.svg.line().x(d=>this.xScale_(d.x)).y(d=>this.yScale_(this.dataRange.clamp(d[key])));return line(dataBySeriesKey[key]);});pathsSel.exit().remove();}};return{LineChart,};});'use strict';Polymer({is:'tr-ui-e-s-input-latency-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.rangeOfInterest_=new tr.b.math.Range();this.frametimeType_=tr.model.helpers.IMPL_FRAMETIME_TYPE;this.latencyChart_=undefined;this.frametimeChart_=undefined;this.selectedProcessId_=undefined;this.mouseDownIndex_=undefined;this.curMouseIndex_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;if(this.model_){this.modelHelper_=this.model_.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);}else{this.modelHelper_=undefined;}
+this.updateToolbar_();this.updateContents_();},get frametimeType(){return this.frametimeType_;},set frametimeType(type){if(this.frametimeType_===type)return;this.frametimeType_=type;this.updateContents_();},get selectedProcessId(){return this.selectedProcessId_;},set selectedProcessId(process){if(this.selectedProcessId_===process)return;this.selectedProcessId_=process;this.updateContents_();},set selection(selection){if(this.latencyChart_===undefined)return;this.latencyChart_.brushedRange=selection.bounds;},setBrushedIndices(mouseDownIndex,curIndex){this.mouseDownIndex_=mouseDownIndex;this.curMouseIndex_=curIndex;this.updateBrushedRange_();},updateBrushedRange_(){if(this.latencyChart_===undefined)return;let r=new tr.b.math.Range();if(this.mouseDownIndex_===undefined){this.latencyChart_.brushedRange=r;return;}
+r=this.latencyChart_.computeBrushRangeFromIndices(this.mouseDownIndex_,this.curMouseIndex_);this.latencyChart_.brushedRange=r;let latencySlices=[];for(const thread of this.model_.getAllThreads()){for(const event of thread.getDescendantEvents()){if(event.title.indexOf('InputLatency:')===0){latencySlices.push(event);}}}
+latencySlices=tr.model.helpers.getSlicesIntersectingRange(r,latencySlices);const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(latencySlices);this.latencyChart_.dispatchEvent(event);},registerMouseEventForLatencyChart_(){this.latencyChart_.addEventListener('item-mousedown',function(e){this.mouseDownIndex_=e.index;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mousemove',function(e){if(e.button===undefined)return;this.curMouseIndex_=e.index;this.updateBrushedRange_();}.bind(this));this.latencyChart_.addEventListener('item-mouseup',function(e){this.curMouseIndex=e.index;this.updateBrushedRange_();}.bind(this));},updateToolbar_(){const browserProcess=this.modelHelper_.browserProcess;const labels=[];if(browserProcess!==undefined){const labelStr='Browser: '+browserProcess.pid;labels.push({label:labelStr,value:browserProcess.pid});}
+for(const rendererHelper of
+Object.values(this.modelHelper_.rendererHelpers)){const rendererProcess=rendererHelper.process;const labelStr='Renderer: '+rendererProcess.userFriendlyName;labels.push({label:labelStr,value:rendererProcess.userFriendlyName});}
+if(labels.length===0)return;this.selectedProcessId_=labels[0].value;const toolbarEl=this.$.toolbar;Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'frametimeType','inputLatencySidePanel.frametimeType',this.frametimeType_,[{label:'Main Thread Frame Times',value:tr.model.helpers.MAIN_FRAMETIME_TYPE},{label:'Impl Thread Frame Times',value:tr.model.helpers.IMPL_FRAMETIME_TYPE}]));Polymer.dom(toolbarEl).appendChild(tr.ui.b.createSelector(this,'selectedProcessId','inputLatencySidePanel.selectedProcessId',this.selectedProcessId_,labels));},get currentRangeOfInterest(){if(this.rangeOfInterest_.isEmpty){return this.model_.bounds;}
+return this.rangeOfInterest_;},createLatencyLineChart(data,title,parentNode){const chart=new tr.ui.b.LineChart();Polymer.dom(parentNode).appendChild(chart);let width=600;if(document.body.clientWidth!==undefined){width=document.body.clientWidth*0.5;}
+chart.graphWidth=width;chart.chartTitle=title;chart.data=data;return chart;},updateContents_(){const resultArea=this.$.result_area;this.latencyChart_=undefined;this.frametimeChart_=undefined;Polymer.dom(resultArea).textContent='';if(this.modelHelper_===undefined)return;const rangeOfInterest=this.currentRangeOfInterest;let chromeProcess;if(this.modelHelper_.rendererHelpers[this.selectedProcessId_]){chromeProcess=this.modelHelper_.rendererHelpers[this.selectedProcessId_];}else{chromeProcess=this.modelHelper_.browserHelper;}
+const frameEvents=chromeProcess.getFrameEventsInRange(this.frametimeType,rangeOfInterest);const frametimeData=tr.model.helpers.getFrametimeDataFromEvents(frameEvents);const averageFrametime=tr.b.math.Statistics.mean(frametimeData,d=>d.frametime);const latencyEvents=this.modelHelper_.browserHelper.getLatencyEventsInRange(rangeOfInterest);const latencyData=[];latencyEvents.forEach(function(event){if(event.inputLatency===undefined)return;latencyData.push({x:event.start,latency:event.inputLatency/1000});});const averageLatency=tr.b.math.Statistics.mean(latencyData,function(d){return d.latency;});const latencySummaryText=document.createElement('div');Polymer.dom(latencySummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Latency '+averageLatency+' ms',bold:true}));Polymer.dom(resultArea).appendChild(latencySummaryText);const frametimeSummaryText=document.createElement('div');Polymer.dom(frametimeSummaryText).appendChild(tr.ui.b.createSpan({textContent:'Average Frame Time '+averageFrametime+' ms',bold:true}));Polymer.dom(resultArea).appendChild(frametimeSummaryText);if(latencyData.length!==0){this.latencyChart_=this.createLatencyLineChart(latencyData,'Latency Over Time',resultArea);this.registerMouseEventForLatencyChart_();}
+if(frametimeData.length!==0){this.frametimeChart_=this.createLatencyLineChart(frametimeData,'Frame Times',resultArea);}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;this.updateContents_();},supportsModel(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}
 if(!tr.model.helpers.ChromeModelHelper.supportsModel(m)){return{supported:false,reason:'No Chrome browser or renderer process found'};}
-var modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
-return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-input-latency-side-panel');});'use strict';tr.exportTo('tr.e.system_stats',function(){var ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
-SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize:function(){if(this.args.length===0){throw new Error('No system stats snapshot data.');}
-this.stats_=this.args;},getStats:function(){return this.stats_;},setStats:function(stats){this.stats_=stats;}};ObjectSnapshot.subTypes.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){var constants={HEADING_WIDTH:250};return{constants,};});'use strict';Polymer({is:'tr-ui-b-heading',DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready:function(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_:function(){this.dispatchEvent(new tr.b.Event('heading-clicked',true));},updateContents_:function(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
+const modelHelper=m.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper.browserHelper&&modelHelper.browserHelper.hasLatencyEvents){return{supported:true};}
+return{supported:false,reason:'No InputLatency events trace. Consider enabling '+'benchmark" and "input" category when recording the trace'};},get textLabel(){return'Input Latency';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-input-latency-side-panel');});'use strict';tr.exportTo('tr.e.system_stats',function(){const ObjectSnapshot=tr.model.ObjectSnapshot;function SystemStatsSnapshot(objectInstance,ts,args){ObjectSnapshot.apply(this,arguments);this.objectInstance=objectInstance;this.ts=ts;this.args=args;this.stats=args;}
+SystemStatsSnapshot.prototype={__proto__:ObjectSnapshot.prototype,initialize(){if(this.args.length===0){throw new Error('No system stats snapshot data.');}
+this.stats_=this.args;},getStats(){return this.stats_;},setStats(stats){this.stats_=stats;}};ObjectSnapshot.subTypes.register(SystemStatsSnapshot,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshot,};});'use strict';tr.exportTo('tr.ui.b',function(){const constants={HEADING_WIDTH:250};return{constants,};});'use strict';Polymer({is:'tr-ui-b-heading',DOWN_ARROW:String.fromCharCode(0x25BE),RIGHT_ARROW:String.fromCharCode(0x25B8),ready(viewport){this.style.width=(tr.ui.b.constants.HEADING_WIDTH-6)+'px';this.heading_='';this.expanded_=true;this.arrowVisible_=false;this.selectionGenerator_=undefined;this.updateContents_();},get heading(){return this.heading_;},set heading(text){if(this.heading_===text)return;this.heading_=text;this.updateContents_();},set arrowVisible(val){if(this.arrowVisible_===val)return;this.arrowVisible_=!!val;this.updateContents_();},set tooltip(text){this.$.heading.title=text;},set selectionGenerator(generator){if(this.selectionGenerator_===generator)return;this.selectionGenerator_=generator;this.updateContents_();},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=!!expanded;this.updateContents_();},onHeadingDivClicked_(){this.dispatchEvent(new tr.b.Event('heading-clicked',true));},updateContents_(){if(this.arrowVisible_){this.$.arrow.style.display='';}else{this.$.arrow.style.display='none';this.$.heading.style.display=this.expanded_?'':'none';}
 if(this.arrowVisible_){Polymer.dom(this.$.arrow).textContent=this.expanded_?this.DOWN_ARROW:this.RIGHT_ARROW;}
-this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;Polymer.dom(this.$.link).textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';Polymer.dom(this.$.heading_content).textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){var Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate:function(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined){throw new Error('viewport is required when creating a Track.');}
+this.$.link.style.display='none';this.$.heading_content.style.display='none';if(this.selectionGenerator_){this.$.link.style.display='inline-block';this.$.link.selection=this.selectionGenerator_;Polymer.dom(this.$.link).textContent=this.heading_;}else{this.$.heading_content.style.display='inline-block';Polymer.dom(this.$.heading_content).textContent=this.heading_;}}});'use strict';tr.exportTo('tr.ui.tracks',function(){const Track=tr.ui.b.define('track',tr.ui.b.ContainerThatDecoratesItsChildren);Track.prototype={__proto__:tr.ui.b.ContainerThatDecoratesItsChildren.prototype,decorate(viewport){tr.ui.b.ContainerThatDecoratesItsChildren.prototype.decorate.call(this);if(viewport===undefined){throw new Error('viewport is required when creating a Track.');}
 this.viewport_=viewport;Polymer.dom(this).classList.add('track');},get viewport(){return this.viewport_;},get drawingContainer(){if(this instanceof tr.ui.tracks.DrawingContainer)return this;let cur=this.parentElement;while(cur){if(cur instanceof tr.ui.tracks.DrawingContainer)return cur;cur=cur.parentElement;}
-return undefined;},get eventContainer(){},invalidateDrawingContainer:function(){var dc=this.drawingContainer;if(dc)dc.invalidate();},context:function(){if(!Polymer.dom(this).parentNode)return undefined;if(!Polymer.dom(this).parentNode.context){throw new Error('Parent container does not support context() method.');}
-return Polymer.dom(this).parentNode.context();},decorateChild_:function(childTrack){},undecorateChild_:function(childTrack){if(childTrack.detach){childTrack.detach();}},updateContents_:function(){},drawTrack:function(type){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw:function(type,viewLWorld,viewRWorld){},addEventsToTrackMap:function(eventToTrackMap){},addContainersToTrackMap:function(containerToTrackMap){},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loVY,hiVY,selection){var pixelRatio=window.devicePixelRatio||1;var dt=this.viewport.currentDisplayTransform;var viewPixWidthWorld=dt.xViewVectorToWorld(1);var loWX=dt.xViewToWorld(loVX*pixelRatio);var hiWX=dt.xViewToWorld(hiVX*pixelRatio);var clientRect=this.getBoundingClientRect();var a=Math.max(loVY,clientRect.top);var b=Math.min(hiVY,clientRect.bottom);if(a>b)return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection:function(instantEvents,worldX,worldMaxDist,selection){var instantEvent=tr.b.math.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)return;selection.push(instantEvent);}};return{Track,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var EventPresenter=tr.ui.b.EventPresenter;var ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length===0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
-this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=dt.xViewVectorToWorld(height);var loI;ctx.save();dt.applyTransformToCanvas(ctx);var objectInstances=this.objectInstances_;var loI=tr.b.math.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(var i=loI;i<objectInstances.length;++i){var instance=objectInstances[i];var x=instance.creationTs;if(x>viewRWorld)break;var right=instance.deletionTs===Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
-ctx.restore();var objectSnapshots=this.objectSnapshots_;loI=tr.b.math.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(var i=loI;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)break;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
-ctx.lineWidth=1;var selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
-if(selectionState===SelectionState.DIMMED){var width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap:function(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
-if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
-var snapshotRadiusView=this.snapshotRadiusView;var snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.math.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)return;tr.b.math.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,(value)=>{selection.push(value);});},addEventNearToProvidedEventToSelection:function(event,offset,selection){var events;if(event instanceof tr.model.ObjectSnapshot){events=this.objectSnapshots_;}else if(event instanceof tr.model.ObjectInstance){events=this.objectInstances_;}else{throw new Error('Unrecognized event');}
-var index=events.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.math.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap:function(eventToTrackMap){var objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
-var snapshots=this.objectInstance_.snapshots;var maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.math.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i===snapshots.length-1){if(snapshots.length===1){return maxBounds;}
+return undefined;},get eventContainer(){},invalidateDrawingContainer(){const dc=this.drawingContainer;if(dc)dc.invalidate();},context(){if(!Polymer.dom(this).parentNode)return undefined;if(!Polymer.dom(this).parentNode.context){throw new Error('Parent container does not support context() method.');}
+return Polymer.dom(this).parentNode.context();},decorateChild_(childTrack){},undecorateChild_(childTrack){if(childTrack.detach){childTrack.detach();}},updateContents_(){},drawTrack(type){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.draw(type,viewLWorld,viewRWorld);ctx.restore();},draw(type,viewLWorld,viewRWorld){},addEventsToTrackMap(eventToTrackMap){},addContainersToTrackMap(containerToTrackMap){},addIntersectingEventsInRangeToSelection(loVX,hiVX,loVY,hiVY,selection){const pixelRatio=window.devicePixelRatio||1;const dt=this.viewport.currentDisplayTransform;const viewPixWidthWorld=dt.xViewVectorToWorld(1);const loWX=dt.xViewToWorld(loVX*pixelRatio);const hiWX=dt.xViewToWorld(hiVX*pixelRatio);const clientRect=this.getBoundingClientRect();const a=Math.max(loVY,clientRect.top);const b=Math.min(hiVY,clientRect.bottom);if(a>b)return;this.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){},addClosestInstantEventToSelection(instantEvents,worldX,worldMaxDist,selection){const instantEvent=tr.b.math.findClosestElementInSortedArray(instantEvents,function(x){return x.start;},worldX,worldMaxDist);if(!instantEvent)return;selection.push(instantEvent);}};return{Track,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const EventPresenter=tr.ui.b.EventPresenter;const ObjectInstanceTrack=tr.ui.b.define('object-instance-track',tr.ui.tracks.Track);ObjectInstanceTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-track');this.objectInstances_=[];this.objectSnapshots_=[];this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get objectInstances(){return this.objectInstances_;},set objectInstances(objectInstances){if(!objectInstances||objectInstances.length===0){this.heading='';this.objectInstances_=[];this.objectSnapshots_=[];return;}
+this.heading=objectInstances[0].typeName;this.objectInstances_=objectInstances;this.objectSnapshots_=[];this.objectInstances_.forEach(function(instance){this.objectSnapshots_.push.apply(this.objectSnapshots_,instance.snapshots);},this);this.objectSnapshots_.sort(function(a,b){return a.ts-b.ts;});},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get snapshotRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const snapshotRadiusView=this.snapshotRadiusView;const snapshotRadiusWorld=dt.xViewVectorToWorld(height);ctx.save();dt.applyTransformToCanvas(ctx);const objectInstances=this.objectInstances_;let loI=tr.b.math.findLowIndexInSortedArray(objectInstances,function(instance){return instance.deletionTs;},viewLWorld);ctx.strokeStyle='rgb(0,0,0)';for(let i=loI;i<objectInstances.length;++i){const instance=objectInstances[i];const x=instance.creationTs;if(x>viewRWorld)break;const right=instance.deletionTs===Number.MAX_VALUE?viewRWorld:instance.deletionTs;ctx.fillStyle=EventPresenter.getObjectInstanceColor(instance);ctx.fillRect(x,pixelRatio,right-x,height-2*pixelRatio);}
+ctx.restore();const objectSnapshots=this.objectSnapshots_;loI=tr.b.math.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts+snapshotRadiusWorld;},viewLWorld);for(let i=loI;i<objectSnapshots.length;++i){const snapshot=objectSnapshots[i];const x=snapshot.ts;if(x-snapshotRadiusWorld>viewRWorld)break;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getObjectSnapshotColor(snapshot);ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView,0,twoPi);ctx.fill();if(snapshot.selected){ctx.lineWidth=5;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,snapshotRadiusView-1,0,twoPi);ctx.lineWidth=2;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}}
+ctx.lineWidth=1;let selectionState=SelectionState.NONE;if(objectInstances.length&&objectInstances[0].selectionState===SelectionState.DIMMED){selectionState=SelectionState.DIMMED;}
+if(selectionState===SelectionState.DIMMED){const width=bounds.width*pixelRatio;ctx.fillStyle='rgba(255,255,255,0.5)';ctx.fillRect(0,0,width,height);ctx.restore();}},addEventsToTrackMap(eventToTrackMap){if(this.objectInstance_!==undefined){this.objectInstance_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}
+if(this.objectSnapshots_!==undefined){this.objectSnapshots_.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){let foundSnapshot=false;function onSnapshot(snapshot){selection.push(snapshot);foundSnapshot=true;}
+const snapshotRadiusView=this.snapshotRadiusView;const snapshotRadiusWorld=viewPixWidthWorld*snapshotRadiusView;tr.b.math.iterateOverIntersectingIntervals(this.objectSnapshots_,function(x){return x.ts-snapshotRadiusWorld;},function(x){return 2*snapshotRadiusWorld;},loWX,hiWX,onSnapshot);if(foundSnapshot)return;tr.b.math.iterateOverIntersectingIntervals(this.objectInstances_,function(x){return x.creationTs;},function(x){return x.deletionTs-x.creationTs;},loWX,hiWX,(value)=>{selection.push(value);});},addEventNearToProvidedEventToSelection(event,offset,selection){let events;if(event instanceof tr.model.ObjectSnapshot){events=this.objectSnapshots_;}else if(event instanceof tr.model.ObjectInstance){events=this.objectInstances_;}else{throw new Error('Unrecognized event');}
+const index=events.indexOf(event);const newIndex=index+offset;if(newIndex>=0&&newIndex<events.length){selection.push(events[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const snapshot=tr.b.math.findClosestElementInSortedArray(this.objectSnapshots_,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ObjectInstanceTrack,options);return{ObjectInstanceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const StackedBarsTrack=tr.ui.b.define('stacked-bars-track',tr.ui.tracks.Track);StackedBarsTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('stacked-bars-track');this.objectInstance_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},addEventsToTrackMap(eventToTrackMap){const objectSnapshots=this.objectInstance_.snapshots;objectSnapshots.forEach(function(obj){eventToTrackMap.addEvent(obj,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onSnapshot(snapshot){selection.push(snapshot);}
+const snapshots=this.objectInstance_.snapshots;const maxBounds=this.objectInstance_.parent.model.bounds.max;tr.b.math.iterateOverIntersectingIntervals(snapshots,function(x){return x.ts;},function(x,i){if(i===snapshots.length-1){if(snapshots.length===1){return maxBounds;}
 return snapshots[i].ts-snapshots[i-1].ts;}
-return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot)){throw new Error('Unrecognized event');}
-var objectSnapshots=this.objectInstance_.snapshots;var index=objectSnapshots.indexOf(event);var newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var snapshot=tr.b.math.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};return{StackedBarsTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var EventPresenter=tr.ui.b.EventPresenter;var statCount;var excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};var SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate:function(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
+return snapshots[i+1].ts-snapshots[i].ts;},loWX,hiWX,onSnapshot);},addEventNearToProvidedEventToSelection(event,offset,selection){if(!(event instanceof tr.model.ObjectSnapshot)){throw new Error('Unrecognized event');}
+const objectSnapshots=this.objectInstance_.snapshots;const index=objectSnapshots.indexOf(event);const newIndex=index+offset;if(newIndex>=0&&newIndex<objectSnapshots.length){selection.push(objectSnapshots[newIndex]);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const snapshot=tr.b.math.findClosestElementInSortedArray(this.objectInstance_.snapshots,function(x){return x.ts;},worldX,worldMaxDist);if(!snapshot)return;selection.push(snapshot);}};return{StackedBarsTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){const EventPresenter=tr.ui.b.EventPresenter;let statCount;const excludedStats={'meminfo':{'pswpin':0,'pswpout':0,'pgmajfault':0},'diskinfo':{'io':0,'io_time':0,'read_time':0,'reads':0,'reads_merged':0,'sectors_read':0,'sectors_written':0,'weighted_io_time':0,'write_time':0,'writes':0,'writes_merged':0},'swapinfo':{}};const SystemStatsInstanceTrack=tr.ui.b.define('tr-ui-e-system-stats-instance-track',tr.ui.tracks.StackedBarsTrack);SystemStatsInstanceTrack.prototype={__proto__:tr.ui.tracks.StackedBarsTrack.prototype,decorate(viewport){tr.ui.tracks.StackedBarsTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('tr-ui-e-system-stats-instance-track');this.objectInstance_=null;},set objectInstances(objectInstances){if(!objectInstances){this.objectInstance_=[];return;}
 if(objectInstances.length!==1){throw new Error('Bad object instance count.');}
-this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_:function(snapshots){for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();var prevSnapshot;var prevStats;if(i===0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
-prevStats=prevSnapshot.getStats();var timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds===0){timeIntervalSeconds=1;}
-this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_:function(prevStats,stats,timeIntervalSeconds){for(var statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName==='sectors_read'){stats['bytes_read_per_sec']=(stats['sectors_read']-
-prevStats['sectors_read'])*512/timeIntervalSeconds;}
-if(statName==='sectors_written'){stats['bytes_written_per_sec']=(stats['sectors_written']-
-prevStats['sectors_written'])*512/timeIntervalSeconds;}
-if(statName==='pgmajfault'){stats['pgmajfault_per_sec']=(stats['pgmajfault']-
-prevStats['pgmajfault'])/timeIntervalSeconds;}
-if(statName==='pswpin'){stats['bytes_swpin_per_sec']=(stats['pswpin']-
-prevStats['pswpin'])*1000/timeIntervalSeconds;}
-if(statName==='pswpout'){stats['bytes_swpout_per_sec']=(stats['pswpout']-
-prevStats['pswpout'])*1000/timeIntervalSeconds;}}}},computeMaxStats_:function(snapshots){var maxStats={};statCount=0;for(var i=0;i<snapshots.length;i++){var snapshot=snapshots[i];var stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
-return maxStats;},computeMaxStatsRecursive_:function(stats,maxStats,excludedStats){for(var statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats)){maxStats[statName]={};}
-var excludedNested;if(excludedStats&&statName in excludedStats){excludedNested=excludedStats[statName];}else{excludedNested=null;}
+this.objectInstance_=objectInstances[0];if(this.objectInstance_!==null){this.computeRates_(this.objectInstance_.snapshots);this.maxStats_=this.computeMaxStats_(this.objectInstance_.snapshots);}},computeRates_(snapshots){for(let i=0;i<snapshots.length;i++){const snapshot=snapshots[i];const stats=snapshot.getStats();let prevSnapshot;if(i===0){prevSnapshot=snapshots[0];}else{prevSnapshot=snapshots[i-1];}
+const prevStats=prevSnapshot.getStats();let timeIntervalSeconds=(snapshot.ts-prevSnapshot.ts)/1000;if(timeIntervalSeconds===0){timeIntervalSeconds=1;}
+this.computeRatesRecursive_(prevStats,stats,timeIntervalSeconds);}},computeRatesRecursive_(prevStats,stats,timeIntervalSeconds){for(const statName in stats){if(stats[statName]instanceof Object){this.computeRatesRecursive_(prevStats[statName],stats[statName],timeIntervalSeconds);}else{if(statName==='sectors_read'){stats.bytes_read_per_sec=(stats.sectors_read-
+prevStats.sectors_read)*512/timeIntervalSeconds;}
+if(statName==='sectors_written'){stats.bytes_written_per_sec=(stats.sectors_written-
+prevStats.sectors_written)*512/timeIntervalSeconds;}
+if(statName==='pgmajfault'){stats.pgmajfault_per_sec=(stats.pgmajfault-
+prevStats.pgmajfault)/timeIntervalSeconds;}
+if(statName==='pswpin'){stats.bytes_swpin_per_sec=(stats.pswpin-
+prevStats.pswpin)*1000/timeIntervalSeconds;}
+if(statName==='pswpout'){stats.bytes_swpout_per_sec=(stats.pswpout-
+prevStats.pswpout)*1000/timeIntervalSeconds;}}}},computeMaxStats_(snapshots){const maxStats={};statCount=0;for(let i=0;i<snapshots.length;i++){const snapshot=snapshots[i];const stats=snapshot.getStats();this.computeMaxStatsRecursive_(stats,maxStats,excludedStats);}
+return maxStats;},computeMaxStatsRecursive_(stats,maxStats,excludedStats){for(const statName in stats){if(stats[statName]instanceof Object){if(!(statName in maxStats)){maxStats[statName]={};}
+let excludedNested;if(excludedStats&&statName in excludedStats){excludedNested=excludedStats[statName];}else{excludedNested=null;}
 this.computeMaxStatsRecursive_(stats[statName],maxStats[statName],excludedNested);}else{if(excludedStats&&statName in excludedStats){continue;}
 if(!(statName in maxStats)){maxStats[statName]=0;statCount++;}
-if(stats[statName]>maxStats[statName]){maxStats[statName]=stats[statName];}}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var width=bounds.width*pixelRatio;var height=(bounds.height*pixelRatio)/statCount;var vp=this.viewport.currentDisplayTransform;var maxStats=this.maxStats_;var objectSnapshots=this.objectInstance_.snapshots;var lowIndex=tr.b.math.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)lowIndex-=1;for(var i=lowIndex;i<objectSnapshots.length;++i){var snapshot=objectSnapshots[i];var trace=snapshot.getStats();var currentY=height;var left=snapshot.ts;if(left>viewRWorld)break;var leftView=vp.xWorldToView(left);if(leftView<0)leftView=0;var right;if(i!==objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1){right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
+if(stats[statName]>maxStats[statName]){maxStats[statName]=stats[statName];}}}},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawStatBars_(viewLWorld,viewRWorld);break;}},drawStatBars_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const width=bounds.width*pixelRatio;const height=(bounds.height*pixelRatio)/statCount;const vp=this.viewport.currentDisplayTransform;const maxStats=this.maxStats_;const objectSnapshots=this.objectInstance_.snapshots;let lowIndex=tr.b.math.findLowIndexInSortedArray(objectSnapshots,function(snapshot){return snapshot.ts;},viewLWorld);if(lowIndex>0)lowIndex-=1;for(let i=lowIndex;i<objectSnapshots.length;++i){const snapshot=objectSnapshots[i];const trace=snapshot.getStats();const currentY=height;const left=snapshot.ts;if(left>viewRWorld)break;let leftView=vp.xWorldToView(left);if(leftView<0)leftView=0;let right;if(i!==objectSnapshots.length-1){right=objectSnapshots[i+1].ts;}else{if(objectSnapshots.length>1){right=objectSnapshots[i].ts+(objectSnapshots[i].ts-
 objectSnapshots[i-1].ts);}else{right=this.objectInstance_.parent.model.bounds.max;}}
-var rightView=vp.xWorldToView(right);if(rightView>width){rightView=width;}
+let rightView=vp.xWorldToView(right);if(rightView>width){rightView=width;}
 leftView=Math.floor(leftView);rightView=Math.floor(rightView);this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,trace,maxStats,currentY);if(i===lowIndex){this.drawStatNames_(leftView,height,currentY,'',maxStats);}}
-ctx.lineWidth=1;},drawStatBarsRecursive_:function(snapshot,leftView,rightView,height,stats,maxStats,currentY){var ctx=this.context();for(var statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{var maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));var barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
+ctx.lineWidth=1;},drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats,maxStats,currentY){const ctx=this.context();for(const statName in maxStats){if(stats[statName]instanceof Object){currentY=this.drawStatBarsRecursive_(snapshot,leftView,rightView,height,stats[statName],maxStats[statName],currentY);}else{const maxStat=maxStats[statName];ctx.fillStyle=EventPresenter.getBarSnapshotColor(snapshot,Math.round(currentY/height));let barHeight;if(maxStat>0){barHeight=height*Math.max(stats[statName],0)/maxStat;}else{barHeight=0;}
 ctx.fillRect(leftView,currentY-barHeight,Math.max(rightView-leftView,1),barHeight);currentY+=height;}}
-return currentY;},drawStatNames_:function(leftView,height,currentY,prefix,maxStats){var ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(var statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{var fullname=statName;if(prefix!==''){fullname=prefix+' :: '+statName;}
+return currentY;},drawStatNames_(leftView,height,currentY,prefix,maxStats){const ctx=this.context();ctx.textAlign='end';ctx.font='12px Arial';ctx.fillStyle='#000000';for(const statName in maxStats){if(maxStats[statName]instanceof Object){currentY=this.drawStatNames_(leftView,height,currentY,statName,maxStats[statName]);}else{let fullname=statName;if(prefix!==''){fullname=prefix+' :: '+statName;}
 ctx.fillText(fullname,leftView-10,currentY-height/4);currentY+=height;}}
-return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){var SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate:function(){Polymer.dom(this).classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents:function(){var snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){Polymer.dom(this).textContent='No system stats snapshot found.';return;}
-Polymer.dom(this).textContent='';var stats=snapshot.getStats();Polymer.dom(this).appendChild(this.buildList_(stats));},isFloat:function(n){return typeof n==='number'&&n%1!==0;},buildList_:function(stats){var statList=document.createElement('ul');for(var statName in stats){var statText=document.createElement('li');Polymer.dom(statText).textContent=''+statName+': ';Polymer.dom(statList).appendChild(statText);if(stats[statName]instanceof Object){Polymer.dom(statList).appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName])){Polymer.dom(statText).textContent+=stats[statName].toFixed(2);}else{Polymer.dom(statText).textContent+=stats[statName];}}}
-return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){var InstanceTypeGroups={Rest:['ACCESSOR_INFO_TYPE','ACCESSOR_PAIR_TYPE','ACCESS_CHECK_INFO_TYPE','ALLOCATION_MEMENTO_TYPE','ALLOCATION_SITE_TYPE','CALL_HANDLER_INFO_TYPE','CELL_TYPE','FIXED_INT8_ARRAY_TYPE','FIXED_UINT8_ARRAY_TYPE','FIXED_UINT8_CLAMPED_ARRAY_TYPE','FIXED_INT16_ARRAY_TYPE','FIXED_UINT16_ARRAY_TYPE','FIXED_INT32_ARRAY_TYPE','FIXED_UINT32_ARRAY_TYPE','FIXED_FLOAT32_ARRAY_TYPE','FIXED_FLOAT64_ARRAY_TYPE','FIXED_DOUBLE_ARRAY_TYPE','FOREIGN_TYPE','FUNCTION_TEMPLATE_INFO_TYPE','HEAP_NUMBER_TYPE','INTERCEPTOR_INFO_TYPE','MUTABLE_HEAP_NUMBER_TYPE','OBJECT_TEMPLATE_INFO_TYPE','ODDBALL_TYPE','PROPERTY_CELL_TYPE','PROTOTYPE_INFO_TYPE','SCRIPT_TYPE','SYMBOL_TYPE','TRANSITION_ARRAY_TYPE','TYPE_FEEDBACK_INFO_TYPE'],Strings:['CONS_ONE_BYTE_STRING_TYPE','CONS_STRING_TYPE','EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE','EXTERNAL_ONE_BYTE_STRING_TYPE','EXTERNAL_INTERNALIZED_STRING_TYPE','EXTERNAL_STRING_TYPE','INTERNALIZED_STRING_TYPE','ONE_BYTE_INTERNALIZED_STRING_TYPE','ONE_BYTE_STRING_TYPE','SHORT_EXTERNAL_INTERNALIZED_STRING_TYPE','SHORT_EXTERNAL_ONE_BYTE_STRING_TYPE','SHORT_EXTERNAL_ONE_BYTE_INTERNALIZED_STRING_TYPE','SHORT_EXTERNAL_STRING_TYPE','SLICED_ONE_BYTE_STRING_TYPE','SLICED_STRING_TYPE','STRING_TYPE'],JS_OTHER:['JS_API_OBJECT_TYPE','JS_ARGUMENTS_TYPE','JS_ARRAY_BUFFER_TYPE','JS_ARRAY_TYPE','JS_BOUND_FUNCTION_TYPE','JS_ERROR_TYPE','JS_DATE_TYPE','JS_FUNCTION_TYPE','JS_GLOBAL_OBJECT_TYPE','JS_GLOBAL_PROXY_TYPE','JS_MAP_ITERATOR_TYPE','JS_MAP_TYPE','JS_MESSAGE_OBJECT_TYPE','JS_PROMISE_TYPE','JS_REGEXP_TYPE','JS_SPECIAL_API_OBJECT_TYPE','JS_TYPED_ARRAY_TYPE','JS_VALUE_TYPE','JS_WEAK_MAP_TYPE'],FIXED_ARRAY_TYPE:['*FIXED_ARRAY_CODE_STUBS_TABLE_SUB_TYPE','*FIXED_ARRAY_COMPILATION_CACHE_TABLE_SUB_TYPE','*FIXED_ARRAY_CONTEXT_SUB_TYPE','*FIXED_ARRAY_COPY_ON_WRITE_SUB_TYPE','*FIXED_ARRAY_DEOPTIMIZATION_DATA_SUB_TYPE','*FIXED_ARRAY_DESCRIPTOR_ARRAY_SUB_TYPE','*FIXED_ARRAY_EMBEDDED_OBJECT_SUB_TYPE','*FIXED_ARRAY_ENUM_CACHE_SUB_TYPE','*FIXED_ARRAY_ENUM_INDICES_CACHE_SUB_TYPE','*FIXED_ARRAY_DEPENDENT_CODE_SUB_TYPE','*FIXED_ARRAY_DICTIONARY_ELEMENTS_SUB_TYPE','*FIXED_ARRAY_DICTIONARY_PROPERTIES_SUB_TYPE','*FIXED_ARRAY_EMPTY_PROPERTIES_DICTIONARY_SUB_TYPE','*FIXED_ARRAY_FAST_ELEMENTS_SUB_TYPE','*FIXED_ARRAY_FAST_PROPERTIES_SUB_TYPE','*FIXED_ARRAY_HANDLER_TABLE_SUB_TYPE','*FIXED_ARRAY_INTRINSIC_FUNCTION_NAMES_SUB_TYPE','*FIXED_ARRAY_JS_COLLECTION_SUB_TYPE','*FIXED_ARRAY_JS_WEAK_COLLECTION_SUB_TYPE','*FIXED_ARRAY_LITERALS_ARRAY_SUB_TYPE','*FIXED_ARRAY_MAP_CODE_CACHE_SUB_TYPE','*FIXED_ARRAY_NOSCRIPT_SHARED_FUNCTION_INFOS_SUB_TYPE','*FIXED_ARRAY_NUMBER_STRING_CACHE_SUB_TYPE','*FIXED_ARRAY_OBJECT_TO_CODE_SUB_TYPE','*FIXED_ARRAY_OPTIMIZED_CODE_LITERALS_TUB_TYPE','*FIXED_ARRAY_OPTIMIZED_CODE_MAP_SUB_TYPE','*FIXED_ARRAY_PROTOTYPE_USERS_SUB_TYPE','*FIXED_ARRAY_REGEXP_MULTIPLE_CACHE_SUB_TYPE','*FIXED_ARRAY_RETAINED_MAPS_SUB_TYPE','*FIXED_ARRAY_SCOPE_INFO_SUB_TYPE','*FIXED_ARRAY_SCRIPT_LIST_SUB_TYPE','*FIXED_ARRAY_SERIALIZED_TEMPLATES_SUB_TYPE','*FIXED_ARRAY_SHARED_FUNCTION_INFOS_SUB_TYPE','*FIXED_ARRAY_SINGLE_CHARACTER_STRING_CACHE_SUB_TYPE','*FIXED_ARRAY_STRING_SPLIT_CACHE_SUB_TYPE','*FIXED_ARRAY_STRING_TABLE_SUB_TYPE','*FIXED_ARRAY_TEMPLATE_INFO_SUB_TYPE','*FIXED_ARRAY_TEMPLATE_INSTANTIATIONS_CACHE_SUB_TYPE','*FIXED_ARRAY_TYPE_FEEDBACK_VECTOR_SUB_TYPE','*FIXED_ARRAY_TYPE_FEEDBACK_METADATA_SUB_TYPE','*FIXED_ARRAY_WEAK_NEW_SPACE_OBJECT_TO_CODE_SUB_TYPE','*FIXED_ARRAY_UNKNOWN_SUB_TYPE'],CODE_TYPE:['*CODE_FUNCTION','*CODE_OPTIMIZED_FUNCTION','*CODE_BYTECODE_HANDLER','*CODE_STUB','*CODE_HANDLER','*CODE_BUILTIN','*CODE_REGEXP','*CODE_WASM_FUNCTION','*CODE_WASM_TO_JS_FUNCTION','*CODE_JS_TO_WASM_FUNCTION','*CODE_LOAD_IC','*CODE_LOAD_GLOBAL_IC','*CODE_KEYED_LOAD_IC','*CODE_CALL_IC','*CODE_STORE_IC','*CODE_KEYED_STORE_IC','*CODE_BINARY_OP_IC','*CODE_COMPARE_IC','*CODE_TO_BOOLEAN_IC'],CONTEXT_EXTENSION_TYPE:['CONTEXT_EXTENSION_TYPE'],MAP_TYPE:['MAP_TYPE'],BYTE_ARRAY_TYPE:['BYTE_ARRAY_TYPE'],SHARED_FUNCTION_INFO_TYPE:['SHARED_FUNCTION_INFO_TYPE'],WEAK_CELL_TYPE:['WEAK_CELL_TYPE'],JS_OBJECT_TYPE:['JS_OBJECT_TYPE'],JS_CONTEXT_EXTENSION_OBJECT_TYPE:['JS_CONTEXT_EXTENSION_OBJECT_TYPE']};var InstanceSubTypeNames={FIXED_ARRAY_TYPE:{keyToName:key=>key.slice('*FIXED_ARRAY_'.length).slice(0,-('_SUB_TYPE'.length)),nameToKey:name=>'*FIXED_ARRAY_'+name+'_SUB_TYPE'},CODE_TYPE:{keyToName:key=>key.slice('*CODE_'.length),nameToKey:name=>'*CODE_'+name},Strings:{keyToName:key=>key,nameToKey:name=>name},Rest:{keyToName:key=>key,nameToKey:name=>name},JS_OTHER:{keyToName:key=>key,nameToKey:name=>name}};var DIFF_COLOR={GREEN:'#64DD17',RED:'#D50000'};function computePercentage(valueA,valueB){if(valueA===0)return 0;return valueA/valueB*100;}
+return currentY;}};tr.ui.tracks.ObjectInstanceTrack.register(SystemStatsInstanceTrack,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsInstanceTrack,};});'use strict';tr.exportTo('tr.ui.e.system_stats',function(){const SystemStatsSnapshotView=tr.ui.b.define('tr-ui-e-system-stats-snapshot-view',tr.ui.analysis.ObjectSnapshotView);SystemStatsSnapshotView.prototype={__proto__:tr.ui.analysis.ObjectSnapshotView.prototype,decorate(){Polymer.dom(this).classList.add('tr-ui-e-system-stats-snapshot-view');},updateContents(){const snapshot=this.objectSnapshot_;if(!snapshot||!snapshot.getStats()){Polymer.dom(this).textContent='No system stats snapshot found.';return;}
+Polymer.dom(this).textContent='';const stats=snapshot.getStats();Polymer.dom(this).appendChild(this.buildList_(stats));},isFloat(n){return typeof n==='number'&&n%1!==0;},buildList_(stats){const statList=document.createElement('ul');for(const statName in stats){const statText=document.createElement('li');Polymer.dom(statText).textContent=''+statName+': ';Polymer.dom(statList).appendChild(statText);if(stats[statName]instanceof Object){Polymer.dom(statList).appendChild(this.buildList_(stats[statName]));}else{if(this.isFloat(stats[statName])){Polymer.dom(statText).textContent+=stats[statName].toFixed(2);}else{Polymer.dom(statText).textContent+=stats[statName];}}}
+return statList;}};tr.ui.analysis.ObjectSnapshotView.register(SystemStatsSnapshotView,{typeName:'base::TraceEventSystemStatsMonitor::SystemStats'});return{SystemStatsSnapshotView,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const IGNORED_ENTRIES={match:full=>full.startsWith('*CODE_AGE_')};const INSTANCE_TYPE_GROUPS={FIXED_ARRAY_TYPE:{match:full=>full.startsWith('*FIXED_ARRAY_'),realEntry:'FIXED_ARRAY_TYPE',keyToName:key=>key.slice('*FIXED_ARRAY_'.length).slice(0,-('_SUB_TYPE'.length)),nameToKey:name=>'*FIXED_ARRAY_'+name+'_SUB_TYPE'},CODE_TYPE:{match:full=>full.startsWith('*CODE_'),realEntry:'CODE_TYPE',keyToName:key=>key.slice('*CODE_'.length),nameToKey:name=>'*CODE_'+name},JS_OBJECTS:{match:full=>full.startsWith('JS_'),keyToName:key=>key,nameToKey:name=>name},Strings:{match:full=>full.endsWith('STRING_TYPE'),keyToName:key=>key,nameToKey:name=>name}};const DIFF_COLOR={GREEN:'#64DD17',RED:'#D50000'};function computePercentage(valueA,valueB){if(valueA===0)return 0;return valueA/valueB*100;}
 class DiffEntry{constructor(originalEntry,diffEntry){this.originalEntry_=originalEntry;this.diffEntry_=diffEntry;}
 get title(){return this.diffEntry_.title;}
 get overall(){return this.diffEntry_.overall;}
@@ -7573,41 +7923,41 @@
 get overAllocatedPercent(){return this.overAllocatedPercent_;}
 set overAllocatedPercent(value){this.overAllocatedPercent_=value;}
 setFromObject(obj){this.count_=obj.count;this.overall_=obj.overall/1024;this.overAllocated_=obj.over_allocated/1024;this.histogram_=obj.histogram;this.overAllocatedHistogram_=obj.over_allocated_histogram;}
-diff(other){var entry=new Entry(this.title_,other.count_-this.count,other.overall_-this.overall,other.overAllocated_-this.overAllocated,[],[]);entry.overallPercent=computePercentage(entry.overall,this.overall);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated);return new DiffEntry(this,entry);}}
+diff(other){const entry=new Entry(this.title_,other.count_-this.count,other.overall_-this.overall,other.overAllocated_-this.overAllocated,[],[]);entry.overallPercent=computePercentage(entry.overall,this.overall);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated);return new DiffEntry(this,entry);}}
 class GroupedEntry extends Entry{constructor(title,count,overall,overAllocated,histogram,overAllocatedHistogram){super(title,count,overall,overAllocated,histogram,overAllocatedHistogram);this.histogram_.fill(0);this.overAllocatedHistogram_.fill(0);this.entries_=new Map();}
 get title(){return this.title_;}
 set title(value){this.title_=value;}
 get subRows(){return Array.from(this.entries_.values());}
 getEntryFromTitle(title){return this.entries_.get(title);}
-add(entry){this.count_+=entry.count;this.overall_+=entry.overall;this.overAllocated_+=entry.overAllocated;if(this.bucketSize_===entry.bucketSize){for(var i=0;i<this.bucketSize_;++i){this.histogram_[i]+=entry.histogram[i];this.overAllocatedHistogram_[i]+=entry.overAllocatedHistogram[i];}}
+add(entry){this.count_+=entry.count;this.overall_+=entry.overall;this.overAllocated_+=entry.overAllocated;if(this.bucketSize_===entry.bucketSize){for(let i=0;i<this.bucketSize_;++i){this.histogram_[i]+=entry.histogram[i];this.overAllocatedHistogram_[i]+=entry.overAllocatedHistogram[i];}}
 this.entries_.set(entry.title,entry);}
-accumulateUnknown(title){var unknownCount=this.count_;var unknownOverall=this.overall_;var unknownOverAllocated=this.overAllocated_;var unknownHistogram=tr.b.deepCopy(this.histogram_);var unknownOverAllocatedHistogram=tr.b.deepCopy(this.overAllocatedHistogram_);for(var entry of this.entries_.values()){unknownCount-=entry.count;unknownOverall-=entry.overall;unknownOverAllocated-=entry.overAllocated;for(var i=0;i<this.bucketSize_;++i){unknownHistogram[i]-=entry.histogram[i];unknownOverAllocatedHistogram[i]-=entry.overAllocatedHistogram[i];}}
+accumulateUnknown(title){let unknownCount=this.count_;let unknownOverall=this.overall_;let unknownOverAllocated=this.overAllocated_;const unknownHistogram=tr.b.deepCopy(this.histogram_);const unknownOverAllocatedHistogram=tr.b.deepCopy(this.overAllocatedHistogram_);for(const entry of this.entries_.values()){unknownCount-=entry.count;unknownOverall-=entry.overall;unknownOverAllocated-=entry.overAllocated;for(let i=0;i<this.bucketSize_;++i){unknownHistogram[i]-=entry.histogram[i];unknownOverAllocatedHistogram[i]-=entry.overAllocatedHistogram[i];}}
 unknownOverAllocated=unknownOverAllocated<0?0:unknownOverAllocated;this.entries_.set(title,new Entry(title,unknownCount,unknownOverall,unknownOverAllocated,unknownHistogram,unknownOverAllocatedHistogram));}
-calculatePercentage(){for(var entry of this.entries_.values()){entry.overallPercent=computePercentage(entry.overall,this.overall_);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated_);if(entry instanceof GroupedEntry)entry.calculatePercentage();}}
-diff(other){if(this.title_.startsWith('Isolate')){var newTitle='Total';}else{var newTitle=this.title_;}
-var result=new GroupedEntry(newTitle,0,0,0,[],[]);for(var entry of this.entries_){var otherEntry=other.getEntryFromTitle(entry[0]);if(otherEntry===undefined)continue;result.add(entry[1].diff(otherEntry));}
+calculatePercentage(){for(const entry of this.entries_.values()){entry.overallPercent=computePercentage(entry.overall,this.overall_);entry.overAllocatedPercent=computePercentage(entry.overAllocated,this.overAllocated_);if(entry instanceof GroupedEntry)entry.calculatePercentage();}}
+diff(other){let newTitle='';if(this.title_.startsWith('Isolate')){newTitle='Total';}else{newTitle=this.title_;}
+const result=new GroupedEntry(newTitle,0,0,0,[],[]);for(const entry of this.entries_){const otherEntry=other.getEntryFromTitle(entry[0]);if(otherEntry===undefined)continue;result.add(entry[1].diff(otherEntry));}
 result.overallPercent=computePercentage(result.overall,this.overall);result.overAllocatedPercent=computePercentage(result.overAllocated,this.overAllocated);return new DiffEntry(this,result);}}
-function createSelector(targetEl,defaultValue,items,callback){var selectorEl=document.createElement('select');selectorEl.addEventListener('change',callback.bind(targetEl));var defaultOptionEl=document.createElement('option');for(var i=0;i<items.length;i++){var item=items[i];var optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
+function createSelector(targetEl,defaultValue,items,callback){const selectorEl=document.createElement('select');selectorEl.addEventListener('change',callback.bind(targetEl));const defaultOptionEl=document.createElement('option');for(let i=0;i<items.length;i++){const item=items[i];const optionEl=document.createElement('option');Polymer.dom(optionEl).textContent=item.label;optionEl.targetPropertyValue=item.value;optionEl.item=item;Polymer.dom(selectorEl).appendChild(optionEl);}
 selectorEl.__defineGetter__('selectedValue',function(v){if(selectorEl.children[selectorEl.selectedIndex]===undefined){return undefined;}
 return selectorEl.children[selectorEl.selectedIndex].targetPropertyValue;});selectorEl.__defineGetter__('selectedItem',function(v){if(selectorEl.children[selectorEl.selectedIndex]===undefined){return undefined;}
-return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(var i=0;i<selectorEl.children.length;i++){var value=selectorEl.children[i].targetPropertyValue;if(value===v){var changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;callback();}
+return selectorEl.children[selectorEl.selectedIndex].item;});selectorEl.__defineSetter__('selectedValue',function(v){for(let i=0;i<selectorEl.children.length;i++){const value=selectorEl.children[i].targetPropertyValue;if(value===v){const changed=selectorEl.selectedIndex!==i;if(changed){selectorEl.selectedIndex=i;callback();}
 return;}}
 throw new Error('Not a valid value');});selectorEl.selectedIndex=-1;return selectorEl;}
 function plusMinus(value,toFixed=3){return(value>0?'+':'')+value.toFixed(toFixed);}
 function addArrow(value){if(value===0)return value;if(value===Number.NEGATIVE_INFINITY)return'\u2193\u221E';if(value===Number.POSITIVE_INFINITY)return'\u2191\u221E';return(value>0?'\u2191':'\u2193')+Math.abs(value.toFixed(3));}
-Polymer({is:'tr-ui-e-v8-gc-objects-stats-table',ready:function(){this.$.diffOption.style.display='none';this.isolateEntries_=[];this.selector1_=undefined;this.selector2_=undefined;},constructDiffTable_:function(table){this.$.diffTable.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.diffTable.tableColumns=[{title:'Component',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory(KB)',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overall.toFixed(3);return spanEl;},cmp:function(a,b){return a.origin.overall-b.origin.overall;}},{title:'diff(KB)',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overall);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
-return spanEl;},cmp:function(a,b){return a.overall-b.overall;}},{title:'diff(%)',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overallPercent);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
-return spanEl;},cmp:function(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory(KB)',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overAllocated.toFixed(3);return spanEl;},cmp:function(a,b){return a.origin.overAllocated-b.origin.overAllocated;}},{title:'diff(KB)',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overAllocated);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
-return spanEl;},cmp:function(a,b){return a.overAllocated-b.overAllocated;}},{title:'diff(%)',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overAllocatedPercent);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
-return spanEl;},cmp:function(a,b){return a.overAllocated-b.overAllocated;}},{title:'Count',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.count;return spanEl;},cmp:function(a,b){return a.origin.count-b.origin.count;}},{title:'diff',value:function(row){var spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.count,0);if(row.count>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.count<0){spanEl.style.color=DIFF_COLOR.GREEN;}
-return spanEl;},cmp:function(a,b){return a.count-b.count;}},];},buildOptions_:function(){var items=[];for(var isolateEntry of this.isolateEntries_){items.push({label:isolateEntry.title,value:isolateEntry});}
-this.$.diffOption.style.display='inline-block';this.selector1_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector1_);var spanEl=tr.ui.b.createSpan();spanEl.innerText=' VS ';Polymer.dom(this.$.diffOption).appendChild(spanEl);this.selector2_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector2_);},diffOptionChanged_:function(){var isolateEntry1=this.selector1_.selectedValue;var isolateEntry2=this.selector2_.selectedValue;if(isolateEntry1===undefined||isolateEntry2===undefined){return;}
+Polymer({is:'tr-ui-e-v8-gc-objects-stats-table',ready(){this.$.diffOption.style.display='none';this.isolateEntries_=[];this.selector1_=undefined;this.selector2_=undefined;},constructDiffTable_(table){this.$.diffTable.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.diffTable.tableColumns=[{title:'Component',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overall.toFixed(3);return spanEl;},cmp(a,b){return a.origin.overall-b.origin.overall;}},{title:'diff(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overall);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overall-b.overall;}},{title:'diff(%)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overallPercent);if(row.overall>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overall<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.overAllocated.toFixed(3);return spanEl;},cmp(a,b){return a.origin.overAllocated-b.origin.overAllocated;}},{title:'diff(KB)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.overAllocated);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'diff(%)',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=addArrow(row.overAllocatedPercent);if(row.overAllocated>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.overAllocated<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'Count',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=row.origin.count;return spanEl;},cmp(a,b){return a.origin.count-b.origin.count;}},{title:'diff',value(row){const spanEl=tr.ui.b.createSpan();spanEl.innerText=plusMinus(row.count,0);if(row.count>0){spanEl.style.color=DIFF_COLOR.RED;}else if(row.count<0){spanEl.style.color=DIFF_COLOR.GREEN;}
+return spanEl;},cmp(a,b){return a.count-b.count;}},];},buildOptions_(){const items=[];for(const isolateEntry of this.isolateEntries_){items.push({label:isolateEntry.title,value:isolateEntry});}
+this.$.diffOption.style.display='inline-block';this.selector1_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector1_);const spanEl=tr.ui.b.createSpan();spanEl.innerText=' VS ';Polymer.dom(this.$.diffOption).appendChild(spanEl);this.selector2_=createSelector(this,'',items,this.diffOptionChanged_);Polymer.dom(this.$.diffOption).appendChild(this.selector2_);},diffOptionChanged_(){const isolateEntry1=this.selector1_.selectedValue;const isolateEntry2=this.selector2_.selectedValue;if(isolateEntry1===undefined||isolateEntry2===undefined){return;}
 if(isolateEntry1===isolateEntry2){this.$.diffTable.tableRows=[];this.$.diffTable.rebuild();return;}
-this.$.diffTable.tableRows=[isolateEntry1.diff(isolateEntry2)];this.$.diffTable.rebuild();},constructTable_:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=[{title:'Component',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory (KB)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.overall.toFixed(3);return typeEl;},cmp:function(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory (KB)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.overAllocated.toFixed(3);return typeEl;},cmp:function(a,b){return a.overAllocated-b.overAllocated;}},{title:'Overall Count',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},cmp:function(a,b){return a.count-b.count;}},{title:'Overall Memory Percent',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.overallPercent.toFixed(3)+'%';return typeEl;},cmp:function(a,b){return a.overall-b.overall;}},{title:'Overall Allocated Memory Percent',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.overAllocatedPercent.toFixed(3)+'%';return typeEl;},cmp:function(a,b){return a.overAllocated-b.overAllocated;}}];this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;},buildSubEntry_:function(objects,groupEntry,keyToName){var typeGroup=InstanceTypeGroups[groupEntry.title];for(var instanceType of typeGroup){var e=objects[instanceType];delete objects[instanceType];if(e===undefined)continue;var title=instanceType;if(keyToName!==undefined)title=keyToName(title);groupEntry.add(new Entry(title,e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));}},buildOthers_:function(objects,groupEntry){for(var title of Object.getOwnPropertyNames(objects)){if(title==='END')continue;var obj=objects[title];groupEntry.add(new Entry(title,obj.count,obj.overall,obj.over_allocated,obj.histogram,obj.over_allocated_histogram));}},build_:function(objects,objectEntry,bucketSize){var fixedArrayObject=objects['FIXED_ARRAY_TYPE'];if(fixedArrayObject===undefined){throw new Error('Fixed Array Object not found.');}
-var groupEntries={restEntry:new GroupedEntry('Rest',0,0,0,new Array(bucketSize),new Array(bucketSize)),stringEntry:new GroupedEntry('Strings',0,0,0,new Array(bucketSize),new Array(bucketSize)),jsEntry:new GroupedEntry('JS_OTHER',0,0,0,new Array(bucketSize),new Array(bucketSize)),fixedArrayEntry:new GroupedEntry('FIXED_ARRAY_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),codeEntry:new GroupedEntry('CODE_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),contextExtensionEntry:new GroupedEntry('CONTEXT_EXTENSION_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),mapEntry:new GroupedEntry('MAP_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),byteArrayEntry:new GroupedEntry('BYTE_ARRAY_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),sharedFunctionInfoEntry:new GroupedEntry('SHARED_FUNCTION_INFO_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),weakCellEntry:new GroupedEntry('WEAK_CELL_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),jsObjectEntry:new GroupedEntry('JS_OBJECT_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize)),jsContextExtensionObjectEntry:new GroupedEntry('JS_CONTEXT_EXTENSION_OBJECT_TYPE',0,0,0,new Array(bucketSize),new Array(bucketSize))};for(var name of Object.getOwnPropertyNames(groupEntries)){var groupEntry=groupEntries[name];var keyToName=undefined;if(InstanceSubTypeNames[groupEntry.title]!==undefined){keyToName=InstanceSubTypeNames[groupEntry.title].keyToName;}
-this.buildSubEntry_(objects,groupEntry,keyToName);if(name==='fixedArrayEntry'){groupEntry.setFromObject(fixedArrayObject);groupEntry.accumulateUnknown('UNKNOWN');}
-objectEntry.add(groupEntry);}},set selection(slices){slices.sortEvents(function(a,b){return b.start-a.start;});var previous=undefined;for(let slice of slices){if(!slice instanceof tr.e.v8.V8GCStatsThreadSlice)continue;var liveObjects=slice.liveObjects;var deadObjects=slice.deadObjects;var isolate=liveObjects.isolate;var isolateEntry=new GroupedEntry('Isolate_'+isolate+' at '+slice.start.toFixed(3)+' ms',0,0,0,[],[]);var liveEntry=new GroupedEntry('live objects',0,0,0,[],[]);var deadEntry=new GroupedEntry('dead objects',0,0,0,[],[]);var liveBucketSize=liveObjects.bucket_sizes.length;var deadBucketSize=deadObjects.bucket_sizes.length;this.build_(tr.b.deepCopy(liveObjects.type_data),liveEntry,liveBucketSize);isolateEntry.add(liveEntry);this.build_(tr.b.deepCopy(deadObjects.type_data),deadEntry,deadBucketSize);isolateEntry.add(deadEntry);isolateEntry.calculatePercentage();this.isolateEntries_.push(isolateEntry);}
-this.updateTable_();if(slices.length>1){this.buildOptions_();this.constructDiffTable_();}},updateTable_:function(){this.constructTable_();this.$.table.tableRows=this.isolateEntries_;this.$.table.rebuild();},});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:true,title:'V8 GC Stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){var IC_STATS_PROPERTIES=['type','category','scriptName','filePosition','state','isNative','map','propertiesMode','numberOfOwnProperties','instanceType'];class ICStatsEntry{constructor(obj){this.type_=obj.type;if(this.type_.includes('Store')){this.category_='Store';}else if(this.type_.includes('Load')){this.category_='Load';}
+this.$.diffTable.tableRows=[isolateEntry1.diff(isolateEntry2)];this.$.diffTable.rebuild();},constructTable_(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.tableColumns=[{title:'Component',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.title;return typeEl;},showExpandButtons:true},{title:'Overall Memory (KB)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overall.toFixed(3);return typeEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Over Allocated Memory (KB)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overAllocated.toFixed(3);return typeEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}},{title:'Overall Count',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},cmp(a,b){return a.count-b.count;}},{title:'Overall Memory Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overallPercent.toFixed(3)+'%';return typeEl;},cmp(a,b){return a.overall-b.overall;}},{title:'Overall Allocated Memory Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.overAllocatedPercent.toFixed(3)+'%';return typeEl;},cmp(a,b){return a.overAllocated-b.overAllocated;}}];this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;},buildSubEntry_(objects,groupEntry,keyToName){const typeGroup=INSTANCE_TYPE_GROUPS[groupEntry.title];for(const instanceType of typeGroup){const e=objects[instanceType];if(e===undefined)continue;delete objects[instanceType];let title=instanceType;if(keyToName!==undefined)title=keyToName(title);groupEntry.add(new Entry(title,e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));}},buildUnGroupedEntries_(objects,objectEntry,bucketSize){for(const title of Object.getOwnPropertyNames(objects)){const obj=objects[title];const groupedEntry=new GroupedEntry(title,0,0,0,new Array(bucketSize),new Array(bucketSize));groupedEntry.setFromObject(obj);objectEntry.add(groupedEntry);}},createGroupEntries_(groupEntries,objects,bucketSize){for(const groupName of Object.getOwnPropertyNames(INSTANCE_TYPE_GROUPS)){const groupEntry=new GroupedEntry(groupName,0,0,0,new Array(bucketSize),new Array(bucketSize));if(INSTANCE_TYPE_GROUPS[groupName].realEntry!==undefined){groupEntry.savedRealEntry=objects[INSTANCE_TYPE_GROUPS[groupName].realEntry];delete objects[INSTANCE_TYPE_GROUPS[groupName].realEntry];}
+groupEntries[groupName]=groupEntry;}},buildGroupEntries_(groupEntries,objectEntry){for(const groupName of Object.getOwnPropertyNames(groupEntries)){const groupEntry=groupEntries[groupName];if(groupEntry.savedRealEntry!==undefined){groupEntry.setFromObject(groupEntry.savedRealEntry);groupEntry.accumulateUnknown('UNKNOWN');delete groupEntry.savedRealEntry;}
+objectEntry.add(groupEntry);}},buildSubEntriesForGroups_(groupEntries,objects){for(const instanceType of Object.getOwnPropertyNames(objects)){if(IGNORED_ENTRIES.match(instanceType)){delete objects[instanceType];continue;}
+const e=objects[instanceType];for(const name of Object.getOwnPropertyNames(INSTANCE_TYPE_GROUPS)){const group=INSTANCE_TYPE_GROUPS[name];if(group.match(instanceType)){groupEntries[name].add(new Entry(group.keyToName(instanceType),e.count,e.overall/1024,e.over_allocated/1024,e.histogram,e.over_allocated_histogram));delete objects[instanceType];}}}},build_(objects,objectEntry,bucketSize){delete objects.END;const groupEntries={};this.createGroupEntries_(groupEntries,objects,bucketSize);this.buildSubEntriesForGroups_(groupEntries,objects);this.buildGroupEntries_(groupEntries,objectEntry);this.buildUnGroupedEntries_(objects,objectEntry,bucketSize);},set selection(slices){slices.sortEvents(function(a,b){return b.start-a.start;});const previous=undefined;for(const slice of slices){if(!slice instanceof tr.e.v8.V8GCStatsThreadSlice)continue;const liveObjects=slice.liveObjects;const deadObjects=slice.deadObjects;const isolate=liveObjects.isolate;const isolateEntry=new GroupedEntry('Isolate_'+isolate+' at '+slice.start.toFixed(3)+' ms',0,0,0,[],[]);const liveEntry=new GroupedEntry('live objects',0,0,0,[],[]);const deadEntry=new GroupedEntry('dead objects',0,0,0,[],[]);const liveBucketSize=liveObjects.bucket_sizes.length;const deadBucketSize=deadObjects.bucket_sizes.length;this.build_(tr.b.deepCopy(liveObjects.type_data),liveEntry,liveBucketSize);isolateEntry.add(liveEntry);this.build_(tr.b.deepCopy(deadObjects.type_data),deadEntry,deadBucketSize);isolateEntry.add(deadEntry);isolateEntry.calculatePercentage();this.isolateEntries_.push(isolateEntry);}
+this.updateTable_();if(slices.length>1){this.buildOptions_();this.constructDiffTable_();}},updateTable_(){this.constructTable_();this.$.table.tableRows=this.isolateEntries_;this.$.table.rebuild();},});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:true,title:'V8 GC Stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){const IC_STATS_PROPERTIES=['type','category','scriptName','filePosition','state','isNative','map','propertiesMode','numberOfOwnProperties','instanceType'];class ICStatsEntry{constructor(obj){this.type_=obj.type;if(this.type_.includes('Store')){this.category_='Store';}else if(this.type_.includes('Load')){this.category_='Load';}
 this.state_=obj.state;if(obj.functionName){this.functionName_=obj.optimized?'*':'~';this.functionName_+=obj.functionName.length===0?'(anonymous function)':obj.functionName;}
 this.offset_=obj.offset;this.scriptName_=obj.scriptName?obj.scriptName:'unknown';this.isNative_=obj.scriptName&&obj.scriptName.includes('native');this.lineNum_=obj.lineNum?obj.lineNum:'unknown';this.filePosition_=this.scriptName_+':'+this.lineNum_;if(this.functionName_){this.filePosition_+=' '+this.functionName_+'+'+this.offset_;}
 this.constructor_=obj.constructor?false:true;this.map_=obj.map;if(this.map_){this.propertiesMode_=obj.dict===0?'slow':'fast';}else{this.propertiesMode_='unknown';}
@@ -7627,11 +7977,11 @@
 get instanceType(){return this.instanceType_;}
 get filePosition(){return this.filePosition_;}}
 class ICStatsEntryGroup{constructor(property,key){this.property_=property;this.key_=key;this.percentage_=0;this.entries_=[];this.subGroup_=undefined;}
-static groupBy(groups,entries,property){for(let entry of entries){let key=entry[property];let group=groups.get(key);if(!group){group=new ICStatsEntryGroup(property,key);groups.set(key,group);}
+static groupBy(groups,entries,property){for(const entry of entries){const key=entry[property];let group=groups.get(key);if(!group){group=new ICStatsEntryGroup(property,key);groups.set(key,group);}
 group.add(entry);}
-for(let group of groups.values()){group.percentage=group.length/entries.length;}}
+for(const group of groups.values()){group.percentage=group.length/entries.length;}}
 add(entry){this.entries_.push(entry);}
-createSubGroup(){if(this.subGroup_)return this.subGroup_;this.subGroup_=new Map();for(let property of IC_STATS_PROPERTIES){if(property===this.property_)continue;var groups=new Map();this.subGroup_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);}
+createSubGroup(){if(this.subGroup_)return this.subGroup_;this.subGroup_=new Map();for(const property of IC_STATS_PROPERTIES){if(property===this.property_)continue;const groups=new Map();this.subGroup_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);}
 return this.subGroup_;}
 get entries(){return this.entries_;}
 get key(){return this.key_;}
@@ -7641,12 +7991,12 @@
 class ICStatsCollection{constructor(){this.entries_=[];this.groupedEntries_=new Map();}
 add(entry){this.entries_.push(entry);}
 groupBy(property){if(this.groupedEntries_.has(property)){return Array.from(this.groupedEntries_.get(property).values());}
-var groups=new Map();this.groupedEntries_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);return Array.from(groups.values());}
+const groups=new Map();this.groupedEntries_.set(property,groups);ICStatsEntryGroup.groupBy(groups,this.entries_,property);return Array.from(groups.values());}
 get entries(){return this.entries_;}
 get length(){return this.entries_.length;}}
-return{IC_STATS_PROPERTIES,ICStatsEntry,ICStatsEntryGroup,ICStatsCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){var PROPERTIES=tr.e.v8.IC_STATS_PROPERTIES.map(x=>{return{label:x,value:x};});var ICStatsEntry=tr.e.v8.ICStatsEntry;var ICStatsEntryGroup=tr.e.v8.ICStatsEntryGroup;var ICStatsCollection=tr.e.v8.ICStatsCollection;Polymer({is:'tr-ui-e-v8-ic-stats-table',ready:function(){this.icStatsCollection_=new ICStatsCollection();this.groupKey_=PROPERTIES[0].value;this.selector_=tr.ui.b.createSelector(this,'groupKey','v8ICStatsGroupKey',this.groupKey_,PROPERTIES);Polymer.dom(this.$.groupOption).appendChild(this.selector_);},get groupKey(){return this.groupKey_;},set groupKey(key){this.groupKey_=key;if(this.icStatsCollection_.length===0)return;this.updateTable_(this.groupKey_);},constructTable_:function(table,groupKey){table.tableColumns=[{title:'',value:row=>{let expanded=false;let buttonEl=tr.ui.b.createButton('details',function(){let previousSibling=Polymer.dom(this).parentNode.parentNode;let parentNode=previousSibling.parentNode;if(expanded){let trEls=parentNode.getElementsByClassName('subTable');Array.from(trEls).map(x=>x.parentNode.removeChild(x));expanded=false;return;}
-expanded=true;let subGroups=row.createSubGroup();let tr=document.createElement('tr');tr.classList.add('subTable');tr.appendChild(document.createElement('td'));let td=document.createElement('td');td.colSpan=3;for(let subGroup of subGroups){let property=subGroup[0];let all=Array.from(subGroup[1].values());let group=all.slice(0,20);let divEl=document.createElement('div');let spanEl=document.createElement('span');let subTableEl=document.createElement('tr-ui-b-table');spanEl.innerText=`Top 20 out of ${all.length}`;spanEl.style.fontWeight='bold';spanEl.style.fontSize='14px';divEl.appendChild(spanEl);this.constructTable_(subTableEl,property);subTableEl.tableRows=group;subTableEl.rebuild();divEl.appendChild(subTableEl);td.appendChild(divEl);}
-tr.appendChild(td);parentNode.insertBefore(tr,previousSibling.nextSibling);});return buttonEl;}},{title:'Percentage',value:function(row){let spanEl=document.createElement('span');spanEl.innerText=(row.percentage*100).toFixed(3)+'%';return spanEl;},cmp:(a,b)=>a.percentage-b.percentage},{title:'Count',value:function(row){let spanEl=document.createElement('span');spanEl.innerText=row.length;return spanEl;},cmp:(a,b)=>a.length-b.length},{title:groupKey,value:function(row){let spanEl=document.createElement('span');spanEl.innerText=row.key?row.key:'';return spanEl;}}];table.sortColumnIndex=1;table.sortDescending=true;},updateTable_:function(groupKey){this.constructTable_(this.$.table,groupKey);this.$.table.tableRows=this.icStatsCollection_.groupBy(groupKey);this.$.table.rebuild();},set selection(slices){for(let slice of slices){for(let icStatsObj of slice.icStats){let entry=new ICStatsEntry(icStatsObj);this.icStatsCollection_.add(entry);}}
+return{IC_STATS_PROPERTIES,ICStatsEntry,ICStatsEntryGroup,ICStatsCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){const PROPERTIES=tr.e.v8.IC_STATS_PROPERTIES.map(x=>{return{label:x,value:x};});const ICStatsEntry=tr.e.v8.ICStatsEntry;const ICStatsEntryGroup=tr.e.v8.ICStatsEntryGroup;const ICStatsCollection=tr.e.v8.ICStatsCollection;Polymer({is:'tr-ui-e-v8-ic-stats-table',ready(){this.icStatsCollection_=new ICStatsCollection();this.groupKey_=PROPERTIES[0].value;this.selector_=tr.ui.b.createSelector(this,'groupKey','v8ICStatsGroupKey',this.groupKey_,PROPERTIES);Polymer.dom(this.$.groupOption).appendChild(this.selector_);},get groupKey(){return this.groupKey_;},set groupKey(key){this.groupKey_=key;if(this.icStatsCollection_.length===0)return;this.updateTable_(this.groupKey_);},constructTable_(table,groupKey){table.tableColumns=[{title:'',value:row=>{let expanded=false;const buttonEl=tr.ui.b.createButton('details',function(){const previousSibling=Polymer.dom(this).parentNode.parentNode;const parentNode=previousSibling.parentNode;if(expanded){const trEls=parentNode.getElementsByClassName('subTable');Array.from(trEls).map(x=>x.parentNode.removeChild(x));expanded=false;return;}
+expanded=true;const subGroups=row.createSubGroup();const tr=document.createElement('tr');tr.classList.add('subTable');tr.appendChild(document.createElement('td'));const td=document.createElement('td');td.colSpan=3;for(const subGroup of subGroups){const property=subGroup[0];const all=Array.from(subGroup[1].values());const group=all.slice(0,20);const divEl=document.createElement('div');const spanEl=document.createElement('span');const subTableEl=document.createElement('tr-ui-b-table');spanEl.innerText=`Top 20 out of ${all.length}`;spanEl.style.fontWeight='bold';spanEl.style.fontSize='14px';divEl.appendChild(spanEl);this.constructTable_(subTableEl,property);subTableEl.tableRows=group;subTableEl.rebuild();divEl.appendChild(subTableEl);td.appendChild(divEl);}
+tr.appendChild(td);parentNode.insertBefore(tr,previousSibling.nextSibling);});return buttonEl;}},{title:'Percentage',value(row){const spanEl=document.createElement('span');spanEl.innerText=(row.percentage*100).toFixed(3)+'%';return spanEl;},cmp:(a,b)=>a.percentage-b.percentage},{title:'Count',value(row){const spanEl=document.createElement('span');spanEl.innerText=row.length;return spanEl;},cmp:(a,b)=>a.length-b.length},{title:groupKey,value(row){const spanEl=document.createElement('span');spanEl.innerText=row.key?row.key:'';return spanEl;}}];table.sortColumnIndex=1;table.sortDescending=true;},updateTable_(groupKey){this.constructTable_(this.$.table,groupKey);this.$.table.tableRows=this.icStatsCollection_.groupBy(groupKey);this.$.table.rebuild();},set selection(slices){for(const slice of slices){for(const icStatsObj of slice.icStats){const entry=new ICStatsEntry(icStatsObj);this.icStatsCollection_.add(entry);}}
 this.$.total.innerText='Total items: '+this.icStatsCollection_.length;this.updateTable_(this.selector_.selectedValue);}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:true,title:'V8 IC stats slices'});'use strict';tr.exportTo('tr.e.v8',function(){class RuntimeStatsEntry{constructor(name,count,time){this.name_=name;this.count_=count;this.time_=time;}
 get name(){return this.name_;}
 get count(){return this.count_;}
@@ -7654,20 +8004,21 @@
 addSample(count,time){this.count_+=count;this.time_+=time;}}
 class RuntimeStatsGroup extends RuntimeStatsEntry{constructor(name,matchRegex){super(name,0,0);this.regex_=matchRegex;this.entries_=new Map();}
 match(name){return this.regex_&&name.match(this.regex_);}
-add(entry){var value=this.entries_.get(entry.name);if(value!==undefined){value.addSample(entry.count,entry.time);}else{this.entries_.set(entry.name,entry);}
+add(entry){const value=this.entries_.get(entry.name);if(value!==undefined){value.addSample(entry.count,entry.time);}else{this.entries_.set(entry.name,entry);}
 this.count_+=entry.count;this.time_+=entry.time;}
 get values(){return Array.from(this.entries_.values());}}
 class RuntimeStatsGroupCollection{constructor(){this.groups_=[new RuntimeStatsGroup('Total'),new RuntimeStatsGroup('IC',/.*IC_.*/),new RuntimeStatsGroup('Optimize',/StackGuard|.*Optimize.*|.*Deoptimize.*|Recompile.*/),new RuntimeStatsGroup('Compile-Background',/(.*CompileBackground.*)/),new RuntimeStatsGroup('Compile',/(^Compile.*)|(.*_Compile.*)/),new RuntimeStatsGroup('Parse-Background',/.*ParseBackground.*/),new RuntimeStatsGroup('Parse',/.*Parse.*/),new RuntimeStatsGroup('Blink C++',/.*Callback.*/),new RuntimeStatsGroup('API',/.*API.*/),new RuntimeStatsGroup('GC',/GC|AllocateInTargetSpace/),new RuntimeStatsGroup('JavaScript',/JS_Execution/),new RuntimeStatsGroup('V8 C++',/.*/)];}
-addSlices(slices){for(var slice of slices){if(!(slice instanceof tr.e.v8.V8ThreadSlice))return;try{var runtimeCallStats=JSON.parse(slice.runtimeCallStats);}catch(e){var runtimeCallStats=slice.runtimeCallStats;}
-if(runtimeCallStats===undefined)continue;for(var[name,stat]of Object.entries(runtimeCallStats)){for(var i=1;i<this.groups_.length;++i){if(this.groups_[i].match(name)){if(stat.length!==2)break;var entry=new RuntimeStatsEntry(name,stat[0],stat[1]);this.groups_[0].addSample(stat[0],stat[1]);this.groups_[i].add(entry);break;}}}}}
+addSlices(slices){for(const slice of slices){if(!(slice instanceof tr.e.v8.V8ThreadSlice))return;let runtimeCallStats;try{runtimeCallStats=JSON.parse(slice.runtimeCallStats);}catch(e){runtimeCallStats=slice.runtimeCallStats;}
+if(runtimeCallStats===undefined)continue;for(const[name,stat]of Object.entries(runtimeCallStats)){for(let i=1;i<this.groups_.length;++i){if(this.groups_[i].match(name)){if(stat.length!==2)break;const entry=new RuntimeStatsEntry(name,stat[0],stat[1]);this.groups_[0].addSample(stat[0],stat[1]);this.groups_[i].add(entry);break;}}}}}
 get totalTime(){return this.groups_[0].time;}
+get totalCount(){return this.groups_[0].count;}
 get runtimeGroups(){return this.groups_;}}
-return{RuntimeStatsEntry,RuntimeStatsGroup,RuntimeStatsGroupCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){function handleCodeSearch_(event){if(event.target.parentNode===undefined)return;var name=event.target.parentNode.entryName;var url='https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=';if(name.startsWith('API_'))name=name.substring(4);url+=encodeURIComponent(name)+'+file:src/v8/src';window.open(url,'_blank');}
-Polymer({is:'tr-ui-e-v8-runtime-call-stats-table',ready:function(){this.table_=this.$.table;this.totalTime_=0;},constructTable_:function(totalTime){this.table_.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.table_.tableColumns=[{title:'Name',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.name;if(!(row instanceof tr.e.v8.RuntimeStatsGroup)){typeEl.title='click ? for code search';typeEl.entryName=row.name;var codeSearchEl=document.createElement('span');codeSearchEl.innerText='?';codeSearchEl.style.float='right';codeSearchEl.style.borderRadius='5px';codeSearchEl.style.backgroundColor='#EEE';codeSearchEl.addEventListener('click',handleCodeSearch_.bind(this));typeEl.appendChild(codeSearchEl);}
-return typeEl;},width:'200px',showExpandButtons:true},{title:'Time',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=(row.time/1000.0).toFixed(3)+' ms';return typeEl;},width:'100px',cmp:function(a,b){return a.time-b.time;}},{title:'Count',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},width:'100px',cmp:function(a,b){return a.count-b.count;}},{title:'Percent',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=(row.time/totalTime*100).toFixed(3)+'%';return typeEl;},width:'100px',cmp:function(a,b){return a.time-b.time;}}];this.table_.sortColumnIndex=1;this.table_.sortDescending=true;this.table_.subRowsPropertyName='values';},set slices(slices){var runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);if(runtimeGroupCollection.totalTime>0){this.constructTable_(runtimeGroupCollection.totalTime);this.table_.tableRows=runtimeGroupCollection.runtimeGroups;this.table_.rebuild();}}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:true,title:'V8 slices'});'use strict';Polymer({is:'tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:false,title:'V8 GC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:false,title:'V8 IC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:false,title:'V8 slice'});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
-ScriptingObject.prototype={onModelChanged:function(model){}};return{ScriptingObject,};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));var typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
+return{RuntimeStatsEntry,RuntimeStatsGroup,RuntimeStatsGroupCollection,};});'use strict';tr.exportTo('tr.ui.e.v8',function(){function handleCodeSearch_(event){if(event.target.parentNode===undefined)return;let name=event.target.parentNode.entryName;let url='https://cs.chromium.org/search/?sq=package:chromium&type=cs&q=';if(name.startsWith('API_'))name=name.substring(4);url+=encodeURIComponent(name)+'+file:src/v8/src';window.open(url,'_blank');}
+Polymer({is:'tr-ui-e-v8-runtime-call-stats-table',ready(){this.table_=this.$.table;this.totalTime_=0;},constructTable_(totalTime){this.table_.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.table_.tableColumns=[{title:'Name',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.name;if(!(row instanceof tr.e.v8.RuntimeStatsGroup)){typeEl.title='click ? for code search';typeEl.entryName=row.name;const codeSearchEl=document.createElement('span');codeSearchEl.innerText='?';codeSearchEl.style.float='right';codeSearchEl.style.borderRadius='5px';codeSearchEl.style.backgroundColor='#EEE';codeSearchEl.addEventListener('click',handleCodeSearch_.bind(this));typeEl.appendChild(codeSearchEl);}
+return typeEl;},width:'200px',showExpandButtons:true},{title:'Time',value(row){const typeEl=document.createElement('span');typeEl.innerText=(row.time/1000.0).toFixed(3)+' ms';return typeEl;},width:'100px',cmp(a,b){return a.time-b.time;}},{title:'Count',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.count;return typeEl;},width:'100px',cmp(a,b){return a.count-b.count;}},{title:'Percent',value(row){const typeEl=document.createElement('span');typeEl.innerText=(row.time/totalTime*100).toFixed(3)+'%';return typeEl;},width:'100px',cmp(a,b){return a.time-b.time;}}];this.table_.sortColumnIndex=1;this.table_.sortDescending=true;this.table_.subRowsPropertyName='values';},set slices(slices){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);if(runtimeGroupCollection.totalTime>0){this.constructTable_(runtimeGroupCollection.totalTime);this.table_.tableRows=runtimeGroupCollection.runtimeGroups;this.table_.rebuild();}}});return{};});'use strict';Polymer({is:'tr-ui-e-multi-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-multi-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:true,title:'V8 slices'});'use strict';Polymer({is:'tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.gcObjectsStats.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-gc-stats-thread-slice-sub-view',tr.e.v8.V8GCStatsThreadSlice,{multi:false,title:'V8 GC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.table.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-ic-stats-thread-slice-sub-view',tr.e.v8.V8ICStatsThreadSlice,{multi:false,title:'V8 IC stats slice'});'use strict';Polymer({is:'tr-ui-e-single-v8-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.runtimeCallStats.slices=selection;this.$.content.selection=selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-e-single-v8-thread-slice-sub-view',tr.e.v8.V8ThreadSlice,{multi:false,title:'V8 slice'});'use strict';tr.exportTo('tr.c',function(){function ScriptingObject(){}
+ScriptingObject.prototype={onModelChanged(model){}};return{ScriptingObject,};});'use strict';tr.exportTo('tr.c',function(){function ScriptingController(brushingStateController){this.brushingStateController_=brushingStateController;this.scriptObjectNames_=[];this.scriptObjectValues_=[];this.brushingStateController.addEventListener('model-changed',this.onModelChanged_.bind(this));const typeInfos=ScriptingObjectRegistry.getAllRegisteredTypeInfos();typeInfos.forEach(function(typeInfo){this.addScriptObject(typeInfo.metadata.name,typeInfo.constructor);global[typeInfo.metadata.name]=typeInfo.constructor;},this);}
 function ScriptingObjectRegistry(){}
-var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_:function(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged){v.onModelChanged(this.brushingStateController.model);}},this);},addScriptObject:function(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand:function(command){var f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController,ScriptingObjectRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(ScriptingObjectRegistry,options);ScriptingController.prototype={get brushingStateController(){return this.brushingStateController_;},onModelChanged_(){this.scriptObjectValues_.forEach(function(v){if(v.onModelChanged){v.onModelChanged(this.brushingStateController.model);}},this);},addScriptObject(name,value){this.scriptObjectNames_.push(name);this.scriptObjectValues_.push(value);},executeCommand(command){const f=new Function(this.scriptObjectNames_,'return eval('+command+')');return f.apply(null,this.scriptObjectValues_);}};return{ScriptingController,ScriptingObjectRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function MetricRegistry(){}
 const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};tr.b.decorateExtensionRegistry(MetricRegistry,options);function camelCaseToHackerString(camelCase){let hackerString='';for(const c of camelCase){const lowered=c.toLocaleLowerCase();if(lowered===c){hackerString+=c;}else{hackerString+='_'+lowered;}}
 return hackerString;}
 function getCallStack(){try{throw new Error();}catch(error){return error.stack;}}
@@ -7676,36 +8027,36 @@
 const expectedFilename=camelCaseToHackerString(metricName)+'.html';const stack=getCallStack();let metricPath=opt_metricPathForTest;if(metricPath===undefined){const paths=getPathsFromStack(stack);const METRIC_STACK_INDEX=5;if(paths.length<=METRIC_STACK_INDEX||paths[METRIC_STACK_INDEX].join('/')===paths[0].join('/')){return;}
 metricPath=paths[METRIC_STACK_INDEX].slice(paths[METRIC_STACK_INDEX].length-2);}
 if(!metricPath[1].endsWith('_test.html')&&metricPath[1]!==expectedFilename&&metricPath.join('_')!==expectedFilename){throw new Error('Expected '+metricName+' to be in a file named '+
-expectedFilename+'; actual: '+metricPath.join('/')+'; stack: '+stack.replace(/\n/g,'\n  '));}};MetricRegistry.addEventListener('will-register',function(e){let metric=e.typeInfo.constructor;if(!(metric instanceof Function)){throw new Error('Metrics must be functions.');}
+expectedFilename+'; actual: '+metricPath.join('/')+'; stack: '+stack.replace(/\n/g,'\n  '));}};MetricRegistry.addEventListener('will-register',function(e){const metric=e.typeInfo.constructor;if(!(metric instanceof Function)){throw new Error('Metrics must be functions.');}
 if(!metric.name.endsWith('Metric')&&!metric.name.endsWith('Metrics')){throw new Error('Metric names must end with "Metric" or "Metrics".');}
 if(metric.length<2){throw new Error('Metrics take a HistogramSet and a Model and '+'optionally an options dictionary.');}
-MetricRegistry.checkFilename(metric.name);});return{MetricRegistry,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS=2000;const MIN_DRAW_DELAY_IN_MS=80;const MAX_DRAW_DELAY_IN_MS=2000;function findProcess(processName,model){for(var pid in model.processes){var process=model.processes[pid];if(process.name===processName){return process;}}
+MetricRegistry.checkFilename(metric.name);});return{MetricRegistry,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS=2000;const MIN_DRAW_DELAY_IN_MS=80;const MAX_DRAW_DELAY_IN_MS=2000;function findProcess(processName,model){for(const pid in model.processes){const process=model.processes[pid];if(process.name===processName){return process;}}
 return undefined;}
-function findThreads(process,threadPrefix){if(process===undefined)return undefined;var threads=[];for(var tid in process.threads){var thread=process.threads[tid];if(thread.name.startsWith(threadPrefix)){threads.push(thread);}}
+function findThreads(process,threadPrefix){if(process===undefined)return undefined;const threads=[];for(const tid in process.threads){const thread=process.threads[tid];if(thread.name.startsWith(threadPrefix)){threads.push(thread);}}
 return threads;}
-function findUIThread(process){if(process===undefined)return undefined;var threads=findThreads(process,'UI Thread');if(threads!==undefined&&threads.length===1){return threads[0];}
+function findUIThread(process){if(process===undefined)return undefined;const threads=findThreads(process,'UI Thread');if(threads!==undefined&&threads.length===1){return threads[0];}
 return process.threads[process.pid];}
-function findLaunchSlices(model){var launches=[];var binders=findThreads(findProcess('system_server',model),'Binder');for(var binderId in binders){var binder=binders[binderId];for(var sliceId in binder.asyncSliceGroup.slices){var slice=binder.asyncSliceGroup.slices[sliceId];if(slice.title.startsWith('launching:')){launches.push(slice);}}}
+function findLaunchSlices(model){const launches=[];const binders=findThreads(findProcess('system_server',model),'Binder');for(const binderId in binders){const binder=binders[binderId];for(const sliceId in binder.asyncSliceGroup.slices){const slice=binder.asyncSliceGroup.slices[sliceId];if(slice.title.startsWith('launching:')){launches.push(slice);}}}
 return launches;}
-function findDrawSlice(appName,startNotBefore,model){var drawSlice=undefined;var thread=findUIThread(findProcess(appName,model));if(thread===undefined)return undefined;for(var sliceId in thread.sliceGroup.slices){var slice=thread.sliceGroup.slices[sliceId];if(slice.start<startNotBefore+MIN_DRAW_DELAY_IN_MS||slice.start>startNotBefore+MAX_DRAW_DELAY_IN_MS)continue;if(slice.title!=='draw')continue;if(drawSlice===undefined||slice.start<drawSlice.start){drawSlice=slice;}}
+function findDrawSlice(appName,startNotBefore,model){let drawSlice=undefined;const thread=findUIThread(findProcess(appName,model));if(thread===undefined)return undefined;for(const sliceId in thread.sliceGroup.slices){const slice=thread.sliceGroup.slices[sliceId];if(slice.start<startNotBefore+MIN_DRAW_DELAY_IN_MS||slice.start>startNotBefore+MAX_DRAW_DELAY_IN_MS)continue;if(slice.title!=='draw')continue;if(drawSlice===undefined||slice.start<drawSlice.start){drawSlice=slice;}}
 return drawSlice;}
-function findInputEventSlice(endNotAfter,model){var endNotBefore=endNotAfter-MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS;var inputSlice=undefined;var systemUi=findUIThread(findProcess('com.android.systemui',model));if(systemUi===undefined)return undefined;for(var sliceId in systemUi.asyncSliceGroup.slices){var slice=systemUi.asyncSliceGroup.slices[sliceId];if(slice.end>endNotAfter||slice.end<endNotBefore)continue;if(slice.title!=='deliverInputEvent')continue;if(inputSlice===undefined||slice.end>inputSlice.end){inputSlice=slice;}}
+function findInputEventSlice(endNotAfter,model){const endNotBefore=endNotAfter-MAX_INPUT_EVENT_TO_STARTUP_DELAY_IN_MS;let inputSlice=undefined;const systemUi=findUIThread(findProcess('com.android.systemui',model));if(systemUi===undefined)return undefined;for(const sliceId in systemUi.asyncSliceGroup.slices){const slice=systemUi.asyncSliceGroup.slices[sliceId];if(slice.end>endNotAfter||slice.end<endNotBefore)continue;if(slice.title!=='deliverInputEvent')continue;if(inputSlice===undefined||slice.end>inputSlice.end){inputSlice=slice;}}
 return inputSlice;}
-function computeStartupTimeInMs(appName,launchSlice,model){var startupStart=launchSlice.start;var startupEnd=launchSlice.end;var drawSlice=findDrawSlice(appName,launchSlice.end,model);if(drawSlice!==undefined){startupEnd=drawSlice.end;}
-var inputSlice=findInputEventSlice(launchSlice.start,model);if(inputSlice!==undefined){startupStart=inputSlice.start;}
+function computeStartupTimeInMs(appName,launchSlice,model){let startupStart=launchSlice.start;let startupEnd=launchSlice.end;const drawSlice=findDrawSlice(appName,launchSlice.end,model);if(drawSlice!==undefined){startupEnd=drawSlice.end;}
+const inputSlice=findInputEventSlice(launchSlice.start,model);if(inputSlice!==undefined){startupStart=inputSlice.start;}
 return startupEnd-startupStart;}
-function measureStartup(values,model){var launches=findLaunchSlices(model);for(var sliceId in launches){var launchSlice=launches[sliceId];var appName=launchSlice.title.split(': ')[1];var startupMs=computeStartupTimeInMs(appName,launchSlice,model);var hist=new tr.v.Histogram('android:systrace:startup:'+appName,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);hist.addSample(startupMs);values.addHistogram(hist);}}
-function measureThreadStates(values,model,rangeOfInterest){var addHistogram=function(processName,timerName,valueInMs,rangeInMs){var hist=new tr.v.Histogram('android:systrace:threadtime:'+processName+':'+timerName,tr.b.Unit.byName.normalizedPercentage);hist.addSample(valueInMs/rangeInMs);values.addHistogram(hist);};for(var pid in model.processes){var process=model.processes[pid];if(process.name===undefined)continue;var hasSlices=false;var timeRunning=0;var timeRunnable=0;var timeSleeping=0;var timeUninterruptible=0;var timeBlockIO=0;var timeUnknown=0;for(var tid in process.threads){var thread=process.threads[tid];if(thread.timeSlices===undefined)continue;for(var sliceId in thread.timeSlices){var slice=thread.timeSlices[sliceId];var sliceRange=tr.b.Range.fromExplicitRange(slice.start,slice.end);var intersection=rangeOfInterest.findIntersection(sliceRange);var duration=intersection.duration;if(duration===0)continue;hasSlices=true;if(slice.title==='Running'){timeRunning+=duration;}else if(slice.title==='Runnable'){timeRunnable+=duration;}else if(slice.title==='Sleeping'){timeSleeping+=duration;}else if(slice.title.startsWith('Uninterruptible')){timeUninterruptible+=duration;if(slice.title.includes('Block I/O'))timeBlockIO+=duration;}else{timeUnknown+=duration;}}}
-if(hasSlices){var wall=rangeOfInterest.max-rangeOfInterest.min;addHistogram(process.name,'running',timeRunning,wall);addHistogram(process.name,'runnable',timeRunnable,wall);addHistogram(process.name,'sleeping',timeSleeping,wall);addHistogram(process.name,'blockio',timeBlockIO,wall);addHistogram(process.name,'uninterruptible',timeUninterruptible,wall);if(timeUnknown>0){addHistogram(process.name,'unknown',timeUnknown,wall);}}}}
-function androidSystraceMetric(values,model,options){var rangeOfInterest=model.bounds;if(options!==undefined&&options.rangeOfInterest!==undefined){rangeOfInterest=options.rangeOfInterest;}
-measureStartup(values,model);measureThreadStates(values,model,rangeOfInterest);}
-tr.metrics.MetricRegistry.register(androidSystraceMetric,{supportsRangeOfInterest:true});return{androidSystraceMetric,};});'use strict';tr.exportTo('tr.b.math',function(){var PERCENTILE_PRECISION=1e-7;function PiecewiseLinearFunction(){this.pieces=[];}
-PiecewiseLinearFunction.prototype={push:function(x1,y1,x2,y2){if(x1>=x2){throw new Error('Invalid segment');}
+function measureStartup(histograms,model){const launches=findLaunchSlices(model);for(const sliceId in launches){const launchSlice=launches[sliceId];const appName=launchSlice.title.split(': ')[1];const startupMs=computeStartupTimeInMs(appName,launchSlice,model);histograms.createHistogram(`android:systrace:startup:${appName}`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,startupMs);}}
+function measureThreadStates(histograms,model,rangeOfInterest){for(const pid in model.processes){const process=model.processes[pid];if(process.name===undefined)continue;let hasSlices=false;let timeRunning=0;let timeRunnable=0;let timeSleeping=0;let timeUninterruptible=0;let timeBlockIO=0;let timeUnknown=0;for(const tid in process.threads){const thread=process.threads[tid];if(thread.timeSlices===undefined)continue;for(const sliceId in thread.timeSlices){const slice=thread.timeSlices[sliceId];const sliceRange=tr.b.math.Range.fromExplicitRange(slice.start,slice.end);const intersection=rangeOfInterest.findIntersection(sliceRange);const duration=intersection.duration;if(duration===0)continue;hasSlices=true;if(slice.title==='Running'){timeRunning+=duration;}else if(slice.title==='Runnable'){timeRunnable+=duration;}else if(slice.title==='Sleeping'){timeSleeping+=duration;}else if(slice.title.startsWith('Uninterruptible')){timeUninterruptible+=duration;if(slice.title.includes('Block I/O'))timeBlockIO+=duration;}else{timeUnknown+=duration;}}}
+if(hasSlices){const wall=rangeOfInterest.max-rangeOfInterest.min;histograms.createHistogram(`android:systrace:threadtime:${process.name}:running`,tr.b.Unit.byName.normalizedPercentage,timeRunning/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:runnable`,tr.b.Unit.byName.normalizedPercentage,timeRunnable/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:sleeping`,tr.b.Unit.byName.normalizedPercentage,timeSleeping/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:blockio`,tr.b.Unit.byName.normalizedPercentage,timeBlockIO/wall);histograms.createHistogram(`android:systrace:threadtime:${process.name}:uninterruptible`,tr.b.Unit.byName.normalizedPercentage,timeUninterruptible/wall);if(timeUnknown>0){histograms.createHistogram(`android:systrace:threadtime:${process.name}:unknown`,tr.b.Unit.byName.normalizedPercentage,timeUnknown/wall);}}}}
+function androidSystraceMetric(histograms,model,options){let rangeOfInterest=model.bounds;if(options!==undefined&&options.rangeOfInterest!==undefined){rangeOfInterest=options.rangeOfInterest;}
+measureStartup(histograms,model);measureThreadStates(histograms,model,rangeOfInterest);}
+tr.metrics.MetricRegistry.register(androidSystraceMetric,{supportsRangeOfInterest:true});return{androidSystraceMetric,};});'use strict';tr.exportTo('tr.b.math',function(){const PERCENTILE_PRECISION=1e-7;function PiecewiseLinearFunction(){this.pieces=[];}
+PiecewiseLinearFunction.prototype={push(x1,y1,x2,y2){if(x1>=x2){throw new Error('Invalid segment');}
 if(this.pieces.length>0&&this.pieces[this.pieces.length-1].x2>x1){throw new Error('Potentially overlapping segments');}
-if(x1<x2){this.pieces.push(new Piece(x1,y1,x2,y2));}},partBelow:function(y){return this.pieces.reduce((acc,p)=>(acc+p.partBelow(y)),0);},get min(){return this.pieces.reduce((acc,p)=>Math.min(acc,p.min),Infinity);},get max(){return this.pieces.reduce((acc,p)=>Math.max(acc,p.max),-Infinity);},get average(){var weightedSum=0;var totalWeight=0;this.pieces.forEach(function(piece){weightedSum+=piece.width*piece.average;totalWeight+=piece.width;});if(totalWeight===0)return 0;return weightedSum/totalWeight;},percentile:function(percent){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
-var lower=this.min;var upper=this.max;var total=this.partBelow(upper);if(total===0)return 0;while(upper-lower>PERCENTILE_PRECISION){var middle=(lower+upper)/2;var below=this.partBelow(middle);if(below/total<percent){lower=middle;}else{upper=middle;}}
+if(x1<x2){this.pieces.push(new Piece(x1,y1,x2,y2));}},partBelow(y){return this.pieces.reduce((acc,p)=>(acc+p.partBelow(y)),0);},get min(){return this.pieces.reduce((acc,p)=>Math.min(acc,p.min),Infinity);},get max(){return this.pieces.reduce((acc,p)=>Math.max(acc,p.max),-Infinity);},get average(){let weightedSum=0;let totalWeight=0;this.pieces.forEach(function(piece){weightedSum+=piece.width*piece.average;totalWeight+=piece.width;});if(totalWeight===0)return 0;return weightedSum/totalWeight;},percentile(percent){if(!(percent>=0&&percent<=1)){throw new Error('percent must be [0,1]');}
+let lower=this.min;let upper=this.max;const total=this.partBelow(upper);if(total===0)return 0;while(upper-lower>PERCENTILE_PRECISION){const middle=(lower+upper)/2;const below=this.partBelow(middle);if(below/total<percent){lower=middle;}else{upper=middle;}}
 return(lower+upper)/2;}};function Piece(x1,y1,x2,y2){this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;}
-Piece.prototype={partBelow:function(y){var width=this.width;if(width===0)return 0;var minY=this.min;var maxY=this.max;if(y>=maxY)return width;if(y<minY)return 0;return(y-minY)/(maxY-minY)*width;},get min(){return Math.min(this.y1,this.y2);},get max(){return Math.max(this.y1,this.y2);},get average(){return(this.y1+this.y2)/2;},get width(){return this.x2-this.x1;}};return{PiecewiseLinearFunction,};});'use strict';tr.exportTo('tr.metrics.v8.utils',function(){var IDLE_TASK_EVENT='SingleThreadIdleTaskRunner::RunTask';var V8_EXECUTE='V8.Execute';var GC_EVENT_PREFIX='V8.GC';var FULL_GC_EVENT='V8.GCCompactor';var LOW_MEMORY_EVENT='V8.GCLowMemoryNotification';var MAJOR_GC_EVENT='MajorGC';var MINOR_GC_EVENT='MinorGC';var TOP_GC_EVENTS={'V8.GCCompactor':'v8-gc-full-mark-compactor','V8.GCFinalizeMC':'v8-gc-latency-mark-compactor','V8.GCFinalizeMCReduceMemory':'v8-gc-memory-mark-compactor','V8.GCIncrementalMarking':'v8-gc-incremental-step','V8.GCIncrementalMarkingFinalize':'v8-gc-incremental-finalize','V8.GCIncrementalMarkingStart':'v8-gc-incremental-start','V8.GCPhantomHandleProcessingCallback':'v8-gc-phantom-handle-callback','V8.GCScavenger':'v8-gc-scavenger'};var LOW_MEMORY_MARK_COMPACTOR='v8-gc-low-memory-mark-compactor';function findParent(event,predicate){var parent=event.parentSlice;while(parent){if(predicate(parent)){return parent;}
+Piece.prototype={partBelow(y){const width=this.width;if(width===0)return 0;const minY=this.min;const maxY=this.max;if(y>=maxY)return width;if(y<minY)return 0;return(y-minY)/(maxY-minY)*width;},get min(){return Math.min(this.y1,this.y2);},get max(){return Math.max(this.y1,this.y2);},get average(){return(this.y1+this.y2)/2;},get width(){return this.x2-this.x1;}};return{PiecewiseLinearFunction,};});'use strict';tr.exportTo('tr.metrics.v8.utils',function(){const IDLE_TASK_EVENT='SingleThreadIdleTaskRunner::RunTask';const V8_EXECUTE='V8.Execute';const GC_EVENT_PREFIX='V8.GC';const FULL_GC_EVENT='V8.GCCompactor';const LOW_MEMORY_EVENT='V8.GCLowMemoryNotification';const MAJOR_GC_EVENT='MajorGC';const MINOR_GC_EVENT='MinorGC';const TOP_GC_EVENTS={'V8.GCCompactor':'v8-gc-full-mark-compactor','V8.GCFinalizeMC':'v8-gc-latency-mark-compactor','V8.GCFinalizeMCReduceMemory':'v8-gc-memory-mark-compactor','V8.GCIncrementalMarking':'v8-gc-incremental-step','V8.GCIncrementalMarkingFinalize':'v8-gc-incremental-finalize','V8.GCIncrementalMarkingStart':'v8-gc-incremental-start','V8.GCPhantomHandleProcessingCallback':'v8-gc-phantom-handle-callback','V8.GCScavenger':'v8-gc-scavenger'};const LOW_MEMORY_MARK_COMPACTOR='v8-gc-low-memory-mark-compactor';function findParent(event,predicate){let parent=event.parentSlice;while(parent){if(predicate(parent)){return parent;}
 parent=parent.parentSlice;}
 return null;}
 function isIdleTask(event){return event.title===IDLE_TASK_EVENT;}
@@ -7717,6 +8068,9 @@
 function isTopGarbageCollectionEvent(event){return event.title in TOP_GC_EVENTS;}
 function isForcedGarbageCollectionEvent(event){return findParent(event,isLowMemoryEvent)!==null;}
 function isSubGarbageCollectionEvent(event){return isGarbageCollectionEvent(event)&&event.parentSlice&&(isTopGarbageCollectionEvent(event.parentSlice)||event.parentSlice.title===MAJOR_GC_EVENT||event.parentSlice.title===MINOR_GC_EVENT);}
+function isCompileOptimizeEvent(event){return(event.title==='V8.OptimizeCode'||event.title==='V8.RecompileSynchronous'||event.title==='V8.RecompileConcurrent');}
+function isCompileUnoptimizeEvent(event){return(event.title==='V8.CompileIgnition'||event.title==='V8.CompileUnoptimizedInnerFunctions'||event.title==='V8.Compile'||event.title==='V8.CompileEval'||event.title==='V8.CompileCode'||event.title==='V8.CompileScript');}
+function isCompileParseEvent(event){return(event.title==='V8.PreParse'||event.title==='V8.ParseFunction'||event.title==='V8.ParseProgram');}
 function isCompileEvent(event){return tr.b.getCategoryParts(event.category).includes('disabled-by-default-v8.compile');}
 function isFullMarkCompactorEvent(event){return event.title==='V8.GCCompactor';}
 function isIncrementalMarkingEvent(event){return event.title.startsWith('V8.GCIncrementalMarking');}
@@ -7725,266 +8079,295 @@
 function isScavengerEvent(event){return event.title==='V8.GCScavenger';}
 function topGarbageCollectionEventName(event){if(event.title===FULL_GC_EVENT){if(findParent(event,isLowMemoryEvent)){return LOW_MEMORY_MARK_COMPACTOR;}}
 return TOP_GC_EVENTS[event.title];}
-function subGarbageCollectionEventName(event){var topEvent=findParent(event,isTopGarbageCollectionEvent);var prefix=topEvent?topGarbageCollectionEventName(topEvent):'unknown';var name=event.title.replace('V8.GC_MC_','').replace('V8.GC_SCAVENGER_','').replace('V8.GC_','').replace(/_/g,'-').toLowerCase();return prefix+'-'+name;}
-function groupAndProcessEvents(model,filterCallback,nameCallback,processCallback){var nameToEvents={};for(var event of model.getDescendantEvents()){if(!filterCallback(event))continue;var name=nameCallback(event);nameToEvents[name]=nameToEvents[name]||[];nameToEvents[name].push(event);}
-for(var[name,events]of Object.entries(nameToEvents)){processCallback(name,events);}}
+function subGarbageCollectionEventName(event){const topEvent=findParent(event,isTopGarbageCollectionEvent);const prefix=topEvent?topGarbageCollectionEventName(topEvent):'unknown';const name=event.title.replace('V8.GC_MC_','').replace('V8.GC_SCAVENGER_','').replace('V8.GC_','').replace(/_/g,'-').toLowerCase();return prefix+'-'+name;}
+function groupAndProcessEvents(model,filterCallback,nameCallback,processCallback){const nameToEvents={};for(const event of model.getDescendantEvents()){if(!filterCallback(event))continue;const name=nameCallback(event);nameToEvents[name]=nameToEvents[name]||[];nameToEvents[name].push(event);}
+for(const[name,events]of Object.entries(nameToEvents)){processCallback(name,events);}}
 function unionOfIntervals(intervals){if(intervals.length===0)return[];return tr.b.math.mergeRanges(intervals.map(x=>{return{min:x.start,max:x.end};}),1e-6,function(ranges){return{start:ranges.reduce((acc,x)=>Math.min(acc,x.min),ranges[0].min),end:ranges.reduce((acc,x)=>Math.max(acc,x.max),ranges[0].max)};});}
-function hasV8Stats(globalMemoryDump){var v8stats=undefined;globalMemoryDump.iterateContainerDumps(function(dump){v8stats=v8stats||dump.getMemoryAllocatorDumpByFullName('v8');});return!!v8stats;}
-function rangeForMemoryDumps(model){var startOfFirstDumpWithV8=model.globalMemoryDumps.filter(hasV8Stats).reduce((start,dump)=>Math.min(start,dump.start),Infinity);if(startOfFirstDumpWithV8===Infinity)return new tr.b.math.Range();return tr.b.math.Range.fromExplicitRange(startOfFirstDumpWithV8,Infinity);}
-return{findParent,groupAndProcessEvents,isCompileEvent,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMemoryMarkCompactorEvent,isScavengerEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){var BLINK_GC_EVENTS={'BlinkGCMarking':'blink-gc-marking','ThreadState::completeSweep':'blink-gc-complete-sweep','ThreadState::performIdleLazySweep':'blink-gc-idle-lazy-sweep'};function isBlinkGarbageCollectionEvent(event){return event.title in BLINK_GC_EVENTS;}
+function hasV8Stats(globalMemoryDump){let v8stats=undefined;globalMemoryDump.iterateContainerDumps(function(dump){v8stats=v8stats||dump.getMemoryAllocatorDumpByFullName('v8');});return!!v8stats;}
+function rangeForMemoryDumps(model){const startOfFirstDumpWithV8=model.globalMemoryDumps.filter(hasV8Stats).reduce((start,dump)=>Math.min(start,dump.start),Infinity);if(startOfFirstDumpWithV8===Infinity)return new tr.b.math.Range();return tr.b.math.Range.fromExplicitRange(startOfFirstDumpWithV8,Infinity);}
+return{findParent,groupAndProcessEvents,isCompileEvent,isCompileOptimizeEvent,isCompileUnoptimizeEvent,isCompileParseEvent,isForcedGarbageCollectionEvent,isFullMarkCompactorEvent,isGarbageCollectionEvent,isIdleTask,isIncrementalMarkingEvent,isLatencyMarkCompactorEvent,isLowMemoryEvent,isMemoryMarkCompactorEvent,isScavengerEvent,isSubGarbageCollectionEvent,isTopGarbageCollectionEvent,isTopV8ExecuteEvent,isV8Event,isV8ExecuteEvent,rangeForMemoryDumps,subGarbageCollectionEventName,topGarbageCollectionEventName,unionOfIntervals,};});'use strict';tr.exportTo('tr.metrics.blink',function(){const BLINK_GC_EVENTS={'BlinkGCMarking':'blink-gc-marking','ThreadState::completeSweep':'blink-gc-complete-sweep','ThreadState::performIdleLazySweep':'blink-gc-idle-lazy-sweep'};function isBlinkGarbageCollectionEvent(event){return event.title in BLINK_GC_EVENTS;}
 function blinkGarbageCollectionEventName(event){return BLINK_GC_EVENTS[event.title];}
 function blinkGcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);addIdleTimesOfTopEvents(histograms,model);addTotalIdleTimesOfTopEvents(histograms,model);}
-tr.metrics.MetricRegistry.register(blinkGcMetric);var timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;var percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;var CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){var n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
-function createNumericForIdleTime(name){var n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
-function createPercentage(name,numerator,denominator){var histogram=new tr.v.Histogram(name,percentage_biggerIsBetter);if(denominator===0){histogram.addSample(0);}else{histogram.addSample(numerator/denominator);}
+tr.metrics.MetricRegistry.register(blinkGcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
+function createNumericForIdleTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
+function createPercentage(name,numerator,denominator){const histogram=new tr.v.Histogram(name,percentage_biggerIsBetter);if(denominator===0){histogram.addSample(0);}else{histogram.addSample(numerator/denominator);}
 return histogram;}
-function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){var cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
-function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){var cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
 function addIdleTimesOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,blinkGarbageCollectionEventName,function(name,events){addIdleTimes(histograms,model,name,events);});}
 function addTotalIdleTimesOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isBlinkGarbageCollectionEvent,event=>'blink-gc-total',function(name,events){addIdleTimes(histograms,model,name,events);});}
-function addIdleTimes(histograms,model,name,events){var cpuDuration=createNumericForIdleTime(name+'_cpu');var insideIdle=createNumericForIdleTime(name+'_inside_idle');var outsideIdle=createNumericForIdleTime(name+'_outside_idle');var idleDeadlineOverrun=createNumericForIdleTime(name+'_idle_deadline_overrun');events.forEach(function(event){var idleTask=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isIdleTask);var inside=0;var overrun=0;if(idleTask){var allottedTime=idleTask['args']['allotted_time_ms'];if(event.duration>allottedTime){overrun=event.duration-allottedTime;inside=event.cpuDuration*allottedTime/event.duration;}else{inside=event.cpuDuration;}}
-cpuDuration.addSample(event.cpuDuration);insideIdle.addSample(inside);outsideIdle.addSample(event.cpuDuration-inside);idleDeadlineOverrun.addSample(overrun);});histograms.addHistogram(idleDeadlineOverrun);histograms.addHistogram(outsideIdle);var percentage=createPercentage(name+'_percentage_idle',insideIdle.sum,cpuDuration.sum);histograms.addHistogram(percentage);}
-return{blinkGcMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function getCpuSnapshotsFromModel(model){var snapshots=[];for(var pid in model.processes){var snapshotInstances=model.processes[pid].objects.getAllInstancesNamed('CPUSnapshots');if(!snapshotInstances)continue;for(var object of snapshotInstances[0].snapshots){snapshots.push(object.args.processes);}}
+function addIdleTimes(histograms,model,name,events){const cpuDuration=createNumericForIdleTime(name+'_cpu');const insideIdle=createNumericForIdleTime(name+'_inside_idle');const outsideIdle=createNumericForIdleTime(name+'_outside_idle');const idleDeadlineOverrun=createNumericForIdleTime(name+'_idle_deadline_overrun');events.forEach(function(event){const idleTask=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isIdleTask);let inside=0;let overrun=0;if(idleTask){const allottedTime=idleTask.args.allotted_time_ms;if(event.duration>allottedTime){overrun=event.duration-allottedTime;inside=event.cpuDuration*allottedTime/event.duration;}else{inside=event.cpuDuration;}}
+cpuDuration.addSample(event.cpuDuration);insideIdle.addSample(inside);outsideIdle.addSample(event.cpuDuration-inside);idleDeadlineOverrun.addSample(overrun);});histograms.addHistogram(idleDeadlineOverrun);histograms.addHistogram(outsideIdle);const percentage=createPercentage(name+'_percentage_idle',insideIdle.sum,cpuDuration.sum);histograms.addHistogram(percentage);}
+return{blinkGcMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function getCpuSnapshotsFromModel(model){const snapshots=[];for(const pid in model.processes){const snapshotInstances=model.processes[pid].objects.getAllInstancesNamed('CPUSnapshots');if(!snapshotInstances)continue;for(const object of snapshotInstances[0].snapshots){snapshots.push(object.args.processes);}}
 return snapshots;}
-function getProcessSumsFromSnapshot(snapshot){var processSums=new Map();for(var processData of snapshot){var processName=processData.name;if(!(processSums.has(processName))){processSums.set(processName,{sum:0.0,paths:new Set()});}
+function getProcessSumsFromSnapshot(snapshot){const processSums=new Map();for(const processData of snapshot){const processName=processData.name;if(!(processSums.has(processName))){processSums.set(processName,{sum:0.0,paths:new Set()});}
 processSums.get(processName).sum+=parseFloat(processData.pCpu);if(processData.path){processSums.get(processName).paths.add(processData.path);}}
 return processSums;}
-function buildNumericsFromSnapshots(snapshots){var processNumerics=new Map();for(var snapshot of snapshots){var processSums=getProcessSumsFromSnapshot(snapshot);for(var[processName,processData]of processSums.entries()){if(!(processNumerics.has(processName))){processNumerics.set(processName,{numeric:new tr.v.Histogram('cpu:percent:'+processName,tr.b.Unit.byName.normalizedPercentage_smallerIsBetter),paths:new Set()});}
-processNumerics.get(processName).numeric.addSample(processData.sum/100.0);for(var path of processData.paths){processNumerics.get(processName).paths.add(path);}}}
+function buildNumericsFromSnapshots(snapshots){const processNumerics=new Map();for(const snapshot of snapshots){const processSums=getProcessSumsFromSnapshot(snapshot);for(const[processName,processData]of processSums.entries()){if(!(processNumerics.has(processName))){processNumerics.set(processName,{numeric:new tr.v.Histogram('cpu:percent:'+processName,tr.b.Unit.byName.normalizedPercentage_smallerIsBetter),paths:new Set()});}
+processNumerics.get(processName).numeric.addSample(processData.sum/100.0);for(const path of processData.paths){processNumerics.get(processName).paths.add(path);}}}
 return processNumerics;}
-function cpuProcessMetric(histograms,model){var snapshots=getCpuSnapshotsFromModel(model);var processNumerics=buildNumericsFromSnapshots(snapshots);for(var[processName,processData]of processNumerics){var numeric=processData.numeric;var missingSnapshotCount=snapshots.length-numeric.numValues;for(var i=0;i<missingSnapshotCount;i++){numeric.addSample(0);}
+function cpuProcessMetric(histograms,model){const snapshots=getCpuSnapshotsFromModel(model);const processNumerics=buildNumericsFromSnapshots(snapshots);for(const[processName,processData]of processNumerics){const numeric=processData.numeric;const missingSnapshotCount=snapshots.length-numeric.numValues;for(let i=0;i<missingSnapshotCount;i++){numeric.addSample(0);}
 numeric.diagnostics.set('paths',new
 tr.v.d.Generic([...processData.paths]));histograms.addHistogram(numeric);}}
-tr.metrics.MetricRegistry.register(cpuProcessMetric);return{cpuProcessMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function sampleMetric(histograms,model){var hist=new tr.v.Histogram('foo',tr.b.Unit.byName.sizeInBytes_smallerIsBetter);hist.addSample(9);hist.addSample(91,{bar:new tr.v.d.Generic({hello:42})});for(var expectation of model.userModel.expectations){if(expectation instanceof tr.model.um.ResponseExpectation){}else if(expectation instanceof tr.model.um.AnimationExpectation){}else if(expectation instanceof tr.model.um.IdleExpectation){}else if(expectation instanceof tr.model.um.LoadExpectation){}}
-var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(var[pid,process]of Object.entries(model.processes)){}
+tr.metrics.MetricRegistry.register(cpuProcessMetric);return{cpuProcessMetric,};});'use strict';tr.exportTo('tr.metrics',function(){function sampleMetric(histograms,model){const hist=new tr.v.Histogram('foo',tr.b.Unit.byName.sizeInBytes_smallerIsBetter);hist.addSample(9);hist.addSample(91,{bar:new tr.v.d.Generic({hello:42})});for(const expectation of model.userModel.expectations){if(expectation instanceof tr.model.um.ResponseExpectation){}else if(expectation instanceof tr.model.um.AnimationExpectation){}else if(expectation instanceof tr.model.um.IdleExpectation){}else if(expectation instanceof tr.model.um.LoadExpectation){}}
+const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const[pid,process]of Object.entries(model.processes)){}
 histograms.addHistogram(hist);}
-tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const HANDLE_INPUT_EVENT_TITLE='WebViewImpl::handleInputEvent';function findPrecedingEvents_(eventsA,eventsB){let events=new Map();let eventsBIndex=0;for(let eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>eventA.start)break;}
+tr.metrics.MetricRegistry.register(sampleMetric);return{sampleMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const HANDLE_INPUT_EVENT_TITLE='WebViewImpl::handleInputEvent';function findPrecedingEvents_(eventsA,eventsB){const events=new Map();let eventsBIndex=0;for(const eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>eventA.start)break;}
 if(eventsBIndex>0){events.set(eventA,eventsB[eventsBIndex-1]);}}
 return events;}
-function findFollowingEvents_(eventsA,eventsB){let events=new Map();let eventsBIndex=0;for(let eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>=eventA.start)break;}
+function findFollowingEvents_(eventsA,eventsB){const events=new Map();let eventsBIndex=0;for(const eventA of eventsA){for(;eventsBIndex<eventsB.length;eventsBIndex++){if(eventsB[eventsBIndex].start>=eventA.start)break;}
 if(eventsBIndex>=0&&eventsBIndex<eventsB.length){events.set(eventA,eventsB[eventsBIndex]);}}
 return events;}
-function getSpaNavigationStartCandidates_(rendererHelper,browserHelper){let isNavStartEvent=e=>{if(e.title===HANDLE_INPUT_EVENT_TITLE&&e.args.type==='MouseUp'){return true;}
+function getSpaNavigationStartCandidates_(rendererHelper,browserHelper){const isNavStartEvent=e=>{if(e.title===HANDLE_INPUT_EVENT_TITLE&&e.args.type==='MouseUp'){return true;}
 return e.title==='NavigationControllerImpl::GoToIndex';};return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents(),...browserHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavStartEvent);}
-function getSpaNavigationEvents_(rendererHelper){let isNavEvent=e=>e.category==='blink'&&e.title==='FrameLoader::updateForSameDocumentNavigation';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavEvent);}
-function getInputLatencyEvents_(browserHelper){let isInputLatencyEvent=e=>e.title==='InputLatency::MouseUp';return browserHelper.getAllAsyncSlicesMatching(isInputLatencyEvent);}
-function getInputLatencyEventByBindIdMap_(browserHelper){let inputLatencyEventByBindIdMap=new Map();for(let event of getInputLatencyEvents_(browserHelper)){inputLatencyEventByBindIdMap.set(event.args.data.trace_id,event);}
+function getSpaNavigationEvents_(rendererHelper){const isNavEvent=e=>e.category==='blink'&&e.title==='FrameLoader::updateForSameDocumentNavigation';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isNavEvent);}
+function getInputLatencyEvents_(browserHelper){const isInputLatencyEvent=e=>e.title==='InputLatency::MouseUp';return browserHelper.getAllAsyncSlicesMatching(isInputLatencyEvent);}
+function getInputLatencyEventByBindIdMap_(browserHelper){const inputLatencyEventByBindIdMap=new Map();for(const event of getInputLatencyEvents_(browserHelper)){inputLatencyEventByBindIdMap.set(event.args.data.trace_id,event);}
 return inputLatencyEventByBindIdMap;}
-function getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper){let mainThread=rendererHelper.mainThread;let spaNavEvents=getSpaNavigationEvents_(rendererHelper);let navStartCandidates=getSpaNavigationStartCandidates_(rendererHelper,browserHelper).sort(tr.importer.compareEvents);let spaNavEventToNavStartCandidateMap=findPrecedingEvents_(spaNavEvents,navStartCandidates);let inputLatencyEventByBindIdMap=getInputLatencyEventByBindIdMap_(browserHelper);let spaNavEventToNavStartEventMap=new Map();for(let[spaNavEvent,navStartCandidate]of
-spaNavEventToNavStartCandidateMap){if(navStartCandidate.title===HANDLE_INPUT_EVENT_TITLE){let inputLatencySlice=inputLatencyEventByBindIdMap.get(Number(navStartCandidate.parentSlice.bindId));if(inputLatencySlice){spaNavEventToNavStartEventMap.set(spaNavEvent,inputLatencySlice);}}else{spaNavEventToNavStartEventMap.set(spaNavEvent,navStartCandidate);}}
+function getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper){const mainThread=rendererHelper.mainThread;const spaNavEvents=getSpaNavigationEvents_(rendererHelper);const navStartCandidates=getSpaNavigationStartCandidates_(rendererHelper,browserHelper).sort(tr.importer.compareEvents);const spaNavEventToNavStartCandidateMap=findPrecedingEvents_(spaNavEvents,navStartCandidates);const inputLatencyEventByBindIdMap=getInputLatencyEventByBindIdMap_(browserHelper);const spaNavEventToNavStartEventMap=new Map();for(const[spaNavEvent,navStartCandidate]of
+spaNavEventToNavStartCandidateMap){if(navStartCandidate.title===HANDLE_INPUT_EVENT_TITLE){const inputLatencySlice=inputLatencyEventByBindIdMap.get(Number(navStartCandidate.parentSlice.bindId));if(inputLatencySlice){spaNavEventToNavStartEventMap.set(spaNavEvent,inputLatencySlice);}}else{spaNavEventToNavStartEventMap.set(spaNavEvent,navStartCandidate);}}
 return spaNavEventToNavStartEventMap;}
-function getFirstPaintEvents_(rendererHelper){let isFirstPaintEvent=e=>e.category==='blink'&&e.title==='PaintLayerCompositor::updateIfNeededRecursive';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isFirstPaintEvent);}
-function getSpaNavigationEventToFirstPaintEventMap_(rendererHelper){let spaNavEvents=getSpaNavigationEvents_(rendererHelper).sort(tr.importer.compareEvents);let firstPaintEvents=getFirstPaintEvents_(rendererHelper).sort(tr.importer.compareEvents);return findFollowingEvents_(spaNavEvents,firstPaintEvents);}
-function findSpaNavigationsOnRenderer(rendererHelper,browserHelper){let spaNavEventToNavStartMap=getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper);let spaNavEventToFirstPaintEventMap=getSpaNavigationEventToFirstPaintEventMap_(rendererHelper);let spaNavigations=[];for(let[spaNavEvent,navStartEvent]of
-spaNavEventToNavStartMap){if(spaNavEventToFirstPaintEventMap.has(spaNavEvent)){let firstPaintEvent=spaNavEventToFirstPaintEventMap.get(spaNavEvent);let isNavStartAsyncSlice=navStartEvent instanceof tr.model.AsyncSlice;spaNavigations.push({navStartCandidates:{inputLatencyAsyncSlice:isNavStartAsyncSlice?navStartEvent:undefined,goToIndexSlice:isNavStartAsyncSlice?undefined:navStartEvent},firstPaintEvent:firstPaintEvent,url:spaNavEvent.args.url});}}
+function getFirstPaintEvents_(rendererHelper){const isFirstPaintEvent=e=>e.category==='blink'&&e.title==='PaintLayerCompositor::updateIfNeededRecursive';return[...rendererHelper.mainThread.sliceGroup.getDescendantEvents()].filter(isFirstPaintEvent);}
+function getSpaNavigationEventToFirstPaintEventMap_(rendererHelper){const spaNavEvents=getSpaNavigationEvents_(rendererHelper).sort(tr.importer.compareEvents);const firstPaintEvents=getFirstPaintEvents_(rendererHelper).sort(tr.importer.compareEvents);return findFollowingEvents_(spaNavEvents,firstPaintEvents);}
+function findSpaNavigationsOnRenderer(rendererHelper,browserHelper){const spaNavEventToNavStartMap=getSpaNavigationEventToNavigationStartMap_(rendererHelper,browserHelper);const spaNavEventToFirstPaintEventMap=getSpaNavigationEventToFirstPaintEventMap_(rendererHelper);const spaNavigations=[];for(const[spaNavEvent,navStartEvent]of
+spaNavEventToNavStartMap){if(spaNavEventToFirstPaintEventMap.has(spaNavEvent)){const firstPaintEvent=spaNavEventToFirstPaintEventMap.get(spaNavEvent);const isNavStartAsyncSlice=navStartEvent instanceof tr.model.AsyncSlice;spaNavigations.push({navStartCandidates:{inputLatencyAsyncSlice:isNavStartAsyncSlice?navStartEvent:undefined,goToIndexSlice:isNavStartAsyncSlice?undefined:navStartEvent},firstPaintEvent,url:spaNavEvent.args.url});}}
 return spaNavigations;}
-return{findSpaNavigationsOnRenderer,};});'use strict';tr.exportTo('tr.metrics',function(){const SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY=tr.v.HistogramBinBoundaries.createExponential(1,1000,50);function spaNavigationMetric(histograms,model){let histogram=new tr.v.Histogram('spaNavigationStartToFpDuration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY);histogram.description='Latency between the input event causing'+' a SPA navigation and the first paint event after it';histogram.customizeSummaryOptions({count:false,sum:false,});let modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper){return;}
-let rendererHelpers=modelHelper.rendererHelpers;if(!rendererHelpers){return;}
-let browserHelper=modelHelper.browserHelper;for(let rendererHelper of Object.values(rendererHelpers)){let spaNavigations=tr.metrics.findSpaNavigationsOnRenderer(rendererHelper,browserHelper);for(let spaNav of spaNavigations){let beginTs=0;if(spaNav.navStartCandidates.inputLatencyAsyncSlice){let beginData=spaNav.navStartCandidates.inputLatencyAsyncSlice.args.data;beginTs=model.convertTimestampToModelTime('traceEventClock',beginData.INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT.time);}else{beginTs=spaNav.navStartCandidates.goToIndexSlice.start;}
-let duration=spaNav.firstPaintEvent.start-beginTs;let breakdownDict=rendererHelper.generateWallClockTimeBreakdownTree(beginTs,spaNav.firstPaintEvent.start);let breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(let label in breakdownDict){breakdownDiagnostic.set(label,parseInt(breakdownDict[label].total*1e3)/1e3);}
-histogram.addSample(duration,{'Breakdown of [navStart, firstPaint]':breakdownDiagnostic,'Start':new tr.v.d.RelatedEventSet(spaNav.navigationStart),'End':new tr.v.d.RelatedEventSet(spaNav.firstPaintEvent),'Navigation infos':new tr.v.d.Generic({url:spaNav.url,pid:rendererHelper.pid,navStart:beginTs,firstPaint:spaNav.firstPaintEvent.start})});}}
-histograms.addHistogram(histogram);}
-tr.metrics.MetricRegistry.register(spaNavigationMetric);return{spaNavigationMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
-function filterExpectationsByRange(irs,opt_range){var filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))return;if(!opt_range||opt_range.intersectsExplicitRangeInclusive(ir.start,ir.end)){filteredExpectations.push(ir);}});return filteredExpectations;}
-return{perceptualBlend,filterExpectationsByRange,};});'use strict';tr.exportTo('tr.metrics.sh',function(){var LATENCY_BOUNDS=tr.v.HistogramBinBoundaries.createLinear(0,20,100);function clockSyncLatencyMetric(values,model){var domains=Array.from(model.clockSyncManager.domainsSeen).sort();for(var i=0;i<domains.length;i++){for(var j=i+1;j<domains.length;j++){var latency=model.clockSyncManager.getTimeTransformerError(domains[i],domains[j]);var hist=new tr.v.Histogram('clock_sync_latency_'+
-domains[i].toLowerCase()+'_to_'+domains[j].toLowerCase(),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,LATENCY_BOUNDS);hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,});hist.description='Clock sync latency for domain '+domains[i]+' to domain '+domains[j];hist.addSample(latency);values.addHistogram(hist);}}}
-tr.metrics.MetricRegistry.register(clockSyncLatencyMetric);return{clockSyncLatencyMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){var CPU_TIME_PERCENTAGE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,50,200);function cpuTimeMetric(histograms,model,opt_options){var rangeOfInterest=model.bounds;if(opt_options&&opt_options.rangeOfInterest){rangeOfInterest=opt_options.rangeOfInterest;}else{var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper){var chromeBounds=chromeHelper.chromeBounds;if(chromeBounds){rangeOfInterest=chromeBounds;}}}
-var allProcessCpuTime=0;for(var pid in model.processes){var process=model.processes[pid];if(tr.model.helpers.ChromeRendererHelper.isTracingProcess(process)){continue;}
-var processCpuTime=0;for(var tid in process.threads){var thread=process.threads[tid];var threadCpuTime=0;thread.sliceGroup.topLevelSlices.forEach(function(slice){if(slice.duration===0)return;if(!slice.cpuDuration)return;var sliceRange=tr.b.math.Range.fromExplicitRange(slice.start,slice.end);var intersection=rangeOfInterest.findIntersection(sliceRange);var fractionOfSliceInsideRangeOfInterest=intersection.duration/slice.duration;threadCpuTime+=slice.cpuDuration*fractionOfSliceInsideRangeOfInterest;});processCpuTime+=threadCpuTime;}
-allProcessCpuTime+=processCpuTime;}
-var normalizedAllProcessCpuTime=0;if(rangeOfInterest.duration>0){normalizedAllProcessCpuTime=allProcessCpuTime/rangeOfInterest.duration;}
-var unit=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;var cpuTimeHist=new tr.v.Histogram('cpu_time_percentage',unit,CPU_TIME_PERCENTAGE_BOUNDARIES);cpuTimeHist.description='Percent CPU utilization, normalized against a single core. Can be '+'greater than 100% if machine has multiple cores.';cpuTimeHist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false});cpuTimeHist.addSample(normalizedAllProcessCpuTime);histograms.addHistogram(cpuTimeHist);}
-tr.metrics.MetricRegistry.register(cpuTimeMetric,{supportsRangeOfInterest:true});return{cpuTimeMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){var RESPONSIVENESS_THRESHOLD_MS=50;var INTERACTIVE_WINDOW_SIZE_MS=5*1000;var timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;var RelatedEventSet=tr.v.d.RelatedEventSet;function hasCategoryAndName(event,category,title){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
-function createBreakdownDiagnostic(breakdownTree){var breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(let label in breakdownTree){breakdownDiagnostic.set(label,breakdownTree[label].total);}
+return{findSpaNavigationsOnRenderer,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function perceptualBlend(ir,index,score){return Math.exp(1-score);}
+function filterExpectationsByRange(irs,opt_range){const filteredExpectations=[];irs.forEach(function(ir){if(!(ir instanceof tr.model.um.UserExpectation))return;if(!opt_range||opt_range.intersectsExplicitRangeInclusive(ir.start,ir.end)){filteredExpectations.push(ir);}});return filteredExpectations;}
+return{perceptualBlend,filterExpectationsByRange,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function generateTimeBreakdownTree(mainThread,rangeOfInterest,getEventStart,getEventDuration,getEventSelfTime){if(mainThread===null)return;const breakdownTree={};for(const title of
+tr.e.chrome.ChromeUserFriendlyCategoryDriver.ALL_TITLES){breakdownTree[title]={total:0,events:{}};}
+for(const event of mainThread.getDescendantEvents()){const eventStart=getEventStart(event);const eventDuration=getEventDuration(event);const eventSelfTime=getEventSelfTime(event);const eventEnd=eventStart+eventDuration;if(!rangeOfInterest.intersectsExplicitRangeExclusive(eventStart,eventEnd)){continue;}
+if(eventSelfTime===undefined)continue;const title=tr.e.chrome.ChromeUserFriendlyCategoryDriver.fromEvent(event);let timeIntersectionRatio=0;if(eventDuration>0){timeIntersectionRatio=rangeOfInterest.findExplicitIntersectionDuration(eventStart,eventEnd)/eventDuration;}
+const v8Runtime=event.args['runtime-call-stat'];if(v8Runtime!==undefined){const v8RuntimeObject=JSON.parse(v8Runtime);for(const runtimeCall in v8RuntimeObject){if(v8RuntimeObject[runtimeCall].length===2){if(breakdownTree.v8_runtime.events[runtimeCall]===undefined){breakdownTree.v8_runtime.events[runtimeCall]=0;}
+const runtimeTime=tr.b.Unit.timestampFromUs(v8RuntimeObject[runtimeCall][1]*timeIntersectionRatio);breakdownTree.v8_runtime.total+=runtimeTime;breakdownTree.v8_runtime.events[runtimeCall]+=runtimeTime;}}}
+const approximatedSelfTimeContribution=eventSelfTime*timeIntersectionRatio;breakdownTree[title].total+=approximatedSelfTimeContribution;if(breakdownTree[title].events[event.title]===undefined){breakdownTree[title].events[event.title]=0;}
+breakdownTree[title].events[event.title]+=approximatedSelfTimeContribution;}
+return breakdownTree;}
+function addIdleAndBlockByNetworkBreakdown_(breakdownTree,mainThreadEvents,networkEvents,rangeOfInterest){let idleRanges=[rangeOfInterest];const mainThreadEventRanges=tr.b.math.convertEventsToRanges(mainThreadEvents);const networkEventRanges=tr.b.math.convertEventsToRanges(networkEvents);const eventRanges=mainThreadEventRanges.concat(networkEventRanges);eventRanges.sort((a,b)=>a.min-b.min);for(const eventRange of eventRanges){if(!eventRange||eventRange.isEmpty||eventRange.duration<0){throw new Error('Range is invalid');}
+const newLastIdleRanges=tr.b.math.Range.findDifference(idleRanges[idleRanges.length-1],eventRange);idleRanges.pop();idleRanges=idleRanges.concat(newLastIdleRanges);if(idleRanges.length===0)break;}
+const totalFreeDuration=tr.b.math.Statistics.sum(idleRanges,range=>range.duration);breakdownTree.idle={total:totalFreeDuration,events:{}};let totalBlockedDuration=rangeOfInterest.duration;for(const component of Object.values(breakdownTree)){totalBlockedDuration-=component.total;}
+breakdownTree.blocked_on_network={total:totalBlockedDuration,events:{}};}
+function generateWallClockTimeBreakdownTree(mainThread,networkEvents,rangeOfInterest){function getEventStart(e){return e.start;}
+function getEventDuration(e){return e.duration;}
+function getEventSelfTime(e){return e.selfTime;}
+const breakdownTree=generateTimeBreakdownTree(mainThread,rangeOfInterest,getEventStart,getEventDuration,getEventSelfTime);const mainThreadEventsInRange=tr.model.helpers.getSlicesIntersectingRange(rangeOfInterest,mainThread.sliceGroup.topLevelSlices);addIdleAndBlockByNetworkBreakdown_(breakdownTree,mainThreadEventsInRange,networkEvents,rangeOfInterest);return breakdownTree;}
+function generateCpuTimeBreakdownTree(mainThread,rangeOfInterestCpuTime){function getEventStart(e){return e.cpuStart;}
+function getEventDuration(e){return e.cpuDuration;}
+function getEventSelfTime(e){return e.cpuSelfTime;}
+return generateTimeBreakdownTree(mainThread,rangeOfInterestCpuTime,getEventStart,getEventDuration,getEventSelfTime);}
+return{generateTimeBreakdownTree,generateWallClockTimeBreakdownTree,generateCpuTimeBreakdownTree,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const RESPONSIVENESS_THRESHOLD_MS=50;const INTERACTIVE_WINDOW_SIZE_MS=5*1000;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const RelatedEventSet=tr.v.d.RelatedEventSet;function getNetworkEventsInRange(process,range){const networkEvents=[];for(const thread of Object.values(process.threads)){const threadHelper=new tr.model.helpers.ChromeThreadHelper(thread);const events=threadHelper.getNetworkEvents();for(const event of events){if(range.intersectsExplicitRangeInclusive(event.start,event.end)){networkEvents.push(event);}}}
+return networkEvents;}
+function hasCategoryAndName(event,category,title){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
+function createBreakdownDiagnostic(breakdownTree){const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownTree){breakdownDiagnostic.set(label,breakdownTree[label].total);}
 return breakdownDiagnostic;}
-function NavigationStartFinder(rendererHelper){this.navigationStartsForFrameId_={};for(var ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(!hasCategoryAndName(ev,'blink.user_timing','navigationStart')){continue;}
-var frameIdRef=ev.args['frame'];var list=this.navigationStartsForFrameId_[frameIdRef];if(list===undefined){this.navigationStartsForFrameId_[frameIdRef]=list=[];}
+function NavigationStartFinder(rendererHelper){this.navigationStartsForFrameId_={};for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(!hasCategoryAndName(ev,'blink.user_timing','navigationStart')){continue;}
+const frameIdRef=ev.args.frame;let list=this.navigationStartsForFrameId_[frameIdRef];if(list===undefined){this.navigationStartsForFrameId_[frameIdRef]=list=[];}
 list.unshift(ev);}}
-NavigationStartFinder.prototype={findNavigationStartEventForFrameBeforeTimestamp:function(frameIdRef,ts){var list=this.navigationStartsForFrameId_[frameIdRef];if(list===undefined)return undefined;var eventBeforeTimestamp;for(var ev of list){if(ev.start>ts)continue;if(eventBeforeTimestamp===undefined){eventBeforeTimestamp=ev;}}
-if(eventBeforeTimestamp===undefined)return undefined;return eventBeforeTimestamp;}};var FIRST_PAINT_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);function createHistogram(name){var histogram=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,FIRST_PAINT_BOUNDARIES);histogram.customizeSummaryOptions({avg:true,count:false,max:true,min:true,std:true,sum:false,});return histogram;}
-function findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ts){var snapshot;var objects=rendererHelper.process.objects;var frameLoaderInstances=objects.instancesByTypeName_['FrameLoader'];if(frameLoaderInstances===undefined)return undefined;var snapshot;for(var instance of frameLoaderInstances){if(!instance.isAliveAt(ts))continue;var maybeSnapshot=instance.getSnapshotAt(ts);if(frameIdRef!==maybeSnapshot.args['frame']['id_ref'])continue;snapshot=maybeSnapshot;}
+NavigationStartFinder.prototype={findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ts){const list=this.navigationStartsForFrameId_[frameIdRef];if(list===undefined)return undefined;let eventBeforeTimestamp;for(const ev of list){if(ev.start>ts)continue;if(eventBeforeTimestamp===undefined){eventBeforeTimestamp=ev;}}
+if(eventBeforeTimestamp===undefined)return undefined;return eventBeforeTimestamp;}};const FIRST_PAINT_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,1e3,20).addLinearBins(3e3,20).addExponentialBins(20e3,20);function createHistogram(name){const histogram=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,FIRST_PAINT_BOUNDARIES);histogram.customizeSummaryOptions({avg:true,count:false,max:true,min:true,std:true,sum:false,});return histogram;}
+function findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ts){const objects=rendererHelper.process.objects;const frameLoaderInstances=objects.instancesByTypeName_.FrameLoader;if(frameLoaderInstances===undefined)return undefined;let snapshot;for(const instance of frameLoaderInstances){if(!instance.isAliveAt(ts))continue;const maybeSnapshot=instance.getSnapshotAt(ts);if(frameIdRef!==maybeSnapshot.args.frame.id_ref)continue;snapshot=maybeSnapshot;}
 return snapshot;}
-function findAllUserTimingEvents(rendererHelper,title){var targetEvents=[];for(var ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,'blink.user_timing',title))continue;targetEvents.push(ev);}
+function findAllEvents(rendererHelper,category,title){const targetEvents=[];for(const ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,category,title))continue;targetEvents.push(ev);}
 return targetEvents;}
-function findFirstMeaningfulPaintCandidates(rendererHelper){var candidatesForFrameId={};for(var ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,'loading','firstMeaningfulPaintCandidate')){continue;}
-if(rendererHelper.isTelemetryInternalEvent(ev))continue;var frameIdRef=ev.args['frame'];if(frameIdRef===undefined)continue;var list=candidatesForFrameId[frameIdRef];if(list===undefined){candidatesForFrameId[frameIdRef]=list=[];}
+function findFirstMeaningfulPaintCandidates(rendererHelper){const candidatesForFrameId={};for(const ev of rendererHelper.process.getDescendantEvents()){if(!hasCategoryAndName(ev,'loading','firstMeaningfulPaintCandidate')){continue;}
+if(rendererHelper.isTelemetryInternalEvent(ev))continue;const frameIdRef=ev.args.frame;if(frameIdRef===undefined)continue;let list=candidatesForFrameId[frameIdRef];if(list===undefined){candidatesForFrameId[frameIdRef]=list=[];}
 list.push(ev);}
 return candidatesForFrameId;}
-var URL_BLACKLIST=['about:blank','data:text/html,pluginplaceholderdata','data:text/html,chromewebdata'];function shouldIgnoreURL(url){return URL_BLACKLIST.includes(url);}
-function collectTimeToEvent(eventName,rendererHelper,navigationStartFinder){var targetEvents=findAllUserTimingEvents(rendererHelper,eventName);var samples=[];for(var ev of targetEvents){if(rendererHelper.isTelemetryInternalEvent(ev))continue;var frameIdRef=ev.args['frame'];var snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ev.start);if(snapshot===undefined||!snapshot.args.isLoadingMainFrame)continue;var url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))continue;var navigationStartEvent=navigationStartFinder.findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ev.start);if(navigationStartEvent===undefined)continue;var timeToEvent=ev.start-navigationStartEvent.start;samples.push({value:timeToEvent,diagnostics:{url:new tr.v.d.Generic(url)}});}
+const URL_BLACKLIST=['about:blank','data:text/html,pluginplaceholderdata','data:text/html,chromewebdata'];function shouldIgnoreURL(url){return URL_BLACKLIST.includes(url);}
+function collectTimeToEvent(category,eventName,rendererHelper,navigationStartFinder){const targetEvents=findAllEvents(rendererHelper,category,eventName);const samples=[];for(const ev of targetEvents){if(rendererHelper.isTelemetryInternalEvent(ev))continue;const frameIdRef=ev.args.frame;const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,ev.start);if(snapshot===undefined||!snapshot.args.isLoadingMainFrame)continue;const url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))continue;const navigationStartEvent=navigationStartFinder.findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ev.start);if(navigationStartEvent===undefined)continue;const timeToEvent=ev.start-navigationStartEvent.start;samples.push({value:timeToEvent,diagnostics:{url:new tr.v.d.Generic(url)}});}
 return samples;}
-function addFirstMeaningfulPaintSample(samples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent){var snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,fmpMarkerEvent.start);if(!snapshot||!snapshot.args.isLoadingMainFrame)return;var url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))return;var timeToFirstMeaningfulPaint=fmpMarkerEvent.start-navigationStart.start;var breakdownTree=rendererHelper.generateWallClockTimeBreakdownTree(navigationStart.start,fmpMarkerEvent.start);var breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);samples.push({value:timeToFirstMeaningfulPaint,diagnostics:{'Breakdown of [navStart, FMP]':breakdownDiagnostic,'Start':new RelatedEventSet(navigationStart),'End':new RelatedEventSet(fmpMarkerEvent),'Navigation infos':new tr.v.d.Generic({url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start}),}});return{firstMeaningfulPaint:fmpMarkerEvent.start,url:url};}
-function addFirstMeaningfulPaintCpuTimeSample(samples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent){var rangeOfInterest=tr.b.math.Range.fromExplicitRange(navigationStart.cpuStart,fmpMarkerEvent.cpuStart);var snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,fmpMarkerEvent.start);if(!snapshot||!snapshot.args.isLoadingMainFrame)return;var url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))return;var mainThreadCpuTime=getMainThreadCpuTime(rendererHelper,rangeOfInterest);var breakdownTree=rendererHelper.generateCpuTimeBreakdownTree(navigationStart.cpuStart,fmpMarkerEvent.cpuStart);var breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);samples.push({value:mainThreadCpuTime,diagnostics:{'Breakdown of [navStart, FMP]':breakdownDiagnostic,'Start':new RelatedEventSet(navigationStart),'End':new RelatedEventSet(fmpMarkerEvent),'Navigation infos':new tr.v.d.Generic({url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start}),}});}
-function getMainThreadCpuTime(rendererHelper,rangeOfInterest){var mainThreadCpuTime=0;for(var slice of rendererHelper.mainThread.sliceGroup.topLevelSlices){if(!slice.cpuDuration)continue;var sliceRange=tr.b.math.Range.fromExplicitRange(slice.cpuStart,slice.cpuStart+slice.cpuDuration);var intersection=rangeOfInterest.findIntersection(sliceRange);mainThreadCpuTime+=intersection.duration;}
+function addFirstMeaningfulPaintSample(samples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent){const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,fmpMarkerEvent.start);if(!snapshot||!snapshot.args.isLoadingMainFrame)return;const url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))return;const navStartToFMPRange=tr.b.math.Range.fromExplicitRange(navigationStart.start,fmpMarkerEvent.start);const networkEvents=getNetworkEventsInRange(rendererHelper.process,navStartToFMPRange);const timeToFirstMeaningfulPaint=navStartToFMPRange.duration;const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToFMPRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);samples.push({value:timeToFirstMeaningfulPaint,diagnostics:{'Breakdown of [navStart, FMP]':breakdownDiagnostic,'Start':new RelatedEventSet(navigationStart),'End':new RelatedEventSet(fmpMarkerEvent),'Navigation infos':new tr.v.d.Generic({url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start}),}});return{firstMeaningfulPaint:fmpMarkerEvent.start,url};}
+function addFirstMeaningfulPaintCpuTimeSample(samples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent){const navStartToFMPCpuRange=tr.b.math.Range.fromExplicitRange(navigationStart.cpuStart,fmpMarkerEvent.cpuStart);const snapshot=findFrameLoaderSnapshotAt(rendererHelper,frameIdRef,fmpMarkerEvent.start);if(!snapshot||!snapshot.args.isLoadingMainFrame)return;const url=snapshot.args.documentLoaderURL;if(shouldIgnoreURL(url))return;const mainThreadCpuTime=getMainThreadCpuTime(rendererHelper,navStartToFMPCpuRange);const breakdownTree=tr.metrics.sh.generateCpuTimeBreakdownTree(rendererHelper.mainThread,navStartToFMPCpuRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);samples.push({value:mainThreadCpuTime,diagnostics:{'Breakdown of [navStart, FMP]':breakdownDiagnostic,'Start':new RelatedEventSet(navigationStart),'End':new RelatedEventSet(fmpMarkerEvent),'Navigation infos':new tr.v.d.Generic({url,pid:rendererHelper.pid,start:navigationStart.start,fmp:fmpMarkerEvent.start}),}});}
+function getMainThreadCpuTime(rendererHelper,rangeOfInterest){let mainThreadCpuTime=0;for(const slice of rendererHelper.mainThread.sliceGroup.topLevelSlices){if(!slice.cpuDuration)continue;const sliceRange=tr.b.math.Range.fromExplicitRange(slice.cpuStart,slice.cpuStart+slice.cpuDuration);const intersection=rangeOfInterest.findIntersection(sliceRange);mainThreadCpuTime+=intersection.duration;}
 return mainThreadCpuTime;}
-function addFirstInteractiveSample(samples,rendererHelper,navigationStart,firstMeaningfulPaint,url){if(shouldIgnoreURL(url))return;var navigationStartTime=navigationStart.start;var firstInteractive=Infinity;var firstInteractiveCandidate=firstMeaningfulPaint;var lastLongTaskEvent=undefined;for(var ev of[...rendererHelper.mainThread.sliceGroup.childEvents()]){if(ev.start<firstInteractiveCandidate)continue;var interactiveDurationSoFar=ev.start-firstInteractiveCandidate;if(interactiveDurationSoFar>=INTERACTIVE_WINDOW_SIZE_MS){firstInteractive=firstInteractiveCandidate;break;}
+function addFirstInteractiveSample(samples,rendererHelper,navigationStart,firstMeaningfulPaint,url){if(shouldIgnoreURL(url))return;const navigationStartTime=navigationStart.start;let firstInteractive=Infinity;let firstInteractiveCandidate=firstMeaningfulPaint;let lastLongTaskEvent=undefined;for(const ev of[...rendererHelper.mainThread.sliceGroup.childEvents()]){if(ev.start<firstInteractiveCandidate)continue;const interactiveDurationSoFar=ev.start-firstInteractiveCandidate;if(interactiveDurationSoFar>=INTERACTIVE_WINDOW_SIZE_MS){firstInteractive=firstInteractiveCandidate;break;}
 if(ev.title==='TaskQueueManager::ProcessTaskFromWorkQueue'&&ev.duration>RESPONSIVENESS_THRESHOLD_MS){firstInteractiveCandidate=ev.end-50;lastLongTaskEvent=ev;}}
-var breakdownTree=rendererHelper.generateWallClockTimeBreakdownTree(navigationStartTime,firstInteractive);var breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);var timeToFirstInteractive=firstInteractive-navigationStartTime;samples.push({value:timeToFirstInteractive,diagnostics:{'Start':new RelatedEventSet(navigationStart),'Last long task':new RelatedEventSet(lastLongTaskEvent),'Navigation infos':new tr.v.d.Generic({url,pid:rendererHelper.pid,start:navigationStartTime,interactive:firstInteractive}),'Breakdown of [navStart, Interactive]':breakdownDiagnostic,}});}
-function collectFirstMeaningfulPaintAndTimeToInteractiveForRenderer(rendererHelper,navigationStartFinder){var firstMeaningfulPaintSamples=[];var firstMeaningfulPaintCpuTimeSamples=[];var firstInteractiveSamples=[];function addSamples(frameIdRef,navigationStart,fmpMarkerEvent){var data=addFirstMeaningfulPaintSample(firstMeaningfulPaintSamples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent);addFirstMeaningfulPaintCpuTimeSample(firstMeaningfulPaintCpuTimeSamples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent);if(data!==undefined){addFirstInteractiveSample(firstInteractiveSamples,rendererHelper,navigationStart,data.firstMeaningfulPaint,data.url);}}
-var candidatesForFrameId=findFirstMeaningfulPaintCandidates(rendererHelper);for(var frameIdRef in candidatesForFrameId){var navigationStart=undefined;var lastCandidate=undefined;for(var ev of candidatesForFrameId[frameIdRef]){var navigationStartForThisCandidate=navigationStartFinder.findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ev.start);if(navigationStartForThisCandidate===undefined)continue;if(navigationStart!==navigationStartForThisCandidate){if(navigationStart!==undefined&&lastCandidate!==undefined){addSamples(frameIdRef,navigationStart,lastCandidate);}
+const navStartToFirstInteractiveRange=tr.b.math.Range.fromExplicitRange(navigationStartTime,firstInteractive);const networkEvents=getNetworkEventsInRange(rendererHelper.process,navStartToFirstInteractiveRange);const breakdownTree=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,navStartToFirstInteractiveRange);const breakdownDiagnostic=createBreakdownDiagnostic(breakdownTree);const timeToFirstInteractive=navStartToFirstInteractiveRange.duration;samples.push({value:timeToFirstInteractive,diagnostics:{'Start':new RelatedEventSet(navigationStart),'Last long task':new RelatedEventSet(lastLongTaskEvent),'Navigation infos':new tr.v.d.Generic({url,pid:rendererHelper.pid,start:navigationStartTime,interactive:firstInteractive}),'Breakdown of [navStart, Interactive]':breakdownDiagnostic,}});}
+function collectFirstMeaningfulPaintAndTimeToInteractiveForRenderer(rendererHelper,navigationStartFinder){const firstMeaningfulPaintSamples=[];const firstMeaningfulPaintCpuTimeSamples=[];const firstInteractiveSamples=[];function addSamples(frameIdRef,navigationStart,fmpMarkerEvent){const data=addFirstMeaningfulPaintSample(firstMeaningfulPaintSamples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent);addFirstMeaningfulPaintCpuTimeSample(firstMeaningfulPaintCpuTimeSamples,rendererHelper,frameIdRef,navigationStart,fmpMarkerEvent);if(data!==undefined){addFirstInteractiveSample(firstInteractiveSamples,rendererHelper,navigationStart,data.firstMeaningfulPaint,data.url);}}
+const candidatesForFrameId=findFirstMeaningfulPaintCandidates(rendererHelper);for(const frameIdRef in candidatesForFrameId){let navigationStart=undefined;let lastCandidate=undefined;for(const ev of candidatesForFrameId[frameIdRef]){const navigationStartForThisCandidate=navigationStartFinder.findNavigationStartEventForFrameBeforeTimestamp(frameIdRef,ev.start);if(navigationStartForThisCandidate===undefined)continue;if(navigationStart!==navigationStartForThisCandidate){if(navigationStart!==undefined&&lastCandidate!==undefined){addSamples(frameIdRef,navigationStart,lastCandidate);}
 navigationStart=navigationStartForThisCandidate;}
 lastCandidate=ev;}
 if(lastCandidate!==undefined){addSamples(frameIdRef,navigationStart,lastCandidate);}}
 return{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples};}
-function collectLoadingMetricsForRenderer(rendererHelper){var navigationStartFinder=new NavigationStartFinder(rendererHelper);var firstContentfulPaintSamples=collectTimeToEvent('firstContentfulPaint',rendererHelper,navigationStartFinder);var onLoadSamples=collectTimeToEvent('loadEventStart',rendererHelper,navigationStartFinder);var{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples}=collectFirstMeaningfulPaintAndTimeToInteractiveForRenderer(rendererHelper,navigationStartFinder);return{firstContentfulPaintSamples,onLoadSamples,firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples};}
-function addSamplesToHistogram(samples,histogram){for(var sample of samples){histogram.addSample(sample.value,sample.diagnostics);}}
-function loadingMetric(histograms,model){var firstContentfulPaintHistogram=createHistogram('timeToFirstContentfulPaint');firstContentfulPaintHistogram.description='time to first contentful paint';var onLoadHistogram=createHistogram('timeToOnload');onLoadHistogram.description='time to onload. '+'This is temporary metric used for PCv1/v2 sanity checking';var firstMeaningfulPaintHistogram=createHistogram('timeToFirstMeaningfulPaint');firstMeaningfulPaintHistogram.description='time to first meaningful paint';var firstMeaningfulPaintCpuTimeHistogram=createHistogram('cpuTimeToFirstMeaningfulPaint');firstMeaningfulPaintCpuTimeHistogram.description='CPU time to first meaningful paint';var firstInteractiveHistogram=createHistogram('timeToFirstInteractive');firstInteractiveHistogram.description='time to first interactive';var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(var pid in chromeHelper.rendererHelpers){var rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;var{firstContentfulPaintSamples,onLoadSamples,firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples}=collectLoadingMetricsForRenderer(rendererHelper);addSamplesToHistogram(firstContentfulPaintSamples,firstContentfulPaintHistogram);addSamplesToHistogram(onLoadSamples,onLoadHistogram);addSamplesToHistogram(firstMeaningfulPaintSamples,firstMeaningfulPaintHistogram);addSamplesToHistogram(firstMeaningfulPaintCpuTimeSamples,firstMeaningfulPaintCpuTimeHistogram);addSamplesToHistogram(firstInteractiveSamples,firstInteractiveHistogram);}
+function collectLoadingMetricsForRenderer(rendererHelper){const navigationStartFinder=new NavigationStartFinder(rendererHelper);const firstContentfulPaintSamples=collectTimeToEvent('loading','firstContentfulPaint',rendererHelper,navigationStartFinder);const onLoadSamples=collectTimeToEvent('blink.user_timing','loadEventStart',rendererHelper,navigationStartFinder);const{firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples}=collectFirstMeaningfulPaintAndTimeToInteractiveForRenderer(rendererHelper,navigationStartFinder);return{firstContentfulPaintSamples,onLoadSamples,firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples};}
+function addSamplesToHistogram(samples,histogram){for(const sample of samples){histogram.addSample(sample.value,sample.diagnostics);}}
+function loadingMetric(histograms,model){const firstContentfulPaintHistogram=createHistogram('timeToFirstContentfulPaint');firstContentfulPaintHistogram.description='time to first contentful paint';const onLoadHistogram=createHistogram('timeToOnload');onLoadHistogram.description='time to onload. '+'This is temporary metric used for PCv1/v2 sanity checking';const firstMeaningfulPaintHistogram=createHistogram('timeToFirstMeaningfulPaint');firstMeaningfulPaintHistogram.description='time to first meaningful paint';const firstMeaningfulPaintCpuTimeHistogram=createHistogram('cpuTimeToFirstMeaningfulPaint');firstMeaningfulPaintCpuTimeHistogram.description='CPU time to first meaningful paint';const firstInteractiveHistogram=createHistogram('timeToFirstInteractive');firstInteractiveHistogram.description='time to first interactive';const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const pid in chromeHelper.rendererHelpers){const rendererHelper=chromeHelper.rendererHelpers[pid];if(rendererHelper.isChromeTracingUI)continue;const{firstContentfulPaintSamples,onLoadSamples,firstMeaningfulPaintSamples,firstMeaningfulPaintCpuTimeSamples,firstInteractiveSamples}=collectLoadingMetricsForRenderer(rendererHelper);addSamplesToHistogram(firstContentfulPaintSamples,firstContentfulPaintHistogram);addSamplesToHistogram(onLoadSamples,onLoadHistogram);addSamplesToHistogram(firstMeaningfulPaintSamples,firstMeaningfulPaintHistogram);addSamplesToHistogram(firstMeaningfulPaintCpuTimeSamples,firstMeaningfulPaintCpuTimeHistogram);addSamplesToHistogram(firstInteractiveSamples,firstInteractiveHistogram);}
 histograms.addHistogram(firstContentfulPaintHistogram);histograms.addHistogram(onLoadHistogram);histograms.addHistogram(firstMeaningfulPaintHistogram);histograms.addHistogram(firstMeaningfulPaintCpuTimeHistogram);histograms.addHistogram(firstInteractiveHistogram);}
-tr.metrics.MetricRegistry.register(loadingMetric);return{loadingMetric,collectLoadingMetricsForRenderer,RESPONSIVENESS_THRESHOLD_MS,INTERACTIVE_WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.v',function(){class HistogramGrouping{constructor(key,callback,opt_label){this.key=key;this.callback=callback;this.label=opt_label||key;}}
-class HistogramSet{constructor(opt_histograms){this.histogramsByGuid_=new Map();this.sharedDiagnosticsByGuid_=new Map();if(opt_histograms!==undefined){for(let hist of opt_histograms){this.addHistogram(hist);}}}
+tr.metrics.MetricRegistry.register(loadingMetric);return{loadingMetric,getNetworkEventsInRange,collectLoadingMetricsForRenderer,RESPONSIVENESS_THRESHOLD_MS,INTERACTIVE_WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics',function(){const SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY=tr.v.HistogramBinBoundaries.createExponential(1,1000,50);function spaNavigationMetric(histograms,model){const histogram=new tr.v.Histogram('spaNavigationStartToFpDuration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,SPA_NAVIGATION_START_TO_FIRST_PAINT_DURATION_BIN_BOUNDARY);histogram.description='Latency between the input event causing'+' a SPA navigation and the first paint event after it';histogram.customizeSummaryOptions({count:false,sum:false,});const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(!modelHelper){return;}
+const rendererHelpers=modelHelper.rendererHelpers;if(!rendererHelpers){return;}
+const browserHelper=modelHelper.browserHelper;for(const rendererHelper of Object.values(rendererHelpers)){const spaNavigations=tr.metrics.findSpaNavigationsOnRenderer(rendererHelper,browserHelper);for(const spaNav of spaNavigations){let beginTs=0;if(spaNav.navStartCandidates.inputLatencyAsyncSlice){const beginData=spaNav.navStartCandidates.inputLatencyAsyncSlice.args.data;beginTs=model.convertTimestampToModelTime('traceEventClock',beginData.INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT.time);}else{beginTs=spaNav.navStartCandidates.goToIndexSlice.start;}
+const rangeOfInterest=tr.b.math.Range.fromExplicitRange(beginTs,spaNav.firstPaintEvent.start);const networkEvents=tr.metrics.sh.getNetworkEventsInRange(rendererHelper.process,rangeOfInterest);const breakdownDict=tr.metrics.sh.generateWallClockTimeBreakdownTree(rendererHelper.mainThread,networkEvents,rangeOfInterest);const breakdownDiagnostic=new tr.v.d.Breakdown();breakdownDiagnostic.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;for(const label in breakdownDict){breakdownDiagnostic.set(label,parseInt(breakdownDict[label].total*1e3)/1e3);}
+histogram.addSample(rangeOfInterest.duration,{'Breakdown of [navStart, firstPaint]':breakdownDiagnostic,'Start':new tr.v.d.RelatedEventSet(spaNav.navigationStart),'End':new tr.v.d.RelatedEventSet(spaNav.firstPaintEvent),'Navigation infos':new tr.v.d.Generic({url:spaNav.url,pid:rendererHelper.pid,navStart:beginTs,firstPaint:spaNav.firstPaintEvent.start})});}}
+histograms.addHistogram(histogram);}
+tr.metrics.MetricRegistry.register(spaNavigationMetric);return{spaNavigationMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LATENCY_BOUNDS=tr.v.HistogramBinBoundaries.createLinear(0,20,100);function clockSyncLatencyMetric(values,model){const domains=Array.from(model.clockSyncManager.domainsSeen).sort();for(let i=0;i<domains.length;i++){for(let j=i+1;j<domains.length;j++){const latency=model.clockSyncManager.getTimeTransformerError(domains[i],domains[j]);const hist=new tr.v.Histogram('clock_sync_latency_'+
+domains[i].toLowerCase()+'_to_'+domains[j].toLowerCase(),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,LATENCY_BOUNDS);hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,});hist.description='Clock sync latency for domain '+domains[i]+' to domain '+domains[j];hist.addSample(latency);values.addHistogram(hist);}}}
+tr.metrics.MetricRegistry.register(clockSyncLatencyMetric);return{clockSyncLatencyMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CPU_TIME_PERCENTAGE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,50,200);function cpuTimeMetric(histograms,model,opt_options){let rangeOfInterest=model.bounds;if(opt_options&&opt_options.rangeOfInterest){rangeOfInterest=opt_options.rangeOfInterest;}else{const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper){const chromeBounds=chromeHelper.chromeBounds;if(chromeBounds){rangeOfInterest=chromeBounds;}}}
+let allProcessCpuTime=0;for(const pid in model.processes){const process=model.processes[pid];if(tr.model.helpers.ChromeRendererHelper.isTracingProcess(process)){continue;}
+let processCpuTime=0;for(const tid in process.threads){const thread=process.threads[tid];let threadCpuTime=0;thread.sliceGroup.topLevelSlices.forEach(function(slice){if(slice.duration===0)return;if(!slice.cpuDuration)return;const sliceRange=tr.b.math.Range.fromExplicitRange(slice.start,slice.end);const intersection=rangeOfInterest.findIntersection(sliceRange);const fractionOfSliceInsideRangeOfInterest=intersection.duration/slice.duration;threadCpuTime+=slice.cpuDuration*fractionOfSliceInsideRangeOfInterest;});processCpuTime+=threadCpuTime;}
+allProcessCpuTime+=processCpuTime;}
+let normalizedAllProcessCpuTime=0;if(rangeOfInterest.duration>0){normalizedAllProcessCpuTime=allProcessCpuTime/rangeOfInterest.duration;}
+const unit=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const cpuTimeHist=new tr.v.Histogram('cpu_time_percentage',unit,CPU_TIME_PERCENTAGE_BOUNDARIES);cpuTimeHist.description='Percent CPU utilization, normalized against a single core. Can be '+'greater than 100% if machine has multiple cores.';cpuTimeHist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false});cpuTimeHist.addSample(normalizedAllProcessCpuTime);histograms.addHistogram(cpuTimeHist);}
+tr.metrics.MetricRegistry.register(cpuTimeMetric,{supportsRangeOfInterest:true});return{cpuTimeMetric,};});'use strict';tr.exportTo('tr.v',function(){class HistogramGrouping{constructor(key,callback,opt_label){this.key=key;this.callback=callback;this.label=opt_label||key;HistogramGrouping.KEYS_TO_GROUPINGS.set(key,this);}}
+HistogramGrouping.KEYS_TO_GROUPINGS=new Map();class HistogramSet{constructor(opt_histograms){this.histogramsByGuid_=new Map();this.sharedDiagnosticsByGuid_=new Map();if(opt_histograms!==undefined){for(const hist of opt_histograms){this.addHistogram(hist);}}}
+createHistogram(name,unit,samples,opt_options){const hist=tr.v.Histogram.create(name,unit,samples,opt_options);this.addHistogram(hist);return hist;}
 addHistogram(hist,opt_diagnostics){if(this.histogramsByGuid_.has(hist.guid)){throw new Error('Cannot add same Histogram twice');}
-if(opt_diagnostics!==undefined){if(opt_diagnostics instanceof tr.v.d.DiagnosticMap){for(let[name,diagnostic]of opt_diagnostics){hist.diagnostics.set(name,diagnostic);}}else{for(var[name,diagnostic]of Object.entries(opt_diagnostics)){hist.diagnostics.set(name,diagnostic);}}}
+if(opt_diagnostics!==undefined){if(!(opt_diagnostics instanceof Map)){opt_diagnostics=Object.entries(opt_diagnostics);}
+for(const[name,diagnostic]of opt_diagnostics){hist.diagnostics.set(name,diagnostic);}}
 this.histogramsByGuid_.set(hist.guid,hist);}
-addSharedDiagnostic(name,diagnostic){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);for(let hist of this){hist.diagnostics.set(name,diagnostic);}}
-get length(){return this.histogramsByGuid_.size;}*[Symbol.iterator](){for(let hist of this.histogramsByGuid_.values()){yield hist;}}
+addSharedDiagnostic(name,diagnostic){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);for(const hist of this){hist.diagnostics.set(name,diagnostic);}}
+get length(){return this.histogramsByGuid_.size;}*[Symbol.iterator](){for(const hist of this.histogramsByGuid_.values()){yield hist;}}
 getHistogramsNamed(name){return[...this].filter(h=>h.name===name);}
-getHistogramNamed(name){let histograms=this.getHistogramsNamed(name);if(histograms.length===0)return undefined;if(histograms.length>1){throw new Error(`Unexpectedly found multiple histograms named"${name}"`);}
+getHistogramNamed(name){const histograms=this.getHistogramsNamed(name);if(histograms.length===0)return undefined;if(histograms.length>1){throw new Error(`Unexpectedly found multiple histograms named "${name}"`);}
 return histograms[0];}
 lookupHistogram(guid){return this.histogramsByGuid_.get(guid);}
 lookupDiagnostic(guid){return this.sharedDiagnosticsByGuid_.get(guid);}
-resolveRelatedHistograms(){const handleDiagnosticMap=dm=>{for(let[name,diagnostic]of dm){if((diagnostic instanceof tr.v.d.RelatedHistogramSet)||(diagnostic instanceof tr.v.d.RelatedHistogramMap)){diagnostic.resolve(this);}}};for(let hist of this){hist.diagnostics.resolveSharedDiagnostics(this);handleDiagnosticMap(hist.diagnostics);for(let dm of hist.nanDiagnosticMaps){handleDiagnosticMap(dm);}
-for(let bin of hist.allBins){for(let dm of bin.diagnosticMaps){handleDiagnosticMap(dm);}}}}
-importDicts(dicts){for(let dict of dicts){if(dict.type&&tr.v.d.Diagnostic.findTypeInfoWithName(dict.type)){this.sharedDiagnosticsByGuid_.set(dict.guid,tr.v.d.Diagnostic.fromDict(dict));}else{this.addHistogram(tr.v.Histogram.fromDict(dict));}}}
-asDicts(){let dicts=[];for(let diagnostic of this.sharedDiagnosticsByGuid_.values()){dicts.push(diagnostic.asDict());}
-for(let hist of this){dicts.push(hist.asDict());}
+resolveRelatedHistograms(){const handleDiagnosticMap=dm=>{for(const[name,diagnostic]of dm){if((diagnostic instanceof tr.v.d.RelatedHistogramSet)||(diagnostic instanceof tr.v.d.RelatedHistogramMap)){diagnostic.resolve(this);}}};for(const hist of this){hist.diagnostics.resolveSharedDiagnostics(this);handleDiagnosticMap(hist.diagnostics);for(const dm of hist.nanDiagnosticMaps){handleDiagnosticMap(dm);}
+for(const bin of hist.allBins){for(const dm of bin.diagnosticMaps){handleDiagnosticMap(dm);}}}}
+importDicts(dicts){for(const dict of dicts){if(dict.type&&tr.v.d.Diagnostic.findTypeInfoWithName(dict.type)){this.sharedDiagnosticsByGuid_.set(dict.guid,tr.v.d.Diagnostic.fromDict(dict));}else{this.addHistogram(tr.v.Histogram.fromDict(dict));}}}
+asDicts(){const dicts=[];for(const diagnostic of this.sharedDiagnosticsByGuid_.values()){dicts.push(diagnostic.asDict());}
+for(const hist of this){dicts.push(hist.asDict());}
 return dicts;}
-get sourceHistograms(){let sourceHistograms=new Map(this.histogramsByGuid_);function deleteSourceHistograms(diagnosticMap){for(let[name,diagnostic]of diagnosticMap){if(diagnostic instanceof tr.v.d.RelatedHistogramSet){for(let relatedHist of diagnostic){sourceHistograms.delete(relatedHist.guid);}}else if(diagnostic instanceof tr.v.d.RelatedHistogramMap){for(let[name,relatedHist]of diagnostic){sourceHistograms.delete(relatedHist.guid);}}}}
-for(let hist of this){deleteSourceHistograms(hist.diagnostics);for(let dm of hist.nanDiagnosticMaps){deleteSourceHistograms(dm);}
-for(let b of hist.allBins){for(let dm of b.diagnosticMaps){deleteSourceHistograms(dm);}}}
+get sourceHistograms(){const sourceHistograms=new Map(this.histogramsByGuid_);function deleteSourceHistograms(diagnosticMap){for(const[name,diagnostic]of diagnosticMap){if(diagnostic instanceof tr.v.d.RelatedHistogramSet){for(const relatedHist of diagnostic){sourceHistograms.delete(relatedHist.guid);}}else if(diagnostic instanceof tr.v.d.RelatedHistogramMap){for(const[name,relatedHist]of diagnostic){sourceHistograms.delete(relatedHist.guid);}}}}
+for(const hist of this){deleteSourceHistograms(hist.diagnostics);for(const dm of hist.nanDiagnosticMaps){deleteSourceHistograms(dm);}
+for(const b of hist.allBins){for(const dm of b.diagnosticMaps){deleteSourceHistograms(dm);}}}
 return new HistogramSet([...sourceHistograms.values()]);}
 groupHistogramsRecursively(groupings,opt_skipGroupingCallback){function recurse(histograms,level){if(level===groupings.length){return histograms;}
-let grouping=groupings[level];let groupedHistograms=tr.b.groupIntoMap(histograms,grouping.callback);if(opt_skipGroupingCallback&&opt_skipGroupingCallback(grouping,groupedHistograms)){return recurse(histograms,level+1);}
-for(let[key,group]of groupedHistograms){groupedHistograms.set(key,recurse(group,level+1));}
+const grouping=groupings[level];const groupedHistograms=tr.b.groupIntoMap(histograms,grouping.callback);if(opt_skipGroupingCallback&&opt_skipGroupingCallback(grouping,groupedHistograms)){return recurse(histograms,level+1);}
+for(const[key,group]of groupedHistograms){groupedHistograms.set(key,recurse(group,level+1));}
 return groupedHistograms;}
 return recurse([...this],0);}
-deduplicateDiagnostics(){let diagnosticsToCounts=new Map();for(let hist of this){let candidates=[];let telemetryInfo=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(telemetryInfo instanceof tr.v.d.MergedTelemetryInfo){candidates.push(telemetryInfo);}
-let buildbotInfo=tr.v.d.BuildbotInfo.getFromHistogram(hist);if(buildbotInfo instanceof tr.v.d.MergedBuildbotInfo){candidates.push(buildbotInfo);}
-let deviceInfo=tr.v.d.DeviceInfo.getFromHistogram(hist);if(deviceInfo instanceof tr.v.d.MergedDeviceInfo){candidates.push(deviceInfo);}
-for(let diagnostic of candidates){if(diagnostic===undefined)continue;let found=false;for(let[testDiagnostic,count]of diagnosticsToCounts){if(diagnostic.equals(testDiagnostic)){testDiagnostic.addToHistogram(hist);diagnosticsToCounts.set(testDiagnostic,count+1);found=true;break;}}
+deduplicateDiagnostics(){const diagnosticsToCounts=new Map();for(const hist of this){const candidates=[];const telemetryInfo=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(telemetryInfo instanceof tr.v.d.MergedTelemetryInfo){candidates.push(telemetryInfo);}
+const buildbotInfo=tr.v.d.BuildbotInfo.getFromHistogram(hist);if(buildbotInfo instanceof tr.v.d.MergedBuildbotInfo){candidates.push(buildbotInfo);}
+const deviceInfo=tr.v.d.DeviceInfo.getFromHistogram(hist);if(deviceInfo instanceof tr.v.d.MergedDeviceInfo){candidates.push(deviceInfo);}
+for(const diagnostic of candidates){if(diagnostic===undefined)continue;let found=false;for(const[testDiagnostic,count]of diagnosticsToCounts){if(diagnostic.equals(testDiagnostic)){testDiagnostic.addToHistogram(hist);diagnosticsToCounts.set(testDiagnostic,count+1);found=true;break;}}
 if(!found){diagnosticsToCounts.set(diagnostic,1);}}}
-for(let[diagnostic,count]of diagnosticsToCounts){if(count>1){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);}}}
-mergeRelationships(){for(let hist of this){hist.diagnostics.mergeRelationships(hist);}}}
+for(const[diagnostic,count]of diagnosticsToCounts){if(count>1){this.sharedDiagnosticsByGuid_.set(diagnostic.guid,diagnostic);}}}
+mergeRelationships(){for(const hist of this){hist.diagnostics.mergeRelationships(hist);}}}
 HistogramSet.GROUPINGS={HISTOGRAM_NAME:new HistogramGrouping('name',h=>h.name),BENCHMARK_NAME:new HistogramGrouping('benchmark',h=>tr.v.d.TelemetryInfo.getField(h,'benchmarkName','')),BENCHMARK_START:new HistogramGrouping('time',h=>tr.v.d.TelemetryInfo.getField(h,'benchmarkStartString','')),STORYSET_REPEAT:new HistogramGrouping('storyset_repeat',h=>tr.v.d.TelemetryInfo.getField(h,'storysetRepeatCounterLabel',0),'storyset repeat'),STORY_NAME:new HistogramGrouping('story',h=>tr.v.d.TelemetryInfo.getField(h,'storyDisplayName','')),LEGACY_TIR_LABEL:new HistogramGrouping('tir',h=>tr.v.d.TelemetryInfo.getField(h,'legacyTIRLabel','')),MASTER_NAME:new HistogramGrouping('master',h=>tr.v.d.BuildbotInfo.getField(h,'buildbotMasterName','')),SLAVE_NAME:new HistogramGrouping('bot',h=>tr.v.d.BuildbotInfo.getField(h,'buildbotName','')),BUILD_NUMBER:new HistogramGrouping('build',h=>tr.v.d.BuildbotInfo.getField(h,'buildNumber','')),DISPLAY_LABEL:new HistogramGrouping('label',h=>tr.v.d.TelemetryInfo.getField(h,'displayLabel','Value'))};return{HistogramGrouping,HistogramSet,};});'use strict';tr.exportTo('tr.e.chrome',function(){function hasTitleAndCategory(event,title,category){return event.title===title&&event.category&&tr.b.getCategoryParts(event.category).includes(category);}
-function getNavStartTimestamps(rendererHelper){var navStartTimestamps=[];for(var e of rendererHelper.mainThread.sliceGroup.childEvents()){if(hasTitleAndCategory(e,'navigationStart','blink.user_timing')){navStartTimestamps.push(e.start);}}
+function getNavStartTimestamps(rendererHelper){const navStartTimestamps=[];for(const e of rendererHelper.mainThread.sliceGroup.childEvents()){if(hasTitleAndCategory(e,'navigationStart','blink.user_timing')){navStartTimestamps.push(e.start);}}
 return navStartTimestamps;}
-function getInteractiveTimestamps(model){var interactiveTimestampsMap=new Map();var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(var rendererHelper of Object.values(chromeHelper.rendererHelpers)){var timestamps=[];interactiveTimestampsMap.set(rendererHelper.pid,timestamps);var samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;for(var sample of samples){timestamps.push(sample.diagnostics['Navigation infos'].value.interactive);}}
+function getInteractiveTimestamps(model){const interactiveTimestampsMap=new Map();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const timestamps=[];interactiveTimestampsMap.set(rendererHelper.pid,timestamps);const samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;for(const sample of samples){timestamps.push(sample.diagnostics['Navigation infos'].value.interactive);}}
 return interactiveTimestampsMap;}
-function getPostInteractiveTaskWindows(interactiveTimestamps,navStartTimestamps,traceEndTimestamp){var navStartTsIndex=0;var lastTaskWindowEndTs=undefined;var taskWindows=[];for(var currTTI of interactiveTimestamps){while(navStartTsIndex<navStartTimestamps.length&&navStartTimestamps[navStartTsIndex]<currTTI){navStartTsIndex++;}
-var taskWindowEndTs=navStartTsIndex<navStartTimestamps.length?navStartTimestamps[navStartTsIndex]:traceEndTimestamp;if(taskWindowEndTs===lastTaskWindowEndTs){throw Error('Encountered two consecutive interactive timestamps '+'with no navigationStart between them. '+'PostInteractiveTaskWindow is not well defined in this case.');}
+function getPostInteractiveTaskWindows(interactiveTimestamps,navStartTimestamps,traceEndTimestamp){let navStartTsIndex=0;let lastTaskWindowEndTs=undefined;const taskWindows=[];for(const currTTI of interactiveTimestamps){while(navStartTsIndex<navStartTimestamps.length&&navStartTimestamps[navStartTsIndex]<currTTI){navStartTsIndex++;}
+const taskWindowEndTs=navStartTsIndex<navStartTimestamps.length?navStartTimestamps[navStartTsIndex]:traceEndTimestamp;if(taskWindowEndTs===lastTaskWindowEndTs){throw Error('Encountered two consecutive interactive timestamps '+'with no navigationStart between them. '+'PostInteractiveTaskWindow is not well defined in this case.');}
 taskWindows.push(tr.b.math.Range.fromExplicitRange(currTTI,taskWindowEndTs));lastTaskWindowEndTs=taskWindowEndTs;}
 return taskWindows;}
-function contributionToEQT(window,task){var startInWindow=Math.max(window.min,task.start);var endInWindow=Math.min(window.max,task.end);var durationInWindow=endInWindow-startInWindow;if(durationInWindow<=0)return 0;var probabilityOfTask=durationInWindow/(window.max-window.min);var minQueueingTime=task.end-endInWindow;var maxQueueingTime=task.end-startInWindow;var expectedQueueingTimeDueToTask=(maxQueueingTime+minQueueingTime)/2;return probabilityOfTask*expectedQueueingTimeDueToTask;}
-function weightedExpectedQueueingTime(window,weightedTasks){var result=0;for(var task of weightedTasks){result+=contributionToEQT(window,task)*task.weight;}
+function contributionToEQT(window,task){const startInWindow=Math.max(window.min,task.start);const endInWindow=Math.min(window.max,task.end);const durationInWindow=endInWindow-startInWindow;if(durationInWindow<=0)return 0;const probabilityOfTask=durationInWindow/(window.max-window.min);const minQueueingTime=task.end-endInWindow;const maxQueueingTime=task.end-startInWindow;const expectedQueueingTimeDueToTask=(maxQueueingTime+minQueueingTime)/2;return probabilityOfTask*expectedQueueingTimeDueToTask;}
+function weightedExpectedQueueingTime(window,weightedTasks){let result=0;for(const task of weightedTasks){result+=contributionToEQT(window,task)*task.weight;}
 return result;}
 function expectedQueueingTime(window,tasks){return weightedExpectedQueueingTime(window,tasks.map(function(task){return{start:task.start,end:task.end,weight:1};}));}
 class SlidingWindow{constructor(startTime,windowSize,sortedTasks){this.windowSize_=windowSize;this.sortedTasks_=sortedTasks;this.range_=tr.b.math.Range.fromExplicitRange(startTime,startTime+windowSize);this.firstTaskIndex_=sortedTasks.findIndex(task=>startTime<task.end);if(this.firstTaskIndex_===-1){this.firstTaskIndex_=sortedTasks.length;}
 this.lastTaskIndex_=-1;while(this.lastTaskIndex_+1<sortedTasks.length&&sortedTasks[this.lastTaskIndex_+1].start<startTime+windowSize){this.lastTaskIndex_++;}
-this.innerEQT_=0;for(var i=this.firstTaskIndex_+1;i<this.lastTaskIndex_;i++){this.innerEQT_+=contributionToEQT(this.range_,sortedTasks[i]);}}
-get getEQT(){var firstTaskEQT=0;if(this.firstTaskIndex_<this.sortedTasks_.length){firstTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}
-var lastTaskEQT=0;if(this.firstTaskIndex_<this.lastTaskIndex_){lastTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
+this.innerEQT_=0;for(let i=this.firstTaskIndex_+1;i<this.lastTaskIndex_;i++){this.innerEQT_+=contributionToEQT(this.range_,sortedTasks[i]);}}
+get getEQT(){let firstTaskEQT=0;if(this.firstTaskIndex_<this.sortedTasks_.length){firstTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}
+let lastTaskEQT=0;if(this.firstTaskIndex_<this.lastTaskIndex_){lastTaskEQT=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
 return firstTaskEQT+this.innerEQT_+lastTaskEQT;}
 slide(t){this.range_=tr.b.math.Range.fromExplicitRange(t,t+this.windowSize_);if(this.firstTaskIndex_<this.sortedTasks_.length&&this.sortedTasks_[this.firstTaskIndex_].end<=t){this.firstTaskIndex_++;if(this.firstTaskIndex_<this.lastTaskIndex_){this.innerEQT_-=contributionToEQT(this.range_,this.sortedTasks_[this.firstTaskIndex_]);}}
 if(this.lastTaskIndex_+1<this.sortedTasks_.length&&this.sortedTasks_[this.lastTaskIndex_+1].start<t+this.windowSize_){if(this.firstTaskIndex_<this.lastTaskIndex_){this.innerEQT_+=contributionToEQT(this.range_,this.sortedTasks_[this.lastTaskIndex_]);}
 this.lastTaskIndex_++;}}}
 function maxExpectedQueueingTimeInSlidingWindow(startTime,endTime,windowSize,tasks){if(windowSize<=0){throw Error('The window size must be positive number');}
 if(startTime+windowSize>endTime){throw Error('The sliding window must fit in the specified time range');}
-var sortedTasks=tasks.slice().sort((a,b)=>a.start-b.start);for(var i=1;i<sortedTasks.length;i++){if(sortedTasks[i-1].end>sortedTasks[i].start+1e-3){throw Error('Tasks must not overlap');}}
-var endpoints=[];endpoints.push(startTime);endpoints.push(endTime-windowSize);for(var task of tasks){endpoints.push(task.start-windowSize);endpoints.push(task.start);endpoints.push(task.end-windowSize);endpoints.push(task.end);}
-endpoints=endpoints.filter(x=>(startTime<=x&&x+windowSize<=endTime));endpoints.sort((a,b)=>a-b);var slidingWindow=new SlidingWindow(endpoints[0],windowSize,sortedTasks);var maxEQT=0;for(var t of endpoints){slidingWindow.slide(t);maxEQT=Math.max(maxEQT,slidingWindow.getEQT);}
+const sortedTasks=tasks.slice().sort((a,b)=>a.start-b.start);for(let i=1;i<sortedTasks.length;i++){const PRECISION_MS=0.1;if(sortedTasks[i-1].end>sortedTasks[i].start+PRECISION_MS){throw Error('Tasks must not overlap');}
+if(sortedTasks[i-1].end>sortedTasks[i].start){const midpoint=(sortedTasks[i-1].end+sortedTasks[i].start)/2;sortedTasks[i-1].end=midpoint;sortedTasks[i].start=midpoint;}}
+let endpoints=[];endpoints.push(startTime);endpoints.push(endTime-windowSize);for(const task of tasks){endpoints.push(task.start-windowSize);endpoints.push(task.start);endpoints.push(task.end-windowSize);endpoints.push(task.end);}
+endpoints=endpoints.filter(x=>(startTime<=x&&x+windowSize<=endTime));endpoints.sort((a,b)=>a-b);const slidingWindow=new SlidingWindow(endpoints[0],windowSize,sortedTasks);let maxEQT=0;for(const t of endpoints){slidingWindow.slide(t);maxEQT=Math.max(maxEQT,slidingWindow.getEQT);}
 return maxEQT;}
-return{getPostInteractiveTaskWindows,getNavStartTimestamps,getInteractiveTimestamps,expectedQueueingTime,maxExpectedQueueingTimeInSlidingWindow,weightedExpectedQueueingTime};});'use strict';tr.exportTo('tr.metrics.sh',function(){const WINDOW_SIZE_MS=500;const EQT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,WINDOW_SIZE_MS,50);const V8_EVENT_NAMES_TO_FILTERS=new Map([['v8',tr.metrics.v8.utils.isV8Event],['v8:compile',tr.metrics.v8.utils.isCompileEvent],['v8:execute',tr.metrics.v8.utils.isV8ExecuteEvent],['v8:gc',tr.metrics.v8.utils.isGarbageCollectionEvent],['v8:gc:full-mark-compactor',tr.metrics.v8.utils.isFullMarkCompactorEvent],['v8:gc:incremental-marking',tr.metrics.v8.utils.isIncrementalMarkingEvent],['v8:gc:latency-mark-compactor',tr.metrics.v8.utils.isLatencyMarkCompactorEvent],['v8:gc:memory-mark-compactor',tr.metrics.v8.utils.isMemoryMarkCompactorEvent],['v8:gc:scavenger',tr.metrics.v8.utils.isScavengerEvent]]);function containsForcedGC_(slice){return slice.findTopmostSlicesRelativeToThisSlice(tr.metrics.v8.utils.isForcedGarbageCollectionEvent).length>0;}
-function createHistogramForEQT_(name,description){let histogram=new tr.v.Histogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,EQT_BOUNDARIES);histogram.customizeSummaryOptions({avg:false,count:false,max:true,min:false,std:false,sum:false,});histogram.description=description;return histogram;}
-function expectedQueueingTimeMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const totalHistogram=createHistogramForEQT_(`total:${WINDOW_SIZE_MS}ms_window:renderer_eqt`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer');const interactiveHistogram=createHistogramForEQT_(`interactive:${WINDOW_SIZE_MS}ms_window:renderer_eqt`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer while the page is interactive');const rendererHelpers=tr.b.dictionaryValues(chromeHelper.rendererHelpers);const rendererToInteractiveTimestamps=tr.e.chrome.getInteractiveTimestamps(model);for(let rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const tasks=rendererHelper.mainThread.sliceGroup.topLevelSlices.filter(slice=>slice.duration>0&&!containsForcedGC_(slice)).map(slice=>{return{start:slice.start,end:slice.end};});totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks));const interactiveTimestamps=rendererToInteractiveTimestamps.get(rendererHelper.pid);if(interactiveTimestamps.length===0)continue;if(interactiveTimestamps.length>1){continue;}
+return{getPostInteractiveTaskWindows,getNavStartTimestamps,getInteractiveTimestamps,expectedQueueingTime,maxExpectedQueueingTimeInSlidingWindow,weightedExpectedQueueingTime};});'use strict';tr.exportTo('tr.metrics.sh',function(){const WINDOW_SIZE_MS=500;const EQT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.01,WINDOW_SIZE_MS,50);const V8_EVENT_NAMES_TO_FILTERS=new Map([['v8',fromPredicate_(tr.metrics.v8.utils.isV8Event)],['v8:compile',fromPredicate_(tr.metrics.v8.utils.isCompileEvent)],['v8:compile:optimize',fromPredicate_(tr.metrics.v8.utils.isCompileOptimizeEvent)],['v8:compile:parse',fromPredicate_(tr.metrics.v8.utils.isCompileParseEvent)],['v8:compile:compile-unoptimize',filterCompileUnoptimizeAndSubtractParseEvents_],['v8:execute',fromPredicate_(tr.metrics.v8.utils.isV8ExecuteEvent)],['v8:gc',fromPredicate_(tr.metrics.v8.utils.isGarbageCollectionEvent)],['v8:gc:full-mark-compactor',fromPredicate_(tr.metrics.v8.utils.isFullMarkCompactorEvent)],['v8:gc:incremental-marking',fromPredicate_(tr.metrics.v8.utils.isIncrementalMarkingEvent)],['v8:gc:latency-mark-compactor',fromPredicate_(tr.metrics.v8.utils.isLatencyMarkCompactorEvent)],['v8:gc:memory-mark-compactor',fromPredicate_(tr.metrics.v8.utils.isMemoryMarkCompactorEvent)],['v8:gc:scavenger',fromPredicate_(tr.metrics.v8.utils.isScavengerEvent)]]);function fromPredicate_(eventPredicate){return function(slice){const duration=durationOfTopmostSubSlices(slice,eventPredicate);return{start:slice.start,end:slice.start+duration};};}
+function filterCompileUnoptimizeAndSubtractParseEvents_(slice){const duration=durationOfTopmostSubSlices(slice,tr.metrics.v8.utils.isCompileUnoptimizeEvent,tr.metrics.v8.utils.isCompileParseEvent);return{start:slice.start,end:slice.start+duration};}
+function containsForcedGC_(slice){return slice.findTopmostSlicesRelativeToThisSlice(tr.metrics.v8.utils.isForcedGarbageCollectionEvent).length>0;}
+function createHistogramForEQT_(name,description){const histogram=new tr.v.Histogram(name,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,EQT_BOUNDARIES);histogram.customizeSummaryOptions({avg:false,count:false,max:true,min:false,std:false,sum:false,});histogram.description=description;return histogram;}
+function expectedQueueingTimeMetric(histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const totalHistogram=createHistogramForEQT_(`total:${WINDOW_SIZE_MS}ms_window:renderer_eqt`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer');const interactiveHistogram=createHistogramForEQT_(`interactive:${WINDOW_SIZE_MS}ms_window:renderer_eqt`,`The maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window`+' for a given renderer while the page is interactive');const rendererHelpers=Object.values(chromeHelper.rendererHelpers);const rendererToInteractiveTimestamps=tr.e.chrome.getInteractiveTimestamps(model);for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const tasks=rendererHelper.mainThread.sliceGroup.topLevelSlices.filter(slice=>slice.duration>0&&!containsForcedGC_(slice)).map(slice=>{return{start:slice.start,end:slice.end};});totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks));const interactiveTimestamps=rendererToInteractiveTimestamps.get(rendererHelper.pid);if(interactiveTimestamps.length===0)continue;if(interactiveTimestamps.length>1){continue;}
 const interactiveWindow=tr.b.math.Range.fromExplicitRange(interactiveTimestamps[0],Infinity).findIntersection(rendererHelper.mainThread.bounds);interactiveHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(interactiveWindow.min,interactiveWindow.max,WINDOW_SIZE_MS,tasks));}
 addV8ContributionToExpectedQueueingTime(totalHistogram,interactiveHistogram,rendererToInteractiveTimestamps,histograms,model);histograms.addHistogram(totalHistogram);histograms.addHistogram(interactiveHistogram);}
-function addV8ContributionToExpectedQueueingTime(totalEqtHistogram,interactiveEqtHistogram,rendererToInteractiveTimestamps,histograms,model){if(!model.categories.includes('v8'))return;const breakdownForTotal=new tr.v.d.RelatedHistogramMap();const breakdownForInteractive=new tr.v.d.RelatedHistogramMap();for(let[eventName,filter]of V8_EVENT_NAMES_TO_FILTERS){const contribution=contributionToExpectedQueueingTime(filter,eventName,rendererToInteractiveTimestamps,histograms,model);breakdownForTotal.set(eventName,contribution.total);breakdownForInteractive.set(eventName,contribution.interactive);}
+function addV8ContributionToExpectedQueueingTime(totalEqtHistogram,interactiveEqtHistogram,rendererToInteractiveTimestamps,histograms,model){if(!model.categories.includes('v8'))return;const breakdownForTotal=new tr.v.d.RelatedHistogramMap();const breakdownForInteractive=new tr.v.d.RelatedHistogramMap();for(const[eventName,filterFunction]of V8_EVENT_NAMES_TO_FILTERS){const contribution=contributionToExpectedQueueingTime(filterFunction,eventName,rendererToInteractiveTimestamps,histograms,model);breakdownForTotal.set(eventName,contribution.total);breakdownForInteractive.set(eventName,contribution.interactive);}
 totalEqtHistogram.diagnostics.set('v8',breakdownForTotal);interactiveEqtHistogram.diagnostics.set('v8',breakdownForInteractive);}
-function durationOfTopmostSubSlices(slice,predicate){let duration=0;for(let sub of slice.findTopmostSlicesRelativeToThisSlice(predicate)){duration+=sub.duration;}
+function durationOfTopmostSubSlices(slice,predicate,subEventPredicate){let duration=0;for(const sub of slice.findTopmostSlicesRelativeToThisSlice(predicate)){duration+=sub.duration;if(subEventPredicate!==null&&subEventPredicate!==undefined){duration-=durationOfTopmostSubSlices(sub,subEventPredicate);}}
 return duration;}
-function contributionToExpectedQueueingTime(eventPredicate,eventName,rendererToInteractiveTimestamps,histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const totalHistogram=createHistogramForEQT_(`total:${WINDOW_SIZE_MS}ms_window:renderer_eqt:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer. It is computed as the maximum EQT in'+`a ${WINDOW_SIZE_MS}ms sliding window after shrinking top-level`+`tasks to contain only ${eventName}subevents`);const interactiveHistogram=createHistogramForEQT_(`interactive:${WINDOW_SIZE_MS}ms_window:renderer_eqt:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer while the page is interactive. It is computed'+`as the maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window after`+`shrinking top-level tasks to contain only ${eventName}subevents`);const rendererHelpers=tr.b.dictionaryValues(chromeHelper.rendererHelpers);for(let rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const tasks=rendererHelper.mainThread.sliceGroup.topLevelSlices.filter(slice=>slice.duration>0&&!containsForcedGC_(slice)).map(slice=>{return{start:slice.start,end:slice.start+
-durationOfTopmostSubSlices(slice,eventPredicate)};});totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks));const interactiveTimestamps=rendererToInteractiveTimestamps.get(rendererHelper.pid);if(interactiveTimestamps.length===0)continue;if(interactiveTimestamps.length>1){continue;}
+function contributionToExpectedQueueingTime(filterFunction,eventName,rendererToInteractiveTimestamps,histograms,model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const totalHistogram=createHistogramForEQT_(`total:${WINDOW_SIZE_MS}ms_window:renderer_eqt:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer. It is computed as the maximum EQT in'+` a ${WINDOW_SIZE_MS}ms sliding window after shrinking top-level`+` tasks to contain only ${eventName} subevents`);const interactiveHistogram=createHistogramForEQT_(`interactive:${WINDOW_SIZE_MS}ms_window:renderer_eqt:${eventName}`,`Contribution to the expected queueing time by ${eventName}`+' for a given renderer while the page is interactive. It is computed'+` as the maximum EQT in a ${WINDOW_SIZE_MS}ms sliding window after`+` shrinking top-level tasks to contain only ${eventName} subevents`);const rendererHelpers=Object.values(chromeHelper.rendererHelpers);for(const rendererHelper of rendererHelpers){if(rendererHelper.isChromeTracingUI)continue;const tasks=rendererHelper.mainThread.sliceGroup.topLevelSlices.filter(slice=>slice.duration>0&&!containsForcedGC_(slice)).map(filterFunction);totalHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(rendererHelper.mainThread.bounds.min,rendererHelper.mainThread.bounds.max,WINDOW_SIZE_MS,tasks));const interactiveTimestamps=rendererToInteractiveTimestamps.get(rendererHelper.pid);if(interactiveTimestamps.length===0)continue;if(interactiveTimestamps.length>1){continue;}
 const interactiveWindow=tr.b.math.Range.fromExplicitRange(interactiveTimestamps[0],Infinity).findIntersection(rendererHelper.mainThread.bounds);interactiveHistogram.addSample(tr.e.chrome.maxExpectedQueueingTimeInSlidingWindow(interactiveWindow.min,interactiveWindow.max,WINDOW_SIZE_MS,tasks));}
 histograms.addHistogram(totalHistogram);histograms.addHistogram(interactiveHistogram);return{total:totalHistogram,interactive:interactiveHistogram};}
-tr.metrics.MetricRegistry.register(expectedQueueingTimeMetric);return{expectedQueueingTimeMetric,contributionToExpectedQueueingTime,};});'use strict';tr.exportTo('tr.metrics.sh',function(){var LONG_TASK_MS=50;var LONGEST_TASK_MS=1000;function iterateLongTopLevelTasksOnThreadInRange(thread,opt_range,cb,opt_this){thread.sliceGroup.topLevelSlices.forEach(function(slice){if(opt_range&&!opt_range.intersectsExplicitRangeInclusive(slice.start,slice.end)){return;}
+tr.metrics.MetricRegistry.register(expectedQueueingTimeMetric);return{expectedQueueingTimeMetric,contributionToExpectedQueueingTime,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const LONG_TASK_MS=50;const LONGEST_TASK_MS=1000;function iterateLongTopLevelTasksOnThreadInRange(thread,opt_range,cb,opt_this){thread.sliceGroup.topLevelSlices.forEach(function(slice){if(opt_range&&!opt_range.intersectsExplicitRangeInclusive(slice.start,slice.end)){return;}
 if(slice.duration<LONG_TASK_MS)return;cb.call(opt_this,slice);});}
-function iterateRendererMainThreads(model,cb,opt_this){var modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper!==undefined){tr.b.dictionaryValues(modelHelper.rendererHelpers).forEach(function(rendererHelper){if(!rendererHelper.mainThread)return;cb.call(opt_this,rendererHelper.mainThread);});}}
-function longTasksMetric(histograms,model,opt_options){var rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;var longTaskHist=new tr.v.Histogram('long tasks',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(LONG_TASK_MS,LONGEST_TASK_MS,40));longTaskHist.description='durations of long tasks';var slices=new tr.model.EventSet();iterateRendererMainThreads(model,function(thread){iterateLongTopLevelTasksOnThreadInRange(thread,rangeOfInterest,function(task){longTaskHist.addSample(task.duration,{relatedEvents:new tr.v.d.RelatedEventSet([task])});slices.push(task);slices.addEventSet(task.descendentSlices);});});histograms.addHistogram(longTaskHist);var sampleForEvent=undefined;var breakdown=tr.v.d.RelatedHistogramBreakdown.buildFromEvents(histograms,'long tasks ',slices,e=>(model.getUserFriendlyCategoryFromEvent(e)||'unknown'),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,sampleForEvent,tr.v.HistogramBinBoundaries.createExponential(1,LONGEST_TASK_MS,40));breakdown.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;longTaskHist.diagnostics.set('category',breakdown);}
-tr.metrics.MetricRegistry.register(longTasksMetric,{supportsRangeOfInterest:true});return{longTasksMetric,iterateLongTopLevelTasksOnThreadInRange,iterateRendererMainThreads,LONG_TASK_MS,LONGEST_TASK_MS,};});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,valueCount){this.title=title;var dimensions=title.length;this.children=new Array(dimensions);for(var i=0;i<dimensions;i++){this.children[i]=new Map();}
-this.values=new Array(valueCount);for(var v=0;v<valueCount;v++){this.values[v]={self:0,total:0,totalState:NOT_PROVIDED};}}
-MultiDimensionalViewNode.TotalState={NOT_PROVIDED:0,LOWER_BOUND:1,EXACT:2};var NOT_PROVIDED=MultiDimensionalViewNode.TotalState.NOT_PROVIDED;var LOWER_BOUND=MultiDimensionalViewNode.TotalState.LOWER_BOUND;var EXACT=MultiDimensionalViewNode.TotalState.EXACT;MultiDimensionalViewNode.prototype={get subRows(){return tr.b.mapValues(this.children[0]);}};function MultiDimensionalViewBuilder(dimensions,valueCount){if(typeof(dimensions)!=='number'||dimensions<0){throw new Error('Dimensions must be a non-negative number');}
+function iterateRendererMainThreads(model,cb,opt_this){const modelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(modelHelper!==undefined){Object.values(modelHelper.rendererHelpers).forEach(function(rendererHelper){if(!rendererHelper.mainThread)return;cb.call(opt_this,rendererHelper.mainThread);});}}
+function longTasksMetric(histograms,model,opt_options){const rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;const longTaskHist=new tr.v.Histogram('long tasks',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(LONG_TASK_MS,LONGEST_TASK_MS,40));longTaskHist.description='durations of long tasks';const slices=new tr.model.EventSet();iterateRendererMainThreads(model,function(thread){iterateLongTopLevelTasksOnThreadInRange(thread,rangeOfInterest,function(task){longTaskHist.addSample(task.duration,{relatedEvents:new tr.v.d.RelatedEventSet([task])});slices.push(task);slices.addEventSet(task.descendentSlices);});});histograms.addHistogram(longTaskHist);const sampleForEvent=undefined;const breakdown=tr.v.d.RelatedHistogramBreakdown.buildFromEvents(histograms,'long tasks ',slices,e=>(model.getUserFriendlyCategoryFromEvent(e)||'unknown'),tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,sampleForEvent,tr.v.HistogramBinBoundaries.createExponential(1,LONGEST_TASK_MS,40));breakdown.colorScheme=tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER;longTaskHist.diagnostics.set('category',breakdown);}
+tr.metrics.MetricRegistry.register(longTasksMetric,{supportsRangeOfInterest:true});return{longTasksMetric,iterateLongTopLevelTasksOnThreadInRange,iterateRendererMainThreads,LONG_TASK_MS,LONGEST_TASK_MS,};});'use strict';tr.exportTo('tr.b',function(){function MultiDimensionalViewNode(title,valueCount){this.title=title;const dimensions=title.length;this.children=new Array(dimensions);for(let i=0;i<dimensions;i++){this.children[i]=new Map();}
+this.values=new Array(valueCount);for(let v=0;v<valueCount;v++){this.values[v]={self:0,total:0,totalState:NOT_PROVIDED};}}
+MultiDimensionalViewNode.TotalState={NOT_PROVIDED:0,LOWER_BOUND:1,EXACT:2};const NOT_PROVIDED=MultiDimensionalViewNode.TotalState.NOT_PROVIDED;const LOWER_BOUND=MultiDimensionalViewNode.TotalState.LOWER_BOUND;const EXACT=MultiDimensionalViewNode.TotalState.EXACT;MultiDimensionalViewNode.prototype={get subRows(){return tr.b.mapValues(this.children[0]);}};function MultiDimensionalViewBuilder(dimensions,valueCount){if(typeof(dimensions)!=='number'||dimensions<0){throw new Error('Dimensions must be a non-negative number');}
 this.dimensions_=dimensions;if(typeof(valueCount)!=='number'||valueCount<0){throw new Error('Number of values must be a non-negative number');}
-this.valueCount_=valueCount;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.maxDimensionDepths_=new Array(dimensions);for(var d=0;d<dimensions;d++){this.maxDimensionDepths_[d]=0;}}
-MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.ViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};MultiDimensionalViewBuilder.prototype={addPath:function(path,values,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
+this.valueCount_=valueCount;this.buildRoot_=this.createRootNode_();this.topDownTreeViewRoot_=undefined;this.topDownHeavyViewRoot_=undefined;this.bottomUpHeavyViewNode_=undefined;this.complete_=false;this.maxDimensionDepths_=new Array(dimensions);for(let d=0;d<dimensions;d++){this.maxDimensionDepths_[d]=0;}}
+MultiDimensionalViewBuilder.ValueKind={SELF:0,TOTAL:1};MultiDimensionalViewBuilder.ViewType={TOP_DOWN_TREE_VIEW:0,TOP_DOWN_HEAVY_VIEW:1,BOTTOM_UP_HEAVY_VIEW:2};MultiDimensionalViewBuilder.prototype={addPath(path,values,valueKind){if(this.buildRoot_===undefined){throw new Error('Paths cannot be added after either view has been built');}
 if(path.length!==this.dimensions_){throw new Error('Path must be '+this.dimensions_+'-dimensional');}
 if(values.length!==this.valueCount_){throw new Error('Must provide '+this.valueCount_+' values');}
-var isTotal;switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:isTotal=false;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:isTotal=true;break;default:throw new Error('Invalid value kind: '+valueKind);}
-var node=this.buildRoot_;for(var d=0;d<path.length;d++){var singleDimensionPath=path[d];var singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(var i=0;i<singleDimensionPathLength;i++){node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}}
-for(var v=0;v<this.valueCount_;v++){var addedValue=values[v];if(addedValue===undefined)continue;var nodeValue=node.values[v];if(isTotal){nodeValue.total+=addedValue;nodeValue.totalState=EXACT;}else{nodeValue.self+=addedValue;nodeValue.totalState=Math.max(nodeValue.totalState,LOWER_BOUND);}}},buildView:function(viewType){switch(viewType){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView:function(){if(this.topDownTreeViewRoot_===undefined){var treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
-return this.topDownTreeViewRoot_;},buildTopDownHeavyView:function(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
-return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView:function(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
-return this.bottomUpHeavyViewNode_;},createRootNode_:function(){return new MultiDimensionalViewNode(new Array(this.dimensions_),this.valueCount_);},getOrCreateChildNode_:function(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_){throw new Error('Invalid dimension');}
-var dimensionChildren=parentNode.children[dimension];var childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined){return childNode;}
-var childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,this.valueCount_);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_:function(node,firstDimensionToSetUp){for(var d=firstDimensionToSetUp;d<this.dimensions_;d++){var currentDimensionChildTitles=new Set(node.children[d].keys());for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){for(var previousDimensionGrandChildTitle of
+let isTotal;switch(valueKind){case MultiDimensionalViewBuilder.ValueKind.SELF:isTotal=false;break;case MultiDimensionalViewBuilder.ValueKind.TOTAL:isTotal=true;break;default:throw new Error('Invalid value kind: '+valueKind);}
+let node=this.buildRoot_;for(let d=0;d<path.length;d++){const singleDimensionPath=path[d];const singleDimensionPathLength=singleDimensionPath.length;this.maxDimensionDepths_[d]=Math.max(this.maxDimensionDepths_[d],singleDimensionPathLength);for(let i=0;i<singleDimensionPathLength;i++){node=this.getOrCreateChildNode_(node,d,singleDimensionPath[i]);}}
+for(let v=0;v<this.valueCount_;v++){const addedValue=values[v];if(addedValue===undefined)continue;const nodeValue=node.values[v];if(isTotal){nodeValue.total+=addedValue;nodeValue.totalState=EXACT;}else{nodeValue.self+=addedValue;nodeValue.totalState=Math.max(nodeValue.totalState,LOWER_BOUND);}}},get complete(){return this.complete_;},set complete(isComplete){if(this.buildRoot_===undefined){throw new Error('Can\'t set complete after any view has been built.');}
+this.complete_=isComplete;},buildView(viewType){switch(viewType){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW:return this.buildTopDownTreeView();case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:return this.buildTopDownHeavyView();case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return this.buildBottomUpHeavyView();default:throw new Error('Unknown multi-dimensional view type: '+viewType);}},buildTopDownTreeView(){if(this.topDownTreeViewRoot_===undefined){const treeViewRoot=this.buildRoot_;this.buildRoot_=undefined;this.setUpMissingChildRelationships_(treeViewRoot,0);this.finalizeTotalValues_(treeViewRoot,0,new WeakMap());this.topDownTreeViewRoot_=treeViewRoot;}
+return this.topDownTreeViewRoot_;},buildTopDownHeavyView(){if(this.topDownHeavyViewRoot_===undefined){this.topDownHeavyViewRoot_=this.buildGenericHeavyView_(this.addDimensionToTopDownHeavyViewNode_.bind(this));}
+return this.topDownHeavyViewRoot_;},buildBottomUpHeavyView(){if(this.bottomUpHeavyViewNode_===undefined){this.bottomUpHeavyViewNode_=this.buildGenericHeavyView_(this.addDimensionToBottomUpHeavyViewNode_.bind(this));}
+return this.bottomUpHeavyViewNode_;},createRootNode_(){return new MultiDimensionalViewNode(new Array(this.dimensions_),this.valueCount_);},getOrCreateChildNode_(parentNode,dimension,childDimensionTitle){if(dimension<0||dimension>=this.dimensions_){throw new Error('Invalid dimension');}
+const dimensionChildren=parentNode.children[dimension];let childNode=dimensionChildren.get(childDimensionTitle);if(childNode!==undefined){return childNode;}
+const childTitle=parentNode.title.slice();childTitle[dimension]=childDimensionTitle;childNode=new MultiDimensionalViewNode(childTitle,this.valueCount_);dimensionChildren.set(childDimensionTitle,childNode);return childNode;},setUpMissingChildRelationships_(node,firstDimensionToSetUp){for(let d=firstDimensionToSetUp;d<this.dimensions_;d++){const currentDimensionChildTitles=new Set(node.children[d].keys());for(let i=0;i<d;i++){for(const previousDimensionChildNode of node.children[i].values()){for(const previousDimensionGrandChildTitle of
 previousDimensionChildNode.children[d].keys()){currentDimensionChildTitles.add(previousDimensionGrandChildTitle);}}}
-for(var currentDimensionChildTitle of currentDimensionChildTitles){var currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(var i=0;i<d;i++){for(var previousDimensionChildNode of node.children[i].values()){var previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
-this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_:function(node,firstDimensionToFinalize,dimensionalSelfSumsMap){var dimensionalSelfSums=new Array(this.dimensions_);var minResidual=new Array(this.valueCount_);for(var v=0;v<this.valueCount_;v++)minResidual[v]=0;var nodeValues=node.values;var nodeSelfSums=new Array(this.valueCount_);for(var v=0;v<this.valueCount_;v++){nodeSelfSums[v]=nodeValues[v].self;}
-for(var d=0;d<this.dimensions_;d++){var childResidualSums=new Array(this.valueCount_);for(var v=0;v<this.valueCount_;v++){childResidualSums[v]=0;}
-for(var childNode of node.children[d].values()){if(d>=firstDimensionToFinalize){this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);}
-var childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);var childNodeValues=childNode.values;for(var v=0;v<this.valueCount_;v++){nodeSelfSums[v]+=childNodeSelfSums[d][v];var residual=childNodeValues[v].total-
-childNodeSelfSums[this.dimensions_-1][v];childResidualSums[v]+=residual;if(childNodeValues[v].totalState>NOT_PROVIDED){nodeValues[v].totalState=Math.max(nodeValues[v].totalState,LOWER_BOUND);}}}
-dimensionalSelfSums[d]=nodeSelfSums.slice();for(var v=0;v<this.valueCount_;v++){minResidual[v]=Math.max(minResidual[v],childResidualSums[v]);}}
-for(var v=0;v<this.valueCount_;v++){nodeValues[v].total=Math.max(nodeValues[v].total,nodeSelfSums[v]+minResidual[v]);}
+for(const currentDimensionChildTitle of currentDimensionChildTitles){const currentDimensionChildNode=this.getOrCreateChildNode_(node,d,currentDimensionChildTitle);for(let i=0;i<d;i++){for(const previousDimensionChildNode of
+node.children[i].values()){const previousDimensionGrandChildNode=previousDimensionChildNode.children[d].get(currentDimensionChildTitle);if(previousDimensionGrandChildNode!==undefined){currentDimensionChildNode.children[i].set(previousDimensionChildNode.title[i],previousDimensionGrandChildNode);}}}
+this.setUpMissingChildRelationships_(currentDimensionChildNode,d);}}},finalizeTotalValues_(node,firstDimensionToFinalize,dimensionalSelfSumsMap){const dimensionalSelfSums=new Array(this.dimensions_);const minResidual=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++)minResidual[v]=0;const nodeValues=node.values;const nodeSelfSums=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++){nodeSelfSums[v]=nodeValues[v].self;}
+for(let d=0;d<this.dimensions_;d++){const childResidualSums=new Array(this.valueCount_);for(let v=0;v<this.valueCount_;v++){childResidualSums[v]=0;}
+for(const childNode of node.children[d].values()){if(d>=firstDimensionToFinalize){this.finalizeTotalValues_(childNode,d,dimensionalSelfSumsMap);}
+const childNodeSelfSums=dimensionalSelfSumsMap.get(childNode);const childNodeValues=childNode.values;for(let v=0;v<this.valueCount_;v++){nodeSelfSums[v]+=childNodeSelfSums[d][v];const residual=childNodeValues[v].total-
+childNodeSelfSums[this.dimensions_-1][v];childResidualSums[v]+=residual;if(this.complete){nodeValues[v].totalState=EXACT;}else if(childNodeValues[v].totalState>NOT_PROVIDED){nodeValues[v].totalState=Math.max(nodeValues[v].totalState,LOWER_BOUND);}}}
+dimensionalSelfSums[d]=nodeSelfSums.slice();for(let v=0;v<this.valueCount_;v++){minResidual[v]=Math.max(minResidual[v],childResidualSums[v]);}}
+for(let v=0;v<this.valueCount_;v++){nodeValues[v].total=Math.max(nodeValues[v].total,nodeSelfSums[v]+minResidual[v]);}
 if(dimensionalSelfSumsMap.has(node)){throw new Error('Internal error: Node finalized more than once');}
-dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_:function(treeViewNodeHandler){var treeViewRoot=this.buildTopDownTreeView();var heavyViewRoot=this.createRootNode_();heavyViewRoot.values=treeViewRoot.values;var recursionDepthTrackers=new Array(this.dimensions_);for(var d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
-this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(var d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_:function(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){var treeViewChildren=treeViewParentNode.children[currentDimension];var recursionDepthTracker=recursionDepthTrackers[currentDimension];for(var treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;var dimensionTitle=treeViewChildNode.title[currentDimension];var heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);this.addNodeValues_(treeViewChildNode,heavyViewChildNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(var treeViewGrandChildNode of
-treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_:function(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){var recursionDepthTracker=recursionDepthTrackers[currentDimension];var bottomIndex=recursionDepthTracker.bottomIndex;var topIndex=recursionDepthTracker.topIndex;var firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;var viewNodePath=recursionDepthTracker.viewNodePath;var trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;var heavyViewDescendantNode=heavyViewParentNode;for(var i=bottomIndex;i<topIndex;i++){var treeViewAncestorNode=viewNodePath[i];var dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);var currentDimensionRecursive=i<firstNonRecursiveIndex;var currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;this.addNodeValues_(treeViewChildNode,heavyViewDescendantNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}},addNodeValues_:function(sourceNode,targetNode,addTotal){var targetNodeValues=targetNode.values;var sourceNodeValues=sourceNode.values;for(var v=0;v<this.valueCount_;v++){var targetNodeValue=targetNodeValues[v];var sourceNodeValue=sourceNodeValues[v];targetNodeValue.self+=sourceNodeValue.self;if(addTotal){targetNodeValue.total+=sourceNodeValue.total;if(sourceNodeValue.totalState>NOT_PROVIDED){targetNodeValue.totalState=Math.max(targetNodeValue.totalState,LOWER_BOUND);}}}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
-RecursionDepthTracker.prototype={push:function(viewNode){if(this.bottomIndex===0){throw new Error('Cannot push to a full tracker');}
-var title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;var childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
-var maxLengths=zFunction(this.titlePath,this.bottomIndex);var recursionDepth=0;for(var i=0;i<maxLengths.length;i++){recursionDepth=Math.max(recursionDepth,maxLengths[i]);}
-childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop:function(){if(this.bottomIndex===this.topIndex){throw new Error('Cannot pop from an empty tracker');}
-this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_:function(recursionDepth,parent){return{recursionDepth:recursionDepth,parent:parent,children:new Map()};}};function zFunction(list,startIndex){var n=list.length-startIndex;if(n===0)return[];var z=new Array(n);z[0]=0;for(var i=1,left=0,right=0;i<n;++i){var maxLength;if(i<=right){maxLength=Math.min(right-i+1,z[i-left]);}else{maxLength=0;}
+dimensionalSelfSumsMap.set(node,dimensionalSelfSums);},buildGenericHeavyView_(treeViewNodeHandler){const treeViewRoot=this.buildTopDownTreeView();const heavyViewRoot=this.createRootNode_();heavyViewRoot.values=treeViewRoot.values;const recursionDepthTrackers=new Array(this.dimensions_);for(let d=0;d<this.dimensions_;d++){recursionDepthTrackers[d]=new RecursionDepthTracker(this.maxDimensionDepths_[d],d);}
+this.addDimensionsToGenericHeavyViewNode_(treeViewRoot,heavyViewRoot,0,recursionDepthTrackers,false,treeViewNodeHandler);this.setUpMissingChildRelationships_(heavyViewRoot,0);return heavyViewRoot;},addDimensionsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,startDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){for(let d=startDimension;d<this.dimensions_;d++){this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,d,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);}},addDimensionDescendantsToGenericHeavyViewNode_(treeViewParentNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler){const treeViewChildren=treeViewParentNode.children[currentDimension];const recursionDepthTracker=recursionDepthTrackers[currentDimension];for(const treeViewChildNode of treeViewChildren.values()){recursionDepthTracker.push(treeViewChildNode);treeViewNodeHandler(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive);this.addDimensionDescendantsToGenericHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,treeViewNodeHandler);recursionDepthTracker.pop();}},addDimensionToTopDownHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,1);},addDimensionToTopDownHeavyViewNodeRecursively_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth){const recursionDepthTracker=recursionDepthTrackers[currentDimension];const currentDimensionRecursive=subTreeDepth<=recursionDepthTracker.recursionDepth;const currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;const dimensionTitle=treeViewChildNode.title[currentDimension];const heavyViewChildNode=this.getOrCreateChildNode_(heavyViewParentNode,currentDimension,dimensionTitle);this.addNodeValues_(treeViewChildNode,heavyViewChildNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewChildNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToTopDownHeavyViewNode_.bind(this));for(const treeViewGrandChildNode of
+treeViewChildNode.children[currentDimension].values()){recursionDepthTracker.push(treeViewGrandChildNode);this.addDimensionToTopDownHeavyViewNodeRecursively_(treeViewGrandChildNode,heavyViewChildNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive,subTreeDepth+1);recursionDepthTracker.pop();}},addDimensionToBottomUpHeavyViewNode_(treeViewChildNode,heavyViewParentNode,currentDimension,recursionDepthTrackers,previousDimensionsRecursive){const recursionDepthTracker=recursionDepthTrackers[currentDimension];const bottomIndex=recursionDepthTracker.bottomIndex;const topIndex=recursionDepthTracker.topIndex;const firstNonRecursiveIndex=bottomIndex+recursionDepthTracker.recursionDepth;const viewNodePath=recursionDepthTracker.viewNodePath;const trackerAncestorNode=recursionDepthTracker.trackerAncestorNode;let heavyViewDescendantNode=heavyViewParentNode;for(let i=bottomIndex;i<topIndex;i++){const treeViewAncestorNode=viewNodePath[i];const dimensionTitle=treeViewAncestorNode.title[currentDimension];heavyViewDescendantNode=this.getOrCreateChildNode_(heavyViewDescendantNode,currentDimension,dimensionTitle);const currentDimensionRecursive=i<firstNonRecursiveIndex;const currentOrPreviousDimensionsRecursive=currentDimensionRecursive||previousDimensionsRecursive;this.addNodeValues_(treeViewChildNode,heavyViewDescendantNode,!currentOrPreviousDimensionsRecursive);this.addDimensionsToGenericHeavyViewNode_(treeViewChildNode,heavyViewDescendantNode,currentDimension+1,recursionDepthTrackers,currentOrPreviousDimensionsRecursive,this.addDimensionToBottomUpHeavyViewNode_.bind(this));}},addNodeValues_(sourceNode,targetNode,addTotal){const targetNodeValues=targetNode.values;const sourceNodeValues=sourceNode.values;for(let v=0;v<this.valueCount_;v++){const targetNodeValue=targetNodeValues[v];const sourceNodeValue=sourceNodeValues[v];targetNodeValue.self+=sourceNodeValue.self;if(addTotal){targetNodeValue.total+=sourceNodeValue.total;if(this.complete){targetNodeValue.totalState=EXACT;}else if(sourceNodeValue.totalState>NOT_PROVIDED){targetNodeValue.totalState=Math.max(targetNodeValue.totalState,LOWER_BOUND);}}}}};function RecursionDepthTracker(maxDepth,dimension){this.titlePath=new Array(maxDepth);this.viewNodePath=new Array(maxDepth);this.bottomIndex=this.topIndex=maxDepth;this.dimension_=dimension;this.currentTrackerNode_=this.createNode_(0,undefined);}
+RecursionDepthTracker.prototype={push(viewNode){if(this.bottomIndex===0){throw new Error('Cannot push to a full tracker');}
+const title=viewNode.title[this.dimension_];this.bottomIndex--;this.titlePath[this.bottomIndex]=title;this.viewNodePath[this.bottomIndex]=viewNode;let childTrackerNode=this.currentTrackerNode_.children.get(title);if(childTrackerNode!==undefined){this.currentTrackerNode_=childTrackerNode;return;}
+const maxLengths=zFunction(this.titlePath,this.bottomIndex);let recursionDepth=0;for(let i=0;i<maxLengths.length;i++){recursionDepth=Math.max(recursionDepth,maxLengths[i]);}
+childTrackerNode=this.createNode_(recursionDepth,this.currentTrackerNode_);this.currentTrackerNode_.children.set(title,childTrackerNode);this.currentTrackerNode_=childTrackerNode;},pop(){if(this.bottomIndex===this.topIndex){throw new Error('Cannot pop from an empty tracker');}
+this.titlePath[this.bottomIndex]=undefined;this.viewNodePath[this.bottomIndex]=undefined;this.bottomIndex++;this.currentTrackerNode_=this.currentTrackerNode_.parent;},get recursionDepth(){return this.currentTrackerNode_.recursionDepth;},createNode_(recursionDepth,parent){return{recursionDepth,parent,children:new Map()};}};function zFunction(list,startIndex){const n=list.length-startIndex;if(n===0)return[];const z=new Array(n);z[0]=0;for(let i=1,left=0,right=0;i<n;++i){let maxLength;if(i<=right){maxLength=Math.min(right-i+1,z[i-left]);}else{maxLength=0;}
 while(i+maxLength<n&&list[startIndex+maxLength]===list[startIndex+i+maxLength]){++maxLength;}
 if(i+maxLength-1>right){left=i;right=i+maxLength-1;}
 z[i]=maxLength;}
 return z;}
 return{MultiDimensionalViewBuilder,MultiDimensionalViewNode,RecursionDepthTracker,zFunction,};});'use strict';tr.exportTo('tr.b',function(){class FixedColorScheme{constructor(namesToColors){this.namesToColors_=namesToColors;}
-static fromNames(names){var namesToColors=new Map();var generator=new tr.b.SinebowColorGenerator();for(var name of names){namesToColors.set(name,generator.colorForKey(name));}
+static fromNames(names){const namesToColors=new Map();const generator=new tr.b.SinebowColorGenerator();for(const name of names){namesToColors.set(name,generator.colorForKey(name));}
 return new FixedColorScheme(namesToColors);}
-getColor(name){var color=this.namesToColors_.get(name);if(color===undefined)throw new Error('Unknown color: '+name);return color;}}
-var MemoryColumnColorScheme=new FixedColorScheme(new Map([['used_memory_column',new tr.b.Color(0,0,255)],['older_used_memory_column',new tr.b.Color(153,204,255)],['tracing_memory_column',new tr.b.Color(153,153,153)]]));function FixedColorSchemeRegistry(){}
-FixedColorSchemeRegistry.lookUp=function(name){var info=this.findTypeInfoMatching(info=>info.metadata.name===name);if(!info)return undefined;return info.constructor();};var options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(FixedColorSchemeRegistry,options);return{MemoryColumnColorScheme,FixedColorScheme,FixedColorSchemeRegistry,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CHROME_PROCESS_NAMES={BROWSER:'browser_process',RENDERER:'renderer_processes',ALL:'all_processes',GPU:'gpu_process',PPAPI:'ppapi_process',UNKNOWN:'unknown_processes',};const PROCESS_COLOR_SCHEME_NAME='ChromeProcessNames';const PROCESS_COLOR_SCHEME=tr.b.FixedColorScheme.fromNames(Object.values(CHROME_PROCESS_NAMES));tr.b.FixedColorSchemeRegistry.register(()=>PROCESS_COLOR_SCHEME,{'name':PROCESS_COLOR_SCHEME_NAME,});return{CHROME_PROCESS_NAMES,PROCESS_COLOR_SCHEME,PROCESS_COLOR_SCHEME_NAME,};});'use strict';tr.exportTo('tr.metrics.sh',function(){var BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;var sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;var count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var LEVEL_OF_DETAIL_NAMES=new Map();LEVEL_OF_DETAIL_NAMES.set(BACKGROUND,'background');LEVEL_OF_DETAIL_NAMES.set(LIGHT,'light');LEVEL_OF_DETAIL_NAMES.set(DETAILED,'detailed');var HEAP_PROFILER_DETAIL_NAME='heap_profiler';var BOUNDARIES_FOR_UNIT_MAP=new WeakMap();BOUNDARIES_FOR_UNIT_MAP.set(count_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,20,20));BOUNDARIES_FOR_UNIT_MAP.set(sizeInBytes_smallerIsBetter,new tr.v.HistogramBinBoundaries(0).addBinBoundary(1024).addExponentialBins(16*1024*1024*1024,4*24));var CHROME_PROCESS_NAMES=tr.metrics.sh.CHROME_PROCESS_NAMES;var PROCESS_COLOR_SCHEME=tr.metrics.sh.PROCESS_COLOR_SCHEME;var PROCESS_COLOR_SCHEME_NAME=tr.metrics.sh.PROCESS_COLOR_SCHEME_NAME;function memoryMetric(values,model,opt_options){var rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;var browserNameToGlobalDumps=splitGlobalDumpsByBrowserName(model,rangeOfInterest);addGeneralMemoryDumpValues(browserNameToGlobalDumps,values);addDetailedMemoryDumpValues(browserNameToGlobalDumps,values);addMemoryDumpCountValues(browserNameToGlobalDumps,values);}
-function splitGlobalDumpsByBrowserName(model,opt_rangeOfInterest){var chromeModelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);var browserNameToGlobalDumps=new Map();var globalDumpToBrowserHelper=new WeakMap();if(chromeModelHelper){chromeModelHelper.browserHelpers.forEach(function(helper){var globalDumps=skipDumpsThatDoNotIntersectRange(helper.process.memoryDumps.map(d=>d.globalMemoryDump),opt_rangeOfInterest);globalDumps.forEach(function(globalDump){var existingHelper=globalDumpToBrowserHelper.get(globalDump);if(existingHelper!==undefined){throw new Error('Memory dump ID clash across multiple browsers '+'with PIDs: '+existingHelper.pid+' and '+helper.pid);}
-globalDumpToBrowserHelper.set(globalDump,helper);});makeKeyUniqueAndSet(browserNameToGlobalDumps,canonicalizeName(helper.browserName),globalDumps);});}
-var unclassifiedGlobalDumps=skipDumpsThatDoNotIntersectRange(model.globalMemoryDumps.filter(g=>!globalDumpToBrowserHelper.has(g)),opt_rangeOfInterest);if(unclassifiedGlobalDumps.length>0){makeKeyUniqueAndSet(browserNameToGlobalDumps,'unknown_browser',unclassifiedGlobalDumps);}
-return browserNameToGlobalDumps;}
-function skipDumpsThatDoNotIntersectRange(dumps,opt_range){if(!opt_range)return dumps;return dumps.filter(d=>opt_range.intersectsExplicitRangeInclusive(d.start,d.end));}
-function canonicalizeName(name){return name.toLowerCase().replace(' ','_');}
-var USER_FRIENDLY_BROWSER_NAMES={'chrome':'Chrome','webview':'WebView','unknown_browser':'an unknown browser'};function convertBrowserNameToUserFriendlyName(browserName){for(var baseName in USER_FRIENDLY_BROWSER_NAMES){if(!browserName.startsWith(baseName))continue;var userFriendlyBaseName=USER_FRIENDLY_BROWSER_NAMES[baseName];var suffix=browserName.substring(baseName.length);if(suffix.length===0){return userFriendlyBaseName;}else if(/^\d+$/.test(suffix)){return userFriendlyBaseName+'('+suffix+')';}}
-return'\''+browserName+'\' browser';}
+getColor(name){const color=this.namesToColors_.get(name);if(color===undefined)throw new Error('Unknown color: '+name);return color;}}
+const MemoryColumnColorScheme=new FixedColorScheme(new Map([['used_memory_column',new tr.b.Color(0,0,255)],['older_used_memory_column',new tr.b.Color(153,204,255)],['tracing_memory_column',new tr.b.Color(153,153,153)]]));function FixedColorSchemeRegistry(){}
+FixedColorSchemeRegistry.lookUp=function(name){const info=this.findTypeInfoMatching(info=>info.metadata.name===name);if(!info)return undefined;return info.constructor();};const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);tr.b.decorateExtensionRegistry(FixedColorSchemeRegistry,options);return{MemoryColumnColorScheme,FixedColorScheme,FixedColorSchemeRegistry,};});'use strict';tr.exportTo('tr.e.chrome.chrome_processes',function(){const CHROME_PROCESS_NAMES={BROWSER:'browser_process',RENDERER:'renderer_processes',ALL:'all_processes',GPU:'gpu_process',PPAPI:'ppapi_process',UNKNOWN:'unknown_processes',};const PROCESS_COLOR_SCHEME_NAME='ChromeProcessNames';const PROCESS_COLOR_SCHEME=tr.b.FixedColorScheme.fromNames(Object.values(CHROME_PROCESS_NAMES));tr.b.FixedColorSchemeRegistry.register(()=>PROCESS_COLOR_SCHEME,{name:PROCESS_COLOR_SCHEME_NAME,});function canonicalizeName(name){return name.toLowerCase().replace(' ','_');}
 function canonicalizeProcessName(rawProcessName){if(!rawProcessName)return CHROME_PROCESS_NAMES.UNKNOWN;const baseCanonicalName=canonicalizeName(rawProcessName);switch(baseCanonicalName){case'renderer':return CHROME_PROCESS_NAMES.RENDERER;case'browser':return CHROME_PROCESS_NAMES.BROWSER;}
 if(Object.values(CHROME_PROCESS_NAMES).includes(baseCanonicalName)){return baseCanonicalName;}
-throw new Error(`Unknown process id"${baseCanonicalName}".`+' Please add it to |CHROME_PROCESS_NAMES|.');}
+throw new Error(`Unknown process name "${baseCanonicalName}".`+' Please add it to |CHROME_PROCESS_NAMES|.');}
+return{CHROME_PROCESS_NAMES,PROCESS_COLOR_SCHEME,PROCESS_COLOR_SCHEME_NAME,canonicalizeName,canonicalizeProcessName,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const LEVEL_OF_DETAIL_NAMES=new Map();LEVEL_OF_DETAIL_NAMES.set(BACKGROUND,'background');LEVEL_OF_DETAIL_NAMES.set(LIGHT,'light');LEVEL_OF_DETAIL_NAMES.set(DETAILED,'detailed');const HEAP_PROFILER_DETAIL_NAME='heap_profiler';const BOUNDARIES_FOR_UNIT_MAP=new WeakMap();BOUNDARIES_FOR_UNIT_MAP.set(count_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,20,20));BOUNDARIES_FOR_UNIT_MAP.set(sizeInBytes_smallerIsBetter,new tr.v.HistogramBinBoundaries(0).addBinBoundary(1024).addExponentialBins(16*1024*1024*1024,4*24));const CHROME_PROCESS_NAMES=tr.e.chrome.chrome_processes.CHROME_PROCESS_NAMES;function memoryMetric(values,model,opt_options){const rangeOfInterest=opt_options?opt_options.rangeOfInterest:undefined;const browserNameToGlobalDumps=splitGlobalDumpsByBrowserName(model,rangeOfInterest);addGeneralMemoryDumpValues(browserNameToGlobalDumps,values);addDetailedMemoryDumpValues(browserNameToGlobalDumps,values);addMemoryDumpCountValues(browserNameToGlobalDumps,values);}
+function splitGlobalDumpsByBrowserName(model,opt_rangeOfInterest){const chromeModelHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const browserNameToGlobalDumps=new Map();const globalDumpToBrowserHelper=new WeakMap();if(chromeModelHelper){chromeModelHelper.browserHelpers.forEach(function(helper){const globalDumps=skipDumpsThatDoNotIntersectRange(helper.process.memoryDumps.map(d=>d.globalMemoryDump),opt_rangeOfInterest);globalDumps.forEach(function(globalDump){const existingHelper=globalDumpToBrowserHelper.get(globalDump);if(existingHelper!==undefined){throw new Error('Memory dump ID clash across multiple browsers '+'with PIDs: '+existingHelper.pid+' and '+helper.pid);}
+globalDumpToBrowserHelper.set(globalDump,helper);});makeKeyUniqueAndSet(browserNameToGlobalDumps,tr.e.chrome.chrome_processes.canonicalizeName(helper.browserName),globalDumps);});}
+const unclassifiedGlobalDumps=skipDumpsThatDoNotIntersectRange(model.globalMemoryDumps.filter(g=>!globalDumpToBrowserHelper.has(g)),opt_rangeOfInterest);if(unclassifiedGlobalDumps.length>0){makeKeyUniqueAndSet(browserNameToGlobalDumps,'unknown_browser',unclassifiedGlobalDumps);}
+return browserNameToGlobalDumps;}
+function skipDumpsThatDoNotIntersectRange(dumps,opt_range){if(!opt_range)return dumps;return dumps.filter(d=>opt_range.intersectsExplicitRangeInclusive(d.start,d.end));}
+const USER_FRIENDLY_BROWSER_NAMES={'chrome':'Chrome','webview':'WebView','unknown_browser':'an unknown browser'};function convertBrowserNameToUserFriendlyName(browserName){for(const baseName in USER_FRIENDLY_BROWSER_NAMES){if(!browserName.startsWith(baseName))continue;const userFriendlyBaseName=USER_FRIENDLY_BROWSER_NAMES[baseName];const suffix=browserName.substring(baseName.length);if(suffix.length===0){return userFriendlyBaseName;}else if(/^\d+$/.test(suffix)){return userFriendlyBaseName+'('+suffix+')';}}
+return'\''+browserName+'\' browser';}
 function convertProcessNameToUserFriendlyName(processName,opt_requirePlural){switch(processName){case CHROME_PROCESS_NAMES.BROWSER:return opt_requirePlural?'browser processes':'the browser process';case CHROME_PROCESS_NAMES.RENDERER:return'renderer processes';case CHROME_PROCESS_NAMES.GPU:return opt_requirePlural?'GPU processes':'the GPU process';case CHROME_PROCESS_NAMES.PPAPI:return opt_requirePlural?'PPAPI processes':'the PPAPI process';case CHROME_PROCESS_NAMES.ALL:return'all processes';case CHROME_PROCESS_NAMES.UNKNOWN:return'unknown processes';default:return'\''+processName+'\' processes';}}
-function makeKeyUniqueAndSet(map,key,value){var uniqueKey=key;var nextIndex=2;while(map.has(uniqueKey)){uniqueKey=key+nextIndex;nextIndex++;}
+function makeKeyUniqueAndSet(map,key,value){let uniqueKey=key;let nextIndex=2;while(map.has(uniqueKey)){uniqueKey=key+nextIndex;nextIndex++;}
 map.set(uniqueKey,value);}
-function addGeneralMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,gmd=>true,function(processDump,addProcessScalar){addProcessScalar({source:'process_count',property:PROCESS_COUNT,value:1});if(processDump.totals!==undefined){addProcessScalar({source:'reported_by_os',property:RESIDENT_SIZE,component:['system_memory'],value:processDump.totals['residentBytes']});addProcessScalar({source:'reported_by_os',property:PEAK_RESIDENT_SIZE,component:['system_memory'],value:processDump.totals['peakResidentBytes']});}
-if(processDump.memoryAllocatorDumps===undefined)return;processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property:property,value:rootAllocatorDump.numerics[property.name]});});if(rootAllocatorDump.numerics['allocated_objects_size']===undefined){var allocatedObjectsDump=rootAllocatorDump.getDescendantDumpByFullName('allocated_objects');if(allocatedObjectsDump!==undefined){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property:ALLOCATED_OBJECTS_SIZE,value:allocatedObjectsDump.numerics['size']});}}});addV8MemoryDumpValues(processDump,addProcessScalar);},function(componentTree){var tracingNode=componentTree.children[1].get('tracing');if(tracingNode===undefined)return;for(var i=0;i<componentTree.values.length;i++){componentTree.values[i].total-=tracingNode.values[i].total;}},values);}
-function addV8MemoryDumpValues(processDump,addProcessScalar){var v8Dump=processDump.getMemoryAllocatorDumpByFullName('v8');if(v8Dump===undefined)return;v8Dump.children.forEach(function(isolateDump){var mallocDump=isolateDump.getDescendantDumpByFullName('malloc');if(mallocDump!==undefined){addV8ComponentValues(mallocDump,['v8','allocated_by_malloc'],addProcessScalar);}
-var heapDump=isolateDump.getDescendantDumpByFullName('heap_spaces');if(heapDump!==undefined){addV8ComponentValues(heapDump,['v8','heap'],addProcessScalar);heapDump.children.forEach(function(spaceDump){if(spaceDump.name==='other_spaces')return;addV8ComponentValues(spaceDump,['v8','heap',spaceDump.name],addProcessScalar);});}});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics['code_and_metadata_size']});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics['bytecode_and_metadata_size']});}
-function addV8ComponentValues(componentDump,componentPath,addProcessScalar){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:componentPath,property:property,value:componentDump.numerics[property.name]});});}
-var PROCESS_COUNT={unit:count_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){if(componentPath.length>0){throw new Error('Unexpected process count non-empty component path: '+
+function addGeneralMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,gmd=>true,function(processDump,addProcessScalar){addProcessScalar({source:'process_count',property:PROCESS_COUNT,value:1});if(processDump.totals!==undefined){addProcessScalar({source:'reported_by_os',property:RESIDENT_SIZE,component:['system_memory'],value:processDump.totals.residentBytes});addProcessScalar({source:'reported_by_os',property:PEAK_RESIDENT_SIZE,component:['system_memory'],value:processDump.totals.peakResidentBytes});}
+if(processDump.memoryAllocatorDumps===undefined)return;processDump.memoryAllocatorDumps.forEach(function(rootAllocatorDump){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property,value:rootAllocatorDump.numerics[property.name]});});if(rootAllocatorDump.numerics.allocated_objects_size===undefined){const allocatedObjectsDump=rootAllocatorDump.getDescendantDumpByFullName('allocated_objects');if(allocatedObjectsDump!==undefined){addProcessScalar({source:'reported_by_chrome',component:[rootAllocatorDump.name],property:ALLOCATED_OBJECTS_SIZE,value:allocatedObjectsDump.numerics.size});}}});addV8MemoryDumpValues(processDump,addProcessScalar);},function(componentTree){const tracingNode=componentTree.children[1].get('tracing');if(tracingNode===undefined)return;for(let i=0;i<componentTree.values.length;i++){componentTree.values[i].total-=tracingNode.values[i].total;}},values);}
+function addV8MemoryDumpValues(processDump,addProcessScalar){const v8Dump=processDump.getMemoryAllocatorDumpByFullName('v8');if(v8Dump===undefined)return;v8Dump.children.forEach(function(isolateDump){const mallocDump=isolateDump.getDescendantDumpByFullName('malloc');if(mallocDump!==undefined){addV8ComponentValues(mallocDump,['v8','allocated_by_malloc'],addProcessScalar);}
+const heapDump=isolateDump.getDescendantDumpByFullName('heap_spaces');if(heapDump!==undefined){addV8ComponentValues(heapDump,['v8','heap'],addProcessScalar);heapDump.children.forEach(function(spaceDump){if(spaceDump.name==='other_spaces')return;addV8ComponentValues(spaceDump,['v8','heap',spaceDump.name],addProcessScalar);});}});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics.code_and_metadata_size});addProcessScalar({source:'reported_by_chrome',component:['v8'],property:CODE_AND_METADATA_SIZE,value:v8Dump.numerics.bytecode_and_metadata_size});}
+function addV8ComponentValues(componentDump,componentPath,addProcessScalar){CHROME_VALUE_PROPERTIES.forEach(function(property){addProcessScalar({source:'reported_by_chrome',component:componentPath,property,value:componentDump.numerics[property.name]});});}
+const PROCESS_COUNT={unit:count_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){if(componentPath.length>0){throw new Error('Unexpected process count non-empty component path: '+
 componentPath.join(':'));}
-return'total number of '+convertProcessNameToUserFriendlyName(processName,true);}};var EFFECTIVE_SIZE={name:'effective_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'effective size',componentPreposition:'of'});}};var ALLOCATED_OBJECTS_SIZE={name:'allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated',totalUserFriendlyPropertyName:'size of all allocated objects',componentPreposition:'by'});}};var LOCKED_SIZE={name:'locked_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'locked (pinned) size',componentPreposition:'of'});}};var PEAK_SIZE={name:'peak_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'peak size',componentPreposition:'of'});}};var CODE_AND_METADATA_SIZE={name:'code_and_metadata_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyNamePrefix:'size of',userFriendlyPropertyName:'code and metadata'});}};var CHROME_VALUE_PROPERTIES=[EFFECTIVE_SIZE,ALLOCATED_OBJECTS_SIZE,LOCKED_SIZE,PEAK_SIZE];function buildChromeValueDescriptionPrefix(componentPath,processName,formatSpec){var nameParts=[];if(componentPath.length===0){nameParts.push('total');if(formatSpec.totalUserFriendlyPropertyName){nameParts.push(formatSpec.totalUserFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
+return'total number of '+convertProcessNameToUserFriendlyName(processName,true);}};const EFFECTIVE_SIZE={name:'effective_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'effective size',componentPreposition:'of'});}};const ALLOCATED_OBJECTS_SIZE={name:'allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated',totalUserFriendlyPropertyName:'size of all allocated objects',componentPreposition:'by'});}};const SHIM_ALLOCATED_OBJECTS_SIZE={name:'shim_allocated_objects_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'size of all objects allocated through shim',totalUserFriendlyPropertyName:'size of all allocated objects through shim',componentPreposition:'by'});}};const LOCKED_SIZE={name:'locked_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'locked (pinned) size',componentPreposition:'of'});}};const PEAK_SIZE={name:'peak_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyName:'peak size',componentPreposition:'of'});}};const CODE_AND_METADATA_SIZE={name:'code_and_metadata_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildChromeValueDescriptionPrefix(componentPath,processName,{userFriendlyPropertyNamePrefix:'size of',userFriendlyPropertyName:'code and metadata'});}};const CHROME_VALUE_PROPERTIES=[EFFECTIVE_SIZE,ALLOCATED_OBJECTS_SIZE,SHIM_ALLOCATED_OBJECTS_SIZE,LOCKED_SIZE,PEAK_SIZE];function buildChromeValueDescriptionPrefix(componentPath,processName,formatSpec){const nameParts=[];if(componentPath.length===0){nameParts.push('total');if(formatSpec.totalUserFriendlyPropertyName){nameParts.push(formatSpec.totalUserFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
 nameParts.push(formatSpec.userFriendlyPropertyName);}
 nameParts.push('reported by Chrome for');}else{if(formatSpec.componentPreposition===undefined){if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
 nameParts.push(componentPath.join(':'));nameParts.push(formatSpec.userFriendlyPropertyName);}else{if(formatSpec.userFriendlyPropertyNamePrefix){nameParts.push(formatSpec.userFriendlyPropertyNamePrefix);}
 nameParts.push(formatSpec.userFriendlyPropertyName);nameParts.push(formatSpec.componentPreposition);if(componentPath[componentPath.length-1]==='allocated_by_malloc'){nameParts.push('objects allocated by malloc for');nameParts.push(componentPath.slice(0,componentPath.length-1).join(':'));}else{nameParts.push(componentPath.join(':'));}}
 nameParts.push('in');}
 nameParts.push(convertProcessNameToUserFriendlyName(processName));return nameParts.join(' ');}
-var RESIDENT_SIZE={name:'resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'resident set size (RSS)');}};var PEAK_RESIDENT_SIZE={name:'peak_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'peak resident set size');}};var PROPORTIONAL_RESIDENT_SIZE={name:'proportional_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'proportional resident size (PSS)');}};var PRIVATE_DIRTY_SIZE={name:'private_dirty_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix:function(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'private dirty size');}};function buildOsValueDescriptionPrefix(componentPath,processName,userFriendlyPropertyName){if(componentPath.length>2){throw new Error('OS value component path for \''+
+const RESIDENT_SIZE={name:'resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'resident set size (RSS)');}};const PEAK_RESIDENT_SIZE={name:'peak_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'peak resident set size');}};const PROPORTIONAL_RESIDENT_SIZE={name:'proportional_resident_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'proportional resident size (PSS)');}};const PRIVATE_DIRTY_SIZE={name:'private_dirty_size',unit:sizeInBytes_smallerIsBetter,buildDescriptionPrefix(componentPath,processName){return buildOsValueDescriptionPrefix(componentPath,processName,'private dirty size');}};function buildOsValueDescriptionPrefix(componentPath,processName,userFriendlyPropertyName){if(componentPath.length>2){throw new Error('OS value component path for \''+
 userFriendlyPropertyName+'\' too long: '+componentPath.join(':'));}
-var nameParts=[];if(componentPath.length<2){nameParts.push('total');}
-nameParts.push(userFriendlyPropertyName);if(componentPath.length>0){switch(componentPath[0]){case'system_memory':if(componentPath.length>1){var userFriendlyComponentName=SYSTEM_VALUE_COMPONENTS[componentPath[1]].userFriendlyName;if(userFriendlyComponentName===undefined){throw new Error('System value sub-component for \''+
+const nameParts=[];if(componentPath.length<2){nameParts.push('total');}
+nameParts.push(userFriendlyPropertyName);if(componentPath.length>0){switch(componentPath[0]){case'system_memory':if(componentPath.length>1){const userFriendlyComponentName=SYSTEM_VALUE_COMPONENTS[componentPath[1]].userFriendlyName;if(userFriendlyComponentName===undefined){throw new Error('System value sub-component for \''+
 userFriendlyPropertyName+'\' unknown: '+
 componentPath.join(':'));}
 nameParts.push('of',userFriendlyComponentName,'in');}else{nameParts.push('of system memory (RAM) used by');}
@@ -7993,435 +8376,442 @@
 userFriendlyPropertyName+'\' unknown: '+
 componentPath.join(':'));}}else{nameParts.push('reported by the OS for');}
 nameParts.push(convertProcessNameToUserFriendlyName(processName));return nameParts.join(' ');}
-function addDetailedMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,g=>g.levelOfDetail===DETAILED,function(processDump,addProcessScalar){for(var[componentName,componentSpec]of
-Object.entries(SYSTEM_VALUE_COMPONENTS)){var node=getDescendantVmRegionClassificationNode(processDump.vmRegions,componentSpec.classificationPath);var componentPath=['system_memory'];if(componentName)componentPath.push(componentName);addProcessScalar({source:'reported_by_os',component:componentPath,property:PROPORTIONAL_RESIDENT_SIZE,value:node===undefined?0:(node.byteStats['proportionalResident']||0)});addProcessScalar({source:'reported_by_os',component:componentPath,property:PRIVATE_DIRTY_SIZE,value:node===undefined?0:(node.byteStats['privateDirtyResident']||0)});}
-var memtrackDump=processDump.getMemoryAllocatorDumpByFullName('gpu/android_memtrack');if(memtrackDump!==undefined){memtrackDump.children.forEach(function(memtrackChildDump){addProcessScalar({source:'reported_by_os',component:['gpu_memory',memtrackChildDump.name],property:PROPORTIONAL_RESIDENT_SIZE,value:memtrackChildDump.numerics['memtrack_pss']});});}},function(componentTree){},values);}
-var SYSTEM_VALUE_COMPONENTS={'':{classificationPath:[],},'java_heap':{classificationPath:['Android','Java runtime','Spaces'],userFriendlyName:'the Java heap'},'ashmem':{classificationPath:['Android','Ashmem'],userFriendlyName:'ashmem'},'native_heap':{classificationPath:['Native heap'],userFriendlyName:'the native heap'},'stack':{classificationPath:['Stack'],userFriendlyName:'the thread stacks'}};function getDescendantVmRegionClassificationNode(node,path){for(var i=0;i<path.length;i++){if(node===undefined)break;node=tr.b.findFirstInArray(node.children,c=>c.title===path[i]);}
+function addDetailedMemoryDumpValues(browserNameToGlobalDumps,values){addMemoryDumpValues(browserNameToGlobalDumps,g=>g.levelOfDetail===DETAILED,function(processDump,addProcessScalar){for(const[componentName,componentSpec]of
+Object.entries(SYSTEM_VALUE_COMPONENTS)){const node=getDescendantVmRegionClassificationNode(processDump.vmRegions,componentSpec.classificationPath);const componentPath=['system_memory'];if(componentName)componentPath.push(componentName);addProcessScalar({source:'reported_by_os',component:componentPath,property:PROPORTIONAL_RESIDENT_SIZE,value:node===undefined?0:(node.byteStats.proportionalResident||0)});addProcessScalar({source:'reported_by_os',component:componentPath,property:PRIVATE_DIRTY_SIZE,value:node===undefined?0:(node.byteStats.privateDirtyResident||0)});}
+const memtrackDump=processDump.getMemoryAllocatorDumpByFullName('gpu/android_memtrack');if(memtrackDump!==undefined){memtrackDump.children.forEach(function(memtrackChildDump){addProcessScalar({source:'reported_by_os',component:['gpu_memory',memtrackChildDump.name],property:PROPORTIONAL_RESIDENT_SIZE,value:memtrackChildDump.numerics.memtrack_pss});});}},function(componentTree){},values);}
+const SYSTEM_VALUE_COMPONENTS={'':{classificationPath:[],},'java_heap':{classificationPath:['Android','Java runtime','Spaces'],userFriendlyName:'the Java heap'},'ashmem':{classificationPath:['Android','Ashmem'],userFriendlyName:'ashmem'},'native_heap':{classificationPath:['Native heap'],userFriendlyName:'the native heap'},'stack':{classificationPath:['Stack'],userFriendlyName:'the thread stacks'}};function getDescendantVmRegionClassificationNode(node,path){for(let i=0;i<path.length;i++){if(node===undefined)break;node=tr.b.findFirstInArray(node.children,c=>c.title===path[i]);}
 return node;}
-function addMemoryDumpCountValues(browserNameToGlobalDumps,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){var totalDumpCount=0;var levelOfDetailNameToDumpCount={};LEVEL_OF_DETAIL_NAMES.forEach(function(levelOfDetailName){levelOfDetailNameToDumpCount[levelOfDetailName]=0;});levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]=0;globalDumps.forEach(function(globalDump){totalDumpCount++;var levelOfDetailName=LEVEL_OF_DETAIL_NAMES.get(globalDump.levelOfDetail);if(levelOfDetailName===undefined){return;}
-levelOfDetailNameToDumpCount[levelOfDetailName]++;if(globalDump.levelOfDetail===DETAILED){if(detectHeapProfilerInMemoryDump(globalDump)){levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]++;}}});reportMemoryDumpCountAsValue(browserName,undefined,totalDumpCount,values);for(var[levelOfDetailName,levelOfDetailDumpCount]of
+function addMemoryDumpCountValues(browserNameToGlobalDumps,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){let totalDumpCount=0;const levelOfDetailNameToDumpCount={};LEVEL_OF_DETAIL_NAMES.forEach(function(levelOfDetailName){levelOfDetailNameToDumpCount[levelOfDetailName]=0;});levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]=0;globalDumps.forEach(function(globalDump){totalDumpCount++;const levelOfDetailName=LEVEL_OF_DETAIL_NAMES.get(globalDump.levelOfDetail);if(levelOfDetailName===undefined){return;}
+levelOfDetailNameToDumpCount[levelOfDetailName]++;if(globalDump.levelOfDetail===DETAILED){if(detectHeapProfilerInMemoryDump(globalDump)){levelOfDetailNameToDumpCount[HEAP_PROFILER_DETAIL_NAME]++;}}});reportMemoryDumpCountAsValue(browserName,undefined,totalDumpCount,values);for(const[levelOfDetailName,levelOfDetailDumpCount]of
 Object.entries(levelOfDetailNameToDumpCount)){reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values);}});}
-function detectHeapProfilerInMemoryDump(globalDump){for(let processDump of Object.values(globalDump.processMemoryDumps)){if(processDump.heapDumps&&processDump.heapDumps.malloc){var mallocDump=processDump.heapDumps.malloc;if(mallocDump.entries&&mallocDump.entries.length>0){return true;}}}
+function detectHeapProfilerInMemoryDump(globalDump){for(const processDump of Object.values(globalDump.processMemoryDumps)){if(processDump.heapDumps&&processDump.heapDumps.malloc){const mallocDump=processDump.heapDumps.malloc;if(mallocDump.entries&&mallocDump.entries.length>0){return true;}}}
 return false;}
-function reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values){var nameParts=['memory',browserName,'all_processes','dump_count'];if(levelOfDetailName!==undefined){nameParts.push(levelOfDetailName);}
-var name=nameParts.join(':');var histogram=new tr.v.Histogram(name,count_smallerIsBetter,BOUNDARIES_FOR_UNIT_MAP.get(count_smallerIsBetter));histogram.addSample(levelOfDetailDumpCount);var userFriendlyLevelOfDetail=(levelOfDetailName||'all').replace('_',' ');histogram.description=['total number of',userFriendlyLevelOfDetail,'memory dumps added by',convertBrowserNameToUserFriendlyName(browserName),'to the trace'].join(' ');values.addHistogram(histogram);}
-function addMemoryDumpValues(browserNameToGlobalDumps,customGlobalDumpFilter,customProcessDumpValueExtractor,customComponentTreeModifier,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){var filteredGlobalDumps=globalDumps.filter(customGlobalDumpFilter);var sourceToPropertyToBuilder=extractDataFromGlobalDumps(filteredGlobalDumps,customProcessDumpValueExtractor);reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values);});}
-function extractDataFromGlobalDumps(globalDumps,customProcessDumpValueExtractor){var sourceToPropertyToBuilder=new Map();var dumpCount=globalDumps.length;globalDumps.forEach(function(globalDump,dumpIndex){for(var processDump of Object.values(globalDump.processMemoryDumps)){extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor);}});return sourceToPropertyToBuilder;}
-function extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor){var rawProcessName=processDump.process.name;var processNamePath=[canonicalizeProcessName(rawProcessName)];customProcessDumpValueExtractor(processDump,function addProcessScalar(spec){if(spec.value===undefined)return;var component=spec.component||[];function createDetailsForErrorMessage(){return['source=',spec.source,', property=',spec.property.name||'(undefined)',', component=',component.length===0?'(empty)':component.join(':'),' in ',processDump.process.userFriendlyName].join('');}
-var value;if(spec.value instanceof tr.b.Scalar){value=spec.value.value;if(spec.value.unit!==spec.property.unit){throw new Error('Scalar unit for '+
+function reportMemoryDumpCountAsValue(browserName,levelOfDetailName,levelOfDetailDumpCount,values){const nameParts=['memory',browserName,'all_processes','dump_count'];if(levelOfDetailName!==undefined){nameParts.push(levelOfDetailName);}
+const name=nameParts.join(':');const histogram=new tr.v.Histogram(name,count_smallerIsBetter,BOUNDARIES_FOR_UNIT_MAP.get(count_smallerIsBetter));histogram.addSample(levelOfDetailDumpCount);const userFriendlyLevelOfDetail=(levelOfDetailName||'all').replace('_',' ');histogram.description=['total number of',userFriendlyLevelOfDetail,'memory dumps added by',convertBrowserNameToUserFriendlyName(browserName),'to the trace'].join(' ');values.addHistogram(histogram);}
+function addMemoryDumpValues(browserNameToGlobalDumps,customGlobalDumpFilter,customProcessDumpValueExtractor,customComponentTreeModifier,values){browserNameToGlobalDumps.forEach(function(globalDumps,browserName){const filteredGlobalDumps=globalDumps.filter(customGlobalDumpFilter);const sourceToPropertyToBuilder=extractDataFromGlobalDumps(filteredGlobalDumps,customProcessDumpValueExtractor);reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values);});}
+function extractDataFromGlobalDumps(globalDumps,customProcessDumpValueExtractor){const sourceToPropertyToBuilder=new Map();const dumpCount=globalDumps.length;globalDumps.forEach(function(globalDump,dumpIndex){for(const processDump of Object.values(globalDump.processMemoryDumps)){extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor);}});return sourceToPropertyToBuilder;}
+function extractDataFromProcessDump(processDump,sourceToPropertyToBuilder,dumpIndex,dumpCount,customProcessDumpValueExtractor){const rawProcessName=processDump.process.name;const processNamePath=[tr.e.chrome.chrome_processes.canonicalizeProcessName(rawProcessName)];customProcessDumpValueExtractor(processDump,function addProcessScalar(spec){if(spec.value===undefined)return;const component=spec.component||[];function createDetailsForErrorMessage(){return['source=',spec.source,', property=',spec.property.name||'(undefined)',', component=',component.length===0?'(empty)':component.join(':'),' in ',processDump.process.userFriendlyName].join('');}
+let value;if(spec.value instanceof tr.b.Scalar){value=spec.value.value;if(spec.value.unit!==spec.property.unit){throw new Error('Scalar unit for '+
 createDetailsForErrorMessage()+' ('+
 spec.value.unit.unitName+') doesn\'t match the unit of the property ('+
 spec.property.unit.unitName+')');}}else{value=spec.value;}
-var propertyToBuilder=sourceToPropertyToBuilder.get(spec.source);if(propertyToBuilder===undefined){propertyToBuilder=new Map();sourceToPropertyToBuilder.set(spec.source,propertyToBuilder);}
-var builder=propertyToBuilder.get(spec.property);if(builder===undefined){builder=new tr.b.MultiDimensionalViewBuilder(2,dumpCount),propertyToBuilder.set(spec.property,builder);}
-var values=new Array(dumpCount);values[dumpIndex]=value;builder.addPath([processNamePath,component],values,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);});}
-function reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values){sourceToPropertyToBuilder.forEach(function(propertyToBuilder,sourceName){propertyToBuilder.forEach(function(builders,property){var tree=builders.buildTopDownTreeView();reportComponentDataAsValues(browserName,sourceName,property,[],tree,values,customComponentTreeModifier);});});}
-function reportComponentDataAsValues(browserName,sourceName,property,componentPath,tree,values,customComponentTreeModifier){var breakdown=new tr.v.d.RelatedHistogramBreakdown();breakdown.colorScheme=PROCESS_COLOR_SCHEME_NAME;tree.children[0].forEach(function(processTree,processName){customComponentTreeModifier(processTree);var numeric=buildNamedMemoryNumericFromNode(browserName,sourceName,property,processName,componentPath,processTree);values.addHistogram(numeric);breakdown.set(processName,numeric);});customComponentTreeModifier(tree);var numeric=buildNamedMemoryNumericFromNode(browserName,sourceName,property,'all_processes',componentPath,tree);numeric.diagnostics.set('processes',breakdown);values.addHistogram(numeric);var depth=componentPath.length;componentPath.push(undefined);tree.children[1].forEach(function(childNode,childName){componentPath[depth]=childName;reportComponentDataAsValues(browserName,sourceName,property,componentPath,childNode,values,customComponentTreeModifier);});componentPath.pop();}
-function getNumericName(browserName,sourceName,propertyName,processName,componentPath){var nameParts=['memory',browserName,processName,sourceName].concat(componentPath);if(propertyName!==undefined)nameParts.push(propertyName);return nameParts.join(':');}
+let propertyToBuilder=sourceToPropertyToBuilder.get(spec.source);if(propertyToBuilder===undefined){propertyToBuilder=new Map();sourceToPropertyToBuilder.set(spec.source,propertyToBuilder);}
+let builder=propertyToBuilder.get(spec.property);if(builder===undefined){builder=new tr.b.MultiDimensionalViewBuilder(2,dumpCount),propertyToBuilder.set(spec.property,builder);}
+const values=new Array(dumpCount);values[dumpIndex]=value;builder.addPath([processNamePath,component],values,tr.b.MultiDimensionalViewBuilder.ValueKind.TOTAL);});}
+function reportDataAsValues(sourceToPropertyToBuilder,browserName,customComponentTreeModifier,values){sourceToPropertyToBuilder.forEach(function(propertyToBuilder,sourceName){propertyToBuilder.forEach(function(builders,property){const tree=builders.buildTopDownTreeView();reportComponentDataAsValues(browserName,sourceName,property,[],[],tree,values,customComponentTreeModifier);});});}
+function reportComponentDataAsValues(browserName,sourceName,property,processPath,componentPath,tree,values,customComponentTreeModifier,opt_cachedHistograms){const cachedHistograms=opt_cachedHistograms||new Map();function recurse(processPath,componentPath,node){return reportComponentDataAsValues(browserName,sourceName,property,processPath,componentPath,node,values,customComponentTreeModifier,cachedHistograms);}
+function buildHistogram(processPath,componentPath,node){return buildNamedMemoryNumericFromNode(browserName,sourceName,property,processPath.length===0?'all_processes':processPath[0],componentPath,node);}
+customComponentTreeModifier(tree);const histogram=buildHistogram(processPath,componentPath,tree);if(cachedHistograms.has(histogram.name)){return cachedHistograms.get(histogram.name);}
+cachedHistograms.set(histogram.name,histogram);const processBreakdown=new tr.v.d.RelatedHistogramBreakdown();processBreakdown.colorScheme=tr.e.chrome.chrome_processes.PROCESS_COLOR_SCHEME_NAME;for(const[childProcessName,childProcessNode]of tree.children[0]){processPath.push(childProcessName);const childProcessHistogram=recurse(processPath,componentPath,childProcessNode);processBreakdown.set(childProcessName,childProcessHistogram);processPath.pop();}
+const componentBreakdown=new tr.v.d.RelatedHistogramBreakdown();for(const[childComponentName,childComponentNode]of tree.children[1]){componentPath.push(childComponentName);const childComponentHistogram=recurse(processPath,componentPath,childComponentNode);componentBreakdown.set(childComponentName,childComponentHistogram);componentPath.pop();}
+values.addHistogram(histogram);if(tree.children[0].size>0){histogram.diagnostics.set('processes',processBreakdown);}
+if(tree.children[1].size>0){histogram.diagnostics.set('components',componentBreakdown);}
+return histogram;}
+function getNumericName(browserName,sourceName,propertyName,processName,componentPath){const nameParts=['memory',browserName,processName,sourceName].concat(componentPath);if(propertyName!==undefined)nameParts.push(propertyName);return nameParts.join(':');}
 function getNumericDescription(property,browserName,processName,componentPath){return[property.buildDescriptionPrefix(componentPath,processName),'in',convertBrowserNameToUserFriendlyName(browserName)].join(' ');}
-function buildNamedMemoryNumericFromNode(browserName,sourceName,property,processName,componentPath,node){var name=getNumericName(browserName,sourceName,property.name,processName,componentPath);var description=getNumericDescription(property,browserName,processName,componentPath);var numeric=buildMemoryNumericFromNode(name,node,property.unit);numeric.description=description;return numeric;}
-function buildMemoryNumericFromNode(name,node,unit){var histogram=new tr.v.Histogram(name,unit,BOUNDARIES_FOR_UNIT_MAP.get(unit));node.values.forEach(v=>histogram.addSample(v.total));return histogram;}
-tr.metrics.MetricRegistry.register(memoryMetric,{supportsRangeOfInterest:true});return{memoryMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){var CHROME_POWER_GRACE_PERIOD_MS=1;function createEmptyHistogram_(interval,histograms){if(interval.perSecond){return{perSecond:true,energy:createPowerHistogram_(histograms,interval.name,interval.description)};}
-return{perSecond:false,energy:createEnergyHistogram_(histograms,interval.name,interval.description)};}
+function buildNamedMemoryNumericFromNode(browserName,sourceName,property,processName,componentPath,node){const name=getNumericName(browserName,sourceName,property.name,processName,componentPath);const description=getNumericDescription(property,browserName,processName,componentPath);const numeric=buildMemoryNumericFromNode(name,node,property.unit);numeric.description=description;return numeric;}
+function buildMemoryNumericFromNode(name,node,unit){const histogram=new tr.v.Histogram(name,unit,BOUNDARIES_FOR_UNIT_MAP.get(unit));node.values.forEach(v=>histogram.addSample(v.total));return histogram;}
+tr.metrics.MetricRegistry.register(memoryMetric,{supportsRangeOfInterest:true});return{memoryMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){const CHROME_POWER_GRACE_PERIOD_MS=1;function createEmptyHistogram_(interval,histograms){if(interval.perSecond){return{perSecond:true,energy:histograms.createHistogram(`${interval.name}:power`,tr.b.Unit.byName.powerInWatts_smallerIsBetter,[],{description:`Energy consumption rate for ${interval.description}`,summaryOptions:{avg:true,count:false,max:true,min:true,std:false,sum:false,},}),};}
+return{perSecond:false,energy:histograms.createHistogram(`${interval.name}:energy`,tr.b.Unit.byName.energyInJoules_smallerIsBetter,[],{description:`Energy consumed in ${interval.description}`,summaryOptions:{avg:false,count:false,max:true,min:true,std:false,sum:true,},}),};}
 function createHistograms_(data,interval,histograms){if(data.histograms[interval.name]===undefined){data.histograms[interval.name]=createEmptyHistogram_(interval,histograms);}
-if(data.histograms[interval.name].perSecond){for(var sample of data.model.device.powerSeries.getSamplesWithinRange(interval.bounds.min,interval.bounds.max)){data.histograms[interval.name].energy.addSample(sample.powerInW);}}else{var energyInJ=data.model.device.powerSeries.getEnergyConsumedInJ(interval.bounds.min,interval.bounds.max);data.histograms[interval.name].energy.addSample(energyInJ);}}
-function getNavigationTTIIntervals_(model){var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);var intervals=[];for(var rendererHelper of Object.values(chromeHelper.rendererHelpers)){var samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;for(var sample of samples){var info=sample.diagnostics['Navigation infos'].value;intervals.push(tr.b.math.Range.fromExplicitRange(info.start,info.interactive));}}
+if(data.histograms[interval.name].perSecond){for(const sample of data.model.device.powerSeries.getSamplesWithinRange(interval.bounds.min,interval.bounds.max)){data.histograms[interval.name].energy.addSample(sample.powerInW);}}else{const energyInJ=data.model.device.powerSeries.getEnergyConsumedInJ(interval.bounds.min,interval.bounds.max);data.histograms[interval.name].energy.addSample(energyInJ);}}
+function getNavigationTTIIntervals_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const intervals=[];for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;for(const sample of samples){const info=sample.diagnostics['Navigation infos'].value;intervals.push(tr.b.math.Range.fromExplicitRange(info.start,info.interactive));}}
 return intervals.sort((x,y)=>x.min-y.min);}
-function createEnergyHistogram_(histograms,histogramName,description){var histogram=new tr.v.Histogram(`${histogramName}:energy`,tr.b.Unit.byName.energyInJoules_smallerIsBetter);histogram.customizeSummaryOptions({avg:false,count:false,max:true,min:true,std:false,sum:true,});histogram.description='Energy consumed in '+description;histograms.addHistogram(histogram);return histogram;}
-function createPowerHistogram_(histograms,histogramName,description){var histogram=new tr.v.Histogram(`${histogramName}:power`,tr.b.Unit.byName.powerInWatts_smallerIsBetter);histogram.customizeSummaryOptions({avg:true,count:false,max:true,min:true,std:false,sum:false,});histogram.description='Energy consumption rate for '+description;histograms.addHistogram(histogram);return histogram;}
-function*computeTimeIntervals_(model){var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);var powerSeries=model.device.powerSeries;if(powerSeries===undefined||powerSeries.samples.length===0){return;}
-yield{bounds:model.bounds,name:'story',description:'user story',perSecond:true};var chromeBounds=computeChromeBounds_(model);if(chromeBounds.isEmpty)return;var powerSeriesBoundsWithGracePeriod=tr.b.math.Range.fromExplicitRange(powerSeries.bounds.min-CHROME_POWER_GRACE_PERIOD_MS,powerSeries.bounds.max+CHROME_POWER_GRACE_PERIOD_MS);if(!powerSeriesBoundsWithGracePeriod.containsRangeExclusive(chromeBounds)){return;}
-for(var interval of getRailStageIntervals_(model)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}
-for(var interval of getLoadingIntervals_(model,chromeBounds)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}}
-function*getRailStageIntervals_(model){for(var exp of model.userModel.expectations){var histogramName=exp.title.toLowerCase().replace(' ','_');var energyHist=undefined;if(histogramName.includes('response')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:false};}else if(histogramName.includes('animation')||histogramName.includes('idle')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:true};}}}
-function*getLoadingIntervals_(model,chromeBounds){var ttiIntervals=getNavigationTTIIntervals_(model);var lastLoadTime=undefined;for(var ttiInterval of ttiIntervals){yield{bounds:ttiInterval,name:'load',description:'page loads',perSecond:false};lastLoadTime=lastLoadTime===undefined?ttiInterval.max:Math.max(lastLoadTime,ttiInterval.max);}
+function*computeTimeIntervals_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);const powerSeries=model.device.powerSeries;if(powerSeries===undefined||powerSeries.samples.length===0){return;}
+yield{bounds:model.bounds,name:'story',description:'user story',perSecond:true};const chromeBounds=computeChromeBounds_(model);if(chromeBounds.isEmpty)return;const powerSeriesBoundsWithGracePeriod=tr.b.math.Range.fromExplicitRange(powerSeries.bounds.min-CHROME_POWER_GRACE_PERIOD_MS,powerSeries.bounds.max+CHROME_POWER_GRACE_PERIOD_MS);if(!powerSeriesBoundsWithGracePeriod.containsRangeExclusive(chromeBounds)){return;}
+for(const interval of getRailStageIntervals_(model)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}
+for(const interval of getLoadingIntervals_(model,chromeBounds)){yield{bounds:interval.bounds.findIntersection(chromeBounds),name:interval.name,description:interval.description,perSecond:interval.perSecond};}}
+function*getRailStageIntervals_(model){for(const exp of model.userModel.expectations){const histogramName=exp.title.toLowerCase().replace(' ','_');const energyHist=undefined;if(histogramName.includes('response')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:false};}else if(histogramName.includes('animation')||histogramName.includes('idle')){yield{bounds:tr.b.math.Range.fromExplicitRange(exp.start,exp.end),name:histogramName,description:'RAIL stage '+histogramName,perSecond:true};}}}
+function*getLoadingIntervals_(model,chromeBounds){const ttiIntervals=getNavigationTTIIntervals_(model);let lastLoadTime=undefined;for(const ttiInterval of ttiIntervals){yield{bounds:ttiInterval,name:'load',description:'page loads',perSecond:false};lastLoadTime=lastLoadTime===undefined?ttiInterval.max:Math.max(lastLoadTime,ttiInterval.max);}
 if(lastLoadTime!==undefined){yield{bounds:tr.b.math.Range.fromExplicitRange(lastLoadTime,chromeBounds.max),name:'after_load',description:'period after load',perSecond:true};}}
-function computeChromeBounds_(model){var chromeBounds=new tr.b.math.Range();var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return chromeBounds;for(var helper of chromeHelper.browserHelpers){if(helper.mainThread){chromeBounds.addRange(helper.mainThread.bounds);}}
-for(var pid in chromeHelper.rendererHelpers){if(chromeHelper.rendererHelpers[pid].mainThread){chromeBounds.addRange(chromeHelper.rendererHelpers[pid].mainThread.bounds);}}
+function computeChromeBounds_(model){const chromeBounds=new tr.b.math.Range();const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);if(chromeHelper===undefined)return chromeBounds;for(const helper of chromeHelper.browserHelpers){if(helper.mainThread){chromeBounds.addRange(helper.mainThread.bounds);}}
+for(const pid in chromeHelper.rendererHelpers){if(chromeHelper.rendererHelpers[pid].mainThread){chromeBounds.addRange(chromeHelper.rendererHelpers[pid].mainThread.bounds);}}
 return chromeBounds;}
-function powerMetric(histograms,model){var data={model:model,histograms:{}};for(var interval of computeTimeIntervals_(model)){createHistograms_(data,interval,histograms);}}
+function powerMetric(histograms,model){const data={model,histograms:{}};for(const interval of computeTimeIntervals_(model)){createHistograms_(data,interval,histograms);}}
 tr.metrics.MetricRegistry.register(powerMetric);return{powerMetric};});'use strict';tr.exportTo('tr.metrics.sh',function(){function computeAnimationThroughput(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0){throw new Error('Animation missing frameEvents '+
 animationExpectation.stableId);}
-var durationInS=tr.b.convertUnit(animationExpectation.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return animationExpectation.frameEvents.length/durationInS;}
+const durationInS=tr.b.convertUnit(animationExpectation.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return animationExpectation.frameEvents.length/durationInS;}
 function computeAnimationframeTimeDiscrepancy(animationExpectation){if(animationExpectation.frameEvents===undefined||animationExpectation.frameEvents.length===0){throw new Error('Animation missing frameEvents '+
 animationExpectation.stableId);}
-var frameTimestamps=animationExpectation.frameEvents;frameTimestamps=frameTimestamps.toArray().map(function(event){return event.start;});var absolute=true;return tr.b.math.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);}
-function responsivenessMetric(histograms,model,opt_options){var responseNumeric=new tr.v.Histogram('response latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(100,1e3,50));var throughputNumeric=new tr.v.Histogram('animation throughput',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,tr.v.HistogramBinBoundaries.createLinear(10,60,10));var frameTimeDiscrepancyNumeric=new tr.v.Histogram('animation frameTimeDiscrepancy',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,1e3,50).addExponentialBins(1e4,10));var latencyNumeric=new tr.v.Histogram('animation latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,300,60));model.userModel.expectations.forEach(function(ue){if(opt_options&&opt_options.rangeOfInterest&&!opt_options.rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){return;}
-var sampleDiagnosticMap=tr.v.d.DiagnosticMap.fromObject({relatedEvents:new tr.v.d.RelatedEventSet([ue])});if(ue instanceof tr.model.um.IdleExpectation){return;}else if(ue instanceof tr.model.um.StartupExpectation){return;}else if(ue instanceof tr.model.um.LoadExpectation){}else if(ue instanceof tr.model.um.ResponseExpectation){responseNumeric.addSample(ue.duration,sampleDiagnosticMap);}else if(ue instanceof tr.model.um.AnimationExpectation){if(ue.frameEvents===undefined||ue.frameEvents.length===0){return;}
-var throughput=computeAnimationThroughput(ue);if(throughput===undefined){throw new Error('Missing throughput for '+
+let frameTimestamps=animationExpectation.frameEvents;frameTimestamps=frameTimestamps.toArray().map(function(event){return event.start;});const absolute=true;return tr.b.math.Statistics.timestampsDiscrepancy(frameTimestamps,absolute);}
+function responsivenessMetric(histograms,model,opt_options){const responseNumeric=new tr.v.Histogram('response latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(100,1e3,50));const throughputNumeric=new tr.v.Histogram('animation throughput',tr.b.Unit.byName.unitlessNumber_biggerIsBetter,tr.v.HistogramBinBoundaries.createLinear(10,60,10));const frameTimeDiscrepancyNumeric=new tr.v.Histogram('animation frameTimeDiscrepancy',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,1e3,50).addExponentialBins(1e4,10));const latencyNumeric=new tr.v.Histogram('animation latency',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(0,300,60));model.userModel.expectations.forEach(function(ue){if(opt_options&&opt_options.rangeOfInterest&&!opt_options.rangeOfInterest.intersectsExplicitRangeInclusive(ue.start,ue.end)){return;}
+const sampleDiagnosticMap=tr.v.d.DiagnosticMap.fromObject({relatedEvents:new tr.v.d.RelatedEventSet([ue])});if(ue instanceof tr.model.um.IdleExpectation){return;}else if(ue instanceof tr.model.um.StartupExpectation){return;}else if(ue instanceof tr.model.um.LoadExpectation){}else if(ue instanceof tr.model.um.ResponseExpectation){responseNumeric.addSample(ue.duration,sampleDiagnosticMap);}else if(ue instanceof tr.model.um.AnimationExpectation){if(ue.frameEvents===undefined||ue.frameEvents.length===0){return;}
+const throughput=computeAnimationThroughput(ue);if(throughput===undefined){throw new Error('Missing throughput for '+
 ue.stableId);}
-throughputNumeric.addSample(throughput,sampleDiagnosticMap);var frameTimeDiscrepancy=computeAnimationframeTimeDiscrepancy(ue);if(frameTimeDiscrepancy===undefined){throw new Error('Missing frameTimeDiscrepancy for '+
+throughputNumeric.addSample(throughput,sampleDiagnosticMap);const frameTimeDiscrepancy=computeAnimationframeTimeDiscrepancy(ue);if(frameTimeDiscrepancy===undefined){throw new Error('Missing frameTimeDiscrepancy for '+
 ue.stableId);}
 frameTimeDiscrepancyNumeric.addSample(frameTimeDiscrepancy,sampleDiagnosticMap);ue.associatedEvents.forEach(function(event){if(!(event instanceof tr.e.cc.InputLatencyAsyncSlice)){return;}
 latencyNumeric.addSample(event.duration,sampleDiagnosticMap);});}else{throw new Error('Unrecognized stage for '+ue.stableId);}});[responseNumeric,throughputNumeric,frameTimeDiscrepancyNumeric,latencyNumeric].forEach(function(numeric){numeric.customizeSummaryOptions({avg:true,max:true,min:true,std:true});});histograms.addHistogram(responseNumeric);histograms.addHistogram(throughputNumeric);histograms.addHistogram(frameTimeDiscrepancyNumeric);histograms.addHistogram(latencyNumeric);}
-tr.metrics.MetricRegistry.register(responsivenessMetric,{supportsRangeOfInterest:true});return{responsivenessMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function webviewStartupMetric(histograms,model){var startupWallHist=new tr.v.Histogram('webview_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebView startup wall time';var startupCPUHist=new tr.v.Histogram('webview_startup_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupCPUHist.description='WebView startup CPU time';var loadWallHist=new tr.v.Histogram('webview_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebView blank URL load wall time';var loadCPUHist=new tr.v.Histogram('webview_url_load_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadCPUHist.description='WebView blank URL load CPU time';for(var slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebViewStartupInterval'){startupWallHist.addSample(slice.duration);startupCPUHist.addSample(slice.cpuDuration);}
+tr.metrics.MetricRegistry.register(responsivenessMetric,{supportsRangeOfInterest:true});return{responsivenessMetric,};});'use strict';tr.exportTo('tr.metrics.sh',function(){function webviewStartupMetric(histograms,model){const startupWallHist=new tr.v.Histogram('webview_startup_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupWallHist.description='WebView startup wall time';const startupCPUHist=new tr.v.Histogram('webview_startup_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);startupCPUHist.description='WebView startup CPU time';const loadWallHist=new tr.v.Histogram('webview_url_load_wall_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadWallHist.description='WebView blank URL load wall time';const loadCPUHist=new tr.v.Histogram('webview_url_load_cpu_time',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter);loadCPUHist.description='WebView blank URL load CPU time';for(const slice of model.getDescendantEvents()){if(!(slice instanceof tr.model.ThreadSlice))continue;if(slice.title==='WebViewStartupInterval'){startupWallHist.addSample(slice.duration);startupCPUHist.addSample(slice.cpuDuration);}
 if(slice.title==='WebViewBlankUrlLoadInterval'){loadWallHist.addSample(slice.duration);loadCPUHist.addSample(slice.cpuDuration);}}
 histograms.addHistogram(startupWallHist);histograms.addHistogram(startupCPUHist);histograms.addHistogram(loadWallHist);histograms.addHistogram(loadCPUHist);}
-tr.metrics.MetricRegistry.register(webviewStartupMetric);return{webviewStartupMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const MEMORY_INFRA_TRACING_CATEGORY='disabled-by-default-memory-infra';const TIME_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1e-3,1e5,30);const BYTE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e9,30);const COUNT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e5,30);function addTimeDurationHistogram(histogramName,duration,histograms,opt_description){let hist=new tr.v.Histogram(histogramName,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,TIME_BOUNDARIES);hist.addSample(duration);hist.customizeSummaryOptions({count:false,min:false,max:false,sum:false,avg:true,std:false});histograms.addHistogram(hist);if(opt_description)hist.description=opt_description;}
-function addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes){let memoryDumpCount=model.globalMemoryDumps.length;if(memoryDumpCount===0)return;let totalOverhead=0;let nonMemoryInfraThreadOverhead=0;let overheadByProvider={};for(let process of Object.values(model.processes)){for(let thread of Object.values(process.threads)){for(let slice of Object.values(thread.sliceGroup.slices)){if(slice.category!==MEMORY_INFRA_TRACING_CATEGORY)continue;totalOverhead+=slice.duration;if(thread.name!=='MemoryInfra'){nonMemoryInfraThreadOverhead+=slice.duration;}
-if(slice.args&&slice.args['dump_provider.name']){let providerName=slice.args['dump_provider.name'];let durationAndCount=overheadByProvider[providerName];if(durationAndCount===undefined){overheadByProvider[providerName]=durationAndCount={duration:0,count:0};}
+tr.metrics.MetricRegistry.register(webviewStartupMetric);return{webviewStartupMetric,};});'use strict';tr.exportTo('tr.metrics',function(){const MEMORY_INFRA_TRACING_CATEGORY='disabled-by-default-memory-infra';const TIME_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1e-3,1e5,30);const BYTE_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e9,30);const COUNT_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1e5,30);const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;function addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes){const memoryDumpCount=model.globalMemoryDumps.length;if(memoryDumpCount===0)return;let totalOverhead=0;let nonMemoryInfraThreadOverhead=0;const overheadByProvider={};for(const process of Object.values(model.processes)){for(const thread of Object.values(process.threads)){for(const slice of Object.values(thread.sliceGroup.slices)){if(slice.category!==MEMORY_INFRA_TRACING_CATEGORY)continue;totalOverhead+=slice.duration;if(thread.name!=='MemoryInfra'){nonMemoryInfraThreadOverhead+=slice.duration;}
+if(slice.args&&slice.args['dump_provider.name']){const providerName=slice.args['dump_provider.name'];let durationAndCount=overheadByProvider[providerName];if(durationAndCount===undefined){overheadByProvider[providerName]=durationAndCount={duration:0,count:0};}
 durationAndCount.duration+=slice.duration;durationAndCount.count++;}}}}
-addTimeDurationHistogram('memory_dump_cpu_overhead',totalOverhead/memoryDumpCount,histograms,'Average CPU overhead on all threads per memory-infra dump');addTimeDurationHistogram('nonmemory_thread_memory_dump_cpu_overhead',nonMemoryInfraThreadOverhead/memoryDumpCount,histograms,'Average CPU overhead on non-memory-infra threads per memory-infra '+'dump');for(let[providerName,overhead]of Object.entries(overheadByProvider)){addTimeDurationHistogram(`${providerName}_memory_dump_cpu_overhead`,overhead.duration/overhead.count,histograms,'Average CPU overhead of '+providerName+' per OnMemoryDump call');}
-let memoryInfraEventsSize=categoryNamesToTotalEventSizes.get(MEMORY_INFRA_TRACING_CATEGORY);let memoryInfraTraceBytesValue=new tr.v.Histogram('total_memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);memoryInfraTraceBytesValue.description='Total trace size of memory-infra dumps in bytes';memoryInfraTraceBytesValue.customizeSummaryOptions({count:false,min:false,max:false,sum:false,avg:true,std:false});memoryInfraTraceBytesValue.addSample(memoryInfraEventsSize);histograms.addHistogram(memoryInfraTraceBytesValue);let traceBytesPerDumpValue=new tr.v.Histogram('memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);traceBytesPerDumpValue.description='Average trace size of memory-infra dumps in bytes';traceBytesPerDumpValue.customizeSummaryOptions({count:false,min:false,max:false,sum:false,avg:true,std:false});traceBytesPerDumpValue.addSample(memoryInfraEventsSize/memoryDumpCount);histograms.addHistogram(traceBytesPerDumpValue);}
-function tracingMetric(histograms,model){addTimeDurationHistogram('trace_import_duration',model.stats.traceImportDurationMs,histograms,'Duration that trace viewer required to import the trace');if(!model.stats.hasEventSizesinBytes)return;let eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort((a,b)=>a.timeInterval-b.timeInterval);let totalTraceBytes=eventStats.reduce((a,b)=>a+b.totalEventSizeinBytes,0);let maxEventCountPerSec=0;let maxEventBytesPerSec=0;let INTERVALS_PER_SEC=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);let runningEventNumPerSec=0;let runningEventBytesPerSec=0;let start=0;let end=0;while(end<eventStats.length){runningEventNumPerSec+=eventStats[end].numEvents;runningEventBytesPerSec+=eventStats[end].totalEventSizeinBytes;end++;while((eventStats[end-1].timeInterval-
+histograms.createHistogram('memory_dump_cpu_overhead',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,totalOverhead/memoryDumpCount,{binBoundaries:TIME_BOUNDARIES,description:'Average CPU overhead on all threads per memory-infra dump',summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('nonmemory_thread_memory_dump_cpu_overhead',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,nonMemoryInfraThreadOverhead/memoryDumpCount,{binBoundaries:TIME_BOUNDARIES,description:'Average CPU overhead on non-memory-infra threads '+'per memory-infra dump',summaryOptions:SUMMARY_OPTIONS,});for(const[providerName,overhead]of Object.entries(overheadByProvider)){histograms.createHistogram(`${providerName}_memory_dump_cpu_overhead`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,overhead.duration/overhead.count,{binBoundaries:TIME_BOUNDARIES,description:`Average CPU overhead of ${providerName} per OnMemoryDump call`,summaryOptions:SUMMARY_OPTIONS,});}
+const memoryInfraEventsSize=categoryNamesToTotalEventSizes.get(MEMORY_INFRA_TRACING_CATEGORY);const memoryInfraTraceBytesValue=new tr.v.Histogram('total_memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);memoryInfraTraceBytesValue.description='Total trace size of memory-infra dumps in bytes';memoryInfraTraceBytesValue.customizeSummaryOptions(SUMMARY_OPTIONS);memoryInfraTraceBytesValue.addSample(memoryInfraEventsSize);histograms.addHistogram(memoryInfraTraceBytesValue);const traceBytesPerDumpValue=new tr.v.Histogram('memory_dump_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);traceBytesPerDumpValue.description='Average trace size of memory-infra dumps in bytes';traceBytesPerDumpValue.customizeSummaryOptions(SUMMARY_OPTIONS);traceBytesPerDumpValue.addSample(memoryInfraEventsSize/memoryDumpCount);histograms.addHistogram(traceBytesPerDumpValue);}
+function tracingMetric(histograms,model){histograms.createHistogram('trace_import_duration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,model.stats.traceImportDurationMs,{binBoundaries:TIME_BOUNDARIES,description:'Duration that trace viewer required to import the trace',summaryOptions:SUMMARY_OPTIONS,});if(!model.stats.hasEventSizesinBytes)return;const eventStats=model.stats.allTraceEventStatsInTimeIntervals;eventStats.sort((a,b)=>a.timeInterval-b.timeInterval);const totalTraceBytes=eventStats.reduce((a,b)=>a+b.totalEventSizeinBytes,0);let maxEventCountPerSec=0;let maxEventBytesPerSec=0;const INTERVALS_PER_SEC=Math.floor(1000/model.stats.TIME_INTERVAL_SIZE_IN_MS);let runningEventNumPerSec=0;let runningEventBytesPerSec=0;let start=0;let end=0;while(end<eventStats.length){runningEventNumPerSec+=eventStats[end].numEvents;runningEventBytesPerSec+=eventStats[end].totalEventSizeinBytes;end++;while((eventStats[end-1].timeInterval-
 eventStats[start].timeInterval)>=INTERVALS_PER_SEC){runningEventNumPerSec-=eventStats[start].numEvents;runningEventBytesPerSec-=eventStats[start].totalEventSizeinBytes;start++;}
 maxEventCountPerSec=Math.max(maxEventCountPerSec,runningEventNumPerSec);maxEventBytesPerSec=Math.max(maxEventBytesPerSec,runningEventBytesPerSec);}
-let stats=model.stats.allTraceEventStats;let categoryNamesToTotalEventSizes=(stats.reduce((map,stat)=>(map.set(stat.category,((map.get(stat.category)||0)+
-stat.totalEventSizeinBytes))),new Map()));let maxCatNameAndBytes=Array.from(categoryNamesToTotalEventSizes.entries()).reduce((a,b)=>((b[1]>=a[1])?b:a));let maxEventBytesPerCategory=maxCatNameAndBytes[1];let categoryWithMaxEventBytes=maxCatNameAndBytes[0];let maxEventCountPerSecValue=new tr.v.Histogram('peak_event_rate',tr.b.Unit.byName.count_smallerIsBetter,COUNT_BOUNDARIES);maxEventCountPerSecValue.description='Max number of events per second';maxEventCountPerSecValue.customizeSummaryOptions({count:false,min:false,max:false,sum:false,avg:true,std:false});maxEventCountPerSecValue.addSample(maxEventCountPerSec);let maxEventBytesPerSecValue=new tr.v.Histogram('peak_event_size_rate',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);maxEventBytesPerSecValue.description='Max event size in bytes per second';maxEventBytesPerSecValue.customizeSummaryOptions({count:false,min:false,max:false,sum:false,avg:true,std:false});maxEventBytesPerSecValue.addSample(maxEventBytesPerSec);let totalTraceBytesValue=new tr.v.Histogram('trace_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);totalTraceBytesValue.customizeSummaryOptions({count:false,min:false,max:false,sum:false,avg:true,std:false});totalTraceBytesValue.addSample(totalTraceBytes);let biggestCategory={name:categoryWithMaxEventBytes,size_in_bytes:maxEventBytesPerCategory};totalTraceBytesValue.diagnostics.set('category_with_max_event_size',new tr.v.d.Generic(biggestCategory));histograms.addHistogram(totalTraceBytesValue);maxEventCountPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.Generic(biggestCategory));histograms.addHistogram(maxEventCountPerSecValue);maxEventBytesPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.Generic(biggestCategory));histograms.addHistogram(maxEventBytesPerSecValue);addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes);}
-tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric,MEMORY_INFRA_TRACING_CATEGORY,};});'use strict';tr.exportTo('tr.metrics.v8',function(){var CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(4,200,100);function computeExecuteMetrics(histograms,model){var cpuTotalExecution=new tr.v.Histogram('v8_execution_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalExecution.description='cpu total time spent in script execution';var wallTotalExecution=new tr.v.Histogram('v8_execution_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalExecution.description='wall total time spent in script execution';var cpuSelfExecution=new tr.v.Histogram('v8_execution_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfExecution.description='cpu self time spent in script execution';var wallSelfExecution=new tr.v.Histogram('v8_execution_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfExecution.description='wall self time spent in script execution';for(var e of model.findTopmostSlicesNamed('V8.Execute')){cpuTotalExecution.addSample(e.cpuDuration);wallTotalExecution.addSample(e.duration);cpuSelfExecution.addSample(e.cpuSelfTime);wallSelfExecution.addSample(e.selfTime);}
+const stats=model.stats.allTraceEventStats;const categoryNamesToTotalEventSizes=(stats.reduce((map,stat)=>(map.set(stat.category,((map.get(stat.category)||0)+
+stat.totalEventSizeinBytes))),new Map()));const maxCatNameAndBytes=Array.from(categoryNamesToTotalEventSizes.entries()).reduce((a,b)=>((b[1]>=a[1])?b:a));const maxEventBytesPerCategory=maxCatNameAndBytes[1];const categoryWithMaxEventBytes=maxCatNameAndBytes[0];const maxEventCountPerSecValue=new tr.v.Histogram('peak_event_rate',tr.b.Unit.byName.count_smallerIsBetter,COUNT_BOUNDARIES);maxEventCountPerSecValue.description='Max number of events per second';maxEventCountPerSecValue.customizeSummaryOptions(SUMMARY_OPTIONS);maxEventCountPerSecValue.addSample(maxEventCountPerSec);const maxEventBytesPerSecValue=new tr.v.Histogram('peak_event_size_rate',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);maxEventBytesPerSecValue.description='Max event size in bytes per second';maxEventBytesPerSecValue.customizeSummaryOptions(SUMMARY_OPTIONS);maxEventBytesPerSecValue.addSample(maxEventBytesPerSec);const totalTraceBytesValue=new tr.v.Histogram('trace_size',tr.b.Unit.byName.sizeInBytes_smallerIsBetter,BYTE_BOUNDARIES);totalTraceBytesValue.customizeSummaryOptions(SUMMARY_OPTIONS);totalTraceBytesValue.addSample(totalTraceBytes);const biggestCategory={name:categoryWithMaxEventBytes,size_in_bytes:maxEventBytesPerCategory};totalTraceBytesValue.diagnostics.set('category_with_max_event_size',new tr.v.d.Generic(biggestCategory));histograms.addHistogram(totalTraceBytesValue);maxEventCountPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.Generic(biggestCategory));histograms.addHistogram(maxEventCountPerSecValue);maxEventBytesPerSecValue.diagnostics.set('category_with_max_event_size',new tr.v.d.Generic(biggestCategory));histograms.addHistogram(maxEventBytesPerSecValue);addMemoryInfraHistograms(histograms,model,categoryNamesToTotalEventSizes);}
+tr.metrics.MetricRegistry.register(tracingMetric);return{tracingMetric,MEMORY_INFRA_TRACING_CATEGORY,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(4,200,100);function computeExecuteMetrics(histograms,model){const cpuTotalExecution=new tr.v.Histogram('v8_execution_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalExecution.description='cpu total time spent in script execution';const wallTotalExecution=new tr.v.Histogram('v8_execution_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalExecution.description='wall total time spent in script execution';const cpuSelfExecution=new tr.v.Histogram('v8_execution_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfExecution.description='cpu self time spent in script execution';const wallSelfExecution=new tr.v.Histogram('v8_execution_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfExecution.description='wall self time spent in script execution';for(const e of model.findTopmostSlicesNamed('V8.Execute')){cpuTotalExecution.addSample(e.cpuDuration);wallTotalExecution.addSample(e.duration);cpuSelfExecution.addSample(e.cpuSelfTime);wallSelfExecution.addSample(e.selfTime);}
 histograms.addHistogram(cpuTotalExecution);histograms.addHistogram(wallTotalExecution);histograms.addHistogram(cpuSelfExecution);histograms.addHistogram(wallSelfExecution);}
-function computeParseLazyMetrics(histograms,model){var cpuSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfParseLazy.description='cpu self time spent performing lazy parsing';var wallSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfParseLazy.description='wall self time spent performing lazy parsing';for(var e of model.findTopmostSlicesNamed('V8.ParseLazyMicroSeconds')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
-for(var e of model.findTopmostSlicesNamed('V8.ParseLazy')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
+function computeParseLazyMetrics(histograms,model){const cpuSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfParseLazy.description='cpu self time spent performing lazy parsing';const wallSelfParseLazy=new tr.v.Histogram('v8_parse_lazy_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfParseLazy.description='wall self time spent performing lazy parsing';for(const e of model.findTopmostSlicesNamed('V8.ParseLazyMicroSeconds')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
+for(const e of model.findTopmostSlicesNamed('V8.ParseLazy')){cpuSelfParseLazy.addSample(e.cpuSelfTime);wallSelfParseLazy.addSample(e.selfTime);}
 histograms.addHistogram(cpuSelfParseLazy);histograms.addHistogram(wallSelfParseLazy);}
-function computeCompileFullCodeMetrics(histograms,model){var cpuSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileFullCode.description='cpu self time spent performing compiling full code';var wallSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileFullCode.description='wall self time spent performing compiling full code';for(var e of model.findTopmostSlicesNamed('V8.CompileFullCode')){cpuSelfCompileFullCode.addSample(e.cpuSelfTime);wallSelfCompileFullCode.addSample(e.selfTime);}
+function computeCompileFullCodeMetrics(histograms,model){const cpuSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileFullCode.description='cpu self time spent performing compiling full code';const wallSelfCompileFullCode=new tr.v.Histogram('v8_compile_full_code_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileFullCode.description='wall self time spent performing compiling full code';for(const e of model.findTopmostSlicesNamed('V8.CompileFullCode')){cpuSelfCompileFullCode.addSample(e.cpuSelfTime);wallSelfCompileFullCode.addSample(e.selfTime);}
 histograms.addHistogram(cpuSelfCompileFullCode);histograms.addHistogram(wallSelfCompileFullCode);}
-function computeCompileIgnitionMetrics(histograms,model){var cpuSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileIgnition.description='cpu self time spent in compile ignition';var wallSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileIgnition.description='wall self time spent in compile ignition';for(var e of model.findTopmostSlicesNamed('V8.CompileIgnition')){cpuSelfCompileIgnition.addSample(e.cpuSelfTime);wallSelfCompileIgnition.addSample(e.selfTime);}
+function computeCompileIgnitionMetrics(histograms,model){const cpuSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_cpu_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuSelfCompileIgnition.description='cpu self time spent in compile ignition';const wallSelfCompileIgnition=new tr.v.Histogram('v8_compile_ignition_wall_self',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallSelfCompileIgnition.description='wall self time spent in compile ignition';for(const e of model.findTopmostSlicesNamed('V8.CompileIgnition')){cpuSelfCompileIgnition.addSample(e.cpuSelfTime);wallSelfCompileIgnition.addSample(e.selfTime);}
 histograms.addHistogram(cpuSelfCompileIgnition);histograms.addHistogram(wallSelfCompileIgnition);}
-function computeRecompileMetrics(histograms,model){var cpuTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileSynchronous.description='cpu total time spent in synchronous recompilation';var wallTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileSynchronous.description='wall total time spent in synchronous recompilation';var cpuTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileConcurrent.description='cpu total time spent in concurrent recompilation';var wallTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileConcurrent.description='wall total time spent in concurrent recompilation';var cpuTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileOverall.description='cpu total time spent in synchronous or concurrent recompilation';var wallTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileOverall.description='wall total time spent in synchronous or concurrent recompilation';for(var e of model.findTopmostSlicesNamed('V8.RecompileSynchronous')){cpuTotalRecompileSynchronous.addSample(e.cpuDuration);wallTotalRecompileSynchronous.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
-histograms.addHistogram(cpuTotalRecompileSynchronous);histograms.addHistogram(wallTotalRecompileSynchronous);for(var e of model.findTopmostSlicesNamed('V8.RecompileConcurrent')){cpuTotalRecompileConcurrent.addSample(e.cpuDuration);wallTotalRecompileConcurrent.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
+function computeRecompileMetrics(histograms,model){const cpuTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileSynchronous.description='cpu total time spent in synchronous recompilation';const wallTotalRecompileSynchronous=new tr.v.Histogram('v8_recompile_synchronous_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileSynchronous.description='wall total time spent in synchronous recompilation';const cpuTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileConcurrent.description='cpu total time spent in concurrent recompilation';const wallTotalRecompileConcurrent=new tr.v.Histogram('v8_recompile_concurrent_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileConcurrent.description='wall total time spent in concurrent recompilation';const cpuTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalRecompileOverall.description='cpu total time spent in synchronous or concurrent recompilation';const wallTotalRecompileOverall=new tr.v.Histogram('v8_recompile_overall_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalRecompileOverall.description='wall total time spent in synchronous or concurrent recompilation';for(const e of model.findTopmostSlicesNamed('V8.RecompileSynchronous')){cpuTotalRecompileSynchronous.addSample(e.cpuDuration);wallTotalRecompileSynchronous.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
+histograms.addHistogram(cpuTotalRecompileSynchronous);histograms.addHistogram(wallTotalRecompileSynchronous);for(const e of model.findTopmostSlicesNamed('V8.RecompileConcurrent')){cpuTotalRecompileConcurrent.addSample(e.cpuDuration);wallTotalRecompileConcurrent.addSample(e.duration);cpuTotalRecompileOverall.addSample(e.cpuDuration);wallTotalRecompileOverall.addSample(e.duration);}
 histograms.addHistogram(cpuTotalRecompileConcurrent);histograms.addHistogram(wallTotalRecompileConcurrent);histograms.addHistogram(cpuTotalRecompileOverall);histograms.addHistogram(wallTotalRecompileOverall);}
-function computeOptimizeCodeMetrics(histograms,model){var cpuTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalOptimizeCode.description='cpu total time spent in code optimization';var wallTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalOptimizeCode.description='wall total time spent in code optimization';for(var e of model.findTopmostSlicesNamed('V8.OptimizeCode')){cpuTotalOptimizeCode.addSample(e.cpuDuration);wallTotalOptimizeCode.addSample(e.duration);}
+function computeOptimizeCodeMetrics(histograms,model){const cpuTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalOptimizeCode.description='cpu total time spent in code optimization';const wallTotalOptimizeCode=new tr.v.Histogram('v8_optimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalOptimizeCode.description='wall total time spent in code optimization';for(const e of model.findTopmostSlicesNamed('V8.OptimizeCode')){cpuTotalOptimizeCode.addSample(e.cpuDuration);wallTotalOptimizeCode.addSample(e.duration);}
 histograms.addHistogram(cpuTotalOptimizeCode);histograms.addHistogram(wallTotalOptimizeCode);}
-function computeDeoptimizeCodeMetrics(histograms,model){var cpuTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalDeoptimizeCode.description='cpu total time spent in code deoptimization';var wallTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalDeoptimizeCode.description='wall total time spent in code deoptimization';for(var e of model.findTopmostSlicesNamed('V8.DeoptimizeCode')){cpuTotalDeoptimizeCode.addSample(e.cpuDuration);wallTotalDeoptimizeCode.addSample(e.duration);}
+function computeDeoptimizeCodeMetrics(histograms,model){const cpuTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_cpu_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);cpuTotalDeoptimizeCode.description='cpu total time spent in code deoptimization';const wallTotalDeoptimizeCode=new tr.v.Histogram('v8_deoptimize_code_wall_total',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);wallTotalDeoptimizeCode.description='wall total time spent in code deoptimization';for(const e of model.findTopmostSlicesNamed('V8.DeoptimizeCode')){cpuTotalDeoptimizeCode.addSample(e.cpuDuration);wallTotalDeoptimizeCode.addSample(e.duration);}
 histograms.addHistogram(cpuTotalDeoptimizeCode);histograms.addHistogram(wallTotalDeoptimizeCode);}
 function executionMetric(histograms,model){computeExecuteMetrics(histograms,model);computeParseLazyMetrics(histograms,model);computeCompileIgnitionMetrics(histograms,model);computeCompileFullCodeMetrics(histograms,model);computeRecompileMetrics(histograms,model);computeOptimizeCodeMetrics(histograms,model);computeDeoptimizeCodeMetrics(histograms,model);}
-tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){var TARGET_FPS=60;var MS_PER_SECOND=1000;var WINDOW_SIZE_MS=MS_PER_SECOND/TARGET_FPS;function gcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);addDurationOfSubEvents(histograms,model);addPercentageInV8ExecuteOfTopEvents(histograms,model);addTotalPercentageInV8Execute(histograms,model);}
-tr.metrics.MetricRegistry.register(gcMetric);var timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;var percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;var percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;var CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){var n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
-function createNumericForSubEventTime(name){var n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:false,percentile:[0.90]});return n;}
-function createNumericForIdleTime(name){var n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
-function createPercentage(name,numerator,denominator,unit){var hist=new tr.v.Histogram(name,unit);if(denominator===0){hist.addSample(0);}else{hist.addSample(numerator/denominator);}
+tr.metrics.MetricRegistry.register(executionMetric);return{executionMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const TARGET_FPS=60;const MS_PER_SECOND=1000;const WINDOW_SIZE_MS=MS_PER_SECOND/TARGET_FPS;function gcMetric(histograms,model){addDurationOfTopEvents(histograms,model);addTotalDurationOfTopEvents(histograms,model);addDurationOfSubEvents(histograms,model);addPercentageInV8ExecuteOfTopEvents(histograms,model);addTotalPercentageInV8Execute(histograms,model);}
+tr.metrics.MetricRegistry.register(gcMetric);const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(0,20,200).addExponentialBins(200,100);function createNumericForTopEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:true,max:true,min:false,std:true,sum:true,percentile:[0.90]});return n;}
+function createNumericForSubEventTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:false,percentile:[0.90]});return n;}
+function createNumericForIdleTime(name){const n=new tr.v.Histogram(name,timeDurationInMs_smallerIsBetter,CUSTOM_BOUNDARIES);n.customizeSummaryOptions({avg:true,count:false,max:true,min:false,std:false,sum:true,percentile:[]});return n;}
+function createPercentage(name,numerator,denominator,unit){const hist=new tr.v.Histogram(name,unit);if(denominator===0){hist.addSample(0);}else{hist.addSample(numerator/denominator);}
 hist.customizeSummaryOptions({avg:true,count:false,max:false,min:false,std:false,sum:false,percentile:[]});return hist;}
 function isNotForcedTopGarbageCollectionEvent(event){return tr.metrics.v8.utils.isTopGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
 function isNotForcedSubGarbageCollectionEvent(event){return tr.metrics.v8.utils.isSubGarbageCollectionEvent(event)&&!tr.metrics.v8.utils.isForcedGarbageCollectionEvent(event);}
-function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){var cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
-function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){var cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
-function addDurationOfSubEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedSubGarbageCollectionEvent,tr.metrics.v8.utils.subGarbageCollectionEventName,function(name,events){var cpuDuration=createNumericForSubEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addTotalDurationOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){const cpuDuration=createNumericForTopEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
+function addDurationOfSubEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedSubGarbageCollectionEvent,tr.metrics.v8.utils.subGarbageCollectionEventName,function(name,events){const cpuDuration=createNumericForSubEventTime(name);events.forEach(function(event){cpuDuration.addSample(event.cpuDuration);});histograms.addHistogram(cpuDuration);});}
 function addPercentageInV8ExecuteOfTopEvents(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,tr.metrics.v8.utils.topGarbageCollectionEventName,function(name,events){addPercentageInV8Execute(histograms,model,name,events);});}
 function addTotalPercentageInV8Execute(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isNotForcedTopGarbageCollectionEvent,event=>'v8-gc-total',function(name,events){addPercentageInV8Execute(histograms,model,name,events);});}
-function addPercentageInV8Execute(histograms,model,name,events){var cpuDurationInV8Execute=0;var cpuDurationTotal=0;events.forEach(function(event){var v8Execute=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isV8ExecuteEvent);if(v8Execute){cpuDurationInV8Execute+=event.cpuDuration;}
-cpuDurationTotal+=event.cpuDuration;});var percentage=createPercentage(name+'_percentage_in_v8_execute',cpuDurationInV8Execute,cpuDurationTotal,percentage_smallerIsBetter);histograms.addHistogram(percentage);}
-return{gcMetric,WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics.v8',function(){var COUNT_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1000000,50);var DURATION_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.1,10000,50);function computeDomContentLoadedTime_(model){var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);var domContentLoadedTime=0;for(var rendererHelper of Object.values(chromeHelper.rendererHelpers)){for(var ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title==='domContentLoadedEventEnd'&&ev.start>domContentLoadedTime){domContentLoadedTime=ev.start;}}}
+function addPercentageInV8Execute(histograms,model,name,events){let cpuDurationInV8Execute=0;let cpuDurationTotal=0;events.forEach(function(event){const v8Execute=tr.metrics.v8.utils.findParent(event,tr.metrics.v8.utils.isV8ExecuteEvent);if(v8Execute){cpuDurationInV8Execute+=event.cpuDuration;}
+cpuDurationTotal+=event.cpuDuration;});const percentage=createPercentage(name+'_percentage_in_v8_execute',cpuDurationInV8Execute,cpuDurationTotal,percentage_smallerIsBetter);histograms.addHistogram(percentage);}
+return{gcMetric,WINDOW_SIZE_MS,};});'use strict';tr.exportTo('tr.metrics.v8',function(){const COUNT_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(1,1000000,50);const DURATION_CUSTOM_BOUNDARIES=tr.v.HistogramBinBoundaries.createExponential(0.1,10000,50);const SUMMARY_OPTIONS={std:false,count:false,sum:false,min:false,max:false,};function computeDomContentLoadedTime_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let domContentLoadedTime=0;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){for(const ev of rendererHelper.mainThread.sliceGroup.childEvents()){if(ev.title==='domContentLoadedEventEnd'&&ev.start>domContentLoadedTime){domContentLoadedTime=ev.start;}}}
 return domContentLoadedTime;}
-function computeInteractiveTime_(model){var chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);var interactiveTime=0;for(var rendererHelper of Object.values(chromeHelper.rendererHelpers)){var samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;if(samples.length===0)continue;if(interactiveTime!==0)throw new Error('Too many navigations');interactiveTime=tr.b.getOnlyElement(samples).diagnostics['Navigation infos'].value.interactive;}
+function computeInteractiveTime_(model){const chromeHelper=model.getOrCreateHelper(tr.model.helpers.ChromeModelHelper);let interactiveTime=0;for(const rendererHelper of Object.values(chromeHelper.rendererHelpers)){const samples=tr.metrics.sh.collectLoadingMetricsForRenderer(rendererHelper).firstInteractiveSamples;if(samples.length===0)continue;if(interactiveTime!==0)throw new Error('Too many navigations');interactiveTime=tr.b.getOnlyElement(samples).diagnostics['Navigation infos'].value.interactive;}
 return interactiveTime;}
-function createDurationHistogram_(name){var histogram=new tr.v.Histogram(name+':duration',tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,DURATION_CUSTOM_BOUNDARIES);histogram.customizeSummaryOptions({std:false,count:false,sum:false,min:false,max:false});return histogram;}
-function createCountHistogram_(name){var histogram=new tr.v.Histogram(name+':count',tr.b.Unit.byName.count_smallerIsBetter,COUNT_CUSTOM_BOUNDARIES);histogram.customizeSummaryOptions({std:false,count:false,sum:false,min:false,max:false});return histogram;}
 function convertMicroToMilli_(time){return tr.b.convertUnit(time,tr.b.UnitPrefixScale.METRIC.MICRO,tr.b.UnitPrefixScale.METRIC.MILLI);}
-function computeRuntimeStats(histograms,slices){var runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);for(var runtimeGroup of runtimeGroupCollection.runtimeGroups){var durationSamples=new tr.v.d.RelatedHistogramBreakdown();var countSamples=new tr.v.d.RelatedHistogramBreakdown();for(var entry of runtimeGroup.values){var durationSampleHistogram=createDurationHistogram_(entry.name);durationSampleHistogram.addSample(convertMicroToMilli_(entry.time));durationSamples.set(entry.name+':duration',durationSampleHistogram);histograms.addHistogram(durationSampleHistogram);var countSampleHistogram=createCountHistogram_(entry.name);countSampleHistogram.addSample(entry.count);countSamples.set(entry.name+':count',countSampleHistogram);histograms.addHistogram(countSampleHistogram);}
-var durationHistogram=createDurationHistogram_(runtimeGroup.name);durationHistogram.addSample(convertMicroToMilli_(runtimeGroup.time),{samples:durationSamples});var countHistogram=createCountHistogram_(runtimeGroup.name);countHistogram.addSample(runtimeGroup.count,{samples:countSamples});histograms.addHistogram(durationHistogram);histograms.addHistogram(countHistogram);}}
-function runtimeStatsMetric(histograms,model){var interactiveTime=computeInteractiveTime_(model);var domContentLoadedTime=computeDomContentLoadedTime_(model);var endTime=Math.max(interactiveTime,domContentLoadedTime);var slices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice&&event.start<=endTime);computeRuntimeStats(histograms,slices);}
-function computeRuntimeStatsBucketOnUE(histograms,slices,v8SlicesBucketOnUEMap){let durationRelatedHistsByGroupName=new Map();let countRelatedHistsByGroupName=new Map();for(var[name,slicesUE]of v8SlicesBucketOnUEMap){var runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slicesUE);for(var runtimeGroup of runtimeGroupCollection.runtimeGroups){var histogramName=name+'_'+runtimeGroup.name;var durationHistogram=createDurationHistogram_(histogramName);durationHistogram.addSample(convertMicroToMilli_(runtimeGroup.time));histograms.addHistogram(durationHistogram);if(durationRelatedHistsByGroupName.get(runtimeGroup.name)===undefined){var durationHistogramMap=new tr.v.d.RelatedHistogramMap();durationHistogramMap.set(name,durationHistogram);durationRelatedHistsByGroupName.set(runtimeGroup.name,durationHistogramMap);}else{durationRelatedHistsByGroupName.get(runtimeGroup.name).set(name,durationHistogram);}
-var countHistogram=createCountHistogram_(histogramName);countHistogram.addSample(runtimeGroup.count);histograms.addHistogram(countHistogram);if(countRelatedHistsByGroupName.get(runtimeGroup.name)===undefined){var countHistogramMap=new tr.v.d.RelatedHistogramMap();countHistogramMap.set(name,countHistogram);countRelatedHistsByGroupName.set(runtimeGroup.name,countHistogramMap);}else{countRelatedHistsByGroupName.get(runtimeGroup.name).set(name,countHistogram);}}}
-var runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);for(var runtimeGroup of runtimeGroupCollection.runtimeGroups){var histogramName=runtimeGroup.name;var durationHistogram=createDurationHistogram_(histogramName);durationHistogram.addSample(convertMicroToMilli_(runtimeGroup.time));histograms.addHistogram(durationHistogram);var durationRelatedHistogram=durationRelatedHistsByGroupName.get(runtimeGroup.name);if(durationRelatedHistogram!==undefined){durationHistogram.diagnostics.set('RAIL stages',durationRelatedHistogram);}
-var countHistogram=createCountHistogram_(histogramName);countHistogram.addSample(runtimeGroup.count);var countRelatedHistogram=countRelatedHistsByGroupName.get(runtimeGroup.name);if(countRelatedHistogram!==undefined){countHistogram.diagnostics.set('RAIL stages',countRelatedHistogram);}
-histograms.addHistogram(countHistogram);}}
-function runtimeStatsTotalMetric(histograms,model){var v8ThreadSlices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice).sort((e1,e2)=>e1.start-e2.start);var v8SlicesBucketOnUEMap=new Map();for(var expectation of model.userModel.expectations){var slices=expectation.range.filterArray(v8ThreadSlices,event=>event.start);if(slices.length===0)continue;var lastSlice=slices[slices.length-1];if(!expectation.range.intersectsRangeExclusive(lastSlice.range)){slices.pop();}
-if(v8SlicesBucketOnUEMap.get(expectation.stageTitle)===undefined){v8SlicesBucketOnUEMap.set(expectation.stageTitle,slices);}else{var totalSlices=v8SlicesBucketOnUEMap.get(expectation.stageTitle).concat(slices);v8SlicesBucketOnUEMap.set(expectation.stageTitle,totalSlices);}}
+function computeRuntimeStats(histograms,slices){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){const durationSamples=new tr.v.d.RelatedHistogramBreakdown();const countSamples=new tr.v.d.RelatedHistogramBreakdown();for(const entry of runtimeGroup.values){const durationSampleHistogram=histograms.createHistogram(`${entry.name}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(entry.time),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});durationSamples.set(durationSampleHistogram.name,durationSampleHistogram);const countSampleHistogram=histograms.createHistogram(`${entry.name}:count`,tr.b.Unit.byName.count_smallerIsBetter,entry.count,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});countSamples.set(countSampleHistogram.name,countSampleHistogram);}
+histograms.createHistogram(`${runtimeGroup.name}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,{value:convertMicroToMilli_(runtimeGroup.time),diagnostics:{samples:durationSamples},},{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram(`${runtimeGroup.name}:count`,tr.b.Unit.byName.count_smallerIsBetter,{value:runtimeGroup.count,diagnostics:{samples:countSamples},},{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});}}
+function runtimeStatsMetric(histograms,model){const interactiveTime=computeInteractiveTime_(model);const domContentLoadedTime=computeDomContentLoadedTime_(model);const endTime=Math.max(interactiveTime,domContentLoadedTime);const slices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice&&event.start<=endTime);computeRuntimeStats(histograms,slices);}
+function addDurationHistogram(railStageName,runtimeGroupName,sampleValue,histograms,durationRelatedHistsByGroupName){const durationHistogram=histograms.createHistogram(`${railStageName}_${runtimeGroupName}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(sampleValue),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});if(durationRelatedHistsByGroupName.get(runtimeGroupName)===undefined){const durationHistogramMap=new tr.v.d.RelatedHistogramMap();durationHistogramMap.set(railStageName,durationHistogram);durationRelatedHistsByGroupName.set(runtimeGroupName,durationHistogramMap);}else{durationRelatedHistsByGroupName.get(runtimeGroupName).set(railStageName,durationHistogram);}}
+function addCountHistogram(railStageName,runtimeGroupName,sampleValue,histograms,countRelatedHistsByGroupName){const countHistogram=histograms.createHistogram(`${railStageName}_${runtimeGroupName}:count`,tr.b.Unit.byName.count_smallerIsBetter,sampleValue,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});if(countRelatedHistsByGroupName.get(runtimeGroupName)===undefined){const countHistogramMap=new tr.v.d.RelatedHistogramMap();countHistogramMap.set(railStageName,countHistogram);countRelatedHistsByGroupName.set(runtimeGroupName,countHistogramMap);}else{countRelatedHistsByGroupName.get(runtimeGroupName).set(railStageName,countHistogram);}}
+function addTotalDurationHistogram(histogramName,time,histograms,durationRelatedHistsByGroupName){const durationHistogram=histograms.createHistogram(`${histogramName}:duration`,tr.b.Unit.byName.timeDurationInMs_smallerIsBetter,convertMicroToMilli_(time),{binBoundaries:DURATION_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});const durationRelatedHistogram=durationRelatedHistsByGroupName.get(histogramName);if(durationRelatedHistogram!==undefined){durationHistogram.diagnostics.set('RAIL stages',durationRelatedHistogram);}}
+function addTotalCountHistogram(histogramName,count,histograms,countRelatedHistsByGroupName){const countHistogram=histograms.createHistogram(`${histogramName}:count`,tr.b.Unit.byName.count_smallerIsBetter,count,{binBoundaries:COUNT_CUSTOM_BOUNDARIES,summaryOptions:SUMMARY_OPTIONS,});const countRelatedHistogram=countRelatedHistsByGroupName.get(histogramName);if(countRelatedHistogram!==undefined){countHistogram.diagnostics.set('RAIL stages',countRelatedHistogram);}}
+function computeRuntimeStatsBucketOnUE(histograms,slices,v8SlicesBucketOnUEMap){const durationRelatedHistsByGroupName=new Map();const countRelatedHistsByGroupName=new Map();for(const[name,slicesUE]of v8SlicesBucketOnUEMap){const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slicesUE);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addDurationHistogram(name,runtimeGroup.name,runtimeGroup.time,histograms,durationRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;}
+addCountHistogram(name,runtimeGroup.name,runtimeGroup.count,histograms,countRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Count-=runtimeGroup.count;}}
+addDurationHistogram(name,'V8-Only',overallV8Time,histograms,durationRelatedHistsByGroupName);addCountHistogram(name,'V8-Only',overallV8Count,histograms,countRelatedHistsByGroupName);}
+const runtimeGroupCollection=new tr.e.v8.RuntimeStatsGroupCollection();runtimeGroupCollection.addSlices(slices);let overallV8Time=runtimeGroupCollection.totalTime;let overallV8Count=runtimeGroupCollection.totalCount;for(const runtimeGroup of runtimeGroupCollection.runtimeGroups){addTotalDurationHistogram(runtimeGroup.name,runtimeGroup.time,histograms,durationRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Time-=runtimeGroup.time;}
+addTotalCountHistogram(runtimeGroup.name,runtimeGroup.count,histograms,countRelatedHistsByGroupName);if(runtimeGroup.name==='Blink C++'){overallV8Count-=runtimeGroup.count;}}
+addTotalDurationHistogram('V8-Only',overallV8Time,histograms,durationRelatedHistsByGroupName);addTotalCountHistogram('V8-Only',overallV8Count,histograms,countRelatedHistsByGroupName);}
+function runtimeStatsTotalMetric(histograms,model){const v8ThreadSlices=[...model.getDescendantEvents()].filter(event=>event instanceof tr.e.v8.V8ThreadSlice).sort((e1,e2)=>e1.start-e2.start);const v8SlicesBucketOnUEMap=new Map();for(const expectation of model.userModel.expectations){const slices=expectation.range.filterArray(v8ThreadSlices,event=>event.start);if(slices.length===0)continue;const lastSlice=slices[slices.length-1];if(!expectation.range.intersectsRangeExclusive(lastSlice.range)){slices.pop();}
+if(v8SlicesBucketOnUEMap.get(expectation.stageTitle)===undefined){v8SlicesBucketOnUEMap.set(expectation.stageTitle,slices);}else{const totalSlices=v8SlicesBucketOnUEMap.get(expectation.stageTitle).concat(slices);v8SlicesBucketOnUEMap.set(expectation.stageTitle,totalSlices);}}
 computeRuntimeStatsBucketOnUE(histograms,v8ThreadSlices,v8SlicesBucketOnUEMap);}
 tr.metrics.MetricRegistry.register(runtimeStatsTotalMetric);tr.metrics.MetricRegistry.register(runtimeStatsMetric);return{runtimeStatsMetric,runtimeStatsTotalMetric,};});'use strict';tr.exportTo('tr.metrics.v8',function(){function v8AndMemoryMetrics(histograms,model){tr.metrics.v8.executionMetric(histograms,model);tr.metrics.v8.gcMetric(histograms,model);tr.metrics.sh.memoryMetric(histograms,model,{rangeOfInterest:tr.metrics.v8.utils.rangeForMemoryDumps(model)});}
-tr.metrics.MetricRegistry.register(v8AndMemoryMetrics);return{v8AndMemoryMetrics,};});'use strict';tr.exportTo('tr.metrics.webrtc',function(){const DISPLAY_HERTZ=60.0;const VSYNC_DURATION_US=1e6/DISPLAY_HERTZ;const SEVERITY=3;const FROZEN_FRAME_VSYNC_COUNT_THRESHOLD=6;const WEB_MEDIA_PLAYER_UPDATE_TITLE='WebMediaPlayerMS::UpdateCurrentFrame';const IDEAL_RENDER_INSTANT_NAME='Ideal Render Instant';const ACTUAL_RENDER_BEGIN_NAME='Actual Render Begin';const ACTUAL_RENDER_END_NAME='Actual Render End';const STREAM_ID_NAME='Serial';const REQUIRED_EVENT_ARGS_NAMES=[IDEAL_RENDER_INSTANT_NAME,ACTUAL_RENDER_BEGIN_NAME,ACTUAL_RENDER_END_NAME,STREAM_ID_NAME];const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_biggerIsBetter=tr.b.Unit.byName.unitlessNumber_biggerIsBetter;function isValidEvent(event){if(event.title!==WEB_MEDIA_PLAYER_UPDATE_TITLE||!event.args){return false;}
-for(let parameter of REQUIRED_EVENT_ARGS_NAMES){if(!(parameter in event.args)){return false;}}
+tr.metrics.MetricRegistry.register(v8AndMemoryMetrics);return{v8AndMemoryMetrics,};});'use strict';tr.exportTo('tr.metrics.webrtc',function(){const DISPLAY_HERTZ=60.0;const VSYNC_DURATION_US=1e6/DISPLAY_HERTZ;const SEVERITY=3;const FROZEN_FRAME_VSYNC_COUNT_THRESHOLD=6;const WEB_MEDIA_PLAYER_UPDATE_TITLE='WebMediaPlayerMS::UpdateCurrentFrame';const IDEAL_RENDER_INSTANT_NAME='Ideal Render Instant';const ACTUAL_RENDER_BEGIN_NAME='Actual Render Begin';const ACTUAL_RENDER_END_NAME='Actual Render End';const STREAM_ID_NAME='Serial';const REQUIRED_EVENT_ARGS_NAMES=[IDEAL_RENDER_INSTANT_NAME,ACTUAL_RENDER_BEGIN_NAME,ACTUAL_RENDER_END_NAME,STREAM_ID_NAME];const SUMMARY_OPTIONS=tr.v.Histogram.AVERAGE_ONLY_SUMMARY_OPTIONS;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const percentage_biggerIsBetter=tr.b.Unit.byName.normalizedPercentage_biggerIsBetter;const percentage_smallerIsBetter=tr.b.Unit.byName.normalizedPercentage_smallerIsBetter;const timeDurationInMs_smallerIsBetter=tr.b.Unit.byName.timeDurationInMs_smallerIsBetter;const unitlessNumber_biggerIsBetter=tr.b.Unit.byName.unitlessNumber_biggerIsBetter;function isValidEvent(event){if(event.title!==WEB_MEDIA_PLAYER_UPDATE_TITLE||!event.args){return false;}
+for(const parameter of REQUIRED_EVENT_ARGS_NAMES){if(!(parameter in event.args)){return false;}}
 return true;}
 function webrtcRenderingMetric(histograms,model){tr.metrics.v8.utils.groupAndProcessEvents(model,isValidEvent,event=>event.args[STREAM_ID_NAME],(streamName,events)=>getTimeStats(histograms,streamName,events));}
-tr.metrics.MetricRegistry.register(webrtcRenderingMetric);function addHistogram(samples,histograms,name,unit,opt_summaryOptions){let summaryOptions=opt_summaryOptions;if(!summaryOptions){summaryOptions={count:false,max:false,min:false,std:false,sum:false,};}
-let histogram=new tr.v.Histogram(name,unit);for(let sample of samples){histogram.addSample(sample);}
-histogram.customizeSummaryOptions(summaryOptions);histograms.addHistogram(histogram);}
-function getTimeStats(histograms,streamName,events){let frameHist=getFrameDistribution(histograms,events);addFpsFromFrameDistribution(histograms,frameHist);addFreezingScore(histograms,frameHist);let driftTimeStats=getDriftStats(events);addHistogram(driftTimeStats.driftTime,histograms,'WebRTCRendering_drift_time',timeDurationInMs_smallerIsBetter,{count:false,min:false,percentile:[0.75,0.9]});addHistogram([driftTimeStats.renderingLengthError],histograms,'WebRTCRendering_rendering_length_error',percentage_smallerIsBetter);let smoothnessStats=getSmoothnessStats(driftTimeStats.driftTime);addHistogram([smoothnessStats.percentBadlyOutOfSync],histograms,'WebRTCRendering_percent_badly_out_of_sync',percentage_smallerIsBetter);addHistogram([smoothnessStats.percentOutOfSync],histograms,'WebRTCRendering_percent_out_of_sync',percentage_smallerIsBetter);addHistogram([smoothnessStats.smoothnessScore],histograms,'WebRTCRendering_smoothness_score',percentage_biggerIsBetter);addHistogram([smoothnessStats.framesOutOfSync],histograms,'WebRTCRendering_frames_out_of_sync',count_smallerIsBetter);addHistogram([smoothnessStats.framesSeverelyOutOfSync],histograms,'WebRTCRendering_frames_badly_out_of_sync',count_smallerIsBetter);}
-function getFrameDistribution(histograms,events){const cadence=tr.b.runLengthEncoding(events.map(e=>e.args[IDEAL_RENDER_INSTANT_NAME]));const frameHist=new tr.v.Histogram('WebRTCRendering_frame_distribution',count_smallerIsBetter,tr.v.HistogramBinBoundaries.createLinear(1,50,49));for(const ticks of cadence){frameHist.addSample(ticks.count);}
-frameHist.customizeSummaryOptions({percentile:[0.75,0.9]});histograms.addHistogram(frameHist);return frameHist;}
+tr.metrics.MetricRegistry.register(webrtcRenderingMetric);function getTimeStats(histograms,streamName,events){const frameHist=getFrameDistribution(histograms,events);addFpsFromFrameDistribution(histograms,frameHist);addFreezingScore(histograms,frameHist);const driftTimeStats=getDriftStats(events);histograms.createHistogram('WebRTCRendering_drift_time',timeDurationInMs_smallerIsBetter,driftTimeStats.driftTime,{summaryOptions:{count:false,min:false,percentile:[0.75,0.9],},});histograms.createHistogram('WebRTCRendering_rendering_length_error',percentage_smallerIsBetter,driftTimeStats.renderingLengthError,{summaryOptions:SUMMARY_OPTIONS,});const smoothnessStats=getSmoothnessStats(driftTimeStats.driftTime);histograms.createHistogram('WebRTCRendering_percent_badly_out_of_sync',percentage_smallerIsBetter,smoothnessStats.percentBadlyOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_percent_out_of_sync',percentage_smallerIsBetter,smoothnessStats.percentOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_smoothness_score',percentage_biggerIsBetter,smoothnessStats.smoothnessScore,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_frames_out_of_sync',count_smallerIsBetter,smoothnessStats.framesOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_frames_badly_out_of_sync',count_smallerIsBetter,smoothnessStats.framesSeverelyOutOfSync,{summaryOptions:SUMMARY_OPTIONS,});}
+const FRAME_DISTRIBUTION_BIN_BOUNDARIES=tr.v.HistogramBinBoundaries.createLinear(1,50,49);function getFrameDistribution(histograms,events){const cadence=tr.b.runLengthEncoding(events.map(e=>e.args[IDEAL_RENDER_INSTANT_NAME]));return histograms.createHistogram('WebRTCRendering_frame_distribution',count_smallerIsBetter,cadence.map(ticks=>ticks.count),{binBoundaries:FRAME_DISTRIBUTION_BIN_BOUNDARIES,summaryOptions:{percentile:[0.75,0.9],},});}
 function addFpsFromFrameDistribution(histograms,frameHist){let numberFrames=0;let numberVsyncs=0;for(let ticks=1;ticks<frameHist.allBins.length;++ticks){const count=frameHist.allBins[ticks].count;numberFrames+=count;numberVsyncs+=ticks*count;}
-let meanRatio=numberVsyncs/numberFrames;addHistogram([DISPLAY_HERTZ/meanRatio],histograms,'WebRTCRendering_fps',unitlessNumber_biggerIsBetter);}
+const meanRatio=numberVsyncs/numberFrames;histograms.createHistogram('WebRTCRendering_fps',unitlessNumber_biggerIsBetter,DISPLAY_HERTZ/meanRatio,{summaryOptions:SUMMARY_OPTIONS,});}
 function frozenPenaltyWeight(numberFrozenFrames){const penalty={5:1,6:5,7:15,8:25};return penalty[numberFrozenFrames]||(8*(numberFrozenFrames-4));}
 function addFreezingScore(histograms,frameHist){let numberVsyncs=0;let freezingScore=0;let frozenFramesCount=0;for(let ticks=1;ticks<frameHist.allBins.length;++ticks){const count=frameHist.allBins[ticks].count;numberVsyncs+=ticks*count;if(ticks>=FROZEN_FRAME_VSYNC_COUNT_THRESHOLD){frozenFramesCount+=count*(ticks-1);freezingScore+=count*frozenPenaltyWeight(ticks-1);}}
 freezingScore=1-freezingScore/numberVsyncs;if(freezingScore<0){freezingScore=0;}
-addHistogram([frozenFramesCount],histograms,'WebRTCRendering_frozen_frames_count',count_smallerIsBetter);addHistogram([freezingScore],histograms,'WebRTCRendering_freezing_score',percentage_biggerIsBetter);}
-function getDriftStats(events){let driftTime=[];let discrepancy=[];let oldIdealRender=0;let expectedIdealRender=0;for(let event of events){let currentIdealRender=event.args[IDEAL_RENDER_INSTANT_NAME];expectedIdealRender+=VSYNC_DURATION_US;if(currentIdealRender===oldIdealRender){continue;}
-let actualRenderBegin=event.args[ACTUAL_RENDER_BEGIN_NAME];driftTime.push(actualRenderBegin-currentIdealRender);discrepancy.push(Math.abs(currentIdealRender-expectedIdealRender));expectedIdealRender=currentIdealRender;oldIdealRender=currentIdealRender;}
-let discrepancySum=tr.b.math.Statistics.sum(discrepancy)-discrepancy[0];let lastIdealRender=events[events.length-1].args[IDEAL_RENDER_INSTANT_NAME];let firstIdealRender=events[0].args[IDEAL_RENDER_INSTANT_NAME];let idealRenderSpan=lastIdealRender-firstIdealRender;let renderingLengthError=discrepancySum/idealRenderSpan;return{driftTime,renderingLengthError};}
-function getSmoothnessStats(driftTimes){let meanDriftTime=tr.b.math.Statistics.mean(driftTimes);let normDriftTimes=driftTimes.map(driftTime=>Math.abs(driftTime-meanDriftTime));let framesSeverelyOutOfSync=normDriftTimes.filter(driftTime=>driftTime>2*VSYNC_DURATION_US).length;let framesOutOfSync=normDriftTimes.filter(driftTime=>driftTime>VSYNC_DURATION_US).length;let percentBadlyOutOfSync=framesSeverelyOutOfSync/driftTimes.length;let percentOutOfSync=framesOutOfSync/driftTimes.length;let framesOutOfSyncOnlyOnce=framesOutOfSync-framesSeverelyOutOfSync;let smoothnessScore=1-(framesOutOfSyncOnlyOnce+
+histograms.createHistogram('WebRTCRendering_frozen_frames_count',count_smallerIsBetter,frozenFramesCount,{summaryOptions:SUMMARY_OPTIONS,});histograms.createHistogram('WebRTCRendering_freezing_score',percentage_biggerIsBetter,freezingScore,{summaryOptions:SUMMARY_OPTIONS,});}
+function getDriftStats(events){const driftTime=[];const discrepancy=[];let oldIdealRender=0;let expectedIdealRender=0;for(const event of events){const currentIdealRender=event.args[IDEAL_RENDER_INSTANT_NAME];expectedIdealRender+=VSYNC_DURATION_US;if(currentIdealRender===oldIdealRender){continue;}
+const actualRenderBegin=event.args[ACTUAL_RENDER_BEGIN_NAME];driftTime.push(actualRenderBegin-currentIdealRender);discrepancy.push(Math.abs(currentIdealRender-expectedIdealRender));expectedIdealRender=currentIdealRender;oldIdealRender=currentIdealRender;}
+const discrepancySum=tr.b.math.Statistics.sum(discrepancy)-
+discrepancy[0];const lastIdealRender=events[events.length-1].args[IDEAL_RENDER_INSTANT_NAME];const firstIdealRender=events[0].args[IDEAL_RENDER_INSTANT_NAME];const idealRenderSpan=lastIdealRender-firstIdealRender;const renderingLengthError=discrepancySum/idealRenderSpan;return{driftTime,renderingLengthError};}
+function getSmoothnessStats(driftTimes){const meanDriftTime=tr.b.math.Statistics.mean(driftTimes);const normDriftTimes=driftTimes.map(driftTime=>Math.abs(driftTime-meanDriftTime));const framesSeverelyOutOfSync=normDriftTimes.filter(driftTime=>driftTime>2*VSYNC_DURATION_US).length;const framesOutOfSync=normDriftTimes.filter(driftTime=>driftTime>VSYNC_DURATION_US).length;const percentBadlyOutOfSync=framesSeverelyOutOfSync/driftTimes.length;const percentOutOfSync=framesOutOfSync/driftTimes.length;const framesOutOfSyncOnlyOnce=framesOutOfSync-framesSeverelyOutOfSync;let smoothnessScore=1-(framesOutOfSyncOnlyOnce+
 SEVERITY*framesSeverelyOutOfSync)/driftTimes.length;if(smoothnessScore<0){smoothnessScore=0;}
 return{framesOutOfSync,framesSeverelyOutOfSync,percentBadlyOutOfSync,percentOutOfSync,smoothnessScore};}
-return{webrtcRenderingMetric,};});'use strict';Polymer({is:'tr-ui-a-alert-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value:function(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_:function(alert){var rows=[];for(var argName in alert.args){var argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
-if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.title);var valueString='';if(event instanceof tr.model.TimedEvent){valueString='took '+event.duration.toFixed(2)+'ms';}
+return{webrtcRenderingMetric,};});'use strict';Polymer({is:'tr-ui-a-alert-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;this.$.table.tableColumns=[{title:'Label',value(row){return row.name;},width:'150px'},{title:'Value',width:'100%',value(row){return row.value;}}];this.$.table.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},getRowsForSingleAlert_(alert){const rows=[];for(const argName in alert.args){const argView=document.createElement('tr-ui-a-generic-object-view');argView.object=alert.args[argName];rows.push({name:argName,value:argView});}
+if(alert.associatedEvents.length){alert.associatedEvents.forEach(function(event,i){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.title);let valueString='';if(event instanceof tr.model.TimedEvent){valueString='took '+event.duration.toFixed(2)+'ms';}
 rows.push({name:linkEl,value:valueString});});}
-var descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){var linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}
-return rows;},getRowsForAlerts_:function(alerts){if(alerts.length===1){var rows=[{name:'Alert',value:tr.b.getOnlyElement(alerts).title}];var detailRows=this.getRowsForSingleAlert_(tr.b.getOnlyElement(alerts));rows.push.apply(rows,detailRows);return rows;}
-return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);},updateContents_:function(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
-var alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;var result=new tr.model.EventSet();for(var event of this.currentSelection_){result.addEventSet(event.associatedEvents);}
-return result;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:false,title:'Alert',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:true,title:'Alerts',});'use strict';tr.exportTo('tr.ui.analysis',function(){var NO_BREAK_SPACE=String.fromCharCode(160);var RIGHTWARDS_ARROW=String.fromCharCode(8594);var COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
-TitleColumn.prototype={supportsCellSelection:false,value:function(row){var formattedTitle=this.formatTitle(row);var contexts=row.contexts;if(contexts===undefined||contexts.length===0){return formattedTitle;}
-var firstContext=contexts[0];var lastContext=contexts[contexts.length-1];var changeDefinedContextCount=0;for(var i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined)){changeDefinedContextCount++;}}
-var color=undefined;var prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
+const descriptionEl=tr.ui.b.createDiv({textContent:alert.info.description,maxWidth:'300px'});rows.push({name:'Description',value:descriptionEl});if(alert.info.docLinks){alert.info.docLinks.forEach(function(linkObject){const linkEl=document.createElement('a');linkEl.target='_blank';linkEl.href=linkObject.href;Polymer.dom(linkEl).textContent=Polymer.dom(linkObject).textContent;rows.push({name:linkObject.label,value:linkEl});});}
+return rows;},getRowsForAlerts_(alerts){if(alerts.length===1){const rows=[{name:'Alert',value:tr.b.getOnlyElement(alerts).title}];const detailRows=this.getRowsForSingleAlert_(tr.b.getOnlyElement(alerts));rows.push.apply(rows,detailRows);return rows;}
+return alerts.map(function(alert){return{name:'Alert',value:alert.title,isExpanded:alerts.size<10,subRows:this.getRowsForSingleAlert_(alert)};},this);},updateContents_(){if(this.currentSelection_===undefined){this.$.table.rows=[];this.$.table.rebuild();return;}
+const alerts=this.currentSelection_;this.$.table.tableRows=this.getRowsForAlerts_(alerts);this.$.table.rebuild();},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const result=new tr.model.EventSet();for(const event of this.currentSelection_){result.addEventSet(event.associatedEvents);}
+return result;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:false,title:'Alert',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-alert-sub-view',tr.model.Alert,{multi:true,title:'Alerts',});'use strict';tr.exportTo('tr.ui.analysis',function(){const NO_BREAK_SPACE=String.fromCharCode(160);const RIGHTWARDS_ARROW=String.fromCharCode(8594);const COLLATOR=new Intl.Collator(undefined,{numeric:true});function TitleColumn(title){this.title=title;}
+TitleColumn.prototype={supportsCellSelection:false,value(row){const formattedTitle=this.formatTitle(row);const contexts=row.contexts;if(contexts===undefined||contexts.length===0){return formattedTitle;}
+const firstContext=contexts[0];const lastContext=contexts[contexts.length-1];let changeDefinedContextCount=0;for(let i=1;i<contexts.length;i++){if((contexts[i]===undefined)!==(contexts[i-1]===undefined)){changeDefinedContextCount++;}}
+let color=undefined;let prefix=undefined;if(!firstContext&&lastContext){color='red';prefix='+++';}else if(firstContext&&!lastContext){color='green';prefix='---';}
 if(changeDefinedContextCount>1){color='purple';}
 if(color===undefined&&prefix===undefined){return formattedTitle;}
-var titleEl=document.createElement('span');if(prefix!==undefined){var prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';Polymer.dom(titleEl).appendChild(prefixEl);Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
+const titleEl=document.createElement('span');if(prefix!==undefined){const prefixEl=tr.ui.b.createSpan({textContent:prefix});prefixEl.style.fontFamily='monospace';Polymer.dom(titleEl).appendChild(prefixEl);Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(NO_BREAK_SPACE));}
 if(color!==undefined){titleEl.style.color=color;}
-Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle:function(row){return row.title;},cmp:function(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.shouldSetContextGroup=false;this.aggregationMode=aggregationMode;}
-MemoryColumn.fromRows=function(rows,config){var cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)return;var fieldCells=row[config.cellKey];if(fieldCells!==undefined){for(var[fieldName,fieldCell]of Object.entries(fieldCells)){if(fieldCell===undefined||fieldCell.fields===undefined){continue;}
+Polymer.dom(titleEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedTitle));return titleEl;},formatTitle(row){return row.title;},cmp(rowA,rowB){return COLLATOR.compare(rowA.title,rowB.title);}};function MemoryColumn(name,cellPath,aggregationMode){this.name=name;this.cellPath=cellPath;this.shouldSetContextGroup=false;this.aggregationMode=aggregationMode;}
+MemoryColumn.fromRows=function(rows,config){const cellNames=new Set();function gatherCellNames(rows){rows.forEach(function(row){if(row===undefined)return;const fieldCells=row[config.cellKey];if(fieldCells!==undefined){for(const[fieldName,fieldCell]of Object.entries(fieldCells)){if(fieldCell===undefined||fieldCell.fields===undefined){continue;}
 cellNames.add(fieldName);}}
-var subRows=row.subRows;if(subRows!==undefined){gatherCellNames(subRows);}});}
-gatherCellNames(rows);var positions=[];cellNames.forEach(function(cellName){var cellPath=[config.cellKey,cellName];var matchingRule=MemoryColumn.findMatchingRule(cellName,config.rules);var constructor=matchingRule.columnConstructor;var column=new constructor(cellName,cellPath,config.aggregationMode);column.shouldSetContextGroup=!!config.shouldSetContextGroup;positions.push({importance:matchingRule.importance,column:column});});positions.sort(function(a,b){if(a.importance===b.importance){return COLLATOR.compare(a.column.name,b.column.name);}
-return b.importance-a.importance;});return positions.map(function(position){return position.column;});};MemoryColumn.spaceEqually=function(columns){var columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(var i=0;i<rules.length;i++){var rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition)){return rule;}}
-return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)return true;if(typeof(condition)==='string')return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell:function(row){var cell=row;var cellPath=this.cellPath;for(var i=0;i<cellPath.length;i++){if(cell===undefined)return undefined;cell=cell[cellPath[i]];}
-return cell;},aggregateCells:function(row,subRows){},fields:function(row){var cell=this.cell(row);if(cell===undefined)return undefined;return cell.fields;},value:function(row){var fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))return'';var contexts=row.contexts;var color=this.color(fields,contexts);var infos=[];this.addInfos(fields,contexts,infos);var formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0){return formattedFields;}
-var fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.style.justifyContent='flex-end';Polymer.dom(fieldEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){var infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';Polymer.dom(infoEl).textContent=info.icon;if(info.color!==undefined){infoEl.style.color=info.color;}
+const subRows=row.subRows;if(subRows!==undefined){gatherCellNames(subRows);}});}
+gatherCellNames(rows);const positions=[];cellNames.forEach(function(cellName){const cellPath=[config.cellKey,cellName];const matchingRule=MemoryColumn.findMatchingRule(cellName,config.rules);const constructor=matchingRule.columnConstructor;const column=new constructor(cellName,cellPath,config.aggregationMode);column.shouldSetContextGroup=!!config.shouldSetContextGroup;positions.push({importance:matchingRule.importance,column});});positions.sort(function(a,b){if(a.importance===b.importance){return COLLATOR.compare(a.column.name,b.column.name);}
+return b.importance-a.importance;});return positions.map(function(position){return position.column;});};MemoryColumn.spaceEqually=function(columns){const columnWidth=(100/columns.length).toFixed(3)+'%';columns.forEach(function(column){column.width=columnWidth;});};MemoryColumn.findMatchingRule=function(name,rules){for(let i=0;i<rules.length;i++){const rule=rules[i];if(MemoryColumn.nameMatchesCondition(name,rule.condition)){return rule;}}
+return undefined;};MemoryColumn.nameMatchesCondition=function(name,condition){if(condition===undefined)return true;if(typeof(condition)==='string')return name===condition;return condition.test(name);};MemoryColumn.AggregationMode={DIFF:0,MAX:1};MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER='at some selected timestamps';MemoryColumn.prototype={get title(){return this.name;},cell(row){let cell=row;const cellPath=this.cellPath;for(let i=0;i<cellPath.length;i++){if(cell===undefined)return undefined;cell=cell[cellPath[i]];}
+return cell;},aggregateCells(row,subRows){},fields(row){const cell=this.cell(row);if(cell===undefined)return undefined;return cell.fields;},value(row){const fields=this.fields(row);if(this.hasAllRelevantFieldsUndefined(fields))return'';const contexts=row.contexts;const color=this.color(fields,contexts);const infos=[];this.addInfos(fields,contexts,infos);const formattedFields=this.formatFields(fields);if((color===undefined||formattedFields==='')&&infos.length===0){return formattedFields;}
+const fieldEl=document.createElement('span');fieldEl.style.display='flex';fieldEl.style.alignItems='center';fieldEl.style.justifyContent='flex-end';Polymer.dom(fieldEl).appendChild(tr.ui.b.asHTMLOrTextNode(formattedFields));infos.forEach(function(info){const infoEl=document.createElement('span');infoEl.style.paddingLeft='4px';infoEl.style.cursor='help';infoEl.style.fontWeight='bold';Polymer.dom(infoEl).textContent=info.icon;if(info.color!==undefined){infoEl.style.color=info.color;}
 infoEl.title=info.message;Polymer.dom(fieldEl).appendChild(infoEl);},this);if(color!==undefined){fieldEl.style.color=color;}
-return fieldEl;},hasAllRelevantFieldsUndefined:function(fields){if(fields===undefined)return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color:function(fields,contexts){return undefined;},formatFields:function(fields){if(fields.length===1){return this.formatSingleField(fields[0]);}
-return this.formatMultipleFields(fields);},formatSingleField:function(field){throw new Error('Not implemented');},formatMultipleFields:function(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff:function(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax:function(fields){return this.formatSingleField(this.getMaxField(fields));},cmp:function(rowA,rowB){var fieldsA=this.fields(rowA);var fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length){throw new Error('Different number of fields');}
-var undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);var undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)return 0;if(undefinedA)return-1;if(undefinedB)return 1;return this.compareFields(fieldsA,fieldsB);},compareFields:function(fieldsA,fieldsB){if(fieldsA.length===1){return this.compareSingleFields(fieldsA[0],fieldsB[0]);}
-return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields:function(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields:function(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff:function(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax:function(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField:function(fields){return fields.reduce(function(accumulator,field){if(field===undefined){return accumulator;}
+return fieldEl;},hasAllRelevantFieldsUndefined(fields){if(fields===undefined)return true;switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return fields[0]===undefined&&fields[fields.length-1]===undefined;case MemoryColumn.AggregationMode.MAX:default:return fields.every(function(field){return field===undefined;});}},color(fields,contexts){return undefined;},formatFields(fields){if(fields.length===1){return this.formatSingleField(fields[0]);}
+return this.formatMultipleFields(fields);},formatSingleField(field){throw new Error('Not implemented');},formatMultipleFields(fields){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.formatMultipleFieldsDiff(fields[0],fields[fields.length-1]);case MemoryColumn.AggregationMode.MAX:return this.formatMultipleFieldsMax(fields);default:return tr.ui.b.createSpan({textContent:'(unsupported aggregation mode)',italic:true});}},formatMultipleFieldsDiff(firstField,lastField){throw new Error('Not implemented');},formatMultipleFieldsMax(fields){return this.formatSingleField(this.getMaxField(fields));},cmp(rowA,rowB){const fieldsA=this.fields(rowA);const fieldsB=this.fields(rowB);if(fieldsA!==undefined&&fieldsB!==undefined&&fieldsA.length!==fieldsB.length){throw new Error('Different number of fields');}
+const undefinedA=this.hasAllRelevantFieldsUndefined(fieldsA);const undefinedB=this.hasAllRelevantFieldsUndefined(fieldsB);if(undefinedA&&undefinedB)return 0;if(undefinedA)return-1;if(undefinedB)return 1;return this.compareFields(fieldsA,fieldsB);},compareFields(fieldsA,fieldsB){if(fieldsA.length===1){return this.compareSingleFields(fieldsA[0],fieldsB[0]);}
+return this.compareMultipleFields(fieldsA,fieldsB);},compareSingleFields(fieldA,fieldB){throw new Error('Not implemented');},compareMultipleFields(fieldsA,fieldsB){switch(this.aggregationMode){case MemoryColumn.AggregationMode.DIFF:return this.compareMultipleFieldsDiff(fieldsA[0],fieldsA[fieldsA.length-1],fieldsB[0],fieldsB[fieldsB.length-1]);case MemoryColumn.AggregationMode.MAX:return this.compareMultipleFieldsMax(fieldsA,fieldsB);default:return 0;}},compareMultipleFieldsDiff(firstFieldA,lastFieldA,firstFieldB,lastFieldB){throw new Error('Not implemented');},compareMultipleFieldsMax(fieldsA,fieldsB){return this.compareSingleFields(this.getMaxField(fieldsA),this.getMaxField(fieldsB));},getMaxField(fields){return fields.reduce(function(accumulator,field){if(field===undefined){return accumulator;}
 if(accumulator===undefined||this.compareSingleFields(field,accumulator)>0){return field;}
-return accumulator;}.bind(this),undefined);},addInfos:function(fields,contexts,infos){},getImportance:function(importanceRules){if(importanceRules.length===0)return 0;var matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined){return matchingRule.importance;}
-var minImportance=importanceRules[0].importance;for(var i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
+return accumulator;}.bind(this),undefined);},addInfos(fields,contexts,infos){},getImportance(importanceRules){if(importanceRules.length===0)return 0;const matchingRule=MemoryColumn.findMatchingRule(this.name,importanceRules);if(matchingRule!==undefined){return matchingRule.importance;}
+let minImportance=importanceRules[0].importance;for(let i=1;i<importanceRules.length;i++){minImportance=Math.min(minImportance,importanceRules[i].importance);}
 return minImportance-1;}};function StringMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
-StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField:function(string){return string;},formatMultipleFieldsDiff:function(firstString,lastString){if(firstString===undefined){var spanEl=tr.ui.b.createSpan({color:'red'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('+'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){var spanEl=tr.ui.b.createSpan({color:'green'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('-'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}
-var spanEl=tr.ui.b.createSpan({color:'DarkOrange'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;},compareSingleFields:function(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff:function(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined){return 1;}
+StringMemoryColumn.prototype={__proto__:MemoryColumn.prototype,formatSingleField(string){return string;},formatMultipleFieldsDiff(firstString,lastString){if(firstString===undefined){const spanEl=tr.ui.b.createSpan({color:'red'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('+'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;}else if(lastString===undefined){const spanEl=tr.ui.b.createSpan({color:'green'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode('-'));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));return spanEl;}else if(firstString===lastString){return this.formatSingleField(firstString);}
+const spanEl=tr.ui.b.createSpan({color:'DarkOrange'});Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(firstString)));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(' '+RIGHTWARDS_ARROW+' '));Polymer.dom(spanEl).appendChild(tr.ui.b.asHTMLOrTextNode(this.formatSingleField(lastString)));return spanEl;},compareSingleFields(stringA,stringB){return COLLATOR.compare(stringA,stringB);},compareMultipleFieldsDiff(firstStringA,lastStringA,firstStringB,lastStringB){if(firstStringA===undefined&&firstStringB!==undefined){return 1;}
 if(firstStringA!==undefined&&firstStringB===undefined){return-1;}
 if(firstStringA===undefined&&firstStringB===undefined){return this.compareSingleFields(lastStringA,lastStringB);}
 if(lastStringA===undefined&&lastStringB!==undefined){return-1;}
 if(lastStringA!==undefined&&lastStringB===undefined){return 1;}
 if(lastStringA===undefined&&lastStringB===undefined){return this.compareSingleFields(firstStringB,firstStringA);}
-var areStringsAEqual=firstStringA===lastStringA;var areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)return 0;if(areStringsAEqual)return-1;if(areStringsBEqual)return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
-NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,aggregateCells:function(row,subRows){var subRowCells=subRows.map(this.cell,this);var hasDefinedSubRowNumeric=false;var timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)return;var subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)return;if(timestampCount===undefined){timestampCount=subRowNumerics.length;}else if(timestampCount!==subRowNumerics.length){throw new Error('Sub-rows have different numbers of timestamps');}
+const areStringsAEqual=firstStringA===lastStringA;const areStringsBEqual=firstStringB===lastStringB;if(areStringsAEqual&&areStringsBEqual)return 0;if(areStringsAEqual)return-1;if(areStringsBEqual)return 1;return 0;}};function NumericMemoryColumn(name,cellPath,aggregationMode){MemoryColumn.call(this,name,cellPath,aggregationMode);}
+NumericMemoryColumn.DIFF_EPSILON=0.0001;NumericMemoryColumn.prototype={__proto__:MemoryColumn.prototype,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,aggregateCells(row,subRows){const subRowCells=subRows.map(this.cell,this);let hasDefinedSubRowNumeric=false;let timestampCount=undefined;subRowCells.forEach(function(subRowCell){if(subRowCell===undefined)return;const subRowNumerics=subRowCell.fields;if(subRowNumerics===undefined)return;if(timestampCount===undefined){timestampCount=subRowNumerics.length;}else if(timestampCount!==subRowNumerics.length){throw new Error('Sub-rows have different numbers of timestamps');}
 if(hasDefinedSubRowNumeric){return;}
 hasDefinedSubRowNumeric=subRowNumerics.some(function(numeric){return numeric!==undefined;});});if(!hasDefinedSubRowNumeric){return;}
-var cellPath=this.cellPath;var rowCell=row;for(var i=0;i<cellPath.length;i++){var nextStepName=cellPath[i];var nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1){nextStep={};}else{nextStep=new MemoryCell(undefined);}
+const cellPath=this.cellPath;let rowCell=row;for(let i=0;i<cellPath.length;i++){const nextStepName=cellPath[i];let nextStep=rowCell[nextStepName];if(nextStep===undefined){if(i<cellPath.length-1){nextStep={};}else{nextStep=new MemoryCell(undefined);}
 rowCell[nextStepName]=nextStep;}
 rowCell=nextStep;}
 if(rowCell.fields===undefined){rowCell.fields=new Array(timestampCount);}else if(rowCell.fields.length!==timestampCount){throw new Error('Row has a different number of timestamps than sub-rows');}
-for(var i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined){return undefined;}
-return subRowCell.fields[i];}));}},formatSingleField:function(numeric){return tr.v.ui.createScalarSpan(numeric,{context:this.getFormattingContext(numeric.unit),contextGroup:this.shouldSetContextGroup?this.name:undefined,inline:true,});},getFormattingContext:function(unit){return undefined;},formatMultipleFieldsDiff:function(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields:function(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff:function(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
-this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_:function(firstNumeric,lastNumeric){var definedNumeric=firstNumeric||lastNumeric;return new tr.b.Scalar(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_:function(firstNumeric,lastNumeric){var firstValue=firstNumeric===undefined?0:firstNumeric.value;var lastValue=lastNumeric===undefined?0:lastNumeric.value;var diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
-MemoryCell.extractFields=function(cell){if(cell===undefined)return undefined;return cell.fields;};var RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){var currentLevelRows=table.tableRows;var totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){var nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
-var nextLevelRows=new Array(nextLevelRowCount);var nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){var subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
-function aggregateTableRowCellsRecursively(row,columns,opt_predicate){var subRows=row.subRows;if(subRows===undefined||subRows.length===0)return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts)){aggregateTableRowCells(row,subRows,columns);}}
+for(let i=0;i<timestampCount;i++){if(rowCell.fields[i]!==undefined)continue;rowCell.fields[i]=tr.model.MemoryAllocatorDump.aggregateNumerics(subRowCells.map(function(subRowCell){if(subRowCell===undefined||subRowCell.fields===undefined){return undefined;}
+return subRowCell.fields[i];}));}},formatSingleField(numeric){return tr.v.ui.createScalarSpan(numeric,{context:this.getFormattingContext(numeric.unit),contextGroup:this.shouldSetContextGroup?this.name:undefined,inline:true,});},getFormattingContext(unit){return undefined;},formatMultipleFieldsDiff(firstNumeric,lastNumeric){return this.formatSingleField(this.getDiffField_(firstNumeric,lastNumeric));},compareSingleFields(numericA,numericB){return numericA.value-numericB.value;},compareMultipleFieldsDiff(firstNumericA,lastNumericA,firstNumericB,lastNumericB){return this.getDiffFieldValue_(firstNumericA,lastNumericA)-
+this.getDiffFieldValue_(firstNumericB,lastNumericB);},getDiffField_(firstNumeric,lastNumeric){const definedNumeric=firstNumeric||lastNumeric;return new tr.b.Scalar(definedNumeric.unit.correspondingDeltaUnit,this.getDiffFieldValue_(firstNumeric,lastNumeric));},getDiffFieldValue_(firstNumeric,lastNumeric){const firstValue=firstNumeric===undefined?0:firstNumeric.value;const lastValue=lastNumeric===undefined?0:lastNumeric.value;const diff=lastValue-firstValue;return Math.abs(diff)<NumericMemoryColumn.DIFF_EPSILON?0:diff;}};function MemoryCell(fields){this.fields=fields;}
+MemoryCell.extractFields=function(cell){if(cell===undefined)return undefined;return cell.fields;};const RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT=10;function expandTableRowsRecursively(table){let currentLevelRows=table.tableRows;let totalVisibleRowCount=currentLevelRows.length;while(currentLevelRows.length>0){let nextLevelRowCount=0;currentLevelRows.forEach(function(currentLevelRow){const subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;nextLevelRowCount+=subRows.length;});if(totalVisibleRowCount+nextLevelRowCount>RECURSIVE_EXPANSION_MAX_VISIBLE_ROW_COUNT){break;}
+const nextLevelRows=new Array(nextLevelRowCount);let nextLevelRowIndex=0;currentLevelRows.forEach(function(currentLevelRow){const subRows=currentLevelRow.subRows;if(subRows===undefined||subRows.length===0)return;table.setExpandedForTableRow(currentLevelRow,true);subRows.forEach(function(subRow){nextLevelRows[nextLevelRowIndex++]=subRow;});});totalVisibleRowCount+=nextLevelRowCount;currentLevelRows=nextLevelRows;}}
+function aggregateTableRowCellsRecursively(row,columns,opt_predicate){const subRows=row.subRows;if(subRows===undefined||subRows.length===0)return;subRows.forEach(function(subRow){aggregateTableRowCellsRecursively(subRow,columns,opt_predicate);});if(opt_predicate===undefined||opt_predicate(row.contexts)){aggregateTableRowCells(row,subRows,columns);}}
 function aggregateTableRowCells(row,subRows,columns){columns.forEach(function(column){if(!(column instanceof MemoryColumn))return;column.aggregateCells(row,subRows);});}
-function createCells(timeToValues,valueFieldsGetter,opt_this){opt_this=opt_this||this;var fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter,opt_this);return tr.b.mapItems(fieldNameToFields,function(fieldName,fields){return new tr.ui.analysis.MemoryCell(fields);});}
-function createWarningInfo(message){return{message:message,icon:String.fromCharCode(9888),color:'red'};}
+function createCells(timeToValues,valueFieldsGetter,opt_this){opt_this=opt_this||this;const fieldNameToFields=tr.b.invertArrayOfDicts(timeToValues,valueFieldsGetter,opt_this);return tr.b.mapItems(fieldNameToFields,function(fieldName,fields){return new tr.ui.analysis.MemoryCell(fields);});}
+function createWarningInfo(message){return{message,icon:String.fromCharCode(9888),color:'red'};}
 function DetailsNumericMemoryColumn(name,cellPath,aggregationMode){NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-DetailsNumericMemoryColumn.prototype={__proto__:NumericMemoryColumn.prototype,getFormattingContext:function(unit){if(unit.baseUnit===tr.b.Unit.byName.sizeInBytes){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.KIBI};}
-return undefined;}};return{TitleColumn,MemoryColumn,StringMemoryColumn,NumericMemoryColumn,MemoryCell,expandTableRowsRecursively,aggregateTableRowCellsRecursively,aggregateTableRowCells,createCells,createWarningInfo,DetailsNumericMemoryColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){var LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);var CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);var HeapDetailsRowDimension={ROOT:{},STACK_FRAME:{label:'Stack frame',symbol:LATIN_SMALL_LETTER_F_WITH_HOOK,color:'heap_dump_stack_frame'},OBJECT_TYPE:{label:'Object type',symbol:CIRCLED_LATIN_CAPITAL_LETTER_T,color:'heap_dump_object_type'}};function HeapDetailsTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
-HeapDetailsTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.dimension===HeapDetailsRowDimension.ROOT){return row.title;}
-var symbolEl=document.createElement('span');Polymer.dom(symbolEl).textContent=row.dimension.symbol;symbolEl.title=row.dimension.label;symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(row.dimension.color);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.fontWeight='bold';var titleEl=document.createElement('span');Polymer.dom(titleEl).appendChild(symbolEl);Polymer.dom(titleEl).appendChild(document.createTextNode(row.title));return titleEl;}};function AllocationCountColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-AllocationCountColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,getFormattingContext:function(unit){return{minimumFractionDigits:0};}};var HEAP_DETAILS_COLUMN_RULES=[{condition:'Size',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Count',importance:1,columnConstructor:AllocationCountColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];return{HeapDetailsRowDimension,HeapDetailsTitleColumn,AllocationCountColumn,HEAP_DETAILS_COLUMN_RULES,};});'use strict';tr.exportTo('tr.ui.analysis',function(){var RebuildableBehavior={rebuild:function(){if(!this.paneDirty_){return;}
-this.paneDirty_=false;this.onRebuild_();},scheduleRebuild_:function(){if(this.paneDirty_)return;this.paneDirty_=true;tr.b.requestAnimationFrame(this.rebuild.bind(this));},onRebuild_:function(){}};return{RebuildableBehavior,};});'use strict';Polymer({is:'tr-ui-b-tab-view',properties:{label_:{type:String,value:()=>''},selectedSubView_:Object,subViews_:{type:Array,value:()=>[]},tabsHidden:{type:Boolean,value:false,observer:'tabsHiddenChanged_'}},ready(){this.$.tabs.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.updateFocusability_();},set label(newLabel){this.set('label_',newLabel);},get tabs(){return this.get('subViews_');},get selectedSubView(){return this.selectedSubView_;},set selectedSubView(subView){if(subView===this.selectedSubView_)return;if(this.selectedSubView_){Polymer.dom(this.$.subView).removeChild(this.selectedSubView_);let oldInput=this.root.getElementById(this.computeRadioId_(this.selectedSubView_));if(oldInput){oldInput.checked=false;}}
-this.set('selectedSubView_',subView);if(subView){Polymer.dom(this.$.subView).appendChild(subView);let newInput=this.root.getElementById(this.computeRadioId_(subView));if(newInput){newInput.checked=true;}}
-this.fire('selected-tab-change');},clearSubViews(){this.splice('subViews_',0,this.subViews_.length);this.selectedSubView=undefined;this.updateFocusability_();},addSubView(subView){this.push('subViews_',subView);if(!this.selectedSubView_)this.selectedSubView=subView;this.updateFocusability_();},resetSubViews(subViews){this.splice('subViews_',0,this.subViews_.length);if(subViews.length){for(let subView of subViews){this.push('subViews_',subView);}
+DetailsNumericMemoryColumn.prototype={__proto__:NumericMemoryColumn.prototype,getFormattingContext(unit){if(unit.baseUnit===tr.b.Unit.byName.sizeInBytes){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.KIBI};}
+return undefined;}};return{TitleColumn,MemoryColumn,StringMemoryColumn,NumericMemoryColumn,MemoryCell,expandTableRowsRecursively,aggregateTableRowCellsRecursively,aggregateTableRowCells,createCells,createWarningInfo,DetailsNumericMemoryColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const LATIN_SMALL_LETTER_F_WITH_HOOK=String.fromCharCode(0x0192);const CIRCLED_LATIN_CAPITAL_LETTER_T=String.fromCharCode(0x24C9);const HeapDetailsRowDimension={ROOT:{},STACK_FRAME:{label:'Stack frame',symbol:LATIN_SMALL_LETTER_F_WITH_HOOK,color:'heap_dump_stack_frame'},OBJECT_TYPE:{label:'Object type',symbol:CIRCLED_LATIN_CAPITAL_LETTER_T,color:'heap_dump_object_type'}};function HeapDetailsTitleColumn(title){tr.ui.analysis.TitleColumn.call(this,title);}
+HeapDetailsTitleColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(row.dimension===HeapDetailsRowDimension.ROOT){return row.title;}
+const symbolEl=document.createElement('span');Polymer.dom(symbolEl).textContent=row.dimension.symbol;symbolEl.title=row.dimension.label;symbolEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString(row.dimension.color);symbolEl.style.paddingRight='4px';symbolEl.style.cursor='help';symbolEl.style.fontWeight='bold';const titleEl=document.createElement('span');Polymer.dom(titleEl).appendChild(symbolEl);Polymer.dom(titleEl).appendChild(document.createTextNode(row.title));return titleEl;}};function AllocationCountColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocationCountColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,getFormattingContext(unit){return{minimumFractionDigits:0};}};const HEAP_DETAILS_COLUMN_RULES=[{condition:'Size',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Count',importance:1,columnConstructor:AllocationCountColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];return{HeapDetailsRowDimension,HeapDetailsTitleColumn,AllocationCountColumn,HEAP_DETAILS_COLUMN_RULES,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const RebuildableBehavior={rebuild(){if(!this.paneDirty_){return;}
+this.paneDirty_=false;this.onRebuild_();},scheduleRebuild_(){if(this.paneDirty_)return;this.paneDirty_=true;tr.b.requestAnimationFrame(this.rebuild.bind(this));},onRebuild_(){}};return{RebuildableBehavior,};});'use strict';Polymer({is:'tr-ui-b-tab-view',properties:{label_:{type:String,value:()=>''},selectedSubView_:Object,subViews_:{type:Array,value:()=>[]},tabsHidden:{type:Boolean,value:false,observer:'tabsHiddenChanged_'}},ready(){this.$.tabs.addEventListener('keydown',this.onKeyDown_.bind(this),true);this.updateFocusability_();},set label(newLabel){this.set('label_',newLabel);},get tabs(){return this.get('subViews_');},get selectedSubView(){return this.selectedSubView_;},set selectedSubView(subView){if(subView===this.selectedSubView_)return;if(this.selectedSubView_){Polymer.dom(this.$.subView).removeChild(this.selectedSubView_);const oldInput=this.root.getElementById(this.computeRadioId_(this.selectedSubView_));if(oldInput){oldInput.checked=false;}}
+this.set('selectedSubView_',subView);if(subView){Polymer.dom(this.$.subView).appendChild(subView);const newInput=this.root.getElementById(this.computeRadioId_(subView));if(newInput){newInput.checked=true;}}
+this.fire('selected-tab-change');},clearSubViews(){this.splice('subViews_',0,this.subViews_.length);this.selectedSubView=undefined;this.updateFocusability_();},addSubView(subView){this.push('subViews_',subView);if(!this.selectedSubView_)this.selectedSubView=subView;this.updateFocusability_();},resetSubViews(subViews){this.splice('subViews_',0,this.subViews_.length);if(subViews.length){for(const subView of subViews){this.push('subViews_',subView);}
 this.selectedSubView=subViews[0];}else{this.selectedSubView=undefined;}
 this.updateFocusability_();},onTabChanged_(event){this.selectedSubView=event.model.item;},isChecked_(subView){return this.selectedSubView_===subView;},tabsHiddenChanged_(){this.updateFocusability_();},onKeyDown_(e){if(this.tabsHidden)return;let keyHandled=false;switch(e.keyCode){case 37:keyHandled=this.selectPreviousTabIfPossible();break;case 39:keyHandled=this.selectNextTabIfPossible();break;}
-if(!keyHandled)return;e.stopPropagation();e.preventDefault();},selectNextTabIfPossible(){return this.selectTabByOffsetIfPossible_(1);},selectPreviousTabIfPossible(){return this.selectTabByOffsetIfPossible_(-1);},selectTabByOffsetIfPossible_(offset){if(!this.selectedSubView_)return false;let currentIndex=this.subViews_.indexOf(this.selectedSubView_);let newSubView=this.tabs[currentIndex+offset];if(!newSubView)return false;this.selectedSubView=newSubView;return true;},shouldBeFocusable_(){return!this.tabsHidden&&this.subViews_.length>0;},updateFocusability_(){if(this.shouldBeFocusable_()){Polymer.dom(this.$.tabs).setAttribute('tabindex',0);}else{Polymer.dom(this.$.tabs).removeAttribute('tabindex');}},computeRadioId_(subView){return subView.tagName+'-'+subView.tabLabel.replace(/ /g,'-');}});'use strict';tr.exportTo('tr.ui.analysis',function(){var RESONABLE_NUMBER_OF_ROWS=200;var TabUiState={NO_LONG_TAIL:0,HIDING_LONG_TAIL:1,SHOWING_LONG_TAIL:2,};function EmptyFillerColumn(){}
-EmptyFillerColumn.prototype={title:'',value:function(){return'';},};Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created:function(){this.displayedNode_=undefined;this.dimensionToTab_=new Map();},ready:function(){this.scheduleRebuild_();this.root.addEventListener('keydown',this.onKeyDown_.bind(this),true);},get displayedNode(){return this.displayedNode_;},set displayedNode(node){this.displayedNode_=node;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;for(var tab of this.$.tabs.tabs){tab.aggregationMode=aggregationMode;}},onRebuild_:function(){var previouslySelectedTab=this.$.tabs.selectedSubView;var previouslySelectedTabFocused=false;var previouslySelectedDimension=undefined;if(previouslySelectedTab){previouslySelectedTabFocused=previouslySelectedTab.isFocused;previouslySelectedDimension=previouslySelectedTab.dimension;}
-for(var tab of this.$.tabs.tabs){tab.nodes=undefined;}
+if(!keyHandled)return;e.stopPropagation();e.preventDefault();},selectNextTabIfPossible(){return this.selectTabByOffsetIfPossible_(1);},selectPreviousTabIfPossible(){return this.selectTabByOffsetIfPossible_(-1);},selectTabByOffsetIfPossible_(offset){if(!this.selectedSubView_)return false;const currentIndex=this.subViews_.indexOf(this.selectedSubView_);const newSubView=this.tabs[currentIndex+offset];if(!newSubView)return false;this.selectedSubView=newSubView;return true;},shouldBeFocusable_(){return!this.tabsHidden&&this.subViews_.length>0;},updateFocusability_(){if(this.shouldBeFocusable_()){Polymer.dom(this.$.tabs).setAttribute('tabindex',0);}else{Polymer.dom(this.$.tabs).removeAttribute('tabindex');}},computeRadioId_(subView){return subView.tagName+'-'+subView.tabLabel.replace(/ /g,'-');}});'use strict';tr.exportTo('tr.ui.analysis',function(){const RESONABLE_NUMBER_OF_ROWS=200;const TabUiState={NO_LONG_TAIL:0,HIDING_LONG_TAIL:1,SHOWING_LONG_TAIL:2,};function EmptyFillerColumn(){}
+EmptyFillerColumn.prototype={title:'',value(){return'';},};Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.displayedNode_=undefined;this.dimensionToTab_=new Map();},ready(){this.scheduleRebuild_();this.root.addEventListener('keydown',this.onKeyDown_.bind(this),true);},get displayedNode(){return this.displayedNode_;},set displayedNode(node){this.displayedNode_=node;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;for(const tab of this.$.tabs.tabs){tab.aggregationMode=aggregationMode;}},onRebuild_(){const previouslySelectedTab=this.$.tabs.selectedSubView;let previouslySelectedTabFocused=false;let previouslySelectedDimension=undefined;if(previouslySelectedTab){previouslySelectedTabFocused=previouslySelectedTab.isFocused;previouslySelectedDimension=previouslySelectedTab.dimension;}
+for(const tab of this.$.tabs.tabs){tab.nodes=undefined;}
 this.$.tabs.clearSubViews();if(this.displayedNode_===undefined){this.$.tabs.label='No heap node provided.';return;}
-for(var[dimension,children]of this.displayedNode_.childNodes){if(!this.dimensionToTab_.has(dimension)){this.dimensionToTab_.set(dimension,document.createElement('tr-ui-a-memory-dump-heap-details-breakdown-view-tab'));}
-var tab=this.dimensionToTab_.get(dimension);tab.aggregationMode=this.aggregationMode_;tab.dimension=dimension;tab.nodes=children;this.$.tabs.addSubView(tab);tab.rebuild();if(dimension===previouslySelectedDimension){this.$.tabs.selectedSubView=tab;if(previouslySelectedTabFocused){tab.focus();}}}
-if(this.$.tabs.tabs.length>0){this.$.tabs.label='Break selected node further by:';}else{this.$.tabs.label='Selected node cannot be broken down any further.';}},onKeyDown_:function(keyEvent){if(!this.displayedNode_)return;var keyHandled=false;switch(keyEvent.keyCode){case 8:if(!this.displayedNode_.parentNode)break;var viewEvent=new tr.b.Event('enter-node');viewEvent.node=this.displayedNode_.parentNode;this.dispatchEvent(viewEvent);keyHandled=true;break;case 37:case 39:var wasFocused=this.$.tabs.selectedSubView.isFocused;keyHandled=keyEvent.keyCode===37?this.$.tabs.selectPreviousTabIfPossible():this.$.tabs.selectNextTabIfPossible();if(wasFocused&&keyHandled){this.$.tabs.selectedSubView.focus();}}
-if(!keyHandled)return;keyEvent.stopPropagation();keyEvent.preventDefault();}});Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view-tab',behaviors:[tr.ui.analysis.RebuildableBehavior],created:function(){this.dimension_=undefined;this.nodes_=undefined;this.aggregationMode_=undefined;this.displayLongTail_=false;},ready:function(){this.$.table.addEventListener('step-into',function(tableEvent){var viewEvent=new tr.b.Event('enter-node');viewEvent.node=tableEvent.tableRow;this.dispatchEvent(viewEvent);}.bind(this));},get displayLongTail(){return this.displayLongTail_;},set displayLongTail(newValue){if(this.displayLongTail===newValue)return;this.displayLongTail_=newValue;this.scheduleRebuild_();},get dimension(){return this.dimension_;},set dimension(dimension){this.dimension_=dimension;this.scheduleRebuild_();},get nodes(){return this.nodes_;},set nodes(nodes){this.nodes_=nodes;this.scheduleRebuild_();},get nodes(){return this.nodes_||[];},get dimensionLabel_(){if(this.dimension_===undefined)return'(undefined)';return this.dimension_.label;},get tabLabel(){var nodeCount=0;if(this.nodes_){nodeCount=this.nodes_.length;}
+for(const[dimension,children]of this.displayedNode_.childNodes){if(!this.dimensionToTab_.has(dimension)){this.dimensionToTab_.set(dimension,document.createElement('tr-ui-a-memory-dump-heap-details-breakdown-view-tab'));}
+const tab=this.dimensionToTab_.get(dimension);tab.aggregationMode=this.aggregationMode_;tab.dimension=dimension;tab.nodes=children;this.$.tabs.addSubView(tab);tab.rebuild();if(dimension===previouslySelectedDimension){this.$.tabs.selectedSubView=tab;if(previouslySelectedTabFocused){tab.focus();}}}
+if(this.$.tabs.tabs.length>0){this.$.tabs.label='Break selected node further by:';}else{this.$.tabs.label='Selected node cannot be broken down any further.';}},onKeyDown_(keyEvent){if(!this.displayedNode_)return;let keyHandled=false;switch(keyEvent.keyCode){case 8:{if(!this.displayedNode_.parentNode)break;const viewEvent=new tr.b.Event('enter-node');viewEvent.node=this.displayedNode_.parentNode;this.dispatchEvent(viewEvent);keyHandled=true;break;}
+case 37:case 39:{const wasFocused=this.$.tabs.selectedSubView.isFocused;keyHandled=keyEvent.keyCode===37?this.$.tabs.selectPreviousTabIfPossible():this.$.tabs.selectNextTabIfPossible();if(wasFocused&&keyHandled){this.$.tabs.selectedSubView.focus();}}}
+if(!keyHandled)return;keyEvent.stopPropagation();keyEvent.preventDefault();}});Polymer({is:'tr-ui-a-memory-dump-heap-details-breakdown-view-tab',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.dimension_=undefined;this.nodes_=undefined;this.aggregationMode_=undefined;this.displayLongTail_=false;},ready(){this.$.table.addEventListener('step-into',function(tableEvent){const viewEvent=new tr.b.Event('enter-node');viewEvent.node=tableEvent.tableRow;this.dispatchEvent(viewEvent);}.bind(this));},get displayLongTail(){return this.displayLongTail_;},set displayLongTail(newValue){if(this.displayLongTail===newValue)return;this.displayLongTail_=newValue;this.scheduleRebuild_();},get dimension(){return this.dimension_;},set dimension(dimension){this.dimension_=dimension;this.scheduleRebuild_();},get nodes(){return this.nodes_;},set nodes(nodes){this.nodes_=nodes;this.scheduleRebuild_();},get nodes(){return this.nodes_||[];},get dimensionLabel_(){if(this.dimension_===undefined)return'(undefined)';return this.dimension_.label;},get tabLabel(){let nodeCount=0;if(this.nodes_){nodeCount=this.nodes_.length;}
 return this.dimensionLabel_+' ('+nodeCount+')';},get tabIcon(){if(this.dimension_===undefined||this.dimension_===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return undefined;}
-return{text:this.dimension_.symbol,style:'color: '+tr.b.ColorScheme.getColorForReservedNameAsString(this.dimension_.color)+';'};},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},focus:function(){this.$.table.focus();},blur:function(){this.$.table.blur();},get isFocused(){return this.$.table.isFocused;},onRebuild_:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.emptyValue='Cannot break down by '+
-this.dimensionLabel_.toLowerCase()+' any further.';var[state,rows]=this.getRows_();var total=this.nodes.length;var displayed=rows.length;var hidden=total-displayed;this.updateInfoBar_(state,[total,displayed,hidden]);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);if(this.$.table.sortColumnIndex===undefined){this.$.table.sortColumnIndex=0;this.$.table.sortDescending=false;}
-this.$.table.rebuild();},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.HeapDetailsTitleColumn(this.dimensionLabel_);titleColumn.width='400px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});if(numericColumns.length===0){numericColumns.push(new EmptyFillerColumn());}
-tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);var columns=[titleColumn].concat(numericColumns);return columns;},getRows_(){var rows=this.nodes;if(rows.length<=RESONABLE_NUMBER_OF_ROWS){return[TabUiState.NO_LONG_TAIL,rows];}else if(this.displayLongTail){return[TabUiState.SHOWING_LONG_TAIL,rows];}
-var absSize=row=>Math.max(row.cells.Size.fields[0].value);rows.sort((a,b)=>absSize(b)-absSize(a));rows=rows.slice(0,RESONABLE_NUMBER_OF_ROWS);return[TabUiState.HIDING_LONG_TAIL,rows];},updateInfoBar_(state,rowStats){if(state===TabUiState.SHOWING_LONG_TAIL){this.longTailVisibleInfoBar_(rowStats);}else if(state===TabUiState.HIDING_LONG_TAIL){this.longTailHiddenInfoBar_(rowStats);}else{this.hideInfoBar_();}},longTailVisibleInfoBar_:function(rowStats){var[total,visible,hidden]=rowStats;var couldHide=total-RESONABLE_NUMBER_OF_ROWS;this.$.info.message='Showing '+total+' rows. This may be slow.';this.$.info.removeAllButtons();var buttonText='Hide '+couldHide+' rows.';this.$.info.addButton(buttonText,()=>this.displayLongTail=false);this.$.info.visible=true;},longTailHiddenInfoBar_:function(rowStats){var[total,visible,hidden]=rowStats;this.$.info.message='Hiding the smallest '+hidden+' rows.';this.$.info.removeAllButtons();this.$.info.addButton('Show all.',()=>this.displayLongTail=true);this.$.info.visible=true;},hideInfoBar_:function(){this.$.info.visible=false;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS=String.fromCharCode(0x21B3);function HeapDetailsPathColumn(title){tr.ui.analysis.HeapDetailsTitleColumn.call(this,title);}
-HeapDetailsPathColumn.prototype={__proto__:tr.ui.analysis.HeapDetailsTitleColumn.prototype,formatTitle:function(row){var title=tr.ui.analysis.HeapDetailsTitleColumn.prototype.formatTitle.call(this,row);if(row.dimension===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return title;}
-var arrowEl=document.createElement('span');Polymer.dom(arrowEl).textContent=DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS;arrowEl.style.paddingRight='2px';arrowEl.style.fontWeight='bold';arrowEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString('heap_dump_child_node_arrow');var rowEl=document.createElement('span');Polymer.dom(rowEl).appendChild(arrowEl);Polymer.dom(rowEl).appendChild(tr.ui.b.asHTMLOrTextNode(title));return rowEl;}};Polymer({is:'tr-ui-a-memory-dump-heap-details-path-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created:function(){this.selectedNode_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.addEventListener('selection-changed',function(event){this.selectedNode_=this.$.table.selectedTableRow;this.didSelectedNodeChange_();}.bind(this));},didSelectedNodeChange_:function(){this.dispatchEvent(new tr.b.Event('selected-node-changed'));},get selectedNode(){return this.selectedNode_;},set selectedNode(node){this.selectedNode_=node;this.didSelectedNodeChange_();this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},onRebuild_:function(){if(this.selectedNode_===undefined){this.$.table.clear();return;}
+return{text:this.dimension_.symbol,style:'color: '+tr.b.ColorScheme.getColorForReservedNameAsString(this.dimension_.color)+';'};},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},focus(){this.$.table.focus();},blur(){this.$.table.blur();},get isFocused(){return this.$.table.isFocused;},onRebuild_(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.emptyValue='Cannot break down by '+
+this.dimensionLabel_.toLowerCase()+' any further.';const[state,rows]=this.getRows_();const total=this.nodes.length;const displayed=rows.length;const hidden=total-displayed;this.updateInfoBar_(state,[total,displayed,hidden]);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);if(this.$.table.sortColumnIndex===undefined){this.$.table.sortColumnIndex=0;this.$.table.sortDescending=false;}
+this.$.table.rebuild();},createColumns_(rows){const titleColumn=new tr.ui.analysis.HeapDetailsTitleColumn(this.dimensionLabel_);titleColumn.width='400px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});if(numericColumns.length===0){numericColumns.push(new EmptyFillerColumn());}
+tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);const columns=[titleColumn].concat(numericColumns);return columns;},getRows_(){let rows=this.nodes;if(rows.length<=RESONABLE_NUMBER_OF_ROWS){return[TabUiState.NO_LONG_TAIL,rows];}else if(this.displayLongTail){return[TabUiState.SHOWING_LONG_TAIL,rows];}
+const absSize=row=>Math.max(row.cells.Size.fields[0].value);rows.sort((a,b)=>absSize(b)-absSize(a));rows=rows.slice(0,RESONABLE_NUMBER_OF_ROWS);return[TabUiState.HIDING_LONG_TAIL,rows];},updateInfoBar_(state,rowStats){if(state===TabUiState.SHOWING_LONG_TAIL){this.longTailVisibleInfoBar_(rowStats);}else if(state===TabUiState.HIDING_LONG_TAIL){this.longTailHiddenInfoBar_(rowStats);}else{this.hideInfoBar_();}},longTailVisibleInfoBar_(rowStats){const[total,visible,hidden]=rowStats;const couldHide=total-RESONABLE_NUMBER_OF_ROWS;this.$.info.message='Showing '+total+' rows. This may be slow.';this.$.info.removeAllButtons();const buttonText='Hide '+couldHide+' rows.';this.$.info.addButton(buttonText,()=>this.displayLongTail=false);this.$.info.visible=true;},longTailHiddenInfoBar_(rowStats){const[total,visible,hidden]=rowStats;this.$.info.message='Hiding the smallest '+hidden+' rows.';this.$.info.removeAllButtons();this.$.info.addButton('Show all.',()=>this.displayLongTail=true);this.$.info.visible=true;},hideInfoBar_(){this.$.info.visible=false;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS=String.fromCharCode(0x21B3);function HeapDetailsPathColumn(title){tr.ui.analysis.HeapDetailsTitleColumn.call(this,title);}
+HeapDetailsPathColumn.prototype={__proto__:tr.ui.analysis.HeapDetailsTitleColumn.prototype,formatTitle(row){const title=tr.ui.analysis.HeapDetailsTitleColumn.prototype.formatTitle.call(this,row);if(row.dimension===tr.ui.analysis.HeapDetailsRowDimension.ROOT){return title;}
+const arrowEl=document.createElement('span');Polymer.dom(arrowEl).textContent=DOWNWARDS_ARROW_WITH_TIP_RIGHTWARDS;arrowEl.style.paddingRight='2px';arrowEl.style.fontWeight='bold';arrowEl.style.color=tr.b.ColorScheme.getColorForReservedNameAsString('heap_dump_child_node_arrow');const rowEl=document.createElement('span');Polymer.dom(rowEl).appendChild(arrowEl);Polymer.dom(rowEl).appendChild(tr.ui.b.asHTMLOrTextNode(title));return rowEl;}};Polymer({is:'tr-ui-a-memory-dump-heap-details-path-view',behaviors:[tr.ui.analysis.RebuildableBehavior],created(){this.selectedNode_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.addEventListener('selection-changed',function(event){this.selectedNode_=this.$.table.selectedTableRow;this.didSelectedNodeChange_();}.bind(this));},didSelectedNodeChange_(){this.dispatchEvent(new tr.b.Event('selected-node-changed'));},get selectedNode(){return this.selectedNode_;},set selectedNode(node){this.selectedNode_=node;this.didSelectedNodeChange_();this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},onRebuild_(){if(this.selectedNode_===undefined){this.$.table.clear();return;}
 if(this.$.table.tableRows.includes(this.selectedNode_)){this.$.table.selectedTableRow=this.selectedNode_;return;}
-this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.userCanModifySortOrder=false;var rows=this.createRows_(this.selectedNode_);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);this.$.table.selectedTableRow=rows[rows.length-1];},createRows_:function(node){var rows=[];while(node){rows.push(node);node=node.parentNode;}
-rows.reverse();return rows;},createColumns_:function(rows){var titleColumn=new HeapDetailsPathColumn('Current path');titleColumn.width='200px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);return[titleColumn].concat(numericColumns);}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var StackedPaneImpl={set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended:function(){this.rebuild();}};var StackedPane=[tr.ui.analysis.RebuildableBehavior,StackedPaneImpl];return{StackedPane,};});Polymer({is:'tr-ui-a-stacked-pane',behaviors:[tr.ui.analysis.StackedPane]});'use strict';tr.exportTo('tr.ui.analysis',function(){var Scalar=tr.b.Scalar;var sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;var count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;var MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;var TotalState=tr.b.MultiDimensionalViewNode.TotalState;function HeapDumpTreeNode(stackFrameNodes,dimension,title,heavyView,parentNode){this.dimension=dimension;this.title=title;this.parentNode=parentNode;this.heavyView_=heavyView;this.stackFrameNodes_=stackFrameNodes;this.lazyCells_=undefined;this.lazyChildNodes_=undefined;}
+this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;this.$.table.userCanModifySortOrder=false;const rows=this.createRows_(this.selectedNode_);this.$.table.tableRows=rows;this.$.table.tableColumns=this.createColumns_(rows);this.$.table.selectedTableRow=rows[rows.length-1];},createRows_(node){const rows=[];while(node){rows.push(node);node=node.parentNode;}
+rows.reverse();return rows;},createColumns_(rows){const titleColumn=new HeapDetailsPathColumn('Current path');titleColumn.width='200px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'cells',aggregationMode:this.aggregationMode_,rules:tr.ui.analysis.HEAP_DETAILS_COLUMN_RULES,shouldSetContextGroup:true});tr.ui.analysis.MemoryColumn.spaceEqually(numericColumns);return[titleColumn].concat(numericColumns);}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const StackedPaneImpl={set childPaneBuilder(childPaneBuilder){this.childPaneBuilder_=childPaneBuilder;this.dispatchEvent(new tr.b.Event('request-child-pane-change'));},get childPaneBuilder(){return this.childPaneBuilder_;},appended(){this.rebuild();}};const StackedPane=[tr.ui.analysis.RebuildableBehavior,StackedPaneImpl];return{StackedPane,};});Polymer({is:'tr-ui-a-stacked-pane',behaviors:[tr.ui.analysis.StackedPane]});'use strict';tr.exportTo('tr.ui.analysis',function(){const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const count_smallerIsBetter=tr.b.Unit.byName.count_smallerIsBetter;const MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;const TotalState=tr.b.MultiDimensionalViewNode.TotalState;function HeapDumpTreeNode(stackFrameNodes,dimension,title,heavyView,parentNode){this.dimension=dimension;this.title=title;this.parentNode=parentNode;this.heavyView_=heavyView;this.stackFrameNodes_=stackFrameNodes;this.lazyCells_=undefined;this.lazyChildNodes_=undefined;}
 HeapDumpTreeNode.prototype={get minDisplayedTotalState_(){if(this.heavyView_){return TotalState.LOWER_BOUND;}
 return TotalState.EXACT;},get childNodes(){if(!this.lazyChildNodes_){this.lazyChildNodes_=new Map();this.addDimensionChildNodes_(tr.ui.analysis.HeapDetailsRowDimension.STACK_FRAME,0);this.addDimensionChildNodes_(tr.ui.analysis.HeapDetailsRowDimension.OBJECT_TYPE,1);this.releaseStackFrameNodesIfPossible_();}
 return this.lazyChildNodes_;},get cells(){if(!this.lazyCells_){this.addCells_();this.releaseStackFrameNodesIfPossible_();}
-return this.lazyCells_;},releaseStackFrameNodesIfPossible_:function(){if(this.lazyCells_&&this.lazyChildNodes_){this.stackFrameNodes_=undefined;}},addDimensionChildNodes_:function(dimension,dimensionIndex){var dimensionChildTitleToStackFrameNodes=tr.b.invertArrayOfDicts(this.stackFrameNodes_,node=>this.convertStackFrameNodeDimensionToChildDict_(node,dimensionIndex));var dimensionChildNodes=[];for(var[childTitle,childStackFrameNodes]of
+return this.lazyCells_;},releaseStackFrameNodesIfPossible_(){if(this.lazyCells_&&this.lazyChildNodes_){this.stackFrameNodes_=undefined;}},addDimensionChildNodes_(dimension,dimensionIndex){const dimensionChildTitleToStackFrameNodes=tr.b.invertArrayOfDicts(this.stackFrameNodes_,node=>this.convertStackFrameNodeDimensionToChildDict_(node,dimensionIndex));const dimensionChildNodes=[];for(const[childTitle,childStackFrameNodes]of
 Object.entries(dimensionChildTitleToStackFrameNodes)){dimensionChildNodes.push(new HeapDumpTreeNode(childStackFrameNodes,dimension,childTitle,this.heavyView_,this));}
-this.lazyChildNodes_.set(dimension,dimensionChildNodes);},convertStackFrameNodeDimensionToChildDict_:function(stackFrameNode,dimensionIndex){var childDict={};var displayedChildrenTotalSize=0;var displayedChildrenTotalCount=0;var hasDisplayedChildren=false;var allDisplayedChildrenHaveDisplayedCounts=true;for(var child of stackFrameNode.children[dimensionIndex].values()){if(child.values[0].totalState<this.minDisplayedTotalState_){continue;}
+this.lazyChildNodes_.set(dimension,dimensionChildNodes);},convertStackFrameNodeDimensionToChildDict_(stackFrameNode,dimensionIndex){const childDict={};let displayedChildrenTotalSize=0;let displayedChildrenTotalCount=0;let hasDisplayedChildren=false;let allDisplayedChildrenHaveDisplayedCounts=true;for(const child of stackFrameNode.children[dimensionIndex].values()){if(child.values[0].totalState<this.minDisplayedTotalState_){continue;}
 if(child.values[1].totalState<this.minDisplayedTotalState_){allDisplayedChildrenHaveDisplayedCounts=false;}
 childDict[child.title[dimensionIndex]]=child;displayedChildrenTotalSize+=child.values[0].total;displayedChildrenTotalCount+=child.values[1].total;hasDisplayedChildren=true;}
-var nodeTotalSize=stackFrameNode.values[0].total;var nodeTotalCount=stackFrameNode.values[1].total;var hasUnclassifiedSizeOrCount=displayedChildrenTotalSize<nodeTotalSize||displayedChildrenTotalCount<nodeTotalCount;if(!this.heavyView_&&hasUnclassifiedSizeOrCount&&hasDisplayedChildren){var otherTitle=stackFrameNode.title.slice();otherTitle[dimensionIndex]='<other>';var otherNode=new tr.b.MultiDimensionalViewNode(otherTitle,2);childDict[otherTitle[dimensionIndex]]=otherNode;otherNode.values[0].total=nodeTotalSize-displayedChildrenTotalSize;otherNode.values[0].totalState=this.minDisplayedTotalState_;otherNode.values[1].total=nodeTotalCount-displayedChildrenTotalCount;otherNode.values[1].totalState=allDisplayedChildrenHaveDisplayedCounts?this.minDisplayedTotalState_:TotalState.NOT_PROVIDED;}
-return childDict;},addCells_:function(){this.lazyCells_=tr.ui.analysis.createCells(this.stackFrameNodes_,function(stackFrameNode){var size=stackFrameNode.values[0].total;var numerics={'Size':new Scalar(sizeInBytes_smallerIsBetter,size)};var countValue=stackFrameNode.values[1];if(countValue.totalState>=this.minDisplayedTotalState_){var count=countValue.total;numerics['Count']=new Scalar(count_smallerIsBetter,count);}
-return numerics;},this);}};Polymer({is:'tr-ui-a-memory-dump-heap-details-pane',behaviors:[tr.ui.analysis.StackedPane],created:function(){this.heapDumps_=undefined;this.viewMode_=undefined;this.aggregationMode_=undefined;this.cachedBuilders_=new Map();},ready:function(){this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';Polymer.dom(this.$.view_mode_container).appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]));this.$.drag_handle.target=this.$.path_view;this.$.drag_handle.horizontal=false;this.$.path_view.addEventListener('selected-node-changed',(function(e){this.$.breakdown_view.displayedNode=this.$.path_view.selectedNode;}).bind(this));this.$.breakdown_view.addEventListener('enter-node',(function(e){this.$.path_view.selectedNode=e.node;}).bind(this));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.$.path_view.aggregationMode=aggregationMode;this.$.breakdown_view.aggregationMode=aggregationMode;},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuild_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},onRebuild_:function(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.split_view.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.hidden=true;this.$.path_view.selectedNode=undefined;return;}
-this.$.info_text.style.display='none';this.$.split_view.style.display='flex';this.$.view_mode_container.style.display='block';this.$.info_bar.hidden=!this.heavyView;this.$.path_view.selectedNode=this.createHeapTree_();this.$.path_view.rebuild();this.$.breakdown_view.rebuild();},createHeapTree_:function(){var definedHeapDump=tr.b.findFirstInArray(this.heapDumps_);if(definedHeapDump===undefined)return undefined;var rootRowTitle=definedHeapDump.allocatorName;var stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);return new HeapDumpTreeNode(stackFrameTrees,tr.ui.analysis.HeapDetailsRowDimension.ROOT,rootRowTitle,this.heavyView);},createStackFrameTrees_:function(heapDumps){var builders=heapDumps.map(heapDump=>this.createBuilder_(heapDump));var views=builders.map(builder=>{if(builder===undefined)return undefined;return builder.buildView(this.viewMode);});return views;},createBuilder_:function(heapDump){if(heapDump===undefined)return undefined;if(this.cachedBuilders_.has(heapDump)){return this.cachedBuilders_.get(heapDump);}
-var dimensions=2;var valueCount=2;var builder=new MultiDimensionalViewBuilder(dimensions,valueCount);for(var entry of heapDump.entries){var leafStackFrame=entry.leafStackFrame;var stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();var objectTypeName=entry.objectTypeName;var objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];builder.addPath([stackTracePath,objectTypeNamePath],[entry.size,entry.count],MultiDimensionalViewBuilder.ValueKind.TOTAL);}
-this.cachedBuilders_.set(heapDump,builder);return builder;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var URL_TO_SIZE_VS_EFFECTIVE_SIZE='https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/README.md#effective_size-vs_size';var SUBALLOCATION_CONTEXT=true;var MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;var PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;var PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;var LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);var RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);var EN_DASH=String.fromCharCode(0x2013);var CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
-AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(!row.suballocation){return row.title;}
-return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){var entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
+const nodeTotalSize=stackFrameNode.values[0].total;const nodeTotalCount=stackFrameNode.values[1].total;const hasUnclassifiedSizeOrCount=displayedChildrenTotalSize<nodeTotalSize||displayedChildrenTotalCount<nodeTotalCount;if(!this.heavyView_&&hasUnclassifiedSizeOrCount&&hasDisplayedChildren){const otherTitle=stackFrameNode.title.slice();otherTitle[dimensionIndex]='<other>';const otherNode=new tr.b.MultiDimensionalViewNode(otherTitle,2);childDict[otherTitle[dimensionIndex]]=otherNode;otherNode.values[0].total=nodeTotalSize-displayedChildrenTotalSize;otherNode.values[0].totalState=this.minDisplayedTotalState_;otherNode.values[1].total=nodeTotalCount-displayedChildrenTotalCount;otherNode.values[1].totalState=allDisplayedChildrenHaveDisplayedCounts?this.minDisplayedTotalState_:TotalState.NOT_PROVIDED;}
+return childDict;},addCells_(){this.lazyCells_=tr.ui.analysis.createCells(this.stackFrameNodes_,function(stackFrameNode){const size=stackFrameNode.values[0].total;const numerics={'Size':new Scalar(sizeInBytes_smallerIsBetter,size)};const countValue=stackFrameNode.values[1];if(countValue.totalState>=this.minDisplayedTotalState_){const count=countValue.total;numerics.Count=new Scalar(count_smallerIsBetter,count);}
+return numerics;},this);}};Polymer({is:'tr-ui-a-memory-dump-heap-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.heapDumps_=undefined;this.viewMode_=undefined;this.aggregationMode_=undefined;this.cachedBuilders_=new Map();},ready(){this.$.info_bar.message='Note: Values displayed in the heavy view '+'are lower bounds (except for the root).';Polymer.dom(this.$.view_mode_container).appendChild(tr.ui.b.createSelector(this,'viewMode','memoryDumpHeapDetailsPane.viewMode',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]));this.$.drag_handle.target=this.$.path_view;this.$.drag_handle.horizontal=false;this.$.path_view.addEventListener('selected-node-changed',(function(e){this.$.breakdown_view.displayedNode=this.$.path_view.selectedNode;}).bind(this));this.$.breakdown_view.addEventListener('enter-node',(function(e){this.$.path_view.selectedNode=e.node;}).bind(this));},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},get heapDumps(){return this.heapDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.$.path_view.aggregationMode=aggregationMode;this.$.breakdown_view.aggregationMode=aggregationMode;},get aggregationMode(){return this.aggregationMode_;},set viewMode(viewMode){this.viewMode_=viewMode;this.scheduleRebuild_();},get viewMode(){return this.viewMode_;},get heavyView(){switch(this.viewMode){case MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW:case MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW:return true;default:return false;}},onRebuild_(){if(this.heapDumps_===undefined||this.heapDumps_.length===0){this.$.info_text.style.display='block';this.$.split_view.style.display='none';this.$.view_mode_container.style.display='none';this.$.info_bar.hidden=true;this.$.path_view.selectedNode=undefined;return;}
+this.$.info_text.style.display='none';this.$.split_view.style.display='flex';this.$.view_mode_container.style.display='block';this.$.info_bar.hidden=!this.heavyView;this.$.path_view.selectedNode=this.createHeapTree_();this.$.path_view.rebuild();this.$.breakdown_view.rebuild();},createHeapTree_(){const definedHeapDump=tr.b.findFirstInArray(this.heapDumps_);if(definedHeapDump===undefined)return undefined;const rootRowTitle=definedHeapDump.allocatorName;const stackFrameTrees=this.createStackFrameTrees_(this.heapDumps_);return new HeapDumpTreeNode(stackFrameTrees,tr.ui.analysis.HeapDetailsRowDimension.ROOT,rootRowTitle,this.heavyView);},createStackFrameTrees_(heapDumps){const builders=heapDumps.map(heapDump=>this.createBuilder_(heapDump));const views=builders.map(builder=>{if(builder===undefined)return undefined;return builder.buildView(this.viewMode);});return views;},createBuilder_(heapDump){if(heapDump===undefined)return undefined;if(this.cachedBuilders_.has(heapDump)){return this.cachedBuilders_.get(heapDump);}
+const dimensions=2;const valueCount=2;const builder=new MultiDimensionalViewBuilder(dimensions,valueCount);for(const entry of heapDump.entries){const leafStackFrame=entry.leafStackFrame;const stackTracePath=leafStackFrame===undefined?[]:leafStackFrame.getUserFriendlyStackTrace().reverse();const objectTypeName=entry.objectTypeName;const objectTypeNamePath=objectTypeName===undefined?[]:[objectTypeName];const valueKind=entry.valuesAreTotals?MultiDimensionalViewBuilder.ValueKind.TOTAL:MultiDimensionalViewBuilder.ValueKind.SELF;builder.addPath([stackTracePath,objectTypeNamePath],[entry.size,entry.count],valueKind);}
+builder.complete=heapDump.isComplete;this.cachedBuilders_.set(heapDump,builder);return builder;},});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const URL_TO_SIZE_VS_EFFECTIVE_SIZE='https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/README.md#effective_size-vs_size';const SUBALLOCATION_CONTEXT=true;const MemoryAllocatorDumpInfoType=tr.model.MemoryAllocatorDumpInfoType;const PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN;const PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER=MemoryAllocatorDumpInfoType.PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER;const LEFTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FD);const RIGHTWARDS_OPEN_HEADED_ARROW=String.fromCharCode(0x21FE);const EN_DASH=String.fromCharCode(0x2013);const CIRCLED_LATIN_SMALL_LETTER_I=String.fromCharCode(0x24D8);function AllocatorDumpNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Component');}
+AllocatorDumpNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(!row.suballocation){return row.title;}
+return tr.ui.b.createSpan({textContent:row.title,italic:true,tooltip:row.fullNames===undefined?undefined:row.fullNames.join(', ')});}};function getAndUpdateEntry(map,name,createdCallback){let entry=map.get(name);if(entry===undefined){entry={count:0};createdCallback(entry);map.set(name,entry);}
 entry.count++;return entry;}
 function SizeInfoMessageBuilder(){this.parts_=[];this.indent_=0;}
-SizeInfoMessageBuilder.prototype={append:function(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap:function(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText){this.append(emptyText);}}else if(map.size===1){this.parts_.push(' ');var key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix){this.parts_.push('s');}
-this.parts_.push(':');this.indent_++;for(var key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
-this.indent_--;}},appendImportanceRange:function(range){this.append(' (importance: ');if(range.min===range.max){this.append(range.min);}else{this.append(range.min,EN_DASH,range.max);}
-this.append(')');},appendSizeIfDefined:function(size){if(size!==undefined){this.append(' (',tr.b.Unit.byName.sizeInBytes.format(size),')');}},appendSomeTimestampsQuantifier:function(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build:function(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory used by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;var ownerNameToEntry=new Map();var ownedNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
-dump.ownedBy.forEach(function(ownerLink){var ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);var ownedLink=dump.owns;if(ownedLink!==undefined){var ownedDump=ownedLink.target;var ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);var sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){var sharerDump=sharerLink.source;if(sharerDump===dump)return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
-if(ownerNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+SizeInfoMessageBuilder.prototype={append(){this.parts_.push.apply(this.parts_,Array.prototype.slice.apply(arguments));},appendMap(map,hasPluralSuffix,emptyText,itemCallback,opt_this){opt_this=opt_this||this;if(map.size===0){if(emptyText){this.append(emptyText);}}else if(map.size===1){this.parts_.push(' ');const key=map.keys().next().value;itemCallback.call(opt_this,key,map.get(key));}else{if(hasPluralSuffix){this.parts_.push('s');}
+this.parts_.push(':');this.indent_++;for(const key of map.keys()){this.parts_.push('\n',' '.repeat(3*(this.indent_-1)),' - ');itemCallback.call(opt_this,key,map.get(key));}
+this.indent_--;}},appendImportanceRange(range){this.append(' (importance: ');if(range.min===range.max){this.append(range.min);}else{this.append(range.min,EN_DASH,range.max);}
+this.append(')');},appendSizeIfDefined(size){if(size!==undefined){this.append(' (',tr.b.Unit.byName.sizeInBytes.format(size),')');}},appendSomeTimestampsQuantifier(){this.append(' ',tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER);},build(){return this.parts_.join('');}};function EffectiveSizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+EffectiveSizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory used by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;const ownerNameToEntry=new Map();const ownedNameToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+dump.ownedBy.forEach(function(ownerLink){const ownerDump=ownerLink.source;this.getAndUpdateOwnershipEntry_(ownerNameToEntry,ownerDump,ownerLink);},this);const ownedLink=dump.owns;if(ownedLink!==undefined){const ownedDump=ownedLink.target;const ownedEntry=this.getAndUpdateOwnershipEntry_(ownedNameToEntry,ownedDump,ownedLink,true);const sharerNameToEntry=ownedEntry.sharerNameToEntry;ownedDump.ownedBy.forEach(function(sharerLink){const sharerDump=sharerLink.source;if(sharerDump===dump)return;this.getAndUpdateOwnershipEntry_(sharerNameToEntry,sharerDump,sharerLink);},this);}}
+if(ownerNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shared by');messageBuilder.appendMap(ownerNameToEntry,false,undefined,function(ownerName,ownerEntry){messageBuilder.append(ownerName);if(ownerEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
 messageBuilder.appendImportanceRange(ownerEntry.importanceRange);},this);infos.push({message:messageBuilder.build(),icon:LEFTWARDS_OPEN_HEADED_ARROW,color:'green'});}
-if(ownedNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);var ownedCount=ownedEntry.count;if(ownedCount<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
+if(ownedNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('shares');messageBuilder.appendMap(ownedNameToEntry,false,undefined,function(ownedName,ownedEntry){messageBuilder.append(ownedName);const ownedCount=ownedEntry.count;if(ownedCount<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
 messageBuilder.appendImportanceRange(ownedEntry.importanceRange);messageBuilder.append(' with');messageBuilder.appendMap(ownedEntry.sharerNameToEntry,false,' no other dumps',function(sharerName,sharerEntry){messageBuilder.append(sharerName);if(sharerEntry.count<ownedCount){messageBuilder.appendSomeTimestampsQuantifier();}
-messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_:function(map,dump,link,opt_withSharerNameToEntry){var entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.math.Range();if(opt_withSharerNameToEntry){newEntry.sharerNameToEntry=new Map();}});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-SizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory requested by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos:function(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_:function(numerics,memoryAllocatorDumps,infos){var siblingNameToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
-var ownedBySiblingSizes=dump.ownedBySiblingSizes;for(var siblingDump of ownedBySiblingSizes.keys()){var siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1){newEntry.size=ownedBySiblingSizes.get(siblingDump);}});}}
-if(siblingNameToEntry.size>0){var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_:function(numerics,memoryAllocatorDumps,infos){var infoTypeToEntry=new Map();for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;var dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+messageBuilder.appendImportanceRange(sharerEntry.importanceRange);},this);},this);infos.push({message:messageBuilder.build(),icon:RIGHTWARDS_OPEN_HEADED_ARROW,color:'green'});}},getAndUpdateOwnershipEntry_(map,dump,link,opt_withSharerNameToEntry){const entry=getAndUpdateEntry(map,dump.quantifiedName,function(newEntry){newEntry.importanceRange=new tr.b.math.Range();if(opt_withSharerNameToEntry){newEntry.sharerNameToEntry=new Map();}});entry.importanceRange.addValue(link.importance||0);return entry;}};function SizeColumn(name,cellPath,aggregationMode){tr.ui.analysis.DetailsNumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+SizeColumn.prototype={__proto__:tr.ui.analysis.DetailsNumericMemoryColumn.prototype,get title(){return tr.ui.b.createLink({textContent:this.name,tooltip:'Memory requested by this component',href:URL_TO_SIZE_VS_EFFECTIVE_SIZE});},addInfos(numerics,memoryAllocatorDumps,infos){if(memoryAllocatorDumps===undefined)return;this.addOverlapInfo_(numerics,memoryAllocatorDumps,infos);this.addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos);},addOverlapInfo_(numerics,memoryAllocatorDumps,infos){const siblingNameToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
+const ownedBySiblingSizes=dump.ownedBySiblingSizes;for(const siblingDump of ownedBySiblingSizes.keys()){const siblingName=siblingDump.name;getAndUpdateEntry(siblingNameToEntry,siblingName,function(newEntry){if(numerics.length===1){newEntry.size=ownedBySiblingSizes.get(siblingDump);}});}}
+if(siblingNameToEntry.size>0){const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('overlaps with its sibling');messageBuilder.appendMap(siblingNameToEntry,true,undefined,function(siblingName,siblingEntry){messageBuilder.append('\'',siblingName,'\'');messageBuilder.appendSizeIfDefined(siblingEntry.size);if(siblingEntry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}},this);infos.push({message:messageBuilder.build(),icon:CIRCLED_LATIN_SMALL_LETTER_I,color:'blue'});}},addProvidedSizeWarningInfos_(numerics,memoryAllocatorDumps,infos){const infoTypeToEntry=new Map();for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;const dump=memoryAllocatorDumps[i];if(dump===SUBALLOCATION_CONTEXT){return;}
 dump.infos.forEach(function(dumpInfo){getAndUpdateEntry(infoTypeToEntry,dumpInfo.type,function(newEntry){if(numerics.length===1){newEntry.providedSize=dumpInfo.providedSize;newEntry.dependencySize=dumpInfo.dependencySize;}});});}
-for(var infoType of infoTypeToEntry.keys()){var entry=infoTypeToEntry.get(infoType);var messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);var dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
+for(const infoType of infoTypeToEntry.keys()){const entry=infoTypeToEntry.get(infoType);const messageBuilder=new SizeInfoMessageBuilder();messageBuilder.append('provided size');messageBuilder.appendSizeIfDefined(entry.providedSize);let dependencyName;switch(infoType){case PROVIDED_SIZE_LESS_THAN_AGGREGATED_CHILDREN:dependencyName='the aggregated size of the children';break;case PROVIDED_SIZE_LESS_THAN_LARGEST_OWNER:dependencyName='the size of the largest owner';break;default:dependencyName='an unknown dependency';break;}
 messageBuilder.append(' was less than ',dependencyName);messageBuilder.appendSizeIfDefined(entry.dependencySize);if(entry.count<numerics.length){messageBuilder.appendSomeTimestampsQuantifier();}
-infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};var NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];var DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer({is:'tr-ui-a-memory-dump-allocator-details-pane',behaviors:[tr.ui.analysis.StackedPane],created:function(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuild_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_:function(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){var pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_:function(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_:function(dumps){var definedDump=tr.b.findFirstInArray(dumps);var title=definedDump.name;var fullName=definedDump.fullName;var numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});var diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});var suballocatedBy=undefined;if(title.startsWith('__')){for(var i=0;i<dumps.length;i++){var dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
-var ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
+infos.push(tr.ui.analysis.createWarningInfo(messageBuilder.build()));}}};const NUMERIC_COLUMN_RULES=[{condition:tr.model.MemoryAllocatorDump.EFFECTIVE_SIZE_NUMERIC_NAME,importance:10,columnConstructor:EffectiveSizeColumn},{condition:tr.model.MemoryAllocatorDump.SIZE_NUMERIC_NAME,importance:9,columnConstructor:SizeColumn},{condition:'page_size',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:/size/,importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];const DIAGNOSTIC_COLUMN_RULES=[{importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];Polymer({is:'tr-ui-a-memory-dump-allocator-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.memoryAllocatorDumps_=undefined;this.heapDumps_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set memoryAllocatorDumps(memoryAllocatorDumps){this.memoryAllocatorDumps_=memoryAllocatorDumps;this.scheduleRebuild_();},get memoryAllocatorDumps(){return this.memoryAllocatorDumps_;},set heapDumps(heapDumps){this.heapDumps_=heapDumps;this.scheduleRebuild_();},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){if(this.memoryAllocatorDumps_===undefined||this.memoryAllocatorDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();this.childPaneBuilder=undefined;return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_();const columns=this.createColumns_(rows);rows.forEach(function(rootRow){tr.ui.analysis.aggregateTableRowCellsRecursively(rootRow,columns,function(contexts){return contexts!==undefined&&contexts.some(function(context){return context===SUBALLOCATION_CONTEXT;});});});this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);if(this.heapDumps_===undefined){this.childPaneBuilder=undefined;}else{this.childPaneBuilder=function(){const pane=document.createElement('tr-ui-a-memory-dump-heap-details-pane');pane.heapDumps=this.heapDumps_;pane.aggregationMode=this.aggregationMode_;return pane;}.bind(this);}},createRows_(){return[this.createAllocatorRowRecursively_(this.memoryAllocatorDumps_)];},createAllocatorRowRecursively_(dumps){const definedDump=tr.b.findFirstInArray(dumps);const title=definedDump.name;const fullName=definedDump.fullName;const numericCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.numerics;});const diagnosticCells=tr.ui.analysis.createCells(dumps,function(dump){return dump.diagnostics;});let suballocatedBy=undefined;if(title.startsWith('__')){for(let i=0;i<dumps.length;i++){const dump=dumps[i];if(dump===undefined||dump.ownedBy.length===0){continue;}
+const ownerDump=dump.ownedBy[0].source;if(dump.ownedBy.length>1||dump.children.length>0||ownerDump.containerMemoryDump!==dump.containerMemoryDump){suballocatedBy=undefined;break;}
 if(suballocatedBy===undefined){suballocatedBy=ownerDump.fullName;}else if(suballocatedBy!==ownerDump.fullName){suballocatedBy=undefined;break;}}}
-var row={title:title,fullNames:[fullName],contexts:dumps,numericCells:numericCells,diagnosticCells:diagnosticCells,suballocatedBy:suballocatedBy};var childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});var subRows=[];var suballocationClassificationRootNode=undefined;for(var childDumps of Object.values(childDumpNameToDumps)){var childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}}
-if(suballocationClassificationRootNode!==undefined){var suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
+const row={title,fullNames:[fullName],contexts:dumps,numericCells,diagnosticCells,suballocatedBy};const childDumpNameToDumps=tr.b.invertArrayOfDicts(dumps,function(dump){return tr.b.arrayToDict(dump.children,function(child){return child.name;});});const subRows=[];let suballocationClassificationRootNode=undefined;for(const childDumps of Object.values(childDumpNameToDumps)){const childRow=this.createAllocatorRowRecursively_(childDumps);if(childRow.suballocatedBy===undefined){subRows.push(childRow);}else{suballocationClassificationRootNode=this.classifySuballocationRow_(childRow,suballocationClassificationRootNode);}}
+if(suballocationClassificationRootNode!==undefined){const suballocationRow=this.createSuballocationRowRecursively_('suballocations',suballocationClassificationRootNode);subRows.push(suballocationRow);}
 if(subRows.length>0){row.subRows=subRows;}
-return row;},classifySuballocationRow_:function(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
-var suballocationLevels=suballocationRow.suballocatedBy.split('/');var currentNode=rootNode;for(var i=0;i<suballocationLevels.length;i++){var suballocationLevel=suballocationLevels[i];var nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
-var currentNode=nextNode;}
-var existingRow=currentNode.row;if(existingRow!==undefined){for(var i=0;i<suballocationRow.contexts.length;i++){var newContext=suballocationRow.contexts[i];if(newContext===undefined)continue;if(existingRow.contexts[i]!==undefined){throw new Error('Multiple suballocations with the same owner name');}
-existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){var suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)return;for(var[cellName,cell]of Object.entries(suballocationCells)){if(cell===undefined)continue;var fields=cell.fields;if(fields===undefined)continue;var field=fields[i];if(field===undefined)continue;var existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
-var existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
+return row;},classifySuballocationRow_(suballocationRow,rootNode){if(rootNode===undefined){rootNode={children:{},row:undefined};}
+const suballocationLevels=suballocationRow.suballocatedBy.split('/');let currentNode=rootNode;for(let i=0;i<suballocationLevels.length;i++){const suballocationLevel=suballocationLevels[i];let nextNode=currentNode.children[suballocationLevel];if(nextNode===undefined){currentNode.children[suballocationLevel]=nextNode={children:{},row:undefined};}
+currentNode=nextNode;}
+const existingRow=currentNode.row;if(existingRow!==undefined){for(let i=0;i<suballocationRow.contexts.length;i++){const newContext=suballocationRow.contexts[i];if(newContext===undefined)continue;if(existingRow.contexts[i]!==undefined){throw new Error('Multiple suballocations with the same owner name');}
+existingRow.contexts[i]=newContext;['numericCells','diagnosticCells'].forEach(function(cellKey){const suballocationCells=suballocationRow[cellKey];if(suballocationCells===undefined)return;for(const[cellName,cell]of Object.entries(suballocationCells)){if(cell===undefined)continue;const fields=cell.fields;if(fields===undefined)continue;const field=fields[i];if(field===undefined)continue;let existingCells=existingRow[cellKey];if(existingCells===undefined){existingCells={};existingRow[cellKey]=existingCells;}
+let existingCell=existingCells[cellName];if(existingCell===undefined){existingCell=new tr.ui.analysis.MemoryCell(new Array(fields.length));existingCells[cellName]=existingCell;}
 existingCell.fields[i]=field;}});}
 existingRow.fullNames.push.apply(existingRow.fullNames,suballocationRow.fullNames);}else{currentNode.row=suballocationRow;}
-return rootNode;},createSuballocationRowRecursively_:function(name,node){var childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined){throw new Error('Suballocation node must have a row or children');}
-var row=node.row;row.title=name;row.suballocation=true;return row;}
-var subRows=tr.b.dictionaryValues(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){var row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
-var contexts=new Array(subRows[0].contexts.length);for(var i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined){contexts[index]=SUBALLOCATION_CONTEXT;}});}
-return{title:name,suballocation:true,contexts:contexts,subRows:subRows};},createColumns_:function(rows){var titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';var numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'numericCells',aggregationMode:this.aggregationMode_,rules:NUMERIC_COLUMN_RULES});var diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'diagnosticCells',aggregationMode:this.aggregationMode_,rules:DIAGNOSTIC_COLUMN_RULES});var fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn,EffectiveSizeColumn,SizeColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){var Scalar=tr.b.Scalar;var sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;var CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];var VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];var BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)return undefined;var hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
+return rootNode;},createSuballocationRowRecursively_(name,node){const childCount=Object.keys(node.children).length;if(childCount===0){if(node.row===undefined){throw new Error('Suballocation node must have a row or children');}
+const row=node.row;row.title=name;row.suballocation=true;return row;}
+const subRows=Object.values(tr.b.mapItems(node.children,this.createSuballocationRowRecursively_,this));if(node.row!==undefined){const row=node.row;row.title='<unspecified>';row.suballocation=true;subRows.unshift(row);}
+const contexts=new Array(subRows[0].contexts.length);for(let i=0;i<subRows.length;i++){subRows[i].contexts.forEach(function(subContext,index){if(subContext!==undefined){contexts[index]=SUBALLOCATION_CONTEXT;}});}
+return{title:name,suballocation:true,contexts,subRows};},createColumns_(rows){const titleColumn=new AllocatorDumpNameColumn();titleColumn.width='200px';const numericColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'numericCells',aggregationMode:this.aggregationMode_,rules:NUMERIC_COLUMN_RULES});const diagnosticColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'diagnosticCells',aggregationMode:this.aggregationMode_,rules:DIAGNOSTIC_COLUMN_RULES});const fieldColumns=numericColumns.concat(diagnosticColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);const columns=[titleColumn].concat(fieldColumns);return columns;}});return{SUBALLOCATION_CONTEXT,AllocatorDumpNameColumn,EffectiveSizeColumn,SizeColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const CONSTANT_COLUMN_RULES=[{condition:'Start address',importance:0,columnConstructor:tr.ui.analysis.StringMemoryColumn}];const VARIABLE_COLUMN_RULES=[{condition:'Virtual size',importance:7,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Protection flags',importance:6,columnConstructor:tr.ui.analysis.StringMemoryColumn},{condition:'PSS',importance:5,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private dirty',importance:4,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Private clean',importance:3,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared dirty',importance:2,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Shared clean',importance:1,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn},{condition:'Swapped',importance:0,columnConstructor:tr.ui.analysis.DetailsNumericMemoryColumn}];const BYTE_STAT_COLUMN_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','privateCleanResident':'Private clean','sharedDirtyResident':'Shared dirty','sharedCleanResident':'Shared clean','swapped':'Swapped'};function hexString(address,is64BitAddress){if(address===undefined)return undefined;const hexPadding=is64BitAddress?'0000000000000000':'00000000';return(hexPadding+address.toString(16)).substr(-hexPadding.length);}
 function pruneEmptyRuleRows(row){if(row.subRows===undefined||row.subRows.length===0)return;if(row.subRows[0].rule===undefined){return;}
 row.subRows.forEach(pruneEmptyRuleRows);row.subRows=row.subRows.filter(function(subRow){return subRow.subRows.length>0;});}
-Polymer({is:'tr-ui-a-memory-dump-vm-regions-details-pane',behaviors:[tr.ui.analysis.StackedPane],created:function(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuild_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_:function(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_(this.vmRegions_);var columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_:function(timeToVmRegionTree){var is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow:function(timeToNode,is64BitAddress){var definedNode=tr.b.findFirstInArray(timeToNode);var childNodeIdToTimeToNode=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var children=node.children;if(children===undefined)return undefined;var childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)return;childMap[childNode.title]=childNode;});return childMap;}));var childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);var regionIdToTimeToRegion=tr.b.dictionaryValues(tr.b.invertArrayOfDicts(timeToNode,function(node){var regions=node.regions;if(regions===undefined)return undefined;return tr.b.arrayToDict(regions,function(region){return region.uniqueIdWithinProcess;});}));var regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);var subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows:subRows};},createRegionRow_:function(timeToRegion,is64BitAddress){var definedRegion=tr.b.findFirstInArray(timeToRegion);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_:function(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){var startAddress=region.startAddress;if(startAddress===undefined)return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_:function(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){var fields={};var sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new Scalar(sizeInBytes_smallerIsBetter,sizeInBytes);}
-var protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined){fields['Protection flags']=protectionFlags;}
-for(var[byteStatName,columnName]of
-Object.entries(BYTE_STAT_COLUMN_MAP)){var byteStat=region.byteStats[byteStatName];if(byteStat===undefined)continue;fields[columnName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}
-return fields;});},createColumns_:function(rows){var titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';var constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'constantCells',aggregationMode:undefined,rules:CONSTANT_COLUMN_RULES});var variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'variableCells',aggregationMode:this.aggregationMode_,rules:VARIABLE_COLUMN_RULES});var fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);var columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer({is:'tr-ui-b-color-legend',ready:function(){var blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
-var colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId:function(label,colorId){this.label_=label;Polymer.dom(this.$.label).textContent='';Polymer.dom(this.$.label).appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined){this.$.square.style.color='initial';}else{this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}}});'use strict';Polymer({is:'tr-ui-b-view-specific-brushing-state',get viewId(){return this.getAttribute('view-id');},set viewId(viewId){Polymer.dom(this).setAttribute('view-id',viewId);},get:function(){var viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
-var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set:function(state){var viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
-var brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){var MemoryColumnColorScheme=tr.b.MemoryColumnColorScheme;var Scalar=tr.b.Scalar;var sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;var PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;var RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);var RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);var GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);var UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);var TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;var result=undefined;list.forEach(function(item,index){var value=fn.call(opt_this,item,index);if(value===undefined)return;if(result===undefined){result=new Array(list.length);}
+Polymer({is:'tr-ui-a-memory-dump-vm-regions-details-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.vmRegions_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},set vmRegions(vmRegions){this.vmRegions_=vmRegions;this.scheduleRebuild_();},get vmRegions(){return this.vmRegions_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){if(this.vmRegions_===undefined||this.vmRegions_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_(this.vmRegions_);const columns=this.createColumns_(rows);this.$.table.tableRows=rows;this.$.table.tableColumns=columns;this.$.table.rebuild();tr.ui.analysis.expandTableRowsRecursively(this.$.table);},createRows_(timeToVmRegionTree){const is64BitAddress=timeToVmRegionTree.some(function(vmRegionTree){if(vmRegionTree===undefined)return false;return vmRegionTree.someRegion(function(region){if(region.startAddress===undefined)return false;return region.startAddress>=4294967296;});});return[this.createClassificationNodeRow(timeToVmRegionTree,is64BitAddress)];},createClassificationNodeRow(timeToNode,is64BitAddress){const definedNode=tr.b.findFirstInArray(timeToNode);const childNodeIdToTimeToNode=Object.values(tr.b.invertArrayOfDicts(timeToNode,function(node){const children=node.children;if(children===undefined)return undefined;const childMap={};children.forEach(function(childNode){if(!childNode.hasRegions)return;childMap[childNode.title]=childNode;});return childMap;}));const childNodeSubRows=childNodeIdToTimeToNode.map(function(timeToChildNode){return this.createClassificationNodeRow(timeToChildNode,is64BitAddress);},this);const regionIdToTimeToRegion=Object.values(tr.b.invertArrayOfDicts(timeToNode,function(node){const regions=node.regions;if(regions===undefined)return undefined;return tr.b.arrayToDict(regions,function(region){return region.uniqueIdWithinProcess;});}));const regionSubRows=regionIdToTimeToRegion.map(function(timeToRegion){return this.createRegionRow_(timeToRegion,is64BitAddress);},this);const subRows=childNodeSubRows.concat(regionSubRows);return{title:definedNode.title,contexts:timeToNode,variableCells:this.createVariableCells_(timeToNode),subRows};},createRegionRow_(timeToRegion,is64BitAddress){const definedRegion=tr.b.findFirstInArray(timeToRegion);return{title:definedRegion.mappedFile,contexts:timeToRegion,constantCells:this.createConstantCells_(definedRegion,is64BitAddress),variableCells:this.createVariableCells_(timeToRegion)};},createConstantCells_(definedRegion,is64BitAddress){return tr.ui.analysis.createCells([definedRegion],function(region){const startAddress=region.startAddress;if(startAddress===undefined)return undefined;return{'Start address':hexString(startAddress,is64BitAddress)};});},createVariableCells_(timeToRegion){return tr.ui.analysis.createCells(timeToRegion,function(region){const fields={};const sizeInBytes=region.sizeInBytes;if(sizeInBytes!==undefined){fields['Virtual size']=new Scalar(sizeInBytes_smallerIsBetter,sizeInBytes);}
+const protectionFlags=region.protectionFlagsToString;if(protectionFlags!==undefined){fields['Protection flags']=protectionFlags;}
+for(const[byteStatName,columnName]of
+Object.entries(BYTE_STAT_COLUMN_MAP)){const byteStat=region.byteStats[byteStatName];if(byteStat===undefined)continue;fields[columnName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}
+return fields;});},createColumns_(rows){const titleColumn=new tr.ui.analysis.TitleColumn('Mapped file');titleColumn.width='200px';const constantColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'constantCells',aggregationMode:undefined,rules:CONSTANT_COLUMN_RULES});const variableColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'variableCells',aggregationMode:this.aggregationMode_,rules:VARIABLE_COLUMN_RULES});const fieldColumns=constantColumns.concat(variableColumns);tr.ui.analysis.MemoryColumn.spaceEqually(fieldColumns);const columns=[titleColumn].concat(fieldColumns);return columns;}});return{};});'use strict';Polymer({is:'tr-ui-b-color-legend',ready(){const blackSquareCharCode=9632;this.$.square.innerText=String.fromCharCode(blackSquareCharCode);this.label_=undefined;this.compoundEventSelectionState_=tr.model.CompoundEventSelectionState.NOT_SELECTED;},set compoundEventSelectionState(compoundEventSelectionState){this.compoundEventSelectionState_=compoundEventSelectionState;},get label(){return this.label_;},set label(label){if(label===undefined){this.setLabelAndColorId(undefined,undefined);return;}
+const colorId=tr.b.ColorScheme.getColorIdForGeneralPurposeString(label);this.setLabelAndColorId(label,colorId);},setLabelAndColorId(label,colorId){this.label_=label;Polymer.dom(this.$.label).textContent='';Polymer.dom(this.$.label).appendChild(tr.ui.b.asHTMLOrTextNode(label));if(colorId===undefined){this.$.square.style.color='initial';}else{this.$.square.style.color=tr.b.ColorScheme.colorsAsStrings[colorId];}}});'use strict';Polymer({is:'tr-ui-b-view-specific-brushing-state',get viewId(){return this.getAttribute('view-id');},set viewId(viewId){Polymer.dom(this).setAttribute('view-id',viewId);},get(){const viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
+const brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return undefined;return brushingStateController.getViewSpecificBrushingState(viewId);},set(state){const viewId=this.viewId;if(!viewId){throw new Error('Element must have a view-id attribute!');}
+const brushingStateController=tr.c.BrushingStateController.getControllerForElement(this);if(!brushingStateController)return;brushingStateController.changeViewSpecificBrushingState(viewId,state);}});'use strict';tr.exportTo('tr.ui.analysis',function(){const MemoryColumnColorScheme=tr.b.MemoryColumnColorScheme;const Scalar=tr.b.Scalar;const sizeInBytes_smallerIsBetter=tr.b.Unit.byName.sizeInBytes_smallerIsBetter;const PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX='_bytes';const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const SOME_TIMESTAMPS_INFO_QUANTIFIER=tr.ui.analysis.MemoryColumn.SOME_TIMESTAMPS_INFO_QUANTIFIER;const RIGHTWARDS_ARROW_WITH_HOOK=String.fromCharCode(0x21AA);const RIGHTWARDS_ARROW_FROM_BAR=String.fromCharCode(0x21A6);const GREATER_THAN_OR_EQUAL_TO=String.fromCharCode(0x2265);const UNMARRIED_PARTNERSHIP_SYMBOL=String.fromCharCode(0x26AF);const TRIGRAM_FOR_HEAVEN=String.fromCharCode(0x2630);function lazyMap(list,fn,opt_this){opt_this=opt_this||this;let result=undefined;list.forEach(function(item,index){const value=fn.call(opt_this,item,index);if(value===undefined)return;if(result===undefined){result=new Array(list.length);}
 result[index]=value;});return result;}
 function ProcessNameColumn(){tr.ui.analysis.TitleColumn.call(this,'Process');}
-ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle:function(row){if(row.contexts===undefined){return row.title;}
-var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-UsedMemoryColumn.COLOR=MemoryColumnColorScheme.getColor('used_memory_column').toString();UsedMemoryColumn.OLDER_COLOR=MemoryColumnColorScheme.getColor('older_used_memory_column').toString();UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},getFormattingContext:function(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},color:function(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;var vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)return undefined;return function(){var pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
-PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;var resettableValueCount=0;var nonResettableValueCount=0;for(var i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;if(processMemoryDumps[i].arePeakResidentBytesResettable){resettableValueCount++;}else{nonResettableValueCount++;}}
+ProcessNameColumn.prototype={__proto__:tr.ui.analysis.TitleColumn.prototype,formatTitle(row){if(row.contexts===undefined){return row.title;}
+const titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=row.title;return titleEl;}};function UsedMemoryColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+UsedMemoryColumn.COLOR=MemoryColumnColorScheme.getColor('used_memory_column').toString();UsedMemoryColumn.OLDER_COLOR=MemoryColumnColorScheme.getColor('older_used_memory_column').toString();UsedMemoryColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:UsedMemoryColumn.COLOR});},getFormattingContext(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},color(numerics,processMemoryDumps){return UsedMemoryColumn.COLOR;},getChildPaneBuilder(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;const vmRegions=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.mostRecentVmRegions;});if(vmRegions===undefined)return undefined;return function(){const pane=document.createElement('tr-ui-a-memory-dump-vm-regions-details-pane');pane.vmRegions=vmRegions;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function PeakMemoryColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
+PeakMemoryColumn.prototype={__proto__:UsedMemoryColumn.prototype,addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let resettableValueCount=0;let nonResettableValueCount=0;for(let i=0;i<numerics.length;i++){if(numerics[i]===undefined)continue;if(processMemoryDumps[i].arePeakResidentBytesResettable){resettableValueCount++;}else{nonResettableValueCount++;}}
 if(resettableValueCount>0&&nonResettableValueCount>0){infos.push(tr.ui.analysis.createWarningInfo('Both resettable and '+'non-resettable peak RSS values were provided by the process'));}else if(resettableValueCount>0){infos.push({icon:RIGHTWARDS_ARROW_WITH_HOOK,message:'Peak RSS since previous memory dump.'});}else{infos.push({icon:RIGHTWARDS_ARROW_FROM_BAR,message:'Peak RSS since process startup. Finer grained '+'peaks require a Linux kernel version '+
 GREATER_THAN_OR_EQUAL_TO+' 4.0.'});}}};function ByteStatColumn(name,cellPath,aggregationMode){UsedMemoryColumn.call(this,name,cellPath,aggregationMode);}
-ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color:function(numerics,processMemoryDumps){if(processMemoryDumps===undefined){return UsedMemoryColumn.COLOR;}
-var allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues){return UsedMemoryColumn.OLDER_COLOR;}
-return UsedMemoryColumn.COLOR;},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;var olderValueCount=0;for(var i=0;i<numerics.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
+ByteStatColumn.prototype={__proto__:UsedMemoryColumn.prototype,color(numerics,processMemoryDumps){if(processMemoryDumps===undefined){return UsedMemoryColumn.COLOR;}
+const allOlderValues=processMemoryDumps.every(function(processMemoryDump){if(processMemoryDump===undefined)return true;return!processMemoryDump.hasOwnVmRegions;});if(allOlderValues){return UsedMemoryColumn.OLDER_COLOR;}
+return UsedMemoryColumn.COLOR;},addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let olderValueCount=0;for(let i=0;i<numerics.length;i++){const processMemoryDump=processMemoryDumps[i];if(processMemoryDump!==undefined&&!processMemoryDump.hasOwnVmRegions){olderValueCount++;}}
 if(olderValueCount===0){return;}
-var infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident'};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
-AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){var titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},getFormattingContext:function(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},addInfos:function(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;var heapDumpCount=0;var missingSizeCount=0;for(var i=0;i<processMemoryDumps.length;i++){var processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)continue;var heapDumps=processMemoryDump.heapDumps;if(heapDumps!==undefined&&heapDumps[this.name]!==undefined){heapDumpCount++;}
-var allocatorDump=processMemoryDump.getMemoryAllocatorDumpByFullName(this.name);if(allocatorDump!==undefined&&allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME]===undefined){missingSizeCount++;}}
-if(heapDumpCount>0){var infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});}
-if(missingSizeCount>0){var infoQuantifier=missingSizeCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push(tr.ui.analysis.createWarningInfo('Size was not provided'+infoQuantifier+'.'));}},getChildPaneBuilder:function(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;var memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)return undefined;var heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)return undefined;return pmd.heapDumps[this.name];},this);return function(){var pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
-TracingColumn.COLOR=MemoryColumnColorScheme.getColor('tracing_memory_column').toString();TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color:function(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer({is:'tr-ui-a-memory-dump-overview-pane',behaviors:[tr.ui.analysis.StackedPane],created:function(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready:function(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuild_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];var selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_:function(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
-var selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},onRebuild_:function(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
-this.$.info_text.style.display='none';this.$.table.style.display='block';var rows=this.createRows_();var columns=this.createColumns_(rows);var footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_:function(){var timeToPidToProcessMemoryDump=this.processMemoryDumps_;var pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);return tr.b.dictionaryValues(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){var process=tr.b.findFirstInArray(timeToDump).process;var usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){var sizes={};var totals=dump.totals;if(totals!==undefined){for(var[totalName,cellName]of
-Object.entries(UsedMemoryColumn.TOTALS_MAP)){var total=totals[totalName];if(total===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,total);}
-var platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){for(var[name,size]of
-Object.entries(platformSpecific)){if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){name=name.substring(0,name.length-
+const infoQuantifier=olderValueCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Older value'+infoQuantifier+' (only heavy (purple) memory dumps contain memory maps).',icon:UNMARRIED_PARTNERSHIP_SYMBOL});}};UsedMemoryColumn.RULES=[{condition:'Total resident',importance:10,columnConstructor:UsedMemoryColumn},{condition:'Peak total resident',importance:9,columnConstructor:PeakMemoryColumn},{condition:'PSS',importance:8,columnConstructor:ByteStatColumn},{condition:'Private dirty',importance:7,columnConstructor:ByteStatColumn},{condition:'Swapped',importance:6,columnConstructor:ByteStatColumn},{importance:0,columnConstructor:UsedMemoryColumn}];UsedMemoryColumn.TOTALS_MAP={'residentBytes':'Total resident','peakResidentBytes':'Peak total resident'};UsedMemoryColumn.BYTE_STAT_MAP={'proportionalResident':'PSS','privateDirtyResident':'Private dirty','swapped':'Swapped'};function AllocatorColumn(name,cellPath,aggregationMode){tr.ui.analysis.NumericMemoryColumn.call(this,name,cellPath,aggregationMode);}
+AllocatorColumn.prototype={__proto__:tr.ui.analysis.NumericMemoryColumn.prototype,get title(){const titleEl=document.createElement('tr-ui-b-color-legend');titleEl.label=this.name;return titleEl;},getFormattingContext(unit){return{unitPrefix:tr.b.UnitPrefixScale.BINARY.MEBI};},addInfos(numerics,processMemoryDumps,infos){if(processMemoryDumps===undefined)return;let heapDumpCount=0;let missingSizeCount=0;for(let i=0;i<processMemoryDumps.length;i++){const processMemoryDump=processMemoryDumps[i];if(processMemoryDump===undefined)continue;const heapDumps=processMemoryDump.heapDumps;if(heapDumps!==undefined&&heapDumps[this.name]!==undefined){heapDumpCount++;}
+const allocatorDump=processMemoryDump.getMemoryAllocatorDumpByFullName(this.name);if(allocatorDump!==undefined&&allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME]===undefined){missingSizeCount++;}}
+if(heapDumpCount>0){const infoQuantifier=heapDumpCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push({message:'Heap dump provided'+infoQuantifier+'.',icon:TRIGRAM_FOR_HEAVEN});}
+if(missingSizeCount>0){const infoQuantifier=missingSizeCount<numerics.length?' '+SOME_TIMESTAMPS_INFO_QUANTIFIER:'';infos.push(tr.ui.analysis.createWarningInfo('Size was not provided'+infoQuantifier+'.'));}},getChildPaneBuilder(processMemoryDumps){if(processMemoryDumps===undefined)return undefined;const memoryAllocatorDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined)return undefined;return pmd.getMemoryAllocatorDumpByFullName(this.name);},this);if(memoryAllocatorDumps===undefined)return undefined;const heapDumps=lazyMap(processMemoryDumps,function(pmd){if(pmd===undefined||pmd.heapDumps===undefined)return undefined;return pmd.heapDumps[this.name];},this);return function(){const pane=document.createElement('tr-ui-a-memory-dump-allocator-details-pane');pane.memoryAllocatorDumps=memoryAllocatorDumps;pane.heapDumps=heapDumps;pane.aggregationMode=this.aggregationMode;return pane;}.bind(this);}};function TracingColumn(name,cellPath,aggregationMode){AllocatorColumn.call(this,name,cellPath,aggregationMode);}
+TracingColumn.COLOR=MemoryColumnColorScheme.getColor('tracing_memory_column').toString();TracingColumn.prototype={__proto__:AllocatorColumn.prototype,get title(){return tr.ui.b.createSpan({textContent:this.name,color:TracingColumn.COLOR});},color(numerics,processMemoryDumps){return TracingColumn.COLOR;}};AllocatorColumn.RULES=[{condition:'tracing',importance:0,columnConstructor:TracingColumn},{importance:1,columnConstructor:AllocatorColumn}];Polymer({is:'tr-ui-a-memory-dump-overview-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.processMemoryDumps_=undefined;this.aggregationMode_=undefined;},ready(){this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.CELL;this.$.table.addEventListener('selection-changed',function(tableEvent){tableEvent.stopPropagation();this.changeChildPane_();}.bind(this));},set processMemoryDumps(processMemoryDumps){this.processMemoryDumps_=processMemoryDumps;this.scheduleRebuild_();},get processMemoryDumps(){return this.processMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},get selectedMemoryCell(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+const selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];const selectedMemoryCell=selectedColumn.cell(selectedTableRow);return selectedMemoryCell;},changeChildPane_(){this.storeSelection_();this.childPaneBuilder=this.determineChildPaneBuilderFromSelection_();},determineChildPaneBuilderFromSelection_(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){return undefined;}
+const selectedTableRow=this.$.table.selectedTableRow;if(!selectedTableRow)return undefined;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex===undefined)return undefined;const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];return selectedColumn.getChildPaneBuilder(selectedTableRow.contexts);},onRebuild_(){if(this.processMemoryDumps_===undefined||this.processMemoryDumps_.length===0){this.$.info_text.style.display='block';this.$.table.style.display='none';this.$.table.clear();this.$.table.rebuild();return;}
+this.$.info_text.style.display='none';this.$.table.style.display='block';const rows=this.createRows_();const columns=this.createColumns_(rows);const footerRows=this.createFooterRows_(rows,columns);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.tableColumns=columns;this.$.table.rebuild();this.restoreSelection_();},createRows_(){const timeToPidToProcessMemoryDump=this.processMemoryDumps_;const pidToTimeToProcessMemoryDump=tr.b.invertArrayOfDicts(timeToPidToProcessMemoryDump);return Object.values(tr.b.mapItems(pidToTimeToProcessMemoryDump,function(pid,timeToDump){const process=tr.b.findFirstInArray(timeToDump).process;const usedMemoryCells=tr.ui.analysis.createCells(timeToDump,function(dump){const sizes={};const totals=dump.totals;if(totals!==undefined){for(const[totalName,cellName]of
+Object.entries(UsedMemoryColumn.TOTALS_MAP)){const total=totals[totalName];if(total===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,total);}
+const platformSpecific=totals.platformSpecific;if(platformSpecific!==undefined){for(const[name,size]of
+Object.entries(platformSpecific)){let newName=name;if(name.endsWith(PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX)){newName=name.substring(0,name.length-
 PLATFORM_SPECIFIC_TOTAL_NAME_SUFFIX.length);}
-name=name.replace('_',' ').trim();name=name.charAt(0).toUpperCase()+name.slice(1);sizes[name]=new Scalar(sizeInBytes_smallerIsBetter,size);}}}
-var vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){for(var[byteStatName,cellName]of
-Object.entries(UsedMemoryColumn.BYTE_STAT_MAP)){var byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}}
-return sizes;});var allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){var memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)return undefined;var sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){var rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric===undefined){rootDisplayedSizeNumeric=new Scalar(sizeInBytes_smallerIsBetter,0);}
-sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});return{title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells:usedMemoryCells,allocatorCells:allocatorCells};}));},createFooterRows_:function(rows,columns){if(rows.length<=1)return[];var totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_:function(rows){var titleColumn=new ProcessNameColumn();titleColumn.width='200px';var usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'usedMemoryCells',aggregationMode:this.aggregationMode_,rules:UsedMemoryColumn.RULES});var allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'allocatorCells',aggregationMode:this.aggregationMode_,rules:AllocatorColumn.RULES});var sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);var columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_:function(){var selectedRowTitle;var selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined){selectedRowTitle=selectedRow.title;}
-var selectedColumnName;var selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){var selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
-this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_:function(){var settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined){return;}
-var selectedColumnName=settings.columnName;var selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)return;var selectedRowTitle=settings.rowTitle;var selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn,UsedMemoryColumn,PeakMemoryColumn,ByteStatColumn,AllocatorColumn,TracingColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-memory-dump-header-pane',behaviors:[tr.ui.analysis.StackedPane],created:function(){this.containerMemoryDumps_=undefined;},ready:function(){Polymer.dom(this.$.aggregation_mode_container).appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuild_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_:function(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_:function(){Polymer.dom(this.$.label).textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){Polymer.dom(this.$.label).textContent='No memory dumps selected';return;}
-var containerDumpCount=this.containerMemoryDumps_.length;var isMultiSelection=containerDumpCount>1;Polymer.dom(this.$.label).appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
-(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){var ELLIPSIS=String.fromCharCode(8230);Polymer.dom(this.$.label).appendChild(document.createTextNode(ELLIPSIS));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_:function(){var displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1){displayStyle='none';}else{displayStyle='initial';}
-this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_:function(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){return undefined;}
-var overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer({is:'tr-ui-a-stacked-pane-view',setPaneBuilder:function(paneBuilder,opt_parentPane){var paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement)){throw new Error('Parent pane must be an HTML element');}
+newName=newName.replace('_',' ').trim();newName=newName.charAt(0).toUpperCase()+
+newName.slice(1);sizes[newName]=new Scalar(sizeInBytes_smallerIsBetter,size);}}}
+const vmRegions=dump.mostRecentVmRegions;if(vmRegions!==undefined){for(const[byteStatName,cellName]of
+Object.entries(UsedMemoryColumn.BYTE_STAT_MAP)){const byteStat=vmRegions.byteStats[byteStatName];if(byteStat===undefined)continue;sizes[cellName]=new Scalar(sizeInBytes_smallerIsBetter,byteStat);}}
+return sizes;});const allocatorCells=tr.ui.analysis.createCells(timeToDump,function(dump){const memoryAllocatorDumps=dump.memoryAllocatorDumps;if(memoryAllocatorDumps===undefined)return undefined;const sizes={};memoryAllocatorDumps.forEach(function(allocatorDump){let rootDisplayedSizeNumeric=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(rootDisplayedSizeNumeric===undefined){rootDisplayedSizeNumeric=new Scalar(sizeInBytes_smallerIsBetter,0);}
+sizes[allocatorDump.fullName]=rootDisplayedSizeNumeric;});return sizes;});return{title:process.userFriendlyName,contexts:timeToDump,usedMemoryCells,allocatorCells};}));},createFooterRows_(rows,columns){if(rows.length<=1)return[];const totalRow={title:'Total'};tr.ui.analysis.aggregateTableRowCells(totalRow,rows,columns);return[totalRow];},createColumns_(rows){const titleColumn=new ProcessNameColumn();titleColumn.width='200px';const usedMemorySizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'usedMemoryCells',aggregationMode:this.aggregationMode_,rules:UsedMemoryColumn.RULES});const allocatorSizeColumns=tr.ui.analysis.MemoryColumn.fromRows(rows,{cellKey:'allocatorCells',aggregationMode:this.aggregationMode_,rules:AllocatorColumn.RULES});const sizeColumns=usedMemorySizeColumns.concat(allocatorSizeColumns);tr.ui.analysis.MemoryColumn.spaceEqually(sizeColumns);const columns=[titleColumn].concat(sizeColumns);return columns;},storeSelection_(){let selectedRowTitle;const selectedRow=this.$.table.selectedTableRow;if(selectedRow!==undefined){selectedRowTitle=selectedRow.title;}
+let selectedColumnName;const selectedColumnIndex=this.$.table.selectedColumnIndex;if(selectedColumnIndex!==undefined){const selectedColumn=this.$.table.tableColumns[selectedColumnIndex];selectedColumnName=selectedColumn.name;}
+this.$.state.set({rowTitle:selectedRowTitle,columnName:selectedColumnName});},restoreSelection_(){const settings=this.$.state.get();if(settings===undefined||settings.rowTitle===undefined||settings.columnName===undefined){return;}
+const selectedColumnName=settings.columnName;const selectedColumnIndex=tr.b.findFirstIndexInArray(this.$.table.tableColumns,function(column){return column.name===selectedColumnName;});if(selectedColumnIndex<0)return;const selectedRowTitle=settings.rowTitle;const selectedRow=tr.b.findFirstInArray(this.$.table.tableRows,function(row){return row.title===selectedRowTitle;});if(selectedRow===undefined)return;this.$.table.selectedTableRow=selectedRow;this.$.table.selectedColumnIndex=selectedColumnIndex;}});return{ProcessNameColumn,UsedMemoryColumn,PeakMemoryColumn,ByteStatColumn,AllocatorColumn,TracingColumn,};});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-memory-dump-header-pane',behaviors:[tr.ui.analysis.StackedPane],created(){this.containerMemoryDumps_=undefined;},ready(){Polymer.dom(this.$.aggregation_mode_container).appendChild(tr.ui.b.createSelector(this,'aggregationMode','memoryDumpHeaderPane.aggregationMode',tr.ui.analysis.MemoryColumn.AggregationMode.DIFF,[{label:'Diff',value:tr.ui.analysis.MemoryColumn.AggregationMode.DIFF},{label:'Max',value:tr.ui.analysis.MemoryColumn.AggregationMode.MAX}]));},set containerMemoryDumps(containerMemoryDumps){this.containerMemoryDumps_=containerMemoryDumps;this.scheduleRebuild_();},get containerMemoryDumps(){return this.containerMemoryDumps_;},set aggregationMode(aggregationMode){this.aggregationMode_=aggregationMode;this.scheduleRebuild_();},get aggregationMode(){return this.aggregationMode_;},onRebuild_(){this.updateLabel_();this.updateAggregationModeSelector_();this.changeChildPane_();},updateLabel_(){Polymer.dom(this.$.label).textContent='';if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){Polymer.dom(this.$.label).textContent='No memory dumps selected';return;}
+const containerDumpCount=this.containerMemoryDumps_.length;const isMultiSelection=containerDumpCount>1;Polymer.dom(this.$.label).appendChild(document.createTextNode('Selected '+containerDumpCount+' memory dump'+
+(isMultiSelection?'s':'')+' in '+this.containerMemoryDumps_[0].containerName+' at '));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[0].start)));if(isMultiSelection){const ELLIPSIS=String.fromCharCode(8230);Polymer.dom(this.$.label).appendChild(document.createTextNode(ELLIPSIS));Polymer.dom(this.$.label).appendChild(document.createTextNode(tr.b.Unit.byName.timeStampInMs.format(this.containerMemoryDumps_[containerDumpCount-1].start)));}},updateAggregationModeSelector_(){let displayStyle;if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=1){displayStyle='none';}else{displayStyle='initial';}
+this.$.aggregation_mode_container.style.display=displayStyle;},changeChildPane_(){this.childPaneBuilder=function(){if(this.containerMemoryDumps_===undefined||this.containerMemoryDumps_.length<=0){return undefined;}
+const overviewPane=document.createElement('tr-ui-a-memory-dump-overview-pane');overviewPane.processMemoryDumps=this.containerMemoryDumps_.map(function(containerDump){return containerDump.processMemoryDumps;});overviewPane.aggregationMode=this.aggregationMode;return overviewPane;}.bind(this);}});return{};});'use strict';Polymer({is:'tr-ui-a-stacked-pane-view',setPaneBuilder(paneBuilder,opt_parentPane){const paneContainer=this.$.pane_container;if(opt_parentPane){if(!(opt_parentPane instanceof HTMLElement)){throw new Error('Parent pane must be an HTML element');}
 if(opt_parentPane.parentElement!==paneContainer){throw new Error('Parent pane must be a child of the pane container');}}
-while(Polymer.dom(paneContainer).lastElementChild!==null&&Polymer.dom(paneContainer).lastElementChild!==opt_parentPane){var removedPane=Polymer.dom(this.$.pane_container).lastElementChild;var listener=this.listeners_.get(removedPane);if(listener===undefined){throw new Error('No listener associated with pane');}
+while(Polymer.dom(paneContainer).lastElementChild!==null&&Polymer.dom(paneContainer).lastElementChild!==opt_parentPane){const removedPane=Polymer.dom(this.$.pane_container).lastElementChild;const listener=this.listeners_.get(removedPane);if(listener===undefined){throw new Error('No listener associated with pane');}
 this.listeners_.delete(removedPane);removedPane.removeEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).removeChild(removedPane);}
 if(opt_parentPane&&opt_parentPane.parentElement!==paneContainer){throw new Error('Parent pane was removed from the pane container');}
-if(!paneBuilder)return;var pane=paneBuilder();if(!pane)return;if(!(pane instanceof HTMLElement)){throw new Error('Pane must be an HTML element');}
-var listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
-this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).appendChild(pane);pane.appended();},rebuild:function(){var currentPane=Polymer.dom(this.$.pane_container).firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){var panes=[];var currentChild=Polymer.dom(this.$.pane_container).firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
+if(!paneBuilder)return;const pane=paneBuilder();if(!pane)return;if(!(pane instanceof HTMLElement)){throw new Error('Pane must be an HTML element');}
+const listener=function(event){this.setPaneBuilder(pane.childPaneBuilder,pane);}.bind(this);if(!this.listeners_){this.listeners_=new WeakMap();}
+this.listeners_.set(pane,listener);pane.addEventListener('request-child-pane-change',listener);Polymer.dom(paneContainer).appendChild(pane);pane.appended();},rebuild(){let currentPane=Polymer.dom(this.$.pane_container).firstElementChild;while(currentPane){currentPane.rebuild();currentPane=currentPane.nextElementSibling;}},get panesForTesting(){const panes=[];let currentChild=Polymer.dom(this.$.pane_container).firstElementChild;while(currentChild){panes.push(currentChild);currentChild=currentChild.nextElementSibling;}
 return panes;}});'use strict';tr.exportTo('tr.ui.analysis',function(){Polymer({is:'tr-ui-a-container-memory-dump-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],set selection(selection){if(selection===undefined){this.currentSelection_=undefined;this.dumpsByContainerName_=undefined;this.updateContents_();return;}
-selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.group(this.currentSelection_.toArray(),dump=>dump.containerName);for(var dumps of Object.values(this.dumpsByContainerName_)){dumps.sort((a,b)=>a.start-b.start);}
-this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_:function(){Polymer.dom(this.$.content).textContent='';if(this.dumpsByContainerName_===undefined)return;var containerNames=Object.keys(this.dumpsByContainerName_);if(containerNames.length===0)return;if(containerNames.length>1){this.buildViewForMultipleContainerNames_();}else{this.buildViewForSingleContainerName_();}},buildViewForSingleContainerName_:function(){var containerMemoryDumps=tr.b.dictionaryValues(this.dumpsByContainerName_)[0];var dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');Polymer.dom(this.$.content).appendChild(dumpView);dumpView.setPaneBuilder(function(){var headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_:function(){var ownerDocument=this.ownerDocument;var rows=tr.b.dictionaryValues(tr.b.mapItems(this.dumpsByContainerName_,function(containerName,dumps){return{containerName:containerName,subRows:dumps,isExpanded:true};}));rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});var columns=[{title:'Dump',value:function(row){if(row.subRows===undefined){return this.singleDumpValue_(row);}
-return this.groupedDumpValue_(row);},singleDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));Polymer.dom(linkEl).appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:ownerDocument}));return linkEl;},groupedDumpValue_:function(row){var linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.subRows.length+' memory dump'+
-(row.subRows.length===1?'':'s')+' in '}));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument:ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];var table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();Polymer.dom(this.$.content).appendChild(table);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:false,title:'Global Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:true,title:'Global Memory Dumps',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:false,title:'Process Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:true,title:'Process Memory Dumps',});return{};});'use strict';(function(){var COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value:function(row){return row.counter;}},{title:'Series',width:'150px',value:function(row){return row.series;}},{title:'Time',width:'150px',value:function(row){return row.start;}},{title:'Value',width:'100%',value:function(row){return row.value;}}];Polymer({is:'tr-ui-a-counter-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_:function(samples){var samplesByCounter=tr.b.groupIntoMap(samples,sample=>sample.series.counter.guid);var rows=[];for(var counterSamples of samplesByCounter.values()){var samplesBySeries=tr.b.groupIntoMap(counterSamples,sample=>sample.series.guid);for(var seriesSamples of samplesBySeries.values()){var seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
+selection.forEach(function(event){if(!(event instanceof tr.model.ContainerMemoryDump)){throw new Error('Memory dump sub-view only supports container memory dumps');}});this.currentSelection_=selection;this.dumpsByContainerName_=tr.b.groupIntoMap(this.currentSelection_.toArray(),dump=>dump.containerName);for(const dumps of this.dumpsByContainerName_.values()){dumps.sort((a,b)=>a.start-b.start);}
+this.updateContents_();},get selection(){return this.currentSelection_;},get requiresTallView(){return true;},updateContents_(){Polymer.dom(this.$.content).textContent='';if(this.dumpsByContainerName_===undefined)return;const containerNames=Array.from(this.dumpsByContainerName_.keys());if(containerNames.length===0)return;if(containerNames.length>1){this.buildViewForMultipleContainerNames_();}else{this.buildViewForSingleContainerName_();}},buildViewForSingleContainerName_(){const containerMemoryDumps=tr.b.getFirstElement(this.dumpsByContainerName_.values());const dumpView=this.ownerDocument.createElement('tr-ui-a-stacked-pane-view');Polymer.dom(this.$.content).appendChild(dumpView);dumpView.setPaneBuilder(function(){const headerPane=document.createElement('tr-ui-a-memory-dump-header-pane');headerPane.containerMemoryDumps=containerMemoryDumps;return headerPane;});},buildViewForMultipleContainerNames_(){const ownerDocument=this.ownerDocument;const rows=[];for(const[containerName,dumps]of this.dumpsByContainerName_){rows.push({containerName,subRows:dumps,isExpanded:true,});}
+rows.sort(function(a,b){return a.containerName.localeCompare(b.containerName);});const columns=[{title:'Dump',value(row){if(row.subRows===undefined){return this.singleDumpValue_(row);}
+return this.groupedDumpValue_(row);},singleDumpValue_(row){const linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet([row]));Polymer.dom(linkEl).appendChild(tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument}));return linkEl;},groupedDumpValue_(row){const linkEl=ownerDocument.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(row.subRows));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument,textContent:row.subRows.length+' memory dump'+
+(row.subRows.length===1?'':'s')+' in '}));Polymer.dom(linkEl).appendChild(tr.ui.b.createSpan({ownerDocument,textContent:row.containerName,bold:true}));return linkEl;}}];const table=this.ownerDocument.createElement('tr-ui-b-table');table.tableColumns=columns;table.tableRows=rows;table.showHeader=false;table.rebuild();Polymer.dom(this.$.content).appendChild(table);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:false,title:'Global Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.GlobalMemoryDump,{multi:true,title:'Global Memory Dumps',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:false,title:'Process Memory Dump',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-container-memory-dump-sub-view',tr.model.ProcessMemoryDump,{multi:true,title:'Process Memory Dumps',});return{};});'use strict';(function(){const COUNTER_SAMPLE_TABLE_COLUMNS=[{title:'Counter',width:'150px',value(row){return row.counter;}},{title:'Series',width:'150px',value(row){return row.series;}},{title:'Time',width:'150px',value(row){return row.start;}},{title:'Value',width:'100%',value(row){return row.value;}}];Polymer({is:'tr-ui-a-counter-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;this.$.table.tableColumns=COUNTER_SAMPLE_TABLE_COLUMNS;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){this.$.table.tableRows=this.selection?this.getRows_(this.selection.toArray()):[];this.$.table.rebuild();},getRows_(samples){const samplesByCounter=tr.b.groupIntoMap(samples,sample=>sample.series.counter.guid);const rows=[];for(const counterSamples of samplesByCounter.values()){const samplesBySeries=tr.b.groupIntoMap(counterSamples,sample=>sample.series.guid);for(const seriesSamples of samplesBySeries.values()){const seriesRows=this.getRowsForSamples_(seriesSamples);seriesRows[0].counter=seriesSamples[0].series.counter.name;seriesRows[0].series=seriesSamples[0].series.name;if(seriesRows.length>1){seriesRows[0].subRows=seriesRows.slice(1);seriesRows[0].isExpanded=true;}
 rows.push(seriesRows[0]);}}
-return rows;},getRowsForSamples_:function(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:false,title:'Counter Sample',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:true,title:'Counter Samples',});})();'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;}
+return rows;},getRowsForSamples_(samples){return samples.map(function(sample){return{start:sample.timestamp,value:sample.value};});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:false,title:'Counter Sample',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-counter-sample-sub-view',tr.model.CounterSample,{multi:true,title:'Counter Samples',});})();'use strict';tr.exportTo('tr.ui.analysis',function(){function MultiEventSummary(title,events){this.title=title;this.duration_=undefined;this.selfTime_=undefined;this.events_=events;this.cpuTimesComputed_=false;this.cpuSelfTime_=undefined;this.cpuDuration_=undefined;this.maxDuration_=undefined;this.maxCpuDuration_=undefined;this.maxSelfTime_=undefined;this.maxCpuSelfTime_=undefined;this.untotallableArgs_=[];this.totalledArgs_=undefined;}
 MultiEventSummary.prototype={set title(title){if(title==='Totals'){this.totalsRow=true;}
 this.title_=title;},get title(){return this.title_;},get duration(){if(this.duration_===undefined){this.duration_=tr.b.math.Statistics.sum(this.events_,function(event){return event.duration;});}
-return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_:function(){if(this.cpuTimesComputed_)return;this.cpuTimesComputed_=true;var cpuSelfTime=0;var cpuDuration=0;var hasCpuData=false;for(var event of this.events_){if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
+return this.duration_;},get cpuSelfTime(){this.computeCpuTimesIfNeeded_();return this.cpuSelfTime_;},get cpuDuration(){this.computeCpuTimesIfNeeded_();return this.cpuDuration_;},computeCpuTimesIfNeeded_(){if(this.cpuTimesComputed_)return;this.cpuTimesComputed_=true;let cpuSelfTime=0;let cpuDuration=0;let hasCpuData=false;for(const event of this.events_){if(event.cpuDuration!==undefined){cpuDuration+=event.cpuDuration;hasCpuData=true;}
 if(event.cpuSelfTime!==undefined){cpuSelfTime+=event.cpuSelfTime;hasCpuData=true;}}
-if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(var event of this.events_){if(event.selfTime!==undefined){this.selfTime_+=event.selfTime;}}}
+if(hasCpuData){this.cpuDuration_=cpuDuration;this.cpuSelfTime_=cpuSelfTime;}},get selfTime(){if(this.selfTime_===undefined){this.selfTime_=0;for(const event of this.events_){if(event.selfTime!==undefined){this.selfTime_+=event.selfTime;}}}
 return this.selfTime_;},get events(){return this.events_;},get numEvents(){return this.events_.length;},get numAlerts(){if(this.numAlerts_===undefined){this.numAlerts_=tr.b.math.Statistics.sum(this.events_,event=>event.associatedAlerts.length);}
 return this.numAlerts_;},get untotallableArgs(){this.updateArgsIfNeeded_();return this.untotallableArgs_;},get totalledArgs(){this.updateArgsIfNeeded_();return this.totalledArgs_;},get maxDuration(){if(this.maxDuration_===undefined){this.maxDuration_=tr.b.math.Statistics.max(this.events_,function(event){return event.duration;});}
 return this.maxDuration_;},get maxCpuDuration(){if(this.maxCpuDuration_===undefined){this.maxCpuDuration_=tr.b.math.Statistics.max(this.events_,function(event){return event.cpuDuration;});}
 return this.maxCpuDuration_;},get maxSelfTime(){if(this.maxSelfTime_===undefined){this.maxSelfTime_=tr.b.math.Statistics.max(this.events_,function(event){return event.selfTime;});}
 return this.maxSelfTime_;},get maxCpuSelfTime(){if(this.maxCpuSelfTime_===undefined){this.maxCpuSelfTime_=tr.b.math.Statistics.max(this.events_,function(event){return event.cpuSelfTime;});}
-return this.maxCpuSelfTime_;},updateArgsIfNeeded_:function(){if(this.totalledArgs_!==undefined)return;var untotallableArgs={};var totalledArgs={};for(var event of this.events_){for(var argName in event.args){var argVal=event.args[argName];var type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
+return this.maxCpuSelfTime_;},updateArgsIfNeeded_(){if(this.totalledArgs_!==undefined)return;const untotallableArgs={};const totalledArgs={};for(const event of this.events_){for(const argName in event.args){const argVal=event.args[argName];const type=typeof argVal;if(type!=='number'){untotallableArgs[argName]=true;delete totalledArgs[argName];continue;}
 if(untotallableArgs[argName]){continue;}
 if(totalledArgs[argName]===undefined){totalledArgs[argName]=0;}
 totalledArgs[argName]+=argVal;}}
-this.untotallableArgs_=Object.keys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary,};});'use strict';Polymer({is:'tr-ui-a-multi-event-summary-table',ready:function(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_:function(rows,maxValues){var hasCpuData=false;var hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined){hasCpuData=true;}
+this.untotallableArgs_=Object.keys(untotallableArgs);this.totalledArgs_=totalledArgs;}};return{MultiEventSummary,};});'use strict';Polymer({is:'tr-ui-a-multi-event-summary-table',ready(){this.showTotals_=false;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;this.eventsByTitle_=undefined;},updateTableColumns_(rows,maxValues){let hasCpuData=false;let hasAlerts=false;rows.forEach(function(row){if(row.cpuDuration!==undefined){hasCpuData=true;}
 if(row.cpuSelfTime!==undefined){hasCpuData=true;}
-if(row.numAlerts){hasAlerts=true;}});var ownerDocument=this.ownerDocument;var columns=[];columns.push({title:'Name',value:function(row){if(row.title==='Totals')return'Totals';var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp:function(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value:function(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument:ownerDocument,});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.duration-rowB.duration;}});}
-if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value:function(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuDuration),ownerDocument:ownerDocument,});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value:function(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.selfTime),ownerDocument:ownerDocument,});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
-if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value:function(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuSelfTime),ownerDocument:ownerDocument,});},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
-if(this.eventsHaveDuration_){columns.push({title:'Average '+(hasCpuData?'CPU':'Wall')+' Duration',value:function(row){var totalDuration=hasCpuData?row.cpuDuration:row.duration;return tr.v.ui.createScalarSpan(totalDuration/row.numEvents,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument:ownerDocument,});},width:'<upated further down>',cmp:function(rowA,rowB){if(hasCpuData){return rowA.cpuDuration/rowA.numEvents-
+if(row.numAlerts){hasAlerts=true;}});const ownerDocument=this.ownerDocument;const columns=[];columns.push({title:'Name',value(row){if(row.title==='Totals')return'Totals';const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(row.events);},row.title);return linkEl;},width:'350px',cmp(rowA,rowB){return rowA.title.localeCompare(rowB.title);}});if(this.eventsHaveDuration_){columns.push({title:'Wall Duration',value(row){return tr.v.ui.createScalarSpan(row.duration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.duration-rowB.duration;}});}
+if(this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Duration',value(row){return tr.v.ui.createScalarSpan(row.cpuDuration,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuDuration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.cpuDuration-rowB.cpuDuration;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_){columns.push({title:'Self time',value(row){return tr.v.ui.createScalarSpan(row.selfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.selfTime),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.selfTime-rowB.selfTime;}});}
+if(this.eventsHaveSubRows_&&this.eventsHaveDuration_&&hasCpuData){columns.push({title:'CPU Self Time',value(row){return tr.v.ui.createScalarSpan(row.cpuSelfTime,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.cpuSelfTime),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){return rowA.cpuSelfTime-rowB.cpuSelfTime;}});}
+if(this.eventsHaveDuration_){columns.push({title:'Average '+(hasCpuData?'CPU':'Wall')+' Duration',value(row){const totalDuration=hasCpuData?row.cpuDuration:row.duration;return tr.v.ui.createScalarSpan(totalDuration/row.numEvents,{unit:tr.b.Unit.byName.timeDurationInMs,customContextRange:row.totalsRow?undefined:tr.b.math.Range.fromExplicitRange(0,maxValues.duration),ownerDocument,});},width:'<upated further down>',cmp(rowA,rowB){if(hasCpuData){return rowA.cpuDuration/rowA.numEvents-
 rowB.cpuDuration/rowB.numEvents;}
 return rowA.duration/rowA.numEvents-
 rowB.duration/rowB.numEvents;}});}
-columns.push({title:'Occurrences',value:function(row){return row.numEvents;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});var alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value:function(row){return row.numAlerts;},width:'<upated further down>',cmp:function(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
-var colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
-for(var i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
-this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure:function(config){if(config.eventsByTitle===undefined){throw new Error('Required: eventsByTitle');}
+columns.push({title:'Occurrences',value(row){return row.numEvents;},width:'<upated further down>',cmp(rowA,rowB){return rowA.numEvents-rowB.numEvents;}});let alertsColumnIndex;if(hasAlerts){columns.push({title:'Num Alerts',value(row){return row.numAlerts;},width:'<upated further down>',cmp(rowA,rowB){return rowA.numAlerts-rowB.numAlerts;}});alertsColumnIndex=columns.length-1;}
+let colWidthPercentage;if(columns.length===1){colWidthPercentage='100%';}else{colWidthPercentage=(100/(columns.length-1)).toFixed(3)+'%';}
+for(let i=1;i<columns.length;i++){columns[i].width=colWidthPercentage;}
+this.$.table.tableColumns=columns;if(hasAlerts){this.$.table.sortColumnIndex=alertsColumnIndex;this.$.table.sortDescending=true;}},configure(config){if(config.eventsByTitle===undefined){throw new Error('Required: eventsByTitle');}
 if(config.showTotals!==undefined){this.showTotals_=config.showTotals;}else{this.showTotals_=true;}
 if(config.eventsHaveDuration!==undefined){this.eventsHaveDuration_=config.eventsHaveDuration;}else{this.eventsHaveDuration_=true;}
 if(config.eventsHaveSubRows!==undefined){this.eventsHaveSubRows_=config.eventsHaveSubRows;}else{this.eventsHaveSubRows_=true;}
-this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_:function(){var eventsByTitle;if(this.eventsByTitle_!==undefined){eventsByTitle=this.eventsByTitle_;}else{eventsByTitle=[];}
-var allEvents=new tr.model.EventSet();var rows=[];for(var[title,eventsOfSingleTitle]of Object.entries(eventsByTitle)){for(var event of eventsOfSingleTitle)allEvents.push(event);var row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);}
-this.updateTableColumns_(rows);this.$.table.tableRows=rows;var maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(var column in maxValues){maxValues[column]=tr.b.math.Statistics.max(rows,function(event){return event[column];});}}
-var footerRows=[];if(this.showTotals_){var multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
-this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-selection-summary-table',created:function(){this.selection_=new tr.b.math.Range();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value:function(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value:function(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_:function(){var selection=this.selection_;var rows=[];var hasRange;if(this.selection_&&(!selection.bounds.isEmpty)){hasRange=true;}else{hasRange=false;}
-rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-b-radio-picker',created:function(){this.needsInit_=true;this.settingsKey_=undefined;this.isReady_=false;this.radioButtons_=undefined;this.selectedKey_=undefined;},ready:function(){this.isReady_=true;this.maybeInit_();this.maybeRenderRadioButtons_();},get vertical(){return this.getAttribute('vertical');},set vertical(vertical){if(vertical){this.setAttribute('vertical',true);}else{this.removeAttribute('vertical');}},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_){throw new Error('Already initialized.');}
-this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_:function(){if(!this.needsInit_)return;if(this.settingsKey_===undefined)return;this.needsInit_=false;this.select(tr.b.Settings.get(this.settingsKey_));},set items(items){this.radioButtons_={};items.forEach(function(e){if(e.key in this.radioButtons_){throw new Error(e.key+' already exists');}
-var radioButton=document.createElement('div');var input=document.createElement('input');var label=document.createElement('label');input.type='radio';input.id=e.label;input.addEventListener('click',function(){this.select(e.key);}.bind(this));Polymer.dom(label).innerHTML=e.label;label.htmlFor=e.label;label.style.display='inline';Polymer.dom(radioButton).appendChild(input);Polymer.dom(radioButton).appendChild(label);this.radioButtons_[e.key]=input;}.bind(this));this.maybeInit_();this.maybeRenderRadioButtons_();},maybeRenderRadioButtons_:function(){if(!this.isReady_)return;if(this.radioButtons_===undefined)return;for(var key in this.radioButtons_){Polymer.dom(this.$.container).appendChild(this.radioButtons_[key].parentElement);}
-if(this.selectedKey_!==undefined){this.select(this.selectedKey_);}},select:function(key){if(key===undefined||key===this.selectedKey_){return;}
+this.eventsByTitle_=config.eventsByTitle;this.updateContents_();},get showTotals(){return this.showTotals_;},set showTotals(showTotals){this.showTotals_=showTotals;this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;this.updateContents_();},get eventsByTitle(){return this.eventsByTitle_;},set eventsByTitle(eventsByTitle){this.eventsByTitle_=eventsByTitle;this.updateContents_();},get selectionBounds(){return this.selectionBounds_;},set selectionBounds(selectionBounds){this.selectionBounds_=selectionBounds;this.updateContents_();},updateContents_(){let eventsByTitle;if(this.eventsByTitle_!==undefined){eventsByTitle=this.eventsByTitle_;}else{eventsByTitle=[];}
+const allEvents=new tr.model.EventSet();const rows=[];for(const[title,eventsOfSingleTitle]of Object.entries(eventsByTitle)){for(const event of eventsOfSingleTitle)allEvents.push(event);const row=new tr.ui.analysis.MultiEventSummary(title,eventsOfSingleTitle);rows.push(row);}
+this.updateTableColumns_(rows);this.$.table.tableRows=rows;const maxValues={duration:undefined,selfTime:undefined,cpuSelfTime:undefined,cpuDuration:undefined};if(this.eventsHaveDuration){for(const column in maxValues){maxValues[column]=tr.b.math.Statistics.max(rows,function(event){return event[column];});}}
+const footerRows=[];if(this.showTotals_){const multiEventSummary=new tr.ui.analysis.MultiEventSummary('Totals',allEvents);footerRows.push(multiEventSummary);}
+this.updateTableColumns_(rows,maxValues);this.$.table.tableRows=rows;this.$.table.footerRows=footerRows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-selection-summary-table',created(){this.selection_=new tr.b.math.Range();},ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{title:'Name',value(row){return row.title;},width:'350px'},{title:'Value',width:'100%',value(row){return row.value;}}];},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},updateContents_(){const selection=this.selection_;const rows=[];let hasRange;if(this.selection_&&(!selection.bounds.isEmpty)){hasRange=true;}else{hasRange=false;}
+rows.push({title:'Selection start',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.min,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument}):'<empty>'});rows.push({title:'Selection extent',value:hasRange?tr.v.ui.createScalarSpan(selection.bounds.range,{unit:tr.b.Unit.byName.timeDurationInMs,ownerDocument:this.ownerDocument}):'<empty>'});this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-b-radio-picker',created(){this.needsInit_=true;this.settingsKey_=undefined;this.isReady_=false;this.radioButtons_=undefined;this.selectedKey_=undefined;},ready(){this.isReady_=true;this.maybeInit_();this.maybeRenderRadioButtons_();},get vertical(){return this.getAttribute('vertical');},set vertical(vertical){if(vertical){this.setAttribute('vertical',true);}else{this.removeAttribute('vertical');}},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){if(!this.needsInit_){throw new Error('Already initialized.');}
+this.settingsKey_=settingsKey;this.maybeInit_();},maybeInit_(){if(!this.needsInit_)return;if(this.settingsKey_===undefined)return;this.needsInit_=false;this.select(tr.b.Settings.get(this.settingsKey_));},set items(items){this.radioButtons_={};items.forEach(function(e){if(e.key in this.radioButtons_){throw new Error(e.key+' already exists');}
+const radioButton=document.createElement('div');const input=document.createElement('input');const label=document.createElement('label');input.type='radio';input.id=e.label;input.addEventListener('click',function(){this.select(e.key);}.bind(this));Polymer.dom(label).innerHTML=e.label;label.htmlFor=e.label;label.style.display='inline';Polymer.dom(radioButton).appendChild(input);Polymer.dom(radioButton).appendChild(label);this.radioButtons_[e.key]=input;}.bind(this));this.maybeInit_();this.maybeRenderRadioButtons_();},maybeRenderRadioButtons_(){if(!this.isReady_)return;if(this.radioButtons_===undefined)return;for(const key in this.radioButtons_){Polymer.dom(this.$.container).appendChild(this.radioButtons_[key].parentElement);}
+if(this.selectedKey_!==undefined){this.select(this.selectedKey_);}},select(key){if(key===undefined||key===this.selectedKey_){return;}
 if(this.radioButtons_===undefined){this.selectedKey_=key;return;}
 if(!(key in this.radioButtons_)){throw new Error(key+' does not exists');}
 if(this.selectedKey_!==undefined){this.radioButtons_[this.selectedKey_].checked=false;}
 this.selectedKey_=key;tr.b.Settings.set(this.settingsKey_,this.selectedKey_);if(this.selectedKey_!==undefined){this.radioButtons_[this.selectedKey_].checked=true;}
-this.dispatchEvent(new tr.b.Event('change',false));},get selectedKey(){return this.selectedKey_;},});'use strict';tr.exportTo('tr.ui.b',function(){var ColumnChart=tr.ui.b.define('column-chart',tr.ui.b.ChartBase2DBrushX);ColumnChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,decorate(){super.decorate();this.xCushion_=1;this.isStacked_=false;this.enableHoverBox=true;},set isStacked(stacked){this.isStacked_=true;this.updateContents_();},get isStacked(){return this.isStacked_;},get defaultGraphHeight(){return 100;},get defaultGraphWidth(){return 10*this.data_.length;},updateScales_(){if(this.data_.length===0)return;var xDifferences=0;var currentX=undefined;var previousX=undefined;this.data_.forEach(function(datum,index){previousX=currentX;currentX=this.getXForDatum_(datum,index);if(previousX!==undefined){xDifferences+=currentX-previousX;}},this);this.xScale_.range([0,this.graphWidth]);var domain=d3.extent(this.data_,this.getXForDatum_.bind(this));if(this.data_.length>1){this.xCushion_=xDifferences/(this.data_.length-1);}
+this.dispatchEvent(new tr.b.Event('change',false));},get selectedKey(){return this.selectedKey_;},});'use strict';tr.exportTo('tr.ui.b',function(){const ColumnChart=tr.ui.b.define('column-chart',tr.ui.b.ChartBase2DBrushX);ColumnChart.prototype={__proto__:tr.ui.b.ChartBase2DBrushX.prototype,decorate(){super.decorate();this.xCushion_=1;this.isStacked_=false;this.enableHoverBox=true;},set isStacked(stacked){this.isStacked_=true;this.updateContents_();},get isStacked(){return this.isStacked_;},get defaultGraphHeight(){return 100;},get defaultGraphWidth(){return 10*this.data_.length;},updateScales_(){if(this.data_.length===0)return;let xDifferences=0;let currentX=undefined;let previousX=undefined;this.data_.forEach(function(datum,index){previousX=currentX;currentX=this.getXForDatum_(datum,index);if(previousX!==undefined){xDifferences+=currentX-previousX;}},this);this.xScale_.range([0,this.graphWidth]);const domain=d3.extent(this.data_,this.getXForDatum_.bind(this));if(this.data_.length>1){this.xCushion_=xDifferences/(this.data_.length-1);}
 this.xScale_.domain([domain[0],domain[1]+this.xCushion_]);this.yScale_.range([this.graphHeight,0]);this.yScale_.domain(this.getYScaleDomain_(this.dataRange.min,this.dataRange.max));},updateDataRange_(){if(!this.isStacked){super.updateDataRange_();return;}
-this.autoDataRange_.reset();this.autoDataRange_.addValue(0);for(var datum of this.data_){var sum=0;for(var[key,series]of this.seriesByKey_){if(datum[key]===undefined){continue;}
+this.autoDataRange_.reset();this.autoDataRange_.addValue(0);for(const datum of this.data_){let sum=0;for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined){continue;}
 sum+=datum[key];}
-this.autoDataRange_.addValue(sum);}},getStackedRectsForDatum_(datum,index){var stacks=[];var bottom=this.yScale_.range()[0];var sum=0;for(var[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
-sum+=this.dataRange.clamp(datum[key]);var heightPx=bottom-this.yScale_(sum);bottom-=heightPx;stacks.push({key:key,value:datum[key],color:this.getDataSeries(key).color,heightPx:heightPx,topPx:bottom,underflow:sum<this.dataRange.min,overflow:sum>this.dataRange.max,});}
+this.autoDataRange_.addValue(sum);}},getStackedRectsForDatum_(datum,index){const stacks=[];let bottom=this.yScale_.range()[0];let sum=0;for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
+sum+=this.dataRange.clamp(datum[key]);const heightPx=bottom-this.yScale_(sum);bottom-=heightPx;stacks.push({key,value:datum[key],color:this.getDataSeries(key).color,heightPx,topPx:bottom,underflow:sum<this.dataRange.min,overflow:sum>this.dataRange.max,});}
 return stacks;},getRectsForDatum_(datum,index){if(this.isStacked){return this.getStackedRectsForDatum_(datum,index);}
-var stacks=[];for(var[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
-var clampedValue=this.dataRange.clamp(datum[key]);var topPx=this.yScale_(Math.max(clampedValue,this.getYScaleMin_()));stacks.push({key:key,value:datum[key],topPx:topPx,heightPx:this.yScale_.range()[0]-topPx,color:this.getDataSeries(key).color,underflow:datum[key]<this.dataRange.min,overflow:datum[key]>this.dataRange.max,});}
-stacks.sort(function(a,b){return b.topPx-a.topPx;});return stacks;},drawHoverValueBox_(rect){var rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;var seriesKeys=[...this.seriesByKey_.keys()];var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();var keyWidthPx=0;var keyHeightPx=0;if(seriesKeys.length>1){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width+5;keyHeightPx=16;}
-var valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.value).width+5;var valueHeightPx=16;var hoverLeftPx=rect.leftPx+(rect.widthPx/2);chartAreaSel.append('rect').attr('class','hover').attr('fill','white').attr('x',hoverLeftPx).attr('y',rect.topPx).attr('width',Math.max(keyWidthPx,valueWidthPx)).attr('height',keyHeightPx+valueHeightPx);if(seriesKeys.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',rect.topPx+keyHeightPx-3).text(rect.key);}
-chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',rect.topPx+keyHeightPx+valueHeightPx-3).text(rect.value);},clearHoverValueBox_(rect){var rectHoverEvent=new tr.b.Event('rect-mouseleave');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);d3.select(this.chartAreaElement).selectAll('.hover').remove();},drawRect_(rect,sel){sel=sel.data([rect]);sel.enter().append('rect').attr('fill',rect.color).attr('x',rect.leftPx).attr('y',rect.topPx).attr('width',rect.widthPx).attr('height',rect.heightPx).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawUnderflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',this.graphHeight).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',0);sel.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();var chartAreaSel=d3.select(this.chartAreaElement);var seriesKeys=[...this.seriesByKey_.keys()];var rectsSel=dataSel.selectAll('path');this.data_.forEach(function(datum,index){var currentX=this.getXForDatum_(datum,index);var width=undefined;if(index<(this.data_.length-1)){var nextX=this.getXForDatum_(this.data_[index+1],index+1);width=nextX-currentX;}else{width=this.xCushion_;}
-for(var rect of this.getRectsForDatum_(datum,index)){rect.datum=datum;rect.index=index;rect.leftPx=this.xScale_(currentX);rect.rightPx=this.xScale_(currentX+width);rect.widthPx=rect.rightPx-rect.leftPx;this.drawRect_(rect,rectsSel);if(rect.underflow){this.drawUnderflow_(rect,rectsSel);}
-if(rect.overflow){this.drawOverflow_(rect,rectsSel);}}},this);}};return{ColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){var MIN_GUIDELINE_HEIGHT_PX=3;var CHECKBOX_WIDTH_PX=18;var NameColumnChart=tr.ui.b.define('name-column-chart',tr.ui.b.ColumnChart);NameColumnChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},updateMargins_(){super.updateMargins_();var xAxisTickOverhangPx=0;for(var i=0;i<this.data_.length;++i){var datum=this.data_[i];xAxisTickOverhangPx=Math.max(xAxisTickOverhangPx,this.xScale_(i)+tr.ui.b.getSVGTextSize(this,datum.x).width-
+const stacks=[];for(const[key,series]of this.seriesByKey_){if(datum[key]===undefined||!this.isSeriesEnabled(key)){continue;}
+const clampedValue=this.dataRange.clamp(datum[key]);const topPx=this.yScale_(Math.max(clampedValue,this.getYScaleMin_()));stacks.push({key,value:datum[key],topPx,heightPx:this.yScale_.range()[0]-topPx,color:this.getDataSeries(key).color,underflow:datum[key]<this.dataRange.min,overflow:datum[key]>this.dataRange.max,});}
+stacks.sort(function(a,b){return b.topPx-a.topPx;});return stacks;},drawHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;const seriesKeys=[...this.seriesByKey_.keys()];const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();let keyWidthPx=0;let keyHeightPx=0;if(seriesKeys.length>1){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width+5;keyHeightPx=16;}
+const valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.value).width+5;const valueHeightPx=16;const hoverLeftPx=rect.leftPx+(rect.widthPx/2);chartAreaSel.append('rect').attr('class','hover').attr('fill','white').attr('x',hoverLeftPx).attr('y',rect.topPx).attr('width',Math.max(keyWidthPx,valueWidthPx)).attr('height',keyHeightPx+valueHeightPx);if(seriesKeys.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',rect.topPx+keyHeightPx-3).text(rect.key);}
+chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',rect.topPx+keyHeightPx+valueHeightPx-3).text(rect.value);},clearHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseleave');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);d3.select(this.chartAreaElement).selectAll('.hover').remove();},drawRect_(rect,sel){sel=sel.data([rect]);sel.enter().append('rect').attr('fill',rect.color).attr('x',rect.leftPx).attr('y',rect.topPx).attr('width',rect.widthPx).attr('height',rect.heightPx).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawUnderflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',this.graphHeight).on('mouseenter',this.drawHoverValueBox_.bind(this,rect)).on('mouseleave',this.clearHoverValueBox_.bind(this,rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',rect.leftPx+(rect.widthPx/2)).attr('y',0);sel.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const chartAreaSel=d3.select(this.chartAreaElement);const seriesKeys=[...this.seriesByKey_.keys()];const rectsSel=dataSel.selectAll('path');this.data_.forEach(function(datum,index){const currentX=this.getXForDatum_(datum,index);let width=undefined;if(index<(this.data_.length-1)){const nextX=this.getXForDatum_(this.data_[index+1],index+1);width=nextX-currentX;}else{width=this.xCushion_;}
+for(const rect of this.getRectsForDatum_(datum,index)){rect.datum=datum;rect.index=index;rect.leftPx=this.xScale_(currentX);rect.rightPx=this.xScale_(currentX+width);rect.widthPx=rect.rightPx-rect.leftPx;this.drawRect_(rect,rectsSel);if(rect.underflow){this.drawUnderflow_(rect,rectsSel);}
+if(rect.overflow){this.drawOverflow_(rect,rectsSel);}}},this);}};return{ColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const MIN_GUIDELINE_HEIGHT_PX=3;const CHECKBOX_WIDTH_PX=18;const NameColumnChart=tr.ui.b.define('name-column-chart',tr.ui.b.ColumnChart);NameColumnChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},updateMargins_(){super.updateMargins_();let xAxisTickOverhangPx=0;for(let i=0;i<this.data_.length;++i){const datum=this.data_[i];xAxisTickOverhangPx=Math.max(xAxisTickOverhangPx,this.xScale_(i)+tr.ui.b.getSVGTextSize(this,datum.x).width-
 this.graphWidth);}
-this.margin.right=Math.max(this.margin.right,xAxisTickOverhangPx);},getXForDatum_:function(datum,index){return index;},get xAxisTickOffset(){return 0.5;},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;var nameTexts=xAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('transform',(d,index)=>'translate(0, '+
-this.textHeightPx_*(this.data_.length-index)+')').attr('x',(d,index)=>this.xScale_(index)).attr('y',d=>this.graphHeight).text(d=>d.x);nameTexts.exit().remove();var guideLines=xAxis.selectAll('line.guide').data(this.data_);guideLines.enter().append('line').attr('x1',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('x2',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('y1',()=>this.graphHeight).attr('y2',(d,index)=>this.graphHeight+Math.max(MIN_GUIDELINE_HEIGHT_PX,(this.textHeightPx_*(this.data_.length-index-1))));}};return{NameColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){var LineChart=tr.ui.b.LineChart;var NameLineChart=tr.ui.b.define('name-line-chart',LineChart);NameLineChart.prototype={__proto__:LineChart.prototype,getXForDatum_:function(datum,index){return index;},get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},get xAxisTickOffset(){return 0;},updateMargins_(){tr.ui.b.NameColumnChart.prototype.updateMargins_.call(this);},updateXAxis_:function(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);var baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length-1)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();}};return{NameLineChart,};});'use strict';tr.exportTo('tr.ui.b',function(){var BoxChart=tr.ui.b.define('box-chart',tr.ui.b.NameLineChart);BoxChart.prototype={__proto__:tr.ui.b.NameLineChart.prototype,get hideLegend(){return true;},updateDataRange_(){if(this.overrideDataRange_!==undefined){return;}
-this.autoDataRange_.reset();for(var datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateScales_(){super.updateScales_();this.xScale_.domain([0,this.data_.length]);},get xAxisTickOffset(){return 0.5;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;this.autoDataRange_.reset();for(var datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);var baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();var boxesSel=dataSel.selectAll('path');for(var index=0;index<this.data_.length;++index){var datum=this.data_[index];var color=datum.color||'black';var sel=boxesSel.data([datum]);sel.enter().append('rect').attr('fill',color).attr('x',this.xScale_(index+0.2)).attr('width',this.xScale_(index+0.8)-this.xScale_(index+0.2)).attr('y',this.yScale_(datum.percentile_75)).attr('height',this.yScale_(datum.percentile_25)-
-this.yScale_(datum.percentile_75));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index)).attr('x2',this.xScale_(index+1)).attr('y1',this.yScale_(datum.percentile_50)).attr('y2',this.yScale_(datum.percentile_50));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_0)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_100));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.5)).attr('x2',this.xScale_(index+0.5)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();}}};return{BoxChart,};});'use strict';tr.exportTo('tr.ui.b',function(){var BarChart=tr.ui.b.define('bar-chart',tr.ui.b.ColumnChart);BarChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,decorate(){super.decorate();this.verticalScale_=undefined;this.horizontalScale_=undefined;},updateScales_(){super.updateScales_();this.yScale_.range([this.graphWidth,0]);this.xScale_.range([0,this.graphHeight]);this.verticalScale_=this.isYLogScale_?d3.scale.log(10):d3.scale.linear();this.verticalScale_.domain(this.xScale_.domain());this.verticalScale_.range([this.graphHeight,0]);this.horizontalScale_=d3.scale.linear();this.horizontalScale_.domain(this.yScale_.domain());this.horizontalScale_.range([0,this.graphWidth]);},get defaultGraphHeight(){return Math.max(20,10*this.data_.length);},get defaultGraphWidth(){return 100;},get barHeight(){return this.graphHeight/this.data.length;},drawBrush_(brushRectsSel){brushRectsSel.attr('x',0).attr('width',this.graphWidth).attr('y',d=>this.verticalScale_(d.max)).attr('height',d=>this.verticalScale_(d.min)-this.verticalScale_(d.max));},getDataPointAtChartPoint_(chartPoint){var flippedPoint={x:this.graphHeight-chartPoint.y,y:this.graphWidth-chartPoint.x};return super.getDataPointAtChartPoint_(flippedPoint);},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.horizontalScale_).orient('bottom'));},get yAxisWidth(){return this.computeScaleTickWidth_(this.verticalScale_);},drawYAxis_(yAxis){var axisModifier=d3.svg.axis().scale(this.verticalScale_).orient('left');yAxis.call(axisModifier);},drawHoverValueBox_(rect){var rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;var seriesKeys=[...this.seriesByKey_.keys()];var chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();var keyWidthPx=0;var keyHeightPx=0;var xWidthPx=0;var xHeightPx=0;if(seriesKeys.length>1){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width;keyHeightPx=this.textHeightPx_;}
+this.margin.right=Math.max(this.margin.right,xAxisTickOverhangPx);},getXForDatum_(datum,index){return index;},get xAxisTickOffset(){return 0.5;},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;const nameTexts=xAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('transform',(d,index)=>'translate(0, '+
+this.textHeightPx_*(this.data_.length-index)+')').attr('x',(d,index)=>this.xScale_(index)).attr('y',d=>this.graphHeight).text(d=>d.x);nameTexts.exit().remove();const guideLines=xAxis.selectAll('line.guide').data(this.data_);guideLines.enter().append('line').attr('x1',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('x2',(d,index)=>this.xScale_(index+this.xAxisTickOffset)).attr('y1',()=>this.graphHeight).attr('y2',(d,index)=>this.graphHeight+Math.max(MIN_GUIDELINE_HEIGHT_PX,(this.textHeightPx_*(this.data_.length-index-1))));}};return{NameColumnChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const LineChart=tr.ui.b.LineChart;const NameLineChart=tr.ui.b.define('name-line-chart',LineChart);NameLineChart.prototype={__proto__:LineChart.prototype,getXForDatum_(datum,index){return index;},get xAxisHeight(){return 5+(this.textHeightPx_*this.data_.length);},get xAxisTickOffset(){return 0;},updateMargins_(){tr.ui.b.NameColumnChart.prototype.updateMargins_.call(this);},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);const baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length-1)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();}};return{NameLineChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const BoxChart=tr.ui.b.define('box-chart',tr.ui.b.NameLineChart);BoxChart.prototype={__proto__:tr.ui.b.NameLineChart.prototype,get hideLegend(){return true;},updateDataRange_(){if(this.overrideDataRange_!==undefined){return;}
+this.autoDataRange_.reset();for(const datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateScales_(){super.updateScales_();this.xScale_.domain([0,this.data_.length]);},get xAxisTickOffset(){return 0.5;},updateDataRange_(){if(this.overrideDataRange_!==undefined)return;this.autoDataRange_.reset();for(const datum of this.data_){this.autoDataRange_.addValue(datum.percentile_0);this.autoDataRange_.addValue(datum.percentile_100);}},updateXAxis_(xAxis){xAxis.selectAll('*').remove();if(this.hideXAxis)return;tr.ui.b.NameColumnChart.prototype.updateXAxis_.call(this,xAxis);const baseline=xAxis.selectAll('path').data([this]);baseline.enter().append('line').attr('stroke','black').attr('x1',this.xScale_(0)).attr('x2',this.xScale_(this.data_.length)).attr('y1',this.graphHeight).attr('y2',this.graphHeight);baseline.exit().remove();},updateDataContents_(dataSel){dataSel.selectAll('*').remove();const boxesSel=dataSel.selectAll('path');for(let index=0;index<this.data_.length;++index){const datum=this.data_[index];const color=datum.color||'black';let sel=boxesSel.data([datum]);sel.enter().append('rect').attr('fill',color).attr('x',this.xScale_(index+0.2)).attr('width',this.xScale_(index+0.8)-this.xScale_(index+0.2)).attr('y',this.yScale_(datum.percentile_75)).attr('height',this.yScale_(datum.percentile_25)-
+this.yScale_(datum.percentile_75));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index)).attr('x2',this.xScale_(index+1)).attr('y1',this.yScale_(datum.percentile_50)).attr('y2',this.yScale_(datum.percentile_50));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_0)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.4)).attr('x2',this.xScale_(index+0.6)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_100));sel.exit().remove();sel=boxesSel.data([datum]);sel.enter().append('line').attr('stroke',color).attr('x1',this.xScale_(index+0.5)).attr('x2',this.xScale_(index+0.5)).attr('y1',this.yScale_(datum.percentile_100)).attr('y2',this.yScale_(datum.percentile_0));sel.exit().remove();}}};return{BoxChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const BarChart=tr.ui.b.define('bar-chart',tr.ui.b.ColumnChart);BarChart.prototype={__proto__:tr.ui.b.ColumnChart.prototype,decorate(){super.decorate();this.verticalScale_=undefined;this.horizontalScale_=undefined;},updateScales_(){super.updateScales_();this.yScale_.range([this.graphWidth,0]);this.xScale_.range([0,this.graphHeight]);this.verticalScale_=this.isYLogScale_?d3.scale.log(10):d3.scale.linear();this.verticalScale_.domain(this.xScale_.domain());this.verticalScale_.range([this.graphHeight,0]);this.horizontalScale_=d3.scale.linear();this.horizontalScale_.domain(this.yScale_.domain());this.horizontalScale_.range([0,this.graphWidth]);},get defaultGraphHeight(){return Math.max(20,10*this.data_.length);},get defaultGraphWidth(){return 100;},get barHeight(){return this.graphHeight/this.data.length;},drawBrush_(brushRectsSel){brushRectsSel.attr('x',0).attr('width',this.graphWidth).attr('y',d=>this.verticalScale_(d.max)).attr('height',d=>this.verticalScale_(d.min)-this.verticalScale_(d.max));},getDataPointAtChartPoint_(chartPoint){const flippedPoint={x:this.graphHeight-chartPoint.y,y:this.graphWidth-chartPoint.x};return super.getDataPointAtChartPoint_(flippedPoint);},drawXAxis_(xAxis){xAxis.attr('transform','translate(0,'+this.graphHeight+')').call(d3.svg.axis().scale(this.horizontalScale_).orient('bottom'));},get yAxisWidth(){return this.computeScaleTickWidth_(this.verticalScale_);},drawYAxis_(yAxis){const axisModifier=d3.svg.axis().scale(this.verticalScale_).orient('left');yAxis.call(axisModifier);},drawHoverValueBox_(rect){const rectHoverEvent=new tr.b.Event('rect-mouseenter');rectHoverEvent.rect=rect;this.dispatchEvent(rectHoverEvent);if(!this.enableHoverBox)return;const seriesKeys=[...this.seriesByKey_.keys()];const chartAreaSel=d3.select(this.chartAreaElement);chartAreaSel.selectAll('.hover').remove();let keyWidthPx=0;let keyHeightPx=0;let xWidthPx=0;let xHeightPx=0;if(seriesKeys.length>1){keyWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.key).width;keyHeightPx=this.textHeightPx_;}
 if(this.data.length>1){xWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,''+rect.datum.x).width;xHeightPx=this.textHeightPx_;}
-var valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.value).width;var valueHeightPx=this.textHeightPx_;var hoverWidthPx=Math.min(Math.max(keyWidthPx,xWidthPx,valueWidthPx)+5,Math.max(50,rect.widthPx));var hoverTopPx=rect.topPx+(rect.heightPx/2);var hoverLeftPx=rect.leftPx+rect.widthPx-hoverWidthPx;chartAreaSel.append('rect').attr('class','hover').attr('fill','white').attr('x',hoverLeftPx).attr('y',hoverTopPx).attr('width',hoverWidthPx).attr('height',keyHeightPx+xHeightPx+valueHeightPx);if(seriesKeys.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx-3).text(rect.key);}
+const valueWidthPx=tr.ui.b.getSVGTextSize(this.chartAreaElement,rect.value).width;const valueHeightPx=this.textHeightPx_;const hoverWidthPx=Math.min(Math.max(keyWidthPx,xWidthPx,valueWidthPx)+5,Math.max(50,rect.widthPx));const hoverTopPx=rect.topPx+(rect.heightPx/2);const hoverLeftPx=rect.leftPx+rect.widthPx-hoverWidthPx;chartAreaSel.append('rect').attr('class','hover').attr('fill','white').attr('x',hoverLeftPx).attr('y',hoverTopPx).attr('width',hoverWidthPx).attr('height',keyHeightPx+xHeightPx+valueHeightPx);if(seriesKeys.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx-3).text(rect.key);}
 if(this.data.length>1){chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+keyHeightPx+valueHeightPx-3).text(''+rect.datum.x);}
-chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+xHeightPx+keyHeightPx+valueHeightPx-3).text(rect.value);},flipRect_(rect){return{datum:rect.datum,index:rect.index,key:rect.key,value:rect.value,color:rect.color,topPx:this.graphHeight-rect.leftPx-rect.widthPx,leftPx:this.graphWidth-rect.topPx-rect.heightPx,widthPx:rect.heightPx,heightPx:rect.widthPx,underflow:rect.underflow,overflow:rect.overflow,};},drawRect_(rect,sel){super.drawRect_(this.flipRect_(rect),sel);},drawUnderflow_(rect,rectsSel){var sel=rectsSel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',0).attr('y',this.graphHeight-rect.leftPx+
+chartAreaSel.append('text').attr('class','hover').attr('fill',rect.color).attr('x',hoverLeftPx+2).attr('y',hoverTopPx+xHeightPx+keyHeightPx+valueHeightPx-3).text(rect.value);},flipRect_(rect){return{datum:rect.datum,index:rect.index,key:rect.key,value:rect.value,color:rect.color,topPx:this.graphHeight-rect.leftPx-rect.widthPx,leftPx:this.graphWidth-rect.topPx-rect.heightPx,widthPx:rect.heightPx,heightPx:rect.widthPx,underflow:rect.underflow,overflow:rect.overflow,};},drawRect_(rect,sel){super.drawRect_(this.flipRect_(rect),sel);},drawUnderflow_(rect,rectsSel){let sel=rectsSel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',0).attr('y',this.graphHeight-rect.leftPx+
 3+(rect.widthPx/2));sel.exit().remove();sel=rectsSel.data([rect]);sel.enter().append('rect').attr('fill','rgba(0, 0, 0, 0)').attr('x',0).attr('y',this.graphHeight-rect.leftPx-rect.widthPx).attr('width',10).attr('height',rect.widthPx).on('mouseenter',()=>this.drawHoverValueBox_(this.flipRect_(rect))).on('mouseleave',()=>this.clearHoverValueBox_(rect));sel.exit().remove();},drawOverflow_(rect,sel){sel=sel.data([rect]);sel.enter().append('text').text('*').attr('fill',rect.color).attr('x',this.graphWidth).attr('y',this.graphHeight-rect.leftPx+
-3+(rect.widthPx/2));sel.exit().remove();}};return{BarChart,};});'use strict';tr.exportTo('tr.ui.b',function(){var NameBarChart=tr.ui.b.define('name-bar-chart',tr.ui.b.BarChart);var Y_AXIS_PADDING=2;NameBarChart.prototype={__proto__:tr.ui.b.BarChart.prototype,getDataPointAtChartPoint_(chartPoint){return{x:tr.ui.b.BarChart.prototype.getDataPointAtChartPoint_.call(this,chartPoint).x,y:parseInt(Math.floor((this.graphHeight-chartPoint.y)/this.barHeight))};},getXForDatum_(datum,index){return index;},get yAxisWidth(){if(this.data.length===0)return 0;return Y_AXIS_PADDING+tr.b.math.Statistics.max(this.data_,d=>tr.ui.b.getSVGTextSize(this,d.x).width);},get defaultGraphHeight(){return(3+this.textHeightPx_)*this.data.length;},updateYAxis_(yAxis){if(tr.ui.b.getSVGTextSize(this,'test').width===0){tr.b.requestAnimationFrame(()=>this.updateYAxis_(yAxis));return;}
-yAxis.selectAll('*').remove();var nameTexts=yAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('x',d=>-(tr.ui.b.getSVGTextSize(this,d.x).width+Y_AXIS_PADDING)).attr('y',(d,index)=>this.verticalScale_(index)).text(d=>d.x);nameTexts.exit().remove();var previousTop=undefined;for(var text of nameTexts[0]){var bbox=text.getBBox();if((previousTop===undefined)||(previousTop>(bbox.y+bbox.height))){previousTop=bbox.y;}else{text.style.opacity=0;}}}};return{NameBarChart,};});'use strict';const DEFAULT_COLOR_SCHEME=new tr.b.SinebowColorGenerator();class BreakdownTableSummaryRow{constructor(displayElement,histogramNames){this.displayElement_=displayElement;this.histogramNames_=histogramNames;this.keySpan_=undefined;}
+3+(rect.widthPx/2));sel.exit().remove();}};return{BarChart,};});'use strict';tr.exportTo('tr.ui.b',function(){const NameBarChart=tr.ui.b.define('name-bar-chart',tr.ui.b.BarChart);const Y_AXIS_PADDING=2;NameBarChart.prototype={__proto__:tr.ui.b.BarChart.prototype,getDataPointAtChartPoint_(chartPoint){return{x:tr.ui.b.BarChart.prototype.getDataPointAtChartPoint_.call(this,chartPoint).x,y:parseInt(Math.floor((this.graphHeight-chartPoint.y)/this.barHeight))};},getXForDatum_(datum,index){return index;},get yAxisWidth(){if(this.data.length===0)return 0;return Y_AXIS_PADDING+tr.b.math.Statistics.max(this.data_,d=>tr.ui.b.getSVGTextSize(this,d.x).width);},get defaultGraphHeight(){return(3+this.textHeightPx_)*this.data.length;},updateYAxis_(yAxis){if(tr.ui.b.getSVGTextSize(this,'test').width===0){tr.b.requestAnimationFrame(()=>this.updateYAxis_(yAxis));return;}
+yAxis.selectAll('*').remove();const nameTexts=yAxis.selectAll('text').data(this.data_);nameTexts.enter().append('text').attr('x',d=>-(tr.ui.b.getSVGTextSize(this,d.x).width+Y_AXIS_PADDING)).attr('y',(d,index)=>this.verticalScale_(index)).text(d=>d.x);nameTexts.exit().remove();let previousTop=undefined;for(const text of nameTexts[0]){const bbox=text.getBBox();if((previousTop===undefined)||(previousTop>(bbox.y+bbox.height))){previousTop=bbox.y;}else{text.style.opacity=0;}}}};return{NameBarChart,};});'use strict';const DEFAULT_COLOR_SCHEME=new tr.b.SinebowColorGenerator();class BreakdownTableSummaryRow{constructor(displayElement,histogramNames){this.displayElement_=displayElement;this.histogramNames_=histogramNames;this.keySpan_=undefined;}
 get numberValue(){return undefined;}
 get keySpan(){if(this.keySpan_===undefined){if(this.histogramNames_.length){this.keySpan_=document.createElement('tr-ui-a-analysis-link');this.keySpan_.setSelectionAndContent(this.histogramNames_,'Select All');}else{this.keySpan_='Sum';}}
 return this.keySpan_;}
 get displayElement(){return this.displayElement_;}
 get stringPercent(){return'100%';}}
 class BreakdownTableRow{constructor(name,value,color){this.name_=name;this.value=value;if(!this.isHistogram&&typeof value!=='number'){throw new Error('unsupported value '+value);}
-this.tableSum_=undefined;this.keySpan_=undefined;this.color_=color;let hsl=this.color.toHSL();hsl.l*=0.85;this.highlightedColor_=tr.b.Color.fromHSL(hsl);}
+this.tableSum_=undefined;this.keySpan_=undefined;this.color_=color;const hsl=this.color.toHSL();hsl.l*=0.85;this.highlightedColor_=tr.b.Color.fromHSL(hsl);}
 get isHistogram(){return this.value instanceof tr.v.Histogram;}
 get name(){return this.name_;}
 get color(){return this.color_;}
@@ -8431,7 +8821,7 @@
 get numberValue(){if(this.isHistogram)return this.value.sum;if(!isNaN(this.value)&&(this.value!==Infinity)&&(this.value!==-Infinity)&&(this.value>0))return this.value;return undefined;}
 get stringValue(){if(this.numberValue===undefined)return this.value.toString();return this.numberValue.toString();}
 set tableSum(s){this.tableSum_=s;}
-get stringPercent(){if(this.tableSum_===undefined)return'';let num=this.numberValue;if(num===undefined)return'';return Math.floor(num*100.0/this.tableSum_)+'%';}
+get stringPercent(){if(this.tableSum_===undefined)return'';const num=this.numberValue;if(num===undefined)return'';return Math.floor(num*100.0/this.tableSum_)+'%';}
 get displayElement(){if(this.numberValue===undefined)return this.value.toString();if(this.isHistogram){return tr.v.ui.createScalarSpan(this.numberValue,{unit:this.value.unit,});}
 return this.numberValue;}
 compare(other){if(this.numberValue===undefined){if(other.numberValue===undefined){return this.name.localeCompare(other.name);}
@@ -8439,24 +8829,24 @@
 if(other.numberValue===undefined){return-1;}
 if(this.numberValue===other.numberValue){return this.name.localeCompare(other.name);}
 return other.numberValue-this.numberValue;}}
-Polymer({is:'tr-v-ui-breakdown-span',created(){this.diagnostic_=undefined;this.chart_=new tr.ui.b.ColumnChart();this.chart_.graphHeight=130;this.chart_.isStacked=true;this.chart_.hideXAxis=true;this.chart_.hideLegend=true;this.chart_.enableHoverBox=false;this.chart_.addEventListener('rect-mouseenter',event=>this.onRectMouseEnter_(event));this.chart_.addEventListener('rect-mouseleave',event=>this.onRectMouseLeave_(event));},onRectMouseEnter_(event){for(let row of this.$.table.tableRows){if(row.name===event.rect.key){row.keySpan.parentNode.nextSibling.style.background=event.rect.color;row.keySpan.scrollIntoViewIfNeeded();}else{row.keySpan.parentNode.nextSibling.style.background='';}}},onRectMouseLeave_(event){for(let row of this.$.table.tableRows){row.keySpan.parentNode.nextSibling.style.background='';}},ready(){Polymer.dom(this.$.container).appendChild(this.chart_);this.$.table.zebra=true;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row.keySpan,},{value:row=>row.displayElement,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},{value:row=>row.stringPercent,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},];},attached(){if(this.diagnostic_)this.updateContents_();},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;if(this.isAttached)this.updateContents_();},updateContents_(){this.$.container.style.display='none';this.$.table.style.display='none';this.$.empty.style.display='block';if(!this.diagnostic_){this.chart_.data=[];return;}
+Polymer({is:'tr-v-ui-breakdown-span',created(){this.diagnostic_=undefined;this.chart_=new tr.ui.b.ColumnChart();this.chart_.graphHeight=130;this.chart_.isStacked=true;this.chart_.hideXAxis=true;this.chart_.hideLegend=true;this.chart_.enableHoverBox=false;this.chart_.addEventListener('rect-mouseenter',event=>this.onRectMouseEnter_(event));this.chart_.addEventListener('rect-mouseleave',event=>this.onRectMouseLeave_(event));},onRectMouseEnter_(event){for(const row of this.$.table.tableRows){if(row.name===event.rect.key){row.keySpan.parentNode.nextSibling.style.background=event.rect.color;row.keySpan.scrollIntoViewIfNeeded();}else{row.keySpan.parentNode.nextSibling.style.background='';}}},onRectMouseLeave_(event){for(const row of this.$.table.tableRows){row.keySpan.parentNode.nextSibling.style.background='';}},ready(){Polymer.dom(this.$.container).appendChild(this.chart_);this.$.table.zebra=true;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row.keySpan,},{value:row=>row.displayElement,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},{value:row=>row.stringPercent,align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,},];},attached(){if(this.diagnostic_)this.updateContents_();},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;if(this.isAttached)this.updateContents_();},updateContents_(){this.$.container.style.display='none';this.$.table.style.display='none';this.$.empty.style.display='block';if(!this.diagnostic_){this.chart_.data=[];return;}
 let colorScheme=undefined;if(this.diagnostic.colorScheme===tr.v.d.COLOR_SCHEME_CHROME_USER_FRIENDLY_CATEGORY_DRIVER){colorScheme=(name)=>{let cat=name.split(' ');cat=cat[cat.length-1];return tr.e.chrome.ChromeUserFriendlyCategoryDriver.getColor(cat);};}else if(this.diagnostic.colorScheme!==undefined){colorScheme=(name)=>tr.b.FixedColorSchemeRegistry.lookUp(this.diagnostic.colorScheme).getColor(name);}else{colorScheme=(name)=>DEFAULT_COLOR_SCHEME.colorForKey(name);}
-let tableRows=[];let tableSum=0;let histogramNames=[];let unit=undefined;for(let[name,value]of this.diagnostic){let row=new BreakdownTableRow(name,value,colorScheme(name));tableRows.push(row);if(row.numberValue!==undefined)tableSum+=row.numberValue;if(row.isHistogram){histogramNames.push(value.name);if(unit===undefined)unit=value.unit;}}
+const tableRows=[];let tableSum=0;const histogramNames=[];let unit=undefined;for(const[name,value]of this.diagnostic){const row=new BreakdownTableRow(name,value,colorScheme(name));tableRows.push(row);if(row.numberValue!==undefined)tableSum+=row.numberValue;if(row.isHistogram){histogramNames.push(value.name);if(unit===undefined)unit=value.unit;}}
 tableRows.sort((x,y)=>x.compare(y));if(tableSum>0){let summaryDisplayElement=tableSum;if(unit!==undefined){summaryDisplayElement=unit.format(tableSum);}
 tableRows.unshift(new BreakdownTableSummaryRow(summaryDisplayElement,histogramNames));}
-let chartData={x:0};for(let row of tableRows){if(row.numberValue===undefined)continue;row.tableSum=tableSum;chartData[row.name]=row.numberValue;let dataSeries=this.chart_.getDataSeries(row.name);dataSeries.color=row.color;dataSeries.highlightedColor=row.highlightedColor;}
+const chartData={x:0};for(const row of tableRows){if(row.numberValue===undefined)continue;row.tableSum=tableSum;chartData[row.name]=row.numberValue;const dataSeries=this.chart_.getDataSeries(row.name);dataSeries.color=row.color;dataSeries.highlightedColor=row.highlightedColor;}
 if(tableRows.length>0){this.$.table.style.display='block';this.$.empty.style.display='none';this.$.table.tableRows=tableRows;this.$.table.rebuild();}
-if(tr.b.dictionaryLength(chartData)>1){this.$.container.style.display='block';this.$.empty.style.display='none';this.chart_.data=[chartData];}}});'use strict';Polymer({is:'tr-v-ui-buildbot-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]}];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.displayMasterName){rows.push(['master',this.diagnostic.displayMasterName]);}
+if(Object.keys(chartData).length>1){this.$.container.style.display='block';this.$.empty.style.display='none';this.chart_.data=[chartData];}}});'use strict';Polymer({is:'tr-v-ui-buildbot-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]}];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
+const rows=[];if(this.diagnostic.displayMasterName){rows.push(['master',this.diagnostic.displayMasterName]);}
 if(this.diagnostic.buildbotMasterName){rows.push(['master',this.diagnostic.buildbotMasterName]);}
 if(this.diagnostic.displayBotName){rows.push(['bot',this.diagnostic.displayBotName]);}
 if(this.diagnostic.buildbotName){rows.push(['bot',this.diagnostic.buildbotName]);}
 if(this.diagnostic.buildNumber){rows.push(['build number',this.diagnostic.buildNumber]);}
-if(this.diagnostic.logUri){let anchor=document.createElement('a');anchor.href=this.diagnostic.logUri;anchor.innerText=this.diagnostic.logUri;rows.push(['log',anchor]);}
-this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-collected-related-event-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';for(let[canonicalUrl,events]of this.diagnostic){let link=document.createElement('a');if(events.length===1){let event=tr.b.getOnlyElement(events);link.textContent=event.title+' '+
+if(this.diagnostic.logUri){const anchor=document.createElement('a');anchor.href=this.diagnostic.logUri;anchor.innerText=this.diagnostic.logUri;rows.push(['log',anchor]);}
+this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-collected-related-event-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';for(const[canonicalUrl,events]of this.diagnostic){const link=document.createElement('a');if(events.length===1){const event=tr.b.getOnlyElement(events);link.textContent=event.title+' '+
 tr.b.Unit.byName.timeDurationInMs.format(event.duration);}else{link.textContent=events.length+' events';}
 link.href=canonicalUrl;Polymer.dom(this).appendChild(link);Polymer.dom(this).appendChild(document.createElement('br'));}}});'use strict';Polymer({is:'tr-v-ui-device-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value(row){return row[0];},},{value(row){return row[1];}}];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.chromeVersion){rows.push(['chrome version',this.diagnostic.chromeVersion]);}
+const rows=[];if(this.diagnostic.chromeVersion){rows.push(['chrome version',this.diagnostic.chromeVersion]);}
 if(this.diagnostic.osName){rows.push(['OS name',this.diagnostic.osName]);}
 if(this.diagnostic.osVersion){rows.push(['OS version',this.diagnostic.osVersion]);}
 if(this.diagnostic.gpuInfo){rows.push(['GPU',JSON.stringify(this.diagnostic.gpuInfo)]);}
@@ -8464,479 +8854,519 @@
 if(this.diagnostic.ram){rows.push(['ram',tr.b.Unit.byName.sizeInBytes.format(this.diagnostic.ram)]);}
 this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-generic-diagnostic-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.generic.object=undefined;return;}
 this.$.generic.object=this.diagnostic.value;}});'use strict';Polymer({is:'tr-v-ui-merged-buildbot-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.displayMasterNames.size){rows.push(['masters',Array.from(this.diagnostic.displayMasterNames).join(', ')]);}
+const rows=[];if(this.diagnostic.displayMasterNames.size){rows.push(['masters',Array.from(this.diagnostic.displayMasterNames).join(', ')]);}
 if(this.diagnostic.displayBotNames.size){rows.push(['bots',Array.from(this.diagnostic.displayBotNames).join(', ')]);}
 if(this.diagnostic.buildNumbers.size){rows.push(['builds',Array.from(this.diagnostic.buildNumbers).join(', ')]);}
-for(let logUri of this.diagnostic.logUris){let anchor=document.createElement('a');anchor.href=logUri;anchor.innerText=logUri;rows.push(['log',anchor]);}
+for(const logUri of this.diagnostic.logUris){const anchor=document.createElement('a');anchor.href=logUri;anchor.innerText=logUri;rows.push(['log',anchor]);}
 this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-merged-device-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.chromeVersions.size){rows.push(['chrome versions',Array.from(this.diagnostic.chromeVersions).join(', ')]);}
+const rows=[];if(this.diagnostic.chromeVersions.size){rows.push(['chrome versions',Array.from(this.diagnostic.chromeVersions).join(', ')]);}
 if(this.diagnostic.osNames.size){rows.push(['os names',Array.from(this.diagnostic.osNames).join(', ')]);}
 if(this.diagnostic.osVersions.size){rows.push(['os versions',Array.from(this.diagnostic.osVersions).join(', ')]);}
-this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-merged-revision-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},buildRow_(rows,label,revisions,host){if(revisions.length===0)return;let valueSpan=document.createElement('span');for(let revs of revisions){let anchor=document.createElement('a');anchor.innerText=revs[0];if(revs.length===1){anchor.href=host+'+/'+revs[0];}else{anchor.innerText+='..'+revs[1];anchor.href=host+'+log/'+revs[0]+'..'+revs[1];}
+this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-merged-revision-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},buildRow_(rows,label,revisions,host){if(revisions.length===0)return;const valueSpan=document.createElement('span');for(const revs of revisions){const anchor=document.createElement('a');anchor.innerText=revs[0];if(revs.length===1){anchor.href=host+'+/'+revs[0];}else{anchor.innerText+='..'+revs[1];anchor.href=host+'+log/'+revs[0]+'..'+revs[1];}
 anchor.addEventListener('click',event=>{event.stopPropagation();});valueSpan.appendChild(anchor);valueSpan.appendChild(document.createTextNode(' '));}
 rows.push([label,valueSpan]);},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.chromiumCommitPosition){let positions=Array.from(this.diagnostic.chromiumCommitPositions);positions.sort((x,y)=>x-y);rows.push(['chromiumCommitPositions',positions.join(', ')]);}
-if(this.diagnostic.v8CommitPosition){let positions=Array.from(this.diagnostic.v8CommitPositions);rows.push(['v8CommitPositions',positions.join(', ')]);}
+const rows=[];if(this.diagnostic.chromiumCommitPosition){const positions=Array.from(this.diagnostic.chromiumCommitPositions);positions.sort((x,y)=>x-y);rows.push(['chromiumCommitPositions',positions.join(', ')]);}
+if(this.diagnostic.v8CommitPosition){const positions=Array.from(this.diagnostic.v8CommitPositions);rows.push(['v8CommitPositions',positions.join(', ')]);}
 this.buildRow_(rows,'chromium',this.diagnostic.chromium,tr.v.ui.CHROMIUM_REVISION_HOST);this.buildRow_(rows,'v8',this.diagnostic.v8,tr.v.ui.V8_REVISION_HOST);this.buildRow_(rows,'catapult',this.diagnostic.catapult,tr.v.ui.CATAPULT_REVISION_HOST);this.buildRow_(rows,'angle',this.diagnostic.angle,tr.v.ui.ANGLE_REVISION_HOST);this.buildRow_(rows,'skia',this.diagnostic.skia,tr.v.ui.SKIA_REVISION_HOST);this.buildRow_(rows,'webrtc',this.diagnostic.webrtc,tr.v.ui.WEBRTC_REVISION_HOST);this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-merged-telemetry-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},onShow_(){this.$.show.style.display='none';this.$.hide.style.display='block';this.$.table.style.display='table';},onHide_(){this.$.show.style.display='block';this.$.hide.style.display='none';this.$.table.style.display='none';},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.benchmarkNames.size){rows.push(['benchmark names',Array.from(this.diagnostic.benchmarkNames).join(', ')]);}
+const rows=[];if(this.diagnostic.benchmarkNames.size){rows.push(['benchmark names',Array.from(this.diagnostic.benchmarkNames).join(', ')]);}
 if(this.diagnostic.benchmarkStarts.length){rows.push(['benchmark starts',this.diagnostic.benchmarkStartStrings.join(', ')]);}
 if(this.diagnostic.storyDisplayNames.size){rows.push(['stories',Array.from(this.diagnostic.storyDisplayNames).join(', ')]);}
 if(this.diagnostic.storysetRepeatCounters.size){rows.push(['storyset repeats',Array.from(this.diagnostic.storysetRepeatCounters).join(', ')]);}
 if(this.diagnostic.labels.size){rows.push(['label',Array.from(this.diagnostic.labels).join(', ')]);}
-if(this.diagnostic.storyGroupingKeys.size){let gov=document.createElement('tr-ui-a-generic-object-view');let obj={};for(let[key,value]of this.diagnostic.storyGroupingKeys){obj[key]=Array.from(value);}
+if(this.diagnostic.storyGroupingKeys.size){const gov=document.createElement('tr-ui-a-generic-object-view');const obj={};for(const[key,value]of this.diagnostic.storyGroupingKeys){obj[key]=Array.from(value);}
 gov.object=obj;rows.push(['grouping keys',gov]);}
-this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-related-event-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';let events=new tr.model.EventSet([...this.diagnostic]);let link=document.createElement('tr-ui-a-analysis-link');let label=events.length+' events';if(events.length===1){let event=tr.b.getOnlyElement(events);label=event.title+' ';label+=tr.b.Unit.byName.timeDurationInMs.format(event.duration);}
-link.setSelectionAndContent(events,label);Polymer.dom(this).appendChild(link);}});'use strict';Polymer({is:'tr-v-ui-related-histogram-map-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';let rows=[];let histogramNames=new Set();for(let[name,hist]of this.diagnostic){histogramNames.add(hist.name);}
-if(histogramNames.size>1){let link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent(Array.from(histogramNames),'Select All');rows.push([link,'']);}
-for(let[name,hist]of this.diagnostic){let link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent([hist.name],name);let scalarSpan=tr.v.ui.createScalarSpan(hist);rows.push([link,scalarSpan]);}
-this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-related-histogram-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},addLink_(selection,content){let link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent(selection,content);Polymer.dom(this).appendChild(link);Polymer.dom(this).appendChild(document.createElement('br'));},updateContents_(){Polymer.dom(this).textContent='';let histogramNames=new Set();for(let hist of this.diagnostic){histogramNames.add(hist.name);}
+this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-related-event-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';const events=new tr.model.EventSet([...this.diagnostic]);const link=document.createElement('tr-ui-a-analysis-link');let label=events.length+' events';if(events.length===1){const event=tr.b.getOnlyElement(events);label=event.title+' ';label+=tr.b.Unit.byName.timeDurationInMs.format(event.duration);}
+link.setSelectionAndContent(events,label);Polymer.dom(this).appendChild(link);}});'use strict';Polymer({is:'tr-v-ui-related-histogram-map-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';const rows=[];const histogramNames=new Set();for(const[name,hist]of this.diagnostic){histogramNames.add(hist.name);}
+if(histogramNames.size>1){const link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent(Array.from(histogramNames),'Select All');rows.push([link,'']);}
+for(const[name,hist]of this.diagnostic){const link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent([hist.name],name);const scalarSpan=tr.v.ui.createScalarSpan(hist);rows.push([link,scalarSpan]);}
+this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-related-histogram-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},addLink_(selection,content){const link=document.createElement('tr-ui-a-analysis-link');link.setSelectionAndContent(selection,content);Polymer.dom(this).appendChild(link);Polymer.dom(this).appendChild(document.createElement('br'));},updateContents_(){Polymer.dom(this).textContent='';const histogramNames=new Set();for(const hist of this.diagnostic){histogramNames.add(hist.name);}
 if(histogramNames.size>1){this.addLink_(Array.from(histogramNames),'Select All');}
-for(let hist of this.diagnostic){this.addLink_([hist.name],hist.name);}}});'use strict';tr.exportTo('tr.v.ui',function(){const CHROMIUM_REVISION_HOST='https://chromium.googlesource.com/chromium/src/';const V8_REVISION_HOST='https://chromium.googlesource.com/v8/v8.git/';const CATAPULT_REVISION_HOST='https://chromium.googlesource.com/external/github.com/catapult-project/catapult.git/';const ANGLE_REVISION_HOST='https://chromium.googlesource.com/angle/angle/';const SKIA_REVISION_HOST='https://chromium.googlesource.com/skia/';const WEBRTC_REVISION_HOST='https://chromium.googlesource.com/external/webrtc/';Polymer({is:'tr-v-ui-revision-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},buildRow_(rows,label,revisions,host){if(revisions.length===0)return;let anchor=document.createElement('a');anchor.innerText=revisions[0];if(revisions.length===1){anchor.href=host+'+/'+revisions[0];}else{anchor.innerText+='..'+revisions[1];anchor.href=host+'+log/'+revisions[0]+'..'+revisions[1];}
+for(const hist of this.diagnostic){this.addLink_([hist.name],hist.name);}}});'use strict';tr.exportTo('tr.v.ui',function(){const CHROMIUM_REVISION_HOST='https://chromium.googlesource.com/chromium/src/';const V8_REVISION_HOST='https://chromium.googlesource.com/v8/v8.git/';const CATAPULT_REVISION_HOST='https://chromium.googlesource.com/external/github.com/catapult-project/catapult.git/';const ANGLE_REVISION_HOST='https://chromium.googlesource.com/angle/angle/';const SKIA_REVISION_HOST='https://chromium.googlesource.com/skia/';const WEBRTC_REVISION_HOST='https://chromium.googlesource.com/external/webrtc/';Polymer({is:'tr-v-ui-revision-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},buildRow_(rows,label,revisions,host){if(revisions.length===0)return;const anchor=document.createElement('a');anchor.innerText=revisions[0];if(revisions.length===1){anchor.href=host+'+/'+revisions[0];}else{anchor.innerText+='..'+revisions[1];anchor.href=host+'+log/'+revisions[0]+'..'+revisions[1];}
 anchor.addEventListener('click',event=>{event.stopPropagation();});rows.push([label,anchor]);},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.chromiumCommitPosition){rows.push(['chromiumCommitPosition',this.diagnostic.chromiumCommitPosition]);}
+const rows=[];if(this.diagnostic.chromiumCommitPosition){rows.push(['chromiumCommitPosition',this.diagnostic.chromiumCommitPosition]);}
 if(this.diagnostic.v8CommitPosition){rows.push(['v8CommitPosition',this.diagnostic.v8CommitPosition]);}
-this.buildRow_(rows,'chromium',this.diagnostic.chromium,CHROMIUM_REVISION_HOST);this.buildRow_(rows,'v8',this.diagnostic.v8,V8_REVISION_HOST);this.buildRow_(rows,'catapult',this.diagnostic.catapult,CATAPULT_REVISION_HOST);this.buildRow_(rows,'angle',this.diagnostic.angle,ANGLE_REVISION_HOST);this.buildRow_(rows,'skia',this.diagnostic.skia,SKIA_REVISION_HOST);this.buildRow_(rows,'webrtc',this.diagnostic.webrtc,WEBRTC_REVISION_HOST);this.$.table.tableRows=rows;}});return{CHROMIUM_REVISION_HOST,V8_REVISION_HOST,CATAPULT_REVISION_HOST,ANGLE_REVISION_HOST,SKIA_REVISION_HOST,WEBRTC_REVISION_HOST,};});'use strict';Polymer({is:'tr-v-ui-scalar-diagnostic-span',ready:function(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_:function(){this.$.scalar.setValueAndUnit(this.diagnostic.value.value,this.diagnostic.value.unit);}});'use strict';Polymer({is:'tr-v-ui-telemetry-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
-let rows=[];if(this.diagnostic.benchmarkName){rows.push(['benchmark name',this.diagnostic.benchmarkName]);}
+this.buildRow_(rows,'chromium',this.diagnostic.chromium,CHROMIUM_REVISION_HOST);this.buildRow_(rows,'v8',this.diagnostic.v8,V8_REVISION_HOST);this.buildRow_(rows,'catapult',this.diagnostic.catapult,CATAPULT_REVISION_HOST);this.buildRow_(rows,'angle',this.diagnostic.angle,ANGLE_REVISION_HOST);this.buildRow_(rows,'skia',this.diagnostic.skia,SKIA_REVISION_HOST);this.buildRow_(rows,'webrtc',this.diagnostic.webrtc,WEBRTC_REVISION_HOST);this.$.table.tableRows=rows;}});return{CHROMIUM_REVISION_HOST,V8_REVISION_HOST,CATAPULT_REVISION_HOST,ANGLE_REVISION_HOST,SKIA_REVISION_HOST,WEBRTC_REVISION_HOST,};});'use strict';Polymer({is:'tr-v-ui-scalar-diagnostic-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){this.$.scalar.setValueAndUnit(this.diagnostic.value.value,this.diagnostic.value.unit);}});'use strict';Polymer({is:'tr-v-ui-telemetry-info-span',ready(){this.diagnostic_=undefined;this.$.table.showHeader=false;this.$.table.tableColumns=[{value:row=>row[0]},{value:row=>row[1]},];},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){if(this.diagnostic===undefined){this.$.table.tableRows=[];return;}
+const rows=[];if(this.diagnostic.benchmarkName){rows.push(['benchmark name',this.diagnostic.benchmarkName]);}
 if(this.diagnostic.benchmarkStart){rows.push(['benchmark start',this.diagnostic.benchmarkStartString]);}
 if(this.diagnostic.storyDisplayName){rows.push(['story',this.diagnostic.storyDisplayName]);}
 if(this.diagnostic.storysetRepeatCounter!==undefined){rows.push(['storyset repeat',this.diagnostic.storysetRepeatCounter]);}
 if(this.diagnostic.label){rows.push(['label',this.diagnostic.label]);}
-if(this.diagnostic.storyGroupingKeys.size){let gov=document.createElement('tr-ui-a-generic-object-view');let obj={};for(let[key,value]of this.diagnostic.storyGroupingKeys){obj[key]=value;}
+if(this.diagnostic.storyGroupingKeys.size){const gov=document.createElement('tr-ui-a-generic-object-view');const obj={};for(const[key,value]of this.diagnostic.storyGroupingKeys){obj[key]=value;}
 gov.object=obj;rows.push(['grouping keys',gov]);}
-this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-unmergeable-diagnostic-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';for(let diagnostic of this.diagnostic){Polymer.dom(this).appendChild(tr.v.ui.createDiagnosticSpan(diagnostic));Polymer.dom(this).appendChild(document.createElement('br'));}}});'use strict';tr.exportTo('tr.v.ui',function(){function findElementNameForDiagnostic(diagnostic){let typeInfo=undefined;let curProto=diagnostic.constructor.prototype;while(curProto){typeInfo=tr.v.d.Diagnostic.findTypeInfo(curProto.constructor);if(typeInfo&&typeInfo.metadata.elementName)break;typeInfo=undefined;curProto=curProto.__proto__;}
+this.$.table.tableRows=rows;}});'use strict';Polymer({is:'tr-v-ui-unmergeable-diagnostic-set-span',ready(){this.diagnostic_=undefined;},get diagnostic(){return this.diagnostic_;},set diagnostic(d){this.diagnostic_=d;this.updateContents_();},updateContents_(){Polymer.dom(this).textContent='';for(const diagnostic of this.diagnostic){Polymer.dom(this).appendChild(tr.v.ui.createDiagnosticSpan(diagnostic));Polymer.dom(this).appendChild(document.createElement('br'));}}});'use strict';tr.exportTo('tr.v.ui',function(){function findElementNameForDiagnostic(diagnostic){let typeInfo=undefined;let curProto=diagnostic.constructor.prototype;while(curProto){typeInfo=tr.v.d.Diagnostic.findTypeInfo(curProto.constructor);if(typeInfo&&typeInfo.metadata.elementName)break;typeInfo=undefined;curProto=curProto.__proto__;}
 if(typeInfo===undefined){throw new Error(diagnostic.constructor.name+' or a base class must have a registered elementName');}
-let tagName=typeInfo.metadata.elementName;if(tr.ui.b.isUnknownElementName(tagName)){throw new Error('Element not registered: '+tagName);}
+const tagName=typeInfo.metadata.elementName;if(tr.ui.b.isUnknownElementName(tagName)){throw new Error('Element not registered: '+tagName);}
 return tagName;}
-function createDiagnosticSpan(diagnostic){let tagName=findElementNameForDiagnostic(diagnostic);let span=document.createElement(tagName);span.diagnostic=diagnostic;return span;}
+function createDiagnosticSpan(diagnostic){const tagName=findElementNameForDiagnostic(diagnostic);const span=document.createElement(tagName);span.diagnostic=diagnostic;return span;}
 return{createDiagnosticSpan,};});'use strict';Polymer({is:'tr-v-ui-diagnostic-map-table',created(){this.diagnosticMaps_=undefined;},set diagnosticMaps(maps){this.diagnosticMaps_=maps;this.updateContents_();},updateContents_(){if(this.diagnosticMaps_===undefined||this.diagnosticMaps_.length===0){this.$.table.tableRows=[];this.$.table.tableColumns=[];return;}
-let columnTitles=new Set();for(let map of this.diagnosticMaps_){for(let[name,diagnostic]of map){if(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)continue;if(diagnostic instanceof tr.v.d.CollectedRelatedEventSet)continue;if(diagnostic instanceof tr.v.d.GroupingPath)continue;columnTitles.add(name);}}
-let columns=[];function makeColumn(title){return{title:title,value(map){let diagnostic=map.get(title);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic);}};}
-for(let title of columnTitles){columns.push(makeColumn(title));}
-this.$.table.tableColumns=columns;this.$.table.tableRows=this.diagnosticMaps_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-scalar-map-table',created:function(){this.scalarMap_=new Map();this.significance_=new Map();},ready:function(){this.$.table.showHeader=false;this.$.table.tableColumns=[{value:function(row){return row.name;}},{value:function(row){let span=tr.v.ui.createScalarSpan(row.value);if(row.significance!==undefined){span.significance=row.significance;}else if(row.anyRowsHaveSignificance){span.style.marginRight='18px';}
-span.style.whiteSpace='nowrap';return span;}}];},get scalarMap(){return this.scalarMap_;},set scalarMap(map){this.scalarMap_=map;this.updateContents_();},setSignificanceForKey:function(key,significance){this.significance_.set(key,significance);this.updateContents_();},updateContents_:function(){let rows=[];for(let[key,scalar]of this.scalarMap){rows.push({name:key,value:scalar,significance:this.significance_.get(key),anyRowsHaveSignificance:(this.significance_.size>0)});}
-this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.v.ui',function(){const DEFAULT_BAR_HEIGHT_PX=5;const TRUNCATE_BIN_MARGIN=0.15;const IGNORE_DELTA_STATISTICS_NAMES=[`${tr.v.DELTA}min`,`%${tr.v.DELTA}min`,`${tr.v.DELTA}max`,`%${tr.v.DELTA}max`,`${tr.v.DELTA}sum`,`%${tr.v.DELTA}sum`,`${tr.v.DELTA}count`,`%${tr.v.DELTA}count`,];Polymer({is:'tr-v-ui-histogram-span',created(){this.histogram_=undefined;this.referenceHistogram_=undefined;this.graphWidth_=undefined;this.graphHeight_=undefined;this.mouseDownBin_=undefined;this.brushedBins_=[];this.prevBrushedBins_=[];this.canMergeSampleDiagnostics_=true;},ready(){this.$.drag_handle.target=this.$.container;this.$.drag_handle.addEventListener('drag-handle-resize',this.onResize_.bind(this));},attached(){if(this.histogram_!==undefined)this.updateContents_();},get canMergeSampleDiagnostics(){return this.canMergeSampleDiagnostics_;},set canMergeSampleDiagnostics(merge){this.canMergeSampleDiagnostics_=merge;this.$.merge_sample_diagnostics_container.style.display=(merge?'':'none');},onResize_(event){event.stopPropagation();let heightPx=parseInt(this.$.container.style.height);if(heightPx<this.defaultGraphHeight){heightPx=this.defaultGraphHeight;this.$.container.style.height=this.defaultGraphHeight+'px';}
+const columnTitles=new Set();for(const map of this.diagnosticMaps_){for(const[name,diagnostic]of map){if(diagnostic instanceof tr.v.d.UnmergeableDiagnosticSet)continue;if(diagnostic instanceof tr.v.d.CollectedRelatedEventSet)continue;if(diagnostic instanceof tr.v.d.GroupingPath)continue;columnTitles.add(name);}}
+const columns=[];function makeColumn(title){return{title,value(map){const diagnostic=map.get(title);if(!diagnostic)return'';return tr.v.ui.createDiagnosticSpan(diagnostic);}};}
+for(const title of columnTitles){columns.push(makeColumn(title));}
+this.$.table.tableColumns=columns;this.$.table.tableRows=this.diagnosticMaps_;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.b',function(){class Serializable{constructor(){Object.defineProperty(this,'properties_',{configurable:false,enumerable:false,value:new Map(),});}
+define(name,initialValue){if(this[name]!==undefined){throw new Error(`"${name}" is already defined.`);}
+if(name[name.length-1]==='_'){throw new Error(`"${name}" cannot end with an underscore.`);}
+this.properties_.set(name,initialValue);Object.defineProperty(this,name,{configurable:false,enumerable:true,get:()=>this.properties_.get(name),set:value=>this.setProperty_(name,value),});}
+setProperty_(name,value){this.properties_.set(name,value);}
+clone(){return Serializable.fromDict(this.asDict());}
+asDict(){function visit(obj){if(obj instanceof Serializable)return obj.asDict();if(obj instanceof Set)return Array.from(obj);if(obj instanceof Array)return obj.map(visit);if(!(obj instanceof Map))return obj;const result={};for(const[name,value]of obj){result[name]=visit(value);}
+return result;}
+const dict={type:this.constructor.name};for(const[name,value]of this.properties_){dict[name.replace(/_$/,'')]=visit(value);}
+return dict;}
+static fromDict(dict){function visit(d){if(d instanceof Array)return d.map(visit);if(!(d instanceof Object))return d;if(typeof d.type==='string')return Serializable.fromDict(d);const result=new Map();for(const[name,value]of Object.entries(d)){result.set(name,visit(value));}
+return result;}
+const typeInfo=Serializable.findTypeInfoWithName(dict.type);const result=new typeInfo.constructor();for(const[name,value]of Object.entries(dict)){result[name]=visit(value);}
+return result;}}
+const options=new tr.b.ExtensionRegistryOptions(tr.b.BASIC_REGISTRY_MODE);options.defaultMetadata={};options.mandatoryBaseClass=Serializable;tr.b.decorateExtensionRegistry(Serializable,options);return{Serializable,};});'use strict';tr.exportTo('tr.b',function(){class ViewState extends tr.b.Serializable{constructor(){super();tr.b.EventTarget.decorate(this);}
+setProperty_(name,value){this.update(new Map([[name,value]]));}
+async updateFromViewState(other){await this.update(other.properties_);}
+async update(delta){if(!(delta instanceof Map))delta=new Map(Object.entries(delta));const actualDelta={};for(const[name,current]of delta){const previous=this[name];if(previous===current)continue;actualDelta[name]={previous,current};tr.b.Serializable.prototype.setProperty_.call(this,name,current);}
+if(Object.keys(actualDelta).length===0)return;await tr.b.dispatchSimpleEventAsync(this,this.updateEventName_,{delta:actualDelta});}
+get updateEventName_(){return this.constructor.name+'.update';}
+addUpdateListener(listener){this.addEventListener(this.updateEventName_,listener);}
+removeUpdateListener(listener){this.removeEventListener(this.updateEventName_,listener);}}
+return{ViewState,};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetViewState extends tr.b.ViewState{constructor(){super();this.define('searchQuery','');this.define('referenceDisplayLabel','');this.define('displayStatisticName','');this.define('showAll',false);this.define('groupings',[]);this.define('sortColumnIndex',0);this.define('sortDescending',false);this.define('constrainNameColumn',true);this.define('tableRowStates',new Map());}}
+tr.b.ViewState.register(HistogramSetViewState);class HistogramSetTableRowState extends tr.b.ViewState{constructor(){super();this.define('isExpanded',false);this.define('isOverviewed',false);this.define('cells',new Map());this.define('subRows',new Map());}
+asCompactDict(){const result={};if(this.isExpanded)result.e='1';if(this.isOverviewed)result.o='1';const cells={};for(const[name,cell]of this.cells){const cellDict=cell.asCompactDict();if(cellDict===undefined)continue;cells[name]=cellDict;}
+if(Object.keys(cells).length>0)result.c=cells;const subRows={};for(const[name,row]of this.subRows){const rowDict=row.asCompactDict();if(rowDict===undefined)continue;subRows[name]=rowDict;}
+if(Object.keys(subRows).length>0)result.r=subRows;if(Object.keys(result).length===0)return undefined;return result;}
+async updateFromCompactDict(dict){await this.update({isExpanded:dict.e==='1',isOverviewed:dict.o==='1',});for(const[name,cellDict]of Object.entries(dict.c||{})){const cell=this.cells.get(name);if(cell===undefined)continue;await cell.updateFromCompactDict(cellDict);}
+for(const[name,subRowDict]of Object.entries(dict.r||{})){const subRow=this.subRows.get(name);if(subRow===undefined)continue;await subRow.updateFromCompactDict(subRowDict);}}*walk(){yield this;for(const row of this.subRows.values())yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}}
+tr.b.ViewState.register(HistogramSetTableRowState);class HistogramSetTableCellState extends tr.b.ViewState{constructor(){super();this.define('isOpen',false);this.define('brushedBinRange',new tr.b.math.Range());this.define('mergeSampleDiagnostics',true);}
+asCompactDict(){const result={};if(this.isOpen)result.o='1';if(!this.mergeSampleDiagnostics)result.m='0';if(!this.brushedBinRange.isEmpty){result.b=this.brushedBinRange.min+'_'+this.brushedBinRange.max;}
+if(Object.keys(result).length===0)return undefined;return result;}
+async updateFromCompactDict(dict){let binRange=this.brushedBinRange;if(dict.b){let[bMin,bMax]=dict.b.split('_');bMin=parseInt(bMin);bMax=parseInt(bMax);if(bMin!==binRange.min||bMax!==binRange.max){binRange=tr.b.math.Range.fromExplicitRange(bMin,bMax);}}
+await this.update({isOpen:dict.o==='1',brushedBinRange:binRange,mergeSampleDiagnostics:dict.m!=='0',});}}
+tr.b.ViewState.register(HistogramSetTableCellState);return{HistogramSetTableCellState,HistogramSetTableRowState,HistogramSetViewState,};});'use strict';Polymer({is:'tr-v-ui-scalar-map-table',created(){this.scalarMap_=new Map();this.significance_=new Map();},ready(){this.$.table.showHeader=false;this.$.table.tableColumns=[{value(row){return row.name;}},{value(row){const span=tr.v.ui.createScalarSpan(row.value);if(row.significance!==undefined){span.significance=row.significance;}else if(row.anyRowsHaveSignificance){span.style.marginRight='18px';}
+span.style.whiteSpace='nowrap';return span;}}];},get scalarMap(){return this.scalarMap_;},set scalarMap(map){this.scalarMap_=map;this.updateContents_();},setSignificanceForKey(key,significance){this.significance_.set(key,significance);this.updateContents_();},updateContents_(){const rows=[];for(const[key,scalar]of this.scalarMap){rows.push({name:key,value:scalar,significance:this.significance_.get(key),anyRowsHaveSignificance:(this.significance_.size>0)});}
+this.$.table.tableRows=rows;this.$.table.rebuild();}});'use strict';tr.exportTo('tr.v.ui',function(){const DEFAULT_BAR_HEIGHT_PX=5;const TRUNCATE_BIN_MARGIN=0.15;const IGNORE_DELTA_STATISTICS_NAMES=[`${tr.v.DELTA}min`,`%${tr.v.DELTA}min`,`${tr.v.DELTA}max`,`%${tr.v.DELTA}max`,`${tr.v.DELTA}sum`,`%${tr.v.DELTA}sum`,`${tr.v.DELTA}count`,`%${tr.v.DELTA}count`,];Polymer({is:'tr-v-ui-histogram-span',created(){this.viewStateListener_=this.onViewStateUpdate_.bind(this);this.viewState=new tr.v.ui.HistogramSetTableCellState();this.histogram_=undefined;this.referenceHistogram_=undefined;this.graphWidth_=undefined;this.graphHeight_=undefined;this.mouseDownBin_=undefined;this.prevBrushedBinRange_=new tr.b.math.Range();this.canMergeSampleDiagnostics_=true;},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState){this.viewState.removeUpdateListener(this.viewStateListener_);}
+this.viewState_=vs;this.viewState.addUpdateListener(this.viewStateListener_);if(this.isAttached)this.updateContents_();},onViewStateUpdate_(event){if(event.delta.brushedBinRange){this.brushedBinRange=this.viewState.brushedBinRange;}
+if(event.delta.mergeSampleDiagnostics){this.mergeSampleDiagnostics=this.canMergeSampleDiagnostics&&this.viewState.mergeSampleDiagnostics;}},ready(){this.$.drag_handle.target=this.$.container;this.$.drag_handle.addEventListener('drag-handle-resize',this.onResize_.bind(this));},attached(){if(this.histogram_!==undefined)this.updateContents_();},get canMergeSampleDiagnostics(){return this.canMergeSampleDiagnostics_;},set canMergeSampleDiagnostics(merge){this.canMergeSampleDiagnostics_=merge;this.$.merge_sample_diagnostics_container.style.display=(merge?'':'none');},onResize_(event){event.stopPropagation();let heightPx=parseInt(this.$.container.style.height);if(heightPx<this.defaultGraphHeight){heightPx=this.defaultGraphHeight;this.$.container.style.height=this.defaultGraphHeight+'px';}
 this.chart_.graphHeight=heightPx-(this.chart_.margin.top+
 this.chart_.margin.bottom);},get graphWidth(){return this.graphWidth_||this.defaultGraphWidth;},set graphWidth(width){this.graphWidth_=width;},get graphHeight(){return this.graphHeight_||this.defaultGraphHeight;},set graphHeight(height){this.graphHeight_=height;},get barHeight(){return this.chart_.barHeight;},set barHeight(px){this.graphHeight=this.computeChartHeight_(px);},computeChartHeight_(barHeightPx){return(this.chart_.margin.top+
 this.chart_.margin.bottom+
 (barHeightPx*this.histogram.allBins.length));},get defaultGraphHeight(){if(this.histogram&&this.histogram.allBins.length===1){return 150;}
 return this.computeChartHeight_(DEFAULT_BAR_HEIGHT_PX);},get defaultGraphWidth(){if(this.histogram.allBins.length===1){return 100;}
-return 300;},get brushedBins(){return this.brushedBins_;},set brushedBins(bins){this.brushedBins_=bins;if(this.chart_===undefined)return;let brushedBinIndices=new tr.b.math.Range();for(let bin of bins){brushedBinIndices.addValue(this.histogram.allBins.indexOf(bin));}
-this.chart_.brushedRange=brushedBinIndices;this.updateDiagnostics_();},get brushedBinRange(){if(this.chart_===undefined)return new tr.b.math.Range();return this.chart_.brushedRange;},set brushedBinRange(r){if(this.chart_===undefined)return;let brushedBins=[];for(let i=r.min;i<=r.max;++i){brushedBins.push(this.histogram.allBins[i]);}
-this.brushedBins=brushedBins;},get mergeSampleDiagnostics(){return this.canMergeSampleDiagnostics&&this.$.merge_sample_diagnostics.checked;},set mergeSampleDiagnostics(m){this.$.merge_sample_diagnostics.checked=m;},updateBrushedRange_(binIndex){let brushedBinIndices=new tr.b.math.Range();brushedBinIndices.addValue(tr.b.math.clamp(this.mouseDownBinIndex_,0,this.histogram.allBins.length-1));brushedBinIndices.addValue(tr.b.math.clamp(binIndex,0,this.histogram.allBins.length-1));brushedBinIndices.max+=1;this.chart_.brushedRange=brushedBinIndices;this.brushedBins_=[];for(let i=brushedBinIndices.min;i<brushedBinIndices.max;++i){this.brushedBins.push(this.histogram.allBins[i]);}},onMouseDown_(chartEvent){chartEvent.stopPropagation();if(!this.histogram){return;}
-this.prevBrushedBins_=this.brushedBins_;this.mouseDownBinIndex_=chartEvent.y;this.updateBrushedRange_(chartEvent.y);},onMouseMove_(chartEvent){chartEvent.stopPropagation();if(!this.histogram){return;}
+return 300;},get brushedBins(){const bins=[];if(this.histogram&&!this.brushedBinRange.isEmpty){for(let i=this.brushedBinRange.min;i<this.brushedBinRange.max;++i){bins.push(this.histogram.allBins[i]);}}
+return bins;},get brushedBinRange(){return this.viewState.brushedBinRange;},set brushedBinRange(r){if(this.chart_===undefined)return;const current=this.brushedBinRange;if(r.min===current.min&&r.max===current.max)return;this.chart_.brushedRange=r;this.viewState.brushedBinRange=r;this.updateDiagnostics_();},get mergeSampleDiagnostics(){return this.canMergeSampleDiagnostics&&this.$.merge_sample_diagnostics.checked;},set mergeSampleDiagnostics(m){this.$.merge_sample_diagnostics.checked=m;},updateBrushedRange_(binIndex){const brushedBinRange=new tr.b.math.Range();brushedBinRange.addValue(tr.b.math.clamp(this.mouseDownBinIndex_,0,this.histogram.allBins.length-1));brushedBinRange.addValue(tr.b.math.clamp(binIndex,0,this.histogram.allBins.length-1));brushedBinRange.max+=1;this.brushedBinRange=brushedBinRange;},onMouseDown_(chartEvent){chartEvent.stopPropagation();if(!this.histogram){return;}
+this.prevBrushedBinRange_=this.brushedBinRange;this.mouseDownBinIndex_=chartEvent.y;this.updateBrushedRange_(chartEvent.y);},onMouseMove_(chartEvent){chartEvent.stopPropagation();if(!this.histogram){return;}
 this.updateBrushedRange_(chartEvent.y);},onMouseUp_(chartEvent){chartEvent.stopPropagation();if(!this.histogram){return;}
-this.updateBrushedRange_(chartEvent.y);if(this.prevBrushedBins_.length===1&&this.brushedBins_.length===1&&this.prevBrushedBins_[0]===this.brushedBins_[0]){this.brushedBins_=[];this.chart_.brushedRange=new tr.b.math.Range();}
-this.updateDiagnostics_();this.mouseDownBinIndex_=undefined;},updateDiagnostics_(){let maps=[];for(let bin of this.brushedBins){for(let map of bin.diagnosticMaps){maps.push(map);}}
+this.updateBrushedRange_(chartEvent.y);if(this.prevBrushedBinRange_.range===1&&this.brushedBinRange.range===1&&this.prevBrushedBinRange_.min===this.brushedBinRange.min){tr.b.Timing.instant('histogram-span','clearBrushedBins');this.brushedBinRange=new tr.b.math.Range();}else{tr.b.Timing.instant('histogram-span','brushBins');}
+this.mouseDownBinIndex_=undefined;},updateDiagnostics_(){let maps=[];for(const bin of this.brushedBins){for(const map of bin.diagnosticMaps){maps.push(map);}}
 if(maps.length===0){this.$.sample_diagnostics_container.style.display='none';return;}
-if(this.mergeSampleDiagnostics){let merged=new tr.v.d.DiagnosticMap();for(let map of maps){merged.addDiagnostics(map);}
+if(this.mergeSampleDiagnostics!==this.viewState.mergeSampleDiagnostics){tr.b.Timing.instant('histogram-span',(this.mergeSampleDiagnostics?'merge':'split')+'SampleDiagnostics');this.viewState.mergeSampleDiagnostics=this.mergeSampleDiagnostics;}
+if(this.mergeSampleDiagnostics){const merged=new tr.v.d.DiagnosticMap();for(const map of maps){merged.addDiagnostics(map);}
 maps=[merged];}
 this.$.sample_diagnostics_container.style.display='block';this.$.sample_diagnostics.diagnosticMaps=maps;},get histogram(){return this.histogram_;},set histogram(histogram){if(histogram===this.histogram_)return;this.histogram_=histogram;if(this.isAttached)this.updateContents_();},get referenceHistogram(){return this.referenceHistogram_;},set referenceHistogram(histogram){if(histogram===this.referenceHistogram_){return;}
-this.referenceHistogram_=histogram;if(this.histogram)this.updateContents_();},getDeltaScalars_(statNames,scalarMap){if(!this.histogram.canCompare(this.referenceHistogram))return;let mwu=tr.b.math.Statistics.mwu(this.histogram.sampleValues,this.referenceHistogram.sampleValues);for(let deltaStatName of tr.v.Histogram.getDeltaStatisticsNames(statNames)){if(IGNORE_DELTA_STATISTICS_NAMES.includes(deltaStatName))continue;let scalar=this.histogram.getStatisticScalar(deltaStatName,this.referenceHistogram,mwu);if(scalar===undefined)continue;scalarMap.set(deltaStatName,scalar);}
-if(this.histogram.unit.improvementDirection!==tr.b.ImprovementDirection.DONT_CARE){this.$.stats.setSignificanceForKey(`${tr.v.DELTA}avg`,mwu.significance);}},set isYLogScale(logScale){this.chart_.isYLogScale=logScale;},updateContents_(){this.$.chart.style.display='none';this.$.drag_handle.style.display='none';this.$.sample_diagnostics_container.style.display='none';this.$.container.style.justifyContent='';this.brushedBins_=[];while(Polymer.dom(this.$.chart).lastChild){Polymer.dom(this.$.chart).removeChild(Polymer.dom(this.$.chart).lastChild);}
-if(!this.histogram)return;this.$.container.style.display='';let scalarMap=new Map();this.getDeltaScalars_(this.histogram.statisticsNames,scalarMap);for(let[name,scalar]of this.histogram.statisticsScalars){scalarMap.set(name,scalar);}
-this.$.stats.scalarMap=scalarMap;if(this.histogram.diagnostics.size>0){let diagnosticMap=new tr.v.d.DiagnosticMap();for(let[key,diagnostic]of this.histogram.diagnostics){if(key!==tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY&&key!==tr.v.d.MERGED_TO_DIAGNOSTIC_KEY){diagnosticMap.set(key,diagnostic);}}
+this.referenceHistogram_=histogram;if(this.histogram)this.updateContents_();},getDeltaScalars_(statNames,scalarMap){if(!this.histogram.canCompare(this.referenceHistogram))return;const mwu=tr.b.math.Statistics.mwu(this.histogram.sampleValues,this.referenceHistogram.sampleValues);for(const deltaStatName of tr.v.Histogram.getDeltaStatisticsNames(statNames)){if(IGNORE_DELTA_STATISTICS_NAMES.includes(deltaStatName))continue;const scalar=this.histogram.getStatisticScalar(deltaStatName,this.referenceHistogram,mwu);if(scalar===undefined)continue;scalarMap.set(deltaStatName,scalar);}
+if(this.histogram.unit.improvementDirection!==tr.b.ImprovementDirection.DONT_CARE){this.$.stats.setSignificanceForKey(`${tr.v.DELTA}avg`,mwu.significance);}},set isYLogScale(logScale){this.chart_.isYLogScale=logScale;},updateContents_(){this.$.chart.style.display='none';this.$.drag_handle.style.display='none';this.$.sample_diagnostics_container.style.display='none';this.$.container.style.justifyContent='';this.brushedBinRange=new tr.b.math.Range();while(Polymer.dom(this.$.chart).lastChild){Polymer.dom(this.$.chart).removeChild(Polymer.dom(this.$.chart).lastChild);}
+if(!this.histogram)return;this.$.container.style.display='';const scalarMap=new Map();this.getDeltaScalars_(this.histogram.statisticsNames,scalarMap);for(const[name,scalar]of this.histogram.statisticsScalars){scalarMap.set(name,scalar);}
+this.$.stats.scalarMap=scalarMap;if(this.histogram.diagnostics.size>0){const diagnosticMap=new tr.v.d.DiagnosticMap();for(const[key,diagnostic]of this.histogram.diagnostics){if(key!==tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY&&key!==tr.v.d.MERGED_TO_DIAGNOSTIC_KEY){diagnosticMap.set(key,diagnostic);}}
 this.$.histogram_diagnostics.diagnosticMaps=[diagnosticMap];this.$.histogram_diagnostics.style.display='block';}else{this.$.histogram_diagnostics.style.display='none';}
-if(this.histogram.numValues<=1){this.brushedBins_=this.histogram.allBins;this.updateDiagnostics_();this.$.container.style.justifyContent='flex-end';return;}
+if(this.histogram.numValues<=1){this.brushedBinRange=tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length);this.updateDiagnostics_();this.$.container.style.justifyContent='flex-end';return;}
 this.$.chart.style.display='block';this.$.drag_handle.style.display='block';if(this.histogram.allBins.length===1){if(this.histogram.min!==this.histogram.max){this.chart_=new tr.ui.b.BoxChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.hideXAxis=true;this.chart_.data=[{x:'',color:'blue',percentile_0:this.histogram.running.min,percentile_25:this.histogram.getApproximatePercentile(0.25),percentile_50:this.histogram.getApproximatePercentile(0.5),percentile_75:this.histogram.getApproximatePercentile(0.75),percentile_100:this.histogram.running.max,}];}
-this.brushedBins_=this.histogram.allBins;this.updateDiagnostics_();return;}
-this.chart_=new tr.ui.b.NameBarChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.addEventListener('item-mousedown',this.onMouseDown_.bind(this));this.chart_.addEventListener('item-mousemove',this.onMouseMove_.bind(this));this.chart_.addEventListener('item-mouseup',this.onMouseUp_.bind(this));this.chart_.hideLegend=true;this.chart_.getDataSeries('y').color='blue';this.chart_.xAxisLabel='#';this.chart_.brushedRange=new tr.b.math.Range();let chartData=[];let binCounts=[];for(let bin of this.histogram.allBins){let x=bin.range.min;if(x===-Number.MAX_VALUE){x='<'+new tr.b.Scalar(this.histogram.unit,bin.range.max).toString();}else{x=new tr.b.Scalar(this.histogram.unit,x).toString();}
-chartData.push({x:x,y:bin.count});binCounts.push(bin.count);}
-binCounts.sort((x,y)=>y-x);let dataRange=tr.b.math.Range.fromExplicitRange(0,binCounts[0]);if(binCounts[1]>0&&binCounts[0]>(binCounts[1]*2)){dataRange.max=binCounts[1]*(1+TRUNCATE_BIN_MARGIN);}
+this.brushedBinRange=tr.b.math.Range.fromExplicitRange(0,this.histogram.allBins.length);this.updateDiagnostics_();return;}
+this.chart_=new tr.ui.b.NameBarChart();Polymer.dom(this.$.chart).appendChild(this.chart_);this.chart_.graphWidth=this.graphWidth;this.chart_.graphHeight=this.graphHeight;this.chart_.addEventListener('item-mousedown',this.onMouseDown_.bind(this));this.chart_.addEventListener('item-mousemove',this.onMouseMove_.bind(this));this.chart_.addEventListener('item-mouseup',this.onMouseUp_.bind(this));this.chart_.hideLegend=true;this.chart_.getDataSeries('y').color='blue';this.chart_.xAxisLabel='#';this.chart_.brushedRange=this.brushedBinRange;this.updateDiagnostics_();const chartData=[];const binCounts=[];for(const bin of this.histogram.allBins){let x=bin.range.min;if(x===-Number.MAX_VALUE){x='<'+new tr.b.Scalar(this.histogram.unit,bin.range.max).toString();}else{x=new tr.b.Scalar(this.histogram.unit,x).toString();}
+chartData.push({x,y:bin.count});binCounts.push(bin.count);}
+binCounts.sort((x,y)=>y-x);const dataRange=tr.b.math.Range.fromExplicitRange(0,binCounts[0]);if(binCounts[1]>0&&binCounts[0]>(binCounts[1]*2)){dataRange.max=binCounts[1]*(1+TRUNCATE_BIN_MARGIN);}
 if(binCounts[2]>0&&binCounts[1]>(binCounts[2]*2)){dataRange.max=binCounts[2]*(1+TRUNCATE_BIN_MARGIN);}
-this.chart_.overrideDataRange=dataRange;this.chart_.data=chartData;}});});'use strict';tr.exportTo('tr.ui.analysis',function(){var EVENT_FIELD=[{key:'start',label:'Start'},{key:'cpuDuration',label:'CPU Duration'},{key:'duration',label:'Duration'},{key:'cpuSelfTime',label:'CPU Self Time'},{key:'selfTime',label:'Self Time'}];function buildDiagnostics_(slice){var diagnostics={};for(var item of EVENT_FIELD){var fieldName=item.key;if(slice[fieldName]===undefined)continue;diagnostics[fieldName]=new tr.v.d.Scalar(new tr.b.Scalar(tr.b.Unit.byName.timeDurationInMs,slice[fieldName]));}
-diagnostics['args']=new tr.v.d.Generic(slice.args);diagnostics['event']=new tr.v.d.RelatedEventSet(slice);return diagnostics;}
+this.chart_.overrideDataRange=dataRange;this.chart_.data=chartData;}});});'use strict';tr.exportTo('tr.ui.analysis',function(){const EVENT_FIELD=[{key:'start',label:'Start'},{key:'cpuDuration',label:'CPU Duration'},{key:'duration',label:'Duration'},{key:'cpuSelfTime',label:'CPU Self Time'},{key:'selfTime',label:'Self Time'}];function buildDiagnostics_(slice){const diagnostics={};for(const item of EVENT_FIELD){const fieldName=item.key;if(slice[fieldName]===undefined)continue;diagnostics[fieldName]=new tr.v.d.Scalar(new tr.b.Scalar(tr.b.Unit.byName.timeDurationInMs,slice[fieldName]));}
+diagnostics.args=new tr.v.d.Generic(slice.args);diagnostics.event=new tr.v.d.RelatedEventSet(slice);return diagnostics;}
 Polymer({is:'tr-ui-a-multi-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;this.eventsHaveDuration_=true;this.eventsHaveSubRows_=true;},ready(){this.$.radioPicker.style.display='none';this.$.radioPicker.items=EVENT_FIELD;this.$.radioPicker.select('cpuSelfTime');this.$.radioPicker.addEventListener('change',()=>{if(this.isAttached)this.updateContents_();});this.$.histogramSpan.graphWidth=400;this.$.histogramSpan.canMergeSampleDiagnostics=false;this.$.histogramContainer.style.display='none';},attached(){if(this.currentSelection_!==undefined)this.updateContents_();},set selection(selection){if(selection.length<=1){throw new Error('Only supports multiple items');}
-this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;if(this.isAttached)this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;if(this.isAttached)this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;if(this.isAttached)this.updateContents_();},buildHistogram_(selectedKey){var leftBoundary=Number.MAX_VALUE;var rightBoundary=tr.b.math.Statistics.percentile(this.currentSelection_,0.95,function(value){leftBoundary=Math.min(leftBoundary,value[selectedKey]);return value[selectedKey];});if(leftBoundary===rightBoundary)rightBoundary+=1;var histogram=new tr.v.Histogram('',tr.b.Unit.byName.timeDurationInMs,tr.v.HistogramBinBoundaries.createLinear(leftBoundary,rightBoundary,Math.ceil(Math.sqrt(this.currentSelection_.length))));histogram.customizeSummaryOptions({sum:false});for(var slice of this.currentSelection_){histogram.addSample(slice[selectedKey],buildDiagnostics_(slice));}
-return histogram;},updateContents_(){var selection=this.currentSelection_;if(!selection)return;var eventsByTitle=selection.getEventsOrganizedByTitle();var numTitles=tr.b.dictionaryLength(eventsByTitle);this.$.eventSummaryTable.configure({showTotals:numTitles>1,eventsByTitle:eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.selectionSummaryTable.selection=this.currentSelection_;if(numTitles===1){this.$.radioPicker.style.display='block';this.$.histogramContainer.style.display='flex';this.$.histogramSpan.histogram=this.buildHistogram_(this.$.radioPicker.selectedKey);if(this.$.histogramSpan.histogram.numValues===0){this.$.histogramContainer.style.display='none';}}else{this.$.radioPicker.style.display='none';this.$.histogramContainer.style.display='none';}}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){var FLOW_IN=0x1;var FLOW_OUT=0x2;var FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
-FlowClassifier.prototype={getFS_:function(event){var fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event:event};this.eventsByGUID_[event.guid]=fs;}
-return fs;},addInFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow:function(event){var fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents:function(){return this.numEvents_>0;},get inFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN){selection.push(fs.event);}}
-return selection;},get outFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT){selection.push(fs.event);}}
-return selection;},get internalFlowEvents(){var selection=new tr.model.EventSet();for(var guid in this.eventsByGUID_){var fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT){selection.push(fs.event);}}
+this.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},setSelectionWithoutErrorChecks(selection){this.currentSelection_=selection;if(this.isAttached)this.updateContents_();},get eventsHaveDuration(){return this.eventsHaveDuration_;},set eventsHaveDuration(eventsHaveDuration){this.eventsHaveDuration_=eventsHaveDuration;if(this.isAttached)this.updateContents_();},get eventsHaveSubRows(){return this.eventsHaveSubRows_;},set eventsHaveSubRows(eventsHaveSubRows){this.eventsHaveSubRows_=eventsHaveSubRows;if(this.isAttached)this.updateContents_();},buildHistogram_(selectedKey){let leftBoundary=Number.MAX_VALUE;let rightBoundary=tr.b.math.Statistics.percentile(this.currentSelection_,0.95,function(value){leftBoundary=Math.min(leftBoundary,value[selectedKey]);return value[selectedKey];});if(leftBoundary===rightBoundary)rightBoundary+=1;const histogram=new tr.v.Histogram('',tr.b.Unit.byName.timeDurationInMs,tr.v.HistogramBinBoundaries.createLinear(leftBoundary,rightBoundary,Math.ceil(Math.sqrt(this.currentSelection_.length))));histogram.customizeSummaryOptions({sum:false});for(const slice of this.currentSelection_){histogram.addSample(slice[selectedKey],buildDiagnostics_(slice));}
+return histogram;},updateContents_(){const selection=this.currentSelection_;if(!selection)return;const eventsByTitle=selection.getEventsOrganizedByTitle();const numTitles=Object.keys(eventsByTitle).length;this.$.eventSummaryTable.configure({showTotals:numTitles>1,eventsByTitle,eventsHaveDuration:this.eventsHaveDuration_,eventsHaveSubRows:this.eventsHaveSubRows_});this.$.selectionSummaryTable.selection=this.currentSelection_;if(numTitles===1){this.$.radioPicker.style.display='block';this.$.histogramContainer.style.display='flex';this.$.histogramSpan.histogram=this.buildHistogram_(this.$.radioPicker.selectedKey);if(this.$.histogramSpan.histogram.numValues===0){this.$.histogramContainer.style.display='none';}}else{this.$.radioPicker.style.display='none';this.$.histogramContainer.style.display='none';}}});return{};});'use strict';tr.exportTo('tr.ui.analysis',function(){const FLOW_IN=0x1;const FLOW_OUT=0x2;const FLOW_IN_OUT=FLOW_IN|FLOW_OUT;function FlowClassifier(){this.numEvents_=0;this.eventsByGUID_={};}
+FlowClassifier.prototype={getFS_(event){let fs=this.eventsByGUID_[event.guid];if(fs===undefined){this.numEvents_++;fs={state:0,event};this.eventsByGUID_[event.guid]=fs;}
+return fs;},addInFlow(event){const fs=this.getFS_(event);fs.state|=FLOW_IN;return event;},addOutFlow(event){const fs=this.getFS_(event);fs.state|=FLOW_OUT;return event;},hasEvents(){return this.numEvents_>0;},get inFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN){selection.push(fs.event);}}
+return selection;},get outFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_OUT){selection.push(fs.event);}}
+return selection;},get internalFlowEvents(){const selection=new tr.model.EventSet();for(const guid in this.eventsByGUID_){const fs=this.eventsByGUID_[guid];if(fs.state===FLOW_IN_OUT){selection.push(fs.event);}}
 return selection;}};return{FlowClassifier,};});'use strict';function*getEventInFlowEvents(event){if(!event.inFlowEvents)return;yield*event.inFlowEvents;}
 function*getEventOutFlowEvents(event){if(!event.outFlowEvents)return;yield*event.outFlowEvents;}
 function*getEventAncestors(event){if(!event.enumerateAllAncestors)return;yield*event.enumerateAllAncestors();}
 function*getEventDescendents(event){if(!event.enumerateAllDescendents)return;yield*event.enumerateAllDescendents();}
-Polymer({is:'tr-ui-a-related-events',ready:function(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){let typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
-return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){let linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
-return linkEl;}}];},hasRelatedEvents:function(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents:function(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addRuntimeCallStats_(eventSet);this.addOverlappingV8ICStats_(eventSet);this.addV8GCObjectStats_(eventSet);this.addV8Slices_(eventSet);this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_:function(eventSet){let classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
-if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())return;let addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type:type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_:function(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_:function(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventAncestors(event);if(event.startSlice){yield event.startSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function*(event){yield*getEventOutFlowEvents(event);yield*getEventDescendents(event);if(event.endSlice){yield event.endSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventOutFlowEvents(event);yield*getEventAncestors(event);yield*getEventDescendents(event);if(event.startSlice){yield event.startSlice;}
-if(event.endSlice){yield event.endSlice;}}.bind(this)));},createEventsLinkIfNeeded_:function(title,tooltip,events,connectedFn){events=new tr.model.EventSet(events);let eventsToProcess=new Set(events);let wasChanged=false;let task;let isCanceled=false;function addEventsUntilTimeout(){if(isCanceled)return;let timeout=window.performance.now()+8;while(eventsToProcess.size>0&&window.performance.now()<=timeout){let nextEvent=tr.b.getFirstElement(eventsToProcess);eventsToProcess.delete(nextEvent);for(let eventToAdd of connectedFn(nextEvent)){if(!events.contains(eventToAdd)){events.push(eventToAdd);eventsToProcess.add(eventToAdd);wasChanged=true;}}}
-if(eventsToProcess.size>0){let newTask=new tr.b.Task(addEventsUntilTimeout.bind(this),this);task.after(newTask);task=newTask;return;}
-if(!wasChanged)return;this.eventGroups_.push({type:title,tooltip:tooltip,selection:events});this.updateContents_();}
+Polymer({is:'tr-ui-a-related-events',ready(){this.eventGroups_=[];this.cancelFunctions_=[];this.$.table.tableColumns=[{title:'Event(s)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
+return typeEl;},width:'150px'},{title:'Link',width:'100%',value(row){const linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
+return linkEl;}}];},hasRelatedEvents(){return(this.eventGroups_&&this.eventGroups_.length>0);},setRelatedEvents(eventSet){this.cancelAllTasks_();this.eventGroups_=[];this.addRuntimeCallStats_(eventSet);this.addOverlappingV8ICStats_(eventSet);this.addV8GCObjectStats_(eventSet);this.addV8Slices_(eventSet);this.addConnectedFlows_(eventSet);this.addConnectedEvents_(eventSet);this.addOverlappingSamples_(eventSet);this.updateContents_();},addConnectedFlows_(eventSet){const classifier=new tr.ui.analysis.FlowClassifier();eventSet.forEach(function(slice){if(slice.inFlowEvents){slice.inFlowEvents.forEach(function(flow){classifier.addInFlow(flow);});}
+if(slice.outFlowEvents){slice.outFlowEvents.forEach(function(flow){classifier.addOutFlow(flow);});}});if(!classifier.hasEvents())return;const addToEventGroups=function(type,flowEvent){this.eventGroups_.push({type,selection:new tr.model.EventSet(flowEvent),name:flowEvent.title});};classifier.inFlowEvents.forEach(addToEventGroups.bind(this,'Incoming flow'));classifier.outFlowEvents.forEach(addToEventGroups.bind(this,'Outgoing flow'));classifier.internalFlowEvents.forEach(addToEventGroups.bind(this,'Internal flow'));},cancelAllTasks_(){this.cancelFunctions_.forEach(function(cancelFunction){cancelFunction();});this.cancelFunctions_=[];},addConnectedEvents_(eventSet){this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Preceding events','Add all events that have led to the selected one(s), connected by '+'flow arrows or by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventAncestors(event);if(event.startSlice){yield event.startSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('Following events','Add all events that have been caused by the selected one(s), '+'connected by flow arrows or by call stack.',eventSet,function*(event){yield*getEventOutFlowEvents(event);yield*getEventDescendents(event);if(event.endSlice){yield event.endSlice;}}.bind(this)));this.cancelFunctions_.push(this.createEventsLinkIfNeeded_('All connected events','Add all events connected to the selected one(s) by flow arrows or '+'by call stack.',eventSet,function*(event){yield*getEventInFlowEvents(event);yield*getEventOutFlowEvents(event);yield*getEventAncestors(event);yield*getEventDescendents(event);if(event.startSlice){yield event.startSlice;}
+if(event.endSlice){yield event.endSlice;}}.bind(this)));},createEventsLinkIfNeeded_(title,tooltip,events,connectedFn){events=new tr.model.EventSet(events);const eventsToProcess=new Set(events);let wasChanged=false;let task;let isCanceled=false;function addEventsUntilTimeout(){if(isCanceled)return;const timeout=window.performance.now()+8;while(eventsToProcess.size>0&&window.performance.now()<=timeout){const nextEvent=tr.b.getFirstElement(eventsToProcess);eventsToProcess.delete(nextEvent);for(const eventToAdd of connectedFn(nextEvent)){if(!events.contains(eventToAdd)){events.push(eventToAdd);eventsToProcess.add(eventToAdd);wasChanged=true;}}}
+if(eventsToProcess.size>0){const newTask=new tr.b.Task(addEventsUntilTimeout.bind(this),this);task.after(newTask);task=newTask;return;}
+if(!wasChanged)return;this.eventGroups_.push({type:title,tooltip,selection:events});this.updateContents_();}
 function cancelTask(){isCanceled=true;}
-task=new tr.b.Task(addEventsUntilTimeout.bind(this),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addOverlappingSamples_:function(eventSet){let samples=new tr.model.EventSet();for(let slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.samples){continue;}
-let candidates=slice.parentContainer.samples;let range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);let filteredSamples=range.filterArray(candidates,function(value){return value.start;});for(let sample of filteredSamples){samples.push(sample);}}
-if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},addV8Slices_:function(eventSet){let v8Slices=new tr.model.EventSet();for(let slice of eventSet){if(slice.category==='v8'){v8Slices.push(slice);}}
-if(v8Slices.length>0){this.eventGroups_.push({type:'V8 Slices',tooltip:'All V8 slices in the selected slice(s).',selection:v8Slices});}},addRuntimeCallStats_:function(eventSet){let slices=new tr.model.EventSet();for(let slice of eventSet){if(slice.category==='v8'&&slice.runtimeCallStats){slices.push(slice);}}
-if(slices.length>0){this.eventGroups_.push({type:'Runtime call stats table',tooltip:'All V8 slices containing runtime call stats table in the selected slice(s).',selection:slices});}},addV8GCObjectStats_:function(eventSet){let slices=new tr.model.EventSet();for(let slice of eventSet){if(slice.title==='V8.GC_Objects_Stats'){slices.push(slice);}}
-if(slices.length>0){this.eventGroups_.push({type:'V8 GC stats table',tooltip:'All V8 GC statistics slices in the selected set.',selection:slices});}},addOverlappingV8ICStats_:function(eventSet){let slices=new tr.model.EventSet();for(let slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.sliceGroup){continue;}
-let sliceGroup=slice.parentContainer.sliceGroup.slices;let range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);let filteredSlices=range.filterArray(sliceGroup,value=>value.start);let icSlices=filteredSlices.filter(x=>x.title==='V8.ICStats');for(let icSlice of icSlices){slices.push(icSlice);}}
-if(slices.length>0){this.eventGroups_.push({type:'Overlapping V8 IC stats',tooltip:'All V8 IC statistics overlapping the selected set.',selection:slices});}},updateContents_:function(){let table=this.$.table;if(this.eventGroups_===undefined){table.tableRows=[];}else{table.tableRows=this.eventGroups_.slice();}
-table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)return undefined;var selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)return selection;return undefined;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-async-slice-sub-view',tr.model.AsyncSlice,{multi:true,title:'Async Slices',});'use strict';Polymer({is:'tr-ui-a-multi-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-cpu-slice-sub-view',tr.model.CpuSlice,{multi:true,title:'CPU Slices',});'use strict';Polymer({is:'tr-ui-a-multi-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-flow-event-sub-view',tr.model.FlowEvent,{multi:true,title:'Flow Events',});'use strict';Polymer({is:'tr-ui-a-multi-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this).textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-frame-sub-view',tr.model.Frame,{multi:true,title:'Frames',});'use strict';Polymer({is:'tr-ui-a-multi-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';var realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this.$.content).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer({is:'tr-ui-a-multi-object-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;var objectEvents=tr.b.asArray(selection).sort(tr.b.math.Range.compareByMinTimes);var timeSpanConfig={unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};var table=this.$.content;table.tableColumns=[{title:'First',value:function(event){if(event instanceof tr.model.ObjectSnapshot){return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);}
-var spanEl=document.createElement('span');Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));Polymer.dom(spanEl).appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!==Number.MAX_VALUE){Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
-return spanEl;},width:'200px'},{title:'Second',value:function(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectInstance,{multi:true,title:'Object Instances',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectSnapshot,{multi:true,title:'Object Snapshots',});'use strict';var EventSet=tr.model.EventSet;var CHART_TITLE='Power (W) by ms since vertical sync';Polymer({is:'tr-ui-a-frame-power-usage-chart',ready:function(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},attached(){if(this.samples_)this.updateContents_();},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData:function(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;if(this.isAttached)this.updateContents_();},updateContents_:function(){this.clearChart_();var data=this.getDataForLineChart_();if(data.length===0)return;this.chart_=new tr.ui.b.LineChart();Polymer.dom(this.$.content).appendChild(this.chart_);this.chart_.chartTitle=CHART_TITLE;this.chart_.data=data;},clearChart_:function(){var content=this.$.content;while(Polymer.dom(content).firstChild){Polymer.dom(content).removeChild(Polymer.dom(content).firstChild);}
-this.chart_=undefined;},getDataForLineChart_:function(){var sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);var vSyncTimestamps=this.vSyncTimestamps.slice();var lastVSyncTimestamp=undefined;var points=[];var frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
-if(lastVSyncTimestamp===undefined)return;var point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.powerInW;points.push(point);});return points;},sortSamplesByTimestampAscending_:function(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer({is:'tr-ui-a-power-sample-summary-table',ready:function(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value:function(row){return tr.b.Unit.byName.powerInWatts.format(row.min);}},{title:'Max power',width:'100px',value:function(row){return tr.b.Unit.byName.powerInWatts.format(row.max);}},{title:'Time-weighted average',width:'100px',value:function(row){return tr.b.Unit.byName.powerInWatts.format(row.timeWeightedAverageInW);}},{title:'Energy consumed',width:'100px',value:function(row){return tr.b.Unit.byName.energyInJoules.format(row.energyConsumedInJ);}},{title:'Sample count',width:'100%',value:function(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_:function(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverageInW:this.getTimeWeightedAverageInW(),energyConsumedInJ:this.getEnergyConsumedInJ(),sampleCount:this.samples.length}];}
-this.$.table.rebuild();},getMin:function(){return Math.min.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getMax:function(){return Math.max.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getTimeWeightedAverageInW:function(){var energyConsumedInJ=this.getEnergyConsumedInJ();if(energyConsumedInJ==='N/A')return'N/A';var durationInS=tr.b.convertUnit(this.samples.bounds.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return energyConsumedInJ/durationInS;},getEnergyConsumedInJ:function(){if(this.samples.length<2)return'N/A';var bounds=this.samples.bounds;var series=tr.b.getFirstElement(this.samples).series;return series.getEnergyConsumedInJ(bounds.min,bounds.max);}});'use strict';Polymer({is:'tr-ui-a-multi-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){var samples=this.selection;var vSyncTimestamps=(!samples?[]:tr.b.getFirstElement(samples).series.device.vSyncTimestamps);this.$.summaryTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-power-sample-sub-view',tr.model.PowerSample,{multi:true,title:'Power Samples',});'use strict';(function(){var MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;Polymer({is:'tr-ui-a-multi-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.viewOption_=undefined;this.selection_=undefined;},ready:function(){var viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]);Polymer.dom(this.$.control).appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_:function(selection,viewOption){var builder=new MultiDimensionalViewBuilder(1,1);var samples=selection.filter(event=>event instanceof tr.model.Sample);samples.forEach(function(sample){builder.addPath([sample.userFriendlyStack.reverse()],[1],MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},processSampleRows_:function(rows){for(var row of rows){var title=row.title[0];var results=/(.*) (Deoptimized reason: .*)/.exec(title);if(results!==null){row.deoptReason=results[2];title=results[1];}
+task=new tr.b.Task(addEventsUntilTimeout.bind(this),this);tr.b.Task.RunWhenIdle(task);return cancelTask;},addOverlappingSamples_(eventSet){const samples=new tr.model.EventSet();for(const slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.samples){continue;}
+const candidates=slice.parentContainer.samples;const range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);const filteredSamples=range.filterArray(candidates,function(value){return value.start;});for(const sample of filteredSamples){samples.push(sample);}}
+if(samples.length>0){this.eventGroups_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected slice(s).',selection:samples});}},addV8Slices_(eventSet){const v8Slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.category==='v8'){v8Slices.push(slice);}}
+if(v8Slices.length>0){this.eventGroups_.push({type:'V8 Slices',tooltip:'All V8 slices in the selected slice(s).',selection:v8Slices});}},addRuntimeCallStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.category==='v8'&&slice.runtimeCallStats){slices.push(slice);}}
+if(slices.length>0){this.eventGroups_.push({type:'Runtime call stats table',tooltip:'All V8 slices containing runtime call stats table in the selected slice(s).',selection:slices});}},addV8GCObjectStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(slice.title==='V8.GC_Objects_Stats'){slices.push(slice);}}
+if(slices.length>0){this.eventGroups_.push({type:'V8 GC stats table',tooltip:'All V8 GC statistics slices in the selected set.',selection:slices});}},addOverlappingV8ICStats_(eventSet){const slices=new tr.model.EventSet();for(const slice of eventSet){if(!slice.parentContainer||!slice.parentContainer.sliceGroup){continue;}
+const sliceGroup=slice.parentContainer.sliceGroup.slices;const range=tr.b.math.Range.fromExplicitRange(slice.start,slice.start+slice.duration);const filteredSlices=range.filterArray(sliceGroup,value=>value.start);const icSlices=filteredSlices.filter(x=>x.title==='V8.ICStats');for(const icSlice of icSlices){slices.push(icSlice);}}
+if(slices.length>0){this.eventGroups_.push({type:'Overlapping V8 IC stats',tooltip:'All V8 IC statistics overlapping the selected set.',selection:slices});}},updateContents_(){const table=this.$.table;if(this.eventGroups_===undefined){table.tableRows=[];}else{table.tableRows=this.eventGroups_.slice();}
+table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},get relatedEventsToHighlight(){if(!this.$.content.selection)return undefined;const selection=new tr.model.EventSet();this.$.content.selection.forEach(function(asyncEvent){if(!asyncEvent.associatedEvents)return;asyncEvent.associatedEvents.forEach(function(event){selection.push(event);});});if(selection.length)return selection;return undefined;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-async-slice-sub-view',tr.model.AsyncSlice,{multi:true,title:'Async Slices',});'use strict';Polymer({is:'tr-ui-a-multi-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-cpu-slice-sub-view',tr.model.CpuSlice,{multi:true,title:'CPU Slices',});'use strict';Polymer({is:'tr-ui-a-multi-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveDuration=false;this.$.content.eventsHaveSubRows=false;},set selection(selection){this.$.content.selection=selection;},get selection(){return this.$.content.selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-flow-event-sub-view',tr.model.FlowEvent,{multi:true,title:'Flow Events',});'use strict';Polymer({is:'tr-ui-a-multi-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this).textContent='';const realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const selection=new tr.model.EventSet();this.currentSelection_.forEach(function(frameEvent){frameEvent.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-frame-sub-view',tr.model.Frame,{multi:true,title:'Frames',});'use strict';Polymer({is:'tr-ui-a-multi-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';const realView=document.createElement('tr-ui-a-multi-event-sub-view');realView.eventsHaveDuration=false;realView.eventsHaveSubRows=false;Polymer.dom(this.$.content).appendChild(realView);realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});'use strict';Polymer({is:'tr-ui-a-multi-object-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},ready(){this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;const objectEvents=tr.b.asArray(selection).sort(tr.b.math.Range.compareByMinTimes);const timeSpanConfig={unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument};const table=this.$.content;table.tableColumns=[{title:'First',value(event){if(event instanceof tr.model.ObjectSnapshot){return tr.v.ui.createScalarSpan(event.ts,timeSpanConfig);}
+const spanEl=document.createElement('span');Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.creationTs,timeSpanConfig));Polymer.dom(spanEl).appendChild(tr.ui.b.createSpan({textContent:'-',marginLeft:'4px',marginRight:'4px'}));if(event.deletionTs!==Number.MAX_VALUE){Polymer.dom(spanEl).appendChild(tr.v.ui.createScalarSpan(event.deletionTs,timeSpanConfig));}
+return spanEl;},width:'200px'},{title:'Second',value(event){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(function(){return new tr.model.EventSet(event);},event.userFriendlyName);return linkEl;},width:'100%'}];table.tableRows=objectEvents;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectInstance,{multi:true,title:'Object Instances',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-object-sub-view',tr.model.ObjectSnapshot,{multi:true,title:'Object Snapshots',});'use strict';const EventSet=tr.model.EventSet;const CHART_TITLE='Power (W) by ms since vertical sync';Polymer({is:'tr-ui-a-frame-power-usage-chart',ready(){this.chart_=undefined;this.samples_=new EventSet();this.vSyncTimestamps_=[];},attached(){if(this.samples_)this.updateContents_();},get chart(){return this.chart_;},get samples(){return this.samples_;},get vSyncTimestamps(){return this.vSyncTimestamps_;},setData(samples,vSyncTimestamps){this.samples_=(samples===undefined)?new EventSet():samples;this.vSyncTimestamps_=(vSyncTimestamps===undefined)?[]:vSyncTimestamps;if(this.isAttached)this.updateContents_();},updateContents_(){this.clearChart_();const data=this.getDataForLineChart_();if(data.length===0)return;this.chart_=new tr.ui.b.LineChart();Polymer.dom(this.$.content).appendChild(this.chart_);this.chart_.chartTitle=CHART_TITLE;this.chart_.data=data;},clearChart_(){const content=this.$.content;while(Polymer.dom(content).firstChild){Polymer.dom(content).removeChild(Polymer.dom(content).firstChild);}
+this.chart_=undefined;},getDataForLineChart_(){const sortedSamples=this.sortSamplesByTimestampAscending_(this.samples);const vSyncTimestamps=this.vSyncTimestamps.slice();let lastVSyncTimestamp=undefined;const points=[];let frameNumber=0;sortedSamples.forEach(function(sample){while(vSyncTimestamps.length>0&&vSyncTimestamps[0]<=sample.start){lastVSyncTimestamp=vSyncTimestamps.shift();frameNumber++;}
+if(lastVSyncTimestamp===undefined)return;const point={x:sample.start-lastVSyncTimestamp};point['f'+frameNumber]=sample.powerInW;points.push(point);});return points;},sortSamplesByTimestampAscending_(samples){return samples.toArray().sort(function(smpl1,smpl2){return smpl1.start-smpl2.start;});}});'use strict';Polymer({is:'tr-ui-a-power-sample-summary-table',ready(){this.$.table.tableColumns=[{title:'Min power',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.min);}},{title:'Max power',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.max);}},{title:'Time-weighted average',width:'100px',value(row){return tr.b.Unit.byName.powerInWatts.format(row.timeWeightedAverageInW);}},{title:'Energy consumed',width:'100px',value(row){return tr.b.Unit.byName.energyInJoules.format(row.energyConsumedInJ);}},{title:'Sample count',width:'100%',value(row){return row.sampleCount;}}];this.samples=new tr.model.EventSet();},get samples(){return this.samples_;},set samples(samples){if(samples===this.samples)return;this.samples_=(samples===undefined)?new tr.model.EventSet():samples;this.updateContents_();},updateContents_(){if(this.samples.length===0){this.$.table.tableRows=[];}else{this.$.table.tableRows=[{min:this.getMin(),max:this.getMax(),timeWeightedAverageInW:this.getTimeWeightedAverageInW(),energyConsumedInJ:this.getEnergyConsumedInJ(),sampleCount:this.samples.length}];}
+this.$.table.rebuild();},getMin(){return Math.min.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getMax(){return Math.max.apply(null,this.samples.map(function(sample){return sample.powerInW;}));},getTimeWeightedAverageInW(){const energyConsumedInJ=this.getEnergyConsumedInJ();if(energyConsumedInJ==='N/A')return'N/A';const durationInS=tr.b.convertUnit(this.samples.bounds.duration,tr.b.UnitPrefixScale.METRIC.MILLI,tr.b.UnitPrefixScale.METRIC.NONE);return energyConsumedInJ/durationInS;},getEnergyConsumedInJ(){if(this.samples.length<2)return'N/A';const bounds=this.samples.bounds;const series=tr.b.getFirstElement(this.samples).series;return series.getEnergyConsumedInJ(bounds.min,bounds.max);}});'use strict';Polymer({is:'tr-ui-a-multi-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){const samples=this.selection;const vSyncTimestamps=(!samples?[]:tr.b.getFirstElement(samples).series.device.vSyncTimestamps);this.$.summaryTable.samples=samples;this.$.chart.setData(this.selection,vSyncTimestamps);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-power-sample-sub-view',tr.model.PowerSample,{multi:true,title:'Power Samples',});'use strict';(function(){const MultiDimensionalViewBuilder=tr.b.MultiDimensionalViewBuilder;Polymer({is:'tr-ui-a-multi-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.viewOption_=undefined;this.selection_=undefined;},ready(){const viewSelector=tr.ui.b.createSelector(this,'viewOption','tracing.ui.analysis.multi_sample_sub_view',MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW,[{label:'Top-down (Tree)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_TREE_VIEW},{label:'Top-down (Heavy)',value:MultiDimensionalViewBuilder.ViewType.TOP_DOWN_HEAVY_VIEW},{label:'Bottom-up (Heavy)',value:MultiDimensionalViewBuilder.ViewType.BOTTOM_UP_HEAVY_VIEW}]);Polymer.dom(this.$.control).appendChild(viewSelector);this.$.table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;this.updateContents_();},get viewOption(){return this.viewOption_;},set viewOption(viewOption){this.viewOption_=viewOption;this.updateContents_();},createSamplingSummary_(selection,viewOption){const builder=new MultiDimensionalViewBuilder(1,1);const samples=selection.filter(event=>event instanceof tr.model.Sample);samples.forEach(function(sample){builder.addPath([sample.userFriendlyStack.reverse()],[1],MultiDimensionalViewBuilder.ValueKind.SELF);});return builder.buildView(viewOption);},processSampleRows_(rows){for(const row of rows){let title=row.title[0];let results=/(.*) (Deoptimized reason: .*)/.exec(title);if(results!==null){row.deoptReason=results[2];title=results[1];}
 results=/(.*) url: (.*)/.exec(title);if(results!==null){row.functionName=results[1];row.url=results[2];if(row.functionName===''){row.functionName='(anonymous function)';}
 if(row.url===''){row.url='unknown';}}else{row.functionName=title;row.url='unknown';}
-this.processSampleRows_(row.subRows);}},updateContents_:function(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
-var samplingData=this.createSamplingSummary_(this.selection,this.viewOption);var total=samplingData.values[0].total;var columns=[this.createPercentColumn_('Total',total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',total),this.createSamplesColumn_('Self'),{title:'Function Name',value:function(row){if(row.deoptReason!==undefined){var spanEl=tr.ui.b.createSpan({italic:true,color:'#F44336',tooltip:row.deoptReason});spanEl.innerText=row.functionName;return spanEl;}
-return row.functionName;},width:'150px',cmp:(a,b)=>a.functionName.localeCompare(b.functionName),showExpandButtons:true},{title:'Location',value:function(row){return row.url;},width:'250px',cmp:(a,b)=>a.url.localeCompare(b.url),}];this.processSampleRows_(samplingData.subRows);this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_:function(title,samplingDataTotal){var field=title.toLowerCase();return{title:title+' percent',value:function(row){return tr.v.ui.createScalarSpan(row.values[0][field]/samplingDataTotal,{customContextRange:tr.b.math.Range.PERCENT_RANGE,unit:tr.b.Unit.byName.normalizedPercentage,context:{minimumFractionDigits:2,maximumFractionDigits:2},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};},createSamplesColumn_:function(title){var field=title.toLowerCase();return{title:title+' samples',value:function(row){return tr.v.ui.createScalarSpan(row.values[0][field],{unit:tr.b.Unit.byName.unitlessNumber,context:{maximumFractionDigits:0},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-sample-sub-view',tr.model.Sample,{multi:true,title:'Samples',});})();'use strict';Polymer({is:'tr-ui-a-multi-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){var ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);var ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).appendChild(ltv);this.requiresTallView_=true;return;}}
-Polymer.dom(this.$.content).textContent='';var mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;Polymer.dom(this.$.content).appendChild(mesv);var relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){Polymer.dom(this.$.content).appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)return false;var childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW'){return false;}
-return true;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-slice-sub-view',tr.model.ThreadSlice,{multi:true,title:'Slices',});'use strict';Polymer({is:'tr-ui-a-multi-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:true,title:'Thread Timeslices',});'use strict';Polymer({is:'tr-ui-a-user-expectation-related-samples-table',ready:function(){this.samples_=[];this.$.table.tableColumns=[{title:'Event(s)',value:function(row){var typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
-return typeEl;},width:'150px'},{title:'Link',width:'100%',value:function(row){var linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
-return linkEl;}}];},hasRelatedSamples:function(){return(this.samples_&&this.samples_.length>0);},set selection(eventSet){this.samples_=[];var samples=new tr.model.EventSet;eventSet.forEach(function(ue){samples.addEventSet(ue.associatedSamples);}.bind(this));if(samples.length>0){this.samples_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected user expectation(s).',selection:samples});}
-this.updateContents_();},updateContents_:function(){var table=this.$.table;if(this.samples_&&this.samples_.length>0){table.tableRows=this.samples_.slice();}else{table.tableRows=[];}
-table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-interaction-record-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;var selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:true,title:'User Expectations',});'use strict';Polymer({is:'tr-ui-a-single-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
-this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_:function(event){var rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-async-slice-sub-view',tr.model.AsyncSlice,{multi:false,title:'Async Slice',});'use strict';Polymer({is:'tr-ui-a-single-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){var cpuSlice=tr.b.getOnlyElement(selection);if(!(cpuSlice instanceof tr.model.CpuSlice)){throw new Error('Only supports thread time slices');}
-this.currentSelection_=selection;var thread=cpuSlice.threadThatWasRunning;var root=Polymer.dom(this.root);if(thread){Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;}else{root.querySelector('#process-name').parentElement.style.display='none';Polymer.dom(root.querySelector('#thread-name')).textContent=cpuSlice.title;}
-root.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.b.Unit.byName.timeDurationInMs);var runningThreadEl=root.querySelector('#running-thread');var timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{var threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);Polymer.dom(threadLink).textContent='Click to select';runningThreadEl.parentElement.style.display='';Polymer.dom(runningThreadEl).textContent='';Polymer.dom(runningThreadEl).appendChild(threadLink);}
-root.querySelector('#args').object=cpuSlice.args;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-cpu-slice-sub-view',tr.model.CpuSlice,{multi:false,title:'CPU Slice',});'use strict';function createAnalysisLinkTo(event){var linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.userFriendlyName);return linkEl;}
-Polymer({is:'tr-ui-a-single-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],listeners:{'singleEventSubView.customize-rows':'onCustomizeRows_'},set selection(selection){this.currentSelection_=selection;this.$.singleEventSubView.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},onCustomizeRows_:function(e){var event=tr.b.getOnlyElement(this.currentSelection_);var rows=e.rows;rows.unshift({name:'ID',value:event.id});rows.push({name:'From',value:createAnalysisLinkTo(event.startSlice)});rows.push({name:'To',value:createAnalysisLinkTo(event.endSlice)});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-flow-event-sub-view',tr.model.FlowEvent,{multi:false,title:'Flow Event',});'use strict';Polymer({is:'tr-ui-a-single-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.$.asv.selection=tr.b.getOnlyElement(selection).associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-frame-sub-view',tr.model.Frame,{multi:false,title:'Frame',});'use strict';Polymer({is:'tr-ui-a-single-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';var realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);Polymer.dom(this.$.content).appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-instant-event-sub-view',tr.model.InstantEvent,{multi:false,title:'Instant Event',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-instant-event-sub-view',tr.model.InstantEvent,{multi:true,title:'Instant Events',});'use strict';tr.exportTo('tr.ui.analysis',function(){var ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLDivElement.prototype,decorate:function(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents:function(){throw new Error('Not implemented');}};var options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView,};});'use strict';Polymer({is:'tr-ui-a-single-object-instance-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0){return false;}
+this.processSampleRows_(row.subRows);}},updateContents_(){if(this.selection===undefined){this.$.table.tableColumns=[];this.$.table.tableRows=[];this.$.table.rebuild();return;}
+const samplingData=this.createSamplingSummary_(this.selection,this.viewOption);const total=samplingData.values[0].total;const columns=[this.createPercentColumn_('Total',total),this.createSamplesColumn_('Total'),this.createPercentColumn_('Self',total),this.createSamplesColumn_('Self'),{title:'Function Name',value(row){if(row.deoptReason!==undefined){const spanEl=tr.ui.b.createSpan({italic:true,color:'#F44336',tooltip:row.deoptReason});spanEl.innerText=row.functionName;return spanEl;}
+return row.functionName;},width:'150px',cmp:(a,b)=>a.functionName.localeCompare(b.functionName),showExpandButtons:true},{title:'Location',value(row){return row.url;},width:'250px',cmp:(a,b)=>a.url.localeCompare(b.url),}];this.processSampleRows_(samplingData.subRows);this.$.table.tableColumns=columns;this.$.table.sortColumnIndex=1;this.$.table.sortDescending=true;this.$.table.tableRows=samplingData.subRows;this.$.table.rebuild();},createPercentColumn_(title,samplingDataTotal){const field=title.toLowerCase();return{title:title+' percent',value(row){return tr.v.ui.createScalarSpan(row.values[0][field]/samplingDataTotal,{customContextRange:tr.b.math.Range.PERCENT_RANGE,unit:tr.b.Unit.byName.normalizedPercentage,context:{minimumFractionDigits:2,maximumFractionDigits:2},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};},createSamplesColumn_(title){const field=title.toLowerCase();return{title:title+' samples',value(row){return tr.v.ui.createScalarSpan(row.values[0][field],{unit:tr.b.Unit.byName.unitlessNumber,context:{maximumFractionDigits:0},});},width:'60px',cmp:(a,b)=>a.values[0][field]-b.values[0][field]};}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-sample-sub-view',tr.model.Sample,{multi:true,title:'Samples',});})();'use strict';Polymer({is:'tr-ui-a-multi-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.selection_=undefined;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;if(tr.isExported('tr.ui.e.chrome.cc.RasterTaskSelection')){if(tr.ui.e.chrome.cc.RasterTaskSelection.supports(selection)){const ltvSelection=new tr.ui.e.chrome.cc.RasterTaskSelection(selection);const ltv=new tr.ui.e.chrome.cc.LayerTreeHostImplSnapshotView();ltv.objectSnapshot=ltvSelection.containingSnapshot;ltv.selection=ltvSelection;ltv.extraHighlightsByLayerId=ltvSelection.extraHighlightsByLayerId;Polymer.dom(this.$.content).textContent='';Polymer.dom(this.$.content).appendChild(ltv);this.requiresTallView_=true;return;}}
+Polymer.dom(this.$.content).textContent='';const mesv=document.createElement('tr-ui-a-multi-event-sub-view');mesv.selection=selection;Polymer.dom(this.$.content).appendChild(mesv);const relatedEvents=document.createElement('tr-ui-a-related-events');relatedEvents.setRelatedEvents(selection);if(relatedEvents.hasRelatedEvents()){Polymer.dom(this.$.content).appendChild(relatedEvents);}},get requiresTallView(){if(this.$.content.children.length===0)return false;const childTagName=this.$.content.children[0].tagName;if(childTagName==='TR-UI-A-MULTI-EVENT-SUB-VIEW'){return false;}
+return true;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-slice-sub-view',tr.model.ThreadSlice,{multi:true,title:'Slices',});'use strict';Polymer({is:'tr-ui-a-multi-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.$.content.eventsHaveSubRows=false;},get selection(){return this.$.content.selection;},set selection(selection){this.$.content.setSelectionWithoutErrorChecks(selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:true,title:'Thread Timeslices',});'use strict';Polymer({is:'tr-ui-a-user-expectation-related-samples-table',ready(){this.samples_=[];this.$.table.tableColumns=[{title:'Event(s)',value(row){const typeEl=document.createElement('span');typeEl.innerText=row.type;if(row.tooltip){typeEl.title=row.tooltip;}
+return typeEl;},width:'150px'},{title:'Link',width:'100%',value(row){const linkEl=document.createElement('tr-ui-a-analysis-link');if(row.name){linkEl.setSelectionAndContent(row.selection,row.name);}else{linkEl.selection=row.selection;}
+return linkEl;}}];},hasRelatedSamples(){return(this.samples_&&this.samples_.length>0);},set selection(eventSet){this.samples_=[];const samples=new tr.model.EventSet;eventSet.forEach(function(ue){samples.addEventSet(ue.associatedSamples);}.bind(this));if(samples.length>0){this.samples_.push({type:'Overlapping samples',tooltip:'All samples overlapping the selected user expectation(s).',selection:samples});}
+this.updateContents_();},updateContents_(){const table=this.$.table;if(this.samples_&&this.samples_.length>0){table.tableRows=this.samples_.slice();}else{table.tableRows=[];}
+table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-multi-interaction-record-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.currentSelection_=selection;this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get selection(){return this.currentSelection_;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;const selection=new tr.model.EventSet();this.currentSelection_.forEach(function(ir){ir.associatedEvents.forEach(function(event){selection.push(event);});});return selection;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:true,title:'User Expectations',});'use strict';Polymer({is:'tr-ui-a-single-async-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){if(selection.length!==1){throw new Error('Only supports single slices');}
+this.$.content.setSelectionWithoutErrorChecks(selection);this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}},getEventRows_(event){const rows=this.__proto__.__proto__.getEventRows_(event);rows.splice(0,0,{name:'ID',value:event.id});return rows;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-async-slice-sub-view',tr.model.AsyncSlice,{multi:false,title:'Async Slice',});'use strict';Polymer({is:'tr-ui-a-single-cpu-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){const cpuSlice=tr.b.getOnlyElement(selection);if(!(cpuSlice instanceof tr.model.CpuSlice)){throw new Error('Only supports thread time slices');}
+this.currentSelection_=selection;const thread=cpuSlice.threadThatWasRunning;const root=Polymer.dom(this.root);if(thread){Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;}else{root.querySelector('#process-name').parentElement.style.display='none';Polymer.dom(root.querySelector('#thread-name')).textContent=cpuSlice.title;}
+root.querySelector('#start').setValueAndUnit(cpuSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(cpuSlice.duration,tr.b.Unit.byName.timeDurationInMs);const runningThreadEl=root.querySelector('#running-thread');const timeSlice=cpuSlice.getAssociatedTimeslice();if(!timeSlice){runningThreadEl.parentElement.style.display='none';}else{const threadLink=document.createElement('tr-ui-a-analysis-link');threadLink.selection=new tr.model.EventSet(timeSlice);Polymer.dom(threadLink).textContent='Click to select';runningThreadEl.parentElement.style.display='';Polymer.dom(runningThreadEl).textContent='';Polymer.dom(runningThreadEl).appendChild(threadLink);}
+root.querySelector('#args').object=cpuSlice.args;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-cpu-slice-sub-view',tr.model.CpuSlice,{multi:false,title:'CPU Slice',});'use strict';function createAnalysisLinkTo(event){const linkEl=document.createElement('tr-ui-a-analysis-link');linkEl.setSelectionAndContent(new tr.model.EventSet(event),event.userFriendlyName);return linkEl;}
+Polymer({is:'tr-ui-a-single-flow-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],listeners:{'singleEventSubView.customize-rows':'onCustomizeRows_'},set selection(selection){this.currentSelection_=selection;this.$.singleEventSubView.setSelectionWithoutErrorChecks(selection);},get selection(){return this.currentSelection_;},onCustomizeRows_(e){const event=tr.b.getOnlyElement(this.currentSelection_);const rows=e.rows;rows.unshift({name:'ID',value:event.id});rows.push({name:'From',value:createAnalysisLinkTo(event.startSlice)});rows.push({name:'To',value:createAnalysisLinkTo(event.endSlice)});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-flow-event-sub-view',tr.model.FlowEvent,{multi:false,title:'Flow Event',});'use strict';Polymer({is:'tr-ui-a-single-frame-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.$.asv.selection=tr.b.getOnlyElement(selection).associatedAlerts;},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-frame-sub-view',tr.model.Frame,{multi:false,title:'Frame',});'use strict';Polymer({is:'tr-ui-a-single-instant-event-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},set selection(selection){Polymer.dom(this.$.content).textContent='';const realView=document.createElement('tr-ui-a-single-event-sub-view');realView.setSelectionWithoutErrorChecks(selection);Polymer.dom(this.$.content).appendChild(realView);this.currentSelection_=selection;},get selection(){return this.currentSelection_;}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-instant-event-sub-view',tr.model.InstantEvent,{multi:false,title:'Instant Event',});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-multi-instant-event-sub-view',tr.model.InstantEvent,{multi:true,title:'Instant Events',});'use strict';tr.exportTo('tr.ui.analysis',function(){const ObjectInstanceView=tr.ui.b.define('object-instance-view');ObjectInstanceView.prototype={__proto__:HTMLDivElement.prototype,decorate(){this.objectInstance_=undefined;},get requiresTallView(){return true;},set modelEvent(obj){this.objectInstance=obj;},get modelEvent(){return this.objectInstance;},get objectInstance(){return this.objectInstance_;},set objectInstance(i){this.objectInstance_=i;this.updateContents();},updateContents(){throw new Error('Not implemented');}};const options=new tr.b.ExtensionRegistryOptions(tr.b.TYPE_BASED_REGISTRY_MODE);options.mandatoryBaseClass=ObjectInstanceView;options.defaultMetadata={showInTrackView:true};tr.b.decorateExtensionRegistry(ObjectInstanceView,options);return{ObjectInstanceView,};});'use strict';Polymer({is:'tr-ui-a-single-object-instance-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get requiresTallView(){if(this.$.content.children.length===0){return false;}
 if(this.$.content.children[0]instanceof
-tr.ui.analysis.ObjectInstanceView){return this.$.content.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){var instance=tr.b.getOnlyElement(selection);if(!(instance instanceof tr.model.ObjectInstance)){throw new Error('Only supports object instances');}
-Polymer.dom(this.$.content).textContent='';this.currentSelection_=selection;var typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){var customView=new typeInfo.constructor();Polymer.dom(this.$.content).appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_:function(instance){var html='';html+='<div class="title">'+
+tr.ui.analysis.ObjectInstanceView){return this.$.content.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){const instance=tr.b.getOnlyElement(selection);if(!(instance instanceof tr.model.ObjectInstance)){throw new Error('Only supports object instances');}
+Polymer.dom(this.$.content).textContent='';this.currentSelection_=selection;const typeInfo=tr.ui.analysis.ObjectInstanceView.getTypeInfo(instance.category,instance.typeName);if(typeInfo){const customView=new typeInfo.constructor();Polymer.dom(this.$.content).appendChild(customView);customView.modelEvent=instance;}else{this.appendGenericAnalysis_(instance);}},appendGenericAnalysis_(instance){let html='';html+='<div class="title">'+
 instance.typeName+' '+
 instance.id+'</div>\n';html+='<table>';html+='<tr>';html+='<tr><td>creationTs:</td><td>'+
 instance.creationTs+'</td></tr>\n';if(instance.deletionTs!==Number.MAX_VALUE){html+='<tr><td>deletionTs:</td><td>'+
 instance.deletionTs+'</td></tr>\n';}else{html+='<tr><td>deletionTs:</td><td>not deleted</td></tr>\n';}
-html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';Polymer.dom(this.$.content).innerHTML=html;var snapshotsEl=Polymer.dom(this.$.content).querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){var snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);Polymer.dom(snapshotsEl).appendChild(snapshotLink);});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-instance-sub-view',tr.model.ObjectInstance,{multi:false,title:'Object Instance',});'use strict';Polymer({is:'tr-ui-a-single-object-snapshot-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0){return false;}
-if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView){return this.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){var snapshot=tr.b.getOnlyElement(selection);if(!(snapshot instanceof tr.model.ObjectSnapshot)){throw new Error('Only supports object instances');}
-Polymer.dom(this).textContent='';this.currentSelection_=selection;var typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){var customView=new typeInfo.constructor();Polymer.dom(this).appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_:function(snapshot){var instance=snapshot.objectInstance;Polymer.dom(this).textContent='';var titleEl=document.createElement('div');Polymer.dom(titleEl).classList.add('title');Polymer.dom(titleEl).appendChild(document.createTextNode('Snapshot of '));Polymer.dom(this).appendChild(titleEl);var instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);Polymer.dom(titleEl).appendChild(instanceLinkEl);Polymer.dom(titleEl).appendChild(document.createTextNode(' @ '));Polymer.dom(titleEl).appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument,inline:true,}));var tableEl=document.createElement('table');Polymer.dom(this).appendChild(tableEl);var rowEl=document.createElement('tr');Polymer.dom(tableEl).appendChild(rowEl);var labelEl=document.createElement('td');Polymer.dom(labelEl).textContent='args:';Polymer.dom(rowEl).appendChild(labelEl);var argsEl=document.createElement('td');argsEl.id='args';Polymer.dom(rowEl).appendChild(argsEl);var objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;Polymer.dom(argsEl).appendChild(objectViewEl);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-snapshot-sub-view',tr.model.ObjectSnapshot,{multi:false,title:'Object Snapshot',});'use strict';Polymer({is:'tr-ui-a-power-sample-table',ready:function(){this.$.table.tableColumns=[{title:'Time',width:'100px',value:function(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value:function(row){return tr.v.ui.createScalarSpan(row.powerInW,{unit:tr.b.Unit.byName.powerInWatts});}}];this.sample=undefined;},get sample(){return this.sample_;},set sample(sample){this.sample_=sample;this.updateContents_();},updateContents_:function(){if(this.sample===undefined){this.$.table.tableRows=[];}else{this.$.table.tableRows=[this.sample];}
-this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-single-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_:function(){if(this.selection.length!==1){throw new Error('Cannot pass multiple samples to sample table.');}
-this.$.samplesTable.sample=tr.b.getOnlyElement(this.selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-power-sample-sub-view',tr.model.PowerSample,{multi:false,title:'Power Sample',});'use strict';Polymer({is:'tr-ui-a-single-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},ready:function(){this.$.content.tableColumns=[{title:'',value:row=>row.title,width:'100px'},{title:'',value:row=>row.value,width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
-var sample=tr.b.getOnlyElement(this.currentSelection_);var table=this.$.content;var rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});var callStackTableEl=document.createElement('tr-ui-b-table');callStackTableEl.tableRows=sample.getNodesAsArray().reverse();callStackTableEl.tableColumns=[{title:'function name',value:row=>row.functionName||'(anonymous function)'},{title:'location',value:row=>row.url}];callStackTableEl.rebuild();rows.push({title:'Call stack',value:callStackTableEl});table.tableRows=rows;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-sample-sub-view',tr.model.Sample,{multi:false,title:'Sample',});'use strict';Polymer({is:'tr-ui-a-single-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-slice-sub-view',tr.model.ThreadSlice,{multi:false,title:'Slice',});'use strict';Polymer({is:'tr-ui-a-single-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){var timeSlice=tr.b.getOnlyElement(selection);if(!(timeSlice instanceof tr.model.ThreadTimeSlice)){throw new Error('Only supports thread time slices');}
-this.currentSelection_=selection;var thread=timeSlice.thread;var root=Polymer.dom(this.root);Polymer.dom(root.querySelector('#state')).textContent=timeSlice.title;var stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];root.querySelector('#state').style.backgroundColor=stateColor;Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;root.querySelector('#start').setValueAndUnit(timeSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.b.Unit.byName.timeDurationInMs);var onCpuEl=root.querySelector('#on-cpu');Polymer.dom(onCpuEl).textContent='';var runningInsteadEl=root.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());Polymer.dom(cpuLink).textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;Polymer.dom(onCpuEl).appendChild(cpuLink);}else{Polymer.dom(onCpuEl.parentElement).removeChild(onCpuEl);var cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){var cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread){Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.thread.userFriendlyName;}else{Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.title;}
+html+='<tr><td>snapshots:</td><td id="snapshots"></td></tr>\n';html+='</table>';Polymer.dom(this.$.content).innerHTML=html;const snapshotsEl=Polymer.dom(this.$.content).querySelector('#snapshots');instance.snapshots.forEach(function(snapshot){const snapshotLink=document.createElement('tr-ui-a-analysis-link');snapshotLink.selection=new tr.model.EventSet(snapshot);Polymer.dom(snapshotsEl).appendChild(snapshotLink);});}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-instance-sub-view',tr.model.ObjectInstance,{multi:false,title:'Object Instance',});'use strict';Polymer({is:'tr-ui-a-single-object-snapshot-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get requiresTallView(){if(this.children.length===0){return false;}
+if(this.children[0]instanceof tr.ui.analysis.ObjectSnapshotView){return this.children[0].requiresTallView;}},get selection(){return this.currentSelection_;},set selection(selection){const snapshot=tr.b.getOnlyElement(selection);if(!(snapshot instanceof tr.model.ObjectSnapshot)){throw new Error('Only supports object instances');}
+Polymer.dom(this).textContent='';this.currentSelection_=selection;const typeInfo=tr.ui.analysis.ObjectSnapshotView.getTypeInfo(snapshot.objectInstance.category,snapshot.objectInstance.typeName);if(typeInfo){const customView=new typeInfo.constructor();Polymer.dom(this).appendChild(customView);customView.modelEvent=snapshot;}else{this.appendGenericAnalysis_(snapshot);}},appendGenericAnalysis_(snapshot){const instance=snapshot.objectInstance;Polymer.dom(this).textContent='';const titleEl=document.createElement('div');Polymer.dom(titleEl).classList.add('title');Polymer.dom(titleEl).appendChild(document.createTextNode('Snapshot of '));Polymer.dom(this).appendChild(titleEl);const instanceLinkEl=document.createElement('tr-ui-a-analysis-link');instanceLinkEl.selection=new tr.model.EventSet(instance);Polymer.dom(titleEl).appendChild(instanceLinkEl);Polymer.dom(titleEl).appendChild(document.createTextNode(' @ '));Polymer.dom(titleEl).appendChild(tr.v.ui.createScalarSpan(snapshot.ts,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument,inline:true,}));const tableEl=document.createElement('table');Polymer.dom(this).appendChild(tableEl);const rowEl=document.createElement('tr');Polymer.dom(tableEl).appendChild(rowEl);const labelEl=document.createElement('td');Polymer.dom(labelEl).textContent='args:';Polymer.dom(rowEl).appendChild(labelEl);const argsEl=document.createElement('td');argsEl.id='args';Polymer.dom(rowEl).appendChild(argsEl);const objectViewEl=document.createElement('tr-ui-a-generic-object-view');objectViewEl.object=snapshot.args;Polymer.dom(argsEl).appendChild(objectViewEl);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-object-snapshot-sub-view',tr.model.ObjectSnapshot,{multi:false,title:'Object Snapshot',});'use strict';Polymer({is:'tr-ui-a-power-sample-table',ready(){this.$.table.tableColumns=[{title:'Time',width:'100px',value(row){return tr.v.ui.createScalarSpan(row.start,{unit:tr.b.Unit.byName.timeStampInMs});}},{title:'Power',width:'100%',value(row){return tr.v.ui.createScalarSpan(row.powerInW,{unit:tr.b.Unit.byName.powerInWatts});}}];this.sample=undefined;},get sample(){return this.sample_;},set sample(sample){this.sample_=sample;this.updateContents_();},updateContents_(){if(this.sample===undefined){this.$.table.tableRows=[];}else{this.$.table.tableRows=[this.sample];}
+this.$.table.rebuild();}});'use strict';Polymer({is:'tr-ui-a-single-power-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],ready(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;this.updateContents_();},updateContents_(){if(this.selection.length!==1){throw new Error('Cannot pass multiple samples to sample table.');}
+this.$.samplesTable.sample=tr.b.getOnlyElement(this.selection);}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-power-sample-sub-view',tr.model.PowerSample,{multi:false,title:'Power Sample',});'use strict';Polymer({is:'tr-ui-a-single-sample-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},ready(){this.$.content.tableColumns=[{title:'',value:row=>row.title,width:'100px'},{title:'',value:row=>row.value,width:'100%'}];this.$.content.showHeader=false;},get selection(){return this.currentSelection_;},set selection(selection){this.currentSelection_=selection;if(this.currentSelection_===undefined){this.$.content.tableRows=[];return;}
+const sample=tr.b.getOnlyElement(this.currentSelection_);const table=this.$.content;const rows=[];rows.push({title:'Title',value:sample.title});rows.push({title:'Sample time',value:tr.v.ui.createScalarSpan(sample.start,{unit:tr.b.Unit.byName.timeStampInMs,ownerDocument:this.ownerDocument})});const callStackTableEl=document.createElement('tr-ui-b-table');callStackTableEl.tableRows=sample.getNodesAsArray().reverse();callStackTableEl.tableColumns=[{title:'function name',value:row=>row.functionName||'(anonymous function)'},{title:'location',value:row=>row.url}];callStackTableEl.rebuild();rows.push({title:'Call stack',value:callStackTableEl});table.tableRows=rows;table.rebuild();}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-sample-sub-view',tr.model.Sample,{multi:false,title:'Sample',});'use strict';Polymer({is:'tr-ui-a-single-thread-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],get selection(){return this.$.content.selection;},set selection(selection){this.$.content.selection=selection;this.$.relatedEvents.setRelatedEvents(selection);if(this.$.relatedEvents.hasRelatedEvents()){this.$.relatedEvents.style.display='';}else{this.$.relatedEvents.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-slice-sub-view',tr.model.ThreadSlice,{multi:false,title:'Slice',});'use strict';Polymer({is:'tr-ui-a-single-thread-time-slice-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){const timeSlice=tr.b.getOnlyElement(selection);if(!(timeSlice instanceof tr.model.ThreadTimeSlice)){throw new Error('Only supports thread time slices');}
+this.currentSelection_=selection;const thread=timeSlice.thread;const root=Polymer.dom(this.root);Polymer.dom(root.querySelector('#state')).textContent=timeSlice.title;const stateColor=tr.b.ColorScheme.colorsAsStrings[timeSlice.colorId];root.querySelector('#state').style.backgroundColor=stateColor;Polymer.dom(root.querySelector('#process-name')).textContent=thread.parent.userFriendlyName;Polymer.dom(root.querySelector('#thread-name')).textContent=thread.userFriendlyName;root.querySelector('#start').setValueAndUnit(timeSlice.start,tr.b.Unit.byName.timeStampInMs);root.querySelector('#duration').setValueAndUnit(timeSlice.duration,tr.b.Unit.byName.timeDurationInMs);const onCpuEl=root.querySelector('#on-cpu');Polymer.dom(onCpuEl).textContent='';const runningInsteadEl=root.querySelector('#running-instead');if(timeSlice.cpuOnWhichThreadWasRunning){Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);const cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(timeSlice.getAssociatedCpuSlice());Polymer.dom(cpuLink).textContent=timeSlice.cpuOnWhichThreadWasRunning.userFriendlyName;Polymer.dom(onCpuEl).appendChild(cpuLink);}else{Polymer.dom(onCpuEl.parentElement).removeChild(onCpuEl);const cpuSliceThatTookCpu=timeSlice.getCpuSliceThatTookCpu();if(cpuSliceThatTookCpu){const cpuLink=document.createElement('tr-ui-a-analysis-link');cpuLink.selection=new tr.model.EventSet(cpuSliceThatTookCpu);if(cpuSliceThatTookCpu.thread){Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.thread.userFriendlyName;}else{Polymer.dom(cpuLink).textContent=cpuSliceThatTookCpu.title;}
 Polymer.dom(runningInsteadEl).appendChild(cpuLink);}else{Polymer.dom(runningInsteadEl.parentElement).removeChild(runningInsteadEl);}}
-var argsEl=root.querySelector('#args');if(tr.b.dictionaryLength(timeSlice.args)>0){var argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';Polymer.dom(argsEl).textContent='';Polymer.dom(argsEl).appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:false,title:'Thread Timeslice',});'use strict';Polymer({is:'tr-ui-a-single-user-expectation-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created:function(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.$.realView.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;},onCustomizeRows_:function(event){var ue=tr.b.getOnlyElement(this.selection);if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.b.Unit.byName.timeDurationInMs})});}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:false,title:'User Expectation',});'use strict';(function(){var EventRegistry=tr.model.EventRegistry;function getTabStripLabel(numEvents){if(numEvents===0){return'Nothing selected. Tap stuff.';}else if(numEvents===1){return'1 item selected.';}
+const argsEl=root.querySelector('#args');if(Object.keys(timeSlice.args).length>0){const argsView=document.createElement('tr-ui-a-generic-object-view');argsView.object=timeSlice.args;argsEl.parentElement.style.display='';Polymer.dom(argsEl).textContent='';Polymer.dom(argsEl).appendChild(argsView);}else{argsEl.parentElement.style.display='none';}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-thread-time-slice-sub-view',tr.model.ThreadTimeSlice,{multi:false,title:'Thread Timeslice',});'use strict';Polymer({is:'tr-ui-a-single-user-expectation-sub-view',behaviors:[tr.ui.analysis.AnalysisSubView],created(){this.currentSelection_=undefined;},get selection(){return this.currentSelection_;},set selection(selection){this.$.realView.addEventListener('customize-rows',this.onCustomizeRows_.bind(this));this.currentSelection_=selection;this.$.realView.setSelectionWithoutErrorChecks(selection);this.$.relatedSamples.selection=selection;if(this.$.relatedSamples.hasRelatedSamples()){this.$.events.style.display='';}else{this.$.events.style.display='none';}},get relatedEventsToHighlight(){if(!this.currentSelection_)return undefined;return tr.b.getOnlyElement(this.currentSelection_).associatedEvents;},onCustomizeRows_(event){const ue=tr.b.getOnlyElement(this.selection);if(ue.rawCpuMs){event.rows.push({name:'Total CPU',value:tr.v.ui.createScalarSpan(ue.totalCpuMs,{unit:tr.b.Unit.byName.timeDurationInMs})});}}});tr.ui.analysis.AnalysisSubView.register('tr-ui-a-single-user-expectation-sub-view',tr.model.um.UserExpectation,{multi:false,title:'User Expectation',});'use strict';(function(){const EventRegistry=tr.model.EventRegistry;function getTabStripLabel(numEvents){if(numEvents===0){return'Nothing selected. Tap stuff.';}else if(numEvents===1){return'1 item selected.';}
 return numEvents+' items selected.';}
-function createSubView(subViewTypeInfo,selection){var tagName;if(selection.length===1){tagName=subViewTypeInfo.singleTagName;}else{tagName=subViewTypeInfo.multiTagName;}
+function createSubView(subViewTypeInfo,selection){let tagName;if(selection.length===1){tagName=subViewTypeInfo.singleTagName;}else{tagName=subViewTypeInfo.multiTagName;}
 if(tagName===undefined){throw new Error('No view registered for '+
 subViewTypeInfo.eventConstructor.name);}
-var subView=document.createElement(tagName);var title;if(selection.length===1){title=subViewTypeInfo.singleTitle;}else{title=subViewTypeInfo.multiTitle;}
+const subView=document.createElement(tagName);let title;if(selection.length===1){title=subViewTypeInfo.singleTitle;}else{title=subViewTypeInfo.multiTitle;}
 title+=' ('+selection.length+')';subView.tabLabel=title;subView.selection=selection;return subView;}
-Polymer({is:'tr-ui-a-analysis-view',ready:function(){this.brushingStateController_=undefined;this.lastSelection_=undefined;this.tabView_=document.createElement('tr-ui-b-tab-view');this.tabView_.addEventListener('selected-tab-change',this.onSelectedSubViewChanged_.bind(this));Polymer.dom(this).appendChild(this.tabView_);},set tallMode(value){Polymer.dom(this).classList.toggle('tall-mode',value);},get tallMode(){return Polymer.dom(this).classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_.bind(this));}
+Polymer({is:'tr-ui-a-analysis-view',ready(){this.brushingStateController_=undefined;this.lastSelection_=undefined;this.tabView_=document.createElement('tr-ui-b-tab-view');this.tabView_.addEventListener('selected-tab-change',this.onSelectedSubViewChanged_.bind(this));Polymer.dom(this).appendChild(this.tabView_);},set tallMode(value){Polymer.dom(this).classList.toggle('tall-mode',value);},get tallMode(){return Polymer.dom(this).classList.contains('tall-mode');},get tabView(){return this.tabView_;},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_.bind(this));}
 this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_.bind(this));}
-this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_:function(e){if(this.lastSelection_&&this.selection.equals(this.lastSelection_)){return;}
-this.lastSelection_=this.selection;this.tallMode=false;this.tabView_.label=getTabStripLabel(this.selection.length);var eventsByBaseTypeName=this.selection.getEventsOrganizedByBaseType(true);var ASV=tr.ui.analysis.AnalysisSubView;var eventsByTagName=ASV.getEventsOrganizedByTypeInfo(this.selection);var newSubViews=[];eventsByTagName.forEach(function(events,typeInfo){newSubViews.push(createSubView(typeInfo,events));});this.tabView_.resetSubViews(newSubViews);},onSelectedSubViewChanged_:function(){var selectedSubView=this.tabView_.selectedSubView;if(!selectedSubView){this.tallMode=false;this.maybeChangeRelatedEvents_(undefined);return;}
-this.tallMode=selectedSubView.requiresTallView;this.maybeChangeRelatedEvents_(selectedSubView.relatedEventsToHighlight);},maybeChangeRelatedEvents_:function(events){if(this.brushingStateController){this.brushingStateController.changeAnalysisViewRelatedEvents(events);}}});})();'use strict';Polymer({is:'tr-ui-b-dropdown',ready:function(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_:function(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_:function(e){var or=this.$.outer.getBoundingClientRect();var inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)return;e.preventDefault();this.toggle_();},toggle_:function(){if(!this.isOpen){this.show();}else{this.close();}},show:function(){if(this.isOpen)return;Polymer.dom(this.$.outer).classList.add('open');var ddr=this.$.outer.getBoundingClientRect();var rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();var ddw=this.$.outer.getBoundingClientRect().width;var w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_:function(e){if(!this.isOpen)return;if(e.srcElement!==this.$.dialog)return;e.preventDefault();this.close();},onDialogCancel_:function(e){e.preventDefault();this.close();},close:function(){if(!this.isOpen)return;this.$.dialog.close();Polymer.dom(this.$.outer).classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){var FaviconsByHue={blue:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAlrklEQVR4Ae2dCXwdVb3H5265yc3SpEk3ukEXCqVUBLT4Wm19oFKtaN0fKijy9CMguPBarIJsIiA8qsjTh7SllAoFeVBaEARkLV1ooXtL0yRdkqZp9u3uy/v/5uY/OZm75y659+acdnLOnP385zv/+58zZ2YMinTplIAhzsoDceaT2RKUQLwHIMFqh0V2ll0kn4XA6byv9/Vw834kX19e7keRQCzhRyk6bJJYRvD1YTXuhRdeqDj77LPPtNls400mU7HRaCzFFggEVJ/iSqhsicFgKIXUKL6bvB6fz9fj9/u7Kb4bPjaK67Xb7Q0HDhw49IUvfKEd2XUb7WpxHIYvXRgJ8AELkzRso1gmKrwkBfjG7373u5Zly5ZNKS8vn2G1Ws80m83YphPI0wnQUemQFp0IzQR9tdfrxXbI5XId6ujo+PCuu+6qXbNmjYfa9NMmngDoBmt+hIe944M53AUhwqwCvXTp0qJrr732opKSkk8XFhZ+imC+gIAryAZB0QnlJuB3OJ3Ot3p6el5/6KGHttxzzz0O6pse+GEP+3AGnKE2EhgG0tAFt99++4WkoT9tsVgW0DaH4guzAeg4+uD0eDxbaXuDNPzrt9xyy3bS8G4qB8BF6OOoKr+yDDfAB0B91VVXFf72t7+9lLT05QUFBZfQoYWtnA+ux+12v0ra/W+/+tWvXlq5cqWTBjUsYR8OgDPU8KGtjR9++OHHx4wZ8+2ioqKv0X4lbfnsWh0Ox9+bmprWzpgxYxsNFBpd1Op5bcbkM+AMtgr11q1bTz/zzDP/gy4Qv02zGtPzmehIY6MZmmq6UF176NChJ+bMmXOkD3QR9khFczY+HwEXwTbV1NTMI229FCYIXSTm43gTho8uUgMwYUir3zN16tR3qAIfbXkJej4dcIxF1dbkm44ePfqZqqqqpTT7MZf2pYsgAZqN2dTS0nLP5MmTX6EsDDrDHqFU7kTnA+Aa2BMmTDBv2bLliyNHjlxCZsgFuXMYhr6nZL7saGtru/eiiy7aUF9f76UeAfKcBz2XAUffVbgJbAuB/Y3KysoldONl5tDjkrs9oBtL+1tbWwH6UwS6/mZSzg0sVwHXTJG9e/deOGXKlOWksS/MOelncYdJo2+vra396axZs7ZTN0XTJYt7Hdq1XANc1dg0DNOqVatGLl68+DZa/3E1XTwCeOn6JLCly6ncU9+mNLnBZRLOYPAHHI5H2l5/8TdHbl3SRjUx6DkztZgrgKOfDLf5xIkT36moqLiLzJG0rAFJAomsKDp1W51S74IZnSIX8DcrXV3LlK/Oe5xqZPsckGc96LkAOPpowrZ79+5ZNK31BzkzQtKI4qxvV0dJTSLJ592kHKu7QfnPxXupFmhzbFkNeTb/tGsae/bs2Va6wr/lrLPO2izhTgLQZIuaaMp1yvTNyvNbb1HomFB1ZtrAUNYqymztGMNt2rhx44T58+evohs1n0r2+AyX8mnT4KIAvZ63lA82f1/55TX1FJ21tnk2As4zJObq6urP0BTgCmlri2TFDmcEcHQDtnlz4w+Uyz+Hm0Rsm2PuPGtcNpkomtZesGBBYXNz8210d+05CXfWsBLaEQNd5I+e8JyyYettCh0zyoBrpawyWbJFg2twv/jiixPnzZu3mhZFzQ2VqIyJRwIZ0+BiZzyeTcqebVcqS350nKKzxmTJBsDRB3WWZN++fXPpps060tpVouxkODEJDAng6GIg0KI0Hv+mcsXnN9FeVsyyDLWJwnCbadXfomnTpm2UcCcGc1blNhiqlNMmblT+9soi6hdmWKC4hlSJDiXgaBsCsNDKvysnTpz4JIWLaJMupyVgKFLGjHtSefrNK2kYFtpwjIeMs6FqWIOb7kr+Yty4cX+m2+0446XLBwkESHuPrPqz8uymX9BwhhTyoQBchZseQiigdcj30grAO+SDCPlAtW4MeLikdMQdyvqt9yp0rCl1SDR5pgFX4V64cGERvdhmRWlp6XU6scjdfJNAcfF1ysqNK5Q5C2F+ZhzyTF4AqHCPGjXKSjdwHqUHfr+ab8cyW8YzZLMo0QTgcj2jfO/S7ynNzS7KxtOI0UqkJC1TGlyFm3pccPDgwfsk3Ck5drlVidX6VWXFxvvAAG0Z0+SZAJzhtjQ2Ni6ld5D8KLeOjOxtyiRgK/6R8uy7S6m+jF14phtwmEBow3L8+PGr6FnJm1MmLFlRbkqgtOxm5am3rgITtIGNtJrJ6QQcHcdPkYUuKL9MsybLKSydlICijKxcrjz+0pdJFKzJ0wZ5ugBnuM27du2aT7ffV9JUIGCXTkqAJEAsjJ2wQlm1fj7tpPWOZzoAB9yo1/zSSy/NoLdJraMwFsdLJyUgSqBQGX/GOuX+FTMoEpCDmZRr8nQBbqIHgovnzp27mtaWlImjkmEpAU0CYGPmR1crF19cTHH4hU854KmuECcMOmo9derUAyNGjLiawtJlWAJZOQ8eTQb27keUyz7xM8qS8jnyVGpwNk0s+/fv/4qEO9oRlWkDJGArvVpZ89JXKC7lMyupApzhNm/YsGH6GWec8eCAAcgdKYFYEhhz2oPK3X+ZTtlSao+nEnDzxWRL0eNmj0q7O9bRlOkhEoA9ft6cR5WPq/Y4IE+J+ZyKSjS7m56jvK+srEzeqQw5epmNyDkbXBRPT8//Kl++6EaKSok9nqwG10yTHTt2fJpWB0q4xYMlw4lLoJhu5z/y3KepYEpMlWQBV7U3mSXFNN99H71YPfEByRJSAqIEwND4yfcpFyzgqcOkGE2mMGtvy2OPPXY9vZjnTLGfMiwlMGgJWCxnKktv/QmVT3pWZbCAM9zmxx9//IzRo0fj0STppARSJ4HykTcqN//3GVRhUqZKMoCrC6no6Zy7yTSxpW5ksiYpAZKA0WhTPj73dxRKakHWYABn7W3Zs2cPvjH5eXlApATSIoGi4i8oK56/tA9ysAr2EnKDARxlzJdddlkJ3dC5N6HWZGYpgUQlMH7SvbRWpYSKsamSUA2JAs7a2/ynP/3pOvrc9eSEWpOZpQQSlYDZPFn54a/xcDoDnpAWTxRw5DfRJ7DL6HUPP060rzK/lMCgJFA+8sfKZd/CqlRc9yXEbCKZWXtbli1b9gN6EX3loDorC0kJJCoBk6lS+ebVP6BiCU8bJgI48ppxU2fs2LHXJNpHmV9KICkJVFZdo3zsY7j5w6ZKXNXFCzhrb/PDDz/8HbK9x8ZVu8wkJZAqCZjNY5Wf3vkdqo4Bj8sWjxdw5DPRt3KKTjvtNNxhkk5KIPMSqBz1E2Xq7ITekBUP4Ky9LevWrfsGae9JmR+ZbFFKgCRgLpik3HL3NygUty0eD+Cq9h4/fnwBbTdIQUsJDKkERo+9QSkr47ubMfmNlQHaG5v56aef/ndaUDVtSAcnG5cSMFumKXc/fDGYpI35jCiXeADH3KOZ7lp+Sy6HjShHmZApCWA57dgJ3wKTtIFNQB7RxQIc6abLL7+cniEesTBiLTJBSiCTEiguWah8/isjqEkAHpXhaIk4M5BuXrp06ZfoOUtcvUonJTD0EjCaipSvff9L1JGYU4bRAEeaCjh9P+fr0jwZ+uMqe9AnAZgpo0Z/nfYY8IgcR0qA9sZmeuCBBybZbLZ/66taelIC2SEBKzF5zTJMWbMdDl5DXDTAVe29aNGib5D2jpQvpEIZISWQEQkYicm5C0QtnjDg6uwJPY72tYx0WDYiJZCoBMorGXDW4iE1hNPMOBMQb1qzZs0MmvueHlJKRmS1BCZYYZoOA2exTFd+dT/eTsuzKSFaPJwkNMDPO++8+fLiMvdA+Z8JJcqPN+9RGnocoZ0PBELjFF2cbjdYIEykvq4wWehd4APb05dBari4gaWCe/p8AT+uFOdT4j7aoJTB7oAGowFurqqqmicBV5QPmgLKX3b7lVbHANmRLLPVVSjnGT6hzFRa44dHHEqIHhQThXC8+YQiqQ66K9rnvakoD1O9DPiAJvSAo8vYjMXFxWZ6U9VFA3IP052fv+5VGntzBW4+SCYl4KtQ/L3tpCBJ0+WpC/hKLgKrvb29DDj41Q4WIvUOcaZHH310lslkGqlPHI77uQd38CgZTBbSVBVKXk+CGYwjS758/ywwS1sIz/oI1uCmmTNnflKaJ7l/OmuQG3migQ9xnvg0W2gaN/2TfYDzoLQDFw5wVYOT/T1XAq7JKacDKuS2csVg1B/unB6W2nkwaiiumEs7rMEBueZEG5zpN9Gt+QKyv+douWQg5yXAkPvtHYO78MxiCZisJXNsVRML7C3HndRN5li1w/WnNPaNDz744Ll0ZpRm8Zhk1wYhAYacjPJBlM7eIgHFUFryxZvPpR6q/Io9DavBJ0yYcJY0T0Qx5U84CDnNrtjb82dQZHqZysefRQPaRltEDc4JRlr7PS1/Ri9HopeAwWRWjLYKQiF/NLnBWgpmocGZY3XYoomCBOybaPXgNKnBVfnk7R8V8qLyvIAcrBoLiqaCXdoYcvXYMeB8KmPfSIBPUVPln7yWQD/kjEEOD7fABsBVfvtGoTIdYoOPHDnSXFhYODmHhyq7noAEgpCPUPyOTiql3QBMoIbsyGo0F04uInYdbW3RTZRbb711AnXZmh3dlr3IhAQYcpooz0RzaWmDTk1r0YLrwS4GwRaJuoMGmXrjOeecI5fHQiLDzKmQF9ILXFXIGYfc8q2jZ4JdBlyFnE9ZHolx1KhR8gJzmMHNw9Ugz8U7nrijWToyZCZFtMEBu7GoqGgiD1j6w08CKuTWUsXv6s65O56GApVdlWM+cnoNbqB3D+JzEdINYwkw5DlnkxvNYJetEdVEETU4Ioy0RLZEzoEPY7r7hh6EvIQ0eQ/FZP/sCpilPgNwKG0VbgyFdzTqCXC8ZFw6KQEAoxgLS3NoPbkR7GosIyxqcBxSgwQcYpCOJWDAOnIrKUbS5AH9M5GcKUt8OiEZcK1HbIMjQiVfAq7JRgb6JADIDQR5tpuuAaMGuGaisAbXIiTgkutwEujX5L2UnJ02uSEIOHdfZVpqcBaH9GNKIKjJQ6yAmOUylYHsa+6cprBZg3MfpA3OkpB+WAkENXmxEnDbs2+e3KABrvU9RINTih56LbMMSAlAAqomL7BRQFOU2SGYgMouOqV1jGHWIrxer50+8iofV8uOQ5a1vVA1OUEecOPtWdlhkxsUH/2saE5lmufBtVifz4erCOmkBGJKIKjJ8V0ETT/GLJPODAG/X8+uOg+O0087BaHB09kJWXd+SSCoyYuUgIceaB/qeXL/AA2uci3a4JB8QGrw/AIwE6NRNbmlcMht8oBftT40ZY2xsw2OsJogAYcopEtUAqomt5Am9w6dJg8ENPNagzysBs/2W7KJCl/mz4wE8OYsg3loNLnKbNAG1+DGqFmDI1LdpA2eGRjytRX19XAEecDr6kMqcyM1BNTrR41ltCxqcAYc6yOlkxIYtASCmhyP9WZ2doVmUXhtL1hWHWtw3lccDkcb1H22L6zROiwDWSmBoCa39mnyDHSRmPV7nG36lliDs1r3t7e31+kzyX0pgcFIQNPkGbrj6be3gV287Z95Vk0U7MCpkdXV1bXyIjMoEPk3eQmokJsKglOIAD1tm6J4Wo7UMsd9PQ+wBse+CvgzzzwjAe+TjvRSIwGGnB4qS02F4WohE8W58zk94CGzKP6XX3652+VyNdN6lFHh6pFxUgKDkQAgDygWxeDzDKZ47DJeV3PvvtfpVQChJgoKs80C+8Xf09NzRJopEIt0qZQAIFfou0GpXoUIVv0uxxHqq8ov+cxzyDShmsFut9elcmCyLikBloAKuZEm71Jsi/vdKrMi4GqTbIMz8cjgw0yK1OB8SKSfagkMgDwVlZMGDzg6oJR9tIFh5lmzwdEMR/pPnjxZiwjppATSJQHVJg/QRaffm3wT9Gvg624GswPgRsXhNLh//fr1u2nRFYCXTkogbRJQbybCXEl2diXgCzh2bthNFQHwAZAz4BgEgEaijz4C29zZ2VkjzRSIRbp0SiAIOT7MgCnExDeyThS/s7uma+vaZqpANFHUbusBZ8i9ra2tWyXgqozknzRLQIMcF56JOiLc19O6lYrB1hmgvVGVCDj2VQ1Ovq+mpmaLBBwikS4TElAhx7vJE55dIWhb6rZQH6G9WYNrXRYBh/ZmDe5buXLlVj85LacMSAmkWQIa5Im0Q4x2bXkUGpzhZo7VWsIBrp4JGzZsaCc7/KDU4olIW+ZNVgL9kMe2x4P2d+dB+86X8NFP1uARAUffWIPDnvHSdOE2CTjEIl0mJRCEPA57nAj3dzXj468qr+SzDa51V9TgiGTAcTZ4yQ7fLAHXZCUDGZSABnlUm5wgba3dDFZpE00Uraf6Bx5YveNM8C5fvnzbJZdc4iwuLqYH7Yavq+ytURq70rRIKIvEGlmZAYswDjZCRBchLUJ0ULeGqYzaQL8AfEj/PA5nz8u/Zw3O2ntAC+EAR0bVnnn33Xe7Gxsb35gyZcqlxhR9mGj/oU7liWfrlPZOd5jRZGfUbK9bmUnPGIYIeEB3B8i1PyUKBHTo+vPFEYrcfpR6orYfR6NZmiUQ8Cs9XU1vbDiyEysI2f5myLVe6wFHAqSlanDyPTt37nz+9NNPTxngv/3DHqW5lV4tkGPO67ErPi+9pgw/mYAGfjyO8zJo+vL6dH2dmc6vb1/fP31/9Pn1+7HK69P15fXt9eUP+LxKR/OB5yk7flrFOfABNehtcCSKgHuvu+66t2n5bGtk7TGgvpg7uQg3BmW22BSTGa8pIwehx+s4L3wxzOXFOM4j+sjHecSwmEcMi3nEsJhHDIt5ENY75IXjMhxWI+P4E6u8Pp3bYV/fHsWDRb/f1Vq3b9XblBzxAhNFowEOte+hlYWO+vr6f6QKcDSaq06F3FQYdeUEow9fDGfLmMU+ieFI/RPziOFU5Y9UT/T4gOJ2tP/D7e7Bmz+hwcNeYKKOcIAjHiaKZqa8+uqr6+l9KYgf9g6QG/sgxwHXbxAQgyCG9fmGal/skxiO1B8xjxhOVf5I9USLV8j+7mjd/Rz1RzRPwGuIiwQ4zBScFaDas3Tp0r0dHR2HpRYPyo8hD+7Jv5mUABj0eeyHjx58Yh+1y4CDVTAb4qIBzpCjEjfNiW+Qd+775dcPeTRdI9NCf+OSlQl98M3RvAFM0sbmCVhNCHAcSah8TYuvXr16PT2MjAql65OAapPjXXzRnP4iCnk5Llw5ToMvhsPlzYU4cQxiOFLfxTxiuC+/3+/xNB9/cz3tito7rHmCIpE0ONJwRrAd7l61alXjkSNHXpBaHKLpd5hZMfELJ3FA9Buy8oESw/p8vC/mEcOcnmu+OAYxHGkcYh4xTPlx38DtaHnhZP3rjZQEDR5xehBF4eIFXDVT1q5d+whp8YhnS7DK4fdXhdyEd/FJl04J+ANef3PDpkeoDTZPkgIcfR2gxe+7776aY8eO/VNq8dDD2A95sjamLE8/eSTggRsuLj2Otn821D5fQ4lxaW8cpWgaHOnQ1pqZQmHXU0899VePxxPWoEeB4ewYchwadhzmw4V4jhPDnJ6oL9YhhuOtRywjhuMtr88n1iGGOZ8YJ4Y5PZKv+H2BthOb/0pl8F5mEfCoFkUswNEHVICLTdVMufPOOw+QFn9TanGIJtTBHjeSucIHCjkQZsfhSOmcL14/2fqSLa/vZ6z6YqXr68M+1p24nK1vHq3++wHaZfMETEaFG2XjARzaWgOcwq4XX3zxYdLiKC9dGAkw5Pqf2czso0OMkRhGXG5u9N5vpb3p/YdpAKy9AR+YjGlJxAs4a3GcPa4lS5bsOnHixGapxUkaEVwQcnqrasYdw80wowMcl/HOJN0gtLfb1bH5yMHHd1FlDDhr75QAjk6yFsdVKyB3bty48UE5owLRRHYa5JgSY8dhniZDPMeJYU5P1BfrEMOR6hHzIBzLcV8j1aePR31cRgxzPjFODPel+xWvv6N5x4OUhCWoYA8MxqW9KV9cJgryAXBocQbcdeONN+6kd4k/J9eoQDyRnQq5se+Fk3yg2UcxDvcdULUmjotcbeQULhtvffr8XC6Sj5a5TORe9KdwXq5PXz5KOn0WUHH2nnyudt/qnVSMtXfMqcH+xuMHHGVYi6sXm2jwpptuWk4PJrfLNSqiSEPDGuShSTImggTUNSdee/uxA2uXUxaGO27bm6uNxwbnvKzF8fOABp2vvfZa89atW/8oLzhZRJF9zVyJnEWmCBKgb14qPZ01f2xv3o03VsE8AXNx295cVSKAo4yoxVXIFy9e/Aw91rZLXnCySCP7Jpo+NNLnPMQvHXAYfjz/UDuXEcNcVowTw5yeal9sQwxHakfMI4bF/HhiyuPq2LV/293PUB6GO2HtjfoHA7g4o4LGnWvWrLnL6XT6pKkCkUZ3gNxAL4HnA4rcCMfrOG+k8rHS420n3nyJthcrPxgK+D2+5oa37qI+qHyRj4vLhLU3xpAo4CjDgOOMUrX4HXfcse/AgQPr6I20SJcuhgQYcvVijS++pN938RpQHD0n1h378Cms99Zrb7CXkBsM4GiAIVenDGnfccMNNzzU0tLSKE2V+OSvmiuYXZFOkwDmvD2e7saa/X99iCLxOBoAF7W3ljfewGABZ1ucpw2d7733XusTTzxxE33+xCNNlfjED3vcqELON2WGr0+WCS03cXtaTmy6qbutppUkyHAnNO+tl/xgAUc9DLmmxWnacAeB/hDdANK3I/cjSCAIebi3d0QokKfRZHcrvZ01D9XtW72DhqjX3mBtUC5ZwGGqaFqcws5LL7109dGjR9+WN4DiPx7DHXLc0HE5Wt7es/m21WCob4PiTOimTjiJJwM46gPg2PiCE2ee/Wc/+9lvyB5vkvY4SSNO12+uxFkgT7LB7vZ6uptq9678DQ3JThsYggkAppgvCg7OJQs4WkUnMH2CMw6dc9ANoJNPPvnkL8ke90p7nCQSpzPS9CFscryHbzhsEEvA7/a2NLzzy46WXSdpV+WH/KQuLFEvu1QAzrY4mypqJ+lVE9u3bdv2Z9jjEnIWd2wfkBsM+W+T9813093K6j/X7l+9nSQjwp3UhaUo5VQAjvoY8gGmysKFC1fSgqxX3G6ckNLFKwEVcu3rY/k5swK729Hb9Mqed29fSXLRmyawCAZ9YSnKOVWAo06GHDTjQgGdti9atOjXdNH5noScpJGAU00VI74+ln+OXv2gOJ0t7x3cduevaXQqJ+TztGDK4IbkUg24aI+rkNNXIrquuOKKG+kBiYNyURZEHr/LR8j99OFXt6v94KH377/R4WjtImkAcBFuMJQS7Q1Jp0NFoHNiBw0Eube2tnbT/PnzFzz3UtMIA76mJV1cEjAYcIhInLgTkuMOZonH3XW8dvdff9zZur+JhtNLGwMO8zal2hviSgfgqBduAOhki7u6u7u3NHWO+yxNidkk5EEhxfM3CHmfSHN0zQq98Fjxunta6w+v+9GphneO0Wj0cKdUc7Nc0wW4qG608AcffNBrMlvfLx0x5XMGo7lAQs6HIbbfLytNnLELZUkOrO2mF2b2nDz64rX1hzccpG7p4YbmBuApd+kCHB3lI8G+2vnOlr0dBYVV+4tKxl1MswWW/gOX8rHlXYUsq+C8ChaeZv8/vOqYvo5hb2l48+d1+9fiNrwId8rmuyMd7HQCLrYJyDXQ20/tOGUxF+6wlU1aYDQWFPGBEwvIcHgJ9MtKE2f4jFkQq9rcnu72xrp//OTIgccx181wY8477XBDBJkGXAO9o2VPm+JzbioZMXWewVRQ2n/g0C3poklgoKyyc57cTxeUXnfHCVrXfU1D7fr9NJ4e2gA4w530OpNoMuK0TAGO9ljlaJB3tVd3u1yNb5ZVzPy40Wyt7L+Y4u5JP5IE+iFnsUbKmfl4zHN7nG3VdXtWXNvU8GYd9QBgZxxujDyTgKM9OAZc9e1dDY6ejoOvl1fNnm0yFY1TaApR/QhoMK/8G0UCGuQGEmUWKHK83jhA89z0gvoPDu1cfn1b864T1H29WZIRzc1iyzTgA+CmTqj7Lkeru6156xsVoy+cQk+fn44DJyHnQxTd1yBXRRk9bzpTsSrQ7/MoLvvJN/a/d9uSno5jLdQew40bOVghmFG4Md5MA4424UJA97rtvub6f71VPupcq9lSNttgNBLj8oZQUFzR/w6UU+ZVOeD2eV2B3u7ax/a9e/PvXI7OTuqxCDcuKDMON6Q2VICjbYacJ/jpHYte/8mjr35gtVUdLCwaPYfmyunDlFKbQ1ixXBByiDRzTl0RGPBiPXd7S8Pbyw68d+/TdAz5YlK8QzkkcEMSQwk42mfI4Wugt53c3uB0nHyttHz6THo4dywOnjRZIK7ojiHPxOw4lg4EYJI4mnfW7V95ff3h9bupd9DarLlhkohTgZk9+/pElS2AA27eVOjt3fW9p4699kr5qFkmc0HZR6TJ0nfEYngDzZUYmQeZrN6ZhEnSeXj1nk2/vr2nsw5vn4LGZrj1i6cG2VLyxYYacIyAz2zW4hro9HPnO3nstZ2FhZX7Cm1j5tCDAEWkyqU2j3HctV+7FJvjWE+CWRKvt6utpeGtX+7f/vv/6zNJGG7McfPFZNpuv8cY/oDkbAAcHRIhF0FXw21N2084HfWv2UonjaHPhEwJaikJ+oAjqdvRINfFD2ZXfSILF5I+Fz2kUP/akT0rlhyv2bCX6mKNDcD1N3CgqIbc4RzPJof+YOoEJx7eioNPl+FDlHSxqdgQnj77h5+oGPeJXxQUlE3Cg7qZ+EmmdnPWYYYjGRec/nMrbnfnsbaT2+6v2f3wZqoPJghDzVOAvNwVDbLCSqbplJTNNsAxKP5hBeR4OBGfSQDkDHpRYWFFyYzzf/Gd4oqpV5JGt+IZxlRqLGorr1zwmdjEmOMZEp/X4erpqFld/f4Djzud7ZghgabGBrDZ1sYsCa/lTqwhKphOly0min6MLCT42KAV2Kbzeb1Ob9Pxf+32utteLSqZOJ4++jRJmi16Efbv95/8rDsi++pzFX3mCM1kvXPkw7X/Vbd31eskc3H6D9pbhBvHJ7mfiv7upjSUjRpcHCD6xyYLa3PW6DBbVM0+4/yffKq88iPXmq0jJuOdf/J2vyjC/nBQk/fviyHRzva6u462N+96qHrng29RHtbUrLUx9cc3bljpsEISq8yKcLYDzkIC5Aw6bHNAzva5CrnZbC6c/pHrLykbefYVZmv5NAk6iy66PwBsV8fhrrYDj1Xv+uOr9GYyBpt9ntcWbe2s1NriiHMFcPSZtTlAhzZn0AE4ww7fOuP86z45ovLcKyzWkecEL0RN0kYnwYguaGP78MJLetl8277O1j2Pffj+n96mPAAZG8BmHxobYPMdSYCdtVqb+qa5XAKcO40+49qBQYc2Z42uAk77qj919tUfqxh1wZXWosrz6cEKslxQbPhOLwZNFKz4I7D9broL2fp+e/OO1TW7H3mPBMNgi75ojgBqvpCkYG64XAQckkW/sYlmCzQ6Ty2KoBeccc53Z5eP/uiXrIWjFpjNRTaD+no0FM1/2DWo6cIRb3D1eh12l7P5jY5TH6yv27cGt9cBsQg1wtDWvIl2dk5obeq75nIVcB4AQ86gs+nCoLNmV7V8YcnY4ikzvr3ANuKMz1mLqi4k0E3q+7nVu6OoIn+cOv9NUyJ4+ACfBKG3t263d9a9XPvh2jecPSdxg4a1M4BmyBlqnvaD1s4ZcyTc0ct1wHlMetBhi7CNziYM+6qmrzrtwtHjJi/6rK1k/OfoiblpAJ1hz0XNzpoai6AANTafu/uwvafh5cajG//ZcmL7KZIJA8xwiz7SoK1ZY+c02DQO1eUL4OJ4grZH0E6HRmetDsAZetE3T5q6eHr5mPPmWQurzjcXls8i0K20VFcx4iWYeA9JFpoyA4CmJatYI0JQu7zOjr0uZ8v7HU073zlW82w1dR7aGPAC5nA+0llj8z2HnDNFaAxhXb4BzoMMUtlvo0Ojs1bXA69qdEqHby4sLLeOm7p4Vln5tAsshRXnFxSMOJseirbgAhXPjAZvmrDYgn7/jRRuPjV+EGLUxbzRBSKWqdJ7RnChGKBPftAt9AMeZ/v7XR2HdzTWPLvX6eyAycFQA2jeGHBOY23NGhuNcEMUzA/HRyo/RhM6ChF0aHbRVhe1O0POceybiovH28ZNW/SR4pJJ55oLiieZzLZJJottPFY2BoHHWnWAT1Wr0owkUn18JJYoHv9xUQiQNd/roJfnNPi89mNed++x3p5jexoPb9zV29uAu4qAlDUx+ww2fI6Dz0CL9nWkzlD23HZ6qef2aKL3HmNl84VBZ83OQEfyOR98lDWOnjB3dFnFOZOttjGTLIWlk81m20RaMlBpUEw2Ay2QoRPARg1SffQXF7F9vtpFaOEgxbSrhuhDAV57gBZ+BBSf3e9ztXq99uMeZ/dRl73pWFf7vqOn6jfBhmYoRe0rwhsuLOZlu5p9tTv5/Gc4Ac7HEWMWN4ZW9AE6Q83Q8z6fHKKvQq+r10DmjrmoZEKx1Ta6yGItK7aYy7AiUvF4u+weV1evy37K4eip7yWzAmBCi4obwwyfta7oI8xAM8TYF/NwWbHevNXWNPYQNxwBF4Uggo4wg8q+CL0IuAg350Ec18H1oi0xjH3RMXiI4zBrVwZcDyxDy1DzPudnn+tjX2x32IQhfOmCEmBZMJDwGXQxLMYBbqSxz5AjDg4+b7wPH9DBMXz6fUCKOEAs+gwv+0gTw9jHBsd+cG+Y/uUDMUyHH3XYLBsGNJIvQq3PgwbEesQGGUDRR1i/Mez6eHEf9WJfOp0EWPi6aLkbQQIsLwYZ2aLFiekRqhwAJkPK8KJMtLhIdcr4PgnwwZECSU4Cejnq91G7Po7BFVvWx+n3xbwyHIcE/h9VLWRYHWXC/QAAAABJRU5ErkJggg==',green:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAltklEQVR4Ae2dCXQcxZnHR3NoNDp8SD7kU7bxFXCchBhMYoLNmhCcOBBykGw2gYTkPV6AhGXD2sTZJQcJG3jsgw3hscuCsTEsOAQW1sbY+MAHxpYtHzI+5EOy5UMStnWPZkZzab9/j75WTWt6NKO5Z6r82lVdXV1d9e/ffPq6uro7zyBDIhXIi7DyngjLyWJRKhDpCYiy2pwoztrpxSwCb+d1bayFm9f1Yu3+cj2MAgOJH2bXnNnEGiHWppW8d999d/inPvWp6YWFheNMJlOR0WgswdLT06PElFdM+xbn5eWVQDXK76TI7vP57H6/v5PyOxFjobwuh8Nx4dixYye+9rWvtaK4ZqFVNY/TiGUIoQCfsBCbcjaLNVHgJRUQG3/4wx9ali1bNmXYsGEzrFbrdLPZjGUagTyNAB2ZCLXoh3CJoD/p9XqxnOju7j7R1tZ2/LHHHqtbtWqVh47pp0X8AaAZbPmRzvnAJzPXhRBhVoBeunSp7b777ruuuLj4xoKCghsI5s8TcPnpIBT9oNwE/D6Xy7Xdbrd/8Oyzz+5+/PHHndQ2LfA5D3suA85QGwmMPLLQ+b///e/nkIW+0WKxLKBlLuUXpAPQEbTB5fF4KmnZShb+g0ceeaSKLLyb9gPgIvQRVJVdRXIN8CCo77777oI//vGPt5CV/n5+fv5NdGrhK2dDsLvd7k1k3f/n17/+9frly5e7qFM5CXsuAM5QI4a1Nh4/fvza0aNH/4PNZvs2rZfRks2h2el0/u2TTz55dcaMGXuoo7DoolXPajcmmwFnsBWoKysrJ02fPv3v6QLxH2hUY1o2E63XNxqhOUkXqq+eOHHitblz557pBV2EXW/XjM3PRsBFsE21tbXXk7VeCheELhKzsb9Rw0cXqT1wYciqP37FFVd8SBX4aMlK0LPphKMvirWm2FRfX//lESNGLKXRj3m0LoOOAjQas/Py5cuPV1RUbKQiDDrDrrNX5mRnA+Aq2OPHjzfv3r3766WlpUvIDfl85pyG1LeU3Jd9LS0tT1x33XVrzp8/76UWAfKMBz2TAUfbFbgJbAuBfUdZWdkSuvFyZepxydwW0I2lo83NzQD9rwS69mZSxnUsUwFXXZHDhw/PmTJlytNksedknPpp3GCy6FV1dXX/OGvWrCpqpui6pHGr+zct0wBXLDZ1w/TSSy+V3n777b+j+R8/pYtHAC9DrwIO9xHD5c5XDF5fS0ya0MWo3+nwvrBx47nfLLlvKypj0DNmaDFTAEc7GW5zQ0PDD4YPH/4YuSMJmQMSExVpsPPxhjsMHt/FuLWkp8dwqb3dt2zhnD2vUKXsnwPytAc9EwBHG01YDh06NIuGtf5DjoyQGmHC4XMLwmwd/Caft2fnmXr3A3d8Zf9hqgXWHEtaQ57Of9pViz179mwrXeE/MnPmzF0S7sEDGuueJnPevCuusO76sPq6R2bPHm2l+sy0gKG0NZTp2jCG27R27drx8+fPf4lu1NwQ6wnKlf0TZcFF/bwe//Z9uxw/vvfuj89Tftr65ukIOI+QmE+ePPllGgJ8UfraIloDp5MBOFoB37zxQvdPvr5gP24SsW+OsfO0CenkoqhWe8GCBQWXLl36Hd1de1vCnTas9GtIXp5h5LgJ1re3H7z2dwsWjMTUYlwrpZXLki4WXIV73bp1E66//vqVNClK3mLvh1RkGcmy4GJr3B7/zkOVXXfd86PD5yg/bVyWdAAcbVBGSY4cOTKPbtqsJqs9QhRPpqNTIBWAo4U0l+1yw1nXd29duH8nrabFKEuqXRSG20yz/hZPnTp1rYQ7OpjTqTRNUhwxtsK69t3tcxZTuzDCAsOVUiOaSsBxbAhgoZl/d02YMOF1SttokSGDFSCabeVj819/v3LOXdQNCy04xynjLFUHVuGmu5K/HDNmzHN0ux2/eBmyQoEe84gRluc2V13zS+pOSiFPBeAK3PQQQj7NQ36CZgA+Kh9EyAqqgzpBQ4h5w4aZH6URlidwrmljSix5sgFX4F60aJGNXmzzYklJyf1BqsiVrFOgqNh0/5ubJr24aFEp3M+kQ57MCwAF7pEjR1rpBs4KeuD3W1l3NtOkQ6kaRQnXfZfL/+Y3bqz7Ed3f6KZyPIwYbpe4bEuWBVfgphbn19TUPCnhjsu5y6hKCgqM33pr4+QnwQAtSbPkyQCc4bY0NjYupXeQ3JNRZ0Y2Nm4KFBab7tlSdc1SqjBpF56JBhwuEI5hOXfu3N30rOS/xk0tWVFGKjB0mPlfN1bOuRtM0AI2EuomJxJwNBx/iix0QfkNupJ+mtIySAUMpSPyn16z5fPfICnYkicM8kQBznCbq6ur59Pt9+U0FAjYZZAK4J6+aczE/BffWn/1fJIjoXc8EwE44Ea95vXr18+gt0mtpjQmx8sgFVAVIEgKJkzJX/2fq66aQZmAHMzE3ZInCnATPRBcNG/evJU0t2SI2iuZkAoIChiNeUM+O6d45cLbxxVRNv7Cxx3weFeIHwwaar148eJTQ4cO/SmlZUiyAuk4Dh5Ogs5O3wsLPrfnQSoT9zHyeFpw/FhQn+Xo0aPflHCHO6Vym6hASYnpp29v+dw3wQ4tYChuhjdegDPc5jVr1kybPHnyM2IHZFoqMJAC48Zbn/nzi1dNo3Jx9cfjCbh54cKFRfS42Qrpdw90OuV2rQLwx6/9QvGKhQsVfxyQx8WKx6MS/EgUv5vmGTw5ZMgQeadSe/aSvJ5pPrgoj73D91/zr97zEOXFxR+P1YKrrsm+fftupNmBEm7xbMl01AoUlRjvWb1u9o20Y1xclVgBV6w3uSVFNN79JL3LLuoOyR2kAqICYKhisu3JBQvG8tBhTIzGsjNbb8vLL7/8C3oxz3SxoTItFRisAhaLcfqyP435Oe0f86jKYAFnuM2vvPLK5FGjRuHRJBmkAnFToLTM8tCfnpk5mSqMyVWJBXBcWFro6Zw/0Z+Vwrj1TFYkFSAFwNQX5w/5N0rGNCFrMICz9bZ8/PHH+MbkV+UZkQokQoGiQtPX/rb+M7f0Qg5WwV5UYTCAYx/zrbfeWkw3dJ6I6miysFQgSgXGV9ieWHjrqGLajV2VqGqIFnC23ua//OUv99PnriuiOposLBWIUgGLJa9iya8q8HA6Ax6VFY8WcJQ30Sewh9DrHn4WZVtlcanAoBQYXmr62fe+NwGzUnHdFxWz0RRm621ZtmzZT+hF9GWDaq3cSSoQpQImU17ZnfeO+gntFvWwYTSAo6wZN3XKy8vvjbKNsrhUICYFykZa7r1mwUjc/GFXJaL6IgWcrbf5+eef/wH53uUR1S4LSQXipIDZklf+m99N/AFVx4BH5ItHCjjKmehbObaxY8fiDpMMUoGkK0BW/OezZxdH9YasSABn621ZvXr1HWS9Jya9Z/KAUgFSID8/b+KjT02/g5IR++KRAK5Y73HjxuXT8oBUWiqQSgVGlVseoCnZfHdzQH4HKgDrjcX8xhtv/B1NqJqays7JY0sFLPl5U59bVbEQTNLCfOoKEwngGHs0013L78npsLo6yg1JUgAMjhlb8D0wSQvYBOS6YSDAsd30/e9/n54hHrpItxa5QSqQRAWKh5gWffWbY4bSIQF4WIbDbcQvA9vNS5cuvY2es8TVqwxSgZQrYDQabHffU34bNWTAIcNwgGObAjh9P+c70j1J+XmVDehVACyOLs//Dq0y4Loc621g59301FNPTSwsLPyiVFcqkE4K2ArzvvjPv52GIWv2w0P64uEAV6z34sWL76BfjF65dOqzbEsOKQAm5/9diWjFowZcGT2hx9G+nUO6ya5mkAL0WBsDzla8X+tDWWa+uDStWrVqBo19T+u3l8xIawUsplFp3b54NY7mik/703/MxNtpeTSlnxWHk64NKuCf/exn58uLS6086b8+3Pqg4WDNHw0O5yf9Gkuf9+sX6N3twXmaVWwMkUWv+Q7eLVShHk1mv310Kg9Vrt/h/PStQoN/PlVxhBYYa7AbVCwc4PQxzxHXS8ANhkZ7jaGq8W8Gh6ed9MuM4C2ebrD7Jhp6CIJsDr481/UGw4nnqY8MeFB3tYDjF6BY8KKiIjO9qeq6oNI5urL+1L8bOt2XM673PrPf4OjwZDXk/p6e68BqV1cXAx5kxUP54MgzrVixYpbJZCrNuLOagAZnItyQwWQ2GgppXlKeEec8OwON75V+/YErZlHv2A8P6qieBTddeeWVX5LuSZBWGbnCkDs7PQa/PyO7EL7RZI5HTCj+EhXaTwt7IKpfprXgintCBU3kf8+TgIfXNlO2AnJbicVAt7izLoBR2xDLPOoYW/CgP1eiBWf6TXRrPp/877lZp0YOd4ghhyUPNUKRydJYbaa5IyYU5l8+53BRP5hjxYprf9NYNz7zzDOfpl9GSSZ3Wra9vwIMORm9rArUn5Kbfzzt09QphV+xcyEt+Pjx42dK90SUKXvSDDksedYEwnrYyIKZ1J89tOhacN5gpLnfU7Om87Ij/RRgyLPJiFlsZjALC84cK/1GBgdswLqJZg9OzabOcwdl3KcAIC8oNuMtrn2ZGZpCHyxW0xXU/H4Xmgw49xLrRgJ8Sob2VTY7CgVUyLNgnLwXcIXfXgkUpvv54KWlpeaCgoKKKHSSRTNYAQXyIrPB1eXVzOLIrE5ZrcaK0lKbuaXFCbDZYCsuCfcEmcbf/va34ym2cqaMs18BhjyTZ/3TmKB17ncngV1Y8X6AM/XGq65SPsaZ/WdV9jBIAUBuLSSfnPFgIjIoHj2pCFO7xR6oFpy7YRw5cqS8wAw69bmz0gc5cMiwQE0uKrH0G0kRfXDFQbfZbBMyrGuyuXFUQIGc3p/Q7fSRT65O6YjjERJXVX6hCewqHPNRsILAFjyP3j2Iz0XIkMMKBCA3ZdwQosloBLsqyziFogXHBiNNkS3OhrFRdE6GwSsAyPPJkrvJkmeCHVeYNeUBcPbBlc7ziko9AY6XjMsgFVDmkysXnqAjAwIN54NdlWWkRQuOLuRJwCGDDKyA0ZRnsNrM5JOn/zi5yZzHgHPz1VEUZCjkS8BVbWSiVwGGXCEkjVUxGlXA1b85bMHVDAl4Gp/BFDaNIXe7vGk7uEL+iOheK0zzKAqkkxY8hQBlwqEBeX4BJmilZ2uNRuX6UeGYW8gWnNelD85KyDikAgy5uzv9xslNRvUiU217PwtOW7TQq4VlQioABRTIrTQzNc1MeU9eD9gNacHVPzper9dBH3mVj6tJlsMqwJB7yJKnyzg5vTXAITRaYZrHwdV8n8/Xpa7IhFQgjAKAnOZhp83gSo/foGVXGQfHD1D9EcKCh+mT3CQVCFKAIfe6yZKrFAUVSdqK39cjsqtwLfrgaEiPtOBJOx9ZcyBAbs7H3JUUd8mnWPCgn5l4QalskICn+CRl6OEVyMld8brp9VkpMuU9fj+7KCrkIS14v9fpZqjostnJVYDuJJIlJ6RSYMrBrK9HAVyFG71nC45MZZE+eHKhyLajMeQ+jz/phtzvy4MPrrIMbUULzoDbs0102Z/kKgDITRZj0g253+8Huwy40mm24KoCTqezBeZezglXJZGJQSgAyA0EOSx5MgLcfp+7p0V7LLbgTL2/tbX1tLaQXJcKDEYBtuSD2Xcw+zg6u8EuflHMs+KiYAVByTx58mSdvMgMCCL/j12BpEFO9Laed9Yxx70t72ELjnUF8DfffFMC3quOjOKjAEOeyMEVfOyqevtFLeD9RlH8GzZs6Ozu7r5E81FGxqd7shapAI1mwCen5zz93sT45H5Pz6UTey52ktb9XBTor1jv3o1+u91+RropkEWGeCoAyI0EebyHV8Bqt8t7htoKuEMCjn4AcqWAw+E4jQwZpALxVkCBnG7tK5DDZ4nT4nb5wawIuNJ09sFFC+7DSIq04PE+tbI+VoAhj5dPjiHCbrsXgNNTGMEWXBwHVyFvamqq48bIWCqQCAUAeQ8ZcJoBGHP1+KF0NHvALCw4c6zUG8qC+995551DNOkq9iPH3HRZQTYrgJuJmKQVa6CvOffUfNhwiOoRXRSFXwYcx0AGCvjoI7CX2tvba6WbAllkSKQCsUKuXGB2eWsr37twidopuihKs7WAM+Te5ubmSgl4Ik+trJsVYMgHMz0E/ndXm6eS6qI3E+m7KHwsxYLTiq+2tna3BJxlkXGiFQDceDe5EiMd6UIPzLU0OneD2d4FDKtBz4L7li9fXkmzs4IKq3vJhFQgAQow5NFUTYT696w5DwsuuieK/416QgGu/BLWrFnTSn54jbTi0cgty8aqgAo5rj0HWHB7vtvhqTnyUVMrlWYLDrhDAo62YQOsNvwZLw0X7pGAkxIyJFWBgHsy8CHhf9tb3Pj4q8IrxWBXhRs1iBYc6ww4fg1e8sN3ScAhiwzJVoAhJ1dc/2YnNaq5oWsXRQBcdFHU5oo3epAJwBly79NPP73npptuchUVFRWoe+RgwnXRZmh3YBQqu4OuMQuyiX0a6GQHCuhs1D1GX7VBKVhp7APgtfvSS4dcm1bUsQVn6x105FCAo6Diz3z00UedjY2NW6dMmXKL0ag19kHtiHil9nyj4b2dVYaOLvEVFhHvnpKCXs9XDUa3m44dpF1QW7TiB23UWdHdR+cw8DlDBlCgE/S30A5h9tOpLubsaG/r6JWnJ+gNrtbmrRdO7sYMQva/GXK1nVrAsQGaoCDMvufgwYP/N2nSpLgB/sJb6w0tHWhTZgV3t4teidBNjYbkkEhPem2/uCyjpt1fu127f7LLa4+vbZ+2Pdry2vWB9tdu1+6vPV6gvN/vMzTUHv8/Ku2hBaz2gxs1hTLLqIEB995///07aPpss661QS1RhEyEG93LtxbQKxH4+7gQPdLAZRGLad5fzOMyYoxyXEZMi2XEtFhGTItlxLRYBmltQFkE3ofTSmYE/w20v3Y7H4dj7fECrorP42mu2rZhB23VvcDEnuEAh9n30MxC5/nz59+LF+A4aKaGAOT5wbxpO6M9X9jOedqyqVjntujxo21Tostrjxfheldnx3tuu91JxWHBQ15goqpQgCMfFpytuGfTpk3v0PtSkJ/zAZBbLL2QMyRiDIUYCjEtlkllWmyTmNZrk1hGTMervF49YfL99JbNpvrat6k5onsCXvsFPcDhpuBXofjhS5cuPdzW1nZKWvGAfhaGvJ+cMiPRCoBBj8t16tCOTUfoWAw4WAWz/UKoi0wUQmGGHJW4aUx8TVlZ2YP0DR9sz/kAyBG8HsgjQ7IUAOD2jvY1dDwMa0F8hjsk4HoWHO2FyVet+MqVK9+hh5Hl2YQyvQGQm/PJXQkXcKcCge9YcFrJDPFftOVDVJFWWdH2Z4Dy9PpjT92R/e9QH8EiPAwwGtI9oXxdHxzb8ItgP9z90ksvNZ45c+ZdOf8K0vQFC42sKJAzwNoYRfmkiWltOV4Xy4hp3p5psdgHMa3XD7GMmKbyALKrs/3dMx8faKQkLDgAB6MhrTflRww4fi3uV1999QWy4rq/FlSYi0GB3GLJxa4ntc9+r9d/5tjHL9BB2T2JCXA0PsiKP/nkk7Vnz559X1rx/ueVIQ9z8a+OJMsygYGmaHTAXVdnZ+f7x/bsqO0FfEC4cZbC+eDYDmutuimU7v7rX//63x6PR/dPAnbK1QDITcoQYq/fDSHwp5hjMR3I7b9d70+3Xj7XPdj6Yt1f266B6htou7a+3nW6c9lTf/Lwf9PuuJ0suidhPYqBAEdzUAEcecVN+cMf/nCMrPg2acUhTf9goYtOk5ncFT5RKII0B07rbedykcax1hfr/tp2DlTfQNu19dE6Rk4c9o5th3d+cIxW2T0Je3HJ1UQCOKy1Cjilu9etW/c8WXGuQ8YaBVTINflydXAK+H007+TUyedpb7begA9MDuhJRAo4W3H8erqXLFlS3dDQsEtacVJDJ0jIdYSJMhvW29nVuevAtvXVtCsDztY7LoCjSWzF4dgDctfatWufkSMqkEY/AHIzja5gLjMHTgcm9AfyOQ9lOM3bo43FOsS0Xj1iGaQHCtG2D/XxPmKa2yPmiWne3uP3+Zvqjj9D21y0gD0wGJH1pnIDXmSiDAIAD7rYfOihhw7Su8TflnNUFH10/zPTRafJbFZOMp9ojrETp/mEinm6lYbZEG192vLcDr042vZp69fuH247psR2tDS/XbVl/UHaj613RKMnLFEkLgqXZSuuXGzigA8//PDT9GByK/6MyKCvAEOuX0Ju0SoAprzd3a3VO9Y/TdsY7oh9b64vWsDZF8cBXZs3b75UWVn5Z3nByXLqxwHI5c0gfYWCt8B6Nzde+HPj6dN4VhDuCZiL2Pfm2qIBHPuIVlyB/Pbbb3+THmurlhecLKl+DH9cHULkYuyfI45kwX68j5jmfcU8Mc3b4x2LxxDTescRy4hpoTwezXN1dVVvfeuVN6kIwx219Ub1gwGcrbhysYkGrFq16jGXy+WTrgokDR8UyE00iZNPKIojHWngsnr7D7Q90uNEWi7a4w1QHgz5vF5f3ZEDj1ETADdfXEZtvdGFaAHHPgw4flGKFX/00UePHDt2bDW9kRbbZRhAAYYcWMslWAMDPcxgb768mm7qYL631nqDvajCYADHARhytuLOBx544NnLly83SlclMv0BuZFGV2ToU6CH4HY7nI37Nr/3LOXicTSt9e4rHGFqsICzL66Oi+/du7f5tddee5g+f+KRrkpk6pvplr4CObsbORwDKBpy9pyuqX74YkN9M60y3FGNe2uVHyzgqIchV604DRvuI9CfpRtA2uPIdR0FFMjlU1L0pQcvjZo0PHvggw37SCqt9QZrgwqxAg5XRbXilHbdcsstK+vr63fIG0CRnw+GPFf9cbpbaejqaNuxZfXylWCod+G7lmAsJYDjDOLgWPiCE788x4MPPvgb8sc/kf44qRFhCECeez45/O5up/OTqo3v/oakwuvOwBBcADDFfFFycCEWC85HRCMwfIJfHBrnpBtATa+//vqvyB/3Sn+cFIkw4Ja+URxCzHKfHGaZ/tJ76SmdX9FrIJpoVeGHYrDEw4KUHHyIB+BoJxrDrorSSHrVRNWePXuegz8uIY/8BCmQG7P/zQVgAn735aYLz+3fsq6KFBLhjunCUlQ7HoCjPoY8yFVZtGjRcpqQtdGtvLhSPKxMh1MgYMkBefZ65TRJ0NDZ1rpxy2vLl1NHta4JDCaYijnEC3A0hCHnURU02rF48eJ/oYvOvRLy6M6ViVwVoymepye64yeytI8sd1dH+94tb6z4FzDSu/CwYNzgRh/iqSAAF/1xNNhBX4nouPPOOx+iByRq5KQsSB55YMizyRXHiEm3vbNm99o3HnJ2dHSQGgBchBsMxcV6Q+lEOHtonNjAPILcW1dXt3P+/PkLPth/eGgePqclQ0QK4L3synvBs2BKMmYIuhz2c/s2rf1ZY33tJyRAFy0MONzbuFpvCJwIwFEvQhDo5It3d3Z27naYCm6mGXWFPNE9UFT+H04B/vhAgPHM9Mv9fvpglNPZfGjnpntOHzl0lvqrhTuulpv1TBTgogVX0wcOHOiix7j2Dx899is0HJYvIefTMHCc1/uFjUwckcL9EHphpv34gY/uq9nzUU0IuGG5AXjcQ6IAR0MZbI6VxjfV17UVlQw5OqR0xEKah2GRkEd+TlXIIW2GGHK86tjtcjnqjx74pwNb38dteNFyx228W0/FRAIuHhOQq6BfqD1+0WIp2Dds1KgFNCRmkz65KFX4tAp5Bvjk8LndDkfriQN7fn5g6waMdTPcGPNOONxQMtmAq6DTnasWn8e1s7R8wvVkyEv4xKFRMoRXQDUIiiGnz16n4b8eGud2d9kbqnd+cC+9bu0o9chOCwBnuHEzJyF+N9WrhmQBjgOyBVchv9xwobOro3XbqPGTrjVZLGV8MaW2TiZ0FQhATlKyqrolk78B49z0HsGT+zatua/uyMHT1AKAnXS40fNkAo7jITDgStx++aKz+cLZD8onTZ1NryEeA59c+uUBoQb6X4UcBdPAJ8dwJt5CRTMDD+xY88YvGs+caqCWad2SpFhu1i7ZgAfBTY1Q1umdz+7zp45uHXfFjCn0AstJeUYJOZ+ggWLVXUmxKcesQHqWkm6/t2zd+saKJW0Xmy5T2xlu3MjBDMGkwg3tkg04jonQD3S60vbVVh/cPmbyFGu+rXA2+eRkyGGWZBhIAdYpYMST75H30Bg3fcqlp62p4eWNry7/N3rVWju1WYQbF5RJhxu6pQpwHJsh5wsN+nit13+quupA4ZChNSVDh881mkw0wiKtOcQaKEAnCJrMoMwIpJESj6Orlaa8Ltv2v6++QeeQLybFO5QpgRtapBJwHJ8hR6yCfuFUzQX6U7d5RPn4K8kvL5cuC6QaOKiQJ8EfJ2/bgItJR3vbwb1b1v3iaOX2Q9RCWG223HBJxKHAZP/+FMHSBXDAzYsCPV18dp06eGBjecVkk7Ww6DPSZVHO14D/sbsyYMEYCuDOpNfj7mlpOL9yw6oXf996sQFvn4LFZri1k6diOFpsu6YacLSef9lsxVXQ6c+d79ShqoN05/NI0TByWYxwWWjAQPrmYc96nz7xNeWBhxRofNvpbDl7rPpX2/73f97qdUkYboxx88Vkwm6/h+28ZmM6AI4miZCLoCvp86eON9ibWzYPHVk+mlyWKXBZMC7WdyI1vZKrvdqwrLEJArAxSoJvgna0XNpctXntkqOVHx6mWtliA3DtDRwYqpQHkJJOAe3BXFr88PCmSist+OKqjZZCpK+55bYvVEy78pcFRcUT8eRL3zAZbZWhnwIAM5bAw3/dXfaz9SeO/vve99fsovrggjDUPATI011xwPj8smJpeO++6QY4mhUwzwHI8Zg5vrQKyBl0W0FJSfENt/39D0pHj73LYrVayXWR1pwE0guBGYjRMaeOkNBDtc1NDSs/XLP6FVdnJ0ZIYKmxAGz2tTFKwnO5ozsQ7ZjIkC4uiraPLBJiLLAK7NP5vG63t/bQvkMOR8emoWWjx9Fr0CZKt0UrYd96nyvHtkM/xhwudkfsra0fHtz6/j/v2/zuB6S5OPwH6y3CjfMT25+KvubGNZWOFlzsINrHLgtbc7bocFsUyz7vq9+6oXzK9PsKCgsraE6L4rb0nVSxutxOByx5aA3Yz/aRn+1yOOobT598dte6N7dTabbUbLUx9Mc3btjosEEKXXkKc9MdcJYGkDPo8M0BOfvnCuRms7lg7uJv31Q+ruJOa1HxVLzcEv65BJ0lDB0z2LiAJD/7VNOF+pcr1/5tE72uhMHmmMe1RV87La222NNMARxtZmsO0GHNGXQAzrAjtn5x0Te/VD556p0FxSVX4Y1RmIorQSdlhKCAjfFsL1lse+eRptOnXv7ovbd2UBGAjAVgcwyLDbD5jiTATlurTW1TQyYBzo1Gm3HtwKDDmrNFVwCndSW+5uavXzNu8oy7CocMuRpfVgi8hiF3hxcDLgpm/GFilMfg6OjYf+H08ZU0MrKXNGOwxVh0RwA1X0hSMjNCJgIOZdFuLKLbAovOQ4si6PlXz7959tipM28rKhm2wGzNL8TrGHLlopShxoQo3Fr3drsdXZ1tWxtO1byzf9v7uL0OiEWokYa15kX0szPCalPb1ZCpgHMHGHIGnV0XBp0tu2Lli4eNKPrc/C8vKC0v/0phybA5NI5uogldivuSbePpGAkB3JifjU+CODrbqlqamjYc2LZxq73tMm7QsHUG0Aw5Q83DfrDaGeOOMBRinOmAc1+0oPONInZfxFix9BOmXjVq+py5Nw8rG/kVmp47lV+XFvDVM8+NUS11H9R0S91xqq350oYTVZXvnzt15CKJxQAz3GKMbbDWbLEzGmwRDE5nQ8ygIwbksOhs1QE54NbG5qu+cMO0cZOmXW8bMvTqgsLiWQS7FW95hc+ersAHA+1XXmRJlrqbXqxz2NnRvv/CmZMfHtm1/ST1F9YY8ALmUDG2s8WGC5IVYFM/lJAtFpz7wzH6xbADdF4AuBZ4xaJTvrKtoLjYOuvaL80qGzPx8wVDSq622Yo/ZTSbLLhbqjwzqsxPp9JKCMiXqBGaAMQ4UMD1xU0Y8jsMmM2HJ9ZpLprH6bQfc3V07m9uPLvv8J4dh112O1wOhhpA88KA8za21myxldqpfFaFbAWcT5IIOvx00VcXrTtDznkcm4aWlRXOuGbeZ4aXjfm0xVYwMT/fOtFsLRhnwsMYyvCjUQG/76KVD62NtVIHoNWWUiAmoHFRCJAVX5pi+oKdk+zzBbe7+6zH6Trb2tz48fG9O6vbm5txVxGQsiXmmMFGzHmIGWjRvw7dGCqc6UGreqb3J1z70VcAzjFbddGVYbC1sVhW+aFUzPzMqNETJ1YUDyubaLUVVeRbrRNMFnOZyWguzAvAj9fToZ6AmwPLjxUKCk1EMltoir30OJOjhyD2+b0On8fb7O7uPtft7Kq3tzWf/eTs2fr6mmr40AylaH1FeEOlxbLsfnCstCeb/2PNs7mP2r6hz+ICeNmycwwwGWqGnde5jBgjjUWsN4/cHfPQ0lFF9PidzVpUWFRgK8KMSIPL2eXo7qLRuvZWZ3vLxS5yKwAmuwgcM8yI2eqKMdIMNEOMdbEM78t1ckzFciPkIuDimQ0CkjYwqByL8IuAY7u4jcujPqS5XkoGpbEuBhE4TrN1ZcC1wDK0DDWvc3mOuT6OxePmTDrXARdPNGvBcCLWgsvrDDEgRzmOOT9UXTgW5wM6BIZPuw5IkQeIxZjh5RjbxDTWsSBwHFjL0f9Z8BztfthuszaIwy0i1NpyOIBYj3hABlCMkdYuDLs2X1xHvViXQaMAi6/Jlqs6CrBeDDKKhcsTt+tUGQQmQ8rwYp9weXp1yvxeBfjkSEFiU0Cro3YdtWvzGFzxyNo87bpYVqYjUOD/AZrbm7Ts1rpFAAAAAElFTkSuQmCC',red:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAk/0lEQVR4Ae2dCZxUxZ3Hq8/pnhkGmOEQuQS5VCTxWHEDBlyNkciakMMkxujGuOvHO24IKCae0UQlKwmyroocoqtozGpA4oFiVAQU5IaRcchwDsPczNF39/5/b+bfVL/p7ume6bur+DyqXt31r2//5//q1XvPIJRLpgQMMVYeiDGfyhanBGKdgDirzYvsLLtIPguB0/lc7+vh5vNIvr68Oo8ige6EH6Vo3iSxjODrw1rcm2++2f+MM84YV1hYONRkMhUZjcY+OAKBgOZTXDGVLTYYDH0gNYpvIa/V5/O1+v3+FopvgY+D4tra29uP7N27d98VV1zRiOy6g06DcRyGr1wYCfCEhUnK2yiWiQYvSQG+8ac//all3rx5o/v16ze+oKBgnNlsxjGWQB5LgA5MhrToh1BL0Fd4vV4c+1wu176mpqYvHnnkkf0rVqzwUJt+OuQfALrBmh/hvHc8mfkuCBlmDei5c+fab7nllguLi4svttlsXyeYzyPgrJkgKPpBuQn4LU6n88PW1tZ1ixYt2vjoo486qG964PMe9nwGnKE2EhgG0tDWBx988HzS0BdbLJbpdEymeFsmAB1DH5wej2cTHR+Qhl937733biYN76ZyAFyGPoaqcitLvgEeAvX1119ve/jhhy8nLX211Wq9lKYWtnIuuFa3272WtPv/3nPPPW8tWbLESYPKS9jzAXCGGj60tfGLL764YPDgwT+x2+3fp/MyOnLZ1Tscjj/X1NS8OH78+E9poNDoslbPaTMmlwFnsDWoN23adNq4ceN+TBeIP6FVjbG5THSksdEKTQVdqL64b9++lyZPnlzVCboMe6SiWRufi4DLYJsqKyunkraeCxOELhJzcbxxw0cXqQGYMKTVHz399NM/pgp8dOQk6Lk04RiLpq3JNx04cOAbAwYMmEurH1PoXLkIEqDVmPV1dXWPjhw58l3KwqAz7BFKZU90LgAeBHvYsGHmjRs3/mtpaekcMkPOy55pSH9PyXzZ0tDQ8NiFF1646vDhw17qESDPetCzGXD0XYObwLYQ2FeVlZXNoRsvZ6Yfl+ztAd1Y2lNfXw/QXyHQ9TeTsm5g2Qp40BTZtWvX+aNHj15AGvv8rJN+BneYNPrm/fv3/2LixImbqZuy6ZLBve7atWwDXNPYNAzT0qVLS2fNmvUA7f+4gS4eAbxynRIwHN8ozDseFQZHTW9l4m/3BBa/8nnDfT97vKqBKmPQs2ZpMVsARz8ZbvPRo0ev6d+//yNkjiRlD0hvqUh3ecsrpwtD2+GEdcMfELUNbWLewNniBaqU7XNAnvGgZwPg6KMJx44dOybSstYf1coISSOKsy4tiJLa8ySPX6wvrxN3TLpX7KJaoM1xZDTkmfynPaixJ02aVEBX+PdOmDBhg4K754D2tqTFKKacPVhsOPEnce+kSQK/IjMdYChjFWWmdozhNq1evXrYtGnTltKNmq/3doLypXyyNLgsP49XfPhOpfjZzCcEbKGMtc0zEXBeITFXVFR8g5YAn1O2toxW9+FUAI5ewDY/UC9+PvrXAjeJ2DbH2nnGuEwyUYJae/r06bba2toH6O7a6wrujGGlS0eMBjFw1ADxetMT4oHpZ2lbi3GtlFEmS6Zo8CDca9asGT516tTltClK3WLvglRsEanS4HJvXF6x/v0vxHXfWigOUXzGmCyZADj6oK2S7N69ewrdtFlJWnuALDwVjk8C6QAcPSSTpa6iTvxwwm/EejrNiFWWdJsoDLeZdv3NHDNmzGoFd3wwZ1JuMlkGjBsoVlf9TsykfmGFBYorrUo0nYCjbQjAQjv/rhs+fPjLFLbToVwWS4Boto/sL14++ri4joZhoQNznDbO0tVwEG66K/nLIUOGPEW32/GLVy43JGAeUiKeqvsv8UsaTlohTwfgGtz0EIKV9iE/RjsAH1IPIuQG1SGjCAhDWaF4qHmBeGzwYIG3EaRFk6cacA3uGTNm2OnFNs/16dPn1hChqJOck0CJTdxaeY94bsZkzfxMOeSpvADQ4B44cGAB3cBZRg/8fi/nZjNDBpSuVZRow3d4xGsjHxT/VlsrXJSPlxGjFUlIWqo0uAY39dhaXl4+X8GdkLnLqkrsFvE90uTzwQAdKdPkqQCc4bZUV1fPpXeQ3JhVM6M6mzAJ9LGJG+v/IOZShSm78Ew24DCB0Ibl0KFD19Ozkr9JmLRURVkpgdIi8Zvqx8X1YIIOsJFUMzmZgKPj+FNkoQvK79CqyQIKK6ckIE4pEQsqHxbfIVGwJk8a5MkCnOE2b9++fRrdfl9CS4GAXTklATwiYRpVJp7bfb+YRuJI6h3PZAAOuFGv+a233hpPb5NaSeHkPGJCFSuXnRIgSGwTBomVb/2nGE8jAORgJuGaPFmAm+iB4KIpU6Ysp70lJdk5BarXyZaA0ShKLh4tls+6QBRRW/gLn3DAE10hfjDoaMHx48ef6Nu37w0UVi7FEsjEdfBoImh2iMX97hR3Up6Er5EnUoPjx4L6LHv27PmugjvalKo0WQJ97eKGLx8U3wU7dIChhCneRAHOcJtXrVo1dtSoUQvlAaiwkkB3EqAngxauuk2MpXwJtccTCbj5kksuKaLHzZYpu7u76VTpegnAHr9svFh2yQTNHgfkCdHiiagEPxLN7qbnKOeXlJSoO5X62UvxebbZ4LJ4yB5/muzx2RSXEHu8txo8aJps2bLlYtodqOCWZ0uF45YA7T68cfu94mIqmBBTpbeAa9qbzJIiWu+eTy9Wj3tAqoCSgCwBIETr4/OnjwsuHfaK0d4UZu1tef7552+nF/OMkzuqwkoCPZWA1SzGvXS9uI3K93pVpaeAM9zmF154YdSgQYPwaJJySgIJk8DgvmL2C/8hRlGFvTJVegM4Liwt9HTO78k0KUzYyFRFSgIkATJVCq88S/yOgr3akNUTwFl7W3bu3IlvTH5LzYiSQDIk0KdAXEEbsi7vhBysgr24XE8ARxnzlVdeWUw3dB6LqzWVWUkgTgmMHSgeu3Ky9oFeNlXiqiFewFl7m5988slb6XPXI+NqTWVWEohTAhaTGPnMLIGH0xnwuLR4vIAjv4k+gV1Cr3u4Kc6+quxKAj2SwIA+4qbrpwjsSsV1X1zMxpOZtbdl3rx5P6cX0Zf1qLeqkJJAnBIwmUTZ/TPFz6lY3MuG8QCOvGbc1DnllFNujrOPKruSQK8kQG/Kuple0Yx942yqxFRfrICz9jY/88wz15DtfUpMtatMSgIJkoDZJE5Z9mNxDVXHgMdki8cKOPKZ6Fs59lNPPRV3mJRTEki5BIb0FbdNOj2+N2TFAjhrb8vKlSuvIu09IuUjUw0qCZAErBYx4i/XiasoGLMtHgvgmvYeOnSolY47lKSVBNIpgWH9xR0lJcG7m93y210GaG8c5ldfffVfaEPVmHQOTrWtJEAbsca8f7O4BEzSwXxGFEwsgGPt0Ux3LX+ktsNGlKNKSJEEsJ121CDxIzBJB9gE5BFdd4Aj3XT11VfTM8R9Z0SsRSUoCaRQAn0LxIyrvyb6UpMAPCrD0RLxy0C6ee7cud+m5yzV50VIGMqlXwL0/Kb9nsvEt6kn3S4ZRgMcaRrg9P2cHyjzJP0Tq3rQIQGYKSP6iR/QGQMekeNICdDeOExPPPHEiMLCwq91VK3+VxLIDAkUWcXXnrhaYMma7XDw2sVFA1zT3jNnzryKtHekfF0qVBFKAqmQABFpnDUxRIvHDbi2ekKPo30/FR1WbSgJxCuBwcVBwFmLd6kinGbGLwHxphUrVoynte+xXUqpiIyWQKBoWEb3L1GdozXxsS/9u/Z2Wl5N6aLFYaTrXRDwr371q9PUxaVePJl/3nzef4uaN28S7hNHunQ2EOgSRa/r1rkuEXild1enr6unecJVHktd9OlwaOJp1LPddEApg92QotEANw8YMGCqApwktmen8K9cIURTI8kv810BdXGI72JR73LR9+ND5jvzOx9nD80u11QhVj1DxRjwkBr0gOMXoGnwoqIiM72p6sKQ3Hl64nv0fhGoPZ5Vo8ff7P5+v2jw+Eil5S7kfQKBC8FqW1sbAx6ixRGpd4gzLVu2bKLJZCrVJ+bjebbBzXNkoTsipfRQo0HTWRybWz7BWvqHkYMn0qjYDg8ZoB5w1uCmM8888yJlnoTIKitPGHIj3R3hyc0lHwCPLbRdRB4A56EF5yoc4Igzkf09RQEelFNWBwB5f3okJhfnE2MqNZumgFk6wC4gDzoZcKbfRLfmrWR/Tw7mUoGsl0Ao5DzVueEXmUyThxcW8heUeVDanMmAIwLnxoULF55Nv4w+Wg71X85IgCE3AoEccjScPr8ZderZNCSNX3lo8ioKk28aNmzYhFz8cyYPPF/DHZAbRKPXmzNrK6B6qM0ygbxP6WCOtaUjWYNzgpH2fo/JVwDyYdxmUuH9zWZN3eXKePuYjGAWPDPH2tD0GhwZTLR7cIzS4Jp8cvY/QN6PIG/KAU0OVouMxtPBLh0MuTZ3rMFBPRzOjQT4aO1M/ZfTEmDIc8Emt5s0wDV+OydNY5oBR5ym2ktLS802m21kTs+sGlxQAoC8r4nMFZp9DQAGIct8m9EwstRuh0XCw9DGqAfceP/992MrGrYzKJcnEjgJOdjIUhcQBbcPHQx2wXRwIGyDM/XGs846S22PzdI57k23AXkJmbAnfNm5dwUAn1mkbe3+ohNwRAVYgwcBHzhwoLrA7A0pWVxWg5xe5Wo8qQCzZjQAuNRs7rKSwhocAwHsRrvdPhwnyuWnBAB5H9LkLZomzy4ZFJmNYFfjmHuu1+AGevdgMScqPz8loEGuafLsGr/ZYAC7bI3A1x6751EgwkhbZIvVGjiLJH99QF5Mmrw1SzQ5mKVFcAAOpa3BjdnjkyD1BDheMq6ckoDQNDntQsQSYjY4ghzsBllGWLbBMQaDAhxiUI4lYCLNWEzmiqbJM/zBIKvByIBz9zUNzica+QpwFofyWQIMObGe0c4kAgx4sKeswYMRCvCMnsO0dY4hb/P5M/YZT7NJ0+AsI41pXkVBJCKUicLiUX4XCQDyIhNWyYP6sEuedEZE0+DcLwU4S0L5YSXAkLdrmjxslrRFGmOxwal3bLakraOq4cyWACAv1DR5ZvWTVlHArmaJcM/YRAn+zfF6ve2cqHwlgUgSYMi7rDNTASYs1b7PH5DZ1Zjm/gXH4fP52oInKqAkEEUCgJz2YWeMRU6Xv3p2NZWO1c3gCqfS4FFmVCV1kQBD7qS3aKX7LXE+v1/W4BrXbKJwxwNKg7MolB+rBAC5jd69Ql5anS8goMGDyhqdkS8otQQFeFrnKGsb1zQ5Qa5p8jSNwm8ImihByMNq8EC6/9akSUCq2d5JAK+H0zR576rpUWkwSyuXETW4Zq9QzQFlg/dIvqpQpwQYche9vDvVb7X1BgRs8CDL6JKswbUEAry1s6/KUxLokQQAeQFtQUz1HU96FzrYZcC1vss2uBbhcDgaoO7VnvAeza0q1CmBDsiFcPlTIxJQ7aTXoetbYw3O1PsbGxv/oc+kzpUEeiKBk5q8J6XjL9Pk9YBd/KSYZ81EwQmcFllRUbFfXWR2CET933sJAHKrZq4k9w4nelrldOwnLwg3wqzBka4lvPbaawpwSEO5hEkgCHkS18kB72v1zXrAg+vgTL3/7bffbnG5XLVms3lgwkaoKsp7CQByC0nBo+nRxIvD7ffXrjve1EI1dzFR0FoQcGRobW2tUmYKxKJcIiWgQU6gJ1qRg9U2X6CK+gq4wwKOcQByLUN7e/s/EKGckkCiJQDI6fUOCd9x2O7zgVkZcK3rbIPLGtyHlRSlwRM9tao+loAMOcf1xge8TT4vAPfREaLB5XXwIOTHjh3b35sGVVklge4kAMhhqngTsC0E9dR6fGA2BG70IZwG97/xxhs7aNMVgFdOSSBpEsDNxA5zpXdWuY/MjVW1zTuoowA8BHIGHIMA0Ej00Udga5ubmyuVmQKxKJdMCQByE/ENfd6Tf6C2xR+ofPFITS31UzZRtG7rAWfIvfX19ZsU4MmcWlU3SyAIeQ8UOYCt93g3keelI0R7o34ZcJxrGpx8X2Vl5UYFOESiXCokAMgBI3lxHTDkqxyujVQU2ps1eLDLMuD4MbAG9y1ZsmSTn1wwpwooCSRZAgx5PM3Qg3L+JTX10OAMN3OsVRMOcO2XsGrVqkayw8uVFo9H3CpvbyXAkMNa6e7AQ6DNXl/5W8fqGyk7a/CIgKNvrMFhz3hpufBTBTjEolwqJQDIAXd3DrDWuj34+KvGK/lsgweLyhockQw4fg1essM3KMCDslKBFEqAIY+mxdGdynbPBvIAuGyiIElz8o0eRLB6xy/Bu2DBgk8vvfRSZ1FRkU3Lnaf/VRaVCM/xmpwffSRlBijCuUjxyBsxLUJCpMfbkB39AvD6/jn8fufjh46wBmftHdJCOMCRUbNnPvnkk5bq6uoPRo8efbmRnphOhGvbWiGO/c9fhaeuORHVpaQOt+8rwlmCb7uHyC6k7UgpUctEKBStTEijnSf6iZfzRGhCyxJvO3K96Q7T42mi2nnig21N5dhByPY3Qx7snh5wJEAmmgYn37Nt27a/nnbaaQkDfP+dTwp3dT3aySrn9HtEu9+r2YYQUCw2IgbIeRk0lOO4cOmIk12q88ttI8x9jdR/fX79eXfl9en68pHG7w34xW5nzV8pv4cOeQ08pIpwahltMuDeW2+99SPaPlsfTUuE1NjNSTbCjSEVGS2i0NihD2KFG+U4L3w5jDQ4OY7zyL6cRw7LeeSwnEcOy3nksJwHYb1DXjguw2EtMob/uiuvT+d22Ne3h3iw6Az46he37PyITiNeYKJsNMCh9j20s9Bx+PDhvyUKcDSarQ6Q2wnyaNf4nMa3nTFWjsuEcXNfYu1fsvP3RCbQwLU+598a3W4HBaHBw15gou5wgCMeGpy1uGft2rVv0OskEJ/3DpDbjCYNWoZE9iEghkIOy3nSGZb7JIcj9UnOI4cTlT9SPdHiAeZ2Z93r5MnmCaK7uEiA40eCXwWo9sydO3dXU1PTl0qLd8iPIe84U/+nUgJgsC3g+XJJ8+7d1C4DDlbBbBcX7iITmZCZIUclbloTX1VWVnYnfcMH6XnvADmcKwDZKpcqCUBN13jbVpHnpoPNE+a1SzciaXBkRF1BLb58+fI36GFkVKhcpwQ0Td7lS4xKPMmUgFv4PG+3HXmD2pC1d1jzBP2IBjh+FSgIM8W9dOnS6qqqqjfV/iuShuSwsmJTkEsSSV4Qa9+1Pseb77ZWVVMr0OBgE4yC1bAuVsA1M+XFF19cTFo84q8lbAt5EKkgT80kuwMB/7q2I4upNTZPegU4eh2ixefPn1958ODBd5QW7zqhDHm0q3+V1nMJkPIW9f72d149UVHZCXi3cGOWomlwpENbB80UCrteeeWVZz0eT8Q/CSiUr64DciwhnnQcjnbjArk5PV6fy3KL+va6q6+35fX1d1dfd+n6+vjcL/yBjx3Vz1J5Fx2yeRLVougOcPQHFeBiUzNTfvvb3+4lLf53pcUhmq4ON4IKDB2QY3Lg2JfDPHFyHMLxOq67p/X1try+v93V1126vj6cd9jezr+vaCrfS6dsnoDJqHCjbCyAQ1sHAaewa82aNc+QFkd55cJIQA85w5cKH91hiORwKtpOVhs+4nij89gzNB7W3oAPTHZrScQKOGtx/Hpcc+bM2X706NENSouTNCI4QG4lTZ5qx3AzbGif41Ldl0S0B+1d73dtWNy4ezvVx4Cz9k4I4Ogna3EY9oDcuXr16oVqRQWiiexOavKTiOEyC44vtzisRXbGcxznicfnsrHWp8/P5SL5+v531zd9/fry3aV7aOVkk+P4QsrnpAPsgcGYtDfli8lEQT4ADi3OgLtmz569jd4l/rraowLxRHY2TZPjY6kd/5CTJ1kOR0qPXHP4FK471vr0+blcJF/uc/gehMbq69eXj5buoy2xR31trz/duGMblWPtHdPqCfciFhOF87IW1y420eBdd921gB5MblR7VFhE4X2GPHyqig0ngY49J97GxU27FlA6wx2z7c11xgs42+Jo0Pnee+/Vbtq06U/qgpPFGdkH5FhdUS42CeD5qb2exj997qzFG6tgnoC5mG1vbiUewFFG1uIa5LNmzXqNHmvbri44WaSR/QLaZstLiJyLrXP4sRwox2XkMJeV4+Qwpyfal9uQw5HakfPIYTk/tHej37X9vuMbX6M8DHfc2hv19wRw1uLaxSY6sGLFikecTifegYg6lYsiAUCO1RWeUGRFOFbHeSOV7y491nZizRdve93lB0Nu+qD8O22HH6E+AG6+uIxbe2MM8QKOMgw4flGaFn/ooYd27927dyW9kRbpynUjgSDkeP+HOkJkEKBfwCF/68oXmvdgv7dee4O9uFxPAEcDDDlrcccdd9yxqK6urlqZKrHJH5BbeqRfYqs/G3NhzftEwF39ZNPORdR/PI6m195xD6ungLMtzsuGzs8++6z+pZdeuos+f0JLl8pUiWUmGHL82c73A69hcwm/5/3WQ3eVOxrw2gWGO651b73cewo46mHIg1qclg23EOiL6AaQvh11HkECgNysNDltdPKLfe6GRU837d5CotJr7x5rzN4CDlMlqMUp7Lz88suXHzhw4CN1AygC0WGi8x1y3NCp8To++lXN+uVgqPPgu5ZgLC2AY6rQOA6+4MQvr/3OO++8j+zxGmWPkzRidJq5YuiNvomxoQzLBru72e+pWdS46z7qWjsdYAgmAJhivijYM5cIiaITWD7BLw6dc9ANoGMvv/zy3WSP0zeGevzjo6ryy2H50EKQR7pNnmvx0MvugN/7vuPw3Vucx47RbGv8kA+WeFmwVxAkAnAQjM6wqaJ1kl41sfnTTz99Cva4gjz2OQLk+DBTrjswAbt7r6fhqacbdm6m8cpw9+rCUpZdIgBHfQx5iKkyY8aMJbQh6123Gz9I5WKVwElNnrurK16C+4i39d05NeuXkFz0pgkUZkL+9CcKcMwdQw6acaGATrfPnDnz13TR+ZmCnKQRh4OpYs5Rm9yjXVS2f3ZX3YZfk0g0TsjnZcGEwQ1xJxpw2R7XIKevRJy49tprZ9MDEuVqUxZEHrtjyHNpjRwrJvU+R/nDjZtn13scJ0gaAFyGGwwlRHtD0snY3obOyR00EOTe/fv3r582bdr0pmXv9MVXbpWLTQImklWHQGWRxlY203IB7kaf69CC5p037XDU4osCbXQw4DBvE6q9Mf5kAI564UJAJ1vc1dLSsnFUZctltKOuUEHeIaRY/gfkcBBotq6k+KnzJwKe+mUnym9c13roIA1FD3dCNTfkBZcswGV1Ewxv3bq1rcBk+Xycpd836c+vVUHeMQmx/M+yCgozlkIZkoe2mYrWgKf19ROVt/y55cty6pYebmhuAJ5wlyzA0VGeC/a1zm9z1jaVme17hluKL6HVAgtPXMJHloMVsqxCBJrh4+yA292+tv3Ifz7btAu34WW4E7beHUkMyQRcbhNzEpyXTY5jx+kJly2jrSXTSZPbeeLkAiocXgIsq6Aww2fLiFjY3Cf8nsbX2/bf9mzjLqx1M9xY80463BBCqgEPgr7VWdvQbvCuH28tnUo2eR+eOHRKuegSCMqKTHOY55l44F0mDQHn0eXNX9z8yomKPTSiVjoAOMONmzlJsbup3qBLFeBokJVOEPJyV2PLUW/738+2DbjAZjCV8cVUsHcqEFECgDwoyIi50pOAde46n6NiYePuW9a2HfgH9QJgpxxujD6VgKM9OJ4XzT/gOeHY7W5Yd65t0CS70TRE24nRuWrQkV39H0kCDHmmrK1gZnH7/ZjXsfWRhs23b3HUHKW+682SlGhullmqAQ+Bmzqhndd6He5PHDUfTC48ZXShwXyagpynp3ufzRUIMp0OuwLpWUq6/d72wd21G+fsdzfVUX8YbtzIwQ7BlMINeaQacLQJ1wX0Fr/b9zfnwQ/PKxhUUGKyTjIJo4Enr6OI+j+SBGQ5YcU81Qfgdga8gQpP0/O/qP/4d41eB77yK8ONC8qUww15pQtwtM2Q84VGwEsbyN9srdo60FRYPsRin2wxmOzYS4AHc5WLLoGT5kr0fIlMxY5AvL+k2e9ufK/98Lz7aje9SnPIF5PyHcq0wI2xphNwtM+Qww+CvsFRfaTa2/beuILSM+0G0ynKZIGounephJxNkhpf+7aFjTtvp5WSHdRDaG3W3DBJ5KVAzHHKXaYADrj50KCv8rS0rXFUvXtOwSBTX5P1K8pkiY0NNleSSRNu3sAkKfc0L7+j9sMH97ua8fYpaGyGW795KrbOJyFXugHHkHgu4DPkmjanP3e+Na1V2waa7buHmAsn0/ZRu7YXQ5ksUVE4adIlducKcU0mCW7euBvWOo7c/UDtxr90miQMN9a4+WIyabffow5el5gJgKNLMuQy6Fp4g+PY0cNksoyylgymz4SM7nioS9nmurkMOT0JeUh0j05ga/toiuj78OKQr/W9RY3b57x64stdVBlrbACuv4EDJZV2l2lXb+gPrivxw8OXVgvosNFhp6MQ4TvKzvnni+yn/rLUaB2BJ1/4TzKlKRdGArCVe+PY1m70uw9+7Kz+wx/rt26g+mCCMNS8BMjbXbW/vr1pM5FlMw1wjA19wgHI8SVmKx2AnEG39zfbiu8vu+CasdZ+19HHWAvM2ESqzBYSUXgHDRwv5rxC0ub3uCrI1n6w/tMXGr1OrJBAU+MA2GxrY5WE93LH2xQVTZ7LFBNFP0IWEnwc0Aps0/mcfq/3rbYDO+r9zrUjLMVDaePWCGW26EV48px//Kw5ovl4wxSbI/Ty+Y+fa97zq0WNO9aRzOXlP2hvGW7MT0aYJCdH3RHCWDPZoX9ssrA2Z40Os0XT7HMGnP/1C2yDbulrtI7E64nx7lae1EweXKr7Bq0cybGd7SI7m9a1D3zmqln0WN3nH1J+1tSstbH0xzduWOlErjhSgymKz3TAWQyAnEGHbQ7I2T7XIDebzba7+p1z6STbgGv7GwvGKNBZdNF9GWx6J/eXO5x1z/++aetaejMZg80+r2vLtnZGam15xNkCOPrM2hygQ5sz6ACcYYdf8Kuy8y86zz7g2jKj7SwFOkkkjJPBJlNv9xZH3fOP12/+iLICZBwAm31obIDNdyQBdsZqbepb0GUT4Nxp9BnXDgw6tDlrdA1wOtf828rO+afJtkHXDTLZz7XiNQxUBIXz1XwB1KASa9n0Rilx3Of4fJPz+PKF9Vs/o2gGW/ZlcwRQ84UkBbPDZSPgkKzGKfmy2QKNzkuLMujWG0rPmnRhwZBvDzbbp9sN5kLAni8XpQy1n9AG1I6At51edPnBRlf1G4sbduP2OiCWoUYY2poP2c7OCq1NfQ+6bAWcB4D+A3IGnU0XBp01u6blh5qLi27od8b0Mdb+3xxosp9PoJvwch3Anmvr6Vi/BtRegprA9tX6HJu/dDe+vbhp7wf0RincoGHtDKAZcoaal/2gtbPGHKG+dnHZDjgPSA86TBi20dmEYV/T9FMKTx00q3j0ZSOsfb5ZYrCO0UyYLNbssqbuhBpfS/jyoLvl7f9r3f/O+vajx0kmDDDDLftIg7ZmjZ3VYNM4NJcrgMvjgTbHuAA5NDprdQDO0Mu++Yf9xo2dXDB4Kmn1c/uZCibShWkBPi+CR+gy1ZSRgcbmJzxJQ0t8riafaxdp6883uWo+Xtm0r4LGDG0MeAFzOB/prLFhguQE2DQOzeUa4PK4WKsDdD4Ath54TaNTvJbWz2wr+FHfsRMnWErPG2iyndvfVHAGwW7BBSqA7/jX0QwLL1kXrYAYjg1f+LhMBNC4UCSoPfSmqL21Pufn5Z6GLS83V+xq8jphcjDUAJoPBpzTWFuzxu6ongrkkuM5yqUxyWPB+Bh0va0ua3eGnOPYNw21FRX+oHDcV06zlpxdQvtfCg2mEYVGy1CrMNpZw7Mvwy93AmG9oBlafT6GGPYzQGbfLfyOdr/nSHvAd5B28x2scp/Y+Wr7vu1HnG24qwhIWROzz2DD5zj4DLRsX0fqDmXPbqeXe3aPJnrvGXT2WavLpgyDrfflvNoP5eLiYYMmWctGDjEVj+hrtowsMliG01cayugppEK6k2qnbWCFlNGMxhh81vRsXkAbgywizUuvWWinW+QOT8DX7vL76tsCnkPNXs+Bal/rwR3u+gPrWg/DhmYoZe0rwxsuLOdl84P96BLLgdR8Apynq4O5DqWKMOAFtLIPwBlqhp3P9Xk14DvrCKmbzB3zSGtx0RBjob2fuaCoj8GKHZGiJeBub/K62qr97Y4D7tY2MisAZofyPukzzPBZ68o+wgw0Q4xzOQ+X1ddN2fLD5SPg8syGAEkJMqx6kGXA9WlcDvUhzPWiLTmMc9kxeIjjMGtXBlwPLEPLUPM552ef62NfbjdvwhC+ch0SYFkwkPD14PI5QwzokY99jg9XF1rheEAHx/DpzwEp4gCx7DO87CNNDuMcBxz7HWd5+j8LPE+HH3XYLBv40Q4Zan0+NCDXIzfIAMo+wvqDYdfHy+eoF+fK6STAwtdFq9MIEmB5McjIFi1OTo9QZQiYDCnDizLR4iLVqeI7JcCTowTSOwno5ag/R+36OAZXblkfpz+X86pwDBL4fwN/IZwMBwH5AAAAAElFTkSuQmCC',yellow:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALcAAAC4CAYAAAChOH1KAAAlaElEQVR4Ae2dCZhUxbXHTy+zL8ywDDsSVhEVJQoCkoSIIr4kvohLxO2ZfC8an0mQrCQm+uJ7qHkv5hE/xSQaNokBogkxigaUuLDIpsiOMA4MOwyz7zPd7/yLOZfqnu7p7umeXut83+2qW7du3apTv3v63Lr31rWRkUhowOZViPc6Nutpbq/8WPVO8173sYtJ6kgDusI7yme2nYdTdIZQj0NH1vrgwYNtc+bMyb344otzCgsL87KysnLT0tKym5ub6+rr62vKy8urd+7cWfv444/XlJSUAGSB2VfoKw3HM9KBBqQzOsiSspsEXgmhCMTtDGT2TTfdNDwvL28kQzvC6XSOcDgcQ2w2Wzfenme323M5nuN2uwPql/O5OF+dy+Wq4X2rOV7Z2tpa3NLSsp9Pgv3V1dX7XnnllU/4RKnj7S5edNARl4WjRnQNBFS+njnJ4wKxHtp37NgxpG/fvlPY6l7CAI/kZTgv/YMBN1L64hPAzcAf5eUTXvax9d9x/PjxtZdcckkxH0OAF8gljNThE7acVIdbQLZzDyJuX7du3YChQ4dOycnJ+QJb5M+zFR4Qr73L1v4IW/h3amtr/3nw4MG1kyZNOsJ1FdglBOwpKakItwfQTz31VN4dd9wxnd2LL7J1/hzDPCxRSWDYD7BVf5fdmbeXLl26avbs2dXcFsCdkqCnCtwCNEL7gAEDnBs2bPh8QUHBnenp6TdyWi4vySY1TU1NKysqKl6cMGHCO0eOHGnhBuqQJ71FT3a4FczcqQgdu3btGtWvX787MzMzv8YWun+y0eyvPWzRjzY0NPzp2LFjL44ePXoP52vlRbfo/nZN6PRkhdvyoX/7299245GNe9iHvoMvBC9P6N6KQOX5gvRD9tGX8gjMovvuu6+SixRrjjCpJJngRluwAGz78uXLu0+dOvXbDPW3eL2QFyOeGihnyOevWbPm6VtvvfUsbwLcAnpSuCzJALcH1KtXr+4zduzYWbm5uf/OnZWMvrQnouGv1bD8ftu2bf937bXXnmgDPCkgT3S4lZXmDrGvX79+0EUXXTSbRz3u5fXM8Ps85Upo4FGWBbt3735q4sSJh7n1YskRJqQkKtyoN8B2vPzyyz2uueaaX2RnZ9/NN1bSE7IX4qjSfMOoqa6ubvFbb7318xkzZpRx1XDxKZY8jmoauCqJBjfqi8WB4bzNmzf/W/fu3R/j9R6Bm5o6OWyuErK1fMiKwuhfJ8VNZWUVtT/77MTHFrYNI8oIS8L444kEt7ggju3bt182bNiweXwHcXwnuy5pdwPYzrofMdiR8SaaW9wffFLc+N3RE/7xEStNrHhkCu/iXkgEuFFHBfb8+fMLb7vttkf4YvGb7II4u1g3CVm8vXEpORtfiGzdbbaWmpqW3724ou4/v/WDj8u5cMAd965KvMMt1tp56NCh24qKip7gmy99IttzyVWao3ERYekKcbnpxKmy5h/3HbVpGZcvdzzj1ooDnngUnHQOLI8++mhBZWXlC3369FlowI5tV9lt1KdPz7SFdaUTXnj00REF0kccxqWRjMdKWWBv2rTpUn7YfwnfWRwZ225NnKN3peXWtdDion0799TedfkXPvqY0+GLywWnni2m8Xiz3KgPLLbz6NGj3xgzZsw7BuyY8uH34E47jRxzUc47J/eN/wb6ixf0W1zxFC+VEWvtnDt3biE/ybagZ8+ez7CysngxEqcasNkoq6i785m6w1ctmDt3GB5xEMjjwiOIh0qgDjjJMG49hp9ae5Gt9fA47c+4r1a03BJvRbS43J/s3FN3R5ubIhebMR0Tj7XlFoudtm/fvmsuvfTSNQZsb2wSY91ptw0fMzrnrYObr7iGa5zGC9yUmBrPWMItYGOY7xZ+W/wvrIw8XowkqAa4Q/M+MzjjL0d2jL+FmxBzFyVWcOO4OLPT+AH6b/ELuAs5bp4LYSUkujDg6f37Ohee3ncVHjUWCx4TzmJxUAE7/eTJk4/06NHjKb7bGIt6JDpH8Vt/N9l7dnc8dfaTcY9wJWG0YjKSEm2oFNh80ZhRVlb2NL/D+KP47SFTs3A1UFiQ9qOakglPjx7dKyMWgEcTbgX2+PHjs3j6hCX8fMjXw1We2T/+NZCTY//65jeGLRk/vjuGdaNqwaN1NavA5salnz179jl+9evO+O+WxKxhrIYCA2mrtq71xdwLNt7P+Zp4kacLA+0W1vZoWG4BO4197McM2GH1V8LunJPtuLP84FWPcQOidpHZ1XCjfCxppaWl32Ef+6GE7R1T8bA1UJDveOjUnvHfAQ+8CBthl+uvgK6EGy6PAru4uPj23r17z/VXCZOeOhro1cs5t3T7uNu5xQJ4l7nGXQU3KqzGsfmF0+v79+8/P5oTR6YOKgnYUjfZ+vdLm7/vg7HXtwEOTroE8K6AWyy2kx9ZHTdkyJAlbY1IwJ4wVe4KDTAgacMHZy3Z9vbl47h83MkEhxEHvCvgRpnOefPmFfF49lLMU83rRowGPDRgs1POpRdlLZ33xJAi3iCAe+QJdyXSZ4sCmyuVwY+truA5RKaFW0Gzf2gaiNehQH+tqKt3vZkzaAOeRWnkRZ4m9Jc9pPRIWm6cKMrPPnz48HcN2CH1Q8pmzs6yTzux+8rvsgJkiDBiBjdScAvY8LOv4hd58UyBEaOBoDRQ1DPtEfa/r+LMEX2SMFJwoxzHE0880Yv97AXsZ6OSRowGgtIAeLl0VNaCJx4d0ot3wL9/RLiMxF8AKgKY4WcvY3dkOseNxEgDieZz62qqq29dlTNo422cFhH/O9wzBCeHgptfOHjAgK13lYmHqoHsLMf0ozvHPcD7yehJWMY3HLgtsBcvXnwB34F8ONTGmPxGA94a6FuU9vDiZy6+gNPDBjxcuNXoyA033PA4+01mLmzvnjLrIWuA36jP/dcb8h7nHcMePeks3JbV3rp167X8sVF8NMmI0UBENJCXa7/xo3fGXsuFhWW9Ows39nNed911uRdeeOEvI9IiU4jRgKaBi0Zk/vK663rDGxDAta3BRTsDt2W1n3/++Vk8jfDQ4A5lchkNBK+BNKdt6OJfD5rFewjcIV9chgq3BTZ/UGkY36wxz2cH318mZ4ga4Js7Dy1fMHpYZwHvDNzqIpI/1fEkX0Sab8+E2GEme/AasNltmdO/kP8k79Gpi8tQ4Las9rvvvjuBXxe7LvhqmpxGA53TQE6O7bp1r4+RW/PgNWj3JFS4ldXmW+zfY6vdudqavYwGQtAAOONb89/nXUK23sHCbVnt119//TKelmFqCPUzWY0GwtJAbq596j9eueQyLiSki8tQ4IbVdl555ZWzOTRmO6zuMjuHpgGbbfxlOeAOcIPDoPgLBm7LavM3H0fl5+d/KbSKmdxGA+FrID/P/qWXXxw1iksK2noHC7ey2pMnT8bQXzD7hN8aU4LRgIcGbPYpV3UDf0Fb70CgitV2LFq0aAhb7RkexzMrRgNR1ADPezJj0fyLhvAhYWzBbofuSbBwO6dOnfogX7miUCNGAzHRAA+cOP5lSt6DfPCgXJNg4HawO5LDs0XdFJMWmYMaDWgaKChw3DR5ck/MqBDwwrIjuMUlwTQN0/lzHvjuoBGjgZhqwG6ngmfnDsTbXgGtd0dwY5u6kBwwYMCt5qZNTPvUHLxNA+BwYP/0W3lVLiz9MuxvA6w2FsecOXN68fPaX2wr2wRGAzHXQF6O44tzZlsvEwur7erVEdzY5rz77rtv5s9S49anEaOBuNCA3W5L+/rt3W/mynTomnQEt3JJ+JvrmA3IiNFAXGmgX1FawC+m+YJbzLxjyZIlI/mNdtzTN2I0EFcayMqyXfbS7y4cyZWSURNw6yH+4MYOjokTJ95iLiQ99BX3K271Tx331Qy7guBy0vg8WG/FKoft4IbP4i3IpPztwsLCz3tvNOvxrYEW23iqKPs9VxKfnUlc4fncPSrvtUpYb2lygU+/frc33JZLcs899xSwS3KpxxFSdMVWv4dsle+Qzd0c9xqAGevm/AJVVBSTy+ViCDwhQQN8JLVLc1P7/bz39VXOuTye+/rK5zvNcz+U1ZG4XO5Lb5teWbBs1QHMUCXsWoV4w42yYLUd99133yQ2/dBVSoutbhc5997MmkscS4hOK2hxU1mlb7h9daj3f7r3uq99Yp3GJ67jnqktk5atopVcF3Dr0UnecKNNCu5+/fpNNv42m4PyN8jWdDTW/Rjy8TF22yPLTWeriFyWLQu5mLjeAbD26eaezMHfeQG3SLJaiwRdsK7g5icAJ+kbUjVuc+OziYkpPD0Cdc/nDk0EM9xJFedn2ybyrvizEnatknS4oQIsjlmzZvXMzs6+0MplIgmrAQHcwT0tHZxMYXaGe9QDX03vCW55kaap/vIFt33mzJlXt2VUmcxPYmsAgBfmsWkD4Nz9SbbYvnq1G7yC5Q7hRgYH35W82vjbiQ20d+11wL23JfI6OO1TSIBbXBMArsTbciu4eU4Sc1dSNJREoQKcZ9+DBY+U4F8AIv8GEleJUfrJyiTw2g5uGS0R2hXcPL79mSjVyxwmyhpwwkXJdVNFTeRGUQRwNEXiEkajedkZBF4FblUN/nHr5zDi9p/85Cd92NSzh2YkWTUAwAtgwcWkJXhD+UTKm3VLWh9uhmJYmiNwo5lY7Pw8yXDZaMLk1YAArkZRuOdhaRN5mXSxDdyCZ2FZrUgPKrj55s1QczEpKknuEIB347cRYcGFiEQMUf++3V1DubcEbtVx7Sw3v3UzLLm71LRO14AADqudyJKbaQO3ArdqjQ434naeB3CIsdyJ3M2h110Aj+QoSui16Pwe4DUnm4ZwCYphDhXcGC2Rcxahg0dKkMlIimkAgOdnu6mqzvdTg/Gujqx0G7jFiInFM0iHIME+atSo9MzMzAEqxfyknAbOAc4gMBWJdnGZke4eMOozmengmBcFuA63bdq0aYV4jDDletU02NIAAM/LOge3lZgYEceUMa2FXFWAbcEtKzaen4RHP42kugYE8M6Mg8uFqVh+6FLSfOlVtnU2v+yHcFCRG/xaPOt3KG29evUyN2989UAKpgHwXH4evKZee0A6SD0IsMgucQl9FaFvk7iEgfLr27vnucGvwK38E9lu42FAY7lFGyYkZcGz2YkFLgkg+TkOsdyqtjJaomjnZ7gN3AnQidGsosOhWXDrHZdo1iC4YwHgzEzfbglKsBm4g1NkquUSwGsb4neYEG5MTjp5WG6P0RIeBswxN3BSDd3g2gvAc/irox35wsGV1DW5UK/0DDemNlZeCI5ijQkikT91jY1GjAZ8asAX4AI7Qj3us4BOJOpl6nFfRaU77AI3Ntv00RK+gDBw+1KaSTuvgXOAu6mOZwqRuUcEOuSSuITn9+x8TC9L4hLqpTqdynIjCdbbc+6t1tbWFiQaMRroSAMAnF/MpXoA3lHGKG9rddk8+BWfG9WwNTU11fqaoSjKdTSHSwANAPCsjDYTGQf1xb9IYzPVclWU1UaVdLipoaEBG40YDQSlAR1wuYrzDlGQRZuPUmWb937+1r3L0/fnuQM9+NXhdhu4fWjfJHWoAQtwocwrtyQHC6vX7u1WvctDBkmrb7YBbstTErhVQl1dHb82asRoIDQNAHA8j+frIi+0ksLLzRe5wq/iGaMlQrq7oqLCw6yHdyizdypp4JwFd1MDzz4noyjRbD9OrMpaD8vtlqFAAO4uLy8X8qNZL3OsJNEAf6uGLfg5wKPdJMBdXuMCv4plHF/cElWX06dPV5vREqUK89NJDZwDPPouCv4tTpVTtV5tgVvRvnv37hoDt64eE++MBgB4Bs+hDGvqvaA8pIlIXPIhXdIkjx7KNskvIa4q9xyyA24Py40ViHvlypXVPNbNMzobMRoITwMW4F7FeMOJzZKmxwVa71DPg7hIczNVvba+SdwSJFszTgntbh4xKTHWW1RmwnA0AMDTYcG5kK5ccAXLIyUlfBiLY9Rb3BLEscFVW1tbghUjRgOR0IAFuOaKRKJc7zJqG2wlnObiRTwRBbfQjg0uHg781Fhu1oSRiGkAgKfxuJy3ixGpdVS0qtb9KQeKYQ4V02K5BXA3j5gUI7MRo4FIakAAj2SZelmnKuggr1scYxvg1hNaecTkoLHcUI2RSGtAAI+UxZZyUM89h1wwyviamcWzWG5sVyZ94cKFn/L3CxE3YjQQcQ0AcCfPjAMwIyVMq2vhasenXJ5iWMoVuIV2165duxp4xOSYZDCh0UCkNaADLtY3nLC+yXZs14EmfsPTuqAEz9ZoiQU3p7XW1NQY1wTaMdJlGsC7urDg4Qpc6JoGN/xtuCSw3MKyB9xi0l0nTpzYbPzucNVu9g+kAQE8lDFwlOnh0TDKJ8tsmznZ4pfjHpYb+yABGVq3bNmywbjdUImRrtYAAHeE4IML2HJC4OvIW/e3buB66pZbVbudz41MP/3pT3fziwvmNnxX96wpX2kAgHd2ZtnGFqr68QuO3eCWF59uCQ5iWe7q6uqms2fPbjWuCdRiJBoaEMBDORb4LKugLYwrvmGuw62KEcuNFQtujrccO3bsAwO30pH5iZIGBPBgR05QrWNltk0c4K33gHADcGRq2bBhw3rjd7MmjERVAwAccAcj8LfX7Wxdz3kFbvCLRYleDOIYnOEX9tWca93OnDmznmd+7aFypuiP48jjhMVIdDUQjNdQVecuK7iheSLXrJIXPO7KM6ko46wAl9fMOE0Rj0Q1YsJhC8O9mT+Vfb09Ub8EhFaFKc2taVReYRmDMEszu4eigY4Ad7HZPnyKMAQoVtvjYhLH0eHGusCNHVr27du3euDAgRGF21axm2zH1pLN3Yzjxb3YG89Qel02PzIM3bUXf9jjtSdf4i8def3s4veFW39l+StHHaODjaGW5zd/R8fw08pQy2ppddOuva2rGVPFKrdN4EYzlehuCRKwDuB5Pk/KGzlyZM/169e/z5/vi8gXFwC28x9fZrDh1ieOVNW7cBcscSqcAjWtbXRXf/l/K6/ed6rpDDcXr5fh9jtAtzrKl+XGRtDXzJa77siRI6tHjBhxUyRcE9vhV8lWe4SLTizJR3XZLtRiwMlIzDWAx/qOn6HV+04Rf1iQ4AKAV3Brgc1x6/Y74iIw71hwFjTxqMlKniBTtoUV2lyJS0c+f+GLJzc3EgcaYI+EthyilVwVAAVOhVmP2unj3LJBLLfyZe6///5NVVVVRzty7mXHZA8BeC6PJcF3M0tsdADbzF94OPq9P5OMb4NTsdweCPqDWwCHyW8uKSl5zcB9Tm95fDWSg8FSIzHRAC48SyvoNT64YpNDARvMeogvuJEBZh474axo5ikf/trM784bOacBATzYO2kmH1t5/quLxNLCCK/aSX8Fl7yI1Qav7cQf3DgLLL/7ySefLC4rK9turPd5/QHwbOODn1dIFGKw2uW1tP3/3qZiPpzub7ez2qhOMHDj7GjasWPHSy1qSBG7GYEGlAVnwI3/HR0dtLK53XWCXmLVC9hgE0Y4JLg5v9oBO8L8N82cOfM1nvah1FhvqOa85BoLfl4ZXRiD1a6sp9L7lil/G3CDS79goyr+LDe24Wyw/G5+9axh+/btf4jUsCAOkCwigEfCpzRl+PbN8ZDUzhP0h5oadbNG97d9Wm2wFQhuAVxZ729+85t/raysPGmsd/vTEoBn8dRhRiKvAWW1G+jk7OXqQlKstt9REqlBR3AjD8w+CgHcjUePHq3duXPnImO9WRs+xFhw31Y33H8jWO29J2jR0Qr1QSc8+QcewSX49CuB4IblRgHqopLDxm9/+9sr+E2dMmO9fesUY+DGgvvWTWdSYbVrmqjsxytpBfjjRS4mO/S3caxAcCOPWG8FOD9vUrVnz54XjfWGanyLAG5GUcIfRcFzJPtP0ov7jhPe6RWwA1pt9EwwcIv1Vn4379M4Z86cl9h6VxrrDRX6FgW4GQf3rZwgU2G1qxup8ud/V8N/YrXBYUCrjUMEAzfyifVWvvfGjRvLN2/e/LS5awnV+Bfc5MnCOHiE7s6lWjktTN22Unp6awmVs5aD9rWlR4KF29t6N8yYMWMFT96z07xnKar0HQLwTDOK4ls5HaTCHTlVTTvvWqR8bTyrLaMkQVltFB0s3MjrYb358yL1y5Ytm8vzm7iMewL1+BcB3PjgwfnguMPC85G4Xt5Gc3nShnrWbMhWG70RCtztrPfDDz/88f79+/9sLi79gy1bBHBZN6F/DeA2+4Ez9OdfvE4fc65OWW2UHgrcyC/WG38ROJsavv/97/+Gb8ufNdYb6ulY4H/DRUk13zmU9kKDlY109sd/pd9wFGDLhWRQIyTYXyRUuGG9cRAMC+Kg9e+9914ZX2D+mt0UXjUSSAMAPMP75b5AO6XQ9iama0sJ/XrjQSrjZotLAt7AHfgLWkKFGwUL4GrkhNfr+eJyJd+93Gbck+D0LoCHYtFSIS/uRJ6oom23v6BeIROwwVnIYKMnOgs33BPrriXHG+bNm/cIv45WY0ZPoNbAIoAHznk+By5IIXJhKnGV2JYuaXpe2R4o1PfR4/720/PocX/5O0rH6EhlA9U88096hPPp7gg4A28hWW0cqzNwYz/xvS3r/dxzzx1cvXr1L3j0hOfZCLkeKDPlBP43XBSAEcwCBQlEelz21dP0uGwPFOr76HF/++l59Li//P7S20ZHaO0++sXv31cfbvK22uAtZOks3DgQDijWG2da/V133fXm3r17l5ubO1BPcALA01PcB29mp4OnaVj+jcX0JmsNYMsIiVjt4JTplSscuGGeAbhYb1So7pZbbvnV8ePH9xr/20vTHaxaFpxNWyr41nob4WefrKG9dy6kX4EfXsQlAVfgq9NuQAS+SsKHPy829rt5gquWDydMmPCVjIyMdMzaKWI/8S5hMdJeA+r7MNyN6GwR0Zy/v/NIp+O4ckw9LsfR0/S4bA81xAx1VQ1U+8s19K1/7qVjXGYtL7Dc8oCUpg0cMTQJx3LjSDi4t3tSN3/+fPjfjxn/O7TOyGAXJQ2f0ODdsEAkPLfWtb9yLH/HD7Q9lNrhsqyBnY639tJjv39X+dlitQXssKw26hIu3ChDABf3BGdeHfvfq/jR2BVm/BsqCl4E8OD3SMycGM/ec4JW3LuYVnELADa4wb2TsN0RLkNJJOBGQTjLMBbpAfj06dOfLC4uft8ADhUFLwAcF5m6b5pMcVxAlpyl9298jp5krXiDDY7AU9gSKbhREVhwffSkjt+3rLn55pt/WFpa+rEZQQmtrwA3XJRkE4B9pJw+/trz9MPKOjVhvLc7Ao4iIpGGW/xv/L2o0ZMDBw5U8HyDD/HjscUteEDXSNAaEMCTxWrjgaiT1VT84Ev00IFTVMGKELDBiwz7RQzurrYNqqKHDh1q4tvzGyZfmHVNbsUHufz5byNBasDRZn7kvpiuOokj9LXgEJJHj/vKK/kk7Ex+7KOLlIUQdyBP19CJOa/Q/W/soSOchJERwB1RP5vLs6Qr4PZ55vHFZb2r1b1lXNHRa/muXKYB3OqDgBFfgOvg+CtAz6PHuyo/jqEvOA7WYbF5GrSKX71NDyzaQAc4SYb88O+O67SI+dlcliVdATcKB+CyyMFsH+w6WsnTAO+8pD9dx4CnGcBFNYFDAVwfBw+8V+xzAGyeKar+D+vpu798k7ZzjWCtxR3Rh/0iXtmugluvqECO0MbPD5zpmUs7RvamKQx4Rgp/S0rXUVBxAVwpkk1ivPviAPtsPVUv2Uizfvaq+jgToBarDbBhsdGcLpFowo0GqIas3kOnud0fjBlAk/nWc450Wpe0MMkKFV3BB9ddgHiLtzC27GOfmvcWPTj3DfqIuwFQY4ErolvshIab22KdnWiIasyGYqrkZwreu/ICmsivYBVIpyGzkY41IP92cpHZce7ob23icY/jVXToZ3+jB55fR59wDfCNSN1iR3xkxFcro2G55bhyhlqAf3yEanccp7WfG05j+XszRQAcf7VGAmsgHgHHyQawedqzXQ8up/949WNrVEQHO2J3IANpKZpwS10EbhV+eoYaV++lt68dRaPyM2mAAVzUFDgUwJEz1v436oBb6p+W0cZbX6CHNn1KpzkJUMPP1h+GYo/U+ifnaNdJtOHWwZZGus/UUMufPqS114+mfvkZNNxpLHjQPS6Ax9JFwRh2Hdtjnqzy9WnP0k9Ky9QNmpiCDQVGG27pNB1yxF31jeT63Xu07ooLqLx3N7oy3UFO6TjZyYS+NaAPqUbbgquhvkZq5FGwX13/ND3L/YgPnsLH9jXch76OmsQKbjRQQd0WWrAv30r7bXbaOLIPXZHppG7GTQmOBQ/AeZeuHj1B7/HEOXSikg4/vZZmzV5Ba/mwsNbiX8uoiNygQR9HVWIJtzQUjYaLYrkp6w5QOfvhb04aSn3YDx9m3BRRVcehAN7VFCk3hAfz9p6kN29fQD9Y+REd4poJ2GKx9TuPXV0ln4qJNdxotPeiQD9dTc3sprw39gI60zufxsFNkb9cny0xiUoDMtrUFTTBr1e30huo8e399D/TfkPPcj9V8oF1/1qeFRGLHbOeiTXcaLj0g1hvPXSv2EqfuG20bngRXc43fAod/H8rHRgzrcX5gS39tOlKjEI4IcDGmzPHKql43ts0i7/g+y6rQe44yoiIgC19GFNNwTWLF0FdcLJh4cf1Cd/p5Q9SqyW7ex7lLL2X7vjsILq3WyZ/vIBzWZ3ImYy01wDch3AFUOMZbJ5TpH7rYVrAs64uPVvtYan1N2hgrbGIwQr38GHtHw+WW28AlCKLnP0IW+ubyLX0A9pxqIzWXNib+vLk7oPlYtNArqvwfDwcvYgLUsu2eP9pemfOSvrBwyvpHe4HuCAyGgKwvZ/siwuwoYV4styojwieYsaCGT14dj1lxfl7YZYlz3j2drr6Xy6m2T3zqD+PqpAZNmTt+BGAiiVYgcWHC8L3H46+toOeenAZvc/7wuUAzAI01vVnRCLwP8ElRlDiFW40EXUTwAVyAG4tA3tR3oI76J4xA+mOvHTKgKtiIIfq2kswcANquCDVTdTIj0YsvXcpLSo9rcatYZ31RaDmU8Aa5Wp/0BinxDPcUA3qhwXuEwCHLw5LbgGO+MyraNCDk+nuEb1pOrsr6TyyYiBnxXiLP8ABNW6dswvStP8UrXrmPVr8x410mPfXgUYcUGOID1CLbx3CfwLvFUWJd7hFFagnrLhALq4KLjoF9IyvXkb9Zk+lmSOK6Cv8XfZMfl7cQC4a9BECatyIqW6gBob6b0+toT/+5SM1OQ5cDgEbcd0FAdRwQeIWaq6bkkSBG5VFXQVyWHFxVQC4QK7iU4ZTr4e/RLeN7kdfzcugXAU57xnOBRYfIykE1htv8yioG6lm1zH6y3/9nZat/UQ96CQgA2yJ+3JB4h5sdFYiwS1wCeDe/jjAFosOa57+2c9Q4X9/mW4Z3Zdm8J3OQszJJ3c7Uwl0AI0Fkw80sFPBU5iV7zpOL//0VVqx9VP1pTAALEAjrltq8asTwlpz3S1JRLil8gI5XBUs8MdlfFwgV8AX5lHW4zfSxCsG0vUDu9NEfnY8Xax5Ml+Awu0QK13bRE2lZ2n9llJ6g4f11pdXW4+h6hYacfjUcus8YVwQrnM7SWS40RjUXyAXn1wgB+ACucTTxw2mbj+cRlNH9aZp/QroYobcpmZ3QkFcUiJbdLHQ8Bnw0gC7Hu5jFbRzDz8Dwi/nrtlUom6VwzLLIhYa6zrUsNJiqRPCBeH6tpNEh1sa5AtyfXQFcAN6gVydAHdNoAF3j6PpQ3rQlIIcGoxRFoCubg5x5niHXYcZz3wAaIx6VNRSSXEZrV28iVYt2UBHuCkCrkCNdT0O10OsdMJDzW1Rkixw6+0R0MVd0V0WuQgV0MXKO798CRV9bRxdMbQHje3TjS7n0Za+cF0wdq7DjgPFwroDZIgCmkPAjDHpttGO4/zo6YcHy2jbnzbRlld30CnOAmB1qAVoPR1Ay4IjyMLRxJdkg1vvEbQNroq4KwI7ABeovUNsQz7nzHHU78YxdMWQnjSWn0q8LDuNemIObVyQAnbrwpQzQ3Tg9fi5rYF/BV7klLgijX9wIQiYEeKtcn7r5czJKvqo+AxtW7mdtvxxkxq+E+urwytwSyh5BGgu0XI/AlcywXIkM9zSFWLJBXSEFsQcB+BYF+glriBvS7dPGU6FUy+iwcOKaFBRPg3qlkUD89NpIFv4fmzdnQAez1OLK6POLK91bBPLq0IGFxd8AjHSsN5mlVt4/PlYVROV8qQ2paeq6DDPr3d4zW4q4WE7fAsdYAJWAVbiANk7DpiRJjAjVIflMGkFfZAqgrbqC+AF6Ahl8QU20mS7vo86WXIzyfm1K6jfZQNpQEEm5fP0w1lZaZTNw47Z7L9ns4XPZl8+i61+NsOdwQA3svWtY9+4ni1xHfvJdTw8V1fPS2Mz1Vc0UNVHpXTkT1voWE2DB5AAFFCK1RVgBWR9Xc8j+wjMEnJRyS2pBLfekzrkiCtQOdThFaB9wS0nhYRShne5so5jIy4CwCACmncolhWQCpwIJS7wAmyJ+8rrXS5nTx3RFZ46rfZsqQCohwK7Hgr4HaXpZUgcR9PjWBfo9LikIRSQBWZ93V8a0vUyJI5jpKRA6UY8NSAgeoeAGmmBQu/9UDrSvAXwQQRCPRRQA4X6PhI/V6r59al0oxZPDQisSPUVlzQ9lLx6iLi3AEiIHgqk3qHk886rCjA/7TWADjESugZ0vUncO5RSJV3W9VBAlTRZ9w6xXdIkrwkDaKAjxQfY1WwOoIFQdGvADaDMzmz+f6SMYEX4z7hMAAAAAElFTkSuQmCC'};return{FaviconsByHue,};});'use strict';Polymer({is:'tr-ui-b-info-bar-group',ready:function(){this.messages_=[];},clearMessages:function(){this.messages_=[];this.updateContents_();},addMessage:function(text,opt_buttons){opt_buttons=opt_buttons||[];for(var i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined){throw new Error('buttonText must be provided');}
+this.onSelectionChanged_();},get selection(){return this.brushingStateController_.selection;},onSelectionChanged_(e){if(this.lastSelection_&&this.selection.equals(this.lastSelection_)){return;}
+this.lastSelection_=this.selection;this.tallMode=false;this.tabView_.label=getTabStripLabel(this.selection.length);const eventsByBaseTypeName=this.selection.getEventsOrganizedByBaseType(true);const ASV=tr.ui.analysis.AnalysisSubView;const eventsByTagName=ASV.getEventsOrganizedByTypeInfo(this.selection);const newSubViews=[];eventsByTagName.forEach(function(events,typeInfo){newSubViews.push(createSubView(typeInfo,events));});this.tabView_.resetSubViews(newSubViews);},onSelectedSubViewChanged_(){const selectedSubView=this.tabView_.selectedSubView;if(!selectedSubView){this.tallMode=false;this.maybeChangeRelatedEvents_(undefined);return;}
+this.tallMode=selectedSubView.requiresTallView;this.maybeChangeRelatedEvents_(selectedSubView.relatedEventsToHighlight);},maybeChangeRelatedEvents_(events){if(this.brushingStateController){this.brushingStateController.changeAnalysisViewRelatedEvents(events);}}});})();'use strict';Polymer({is:'tr-ui-b-dropdown',ready(){this.$.outer.tabIndex=0;},get iconElement(){return this.$.icon;},onOuterKeyDown_(e){if(e.keyCode===' '.charCodeAt(0)){this.toggle_();e.preventDefault();e.stopPropagation();}},onOuterClick_(e){const or=this.$.outer.getBoundingClientRect();let inside=true;inside&=e.clientX>=or.left;inside&=e.clientX<or.right;inside&=e.clientY>=or.top;inside&=e.clientY<or.bottom;if(!inside)return;e.preventDefault();this.toggle_();},toggle_(){if(!this.isOpen){this.show();}else{this.close();}},show(){if(this.isOpen)return;Polymer.dom(this.$.outer).classList.add('open');const ddr=this.$.outer.getBoundingClientRect();const rW=Math.max(ddr.width,150);this.$.dialog.style.minWidth=rW+'px';this.$.dialog.showModal();const ddw=this.$.outer.getBoundingClientRect().width;const w=this.$.dialog.getBoundingClientRect().width;this.$.dialog.style.top=ddr.bottom-1+'px';this.$.dialog.style.left=ddr.left+'px';},onDialogClick_(e){if(!this.isOpen)return;if(e.srcElement!==this.$.dialog)return;e.preventDefault();this.close();},onDialogCancel_(e){e.preventDefault();this.close();},close(){if(!this.isOpen)return;this.$.dialog.close();Polymer.dom(this.$.outer).classList.remove('open');this.$.outer.focus();},get isOpen(){return this.$.dialog.hasAttribute('open');}});'use strict';tr.exportTo('tr.ui.b',function(){const FaviconsByHue={blue:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAlrklEQVR4Ae2dCXwdVb3H5265yc3SpEk3ukEXCqVUBLT4Wm19oFKtaN0fKijy9CMguPBarIJsIiA8qsjTh7SllAoFeVBaEARkLV1ooXtL0yRdkqZp9u3uy/v/5uY/OZm75y659+acdnLOnP385zv/+58zZ2YMinTplIAhzsoDceaT2RKUQLwHIMFqh0V2ll0kn4XA6byv9/Vw834kX19e7keRQCzhRyk6bJJYRvD1YTXuhRdeqDj77LPPtNls400mU7HRaCzFFggEVJ/iSqhsicFgKIXUKL6bvB6fz9fj9/u7Kb4bPjaK67Xb7Q0HDhw49IUvfKEd2XUb7WpxHIYvXRgJ8AELkzRso1gmKrwkBfjG7373u5Zly5ZNKS8vn2G1Ws80m83YphPI0wnQUemQFp0IzQR9tdfrxXbI5XId6ujo+PCuu+6qXbNmjYfa9NMmngDoBmt+hIe944M53AUhwqwCvXTp0qJrr732opKSkk8XFhZ+imC+gIAryAZB0QnlJuB3OJ3Ot3p6el5/6KGHttxzzz0O6pse+GEP+3AGnKE2EhgG0tAFt99++4WkoT9tsVgW0DaH4guzAeg4+uD0eDxbaXuDNPzrt9xyy3bS8G4qB8BF6OOoKr+yDDfAB0B91VVXFf72t7+9lLT05QUFBZfQoYWtnA+ux+12v0ra/W+/+tWvXlq5cqWTBjUsYR8OgDPU8KGtjR9++OHHx4wZ8+2ioqKv0X4lbfnsWh0Ox9+bmprWzpgxYxsNFBpd1Op5bcbkM+AMtgr11q1bTz/zzDP/gy4Qv02zGtPzmehIY6MZmmq6UF176NChJ+bMmXOkD3QR9khFczY+HwEXwTbV1NTMI229FCYIXSTm43gTho8uUgMwYUir3zN16tR3qAIfbXkJej4dcIxF1dbkm44ePfqZqqqqpTT7MZf2pYsgAZqN2dTS0nLP5MmTX6EsDDrDHqFU7kTnA+Aa2BMmTDBv2bLliyNHjlxCZsgFuXMYhr6nZL7saGtru/eiiy7aUF9f76UeAfKcBz2XAUffVbgJbAuB/Y3KysoldONl5tDjkrs9oBtL+1tbWwH6UwS6/mZSzg0sVwHXTJG9e/deOGXKlOWksS/MOelncYdJo2+vra396axZs7ZTN0XTJYt7Hdq1XANc1dg0DNOqVatGLl68+DZa/3E1XTwCeOn6JLCly6ncU9+mNLnBZRLOYPAHHI5H2l5/8TdHbl3SRjUx6DkztZgrgKOfDLf5xIkT36moqLiLzJG0rAFJAomsKDp1W51S74IZnSIX8DcrXV3LlK/Oe5xqZPsckGc96LkAOPpowrZ79+5ZNK31BzkzQtKI4qxvV0dJTSLJ592kHKu7QfnPxXupFmhzbFkNeTb/tGsae/bs2Va6wr/lrLPO2izhTgLQZIuaaMp1yvTNyvNbb1HomFB1ZtrAUNYqymztGMNt2rhx44T58+evohs1n0r2+AyX8mnT4KIAvZ63lA82f1/55TX1FJ21tnk2As4zJObq6urP0BTgCmlri2TFDmcEcHQDtnlz4w+Uyz+Hm0Rsm2PuPGtcNpkomtZesGBBYXNz8210d+05CXfWsBLaEQNd5I+e8JyyYettCh0zyoBrpawyWbJFg2twv/jiixPnzZu3mhZFzQ2VqIyJRwIZ0+BiZzyeTcqebVcqS350nKKzxmTJBsDRB3WWZN++fXPpps060tpVouxkODEJDAng6GIg0KI0Hv+mcsXnN9FeVsyyDLWJwnCbadXfomnTpm2UcCcGc1blNhiqlNMmblT+9soi6hdmWKC4hlSJDiXgaBsCsNDKvysnTpz4JIWLaJMupyVgKFLGjHtSefrNK2kYFtpwjIeMs6FqWIOb7kr+Yty4cX+m2+0446XLBwkESHuPrPqz8uymX9BwhhTyoQBchZseQiigdcj30grAO+SDCPlAtW4MeLikdMQdyvqt9yp0rCl1SDR5pgFX4V64cGERvdhmRWlp6XU6scjdfJNAcfF1ysqNK5Q5C2F+ZhzyTF4AqHCPGjXKSjdwHqUHfr+ab8cyW8YzZLMo0QTgcj2jfO/S7ynNzS7KxtOI0UqkJC1TGlyFm3pccPDgwfsk3Ck5drlVidX6VWXFxvvAAG0Z0+SZAJzhtjQ2Ni6ld5D8KLeOjOxtyiRgK/6R8uy7S6m+jF14phtwmEBow3L8+PGr6FnJm1MmLFlRbkqgtOxm5am3rgITtIGNtJrJ6QQcHcdPkYUuKL9MsybLKSydlICijKxcrjz+0pdJFKzJ0wZ5ugBnuM27du2aT7ffV9JUIGCXTkqAJEAsjJ2wQlm1fj7tpPWOZzoAB9yo1/zSSy/NoLdJraMwFsdLJyUgSqBQGX/GOuX+FTMoEpCDmZRr8nQBbqIHgovnzp27mtaWlImjkmEpAU0CYGPmR1crF19cTHH4hU854KmuECcMOmo9derUAyNGjLiawtJlWAJZOQ8eTQb27keUyz7xM8qS8jnyVGpwNk0s+/fv/4qEO9oRlWkDJGArvVpZ89JXKC7lMyupApzhNm/YsGH6GWec8eCAAcgdKYFYEhhz2oPK3X+ZTtlSao+nEnDzxWRL0eNmj0q7O9bRlOkhEoA9ft6cR5WPq/Y4IE+J+ZyKSjS7m56jvK+srEzeqQw5epmNyDkbXBRPT8//Kl++6EaKSok9nqwG10yTHTt2fJpWB0q4xYMlw4lLoJhu5z/y3KepYEpMlWQBV7U3mSXFNN99H71YPfEByRJSAqIEwND4yfcpFyzgqcOkGE2mMGtvy2OPPXY9vZjnTLGfMiwlMGgJWCxnKktv/QmVT3pWZbCAM9zmxx9//IzRo0fj0STppARSJ4HykTcqN//3GVRhUqZKMoCrC6no6Zy7yTSxpW5ksiYpAZKA0WhTPj73dxRKakHWYABn7W3Zs2cPvjH5eXlApATSIoGi4i8oK56/tA9ysAr2EnKDARxlzJdddlkJ3dC5N6HWZGYpgUQlMH7SvbRWpYSKsamSUA2JAs7a2/ynP/3pOvrc9eSEWpOZpQQSlYDZPFn54a/xcDoDnpAWTxRw5DfRJ7DL6HUPP060rzK/lMCgJFA+8sfKZd/CqlRc9yXEbCKZWXtbli1b9gN6EX3loDorC0kJJCoBk6lS+ebVP6BiCU8bJgI48ppxU2fs2LHXJNpHmV9KICkJVFZdo3zsY7j5w6ZKXNXFCzhrb/PDDz/8HbK9x8ZVu8wkJZAqCZjNY5Wf3vkdqo4Bj8sWjxdw5DPRt3KKTjvtNNxhkk5KIPMSqBz1E2Xq7ITekBUP4Ky9LevWrfsGae9JmR+ZbFFKgCRgLpik3HL3NygUty0eD+Cq9h4/fnwBbTdIQUsJDKkERo+9QSkr47ubMfmNlQHaG5v56aef/ndaUDVtSAcnG5cSMFumKXc/fDGYpI35jCiXeADH3KOZ7lp+Sy6HjShHmZApCWA57dgJ3wKTtIFNQB7RxQIc6abLL7+cniEesTBiLTJBSiCTEiguWah8/isjqEkAHpXhaIk4M5BuXrp06ZfoOUtcvUonJTD0EjCaipSvff9L1JGYU4bRAEeaCjh9P+fr0jwZ+uMqe9AnAZgpo0Z/nfYY8IgcR0qA9sZmeuCBBybZbLZ/66taelIC2SEBKzF5zTJMWbMdDl5DXDTAVe29aNGib5D2jpQvpEIZISWQEQkYicm5C0QtnjDg6uwJPY72tYx0WDYiJZCoBMorGXDW4iE1hNPMOBMQb1qzZs0MmvueHlJKRmS1BCZYYZoOA2exTFd+dT/eTsuzKSFaPJwkNMDPO++8+fLiMvdA+Z8JJcqPN+9RGnocoZ0PBELjFF2cbjdYIEykvq4wWehd4APb05dBari4gaWCe/p8AT+uFOdT4j7aoJTB7oAGowFurqqqmicBV5QPmgLKX3b7lVbHANmRLLPVVSjnGT6hzFRa44dHHEqIHhQThXC8+YQiqQ66K9rnvakoD1O9DPiAJvSAo8vYjMXFxWZ6U9VFA3IP052fv+5VGntzBW4+SCYl4KtQ/L3tpCBJ0+WpC/hKLgKrvb29DDj41Q4WIvUOcaZHH310lslkGqlPHI77uQd38CgZTBbSVBVKXk+CGYwjS758/ywwS1sIz/oI1uCmmTNnflKaJ7l/OmuQG3migQ9xnvg0W2gaN/2TfYDzoLQDFw5wVYOT/T1XAq7JKacDKuS2csVg1B/unB6W2nkwaiiumEs7rMEBueZEG5zpN9Gt+QKyv+douWQg5yXAkPvtHYO78MxiCZisJXNsVRML7C3HndRN5li1w/WnNPaNDz744Ll0ZpRm8Zhk1wYhAYacjPJBlM7eIgHFUFryxZvPpR6q/Io9DavBJ0yYcJY0T0Qx5U84CDnNrtjb82dQZHqZysefRQPaRltEDc4JRlr7PS1/Ri9HopeAwWRWjLYKQiF/NLnBWgpmocGZY3XYoomCBOybaPXgNKnBVfnk7R8V8qLyvIAcrBoLiqaCXdoYcvXYMeB8KmPfSIBPUVPln7yWQD/kjEEOD7fABsBVfvtGoTIdYoOPHDnSXFhYODmHhyq7noAEgpCPUPyOTiql3QBMoIbsyGo0F04uInYdbW3RTZRbb711AnXZmh3dlr3IhAQYcpooz0RzaWmDTk1r0YLrwS4GwRaJuoMGmXrjOeecI5fHQiLDzKmQF9ILXFXIGYfc8q2jZ4JdBlyFnE9ZHolx1KhR8gJzmMHNw9Ugz8U7nrijWToyZCZFtMEBu7GoqGgiD1j6w08CKuTWUsXv6s65O56GApVdlWM+cnoNbqB3D+JzEdINYwkw5DlnkxvNYJetEdVEETU4Ioy0RLZEzoEPY7r7hh6EvIQ0eQ/FZP/sCpilPgNwKG0VbgyFdzTqCXC8ZFw6KQEAoxgLS3NoPbkR7GosIyxqcBxSgwQcYpCOJWDAOnIrKUbS5AH9M5GcKUt8OiEZcK1HbIMjQiVfAq7JRgb6JADIDQR5tpuuAaMGuGaisAbXIiTgkutwEujX5L2UnJ02uSEIOHdfZVpqcBaH9GNKIKjJQ6yAmOUylYHsa+6cprBZg3MfpA3OkpB+WAkENXmxEnDbs2+e3KABrvU9RINTih56LbMMSAlAAqomL7BRQFOU2SGYgMouOqV1jGHWIrxer50+8iofV8uOQ5a1vVA1OUEecOPtWdlhkxsUH/2saE5lmufBtVifz4erCOmkBGJKIKjJ8V0ETT/GLJPODAG/X8+uOg+O0087BaHB09kJWXd+SSCoyYuUgIceaB/qeXL/AA2uci3a4JB8QGrw/AIwE6NRNbmlcMht8oBftT40ZY2xsw2OsJogAYcopEtUAqomt5Am9w6dJg8ENPNagzysBs/2W7KJCl/mz4wE8OYsg3loNLnKbNAG1+DGqFmDI1LdpA2eGRjytRX19XAEecDr6kMqcyM1BNTrR41ltCxqcAYc6yOlkxIYtASCmhyP9WZ2doVmUXhtL1hWHWtw3lccDkcb1H22L6zROiwDWSmBoCa39mnyDHSRmPV7nG36lliDs1r3t7e31+kzyX0pgcFIQNPkGbrj6be3gV287Z95Vk0U7MCpkdXV1bXyIjMoEPk3eQmokJsKglOIAD1tm6J4Wo7UMsd9PQ+wBse+CvgzzzwjAe+TjvRSIwGGnB4qS02F4WohE8W58zk94CGzKP6XX3652+VyNdN6lFHh6pFxUgKDkQAgDygWxeDzDKZ47DJeV3PvvtfpVQChJgoKs80C+8Xf09NzRJopEIt0qZQAIFfou0GpXoUIVv0uxxHqq8ov+cxzyDShmsFut9elcmCyLikBloAKuZEm71Jsi/vdKrMi4GqTbIMz8cjgw0yK1OB8SKSfagkMgDwVlZMGDzg6oJR9tIFh5lmzwdEMR/pPnjxZiwjppATSJQHVJg/QRaffm3wT9Gvg624GswPgRsXhNLh//fr1u2nRFYCXTkogbRJQbybCXEl2diXgCzh2bthNFQHwAZAz4BgEgEaijz4C29zZ2VkjzRSIRbp0SiAIOT7MgCnExDeyThS/s7uma+vaZqpANFHUbusBZ8i9ra2tWyXgqozknzRLQIMcF56JOiLc19O6lYrB1hmgvVGVCDj2VQ1Ovq+mpmaLBBwikS4TElAhx7vJE55dIWhb6rZQH6G9WYNrXRYBh/ZmDe5buXLlVj85LacMSAmkWQIa5Im0Q4x2bXkUGpzhZo7VWsIBrp4JGzZsaCc7/KDU4olIW+ZNVgL9kMe2x4P2d+dB+86X8NFP1uARAUffWIPDnvHSdOE2CTjEIl0mJRCEPA57nAj3dzXj468qr+SzDa51V9TgiGTAcTZ4yQ7fLAHXZCUDGZSABnlUm5wgba3dDFZpE00Uraf6Bx5YveNM8C5fvnzbJZdc4iwuLqYH7Yavq+ytURq70rRIKIvEGlmZAYswDjZCRBchLUJ0ULeGqYzaQL8AfEj/PA5nz8u/Zw3O2ntAC+EAR0bVnnn33Xe7Gxsb35gyZcqlxhR9mGj/oU7liWfrlPZOd5jRZGfUbK9bmUnPGIYIeEB3B8i1PyUKBHTo+vPFEYrcfpR6orYfR6NZmiUQ8Cs9XU1vbDiyEysI2f5myLVe6wFHAqSlanDyPTt37nz+9NNPTxngv/3DHqW5lV4tkGPO67ErPi+9pgw/mYAGfjyO8zJo+vL6dH2dmc6vb1/fP31/9Pn1+7HK69P15fXt9eUP+LxKR/OB5yk7flrFOfABNehtcCSKgHuvu+66t2n5bGtk7TGgvpg7uQg3BmW22BSTGa8pIwehx+s4L3wxzOXFOM4j+sjHecSwmEcMi3nEsJhHDIt5ENY75IXjMhxWI+P4E6u8Pp3bYV/fHsWDRb/f1Vq3b9XblBzxAhNFowEOte+hlYWO+vr6f6QKcDSaq06F3FQYdeUEow9fDGfLmMU+ieFI/RPziOFU5Y9UT/T4gOJ2tP/D7e7Bmz+hwcNeYKKOcIAjHiaKZqa8+uqr6+l9KYgf9g6QG/sgxwHXbxAQgyCG9fmGal/skxiO1B8xjxhOVf5I9USLV8j+7mjd/Rz1RzRPwGuIiwQ4zBScFaDas3Tp0r0dHR2HpRYPyo8hD+7Jv5mUABj0eeyHjx58Yh+1y4CDVTAb4qIBzpCjEjfNiW+Qd+775dcPeTRdI9NCf+OSlQl98M3RvAFM0sbmCVhNCHAcSah8TYuvXr16PT2MjAql65OAapPjXXzRnP4iCnk5Llw5ToMvhsPlzYU4cQxiOFLfxTxiuC+/3+/xNB9/cz3tito7rHmCIpE0ONJwRrAd7l61alXjkSNHXpBaHKLpd5hZMfELJ3FA9Buy8oESw/p8vC/mEcOcnmu+OAYxHGkcYh4xTPlx38DtaHnhZP3rjZQEDR5xehBF4eIFXDVT1q5d+whp8YhnS7DK4fdXhdyEd/FJl04J+ANef3PDpkeoDTZPkgIcfR2gxe+7776aY8eO/VNq8dDD2A95sjamLE8/eSTggRsuLj2Otn821D5fQ4lxaW8cpWgaHOnQ1pqZQmHXU0899VePxxPWoEeB4ewYchwadhzmw4V4jhPDnJ6oL9YhhuOtRywjhuMtr88n1iGGOZ8YJ4Y5PZKv+H2BthOb/0pl8F5mEfCoFkUswNEHVICLTdVMufPOOw+QFn9TanGIJtTBHjeSucIHCjkQZsfhSOmcL14/2fqSLa/vZ6z6YqXr68M+1p24nK1vHq3++wHaZfMETEaFG2XjARzaWgOcwq4XX3zxYdLiKC9dGAkw5Pqf2czso0OMkRhGXG5u9N5vpb3p/YdpAKy9AR+YjGlJxAs4a3GcPa4lS5bsOnHixGapxUkaEVwQcnqrasYdw80wowMcl/HOJN0gtLfb1bH5yMHHd1FlDDhr75QAjk6yFsdVKyB3bty48UE5owLRRHYa5JgSY8dhniZDPMeJYU5P1BfrEMOR6hHzIBzLcV8j1aePR31cRgxzPjFODPel+xWvv6N5x4OUhCWoYA8MxqW9KV9cJgryAXBocQbcdeONN+6kd4k/J9eoQDyRnQq5se+Fk3yg2UcxDvcdULUmjotcbeQULhtvffr8XC6Sj5a5TORe9KdwXq5PXz5KOn0WUHH2nnyudt/qnVSMtXfMqcH+xuMHHGVYi6sXm2jwpptuWk4PJrfLNSqiSEPDGuShSTImggTUNSdee/uxA2uXUxaGO27bm6uNxwbnvKzF8fOABp2vvfZa89atW/8oLzhZRJF9zVyJnEWmCBKgb14qPZ01f2xv3o03VsE8AXNx295cVSKAo4yoxVXIFy9e/Aw91rZLXnCySCP7Jpo+NNLnPMQvHXAYfjz/UDuXEcNcVowTw5yeal9sQwxHakfMI4bF/HhiyuPq2LV/293PUB6GO2HtjfoHA7g4o4LGnWvWrLnL6XT6pKkCkUZ3gNxAL4HnA4rcCMfrOG+k8rHS420n3nyJthcrPxgK+D2+5oa37qI+qHyRj4vLhLU3xpAo4CjDgOOMUrX4HXfcse/AgQPr6I20SJcuhgQYcvVijS++pN938RpQHD0n1h378Cms99Zrb7CXkBsM4GiAIVenDGnfccMNNzzU0tLSKE2V+OSvmiuYXZFOkwDmvD2e7saa/X99iCLxOBoAF7W3ljfewGABZ1ucpw2d7733XusTTzxxE33+xCNNlfjED3vcqELON2WGr0+WCS03cXtaTmy6qbutppUkyHAnNO+tl/xgAUc9DLmmxWnacAeB/hDdANK3I/cjSCAIebi3d0QokKfRZHcrvZ01D9XtW72DhqjX3mBtUC5ZwGGqaFqcws5LL7109dGjR9+WN4DiPx7DHXLc0HE5Wt7es/m21WCob4PiTOimTjiJJwM46gPg2PiCE2ee/Wc/+9lvyB5vkvY4SSNO12+uxFkgT7LB7vZ6uptq9678DQ3JThsYggkAppgvCg7OJQs4WkUnMH2CMw6dc9ANoJNPPvnkL8ke90p7nCQSpzPS9CFscryHbzhsEEvA7/a2NLzzy46WXSdpV+WH/KQuLFEvu1QAzrY4mypqJ+lVE9u3bdv2Z9jjEnIWd2wfkBsM+W+T9813093K6j/X7l+9nSQjwp3UhaUo5VQAjvoY8gGmysKFC1fSgqxX3G6ckNLFKwEVcu3rY/k5swK729Hb9Mqed29fSXLRmyawCAZ9YSnKOVWAo06GHDTjQgGdti9atOjXdNH5noScpJGAU00VI74+ln+OXv2gOJ0t7x3cduevaXQqJ+TztGDK4IbkUg24aI+rkNNXIrquuOKKG+kBiYNyURZEHr/LR8j99OFXt6v94KH377/R4WjtImkAcBFuMJQS7Q1Jp0NFoHNiBw0Eube2tnbT/PnzFzz3UtMIA76mJV1cEjAYcIhInLgTkuMOZonH3XW8dvdff9zZur+JhtNLGwMO8zal2hviSgfgqBduAOhki7u6u7u3NHWO+yxNidkk5EEhxfM3CHmfSHN0zQq98Fjxunta6w+v+9GphneO0Wj0cKdUc7Nc0wW4qG608AcffNBrMlvfLx0x5XMGo7lAQs6HIbbfLytNnLELZUkOrO2mF2b2nDz64rX1hzccpG7p4YbmBuApd+kCHB3lI8G+2vnOlr0dBYVV+4tKxl1MswWW/gOX8rHlXYUsq+C8ChaeZv8/vOqYvo5hb2l48+d1+9fiNrwId8rmuyMd7HQCLrYJyDXQ20/tOGUxF+6wlU1aYDQWFPGBEwvIcHgJ9MtKE2f4jFkQq9rcnu72xrp//OTIgccx181wY8477XBDBJkGXAO9o2VPm+JzbioZMXWewVRQ2n/g0C3poklgoKyyc57cTxeUXnfHCVrXfU1D7fr9NJ4e2gA4w530OpNoMuK0TAGO9ljlaJB3tVd3u1yNb5ZVzPy40Wyt7L+Y4u5JP5IE+iFnsUbKmfl4zHN7nG3VdXtWXNvU8GYd9QBgZxxujDyTgKM9OAZc9e1dDY6ejoOvl1fNnm0yFY1TaApR/QhoMK/8G0UCGuQGEmUWKHK83jhA89z0gvoPDu1cfn1b864T1H29WZIRzc1iyzTgA+CmTqj7Lkeru6156xsVoy+cQk+fn44DJyHnQxTd1yBXRRk9bzpTsSrQ7/MoLvvJN/a/d9uSno5jLdQew40bOVghmFG4Md5MA4424UJA97rtvub6f71VPupcq9lSNttgNBLj8oZQUFzR/w6UU+ZVOeD2eV2B3u7ax/a9e/PvXI7OTuqxCDcuKDMON6Q2VICjbYacJ/jpHYte/8mjr35gtVUdLCwaPYfmyunDlFKbQ1ixXBByiDRzTl0RGPBiPXd7S8Pbyw68d+/TdAz5YlK8QzkkcEMSQwk42mfI4Wugt53c3uB0nHyttHz6THo4dywOnjRZIK7ojiHPxOw4lg4EYJI4mnfW7V95ff3h9bupd9DarLlhkohTgZk9+/pElS2AA27eVOjt3fW9p4699kr5qFkmc0HZR6TJ0nfEYngDzZUYmQeZrN6ZhEnSeXj1nk2/vr2nsw5vn4LGZrj1i6cG2VLyxYYacIyAz2zW4hro9HPnO3nstZ2FhZX7Cm1j5tCDAEWkyqU2j3HctV+7FJvjWE+CWRKvt6utpeGtX+7f/vv/6zNJGG7McfPFZNpuv8cY/oDkbAAcHRIhF0FXw21N2084HfWv2UonjaHPhEwJaikJ+oAjqdvRINfFD2ZXfSILF5I+Fz2kUP/akT0rlhyv2bCX6mKNDcD1N3CgqIbc4RzPJof+YOoEJx7eioNPl+FDlHSxqdgQnj77h5+oGPeJXxQUlE3Cg7qZ+EmmdnPWYYYjGRec/nMrbnfnsbaT2+6v2f3wZqoPJghDzVOAvNwVDbLCSqbplJTNNsAxKP5hBeR4OBGfSQDkDHpRYWFFyYzzf/Gd4oqpV5JGt+IZxlRqLGorr1zwmdjEmOMZEp/X4erpqFld/f4Djzud7ZghgabGBrDZ1sYsCa/lTqwhKphOly0min6MLCT42KAV2Kbzeb1Ob9Pxf+32utteLSqZOJ4++jRJmi16Efbv95/8rDsi++pzFX3mCM1kvXPkw7X/Vbd31eskc3H6D9pbhBvHJ7mfiv7upjSUjRpcHCD6xyYLa3PW6DBbVM0+4/yffKq88iPXmq0jJuOdf/J2vyjC/nBQk/fviyHRzva6u462N+96qHrng29RHtbUrLUx9cc3bljpsEISq8yKcLYDzkIC5Aw6bHNAzva5CrnZbC6c/pHrLykbefYVZmv5NAk6iy66PwBsV8fhrrYDj1Xv+uOr9GYyBpt9ntcWbe2s1NriiHMFcPSZtTlAhzZn0AE4ww7fOuP86z45ovLcKyzWkecEL0RN0kYnwYguaGP78MJLetl8277O1j2Pffj+n96mPAAZG8BmHxobYPMdSYCdtVqb+qa5XAKcO40+49qBQYc2Z42uAk77qj919tUfqxh1wZXWosrz6cEKslxQbPhOLwZNFKz4I7D9broL2fp+e/OO1TW7H3mPBMNgi75ojgBqvpCkYG64XAQckkW/sYlmCzQ6Ty2KoBeccc53Z5eP/uiXrIWjFpjNRTaD+no0FM1/2DWo6cIRb3D1eh12l7P5jY5TH6yv27cGt9cBsQg1wtDWvIl2dk5obeq75nIVcB4AQ86gs+nCoLNmV7V8YcnY4ikzvr3ANuKMz1mLqi4k0E3q+7nVu6OoIn+cOv9NUyJ4+ACfBKG3t263d9a9XPvh2jecPSdxg4a1M4BmyBlqnvaD1s4ZcyTc0ct1wHlMetBhi7CNziYM+6qmrzrtwtHjJi/6rK1k/OfoiblpAJ1hz0XNzpoai6AANTafu/uwvafh5cajG//ZcmL7KZIJA8xwiz7SoK1ZY+c02DQO1eUL4OJ4grZH0E6HRmetDsAZetE3T5q6eHr5mPPmWQurzjcXls8i0K20VFcx4iWYeA9JFpoyA4CmJatYI0JQu7zOjr0uZ8v7HU073zlW82w1dR7aGPAC5nA+0llj8z2HnDNFaAxhXb4BzoMMUtlvo0Ojs1bXA69qdEqHby4sLLeOm7p4Vln5tAsshRXnFxSMOJseirbgAhXPjAZvmrDYgn7/jRRuPjV+EGLUxbzRBSKWqdJ7RnChGKBPftAt9AMeZ/v7XR2HdzTWPLvX6eyAycFQA2jeGHBOY23NGhuNcEMUzA/HRyo/RhM6ChF0aHbRVhe1O0POceybiovH28ZNW/SR4pJJ55oLiieZzLZJJottPFY2BoHHWnWAT1Wr0owkUn18JJYoHv9xUQiQNd/roJfnNPi89mNed++x3p5jexoPb9zV29uAu4qAlDUx+ww2fI6Dz0CL9nWkzlD23HZ6qef2aKL3HmNl84VBZ83OQEfyOR98lDWOnjB3dFnFOZOttjGTLIWlk81m20RaMlBpUEw2Ay2QoRPARg1SffQXF7F9vtpFaOEgxbSrhuhDAV57gBZ+BBSf3e9ztXq99uMeZ/dRl73pWFf7vqOn6jfBhmYoRe0rwhsuLOZlu5p9tTv5/Gc4Ac7HEWMWN4ZW9AE6Q83Q8z6fHKKvQq+r10DmjrmoZEKx1Ta6yGItK7aYy7AiUvF4u+weV1evy37K4eip7yWzAmBCi4obwwyfta7oI8xAM8TYF/NwWbHevNXWNPYQNxwBF4Uggo4wg8q+CL0IuAg350Ec18H1oi0xjH3RMXiI4zBrVwZcDyxDy1DzPudnn+tjX2x32IQhfOmCEmBZMJDwGXQxLMYBbqSxz5AjDg4+b7wPH9DBMXz6fUCKOEAs+gwv+0gTw9jHBsd+cG+Y/uUDMUyHH3XYLBsGNJIvQq3PgwbEesQGGUDRR1i/Mez6eHEf9WJfOp0EWPi6aLkbQQIsLwYZ2aLFiekRqhwAJkPK8KJMtLhIdcr4PgnwwZECSU4Cejnq91G7Po7BFVvWx+n3xbwyHIcE/h9VLWRYHWXC/QAAAABJRU5ErkJggg==',green:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAltklEQVR4Ae2dCXQcxZnHR3NoNDp8SD7kU7bxFXCchBhMYoLNmhCcOBBykGw2gYTkPV6AhGXD2sTZJQcJG3jsgw3hscuCsTEsOAQW1sbY+MAHxpYtHzI+5EOy5UMStnWPZkZzab9/j75WTWt6NKO5Z6r82lVdXV1d9e/ffPq6uro7zyBDIhXIi7DyngjLyWJRKhDpCYiy2pwoztrpxSwCb+d1bayFm9f1Yu3+cj2MAgOJH2bXnNnEGiHWppW8d999d/inPvWp6YWFheNMJlOR0WgswdLT06PElFdM+xbn5eWVQDXK76TI7vP57H6/v5PyOxFjobwuh8Nx4dixYye+9rWvtaK4ZqFVNY/TiGUIoQCfsBCbcjaLNVHgJRUQG3/4wx9ali1bNmXYsGEzrFbrdLPZjGUagTyNAB2ZCLXoh3CJoD/p9XqxnOju7j7R1tZ2/LHHHqtbtWqVh47pp0X8AaAZbPmRzvnAJzPXhRBhVoBeunSp7b777ruuuLj4xoKCghsI5s8TcPnpIBT9oNwE/D6Xy7Xdbrd/8Oyzz+5+/PHHndQ2LfA5D3suA85QGwmMPLLQ+b///e/nkIW+0WKxLKBlLuUXpAPQEbTB5fF4KmnZShb+g0ceeaSKLLyb9gPgIvQRVJVdRXIN8CCo77777oI//vGPt5CV/n5+fv5NdGrhK2dDsLvd7k1k3f/n17/+9frly5e7qFM5CXsuAM5QI4a1Nh4/fvza0aNH/4PNZvs2rZfRks2h2el0/u2TTz55dcaMGXuoo7DoolXPajcmmwFnsBWoKysrJ02fPv3v6QLxH2hUY1o2E63XNxqhOUkXqq+eOHHitblz557pBV2EXW/XjM3PRsBFsE21tbXXk7VeCheELhKzsb9Rw0cXqT1wYciqP37FFVd8SBX4aMlK0LPphKMvirWm2FRfX//lESNGLKXRj3m0LoOOAjQas/Py5cuPV1RUbKQiDDrDrrNX5mRnA+Aq2OPHjzfv3r3766WlpUvIDfl85pyG1LeU3Jd9LS0tT1x33XVrzp8/76UWAfKMBz2TAUfbFbgJbAuBfUdZWdkSuvFyZepxydwW0I2lo83NzQD9rwS69mZSxnUsUwFXXZHDhw/PmTJlytNksedknPpp3GCy6FV1dXX/OGvWrCpqpui6pHGr+zct0wBXLDZ1w/TSSy+V3n777b+j+R8/pYtHAC9DrwIO9xHD5c5XDF5fS0ya0MWo3+nwvrBx47nfLLlvKypj0DNmaDFTAEc7GW5zQ0PDD4YPH/4YuSMJmQMSExVpsPPxhjsMHt/FuLWkp8dwqb3dt2zhnD2vUKXsnwPytAc9EwBHG01YDh06NIuGtf5DjoyQGmHC4XMLwmwd/Caft2fnmXr3A3d8Zf9hqgXWHEtaQ57Of9pViz179mwrXeE/MnPmzF0S7sEDGuueJnPevCuusO76sPq6R2bPHm2l+sy0gKG0NZTp2jCG27R27drx8+fPf4lu1NwQ6wnKlf0TZcFF/bwe//Z9uxw/vvfuj89Tftr65ukIOI+QmE+ePPllGgJ8UfraIloDp5MBOFoB37zxQvdPvr5gP24SsW+OsfO0CenkoqhWe8GCBQWXLl36Hd1de1vCnTas9GtIXp5h5LgJ1re3H7z2dwsWjMTUYlwrpZXLki4WXIV73bp1E66//vqVNClK3mLvh1RkGcmy4GJr3B7/zkOVXXfd86PD5yg/bVyWdAAcbVBGSY4cOTKPbtqsJqs9QhRPpqNTIBWAo4U0l+1yw1nXd29duH8nrabFKEuqXRSG20yz/hZPnTp1rYQ7OpjTqTRNUhwxtsK69t3tcxZTuzDCAsOVUiOaSsBxbAhgoZl/d02YMOF1SttokSGDFSCabeVj819/v3LOXdQNCy04xynjLFUHVuGmu5K/HDNmzHN0ux2/eBmyQoEe84gRluc2V13zS+pOSiFPBeAK3PQQQj7NQ36CZgA+Kh9EyAqqgzpBQ4h5w4aZH6URlidwrmljSix5sgFX4F60aJGNXmzzYklJyf1BqsiVrFOgqNh0/5ubJr24aFEp3M+kQ57MCwAF7pEjR1rpBs4KeuD3W1l3NtOkQ6kaRQnXfZfL/+Y3bqz7Ed3f6KZyPIwYbpe4bEuWBVfgphbn19TUPCnhjsu5y6hKCgqM33pr4+QnwQAtSbPkyQCc4bY0NjYupXeQ3JNRZ0Y2Nm4KFBab7tlSdc1SqjBpF56JBhwuEI5hOXfu3N30rOS/xk0tWVFGKjB0mPlfN1bOuRtM0AI2EuomJxJwNBx/iix0QfkNupJ+mtIySAUMpSPyn16z5fPfICnYkicM8kQBznCbq6ur59Pt9+U0FAjYZZAK4J6+aczE/BffWn/1fJIjoXc8EwE44Ea95vXr18+gt0mtpjQmx8sgFVAVIEgKJkzJX/2fq66aQZmAHMzE3ZInCnATPRBcNG/evJU0t2SI2iuZkAoIChiNeUM+O6d45cLbxxVRNv7Cxx3weFeIHwwaar148eJTQ4cO/SmlZUiyAuk4Dh5Ogs5O3wsLPrfnQSoT9zHyeFpw/FhQn+Xo0aPflHCHO6Vym6hASYnpp29v+dw3wQ4tYChuhjdegDPc5jVr1kybPHnyM2IHZFoqMJAC48Zbn/nzi1dNo3Jx9cfjCbh54cKFRfS42Qrpdw90OuV2rQLwx6/9QvGKhQsVfxyQx8WKx6MS/EgUv5vmGTw5ZMgQeadSe/aSvJ5pPrgoj73D91/zr97zEOXFxR+P1YKrrsm+fftupNmBEm7xbMl01AoUlRjvWb1u9o20Y1xclVgBV6w3uSVFNN79JL3LLuoOyR2kAqICYKhisu3JBQvG8tBhTIzGsjNbb8vLL7/8C3oxz3SxoTItFRisAhaLcfqyP435Oe0f86jKYAFnuM2vvPLK5FGjRuHRJBmkAnFToLTM8tCfnpk5mSqMyVWJBXBcWFro6Zw/0Z+Vwrj1TFYkFSAFwNQX5w/5N0rGNCFrMICz9bZ8/PHH+MbkV+UZkQokQoGiQtPX/rb+M7f0Qg5WwV5UYTCAYx/zrbfeWkw3dJ6I6miysFQgSgXGV9ieWHjrqGLajV2VqGqIFnC23ua//OUv99PnriuiOposLBWIUgGLJa9iya8q8HA6Ax6VFY8WcJQ30Sewh9DrHn4WZVtlcanAoBQYXmr62fe+NwGzUnHdFxWz0RRm621ZtmzZT+hF9GWDaq3cSSoQpQImU17ZnfeO+gntFvWwYTSAo6wZN3XKy8vvjbKNsrhUICYFykZa7r1mwUjc/GFXJaL6IgWcrbf5+eef/wH53uUR1S4LSQXipIDZklf+m99N/AFVx4BH5ItHCjjKmehbObaxY8fiDpMMUoGkK0BW/OezZxdH9YasSABn621ZvXr1HWS9Jya9Z/KAUgFSID8/b+KjT02/g5IR++KRAK5Y73HjxuXT8oBUWiqQSgVGlVseoCnZfHdzQH4HKgDrjcX8xhtv/B1NqJqays7JY0sFLPl5U59bVbEQTNLCfOoKEwngGHs0013L78npsLo6yg1JUgAMjhlb8D0wSQvYBOS6YSDAsd30/e9/n54hHrpItxa5QSqQRAWKh5gWffWbY4bSIQF4WIbDbcQvA9vNS5cuvY2es8TVqwxSgZQrYDQabHffU34bNWTAIcNwgGObAjh9P+c70j1J+XmVDehVACyOLs//Dq0y4Loc621g59301FNPTSwsLPyiVFcqkE4K2ArzvvjPv52GIWv2w0P64uEAV6z34sWL76BfjF65dOqzbEsOKQAm5/9diWjFowZcGT2hx9G+nUO6ya5mkAL0WBsDzla8X+tDWWa+uDStWrVqBo19T+u3l8xIawUsplFp3b54NY7mik/703/MxNtpeTSlnxWHk64NKuCf/exn58uLS6086b8+3Pqg4WDNHw0O5yf9Gkuf9+sX6N3twXmaVWwMkUWv+Q7eLVShHk1mv310Kg9Vrt/h/PStQoN/PlVxhBYYa7AbVCwc4PQxzxHXS8ANhkZ7jaGq8W8Gh6ed9MuM4C2ebrD7Jhp6CIJsDr481/UGw4nnqY8MeFB3tYDjF6BY8KKiIjO9qeq6oNI5urL+1L8bOt2XM673PrPf4OjwZDXk/p6e68BqV1cXAx5kxUP54MgzrVixYpbJZCrNuLOagAZnItyQwWQ2GgppXlKeEec8OwON75V+/YErZlHv2A8P6qieBTddeeWVX5LuSZBWGbnCkDs7PQa/PyO7EL7RZI5HTCj+EhXaTwt7IKpfprXgintCBU3kf8+TgIfXNlO2AnJbicVAt7izLoBR2xDLPOoYW/CgP1eiBWf6TXRrPp/877lZp0YOd4ghhyUPNUKRydJYbaa5IyYU5l8+53BRP5hjxYprf9NYNz7zzDOfpl9GSSZ3Wra9vwIMORm9rArUn5Kbfzzt09QphV+xcyEt+Pjx42dK90SUKXvSDDksedYEwnrYyIKZ1J89tOhacN5gpLnfU7Om87Ij/RRgyLPJiFlsZjALC84cK/1GBgdswLqJZg9OzabOcwdl3KcAIC8oNuMtrn2ZGZpCHyxW0xXU/H4Xmgw49xLrRgJ8Sob2VTY7CgVUyLNgnLwXcIXfXgkUpvv54KWlpeaCgoKKKHSSRTNYAQXyIrPB1eXVzOLIrE5ZrcaK0lKbuaXFCbDZYCsuCfcEmcbf/va34ym2cqaMs18BhjyTZ/3TmKB17ncngV1Y8X6AM/XGq65SPsaZ/WdV9jBIAUBuLSSfnPFgIjIoHj2pCFO7xR6oFpy7YRw5cqS8wAw69bmz0gc5cMiwQE0uKrH0G0kRfXDFQbfZbBMyrGuyuXFUQIGc3p/Q7fSRT65O6YjjERJXVX6hCewqHPNRsILAFjyP3j2Iz0XIkMMKBCA3ZdwQosloBLsqyziFogXHBiNNkS3OhrFRdE6GwSsAyPPJkrvJkmeCHVeYNeUBcPbBlc7ziko9AY6XjMsgFVDmkysXnqAjAwIN54NdlWWkRQuOLuRJwCGDDKyA0ZRnsNrM5JOn/zi5yZzHgHPz1VEUZCjkS8BVbWSiVwGGXCEkjVUxGlXA1b85bMHVDAl4Gp/BFDaNIXe7vGk7uEL+iOheK0zzKAqkkxY8hQBlwqEBeX4BJmilZ2uNRuX6UeGYW8gWnNelD85KyDikAgy5uzv9xslNRvUiU217PwtOW7TQq4VlQioABRTIrTQzNc1MeU9eD9gNacHVPzper9dBH3mVj6tJlsMqwJB7yJKnyzg5vTXAITRaYZrHwdV8n8/Xpa7IhFQgjAKAnOZhp83gSo/foGVXGQfHD1D9EcKCh+mT3CQVCFKAIfe6yZKrFAUVSdqK39cjsqtwLfrgaEiPtOBJOx9ZcyBAbs7H3JUUd8mnWPCgn5l4QalskICn+CRl6OEVyMld8brp9VkpMuU9fj+7KCrkIS14v9fpZqjostnJVYDuJJIlJ6RSYMrBrK9HAVyFG71nC45MZZE+eHKhyLajMeQ+jz/phtzvy4MPrrIMbUULzoDbs0102Z/kKgDITRZj0g253+8Huwy40mm24KoCTqezBeZezglXJZGJQSgAyA0EOSx5MgLcfp+7p0V7LLbgTL2/tbX1tLaQXJcKDEYBtuSD2Xcw+zg6u8EuflHMs+KiYAVByTx58mSdvMgMCCL/j12BpEFO9Laed9Yxx70t72ELjnUF8DfffFMC3quOjOKjAEOeyMEVfOyqevtFLeD9RlH8GzZs6Ozu7r5E81FGxqd7shapAI1mwCen5zz93sT45H5Pz6UTey52ktb9XBTor1jv3o1+u91+RropkEWGeCoAyI0EebyHV8Bqt8t7htoKuEMCjn4AcqWAw+E4jQwZpALxVkCBnG7tK5DDZ4nT4nb5wawIuNJ09sFFC+7DSIq04PE+tbI+VoAhj5dPjiHCbrsXgNNTGMEWXBwHVyFvamqq48bIWCqQCAUAeQ8ZcJoBGHP1+KF0NHvALCw4c6zUG8qC+995551DNOkq9iPH3HRZQTYrgJuJmKQVa6CvOffUfNhwiOoRXRSFXwYcx0AGCvjoI7CX2tvba6WbAllkSKQCsUKuXGB2eWsr37twidopuihKs7WAM+Te5ubmSgl4Ik+trJsVYMgHMz0E/ndXm6eS6qI3E+m7KHwsxYLTiq+2tna3BJxlkXGiFQDceDe5EiMd6UIPzLU0OneD2d4FDKtBz4L7li9fXkmzs4IKq3vJhFQgAQow5NFUTYT696w5DwsuuieK/416QgGu/BLWrFnTSn54jbTi0cgty8aqgAo5rj0HWHB7vtvhqTnyUVMrlWYLDrhDAo62YQOsNvwZLw0X7pGAkxIyJFWBgHsy8CHhf9tb3Pj4q8IrxWBXhRs1iBYc6ww4fg1e8sN3ScAhiwzJVoAhJ1dc/2YnNaq5oWsXRQBcdFHU5oo3epAJwBly79NPP73npptuchUVFRWoe+RgwnXRZmh3YBQqu4OuMQuyiX0a6GQHCuhs1D1GX7VBKVhp7APgtfvSS4dcm1bUsQVn6x105FCAo6Diz3z00UedjY2NW6dMmXKL0ag19kHtiHil9nyj4b2dVYaOLvEVFhHvnpKCXs9XDUa3m44dpF1QW7TiB23UWdHdR+cw8DlDBlCgE/S30A5h9tOpLubsaG/r6JWnJ+gNrtbmrRdO7sYMQva/GXK1nVrAsQGaoCDMvufgwYP/N2nSpLgB/sJb6w0tHWhTZgV3t4teidBNjYbkkEhPem2/uCyjpt1fu127f7LLa4+vbZ+2Pdry2vWB9tdu1+6vPV6gvN/vMzTUHv8/Ku2hBaz2gxs1hTLLqIEB995///07aPpss661QS1RhEyEG93LtxbQKxH4+7gQPdLAZRGLad5fzOMyYoxyXEZMi2XEtFhGTItlxLRYBmltQFkE3ofTSmYE/w20v3Y7H4dj7fECrorP42mu2rZhB23VvcDEnuEAh9n30MxC5/nz59+LF+A4aKaGAOT5wbxpO6M9X9jOedqyqVjntujxo21Tostrjxfheldnx3tuu91JxWHBQ15goqpQgCMfFpytuGfTpk3v0PtSkJ/zAZBbLL2QMyRiDIUYCjEtlkllWmyTmNZrk1hGTMervF49YfL99JbNpvrat6k5onsCXvsFPcDhpuBXofjhS5cuPdzW1nZKWvGAfhaGvJ+cMiPRCoBBj8t16tCOTUfoWAw4WAWz/UKoi0wUQmGGHJW4aUx8TVlZ2YP0DR9sz/kAyBG8HsgjQ7IUAOD2jvY1dDwMa0F8hjsk4HoWHO2FyVet+MqVK9+hh5Hl2YQyvQGQm/PJXQkXcKcCge9YcFrJDPFftOVDVJFWWdH2Z4Dy9PpjT92R/e9QH8EiPAwwGtI9oXxdHxzb8ItgP9z90ksvNZ45c+ZdOf8K0vQFC42sKJAzwNoYRfmkiWltOV4Xy4hp3p5psdgHMa3XD7GMmKbyALKrs/3dMx8faKQkLDgAB6MhrTflRww4fi3uV1999QWy4rq/FlSYi0GB3GLJxa4ntc9+r9d/5tjHL9BB2T2JCXA0PsiKP/nkk7Vnz559X1rx/ueVIQ9z8a+OJMsygYGmaHTAXVdnZ+f7x/bsqO0FfEC4cZbC+eDYDmutuimU7v7rX//63x6PR/dPAnbK1QDITcoQYq/fDSHwp5hjMR3I7b9d70+3Xj7XPdj6Yt1f266B6htou7a+3nW6c9lTf/Lwf9PuuJ0suidhPYqBAEdzUAEcecVN+cMf/nCMrPg2acUhTf9goYtOk5ncFT5RKII0B07rbedykcax1hfr/tp2DlTfQNu19dE6Rk4c9o5th3d+cIxW2T0Je3HJ1UQCOKy1Cjilu9etW/c8WXGuQ8YaBVTINflydXAK+H007+TUyedpb7begA9MDuhJRAo4W3H8erqXLFlS3dDQsEtacVJDJ0jIdYSJMhvW29nVuevAtvXVtCsDztY7LoCjSWzF4dgDctfatWufkSMqkEY/AHIzja5gLjMHTgcm9AfyOQ9lOM3bo43FOsS0Xj1iGaQHCtG2D/XxPmKa2yPmiWne3uP3+Zvqjj9D21y0gD0wGJH1pnIDXmSiDAIAD7rYfOihhw7Su8TflnNUFH10/zPTRafJbFZOMp9ojrETp/mEinm6lYbZEG192vLcDr042vZp69fuH247psR2tDS/XbVl/UHaj613RKMnLFEkLgqXZSuuXGzigA8//PDT9GByK/6MyKCvAEOuX0Ju0SoAprzd3a3VO9Y/TdsY7oh9b64vWsDZF8cBXZs3b75UWVn5Z3nByXLqxwHI5c0gfYWCt8B6Nzde+HPj6dN4VhDuCZiL2Pfm2qIBHPuIVlyB/Pbbb3+THmurlhecLKl+DH9cHULkYuyfI45kwX68j5jmfcU8Mc3b4x2LxxDTescRy4hpoTwezXN1dVVvfeuVN6kIwx219Ub1gwGcrbhysYkGrFq16jGXy+WTrgokDR8UyE00iZNPKIojHWngsnr7D7Q90uNEWi7a4w1QHgz5vF5f3ZEDj1ETADdfXEZtvdGFaAHHPgw4flGKFX/00UePHDt2bDW9kRbbZRhAAYYcWMslWAMDPcxgb768mm7qYL631nqDvajCYADHARhytuLOBx544NnLly83SlclMv0BuZFGV2ToU6CH4HY7nI37Nr/3LOXicTSt9e4rHGFqsICzL66Oi+/du7f5tddee5g+f+KRrkpk6pvplr4CObsbORwDKBpy9pyuqX74YkN9M60y3FGNe2uVHyzgqIchV604DRvuI9CfpRtA2uPIdR0FFMjlU1L0pQcvjZo0PHvggw37SCqt9QZrgwqxAg5XRbXilHbdcsstK+vr63fIG0CRnw+GPFf9cbpbaejqaNuxZfXylWCod+G7lmAsJYDjDOLgWPiCE788x4MPPvgb8sc/kf44qRFhCECeez45/O5up/OTqo3v/oakwuvOwBBcADDFfFFycCEWC85HRCMwfIJfHBrnpBtATa+//vqvyB/3Sn+cFIkw4Ja+URxCzHKfHGaZ/tJ76SmdX9FrIJpoVeGHYrDEw4KUHHyIB+BoJxrDrorSSHrVRNWePXuegz8uIY/8BCmQG7P/zQVgAn735aYLz+3fsq6KFBLhjunCUlQ7HoCjPoY8yFVZtGjRcpqQtdGtvLhSPKxMh1MgYMkBefZ65TRJ0NDZ1rpxy2vLl1NHta4JDCaYijnEC3A0hCHnURU02rF48eJ/oYvOvRLy6M6ViVwVoymepye64yeytI8sd1dH+94tb6z4FzDSu/CwYNzgRh/iqSAAF/1xNNhBX4nouPPOOx+iByRq5KQsSB55YMizyRXHiEm3vbNm99o3HnJ2dHSQGgBchBsMxcV6Q+lEOHtonNjAPILcW1dXt3P+/PkLPth/eGgePqclQ0QK4L3synvBs2BKMmYIuhz2c/s2rf1ZY33tJyRAFy0MONzbuFpvCJwIwFEvQhDo5It3d3Z27naYCm6mGXWFPNE9UFT+H04B/vhAgPHM9Mv9fvpglNPZfGjnpntOHzl0lvqrhTuulpv1TBTgogVX0wcOHOiix7j2Dx899is0HJYvIefTMHCc1/uFjUwckcL9EHphpv34gY/uq9nzUU0IuGG5AXjcQ6IAR0MZbI6VxjfV17UVlQw5OqR0xEKah2GRkEd+TlXIIW2GGHK86tjtcjnqjx74pwNb38dteNFyx228W0/FRAIuHhOQq6BfqD1+0WIp2Dds1KgFNCRmkz65KFX4tAp5Bvjk8LndDkfriQN7fn5g6waMdTPcGPNOONxQMtmAq6DTnasWn8e1s7R8wvVkyEv4xKFRMoRXQDUIiiGnz16n4b8eGud2d9kbqnd+cC+9bu0o9chOCwBnuHEzJyF+N9WrhmQBjgOyBVchv9xwobOro3XbqPGTrjVZLGV8MaW2TiZ0FQhATlKyqrolk78B49z0HsGT+zatua/uyMHT1AKAnXS40fNkAo7jITDgStx++aKz+cLZD8onTZ1NryEeA59c+uUBoQb6X4UcBdPAJ8dwJt5CRTMDD+xY88YvGs+caqCWad2SpFhu1i7ZgAfBTY1Q1umdz+7zp45uHXfFjCn0AstJeUYJOZ+ggWLVXUmxKcesQHqWkm6/t2zd+saKJW0Xmy5T2xlu3MjBDMGkwg3tkg04jonQD3S60vbVVh/cPmbyFGu+rXA2+eRkyGGWZBhIAdYpYMST75H30Bg3fcqlp62p4eWNry7/N3rVWju1WYQbF5RJhxu6pQpwHJsh5wsN+nit13+quupA4ZChNSVDh881mkw0wiKtOcQaKEAnCJrMoMwIpJESj6Orlaa8Ltv2v6++QeeQLybFO5QpgRtapBJwHJ8hR6yCfuFUzQX6U7d5RPn4K8kvL5cuC6QaOKiQJ8EfJ2/bgItJR3vbwb1b1v3iaOX2Q9RCWG223HBJxKHAZP/+FMHSBXDAzYsCPV18dp06eGBjecVkk7Ww6DPSZVHO14D/sbsyYMEYCuDOpNfj7mlpOL9yw6oXf996sQFvn4LFZri1k6diOFpsu6YacLSef9lsxVXQ6c+d79ShqoN05/NI0TByWYxwWWjAQPrmYc96nz7xNeWBhxRofNvpbDl7rPpX2/73f97qdUkYboxx88Vkwm6/h+28ZmM6AI4miZCLoCvp86eON9ibWzYPHVk+mlyWKXBZMC7WdyI1vZKrvdqwrLEJArAxSoJvgna0XNpctXntkqOVHx6mWtliA3DtDRwYqpQHkJJOAe3BXFr88PCmSist+OKqjZZCpK+55bYvVEy78pcFRcUT8eRL3zAZbZWhnwIAM5bAw3/dXfaz9SeO/vve99fsovrggjDUPATI011xwPj8smJpeO++6QY4mhUwzwHI8Zg5vrQKyBl0W0FJSfENt/39D0pHj73LYrVayXWR1pwE0guBGYjRMaeOkNBDtc1NDSs/XLP6FVdnJ0ZIYKmxAGz2tTFKwnO5ozsQ7ZjIkC4uiraPLBJiLLAK7NP5vG63t/bQvkMOR8emoWWjx9Fr0CZKt0UrYd96nyvHtkM/xhwudkfsra0fHtz6/j/v2/zuB6S5OPwH6y3CjfMT25+KvubGNZWOFlzsINrHLgtbc7bocFsUyz7vq9+6oXzK9PsKCgsraE6L4rb0nVSxutxOByx5aA3Yz/aRn+1yOOobT598dte6N7dTabbUbLUx9Mc3btjosEEKXXkKc9MdcJYGkDPo8M0BOfvnCuRms7lg7uJv31Q+ruJOa1HxVLzcEv65BJ0lDB0z2LiAJD/7VNOF+pcr1/5tE72uhMHmmMe1RV87La222NNMARxtZmsO0GHNGXQAzrAjtn5x0Te/VD556p0FxSVX4Y1RmIorQSdlhKCAjfFsL1lse+eRptOnXv7ovbd2UBGAjAVgcwyLDbD5jiTATlurTW1TQyYBzo1Gm3HtwKDDmrNFVwCndSW+5uavXzNu8oy7CocMuRpfVgi8hiF3hxcDLgpm/GFilMfg6OjYf+H08ZU0MrKXNGOwxVh0RwA1X0hSMjNCJgIOZdFuLKLbAovOQ4si6PlXz7959tipM28rKhm2wGzNL8TrGHLlopShxoQo3Fr3drsdXZ1tWxtO1byzf9v7uL0OiEWokYa15kX0szPCalPb1ZCpgHMHGHIGnV0XBp0tu2Lli4eNKPrc/C8vKC0v/0phybA5NI5uogldivuSbePpGAkB3JifjU+CODrbqlqamjYc2LZxq73tMm7QsHUG0Aw5Q83DfrDaGeOOMBRinOmAc1+0oPONInZfxFix9BOmXjVq+py5Nw8rG/kVmp47lV+XFvDVM8+NUS11H9R0S91xqq350oYTVZXvnzt15CKJxQAz3GKMbbDWbLEzGmwRDE5nQ8ygIwbksOhs1QE54NbG5qu+cMO0cZOmXW8bMvTqgsLiWQS7FW95hc+ersAHA+1XXmRJlrqbXqxz2NnRvv/CmZMfHtm1/ST1F9YY8ALmUDG2s8WGC5IVYFM/lJAtFpz7wzH6xbADdF4AuBZ4xaJTvrKtoLjYOuvaL80qGzPx8wVDSq622Yo/ZTSbLLhbqjwzqsxPp9JKCMiXqBGaAMQ4UMD1xU0Y8jsMmM2HJ9ZpLprH6bQfc3V07m9uPLvv8J4dh112O1wOhhpA88KA8za21myxldqpfFaFbAWcT5IIOvx00VcXrTtDznkcm4aWlRXOuGbeZ4aXjfm0xVYwMT/fOtFsLRhnwsMYyvCjUQG/76KVD62NtVIHoNWWUiAmoHFRCJAVX5pi+oKdk+zzBbe7+6zH6Trb2tz48fG9O6vbm5txVxGQsiXmmMFGzHmIGWjRvw7dGCqc6UGreqb3J1z70VcAzjFbddGVYbC1sVhW+aFUzPzMqNETJ1YUDyubaLUVVeRbrRNMFnOZyWguzAvAj9fToZ6AmwPLjxUKCk1EMltoir30OJOjhyD2+b0On8fb7O7uPtft7Kq3tzWf/eTs2fr6mmr40AylaH1FeEOlxbLsfnCstCeb/2PNs7mP2r6hz+ICeNmycwwwGWqGnde5jBgjjUWsN4/cHfPQ0lFF9PidzVpUWFRgK8KMSIPL2eXo7qLRuvZWZ3vLxS5yKwAmuwgcM8yI2eqKMdIMNEOMdbEM78t1ckzFciPkIuDimQ0CkjYwqByL8IuAY7u4jcujPqS5XkoGpbEuBhE4TrN1ZcC1wDK0DDWvc3mOuT6OxePmTDrXARdPNGvBcCLWgsvrDDEgRzmOOT9UXTgW5wM6BIZPuw5IkQeIxZjh5RjbxDTWsSBwHFjL0f9Z8BztfthuszaIwy0i1NpyOIBYj3hABlCMkdYuDLs2X1xHvViXQaMAi6/Jlqs6CrBeDDKKhcsTt+tUGQQmQ8rwYp9weXp1yvxeBfjkSEFiU0Cro3YdtWvzGFzxyNo87bpYVqYjUOD/AZrbm7Ts1rpFAAAAAElFTkSuQmCC',red:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALgAAAC4CAYAAABQMybHAAAk/0lEQVR4Ae2dCZxUxZ3Hq8/pnhkGmOEQuQS5VCTxWHEDBlyNkciakMMkxujGuOvHO24IKCae0UQlKwmyroocoqtozGpA4oFiVAQU5IaRcchwDsPczNF39/5/b+bfVL/p7ume6bur+DyqXt31r2//5//q1XvPIJRLpgQMMVYeiDGfyhanBGKdgDirzYvsLLtIPguB0/lc7+vh5vNIvr68Oo8ige6EH6Vo3iSxjODrw1rcm2++2f+MM84YV1hYONRkMhUZjcY+OAKBgOZTXDGVLTYYDH0gNYpvIa/V5/O1+v3+FopvgY+D4tra29uP7N27d98VV1zRiOy6g06DcRyGr1wYCfCEhUnK2yiWiQYvSQG+8ac//all3rx5o/v16ze+oKBgnNlsxjGWQB5LgA5MhrToh1BL0Fd4vV4c+1wu176mpqYvHnnkkf0rVqzwUJt+OuQfALrBmh/hvHc8mfkuCBlmDei5c+fab7nllguLi4svttlsXyeYzyPgrJkgKPpBuQn4LU6n88PW1tZ1ixYt2vjoo486qG964PMe9nwGnKE2EhgG0tDWBx988HzS0BdbLJbpdEymeFsmAB1DH5wej2cTHR+Qhl937733biYN76ZyAFyGPoaqcitLvgEeAvX1119ve/jhhy8nLX211Wq9lKYWtnIuuFa3272WtPv/3nPPPW8tWbLESYPKS9jzAXCGGj60tfGLL764YPDgwT+x2+3fp/MyOnLZ1Tscjj/X1NS8OH78+E9poNDoslbPaTMmlwFnsDWoN23adNq4ceN+TBeIP6FVjbG5THSksdEKTQVdqL64b9++lyZPnlzVCboMe6SiWRufi4DLYJsqKyunkraeCxOELhJzcbxxw0cXqQGYMKTVHz399NM/pgp8dOQk6Lk04RiLpq3JNx04cOAbAwYMmEurH1PoXLkIEqDVmPV1dXWPjhw58l3KwqAz7BFKZU90LgAeBHvYsGHmjRs3/mtpaekcMkPOy55pSH9PyXzZ0tDQ8NiFF1646vDhw17qESDPetCzGXD0XYObwLYQ2FeVlZXNoRsvZ6Yfl+ztAd1Y2lNfXw/QXyHQ9TeTsm5g2Qp40BTZtWvX+aNHj15AGvv8rJN+BneYNPrm/fv3/2LixImbqZuy6ZLBve7atWwDXNPYNAzT0qVLS2fNmvUA7f+4gS4eAbxynRIwHN8ozDseFQZHTW9l4m/3BBa/8nnDfT97vKqBKmPQs2ZpMVsARz8ZbvPRo0ev6d+//yNkjiRlD0hvqUh3ecsrpwtD2+GEdcMfELUNbWLewNniBaqU7XNAnvGgZwPg6KMJx44dOybSstYf1coISSOKsy4tiJLa8ySPX6wvrxN3TLpX7KJaoM1xZDTkmfynPaixJ02aVEBX+PdOmDBhg4K754D2tqTFKKacPVhsOPEnce+kSQK/IjMdYChjFWWmdozhNq1evXrYtGnTltKNmq/3doLypXyyNLgsP49XfPhOpfjZzCcEbKGMtc0zEXBeITFXVFR8g5YAn1O2toxW9+FUAI5ewDY/UC9+PvrXAjeJ2DbH2nnGuEwyUYJae/r06bba2toH6O7a6wrujGGlS0eMBjFw1ADxetMT4oHpZ2lbi3GtlFEmS6Zo8CDca9asGT516tTltClK3WLvglRsEanS4HJvXF6x/v0vxHXfWigOUXzGmCyZADj6oK2S7N69ewrdtFlJWnuALDwVjk8C6QAcPSSTpa6iTvxwwm/EejrNiFWWdJsoDLeZdv3NHDNmzGoFd3wwZ1JuMlkGjBsoVlf9TsykfmGFBYorrUo0nYCjbQjAQjv/rhs+fPjLFLbToVwWS4Boto/sL14++ri4joZhoQNznDbO0tVwEG66K/nLIUOGPEW32/GLVy43JGAeUiKeqvsv8UsaTlohTwfgGtz0EIKV9iE/RjsAH1IPIuQG1SGjCAhDWaF4qHmBeGzwYIG3EaRFk6cacA3uGTNm2OnFNs/16dPn1hChqJOck0CJTdxaeY94bsZkzfxMOeSpvADQ4B44cGAB3cBZRg/8fi/nZjNDBpSuVZRow3d4xGsjHxT/VlsrXJSPlxGjFUlIWqo0uAY39dhaXl4+X8GdkLnLqkrsFvE90uTzwQAdKdPkqQCc4bZUV1fPpXeQ3JhVM6M6mzAJ9LGJG+v/IOZShSm78Ew24DCB0Ibl0KFD19Ozkr9JmLRURVkpgdIi8Zvqx8X1YIIOsJFUMzmZgKPj+FNkoQvK79CqyQIKK6ckIE4pEQsqHxbfIVGwJk8a5MkCnOE2b9++fRrdfl9CS4GAXTklATwiYRpVJp7bfb+YRuJI6h3PZAAOuFGv+a233hpPb5NaSeHkPGJCFSuXnRIgSGwTBomVb/2nGE8jAORgJuGaPFmAm+iB4KIpU6Ysp70lJdk5BarXyZaA0ShKLh4tls+6QBRRW/gLn3DAE10hfjDoaMHx48ef6Nu37w0UVi7FEsjEdfBoImh2iMX97hR3Up6Er5EnUoPjx4L6LHv27PmugjvalKo0WQJ97eKGLx8U3wU7dIChhCneRAHOcJtXrVo1dtSoUQvlAaiwkkB3EqAngxauuk2MpXwJtccTCbj5kksuKaLHzZYpu7u76VTpegnAHr9svFh2yQTNHgfkCdHiiagEPxLN7qbnKOeXlJSoO5X62UvxebbZ4LJ4yB5/muzx2RSXEHu8txo8aJps2bLlYtodqOCWZ0uF45YA7T68cfu94mIqmBBTpbeAa9qbzJIiWu+eTy9Wj3tAqoCSgCwBIETr4/OnjwsuHfaK0d4UZu1tef7552+nF/OMkzuqwkoCPZWA1SzGvXS9uI3K93pVpaeAM9zmF154YdSgQYPwaJJySgIJk8DgvmL2C/8hRlGFvTJVegM4Liwt9HTO78k0KUzYyFRFSgIkATJVCq88S/yOgr3akNUTwFl7W3bu3IlvTH5LzYiSQDIk0KdAXEEbsi7vhBysgr24XE8ARxnzlVdeWUw3dB6LqzWVWUkgTgmMHSgeu3Ky9oFeNlXiqiFewFl7m5988slb6XPXI+NqTWVWEohTAhaTGPnMLIGH0xnwuLR4vIAjv4k+gV1Cr3u4Kc6+quxKAj2SwIA+4qbrpwjsSsV1X1zMxpOZtbdl3rx5P6cX0Zf1qLeqkJJAnBIwmUTZ/TPFz6lY3MuG8QCOvGbc1DnllFNujrOPKruSQK8kQG/Kuple0Yx942yqxFRfrICz9jY/88wz15DtfUpMtatMSgIJkoDZJE5Z9mNxDVXHgMdki8cKOPKZ6Fs59lNPPRV3mJRTEki5BIb0FbdNOj2+N2TFAjhrb8vKlSuvIu09IuUjUw0qCZAErBYx4i/XiasoGLMtHgvgmvYeOnSolY47lKSVBNIpgWH9xR0lJcG7m93y210GaG8c5ldfffVfaEPVmHQOTrWtJEAbsca8f7O4BEzSwXxGFEwsgGPt0Ux3LX+ktsNGlKNKSJEEsJ121CDxIzBJB9gE5BFdd4Aj3XT11VfTM8R9Z0SsRSUoCaRQAn0LxIyrvyb6UpMAPCrD0RLxy0C6ee7cud+m5yzV50VIGMqlXwL0/Kb9nsvEt6kn3S4ZRgMcaRrg9P2cHyjzJP0Tq3rQIQGYKSP6iR/QGQMekeNICdDeOExPPPHEiMLCwq91VK3+VxLIDAkUWcXXnrhaYMma7XDw2sVFA1zT3jNnzryKtHekfF0qVBFKAqmQABFpnDUxRIvHDbi2ekKPo30/FR1WbSgJxCuBwcVBwFmLd6kinGbGLwHxphUrVoynte+xXUqpiIyWQKBoWEb3L1GdozXxsS/9u/Z2Wl5N6aLFYaTrXRDwr371q9PUxaVePJl/3nzef4uaN28S7hNHunQ2EOgSRa/r1rkuEXild1enr6unecJVHktd9OlwaOJp1LPddEApg92QotEANw8YMGCqApwktmen8K9cIURTI8kv810BdXGI72JR73LR9+ND5jvzOx9nD80u11QhVj1DxRjwkBr0gOMXoGnwoqIiM72p6sKQ3Hl64nv0fhGoPZ5Vo8ff7P5+v2jw+Eil5S7kfQKBC8FqW1sbAx6ixRGpd4gzLVu2bKLJZCrVJ+bjebbBzXNkoTsipfRQo0HTWRybWz7BWvqHkYMn0qjYDg8ZoB5w1uCmM8888yJlnoTIKitPGHIj3R3hyc0lHwCPLbRdRB4A56EF5yoc4Igzkf09RQEelFNWBwB5f3okJhfnE2MqNZumgFk6wC4gDzoZcKbfRLfmrWR/Tw7mUoGsl0Ao5DzVueEXmUyThxcW8heUeVDanMmAIwLnxoULF55Nv4w+Wg71X85IgCE3AoEccjScPr8ZderZNCSNX3lo8ioKk28aNmzYhFz8cyYPPF/DHZAbRKPXmzNrK6B6qM0ygbxP6WCOtaUjWYNzgpH2fo/JVwDyYdxmUuH9zWZN3eXKePuYjGAWPDPH2tD0GhwZTLR7cIzS4Jp8cvY/QN6PIG/KAU0OVouMxtPBLh0MuTZ3rMFBPRzOjQT4aO1M/ZfTEmDIc8Emt5s0wDV+OydNY5oBR5ym2ktLS802m21kTs+sGlxQAoC8r4nMFZp9DQAGIct8m9EwstRuh0XCw9DGqAfceP/992MrGrYzKJcnEjgJOdjIUhcQBbcPHQx2wXRwIGyDM/XGs846S22PzdI57k23AXkJmbAnfNm5dwUAn1mkbe3+ohNwRAVYgwcBHzhwoLrA7A0pWVxWg5xe5Wo8qQCzZjQAuNRs7rKSwhocAwHsRrvdPhwnyuWnBAB5H9LkLZomzy4ZFJmNYFfjmHuu1+AGevdgMScqPz8loEGuafLsGr/ZYAC7bI3A1x6751EgwkhbZIvVGjiLJH99QF5Mmrw1SzQ5mKVFcAAOpa3BjdnjkyD1BDheMq6ckoDQNDntQsQSYjY4ghzsBllGWLbBMQaDAhxiUI4lYCLNWEzmiqbJM/zBIKvByIBz9zUNzica+QpwFofyWQIMObGe0c4kAgx4sKeswYMRCvCMnsO0dY4hb/P5M/YZT7NJ0+AsI41pXkVBJCKUicLiUX4XCQDyIhNWyYP6sEuedEZE0+DcLwU4S0L5YSXAkLdrmjxslrRFGmOxwal3bLakraOq4cyWACAv1DR5ZvWTVlHArmaJcM/YRAn+zfF6ve2cqHwlgUgSYMi7rDNTASYs1b7PH5DZ1Zjm/gXH4fP52oInKqAkEEUCgJz2YWeMRU6Xv3p2NZWO1c3gCqfS4FFmVCV1kQBD7qS3aKX7LXE+v1/W4BrXbKJwxwNKg7MolB+rBAC5jd69Ql5anS8goMGDyhqdkS8otQQFeFrnKGsb1zQ5Qa5p8jSNwm8ImihByMNq8EC6/9akSUCq2d5JAK+H0zR576rpUWkwSyuXETW4Zq9QzQFlg/dIvqpQpwQYche9vDvVb7X1BgRs8CDL6JKswbUEAry1s6/KUxLokQQAeQFtQUz1HU96FzrYZcC1vss2uBbhcDgaoO7VnvAeza0q1CmBDsiFcPlTIxJQ7aTXoetbYw3O1PsbGxv/oc+kzpUEeiKBk5q8J6XjL9Pk9YBd/KSYZ81EwQmcFllRUbFfXWR2CET933sJAHKrZq4k9w4nelrldOwnLwg3wqzBka4lvPbaawpwSEO5hEkgCHkS18kB72v1zXrAg+vgTL3/7bffbnG5XLVms3lgwkaoKsp7CQByC0nBo+nRxIvD7ffXrjve1EI1dzFR0FoQcGRobW2tUmYKxKJcIiWgQU6gJ1qRg9U2X6CK+gq4wwKOcQByLUN7e/s/EKGckkCiJQDI6fUOCd9x2O7zgVkZcK3rbIPLGtyHlRSlwRM9tao+loAMOcf1xge8TT4vAPfREaLB5XXwIOTHjh3b35sGVVklge4kAMhhqngTsC0E9dR6fGA2BG70IZwG97/xxhs7aNMVgFdOSSBpEsDNxA5zpXdWuY/MjVW1zTuoowA8BHIGHIMA0Ej00Udga5ubmyuVmQKxKJdMCQByE/ENfd6Tf6C2xR+ofPFITS31UzZRtG7rAWfIvfX19ZsU4MmcWlU3SyAIeQ8UOYCt93g3keelI0R7o34ZcJxrGpx8X2Vl5UYFOESiXCokAMgBI3lxHTDkqxyujVQU2ps1eLDLMuD4MbAG9y1ZsmSTn1wwpwooCSRZAgx5PM3Qg3L+JTX10OAMN3OsVRMOcO2XsGrVqkayw8uVFo9H3CpvbyXAkMNa6e7AQ6DNXl/5W8fqGyk7a/CIgKNvrMFhz3hpufBTBTjEolwqJQDIAXd3DrDWuj34+KvGK/lsgweLyhockQw4fg1essM3KMCDslKBFEqAIY+mxdGdynbPBvIAuGyiIElz8o0eRLB6xy/Bu2DBgk8vvfRSZ1FRkU3Lnaf/VRaVCM/xmpwffSRlBijCuUjxyBsxLUJCpMfbkB39AvD6/jn8fufjh46wBmftHdJCOMCRUbNnPvnkk5bq6uoPRo8efbmRnphOhGvbWiGO/c9fhaeuORHVpaQOt+8rwlmCb7uHyC6k7UgpUctEKBStTEijnSf6iZfzRGhCyxJvO3K96Q7T42mi2nnig21N5dhByPY3Qx7snh5wJEAmmgYn37Nt27a/nnbaaQkDfP+dTwp3dT3aySrn9HtEu9+r2YYQUCw2IgbIeRk0lOO4cOmIk12q88ttI8x9jdR/fX79eXfl9en68pHG7w34xW5nzV8pv4cOeQ08pIpwahltMuDeW2+99SPaPlsfTUuE1NjNSTbCjSEVGS2i0NihD2KFG+U4L3w5jDQ4OY7zyL6cRw7LeeSwnEcOy3nksJwHYb1DXjguw2EtMob/uiuvT+d22Ne3h3iw6Az46he37PyITiNeYKJsNMCh9j20s9Bx+PDhvyUKcDSarQ6Q2wnyaNf4nMa3nTFWjsuEcXNfYu1fsvP3RCbQwLU+598a3W4HBaHBw15gou5wgCMeGpy1uGft2rVv0OskEJ/3DpDbjCYNWoZE9iEghkIOy3nSGZb7JIcj9UnOI4cTlT9SPdHiAeZ2Z93r5MnmCaK7uEiA40eCXwWo9sydO3dXU1PTl0qLd8iPIe84U/+nUgJgsC3g+XJJ8+7d1C4DDlbBbBcX7iITmZCZIUclbloTX1VWVnYnfcMH6XnvADmcKwDZKpcqCUBN13jbVpHnpoPNE+a1SzciaXBkRF1BLb58+fI36GFkVKhcpwQ0Td7lS4xKPMmUgFv4PG+3HXmD2pC1d1jzBP2IBjh+FSgIM8W9dOnS6qqqqjfV/iuShuSwsmJTkEsSSV4Qa9+1Pseb77ZWVVMr0OBgE4yC1bAuVsA1M+XFF19cTFo84q8lbAt5EKkgT80kuwMB/7q2I4upNTZPegU4eh2ixefPn1958ODBd5QW7zqhDHm0q3+V1nMJkPIW9f72d149UVHZCXi3cGOWomlwpENbB80UCrteeeWVZz0eT8Q/CSiUr64DciwhnnQcjnbjArk5PV6fy3KL+va6q6+35fX1d1dfd+n6+vjcL/yBjx3Vz1J5Fx2yeRLVougOcPQHFeBiUzNTfvvb3+4lLf53pcUhmq4ON4IKDB2QY3Lg2JfDPHFyHMLxOq67p/X1try+v93V1126vj6cd9jezr+vaCrfS6dsnoDJqHCjbCyAQ1sHAaewa82aNc+QFkd55cJIQA85w5cKH91hiORwKtpOVhs+4nij89gzNB7W3oAPTHZrScQKOGtx/Hpcc+bM2X706NENSouTNCI4QG4lTZ5qx3AzbGif41Ldl0S0B+1d73dtWNy4ezvVx4Cz9k4I4Ogna3EY9oDcuXr16oVqRQWiiexOavKTiOEyC44vtzisRXbGcxznicfnsrHWp8/P5SL5+v531zd9/fry3aV7aOVkk+P4QsrnpAPsgcGYtDfli8lEQT4ADi3OgLtmz569jd4l/rraowLxRHY2TZPjY6kd/5CTJ1kOR0qPXHP4FK471vr0+blcJF/uc/gehMbq69eXj5buoy2xR31trz/duGMblWPtHdPqCfciFhOF87IW1y420eBdd921gB5MblR7VFhE4X2GPHyqig0ngY49J97GxU27FlA6wx2z7c11xgs42+Jo0Pnee+/Vbtq06U/qgpPFGdkH5FhdUS42CeD5qb2exj997qzFG6tgnoC5mG1vbiUewFFG1uIa5LNmzXqNHmvbri44WaSR/QLaZstLiJyLrXP4sRwox2XkMJeV4+Qwpyfal9uQw5HakfPIYTk/tHej37X9vuMbX6M8DHfc2hv19wRw1uLaxSY6sGLFikecTifegYg6lYsiAUCO1RWeUGRFOFbHeSOV7y491nZizRdve93lB0Nu+qD8O22HH6E+AG6+uIxbe2MM8QKOMgw4flGaFn/ooYd27927dyW9kRbpynUjgSDkeP+HOkJkEKBfwCF/68oXmvdgv7dee4O9uFxPAEcDDDlrcccdd9yxqK6urlqZKrHJH5BbeqRfYqs/G3NhzftEwF39ZNPORdR/PI6m195xD6ungLMtzsuGzs8++6z+pZdeuos+f0JLl8pUiWUmGHL82c73A69hcwm/5/3WQ3eVOxrw2gWGO651b73cewo46mHIg1qclg23EOiL6AaQvh11HkECgNysNDltdPKLfe6GRU837d5CotJr7x5rzN4CDlMlqMUp7Lz88suXHzhw4CN1AygC0WGi8x1y3NCp8To++lXN+uVgqPPgu5ZgLC2AY6rQOA6+4MQvr/3OO++8j+zxGmWPkzRidJq5YuiNvomxoQzLBru72e+pWdS46z7qWjsdYAgmAJhivijYM5cIiaITWD7BLw6dc9ANoGMvv/zy3WSP0zeGevzjo6ryy2H50EKQR7pNnmvx0MvugN/7vuPw3Vucx47RbGv8kA+WeFmwVxAkAnAQjM6wqaJ1kl41sfnTTz99Cva4gjz2OQLk+DBTrjswAbt7r6fhqacbdm6m8cpw9+rCUpZdIgBHfQx5iKkyY8aMJbQh6123Gz9I5WKVwElNnrurK16C+4i39d05NeuXkFz0pgkUZkL+9CcKcMwdQw6acaGATrfPnDnz13TR+ZmCnKQRh4OpYs5Rm9yjXVS2f3ZX3YZfk0g0TsjnZcGEwQ1xJxpw2R7XIKevRJy49tprZ9MDEuVqUxZEHrtjyHNpjRwrJvU+R/nDjZtn13scJ0gaAFyGGwwlRHtD0snY3obOyR00EOTe/fv3r582bdr0pmXv9MVXbpWLTQImklWHQGWRxlY203IB7kaf69CC5p037XDU4osCbXQw4DBvE6q9Mf5kAI564UJAJ1vc1dLSsnFUZctltKOuUEHeIaRY/gfkcBBotq6k+KnzJwKe+mUnym9c13roIA1FD3dCNTfkBZcswGV1Ewxv3bq1rcBk+Xycpd836c+vVUHeMQmx/M+yCgozlkIZkoe2mYrWgKf19ROVt/y55cty6pYebmhuAJ5wlyzA0VGeC/a1zm9z1jaVme17hluKL6HVAgtPXMJHloMVsqxCBJrh4+yA292+tv3Ifz7btAu34WW4E7beHUkMyQRcbhNzEpyXTY5jx+kJly2jrSXTSZPbeeLkAiocXgIsq6Aww2fLiFjY3Cf8nsbX2/bf9mzjLqx1M9xY80463BBCqgEPgr7VWdvQbvCuH28tnUo2eR+eOHRKuegSCMqKTHOY55l44F0mDQHn0eXNX9z8yomKPTSiVjoAOMONmzlJsbup3qBLFeBokJVOEPJyV2PLUW/738+2DbjAZjCV8cVUsHcqEFECgDwoyIi50pOAde46n6NiYePuW9a2HfgH9QJgpxxujD6VgKM9OJ4XzT/gOeHY7W5Yd65t0CS70TRE24nRuWrQkV39H0kCDHmmrK1gZnH7/ZjXsfWRhs23b3HUHKW+682SlGhullmqAQ+Bmzqhndd6He5PHDUfTC48ZXShwXyagpynp3ufzRUIMp0OuwLpWUq6/d72wd21G+fsdzfVUX8YbtzIwQ7BlMINeaQacLQJ1wX0Fr/b9zfnwQ/PKxhUUGKyTjIJo4Enr6OI+j+SBGQ5YcU81Qfgdga8gQpP0/O/qP/4d41eB77yK8ONC8qUww15pQtwtM2Q84VGwEsbyN9srdo60FRYPsRin2wxmOzYS4AHc5WLLoGT5kr0fIlMxY5AvL+k2e9ufK/98Lz7aje9SnPIF5PyHcq0wI2xphNwtM+Qww+CvsFRfaTa2/beuILSM+0G0ynKZIGounephJxNkhpf+7aFjTtvp5WSHdRDaG3W3DBJ5KVAzHHKXaYADrj50KCv8rS0rXFUvXtOwSBTX5P1K8pkiY0NNleSSRNu3sAkKfc0L7+j9sMH97ua8fYpaGyGW795KrbOJyFXugHHkHgu4DPkmjanP3e+Na1V2waa7buHmAsn0/ZRu7YXQ5ksUVE4adIlducKcU0mCW7euBvWOo7c/UDtxr90miQMN9a4+WIyabffow5el5gJgKNLMuQy6Fp4g+PY0cNksoyylgymz4SM7nioS9nmurkMOT0JeUh0j05ga/toiuj78OKQr/W9RY3b57x64stdVBlrbACuv4EDJZV2l2lXb+gPrivxw8OXVgvosNFhp6MQ4TvKzvnni+yn/rLUaB2BJ1/4TzKlKRdGArCVe+PY1m70uw9+7Kz+wx/rt26g+mCCMNS8BMjbXbW/vr1pM5FlMw1wjA19wgHI8SVmKx2AnEG39zfbiu8vu+CasdZ+19HHWAvM2ESqzBYSUXgHDRwv5rxC0ub3uCrI1n6w/tMXGr1OrJBAU+MA2GxrY5WE93LH2xQVTZ7LFBNFP0IWEnwc0Aps0/mcfq/3rbYDO+r9zrUjLMVDaePWCGW26EV48px//Kw5ovl4wxSbI/Ty+Y+fa97zq0WNO9aRzOXlP2hvGW7MT0aYJCdH3RHCWDPZoX9ssrA2Z40Os0XT7HMGnP/1C2yDbulrtI7E64nx7lae1EweXKr7Bq0cybGd7SI7m9a1D3zmqln0WN3nH1J+1tSstbH0xzduWOlErjhSgymKz3TAWQyAnEGHbQ7I2T7XIDebzba7+p1z6STbgGv7GwvGKNBZdNF9GWx6J/eXO5x1z/++aetaejMZg80+r2vLtnZGam15xNkCOPrM2hygQ5sz6ACcYYdf8Kuy8y86zz7g2jKj7SwFOkkkjJPBJlNv9xZH3fOP12/+iLICZBwAm31obIDNdyQBdsZqbepb0GUT4Nxp9BnXDgw6tDlrdA1wOtf828rO+afJtkHXDTLZz7XiNQxUBIXz1XwB1KASa9n0Rilx3Of4fJPz+PKF9Vs/o2gGW/ZlcwRQ84UkBbPDZSPgkKzGKfmy2QKNzkuLMujWG0rPmnRhwZBvDzbbp9sN5kLAni8XpQy1n9AG1I6At51edPnBRlf1G4sbduP2OiCWoUYY2poP2c7OCq1NfQ+6bAWcB4D+A3IGnU0XBp01u6blh5qLi27od8b0Mdb+3xxosp9PoJvwch3Anmvr6Vi/BtRegprA9tX6HJu/dDe+vbhp7wf0RincoGHtDKAZcoaal/2gtbPGHKG+dnHZDjgPSA86TBi20dmEYV/T9FMKTx00q3j0ZSOsfb5ZYrCO0UyYLNbssqbuhBpfS/jyoLvl7f9r3f/O+vajx0kmDDDDLftIg7ZmjZ3VYNM4NJcrgMvjgTbHuAA5NDprdQDO0Mu++Yf9xo2dXDB4Kmn1c/uZCibShWkBPi+CR+gy1ZSRgcbmJzxJQ0t8riafaxdp6883uWo+Xtm0r4LGDG0MeAFzOB/prLFhguQE2DQOzeUa4PK4WKsDdD4Ath54TaNTvJbWz2wr+FHfsRMnWErPG2iyndvfVHAGwW7BBSqA7/jX0QwLL1kXrYAYjg1f+LhMBNC4UCSoPfSmqL21Pufn5Z6GLS83V+xq8jphcjDUAJoPBpzTWFuzxu6ongrkkuM5yqUxyWPB+Bh0va0ua3eGnOPYNw21FRX+oHDcV06zlpxdQvtfCg2mEYVGy1CrMNpZw7Mvwy93AmG9oBlafT6GGPYzQGbfLfyOdr/nSHvAd5B28x2scp/Y+Wr7vu1HnG24qwhIWROzz2DD5zj4DLRsX0fqDmXPbqeXe3aPJnrvGXT2WavLpgyDrfflvNoP5eLiYYMmWctGDjEVj+hrtowsMliG01cayugppEK6k2qnbWCFlNGMxhh81vRsXkAbgywizUuvWWinW+QOT8DX7vL76tsCnkPNXs+Bal/rwR3u+gPrWg/DhmYoZe0rwxsuLOdl84P96BLLgdR8Apynq4O5DqWKMOAFtLIPwBlqhp3P9Xk14DvrCKmbzB3zSGtx0RBjob2fuaCoj8GKHZGiJeBub/K62qr97Y4D7tY2MisAZofyPukzzPBZ68o+wgw0Q4xzOQ+X1ddN2fLD5SPg8syGAEkJMqx6kGXA9WlcDvUhzPWiLTmMc9kxeIjjMGtXBlwPLEPLUPM552ef62NfbjdvwhC+ch0SYFkwkPD14PI5QwzokY99jg9XF1rheEAHx/DpzwEp4gCx7DO87CNNDuMcBxz7HWd5+j8LPE+HH3XYLBv40Q4Zan0+NCDXIzfIAMo+wvqDYdfHy+eoF+fK6STAwtdFq9MIEmB5McjIFi1OTo9QZQiYDCnDizLR4iLVqeI7JcCTowTSOwno5ag/R+36OAZXblkfpz+X86pwDBL4fwN/IZwMBwH5AAAAAElFTkSuQmCC',yellow:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALcAAAC4CAYAAAChOH1KAAAlaElEQVR4Ae2dCZhUxbXHTy+zL8ywDDsSVhEVJQoCkoSIIr4kvohLxO2ZfC8an0mQrCQm+uJ7qHkv5hE/xSQaNokBogkxigaUuLDIpsiOMA4MOwyz7zPd7/yLOZfqnu7p7umeXut83+2qW7du3apTv3v63Lr31rWRkUhowOZViPc6Nutpbq/8WPVO8173sYtJ6kgDusI7yme2nYdTdIZQj0NH1vrgwYNtc+bMyb344otzCgsL87KysnLT0tKym5ub6+rr62vKy8urd+7cWfv444/XlJSUAGSB2VfoKw3HM9KBBqQzOsiSspsEXgmhCMTtDGT2TTfdNDwvL28kQzvC6XSOcDgcQ2w2Wzfenme323M5nuN2uwPql/O5OF+dy+Wq4X2rOV7Z2tpa3NLSsp9Pgv3V1dX7XnnllU/4RKnj7S5edNARl4WjRnQNBFS+njnJ4wKxHtp37NgxpG/fvlPY6l7CAI/kZTgv/YMBN1L64hPAzcAf5eUTXvax9d9x/PjxtZdcckkxH0OAF8gljNThE7acVIdbQLZzDyJuX7du3YChQ4dOycnJ+QJb5M+zFR4Qr73L1v4IW/h3amtr/3nw4MG1kyZNOsJ1FdglBOwpKakItwfQTz31VN4dd9wxnd2LL7J1/hzDPCxRSWDYD7BVf5fdmbeXLl26avbs2dXcFsCdkqCnCtwCNEL7gAEDnBs2bPh8QUHBnenp6TdyWi4vySY1TU1NKysqKl6cMGHCO0eOHGnhBuqQJ71FT3a4FczcqQgdu3btGtWvX787MzMzv8YWun+y0eyvPWzRjzY0NPzp2LFjL44ePXoP52vlRbfo/nZN6PRkhdvyoX/7299245GNe9iHvoMvBC9P6N6KQOX5gvRD9tGX8gjMovvuu6+SixRrjjCpJJngRluwAGz78uXLu0+dOvXbDPW3eL2QFyOeGihnyOevWbPm6VtvvfUsbwLcAnpSuCzJALcH1KtXr+4zduzYWbm5uf/OnZWMvrQnouGv1bD8ftu2bf937bXXnmgDPCkgT3S4lZXmDrGvX79+0EUXXTSbRz3u5fXM8Ps85Upo4FGWBbt3735q4sSJh7n1YskRJqQkKtyoN8B2vPzyyz2uueaaX2RnZ9/NN1bSE7IX4qjSfMOoqa6ubvFbb7318xkzZpRx1XDxKZY8jmoauCqJBjfqi8WB4bzNmzf/W/fu3R/j9R6Bm5o6OWyuErK1fMiKwuhfJ8VNZWUVtT/77MTHFrYNI8oIS8L444kEt7ggju3bt182bNiweXwHcXwnuy5pdwPYzrofMdiR8SaaW9wffFLc+N3RE/7xEStNrHhkCu/iXkgEuFFHBfb8+fMLb7vttkf4YvGb7II4u1g3CVm8vXEpORtfiGzdbbaWmpqW3724ou4/v/WDj8u5cMAd965KvMMt1tp56NCh24qKip7gmy99IttzyVWao3ERYekKcbnpxKmy5h/3HbVpGZcvdzzj1ooDnngUnHQOLI8++mhBZWXlC3369FlowI5tV9lt1KdPz7SFdaUTXnj00REF0kccxqWRjMdKWWBv2rTpUn7YfwnfWRwZ225NnKN3peXWtdDion0799TedfkXPvqY0+GLywWnni2m8Xiz3KgPLLbz6NGj3xgzZsw7BuyY8uH34E47jRxzUc47J/eN/wb6ixf0W1zxFC+VEWvtnDt3biE/ybagZ8+ez7CysngxEqcasNkoq6i785m6w1ctmDt3GB5xEMjjwiOIh0qgDjjJMG49hp9ae5Gt9fA47c+4r1a03BJvRbS43J/s3FN3R5ubIhebMR0Tj7XlFoudtm/fvmsuvfTSNQZsb2wSY91ptw0fMzrnrYObr7iGa5zGC9yUmBrPWMItYGOY7xZ+W/wvrIw8XowkqAa4Q/M+MzjjL0d2jL+FmxBzFyVWcOO4OLPT+AH6b/ELuAs5bp4LYSUkujDg6f37Ohee3ncVHjUWCx4TzmJxUAE7/eTJk4/06NHjKb7bGIt6JDpH8Vt/N9l7dnc8dfaTcY9wJWG0YjKSEm2oFNh80ZhRVlb2NL/D+KP47SFTs3A1UFiQ9qOakglPjx7dKyMWgEcTbgX2+PHjs3j6hCX8fMjXw1We2T/+NZCTY//65jeGLRk/vjuGdaNqwaN1NavA5salnz179jl+9evO+O+WxKxhrIYCA2mrtq71xdwLNt7P+Zp4kacLA+0W1vZoWG4BO4197McM2GH1V8LunJPtuLP84FWPcQOidpHZ1XCjfCxppaWl32Ef+6GE7R1T8bA1UJDveOjUnvHfAQ+8CBthl+uvgK6EGy6PAru4uPj23r17z/VXCZOeOhro1cs5t3T7uNu5xQJ4l7nGXQU3KqzGsfmF0+v79+8/P5oTR6YOKgnYUjfZ+vdLm7/vg7HXtwEOTroE8K6AWyy2kx9ZHTdkyJAlbY1IwJ4wVe4KDTAgacMHZy3Z9vbl47h83MkEhxEHvCvgRpnOefPmFfF49lLMU83rRowGPDRgs1POpRdlLZ33xJAi3iCAe+QJdyXSZ4sCmyuVwY+truA5RKaFW0Gzf2gaiNehQH+tqKt3vZkzaAOeRWnkRZ4m9Jc9pPRIWm6cKMrPPnz48HcN2CH1Q8pmzs6yTzux+8rvsgJkiDBiBjdScAvY8LOv4hd58UyBEaOBoDRQ1DPtEfa/r+LMEX2SMFJwoxzHE0880Yv97AXsZ6OSRowGgtIAeLl0VNaCJx4d0ot3wL9/RLiMxF8AKgKY4WcvY3dkOseNxEgDieZz62qqq29dlTNo422cFhH/O9wzBCeHgptfOHjAgK13lYmHqoHsLMf0ozvHPcD7yehJWMY3HLgtsBcvXnwB34F8ONTGmPxGA94a6FuU9vDiZy6+gNPDBjxcuNXoyA033PA4+01mLmzvnjLrIWuA36jP/dcb8h7nHcMePeks3JbV3rp167X8sVF8NMmI0UBENJCXa7/xo3fGXsuFhWW9Ows39nNed911uRdeeOEvI9IiU4jRgKaBi0Zk/vK663rDGxDAta3BRTsDt2W1n3/++Vk8jfDQ4A5lchkNBK+BNKdt6OJfD5rFewjcIV9chgq3BTZ/UGkY36wxz2cH318mZ4ga4Js7Dy1fMHpYZwHvDNzqIpI/1fEkX0Sab8+E2GEme/AasNltmdO/kP8k79Gpi8tQ4Las9rvvvjuBXxe7LvhqmpxGA53TQE6O7bp1r4+RW/PgNWj3JFS4ldXmW+zfY6vdudqavYwGQtAAOONb89/nXUK23sHCbVnt119//TKelmFqCPUzWY0GwtJAbq596j9eueQyLiSki8tQ4IbVdl555ZWzOTRmO6zuMjuHpgGbbfxlOeAOcIPDoPgLBm7LavM3H0fl5+d/KbSKmdxGA+FrID/P/qWXXxw1iksK2noHC7ey2pMnT8bQXzD7hN8aU4LRgIcGbPYpV3UDf0Fb70CgitV2LFq0aAhb7RkexzMrRgNR1ADPezJj0fyLhvAhYWzBbofuSbBwO6dOnfogX7miUCNGAzHRAA+cOP5lSt6DfPCgXJNg4HawO5LDs0XdFJMWmYMaDWgaKChw3DR5ck/MqBDwwrIjuMUlwTQN0/lzHvjuoBGjgZhqwG6ngmfnDsTbXgGtd0dwY5u6kBwwYMCt5qZNTPvUHLxNA+BwYP/0W3lVLiz9MuxvA6w2FsecOXN68fPaX2wr2wRGAzHXQF6O44tzZlsvEwur7erVEdzY5rz77rtv5s9S49anEaOBuNCA3W5L+/rt3W/mynTomnQEt3JJ+JvrmA3IiNFAXGmgX1FawC+m+YJbzLxjyZIlI/mNdtzTN2I0EFcayMqyXfbS7y4cyZWSURNw6yH+4MYOjokTJ95iLiQ99BX3K271Tx331Qy7guBy0vg8WG/FKoft4IbP4i3IpPztwsLCz3tvNOvxrYEW23iqKPs9VxKfnUlc4fncPSrvtUpYb2lygU+/frc33JZLcs899xSwS3KpxxFSdMVWv4dsle+Qzd0c9xqAGevm/AJVVBSTy+ViCDwhQQN8JLVLc1P7/bz39VXOuTye+/rK5zvNcz+U1ZG4XO5Lb5teWbBs1QHMUCXsWoV4w42yYLUd99133yQ2/dBVSoutbhc5997MmkscS4hOK2hxU1mlb7h9daj3f7r3uq99Yp3GJ67jnqktk5atopVcF3Dr0UnecKNNCu5+/fpNNv42m4PyN8jWdDTW/Rjy8TF22yPLTWeriFyWLQu5mLjeAbD26eaezMHfeQG3SLJaiwRdsK7g5icAJ+kbUjVuc+OziYkpPD0Cdc/nDk0EM9xJFedn2ybyrvizEnatknS4oQIsjlmzZvXMzs6+0MplIgmrAQHcwT0tHZxMYXaGe9QDX03vCW55kaap/vIFt33mzJlXt2VUmcxPYmsAgBfmsWkD4Nz9SbbYvnq1G7yC5Q7hRgYH35W82vjbiQ20d+11wL23JfI6OO1TSIBbXBMArsTbciu4eU4Sc1dSNJREoQKcZ9+DBY+U4F8AIv8GEleJUfrJyiTw2g5uGS0R2hXcPL79mSjVyxwmyhpwwkXJdVNFTeRGUQRwNEXiEkajedkZBF4FblUN/nHr5zDi9p/85Cd92NSzh2YkWTUAwAtgwcWkJXhD+UTKm3VLWh9uhmJYmiNwo5lY7Pw8yXDZaMLk1YAArkZRuOdhaRN5mXSxDdyCZ2FZrUgPKrj55s1QczEpKknuEIB347cRYcGFiEQMUf++3V1DubcEbtVx7Sw3v3UzLLm71LRO14AADqudyJKbaQO3ArdqjQ434naeB3CIsdyJ3M2h110Aj+QoSui16Pwe4DUnm4ZwCYphDhXcGC2Rcxahg0dKkMlIimkAgOdnu6mqzvdTg/Gujqx0G7jFiInFM0iHIME+atSo9MzMzAEqxfyknAbOAc4gMBWJdnGZke4eMOozmengmBcFuA63bdq0aYV4jDDletU02NIAAM/LOge3lZgYEceUMa2FXFWAbcEtKzaen4RHP42kugYE8M6Mg8uFqVh+6FLSfOlVtnU2v+yHcFCRG/xaPOt3KG29evUyN2989UAKpgHwXH4evKZee0A6SD0IsMgucQl9FaFvk7iEgfLr27vnucGvwK38E9lu42FAY7lFGyYkZcGz2YkFLgkg+TkOsdyqtjJaomjnZ7gN3AnQidGsosOhWXDrHZdo1iC4YwHgzEzfbglKsBm4g1NkquUSwGsb4neYEG5MTjp5WG6P0RIeBswxN3BSDd3g2gvAc/irox35wsGV1DW5UK/0DDemNlZeCI5ijQkikT91jY1GjAZ8asAX4AI7Qj3us4BOJOpl6nFfRaU77AI3Ntv00RK+gDBw+1KaSTuvgXOAu6mOZwqRuUcEOuSSuITn9+x8TC9L4hLqpTqdynIjCdbbc+6t1tbWFiQaMRroSAMAnF/MpXoA3lHGKG9rddk8+BWfG9WwNTU11fqaoSjKdTSHSwANAPCsjDYTGQf1xb9IYzPVclWU1UaVdLipoaEBG40YDQSlAR1wuYrzDlGQRZuPUmWb937+1r3L0/fnuQM9+NXhdhu4fWjfJHWoAQtwocwrtyQHC6vX7u1WvctDBkmrb7YBbstTErhVQl1dHb82asRoIDQNAHA8j+frIi+0ksLLzRe5wq/iGaMlQrq7oqLCw6yHdyizdypp4JwFd1MDzz4noyjRbD9OrMpaD8vtlqFAAO4uLy8X8qNZL3OsJNEAf6uGLfg5wKPdJMBdXuMCv4plHF/cElWX06dPV5vREqUK89NJDZwDPPouCv4tTpVTtV5tgVvRvnv37hoDt64eE++MBgB4Bs+hDGvqvaA8pIlIXPIhXdIkjx7KNskvIa4q9xyyA24Py40ViHvlypXVPNbNMzobMRoITwMW4F7FeMOJzZKmxwVa71DPg7hIczNVvba+SdwSJFszTgntbh4xKTHWW1RmwnA0AMDTYcG5kK5ccAXLIyUlfBiLY9Rb3BLEscFVW1tbghUjRgOR0IAFuOaKRKJc7zJqG2wlnObiRTwRBbfQjg0uHg781Fhu1oSRiGkAgKfxuJy3ixGpdVS0qtb9KQeKYQ4V02K5BXA3j5gUI7MRo4FIakAAj2SZelmnKuggr1scYxvg1hNaecTkoLHcUI2RSGtAAI+UxZZyUM89h1wwyviamcWzWG5sVyZ94cKFn/L3CxE3YjQQcQ0AcCfPjAMwIyVMq2vhasenXJ5iWMoVuIV2165duxp4xOSYZDCh0UCkNaADLtY3nLC+yXZs14EmfsPTuqAEz9ZoiQU3p7XW1NQY1wTaMdJlGsC7urDg4Qpc6JoGN/xtuCSw3MKyB9xi0l0nTpzYbPzucNVu9g+kAQE8lDFwlOnh0TDKJ8tsmznZ4pfjHpYb+yABGVq3bNmywbjdUImRrtYAAHeE4IML2HJC4OvIW/e3buB66pZbVbudz41MP/3pT3fziwvmNnxX96wpX2kAgHd2ZtnGFqr68QuO3eCWF59uCQ5iWe7q6uqms2fPbjWuCdRiJBoaEMBDORb4LKugLYwrvmGuw62KEcuNFQtujrccO3bsAwO30pH5iZIGBPBgR05QrWNltk0c4K33gHADcGRq2bBhw3rjd7MmjERVAwAccAcj8LfX7Wxdz3kFbvCLRYleDOIYnOEX9tWca93OnDmznmd+7aFypuiP48jjhMVIdDUQjNdQVecuK7iheSLXrJIXPO7KM6ko46wAl9fMOE0Rj0Q1YsJhC8O9mT+Vfb09Ub8EhFaFKc2taVReYRmDMEszu4eigY4Ad7HZPnyKMAQoVtvjYhLH0eHGusCNHVr27du3euDAgRGF21axm2zH1pLN3Yzjxb3YG89Qel02PzIM3bUXf9jjtSdf4i8def3s4veFW39l+StHHaODjaGW5zd/R8fw08pQy2ppddOuva2rGVPFKrdN4EYzlehuCRKwDuB5Pk/KGzlyZM/169e/z5/vi8gXFwC28x9fZrDh1ieOVNW7cBcscSqcAjWtbXRXf/l/K6/ed6rpDDcXr5fh9jtAtzrKl+XGRtDXzJa77siRI6tHjBhxUyRcE9vhV8lWe4SLTizJR3XZLtRiwMlIzDWAx/qOn6HV+04Rf1iQ4AKAV3Brgc1x6/Y74iIw71hwFjTxqMlKniBTtoUV2lyJS0c+f+GLJzc3EgcaYI+EthyilVwVAAVOhVmP2unj3LJBLLfyZe6///5NVVVVRzty7mXHZA8BeC6PJcF3M0tsdADbzF94OPq9P5OMb4NTsdweCPqDWwCHyW8uKSl5zcB9Tm95fDWSg8FSIzHRAC48SyvoNT64YpNDARvMeogvuJEBZh474axo5ikf/trM784bOacBATzYO2kmH1t5/quLxNLCCK/aSX8Fl7yI1Qav7cQf3DgLLL/7ySefLC4rK9turPd5/QHwbOODn1dIFGKw2uW1tP3/3qZiPpzub7ez2qhOMHDj7GjasWPHSy1qSBG7GYEGlAVnwI3/HR0dtLK53XWCXmLVC9hgE0Y4JLg5v9oBO8L8N82cOfM1nvah1FhvqOa85BoLfl4ZXRiD1a6sp9L7lil/G3CDS79goyr+LDe24Wyw/G5+9axh+/btf4jUsCAOkCwigEfCpzRl+PbN8ZDUzhP0h5oadbNG97d9Wm2wFQhuAVxZ729+85t/raysPGmsd/vTEoBn8dRhRiKvAWW1G+jk7OXqQlKstt9REqlBR3AjD8w+CgHcjUePHq3duXPnImO9WRs+xFhw31Y33H8jWO29J2jR0Qr1QSc8+QcewSX49CuB4IblRgHqopLDxm9/+9sr+E2dMmO9fesUY+DGgvvWTWdSYbVrmqjsxytpBfjjRS4mO/S3caxAcCOPWG8FOD9vUrVnz54XjfWGanyLAG5GUcIfRcFzJPtP0ov7jhPe6RWwA1pt9EwwcIv1Vn4379M4Z86cl9h6VxrrDRX6FgW4GQf3rZwgU2G1qxup8ud/V8N/YrXBYUCrjUMEAzfyifVWvvfGjRvLN2/e/LS5awnV+Bfc5MnCOHiE7s6lWjktTN22Unp6awmVs5aD9rWlR4KF29t6N8yYMWMFT96z07xnKar0HQLwTDOK4ls5HaTCHTlVTTvvWqR8bTyrLaMkQVltFB0s3MjrYb358yL1y5Ytm8vzm7iMewL1+BcB3PjgwfnguMPC85G4Xt5Gc3nShnrWbMhWG70RCtztrPfDDz/88f79+/9sLi79gy1bBHBZN6F/DeA2+4Ez9OdfvE4fc65OWW2UHgrcyC/WG38ROJsavv/97/+Gb8ufNdYb6ulY4H/DRUk13zmU9kKDlY109sd/pd9wFGDLhWRQIyTYXyRUuGG9cRAMC+Kg9e+9914ZX2D+mt0UXjUSSAMAPMP75b5AO6XQ9iama0sJ/XrjQSrjZotLAt7AHfgLWkKFGwUL4GrkhNfr+eJyJd+93Gbck+D0LoCHYtFSIS/uRJ6oom23v6BeIROwwVnIYKMnOgs33BPrriXHG+bNm/cIv45WY0ZPoNbAIoAHznk+By5IIXJhKnGV2JYuaXpe2R4o1PfR4/720/PocX/5O0rH6EhlA9U88096hPPp7gg4A28hWW0cqzNwYz/xvS3r/dxzzx1cvXr1L3j0hOfZCLkeKDPlBP43XBSAEcwCBQlEelz21dP0uGwPFOr76HF/++l59Li//P7S20ZHaO0++sXv31cfbvK22uAtZOks3DgQDijWG2da/V133fXm3r17l5ubO1BPcALA01PcB29mp4OnaVj+jcX0JmsNYMsIiVjt4JTplSscuGGeAbhYb1So7pZbbvnV8ePH9xr/20vTHaxaFpxNWyr41nob4WefrKG9dy6kX4EfXsQlAVfgq9NuQAS+SsKHPy829rt5gquWDydMmPCVjIyMdMzaKWI/8S5hMdJeA+r7MNyN6GwR0Zy/v/NIp+O4ckw9LsfR0/S4bA81xAx1VQ1U+8s19K1/7qVjXGYtL7Dc8oCUpg0cMTQJx3LjSDi4t3tSN3/+fPjfjxn/O7TOyGAXJQ2f0ODdsEAkPLfWtb9yLH/HD7Q9lNrhsqyBnY639tJjv39X+dlitQXssKw26hIu3ChDABf3BGdeHfvfq/jR2BVm/BsqCl4E8OD3SMycGM/ec4JW3LuYVnELADa4wb2TsN0RLkNJJOBGQTjLMBbpAfj06dOfLC4uft8ADhUFLwAcF5m6b5pMcVxAlpyl9298jp5krXiDDY7AU9gSKbhREVhwffSkjt+3rLn55pt/WFpa+rEZQQmtrwA3XJRkE4B9pJw+/trz9MPKOjVhvLc7Ao4iIpGGW/xv/L2o0ZMDBw5U8HyDD/HjscUteEDXSNAaEMCTxWrjgaiT1VT84Ev00IFTVMGKELDBiwz7RQzurrYNqqKHDh1q4tvzGyZfmHVNbsUHufz5byNBasDRZn7kvpiuOokj9LXgEJJHj/vKK/kk7Ex+7KOLlIUQdyBP19CJOa/Q/W/soSOchJERwB1RP5vLs6Qr4PZ55vHFZb2r1b1lXNHRa/muXKYB3OqDgBFfgOvg+CtAz6PHuyo/jqEvOA7WYbF5GrSKX71NDyzaQAc4SYb88O+O67SI+dlcliVdATcKB+CyyMFsH+w6WsnTAO+8pD9dx4CnGcBFNYFDAVwfBw+8V+xzAGyeKar+D+vpu798k7ZzjWCtxR3Rh/0iXtmugluvqECO0MbPD5zpmUs7RvamKQx4Rgp/S0rXUVBxAVwpkk1ivPviAPtsPVUv2Uizfvaq+jgToBarDbBhsdGcLpFowo0GqIas3kOnud0fjBlAk/nWc450Wpe0MMkKFV3BB9ddgHiLtzC27GOfmvcWPTj3DfqIuwFQY4ErolvshIab22KdnWiIasyGYqrkZwreu/ICmsivYBVIpyGzkY41IP92cpHZce7ob23icY/jVXToZ3+jB55fR59wDfCNSN1iR3xkxFcro2G55bhyhlqAf3yEanccp7WfG05j+XszRQAcf7VGAmsgHgHHyQawedqzXQ8up/949WNrVEQHO2J3IANpKZpwS10EbhV+eoYaV++lt68dRaPyM2mAAVzUFDgUwJEz1v436oBb6p+W0cZbX6CHNn1KpzkJUMPP1h+GYo/U+ifnaNdJtOHWwZZGus/UUMufPqS114+mfvkZNNxpLHjQPS6Ax9JFwRh2Hdtjnqzy9WnP0k9Ky9QNmpiCDQVGG27pNB1yxF31jeT63Xu07ooLqLx3N7oy3UFO6TjZyYS+NaAPqUbbgquhvkZq5FGwX13/ND3L/YgPnsLH9jXch76OmsQKbjRQQd0WWrAv30r7bXbaOLIPXZHppG7GTQmOBQ/AeZeuHj1B7/HEOXSikg4/vZZmzV5Ba/mwsNbiX8uoiNygQR9HVWIJtzQUjYaLYrkp6w5QOfvhb04aSn3YDx9m3BRRVcehAN7VFCk3hAfz9p6kN29fQD9Y+REd4poJ2GKx9TuPXV0ln4qJNdxotPeiQD9dTc3sprw39gI60zufxsFNkb9cny0xiUoDMtrUFTTBr1e30huo8e399D/TfkPPcj9V8oF1/1qeFRGLHbOeiTXcaLj0g1hvPXSv2EqfuG20bngRXc43fAod/H8rHRgzrcX5gS39tOlKjEI4IcDGmzPHKql43ts0i7/g+y6rQe44yoiIgC19GFNNwTWLF0FdcLJh4cf1Cd/p5Q9SqyW7ex7lLL2X7vjsILq3WyZ/vIBzWZ3ImYy01wDch3AFUOMZbJ5TpH7rYVrAs64uPVvtYan1N2hgrbGIwQr38GHtHw+WW28AlCKLnP0IW+ubyLX0A9pxqIzWXNib+vLk7oPlYtNArqvwfDwcvYgLUsu2eP9pemfOSvrBwyvpHe4HuCAyGgKwvZ/siwuwoYV4styojwieYsaCGT14dj1lxfl7YZYlz3j2drr6Xy6m2T3zqD+PqpAZNmTt+BGAiiVYgcWHC8L3H46+toOeenAZvc/7wuUAzAI01vVnRCLwP8ElRlDiFW40EXUTwAVyAG4tA3tR3oI76J4xA+mOvHTKgKtiIIfq2kswcANquCDVTdTIj0YsvXcpLSo9rcatYZ31RaDmU8Aa5Wp/0BinxDPcUA3qhwXuEwCHLw5LbgGO+MyraNCDk+nuEb1pOrsr6TyyYiBnxXiLP8ABNW6dswvStP8UrXrmPVr8x410mPfXgUYcUGOID1CLbx3CfwLvFUWJd7hFFagnrLhALq4KLjoF9IyvXkb9Zk+lmSOK6Cv8XfZMfl7cQC4a9BECatyIqW6gBob6b0+toT/+5SM1OQ5cDgEbcd0FAdRwQeIWaq6bkkSBG5VFXQVyWHFxVQC4QK7iU4ZTr4e/RLeN7kdfzcugXAU57xnOBRYfIykE1htv8yioG6lm1zH6y3/9nZat/UQ96CQgA2yJ+3JB4h5sdFYiwS1wCeDe/jjAFosOa57+2c9Q4X9/mW4Z3Zdm8J3OQszJJ3c7Uwl0AI0Fkw80sFPBU5iV7zpOL//0VVqx9VP1pTAALEAjrltq8asTwlpz3S1JRLil8gI5XBUs8MdlfFwgV8AX5lHW4zfSxCsG0vUDu9NEfnY8Xax5Ml+Awu0QK13bRE2lZ2n9llJ6g4f11pdXW4+h6hYacfjUcus8YVwQrnM7SWS40RjUXyAXn1wgB+ACucTTxw2mbj+cRlNH9aZp/QroYobcpmZ3QkFcUiJbdLHQ8Bnw0gC7Hu5jFbRzDz8Dwi/nrtlUom6VwzLLIhYa6zrUsNJiqRPCBeH6tpNEh1sa5AtyfXQFcAN6gVydAHdNoAF3j6PpQ3rQlIIcGoxRFoCubg5x5niHXYcZz3wAaIx6VNRSSXEZrV28iVYt2UBHuCkCrkCNdT0O10OsdMJDzW1Rkixw6+0R0MVd0V0WuQgV0MXKO798CRV9bRxdMbQHje3TjS7n0Za+cF0wdq7DjgPFwroDZIgCmkPAjDHpttGO4/zo6YcHy2jbnzbRlld30CnOAmB1qAVoPR1Ay4IjyMLRxJdkg1vvEbQNroq4KwI7ABeovUNsQz7nzHHU78YxdMWQnjSWn0q8LDuNemIObVyQAnbrwpQzQ3Tg9fi5rYF/BV7klLgijX9wIQiYEeKtcn7r5czJKvqo+AxtW7mdtvxxkxq+E+urwytwSyh5BGgu0XI/AlcywXIkM9zSFWLJBXSEFsQcB+BYF+glriBvS7dPGU6FUy+iwcOKaFBRPg3qlkUD89NpIFv4fmzdnQAez1OLK6POLK91bBPLq0IGFxd8AjHSsN5mlVt4/PlYVROV8qQ2paeq6DDPr3d4zW4q4WE7fAsdYAJWAVbiANk7DpiRJjAjVIflMGkFfZAqgrbqC+AF6Ahl8QU20mS7vo86WXIzyfm1K6jfZQNpQEEm5fP0w1lZaZTNw47Z7L9ns4XPZl8+i61+NsOdwQA3svWtY9+4ni1xHfvJdTw8V1fPS2Mz1Vc0UNVHpXTkT1voWE2DB5AAFFCK1RVgBWR9Xc8j+wjMEnJRyS2pBLfekzrkiCtQOdThFaB9wS0nhYRShne5so5jIy4CwCACmncolhWQCpwIJS7wAmyJ+8rrXS5nTx3RFZ46rfZsqQCohwK7Hgr4HaXpZUgcR9PjWBfo9LikIRSQBWZ93V8a0vUyJI5jpKRA6UY8NSAgeoeAGmmBQu/9UDrSvAXwQQRCPRRQA4X6PhI/V6r59al0oxZPDQisSPUVlzQ9lLx6iLi3AEiIHgqk3qHk886rCjA/7TWADjESugZ0vUncO5RSJV3W9VBAlTRZ9w6xXdIkrwkDaKAjxQfY1WwOoIFQdGvADaDMzmz+f6SMYEX4z7hMAAAAAElFTkSuQmCC'};return{FaviconsByHue,};});'use strict';Polymer({is:'tr-ui-b-info-bar-group',ready(){this.messages_=[];},clearMessages(){this.messages_=[];this.updateContents_();},addMessage(text,opt_buttons){opt_buttons=opt_buttons||[];for(let i=0;i<opt_buttons.length;i++){if(opt_buttons[i].buttonText===undefined){throw new Error('buttonText must be provided');}
 if(opt_buttons[i].onClick===undefined){throw new Error('onClick must be provided');}}
-this.messages_.push({text:text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_:function(){Polymer.dom(this.$.messages).textContent='';this.messages_.forEach(function(message){var bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);Polymer.dom(this.$.messages).appendChild(bar);},this);}});'use strict';Polymer({is:'tr-ui-b-toolbar-button'});'use strict';tr.exportTo('tr.ui',function(){var Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=[];this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;}
-FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_:function(operation){var task;if(operation instanceof tr.b.Task){task=operation;}else{task=new tr.b.Task(operation,this);}
-if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering:function(filterText){var sc=this.brushingStateController_;if(!sc)return;this.enqueueOperation_(function(){this.filterHits_=[];this.currentHitIndex_=-1;}.bind(this));var stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){var overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
-if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{var filter=new tr.c.FullTextFilter(filterText);var filterHitSet=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHitSet));this.enqueueOperation_(function(){this.filterHits_=filterHitSet.toArray();sc.findTextChangedTo(filterHitSet);}.bind(this));}}
-return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_:function(dir){var firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0){this.currentHitIndex_=0;}
-var N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)return;this.brushingStateController_.findFocusChangedTo(new tr.model.EventSet(this.filterHits[this.currentHitIndex]));},findNext:function(){this.find_(1);},findPrevious:function(){this.find_(-1);}};return{FindController,};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;}
-TimingTool.prototype={onEnterTiming:function(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming:function(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY)){return;}
-var pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_:function(pt){if(!pt.snapped)return;var ir=this.viewport_.interestRange;if(ir.min===pt.x){ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}
-if(ir.max===pt.x){ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}},onUpdateTiming:function(e){var pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming:function(e){this.mouseUp_();},onExitTiming:function(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_:function(e){if(e.button)return;var worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_:function(e){},isTouchPointInsideTrackBounds_:function(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas){return false;}
-var canvas=this.viewport_.modelTrackContainer.canvas;var canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom){return true;}
-return false;},mouseDownAt_:function(worldX,y){var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
+this.messages_.push({text,buttons:opt_buttons||[]});this.updateContents_();},updateContents_(){Polymer.dom(this.$.messages).textContent='';this.messages_.forEach(function(message){const bar=document.createElement('tr-ui-b-info-bar');bar.message=message.text;bar.visible=true;message.buttons.forEach(function(button){bar.addButton(button.buttonText,button.onClick);},this);Polymer.dom(this.$.messages).appendChild(bar);},this);}});'use strict';Polymer({is:'tr-ui-b-toolbar-button'});'use strict';tr.exportTo('tr.ui',function(){const Task=tr.b.Task;function FindController(brushingStateController){this.brushingStateController_=brushingStateController;this.filterHits_=[];this.currentHitIndex_=-1;this.activePromise_=Promise.resolve();this.activeTask_=undefined;}
+FindController.prototype={__proto__:Object.prototype,get model(){return this.brushingStateController_.model;},get brushingStateController(){return this.brushingStateController_;},enqueueOperation_(operation){let task;if(operation instanceof tr.b.Task){task=operation;}else{task=new tr.b.Task(operation,this);}
+if(this.activeTask_){this.activeTask_=this.activeTask_.enqueue(task);}else{this.activeTask_=task;this.activePromise_=Task.RunWhenIdle(this.activeTask_);this.activePromise_.then(function(){this.activePromise_=undefined;this.activeTask_=undefined;}.bind(this));}},startFiltering(filterText){const sc=this.brushingStateController_;if(!sc)return;this.enqueueOperation_(function(){this.filterHits_=[];this.currentHitIndex_=-1;}.bind(this));let stateFromString;try{stateFromString=sc.uiStateFromString(filterText);}catch(e){this.enqueueOperation_(function(){const overlay=new tr.ui.b.Overlay();Polymer.dom(overlay).textContent=e.message;overlay.title='UI State Navigation Error';overlay.visible=true;});return this.activePromise_;}
+if(stateFromString!==undefined){this.enqueueOperation_(sc.navToPosition.bind(this,stateFromString,true));}else{if(filterText.length===0){this.enqueueOperation_(sc.findTextCleared.bind(sc));}else{const filter=new tr.c.FullTextFilter(filterText);const filterHitSet=new tr.model.EventSet();this.enqueueOperation_(sc.addAllEventsMatchingFilterToSelectionAsTask(filter,filterHitSet));this.enqueueOperation_(function(){this.filterHits_=filterHitSet.toArray();sc.findTextChangedTo(filterHitSet);}.bind(this));}}
+return this.activePromise_;},get filterHits(){return this.filterHits_;},get currentHitIndex(){return this.currentHitIndex_;},find_(dir){const firstHit=this.currentHitIndex_===-1;if(firstHit&&dir<0){this.currentHitIndex_=0;}
+const N=this.filterHits.length;this.currentHitIndex_=(this.currentHitIndex_+dir+N)%N;if(!this.brushingStateController_)return;this.brushingStateController_.findFocusChangedTo(new tr.model.EventSet(this.filterHits[this.currentHitIndex]));},findNext(){this.find_(1);},findPrevious(){this.find_(-1);}};return{FindController,};});'use strict';tr.exportTo('tr.ui.b',function(){function TimingTool(viewport,targetElement){this.viewport_=viewport;this.onMouseMove_=this.onMouseMove_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.targetElement_=targetElement;this.isMovingLeftEdge_=false;}
+TimingTool.prototype={onEnterTiming(e){this.targetElement_.addEventListener('mousemove',this.onMouseMove_);this.targetElement_.addEventListener('dblclick',this.onDblClick_);},onBeginTiming(e){if(!this.isTouchPointInsideTrackBounds_(e.clientX,e.clientY)){return;}
+const pt=this.getSnappedToEventPosition_(e);this.mouseDownAt_(pt.x,pt.y);this.updateSnapIndicators_(pt);},updateSnapIndicators_(pt){if(!pt.snapped)return;const ir=this.viewport_.interestRange;if(ir.min===pt.x){ir.leftSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}
+if(ir.max===pt.x){ir.rightSnapIndicator=new tr.ui.SnapIndicator(pt.y,pt.height);}},onUpdateTiming(e){const pt=this.getSnappedToEventPosition_(e);this.mouseMoveAt_(pt.x,pt.y,true);this.updateSnapIndicators_(pt);},onEndTiming(e){this.mouseUp_();},onExitTiming(e){this.targetElement_.removeEventListener('mousemove',this.onMouseMove_);this.targetElement_.removeEventListener('dblclick',this.onDblClick_);},onMouseMove_(e){if(e.button)return;const worldX=this.getWorldXFromEvent_(e);this.mouseMoveAt_(worldX,e.clientY,false);},onDblClick_(e){},isTouchPointInsideTrackBounds_(clientX,clientY){if(!this.viewport_||!this.viewport_.modelTrackContainer||!this.viewport_.modelTrackContainer.canvas){return false;}
+const canvas=this.viewport_.modelTrackContainer.canvas;const canvasRect=canvas.getBoundingClientRect();if(clientX>=canvasRect.left&&clientX<=canvasRect.right&&clientY>=canvasRect.top&&clientY<=canvasRect.bottom){return true;}
+return false;},mouseDownAt_(worldX,y){const ir=this.viewport_.interestRange;const dt=this.viewport_.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(ir.isEmpty){ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;return;}
 if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.min=worldX;this.isMovingLeftEdge_=true;return;}
 if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.rightSelected=true;ir.max=worldX;this.isMovingLeftEdge_=false;return;}
-ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_:function(worldX,y,mouseDown){var ir=this.viewport_.interestRange;if(mouseDown){this.updateMovingEdge_(worldX);return;}
-var ir=this.viewport_.interestRange;var dt=this.viewport_.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
+ir.setMinAndMax(worldX,worldX);ir.rightSelected=true;this.isMovingLeftEdge_=false;},mouseMoveAt_(worldX,y,mouseDown){if(mouseDown){this.updateMovingEdge_(worldX);return;}
+const ir=this.viewport_.interestRange;const dt=this.viewport_.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const nearnessThresholdWorld=dt.xViewVectorToWorld(6*pixelRatio);if(Math.abs(worldX-ir.min)<nearnessThresholdWorld){ir.leftSelected=true;ir.rightSelected=false;return;}
 if(Math.abs(worldX-ir.max)<nearnessThresholdWorld){ir.leftSelected=false;ir.rightSelected=true;return;}
-ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_:function(newWorldX){var ir=this.viewport_.interestRange;var a=ir.min;var b=ir.max;if(this.isMovingLeftEdge_){a=newWorldX;}else{b=newWorldX;}
+ir.leftSelected=false;ir.rightSelected=false;return;},updateMovingEdge_(newWorldX){const ir=this.viewport_.interestRange;let a=ir.min;let b=ir.max;if(this.isMovingLeftEdge_){a=newWorldX;}else{b=newWorldX;}
 if(a<=b){ir.setMinAndMax(a,b);}else{ir.setMinAndMax(b,a);}
-if(ir.min===newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_:function(){var dt=this.viewport_.currentDisplayTransform;var ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;var pixelRatio=window.devicePixelRatio||1;var minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue){ir.reset();}},getWorldXFromEvent_:function(e){var pixelRatio=window.devicePixelRatio||1;var canvas=this.viewport_.modelTrackContainer.canvas;var worldOffset=canvas.getBoundingClientRect().left;var viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_:function(e){var pixelRatio=window.devicePixelRatio||1;var EVENT_SNAP_RANGE=16*pixelRatio;var modelTrackContainer=this.viewport_.modelTrackContainer;var modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();var viewport=this.viewport_;var dt=viewport.currentDisplayTransform;var worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);var worldX=this.getWorldXFromEvent_(e);var mouseY=e.clientY;var selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
-var minDistX=worldMaxDist;var minDistY=Infinity;var pixWidth=dt.xViewVectorToWorld(1);var result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};var eventBounds=new tr.b.math.Range();for(var event of selection){var track=viewport.trackForEvent(event);var trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);var eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
-var distX=eventX-worldX;var eventY=trackRect.top;var eventHeight=trackRect.height;var distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
+if(ir.min===newWorldX){this.isMovingLeftEdge_=true;ir.leftSelected=true;ir.rightSelected=false;}else{this.isMovingLeftEdge_=false;ir.leftSelected=false;ir.rightSelected=true;}},mouseUp_(){const dt=this.viewport_.currentDisplayTransform;const ir=this.viewport_.interestRange;ir.leftSelected=false;ir.rightSelected=false;const pixelRatio=window.devicePixelRatio||1;const minWidthValue=dt.xViewVectorToWorld(2*pixelRatio);if(ir.range<minWidthValue){ir.reset();}},getWorldXFromEvent_(e){const pixelRatio=window.devicePixelRatio||1;const canvas=this.viewport_.modelTrackContainer.canvas;const worldOffset=canvas.getBoundingClientRect().left;const viewX=(e.clientX-worldOffset)*pixelRatio;return this.viewport_.currentDisplayTransform.xViewToWorld(viewX);},getSnappedToEventPosition_(e){const pixelRatio=window.devicePixelRatio||1;const EVENT_SNAP_RANGE=16*pixelRatio;const modelTrackContainer=this.viewport_.modelTrackContainer;const modelTrackContainerRect=modelTrackContainer.getBoundingClientRect();const viewport=this.viewport_;const dt=viewport.currentDisplayTransform;const worldMaxDist=dt.xViewVectorToWorld(EVENT_SNAP_RANGE);const worldX=this.getWorldXFromEvent_(e);const mouseY=e.clientY;const selection=new tr.model.EventSet();modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,mouseY,mouseY,selection);if(!selection.length){modelTrackContainer.addClosestEventToSelection(worldX,worldMaxDist,modelTrackContainerRect.top,modelTrackContainerRect.bottom,selection);}
+let minDistX=worldMaxDist;let minDistY=Infinity;const pixWidth=dt.xViewVectorToWorld(1);const result={x:worldX,y:mouseY-modelTrackContainerRect.top,height:0,snapped:false};const eventBounds=new tr.b.math.Range();for(const event of selection){const track=viewport.trackForEvent(event);const trackRect=track.getBoundingClientRect();eventBounds.reset();event.addBoundsToRange(eventBounds);let eventX;if(Math.abs(eventBounds.min-worldX)<Math.abs(eventBounds.max-worldX)){eventX=eventBounds.min;}else{eventX=eventBounds.max;}
+const distX=eventX-worldX;const eventY=trackRect.top;const eventHeight=trackRect.height;const distY=Math.abs(eventY+eventHeight/2-mouseY);if((distX<=minDistX||Math.abs(distX-minDistX)<pixWidth)&&distY<minDistY){minDistX=distX;minDistY=distY;result.x=eventX;result.y=eventY+
 modelTrackContainer.scrollTop-modelTrackContainerRect.top;result.height=eventHeight;result.snapped=true;}}
-return result;}};return{TimingTool,};});'use strict';tr.exportTo('tr.ui',function(){var kDefaultPanAnimationDurationMs=100.0;const lerp=tr.b.math.lerp;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
+return result;}};return{TimingTool,};});'use strict';tr.exportTo('tr.ui',function(){const kDefaultPanAnimationDurationMs=100.0;const lerp=tr.b.math.lerp;function TimelineDisplayTransformPanAnimation(deltaX,deltaY,opt_durationMs){this.deltaX=deltaX;this.deltaY=deltaY;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
 this.startPanX=undefined;this.startPanY=undefined;this.startTimeMs=undefined;}
-TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor:function(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor:function(existing,timestamp,target){var remainingDeltaXOnExisting=existing.goalPanX-target.panX;var remainingDeltaYOnExisting=existing.goalPanY-target.panY;var remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.panX=lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalPanY);}
+TimelineDisplayTransformPanAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.deltaY!==0;},canTakeOverFor(existingAnimation){return existingAnimation instanceof TimelineDisplayTransformPanAnimation;},takeOverFor(existing,timestamp,target){const remainingDeltaXOnExisting=existing.goalPanX-target.panX;const remainingDeltaYOnExisting=existing.goalPanY-target.panY;let remainingTimeOnExisting=timestamp-(existing.startTimeMs+existing.durationMs);remainingTimeOnExisting=Math.max(remainingTimeOnExisting,0);this.deltaX+=remainingDeltaXOnExisting;this.deltaY+=remainingDeltaYOnExisting;this.durationMs+=remainingTimeOnExisting;},start(timestamp,target){this.startTimeMs=timestamp;this.startPanX=target.panX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.panX=lerp(percentDone,this.startPanX,this.goalPanX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalPanY);}
 return timestamp>=this.startTimeMs+this.durationMs;},get goalPanX(){return this.startPanX+this.deltaX;},get goalPanY(){return this.startPanY+this.deltaY;}};function TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,goalFocalPointY,zoomInRatioX,opt_durationMs){this.goalFocalPointXWorld=goalFocalPointXWorld;this.goalFocalPointXView=goalFocalPointXView;this.goalFocalPointY=goalFocalPointY;this.zoomInRatioX=zoomInRatioX;if(opt_durationMs===undefined){this.durationMs=kDefaultPanAnimationDurationMs;}else{this.durationMs=opt_durationMs;}
 this.startTimeMs=undefined;this.startScaleX=undefined;this.goalScaleX=undefined;this.startPanY=undefined;}
-TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!==this.goalFocalPointY;},canTakeOverFor:function(existingAnimation){return false;},takeOverFor:function(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start:function(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick:function(timestamp,target){var percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.scaleX=lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalFocalPointY);}
-target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};var MAX_OVERSIZE_MULTIPLE=3.0;var REDRAW_SLOP=(MAX_OVERSIZE_MULTIPLE-1)/2;var DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';Polymer.dom(this).appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.offsetY_=0;this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);window.addEventListener('resize',this.windowResized_.bind(this));this.addEventListener('scroll',this.scrollChanged_.bind(this));},get canvas(){return this.canvas_;},context:function(){return this.ctx_;},viewportChange_:function(){this.invalidate();},windowResized_:function(){this.invalidate();},scrollChanged_:function(){if(this.updateOffsetY_()){this.invalidate();}},invalidate:function(){if(this.rafPending_)return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_:function(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_:function(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);var typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(var idx in typesToDraw){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+TimelineDisplayTransformZoomToAnimation.prototype={__proto__:tr.ui.b.Animation.prototype,get affectsPanY(){return this.startPanY!==this.goalFocalPointY;},canTakeOverFor(existingAnimation){return false;},takeOverFor(existingAnimation,timestamp,target){this.goalScaleX=target.scaleX*this.zoomInRatioX;},start(timestamp,target){this.startTimeMs=timestamp;this.startScaleX=target.scaleX;this.goalScaleX=this.zoomInRatioX*target.scaleX;this.startPanY=target.panY;},tick(timestamp,target){let percentDone=(timestamp-this.startTimeMs)/this.durationMs;percentDone=tr.b.math.clamp(percentDone,0,1);target.scaleX=lerp(percentDone,this.startScaleX,this.goalScaleX);if(this.affectsPanY){target.panY=lerp(percentDone,this.startPanY,this.goalFocalPointY);}
+target.xPanWorldPosToViewPos(this.goalFocalPointXWorld,this.goalFocalPointXView);return timestamp>=this.startTimeMs+this.durationMs;}};return{TimelineDisplayTransformPanAnimation,TimelineDisplayTransformZoomToAnimation,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const DrawType={GENERAL_EVENT:1,INSTANT_EVENT:2,BACKGROUND:3,GRID:4,FLOW_ARROWS:5,MARKERS:6,HIGHLIGHTS:7,ANNOTATIONS:8};const MAX_OVERSIZE_MULTIPLE=3.0;const REDRAW_SLOP=(MAX_OVERSIZE_MULTIPLE-1)/2;const DrawingContainer=tr.ui.b.define('drawing-container',tr.ui.tracks.Track);DrawingContainer.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('drawing-container');this.canvas_=document.createElement('canvas');this.canvas_.className='drawing-container-canvas';this.canvas_.style.left=tr.ui.b.constants.HEADING_WIDTH+'px';Polymer.dom(this).appendChild(this.canvas_);this.ctx_=this.canvas_.getContext('2d');this.offsetY_=0;this.viewportChange_=this.viewportChange_.bind(this);this.viewport.addEventListener('change',this.viewportChange_);window.addEventListener('resize',this.windowResized_.bind(this));this.addEventListener('scroll',this.scrollChanged_.bind(this));},get canvas(){return this.canvas_;},context(){return this.ctx_;},viewportChange_(){this.invalidate();},windowResized_(){this.invalidate();},scrollChanged_(){if(this.updateOffsetY_()){this.invalidate();}},invalidate(){if(this.rafPending_)return;this.rafPending_=true;tr.b.requestPreAnimationFrame(this.preDraw_,this);},preDraw_(){this.rafPending_=false;this.updateCanvasSizeIfNeeded_();tr.b.requestAnimationFrameInThisFrameIfPossible(this.draw_,this);},draw_(){this.ctx_.clearRect(0,0,this.canvas_.width,this.canvas_.height);const typesToDraw=[DrawType.BACKGROUND,DrawType.HIGHLIGHTS,DrawType.GRID,DrawType.INSTANT_EVENT,DrawType.GENERAL_EVENT,DrawType.MARKERS,DrawType.ANNOTATIONS,DrawType.FLOW_ARROWS];for(const idx in typesToDraw){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
 this.children[i].drawTrack(typesToDraw[idx]);}}
-var pixelRatio=window.devicePixelRatio||1;var bounds=this.canvas_.getBoundingClientRect();var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateOffsetY_:function(){var maxYDelta=window.innerHeight*REDRAW_SLOP;var newOffset=this.scrollTop-maxYDelta;if(Math.abs(newOffset-this.offsetY_)<=maxYDelta)return false;var maxOffset=this.scrollHeight-
+const pixelRatio=window.devicePixelRatio||1;const bounds=this.canvas_.getBoundingClientRect();const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);this.viewport.drawGridLines(this.ctx_,viewLWorld,viewRWorld);},updateOffsetY_(){const maxYDelta=window.innerHeight*REDRAW_SLOP;let newOffset=this.scrollTop-maxYDelta;if(Math.abs(newOffset-this.offsetY_)<=maxYDelta)return false;const maxOffset=this.scrollHeight-
 this.canvas_.getBoundingClientRect().height;newOffset=Math.max(0,Math.min(newOffset,maxOffset));if(newOffset!==this.offsetY_){this.offsetY_=newOffset;return true;}
-return false;},updateCanvasSizeIfNeeded_:function(){var visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);if(visibleChildTracks.length===0){return;}
-var thisBounds=this.getBoundingClientRect();var firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();var lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();var innerWidth=firstChildTrackBounds.width-
-tr.ui.b.constants.HEADING_WIDTH;var innerHeight=lastChildTrackBounds.bottom-firstChildTrackBounds.top;var innerHeight=Math.min(innerHeight,Math.floor(window.innerHeight*MAX_OVERSIZE_MULTIPLE));var pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!==innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
+return false;},updateCanvasSizeIfNeeded_(){const visibleChildTracks=tr.b.asArray(this.children).filter(this.visibleFilter_);if(visibleChildTracks.length===0){return;}
+const thisBounds=this.getBoundingClientRect();const firstChildTrackBounds=visibleChildTracks[0].getBoundingClientRect();const lastChildTrackBounds=visibleChildTracks[visibleChildTracks.length-1].getBoundingClientRect();const innerWidth=firstChildTrackBounds.width-
+tr.ui.b.constants.HEADING_WIDTH;const innerHeight=Math.min(lastChildTrackBounds.bottom-firstChildTrackBounds.top,Math.floor(window.innerHeight*MAX_OVERSIZE_MULTIPLE));const pixelRatio=window.devicePixelRatio||1;if(this.canvas_.width!==innerWidth*pixelRatio){this.canvas_.width=innerWidth*pixelRatio;this.canvas_.style.width=innerWidth+'px';}
 if(this.canvas_.height!==innerHeight*pixelRatio){this.canvas_.height=innerHeight*pixelRatio;this.canvas_.style.height=innerHeight+'px';}
-if(this.canvas_.top!==this.offsetY_){this.canvas_.top=this.offsetY_;this.canvas_.style.top=this.offsetY_+'px';}},visibleFilter_:function(element){if(!(element instanceof tr.ui.tracks.Track))return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
-var trackClientRect=this.children[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
-this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer,DrawType,};});'use strict';tr.exportTo('tr.model',function(){var SelectableItem=tr.model.SelectableItem;var SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);}
-ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){var modelItem=this.modelItem_;if(modelItem===undefined){return SelectionState.NONE;}
-return modelItem.selectionState;}};return{ProxySelectableItem,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw:function(type,viewLWorld,viewRWorld){if(this.items_===undefined)return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var height=bounds.height*pixelRatio;var halfHeight=height*0.5;var twoPi=Math.PI*2;var dt=this.viewport.currentDisplayTransform;var dumpRadiusView=this.dumpRadiusView;var itemRadiusWorld=dt.xViewVectorToWorld(height);var items=this.items_;var loI=tr.b.math.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);var oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';var drawItems=function(selected){for(var i=loI;i<items.length;++i){var item=items[i];var x=item.start;if(x-itemRadiusWorld>viewRWorld)break;if(item.selected!==selected)continue;var xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
-ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap:function(eventToTrackMap){if(this.items_===undefined)return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)return;var itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.math.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.items_===undefined)return;var items=this.items_;var index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)return false;var newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
-return false;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)return;var item=tr.b.math.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;}
-LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack,LetterDot,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
-this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Task=tr.b.Task;var ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach:function(){Polymer.dom(this).textContent='';},get tracks_(){var tracks=[];for(var i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track){tracks.push(this.children[i]);}}
-return tracks;},drawTrack:function(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap:function(eventToTrackMap){for(var track of this.tracks_){track.addEventsToTrackMap(eventToTrackMap);}},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.tracks_.length;i++){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var task=new Task();for(var i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);};}(i),this);}
-return task;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){for(var i=0;i<this.tracks_.length;i++){var trackClientRect=this.tracks_[i].getBoundingClientRect();var a=Math.max(loY,trackClientRect.top);var b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
-tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap:function(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_:function(){this.tracks_.forEach(function(track){Polymer.dom(this).removeChild(track);},this);}};return{ContainerTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.dotLetter=undefined;this.yBase=opt_yBase;}
-ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype,};return{ChartPoint,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var EventPresenter=tr.ui.b.EventPresenter;var SelectionState=tr.model.SelectionState;var ChartSeriesType={LINE:0,AREA:1};var DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,solidSelectedDots:false,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5,stepGraph:true};var LAST_POINT_WIDTH=16;var DOT_LETTER_RADIUS_PX=7;var DOT_LETTER_RADIUS_PADDING_PX=0.5;var DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX=3;var DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX=1.5;var DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX=1;var DOT_LETTER_FONT_WEIGHT=400;var DOT_LETTER_FONT_SIZE_PX=9;var DOT_LETTER_FONT='Arial';var ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,seriesYAxis,opt_renderingConfig){this.points=points;this.seriesYAxis=seriesYAxis;this.useRenderingConfig_(opt_renderingConfig);}
-ChartSeries.prototype={useRenderingConfig_:function(opt_renderingConfig){var config=opt_renderingConfig||{};for(var[key,defaultValue]of
-Object.entries(DEFAULT_RENDERING_CONFIG)){var value=config[key];if(value===undefined){value=defaultValue;}
+if(this.canvas_.top!==this.offsetY_){this.canvas_.top=this.offsetY_;this.canvas_.style.top=this.offsetY_+'px';}},visibleFilter_(element){if(!(element instanceof tr.ui.tracks.Track))return false;return window.getComputedStyle(element).display!=='none';},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+const trackClientRect=this.children[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.children[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)){continue;}
+this.children[i].addEventsToTrackMap(eventToTrackMap);}}};return{DrawingContainer,DrawType,};});'use strict';tr.exportTo('tr.model',function(){const SelectableItem=tr.model.SelectableItem;const SelectionState=tr.model.SelectionState;function ProxySelectableItem(modelItem){SelectableItem.call(this,modelItem);}
+ProxySelectableItem.prototype={__proto__:SelectableItem.prototype,get selectionState(){const modelItem=this.modelItem_;if(modelItem===undefined){return SelectionState.NONE;}
+return modelItem.selectionState;}};return{ProxySelectableItem,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const LetterDotTrack=tr.ui.b.define('letter-dot-track',tr.ui.tracks.Track);LetterDotTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('letter-dot-track');this.items_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get items(){return this.items_;},set items(items){this.items_=items;this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;},get dumpRadiusView(){return 7*(window.devicePixelRatio||1);},draw(type,viewLWorld,viewRWorld){if(this.items_===undefined)return;switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawLetterDots_(viewLWorld,viewRWorld);break;}},drawLetterDots_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const height=bounds.height*pixelRatio;const halfHeight=height*0.5;const twoPi=Math.PI*2;const dt=this.viewport.currentDisplayTransform;const dumpRadiusView=this.dumpRadiusView;const itemRadiusWorld=dt.xViewVectorToWorld(height);const items=this.items_;const loI=tr.b.math.findLowIndexInSortedArray(items,function(item){return item.start;},viewLWorld);const oldFont=ctx.font;ctx.font='400 '+Math.floor(9*pixelRatio)+'px Arial';ctx.strokeStyle='rgb(0,0,0)';ctx.textBaseline='middle';ctx.textAlign='center';const drawItems=function(selected){for(let i=loI;i<items.length;++i){const item=items[i];const x=item.start;if(x-itemRadiusWorld>viewRWorld)break;if(item.selected!==selected)continue;const xView=dt.xWorldToView(x);ctx.fillStyle=EventPresenter.getSelectableItemColorAsString(item);ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView+0.5,0,twoPi);ctx.fill();if(item.selected){ctx.lineWidth=3;ctx.strokeStyle='rgb(100,100,0)';ctx.stroke();ctx.beginPath();ctx.arc(xView,halfHeight,dumpRadiusView,0,twoPi);ctx.lineWidth=1.5;ctx.strokeStyle='rgb(255,255,0)';ctx.stroke();}else{ctx.lineWidth=1;ctx.strokeStyle='rgb(0,0,0)';ctx.stroke();}
+ctx.fillStyle='rgb(255, 255, 255)';ctx.fillText(item.dotLetter,xView,halfHeight);}};drawItems(false);drawItems(true);ctx.lineWidth=1;ctx.font=oldFont;},addEventsToTrackMap(eventToTrackMap){if(this.items_===undefined)return;this.items_.forEach(function(item){item.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){if(this.items_===undefined)return;const itemRadiusWorld=viewPixWidthWorld*this.dumpRadiusView;tr.b.math.iterateOverIntersectingIntervals(this.items_,function(x){return x.start-itemRadiusWorld;},function(x){return 2*itemRadiusWorld;},loWX,hiWX,function(item){item.addToSelection(selection);}.bind(this));},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.items_===undefined)return;const items=this.items_;const index=tr.b.findFirstIndexInArray(items,function(item){return item.modelItem===event;});if(index===-1)return false;const newIndex=index+offset;if(newIndex>=0&&newIndex<items.length){items[newIndex].addToSelection(selection);return true;}
+return false;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.items_===undefined)return;const item=tr.b.math.findClosestElementInSortedArray(this.items_,function(x){return x.start;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};function LetterDot(modelItem,dotLetter,colorId,start){tr.model.ProxySelectableItem.call(this,modelItem);this.dotLetter=dotLetter;this.colorId=colorId;this.start=start;}
+LetterDot.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{LetterDotTrack,LetterDot,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AlertTrack=tr.ui.b.define('alert-track',tr.ui.tracks.LetterDotTrack);AlertTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Alerts';this.alerts_=undefined;},get alerts(){return this.alerts_;},set alerts(alerts){this.alerts_=alerts;if(alerts===undefined){this.items=undefined;return;}
+this.items=this.alerts_.map(function(alert){return new tr.ui.tracks.LetterDot(alert,String.fromCharCode(9888),alert.colorId,alert.start);});}};return{AlertTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Task=tr.b.Task;const ContainerTrack=tr.ui.b.define('container-track',tr.ui.tracks.Track);ContainerTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);},detach(){Polymer.dom(this).textContent='';},get tracks_(){const tracks=[];for(let i=0;i<this.children.length;i++){if(this.children[i]instanceof tr.ui.tracks.Track){tracks.push(this.children[i]);}}
+return tracks;},drawTrack(type){this.tracks_.forEach(function(track){track.drawTrack(type);});},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addIntersectingEventsInRangeToSelection.apply(this,arguments);},addEventsToTrackMap(eventToTrackMap){for(const track of this.tracks_){track.addEventsToTrackMap(eventToTrackMap);}},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.tracks_.length;i++){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);}},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const task=new Task();for(let i=0;i<this.tracks_.length;i++){task.subTask(function(i){return function(){this.tracks_[i].addAllEventsMatchingFilterToSelection(filter,selection);};}(i),this);}
+return task;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){for(let i=0;i<this.tracks_.length;i++){const trackClientRect=this.tracks_[i].getBoundingClientRect();const a=Math.max(loY,trackClientRect.top);const b=Math.min(hiY,trackClientRect.bottom);if(a<=b){this.tracks_[i].addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);}}
+tr.ui.tracks.Track.prototype.addClosestEventToSelection.apply(this,arguments);},addContainersToTrackMap(containerToTrackMap){this.tracks_.forEach(function(track){track.addContainersToTrackMap(containerToTrackMap);});},clearTracks_(){this.tracks_.forEach(function(track){Polymer.dom(this).removeChild(track);},this);}};return{ContainerTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartPoint(modelItem,x,y,opt_yBase){tr.model.ProxySelectableItem.call(this,modelItem);this.x=x;this.y=y;this.dotLetter=undefined;this.yBase=opt_yBase;}
+ChartPoint.prototype={__proto__:tr.model.ProxySelectableItem.prototype,};return{ChartPoint,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const SelectionState=tr.model.SelectionState;const ChartSeriesType={LINE:0,AREA:1};const DEFAULT_RENDERING_CONFIG={chartType:ChartSeriesType.LINE,selectedPointSize:4,unselectedPointSize:3,solidSelectedDots:false,colorId:0,lineWidth:1,skipDistance:1,unselectedPointDensityTransparent:0.10,unselectedPointDensityOpaque:0.05,backgroundOpacity:0.5,stepGraph:true};const LAST_POINT_WIDTH=16;const DOT_LETTER_RADIUS_PX=7;const DOT_LETTER_RADIUS_PADDING_PX=0.5;const DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX=3;const DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX=1.5;const DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX=1;const DOT_LETTER_FONT_WEIGHT=400;const DOT_LETTER_FONT_SIZE_PX=9;const DOT_LETTER_FONT='Arial';const ChartSeriesComponent={BACKGROUND:0,LINE:1,DOTS:2};function ChartSeries(points,seriesYAxis,opt_renderingConfig){this.points=points;this.seriesYAxis=seriesYAxis;this.useRenderingConfig_(opt_renderingConfig);}
+ChartSeries.prototype={useRenderingConfig_(opt_renderingConfig){const config=opt_renderingConfig||{};for(const[key,defaultValue]of
+Object.entries(DEFAULT_RENDERING_CONFIG)){let value=config[key];if(value===undefined){value=defaultValue;}
 this[key+'_']=value;}
-this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){var range=new tr.b.math.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw:function(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0){return;}
+this.topPadding=this.bottomPadding=Math.max(this.selectedPointSize_,this.unselectedPointSize_)/2;},get range(){const range=new tr.b.math.Range();this.points.forEach(function(point){range.addValue(point.y);},this);return range;},draw(ctx,transform,highDetails){if(this.points===undefined||this.points.length===0){return;}
 if(this.chartType_===ChartSeriesType.AREA){this.drawComponent_(ctx,transform,ChartSeriesComponent.BACKGROUND,highDetails);}
 if(this.chartType_===ChartSeriesType.LINE||highDetails){this.drawComponent_(ctx,transform,ChartSeriesComponent.LINE,highDetails);}
-this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_:function(ctx,transform,component,highDetails){var extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
-var pixelRatio=transform.pixelRatio;var leftViewX=transform.leftViewX-extraPixels*pixelRatio;var rightViewX=transform.rightViewX+extraPixels*pixelRatio;var leftTimestamp=transform.leftTimestamp-extraPixels;var rightTimestamp=transform.rightTimestamp+extraPixels;var firstVisibleIndex=tr.b.math.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);var lastVisibleIndex=tr.b.math.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
-var viewSkipDistance=this.skipDistance_*pixelRatio;var selectedCircleRadius;var letterDotRadius;var squareSize;var squareHalfSize;var squareOpacity;var unselectedSeriesColor;var currentStateSeriesColor;ctx.save();ctx.font=DOT_LETTER_FONT_WEIGHT+' '+
+this.drawComponent_(ctx,transform,ChartSeriesComponent.DOTS,highDetails);},drawComponent_(ctx,transform,component,highDetails){let extraPixels=0;if(component===ChartSeriesComponent.DOTS){extraPixels=Math.max(this.selectedPointSize_,this.unselectedPointSize_);}
+const pixelRatio=transform.pixelRatio;const leftViewX=transform.leftViewX-extraPixels*pixelRatio;const rightViewX=transform.rightViewX+extraPixels*pixelRatio;const leftTimestamp=transform.leftTimestamp-extraPixels;const rightTimestamp=transform.rightTimestamp+extraPixels;const firstVisibleIndex=tr.b.math.findLowIndexInSortedArray(this.points,function(point){return point.x;},leftTimestamp);let lastVisibleIndex=tr.b.math.findLowIndexInSortedArray(this.points,function(point){return point.x;},rightTimestamp);if(lastVisibleIndex>=this.points.length||this.points[lastVisibleIndex].x>rightTimestamp){lastVisibleIndex--;}
+const viewSkipDistance=this.skipDistance_*pixelRatio;let selectedCircleRadius;let letterDotRadius;let squareSize;let squareHalfSize;let squareOpacity;let unselectedSeriesColor;let currentStateSeriesColor;ctx.save();ctx.font=DOT_LETTER_FONT_WEIGHT+' '+
 Math.floor(DOT_LETTER_FONT_SIZE_PX*pixelRatio)+'px '+
-DOT_LETTER_FONT;ctx.textBaseline='middle';ctx.textAlign='center';switch(component){case ChartSeriesComponent.DOTS:selectedCircleRadius=(this.selectedPointSize_/2)*pixelRatio;letterDotRadius=Math.max(selectedCircleRadius,DOT_LETTER_RADIUS_PX*pixelRatio);squareSize=this.unselectedPointSize_*pixelRatio;squareHalfSize=squareSize/2;unselectedSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);if(!highDetails){squareOpacity=0;break;}
-var visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
-var visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
+DOT_LETTER_FONT;ctx.textBaseline='middle';ctx.textAlign='center';switch(component){case ChartSeriesComponent.DOTS:{selectedCircleRadius=(this.selectedPointSize_/2)*pixelRatio;letterDotRadius=Math.max(selectedCircleRadius,DOT_LETTER_RADIUS_PX*pixelRatio);squareSize=this.unselectedPointSize_*pixelRatio;squareHalfSize=squareSize/2;unselectedSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);if(!highDetails){squareOpacity=0;break;}
+const visibleIndexRange=lastVisibleIndex-firstVisibleIndex;if(visibleIndexRange<=0){squareOpacity=1;break;}
+const visibleViewXRange=transform.worldXToViewX(this.points[lastVisibleIndex].x)-
 transform.worldXToViewX(this.points[firstVisibleIndex].x);if(visibleViewXRange===0){squareOpacity=1;break;}
-var density=visibleIndexRange/visibleViewXRange;var clampedDensity=tr.b.math.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);var densityRange=this.unselectedPointDensityTransparent_-
-this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
-var previousViewX=undefined;var previousViewY=undefined;var previousViewYBase=undefined;var lastSelectionState=undefined;var baseSteps=undefined;var startIndex=Math.max(firstVisibleIndex-1,0);for(var i=startIndex;i<this.points.length;i++){var currentPoint=this.points[i];var currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
+const density=visibleIndexRange/visibleViewXRange;const clampedDensity=tr.b.math.clamp(density,this.unselectedPointDensityOpaque_,this.unselectedPointDensityTransparent_);const densityRange=this.unselectedPointDensityTransparent_-
+this.unselectedPointDensityOpaque_;squareOpacity=(this.unselectedPointDensityTransparent_-clampedDensity)/densityRange;break;}
+case ChartSeriesComponent.LINE:ctx.strokeStyle=EventPresenter.getCounterSeriesColor(this.colorId_,SelectionState.NONE);ctx.lineWidth=this.lineWidth_*pixelRatio;break;case ChartSeriesComponent.BACKGROUND:break;default:throw new Error('Invalid component: '+component);}
+let previousViewX=undefined;let previousViewY=undefined;let previousViewYBase=undefined;let lastSelectionState=undefined;let baseSteps=undefined;const startIndex=Math.max(firstVisibleIndex-1,0);let currentViewX;for(let i=startIndex;i<this.points.length;i++){const currentPoint=this.points[i];currentViewX=transform.worldXToViewX(currentPoint.x);if(currentViewX>rightViewX){if(previousViewX!==undefined){previousViewX=currentViewX=rightViewX;if(component===ChartSeriesComponent.BACKGROUND||component===ChartSeriesComponent.LINE){ctx.lineTo(currentViewX,previousViewY);}}
 break;}
-if(i+1<this.points.length){var nextPoint=this.points[i+1];var nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
+if(i+1<this.points.length){const nextPoint=this.points[i+1];const nextViewX=transform.worldXToViewX(nextPoint.x);if(previousViewX!==undefined&&nextViewX-previousViewX<=viewSkipDistance&&nextViewX<rightViewX){continue;}
 if(currentViewX<leftViewX){currentViewX=leftViewX;}}
 if(previousViewX!==undefined&&currentViewX-previousViewX<viewSkipDistance){currentViewX=previousViewX+viewSkipDistance;}
-var currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));var currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
-var currentSelectionState=currentPoint.selectionState;if(currentSelectionState!==lastSelectionState){var opacity=currentSelectionState===SelectionState.SELECTED?1:squareOpacity;currentStateSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,opacity);}
+const currentViewY=Math.round(transform.worldYToViewY(currentPoint.y));let currentViewYBase;if(currentPoint.yBase===undefined){currentViewYBase=transform.outerBottomViewY;}else{currentViewYBase=Math.round(transform.worldYToViewY(currentPoint.yBase));}
+const currentSelectionState=currentPoint.selectionState;if(currentSelectionState!==lastSelectionState){const opacity=currentSelectionState===SelectionState.SELECTED?1:squareOpacity;currentStateSeriesColor=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,opacity);}
 switch(component){case ChartSeriesComponent.DOTS:if(currentPoint.dotLetter){ctx.fillStyle=unselectedSeriesColor;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.beginPath();ctx.arc(currentViewX,currentViewY,letterDotRadius+DOT_LETTER_RADIUS_PADDING_PX,0,2*Math.PI);ctx.fill();if(currentSelectionState===SelectionState.SELECTED){ctx.lineWidth=DOT_LETTER_SELECTED_OUTLINE_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('olive');ctx.stroke();ctx.beginPath();ctx.arc(currentViewX,currentViewY,letterDotRadius,0,2*Math.PI);ctx.lineWidth=DOT_LETTER_SELECTED_OUTLINE_DETAIL_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('yellow');ctx.stroke();}else{ctx.lineWidth=DOT_LETTER_UNSELECTED_OUTLINE_WIDTH_PX;ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.stroke();}
 ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('white');ctx.fillText(currentPoint.dotLetter,currentViewX,currentViewY);}else{ctx.strokeStyle=unselectedSeriesColor;ctx.lineWidth=pixelRatio;if(currentSelectionState===SelectionState.SELECTED){if(this.solidSelectedDots_){ctx.fillStyle=ctx.strokeStyle;}else{ctx.fillStyle=currentStateSeriesColor;}
 ctx.beginPath();ctx.arc(currentViewX,currentViewY,selectedCircleRadius,0,2*Math.PI);ctx.fill();ctx.stroke();}else if(squareOpacity>0){ctx.fillStyle=currentStateSeriesColor;ctx.fillRect(currentViewX-squareHalfSize,currentViewY-squareHalfSize,squareSize,squareSize);}}
 break;case ChartSeriesComponent.LINE:if(previousViewX===undefined){ctx.beginPath();ctx.moveTo(currentViewX,currentViewY);}else if(this.stepGraph_){ctx.lineTo(currentViewX,previousViewY);}
 ctx.lineTo(currentViewX,currentViewY);break;case ChartSeriesComponent.BACKGROUND:if(previousViewX!==undefined&&this.stepGraph_){ctx.lineTo(currentViewX,previousViewY);}else{ctx.lineTo(currentViewX,currentViewY);}
-if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+if(currentSelectionState!==lastSelectionState){if(previousViewX!==undefined){let previousBaseStepViewX=currentViewX;for(let j=baseSteps.length-1;j>=0;j--){const baseStep=baseSteps[j];const baseStepViewX=baseStep.viewX;const baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
 ctx.closePath();ctx.fill();}
 ctx.beginPath();ctx.fillStyle=EventPresenter.getCounterSeriesColor(this.colorId_,currentSelectionState,this.backgroundOpacity_);ctx.moveTo(currentViewX,currentViewYBase);baseSteps=[];}
 if(currentViewYBase!==previousViewYBase||currentSelectionState!==lastSelectionState){baseSteps.push({viewX:currentViewX,viewY:currentViewYBase});}
 ctx.lineTo(currentViewX,currentViewY);break;default:throw new Error('Not reachable');}
 previousViewX=currentViewX;previousViewY=currentViewY;previousViewYBase=currentViewYBase;lastSelectionState=currentSelectionState;}
-if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:var previousBaseStepViewX=currentViewX;for(var j=baseSteps.length-1;j>=0;j--){var baseStep=baseSteps[j];var baseStepViewX=baseStep.viewX;var baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
-ctx.closePath();ctx.fill();break;default:throw new Error('Not reachable');}}
-ctx.restore();},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){var points=this.points;function getPointWidth(point,i){if(i===points.length-1){return LAST_POINT_WIDTH*viewPixWidthWorld;}
-var nextPoint=points[i+1];return nextPoint.x-point.x;}
+if(previousViewX!==undefined){switch(component){case ChartSeriesComponent.DOTS:break;case ChartSeriesComponent.LINE:ctx.stroke();break;case ChartSeriesComponent.BACKGROUND:{let previousBaseStepViewX=currentViewX;for(let j=baseSteps.length-1;j>=0;j--){const baseStep=baseSteps[j];const baseStepViewX=baseStep.viewX;const baseStepViewY=baseStep.viewY;ctx.lineTo(previousBaseStepViewX,baseStepViewY);ctx.lineTo(baseStepViewX,baseStepViewY);previousBaseStepViewX=baseStepViewX;}
+ctx.closePath();ctx.fill();break;}
+default:throw new Error('Not reachable');}}
+ctx.restore();},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){const points=this.points;function getPointWidth(point,i){if(i===points.length-1){return LAST_POINT_WIDTH*viewPixWidthWorld;}
+const nextPoint=points[i+1];return nextPoint.x-point.x;}
 function selectPoint(point){point.addToSelection(selection);}
-tr.b.math.iterateOverIntersectingIntervals(this.points,function(point){return point.x;},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection:function(event,offset,selection){if(this.points===undefined)return false;var index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)return;var item=tr.b.math.findClosestElementInSortedArray(this.points,function(point){return point.x;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};return{ChartSeries,ChartSeriesType,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var IDEAL_MAJOR_MARK_HEIGHT_PX=30;var AXIS_LABLE_MARGIN_PX=10;var AXIS_LABLE_FONT_SIZE_PX=9;var AXIS_LABLE_FONT='Arial';function ChartSeriesYAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocateSimple();this.bounds=new tr.b.math.Range();if(opt_min!==undefined)this.bounds.addValue(opt_min);if(opt_max!==undefined)this.bounds.addValue(opt_max);}
-ChartSeriesYAxis.prototype={get guid(){return this.guid_;},valueToUnitRange:function(value){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
-var bounds=this.bounds;if(bounds.range===0)return 0;return(value-bounds.min)/bounds.range;},unitRangeToValue:function(unitRange){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
-return unitRange*this.bounds.range+this.bounds.min;},autoSetFromSeries:function(series,opt_config){var range=new tr.b.math.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange:function(range,opt_config){if(range.isEmpty)return;var bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
-if(!opt_config)return;var useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);var useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
-if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}},majorMarkHeightWorld_:function(transform,pixelRatio){var idealMajorMarkHeightPx=IDEAL_MAJOR_MARK_HEIGHT_PX*pixelRatio;var idealMajorMarkHeightWorld=transform.vectorToWorldDistance(idealMajorMarkHeightPx);return tr.b.math.preferredNumberLargerThanMin(idealMajorMarkHeightWorld);},draw:function(ctx,transform,showYAxisLabels,showYGridLines){if(!showYAxisLabels&&!showYGridLines)return;var pixelRatio=transform.pixelRatio;var viewTop=transform.outerTopViewY;var worldTop=transform.viewYToWorldY(viewTop);var viewBottom=transform.outerBottomViewY;var viewHeight=viewBottom-viewTop;var viewLeft=transform.leftViewX;var viewRight=transform.rightViewX;var labelLeft=transform.leftYLabel;ctx.save();ctx.lineWidth=pixelRatio;ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.textAlign='left';ctx.textBaseline='center';ctx.font=(AXIS_LABLE_FONT_SIZE_PX*pixelRatio)+'px '+AXIS_LABLE_FONT;ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');tr.ui.b.drawLine(ctx,viewLeft,viewTop,viewLeft,viewBottom,viewLeft);ctx.stroke();ctx.closePath();ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('grey');var majorMarkHeight=this.majorMarkHeightWorld_(transform,pixelRatio);var maxMajorMark=Math.max(transform.viewYToWorldY(viewTop),Math.abs(transform.viewYToWorldY(viewBottom)));for(var curWorldY=0;curWorldY<=maxMajorMark;curWorldY+=majorMarkHeight){var roundedUnitValue=Math.floor(curWorldY*1000000)/1000000;var curViewYPositive=transform.worldYToViewY(curWorldY);if(curViewYPositive>=viewTop){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYPositive-AXIS_LABLE_MARGIN_PX);}
+tr.b.math.iterateOverIntersectingIntervals(this.points,function(point){return point.x;},getPointWidth,loWX,hiWX,selectPoint);},addEventNearToProvidedEventToSelection(event,offset,selection){if(this.points===undefined)return false;const index=tr.b.findFirstIndexInArray(this.points,function(point){return point.modelItem===event;},this);if(index===-1)return false;const newIndex=index+offset;if(newIndex<0||newIndex>=this.points.length)return false;this.points[newIndex].addToSelection(selection);return true;},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){if(this.points===undefined)return;const item=tr.b.math.findClosestElementInSortedArray(this.points,function(point){return point.x;},worldX,worldMaxDist);if(!item)return;item.addToSelection(selection);}};return{ChartSeries,ChartSeriesType,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const IDEAL_MAJOR_MARK_HEIGHT_PX=30;const AXIS_LABLE_MARGIN_PX=10;const AXIS_LABLE_FONT_SIZE_PX=9;const AXIS_LABLE_FONT='Arial';function ChartSeriesYAxis(opt_min,opt_max){this.guid_=tr.b.GUID.allocateSimple();this.bounds=new tr.b.math.Range();if(opt_min!==undefined)this.bounds.addValue(opt_min);if(opt_max!==undefined)this.bounds.addValue(opt_max);}
+ChartSeriesYAxis.prototype={get guid(){return this.guid_;},valueToUnitRange(value){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
+const bounds=this.bounds;if(bounds.range===0)return 0;return(value-bounds.min)/bounds.range;},unitRangeToValue(unitRange){if(this.bounds.isEmpty){throw new Error('Chart series y-axis bounds are empty');}
+return unitRange*this.bounds.range+this.bounds.min;},autoSetFromSeries(series,opt_config){const range=new tr.b.math.Range();series.forEach(function(s){range.addRange(s.range);},this);this.autoSetFromRange(range,opt_config);},autoSetFromRange(range,opt_config){if(range.isEmpty)return;const bounds=this.bounds;if(bounds.isEmpty){bounds.addRange(range);return;}
+if(!opt_config)return;const useRangeMin=(opt_config.expandMin&&range.min<bounds.min||opt_config.shrinkMin&&range.min>bounds.min);const useRangeMax=(opt_config.expandMax&&range.max>bounds.max||opt_config.shrinkMax&&range.max<bounds.max);if(!useRangeMin&&!useRangeMax)return;if(useRangeMin&&useRangeMax){bounds.min=range.min;bounds.max=range.max;return;}
+if(useRangeMin){bounds.min=Math.min(range.min,bounds.max);}else{bounds.max=Math.max(range.max,bounds.min);}},majorMarkHeightWorld_(transform,pixelRatio){const idealMajorMarkHeightPx=IDEAL_MAJOR_MARK_HEIGHT_PX*pixelRatio;const idealMajorMarkHeightWorld=transform.vectorToWorldDistance(idealMajorMarkHeightPx);return tr.b.math.preferredNumberLargerThanMin(idealMajorMarkHeightWorld);},draw(ctx,transform,showYAxisLabels,showYGridLines){if(!showYAxisLabels&&!showYGridLines)return;const pixelRatio=transform.pixelRatio;const viewTop=transform.outerTopViewY;const worldTop=transform.viewYToWorldY(viewTop);const viewBottom=transform.outerBottomViewY;const viewHeight=viewBottom-viewTop;const viewLeft=transform.leftViewX;const viewRight=transform.rightViewX;const labelLeft=transform.leftYLabel;ctx.save();ctx.lineWidth=pixelRatio;ctx.fillStyle=ColorScheme.getColorForReservedNameAsString('black');ctx.textAlign='left';ctx.textBaseline='center';ctx.font=(AXIS_LABLE_FONT_SIZE_PX*pixelRatio)+'px '+AXIS_LABLE_FONT;ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('black');tr.ui.b.drawLine(ctx,viewLeft,viewTop,viewLeft,viewBottom,viewLeft);ctx.stroke();ctx.closePath();ctx.beginPath();ctx.strokeStyle=ColorScheme.getColorForReservedNameAsString('grey');const majorMarkHeight=this.majorMarkHeightWorld_(transform,pixelRatio);const maxMajorMark=Math.max(transform.viewYToWorldY(viewTop),Math.abs(transform.viewYToWorldY(viewBottom)));for(let curWorldY=0;curWorldY<=maxMajorMark;curWorldY+=majorMarkHeight){const roundedUnitValue=Math.floor(curWorldY*1000000)/1000000;const curViewYPositive=transform.worldYToViewY(curWorldY);if(curViewYPositive>=viewTop){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYPositive-AXIS_LABLE_MARGIN_PX);}
 if(showYGridLines){tr.ui.b.drawLine(ctx,viewLeft,curViewYPositive,viewRight,curViewYPositive);}}
-var curViewYNegative=transform.worldYToViewY(-1*curWorldY);if(curViewYNegative<=viewBottom){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYNegative-AXIS_LABLE_MARGIN_PX);}
+const curViewYNegative=transform.worldYToViewY(-1*curWorldY);if(curViewYNegative<=viewBottom){if(showYAxisLabels){ctx.fillText(roundedUnitValue,viewLeft+AXIS_LABLE_MARGIN_PX,curViewYNegative-AXIS_LABLE_MARGIN_PX);}
 if(showYGridLines){tr.ui.b.drawLine(ctx,viewLeft,curViewYNegative,viewRight,curViewYNegative);}}}
 ctx.stroke();ctx.restore();}};return{ChartSeriesYAxis,};});'use strict';tr.exportTo('tr.ui.tracks',function(){function ChartTransform(displayTransform,axis,trackWidth,trackHeight,topPadding,bottomPadding,pixelRatio){this.pixelRatio=pixelRatio;this.leftViewX=0;this.rightViewX=trackWidth;this.leftTimestamp=displayTransform.xViewToWorld(this.leftViewX);this.rightTimestamp=displayTransform.xViewToWorld(this.rightViewX);this.displayTransform_=displayTransform;this.outerTopViewY=0;this.innerTopViewY=topPadding;this.innerBottomViewY=trackHeight-bottomPadding;this.outerBottomViewY=trackHeight;this.axis_=axis;this.innerHeight_=this.innerBottomViewY-this.innerTopViewY;}
-ChartTransform.prototype={worldXToViewX:function(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX:function(viewX){return this.displayTransform_.xViewToWorld(viewX);},vectorToWorldDistance:function(viewY){return this.axis_.bounds.range*Math.abs(viewY/this.innerHeight_);},viewYToWorldY:function(viewY){return this.axis_.unitRangeToValue(1-(viewY-this.innerTopViewY)/this.innerHeight_);},worldYToViewY:function(worldY){var innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('chart-track');this.series_=undefined;this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.showYAxisLabels_=undefined;this.showGridLines_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get showYAxisLabels(){return this.showYAxisLabels_;},set showYAxisLabels(showYAxisLabels){this.showYAxisLabels_=showYAxisLabels;this.invalidateDrawingContainer();},get showGridLines(){return this.showGridLines_;},set showGridLines(showGridLines){this.showGridLines_=showGridLines;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_:function(){if(!this.series_){this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
-var axisGuidToAxisData={};var topPadding=0;var bottomPadding=0;this.series_.forEach(function(series){var seriesYAxis=series.seriesYAxis;var axisGuid=seriesYAxis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:seriesYAxis,series:[]};if(!this.axes_)this.axes_=[];this.axes_.push(seriesYAxis);}
-axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_:function(viewLWorld,viewRWorld){if(!this.series_)return;var ctx=this.context();var displayTransform=this.viewport.currentDisplayTransform;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var highDetails=this.viewport.highDetails;var width=bounds.width*pixelRatio;var height=bounds.height*pixelRatio;var topPadding=this.topPadding_*pixelRatio;var bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();if(this.axes_){if((this.showGridLines_||this.showYAxisLabels_)&&this.axes_.length>1){throw new Error('Only one axis allowed when showing grid lines.');}
-for(var yAxis of this.axes_){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,yAxis,width,height,topPadding,bottomPadding,pixelRatio);yAxis.draw(ctx,chartTransform,this.showYAxisLabels_,this.showGridLines_);}}
-for(var series of this.series){var chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.seriesYAxis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);}
-ctx.restore();},addEventsToTrackMap:function(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection:function(filter,selection){},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes:function(opt_config){for(var axisData of Object.values(this.axisGuidToAxisData_)){var seriesYAxis=axisData.axis;var series=axisData.series;seriesYAxis.autoSetFromSeries(series,opt_config);}},autoSetAxis:function(seriesYAxis,opt_config){var series=this.axisGuidToAxisData_[seriesYAxis.guid].series;seriesYAxis.autoSetFromSeries(series,opt_config);}};return{ChartTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var CpuUsageTrack=tr.ui.b.define('cpu-usage-track',ChartTrack);CpuUsageTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-usage-track');this.heading='CPU usage';this.cpuUsageSeries_=undefined;},initialize:function(model){if(model!==undefined){this.cpuUsageSeries_=model.device.cpuUsageSeries;}else{this.cpuUsageSeries_=undefined;}
-this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return!!this.cpuUsageSeries_&&this.cpuUsageSeries_.samples.length>0;},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.series_,this);},buildChartSeries_:function(yAxis,color){if(!this.hasVisibleContent)return[];var yAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);var usageSamples=this.cpuUsageSeries_.samples;var pts=new Array(usageSamples.length+1);for(var i=0;i<usageSamples.length;i++){pts[i]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[i].start,usageSamples[i].usage);}
-pts[usageSamples.length]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[usageSamples.length-1].start,0);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:color};return[new tr.ui.tracks.ChartSeries(pts,yAxis,renderingConfig)];},};return{CpuUsageTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ChartTrack=tr.ui.tracks.ChartTrack;var PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate:function(viewport){ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap:function(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_:function(){if(!this.hasVisibleContent)return[];var seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);var pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.powerInW);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,seriesYAxis,renderingConfig)];}};return{PowerSeriesTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('spacing-track');this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{SpacingTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ContainerTrack=tr.ui.tracks.ContainerTrack;var DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate:function(viewport){ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap:function(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_:function(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){Polymer.dom(this).appendChild(this.powerSeriesTrack_);Polymer.dom(this).appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_:function(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;var BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;var LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;var DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;function extractGlobalMemoryDumpUsedSizes(globalMemoryDump,addSize){for(var[pid,pmd]of
-Object.entries(globalMemoryDump.processMemoryDumps)){var mostRecentVmRegions=pmd.mostRecentVmRegions;if(mostRecentVmRegions===undefined)continue;addSize(pid,mostRecentVmRegions.byteStats.proportionalResident||0,pmd.process.userFriendlyName);}}
-function extractProcessMemoryDumpAllocatorSizes(processMemoryDump,addSize){var allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)return;allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')return;var allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)return;var allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)return;addSize(allocatorDump.fullName,allocatorSizeValue);});}
-function extractGlobalMemoryDumpAllocatorSizes(globalMemoryDump,addSize){for(var pmd of Object.values(globalMemoryDump.processMemoryDumps)){extractProcessMemoryDumpAllocatorSizes(pmd,addSize);}}
-function buildMemoryChartSeries(memoryDumps,dumpSizeExtractor){var dumpCount=memoryDumps.length;var idToTimestampToPoint={};var idToName={};memoryDumps.forEach(function(dump,index){dumpSizeExtractor(dump,function addSize(id,size,opt_name){var timestampToPoint=idToTimestampToPoint[id];if(timestampToPoint===undefined){idToTimestampToPoint[id]=timestampToPoint=new Array(dumpCount);for(var i=0;i<dumpCount;i++){var modelItem=memoryDumps[i];timestampToPoint[i]=new tr.ui.tracks.ChartPoint(modelItem,modelItem.start,0);}}
-timestampToPoint[index].y+=size;if(opt_name!==undefined)idToName[id]=opt_name;});});var ids=Object.keys(idToTimestampToPoint);if(ids.length===0)return undefined;ids.sort();for(var i=0;i<dumpCount;i++){var baseSize=0;for(var j=ids.length-1;j>=0;j--){var point=idToTimestampToPoint[ids[j]][i];point.yBase=baseSize;point.y+=baseSize;baseSize=point.y;}}
-var seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0);var series=ids.map(function(id){var colorId=ColorScheme.getColorIdForGeneralPurposeString(idToName[id]||id);var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:colorId,backgroundOpacity:0.8};return new tr.ui.tracks.ChartSeries(idToTimestampToPoint[id],seriesYAxis,renderingConfig);});series.reverse();return series;}
-function buildMemoryLetterDots(memoryDumps){var backgroundMemoryColorId=ColorScheme.getColorIdForReservedName('background_memory_dump');var lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');var detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){var memoryColorId;switch(memoryDump.levelOfDetail){case BACKGROUND:memoryColorId=backgroundMemoryColorId;break;case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
+ChartTransform.prototype={worldXToViewX(worldX){return this.displayTransform_.xWorldToView(worldX);},viewXToWorldX(viewX){return this.displayTransform_.xViewToWorld(viewX);},vectorToWorldDistance(viewY){return this.axis_.bounds.range*Math.abs(viewY/this.innerHeight_);},viewYToWorldY(viewY){return this.axis_.unitRangeToValue(1-(viewY-this.innerTopViewY)/this.innerHeight_);},worldYToViewY(worldY){const innerHeightCoefficient=1-this.axis_.valueToUnitRange(worldY);return innerHeightCoefficient*this.innerHeight_+this.innerTopViewY;}};return{ChartTransform,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ChartTrack=tr.ui.b.define('chart-track',tr.ui.tracks.Track);ChartTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('chart-track');this.series_=undefined;this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;this.showYAxisLabels_=undefined;this.showGridLines_=undefined;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},get series(){return this.series_;},set series(series){this.series_=series;this.calculateAxisDataAndPadding_();this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get showYAxisLabels(){return this.showYAxisLabels_;},set showYAxisLabels(showYAxisLabels){this.showYAxisLabels_=showYAxisLabels;this.invalidateDrawingContainer();},get showGridLines(){return this.showGridLines_;},set showGridLines(showGridLines){this.showGridLines_=showGridLines;this.invalidateDrawingContainer();},get hasVisibleContent(){return!!this.series&&this.series.length>0;},calculateAxisDataAndPadding_(){if(!this.series_){this.axes_=undefined;this.axisGuidToAxisData_=undefined;this.topPadding_=undefined;this.bottomPadding_=undefined;return;}
+const axisGuidToAxisData={};let topPadding=0;let bottomPadding=0;this.series_.forEach(function(series){const seriesYAxis=series.seriesYAxis;const axisGuid=seriesYAxis.guid;if(!(axisGuid in axisGuidToAxisData)){axisGuidToAxisData[axisGuid]={axis:seriesYAxis,series:[]};if(!this.axes_)this.axes_=[];this.axes_.push(seriesYAxis);}
+axisGuidToAxisData[axisGuid].series.push(series);topPadding=Math.max(topPadding,series.topPadding);bottomPadding=Math.max(bottomPadding,series.bottomPadding);},this);this.axisGuidToAxisData_=axisGuidToAxisData;this.topPadding_=topPadding;this.bottomPadding_=bottomPadding;},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawChart_(viewLWorld,viewRWorld);break;}},drawChart_(viewLWorld,viewRWorld){if(!this.series_)return;const ctx=this.context();const displayTransform=this.viewport.currentDisplayTransform;const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const highDetails=this.viewport.highDetails;const width=bounds.width*pixelRatio;const height=bounds.height*pixelRatio;const topPadding=this.topPadding_*pixelRatio;const bottomPadding=this.bottomPadding_*pixelRatio;ctx.save();ctx.beginPath();ctx.rect(0,0,width,height);ctx.clip();if(this.axes_){if((this.showGridLines_||this.showYAxisLabels_)&&this.axes_.length>1){throw new Error('Only one axis allowed when showing grid lines.');}
+for(const yAxis of this.axes_){const chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,yAxis,width,height,topPadding,bottomPadding,pixelRatio);yAxis.draw(ctx,chartTransform,this.showYAxisLabels_,this.showGridLines_);}}
+for(const series of this.series){const chartTransform=new tr.ui.tracks.ChartTransform(displayTransform,series.seriesYAxis,width,height,topPadding,bottomPadding,pixelRatio);series.draw(ctx,chartTransform,highDetails);}
+ctx.restore();},addEventsToTrackMap(eventToTrackMap){this.series_.forEach(function(series){series.points.forEach(function(point){point.addToTrackMap(eventToTrackMap,this);},this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){this.series_.forEach(function(series){series.addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection);},this);},addEventNearToProvidedEventToSelection(event,offset,selection){let foundItem=false;this.series_.forEach(function(series){foundItem=foundItem||series.addEventNearToProvidedEventToSelection(event,offset,selection);},this);return foundItem;},addAllEventsMatchingFilterToSelection(filter,selection){},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.series_.forEach(function(series){series.addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection);},this);},autoSetAllAxes(opt_config){for(const axisData of Object.values(this.axisGuidToAxisData_)){const seriesYAxis=axisData.axis;const series=axisData.series;seriesYAxis.autoSetFromSeries(series,opt_config);}},autoSetAxis(seriesYAxis,opt_config){const series=this.axisGuidToAxisData_[seriesYAxis.guid].series;seriesYAxis.autoSetFromSeries(series,opt_config);}};return{ChartTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ChartTrack=tr.ui.tracks.ChartTrack;const CpuUsageTrack=tr.ui.b.define('cpu-usage-track',ChartTrack);CpuUsageTrack.prototype={__proto__:ChartTrack.prototype,decorate(viewport){ChartTrack.prototype.decorate.call(this,viewport);this.classList.add('cpu-usage-track');this.heading='CPU usage';this.cpuUsageSeries_=undefined;},initialize(model){if(model!==undefined){this.cpuUsageSeries_=model.device.cpuUsageSeries;}else{this.cpuUsageSeries_=undefined;}
+this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return!!this.cpuUsageSeries_&&this.cpuUsageSeries_.samples.length>0;},addContainersToTrackMap(containerToTrackMap){containerToTrackMap.addContainer(this.series_,this);},buildChartSeries_(yAxis,color){if(!this.hasVisibleContent)return[];yAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const usageSamples=this.cpuUsageSeries_.samples;const pts=new Array(usageSamples.length+1);for(let i=0;i<usageSamples.length;i++){pts[i]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[i].start,usageSamples[i].usage);}
+pts[usageSamples.length]=new tr.ui.tracks.ChartPoint(undefined,usageSamples[usageSamples.length-1].start,0);const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:color};return[new tr.ui.tracks.ChartSeries(pts,yAxis,renderingConfig)];},};return{CpuUsageTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ChartTrack=tr.ui.tracks.ChartTrack;const PowerSeriesTrack=tr.ui.b.define('power-series-track',ChartTrack);PowerSeriesTrack.prototype={__proto__:ChartTrack.prototype,decorate(viewport){ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('power-series-track');this.heading='Power';this.powerSeries_=undefined;},set powerSeries(powerSeries){this.powerSeries_=powerSeries;this.series=this.buildChartSeries_();this.autoSetAllAxes({expandMax:true});},get hasVisibleContent(){return(this.powerSeries_&&this.powerSeries_.samples.length>0);},addContainersToTrackMap(containerToTrackMap){containerToTrackMap.addContainer(this.powerSeries_,this);},buildChartSeries_(){if(!this.hasVisibleContent)return[];const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const pts=this.powerSeries_.samples.map(function(smpl){return new tr.ui.tracks.ChartPoint(smpl,smpl.start,smpl.powerInW);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:ColorScheme.getColorIdForGeneralPurposeString(this.heading)};return[new tr.ui.tracks.ChartSeries(pts,seriesYAxis,renderingConfig)];}};return{PowerSeriesTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SpacingTrack=tr.ui.b.define('spacing-track',tr.ui.tracks.Track);SpacingTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('spacing-track');this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},addAllEventsMatchingFilterToSelection(filter,selection){}};return{SpacingTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ContainerTrack=tr.ui.tracks.ContainerTrack;const DeviceTrack=tr.ui.b.define('device-track',ContainerTrack);DeviceTrack.prototype={__proto__:ContainerTrack.prototype,decorate(viewport){ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('device-track');this.device_=undefined;this.powerSeriesTrack_=undefined;},get device(){return this.device_;},set device(device){this.device_=device;this.updateContents_();},get powerSeriesTrack(){return this.powerSeriesTrack_;},get hasVisibleContent(){return(this.powerSeriesTrack_&&this.powerSeriesTrack_.hasVisibleContent);},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.device,this);},addEventsToTrackMap(eventToTrackMap){this.tracks_.forEach(function(track){track.addEventsToTrackMap(eventToTrackMap);});},appendPowerSeriesTrack_(){this.powerSeriesTrack_=new tr.ui.tracks.PowerSeriesTrack(this.viewport);this.powerSeriesTrack_.powerSeries=this.device.powerSeries;if(this.powerSeriesTrack_.hasVisibleContent){Polymer.dom(this).appendChild(this.powerSeriesTrack_);Polymer.dom(this).appendChild(new tr.ui.tracks.SpacingTrack(this.viewport));}},updateContents_(){this.clearTracks_();this.appendPowerSeriesTrack_();}};return{DeviceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const DISPLAYED_SIZE_NUMERIC_NAME=tr.model.MemoryAllocatorDump.DISPLAYED_SIZE_NUMERIC_NAME;const BACKGROUND=tr.model.ContainerMemoryDump.LevelOfDetail.BACKGROUND;const LIGHT=tr.model.ContainerMemoryDump.LevelOfDetail.LIGHT;const DETAILED=tr.model.ContainerMemoryDump.LevelOfDetail.DETAILED;function extractGlobalMemoryDumpUsedSizes(globalMemoryDump,addSize){for(const[pid,pmd]of
+Object.entries(globalMemoryDump.processMemoryDumps)){const mostRecentVmRegions=pmd.mostRecentVmRegions;if(mostRecentVmRegions===undefined)continue;addSize(pid,mostRecentVmRegions.byteStats.proportionalResident||0,pmd.process.userFriendlyName);}}
+function extractProcessMemoryDumpAllocatorSizes(processMemoryDump,addSize){const allocatorDumps=processMemoryDump.memoryAllocatorDumps;if(allocatorDumps===undefined)return;allocatorDumps.forEach(function(allocatorDump){if(allocatorDump.fullName==='tracing')return;const allocatorSize=allocatorDump.numerics[DISPLAYED_SIZE_NUMERIC_NAME];if(allocatorSize===undefined)return;const allocatorSizeValue=allocatorSize.value;if(allocatorSizeValue===undefined)return;addSize(allocatorDump.fullName,allocatorSizeValue);});}
+function extractGlobalMemoryDumpAllocatorSizes(globalMemoryDump,addSize){for(const pmd of Object.values(globalMemoryDump.processMemoryDumps)){extractProcessMemoryDumpAllocatorSizes(pmd,addSize);}}
+function buildMemoryChartSeries(memoryDumps,dumpSizeExtractor){const dumpCount=memoryDumps.length;const idToTimestampToPoint={};const idToName={};memoryDumps.forEach(function(dump,index){dumpSizeExtractor(dump,function addSize(id,size,opt_name){let timestampToPoint=idToTimestampToPoint[id];if(timestampToPoint===undefined){idToTimestampToPoint[id]=timestampToPoint=new Array(dumpCount);for(let i=0;i<dumpCount;i++){const modelItem=memoryDumps[i];timestampToPoint[i]=new tr.ui.tracks.ChartPoint(modelItem,modelItem.start,0);}}
+timestampToPoint[index].y+=size;if(opt_name!==undefined)idToName[id]=opt_name;});});const ids=Object.keys(idToTimestampToPoint);if(ids.length===0)return undefined;ids.sort();for(let i=0;i<dumpCount;i++){let baseSize=0;for(let j=ids.length-1;j>=0;j--){const point=idToTimestampToPoint[ids[j]][i];point.yBase=baseSize;point.y+=baseSize;baseSize=point.y;}}
+const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0);const series=ids.map(function(id){const colorId=ColorScheme.getColorIdForGeneralPurposeString(idToName[id]||id);const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId,backgroundOpacity:0.8};return new tr.ui.tracks.ChartSeries(idToTimestampToPoint[id],seriesYAxis,renderingConfig);});series.reverse();return series;}
+function buildMemoryLetterDots(memoryDumps){const backgroundMemoryColorId=ColorScheme.getColorIdForReservedName('background_memory_dump');const lightMemoryColorId=ColorScheme.getColorIdForReservedName('light_memory_dump');const detailedMemoryColorId=ColorScheme.getColorIdForReservedName('detailed_memory_dump');return memoryDumps.map(function(memoryDump){let memoryColorId;switch(memoryDump.levelOfDetail){case BACKGROUND:memoryColorId=backgroundMemoryColorId;break;case DETAILED:memoryColorId=detailedMemoryColorId;break;case LIGHT:default:memoryColorId=lightMemoryColorId;}
 return new tr.ui.tracks.LetterDot(memoryDump,'M',memoryColorId,memoryDump.start);});}
 function buildGlobalUsedMemoryChartSeries(globalMemoryDumps){return buildMemoryChartSeries(globalMemoryDumps,extractGlobalMemoryDumpUsedSizes);}
 function buildProcessAllocatedMemoryChartSeries(processMemoryDumps){return buildMemoryChartSeries(processMemoryDumps,extractProcessMemoryDumpAllocatorSizes);}
 function buildGlobalAllocatedMemoryChartSeries(globalMemoryDumps){return buildMemoryChartSeries(globalMemoryDumps,extractGlobalMemoryDumpAllocatorSizes);}
-return{buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var USED_MEMORY_TRACK_HEIGHT=50;var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_:function(){var items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)return;var track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;Polymer.dom(this).appendChild(track);},appendUsedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{GlobalMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
-FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH:function(y,h){if(this.y_===y&&this.h_===h){return;}
-this.flush();this.y_=y;this.h_=h;},fillRect:function(x,w,colorId,alpha){var r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_){this.flush();}
+return{buildMemoryLetterDots,buildGlobalUsedMemoryChartSeries,buildProcessAllocatedMemoryChartSeries,buildGlobalAllocatedMemoryChartSeries,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const USED_MEMORY_TRACK_HEIGHT=50;const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const GlobalMemoryDumpTrack=tr.ui.b.define('global-memory-dump-track',tr.ui.tracks.ContainerTrack);GlobalMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendDumpDotsTrack_();this.appendUsedMemoryTrack_();this.appendAllocatedMemoryTrack_();},appendDumpDotsTrack_(){const items=tr.ui.tracks.buildMemoryLetterDots(this.memoryDumps_);if(!items)return;const track=new tr.ui.tracks.LetterDotTrack(this.viewport);track.heading='Memory Dumps';track.items=items;Polymer.dom(this).appendChild(track);},appendUsedMemoryTrack_(){const series=tr.ui.tracks.buildGlobalUsedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per process';track.height=USED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildGlobalAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{GlobalMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.b',function(){function FastRectRenderer(ctx,minRectSize,maxMergeDist,pallette){this.ctx_=ctx;this.minRectSize_=minRectSize;this.maxMergeDist_=maxMergeDist;this.pallette_=pallette;}
+FastRectRenderer.prototype={y_:0,h_:0,merging_:false,mergeStartX_:0,mergeCurRight_:0,mergedColorId_:0,mergedAlpha_:0,setYandH(y,h){if(this.y_===y&&this.h_===h){return;}
+this.flush();this.y_=y;this.h_=h;},fillRect(x,w,colorId,alpha){const r=x+w;if(w<this.minRectSize_){if(r-this.mergeStartX_>this.maxMergeDist_){this.flush();}
 if(!this.merging_){this.merging_=true;this.mergeStartX_=x;this.mergeCurRight_=r;this.mergedColorId_=colorId;this.mergedAlpha_=alpha;}else{this.mergeCurRight_=r;if(this.mergedAlpha_<alpha||(this.mergedAlpha_===alpha&&this.mergedColorId_<colorId)){this.mergedAlpha_=alpha;this.mergedColorId_=colorId;}}}else{if(this.merging_){this.flush();}
-this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush:function(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_:function(viewLWorld,viewRWorld){var ctx=this.context();ctx.save();var bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)return;var fontSize;var yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
-tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap:function(eventToTrackMap){if(this.rects_===undefined||this.rects_===null){return;}
-this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
-onRect=onRect.bind(this);var instantEventWidth=2*viewPixWidthWorld;tr.b.math.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration===0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection:function(event,offset,selection){var index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)return false;var newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection:function(filter,selection){for(var i=0;i<this.rects_.length;++i){var modelItem=this.rects_[i].modelItem;if(!modelItem)continue;if(filter.matchSlice(modelItem)){selection.push(modelItem);}}},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){var rect=tr.b.math.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;}
-Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack,Rect,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)return false;var cpu=this.cpu_;if(cpu.slices.length)return true;if(cpu.samples&&cpu.samples.length)return true;if(tr.b.dictionaryLength(cpu.counters)>0)return true;return false;},updateContents_:function(){this.detach();if(!this.cpu_)return;var slices=this.cpu_.slices;if(slices.length){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';Polymer.dom(this).appendChild(track);}
-if(this.detailedMode_){this.appendSamplesTracks_();for(var counterName in this.cpu_.counters){var counter=this.cpu_.counters[counterName];track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
-counter.name+':';track.counter=counter;Polymer.dom(this).appendChild(track);}}},appendSamplesTracks_:function(){var samples=this.cpu_.samples;if(samples===undefined||samples.length===0){return;}
-var samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
-samplesByTitle[sample.title].push(sample);});var sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
-return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);}};return{CpuTrack,};});'use strict';tr.exportTo('tr.model',function(){var Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
-ModelSettings.prototype={buildObjectsByKeyMap_:function(){var objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});var objectsByKey={};var NONUNIQUE_KEY='nonuniqueKey';for(var i=0;i<objects.length;i++){var object=objects[i];var objectKey=object.getSettingsKey();if(!objectKey)continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
+this.ctx_.fillStyle=this.pallette_[colorId];this.ctx_.globalAlpha=alpha;this.ctx_.fillRect(x,this.y_,w,this.h_);}},flush(){if(this.merging_){this.ctx_.fillStyle=this.pallette_[this.mergedColorId_];this.ctx_.globalAlpha=this.mergedAlpha_;this.ctx_.fillRect(this.mergeStartX_,this.y_,this.mergeCurRight_-this.mergeStartX_,this.h_);this.merging_=false;}}};return{FastRectRenderer,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const RectTrack=tr.ui.b.define('rect-track',tr.ui.tracks.Track);RectTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('rect-track');this.asyncStyle_=false;this.rects_=null;this.heading_=document.createElement('tr-ui-b-heading');Polymer.dom(this).appendChild(this.heading_);},set heading(heading){this.heading_.heading=heading;},get heading(){return this.heading_.heading;},set tooltip(tooltip){this.heading_.tooltip=tooltip;},set selectionGenerator(generator){this.heading_.selectionGenerator=generator;},set expanded(expanded){this.heading_.expanded=!!expanded;},set arrowVisible(arrowVisible){this.heading_.arrowVisible=!!arrowVisible;},get expanded(){return this.heading_.expanded;},get asyncStyle(){return this.asyncStyle_;},set asyncStyle(v){this.asyncStyle_=!!v;},get rects(){return this.rects_;},set rects(rects){this.rects_=rects||[];this.invalidateDrawingContainer();},get height(){return window.getComputedStyle(this).height;},set height(height){this.style.height=height;this.invalidateDrawingContainer();},get hasVisibleContent(){return this.rects_.length>0;},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GENERAL_EVENT:this.drawRects_(viewLWorld,viewRWorld);break;}},drawRects_(viewLWorld,viewRWorld){const ctx=this.context();ctx.save();const bounds=this.getBoundingClientRect();tr.ui.b.drawSlices(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.rects_,this.asyncStyle_);ctx.restore();if(bounds.height<=6)return;let fontSize;let yOffset;if(bounds.height<15){fontSize=6;yOffset=1.0;}else{fontSize=10;yOffset=2.5;}
+tr.ui.b.drawLabels(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,this.rects_,this.asyncStyle_,fontSize,yOffset);},addEventsToTrackMap(eventToTrackMap){if(this.rects_===undefined||this.rects_===null){return;}
+this.rects_.forEach(function(rect){rect.addToTrackMap(eventToTrackMap,this);},this);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onRect(rect){rect.addToSelection(selection);}
+onRect=onRect.bind(this);const instantEventWidth=2*viewPixWidthWorld;tr.b.math.iterateOverIntersectingIntervals(this.rects_,function(x){return x.start;},function(x){return x.duration===0?x.duration+instantEventWidth:x.duration;},loWX,hiWX,onRect);},addEventNearToProvidedEventToSelection(event,offset,selection){const index=tr.b.findFirstIndexInArray(this.rects_,function(rect){return rect.modelItem===event;});if(index===-1)return false;const newIndex=index+offset;if(newIndex<0||newIndex>=this.rects_.length)return false;this.rects_[newIndex].addToSelection(selection);return true;},addAllEventsMatchingFilterToSelection(filter,selection){for(let i=0;i<this.rects_.length;++i){const modelItem=this.rects_[i].modelItem;if(!modelItem)continue;if(filter.matchSlice(modelItem)){selection.push(modelItem);}}},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){const rect=tr.b.math.findClosestIntervalInSortedIntervals(this.rects_,function(x){return x.start;},function(x){return x.end;},worldX,worldMaxDist);if(!rect)return;rect.addToSelection(selection);}};function Rect(modelItem,title,colorId,start,duration){tr.model.ProxySelectableItem.call(this,modelItem);this.title=title;this.colorId=colorId;this.start=start;this.duration=duration;this.end=start+duration;}
+Rect.prototype={__proto__:tr.model.ProxySelectableItem.prototype};return{RectTrack,Rect,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SliceTrack=tr.ui.b.define('slice-track',tr.ui.tracks.RectTrack);SliceTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get slices(){return this.rects;},set slices(slices){this.rects=slices;}};return{SliceTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CpuTrack=tr.ui.b.define('cpu-track',tr.ui.tracks.ContainerTrack);CpuTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('cpu-track');this.detailedMode_=true;},get cpu(){return this.cpu_;},set cpu(cpu){this.cpu_=cpu;this.updateContents_();},get detailedMode(){return this.detailedMode_;},set detailedMode(detailedMode){this.detailedMode_=detailedMode;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(value){this.tooltip_=value;this.updateContents_();},get hasVisibleContent(){if(this.cpu_===undefined)return false;const cpu=this.cpu_;if(cpu.slices.length)return true;if(cpu.samples&&cpu.samples.length)return true;if(Object.keys(cpu.counters).length>0)return true;return false;},updateContents_(){this.detach();if(!this.cpu_)return;const slices=this.cpu_.slices;if(slices.length){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;track.heading=this.cpu_.userFriendlyName+':';Polymer.dom(this).appendChild(track);}
+if(this.detailedMode_){this.appendSamplesTracks_();for(const counterName in this.cpu_.counters){const counter=this.cpu_.counters[counterName];const track=new tr.ui.tracks.CounterTrack(this.viewport);track.heading=this.cpu_.userFriendlyName+' '+
+counter.name+':';track.counter=counter;Polymer.dom(this).appendChild(track);}}},appendSamplesTracks_(){const samples=this.cpu_.samples;if(samples===undefined||samples.length===0){return;}
+const samplesByTitle={};samples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
+samplesByTitle[sample.title].push(sample);});const sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){const samples=samplesByTitle[sampleTitle];const samplesTrack=new tr.ui.tracks.SliceTrack(this.viewport);samplesTrack.group=this.cpu_;samplesTrack.slices=samples;samplesTrack.heading=this.cpu_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.cpu_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){const selection=new tr.model.EventSet();for(let i=0;i<samplesTrack.slices.length;i++){selection.push(samplesTrack.slices[i]);}
+return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);}};return{CpuTrack,};});'use strict';tr.exportTo('tr.model',function(){const Settings=tr.b.Settings;function ModelSettings(model){this.model=model;this.objectsByKey_=[];this.nonuniqueKeys_=[];this.buildObjectsByKeyMap_();this.removeNonuniqueKeysFromSettings_();this.ephemeralSettingsByGUID_={};}
+ModelSettings.prototype={buildObjectsByKeyMap_(){const objects=[];this.model.iterateAllPersistableObjects(function(o){objects.push(o);});const objectsByKey={};const NONUNIQUE_KEY='nonuniqueKey';for(let i=0;i<objects.length;i++){const object=objects[i];const objectKey=object.getSettingsKey();if(!objectKey)continue;if(objectsByKey[objectKey]===undefined){objectsByKey[objectKey]=object;continue;}
 objectsByKey[objectKey]=NONUNIQUE_KEY;}
-var nonuniqueKeys={};Object.keys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY){return;}
-delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_:function(){var settings=Settings.get('trace_model_settings',{});var settingsChanged=false;Object.keys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey]){return;}
-settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged){Settings.set('trace_model_settings',settings);}},hasUniqueSettingKey:function(object){var objectKey=object.getSettingsKey();if(!objectKey)return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor:function(object,objectLevelKey,defaultValue){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){var settings=this.getEphemeralSettingsFor_(object);var ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined){return ephemeralValue;}
+const nonuniqueKeys={};Object.keys(objectsByKey).forEach(function(objectKey){if(objectsByKey[objectKey]!==NONUNIQUE_KEY){return;}
+delete objectsByKey[objectKey];nonuniqueKeys[objectKey]=true;});this.nonuniqueKeys=nonuniqueKeys;this.objectsByKey_=objectsByKey;},removeNonuniqueKeysFromSettings_(){const settings=Settings.get('trace_model_settings',{});let settingsChanged=false;Object.keys(settings).forEach(function(objectKey){if(!this.nonuniqueKeys[objectKey]){return;}
+settingsChanged=true;delete settings[objectKey];},this);if(settingsChanged){Settings.set('trace_model_settings',settings);}},hasUniqueSettingKey(object){const objectKey=object.getSettingsKey();if(!objectKey)return false;return this.objectsByKey_[objectKey]!==undefined;},getSettingFor(object,objectLevelKey,defaultValue){const objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){const settings=this.getEphemeralSettingsFor_(object);const ephemeralValue=settings[objectLevelKey];if(ephemeralValue!==undefined){return ephemeralValue;}
 return defaultValue;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
-var value=settings[objectKey][objectLevelKey];if(value!==undefined){return value;}
-return defaultValue;},setSettingFor:function(object,objectLevelKey,value){var objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
-var settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
+const settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
+const value=settings[objectKey][objectLevelKey];if(value!==undefined){return value;}
+return defaultValue;},setSettingFor(object,objectLevelKey,value){const objectKey=object.getSettingsKey();if(!objectKey||!this.objectsByKey_[objectKey]){this.getEphemeralSettingsFor_(object)[objectLevelKey]=value;return;}
+const settings=Settings.get('trace_model_settings',{});if(!settings[objectKey]){settings[objectKey]={};}
 if(settings[objectKey][objectLevelKey]===value){return;}
-settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_:function(object){if(object.guid===undefined){throw new Error('Only objects with GUIDs can be persisted');}
+settings[objectKey][objectLevelKey]=value;Settings.set('trace_model_settings',settings);},getEphemeralSettingsFor_(object){if(object.guid===undefined){throw new Error('Only objects with GUIDs can be persisted');}
 if(this.ephemeralSettingsByGUID_[object.guid]===undefined){this.ephemeralSettingsByGUID_[object.guid]={};}
-return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate:function(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem:function(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){var numSeries=counter.series.length;var totals=counter.totals;var seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);var chartSeries=counter.series.map(function(series,seriesIndex){var chartPoints=series.samples.map(function(sample,sampleIndex){var total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});var renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,seriesYAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var startCompare=function(x,y){return x.start-y.start;};var FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate:function(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
-FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup:function(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_:function(e){if(this.subRows.length<=1)return;this.expanded=!this.expanded;if(this.groupingSource_){var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
-e.stopPropagation();},updateExpandedStateFromGroupingSource_:function(){if(this.groupingSource_){var numSubRows=this.subRows.length;var modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){var defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
-this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_:function(){var minH=Math.max(2,Math.ceil(18/this.children.length));var h=(this.expanded_?18:minH)+'px';for(var i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0){this.children[i].arrowVisible=true;}
+return this.ephemeralSettingsByGUID_[object.guid];}};return{ModelSettings,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const CounterTrack=tr.ui.b.define('counter-track',tr.ui.tracks.ChartTrack);CounterTrack.prototype={__proto__:tr.ui.tracks.ChartTrack.prototype,decorate(viewport){tr.ui.tracks.ChartTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('counter-track');},get counter(){return this.chart;},set counter(counter){this.heading=counter.name+': ';this.series=CounterTrack.buildChartSeriesFromCounter(counter);this.autoSetAllAxes({expandMax:true});},getModelEventFromItem(chartValue){return chartValue;}};CounterTrack.buildChartSeriesFromCounter=function(counter){const numSeries=counter.series.length;const totals=counter.totals;const seriesYAxis=new tr.ui.tracks.ChartSeriesYAxis(0,undefined);const chartSeries=counter.series.map(function(series,seriesIndex){const chartPoints=series.samples.map(function(sample,sampleIndex){const total=totals[sampleIndex*numSeries+seriesIndex];return new tr.ui.tracks.ChartPoint(sample,sample.timestamp,total);});const renderingConfig={chartType:tr.ui.tracks.ChartSeriesType.AREA,colorId:series.color};return new tr.ui.tracks.ChartSeries(chartPoints,seriesYAxis,renderingConfig);});chartSeries.reverse();return chartSeries;};return{CounterTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const startCompare=function(x,y){return x.start-y.start;};const FrameTrack=tr.ui.b.define('frame-track',tr.ui.tracks.LetterDotTrack);FrameTrack.prototype={__proto__:tr.ui.tracks.LetterDotTrack.prototype,decorate(viewport){tr.ui.tracks.LetterDotTrack.prototype.decorate.call(this,viewport);this.heading='Frames';this.frames_=undefined;this.items=undefined;},get frames(){return this.frames_;},set frames(frames){this.frames_=frames;if(frames===undefined)return;this.frames_=this.frames_.slice();this.frames_.sort(startCompare);this.items=this.frames_.map(function(frame){return new FrameDot(frame);});}};function FrameDot(frame){tr.ui.tracks.LetterDot.call(this,frame,'F',frame.colorId,frame.start);}
+FrameDot.prototype={__proto__:tr.ui.tracks.LetterDot.prototype};return{FrameTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const MultiRowTrack=tr.ui.b.define('multi-row-track',tr.ui.tracks.ContainerTrack);MultiRowTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.tooltip_='';this.heading_='';this.groupingSource_=undefined;this.itemsToGroup_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=1;this.itemsGroupedOnLastUpdateContents_=undefined;this.currentSubRows_=[];this.expanded_=true;},get itemsToGroup(){return this.itemsToGroup_;},setItemsToGroup(itemsToGroup,opt_groupingSource){this.itemsToGroup_=itemsToGroup;this.groupingSource_=opt_groupingSource;this.updateContents_();this.updateExpandedStateFromGroupingSource_();},get heading(){return this.heading_;},set heading(h){this.heading_=h;this.updateContents_();},get tooltip(){return this.tooltip_;},set tooltip(t){this.tooltip_=t;this.updateContents_();},get subRows(){return this.currentSubRows_;},get hasVisibleContent(){return this.children.length>0;},get expanded(){return this.expanded_;},set expanded(expanded){if(this.expanded_===expanded)return;this.expanded_=expanded;this.expandedStateChanged_();},onHeadingClicked_(e){if(this.subRows.length<=1)return;this.expanded=!this.expanded;if(this.groupingSource_){const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);modelSettings.setSettingFor(this.groupingSource_,'expanded',this.expanded);}
+e.stopPropagation();},updateExpandedStateFromGroupingSource_(){if(this.groupingSource_){const numSubRows=this.subRows.length;const modelSettings=new tr.model.ModelSettings(this.groupingSource_.model);if(numSubRows>1){let defaultExpanded;if(numSubRows>this.defaultToCollapsedWhenSubRowCountMoreThan){defaultExpanded=false;}else{defaultExpanded=true;}
+this.expanded=modelSettings.getSettingFor(this.groupingSource_,'expanded',defaultExpanded);}else{this.expanded=undefined;}}},expandedStateChanged_(){const minH=Math.max(2,Math.ceil(18/this.children.length));const h=(this.expanded_?18:minH)+'px';for(let i=0;i<this.children.length;i++){this.children[i].height=h;if(i===0){this.children[i].arrowVisible=true;}
 this.children[i].expanded=this.expanded;}
-if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_:function(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
+if(this.children.length===1){this.children[0].expanded=true;this.children[0].arrowVisible=false;}},updateContents_(){tr.ui.tracks.ContainerTrack.prototype.updateContents_.call(this);if(!this.itemsToGroup_){this.updateHeadingAndTooltip_();this.currentSubRows_=[];return;}
 if(this.areArrayContentsSame_(this.itemsGroupedOnLastUpdateContents_,this.itemsToGroup_)){this.updateHeadingAndTooltip_();return;}
 this.itemsGroupedOnLastUpdateContents_=this.itemsToGroup_;this.detach();if(!this.itemsToGroup_.length){this.currentSubRows_=[];return;}
-var subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(var srI=0;srI<subRows.length;srI++){var subRow=subRows[srI];if(!subRow.length)continue;var track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
-this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_:function(){if(!Polymer.dom(this).firstChild)return;Polymer.dom(this).firstChild.heading=this.heading_;Polymer.dom(this).firstChild.tooltip=this.tooltip_;},buildSubRows_:function(itemsToGroup){throw new Error('Not implemented');},addSubTrack_:function(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_:function(a,b){if(!a||!b)return false;if(!a.length||!b.length)return false;if(a.length!==b.length)return false;for(var i=0;i<a.length;++i){if(a[i]!==b[i])return false;}
-return true;}};return{MultiRowTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_:function(objectInstances){var hasMultipleRows=this.subRows.length>1;var track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;Polymer.dom(this).appendChild(track);return track;},buildSubRows_:function(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});var subRows=[];for(var i=0;i<objectInstances.length;i++){var objectInstance=objectInstances[i];var found=false;for(var j=0;j<subRows.length;j++){var subRow=subRows[j];var lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
-if(!found){var subRow=[objectInstance];subRows.push(subRow);}}
-return subRows;},updateHeadingAndTooltip_:function(){}};return{ObjectInstanceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
-var findLevel=function(sliceToPut,rows,n){if(n>=rows.length){return true;}
-var subRow=rows[n];var lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
-for(var subSlice of sliceToPut.subSlices){if(!findLevel(subSlice,rows,n+1)){return false;}}
+const subRows=this.buildSubRows_(this.itemsToGroup_);this.currentSubRows_=subRows;for(let srI=0;srI<subRows.length;srI++){const subRow=subRows[srI];if(!subRow.length)continue;const track=this.addSubTrack_(subRow);track.addEventListener('heading-clicked',this.onHeadingClicked_.bind(this));}
+this.updateHeadingAndTooltip_();this.expandedStateChanged_();},updateHeadingAndTooltip_(){if(!Polymer.dom(this).firstChild)return;Polymer.dom(this).firstChild.heading=this.heading_;Polymer.dom(this).firstChild.tooltip=this.tooltip_;},buildSubRows_(itemsToGroup){throw new Error('Not implemented');},addSubTrack_(subRowItems){throw new Error('Not implemented');},areArrayContentsSame_(a,b){if(!a||!b)return false;if(!a.length||!b.length)return false;if(a.length!==b.length)return false;for(let i=0;i<a.length;++i){if(a[i]!==b[i])return false;}
+return true;}};return{MultiRowTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ObjectInstanceGroupTrack=tr.ui.b.define('object-instance-group-track',tr.ui.tracks.MultiRowTrack);ObjectInstanceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('object-instance-group-track');this.objectInstances_=undefined;},get objectInstances(){return this.itemsToGroup;},set objectInstances(objectInstances){this.setItemsToGroup(objectInstances);},addSubTrack_(objectInstances){const hasMultipleRows=this.subRows.length>1;const track=new tr.ui.tracks.ObjectInstanceTrack(this.viewport);track.objectInstances=objectInstances;Polymer.dom(this).appendChild(track);return track;},buildSubRows_(objectInstances){objectInstances.sort(function(x,y){return x.creationTs-y.creationTs;});const subRows=[];for(let i=0;i<objectInstances.length;i++){const objectInstance=objectInstances[i];let found=false;for(let j=0;j<subRows.length;j++){const subRow=subRows[j];const lastItemInSubRow=subRow[subRow.length-1];if(objectInstance.creationTs>=lastItemInSubRow.deletionTs){found=true;subRow.push(objectInstance);break;}}
+if(!found){subRows.push([objectInstance]);}}
+return subRows;},updateHeadingAndTooltip_(){}};return{ObjectInstanceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const AsyncSliceGroupTrack=tr.ui.b.define('async-slice-group-track',tr.ui.tracks.MultiRowTrack);AsyncSliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('async-slice-group-track');this.group_=undefined;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);track.asyncStyle=true;return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_(slices,opt_skipSort){if(!opt_skipSort){slices.sort(function(x,y){return x.start-y.start;});}
+const findLevel=function(sliceToPut,rows,n){if(n>=rows.length){return true;}
+const subRow=rows[n];const lastSliceInSubRow=subRow[subRow.length-1];if(sliceToPut.start>=lastSliceInSubRow.end){if(sliceToPut.subSlices===undefined||sliceToPut.subSlices.length===0){return true;}
+for(const subSlice of sliceToPut.subSlices){if(!findLevel(subSlice,rows,n+1)){return false;}}
 return true;}
-return false;};var subRows=[];for(var slice of slices){var found=false;var index=subRows.length;for(var j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
+return false;};const subRows=[];for(const slice of slices){let found=false;let index=subRows.length;for(let j=0;j<subRows.length;j++){if(findLevel(slice,subRows,j)){found=true;index=j;break;}}
 if(!found){subRows.push([]);}
-subRows[index].push(slice);var fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0){return;}
+subRows[index].push(slice);const fitSubSlicesRecursively=function(subSlices,level,rows){if(subSlices===undefined||subSlices.length===0){return;}
 if(level===rows.length){rows.push([]);}
-for(var subSlice of subSlices){rows[level].push(subSlice);fitSubSlicesRecursively(subSlice.subSlices,level+1,rows);}};fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
-return subRows;}};return{AsyncSliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_:function(slices){var precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)return[];var ops=[];for(var i=0;i<slices.length;i++){if(slices[i].subSlices){slices[i].subSlices.splice(0,slices[i].subSlices.length);}
+for(const subSlice of subSlices){rows[level].push(subSlice);fitSubSlicesRecursively(subSlice.subSlices,level+1,rows);}};fitSubSlicesRecursively(slice.subSlices,index+1,subRows);}
+return subRows;}};return{AsyncSliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SampleTrack=tr.ui.b.define('sample-track',tr.ui.tracks.RectTrack);SampleTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get samples(){return this.rects;},set samples(samples){this.rects=samples;}};return{SampleTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SliceGroupTrack=tr.ui.b.define('slice-group-track',tr.ui.tracks.MultiRowTrack);SliceGroupTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('slice-group-track');this.group_=undefined;this.defaultToCollapsedWhenSubRowCountMoreThan=100;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;},get group(){return this.group_;},set group(group){this.group_=group;this.setItemsToGroup(this.group_.slices,this.group_);},get eventContainer(){return this.group;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.MultiRowTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.group,this);},buildSubRows_(slices){const precisionUnit=this.group.model.intrinsicTimeUnit;if(!slices.length)return[];const ops=[];for(let i=0;i<slices.length;i++){if(slices[i].subSlices){slices[i].subSlices.splice(0,slices[i].subSlices.length);}
 ops.push(i);}
-ops.sort(function(ix,iy){var x=slices[ix];var y=slices[iy];if(x.start!==y.start)return x.start-y.start;return ix-iy;});var subRows=[[]];this.badSlices_=[];for(var i=0;i<ops.length;i++){var op=ops[i];var slice=slices[op];var inserted=false;for(var j=subRows.length-1;j>=0;j--){if(subRows[j].length===0)continue;var insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
+ops.sort(function(ix,iy){const x=slices[ix];const y=slices[iy];if(x.start!==y.start)return x.start-y.start;return ix-iy;});const subRows=[[]];this.badSlices_=[];for(let i=0;i<ops.length;i++){const op=ops[i];const slice=slices[op];let inserted=false;for(let j=subRows.length-1;j>=0;j--){if(subRows[j].length===0)continue;const insertedSlice=subRows[j][subRows[j].length-1];if(slice.start<insertedSlice.start){this.badSlices_.push(slice);inserted=true;}
 if(insertedSlice.bounds(slice,precisionUnit)){while(subRows.length<=j+1){subRows.push([]);}
 subRows[j+1].push(slice);if(insertedSlice.subSlices){insertedSlice.subSlices.push(slice);}
 inserted=true;break;}}
 if(inserted)continue;subRows[0].push(slice);}
-return subRows;}};return{SliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('thread-track');this.heading_=document.createElement('tr-ui-b-heading');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get hasSlices(){return this.thread_.asyncSliceGroup.length>0||this.thread_.sliceGroup.length>0;},get hasTimeSlices(){return this.thread_.timeSlices;},get eventContainer(){return this.thread;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_:function(){this.detach();if(!this.thread_)return;this.heading_.heading=this.thread_.userFriendlyName;this.heading_.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length){this.appendAsyncSliceTracks_();}
-this.appendThreadSamplesTracks_();var needsHeading=false;if(this.thread_.timeSlices){var timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent){needsHeading=true;Polymer.dom(this).appendChild(timeSlicesTrack);}}
-if(this.thread_.sliceGroup.length){var track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent){needsHeading=false;Polymer.dom(this).appendChild(track);}}
-if(needsHeading){Polymer.dom(this).appendChild(this.heading_);}},appendAsyncSliceTracks_:function(){var subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){var asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);var title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent){Polymer.dom(this).appendChild(asyncTrack);}},this);},appendThreadSamplesTracks_:function(){var threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0){return;}
-var samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
-samplesByTitle[sample.title].push(sample);});var sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){var samples=samplesByTitle[sampleTitle];var samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
-sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){var selection=new tr.model.EventSet();for(var i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
-return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);},collapsedDidChange:function(collapsed){if(collapsed){var h=parseInt(this.tracks[0].height);for(var i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
-h=h*0.5;}}else{for(var i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var OtherThreadsTrack=tr.ui.b.define('other-threads-track',tr.ui.tracks.OtherThreadsTrack);var SpacingTrack=tr.ui.tracks.SpacingTrack;OtherThreadsTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.header_=document.createElement('tr-ui-b-heading');this.header_.addEventListener('click',this.onHeaderClick_.bind(this));this.header_.heading='Other Threads';this.header_.tooltip='Threads with only scheduling information';this.header_.arrowVisible=true;this.threads_=[];this.expanded=false;this.collapsible_=true;},set threads(threads){this.threads_=threads;this.updateContents_();},set collapsible(collapsible){this.collapsible_=collapsible;this.updateContents_();},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},get expanded(){return this.header_.expanded;},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;this.header_.expanded=expanded;this.viewport_.dispatchChangeEvent();this.updateContents_();},updateContents_:function(){this.detach();if(this.collapsible_){Polymer.dom(this).appendChild(this.header_);}
-if(this.expanded||!this.collapsible_){for(var thread of this.threads_){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}}};return{OtherThreadsTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ColorScheme=tr.b.ColorScheme;var ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)return[];var ops=[];var pushOp=function(isStart,time,slice){ops.push({isStart:isStart,time:time,slice:slice});};for(var tid in process.threads){var sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
-ops.sort(function(a,b){return a.time-b.time;});var rects=[];var genericColorId=ColorScheme.getColorIdForReservedName('generic_work');var pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));};var depth=0;var currentSlice=undefined;var lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice===currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth===1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!==lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
-currentSlice=op.slice;}}else{if(depth===0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate:function(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;var ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;var SpacingTrack=tr.ui.tracks.SpacingTrack;var ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;Polymer.dom(this).classList.add('process-track-base');Polymer.dom(this).classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();Polymer.dom(this.processNameEl_).classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});Polymer.dom(this.headerEl_).appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));Polymer.dom(this).appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){var modelSettings=new tr.model.ModelSettings(this.processBase_.model);var defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
-this.updateContents_();},get expanded(){return Polymer.dom(this).classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;Polymer.dom(this).classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)return;var modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded){return this.children.length>1;}
-return true;},onHeaderClick_:function(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_:function(){this.clearTracks_();if(!this.processBase_)return;Polymer.dom(this.processNameEl_).textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
-this.didAppendTracks_();},willAppendTracks_:function(){},didAppendTracks_:function(){},appendMemoryDumpTrack_:function(){},appendSummaryTrack_:function(){var track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendFrameTrack_:function(){var frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)return;var track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;Polymer.dom(this).appendChild(track);},appendObjectInstanceTracks_:function(){var instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();var instanceTypeNames=Object.keys(instancesByTypeName);instanceTypeNames.sort();var didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){var allInstances=instancesByTypeName[typeName];var instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView){instanceViewInfo=undefined;}
+return subRows;}};return{SliceGroupTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ThreadTrack=tr.ui.b.define('thread-track',tr.ui.tracks.ContainerTrack);ThreadTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('thread-track');this.heading_=document.createElement('tr-ui-b-heading');},get thread(){return this.thread_;},set thread(thread){this.thread_=thread;this.updateContents_();},get hasVisibleContent(){return this.tracks_.length>0;},get hasSlices(){return this.thread_.asyncSliceGroup.length>0||this.thread_.sliceGroup.length>0;},get hasTimeSlices(){return this.thread_.timeSlices;},get eventContainer(){return this.thread;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ContainerTrack.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.thread,this);},updateContents_(){this.detach();if(!this.thread_)return;this.heading_.heading=this.thread_.userFriendlyName;this.heading_.tooltip=this.thread_.userFriendlyDetails;if(this.thread_.asyncSliceGroup.length){this.appendAsyncSliceTracks_();}
+this.appendThreadSamplesTracks_();let needsHeading=false;if(this.thread_.timeSlices){const timeSlicesTrack=new tr.ui.tracks.SliceTrack(this.viewport);timeSlicesTrack.heading='';timeSlicesTrack.height=tr.ui.b.THIN_SLICE_HEIGHT+'px';timeSlicesTrack.slices=this.thread_.timeSlices;if(timeSlicesTrack.hasVisibleContent){needsHeading=true;Polymer.dom(this).appendChild(timeSlicesTrack);}}
+if(this.thread_.sliceGroup.length){const track=new tr.ui.tracks.SliceGroupTrack(this.viewport);track.heading=this.thread_.userFriendlyName;track.tooltip=this.thread_.userFriendlyDetails;track.group=this.thread_.sliceGroup;if(track.hasVisibleContent){needsHeading=false;Polymer.dom(this).appendChild(track);}}
+if(needsHeading){Polymer.dom(this).appendChild(this.heading_);}},appendAsyncSliceTracks_(){const subGroups=this.thread_.asyncSliceGroup.viewSubGroups;subGroups.forEach(function(subGroup){const asyncTrack=new tr.ui.tracks.AsyncSliceGroupTrack(this.viewport);const title=subGroup.slices[0].viewSubGroupTitle;asyncTrack.group=subGroup;asyncTrack.heading=title;if(asyncTrack.hasVisibleContent){Polymer.dom(this).appendChild(asyncTrack);}},this);},appendThreadSamplesTracks_(){const threadSamples=this.thread_.samples;if(threadSamples===undefined||threadSamples.length===0){return;}
+const samplesByTitle={};threadSamples.forEach(function(sample){if(samplesByTitle[sample.title]===undefined){samplesByTitle[sample.title]=[];}
+samplesByTitle[sample.title].push(sample);});const sampleTitles=Object.keys(samplesByTitle);sampleTitles.sort();sampleTitles.forEach(function(sampleTitle){const samples=samplesByTitle[sampleTitle];const samplesTrack=new tr.ui.tracks.SampleTrack(this.viewport);samplesTrack.group=this.thread_;samplesTrack.samples=samples;samplesTrack.heading=this.thread_.userFriendlyName+': '+
+sampleTitle;samplesTrack.tooltip=this.thread_.userFriendlyDetails;samplesTrack.selectionGenerator=function(){const selection=new tr.model.EventSet();for(let i=0;i<samplesTrack.samples.length;i++){selection.push(samplesTrack.samples[i]);}
+return selection;};Polymer.dom(this).appendChild(samplesTrack);},this);},collapsedDidChange(collapsed){if(collapsed){let h=parseInt(this.tracks[0].height);for(let i=0;i<this.tracks.length;++i){if(h>2){this.tracks[i].height=Math.floor(h)+'px';}else{this.tracks[i].style.display='none';}
+h=h*0.5;}}else{for(let i=0;i<this.tracks.length;++i){this.tracks[i].height=this.tracks[0].height;this.tracks[i].style.display='';}}}};return{ThreadTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const OtherThreadsTrack=tr.ui.b.define('other-threads-track',tr.ui.tracks.OtherThreadsTrack);const SpacingTrack=tr.ui.tracks.SpacingTrack;OtherThreadsTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.header_=document.createElement('tr-ui-b-heading');this.header_.addEventListener('click',this.onHeaderClick_.bind(this));this.header_.heading='Other Threads';this.header_.tooltip='Threads with only scheduling information';this.header_.arrowVisible=true;this.threads_=[];this.expanded=false;this.collapsible_=true;},set threads(threads){this.threads_=threads;this.updateContents_();},set collapsible(collapsible){this.collapsible_=collapsible;this.updateContents_();},onHeaderClick_(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},get expanded(){return this.header_.expanded;},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;this.header_.expanded=expanded;this.viewport_.dispatchChangeEvent();this.updateContents_();},updateContents_(){this.detach();if(this.collapsible_){Polymer.dom(this).appendChild(this.header_);}
+if(this.expanded||!this.collapsible_){for(const thread of this.threads_){const track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}}};return{OtherThreadsTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ColorScheme=tr.b.ColorScheme;const ProcessSummaryTrack=tr.ui.b.define('process-summary-track',tr.ui.tracks.RectTrack);ProcessSummaryTrack.buildRectsFromProcess=function(process){if(!process)return[];const ops=[];const pushOp=function(isStart,time,slice){ops.push({isStart,time,slice});};for(const tid in process.threads){const sliceGroup=process.threads[tid].sliceGroup;sliceGroup.topLevelSlices.forEach(function(slice){pushOp(true,slice.start,undefined);pushOp(false,slice.end,undefined);});sliceGroup.slices.forEach(function(slice){if(slice.important){pushOp(true,slice.start,slice);pushOp(false,slice.end,slice);}});}
+ops.sort(function(a,b){return a.time-b.time;});const rects=[];const genericColorId=ColorScheme.getColorIdForReservedName('generic_work');const pushRect=function(start,end,slice){rects.push(new tr.ui.tracks.Rect(slice,slice?slice.title:'',slice?slice.colorId:genericColorId,start,end-start));};let depth=0;let currentSlice=undefined;let lastStart=undefined;ops.forEach(function(op){depth+=op.isStart?1:-1;if(currentSlice){if(!op.isStart&&op.slice===currentSlice){pushRect(lastStart,op.time,currentSlice);lastStart=depth>=1?op.time:undefined;currentSlice=undefined;}}else{if(op.isStart){if(depth===1){lastStart=op.time;currentSlice=op.slice;}else if(op.slice){if(op.time!==lastStart){pushRect(lastStart,op.time,undefined);lastStart=op.time;}
+currentSlice=op.slice;}}else{if(depth===0){pushRect(lastStart,op.time,undefined);lastStart=undefined;}}}});return rects;};ProcessSummaryTrack.prototype={__proto__:tr.ui.tracks.RectTrack.prototype,decorate(viewport){tr.ui.tracks.RectTrack.prototype.decorate.call(this,viewport);},get process(){return this.process_;},set process(process){this.process_=process;this.rects=ProcessSummaryTrack.buildRectsFromProcess(process);}};return{ProcessSummaryTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ObjectSnapshotView=tr.ui.analysis.ObjectSnapshotView;const ObjectInstanceView=tr.ui.analysis.ObjectInstanceView;const SpacingTrack=tr.ui.tracks.SpacingTrack;const ProcessTrackBase=tr.ui.b.define('process-track-base',tr.ui.tracks.ContainerTrack);ProcessTrackBase.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.processBase_=undefined;Polymer.dom(this).classList.add('process-track-base');Polymer.dom(this).classList.add('expanded');this.processNameEl_=tr.ui.b.createSpan();Polymer.dom(this.processNameEl_).classList.add('process-track-name');this.headerEl_=tr.ui.b.createDiv({className:'process-track-header'});Polymer.dom(this.headerEl_).appendChild(this.processNameEl_);this.headerEl_.addEventListener('click',this.onHeaderClick_.bind(this));Polymer.dom(this).appendChild(this.headerEl_);},get processBase(){return this.processBase_;},set processBase(processBase){this.processBase_=processBase;if(this.processBase_){const modelSettings=new tr.model.ModelSettings(this.processBase_.model);const defaultValue=this.processBase_.important;this.expanded=modelSettings.getSettingFor(this.processBase_,'expanded',defaultValue);}
+this.updateContents_();},get expanded(){return Polymer.dom(this).classList.contains('expanded');},set expanded(expanded){expanded=!!expanded;if(this.expanded===expanded)return;Polymer.dom(this).classList.toggle('expanded');this.viewport_.dispatchChangeEvent();if(!this.processBase_)return;const modelSettings=new tr.model.ModelSettings(this.processBase_.model);modelSettings.setSettingFor(this.processBase_,'expanded',expanded);this.updateContents_();this.viewport.rebuildEventToTrackMap();this.viewport.rebuildContainerToTrackMap();},get hasVisibleContent(){if(this.expanded){return this.children.length>1;}
+return true;},onHeaderClick_(e){e.stopPropagation();e.preventDefault();this.expanded=!this.expanded;},updateContents_(){this.clearTracks_();if(!this.processBase_)return;Polymer.dom(this.processNameEl_).textContent=this.processBase_.userFriendlyName;this.headerEl_.title=this.processBase_.userFriendlyDetails;this.willAppendTracks_();if(this.expanded){this.appendMemoryDumpTrack_();this.appendObjectInstanceTracks_();this.appendCounterTracks_();this.appendFrameTrack_();this.appendThreadTracks_();}else{this.appendSummaryTrack_();}
+this.didAppendTracks_();},willAppendTracks_(){},didAppendTracks_(){},appendMemoryDumpTrack_(){},appendSummaryTrack_(){const track=new tr.ui.tracks.ProcessSummaryTrack(this.viewport);track.process=this.process;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendFrameTrack_(){const frames=this.process?this.process.frames:undefined;if(!frames||!frames.length)return;const track=new tr.ui.tracks.FrameTrack(this.viewport);track.frames=frames;Polymer.dom(this).appendChild(track);},appendObjectInstanceTracks_(){const instancesByTypeName=this.processBase_.objects.getAllInstancesByTypeName();const instanceTypeNames=Object.keys(instancesByTypeName);instanceTypeNames.sort();let didAppendAtLeastOneTrack=false;instanceTypeNames.forEach(function(typeName){const allInstances=instancesByTypeName[typeName];let instanceViewInfo=ObjectInstanceView.getTypeInfo(undefined,typeName);let snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(instanceViewInfo&&!instanceViewInfo.metadata.showInTrackView){instanceViewInfo=undefined;}
 if(snapshotViewInfo&&!snapshotViewInfo.metadata.showInTrackView){snapshotViewInfo=undefined;}
-var hasViewInfo=instanceViewInfo||snapshotViewInfo;var visibleInstances=[];for(var i=0;i<allInstances.length;i++){var instance=allInstances[i];if(instance.snapshots.length===0)continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)continue;visibleInstances.push(instance);}
-if(visibleInstances.length===0)return;var trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){var snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
-var track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}},appendCounterTracks_:function(){var counters=tr.b.dictionaryValues(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){var track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_:function(){var threads=tr.b.dictionaryValues(this.processBase.threads);threads.sort(tr.model.Thread.compare);var otherThreads=[];var hasVisibleThreads=false;threads.forEach(function(thread){var track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;if(track.hasSlices){hasVisibleThreads=true;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}else if(track.hasTimeSlices){otherThreads.push(thread);}}.bind(this));if(otherThreads.length>0){var track=new tr.ui.tracks.OtherThreadsTrack(this.viewport);track.threads=otherThreads;track.collapsible=otherThreads.length>1&&hasVisibleThreads;Polymer.dom(this).appendChild(track);}}};return{ProcessTrackBase,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var Cpu=tr.model.Cpu;var CpuTrack=tr.ui.tracks.cpu_track;var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var SpacingTrack=tr.ui.tracks.SpacingTrack;var KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_:function(){var cpus=tr.b.dictionaryValues(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);var didAppendAtLeastOneTrack=false;for(var i=0;i<cpus.length;++i){var cpu=cpus[i];var track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;}
-if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}};return{KernelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate:function(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocateSimple(),model:model,getSettingsKey:function(){return undefined;}});},buildSubRows_:function(slices){if(this.subRows_.length){return this.subRows_;}
-this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_:function(slices){var track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;}};return{InteractionTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ALLOCATED_MEMORY_TRACK_HEIGHT=50;var ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_:function(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_:function(){var series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;var track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{ProcessMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;var ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate:function(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack:function(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0){break;}
-var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
-tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_:function(){var ctx=this.context();var canvasBounds=ctx.canvas.getBoundingClientRect();var pixelRatio=window.devicePixelRatio||1;var draw=false;ctx.fillStyle='#eee';for(var i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack)){continue;}
-draw=!draw;if(!draw)continue;var bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap:function(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_:function(){var processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){var pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;Polymer.dom(this).appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=2*viewPixWidthWorld;tr.b.math.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var SelectionState=tr.model.SelectionState;var ColorScheme=tr.b.ColorScheme;var EventPresenter=tr.ui.b.EventPresenter;var ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.VSYNC_HIGHLIGHT_ALPHA=0.1;ModelTrack.VSYNC_DENSITY_TRANSPARENT=0.20;ModelTrack.VSYNC_DENSITY_OPAQUE=0.10;ModelTrack.VSYNC_DENSITY_RANGE=ModelTrack.VSYNC_DENSITY_TRANSPARENT-ModelTrack.VSYNC_DENSITY_OPAQUE;ModelTrack.generateStripes_=function(times,minTime,maxTime){if(times.length===0)return[];var lowIndex=tr.b.math.findLowIndexInSortedArray(times,tr.b.identity,minTime);var highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
-var stripes=[];for(var i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){var left=i<lowIndex?minTime:times[i];var right=i+1>highIndex?maxTime:times[i+1];stripes.push(tr.b.math.Range.fromExplicitRange(left,right));}
-return stripes;};ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate:function(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('model-track');this.upperMode_=false;this.annotationViews_=[];this.vSyncTimes_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach:function(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_:function(){Polymer.dom(this).textContent='';if(!this.model_)return;if(this.upperMode_){this.updateContentsForUpperMode_();}else{this.updateContentsForLowerMode_();}},updateContentsForUpperMode_:function(){},updateContentsForLowerMode_:function(){if(this.model_.userModel.expectations.length>1){var mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;Polymer.dom(this).appendChild(mrt);}
-if(this.model_.alerts.length){var at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;Polymer.dom(this).appendChild(at);}
-if(this.model_.globalMemoryDumps.length){var gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;Polymer.dom(this).appendChild(gmdt);}
-this.appendDeviceTrack_();this.appendCpuUsageTrack_();this.appendKernelTrack_();var processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(var i=0;i<processes.length;++i){var process=processes[i];var track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);}
-this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();this.vSyncTimes_=this.model_.device.vSyncTimestamps;this.updateAnnotations_();},getContentBounds:function(){return this.model.bounds;},addAnnotation:function(annotation){this.model.addAnnotation(annotation);},removeAnnotation:function(annotation){this.model.removeAnnotation(annotation);},updateAnnotations_:function(){this.annotationViews_=[];var annotations=this.model_.getAllAnnotations();for(var i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
-this.invalidateDrawingContainer();},addEventsToTrackMap:function(eventToTrackMap){if(!this.model_)return;var tracks=this.children;for(var i=0;i<tracks.length;++i){tracks[i].addEventsToTrackMap(eventToTrackMap);}
-if(this.instantEvents===undefined)return;var vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_:function(){var device=this.model.device;var track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendKernelTrack_:function(){var kernel=this.model.kernel;var track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendCpuUsageTrack_:function(){var track=new tr.ui.tracks.CpuUsageTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;this.appendChild(track);},appendCpuUsageTrack_:function(){var track=new tr.ui.tracks.CpuUsageTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;this.appendChild(track);},drawTrack:function(type){var ctx=this.context();if(!this.model_)return;var pixelRatio=window.devicePixelRatio||1;var bounds=this.getBoundingClientRect();var canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));var dt=this.viewport.currentDisplayTransform;var viewLWorld=dt.xViewToWorld(0);var viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
+const hasViewInfo=instanceViewInfo||snapshotViewInfo;const visibleInstances=[];for(let i=0;i<allInstances.length;i++){const instance=allInstances[i];if(instance.snapshots.length===0)continue;if(instance.hasImplicitSnapshots&&!hasViewInfo)continue;visibleInstances.push(instance);}
+if(visibleInstances.length===0)return;let trackConstructor=tr.ui.tracks.ObjectInstanceTrack.getConstructor(undefined,typeName);if(!trackConstructor){snapshotViewInfo=ObjectSnapshotView.getTypeInfo(undefined,typeName);if(snapshotViewInfo&&snapshotViewInfo.metadata.showInstances){trackConstructor=tr.ui.tracks.ObjectInstanceGroupTrack;}else{trackConstructor=tr.ui.tracks.ObjectInstanceTrack;}}
+const track=new trackConstructor(this.viewport);track.objectInstances=visibleInstances;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;},this);if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}},appendCounterTracks_(){const counters=Object.values(this.processBase.counters);counters.sort(tr.model.Counter.compare);counters.forEach(function(counter){const track=new tr.ui.tracks.CounterTrack(this.viewport);track.counter=counter;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}.bind(this));},appendThreadTracks_(){const threads=Object.values(this.processBase.threads);threads.sort(tr.model.Thread.compare);const otherThreads=[];let hasVisibleThreads=false;threads.forEach(function(thread){const track=new tr.ui.tracks.ThreadTrack(this.viewport);track.thread=thread;if(!track.hasVisibleContent)return;if(track.hasSlices){hasVisibleThreads=true;Polymer.dom(this).appendChild(track);Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}else if(track.hasTimeSlices){otherThreads.push(thread);}}.bind(this));if(otherThreads.length>0){const track=new tr.ui.tracks.OtherThreadsTrack(this.viewport);track.threads=otherThreads;track.collapsible=otherThreads.length>1&&hasVisibleThreads;Polymer.dom(this).appendChild(track);}}};return{ProcessTrackBase,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const Cpu=tr.model.Cpu;const CpuTrack=tr.ui.tracks.cpu_track;const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const SpacingTrack=tr.ui.tracks.SpacingTrack;const KernelTrack=tr.ui.b.define('kernel-track',ProcessTrackBase);KernelTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){ProcessTrackBase.prototype.decorate.call(this,viewport);},set kernel(kernel){this.processBase=kernel;},get kernel(){return this.processBase;},get eventContainer(){return this.kernel;},get hasVisibleContent(){return this.children.length>1;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.call(this,containerToTrackMap);containerToTrackMap.addContainer(this.kernel,this);},willAppendTracks_(){const cpus=Object.values(this.kernel.cpus);cpus.sort(tr.model.Cpu.compare);let didAppendAtLeastOneTrack=false;for(let i=0;i<cpus.length;++i){const cpu=cpus[i];const track=new tr.ui.tracks.CpuTrack(this.viewport);track.detailedMode=this.expanded;track.cpu=cpu;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);didAppendAtLeastOneTrack=true;}
+if(didAppendAtLeastOneTrack){Polymer.dom(this).appendChild(new SpacingTrack(this.viewport));}}};return{KernelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const InteractionTrack=tr.ui.b.define('interaction-track',tr.ui.tracks.MultiRowTrack);InteractionTrack.prototype={__proto__:tr.ui.tracks.MultiRowTrack.prototype,decorate(viewport){tr.ui.tracks.MultiRowTrack.prototype.decorate.call(this,viewport);this.heading='Interactions';this.subRows_=[];},set model(model){this.setItemsToGroup(model.userModel.expectations,{guid:tr.b.GUID.allocateSimple(),model,getSettingsKey(){return undefined;}});},buildSubRows_(slices){if(this.subRows_.length){return this.subRows_;}
+this.subRows_.push.apply(this.subRows_,tr.ui.tracks.AsyncSliceGroupTrack.prototype.buildSubRows_.call({},slices,true));return this.subRows_;},addSubTrack_(slices){const track=new tr.ui.tracks.SliceTrack(this.viewport);track.slices=slices;Polymer.dom(this).appendChild(track);return track;}};return{InteractionTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ALLOCATED_MEMORY_TRACK_HEIGHT=50;const ProcessMemoryDumpTrack=tr.ui.b.define('process-memory-dump-track',tr.ui.tracks.ContainerTrack);ProcessMemoryDumpTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);this.memoryDumps_=undefined;},get memoryDumps(){return this.memoryDumps_;},set memoryDumps(memoryDumps){this.memoryDumps_=memoryDumps;this.updateContents_();},updateContents_(){this.clearTracks_();if(!this.memoryDumps_||!this.memoryDumps_.length)return;this.appendAllocatedMemoryTrack_();},appendAllocatedMemoryTrack_(){const series=tr.ui.tracks.buildProcessAllocatedMemoryChartSeries(this.memoryDumps_);if(!series)return;const track=new tr.ui.tracks.ChartTrack(this.viewport);track.heading='Memory per component';track.height=ALLOCATED_MEMORY_TRACK_HEIGHT+'px';track.series=series;track.autoSetAllAxes({expandMax:true});Polymer.dom(this).appendChild(track);}};return{ProcessMemoryDumpTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const ProcessTrackBase=tr.ui.tracks.ProcessTrackBase;const ProcessTrack=tr.ui.b.define('process-track',ProcessTrackBase);ProcessTrack.prototype={__proto__:ProcessTrackBase.prototype,decorate(viewport){tr.ui.tracks.ProcessTrackBase.prototype.decorate.call(this,viewport);},drawTrack(type){switch(type){case tr.ui.tracks.DrawType.INSTANT_EVENT:{if(!this.processBase.instantEvents||this.processBase.instantEvents.length===0){break;}
+const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.processBase.instantEvents,2);ctx.restore();break;}
+case tr.ui.tracks.DrawType.BACKGROUND:this.drawBackground_();return;}
+tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawBackground_(){const ctx=this.context();const canvasBounds=ctx.canvas.getBoundingClientRect();const pixelRatio=window.devicePixelRatio||1;let draw=false;ctx.fillStyle='#eee';for(let i=0;i<this.children.length;++i){if(!(this.children[i]instanceof tr.ui.tracks.Track)||(this.children[i]instanceof tr.ui.tracks.SpacingTrack)){continue;}
+draw=!draw;if(!draw)continue;const bounds=this.children[i].getBoundingClientRect();ctx.fillRect(0,pixelRatio*(bounds.top-canvasBounds.top),ctx.canvas.width,pixelRatio*bounds.height);}},set process(process){this.processBase=process;},get process(){return this.processBase;},get eventContainer(){return this.process;},addContainersToTrackMap(containerToTrackMap){tr.ui.tracks.ProcessTrackBase.prototype.addContainersToTrackMap.apply(this,arguments);containerToTrackMap.addContainer(this.process,this);},appendMemoryDumpTrack_(){const processMemoryDumps=this.process.memoryDumps;if(processMemoryDumps.length){const pmdt=new tr.ui.tracks.ProcessMemoryDumpTrack(this.viewport_);pmdt.memoryDumps=processMemoryDumps;Polymer.dom(this).appendChild(pmdt);}},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+const instantEventWidth=2*viewPixWidthWorld;tr.b.math.iterateOverIntersectingIntervals(this.processBase.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.processBase.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ProcessTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const SelectionState=tr.model.SelectionState;const ColorScheme=tr.b.ColorScheme;const EventPresenter=tr.ui.b.EventPresenter;const ModelTrack=tr.ui.b.define('model-track',tr.ui.tracks.ContainerTrack);ModelTrack.VSYNC_HIGHLIGHT_ALPHA=0.1;ModelTrack.VSYNC_DENSITY_TRANSPARENT=0.20;ModelTrack.VSYNC_DENSITY_OPAQUE=0.10;ModelTrack.VSYNC_DENSITY_RANGE=ModelTrack.VSYNC_DENSITY_TRANSPARENT-ModelTrack.VSYNC_DENSITY_OPAQUE;ModelTrack.generateStripes_=function(times,minTime,maxTime){if(times.length===0)return[];const lowIndex=tr.b.math.findLowIndexInSortedArray(times,tr.b.identity,minTime);let highIndex=lowIndex-1;while(times[highIndex+1]<=maxTime){highIndex++;}
+const stripes=[];for(let i=lowIndex-(lowIndex%2);i<=highIndex;i+=2){const left=i<lowIndex?minTime:times[i];const right=i+1>highIndex?maxTime:times[i+1];stripes.push(tr.b.math.Range.fromExplicitRange(left,right));}
+return stripes;};ModelTrack.prototype={__proto__:tr.ui.tracks.ContainerTrack.prototype,decorate(viewport){tr.ui.tracks.ContainerTrack.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('model-track');this.upperMode_=false;this.annotationViews_=[];this.vSyncTimes_=[];},get upperMode(){return this.upperMode_;},set upperMode(upperMode){this.upperMode_=upperMode;this.updateContents_();},detach(){tr.ui.tracks.ContainerTrack.prototype.detach.call(this);},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();this.model_.addEventListener('annotationChange',this.updateAnnotations_.bind(this));},get hasVisibleContent(){return this.children.length>0;},updateContents_(){Polymer.dom(this).textContent='';if(!this.model_)return;if(this.upperMode_){this.updateContentsForUpperMode_();}else{this.updateContentsForLowerMode_();}},updateContentsForUpperMode_(){},updateContentsForLowerMode_(){if(this.model_.userModel.expectations.length>1){const mrt=new tr.ui.tracks.InteractionTrack(this.viewport_);mrt.model=this.model_;Polymer.dom(this).appendChild(mrt);}
+if(this.model_.alerts.length){const at=new tr.ui.tracks.AlertTrack(this.viewport_);at.alerts=this.model_.alerts;Polymer.dom(this).appendChild(at);}
+if(this.model_.globalMemoryDumps.length){const gmdt=new tr.ui.tracks.GlobalMemoryDumpTrack(this.viewport_);gmdt.memoryDumps=this.model_.globalMemoryDumps;Polymer.dom(this).appendChild(gmdt);}
+this.appendDeviceTrack_();this.appendCpuUsageTrack_();this.appendKernelTrack_();const processes=this.model_.getAllProcesses();processes.sort(tr.model.Process.compare);for(let i=0;i<processes.length;++i){const process=processes[i];const track=new tr.ui.tracks.ProcessTrack(this.viewport);track.process=process;if(!track.hasVisibleContent)continue;Polymer.dom(this).appendChild(track);}
+this.viewport_.rebuildEventToTrackMap();this.viewport_.rebuildContainerToTrackMap();this.vSyncTimes_=this.model_.device.vSyncTimestamps;this.updateAnnotations_();},getContentBounds(){return this.model.bounds;},addAnnotation(annotation){this.model.addAnnotation(annotation);},removeAnnotation(annotation){this.model.removeAnnotation(annotation);},updateAnnotations_(){this.annotationViews_=[];const annotations=this.model_.getAllAnnotations();for(let i=0;i<annotations.length;i++){this.annotationViews_.push(annotations[i].getOrCreateView(this.viewport_));}
+this.invalidateDrawingContainer();},addEventsToTrackMap(eventToTrackMap){if(!this.model_)return;const tracks=this.children;for(let i=0;i<tracks.length;++i){tracks[i].addEventsToTrackMap(eventToTrackMap);}
+if(this.instantEvents===undefined)return;const vp=this.viewport_;this.instantEvents.forEach(function(ev){eventToTrackMap.addEvent(ev,this);}.bind(this));},appendDeviceTrack_(){const device=this.model.device;const track=new tr.ui.tracks.DeviceTrack(this.viewport);track.device=this.model.device;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendKernelTrack_(){const kernel=this.model.kernel;const track=new tr.ui.tracks.KernelTrack(this.viewport);track.kernel=this.model.kernel;if(!track.hasVisibleContent)return;Polymer.dom(this).appendChild(track);},appendCpuUsageTrack_(){const track=new tr.ui.tracks.CpuUsageTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;this.appendChild(track);},appendCpuUsageTrack_(){const track=new tr.ui.tracks.CpuUsageTrack(this.viewport);track.initialize(this.model);if(!track.hasVisibleContent)return;this.appendChild(track);},drawTrack(type){const ctx=this.context();if(!this.model_)return;const pixelRatio=window.devicePixelRatio||1;const bounds=this.getBoundingClientRect();const canvasBounds=ctx.canvas.getBoundingClientRect();ctx.save();ctx.translate(0,pixelRatio*(bounds.top-canvasBounds.top));const dt=this.viewport.currentDisplayTransform;const viewLWorld=dt.xViewToWorld(0);const viewRWorld=dt.xViewToWorld(bounds.width*pixelRatio);switch(type){case tr.ui.tracks.DrawType.GRID:this.viewport.drawMajorMarkLines(ctx);ctx.restore();return;case tr.ui.tracks.DrawType.FLOW_ARROWS:if(this.model_.flowIntervalTree.size===0){ctx.restore();return;}
 this.drawFlowArrows_(viewLWorld,viewRWorld);ctx.restore();return;case tr.ui.tracks.DrawType.INSTANT_EVENT:if(!this.model_.instantEvents||this.model_.instantEvents.length===0){break;}
 tr.ui.b.drawInstantSlicesAsLines(ctx,this.viewport.currentDisplayTransform,viewLWorld,viewRWorld,bounds.height,this.model_.instantEvents,4);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(ctx,viewLWorld,viewRWorld);this.viewport.interestRange.drawIndicators(ctx,viewLWorld,viewRWorld);}
-ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:this.drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(var i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
+ctx.restore();return;case tr.ui.tracks.DrawType.HIGHLIGHTS:this.drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,bounds.height);ctx.restore();return;case tr.ui.tracks.DrawType.ANNOTATIONS:for(let i=0;i<this.annotationViews_.length;i++){this.annotationViews_[i].draw(ctx);}
 ctx.restore();return;}
-ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_:function(viewLWorld,viewRWorld){var ctx=this.context();var dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);var pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;var events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);var onlyHighlighted=!this.viewport.showFlowEvents;var canvasBounds=ctx.canvas.getBoundingClientRect();for(var i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED){continue;}
-this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_:function(ctx,flowEvent,canvasBounds,pixWidth){var pixelRatio=window.devicePixelRatio||1;var startTrack=this.viewport.trackForEvent(flowEvent.startSlice);var endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)return;var startBounds=startTrack.getBoundingClientRect();var endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState===SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState===SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState===SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{var hasBoost=false;var startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;var endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
-var startSize=startBounds.left+startBounds.top+
-startBounds.bottom+startBounds.right;var endSize=endBounds.left+endBounds.top+
-endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)return;var startY=this.calculateTrackY_(startTrack,canvasBounds);var endY=this.calculateTrackY_(endTrack,canvasBounds);var pixelStartY=pixelRatio*startY;var pixelEndY=pixelRatio*endY;var half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();var arrowWidth=5*pixWidth*pixelRatio;var distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))return;var tipX=flowEvent.end;var tipY=pixelEndY;var arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},drawVSyncHighlight:function(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
-var stripes=ModelTrack.generateStripes_(this.vSyncTimes_,viewLWorld,viewRWorld);if(stripes.length===0){return;}
-var vSyncHighlightColor=new tr.b.Color(ColorScheme.getColorForReservedNameAsString('vsync_highlight_color'));var stripeRange=stripes[stripes.length-1].max-stripes[0].min;var stripeDensity=stripeRange?stripes.length/(dt.scaleX*stripeRange):0;var clampedStripeDensity=tr.b.math.clamp(stripeDensity,ModelTrack.VSYNC_DENSITY_OPAQUE,ModelTrack.VSYNC_DENSITY_TRANSPARENT);var opacity=(ModelTrack.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/ModelTrack.VSYNC_DENSITY_RANGE;if(opacity===0){return;}
-var pixelRatio=window.devicePixelRatio||1;var height=viewHeight*pixelRatio;ctx.fillStyle=vSyncHighlightColor.toStringWithAlphaOverride(ModelTrack.VSYNC_HIGHLIGHT_ALPHA*opacity);for(var i=0;i<stripes.length;i++){var xLeftView=dt.xWorldToView(stripes[i].min);var xRightView=dt.xWorldToView(stripes[i].max);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}},calculateTrackY_:function(track,canvasBounds){var bounds=track.getBoundingClientRect();var size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0){return this.calculateTrackY_(Polymer.dom(track).parentNode,canvasBounds);}
-return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace:function(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
-var instantEventWidth=3*viewPixWidthWorld;tr.b.math.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection:function(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){var XAxisTrack=tr.ui.b.define('x-axis-track',tr.ui.tracks.Track);XAxisTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate:function(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('x-axis-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);var heading=document.createElement('tr-ui-b-heading');heading.arrowVisible=false;Polymer.dom(this).appendChild(heading);},detach:function(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_:function(){if(this.viewport.interestRange.isEmpty){Polymer.dom(this).classList.remove('tall-mode');}else{Polymer.dom(this).classList.add('tall-mode');}},draw:function(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);}
-break;}},drawGrid_:function(viewLWorld,viewRWorld){var ctx=this.context();var pixelRatio=window.devicePixelRatio||1;var canvasBounds=ctx.canvas.getBoundingClientRect();var trackBounds=this.getBoundingClientRect();var width=canvasBounds.width*pixelRatio;var height=trackBounds.height*pixelRatio;var hasInterestRange=!this.viewport.interestRange.isEmpty;var xAxisHeightPx=hasInterestRange?(height*2)/5:height;var vp=this.viewport;var dt=vp.currentDisplayTransform;vp.updateMajorMarkData(viewLWorld,viewRWorld);var majorMarkDistanceWorld=vp.majorMarkWorldPositions.length>1?vp.majorMarkWorldPositions[1]-vp.majorMarkWorldPositions[0]:0;var numTicksPerMajor=5;var minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;var minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);var minorTickHeight=Math.floor(xAxisHeightPx*0.25);ctx.save();var pixelRatio=window.devicePixelRatio||1;ctx.lineWidth=Math.round(pixelRatio);var crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';var tickLabels=[];ctx.beginPath();for(var i=0;i<vp.majorMarkWorldPositions.length;i++){var curXWorld=vp.majorMarkWorldPositions[i];var curXView=dt.xWorldToView(curXWorld);var displayText=vp.majorMarkUnit.format(curXWorld,{deltaValue:majorMarkDistanceWorld});ctx.fillText(displayText,curXView+(2*pixelRatio),0);tr.ui.b.drawLine(ctx,curXView,0,curXView,xAxisHeightPx);if(minorMarkDistancePx){for(var j=1;j<numTicksPerMajor;++j){var xView=Math.floor(curXView+minorMarkDistancePx*j);tr.ui.b.drawLine(ctx,xView,xAxisHeightPx-minorTickHeight,xView,xAxisHeightPx);}}}
-ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)return;tr.ui.b.drawLine(ctx,0,xAxisHeightPx,width,xAxisHeightPx);ctx.stroke();var displayDistance;var displayTextColor='rgb(0,0,0)';var arrowSpacing=10*pixelRatio;var arrowColor='rgb(128,121,121)';var arrowPosY=xAxisHeightPx*1.75;var arrowWidthView=3*pixelRatio;var arrowLengthView=10*pixelRatio;var spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';var textPosY=arrowPosY;var interestRange=vp.interestRange;if(interestRange.range===0){var markerWorld=interestRange.min;var markerView=dt.xWorldToView(markerWorld);var textToDraw=vp.majorMarkUnit.format(markerWorld);var textLeftView=markerView+4*pixelRatio;var textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width){textLeftView=markerView-4*pixelRatio-textWidthView;}
+ctx.restore();tr.ui.tracks.ContainerTrack.prototype.drawTrack.call(this,type);},drawFlowArrows_(viewLWorld,viewRWorld){const ctx=this.context();const dt=this.viewport.currentDisplayTransform;dt.applyTransformToCanvas(ctx);const pixWidth=dt.xViewVectorToWorld(1);ctx.strokeStyle='rgba(0, 0, 0, 0.4)';ctx.fillStyle='rgba(0, 0, 0, 0.4)';ctx.lineWidth=pixWidth>1.0?1:pixWidth;const events=this.model_.flowIntervalTree.findIntersection(viewLWorld,viewRWorld);const onlyHighlighted=!this.viewport.showFlowEvents;const canvasBounds=ctx.canvas.getBoundingClientRect();for(let i=0;i<events.length;++i){if(onlyHighlighted&&events[i].selectionState!==SelectionState.SELECTED&&events[i].selectionState!==SelectionState.HIGHLIGHTED){continue;}
+this.drawFlowArrow_(ctx,events[i],canvasBounds,pixWidth);}},drawFlowArrow_(ctx,flowEvent,canvasBounds,pixWidth){const pixelRatio=window.devicePixelRatio||1;const startTrack=this.viewport.trackForEvent(flowEvent.startSlice);const endTrack=this.viewport.trackForEvent(flowEvent.endSlice);if(startTrack===undefined||endTrack===undefined)return;const startBounds=startTrack.getBoundingClientRect();const endBounds=endTrack.getBoundingClientRect();if(flowEvent.selectionState===SelectionState.SELECTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState===SelectionState.HIGHLIGHTED){ctx.shadowBlur=1;ctx.shadowColor='red';ctx.shadowOffsety=2;ctx.strokeStyle='red';}else if(flowEvent.selectionState===SelectionState.DIMMED){ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.2)';}else{let hasBoost=false;const startSlice=flowEvent.startSlice;hasBoost|=startSlice.selectionState===SelectionState.SELECTED;hasBoost|=startSlice.selectionState===SelectionState.HIGHLIGHTED;const endSlice=flowEvent.endSlice;hasBoost|=endSlice.selectionState===SelectionState.SELECTED;hasBoost|=endSlice.selectionState===SelectionState.HIGHLIGHTED;if(hasBoost){ctx.shadowBlur=1;ctx.shadowColor='rgba(255, 0, 0, 0.4)';ctx.shadowOffsety=2;ctx.strokeStyle='rgba(255, 0, 0, 0.4)';}else{ctx.shadowBlur=0;ctx.shadowOffsetX=0;ctx.strokeStyle='rgba(0, 0, 0, 0.4)';}}
+const startSize=startBounds.left+startBounds.top+
+startBounds.bottom+startBounds.right;const endSize=endBounds.left+endBounds.top+
+endBounds.bottom+endBounds.right;if(startSize===0&&endSize===0)return;const startY=this.calculateTrackY_(startTrack,canvasBounds);const endY=this.calculateTrackY_(endTrack,canvasBounds);const pixelStartY=pixelRatio*startY;const pixelEndY=pixelRatio*endY;const half=(flowEvent.end-flowEvent.start)/2;ctx.beginPath();ctx.moveTo(flowEvent.start,pixelStartY);ctx.bezierCurveTo(flowEvent.start+half,pixelStartY,flowEvent.start+half,pixelEndY,flowEvent.end,pixelEndY);ctx.stroke();const arrowWidth=5*pixWidth*pixelRatio;const distance=flowEvent.end-flowEvent.start;if(distance<=(2*arrowWidth))return;const tipX=flowEvent.end;const tipY=pixelEndY;const arrowHeight=(endBounds.height/4)*pixelRatio;tr.ui.b.drawTriangle(ctx,tipX,tipY,tipX-arrowWidth,tipY-arrowHeight,tipX-arrowWidth,tipY+arrowHeight);ctx.fill();},drawVSyncHighlight(ctx,dt,viewLWorld,viewRWorld,viewHeight){if(!this.viewport_.highlightVSync){return;}
+const stripes=ModelTrack.generateStripes_(this.vSyncTimes_,viewLWorld,viewRWorld);if(stripes.length===0){return;}
+const vSyncHighlightColor=new tr.b.Color(ColorScheme.getColorForReservedNameAsString('vsync_highlight_color'));const stripeRange=stripes[stripes.length-1].max-stripes[0].min;const stripeDensity=stripeRange?stripes.length/(dt.scaleX*stripeRange):0;const clampedStripeDensity=tr.b.math.clamp(stripeDensity,ModelTrack.VSYNC_DENSITY_OPAQUE,ModelTrack.VSYNC_DENSITY_TRANSPARENT);const opacity=(ModelTrack.VSYNC_DENSITY_TRANSPARENT-clampedStripeDensity)/ModelTrack.VSYNC_DENSITY_RANGE;if(opacity===0){return;}
+const pixelRatio=window.devicePixelRatio||1;const height=viewHeight*pixelRatio;ctx.fillStyle=vSyncHighlightColor.toStringWithAlphaOverride(ModelTrack.VSYNC_HIGHLIGHT_ALPHA*opacity);for(let i=0;i<stripes.length;i++){const xLeftView=dt.xWorldToView(stripes[i].min);const xRightView=dt.xWorldToView(stripes[i].max);ctx.fillRect(xLeftView,0,xRightView-xLeftView,height);}},calculateTrackY_(track,canvasBounds){const bounds=track.getBoundingClientRect();const size=bounds.left+bounds.top+bounds.bottom+bounds.right;if(size===0){return this.calculateTrackY_(Polymer.dom(track).parentNode,canvasBounds);}
+return bounds.top-canvasBounds.top+(bounds.height/2);},addIntersectingEventsInRangeToSelectionInWorldSpace(loWX,hiWX,viewPixWidthWorld,selection){function onPickHit(instantEvent){selection.push(instantEvent);}
+const instantEventWidth=3*viewPixWidthWorld;tr.b.math.iterateOverIntersectingIntervals(this.model_.instantEvents,function(x){return x.start;},function(x){return x.duration+instantEventWidth;},loWX,hiWX,onPickHit.bind(this));tr.ui.tracks.ContainerTrack.prototype.addIntersectingEventsInRangeToSelectionInWorldSpace.apply(this,arguments);},addClosestEventToSelection(worldX,worldMaxDist,loY,hiY,selection){this.addClosestInstantEventToSelection(this.model_.instantEvents,worldX,worldMaxDist,selection);tr.ui.tracks.ContainerTrack.prototype.addClosestEventToSelection.apply(this,arguments);}};return{ModelTrack,};});'use strict';tr.exportTo('tr.ui.tracks',function(){const XAxisTrack=tr.ui.b.define('x-axis-track',tr.ui.tracks.Track);XAxisTrack.prototype={__proto__:tr.ui.tracks.Track.prototype,decorate(viewport){tr.ui.tracks.Track.prototype.decorate.call(this,viewport);Polymer.dom(this).classList.add('x-axis-track');this.strings_secs_=[];this.strings_msecs_=[];this.strings_usecs_=[];this.strings_nsecs_=[];this.viewportChange_=this.viewportChange_.bind(this);viewport.addEventListener('change',this.viewportChange_);const heading=document.createElement('tr-ui-b-heading');heading.arrowVisible=false;Polymer.dom(this).appendChild(heading);},detach(){tr.ui.tracks.Track.prototype.detach.call(this);this.viewport.removeEventListener('change',this.viewportChange_);},viewportChange_(){if(this.viewport.interestRange.isEmpty){Polymer.dom(this).classList.remove('tall-mode');}else{Polymer.dom(this).classList.add('tall-mode');}},draw(type,viewLWorld,viewRWorld){switch(type){case tr.ui.tracks.DrawType.GRID:this.drawGrid_(viewLWorld,viewRWorld);break;case tr.ui.tracks.DrawType.MARKERS:if(!this.viewport.interestRange.isEmpty){this.viewport.interestRange.draw(this.context(),viewLWorld,viewRWorld);}
+break;}},drawGrid_(viewLWorld,viewRWorld){const ctx=this.context();const pixelRatio=window.devicePixelRatio||1;const canvasBounds=ctx.canvas.getBoundingClientRect();const trackBounds=this.getBoundingClientRect();const width=canvasBounds.width*pixelRatio;const height=trackBounds.height*pixelRatio;const hasInterestRange=!this.viewport.interestRange.isEmpty;const xAxisHeightPx=hasInterestRange?(height*2)/5:height;const vp=this.viewport;const dt=vp.currentDisplayTransform;vp.updateMajorMarkData(viewLWorld,viewRWorld);const majorMarkDistanceWorld=vp.majorMarkWorldPositions.length>1?vp.majorMarkWorldPositions[1]-vp.majorMarkWorldPositions[0]:0;const numTicksPerMajor=5;const minorMarkDistanceWorld=majorMarkDistanceWorld/numTicksPerMajor;const minorMarkDistancePx=dt.xWorldVectorToView(minorMarkDistanceWorld);const minorTickHeight=Math.floor(xAxisHeightPx*0.25);ctx.save();ctx.lineWidth=Math.round(pixelRatio);const crispLineCorrection=(ctx.lineWidth%2)/2;ctx.translate(crispLineCorrection,-crispLineCorrection);ctx.fillStyle='rgb(0, 0, 0)';ctx.strokeStyle='rgb(0, 0, 0)';ctx.textAlign='left';ctx.textBaseline='top';ctx.font=(9*pixelRatio)+'px sans-serif';const tickLabels=[];ctx.beginPath();for(let i=0;i<vp.majorMarkWorldPositions.length;i++){const curXWorld=vp.majorMarkWorldPositions[i];const curXView=dt.xWorldToView(curXWorld);const displayText=vp.majorMarkUnit.format(curXWorld,{deltaValue:majorMarkDistanceWorld});ctx.fillText(displayText,curXView+(2*pixelRatio),0);tr.ui.b.drawLine(ctx,curXView,0,curXView,xAxisHeightPx);if(minorMarkDistancePx){for(let j=1;j<numTicksPerMajor;++j){const xView=Math.floor(curXView+minorMarkDistancePx*j);tr.ui.b.drawLine(ctx,xView,xAxisHeightPx-minorTickHeight,xView,xAxisHeightPx);}}}
+ctx.strokeStyle='rgb(0, 0, 0)';tr.ui.b.drawLine(ctx,0,height,width,height);ctx.stroke();if(!hasInterestRange)return;tr.ui.b.drawLine(ctx,0,xAxisHeightPx,width,xAxisHeightPx);ctx.stroke();let displayDistance;const displayTextColor='rgb(0,0,0)';const arrowSpacing=10*pixelRatio;const arrowColor='rgb(128,121,121)';const arrowPosY=xAxisHeightPx*1.75;const arrowWidthView=3*pixelRatio;const arrowLengthView=10*pixelRatio;const spaceForArrowsView=2*(arrowWidthView+arrowSpacing);ctx.textBaseline='middle';ctx.font=(14*pixelRatio)+'px sans-serif';const textPosY=arrowPosY;const interestRange=vp.interestRange;if(interestRange.range===0){const markerWorld=interestRange.min;const markerView=dt.xWorldToView(markerWorld);const textToDraw=vp.majorMarkUnit.format(markerWorld);let textLeftView=markerView+4*pixelRatio;const textWidthView=ctx.measureText(textToDraw).width;if(textLeftView+textWidthView>width){textLeftView=markerView-4*pixelRatio-textWidthView;}
 ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);return;}
-var leftMarker=interestRange.min;var rightMarker=interestRange.max;var leftMarkerView=dt.xWorldToView(leftMarker);var rightMarkerView=dt.xWorldToView(rightMarker);var distanceBetweenMarkers=interestRange.range;var distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);var positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);var textToDraw=vp.majorMarkUnit.format(distanceBetweenMarkers);var textWidthView=ctx.measureText(textToDraw).width;var spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;var textLeftView=positionInMiddleOfMarkersView-textWidthView/2;var textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width){textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;}
-ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){var leftArrowStart;var rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
+const leftMarker=interestRange.min;const rightMarker=interestRange.max;const leftMarkerView=dt.xWorldToView(leftMarker);const rightMarkerView=dt.xWorldToView(rightMarker);const distanceBetweenMarkers=interestRange.range;const distanceBetweenMarkersView=dt.xWorldVectorToView(distanceBetweenMarkers);const positionInMiddleOfMarkersView=leftMarkerView+(distanceBetweenMarkersView/2);const textToDraw=vp.majorMarkUnit.format(distanceBetweenMarkers);const textWidthView=ctx.measureText(textToDraw).width;const spaceForArrowsAndTextView=textWidthView+spaceForArrowsView+arrowSpacing;let textLeftView=positionInMiddleOfMarkersView-textWidthView/2;const textRightView=textLeftView+textWidthView;if(spaceForArrowsAndTextView>distanceBetweenMarkersView){textLeftView=rightMarkerView+2*arrowSpacing;if(textLeftView+textWidthView>width){textLeftView=leftMarkerView-2*arrowSpacing-textWidthView;}
+ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);ctx.strokeStyle=arrowColor;ctx.beginPath();tr.ui.b.drawLine(ctx,leftMarkerView,arrowPosY,rightMarkerView,arrowPosY);ctx.stroke();ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftMarkerView-1.5*arrowSpacing,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightMarkerView+1.5*arrowSpacing,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}else if(spaceForArrowsView<=distanceBetweenMarkersView){let leftArrowStart;let rightArrowStart;if(spaceForArrowsAndTextView<=distanceBetweenMarkersView){ctx.fillStyle=displayTextColor;ctx.fillText(textToDraw,textLeftView,textPosY);leftArrowStart=textLeftView-arrowSpacing;rightArrowStart=textRightView+arrowSpacing;}else{leftArrowStart=positionInMiddleOfMarkersView;rightArrowStart=positionInMiddleOfMarkersView;}
 ctx.strokeStyle=arrowColor;ctx.fillStyle=arrowColor;tr.ui.b.drawArrow(ctx,leftArrowStart,arrowPosY,leftMarkerView,arrowPosY,arrowLengthView,arrowWidthView);tr.ui.b.drawArrow(ctx,rightArrowStart,arrowPosY,rightMarkerView,arrowPosY,arrowLengthView,arrowWidthView);}
-ctx.restore();},addIntersectingEventsInRangeToSelection:function(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection:function(filter,selection){}};return{XAxisTrack,};});'use strict';Polymer({is:'tr-ui-timeline-track-view',ready:function(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.pollIfViewportAttachedInterval_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.XAxisTrack(this.viewport_);Polymer.dom(this.rulerTrackContainer_).appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;Polymer.dom(this.rulerTrackContainer_).appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);Polymer.dom(this.modelTrackContainer_).appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector:function(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));var m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_:function(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach:function(){this.modelTrack_.detach();this.upperModelTrack_.detach();if(this.pollIfViewportAttachedInterval_){window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;}
+ctx.restore();},addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection){},addAllEventsMatchingFilterToSelection(filter,selection){}};return{XAxisTrack,};});'use strict';Polymer({is:'tr-ui-timeline-track-view',ready(){this.displayTransform_=new tr.ui.TimelineDisplayTransform();this.model_=undefined;this.timelineView_=undefined;this.pollIfViewportAttachedInterval_=undefined;this.viewport_=new tr.ui.TimelineViewport(this);this.viewportDisplayTransformAtMouseDown_=undefined;this.brushingStateController_=undefined;this.rulerTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.rulerTrackContainer_);this.rulerTrackContainer_.invalidate();this.rulerTrack_=new tr.ui.tracks.XAxisTrack(this.viewport_);Polymer.dom(this.rulerTrackContainer_).appendChild(this.rulerTrack_);this.upperModelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);this.upperModelTrack_.upperMode=true;Polymer.dom(this.rulerTrackContainer_).appendChild(this.upperModelTrack_);this.modelTrackContainer_=new tr.ui.tracks.DrawingContainer(this.viewport_);Polymer.dom(this).appendChild(this.modelTrackContainer_);this.modelTrackContainer_.style.display='block';this.modelTrackContainer_.invalidate();this.viewport_.modelTrackContainer=this.modelTrackContainer_;this.modelTrack_=new tr.ui.tracks.ModelTrack(this.viewport_);Polymer.dom(this.modelTrackContainer_).appendChild(this.modelTrack_);this.timingTool_=new tr.ui.b.TimingTool(this.viewport_,this);this.initMouseModeSelector();this.hideDragBox_();this.initHintText_();this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onDblClick_=this.onDblClick_.bind(this);this.addEventListener('dblclick',this.onDblClick_);this.onMouseWheel_=this.onMouseWheel_.bind(this);this.addEventListener('mousewheel',this.onMouseWheel_);this.onMouseDown_=this.onMouseDown_.bind(this);this.addEventListener('mousedown',this.onMouseDown_);this.onMouseMove_=this.onMouseMove_.bind(this);this.addEventListener('mousemove',this.onMouseMove_);this.onTouchStart_=this.onTouchStart_.bind(this);this.addEventListener('touchstart',this.onTouchStart_);this.onTouchMove_=this.onTouchMove_.bind(this);this.addEventListener('touchmove',this.onTouchMove_);this.onTouchEnd_=this.onTouchEnd_.bind(this);this.addEventListener('touchend',this.onTouchEnd_);this.addHotKeys_();this.mouseViewPosAtMouseDown_={x:0,y:0};this.lastMouseViewPos_={x:0,y:0};this.lastTouchViewPositions_=[];this.alert_=undefined;this.isPanningAndScanning_=false;this.isZooming_=false;},initMouseModeSelector(){this.mouseModeSelector_=document.createElement('tr-ui-b-mouse-mode-selector');this.mouseModeSelector_.targetElement=this;Polymer.dom(this).appendChild(this.mouseModeSelector_);this.mouseModeSelector_.addEventListener('beginpan',this.onBeginPanScan_.bind(this));this.mouseModeSelector_.addEventListener('updatepan',this.onUpdatePanScan_.bind(this));this.mouseModeSelector_.addEventListener('endpan',this.onEndPanScan_.bind(this));this.mouseModeSelector_.addEventListener('beginselection',this.onBeginSelection_.bind(this));this.mouseModeSelector_.addEventListener('updateselection',this.onUpdateSelection_.bind(this));this.mouseModeSelector_.addEventListener('endselection',this.onEndSelection_.bind(this));this.mouseModeSelector_.addEventListener('beginzoom',this.onBeginZoom_.bind(this));this.mouseModeSelector_.addEventListener('updatezoom',this.onUpdateZoom_.bind(this));this.mouseModeSelector_.addEventListener('endzoom',this.onEndZoom_.bind(this));this.mouseModeSelector_.addEventListener('entertiming',this.timingTool_.onEnterTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('begintiming',this.timingTool_.onBeginTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('updatetiming',this.timingTool_.onUpdateTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('endtiming',this.timingTool_.onEndTiming.bind(this.timingTool_));this.mouseModeSelector_.addEventListener('exittiming',this.timingTool_.onExitTiming.bind(this.timingTool_));const m=tr.ui.b.MOUSE_SELECTOR_MODE;this.mouseModeSelector_.supportedModeMask=m.SELECTION|m.PANSCAN|m.ZOOM|m.TIMING;this.mouseModeSelector_.settingsKey='timelineTrackView.mouseModeSelector';this.mouseModeSelector_.setKeyCodeForMode(m.PANSCAN,'2'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.SELECTION,'1'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.ZOOM,'3'.charCodeAt(0));this.mouseModeSelector_.setKeyCodeForMode(m.TIMING,'4'.charCodeAt(0));this.mouseModeSelector_.setModifierForAlternateMode(m.SELECTION,tr.ui.b.MODIFIER.SHIFT);this.mouseModeSelector_.setModifierForAlternateMode(m.PANSCAN,tr.ui.b.MODIFIER.SPACE);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController_){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController_){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);}},set timelineView(view){this.timelineView_=view;},onSelectionChanged_(){this.showHintText_('Press \'m\' to mark current selection');this.viewport_.dispatchChangeEvent();},set selection(selection){throw new Error('DO NOT CALL THIS');},set highlight(highlight){throw new Error('DO NOT CALL THIS');},detach(){this.modelTrack_.detach();this.upperModelTrack_.detach();if(this.pollIfViewportAttachedInterval_){window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;}
 this.viewport_.detach();},get viewport(){return this.viewport_;},get model(){return this.model_;},set model(model){if(!model){throw new Error('Model cannot be undefined');}
-var modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged){this.pollIfViewportAttachedInterval_=window.setInterval(this.pollIfViewportAttached_.bind(this),250);}},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},pollIfViewportAttached_:function(){if(!this.viewport_.isAttachedToDocumentOrInTestMode||this.viewport_.clientWidth===0){return;}
-window.addEventListener('resize',this.viewport_.dispatchChangeEvent);window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;this.setInitialViewport_();},setInitialViewport_:function(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();var w=this.modelTrackContainer_.canvas.width;var min;var range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
-var boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask:function(filter,selection){var modelTrack=this.modelTrack_;var firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);var lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_:function(e){if(this.isZooming_)return;this.storeLastMousePos_(e);},onTouchStart_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_:function(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_:function(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_:function(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKey:function(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);},addKeyPressHotKeys_:function(){this.addKeyPressHotKey({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback:function(e){this.zoomBy_(1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'g'.charCodeAt(0),callback:function(e){this.onGridToggle_(true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'G'.charCodeAt(0),callback:function(e){this.onGridToggle_(false);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback:function(e){this.zoomBy_(10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback:function(e){this.zoomBy_(1/10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'a'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback:function(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'A'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'D'.charCodeAt(0),callback:function(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'0'.charCodeAt(0),callback:function(e){this.setInitialViewport_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'f'.charCodeAt(0),callback:function(e){this.zoomToSelection();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'m'.charCodeAt(0),callback:function(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'p'.charCodeAt(0),callback:function(e){this.selectPowerSamplesInCurrentTimeRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'h'.charCodeAt(0),callback:function(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_:function(){var addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;var binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback:function(e){var curSel=this.brushingStateController_.selection;var sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
-e.preventDefault();e.stopPropagation();}});},onDblClick_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
-var curSelection=this.brushingStateController_.selection;if(!curSelection.length||!tr.b.getOnlyElement(curSelection).title){return;}
-var selection=new tr.model.EventSet();var filter=new tr.c.ExactTitleFilter(tr.b.getOnlyElement(curSelection).title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_:function(e){if(!e.altKey)return;var delta=e.wheelDelta/120;var zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_:function(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
+const modelInstanceChanged=this.model_!==model;this.model_=model;this.modelTrack_.model=model;this.upperModelTrack_.model=model;if(modelInstanceChanged){this.pollIfViewportAttachedInterval_=window.setInterval(this.pollIfViewportAttached_.bind(this),250);}},get hasVisibleContent(){return this.modelTrack_.hasVisibleContent||this.upperModelTrack_.hasVisibleContent;},pollIfViewportAttached_(){if(!this.viewport_.isAttachedToDocumentOrInTestMode||this.viewport_.clientWidth===0){return;}
+window.addEventListener('resize',this.viewport_.dispatchChangeEvent);window.clearInterval(this.pollIfViewportAttachedInterval_);this.pollIfViewportAttachedInterval_=undefined;this.setInitialViewport_();},setInitialViewport_(){this.modelTrackContainer_.updateCanvasSizeIfNeeded_();const w=this.modelTrackContainer_.canvas.width;let min;let range;if(this.model_.bounds.isEmpty){min=0;range=1000;}else if(this.model_.bounds.range===0){min=this.model_.bounds.min;range=1000;}else{min=this.model_.bounds.min;range=this.model_.bounds.range;}
+const boost=range*0.15;this.displayTransform_.set(this.viewport_.currentDisplayTransform);this.displayTransform_.xSetWorldBounds(min-boost,min+range+boost,w);this.viewport_.setDisplayTransformImmediately(this.displayTransform_);},addAllEventsMatchingFilterToSelectionAsTask(filter,selection){const modelTrack=this.modelTrack_;const firstT=modelTrack.addAllEventsMatchingFilterToSelectionAsTask(filter,selection);const lastT=firstT.after(function(){this.upperModelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);},this);return firstT;},onMouseMove_(e){if(this.isZooming_)return;this.storeLastMousePos_(e);},onTouchStart_(e){this.storeLastTouchPositions_(e);this.focusElements_();},onTouchMove_(e){e.preventDefault();this.onUpdateTransformForTouch_(e);},onTouchEnd_(e){this.storeLastTouchPositions_(e);this.focusElements_();},addHotKeys_(){this.addKeyDownHotKeys_();this.addKeyPressHotKeys_();},addKeyPressHotKey(dict){dict.eventType='keypress';dict.useCapture=false;dict.thisArg=this;const binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);},addKeyPressHotKeys_(){this.addKeyPressHotKey({keyCodes:['w'.charCodeAt(0),','.charCodeAt(0)],callback(e){this.zoomBy_(1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['s'.charCodeAt(0),'o'.charCodeAt(0)],callback(e){this.zoomBy_(1/1.5,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'g'.charCodeAt(0),callback(e){this.onGridToggle_(true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'G'.charCodeAt(0),callback(e){this.onGridToggle_(false);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['W'.charCodeAt(0),'<'.charCodeAt(0)],callback(e){this.zoomBy_(10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['S'.charCodeAt(0),'O'.charCodeAt(0)],callback(e){this.zoomBy_(1/10,true);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'a'.charCodeAt(0),callback(e){this.queueSmoothPan_(this.viewWidth_*0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCodes:['d'.charCodeAt(0),'e'.charCodeAt(0)],callback(e){this.queueSmoothPan_(this.viewWidth_*-0.3,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'A'.charCodeAt(0),callback(e){this.queueSmoothPan_(viewWidth*0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'D'.charCodeAt(0),callback(e){this.queueSmoothPan_(viewWidth*-0.5,0);e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'0'.charCodeAt(0),callback(e){this.setInitialViewport_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'f'.charCodeAt(0),callback(e){this.zoomToSelection();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'m'.charCodeAt(0),callback(e){this.setCurrentSelectionAsInterestRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'p'.charCodeAt(0),callback(e){this.selectPowerSamplesInCurrentTimeRange_();e.stopPropagation();}});this.addKeyPressHotKey({keyCode:'h'.charCodeAt(0),callback(e){this.toggleHighDetails_();e.stopPropagation();}});},get viewWidth_(){return this.modelTrackContainer_.canvas.clientWidth;},addKeyDownHotKeys_(){const addBinding=function(dict){dict.eventType='keydown';dict.useCapture=false;dict.thisArg=this;const binding=new tr.ui.b.HotKey(dict);this.$.hotkey_controller.addHotKey(binding);}.bind(this);addBinding({keyCode:37,callback(e){const curSel=this.brushingStateController_.selection;const sel=this.viewport.getShiftedSelection(curSel,-1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});addBinding({keyCode:39,callback(e){const curSel=this.brushingStateController_.selection;const sel=this.viewport.getShiftedSelection(curSel,1);if(sel){this.brushingStateController.changeSelectionFromTimeline(sel);this.panToSelection();}else{this.queueSmoothPan_(-this.viewWidth_*0.3,0);}
+e.preventDefault();e.stopPropagation();}});},onDblClick_(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
+const curSelection=this.brushingStateController_.selection;if(!curSelection.length||!tr.b.getOnlyElement(curSelection).title){return;}
+const selection=new tr.model.EventSet();const filter=new tr.c.ExactTitleFilter(tr.b.getOnlyElement(curSelection).title);this.modelTrack_.addAllEventsMatchingFilterToSelection(filter,selection);this.brushingStateController.changeSelectionFromTimeline(selection);},onMouseWheel_(e){if(!e.altKey)return;const delta=e.wheelDelta/120;const zoomScale=Math.pow(1.5,delta);this.zoomBy_(zoomScale);e.preventDefault();},onMouseDown_(e){if(this.mouseModeSelector_.mode!==tr.ui.b.MOUSE_SELECTOR_MODE.SELECTION){return;}
 if(e.target!==this.rulerTrack_)return;this.dragBeginEvent_=undefined;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);this.xNavStringMarker_=undefined;}
-var dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)return;var relativePosition=this.extractRelativeMousePosition_(e);var loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
-var state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_:function(viewDeltaX,deltaY){var deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_:function(scale,smooth){if(scale<=0){return;}
-smooth=!!smooth;var vp=this.viewport_;var pixelRatio=window.devicePixelRatio||1;var goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;var goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)return;var bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)return;var worldCenter=bounds.center;var viewCenter=this.modelTrackContainer_.canvas.width/2;var adjustedWorldRange=bounds.range*1.25;var newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;var zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection:function(){if(!this.brushingStateController.selectionOfInterest.length)return;var bounds=this.brushingStateController.selectionOfInterest.bounds;var worldCenter=bounds.center;var viewWidth=this.viewWidth_;var dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
+const dt=this.viewport_.currentDisplayTransform;tr.ui.b.trackMouseMovesUntilMouseUp(function(e){if(e.target===this.rulerTrack_)return;const relativePosition=this.extractRelativeMousePosition_(e);const loc=tr.model.Location.fromViewCoordinates(this.viewport_,relativePosition.x,relativePosition.y);if(!loc)return;if(this.guideLineAnnotation_===undefined){this.guideLineAnnotation_=new tr.model.XMarkerAnnotation(loc.xWorld);this.model.addAnnotation(this.guideLineAnnotation_);}else{this.guideLineAnnotation_.timestamp=loc.xWorld;this.modelTrackContainer_.invalidate();}
+const state=new tr.ui.b.UIState(loc,this.viewport_.currentDisplayTransform.scaleX);this.timelineView_.setFindCtlText(state.toUserFriendlyString(this.viewport_));}.bind(this),undefined,function onKeyUpDuringDrag(){if(this.dragBeginEvent_){this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);}}.bind(this));},queueSmoothPan_(viewDeltaX,deltaY){const deltaX=this.viewport_.currentDisplayTransform.xViewVectorToWorld(viewDeltaX);const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,deltaY);this.viewport_.queueDisplayTransformAnimation(animation);},zoomBy_(scale,smooth){if(scale<=0){return;}
+smooth=!!smooth;const vp=this.viewport_;const pixelRatio=window.devicePixelRatio||1;const goalFocalPointXView=this.lastMouseViewPos_.x*pixelRatio;const goalFocalPointXWorld=vp.currentDisplayTransform.xViewToWorld(goalFocalPointXView);if(smooth){const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(goalFocalPointXWorld,goalFocalPointXView,vp.currentDisplayTransform.panY,scale);vp.queueDisplayTransformAnimation(animation);}else{this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=scale;this.displayTransform_.xPanWorldPosToViewPos(goalFocalPointXWorld,goalFocalPointXView,this.viewWidth_);vp.setDisplayTransformImmediately(this.displayTransform_);}},zoomToSelection(){if(!this.brushingStateController.selectionOfInterest.length)return;const bounds=this.brushingStateController.selectionOfInterest.bounds;if(!bounds.range)return;const worldCenter=bounds.center;const viewCenter=this.modelTrackContainer_.canvas.width/2;const adjustedWorldRange=bounds.range*1.25;const newScale=this.modelTrackContainer_.canvas.width/adjustedWorldRange;const zoomInRatio=newScale/this.viewport_.currentDisplayTransform.scaleX;const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);},panToSelection(){if(!this.brushingStateController.selectionOfInterest.length)return;const bounds=this.brushingStateController.selectionOfInterest.bounds;const worldCenter=bounds.center;const viewWidth=this.viewWidth_;const dt=this.viewport_.currentDisplayTransform;if(false&&!bounds.range){if(dt.xWorldToView(bounds.center)<0||dt.xWorldToView(bounds.center)>viewWidth){this.displayTransform_.set(dt);this.displayTransform_.xPanWorldPosToViewPos(worldCenter,'center',viewWidth);const deltaX=this.displayTransform_.panX-dt.panX;const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);}
 return;}
-this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);var deltaX=this.displayTransform_.panX-dt.panX;var animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition:function(uiState,showNavLine){var location=uiState.location;var scaleX=uiState.scaleX;var track=location.getContainingTrack(this.viewport_);var worldCenter=location.xWorld;var viewCenter=this.modelTrackContainer_.canvas.width/5;var zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();var animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)return;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);}
-this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},selectPowerSamplesInCurrentTimeRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(this.model.device.powerSeries&&!selectionBounds.empty){var events=this.model.device.powerSeries.getSamplesWithinRange(selectionBounds.min,selectionBounds.max);var selection=new tr.model.EventSet(events);this.brushingStateController_.changeSelectionFromTimeline(selection);}},setCurrentSelectionAsInterestRange_:function(){var selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
-if(this.viewport_.interestRange.min===selectionBounds.min&&this.viewport_.interestRange.max===selectionBounds.max){this.viewport_.interestRange.reset();}else{this.viewport_.interestRange.set(selectionBounds);}},toggleHighDetails_:function(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_:function(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_:function(xStart,yStart,xEnd,yEnd){var loY=Math.min(yStart,yEnd);var hiY=Math.max(yStart,yEnd);var loX=Math.min(xStart,xEnd);var hiX=Math.max(xStart,xEnd);var modelTrackRect=this.modelTrack_.getBoundingClientRect();var dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;var modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();var clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};var headingWidth=window.getComputedStyle(Polymer.dom(this).querySelector('tr-ui-b-heading')).width;var trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;var intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top){return false;}
-var results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};var finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';var pixelRatio=window.devicePixelRatio||1;var canv=this.modelTrackContainer_.canvas;var dt=this.viewport_.currentDisplayTransform;var loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);var hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);Polymer.dom(this.$.drag_box).textContent=tr.b.Unit.byName.timeDurationInMs.format(hiWX-loWX);var e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_:function(left){var selection=this.brushingStateController_.selection;var tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
-var numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
-(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_:function(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_:function(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_:function(e){var canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_:function(e){var canv=this.modelTrackContainer_.canvas;var touches=[];for(var i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
-return touches;},storeInitialMouseDownPos_:function(e){var position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_:function(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_:function(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_:function(e){var vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_:function(e){if(!this.isPanningAndScanning_)return;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
-this.mouseViewPosAtMouseDown_.x);var yDelta=this.lastMouseViewPos_.y-
-this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_:function(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick){e.preventDefault();}},onBeginSelection_:function(e){var canv=this.modelTrackContainer_.canvas;var rect=this.modelTrack_.getBoundingClientRect();var canvRect=canv.getBoundingClientRect();var inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_:function(e){if(!this.dragBeginEvent_)return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_:function(e){e.preventDefault();if(!this.dragBeginEvent_)return;this.hideDragBox_();var eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;var loY=Math.min(eDown.clientY,e.clientY);var hiY=Math.max(eDown.clientY,e.clientY);var loX=Math.min(eDown.clientX,e.clientX);var hiX=Math.max(eDown.clientX,e.clientX);var canv=this.modelTrackContainer_.canvas;var worldOffset=canv.getBoundingClientRect().left;var loVX=loX-worldOffset;var hiVX=hiX-worldOffset;var selection=new tr.model.EventSet();if(eDown.appendSelection){var previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined){selection.addEventSet(previousSelection);}}
-this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_:function(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_:function(e){if(!this.isZooming_)return;var newPosition=this.extractRelativeMousePosition_(e);var zoomScaleValue=1+(this.lastMouseViewPos_.y-
-newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_:function(e){this.isZooming_=false;if(!e.isClick){e.preventDefault();}},computeTouchCenter_:function(positions){var xSum=0;var ySum=0;for(var i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
-return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_:function(positions){var xMin=Number.MAX_VALUE;var yMin=Number.MAX_VALUE;var xMax=Number.MIN_VALUE;var yMax=Number.MIN_VALUE;for(var i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
+this.displayTransform_.set(dt);this.displayTransform_.xPanWorldBoundsIntoView(bounds.min,bounds.max,viewWidth);const deltaX=this.displayTransform_.panX-dt.panX;const animation=new tr.ui.TimelineDisplayTransformPanAnimation(deltaX,0);this.viewport_.queueDisplayTransformAnimation(animation);},navToPosition(uiState,showNavLine){const location=uiState.location;const scaleX=uiState.scaleX;const track=location.getContainingTrack(this.viewport_);const worldCenter=location.xWorld;const viewCenter=this.modelTrackContainer_.canvas.width/5;const zoomInRatio=scaleX/this.viewport_.currentDisplayTransform.scaleX;track.scrollIntoViewIfNeeded();const animation=new tr.ui.TimelineDisplayTransformZoomToAnimation(worldCenter,viewCenter,this.viewport_.currentDisplayTransform.panY,zoomInRatio);this.viewport_.queueDisplayTransformAnimation(animation);if(!showNavLine)return;if(this.xNavStringMarker_){this.model.removeAnnotation(this.xNavStringMarker_);}
+this.xNavStringMarker_=new tr.model.XMarkerAnnotation(worldCenter);this.model.addAnnotation(this.xNavStringMarker_);},selectPowerSamplesInCurrentTimeRange_(){const selectionBounds=this.brushingStateController_.selection.bounds;if(this.model.device.powerSeries&&!selectionBounds.empty){const events=this.model.device.powerSeries.getSamplesWithinRange(selectionBounds.min,selectionBounds.max);const selection=new tr.model.EventSet(events);this.brushingStateController_.changeSelectionFromTimeline(selection);}},setCurrentSelectionAsInterestRange_(){const selectionBounds=this.brushingStateController_.selection.bounds;if(selectionBounds.empty){this.viewport_.interestRange.reset();return;}
+if(this.viewport_.interestRange.min===selectionBounds.min&&this.viewport_.interestRange.max===selectionBounds.max){this.viewport_.interestRange.reset();}else{this.viewport_.interestRange.set(selectionBounds);}},toggleHighDetails_(){this.viewport_.highDetails=!this.viewport_.highDetails;},hideDragBox_(){this.$.drag_box.style.left='-1000px';this.$.drag_box.style.top='-1000px';this.$.drag_box.style.width=0;this.$.drag_box.style.height=0;},setDragBoxPosition_(xStart,yStart,xEnd,yEnd){const loY=Math.min(yStart,yEnd);const hiY=Math.max(yStart,yEnd);const loX=Math.min(xStart,xEnd);const hiX=Math.max(xStart,xEnd);const modelTrackRect=this.modelTrack_.getBoundingClientRect();const dragRect={left:loX,top:loY,width:hiX-loX,height:hiY-loY};dragRect.right=dragRect.left+dragRect.width;dragRect.bottom=dragRect.top+dragRect.height;const modelTrackContainerRect=this.modelTrackContainer_.getBoundingClientRect();const clipRect={left:modelTrackContainerRect.left,top:modelTrackContainerRect.top,right:modelTrackContainerRect.right,bottom:modelTrackContainerRect.bottom};const headingWidth=window.getComputedStyle(Polymer.dom(this).querySelector('tr-ui-b-heading')).width;const trackTitleWidth=parseInt(headingWidth);clipRect.left=clipRect.left+trackTitleWidth;const intersectRect_=function(r1,r2){if(r2.left>r1.right||r2.right<r1.left||r2.top>r1.bottom||r2.bottom<r1.top){return false;}
+const results={};results.left=Math.max(r1.left,r2.left);results.top=Math.max(r1.top,r2.top);results.right=Math.min(r1.right,r2.right);results.bottom=Math.min(r1.bottom,r2.bottom);results.width=results.right-results.left;results.height=results.bottom-results.top;return results;};const finalDragBox=intersectRect_(clipRect,dragRect);this.$.drag_box.style.left=finalDragBox.left+'px';this.$.drag_box.style.width=finalDragBox.width+'px';this.$.drag_box.style.top=finalDragBox.top+'px';this.$.drag_box.style.height=finalDragBox.height+'px';this.$.drag_box.style.whiteSpace='nowrap';const pixelRatio=window.devicePixelRatio||1;const canv=this.modelTrackContainer_.canvas;const dt=this.viewport_.currentDisplayTransform;const loWX=dt.xViewToWorld((loX-canv.offsetLeft)*pixelRatio);const hiWX=dt.xViewToWorld((hiX-canv.offsetLeft)*pixelRatio);Polymer.dom(this.$.drag_box).textContent=tr.b.Unit.byName.timeDurationInMs.format(hiWX-loWX);const e=new tr.b.Event('selectionChanging');e.loWX=loWX;e.hiWX=hiWX;this.dispatchEvent(e);},onGridToggle_(left){const selection=this.brushingStateController_.selection;const tb=left?selection.bounds.min:selection.bounds.max;if(this.viewport_.gridEnabled&&this.viewport_.gridSide===left&&this.viewport_.gridInitialTimebase===tb){this.viewport_.gridside=undefined;this.viewport_.gridEnabled=false;this.viewport_.gridInitialTimebase=undefined;return;}
+const numIntervalsSinceStart=Math.ceil((tb-this.model_.bounds.min)/this.viewport_.gridStep_);this.viewport_.gridEnabled=true;this.viewport_.gridSide=left;this.viewport_.gridInitialTimebase=tb;this.viewport_.gridTimebase=tb-
+(numIntervalsSinceStart+1)*this.viewport_.gridStep_;},storeLastMousePos_(e){this.lastMouseViewPos_=this.extractRelativeMousePosition_(e);},storeLastTouchPositions_(e){this.lastTouchViewPositions_=this.extractRelativeTouchPositions_(e);},extractRelativeMousePosition_(e){const canv=this.modelTrackContainer_.canvas;return{x:e.clientX-canv.offsetLeft,y:e.clientY-canv.offsetTop};},extractRelativeTouchPositions_(e){const canv=this.modelTrackContainer_.canvas;const touches=[];for(let i=0;i<e.touches.length;++i){touches.push({x:e.touches[i].clientX-canv.offsetLeft,y:e.touches[i].clientY-canv.offsetTop});}
+return touches;},storeInitialMouseDownPos_(e){const position=this.extractRelativeMousePosition_(e);this.mouseViewPosAtMouseDown_.x=position.x;this.mouseViewPosAtMouseDown_.y=position.y;},focusElements_(){this.$.hotkey_controller.childRequestsGeneralFocus(this);},storeInitialInteractionPositionsAndFocus_(e){this.storeInitialMouseDownPos_(e);this.storeLastMousePos_(e);this.focusElements_();},onBeginPanScan_(e){const vp=this.viewport_;this.viewportDisplayTransformAtMouseDown_=vp.currentDisplayTransform.clone();this.isPanningAndScanning_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdatePanScan_(e){if(!this.isPanningAndScanning_)return;const viewWidth=this.viewWidth_;const pixelRatio=window.devicePixelRatio||1;const xDeltaView=pixelRatio*(this.lastMouseViewPos_.x-
+this.mouseViewPosAtMouseDown_.x);const yDelta=this.lastMouseViewPos_.y-
+this.mouseViewPosAtMouseDown_.y;this.displayTransform_.set(this.viewportDisplayTransformAtMouseDown_);this.displayTransform_.incrementPanXInViewUnits(xDeltaView);this.displayTransform_.panY-=yDelta;this.viewport_.setDisplayTransformImmediately(this.displayTransform_);e.preventDefault();e.stopPropagation();this.storeLastMousePos_(e);},onEndPanScan_(e){this.isPanningAndScanning_=false;this.storeLastMousePos_(e);if(!e.isClick){e.preventDefault();}},onBeginSelection_(e){const canv=this.modelTrackContainer_.canvas;const rect=this.modelTrack_.getBoundingClientRect();const canvRect=canv.getBoundingClientRect();const inside=rect&&e.clientX>=rect.left&&e.clientX<rect.right&&e.clientY>=rect.top&&e.clientY<rect.bottom&&e.clientX>=canvRect.left&&e.clientX<canvRect.right;if(!inside)return;this.dragBeginEvent_=e;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateSelection_(e){if(!this.dragBeginEvent_)return;this.dragBoxXStart_=this.dragBeginEvent_.clientX;this.dragBoxXEnd_=e.clientX;this.dragBoxYStart_=this.dragBeginEvent_.clientY;this.dragBoxYEnd_=e.clientY;this.setDragBoxPosition_(this.dragBoxXStart_,this.dragBoxYStart_,this.dragBoxXEnd_,this.dragBoxYEnd_);},onEndSelection_(e){e.preventDefault();if(!this.dragBeginEvent_)return;this.hideDragBox_();const eDown=this.dragBeginEvent_;this.dragBeginEvent_=undefined;const loY=Math.min(eDown.clientY,e.clientY);const hiY=Math.max(eDown.clientY,e.clientY);const loX=Math.min(eDown.clientX,e.clientX);const hiX=Math.max(eDown.clientX,e.clientX);const canv=this.modelTrackContainer_.canvas;const worldOffset=canv.getBoundingClientRect().left;const loVX=loX-worldOffset;const hiVX=hiX-worldOffset;const selection=new tr.model.EventSet();if(eDown.appendSelection){const previousSelection=this.brushingStateController_.selection;if(previousSelection!==undefined){selection.addEventSet(previousSelection);}}
+this.modelTrack_.addIntersectingEventsInRangeToSelection(loVX,hiVX,loY,hiY,selection);this.brushingStateController_.changeSelectionFromTimeline(selection);},onBeginZoom_(e){this.isZooming_=true;this.storeInitialInteractionPositionsAndFocus_(e);e.preventDefault();},onUpdateZoom_(e){if(!this.isZooming_)return;const newPosition=this.extractRelativeMousePosition_(e);const zoomScaleValue=1+(this.lastMouseViewPos_.y-
+newPosition.y)*0.01;this.zoomBy_(zoomScaleValue,false);this.storeLastMousePos_(e);},onEndZoom_(e){this.isZooming_=false;if(!e.isClick){e.preventDefault();}},computeTouchCenter_(positions){let xSum=0;let ySum=0;for(let i=0;i<positions.length;++i){xSum+=positions[i].x;ySum+=positions[i].y;}
+return{x:xSum/positions.length,y:ySum/positions.length};},computeTouchSpan_(positions){let xMin=Number.MAX_VALUE;let yMin=Number.MAX_VALUE;let xMax=Number.MIN_VALUE;let yMax=Number.MIN_VALUE;for(let i=0;i<positions.length;++i){xMin=Math.min(xMin,positions[i].x);yMin=Math.min(yMin,positions[i].y);xMax=Math.max(xMax,positions[i].x);yMax=Math.max(yMax,positions[i].y);}
 return Math.sqrt((xMin-xMax)*(xMin-xMax)+
-(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_:function(e){var newPositions=this.extractRelativeTouchPositions_(e);var currentPositions=this.lastTouchViewPositions_;var newCenter=this.computeTouchCenter_(newPositions);var currentCenter=this.computeTouchCenter_(currentPositions);var newSpan=this.computeTouchSpan_(newPositions);var currentSpan=this.computeTouchSpan_(currentPositions);var vp=this.viewport_;var viewWidth=this.viewWidth_;var pixelRatio=window.devicePixelRatio||1;var xDelta=pixelRatio*(newCenter.x-currentCenter.x);var yDelta=newCenter.y-currentCenter.y;var zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;var viewFocus=pixelRatio*newCenter.x;var worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_:function(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_:function(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
-this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);Polymer.dom(this.$.hint_text).textContent=text;this.$.hint_text.style.display='';},hideHintText_:function(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer({is:'tr-ui-find-control',filterKeyDown:function(e){if(e.keyCode===27){var hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
-e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey){this.findPrevious();}else{this.findNext();}}},filterBlur:function(e){this.updateHitCountEl();},filterFocus:function(e){this.$.filter.select();},filterMouseUp:function(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus:function(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged:function(){Polymer.dom(this.$.hitCount).textContent='';this.$.spinner.style.visibility='visible';this.$.spinner.style.animation='spin 1s linear infinite';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.$.spinner.style.animation='';this.updateHitCountEl();}.bind(this));},findNext:function(){if(this.controller){this.controller.findNext();}
-this.updateHitCountEl();},findPrevious:function(){if(this.controller){this.controller.findPrevious();}
-this.updateHitCountEl();},updateHitCountEl:function(){if(!this.controller||this.$.filter.value.length===0){Polymer.dom(this.$.hitCount).textContent='';return;}
-var n=this.controller.filterHits.length;var i=n===0?-1:this.controller.currentHitIndex;Polymer.dom(this.$.hitCount).textContent=(i+1)+' of '+n;},setText:function(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
-Context.prototype={push:function(event){var ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop:function(event){var ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context,};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
-Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)==='string'||filterExpression instanceof RegExp){var filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
-return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate:function(context){throw new Error('Not implemented');},matchValue_:function(value,expected){if(expected instanceof RegExp){return expected.test(value);}else if(expected instanceof Function){return expected(value);}
+(yMin-yMax)*(yMin-yMax));},onUpdateTransformForTouch_(e){const newPositions=this.extractRelativeTouchPositions_(e);const currentPositions=this.lastTouchViewPositions_;const newCenter=this.computeTouchCenter_(newPositions);const currentCenter=this.computeTouchCenter_(currentPositions);const newSpan=this.computeTouchSpan_(newPositions);const currentSpan=this.computeTouchSpan_(currentPositions);const vp=this.viewport_;const viewWidth=this.viewWidth_;const pixelRatio=window.devicePixelRatio||1;const xDelta=pixelRatio*(newCenter.x-currentCenter.x);const yDelta=newCenter.y-currentCenter.y;const zoomScaleValue=currentSpan>10?newSpan/currentSpan:1;const viewFocus=pixelRatio*newCenter.x;const worldFocus=vp.currentDisplayTransform.xViewToWorld(viewFocus);this.displayTransform_.set(vp.currentDisplayTransform);this.displayTransform_.scaleX*=zoomScaleValue;this.displayTransform_.xPanWorldPosToViewPos(worldFocus,viewFocus,viewWidth);this.displayTransform_.incrementPanXInViewUnits(xDelta);this.displayTransform_.panY-=yDelta;vp.setDisplayTransformImmediately(this.displayTransform_);this.storeLastTouchPositions_(e);},initHintText_(){this.$.hint_text.style.display='none';this.pendingHintTextClearTimeout_=undefined;},showHintText_(text){if(this.pendingHintTextClearTimeout_){window.clearTimeout(this.pendingHintTextClearTimeout_);this.pendingHintTextClearTimeout_=undefined;}
+this.pendingHintTextClearTimeout_=setTimeout(this.hideHintText_.bind(this),1000);Polymer.dom(this.$.hint_text).textContent=text;this.$.hint_text.style.display='';},hideHintText_(){this.pendingHintTextClearTimeout_=undefined;this.$.hint_text.style.display='none';}});'use strict';Polymer({is:'tr-ui-find-control',filterKeyDown(e){if(e.keyCode===27){const hkc=tr.b.getHotkeyControllerForElement(this);if(hkc){hkc.childRequestsBlur(this);}else{this.blur();}
+e.preventDefault();e.stopPropagation();return;}else if(e.keyCode===13){if(e.shiftKey){this.findPrevious();}else{this.findNext();}}},filterBlur(e){this.updateHitCountEl();},filterFocus(e){this.$.filter.select();},filterMouseUp(e){e.preventDefault();},get controller(){return this.controller_;},set controller(c){this.controller_=c;this.updateHitCountEl();},focus(){this.$.filter.focus();},get hasFocus(){return this===document.activeElement;},filterTextChanged(){Polymer.dom(this.$.hitCount).textContent='';this.$.spinner.style.visibility='visible';this.$.spinner.style.animation='spin 1s linear infinite';this.controller.startFiltering(this.$.filter.value).then(function(){this.$.spinner.style.visibility='hidden';this.$.spinner.style.animation='';this.updateHitCountEl();}.bind(this));},findNext(){if(this.controller){this.controller.findNext();}
+this.updateHitCountEl();},findPrevious(){if(this.controller){this.controller.findPrevious();}
+this.updateHitCountEl();},updateHitCountEl(){if(!this.controller||this.$.filter.value.length===0){Polymer.dom(this.$.hitCount).textContent='';return;}
+const n=this.controller.filterHits.length;const i=n===0?-1:this.controller.currentHitIndex;Polymer.dom(this.$.hitCount).textContent=(i+1)+' of '+n;},setText(string){this.$.filter.value=string;}});'use strict';tr.exportTo('tr.e.tquery',function(){function Context(){this.event=undefined;this.ancestors=[];}
+Context.prototype={push(event){const ctx=new Context();ctx.ancestors=this.ancestors.slice();ctx.ancestors.push(event);return ctx;},pop(event){const ctx=new Context();ctx.event=this.ancestors[this.ancestors.length-1];ctx.ancestors=this.ancestors.slice(0,this.ancestors.length-1);return ctx;}};return{Context,};});'use strict';tr.exportTo('tr.e.tquery',function(){function Filter(){tr.c.ScriptingObject.call(this);}
+Filter.normalizeFilterExpression=function(filterExpression){if(filterExpression instanceof String||typeof(filterExpression)==='string'||filterExpression instanceof RegExp){const filter=new tr.e.tquery.FilterHasTitle(filterExpression);return filter;}
+return filterExpression;};Filter.prototype={__proto__:tr.c.ScriptingObject.prototype,evaluate(context){throw new Error('Not implemented');},matchValue_(value,expected){if(expected instanceof RegExp){return expected.test(value);}else if(expected instanceof Function){return expected(value);}
 return value===expected;}};return{Filter,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAllOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
-FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)return true;for(var i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context)){return false;}}
-return true;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=[];for(var i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
+FilterAllOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(let i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate(context){if(!this.subExpressions.length)return true;for(let i=0;i<this.subExpressions.length;i++){if(!this.subExpressions[i].evaluate(context)){return false;}}
+return true;}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=[];for(let i=0;i<arguments.length;i++){exprs.push(arguments[i]);}
 return new FilterAllOf(exprs);},{name:'allOf'});return{FilterAllOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterNot(subExpression){tr.e.tquery.Filter.call(this);this.subExpression=subExpression;}
-FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1){throw new Error('not() must have exactly one subexpression');}
+FilterNot.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){return!this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);if(exprs.length!==1){throw new Error('not() must have exactly one subexpression');}
 return new FilterNot(exprs[0]);},{name:'not'});return{FilterNot,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterAnyOf(opt_subExpressions){tr.e.tquery.Filter.call(this);this.subExpressions=opt_subExpressions||[];}
-FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(var i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate:function(context){if(!this.subExpressions.length)return true;for(var i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))return true;}
-return false;}};tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){var exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;}
-FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(!this.subExpression){return context.ancestors.length>0;}
+FilterAnyOf.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpressions(exprs){this.subExpressions_=[];for(let i=0;i<exprs.length;i++){this.subExpressions_.push(tr.e.tquery.Filter.normalizeFilterExpression(exprs[i]));}},get subExpressions(){return this.subExpressions_;},evaluate(context){if(!this.subExpressions.length)return true;for(let i=0;i<this.subExpressions.length;i++){if(this.subExpressions[i].evaluate(context))return true;}
+return false;}};tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);return new FilterAnyOf(exprs);},{name:'anyOf'});tr.c.ScriptingObjectRegistry.register(function(){const exprs=Array.prototype.slice.call(arguments);return new tr.e.tquery.FilterNot(new FilterAnyOf(exprs));},{name:'noneOf'});return{FilterAnyOf,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasAncestor(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterHasAncestor.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){if(!this.subExpression){return context.ancestors.length>0;}
 while(context.ancestors.length){context=context.pop();if(this.subExpression.evaluate(context))return true;}
 return false;}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterHasAncestor(subExpression);},{name:'hasAncestor'});return{FilterHasAncestor,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasDuration(minValueOrExpected,opt_maxValue){if(minValueOrExpected!==undefined&&opt_maxValue!==undefined){this.minValue=minValueOrExpected;this.maxValue=opt_maxValue;}else{this.expected=minValueOrExpected;}}
-FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){if(context.event.duration===undefined)return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
+FilterHasDuration.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate(context){if(context.event.duration===undefined)return false;if(this.minValue!==undefined&&this.maxValue!==undefined){return context.event.duration>=this.minValue&&context.event.duration<=this.maxValue;}
 return this.matchValue_(context.event.duration,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(minValueOrExpected,opt_maxValue){return new FilterHasDuration(minValueOrExpected,opt_maxValue);},{name:'hasDuration'});return{FilterHasDuration,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterHasTitle(expected){tr.e.tquery.Filter.call(this);this.expected=expected;}
-FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate:function(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){var filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
-FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate:function(context){if(context.ancestors.length>0)return false;if(!this.subExpression)return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel,};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
+FilterHasTitle.prototype={__proto__:tr.e.tquery.Filter.prototype,evaluate(context){return this.matchValue_(context.event.title,this.expected);}};tr.c.ScriptingObjectRegistry.register(function(expected){const filter=new tr.e.tquery.FilterHasTitle(expected);return filter;},{name:'hasTitle'});return{FilterHasTitle,};});'use strict';tr.exportTo('tr.e.tquery',function(){function FilterIsTopLevel(opt_subExpression){this.subExpression=opt_subExpression;}
+FilterIsTopLevel.prototype={__proto__:tr.e.tquery.Filter.prototype,set subExpression(expr){this.subExpression_=tr.e.tquery.Filter.normalizeFilterExpression(expr);},get subExpression(){return this.subExpression_;},evaluate(context){if(context.ancestors.length>0)return false;if(!this.subExpression)return true;return this.subExpression.evaluate(context);}};tr.c.ScriptingObjectRegistry.register(function(subExpression){return new FilterIsTopLevel(subExpression);},{name:'isTopLevel'});return{FilterIsTopLevel,};});'use strict';tr.exportTo('tr.e.tquery',function(){function addEventTreeToSelection(selection,event){selection.push(event);if(!event.subSlices)return;event.subSlices.forEach(addEventTreeToSelection.bind(undefined,selection));}
 function TQuery(model){tr.c.ScriptingObject.call(this);this.model_=model;this.parent_=undefined;this.filterExpression_=undefined;this.selection_=undefined;}
-TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged:function(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter:function(filterExpression){var result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_:function(){let nodes=[this];while(nodes[nodes.length-1].parent_){nodes.push(nodes[nodes.length-1].parent_);}
-var rootTask=new tr.b.Task();var lastTask=rootTask;for(var i=nodes.length-1;i>=0;i--){var node=nodes[i];if(node.selection_!==undefined)continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{var prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
-return{rootTask:rootTask,lastTask:lastTask,lastNode:node};},createFilterTaskForNode_:function(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_:function(inputSelection,outputSelection){var seenEvents={};inputSelection.forEach(function(event){var context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_:function(context,inputSelection,outputSelection,seenEvents){var event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context)){outputSelection.push(event);}}
-if(!event.subSlices)return;context=context.push(event);for(var i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_:function(selection){var filterTask=new tr.b.Task();for(let container of this.model_.getDescendantEventContainers()){filterTask.subTask(()=>{for(var event of container.childEvents()){addEventTreeToSelection(selection,event);}},this);}
-return filterTask;},ready:function(){return new Promise(function(resolve,reject){var graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){var graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
-return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery,};});'use strict';Polymer({is:'tr-ui-scripting-control',_isEnterKey:function(event){return event.keyCode!==229&&(event.key==='Enter'||event.keyIdentifier==='Enter');},_setFocused:function(focused){var promptEl=this.$.prompt;if(focused){promptEl.focus();Polymer.dom(this.$.root).classList.add('focused');if(promptEl.value.length>0){var sel=window.getSelection();sel.collapse(Polymer.dom(promptEl).firstChild,promptEl.value.length);}}else{promptEl.blur();Polymer.dom(this.$.root).classList.remove('focused');var parent=promptEl.parentElement;var nextEl=Polymer.dom(promptEl).nextSibling;promptEl.remove();Polymer.dom(parent).insertBefore(promptEl,nextEl);}},onConsoleFocus:function(e){e.stopPropagation();this._setFocused(true);},onConsoleBlur:function(e){e.stopPropagation();this._setFocused(false);},promptKeyDown:function(e){e.stopPropagation();if(!this._isEnterKey(e))return;e.preventDefault();var promptEl=this.$.prompt;var command=promptEl.value;if(command.length===0)return;promptEl.value='';this.addLine_(String.fromCharCode(187)+' '+command);try{var result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
+TQuery.prototype={__proto__:tr.c.ScriptingObject.prototype,onModelChanged(model){this.model_=model;this.selection_=undefined;},get brushingStateController(){return this.brushingStateController_;},filter(filterExpression){const result=new TQuery(this.model_);result.parent_=this;result.filterExpression_=tr.e.tquery.Filter.normalizeFilterExpression(filterExpression);return result;},createFilterTaskGraph_(){const nodes=[this];while(nodes[nodes.length-1].parent_){nodes.push(nodes[nodes.length-1].parent_);}
+const rootTask=new tr.b.Task();let lastTask=rootTask;let node;for(let i=nodes.length-1;i>=0;i--){node=nodes[i];if(node.selection_!==undefined)continue;node.selection_=new tr.model.EventSet();if(node.parent_===undefined){lastTask=lastTask.after(this.selectEverythingAsTask_(node.selection_));}else{const prevNode=nodes[i+1];lastTask=this.createFilterTaskForNode_(lastTask,node,prevNode);}}
+return{rootTask,lastTask,lastNode:node};},createFilterTaskForNode_(lastTask,node,prevNode){return lastTask.after(function(){node.evaluateFilterExpression_(prevNode.selection_,node.selection_);},this);},evaluateFilterExpression_(inputSelection,outputSelection){const seenEvents={};inputSelection.forEach(function(event){const context=new tr.e.tquery.Context();context.event=event;this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}.bind(this));},evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents){const event=context.event;if(inputSelection.contains(event)&&!seenEvents[event.guid]){seenEvents[event.guid]=true;if(!this.filterExpression_||this.filterExpression_.evaluate(context)){outputSelection.push(event);}}
+if(!event.subSlices)return;context=context.push(event);for(let i=0;i<event.subSlices.length;i++){context.event=event.subSlices[i];this.evaluateFilterExpressionForEvent_(context,inputSelection,outputSelection,seenEvents);}},selectEverythingAsTask_(selection){const filterTask=new tr.b.Task();for(const container of this.model_.getDescendantEventContainers()){filterTask.subTask(()=>{for(const event of container.childEvents()){addEventTreeToSelection(selection,event);}},this);}
+return filterTask;},ready(){return new Promise(function(resolve,reject){const graph=this.createFilterTaskGraph_();graph.lastTask=graph.lastTask.after(function(){resolve(this.selection_);},this);tr.b.Task.RunWhenIdle(graph.rootTask);}.bind(this));},get selection(){if(this.selection_===undefined){const graph=this.createFilterTaskGraph_();tr.b.Task.RunSynchronously(graph.rootTask);}
+return this.selection_;}};tr.c.ScriptingObjectRegistry.register(new TQuery(),{name:'$t'});return{TQuery,};});'use strict';Polymer({is:'tr-ui-scripting-control',isEnterKey_(event){return event.keyCode!==229&&(event.key==='Enter'||event.keyIdentifier==='Enter');},setFocus_(focused){const promptEl=this.$.prompt;if(focused){promptEl.focus();Polymer.dom(this.$.root).classList.add('focused');if(promptEl.value.length>0){const sel=window.getSelection();sel.collapse(Polymer.dom(promptEl).firstChild,promptEl.value.length);}}else{promptEl.blur();Polymer.dom(this.$.root).classList.remove('focused');const parent=promptEl.parentElement;const nextEl=Polymer.dom(promptEl).nextSibling;promptEl.remove();Polymer.dom(parent).insertBefore(promptEl,nextEl);}},onConsoleFocus(e){e.stopPropagation();this.setFocus_(true);},onConsoleBlur(e){e.stopPropagation();this.setFocus_(false);},promptKeyDown(e){e.stopPropagation();if(!this.isEnterKey_(e))return;e.preventDefault();const promptEl=this.$.prompt;const command=promptEl.value;if(command.length===0)return;promptEl.value='';this.addLine_(String.fromCharCode(187)+' '+command);let result;try{result=this.controller_.executeCommand(command);}catch(e){result=e.stack||e.stackTrace;}
 if(result instanceof tr.e.tquery.TQuery){result.ready().then(function(selection){this.addLine_(selection.length+' matches');this.controller_.brushingStateController.showScriptControlSelection(selection);}.bind(this));}else{this.addLine_(result);}
-promptEl.scrollIntoView();},addLine_:function(line){var historyEl=this.$.history;if(historyEl.innerText.length!==0){historyEl.innerText+='\n';}
-historyEl.innerText+=line;},promptKeyPress:function(e){e.stopPropagation();},toggleVisibility:function(){var root=this.$.root;if(!this.visible){Polymer.dom(root).classList.remove('hidden');this._setFocused(true);}else{Polymer.dom(root).classList.add('hidden');this._setFocused(false);}},get hasFocus(){return this===document.activeElement;},get visible(){var root=this.$.root;return!Polymer.dom(root).classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer({is:'tr-ui-side-panel-container',ready:function(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.dragHandle_=this.$.side_panel_drag_handle;this.dragHandle_.horizontal=false;this.dragHandle_.target=this.activePanelContainer_;this.rangeOfInterest_=new tr.b.math.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
-this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},onSelectionChanged_:function(){if(this.activePanel){this.activePanel.selection=this.selection;}},get model(){return this.brushingStateController_.model;},onModelChanged_:function(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined){throw new Error('Cannot activate panel without a model');}
-var panel=undefined;if(panelType){panel=document.createElement(panelType);}
+promptEl.scrollIntoView();},addLine_(line){const historyEl=this.$.history;if(historyEl.innerText.length!==0){historyEl.innerText+='\n';}
+historyEl.innerText+=line;},promptKeyPress(e){e.stopPropagation();},toggleVisibility(){const root=this.$.root;if(!this.visible){Polymer.dom(root).classList.remove('hidden');this.setFocus_(true);}else{Polymer.dom(root).classList.add('hidden');this.setFocus_(false);}},get hasFocus(){return this===document.activeElement;},get visible(){const root=this.$.root;return!Polymer.dom(root).classList.contains('hidden');},get controller(){return this.controller_;},set controller(c){this.controller_=c;}});'use strict';Polymer({is:'tr-ui-side-panel-container',ready(){this.activePanelContainer_=this.$.active_panel_container;this.tabStrip_=this.$.tab_strip;this.dragHandle_=this.$.side_panel_drag_handle;this.dragHandle_.horizontal=false;this.dragHandle_.target=this.activePanelContainer_;this.rangeOfInterest_=new tr.b.math.Range();this.brushingStateController_=undefined;this.onSelectionChanged_=this.onSelectionChanged_.bind(this);this.onModelChanged_=this.onModelChanged_.bind(this);},get brushingStateController(){return this.brushingStateController_;},set brushingStateController(brushingStateController){if(this.brushingStateController){this.brushingStateController_.removeEventListener('change',this.onSelectionChanged_);this.brushingStateController_.removeEventListener('model-changed',this.onModelChanged_);}
+this.brushingStateController_=brushingStateController;if(this.brushingStateController){this.brushingStateController_.addEventListener('change',this.onSelectionChanged_);this.brushingStateController_.addEventListener('model-changed',this.onModelChanged_);}},onSelectionChanged_(){if(this.activePanel){this.activePanel.selection=this.selection;}},get model(){return this.brushingStateController_.model;},onModelChanged_(){this.activePanelType_=undefined;this.updateContents_();},get expanded(){this.hasAttribute('expanded');},get activePanel(){return this.activePanelContainer_.children[0];},get activePanelType(){return this.activePanelType_;},set activePanelType(panelType){if(this.model===undefined){throw new Error('Cannot activate panel without a model');}
+let panel=undefined;if(panelType){panel=document.createElement(panelType);}
 if(panel!==undefined&&!panel.supportsModel(this.model)){throw new Error('Cannot activate panel: does not support this model');}
 if(this.activePanelType){Polymer.dom(this.getLabelElementForPanelType_(this.activePanelType)).removeAttribute('selected');}
 if(this.activePanelType){this.getLabelElementForPanelType_(this.activePanelType).removeAttribute('selected');}
 if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
 if(panelType===undefined){Polymer.dom(this).removeAttribute('expanded');this.activePanelType_=undefined;return;}
-Polymer.dom(this.getLabelElementForPanelType_(panelType)).setAttribute('selected',true);Polymer.dom(this).setAttribute('expanded',true);Polymer.dom(this.activePanelContainer_).appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_:function(constructor){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor===constructor){return this.tabStrip_.children[i].panelType;}}},getLabelElementForPanelType_:function(panelType){for(var i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType===panelType){return this.tabStrip_.children[i];}}
-return undefined;},updateContents_:function(){var previouslyActivePanelType=this.activePanelType;Polymer.dom(this.tabStrip_).textContent='';var supportedPanelTypes=[];for(var panelTypeInfo of
-tr.ui.side_panel.SidePanelRegistry.getAllRegisteredTypeInfos()){var labelEl=document.createElement('tab-strip-label');var panel=panelTypeInfo.constructor();var panelType=panel.tagName;Polymer.dom(labelEl).textContent=panel.textLabel;labelEl.panelType=panelType;var supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);Polymer.dom(labelEl).setAttribute('enabled',true);labelEl.addEventListener('click',function(panelType){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this,panelType));}else{if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
+Polymer.dom(this.getLabelElementForPanelType_(panelType)).setAttribute('selected',true);Polymer.dom(this).setAttribute('expanded',true);Polymer.dom(this.activePanelContainer_).appendChild(panel);panel.rangeOfInterest=this.rangeOfInterest_;panel.selection=this.selection_;panel.model=this.model;this.activePanelType_=panelType;},getPanelTypeForConstructor_(constructor){for(let i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType.constructor===constructor){return this.tabStrip_.children[i].panelType;}}},getLabelElementForPanelType_(panelType){for(let i=0;i<this.tabStrip_.children.length;i++){if(this.tabStrip_.children[i].panelType===panelType){return this.tabStrip_.children[i];}}
+return undefined;},updateContents_(){const previouslyActivePanelType=this.activePanelType;Polymer.dom(this.tabStrip_).textContent='';const supportedPanelTypes=[];for(const panelTypeInfo of
+tr.ui.side_panel.SidePanelRegistry.getAllRegisteredTypeInfos()){const labelEl=document.createElement('tab-strip-label');const panel=panelTypeInfo.constructor();const panelType=panel.tagName;Polymer.dom(labelEl).textContent=panel.textLabel;labelEl.panelType=panelType;const supported=panel.supportsModel(this.model);if(this.model&&supported.supported){supportedPanelTypes.push(panelType);Polymer.dom(labelEl).setAttribute('enabled',true);labelEl.addEventListener('click',function(panelType){this.activePanelType=this.activePanelType===panelType?undefined:panelType;}.bind(this,panelType));}else{if(this.activePanel){this.activePanelContainer_.removeChild(this.activePanel);}
 this.removeAttribute('expanded');}
 Polymer.dom(this.tabStrip_).appendChild(labelEl);}
 if(previouslyActivePanelType&&supportedPanelTypes.includes(previouslyActivePanelType)){this.activePanelType=previouslyActivePanelType;Polymer.dom(this).setAttribute('expanded',true);}else{if(this.activePanel){Polymer.dom(this.activePanelContainer_).removeChild(this.activePanel);}
 Polymer.dom(this).removeAttribute('expanded');}},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){if(range===undefined){throw new Error('Must not be undefined');}
-this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready:function(){var mod=tr.isMac?'cmd ':'ctrl';var spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(var i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready:function(){this.preferredTimeDisplayMode_=undefined;},attached:function(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached:function(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer({is:'tr-ui-timeline-view',attached:function(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}});},ready:function(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');Polymer.dom(this.rightControls).appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
-this.optionsDropdown_=this.$.view_options_dropdown;Polymer.dom(this.optionsDropdown_.iconElement).textContent='View Options';this.showFlowEvents_=false;Polymer.dom(this.optionsDropdown_).appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){var sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon:function(){var hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
-var faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined){faviconData=tr.ui.b.FaviconsByHue['blue'];}
-var link=Polymer.dom(document.head).querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';Polymer.dom(document.head).appendChild(link);}
-link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_:function(){var helpButtonEl=this.$.view_help_button;var dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.visible=false;dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));function onClick(e){dlg.visible=!dlg.visible;e.stopPropagation();}
-helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_:function(){var toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
-toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_:function(){var showEl=this.$.view_metadata_button;function onClick(e){var dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';var metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;Polymer.dom(dlg).appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
-showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_:function(){var showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return Polymer.dom(this.titleEl_).textContent.substring(Polymer.dom(this.titleEl_).textContent.length-2);},set viewTitle(text){if(text===undefined){Polymer.dom(this.titleEl_).textContent='';this.titleEl_.hidden=true;return;}
+this.rangeOfInterest_=range;if(this.activePanel){this.activePanel.rangeOfInterest=range;}}});'use strict';Polymer({is:'tr-ui-timeline-view-help-overlay',ready(){const mod=tr.isMac?'cmd ':'ctrl';const spans=Polymer.dom(this.root).querySelectorAll('span.mod');for(let i=0;i<spans.length;i++){Polymer.dom(spans[i]).textContent=mod;}}});'use strict';Polymer({is:'tr-ui-timeline-view-metadata-overlay',created(){this.metadata_=undefined;},ready(){this.$.table.tableColumns=[{title:'name',value:d=>d.name,},{title:'value',value:d=>{const gov=document.createElement('tr-ui-a-generic-object-view');gov.object=d.value;return gov;},}];},get metadata(){return this.metadata_;},set metadata(metadata){this.metadata_=metadata;this.$.table.tableRows=this.metadata_;this.$.table.rebuild();}});'use strict';Polymer({is:'tr-v-ui-preferred-display-unit',ready(){this.preferredTimeDisplayMode_=undefined;},attached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},detached(){tr.b.Unit.didPreferredTimeDisplayUnitChange();},get preferredTimeDisplayMode(){return this.preferredTimeDisplayMode_;},set preferredTimeDisplayMode(v){if(this.preferredTimeDisplayMode_===v)return;this.preferredTimeDisplayMode_=v;tr.b.Unit.didPreferredTimeDisplayUnitChange();}});'use strict';Polymer({is:'tr-ui-timeline-view',attached(){this.async(function(){this.trackViewContainer_=Polymer.dom(this).querySelector('#track_view_container');if(!this.trackViewContainer_){throw new Error('missing trackviewContainer');}});},ready(){this.tabIndex=0;this.titleEl_=this.$.title;this.leftControlsEl_=this.$.left_controls;this.rightControlsEl_=this.$.right_controls;this.collapsingControlsEl_=this.$.collapsing_controls;this.sidePanelContainer_=this.$.side_panel_container;this.brushingStateController_=new tr.c.BrushingStateController(this);this.findCtl_=this.$.view_find_control;this.findCtl_.controller=new tr.ui.FindController(this.brushingStateController_);this.scriptingCtl_=document.createElement('tr-ui-scripting-control');this.scriptingCtl_.controller=new tr.c.ScriptingController(this.brushingStateController_);this.sidePanelContainer_.brushingStateController=this.brushingStateController_;if(window.tr.metrics&&window.tr.metrics.sh&&window.tr.metrics.sh.SystemHealthMetric){this.railScoreSpan_=document.createElement('tr-metrics-ui-sh-system-health-span');Polymer.dom(this.rightControls).appendChild(this.railScoreSpan_);}else{this.railScoreSpan_=undefined;}
+this.optionsDropdown_=this.$.view_options_dropdown;Polymer.dom(this.optionsDropdown_.iconElement).textContent='View Options';this.showFlowEvents_=false;Polymer.dom(this.optionsDropdown_).appendChild(tr.ui.b.createCheckBox(this,'showFlowEvents','tr.ui.TimelineView.showFlowEvents',false,'Flow events'));this.highlightVSync_=false;this.highlightVSyncCheckbox_=tr.ui.b.createCheckBox(this,'highlightVSync','tr.ui.TimelineView.highlightVSync',false,'Highlight VSync');Polymer.dom(this.optionsDropdown_).appendChild(this.highlightVSyncCheckbox_);this.initMetadataButton_();this.initConsoleButton_();this.initHelpButton_();Polymer.dom(this.collapsingControls).appendChild(this.scriptingCtl_);this.dragEl_=this.$.drag_handle;this.analysisEl_=this.$.analysis;this.analysisEl_.brushingStateController=this.brushingStateController_;this.addEventListener('requestSelectionChange',function(e){const sc=this.brushingStateController_;sc.changeSelectionFromRequestSelectionChangeEvent(e.selection);}.bind(this));this.onViewportChanged_=this.onViewportChanged_.bind(this);this.bindKeyListeners_();this.dragEl_.target=this.analysisEl_;},get globalMode(){return this.hotkeyController.globalMode;},set globalMode(globalMode){globalMode=!!globalMode;this.brushingStateController_.historyEnabled=globalMode;this.hotkeyController.globalMode=globalMode;},get hotkeyController(){return this.$.hkc;},updateDocumentFavicon(){let hue;if(!this.model){hue='blue';}else{hue=this.model.faviconHue;}
+let faviconData=tr.ui.b.FaviconsByHue[hue];if(faviconData===undefined){faviconData=tr.ui.b.FaviconsByHue.blue;}
+let link=Polymer.dom(document.head).querySelector('link[rel="shortcut icon"]');if(!link){link=document.createElement('link');link.rel='shortcut icon';Polymer.dom(document.head).appendChild(link);}
+link.href=faviconData;},get showFlowEvents(){return this.showFlowEvents_;},set showFlowEvents(showFlowEvents){this.showFlowEvents_=showFlowEvents;if(!this.trackView_)return;this.trackView_.viewport.showFlowEvents=showFlowEvents;},get highlightVSync(){return this.highlightVSync_;},set highlightVSync(highlightVSync){this.highlightVSync_=highlightVSync;if(!this.trackView_)return;this.trackView_.viewport.highlightVSync=highlightVSync;},initHelpButton_(){const helpButtonEl=this.$.view_help_button;const dlg=new tr.ui.b.Overlay();dlg.title='Chrome Tracing Help';dlg.visible=false;dlg.appendChild(document.createElement('tr-ui-timeline-view-help-overlay'));function onClick(e){dlg.visible=!dlg.visible;e.stopPropagation();}
+helpButtonEl.addEventListener('click',onClick.bind(this));},initConsoleButton_(){const toggleEl=this.$.view_console_button;function onClick(e){this.scriptingCtl_.toggleVisibility();e.stopPropagation();return false;}
+toggleEl.addEventListener('click',onClick.bind(this));},initMetadataButton_(){const showEl=this.$.view_metadata_button;function onClick(e){const dlg=new tr.ui.b.Overlay();dlg.title='Metadata for trace';const metadataOverlay=document.createElement('tr-ui-timeline-view-metadata-overlay');metadataOverlay.metadata=this.model.metadata;Polymer.dom(dlg).appendChild(metadataOverlay);dlg.visible=true;e.stopPropagation();return false;}
+showEl.addEventListener('click',onClick.bind(this));this.updateMetadataButtonVisibility_();},updateMetadataButtonVisibility_(){const showEl=this.$.view_metadata_button;showEl.style.display=(this.model&&this.model.metadata.length)?'':'none';},get leftControls(){return this.leftControlsEl_;},get rightControls(){return this.rightControlsEl_;},get collapsingControls(){return this.collapsingControlsEl_;},get viewTitle(){return Polymer.dom(this.titleEl_).textContent.substring(Polymer.dom(this.titleEl_).textContent.length-2);},set viewTitle(text){if(text===undefined){Polymer.dom(this.titleEl_).textContent='';this.titleEl_.hidden=true;return;}
 this.titleEl_.hidden=false;Polymer.dom(this.titleEl_).textContent=text;},get model(){if(this.trackView_){return this.trackView_.model;}
-return undefined;},set model(model){var modelInstanceChanged=model!==this.model;var modelValid=model&&!model.bounds.isEmpty;var importWarningsEl=Polymer.dom(this.root).querySelector('#import-warnings');Polymer.dom(importWarningsEl).textContent='';if(modelInstanceChanged){if(this.railScoreSpan_){this.railScoreSpan_.model=undefined;}
+return undefined;},set model(model){const modelInstanceChanged=model!==this.model;const modelValid=model&&!model.bounds.isEmpty;const importWarningsEl=Polymer.dom(this.root).querySelector('#import-warnings');Polymer.dom(importWarningsEl).textContent='';if(modelInstanceChanged){if(this.railScoreSpan_){this.railScoreSpan_.model=undefined;}
 Polymer.dom(this.trackViewContainer_).textContent='';if(this.trackView_){this.trackView_.viewport.removeEventListener('change',this.onViewportChanged_);this.trackView_.brushingStateController=undefined;this.trackView_.detach();this.trackView_=undefined;}
 this.brushingStateController_.modelWillChange();}
 if(modelValid&&!this.trackView_){this.trackView_=document.createElement('tr-ui-timeline-track-view');this.trackView_.timelineView=this;this.trackView.brushingStateController=this.brushingStateController_;Polymer.dom(this.trackViewContainer_).appendChild(this.trackView_);this.trackView_.viewport.addEventListener('change',this.onViewportChanged_);}
@@ -8945,69 +9375,68 @@
 if(model){model.importWarningsThatShouldBeShownToUser.forEach(function(importWarning){importWarningsEl.addMessage('Import Warning: '+importWarning.type+': '+
 importWarning.message);},this);}
 if(modelInstanceChanged){this.updateMetadataButtonVisibility_();this.brushingStateController_.modelDidChange();this.onViewportChanged_();}},get brushingStateController(){return this.brushingStateController_;},get trackView(){return this.trackView_;},get settings(){if(!this.settings_){this.settings_=new tr.b.Settings();}
-return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_:function(){var hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus){this.focus();}
-e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback:function(e){if(this.scriptingCtl_.hasFocus)return;if(this.findCtl_.hasFocus){this.focus();}else{this.findCtl_.focus();}
-e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback:function(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_:function(e){var spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
-var vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr)){spc.rangeOfInterest=vr;}
-if(this.railScoreSpan_&&this.model){this.railScoreSpan_.model=this.model;}},toggleHighlightVSync_:function(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText:function(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined){groupingKeyFuncs=[];}
+return this.settings_;},set focusElement(value){throw new Error('This is deprecated. Please set globalMode to true.');},bindKeyListeners_(){const hkc=this.hotkeyController;hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'`'.charCodeAt(0),useCapture:true,thisArg:this,callback(e){this.scriptingCtl_.toggleVisibility();if(!this.scriptingCtl_.hasFocus){this.focus();}
+e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'/'.charCodeAt(0),useCapture:true,thisArg:this,callback(e){if(this.scriptingCtl_.hasFocus)return;if(this.findCtl_.hasFocus){this.focus();}else{this.findCtl_.focus();}
+e.preventDefault();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'?'.charCodeAt(0),useCapture:false,thisArg:this,callback(e){this.$.view_help_button.click();e.stopPropagation();}}));hkc.addHotKey(new tr.ui.b.HotKey({eventType:'keypress',keyCode:'v'.charCodeAt(0),useCapture:false,thisArg:this,callback(e){this.toggleHighlightVSync_();e.stopPropagation();}}));},onViewportChanged_(e){const spc=this.sidePanelContainer_;if(!this.trackView_){spc.rangeOfInterest.reset();return;}
+const vr=this.trackView_.viewport.interestRange.asRangeObject();if(!spc.rangeOfInterest.equals(vr)){spc.rangeOfInterest=vr;}
+if(this.railScoreSpan_&&this.model){this.railScoreSpan_.model=this.model;}},toggleHighlightVSync_(){this.highlightVSyncCheckbox_.checked=!this.highlightVSyncCheckbox_.checked;},setFindCtlText(string){this.findCtl_.setText(string);}});'use strict';tr.exportTo('tr.ui.b',function(){function Row(title,data,groupingKeyFuncs,rowStatsConstructor){this.title=title;this.data_=data;if(groupingKeyFuncs===undefined){groupingKeyFuncs=[];}
 this.groupingKeyFuncs_=groupingKeyFuncs;this.rowStatsConstructor_=rowStatsConstructor;this.subRowsBuilt_=false;this.subRows_=undefined;this.rowStats_=undefined;}
-Row.prototype={getCurrentGroupingKeyFunc_:function(){if(this.groupingKeyFuncs_.length===0)return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
-return this.rowStats_;},rebuildSubRowsIfNeeded_:function(){if(this.subRowsBuilt_)return;this.subRowsBuilt_=true;var groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
-var dataByKey={};var hasValues=false;this.data_.forEach(function(datum){var key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined){dataByKey[key]=[];}
+Row.prototype={getCurrentGroupingKeyFunc_(){if(this.groupingKeyFuncs_.length===0)return undefined;return this.groupingKeyFuncs_[0];},get data(){return this.data_;},get rowStats(){if(this.rowStats_===undefined){this.rowStats_=new this.rowStatsConstructor_(this);}
+return this.rowStats_;},rebuildSubRowsIfNeeded_(){if(this.subRowsBuilt_)return;this.subRowsBuilt_=true;const groupingKeyFunc=this.getCurrentGroupingKeyFunc_();if(groupingKeyFunc===undefined){this.subRows_=undefined;return;}
+const dataByKey={};let hasValues=false;this.data_.forEach(function(datum){const key=groupingKeyFunc(datum);hasValues=hasValues||(key!==undefined);if(dataByKey[key]===undefined){dataByKey[key]=[];}
 dataByKey[key].push(datum);});if(!hasValues){this.subRows_=undefined;return;}
-this.subRows_=[];for(var key in dataByKey){var row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer({is:'tr-ui-b-grouping-table',created:function(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild:function(){this.$.table.rebuild();},updateContents_:function(){var groupBy=this.groupBy_||[];var dataToGroup=this.dataToGroup_||[];var rowStatsConstructor=this.rowStatsConstructor_||function(){};var superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){var THIS_DOC=document.currentScript.ownerDocument;Polymer({is:'tr-ui-b-grouping-table-groupby-picker-group',created:function(){this.picker_=undefined;this.group_=undefined;},get picker(){return this.picker_;},set picker(picker){this.picker_=picker;},get group(){return this.group_;},set group(g){this.group_=g;this.$.label.textContent=g.label;},get enabled(){return this.$.enabled.checked;},set enabled(enabled){this.$.enabled.checked=enabled;if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}},set isFirst(isFirst){this.$.left.style.display=(!this.enabled||isFirst)?'none':'inline';},set isLast(isLast){this.$.right.style.display=(!this.enabled||isLast)?'none':'inline';},moveLeft_:function(){this.picker.moveLeft_(this);},moveRight_:function(){this.picker.moveRight_(this);},onEnableChanged_:function(){if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}
-this.picker.onEnableChanged_(this);}});Polymer({is:'tr-ui-b-grouping-table-groupby-picker',created:function(){this.settingsKey_=undefined;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(this.$.container.children.length){this.restoreSetting_();}},restoreSetting_:function(){this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.currentGroupKeys);},get possibleGroups(){return[...this.$.container.children].map(groupEl=>groupEl.group);},set possibleGroups(possibleGroups){Polymer.dom(this.$.container).textContent='';for(var i=0;i<possibleGroups.length;++i){var groupEl=document.createElement('tr-ui-b-grouping-table-groupby-picker-group');groupEl.picker=this;groupEl.group=possibleGroups[i];Polymer.dom(this.$.container).appendChild(groupEl);}
-this.restoreSetting_();this.updateFirstLast_();},updateFirstLast_:function(){var groupEls=this.$.container.children;var enabledGroupEls=[...groupEls].filter(el=>el.enabled);for(var i=0;i<enabledGroupEls.length;++i){enabledGroupEls[i].isFirst=i===0;enabledGroupEls[i].isLast=i===enabledGroupEls.length-1;}},get currentGroupKeys(){return this.currentGroups.map(group=>group.key);},get currentGroups(){var groups=[];for(var groupEl of this.$.container.children){if(groupEl.enabled){groups.push(groupEl.group);}}
+this.subRows_=[];for(const key in dataByKey){const row=new Row(key,dataByKey[key],this.groupingKeyFuncs_.slice(1),this.rowStatsConstructor_);this.subRows_.push(row);}},get isExpanded(){return(this.subRows&&(this.subRows.length>0)&&(this.subRows.length<5));},get subRows(){this.rebuildSubRowsIfNeeded_();return this.subRows_;}};Polymer({is:'tr-ui-b-grouping-table',created(){this.dataToGroup_=undefined;this.groupBy_=undefined;this.rowStatsConstructor_=undefined;},get tableColumns(){return this.$.table.tableColumns;},set tableColumns(tableColumns){this.$.table.tableColumns=tableColumns;},get tableRows(){return this.$.table.tableRows;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortColumnIndex(sortColumnIndex){this.$.table.sortColumnIndex=sortColumnIndex;},get sortDescending(){return this.$.table.sortDescending;},set sortDescending(sortDescending){this.$.table.sortDescending=sortDescending;},get selectionMode(){return this.$.table.selectionMode;},set selectionMode(selectionMode){this.$.table.selectionMode=selectionMode;},get rowHighlightStyle(){return this.$.table.rowHighlightStyle;},set rowHighlightStyle(rowHighlightStyle){this.$.table.rowHighlightStyle=rowHighlightStyle;},get cellHighlightStyle(){return this.$.table.cellHighlightStyle;},set cellHighlightStyle(cellHighlightStyle){this.$.table.cellHighlightStyle=cellHighlightStyle;},get selectedColumnIndex(){return this.$.table.selectedColumnIndex;},set selectedColumnIndex(selectedColumnIndex){this.$.table.selectedColumnIndex=selectedColumnIndex;},get selectedTableRow(){return this.$.table.selectedTableRow;},set selectedTableRow(selectedTableRow){this.$.table.selectedTableRow=selectedTableRow;},get groupBy(){return this.groupBy_;},set groupBy(groupBy){this.groupBy_=groupBy;this.updateContents_();},get dataToGroup(){return this.dataToGroup_;},set dataToGroup(dataToGroup){this.dataToGroup_=dataToGroup;this.updateContents_();},get rowStatsConstructor(){return this.rowStatsConstructor_;},set rowStatsConstructor(rowStatsConstructor){this.rowStatsConstructor_=rowStatsConstructor;this.updateContents_();},rebuild(){this.$.table.rebuild();},updateContents_(){const groupBy=this.groupBy_||[];const dataToGroup=this.dataToGroup_||[];const rowStatsConstructor=this.rowStatsConstructor_||function(){};const superRow=new Row('',dataToGroup,groupBy,rowStatsConstructor);this.$.table.tableRows=superRow.subRows||[];}});return{};});'use strict';tr.exportTo('tr.ui.b',function(){const THIS_DOC=document.currentScript.ownerDocument;Polymer({is:'tr-ui-b-grouping-table-groupby-picker-group',created(){this.picker_=undefined;this.group_=undefined;},get picker(){return this.picker_;},set picker(picker){this.picker_=picker;},get group(){return this.group_;},set group(g){this.group_=g;this.$.label.textContent=g.label;},get enabled(){return this.$.enabled.checked;},set enabled(enabled){this.$.enabled.checked=enabled;if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}},set isFirst(isFirst){this.$.left.style.display=(!this.enabled||isFirst)?'none':'inline';},set isLast(isLast){this.$.right.style.display=(!this.enabled||isLast)?'none':'inline';},moveLeft_(){this.picker.moveLeft_(this);},moveRight_(){this.picker.moveRight_(this);},onEnableChanged_(){if(!this.enabled){this.$.left.style.display='none';this.$.right.style.display='none';}
+this.picker.onEnableChanged_(this);}});Polymer({is:'tr-ui-b-grouping-table-groupby-picker',created(){this.settingsKey_=undefined;},get settingsKey(){return this.settingsKey_;},set settingsKey(settingsKey){this.settingsKey_=settingsKey;if(this.$.container.children.length){this.restoreSetting_();}},restoreSetting_(){if(this.settingsKey_===undefined)return;this.currentGroupKeys=tr.b.Settings.get(this.settingsKey_,this.currentGroupKeys);},get possibleGroups(){return[...this.$.container.children].map(groupEl=>groupEl.group);},set possibleGroups(possibleGroups){Polymer.dom(this.$.container).textContent='';for(let i=0;i<possibleGroups.length;++i){const groupEl=document.createElement('tr-ui-b-grouping-table-groupby-picker-group');groupEl.picker=this;groupEl.group=possibleGroups[i];Polymer.dom(this.$.container).appendChild(groupEl);}
+this.restoreSetting_();this.updateFirstLast_();},updateFirstLast_(){const groupEls=this.$.container.children;const enabledGroupEls=[...groupEls].filter(el=>el.enabled);for(let i=0;i<enabledGroupEls.length;++i){enabledGroupEls[i].isFirst=i===0;enabledGroupEls[i].isLast=i===enabledGroupEls.length-1;}},get currentGroupKeys(){return this.currentGroups.map(group=>group.key);},get currentGroups(){const groups=[];for(const groupEl of this.$.container.children){if(groupEl.enabled){groups.push(groupEl.group);}}
 return groups;},set currentGroupKeys(newKeys){if(!tr.b.compareArrays(this.currentGroupKeys,newKeys,(x,y)=>x.localeCompare(y))){return;}
-var possibleGroups=new Map();for(var group of this.possibleGroups){possibleGroups.set(group.key,group);}
-var groupEls=this.$.container.children;var i=0;for(i=0;i<newKeys.length;++i){var group=possibleGroups.get(newKeys[i]);if(group===undefined){newKeys.splice(i,1);--i;continue;}
+const possibleGroups=new Map();for(const group of this.possibleGroups){possibleGroups.set(group.key,group);}
+const groupEls=this.$.container.children;let i=0;for(i=0;i<newKeys.length;++i){const group=possibleGroups.get(newKeys[i]);if(group===undefined){newKeys.splice(i,1);--i;continue;}
 groupEls[i].group=group;groupEls[i].enabled=true;possibleGroups.delete(newKeys[i]);}
-for(var group of possibleGroups.values()){groupEls[i].group=group;groupEls[i].enabled=false;++i;}
-this.updateFirstLast_();this.onCurrentGroupsChanged_();},moveLeft_:function(groupEl){var reference=groupEl.previousSibling;Polymer.dom(this.$.container).removeChild(groupEl);Polymer.dom(this.$.container).insertBefore(groupEl,reference);this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},moveRight_:function(groupEl){var reference=groupEl.nextSibling.nextSibling;Polymer.dom(this.$.container).removeChild(groupEl);if(reference){Polymer.dom(this.$.container).insertBefore(groupEl,reference);}else{Polymer.dom(this.$.container).appendChild(groupEl);}
-this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},onCurrentGroupsChanged_:function(){this.dispatchEvent(new tr.b.Event('current-groups-changed'));tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys);},onEnableChanged_:function(groupEl){this.updateFirstLast_();this.onCurrentGroupsChanged_();}});return{};});'use strict';(function(){Polymer({is:'tr-ui-sp-file-size-stats-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready:function(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn:function(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn:function(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn:function(eventStat){return eventStat.title;}}];if(this.$.picker.currentGroupKeys.length===0){this.$.picker.currentGroupKeys=['phase','title'];}
-this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel:function(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
+for(const group of possibleGroups.values()){groupEls[i].group=group;groupEls[i].enabled=false;++i;}
+this.updateFirstLast_();this.onCurrentGroupsChanged_();},moveLeft_(groupEl){const reference=groupEl.previousSibling;Polymer.dom(this.$.container).removeChild(groupEl);Polymer.dom(this.$.container).insertBefore(groupEl,reference);this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},moveRight_(groupEl){const reference=groupEl.nextSibling.nextSibling;Polymer.dom(this.$.container).removeChild(groupEl);if(reference){Polymer.dom(this.$.container).insertBefore(groupEl,reference);}else{Polymer.dom(this.$.container).appendChild(groupEl);}
+this.updateFirstLast_();if(groupEl.enabled){this.onCurrentGroupsChanged_();}},onCurrentGroupsChanged_(){this.dispatchEvent(new tr.b.Event('current-groups-changed'));tr.b.Settings.set(this.settingsKey_,this.currentGroupKeys);},onEnableChanged_(groupEl){this.updateFirstLast_();this.onCurrentGroupsChanged_();}});return{};});'use strict';(function(){Polymer({is:'tr-ui-sp-file-size-stats-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.selection_=new tr.model.EventSet();this.$.picker.settingsKey='tr-ui-sp-file-size-stats-side-panel-picker';this.$.picker.possibleGroups=[{key:'phase',label:'Event Type',dataFn(eventStat){return eventStat.phase;}},{key:'category',label:'Category',dataFn(eventStat){return eventStat.category;}},{key:'title',label:'Title',dataFn(eventStat){return eventStat.title;}}];if(this.$.picker.currentGroupKeys.length===0){this.$.picker.currentGroupKeys=['phase','title'];}
+this.$.picker.addEventListener('current-groups-changed',this.updateContents_.bind(this));},get textLabel(){return'File Size Stats';},supportsModel(m){if(!m){return{supported:false,reason:'No stats were collected for this file.'};}
 if(m.stats.allTraceEventStats.length===0){return{supported:false,reason:'No stats were collected for this file.'};}
-return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_:function(stats){var columns=[{title:'Title',value:function(row){var titleEl=document.createElement('span');Polymer.dom(titleEl).textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp:function(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,value:function(row){return row.rowStats.numEvents;},cmp:function(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',value:function(row){var value=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);var spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp:function(a,b){return a.rowStats.totalEventSizeinBytes-
+return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(rangeOfInterest){this.rangeOfInterest_=rangeOfInterest;},get selection(){return this.selection_;},set selection(selection){this.selection_=selection;},createColumns_(stats){const columns=[{title:'Title',value(row){const titleEl=document.createElement('span');Polymer.dom(titleEl).textContent=row.title;titleEl.style.textOverflow='ellipsis';return titleEl;},cmp(a,b){return a.title.localeCompare(b.title);},width:'400px'},{title:'Num Events',align:tr.ui.b.TableFormat.ColumnAlignment.RIGHT,value(row){return row.rowStats.numEvents;},cmp(a,b){return a.rowStats.numEvents-b.rowStats.numEvents;},width:'80px'}];if(stats&&stats.hasEventSizesinBytes){columns.push({title:'Bytes',value(row){const value=new tr.b.Scalar(tr.b.Unit.byName.sizeInBytes,row.rowStats.totalEventSizeinBytes);const spanEl=tr.v.ui.createScalarSpan(value);return spanEl;},cmp(a,b){return a.rowStats.totalEventSizeinBytes-
 b.rowStats.totalEventSizeinBytes;},width:'80px'});}
-return columns;},updateContents_:function(){var table=this.$.table;var columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){var sum=tr.b.math.Statistics.sum(row.data,function(x){return x.numEvents;});var totalEventSizeinBytes=tr.b.math.Statistics.sum(row.data,x=>x.totalEventSizeinBytes);return{numEvents:sum,totalEventSizeinBytes:totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
-this.$.table.rebuild();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-file-size-stats-side-panel');});})();'use strict';tr.exportTo('tr.mre',function(){var FunctionRegistry={allFunctions_:[],allFunctionsByName_:{},get allFunctions(){return this.allFunctions_;},get allFunctionsByName(){return this.allFunctionsByName_;}};FunctionRegistry.getFunction=function(name){return this.allFunctionsByName_[name];};FunctionRegistry.register=function(func){if(func.name===''){throw new Error('Registered functions must not be anonymous');}
+return columns;},updateContents_(){const table=this.$.table;const columns=this.createColumns_(this.model.stats);table.rowStatsConstructor=function ModelStatsRowStats(row){const sum=tr.b.math.Statistics.sum(row.data,function(x){return x.numEvents;});const totalEventSizeinBytes=tr.b.math.Statistics.sum(row.data,x=>x.totalEventSizeinBytes);return{numEvents:sum,totalEventSizeinBytes};};table.tableColumns=columns;table.sortColumnIndex=1;table.sortDescending=true;table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.groupBy=this.$.picker.currentGroups.map(function(group){return group.dataFn;});if(!this.model){table.dataToGroup=[];}else{table.dataToGroup=this.model.stats.allTraceEventStats;}
+this.$.table.rebuild();}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-file-size-stats-side-panel');});})();'use strict';tr.exportTo('tr.mre',function(){const FunctionRegistry={allFunctions_:[],allFunctionsByName_:{},get allFunctions(){return this.allFunctions_;},get allFunctionsByName(){return this.allFunctionsByName_;}};FunctionRegistry.getFunction=function(name){return this.allFunctionsByName_[name];};FunctionRegistry.register=function(func){if(func.name===''){throw new Error('Registered functions must not be anonymous');}
 if(this.allFunctionsByName[func.name]!==undefined){throw new Error('Function named '+func.name+'is already registered.');}
 this.allFunctionsByName[func.name]=func;this.allFunctions.push(func);};function ModuleToLoad(href,filename){if((href!==undefined)?(filename!==undefined):(filename===undefined)){throw new Error('ModuleToLoad must specify exactly one of href or '+'filename');}
 this.href=href;this.filename=filename;}
-ModuleToLoad.prototype={asDict:function(){if(this.href!==undefined){return{'href':this.href};}
-return{'filename':this.filename};},toString:function(){if(this.href!==undefined){return'ModuleToLoad(href="'+this.href+'")';}
+ModuleToLoad.prototype={asDict(){if(this.href!==undefined){return{'href':this.href};}
+return{'filename':this.filename};},toString(){if(this.href!==undefined){return'ModuleToLoad(href="'+this.href+'")';}
 return'ModuleToLoad(filename="'+this.filename+'")';}};ModuleToLoad.fromDict=function(moduleDict){return new ModuleToLoad(moduleDict.href,moduleDict.filename);};function FunctionHandle(modulesToLoad,functionName,opt_options){if(!(modulesToLoad instanceof Array)){throw new Error('modulesToLoad in FunctionHandle must be an array');}
 if(typeof(functionName)!=='string'){throw new Error('functionName in FunctionHandle must be a string');}
 this.modulesToLoad=modulesToLoad;this.functionName=functionName;this.options_=opt_options;}
-FunctionHandle.prototype={get options(){return this.options_;},asDict:function(){return{'modules_to_load':this.modulesToLoad.map(function(m){return m.asDict();}),'function_name':this.functionName,'options':this.options_};},asUserFriendlyString:function(){var parts=this.modulesToLoad.map(function(mtl){return mtl.filename;});parts.push(this.functionName);parts.push(JSON.stringify(this.options_));return parts.join(',');},hasHrefs:function(){for(var module in this.modulesToLoad){if(this.modulesToLoad[module].href!==undefined){return true;}}
-return false;},load:function(){if(this.hasHrefs()){var err=new Error('FunctionHandle named '+this.functionName+' specifies hrefs, which cannot be loaded.');err.name='FunctionLoadingError';throw err;}
-for(var module in this.modulesToLoad){var filename=this.modulesToLoad[module].filename;try{HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}}
-var func=FunctionRegistry.getFunction(this.functionName);if(func===undefined){var err=new Error('No registered function named '+this.functionName);err.name='FunctionNotDefinedError';throw err;}
-return func;},toString:function(){var modulesToLoadStr=this.modulesToLoad.map(function(module){return module.toString();});return'FunctionHandle(modulesToLoad=['+modulesToLoadStr+'], '+'functionName="'+this.functionName+'", options="'+
-JSON.stringify(this.options_)+'")';}};FunctionHandle.loadFromFilename_=function(filename){try{var numFunctionsBefore=FunctionRegistry.allFunctions.length;HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}
-var numFunctionsNow=FunctionRegistry.allFunctions.length;if(numFunctionsNow!==(numFunctionsBefore+1)){var err=new Error(filename+' didn\'t call FunctionRegistry.register');err.name='FunctionNotDefinedError';throw err;}
-return FunctionRegistry.allFunctions[numFunctionsNow-1];};FunctionHandle.fromDict=function(handleDict){var options=handleDict.options;if(handleDict.modules_to_load!==undefined){var modulesToLoad=handleDict.modules_to_load.map(function(module){return ModuleToLoad.fromDict(module);});}
+FunctionHandle.prototype={get options(){return this.options_;},asDict(){return{'modules_to_load':this.modulesToLoad.map(function(m){return m.asDict();}),'function_name':this.functionName,'options':this.options_};},asUserFriendlyString(){const parts=this.modulesToLoad.map(mtl=>mtl.filename);parts.push(this.functionName);parts.push(JSON.stringify(this.options_));return parts.join(',');},hasHrefs(){for(const module in this.modulesToLoad){if(this.modulesToLoad[module].href!==undefined){return true;}}
+return false;},load(){if(this.hasHrefs()){const err=new Error('FunctionHandle named '+this.functionName+' specifies hrefs, which cannot be loaded.');err.name='FunctionLoadingError';throw err;}
+for(const module in this.modulesToLoad){const filename=this.modulesToLoad[module].filename;try{HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}}
+const func=FunctionRegistry.getFunction(this.functionName);if(func===undefined){const err=new Error('No registered function named '+this.functionName);err.name='FunctionNotDefinedError';throw err;}
+return func;},toString(){const modulesToLoadStr=this.modulesToLoad.map(function(module){return module.toString();});return'FunctionHandle(modulesToLoad=['+modulesToLoadStr+'], '+'functionName="'+this.functionName+'", options="'+
+JSON.stringify(this.options_)+'")';}};FunctionHandle.loadFromFilename_=function(filename){try{const numFunctionsBefore=FunctionRegistry.allFunctions.length;HTMLImportsLoader.loadHTMLFile(filename);}catch(err){err.name='FunctionLoadingError';throw err;}
+const numFunctionsNow=FunctionRegistry.allFunctions.length;if(numFunctionsNow!==(numFunctionsBefore+1)){const err=new Error(filename+' didn\'t call FunctionRegistry.register');err.name='FunctionNotDefinedError';throw err;}
+return FunctionRegistry.allFunctions[numFunctionsNow-1];};FunctionHandle.fromDict=function(handleDict){const options=handleDict.options;let modulesToLoad;if(handleDict.modules_to_load!==undefined){modulesToLoad=handleDict.modules_to_load.map(function(module){return ModuleToLoad.fromDict(module);});}
 return new FunctionHandle(modulesToLoad,handleDict.function_name,options);};return{FunctionHandle,ModuleToLoad,FunctionRegistry,};});'use strict';tr.exportTo('tr.metrics',function(){function runMetrics(model,options){if(options===undefined){throw new Error('Options are required.');}
-var metricNames=options.metrics;if(!metricNames){throw new Error('Metric names should be specified.');}
-var histograms=new tr.v.HistogramSet();for(var metricName of metricNames){var metric=tr.metrics.MetricRegistry.findTypeInfoWithName(metricName);if(metric===undefined){throw new Error('"'+metricName+'" is not a registered metric.');}
+const metricNames=options.metrics;if(!metricNames){throw new Error('Metric names should be specified.');}
+const histograms=new tr.v.HistogramSet();for(const metricName of metricNames){const metric=tr.metrics.MetricRegistry.findTypeInfoWithName(metricName);if(metric===undefined){throw new Error('"'+metricName+'" is not a registered metric.');}
 metric.constructor(histograms,model,options);}
 return histograms;}
-function addTelemetryInfo(histograms,model){var telemetry=new tr.v.d.TelemetryInfo();for(var metadata of model.metadata){if(!metadata.value)continue;if(metadata.value.telemetry){telemetry.addInfo(metadata.value.telemetry);}}
+function addTelemetryInfo(histograms,model){const telemetry=new tr.v.d.TelemetryInfo();for(const metadata of model.metadata){if(!metadata.value)continue;if(metadata.value.telemetry){telemetry.addInfo(metadata.value.telemetry);}}
 histograms.addSharedDiagnostic(tr.v.d.TelemetryInfo.NAME,telemetry);}
-function metricMapFunction(result,model,options){var histograms=runMetrics(model,options);addTelemetryInfo(histograms,model);result.addPair('histograms',histograms.asDicts());var scalarDicts=[];for(var value of histograms){for(var[statName,scalar]of value.statisticsScalars){scalarDicts.push({name:value.name+'_'+statName,numeric:scalar.asDict(),description:value.description,});}}
+function metricMapFunction(result,model,options){const histograms=runMetrics(model,options);addTelemetryInfo(histograms,model);result.addPair('histograms',histograms.asDicts());const scalarDicts=[];for(const value of histograms){for(const[statName,scalar]of value.statisticsScalars){scalarDicts.push({name:value.name+'_'+statName,numeric:scalar.asDict(),description:value.description,});}}
 result.addPair('scalars',scalarDicts);}
 tr.mre.FunctionRegistry.register(metricMapFunction);return{metricMapFunction,runMetrics,};});'use strict';tr.exportTo('tr.mre',function(){function Failure(job,functionHandleString,traceCanonicalUrl,failureTypeName,description,stack){this.job=job;this.functionHandleString=functionHandleString;this.traceCanonicalUrl=traceCanonicalUrl;this.failureTypeName=failureTypeName;this.description=description;this.stack=stack;}
-Failure.prototype={asDict:function(){return{function_handle_string:this.functionHandleString,trace_canonical_url:this.traceCanonicalUrl,type:this.failureTypeName,description:this.description,stack:this.stack};}};Failure.fromDict=function(failureDict){return new Failure(undefined,failureDict.function_handle_string,failureDict.trace_canonical_url,failureDict.type,failureDict.description,failureDict.stack);};return{Failure,};});'use strict';tr.exportTo('tr.mre',function(){class MreResult{constructor(failures,pairs){if(failures===undefined){failures=[];}
+Failure.prototype={asDict(){return{function_handle_string:this.functionHandleString,trace_canonical_url:this.traceCanonicalUrl,type:this.failureTypeName,description:this.description,stack:this.stack};}};Failure.fromDict=function(failureDict){return new Failure(undefined,failureDict.function_handle_string,failureDict.trace_canonical_url,failureDict.type,failureDict.description,failureDict.stack);};return{Failure,};});'use strict';tr.exportTo('tr.mre',function(){class MreResult{constructor(failures,pairs){if(failures===undefined){failures=[];}
 if(pairs===undefined){pairs={};}
 this.failures=failures;this.pairs=pairs;}
 addFailure(failure){this.failures.push(failure);}
 addPair(key,value){if(key in this.pairs){throw new Error('Key '+key+' already exists in result.');}
 this.pairs[key]=value;}
-asDict(){var d={pairs:this.pairs};if(this.failures){d.failures=this.failures.map(function(f){return f.asDict();});}
+asDict(){const d={pairs:this.pairs};if(this.failures){d.failures=this.failures.map(function(f){return f.asDict();});}
 return d;}
 hadFailures(){return this.failures.length>0;}
-static fromDict(resultDict){if(resultDict.failures!==undefined){var failures=resultDict.failures.map(tr.mre.Failure.fromDict);}
-var pairs=resultDict.pairs;return new MreResult(failures,pairs);}}
+static fromDict(resultDict){const failures=(resultDict.failures!==undefined)?resultDict.failures.map(tr.mre.Failure.fromDict):undefined;const pairs=resultDict.pairs;return new MreResult(failures,pairs);}}
 return{MreResult,};});'use strict';tr.exportTo('tr.ui',function(){class NullBrushingStateController extends tr.c.BrushingStateController{constructor(){super(undefined);this.parentController=undefined;}
 dispatchChangeEvent_(){if(this.parentController)this.parentController.dispatchChangeEvent_();}
 get model(){if(!this.parentController)return undefined;return this.parentController.model;}
@@ -9038,130 +9467,164 @@
 getViewSpecificBrushingState(viewId){if(this.parentController){this.parentController.getViewSpecificBrushingState(viewId);}}
 changeViewSpecificBrushingState(viewId,newState){if(this.parentController){this.parentController.changeViewSpecificBrushingState(viewId,newState);}}}
 return{NullBrushingStateController,};});'use strict';tr.exportTo('tr.v',function(){const CSV_ITERATION_INFO_NAMES=['benchmarkName','benchmarkStartString','label','osVersion','productVersion','storyDisplayName','storysetRepeatCounter',];class CSVBuilder{constructor(histograms){this.histograms_=histograms;this.table_=[];this.statisticsNames_=new Set();this.iterationInfoNames_=new Set();this.storyGroupingKeys_=new Set();}
-build(){this.prepare_();this.buildHeader_();for(let hist of this.histograms_){let row=[hist.name,hist.unit.unitString];this.table_.push(row);let stats=hist.statisticsScalars;for(let name of this.statisticsNames_){row.push(stats.has(name)?stats.get(name).value:'');}
-let iteration=tr.v.d.TelemetryInfo.getFromHistogram(hist);for(let name of this.iterationInfoNames_){if(iteration===undefined||iteration[name]===undefined){row.push('');}else{row.push(iteration[name]);}}
-for(let key of this.storyGroupingKeys_){if(iteration===undefined||iteration.storyGroupingKeys.get(key)===undefined){row.push('');}else{row.push(iteration.storyGroupingKeys.get(key));}}}}
-prepare_(){for(let hist of this.histograms_){for(const name of hist.statisticsNames){this.statisticsNames_.add(name);}
-let iteration=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(iteration===undefined)continue;for(let name of CSV_ITERATION_INFO_NAMES){if(iteration[name]){this.iterationInfoNames_.add(name);}}
-for(let[key,value]of iteration.storyGroupingKeys){this.storyGroupingKeys_.add(key);}}}
-buildHeader_(){let header=['name','unit'];for(let name of this.statisticsNames_){header.push(name);}
-for(let name of this.iterationInfoNames_){header.push(name);}
-for(let key of this.storyGroupingKeys_){header.push(key);}
+build(){this.prepare_();this.buildHeader_();for(const hist of this.histograms_){const row=[hist.name,hist.unit.unitString];this.table_.push(row);const stats=hist.statisticsScalars;for(const name of this.statisticsNames_){row.push(stats.has(name)?stats.get(name).value:'');}
+const iteration=tr.v.d.TelemetryInfo.getFromHistogram(hist);for(const name of this.iterationInfoNames_){if(iteration===undefined||iteration[name]===undefined){row.push('');}else{row.push(iteration[name]);}}
+for(const key of this.storyGroupingKeys_){if(iteration===undefined||iteration.storyGroupingKeys.get(key)===undefined){row.push('');}else{row.push(iteration.storyGroupingKeys.get(key));}}}}
+prepare_(){for(const hist of this.histograms_){for(const name of hist.statisticsNames){this.statisticsNames_.add(name);}
+const iteration=tr.v.d.TelemetryInfo.getFromHistogram(hist);if(iteration===undefined)continue;for(const name of CSV_ITERATION_INFO_NAMES){if(iteration[name]){this.iterationInfoNames_.add(name);}}
+for(const[key,value]of iteration.storyGroupingKeys){this.storyGroupingKeys_.add(key);}}}
+buildHeader_(){const header=['name','unit'];for(const name of this.statisticsNames_){header.push(name);}
+for(const name of this.iterationInfoNames_){header.push(name);}
+for(const key of this.storyGroupingKeys_){header.push(key);}
 this.table_.push(header);}
-toString(){let str='';for(let row of this.table_){for(let i=0;i<row.length;++i){if(i>0){str+=',';}
+toString(){let str='';for(const row of this.table_){for(let i=0;i<row.length;++i){if(i>0){str+=',';}
 let cell=''+row[i];if(cell.indexOf(',')>=0||cell.indexOf('"')>=0){cell='"'+cell.replace(/"/g,'""')+'"';}
 str+=cell;}
 str+='\n';}
 return str;}}
-return{CSVBuilder,};});'use strict';tr.exportTo('tr.ui',function(){Polymer({is:'tr-v-ui-histogram-set-table-cell',created(){this.histogram_=undefined;this.referenceHistogram_=undefined;this.histogramSpan_=undefined;this.overviewChart_=undefined;this.row_=undefined;this.displayStatistic_='avg';},get displayStatistic(){return this.displayStatistic_;},set displayStatistic(statName){if(statName===this.displayStatistic)return;this.displayStatistic_=statName;this.updateContents_();},ready(){this.addEventListener('click',this.onClick_.bind(this));},onClick_(event){event.stopPropagation();},set row(row){this.row_=row;},get row(){return this.row_;},get histogram(){return this.histogram_;},set histogram(h){this.histogram_=h;this.updateContents_();},set referenceHistogram(rh){this.referenceHistogram_=rh;this.updateContents_();},get referenceHistogram(){return this.referenceHistogram_;},get isHistogramOpen(){return this.histogramSpan_&&(this.$.histogram.style.display==='block');},set isHistogramOpen(open){if(!(this.histogram instanceof tr.v.Histogram)||(this.histogram.numValues===0)){return;}
-this.$.scalar.style.display=open?'none':'flex';this.$.open_histogram.style.display=open?'none':'block';this.$.close_histogram.style.display=open?'block':'none';this.$.histogram.style.display=open?'block':'none';this.row.nameCell.onHistogramOpenChange();if(open&&this.histogramSpan_===undefined){this.histogramSpan_=document.createElement('tr-v-ui-histogram-span');this.$.histogram.appendChild(this.histogramSpan_);this.histogramSpan_.referenceHistogram=this.referenceHistogram;this.histogramSpan_.histogram=this.histogram;}},openHistogram_(){this.isHistogramOpen=true;},closeHistogram_(){this.isHistogramOpen=false;},updateContents_(){let isOpen=this.isHistogramOpen;this.$.empty.style.display='none';this.$.unmergeable.style.display='none';this.$.scalar.style.display='none';this.$.histogram.style.display='none';this.$.close_histogram.style.display='none';this.$.open_histogram.style.visibility='hidden';if(!this.histogram){this.$.missing.style.display='block';return;}
-this.$.missing.style.display='none';if(this.histogram===tr.v.ui.UNMERGEABLE){this.$.unmergeable.style.display='block';return;}
-if(!(this.histogram instanceof tr.v.Histogram)){throw new Error('Invalid Histogram: '+this.histogram);}
-if(this.histogram.numValues===0){this.$.empty.style.display='block';return;}
-this.$.open_histogram.style.display='block';this.$.open_histogram.style.visibility='visible';this.$.scalar.style.display='flex';if((this.referenceHistogram instanceof tr.v.Histogram)&&(this.histogram.unit===this.referenceHistogram.unit)&&(this.referenceHistogram.numValues>0)){this.$.scalar.significance=this.histogram.getDifferenceSignificance(this.referenceHistogram);}
-const statName=this.histogram.getAvailableStatisticName(this.displayStatistic,this.referenceHistogram);const statisticScalar=this.histogram.getStatisticScalar(statName,this.referenceHistogram);this.$.scalar.setValueAndUnit(statisticScalar.value,statisticScalar.unit);this.isHistogramOpen=isOpen;},showOverview(){this.$.overview_container.style.display='block';if(this.overviewChart_!==undefined)return;let displayLabel;for(let[label,hist]of this.row.columns){if(hist===this.histogram){displayLabel=label;}}
-let data=[];let unitString;for(let subRow of this.row.subRows){let subHist=subRow.columns.get(displayLabel);if(subHist){data.push({x:subRow.name,y:subHist.average});unitString=subHist.unit.unitString;}}
-if(data.length<2)return;this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.hideLegend=true;this.overviewChart_.yAxisLabel=unitString;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;},hideOverview(){this.$.overview_container.style.display='none';}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){const NAME_COLUMN_WIDTH_PX=300;Polymer({is:'tr-v-ui-histogram-set-table-name-cell',created(){this.row_=undefined;this.overviewChart_=undefined;},attached(){if(this.isOverflowing){this.dispatchEvent(new tr.b.Event('name-cell-overflow'));}},get row(){return this.row_;},set row(row){this.row_=row;Polymer.dom(this.$.name).textContent=this.row.name;this.title=this.row.name;if(this.row.description){this.title+='\n'+this.row.description;}
-let histogramCount=0;for(const cell of this.row.cells.values()){if(cell.histogram instanceof tr.v.Histogram&&cell.histogram.numValues>0){++histogramCount;}}
-if(histogramCount<=1){this.$.close_histograms.style.display='none';this.$.open_histograms.style.display='none';}},set constrainWidth(constrain){this.$.name.style.maxWidth=constrain?(this.nameWidthPx+'px'):'none';},get nameWidthPx(){return NAME_COLUMN_WIDTH_PX-(16*this.row.depth);},get isOverflowing(){return this.$.name.style.maxWidth!=='none'&&this.$.name.getBoundingClientRect().width===this.nameWidthPx;},hideOverview_(opt_event){if(opt_event){opt_event.stopPropagation();}
-this.$.overview_container.style.display='none';this.$.hide_overview.style.display='none';this.$.show_overview.style.display='block';for(let[displayLabel,cell]of this.row.cells){cell.hideOverview();}},showOverview_(opt_event){if(opt_event){opt_event.preventDefault();opt_event.stopPropagation();}
-this.$.overview_container.style.display='block';if(this.overviewChart_===undefined){let data=[];let unitString=undefined;for(let[displayLabel,hist]of this.row.columns){data.push({x:displayLabel,y:hist.average});unitString=hist.unit.unitString;}
-if(data.length<2){return;}
-this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.hideLegend=true;this.overviewChart_.yAxisLabel=unitString;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;}
-this.$.hide_overview.style.display='block';this.$.show_overview.style.display='none';for(let cell of this.row.cells.values()){cell.showOverview();}},openHistograms_(){for(let cell of this.row.cells.values()){cell.isHistogramOpen=true;}
-this.$.close_histograms.style.display='block';this.$.open_histograms.style.display='none';},closeHistograms_(){for(let cell of this.row.cells.values()){cell.isHistogramOpen=false;}
-this.$.open_histograms.style.display='block';this.$.close_histograms.style.display='none';},onHistogramOpenChange(){let cellCount=0;let openCellCount=0;for(let cell of this.row.cells.values()){if(!(cell.histogram instanceof tr.v.Histogram)||(cell.histogram.numValues===0)){continue;}
-++cellCount;if(cell.isHistogramOpen)++openCellCount;}
-if(cellCount<=1)return;const mostlyOpen=openCellCount>(cellCount/2);this.$.open_histograms.style.display=mostlyOpen?'none':'block';this.$.close_histograms.style.display=mostlyOpen?'block':'none';}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetTableRow{constructor(name){this.name=name;this.description='';this.depth=0;this.subRows=[];this.columns=new Map();this.nameCell_=undefined;this.cells=new Map();this.constrainNameColumnWidth_=false;this.overviewDataRange_=undefined;this.displayStatistic_='avg';this.doMergeRelationshipsForColumn_=new Map();}
-static filter(rows,histograms){let results=[];for(let row of rows){let filteredSubRows=[];if(row.subRows.length>0){filteredSubRows=HistogramSetTableRow.filter(row.subRows,histograms);if(filteredSubRows.length===0)continue;}else{let found=false;for(let testHist of row.columns.values()){if(!(testHist instanceof tr.v.Histogram))continue;if(histograms.lookupHistogram(testHist.guid)!==undefined){found=true;break;}
-let mergedFrom=testHist.diagnostics.get(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY);if(mergedFrom!==undefined){for(let origHist of mergedFrom){if(histograms.lookupHistogram(origHist.guid)!==undefined){found=true;break;}}}
-if(found)break;}
-if(!found)continue;}
-let clone=new HistogramSetTableRow(row.name);clone.description=row.description;clone.depth=row.depth;clone.subRows=filteredSubRows;clone.columns=row.columns;clone.nameCell_=row.nameCell_;clone.cells=row.cells;clone.constrainNameColumnWidth_=row.constrainNameColumnWidth_;clone.overviewDataRange_=row.overviewDataRange_;clone.displayStatistic_=row.displayStatistic_;results.push(clone);}
-return results;}
-static build(histogramArrayMap){const rootRows=[];HistogramSetTableRow.buildInternal_(histogramArrayMap,[],rootRows);const histograms=new tr.v.HistogramSet();for(const row of HistogramSetTableRow.walkAll(rootRows)){for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
-histograms.deduplicateDiagnostics();for(const row of HistogramSetTableRow.walkAll(rootRows)){for(const[name,hist]of row.columns){if(!(hist instanceof tr.v.Histogram))continue;if(!row.doMergeRelationshipsForColumn_.get(name))continue;hist.diagnostics.mergeRelationships(hist);}}
-for(const row of HistogramSetTableRow.walkAll(rootRows)){if(row.subRows.length)continue;for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;const mergedFrom=hist.diagnostics.get(tr.v.MERGED_FROM_DIAGNOSTIC_KEY);if(mergedFrom!==undefined){for(const other of mergedFrom){other.diagnostics.delete(tr.v.MERGED_TO_DIAGNOSTIC_KEY);}}}}
-for(const row of HistogramSetTableRow.walkAll(rootRows)){row.maybeRebin_();}
-return rootRows;}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
+return{CSVBuilder,};});'use strict';tr.exportTo('tr.v',function(){const getDisplayLabel=tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL.callback;const DEFAULT_POSSIBLE_GROUPS=[];DEFAULT_POSSIBLE_GROUPS.push(new tr.v.HistogramGrouping(tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME.key,h=>h.shortName||h.name));for(const group of Object.values(tr.v.HistogramSet.GROUPINGS)){if(group!==tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL&&group!==tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME){DEFAULT_POSSIBLE_GROUPS.push(group);}}
+class HistogramParameterCollector{constructor(){this.statisticNames_=new Set(['avg']);this.labelsToStartTimes_=new Map();this.keysToGroupings_=new Map(DEFAULT_POSSIBLE_GROUPS.map(g=>[g.key,g]));this.keysToValues_=new Map(DEFAULT_POSSIBLE_GROUPS.map(g=>[g.key,new Set()]));this.keysToValues_.delete(tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME.key);}
+process(histograms){for(const hist of histograms){for(const statName of hist.statisticsNames){this.statisticNames_.add(statName);}
+const telemetry=tr.v.d.TelemetryInfo.getFromHistogram(hist);let startTime=0;if(telemetry&&telemetry.benchmarkStart){startTime=telemetry.benchmarkStart.getTime();}
+const displayLabel=getDisplayLabel(hist);if(this.labelsToStartTimes_.has(displayLabel)){startTime=Math.min(startTime,this.labelsToStartTimes_.get(displayLabel));}
+this.labelsToStartTimes_.set(displayLabel,startTime);if(!telemetry)continue;for(const[groupingKey,values]of this.keysToValues_){const grouping=this.keysToGroupings_.get(groupingKey);const value=grouping.callback(hist);if(!value)continue;values.add(value);if(values.size>1){this.keysToValues_.delete(groupingKey);}}
+for(const[key,value]of telemetry.storyGroupingKeys){const groupingKey='storyGroupingKey_'+key;if(this.keysToGroupings_.has(groupingKey))continue;this.keysToGroupings_.set(groupingKey,new tr.v.HistogramGrouping(groupingKey,tr.v.d.TelemetryInfo.makeStoryGroupingKeyLabelGetter(key)));this.keysToValues_.set(groupingKey,new Set([value]));}}}
+get statisticNames(){return Array.from(this.statisticNames_);}
+get labels(){const displayLabels=Array.from(this.labelsToStartTimes_.keys());displayLabels.sort((x,y)=>this.labelsToStartTimes_.get(x)-this.labelsToStartTimes_.get(y));return displayLabels;}
+get possibleGroupings(){for(const[key,values]of this.keysToValues_){if(values.size>=2)continue;this.keysToGroupings_.delete(key);}
+return Array.from(this.keysToGroupings_.values());}}
+return{HistogramParameterCollector,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-controls',properties:{searchQuery:{type:String,value:'',observer:'onUserChange_',},showAll:{type:Boolean,value:false,observer:'onUserChange_',},referenceDisplayLabel:{type:String,value:'',observer:'onUserChange_',},displayStatisticName:{type:String,value:'',observer:'onUserChange_',},},created(){this.viewState_=undefined;this.rowListener_=this.onRowViewStateUpdate_.bind(this);this.baseStatisticNames_=[];this.isInOnViewStateUpdate_=false;},ready(){this.$.picker.addEventListener('current-groups-changed',this.onGroupsChanged_.bind(this));},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState_){throw new Error('viewState must be set exactly once.');}
+this.viewState_=vs;this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));},async onUserChange_(){if(!this.viewState)return;if(this.isInOnViewStateUpdate_)return;const marks=[];if(this.searchQuery!==this.viewState.searchQuery){marks.push(tr.b.Timing.mark('histogram-set-controls','search'));}
+if(this.showAll!==this.viewState.showAll){marks.push(tr.b.Timing.mark('histogram-set-controls','showAll'));}
+if(this.referenceDisplayLabel!==this.viewState.referenceDisplayLabel){marks.push(tr.b.Timing.mark('histogram-set-controls','referenceColumn'));}
+if(this.displayStatisticName!==this.viewState.displayStatisticName){marks.push(tr.b.Timing.mark('histogram-set-controls','statistic'));}
+let displayStatisticName=this.displayStatisticName;if(this.viewState.referenceDisplayLabel===''&&this.referenceDisplayLabel!==''&&this.baseStatisticNames.length){displayStatisticName=`${tr.v.DELTA}${this.displayStatisticName}`;}
+if(this.referenceDisplayLabel===''&&this.viewState.referenceDisplayLabel!==''&&this.baseStatisticNames.length){const deltaIndex=displayStatisticName.indexOf(tr.v.DELTA);if(deltaIndex>=0){displayStatisticName=displayStatisticName.slice(deltaIndex+1);}else if(!this.baseStatisticNames.includes(displayStatisticName)){displayStatisticName='avg';}}
+await this.viewState.update({searchQuery:this.searchQuery,showAll:this.showAll,referenceDisplayLabel:this.referenceDisplayLabel,displayStatisticName,});if(this.referenceDisplayLabel&&this.statisticNames.length===this.baseStatisticNames.length){this.statisticNames=this.baseStatisticNames.concat(tr.v.Histogram.getDeltaStatisticsNames(this.baseStatisticNames));}else if(!this.referenceDisplayLabel&&this.statisticNames.length>this.baseStatisticNames.length){this.statisticNames=this.baseStatisticNames;}
+for(const mark of marks)mark.end();},onViewStateUpdate_(event){this.isInOnViewStateUpdate_=true;if(event.delta.searchQuery){this.searchQuery=this.viewState.searchQuery;}
+if(event.delta.showAll)this.showAll=this.viewState.showAll;if(event.delta.displayStatisticName){this.displayStatisticName=this.viewState.displayStatisticName;}
+if(event.delta.referenceDisplayLabel){this.referenceDisplayLabel=this.viewState.referenceDisplayLabel;}
+if(event.delta.groupings){this.$.picker.currentGroupKeys=this.viewState.groupings.map(g=>g.key);}
+if(event.delta.tableRowStates){for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){row.addUpdateListener(this.rowListener_);}
+const anyShowing=this.anyOverviewCharts_;this.$.hide_overview.style.display=anyShowing?'inline':'none';this.$.show_overview.style.display=anyShowing?'none':'inline';}
+this.isInOnViewStateUpdate_=false;this.onUserChange_();},onRowViewStateUpdate_(event){if(event.delta.isOverviewed){const anyShowing=event.delta.isOverviewed.current||this.anyOverviewCharts_;this.$.hide_overview.style.display=anyShowing?'inline':'none';this.$.show_overview.style.display=anyShowing?'none':'inline';}
+if(event.delta.subRows){for(const subRow of event.delta.subRows.previous){subRow.removeUpdateListener(this.rowListener_);}
+for(const subRow of event.delta.subRows.current){subRow.addUpdateListener(this.rowListener_);}}},onGroupsChanged_(){if(this.$.picker.currentGroups.length===0&&this.$.picker.possibleGroups.length>0){this.$.picker.currentGroupKeys=[this.$.picker.possibleGroups[0].key];}
+this.viewState.groupings=this.$.picker.currentGroups;},set showAllEnabled(enable){if(!enable)this.$.show_all.checked=true;this.$.show_all.disabled=!enable;},set possibleGroupings(groupings){this.$.picker.possibleGroups=groupings;this.$.picker.style.display=(groupings.length<2)?'none':'block';this.onGroupsChanged_();},set displayLabels(labels){this.$.reference_display_label.style.display=(labels.length<2)?'none':'inline';while(this.$.reference_display_label.children.length>1){this.$.reference_display_label.removeChild(this.$.reference_display_label.lastChild);}
+for(const displayLabel of labels){const option=document.createElement('option');option.textContent=displayLabel;this.$.reference_display_label.appendChild(option);}
+if(labels.includes(this.viewState.referenceDisplayLabel)){this.referenceDisplayLabel=this.viewState.referenceDisplayLabel;}else{this.viewState.referenceDisplayLabel='';}},get baseStatisticNames(){return this.baseStatisticNames_;},set baseStatisticNames(names){this.baseStatisticNames_=names;this.statisticNames=names;},get statisticNames(){return Array.from(this.$.statistic.options).map(o=>o.value);},set statisticNames(names){this.$.statistic.style.display=(names.length<2)?'none':'inline';while(this.$.statistic.children.length){this.$.statistic.removeChild(this.$.statistic.lastChild);}
+for(const name of names){const option=document.createElement('option');option.textContent=name;this.$.statistic.appendChild(option);}
+if(names.includes(this.viewState.displayStatisticName)){this.displayStatisticName=this.viewState.displayStatisticName;this.$.statistic.value=this.displayStatisticName;}else{this.viewState.displayStatisticName=names[0]||'';}},get anyOverviewCharts_(){for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){if(row.isOverviewed)return true;}
+return false;},async toggleOverviewLineCharts_(){const showOverviews=!this.anyOverviewCharts_;const mark=tr.b.Timing.mark('histogram-set-controls',(showOverviews?'show':'hide')+'OverviewCharts');for(const row of tr.v.ui.HistogramSetTableRowState.walkAll(this.viewState.tableRowStates.values())){await row.update({isOverviewed:showOverviews});}
+this.$.hide_overview.style.display=showOverviews?'inline':'none';this.$.show_overview.style.display=showOverviews?'none':'inline';await tr.b.animationFrame();mark.end();},set helpHref(href){this.$.help.href=href;this.$.help.style.display='inline';},set feedbackHref(href){this.$.feedback.href=href;this.$.feedback.style.display='inline';},downloadCSV_(event){this.dispatchEvent(new tr.b.Event('download-csv'));}});return{};});'use strict';tr.exportTo('tr.v',function(){class HistogramSetHierarchy{constructor(name){this.name=name;this.description='';this.depth=0;this.subRows=[];this.columns=new Map();this.overviewDataRange_=undefined;this.mergeRelationshipsForColumn_=new Map();}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
 static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}
+static build(histogramArrayMap){const rootRows=[];HistogramSetHierarchy.buildInternal_(histogramArrayMap,[],rootRows);const histograms=new tr.v.HistogramSet();for(const row of HistogramSetHierarchy.walkAll(rootRows)){for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
+histograms.deduplicateDiagnostics();for(const row of HistogramSetHierarchy.walkAll(rootRows)){for(const[name,hist]of row.columns){if(!(hist instanceof tr.v.Histogram))continue;if(!row.mergeRelationshipsForColumn_.get(name))continue;hist.diagnostics.mergeRelationships(hist);}}
+for(const row of HistogramSetHierarchy.walkAll(rootRows)){if(row.subRows.length)continue;for(const hist of row.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;const mergedFrom=hist.diagnostics.get(tr.v.MERGED_FROM_DIAGNOSTIC_KEY);if(mergedFrom!==undefined){for(const other of mergedFrom){other.diagnostics.delete(tr.v.MERGED_TO_DIAGNOSTIC_KEY);}}}}
+for(const row of HistogramSetHierarchy.walkAll(rootRows)){row.maybeRebin_();}
+return rootRows;}
 maybeRebin_(){const dataRange=new tr.b.math.Range();for(const hist of this.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;if(hist.allBins.length>1)return;if(hist.numValues===0)continue;dataRange.addValue(hist.min);dataRange.addValue(hist.max);}
 dataRange.addValue(tr.b.math.lesserWholeNumber(dataRange.min));dataRange.addValue(tr.b.math.greaterWholeNumber(dataRange.max));if(dataRange.min===dataRange.max)return;const boundaries=tr.v.HistogramBinBoundaries.createLinear(dataRange.min,dataRange.max,tr.v.DEFAULT_REBINNED_COUNT);for(const[name,hist]of this.columns){if(!(hist instanceof tr.v.Histogram))continue;this.columns.set(name,hist.rebin(boundaries));}}
-static mergeHistogramDownHierarchy_(histogram,hierarchy,columnName){let groupingPath=undefined;for(let row of hierarchy){if(groupingPath!==undefined){groupingPath.push(row.name);}else if(row.name===histogram.name){groupingPath=[];}
+static mergeHistogramDownHierarchy_(histogram,hierarchy,columnName){let groupingPath=undefined;for(const row of hierarchy){if(groupingPath!==undefined){groupingPath.push(row.name);}else if(row.name===histogram.name){groupingPath=[];}
 if(!row.description){row.description=histogram.description;}
-if(row.columns.get(columnName)===undefined){let clone=histogram.clone();if(groupingPath!==undefined){new tr.v.d.GroupingPath(groupingPath).addToHistogram(clone);}
-row.columns.set(columnName,clone);row.doMergeRelationshipsForColumn_.set(columnName,true);continue;}
-if(!(row.columns.get(columnName)instanceof tr.v.Histogram))continue;if(!row.columns.get(columnName).canAddHistogram(histogram)){row.columns.set(columnName,tr.v.ui.UNMERGEABLE);continue;}
-let merged=row.columns.get(columnName);if(merged.name!==histogram.name){row.doMergeRelationshipsForColumn_.set(name,false);}
-merged.addHistogram(histogram);}}
-static buildInternal_(histogramArrayMap,hierarchy,rootRows){for(let[name,histograms]of histogramArrayMap){if(histograms instanceof Array){for(let histogram of histograms){HistogramSetTableRow.mergeHistogramDownHierarchy_(histogram,hierarchy,name);}}else if(histograms instanceof Map){let row=new HistogramSetTableRow(name);row.depth=hierarchy.length;hierarchy.push(row);HistogramSetTableRow.buildInternal_(histograms,hierarchy,rootRows);hierarchy.pop();if(hierarchy.length===0){rootRows.push(row);}else{hierarchy[hierarchy.length-1].subRows.push(row);}}}}
-get nameCell(){if(this.nameCell_===undefined){this.nameCell_=document.createElement('tr-v-ui-histogram-set-table-name-cell');this.nameCell_.row=this;this.nameCell_.constrainWidth=this.constrainNameColumnWidth_;}
+const existing=row.columns.get(columnName);if(existing===undefined){const clone=histogram.clone();if(groupingPath!==undefined){new tr.v.d.GroupingPath(groupingPath).addToHistogram(clone);}
+row.columns.set(columnName,clone);row.mergeRelationshipsForColumn_.set(columnName,true);continue;}
+if(existing instanceof tr.v.HistogramSet){existing.addHistogram(histogram);continue;}
+if(!existing.canAddHistogram(histogram)){const unmergeableHistograms=new tr.v.HistogramSet([histogram]);const mergedFrom=existing.diagnostics.get(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY);if(mergedFrom!==undefined){for(const origHist of mergedFrom){unmergeableHistograms.addHistogram(origHist);}}
+row.columns.set(columnName,unmergeableHistograms);continue;}
+if(existing.name!==histogram.name){row.mergeRelationshipsForColumn_.set(name,false);}
+existing.addHistogram(histogram);}}
+static buildInternal_(histogramArrayMap,hierarchy,rootRows){for(const[name,histograms]of histogramArrayMap){if(histograms instanceof Array){for(const histogram of histograms){HistogramSetHierarchy.mergeHistogramDownHierarchy_(histogram,hierarchy,name);}}else if(histograms instanceof Map){const row=new HistogramSetHierarchy(name);row.depth=hierarchy.length;hierarchy.push(row);HistogramSetHierarchy.buildInternal_(histograms,hierarchy,rootRows);hierarchy.pop();if(hierarchy.length===0){rootRows.push(row);}else{const parentRow=hierarchy[hierarchy.length-1];parentRow.subRows.push(row);}}}}
+static filter(rows,histograms){const results=[];for(const row of rows){let filteredSubRows=[];if(row.subRows.length>0){filteredSubRows=HistogramSetHierarchy.filter(row.subRows,histograms);if(filteredSubRows.length===0)continue;}else{let found=false;for(const testHist of row.columns.values()){if(testHist instanceof tr.v.HistogramSet){for(const origHist of testHist){if(histograms.lookupHistogram(origHist.guid)!==undefined){found=true;break;}}
+if(found)break;continue;}
+if(!(testHist instanceof tr.v.Histogram)){throw new Error('Cells can only contain Histogram or HistogramSet');}
+if(histograms.lookupHistogram(testHist.guid)!==undefined){found=true;break;}
+const mergedFrom=testHist.diagnostics.get(tr.v.d.MERGED_FROM_DIAGNOSTIC_KEY);if(mergedFrom!==undefined){for(const origHist of mergedFrom){if(histograms.lookupHistogram(origHist.guid)!==undefined){found=true;break;}}}
+if(found)break;}
+if(!found)continue;}
+const clone=new HistogramSetHierarchy(row.name);clone.description=row.description;clone.depth=row.depth;clone.subRows=filteredSubRows;clone.columns=row.columns;clone.overviewDataRange_=row.overviewDataRange_;results.push(clone);}
+return results;}
+get overviewDataRange(){if(this.overviewDataRange_===undefined){this.overviewDataRange_=new tr.b.math.Range();for(const[displayLabel,hist]of this.columns){if(hist instanceof tr.v.Histogram&&hist.average!==undefined){this.overviewDataRange_.addValue(hist.average);}
+for(const subRow of this.subRows){const subHist=subRow.columns.get(displayLabel);if(!(subHist instanceof tr.v.Histogram))continue;if(subHist.average===undefined)continue;this.overviewDataRange_.addValue(subHist.average);}}}
+return this.overviewDataRange_;}}
+return{HistogramSetHierarchy,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-table-cell',created(){this.viewState_=undefined;this.rootListener_=this.onRootStateUpdate_.bind(this);this.row_=undefined;this.displayLabel_='';this.histogram_=undefined;this.histogramSpan_=undefined;this.overviewChart_=undefined;},ready(){this.addEventListener('click',this.onClick_.bind(this));},attached(){if(this.row){this.row.rootViewState.addUpdateListener(this.rootListener_);}},detached(){this.row.rootViewState.removeUpdateListener(this.rootListener_);},build(row,displayLabel,viewState){this.row_=row;this.displayLabel_=displayLabel;this.viewState_=viewState;this.histogram_=this.row.columns.get(displayLabel);if(this.viewState){this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));}
+this.row.viewState.addUpdateListener(this.onRowStateUpdate_.bind(this));if(this.isAttached){this.row.rootViewState.addUpdateListener(this.rootListener_);}
+this.updateContents_();},get viewState(){return this.viewState_;},get row(){return this.row_;},get histogram(){return this.histogram_;},get referenceHistogram(){const referenceDisplayLabel=this.row.rootViewState.referenceDisplayLabel;if(!referenceDisplayLabel)return undefined;if(referenceDisplayLabel===this.displayLabel_)return undefined;return this.row.columns.get(referenceDisplayLabel);},get isHistogramOpen(){return(this.histogramSpan_!==undefined)&&(this.$.histogram.style.display==='block');},get brushedBinRange(){if(!this.isHistogramOpen)return new tr.b.math.Range();return this.histogramSpan_.brushedBinRange;},set brushedBinRange(r){if(this.histogramSpan_===undefined)return;this.histogramSpan_.brushedBinRange=r;},get mergeSampleDiagnostics(){if(!this.isHistogramOpen)return false;return this.histogramSpan_.mergeSampleDiagnostics;},set mergeSampleDiagnostics(m){if(this.histogramSpan_===undefined)return;this.histogramSpan_.mergeSampleDiagnostics=m;},set isHistogramOpen(open){if(!(this.histogram instanceof tr.v.Histogram)||(this.histogram.numValues===0)){return;}
+this.$.scalar.style.display=open?'none':'flex';this.$.open_histogram.style.display=open?'none':'block';this.$.close_histogram.style.display=open?'block':'none';this.$.histogram.style.display=open?'block':'none';if(open&&this.histogramSpan_===undefined){this.histogramSpan_=document.createElement('tr-v-ui-histogram-span');this.$.histogram.appendChild(this.histogramSpan_);this.histogramSpan_.viewState=this.viewState;this.histogramSpan_.referenceHistogram=this.referenceHistogram;this.histogramSpan_.histogram=this.histogram;}
+this.viewState.isOpen=open;},onViewStateUpdate_(event){if(event.delta.isOpen){this.isHistogramOpen=this.viewState.isOpen;}},onRowStateUpdate_(event){if(event.delta.isOverviewed===undefined)return;if(this.row.viewState.isOverviewed){this.showOverview();}else{this.hideOverview();}},onRootStateUpdate_(event){if(event.delta.displayStatisticName||event.delta.referenceDisplayLabel){this.updateContents_();}},onClick_(event){event.stopPropagation();},openHistogram_(){this.isHistogramOpen=true;tr.b.Timing.instant('histogram-set-table-cell','open');},closeHistogram_(){this.isHistogramOpen=false;tr.b.Timing.instant('histogram-set-table-cell','close');},updateContents_(){const isOpen=this.isHistogramOpen;this.$.empty.style.display='none';this.$.unmergeable.style.display='none';this.$.scalar.style.display='none';this.$.histogram.style.display='none';this.$.close_histogram.style.display='none';this.$.open_histogram.style.visibility='hidden';if(!this.histogram){this.$.missing.style.display='block';return;}
+this.$.missing.style.display='none';if(this.histogram instanceof tr.v.HistogramSet){this.$.unmergeable.style.display='block';return;}
+if(!(this.histogram instanceof tr.v.Histogram)){throw new Error('Invalid Histogram: '+this.histogram);}
+if(this.histogram.numValues===0){this.$.empty.style.display='block';return;}
+this.$.open_histogram.style.display='block';this.$.open_histogram.style.visibility='visible';this.$.scalar.style.display='flex';const referenceHistogram=this.referenceHistogram;if(this.histogramSpan_){this.histogramSpan_.referenceHistogram=referenceHistogram;}
+if((referenceHistogram instanceof tr.v.Histogram)&&(this.histogram.unit===referenceHistogram.unit)&&(referenceHistogram.numValues>0)){this.$.scalar.significance=this.histogram.getDifferenceSignificance(referenceHistogram);}
+const statName=this.histogram.getAvailableStatisticName(this.row.rootViewState.displayStatisticName,referenceHistogram);const statisticScalar=this.histogram.getStatisticScalar(statName,referenceHistogram);this.$.scalar.setValueAndUnit(statisticScalar.value,statisticScalar.unit);this.isHistogramOpen=isOpen;},showOverview(){this.$.overview_container.style.display='block';if(this.overviewChart_!==undefined)return;const data=[];let unitString;for(const subRow of this.row.subRows){const subHist=subRow.columns.get(this.displayLabel_);if(!(subHist instanceof tr.v.Histogram))continue;data.push({x:subRow.name,y:subHist.average});unitString=subHist.unit.unitString;}
+if(data.length<2)return;this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.hideLegend=true;this.overviewChart_.yAxisLabel=unitString;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;},hideOverview(){this.$.overview_container.style.display='none';}});return{};});'use strict';tr.exportTo('tr.v.ui',function(){const NAME_COLUMN_WIDTH_PX=300;Polymer({is:'tr-v-ui-histogram-set-table-name-cell',created(){this.row_=undefined;this.overviewChart_=undefined;this.cellListener_=this.onCellStateUpdate_.bind(this);this.rootListener_=this.onRootStateUpdate_.bind(this);},attached(){if(this.row){this.row.rootViewState.addUpdateListener(this.rootListener_);}},detached(){this.row.rootViewState.removeUpdateListener(this.rootListener_);},get row(){return this.row_;},build(row){if(this.row_!==undefined){throw new Error('row must be set exactly once.');}
+this.row_=row;this.row.viewState.addUpdateListener(this.onRowStateUpdate_.bind(this));this.constrainWidth=this.row.rootViewState.constrainNameColumn;if(this.isAttached){this.row.rootViewState.addUpdateListener(this.rootListener_);}
+for(const cellState of this.row.viewState.cells.values()){cellState.addUpdateListener(this.cellListener_);}
+Polymer.dom(this.$.name).textContent=this.row.name;this.title=this.row.name;if(this.row.description){this.title+='\n'+this.row.description;}
+if(this.row.overviewDataRange.isEmpty||this.row.overviewDataRange.min===this.row.overviewDataRange.max){this.$.show_overview.style.display='none';}
+let histogramCount=0;for(const cell of this.row.columns.values()){if(cell instanceof tr.v.Histogram&&cell.numValues>0){++histogramCount;}}
+if(histogramCount<=1){this.$.open_histograms.style.display='none';}},set constrainWidth(constrain){this.$.name.style.maxWidth=constrain?(this.nameWidthPx+'px'):'none';},get nameWidthPx(){return NAME_COLUMN_WIDTH_PX-(16*this.row.depth);},get isOverflowing(){return this.$.name.style.maxWidth!=='none'&&this.$.name.getBoundingClientRect().width===this.nameWidthPx;},get isOverviewed(){return this.$.overview_container.style.display==='block';},set isOverviewed(isOverviewed){if(isOverviewed===this.isOverviewed)return;if(isOverviewed){this.showOverview_();}else{this.hideOverview_();}},hideOverview_(opt_event){this.$.overview_container.style.display='none';this.$.hide_overview.style.display='none';this.$.show_overview.style.display='block';if(opt_event!==undefined){opt_event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','hideOverview');this.row.viewState.isOverviewed=this.isOverviewed;}},showOverview_(opt_event){this.$.overview_container.style.display='block';if(this.overviewChart_===undefined){const data=[];let unitString=undefined;for(const[displayLabel,hist]of this.row.columns){data.push({x:displayLabel,y:hist.average});unitString=hist.unit.unitString;}
+if(data.length<2){return;}
+this.overviewChart_=new tr.ui.b.NameLineChart();this.$.overview_container.appendChild(this.overviewChart_);this.overviewChart_.hideLegend=true;this.overviewChart_.yAxisLabel=unitString;this.overviewChart_.overrideDataRange=this.row.overviewDataRange;this.overviewChart_.data=data;}
+this.$.hide_overview.style.display='block';this.$.show_overview.style.display='none';if(opt_event!==undefined){opt_event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','showOverview');this.row.viewState.isOverviewed=this.isOverviewed;}},openHistograms_(event){event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','openHistograms');for(const cell of this.row.cells.values()){cell.isHistogramOpen=true;}
+this.$.close_histograms.style.display='block';this.$.open_histograms.style.display='none';},closeHistograms_(event){event.stopPropagation();tr.b.Timing.instant('histogram-set-table-name-cell','closeHistograms');for(const cell of this.row.cells.values()){cell.isHistogramOpen=false;}
+this.$.open_histograms.style.display='block';this.$.close_histograms.style.display='none';},onRootStateUpdate_(event){if(event.delta.constrainNameColumn){this.constrainWidth=this.row.rootViewState.constrainNameColumn;}},onRowStateUpdate_(event){if(event.delta.isOverviewed){this.isOverviewed=this.row.viewState.isOverviewed;}},onCellStateUpdate_(event){if(!event.delta.isOpen)return;let cellCount=0;let openCellCount=0;for(const cell of this.row.cells.values()){if(!(cell.histogram instanceof tr.v.Histogram)||(cell.histogram.numValues===0)){continue;}
+++cellCount;if(cell.isHistogramOpen)++openCellCount;}
+if(cellCount<=1)return;const mostlyOpen=openCellCount>(cellCount/2);this.$.open_histograms.style.display=mostlyOpen?'none':'block';this.$.close_histograms.style.display=mostlyOpen?'block':'none';}});return{NAME_COLUMN_WIDTH_PX,};});'use strict';tr.exportTo('tr.v.ui',function(){class HistogramSetTableRow{constructor(hierarchy,baseTable,rootViewState){this.hierarchy_=hierarchy;this.baseTable_=baseTable;this.rootViewState_=rootViewState;this.viewState_=new tr.v.ui.HistogramSetTableRowState();this.viewState_.addUpdateListener(this.onViewStateUpdate_.bind(this));this.nameCell_=undefined;this.cells_=new Map();this.subRows_=[];for(const subHierarchy of hierarchy.subRows){const subRow=new HistogramSetTableRow(subHierarchy,baseTable,rootViewState);this.subRows_.push(subRow);this.viewState.subRows.set(subRow.name,subRow.viewState);}
+for(const columnName of this.columns.keys()){this.viewState.cells.set(columnName,new tr.v.ui.HistogramSetTableCellState());}}
+get name(){return this.hierarchy_.name;}
+get depth(){return this.hierarchy_.depth;}
+get description(){return this.hierarchy_.description;}
+get columns(){return this.hierarchy_.columns;}
+get overviewDataRange(){return this.hierarchy_.overviewDataRange;}
+get rootViewState(){return this.rootViewState_;}
+get cells(){return this.cells_;}
+get subRows(){return this.subRows_;}
+get viewState(){return this.viewState_;}*walk(){yield this;for(const row of this.subRows)yield*row.walk();}
+static*walkAll(rootRows){for(const rootRow of rootRows)yield*rootRow.walk();}
+get nameCell(){if(this.nameCell_===undefined){this.nameCell_=document.createElement('tr-v-ui-histogram-set-table-name-cell');this.nameCell_.build(this);}
 return this.nameCell_;}
-set constrainNameColumnWidth(constrain){for(const row of this.walk()){row.constrainNameColumnWidth_=constrain;if(row.nameCell_!==undefined){row.nameCell_.constrainWidth=constrain;}}}
-get isNameCellOverflowing(){for(const row of this.walk()){if(row.nameCell.isOverflowing)return true;}
-return false;}
-get displayStatistic(){return this.displayStatistic_;}
-set displayStatistic(statName){for(const row of this.walk()){row.displayStatistic_=statName;for(let[displayLabel,cell]of row.cells){cell.displayStatistic=statName;}}}
-buildCell(displayLabel,referenceDisplayLabel){let cell=document.createElement('tr-v-ui-histogram-set-table-cell');cell.row=this;cell.histogram=this.columns.get(displayLabel);cell.displayStatistic=this.displayStatistic;if(referenceDisplayLabel&&referenceDisplayLabel!==displayLabel){cell.referenceHistogram=this.columns.get(referenceDisplayLabel);}
-this.cells.set(displayLabel,cell);return cell;}
-get overviewDataRange(){if(this.overviewDataRange_===undefined){this.overviewDataRange_=new tr.b.math.Range();for(let[displayLabel,hist]of this.columns){if(hist.average!==undefined){this.overviewDataRange_.addValue(hist.average);}
-for(let subRow of this.subRows){let subHist=subRow.columns.get(displayLabel);if(!(subHist instanceof tr.v.Histogram))continue;if(subHist.average===undefined)continue;this.overviewDataRange_.addValue(subHist.average);}}}
-return this.overviewDataRange_;}
-getLeafHistograms(histograms){for(const row of this.walk()){if(row.subRows.length)return;for(const hist of this.columns.values()){histograms.addHistogram(hist);}}}
+getCell(columnName){if(this.cells.has(columnName))return this.cells.get(columnName);const cell=document.createElement('tr-v-ui-histogram-set-table-cell');cell.build(this,columnName,this.viewState.cells.get(columnName));this.cells.set(columnName,cell);return cell;}
 compareNames(other){return this.name.localeCompare(other.name);}
-compareCells(other,displayLabel,referenceDisplayLabel){let cellA=this.columns.get(displayLabel);let cellB=other.columns.get(displayLabel);if(!(cellA instanceof tr.v.Histogram)||!(cellB instanceof tr.v.Histogram)){return undefined;}
+compareCells(other,displayLabel,referenceDisplayLabel){const cellA=this.columns.get(displayLabel);const cellB=other.columns.get(displayLabel);if(!(cellA instanceof tr.v.Histogram)||!(cellB instanceof tr.v.Histogram)){return undefined;}
 let referenceCellA;let referenceCellB;if(referenceDisplayLabel&&referenceDisplayLabel!==displayLabel){referenceCellA=this.columns.get(referenceDisplayLabel);referenceCellB=other.columns.get(referenceDisplayLabel);}
-const statisticA=cellA.getAvailableStatisticName(this.displayStatistic,referenceCellA);const statisticB=cellB.getAvailableStatisticName(this.displayStatistic,referenceCellB);const valueA=cellA.getStatisticScalar(statisticA,referenceCellA).value;const valueB=cellB.getStatisticScalar(statisticB,referenceCellB).value;return valueA-valueB;}
-getExpansionStates(table){let states={expanded:table.getExpandedForTableRow(this),cells:new Map(),subRows:new Map(),};for(let[displayLabel,cell]of this.cells){if(cell.isHistogramOpen){states.cells.set(displayLabel,true);}}
-if(states.expanded){for(let i=0;i<this.subRows.length;++i){states.subRows.set(i,this.subRows[i].getExpansionStates(table));}}
-return states;}
-setExpansionStates(states,table){if(states.expanded){if(this.subRows.length){table.setExpandedForTableRow(this,true);for(let[index,subStates]of states.subRows){this.subRows[index].setExpansionStates(subStates,table);}}}
-for(let[displayLabel,isHistogramOpen]of states.cells){let cell=this.cells.get(displayLabel);if(cell){cell.isHistogramOpen=isHistogramOpen;}}}}
-return{HistogramSetTableRow,};});'use strict';tr.exportTo('tr.v.ui',function(){let getDisplayLabel=tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL.callback;const DEFAULT_POSSIBLE_GROUPS=[];DEFAULT_POSSIBLE_GROUPS.push(new tr.v.HistogramGrouping(tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME.key,h=>h.shortName||h.name));for(var group of Object.values(tr.v.HistogramSet.GROUPINGS)){if(group!==tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL&&group!==tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME){DEFAULT_POSSIBLE_GROUPS.push(group);}}
-const SHOW_ALL_SETTINGS_KEY='tr-v-ui-histogram-set-table-show-all';const CONSTRAIN_NAME_COLUMN_WIDTH_KEY='tr-v-ui-histogram-set-table-constrain-name-column-width';const DISPLAY_STATISTIC_KEY='tr-v-ui-histogram-set-table-statistic';const REFERENCE_DISPLAY_LABEL_KEY='tr-v-ui-histogram-set-table-reference-display-label';const UNMERGEABLE='(unmergeable)';const MIDLINE_HORIZONTAL_ELLIPSIS=String.fromCharCode(0x22ef);function escapeRegExp(str){return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,'\\$&');}
-Polymer({is:'tr-v-ui-histogram-set-table',get tabLabel(){return'Table';},created(){this.histograms_=undefined;this.sourceHistograms_=undefined;this.unfilteredRows_=undefined;this.rows_=undefined;this.columns_=undefined;this.updatingContents_=false;this.displayLabels_=undefined;this.displayStatistic_='avg';this.statNames_=undefined;this.referenceDisplayLabel_=undefined;this.constrainNameColumnWidth_=true;this.nameColumnTitle_=undefined;this.isDisplayed=false;},ready(){this.$.table.zebra=true;this.addEventListener('name-cell-overflow',this.onNameCellOverflow_.bind(this));this.addEventListener('requestSelectionChange',this.onRequestSelectionChange_.bind(this));this.$.show_all.checked=tr.b.Settings.get(SHOW_ALL_SETTINGS_KEY,false);this.$.picker.settingsKey='tr-v-ui-histogram-set-table-groupby-picker';this.$.picker.possibleGroups=DEFAULT_POSSIBLE_GROUPS.slice();if(this.$.picker.currentGroupKeys.length===0){this.$.picker.currentGroupKeys=[tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME.key,tr.v.HistogramSet.GROUPINGS.STORY_NAME.key];}
-this.$.picker.addEventListener('current-groups-changed',this.currentGroupsChanged_.bind(this));},set groupingKeys(keys){this.$.picker.currentGroupKeys=keys;},get groupingKeys(){return this.$.picker.currentGroupKeys;},get possibleGroupingKeys(){return this.$.picker.possibleGroups.map(g=>g.key);},currentGroupsChanged_(){if(this.updatingContents_)return;if(this.$.picker.currentGroups.length===0&&this.possibleGroupingKeys.length>0){this.$.picker.currentGroupKeys=[this.$.picker.possibleGroups[0].key];}
-this.unfilteredRows_=tr.v.ui.HistogramSetTableRow.build(this.groupedHistograms);let expansionStates=undefined;if(this.rows_)expansionStates=this.getExpansionStates_();this.updateContents_();if(expansionStates)this.setExpansionStates_(expansionStates);},onShowAllChange_(){if(this.updatingContents_)return;tr.b.Settings.set(SHOW_ALL_SETTINGS_KEY,this.$.show_all.checked);let expansionStates=this.getExpansionStates_();this.updateContents_();this.setExpansionStates_(expansionStates);},getExpansionStates_(){let states=new Map();for(let i=0;i<this.rows_.length;++i){states.set(i,this.rows_[i].getExpansionStates(this.$.table));}
-return states;},setExpansionStates_(states){for(let i=0;i<this.rows_.length;++i){let rowStates=states.get(i);if(rowStates===undefined){continue;}
-this.rows_[i].setExpansionStates(rowStates,this.$.table);}},showOverview_(){let table=this.$.table;function recurse(row){row.nameCell.showOverview_();if(table.getExpandedForTableRow(row)){for(let subrow of row.subRows){recurse(subrow);}}}
-for(let i=0;i<this.rows_.length;++i){recurse(this.rows_[i]);}
-this.$.hide_overview.style.display='inline';this.$.show_overview.style.display='none';},hideOverview_(){let table=this.$.table;function recurse(row){row.nameCell.hideOverview_();if(table.getExpandedForTableRow(row)){for(let subrow of row.subRows){recurse(subrow);}}}
-for(let i=0;i<this.rows_.length;++i){recurse(this.rows_[i]);}
-this.$.hide_overview.style.display='none';this.$.show_overview.style.display='inline';},onSearch_(){this.updateContents_();},onRequestSelectionChange_(event){if(event.selection instanceof tr.model.EventSet)return;event.stopPropagation();let histogramNames=event.selection;histogramNames.sort();histogramNames=histogramNames.map(escapeRegExp);this.$.search.value='^('+histogramNames.join('|')+')$';this.$.show_all.checked=true;this.onShowAllChange_();this.$.search.focus();},set helpHref(href){this.$.help.href=href;this.$.help.style.display='inline';},get histograms(){return this.histograms_;},set histograms(histograms){this.histograms_=histograms;this.displayLabels_=undefined;this.statNames_=undefined;this.referenceDisplayLabel_=undefined;if(this.histograms_===undefined){this.unfilteredRows_=[];this.sourceHistograms_=new tr.v.HistogramSet();}else{this.updatingContents_=true;this.updateGroups_();this.updatingContents_=false;this.unfilteredRows_=tr.v.ui.HistogramSetTableRow.build(this.groupedHistograms);this.sourceHistograms_=this.histograms_.sourceHistograms;}
-this.maybeDisableShowAll_();this.updateContents_();},get referenceDisplayLabel(){return this.referenceDisplayLabel_;},set referenceDisplayLabel(reference){if(reference===this.referenceDisplayLabel)return;let prevReferenceDisplayLabel=this.referenceDisplayLabel;this.referenceDisplayLabel_=reference;if(this.updatingContents_)return;let select=this.$.reference_column_container.children[0];if(select){select.value=reference?reference:'Select a reference column';}
-this.$.table.selectedTableColumnIndex=this.referenceDisplayLabel?1+this.displayLabels.indexOf(this.referenceDisplayLabel):undefined;let expansionStates=this.getExpansionStates_();this.$.table.tableRows=this.rows_;this.setExpansionStates_(expansionStates);this.updateStatisticSelector_();if(prevReferenceDisplayLabel===''&&this.referenceDisplayLabel){this.displayStatistic=tr.v.DELTA+this.displayStatistic;}},get statNames(){if(this.statNames_===undefined){this.statNames_=new Set(['avg']);for(let hist of this.histograms){for(let statName of hist.statisticsNames){this.statNames_.add(statName);}}}
-return this.statNames_;},updateStatisticSelector_(){Polymer.dom(this.$.statistic_container).textContent='';let statNames=Array.from(this.statNames);if(this.referenceDisplayLabel){statNames.push.apply(statNames,tr.v.Histogram.getDeltaStatisticsNames(statNames));}
-if(statNames.indexOf(this.displayStatistic_)<0){this.displayStatistic_=statNames[0];}
-let options=[];for(let statName of statNames){options.push({value:statName,label:statName});}
-let selector=tr.ui.b.createSelector(this,'displayStatistic',DISPLAY_STATISTIC_KEY,this.displayStatistic,options);Polymer.dom(this.$.statistic_container).appendChild(selector);},get displayStatistic(){return this.displayStatistic_;},set displayStatistic(statName){if(statName===this.displayStatistic_)return;this.displayStatistic_=statName;let select=this.$.statistic_container.children[0];if(select&&select.value!==statName){select.value=statName;}
-if(this.rows_!==undefined){for(let row of this.rows_){row.displayStatistic=this.displayStatistic;}}
-let sortColumnIndex=this.$.table.sortColumnIndex;this.sortColumnIndex=undefined;this.$.table.rebuild();this.sortColumnIndex=sortColumnIndex;this.$.table.rebuild();},updateReferenceColumnSelector_(){Polymer.dom(this.$.reference_column_container).textContent='';if(this.displayLabels.length<2)return;let options=[{value:'',label:'Select a reference column'}];for(let displayLabel of this.displayLabels){options.push({value:displayLabel,label:displayLabel});}
-let selector=tr.ui.b.createSelector(this,'referenceDisplayLabel',REFERENCE_DISPLAY_LABEL_KEY,'',options);Polymer.dom(this.$.reference_column_container).appendChild(selector);},set sortColumnIndex(i){this.$.table.sortColumnIndex=i;},get sortColumnIndex(){return this.$.table.sortColumnIndex;},set sortDescending(d){this.$.table.sortDescending=d;},get sortDescending(){return this.$.table.sortDescending;},updateGroups_(){let groups=DEFAULT_POSSIBLE_GROUPS.filter(function(group){if(group.key===tr.v.HistogramSet.GROUPINGS.HISTOGRAM_NAME.key){return true;}
-let values=new Set();for(let hist of this.histograms_){hist=group.callback(hist);if(!hist)continue;values.add(hist);if(values.size>1)return true;}
-return false;},this);for(let storyGroupingKey of this.storyGroupingKeys){groups.push(new tr.v.HistogramGrouping('storyGroupingKey_'+storyGroupingKey,tr.v.d.TelemetryInfo.makeStoryGroupingKeyLabelGetter(storyGroupingKey),storyGroupingKey));}
-let groupingKeys=this.groupingKeys;if(groupingKeys.length===0&&groups.length>0){groupingKeys=[groups[0].key];}
-this.$.picker.possibleGroups=groups;this.$.picker.currentGroupKeys=groupingKeys;this.$.picker.style.display=(groups.length===1)?'none':'';},updateContents_(){if(this.updatingContents_)return;if(!this.histograms_||(this.histograms_.length===0)){this.$.container.style.display='';this.$.zero.style.display='';return;}
-this.updatingContents_=true;this.$.zero.style.display='none';this.$.container.style.display='flex';this.$.table.style.display='';this.$.container.style.maxHeight=(window.innerHeight-16)+'px';this.updateReferenceColumnSelector_();this.updateStatisticSelector_();this.rows_=tr.v.ui.HistogramSetTableRow.filter(this.unfilteredRows_,this.filteredHistograms);this.buildColumns_();this.$.table.tableColumns=this.columns_;this.$.table.tableRows=this.rows_;this.$.table.sortColumnIndex=0;this.$.table.rebuild();for(let row of this.rows_){row.constrainNameColumnWidth=this.constrainNameColumnWidth;}
-this.checkNameColumnOverflow_();for(let row of this.rows_){row.displayStatistic=this.displayStatistic;}
-this.$.table.selectedTableColumnIndex=this.referenceDisplayLabel?1+this.displayLabels.indexOf(this.referenceDisplayLabel):undefined;this.updatingContents_=false;},maybeDisableShowAll_(){let allHistogramsAreSource=!this.histograms||(this.histograms.length===this.sourceHistograms_.length);this.$.show_all.disabled=allHistogramsAreSource;if(this.$.show_all.disabled){this.$.show_all.checked=true;}},get storyGroupingKeys(){let keys=new Set();for(let value of this.histograms){let telemetry=tr.v.d.TelemetryInfo.getFromHistogram(value);if(!(telemetry instanceof tr.v.d.TelemetryInfo))continue;for(let[key,value]of telemetry.storyGroupingKeys){keys.add(key);}}
-return[...keys.values()].sort();},get filteredHistograms(){let histograms=this.$.show_all.checked?this.histograms:this.sourceHistograms_;if(this.$.search.value){let query=undefined;try{query=new RegExp(this.$.search.value);}catch(e){}
-if(query!==undefined){histograms=new tr.v.HistogramSet([...histograms].filter(hist=>hist.name.match(query)));}}
-return histograms;},get groupedHistograms(){let groupings=this.$.picker.currentGroups.slice();groupings.push(tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL);function canSkipGrouping(grouping,groupedHistograms){if(groupedHistograms.size>1)return false;if(grouping.key===groupings[0].key)return false;if(grouping.key===tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL.key){return false;}
+const statisticA=cellA.getAvailableStatisticName(this.rootViewState.displayStatisticName,referenceCellA);const statisticB=cellB.getAvailableStatisticName(this.rootViewState.displayStatisticName,referenceCellB);const valueA=cellA.getStatisticScalar(statisticA,referenceCellA).value;const valueB=cellB.getStatisticScalar(statisticB,referenceCellB).value;return valueA-valueB;}
+onViewStateUpdate_(event){if(event.delta.isExpanded){this.baseTable_.setExpandedForTableRow(this,this.viewState.isExpanded);}
+if(event.delta.subRows){throw new Error('HistogramSetTableRow.subRows must not be reassigned.');}
+if(event.delta.cells){for(const[displayLabel,cell]of this.cells){if(cell.viewState!==this.viewState.cells.get(displayLabel)){throw new Error('Only HistogramSetTableRow may update cells');}}}}
+async restoreState(vs){await this.viewState.update({isExpanded:vs.isExpanded,isOverviewed:vs.isOverviewed,});for(const[displayLabel,cell]of this.cells){const previousState=vs.cells.get(displayLabel);if(!previousState)continue;await cell.viewState.updateFromViewState(previousState);}
+for(const row of this.subRows){const previousState=vs.subRows.get(row.name);if(!previousState)continue;await row.restoreState(previousState);}}}
+return{HistogramSetTableRow,};});'use strict';tr.exportTo('tr.v.ui',function(){const MIDLINE_HORIZONTAL_ELLIPSIS=String.fromCharCode(0x22ef);function escapeRegExp(str){return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,'\\$&');}
+Polymer({is:'tr-v-ui-histogram-set-table',created(){this.viewState_=undefined;this.progress_=()=>Promise.resolve();this.nameColumnTitle_=undefined;this.displayLabels_=[];this.histograms_=undefined;this.sourceHistograms_=undefined;this.groupedHistograms_=undefined;this.hierarchies_=undefined;this.tableRows_=undefined;},ready(){this.$.table.zebra=true;this.addEventListener('sort-column-changed',this.onSortColumnChanged_.bind(this));this.addEventListener('requestSelectionChange',this.onRequestSelectionChange_.bind(this));this.addEventListener('row-expanded-changed',this.onRowExpandedChanged_.bind(this));},get viewState(){return this.viewState_;},set viewState(vs){if(this.viewState_){throw new Error('viewState must be set exactly once.');}
+this.viewState_=vs;this.viewState.addUpdateListener(this.onViewStateUpdate_.bind(this));},get histograms(){return this.histograms_;},async build(histograms,sourceHistograms,displayLabels,opt_progress){this.histograms_=histograms;this.sourceHistograms_=sourceHistograms;this.groupedHistograms_=undefined;this.displayLabels_=displayLabels;if(opt_progress!==undefined)this.progress_=opt_progress;if(histograms.length===0){throw new Error('histogram-set-table requires non-empty HistogramSet.');}
+await this.progress_('Building columns...');this.$.table.tableColumns=[{title:this.buildNameColumnTitle_(),value:row=>row.nameCell,cmp:(a,b)=>a.compareNames(b),}].concat(displayLabels.map(l=>this.buildColumn_(l)));tr.b.Timing.instant('histogram-set-table','columnCount',this.$.table.tableColumns.length);await this.updateContents_();this.fire('display-ready');this.progress_=()=>Promise.resolve();this.checkNameColumnOverflow_(tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows));},buildNameColumnTitle_(){this.nameColumnTitle_=document.createElement('span');this.nameColumnTitle_.style.display='inline-flex';const nameEl=document.createElement('span');nameEl.textContent='Name';this.nameColumnTitle_.appendChild(nameEl);const toggleWidthEl=document.createElement('span');toggleWidthEl.style.fontWeight='bold';toggleWidthEl.style.background='#bbb';toggleWidthEl.style.color='#333';toggleWidthEl.style.padding='0px 3px';toggleWidthEl.style.marginRight='8px';toggleWidthEl.style.display='none';toggleWidthEl.textContent=MIDLINE_HORIZONTAL_ELLIPSIS;toggleWidthEl.addEventListener('click',this.toggleNameColumnWidth_.bind(this));this.nameColumnTitle_.appendChild(toggleWidthEl);return this.nameColumnTitle_;},toggleNameColumnWidth_(opt_event){this.viewState.update({constrainNameColumn:!this.viewState.constrainNameColumn,});if(opt_event!==undefined){opt_event.stopPropagation();opt_event.preventDefault();tr.b.Timing.instant('histogram-set-table','nameColumn'+
+(this.viewState.constrainNameColumn?'Constrained':'Unconstrained'));}},buildColumn_(displayLabel){const title=document.createElement('span');title.textContent=displayLabel;title.style.whiteSpace='pre';return{title,value:row=>row.getCell(displayLabel),cmp:(rowA,rowB)=>rowA.compareCells(rowB,displayLabel),};},async updateContents_(){if(this.groupedHistograms_===undefined){await this.progress_('Grouping Histograms...');this.groupHistograms_();}
+if(this.hierarchies_===undefined){await this.progress_('Merging Histograms...');this.hierarchies_=tr.v.HistogramSetHierarchy.build(this.groupedHistograms_);this.tableRows_=undefined;}
+const tableRowsDirty=this.tableRows_===undefined;const previousRowStates=this.viewState.tableRowStates;if(tableRowsDirty){await this.progress_('Filtering rows...');let filteredHistograms=this.viewState.showAll?this.histograms:this.sourceHistograms_;if(this.viewState.searchQuery){let query=undefined;try{query=new RegExp(this.viewState.searchQuery);}catch(e){}
+if(query!==undefined){filteredHistograms=new tr.v.HistogramSet([...filteredHistograms].filter(hist=>hist.name.match(query)));}}
+const filteredHierarchies=tr.v.HistogramSetHierarchy.filter(this.hierarchies_,filteredHistograms);this.tableRows_=filteredHierarchies.map(hierarchy=>new tr.v.ui.HistogramSetTableRow(hierarchy,this.$.table,this.viewState));tr.b.Timing.instant('histogram-set-table','rootRowCount',this.tableRows_.length);const namesToRowStates=new Map();for(const row of this.tableRows_){namesToRowStates.set(row.name,row.viewState);}
+await this.viewState.update({tableRowStates:namesToRowStates});}
+await this.progress_('Configuring table...');this.nameColumnTitle_.children[1].style.filter=this.viewState.constrainNameColumn?'invert(100%)':'';const referenceDisplayLabelIndex=this.displayLabels_.indexOf(this.viewState.referenceDisplayLabel);this.$.table.selectedTableColumnIndex=(referenceDisplayLabelIndex<0)?undefined:(1+referenceDisplayLabelIndex);this.$.table.sortColumnIndex=this.viewState.sortColumnIndex;this.$.table.sortDescending=this.viewState.sortDescending;if(tableRowsDirty){await this.progress_('Building DOM...');this.$.table.tableRows=this.tableRows_;for(const row of this.tableRows_){const previousState=previousRowStates.get(row.name);if(!previousState)continue;await row.restoreState(previousState);}}
+this.$.table.rebuild();},async onRowExpandedChanged_(event){event.row.viewState.isExpanded=this.$.table.getExpandedForTableRow(event.row);tr.b.Timing.instant('histogram-set-table','row'+(event.row.viewState.isExpanded?'Expanded':'Collapsed'));if(this.nameColumnTitle_.children[1].style.display==='block')return;await tr.b.animationFrame();this.checkNameColumnOverflow_(event.row.subRows);},checkNameColumnOverflow_(rows){for(const row of rows){if(!row.nameCell.isOverflowing)continue;const[nameSpan,dots]=this.nameColumnTitle_.children;dots.style.display='block';const labelWidthPx=tr.v.ui.NAME_COLUMN_WIDTH_PX-
+dots.getBoundingClientRect().width;nameSpan.style.width=labelWidthPx+'px';return;}},groupHistograms_(){const groupings=this.viewState.groupings.slice();groupings.push(tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL);function canSkipGrouping(grouping,groupedHistograms){if(groupedHistograms.size>1)return false;if(grouping.key===groupings[0].key)return false;if(grouping.key===tr.v.HistogramSet.GROUPINGS.DISPLAY_LABEL.key){return false;}
 return true;}
-return this.histograms.groupHistogramsRecursively(groupings,canSkipGrouping);},get startTimesForDisplayLabels(){let startTimesForDisplayLabels={};for(let value of this.histograms){let displayLabel=getDisplayLabel(value);startTimesForDisplayLabels[displayLabel]=Math.min(startTimesForDisplayLabels[displayLabel]||0,tr.v.d.TelemetryInfo.getField(value,'benchmarkStart',new Date(0)).getTime());}
-return startTimesForDisplayLabels;},get displayLabels(){if(this.displayLabels_===undefined){let startTimesForDisplayLabels=this.startTimesForDisplayLabels;this.displayLabels_=Object.keys(startTimesForDisplayLabels);this.displayLabels_.sort(function(a,b){return startTimesForDisplayLabels[a]-startTimesForDisplayLabels[b];});}
-return this.displayLabels_;},buildColumn_(displayLabel){let title=displayLabel;if(displayLabel.indexOf('\n')>0){title=document.createElement('div');for(let line of displayLabel.split('\n')){let lineDiv=document.createElement('div');lineDiv.appendChild(document.createTextNode(line));title.appendChild(lineDiv);}}
-return{title:title,value:row=>row.buildCell(displayLabel,this.referenceDisplayLabel),cmp:(rowA,rowB)=>rowA.compareCells(rowB,displayLabel,this.referenceDisplayLabel),};},get nameColumnTitle(){if(this.nameColumnTitle_===undefined){this.nameColumnTitle_=document.createElement('span');this.nameColumnTitle_.style.display='inline-flex';let nameEl=document.createElement('span');nameEl.textContent='Name';this.nameColumnTitle_.appendChild(nameEl);let toggleWidthEl=document.createElement('span');toggleWidthEl.style.fontWeight='bold';toggleWidthEl.style.background='#bbb';toggleWidthEl.style.color='#333';toggleWidthEl.style.padding='0px 3px';toggleWidthEl.style.marginRight='8px';toggleWidthEl.style.display='none';toggleWidthEl.textContent=MIDLINE_HORIZONTAL_ELLIPSIS;toggleWidthEl.addEventListener('click',this.toggleNameColumnWidth_.bind(this));this.nameColumnTitle_.appendChild(toggleWidthEl);}
-return this.nameColumnTitle_;},onNameCellOverflow_(){this.nameColumnTitle.children[0].style.width='275px';this.nameColumnTitle.children[1].style.display='block';this.constrainNameColumnWidth=tr.b.Settings.get(CONSTRAIN_NAME_COLUMN_WIDTH_KEY,true);},checkNameColumnOverflow_(){if(this.nameColumnTitle_===undefined)return;this.nameColumnTitle.children[0].style.width='';this.nameColumnTitle.children[1].style.display='none';if(this.rows_===undefined)return;for(const row of this.rows_){if(row.isNameCellOverflowing){this.onNameCellOverflow_();return;}}},displayed(){this.isDisplayed=true;this.checkNameColumnOverflow_();},get constrainNameColumnWidth(){return this.constrainNameColumnWidth_;},set constrainNameColumnWidth(c){if(this.constrainNameColumnWidth!==!!c){this.toggleNameColumnWidth_();}},toggleNameColumnWidth_(opt_event){if(opt_event){opt_event.stopPropagation();opt_event.preventDefault();}
-this.constrainNameColumnWidth_=!this.constrainNameColumnWidth;tr.b.Settings.set(CONSTRAIN_NAME_COLUMN_WIDTH_KEY,this.constrainNameColumnWidth);for(let row of this.rows_){row.constrainNameColumnWidth=this.constrainNameColumnWidth;}
-this.nameColumnTitle.children[1].style.filter=this.constrainNameColumnWidth?'':'invert(100%)';},get leafHistograms(){let histograms=new tr.v.HistogramSet();for(let row of this.rows_){row.getLeafHistograms(histograms);}
-return histograms;},downloadCSV_(){let anchor=document.createElement('a');let path=window.location.pathname.split('/');let basename=path[path.length-1].split('.')[0]||'histograms';anchor.download=basename+'.csv';let csv=new tr.v.CSVBuilder(this.leafHistograms);csv.build();let blob=new window.Blob([csv.toString()],{type:'text/csv'});anchor.href=window.URL.createObjectURL(blob);anchor.click();},buildColumns_(){this.columns_=[{title:this.nameColumnTitle,value:row=>row.nameCell,cmp:(a,b)=>a.compareNames(b),}];for(let displayLabel of this.displayLabels){this.columns_.push(this.buildColumn_(displayLabel));}}});return{CONSTRAIN_NAME_COLUMN_WIDTH_KEY,DISPLAY_STATISTIC_KEY,MIDLINE_HORIZONTAL_ELLIPSIS,REFERENCE_DISPLAY_LABEL_KEY,SHOW_ALL_SETTINGS_KEY,UNMERGEABLE,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-view',ready(){this.brushingStateController=new tr.ui.NullBrushingStateController();},attached(){this.brushingStateController.parentController=tr.c.BrushingStateController.getControllerForElement(this.parentNode);},set helpHref(href){this.$.histograms.helpHref=href;},set histograms(histograms){this.$.histograms.histograms=histograms;},get histograms(){return this.$.histograms.histograms;},displayed(){this.$.histograms.displayed();},});return{};});'use strict';tr.exportTo('tr.ui',function(){Polymer({is:'tr-ui-sp-metrics-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready:function(){this.model_=undefined;this.rangeOfInterest_=undefined;this.metricLatenciesMs_=[];this.metrics_=[];tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(function(m){if(m.constructor.name==='sampleMetric')return;this.metrics_.push({label:m.constructor.name,value:m.constructor.name});},this);this.settingsKey_='metrics-side-panel-metric-name';this.currentMetricName_='responsivenessMetric';var metricSelector=tr.ui.b.createSelector(this,'currentMetricName_',this.settingsKey_,this.currentMetricName_,this.metrics_);Polymer.dom(this.$.top_left_controls).appendChild(metricSelector);metricSelector.addEventListener('change',this.onMetricChange_.bind(this));this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.recomputeButton_=tr.ui.b.createButton('Recompute',this.onRecompute_,this);Polymer.dom(this.$.top_left_controls).appendChild(this.recomputeButton_);},get metricLatencyMs(){return tr.b.math.Statistics.mean(this.metricLatenciesMs_);},onMetricChange_:function(){this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.metricLatenciesMs_=[];this.updateContents_();},onRecompute_:function(){this.updateContents_();},get textLabel(){return'Metrics';},supportsModel:function(m){if(!m){return{supported:false,reason:'No model available'};}
-return{supported:true};},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},get selection(){},set selection(_){},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){this.rangeOfInterest_=range;if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest){if((this.metricLatencyMs===undefined)||(this.metricLatencyMs<100)){this.updateContents_();}else{this.recomputeButton_.style.background='red';}}},updateContents_:function(){Polymer.dom(this.$.error).textContent='';this.$.results.style.display='none';if(!this.model_){Polymer.dom(this.$.error).textContent='Missing model';return;}
-var options={metrics:[this.currentMetricName_]};if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest&&this.rangeOfInterest&&!this.rangeOfInterest.isEmpty){options.rangeOfInterest=this.rangeOfInterest;}
-var startDate=new Date();try{var histograms=tr.metrics.runMetrics(this.model_,options);}catch(err){Polymer.dom(this.$.error).textContent=err.message;return;}
+this.groupedHistograms_=this.histograms.groupHistogramsRecursively(groupings,canSkipGrouping);this.hierarchies_=undefined;},async onViewStateUpdate_(event){if(this.histograms_===undefined)return;if(event.delta.groupings!==undefined){this.groupedHistograms_=undefined;}
+if(event.delta.searchQuery!==undefined||event.delta.showAll!==undefined){this.tableRows_=undefined;}
+if(event.delta.displayStatistic!==undefined&&this.$.table.sortColumnIndex>0){this.$.table.sortColumnIndex=undefined;}
+if(event.delta.referenceDisplayLabel!==undefined||event.delta.displayStatisticName!==undefined){this.$.table.tableRows=this.$.table.tableRows;}
+if(event.delta.tableRowStates){if(this.tableRows_.length!==this.viewState.tableRowStates.size){throw new Error('Only histogram-set-table may update tableRowStates');}
+for(const row of this.tableRows_){if(this.viewState.tableRowStates.get(row.name)!==row.viewState){throw new Error('Only histogram-set-table may update tableRowStates');}}}
+await this.updateContents_();},onSortColumnChanged_(event){tr.b.Timing.instant('histogram-set-table','sortColumn');this.viewState.update({sortColumnIndex:event.sortColumnIndex,sortDescending:event.sortDescending,});},onRequestSelectionChange_(event){if(event.selection instanceof tr.model.EventSet)return;event.stopPropagation();tr.b.Timing.instant('histogram-set-table','selectHistogramNames');let histogramNames=event.selection;histogramNames.sort();histogramNames=histogramNames.map(escapeRegExp).join('|');this.viewState.update({showAll:true,searchQuery:`^(${histogramNames})$`,});},get leafHistograms(){const histograms=new tr.v.HistogramSet();for(const row of
+tr.v.ui.HistogramSetTableRow.walkAll(this.$.table.tableRows)){if(row.subRows.length)continue;for(const hist of this.columns.values()){if(!(hist instanceof tr.v.Histogram))continue;histograms.addHistogram(hist);}}
+return histograms;}});return{MIDLINE_HORIZONTAL_ELLIPSIS,};});'use strict';tr.exportTo('tr.v.ui',function(){Polymer({is:'tr-v-ui-histogram-set-view',created(){this.brushingStateController_=new tr.ui.NullBrushingStateController();this.viewState_=new tr.v.ui.HistogramSetViewState();},ready(){this.$.table.viewState=this.viewState;this.$.controls.viewState=this.viewState;this.$.controls.addEventListener('download-csv',this.downloadCSV_.bind(this));},attached(){this.brushingStateController.parentController=tr.c.BrushingStateController.getControllerForElement(this.parentNode);},get brushingStateController(){return this.brushingStateController_;},get viewState(){return this.viewState_;},set helpHref(href){this.$.controls.helpHref=href;},set feedbackHref(href){this.$.controls.feedbackHref=href;},get histograms(){return this.$.table.histograms;},async build(histograms,opt_progress){const progress=opt_progress||(()=>Promise.resolve());if(histograms===undefined||histograms.length===0){this.$.container.style.display='none';this.$.zero.style.display='block';this.style.display='block';return;}
+this.$.zero.style.display='none';this.$.container.style.display='block';this.$.container.style.maxHeight=(window.innerHeight-16)+'px';const buildMark=tr.b.Timing.mark('histogram-set-view','build');await progress('Finding important Histograms...');const sourceHistogramsMark=tr.b.Timing.mark('histogram-set-view','sourceHistograms');const sourceHistograms=histograms.sourceHistograms;sourceHistogramsMark.end();this.$.controls.showAllEnabled=(sourceHistograms.length!==histograms.length);await progress('Collecting parameters...');const collectParametersMark=tr.b.Timing.mark('histogram-set-view','collectParameters');const parameterCollector=new tr.v.HistogramParameterCollector();parameterCollector.process(histograms);this.$.controls.baseStatisticNames=parameterCollector.statisticNames;this.$.controls.possibleGroupings=parameterCollector.possibleGroupings;const displayLabels=parameterCollector.labels;this.$.controls.displayLabels=displayLabels;collectParametersMark.end();await this.$.table.build(histograms,sourceHistograms,displayLabels,progress);buildMark.end();},downloadCSV_(){const downloadCSVMark=tr.b.Timing.mark('histogram-set-view','downloadCSV');const anchor=document.createElement('a');const path=window.location.pathname.split('/');const basename=path[path.length-1].split('.')[0]||'histograms';anchor.download=basename+'.csv';const csv=new tr.v.CSVBuilder(this.$.table.leafHistograms);csv.build();const blob=new window.Blob([csv.toString()],{type:'text/csv'});anchor.href=window.URL.createObjectURL(blob);anchor.click();downloadCSVMark.end();}});return{};});'use strict';tr.exportTo('tr.ui',function(){Polymer({is:'tr-ui-sp-metrics-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.model_=undefined;this.rangeOfInterest_=undefined;this.metricLatenciesMs_=[];this.metrics_=[];tr.metrics.MetricRegistry.getAllRegisteredTypeInfos().forEach(function(m){if(m.constructor.name==='sampleMetric')return;this.metrics_.push({label:m.constructor.name,value:m.constructor.name});},this);this.settingsKey_='metrics-side-panel-metric-name';this.currentMetricName_='responsivenessMetric';const metricSelector=tr.ui.b.createSelector(this,'currentMetricName_',this.settingsKey_,this.currentMetricName_,this.metrics_);Polymer.dom(this.$.top_left_controls).appendChild(metricSelector);metricSelector.addEventListener('change',this.onMetricChange_.bind(this));this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.recomputeButton_=tr.ui.b.createButton('Recompute',this.onRecompute_,this);Polymer.dom(this.$.top_left_controls).appendChild(this.recomputeButton_);this.$.results.addEventListener('display-ready',()=>{this.$.results.style.display='';});},async build(model){this.model_=model;await this.updateContents_();},get metricLatencyMs(){return tr.b.math.Statistics.mean(this.metricLatenciesMs_);},onMetricChange_(){this.currentMetricTypeInfo_=tr.metrics.MetricRegistry.findTypeInfoWithName(this.currentMetricName_);this.metricLatenciesMs_=[];this.updateContents_();},onRecompute_(){this.updateContents_();},get textLabel(){return'Metrics';},supportsModel(m){if(!m){return{supported:false,reason:'No model available'};}
+return{supported:true};},get model(){return this.model_;},set model(model){this.build(model);},get selection(){},set selection(_){},get rangeOfInterest(){return this.rangeOfInterest_;},set rangeOfInterest(range){this.rangeOfInterest_=range;if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest){if((this.metricLatencyMs===undefined)||(this.metricLatencyMs<100)){this.updateContents_();}else{this.recomputeButton_.style.background='red';}}},async updateContents_(){Polymer.dom(this.$.error).textContent='';this.$.results.style.display='none';if(!this.model_){Polymer.dom(this.$.error).textContent='Missing model';return;}
+const options={metrics:[this.currentMetricName_]};if(this.currentMetricTypeInfo_&&this.currentMetricTypeInfo_.metadata.supportsRangeOfInterest&&this.rangeOfInterest&&!this.rangeOfInterest.isEmpty){options.rangeOfInterest=this.rangeOfInterest;}
+const startDate=new Date();let histograms;try{histograms=tr.metrics.runMetrics(this.model_,options);}catch(err){Polymer.dom(this.$.error).textContent=err.message;return;}
 this.metricLatenciesMs_.push(new Date()-startDate);while(this.metricLatenciesMs_.length>20){this.metricLatenciesMs_.shift();}
-this.recomputeButton_.style.background='';this.$.results.style.display='';this.$.results.histograms=histograms;}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-metrics-side-panel');});return{};});'use strict';Polymer({is:'tr-ui-e-s-alerts-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready:function(){this.rangeOfInterest_=new tr.b.math.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType:function(alertTypeString){var alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});var event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_:function(alerts){var alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title]){alertsByType[alert.title]=[];}
-alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_:function(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_:function(){return[{title:'Alert type',value:function(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value:function(row){return row.count;}}];},createAlertsTable_:function(alerts){var alertsByType=this.alertsByType_(alerts);var table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){var row=table.selectedTableRow;if(row){this.selectAlertsOfType(row.alertType);}}.bind(this));return table;},updateContents_:function(){Polymer.dom(this.$.result_area).textContent='';if(this.model_===undefined)return;var panel=this.createAlertsTable_(this.model_.alerts);Polymer.dom(this.$.result_area).appendChild(panel);},supportsModel:function(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
+this.recomputeButton_.style.background='';await this.$.results.build(histograms);}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-sp-metrics-side-panel');});return{};});'use strict';Polymer({is:'tr-ui-e-s-alerts-side-panel',behaviors:[tr.ui.behaviors.SidePanel],ready(){this.rangeOfInterest_=new tr.b.math.Range();this.selection_=undefined;},get model(){return this.model_;},set model(model){this.model_=model;this.updateContents_();},set selection(selection){},set rangeOfInterest(rangeOfInterest){},selectAlertsOfType(alertTypeString){const alertsOfType=this.model_.alerts.filter(function(alert){return alert.title===alertTypeString;});const event=new tr.model.RequestSelectionChangeEvent();event.selection=new tr.model.EventSet(alertsOfType);this.dispatchEvent(event);},alertsByType_(alerts){const alertsByType={};alerts.forEach(function(alert){if(!alertsByType[alert.title]){alertsByType[alert.title]=[];}
+alertsByType[alert.title].push(alert);});return alertsByType;},alertsTableRows_(alertsByType){return Object.keys(alertsByType).map(function(key){return{alertType:key,count:alertsByType[key].length};});},alertsTableColumns_(){return[{title:'Alert type',value(row){return row.alertType;},width:'180px'},{title:'Count',width:'100%',value(row){return row.count;}}];},createAlertsTable_(alerts){const alertsByType=this.alertsByType_(alerts);const table=document.createElement('tr-ui-b-table');table.tableColumns=this.alertsTableColumns_();table.tableRows=this.alertsTableRows_(alertsByType);table.selectionMode=tr.ui.b.TableFormat.SelectionMode.ROW;table.addEventListener('selection-changed',function(e){const row=table.selectedTableRow;if(row){this.selectAlertsOfType(row.alertType);}}.bind(this));return table;},updateContents_(){Polymer.dom(this.$.result_area).textContent='';if(this.model_===undefined)return;const panel=this.createAlertsTable_(this.model_.alerts);Polymer.dom(this.$.result_area).appendChild(panel);},supportsModel(m){if(m===undefined){return{supported:false,reason:'Unknown tracing model'};}else if(m.alerts.length===0){return{supported:false,reason:'No alerts in tracing model'};}
 return{supported:true};},get textLabel(){return'Alerts';}});tr.ui.side_panel.SidePanelRegistry.register(function(){return document.createElement('tr-ui-e-s-alerts-side-panel');});
 </script>
 <!--CATAPULT_REV=NO_AUTO_UPDATE-->
\ No newline at end of file
diff --git a/catapult/systrace/systrace/test_data/atrace_data_thread_fixed b/catapult/systrace/systrace/test_data/atrace_data_thread_fixed
deleted file mode 100644
index 7b423e7..0000000
--- a/catapult/systrace/systrace/test_data/atrace_data_thread_fixed
+++ /dev/null
@@ -1,127 +0,0 @@
-# tracer: nop
-#
-# entries-in-buffer/entries-written: 116/116   #P:1
-#
-#                              _-----=> irqs-off
-#                             / _----=> need-resched
-#                            | / _---=> hardirq/softirq
-#                            || / _--=> preempt-depth
-#                            ||| /     delay
-#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
-#              | |       |   ||||       |         |
-atrace-14446 [000] ...2  1212.465062: sched_switch: prev_comm=atrace prev_pid=14446 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.465074: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465082: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.465092: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.465102: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465126: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.465132: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.465139: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465145: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.465227: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h5  1212.465297: sched_wakeup: comm=adbd pid=212 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465306: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=adbd next_pid=212 next_prio=120
-adbd-212   [000] d..4  1212.465329: sched_wakeup: comm=adbd pid=209 prio=120 success=1 target_cpu=000
-adbd-212   [000] ...2  1212.465348: sched_switch: prev_comm=adbd prev_pid=212 prev_prio=120 prev_state=S ==> next_comm=adbd next_pid=209 next_prio=120
-/sbin/adbd-209   [000] d..4  1212.465395: sched_wakeup: comm=adbd pid=211 prio=120 success=1 target_cpu=000
-/sbin/adbd-209   [000] ...2  1212.465441: sched_switch: prev_comm=adbd prev_pid=209 prev_prio=120 prev_state=S ==> next_comm=adbd next_pid=211 next_prio=120
-adbd-211   [000] ...2  1212.465448: sched_switch: prev_comm=adbd prev_pid=211 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h5  1212.574554: sched_wakeup: comm=sensors.qcom pid=292 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.574566: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=sensors.qcom next_pid=292 next_prio=120
-sensors.qcom-292   [000] ...2  1212.574665: sched_switch: prev_comm=sensors.qcom prev_pid=292 prev_prio=120 prev_state=S ==> next_comm=sensors.qcom next_pid=14447 next_prio=120
-sensors.qcom-14447 [000] d..4  1212.574797: sched_wakeup: comm=sensors.qcom pid=1593 prio=120 success=1 target_cpu=000
-sensors.qcom-14447 [000] ...2  1212.574802: sched_switch: prev_comm=sensors.qcom prev_pid=14447 prev_prio=120 prev_state=R+ ==> next_comm=sensors.qcom next_pid=1593 next_prio=120
-sensors.qcom-1593  [000] ...2  1212.574819: sched_switch: prev_comm=sensors.qcom prev_pid=1593 prev_prio=120 prev_state=D ==> next_comm=sensors.qcom next_pid=14447 next_prio=120
-sensors.qcom-14447 [000] d..3  1212.574823: sched_wakeup: comm=sensors.qcom pid=1593 prio=120 success=1 target_cpu=000
-sensors.qcom-14447 [000] ...2  1212.574827: sched_switch: prev_comm=sensors.qcom prev_pid=14447 prev_prio=120 prev_state=R+ ==> next_comm=sensors.qcom next_pid=1593 next_prio=120
-sensors.qcom-1593  [000] d..4  1212.574865: sched_wakeup: comm=sensors.qcom pid=760 prio=120 success=1 target_cpu=000
-sensors.qcom-1593  [000] ...2  1212.574876: sched_switch: prev_comm=sensors.qcom prev_pid=1593 prev_prio=120 prev_state=S ==> next_comm=sensors.qcom next_pid=760 next_prio=120
-sensors.qcom-760   [000] d..4  1212.574905: sched_wakeup: comm=system_server pid=782 prio=118 success=1 target_cpu=000
-sensors.qcom-760   [000] ...2  1212.574917: sched_switch: prev_comm=sensors.qcom prev_pid=760 prev_prio=120 prev_state=S ==> next_comm=system_server next_pid=782 next_prio=118
-system_server-782   [000] d..4  1212.574981: sched_wakeup: comm=system_server pid=785 prio=118 success=1 target_cpu=000
-system_server-782   [000] ...2  1212.575009: sched_switch: prev_comm=system_server prev_pid=782 prev_prio=118 prev_state=S ==> next_comm=system_server next_pid=785 next_prio=118
-system_server-785   [000] ...2  1212.575045: sched_switch: prev_comm=system_server prev_pid=785 prev_prio=118 prev_state=S ==> next_comm=sensors.qcom next_pid=14447 next_prio=120
-sensors.qcom-14447 [000] ...3  1212.575143: sched_switch: prev_comm=sensors.qcom prev_pid=14447 prev_prio=120 prev_state=x ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.575153: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.575159: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.575167: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.575175: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.575181: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.575188: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.575195: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.575201: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.575211: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1212.649601: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.649614: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
-MMHandlerThread-7231  [000] ...2  1212.649630: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.729539: sched_wakeup: comm=kworker/u:1 pid=21 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNs6  1212.729550: sched_wakeup: comm=kworker/0:2H pid=557 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.729563: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:1 next_pid=21 next_prio=120
-kworker/u:1-21    [000] d..5  1212.729571: sched_wakeup: comm=mpdecision pid=2046 prio=113 success=1 target_cpu=000
-kworker/u:1-21    [000] ...2  1212.729578: sched_switch: prev_comm=kworker/u:1 prev_pid=21 prev_prio=120 prev_state=S ==> next_comm=kworker/0:2H next_pid=557 next_prio=100
-kworker/0:2H-557   [000] d..4  1212.729597: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-kworker/0:2H-557   [000] ...2  1212.729600: sched_switch: prev_comm=kworker/0:2H prev_pid=557 prev_prio=100 prev_state=D ==> next_comm=mpdecision next_pid=2046 next_prio=113
-mpdecision-2046  [000] ...2  1212.729801: sched_switch: prev_comm=mpdecision prev_pid=2046 prev_prio=113 prev_state=S ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-kworker/0:1H-17    [000] ...2  1212.730104: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.730134: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730154: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.730176: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.730201: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730220: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.730241: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.730262: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730280: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1212.730303: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.730638: sched_wakeup: comm=kworker/u:0H pid=7 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730669: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:0H next_pid=7 next_prio=100
-kworker/u:0H-7     [000] d..6  1212.730707: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-kworker/u:0H-7     [000] ...2  1212.730728: sched_switch: prev_comm=kworker/u:0H prev_pid=7 prev_prio=100 prev_state=D ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-kworker/0:1H-17    [000] ...2  1212.730916: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.731632: sched_wakeup: comm=kworker/u:0H pid=7 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.731661: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:0H next_pid=7 next_prio=100
-kworker/u:0H-7     [000] d..6  1212.731702: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-kworker/u:0H-7     [000] ...2  1212.731722: sched_switch: prev_comm=kworker/u:0H prev_pid=7 prev_prio=100 prev_state=D ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-kworker/0:1H-17    [000] ...2  1212.731832: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.732685: sched_wakeup: comm=kworker/u:0H pid=7 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.732714: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:0H next_pid=7 next_prio=100
-kworker/u:0H-7     [000] d..6  1212.732747: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-kworker/u:0H-7     [000] ...2  1212.732767: sched_switch: prev_comm=kworker/u:0H prev_pid=7 prev_prio=100 prev_state=D ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-kworker/0:1H-17    [000] d..4  1212.732810: sched_wakeup: comm=kworker/0:2H pid=557 prio=100 success=1 target_cpu=000
-kworker/0:1H-17    [000] ...2  1212.732829: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=S ==> next_comm=kworker/0:2H next_pid=557 next_prio=100
-kworker/0:2H-557   [000] ...2  1212.732854: sched_switch: prev_comm=kworker/0:2H prev_pid=557 prev_prio=100 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1212.876266: sched_wakeup: comm=RILSender0 pid=1365 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNh4  1212.876284: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.876316: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=RILSender0 next_pid=1365 next_prio=120
-RILSender0-1365  [000] ...2  1212.876415: sched_switch: prev_comm=RILSender0 prev_pid=1365 prev_prio=120 prev_state=S ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
-MMHandlerThread-7231  [000] ...2  1212.876454: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1213.089569: sched_wakeup: comm=Thread-625 pid=5750 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNh4  1213.089587: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.089622: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=Thread-625 next_pid=5750 next_prio=120
-Thread-625-5750  [000] ...2  1213.089842: sched_switch: prev_comm=Thread-625 prev_pid=5750 prev_prio=120 prev_state=S ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
-MMHandlerThread-7231  [000] ...2  1213.089879: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1213.327439: sched_wakeup: comm=pandora.android pid=5395 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNh4  1213.327455: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.327487: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
-MMHandlerThread-7231  [000] ...2  1213.327518: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=pandora.android next_pid=5395 next_prio=120
-com.pandora.android-5395  [000] d..4  1213.327718: sched_wakeup: comm=Binder_1 pid=780 prio=120 success=1 target_cpu=000
-com.pandora.android-5395  [000] ...2  1213.327739: sched_switch: prev_comm=pandora.android prev_pid=5395 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=780 next_prio=120
-Binder_1-780   [000] ...2  1213.327763: sched_switch: prev_comm=Binder_1 prev_pid=780 prev_prio=120 prev_state=D ==> next_comm=pandora.android next_pid=5395 next_prio=120
-com.pandora.android-5395  [000] d..3  1213.327781: sched_wakeup: comm=Binder_1 pid=780 prio=120 success=1 target_cpu=000
-com.pandora.android-5395  [000] ...2  1213.327795: sched_switch: prev_comm=pandora.android prev_pid=5395 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=780 next_prio=120
-Binder_1-780   [000] d..4  1213.328056: sched_wakeup: comm=Binder_1 pid=878 prio=120 success=1 target_cpu=000
-Binder_1-780   [000] ...2  1213.328095: sched_switch: prev_comm=Binder_1 prev_pid=780 prev_prio=120 prev_state=S ==> next_comm=Binder_1 next_pid=878 next_prio=120
-Binder_1-878   [000] d..4  1213.328263: sched_wakeup: comm=Binder_1 pid=780 prio=120 success=1 target_cpu=000
-Binder_1-878   [000] ...2  1213.328345: sched_switch: prev_comm=Binder_1 prev_pid=878 prev_prio=120 prev_state=S ==> next_comm=Binder_1 next_pid=780 next_prio=120
-Binder_1-780   [000] ...2  1213.328558: sched_switch: prev_comm=Binder_1 prev_pid=780 prev_prio=120 prev_state=S ==> next_comm=pandora.android next_pid=5395 next_prio=120
-com.pandora.android-5395  [000] ...2  1213.328743: sched_switch: prev_comm=pandora.android prev_pid=5395 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1213.328773: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.328793: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1213.328821: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1213.328846: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.328866: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1213.328891: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1213.328913: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.328931: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-ksoftirqd/0-3     [000] ...2  1213.328964: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1213.465138: sched_wakeup: comm=atrace pid=14446 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.465171: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=atrace next_pid=14446 next_prio=120
diff --git a/catapult/systrace/systrace/test_data/atrace_data_with_thread_list b/catapult/systrace/systrace/test_data/atrace_data_with_thread_list
deleted file mode 100644
index 32091c9..0000000
--- a/catapult/systrace/systrace/test_data/atrace_data_with_thread_list
+++ /dev/null
@@ -1,1660 +0,0 @@
-
-# tracer: nop
-#
-# entries-in-buffer/entries-written: 116/116   #P:1
-#
-#                              _-----=> irqs-off
-#                             / _----=> need-resched
-#                            | / _---=> hardirq/softirq
-#                            || / _--=> preempt-depth
-#                            ||| /     delay
-#           TASK-PID   CPU#  ||||    TIMESTAMP  FUNCTION
-#              | |       |   ||||       |         |
-          atrace-14446 [000] ...2  1212.465062: sched_switch: prev_comm=atrace prev_pid=14446 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.465074: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465082: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.465092: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.465102: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465126: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.465132: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.465139: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465145: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.465227: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h5  1212.465297: sched_wakeup: comm=adbd pid=212 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.465306: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=adbd next_pid=212 next_prio=120
-            adbd-212   [000] d..4  1212.465329: sched_wakeup: comm=adbd pid=209 prio=120 success=1 target_cpu=000
-            adbd-212   [000] ...2  1212.465348: sched_switch: prev_comm=adbd prev_pid=212 prev_prio=120 prev_state=S ==> next_comm=adbd next_pid=209 next_prio=120
-            adbd-209   [000] d..4  1212.465395: sched_wakeup: comm=adbd pid=211 prio=120 success=1 target_cpu=000
-            adbd-209   [000] ...2  1212.465441: sched_switch: prev_comm=adbd prev_pid=209 prev_prio=120 prev_state=S ==> next_comm=adbd next_pid=211 next_prio=120
-            adbd-211   [000] ...2  1212.465448: sched_switch: prev_comm=adbd prev_pid=211 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h5  1212.574554: sched_wakeup: comm=sensors.qcom pid=292 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.574566: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=sensors.qcom next_pid=292 next_prio=120
-    sensors.qcom-292   [000] ...2  1212.574665: sched_switch: prev_comm=sensors.qcom prev_pid=292 prev_prio=120 prev_state=S ==> next_comm=sensors.qcom next_pid=14447 next_prio=120
-    sensors.qcom-14447 [000] d..4  1212.574797: sched_wakeup: comm=sensors.qcom pid=1593 prio=120 success=1 target_cpu=000
-    sensors.qcom-14447 [000] ...2  1212.574802: sched_switch: prev_comm=sensors.qcom prev_pid=14447 prev_prio=120 prev_state=R+ ==> next_comm=sensors.qcom next_pid=1593 next_prio=120
-    sensors.qcom-1593  [000] ...2  1212.574819: sched_switch: prev_comm=sensors.qcom prev_pid=1593 prev_prio=120 prev_state=D ==> next_comm=sensors.qcom next_pid=14447 next_prio=120
-    sensors.qcom-14447 [000] d..3  1212.574823: sched_wakeup: comm=sensors.qcom pid=1593 prio=120 success=1 target_cpu=000
-    sensors.qcom-14447 [000] ...2  1212.574827: sched_switch: prev_comm=sensors.qcom prev_pid=14447 prev_prio=120 prev_state=R+ ==> next_comm=sensors.qcom next_pid=1593 next_prio=120
-    sensors.qcom-1593  [000] d..4  1212.574865: sched_wakeup: comm=sensors.qcom pid=760 prio=120 success=1 target_cpu=000
-    sensors.qcom-1593  [000] ...2  1212.574876: sched_switch: prev_comm=sensors.qcom prev_pid=1593 prev_prio=120 prev_state=S ==> next_comm=sensors.qcom next_pid=760 next_prio=120
-    sensors.qcom-760   [000] d..4  1212.574905: sched_wakeup: comm=system_server pid=782 prio=118 success=1 target_cpu=000
-    sensors.qcom-760   [000] ...2  1212.574917: sched_switch: prev_comm=sensors.qcom prev_pid=760 prev_prio=120 prev_state=S ==> next_comm=system_server next_pid=782 next_prio=118
-   system_server-782   [000] d..4  1212.574981: sched_wakeup: comm=system_server pid=785 prio=118 success=1 target_cpu=000
-   system_server-782   [000] ...2  1212.575009: sched_switch: prev_comm=system_server prev_pid=782 prev_prio=118 prev_state=S ==> next_comm=system_server next_pid=785 next_prio=118
-   system_server-785   [000] ...2  1212.575045: sched_switch: prev_comm=system_server prev_pid=785 prev_prio=118 prev_state=S ==> next_comm=sensors.qcom next_pid=14447 next_prio=120
-    sensors.qcom-14447 [000] ...3  1212.575143: sched_switch: prev_comm=sensors.qcom prev_pid=14447 prev_prio=120 prev_state=x ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.575153: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.575159: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.575167: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.575175: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.575181: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.575188: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.575195: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.575201: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.575211: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1212.649601: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.649614: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
- MMHandlerThread-7231  [000] ...2  1212.649630: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.729539: sched_wakeup: comm=kworker/u:1 pid=21 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNs6  1212.729550: sched_wakeup: comm=kworker/0:2H pid=557 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.729563: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:1 next_pid=21 next_prio=120
-     kworker/u:1-21    [000] d..5  1212.729571: sched_wakeup: comm=mpdecision pid=2046 prio=113 success=1 target_cpu=000
-     kworker/u:1-21    [000] ...2  1212.729578: sched_switch: prev_comm=kworker/u:1 prev_pid=21 prev_prio=120 prev_state=S ==> next_comm=kworker/0:2H next_pid=557 next_prio=100
-    kworker/0:2H-557   [000] d..4  1212.729597: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-    kworker/0:2H-557   [000] ...2  1212.729600: sched_switch: prev_comm=kworker/0:2H prev_pid=557 prev_prio=100 prev_state=D ==> next_comm=mpdecision next_pid=2046 next_prio=113
-      mpdecision-2046  [000] ...2  1212.729801: sched_switch: prev_comm=mpdecision prev_pid=2046 prev_prio=113 prev_state=S ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-    kworker/0:1H-17    [000] ...2  1212.730104: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.730134: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730154: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.730176: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.730201: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730220: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.730241: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1212.730262: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730280: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1212.730303: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.730638: sched_wakeup: comm=kworker/u:0H pid=7 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.730669: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:0H next_pid=7 next_prio=100
-    kworker/u:0H-7     [000] d..6  1212.730707: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-    kworker/u:0H-7     [000] ...2  1212.730728: sched_switch: prev_comm=kworker/u:0H prev_pid=7 prev_prio=100 prev_state=D ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-    kworker/0:1H-17    [000] ...2  1212.730916: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.731632: sched_wakeup: comm=kworker/u:0H pid=7 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.731661: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:0H next_pid=7 next_prio=100
-    kworker/u:0H-7     [000] d..6  1212.731702: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-    kworker/u:0H-7     [000] ...2  1212.731722: sched_switch: prev_comm=kworker/u:0H prev_pid=7 prev_prio=100 prev_state=D ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-    kworker/0:1H-17    [000] ...2  1212.731832: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=D ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h6  1212.732685: sched_wakeup: comm=kworker/u:0H pid=7 prio=100 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.732714: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=kworker/u:0H next_pid=7 next_prio=100
-    kworker/u:0H-7     [000] d..6  1212.732747: sched_wakeup: comm=kworker/0:1H pid=17 prio=100 success=1 target_cpu=000
-    kworker/u:0H-7     [000] ...2  1212.732767: sched_switch: prev_comm=kworker/u:0H prev_pid=7 prev_prio=100 prev_state=D ==> next_comm=kworker/0:1H next_pid=17 next_prio=100
-    kworker/0:1H-17    [000] d..4  1212.732810: sched_wakeup: comm=kworker/0:2H pid=557 prio=100 success=1 target_cpu=000
-    kworker/0:1H-17    [000] ...2  1212.732829: sched_switch: prev_comm=kworker/0:1H prev_pid=17 prev_prio=100 prev_state=S ==> next_comm=kworker/0:2H next_pid=557 next_prio=100
-    kworker/0:2H-557   [000] ...2  1212.732854: sched_switch: prev_comm=kworker/0:2H prev_pid=557 prev_prio=100 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1212.876266: sched_wakeup: comm=RILSender0 pid=1365 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNh4  1212.876284: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1212.876316: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=RILSender0 next_pid=1365 next_prio=120
-      RILSender0-1365  [000] ...2  1212.876415: sched_switch: prev_comm=RILSender0 prev_pid=1365 prev_prio=120 prev_state=S ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
- MMHandlerThread-7231  [000] ...2  1212.876454: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1213.089569: sched_wakeup: comm=Thread-625 pid=5750 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNh4  1213.089587: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.089622: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=Thread-625 next_pid=5750 next_prio=120
-      Thread-625-5750  [000] ...2  1213.089842: sched_switch: prev_comm=Thread-625 prev_pid=5750 prev_prio=120 prev_state=S ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
- MMHandlerThread-7231  [000] ...2  1213.089879: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1213.327439: sched_wakeup: comm=pandora.android pid=5395 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] dNh4  1213.327455: sched_wakeup: comm=MMHandlerThread pid=7231 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.327487: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=MMHandlerThread next_pid=7231 next_prio=120
- MMHandlerThread-7231  [000] ...2  1213.327518: sched_switch: prev_comm=MMHandlerThread prev_pid=7231 prev_prio=120 prev_state=S ==> next_comm=pandora.android next_pid=5395 next_prio=120
- pandora.android-5395  [000] d..4  1213.327718: sched_wakeup: comm=Binder_1 pid=780 prio=120 success=1 target_cpu=000
- pandora.android-5395  [000] ...2  1213.327739: sched_switch: prev_comm=pandora.android prev_pid=5395 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=780 next_prio=120
-        Binder_1-780   [000] ...2  1213.327763: sched_switch: prev_comm=Binder_1 prev_pid=780 prev_prio=120 prev_state=D ==> next_comm=pandora.android next_pid=5395 next_prio=120
- pandora.android-5395  [000] d..3  1213.327781: sched_wakeup: comm=Binder_1 pid=780 prio=120 success=1 target_cpu=000
- pandora.android-5395  [000] ...2  1213.327795: sched_switch: prev_comm=pandora.android prev_pid=5395 prev_prio=120 prev_state=R+ ==> next_comm=Binder_1 next_pid=780 next_prio=120
-        Binder_1-780   [000] d..4  1213.328056: sched_wakeup: comm=Binder_1 pid=878 prio=120 success=1 target_cpu=000
-        Binder_1-780   [000] ...2  1213.328095: sched_switch: prev_comm=Binder_1 prev_pid=780 prev_prio=120 prev_state=S ==> next_comm=Binder_1 next_pid=878 next_prio=120
-        Binder_1-878   [000] d..4  1213.328263: sched_wakeup: comm=Binder_1 pid=780 prio=120 success=1 target_cpu=000
-        Binder_1-878   [000] ...2  1213.328345: sched_switch: prev_comm=Binder_1 prev_pid=878 prev_prio=120 prev_state=S ==> next_comm=Binder_1 next_pid=780 next_prio=120
-        Binder_1-780   [000] ...2  1213.328558: sched_switch: prev_comm=Binder_1 prev_pid=780 prev_prio=120 prev_state=S ==> next_comm=pandora.android next_pid=5395 next_prio=120
- pandora.android-5395  [000] ...2  1213.328743: sched_switch: prev_comm=pandora.android prev_pid=5395 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1213.328773: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.328793: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1213.328821: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1213.328846: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.328866: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1213.328891: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d..4  1213.328913: sched_wakeup: comm=ksoftirqd/0 pid=3 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.328931: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=ksoftirqd/0 next_pid=3 next_prio=120
-     ksoftirqd/0-3     [000] ...2  1213.328964: sched_switch: prev_comm=ksoftirqd/0 prev_pid=3 prev_prio=120 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
-          <idle>-0     [000] d.h4  1213.465138: sched_wakeup: comm=atrace pid=14446 prio=120 success=1 target_cpu=000
-          <idle>-0     [000] ...2  1213.465171: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=atrace next_pid=14446 next_prio=120
-USER     PID   PPID  VSIZE  RSS     WCHAN    PC        NAME
-root      1     0     8784   712   ffffffff 00000000 S /init
-root      2     0     0      0     ffffffff 00000000 S kthreadd
-root      3     2     0      0     ffffffff 00000000 S ksoftirqd/0
-root      7     2     0      0     ffffffff 00000000 D kworker/u:0H
-root      8     2     0      0     ffffffff 00000000 S migration/0
-root      13    2     0      0     ffffffff 00000000 S khelper
-root      14    2     0      0     ffffffff 00000000 S netns
-root      17    2     0      0     ffffffff 00000000 S kworker/0:1H
-root      18    2     0      0     ffffffff 00000000 S modem_notifier
-root      19    2     0      0     ffffffff 00000000 S smd_channel_clo
-root      20    2     0      0     ffffffff 00000000 S smsm_cb_wq
-root      21    2     0      0     ffffffff 00000000 S kworker/u:1
-root      22    2     0      0     ffffffff 00000000 S rpm-smd
-root      23    2     0      0     ffffffff 00000000 S kworker/u:1H
-root      24    2     0      0     ffffffff 00000000 S irq/317-earjack
-root      25    2     0      0     ffffffff 00000000 S sync_supers
-root      26    2     0      0     ffffffff 00000000 S bdi-default
-root      27    2     0      0     ffffffff 00000000 S kblockd
-root      28    2     0      0     ffffffff 00000000 S vmalloc
-root      29    2     0      0     ffffffff 00000000 S khubd
-root      30    2     0      0     ffffffff 00000000 S irq/102-msm_iom
-root      31    2     0      0     ffffffff 00000000 S irq/102-msm_iom
-root      32    2     0      0     ffffffff 00000000 S irq/102-msm_iom
-root      33    2     0      0     ffffffff 00000000 S irq/79-msm_iomm
-root      34    2     0      0     ffffffff 00000000 S irq/78-msm_iomm
-root      35    2     0      0     ffffffff 00000000 S irq/78-msm_iomm
-root      36    2     0      0     ffffffff 00000000 S irq/74-msm_iomm
-root      37    2     0      0     ffffffff 00000000 S irq/75-msm_iomm
-root      38    2     0      0     ffffffff 00000000 S irq/75-msm_iomm
-root      39    2     0      0     ffffffff 00000000 S irq/75-msm_iomm
-root      40    2     0      0     ffffffff 00000000 S irq/75-msm_iomm
-root      41    2     0      0     ffffffff 00000000 S irq/273-msm_iom
-root      42    2     0      0     ffffffff 00000000 S irq/273-msm_iom
-root      43    2     0      0     ffffffff 00000000 S irq/97-msm_iomm
-root      44    2     0      0     ffffffff 00000000 S irq/97-msm_iomm
-root      45    2     0      0     ffffffff 00000000 S irq/97-msm_iomm
-root      46    2     0      0     ffffffff 00000000 S l2cap
-root      47    2     0      0     ffffffff 00000000 S a2mp
-root      48    2     0      0     ffffffff 00000000 S cfg80211
-root      49    2     0      0     ffffffff 00000000 S qmi
-root      50    2     0      0     ffffffff 00000000 S nmea
-root      51    2     0      0     ffffffff 00000000 S msm_ipc_router
-root      52    2     0      0     ffffffff 00000000 S apr_driver
-root      54    2     0      0     ffffffff 00000000 S kswapd0
-root      55    2     0      0     ffffffff 00000000 S fsnotify_mark
-root      56    2     0      0     ffffffff 00000000 S cifsiod
-root      57    2     0      0     ffffffff 00000000 S crypto
-root      75    2     0      0     ffffffff 00000000 S ad_calc_wq
-root      76    2     0      0     ffffffff 00000000 S hdmi_tx_workq
-root      77    2     0      0     ffffffff 00000000 S anx7808_work
-root      78    2     0      0     ffffffff 00000000 S k_hsuart
-root      79    2     0      0     ffffffff 00000000 S diag_wq
-root      80    2     0      0     ffffffff 00000000 S diag_cntl_wq
-root      81    2     0      0     ffffffff 00000000 S diag_dci_wq
-root      82    2     0      0     ffffffff 00000000 S kgsl-3d0
-root      84    2     0      0     ffffffff 00000000 S f9966000.spi
-root      88    2     0      0     ffffffff 00000000 S usbnet
-root      89    2     0      0     ffffffff 00000000 S irq/329-anx7808
-root      90    2     0      0     ffffffff 00000000 S k_rmnet_mux_wor
-root      91    2     0      0     ffffffff 00000000 S f_mtp
-root      92    2     0      0     ffffffff 00000000 S file-storage
-root      93    2     0      0     ffffffff 00000000 S uether
-root      94    2     0      0     ffffffff 00000000 S synaptics_wq
-root      95    2     0      0     ffffffff 00000000 S irq/362-s3350
-root      96    2     0      0     ffffffff 00000000 S kworker/0:2
-root      97    2     0      0     ffffffff 00000000 S msm_vidc_worker
-root      98    2     0      0     ffffffff 00000000 S msm_vidc_worker
-root      99    2     0      0     ffffffff 00000000 S msm_cpp_workque
-root      100   2     0      0     ffffffff 00000000 S irq/350-bq51013
-root      102   2     0      0     ffffffff 00000000 S dm_bufio_cache
-root      103   2     0      0     ffffffff 00000000 D dbs_sync/0
-root      104   2     0      0     ffffffff 00000000 D dbs_sync/1
-root      105   2     0      0     ffffffff 00000000 D dbs_sync/2
-root      106   2     0      0     ffffffff 00000000 D dbs_sync/3
-root      107   2     0      0     ffffffff 00000000 S cfinteractive
-root      108   2     0      0     ffffffff 00000000 S irq/170-msm_sdc
-root      109   2     0      0     ffffffff 00000000 S binder
-root      110   2     0      0     ffffffff 00000000 S usb_bam_wq
-root      111   2     0      0     ffffffff 00000000 S krfcommd
-root      112   2     0      0     ffffffff 00000000 S bam_dmux_rx
-root      113   2     0      0     ffffffff 00000000 S bam_dmux_tx
-root      114   2     0      0     ffffffff 00000000 S rq_stats
-root      115   2     0      0     ffffffff 00000000 S deferwq
-root      117   2     0      0     ffffffff 00000000 S irq/361-MAX1704
-root      119   2     0      0     ffffffff 00000000 S mmcqd/1
-root      120   2     0      0     ffffffff 00000000 S mmcqd/1rpmb
-root      121   2     0      0     ffffffff 00000000 S wl_event_handle
-root      122   2     0      0     ffffffff 00000000 S dhd_watchdog_th
-root      123   2     0      0     ffffffff 00000000 S dhd_dpc
-root      124   2     0      0     ffffffff 00000000 S dhd_rxf
-root      125   2     0      0     ffffffff 00000000 S dhd_sysioc
-root      126   2     0      0     ffffffff 00000000 S vibrator
-root      127   2     0      0     ffffffff 00000000 S max1462x
-root      128   2     0      0     ffffffff 00000000 S irq/310-maxim_m
-root      129   2     0      0     ffffffff 00000000 S irq/311-maxim_m
-root      130   1     8780   576   ffffffff 00000000 S /sbin/ueventd
-root      132   2     0      0     ffffffff 00000000 S jbd2/mmcblk0p25
-root      133   2     0      0     ffffffff 00000000 S ext4-dio-unwrit
-root      136   2     0      0     ffffffff 00000000 S flush-179:0
-root      138   2     0      0     ffffffff 00000000 S jbd2/mmcblk0p28
-root      139   2     0      0     ffffffff 00000000 S ext4-dio-unwrit
-root      143   2     0      0     ffffffff 00000000 S jbd2/mmcblk0p27
-root      144   2     0      0     ffffffff 00000000 S ext4-dio-unwrit
-root      145   2     0      0     ffffffff 00000000 S jbd2/mmcblk0p16
-root      146   2     0      0     ffffffff 00000000 S ext4-dio-unwrit
-logd      169   1     18632  2740  ffffffff 00000000 S /system/bin/logd
-logd      216   169   18632  2740  ffffffff 00000000 S logd.reader
-logd      217   169   18632  2740  ffffffff 00000000 S logd.writer
-logd      218   169   18632  2740  ffffffff 00000000 S logd
-logd      244   169   18632  2740  ffffffff 00000000 S logd.auditd
-root      170   1     9832   304   ffffffff 00000000 S /sbin/healthd
-root      171   1     10620  1240  ffffffff 00000000 S /system/bin/lmkd
-system    172   1     9452   676   ffffffff 00000000 S /system/bin/servicemanager
-root      173   1     18028  1652  ffffffff 00000000 S /system/bin/vold
-root      223   173   18028  1652  ffffffff 00000000 S vold
-root      226   173   18028  1652  ffffffff 00000000 S vold
-root      174   2     0      0     ffffffff 00000000 S IPCRTR
-root      175   2     0      0     ffffffff 00000000 S sb-1
-root      177   2     0      0     ffffffff 00000000 S ipc_rtr_q6_ipcr
-root      179   2     0      0     ffffffff 00000000 S ngd_msm_ctrl_ng
-system    180   1     146792 9724  ffffffff 00000000 S /system/bin/surfaceflinger
-system    240   180   146792 9724  ffffffff 00000000 S Binder_1
-system    242   180   146792 9724  ffffffff 00000000 S DispSync
-system    243   180   146792 9724  ffffffff 00000000 S Binder_2
-system    361   180   146792 9724  ffffffff 00000000 S hwcUeventThread
-system    362   180   146792 9724  ffffffff 00000000 S hwcVsyncThread
-system    396   180   146792 9724  ffffffff 00000000 S GL updater
-system    397   180   146792 9724  ffffffff 00000000 S surfaceflinger
-system    398   180   146792 9724  ffffffff 00000000 S EventThread
-system    399   180   146792 9724  ffffffff 00000000 S surfaceflinger
-system    400   180   146792 9724  ffffffff 00000000 S EventThread
-system    401   180   146792 9724  ffffffff 00000000 S EventControl
-system    575   180   146792 9724  ffffffff 00000000 S Binder_3
-system    1501  180   146792 9724  ffffffff 00000000 S Binder_4
-system    5633  180   146792 9724  ffffffff 00000000 S Binder_5
-nobody    181   1     19792  1112  ffffffff 00000000 S /system/bin/rmt_storage
-nobody    571   181   19792  1112  ffffffff 00000000 S rmt_storage
-nobody    572   181   19792  1112  ffffffff 00000000 S rmt_storage
-nobody    573   181   19792  1112  ffffffff 00000000 S rmt_storage
-nobody    574   181   19792  1112  ffffffff 00000000 S rmt_storage
-system    182   1     11100  992   ffffffff 00000000 S /system/bin/qseecomd
-root      183   2     0      0     ffffffff 00000000 S msm_slim_qmi_cl
-root      184   2     0      0     ffffffff 00000000 S msm_qmi_rtx_q
-shell     185   1     9316   716   c047451c b6f58da8 S /system/bin/sh
-root      187   1     9200   368   ffffffff 00000000 S /system/bin/subsystem_ramdump
-root      188   1     22828  1404  ffffffff 00000000 S /system/bin/netd
-root      548   188   22828  1404  ffffffff 00000000 S netd
-root      549   188   22828  1404  ffffffff 00000000 S netd
-root      550   188   22828  1404  ffffffff 00000000 S netd
-root      551   188   22828  1404  ffffffff 00000000 S netd
-root      552   188   22828  1404  ffffffff 00000000 S netd
-root      553   188   22828  1404  ffffffff 00000000 S netd
-root      554   188   22828  1404  ffffffff 00000000 S netd
-root      555   188   22828  1404  ffffffff 00000000 S netd
-root      189   1     10048  848   ffffffff 00000000 S /system/bin/debuggerd
-radio     191   1     35988  4712  ffffffff 00000000 S /system/bin/rild
-radio     335   191   35988  4712  ffffffff 00000000 S rild
-radio     343   191   35988  4712  ffffffff 00000000 S rild
-radio     346   191   35988  4712  ffffffff 00000000 S rild
-radio     584   191   35988  4712  ffffffff 00000000 S rild
-radio     585   191   35988  4712  ffffffff 00000000 S rild
-radio     587   191   35988  4712  ffffffff 00000000 S rild
-radio     588   191   35988  4712  ffffffff 00000000 S rild
-radio     589   191   35988  4712  ffffffff 00000000 S rild
-radio     591   191   35988  4712  ffffffff 00000000 S rild
-radio     592   191   35988  4712  ffffffff 00000000 S rild
-radio     593   191   35988  4712  ffffffff 00000000 S rild
-radio     594   191   35988  4712  ffffffff 00000000 S rild
-drm       192   1     26084  3832  ffffffff 00000000 S /system/bin/drmserver
-drm       419   192   26084  3832  ffffffff 00000000 S Binder_1
-media     194   1     106516 8584  ffffffff 00000000 S /system/bin/mediaserver
-media     755   194   106516 8584  ffffffff 00000000 S ApmTone
-media     756   194   106516 8584  ffffffff 00000000 S ApmAudio
-media     757   194   106516 8584  ffffffff 00000000 S ApmOutput
-media     758   194   106516 8584  ffffffff 00000000 S mediaserver
-media     759   194   106516 8584  ffffffff 00000000 S FastMixer
-media     871   194   106516 8584  ffffffff 00000000 S AudioOut_2
-media     872   194   106516 8584  ffffffff 00000000 S AudioOut_4
-media     873   194   106516 8584  ffffffff 00000000 S FastMixer
-media     874   194   106516 8584  ffffffff 00000000 S AudioOut_6
-media     878   194   106516 8584  ffffffff 00000000 S Binder_1
-media     879   194   106516 8584  ffffffff 00000000 S Binder_2
-media     1133  194   106516 8584  ffffffff 00000000 S Binder_3
-install   195   1     9408   704   ffffffff 00000000 S /system/bin/installd
-keystore  197   1     12536  1848  ffffffff 00000000 S /system/bin/keystore
-radio     198   1     18856  636   ffffffff 00000000 S /system/bin/bridgemgrd
-radio     288   198   18856  636   ffffffff 00000000 S bridgemgrd
-radio     602   198   18856  636   ffffffff 00000000 S bridgemgrd
-radio     603   198   18856  636   ffffffff 00000000 S bridgemgrd
-radio     841   198   18856  636   ffffffff 00000000 S bridgemgrd
-radio     199   1     24060  732   ffffffff 00000000 S /system/bin/qmuxd
-radio     293   199   24060  732   ffffffff 00000000 S qmuxd
-radio     576   199   24060  732   ffffffff 00000000 S qmuxd
-radio     577   199   24060  732   ffffffff 00000000 S qmuxd
-radio     578   199   24060  732   ffffffff 00000000 S qmuxd
-radio     579   199   24060  732   ffffffff 00000000 S qmuxd
-radio     580   199   24060  732   ffffffff 00000000 S qmuxd
-radio     581   199   24060  732   ffffffff 00000000 S qmuxd
-radio     582   199   24060  732   ffffffff 00000000 S qmuxd
-radio     583   199   24060  732   ffffffff 00000000 S qmuxd
-radio     200   1     20036  996   ffffffff 00000000 S /system/bin/netmgrd
-radio     289   200   20036  996   ffffffff 00000000 S netmgrd
-radio     736   200   20036  996   ffffffff 00000000 S netmgrd
-radio     746   200   20036  996   ffffffff 00000000 S netmgrd
-radio     747   200   20036  996   ffffffff 00000000 S netmgrd
-radio     748   200   20036  996   ffffffff 00000000 S netmgrd
-nobody    201   1     59912  1748  ffffffff 00000000 S /system/bin/sensors.qcom
-nobody    290   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    292   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    560   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    563   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    564   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    605   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    614   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    621   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    622   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    623   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    624   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    625   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    626   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    627   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    628   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    629   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    633   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    643   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    650   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    651   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    760   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    763   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    784   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    790   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    792   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    794   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    796   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    798   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    800   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    802   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    804   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    806   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    808   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    810   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    812   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    814   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    816   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    818   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    820   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    822   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    824   201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    1593  201   59912  1748  ffffffff 00000000 S sensors.qcom
-nobody    1600  201   59912  1748  ffffffff 00000000 S sensors.qcom
-root      204   1     58772  1524  ffffffff 00000000 S /system/bin/thermal-engine-hh
-root      247   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      250   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      252   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      253   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      254   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      255   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      257   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      258   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      259   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      260   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      261   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      262   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      263   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      264   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      265   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      266   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      267   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      268   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      269   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      270   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      272   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      273   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      275   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      276   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      277   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      278   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      280   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      281   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      282   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      283   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      284   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      286   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      287   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      295   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      297   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      299   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      300   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      301   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      559   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      596   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      600   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      601   204   58772  1524  ffffffff 00000000 S thermal-engine-
-root      205   1     1482684 53160 ffffffff 00000000 S zygote
-root      14357 205   1482684 53160 ffffffff 00000000 S ReferenceQueueD
-root      14358 205   1482684 53160 ffffffff 00000000 S FinalizerDaemon
-root      14359 205   1482684 53160 ffffffff 00000000 S FinalizerWatchd
-root      14360 205   1482684 53160 ffffffff 00000000 S HeapTrimmerDaem
-root      14361 205   1482684 53160 ffffffff 00000000 S GCDaemon
-media_rw  206   1     15400  5240  ffffffff 00000000 S /system/bin/sdcard
-media_rw  227   206   15400  5240  ffffffff 00000000 S sdcard
-media_rw  228   206   15400  5240  ffffffff 00000000 S sdcard
-camera    207   1     16300  4440  ffffffff 00000000 S /system/bin/mm-qcamera-daemon
-system    208   1     20500  1236  ffffffff 00000000 S /system/bin/time_daemon
-system    308   208   20500  1236  ffffffff 00000000 S time_daemon
-system    561   208   20500  1236  ffffffff 00000000 S time_daemon
-system    597   208   20500  1236  ffffffff 00000000 S time_daemon
-system    598   208   20500  1236  ffffffff 00000000 S time_daemon
-system    599   208   20500  1236  ffffffff 00000000 S time_daemon
-shell     209   1     16984  312   ffffffff 00000000 S /sbin/adbd
-shell     210   209   16984  312   ffffffff 00000000 S adbd
-shell     211   209   16984  312   ffffffff 00000000 S adbd
-shell     212   209   16984  308   ffffffff 00000000 S adbd
-shell     14445 209   16984  308   ffffffff 00000000 S adbd
-root      214   2     0      0     ffffffff 00000000 S irq/288-wcd9xxx
-root      219   2     0      0     ffffffff 00000000 S kauditd
-root      311   2     0      0     ffffffff 00000000 D msm_thermal:hot
-root      312   2     0      0     ffffffff 00000000 D msm_thermal:fre
-system    348   182   15288  564   ffffffff 00000000 S /system/bin/qseecomd
-system    349   348   15288  564   ffffffff 00000000 S qseecomd
-system    351   348   15288  564   ffffffff 00000000 S qseecomd
-system    386   348   15288  564   ffffffff 00000000 S qseecomd
-system    387   348   15288  564   ffffffff 00000000 S qseecomd
-root      360   2     0      0     ffffffff 00000000 D mdss_fb0
-root      557   2     0      0     ffffffff 00000000 S kworker/0:2H
-root      558   2     0      0     ffffffff 00000000 S IPCRTR
-root      562   2     0      0     ffffffff 00000000 S ipc_rtr_smd_ipc
-system    764   205   1701620 103200 ffffffff 00000000 S system_server
-system    767   764   1701620 103200 ffffffff 00000000 S Heap thread poo
-system    768   764   1701620 103200 ffffffff 00000000 S Heap thread poo
-system    770   764   1701620 103200 ffffffff 00000000 S Heap thread poo
-system    773   764   1701620 103200 ffffffff 00000000 S Signal Catcher
-system    774   764   1701620 103200 ffffffff 00000000 S JDWP
-system    775   764   1701620 103200 ffffffff 00000000 S ReferenceQueueD
-system    776   764   1701620 103200 ffffffff 00000000 S FinalizerDaemon
-system    777   764   1701620 103200 ffffffff 00000000 S FinalizerWatchd
-system    778   764   1701620 103200 ffffffff 00000000 S HeapTrimmerDaem
-system    779   764   1701620 103200 ffffffff 00000000 S GCDaemon
-system    780   764   1701620 103200 ffffffff 00000000 S Binder_1
-system    781   764   1701620 103200 ffffffff 00000000 S Binder_2
-system    782   764   1701620 103200 ffffffff 00000000 S system_server
-system    783   764   1701620 103200 ffffffff 00000000 S system_server
-system    785   764   1701620 103200 ffffffff 00000000 S system_server
-system    786   764   1701620 103200 ffffffff 00000000 S system_server
-system    788   764   1701620 103200 ffffffff 00000000 S system_server
-system    789   764   1701620 103200 ffffffff 00000000 S system_server
-system    791   764   1701620 103200 ffffffff 00000000 S system_server
-system    793   764   1701620 103200 ffffffff 00000000 S system_server
-system    795   764   1701620 103200 ffffffff 00000000 S system_server
-system    797   764   1701620 103200 ffffffff 00000000 S system_server
-system    799   764   1701620 103200 ffffffff 00000000 S system_server
-system    801   764   1701620 103200 ffffffff 00000000 S system_server
-system    803   764   1701620 103200 ffffffff 00000000 S system_server
-system    805   764   1701620 103200 ffffffff 00000000 S system_server
-system    807   764   1701620 103200 ffffffff 00000000 S system_server
-system    809   764   1701620 103200 ffffffff 00000000 S system_server
-system    811   764   1701620 103200 ffffffff 00000000 S system_server
-system    813   764   1701620 103200 ffffffff 00000000 S system_server
-system    815   764   1701620 103200 ffffffff 00000000 S system_server
-system    817   764   1701620 103200 ffffffff 00000000 S system_server
-system    819   764   1701620 103200 ffffffff 00000000 S system_server
-system    821   764   1701620 103200 ffffffff 00000000 S system_server
-system    823   764   1701620 103200 ffffffff 00000000 S system_server
-system    826   764   1701620 103200 ffffffff 00000000 S SensorEventAckR
-system    827   764   1701620 103200 ffffffff 00000000 S SensorService
-system    828   764   1701620 103200 ffffffff 00000000 S android.bg
-system    829   764   1701620 103200 ffffffff 00000000 S ActivityManager
-system    830   764   1701620 103200 ffffffff 00000000 S FileObserver
-system    831   764   1701620 103200 ffffffff 00000000 S android.fg
-system    832   764   1701620 103200 ffffffff 00000000 S android.ui
-system    833   764   1701620 103200 ffffffff 00000000 S android.io
-system    834   764   1701620 103200 ffffffff 00000000 S android.display
-system    835   764   1701620 103200 ffffffff 00000000 S CpuTracker
-system    836   764   1701620 103200 ffffffff 00000000 S PowerManagerSer
-system    837   764   1701620 103200 ffffffff 00000000 S system_server
-system    838   764   1701620 103200 ffffffff 00000000 S system_server
-system    839   764   1701620 103200 ffffffff 00000000 S BatteryStats_wa
-system    840   764   1701620 103200 ffffffff 00000000 S PackageManager
-system    842   764   1701620 103200 ffffffff 00000000 S PackageInstalle
-system    844   764   1701620 103200 ffffffff 00000000 S AlarmManager
-system    845   764   1701620 103200 ffffffff 00000000 S UEventObserver
-system    853   764   1701620 103200 ffffffff 00000000 S InputDispatcher
-system    854   764   1701620 103200 ffffffff 00000000 S InputReader
-system    857   764   1701620 103200 ffffffff 00000000 S MountService
-system    858   764   1701620 103200 ffffffff 00000000 S VoldConnector
-system    860   764   1701620 103200 ffffffff 00000000 S NetdConnector
-system    861   764   1701620 103200 ffffffff 00000000 S NetworkStats
-system    862   764   1701620 103200 ffffffff 00000000 S NetworkPolicy
-system    863   764   1701620 103200 ffffffff 00000000 S WifiP2pService
-system    864   764   1701620 103200 ffffffff 00000000 S WifiStateMachin
-system    865   764   1701620 103200 ffffffff 00000000 S WifiService
-system    866   764   1701620 103200 ffffffff 00000000 S ConnectivitySer
-system    867   764   1701620 103200 ffffffff 00000000 S NsdService
-system    868   764   1701620 103200 ffffffff 00000000 S mDnsConnector
-system    869   764   1701620 103200 ffffffff 00000000 S ranker
-system    870   764   1701620 103200 ffffffff 00000000 S AudioService
-system    882   764   1701620 103200 ffffffff 00000000 S WifiWatchdogSta
-system    883   764   1701620 103200 ffffffff 00000000 S WifiManager
-system    884   764   1701620 103200 ffffffff 00000000 S WifiScanningSer
-system    885   764   1701620 103200 ffffffff 00000000 S WifiRttService
-system    886   764   1701620 103200 ffffffff 00000000 S EthernetService
-system    887   764   1701620 103200 ffffffff 00000000 S backup
-system    889   764   1701620 103200 ffffffff 00000000 S Thread-69
-system    892   764   1701620 103200 ffffffff 00000000 S LazyTaskWriterT
-system    893   764   1701620 103200 ffffffff 00000000 S UsbService host
-system    894   764   1701620 103200 ffffffff 00000000 S Thread-73
-system    942   764   1701620 103200 ffffffff 00000000 S Binder_3
-system    1079  764   1701620 103200 ffffffff 00000000 S watchdog
-system    1094  764   1701620 103200 ffffffff 00000000 S SoundPool
-system    1095  764   1701620 103200 ffffffff 00000000 S SoundPoolThread
-system    1108  764   1701620 103200 ffffffff 00000000 S Binder_4
-system    1109  764   1701620 103200 ffffffff 00000000 S Binder_5
-system    1186  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1188  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1191  764   1701620 103200 ffffffff 00000000 S NetworkTimeUpda
-system    1192  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1226  764   1701620 103200 ffffffff 00000000 S Binder_6
-system    1233  764   1701620 103200 ffffffff 00000000 S Binder_7
-system    1247  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1256  764   1701620 103200 ffffffff 00000000 S Binder_8
-system    1260  764   1701620 103200 ffffffff 00000000 S WifiMonitor
-system    1271  764   1701620 103200 ffffffff 00000000 S Binder_9
-system    1288  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1289  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1319  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1320  764   1701620 103200 ffffffff 00000000 S FLP Service Cal
-system    1367  764   1701620 103200 ffffffff 00000000 S Thread-89
-system    1391  764   1701620 103200 ffffffff 00000000 S AsyncQueryWorke
-system    1654  764   1701620 103200 ffffffff 00000000 S Binder_A
-system    1693  764   1701620 103200 ffffffff 00000000 S NetworkMonitorN
-system    1695  764   1701620 103200 ffffffff 00000000 S DhcpStateMachin
-system    1781  764   1701620 103200 ffffffff 00000000 S AsyncTask #1
-system    1782  764   1701620 103200 ffffffff 00000000 S AsyncTask #2
-system    2097  764   1701620 103200 ffffffff 00000000 S AsyncTask #3
-system    2124  764   1701620 103200 ffffffff 00000000 S SyncHandler-0
-system    2905  764   1701620 103200 ffffffff 00000000 S PowerManagerSer
-system    4226  764   1701620 103200 ffffffff 00000000 S AsyncTask #4
-system    4265  764   1701620 103200 ffffffff 00000000 S UsbDebuggingMan
-system    5717  764   1701620 103200 ffffffff 00000000 S GL updater
-system    6709  764   1701620 103200 ffffffff 00000000 S Binder_B
-wifi      888   1     12568  2672  ffffffff 00000000 S /system/bin/wpa_supplicant
-u0_a20    915   205   1616624 108684 ffffffff 00000000 S com.android.systemui
-u0_a20    919   915   1616624 108684 ffffffff 00000000 S Heap thread poo
-u0_a20    920   915   1616624 108684 ffffffff 00000000 S Heap thread poo
-u0_a20    921   915   1616624 108684 ffffffff 00000000 S Heap thread poo
-u0_a20    925   915   1616624 108684 ffffffff 00000000 S Signal Catcher
-u0_a20    926   915   1616624 108684 ffffffff 00000000 S JDWP
-u0_a20    927   915   1616624 108684 ffffffff 00000000 S ReferenceQueueD
-u0_a20    928   915   1616624 108684 ffffffff 00000000 S FinalizerDaemon
-u0_a20    929   915   1616624 108684 ffffffff 00000000 S FinalizerWatchd
-u0_a20    930   915   1616624 108684 ffffffff 00000000 S HeapTrimmerDaem
-u0_a20    931   915   1616624 108684 ffffffff 00000000 S GCDaemon
-u0_a20    933   915   1616624 108684 ffffffff 00000000 S Binder_1
-u0_a20    934   915   1616624 108684 ffffffff 00000000 S Binder_2
-u0_a20    964   915   1616624 108684 ffffffff 00000000 S SoundPool
-u0_a20    965   915   1616624 108684 ffffffff 00000000 S SoundPoolThread
-u0_a20    970   915   1616624 108684 ffffffff 00000000 S Recents-TaskRes
-u0_a20    1078  915   1616624 108684 ffffffff 00000000 S SystemUI Storag
-u0_a20    1378  915   1616624 108684 ffffffff 00000000 S PhoneStatusBar
-u0_a20    1381  915   1616624 108684 ffffffff 00000000 S WifiManager
-u0_a20    1416  915   1616624 108684 ffffffff 00000000 S ConnectivityMan
-u0_a20    1428  915   1616624 108684 ffffffff 00000000 S Binder_3
-u0_a20    1431  915   1616624 108684 ffffffff 00000000 S FlashlightContr
-u0_a20    1434  915   1616624 108684 ffffffff 00000000 S AsyncTask #1
-u0_a20    1435  915   1616624 108684 ffffffff 00000000 S QSTileHost
-u0_a20    1438  915   1616624 108684 ffffffff 00000000 S AsyncTask #2
-u0_a20    1441  915   1616624 108684 ffffffff 00000000 S RenderThread
-u0_a20    1442  915   1616624 108684 ffffffff 00000000 S AsyncTask #3
-u0_a20    1565  915   1616624 108684 ffffffff 00000000 S hwuiTask1
-u0_a20    1566  915   1616624 108684 ffffffff 00000000 S hwuiTask2
-u0_a20    1637  915   1616624 108684 ffffffff 00000000 S AsyncTask #4
-u0_a20    1692  915   1616624 108684 ffffffff 00000000 S GL updater
-u0_a20    1807  915   1616624 108684 ffffffff 00000000 S RenderThread
-u0_a20    4480  915   1616624 108684 ffffffff 00000000 S Binder_4
-u0_a6     936   205   1506908 56892 ffffffff 00000000 S android.process.media
-u0_a6     943   936   1506908 56892 ffffffff 00000000 S Heap thread poo
-u0_a6     944   936   1506908 56892 ffffffff 00000000 S Heap thread poo
-u0_a6     945   936   1506908 56892 ffffffff 00000000 S Heap thread poo
-u0_a6     947   936   1506908 56892 ffffffff 00000000 S Signal Catcher
-u0_a6     949   936   1506908 56892 ffffffff 00000000 S JDWP
-u0_a6     950   936   1506908 56892 ffffffff 00000000 S ReferenceQueueD
-u0_a6     951   936   1506908 56892 ffffffff 00000000 S FinalizerDaemon
-u0_a6     952   936   1506908 56892 ffffffff 00000000 S FinalizerWatchd
-u0_a6     953   936   1506908 56892 ffffffff 00000000 S HeapTrimmerDaem
-u0_a6     954   936   1506908 56892 ffffffff 00000000 S GCDaemon
-u0_a6     956   936   1506908 56892 ffffffff 00000000 S Binder_1
-u0_a6     957   936   1506908 56892 ffffffff 00000000 S Binder_2
-u0_a6     1007  936   1506908 56892 ffffffff 00000000 S thumbs thread
-u0_a6     1020  936   1506908 56892 ffffffff 00000000 S MtpServer
-u0_a6     2810  936   1506908 56892 ffffffff 00000000 S DownloadReceive
-u0_a6     4917  936   1506908 56892 ffffffff 00000000 S Binder_3
-u0_a6     5816  936   1506908 56892 ffffffff 00000000 S Binder_4
-u0_a6     8575  936   1506908 56892 ffffffff 00000000 S Binder_5
-u0_a22    1111  205   1526156 42532 ffffffff 00000000 S com.google.android.googlequicksearchbox:interactor
-u0_a22    1113  1111  1526156 42532 ffffffff 00000000 S Heap thread poo
-u0_a22    1114  1111  1526156 42532 ffffffff 00000000 S Heap thread poo
-u0_a22    1116  1111  1526156 42532 ffffffff 00000000 S Heap thread poo
-u0_a22    1121  1111  1526156 42532 ffffffff 00000000 S Signal Catcher
-u0_a22    1124  1111  1526156 42532 ffffffff 00000000 S JDWP
-u0_a22    1125  1111  1526156 42532 ffffffff 00000000 S ReferenceQueueD
-u0_a22    1126  1111  1526156 42532 ffffffff 00000000 S FinalizerDaemon
-u0_a22    1127  1111  1526156 42532 ffffffff 00000000 S FinalizerWatchd
-u0_a22    1128  1111  1526156 42532 ffffffff 00000000 S HeapTrimmerDaem
-u0_a22    1129  1111  1526156 42532 ffffffff 00000000 S GCDaemon
-u0_a22    1131  1111  1526156 42532 ffffffff 00000000 S Binder_1
-u0_a22    1132  1111  1526156 42532 ffffffff 00000000 S Binder_2
-u0_a22    1561  1111  1526156 42532 ffffffff 00000000 S AsyncTask #1
-u0_a51    1136  205   1515064 46788 ffffffff 00000000 S com.google.android.inputmethod.pinyin
-u0_a51    1142  1136  1515064 46788 ffffffff 00000000 S Heap thread poo
-u0_a51    1143  1136  1515064 46788 ffffffff 00000000 S Heap thread poo
-u0_a51    1144  1136  1515064 46788 ffffffff 00000000 S Heap thread poo
-u0_a51    1145  1136  1515064 46788 ffffffff 00000000 S Signal Catcher
-u0_a51    1146  1136  1515064 46788 ffffffff 00000000 S JDWP
-u0_a51    1147  1136  1515064 46788 ffffffff 00000000 S ReferenceQueueD
-u0_a51    1148  1136  1515064 46788 ffffffff 00000000 S FinalizerDaemon
-u0_a51    1149  1136  1515064 46788 ffffffff 00000000 S FinalizerWatchd
-u0_a51    1151  1136  1515064 46788 ffffffff 00000000 S HeapTrimmerDaem
-u0_a51    1152  1136  1515064 46788 ffffffff 00000000 S GCDaemon
-u0_a51    1153  1136  1515064 46788 ffffffff 00000000 S Binder_1
-u0_a51    1154  1136  1515064 46788 ffffffff 00000000 S Binder_2
-u0_a51    1330  1136  1515064 46788 ffffffff 00000000 S GAThread
-u0_a51    1331  1136  1515064 46788 ffffffff 00000000 S measurement-1
-u0_a51    1336  1136  1515064 46788 ffffffff 00000000 S pool-1-thread-1
-u0_a51    1503  1136  1515064 46788 ffffffff 00000000 S AsyncTask #1
-u0_a51    1622  1136  1515064 46788 ffffffff 00000000 S AsyncTask #2
-nfc       1199  205   1511808 46336 ffffffff 00000000 S com.android.nfc
-nfc       1208  1199  1511808 46336 ffffffff 00000000 S Heap thread poo
-nfc       1209  1199  1511808 46336 ffffffff 00000000 S Heap thread poo
-nfc       1210  1199  1511808 46336 ffffffff 00000000 S Heap thread poo
-nfc       1211  1199  1511808 46336 ffffffff 00000000 S Signal Catcher
-nfc       1212  1199  1511808 46336 ffffffff 00000000 S JDWP
-nfc       1213  1199  1511808 46336 ffffffff 00000000 S ReferenceQueueD
-nfc       1214  1199  1511808 46336 ffffffff 00000000 S FinalizerDaemon
-nfc       1215  1199  1511808 46336 ffffffff 00000000 S FinalizerWatchd
-nfc       1216  1199  1511808 46336 ffffffff 00000000 S HeapTrimmerDaem
-nfc       1219  1199  1511808 46336 ffffffff 00000000 S GCDaemon
-nfc       1220  1199  1511808 46336 ffffffff 00000000 S Binder_1
-nfc       1221  1199  1511808 46336 ffffffff 00000000 S Binder_2
-nfc       1385  1199  1511808 46336 ffffffff 00000000 S AsyncTask #1
-nfc       1388  1199  1511808 46336 ffffffff 00000000 S AsyncTask #1
-nfc       1393  1199  1511808 46336 ffffffff 00000000 S AsyncTask #1
-nfc       1408  1199  1511808 46336 ffffffff 00000000 S AsyncTask #1
-nfc       1409  1199  1511808 46336 ffffffff 00000000 S AsyncTask #1
-nfc       1425  1199  1511808 46336 ffffffff 00000000 S AsyncTask #1
-nfc       1573  1199  1511808 46336 ffffffff 00000000 S Thread-55
-nfc       1574  1199  1511808 46336 ffffffff 00000000 S Thread-56
-nfc       1575  1199  1511808 46336 ffffffff 00000000 S Thread-57
-nfc       1577  1199  1511808 46336 ffffffff 00000000 S SoundPool
-nfc       1578  1199  1511808 46336 ffffffff 00000000 S SoundPoolThread
-nfc       2906  1199  1511808 46336 ffffffff 00000000 S AsyncTask #2
-nfc       2915  1199  1511808 46336 ffffffff 00000000 S AsyncTask #3
-nfc       5610  1199  1511808 46336 ffffffff 00000000 S AsyncTask #4
-nfc       5719  1199  1511808 46336 ffffffff 00000000 S AsyncTask #5
-radio     1234  205   1493064 38832 ffffffff 00000000 S com.redbend.vdmc
-radio     1236  1234  1493064 38832 ffffffff 00000000 S Heap thread poo
-radio     1237  1234  1493064 38832 ffffffff 00000000 S Heap thread poo
-radio     1238  1234  1493064 38832 ffffffff 00000000 S Heap thread poo
-radio     1244  1234  1493064 38832 ffffffff 00000000 S Signal Catcher
-radio     1245  1234  1493064 38832 ffffffff 00000000 S JDWP
-radio     1246  1234  1493064 38832 ffffffff 00000000 S ReferenceQueueD
-radio     1248  1234  1493064 38832 ffffffff 00000000 S FinalizerDaemon
-radio     1249  1234  1493064 38832 ffffffff 00000000 S FinalizerWatchd
-radio     1250  1234  1493064 38832 ffffffff 00000000 S HeapTrimmerDaem
-radio     1251  1234  1493064 38832 ffffffff 00000000 S GCDaemon
-radio     1252  1234  1493064 38832 ffffffff 00000000 S Binder_1
-radio     1257  1234  1493064 38832 ffffffff 00000000 S Binder_2
-radio     1274  205   1525408 58916 ffffffff 00000000 S com.android.phone
-radio     1282  1274  1525408 58916 ffffffff 00000000 S Heap thread poo
-radio     1283  1274  1525408 58916 ffffffff 00000000 S Heap thread poo
-radio     1284  1274  1525408 58916 ffffffff 00000000 S Heap thread poo
-radio     1285  1274  1525408 58916 ffffffff 00000000 S Signal Catcher
-radio     1286  1274  1525408 58916 ffffffff 00000000 S JDWP
-radio     1287  1274  1525408 58916 ffffffff 00000000 S ReferenceQueueD
-radio     1290  1274  1525408 58916 ffffffff 00000000 S FinalizerDaemon
-radio     1291  1274  1525408 58916 ffffffff 00000000 S FinalizerWatchd
-radio     1292  1274  1525408 58916 ffffffff 00000000 S HeapTrimmerDaem
-radio     1293  1274  1525408 58916 ffffffff 00000000 S GCDaemon
-radio     1299  1274  1525408 58916 ffffffff 00000000 S Binder_1
-radio     1315  1274  1525408 58916 ffffffff 00000000 S Binder_2
-radio     1365  1274  1525408 58916 ffffffff 00000000 S RILSender0
-radio     1366  1274  1525408 58916 ffffffff 00000000 S RILReceiver0
-radio     1380  1274  1525408 58916 ffffffff 00000000 S DcHandlerThread
-radio     1392  1274  1525408 58916 ffffffff 00000000 S GsmCellBroadcas
-radio     1394  1274  1525408 58916 ffffffff 00000000 S GsmInboundSmsHa
-radio     1397  1274  1525408 58916 ffffffff 00000000 S CellBroadcastHa
-radio     1417  1274  1525408 58916 ffffffff 00000000 S CdmaInboundSmsH
-radio     1418  1274  1525408 58916 ffffffff 00000000 S CdmaServiceCate
-radio     1427  1274  1525408 58916 ffffffff 00000000 S DcSwitchStateMa
-radio     1429  1274  1525408 58916 ffffffff 00000000 S SyncHandler-0
-radio     1443  1274  1525408 58916 ffffffff 00000000 S AsyncTask #1
-radio     1473  1274  1525408 58916 ffffffff 00000000 S Binder_3
-radio     1517  1274  1525408 58916 ffffffff 00000000 S ervice.Executor
-radio     1518  1274  1525408 58916 ffffffff 00000000 S WifiManager
-radio     1563  1274  1525408 58916 ffffffff 00000000 S Cat Telephony s
-radio     1564  1274  1525408 58916 ffffffff 00000000 S RilMessageDecod
-radio     1567  1274  1525408 58916 ffffffff 00000000 S Cat Icon Loader
-radio     1690  1274  1525408 58916 ffffffff 00000000 S Binder_4
-radio     4571  1274  1525408 58916 ffffffff 00000000 S Stk App Service
-u0_a22    1305  205   1674592 127012 ffffffff 00000000 S com.google.android.googlequicksearchbox
-u0_a22    1306  1305  1674592 127012 ffffffff 00000000 S Heap thread poo
-u0_a22    1307  1305  1674592 127012 ffffffff 00000000 S Heap thread poo
-u0_a22    1308  1305  1674592 127012 ffffffff 00000000 S Heap thread poo
-u0_a22    1317  1305  1674592 127012 ffffffff 00000000 S Signal Catcher
-u0_a22    1318  1305  1674592 127012 ffffffff 00000000 S JDWP
-u0_a22    1322  1305  1674592 127012 ffffffff 00000000 S ReferenceQueueD
-u0_a22    1323  1305  1674592 127012 ffffffff 00000000 S FinalizerDaemon
-u0_a22    1324  1305  1674592 127012 ffffffff 00000000 S FinalizerWatchd
-u0_a22    1332  1305  1674592 127012 ffffffff 00000000 S HeapTrimmerDaem
-u0_a22    1333  1305  1674592 127012 ffffffff 00000000 S GCDaemon
-u0_a22    1334  1305  1674592 127012 ffffffff 00000000 S Binder_1
-u0_a22    1335  1305  1674592 127012 ffffffff 00000000 S Binder_2
-u0_a22    1386  1305  1674592 127012 ffffffff 00000000 S launcher-loader
-u0_a22    1395  1305  1674592 127012 ffffffff 00000000 S AsyncTask #1
-u0_a22    1432  1305  1674592 127012 ffffffff 00000000 S AsyncTask #2
-u0_a22    1484  1305  1674592 127012 ffffffff 00000000 S GELServices-0
-u0_a22    1514  1305  1674592 127012 ffffffff 00000000 S RenderThread
-u0_a22    1540  1305  1674592 127012 ffffffff 00000000 S AsyncTask #3
-u0_a22    1618  1305  1674592 127012 ffffffff 00000000 S GELServices-1
-u0_a22    1621  1305  1674592 127012 ffffffff 00000000 S GELServices-2
-u0_a22    1629  1305  1674592 127012 ffffffff 00000000 S GELServices-3
-u0_a22    1632  1305  1674592 127012 ffffffff 00000000 S AsyncTask #4
-u0_a22    1633  1305  1674592 127012 ffffffff 00000000 S AsyncTask #5
-u0_a22    1636  1305  1674592 127012 ffffffff 00000000 S GELServices-4
-u0_a22    1644  1305  1674592 127012 ffffffff 00000000 S GL updater
-u0_a22    1647  1305  1674592 127012 ffffffff 00000000 S GELServices-5
-u0_a22    1664  1305  1674592 127012 ffffffff 00000000 S GELServices-6
-u0_a22    1764  1305  1674592 127012 ffffffff 00000000 S Binder_3
-u0_a22    1766  1305  1674592 127012 ffffffff 00000000 S GELServices-7
-u0_a22    1772  1305  1674592 127012 ffffffff 00000000 S RenderThread
-u0_a22    1773  1305  1674592 127012 ffffffff 00000000 S RenderThread
-u0_a22    1774  1305  1674592 127012 ffffffff 00000000 S RenderThread
-u0_a22    1775  1305  1674592 127012 ffffffff 00000000 S RenderThread
-u0_a22    1998  1305  1674592 127012 ffffffff 00000000 S GELServices-8
-u0_a22    2320  1305  1674592 127012 ffffffff 00000000 S RemoteViewsCach
-u0_a22    2321  1305  1674592 127012 ffffffff 00000000 S RemoteViewsAdap
-u0_a22    2902  1305  1674592 127012 ffffffff 00000000 S GELServices-9
-u0_a22    1451  205   1584512 87716 ffffffff 00000000 S com.google.android.googlequicksearchbox:search
-u0_a22    1457  1451  1584512 87716 ffffffff 00000000 S Heap thread poo
-u0_a22    1458  1451  1584512 87716 ffffffff 00000000 S Heap thread poo
-u0_a22    1459  1451  1584512 87716 ffffffff 00000000 S Heap thread poo
-u0_a22    1460  1451  1584512 87716 ffffffff 00000000 S Signal Catcher
-u0_a22    1461  1451  1584512 87716 ffffffff 00000000 S JDWP
-u0_a22    1462  1451  1584512 87716 ffffffff 00000000 S ReferenceQueueD
-u0_a22    1463  1451  1584512 87716 ffffffff 00000000 S FinalizerDaemon
-u0_a22    1464  1451  1584512 87716 ffffffff 00000000 S FinalizerWatchd
-u0_a22    1466  1451  1584512 87716 ffffffff 00000000 S HeapTrimmerDaem
-u0_a22    1468  1451  1584512 87716 ffffffff 00000000 S GCDaemon
-u0_a22    1474  1451  1584512 87716 ffffffff 00000000 S Binder_1
-u0_a22    1475  1451  1584512 87716 ffffffff 00000000 S Binder_2
-u0_a22    1515  1451  1584512 87716 ffffffff 00000000 S User-Facing Non
-u0_a22    1516  1451  1584512 87716 ffffffff 00000000 S User-Facing Non
-u0_a22    1535  1451  1584512 87716 ffffffff 00000000 S User-Facing Non
-u0_a22    1538  1451  1584512 87716 ffffffff 00000000 S User-Facing Non
-u0_a22    1553  1451  1584512 87716 ffffffff 00000000 S User-Facing Non
-u0_a22    1560  1451  1584512 87716 ffffffff 00000000 S IcingConnection
-u0_a22    1580  1451  1584512 87716 ffffffff 00000000 S AudioRouter-0
-u0_a22    1626  1451  1584512 87716 ffffffff 00000000 S AsyncFileStorag
-u0_a22    1635  1451  1584512 87716 ffffffff 00000000 S WifiManager
-u0_a22    1643  1451  1584512 87716 ffffffff 00000000 S LocationOracleI
-u0_a22    1646  1451  1584512 87716 ffffffff 00000000 S GoogleApiClient
-u0_a22    1769  1451  1584512 87716 ffffffff 00000000 S Binder_3
-u0_a22    1770  1451  1584512 87716 ffffffff 00000000 S Gservices
-u0_a22    1810  1451  1584512 87716 ffffffff 00000000 S ChromiumNet
-u0_a22    1811  1451  1584512 87716 ffffffff 00000000 S DnsConfigServic
-u0_a22    1812  1451  1584512 87716 ffffffff 00000000 S inotify_reader
-u0_a22    1815  1451  1584512 87716 ffffffff 00000000 S Network File Th
-u0_a22    1816  1451  1584512 87716 ffffffff 00000000 S SimpleCacheWork
-u0_a22    1817  1451  1584512 87716 ffffffff 00000000 S SimpleCacheWork
-u0_a22    1823  1451  1584512 87716 ffffffff 00000000 S Binder_4
-u0_a22    1824  1451  1584512 87716 ffffffff 00000000 S Binder_5
-u0_a22    12193 1451  1584512 87716 ffffffff 00000000 S Background Bloc
-u0_a22    12207 1451  1584512 87716 ffffffff 00000000 S User-Facing Blo
-u0_a22    12211 1451  1584512 87716 ffffffff 00000000 S WorkerPool/1221
-u0_a22    12232 1451  1584512 87716 ffffffff 00000000 S Background Non-
-u0_a22    12235 1451  1584512 87716 ffffffff 00000000 S Background Bloc
-u0_a22    12236 1451  1584512 87716 ffffffff 00000000 S Background Bloc
-u0_a22    12237 1451  1584512 87716 ffffffff 00000000 S Background Non-
-u0_a8     1478  205   1613496 72932 ffffffff 00000000 S com.google.process.gapps
-u0_a8     1485  1478  1613496 72932 ffffffff 00000000 S Heap thread poo
-u0_a8     1486  1478  1613496 72932 ffffffff 00000000 S Heap thread poo
-u0_a8     1487  1478  1613496 72932 ffffffff 00000000 S Heap thread poo
-u0_a8     1488  1478  1613496 72932 ffffffff 00000000 S Signal Catcher
-u0_a8     1489  1478  1613496 72932 ffffffff 00000000 S JDWP
-u0_a8     1490  1478  1613496 72932 ffffffff 00000000 S ReferenceQueueD
-u0_a8     1491  1478  1613496 72932 ffffffff 00000000 S FinalizerDaemon
-u0_a8     1492  1478  1613496 72932 ffffffff 00000000 S FinalizerWatchd
-u0_a8     1493  1478  1613496 72932 ffffffff 00000000 S HeapTrimmerDaem
-u0_a8     1494  1478  1613496 72932 ffffffff 00000000 S GCDaemon
-u0_a8     1495  1478  1613496 72932 ffffffff 00000000 S Binder_1
-u0_a8     1496  1478  1613496 72932 ffffffff 00000000 S Binder_2
-u0_a8     1497  1478  1613496 72932 ffffffff 00000000 S Binder_3
-u0_a8     1613  1478  1613496 72932 ffffffff 00000000 S Gservices
-u0_a8     1614  1478  1613496 72932 ffffffff 00000000 S RefQueueWorker@
-u0_a8     1615  1478  1613496 72932 ffffffff 00000000 S Gservices
-u0_a8     1616  1478  1613496 72932 ffffffff 00000000 S RefQueueWorker@
-u0_a8     1620  1478  1613496 72932 ffffffff 00000000 S Gservices
-u0_a8     1996  1478  1613496 72932 ffffffff 00000000 S Binder_4
-u0_a8     1997  1478  1613496 72932 ffffffff 00000000 S Binder_5
-u0_a8     2510  1478  1613496 72932 ffffffff 00000000 S GCMWriter
-u0_a8     2512  1478  1613496 72932 ffffffff 00000000 S AsyncTask #1
-u0_a8     2536  1478  1613496 72932 ffffffff 00000000 S GCMReader
-u0_a8     2547  1478  1613496 72932 ffffffff 00000000 S pool-2-thread-1
-u0_a8     3680  1478  1613496 72932 ffffffff 00000000 S WifiManager
-u0_a8     4135  1478  1613496 72932 ffffffff 00000000 S AsyncTask #2
-u0_a8     4159  1478  1613496 72932 ffffffff 00000000 S AsyncTask #3
-u0_a8     4184  1478  1613496 72932 ffffffff 00000000 S AsyncTask #4
-u0_a8     4210  1478  1613496 72932 ffffffff 00000000 S AsyncTask #5
-u0_a8     4541  1478  1613496 72932 ffffffff 00000000 S RefQueueWorker@
-u0_a8     4735  1478  1613496 72932 ffffffff 00000000 S pool-8-thread-1
-u0_a8     4770  1478  1613496 72932 ffffffff 00000000 S Binder_6
-u0_a8     12448 1478  1613496 72932 ffffffff 00000000 S OkHttp Connecti
-u0_a8     14401 1478  1613496 72932 ffffffff 00000000 S Thread-233
-u0_a8     14409 1478  1613496 72932 ffffffff 00000000 S OkHttp Connecti
-dhcp      1700  1     9344   756   ffffffff 00000000 S /system/bin/dhcpcd
-u0_a8     1873  205   1756828 84724 ffffffff 00000000 S com.google.android.gms
-u0_a8     1878  1873  1756828 84724 ffffffff 00000000 S Heap thread poo
-u0_a8     1880  1873  1756828 84724 ffffffff 00000000 S Heap thread poo
-u0_a8     1881  1873  1756828 84724 ffffffff 00000000 S Heap thread poo
-u0_a8     1882  1873  1756828 84724 ffffffff 00000000 S Signal Catcher
-u0_a8     1883  1873  1756828 84724 ffffffff 00000000 S JDWP
-u0_a8     1884  1873  1756828 84724 ffffffff 00000000 S ReferenceQueueD
-u0_a8     1885  1873  1756828 84724 ffffffff 00000000 S FinalizerDaemon
-u0_a8     1886  1873  1756828 84724 ffffffff 00000000 S FinalizerWatchd
-u0_a8     1887  1873  1756828 84724 ffffffff 00000000 S HeapTrimmerDaem
-u0_a8     1888  1873  1756828 84724 ffffffff 00000000 S GCDaemon
-u0_a8     1889  1873  1756828 84724 ffffffff 00000000 S Binder_1
-u0_a8     1890  1873  1756828 84724 ffffffff 00000000 S Binder_2
-u0_a8     1895  1873  1756828 84724 ffffffff 00000000 S Gservices
-u0_a8     1898  1873  1756828 84724 ffffffff 00000000 S measurement-1
-u0_a8     1900  1873  1756828 84724 ffffffff 00000000 S AsyncTask #1
-u0_a8     1904  1873  1756828 84724 ffffffff 00000000 S AsyncTask #2
-u0_a8     2001  1873  1756828 84724 ffffffff 00000000 S Binder_3
-u0_a8     2497  1873  1756828 84724 ffffffff 00000000 S WifiManager
-u0_a8     2509  1873  1756828 84724 ffffffff 00000000 S picasa-uploads-
-u0_a8     2946  1873  1756828 84724 ffffffff 00000000 S pool-7-thread-1
-u0_a8     4390  1873  1756828 84724 ffffffff 00000000 S pool-13-thread-
-u0_a8     4391  1873  1756828 84724 ffffffff 00000000 S pool-18-thread-
-u0_a8     4392  1873  1756828 84724 ffffffff 00000000 S pool-11-thread-
-u0_a8     4394  1873  1756828 84724 ffffffff 00000000 S pool-25-thread-
-u0_a8     4395  1873  1756828 84724 ffffffff 00000000 S pool-25-thread-
-u0_a8     4396  1873  1756828 84724 ffffffff 00000000 S pool-25-thread-
-u0_a8     4397  1873  1756828 84724 ffffffff 00000000 S pool-25-thread-
-u0_a8     4398  1873  1756828 84724 ffffffff 00000000 S pool-14-thread-
-u0_a8     4521  1873  1756828 84724 ffffffff 00000000 S MediaTracker bu
-u0_a8     4766  1873  1756828 84724 ffffffff 00000000 S Icing-Pool-0
-u0_a8     4771  1873  1756828 84724 ffffffff 00000000 S Icing-Worker-0
-u0_a8     4796  1873  1756828 84724 ffffffff 00000000 S Thread-200
-u0_a8     4797  1873  1756828 84724 ffffffff 00000000 S Thread-201
-u0_a8     4798  1873  1756828 84724 ffffffff 00000000 S Thread-202
-u0_a8     4799  1873  1756828 84724 ffffffff 00000000 S Thread-203
-u0_a8     4800  1873  1756828 84724 ffffffff 00000000 S Thread-204
-u0_a8     5793  1873  1756828 84724 ffffffff 00000000 S Binder_4
-u0_a8     6257  1873  1756828 84724 ffffffff 00000000 S Icing-Pool-1
-u0_a8     6258  1873  1756828 84724 ffffffff 00000000 S Icing-Pool-2
-u0_a8     6259  1873  1756828 84724 ffffffff 00000000 S Icing-Pool-3
-u0_a8     6673  1873  1756828 84724 ffffffff 00000000 S pool-22-thread-
-u0_a8     8581  1873  1756828 84724 ffffffff 00000000 S Binder_5
-u0_a8     9001  1873  1756828 84724 ffffffff 00000000 S Gservices
-u0_a8     9024  1873  1756828 84724 ffffffff 00000000 S GamesProviderWo
-u0_a8     11865 1873  1756828 84724 ffffffff 00000000 S pool-37-thread-
-u0_a8     1949  205   1614008 81544 ffffffff 00000000 S com.google.android.gms.persistent
-u0_a8     1954  1949  1614008 81544 ffffffff 00000000 S Heap thread poo
-u0_a8     1955  1949  1614008 81544 ffffffff 00000000 S Heap thread poo
-u0_a8     1956  1949  1614008 81544 ffffffff 00000000 S Heap thread poo
-u0_a8     1959  1949  1614008 81544 ffffffff 00000000 S Signal Catcher
-u0_a8     1960  1949  1614008 81544 ffffffff 00000000 S JDWP
-u0_a8     1961  1949  1614008 81544 ffffffff 00000000 S ReferenceQueueD
-u0_a8     1962  1949  1614008 81544 ffffffff 00000000 S FinalizerDaemon
-u0_a8     1963  1949  1614008 81544 ffffffff 00000000 S FinalizerWatchd
-u0_a8     1964  1949  1614008 81544 ffffffff 00000000 S HeapTrimmerDaem
-u0_a8     1965  1949  1614008 81544 ffffffff 00000000 S GCDaemon
-u0_a8     1966  1949  1614008 81544 ffffffff 00000000 S Binder_1
-u0_a8     1967  1949  1614008 81544 ffffffff 00000000 S Binder_2
-u0_a8     1968  1949  1614008 81544 ffffffff 00000000 S Gservices
-u0_a8     1973  1949  1614008 81544 ffffffff 00000000 S IntentService[G
-u0_a8     1976  1949  1614008 81544 ffffffff 00000000 S FlpThread
-u0_a8     1977  1949  1614008 81544 ffffffff 00000000 S Binder_3
-u0_a8     1978  1949  1614008 81544 ffffffff 00000000 S WifiManager
-u0_a8     1979  1949  1614008 81544 ffffffff 00000000 S GeofencerStateM
-u0_a8     1980  1949  1614008 81544 ffffffff 00000000 S LocationService
-u0_a8     1984  1949  1614008 81544 ffffffff 00000000 S Binder_4
-u0_a8     1986  1949  1614008 81544 ffffffff 00000000 S Binder_5
-u0_a8     1990  1949  1614008 81544 ffffffff 00000000 S pool-4-thread-1
-u0_a8     1992  1949  1614008 81544 ffffffff 00000000 S GmsCoreStatsSer
-u0_a8     1995  1949  1614008 81544 ffffffff 00000000 S GoogleLocationS
-u0_a8     2004  1949  1614008 81544 ffffffff 00000000 S Thread-139
-u0_a8     2005  1949  1614008 81544 ffffffff 00000000 S Thread-140
-u0_a8     2006  1949  1614008 81544 ffffffff 00000000 S Thread-141
-u0_a8     2007  1949  1614008 81544 ffffffff 00000000 S Thread-142
-u0_a8     2021  1949  1614008 81544 ffffffff 00000000 S NetworkLocation
-u0_a8     2029  1949  1614008 81544 ffffffff 00000000 S UlrDispatchingS
-u0_a8     2030  1949  1614008 81544 ffffffff 00000000 S nlp-async-worke
-u0_a8     2521  1949  1614008 81544 ffffffff 00000000 S FitnessServiceF
-u0_a8     2522  1949  1614008 81544 ffffffff 00000000 S FitRecordingBro
-u0_a8     2526  1949  1614008 81544 ffffffff 00000000 S AsyncTask #1
-u0_a8     2530  1949  1614008 81544 ffffffff 00000000 S NearbyMessagesB
-u0_a8     4180  1949  1614008 81544 ffffffff 00000000 S AsyncTask #2
-u0_a8     4221  1949  1614008 81544 ffffffff 00000000 S AsyncTask #3
-u0_a8     4223  1949  1614008 81544 ffffffff 00000000 S AsyncTask #4
-u0_a8     4749  1949  1614008 81544 ffffffff 00000000 S CopresenceEvent
-u0_a8     6326  1949  1614008 81544 ffffffff 00000000 S AsyncTask #5
-u0_a8     6917  1949  1614008 81544 ffffffff 00000000 S Binder_6
-u0_a8     7196  1949  1614008 81544 ffffffff 00000000 S UlrDispatchingS
-u0_a8     7260  1949  1614008 81544 ffffffff 00000000 S Thread-174
-u0_a8     7261  1949  1614008 81544 ffffffff 00000000 S Thread-175
-u0_a8     7262  1949  1614008 81544 ffffffff 00000000 S Thread-176
-u0_a8     7263  1949  1614008 81544 ffffffff 00000000 S Thread-177
-u0_a8     7264  1949  1614008 81544 ffffffff 00000000 S Thread-178
-u0_a8     12449 1949  1614008 81544 ffffffff 00000000 S OkHttp Connecti
-root      2031  1     20256  880   ffffffff 00000000 S /system/bin/mpdecision
-root      2032  2031  20256  880   ffffffff 00000000 S mpdecision
-root      2033  2031  20256  880   ffffffff 00000000 S mpdecision
-root      2034  2031  20256  880   ffffffff 00000000 S mpdecision
-root      2035  2031  20256  880   ffffffff 00000000 S mpdecision
-root      2036  2031  20256  880   ffffffff 00000000 S mpdecision
-root      2046  2031  20256  880   ffffffff 00000000 S mpdecision
-u0_a193   2647  205   1541760 60840 ffffffff 00000000 S com.qiyi.video.market
-u0_a193   2653  2647  1541760 60840 ffffffff 00000000 S Heap thread poo
-u0_a193   2654  2647  1541760 60840 ffffffff 00000000 S Heap thread poo
-u0_a193   2655  2647  1541760 60840 ffffffff 00000000 S Heap thread poo
-u0_a193   2656  2647  1541760 60840 ffffffff 00000000 S Signal Catcher
-u0_a193   2657  2647  1541760 60840 ffffffff 00000000 S JDWP
-u0_a193   2658  2647  1541760 60840 ffffffff 00000000 S ReferenceQueueD
-u0_a193   2659  2647  1541760 60840 ffffffff 00000000 S FinalizerDaemon
-u0_a193   2660  2647  1541760 60840 ffffffff 00000000 S FinalizerWatchd
-u0_a193   2661  2647  1541760 60840 ffffffff 00000000 S HeapTrimmerDaem
-u0_a193   2662  2647  1541760 60840 ffffffff 00000000 S GCDaemon
-u0_a193   2663  2647  1541760 60840 ffffffff 00000000 S Binder_1
-u0_a193   2664  2647  1541760 60840 ffffffff 00000000 S Binder_2
-u0_a193   2671  2647  1541760 60840 ffffffff 00000000 S RefQueueWorker@
-u0_a193   2673  2647  1541760 60840 ffffffff 00000000 S .ProcessManager
-u0_a193   2675  2647  1541760 60840 ffffffff 00000000 S Binder_3
-u0_a193   2677  2647  1541760 60840 ffffffff 00000000 S Thread-208
-u0_a193   2679  2647  1541760 60840 ffffffff 00000000 S pool-2-thread-1
-u0_a193   2680  2647  1541760 60840 ffffffff 00000000 S WifiManager
-u0_a193   2682  2647  1541760 60840 ffffffff 00000000 S Timer-0
-u0_a193   2683  2647  1541760 60840 ffffffff 00000000 S Timer-1
-u0_a193   2710  2647  1541760 60840 ffffffff 00000000 S AsyncTask #1
-u0_a193   2718  2647  1541760 60840 ffffffff 00000000 S pool-3-thread-1
-u0_a193   3103  2647  1541760 60840 ffffffff 00000000 S pool-4-thread-1
-u0_a193   6672  2647  1541760 60840 ffffffff 00000000 S AsyncTask #2
-u0_a193   6752  2647  1541760 60840 ffffffff 00000000 S AsyncTask #3
-u0_a193   12484 2647  1541760 60840 ffffffff 00000000 S AsyncTask #4
-u0_a193   12576 2647  1541760 60840 ffffffff 00000000 S AsyncTask #5
-u0_a193   3104  205   1523132 46892 ffffffff 00000000 S com.qiyi.video.market:pluginDownloadService
-u0_a193   3110  3104  1523132 46892 ffffffff 00000000 S Heap thread poo
-u0_a193   3111  3104  1523132 46892 ffffffff 00000000 S Heap thread poo
-u0_a193   3112  3104  1523132 46892 ffffffff 00000000 S Heap thread poo
-u0_a193   3113  3104  1523132 46892 ffffffff 00000000 S Signal Catcher
-u0_a193   3114  3104  1523132 46892 ffffffff 00000000 S JDWP
-u0_a193   3115  3104  1523132 46892 ffffffff 00000000 S ReferenceQueueD
-u0_a193   3116  3104  1523132 46892 ffffffff 00000000 S FinalizerDaemon
-u0_a193   3117  3104  1523132 46892 ffffffff 00000000 S FinalizerWatchd
-u0_a193   3118  3104  1523132 46892 ffffffff 00000000 S HeapTrimmerDaem
-u0_a193   3119  3104  1523132 46892 ffffffff 00000000 S GCDaemon
-u0_a193   3120  3104  1523132 46892 ffffffff 00000000 S Binder_1
-u0_a193   3121  3104  1523132 46892 ffffffff 00000000 S Binder_2
-u0_a193   3141  3104  1523132 46892 ffffffff 00000000 S RefQueueWorker@
-u0_a193   3257  3104  1523132 46892 ffffffff 00000000 S pool-3-thread-1
-u0_a193   7173  3104  1523132 46892 ffffffff 00000000 S Binder_3
-u0_a193   3122  205   1538224 61140 ffffffff 00000000 S com.qiyi.video.market:bdservice_v1
-u0_a193   3128  3122  1538224 61140 ffffffff 00000000 S Heap thread poo
-u0_a193   3129  3122  1538224 61140 ffffffff 00000000 S Heap thread poo
-u0_a193   3130  3122  1538224 61140 ffffffff 00000000 S Heap thread poo
-u0_a193   3131  3122  1538224 61140 ffffffff 00000000 S Signal Catcher
-u0_a193   3132  3122  1538224 61140 ffffffff 00000000 S JDWP
-u0_a193   3133  3122  1538224 61140 ffffffff 00000000 S ReferenceQueueD
-u0_a193   3134  3122  1538224 61140 ffffffff 00000000 S FinalizerDaemon
-u0_a193   3135  3122  1538224 61140 ffffffff 00000000 S FinalizerWatchd
-u0_a193   3136  3122  1538224 61140 ffffffff 00000000 S HeapTrimmerDaem
-u0_a193   3137  3122  1538224 61140 ffffffff 00000000 S GCDaemon
-u0_a193   3138  3122  1538224 61140 ffffffff 00000000 S Binder_1
-u0_a193   3139  3122  1538224 61140 ffffffff 00000000 S Binder_2
-u0_a193   3145  3122  1538224 61140 ffffffff 00000000 S RefQueueWorker@
-u0_a193   3206  3122  1538224 61140 ffffffff 00000000 S WifiManager
-u0_a193   3208  3122  1538224 61140 ffffffff 00000000 S NanoHttpd Main 
-u0_a193   7586  3122  1538224 61140 ffffffff 00000000 S pool-4-thread-1
-u0_a193   10584 3122  1538224 61140 ffffffff 00000000 S pool-2-thread-1
-u0_a193   3154  205   1522116 53536 ffffffff 00000000 S com.qiyi.video.market:baiduLocation
-u0_a193   3163  3154  1522116 53536 ffffffff 00000000 S Heap thread poo
-u0_a193   3164  3154  1522116 53536 ffffffff 00000000 S Heap thread poo
-u0_a193   3165  3154  1522116 53536 ffffffff 00000000 S Heap thread poo
-u0_a193   3166  3154  1522116 53536 ffffffff 00000000 S Signal Catcher
-u0_a193   3167  3154  1522116 53536 ffffffff 00000000 S JDWP
-u0_a193   3168  3154  1522116 53536 ffffffff 00000000 S ReferenceQueueD
-u0_a193   3169  3154  1522116 53536 ffffffff 00000000 S FinalizerDaemon
-u0_a193   3170  3154  1522116 53536 ffffffff 00000000 S FinalizerWatchd
-u0_a193   3171  3154  1522116 53536 ffffffff 00000000 S HeapTrimmerDaem
-u0_a193   3172  3154  1522116 53536 ffffffff 00000000 S GCDaemon
-u0_a193   3173  3154  1522116 53536 ffffffff 00000000 S Binder_1
-u0_a193   3174  3154  1522116 53536 ffffffff 00000000 S Binder_2
-u0_a193   3177  3154  1522116 53536 ffffffff 00000000 S RefQueueWorker@
-u0_a193   3199  3154  1522116 53536 ffffffff 00000000 S WifiManager
-u0_a86    3179  205   1561816 58376 ffffffff 00000000 S com.tencent.mm:push
-u0_a86    3183  3179  1561816 58376 ffffffff 00000000 S Heap thread poo
-u0_a86    3184  3179  1561816 58376 ffffffff 00000000 S Heap thread poo
-u0_a86    3185  3179  1561816 58376 ffffffff 00000000 S Heap thread poo
-u0_a86    3187  3179  1561816 58376 ffffffff 00000000 S Signal Catcher
-u0_a86    3189  3179  1561816 58376 ffffffff 00000000 S JDWP
-u0_a86    3190  3179  1561816 58376 ffffffff 00000000 S ReferenceQueueD
-u0_a86    3191  3179  1561816 58376 ffffffff 00000000 S FinalizerDaemon
-u0_a86    3192  3179  1561816 58376 ffffffff 00000000 S FinalizerWatchd
-u0_a86    3193  3179  1561816 58376 ffffffff 00000000 S HeapTrimmerDaem
-u0_a86    3194  3179  1561816 58376 ffffffff 00000000 S GCDaemon
-u0_a86    3195  3179  1561816 58376 ffffffff 00000000 S Binder_1
-u0_a86    3196  3179  1561816 58376 ffffffff 00000000 S Binder_2
-u0_a86    3210  3179  1561816 58376 ffffffff 00000000 S THREAD_POOL_HAN
-u0_a86    3212  3179  1561816 58376 ffffffff 00000000 S tencent.mm:push
-u0_a86    3216  3179  1561816 58376 ffffffff 00000000 S FileObserver
-u0_a86    3238  3179  1561816 58376 ffffffff 00000000 S tencent.mm:push
-u0_a86    3239  3179  1561816 58376 ffffffff 00000000 S default
-u0_a86    3240  3179  1561816 58376 ffffffff 00000000 S WifiManager
-u0_a86    5627  3179  1561816 58376 ffffffff 00000000 S Binder_3
-u0_a86    7150  3179  1561816 58376 ffffffff 00000000 S default
-u0_a170   3217  205   1531688 52204 ffffffff 00000000 S com.baidu.searchbox:bdservice_v1
-u0_a170   3220  3217  1531688 52204 ffffffff 00000000 S Heap thread poo
-u0_a170   3221  3217  1531688 52204 ffffffff 00000000 S Heap thread poo
-u0_a170   3223  3217  1531688 52204 ffffffff 00000000 S Heap thread poo
-u0_a170   3226  3217  1531688 52204 ffffffff 00000000 S Signal Catcher
-u0_a170   3228  3217  1531688 52204 ffffffff 00000000 S JDWP
-u0_a170   3229  3217  1531688 52204 ffffffff 00000000 S ReferenceQueueD
-u0_a170   3230  3217  1531688 52204 ffffffff 00000000 S FinalizerDaemon
-u0_a170   3231  3217  1531688 52204 ffffffff 00000000 S FinalizerWatchd
-u0_a170   3233  3217  1531688 52204 ffffffff 00000000 S HeapTrimmerDaem
-u0_a170   3234  3217  1531688 52204 ffffffff 00000000 S GCDaemon
-u0_a170   3235  3217  1531688 52204 ffffffff 00000000 S Binder_1
-u0_a170   3236  3217  1531688 52204 ffffffff 00000000 S Binder_2
-u0_a170   3303  3217  1531688 52204 ffffffff 00000000 S AsyncTask #1
-u0_a170   3304  3217  1531688 52204 ffffffff 00000000 S AsyncTask #2
-u0_a170   3518  3217  1531688 52204 ffffffff 00000000 S PushService-Pus
-u0_a170   3519  3217  1531688 52204 ffffffff 00000000 S PushService-Pus
-u0_a170   6201  3217  1531688 52204 ffffffff 00000000 S pool-1-thread-1
-u0_a170   10591 3217  1531688 52204 ffffffff 00000000 S RefQueueWorker@
-u0_a170   3260  205   1533384 53212 ffffffff 00000000 S com.baidu.searchbox:bdmoservice
-u0_a170   3264  3260  1533384 53212 ffffffff 00000000 S Heap thread poo
-u0_a170   3265  3260  1533384 53212 ffffffff 00000000 S Heap thread poo
-u0_a170   3266  3260  1533384 53212 ffffffff 00000000 S Heap thread poo
-u0_a170   3269  3260  1533384 53212 ffffffff 00000000 S Signal Catcher
-u0_a170   3270  3260  1533384 53212 ffffffff 00000000 S JDWP
-u0_a170   3271  3260  1533384 53212 ffffffff 00000000 S ReferenceQueueD
-u0_a170   3272  3260  1533384 53212 ffffffff 00000000 S FinalizerDaemon
-u0_a170   3273  3260  1533384 53212 ffffffff 00000000 S FinalizerWatchd
-u0_a170   3274  3260  1533384 53212 ffffffff 00000000 S HeapTrimmerDaem
-u0_a170   3275  3260  1533384 53212 ffffffff 00000000 S GCDaemon
-u0_a170   3276  3260  1533384 53212 ffffffff 00000000 S Binder_1
-u0_a170   3277  3260  1533384 53212 ffffffff 00000000 S Binder_2
-u0_a170   3738  3260  1533384 53212 ffffffff 00000000 S NanoHttpd Main 
-u0_a170   5783  3260  1533384 53212 ffffffff 00000000 S WifiManager
-u0_a126   3633  205   1515740 46080 ffffffff 00000000 S com.tencent.portfolio:push
-u0_a126   3636  3633  1515740 46080 ffffffff 00000000 S Heap thread poo
-u0_a126   3638  3633  1515740 46080 ffffffff 00000000 S Heap thread poo
-u0_a126   3639  3633  1515740 46080 ffffffff 00000000 S Heap thread poo
-u0_a126   3642  3633  1515740 46080 ffffffff 00000000 S Signal Catcher
-u0_a126   3643  3633  1515740 46080 ffffffff 00000000 S JDWP
-u0_a126   3645  3633  1515740 46080 ffffffff 00000000 S ReferenceQueueD
-u0_a126   3646  3633  1515740 46080 ffffffff 00000000 S FinalizerDaemon
-u0_a126   3647  3633  1515740 46080 ffffffff 00000000 S FinalizerWatchd
-u0_a126   3648  3633  1515740 46080 ffffffff 00000000 S HeapTrimmerDaem
-u0_a126   3649  3633  1515740 46080 ffffffff 00000000 S GCDaemon
-u0_a126   3650  3633  1515740 46080 ffffffff 00000000 S Binder_1
-u0_a126   3651  3633  1515740 46080 ffffffff 00000000 S Binder_2
-u0_a126   3661  3633  1515740 46080 ffffffff 00000000 S TPPluginCenter 
-u0_a126   3663  3633  1515740 46080 ffffffff 00000000 S pool-1-thread-1
-u0_a126   3665  3633  1515740 46080 ffffffff 00000000 S MidService
-u0_a126   3667  3633  1515740 46080 ffffffff 00000000 S pool-2-thread-1
-u0_a126   3668  3633  1515740 46080 ffffffff 00000000 S push core threa
-u0_a126   3670  3633  1515740 46080 ffffffff 00000000 S .ProcessManager
-u0_a126   3672  3633  1515740 46080 ffffffff 00000000 S Binder_3
-u0_a126   3674  3633  1515740 46080 ffffffff 00000000 S pool-4-thread-1
-u0_a126   3675  3633  1515740 46080 ffffffff 00000000 S pool-3-thread-1
-u0_a126   5638  3633  1515740 46080 ffffffff 00000000 S Timer-0
-bluetooth 4227  205   1527652 48088 ffffffff 00000000 S com.android.bluetooth
-bluetooth 4231  4227  1527652 48088 ffffffff 00000000 S Heap thread poo
-bluetooth 4233  4227  1527652 48088 ffffffff 00000000 S Heap thread poo
-bluetooth 4235  4227  1527652 48088 ffffffff 00000000 S Heap thread poo
-bluetooth 4236  4227  1527652 48088 ffffffff 00000000 S Signal Catcher
-bluetooth 4237  4227  1527652 48088 ffffffff 00000000 S JDWP
-bluetooth 4238  4227  1527652 48088 ffffffff 00000000 S ReferenceQueueD
-bluetooth 4239  4227  1527652 48088 ffffffff 00000000 S FinalizerDaemon
-bluetooth 4240  4227  1527652 48088 ffffffff 00000000 S FinalizerWatchd
-bluetooth 4241  4227  1527652 48088 ffffffff 00000000 S HeapTrimmerDaem
-bluetooth 4242  4227  1527652 48088 ffffffff 00000000 S GCDaemon
-bluetooth 4243  4227  1527652 48088 ffffffff 00000000 S Binder_1
-bluetooth 4244  4227  1527652 48088 ffffffff 00000000 S Binder_2
-bluetooth 4308  4227  1527652 48088 ffffffff 00000000 S BluetoothAdapte
-bluetooth 4309  4227  1527652 48088 ffffffff 00000000 S droid.bluetooth
-bluetooth 4311  4227  1527652 48088 ffffffff 00000000 S bluedroid wake/
-bluetooth 4312  4227  1527652 48088 ffffffff 00000000 S BT Service Call
-bluetooth 4315  4227  1527652 48088 ffffffff 00000000 S BondStateMachin
-bluetooth 4316  4227  1527652 48088 ffffffff 00000000 S Binder_3
-bluetooth 4317  4227  1527652 48088 ffffffff 00000000 S Binder_4
-bluetooth 4318  4227  1527652 48088 ffffffff 00000000 S HeadsetStateMac
-bluetooth 4320  4227  1527652 48088 ffffffff 00000000 S BluetoothAvrcpH
-bluetooth 4321  4227  1527652 48088 ffffffff 00000000 S A2dpStateMachin
-bluetooth 4322  4227  1527652 48088 ffffffff 00000000 S A2DP-MEDIA
-bluetooth 4323  4227  1527652 48088 ffffffff 00000000 S uipc-main
-bluetooth 4324  4227  1527652 48088 ffffffff 00000000 S BluetoothHdpHan
-bluetooth 4325  4227  1527652 48088 ffffffff 00000000 S droid.bluetooth
-bluetooth 4326  4227  1527652 48088 ffffffff 00000000 S BluetoothAdvert
-bluetooth 4327  4227  1527652 48088 ffffffff 00000000 S BluetoothScanMa
-bluetooth 4331  4227  1527652 48088 ffffffff 00000000 S bluedroid wake/
-bluetooth 4333  4227  1527652 48088 ffffffff 00000000 S bt_hc_worker
-bluetooth 4338  4227  1527652 48088 ffffffff 00000000 S userial_read
-bluetooth 4478  4227  1527652 48088 ffffffff 00000000 S BT Service Call
-bluetooth 4479  4227  1527652 48088 ffffffff 00000000 S bt_hc_worker
-bluetooth 4481  4227  1527652 48088 ffffffff 00000000 S bt_hc_worker
-bluetooth 4482  4227  1527652 48088 ffffffff 00000000 S BluetoothMapAcc
-bluetooth 6459  4227  1527652 48088 ffffffff 00000000 S BluetoothPbapAc
-bluetooth 6473  4227  1527652 48088 ffffffff 00000000 S pool-1-thread-1
-bluetooth 6477  4227  1527652 48088 ffffffff 00000000 S BtOppRfcommList
-radio     4597  205   1493160 37460 ffffffff 00000000 S com.qualcomm.qcrilmsgtunnel
-radio     4603  4597  1493160 37460 ffffffff 00000000 S Heap thread poo
-radio     4604  4597  1493160 37460 ffffffff 00000000 S Heap thread poo
-radio     4605  4597  1493160 37460 ffffffff 00000000 S Heap thread poo
-radio     4606  4597  1493160 37460 ffffffff 00000000 S Signal Catcher
-radio     4607  4597  1493160 37460 ffffffff 00000000 S JDWP
-radio     4608  4597  1493160 37460 ffffffff 00000000 S ReferenceQueueD
-radio     4609  4597  1493160 37460 ffffffff 00000000 S FinalizerDaemon
-radio     4610  4597  1493160 37460 ffffffff 00000000 S FinalizerWatchd
-radio     4611  4597  1493160 37460 ffffffff 00000000 S HeapTrimmerDaem
-radio     4612  4597  1493160 37460 ffffffff 00000000 S GCDaemon
-radio     4613  4597  1493160 37460 ffffffff 00000000 S Binder_1
-radio     4614  4597  1493160 37460 ffffffff 00000000 S Binder_2
-radio     4615  4597  1493160 37460 ffffffff 00000000 S QcRilReceiver
-radio     4616  4597  1493160 37460 ffffffff 00000000 S QcRilSender
-u0_a193   5239  205   1528424 47860 ffffffff 00000000 S .iqiyipushserviceGlobal
-u0_a193   5242  5239  1528424 47860 ffffffff 00000000 S Heap thread poo
-u0_a193   5244  5239  1528424 47860 ffffffff 00000000 S Heap thread poo
-u0_a193   5245  5239  1528424 47860 ffffffff 00000000 S Heap thread poo
-u0_a193   5248  5239  1528424 47860 ffffffff 00000000 S Signal Catcher
-u0_a193   5249  5239  1528424 47860 ffffffff 00000000 S JDWP
-u0_a193   5250  5239  1528424 47860 ffffffff 00000000 S ReferenceQueueD
-u0_a193   5251  5239  1528424 47860 ffffffff 00000000 S FinalizerDaemon
-u0_a193   5252  5239  1528424 47860 ffffffff 00000000 S FinalizerWatchd
-u0_a193   5253  5239  1528424 47860 ffffffff 00000000 S HeapTrimmerDaem
-u0_a193   5254  5239  1528424 47860 ffffffff 00000000 S GCDaemon
-u0_a193   5255  5239  1528424 47860 ffffffff 00000000 S Binder_1
-u0_a193   5257  5239  1528424 47860 ffffffff 00000000 S Binder_2
-u0_a193   5280  5239  1528424 47860 ffffffff 00000000 S RefQueueWorker@
-u0_a193   5281  5239  1528424 47860 ffffffff 00000000 S Binder_3
-u0_a193   5361  5239  1528424 47860 ffffffff 00000000 S Micro Client Co
-u0_a193   5362  5239  1528424 47860 ffffffff 00000000 S Micro Client Co
-u0_a193   5363  5239  1528424 47860 ffffffff 00000000 S Micro Client Ca
-u0_a193   6740  5239  1528424 47860 ffffffff 00000000 S Binder_4
-u0_a193   7091  5239  1528424 47860 ffffffff 00000000 S Binder_5
-u0_a193   7557  5239  1528424 47860 ffffffff 00000000 S Binder_6
-u0_a193   5285  5239  1521088 34196 ffffffff 00000000 S .iqiyipushserviceGlobal
-u0_a90    5323  205   1557268 59988 ffffffff 00000000 S com.strava
-u0_a90    5327  5323  1557268 59988 ffffffff 00000000 S Heap thread poo
-u0_a90    5328  5323  1557268 59988 ffffffff 00000000 S Heap thread poo
-u0_a90    5329  5323  1557268 59988 ffffffff 00000000 S Heap thread poo
-u0_a90    5332  5323  1557268 59988 ffffffff 00000000 S Signal Catcher
-u0_a90    5333  5323  1557268 59988 ffffffff 00000000 S JDWP
-u0_a90    5334  5323  1557268 59988 ffffffff 00000000 S ReferenceQueueD
-u0_a90    5335  5323  1557268 59988 ffffffff 00000000 S FinalizerDaemon
-u0_a90    5336  5323  1557268 59988 ffffffff 00000000 S FinalizerWatchd
-u0_a90    5337  5323  1557268 59988 ffffffff 00000000 S HeapTrimmerDaem
-u0_a90    5338  5323  1557268 59988 ffffffff 00000000 S GCDaemon
-u0_a90    5339  5323  1557268 59988 ffffffff 00000000 S Binder_1
-u0_a90    5340  5323  1557268 59988 ffffffff 00000000 S Binder_2
-u0_a90    5345  5323  1557268 59988 ffffffff 00000000 S Queue
-u0_a90    5346  5323  1557268 59988 ffffffff 00000000 S Queue
-u0_a90    5347  5323  1557268 59988 ffffffff 00000000 S Queue
-u0_a90    5348  5323  1557268 59988 ffffffff 00000000 S Queue
-u0_a90    5349  5323  1557268 59988 ffffffff 00000000 S Queue
-u0_a90    5352  5323  1557268 59988 ffffffff 00000000 S Crashlytics Exc
-u0_a90    5354  5323  1557268 59988 ffffffff 00000000 S pool-3-thread-1
-u0_a90    5364  5323  1557268 59988 ffffffff 00000000 S Thread-584
-u0_a90    5365  5323  1557268 59988 ffffffff 00000000 S Thread-585
-u0_a90    5366  5323  1557268 59988 ffffffff 00000000 S Thread-586
-u0_a90    5367  5323  1557268 59988 ffffffff 00000000 S pool-4-thread-1
-u0_a90    5369  5323  1557268 59988 ffffffff 00000000 S Crashlytics Tra
-u0_a90    5372  5323  1557268 59988 ffffffff 00000000 S Thread-593
-u0_a90    5373  5323  1557268 59988 ffffffff 00000000 S Thread-594
-u0_a90    5374  5323  1557268 59988 ffffffff 00000000 S Thread-595
-u0_a90    5375  5323  1557268 59988 ffffffff 00000000 S Thread-596
-u0_a90    5376  5323  1557268 59988 ffffffff 00000000 S pool-6-thread-1
-u0_a90    5377  5323  1557268 59988 ffffffff 00000000 S Thread-598
-u0_a90    5378  5323  1557268 59988 ffffffff 00000000 S Thread-599
-u0_a90    5379  5323  1557268 59988 ffffffff 00000000 S Thread-600
-u0_a90    5381  5323  1557268 59988 ffffffff 00000000 S Thread-602
-u0_a90    5383  5323  1557268 59988 ffffffff 00000000 S Thread #1
-u0_a90    5384  5323  1557268 59988 ffffffff 00000000 S AsyncTask #1
-u0_a90    5387  5323  1557268 59988 ffffffff 00000000 S Thread-605
-u0_a90    5388  5323  1557268 59988 ffffffff 00000000 S Thread-606
-u0_a90    5389  5323  1557268 59988 ffffffff 00000000 S Thread-607
-u0_a90    5390  5323  1557268 59988 ffffffff 00000000 S Thread-608
-u0_a90    5391  5323  1557268 59988 ffffffff 00000000 S Thread-609
-u0_a90    5393  5323  1557268 59988 ffffffff 00000000 S eNowAuthService
-u0_a90    5394  5323  1557268 59988 ffffffff 00000000 S Thread #2
-u0_a90    5468  5323  1557268 59988 ffffffff 00000000 S Okio Watchdog
-u0_a90    5498  5323  1557268 59988 ffffffff 00000000 S Thread #3
-u0_a109   5395  205   1524968 53976 ffffffff 00000000 S com.pandora.android
-u0_a109   5397  5395  1524968 53976 ffffffff 00000000 S Heap thread poo
-u0_a109   5398  5395  1524968 53976 ffffffff 00000000 S Heap thread poo
-u0_a109   5399  5395  1524968 53976 ffffffff 00000000 S Heap thread poo
-u0_a109   5401  5395  1524968 53976 ffffffff 00000000 S Signal Catcher
-u0_a109   5403  5395  1524968 53976 ffffffff 00000000 S JDWP
-u0_a109   5407  5395  1524968 53976 ffffffff 00000000 S ReferenceQueueD
-u0_a109   5408  5395  1524968 53976 ffffffff 00000000 S FinalizerDaemon
-u0_a109   5409  5395  1524968 53976 ffffffff 00000000 S FinalizerWatchd
-u0_a109   5410  5395  1524968 53976 ffffffff 00000000 S HeapTrimmerDaem
-u0_a109   5411  5395  1524968 53976 ffffffff 00000000 S GCDaemon
-u0_a109   5414  5395  1524968 53976 ffffffff 00000000 S Binder_1
-u0_a109   5416  5395  1524968 53976 ffffffff 00000000 S Binder_2
-u0_a109   5422  5395  1524968 53976 ffffffff 00000000 S Crashlytics Exc
-u0_a109   5429  5395  1524968 53976 ffffffff 00000000 S pool-2-thread-1
-u0_a109   5430  5395  1524968 53976 ffffffff 00000000 S AsyncTask #1
-u0_a109   5437  5395  1524968 53976 ffffffff 00000000 S Crashlytics Tra
-u0_a109   5439  5395  1524968 53976 ffffffff 00000000 S AsyncTask #2
-u0_a109   5440  5395  1524968 53976 ffffffff 00000000 S pool-4-thread-1
-u0_a109   5443  5395  1524968 53976 ffffffff 00000000 S PurchasingManag
-u0_a109   5444  5395  1524968 53976 ffffffff 00000000 S BluetoothServer
-u0_a109   5445  5395  1524968 53976 ffffffff 00000000 S AsyncTask #3
-u0_a109   5446  5395  1524968 53976 ffffffff 00000000 S AsyncTask #4
-u0_a109   5590  5395  1524968 53976 ffffffff 00000000 S Binder_3
-u0_a109   6481  5395  1524968 53976 ffffffff 00000000 S AsyncTask #5
-u0_a110   5474  205   1525556 49828 ffffffff 00000000 S tunein.player
-u0_a110   5479  5474  1525556 49828 ffffffff 00000000 S Heap thread poo
-u0_a110   5480  5474  1525556 49828 ffffffff 00000000 S Heap thread poo
-u0_a110   5481  5474  1525556 49828 ffffffff 00000000 S Heap thread poo
-u0_a110   5483  5474  1525556 49828 ffffffff 00000000 S Signal Catcher
-u0_a110   5484  5474  1525556 49828 ffffffff 00000000 S JDWP
-u0_a110   5485  5474  1525556 49828 ffffffff 00000000 S ReferenceQueueD
-u0_a110   5486  5474  1525556 49828 ffffffff 00000000 S FinalizerDaemon
-u0_a110   5487  5474  1525556 49828 ffffffff 00000000 S FinalizerWatchd
-u0_a110   5488  5474  1525556 49828 ffffffff 00000000 S HeapTrimmerDaem
-u0_a110   5489  5474  1525556 49828 ffffffff 00000000 S GCDaemon
-u0_a110   5490  5474  1525556 49828 ffffffff 00000000 S Binder_1
-u0_a110   5492  5474  1525556 49828 ffffffff 00000000 S Binder_2
-u0_a110   5503  5474  1525556 49828 ffffffff 00000000 S geHandlerThread
-u0_a110   5504  5474  1525556 49828 ffffffff 00000000 S GAThread
-u0_a110   5507  5474  1525556 49828 ffffffff 00000000 S Crashlytics Exc
-u0_a110   5510  5474  1525556 49828 ffffffff 00000000 S AsyncTask #1
-u0_a110   5515  5474  1525556 49828 ffffffff 00000000 S Crashlytics Tra
-u0_a110   5518  5474  1525556 49828 ffffffff 00000000 S AsyncTask #2
-u0_a110   5587  5474  1525556 49828 ffffffff 00000000 S AcceptThreadSec
-u0_a88    5519  205   1556696 65876 ffffffff 00000000 S com.dropbox.android
-u0_a88    5525  5519  1556696 65876 ffffffff 00000000 S Heap thread poo
-u0_a88    5526  5519  1556696 65876 ffffffff 00000000 S Heap thread poo
-u0_a88    5527  5519  1556696 65876 ffffffff 00000000 S Heap thread poo
-u0_a88    5528  5519  1556696 65876 ffffffff 00000000 S Signal Catcher
-u0_a88    5529  5519  1556696 65876 ffffffff 00000000 S JDWP
-u0_a88    5530  5519  1556696 65876 ffffffff 00000000 S ReferenceQueueD
-u0_a88    5531  5519  1556696 65876 ffffffff 00000000 S FinalizerDaemon
-u0_a88    5532  5519  1556696 65876 ffffffff 00000000 S FinalizerWatchd
-u0_a88    5533  5519  1556696 65876 ffffffff 00000000 S HeapTrimmerDaem
-u0_a88    5534  5519  1556696 65876 ffffffff 00000000 S GCDaemon
-u0_a88    5535  5519  1556696 65876 ffffffff 00000000 S Binder_1
-u0_a88    5536  5519  1556696 65876 ffffffff 00000000 S Binder_2
-u0_a88    5562  5519  1556696 65876 ffffffff 00000000 S Dropbox log upl
-u0_a88    5563  5519  1556696 65876 ffffffff 00000000 S gandalf updater
-u0_a88    5568  5519  1556696 65876 ffffffff 00000000 S pool-10-thread-
-u0_a88    5569  5519  1556696 65876 ffffffff 00000000 S DbxFileObserver
-u0_a88    5570  5519  1556696 65876 ffffffff 00000000 S LocalThumbManag
-u0_a88    5574  5519  1556696 65876 ffffffff 00000000 S local AsyncTask
-u0_a88    5575  5519  1556696 65876 ffffffff 00000000 S remote AsyncTas
-u0_a88    5576  5519  1556696 65876 ffffffff 00000000 S local AsyncTask
-u0_a88    5577  5519  1556696 65876 ffffffff 00000000 S remote AsyncTas
-u0_a88    5578  5519  1556696 65876 ffffffff 00000000 S Dropbox notif o
-u0_a88    5579  5519  1556696 65876 ffffffff 00000000 S Dropbox notif s
-u0_a88    5580  5519  1556696 65876 ffffffff 00000000 S Picasso-Stats
-u0_a88    5581  5519  1556696 65876 ffffffff 00000000 S Picasso-Dispatc
-u0_a88    5582  5519  1556696 65876 ffffffff 00000000 S Picasso-refQueu
-u0_a88    5583  5519  1556696 65876 ffffffff 00000000 S gandalf updater
-u0_a88    5592  5519  1556696 65876 ffffffff 00000000 S DbxFileObserver
-u0_a88    5593  5519  1556696 65876 ffffffff 00000000 S dbxpool-34:r-th
-u0_a88    5594  5519  1556696 65876 ffffffff 00000000 S dbxpool-32:au-t
-u0_a88    5595  5519  1556696 65876 ffffffff 00000000 S dbxpool-38:a-th
-u0_a88    5596  5519  1556696 65876 ffffffff 00000000 S Timer-0
-u0_a88    5597  5519  1556696 65876 ffffffff 00000000 S dbxpool-6:a-thr
-u0_a88    5599  5519  1556696 65876 ffffffff 00000000 S Timer-1
-u0_a88    5718  5519  1556696 65876 ffffffff 00000000 S RefQueueWorker@
-u0_a88    5750  5519  1556696 65876 ffffffff 00000000 S Thread-625
-u0_a88    5818  5519  1556696 65876 ffffffff 00000000 S Binder_3
-u0_a88    8569  5519  1556696 65876 ffffffff 00000000 S Binder_4
-u0_a88    8572  5519  1556696 65876 ffffffff 00000000 S Binder_5
-u0_a88    8580  5519  1556696 65876 ffffffff 00000000 S Binder_6
-u0_a93    5688  205   1496212 39724 ffffffff 00000000 S com.devuni.flashlight:remote
-u0_a93    5693  5688  1496212 39724 ffffffff 00000000 S Heap thread poo
-u0_a93    5694  5688  1496212 39724 ffffffff 00000000 S Heap thread poo
-u0_a93    5695  5688  1496212 39724 ffffffff 00000000 S Heap thread poo
-u0_a93    5697  5688  1496212 39724 ffffffff 00000000 S Signal Catcher
-u0_a93    5698  5688  1496212 39724 ffffffff 00000000 S JDWP
-u0_a93    5699  5688  1496212 39724 ffffffff 00000000 S ReferenceQueueD
-u0_a93    5700  5688  1496212 39724 ffffffff 00000000 S FinalizerDaemon
-u0_a93    5701  5688  1496212 39724 ffffffff 00000000 S FinalizerWatchd
-u0_a93    5702  5688  1496212 39724 ffffffff 00000000 S HeapTrimmerDaem
-u0_a93    5703  5688  1496212 39724 ffffffff 00000000 S GCDaemon
-u0_a93    5704  5688  1496212 39724 ffffffff 00000000 S Binder_1
-u0_a93    5705  5688  1496212 39724 ffffffff 00000000 S Binder_2
-u0_a93    12039 5688  1496212 39724 ffffffff 00000000 S pool-1-thread-1
-u0_a86    6202  205   1809096 86876 ffffffff 00000000 S com.tencent.mm
-u0_a86    6206  6202  1809096 86876 ffffffff 00000000 S Heap thread poo
-u0_a86    6207  6202  1809096 86876 ffffffff 00000000 S Heap thread poo
-u0_a86    6208  6202  1809096 86876 ffffffff 00000000 S Heap thread poo
-u0_a86    6211  6202  1809096 86876 ffffffff 00000000 S Signal Catcher
-u0_a86    6212  6202  1809096 86876 ffffffff 00000000 S JDWP
-u0_a86    6213  6202  1809096 86876 ffffffff 00000000 S ReferenceQueueD
-u0_a86    6214  6202  1809096 86876 ffffffff 00000000 S FinalizerDaemon
-u0_a86    6215  6202  1809096 86876 ffffffff 00000000 S FinalizerWatchd
-u0_a86    6217  6202  1809096 86876 ffffffff 00000000 S HeapTrimmerDaem
-u0_a86    6218  6202  1809096 86876 ffffffff 00000000 S GCDaemon
-u0_a86    6220  6202  1809096 86876 ffffffff 00000000 S Binder_1
-u0_a86    6221  6202  1809096 86876 ffffffff 00000000 S Binder_2
-u0_a86    6236  6202  1809096 86876 ffffffff 00000000 S THREAD_POOL_HAN
-u0_a86    6237  6202  1809096 86876 ffffffff 00000000 S com.tencent.mm
-u0_a86    6239  6202  1809096 86876 ffffffff 00000000 S com.tencent.mm
-u0_a86    6240  6202  1809096 86876 ffffffff 00000000 S MonitorHandlerT
-u0_a86    6241  6202  1809096 86876 ffffffff 00000000 S .ProcessManager
-u0_a86    6243  6202  1809096 86876 ffffffff 00000000 S Binder_3
-u0_a86    6245  6202  1809096 86876 ffffffff 00000000 S default
-u0_a86    6246  6202  1809096 86876 ffffffff 00000000 S com.tencent.mm
-u0_a86    6247  6202  1809096 86876 ffffffff 00000000 S MMHandlerThread
-u0_a86    6269  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6270  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6271  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6272  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6273  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6274  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6276  6202  1809096 86876 ffffffff 00000000 S ExdeviceHandler
-u0_a86    6277  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6279  6202  1809096 86876 ffffffff 00000000 S RWCache_timeout
-u0_a86    6280  6202  1809096 86876 ffffffff 00000000 S RWCache_timeout
-u0_a86    6282  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6284  6202  1809096 86876 ffffffff 00000000 S downloadStateCh
-u0_a86    6288  6202  1809096 86876 ffffffff 00000000 S WifiManager
-u0_a86    6289  6202  1809096 86876 ffffffff 00000000 S refresh Notific
-u0_a86    6292  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6293  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6294  6202  1809096 86876 ffffffff 00000000 S MM_Thread_Pool_
-u0_a86    6295  6202  1809096 86876 ffffffff 00000000 S SearchDaemon
-u0_a86    6303  6202  1809096 86876 ffffffff 00000000 S Binder_4
-u0_a86    6313  6202  1809096 86876 ffffffff 00000000 S pool-2-thread-1
-u0_a86    6373  6202  1809096 86876 ffffffff 00000000 S RWCache_timeout
-u0_a86    6408  6202  1809096 86876 ffffffff 00000000 S h
-u0_a86    7230  6202  1809096 86876 ffffffff 00000000 S default
-u0_a86    7231  6202  1809096 86876 ffffffff 00000000 S MMHandlerThread
-u0_a191   8839  205   1510312 57352 ffffffff 00000000 S com.ushaqi.zhuishushenqi:pushservice
-u0_a191   8845  8839  1510312 57352 ffffffff 00000000 S Heap thread poo
-u0_a191   8846  8839  1510312 57352 ffffffff 00000000 S Heap thread poo
-u0_a191   8847  8839  1510312 57352 ffffffff 00000000 S Heap thread poo
-u0_a191   8849  8839  1510312 57352 ffffffff 00000000 S Signal Catcher
-u0_a191   8850  8839  1510312 57352 ffffffff 00000000 S JDWP
-u0_a191   8851  8839  1510312 57352 ffffffff 00000000 S ReferenceQueueD
-u0_a191   8852  8839  1510312 57352 ffffffff 00000000 S FinalizerDaemon
-u0_a191   8853  8839  1510312 57352 ffffffff 00000000 S FinalizerWatchd
-u0_a191   8854  8839  1510312 57352 ffffffff 00000000 S HeapTrimmerDaem
-u0_a191   8855  8839  1510312 57352 ffffffff 00000000 S GCDaemon
-u0_a191   8856  8839  1510312 57352 ffffffff 00000000 S Binder_1
-u0_a191   8857  8839  1510312 57352 ffffffff 00000000 S Binder_2
-u0_a191   8867  8839  1510312 57352 ffffffff 00000000 S local_job_dispa
-u0_a191   8869  8839  1510312 57352 ffffffff 00000000 S remote_job_disp
-u0_a191   8887  8839  1510312 57352 ffffffff 00000000 S Upload Http Rec
-u0_a191   8890  8839  1510312 57352 ffffffff 00000000 S Connection Cont
-u0_a191   8963  8839  1510312 57352 ffffffff 00000000 S Smack Packet Re
-root      11634 2     0      0     ffffffff 00000000 S kworker/u:0
-root      11779 2     0      0     ffffffff 00000000 S kworker/0:3H
-root      11928 2     0      0     ffffffff 00000000 S kworker/0:1
-root      12431 2     0      0     ffffffff 00000000 S kworker/u:2
-u0_a85    12971 205   1595348 59000 ffffffff 00000000 S com.life360.android.safetymapd:service
-u0_a85    12977 12971 1595348 59000 ffffffff 00000000 S Heap thread poo
-u0_a85    12978 12971 1595348 59000 ffffffff 00000000 S Heap thread poo
-u0_a85    12979 12971 1595348 59000 ffffffff 00000000 S Heap thread poo
-u0_a85    12980 12971 1595348 59000 ffffffff 00000000 S Signal Catcher
-u0_a85    12981 12971 1595348 59000 ffffffff 00000000 S JDWP
-u0_a85    12982 12971 1595348 59000 ffffffff 00000000 S ReferenceQueueD
-u0_a85    12983 12971 1595348 59000 ffffffff 00000000 S FinalizerDaemon
-u0_a85    12984 12971 1595348 59000 ffffffff 00000000 S FinalizerWatchd
-u0_a85    12985 12971 1595348 59000 ffffffff 00000000 S HeapTrimmerDaem
-u0_a85    12986 12971 1595348 59000 ffffffff 00000000 S GCDaemon
-u0_a85    12987 12971 1595348 59000 ffffffff 00000000 S Binder_1
-u0_a85    12988 12971 1595348 59000 ffffffff 00000000 S Binder_2
-u0_a85    13099 12971 1595348 59000 ffffffff 00000000 S WifiManager
-u0_a106   13071 205   1523392 47680 ffffffff 00000000 S com.xianguo.tingguo
-u0_a106   13075 13071 1523392 47680 ffffffff 00000000 S Heap thread poo
-u0_a106   13076 13071 1523392 47680 ffffffff 00000000 S Heap thread poo
-u0_a106   13077 13071 1523392 47680 ffffffff 00000000 S Heap thread poo
-u0_a106   13080 13071 1523392 47680 ffffffff 00000000 S Signal Catcher
-u0_a106   13081 13071 1523392 47680 ffffffff 00000000 S JDWP
-u0_a106   13082 13071 1523392 47680 ffffffff 00000000 S ReferenceQueueD
-u0_a106   13083 13071 1523392 47680 ffffffff 00000000 S FinalizerDaemon
-u0_a106   13084 13071 1523392 47680 ffffffff 00000000 S FinalizerWatchd
-u0_a106   13085 13071 1523392 47680 ffffffff 00000000 S HeapTrimmerDaem
-u0_a106   13086 13071 1523392 47680 ffffffff 00000000 S GCDaemon
-u0_a106   13087 13071 1523392 47680 ffffffff 00000000 S Binder_1
-u0_a106   13088 13071 1523392 47680 ffffffff 00000000 S Binder_2
-u0_a106   13090 13071 1523392 47680 ffffffff 00000000 S SoundPool
-u0_a106   13091 13071 1523392 47680 ffffffff 00000000 S SoundPoolThread
-u0_a106   13276 13071 1523392 47680 ffffffff 00000000 S WifiManager
-u0_a65    13345 205   1526244 52680 ffffffff 00000000 S com.google.android.apps.photos
-u0_a65    13351 13345 1526244 52680 ffffffff 00000000 S Heap thread poo
-u0_a65    13352 13345 1526244 52680 ffffffff 00000000 S Heap thread poo
-u0_a65    13353 13345 1526244 52680 ffffffff 00000000 S Heap thread poo
-u0_a65    13354 13345 1526244 52680 ffffffff 00000000 S Signal Catcher
-u0_a65    13355 13345 1526244 52680 ffffffff 00000000 S JDWP
-u0_a65    13356 13345 1526244 52680 ffffffff 00000000 S ReferenceQueueD
-u0_a65    13357 13345 1526244 52680 ffffffff 00000000 S FinalizerDaemon
-u0_a65    13358 13345 1526244 52680 ffffffff 00000000 S FinalizerWatchd
-u0_a65    13359 13345 1526244 52680 ffffffff 00000000 S HeapTrimmerDaem
-u0_a65    13360 13345 1526244 52680 ffffffff 00000000 S GCDaemon
-u0_a65    13361 13345 1526244 52680 ffffffff 00000000 S Binder_1
-u0_a65    13362 13345 1526244 52680 ffffffff 00000000 S Binder_2
-u0_a65    13783 13345 1526244 52680 ffffffff 00000000 S pool-1-thread-1
-u0_a65    13796 13345 1526244 52680 ffffffff 00000000 S rotating_file-t
-u0_a65    13904 13345 1526244 52680 ffffffff 00000000 S Binder_3
-u0_a67    13491 205   1567688 56576 ffffffff 00000000 S com.google.android.apps.plus
-u0_a67    13493 13491 1567688 56576 ffffffff 00000000 S Heap thread poo
-u0_a67    13494 13491 1567688 56576 ffffffff 00000000 S Heap thread poo
-u0_a67    13495 13491 1567688 56576 ffffffff 00000000 S Heap thread poo
-u0_a67    13497 13491 1567688 56576 ffffffff 00000000 S Signal Catcher
-u0_a67    13499 13491 1567688 56576 ffffffff 00000000 S JDWP
-u0_a67    13502 13491 1567688 56576 ffffffff 00000000 S ReferenceQueueD
-u0_a67    13503 13491 1567688 56576 ffffffff 00000000 S FinalizerDaemon
-u0_a67    13504 13491 1567688 56576 ffffffff 00000000 S FinalizerWatchd
-u0_a67    13505 13491 1567688 56576 ffffffff 00000000 S HeapTrimmerDaem
-u0_a67    13506 13491 1567688 56576 ffffffff 00000000 S GCDaemon
-u0_a67    13507 13491 1567688 56576 ffffffff 00000000 S Binder_1
-u0_a67    13508 13491 1567688 56576 ffffffff 00000000 S Binder_2
-u0_a67    13512 13491 1567688 56576 ffffffff 00000000 S picasa-photo-pr
-u0_a67    13528 13491 1567688 56576 ffffffff 00000000 S iu-sync-manager
-u0_a67    13538 13491 1567688 56576 ffffffff 00000000 S pool-2-thread-1
-u0_a67    13881 13491 1567688 56576 ffffffff 00000000 S Gservices
-u0_a4     13516 205   1503264 48612 ffffffff 00000000 S android.process.acore
-u0_a4     13520 13516 1503264 48612 ffffffff 00000000 S Heap thread poo
-u0_a4     13521 13516 1503264 48612 ffffffff 00000000 S Heap thread poo
-u0_a4     13522 13516 1503264 48612 ffffffff 00000000 S Heap thread poo
-u0_a4     13525 13516 1503264 48612 ffffffff 00000000 S Signal Catcher
-u0_a4     13526 13516 1503264 48612 ffffffff 00000000 S JDWP
-u0_a4     13527 13516 1503264 48612 ffffffff 00000000 S ReferenceQueueD
-u0_a4     13529 13516 1503264 48612 ffffffff 00000000 S FinalizerDaemon
-u0_a4     13530 13516 1503264 48612 ffffffff 00000000 S FinalizerWatchd
-u0_a4     13531 13516 1503264 48612 ffffffff 00000000 S HeapTrimmerDaem
-u0_a4     13532 13516 1503264 48612 ffffffff 00000000 S GCDaemon
-u0_a4     13533 13516 1503264 48612 ffffffff 00000000 S Binder_1
-u0_a4     13534 13516 1503264 48612 ffffffff 00000000 S Binder_2
-u0_a4     13536 13516 1503264 48612 ffffffff 00000000 S ContactsProvide
-u0_a4     13537 13516 1503264 48612 ffffffff 00000000 S CallLogProvider
-u0_a102   13613 205   1521420 45204 ffffffff 00000000 S com.sohu.inputmethod.sogou:classic
-u0_a102   13616 13613 1521420 45204 ffffffff 00000000 S Heap thread poo
-u0_a102   13617 13613 1521420 45204 ffffffff 00000000 S Heap thread poo
-u0_a102   13618 13613 1521420 45204 ffffffff 00000000 S Heap thread poo
-u0_a102   13620 13613 1521420 45204 ffffffff 00000000 S Signal Catcher
-u0_a102   13623 13613 1521420 45204 ffffffff 00000000 S JDWP
-u0_a102   13624 13613 1521420 45204 ffffffff 00000000 S ReferenceQueueD
-u0_a102   13625 13613 1521420 45204 ffffffff 00000000 S FinalizerDaemon
-u0_a102   13626 13613 1521420 45204 ffffffff 00000000 S FinalizerWatchd
-u0_a102   13627 13613 1521420 45204 ffffffff 00000000 S HeapTrimmerDaem
-u0_a102   13628 13613 1521420 45204 ffffffff 00000000 S GCDaemon
-u0_a102   13629 13613 1521420 45204 ffffffff 00000000 S Binder_1
-u0_a102   13630 13613 1521420 45204 ffffffff 00000000 S Binder_2
-u0_a102   13635 13613 1521420 45204 ffffffff 00000000 S Thread-1443
-u0_a102   13636 13613 1521420 45204 ffffffff 00000000 S Thread-1444
-u0_a102   13637 13613 1521420 45204 ffffffff 00000000 S Thread-1445
-u0_a102   13638 13613 1521420 45204 ffffffff 00000000 S Thread-1446
-u0_a102   13639 13613 1521420 45204 ffffffff 00000000 S Thread-1447
-u0_a102   13641 13613 1521420 45204 ffffffff 00000000 S WifiManager
-u0_a102   13905 13613 1521420 45204 ffffffff 00000000 S Binder_3
-u0_a102   13647 205   1514052 44264 ffffffff 00000000 S com.sohu.inputmethod.sogou
-u0_a102   13651 13647 1514052 44264 ffffffff 00000000 S Heap thread poo
-u0_a102   13652 13647 1514052 44264 ffffffff 00000000 S Heap thread poo
-u0_a102   13653 13647 1514052 44264 ffffffff 00000000 S Heap thread poo
-u0_a102   13656 13647 1514052 44264 ffffffff 00000000 S Signal Catcher
-u0_a102   13657 13647 1514052 44264 ffffffff 00000000 S JDWP
-u0_a102   13658 13647 1514052 44264 ffffffff 00000000 S ReferenceQueueD
-u0_a102   13659 13647 1514052 44264 ffffffff 00000000 S FinalizerDaemon
-u0_a102   13660 13647 1514052 44264 ffffffff 00000000 S FinalizerWatchd
-u0_a102   13661 13647 1514052 44264 ffffffff 00000000 S HeapTrimmerDaem
-u0_a102   13662 13647 1514052 44264 ffffffff 00000000 S GCDaemon
-u0_a102   13663 13647 1514052 44264 ffffffff 00000000 S Binder_1
-u0_a102   13664 13647 1514052 44264 ffffffff 00000000 S Binder_2
-u0_a102   13671 205   1519416 43248 ffffffff 00000000 S sogou.mobile.explorer.hotwords
-u0_a102   13677 13671 1519416 43248 ffffffff 00000000 S Heap thread poo
-u0_a102   13678 13671 1519416 43248 ffffffff 00000000 S Heap thread poo
-u0_a102   13679 13671 1519416 43248 ffffffff 00000000 S Heap thread poo
-u0_a102   13680 13671 1519416 43248 ffffffff 00000000 S Signal Catcher
-u0_a102   13681 13671 1519416 43248 ffffffff 00000000 S JDWP
-u0_a102   13682 13671 1519416 43248 ffffffff 00000000 S ReferenceQueueD
-u0_a102   13683 13671 1519416 43248 ffffffff 00000000 S FinalizerDaemon
-u0_a102   13684 13671 1519416 43248 ffffffff 00000000 S FinalizerWatchd
-u0_a102   13685 13671 1519416 43248 ffffffff 00000000 S HeapTrimmerDaem
-u0_a102   13686 13671 1519416 43248 ffffffff 00000000 S GCDaemon
-u0_a102   13687 13671 1519416 43248 ffffffff 00000000 S Binder_1
-u0_a102   13688 13671 1519416 43248 ffffffff 00000000 S Binder_2
-u0_a102   13690 13671 1519416 43248 ffffffff 00000000 S pool-1-thread-1
-u0_a102   13691 13671 1519416 43248 ffffffff 00000000 S pool-1-thread-2
-u0_a102   13692 13671 1519416 43248 ffffffff 00000000 S pool-1-thread-3
-u0_a102   13694 13671 1519416 43248 ffffffff 00000000 S Timer-0
-u0_a198   13695 205   1506040 40332 ffffffff 00000000 S org.chromium.chrome.shell
-u0_a198   13701 13695 1506040 40332 ffffffff 00000000 S Heap thread poo
-u0_a198   13702 13695 1506040 40332 ffffffff 00000000 S Heap thread poo
-u0_a198   13703 13695 1506040 40332 ffffffff 00000000 S Heap thread poo
-u0_a198   13704 13695 1506040 40332 ffffffff 00000000 S Signal Catcher
-u0_a198   13705 13695 1506040 40332 ffffffff 00000000 S JDWP
-u0_a198   13706 13695 1506040 40332 ffffffff 00000000 S ReferenceQueueD
-u0_a198   13707 13695 1506040 40332 ffffffff 00000000 S FinalizerDaemon
-u0_a198   13708 13695 1506040 40332 ffffffff 00000000 S FinalizerWatchd
-u0_a198   13709 13695 1506040 40332 ffffffff 00000000 S HeapTrimmerDaem
-u0_a198   13710 13695 1506040 40332 ffffffff 00000000 S GCDaemon
-u0_a198   13711 13695 1506040 40332 ffffffff 00000000 S Binder_1
-u0_a198   13712 13695 1506040 40332 ffffffff 00000000 S Binder_2
-u0_a198   13713 13695 1506040 40332 ffffffff 00000000 S Binder_3
-u0_a200   13715 205   1511344 38748 ffffffff 00000000 S com.rolocule.motiontennis
-u0_a200   13721 13715 1511344 38748 ffffffff 00000000 S Heap thread poo
-u0_a200   13722 13715 1511344 38748 ffffffff 00000000 S Heap thread poo
-u0_a200   13723 13715 1511344 38748 ffffffff 00000000 S Heap thread poo
-u0_a200   13724 13715 1511344 38748 ffffffff 00000000 S Signal Catcher
-u0_a200   13725 13715 1511344 38748 ffffffff 00000000 S JDWP
-u0_a200   13731 13715 1511344 38748 ffffffff 00000000 S ReferenceQueueD
-u0_a200   13732 13715 1511344 38748 ffffffff 00000000 S FinalizerDaemon
-u0_a200   13733 13715 1511344 38748 ffffffff 00000000 S FinalizerWatchd
-u0_a200   13734 13715 1511344 38748 ffffffff 00000000 S HeapTrimmerDaem
-u0_a200   13735 13715 1511344 38748 ffffffff 00000000 S GCDaemon
-u0_a200   13736 13715 1511344 38748 ffffffff 00000000 S Binder_1
-u0_a200   13737 13715 1511344 38748 ffffffff 00000000 S Binder_2
-u0_a175   13747 205   1510096 43460 ffffffff 00000000 S com.google.android.apps.chrome
-u0_a175   13751 13747 1510096 43460 ffffffff 00000000 S Heap thread poo
-u0_a175   13752 13747 1510096 43460 ffffffff 00000000 S Heap thread poo
-u0_a175   13754 13747 1510096 43460 ffffffff 00000000 S Heap thread poo
-u0_a175   13756 13747 1510096 43460 ffffffff 00000000 S Signal Catcher
-u0_a175   13757 13747 1510096 43460 ffffffff 00000000 S JDWP
-u0_a175   13758 13747 1510096 43460 ffffffff 00000000 S ReferenceQueueD
-u0_a175   13759 13747 1510096 43460 ffffffff 00000000 S FinalizerDaemon
-u0_a175   13760 13747 1510096 43460 ffffffff 00000000 S FinalizerWatchd
-u0_a175   13761 13747 1510096 43460 ffffffff 00000000 S HeapTrimmerDaem
-u0_a175   13762 13747 1510096 43460 ffffffff 00000000 S GCDaemon
-u0_a175   13763 13747 1510096 43460 ffffffff 00000000 S Binder_1
-u0_a175   13764 13747 1510096 43460 ffffffff 00000000 S Binder_2
-u0_a85    13774 205   1594212 50972 ffffffff 00000000 S com.life360.android.safetymapd
-u0_a85    13780 13774 1594212 50972 ffffffff 00000000 S Heap thread poo
-u0_a85    13781 13774 1594212 50972 ffffffff 00000000 S Heap thread poo
-u0_a85    13782 13774 1594212 50972 ffffffff 00000000 S Heap thread poo
-u0_a85    13784 13774 1594212 50972 ffffffff 00000000 S Signal Catcher
-u0_a85    13785 13774 1594212 50972 ffffffff 00000000 S JDWP
-u0_a85    13786 13774 1594212 50972 ffffffff 00000000 S ReferenceQueueD
-u0_a85    13787 13774 1594212 50972 ffffffff 00000000 S FinalizerDaemon
-u0_a85    13788 13774 1594212 50972 ffffffff 00000000 S FinalizerWatchd
-u0_a85    13789 13774 1594212 50972 ffffffff 00000000 S HeapTrimmerDaem
-u0_a85    13790 13774 1594212 50972 ffffffff 00000000 S GCDaemon
-u0_a85    13791 13774 1594212 50972 ffffffff 00000000 S Binder_1
-u0_a85    13792 13774 1594212 50972 ffffffff 00000000 S Binder_2
-u0_a16    13801 205   1538004 50644 ffffffff 00000000 S com.android.vending
-u0_a16    13807 13801 1538004 50644 ffffffff 00000000 S Heap thread poo
-u0_a16    13808 13801 1538004 50644 ffffffff 00000000 S Heap thread poo
-u0_a16    13809 13801 1538004 50644 ffffffff 00000000 S Heap thread poo
-u0_a16    13811 13801 1538004 50644 ffffffff 00000000 S Signal Catcher
-u0_a16    13812 13801 1538004 50644 ffffffff 00000000 S JDWP
-u0_a16    13813 13801 1538004 50644 ffffffff 00000000 S ReferenceQueueD
-u0_a16    13814 13801 1538004 50644 ffffffff 00000000 S FinalizerDaemon
-u0_a16    13815 13801 1538004 50644 ffffffff 00000000 S FinalizerWatchd
-u0_a16    13816 13801 1538004 50644 ffffffff 00000000 S HeapTrimmerDaem
-u0_a16    13817 13801 1538004 50644 ffffffff 00000000 S GCDaemon
-u0_a16    13818 13801 1538004 50644 ffffffff 00000000 S Binder_1
-u0_a16    13819 13801 1538004 50644 ffffffff 00000000 S Binder_2
-u0_a16    13828 13801 1538004 50644 ffffffff 00000000 S Gservices
-u0_a16    13833 13801 1538004 50644 ffffffff 00000000 S pool-1-thread-1
-u0_a16    13834 13801 1538004 50644 ffffffff 00000000 S RefQueueWorker@
-u0_a16    13837 13801 1538004 50644 ffffffff 00000000 S RefQueueWorker@
-u0_a16    13838 13801 1538004 50644 ffffffff 00000000 S Thread-1482
-u0_a16    13839 13801 1538004 50644 ffffffff 00000000 S Thread-1483
-u0_a16    13840 13801 1538004 50644 ffffffff 00000000 S Thread-1484
-u0_a16    13843 13801 1538004 50644 ffffffff 00000000 S download-manage
-u0_a16    13844 13801 1538004 50644 ffffffff 00000000 S NetworkQualityQ
-u0_a16    13845 13801 1538004 50644 ffffffff 00000000 S RefQueueWorker@
-u0_a16    13846 13801 1538004 50644 ffffffff 00000000 S Thread-1489
-u0_a16    13847 13801 1538004 50644 ffffffff 00000000 S Thread-1490
-u0_a16    13848 13801 1538004 50644 ffffffff 00000000 S Thread-1491
-u0_a16    13849 13801 1538004 50644 ffffffff 00000000 S Thread-1492
-u0_a16    13850 13801 1538004 50644 ffffffff 00000000 S Thread-1493
-u0_a16    13851 13801 1538004 50644 ffffffff 00000000 S PlayEventLogger
-u0_a16    13852 13801 1538004 50644 ffffffff 00000000 S tentative-gc-ru
-u0_a16    13862 13801 1538004 50644 ffffffff 00000000 S libraries-threa
-u0_a16    13872 13801 1538004 50644 ffffffff 00000000 S AsyncTask #1
-u0_a16    13876 13801 1538004 50644 ffffffff 00000000 S AsyncTask #2
-u0_a16    13877 13801 1538004 50644 ffffffff 00000000 S AsyncTask #3
-u0_a16    13878 13801 1538004 50644 ffffffff 00000000 S PlayEventLogger
-u0_a16    13880 13801 1538004 50644 ffffffff 00000000 S Thread-1501
-u0_a16    14407 13801 1538004 50644 ffffffff 00000000 S Binder_3
-u0_a8     13853 205   1573700 51720 ffffffff 00000000 S com.google.android.gms:car
-u0_a8     13856 13853 1573700 51720 ffffffff 00000000 S Heap thread poo
-u0_a8     13857 13853 1573700 51720 ffffffff 00000000 S Heap thread poo
-u0_a8     13858 13853 1573700 51720 ffffffff 00000000 S Heap thread poo
-u0_a8     13863 13853 1573700 51720 ffffffff 00000000 S Signal Catcher
-u0_a8     13864 13853 1573700 51720 ffffffff 00000000 S JDWP
-u0_a8     13865 13853 1573700 51720 ffffffff 00000000 S ReferenceQueueD
-u0_a8     13866 13853 1573700 51720 ffffffff 00000000 S FinalizerDaemon
-u0_a8     13867 13853 1573700 51720 ffffffff 00000000 S FinalizerWatchd
-u0_a8     13868 13853 1573700 51720 ffffffff 00000000 S HeapTrimmerDaem
-u0_a8     13869 13853 1573700 51720 ffffffff 00000000 S GCDaemon
-u0_a8     13870 13853 1573700 51720 ffffffff 00000000 S Binder_1
-u0_a8     13871 13853 1573700 51720 ffffffff 00000000 S Binder_2
-u0_a8     13873 13853 1573700 51720 ffffffff 00000000 S Gservices
-u0_a8     13913 13853 1573700 51720 ffffffff 00000000 S Binder_3
-u0_a8     13885 205   1572668 47460 ffffffff 00000000 S com.google.android.gms.wearable
-u0_a8     13890 13885 1572668 47460 ffffffff 00000000 S Heap thread poo
-u0_a8     13891 13885 1572668 47460 ffffffff 00000000 S Heap thread poo
-u0_a8     13892 13885 1572668 47460 ffffffff 00000000 S Heap thread poo
-u0_a8     13894 13885 1572668 47460 ffffffff 00000000 S Signal Catcher
-u0_a8     13895 13885 1572668 47460 ffffffff 00000000 S JDWP
-u0_a8     13896 13885 1572668 47460 ffffffff 00000000 S ReferenceQueueD
-u0_a8     13897 13885 1572668 47460 ffffffff 00000000 S FinalizerDaemon
-u0_a8     13898 13885 1572668 47460 ffffffff 00000000 S FinalizerWatchd
-u0_a8     13899 13885 1572668 47460 ffffffff 00000000 S HeapTrimmerDaem
-u0_a8     13900 13885 1572668 47460 ffffffff 00000000 S GCDaemon
-u0_a8     13901 13885 1572668 47460 ffffffff 00000000 S Binder_1
-u0_a8     13902 13885 1572668 47460 ffffffff 00000000 S Binder_2
-u0_a8     13903 13885 1572668 47460 ffffffff 00000000 S Gservices
-root      14061 2     0      0     ffffffff 00000000 S kworker/u:3
-root      14136 2     0      0     ffffffff 00000000 S kworker/0:0H
-u0_a101   14356 205   1503136 44308 ffffffff 00000000 S com.google.android.apps.gcs
-u0_a101   14362 14356 1503136 44308 ffffffff 00000000 S Heap thread poo
-u0_a101   14363 14356 1503136 44308 ffffffff 00000000 S Heap thread poo
-u0_a101   14364 14356 1503136 44308 ffffffff 00000000 S Heap thread poo
-u0_a101   14365 14356 1503136 44308 ffffffff 00000000 S Signal Catcher
-u0_a101   14366 14356 1503136 44308 ffffffff 00000000 S JDWP
-u0_a101   14367 14356 1503136 44308 ffffffff 00000000 S ReferenceQueueD
-u0_a101   14368 14356 1503136 44308 ffffffff 00000000 S FinalizerDaemon
-u0_a101   14369 14356 1503136 44308 ffffffff 00000000 S FinalizerWatchd
-u0_a101   14370 14356 1503136 44308 ffffffff 00000000 S HeapTrimmerDaem
-u0_a101   14371 14356 1503136 44308 ffffffff 00000000 S GCDaemon
-u0_a101   14372 14356 1503136 44308 ffffffff 00000000 S Binder_1
-u0_a101   14373 14356 1503136 44308 ffffffff 00000000 S Binder_2
-u0_a101   14375 14356 1503136 44308 ffffffff 00000000 S Gservices
-u0_a101   14376 14356 1503136 44308 ffffffff 00000000 S RefQueueWorker@
-u0_a101   14377 14356 1503136 44308 ffffffff 00000000 S Thread-1495
-u0_a101   14378 14356 1503136 44308 ffffffff 00000000 S Thread-1496
-u0_a101   14379 14356 1503136 44308 ffffffff 00000000 S Thread-1497
-u0_a101   14380 14356 1503136 44308 ffffffff 00000000 S Thread-1498
-u0_a101   14381 14356 1503136 44308 ffffffff 00000000 S Thread-1499
-shell     14444 209   9316   612   c01a863c b6eeee44 S /system/bin/sh
-shell     14448 14444 10672  768   00000000 b6ef0da8 R ps
diff --git a/catapult/systrace/systrace/test_data/atrace_ps_dump b/catapult/systrace/systrace/test_data/atrace_ps_dump
deleted file mode 100644
index 3c412fc..0000000
--- a/catapult/systrace/systrace/test_data/atrace_ps_dump
+++ /dev/null
@@ -1,8 +0,0 @@
-USER     PID   PPID  VSIZE  RSS     WCHAN    PC        NAME
-root      1     0     8784   712   ffffffff 00000000 S /init
-root      2     0     0      0     ffffffff 00000000 S kthreadd
-root      3     2     0      0     ffffffff 00000000 S ksoftirqd/0
-root      7     2     0      0     ffffffff 00000000 D kworker/u:0H
-root      8     2     0      0     ffffffff 00000000 S migration/0
-root      13    2     0      0     ffffffff 00000000 S khelper
-root      14    2     0      0     ffffffff 00000000 S netns
diff --git a/catapult/systrace/systrace/test_data/atrace_ps_dump_2 b/catapult/systrace/systrace/test_data/atrace_ps_dump_2
deleted file mode 100644
index 20985c7..0000000
--- a/catapult/systrace/systrace/test_data/atrace_ps_dump_2
+++ /dev/null
@@ -1,11 +0,0 @@
-adb server version (36) doesn't match this client (38); killing...
-* daemon not running. starting it now on port 5037 *
-* daemon started successfully *
-USER     PID   PPID  VSIZE  RSS     WCHAN    PC        NAME
-root      1     0     8784   712   ffffffff 00000000 S /init
-root      2     0     0      0     ffffffff 00000000 S kthreadd
-root      3     2     0      0     ffffffff 00000000 S ksoftirqd/0
-root      7     2     0      0     ffffffff 00000000 D kworker/u:0H
-root      8     2     0      0     ffffffff 00000000 S migration/0
-root      13    2     0      0     ffffffff 00000000 S khelper
-root      14    2     0      0     ffffffff 00000000 S netns
diff --git a/catapult/systrace/systrace/test_data/atrace_ps_dump_3 b/catapult/systrace/systrace/test_data/atrace_ps_dump_3
deleted file mode 100644
index 797c61f..0000000
--- a/catapult/systrace/systrace/test_data/atrace_ps_dump_3
+++ /dev/null
@@ -1,11 +0,0 @@
-adb server version (36) doesn't match this client (38); killing...
-* daemon not running. starting it now on port 5037 *
-* daemon started successfully *
-USER     TID   PPID  VSIZE  RSS     WCHAN    PC      S CMD
-root      1     0     8784   712   ffffffff 00000000 S /init
-root      2     0     0      0     ffffffff 00000000 S kthreadd
-root      3     2     0      0     ffffffff 00000000 S ksoftirqd/0
-root      7     2     0      0     ffffffff 00000000 D kworker/u:0H
-root      8     2     0      0     ffffffff 00000000 S migration/0
-root      13    2     0      0     ffffffff 00000000 S khelper
-root      14    2     0      0     ffffffff 00000000 S netns
diff --git a/catapult/systrace/systrace/test_data/atrace_thread_names b/catapult/systrace/systrace/test_data/atrace_thread_names
deleted file mode 100644
index bff5d1b..0000000
--- a/catapult/systrace/systrace/test_data/atrace_thread_names
+++ /dev/null
@@ -1 +0,0 @@
-{1: '/init', 2: 'kthreadd', 3: 'ksoftirqd/0', 7: 'kworker/u:0H', 8: 'migration/0', 13: 'khelper', 14: 'netns', 17: 'kworker/0:1H', 18: 'modem_notifier', 19: 'smd_channel_clo', 20: 'smsm_cb_wq', 21: 'kworker/u:1', 22: 'rpm-smd', 23: 'kworker/u:1H', 24: 'irq/317-earjack', 25: 'sync_supers', 26: 'bdi-default', 27: 'kblockd', 28: 'vmalloc', 29: 'khubd', 30: 'irq/102-msm_iom', 31: 'irq/102-msm_iom', 32: 'irq/102-msm_iom', 33: 'irq/79-msm_iomm', 34: 'irq/78-msm_iomm', 35: 'irq/78-msm_iomm', 36: 'irq/74-msm_iomm', 37: 'irq/75-msm_iomm', 38: 'irq/75-msm_iomm', 39: 'irq/75-msm_iomm', 40: 'irq/75-msm_iomm', 41: 'irq/273-msm_iom', 42: 'irq/273-msm_iom', 43: 'irq/97-msm_iomm', 44: 'irq/97-msm_iomm', 45: 'irq/97-msm_iomm', 46: 'l2cap', 47: 'a2mp', 48: 'cfg80211', 49: 'qmi', 50: 'nmea', 51: 'msm_ipc_router', 52: 'apr_driver', 54: 'kswapd0', 55: 'fsnotify_mark', 56: 'cifsiod', 57: 'crypto', 75: 'ad_calc_wq', 76: 'hdmi_tx_workq', 77: 'anx7808_work', 78: 'k_hsuart', 79: 'diag_wq', 80: 'diag_cntl_wq', 81: 'diag_dci_wq', 82: 'kgsl-3d0', 84: 'f9966000.spi', 88: 'usbnet', 89: 'irq/329-anx7808', 90: 'k_rmnet_mux_wor', 91: 'f_mtp', 92: 'file-storage', 93: 'uether', 94: 'synaptics_wq', 95: 'irq/362-s3350', 96: 'kworker/0:2', 97: 'msm_vidc_worker', 98: 'msm_vidc_worker', 99: 'msm_cpp_workque', 100: 'irq/350-bq51013', 102: 'dm_bufio_cache', 103: 'dbs_sync/0', 104: 'dbs_sync/1', 105: 'dbs_sync/2', 106: 'dbs_sync/3', 107: 'cfinteractive', 108: 'irq/170-msm_sdc', 109: 'binder', 110: 'usb_bam_wq', 111: 'krfcommd', 112: 'bam_dmux_rx', 113: 'bam_dmux_tx', 114: 'rq_stats', 115: 'deferwq', 117: 'irq/361-MAX1704', 119: 'mmcqd/1', 120: 'mmcqd/1rpmb', 121: 'wl_event_handle', 122: 'dhd_watchdog_th', 123: 'dhd_dpc', 124: 'dhd_rxf', 125: 'dhd_sysioc', 126: 'vibrator', 127: 'max1462x', 128: 'irq/310-maxim_m', 129: 'irq/311-maxim_m', 130: '/sbin/ueventd', 132: 'jbd2/mmcblk0p25', 133: 'ext4-dio-unwrit', 136: 'flush-179:0', 138: 'jbd2/mmcblk0p28', 139: 'ext4-dio-unwrit', 143: 'jbd2/mmcblk0p27', 144: 'ext4-dio-unwrit', 145: 'jbd2/mmcblk0p16', 146: 'ext4-dio-unwrit', 13678: 'Heap thread poo', 13679: 'Heap thread poo', 13680: 'Signal Catcher', 13681: 'JDWP', 169: '/system/bin/logd', 170: '/sbin/healthd', 171: '/system/bin/lmkd', 172: '/system/bin/servicemanager', 173: '/system/bin/vold', 174: 'IPCRTR', 175: 'sb-1', 177: 'ipc_rtr_q6_ipcr', 179: 'ngd_msm_ctrl_ng', 180: '/system/bin/surfaceflinger', 181: '/system/bin/rmt_storage', 182: '/system/bin/qseecomd', 183: 'msm_slim_qmi_cl', 184: 'msm_qmi_rtx_q', 185: '/system/bin/sh', 187: '/system/bin/subsystem_ramdump', 188: '/system/bin/netd', 189: '/system/bin/debuggerd', 191: '/system/bin/rild', 192: '/system/bin/drmserver', 194: '/system/bin/mediaserver', 195: '/system/bin/installd', 197: '/system/bin/keystore', 198: '/system/bin/bridgemgrd', 199: '/system/bin/qmuxd', 200: '/system/bin/netmgrd', 201: '/system/bin/sensors.qcom', 204: '/system/bin/thermal-engine-hh', 205: 'zygote', 206: '/system/bin/sdcard', 207: '/system/bin/mm-qcamera-daemon', 208: '/system/bin/time_daemon', 209: '/sbin/adbd', 210: 'adbd', 211: 'adbd', 212: 'adbd', 214: 'irq/288-wcd9xxx', 216: 'logd.reader', 217: 'logd.writer', 218: 'logd', 219: 'kauditd', 13690: 'pool-1-thread-1', 223: 'vold', 226: 'vold', 227: 'sdcard', 228: 'sdcard', 240: 'Binder_1', 242: 'DispSync', 243: 'Binder_2', 244: 'logd.auditd', 247: 'thermal-engine-', 250: 'thermal-engine-', 13695: 'org.chromium.chrome.shell', 252: 'thermal-engine-', 253: 'thermal-engine-', 254: 'thermal-engine-', 255: 'thermal-engine-', 257: 'thermal-engine-', 258: 'thermal-engine-', 259: 'thermal-engine-', 260: 'thermal-engine-', 261: 'thermal-engine-', 262: 'thermal-engine-', 263: 'thermal-engine-', 264: 'thermal-engine-', 265: 'thermal-engine-', 266: 'thermal-engine-', 267: 'thermal-engine-', 268: 'thermal-engine-', 269: 'thermal-engine-', 270: 'thermal-engine-', 272: 'thermal-engine-', 273: 'thermal-engine-', 275: 'thermal-engine-', 276: 'thermal-engine-', 277: 'thermal-engine-', 278: 'thermal-engine-', 280: 'thermal-engine-', 281: 'thermal-engine-', 282: 'thermal-engine-', 283: 'thermal-engine-', 284: 'thermal-engine-', 286: 'thermal-engine-', 287: 'thermal-engine-', 288: 'bridgemgrd', 289: 'netmgrd', 290: 'sensors.qcom', 292: 'sensors.qcom', 293: 'qmuxd', 295: 'thermal-engine-', 297: 'thermal-engine-', 299: 'thermal-engine-', 300: 'thermal-engine-', 301: 'thermal-engine-', 308: 'time_daemon', 311: 'msm_thermal:hot', 312: 'msm_thermal:fre', 13707: 'FinalizerDaemon', 335: 'rild', 13710: 'GCDaemon', 343: 'rild', 346: 'rild', 13711: 'Binder_1', 348: '/system/bin/qseecomd', 349: 'qseecomd', 351: 'qseecomd', 360: 'mdss_fb0', 361: 'hwcUeventThread', 362: 'hwcVsyncThread', 8569: 'Binder_4', 8572: 'Binder_5', 8575: 'Binder_5', 386: 'qseecomd', 387: 'qseecomd', 8580: 'Binder_6', 8581: 'Binder_5', 396: 'GL updater', 397: 'surfaceflinger', 398: 'EventThread', 399: 'surfaceflinger', 400: 'EventThread', 401: 'EventControl', 13721: 'Heap thread poo', 13722: 'Heap thread poo', 419: 'Binder_1', 13724: 'Signal Catcher', 13725: 'JDWP', 548: 'netd', 549: 'netd', 550: 'netd', 551: 'netd', 552: 'netd', 553: 'netd', 554: 'netd', 555: 'netd', 557: 'kworker/0:2H', 558: 'IPCRTR', 559: 'thermal-engine-', 560: 'sensors.qcom', 561: 'time_daemon', 562: 'ipc_rtr_smd_ipc', 563: 'sensors.qcom', 564: 'sensors.qcom', 571: 'rmt_storage', 572: 'rmt_storage', 573: 'rmt_storage', 574: 'rmt_storage', 575: 'Binder_3', 576: 'qmuxd', 577: 'qmuxd', 578: 'qmuxd', 579: 'qmuxd', 580: 'qmuxd', 581: 'qmuxd', 582: 'qmuxd', 583: 'qmuxd', 584: 'rild', 585: 'rild', 587: 'rild', 588: 'rild', 589: 'rild', 591: 'rild', 592: 'rild', 593: 'rild', 594: 'rild', 596: 'thermal-engine-', 597: 'time_daemon', 598: 'time_daemon', 599: 'time_daemon', 600: 'thermal-engine-', 601: 'thermal-engine-', 602: 'bridgemgrd', 603: 'bridgemgrd', 605: 'sensors.qcom', 614: 'sensors.qcom', 621: 'sensors.qcom', 622: 'sensors.qcom', 623: 'sensors.qcom', 624: 'sensors.qcom', 625: 'sensors.qcom', 626: 'sensors.qcom', 627: 'sensors.qcom', 628: 'sensors.qcom', 629: 'sensors.qcom', 13660: 'FinalizerWatchd', 633: 'sensors.qcom', 13760: 'FinalizerWatchd', 643: 'sensors.qcom', 8839: 'com.ushaqi.zhuishushenqi:pushservice', 650: 'sensors.qcom', 651: 'sensors.qcom', 8845: 'Heap thread poo', 8846: 'Heap thread poo', 8847: 'Heap thread poo', 8849: 'Signal Catcher', 8850: 'JDWP', 8851: 'ReferenceQueueD', 8852: 'FinalizerDaemon', 8853: 'FinalizerWatchd', 8854: 'HeapTrimmerDaem', 8855: 'GCDaemon', 8856: 'Binder_1', 8857: 'Binder_2', 8867: 'local_job_dispa', 8869: 'remote_job_disp', 8887: 'Upload Http Rec', 8890: 'Connection Cont', 13774: 'com.life360.android.safetymapd', 736: 'netmgrd', 746: 'netmgrd', 747: 'netmgrd', 748: 'netmgrd', 755: 'ApmTone', 756: 'ApmAudio', 757: 'ApmOutput', 758: 'mediaserver', 759: 'FastMixer', 760: 'sensors.qcom', 763: 'sensors.qcom', 764: 'system_server', 767: 'Heap thread poo', 768: 'Heap thread poo', 770: 'Heap thread poo', 8963: 'Smack Packet Re', 773: 'Signal Catcher', 774: 'JDWP', 775: 'ReferenceQueueD', 776: 'FinalizerDaemon', 777: 'FinalizerWatchd', 778: 'HeapTrimmerDaem', 779: 'GCDaemon', 780: 'Binder_1', 781: 'Binder_2', 782: 'system_server', 783: 'system_server', 784: 'sensors.qcom', 785: 'system_server', 786: 'system_server', 788: 'system_server', 789: 'system_server', 790: 'sensors.qcom', 791: 'system_server', 792: 'sensors.qcom', 793: 'system_server', 794: 'sensors.qcom', 795: 'system_server', 796: 'sensors.qcom', 797: 'system_server', 798: 'sensors.qcom', 799: 'system_server', 800: 'sensors.qcom', 801: 'system_server', 802: 'sensors.qcom', 803: 'system_server', 804: 'sensors.qcom', 805: 'system_server', 806: 'sensors.qcom', 807: 'system_server', 808: 'sensors.qcom', 809: 'system_server', 810: 'sensors.qcom', 811: 'system_server', 812: 'sensors.qcom', 813: 'system_server', 814: 'sensors.qcom', 815: 'system_server', 816: 'sensors.qcom', 817: 'system_server', 818: 'sensors.qcom', 819: 'system_server', 820: 'sensors.qcom', 821: 'system_server', 822: 'sensors.qcom', 823: 'system_server', 824: 'sensors.qcom', 826: 'SensorEventAckR', 827: 'SensorService', 828: 'android.bg', 829: 'ActivityManager', 830: 'FileObserver', 831: 'android.fg', 832: 'android.ui', 833: 'android.io', 834: 'android.display', 835: 'CpuTracker', 836: 'PowerManagerSer', 837: 'system_server', 838: 'system_server', 839: 'BatteryStats_wa', 840: 'PackageManager', 841: 'bridgemgrd', 842: 'PackageInstalle', 844: 'AlarmManager', 845: 'UEventObserver', 853: 'InputDispatcher', 854: 'InputReader', 857: 'MountService', 858: 'VoldConnector', 4239: 'FinalizerDaemon', 860: 'NetdConnector', 861: 'NetworkStats', 862: 'NetworkPolicy', 863: 'WifiP2pService', 864: 'WifiStateMachin', 865: 'WifiService', 866: 'ConnectivitySer', 867: 'NsdService', 868: 'mDnsConnector', 869: 'ranker', 870: 'AudioService', 871: 'AudioOut_2', 872: 'AudioOut_4', 873: 'FastMixer', 874: 'AudioOut_6', 878: 'Binder_1', 879: 'Binder_2', 882: 'WifiWatchdogSta', 883: 'WifiManager', 884: 'WifiScanningSer', 885: 'WifiRttService', 886: 'EthernetService', 887: 'backup', 888: '/system/bin/wpa_supplicant', 889: 'Thread-69', 892: 'LazyTaskWriterT', 893: 'UsbService host', 894: 'Thread-73', 915: 'com.android.systemui', 919: 'Heap thread poo', 920: 'Heap thread poo', 921: 'Heap thread poo', 925: 'Signal Catcher', 926: 'JDWP', 927: 'ReferenceQueueD', 928: 'FinalizerDaemon', 929: 'FinalizerWatchd', 930: 'HeapTrimmerDaem', 931: 'GCDaemon', 933: 'Binder_1', 934: 'Binder_2', 936: 'android.process.media', 942: 'Binder_3', 943: 'Heap thread poo', 944: 'Heap thread poo', 945: 'Heap thread poo', 947: 'Signal Catcher', 949: 'JDWP', 950: 'ReferenceQueueD', 951: 'FinalizerDaemon', 952: 'FinalizerWatchd', 953: 'HeapTrimmerDaem', 954: 'GCDaemon', 956: 'Binder_1', 957: 'Binder_2', 13671: 'sogou.mobile.explorer.hotwords', 964: 'SoundPool', 965: 'SoundPoolThread', 970: 'Recents-TaskRes', 13819: 'Binder_2', 1007: 'thumbs thread', 1020: 'MtpServer', 1078: 'SystemUI Storag', 1079: 'watchdog', 1094: 'SoundPool', 1095: 'SoundPoolThread', 1108: 'Binder_4', 1109: 'Binder_5', 1111: 'com.google.android.googlequicksearchbox:interactor', 1113: 'Heap thread poo', 1114: 'Heap thread poo', 1116: 'Heap thread poo', 1121: 'Signal Catcher', 1124: 'JDWP', 1125: 'ReferenceQueueD', 1126: 'FinalizerDaemon', 1127: 'FinalizerWatchd', 1128: 'HeapTrimmerDaem', 1129: 'GCDaemon', 1131: 'Binder_1', 1132: 'Binder_2', 1133: 'Binder_3', 1136: 'com.google.android.inputmethod.pinyin', 1142: 'Heap thread poo', 1143: 'Heap thread poo', 1144: 'Heap thread poo', 1145: 'Signal Catcher', 1146: 'JDWP', 1147: 'ReferenceQueueD', 1148: 'FinalizerDaemon', 1149: 'FinalizerWatchd', 1151: 'HeapTrimmerDaem', 1152: 'GCDaemon', 1153: 'Binder_1', 1154: 'Binder_2', 1186: 'FLP Service Cal', 1188: 'FLP Service Cal', 1191: 'NetworkTimeUpda', 1192: 'FLP Service Cal', 1199: 'com.android.nfc', 1208: 'Heap thread poo', 1209: 'Heap thread poo', 1210: 'Heap thread poo', 1211: 'Signal Catcher', 1212: 'JDWP', 1213: 'ReferenceQueueD', 1214: 'FinalizerDaemon', 1215: 'FinalizerWatchd', 1216: 'HeapTrimmerDaem', 1219: 'GCDaemon', 1220: 'Binder_1', 1221: 'Binder_2', 1226: 'Binder_6', 1233: 'Binder_7', 1234: 'com.redbend.vdmc', 1236: 'Heap thread poo', 1237: 'Heap thread poo', 1238: 'Heap thread poo', 1244: 'Signal Catcher', 1245: 'JDWP', 1246: 'ReferenceQueueD', 1247: 'FLP Service Cal', 1248: 'FinalizerDaemon', 1249: 'FinalizerWatchd', 1250: 'HeapTrimmerDaem', 1251: 'GCDaemon', 1252: 'Binder_1', 1256: 'Binder_8', 1257: 'Binder_2', 1260: 'WifiMonitor', 1271: 'Binder_9', 1274: 'com.android.phone', 1282: 'Heap thread poo', 1283: 'Heap thread poo', 1284: 'Heap thread poo', 1285: 'Signal Catcher', 1286: 'JDWP', 1287: 'ReferenceQueueD', 1288: 'FLP Service Cal', 1289: 'FLP Service Cal', 1290: 'FinalizerDaemon', 1291: 'FinalizerWatchd', 1292: 'HeapTrimmerDaem', 1293: 'GCDaemon', 1299: 'Binder_1', 1305: 'com.google.android.googlequicksearchbox', 1306: 'Heap thread poo', 1307: 'Heap thread poo', 1308: 'Heap thread poo', 1315: 'Binder_2', 1317: 'Signal Catcher', 1318: 'JDWP', 1319: 'FLP Service Cal', 1320: 'FLP Service Cal', 1322: 'ReferenceQueueD', 1323: 'FinalizerDaemon', 1324: 'FinalizerWatchd', 1330: 'GAThread', 1331: 'measurement-1', 1332: 'HeapTrimmerDaem', 1333: 'GCDaemon', 1334: 'Binder_1', 1335: 'Binder_2', 1336: 'pool-1-thread-1', 13684: 'FinalizerWatchd', 13880: 'Thread-1501', 1365: 'RILSender0', 1366: 'RILReceiver0', 1367: 'Thread-89', 1378: 'PhoneStatusBar', 1380: 'DcHandlerThread', 1381: 'WifiManager', 1385: 'AsyncTask #1', 1386: 'launcher-loader', 1388: 'AsyncTask #1', 1391: 'AsyncQueryWorke', 1392: 'GsmCellBroadcas', 1393: 'AsyncTask #1', 1394: 'GsmInboundSmsHa', 1395: 'AsyncTask #1', 1397: 'CellBroadcastHa', 1408: 'AsyncTask #1', 1409: 'AsyncTask #1', 1416: 'ConnectivityMan', 1417: 'CdmaInboundSmsH', 1418: 'CdmaServiceCate', 13890: 'Heap thread poo', 1425: 'AsyncTask #1', 1427: 'DcSwitchStateMa', 1428: 'Binder_3', 1429: 'SyncHandler-0', 1431: 'FlashlightContr', 1432: 'AsyncTask #2', 13892: 'Heap thread poo', 1434: 'AsyncTask #1', 1435: 'QSTileHost', 1438: 'AsyncTask #2', 1441: 'RenderThread', 1442: 'AsyncTask #3', 1443: 'AsyncTask #1', 13894: 'Signal Catcher', 1451: 'com.google.android.googlequicksearchbox:search', 1457: 'Heap thread poo', 1458: 'Heap thread poo', 1459: 'Heap thread poo', 1460: 'Signal Catcher', 1461: 'JDWP', 1462: 'ReferenceQueueD', 1463: 'FinalizerDaemon', 1464: 'FinalizerWatchd', 1466: 'HeapTrimmerDaem', 1468: 'GCDaemon', 1473: 'Binder_3', 1474: 'Binder_1', 1475: 'Binder_2', 1478: 'com.google.process.gapps', 1484: 'GELServices-0', 1485: 'Heap thread poo', 1486: 'Heap thread poo', 1487: 'Heap thread poo', 1488: 'Signal Catcher', 1489: 'JDWP', 1490: 'ReferenceQueueD', 1491: 'FinalizerDaemon', 1492: 'FinalizerWatchd', 1493: 'HeapTrimmerDaem', 1494: 'GCDaemon', 1495: 'Binder_1', 1496: 'Binder_2', 1497: 'Binder_3', 1501: 'Binder_4', 1503: 'AsyncTask #1', 1514: 'RenderThread', 1515: 'User-Facing Non', 1516: 'User-Facing Non', 1517: 'ervice.Executor', 1518: 'WifiManager', 1535: 'User-Facing Non', 1538: 'User-Facing Non', 1540: 'AsyncTask #3', 1553: 'User-Facing Non', 1560: 'IcingConnection', 1561: 'AsyncTask #1', 1563: 'Cat Telephony s', 1564: 'RilMessageDecod', 1565: 'hwuiTask1', 1566: 'hwuiTask2', 1567: 'Cat Icon Loader', 1573: 'Thread-55', 1574: 'Thread-56', 1575: 'Thread-57', 1577: 'SoundPool', 1578: 'SoundPoolThread', 1580: 'AudioRouter-0', 1593: 'sensors.qcom', 1600: 'sensors.qcom', 1613: 'Gservices', 1614: 'RefQueueWorker@', 1615: 'Gservices', 1616: 'RefQueueWorker@', 1618: 'GELServices-1', 1620: 'Gservices', 1621: 'GELServices-2', 1622: 'AsyncTask #2', 1626: 'AsyncFileStorag', 1629: 'GELServices-3', 1632: 'AsyncTask #4', 1633: 'AsyncTask #5', 1635: 'WifiManager', 1636: 'GELServices-4', 1637: 'AsyncTask #4', 1643: 'LocationOracleI', 1644: 'GL updater', 1646: 'GoogleApiClient', 1647: 'GELServices-5', 1654: 'Binder_A', 1664: 'GELServices-6', 1690: 'Binder_4', 1692: 'GL updater', 1693: 'NetworkMonitorN', 1695: 'DhcpStateMachin', 1700: '/system/bin/dhcpcd', 1764: 'Binder_3', 1766: 'GELServices-7', 1769: 'Binder_3', 1770: 'Gservices', 1772: 'RenderThread', 1773: 'RenderThread', 1774: 'RenderThread', 1775: 'RenderThread', 1781: 'AsyncTask #1', 1782: 'AsyncTask #2', 1807: 'RenderThread', 1810: 'ChromiumNet', 1811: 'DnsConfigServic', 1812: 'inotify_reader', 1815: 'Network File Th', 1816: 'SimpleCacheWork', 1817: 'SimpleCacheWork', 1823: 'Binder_4', 1824: 'Binder_5', 1873: 'com.google.android.gms', 1878: 'Heap thread poo', 1880: 'Heap thread poo', 1881: 'Heap thread poo', 1882: 'Signal Catcher', 1883: 'JDWP', 1884: 'ReferenceQueueD', 1885: 'FinalizerDaemon', 1886: 'FinalizerWatchd', 1887: 'HeapTrimmerDaem', 1888: 'GCDaemon', 1889: 'Binder_1', 1890: 'Binder_2', 13702: 'Heap thread poo', 1895: 'Gservices', 1898: 'measurement-1', 1900: 'AsyncTask #1', 1904: 'AsyncTask #2', 1949: 'com.google.android.gms.persistent', 1954: 'Heap thread poo', 1955: 'Heap thread poo', 1956: 'Heap thread poo', 1959: 'Signal Catcher', 1960: 'JDWP', 1961: 'ReferenceQueueD', 1962: 'FinalizerDaemon', 1963: 'FinalizerWatchd', 1964: 'HeapTrimmerDaem', 1965: 'GCDaemon', 1966: 'Binder_1', 1967: 'Binder_2', 1968: 'Gservices', 1973: 'IntentService[G', 1976: 'FlpThread', 1977: 'Binder_3', 1978: 'WifiManager', 1979: 'GeofencerStateM', 1980: 'LocationService', 1984: 'Binder_4', 1986: 'Binder_5', 1990: 'pool-4-thread-1', 1992: 'GmsCoreStatsSer', 1995: 'GoogleLocationS', 1996: 'Binder_4', 1997: 'Binder_5', 1998: 'GELServices-8', 2001: 'Binder_3', 2004: 'Thread-139', 2005: 'Thread-140', 2006: 'Thread-141', 2007: 'Thread-142', 2021: 'NetworkLocation', 2029: 'UlrDispatchingS', 2030: 'nlp-async-worke', 2031: '/system/bin/mpdecision', 2032: 'mpdecision', 2033: 'mpdecision', 2034: 'mpdecision', 2035: 'mpdecision', 2036: 'mpdecision', 2046: 'mpdecision', 2097: 'AsyncTask #3', 2124: 'SyncHandler-0', 2320: 'RemoteViewsCach', 2321: 'RemoteViewsAdap', 10584: 'pool-2-thread-1', 10591: 'RefQueueWorker@', 2497: 'WifiManager', 2509: 'picasa-uploads-', 2510: 'GCMWriter', 2512: 'AsyncTask #1', 2521: 'FitnessServiceF', 2522: 'FitRecordingBro', 13723: 'Heap thread poo', 2526: 'AsyncTask #1', 2530: 'NearbyMessagesB', 2536: 'GCMReader', 2547: 'pool-2-thread-1', 2647: 'com.qiyi.video.market', 2653: 'Heap thread poo', 2654: 'Heap thread poo', 2655: 'Heap thread poo', 2656: 'Signal Catcher', 2657: 'JDWP', 2658: 'ReferenceQueueD', 2659: 'FinalizerDaemon', 2660: 'FinalizerWatchd', 2661: 'HeapTrimmerDaem', 2662: 'GCDaemon', 2663: 'Binder_1', 2664: 'Binder_2', 2671: 'RefQueueWorker@', 2673: '.ProcessManager', 2675: 'Binder_3', 2677: 'Thread-208', 2679: 'pool-2-thread-1', 2680: 'WifiManager', 2682: 'Timer-0', 2683: 'Timer-1', 2710: 'AsyncTask #1', 2718: 'pool-3-thread-1', 2810: 'DownloadReceive', 2902: 'GELServices-9', 2905: 'PowerManagerSer', 2906: 'AsyncTask #2', 2915: 'AsyncTask #3', 2946: 'pool-7-thread-1', 3103: 'pool-4-thread-1', 3104: 'com.qiyi.video.market:pluginDownloadService', 3110: 'Heap thread poo', 3111: 'Heap thread poo', 3112: 'Heap thread poo', 3113: 'Signal Catcher', 3114: 'JDWP', 3115: 'ReferenceQueueD', 3116: 'FinalizerDaemon', 3117: 'FinalizerWatchd', 3118: 'HeapTrimmerDaem', 3119: 'GCDaemon', 3120: 'Binder_1', 3121: 'Binder_2', 3122: 'com.qiyi.video.market:bdservice_v1', 3128: 'Heap thread poo', 3129: 'Heap thread poo', 3130: 'Heap thread poo', 3131: 'Signal Catcher', 3132: 'JDWP', 3133: 'ReferenceQueueD', 3134: 'FinalizerDaemon', 3135: 'FinalizerWatchd', 3136: 'HeapTrimmerDaem', 3137: 'GCDaemon', 3138: 'Binder_1', 3139: 'Binder_2', 3141: 'RefQueueWorker@', 3145: 'RefQueueWorker@', 3154: 'com.qiyi.video.market:baiduLocation', 3163: 'Heap thread poo', 3164: 'Heap thread poo', 3165: 'Heap thread poo', 3166: 'Signal Catcher', 3167: 'JDWP', 3168: 'ReferenceQueueD', 3169: 'FinalizerDaemon', 3170: 'FinalizerWatchd', 3171: 'HeapTrimmerDaem', 3172: 'GCDaemon', 3173: 'Binder_1', 3174: 'Binder_2', 3177: 'RefQueueWorker@', 3179: 'com.tencent.mm:push', 3183: 'Heap thread poo', 3184: 'Heap thread poo', 3185: 'Heap thread poo', 3187: 'Signal Catcher', 3189: 'JDWP', 3190: 'ReferenceQueueD', 3191: 'FinalizerDaemon', 3192: 'FinalizerWatchd', 3193: 'HeapTrimmerDaem', 3194: 'GCDaemon', 3195: 'Binder_1', 3196: 'Binder_2', 3199: 'WifiManager', 3206: 'WifiManager', 3208: 'NanoHttpd Main ', 3210: 'THREAD_POOL_HAN', 3212: 'tencent.mm:push', 3216: 'FileObserver', 3217: 'com.baidu.searchbox:bdservice_v1', 3220: 'Heap thread poo', 3221: 'Heap thread poo', 3223: 'Heap thread poo', 3226: 'Signal Catcher', 3228: 'JDWP', 3229: 'ReferenceQueueD', 3230: 'FinalizerDaemon', 3231: 'FinalizerWatchd', 3233: 'HeapTrimmerDaem', 3234: 'GCDaemon', 3235: 'Binder_1', 3236: 'Binder_2', 3238: 'tencent.mm:push', 3239: 'default', 3240: 'WifiManager', 3257: 'pool-3-thread-1', 3260: 'com.baidu.searchbox:bdmoservice', 3264: 'Heap thread poo', 3265: 'Heap thread poo', 3266: 'Heap thread poo', 3269: 'Signal Catcher', 3270: 'JDWP', 3271: 'ReferenceQueueD', 3272: 'FinalizerDaemon', 3273: 'FinalizerWatchd', 3274: 'HeapTrimmerDaem', 3275: 'GCDaemon', 3276: 'Binder_1', 3277: 'Binder_2', 3303: 'AsyncTask #1', 3304: 'AsyncTask #2', 11634: 'kworker/u:0', 13754: 'Heap thread poo', 3518: 'PushService-Pus', 3519: 'PushService-Pus', 11779: 'kworker/0:3H', 3633: 'com.tencent.portfolio:push', 3636: 'Heap thread poo', 3638: 'Heap thread poo', 3639: 'Heap thread poo', 3642: 'Signal Catcher', 3643: 'JDWP', 3645: 'ReferenceQueueD', 3646: 'FinalizerDaemon', 3647: 'FinalizerWatchd', 3648: 'HeapTrimmerDaem', 3649: 'GCDaemon', 3650: 'Binder_1', 3651: 'Binder_2', 3661: 'TPPluginCenter ', 3663: 'pool-1-thread-1', 3665: 'MidService', 13761: 'HeapTrimmerDaem', 3667: 'pool-2-thread-1', 3668: 'push core threa', 3670: '.ProcessManager', 3672: 'Binder_3', 11865: 'pool-37-thread-', 3674: 'pool-4-thread-1', 3675: 'pool-3-thread-1', 3680: 'WifiManager', 13762: 'GCDaemon', 11928: 'kworker/0:1', 3738: 'NanoHttpd Main ', 12039: 'pool-1-thread-1', 12193: 'Background Bloc', 12207: 'User-Facing Blo', 12211: 'WorkerPool/1221', 12232: 'Background Non-', 12235: 'Background Bloc', 12236: 'Background Bloc', 12237: 'Background Non-', 4135: 'AsyncTask #2', 4159: 'AsyncTask #3', 4180: 'AsyncTask #2', 4184: 'AsyncTask #4', 12988: 'Binder_2', 4210: 'AsyncTask #5', 4221: 'AsyncTask #3', 4223: 'AsyncTask #4', 4226: 'AsyncTask #4', 4227: 'com.android.bluetooth', 4231: 'Heap thread poo', 4233: 'Heap thread poo', 4235: 'Heap thread poo', 4236: 'Signal Catcher', 4237: 'JDWP', 4238: 'ReferenceQueueD', 12431: 'kworker/u:2', 4240: 'FinalizerWatchd', 4241: 'HeapTrimmerDaem', 4242: 'GCDaemon', 4243: 'Binder_1', 4244: 'Binder_2', 12448: 'OkHttp Connecti', 12449: 'OkHttp Connecti', 4265: 'UsbDebuggingMan', 12484: 'AsyncTask #4', 13782: 'Heap thread poo', 4308: 'BluetoothAdapte', 4309: 'droid.bluetooth', 4311: 'bluedroid wake/', 4312: 'BT Service Call', 4315: 'BondStateMachin', 4316: 'Binder_3', 4317: 'Binder_4', 4318: 'HeadsetStateMac', 4320: 'BluetoothAvrcpH', 4321: 'A2dpStateMachin', 4322: 'A2DP-MEDIA', 4323: 'uipc-main', 4324: 'BluetoothHdpHan', 4325: 'droid.bluetooth', 4326: 'BluetoothAdvert', 4327: 'BluetoothScanMa', 4331: 'bluedroid wake/', 4333: 'bt_hc_worker', 4338: 'userial_read', 13784: 'Signal Catcher', 12576: 'AsyncTask #5', 13785: 'JDWP', 4390: 'pool-13-thread-', 4391: 'pool-18-thread-', 4392: 'pool-11-thread-', 4394: 'pool-25-thread-', 4395: 'pool-25-thread-', 4396: 'pool-25-thread-', 4397: 'pool-25-thread-', 4398: 'pool-14-thread-', 13786: 'ReferenceQueueD', 13787: 'FinalizerDaemon', 13788: 'FinalizerWatchd', 4478: 'BT Service Call', 4479: 'bt_hc_worker', 4480: 'Binder_4', 4481: 'bt_hc_worker', 4482: 'BluetoothMapAcc', 13789: 'HeapTrimmerDaem', 4521: 'MediaTracker bu', 14407: 'Binder_3', 6217: 'HeapTrimmerDaem', 4541: 'RefQueueWorker@', 13791: 'Binder_1', 4571: 'Stk App Service', 4597: 'com.qualcomm.qcrilmsgtunnel', 4603: 'Heap thread poo', 4604: 'Heap thread poo', 4605: 'Heap thread poo', 4606: 'Signal Catcher', 4607: 'JDWP', 4608: 'ReferenceQueueD', 4609: 'FinalizerDaemon', 4610: 'FinalizerWatchd', 4611: 'HeapTrimmerDaem', 4612: 'GCDaemon', 4613: 'Binder_1', 4614: 'Binder_2', 4615: 'QcRilReceiver', 4616: 'QcRilSender', 4735: 'pool-8-thread-1', 4749: 'CopresenceEvent', 4766: 'Icing-Pool-0', 4770: 'Binder_6', 4771: 'Icing-Worker-0', 12971: 'com.life360.android.safetymapd:service', 12977: 'Heap thread poo', 12978: 'Heap thread poo', 12979: 'Heap thread poo', 12980: 'Signal Catcher', 12981: 'JDWP', 12982: 'ReferenceQueueD', 12983: 'FinalizerDaemon', 12984: 'FinalizerWatchd', 12985: 'HeapTrimmerDaem', 12986: 'GCDaemon', 12987: 'Binder_1', 4796: 'Thread-200', 4797: 'Thread-201', 4798: 'Thread-202', 4799: 'Thread-203', 4800: 'Thread-204', 9001: 'Gservices', 13071: 'com.xianguo.tingguo', 13075: 'Heap thread poo', 13076: 'Heap thread poo', 13077: 'Heap thread poo', 13080: 'Signal Catcher', 13081: 'JDWP', 13082: 'ReferenceQueueD', 13083: 'FinalizerDaemon', 13084: 'FinalizerWatchd', 13085: 'HeapTrimmerDaem', 13086: 'GCDaemon', 13087: 'Binder_1', 13088: 'Binder_2', 13090: 'SoundPool', 13091: 'SoundPoolThread', 13099: 'WifiManager', 4917: 'Binder_3', 9024: 'GamesProviderWo', 13276: 'WifiManager', 13345: 'com.google.android.apps.photos', 13351: 'Heap thread poo', 13352: 'Heap thread poo', 13353: 'Heap thread poo', 13354: 'Signal Catcher', 13355: 'JDWP', 13356: 'ReferenceQueueD', 13357: 'FinalizerDaemon', 13358: 'FinalizerWatchd', 13359: 'HeapTrimmerDaem', 13360: 'GCDaemon', 13361: 'Binder_1', 13362: 'Binder_2', 5239: '.iqiyipushserviceGlobal', 5242: 'Heap thread poo', 5244: 'Heap thread poo', 5245: 'Heap thread poo', 5248: 'Signal Catcher', 5249: 'JDWP', 5250: 'ReferenceQueueD', 5251: 'FinalizerDaemon', 5252: 'FinalizerWatchd', 5253: 'HeapTrimmerDaem', 5254: 'GCDaemon', 5255: 'Binder_1', 5257: 'Binder_2', 5280: 'RefQueueWorker@', 5281: 'Binder_3', 5285: '.iqiyipushserviceGlobal', 13491: 'com.google.android.apps.plus', 13493: 'Heap thread poo', 13494: 'Heap thread poo', 13495: 'Heap thread poo', 13497: 'Signal Catcher', 13499: 'JDWP', 13502: 'ReferenceQueueD', 13503: 'FinalizerDaemon', 13504: 'FinalizerWatchd', 13505: 'HeapTrimmerDaem', 13506: 'GCDaemon', 13507: 'Binder_1', 13508: 'Binder_2', 13512: 'picasa-photo-pr', 5323: 'com.strava', 13516: 'android.process.acore', 5327: 'Heap thread poo', 13520: 'Heap thread poo', 5329: 'Heap thread poo', 13522: 'Heap thread poo', 5332: 'Signal Catcher', 5333: 'JDWP', 5334: 'ReferenceQueueD', 13527: 'ReferenceQueueD', 5336: 'FinalizerWatchd', 13529: 'FinalizerDaemon', 13530: 'FinalizerWatchd', 13531: 'HeapTrimmerDaem', 13532: 'GCDaemon', 13533: 'Binder_1', 13534: 'Binder_2', 13536: 'ContactsProvide', 13537: 'CallLogProvider', 13538: 'pool-2-thread-1', 5347: 'Queue', 5348: 'Queue', 5349: 'Queue', 5352: 'Crashlytics Exc', 5354: 'pool-3-thread-1', 5361: 'Micro Client Co', 5362: 'Micro Client Co', 5363: 'Micro Client Ca', 5364: 'Thread-584', 5365: 'Thread-585', 5366: 'Thread-586', 5367: 'pool-4-thread-1', 5369: 'Crashlytics Tra', 5372: 'Thread-593', 5373: 'Thread-594', 5374: 'Thread-595', 5375: 'Thread-596', 5376: 'pool-6-thread-1', 5377: 'Thread-598', 5378: 'Thread-599', 5379: 'Thread-600', 5381: 'Thread-602', 5383: 'Thread #1', 5384: 'AsyncTask #1', 5387: 'Thread-605', 5388: 'Thread-606', 5389: 'Thread-607', 5390: 'Thread-608', 5391: 'Thread-609', 5393: 'eNowAuthService', 5394: 'Thread #2', 5395: 'com.pandora.android', 5397: 'Heap thread poo', 5398: 'Heap thread poo', 5399: 'Heap thread poo', 5401: 'Signal Catcher', 5403: 'JDWP', 5407: 'ReferenceQueueD', 5408: 'FinalizerDaemon', 5409: 'FinalizerWatchd', 5410: 'HeapTrimmerDaem', 5411: 'GCDaemon', 5414: 'Binder_1', 5416: 'Binder_2', 13613: 'com.sohu.inputmethod.sogou:classic', 5422: 'Crashlytics Exc', 13616: 'Heap thread poo', 13617: 'Heap thread poo', 13618: 'Heap thread poo', 13620: 'Signal Catcher', 5429: 'pool-2-thread-1', 5430: 'AsyncTask #1', 13623: 'JDWP', 13624: 'ReferenceQueueD', 13625: 'FinalizerDaemon', 13626: 'FinalizerWatchd', 13627: 'HeapTrimmerDaem', 13628: 'GCDaemon', 5437: 'Crashlytics Tra', 13630: 'Binder_2', 5439: 'AsyncTask #2', 5440: 'pool-4-thread-1', 5443: 'PurchasingManag', 13636: 'Thread-1444', 5445: 'AsyncTask #3', 13638: 'Thread-1446', 13639: 'Thread-1447', 13641: 'WifiManager', 13647: 'com.sohu.inputmethod.sogou', 13651: 'Heap thread poo', 13652: 'Heap thread poo', 13653: 'Heap thread poo', 13656: 'Signal Catcher', 13657: 'JDWP', 13658: 'ReferenceQueueD', 13659: 'FinalizerDaemon', 5468: 'Okio Watchdog', 13661: 'HeapTrimmerDaem', 13662: 'GCDaemon', 13663: 'Binder_1', 13664: 'Binder_2', 5474: 'tunein.player', 5479: 'Heap thread poo', 5480: 'Heap thread poo', 5481: 'Heap thread poo', 5483: 'Signal Catcher', 5484: 'JDWP', 5485: 'ReferenceQueueD', 5486: 'FinalizerDaemon', 5487: 'FinalizerWatchd', 5488: 'HeapTrimmerDaem', 5489: 'GCDaemon', 5490: 'Binder_1', 13683: 'FinalizerDaemon', 5492: 'Binder_2', 13685: 'HeapTrimmerDaem', 13686: 'GCDaemon', 13687: 'Binder_1', 13688: 'Binder_2', 5498: 'Thread #3', 13691: 'pool-1-thread-2', 13692: 'pool-1-thread-3', 13694: 'Timer-0', 5503: 'geHandlerThread', 5504: 'GAThread', 5507: 'Crashlytics Exc', 13701: 'Heap thread poo', 5510: 'AsyncTask #1', 13703: 'Heap thread poo', 13704: 'Signal Catcher', 13705: 'JDWP', 13706: 'ReferenceQueueD', 5515: 'Crashlytics Tra', 13708: 'FinalizerWatchd', 13709: 'HeapTrimmerDaem', 5518: 'AsyncTask #2', 5519: 'com.dropbox.android', 13712: 'Binder_2', 13713: 'Binder_3', 13715: 'com.rolocule.motiontennis', 5525: 'Heap thread poo', 5526: 'Heap thread poo', 5527: 'Heap thread poo', 5528: 'Signal Catcher', 5529: 'JDWP', 5530: 'ReferenceQueueD', 5531: 'FinalizerDaemon', 5532: 'FinalizerWatchd', 5533: 'HeapTrimmerDaem', 5534: 'GCDaemon', 5535: 'Binder_1', 5536: 'Binder_2', 13731: 'ReferenceQueueD', 13732: 'FinalizerDaemon', 13733: 'FinalizerWatchd', 13734: 'HeapTrimmerDaem', 13735: 'GCDaemon', 13736: 'Binder_1', 13737: 'Binder_2', 13747: 'com.google.android.apps.chrome', 13751: 'Heap thread poo', 13752: 'Heap thread poo', 5562: 'Dropbox log upl', 5563: 'gandalf updater', 13756: 'Signal Catcher', 13757: 'JDWP', 13758: 'ReferenceQueueD', 13759: 'FinalizerDaemon', 5568: 'pool-10-thread-', 5569: 'DbxFileObserver', 5570: 'LocalThumbManag', 13763: 'Binder_1', 13764: 'Binder_2', 5574: 'local AsyncTask', 5575: 'remote AsyncTas', 5576: 'local AsyncTask', 5577: 'remote AsyncTas', 5578: 'Dropbox notif o', 5579: 'Dropbox notif s', 5580: 'Picasso-Stats', 5581: 'Picasso-Dispatc', 5582: 'Picasso-refQueu', 5583: 'gandalf updater', 5587: 'AcceptThreadSec', 13780: 'Heap thread poo', 13781: 'Heap thread poo', 5590: 'Binder_3', 13783: 'pool-1-thread-1', 5592: 'DbxFileObserver', 5593: 'dbxpool-34:r-th', 5594: 'dbxpool-32:au-t', 5595: 'dbxpool-38:a-th', 5596: 'Timer-0', 5597: 'dbxpool-6:a-thr', 13790: 'GCDaemon', 5599: 'Timer-1', 13792: 'Binder_2', 13796: 'rotating_file-t', 13801: 'com.android.vending', 5610: 'AsyncTask #4', 13807: 'Heap thread poo', 13808: 'Heap thread poo', 13809: 'Heap thread poo', 13811: 'Signal Catcher', 13812: 'JDWP', 13813: 'ReferenceQueueD', 13814: 'FinalizerDaemon', 13815: 'FinalizerWatchd', 13816: 'HeapTrimmerDaem', 13817: 'GCDaemon', 13818: 'Binder_1', 5627: 'Binder_3', 5633: 'Binder_5', 13828: 'Gservices', 5638: 'Timer-0', 13833: 'pool-1-thread-1', 13834: 'RefQueueWorker@', 13837: 'RefQueueWorker@', 13838: 'Thread-1482', 13839: 'Thread-1483', 13840: 'Thread-1484', 13843: 'download-manage', 13844: 'NetworkQualityQ', 13845: 'RefQueueWorker@', 13846: 'Thread-1489', 13847: 'Thread-1490', 13848: 'Thread-1491', 13849: 'Thread-1492', 13850: 'Thread-1493', 13851: 'PlayEventLogger', 13852: 'tentative-gc-ru', 13853: 'com.google.android.gms:car', 13856: 'Heap thread poo', 13857: 'Heap thread poo', 13858: 'Heap thread poo', 13862: 'libraries-threa', 13863: 'Signal Catcher', 13864: 'JDWP', 13865: 'ReferenceQueueD', 13866: 'FinalizerDaemon', 13867: 'FinalizerWatchd', 13868: 'HeapTrimmerDaem', 13869: 'GCDaemon', 13870: 'Binder_1', 13871: 'Binder_2', 13872: 'AsyncTask #1', 13873: 'Gservices', 13876: 'AsyncTask #2', 13877: 'AsyncTask #3', 13878: 'PlayEventLogger', 5688: 'com.devuni.flashlight:remote', 13881: 'Gservices', 5693: 'Heap thread poo', 5694: 'Heap thread poo', 5695: 'Heap thread poo', 5697: 'Signal Catcher', 5698: 'JDWP', 5699: 'ReferenceQueueD', 5700: 'FinalizerDaemon', 5701: 'FinalizerWatchd', 5702: 'HeapTrimmerDaem', 5703: 'GCDaemon', 5704: 'Binder_1', 5705: 'Binder_2', 13898: 'FinalizerWatchd', 13899: 'HeapTrimmerDaem', 13900: 'GCDaemon', 13901: 'Binder_1', 13902: 'Binder_2', 13903: 'Gservices', 13904: 'Binder_3', 13905: 'Binder_3', 5717: 'GL updater', 5718: 'RefQueueWorker@', 5719: 'AsyncTask #5', 13913: 'Binder_3', 13677: 'Heap thread poo', 5750: 'Thread-625', 5783: 'WifiManager', 5793: 'Binder_4', 5816: 'Binder_4', 5818: 'Binder_3', 14061: 'kworker/u:3', 14136: 'kworker/0:0H', 14356: 'com.google.android.apps.gcs', 14357: 'ReferenceQueueD', 14358: 'FinalizerDaemon', 14359: 'FinalizerWatchd', 14360: 'HeapTrimmerDaem', 14361: 'GCDaemon', 14362: 'Heap thread poo', 14363: 'Heap thread poo', 14364: 'Heap thread poo', 14365: 'Signal Catcher', 14366: 'JDWP', 14367: 'ReferenceQueueD', 14368: 'FinalizerDaemon', 14369: 'FinalizerWatchd', 14370: 'HeapTrimmerDaem', 14371: 'GCDaemon', 14372: 'Binder_1', 14373: 'Binder_2', 14375: 'Gservices', 14376: 'RefQueueWorker@', 14377: 'Thread-1495', 14378: 'Thread-1496', 14379: 'Thread-1497', 14380: 'Thread-1498', 14381: 'Thread-1499', 6201: 'pool-1-thread-1', 6202: 'com.tencent.mm', 6206: 'Heap thread poo', 6207: 'Heap thread poo', 6208: 'Heap thread poo', 14401: 'Thread-233', 6211: 'Signal Catcher', 6212: 'JDWP', 6213: 'ReferenceQueueD', 6214: 'FinalizerDaemon', 6215: 'FinalizerWatchd', 14409: 'OkHttp Connecti', 6218: 'GCDaemon', 6220: 'Binder_1', 6221: 'Binder_2', 6236: 'THREAD_POOL_HAN', 6237: 'com.tencent.mm', 6239: 'com.tencent.mm', 6240: 'MonitorHandlerT', 6241: '.ProcessManager', 6243: 'Binder_3', 6245: 'default', 6246: 'com.tencent.mm', 6247: 'MMHandlerThread', 14444: '/system/bin/sh', 14445: 'adbd', 14448: 'ps', 6257: 'Icing-Pool-1', 6258: 'Icing-Pool-2', 6259: 'Icing-Pool-3', 6269: 'MM_Thread_Pool_', 6270: 'MM_Thread_Pool_', 6271: 'MM_Thread_Pool_', 6272: 'MM_Thread_Pool_', 6273: 'MM_Thread_Pool_', 6274: 'MM_Thread_Pool_', 6276: 'ExdeviceHandler', 6277: 'MM_Thread_Pool_', 6279: 'RWCache_timeout', 6280: 'RWCache_timeout', 6282: 'MM_Thread_Pool_', 6284: 'downloadStateCh', 6288: 'WifiManager', 6289: 'refresh Notific', 6292: 'MM_Thread_Pool_', 6293: 'MM_Thread_Pool_', 6294: 'MM_Thread_Pool_', 6295: 'SearchDaemon', 6303: 'Binder_4', 6313: 'pool-2-thread-1', 6326: 'AsyncTask #5', 6373: 'RWCache_timeout', 6408: 'h', 6459: 'BluetoothPbapAc', 6473: 'pool-1-thread-1', 6477: 'BtOppRfcommList', 13682: 'ReferenceQueueD', 6481: 'AsyncTask #5', 6672: 'AsyncTask #2', 6673: 'pool-22-thread-', 6709: 'Binder_B', 6740: 'Binder_4', 6752: 'AsyncTask #3', 6917: 'Binder_6', 7091: 'Binder_5', 7150: 'default', 7173: 'Binder_3', 7196: 'UlrDispatchingS', 7230: 'default', 7231: 'MMHandlerThread', 7260: 'Thread-174', 7261: 'Thread-175', 7262: 'Thread-176', 7263: 'Thread-177', 7264: 'Thread-178', 13885: 'com.google.android.gms.wearable', 5328: 'Heap thread poo', 13521: 'Heap thread poo', 13525: 'Signal Catcher', 13526: 'JDWP', 5335: 'FinalizerDaemon', 13528: 'iu-sync-manager', 5337: 'HeapTrimmerDaem', 5338: 'GCDaemon', 5339: 'Binder_1', 5340: 'Binder_2', 5345: 'Queue', 5346: 'Queue', 7557: 'Binder_6', 13891: 'Heap thread poo', 7586: 'pool-4-thread-1', 13895: 'JDWP', 13896: 'ReferenceQueueD', 13897: 'FinalizerDaemon', 13629: 'Binder_1', 13635: 'Thread-1443', 5444: 'BluetoothServer', 13637: 'Thread-1445', 5446: 'AsyncTask #4'}
\ No newline at end of file
diff --git a/catapult/systrace/systrace/test_data/battor_test_data.txt b/catapult/systrace/systrace/test_data/battor_test_data.txt
new file mode 100644
index 0000000..9672736
--- /dev/null
+++ b/catapult/systrace/systrace/test_data/battor_test_data.txt
@@ -0,0 +1,16 @@
+# BattOr
+# voltage_range [-6079.7, 6196.8] mV
+# current_range [-6057.3, 5764.1] mA
+# sample_rate 10000 Hz, gain 10.1x
+0.00 6.5 4307.7
+0.10 15.1 4313.7
+0.20 15.1 4313.7
+0.30 12.2 4310.7
+0.40 12.2 4307.7
+0.50 18.0 4334.7
+0.60 15.1 4334.7
+0.70 18.0 4337.7
+0.80 18.0 4337.7
+0.90 20.9 4331.7
+1.00 9.3 4334.7
+1.10 9.3 4307.7
diff --git a/catapult/systrace/systrace/tracing_agents/android_process_data_agent.py b/catapult/systrace/systrace/tracing_agents/android_process_data_agent.py
new file mode 100644
index 0000000..1a40aea
--- /dev/null
+++ b/catapult/systrace/systrace/tracing_agents/android_process_data_agent.py
@@ -0,0 +1,89 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Tracing agent that captures friendly process and thread data - names, pids and
+# tids and names, etc to enrich display in the trace viewer. Captures snapshots
+# of the output of 'ps' on the device at intervals.
+
+import logging
+import py_utils
+
+from devil.android import device_utils
+from devil.android.device_errors import AdbShellCommandFailedError
+from systrace import tracing_agents
+from systrace import trace_result
+
+# Leftmost output columns match those used on legacy devices.
+# Get thread names separately as there may be spaces that breaks col
+# splitting.
+# TODO(benm): Refactor device_utils.GetPids to get threads and use that here.
+PS_COMMAND_PROC = "ps -A -o USER,PID,PPID,VSIZE,RSS,WCHAN,ADDR=PC,S,NAME,COMM" \
+    "&& ps -AT -o USER,PID,TID,CMD"
+
+# Fallback for old devices.
+PS_COMMAND_PROC_LEGACY = "ps && ps -t"
+
+# identify this as trace of thread / process state
+TRACE_HEADER = 'PROCESS DUMP\n'
+
+def try_create_agent(config):
+  if config.target != 'android':
+    return None
+  if config.from_file is not None:
+    return None
+  return AndroidProcessDataAgent()
+
+def get_config(options):
+  return options
+
+class AndroidProcessDataAgent(tracing_agents.TracingAgent):
+  def __init__(self):
+    super(AndroidProcessDataAgent, self).__init__()
+    self._trace_data = ""
+    self._device = None
+
+  def __repr__(self):
+    return 'android_process_data'
+
+  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
+  def StartAgentTracing(self, config, timeout=None):
+    self._device = device_utils.DeviceUtils(config.device_serial_number)
+    self._trace_data += self._get_process_snapshot()
+    return True
+
+  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
+  def StopAgentTracing(self, timeout=None):
+    self._trace_data += self._get_process_snapshot()
+    return True
+
+  @py_utils.Timeout(tracing_agents.GET_RESULTS_TIMEOUT)
+  def GetResults(self, timeout=None):
+    result = TRACE_HEADER + self._trace_data
+    return trace_result.TraceResult('androidProcessDump', result)
+
+  def SupportsExplicitClockSync(self):
+    return False
+
+  def RecordClockSyncMarker(self, sync_id, did_record_sync_marker_callback):
+    pass
+
+  def _get_process_snapshot(self):
+    use_legacy = False
+    try:
+      dump = self._device.RunShellCommand( \
+          PS_COMMAND_PROC, check_return=True, as_root=True, shell=True)
+    except AdbShellCommandFailedError:
+      use_legacy = True
+
+    # Check length of 2 as we execute two commands, which in case of failure
+    # on old devices output 1 line each.
+    if use_legacy or len(dump) == 2:
+      logging.debug('Couldn\'t parse ps dump, trying legacy method ...')
+      dump = self._device.RunShellCommand( \
+          PS_COMMAND_PROC_LEGACY, check_return=True, as_root=True, shell=True)
+      if len(dump) == 2:
+        logging.error('Unable to extract process data!')
+        return ""
+
+    return '\n'.join(dump) + '\n'
diff --git a/catapult/systrace/systrace/tracing_agents/atrace_agent.py b/catapult/systrace/systrace/tracing_agents/atrace_agent.py
index a22a6aa..e7e15e9 100644
--- a/catapult/systrace/systrace/tracing_agents/atrace_agent.py
+++ b/catapult/systrace/systrace/tracing_agents/atrace_agent.py
@@ -34,7 +34,6 @@
 TRACE_START_REGEXP = r'TRACE\:'
 # Plain-text trace data should always start with this string.
 TRACE_TEXT_HEADER = '# tracer'
-_FIX_THREAD_IDS = True
 _FIX_MISSING_TGIDS = True
 _FIX_CIRCULAR_TRACES = True
 
@@ -250,7 +249,7 @@
     """Reads the output from atrace and stops the trace."""
     dump_cmd = self._tracer_args + ['--async_dump']
     result = self._device_utils.RunShellCommand(
-        dump_cmd, raw_output=True, check_return=True)
+        dump_cmd, raw_output=True, large_output=True, check_return=True)
 
     data_start = re.search(TRACE_START_REGEXP, result)
     if data_start:
@@ -277,20 +276,11 @@
                             'written.')
       sys.exit(1)
 
-    if _FIX_THREAD_IDS:
-      # Issue ps command to device and patch thread names
-      # TODO(catapult:#3215): Migrate to device.GetPids()
-      ps_dump = self._device_utils.RunShellCommand(
-          'ps -T -o USER,TID,PPID,VSIZE,RSS,WCHAN,ADDR=PC,S,CMD || ps -t',
-          shell=True, check_return=True)
-      thread_names = extract_thread_list(ps_dump)
-      trace_data = fix_thread_names(trace_data, thread_names)
-
     if _FIX_MISSING_TGIDS:
-      # Issue printf command to device and patch tgids
+      # Gather proc data from device and patch tgids
       procfs_dump = self._device_utils.RunShellCommand(
-          'printf "%s\n" /proc/[0-9]*/task/[0-9]*',
-          shell=True, check_return=True)
+          'echo -n /proc/[0-9]*/task/[0-9]*',
+          shell=True, check_return=True)[0].split(' ')
       pid2_tgid = extract_tgids(procfs_dump)
       trace_data = fix_missing_tgids(trace_data, pid2_tgid)
 
@@ -299,37 +289,6 @@
 
     return trace_data
 
-
-def extract_thread_list(trace_lines):
-  """Removes the thread list from the given trace data.
-
-  Args:
-    trace_lines: The text portion of the trace
-
-  Returns:
-    a map of thread ids to thread names
-  """
-
-  threads = {}
-  # Assume any line that starts with USER is the header
-  header = -1
-  for i, line in enumerate(trace_lines):
-    cols = line.split()
-    if len(cols) >= 8 and cols[0] == 'USER':
-      header = i
-      break
-  if header == -1:
-    return threads
-  for line in trace_lines[header + 1:]:
-    cols = line.split(None, 8)
-    if len(cols) == 9:
-      tid = int(cols[1])
-      name = cols[8]
-      threads[tid] = name
-
-  return threads
-
-
 def extract_tgids(trace_lines):
   """Removes the procfs dump from the given trace text
 
@@ -382,36 +341,6 @@
   return trace_data
 
 
-def fix_thread_names(trace_data, thread_names):
-  """Replaces thread ids with their names.
-
-  Args:
-    trace_data: The atrace data.
-    thread_names: A mapping of thread ids to thread names.
-  Returns:
-    The updated trace data.
-  """
-
-  def repl(m):
-    tid = int(m.group(2))
-    if tid > 0:
-      name = thread_names.get(tid)
-      if name is None:
-        name = m.group(1)
-        if name == '<...>':
-          name = '<' + str(tid) + '>'
-        thread_names[tid] = name
-      return name + '-' + m.group(2)
-    else:
-      return m.group(0)
-
-  # matches something like:
-  # Binder_2-895, or com.google.android.inputmethod.latin-1078 etc...
-  trace_data = re.sub(r'^\s*(\S+)-(\d+)', repl, trace_data,
-                      flags=re.MULTILINE)
-  return trace_data
-
-
 def fix_missing_tgids(trace_data, pid2_tgid):
   """Replaces missing TGIDs from the trace data with those found in procfs
 
diff --git a/catapult/systrace/systrace/tracing_agents/atrace_agent_unittest.py b/catapult/systrace/systrace/tracing_agents/atrace_agent_unittest.py
index af30c92..9ccc6e3 100755
--- a/catapult/systrace/systrace/tracing_agents/atrace_agent_unittest.py
+++ b/catapult/systrace/systrace/tracing_agents/atrace_agent_unittest.py
@@ -31,13 +31,6 @@
 ATRACE_DATA = os.path.join(TEST_DIR, 'atrace_data')
 ATRACE_DATA_RAW = os.path.join(TEST_DIR, 'atrace_data_raw')
 ATRACE_DATA_STRIPPED = os.path.join(TEST_DIR, 'atrace_data_stripped')
-ATRACE_DATA_THREAD_FIXED = os.path.join(TEST_DIR, 'atrace_data_thread_fixed')
-ATRACE_DATA_WITH_THREAD_LIST = os.path.join(TEST_DIR,
-                                            'atrace_data_with_thread_list')
-ATRACE_THREAD_NAMES = os.path.join(TEST_DIR, 'atrace_thread_names')
-ATRACE_PS_DUMPS = [os.path.join(TEST_DIR, psdump) for psdump in
-        ['atrace_ps_dump', 'atrace_ps_dump_2', 'atrace_ps_dump_3']]
-ATRACE_EXTRACTED_THREADS = os.path.join(TEST_DIR, 'atrace_extracted_threads')
 ATRACE_PROCFS_DUMP = os.path.join(TEST_DIR, 'atrace_procfs_dump')
 ATRACE_EXTRACTED_TGIDS = os.path.join(TEST_DIR, 'atrace_extracted_tgids')
 ATRACE_MISSING_TGIDS = os.path.join(TEST_DIR, 'atrace_missing_tgids')
@@ -98,16 +91,6 @@
     self.assertEqual(' '.join(TRACE_ARGS), ' '.join(tracer_args))
 
   @decorators.HostOnlyTest
-  def test_extract_thread_list(self):
-    with open(ATRACE_EXTRACTED_THREADS, 'r') as expected_file:
-      expected = expected_file.read().strip()
-      for dump_file_name in ATRACE_PS_DUMPS:
-        with open(dump_file_name, 'r') as dump_file:
-          ps_dump = dump_file.read()
-          thread_names = atrace_agent.extract_thread_list(ps_dump.splitlines())
-          self.assertEqual(expected, str(thread_names))
-
-  @decorators.HostOnlyTest
   def test_strip_and_decompress_trace(self):
     with contextlib.nested(open(ATRACE_DATA_RAW, 'r'),
                            open(ATRACE_DATA_STRIPPED, 'r')) as (f1, f2):
@@ -118,21 +101,6 @@
       self.assertEqual(atrace_data_stripped, trace_data)
 
   @decorators.HostOnlyTest
-  def test_fix_thread_names(self):
-    with contextlib.nested(
-        open(ATRACE_DATA_STRIPPED, 'r'),
-        open(ATRACE_THREAD_NAMES, 'r'),
-        open(ATRACE_DATA_THREAD_FIXED, 'r')) as (f1, f2, f3):
-      atrace_data_stripped = f1.read()
-      atrace_thread_names = f2.read()
-      atrace_data_thread_fixed = f3.read()
-      thread_names = eval(atrace_thread_names)
-
-      trace_data = atrace_agent.fix_thread_names(
-          atrace_data_stripped, thread_names)
-      self.assertEqual(atrace_data_thread_fixed, trace_data)
-
-  @decorators.HostOnlyTest
   def test_extract_tgids(self):
     with contextlib.nested(open(ATRACE_PROCFS_DUMP, 'r'),
                            open(ATRACE_EXTRACTED_TGIDS, 'r')) as (f1, f2):
diff --git a/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent.py b/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent.py
index fadd96c..2a4e781 100644
--- a/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent.py
+++ b/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent.py
@@ -66,7 +66,7 @@
     return trace_result.TraceResult('trace-data', self._trace_data)
 
   def _read_trace_data(self):
-    with open(self._filename, 'r') as f:
+    with open(self._filename, 'rb') as f:
       result = f.read()
     data_start = re.search(TRACE_START_REGEXP, result).end(0)
     data = re.sub(ADB_IGNORE_REGEXP, '', result[data_start:])
diff --git a/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent_unittest.py b/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent_unittest.py
index 3efa099..2531c91 100755
--- a/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent_unittest.py
+++ b/catapult/systrace/systrace/tracing_agents/atrace_from_file_agent_unittest.py
@@ -10,6 +10,7 @@
 
 from systrace import decorators
 from systrace import run_systrace
+from systrace import update_systrace_trace_viewer
 from systrace import util
 
 TEST_DIR = os.path.join(os.path.dirname(__file__), '..', 'test_data')
@@ -20,9 +21,11 @@
 NON_EXISTENT_DATA = os.path.join(TEST_DIR, 'THIS_FILE_DOES_NOT_EXIST.txt')
 
 class AtraceFromFileAgentTest(unittest.TestCase):
-  # TODO(ccraik): fix test on windows
-  @decorators.LinuxMacTest
+  @decorators.HostOnlyTest
   def test_from_file(self):
+    update_systrace_trace_viewer.update(force_update=True)
+    self.assertTrue(os.path.exists(
+        update_systrace_trace_viewer.SYSTRACE_TRACE_VIEWER_HTML_FILE))
     output_file_name = util.generate_random_filename_for_test()
     try:
       # use from-file to create a specific expected output
@@ -40,12 +43,12 @@
     except:
       raise
     finally:
+      os.remove(update_systrace_trace_viewer.SYSTRACE_TRACE_VIEWER_HTML_FILE)
       if os.path.exists(output_file_name):
         os.remove(output_file_name)
 
 
-  # TODO(ccraik): fix test on windows
-  @decorators.LinuxMacTest
+  @decorators.HostOnlyTest
   def test_missing_file(self):
     try:
       run_systrace.main_impl(['./run_systrace.py',
diff --git a/catapult/systrace/systrace/tracing_agents/walt_agent.py b/catapult/systrace/systrace/tracing_agents/walt_agent.py
new file mode 100644
index 0000000..72d84b5
--- /dev/null
+++ b/catapult/systrace/systrace/tracing_agents/walt_agent.py
@@ -0,0 +1,120 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import py_utils
+import optparse
+import threading
+
+from devil.android import device_utils
+from systrace import trace_result
+from systrace import tracing_agents
+from py_trace_event import trace_time as trace_time_module
+
+TRACE_FILE_PATH = \
+    '/sdcard/Android/data/org.chromium.latency.walt/files/trace.txt'
+
+CLOCK_DOMAIN_MARKER = '# clock_type=LINUX_CLOCK_MONOTONIC\n'
+
+
+def try_create_agent(options):
+  if options.is_walt_enabled:
+    return WaltAgent()
+  return None
+
+
+class WaltConfig(tracing_agents.TracingConfig):
+  def __init__(self, device_serial_number, is_walt_enabled):
+    tracing_agents.TracingConfig.__init__(self)
+    self.device_serial_number = device_serial_number
+    self.is_walt_enabled = is_walt_enabled
+
+
+def add_options(parser):
+  options = optparse.OptionGroup(parser, 'WALT trace options')
+  options.add_option('--walt', dest='is_walt_enabled', default=False,
+                    action='store_true', help='Use the WALT tracing agent. '
+                    'WALT is a device for measuring latency of physical '
+                    'sensors on phones and computers. '
+                    'See https://github.com/google/walt')
+  return options
+
+
+def get_config(options):
+  return WaltConfig(options.device_serial_number, options.is_walt_enabled)
+
+
+class WaltAgent(tracing_agents.TracingAgent):
+  """
+  This tracing agent requires the WALT app to be installed on the Android phone,
+  and requires the WALT device to be attached to the phone. WALT is a device
+  for measuring latency of physical sensors and outputs on phones and
+  computers. For more information, visit https://github.com/google/walt
+  """
+  def __init__(self):
+    super(WaltAgent, self).__init__()
+    self._trace_contents = None
+    self._config = None
+    self._device_utils = None
+    self._clock_sync_marker = None
+    self._collection_thread = None
+
+  def __repr__(self):
+    return 'WaltAgent'
+
+  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
+  def StartAgentTracing(self, config, timeout=None):
+    del timeout  # unused
+    self._config = config
+    self._device_utils = device_utils.DeviceUtils(
+        self._config.device_serial_number)
+    if self._device_utils.PathExists(TRACE_FILE_PATH):
+      # clear old trace events so they are not included in the current trace
+      self._device_utils.WriteFile(TRACE_FILE_PATH, '')
+    return True
+
+  @py_utils.Timeout(tracing_agents.START_STOP_TIMEOUT)
+  def StopAgentTracing(self, timeout=None):
+    """Stops tracing and starts collecting results.
+
+    To synchronously retrieve the results after calling this function,
+    call GetResults().
+    """
+    del timeout  # unused
+    self._collection_thread = threading.Thread(
+        target=self._collect_trace_data)
+    self._collection_thread.start()
+    return True
+
+  def _collect_trace_data(self):
+    self._trace_contents = self._device_utils.ReadFile(TRACE_FILE_PATH)
+
+  def SupportsExplicitClockSync(self):
+    return True
+
+  def RecordClockSyncMarker(self, sync_id, did_record_clock_sync_callback):
+    cmd = 'cat /proc/timer_list | grep now'
+    t1 = trace_time_module.Now()
+    command_result = self._device_utils.RunShellCommand(cmd, shell=True)
+    nsec = command_result[0].split()[2]
+    self._clock_sync_marker = format_clock_sync_marker(sync_id, nsec)
+    did_record_clock_sync_callback(t1, sync_id)
+
+  @py_utils.Timeout(tracing_agents.GET_RESULTS_TIMEOUT)
+  def GetResults(self, timeout=None):
+    del timeout  # unused
+    self._collection_thread.join()
+    self._collection_thread = None
+    return trace_result.TraceResult('waltTrace', self._get_trace_result())
+
+  def _get_trace_result(self):
+    result = '# tracer: \n' + CLOCK_DOMAIN_MARKER + self._trace_contents
+    if self._clock_sync_marker is not None:
+      result += self._clock_sync_marker
+    return result
+
+
+def format_clock_sync_marker(sync_id, nanosec_time):
+  return ('<0>-0  (-----) [001] ...1  ' + str(float(nanosec_time) / 1e9)
+          + ': tracing_mark_write: trace_event_clock_sync: name='
+          + sync_id + '\n')
diff --git a/catapult/systrace/systrace/tracing_agents/walt_agent_unittest.py b/catapult/systrace/systrace/tracing_agents/walt_agent_unittest.py
new file mode 100644
index 0000000..b4fcaf7
--- /dev/null
+++ b/catapult/systrace/systrace/tracing_agents/walt_agent_unittest.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+import unittest
+
+from systrace import decorators
+from systrace import run_systrace
+from systrace.tracing_agents import walt_agent
+
+
+class WaltAgentTest(unittest.TestCase):
+  """
+  The WALT agent pulls the trace log from the Android phone, and does not
+  communicate with the WALT device directly. This makes the agent more similar
+  to atrace than BattOr. Since the host only connects to the Android phone,
+  more exhaustive testing would require mocking DeviceUtils.
+  """
+
+  @decorators.HostOnlyTest
+  def test_construct_walt_args(self):
+    options, _ = run_systrace.parse_options(['./run_systrace.py',
+                                                      '--walt'])
+    self.assertTrue(walt_agent.get_config(options).is_walt_enabled)
+    options, _ = run_systrace.parse_options(['./run_systrace.py'])
+    self.assertFalse(walt_agent.get_config(options).is_walt_enabled)
+
+  @decorators.HostOnlyTest
+  def test_format_clock_sync_marker(self):
+    actual_marker = walt_agent.format_clock_sync_marker(
+                    'some_sync_id', 12345678901234)
+    expected_marker = ('<0>-0  (-----) [001] ...1  12345.6789012: ' +
+                       'tracing_mark_write: trace_event_clock_sync: ' +
+                       'name=some_sync_id\n')
+    self.assertEqual(actual_marker, expected_marker)
+
+  @decorators.HostOnlyTest
+  def test_get_results_string(self):
+    agent = walt_agent.WaltAgent()
+    agent._trace_contents = '<trace contents here>\n'
+    agent._clock_sync_marker = '<clock sync marker here>\n'
+    result = agent._get_trace_result()
+    self.assertEquals(result, '# tracer: \n# clock_type=LINUX_CLOCK_MONOTONIC\n'
+                      '<trace contents here>\n<clock sync marker here>\n')
+
+if __name__ == "__main__":
+  logging.getLogger().setLevel(logging.DEBUG)
+  unittest.main(verbosity=2)
diff --git a/catapult/systrace/systrace/tracing_controller.py b/catapult/systrace/systrace/tracing_controller.py
index e6f4d6d..d0d2d7c 100644
--- a/catapult/systrace/systrace/tracing_controller.py
+++ b/catapult/systrace/systrace/tracing_controller.py
@@ -10,6 +10,7 @@
 '''
 
 import ast
+import json
 import sys
 import py_utils
 import tempfile
@@ -74,9 +75,17 @@
     This output only contains the "controller side" of the clock sync records.
     """
     with open(self._log_path, 'r') as outfile:
-      result = outfile.read() + ']'
+      data = ast.literal_eval(outfile.read() + ']')
+    # Explicitly set its own clock domain. This will stop the Systrace clock
+    # domain from incorrectly being collapsed into the on device clock domain.
+    formatted_data = {
+        'traceEvents': data,
+        'metadata': {
+            'clock-domain': 'SYSTRACE',
+        }
+    }
     return trace_result.TraceResult(TRACE_DATA_CONTROLLER_NAME,
-                                    ast.literal_eval(result))
+                                    json.dumps(formatted_data))
 
   def SupportsExplicitClockSync(self):
     """Returns whether this supports explicit clock sync.
diff --git a/catapult/systrace/systrace/update_systrace_trace_viewer.py b/catapult/systrace/systrace/update_systrace_trace_viewer.py
index cdb6fe1..c735e82 100755
--- a/catapult/systrace/systrace/update_systrace_trace_viewer.py
+++ b/catapult/systrace/systrace/update_systrace_trace_viewer.py
@@ -46,6 +46,7 @@
   try:
     catapult_rev = subprocess.check_output(
         ['git', 'rev-parse', 'HEAD'],
+        shell=True, # Needed by Windows
         cwd=os.path.dirname(os.path.abspath(__file__))).strip()
   except (subprocess.CalledProcessError, OSError):
     catapult_rev = ''
diff --git a/catapult/telemetry/BUILD.gn b/catapult/telemetry/BUILD.gn
deleted file mode 100644
index f786e3c..0000000
--- a/catapult/telemetry/BUILD.gn
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-group("telemetry_test_support") {
-  # Generic telemetry deps. For now, just include the whole catapult directory.
-  # TODO(nednguyen, aiolos): only include what telemetry needs.
-  # https://github.com/catapult-project/catapult/issues/1953
-  data = [
-    "../",
-  ]
-}
-
-executable("bitmaptools") {
-  sources = [
-    "telemetry/internal/image_processing/bitmaptools.cc",
-  ]
-
-  deps = [
-    "//build/config/sanitizers:deps",
-    "//build/win:default_exe_manifest",
-  ]
-}
diff --git a/catapult/telemetry/PRESUBMIT.py b/catapult/telemetry/PRESUBMIT.py
deleted file mode 100644
index 754847d..0000000
--- a/catapult/telemetry/PRESUBMIT.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-def _CommonChecks(input_api, output_api):
-  results = []
-
-  results += input_api.RunTests(input_api.canned_checks.GetPylint(
-      input_api, output_api, extra_paths_list=_GetPathsToPrepend(input_api),
-      pylintrc='pylintrc'))
-  results += _CheckNoMoreUsageOfDeprecatedCode(
-      input_api, output_api, deprecated_code='GetChromiumSrcDir()',
-      crbug_number=511332)
-  return results
-
-
-def _RunArgs(args, input_api):
-  p = input_api.subprocess.Popen(args, stdout=input_api.subprocess.PIPE,
-                                 stderr=input_api.subprocess.STDOUT)
-  out, _ = p.communicate()
-  return (out, p.returncode)
-
-
-def _ValidateDependenciesFile(input_api, output_api, dependencies_path):
-  """ Check that binary_dependencies.json has valid format and content.
-
-  This check should only be done in CheckChangeOnUpload() only since it invokes
-  network I/O.
-  """
-  results = []
-  telemetry_dir = input_api.PresubmitLocalPath()
-  for f in input_api.AffectedFiles():
-    if not f.AbsoluteLocalPath() == dependencies_path:
-      continue
-    out, return_code = _RunArgs([
-        input_api.python_executable,
-        input_api.os_path.join(telemetry_dir, 'json_format'),
-        dependencies_path], input_api)
-    if return_code:
-      results.append(output_api.PresubmitError(
-           'Validating %s failed:' % dependencies_path, long_text=out))
-      break
-    out, return_code = _RunArgs([
-        input_api.python_executable,
-        input_api.os_path.join(telemetry_dir, 'validate_binary_dependencies'),
-        dependencies_path], input_api)
-    if return_code:
-      results.append(output_api.PresubmitError(
-          'Validating %s failed:' % dependencies_path, long_text=out))
-      break
-  return results
-
-
-def _CheckNoMoreUsageOfDeprecatedCode(
-    input_api, output_api, deprecated_code, crbug_number):
-  results = []
-  # These checks are not perfcet but should be good enough for most of our
-  # usecases.
-  def _IsAddedLine(line):
-    return line.startswith('+') and not line.startswith('+++ ')
-  def _IsRemovedLine(line):
-    return line.startswith('-') and not line.startswith('--- ')
-
-  presubmit_dir = input_api.os_path.join(
-      input_api.PresubmitLocalPath(), 'PRESUBMIT.py')
-
-  added_calls = 0
-  removed_calls = 0
-  for affected_file in input_api.AffectedFiles():
-    # Do not do the check on PRESUBMIT.py itself.
-    if affected_file.AbsoluteLocalPath() == presubmit_dir:
-      continue
-    for line in affected_file.GenerateScmDiff().splitlines():
-      if _IsAddedLine(line) and deprecated_code in line:
-        added_calls += 1
-      elif _IsRemovedLine(line) and deprecated_code in line:
-        removed_calls += 1
-
-  if added_calls > removed_calls:
-    results.append(output_api.PresubmitError(
-        'Your patch adds more instances of %s. Please see crbug.com/%i for'
-        'how to proceed.' % (deprecated_code, crbug_number)))
-  return results
-
-
-def _GetPathsToPrepend(input_api):
-  telemetry_dir = input_api.PresubmitLocalPath()
-  catapult_dir = input_api.os_path.join(telemetry_dir, '..')
-  return [
-      telemetry_dir,
-
-      input_api.os_path.join(telemetry_dir, 'third_party', 'altgraph'),
-      input_api.os_path.join(telemetry_dir, 'third_party', 'modulegraph'),
-      input_api.os_path.join(telemetry_dir, 'third_party', 'pexpect'),
-      input_api.os_path.join(telemetry_dir, 'third_party', 'png'),
-      input_api.os_path.join(telemetry_dir, 'third_party', 'web-page-replay'),
-      input_api.os_path.join(telemetry_dir, 'third_party', 'websocket-client'),
-
-      input_api.os_path.join(catapult_dir, 'common', 'py_utils'),
-      input_api.os_path.join(catapult_dir, 'dependency_manager'),
-      input_api.os_path.join(catapult_dir, 'devil'),
-      input_api.os_path.join(catapult_dir, 'systrace'),
-      input_api.os_path.join(catapult_dir, 'tracing'),
-      input_api.os_path.join(catapult_dir, 'common', 'battor'),
-      input_api.os_path.join(catapult_dir, 'common', 'py_trace_event'),
-
-      input_api.os_path.join(catapult_dir, 'third_party', 'mock'),
-      input_api.os_path.join(catapult_dir, 'third_party', 'pyfakefs'),
-      input_api.os_path.join(catapult_dir, 'third_party', 'pyserial'),
-      input_api.os_path.join(catapult_dir, 'third_party', 'typ'),
-  ]
-
-
-def _ValidateAllDependenciesFiles(input_api, output_api):
-  results = []
-  telemetry_dir = input_api.PresubmitLocalPath()
-  binary_dependencies = input_api.os_path.join(
-      telemetry_dir, 'telemetry', 'internal', 'binary_dependencies.json')
-  telemetry_unittest_dependencies = input_api.os_path.join(
-      telemetry_dir, 'telemetry', 'telemetry_unittest_deps.json')
-  for path in [binary_dependencies, telemetry_unittest_dependencies]:
-    results += _ValidateDependenciesFile(input_api, output_api, path)
-  return results
-
-
-def CheckChangeOnUpload(input_api, output_api):
-  results = []
-  results += _CommonChecks(input_api, output_api)
-  results += _ValidateAllDependenciesFiles(input_api, output_api)
-  return results
-
-
-def CheckChangeOnCommit(input_api, output_api):
-  results = []
-  results += _CommonChecks(input_api, output_api)
-  return results
diff --git a/catapult/telemetry/README.md b/catapult/telemetry/README.md
deleted file mode 100644
index cb61fba..0000000
--- a/catapult/telemetry/README.md
+++ /dev/null
@@ -1,155 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file.
--->
-
-# Telemetry
-
-Telemetry is the performance testing framework used by Chrome.  It allows you
-to perform arbitrary actions on a set of web pages (or any android application!)
-and report metrics about it.  The framework abstracts:
-
-*   Launching a browser with arbitrary flags on any platform.
-*   Opening a tab and navigating to the page under test.
-*   Launching an Android application with intents through ADB.
-*   Fetching data via the Inspector timeline and traces.
-*   Using [Web Page Replay](https://github.com/chromium/web-page-replay) to
-    cache real-world websites so they don’t change when used in benchmarks.
-
-## Design Principles
-
-*   Write one performance test that runs on major platforms - Windows, Mac,
-    Linux, Chrome OS, and Android for both Chrome and ContentShell.
-*   Run on browser binaries, without a full Chromium checkout, and without
-    having to build the browser yourself.
-*   Use Web Page Replay to get repeatable test results.
-*   Clean architecture for writing benchmarks that keeps measurements and use
-    cases separate.
-
-**Telemetry is designed for measuring performance rather than checking
-  correctness. If you want to check for correctness,
-  [browser tests](http://www.chromium.org/developers/testing/browser-tests) are
-  your friend.**
-
-**If you are a Chromium developer looking to add a new Telemetry benchmark to
-[`src/tools/perf/`](https://code.google.com/p/chromium/codesearch#chromium/src/tools/perf/),
-please make sure to read our
-[Benchmark Policy](https://docs.google.com/document/d/1bBKyYCW3VlUUPDpQE4xvrMFdA6tovQMZoqO9KCcmqqQ/preview)
-first.**
-
-## Code Concepts
-
-Telemetry provides two major functionality groups: those that provide test
-automation, and those that provide the capability to collect data.
-
-### Test Automation
-
-The test automation facilities of Telemetry provide Python wrappers for a number
-of different system concepts.
-
-*   _Platforms_ use a variety of libraries & tools to abstract away the OS
-    specific logic.
-*   _Browser_ wraps Chrome's
-    [DevTools Remote Debugging Protocol](https://developer.chrome.com/devtools/docs/remote-debugging)
-    to perform actions and extract information from the browser.
-*   _Android App_ is a Python wrapper around
-    [`adb shell`](http://developer.android.com/tools/help/adb.html).
-
-The Telemetry framework lives in
-[`src/third_party/catapult/telemetry/`](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/)
-and performance benchmarks that use Telemetry live in
-[`src/tools/perf/`](https://code.google.com/p/chromium/codesearch#chromium/src/tools/perf/).
-
-### Data Collection
-
-Telemetry offers a framework for collecting metrics that quantify the
-performance of automated actions in terms of benchmarks, measurements, and story
-sets.
-
-*   A
-    [_benchmark_](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/benchmark.py)
-    combines a _measurement_ together with a _story set_, and optionally a set
-    of browser options.
-    *   We strongly discourage benchmark authors from using command-line flags
-        to specify the behavior of benchmarks, since benchmarks should be
-        cross-platform.
-    *   Benchmarks are discovered and run by the
-        [benchmark runner](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/benchmark_runner.py),
-        which is wrapped by scripts like
-        [`run_benchmark`](https://code.google.com/p/chromium/codesearch#chromium/src/tools/perf/run_benchmark)
-        in `tools/perf`.
-*   A _measurement_ (called
-    [`StoryTest`](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/web_perf/story_test.py)
-    in the code) is responsible for setting up and tearing down the testing
-    platform, and for collecting _metrics_ that quantify the application
-    scenario under test.
-    *   Measurements need to work with all story sets, to provide consistency
-        and prevent benchmark rot.
-    *   You probably don't need to override `StoryTest` (see "Timeline Based
-        Measurement" below). If you think you do, please talk to us.
-*   A
-    [_story set_](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/story/story_set.py)
-    is a set of _stories_ together with a
-    [_shared state_](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/story/shared_state.py)
-    that describes application-level configuration options.
-*   A
-    [_story_](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/story/story.py)
-    is an application scenario and a set of actions to run in that scenario. In
-    the typical Chromium use case, this will be a web page together with actions
-    like scrolling, clicking, or executing JavaScript.
-*   A _metric_ describes how to collect data about the story run and compute
-    results.
-    *   New metrics should generally be
-        [timeline-based](https://cs.chromium.org/chromium/src/third_party/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric.py).
-    *   Metrics can specify many different types of results, including numbers,
-        histograms, traces, and failures.
-*   _Timeline Based Measurement_ is a built-in `StoryTest` that runs all
-    available timeline-based metrics, and benchmarks that use it can filter
-    relevant results.
-
-## Next Steps
-
-*   [Run Telemetry benchmarks locally](/telemetry/docs/run_benchmarks_locally.md)
-*   [Record a story set](https://sites.google.com/a/chromium.org/dev/developers/telemetry/record_a_page_set)
-    with Web Page Replay
-*   [Add a measurement](https://sites.google.com/a/chromium.org/dev/developers/telemetry/add_a_measurement)
-*   [Feature guidelines](https://sites.google.com/a/chromium.org/dev/developers/telemetry/telemetry-feature-guidelines)
-*   [Profiling with Telemetry](https://sites.google.com/a/chromium.org/dev/developers/telemetry/profiling)
-*   [Profile generation](https://sites.google.com/a/chromium.org/dev/developers/telemetry/telemetry-profile-generation)
-*   [Telemetry unittests](https://sites.google.com/a/chromium.org/dev/developers/telemetry/telemetry-unittests)
-
-## Contact Us or Follow Along
-
-If you have questions, please email telemetry@chromium.org.
-
-You can keep up with Telemetry related discussions by joining the
-[telemetry group](https://groups.google.com/a/chromium.org/forum/#!forum/telemetry).
-
-[For Googlers](http://go/telemetry)
-
-## Frequently Asked Questions
-
-### I get an error when I try to use recorded story sets.
-
-The recordings are not included in the Chromium source tree. If you are a Google
-partner, run `gsutil config` to authenticate, then try running the test again.
-If you don't have `gsutil` installed on your machine, you can find it in
-`build/third_party/gsutil/gsutil`.
-
-If you are not a Google partner, you can run on live sites with
---use-live-sites` or
-[record your own](http://dev.chromium.org/developers/telemetry/record_a_page_set)
-story set archive.
-
-### I get mysterious errors about device\_forwarder failing.
-
-Your forwarder binary may be outdated. If you have built the forwarder in
-src/out that one will be used. if there isn't anything there Telemetry will
-default to downloading a pre-built binary. Try re-building the forwarder, or
-alternatively wiping the contents of `src/out/` and running `run_benchmark`,
-which should download the latest binary.
-
-### I'm having problems with keychain prompts on Mac.
-
-Make sure that your keychain is
-[correctly configured](https://sites.google.com/a/chromium.org/dev/developers/telemetry/telemetry-mac-keychain-setup).
diff --git a/catapult/telemetry/bin/.gitignore b/catapult/telemetry/bin/.gitignore
deleted file mode 100644
index 3f1bb9d..0000000
--- a/catapult/telemetry/bin/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-*/*
-!**.sha1
diff --git a/catapult/telemetry/bin/README.chromium b/catapult/telemetry/bin/README.chromium
deleted file mode 100644
index b2cd84a..0000000
--- a/catapult/telemetry/bin/README.chromium
+++ /dev/null
@@ -1,54 +0,0 @@
-This directory contains prebuilt binaries used by Telemetry which allow it to
-be run without requiring any compilation.
-
-For usage instructions, see:
-http://www.chromium.org/developers/telemetry/upload_to_cloud_storage
-
-avconv:
-   version 0.8.9-4:0.8.9-0ubuntu0.12.04.1
-
-IEDriverServer binary:
-  Both 32-bit and 64-bit are of version 2.35.2.
-
-ipfw and ipfw_mod.ko:
-  Version 20120812
-
-perfhost_trusty:
-  Built from branch modified by vmiura on github. The git branch used is
-  "perf_tracing_changes" but in the directions below I have included the actual
-  hash of the checkout.
-
-  Make sure you have the proper libraries installed for symbol demangling:
-    shell> sudo apt-get install binutils-dev
-    shell> sudo apt-get install libiberty-dev
-
-  Directions for building perf:
-    shell> git clone https://github.com/vmiura/linux.git
-    shell> cd linux
-    shell> git checkout e1fe871e4a33712ad4964a70904d5d59188e3cc2
-    shell> cd tools/perf
-    shell> make
-    shell> ./perf test
-    Tests should mostly pass, except a few:
-     1: vmlinux symtab matches kallsyms                        : FAILED!
-     2: detect open syscall event                              : FAILED!
-     3: detect open syscall event on all cpus                  : FAILED!
-     4: read samples using the mmap interface                  : FAILED!
-     5: parse events tests                                     : FAILED!
-     [snip]
-     11: Check parsing of sched tracepoints fields              : FAILED!
-     12: Generate and check syscalls:sys_enter_open event fields: FAILED!
-     21: Test object code reading          :[kernel.kallsyms] ... FAILED!
-    shell> mv perf perfhost_trusty
-
-android/armeabi-v7a/perf:
-  Follow http://source.android.com/source/building.html
-  . build/envsetup.sh
-  lunch aosp_arm-user
-
-2013-09-26 - bulach - perf / perfhost / tcpdump:
-  git revert -n 93501d3 # issue with __strncpy_chk2
-  make -j32 perf perfhost tcpdump
-
-android/arm64-v8a/perf:
-  Same as above, with aarch64 architecture, from branch android-5.0.0_r2
diff --git a/catapult/telemetry/bin/run_browser_tests b/catapult/telemetry/bin/run_browser_tests
deleted file mode 100755
index 8d60895..0000000
--- a/catapult/telemetry/bin/run_browser_tests
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-TELEMETRY_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
-sys.path.append(TELEMETRY_DIR)
-from telemetry import project_config
-from telemetry.testing import browser_test_runner
-
-
-def main():
-  config = project_config.ProjectConfig(
-      top_level_dir=os.path.join(TELEMETRY_DIR, 'examples'),
-      benchmark_dirs=[os.path.join(TELEMETRY_DIR, 'examples', 'browser_tests')])
-  return browser_test_runner.Run(config, sys.argv[1:])
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/catapult/telemetry/bin/run_tests b/catapult/telemetry/bin/run_tests
deleted file mode 100755
index bebddaf..0000000
--- a/catapult/telemetry/bin/run_tests
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-TELEMETRY_DIR = os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
-sys.path.append(TELEMETRY_DIR)
-from telemetry import project_config
-from telemetry.testing import unittest_runner
-
-
-def main():
-  config = project_config.ProjectConfig(
-      top_level_dir=TELEMETRY_DIR,
-      client_configs=[
-          os.path.join(TELEMETRY_DIR,
-                       'telemetry', 'telemetry_unittest_deps.json')])
-  return unittest_runner.Run(config, disable_cloud_storage_io_during_test=True)
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/catapult/telemetry/build/__init__.py b/catapult/telemetry/build/__init__.py
deleted file mode 100644
index 9228df8..0000000
--- a/catapult/telemetry/build/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/build/generate_telemetry_harness.sh b/catapult/telemetry/build/generate_telemetry_harness.sh
deleted file mode 100755
index b1e7f05..0000000
--- a/catapult/telemetry/build/generate_telemetry_harness.sh
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This is a script meant to be run by a bot to periodically release new versions
-# of the telemetry harness. It needs to be run from one level above src/ (such
-# as build/).
-
-src/tools/perf/find_dependencies \
-  src/tools/perf/run_benchmark \
-  src/tools/perf/record_wpr \
-  src/content/test/gpu/run_gpu_test.py \
-  --exclude=*/third_party/catapult/test_data/* \
-  -z $1
diff --git a/catapult/telemetry/build/linux_setup_msr.py b/catapult/telemetry/build/linux_setup_msr.py
deleted file mode 100755
index a61828b..0000000
--- a/catapult/telemetry/build/linux_setup_msr.py
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This is a script developers can use to set-up their workstation to let
-# Telemetry read the CPU's Model Specific Registers in order to get power
-# measurements. It can check if reading from MSRs is possible as any user, but
-# must run as root to make changes. Not all changes are sticky, so one has to
-# re-run this script after each reboot.
-#
-# This script is currently Debian/Ubuntu specific.
-
-import os
-import subprocess
-import sys
-
-MSR_DEV_FILE_PATH = '/dev/cpu/0/msr'
-RDMSR_PATH = '/usr/sbin/rdmsr'
-
-def _Usage(prog_name):
-  """Print a help message."""
-  print 'Run "%s" as a regular user to check if reading from the MSR ' \
-      'is possible.' % prog_name
-  print 'Run "%s enable" as root to automatically set up reading from ' \
-      'the MSR.' % prog_name
-
-
-def _CheckMsrKernelModule():
-  """Return whether the 'msr' kernel module is loaded."""
-  proc = subprocess.Popen('/sbin/lsmod', stdout=subprocess.PIPE)
-  stdout = proc.communicate()[0]
-  ret = proc.wait()
-  if ret != 0:
-    raise OSError('lsmod failed')
-
-  if not any([line.startswith('msr ') for line in stdout.splitlines()]):
-    print 'Error: MSR module not loaded.'
-    return False
-
-  return True
-
-
-def _CheckMsrDevNodes():
-  """Check whether the MSR /dev files have the right permissions."""
-  if not os.path.exists(MSR_DEV_FILE_PATH):
-    print 'Error: %s does not exist.' % MSR_DEV_FILE_PATH
-    return False
-
-  if not os.access(MSR_DEV_FILE_PATH, os.R_OK):
-    print 'Error: Cannot read from %s' % MSR_DEV_FILE_PATH
-    return False
-
-  return True
-
-
-def _CheckRdmsr():
-  """Check and make sure /usr/sbin/rdmsr is set up correctly."""
-  if not os.access(RDMSR_PATH, os.X_OK):
-    print 'Error: %s missing or not executable.' % RDMSR_PATH
-    return False
-
-  proc = subprocess.Popen(['/sbin/getcap', RDMSR_PATH], stdout=subprocess.PIPE)
-  stdout = proc.communicate()[0]
-  ret = proc.wait()
-  if ret != 0:
-    raise OSError('getcap failed')
-
-  if not 'cap_sys_rawio+ep' in stdout:
-    print 'Error: /usr/sbin/rdmsr needs RAWIO capability.'
-    return False
-
-  return True
-
-
-def _RunAllChecks():
-  """Check to make sure it is possible to read from the MSRs."""
-  if os.geteuid() == 0:
-    print 'WARNING: Running as root, msr permission check likely inaccurate.'
-
-  has_dev_node = _CheckMsrDevNodes() if _CheckMsrKernelModule() else False
-  has_rdmsr = _CheckRdmsr()
-  return has_dev_node and has_rdmsr
-
-
-def _EnableMsr(prog_name):
-  """Do all the setup needed to pass _RunAllChecks().
-
-  Needs to run as root."""
-  if os.geteuid() != 0:
-    print 'Error: Must run "%s enable" as root.' % prog_name
-    return False
-
-  print 'Loading msr kernel module.'
-  ret = subprocess.call(['/sbin/modprobe', 'msr'])
-  if ret != 0:
-    print 'Error: Cannot load msr module.'
-    return False
-
-  print 'Running chmod on %s.' % MSR_DEV_FILE_PATH
-  ret = subprocess.call(['/bin/chmod', 'a+r', MSR_DEV_FILE_PATH])
-  if ret != 0:
-    print 'Error: Cannot chmod %s.' % MSR_DEV_FILE_PATH
-    return False
-
-  if not os.access(RDMSR_PATH, os.F_OK):
-    print 'Need to install the msr-tools package.'
-    ret = subprocess.call(['/usr/bin/apt-get', 'install', '-y', 'msr-tools'])
-    if ret != 0:
-      print 'Error: Did not successfully install msr-tools.'
-      return False
-
-  print 'Running setcap on %s.' % RDMSR_PATH
-  ret = subprocess.call(['/sbin/setcap', 'cap_sys_rawio+ep', RDMSR_PATH])
-  if ret != 0:
-    print 'Error: Cannot give /usr/sbin/rdmsr RAWIO capability.'
-    return False
-
-  return True
-
-
-def main(prog_name, argv):
-  if len(argv) == 0:
-    if _RunAllChecks():
-      print 'Check succeeded'
-      return 0
-
-    print 'Check failed, try running "%s enable" as root to fix.' % prog_name
-    return 1
-
-  if len(argv) == 1:
-    if argv[0] == 'enable':
-      return 0 if _EnableMsr(prog_name) else 1
-
-    print 'Error: Unknown sub-command %s' % argv[0]
-    _Usage(prog_name)
-    return 1
-
-  print 'Error: Bad number of arguments'
-  _Usage(prog_name)
-  return 1
-
-
-if '__main__' == __name__:
-  sys.exit(main(os.path.basename(sys.argv[0]), sys.argv[1:]))
diff --git a/catapult/telemetry/build/update_docs.py b/catapult/telemetry/build/update_docs.py
deleted file mode 100644
index 7f43b58..0000000
--- a/catapult/telemetry/build/update_docs.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-import optparse
-import os
-import pkgutil
-import pydoc
-import re
-import sys
-
-import telemetry
-from telemetry.core import util
-
-telemetry_dir = util.GetTelemetryDir()
-docs_dir = os.path.join(telemetry_dir, 'docs', 'pydoc')
-
-def RemoveAllDocs():
-  for dirname, _, filenames in os.walk(docs_dir):
-    for filename in filenames:
-      os.remove(os.path.join(dirname, filename))
-
-def GenerateHTMLForModule(module):
-  html = pydoc.html.page(pydoc.describe(module),
-                         pydoc.html.document(module, module.__name__))
-
-  # pydoc writes out html with links in a variety of funky ways. We need
-  # to fix them up.
-  assert not telemetry_dir.endswith(os.sep)
-  links = re.findall('(<a href="(.+?)">(.+?)</a>)', html)
-  for link_match in links:
-    link, href, link_text = link_match
-    if not href.startswith('file:'):
-      continue
-
-    new_href = href.replace('file:', '')
-    new_href = new_href.replace(telemetry_dir, '..')
-    new_href = new_href.replace(os.sep, '/')
-
-    new_link_text = link_text.replace(telemetry_dir + os.sep, '')
-
-    new_link = '<a href="%s">%s</a>' % (new_href, new_link_text)
-    html = html.replace(link, new_link)
-
-  # pydoc writes out html with absolute path file links. This is not suitable
-  # for checked in documentation. So, fix up the HTML after it is generated.
-  #html = re.sub('href="file:%s' % telemetry_dir, 'href="..', html)
-  #html = re.sub(telemetry_dir + os.sep, '', html)
-  return html
-
-def WriteHTMLForModule(module):
-  page = GenerateHTMLForModule(module)
-  path = os.path.join(docs_dir, '%s.html' % module.__name__)
-  with open(path, 'w') as f:
-    sys.stderr.write('Wrote %s\n' % os.path.relpath(path))
-    f.write(page)
-
-def GetAllModulesToDocument(module):
-  modules = [module]
-  for _, modname, _ in pkgutil.walk_packages(
-      module.__path__, module.__name__ + '.'):
-    if modname.endswith('_unittest'):
-      logging.debug("skipping %s due to being a unittest", modname)
-      continue
-
-    module = __import__(modname, fromlist=[""])
-    name, _ = os.path.splitext(module.__file__)
-    if not os.path.exists(name + '.py'):
-      logging.info("skipping %s due to being an orphan .pyc", module.__file__)
-      continue
-
-    modules.append(module)
-  return modules
-
-class AlreadyDocumentedModule(object):
-  def __init__(self, filename):
-    self.filename = filename
-
-  @property
-  def name(self):
-    basename = os.path.basename(self.filename)
-    return os.path.splitext(basename)[0]
-
-  @property
-  def contents(self):
-    with open(self.filename, 'r') as f:
-      return f.read()
-
-def GetAlreadyDocumentedModules():
-  modules = []
-  for dirname, _, filenames in os.walk(docs_dir):
-    for filename in filenames:
-      path = os.path.join(dirname, filename)
-      modules.append(AlreadyDocumentedModule(path))
-  return modules
-
-
-def IsUpdateDocsNeeded():
-  already_documented_modules = GetAlreadyDocumentedModules()
-  already_documented_modules_by_name = dict(
-    (module.name, module) for module in already_documented_modules)
-  current_modules = GetAllModulesToDocument(telemetry)
-
-  # Quick check: if the names of modules has changed, we definitely need
-  # an update.
-  already_documented_module_names = set(
-    m.name for m in already_documented_modules)
-
-  current_module_names = set([m.__name__ for m in current_modules])
-
-  if current_module_names != already_documented_module_names:
-    return True
-
-  # Generate the new docs and compare aganist the old. If changed, then a
-  # an update is needed.
-  for current_module in current_modules:
-    already_documented_module = already_documented_modules_by_name[
-      current_module.__name__]
-    current_html = GenerateHTMLForModule(current_module)
-    if current_html != already_documented_module.contents:
-      return True
-
-  return False
-
-def Main(args):
-  parser = optparse.OptionParser()
-  parser.add_option(
-      '-v', '--verbose', action='count', dest='verbosity',
-      help='Increase verbosity level (repeat as needed)')
-  options, args = parser.parse_args(args)
-  if options.verbosity >= 2:
-    logging.getLogger().setLevel(logging.DEBUG)
-  elif options.verbosity:
-    logging.getLogger().setLevel(logging.INFO)
-  else:
-    logging.getLogger().setLevel(logging.WARNING)
-
-  assert os.path.isdir(docs_dir), '%s does not exist' % docs_dir
-
-  RemoveAllDocs()
-
-  old_cwd = os.getcwd()
-  try:
-    os.chdir(telemetry_dir)
-    for module in GetAllModulesToDocument(telemetry):
-      WriteHTMLForModule(module)
-  finally:
-    os.chdir(old_cwd)
diff --git a/catapult/telemetry/cloud_storage b/catapult/telemetry/cloud_storage
deleted file mode 100755
index 37adbbc..0000000
--- a/catapult/telemetry/cloud_storage
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import logging
-import os
-import subprocess
-import sys
-
-from telemetry.core import util
-from telemetry.internal.util import command_line
-
-sys.path.insert(1, os.path.abspath(os.path.join(
-    util.GetCatapultDir(), 'common', 'py_utils')))
-from py_utils import cloud_storage
-
-
-BUCKETS = {bucket: easy_bucket_name for easy_bucket_name, bucket
-           in cloud_storage.BUCKET_ALIASES.iteritems()}
-
-
-def _GetPaths(path):
-  root, ext = os.path.splitext(path)
-  if ext == '.sha1':
-    file_path = root
-    hash_path = path
-  else:
-    file_path = path
-    hash_path = path + '.sha1'
-  return file_path, hash_path
-
-
-def _FindFilesInCloudStorage(files):
-  """Returns a dict of all files and which buckets they're in."""
-  # Preprocessing: get the contents of all buckets.
-  bucket_contents = {}
-  for bucket in BUCKETS:
-    try:
-      bucket_contents[bucket] = cloud_storage.List(bucket)
-    except (cloud_storage.PermissionError, cloud_storage.CredentialsError):
-      pass
-
-  # Check if each file is in the bucket contents.
-  file_buckets = {}
-  for path in files:
-    file_path, hash_path = _GetPaths(path)
-
-    if file_path in file_buckets:
-      # Ignore duplicates, if both data and sha1 file were in the file list.
-      continue
-    if not os.path.exists(hash_path):
-      # Probably got some non-Cloud Storage files in the file list. Ignore.
-      continue
-
-    file_hash = cloud_storage.ReadHash(hash_path)
-    file_buckets[file_path] = []
-    for bucket in BUCKETS:
-      if bucket in bucket_contents and file_hash in bucket_contents[bucket]:
-        file_buckets[file_path].append(bucket)
-
-  return file_buckets
-
-
-class Ls(command_line.Command):
-  """List which bucket each file is in."""
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    parser.add_argument('-r', '--recursive', action='store_true')
-    parser.add_argument('paths', nargs='+')
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    for path in args.paths:
-      if not os.path.exists(path):
-        parser.error('Path not found: %s' % path)
-
-  def Run(self, args):
-    def GetFilesInPaths(paths, recursive):
-      """If path is a dir, yields all files in path, otherwise just yields path.
-      If recursive is true, walks subdirectories recursively."""
-      for path in paths:
-        if not os.path.isdir(path):
-          yield path
-          continue
-
-        if recursive:
-          for root, _, filenames in os.walk(path):
-            for filename in filenames:
-              yield os.path.join(root, filename)
-        else:
-          for filename in os.listdir(path):
-            yield os.path.join(path, filename)
-
-    files = _FindFilesInCloudStorage(GetFilesInPaths(args.paths, args.recursive))
-
-    if not files:
-      print 'No files in Cloud Storage.'
-      return
-
-    for file_path, buckets in sorted(files.iteritems()):
-      if buckets:
-        buckets = [BUCKETS[bucket] for bucket in buckets]
-        print '%-11s  %s' % (','.join(buckets), file_path)
-      else:
-        print '%-11s  %s' % ('not found', file_path)
-
-
-class Mv(command_line.Command):
-  """Move files to the given bucket."""
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    parser.add_argument('files', nargs='+')
-    parser.add_argument('bucket', choices=cloud_storage.BUCKET_ALIASES)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    args.bucket = cloud_storage.BUCKET_ALIASES[args.bucket]
-
-  def Run(self, args):
-    files = _FindFilesInCloudStorage(args.files)
-
-    for file_path, buckets in sorted(files.iteritems()):
-      if not buckets:
-        raise IOError('%s not found in Cloud Storage.' % file_path)
-
-    for file_path, buckets in sorted(files.iteritems()):
-      if args.bucket in buckets:
-        buckets.remove(args.bucket)
-      if not buckets:
-        logging.info('Skipping %s, no action needed.' % file_path)
-        continue
-
-      # Move to the target bucket.
-      file_hash = cloud_storage.ReadHash(file_path + '.sha1')
-      cloud_storage.Move(buckets.pop(), args.bucket, file_hash)
-
-      # Delete all additional copies.
-      for bucket in buckets:
-        cloud_storage.Delete(bucket, file_hash)
-
-
-class Rm(command_line.Command):
-  """Remove files from Cloud Storage."""
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    parser.add_argument('files', nargs='+')
-
-  def Run(self, args):
-    files = _FindFilesInCloudStorage(args.files)
-    for file_path, buckets in sorted(files.iteritems()):
-      file_hash = cloud_storage.ReadHash(file_path + '.sha1')
-      for bucket in buckets:
-        cloud_storage.Delete(bucket, file_hash)
-
-
-class Upload(command_line.Command):
-  """Upload files to Cloud Storage."""
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    parser.add_argument('files', nargs='+')
-    parser.add_argument('bucket', choices=cloud_storage.BUCKET_ALIASES)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    args.bucket = cloud_storage.BUCKET_ALIASES[args.bucket]
-
-    for path in args.files:
-      if not os.path.exists(path):
-        parser.error('File not found: %s' % path)
-
-  def Run(self, args):
-    for file_path in args.files:
-      file_hash = cloud_storage.CalculateHash(file_path)
-
-      # Create or update the hash file.
-      hash_path = file_path + '.sha1'
-      with open(hash_path, 'wb') as f:
-        f.write(file_hash)
-        f.flush()
-
-      # Add the data to Cloud Storage.
-      cloud_storage.Insert(args.bucket, file_hash, file_path)
-
-      # Add the hash file to the branch, for convenience. :)
-      subprocess.call(['git', 'add', hash_path])
-
-
-class CloudStorageCommand(command_line.SubcommandCommand):
-  commands = (Ls, Mv, Rm, Upload)
-
-
-if __name__ == '__main__':
-  logging.getLogger().setLevel(logging.INFO)
-  sys.exit(CloudStorageCommand.main())
diff --git a/catapult/telemetry/docs/api-deprecation-procedure.md b/catapult/telemetry/docs/api-deprecation-procedure.md
deleted file mode 100644
index 0023db2..0000000
--- a/catapult/telemetry/docs/api-deprecation-procedure.md
+++ /dev/null
@@ -1,46 +0,0 @@
-# Telemetry API Deprecation Procedure
-
-## Procedure for hard deprecation:
-1. Determine a deprecation time-frame.
-2. Create documentation on suggested refactor/workarounds if applicable.
-3. Apply applicable warnings for users about the deprecation.
-4. Announce deprecation.
-5. (Optional) Audit important users for usage of deprecated code prior to deletion.
-6. Delete the offending code.
-
-## Determine deprecation time-frame.
-
-The default time-frame is 18 weeks. If the expected user refractors are expected to take more than a third of that time to complete, this timeframe may be extended on a case-by-case basis as appropriate prior to announcement.
-
-## Create documentation on suggested refactor/workarounds if applicable.
-
-If a large refactor is expected for the users to stop using the deprecated code, documentation with suggested alternatives should be created. This may include examples (placed in the examples folder in the appropriate location), a wiki page documenting the change and/or our suggested workarounds/refactors, and/or a link to any replacement features.
-
-## Apply applicable warnings for users about the deprecation.
-
-This should include any applicable documentation (or links there to), deprecation deadline (as determined in step 1).
-
-### For Python code:
-
-1. All functions and classes to be deprecated should use a deprecation decorator.
-   You must pass in the deprecation deadline as determined by step 1 (counted from time of the CL containing these changes) into the decorator. The decorator will contain a warning message using the DeprecationWarning category and outlining the following:
-   * A warning of the function being deprecated.
-   * The deadline to refactor their code before the function is deleted.
-   * An (externally available) email they can use to contact us requesting an extension to the proposed deletion date.
-   * A warning that the deadline will only rarely be extended, and only for cases with obvious need and significant forewarning.
-
-2. All functions should log links to any applicable documentation for refactoring, or references to replacement API.
-
-## Announce deprecation
-An email should be sent out to telemetry-announce@chromium.org announcing the API being deprecated, the reason(s) for the deprecation, the deprecation deadline, and include any (links to) documentation.
-Extension of deprecation deadline
-This should happen extremely rarely, if ever. If a user brings up extenuating circumstances, contributors may be asked to give input, and are welcome to make suggestions, on whether we should give an extension to the deadline. The final decision is at the discretion of the PM and TL/TLM for the team owning the portion of the codebase in question, and should take any blocked future work for the product, and timeliness of the request into account.
-
-## (Optional) Audit important users for usage of deprecated code prior to deletion.
-
-In some circumstances, it may be worthwhile to check chromium (or other important users) for usage of deprecated API’s prior to deletion. It may be done on a case by case basis as needed for deprecation of important features.
-
-## Delete the offending code.
-1. Commit CL deleting code.
-2. ???
-3. Profit.
diff --git a/catapult/telemetry/docs/pydoc/telemetry.android.android_story.html b/catapult/telemetry/docs/pydoc/telemetry.android.android_story.html
deleted file mode 100644
index 83abe1b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.android.android_story.html
+++ /dev/null
@@ -1,105 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.android.android_story</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.android.html"><font color="#ffffff">android</font></a>.android_story</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/android/android_story.py">telemetry/android/android_story.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.android.shared_android_state.html">telemetry.android.shared_android_state</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.html">telemetry.story</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.android.android_story.html#AndroidStory">AndroidStory</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidStory">class <strong>AndroidStory</strong></a>(<a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.android.android_story.html#AndroidStory">AndroidStory</a></dd>
-<dd><a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidStory-Run"><strong>Run</strong></a>(self, shared_state)</dt><dd><tt>Execute&nbsp;the&nbsp;interactions&nbsp;with&nbsp;the&nbsp;applications.</tt></dd></dl>
-
-<dl><dt><a name="AndroidStory-__init__"><strong>__init__</strong></a>(self, start_intent, is_app_ready_predicate<font color="#909090">=None</font>, name<font color="#909090">=''</font>, labels<font color="#909090">=None</font>, is_local<font color="#909090">=False</font>)</dt><dd><tt>Creates&nbsp;a&nbsp;new&nbsp;story&nbsp;for&nbsp;Android&nbsp;app.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;start_intent:&nbsp;See&nbsp;AndroidPlatform.LaunchAndroidApplication.<br>
-&nbsp;&nbsp;is_app_ready_predicate:&nbsp;See&nbsp;AndroidPlatform.LaunchAndroidApplication.<br>
-&nbsp;&nbsp;name:&nbsp;See&nbsp;<a href="telemetry.story.story.html#Story">Story</a>.__init__.<br>
-&nbsp;&nbsp;labels:&nbsp;See&nbsp;<a href="telemetry.story.story.html#Story">Story</a>.__init__.<br>
-&nbsp;&nbsp;is_app_ready_predicate:&nbsp;See&nbsp;<a href="telemetry.story.story.html#Story">Story</a>.__init__.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>:<br>
-<dl><dt><a name="AndroidStory-AsDict"><strong>AsDict</strong></a>(self)</dt><dd><tt>Converts&nbsp;a&nbsp;story&nbsp;object&nbsp;to&nbsp;a&nbsp;dict&nbsp;suitable&nbsp;for&nbsp;JSON&nbsp;output.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>display_name</strong></dt>
-</dl>
-<dl><dt><strong>file_safe_name</strong></dt>
-<dd><tt>A&nbsp;version&nbsp;of&nbsp;display_name&nbsp;that's&nbsp;safe&nbsp;to&nbsp;use&nbsp;as&nbsp;a&nbsp;filename.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;sanitizes&nbsp;special&nbsp;characters&nbsp;with&nbsp;underscores,<br>
-but&nbsp;it's&nbsp;okay&nbsp;to&nbsp;override&nbsp;it&nbsp;with&nbsp;a&nbsp;more&nbsp;specific&nbsp;implementation&nbsp;in<br>
-subclasses.</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-<dl><dt><strong>is_local</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;story&nbsp;does&nbsp;not&nbsp;require&nbsp;network.</tt></dd>
-</dl>
-<dl><dt><strong>labels</strong></dt>
-</dl>
-<dl><dt><strong>make_javascript_deterministic</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>serving_dir</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;absolute&nbsp;path&nbsp;to&nbsp;a&nbsp;directory&nbsp;with&nbsp;hash&nbsp;files&nbsp;to&nbsp;data&nbsp;that<br>
-should&nbsp;be&nbsp;updated&nbsp;from&nbsp;cloud&nbsp;storage,&nbsp;or&nbsp;None&nbsp;if&nbsp;no&nbsp;files&nbsp;need&nbsp;to&nbsp;be<br>
-updated.</tt></dd>
-</dl>
-<dl><dt><strong>shared_state_class</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.android.html b/catapult/telemetry/docs/pydoc/telemetry.android.html
deleted file mode 100644
index 748edfe..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.android.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.android</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.android</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/android/__init__.py">telemetry/android/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.android.android_story.html">android_story</a><br>
-</td><td width="25%" valign=top><a href="telemetry.android.shared_android_state.html">shared_android_state</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.android.shared_android_state.html b/catapult/telemetry/docs/pydoc/telemetry.android.shared_android_state.html
deleted file mode 100644
index c285378..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.android.shared_android_state.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.android.shared_android_state</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.android.html"><font color="#ffffff">android</font></a>.shared_android_state</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/android/shared_android_state.py">telemetry/android/shared_android_state.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.android_device.html">telemetry.internal.platform.android_device</a><br>
-<a href="telemetry.core.android_platform.html">telemetry.core.android_platform</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.story.html">telemetry.story</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.timeline_based_measurement.html">telemetry.web_perf.timeline_based_measurement</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.android.shared_android_state.html#SharedAndroidState">SharedAndroidState</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SharedAndroidState">class <strong>SharedAndroidState</strong></a>(<a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Manage&nbsp;test&nbsp;state/transitions&nbsp;across&nbsp;multiple&nbsp;android.AndroidStory's.<br>
-&nbsp;<br>
-WARNING:&nbsp;the&nbsp;class&nbsp;is&nbsp;not&nbsp;ready&nbsp;for&nbsp;public&nbsp;consumption.<br>
-Email&nbsp;telemetry@chromium.org&nbsp;if&nbsp;you&nbsp;feel&nbsp;like&nbsp;you&nbsp;must&nbsp;use&nbsp;it.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.android.shared_android_state.html#SharedAndroidState">SharedAndroidState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SharedAndroidState-CanRunStory"><strong>CanRunStory</strong></a>(self, story)</dt><dd><tt>This&nbsp;does&nbsp;not&nbsp;apply&nbsp;to&nbsp;android&nbsp;app&nbsp;stories.</tt></dd></dl>
-
-<dl><dt><a name="SharedAndroidState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedAndroidState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedAndroidState-TearDownState"><strong>TearDownState</strong></a>(self)</dt><dd><tt>Tear&nbsp;down&nbsp;anything&nbsp;created&nbsp;in&nbsp;the&nbsp;__init__&nbsp;method&nbsp;that&nbsp;is&nbsp;not&nbsp;needed.<br>
-&nbsp;<br>
-Currently,&nbsp;there&nbsp;is&nbsp;no&nbsp;clean-up&nbsp;needed&nbsp;from&nbsp;<a href="#SharedAndroidState">SharedAndroidState</a>.__init__.</tt></dd></dl>
-
-<dl><dt><a name="SharedAndroidState-WillRunStory"><strong>WillRunStory</strong></a>(self, story)</dt></dl>
-
-<dl><dt><a name="SharedAndroidState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt><dd><tt>This&nbsp;method&nbsp;is&nbsp;styled&nbsp;on&nbsp;unittest.TestCase.setUpClass.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;test:&nbsp;a&nbsp;web_perf.TimelineBasedMeasurement&nbsp;instance.<br>
-&nbsp;&nbsp;options:&nbsp;a&nbsp;BrowserFinderOptions&nbsp;instance&nbsp;with&nbsp;command&nbsp;line&nbsp;options.<br>
-&nbsp;&nbsp;story_set:&nbsp;a&nbsp;story.StorySet&nbsp;instance.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.benchmark.html b/catapult/telemetry/docs/pydoc/telemetry.benchmark.html
deleted file mode 100644
index fb5de7b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.benchmark.html
+++ /dev/null
@@ -1,299 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.benchmark</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.benchmark</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/benchmark.py">telemetry/benchmark.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.command_line.html">telemetry.internal.util.command_line</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="optparse.html">optparse</a><br>
-<a href="telemetry.page.page_test.html">telemetry.page.page_test</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.story_runner.html">telemetry.internal.story_runner</a><br>
-<a href="telemetry.web_perf.timeline_based_measurement.html">telemetry.web_perf.timeline_based_measurement</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.benchmark.html#BenchmarkMetadata">BenchmarkMetadata</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.benchmark.html#InvalidOptionsError">InvalidOptionsError</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>(<a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.benchmark.html#Benchmark">Benchmark</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Benchmark">class <strong>Benchmark</strong></a>(<a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Base&nbsp;class&nbsp;for&nbsp;a&nbsp;Telemetry&nbsp;benchmark.<br>
-&nbsp;<br>
-A&nbsp;benchmark&nbsp;packages&nbsp;a&nbsp;measurement&nbsp;and&nbsp;a&nbsp;PageSet&nbsp;together.<br>
-Benchmarks&nbsp;default&nbsp;to&nbsp;using&nbsp;TBM&nbsp;unless&nbsp;you&nbsp;override&nbsp;the&nbsp;value&nbsp;of<br>
-<a href="#Benchmark">Benchmark</a>.test,&nbsp;or&nbsp;override&nbsp;the&nbsp;CreatePageTest&nbsp;method.<br>
-&nbsp;<br>
-New&nbsp;benchmarks&nbsp;should&nbsp;override&nbsp;CreateStorySet.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.benchmark.html#Benchmark">Benchmark</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Benchmark-CreatePageTest"><strong>CreatePageTest</strong></a>(self, options)</dt><dd><tt>Return&nbsp;the&nbsp;PageTest&nbsp;for&nbsp;this&nbsp;<a href="#Benchmark">Benchmark</a>.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;for&nbsp;PageTest&nbsp;tests.<br>
-Override,&nbsp;override&nbsp;CreateTimelineBasedMeasurementOptions&nbsp;to&nbsp;configure<br>
-TimelineBasedMeasurement&nbsp;tests.&nbsp;Do&nbsp;not&nbsp;override&nbsp;both&nbsp;methods.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;options:&nbsp;a&nbsp;browser_options.BrowserFinderOptions&nbsp;instance<br>
-Returns:<br>
-&nbsp;&nbsp;|<a href="#Benchmark-test">test</a>()|&nbsp;if&nbsp;|test|&nbsp;is&nbsp;a&nbsp;PageTest&nbsp;class.<br>
-&nbsp;&nbsp;Otherwise,&nbsp;a&nbsp;TimelineBasedMeasurement&nbsp;instance.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-CreateStorySet"><strong>CreateStorySet</strong></a>(self, options)</dt><dd><tt>Creates&nbsp;the&nbsp;instance&nbsp;of&nbsp;StorySet&nbsp;used&nbsp;to&nbsp;run&nbsp;the&nbsp;benchmark.<br>
-&nbsp;<br>
-Can&nbsp;be&nbsp;overridden&nbsp;by&nbsp;subclasses.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-CreateTimelineBasedMeasurementOptions"><strong>CreateTimelineBasedMeasurementOptions</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;TimelineBasedMeasurementOptions&nbsp;for&nbsp;this&nbsp;<a href="#Benchmark">Benchmark</a>.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;configure&nbsp;a&nbsp;TimelineBasedMeasurement&nbsp;benchmark.<br>
-Otherwise,&nbsp;override&nbsp;CreatePageTest&nbsp;for&nbsp;PageTest&nbsp;tests.&nbsp;Do&nbsp;not&nbsp;override<br>
-both&nbsp;methods.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(self, options)</dt><dd><tt>Add&nbsp;browser&nbsp;options&nbsp;that&nbsp;are&nbsp;required&nbsp;by&nbsp;this&nbsp;benchmark.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-GetMetadata"><strong>GetMetadata</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Benchmark-GetTraceRerunCommands"><strong>GetTraceRerunCommands</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Benchmark-Run"><strong>Run</strong></a>(self, finder_options)</dt><dd><tt>Do&nbsp;not&nbsp;override&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-SetupBenchmarkDebugTraceRerunOptions"><strong>SetupBenchmarkDebugTraceRerunOptions</strong></a>(self, tbm_options)</dt><dd><tt>Setup&nbsp;tracing&nbsp;categories&nbsp;associated&nbsp;with&nbsp;debug&nbsp;trace&nbsp;option.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-SetupBenchmarkDefaultTraceRerunOptions"><strong>SetupBenchmarkDefaultTraceRerunOptions</strong></a>(self, tbm_options)</dt><dd><tt>Setup&nbsp;tracing&nbsp;categories&nbsp;associated&nbsp;with&nbsp;default&nbsp;trace&nbsp;option.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-SetupTraceRerunOptions"><strong>SetupTraceRerunOptions</strong></a>(self, browser_options, tbm_options)</dt></dl>
-
-<dl><dt><a name="Benchmark-__init__"><strong>__init__</strong></a>(self, max_failures<font color="#909090">=None</font>)</dt><dd><tt>Creates&nbsp;a&nbsp;new&nbsp;<a href="#Benchmark">Benchmark</a>.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;max_failures:&nbsp;The&nbsp;number&nbsp;of&nbsp;story&nbsp;run's&nbsp;failures&nbsp;before&nbsp;bailing<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;executing&nbsp;subsequent&nbsp;page&nbsp;runs.&nbsp;If&nbsp;None,&nbsp;we&nbsp;never&nbsp;bail.</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Benchmark-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Benchmark-HasTraceRerunDebugOption"><strong>HasTraceRerunDebugOption</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Benchmark-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Benchmark-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Benchmark-SetArgumentDefaults"><strong>SetArgumentDefaults</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Benchmark-ShouldDisable"><strong>ShouldDisable</strong></a>(cls, possible_browser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;this&nbsp;method&nbsp;to&nbsp;disable&nbsp;a&nbsp;benchmark&nbsp;under&nbsp;specific&nbsp;conditions.<br>
-&nbsp;<br>
-Supports&nbsp;logic&nbsp;too&nbsp;complex&nbsp;for&nbsp;simple&nbsp;Enabled&nbsp;and&nbsp;Disabled&nbsp;decorators.<br>
-Decorators&nbsp;are&nbsp;still&nbsp;respected&nbsp;in&nbsp;cases&nbsp;where&nbsp;this&nbsp;function&nbsp;returns&nbsp;False.</tt></dd></dl>
-
-<dl><dt><a name="Benchmark-ValueCanBeAddedPredicate"><strong>ValueCanBeAddedPredicate</strong></a>(cls, value, is_first_result)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;|value|&nbsp;can&nbsp;be&nbsp;added&nbsp;to&nbsp;the&nbsp;test&nbsp;results.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;customize&nbsp;the&nbsp;logic&nbsp;of&nbsp;adding&nbsp;values&nbsp;to&nbsp;test<br>
-results.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;value:&nbsp;a&nbsp;value.Value&nbsp;instance&nbsp;(except&nbsp;failure.FailureValue,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;skip.SkipValue&nbsp;or&nbsp;trace.TraceValue&nbsp;which&nbsp;will&nbsp;always&nbsp;be&nbsp;added).<br>
-&nbsp;&nbsp;is_first_result:&nbsp;True&nbsp;if&nbsp;|value|&nbsp;is&nbsp;the&nbsp;first&nbsp;result&nbsp;for&nbsp;its<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;corresponding&nbsp;story.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;|value|&nbsp;should&nbsp;be&nbsp;added&nbsp;to&nbsp;the&nbsp;test&nbsp;results.<br>
-&nbsp;&nbsp;Otherwise,&nbsp;it&nbsp;returns&nbsp;False.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>max_failures</strong></dt>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>options</strong> = {}</dl>
-
-<dl><dt><strong>test</strong> = &lt;class 'telemetry.web_perf.timeline_based_measurement.TimelineBasedMeasurement'&gt;<dd><tt>Collects&nbsp;multiple&nbsp;metrics&nbsp;based&nbsp;on&nbsp;their&nbsp;interaction&nbsp;records.<br>
-&nbsp;<br>
-A&nbsp;timeline&nbsp;based&nbsp;measurement&nbsp;shifts&nbsp;the&nbsp;burden&nbsp;of&nbsp;what&nbsp;metrics&nbsp;to&nbsp;collect&nbsp;onto<br>
-the&nbsp;story&nbsp;under&nbsp;test.&nbsp;Instead&nbsp;of&nbsp;the&nbsp;measurement<br>
-having&nbsp;a&nbsp;fixed&nbsp;set&nbsp;of&nbsp;values&nbsp;it&nbsp;collects,&nbsp;the&nbsp;story&nbsp;being&nbsp;tested<br>
-issues&nbsp;(via&nbsp;javascript)&nbsp;an&nbsp;Interaction&nbsp;record&nbsp;into&nbsp;the&nbsp;user&nbsp;timing&nbsp;API&nbsp;that<br>
-describing&nbsp;what&nbsp;is&nbsp;happening&nbsp;at&nbsp;that&nbsp;time,&nbsp;as&nbsp;well&nbsp;as&nbsp;a&nbsp;standardized&nbsp;set<br>
-of&nbsp;flags&nbsp;describing&nbsp;the&nbsp;semantics&nbsp;of&nbsp;the&nbsp;work&nbsp;being&nbsp;done.&nbsp;The<br>
-TimelineBasedMeasurement&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;collects&nbsp;a&nbsp;trace&nbsp;that&nbsp;includes&nbsp;both&nbsp;these<br>
-interaction&nbsp;records,&nbsp;and&nbsp;a&nbsp;user-chosen&nbsp;amount&nbsp;of&nbsp;performance&nbsp;data&nbsp;using<br>
-Telemetry's&nbsp;various&nbsp;timeline-producing&nbsp;APIs,&nbsp;tracing&nbsp;especially.<br>
-&nbsp;<br>
-It&nbsp;then&nbsp;passes&nbsp;the&nbsp;recorded&nbsp;timeline&nbsp;to&nbsp;different&nbsp;TimelineBasedMetrics&nbsp;based<br>
-on&nbsp;those&nbsp;flags.&nbsp;As&nbsp;an&nbsp;example,&nbsp;this&nbsp;allows&nbsp;a&nbsp;single&nbsp;story&nbsp;run&nbsp;to&nbsp;produce<br>
-load&nbsp;timing&nbsp;data,&nbsp;smoothness&nbsp;data,&nbsp;critical&nbsp;jank&nbsp;information&nbsp;and&nbsp;overall&nbsp;cpu<br>
-usage&nbsp;information.<br>
-&nbsp;<br>
-For&nbsp;information&nbsp;on&nbsp;how&nbsp;to&nbsp;mark&nbsp;up&nbsp;a&nbsp;page&nbsp;to&nbsp;work&nbsp;with<br>
-TimelineBasedMeasurement,&nbsp;refer&nbsp;to&nbsp;the<br>
-perf.metrics.timeline_interaction_record&nbsp;module.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;options:&nbsp;an&nbsp;instance&nbsp;of&nbsp;timeline_based_measurement.Options.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;results_wrapper:&nbsp;A&nbsp;class&nbsp;that&nbsp;has&nbsp;the&nbsp;__init__&nbsp;method&nbsp;takes&nbsp;in<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page_test_results&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;and&nbsp;the&nbsp;interaction&nbsp;record&nbsp;label.&nbsp;This<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;follows&nbsp;the&nbsp;ResultsWrapperInterface.&nbsp;Note:&nbsp;this&nbsp;class&nbsp;is&nbsp;not<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;supported&nbsp;long&nbsp;term&nbsp;and&nbsp;to&nbsp;be&nbsp;removed&nbsp;when&nbsp;crbug.com/453109&nbsp;is&nbsp;resolved.</tt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>:<br>
-<dl><dt><a name="Benchmark-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Benchmark-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BenchmarkMetadata">class <strong>BenchmarkMetadata</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="BenchmarkMetadata-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BenchmarkMetadata-__init__"><strong>__init__</strong></a>(self, name, description<font color="#909090">=''</font>, rerun_options<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>description</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>rerun_options</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InvalidOptionsError">class <strong>InvalidOptionsError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Raised&nbsp;for&nbsp;invalid&nbsp;benchmark&nbsp;options.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.benchmark.html#InvalidOptionsError">InvalidOptionsError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="InvalidOptionsError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#InvalidOptionsError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="InvalidOptionsError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InvalidOptionsError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InvalidOptionsError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidOptionsError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="InvalidOptionsError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(parser)</dt></dl>
- <dl><dt><a name="-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(parser, args)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.benchmark_runner.html b/catapult/telemetry/docs/pydoc/telemetry.benchmark_runner.html
deleted file mode 100644
index a6abee5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.benchmark_runner.html
+++ /dev/null
@@ -1,223 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.benchmark_runner</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.benchmark_runner</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/benchmark_runner.py">telemetry/benchmark_runner.py</a></font></td></tr></table>
-    <p><tt>Parses&nbsp;the&nbsp;command&nbsp;line,&nbsp;discovers&nbsp;the&nbsp;appropriate&nbsp;benchmarks,&nbsp;and&nbsp;runs&nbsp;them.<br>
-&nbsp;<br>
-Handles&nbsp;benchmark&nbsp;configuration,&nbsp;but&nbsp;all&nbsp;the&nbsp;logic&nbsp;for<br>
-actually&nbsp;running&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;in&nbsp;Benchmark&nbsp;and&nbsp;PageRunner.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.benchmark.html">telemetry.benchmark</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="telemetry.internal.browser.browser_options.html">telemetry.internal.browser.browser_options</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.command_line.html">telemetry.internal.util.command_line</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-<a href="hashlib.html">hashlib</a><br>
-</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-<a href="json.html">json</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.project_config.html">telemetry.project_config</a><br>
-<a href="telemetry.internal.util.ps_util.html">telemetry.internal.util.ps_util</a><br>
-<a href="sys.html">sys</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>(<a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.benchmark_runner.html#Help">Help</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.benchmark_runner.html#List">List</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.benchmark_runner.html#Run">Run</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Help">class <strong>Help</strong></a>(<a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Display&nbsp;help&nbsp;information&nbsp;about&nbsp;a&nbsp;command<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.benchmark_runner.html#Help">Help</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Help-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>usage</strong> = '[command]'</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>:<br>
-<dl><dt><a name="Help-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Help-CreateParser"><strong>CreateParser</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Help-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Help-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>:<br>
-<dl><dt><a name="Help-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Help-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="List">class <strong>List</strong></a>(<a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Lists&nbsp;the&nbsp;available&nbsp;benchmarks<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.benchmark_runner.html#List">List</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="List-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="List-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser, _)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="List-CreateParser"><strong>CreateParser</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="List-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>usage</strong> = '[benchmark_name] [&lt;options&gt;]'</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>:<br>
-<dl><dt><a name="List-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>:<br>
-<dl><dt><a name="List-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="List-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Run">class <strong>Run</strong></a>(<a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#Run">Run</a>&nbsp;one&nbsp;or&nbsp;more&nbsp;benchmarks&nbsp;(default)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.benchmark_runner.html#Run">Run</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Run-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Run-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Run-CreateParser"><strong>CreateParser</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Run-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>usage</strong> = 'benchmark_name [page_set] [&lt;options&gt;]'</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>:<br>
-<dl><dt><a name="Run-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>:<br>
-<dl><dt><a name="Run-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Run-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetBenchmarkByName"><strong>GetBenchmarkByName</strong></a>(name, environment)</dt></dl>
- <dl><dt><a name="-PrintBenchmarkList"><strong>PrintBenchmarkList</strong></a>(benchmarks, possible_browser, output_pipe<font color="#909090">=&lt;open file '&lt;stdout&gt;', mode 'w'&gt;</font>)</dt><dd><tt>Print&nbsp;benchmarks&nbsp;that&nbsp;are&nbsp;not&nbsp;filtered&nbsp;in&nbsp;the&nbsp;same&nbsp;order&nbsp;of&nbsp;benchmarks&nbsp;in<br>
-the&nbsp;|benchmarks|&nbsp;list.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;benchmarks:&nbsp;the&nbsp;list&nbsp;of&nbsp;benchmarks&nbsp;to&nbsp;be&nbsp;printed&nbsp;(in&nbsp;the&nbsp;same&nbsp;order&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list).<br>
-&nbsp;&nbsp;possible_browser:&nbsp;the&nbsp;possible_browser&nbsp;instance&nbsp;that's&nbsp;used&nbsp;for&nbsp;checking<br>
-&nbsp;&nbsp;&nbsp;&nbsp;which&nbsp;benchmarks&nbsp;are&nbsp;enabled.<br>
-&nbsp;&nbsp;output_pipe:&nbsp;the&nbsp;stream&nbsp;in&nbsp;which&nbsp;benchmarks&nbsp;are&nbsp;printed&nbsp;on.</tt></dd></dl>
- <dl><dt><a name="-main"><strong>main</strong></a>(environment)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.android_action_runner.html b/catapult/telemetry/docs/pydoc/telemetry.core.android_action_runner.html
deleted file mode 100644
index ec50ae5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.android_action_runner.html
+++ /dev/null
@@ -1,191 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.android_action_runner</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.android_action_runner</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/android_action_runner.py">telemetry/core/android_action_runner.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.android_action_runner.html#AndroidActionRunner">AndroidActionRunner</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.android_action_runner.html#ActionNotSupported">ActionNotSupported</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ActionNotSupported">class <strong>ActionNotSupported</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.android_action_runner.html#ActionNotSupported">ActionNotSupported</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ActionNotSupported-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ActionNotSupported-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ActionNotSupported-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ActionNotSupported-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ActionNotSupported-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ActionNotSupported-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ActionNotSupported-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidActionRunner">class <strong>AndroidActionRunner</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;an&nbsp;API&nbsp;for&nbsp;interacting&nbsp;with&nbsp;an&nbsp;android&nbsp;device.<br>
-&nbsp;<br>
-This&nbsp;makes&nbsp;use&nbsp;of&nbsp;functionality&nbsp;provided&nbsp;by&nbsp;the&nbsp;android&nbsp;input&nbsp;command.&nbsp;None<br>
-of&nbsp;the&nbsp;gestures&nbsp;here&nbsp;are&nbsp;guaranteed&nbsp;to&nbsp;be&nbsp;performant&nbsp;for&nbsp;telemetry&nbsp;tests&nbsp;and<br>
-there&nbsp;is&nbsp;no&nbsp;official&nbsp;support&nbsp;for&nbsp;this&nbsp;API.<br>
-&nbsp;<br>
-TODO(ariblue):&nbsp;Replace&nbsp;this&nbsp;API&nbsp;with&nbsp;a&nbsp;better&nbsp;implementation&nbsp;for&nbsp;interacting<br>
-with&nbsp;native&nbsp;components.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AndroidActionRunner-InputKeyEvent"><strong>InputKeyEvent</strong></a>(self, key)</dt><dd><tt>Send&nbsp;a&nbsp;single&nbsp;key&nbsp;input&nbsp;to&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;key:&nbsp;A&nbsp;key&nbsp;code&nbsp;number&nbsp;or&nbsp;name&nbsp;that&nbsp;will&nbsp;be&nbsp;sent&nbsp;to&nbsp;the&nbsp;device</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-InputPress"><strong>InputPress</strong></a>(self)</dt><dd><tt>Perform&nbsp;a&nbsp;press&nbsp;input.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-InputRoll"><strong>InputRoll</strong></a>(self, dx, dy)</dt><dd><tt>Perform&nbsp;a&nbsp;roll&nbsp;input.&nbsp;This&nbsp;sends&nbsp;a&nbsp;simple&nbsp;zero-pressure&nbsp;move&nbsp;event.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;dx:&nbsp;Change&nbsp;in&nbsp;the&nbsp;x&nbsp;coordinate&nbsp;due&nbsp;to&nbsp;move.<br>
-&nbsp;&nbsp;dy:&nbsp;Change&nbsp;in&nbsp;the&nbsp;y&nbsp;coordinate&nbsp;due&nbsp;to&nbsp;move.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-InputSwipe"><strong>InputSwipe</strong></a>(self, left_start_coord, top_start_coord, left_end_coord, top_end_coord, duration)</dt><dd><tt>Perform&nbsp;a&nbsp;swipe&nbsp;input.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;left_start_coord:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;gesture<br>
-&nbsp;&nbsp;top_start_coord:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;gesture<br>
-&nbsp;&nbsp;left_end_coord:&nbsp;The&nbsp;horizontal&nbsp;ending&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;gesture<br>
-&nbsp;&nbsp;top_end_coord:&nbsp;The&nbsp;vertical&nbsp;ending&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;gesture<br>
-&nbsp;&nbsp;duration:&nbsp;The&nbsp;length&nbsp;of&nbsp;time&nbsp;of&nbsp;the&nbsp;swipe&nbsp;in&nbsp;milliseconds</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-InputTap"><strong>InputTap</strong></a>(self, x_coord, y_coord)</dt><dd><tt>Perform&nbsp;a&nbsp;tap&nbsp;input&nbsp;at&nbsp;the&nbsp;given&nbsp;coordinates.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x_coord:&nbsp;The&nbsp;x&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;tap&nbsp;event.<br>
-&nbsp;&nbsp;y_coord:&nbsp;The&nbsp;y&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;tap&nbsp;event.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-InputText"><strong>InputText</strong></a>(self, string)</dt><dd><tt>Convert&nbsp;the&nbsp;characters&nbsp;of&nbsp;the&nbsp;string&nbsp;into&nbsp;key&nbsp;events&nbsp;and&nbsp;send&nbsp;to&nbsp;device.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;string:&nbsp;The&nbsp;string&nbsp;to&nbsp;send&nbsp;to&nbsp;the&nbsp;device.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-SmoothScrollBy"><strong>SmoothScrollBy</strong></a>(self, left_start_coord, top_start_coord, direction, scroll_distance)</dt><dd><tt>Perfrom&nbsp;gesture&nbsp;to&nbsp;scroll&nbsp;down&nbsp;on&nbsp;the&nbsp;android&nbsp;device.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-TurnScreenOff"><strong>TurnScreenOff</strong></a>(self)</dt><dd><tt>If&nbsp;device&nbsp;screen&nbsp;is&nbsp;on,&nbsp;turn&nbsp;screen&nbsp;off.<br>
-If&nbsp;the&nbsp;screen&nbsp;is&nbsp;already&nbsp;off,&nbsp;log&nbsp;a&nbsp;warning&nbsp;and&nbsp;return&nbsp;immediately.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;Timeout:&nbsp;If&nbsp;the&nbsp;screen&nbsp;is&nbsp;on&nbsp;and&nbsp;device&nbsp;fails&nbsp;to&nbsp;turn&nbsp;screen&nbsp;off.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-TurnScreenOn"><strong>TurnScreenOn</strong></a>(self)</dt><dd><tt>If&nbsp;device&nbsp;screen&nbsp;is&nbsp;off,&nbsp;turn&nbsp;screen&nbsp;on.<br>
-If&nbsp;the&nbsp;screen&nbsp;is&nbsp;already&nbsp;on,&nbsp;log&nbsp;a&nbsp;warning&nbsp;and&nbsp;return&nbsp;immediately.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;Timeout:&nbsp;If&nbsp;the&nbsp;screen&nbsp;is&nbsp;off&nbsp;and&nbsp;device&nbsp;fails&nbsp;to&nbsp;turn&nbsp;screen&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-UnlockScreen"><strong>UnlockScreen</strong></a>(self)</dt><dd><tt>If&nbsp;device&nbsp;screen&nbsp;is&nbsp;locked,&nbsp;unlocks&nbsp;it.<br>
-If&nbsp;the&nbsp;device&nbsp;is&nbsp;not&nbsp;locked,&nbsp;log&nbsp;a&nbsp;warning&nbsp;and&nbsp;return&nbsp;immediately.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;Timeout:&nbsp;If&nbsp;device&nbsp;fails&nbsp;to&nbsp;unlock&nbsp;screen.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-Wait"><strong>Wait</strong></a>(self, seconds)</dt><dd><tt>Wait&nbsp;for&nbsp;the&nbsp;number&nbsp;of&nbsp;seconds&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;seconds:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait.</tt></dd></dl>
-
-<dl><dt><a name="AndroidActionRunner-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.android_platform.html b/catapult/telemetry/docs/pydoc/telemetry.core.android_platform.html
deleted file mode 100644
index 8a56589..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.android_platform.html
+++ /dev/null
@@ -1,275 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.android_platform</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.android_platform</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/android_platform.py">telemetry/core/android_platform.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.android_action_runner.html">telemetry.core.android_action_runner</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.app.android_app.html">telemetry.internal.app.android_app</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.android_app_backend.html">telemetry.internal.backends.android_app_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.platform.html#Platform">telemetry.core.platform.Platform</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.android_platform.html#AndroidPlatform">AndroidPlatform</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidPlatform">class <strong>AndroidPlatform</strong></a>(<a href="telemetry.core.platform.html#Platform">telemetry.core.platform.Platform</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.android_platform.html#AndroidPlatform">AndroidPlatform</a></dd>
-<dd><a href="telemetry.core.platform.html#Platform">telemetry.core.platform.Platform</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidPlatform-LaunchAndroidApplication"><strong>LaunchAndroidApplication</strong></a>(self, start_intent, is_app_ready_predicate<font color="#909090">=None</font>, app_has_webviews<font color="#909090">=True</font>)</dt><dd><tt>Launches&nbsp;an&nbsp;Android&nbsp;application&nbsp;given&nbsp;the&nbsp;intent.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;start_intent:&nbsp;The&nbsp;intent&nbsp;to&nbsp;use&nbsp;to&nbsp;start&nbsp;the&nbsp;app.<br>
-&nbsp;&nbsp;is_app_ready_predicate:&nbsp;A&nbsp;predicate&nbsp;function&nbsp;to&nbsp;determine<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;whether&nbsp;the&nbsp;app&nbsp;is&nbsp;ready.&nbsp;This&nbsp;is&nbsp;a&nbsp;function&nbsp;that&nbsp;takes&nbsp;an<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AndroidApp&nbsp;instance&nbsp;and&nbsp;return&nbsp;a&nbsp;boolean.&nbsp;When&nbsp;it&nbsp;is&nbsp;not&nbsp;passed&nbsp;in,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;app&nbsp;is&nbsp;ready&nbsp;when&nbsp;the&nbsp;intent&nbsp;to&nbsp;launch&nbsp;it&nbsp;is&nbsp;completed.<br>
-&nbsp;&nbsp;app_has_webviews:&nbsp;A&nbsp;boolean&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;app&nbsp;is&nbsp;expected&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;contain&nbsp;any&nbsp;WebViews.&nbsp;If&nbsp;True,&nbsp;the&nbsp;app&nbsp;will&nbsp;be&nbsp;launched&nbsp;with<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;appropriate&nbsp;webview&nbsp;flags,&nbsp;and&nbsp;the&nbsp;GetWebViews&nbsp;method&nbsp;of&nbsp;the&nbsp;returned<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object&nbsp;may&nbsp;be&nbsp;used&nbsp;to&nbsp;access&nbsp;them.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;reference&nbsp;to&nbsp;the&nbsp;android_app&nbsp;launched.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>android_action_runner</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.platform.html#Platform">telemetry.core.platform.Platform</a>:<br>
-<dl><dt><a name="AndroidPlatform-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;bool&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;platform&nbsp;supports&nbsp;video&nbsp;capture.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;disk&nbsp;cache&nbsp;can&nbsp;be&nbsp;flushed&nbsp;for&nbsp;specific&nbsp;files.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt><dd><tt>Returns&nbsp;whether&nbsp;the&nbsp;platform&nbsp;can&nbsp;launch&nbsp;the&nbsp;given&nbsp;application.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;network&nbsp;data&nbsp;can&nbsp;be&nbsp;retrieved,&nbsp;false&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;power&nbsp;can&nbsp;be&nbsp;monitored&nbsp;asynchronously&nbsp;via<br>
-<a href="#AndroidPlatform-StartMonitoringPower">StartMonitoringPower</a>()&nbsp;and&nbsp;<a href="#AndroidPlatform-StopMonitoringPower">StopMonitoringPower</a>().</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt><dd><tt>Platforms&nbsp;may&nbsp;be&nbsp;able&nbsp;to&nbsp;detect&nbsp;thermal&nbsp;throttling.<br>
-&nbsp;<br>
-Some&nbsp;fan-less&nbsp;computers&nbsp;go&nbsp;into&nbsp;a&nbsp;reduced&nbsp;performance&nbsp;mode&nbsp;when&nbsp;their&nbsp;heat<br>
-exceeds&nbsp;a&nbsp;certain&nbsp;threshold.&nbsp;Performance&nbsp;tests&nbsp;in&nbsp;particular&nbsp;should&nbsp;use&nbsp;this<br>
-API&nbsp;to&nbsp;detect&nbsp;if&nbsp;this&nbsp;has&nbsp;happened&nbsp;and&nbsp;interpret&nbsp;results&nbsp;accordingly.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatform-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt><dd><tt>Flushes&nbsp;the&nbsp;OS's&nbsp;DNS&nbsp;cache&nbsp;completely.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;may&nbsp;require&nbsp;root&nbsp;or&nbsp;administrator&nbsp;access.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt><dd><tt>Flushes&nbsp;the&nbsp;OS's&nbsp;file&nbsp;cache&nbsp;completely.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;may&nbsp;require&nbsp;root&nbsp;or&nbsp;administrator&nbsp;access.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt><dd><tt>Flushes&nbsp;the&nbsp;OS's&nbsp;file&nbsp;cache&nbsp;for&nbsp;the&nbsp;specified&nbsp;directory.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;does&nbsp;not&nbsp;require&nbsp;root&nbsp;or&nbsp;administrator&nbsp;access.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-GetArchName"><strong>GetArchName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="telemetry.core.platform.html#Platform">Platform</a>&nbsp;architecture.<br>
-&nbsp;<br>
-Examples:&nbsp;x86_64&nbsp;(posix),&nbsp;AMD64&nbsp;(win),&nbsp;armeabi-v7a,&nbsp;x86</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="telemetry.core.platform.html#Platform">Platform</a>&nbsp;device,&nbsp;or&nbsp;None.<br>
-&nbsp;<br>
-Examples:&nbsp;Nexus&nbsp;7,&nbsp;Nexus&nbsp;6,&nbsp;Desktop</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt><dd><tt>Get&nbsp;current&nbsp;network&nbsp;data.<br>
-Returns:<br>
-&nbsp;&nbsp;Tuple&nbsp;of&nbsp;(sent_data,&nbsp;received_data)&nbsp;in&nbsp;kb&nbsp;if&nbsp;data&nbsp;can&nbsp;be&nbsp;found,<br>
-&nbsp;&nbsp;None&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-GetOSName"><strong>GetOSName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="telemetry.core.platform.html#Platform">Platform</a>&nbsp;OS.<br>
-&nbsp;<br>
-Examples:&nbsp;WIN,&nbsp;MAC,&nbsp;LINUX,&nbsp;CHROMEOS</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;logically&nbsp;sortable,&nbsp;string-like&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="telemetry.core.platform.html#Platform">Platform</a>&nbsp;OS<br>
-version.<br>
-&nbsp;<br>
-Examples:&nbsp;VISTA,&nbsp;WIN7,&nbsp;LION,&nbsp;MOUNTAINLION</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-GetOSVersionNumber"><strong>GetOSVersionNumber</strong></a>(self)</dt><dd><tt>Returns&nbsp;an&nbsp;integer&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="telemetry.core.platform.html#Platform">Platform</a>&nbsp;OS&nbsp;major&nbsp;version.<br>
-&nbsp;<br>
-Examples:&nbsp;On&nbsp;Mac,&nbsp;13&nbsp;for&nbsp;Mavericks,&nbsp;14&nbsp;for&nbsp;Yosemite.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;device&nbsp;has&nbsp;been&nbsp;thermally&nbsp;throttled.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt><dd><tt>Installs&nbsp;the&nbsp;given&nbsp;application.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt><dd><tt>Returns&nbsp;whether&nbsp;an&nbsp;application&nbsp;is&nbsp;currently&nbsp;running.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-IsMonitoringPower"><strong>IsMonitoringPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;power&nbsp;is&nbsp;currently&nbsp;being&nbsp;monitored,&nbsp;false&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;device&nbsp;is&nbsp;currently&nbsp;thermally&nbsp;throttled.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt><dd><tt>"Launches&nbsp;the&nbsp;given&nbsp;|application|&nbsp;with&nbsp;a&nbsp;list&nbsp;of&nbsp;|parameters|&nbsp;on&nbsp;the&nbsp;OS.<br>
-&nbsp;<br>
-Set&nbsp;|elevate_privilege|&nbsp;to&nbsp;launch&nbsp;the&nbsp;application&nbsp;with&nbsp;root&nbsp;or&nbsp;admin&nbsp;rights.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;popen&nbsp;style&nbsp;process&nbsp;handle&nbsp;for&nbsp;host&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-SetHTTPServerDirectories"><strong>SetHTTPServerDirectories</strong></a>(self, paths)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;HTTP&nbsp;server&nbsp;was&nbsp;started,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-StartLocalServer"><strong>StartLocalServer</strong></a>(self, server)</dt><dd><tt>Starts&nbsp;a&nbsp;LocalServer&nbsp;and&nbsp;associates&nbsp;it&nbsp;with&nbsp;this&nbsp;platform.<br>
-|server.Close()|&nbsp;should&nbsp;be&nbsp;called&nbsp;manually&nbsp;to&nbsp;close&nbsp;the&nbsp;started&nbsp;server.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt><dd><tt>Starts&nbsp;monitoring&nbsp;power&nbsp;utilization&nbsp;statistics.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser:&nbsp;The&nbsp;browser&nbsp;to&nbsp;monitor.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt><dd><tt>Starts&nbsp;capturing&nbsp;video.<br>
-&nbsp;<br>
-Outer&nbsp;framing&nbsp;may&nbsp;be&nbsp;included&nbsp;(from&nbsp;the&nbsp;OS,&nbsp;browser&nbsp;window,&nbsp;and&nbsp;webcam).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;min_bitrate_mbps:&nbsp;The&nbsp;minimum&nbsp;capture&nbsp;bitrate&nbsp;in&nbsp;MegaBits&nbsp;Per&nbsp;Second.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;platform&nbsp;is&nbsp;free&nbsp;to&nbsp;deliver&nbsp;a&nbsp;higher&nbsp;bitrate&nbsp;if&nbsp;it&nbsp;can&nbsp;do&nbsp;so<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;without&nbsp;increasing&nbsp;overhead.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;required&nbsp;|min_bitrate_mbps|&nbsp;can't&nbsp;be&nbsp;achieved.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-StopAllLocalServers"><strong>StopAllLocalServers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatform-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt><dd><tt>Stops&nbsp;monitoring&nbsp;power&nbsp;utilization&nbsp;and&nbsp;returns&nbsp;stats<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;None&nbsp;if&nbsp;power&nbsp;measurement&nbsp;failed&nbsp;for&nbsp;some&nbsp;reason,&nbsp;otherwise&nbsp;a&nbsp;dict&nbsp;of<br>
-&nbsp;&nbsp;power&nbsp;utilization&nbsp;statistics&nbsp;containing:&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;An&nbsp;identifier&nbsp;for&nbsp;the&nbsp;data&nbsp;provider.&nbsp;Allows&nbsp;to&nbsp;evaluate&nbsp;the&nbsp;precision<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;of&nbsp;the&nbsp;data.&nbsp;Example&nbsp;values:&nbsp;monsoon,&nbsp;powermetrics,&nbsp;ds2784<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'identifier':&nbsp;identifier,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;The&nbsp;instantaneous&nbsp;power&nbsp;(voltage&nbsp;*&nbsp;current)&nbsp;reading&nbsp;in&nbsp;milliwatts&nbsp;at<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;each&nbsp;sample.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'power_samples_mw':&nbsp;&nbsp;[mw0,&nbsp;mw1,&nbsp;...,&nbsp;mwN],<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;The&nbsp;full&nbsp;system&nbsp;energy&nbsp;consumption&nbsp;during&nbsp;the&nbsp;sampling&nbsp;period&nbsp;in<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;milliwatt&nbsp;hours.&nbsp;May&nbsp;be&nbsp;estimated&nbsp;by&nbsp;integrating&nbsp;power&nbsp;samples&nbsp;or&nbsp;may<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;be&nbsp;exact&nbsp;on&nbsp;supported&nbsp;hardware.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'energy_consumption_mwh':&nbsp;mwh,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;The&nbsp;target&nbsp;application's&nbsp;energy&nbsp;consumption&nbsp;during&nbsp;the&nbsp;sampling&nbsp;period<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;in&nbsp;milliwatt&nbsp;hours.&nbsp;Should&nbsp;be&nbsp;returned&nbsp;iff<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;<a href="#AndroidPlatform-CanMeasurePerApplicationPower">CanMeasurePerApplicationPower</a>()&nbsp;return&nbsp;true.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'application_energy_consumption_mwh':&nbsp;mwh,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;A&nbsp;platform-specific&nbsp;dictionary&nbsp;of&nbsp;additional&nbsp;details&nbsp;about&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;utilization&nbsp;of&nbsp;individual&nbsp;hardware&nbsp;components.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;component_utilization:&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>
-&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;<a href="telemetry.core.platform.html#Platform">Platform</a>-specific&nbsp;data&nbsp;not&nbsp;attributed&nbsp;to&nbsp;any&nbsp;particular&nbsp;hardware<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;component.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;platform_info:&nbsp;{<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Device-specific&nbsp;onboard&nbsp;temperature&nbsp;sensor.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'average_temperature_c':&nbsp;c,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>
-&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-&nbsp;<br>
-&nbsp;&nbsp;}</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt><dd><tt>Stops&nbsp;capturing&nbsp;video.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;telemetry.core.video.Video&nbsp;object.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatform-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt><dd><tt>Takes&nbsp;a&nbsp;screenshot&nbsp;of&nbsp;the&nbsp;platform&nbsp;and&nbsp;save&nbsp;to&nbsp;|file_path|.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;this&nbsp;method&nbsp;may&nbsp;not&nbsp;be&nbsp;supported&nbsp;on&nbsp;all&nbsp;platform,&nbsp;so&nbsp;check&nbsp;with<br>
-CanTakeScreenshot&nbsp;before&nbsp;calling&nbsp;this.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;file_path:&nbsp;Where&nbsp;to&nbsp;save&nbsp;the&nbsp;screenshot&nbsp;to.&nbsp;If&nbsp;the&nbsp;platform&nbsp;is&nbsp;remote,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;|file_path|&nbsp;is&nbsp;the&nbsp;path&nbsp;on&nbsp;the&nbsp;host&nbsp;platform.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.platform.html#Platform">telemetry.core.platform.Platform</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>http_server</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>local_servers</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;currently&nbsp;running&nbsp;local&nbsp;servers.</tt></dd>
-</dl>
-<dl><dt><strong>network_controller</strong></dt>
-<dd><tt>Control&nbsp;network&nbsp;settings&nbsp;and&nbsp;servers&nbsp;to&nbsp;simulate&nbsp;the&nbsp;Web.</tt></dd>
-</dl>
-<dl><dt><strong>tracing_controller</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.cros_interface.html b/catapult/telemetry/docs/pydoc/telemetry.core.cros_interface.html
deleted file mode 100644
index 1baf490..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.cros_interface.html
+++ /dev/null
@@ -1,355 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.cros_interface</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.cros_interface</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/cros_interface.py">telemetry/core/cros_interface.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;wrapper&nbsp;around&nbsp;ssh&nbsp;for&nbsp;common&nbsp;operations&nbsp;on&nbsp;a&nbsp;CrOS-based&nbsp;device</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="shutil.html">shutil</a><br>
-</td><td width="25%" valign=top><a href="stat.html">stat</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="tempfile.html">tempfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.cros_interface.html#CrOSInterface">CrOSInterface</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.cros_interface.html#LoginException">LoginException</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.cros_interface.html#DNSFailureException">DNSFailureException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.cros_interface.html#KeylessLoginRequiredException">KeylessLoginRequiredException</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOSInterface">class <strong>CrOSInterface</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="CrOSInterface-Chown"><strong>Chown</strong></a>(self, filename)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-CloseConnection"><strong>CloseConnection</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-CryptohomePath"><strong>CryptohomePath</strong></a>(self, user)</dt><dd><tt>Returns&nbsp;the&nbsp;cryptohome&nbsp;mount&nbsp;point&nbsp;for&nbsp;|user|.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-FileExistsOnDevice"><strong>FileExistsOnDevice</strong></a>(self, file_name)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-FilesystemMountedAt"><strong>FilesystemMountedAt</strong></a>(self, path)</dt><dd><tt>Returns&nbsp;the&nbsp;filesystem&nbsp;mounted&nbsp;at&nbsp;|path|</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-FormSSHCommandLine"><strong>FormSSHCommandLine</strong></a>(self, args, extra_ssh_args<font color="#909090">=None</font>)</dt><dd><tt>Constructs&nbsp;a&nbsp;subprocess-suitable&nbsp;command&nbsp;line&nbsp;for&nbsp;`ssh'.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-GetChromePid"><strong>GetChromePid</strong></a>(self)</dt><dd><tt>Returns&nbsp;pid&nbsp;of&nbsp;main&nbsp;chrome&nbsp;browser&nbsp;process.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-GetChromeProcess"><strong>GetChromeProcess</strong></a>(self)</dt><dd><tt>Locates&nbsp;the&nbsp;the&nbsp;main&nbsp;chrome&nbsp;browser&nbsp;process.<br>
-&nbsp;<br>
-Chrome&nbsp;on&nbsp;cros&nbsp;is&nbsp;usually&nbsp;in&nbsp;/opt/google/chrome,&nbsp;but&nbsp;could&nbsp;be&nbsp;in<br>
-/usr/local/&nbsp;for&nbsp;developer&nbsp;workflows&nbsp;-&nbsp;debug&nbsp;chrome&nbsp;is&nbsp;too&nbsp;large&nbsp;to&nbsp;fit&nbsp;on<br>
-rootfs.<br>
-&nbsp;<br>
-Chrome&nbsp;spawns&nbsp;multiple&nbsp;processes&nbsp;for&nbsp;renderers.&nbsp;pids&nbsp;wrap&nbsp;around&nbsp;after&nbsp;they<br>
-are&nbsp;exhausted&nbsp;so&nbsp;looking&nbsp;for&nbsp;the&nbsp;smallest&nbsp;pid&nbsp;is&nbsp;not&nbsp;always&nbsp;correct.&nbsp;We<br>
-locate&nbsp;the&nbsp;session_manager's&nbsp;pid,&nbsp;and&nbsp;look&nbsp;for&nbsp;the&nbsp;chrome&nbsp;process&nbsp;that's&nbsp;an<br>
-immediate&nbsp;child.&nbsp;This&nbsp;is&nbsp;the&nbsp;main&nbsp;browser&nbsp;process.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-GetFile"><strong>GetFile</strong></a>(self, filename, destfile<font color="#909090">=None</font>)</dt><dd><tt>Copies&nbsp;a&nbsp;local&nbsp;file&nbsp;|filename|&nbsp;to&nbsp;|destfile|&nbsp;on&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;filename:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;local&nbsp;source&nbsp;file.<br>
-&nbsp;&nbsp;destfile:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;file&nbsp;to&nbsp;copy&nbsp;to,&nbsp;and&nbsp;if&nbsp;it&nbsp;is&nbsp;not&nbsp;specified<br>
-&nbsp;&nbsp;&nbsp;&nbsp;then&nbsp;it&nbsp;is&nbsp;the&nbsp;basename&nbsp;of&nbsp;the&nbsp;source&nbsp;file.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-GetFileContents"><strong>GetFileContents</strong></a>(self, filename)</dt><dd><tt>Get&nbsp;the&nbsp;contents&nbsp;of&nbsp;a&nbsp;file&nbsp;on&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;filename:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;file&nbsp;on&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;string&nbsp;containing&nbsp;the&nbsp;contents&nbsp;of&nbsp;the&nbsp;file.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-GetRemotePort"><strong>GetRemotePort</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-IsCryptohomeMounted"><strong>IsCryptohomeMounted</strong></a>(self, username, is_guest)</dt><dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;|user|'s&nbsp;cryptohome&nbsp;is&nbsp;mounted.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-IsHTTPServerRunningOnPort"><strong>IsHTTPServerRunningOnPort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-IsServiceRunning"><strong>IsServiceRunning</strong></a>(self, service_name)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-KillAllMatching"><strong>KillAllMatching</strong></a>(self, predicate)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-ListProcesses"><strong>ListProcesses</strong></a>(self)</dt><dd><tt>Returns&nbsp;(pid,&nbsp;cmd,&nbsp;ppid,&nbsp;state)&nbsp;of&nbsp;all&nbsp;processes&nbsp;on&nbsp;the&nbsp;device.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-PushContents"><strong>PushContents</strong></a>(self, text, remote_filename)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-PushFile"><strong>PushFile</strong></a>(self, filename, remote_filename)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-RestartUI"><strong>RestartUI</strong></a>(self, clear_enterprise_policy)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-RmRF"><strong>RmRF</strong></a>(self, filename)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-RunCmdOnDevice"><strong>RunCmdOnDevice</strong></a>(self, args, cwd<font color="#909090">=None</font>, quiet<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-TakeScreenShot"><strong>TakeScreenShot</strong></a>(self, screenshot_prefix)</dt><dd><tt>Takes&nbsp;a&nbsp;screenshot,&nbsp;useful&nbsp;for&nbsp;debugging&nbsp;failures.</tt></dd></dl>
-
-<dl><dt><a name="CrOSInterface-TryLogin"><strong>TryLogin</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<dl><dt><a name="CrOSInterface-__init__"><strong>__init__</strong></a>(self, hostname<font color="#909090">=None</font>, ssh_port<font color="#909090">=None</font>, ssh_identity<font color="#909090">=None</font>)</dt><dd><tt>#&nbsp;pylint:&nbsp;disable=R0923</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>hostname</strong></dt>
-</dl>
-<dl><dt><strong>local</strong></dt>
-</dl>
-<dl><dt><strong>ssh_port</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DNSFailureException">class <strong>DNSFailureException</strong></a>(<a href="telemetry.core.cros_interface.html#LoginException">LoginException</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.cros_interface.html#DNSFailureException">DNSFailureException</a></dd>
-<dd><a href="telemetry.core.cros_interface.html#LoginException">LoginException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.core.cros_interface.html#LoginException">LoginException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="DNSFailureException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DNSFailureException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DNSFailureException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DNSFailureException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DNSFailureException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#DNSFailureException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="DNSFailureException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="KeylessLoginRequiredException">class <strong>KeylessLoginRequiredException</strong></a>(<a href="telemetry.core.cros_interface.html#LoginException">LoginException</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.cros_interface.html#KeylessLoginRequiredException">KeylessLoginRequiredException</a></dd>
-<dd><a href="telemetry.core.cros_interface.html#LoginException">LoginException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.core.cros_interface.html#LoginException">LoginException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="KeylessLoginRequiredException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#KeylessLoginRequiredException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="KeylessLoginRequiredException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#KeylessLoginRequiredException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="KeylessLoginRequiredException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LoginException">class <strong>LoginException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.cros_interface.html#LoginException">LoginException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="LoginException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#LoginException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="LoginException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="LoginException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="LoginException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetAllCmdOutput"><strong>GetAllCmdOutput</strong></a>(args, cwd<font color="#909090">=None</font>, quiet<font color="#909090">=False</font>)</dt><dd><tt>Open&nbsp;a&nbsp;subprocess&nbsp;to&nbsp;execute&nbsp;a&nbsp;program&nbsp;and&nbsp;returns&nbsp;its&nbsp;output.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;args:&nbsp;A&nbsp;string&nbsp;or&nbsp;a&nbsp;sequence&nbsp;of&nbsp;program&nbsp;arguments.&nbsp;The&nbsp;program&nbsp;to&nbsp;execute&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;string&nbsp;or&nbsp;the&nbsp;first&nbsp;item&nbsp;in&nbsp;the&nbsp;args&nbsp;sequence.<br>
-&nbsp;&nbsp;cwd:&nbsp;If&nbsp;not&nbsp;None,&nbsp;the&nbsp;subprocess's&nbsp;current&nbsp;directory&nbsp;will&nbsp;be&nbsp;changed&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;|cwd|&nbsp;before&nbsp;it's&nbsp;executed.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;Captures&nbsp;and&nbsp;returns&nbsp;the&nbsp;command's&nbsp;stdout.<br>
-&nbsp;&nbsp;Prints&nbsp;the&nbsp;command's&nbsp;stderr&nbsp;to&nbsp;logger&nbsp;(which&nbsp;defaults&nbsp;to&nbsp;stdout).</tt></dd></dl>
- <dl><dt><a name="-HasSSH"><strong>HasSSH</strong></a>()</dt></dl>
- <dl><dt><a name="-RunCmd"><strong>RunCmd</strong></a>(args, cwd<font color="#909090">=None</font>, quiet<font color="#909090">=False</font>)</dt><dd><tt>Opens&nbsp;a&nbsp;subprocess&nbsp;to&nbsp;execute&nbsp;a&nbsp;program&nbsp;and&nbsp;returns&nbsp;its&nbsp;return&nbsp;value.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;args:&nbsp;A&nbsp;string&nbsp;or&nbsp;a&nbsp;sequence&nbsp;of&nbsp;program&nbsp;arguments.&nbsp;The&nbsp;program&nbsp;to&nbsp;execute&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;string&nbsp;or&nbsp;the&nbsp;first&nbsp;item&nbsp;in&nbsp;the&nbsp;args&nbsp;sequence.<br>
-&nbsp;&nbsp;cwd:&nbsp;If&nbsp;not&nbsp;None,&nbsp;the&nbsp;subprocess's&nbsp;current&nbsp;directory&nbsp;will&nbsp;be&nbsp;changed&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;|cwd|&nbsp;before&nbsp;it's&nbsp;executed.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;Return&nbsp;code&nbsp;from&nbsp;the&nbsp;command&nbsp;execution.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.discover.html b/catapult/telemetry/docs/pydoc/telemetry.core.discover.html
deleted file mode 100644
index 5912099..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.discover.html
+++ /dev/null
@@ -1,75 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.discover</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.discover</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/discover.py">telemetry/core/discover.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.camel_case.html">telemetry.internal.util.camel_case</a><br>
-<a href="telemetry.internal.util.classes.html">telemetry.internal.util.classes</a><br>
-</td><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="fnmatch.html">fnmatch</a><br>
-</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-DiscoverClasses"><strong>DiscoverClasses</strong></a>(*args, **kwargs)</dt><dd><tt>Discover&nbsp;all&nbsp;classes&nbsp;in&nbsp;|start_dir|&nbsp;which&nbsp;subclass&nbsp;|base_class|.<br>
-&nbsp;<br>
-Base&nbsp;classes&nbsp;that&nbsp;contain&nbsp;subclasses&nbsp;are&nbsp;ignored&nbsp;by&nbsp;default.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;start_dir:&nbsp;The&nbsp;directory&nbsp;to&nbsp;recursively&nbsp;search.<br>
-&nbsp;&nbsp;top_level_dir:&nbsp;The&nbsp;top&nbsp;level&nbsp;of&nbsp;the&nbsp;package,&nbsp;for&nbsp;importing.<br>
-&nbsp;&nbsp;base_class:&nbsp;The&nbsp;base&nbsp;class&nbsp;to&nbsp;search&nbsp;for.<br>
-&nbsp;&nbsp;pattern:&nbsp;Unix&nbsp;shell-style&nbsp;pattern&nbsp;for&nbsp;filtering&nbsp;the&nbsp;filenames&nbsp;to&nbsp;import.<br>
-&nbsp;&nbsp;index_by_class_name:&nbsp;If&nbsp;True,&nbsp;use&nbsp;class&nbsp;name&nbsp;converted&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowercase_with_underscores&nbsp;instead&nbsp;of&nbsp;module&nbsp;name&nbsp;in&nbsp;return&nbsp;dict&nbsp;keys.<br>
-&nbsp;&nbsp;directly_constructable:&nbsp;If&nbsp;True,&nbsp;will&nbsp;only&nbsp;return&nbsp;classes&nbsp;that&nbsp;can&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;constructed&nbsp;without&nbsp;arguments<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;dict&nbsp;of&nbsp;{module_name:&nbsp;class}&nbsp;or&nbsp;{underscored_class_name:&nbsp;class}</tt></dd></dl>
- <dl><dt><a name="-DiscoverClassesInModule"><strong>DiscoverClassesInModule</strong></a>(*args, **kwargs)</dt><dd><tt>Discover&nbsp;all&nbsp;classes&nbsp;in&nbsp;|module|&nbsp;which&nbsp;subclass&nbsp;|base_class|.<br>
-&nbsp;<br>
-Base&nbsp;classes&nbsp;that&nbsp;contain&nbsp;subclasses&nbsp;are&nbsp;ignored&nbsp;by&nbsp;default.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;module:&nbsp;The&nbsp;module&nbsp;to&nbsp;search.<br>
-&nbsp;&nbsp;base_class:&nbsp;The&nbsp;base&nbsp;class&nbsp;to&nbsp;search&nbsp;for.<br>
-&nbsp;&nbsp;index_by_class_name:&nbsp;If&nbsp;True,&nbsp;use&nbsp;class&nbsp;name&nbsp;converted&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lowercase_with_underscores&nbsp;instead&nbsp;of&nbsp;module&nbsp;name&nbsp;in&nbsp;return&nbsp;dict&nbsp;keys.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;dict&nbsp;of&nbsp;{module_name:&nbsp;class}&nbsp;or&nbsp;{underscored_class_name:&nbsp;class}</tt></dd></dl>
- <dl><dt><a name="-DiscoverModules"><strong>DiscoverModules</strong></a>(*args, **kwargs)</dt><dd><tt>Discover&nbsp;all&nbsp;modules&nbsp;in&nbsp;|start_dir|&nbsp;which&nbsp;match&nbsp;|pattern|.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;start_dir:&nbsp;The&nbsp;directory&nbsp;to&nbsp;recursively&nbsp;search.<br>
-&nbsp;&nbsp;top_level_dir:&nbsp;The&nbsp;top&nbsp;level&nbsp;of&nbsp;the&nbsp;package,&nbsp;for&nbsp;importing.<br>
-&nbsp;&nbsp;pattern:&nbsp;Unix&nbsp;shell-style&nbsp;pattern&nbsp;for&nbsp;filtering&nbsp;the&nbsp;filenames&nbsp;to&nbsp;import.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;list&nbsp;of&nbsp;modules.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.exceptions.html b/catapult/telemetry/docs/pydoc/telemetry.core.exceptions.html
deleted file mode 100644
index 744db81..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.exceptions.html
+++ /dev/null
@@ -1,1241 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.exceptions</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.exceptions</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/exceptions.py">telemetry/core/exceptions.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#Error">Error</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#AndroidDeviceParsingError">AndroidDeviceParsingError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#BrowserGoneException">BrowserGoneException</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#BrowserConnectionGoneException">BrowserConnectionGoneException</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#DevtoolsTargetCrashException">DevtoolsTargetCrashException</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#EvaluateException">EvaluateException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#InitializationError">InitializationError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#IntentionalException">IntentionalException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#LoginException">LoginException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#PackageDetectionError">PackageDetectionError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#PathMissingError">PathMissingError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#PlatformError">PlatformError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#ProcessGoneException">ProcessGoneException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#ProfilingException">ProfilingException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#TimeoutException">TimeoutException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#UnknownPackageError">UnknownPackageError</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidDeviceParsingError">class <strong>AndroidDeviceParsingError</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;error&nbsp;when&nbsp;parsing&nbsp;output&nbsp;from&nbsp;an&nbsp;android&nbsp;device<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#AndroidDeviceParsingError">AndroidDeviceParsingError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="AndroidDeviceParsingError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#AndroidDeviceParsingError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="AndroidDeviceParsingError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#AndroidDeviceParsingError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#AndroidDeviceParsingError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#AndroidDeviceParsingError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#AndroidDeviceParsingError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#AndroidDeviceParsingError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#AndroidDeviceParsingError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="AndroidDeviceParsingError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AppCrashException">class <strong>AppCrashException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AppCrashException-__init__"><strong>__init__</strong></a>(self, app<font color="#909090">=None</font>, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="AppCrashException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="AppCrashException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#AppCrashException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="AppCrashException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#AppCrashException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="AppCrashException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#AppCrashException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="AppCrashException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#AppCrashException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="AppCrashException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#AppCrashException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="AppCrashException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="AppCrashException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#AppCrashException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="AppCrashException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#AppCrashException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="AppCrashException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="AppCrashException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserConnectionGoneException">class <strong>BrowserConnectionGoneException</strong></a>(<a href="telemetry.core.exceptions.html#BrowserGoneException">BrowserGoneException</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;browser&nbsp;that&nbsp;still&nbsp;exists&nbsp;but&nbsp;cannot&nbsp;be&nbsp;reached.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#BrowserConnectionGoneException">BrowserConnectionGoneException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#BrowserGoneException">BrowserGoneException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="BrowserConnectionGoneException-__init__"><strong>__init__</strong></a>(self, app, msg<font color="#909090">='Browser exists but the connection is gone'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a>:<br>
-<dl><dt><a name="BrowserConnectionGoneException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="BrowserConnectionGoneException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#BrowserConnectionGoneException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="BrowserConnectionGoneException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserConnectionGoneException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserConnectionGoneException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserConnectionGoneException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserConnectionGoneException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserConnectionGoneException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserConnectionGoneException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserConnectionGoneException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserGoneException">class <strong>BrowserGoneException</strong></a>(<a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;crash&nbsp;of&nbsp;the&nbsp;entire&nbsp;browser.<br>
-&nbsp;<br>
-In&nbsp;this&nbsp;state,&nbsp;all&nbsp;bets&nbsp;are&nbsp;pretty&nbsp;much&nbsp;off.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#BrowserGoneException">BrowserGoneException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="BrowserGoneException-__init__"><strong>__init__</strong></a>(self, app, msg<font color="#909090">='Browser crashed'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a>:<br>
-<dl><dt><a name="BrowserGoneException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="BrowserGoneException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#BrowserGoneException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="BrowserGoneException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserGoneException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserGoneException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserGoneException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserGoneException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserGoneException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="BrowserGoneException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserGoneException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="BrowserGoneException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserGoneException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserGoneException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="BrowserGoneException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserGoneException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="BrowserGoneException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserGoneException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DevtoolsTargetCrashException">class <strong>DevtoolsTargetCrashException</strong></a>(<a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;crash&nbsp;of&nbsp;the&nbsp;current&nbsp;devtools&nbsp;target&nbsp;but&nbsp;not&nbsp;the&nbsp;overall&nbsp;app.<br>
-&nbsp;<br>
-This&nbsp;can&nbsp;be&nbsp;a&nbsp;tab&nbsp;or&nbsp;a&nbsp;WebView.&nbsp;In&nbsp;this&nbsp;state,&nbsp;the&nbsp;tab/WebView&nbsp;is<br>
-gone,&nbsp;but&nbsp;the&nbsp;underlying&nbsp;browser&nbsp;is&nbsp;still&nbsp;alive.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#DevtoolsTargetCrashException">DevtoolsTargetCrashException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DevtoolsTargetCrashException-__init__"><strong>__init__</strong></a>(self, app, msg<font color="#909090">='Devtools target crashed'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#AppCrashException">AppCrashException</a>:<br>
-<dl><dt><a name="DevtoolsTargetCrashException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="DevtoolsTargetCrashException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DevtoolsTargetCrashException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DevtoolsTargetCrashException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevtoolsTargetCrashException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DevtoolsTargetCrashException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DevtoolsTargetCrashException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DevtoolsTargetCrashException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevtoolsTargetCrashException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevtoolsTargetCrashException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DevtoolsTargetCrashException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Error">class <strong>Error</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Base&nbsp;class&nbsp;for&nbsp;Telemetry&nbsp;exceptions.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Error-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="Error-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="Error-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Error-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="Error-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Error-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Error-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="Error-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="Error-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="Error-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="Error-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="Error-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="Error-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="EvaluateException">class <strong>EvaluateException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#EvaluateException">EvaluateException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="EvaluateException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="EvaluateException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#EvaluateException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="EvaluateException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#EvaluateException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#EvaluateException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#EvaluateException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#EvaluateException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="EvaluateException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#EvaluateException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#EvaluateException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="EvaluateException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="EvaluateException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InitializationError">class <strong>InitializationError</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#InitializationError">InitializationError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="InitializationError-__init__"><strong>__init__</strong></a>(self, string)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="InitializationError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#InitializationError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="InitializationError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InitializationError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#InitializationError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#InitializationError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#InitializationError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InitializationError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#InitializationError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InitializationError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="InitializationError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InitializationError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IntentionalException">class <strong>IntentionalException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represent&nbsp;an&nbsp;exception&nbsp;raised&nbsp;by&nbsp;a&nbsp;unittest&nbsp;which&nbsp;is&nbsp;not&nbsp;printed.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#IntentionalException">IntentionalException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="IntentionalException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="IntentionalException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#IntentionalException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="IntentionalException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#IntentionalException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#IntentionalException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#IntentionalException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#IntentionalException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="IntentionalException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#IntentionalException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#IntentionalException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="IntentionalException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="IntentionalException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LoginException">class <strong>LoginException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#LoginException">LoginException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="LoginException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="LoginException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#LoginException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="LoginException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="LoginException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#LoginException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="LoginException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="LoginException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PackageDetectionError">class <strong>PackageDetectionError</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;error&nbsp;when&nbsp;parsing&nbsp;an&nbsp;Android&nbsp;APK's&nbsp;package.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#PackageDetectionError">PackageDetectionError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="PackageDetectionError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="PackageDetectionError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#PackageDetectionError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="PackageDetectionError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PackageDetectionError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PackageDetectionError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PackageDetectionError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PackageDetectionError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PackageDetectionError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#PackageDetectionError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PackageDetectionError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PackageDetectionError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PackageDetectionError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PathMissingError">class <strong>PathMissingError</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;exception&nbsp;thrown&nbsp;when&nbsp;an&nbsp;expected&nbsp;path&nbsp;doesn't&nbsp;exist.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#PathMissingError">PathMissingError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="PathMissingError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="PathMissingError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#PathMissingError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="PathMissingError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PathMissingError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PathMissingError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PathMissingError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PathMissingError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PathMissingError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#PathMissingError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PathMissingError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PathMissingError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PathMissingError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PlatformError">class <strong>PlatformError</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;exception&nbsp;thrown&nbsp;when&nbsp;constructing&nbsp;platform.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#PlatformError">PlatformError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="PlatformError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="PlatformError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#PlatformError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="PlatformError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PlatformError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PlatformError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PlatformError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PlatformError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PlatformError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#PlatformError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PlatformError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PlatformError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PlatformError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProcessGoneException">class <strong>ProcessGoneException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;process&nbsp;that&nbsp;no&nbsp;longer&nbsp;exists&nbsp;for&nbsp;an&nbsp;unknown&nbsp;reason.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#ProcessGoneException">ProcessGoneException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="ProcessGoneException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="ProcessGoneException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ProcessGoneException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ProcessGoneException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ProcessGoneException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ProcessGoneException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ProcessGoneException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ProcessGoneException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ProcessGoneException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ProcessGoneException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ProcessGoneException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ProcessGoneException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ProcessGoneException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProfilingException">class <strong>ProfilingException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#ProfilingException">ProfilingException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="ProfilingException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="ProfilingException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ProfilingException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ProfilingException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ProfilingException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ProfilingException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ProfilingException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ProfilingException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ProfilingException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ProfilingException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ProfilingException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ProfilingException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ProfilingException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimeoutException">class <strong>TimeoutException</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;operation&nbsp;failed&nbsp;to&nbsp;complete&nbsp;because&nbsp;of&nbsp;a&nbsp;timeout.<br>
-&nbsp;<br>
-It&nbsp;is&nbsp;possible&nbsp;that&nbsp;waiting&nbsp;for&nbsp;a&nbsp;longer&nbsp;period&nbsp;of&nbsp;time&nbsp;would&nbsp;result&nbsp;in&nbsp;a<br>
-successful&nbsp;operation.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#TimeoutException">TimeoutException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="TimeoutException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="TimeoutException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TimeoutException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TimeoutException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TimeoutException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TimeoutException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TimeoutException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TimeoutException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TimeoutException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TimeoutException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TimeoutException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TimeoutException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TimeoutException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="UnknownPackageError">class <strong>UnknownPackageError</strong></a>(<a href="telemetry.core.exceptions.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;exception&nbsp;when&nbsp;encountering&nbsp;an&nbsp;unsupported&nbsp;Android&nbsp;APK.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.exceptions.html#UnknownPackageError">UnknownPackageError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><a name="UnknownPackageError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="UnknownPackageError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#UnknownPackageError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="UnknownPackageError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#UnknownPackageError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#UnknownPackageError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#UnknownPackageError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#UnknownPackageError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="UnknownPackageError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#UnknownPackageError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#UnknownPackageError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="UnknownPackageError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="UnknownPackageError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.html b/catapult/telemetry/docs/pydoc/telemetry.core.html
deleted file mode 100644
index d941689..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.html
+++ /dev/null
@@ -1,44 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.core</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.core</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/__init__.py">telemetry/core/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.android_action_runner.html">android_action_runner</a><br>
-<a href="telemetry.core.android_platform.html">android_platform</a><br>
-<a href="telemetry.core.cros_interface.html">cros_interface</a><br>
-<a href="telemetry.core.cros_interface_unittest.html">cros_interface_unittest</a><br>
-<a href="telemetry.core.discover.html">discover</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.discover_unittest.html">discover_unittest</a><br>
-<a href="telemetry.core.exceptions.html">exceptions</a><br>
-<a href="telemetry.core.local_server.html">local_server</a><br>
-<a href="telemetry.core.local_server_unittest.html">local_server_unittest</a><br>
-<a href="telemetry.core.memory_cache_http_server.html">memory_cache_http_server</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.memory_cache_http_server_unittest.html">memory_cache_http_server_unittest</a><br>
-<a href="telemetry.core.network_controller.html">network_controller</a><br>
-<a href="telemetry.core.os_version.html">os_version</a><br>
-<a href="telemetry.core.platform.html">platform</a><br>
-<a href="telemetry.core.platform_unittest.html">platform_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.profiling_controller.html">profiling_controller</a><br>
-<a href="telemetry.core.tracing_controller.html">tracing_controller</a><br>
-<a href="telemetry.core.tracing_controller_unittest.html">tracing_controller_unittest</a><br>
-<a href="telemetry.core.util.html">util</a><br>
-<a href="telemetry.core.util_unittest.html">util_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.local_server.html b/catapult/telemetry/docs/pydoc/telemetry.core.local_server.html
deleted file mode 100644
index 6f9cd22..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.local_server.html
+++ /dev/null
@@ -1,241 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.local_server</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.local_server</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/local_server.py">telemetry/core/local_server.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.local_server.html#LocalServer">LocalServer</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.local_server.html#LocalServerBackend">LocalServerBackend</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.local_server.html#LocalServerController">LocalServerController</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#tuple">__builtin__.tuple</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.local_server.html#NamedPort">NamedPort</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LocalServer">class <strong>LocalServer</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="LocalServer-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LocalServer-GetBackendStartupArgs"><strong>GetBackendStartupArgs</strong></a>(self)</dt><dd><tt>Returns&nbsp;whatever&nbsp;arguments&nbsp;are&nbsp;required&nbsp;to&nbsp;start&nbsp;up&nbsp;the&nbsp;backend</tt></dd></dl>
-
-<dl><dt><a name="LocalServer-Start"><strong>Start</strong></a>(self, local_server_controller)</dt></dl>
-
-<dl><dt><a name="LocalServer-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LocalServer-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LocalServer-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<dl><dt><a name="LocalServer-__init__"><strong>__init__</strong></a>(self, server_backend_class)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_running</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LocalServerBackend">class <strong>LocalServerBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="LocalServerBackend-ServeForever"><strong>ServeForever</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LocalServerBackend-StartAndGetNamedPorts"><strong>StartAndGetNamedPorts</strong></a>(self, args)</dt><dd><tt>Starts&nbsp;the&nbsp;actual&nbsp;server&nbsp;and&nbsp;obtains&nbsp;any&nbsp;sockets&nbsp;on&nbsp;which&nbsp;it<br>
-should&nbsp;listen.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;<a href="#NamedPort">NamedPort</a>&nbsp;on&nbsp;which&nbsp;this&nbsp;backend&nbsp;is&nbsp;listening.</tt></dd></dl>
-
-<dl><dt><a name="LocalServerBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LocalServerController">class <strong>LocalServerController</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Manages&nbsp;the&nbsp;list&nbsp;of&nbsp;running&nbsp;servers<br>
-&nbsp;<br>
-This&nbsp;class&nbsp;manages&nbsp;the&nbsp;running&nbsp;servers,&nbsp;but&nbsp;also&nbsp;provides&nbsp;an&nbsp;isolation&nbsp;layer<br>
-to&nbsp;prevent&nbsp;<a href="#LocalServer">LocalServer</a>&nbsp;subclasses&nbsp;from&nbsp;accessing&nbsp;the&nbsp;browser&nbsp;backend&nbsp;directly.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="LocalServerController-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LocalServerController-CreateForwarder"><strong>CreateForwarder</strong></a>(self, port_pairs)</dt></dl>
-
-<dl><dt><a name="LocalServerController-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="LocalServerController-GetRunningServer"><strong>GetRunningServer</strong></a>(self, server_class, default_value)</dt></dl>
-
-<dl><dt><a name="LocalServerController-ServerDidClose"><strong>ServerDidClose</strong></a>(self, server)</dt></dl>
-
-<dl><dt><a name="LocalServerController-StartServer"><strong>StartServer</strong></a>(self, server)</dt></dl>
-
-<dl><dt><a name="LocalServerController-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>local_servers</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NamedPort">class <strong>NamedPort</strong></a>(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#NamedPort">NamedPort</a>(name,&nbsp;port)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.local_server.html#NamedPort">NamedPort</a></dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="NamedPort-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;<a href="__builtin__.html#tuple">tuple</a>.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#NamedPort">NamedPort</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="NamedPort-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#NamedPort">NamedPort</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="NamedPort-__new__"><strong>__new__</strong></a>(_cls, name, port)</dt><dd><tt>Create&nbsp;new&nbsp;instance&nbsp;of&nbsp;<a href="#NamedPort">NamedPort</a>(name,&nbsp;port)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd>
-</dl>
-<dl><dt><strong>name</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<dl><dt><strong>port</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>_fields</strong> = ('name', 'port')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="NamedPort-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#NamedPort-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#NamedPort-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#NamedPort-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="NamedPort-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#NamedPort-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.memory_cache_http_server.html b/catapult/telemetry/docs/pydoc/telemetry.core.memory_cache_http_server.html
deleted file mode 100644
index 1a50b5e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.memory_cache_http_server.html
+++ /dev/null
@@ -1,527 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.memory_cache_http_server</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.memory_cache_http_server</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/memory_cache_http_server.py">telemetry/core/memory_cache_http_server.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="BaseHTTPServer.html">BaseHTTPServer</a><br>
-<a href="SimpleHTTPServer.html">SimpleHTTPServer</a><br>
-<a href="SocketServer.html">SocketServer</a><br>
-</td><td width="25%" valign=top><a href="StringIO.html">StringIO</a><br>
-<a href="errno.html">errno</a><br>
-<a href="gzip.html">gzip</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.local_server.html">telemetry.core.local_server</a><br>
-<a href="mimetypes.html">mimetypes</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="socket.html">socket</a><br>
-<a href="sys.html">sys</a><br>
-<a href="urlparse.html">urlparse</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="SimpleHTTPServer.html#SimpleHTTPRequestHandler">SimpleHTTPServer.SimpleHTTPRequestHandler</a>(<a href="BaseHTTPServer.html#BaseHTTPRequestHandler">BaseHTTPServer.BaseHTTPRequestHandler</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.memory_cache_http_server.html#MemoryCacheHTTPRequestHandler">MemoryCacheHTTPRequestHandler</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#tuple">__builtin__.tuple</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.memory_cache_http_server.html#ByteRange">ByteRange</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.core.memory_cache_http_server.html#ResourceAndRange">ResourceAndRange</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.local_server.html#LocalServer">telemetry.core.local_server.LocalServer</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.memory_cache_http_server.html#MemoryCacheHTTPServer">MemoryCacheHTTPServer</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.local_server.html#LocalServerBackend">telemetry.core.local_server.LocalServerBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.memory_cache_http_server.html#MemoryCacheHTTPServerBackend">MemoryCacheHTTPServerBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ByteRange">class <strong>ByteRange</strong></a>(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#ByteRange">ByteRange</a>(from_byte,&nbsp;to_byte)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.memory_cache_http_server.html#ByteRange">ByteRange</a></dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ByteRange-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;<a href="__builtin__.html#tuple">tuple</a>.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#ByteRange">ByteRange</a>&nbsp;object&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="ByteRange-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#ByteRange">ByteRange</a>&nbsp;object&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="ByteRange-__new__"><strong>__new__</strong></a>(_cls, from_byte, to_byte)</dt><dd><tt>Create&nbsp;new&nbsp;instance&nbsp;of&nbsp;<a href="#ByteRange">ByteRange</a>(from_byte,&nbsp;to_byte)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd>
-</dl>
-<dl><dt><strong>from_byte</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<dl><dt><strong>to_byte</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>_fields</strong> = ('from_byte', 'to_byte')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="ByteRange-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#ByteRange-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#ByteRange-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#ByteRange-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ByteRange-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#ByteRange-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryCacheHTTPRequestHandler">class <strong>MemoryCacheHTTPRequestHandler</strong></a>(<a href="SimpleHTTPServer.html#SimpleHTTPRequestHandler">SimpleHTTPServer.SimpleHTTPRequestHandler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.memory_cache_http_server.html#MemoryCacheHTTPRequestHandler">MemoryCacheHTTPRequestHandler</a></dd>
-<dd><a href="SimpleHTTPServer.html#SimpleHTTPRequestHandler">SimpleHTTPServer.SimpleHTTPRequestHandler</a></dd>
-<dd><a href="BaseHTTPServer.html#BaseHTTPRequestHandler">BaseHTTPServer.BaseHTTPRequestHandler</a></dd>
-<dd><a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a></dd>
-<dd><a href="SocketServer.html#BaseRequestHandler">SocketServer.BaseRequestHandler</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-GetByteRange"><strong>GetByteRange</strong></a>(self, total_num_of_bytes)</dt><dd><tt>Parse&nbsp;the&nbsp;header&nbsp;and&nbsp;get&nbsp;the&nbsp;range&nbsp;values&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;total_num_of_bytes:&nbsp;Total&nbsp;#&nbsp;of&nbsp;bytes&nbsp;in&nbsp;requested&nbsp;resource,<br>
-&nbsp;&nbsp;used&nbsp;to&nbsp;calculate&nbsp;upper&nbsp;range&nbsp;limit.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;<a href="#ByteRange">ByteRange</a>&nbsp;namedtuple&nbsp;object&nbsp;with&nbsp;the&nbsp;requested&nbsp;byte-range&nbsp;values.<br>
-&nbsp;&nbsp;If&nbsp;no&nbsp;Range&nbsp;is&nbsp;explicitly&nbsp;requested&nbsp;or&nbsp;there&nbsp;is&nbsp;a&nbsp;failure&nbsp;parsing,<br>
-&nbsp;&nbsp;return&nbsp;None.<br>
-&nbsp;&nbsp;If&nbsp;range&nbsp;specified&nbsp;is&nbsp;in&nbsp;the&nbsp;format&nbsp;"N-",&nbsp;return&nbsp;N-END.&nbsp;Refer&nbsp;to<br>
-&nbsp;&nbsp;<a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html</a>&nbsp;for&nbsp;details.<br>
-&nbsp;&nbsp;If&nbsp;upper&nbsp;range&nbsp;limit&nbsp;is&nbsp;greater&nbsp;than&nbsp;total&nbsp;#&nbsp;of&nbsp;bytes,&nbsp;return&nbsp;upper&nbsp;index.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-SendHead"><strong>SendHead</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-do_GET"><strong>do_GET</strong></a>(self)</dt><dd><tt>Serve&nbsp;a&nbsp;GET&nbsp;request.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-do_HEAD"><strong>do_HEAD</strong></a>(self)</dt><dd><tt>Serve&nbsp;a&nbsp;HEAD&nbsp;request.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-handle"><strong>handle</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-log_error"><strong>log_error</strong></a>(self, fmt, *args)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-log_request"><strong>log_request</strong></a>(self, code<font color="#909090">='-'</font>, size<font color="#909090">='-'</font>)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>protocol_version</strong> = 'HTTP/1.1'</dl>
-
-<dl><dt><strong>wbufsize</strong> = -1</dl>
-
-<hr>
-Methods inherited from <a href="SimpleHTTPServer.html#SimpleHTTPRequestHandler">SimpleHTTPServer.SimpleHTTPRequestHandler</a>:<br>
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-copyfile"><strong>copyfile</strong></a>(self, source, outputfile)</dt><dd><tt>Copy&nbsp;all&nbsp;data&nbsp;between&nbsp;two&nbsp;file&nbsp;objects.<br>
-&nbsp;<br>
-The&nbsp;SOURCE&nbsp;argument&nbsp;is&nbsp;a&nbsp;file&nbsp;object&nbsp;open&nbsp;for&nbsp;reading<br>
-(or&nbsp;anything&nbsp;with&nbsp;a&nbsp;read()&nbsp;method)&nbsp;and&nbsp;the&nbsp;DESTINATION<br>
-argument&nbsp;is&nbsp;a&nbsp;file&nbsp;object&nbsp;open&nbsp;for&nbsp;writing&nbsp;(or<br>
-anything&nbsp;with&nbsp;a&nbsp;write()&nbsp;method).<br>
-&nbsp;<br>
-The&nbsp;only&nbsp;reason&nbsp;for&nbsp;overriding&nbsp;this&nbsp;would&nbsp;be&nbsp;to&nbsp;change<br>
-the&nbsp;block&nbsp;size&nbsp;or&nbsp;perhaps&nbsp;to&nbsp;replace&nbsp;newlines&nbsp;by&nbsp;CRLF<br>
---&nbsp;note&nbsp;however&nbsp;that&nbsp;this&nbsp;the&nbsp;default&nbsp;server&nbsp;uses&nbsp;this<br>
-to&nbsp;copy&nbsp;binary&nbsp;data&nbsp;as&nbsp;well.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-guess_type"><strong>guess_type</strong></a>(self, path)</dt><dd><tt>Guess&nbsp;the&nbsp;type&nbsp;of&nbsp;a&nbsp;file.<br>
-&nbsp;<br>
-Argument&nbsp;is&nbsp;a&nbsp;PATH&nbsp;(a&nbsp;filename).<br>
-&nbsp;<br>
-Return&nbsp;value&nbsp;is&nbsp;a&nbsp;string&nbsp;of&nbsp;the&nbsp;form&nbsp;type/subtype,<br>
-usable&nbsp;for&nbsp;a&nbsp;MIME&nbsp;Content-type&nbsp;header.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;looks&nbsp;the&nbsp;file's&nbsp;extension<br>
-up&nbsp;in&nbsp;the&nbsp;table&nbsp;self.<strong>extensions_map</strong>,&nbsp;using&nbsp;application/octet-stream<br>
-as&nbsp;a&nbsp;default;&nbsp;however&nbsp;it&nbsp;would&nbsp;be&nbsp;permissible&nbsp;(if<br>
-slow)&nbsp;to&nbsp;look&nbsp;inside&nbsp;the&nbsp;data&nbsp;to&nbsp;make&nbsp;a&nbsp;better&nbsp;guess.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-list_directory"><strong>list_directory</strong></a>(self, path)</dt><dd><tt>Helper&nbsp;to&nbsp;produce&nbsp;a&nbsp;directory&nbsp;listing&nbsp;(absent&nbsp;index.html).<br>
-&nbsp;<br>
-Return&nbsp;value&nbsp;is&nbsp;either&nbsp;a&nbsp;file&nbsp;object,&nbsp;or&nbsp;None&nbsp;(indicating&nbsp;an<br>
-error).&nbsp;&nbsp;In&nbsp;either&nbsp;case,&nbsp;the&nbsp;headers&nbsp;are&nbsp;sent,&nbsp;making&nbsp;the<br>
-interface&nbsp;the&nbsp;same&nbsp;as&nbsp;for&nbsp;<a href="#MemoryCacheHTTPRequestHandler-send_head">send_head</a>().</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-send_head"><strong>send_head</strong></a>(self)</dt><dd><tt>Common&nbsp;code&nbsp;for&nbsp;GET&nbsp;and&nbsp;HEAD&nbsp;commands.<br>
-&nbsp;<br>
-This&nbsp;sends&nbsp;the&nbsp;response&nbsp;code&nbsp;and&nbsp;MIME&nbsp;headers.<br>
-&nbsp;<br>
-Return&nbsp;value&nbsp;is&nbsp;either&nbsp;a&nbsp;file&nbsp;object&nbsp;(which&nbsp;has&nbsp;to&nbsp;be&nbsp;copied<br>
-to&nbsp;the&nbsp;outputfile&nbsp;by&nbsp;the&nbsp;caller&nbsp;unless&nbsp;the&nbsp;command&nbsp;was&nbsp;HEAD,<br>
-and&nbsp;must&nbsp;be&nbsp;closed&nbsp;by&nbsp;the&nbsp;caller&nbsp;under&nbsp;all&nbsp;circumstances),&nbsp;or<br>
-None,&nbsp;in&nbsp;which&nbsp;case&nbsp;the&nbsp;caller&nbsp;has&nbsp;nothing&nbsp;further&nbsp;to&nbsp;do.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-translate_path"><strong>translate_path</strong></a>(self, path)</dt><dd><tt>Translate&nbsp;a&nbsp;/-separated&nbsp;PATH&nbsp;to&nbsp;the&nbsp;local&nbsp;filename&nbsp;syntax.<br>
-&nbsp;<br>
-Components&nbsp;that&nbsp;mean&nbsp;special&nbsp;things&nbsp;to&nbsp;the&nbsp;local&nbsp;file&nbsp;system<br>
-(e.g.&nbsp;drive&nbsp;or&nbsp;directory&nbsp;names)&nbsp;are&nbsp;ignored.&nbsp;&nbsp;(XXX&nbsp;They&nbsp;should<br>
-probably&nbsp;be&nbsp;diagnosed.)</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="SimpleHTTPServer.html#SimpleHTTPRequestHandler">SimpleHTTPServer.SimpleHTTPRequestHandler</a>:<br>
-<dl><dt><strong>extensions_map</strong> = {'': 'application/octet-stream', '.%': 'application/x-trash', '.323': 'text/h323', '.3gp': 'video/3gpp', '.7z': 'application/x-7z-compressed', '.a': 'application/octet-stream', '.abw': 'application/x-abiword', '.ai': 'application/postscript', '.aif': 'audio/x-aiff', '.aifc': 'audio/x-aiff', ...}</dl>
-
-<dl><dt><strong>server_version</strong> = 'SimpleHTTP/0.6'</dl>
-
-<hr>
-Methods inherited from <a href="BaseHTTPServer.html#BaseHTTPRequestHandler">BaseHTTPServer.BaseHTTPRequestHandler</a>:<br>
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-address_string"><strong>address_string</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;client&nbsp;address&nbsp;formatted&nbsp;for&nbsp;logging.<br>
-&nbsp;<br>
-This&nbsp;version&nbsp;looks&nbsp;up&nbsp;the&nbsp;full&nbsp;hostname&nbsp;using&nbsp;gethostbyaddr(),<br>
-and&nbsp;tries&nbsp;to&nbsp;find&nbsp;a&nbsp;name&nbsp;that&nbsp;contains&nbsp;at&nbsp;least&nbsp;one&nbsp;dot.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-date_time_string"><strong>date_time_string</strong></a>(self, timestamp<font color="#909090">=None</font>)</dt><dd><tt>Return&nbsp;the&nbsp;current&nbsp;date&nbsp;and&nbsp;time&nbsp;formatted&nbsp;for&nbsp;a&nbsp;message&nbsp;header.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-end_headers"><strong>end_headers</strong></a>(self)</dt><dd><tt>Send&nbsp;the&nbsp;blank&nbsp;line&nbsp;ending&nbsp;the&nbsp;MIME&nbsp;headers.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-handle_one_request"><strong>handle_one_request</strong></a>(self)</dt><dd><tt>Handle&nbsp;a&nbsp;single&nbsp;HTTP&nbsp;request.<br>
-&nbsp;<br>
-You&nbsp;normally&nbsp;don't&nbsp;need&nbsp;to&nbsp;override&nbsp;this&nbsp;method;&nbsp;see&nbsp;the&nbsp;class<br>
-__doc__&nbsp;string&nbsp;for&nbsp;information&nbsp;on&nbsp;how&nbsp;to&nbsp;handle&nbsp;specific&nbsp;HTTP<br>
-commands&nbsp;such&nbsp;as&nbsp;GET&nbsp;and&nbsp;POST.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-log_date_time_string"><strong>log_date_time_string</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;current&nbsp;time&nbsp;formatted&nbsp;for&nbsp;logging.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-log_message"><strong>log_message</strong></a>(self, format, *args)</dt><dd><tt>Log&nbsp;an&nbsp;arbitrary&nbsp;message.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;used&nbsp;by&nbsp;all&nbsp;other&nbsp;logging&nbsp;functions.&nbsp;&nbsp;Override<br>
-it&nbsp;if&nbsp;you&nbsp;have&nbsp;specific&nbsp;logging&nbsp;wishes.<br>
-&nbsp;<br>
-The&nbsp;first&nbsp;argument,&nbsp;FORMAT,&nbsp;is&nbsp;a&nbsp;format&nbsp;string&nbsp;for&nbsp;the<br>
-message&nbsp;to&nbsp;be&nbsp;logged.&nbsp;&nbsp;If&nbsp;the&nbsp;format&nbsp;string&nbsp;contains<br>
-any&nbsp;%&nbsp;escapes&nbsp;requiring&nbsp;parameters,&nbsp;they&nbsp;should&nbsp;be<br>
-specified&nbsp;as&nbsp;subsequent&nbsp;arguments&nbsp;(it's&nbsp;just&nbsp;like<br>
-printf!).<br>
-&nbsp;<br>
-The&nbsp;client&nbsp;ip&nbsp;address&nbsp;and&nbsp;current&nbsp;date/time&nbsp;are&nbsp;prefixed&nbsp;to&nbsp;every<br>
-message.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-parse_request"><strong>parse_request</strong></a>(self)</dt><dd><tt>Parse&nbsp;a&nbsp;request&nbsp;(internal).<br>
-&nbsp;<br>
-The&nbsp;request&nbsp;should&nbsp;be&nbsp;stored&nbsp;in&nbsp;self.<strong>raw_requestline</strong>;&nbsp;the&nbsp;results<br>
-are&nbsp;in&nbsp;self.<strong>command</strong>,&nbsp;self.<strong>path</strong>,&nbsp;self.<strong>request_version</strong>&nbsp;and<br>
-self.<strong>headers</strong>.<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;for&nbsp;success,&nbsp;False&nbsp;for&nbsp;failure;&nbsp;on&nbsp;failure,&nbsp;an<br>
-error&nbsp;is&nbsp;sent&nbsp;back.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-send_error"><strong>send_error</strong></a>(self, code, message<font color="#909090">=None</font>)</dt><dd><tt>Send&nbsp;and&nbsp;log&nbsp;an&nbsp;error&nbsp;reply.<br>
-&nbsp;<br>
-Arguments&nbsp;are&nbsp;the&nbsp;error&nbsp;code,&nbsp;and&nbsp;a&nbsp;detailed&nbsp;message.<br>
-The&nbsp;detailed&nbsp;message&nbsp;defaults&nbsp;to&nbsp;the&nbsp;short&nbsp;entry&nbsp;matching&nbsp;the<br>
-response&nbsp;code.<br>
-&nbsp;<br>
-This&nbsp;sends&nbsp;an&nbsp;error&nbsp;response&nbsp;(so&nbsp;it&nbsp;must&nbsp;be&nbsp;called&nbsp;before&nbsp;any<br>
-output&nbsp;has&nbsp;been&nbsp;generated),&nbsp;logs&nbsp;the&nbsp;error,&nbsp;and&nbsp;finally&nbsp;sends<br>
-a&nbsp;piece&nbsp;of&nbsp;HTML&nbsp;explaining&nbsp;the&nbsp;error&nbsp;to&nbsp;the&nbsp;user.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-send_header"><strong>send_header</strong></a>(self, keyword, value)</dt><dd><tt>Send&nbsp;a&nbsp;MIME&nbsp;header.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-send_response"><strong>send_response</strong></a>(self, code, message<font color="#909090">=None</font>)</dt><dd><tt>Send&nbsp;the&nbsp;response&nbsp;header&nbsp;and&nbsp;log&nbsp;the&nbsp;response&nbsp;code.<br>
-&nbsp;<br>
-Also&nbsp;send&nbsp;two&nbsp;standard&nbsp;headers&nbsp;with&nbsp;the&nbsp;server&nbsp;software<br>
-version&nbsp;and&nbsp;the&nbsp;current&nbsp;date.</tt></dd></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-version_string"><strong>version_string</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;server&nbsp;software&nbsp;version&nbsp;string.</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="BaseHTTPServer.html#BaseHTTPRequestHandler">BaseHTTPServer.BaseHTTPRequestHandler</a>:<br>
-<dl><dt><strong>MessageClass</strong> = &lt;class mimetools.Message&gt;</dl>
-
-<dl><dt><strong>default_request_version</strong> = 'HTTP/0.9'</dl>
-
-<dl><dt><strong>error_content_type</strong> = 'text/html'</dl>
-
-<dl><dt><strong>error_message_format</strong> = '&lt;head&gt;<font color="#c040c0">\n</font>&lt;title&gt;Error response&lt;/title&gt;<font color="#c040c0">\n</font>&lt;/head&gt;<font color="#c040c0">\n</font>&lt;bo...ode explanation: %(code)s = %(explain)s.<font color="#c040c0">\n</font>&lt;/body&gt;<font color="#c040c0">\n</font>'</dl>
-
-<dl><dt><strong>monthname</strong> = [None, 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']</dl>
-
-<dl><dt><strong>responses</strong> = {100: ('Continue', 'Request received, please continue'), 101: ('Switching Protocols', 'Switching to new protocol; obey Upgrade header'), 200: ('OK', 'Request fulfilled, document follows'), 201: ('Created', 'Document created, URL follows'), 202: ('Accepted', 'Request accepted, processing continues off-line'), 203: ('Non-Authoritative Information', 'Request fulfilled from cache'), 204: ('No Content', 'Request fulfilled, nothing follows'), 205: ('Reset Content', 'Clear input form for further input.'), 206: ('Partial Content', 'Partial content follows.'), 300: ('Multiple Choices', 'Object has several resources -- see URI list'), ...}</dl>
-
-<dl><dt><strong>sys_version</strong> = 'Python/2.7.6'</dl>
-
-<dl><dt><strong>weekdayname</strong> = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']</dl>
-
-<hr>
-Methods inherited from <a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a>:<br>
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-finish"><strong>finish</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-setup"><strong>setup</strong></a>(self)</dt></dl>
-
-<hr>
-Data and other attributes inherited from <a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a>:<br>
-<dl><dt><strong>disable_nagle_algorithm</strong> = False</dl>
-
-<dl><dt><strong>rbufsize</strong> = -1</dl>
-
-<dl><dt><strong>timeout</strong> = None</dl>
-
-<hr>
-Methods inherited from <a href="SocketServer.html#BaseRequestHandler">SocketServer.BaseRequestHandler</a>:<br>
-<dl><dt><a name="MemoryCacheHTTPRequestHandler-__init__"><strong>__init__</strong></a>(self, request, client_address, server)</dt></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryCacheHTTPServer">class <strong>MemoryCacheHTTPServer</strong></a>(<a href="telemetry.core.local_server.html#LocalServer">telemetry.core.local_server.LocalServer</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.memory_cache_http_server.html#MemoryCacheHTTPServer">MemoryCacheHTTPServer</a></dd>
-<dd><a href="telemetry.core.local_server.html#LocalServer">telemetry.core.local_server.LocalServer</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MemoryCacheHTTPServer-GetBackendStartupArgs"><strong>GetBackendStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServer-UrlOf"><strong>UrlOf</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServer-__init__"><strong>__init__</strong></a>(self, paths)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>paths</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.local_server.html#LocalServer">telemetry.core.local_server.LocalServer</a>:<br>
-<dl><dt><a name="MemoryCacheHTTPServer-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServer-Start"><strong>Start</strong></a>(self, local_server_controller)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServer-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServer-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServer-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.local_server.html#LocalServer">telemetry.core.local_server.LocalServer</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_running</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryCacheHTTPServerBackend">class <strong>MemoryCacheHTTPServerBackend</strong></a>(<a href="telemetry.core.local_server.html#LocalServerBackend">telemetry.core.local_server.LocalServerBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.memory_cache_http_server.html#MemoryCacheHTTPServerBackend">MemoryCacheHTTPServerBackend</a></dd>
-<dd><a href="telemetry.core.local_server.html#LocalServerBackend">telemetry.core.local_server.LocalServerBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MemoryCacheHTTPServerBackend-ServeForever"><strong>ServeForever</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServerBackend-StartAndGetNamedPorts"><strong>StartAndGetNamedPorts</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="MemoryCacheHTTPServerBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.local_server.html#LocalServerBackend">telemetry.core.local_server.LocalServerBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ResourceAndRange">class <strong>ResourceAndRange</strong></a>(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#ResourceAndRange">ResourceAndRange</a>(resource,&nbsp;byte_range)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.memory_cache_http_server.html#ResourceAndRange">ResourceAndRange</a></dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ResourceAndRange-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;<a href="__builtin__.html#tuple">tuple</a>.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#ResourceAndRange">ResourceAndRange</a>&nbsp;object&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="ResourceAndRange-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#ResourceAndRange">ResourceAndRange</a>&nbsp;object&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="ResourceAndRange-__new__"><strong>__new__</strong></a>(_cls, resource, byte_range)</dt><dd><tt>Create&nbsp;new&nbsp;instance&nbsp;of&nbsp;<a href="#ResourceAndRange">ResourceAndRange</a>(resource,&nbsp;byte_range)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd>
-</dl>
-<dl><dt><strong>byte_range</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<dl><dt><strong>resource</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>_fields</strong> = ('resource', 'byte_range')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="ResourceAndRange-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#ResourceAndRange-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#ResourceAndRange-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#ResourceAndRange-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ResourceAndRange-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#ResourceAndRange-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.network_controller.html b/catapult/telemetry/docs/pydoc/telemetry.core.network_controller.html
deleted file mode 100644
index 01e3e24..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.network_controller.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.network_controller</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.network_controller</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/network_controller.py">telemetry/core/network_controller.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.network_controller.html#NetworkController">NetworkController</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NetworkController">class <strong>NetworkController</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Control&nbsp;network&nbsp;settings&nbsp;and&nbsp;servers&nbsp;to&nbsp;simulate&nbsp;the&nbsp;Web.<br>
-&nbsp;<br>
-Network&nbsp;changes&nbsp;include&nbsp;forwarding&nbsp;device&nbsp;ports&nbsp;to&nbsp;host&nbsp;platform&nbsp;ports.<br>
-Web&nbsp;Page&nbsp;Replay&nbsp;is&nbsp;used&nbsp;to&nbsp;record&nbsp;and&nbsp;replay&nbsp;HTTP/HTTPS&nbsp;responses.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="NetworkController-SetReplayArgs"><strong>SetReplayArgs</strong></a>(self, archive_path, wpr_mode, netsim, extra_wpr_args, make_javascript_deterministic<font color="#909090">=False</font>)</dt><dd><tt>Save&nbsp;the&nbsp;arguments&nbsp;needed&nbsp;for&nbsp;replay.</tt></dd></dl>
-
-<dl><dt><a name="NetworkController-UpdateReplayForExistingBrowser"><strong>UpdateReplayForExistingBrowser</strong></a>(self)</dt><dd><tt>Restart&nbsp;replay&nbsp;if&nbsp;needed&nbsp;for&nbsp;an&nbsp;existing&nbsp;browser.<br>
-&nbsp;<br>
-TODO(slamm):&nbsp;Drop&nbsp;this&nbsp;method&nbsp;when&nbsp;the&nbsp;browser_backend&nbsp;dependencies&nbsp;are<br>
-moved&nbsp;to&nbsp;the&nbsp;platform.&nbsp;https://crbug.com/423962</tt></dd></dl>
-
-<dl><dt><a name="NetworkController-__init__"><strong>__init__</strong></a>(self, network_controller_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.os_version.html b/catapult/telemetry/docs/pydoc/telemetry.core.os_version.html
deleted file mode 100644
index bb21b3f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.os_version.html
+++ /dev/null
@@ -1,350 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.os_version</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.os_version</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/os_version.py">telemetry/core/os_version.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#str">__builtin__.str</a>(<a href="__builtin__.html#basestring">__builtin__.basestring</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.os_version.html#OSVersion">OSVersion</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="OSVersion">class <strong>OSVersion</strong></a>(<a href="__builtin__.html#str">__builtin__.str</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;pylint:&nbsp;disable=W0212<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.core.os_version.html#OSVersion">OSVersion</a></dd>
-<dd><a href="__builtin__.html#str">__builtin__.str</a></dd>
-<dd><a href="__builtin__.html#basestring">__builtin__.basestring</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="OSVersion-__ge__"><strong>__ge__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="OSVersion-__gt__"><strong>__gt__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="OSVersion-__le__"><strong>__le__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="OSVersion-__lt__"><strong>__lt__</strong></a>(self, other)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="OSVersion-__new__"><strong>__new__</strong></a>(cls, friendly_name, sortable_name, *args, **kwargs)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="__builtin__.html#str">__builtin__.str</a>:<br>
-<dl><dt><a name="OSVersion-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__format__"><strong>__format__</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-__format__">__format__</a>(format_spec)&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;formatted&nbsp;version&nbsp;of&nbsp;S&nbsp;as&nbsp;described&nbsp;by&nbsp;format_spec.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__getnewargs__"><strong>__getnewargs__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="OSVersion-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__mod__"><strong>__mod__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__mod__">__mod__</a>(y)&nbsp;&lt;==&gt;&nbsp;x%y</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__rmod__"><strong>__rmod__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__rmod__">__rmod__</a>(y)&nbsp;&lt;==&gt;&nbsp;y%x</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-__sizeof__">__sizeof__</a>()&nbsp;-&gt;&nbsp;size&nbsp;of&nbsp;S&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#OSVersion-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;<a href="__builtin__.html#str">str</a>(x)</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-capitalize"><strong>capitalize</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-capitalize">capitalize</a>()&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;with&nbsp;only&nbsp;its&nbsp;first&nbsp;character<br>
-capitalized.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-center"><strong>center</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-center">center</a>(width[,&nbsp;fillchar])&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;S&nbsp;centered&nbsp;in&nbsp;a&nbsp;string&nbsp;of&nbsp;length&nbsp;width.&nbsp;Padding&nbsp;is<br>
-done&nbsp;using&nbsp;the&nbsp;specified&nbsp;fill&nbsp;character&nbsp;(default&nbsp;is&nbsp;a&nbsp;space)</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-count"><strong>count</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-count">count</a>(sub[,&nbsp;start[,&nbsp;end]])&nbsp;-&gt;&nbsp;int<br>
-&nbsp;<br>
-Return&nbsp;the&nbsp;number&nbsp;of&nbsp;non-overlapping&nbsp;occurrences&nbsp;of&nbsp;substring&nbsp;sub&nbsp;in<br>
-string&nbsp;S[start:end].&nbsp;&nbsp;Optional&nbsp;arguments&nbsp;start&nbsp;and&nbsp;end&nbsp;are&nbsp;interpreted<br>
-as&nbsp;in&nbsp;slice&nbsp;notation.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-decode"><strong>decode</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-decode">decode</a>([encoding[,errors]])&nbsp;-&gt;&nbsp;object<br>
-&nbsp;<br>
-Decodes&nbsp;S&nbsp;using&nbsp;the&nbsp;codec&nbsp;registered&nbsp;for&nbsp;encoding.&nbsp;encoding&nbsp;defaults<br>
-to&nbsp;the&nbsp;default&nbsp;encoding.&nbsp;errors&nbsp;may&nbsp;be&nbsp;given&nbsp;to&nbsp;set&nbsp;a&nbsp;different&nbsp;error<br>
-handling&nbsp;scheme.&nbsp;Default&nbsp;is&nbsp;'strict'&nbsp;meaning&nbsp;that&nbsp;encoding&nbsp;errors&nbsp;raise<br>
-a&nbsp;UnicodeDecodeError.&nbsp;Other&nbsp;possible&nbsp;values&nbsp;are&nbsp;'ignore'&nbsp;and&nbsp;'replace'<br>
-as&nbsp;well&nbsp;as&nbsp;any&nbsp;other&nbsp;name&nbsp;registered&nbsp;with&nbsp;codecs.register_error&nbsp;that&nbsp;is<br>
-able&nbsp;to&nbsp;handle&nbsp;UnicodeDecodeErrors.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-encode"><strong>encode</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-encode">encode</a>([encoding[,errors]])&nbsp;-&gt;&nbsp;object<br>
-&nbsp;<br>
-Encodes&nbsp;S&nbsp;using&nbsp;the&nbsp;codec&nbsp;registered&nbsp;for&nbsp;encoding.&nbsp;encoding&nbsp;defaults<br>
-to&nbsp;the&nbsp;default&nbsp;encoding.&nbsp;errors&nbsp;may&nbsp;be&nbsp;given&nbsp;to&nbsp;set&nbsp;a&nbsp;different&nbsp;error<br>
-handling&nbsp;scheme.&nbsp;Default&nbsp;is&nbsp;'strict'&nbsp;meaning&nbsp;that&nbsp;encoding&nbsp;errors&nbsp;raise<br>
-a&nbsp;UnicodeEncodeError.&nbsp;Other&nbsp;possible&nbsp;values&nbsp;are&nbsp;'ignore',&nbsp;'replace'&nbsp;and<br>
-'xmlcharrefreplace'&nbsp;as&nbsp;well&nbsp;as&nbsp;any&nbsp;other&nbsp;name&nbsp;registered&nbsp;with<br>
-codecs.register_error&nbsp;that&nbsp;is&nbsp;able&nbsp;to&nbsp;handle&nbsp;UnicodeEncodeErrors.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-endswith"><strong>endswith</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-endswith">endswith</a>(suffix[,&nbsp;start[,&nbsp;end]])&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;S&nbsp;ends&nbsp;with&nbsp;the&nbsp;specified&nbsp;suffix,&nbsp;False&nbsp;otherwise.<br>
-With&nbsp;optional&nbsp;start,&nbsp;test&nbsp;S&nbsp;beginning&nbsp;at&nbsp;that&nbsp;position.<br>
-With&nbsp;optional&nbsp;end,&nbsp;stop&nbsp;comparing&nbsp;S&nbsp;at&nbsp;that&nbsp;position.<br>
-suffix&nbsp;can&nbsp;also&nbsp;be&nbsp;a&nbsp;tuple&nbsp;of&nbsp;strings&nbsp;to&nbsp;try.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-expandtabs"><strong>expandtabs</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-expandtabs">expandtabs</a>([tabsize])&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;S&nbsp;where&nbsp;all&nbsp;tab&nbsp;characters&nbsp;are&nbsp;expanded&nbsp;using&nbsp;spaces.<br>
-If&nbsp;tabsize&nbsp;is&nbsp;not&nbsp;given,&nbsp;a&nbsp;tab&nbsp;size&nbsp;of&nbsp;8&nbsp;characters&nbsp;is&nbsp;assumed.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-find"><strong>find</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-find">find</a>(sub&nbsp;[,start&nbsp;[,end]])&nbsp;-&gt;&nbsp;int<br>
-&nbsp;<br>
-Return&nbsp;the&nbsp;lowest&nbsp;index&nbsp;in&nbsp;S&nbsp;where&nbsp;substring&nbsp;sub&nbsp;is&nbsp;found,<br>
-such&nbsp;that&nbsp;sub&nbsp;is&nbsp;contained&nbsp;within&nbsp;S[start:end].&nbsp;&nbsp;Optional<br>
-arguments&nbsp;start&nbsp;and&nbsp;end&nbsp;are&nbsp;interpreted&nbsp;as&nbsp;in&nbsp;slice&nbsp;notation.<br>
-&nbsp;<br>
-Return&nbsp;-1&nbsp;on&nbsp;failure.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-format"><strong>format</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-format">format</a>(*args,&nbsp;**kwargs)&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;formatted&nbsp;version&nbsp;of&nbsp;S,&nbsp;using&nbsp;substitutions&nbsp;from&nbsp;args&nbsp;and&nbsp;kwargs.<br>
-The&nbsp;substitutions&nbsp;are&nbsp;identified&nbsp;by&nbsp;braces&nbsp;('{'&nbsp;and&nbsp;'}').</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-index"><strong>index</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-index">index</a>(sub&nbsp;[,start&nbsp;[,end]])&nbsp;-&gt;&nbsp;int<br>
-&nbsp;<br>
-Like&nbsp;S.<a href="#OSVersion-find">find</a>()&nbsp;but&nbsp;raise&nbsp;ValueError&nbsp;when&nbsp;the&nbsp;substring&nbsp;is&nbsp;not&nbsp;found.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-isalnum"><strong>isalnum</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-isalnum">isalnum</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;all&nbsp;characters&nbsp;in&nbsp;S&nbsp;are&nbsp;alphanumeric<br>
-and&nbsp;there&nbsp;is&nbsp;at&nbsp;least&nbsp;one&nbsp;character&nbsp;in&nbsp;S,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-isalpha"><strong>isalpha</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-isalpha">isalpha</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;all&nbsp;characters&nbsp;in&nbsp;S&nbsp;are&nbsp;alphabetic<br>
-and&nbsp;there&nbsp;is&nbsp;at&nbsp;least&nbsp;one&nbsp;character&nbsp;in&nbsp;S,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-isdigit"><strong>isdigit</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-isdigit">isdigit</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;all&nbsp;characters&nbsp;in&nbsp;S&nbsp;are&nbsp;digits<br>
-and&nbsp;there&nbsp;is&nbsp;at&nbsp;least&nbsp;one&nbsp;character&nbsp;in&nbsp;S,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-islower"><strong>islower</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-islower">islower</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;all&nbsp;cased&nbsp;characters&nbsp;in&nbsp;S&nbsp;are&nbsp;lowercase&nbsp;and&nbsp;there&nbsp;is<br>
-at&nbsp;least&nbsp;one&nbsp;cased&nbsp;character&nbsp;in&nbsp;S,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-isspace"><strong>isspace</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-isspace">isspace</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;all&nbsp;characters&nbsp;in&nbsp;S&nbsp;are&nbsp;whitespace<br>
-and&nbsp;there&nbsp;is&nbsp;at&nbsp;least&nbsp;one&nbsp;character&nbsp;in&nbsp;S,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-istitle"><strong>istitle</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-istitle">istitle</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;S&nbsp;is&nbsp;a&nbsp;titlecased&nbsp;string&nbsp;and&nbsp;there&nbsp;is&nbsp;at&nbsp;least&nbsp;one<br>
-character&nbsp;in&nbsp;S,&nbsp;i.e.&nbsp;uppercase&nbsp;characters&nbsp;may&nbsp;only&nbsp;follow&nbsp;uncased<br>
-characters&nbsp;and&nbsp;lowercase&nbsp;characters&nbsp;only&nbsp;cased&nbsp;ones.&nbsp;Return&nbsp;False<br>
-otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-isupper"><strong>isupper</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-isupper">isupper</a>()&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;all&nbsp;cased&nbsp;characters&nbsp;in&nbsp;S&nbsp;are&nbsp;uppercase&nbsp;and&nbsp;there&nbsp;is<br>
-at&nbsp;least&nbsp;one&nbsp;cased&nbsp;character&nbsp;in&nbsp;S,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-join"><strong>join</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-join">join</a>(iterable)&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;string&nbsp;which&nbsp;is&nbsp;the&nbsp;concatenation&nbsp;of&nbsp;the&nbsp;strings&nbsp;in&nbsp;the<br>
-iterable.&nbsp;&nbsp;The&nbsp;separator&nbsp;between&nbsp;elements&nbsp;is&nbsp;S.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-ljust"><strong>ljust</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-ljust">ljust</a>(width[,&nbsp;fillchar])&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;S&nbsp;left-justified&nbsp;in&nbsp;a&nbsp;string&nbsp;of&nbsp;length&nbsp;width.&nbsp;Padding&nbsp;is<br>
-done&nbsp;using&nbsp;the&nbsp;specified&nbsp;fill&nbsp;character&nbsp;(default&nbsp;is&nbsp;a&nbsp;space).</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-lower"><strong>lower</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-lower">lower</a>()&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;converted&nbsp;to&nbsp;lowercase.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-lstrip"><strong>lstrip</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-lstrip">lstrip</a>([chars])&nbsp;-&gt;&nbsp;string&nbsp;or&nbsp;unicode<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;with&nbsp;leading&nbsp;whitespace&nbsp;removed.<br>
-If&nbsp;chars&nbsp;is&nbsp;given&nbsp;and&nbsp;not&nbsp;None,&nbsp;remove&nbsp;characters&nbsp;in&nbsp;chars&nbsp;instead.<br>
-If&nbsp;chars&nbsp;is&nbsp;unicode,&nbsp;S&nbsp;will&nbsp;be&nbsp;converted&nbsp;to&nbsp;unicode&nbsp;before&nbsp;stripping</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-partition"><strong>partition</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-partition">partition</a>(sep)&nbsp;-&gt;&nbsp;(head,&nbsp;sep,&nbsp;tail)<br>
-&nbsp;<br>
-Search&nbsp;for&nbsp;the&nbsp;separator&nbsp;sep&nbsp;in&nbsp;S,&nbsp;and&nbsp;return&nbsp;the&nbsp;part&nbsp;before&nbsp;it,<br>
-the&nbsp;separator&nbsp;itself,&nbsp;and&nbsp;the&nbsp;part&nbsp;after&nbsp;it.&nbsp;&nbsp;If&nbsp;the&nbsp;separator&nbsp;is&nbsp;not<br>
-found,&nbsp;return&nbsp;S&nbsp;and&nbsp;two&nbsp;empty&nbsp;strings.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-replace"><strong>replace</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-replace">replace</a>(old,&nbsp;new[,&nbsp;count])&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;string&nbsp;S&nbsp;with&nbsp;all&nbsp;occurrences&nbsp;of&nbsp;substring<br>
-old&nbsp;replaced&nbsp;by&nbsp;new.&nbsp;&nbsp;If&nbsp;the&nbsp;optional&nbsp;argument&nbsp;count&nbsp;is<br>
-given,&nbsp;only&nbsp;the&nbsp;first&nbsp;count&nbsp;occurrences&nbsp;are&nbsp;replaced.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-rfind"><strong>rfind</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-rfind">rfind</a>(sub&nbsp;[,start&nbsp;[,end]])&nbsp;-&gt;&nbsp;int<br>
-&nbsp;<br>
-Return&nbsp;the&nbsp;highest&nbsp;index&nbsp;in&nbsp;S&nbsp;where&nbsp;substring&nbsp;sub&nbsp;is&nbsp;found,<br>
-such&nbsp;that&nbsp;sub&nbsp;is&nbsp;contained&nbsp;within&nbsp;S[start:end].&nbsp;&nbsp;Optional<br>
-arguments&nbsp;start&nbsp;and&nbsp;end&nbsp;are&nbsp;interpreted&nbsp;as&nbsp;in&nbsp;slice&nbsp;notation.<br>
-&nbsp;<br>
-Return&nbsp;-1&nbsp;on&nbsp;failure.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-rindex"><strong>rindex</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-rindex">rindex</a>(sub&nbsp;[,start&nbsp;[,end]])&nbsp;-&gt;&nbsp;int<br>
-&nbsp;<br>
-Like&nbsp;S.<a href="#OSVersion-rfind">rfind</a>()&nbsp;but&nbsp;raise&nbsp;ValueError&nbsp;when&nbsp;the&nbsp;substring&nbsp;is&nbsp;not&nbsp;found.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-rjust"><strong>rjust</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-rjust">rjust</a>(width[,&nbsp;fillchar])&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;S&nbsp;right-justified&nbsp;in&nbsp;a&nbsp;string&nbsp;of&nbsp;length&nbsp;width.&nbsp;Padding&nbsp;is<br>
-done&nbsp;using&nbsp;the&nbsp;specified&nbsp;fill&nbsp;character&nbsp;(default&nbsp;is&nbsp;a&nbsp;space)</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-rpartition"><strong>rpartition</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-rpartition">rpartition</a>(sep)&nbsp;-&gt;&nbsp;(head,&nbsp;sep,&nbsp;tail)<br>
-&nbsp;<br>
-Search&nbsp;for&nbsp;the&nbsp;separator&nbsp;sep&nbsp;in&nbsp;S,&nbsp;starting&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;S,&nbsp;and&nbsp;return<br>
-the&nbsp;part&nbsp;before&nbsp;it,&nbsp;the&nbsp;separator&nbsp;itself,&nbsp;and&nbsp;the&nbsp;part&nbsp;after&nbsp;it.&nbsp;&nbsp;If&nbsp;the<br>
-separator&nbsp;is&nbsp;not&nbsp;found,&nbsp;return&nbsp;two&nbsp;empty&nbsp;strings&nbsp;and&nbsp;S.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-rsplit"><strong>rsplit</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-rsplit">rsplit</a>([sep&nbsp;[,maxsplit]])&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;strings<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;words&nbsp;in&nbsp;the&nbsp;string&nbsp;S,&nbsp;using&nbsp;sep&nbsp;as&nbsp;the<br>
-delimiter&nbsp;string,&nbsp;starting&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;string&nbsp;and&nbsp;working<br>
-to&nbsp;the&nbsp;front.&nbsp;&nbsp;If&nbsp;maxsplit&nbsp;is&nbsp;given,&nbsp;at&nbsp;most&nbsp;maxsplit&nbsp;splits&nbsp;are<br>
-done.&nbsp;If&nbsp;sep&nbsp;is&nbsp;not&nbsp;specified&nbsp;or&nbsp;is&nbsp;None,&nbsp;any&nbsp;whitespace&nbsp;string<br>
-is&nbsp;a&nbsp;separator.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-rstrip"><strong>rstrip</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-rstrip">rstrip</a>([chars])&nbsp;-&gt;&nbsp;string&nbsp;or&nbsp;unicode<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;with&nbsp;trailing&nbsp;whitespace&nbsp;removed.<br>
-If&nbsp;chars&nbsp;is&nbsp;given&nbsp;and&nbsp;not&nbsp;None,&nbsp;remove&nbsp;characters&nbsp;in&nbsp;chars&nbsp;instead.<br>
-If&nbsp;chars&nbsp;is&nbsp;unicode,&nbsp;S&nbsp;will&nbsp;be&nbsp;converted&nbsp;to&nbsp;unicode&nbsp;before&nbsp;stripping</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-split"><strong>split</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-split">split</a>([sep&nbsp;[,maxsplit]])&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;strings<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;words&nbsp;in&nbsp;the&nbsp;string&nbsp;S,&nbsp;using&nbsp;sep&nbsp;as&nbsp;the<br>
-delimiter&nbsp;string.&nbsp;&nbsp;If&nbsp;maxsplit&nbsp;is&nbsp;given,&nbsp;at&nbsp;most&nbsp;maxsplit<br>
-splits&nbsp;are&nbsp;done.&nbsp;If&nbsp;sep&nbsp;is&nbsp;not&nbsp;specified&nbsp;or&nbsp;is&nbsp;None,&nbsp;any<br>
-whitespace&nbsp;string&nbsp;is&nbsp;a&nbsp;separator&nbsp;and&nbsp;empty&nbsp;strings&nbsp;are&nbsp;removed<br>
-from&nbsp;the&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-splitlines"><strong>splitlines</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-splitlines">splitlines</a>(keepends=False)&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;strings<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;lines&nbsp;in&nbsp;S,&nbsp;breaking&nbsp;at&nbsp;line&nbsp;boundaries.<br>
-Line&nbsp;breaks&nbsp;are&nbsp;not&nbsp;included&nbsp;in&nbsp;the&nbsp;resulting&nbsp;list&nbsp;unless&nbsp;keepends<br>
-is&nbsp;given&nbsp;and&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-startswith"><strong>startswith</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-startswith">startswith</a>(prefix[,&nbsp;start[,&nbsp;end]])&nbsp;-&gt;&nbsp;bool<br>
-&nbsp;<br>
-Return&nbsp;True&nbsp;if&nbsp;S&nbsp;starts&nbsp;with&nbsp;the&nbsp;specified&nbsp;prefix,&nbsp;False&nbsp;otherwise.<br>
-With&nbsp;optional&nbsp;start,&nbsp;test&nbsp;S&nbsp;beginning&nbsp;at&nbsp;that&nbsp;position.<br>
-With&nbsp;optional&nbsp;end,&nbsp;stop&nbsp;comparing&nbsp;S&nbsp;at&nbsp;that&nbsp;position.<br>
-prefix&nbsp;can&nbsp;also&nbsp;be&nbsp;a&nbsp;tuple&nbsp;of&nbsp;strings&nbsp;to&nbsp;try.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-strip"><strong>strip</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-strip">strip</a>([chars])&nbsp;-&gt;&nbsp;string&nbsp;or&nbsp;unicode<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;with&nbsp;leading&nbsp;and&nbsp;trailing<br>
-whitespace&nbsp;removed.<br>
-If&nbsp;chars&nbsp;is&nbsp;given&nbsp;and&nbsp;not&nbsp;None,&nbsp;remove&nbsp;characters&nbsp;in&nbsp;chars&nbsp;instead.<br>
-If&nbsp;chars&nbsp;is&nbsp;unicode,&nbsp;S&nbsp;will&nbsp;be&nbsp;converted&nbsp;to&nbsp;unicode&nbsp;before&nbsp;stripping</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-swapcase"><strong>swapcase</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-swapcase">swapcase</a>()&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;with&nbsp;uppercase&nbsp;characters<br>
-converted&nbsp;to&nbsp;lowercase&nbsp;and&nbsp;vice&nbsp;versa.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-title"><strong>title</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-title">title</a>()&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;titlecased&nbsp;version&nbsp;of&nbsp;S,&nbsp;i.e.&nbsp;words&nbsp;start&nbsp;with&nbsp;uppercase<br>
-characters,&nbsp;all&nbsp;remaining&nbsp;cased&nbsp;characters&nbsp;have&nbsp;lowercase.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-translate"><strong>translate</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-translate">translate</a>(table&nbsp;[,deletechars])&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S,&nbsp;where&nbsp;all&nbsp;characters&nbsp;occurring<br>
-in&nbsp;the&nbsp;optional&nbsp;argument&nbsp;deletechars&nbsp;are&nbsp;removed,&nbsp;and&nbsp;the<br>
-remaining&nbsp;characters&nbsp;have&nbsp;been&nbsp;mapped&nbsp;through&nbsp;the&nbsp;given<br>
-translation&nbsp;table,&nbsp;which&nbsp;must&nbsp;be&nbsp;a&nbsp;string&nbsp;of&nbsp;length&nbsp;256&nbsp;or&nbsp;None.<br>
-If&nbsp;the&nbsp;table&nbsp;argument&nbsp;is&nbsp;None,&nbsp;no&nbsp;translation&nbsp;is&nbsp;applied&nbsp;and<br>
-the&nbsp;operation&nbsp;simply&nbsp;removes&nbsp;the&nbsp;characters&nbsp;in&nbsp;deletechars.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-upper"><strong>upper</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-upper">upper</a>()&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Return&nbsp;a&nbsp;copy&nbsp;of&nbsp;the&nbsp;string&nbsp;S&nbsp;converted&nbsp;to&nbsp;uppercase.</tt></dd></dl>
-
-<dl><dt><a name="OSVersion-zfill"><strong>zfill</strong></a>(...)</dt><dd><tt>S.<a href="#OSVersion-zfill">zfill</a>(width)&nbsp;-&gt;&nbsp;string<br>
-&nbsp;<br>
-Pad&nbsp;a&nbsp;numeric&nbsp;string&nbsp;S&nbsp;with&nbsp;zeros&nbsp;on&nbsp;the&nbsp;left,&nbsp;to&nbsp;fill&nbsp;a&nbsp;field<br>
-of&nbsp;the&nbsp;specified&nbsp;width.&nbsp;&nbsp;The&nbsp;string&nbsp;S&nbsp;is&nbsp;never&nbsp;truncated.</tt></dd></dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ELCAPITAN</strong> = 'elcapitan'<br>
-<strong>LEOPARD</strong> = 'leopard'<br>
-<strong>LION</strong> = 'lion'<br>
-<strong>MAVERICKS</strong> = 'mavericks'<br>
-<strong>MOUNTAINLION</strong> = 'mountainlion'<br>
-<strong>SNOWLEOPARD</strong> = 'snowleopard'<br>
-<strong>VISTA</strong> = 'vista'<br>
-<strong>WIN7</strong> = 'win7'<br>
-<strong>WIN8</strong> = 'win8'<br>
-<strong>XP</strong> = 'xp'<br>
-<strong>YOSEMITE</strong> = 'yosemite'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.platform.html b/catapult/telemetry/docs/pydoc/telemetry.core.platform.html
deleted file mode 100644
index 46f4e38..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.platform.html
+++ /dev/null
@@ -1,269 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.platform</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.platform</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/platform.py">telemetry/core/platform.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-<a href="telemetry.core.local_server.html">telemetry.core.local_server</a><br>
-<a href="telemetry.core.memory_cache_http_server.html">telemetry.core.memory_cache_http_server</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.network_controller.html">telemetry.core.network_controller</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.internal.platform.platform_backend.html">telemetry.internal.platform.platform_backend</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.core.tracing_controller.html">telemetry.core.tracing_controller</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.platform.html#Platform">Platform</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Platform">class <strong>Platform</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;platform&nbsp;that&nbsp;the&nbsp;target&nbsp;browser&nbsp;is&nbsp;running&nbsp;on.<br>
-&nbsp;<br>
-Provides&nbsp;a&nbsp;limited&nbsp;interface&nbsp;to&nbsp;interact&nbsp;with&nbsp;the&nbsp;platform&nbsp;itself,&nbsp;where<br>
-possible.&nbsp;It's&nbsp;important&nbsp;to&nbsp;note&nbsp;that&nbsp;platforms&nbsp;may&nbsp;not&nbsp;provide&nbsp;a&nbsp;specific<br>
-API,&nbsp;so&nbsp;check&nbsp;with&nbsp;IsFooBar()&nbsp;for&nbsp;availability.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Platform-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;bool&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;platform&nbsp;supports&nbsp;video&nbsp;capture.</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;disk&nbsp;cache&nbsp;can&nbsp;be&nbsp;flushed&nbsp;for&nbsp;specific&nbsp;files.</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt><dd><tt>Returns&nbsp;whether&nbsp;the&nbsp;platform&nbsp;can&nbsp;launch&nbsp;the&nbsp;given&nbsp;application.</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;network&nbsp;data&nbsp;can&nbsp;be&nbsp;retrieved,&nbsp;false&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;power&nbsp;can&nbsp;be&nbsp;monitored&nbsp;asynchronously&nbsp;via<br>
-<a href="#Platform-StartMonitoringPower">StartMonitoringPower</a>()&nbsp;and&nbsp;<a href="#Platform-StopMonitoringPower">StopMonitoringPower</a>().</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt><dd><tt>Platforms&nbsp;may&nbsp;be&nbsp;able&nbsp;to&nbsp;detect&nbsp;thermal&nbsp;throttling.<br>
-&nbsp;<br>
-Some&nbsp;fan-less&nbsp;computers&nbsp;go&nbsp;into&nbsp;a&nbsp;reduced&nbsp;performance&nbsp;mode&nbsp;when&nbsp;their&nbsp;heat<br>
-exceeds&nbsp;a&nbsp;certain&nbsp;threshold.&nbsp;Performance&nbsp;tests&nbsp;in&nbsp;particular&nbsp;should&nbsp;use&nbsp;this<br>
-API&nbsp;to&nbsp;detect&nbsp;if&nbsp;this&nbsp;has&nbsp;happened&nbsp;and&nbsp;interpret&nbsp;results&nbsp;accordingly.</tt></dd></dl>
-
-<dl><dt><a name="Platform-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Platform-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="Platform-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt><dd><tt>Flushes&nbsp;the&nbsp;OS's&nbsp;DNS&nbsp;cache&nbsp;completely.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;may&nbsp;require&nbsp;root&nbsp;or&nbsp;administrator&nbsp;access.</tt></dd></dl>
-
-<dl><dt><a name="Platform-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt><dd><tt>Flushes&nbsp;the&nbsp;OS's&nbsp;file&nbsp;cache&nbsp;completely.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;may&nbsp;require&nbsp;root&nbsp;or&nbsp;administrator&nbsp;access.</tt></dd></dl>
-
-<dl><dt><a name="Platform-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt><dd><tt>Flushes&nbsp;the&nbsp;OS's&nbsp;file&nbsp;cache&nbsp;for&nbsp;the&nbsp;specified&nbsp;directory.<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;does&nbsp;not&nbsp;require&nbsp;root&nbsp;or&nbsp;administrator&nbsp;access.</tt></dd></dl>
-
-<dl><dt><a name="Platform-GetArchName"><strong>GetArchName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="#Platform">Platform</a>&nbsp;architecture.<br>
-&nbsp;<br>
-Examples:&nbsp;x86_64&nbsp;(posix),&nbsp;AMD64&nbsp;(win),&nbsp;armeabi-v7a,&nbsp;x86</tt></dd></dl>
-
-<dl><dt><a name="Platform-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="#Platform">Platform</a>&nbsp;device,&nbsp;or&nbsp;None.<br>
-&nbsp;<br>
-Examples:&nbsp;Nexus&nbsp;7,&nbsp;Nexus&nbsp;6,&nbsp;Desktop</tt></dd></dl>
-
-<dl><dt><a name="Platform-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt><dd><tt>Get&nbsp;current&nbsp;network&nbsp;data.<br>
-Returns:<br>
-&nbsp;&nbsp;Tuple&nbsp;of&nbsp;(sent_data,&nbsp;received_data)&nbsp;in&nbsp;kb&nbsp;if&nbsp;data&nbsp;can&nbsp;be&nbsp;found,<br>
-&nbsp;&nbsp;None&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="Platform-GetOSName"><strong>GetOSName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;string&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="#Platform">Platform</a>&nbsp;OS.<br>
-&nbsp;<br>
-Examples:&nbsp;WIN,&nbsp;MAC,&nbsp;LINUX,&nbsp;CHROMEOS</tt></dd></dl>
-
-<dl><dt><a name="Platform-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;logically&nbsp;sortable,&nbsp;string-like&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="#Platform">Platform</a>&nbsp;OS<br>
-version.<br>
-&nbsp;<br>
-Examples:&nbsp;VISTA,&nbsp;WIN7,&nbsp;LION,&nbsp;MOUNTAINLION</tt></dd></dl>
-
-<dl><dt><a name="Platform-GetOSVersionNumber"><strong>GetOSVersionNumber</strong></a>(self)</dt><dd><tt>Returns&nbsp;an&nbsp;integer&nbsp;description&nbsp;of&nbsp;the&nbsp;<a href="#Platform">Platform</a>&nbsp;OS&nbsp;major&nbsp;version.<br>
-&nbsp;<br>
-Examples:&nbsp;On&nbsp;Mac,&nbsp;13&nbsp;for&nbsp;Mavericks,&nbsp;14&nbsp;for&nbsp;Yosemite.</tt></dd></dl>
-
-<dl><dt><a name="Platform-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;device&nbsp;has&nbsp;been&nbsp;thermally&nbsp;throttled.</tt></dd></dl>
-
-<dl><dt><a name="Platform-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt><dd><tt>Installs&nbsp;the&nbsp;given&nbsp;application.</tt></dd></dl>
-
-<dl><dt><a name="Platform-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt><dd><tt>Returns&nbsp;whether&nbsp;an&nbsp;application&nbsp;is&nbsp;currently&nbsp;running.</tt></dd></dl>
-
-<dl><dt><a name="Platform-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="Platform-IsMonitoringPower"><strong>IsMonitoringPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;power&nbsp;is&nbsp;currently&nbsp;being&nbsp;monitored,&nbsp;false&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="Platform-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;device&nbsp;is&nbsp;currently&nbsp;thermally&nbsp;throttled.</tt></dd></dl>
-
-<dl><dt><a name="Platform-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt><dd><tt>"Launches&nbsp;the&nbsp;given&nbsp;|application|&nbsp;with&nbsp;a&nbsp;list&nbsp;of&nbsp;|parameters|&nbsp;on&nbsp;the&nbsp;OS.<br>
-&nbsp;<br>
-Set&nbsp;|elevate_privilege|&nbsp;to&nbsp;launch&nbsp;the&nbsp;application&nbsp;with&nbsp;root&nbsp;or&nbsp;admin&nbsp;rights.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;popen&nbsp;style&nbsp;process&nbsp;handle&nbsp;for&nbsp;host&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="Platform-SetHTTPServerDirectories"><strong>SetHTTPServerDirectories</strong></a>(self, paths)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;HTTP&nbsp;server&nbsp;was&nbsp;started,&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="Platform-StartLocalServer"><strong>StartLocalServer</strong></a>(self, server)</dt><dd><tt>Starts&nbsp;a&nbsp;LocalServer&nbsp;and&nbsp;associates&nbsp;it&nbsp;with&nbsp;this&nbsp;platform.<br>
-|server.Close()|&nbsp;should&nbsp;be&nbsp;called&nbsp;manually&nbsp;to&nbsp;close&nbsp;the&nbsp;started&nbsp;server.</tt></dd></dl>
-
-<dl><dt><a name="Platform-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt><dd><tt>Starts&nbsp;monitoring&nbsp;power&nbsp;utilization&nbsp;statistics.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser:&nbsp;The&nbsp;browser&nbsp;to&nbsp;monitor.</tt></dd></dl>
-
-<dl><dt><a name="Platform-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt><dd><tt>Starts&nbsp;capturing&nbsp;video.<br>
-&nbsp;<br>
-Outer&nbsp;framing&nbsp;may&nbsp;be&nbsp;included&nbsp;(from&nbsp;the&nbsp;OS,&nbsp;browser&nbsp;window,&nbsp;and&nbsp;webcam).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;min_bitrate_mbps:&nbsp;The&nbsp;minimum&nbsp;capture&nbsp;bitrate&nbsp;in&nbsp;MegaBits&nbsp;Per&nbsp;Second.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;platform&nbsp;is&nbsp;free&nbsp;to&nbsp;deliver&nbsp;a&nbsp;higher&nbsp;bitrate&nbsp;if&nbsp;it&nbsp;can&nbsp;do&nbsp;so<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;without&nbsp;increasing&nbsp;overhead.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;required&nbsp;|min_bitrate_mbps|&nbsp;can't&nbsp;be&nbsp;achieved.</tt></dd></dl>
-
-<dl><dt><a name="Platform-StopAllLocalServers"><strong>StopAllLocalServers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Platform-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt><dd><tt>Stops&nbsp;monitoring&nbsp;power&nbsp;utilization&nbsp;and&nbsp;returns&nbsp;stats<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;None&nbsp;if&nbsp;power&nbsp;measurement&nbsp;failed&nbsp;for&nbsp;some&nbsp;reason,&nbsp;otherwise&nbsp;a&nbsp;dict&nbsp;of<br>
-&nbsp;&nbsp;power&nbsp;utilization&nbsp;statistics&nbsp;containing:&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;An&nbsp;identifier&nbsp;for&nbsp;the&nbsp;data&nbsp;provider.&nbsp;Allows&nbsp;to&nbsp;evaluate&nbsp;the&nbsp;precision<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;of&nbsp;the&nbsp;data.&nbsp;Example&nbsp;values:&nbsp;monsoon,&nbsp;powermetrics,&nbsp;ds2784<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'identifier':&nbsp;identifier,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;The&nbsp;instantaneous&nbsp;power&nbsp;(voltage&nbsp;*&nbsp;current)&nbsp;reading&nbsp;in&nbsp;milliwatts&nbsp;at<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;each&nbsp;sample.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'power_samples_mw':&nbsp;&nbsp;[mw0,&nbsp;mw1,&nbsp;...,&nbsp;mwN],<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;The&nbsp;full&nbsp;system&nbsp;energy&nbsp;consumption&nbsp;during&nbsp;the&nbsp;sampling&nbsp;period&nbsp;in<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;milliwatt&nbsp;hours.&nbsp;May&nbsp;be&nbsp;estimated&nbsp;by&nbsp;integrating&nbsp;power&nbsp;samples&nbsp;or&nbsp;may<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;be&nbsp;exact&nbsp;on&nbsp;supported&nbsp;hardware.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'energy_consumption_mwh':&nbsp;mwh,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;The&nbsp;target&nbsp;application's&nbsp;energy&nbsp;consumption&nbsp;during&nbsp;the&nbsp;sampling&nbsp;period<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;in&nbsp;milliwatt&nbsp;hours.&nbsp;Should&nbsp;be&nbsp;returned&nbsp;iff<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;<a href="#Platform-CanMeasurePerApplicationPower">CanMeasurePerApplicationPower</a>()&nbsp;return&nbsp;true.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'application_energy_consumption_mwh':&nbsp;mwh,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;A&nbsp;platform-specific&nbsp;dictionary&nbsp;of&nbsp;additional&nbsp;details&nbsp;about&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;utilization&nbsp;of&nbsp;individual&nbsp;hardware&nbsp;components.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;component_utilization:&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>
-&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;<a href="#Platform">Platform</a>-specific&nbsp;data&nbsp;not&nbsp;attributed&nbsp;to&nbsp;any&nbsp;particular&nbsp;hardware<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;component.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;platform_info:&nbsp;{<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Device-specific&nbsp;onboard&nbsp;temperature&nbsp;sensor.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'average_temperature_c':&nbsp;c,<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br>
-&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-&nbsp;<br>
-&nbsp;&nbsp;}</tt></dd></dl>
-
-<dl><dt><a name="Platform-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt><dd><tt>Stops&nbsp;capturing&nbsp;video.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;telemetry.core.video.Video&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
-
-<dl><dt><a name="Platform-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt><dd><tt>Takes&nbsp;a&nbsp;screenshot&nbsp;of&nbsp;the&nbsp;platform&nbsp;and&nbsp;save&nbsp;to&nbsp;|file_path|.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;this&nbsp;method&nbsp;may&nbsp;not&nbsp;be&nbsp;supported&nbsp;on&nbsp;all&nbsp;platform,&nbsp;so&nbsp;check&nbsp;with<br>
-CanTakeScreenshot&nbsp;before&nbsp;calling&nbsp;this.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;file_path:&nbsp;Where&nbsp;to&nbsp;save&nbsp;the&nbsp;screenshot&nbsp;to.&nbsp;If&nbsp;the&nbsp;platform&nbsp;is&nbsp;remote,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;|file_path|&nbsp;is&nbsp;the&nbsp;path&nbsp;on&nbsp;the&nbsp;host&nbsp;platform.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="Platform-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>http_server</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>local_servers</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;currently&nbsp;running&nbsp;local&nbsp;servers.</tt></dd>
-</dl>
-<dl><dt><strong>network_controller</strong></dt>
-<dd><tt>Control&nbsp;network&nbsp;settings&nbsp;and&nbsp;servers&nbsp;to&nbsp;simulate&nbsp;the&nbsp;Web.</tt></dd>
-</dl>
-<dl><dt><strong>tracing_controller</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetHostPlatform"><strong>GetHostPlatform</strong></a>()</dt></dl>
- <dl><dt><a name="-GetPlatformForDevice"><strong>GetPlatformForDevice</strong></a>(device, finder_options, logging<font color="#909090">=&lt;module 'logging' from '/usr/lib/python2.7/logging/__init__.pyc'&gt;</font>)</dt><dd><tt>Returns&nbsp;a&nbsp;platform&nbsp;instance&nbsp;for&nbsp;the&nbsp;device.<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;a&nbsp;device.Device&nbsp;instance.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.profiling_controller.html b/catapult/telemetry/docs/pydoc/telemetry.core.profiling_controller.html
deleted file mode 100644
index c5d4b2c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.profiling_controller.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.profiling_controller</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.profiling_controller</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/profiling_controller.py">telemetry/core/profiling_controller.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.profiling_controller.html#ProfilingController">ProfilingController</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProfilingController">class <strong>ProfilingController</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ProfilingController-Start"><strong>Start</strong></a>(self, profiler_name, base_output_file)</dt></dl>
-
-<dl><dt><a name="ProfilingController-Stop"><strong>Stop</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ProfilingController-__init__"><strong>__init__</strong></a>(self, profiling_controller_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.tracing_controller.html b/catapult/telemetry/docs/pydoc/telemetry.core.tracing_controller.html
deleted file mode 100644
index 4557f4b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.tracing_controller.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.tracing_controller</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.tracing_controller</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/tracing_controller.py">telemetry/core/tracing_controller.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.tracing_controller.html#TracingController">TracingController</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingController">class <strong>TracingController</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingController-IsChromeTracingSupported"><strong>IsChromeTracingSupported</strong></a>(self)</dt><dd><tt>Returns&nbsp;whether&nbsp;chrome&nbsp;tracing&nbsp;is&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingController-Start"><strong>Start</strong></a>(self, trace_options, category_filter, timeout<font color="#909090">=10</font>)</dt><dd><tt>Starts&nbsp;tracing.<br>
-&nbsp;<br>
-trace_options&nbsp;specifies&nbsp;which&nbsp;tracing&nbsp;systems&nbsp;to&nbsp;activate.&nbsp;Category&nbsp;filter<br>
-allows&nbsp;fine-tuning&nbsp;of&nbsp;the&nbsp;data&nbsp;that&nbsp;are&nbsp;collected&nbsp;by&nbsp;the&nbsp;selected&nbsp;tracing<br>
-systems.<br>
-&nbsp;<br>
-Some&nbsp;tracers&nbsp;are&nbsp;process-specific,&nbsp;e.g.&nbsp;chrome&nbsp;tracing,&nbsp;but&nbsp;are&nbsp;not<br>
-guaranteed&nbsp;to&nbsp;be&nbsp;supported.&nbsp;In&nbsp;order&nbsp;to&nbsp;support&nbsp;tracing&nbsp;of&nbsp;these&nbsp;kinds&nbsp;of<br>
-tracers,&nbsp;Start&nbsp;will&nbsp;succeed&nbsp;*always*,&nbsp;even&nbsp;if&nbsp;the&nbsp;tracing&nbsp;systems&nbsp;you&nbsp;have<br>
-requested&nbsp;are&nbsp;not&nbsp;supported.<br>
-&nbsp;<br>
-If&nbsp;you&nbsp;absolutely&nbsp;require&nbsp;a&nbsp;particular&nbsp;tracer&nbsp;to&nbsp;exist,&nbsp;then&nbsp;check<br>
-for&nbsp;its&nbsp;support&nbsp;after&nbsp;you&nbsp;have&nbsp;started&nbsp;the&nbsp;process&nbsp;in&nbsp;question.&nbsp;Or,&nbsp;have<br>
-your&nbsp;code&nbsp;fail&nbsp;gracefully&nbsp;when&nbsp;the&nbsp;data&nbsp;you&nbsp;require&nbsp;is&nbsp;not&nbsp;present&nbsp;in&nbsp;the<br>
-resulting&nbsp;trace.</tt></dd></dl>
-
-<dl><dt><a name="TracingController-Stop"><strong>Stop</strong></a>(self)</dt><dd><tt>Stops&nbsp;tracing&nbsp;and&nbsp;returns&nbsp;a&nbsp;TraceValue.</tt></dd></dl>
-
-<dl><dt><a name="TracingController-__init__"><strong>__init__</strong></a>(self, tracing_controller_backend)</dt><dd><tt>Provides&nbsp;control&nbsp;of&nbsp;the&nbsp;tracing&nbsp;systems&nbsp;supported&nbsp;by&nbsp;telemetry.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_tracing_running</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.core.util.html b/catapult/telemetry/docs/pydoc/telemetry.core.util.html
deleted file mode 100644
index 1c76b79..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.core.util.html
+++ /dev/null
@@ -1,104 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.core.util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.core.html"><font color="#ffffff">core</font></a>.util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/core/util.py">telemetry/core/util.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="glob.html">glob</a><br>
-<a href="imp.html">imp</a><br>
-</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="socket.html">socket</a><br>
-<a href="sys.html">sys</a><br>
-<a href="time.html">time</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.util.html#PortKeeper">PortKeeper</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PortKeeper">class <strong>PortKeeper</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Port&nbsp;keeper&nbsp;hold&nbsp;an&nbsp;available&nbsp;port&nbsp;on&nbsp;the&nbsp;system.<br>
-&nbsp;<br>
-Before&nbsp;actually&nbsp;use&nbsp;the&nbsp;port,&nbsp;you&nbsp;must&nbsp;call&nbsp;<a href="#PortKeeper-Release">Release</a>().<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PortKeeper-Release"><strong>Release</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PortKeeper-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetBaseDir"><strong>GetBaseDir</strong></a>()</dt></dl>
- <dl><dt><a name="-GetBuildDirectories"><strong>GetBuildDirectories</strong></a>()</dt><dd><tt>Yields&nbsp;all&nbsp;combination&nbsp;of&nbsp;Chromium&nbsp;build&nbsp;output&nbsp;directories.</tt></dd></dl>
- <dl><dt><a name="-GetChromiumSrcDir"><strong>GetChromiumSrcDir</strong></a>()</dt></dl>
- <dl><dt><a name="-GetPythonPageSetModule"><strong>GetPythonPageSetModule</strong></a>(file_path)</dt></dl>
- <dl><dt><a name="-GetSequentialFileName"><strong>GetSequentialFileName</strong></a>(base_name)</dt><dd><tt>Returns&nbsp;the&nbsp;next&nbsp;sequential&nbsp;file&nbsp;name&nbsp;based&nbsp;on&nbsp;|base_name|&nbsp;and&nbsp;the<br>
-existing&nbsp;files.&nbsp;base_name&nbsp;should&nbsp;not&nbsp;contain&nbsp;extension.<br>
-e.g:&nbsp;if&nbsp;base_name&nbsp;is&nbsp;/tmp/test,&nbsp;and&nbsp;/tmp/test_000.json,<br>
-/tmp/test_001.mp3&nbsp;exist,&nbsp;this&nbsp;returns&nbsp;/tmp/test_002.&nbsp;In&nbsp;case&nbsp;no<br>
-other&nbsp;sequential&nbsp;file&nbsp;name&nbsp;exist,&nbsp;this&nbsp;will&nbsp;return&nbsp;/tmp/test_000</tt></dd></dl>
- <dl><dt><a name="-GetTelemetryDir"><strong>GetTelemetryDir</strong></a>()</dt></dl>
- <dl><dt><a name="-GetTelemetryThirdPartyDir"><strong>GetTelemetryThirdPartyDir</strong></a>()</dt></dl>
- <dl><dt><a name="-GetUnittestDataDir"><strong>GetUnittestDataDir</strong></a>()</dt></dl>
- <dl><dt><a name="-GetUnreservedAvailableLocalPort"><strong>GetUnreservedAvailableLocalPort</strong></a>()</dt><dd><tt>Returns&nbsp;an&nbsp;available&nbsp;port&nbsp;on&nbsp;the&nbsp;system.<br>
-&nbsp;<br>
-WARNING:&nbsp;This&nbsp;method&nbsp;does&nbsp;not&nbsp;reserve&nbsp;the&nbsp;port&nbsp;it&nbsp;returns,&nbsp;so&nbsp;it&nbsp;may&nbsp;be&nbsp;used<br>
-by&nbsp;something&nbsp;else&nbsp;before&nbsp;you&nbsp;get&nbsp;to&nbsp;use&nbsp;it.&nbsp;This&nbsp;can&nbsp;lead&nbsp;to&nbsp;flake.</tt></dd></dl>
- <dl><dt><a name="-IsRunningOnCrosDevice"><strong>IsRunningOnCrosDevice</strong></a>()</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;we're&nbsp;on&nbsp;a&nbsp;ChromeOS&nbsp;device.</tt></dd></dl>
- <dl><dt><a name="-WaitFor"><strong>WaitFor</strong></a>(condition, timeout)</dt><dd><tt>Waits&nbsp;for&nbsp;up&nbsp;to&nbsp;|timeout|&nbsp;secs&nbsp;for&nbsp;the&nbsp;function&nbsp;|condition|&nbsp;to&nbsp;return&nbsp;True.<br>
-&nbsp;<br>
-Polling&nbsp;frequency&nbsp;is&nbsp;(elapsed_time&nbsp;/&nbsp;10),&nbsp;with&nbsp;a&nbsp;min&nbsp;of&nbsp;.1s&nbsp;and&nbsp;max&nbsp;of&nbsp;5s.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;Result&nbsp;of&nbsp;|condition|&nbsp;function&nbsp;(if&nbsp;present).</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.decorators.html b/catapult/telemetry/docs/pydoc/telemetry.decorators.html
deleted file mode 100644
index b203e50..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.decorators.html
+++ /dev/null
@@ -1,117 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.decorators</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.decorators</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/decorators.py">telemetry/decorators.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.<br>
-#&nbsp;pylint:&nbsp;disable=W0212</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="datetime.html">datetime</a><br>
-<a href="functools.html">functools</a><br>
-</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="types.html">types</a><br>
-<a href="warnings.html">warnings</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.decorators.html#Deprecated">Deprecated</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Deprecated">class <strong>Deprecated</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Deprecated-__call__"><strong>__call__</strong></a>(self, target)</dt></dl>
-
-<dl><dt><a name="Deprecated-__init__"><strong>__init__</strong></a>(self, year, month, day, extra_guidance<font color="#909090">=''</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-Cache"><strong>Cache</strong></a>(obj)</dt><dd><tt>Decorator&nbsp;for&nbsp;caching&nbsp;read-only&nbsp;properties.<br>
-&nbsp;<br>
-Example&nbsp;usage&nbsp;(always&nbsp;returns&nbsp;the&nbsp;same&nbsp;Foo&nbsp;instance):<br>
-&nbsp;&nbsp;@Cache<br>
-&nbsp;&nbsp;def&nbsp;CreateFoo():<br>
-&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Foo()<br>
-&nbsp;<br>
-If&nbsp;CreateFoo()&nbsp;accepts&nbsp;parameters,&nbsp;a&nbsp;separate&nbsp;cached&nbsp;value&nbsp;is&nbsp;maintained<br>
-for&nbsp;each&nbsp;unique&nbsp;parameter&nbsp;combination.<br>
-&nbsp;<br>
-Cached&nbsp;methods&nbsp;maintain&nbsp;their&nbsp;cache&nbsp;for&nbsp;the&nbsp;lifetime&nbsp;of&nbsp;the&nbsp;/instance/,&nbsp;while<br>
-cached&nbsp;functions&nbsp;maintain&nbsp;their&nbsp;cache&nbsp;for&nbsp;the&nbsp;lifetime&nbsp;of&nbsp;the&nbsp;/module/.</tt></dd></dl>
- <dl><dt><a name="-Disabled"><strong>Disabled</strong></a>(*args)</dt><dd><tt>Decorator&nbsp;for&nbsp;disabling&nbsp;tests/benchmarks.<br>
-&nbsp;<br>
-&nbsp;<br>
-If&nbsp;args&nbsp;are&nbsp;given,&nbsp;the&nbsp;test&nbsp;will&nbsp;be&nbsp;disabled&nbsp;if&nbsp;ANY&nbsp;of&nbsp;the&nbsp;args&nbsp;match&nbsp;the<br>
-browser&nbsp;type,&nbsp;OS&nbsp;name&nbsp;or&nbsp;OS&nbsp;version:<br>
-&nbsp;&nbsp;@<a href="#-Disabled">Disabled</a>('canary')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Disabled&nbsp;for&nbsp;canary&nbsp;browsers<br>
-&nbsp;&nbsp;@<a href="#-Disabled">Disabled</a>('win')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Disabled&nbsp;on&nbsp;Windows.<br>
-&nbsp;&nbsp;@<a href="#-Disabled">Disabled</a>('win',&nbsp;'linux')&nbsp;&nbsp;#&nbsp;Disabled&nbsp;on&nbsp;both&nbsp;Windows&nbsp;and&nbsp;Linux.<br>
-&nbsp;&nbsp;@<a href="#-Disabled">Disabled</a>('mavericks')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Disabled&nbsp;on&nbsp;Mac&nbsp;Mavericks&nbsp;(10.9)&nbsp;only.<br>
-&nbsp;&nbsp;@<a href="#-Disabled">Disabled</a>('all')&nbsp;&nbsp;#&nbsp;Unconditionally&nbsp;disabled.</tt></dd></dl>
- <dl><dt><a name="-Enabled"><strong>Enabled</strong></a>(*args)</dt><dd><tt>Decorator&nbsp;for&nbsp;enabling&nbsp;tests/benchmarks.<br>
-&nbsp;<br>
-The&nbsp;test&nbsp;will&nbsp;be&nbsp;enabled&nbsp;if&nbsp;ANY&nbsp;of&nbsp;the&nbsp;args&nbsp;match&nbsp;the&nbsp;browser&nbsp;type,&nbsp;OS&nbsp;name<br>
-or&nbsp;OS&nbsp;version:<br>
-&nbsp;&nbsp;@<a href="#-Enabled">Enabled</a>('canary')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Enabled&nbsp;only&nbsp;for&nbsp;canary&nbsp;browsers<br>
-&nbsp;&nbsp;@<a href="#-Enabled">Enabled</a>('win')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Enabled&nbsp;only&nbsp;on&nbsp;Windows.<br>
-&nbsp;&nbsp;@<a href="#-Enabled">Enabled</a>('win',&nbsp;'linux')&nbsp;&nbsp;#&nbsp;Enabled&nbsp;only&nbsp;on&nbsp;Windows&nbsp;or&nbsp;Linux.<br>
-&nbsp;&nbsp;@<a href="#-Enabled">Enabled</a>('mavericks')&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Enabled&nbsp;only&nbsp;on&nbsp;Mac&nbsp;Mavericks&nbsp;(10.9).</tt></dd></dl>
- <dl><dt><a name="-IsEnabled"><strong>IsEnabled</strong></a>(test, possible_browser)</dt><dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;|test|&nbsp;is&nbsp;enabled&nbsp;given&nbsp;the&nbsp;|possible_browser|.<br>
-&nbsp;<br>
-Use&nbsp;to&nbsp;respect&nbsp;the&nbsp;@Enabled&nbsp;/&nbsp;@Disabled&nbsp;decorators.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;test:&nbsp;A&nbsp;function&nbsp;or&nbsp;class&nbsp;that&nbsp;may&nbsp;contain&nbsp;_disabled_strings&nbsp;and/or<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_enabled_strings&nbsp;attributes.<br>
-&nbsp;&nbsp;possible_browser:&nbsp;A&nbsp;PossibleBrowser&nbsp;to&nbsp;check&nbsp;whether&nbsp;|test|&nbsp;may&nbsp;run&nbsp;against.</tt></dd></dl>
- <dl><dt><a name="-Isolated"><strong>Isolated</strong></a>(*args)</dt><dd><tt>Decorator&nbsp;for&nbsp;noting&nbsp;that&nbsp;tests&nbsp;must&nbsp;be&nbsp;run&nbsp;in&nbsp;isolation.<br>
-&nbsp;<br>
-The&nbsp;test&nbsp;will&nbsp;be&nbsp;run&nbsp;by&nbsp;itself&nbsp;(not&nbsp;concurrently&nbsp;with&nbsp;any&nbsp;other&nbsp;tests)<br>
-if&nbsp;ANY&nbsp;of&nbsp;the&nbsp;args&nbsp;match&nbsp;the&nbsp;browser&nbsp;type,&nbsp;OS&nbsp;name,&nbsp;or&nbsp;OS&nbsp;version.</tt></dd></dl>
- <dl><dt><a name="-ShouldBeIsolated"><strong>ShouldBeIsolated</strong></a>(test, possible_browser)</dt></dl>
- <dl><dt><a name="-ShouldSkip"><strong>ShouldSkip</strong></a>(test, possible_browser)</dt><dd><tt>Returns&nbsp;whether&nbsp;the&nbsp;test&nbsp;should&nbsp;be&nbsp;skipped&nbsp;and&nbsp;the&nbsp;reason&nbsp;for&nbsp;it.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.html b/catapult/telemetry/docs/pydoc/telemetry.html
deleted file mode 100644
index e1962d2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.html
+++ /dev/null
@@ -1,44 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>telemetry</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/__init__.py">telemetry/__init__.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;library&nbsp;for&nbsp;cross-platform&nbsp;browser&nbsp;tests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.android.html"><strong>android</strong>&nbsp;(package)</a><br>
-<a href="telemetry.benchmark.html">benchmark</a><br>
-<a href="telemetry.benchmark_run_unittest.html">benchmark_run_unittest</a><br>
-<a href="telemetry.benchmark_runner.html">benchmark_runner</a><br>
-<a href="telemetry.benchmark_runner_unittest.html">benchmark_runner_unittest</a><br>
-<a href="telemetry.benchmark_unittest.html">benchmark_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.html"><strong>core</strong>&nbsp;(package)</a><br>
-<a href="telemetry.decorators.html">decorators</a><br>
-<a href="telemetry.decorators_unittest.html">decorators_unittest</a><br>
-<a href="telemetry.internal.html"><strong>internal</strong>&nbsp;(package)</a><br>
-<a href="telemetry.page.html"><strong>page</strong>&nbsp;(package)</a><br>
-<a href="telemetry.project_config.html">project_config</a><br>
-</td><td width="25%" valign=top><a href="telemetry.record_wpr.html">record_wpr</a><br>
-<a href="telemetry.record_wpr_unittest.html">record_wpr_unittest</a><br>
-<a href="telemetry.story.html"><strong>story</strong>&nbsp;(package)</a><br>
-<a href="telemetry.telemetry_dependencies_unittest.html">telemetry_dependencies_unittest</a><br>
-<a href="telemetry.testing.html"><strong>testing</strong>&nbsp;(package)</a><br>
-<a href="telemetry.timeline.html"><strong>timeline</strong>&nbsp;(package)</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.html"><strong>util</strong>&nbsp;(package)</a><br>
-<a href="telemetry.value.html"><strong>value</strong>&nbsp;(package)</a><br>
-<a href="telemetry.web_perf.html"><strong>web_perf</strong>&nbsp;(package)</a><br>
-<a href="telemetry.wpr.html"><strong>wpr</strong>&nbsp;(package)</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.drag.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.drag.html
deleted file mode 100644
index 3169961..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.drag.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.drag</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.drag</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/drag.py">telemetry/internal/actions/drag.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;Telemetry&nbsp;page_action&nbsp;that&nbsp;performs&nbsp;the&nbsp;"drag"&nbsp;action&nbsp;on&nbsp;pages.<br>
-&nbsp;<br>
-Action&nbsp;parameters&nbsp;are:<br>
--&nbsp;selector:&nbsp;If&nbsp;no&nbsp;selector&nbsp;is&nbsp;defined&nbsp;then&nbsp;the&nbsp;action&nbsp;attempts&nbsp;to&nbsp;drag&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document&nbsp;element&nbsp;on&nbsp;the&nbsp;page.<br>
--&nbsp;element_function:&nbsp;CSS&nbsp;selector&nbsp;used&nbsp;to&nbsp;evaluate&nbsp;callback&nbsp;when&nbsp;test&nbsp;completes<br>
--&nbsp;text:&nbsp;The&nbsp;element&nbsp;with&nbsp;exact&nbsp;text&nbsp;is&nbsp;selected.<br>
--&nbsp;left_start_ratio:&nbsp;ratio&nbsp;of&nbsp;start&nbsp;point's&nbsp;left&nbsp;coordinate&nbsp;to&nbsp;the&nbsp;element<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;width.<br>
--&nbsp;top_start_ratio:&nbsp;ratio&nbsp;of&nbsp;start&nbsp;point's&nbsp;top&nbsp;coordinate&nbsp;to&nbsp;the&nbsp;element&nbsp;height.<br>
--&nbsp;left_end_ratio:&nbsp;ratio&nbsp;of&nbsp;end&nbsp;point's&nbsp;left&nbsp;coordinate&nbsp;to&nbsp;the&nbsp;element&nbsp;width.<br>
--&nbsp;left_end_ratio:&nbsp;ratio&nbsp;of&nbsp;end&nbsp;point's&nbsp;top&nbsp;coordinate&nbsp;to&nbsp;the&nbsp;element&nbsp;height.<br>
--&nbsp;speed_in_pixels_per_second:&nbsp;speed&nbsp;of&nbsp;the&nbsp;drag&nbsp;gesture&nbsp;in&nbsp;pixels&nbsp;per&nbsp;second.<br>
--&nbsp;use_touch:&nbsp;boolean&nbsp;value&nbsp;to&nbsp;specify&nbsp;if&nbsp;gesture&nbsp;should&nbsp;use&nbsp;touch&nbsp;input&nbsp;or&nbsp;not.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.drag.html#DragAction">DragAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DragAction">class <strong>DragAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.drag.html#DragAction">DragAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DragAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="DragAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="DragAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=None</font>, top_start_ratio<font color="#909090">=None</font>, left_end_ratio<font color="#909090">=None</font>, top_end_ratio<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>, use_touch<font color="#909090">=False</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="DragAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.html
deleted file mode 100644
index 0a52825..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.html
+++ /dev/null
@@ -1,52 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.actions</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.actions</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/__init__.py">telemetry/internal/actions/__init__.py</a></font></td></tr></table>
-    <p></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.action_runner_unittest.html">action_runner_unittest</a><br>
-<a href="telemetry.internal.actions.drag.html">drag</a><br>
-<a href="telemetry.internal.actions.drag_unittest.html">drag_unittest</a><br>
-<a href="telemetry.internal.actions.javascript_click.html">javascript_click</a><br>
-<a href="telemetry.internal.actions.load_media.html">load_media</a><br>
-<a href="telemetry.internal.actions.load_media_unittest.html">load_media_unittest</a><br>
-<a href="telemetry.internal.actions.loop.html">loop</a><br>
-<a href="telemetry.internal.actions.loop_unittest.html">loop_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.media_action.html">media_action</a><br>
-<a href="telemetry.internal.actions.mouse_click.html">mouse_click</a><br>
-<a href="telemetry.internal.actions.mouse_click_unittest.html">mouse_click_unittest</a><br>
-<a href="telemetry.internal.actions.navigate.html">navigate</a><br>
-<a href="telemetry.internal.actions.navigate_unittest.html">navigate_unittest</a><br>
-<a href="telemetry.internal.actions.page_action.html">page_action</a><br>
-<a href="telemetry.internal.actions.page_action_unittest.html">page_action_unittest</a><br>
-<a href="telemetry.internal.actions.pinch.html">pinch</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.pinch_unittest.html">pinch_unittest</a><br>
-<a href="telemetry.internal.actions.play.html">play</a><br>
-<a href="telemetry.internal.actions.play_unittest.html">play_unittest</a><br>
-<a href="telemetry.internal.actions.repaint_continuously.html">repaint_continuously</a><br>
-<a href="telemetry.internal.actions.repeatable_scroll.html">repeatable_scroll</a><br>
-<a href="telemetry.internal.actions.repeatable_scroll_unittest.html">repeatable_scroll_unittest</a><br>
-<a href="telemetry.internal.actions.scroll.html">scroll</a><br>
-<a href="telemetry.internal.actions.scroll_bounce.html">scroll_bounce</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.scroll_unittest.html">scroll_unittest</a><br>
-<a href="telemetry.internal.actions.seek.html">seek</a><br>
-<a href="telemetry.internal.actions.seek_unittest.html">seek_unittest</a><br>
-<a href="telemetry.internal.actions.swipe.html">swipe</a><br>
-<a href="telemetry.internal.actions.tap.html">tap</a><br>
-<a href="telemetry.internal.actions.wait.html">wait</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.javascript_click.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.javascript_click.html
deleted file mode 100644
index 4765ecc..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.javascript_click.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.javascript_click</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.javascript_click</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/javascript_click.py">telemetry/internal/actions/javascript_click.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.javascript_click.html#ClickElementAction">ClickElementAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ClickElementAction">class <strong>ClickElementAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.javascript_click.html#ClickElementAction">ClickElementAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ClickElementAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="ClickElementAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="ClickElementAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="ClickElementAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;action-specific&nbsp;setup&nbsp;before<br>
-Test.WillRunAction&nbsp;is&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.load_media.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.load_media.html
deleted file mode 100644
index 7830363..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.load_media.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.load_media</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.load_media</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/load_media.py">telemetry/internal/actions/load_media.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.media_action.html">telemetry.internal.actions.media_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.load_media.html#LoadMediaAction">LoadMediaAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LoadMediaAction">class <strong>LoadMediaAction</strong></a>(<a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>For&nbsp;calling&nbsp;load()&nbsp;on&nbsp;media&nbsp;elements&nbsp;and&nbsp;waiting&nbsp;for&nbsp;an&nbsp;event&nbsp;to&nbsp;fire.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.load_media.html#LoadMediaAction">LoadMediaAction</a></dd>
-<dd><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="LoadMediaAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="LoadMediaAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Load&nbsp;the&nbsp;JS&nbsp;code&nbsp;prior&nbsp;to&nbsp;running&nbsp;the&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="LoadMediaAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=0</font>, event_to_await<font color="#909090">='canplaythrough'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>:<br>
-<dl><dt><a name="LoadMediaAction-HasEventCompletedOrError"><strong>HasEventCompletedOrError</strong></a>(self, tab, selector, event_name)</dt></dl>
-
-<dl><dt><a name="LoadMediaAction-LoadJS"><strong>LoadJS</strong></a>(self, tab, js_file_name)</dt><dd><tt>Loads&nbsp;and&nbsp;executes&nbsp;a&nbsp;JS&nbsp;file&nbsp;in&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="LoadMediaAction-WaitForEvent"><strong>WaitForEvent</strong></a>(self, tab, selector, event_name, timeout_in_seconds)</dt><dd><tt>Halts&nbsp;media&nbsp;action&nbsp;until&nbsp;the&nbsp;selector's&nbsp;event&nbsp;is&nbsp;fired.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;tab:&nbsp;The&nbsp;tab&nbsp;to&nbsp;check&nbsp;for&nbsp;event&nbsp;on.<br>
-&nbsp;&nbsp;selector:&nbsp;Media&nbsp;element&nbsp;selector.<br>
-&nbsp;&nbsp;event_name:&nbsp;Name&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;check&nbsp;if&nbsp;fired&nbsp;or&nbsp;not.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Timeout&nbsp;to&nbsp;check&nbsp;for&nbsp;event,&nbsp;throws&nbsp;an&nbsp;exception&nbsp;if<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fired.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="LoadMediaAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.loop.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.loop.html
deleted file mode 100644
index ca62f46..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.loop.html
+++ /dev/null
@@ -1,95 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.loop</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.loop</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/loop.py">telemetry/internal/actions/loop.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;Telemetry&nbsp;page_action&nbsp;that&nbsp;loops&nbsp;media&nbsp;playback.<br>
-&nbsp;<br>
-Action&nbsp;parameters&nbsp;are:<br>
--&nbsp;loop_count:&nbsp;The&nbsp;number&nbsp;of&nbsp;times&nbsp;to&nbsp;loop&nbsp;media.<br>
--&nbsp;selector:&nbsp;If&nbsp;no&nbsp;selector&nbsp;is&nbsp;defined&nbsp;then&nbsp;the&nbsp;action&nbsp;attempts&nbsp;to&nbsp;loop&nbsp;the&nbsp;first<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;media&nbsp;element&nbsp;on&nbsp;the&nbsp;page.&nbsp;If&nbsp;'all'&nbsp;then&nbsp;loop&nbsp;all&nbsp;media&nbsp;elements.<br>
--&nbsp;timeout_in_seconds:&nbsp;Timeout&nbsp;to&nbsp;wait&nbsp;for&nbsp;media&nbsp;to&nbsp;loop.&nbsp;Default&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;60&nbsp;sec&nbsp;x&nbsp;loop_count.&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.media_action.html">telemetry.internal.actions.media_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.loop.html#LoopAction">LoopAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LoopAction">class <strong>LoopAction</strong></a>(<a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.loop.html#LoopAction">LoopAction</a></dd>
-<dd><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="LoopAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="LoopAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Load&nbsp;the&nbsp;media&nbsp;metrics&nbsp;JS&nbsp;code&nbsp;prior&nbsp;to&nbsp;running&nbsp;the&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="LoopAction-__init__"><strong>__init__</strong></a>(self, loop_count, selector<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>:<br>
-<dl><dt><a name="LoopAction-HasEventCompletedOrError"><strong>HasEventCompletedOrError</strong></a>(self, tab, selector, event_name)</dt></dl>
-
-<dl><dt><a name="LoopAction-LoadJS"><strong>LoadJS</strong></a>(self, tab, js_file_name)</dt><dd><tt>Loads&nbsp;and&nbsp;executes&nbsp;a&nbsp;JS&nbsp;file&nbsp;in&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="LoopAction-WaitForEvent"><strong>WaitForEvent</strong></a>(self, tab, selector, event_name, timeout_in_seconds)</dt><dd><tt>Halts&nbsp;media&nbsp;action&nbsp;until&nbsp;the&nbsp;selector's&nbsp;event&nbsp;is&nbsp;fired.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;tab:&nbsp;The&nbsp;tab&nbsp;to&nbsp;check&nbsp;for&nbsp;event&nbsp;on.<br>
-&nbsp;&nbsp;selector:&nbsp;Media&nbsp;element&nbsp;selector.<br>
-&nbsp;&nbsp;event_name:&nbsp;Name&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;check&nbsp;if&nbsp;fired&nbsp;or&nbsp;not.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Timeout&nbsp;to&nbsp;check&nbsp;for&nbsp;event,&nbsp;throws&nbsp;an&nbsp;exception&nbsp;if<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fired.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="LoopAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.media_action.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.media_action.html
deleted file mode 100644
index 80b6ea3..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.media_action.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.media_action</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.media_action</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/media_action.py">telemetry/internal/actions/media_action.py</a></font></td></tr></table>
-    <p><tt>Common&nbsp;media&nbsp;action&nbsp;functions.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.media_action.html#MediaAction">MediaAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MediaAction">class <strong>MediaAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.media_action.html#MediaAction">MediaAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MediaAction-HasEventCompletedOrError"><strong>HasEventCompletedOrError</strong></a>(self, tab, selector, event_name)</dt></dl>
-
-<dl><dt><a name="MediaAction-LoadJS"><strong>LoadJS</strong></a>(self, tab, js_file_name)</dt><dd><tt>Loads&nbsp;and&nbsp;executes&nbsp;a&nbsp;JS&nbsp;file&nbsp;in&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="MediaAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="MediaAction-WaitForEvent"><strong>WaitForEvent</strong></a>(self, tab, selector, event_name, timeout_in_seconds)</dt><dd><tt>Halts&nbsp;media&nbsp;action&nbsp;until&nbsp;the&nbsp;selector's&nbsp;event&nbsp;is&nbsp;fired.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;tab:&nbsp;The&nbsp;tab&nbsp;to&nbsp;check&nbsp;for&nbsp;event&nbsp;on.<br>
-&nbsp;&nbsp;selector:&nbsp;Media&nbsp;element&nbsp;selector.<br>
-&nbsp;&nbsp;event_name:&nbsp;Name&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;check&nbsp;if&nbsp;fired&nbsp;or&nbsp;not.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Timeout&nbsp;to&nbsp;check&nbsp;for&nbsp;event,&nbsp;throws&nbsp;an&nbsp;exception&nbsp;if<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fired.</tt></dd></dl>
-
-<dl><dt><a name="MediaAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Loads&nbsp;the&nbsp;common&nbsp;media&nbsp;action&nbsp;JS&nbsp;code&nbsp;prior&nbsp;to&nbsp;running&nbsp;the&nbsp;action.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="MediaAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.mouse_click.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.mouse_click.html
deleted file mode 100644
index 0d2d5b5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.mouse_click.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.mouse_click</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.mouse_click</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/mouse_click.py">telemetry/internal/actions/mouse_click.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.mouse_click.html#MouseClickAction">MouseClickAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MouseClickAction">class <strong>MouseClickAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.mouse_click.html#MouseClickAction">MouseClickAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MouseClickAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="MouseClickAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Load&nbsp;the&nbsp;mouse&nbsp;click&nbsp;JS&nbsp;code&nbsp;prior&nbsp;to&nbsp;running&nbsp;the&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="MouseClickAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="MouseClickAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-read_js"><strong>read_js</strong></a>()</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.navigate.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.navigate.html
deleted file mode 100644
index 3c11b2a..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.navigate.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.navigate</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.navigate</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/navigate.py">telemetry/internal/actions/navigate.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.navigate.html#NavigateAction">NavigateAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NavigateAction">class <strong>NavigateAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.navigate.html#NavigateAction">NavigateAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="NavigateAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="NavigateAction-__init__"><strong>__init__</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=60</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="NavigateAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="NavigateAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;action-specific&nbsp;setup&nbsp;before<br>
-Test.WillRunAction&nbsp;is&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.page_action.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.page_action.html
deleted file mode 100644
index 40ba46f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.page_action.html
+++ /dev/null
@@ -1,235 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.page_action</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.page_action</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/page_action.py">telemetry/internal/actions/page_action.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">PageAction</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageActionFailed">PageActionFailed</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageActionNotSupported">PageActionNotSupported</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PageAction">class <strong>PageAction</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;action&nbsp;that&nbsp;a&nbsp;user&nbsp;might&nbsp;try&nbsp;to&nbsp;perform&nbsp;to&nbsp;a&nbsp;page.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PageAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="PageAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="PageAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;action-specific&nbsp;setup&nbsp;before<br>
-Test.WillRunAction&nbsp;is&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PageActionFailed">class <strong>PageActionFailed</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.page_action.html#PageActionFailed">PageActionFailed</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="PageActionFailed-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#PageActionFailed-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="PageActionFailed-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PageActionFailed-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PageActionFailed-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionFailed-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="PageActionFailed-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PageActionNotSupported">class <strong>PageActionNotSupported</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.page_action.html#PageActionNotSupported">PageActionNotSupported</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="PageActionNotSupported-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#PageActionNotSupported-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="PageActionNotSupported-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PageActionNotSupported-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PageActionNotSupported-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#PageActionNotSupported-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="PageActionNotSupported-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-EvaluateCallbackWithElement"><strong>EvaluateCallbackWithElement</strong></a>(tab, callback_js, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, wait<font color="#909090">=False</font>, timeout_in_seconds<font color="#909090">=60</font>)</dt><dd><tt>Evaluates&nbsp;the&nbsp;JavaScript&nbsp;callback&nbsp;with&nbsp;the&nbsp;given&nbsp;element.<br>
-&nbsp;<br>
-The&nbsp;element&nbsp;may&nbsp;be&nbsp;selected&nbsp;via&nbsp;selector,&nbsp;text,&nbsp;or&nbsp;element_function.<br>
-Only&nbsp;one&nbsp;of&nbsp;these&nbsp;arguments&nbsp;must&nbsp;be&nbsp;specified.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;callback's&nbsp;return&nbsp;value,&nbsp;if&nbsp;any.&nbsp;The&nbsp;return&nbsp;value&nbsp;must&nbsp;be<br>
-&nbsp;&nbsp;convertible&nbsp;to&nbsp;JSON.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;tab:&nbsp;A&nbsp;telemetry.core.Tab&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;&nbsp;callback_js:&nbsp;The&nbsp;JavaScript&nbsp;callback&nbsp;to&nbsp;call&nbsp;(as&nbsp;string).<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;callback&nbsp;receive&nbsp;2&nbsp;parameters:&nbsp;the&nbsp;element,&nbsp;and&nbsp;information<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string&nbsp;about&nbsp;what&nbsp;method&nbsp;was&nbsp;used&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Example:&nbsp;'''<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;function(element,&nbsp;info)&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!element)&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;Error('Can&nbsp;not&nbsp;find&nbsp;element:&nbsp;'&nbsp;+&nbsp;info);<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;element.click()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}'''<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;})()'.<br>
-&nbsp;&nbsp;wait:&nbsp;Whether&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;return&nbsp;value&nbsp;to&nbsp;be&nbsp;true.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;The&nbsp;timeout&nbsp;for&nbsp;wait&nbsp;(if&nbsp;waiting).</tt></dd></dl>
- <dl><dt><a name="-IsGestureSourceTypeSupported"><strong>IsGestureSourceTypeSupported</strong></a>(*args, **kwargs)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>GESTURE_SOURCE_DEFAULT</strong> = 'DEFAULT'<br>
-<strong>GESTURE_SOURCE_MOUSE</strong> = 'MOUSE'<br>
-<strong>GESTURE_SOURCE_TOUCH</strong> = 'TOUCH'<br>
-<strong>SUPPORTED_GESTURE_SOURCES</strong> = ('DEFAULT', 'MOUSE', 'TOUCH')</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.pinch.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.pinch.html
deleted file mode 100644
index c046f17..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.pinch.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.pinch</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.pinch</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/pinch.py">telemetry/internal/actions/pinch.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.pinch.html#PinchAction">PinchAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PinchAction">class <strong>PinchAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.pinch.html#PinchAction">PinchAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PinchAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="PinchAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="PinchAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_anchor_ratio<font color="#909090">=0.5</font>, top_anchor_ratio<font color="#909090">=0.5</font>, scale_factor<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="PinchAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.play.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.play.html
deleted file mode 100644
index c810155..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.play.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.play</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.play</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/play.py">telemetry/internal/actions/play.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;Telemetry&nbsp;page_action&nbsp;that&nbsp;performs&nbsp;the&nbsp;"play"&nbsp;action&nbsp;on&nbsp;media&nbsp;elements.<br>
-&nbsp;<br>
-Media&nbsp;elements&nbsp;can&nbsp;be&nbsp;specified&nbsp;by&nbsp;a&nbsp;selector&nbsp;argument.&nbsp;If&nbsp;no&nbsp;selector&nbsp;is<br>
-defined&nbsp;then&nbsp;then&nbsp;the&nbsp;action&nbsp;attempts&nbsp;to&nbsp;play&nbsp;the&nbsp;first&nbsp;video&nbsp;element&nbsp;or&nbsp;audio<br>
-element&nbsp;on&nbsp;the&nbsp;page.&nbsp;A&nbsp;selector&nbsp;can&nbsp;also&nbsp;be&nbsp;'all'&nbsp;to&nbsp;play&nbsp;all&nbsp;media&nbsp;elements.<br>
-&nbsp;<br>
-Other&nbsp;arguments&nbsp;to&nbsp;use&nbsp;are:&nbsp;playing_event_timeout_in_seconds&nbsp;and<br>
-ended_event_timeout_in_seconds,&nbsp;which&nbsp;forces&nbsp;the&nbsp;action&nbsp;to&nbsp;wait&nbsp;until<br>
-playing&nbsp;and&nbsp;ended&nbsp;events&nbsp;get&nbsp;fired&nbsp;respectively.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.media_action.html">telemetry.internal.actions.media_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.play.html#PlayAction">PlayAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PlayAction">class <strong>PlayAction</strong></a>(<a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.play.html#PlayAction">PlayAction</a></dd>
-<dd><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PlayAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="PlayAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Load&nbsp;the&nbsp;media&nbsp;metrics&nbsp;JS&nbsp;code&nbsp;prior&nbsp;to&nbsp;running&nbsp;the&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="PlayAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, playing_event_timeout_in_seconds<font color="#909090">=0</font>, ended_event_timeout_in_seconds<font color="#909090">=0</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>:<br>
-<dl><dt><a name="PlayAction-HasEventCompletedOrError"><strong>HasEventCompletedOrError</strong></a>(self, tab, selector, event_name)</dt></dl>
-
-<dl><dt><a name="PlayAction-LoadJS"><strong>LoadJS</strong></a>(self, tab, js_file_name)</dt><dd><tt>Loads&nbsp;and&nbsp;executes&nbsp;a&nbsp;JS&nbsp;file&nbsp;in&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="PlayAction-WaitForEvent"><strong>WaitForEvent</strong></a>(self, tab, selector, event_name, timeout_in_seconds)</dt><dd><tt>Halts&nbsp;media&nbsp;action&nbsp;until&nbsp;the&nbsp;selector's&nbsp;event&nbsp;is&nbsp;fired.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;tab:&nbsp;The&nbsp;tab&nbsp;to&nbsp;check&nbsp;for&nbsp;event&nbsp;on.<br>
-&nbsp;&nbsp;selector:&nbsp;Media&nbsp;element&nbsp;selector.<br>
-&nbsp;&nbsp;event_name:&nbsp;Name&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;check&nbsp;if&nbsp;fired&nbsp;or&nbsp;not.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Timeout&nbsp;to&nbsp;check&nbsp;for&nbsp;event,&nbsp;throws&nbsp;an&nbsp;exception&nbsp;if<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fired.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="PlayAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.repaint_continuously.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.repaint_continuously.html
deleted file mode 100644
index 4a1e7dc..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.repaint_continuously.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.repaint_continuously</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.repaint_continuously</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/repaint_continuously.py">telemetry/internal/actions/repaint_continuously.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.repaint_continuously.html#RepaintContinuouslyAction">RepaintContinuouslyAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RepaintContinuouslyAction">class <strong>RepaintContinuouslyAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Continuously&nbsp;repaints&nbsp;the&nbsp;visible&nbsp;content&nbsp;by&nbsp;requesting&nbsp;animation&nbsp;frames<br>
-until&nbsp;self.<strong>seconds</strong>&nbsp;have&nbsp;elapsed&nbsp;AND&nbsp;at&nbsp;least&nbsp;three&nbsp;RAFs&nbsp;have&nbsp;been&nbsp;fired.&nbsp;Times<br>
-out&nbsp;after&nbsp;max(60,&nbsp;self.<strong>seconds</strong>),&nbsp;if&nbsp;less&nbsp;than&nbsp;three&nbsp;RAFs&nbsp;were&nbsp;fired.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.repaint_continuously.html#RepaintContinuouslyAction">RepaintContinuouslyAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="RepaintContinuouslyAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="RepaintContinuouslyAction-__init__"><strong>__init__</strong></a>(self, seconds)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="RepaintContinuouslyAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="RepaintContinuouslyAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;action-specific&nbsp;setup&nbsp;before<br>
-Test.WillRunAction&nbsp;is&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.repeatable_scroll.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.repeatable_scroll.html
deleted file mode 100644
index 22179ba..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.repeatable_scroll.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.repeatable_scroll</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.repeatable_scroll</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/repeatable_scroll.py">telemetry/internal/actions/repeatable_scroll.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.timeline_interaction_record.html">telemetry.web_perf.timeline_interaction_record</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.repeatable_scroll.html#RepeatableScrollAction">RepeatableScrollAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RepeatableScrollAction">class <strong>RepeatableScrollAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.repeatable_scroll.html#RepeatableScrollAction">RepeatableScrollAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="RepeatableScrollAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="RepeatableScrollAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="RepeatableScrollAction-__init__"><strong>__init__</strong></a>(self, x_scroll_distance_ratio<font color="#909090">=0.0</font>, y_scroll_distance_ratio<font color="#909090">=0.5</font>, repeat_count<font color="#909090">=0</font>, repeat_delay_ms<font color="#909090">=250</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="RepeatableScrollAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.scroll.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.scroll.html
deleted file mode 100644
index 4240094..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.scroll.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.scroll</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.scroll</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/scroll.py">telemetry/internal/actions/scroll.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.scroll.html#ScrollAction">ScrollAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ScrollAction">class <strong>ScrollAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.scroll.html#ScrollAction">ScrollAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ScrollAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="ScrollAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="ScrollAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='down'</font>, distance<font color="#909090">=None</font>, distance_expr<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>, use_touch<font color="#909090">=False</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt><dd><tt>#&nbsp;TODO(chrishenry):&nbsp;Ignore&nbsp;attributes,&nbsp;to&nbsp;be&nbsp;deleted&nbsp;when&nbsp;usage&nbsp;in<br>
-#&nbsp;other&nbsp;repo&nbsp;is&nbsp;cleaned&nbsp;up.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="ScrollAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.scroll_bounce.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.scroll_bounce.html
deleted file mode 100644
index bb44b14..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.scroll_bounce.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.scroll_bounce</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.scroll_bounce</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/scroll_bounce.py">telemetry/internal/actions/scroll_bounce.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.scroll_bounce.html#ScrollBounceAction">ScrollBounceAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ScrollBounceAction">class <strong>ScrollBounceAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.scroll_bounce.html#ScrollBounceAction">ScrollBounceAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ScrollBounceAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="ScrollBounceAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="ScrollBounceAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='down'</font>, distance<font color="#909090">=100</font>, overscroll<font color="#909090">=10</font>, repeat_count<font color="#909090">=10</font>, speed_in_pixels_per_second<font color="#909090">=400</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="ScrollBounceAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.seek.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.seek.html
deleted file mode 100644
index 42b7d31..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.seek.html
+++ /dev/null
@@ -1,100 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.seek</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.seek</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/seek.py">telemetry/internal/actions/seek.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;Telemetry&nbsp;page_action&nbsp;that&nbsp;performs&nbsp;the&nbsp;"seek"&nbsp;action&nbsp;on&nbsp;media&nbsp;elements.<br>
-&nbsp;<br>
-Action&nbsp;parameters&nbsp;are:<br>
--&nbsp;seconds:&nbsp;The&nbsp;media&nbsp;time&nbsp;to&nbsp;seek&nbsp;to.&nbsp;Test&nbsp;fails&nbsp;if&nbsp;not&nbsp;provided.<br>
--&nbsp;selector:&nbsp;If&nbsp;no&nbsp;selector&nbsp;is&nbsp;defined&nbsp;then&nbsp;the&nbsp;action&nbsp;attempts&nbsp;to&nbsp;seek&nbsp;the&nbsp;first<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;media&nbsp;element&nbsp;on&nbsp;the&nbsp;page.&nbsp;If&nbsp;'all'&nbsp;then&nbsp;seek&nbsp;all&nbsp;media&nbsp;elements.<br>
--&nbsp;timeout_in_seconds:&nbsp;Maximum&nbsp;waiting&nbsp;time&nbsp;for&nbsp;the&nbsp;"seeked"&nbsp;event<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(dispatched&nbsp;when&nbsp;the&nbsp;seeked&nbsp;operation&nbsp;completes)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;fired.&nbsp;&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.<br>
--&nbsp;log_time:&nbsp;If&nbsp;true&nbsp;the&nbsp;seek&nbsp;time&nbsp;is&nbsp;recorded,&nbsp;otherwise&nbsp;media<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;measurement&nbsp;will&nbsp;not&nbsp;be&nbsp;aware&nbsp;of&nbsp;the&nbsp;seek&nbsp;action.&nbsp;Used&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perform&nbsp;multiple&nbsp;seeks.&nbsp;Default&nbsp;true.<br>
--&nbsp;label:&nbsp;A&nbsp;suffix&nbsp;string&nbsp;to&nbsp;name&nbsp;the&nbsp;seek&nbsp;perf&nbsp;measurement.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.media_action.html">telemetry.internal.actions.media_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.seek.html#SeekAction">SeekAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SeekAction">class <strong>SeekAction</strong></a>(<a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.seek.html#SeekAction">SeekAction</a></dd>
-<dd><a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SeekAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="SeekAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Load&nbsp;the&nbsp;media&nbsp;metrics&nbsp;JS&nbsp;code&nbsp;prior&nbsp;to&nbsp;running&nbsp;the&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="SeekAction-__init__"><strong>__init__</strong></a>(self, seconds, selector<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=0</font>, log_time<font color="#909090">=True</font>, label<font color="#909090">=''</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.media_action.html#MediaAction">telemetry.internal.actions.media_action.MediaAction</a>:<br>
-<dl><dt><a name="SeekAction-HasEventCompletedOrError"><strong>HasEventCompletedOrError</strong></a>(self, tab, selector, event_name)</dt></dl>
-
-<dl><dt><a name="SeekAction-LoadJS"><strong>LoadJS</strong></a>(self, tab, js_file_name)</dt><dd><tt>Loads&nbsp;and&nbsp;executes&nbsp;a&nbsp;JS&nbsp;file&nbsp;in&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="SeekAction-WaitForEvent"><strong>WaitForEvent</strong></a>(self, tab, selector, event_name, timeout_in_seconds)</dt><dd><tt>Halts&nbsp;media&nbsp;action&nbsp;until&nbsp;the&nbsp;selector's&nbsp;event&nbsp;is&nbsp;fired.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;tab:&nbsp;The&nbsp;tab&nbsp;to&nbsp;check&nbsp;for&nbsp;event&nbsp;on.<br>
-&nbsp;&nbsp;selector:&nbsp;Media&nbsp;element&nbsp;selector.<br>
-&nbsp;&nbsp;event_name:&nbsp;Name&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;check&nbsp;if&nbsp;fired&nbsp;or&nbsp;not.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Timeout&nbsp;to&nbsp;check&nbsp;for&nbsp;event,&nbsp;throws&nbsp;an&nbsp;exception&nbsp;if<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;not&nbsp;fired.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="SeekAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.swipe.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.swipe.html
deleted file mode 100644
index fe542d5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.swipe.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.swipe</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.swipe</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/swipe.py">telemetry/internal/actions/swipe.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.swipe.html#SwipeAction">SwipeAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SwipeAction">class <strong>SwipeAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.swipe.html#SwipeAction">SwipeAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SwipeAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="SwipeAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="SwipeAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='left'</font>, distance<font color="#909090">=100</font>, speed_in_pixels_per_second<font color="#909090">=800</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="SwipeAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.tap.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.tap.html
deleted file mode 100644
index 166ac78..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.tap.html
+++ /dev/null
@@ -1,75 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.tap</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.tap</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/tap.py">telemetry/internal/actions/tap.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.tap.html#TapAction">TapAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TapAction">class <strong>TapAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.tap.html#TapAction">TapAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TapAction-HasElementSelector"><strong>HasElementSelector</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TapAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="TapAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="TapAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_position_percentage<font color="#909090">=0.5</font>, top_position_percentage<font color="#909090">=0.5</font>, duration_ms<font color="#909090">=50</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="TapAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.wait.html b/catapult/telemetry/docs/pydoc/telemetry.internal.actions.wait.html
deleted file mode 100644
index 6294c76..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.actions.wait.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.actions.wait</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.actions.html"><font color="#ffffff">actions</font></a>.wait</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/actions/wait.py">telemetry/internal/actions/wait.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.actions.wait.html#WaitForElementAction">WaitForElementAction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WaitForElementAction">class <strong>WaitForElementAction</strong></a>(<a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.actions.wait.html#WaitForElementAction">WaitForElementAction</a></dd>
-<dd><a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="WaitForElementAction-RunAction"><strong>RunAction</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="WaitForElementAction-__init__"><strong>__init__</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=60</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><a name="WaitForElementAction-CleanUp"><strong>CleanUp</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="WaitForElementAction-WillRunAction"><strong>WillRunAction</strong></a>(self, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;action-specific&nbsp;setup&nbsp;before<br>
-Test.WillRunAction&nbsp;is&nbsp;called.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.actions.page_action.html#PageAction">telemetry.internal.actions.page_action.PageAction</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.app.android_app.html b/catapult/telemetry/docs/pydoc/telemetry.internal.app.android_app.html
deleted file mode 100644
index 4aa1e0d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.app.android_app.html
+++ /dev/null
@@ -1,93 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.app.android_app</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.app.html"><font color="#ffffff">app</font></a>.android_app</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/app/android_app.py">telemetry/internal/app/android_app.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.app.html">telemetry.internal.app</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.android_app.html#AndroidApp">AndroidApp</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidApp">class <strong>AndroidApp</strong></a>(<a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;running&nbsp;android&nbsp;app&nbsp;instance&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;in&nbsp;a&nbsp;limited&nbsp;way.<br>
-&nbsp;<br>
-Be&nbsp;sure&nbsp;to&nbsp;clean&nbsp;up&nbsp;after&nbsp;yourself&nbsp;by&nbsp;calling&nbsp;<a href="#AndroidApp-Close">Close</a>()&nbsp;when&nbsp;you&nbsp;are&nbsp;done&nbsp;with<br>
-the&nbsp;app.&nbsp;Or&nbsp;better&nbsp;yet:<br>
-&nbsp;&nbsp;with&nbsp;possible_android_app.Create(options)&nbsp;as&nbsp;android_app:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;do&nbsp;all&nbsp;your&nbsp;operations&nbsp;on&nbsp;android_app&nbsp;here<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.app.android_app.html#AndroidApp">AndroidApp</a></dd>
-<dd><a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidApp-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidApp-GetProcess"><strong>GetProcess</strong></a>(self, subprocess_name)</dt><dd><tt>Returns&nbsp;the&nbsp;process&nbsp;with&nbsp;the&nbsp;specified&nbsp;subprocess&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="AndroidApp-GetProcesses"><strong>GetProcesses</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;current&nbsp;set&nbsp;of&nbsp;processes&nbsp;belonging&nbsp;to&nbsp;this&nbsp;app.</tt></dd></dl>
-
-<dl><dt><a name="AndroidApp-GetWebViews"><strong>GetWebViews</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;all&nbsp;WebViews&nbsp;belonging&nbsp;to&nbsp;all&nbsp;processes&nbsp;of&nbsp;the&nbsp;app.</tt></dd></dl>
-
-<dl><dt><a name="AndroidApp-__init__"><strong>__init__</strong></a>(self, app_backend, platform_backend)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>:<br>
-<dl><dt><a name="AndroidApp-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidApp-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidApp-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidApp-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.app.android_process.html b/catapult/telemetry/docs/pydoc/telemetry.internal.app.android_process.html
deleted file mode 100644
index 993c2d5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.app.android_process.html
+++ /dev/null
@@ -1,132 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.app.android_process</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.app.html"><font color="#ffffff">app</font></a>.android_process</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/app/android_process.py">telemetry/internal/app/android_process.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html">telemetry.internal.backends.chrome_inspector.devtools_client_backend</a><br>
-</td><td width="25%" valign=top><a href="devil.android.ports.html">devil.android.ports</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.android_process.html#AndroidProcess">AndroidProcess</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.android_process.html#WebViewNotFoundException">WebViewNotFoundException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidProcess">class <strong>AndroidProcess</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;single&nbsp;android&nbsp;process.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AndroidProcess-GetWebViews"><strong>GetWebViews</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidProcess-__init__"><strong>__init__</strong></a>(self, app_backend, pid, name)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebViewNotFoundException">class <strong>WebViewNotFoundException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.app.android_process.html#WebViewNotFoundException">WebViewNotFoundException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="WebViewNotFoundException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#WebViewNotFoundException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="WebViewNotFoundException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#WebViewNotFoundException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="WebViewNotFoundException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.app.html b/catapult/telemetry/docs/pydoc/telemetry.internal.app.html
deleted file mode 100644
index 460b3ff..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.app.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.app</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.app</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/app/__init__.py">telemetry/internal/app/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.app.android_app.html">android_app</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.app.android_app_unittest.html">android_app_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.app.android_process.html">android_process</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.app.possible_app.html">possible_app</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.html#App">App</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="App">class <strong>App</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;running&nbsp;application&nbsp;instance&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;in&nbsp;a&nbsp;limited&nbsp;way.<br>
-&nbsp;<br>
-Be&nbsp;sure&nbsp;to&nbsp;clean&nbsp;up&nbsp;after&nbsp;yourself&nbsp;by&nbsp;calling&nbsp;<a href="#App-Close">Close</a>()&nbsp;when&nbsp;you&nbsp;are&nbsp;done&nbsp;with<br>
-the&nbsp;app.&nbsp;Or&nbsp;better&nbsp;yet:<br>
-&nbsp;&nbsp;with&nbsp;possible_app.Create(options)&nbsp;as&nbsp;app:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;do&nbsp;all&nbsp;your&nbsp;operations&nbsp;on&nbsp;app&nbsp;here<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="App-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="App-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="App-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="App-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="App-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<dl><dt><a name="App-__init__"><strong>__init__</strong></a>(self, app_backend, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.app.possible_app.html b/catapult/telemetry/docs/pydoc/telemetry.internal.app.possible_app.html
deleted file mode 100644
index da762aa..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.app.possible_app.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.app.possible_app</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.app.html"><font color="#ffffff">app</font></a>.possible_app</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/app/possible_app.py">telemetry/internal/app/possible_app.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.possible_app.html#PossibleApp">PossibleApp</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleApp">class <strong>PossibleApp</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;factory&nbsp;class&nbsp;that&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;create&nbsp;a&nbsp;running&nbsp;instance&nbsp;of&nbsp;app.<br>
-&nbsp;<br>
-Call&nbsp;<a href="#PossibleApp-Create">Create</a>()&nbsp;to&nbsp;launch&nbsp;the&nbsp;app&nbsp;and&nbsp;begin&nbsp;manipulating&nbsp;it.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PossibleApp-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleApp-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt><dd><tt>Tests&nbsp;for&nbsp;extension&nbsp;support.</tt></dd></dl>
-
-<dl><dt><a name="PossibleApp-__init__"><strong>__init__</strong></a>(self, app_type, target_os)</dt></dl>
-
-<dl><dt><a name="PossibleApp-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_app_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_app_backend.html
deleted file mode 100644
index d2c2a06..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_app_backend.html
+++ /dev/null
@@ -1,111 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.android_app_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.android_app_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/android_app_backend.py">telemetry/internal/backends/android_app_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.android_browser_backend_settings.html">telemetry.internal.backends.android_browser_backend_settings</a><br>
-<a href="telemetry.internal.backends.android_command_line_backend.html">telemetry.internal.backends.android_command_line_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.app.android_process.html">telemetry.internal.app.android_process</a><br>
-<a href="telemetry.internal.backends.app_backend.html">telemetry.internal.backends.app_backend</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_app_backend.html#AndroidAppBackend">AndroidAppBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidAppBackend">class <strong>AndroidAppBackend</strong></a>(<a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.android_app_backend.html#AndroidAppBackend">AndroidAppBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidAppBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-GetProcess"><strong>GetProcess</strong></a>(self, subprocess_name)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-GetProcesses"><strong>GetProcesses</strong></a>(self, process_filter<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-GetWebViews"><strong>GetWebViews</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-GetWebviewStartupArgs"><strong>GetWebviewStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-Start"><strong>Start</strong></a>(self)</dt><dd><tt>Start&nbsp;an&nbsp;Android&nbsp;app&nbsp;and&nbsp;wait&nbsp;for&nbsp;it&nbsp;to&nbsp;finish&nbsp;launching.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;app&nbsp;has&nbsp;webviews,&nbsp;the&nbsp;app&nbsp;is&nbsp;launched&nbsp;with&nbsp;the&nbsp;suitable<br>
-command&nbsp;line&nbsp;arguments.<br>
-&nbsp;<br>
-AppStory&nbsp;derivations&nbsp;can&nbsp;customize&nbsp;the&nbsp;wait-for-ready-state&nbsp;to&nbsp;wait<br>
-for&nbsp;a&nbsp;more&nbsp;specific&nbsp;event&nbsp;if&nbsp;needed.</tt></dd></dl>
-
-<dl><dt><a name="AndroidAppBackend-__init__"><strong>__init__</strong></a>(self, android_platform_backend, start_intent, is_app_ready_predicate<font color="#909090">=None</font>, app_has_webviews<font color="#909090">=True</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>device</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="AndroidAppBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<dl><dt><a name="AndroidAppBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_browser_backend_settings.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_browser_backend_settings.html
deleted file mode 100644
index 771d1e0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_browser_backend_settings.html
+++ /dev/null
@@ -1,247 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.android_browser_backend_settings</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.android_browser_backend_settings</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/android_browser_backend_settings.py">telemetry/internal/backends/android_browser_backend_settings.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_browser_backend_settings.html#ChromeBackendSettings">ChromeBackendSettings</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_browser_backend_settings.html#ContentShellBackendSettings">ContentShellBackendSettings</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewBackendSettings">WebviewBackendSettings</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewShellBackendSettings">WebviewShellBackendSettings</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidBrowserBackendSettings">class <strong>AndroidBrowserBackendSettings</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AndroidBrowserBackendSettings-GetCommandLineFile"><strong>GetCommandLineFile</strong></a>(self, is_user_debug_build)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackendSettings-GetDevtoolsRemotePort"><strong>GetDevtoolsRemotePort</strong></a>(self, device)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackendSettings-__init__"><strong>__init__</strong></a>(self, activity, cmdline_file, package, pseudo_exec_name, supports_tab_control)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>profile_ignore_list</strong></dt>
-</dl>
-<dl><dt><strong>pseudo_exec_name</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChromeBackendSettings">class <strong>ChromeBackendSettings</strong></a>(<a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#ChromeBackendSettings">ChromeBackendSettings</a></dd>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ChromeBackendSettings-GetCommandLineFile"><strong>GetCommandLineFile</strong></a>(self, is_user_debug_build)</dt></dl>
-
-<dl><dt><a name="ChromeBackendSettings-GetDevtoolsRemotePort"><strong>GetDevtoolsRemotePort</strong></a>(self, device)</dt></dl>
-
-<dl><dt><a name="ChromeBackendSettings-__init__"><strong>__init__</strong></a>(self, package)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>profile_ignore_list</strong></dt>
-</dl>
-<dl><dt><strong>pseudo_exec_name</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ContentShellBackendSettings">class <strong>ContentShellBackendSettings</strong></a>(<a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#ContentShellBackendSettings">ContentShellBackendSettings</a></dd>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ContentShellBackendSettings-GetDevtoolsRemotePort"><strong>GetDevtoolsRemotePort</strong></a>(self, device)</dt></dl>
-
-<dl><dt><a name="ContentShellBackendSettings-__init__"><strong>__init__</strong></a>(self, package)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><a name="ContentShellBackendSettings-GetCommandLineFile"><strong>GetCommandLineFile</strong></a>(self, is_user_debug_build)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>profile_ignore_list</strong></dt>
-</dl>
-<dl><dt><strong>pseudo_exec_name</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebviewBackendSettings">class <strong>WebviewBackendSettings</strong></a>(<a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewBackendSettings">WebviewBackendSettings</a></dd>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="WebviewBackendSettings-GetDevtoolsRemotePort"><strong>GetDevtoolsRemotePort</strong></a>(self, device)</dt></dl>
-
-<dl><dt><a name="WebviewBackendSettings-__init__"><strong>__init__</strong></a>(self, package, activity<font color="#909090">='org.chromium.webview_shell.TelemetryActivity'</font>, cmdline_file<font color="#909090">='/data/local/tmp/webview-command-line'</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><a name="WebviewBackendSettings-GetCommandLineFile"><strong>GetCommandLineFile</strong></a>(self, is_user_debug_build)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>profile_ignore_list</strong></dt>
-</dl>
-<dl><dt><strong>pseudo_exec_name</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebviewShellBackendSettings">class <strong>WebviewShellBackendSettings</strong></a>(<a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewBackendSettings">WebviewBackendSettings</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewShellBackendSettings">WebviewShellBackendSettings</a></dd>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewBackendSettings">WebviewBackendSettings</a></dd>
-<dd><a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="WebviewShellBackendSettings-__init__"><strong>__init__</strong></a>(self, package)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#WebviewBackendSettings">WebviewBackendSettings</a>:<br>
-<dl><dt><a name="WebviewShellBackendSettings-GetDevtoolsRemotePort"><strong>GetDevtoolsRemotePort</strong></a>(self, device)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><a name="WebviewShellBackendSettings-GetCommandLineFile"><strong>GetCommandLineFile</strong></a>(self, is_user_debug_build)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.android_browser_backend_settings.html#AndroidBrowserBackendSettings">AndroidBrowserBackendSettings</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>profile_ignore_list</strong></dt>
-</dl>
-<dl><dt><strong>pseudo_exec_name</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_command_line_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_command_line_backend.html
deleted file mode 100644
index acb7d5d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.android_command_line_backend.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.android_command_line_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.android_command_line_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/android_command_line_backend.py">telemetry/internal/backends/android_command_line_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="pipes.html">pipes</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.android_command_line_backend.html#SetUpCommandLineFlags">SetUpCommandLineFlags</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SetUpCommandLineFlags">class <strong>SetUpCommandLineFlags</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;context&nbsp;manager&nbsp;for&nbsp;setting&nbsp;up&nbsp;the&nbsp;android&nbsp;command&nbsp;line&nbsp;flags.<br>
-&nbsp;<br>
-This&nbsp;provides&nbsp;a&nbsp;readable&nbsp;way&nbsp;of&nbsp;using&nbsp;the&nbsp;android&nbsp;command&nbsp;line&nbsp;backend&nbsp;class.<br>
-Example&nbsp;usage:<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;android_command_line_backend.<a href="#SetUpCommandLineFlags">SetUpCommandLineFlags</a>(<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device,&nbsp;backend_settings,&nbsp;startup_args):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Something&nbsp;to&nbsp;run&nbsp;while&nbsp;the&nbsp;command&nbsp;line&nbsp;flags&nbsp;are&nbsp;set&nbsp;appropriately.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="SetUpCommandLineFlags-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SetUpCommandLineFlags-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<dl><dt><a name="SetUpCommandLineFlags-__init__"><strong>__init__</strong></a>(self, device, backend_settings, startup_args)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.app_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.app_backend.html
deleted file mode 100644
index cfa3b69..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.app_backend.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.app_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.app_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/app_backend.py">telemetry/internal/backends/app_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.app_backend.html#AppBackend">AppBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AppBackend">class <strong>AppBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AppBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AppBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AppBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AppBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AppBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<dl><dt><a name="AppBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AppBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AppBackend-__init__"><strong>__init__</strong></a>(self, app_type, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.browser_backend.html
deleted file mode 100644
index 1555523..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.browser_backend.html
+++ /dev/null
@@ -1,218 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/browser_backend.py">telemetry/internal/backends/browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.app_backend.html">telemetry.internal.backends.app_backend</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-</td><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiling_controller_backend.html">telemetry.internal.platform.profiling_controller_backend</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="uuid.html">uuid</a><br>
-<a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.browser_backend.html#ExtensionsNotSupportedException">ExtensionsNotSupportedException</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">BrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserBackend">class <strong>BrowserBackend</strong></a>(<a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;base&nbsp;class&nbsp;for&nbsp;browser&nbsp;backends.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="BrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="BrowserBackend-__init__"><strong>__init__</strong></a>(self, platform_backend, supports_extensions, browser_options, tab_list_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="BrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<dl><dt><a name="BrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionsNotSupportedException">class <strong>ExtensionsNotSupportedException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.browser_backend.html#ExtensionsNotSupportedException">ExtensionsNotSupportedException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ExtensionsNotSupportedException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ExtensionsNotSupportedException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ExtensionsNotSupportedException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionsNotSupportedException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ExtensionsNotSupportedException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.android_browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.android_browser_backend.html
deleted file mode 100644
index 1a6ac27..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.android_browser_backend.html
+++ /dev/null
@@ -1,194 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.android_browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.android_browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/android_browser_backend.py">telemetry/internal/backends/chrome/android_browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.android_command_line_backend.html">telemetry.internal.backends.android_command_line_backend</a><br>
-<a href="telemetry.internal.platform.android_platform_backend.html">telemetry.internal.platform.android_platform_backend</a><br>
-<a href="telemetry.internal.backends.browser_backend.html">telemetry.internal.backends.browser_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html">telemetry.internal.backends.chrome.chrome_browser_backend</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-</td><td width="25%" valign=top><a href="devil.android.sdk.intent.html">devil.android.sdk.intent</a><br>
-<a href="logging.html">logging</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.android_browser_backend.html#AndroidBrowserBackend">AndroidBrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidBrowserBackend">class <strong>AndroidBrowserBackend</strong></a>(<a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;backend&nbsp;for&nbsp;controlling&nbsp;a&nbsp;browser&nbsp;instance&nbsp;running&nbsp;on&nbsp;Android.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.android_browser_backend.html#AndroidBrowserBackend">AndroidBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidBrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-__init__"><strong>__init__</strong></a>(self, android_platform_backend, browser_options, backend_settings, output_profile_path, extensions_to_load, target_arch)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>device</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><a name="AndroidBrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_options:&nbsp;An&nbsp;tracing_options.TracingOptions&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;custom_categories:&nbsp;An&nbsp;optional&nbsp;string&nbsp;containing&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comma&nbsp;separated&nbsp;categories&nbsp;that&nbsp;will&nbsp;be&nbsp;traced<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;category&nbsp;set.&nbsp;&nbsp;Example:&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"webkit,cc,disabled-by-default-cc.debug"&nbsp;to&nbsp;trace&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;three&nbsp;event&nbsp;categories.</tt></dd></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>extension_backend</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="AndroidBrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="AndroidBrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="AndroidBrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.android_browser_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.android_browser_finder.html
deleted file mode 100644
index f8020b1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.android_browser_finder.html
+++ /dev/null
@@ -1,132 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.android_browser_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.android_browser_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/android_browser_finder.py">telemetry/internal/backends/chrome/android_browser_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;android&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_backend.html">telemetry.internal.backends.chrome.android_browser_backend</a><br>
-<a href="telemetry.internal.backends.android_browser_backend_settings.html">telemetry.internal.backends.android_browser_backend_settings</a><br>
-<a href="telemetry.internal.platform.android_device.html">telemetry.internal.platform.android_device</a><br>
-<a href="devil.android.apk_helper.html">devil.android.apk_helper</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.android_browser_finder.html#PossibleAndroidBrowser">PossibleAndroidBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleAndroidBrowser">class <strong>PossibleAndroidBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;launchable&nbsp;android&nbsp;browser&nbsp;instance.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.android_browser_finder.html#PossibleAndroidBrowser">PossibleAndroidBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleAndroidBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-HaveLocalAPK"><strong>HaveLocalAPK</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, finder_options, android_platform, backend_settings, apk_name)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleAndroidBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>()</dt></dl>
- <dl><dt><a name="-CanPossiblyHandlePath"><strong>CanPossiblyHandlePath</strong></a>(target_path)</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Finds&nbsp;all&nbsp;the&nbsp;possible&nbsp;browsers&nbsp;on&nbsp;one&nbsp;device.<br>
-&nbsp;<br>
-The&nbsp;device&nbsp;is&nbsp;either&nbsp;the&nbsp;only&nbsp;device&nbsp;on&nbsp;the&nbsp;host&nbsp;platform,<br>
-or&nbsp;|finder_options|&nbsp;specifies&nbsp;a&nbsp;particular&nbsp;device.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(_options)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(possible_browsers)</dt><dd><tt>Return&nbsp;the&nbsp;newest&nbsp;possible&nbsp;browser.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>CHROME_PACKAGE_NAMES</strong> = {'android-chrome': ['com.google.android.apps.chrome', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, 'Chrome.apk'], 'android-chrome-beta': ['com.chrome.beta', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, None], 'android-chrome-canary': ['com.chrome.canary', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, None], 'android-chrome-dev': ['com.chrome.dev', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, None], 'android-chrome-work': ['com.chrome.work', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, None], 'android-chromium': ['org.chromium.chrome', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, 'ChromePublic.apk'], 'android-content-shell': ['org.chromium.content_shell_apk', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ContentShellBackendSettings'&gt;, 'ContentShell.apk'], 'android-jb-system-chrome': ['com.android.chrome', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.ChromeBackendSettings'&gt;, None], 'android-webview': ['org.chromium.webview_shell', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.WebviewBackendSettings'&gt;, None], 'android-webview-shell': ['org.chromium.android_webview.shell', &lt;class 'telemetry.internal.backends.android_browser_backend_settings.WebviewShellBackendSettings'&gt;, 'AndroidWebView.apk']}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.chrome_browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.chrome_browser_backend.html
deleted file mode 100644
index c599ca9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.chrome_browser_backend.html
+++ /dev/null
@@ -1,191 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.chrome_browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.chrome_browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/chrome_browser_backend.py">telemetry/internal/backends/chrome/chrome_browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.browser_backend.html">telemetry.internal.backends.browser_backend</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html">telemetry.internal.backends.chrome_inspector.devtools_client_backend</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.backends.chrome.extension_backend.html">telemetry.internal.backends.chrome.extension_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-<a href="logging.html">logging</a><br>
-<a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-<a href="pprint.html">pprint</a><br>
-<a href="shlex.html">shlex</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="telemetry.internal.backends.chrome.system_info_backend.html">telemetry.internal.backends.chrome.system_info_backend</a><br>
-<a href="telemetry.internal.backends.chrome.tab_list_backend.html">telemetry.internal.backends.chrome.tab_list_backend</a><br>
-<a href="telemetry.internal.browser.user_agent.html">telemetry.internal.browser.user_agent</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-<a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>(<a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">ChromeBrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChromeBrowserBackend">class <strong>ChromeBrowserBackend</strong></a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;abstract&nbsp;class&nbsp;for&nbsp;chrome&nbsp;browser&nbsp;backends.&nbsp;Provides&nbsp;basic&nbsp;functionality<br>
-once&nbsp;a&nbsp;remote-debugger&nbsp;port&nbsp;has&nbsp;been&nbsp;established.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">ChromeBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ChromeBrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_options:&nbsp;An&nbsp;tracing_options.TracingOptions&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;custom_categories:&nbsp;An&nbsp;optional&nbsp;string&nbsp;containing&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comma&nbsp;separated&nbsp;categories&nbsp;that&nbsp;will&nbsp;be&nbsp;traced<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;category&nbsp;set.&nbsp;&nbsp;Example:&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"webkit,cc,disabled-by-default-cc.debug"&nbsp;to&nbsp;trace&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;three&nbsp;event&nbsp;categories.</tt></dd></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-__init__"><strong>__init__</strong></a>(self, platform_backend, supports_tab_control, supports_extensions, browser_options, output_profile_path, extensions_to_load)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>extension_backend</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="ChromeBrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="ChromeBrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_backend.html
deleted file mode 100644
index b10d981..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_backend.html
+++ /dev/null
@@ -1,191 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.cros_browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.cros_browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/cros_browser_backend.py">telemetry/internal/backends/chrome/cros_browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html">telemetry.internal.backends.chrome.chrome_browser_backend</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.internal.backends.chrome.misc_web_contents_backend.html">telemetry.internal.backends.chrome.misc_web_contents_backend</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.cros_browser_backend.html#CrOSBrowserBackend">CrOSBrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOSBrowserBackend">class <strong>CrOSBrowserBackend</strong></a>(<a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.cros_browser_backend.html#CrOSBrowserBackend">CrOSBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrOSBrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-__init__"><strong>__init__</strong></a>(self, cros_platform_backend, browser_options, cri, is_guest, extensions_to_load)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>misc_web_contents_backend</strong></dt>
-<dd><tt>Access&nbsp;to&nbsp;chrome://oobe/login&nbsp;page.</tt></dd>
-</dl>
-<dl><dt><strong>oobe</strong></dt>
-</dl>
-<dl><dt><strong>oobe_exists</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><a name="CrOSBrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_options:&nbsp;An&nbsp;tracing_options.TracingOptions&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;custom_categories:&nbsp;An&nbsp;optional&nbsp;string&nbsp;containing&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comma&nbsp;separated&nbsp;categories&nbsp;that&nbsp;will&nbsp;be&nbsp;traced<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;category&nbsp;set.&nbsp;&nbsp;Example:&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"webkit,cc,disabled-by-default-cc.debug"&nbsp;to&nbsp;trace&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;three&nbsp;event&nbsp;categories.</tt></dd></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>extension_backend</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="CrOSBrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="CrOSBrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_finder.html
deleted file mode 100644
index aed268e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_finder.html
+++ /dev/null
@@ -1,115 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.cros_browser_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.cros_browser_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/cros_browser_finder.py">telemetry/internal/backends/chrome/cros_browser_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;CrOS&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-<a href="telemetry.internal.browser.browser_finder_exceptions.html">telemetry.internal.browser.browser_finder_exceptions</a><br>
-<a href="telemetry.internal.backends.chrome.cros_browser_backend.html">telemetry.internal.backends.chrome.cros_browser_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.cros_browser_with_oobe.html">telemetry.internal.backends.chrome.cros_browser_with_oobe</a><br>
-<a href="telemetry.internal.platform.cros_device.html">telemetry.internal.platform.cros_device</a><br>
-<a href="telemetry.core.cros_interface.html">telemetry.core.cros_interface</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.cros_browser_finder.html#PossibleCrOSBrowser">PossibleCrOSBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleCrOSBrowser">class <strong>PossibleCrOSBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;launchable&nbsp;CrOS&nbsp;browser&nbsp;instance.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.cros_browser_finder.html#PossibleCrOSBrowser">PossibleCrOSBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleCrOSBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, finder_options, cros_platform, is_guest)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleCrOSBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<dl><dt><a name="PossibleCrOSBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>(finder_options)</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Finds&nbsp;all&nbsp;available&nbsp;CrOS&nbsp;browsers,&nbsp;locally&nbsp;and&nbsp;remotely.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(_)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(possible_browsers)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_with_oobe.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_with_oobe.html
deleted file mode 100644
index 5565f52..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_browser_with_oobe.html
+++ /dev/null
@@ -1,183 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.cros_browser_with_oobe</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.cros_browser_with_oobe</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/cros_browser_with_oobe.py">telemetry/internal/backends/chrome/cros_browser_with_oobe.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.cros_browser_backend.html">telemetry.internal.backends.chrome.cros_browser_backend</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser.html#Browser">telemetry.internal.browser.browser.Browser</a>(<a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.cros_browser_with_oobe.html#CrOSBrowserWithOOBE">CrOSBrowserWithOOBE</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOSBrowserWithOOBE">class <strong>CrOSBrowserWithOOBE</strong></a>(<a href="telemetry.internal.browser.browser.html#Browser">telemetry.internal.browser.browser.Browser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Cros-specific&nbsp;browser.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.cros_browser_with_oobe.html#CrOSBrowserWithOOBE">CrOSBrowserWithOOBE</a></dd>
-<dd><a href="telemetry.internal.browser.browser.html#Browser">telemetry.internal.browser.browser.Browser</a></dd>
-<dd><a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrOSBrowserWithOOBE-__init__"><strong>__init__</strong></a>(self, backend, platform_backend, credentials_path)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>oobe</strong></dt>
-<dd><tt>The&nbsp;login&nbsp;webui&nbsp;(also&nbsp;serves&nbsp;as&nbsp;ui&nbsp;for&nbsp;screenlock&nbsp;and<br>
-out-of-box-experience).</tt></dd>
-</dl>
-<dl><dt><strong>oobe_exists</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;the&nbsp;login/oobe/screenlock&nbsp;webui&nbsp;exists.&nbsp;This&nbsp;is&nbsp;more&nbsp;lightweight<br>
-than&nbsp;accessing&nbsp;the&nbsp;oobe&nbsp;property.</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.browser.html#Browser">telemetry.internal.browser.browser.Browser</a>:<br>
-<dl><dt><a name="CrOSBrowserWithOOBE-Close"><strong>Close</strong></a>(self)</dt><dd><tt>Closes&nbsp;this&nbsp;browser.</tt></dd></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt><dd><tt>Returns&nbsp;low-level&nbsp;information&nbsp;about&nbsp;the&nbsp;system,&nbsp;if&nbsp;available.<br>
-&nbsp;<br>
-See&nbsp;the&nbsp;documentation&nbsp;of&nbsp;the&nbsp;SystemInfo&nbsp;class&nbsp;for&nbsp;more&nbsp;details.</tt></dd></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.browser.html#Browser">telemetry.internal.browser.browser.Browser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>cpu_stats</strong></dt>
-<dd><tt>Returns&nbsp;a&nbsp;dict&nbsp;of&nbsp;cpu&nbsp;statistics&nbsp;for&nbsp;the&nbsp;system.<br>
-{&nbsp;'Browser':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'CpuProcessTime':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'TotalTime':&nbsp;T<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Gpu':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'CpuProcessTime':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'TotalTime':&nbsp;T<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Renderer':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'CpuProcessTime':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'TotalTime':&nbsp;T<br>
-&nbsp;&nbsp;}<br>
-}<br>
-Any&nbsp;of&nbsp;the&nbsp;above&nbsp;keys&nbsp;may&nbsp;be&nbsp;missing&nbsp;on&nbsp;a&nbsp;per-platform&nbsp;basis.</tt></dd>
-</dl>
-<dl><dt><strong>extensions</strong></dt>
-</dl>
-<dl><dt><strong>foreground_tab</strong></dt>
-</dl>
-<dl><dt><strong>memory_stats</strong></dt>
-<dd><tt>Returns&nbsp;a&nbsp;dict&nbsp;of&nbsp;memory&nbsp;statistics&nbsp;for&nbsp;the&nbsp;browser:<br>
-{&nbsp;'Browser':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VM':&nbsp;R,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VMPeak':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSize':&nbsp;T,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSizePeak':&nbsp;U,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'ProportionalSetSize':&nbsp;V,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'PrivateDirty':&nbsp;W<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Gpu':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VM':&nbsp;R,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VMPeak':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSize':&nbsp;T,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSizePeak':&nbsp;U,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'ProportionalSetSize':&nbsp;V,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'PrivateDirty':&nbsp;W<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Renderer':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VM':&nbsp;R,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VMPeak':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSize':&nbsp;T,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSizePeak':&nbsp;U,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'ProportionalSetSize':&nbsp;V,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'PrivateDirty':&nbsp;W<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'SystemCommitCharge':&nbsp;X,<br>
-&nbsp;&nbsp;'SystemTotalPhysicalMemory':&nbsp;Y,<br>
-&nbsp;&nbsp;'ProcessCount':&nbsp;Z,<br>
-}<br>
-Any&nbsp;of&nbsp;the&nbsp;above&nbsp;keys&nbsp;may&nbsp;be&nbsp;missing&nbsp;on&nbsp;a&nbsp;per-platform&nbsp;basis.</tt></dd>
-</dl>
-<dl><dt><strong>profiling_controller</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>tabs</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>:<br>
-<dl><dt><a name="CrOSBrowserWithOOBE-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSBrowserWithOOBE-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_test_case.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_test_case.html
deleted file mode 100644
index b12b369..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.cros_test_case.html
+++ /dev/null
@@ -1,339 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.cros_test_case</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.cros_test_case</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/cros_test_case.py">telemetry/internal/backends/chrome/cros_test_case.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="telemetry.core.cros_interface.html">telemetry.core.cros_interface</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.extension_to_load.html">telemetry.internal.browser.extension_to_load</a><br>
-<a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="unittest.html">unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="unittest.case.html#TestCase">unittest.case.TestCase</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.cros_test_case.html#CrOSTestCase">CrOSTestCase</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOSTestCase">class <strong>CrOSTestCase</strong></a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.cros_test_case.html#CrOSTestCase">CrOSTestCase</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrOSTestCase-setUp"><strong>setUp</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="CrOSTestCase-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-__init__"><strong>__init__</strong></a>(self, methodName<font color="#909090">='runTest'</font>)</dt><dd><tt>Create&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;class&nbsp;that&nbsp;will&nbsp;use&nbsp;the&nbsp;named&nbsp;test<br>
-method&nbsp;when&nbsp;executed.&nbsp;Raises&nbsp;a&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;instance&nbsp;does<br>
-not&nbsp;have&nbsp;a&nbsp;method&nbsp;with&nbsp;the&nbsp;specified&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#CrOSTestCase-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#CrOSTestCase-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#CrOSTestCase-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#CrOSTestCase-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#CrOSTestCase-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#CrOSTestCase-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="CrOSTestCase-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="CrOSTestCase-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;class&nbsp;fixture&nbsp;before&nbsp;running&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<dl><dt><a name="CrOSTestCase-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;class&nbsp;fixture&nbsp;after&nbsp;running&nbsp;all&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.crx_id.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.crx_id.html
deleted file mode 100644
index f1b3cfe..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.crx_id.html
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.desktop_browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.desktop_browser_backend.html
deleted file mode 100644
index 29637bb..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.desktop_browser_backend.html
+++ /dev/null
@@ -1,206 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.desktop_browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.desktop_browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/desktop_browser_backend.py">telemetry/internal/backends/chrome/desktop_browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="telemetry.internal.backends.browser_backend.html">telemetry.internal.backends.browser_backend</a><br>
-<a href="telemetry.internal.backends.chrome.chrome_browser_backend.html">telemetry.internal.backends.chrome.chrome_browser_backend</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="datetime.html">datetime</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="glob.html">glob</a><br>
-<a href="heapq.html">heapq</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-<a href="random.html">random</a><br>
-<a href="re.html">re</a><br>
-<a href="shutil.html">shutil</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-<a href="time.html">time</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.desktop_browser_backend.html#DesktopBrowserBackend">DesktopBrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DesktopBrowserBackend">class <strong>DesktopBrowserBackend</strong></a>(<a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;backend&nbsp;for&nbsp;controlling&nbsp;a&nbsp;locally-executed&nbsp;browser&nbsp;instance,&nbsp;on&nbsp;Linux,<br>
-Mac&nbsp;or&nbsp;Windows.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.desktop_browser_backend.html#DesktopBrowserBackend">DesktopBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DesktopBrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-__init__"><strong>__init__</strong></a>(self, desktop_platform_backend, browser_options, executable, flash_path, is_content_shell, browser_directory, output_profile_path, extensions_to_load)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><a name="DesktopBrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_options:&nbsp;An&nbsp;tracing_options.TracingOptions&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;custom_categories:&nbsp;An&nbsp;optional&nbsp;string&nbsp;containing&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comma&nbsp;separated&nbsp;categories&nbsp;that&nbsp;will&nbsp;be&nbsp;traced<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;category&nbsp;set.&nbsp;&nbsp;Example:&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"webkit,cc,disabled-by-default-cc.debug"&nbsp;to&nbsp;trace&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;three&nbsp;event&nbsp;categories.</tt></dd></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>extension_backend</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="DesktopBrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="DesktopBrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="DesktopBrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ParseCrashpadDateTime"><strong>ParseCrashpadDateTime</strong></a>(date_time_str)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.desktop_browser_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.desktop_browser_finder.html
deleted file mode 100644
index 124af91..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.desktop_browser_finder.html
+++ /dev/null
@@ -1,117 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.desktop_browser_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.desktop_browser_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/desktop_browser_finder.py">telemetry/internal/backends/chrome/desktop_browser_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;desktop&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-<a href="telemetry.internal.backends.chrome.desktop_browser_backend.html">telemetry.internal.backends.chrome.desktop_browser_backend</a><br>
-<a href="telemetry.internal.platform.desktop_device.html">telemetry.internal.platform.desktop_device</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.desktop_browser_finder.html#PossibleDesktopBrowser">PossibleDesktopBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleDesktopBrowser">class <strong>PossibleDesktopBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;desktop&nbsp;browser&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.desktop_browser_finder.html#PossibleDesktopBrowser">PossibleDesktopBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleDesktopBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, finder_options, executable, flash_path, is_content_shell, browser_directory, is_local_build<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleDesktopBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>()</dt></dl>
- <dl><dt><a name="-CanPossiblyHandlePath"><strong>CanPossiblyHandlePath</strong></a>(target_path)</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Finds&nbsp;all&nbsp;the&nbsp;desktop&nbsp;browsers&nbsp;available&nbsp;on&nbsp;this&nbsp;machine.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(_)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(possible_browsers)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.extension_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.extension_backend.html
deleted file mode 100644
index ca4bb7f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.extension_backend.html
+++ /dev/null
@@ -1,221 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.extension_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.extension_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/extension_backend.py">telemetry/internal/backends/chrome/extension_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.extension_page.html">telemetry.internal.browser.extension_page</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html">telemetry.internal.backends.chrome_inspector.inspector_backend_list</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="_abcoll.html#Mapping">_abcoll.Mapping</a>(<a href="_abcoll.html#Sized">_abcoll.Sized</a>, <a href="_abcoll.html#Iterable">_abcoll.Iterable</a>, <a href="_abcoll.html#Container">_abcoll.Container</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.extension_backend.html#ExtensionBackendDict">ExtensionBackendDict</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>(<a href="_abcoll.html#Sequence">_abcoll.Sequence</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.extension_backend.html#ExtensionBackendList">ExtensionBackendList</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionBackendDict">class <strong>ExtensionBackendDict</strong></a>(<a href="_abcoll.html#Mapping">_abcoll.Mapping</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;dynamic&nbsp;mapping&nbsp;of&nbsp;extension_id&nbsp;to&nbsp;extension_page.ExtensionPages.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.extension_backend.html#ExtensionBackendDict">ExtensionBackendDict</a></dd>
-<dd><a href="_abcoll.html#Mapping">_abcoll.Mapping</a></dd>
-<dd><a href="_abcoll.html#Sized">_abcoll.Sized</a></dd>
-<dd><a href="_abcoll.html#Iterable">_abcoll.Iterable</a></dd>
-<dd><a href="_abcoll.html#Container">_abcoll.Container</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ExtensionBackendDict-ContextIdToExtensionId"><strong>ContextIdToExtensionId</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-__getitem__"><strong>__getitem__</strong></a>(self, extension_id)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-__init__"><strong>__init__</strong></a>(self, browser_backend)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Methods inherited from <a href="_abcoll.html#Mapping">_abcoll.Mapping</a>:<br>
-<dl><dt><a name="ExtensionBackendDict-__contains__"><strong>__contains__</strong></a>(self, key)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendDict-get"><strong>get</strong></a>(self, key, default<font color="#909090">=None</font>)</dt><dd><tt>D.<a href="#ExtensionBackendDict-get">get</a>(k[,d])&nbsp;-&gt;&nbsp;D[k]&nbsp;if&nbsp;k&nbsp;in&nbsp;D,&nbsp;else&nbsp;d.&nbsp;&nbsp;d&nbsp;defaults&nbsp;to&nbsp;None.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendDict-items"><strong>items</strong></a>(self)</dt><dd><tt>D.<a href="#ExtensionBackendDict-items">items</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;D's&nbsp;(key,&nbsp;value)&nbsp;pairs,&nbsp;as&nbsp;2-tuples</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendDict-iteritems"><strong>iteritems</strong></a>(self)</dt><dd><tt>D.<a href="#ExtensionBackendDict-iteritems">iteritems</a>()&nbsp;-&gt;&nbsp;an&nbsp;iterator&nbsp;over&nbsp;the&nbsp;(key,&nbsp;value)&nbsp;items&nbsp;of&nbsp;D</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendDict-iterkeys"><strong>iterkeys</strong></a>(self)</dt><dd><tt>D.<a href="#ExtensionBackendDict-iterkeys">iterkeys</a>()&nbsp;-&gt;&nbsp;an&nbsp;iterator&nbsp;over&nbsp;the&nbsp;keys&nbsp;of&nbsp;D</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendDict-itervalues"><strong>itervalues</strong></a>(self)</dt><dd><tt>D.<a href="#ExtensionBackendDict-itervalues">itervalues</a>()&nbsp;-&gt;&nbsp;an&nbsp;iterator&nbsp;over&nbsp;the&nbsp;values&nbsp;of&nbsp;D</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendDict-keys"><strong>keys</strong></a>(self)</dt><dd><tt>D.<a href="#ExtensionBackendDict-keys">keys</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;D's&nbsp;keys</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendDict-values"><strong>values</strong></a>(self)</dt><dd><tt>D.<a href="#ExtensionBackendDict-values">values</a>()&nbsp;-&gt;&nbsp;list&nbsp;of&nbsp;D's&nbsp;values</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Mapping">_abcoll.Mapping</a>:<br>
-<dl><dt><strong>__hash__</strong> = None</dl>
-
-<hr>
-Class methods inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><a name="ExtensionBackendDict-__subclasshook__"><strong>__subclasshook__</strong></a>(cls, C)<font color="#909090"><font face="helvetica, arial"> from <a href="abc.html#ABCMeta">abc.ABCMeta</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionBackendList">class <strong>ExtensionBackendList</strong></a>(<a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;dynamic&nbsp;sequence&nbsp;of&nbsp;extension_page.ExtensionPages.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.extension_backend.html#ExtensionBackendList">ExtensionBackendList</a></dd>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a></dd>
-<dd><a href="_abcoll.html#Sequence">_abcoll.Sequence</a></dd>
-<dd><a href="_abcoll.html#Sized">_abcoll.Sized</a></dd>
-<dd><a href="_abcoll.html#Iterable">_abcoll.Iterable</a></dd>
-<dd><a href="_abcoll.html#Container">_abcoll.Container</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ExtensionBackendList-CreateWrapper"><strong>CreateWrapper</strong></a>(self, inspector_backend)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-ShouldIncludeContext"><strong>ShouldIncludeContext</strong></a>(self, context)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-__init__"><strong>__init__</strong></a>(self, browser_backend)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>:<br>
-<dl><dt><a name="ExtensionBackendList-GetBackendFromContextId"><strong>GetBackendFromContextId</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-GetContextInfo"><strong>GetContextInfo</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-GetTabById"><strong>GetTabById</strong></a>(self, identifier)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-IterContextIds"><strong>IterContextIds</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-__getitem__"><strong>__getitem__</strong></a>(self, index)</dt><dd><tt>#&nbsp;TODO(nednguyen):&nbsp;Remove&nbsp;this&nbsp;method&nbsp;and&nbsp;turn&nbsp;inspector_backend_list&nbsp;API&nbsp;to<br>
-#&nbsp;dictionary-like&nbsp;API&nbsp;(crbug.com/398467)</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendList-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>:<br>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="_abcoll.html#Sequence">_abcoll.Sequence</a>:<br>
-<dl><dt><a name="ExtensionBackendList-__contains__"><strong>__contains__</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-__reversed__"><strong>__reversed__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExtensionBackendList-count"><strong>count</strong></a>(self, value)</dt><dd><tt>S.<a href="#ExtensionBackendList-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ExtensionBackendList-index"><strong>index</strong></a>(self, value)</dt><dd><tt>S.<a href="#ExtensionBackendList-index">index</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><a name="ExtensionBackendList-__subclasshook__"><strong>__subclasshook__</strong></a>(cls, C)<font color="#909090"><font face="helvetica, arial"> from <a href="abc.html#ABCMeta">abc.ABCMeta</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.html
deleted file mode 100644
index 3af1eec..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.backends.chrome</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.chrome</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/__init__.py">telemetry/internal/backends/chrome/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_backend.html">android_browser_backend</a><br>
-<a href="telemetry.internal.backends.chrome.android_browser_finder.html">android_browser_finder</a><br>
-<a href="telemetry.internal.backends.chrome.android_browser_finder_unittest.html">android_browser_finder_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.chrome_browser_backend.html">chrome_browser_backend</a><br>
-<a href="telemetry.internal.backends.chrome.chrome_browser_backend_unittest.html">chrome_browser_backend_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.cros_browser_backend.html">cros_browser_backend</a><br>
-<a href="telemetry.internal.backends.chrome.cros_browser_finder.html">cros_browser_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.cros_browser_finder_unittest.html">cros_browser_finder_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.cros_browser_with_oobe.html">cros_browser_with_oobe</a><br>
-<a href="telemetry.internal.backends.chrome.cros_test_case.html">cros_test_case</a><br>
-<a href="telemetry.internal.backends.chrome.cros_unittest.html">cros_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.crx_id.html">crx_id</a><br>
-<a href="telemetry.internal.backends.chrome.crx_id_unittest.html">crx_id_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.desktop_browser_backend.html">desktop_browser_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.desktop_browser_finder.html">desktop_browser_finder</a><br>
-<a href="telemetry.internal.backends.chrome.desktop_browser_finder_unittest.html">desktop_browser_finder_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.extension_backend.html">extension_backend</a><br>
-<a href="telemetry.internal.backends.chrome.ios_browser_backend.html">ios_browser_backend</a><br>
-<a href="telemetry.internal.backends.chrome.ios_browser_finder.html">ios_browser_finder</a><br>
-<a href="telemetry.internal.backends.chrome.ios_browser_finder_unittest.html">ios_browser_finder_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.misc_web_contents_backend.html">misc_web_contents_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.oobe.html">oobe</a><br>
-<a href="telemetry.internal.backends.chrome.system_info_backend.html">system_info_backend</a><br>
-<a href="telemetry.internal.backends.chrome.tab_list_backend.html">tab_list_backend</a><br>
-<a href="telemetry.internal.backends.chrome.tab_list_backend_unittest.html">tab_list_backend_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.ios_browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.ios_browser_backend.html
deleted file mode 100644
index f798df7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.ios_browser_backend.html
+++ /dev/null
@@ -1,192 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.ios_browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.ios_browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/ios_browser_backend.py">telemetry/internal/backends/chrome/ios_browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html">telemetry.internal.backends.chrome.chrome_browser_backend</a><br>
-<a href="contextlib.html">contextlib</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="logging.html">logging</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.system_info_backend.html">telemetry.internal.backends.chrome.system_info_backend</a><br>
-<a href="urllib2.html">urllib2</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.ios_browser_backend.html#IosBrowserBackend">IosBrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IosBrowserBackend">class <strong>IosBrowserBackend</strong></a>(<a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.ios_browser_backend.html#IosBrowserBackend">IosBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="IosBrowserBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetDeviceUrls"><strong>GetDeviceUrls</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetWebSocketDebuggerUrls"><strong>GetWebSocketDebuggerUrls</strong></a>(self, device_urls)</dt><dd><tt>Get&nbsp;a&nbsp;list&nbsp;of&nbsp;the&nbsp;websocket&nbsp;debugger&nbsp;URLs&nbsp;to&nbsp;communicate&nbsp;with<br>
-all&nbsp;running&nbsp;UIWebViews.</tt></dd></dl>
-
-<dl><dt><a name="IosBrowserBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-UpdateRunningBrowsersInfo"><strong>UpdateRunningBrowsersInfo</strong></a>(self)</dt><dd><tt>Refresh&nbsp;to&nbsp;match&nbsp;current&nbsp;state&nbsp;of&nbsp;the&nbsp;running&nbsp;browser.</tt></dd></dl>
-
-<dl><dt><a name="IosBrowserBackend-__init__"><strong>__init__</strong></a>(self, ios_platform_backend, browser_options)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-extension_backend"><strong>extension_backend</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><a name="IosBrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="IosBrowserBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_options:&nbsp;An&nbsp;tracing_options.TracingOptions&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;custom_categories:&nbsp;An&nbsp;optional&nbsp;string&nbsp;containing&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comma&nbsp;separated&nbsp;categories&nbsp;that&nbsp;will&nbsp;be&nbsp;traced<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;category&nbsp;set.&nbsp;&nbsp;Example:&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"webkit,cc,disabled-by-default-cc.debug"&nbsp;to&nbsp;trace&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;three&nbsp;event&nbsp;categories.</tt></dd></dl>
-
-<dl><dt><a name="IosBrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome.chrome_browser_backend.html#ChromeBrowserBackend">telemetry.internal.backends.chrome.chrome_browser_backend.ChromeBrowserBackend</a>:<br>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="IosBrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="IosBrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<dl><dt><a name="IosBrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.ios_browser_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.ios_browser_finder.html
deleted file mode 100644
index d8dc94c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.ios_browser_finder.html
+++ /dev/null
@@ -1,124 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.ios_browser_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.ios_browser_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/ios_browser_finder.py">telemetry/internal/backends/chrome/ios_browser_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;iOS&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_backend.html">telemetry.internal.backends.chrome_inspector.inspector_backend</a><br>
-<a href="telemetry.internal.backends.chrome.ios_browser_backend.html">telemetry.internal.backends.chrome.ios_browser_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.ios_device.html">telemetry.internal.platform.ios_device</a><br>
-<a href="telemetry.internal.platform.ios_platform_backend.html">telemetry.internal.platform.ios_platform_backend</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.ios_browser_finder.html#PossibleIOSBrowser">PossibleIOSBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleIOSBrowser">class <strong>PossibleIOSBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;running&nbsp;iOS&nbsp;browser&nbsp;instance.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.ios_browser_finder.html#PossibleIOSBrowser">PossibleIOSBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleIOSBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt><dd><tt>#&nbsp;TODO(baxley):&nbsp;Implement&nbsp;the&nbsp;following&nbsp;methods&nbsp;for&nbsp;iOS.</tt></dd></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, _)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleIOSBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleIOSBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>()</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Find&nbsp;all&nbsp;running&nbsp;iOS&nbsp;browsers&nbsp;on&nbsp;connected&nbsp;devices.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(_)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(_)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEVICE_LIST_URL</strong> = 'http://127.0.0.1:9221/json'<br>
-<strong>IOS_BROWSERS</strong> = {'CriOS': 'ios-chrome', 'Version': 'ios-safari'}<br>
-<strong>IOS_WEBKIT_DEBUG_PROXY</strong> = 'ios_webkit_debug_proxy'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.misc_web_contents_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.misc_web_contents_backend.html
deleted file mode 100644
index b3066c7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.misc_web_contents_backend.html
+++ /dev/null
@@ -1,139 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.misc_web_contents_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.misc_web_contents_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/misc_web_contents_backend.py">telemetry/internal/backends/chrome/misc_web_contents_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html">telemetry.internal.backends.chrome_inspector.inspector_backend_list</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.oobe.html">telemetry.internal.backends.chrome.oobe</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>(<a href="_abcoll.html#Sequence">_abcoll.Sequence</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.misc_web_contents_backend.html#MiscWebContentsBackend">MiscWebContentsBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MiscWebContentsBackend">class <strong>MiscWebContentsBackend</strong></a>(<a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;dynamic&nbsp;sequence&nbsp;of&nbsp;web&nbsp;contents&nbsp;not&nbsp;related&nbsp;to&nbsp;tabs&nbsp;and&nbsp;extensions.<br>
-&nbsp;<br>
-Provides&nbsp;acccess&nbsp;to&nbsp;chrome://oobe/login&nbsp;page.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.misc_web_contents_backend.html#MiscWebContentsBackend">MiscWebContentsBackend</a></dd>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a></dd>
-<dd><a href="_abcoll.html#Sequence">_abcoll.Sequence</a></dd>
-<dd><a href="_abcoll.html#Sized">_abcoll.Sized</a></dd>
-<dd><a href="_abcoll.html#Iterable">_abcoll.Iterable</a></dd>
-<dd><a href="_abcoll.html#Container">_abcoll.Container</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MiscWebContentsBackend-CreateWrapper"><strong>CreateWrapper</strong></a>(self, inspector_backend)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-GetOobe"><strong>GetOobe</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-ShouldIncludeContext"><strong>ShouldIncludeContext</strong></a>(self, context)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-__init__"><strong>__init__</strong></a>(self, browser_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>oobe_exists</strong></dt>
-<dd><tt>Lightweight&nbsp;property&nbsp;to&nbsp;determine&nbsp;if&nbsp;the&nbsp;oobe&nbsp;webui&nbsp;is&nbsp;visible.</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>:<br>
-<dl><dt><a name="MiscWebContentsBackend-GetBackendFromContextId"><strong>GetBackendFromContextId</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-GetContextInfo"><strong>GetContextInfo</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-GetTabById"><strong>GetTabById</strong></a>(self, identifier)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-IterContextIds"><strong>IterContextIds</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-__getitem__"><strong>__getitem__</strong></a>(self, index)</dt><dd><tt>#&nbsp;TODO(nednguyen):&nbsp;Remove&nbsp;this&nbsp;method&nbsp;and&nbsp;turn&nbsp;inspector_backend_list&nbsp;API&nbsp;to<br>
-#&nbsp;dictionary-like&nbsp;API&nbsp;(crbug.com/398467)</tt></dd></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>:<br>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="_abcoll.html#Sequence">_abcoll.Sequence</a>:<br>
-<dl><dt><a name="MiscWebContentsBackend-__contains__"><strong>__contains__</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-__reversed__"><strong>__reversed__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-count"><strong>count</strong></a>(self, value)</dt><dd><tt>S.<a href="#MiscWebContentsBackend-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MiscWebContentsBackend-index"><strong>index</strong></a>(self, value)</dt><dd><tt>S.<a href="#MiscWebContentsBackend-index">index</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><a name="MiscWebContentsBackend-__subclasshook__"><strong>__subclasshook__</strong></a>(cls, C)<font color="#909090"><font face="helvetica, arial"> from <a href="abc.html#ABCMeta">abc.ABCMeta</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.oobe.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.oobe.html
deleted file mode 100644
index 57e61f2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.oobe.html
+++ /dev/null
@@ -1,246 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.oobe</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.oobe</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/oobe.py">telemetry/internal/backends/chrome/oobe.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.oobe.html#Oobe">Oobe</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Oobe">class <strong>Oobe</strong></a>(<a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.oobe.html#Oobe">Oobe</a></dd>
-<dd><a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Oobe-NavigateFakeLogin"><strong>NavigateFakeLogin</strong></a>(self, username, password, gaia_id)</dt><dd><tt>Fake&nbsp;user&nbsp;login.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-NavigateGaiaLogin"><strong>NavigateGaiaLogin</strong></a>(self, username, password, enterprise_enroll<font color="#909090">=False</font>, for_user_triggered_enrollment<font color="#909090">=False</font>)</dt><dd><tt>Logs&nbsp;in&nbsp;using&nbsp;the&nbsp;GAIA&nbsp;webview&nbsp;or&nbsp;IFrame,&nbsp;whichever&nbsp;is<br>
-present.&nbsp;|enterprise_enroll|&nbsp;allows&nbsp;for&nbsp;enterprise&nbsp;enrollment.<br>
-|for_user_triggered_enrollment|&nbsp;should&nbsp;be&nbsp;False&nbsp;for&nbsp;remora&nbsp;enrollment.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-NavigateGuestLogin"><strong>NavigateGuestLogin</strong></a>(self)</dt><dd><tt>Logs&nbsp;in&nbsp;as&nbsp;guest.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-__init__"><strong>__init__</strong></a>(self, inspector_backend)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>:<br>
-<dl><dt><a name="Oobe-CloseConnections"><strong>CloseConnections</strong></a>(self)</dt><dd><tt>Closes&nbsp;all&nbsp;TCP&nbsp;sockets&nbsp;held&nbsp;open&nbsp;by&nbsp;the&nbsp;browser.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException&nbsp;if&nbsp;the&nbsp;tab&nbsp;is&nbsp;not&nbsp;alive.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-EnableAllContexts"><strong>EnableAllContexts</strong></a>(self)</dt><dd><tt>Enable&nbsp;all&nbsp;contexts&nbsp;in&nbsp;a&nbsp;page.&nbsp;Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;available&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-EvaluateJavaScript"><strong>EvaluateJavaScript</strong></a>(self, expr, timeout<font color="#909090">=90</font>)</dt><dd><tt>Evalutes&nbsp;expr&nbsp;in&nbsp;JavaScript&nbsp;and&nbsp;returns&nbsp;the&nbsp;JSONized&nbsp;result.<br>
-&nbsp;<br>
-Consider&nbsp;using&nbsp;ExecuteJavaScript&nbsp;for&nbsp;cases&nbsp;where&nbsp;the&nbsp;result&nbsp;of&nbsp;the<br>
-expression&nbsp;is&nbsp;not&nbsp;needed.<br>
-&nbsp;<br>
-If&nbsp;evaluation&nbsp;throws&nbsp;in&nbsp;JavaScript,&nbsp;a&nbsp;Python&nbsp;EvaluateException&nbsp;will<br>
-be&nbsp;raised.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;result&nbsp;of&nbsp;the&nbsp;evaluation&nbsp;cannot&nbsp;be&nbsp;JSONized,&nbsp;then&nbsp;an<br>
-EvaluationException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Oobe-EvaluateJavaScriptInContext">EvaluateJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-EvaluateJavaScriptInContext"><strong>EvaluateJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-ExecuteJavaScript"><strong>ExecuteJavaScript</strong></a>(self, statement, timeout<font color="#909090">=90</font>)</dt><dd><tt>Executes&nbsp;statement&nbsp;in&nbsp;JavaScript.&nbsp;Does&nbsp;not&nbsp;return&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;statement&nbsp;failed&nbsp;to&nbsp;evaluate,&nbsp;EvaluateException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Oobe-ExecuteJavaScriptInContext">ExecuteJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-ExecuteJavaScriptInContext"><strong>ExecuteJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-GetUrl"><strong>GetUrl</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;to&nbsp;which&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;connected.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-GetWebviewContexts"><strong>GetWebviewContexts</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;webview&nbsp;contexts&nbsp;within&nbsp;the&nbsp;current&nbsp;inspector&nbsp;backend.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;objects&nbsp;representing&nbsp;the&nbsp;webview&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-HasReachedQuiescence"><strong>HasReachedQuiescence</strong></a>(self)</dt><dd><tt>Determine&nbsp;whether&nbsp;the&nbsp;page&nbsp;has&nbsp;reached&nbsp;quiescence&nbsp;after&nbsp;loading.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;2&nbsp;seconds&nbsp;have&nbsp;passed&nbsp;since&nbsp;last&nbsp;resource&nbsp;received,&nbsp;false<br>
-&nbsp;&nbsp;otherwise.<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Oobe-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-IsAlive"><strong>IsAlive</strong></a>(self)</dt><dd><tt>Whether&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;still&nbsp;operating&nbsp;normally.<br>
-&nbsp;<br>
-Since&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;function&nbsp;asynchronously,&nbsp;this&nbsp;method&nbsp;does&nbsp;not&nbsp;guarantee<br>
-that&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;will&nbsp;still&nbsp;be&nbsp;alive&nbsp;at&nbsp;any&nbsp;point&nbsp;in&nbsp;the&nbsp;future.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;boolean&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;opearting&nbsp;normally.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-Navigate"><strong>Navigate</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Navigates&nbsp;to&nbsp;url.<br>
-&nbsp;<br>
-If&nbsp;|script_to_evaluate_on_commit|&nbsp;is&nbsp;given,&nbsp;the&nbsp;script&nbsp;source&nbsp;string&nbsp;will&nbsp;be<br>
-evaluated&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;committed.&nbsp;This&nbsp;is&nbsp;after&nbsp;the&nbsp;context&nbsp;of<br>
-the&nbsp;page&nbsp;exists,&nbsp;but&nbsp;before&nbsp;any&nbsp;script&nbsp;on&nbsp;the&nbsp;page&nbsp;itself&nbsp;has&nbsp;executed.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-StartTimelineRecording"><strong>StartTimelineRecording</strong></a>(self)</dt><dd><tt>Starts&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-StopTimelineRecording"><strong>StopTimelineRecording</strong></a>(self)</dt><dd><tt>Stops&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-SynthesizeScrollGesture"><strong>SynthesizeScrollGesture</strong></a>(self, x<font color="#909090">=100</font>, y<font color="#909090">=800</font>, xDistance<font color="#909090">=0</font>, yDistance<font color="#909090">=-500</font>, xOverscroll<font color="#909090">=None</font>, yOverscroll<font color="#909090">=None</font>, preventFling<font color="#909090">=True</font>, speed<font color="#909090">=None</font>, gestureSourceType<font color="#909090">=None</font>, repeatCount<font color="#909090">=None</font>, repeatDelayMs<font color="#909090">=None</font>, interactionMarkerName<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;an&nbsp;inspector&nbsp;command&nbsp;that&nbsp;causes&nbsp;a&nbsp;repeatable&nbsp;browser&nbsp;driven&nbsp;scroll.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x:&nbsp;X&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;y:&nbsp;Y&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;xDistance:&nbsp;Distance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;X&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;left).<br>
-&nbsp;&nbsp;yDistance:&nbsp;Ddistance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;up).<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;X&nbsp;axis.<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis.<br>
-&nbsp;&nbsp;preventFling:&nbsp;Prevents&nbsp;a&nbsp;fling&nbsp;gesture.<br>
-&nbsp;&nbsp;speed:&nbsp;Swipe&nbsp;speed&nbsp;in&nbsp;pixels&nbsp;per&nbsp;second.<br>
-&nbsp;&nbsp;gestureSourceType:&nbsp;Which&nbsp;type&nbsp;of&nbsp;input&nbsp;events&nbsp;to&nbsp;be&nbsp;generated.<br>
-&nbsp;&nbsp;repeatCount:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;repeats&nbsp;beyond&nbsp;the&nbsp;first&nbsp;scroll.<br>
-&nbsp;&nbsp;repeatDelayMs:&nbsp;Number&nbsp;of&nbsp;milliseconds&nbsp;delay&nbsp;between&nbsp;each&nbsp;repeat.<br>
-&nbsp;&nbsp;interactionMarkerName:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;interaction&nbsp;markers&nbsp;to&nbsp;generate.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Oobe-WaitForDocumentReadyStateToBeComplete"><strong>WaitForDocumentReadyStateToBeComplete</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;finish&nbsp;loading.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Oobe-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-WaitForDocumentReadyStateToBeInteractiveOrBetter"><strong>WaitForDocumentReadyStateToBeInteractiveOrBetter</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;be&nbsp;interactive.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Oobe-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-WaitForJavaScriptExpression"><strong>WaitForJavaScriptExpression</strong></a>(self, expr, timeout, dump_page_state_on_timeout<font color="#909090">=True</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;given&nbsp;JavaScript&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;robust&nbsp;against&nbsp;any&nbsp;given&nbsp;Evaluation&nbsp;timing&nbsp;out.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;expr:&nbsp;The&nbsp;expression&nbsp;to&nbsp;evaluate.<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;&nbsp;dump_page_state_on_timeout:&nbsp;Whether&nbsp;to&nbsp;provide&nbsp;additional&nbsp;information&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page&nbsp;state&nbsp;if&nbsp;a&nbsp;TimeoutException&nbsp;is&nbsp;thrown.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException:&nbsp;On&nbsp;a&nbsp;timeout.<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Oobe-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Oobe-WaitForNavigate"><strong>WaitForNavigate</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;navigation&nbsp;to&nbsp;complete.<br>
-&nbsp;<br>
-The&nbsp;current&nbsp;page&nbsp;is&nbsp;expect&nbsp;to&nbsp;be&nbsp;in&nbsp;a&nbsp;navigation.<br>
-This&nbsp;function&nbsp;returns&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;complete&nbsp;or&nbsp;when<br>
-the&nbsp;timeout&nbsp;has&nbsp;been&nbsp;exceeded.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-<dd><tt>Return&nbsp;the&nbsp;unique&nbsp;id&nbsp;string&nbsp;for&nbsp;this&nbsp;tab&nbsp;object.</tt></dd>
-</dl>
-<dl><dt><strong>message_output_stream</strong></dt>
-</dl>
-<dl><dt><strong>timeline_model</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.system_info_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.system_info_backend.html
deleted file mode 100644
index ea93819..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.system_info_backend.html
+++ /dev/null
@@ -1,62 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.system_info_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.system_info_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/system_info_backend.py">telemetry/internal/backends/chrome/system_info_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.camel_case.html">telemetry.internal.util.camel_case</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html">telemetry.internal.backends.chrome_inspector.inspector_websocket</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.system_info.html">telemetry.internal.platform.system_info</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.system_info_backend.html#SystemInfoBackend">SystemInfoBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SystemInfoBackend">class <strong>SystemInfoBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="SystemInfoBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self, timeout<font color="#909090">=10</font>)</dt></dl>
-
-<dl><dt><a name="SystemInfoBackend-__init__"><strong>__init__</strong></a>(self, devtools_port, devtools_page<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.tab_list_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.tab_list_backend.html
deleted file mode 100644
index 4cba6df..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome.tab_list_backend.html
+++ /dev/null
@@ -1,229 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome.tab_list_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome.html"><font color="#ffffff">chrome</font></a>.tab_list_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome/tab_list_backend.py">telemetry/internal/backends/chrome/tab_list_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html">telemetry.internal.backends.chrome_inspector.inspector_backend_list</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="telemetry.internal.browser.tab.html">telemetry.internal.browser.tab</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.tab_list_backend.html#TabUnexpectedResponseException">TabUnexpectedResponseException</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>(<a href="_abcoll.html#Sequence">_abcoll.Sequence</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome.tab_list_backend.html#TabListBackend">TabListBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TabListBackend">class <strong>TabListBackend</strong></a>(<a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;dynamic&nbsp;sequence&nbsp;of&nbsp;tab.Tabs&nbsp;in&nbsp;UI&nbsp;order.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.tab_list_backend.html#TabListBackend">TabListBackend</a></dd>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a></dd>
-<dd><a href="_abcoll.html#Sequence">_abcoll.Sequence</a></dd>
-<dd><a href="_abcoll.html#Sized">_abcoll.Sized</a></dd>
-<dd><a href="_abcoll.html#Iterable">_abcoll.Iterable</a></dd>
-<dd><a href="_abcoll.html#Container">_abcoll.Container</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TabListBackend-ActivateTab"><strong>ActivateTab</strong></a>(self, tab_id, timeout<font color="#909090">=30</font>)</dt><dd><tt>Activates&nbsp;the&nbsp;tab&nbsp;with&nbsp;the&nbsp;given&nbsp;debugger_url.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError<br>
-&nbsp;&nbsp;devtools_client_backend.TabNotFoundError<br>
-&nbsp;&nbsp;<a href="#TabUnexpectedResponseException">TabUnexpectedResponseException</a></tt></dd></dl>
-
-<dl><dt><a name="TabListBackend-CloseTab"><strong>CloseTab</strong></a>(self, tab_id, timeout<font color="#909090">=300</font>)</dt><dd><tt>Closes&nbsp;the&nbsp;tab&nbsp;with&nbsp;the&nbsp;given&nbsp;debugger_url.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError<br>
-&nbsp;&nbsp;devtools_client_backend.TabNotFoundError<br>
-&nbsp;&nbsp;<a href="#TabUnexpectedResponseException">TabUnexpectedResponseException</a><br>
-&nbsp;&nbsp;exceptions.TimeoutException</tt></dd></dl>
-
-<dl><dt><a name="TabListBackend-CreateWrapper"><strong>CreateWrapper</strong></a>(self, inspector_backend)</dt></dl>
-
-<dl><dt><a name="TabListBackend-Get"><strong>Get</strong></a>(self, index, ret)</dt><dd><tt>Returns&nbsp;self[index]&nbsp;if&nbsp;it&nbsp;exists,&nbsp;or&nbsp;ret&nbsp;if&nbsp;index&nbsp;is&nbsp;out&nbsp;of&nbsp;bounds.</tt></dd></dl>
-
-<dl><dt><a name="TabListBackend-New"><strong>New</strong></a>(self, timeout)</dt><dd><tt>Makes&nbsp;a&nbsp;new&nbsp;tab.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;Tab&nbsp;object.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd></dl>
-
-<dl><dt><a name="TabListBackend-ShouldIncludeContext"><strong>ShouldIncludeContext</strong></a>(self, context)</dt></dl>
-
-<dl><dt><a name="TabListBackend-__init__"><strong>__init__</strong></a>(self, browser_backend)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>:<br>
-<dl><dt><a name="TabListBackend-GetBackendFromContextId"><strong>GetBackendFromContextId</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="TabListBackend-GetContextInfo"><strong>GetContextInfo</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="TabListBackend-GetTabById"><strong>GetTabById</strong></a>(self, identifier)</dt></dl>
-
-<dl><dt><a name="TabListBackend-IterContextIds"><strong>IterContextIds</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabListBackend-__getitem__"><strong>__getitem__</strong></a>(self, index)</dt><dd><tt>#&nbsp;TODO(nednguyen):&nbsp;Remove&nbsp;this&nbsp;method&nbsp;and&nbsp;turn&nbsp;inspector_backend_list&nbsp;API&nbsp;to<br>
-#&nbsp;dictionary-like&nbsp;API&nbsp;(crbug.com/398467)</tt></dd></dl>
-
-<dl><dt><a name="TabListBackend-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabListBackend-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">telemetry.internal.backends.chrome_inspector.inspector_backend_list.InspectorBackendList</a>:<br>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="_abcoll.html#Sequence">_abcoll.Sequence</a>:<br>
-<dl><dt><a name="TabListBackend-__contains__"><strong>__contains__</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="TabListBackend-__reversed__"><strong>__reversed__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabListBackend-count"><strong>count</strong></a>(self, value)</dt><dd><tt>S.<a href="#TabListBackend-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TabListBackend-index"><strong>index</strong></a>(self, value)</dt><dd><tt>S.<a href="#TabListBackend-index">index</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><a name="TabListBackend-__subclasshook__"><strong>__subclasshook__</strong></a>(cls, C)<font color="#909090"><font face="helvetica, arial"> from <a href="abc.html#ABCMeta">abc.ABCMeta</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TabUnexpectedResponseException">class <strong>TabUnexpectedResponseException</strong></a>(<a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome.tab_list_backend.html#TabUnexpectedResponseException">TabUnexpectedResponseException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><a name="TabUnexpectedResponseException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TabUnexpectedResponseException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TabUnexpectedResponseException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TabUnexpectedResponseException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TabUnexpectedResponseException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TabUnexpectedResponseException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TabUnexpectedResponseException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TabUnexpectedResponseException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TabUnexpectedResponseException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TabUnexpectedResponseException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.devtools_client_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.devtools_client_backend.html
deleted file mode 100644
index ff536e3..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.devtools_client_backend.html
+++ /dev/null
@@ -1,284 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.devtools_client_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.devtools_client_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/devtools_client_backend.py">telemetry/internal/backends/chrome_inspector/devtools_client_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.browser_backend.html">telemetry.internal.backends.browser_backend</a><br>
-<a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html">telemetry.internal.platform.tracing_agent.chrome_tracing_agent</a><br>
-<a href="telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager.html">telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html">telemetry.internal.backends.chrome_inspector.devtools_http</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_backend.html">telemetry.internal.backends.chrome_inspector.inspector_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html">telemetry.internal.backends.chrome_inspector.inspector_websocket</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.memory_backend.html">telemetry.internal.backends.chrome_inspector.memory_backend</a><br>
-<a href="re.html">re</a><br>
-<a href="socket.html">socket</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html">telemetry.internal.backends.chrome_inspector.tracing_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.websocket.html">telemetry.internal.backends.chrome_inspector.websocket</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html#DevToolsClientBackend">DevToolsClientBackend</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html#TabNotFoundError">TabNotFoundError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DevToolsClientBackend">class <strong>DevToolsClientBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;that&nbsp;communicates&nbsp;with&nbsp;Chrome's&nbsp;devtools.<br>
-&nbsp;<br>
-This&nbsp;class&nbsp;owns&nbsp;a&nbsp;map&nbsp;of&nbsp;InspectorBackends.&nbsp;It&nbsp;is&nbsp;responsible&nbsp;for&nbsp;creating<br>
-them&nbsp;and&nbsp;destroying&nbsp;them.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="DevToolsClientBackend-ActivateTab"><strong>ActivateTab</strong></a>(self, tab_id, timeout)</dt><dd><tt>Activates&nbsp;the&nbsp;tab&nbsp;with&nbsp;the&nbsp;given&nbsp;id.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError<br>
-&nbsp;&nbsp;<a href="#TabNotFoundError">TabNotFoundError</a></tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DevToolsClientBackend-CloseTab"><strong>CloseTab</strong></a>(self, tab_id, timeout)</dt><dd><tt>Closes&nbsp;the&nbsp;tab&nbsp;with&nbsp;the&nbsp;given&nbsp;id.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError<br>
-&nbsp;&nbsp;<a href="#TabNotFoundError">TabNotFoundError</a></tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=30</font>)</dt><dd><tt>Dumps&nbsp;memory.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;GUID&nbsp;of&nbsp;the&nbsp;generated&nbsp;dump&nbsp;if&nbsp;successful,&nbsp;None&nbsp;otherwise.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;TracingTimeoutException:&nbsp;If&nbsp;more&nbsp;than&nbsp;|timeout|&nbsp;seconds&nbsp;has&nbsp;passed<br>
-&nbsp;&nbsp;since&nbsp;the&nbsp;last&nbsp;time&nbsp;any&nbsp;data&nbsp;is&nbsp;received.<br>
-&nbsp;&nbsp;TracingUnrecoverableException:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;websocket&nbsp;error.<br>
-&nbsp;&nbsp;TracingUnexpectedResponseException:&nbsp;If&nbsp;the&nbsp;response&nbsp;contains&nbsp;an&nbsp;error<br>
-&nbsp;&nbsp;or&nbsp;does&nbsp;not&nbsp;contain&nbsp;the&nbsp;expected&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-GetChromeBranchNumber"><strong>GetChromeBranchNumber</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DevToolsClientBackend-GetUpdatedInspectableContexts"><strong>GetUpdatedInspectableContexts</strong></a>(self)</dt><dd><tt>Returns&nbsp;an&nbsp;updated&nbsp;instance&nbsp;of&nbsp;_DevToolsContextMapBackend.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-GetUrl"><strong>GetUrl</strong></a>(self, tab_id)</dt><dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;of&nbsp;the&nbsp;tab&nbsp;with&nbsp;|tab_id|,&nbsp;as&nbsp;reported&nbsp;by&nbsp;devtools.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-IsAlive"><strong>IsAlive</strong></a>(self)</dt><dd><tt>Whether&nbsp;the&nbsp;DevTools&nbsp;server&nbsp;is&nbsp;available&nbsp;and&nbsp;connectable.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-IsChromeTracingSupported"><strong>IsChromeTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DevToolsClientBackend-IsInspectable"><strong>IsInspectable</strong></a>(self, tab_id)</dt><dd><tt>Whether&nbsp;the&nbsp;tab&nbsp;with&nbsp;|tab_id|&nbsp;is&nbsp;inspectable,&nbsp;as&nbsp;reported&nbsp;by&nbsp;devtools.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-RequestNewTab"><strong>RequestNewTab</strong></a>(self, timeout)</dt><dd><tt>Creates&nbsp;a&nbsp;new&nbsp;tab.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;JSON&nbsp;string&nbsp;as&nbsp;returned&nbsp;by&nbsp;DevTools.&nbsp;Example:<br>
-&nbsp;&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"description":&nbsp;"",<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"devtoolsFrontendUrl":<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"/devtools/inspector.html?ws=host:port/devtools/page/id-string",<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"id":&nbsp;"id-string",<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"title":&nbsp;"Page&nbsp;Title",<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"type":&nbsp;"page",<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"url":&nbsp;"url",<br>
-&nbsp;&nbsp;&nbsp;&nbsp;"webSocketDebuggerUrl":&nbsp;"ws://host:port/devtools/page/id-string"<br>
-&nbsp;&nbsp;}<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=30</font>)</dt><dd><tt>Enable/disable&nbsp;suppressing&nbsp;memory&nbsp;pressure&nbsp;notifications.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;suppressed:&nbsp;If&nbsp;true,&nbsp;memory&nbsp;pressure&nbsp;notifications&nbsp;will&nbsp;be&nbsp;suppressed.<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;timeout&nbsp;in&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;MemoryTimeoutException:&nbsp;If&nbsp;more&nbsp;than&nbsp;|timeout|&nbsp;seconds&nbsp;has&nbsp;passed<br>
-&nbsp;&nbsp;since&nbsp;the&nbsp;last&nbsp;time&nbsp;any&nbsp;data&nbsp;is&nbsp;received.<br>
-&nbsp;&nbsp;MemoryUnrecoverableException:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;websocket&nbsp;error.<br>
-&nbsp;&nbsp;MemoryUnexpectedResponseException:&nbsp;If&nbsp;the&nbsp;response&nbsp;contains&nbsp;an&nbsp;error<br>
-&nbsp;&nbsp;or&nbsp;does&nbsp;not&nbsp;contain&nbsp;the&nbsp;expected&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=30</font>)</dt><dd><tt>Simulate&nbsp;a&nbsp;memory&nbsp;pressure&nbsp;notification.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;pressure&nbsp;level:&nbsp;The&nbsp;memory&nbsp;pressure&nbsp;level&nbsp;of&nbsp;the&nbsp;notification&nbsp;('moderate'<br>
-&nbsp;&nbsp;or&nbsp;'critical').<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;timeout&nbsp;in&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;MemoryTimeoutException:&nbsp;If&nbsp;more&nbsp;than&nbsp;|timeout|&nbsp;seconds&nbsp;has&nbsp;passed<br>
-&nbsp;&nbsp;since&nbsp;the&nbsp;last&nbsp;time&nbsp;any&nbsp;data&nbsp;is&nbsp;received.<br>
-&nbsp;&nbsp;MemoryUnrecoverableException:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;websocket&nbsp;error.<br>
-&nbsp;&nbsp;MemoryUnexpectedResponseException:&nbsp;If&nbsp;the&nbsp;response&nbsp;contains&nbsp;an&nbsp;error<br>
-&nbsp;&nbsp;or&nbsp;does&nbsp;not&nbsp;contain&nbsp;the&nbsp;expected&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-StartChromeTracing"><strong>StartChromeTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=10</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_options:&nbsp;An&nbsp;tracing_options.TracingOptions&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;custom_categories:&nbsp;An&nbsp;optional&nbsp;string&nbsp;containing&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comma&nbsp;separated&nbsp;categories&nbsp;that&nbsp;will&nbsp;be&nbsp;traced<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;instead&nbsp;of&nbsp;the&nbsp;default&nbsp;category&nbsp;set.&nbsp;&nbsp;Example:&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"webkit,cc,disabled-by-default-cc.debug"&nbsp;to&nbsp;trace&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;those&nbsp;three&nbsp;event&nbsp;categories.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientBackend-StopChromeTracing"><strong>StopChromeTracing</strong></a>(self, trace_data_builder, timeout<font color="#909090">=30</font>)</dt></dl>
-
-<dl><dt><a name="DevToolsClientBackend-__init__"><strong>__init__</strong></a>(self, devtools_port, remote_devtools_port, app_backend)</dt><dd><tt>Creates&nbsp;a&nbsp;new&nbsp;<a href="#DevToolsClientBackend">DevToolsClientBackend</a>.<br>
-&nbsp;<br>
-A&nbsp;DevTools&nbsp;agent&nbsp;must&nbsp;exist&nbsp;on&nbsp;the&nbsp;given&nbsp;devtools_port.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;devtools_port:&nbsp;The&nbsp;port&nbsp;to&nbsp;use&nbsp;to&nbsp;connect&nbsp;to&nbsp;DevTools&nbsp;agent.<br>
-&nbsp;&nbsp;remote_devtools_port:&nbsp;In&nbsp;some&nbsp;cases&nbsp;(e.g.,&nbsp;app&nbsp;running&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Android&nbsp;device,&nbsp;devtools_port&nbsp;is&nbsp;the&nbsp;forwarded&nbsp;port&nbsp;on&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host&nbsp;platform.&nbsp;We&nbsp;also&nbsp;need&nbsp;to&nbsp;know&nbsp;the&nbsp;remote_devtools_port<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;so&nbsp;that&nbsp;we&nbsp;can&nbsp;uniquely&nbsp;identify&nbsp;the&nbsp;DevTools&nbsp;agent.<br>
-&nbsp;&nbsp;app_backend:&nbsp;For&nbsp;the&nbsp;app&nbsp;that&nbsp;contains&nbsp;the&nbsp;DevTools&nbsp;agent.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_tracing_running</strong></dt>
-</dl>
-<dl><dt><strong>remote_port</strong></dt>
-</dl>
-<dl><dt><strong>support_startup_tracing</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TabNotFoundError">class <strong>TabNotFoundError</strong></a>(<a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html#TabNotFoundError">TabNotFoundError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><a name="TabNotFoundError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="TabNotFoundError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TabNotFoundError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TabNotFoundError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TabNotFoundError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TabNotFoundError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TabNotFoundError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TabNotFoundError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TabNotFoundError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TabNotFoundError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TabNotFoundError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TabNotFoundError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TabNotFoundError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-IsDevToolsAgentAvailable"><strong>IsDevToolsAgentAvailable</strong></a>(port, app_backend)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;a&nbsp;DevTools&nbsp;agent&nbsp;is&nbsp;available&nbsp;on&nbsp;the&nbsp;given&nbsp;port.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>BROWSER_INSPECTOR_WEBSOCKET_URL</strong> = 'ws://127.0.0.1:%i/devtools/browser'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.devtools_http.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.devtools_http.html
deleted file mode 100644
index 03dfd8b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.devtools_http.html
+++ /dev/null
@@ -1,240 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.devtools_http</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.devtools_http</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/devtools_http.py">telemetry/internal/backends/chrome_inspector/devtools_http.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="errno.html">errno</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="httplib.html">httplib</a><br>
-<a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="socket.html">socket</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsHttp">DevToolsHttp</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsClientConnectionError">DevToolsClientConnectionError</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsClientUrlError">DevToolsClientUrlError</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DevToolsClientConnectionError">class <strong>DevToolsClientConnectionError</strong></a>(<a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsClientConnectionError">DevToolsClientConnectionError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><a name="DevToolsClientConnectionError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DevToolsClientConnectionError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DevToolsClientConnectionError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientConnectionError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientConnectionError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientConnectionError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientConnectionError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientConnectionError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientConnectionError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DevToolsClientConnectionError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DevToolsClientUrlError">class <strong>DevToolsClientUrlError</strong></a>(<a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsClientConnectionError">DevToolsClientConnectionError</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsClientUrlError">DevToolsClientUrlError</a></dd>
-<dd><a href="telemetry.internal.backends.chrome_inspector.devtools_http.html#DevToolsClientConnectionError">DevToolsClientConnectionError</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><a name="DevToolsClientUrlError-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DevToolsClientUrlError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DevToolsClientUrlError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientUrlError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientUrlError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientUrlError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientUrlError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientUrlError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DevToolsClientUrlError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DevToolsClientUrlError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DevToolsHttp">class <strong>DevToolsHttp</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;helper&nbsp;class&nbsp;to&nbsp;send&nbsp;and&nbsp;parse&nbsp;DevTools&nbsp;HTTP&nbsp;requests.<br>
-&nbsp;<br>
-This&nbsp;class&nbsp;maintains&nbsp;a&nbsp;persistent&nbsp;http&nbsp;connection&nbsp;to&nbsp;Chrome&nbsp;devtools.<br>
-Ideally,&nbsp;owners&nbsp;of&nbsp;instances&nbsp;of&nbsp;this&nbsp;class&nbsp;should&nbsp;call&nbsp;<a href="#DevToolsHttp-Disconnect">Disconnect</a>()&nbsp;before<br>
-disposing&nbsp;of&nbsp;the&nbsp;instance.&nbsp;Otherwise,&nbsp;the&nbsp;connection&nbsp;will&nbsp;not&nbsp;be&nbsp;closed&nbsp;until<br>
-the&nbsp;instance&nbsp;is&nbsp;garbage&nbsp;collected.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="DevToolsHttp-Disconnect"><strong>Disconnect</strong></a>(self)</dt><dd><tt>Closes&nbsp;the&nbsp;HTTP&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsHttp-Request"><strong>Request</strong></a>(self, path, timeout<font color="#909090">=30</font>)</dt><dd><tt>Sends&nbsp;a&nbsp;request&nbsp;to&nbsp;Chrome&nbsp;devtools.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;lazily&nbsp;creates&nbsp;an&nbsp;HTTP&nbsp;connection,&nbsp;if&nbsp;one&nbsp;does&nbsp;not&nbsp;already<br>
-exist.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;The&nbsp;DevTools&nbsp;URL&nbsp;path,&nbsp;without&nbsp;the&nbsp;/json/&nbsp;prefix.<br>
-&nbsp;&nbsp;timeout:&nbsp;Timeout&nbsp;defaults&nbsp;to&nbsp;30&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#DevToolsClientConnectionError">DevToolsClientConnectionError</a>:&nbsp;If&nbsp;the&nbsp;connection&nbsp;fails.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsHttp-RequestJson"><strong>RequestJson</strong></a>(self, path, timeout<font color="#909090">=30</font>)</dt><dd><tt>Sends&nbsp;a&nbsp;request&nbsp;and&nbsp;parse&nbsp;the&nbsp;response&nbsp;as&nbsp;JSON.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;The&nbsp;DevTools&nbsp;URL&nbsp;path,&nbsp;without&nbsp;the&nbsp;/json/&nbsp;prefix.<br>
-&nbsp;&nbsp;timeout:&nbsp;Timeout&nbsp;defaults&nbsp;to&nbsp;30&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#DevToolsClientConnectionError">DevToolsClientConnectionError</a>:&nbsp;If&nbsp;the&nbsp;connection&nbsp;fails.<br>
-&nbsp;&nbsp;ValueError:&nbsp;If&nbsp;the&nbsp;response&nbsp;is&nbsp;not&nbsp;a&nbsp;valid&nbsp;JSON.</tt></dd></dl>
-
-<dl><dt><a name="DevToolsHttp-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DevToolsHttp-__init__"><strong>__init__</strong></a>(self, devtools_port)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.html
deleted file mode 100644
index 0fc43b0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.backends.chrome_inspector</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.chrome_inspector</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/__init__.py">telemetry/internal/backends/chrome_inspector/__init__.py</a></font></td></tr></table>
-    <p><tt>This&nbsp;package&nbsp;contains&nbsp;classes&nbsp;and&nbsp;methods&nbsp;for&nbsp;controlling&nbsp;the&nbsp;chrome<br>
-devtool.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html">devtools_client_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend_unittest.html">devtools_client_backend_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.devtools_http.html">devtools_http</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.devtools_http_unittest.html">devtools_http_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_backend.html">inspector_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html">inspector_backend_list</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_console.html">inspector_console</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_console_unittest.html">inspector_console_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_memory.html">inspector_memory</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_memory_unittest.html">inspector_memory_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_network.html">inspector_network</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_network_unittest.html">inspector_network_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_page.html">inspector_page</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_page_unittest.html">inspector_page_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_runtime.html">inspector_runtime</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_runtime_unittest.html">inspector_runtime_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html">inspector_websocket</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_websocket_unittest.html">inspector_websocket_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html">memory_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.memory_backend_unittest.html">memory_backend_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html">tracing_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.tracing_backend_unittest.html">tracing_backend_unittest</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.websocket.html">websocket</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.websocket_unittest.html">websocket_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_backend.html
deleted file mode 100644
index cab059e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_backend.html
+++ /dev/null
@@ -1,177 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_backend.py">telemetry/internal/backends/chrome_inspector/inspector_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.devtools_http.html">telemetry.internal.backends.chrome_inspector.devtools_http</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="functools.html">functools</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_console.html">telemetry.internal.backends.chrome_inspector.inspector_console</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_memory.html">telemetry.internal.backends.chrome_inspector.inspector_memory</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_network.html">telemetry.internal.backends.chrome_inspector.inspector_network</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_page.html">telemetry.internal.backends.chrome_inspector.inspector_page</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_runtime.html">telemetry.internal.backends.chrome_inspector.inspector_runtime</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html">telemetry.internal.backends.chrome_inspector.inspector_websocket</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-<a href="socket.html">socket</a><br>
-<a href="sys.html">sys</a><br>
-<a href="telemetry.timeline.model.html">telemetry.timeline.model</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.websocket.html">telemetry.internal.backends.chrome_inspector.websocket</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_backend.html#InspectorBackend">InspectorBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorBackend">class <strong>InspectorBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Class&nbsp;for&nbsp;communicating&nbsp;with&nbsp;a&nbsp;devtools&nbsp;client.<br>
-&nbsp;<br>
-The&nbsp;owner&nbsp;of&nbsp;an&nbsp;instance&nbsp;of&nbsp;this&nbsp;class&nbsp;is&nbsp;responsible&nbsp;for&nbsp;calling<br>
-<a href="#InspectorBackend-Disconnect">Disconnect</a>()&nbsp;before&nbsp;disposing&nbsp;of&nbsp;the&nbsp;instance.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorBackend-ClearCache"><strong>ClearCache</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-CollectGarbage"><strong>CollectGarbage</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-Disconnect"><strong>Disconnect</strong></a>(self)</dt><dd><tt>Disconnects&nbsp;the&nbsp;inspector&nbsp;websocket.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;intentionally&nbsp;leaves&nbsp;the&nbsp;self.<strong>_websocket</strong>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;around,&nbsp;so&nbsp;that<br>
-future&nbsp;calls&nbsp;it&nbsp;to&nbsp;it&nbsp;will&nbsp;fail&nbsp;with&nbsp;a&nbsp;relevant&nbsp;error.</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-EnableAllContexts"><strong>EnableAllContexts</strong></a>(inspector_backend, *args, **kwargs)</dt><dd><tt>Allows&nbsp;access&nbsp;to&nbsp;iframes.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-EvaluateJavaScript"><strong>EvaluateJavaScript</strong></a>(inspector_backend, *args, **kwargs)</dt><dd><tt>Evaluates&nbsp;a&nbsp;javascript&nbsp;expression&nbsp;and&nbsp;returns&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-ExecuteJavaScript"><strong>ExecuteJavaScript</strong></a>(inspector_backend, *args, **kwargs)</dt><dd><tt>Executes&nbsp;a&nbsp;javascript&nbsp;expression&nbsp;without&nbsp;returning&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-GetCookieByName"><strong>GetCookieByName</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-GetDOMStats"><strong>GetDOMStats</strong></a>(inspector_backend, *args, **kwargs)</dt><dd><tt>Gets&nbsp;memory&nbsp;stats&nbsp;from&nbsp;the&nbsp;DOM.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;inspector_memory.InspectorMemoryException<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-GetWebviewInspectorBackends"><strong>GetWebviewInspectorBackends</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;<a href="#InspectorBackend">InspectorBackend</a>&nbsp;instances&nbsp;associated&nbsp;with&nbsp;webviews.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-IsInspectable"><strong>IsInspectable</strong></a>(self)</dt><dd><tt>Whether&nbsp;the&nbsp;tab&nbsp;is&nbsp;inspectable,&nbsp;as&nbsp;reported&nbsp;by&nbsp;devtools.</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-Navigate"><strong>Navigate</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-Screenshot"><strong>Screenshot</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-StartTimelineRecording"><strong>StartTimelineRecording</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-StopTimelineRecording"><strong>StopTimelineRecording</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-SynthesizeScrollGesture"><strong>SynthesizeScrollGesture</strong></a>(inspector_backend, *args, **kwargs)</dt><dd><tt>Runs&nbsp;an&nbsp;inspector&nbsp;command&nbsp;that&nbsp;causes&nbsp;a&nbsp;repeatable&nbsp;browser&nbsp;driven&nbsp;scroll.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x:&nbsp;X&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;y:&nbsp;Y&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;xDistance:&nbsp;Distance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;X&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;left).<br>
-&nbsp;&nbsp;yDistance:&nbsp;Distance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;up).<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;X&nbsp;axis.<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis.<br>
-&nbsp;&nbsp;preventFling:&nbsp;Prevents&nbsp;a&nbsp;fling&nbsp;gesture.<br>
-&nbsp;&nbsp;speed:&nbsp;Swipe&nbsp;speed&nbsp;in&nbsp;pixels&nbsp;per&nbsp;second.<br>
-&nbsp;&nbsp;gestureSourceType:&nbsp;Which&nbsp;type&nbsp;of&nbsp;input&nbsp;events&nbsp;to&nbsp;be&nbsp;generated.<br>
-&nbsp;&nbsp;repeatCount:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;repeats&nbsp;beyond&nbsp;the&nbsp;first&nbsp;scroll.<br>
-&nbsp;&nbsp;repeatDelayMs:&nbsp;Number&nbsp;of&nbsp;milliseconds&nbsp;delay&nbsp;between&nbsp;each&nbsp;repeat.<br>
-&nbsp;&nbsp;interactionMarkerName:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;interaction&nbsp;markers&nbsp;to&nbsp;generate.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackend-WaitForNavigate"><strong>WaitForNavigate</strong></a>(inspector_backend, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorBackend-__init__"><strong>__init__</strong></a>(self, app, devtools_client, context, timeout<font color="#909090">=60</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>debugger_url</strong></dt>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-<dl><dt><strong>message_output_stream</strong></dt>
-</dl>
-<dl><dt><strong>screenshot_supported</strong></dt>
-</dl>
-<dl><dt><strong>timeline_model</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;of&nbsp;the&nbsp;tab,&nbsp;as&nbsp;reported&nbsp;by&nbsp;devtools.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_backend_list.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_backend_list.html
deleted file mode 100644
index 6424181..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_backend_list.html
+++ /dev/null
@@ -1,141 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_backend_list</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_backend_list</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_backend_list.py">telemetry/internal/backends/chrome_inspector/inspector_backend_list.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="_abcoll.html#Sequence">_abcoll.Sequence</a>(<a href="_abcoll.html#Sized">_abcoll.Sized</a>, <a href="_abcoll.html#Iterable">_abcoll.Iterable</a>, <a href="_abcoll.html#Container">_abcoll.Container</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">InspectorBackendList</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorBackendList">class <strong>InspectorBackendList</strong></a>(<a href="_abcoll.html#Sequence">_abcoll.Sequence</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;dynamic&nbsp;sequence&nbsp;of&nbsp;active&nbsp;InspectorBackends.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_backend_list.html#InspectorBackendList">InspectorBackendList</a></dd>
-<dd><a href="_abcoll.html#Sequence">_abcoll.Sequence</a></dd>
-<dd><a href="_abcoll.html#Sized">_abcoll.Sized</a></dd>
-<dd><a href="_abcoll.html#Iterable">_abcoll.Iterable</a></dd>
-<dd><a href="_abcoll.html#Container">_abcoll.Container</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="InspectorBackendList-CreateWrapper"><strong>CreateWrapper</strong></a>(self, inspector_backend_instance)</dt><dd><tt>Override&nbsp;to&nbsp;return&nbsp;the&nbsp;wrapper&nbsp;API&nbsp;over&nbsp;InspectorBackend.<br>
-&nbsp;<br>
-The&nbsp;wrapper&nbsp;API&nbsp;is&nbsp;the&nbsp;public&nbsp;interface&nbsp;for&nbsp;InspectorBackend.&nbsp;It<br>
-may&nbsp;expose&nbsp;whatever&nbsp;methods&nbsp;are&nbsp;desired&nbsp;on&nbsp;top&nbsp;of&nbsp;that&nbsp;backend.</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackendList-GetBackendFromContextId"><strong>GetBackendFromContextId</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-GetContextInfo"><strong>GetContextInfo</strong></a>(self, context_id)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-GetTabById"><strong>GetTabById</strong></a>(self, identifier)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-IterContextIds"><strong>IterContextIds</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-ShouldIncludeContext"><strong>ShouldIncludeContext</strong></a>(self, _)</dt><dd><tt>Override&nbsp;this&nbsp;method&nbsp;to&nbsp;control&nbsp;which&nbsp;contexts&nbsp;are&nbsp;included.</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackendList-__getitem__"><strong>__getitem__</strong></a>(self, index)</dt><dd><tt>#&nbsp;TODO(nednguyen):&nbsp;Remove&nbsp;this&nbsp;method&nbsp;and&nbsp;turn&nbsp;inspector_backend_list&nbsp;API&nbsp;to<br>
-#&nbsp;dictionary-like&nbsp;API&nbsp;(crbug.com/398467)</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackendList-__init__"><strong>__init__</strong></a>(self, browser_backend)</dt><dd><tt>Constructor.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_backend:&nbsp;The&nbsp;BrowserBackend&nbsp;instance&nbsp;to&nbsp;query&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InspectorBackends.</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackendList-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Methods inherited from <a href="_abcoll.html#Sequence">_abcoll.Sequence</a>:<br>
-<dl><dt><a name="InspectorBackendList-__contains__"><strong>__contains__</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-__reversed__"><strong>__reversed__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorBackendList-count"><strong>count</strong></a>(self, value)</dt><dd><tt>S.<a href="#InspectorBackendList-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="InspectorBackendList-index"><strong>index</strong></a>(self, value)</dt><dd><tt>S.<a href="#InspectorBackendList-index">index</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><a name="InspectorBackendList-__subclasshook__"><strong>__subclasshook__</strong></a>(cls, C)<font color="#909090"><font face="helvetica, arial"> from <a href="abc.html#ABCMeta">abc.ABCMeta</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-DebuggerUrlToId"><strong>DebuggerUrlToId</strong></a>(debugger_url)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_console.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_console.html
deleted file mode 100644
index 7ce3e88..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_console.html
+++ /dev/null
@@ -1,52 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_console</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_console</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_console.py">telemetry/internal/backends/chrome_inspector/inspector_console.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_console.html#InspectorConsole">InspectorConsole</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorConsole">class <strong>InspectorConsole</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorConsole-__init__"><strong>__init__</strong></a>(self, inspector_websocket)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>message_output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_memory.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_memory.html
deleted file mode 100644
index d3648d1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_memory.html
+++ /dev/null
@@ -1,148 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_memory</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_memory</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_memory.py">telemetry/internal/backends/chrome_inspector/inspector_memory.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_memory.html#InspectorMemory">InspectorMemory</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_memory.html#InspectorMemoryException">InspectorMemoryException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorMemory">class <strong>InspectorMemory</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Communicates&nbsp;with&nbsp;the&nbsp;remote&nbsp;inspector's&nbsp;Memory&nbsp;domain.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorMemory-GetDOMCounters"><strong>GetDOMCounters</strong></a>(self, timeout)</dt><dd><tt>Retrieves&nbsp;DOM&nbsp;element&nbsp;counts.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;inspector&nbsp;backend&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;service&nbsp;the&nbsp;request&nbsp;before&nbsp;timing&nbsp;out.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;dictionary&nbsp;containing&nbsp;the&nbsp;counts&nbsp;associated&nbsp;with&nbsp;"nodes",&nbsp;"documents",<br>
-&nbsp;&nbsp;and&nbsp;"jsEventListeners".<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#InspectorMemoryException">InspectorMemoryException</a><br>
-&nbsp;&nbsp;websocket.WebSocketException<br>
-&nbsp;&nbsp;socket.error<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemory-__init__"><strong>__init__</strong></a>(self, inspector_websocket)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorMemoryException">class <strong>InspectorMemoryException</strong></a>(<a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_memory.html#InspectorMemoryException">InspectorMemoryException</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><a name="InspectorMemoryException-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="InspectorMemoryException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#InspectorMemoryException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="InspectorMemoryException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorMemoryException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorMemoryException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorMemoryException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorMemoryException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InspectorMemoryException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorMemoryException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorMemoryException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="InspectorMemoryException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InspectorMemoryException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_network.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_network.html
deleted file mode 100644
index 62e02a3..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_network.html
+++ /dev/null
@@ -1,209 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_network</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_network</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_network.py">telemetry/internal/backends/chrome_inspector/inspector_network.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_network.html#InspectorNetwork">InspectorNetwork</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_network.html#InspectorNetworkResponseData">InspectorNetworkResponseData</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_network.html#TimelineRecorder">TimelineRecorder</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_network.html#InspectorNetworkException">InspectorNetworkException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorNetwork">class <strong>InspectorNetwork</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorNetwork-ClearCache"><strong>ClearCache</strong></a>(self, timeout<font color="#909090">=60</font>)</dt><dd><tt>Clears&nbsp;the&nbsp;browser's&nbsp;disk&nbsp;and&nbsp;memory&nbsp;cache.</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetwork-ClearResponseData"><strong>ClearResponseData</strong></a>(self)</dt><dd><tt>Clears&nbsp;recorded&nbsp;HTTP&nbsp;responses.</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetwork-GetHTTPResponseBody"><strong>GetHTTPResponseBody</strong></a>(self, request_id, timeout<font color="#909090">=60</font>)</dt></dl>
-
-<dl><dt><a name="InspectorNetwork-GetResponseData"><strong>GetResponseData</strong></a>(self)</dt><dd><tt>Returns&nbsp;all&nbsp;recorded&nbsp;HTTP&nbsp;responses.</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetwork-HTTPResponseServedFromCache"><strong>HTTPResponseServedFromCache</strong></a>(self, request_id)</dt></dl>
-
-<dl><dt><a name="InspectorNetwork-StartMonitoringNetwork"><strong>StartMonitoringNetwork</strong></a>(self)</dt><dd><tt>Starts&nbsp;monitoring&nbsp;network&nbsp;notifications&nbsp;and&nbsp;recording&nbsp;HTTP&nbsp;responses.</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetwork-StopMonitoringNetwork"><strong>StopMonitoringNetwork</strong></a>(self)</dt><dd><tt>Stops&nbsp;monitoring&nbsp;network&nbsp;notifications&nbsp;and&nbsp;recording&nbsp;HTTP&nbsp;responses.</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetwork-__init__"><strong>__init__</strong></a>(self, inspector_websocket)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>timeline_recorder</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorNetworkException">class <strong>InspectorNetworkException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_network.html#InspectorNetworkException">InspectorNetworkException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="InspectorNetworkException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#InspectorNetworkException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="InspectorNetworkException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InspectorNetworkException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InspectorNetworkException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#InspectorNetworkException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="InspectorNetworkException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorNetworkResponseData">class <strong>InspectorNetworkResponseData</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorNetworkResponseData-AsTimelineEvent"><strong>AsTimelineEvent</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorNetworkResponseData-GetBody"><strong>GetBody</strong></a>(self, timeout<font color="#909090">=60</font>)</dt></dl>
-
-<dl><dt><a name="InspectorNetworkResponseData-GetHeader"><strong>GetHeader</strong></a>(self, name)</dt></dl>
-
-<dl><dt><a name="InspectorNetworkResponseData-__init__"><strong>__init__</strong></a>(self, inspector_network, params)</dt></dl>
-
-<dl><dt><a name="InspectorNetworkResponseData-status_text"><strong>status_text</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="InspectorNetworkResponseData-FromTimelineEvent"><strong>FromTimelineEvent</strong></a>(event)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>headers</strong></dt>
-</dl>
-<dl><dt><strong>request_headers</strong></dt>
-</dl>
-<dl><dt><strong>request_id</strong></dt>
-</dl>
-<dl><dt><strong>served_from_cache</strong></dt>
-</dl>
-<dl><dt><strong>status</strong></dt>
-</dl>
-<dl><dt><strong>timestamp</strong></dt>
-</dl>
-<dl><dt><strong>timing</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineRecorder">class <strong>TimelineRecorder</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimelineRecorder-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineRecorder-Stop"><strong>Stop</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineRecorder-__init__"><strong>__init__</strong></a>(self, inspector_network)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_page.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_page.html
deleted file mode 100644
index b0e110d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_page.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_page</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_page</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_page.py">telemetry/internal/backends/chrome_inspector/inspector_page.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.util.image_util.html">telemetry.util.image_util</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_page.html#InspectorPage">InspectorPage</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorPage">class <strong>InspectorPage</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Class&nbsp;that&nbsp;controls&nbsp;a&nbsp;page&nbsp;connected&nbsp;by&nbsp;an&nbsp;inspector_websocket.<br>
-&nbsp;<br>
-This&nbsp;class&nbsp;provides&nbsp;utility&nbsp;methods&nbsp;for&nbsp;controlling&nbsp;a&nbsp;page&nbsp;connected&nbsp;by&nbsp;an<br>
-inspector_websocket.&nbsp;It&nbsp;does&nbsp;not&nbsp;perform&nbsp;any&nbsp;exception&nbsp;handling.&nbsp;All<br>
-inspector_websocket&nbsp;exceptions&nbsp;must&nbsp;be&nbsp;handled&nbsp;by&nbsp;the&nbsp;caller.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorPage-CaptureScreenshot"><strong>CaptureScreenshot</strong></a>(self, timeout<font color="#909090">=60</font>)</dt></dl>
-
-<dl><dt><a name="InspectorPage-CollectGarbage"><strong>CollectGarbage</strong></a>(self, timeout<font color="#909090">=60</font>)</dt></dl>
-
-<dl><dt><a name="InspectorPage-GetCookieByName"><strong>GetCookieByName</strong></a>(self, name, timeout<font color="#909090">=60</font>)</dt><dd><tt>Returns&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;cookie&nbsp;by&nbsp;the&nbsp;given&nbsp;|name|.</tt></dd></dl>
-
-<dl><dt><a name="InspectorPage-Navigate"><strong>Navigate</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout<font color="#909090">=60</font>)</dt><dd><tt>Navigates&nbsp;to&nbsp;|url|.<br>
-&nbsp;<br>
-If&nbsp;|script_to_evaluate_on_commit|&nbsp;is&nbsp;given,&nbsp;the&nbsp;script&nbsp;source&nbsp;string&nbsp;will&nbsp;be<br>
-evaluated&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;committed.&nbsp;This&nbsp;is&nbsp;after&nbsp;the&nbsp;context&nbsp;of<br>
-the&nbsp;page&nbsp;exists,&nbsp;but&nbsp;before&nbsp;any&nbsp;script&nbsp;on&nbsp;the&nbsp;page&nbsp;itself&nbsp;has&nbsp;executed.</tt></dd></dl>
-
-<dl><dt><a name="InspectorPage-WaitForNavigate"><strong>WaitForNavigate</strong></a>(self, timeout<font color="#909090">=60</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;navigation&nbsp;to&nbsp;complete.<br>
-&nbsp;<br>
-The&nbsp;current&nbsp;page&nbsp;is&nbsp;expect&nbsp;to&nbsp;be&nbsp;in&nbsp;a&nbsp;navigation.&nbsp;This&nbsp;function&nbsp;returns<br>
-when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;complete&nbsp;or&nbsp;when&nbsp;the&nbsp;timeout&nbsp;has&nbsp;been&nbsp;exceeded.</tt></dd></dl>
-
-<dl><dt><a name="InspectorPage-__init__"><strong>__init__</strong></a>(self, inspector_websocket, timeout<font color="#909090">=60</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_runtime.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_runtime.html
deleted file mode 100644
index bcbf564..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_runtime.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_runtime</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_runtime</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_runtime.py">telemetry/internal/backends/chrome_inspector/inspector_runtime.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_runtime.html#InspectorRuntime">InspectorRuntime</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorRuntime">class <strong>InspectorRuntime</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorRuntime-EnableAllContexts"><strong>EnableAllContexts</strong></a>(self)</dt><dd><tt>Allow&nbsp;access&nbsp;to&nbsp;iframes.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;websocket.WebSocketException<br>
-&nbsp;&nbsp;socket.error</tt></dd></dl>
-
-<dl><dt><a name="InspectorRuntime-Evaluate"><strong>Evaluate</strong></a>(self, expr, context_id, timeout)</dt><dd><tt>Evaluates&nbsp;a&nbsp;javascript&nbsp;expression&nbsp;and&nbsp;returns&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-|context_id|&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.&nbsp;The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the<br>
-first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;websocket.WebSocketException<br>
-&nbsp;&nbsp;socket.error</tt></dd></dl>
-
-<dl><dt><a name="InspectorRuntime-Execute"><strong>Execute</strong></a>(self, expr, context_id, timeout)</dt></dl>
-
-<dl><dt><a name="InspectorRuntime-RunInspectorCommand"><strong>RunInspectorCommand</strong></a>(self, command, timeout)</dt><dd><tt>Runs&nbsp;an&nbsp;inspector&nbsp;command.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;websocket.WebSocketException<br>
-&nbsp;&nbsp;socket.error</tt></dd></dl>
-
-<dl><dt><a name="InspectorRuntime-__init__"><strong>__init__</strong></a>(self, inspector_websocket)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_websocket.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_websocket.html
deleted file mode 100644
index 9c1ddda..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.inspector_websocket.html
+++ /dev/null
@@ -1,200 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.inspector_websocket</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.inspector_websocket</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/inspector_websocket.py">telemetry/internal/backends/chrome_inspector/inspector_websocket.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="errno.html">errno</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="socket.html">socket</a><br>
-<a href="time.html">time</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.websocket.html">telemetry.internal.backends.chrome_inspector.websocket</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html#InspectorWebsocket">InspectorWebsocket</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html#WebSocketDisconnected">WebSocketDisconnected</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorWebsocket">class <strong>InspectorWebsocket</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="InspectorWebsocket-AsyncRequest"><strong>AsyncRequest</strong></a>(self, req, callback)</dt><dd><tt>Sends&nbsp;an&nbsp;async&nbsp;request&nbsp;and&nbsp;returns&nbsp;immediately.<br>
-&nbsp;<br>
-Response&nbsp;will&nbsp;be&nbsp;handled&nbsp;in&nbsp;the&nbsp;|callback|&nbsp;later&nbsp;when&nbsp;DispatchNotifications<br>
-is&nbsp;invoked.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;callback:&nbsp;a&nbsp;function&nbsp;that&nbsp;takes&nbsp;inspector's&nbsp;response&nbsp;as&nbsp;the&nbsp;argument.</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-Connect"><strong>Connect</strong></a>(self, url, timeout<font color="#909090">=10</font>)</dt><dd><tt>Connects&nbsp;the&nbsp;websocket.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;websocket.WebSocketException<br>
-&nbsp;&nbsp;socket.error</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-Disconnect"><strong>Disconnect</strong></a>(self)</dt><dd><tt>Disconnects&nbsp;the&nbsp;inspector&nbsp;websocket.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;websocket.WebSocketException<br>
-&nbsp;&nbsp;socket.error</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-DispatchNotifications"><strong>DispatchNotifications</strong></a>(self, timeout<font color="#909090">=10</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;responses&nbsp;from&nbsp;the&nbsp;websocket,&nbsp;dispatching&nbsp;them&nbsp;as&nbsp;necessary.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;websocket.WebSocketException:&nbsp;<a href="telemetry.core.exceptions.html#Error">Error</a>&nbsp;from&nbsp;websocket&nbsp;library.<br>
-&nbsp;&nbsp;socket.error:&nbsp;<a href="telemetry.core.exceptions.html#Error">Error</a>&nbsp;from&nbsp;websocket&nbsp;library.<br>
-&nbsp;&nbsp;exceptions.<a href="#WebSocketDisconnected">WebSocketDisconnected</a>:&nbsp;The&nbsp;socket&nbsp;was&nbsp;disconnected.</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-RegisterDomain"><strong>RegisterDomain</strong></a>(self, domain_name, notification_handler)</dt><dd><tt>Registers&nbsp;a&nbsp;given&nbsp;domain&nbsp;for&nbsp;handling&nbsp;notification&nbsp;methods.<br>
-&nbsp;<br>
-For&nbsp;example,&nbsp;given&nbsp;inspector_backend:<br>
-&nbsp;&nbsp;&nbsp;def&nbsp;OnConsoleNotification(msg):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;msg['method']&nbsp;==&nbsp;'Console.messageAdded':<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;msg['params']['message']<br>
-&nbsp;&nbsp;&nbsp;inspector_backend.<a href="#InspectorWebsocket-RegisterDomain">RegisterDomain</a>('Console',&nbsp;OnConsoleNotification)<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;domain_name:&nbsp;The&nbsp;devtools&nbsp;domain&nbsp;name.&nbsp;E.g.,&nbsp;'Tracing',&nbsp;'Memory',&nbsp;'Page'.<br>
-&nbsp;&nbsp;notification_handler:&nbsp;Handler&nbsp;for&nbsp;devtools&nbsp;notification.&nbsp;Will&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;called&nbsp;if&nbsp;a&nbsp;devtools&nbsp;notification&nbsp;with&nbsp;matching&nbsp;domain&nbsp;is&nbsp;received<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;via&nbsp;DispatchNotifications.&nbsp;The&nbsp;handler&nbsp;accepts&nbsp;a&nbsp;single&nbsp;paramater:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;JSON&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;representing&nbsp;the&nbsp;notification.</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-SendAndIgnoreResponse"><strong>SendAndIgnoreResponse</strong></a>(self, req)</dt><dd><tt>Sends&nbsp;a&nbsp;request&nbsp;without&nbsp;waiting&nbsp;for&nbsp;a&nbsp;response.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;websocket.WebSocketException:&nbsp;<a href="telemetry.core.exceptions.html#Error">Error</a>&nbsp;from&nbsp;websocket&nbsp;library.<br>
-&nbsp;&nbsp;socket.error:&nbsp;<a href="telemetry.core.exceptions.html#Error">Error</a>&nbsp;from&nbsp;websocket&nbsp;library.<br>
-&nbsp;&nbsp;exceptions.<a href="#WebSocketDisconnected">WebSocketDisconnected</a>:&nbsp;The&nbsp;socket&nbsp;was&nbsp;disconnected.</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-SyncRequest"><strong>SyncRequest</strong></a>(self, req, timeout<font color="#909090">=10</font>)</dt><dd><tt>Sends&nbsp;a&nbsp;request&nbsp;and&nbsp;waits&nbsp;for&nbsp;a&nbsp;response.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;websocket.WebSocketException:&nbsp;<a href="telemetry.core.exceptions.html#Error">Error</a>&nbsp;from&nbsp;websocket&nbsp;library.<br>
-&nbsp;&nbsp;socket.error:&nbsp;<a href="telemetry.core.exceptions.html#Error">Error</a>&nbsp;from&nbsp;websocket&nbsp;library.<br>
-&nbsp;&nbsp;exceptions.<a href="#WebSocketDisconnected">WebSocketDisconnected</a>:&nbsp;The&nbsp;socket&nbsp;was&nbsp;disconnected.</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-UnregisterDomain"><strong>UnregisterDomain</strong></a>(self, domain_name)</dt><dd><tt>Unregisters&nbsp;a&nbsp;previously&nbsp;registered&nbsp;domain.</tt></dd></dl>
-
-<dl><dt><a name="InspectorWebsocket-__init__"><strong>__init__</strong></a>(self)</dt><dd><tt>Create&nbsp;a&nbsp;websocket&nbsp;handler&nbsp;for&nbsp;communicating&nbsp;with&nbsp;Inspectors.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>METHOD_NOT_FOUND_CODE</strong> = -32601</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebSocketDisconnected">class <strong>WebSocketDisconnected</strong></a>(<a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;attempt&nbsp;was&nbsp;made&nbsp;to&nbsp;use&nbsp;a&nbsp;web&nbsp;socket&nbsp;after&nbsp;it&nbsp;had&nbsp;been&nbsp;disconnected.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html#WebSocketDisconnected">WebSocketDisconnected</a></dd>
-<dd><a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><a name="WebSocketDisconnected-AddDebuggingMessage"><strong>AddDebuggingMessage</strong></a>(self, msg)</dt><dd><tt>Adds&nbsp;a&nbsp;message&nbsp;to&nbsp;the&nbsp;description&nbsp;of&nbsp;the&nbsp;exception.<br>
-&nbsp;<br>
-Many&nbsp;Telemetry&nbsp;exceptions&nbsp;arise&nbsp;from&nbsp;failures&nbsp;in&nbsp;another&nbsp;application.&nbsp;These<br>
-failures&nbsp;are&nbsp;difficult&nbsp;to&nbsp;pinpoint.&nbsp;This&nbsp;method&nbsp;allows&nbsp;Telemetry&nbsp;classes&nbsp;to<br>
-append&nbsp;useful&nbsp;debugging&nbsp;information&nbsp;to&nbsp;the&nbsp;exception.&nbsp;This&nbsp;method&nbsp;also&nbsp;logs<br>
-information&nbsp;about&nbsp;the&nbsp;location&nbsp;from&nbsp;where&nbsp;it&nbsp;was&nbsp;called.</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__init__"><strong>__init__</strong></a>(self, msg<font color="#909090">=''</font>)</dt></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.core.exceptions.html#Error">telemetry.core.exceptions.Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#WebSocketDisconnected-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="WebSocketDisconnected-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#WebSocketDisconnected-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#WebSocketDisconnected-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#WebSocketDisconnected-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#WebSocketDisconnected-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#WebSocketDisconnected-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#WebSocketDisconnected-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="WebSocketDisconnected-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.memory_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.memory_backend.html
deleted file mode 100644
index 2258e4e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.memory_backend.html
+++ /dev/null
@@ -1,274 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.memory_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.memory_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/memory_backend.py">telemetry/internal/backends/chrome_inspector/memory_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html">telemetry.internal.backends.chrome_inspector.inspector_websocket</a><br>
-<a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="socket.html">socket</a><br>
-</td><td width="25%" valign=top><a href="traceback.html">traceback</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.websocket.html">telemetry.internal.backends.chrome_inspector.websocket</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryBackend">MemoryBackend</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryTimeoutException">MemoryTimeoutException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryUnexpectedResponseException">MemoryUnexpectedResponseException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryUnrecoverableException">MemoryUnrecoverableException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryBackend">class <strong>MemoryBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MemoryBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=30</font>)</dt><dd><tt>Enable/disable&nbsp;suppressing&nbsp;memory&nbsp;pressure&nbsp;notifications.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;suppressed:&nbsp;If&nbsp;true,&nbsp;memory&nbsp;pressure&nbsp;notifications&nbsp;will&nbsp;be&nbsp;suppressed.<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;timeout&nbsp;in&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#MemoryTimeoutException">MemoryTimeoutException</a>:&nbsp;If&nbsp;more&nbsp;than&nbsp;|timeout|&nbsp;seconds&nbsp;has&nbsp;passed<br>
-&nbsp;&nbsp;since&nbsp;the&nbsp;last&nbsp;time&nbsp;any&nbsp;data&nbsp;is&nbsp;received.<br>
-&nbsp;&nbsp;<a href="#MemoryUnrecoverableException">MemoryUnrecoverableException</a>:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;websocket&nbsp;error.<br>
-&nbsp;&nbsp;<a href="#MemoryUnexpectedResponseException">MemoryUnexpectedResponseException</a>:&nbsp;If&nbsp;the&nbsp;response&nbsp;contains&nbsp;an&nbsp;error<br>
-&nbsp;&nbsp;or&nbsp;does&nbsp;not&nbsp;contain&nbsp;the&nbsp;expected&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="MemoryBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=30</font>)</dt><dd><tt>Simulate&nbsp;a&nbsp;memory&nbsp;pressure&nbsp;notification.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;pressure&nbsp;level:&nbsp;The&nbsp;memory&nbsp;pressure&nbsp;level&nbsp;of&nbsp;the&nbsp;notification&nbsp;('moderate'<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;'critical').<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;timeout&nbsp;in&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#MemoryTimeoutException">MemoryTimeoutException</a>:&nbsp;If&nbsp;more&nbsp;than&nbsp;|timeout|&nbsp;seconds&nbsp;has&nbsp;passed<br>
-&nbsp;&nbsp;since&nbsp;the&nbsp;last&nbsp;time&nbsp;any&nbsp;data&nbsp;is&nbsp;received.<br>
-&nbsp;&nbsp;<a href="#MemoryUnrecoverableException">MemoryUnrecoverableException</a>:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;websocket&nbsp;error.<br>
-&nbsp;&nbsp;<a href="#MemoryUnexpectedResponseException">MemoryUnexpectedResponseException</a>:&nbsp;If&nbsp;the&nbsp;response&nbsp;contains&nbsp;an&nbsp;error<br>
-&nbsp;&nbsp;or&nbsp;does&nbsp;not&nbsp;contain&nbsp;the&nbsp;expected&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="MemoryBackend-__init__"><strong>__init__</strong></a>(self, inspector_socket)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryTimeoutException">class <strong>MemoryTimeoutException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryTimeoutException">MemoryTimeoutException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MemoryTimeoutException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MemoryTimeoutException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MemoryTimeoutException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryTimeoutException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimeoutException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryUnexpectedResponseException">class <strong>MemoryUnexpectedResponseException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryUnexpectedResponseException">MemoryUnexpectedResponseException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MemoryUnexpectedResponseException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MemoryUnexpectedResponseException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MemoryUnexpectedResponseException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnexpectedResponseException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnexpectedResponseException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryUnrecoverableException">class <strong>MemoryUnrecoverableException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.memory_backend.html#MemoryUnrecoverableException">MemoryUnrecoverableException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MemoryUnrecoverableException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MemoryUnrecoverableException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MemoryUnrecoverableException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MemoryUnrecoverableException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MemoryUnrecoverableException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.tracing_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.tracing_backend.html
deleted file mode 100644
index fbd8de1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.tracing_backend.html
+++ /dev/null
@@ -1,392 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.tracing_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.tracing_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/tracing_backend.py">telemetry/internal/backends/chrome_inspector/tracing_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.inspector_websocket.html">telemetry.internal.backends.chrome_inspector.inspector_websocket</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="socket.html">socket</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="traceback.html">traceback</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.websocket.html">telemetry.internal.backends.chrome_inspector.websocket</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingBackend">TracingBackend</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingHasNotRunException">TracingHasNotRunException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingTimeoutException">TracingTimeoutException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingUnexpectedResponseException">TracingUnexpectedResponseException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingUnrecoverableException">TracingUnrecoverableException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingUnsupportedException">TracingUnsupportedException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingBackend">class <strong>TracingBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=30</font>)</dt><dd><tt>Dumps&nbsp;memory.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;GUID&nbsp;of&nbsp;the&nbsp;generated&nbsp;dump&nbsp;if&nbsp;successful,&nbsp;None&nbsp;otherwise.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#TracingTimeoutException">TracingTimeoutException</a>:&nbsp;If&nbsp;more&nbsp;than&nbsp;|timeout|&nbsp;seconds&nbsp;has&nbsp;passed<br>
-&nbsp;&nbsp;since&nbsp;the&nbsp;last&nbsp;time&nbsp;any&nbsp;data&nbsp;is&nbsp;received.<br>
-&nbsp;&nbsp;<a href="#TracingUnrecoverableException">TracingUnrecoverableException</a>:&nbsp;If&nbsp;there&nbsp;is&nbsp;a&nbsp;websocket&nbsp;error.<br>
-&nbsp;&nbsp;<a href="#TracingUnexpectedResponseException">TracingUnexpectedResponseException</a>:&nbsp;If&nbsp;the&nbsp;response&nbsp;contains&nbsp;an&nbsp;error<br>
-&nbsp;&nbsp;or&nbsp;does&nbsp;not&nbsp;contain&nbsp;the&nbsp;expected&nbsp;result.</tt></dd></dl>
-
-<dl><dt><a name="TracingBackend-IsTracingSupported"><strong>IsTracingSupported</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TracingBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=10</font>)</dt><dd><tt>When&nbsp;first&nbsp;called,&nbsp;starts&nbsp;tracing,&nbsp;and&nbsp;returns&nbsp;True.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;during&nbsp;tracing,&nbsp;tracing&nbsp;is&nbsp;unchanged,&nbsp;and&nbsp;it&nbsp;returns&nbsp;False.</tt></dd></dl>
-
-<dl><dt><a name="TracingBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder, timeout<font color="#909090">=30</font>)</dt><dd><tt>Stops&nbsp;tracing&nbsp;and&nbsp;pushes&nbsp;results&nbsp;to&nbsp;the&nbsp;supplied&nbsp;TraceDataBuilder.<br>
-&nbsp;<br>
-If&nbsp;this&nbsp;is&nbsp;called&nbsp;after&nbsp;tracing&nbsp;has&nbsp;been&nbsp;stopped,&nbsp;trace&nbsp;data&nbsp;from&nbsp;the&nbsp;last<br>
-tracing&nbsp;run&nbsp;is&nbsp;pushed.</tt></dd></dl>
-
-<dl><dt><a name="TracingBackend-__init__"><strong>__init__</strong></a>(self, inspector_socket, is_tracing_running<font color="#909090">=False</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_tracing_running</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingHasNotRunException">class <strong>TracingHasNotRunException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingHasNotRunException">TracingHasNotRunException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TracingHasNotRunException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TracingHasNotRunException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TracingHasNotRunException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingHasNotRunException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingHasNotRunException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingTimeoutException">class <strong>TracingTimeoutException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingTimeoutException">TracingTimeoutException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TracingTimeoutException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TracingTimeoutException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TracingTimeoutException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingTimeoutException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingTimeoutException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingTimeoutException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingTimeoutException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingUnexpectedResponseException">class <strong>TracingUnexpectedResponseException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingUnexpectedResponseException">TracingUnexpectedResponseException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TracingUnexpectedResponseException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TracingUnexpectedResponseException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TracingUnexpectedResponseException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnexpectedResponseException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingUnexpectedResponseException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingUnrecoverableException">class <strong>TracingUnrecoverableException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingUnrecoverableException">TracingUnrecoverableException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TracingUnrecoverableException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TracingUnrecoverableException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TracingUnrecoverableException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnrecoverableException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingUnrecoverableException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingUnsupportedException">class <strong>TracingUnsupportedException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.chrome_inspector.tracing_backend.html#TracingUnsupportedException">TracingUnsupportedException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TracingUnsupportedException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TracingUnsupportedException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TracingUnsupportedException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingUnsupportedException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingUnsupportedException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.websocket.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.websocket.html
deleted file mode 100644
index 8c20ae9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.chrome_inspector.websocket.html
+++ /dev/null
@@ -1,40 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.chrome_inspector.websocket</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.chrome_inspector.html"><font color="#ffffff">chrome_inspector</font></a>.websocket</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/chrome_inspector/websocket.py">telemetry/internal/backends/chrome_inspector/websocket.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="socket.html">socket</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-create_connection"><strong>create_connection</strong></a>(*args, **kwargs)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>absolute_import</strong> = _Feature((2, 5, 0, 'alpha', 1), (3, 0, 0, 'alpha', 0), 16384)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.codepen_credentials_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.codepen_credentials_backend.html
deleted file mode 100644
index 27388f2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.codepen_credentials_backend.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.codepen_credentials_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.codepen_credentials_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/codepen_credentials_backend.py">telemetry/internal/backends/codepen_credentials_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.form_based_credentials_backend.html">telemetry.internal.backends.form_based_credentials_backend</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.codepen_credentials_backend.html#CodePenCredentialsBackend">CodePenCredentialsBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CodePenCredentialsBackend">class <strong>CodePenCredentialsBackend</strong></a>(<a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.codepen_credentials_backend.html#CodePenCredentialsBackend">CodePenCredentialsBackend</a></dd>
-<dd><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>credentials_type</strong></dt>
-</dl>
-<dl><dt><strong>logged_in_javascript</strong></dt>
-<dd><tt>Evaluates&nbsp;to&nbsp;true&nbsp;iff&nbsp;already&nbsp;logged&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_button_javascript</strong></dt>
-</dl>
-<dl><dt><strong>login_form_id</strong></dt>
-</dl>
-<dl><dt><strong>login_input_id</strong></dt>
-</dl>
-<dl><dt><strong>password_input_id</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><a name="CodePenCredentialsBackend-IsAlreadyLoggedIn"><strong>IsAlreadyLoggedIn</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="CodePenCredentialsBackend-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CodePenCredentialsBackend-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, action_runner, config)</dt><dd><tt>Logs&nbsp;in&nbsp;to&nbsp;a&nbsp;test&nbsp;account.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;if&nbsp;could&nbsp;not&nbsp;get&nbsp;credential&nbsp;information.</tt></dd></dl>
-
-<dl><dt><a name="CodePenCredentialsBackend-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="CodePenCredentialsBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.facebook_credentials_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.facebook_credentials_backend.html
deleted file mode 100644
index 8f1cd05..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.facebook_credentials_backend.html
+++ /dev/null
@@ -1,156 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.facebook_credentials_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.facebook_credentials_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/facebook_credentials_backend.py">telemetry/internal/backends/facebook_credentials_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.form_based_credentials_backend.html">telemetry.internal.backends.form_based_credentials_backend</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend">FacebookCredentialsBackend</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend2">FacebookCredentialsBackend2</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FacebookCredentialsBackend">class <strong>FacebookCredentialsBackend</strong></a>(<a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend">FacebookCredentialsBackend</a></dd>
-<dd><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>credentials_type</strong></dt>
-</dl>
-<dl><dt><strong>logged_in_javascript</strong></dt>
-<dd><tt>Evaluates&nbsp;to&nbsp;true&nbsp;iff&nbsp;already&nbsp;logged&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_form_id</strong></dt>
-</dl>
-<dl><dt><strong>login_input_id</strong></dt>
-</dl>
-<dl><dt><strong>password_input_id</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><a name="FacebookCredentialsBackend-IsAlreadyLoggedIn"><strong>IsAlreadyLoggedIn</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, action_runner, config)</dt><dd><tt>Logs&nbsp;in&nbsp;to&nbsp;a&nbsp;test&nbsp;account.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;if&nbsp;could&nbsp;not&nbsp;get&nbsp;credential&nbsp;information.</tt></dd></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>login_button_javascript</strong></dt>
-<dd><tt>Some&nbsp;sites&nbsp;have&nbsp;custom&nbsp;JS&nbsp;to&nbsp;log&nbsp;in.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FacebookCredentialsBackend2">class <strong>FacebookCredentialsBackend2</strong></a>(<a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend">FacebookCredentialsBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Facebook&nbsp;credential&nbsp;backend&nbsp;for&nbsp;https&nbsp;client.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend2">FacebookCredentialsBackend2</a></dd>
-<dd><a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend">FacebookCredentialsBackend</a></dd>
-<dd><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>credentials_type</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.facebook_credentials_backend.html#FacebookCredentialsBackend">FacebookCredentialsBackend</a>:<br>
-<dl><dt><strong>logged_in_javascript</strong></dt>
-<dd><tt>Evaluates&nbsp;to&nbsp;true&nbsp;iff&nbsp;already&nbsp;logged&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_form_id</strong></dt>
-</dl>
-<dl><dt><strong>login_input_id</strong></dt>
-</dl>
-<dl><dt><strong>password_input_id</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><a name="FacebookCredentialsBackend2-IsAlreadyLoggedIn"><strong>IsAlreadyLoggedIn</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend2-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend2-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, action_runner, config)</dt><dd><tt>Logs&nbsp;in&nbsp;to&nbsp;a&nbsp;test&nbsp;account.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;if&nbsp;could&nbsp;not&nbsp;get&nbsp;credential&nbsp;information.</tt></dd></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend2-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="FacebookCredentialsBackend2-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>login_button_javascript</strong></dt>
-<dd><tt>Some&nbsp;sites&nbsp;have&nbsp;custom&nbsp;JS&nbsp;to&nbsp;log&nbsp;in.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.form_based_credentials_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.form_based_credentials_backend.html
deleted file mode 100644
index 109b617..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.form_based_credentials_backend.html
+++ /dev/null
@@ -1,86 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.form_based_credentials_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.form_based_credentials_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/form_based_credentials_backend.py">telemetry/internal/backends/form_based_credentials_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">FormBasedCredentialsBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FormBasedCredentialsBackend">class <strong>FormBasedCredentialsBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FormBasedCredentialsBackend-IsAlreadyLoggedIn"><strong>IsAlreadyLoggedIn</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackend-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackend-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, action_runner, config)</dt><dd><tt>Logs&nbsp;in&nbsp;to&nbsp;a&nbsp;test&nbsp;account.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;if&nbsp;could&nbsp;not&nbsp;get&nbsp;credential&nbsp;information.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackend-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>credentials_type</strong></dt>
-</dl>
-<dl><dt><strong>logged_in_javascript</strong></dt>
-<dd><tt>Evaluates&nbsp;to&nbsp;true&nbsp;iff&nbsp;already&nbsp;logged&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_button_javascript</strong></dt>
-<dd><tt>Some&nbsp;sites&nbsp;have&nbsp;custom&nbsp;JS&nbsp;to&nbsp;log&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_form_id</strong></dt>
-</dl>
-<dl><dt><strong>login_input_id</strong></dt>
-</dl>
-<dl><dt><strong>password_input_id</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.form_based_credentials_backend_unittest_base.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.form_based_credentials_backend_unittest_base.html
deleted file mode 100644
index 00d7328..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.form_based_credentials_backend_unittest_base.html
+++ /dev/null
@@ -1,336 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.form_based_credentials_backend_unittest_base</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.form_based_credentials_backend_unittest_base</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/form_based_credentials_backend_unittest_base.py">telemetry/internal/backends/form_based_credentials_backend_unittest_base.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.testing.simple_mock.html">telemetry.testing.simple_mock</a><br>
-</td><td width="25%" valign=top><a href="unittest.html">unittest</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="unittest.case.html#TestCase">unittest.case.TestCase</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.form_based_credentials_backend_unittest_base.html#FormBasedCredentialsBackendUnitTestBase">FormBasedCredentialsBackendUnitTestBase</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FormBasedCredentialsBackendUnitTestBase">class <strong>FormBasedCredentialsBackendUnitTestBase</strong></a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.form_based_credentials_backend_unittest_base.html#FormBasedCredentialsBackendUnitTestBase">FormBasedCredentialsBackendUnitTestBase</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-setUp"><strong>setUp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-testLoginUsingMock"><strong>testLoginUsingMock</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__init__"><strong>__init__</strong></a>(self, methodName<font color="#909090">='runTest'</font>)</dt><dd><tt>Create&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;class&nbsp;that&nbsp;will&nbsp;use&nbsp;the&nbsp;named&nbsp;test<br>
-method&nbsp;when&nbsp;executed.&nbsp;Raises&nbsp;a&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;instance&nbsp;does<br>
-not&nbsp;have&nbsp;a&nbsp;method&nbsp;with&nbsp;the&nbsp;specified&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#FormBasedCredentialsBackendUnitTestBase-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;class&nbsp;fixture&nbsp;before&nbsp;running&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<dl><dt><a name="FormBasedCredentialsBackendUnitTestBase-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;class&nbsp;fixture&nbsp;after&nbsp;running&nbsp;all&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.google_credentials_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.google_credentials_backend.html
deleted file mode 100644
index 389a886..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.google_credentials_backend.html
+++ /dev/null
@@ -1,156 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.google_credentials_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.google_credentials_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/google_credentials_backend.py">telemetry/internal/backends/google_credentials_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.form_based_credentials_backend.html">telemetry.internal.backends.form_based_credentials_backend</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend">GoogleCredentialsBackend</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend2">GoogleCredentialsBackend2</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GoogleCredentialsBackend">class <strong>GoogleCredentialsBackend</strong></a>(<a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend">GoogleCredentialsBackend</a></dd>
-<dd><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>credentials_type</strong></dt>
-</dl>
-<dl><dt><strong>logged_in_javascript</strong></dt>
-<dd><tt>Evaluates&nbsp;to&nbsp;true&nbsp;iff&nbsp;already&nbsp;logged&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_form_id</strong></dt>
-</dl>
-<dl><dt><strong>login_input_id</strong></dt>
-</dl>
-<dl><dt><strong>password_input_id</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><a name="GoogleCredentialsBackend-IsAlreadyLoggedIn"><strong>IsAlreadyLoggedIn</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, action_runner, config)</dt><dd><tt>Logs&nbsp;in&nbsp;to&nbsp;a&nbsp;test&nbsp;account.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;if&nbsp;could&nbsp;not&nbsp;get&nbsp;credential&nbsp;information.</tt></dd></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>login_button_javascript</strong></dt>
-<dd><tt>Some&nbsp;sites&nbsp;have&nbsp;custom&nbsp;JS&nbsp;to&nbsp;log&nbsp;in.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GoogleCredentialsBackend2">class <strong>GoogleCredentialsBackend2</strong></a>(<a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend">GoogleCredentialsBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Google&nbsp;credential&nbsp;backend&nbsp;for&nbsp;google2&nbsp;credential.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend2">GoogleCredentialsBackend2</a></dd>
-<dd><a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend">GoogleCredentialsBackend</a></dd>
-<dd><a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>credentials_type</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.google_credentials_backend.html#GoogleCredentialsBackend">GoogleCredentialsBackend</a>:<br>
-<dl><dt><strong>logged_in_javascript</strong></dt>
-<dd><tt>Evaluates&nbsp;to&nbsp;true&nbsp;iff&nbsp;already&nbsp;logged&nbsp;in.</tt></dd>
-</dl>
-<dl><dt><strong>login_form_id</strong></dt>
-</dl>
-<dl><dt><strong>login_input_id</strong></dt>
-</dl>
-<dl><dt><strong>password_input_id</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><a name="GoogleCredentialsBackend2-IsAlreadyLoggedIn"><strong>IsAlreadyLoggedIn</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend2-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend2-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, action_runner, config)</dt><dd><tt>Logs&nbsp;in&nbsp;to&nbsp;a&nbsp;test&nbsp;account.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;if&nbsp;could&nbsp;not&nbsp;get&nbsp;credential&nbsp;information.</tt></dd></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend2-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab)</dt></dl>
-
-<dl><dt><a name="GoogleCredentialsBackend2-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.form_based_credentials_backend.html#FormBasedCredentialsBackend">telemetry.internal.backends.form_based_credentials_backend.FormBasedCredentialsBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>login_button_javascript</strong></dt>
-<dd><tt>Some&nbsp;sites&nbsp;have&nbsp;custom&nbsp;JS&nbsp;to&nbsp;log&nbsp;in.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.html
deleted file mode 100644
index 59435ea..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.backends</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.backends</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/__init__.py">telemetry/internal/backends/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.android_app_backend.html">android_app_backend</a><br>
-<a href="telemetry.internal.backends.android_browser_backend_settings.html">android_browser_backend_settings</a><br>
-<a href="telemetry.internal.backends.android_command_line_backend.html">android_command_line_backend</a><br>
-<a href="telemetry.internal.backends.android_command_line_backend_unittest.html">android_command_line_backend_unittest</a><br>
-<a href="telemetry.internal.backends.app_backend.html">app_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.browser_backend.html">browser_backend</a><br>
-<a href="telemetry.internal.backends.browser_backend_unittest.html">browser_backend_unittest</a><br>
-<a href="telemetry.internal.backends.chrome.html"><strong>chrome</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.html"><strong>chrome_inspector</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.backends.codepen_credentials_backend.html">codepen_credentials_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.codepen_credentials_backend_unittest.html">codepen_credentials_backend_unittest</a><br>
-<a href="telemetry.internal.backends.facebook_credentials_backend.html">facebook_credentials_backend</a><br>
-<a href="telemetry.internal.backends.facebook_credentials_backend_unittest.html">facebook_credentials_backend_unittest</a><br>
-<a href="telemetry.internal.backends.form_based_credentials_backend.html">form_based_credentials_backend</a><br>
-<a href="telemetry.internal.backends.form_based_credentials_backend_unittest_base.html">form_based_credentials_backend_unittest_base</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.google_credentials_backend.html">google_credentials_backend</a><br>
-<a href="telemetry.internal.backends.google_credentials_backend_unittest.html">google_credentials_backend_unittest</a><br>
-<a href="telemetry.internal.backends.mandoline.html"><strong>mandoline</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.backends.remote.html"><strong>remote</strong>&nbsp;(package)</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android.html
deleted file mode 100644
index f64be17..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android.html
+++ /dev/null
@@ -1,94 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.android</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.android</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/android.py">telemetry/internal/backends/mandoline/android.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="devil.android.apk_helper.html">devil.android.apk_helper</a><br>
-<a href="atexit.html">atexit</a><br>
-<a href="devil.base_error.html">devil.base_error</a><br>
-<a href="pylib.constants.html">pylib.constants</a><br>
-</td><td width="25%" valign=top><a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-<a href="devil.android.device_utils.html">devil.android.device_utils</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="signal.html">signal</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-<a href="threading.html">threading</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.android.html#AndroidShell">AndroidShell</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidShell">class <strong>AndroidShell</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Used&nbsp;to&nbsp;set&nbsp;up&nbsp;and&nbsp;run&nbsp;a&nbsp;given&nbsp;mojo&nbsp;shell&nbsp;binary&nbsp;on&nbsp;an&nbsp;Android&nbsp;device.<br>
-|config|&nbsp;is&nbsp;the&nbsp;mopy.config.Config&nbsp;for&nbsp;the&nbsp;build.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AndroidShell-InitShell"><strong>InitShell</strong></a>(self, device<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;adb&nbsp;as&nbsp;root,&nbsp;and&nbsp;installs&nbsp;the&nbsp;apk&nbsp;as&nbsp;needed.&nbsp;&nbsp;|device|&nbsp;is&nbsp;the&nbsp;target<br>
-device&nbsp;to&nbsp;run&nbsp;on,&nbsp;if&nbsp;multiple&nbsp;devices&nbsp;are&nbsp;connected.&nbsp;Returns&nbsp;0&nbsp;on&nbsp;success&nbsp;or<br>
-a&nbsp;non-zero&nbsp;exit&nbsp;code&nbsp;on&nbsp;a&nbsp;terminal&nbsp;failure.</tt></dd></dl>
-
-<dl><dt><a name="AndroidShell-ShowLogs"><strong>ShowLogs</strong></a>(self, stdout<font color="#909090">=&lt;open file '&lt;stdout&gt;', mode 'w'&gt;</font>)</dt><dd><tt>Displays&nbsp;the&nbsp;mojo&nbsp;shell&nbsp;logs&nbsp;and&nbsp;returns&nbsp;the&nbsp;process&nbsp;reading&nbsp;the&nbsp;logs.</tt></dd></dl>
-
-<dl><dt><a name="AndroidShell-StartActivity"><strong>StartActivity</strong></a>(self, activity_name, arguments, stdout, on_fifo_closed, temp_gdb_dir<font color="#909090">=None</font>)</dt><dd><tt>Starts&nbsp;the&nbsp;shell&nbsp;with&nbsp;the&nbsp;given&nbsp;|arguments|,&nbsp;directing&nbsp;output&nbsp;to&nbsp;|stdout|.<br>
-|on_fifo_closed|&nbsp;will&nbsp;be&nbsp;run&nbsp;if&nbsp;the&nbsp;FIFO&nbsp;can't&nbsp;be&nbsp;found&nbsp;or&nbsp;when&nbsp;it's&nbsp;closed.<br>
-|temp_gdb_dir|&nbsp;is&nbsp;set&nbsp;to&nbsp;a&nbsp;location&nbsp;with&nbsp;appropriate&nbsp;symlinks&nbsp;for&nbsp;gdb&nbsp;to<br>
-find&nbsp;when&nbsp;attached&nbsp;to&nbsp;the&nbsp;device's&nbsp;remote&nbsp;process&nbsp;on&nbsp;startup.</tt></dd></dl>
-
-<dl><dt><a name="AndroidShell-__init__"><strong>__init__</strong></a>(self, config, chrome_root)</dt></dl>
-
-<dl><dt><a name="AndroidShell-kill"><strong>kill</strong></a>(self)</dt><dd><tt>Stops&nbsp;the&nbsp;mojo&nbsp;shell;&nbsp;matches&nbsp;the&nbsp;Popen.kill&nbsp;method&nbsp;signature.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>LOGCAT_TAGS</strong> = ['AndroidHandler', 'MojoFileHelper', 'MojoMain', 'MojoShellActivity', 'MojoShellApplication', 'chromium']<br>
-<strong>MAPPING_PREFIX</strong> = '--map-origin='</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android_mandoline_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android_mandoline_backend.html
deleted file mode 100644
index a65bf6f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android_mandoline_backend.html
+++ /dev/null
@@ -1,189 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.android_mandoline_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.android_mandoline_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/android_mandoline_backend.py">telemetry/internal/backends/mandoline/android_mandoline_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.mandoline.android.html">telemetry.internal.backends.mandoline.android</a><br>
-<a href="telemetry.internal.platform.android_platform_backend.html">telemetry.internal.platform.android_platform_backend</a><br>
-<a href="telemetry.internal.backends.mandoline.config.html">telemetry.internal.backends.mandoline.config</a><br>
-</td><td width="25%" valign=top><a href="pylib.constants.html">pylib.constants</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html">telemetry.internal.backends.mandoline.mandoline_browser_backend</a><br>
-<a href="os.html">os</a><br>
-<a href="random.html">random</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="sys.html">sys</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.android_mandoline_backend.html#AndroidMandolineBackend">AndroidMandolineBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidMandolineBackend">class <strong>AndroidMandolineBackend</strong></a>(<a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;backend&nbsp;for&nbsp;controlling&nbsp;a&nbsp;mandoline&nbsp;browser&nbsp;instance&nbsp;running&nbsp;on<br>
-Android.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.mandoline.android_mandoline_backend.html#AndroidMandolineBackend">AndroidMandolineBackend</a></dd>
-<dd><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidMandolineBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-__init__"><strong>__init__</strong></a>(self, android_platform_backend, browser_options, target_arch, browser_type, build_path, package, chrome_root)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>activity</strong></dt>
-</dl>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>device</strong></dt>
-</dl>
-<dl><dt><strong>package</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>:<br>
-<dl><dt><a name="AndroidMandolineBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>:<br>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="AndroidMandolineBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="AndroidMandolineBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="AndroidMandolineBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android_mandoline_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android_mandoline_finder.html
deleted file mode 100644
index 6131199..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.android_mandoline_finder.html
+++ /dev/null
@@ -1,120 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.android_mandoline_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.android_mandoline_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/android_mandoline_finder.py">telemetry/internal/backends/mandoline/android_mandoline_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;android&nbsp;mandoline&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.android_device.html">telemetry.internal.platform.android_device</a><br>
-<a href="telemetry.internal.backends.mandoline.android_mandoline_backend.html">telemetry.internal.backends.mandoline.android_mandoline_backend</a><br>
-<a href="devil.android.apk_helper.html">devil.android.apk_helper</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.android_mandoline_finder.html#PossibleAndroidMandolineBrowser">PossibleAndroidMandolineBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleAndroidMandolineBrowser">class <strong>PossibleAndroidMandolineBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;launchable&nbsp;android&nbsp;mandoline&nbsp;browser&nbsp;instance.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.mandoline.android_mandoline_finder.html#PossibleAndroidMandolineBrowser">PossibleAndroidMandolineBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleAndroidMandolineBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-HaveLocalAPK"><strong>HaveLocalAPK</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, finder_options, android_platform, build_path, local_apk)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleAndroidMandolineBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleAndroidMandolineBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>()</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Finds&nbsp;all&nbsp;the&nbsp;possible&nbsp;browsers&nbsp;to&nbsp;run&nbsp;on&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-The&nbsp;device&nbsp;is&nbsp;either&nbsp;the&nbsp;only&nbsp;device&nbsp;on&nbsp;the&nbsp;host&nbsp;platform,<br>
-or&nbsp;|finder_options|&nbsp;specifies&nbsp;a&nbsp;particular&nbsp;device.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(_options)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(possible_browsers)</dt><dd><tt>Returns&nbsp;the&nbsp;newest&nbsp;possible&nbsp;browser.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.config.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.config.html
deleted file mode 100644
index 08beced..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.config.html
+++ /dev/null
@@ -1,112 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.config</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.config</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/config.py">telemetry/internal/backends/mandoline/config.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ast.html">ast</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="platform.html">platform</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.config.html#Config">Config</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Config">class <strong>Config</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;<a href="#Config">Config</a>&nbsp;contains&nbsp;a&nbsp;dictionary&nbsp;that&nbsp;species&nbsp;a&nbsp;build&nbsp;configuration.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Config-__init__"><strong>__init__</strong></a>(self, build_dir<font color="#909090">=None</font>, target_os<font color="#909090">=None</font>, target_cpu<font color="#909090">=None</font>, is_debug<font color="#909090">=None</font>, is_verbose<font color="#909090">=None</font>, apk_name<font color="#909090">='MojoRunner.apk'</font>)</dt><dd><tt>Function&nbsp;arguments&nbsp;take&nbsp;precedence&nbsp;over&nbsp;GN&nbsp;args&nbsp;and&nbsp;default&nbsp;values.</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="Config-GetHostCPU"><strong>GetHostCPU</strong></a>()</dt></dl>
-
-<dl><dt><a name="Config-GetHostOS"><strong>GetHostOS</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>apk_name</strong></dt>
-<dd><tt>Name&nbsp;of&nbsp;the&nbsp;APK&nbsp;file&nbsp;to&nbsp;run</tt></dd>
-</dl>
-<dl><dt><strong>build_dir</strong></dt>
-<dd><tt>Build&nbsp;directory&nbsp;path.</tt></dd>
-</dl>
-<dl><dt><strong>dcheck_always_on</strong></dt>
-<dd><tt>DCHECK&nbsp;and&nbsp;MOJO_DCHECK&nbsp;are&nbsp;fatal&nbsp;even&nbsp;in&nbsp;release&nbsp;builds</tt></dd>
-</dl>
-<dl><dt><strong>is_asan</strong></dt>
-<dd><tt>Is&nbsp;ASAN&nbsp;build?</tt></dd>
-</dl>
-<dl><dt><strong>is_debug</strong></dt>
-<dd><tt>Is&nbsp;Debug&nbsp;build?</tt></dd>
-</dl>
-<dl><dt><strong>is_verbose</strong></dt>
-<dd><tt>Should&nbsp;print&nbsp;additional&nbsp;logging&nbsp;information?</tt></dd>
-</dl>
-<dl><dt><strong>target_cpu</strong></dt>
-<dd><tt>CPU&nbsp;arch&nbsp;of&nbsp;the&nbsp;build/test&nbsp;target.</tt></dd>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>OS&nbsp;of&nbsp;the&nbsp;build/test&nbsp;target.</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>ARCH_ARM</strong> = 'arm'</dl>
-
-<dl><dt><strong>ARCH_X64</strong> = 'x64'</dl>
-
-<dl><dt><strong>ARCH_X86</strong> = 'x86'</dl>
-
-<dl><dt><strong>OS_ANDROID</strong> = 'android'</dl>
-
-<dl><dt><strong>OS_CHROMEOS</strong> = 'chromeos'</dl>
-
-<dl><dt><strong>OS_LINUX</strong> = 'linux'</dl>
-
-<dl><dt><strong>OS_MAC</strong> = 'mac'</dl>
-
-<dl><dt><strong>OS_WINDOWS</strong> = 'windows'</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.desktop_mandoline_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.desktop_mandoline_backend.html
deleted file mode 100644
index a587529..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.desktop_mandoline_backend.html
+++ /dev/null
@@ -1,180 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.desktop_mandoline_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.desktop_mandoline_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/desktop_mandoline_backend.py">telemetry/internal/backends/mandoline/desktop_mandoline_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-<a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html">telemetry.internal.backends.mandoline.mandoline_browser_backend</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="shutil.html">shutil</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.desktop_mandoline_backend.html#DesktopMandolineBackend">DesktopMandolineBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DesktopMandolineBackend">class <strong>DesktopMandolineBackend</strong></a>(<a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;backend&nbsp;for&nbsp;controlling&nbsp;a&nbsp;locally-executed&nbsp;browser&nbsp;instance,&nbsp;on&nbsp;Linux<br>
-or&nbsp;Windows.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.mandoline.desktop_mandoline_backend.html#DesktopMandolineBackend">DesktopMandolineBackend</a></dd>
-<dd><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DesktopMandolineBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-__init__"><strong>__init__</strong></a>(self, desktop_platform_backend, browser_options, executable, browser_directory)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>:<br>
-<dl><dt><a name="DesktopMandolineBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">telemetry.internal.backends.mandoline.mandoline_browser_backend.MandolineBrowserBackend</a>:<br>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="DesktopMandolineBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="DesktopMandolineBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="DesktopMandolineBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.desktop_mandoline_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.desktop_mandoline_finder.html
deleted file mode 100644
index 5b881aa..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.desktop_mandoline_finder.html
+++ /dev/null
@@ -1,117 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.desktop_mandoline_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.desktop_mandoline_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/desktop_mandoline_finder.py">telemetry/internal/backends/mandoline/desktop_mandoline_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;desktop&nbsp;mandoline&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">telemetry.internal.browser.browser</a><br>
-<a href="telemetry.internal.platform.desktop_device.html">telemetry.internal.platform.desktop_device</a><br>
-<a href="telemetry.internal.backends.mandoline.desktop_mandoline_backend.html">telemetry.internal.backends.mandoline.desktop_mandoline_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.desktop_mandoline_finder.html#PossibleDesktopMandolineBrowser">PossibleDesktopMandolineBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleDesktopMandolineBrowser">class <strong>PossibleDesktopMandolineBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;desktop&nbsp;mandoline&nbsp;browser&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.mandoline.desktop_mandoline_finder.html#PossibleDesktopMandolineBrowser">PossibleDesktopMandolineBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleDesktopMandolineBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, finder_options, executable, browser_directory)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleDesktopMandolineBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleDesktopMandolineBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>()</dt></dl>
- <dl><dt><a name="-CanPossiblyHandlePath"><strong>CanPossiblyHandlePath</strong></a>(target_path)</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Finds&nbsp;all&nbsp;the&nbsp;desktop&nbsp;mandoline&nbsp;browsers&nbsp;available&nbsp;on&nbsp;this&nbsp;machine.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(_)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(possible_browsers)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.html
deleted file mode 100644
index 05bed22..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.backends.mandoline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.mandoline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/__init__.py">telemetry/internal/backends/mandoline/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.mandoline.android.html">android</a><br>
-<a href="telemetry.internal.backends.mandoline.android_mandoline_backend.html">android_mandoline_backend</a><br>
-<a href="telemetry.internal.backends.mandoline.android_mandoline_finder.html">android_mandoline_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.mandoline.config.html">config</a><br>
-<a href="telemetry.internal.backends.mandoline.desktop_mandoline_backend.html">desktop_mandoline_backend</a><br>
-<a href="telemetry.internal.backends.mandoline.desktop_mandoline_finder.html">desktop_mandoline_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.mandoline.desktop_mandoline_finder_unittest.html">desktop_mandoline_finder_unittest</a><br>
-<a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html">mandoline_browser_backend</a><br>
-<a href="telemetry.internal.backends.mandoline.paths.html">paths</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.mandoline_browser_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.mandoline_browser_backend.html
deleted file mode 100644
index cfb90e8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.mandoline_browser_backend.html
+++ /dev/null
@@ -1,175 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.mandoline_browser_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.mandoline_browser_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/mandoline_browser_backend.py">telemetry/internal/backends/mandoline/mandoline_browser_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.browser_backend.html">telemetry.internal.backends.browser_backend</a><br>
-<a href="telemetry.internal.backends.chrome_inspector.devtools_client_backend.html">telemetry.internal.backends.chrome_inspector.devtools_client_backend</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-<a href="logging.html">logging</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.tab_list_backend.html">telemetry.internal.backends.chrome.tab_list_backend</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>(<a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">MandolineBrowserBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MandolineBrowserBackend">class <strong>MandolineBrowserBackend</strong></a>(<a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;abstract&nbsp;class&nbsp;for&nbsp;mandoline&nbsp;browser&nbsp;backends.&nbsp;Provides&nbsp;basic<br>
-functionality&nbsp;once&nbsp;a&nbsp;remote-debugger&nbsp;port&nbsp;has&nbsp;been&nbsp;established.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.mandoline.mandoline_browser_backend.html#MandolineBrowserBackend">MandolineBrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a></dd>
-<dd><a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MandolineBrowserBackend-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-GetBrowserStartupArgs"><strong>GetBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-GetProcessName"><strong>GetProcessName</strong></a>(self, cmd_line)</dt><dd><tt>Returns&nbsp;a&nbsp;user-friendly&nbsp;name&nbsp;for&nbsp;the&nbsp;process&nbsp;of&nbsp;the&nbsp;given&nbsp;|cmd_line|.</tt></dd></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-GetReplayBrowserStartupArgs"><strong>GetReplayBrowserStartupArgs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-HasBrowserFinishedLaunching"><strong>HasBrowserFinishedLaunching</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-__init__"><strong>__init__</strong></a>(self, platform_backend, browser_options)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_directory</strong></dt>
-</dl>
-<dl><dt><strong>devtools_client</strong></dt>
-</dl>
-<dl><dt><strong>profile_directory</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>supports_tracing</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><a name="MandolineBrowserBackend-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-IsBrowserRunning"><strong>IsBrowserRunning</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-SetBrowser"><strong>SetBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-Start"><strong>Start</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-StartTracing"><strong>StartTracing</strong></a>(self, trace_options, custom_categories<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-StopTracing"><strong>StopTracing</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-UploadLogsToCloudStorage"><strong>UploadLogsToCloudStorage</strong></a>(self)</dt><dd><tt>Uploading&nbsp;log&nbsp;files&nbsp;produce&nbsp;by&nbsp;this&nbsp;browser&nbsp;instance&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Check&nbsp;supports_uploading_logs&nbsp;before&nbsp;calling&nbsp;this&nbsp;method.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.browser_backend.html#BrowserBackend">telemetry.internal.backends.browser_backend.BrowserBackend</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>profiling_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>should_ignore_certificate_errors</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;this&nbsp;browser&nbsp;backend&nbsp;supports&nbsp;extensions.</tt></dd>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_uploading_logs</strong></dt>
-</dl>
-<dl><dt><strong>tab_list_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_mode</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><a name="MandolineBrowserBackend-SetApp"><strong>SetApp</strong></a>(self, app)</dt></dl>
-
-<dl><dt><a name="MandolineBrowserBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.backends.app_backend.html#AppBackend">telemetry.internal.backends.app_backend.AppBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app</strong></dt>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>pid</strong></dt>
-</dl>
-<dl><dt><strong>platform_backend</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.paths.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.paths.html
deleted file mode 100644
index 839c9c1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.mandoline.paths.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.mandoline.paths</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.mandoline.html"><font color="#ffffff">mandoline</font></a>.paths</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/mandoline/paths.py">telemetry/internal/backends/mandoline/paths.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.mandoline.paths.html#Paths">Paths</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Paths">class <strong>Paths</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;commonly&nbsp;used&nbsp;paths<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Paths-RelPath"><strong>RelPath</strong></a>(self, path)</dt><dd><tt>Returns&nbsp;the&nbsp;given&nbsp;path,&nbsp;relative&nbsp;to&nbsp;the&nbsp;current&nbsp;directory.</tt></dd></dl>
-
-<dl><dt><a name="Paths-SrcRelPath"><strong>SrcRelPath</strong></a>(self, path)</dt><dd><tt>Returns&nbsp;the&nbsp;given&nbsp;path,&nbsp;relative&nbsp;to&nbsp;self.<strong>src_root</strong>.</tt></dd></dl>
-
-<dl><dt><a name="Paths-__init__"><strong>__init__</strong></a>(self, config, chrome_root)</dt><dd><tt>Generate&nbsp;paths&nbsp;to&nbsp;binary&nbsp;artifacts&nbsp;from&nbsp;a&nbsp;Config&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.remote.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.remote.html
deleted file mode 100644
index 76f7e88..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.remote.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.backends.remote</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.remote</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/remote/__init__.py">telemetry/internal/backends/remote/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.remote.trybot_browser_finder.html">trybot_browser_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.remote.trybot_browser_finder_unittest.html">trybot_browser_finder_unittest</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.remote.trybot_browser_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.backends.remote.trybot_browser_finder.html
deleted file mode 100644
index 9e5b6c5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.backends.remote.trybot_browser_finder.html
+++ /dev/null
@@ -1,200 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.backends.remote.trybot_browser_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.backends.html"><font color="#ffffff">backends</font></a>.<a href="telemetry.internal.backends.remote.html"><font color="#ffffff">remote</font></a>.trybot_browser_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/backends/remote/trybot_browser_finder.py">telemetry/internal/backends/remote/trybot_browser_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;perf&nbsp;trybots&nbsp;that&nbsp;can&nbsp;run&nbsp;telemetry&nbsp;tests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="json.html">json</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">telemetry.internal.browser.possible_browser</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.trybot_device.html">telemetry.internal.platform.trybot_device</a><br>
-<a href="urllib2.html">urllib2</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.remote.trybot_browser_finder.html#TrybotError">TrybotError</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.backends.remote.trybot_browser_finder.html#PossibleTrybotBrowser">PossibleTrybotBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleTrybotBrowser">class <strong>PossibleTrybotBrowser</strong></a>(<a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;script&nbsp;that&nbsp;sends&nbsp;a&nbsp;job&nbsp;to&nbsp;a&nbsp;trybot.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.remote.trybot_browser_finder.html#PossibleTrybotBrowser">PossibleTrybotBrowser</a></dd>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleTrybotBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt><dd><tt>Sends&nbsp;a&nbsp;tryjob&nbsp;to&nbsp;a&nbsp;perf&nbsp;trybot.<br>
-&nbsp;<br>
-This&nbsp;creates&nbsp;a&nbsp;branch,&nbsp;telemetry-tryjob,&nbsp;switches&nbsp;to&nbsp;that&nbsp;branch,&nbsp;edits<br>
-the&nbsp;bisect&nbsp;config,&nbsp;commits&nbsp;it,&nbsp;uploads&nbsp;the&nbsp;CL&nbsp;to&nbsp;rietveld,&nbsp;and&nbsp;runs&nbsp;a<br>
-tryjob&nbsp;on&nbsp;the&nbsp;given&nbsp;bot.</tt></dd></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, _)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><a name="PossibleTrybotBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleTrybotBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">telemetry.internal.browser.possible_browser.PossibleBrowser</a>:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TrybotError">class <strong>TrybotError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.backends.remote.trybot_browser_finder.html#TrybotError">TrybotError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TrybotError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TrybotError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TrybotError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TrybotError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TrybotError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TrybotError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TrybotError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TrybotError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TrybotError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TrybotError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TrybotError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TrybotError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TrybotError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanFindAvailableBrowsers"><strong>CanFindAvailableBrowsers</strong></a>()</dt></dl>
- <dl><dt><a name="-FindAllAvailableBrowsers"><strong>FindAllAvailableBrowsers</strong></a>(finder_options, device)</dt><dd><tt>Find&nbsp;all&nbsp;perf&nbsp;trybots&nbsp;on&nbsp;tryserver.chromium.perf.</tt></dd></dl>
- <dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(finder_options)</dt></dl>
- <dl><dt><a name="-SelectDefaultBrowser"><strong>SelectDefaultBrowser</strong></a>(_)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>BLINK_CONFIG_FILENAME</strong> = 'Tools/run-perf-test.cfg'<br>
-<strong>CHROMIUM_CONFIG_FILENAME</strong> = 'tools/run-perf-test.cfg'<br>
-<strong>ERROR</strong> = 2<br>
-<strong>EXCLUDED_BOTS</strong> = set(['android_arm64_perf_bisect_builder', 'android_perf_bisect_builder', 'linux_perf_bisect_builder', 'linux_perf_bisector', 'linux_perf_tester', 'mac_perf_bisect_builder', ...])<br>
-<strong>INCLUDE_BOTS</strong> = ['trybot-all', 'trybot-all-win', 'trybot-all-mac', 'trybot-all-linux', 'trybot-all-android']<br>
-<strong>NO_CHANGES</strong> = 1<br>
-<strong>SUCCESS</strong> = 0</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser.html
deleted file mode 100644
index 53aff2e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser.html
+++ /dev/null
@@ -1,189 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.browser</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.browser</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/browser.py">telemetry/internal/browser/browser.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.app.html">telemetry.internal.app</a><br>
-<a href="telemetry.internal.backends.browser_backend.html">telemetry.internal.backends.browser_backend</a><br>
-<a href="telemetry.internal.browser.browser_credentials.html">telemetry.internal.browser.browser_credentials</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-</td><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.util.exception_formatter.html">telemetry.internal.util.exception_formatter</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.browser.extension_dict.html">telemetry.internal.browser.extension_dict</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.core.profiling_controller.html">telemetry.core.profiling_controller</a><br>
-<a href="sys.html">sys</a><br>
-<a href="telemetry.internal.browser.tab_list.html">telemetry.internal.browser.tab_list</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser.html#Browser">Browser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Browser">class <strong>Browser</strong></a>(<a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;running&nbsp;browser&nbsp;instance&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;in&nbsp;a&nbsp;limited&nbsp;way.<br>
-&nbsp;<br>
-To&nbsp;create&nbsp;a&nbsp;browser&nbsp;instance,&nbsp;use&nbsp;browser_finder.FindBrowser.<br>
-&nbsp;<br>
-Be&nbsp;sure&nbsp;to&nbsp;clean&nbsp;up&nbsp;after&nbsp;yourself&nbsp;by&nbsp;calling&nbsp;<a href="#Browser-Close">Close</a>()&nbsp;when&nbsp;you&nbsp;are&nbsp;done&nbsp;with<br>
-the&nbsp;browser.&nbsp;Or&nbsp;better&nbsp;yet:<br>
-&nbsp;&nbsp;browser_to_create&nbsp;=&nbsp;FindBrowser(options)<br>
-&nbsp;&nbsp;with&nbsp;browser_to_create.Create(options)&nbsp;as&nbsp;browser:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;...&nbsp;do&nbsp;all&nbsp;your&nbsp;operations&nbsp;on&nbsp;browser&nbsp;here<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.browser.html#Browser">Browser</a></dd>
-<dd><a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Browser-Close"><strong>Close</strong></a>(self)</dt><dd><tt>Closes&nbsp;this&nbsp;browser.</tt></dd></dl>
-
-<dl><dt><a name="Browser-DumpMemory"><strong>DumpMemory</strong></a>(self, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="Browser-GetStackTrace"><strong>GetStackTrace</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Browser-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Browser-GetSystemInfo"><strong>GetSystemInfo</strong></a>(self)</dt><dd><tt>Returns&nbsp;low-level&nbsp;information&nbsp;about&nbsp;the&nbsp;system,&nbsp;if&nbsp;available.<br>
-&nbsp;<br>
-See&nbsp;the&nbsp;documentation&nbsp;of&nbsp;the&nbsp;SystemInfo&nbsp;class&nbsp;for&nbsp;more&nbsp;details.</tt></dd></dl>
-
-<dl><dt><a name="Browser-SetMemoryPressureNotificationsSuppressed"><strong>SetMemoryPressureNotificationsSuppressed</strong></a>(self, suppressed, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="Browser-SimulateMemoryPressureNotification"><strong>SimulateMemoryPressureNotification</strong></a>(self, pressure_level, timeout<font color="#909090">=90</font>)</dt></dl>
-
-<dl><dt><a name="Browser-__init__"><strong>__init__</strong></a>(self, backend, platform_backend, credentials_path)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>cpu_stats</strong></dt>
-<dd><tt>Returns&nbsp;a&nbsp;dict&nbsp;of&nbsp;cpu&nbsp;statistics&nbsp;for&nbsp;the&nbsp;system.<br>
-{&nbsp;'Browser':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'CpuProcessTime':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'TotalTime':&nbsp;T<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Gpu':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'CpuProcessTime':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'TotalTime':&nbsp;T<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Renderer':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'CpuProcessTime':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'TotalTime':&nbsp;T<br>
-&nbsp;&nbsp;}<br>
-}<br>
-Any&nbsp;of&nbsp;the&nbsp;above&nbsp;keys&nbsp;may&nbsp;be&nbsp;missing&nbsp;on&nbsp;a&nbsp;per-platform&nbsp;basis.</tt></dd>
-</dl>
-<dl><dt><strong>extensions</strong></dt>
-</dl>
-<dl><dt><strong>foreground_tab</strong></dt>
-</dl>
-<dl><dt><strong>memory_stats</strong></dt>
-<dd><tt>Returns&nbsp;a&nbsp;dict&nbsp;of&nbsp;memory&nbsp;statistics&nbsp;for&nbsp;the&nbsp;browser:<br>
-{&nbsp;'Browser':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VM':&nbsp;R,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VMPeak':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSize':&nbsp;T,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSizePeak':&nbsp;U,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'ProportionalSetSize':&nbsp;V,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'PrivateDirty':&nbsp;W<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Gpu':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VM':&nbsp;R,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VMPeak':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSize':&nbsp;T,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSizePeak':&nbsp;U,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'ProportionalSetSize':&nbsp;V,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'PrivateDirty':&nbsp;W<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'Renderer':&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VM':&nbsp;R,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'VMPeak':&nbsp;S,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSize':&nbsp;T,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'WorkingSetSizePeak':&nbsp;U,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'ProportionalSetSize':&nbsp;V,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'PrivateDirty':&nbsp;W<br>
-&nbsp;&nbsp;},<br>
-&nbsp;&nbsp;'SystemCommitCharge':&nbsp;X,<br>
-&nbsp;&nbsp;'SystemTotalPhysicalMemory':&nbsp;Y,<br>
-&nbsp;&nbsp;'ProcessCount':&nbsp;Z,<br>
-}<br>
-Any&nbsp;of&nbsp;the&nbsp;above&nbsp;keys&nbsp;may&nbsp;be&nbsp;missing&nbsp;on&nbsp;a&nbsp;per-platform&nbsp;basis.</tt></dd>
-</dl>
-<dl><dt><strong>profiling_controller</strong></dt>
-</dl>
-<dl><dt><strong>supports_cpu_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_extensions</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_dumping</strong></dt>
-</dl>
-<dl><dt><strong>supports_memory_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_overriding_memory_pressure_notifications</strong></dt>
-</dl>
-<dl><dt><strong>supports_power_metrics</strong></dt>
-</dl>
-<dl><dt><strong>supports_system_info</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<dl><dt><strong>tabs</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>:<br>
-<dl><dt><a name="Browser-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Browser-__exit__"><strong>__exit__</strong></a>(self, *args)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.html#App">telemetry.internal.app.App</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_credentials.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_credentials.html
deleted file mode 100644
index 5933292..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_credentials.html
+++ /dev/null
@@ -1,147 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.browser_credentials</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.browser_credentials</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/browser_credentials.py">telemetry/internal/browser/browser_credentials.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.codepen_credentials_backend.html">telemetry.internal.backends.codepen_credentials_backend</a><br>
-<a href="telemetry.internal.backends.facebook_credentials_backend.html">telemetry.internal.backends.facebook_credentials_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.google_credentials_backend.html">telemetry.internal.backends.google_credentials_backend</a><br>
-<a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_credentials.html#BrowserCredentials">BrowserCredentials</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_credentials.html#CredentialsError">CredentialsError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserCredentials">class <strong>BrowserCredentials</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="BrowserCredentials-Add"><strong>Add</strong></a>(self, credentials_type, data)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-AddBackend"><strong>AddBackend</strong></a>(self, backend)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-CanLogin"><strong>CanLogin</strong></a>(self, credentials_type)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-IsLoggedIn"><strong>IsLoggedIn</strong></a>(self, credentials_type)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-LoginNeeded"><strong>LoginNeeded</strong></a>(self, tab, credentials_type)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-LoginNoLongerNeeded"><strong>LoginNoLongerNeeded</strong></a>(self, tab, credentials_type)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-WarnIfMissingCredentials"><strong>WarnIfMissingCredentials</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="BrowserCredentials-__init__"><strong>__init__</strong></a>(self, backends<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>credentials_path</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CredentialsError">class <strong>CredentialsError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Error&nbsp;that&nbsp;can&nbsp;be&nbsp;thrown&nbsp;when&nbsp;logging&nbsp;in.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.browser_credentials.html#CredentialsError">CredentialsError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="CredentialsError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#CredentialsError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="CredentialsError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="CredentialsError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="CredentialsError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#CredentialsError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="CredentialsError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_finder.html
deleted file mode 100644
index 77c1c86..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_finder.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.browser_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.browser_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/browser_finder.py">telemetry/internal/browser/browser_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;browsers&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-<a href="telemetry.internal.backends.mandoline.android_mandoline_finder.html">telemetry.internal.backends.mandoline.android_mandoline_finder</a><br>
-<a href="telemetry.internal.browser.browser_finder_exceptions.html">telemetry.internal.browser.browser_finder_exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.cros_browser_finder.html">telemetry.internal.backends.chrome.cros_browser_finder</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.backends.chrome.desktop_browser_finder.html">telemetry.internal.backends.chrome.desktop_browser_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.backends.mandoline.desktop_mandoline_finder.html">telemetry.internal.backends.mandoline.desktop_mandoline_finder</a><br>
-<a href="telemetry.internal.platform.device_finder.html">telemetry.internal.platform.device_finder</a><br>
-<a href="telemetry.internal.backends.chrome.ios_browser_finder.html">telemetry.internal.backends.chrome.ios_browser_finder</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="operator.html">operator</a><br>
-<a href="telemetry.internal.backends.remote.trybot_browser_finder.html">telemetry.internal.backends.remote.trybot_browser_finder</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindAllBrowserTypes"><strong>FindAllBrowserTypes</strong></a>(options)</dt></dl>
- <dl><dt><a name="-FindBrowser"><strong>FindBrowser</strong></a>(*args, **kwargs)</dt><dd><tt>Finds&nbsp;the&nbsp;best&nbsp;PossibleBrowser&nbsp;object&nbsp;given&nbsp;a&nbsp;BrowserOptions&nbsp;object.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;A&nbsp;BrowserOptions&nbsp;object.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;PossibleBrowser&nbsp;object.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;BrowserFinderException:&nbsp;Options&nbsp;improperly&nbsp;set,&nbsp;or&nbsp;an&nbsp;error&nbsp;occurred.</tt></dd></dl>
- <dl><dt><a name="-GetAllAvailableBrowserTypes"><strong>GetAllAvailableBrowserTypes</strong></a>(*args, **kwargs)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;browser&nbsp;types.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;options:&nbsp;A&nbsp;BrowserOptions&nbsp;object.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;browser&nbsp;type&nbsp;strings.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;BrowserFinderException:&nbsp;Options&nbsp;are&nbsp;improperly&nbsp;set,&nbsp;or&nbsp;an&nbsp;error&nbsp;occurred.</tt></dd></dl>
- <dl><dt><a name="-GetAllAvailableBrowsers"><strong>GetAllAvailableBrowsers</strong></a>(*args, **kwargs)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;browsers&nbsp;on&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;options:&nbsp;A&nbsp;BrowserOptions&nbsp;object.<br>
-&nbsp;&nbsp;device:&nbsp;The&nbsp;target&nbsp;device,&nbsp;which&nbsp;can&nbsp;be&nbsp;None.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;browser&nbsp;instances.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;BrowserFinderException:&nbsp;Options&nbsp;are&nbsp;improperly&nbsp;set,&nbsp;or&nbsp;an&nbsp;error&nbsp;occurred.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>BROWSER_FINDERS</strong> = [&lt;module 'telemetry.internal.backends.chrome.desk...rnal/backends/chrome/desktop_browser_finder.pyc'&gt;, &lt;module 'telemetry.internal.backends.chrome.andr...rnal/backends/chrome/android_browser_finder.pyc'&gt;, &lt;module 'telemetry.internal.backends.chrome.cros...nternal/backends/chrome/cros_browser_finder.pyc'&gt;, &lt;module 'telemetry.internal.backends.chrome.ios_...internal/backends/chrome/ios_browser_finder.pyc'&gt;, &lt;module 'telemetry.internal.backends.remote.tryb...ernal/backends/remote/trybot_browser_finder.pyc'&gt;, &lt;module 'telemetry.internal.backends.mandoline.d...backends/mandoline/desktop_mandoline_finder.pyc'&gt;, &lt;module 'telemetry.internal.backends.mandoline.a...backends/mandoline/android_mandoline_finder.pyc'&gt;]</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_finder_exceptions.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_finder_exceptions.html
deleted file mode 100644
index f796cc5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_finder_exceptions.html
+++ /dev/null
@@ -1,149 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.browser_finder_exceptions</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.browser_finder_exceptions</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/browser_finder_exceptions.py">telemetry/internal/browser/browser_finder_exceptions.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_finder_exceptions.html#BrowserFinderException">BrowserFinderException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_finder_exceptions.html#BrowserTypeRequiredException">BrowserTypeRequiredException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserFinderException">class <strong>BrowserFinderException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.browser_finder_exceptions.html#BrowserFinderException">BrowserFinderException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="BrowserFinderException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#BrowserFinderException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="BrowserFinderException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserFinderException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserFinderException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserFinderException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="BrowserFinderException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserTypeRequiredException">class <strong>BrowserTypeRequiredException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.browser_finder_exceptions.html#BrowserTypeRequiredException">BrowserTypeRequiredException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="BrowserTypeRequiredException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#BrowserTypeRequiredException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="BrowserTypeRequiredException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#BrowserTypeRequiredException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="BrowserTypeRequiredException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_info.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_info.html
deleted file mode 100644
index 0d5c7f4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_info.html
+++ /dev/null
@@ -1,65 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.browser_info</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.browser_info</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/browser_info.py">telemetry/internal/browser/browser_info.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_info.html#BrowserInfo">BrowserInfo</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserInfo">class <strong>BrowserInfo</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;wrapper&nbsp;around&nbsp;browser&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;that&nbsp;allows&nbsp;looking&nbsp;up&nbsp;infos&nbsp;of&nbsp;the<br>
-browser.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="BrowserInfo-HasDiagonalScrollingSupport"><strong>HasDiagonalScrollingSupport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserInfo-HasFlingGestureSupport"><strong>HasFlingGestureSupport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserInfo-HasRepeatableSynthesizeScrollGesture"><strong>HasRepeatableSynthesizeScrollGesture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserInfo-HasWebGLSupport"><strong>HasWebGLSupport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserInfo-__init__"><strong>__init__</strong></a>(self, browser)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_options.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_options.html
deleted file mode 100644
index c31e571..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.browser_options.html
+++ /dev/null
@@ -1,245 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.browser_options</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.browser_options</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/browser_options.py">telemetry/internal/browser/browser_options.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="telemetry.internal.browser.browser_finder_exceptions.html">telemetry.internal.browser.browser_finder_exceptions</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="copy.html">copy</a><br>
-<a href="telemetry.internal.platform.device_finder.html">telemetry.internal.platform.device_finder</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="net_configs.html">net_configs</a><br>
-<a href="optparse.html">optparse</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.profile_types.html">telemetry.internal.browser.profile_types</a><br>
-<a href="telemetry.internal.platform.profiler.profiler_finder.html">telemetry.internal.platform.profiler.profiler_finder</a><br>
-<a href="shlex.html">shlex</a><br>
-<a href="socket.html">socket</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_options.html#ChromeBrowserOptions">ChromeBrowserOptions</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_options.html#CrosBrowserOptions">CrosBrowserOptions</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="optparse.html#Values">optparse.Values</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.browser_options.html#BrowserFinderOptions">BrowserFinderOptions</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserFinderOptions">class <strong>BrowserFinderOptions</strong></a>(<a href="optparse.html#Values">optparse.Values</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Options&nbsp;to&nbsp;be&nbsp;used&nbsp;for&nbsp;discovering&nbsp;a&nbsp;browser.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="BrowserFinderOptions-AppendExtraBrowserArgs"><strong>AppendExtraBrowserArgs</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-Copy"><strong>Copy</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-CreateParser"><strong>CreateParser</strong></a>(self, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-MergeDefaultValues"><strong>MergeDefaultValues</strong></a>(self, defaults)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-__init__"><strong>__init__</strong></a>(self, browser_type<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="optparse.html#Values">optparse.Values</a>:<br>
-<dl><dt><a name="BrowserFinderOptions-__cmp__"><strong>__cmp__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-ensure_value"><strong>ensure_value</strong></a>(self, attr, value)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-read_file"><strong>read_file</strong></a>(self, filename, mode<font color="#909090">='careful'</font>)</dt></dl>
-
-<dl><dt><a name="BrowserFinderOptions-read_module"><strong>read_module</strong></a>(self, modname, mode<font color="#909090">='careful'</font>)</dt></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserOptions">class <strong>BrowserOptions</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Options&nbsp;to&nbsp;be&nbsp;used&nbsp;for&nbsp;launching&nbsp;a&nbsp;browser.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="BrowserOptions-AppendExtraBrowserArgs"><strong>AppendExtraBrowserArgs</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="BrowserOptions-IsCrosBrowserOptions"><strong>IsCrosBrowserOptions</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserOptions-UpdateFromParseResults"><strong>UpdateFromParseResults</strong></a>(self, finder_options)</dt><dd><tt>Copies&nbsp;our&nbsp;options&nbsp;from&nbsp;finder_options</tt></dd></dl>
-
-<dl><dt><a name="BrowserOptions-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserOptions-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="BrowserOptions-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>browser_startup_timeout</strong></dt>
-</dl>
-<dl><dt><strong>extra_browser_args</strong></dt>
-</dl>
-<dl><dt><strong>finder_options</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChromeBrowserOptions">class <strong>ChromeBrowserOptions</strong></a>(<a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Chrome-specific&nbsp;browser&nbsp;options.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.browser_options.html#ChromeBrowserOptions">ChromeBrowserOptions</a></dd>
-<dd><a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ChromeBrowserOptions-__init__"><strong>__init__</strong></a>(self, br_options)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>:<br>
-<dl><dt><a name="ChromeBrowserOptions-AppendExtraBrowserArgs"><strong>AppendExtraBrowserArgs</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserOptions-IsCrosBrowserOptions"><strong>IsCrosBrowserOptions</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ChromeBrowserOptions-UpdateFromParseResults"><strong>UpdateFromParseResults</strong></a>(self, finder_options)</dt><dd><tt>Copies&nbsp;our&nbsp;options&nbsp;from&nbsp;finder_options</tt></dd></dl>
-
-<dl><dt><a name="ChromeBrowserOptions-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>:<br>
-<dl><dt><a name="ChromeBrowserOptions-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>browser_startup_timeout</strong></dt>
-</dl>
-<dl><dt><strong>extra_browser_args</strong></dt>
-</dl>
-<dl><dt><strong>finder_options</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrosBrowserOptions">class <strong>CrosBrowserOptions</strong></a>(<a href="telemetry.internal.browser.browser_options.html#ChromeBrowserOptions">ChromeBrowserOptions</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>ChromeOS-specific&nbsp;browser&nbsp;options.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.browser_options.html#CrosBrowserOptions">CrosBrowserOptions</a></dd>
-<dd><a href="telemetry.internal.browser.browser_options.html#ChromeBrowserOptions">ChromeBrowserOptions</a></dd>
-<dd><a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrosBrowserOptions-IsCrosBrowserOptions"><strong>IsCrosBrowserOptions</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosBrowserOptions-__init__"><strong>__init__</strong></a>(self, br_options)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>:<br>
-<dl><dt><a name="CrosBrowserOptions-AppendExtraBrowserArgs"><strong>AppendExtraBrowserArgs</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="CrosBrowserOptions-UpdateFromParseResults"><strong>UpdateFromParseResults</strong></a>(self, finder_options)</dt><dd><tt>Copies&nbsp;our&nbsp;options&nbsp;from&nbsp;finder_options</tt></dd></dl>
-
-<dl><dt><a name="CrosBrowserOptions-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>:<br>
-<dl><dt><a name="CrosBrowserOptions-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.browser_options.html#BrowserOptions">BrowserOptions</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>browser_startup_timeout</strong></dt>
-</dl>
-<dl><dt><strong>extra_browser_args</strong></dt>
-</dl>
-<dl><dt><strong>finder_options</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CreateChromeBrowserOptions"><strong>CreateChromeBrowserOptions</strong></a>(br_options)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_dict.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_dict.html
deleted file mode 100644
index ea84cab..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_dict.html
+++ /dev/null
@@ -1,70 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.extension_dict</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.extension_dict</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/extension_dict.py">telemetry/internal/browser/extension_dict.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.extension_to_load.html">telemetry.internal.browser.extension_to_load</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.extension_dict.html#ExtensionDict">ExtensionDict</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionDict">class <strong>ExtensionDict</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Dictionary&nbsp;of&nbsp;ExtensionPage&nbsp;instances,&nbsp;with&nbsp;extension_id&nbsp;as&nbsp;key.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ExtensionDict-GetByExtensionId"><strong>GetByExtensionId</strong></a>(self, extension_id)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;extensions&nbsp;given&nbsp;an&nbsp;extension&nbsp;id.&nbsp;This&nbsp;is&nbsp;useful&nbsp;for<br>
-connecting&nbsp;to&nbsp;built-in&nbsp;apps&nbsp;and&nbsp;component&nbsp;extensions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionDict-__contains__"><strong>__contains__</strong></a>(self, load_extension)</dt><dd><tt>Checks&nbsp;if&nbsp;this&nbsp;ExtensionToLoad&nbsp;instance&nbsp;has&nbsp;been&nbsp;loaded</tt></dd></dl>
-
-<dl><dt><a name="ExtensionDict-__getitem__"><strong>__getitem__</strong></a>(self, load_extension)</dt><dd><tt>Given&nbsp;an&nbsp;ExtensionToLoad&nbsp;instance,&nbsp;returns&nbsp;the&nbsp;corresponding<br>
-ExtensionPage&nbsp;instance.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionDict-__init__"><strong>__init__</strong></a>(self, extension_backend)</dt></dl>
-
-<dl><dt><a name="ExtensionDict-keys"><strong>keys</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_page.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_page.html
deleted file mode 100644
index adbac7d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_page.html
+++ /dev/null
@@ -1,250 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.extension_page</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.extension_page</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/extension_page.py">telemetry/internal/browser/extension_page.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.extension_page.html#ExtensionPage">ExtensionPage</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionPage">class <strong>ExtensionPage</strong></a>(<a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;extension&nbsp;page&nbsp;in&nbsp;the&nbsp;browser<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.extension_page.html#ExtensionPage">ExtensionPage</a></dd>
-<dd><a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ExtensionPage-Reload"><strong>Reload</strong></a>(self)</dt><dd><tt>Reloading&nbsp;an&nbsp;extension&nbsp;page&nbsp;is&nbsp;used&nbsp;as&nbsp;a&nbsp;workaround&nbsp;for&nbsp;an&nbsp;extension<br>
-binding&nbsp;bug&nbsp;for&nbsp;old&nbsp;versions&nbsp;of&nbsp;Chrome&nbsp;(crbug.com/263162).&nbsp;After&nbsp;Navigate<br>
-returns,&nbsp;we&nbsp;are&nbsp;guaranteed&nbsp;that&nbsp;the&nbsp;inspected&nbsp;page&nbsp;is&nbsp;in&nbsp;the&nbsp;correct&nbsp;state.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-__init__"><strong>__init__</strong></a>(self, inspector_backend)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>:<br>
-<dl><dt><a name="ExtensionPage-CloseConnections"><strong>CloseConnections</strong></a>(self)</dt><dd><tt>Closes&nbsp;all&nbsp;TCP&nbsp;sockets&nbsp;held&nbsp;open&nbsp;by&nbsp;the&nbsp;browser.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException&nbsp;if&nbsp;the&nbsp;tab&nbsp;is&nbsp;not&nbsp;alive.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-EnableAllContexts"><strong>EnableAllContexts</strong></a>(self)</dt><dd><tt>Enable&nbsp;all&nbsp;contexts&nbsp;in&nbsp;a&nbsp;page.&nbsp;Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;available&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-EvaluateJavaScript"><strong>EvaluateJavaScript</strong></a>(self, expr, timeout<font color="#909090">=90</font>)</dt><dd><tt>Evalutes&nbsp;expr&nbsp;in&nbsp;JavaScript&nbsp;and&nbsp;returns&nbsp;the&nbsp;JSONized&nbsp;result.<br>
-&nbsp;<br>
-Consider&nbsp;using&nbsp;ExecuteJavaScript&nbsp;for&nbsp;cases&nbsp;where&nbsp;the&nbsp;result&nbsp;of&nbsp;the<br>
-expression&nbsp;is&nbsp;not&nbsp;needed.<br>
-&nbsp;<br>
-If&nbsp;evaluation&nbsp;throws&nbsp;in&nbsp;JavaScript,&nbsp;a&nbsp;Python&nbsp;EvaluateException&nbsp;will<br>
-be&nbsp;raised.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;result&nbsp;of&nbsp;the&nbsp;evaluation&nbsp;cannot&nbsp;be&nbsp;JSONized,&nbsp;then&nbsp;an<br>
-EvaluationException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#ExtensionPage-EvaluateJavaScriptInContext">EvaluateJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-EvaluateJavaScriptInContext"><strong>EvaluateJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-ExecuteJavaScript"><strong>ExecuteJavaScript</strong></a>(self, statement, timeout<font color="#909090">=90</font>)</dt><dd><tt>Executes&nbsp;statement&nbsp;in&nbsp;JavaScript.&nbsp;Does&nbsp;not&nbsp;return&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;statement&nbsp;failed&nbsp;to&nbsp;evaluate,&nbsp;EvaluateException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#ExtensionPage-ExecuteJavaScriptInContext">ExecuteJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-ExecuteJavaScriptInContext"><strong>ExecuteJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-GetUrl"><strong>GetUrl</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;to&nbsp;which&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;connected.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-GetWebviewContexts"><strong>GetWebviewContexts</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;webview&nbsp;contexts&nbsp;within&nbsp;the&nbsp;current&nbsp;inspector&nbsp;backend.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;objects&nbsp;representing&nbsp;the&nbsp;webview&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-HasReachedQuiescence"><strong>HasReachedQuiescence</strong></a>(self)</dt><dd><tt>Determine&nbsp;whether&nbsp;the&nbsp;page&nbsp;has&nbsp;reached&nbsp;quiescence&nbsp;after&nbsp;loading.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;2&nbsp;seconds&nbsp;have&nbsp;passed&nbsp;since&nbsp;last&nbsp;resource&nbsp;received,&nbsp;false<br>
-&nbsp;&nbsp;otherwise.<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#ExtensionPage-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-IsAlive"><strong>IsAlive</strong></a>(self)</dt><dd><tt>Whether&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;still&nbsp;operating&nbsp;normally.<br>
-&nbsp;<br>
-Since&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;function&nbsp;asynchronously,&nbsp;this&nbsp;method&nbsp;does&nbsp;not&nbsp;guarantee<br>
-that&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;will&nbsp;still&nbsp;be&nbsp;alive&nbsp;at&nbsp;any&nbsp;point&nbsp;in&nbsp;the&nbsp;future.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;boolean&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;opearting&nbsp;normally.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-Navigate"><strong>Navigate</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Navigates&nbsp;to&nbsp;url.<br>
-&nbsp;<br>
-If&nbsp;|script_to_evaluate_on_commit|&nbsp;is&nbsp;given,&nbsp;the&nbsp;script&nbsp;source&nbsp;string&nbsp;will&nbsp;be<br>
-evaluated&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;committed.&nbsp;This&nbsp;is&nbsp;after&nbsp;the&nbsp;context&nbsp;of<br>
-the&nbsp;page&nbsp;exists,&nbsp;but&nbsp;before&nbsp;any&nbsp;script&nbsp;on&nbsp;the&nbsp;page&nbsp;itself&nbsp;has&nbsp;executed.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-StartTimelineRecording"><strong>StartTimelineRecording</strong></a>(self)</dt><dd><tt>Starts&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-StopTimelineRecording"><strong>StopTimelineRecording</strong></a>(self)</dt><dd><tt>Stops&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-SynthesizeScrollGesture"><strong>SynthesizeScrollGesture</strong></a>(self, x<font color="#909090">=100</font>, y<font color="#909090">=800</font>, xDistance<font color="#909090">=0</font>, yDistance<font color="#909090">=-500</font>, xOverscroll<font color="#909090">=None</font>, yOverscroll<font color="#909090">=None</font>, preventFling<font color="#909090">=True</font>, speed<font color="#909090">=None</font>, gestureSourceType<font color="#909090">=None</font>, repeatCount<font color="#909090">=None</font>, repeatDelayMs<font color="#909090">=None</font>, interactionMarkerName<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;an&nbsp;inspector&nbsp;command&nbsp;that&nbsp;causes&nbsp;a&nbsp;repeatable&nbsp;browser&nbsp;driven&nbsp;scroll.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x:&nbsp;X&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;y:&nbsp;Y&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;xDistance:&nbsp;Distance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;X&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;left).<br>
-&nbsp;&nbsp;yDistance:&nbsp;Ddistance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;up).<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;X&nbsp;axis.<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis.<br>
-&nbsp;&nbsp;preventFling:&nbsp;Prevents&nbsp;a&nbsp;fling&nbsp;gesture.<br>
-&nbsp;&nbsp;speed:&nbsp;Swipe&nbsp;speed&nbsp;in&nbsp;pixels&nbsp;per&nbsp;second.<br>
-&nbsp;&nbsp;gestureSourceType:&nbsp;Which&nbsp;type&nbsp;of&nbsp;input&nbsp;events&nbsp;to&nbsp;be&nbsp;generated.<br>
-&nbsp;&nbsp;repeatCount:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;repeats&nbsp;beyond&nbsp;the&nbsp;first&nbsp;scroll.<br>
-&nbsp;&nbsp;repeatDelayMs:&nbsp;Number&nbsp;of&nbsp;milliseconds&nbsp;delay&nbsp;between&nbsp;each&nbsp;repeat.<br>
-&nbsp;&nbsp;interactionMarkerName:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;interaction&nbsp;markers&nbsp;to&nbsp;generate.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-WaitForDocumentReadyStateToBeComplete"><strong>WaitForDocumentReadyStateToBeComplete</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;finish&nbsp;loading.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#ExtensionPage-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-WaitForDocumentReadyStateToBeInteractiveOrBetter"><strong>WaitForDocumentReadyStateToBeInteractiveOrBetter</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;be&nbsp;interactive.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#ExtensionPage-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-WaitForJavaScriptExpression"><strong>WaitForJavaScriptExpression</strong></a>(self, expr, timeout, dump_page_state_on_timeout<font color="#909090">=True</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;given&nbsp;JavaScript&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;robust&nbsp;against&nbsp;any&nbsp;given&nbsp;Evaluation&nbsp;timing&nbsp;out.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;expr:&nbsp;The&nbsp;expression&nbsp;to&nbsp;evaluate.<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;&nbsp;dump_page_state_on_timeout:&nbsp;Whether&nbsp;to&nbsp;provide&nbsp;additional&nbsp;information&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page&nbsp;state&nbsp;if&nbsp;a&nbsp;TimeoutException&nbsp;is&nbsp;thrown.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException:&nbsp;On&nbsp;a&nbsp;timeout.<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#ExtensionPage-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPage-WaitForNavigate"><strong>WaitForNavigate</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;navigation&nbsp;to&nbsp;complete.<br>
-&nbsp;<br>
-The&nbsp;current&nbsp;page&nbsp;is&nbsp;expect&nbsp;to&nbsp;be&nbsp;in&nbsp;a&nbsp;navigation.<br>
-This&nbsp;function&nbsp;returns&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;complete&nbsp;or&nbsp;when<br>
-the&nbsp;timeout&nbsp;has&nbsp;been&nbsp;exceeded.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-<dd><tt>Return&nbsp;the&nbsp;unique&nbsp;id&nbsp;string&nbsp;for&nbsp;this&nbsp;tab&nbsp;object.</tt></dd>
-</dl>
-<dl><dt><strong>message_output_stream</strong></dt>
-</dl>
-<dl><dt><strong>timeline_model</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-UrlToExtensionId"><strong>UrlToExtensionId</strong></a>(url)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_to_load.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_to_load.html
deleted file mode 100644
index 33162f9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.extension_to_load.html
+++ /dev/null
@@ -1,195 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.extension_to_load</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.extension_to_load</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/extension_to_load.py">telemetry/internal/browser/extension_to_load.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.crx_id.html">telemetry.internal.backends.chrome.crx_id</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.extension_to_load.html#ExtensionToLoad">ExtensionToLoad</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.extension_to_load.html#ExtensionPathNonExistentException">ExtensionPathNonExistentException</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.browser.extension_to_load.html#MissingPublicKeyException">MissingPublicKeyException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionPathNonExistentException">class <strong>ExtensionPathNonExistentException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.extension_to_load.html#ExtensionPathNonExistentException">ExtensionPathNonExistentException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ExtensionPathNonExistentException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ExtensionPathNonExistentException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ExtensionPathNonExistentException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ExtensionPathNonExistentException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ExtensionPathNonExistentException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExtensionToLoad">class <strong>ExtensionToLoad</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ExtensionToLoad-__init__"><strong>__init__</strong></a>(self, path, browser_type, is_component<font color="#909090">=False</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>extension_id</strong></dt>
-<dd><tt>Unique&nbsp;extension&nbsp;id&nbsp;of&nbsp;this&nbsp;extension.</tt></dd>
-</dl>
-<dl><dt><strong>is_component</strong></dt>
-<dd><tt>Whether&nbsp;this&nbsp;extension&nbsp;should&nbsp;be&nbsp;loaded&nbsp;as&nbsp;a&nbsp;component&nbsp;extension.</tt></dd>
-</dl>
-<dl><dt><strong>local_path</strong></dt>
-<dd><tt>Path&nbsp;to&nbsp;extension&nbsp;destination&nbsp;directory,&nbsp;for&nbsp;remote&nbsp;instances&nbsp;of<br>
-chrome</tt></dd>
-</dl>
-<dl><dt><strong>path</strong></dt>
-<dd><tt>Path&nbsp;to&nbsp;extension&nbsp;source&nbsp;directory.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MissingPublicKeyException">class <strong>MissingPublicKeyException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.extension_to_load.html#MissingPublicKeyException">MissingPublicKeyException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MissingPublicKeyException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MissingPublicKeyException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MissingPublicKeyException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingPublicKeyException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MissingPublicKeyException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.html
deleted file mode 100644
index cb39678..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.browser</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.browser</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/__init__.py">telemetry/internal/browser/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser.html">browser</a><br>
-<a href="telemetry.internal.browser.browser_credentials.html">browser_credentials</a><br>
-<a href="telemetry.internal.browser.browser_credentials_unittest.html">browser_credentials_unittest</a><br>
-<a href="telemetry.internal.browser.browser_finder.html">browser_finder</a><br>
-<a href="telemetry.internal.browser.browser_finder_exceptions.html">browser_finder_exceptions</a><br>
-<a href="telemetry.internal.browser.browser_info.html">browser_info</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.browser_options.html">browser_options</a><br>
-<a href="telemetry.internal.browser.browser_options_unittest.html">browser_options_unittest</a><br>
-<a href="telemetry.internal.browser.browser_unittest.html">browser_unittest</a><br>
-<a href="telemetry.internal.browser.extension_dict.html">extension_dict</a><br>
-<a href="telemetry.internal.browser.extension_page.html">extension_page</a><br>
-<a href="telemetry.internal.browser.extension_to_load.html">extension_to_load</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.extension_unittest.html">extension_unittest</a><br>
-<a href="telemetry.internal.browser.possible_browser.html">possible_browser</a><br>
-<a href="telemetry.internal.browser.profile_types.html">profile_types</a><br>
-<a href="telemetry.internal.browser.profile_types_unittest.html">profile_types_unittest</a><br>
-<a href="telemetry.internal.browser.tab.html">tab</a><br>
-<a href="telemetry.internal.browser.tab_list.html">tab_list</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.tab_unittest.html">tab_unittest</a><br>
-<a href="telemetry.internal.browser.user_agent.html">user_agent</a><br>
-<a href="telemetry.internal.browser.user_agent_unittest.html">user_agent_unittest</a><br>
-<a href="telemetry.internal.browser.web_contents.html">web_contents</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.possible_browser.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.possible_browser.html
deleted file mode 100644
index 2f77507..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.possible_browser.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.possible_browser</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.possible_browser</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/possible_browser.py">telemetry/internal/browser/possible_browser.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.app.possible_app.html">telemetry.internal.app.possible_app</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">PossibleBrowser</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PossibleBrowser">class <strong>PossibleBrowser</strong></a>(<a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;browser&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled.<br>
-&nbsp;<br>
-Call&nbsp;<a href="#PossibleBrowser-Create">Create</a>()&nbsp;to&nbsp;launch&nbsp;the&nbsp;browser&nbsp;and&nbsp;begin&nbsp;manipulating&nbsp;it..<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.possible_browser.html#PossibleBrowser">PossibleBrowser</a></dd>
-<dd><a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PossibleBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-RunRemote"><strong>RunRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, credentials_path)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-SupportsOptions"><strong>SupportsOptions</strong></a>(self, finder_options)</dt><dd><tt>Tests&nbsp;for&nbsp;extension&nbsp;support.</tt></dd></dl>
-
-<dl><dt><a name="PossibleBrowser-UpdateExecutableIfNeeded"><strong>UpdateExecutableIfNeeded</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-__init__"><strong>__init__</strong></a>(self, browser_type, target_os, supports_tab_control)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PossibleBrowser-last_modification_time"><strong>last_modification_time</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser_type</strong></dt>
-</dl>
-<dl><dt><strong>supports_tab_control</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.app.possible_app.html#PossibleApp">telemetry.internal.app.possible_app.PossibleApp</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>app_type</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>target_os</strong></dt>
-<dd><tt>Target&nbsp;OS,&nbsp;the&nbsp;app&nbsp;will&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.profile_types.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.profile_types.html
deleted file mode 100644
index 2311ceb..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.profile_types.html
+++ /dev/null
@@ -1,46 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.profile_types</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.profile_types</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/profile_types.py">telemetry/internal/browser/profile_types.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetProfileDir"><strong>GetProfileDir</strong></a>(profile_type)</dt><dd><tt>Given&nbsp;a&nbsp;|profile_type|&nbsp;(as&nbsp;returned&nbsp;by&nbsp;<a href="#-GetProfileTypes">GetProfileTypes</a>()),&nbsp;return&nbsp;the<br>
-directory&nbsp;to&nbsp;use&nbsp;for&nbsp;that&nbsp;profile&nbsp;or&nbsp;None&nbsp;if&nbsp;the&nbsp;profile&nbsp;doesn't&nbsp;need&nbsp;a<br>
-profile&nbsp;directory&nbsp;(e.g.&nbsp;using&nbsp;the&nbsp;browser&nbsp;default&nbsp;profile).</tt></dd></dl>
- <dl><dt><a name="-GetProfileTypes"><strong>GetProfileTypes</strong></a>()</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;all&nbsp;command&nbsp;line&nbsp;options&nbsp;that&nbsp;can&nbsp;be&nbsp;specified&nbsp;for<br>
-profile&nbsp;type.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>BASE_PROFILE_TYPES</strong> = ['clean', 'default']<br>
-<strong>PROFILE_TYPE_MAPPING</strong> = {'power_user': 'extension_webrequest', 'typical_user': 'content_scripts1'}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.tab.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.tab.html
deleted file mode 100644
index 2133051..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.tab.html
+++ /dev/null
@@ -1,395 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.tab</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.tab</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/tab.py">telemetry/internal/browser/tab.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.image_processing.video.html">telemetry.internal.image_processing.video</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.web_contents.html">telemetry.internal.browser.web_contents</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.tab.html#Tab">Tab</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Tab">class <strong>Tab</strong></a>(<a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;tab&nbsp;in&nbsp;the&nbsp;browser<br>
-&nbsp;<br>
-The&nbsp;important&nbsp;parts&nbsp;of&nbsp;the&nbsp;<a href="#Tab">Tab</a>&nbsp;object&nbsp;are&nbsp;in&nbsp;the&nbsp;runtime&nbsp;and&nbsp;page&nbsp;objects.<br>
-E.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Navigates&nbsp;the&nbsp;tab&nbsp;to&nbsp;a&nbsp;given&nbsp;url.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tab.<a href="#Tab-Navigate">Navigate</a>('<a href="http://www.google.com/">http://www.google.com/</a>')<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Evaluates&nbsp;1+1&nbsp;in&nbsp;the&nbsp;tab's&nbsp;JavaScript&nbsp;context.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tab.Evaluate('1+1')<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.browser.tab.html#Tab">Tab</a></dd>
-<dd><a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Tab-Activate"><strong>Activate</strong></a>(self)</dt><dd><tt>Brings&nbsp;this&nbsp;tab&nbsp;to&nbsp;the&nbsp;foreground&nbsp;asynchronously.<br>
-&nbsp;<br>
-Not&nbsp;all&nbsp;browsers&nbsp;or&nbsp;browser&nbsp;versions&nbsp;support&nbsp;this&nbsp;method.<br>
-Be&nbsp;sure&nbsp;to&nbsp;check&nbsp;browser.supports_tab_control.<br>
-&nbsp;<br>
-Please&nbsp;note:&nbsp;this&nbsp;is&nbsp;asynchronous.&nbsp;There&nbsp;is&nbsp;a&nbsp;delay&nbsp;between&nbsp;this&nbsp;call<br>
-and&nbsp;the&nbsp;page's&nbsp;documentVisibilityState&nbsp;becoming&nbsp;'visible',&nbsp;and&nbsp;yet&nbsp;more<br>
-delay&nbsp;until&nbsp;the&nbsp;actual&nbsp;tab&nbsp;is&nbsp;visible&nbsp;to&nbsp;the&nbsp;user.&nbsp;None&nbsp;of&nbsp;these&nbsp;delays<br>
-are&nbsp;included&nbsp;in&nbsp;this&nbsp;call.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError<br>
-&nbsp;&nbsp;devtools_client_backend.TabNotFoundError<br>
-&nbsp;&nbsp;tab_list_backend.TabUnexpectedResponseException</tt></dd></dl>
-
-<dl><dt><a name="Tab-ClearCache"><strong>ClearCache</strong></a>(self, force)</dt><dd><tt>Clears&nbsp;the&nbsp;browser's&nbsp;networking&nbsp;related&nbsp;disk,&nbsp;memory&nbsp;and&nbsp;other&nbsp;caches.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;force:&nbsp;Iff&nbsp;true,&nbsp;navigates&nbsp;to&nbsp;about:blank&nbsp;which&nbsp;destroys&nbsp;the&nbsp;previous<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;renderer,&nbsp;ensuring&nbsp;that&nbsp;even&nbsp;"live"&nbsp;resources&nbsp;in&nbsp;the&nbsp;memory&nbsp;cache&nbsp;are<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;cleared.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException<br>
-&nbsp;&nbsp;errors.DeviceUnresponsiveError</tt></dd></dl>
-
-<dl><dt><a name="Tab-ClearHighlight"><strong>ClearHighlight</strong></a>(self, color)</dt><dd><tt>Clears&nbsp;a&nbsp;highlight&nbsp;of&nbsp;the&nbsp;given&nbsp;bitmap.RgbaColor.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-Close"><strong>Close</strong></a>(self)</dt><dd><tt>Closes&nbsp;this&nbsp;tab.<br>
-&nbsp;<br>
-Not&nbsp;all&nbsp;browsers&nbsp;or&nbsp;browser&nbsp;versions&nbsp;support&nbsp;this&nbsp;method.<br>
-Be&nbsp;sure&nbsp;to&nbsp;check&nbsp;browser.supports_tab_control.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError<br>
-&nbsp;&nbsp;devtools_client_backend.TabNotFoundError<br>
-&nbsp;&nbsp;tab_list_backend.TabUnexpectedResponseException<br>
-&nbsp;&nbsp;exceptions.TimeoutException</tt></dd></dl>
-
-<dl><dt><a name="Tab-CollectGarbage"><strong>CollectGarbage</strong></a>(self)</dt><dd><tt>Forces&nbsp;a&nbsp;garbage&nbsp;collection.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-GetCookieByName"><strong>GetCookieByName</strong></a>(self, name, timeout<font color="#909090">=60</font>)</dt><dd><tt>Returns&nbsp;the&nbsp;value&nbsp;of&nbsp;the&nbsp;cookie&nbsp;by&nbsp;the&nbsp;given&nbsp;|name|.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-Highlight"><strong>Highlight</strong></a>(self, color)</dt><dd><tt>Synchronously&nbsp;highlights&nbsp;entire&nbsp;tab&nbsp;contents&nbsp;with&nbsp;the&nbsp;given&nbsp;RgbaColor.<br>
-&nbsp;<br>
-TODO(tonyg):&nbsp;It&nbsp;is&nbsp;possible&nbsp;that&nbsp;the&nbsp;z-index&nbsp;hack&nbsp;here&nbsp;might&nbsp;not&nbsp;work&nbsp;for<br>
-all&nbsp;pages.&nbsp;If&nbsp;this&nbsp;happens,&nbsp;DevTools&nbsp;also&nbsp;provides&nbsp;a&nbsp;method&nbsp;for&nbsp;this.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-Screenshot"><strong>Screenshot</strong></a>(self, timeout<font color="#909090">=60</font>)</dt><dd><tt>Capture&nbsp;a&nbsp;screenshot&nbsp;of&nbsp;the&nbsp;tab's&nbsp;contents.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;telemetry.core.Bitmap.<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps, highlight_bitmap<font color="#909090">=RgbaColor(r=222, g=100, b=13, a=255)</font>)</dt><dd><tt>Starts&nbsp;capturing&nbsp;video&nbsp;of&nbsp;the&nbsp;tab's&nbsp;contents.<br>
-&nbsp;<br>
-This&nbsp;works&nbsp;by&nbsp;flashing&nbsp;the&nbsp;entire&nbsp;tab&nbsp;contents&nbsp;to&nbsp;a&nbsp;arbitrary&nbsp;color&nbsp;and&nbsp;then<br>
-starting&nbsp;video&nbsp;recording.&nbsp;When&nbsp;the&nbsp;frames&nbsp;are&nbsp;processed,&nbsp;we&nbsp;can&nbsp;look&nbsp;for<br>
-that&nbsp;flash&nbsp;as&nbsp;the&nbsp;content&nbsp;bounds.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;min_bitrate_mbps:&nbsp;The&nbsp;minimum&nbsp;caputre&nbsp;bitrate&nbsp;in&nbsp;MegaBits&nbsp;Per&nbsp;Second.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;platform&nbsp;is&nbsp;free&nbsp;to&nbsp;deliver&nbsp;a&nbsp;higher&nbsp;bitrate&nbsp;if&nbsp;it&nbsp;can&nbsp;do&nbsp;so<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;without&nbsp;increasing&nbsp;overhead.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException<br>
-&nbsp;&nbsp;ValueError:&nbsp;If&nbsp;the&nbsp;required&nbsp;|min_bitrate_mbps|&nbsp;can't&nbsp;be&nbsp;achieved.</tt></dd></dl>
-
-<dl><dt><a name="Tab-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt><dd><tt>Stops&nbsp;recording&nbsp;video&nbsp;of&nbsp;the&nbsp;tab's&nbsp;contents.<br>
-&nbsp;<br>
-This&nbsp;looks&nbsp;for&nbsp;the&nbsp;initial&nbsp;color&nbsp;flash&nbsp;in&nbsp;the&nbsp;first&nbsp;frame&nbsp;to&nbsp;establish&nbsp;the<br>
-tab&nbsp;content&nbsp;boundaries&nbsp;and&nbsp;then&nbsp;omits&nbsp;all&nbsp;frames&nbsp;displaying&nbsp;the&nbsp;flash.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;video:&nbsp;A&nbsp;video&nbsp;object&nbsp;which&nbsp;is&nbsp;a&nbsp;telemetry.core.Video</tt></dd></dl>
-
-<dl><dt><a name="Tab-__init__"><strong>__init__</strong></a>(self, inspector_backend, tab_list_backend, browser)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser</strong></dt>
-<dd><tt>The&nbsp;browser&nbsp;in&nbsp;which&nbsp;this&nbsp;tab&nbsp;resides.</tt></dd>
-</dl>
-<dl><dt><strong>dom_stats</strong></dt>
-<dd><tt>A&nbsp;dictionary&nbsp;populated&nbsp;with&nbsp;measured&nbsp;DOM&nbsp;statistics.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;dictionary&nbsp;contains:<br>
-{<br>
-&nbsp;&nbsp;'document_count':&nbsp;integer,<br>
-&nbsp;&nbsp;'node_count':&nbsp;integer,<br>
-&nbsp;&nbsp;'event_listener_count':&nbsp;integer<br>
-}<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;inspector_memory.InspectorMemoryException<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>screenshot_supported</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;the&nbsp;browser&nbsp;instance&nbsp;is&nbsp;capable&nbsp;of&nbsp;capturing&nbsp;screenshots.</tt></dd>
-</dl>
-<dl><dt><strong>url</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;of&nbsp;the&nbsp;tab,&nbsp;as&nbsp;reported&nbsp;by&nbsp;devtools.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;devtools_http.DevToolsClientConnectionError</tt></dd>
-</dl>
-<dl><dt><strong>video_capture_supported</strong></dt>
-<dd><tt>True&nbsp;if&nbsp;the&nbsp;browser&nbsp;instance&nbsp;is&nbsp;capable&nbsp;of&nbsp;capturing&nbsp;video.</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>:<br>
-<dl><dt><a name="Tab-CloseConnections"><strong>CloseConnections</strong></a>(self)</dt><dd><tt>Closes&nbsp;all&nbsp;TCP&nbsp;sockets&nbsp;held&nbsp;open&nbsp;by&nbsp;the&nbsp;browser.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException&nbsp;if&nbsp;the&nbsp;tab&nbsp;is&nbsp;not&nbsp;alive.</tt></dd></dl>
-
-<dl><dt><a name="Tab-EnableAllContexts"><strong>EnableAllContexts</strong></a>(self)</dt><dd><tt>Enable&nbsp;all&nbsp;contexts&nbsp;in&nbsp;a&nbsp;page.&nbsp;Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;available&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-EvaluateJavaScript"><strong>EvaluateJavaScript</strong></a>(self, expr, timeout<font color="#909090">=90</font>)</dt><dd><tt>Evalutes&nbsp;expr&nbsp;in&nbsp;JavaScript&nbsp;and&nbsp;returns&nbsp;the&nbsp;JSONized&nbsp;result.<br>
-&nbsp;<br>
-Consider&nbsp;using&nbsp;ExecuteJavaScript&nbsp;for&nbsp;cases&nbsp;where&nbsp;the&nbsp;result&nbsp;of&nbsp;the<br>
-expression&nbsp;is&nbsp;not&nbsp;needed.<br>
-&nbsp;<br>
-If&nbsp;evaluation&nbsp;throws&nbsp;in&nbsp;JavaScript,&nbsp;a&nbsp;Python&nbsp;EvaluateException&nbsp;will<br>
-be&nbsp;raised.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;result&nbsp;of&nbsp;the&nbsp;evaluation&nbsp;cannot&nbsp;be&nbsp;JSONized,&nbsp;then&nbsp;an<br>
-EvaluationException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Tab-EvaluateJavaScriptInContext">EvaluateJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Tab-EvaluateJavaScriptInContext"><strong>EvaluateJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-ExecuteJavaScript"><strong>ExecuteJavaScript</strong></a>(self, statement, timeout<font color="#909090">=90</font>)</dt><dd><tt>Executes&nbsp;statement&nbsp;in&nbsp;JavaScript.&nbsp;Does&nbsp;not&nbsp;return&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;statement&nbsp;failed&nbsp;to&nbsp;evaluate,&nbsp;EvaluateException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Tab-ExecuteJavaScriptInContext">ExecuteJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Tab-ExecuteJavaScriptInContext"><strong>ExecuteJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-GetUrl"><strong>GetUrl</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;to&nbsp;which&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;connected.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="Tab-GetWebviewContexts"><strong>GetWebviewContexts</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;webview&nbsp;contexts&nbsp;within&nbsp;the&nbsp;current&nbsp;inspector&nbsp;backend.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;objects&nbsp;representing&nbsp;the&nbsp;webview&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="Tab-HasReachedQuiescence"><strong>HasReachedQuiescence</strong></a>(self)</dt><dd><tt>Determine&nbsp;whether&nbsp;the&nbsp;page&nbsp;has&nbsp;reached&nbsp;quiescence&nbsp;after&nbsp;loading.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;2&nbsp;seconds&nbsp;have&nbsp;passed&nbsp;since&nbsp;last&nbsp;resource&nbsp;received,&nbsp;false<br>
-&nbsp;&nbsp;otherwise.<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Tab-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Tab-IsAlive"><strong>IsAlive</strong></a>(self)</dt><dd><tt>Whether&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;still&nbsp;operating&nbsp;normally.<br>
-&nbsp;<br>
-Since&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;function&nbsp;asynchronously,&nbsp;this&nbsp;method&nbsp;does&nbsp;not&nbsp;guarantee<br>
-that&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;will&nbsp;still&nbsp;be&nbsp;alive&nbsp;at&nbsp;any&nbsp;point&nbsp;in&nbsp;the&nbsp;future.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;boolean&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;<a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>&nbsp;is&nbsp;opearting&nbsp;normally.</tt></dd></dl>
-
-<dl><dt><a name="Tab-Navigate"><strong>Navigate</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Navigates&nbsp;to&nbsp;url.<br>
-&nbsp;<br>
-If&nbsp;|script_to_evaluate_on_commit|&nbsp;is&nbsp;given,&nbsp;the&nbsp;script&nbsp;source&nbsp;string&nbsp;will&nbsp;be<br>
-evaluated&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;committed.&nbsp;This&nbsp;is&nbsp;after&nbsp;the&nbsp;context&nbsp;of<br>
-the&nbsp;page&nbsp;exists,&nbsp;but&nbsp;before&nbsp;any&nbsp;script&nbsp;on&nbsp;the&nbsp;page&nbsp;itself&nbsp;has&nbsp;executed.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-StartTimelineRecording"><strong>StartTimelineRecording</strong></a>(self)</dt><dd><tt>Starts&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-StopTimelineRecording"><strong>StopTimelineRecording</strong></a>(self)</dt><dd><tt>Stops&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-SynthesizeScrollGesture"><strong>SynthesizeScrollGesture</strong></a>(self, x<font color="#909090">=100</font>, y<font color="#909090">=800</font>, xDistance<font color="#909090">=0</font>, yDistance<font color="#909090">=-500</font>, xOverscroll<font color="#909090">=None</font>, yOverscroll<font color="#909090">=None</font>, preventFling<font color="#909090">=True</font>, speed<font color="#909090">=None</font>, gestureSourceType<font color="#909090">=None</font>, repeatCount<font color="#909090">=None</font>, repeatDelayMs<font color="#909090">=None</font>, interactionMarkerName<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;an&nbsp;inspector&nbsp;command&nbsp;that&nbsp;causes&nbsp;a&nbsp;repeatable&nbsp;browser&nbsp;driven&nbsp;scroll.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x:&nbsp;X&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;y:&nbsp;Y&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;xDistance:&nbsp;Distance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;X&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;left).<br>
-&nbsp;&nbsp;yDistance:&nbsp;Ddistance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;up).<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;X&nbsp;axis.<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis.<br>
-&nbsp;&nbsp;preventFling:&nbsp;Prevents&nbsp;a&nbsp;fling&nbsp;gesture.<br>
-&nbsp;&nbsp;speed:&nbsp;Swipe&nbsp;speed&nbsp;in&nbsp;pixels&nbsp;per&nbsp;second.<br>
-&nbsp;&nbsp;gestureSourceType:&nbsp;Which&nbsp;type&nbsp;of&nbsp;input&nbsp;events&nbsp;to&nbsp;be&nbsp;generated.<br>
-&nbsp;&nbsp;repeatCount:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;repeats&nbsp;beyond&nbsp;the&nbsp;first&nbsp;scroll.<br>
-&nbsp;&nbsp;repeatDelayMs:&nbsp;Number&nbsp;of&nbsp;milliseconds&nbsp;delay&nbsp;between&nbsp;each&nbsp;repeat.<br>
-&nbsp;&nbsp;interactionMarkerName:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;interaction&nbsp;markers&nbsp;to&nbsp;generate.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="Tab-WaitForDocumentReadyStateToBeComplete"><strong>WaitForDocumentReadyStateToBeComplete</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;finish&nbsp;loading.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Tab-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Tab-WaitForDocumentReadyStateToBeInteractiveOrBetter"><strong>WaitForDocumentReadyStateToBeInteractiveOrBetter</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;be&nbsp;interactive.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Tab-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Tab-WaitForJavaScriptExpression"><strong>WaitForJavaScriptExpression</strong></a>(self, expr, timeout, dump_page_state_on_timeout<font color="#909090">=True</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;given&nbsp;JavaScript&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;robust&nbsp;against&nbsp;any&nbsp;given&nbsp;Evaluation&nbsp;timing&nbsp;out.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;expr:&nbsp;The&nbsp;expression&nbsp;to&nbsp;evaluate.<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;&nbsp;dump_page_state_on_timeout:&nbsp;Whether&nbsp;to&nbsp;provide&nbsp;additional&nbsp;information&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page&nbsp;state&nbsp;if&nbsp;a&nbsp;TimeoutException&nbsp;is&nbsp;thrown.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException:&nbsp;On&nbsp;a&nbsp;timeout.<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#Tab-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="Tab-WaitForNavigate"><strong>WaitForNavigate</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;navigation&nbsp;to&nbsp;complete.<br>
-&nbsp;<br>
-The&nbsp;current&nbsp;page&nbsp;is&nbsp;expect&nbsp;to&nbsp;be&nbsp;in&nbsp;a&nbsp;navigation.<br>
-This&nbsp;function&nbsp;returns&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;complete&nbsp;or&nbsp;when<br>
-the&nbsp;timeout&nbsp;has&nbsp;been&nbsp;exceeded.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.browser.web_contents.html#WebContents">telemetry.internal.browser.web_contents.WebContents</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-<dd><tt>Return&nbsp;the&nbsp;unique&nbsp;id&nbsp;string&nbsp;for&nbsp;this&nbsp;tab&nbsp;object.</tt></dd>
-</dl>
-<dl><dt><strong>message_output_stream</strong></dt>
-</dl>
-<dl><dt><strong>timeline_model</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEFAULT_TAB_TIMEOUT</strong> = 60</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.tab_list.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.tab_list.html
deleted file mode 100644
index cccfea5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.tab_list.html
+++ /dev/null
@@ -1,64 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.tab_list</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.tab_list</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/tab_list.py">telemetry/internal/browser/tab_list.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.tab_list.html#TabList">TabList</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TabList">class <strong>TabList</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TabList-GetTabById"><strong>GetTabById</strong></a>(self, identifier)</dt><dd><tt>The&nbsp;identifier&nbsp;of&nbsp;a&nbsp;tab&nbsp;can&nbsp;be&nbsp;accessed&nbsp;with&nbsp;tab.id.</tt></dd></dl>
-
-<dl><dt><a name="TabList-New"><strong>New</strong></a>(self, timeout<font color="#909090">=300</font>)</dt></dl>
-
-<dl><dt><a name="TabList-__getitem__"><strong>__getitem__</strong></a>(self, index)</dt></dl>
-
-<dl><dt><a name="TabList-__init__"><strong>__init__</strong></a>(self, tab_list_backend)</dt></dl>
-
-<dl><dt><a name="TabList-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabList-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.user_agent.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.user_agent.html
deleted file mode 100644
index cdc875e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.user_agent.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.user_agent</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.user_agent</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/user_agent.py">telemetry/internal/browser/user_agent.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetChromeUserAgentArgumentFromType"><strong>GetChromeUserAgentArgumentFromType</strong></a>(user_agent_type)</dt><dd><tt>Returns&nbsp;a&nbsp;chrome&nbsp;user&nbsp;agent&nbsp;based&nbsp;on&nbsp;a&nbsp;user&nbsp;agent&nbsp;type.<br>
-This&nbsp;is&nbsp;derived&nbsp;from:<br>
-https://developers.google.com/chrome/mobile/docs/user-agent</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>UA_TYPE_MAPPING</strong> = {'desktop': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) A...TML, like Gecko) Chrome/40.0.2194.2 Safari/537.36', 'mobile': 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus ...ke Gecko) Chrome/40.0.2194.2 Mobile Safari/535.36', 'tablet': 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus ...TML, like Gecko) Chrome/40.0.2194.2 Safari/535.36', 'tablet_10_inch': 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus ...TML, like Gecko) Chrome/40.0.2194.2 Safari/535.36'}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.web_contents.html b/catapult/telemetry/docs/pydoc/telemetry.internal.browser.web_contents.html
deleted file mode 100644
index 0a7a99e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.browser.web_contents.html
+++ /dev/null
@@ -1,238 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.browser.web_contents</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.browser.html"><font color="#ffffff">browser</font></a>.web_contents</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/browser/web_contents.py">telemetry/internal/browser/web_contents.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.browser.web_contents.html#WebContents">WebContents</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebContents">class <strong>WebContents</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;web&nbsp;contents&nbsp;in&nbsp;the&nbsp;browser<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="WebContents-CloseConnections"><strong>CloseConnections</strong></a>(self)</dt><dd><tt>Closes&nbsp;all&nbsp;TCP&nbsp;sockets&nbsp;held&nbsp;open&nbsp;by&nbsp;the&nbsp;browser.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException&nbsp;if&nbsp;the&nbsp;tab&nbsp;is&nbsp;not&nbsp;alive.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-EnableAllContexts"><strong>EnableAllContexts</strong></a>(self)</dt><dd><tt>Enable&nbsp;all&nbsp;contexts&nbsp;in&nbsp;a&nbsp;page.&nbsp;Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;available&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-EvaluateJavaScript"><strong>EvaluateJavaScript</strong></a>(self, expr, timeout<font color="#909090">=90</font>)</dt><dd><tt>Evalutes&nbsp;expr&nbsp;in&nbsp;JavaScript&nbsp;and&nbsp;returns&nbsp;the&nbsp;JSONized&nbsp;result.<br>
-&nbsp;<br>
-Consider&nbsp;using&nbsp;ExecuteJavaScript&nbsp;for&nbsp;cases&nbsp;where&nbsp;the&nbsp;result&nbsp;of&nbsp;the<br>
-expression&nbsp;is&nbsp;not&nbsp;needed.<br>
-&nbsp;<br>
-If&nbsp;evaluation&nbsp;throws&nbsp;in&nbsp;JavaScript,&nbsp;a&nbsp;Python&nbsp;EvaluateException&nbsp;will<br>
-be&nbsp;raised.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;result&nbsp;of&nbsp;the&nbsp;evaluation&nbsp;cannot&nbsp;be&nbsp;JSONized,&nbsp;then&nbsp;an<br>
-EvaluationException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#WebContents-EvaluateJavaScriptInContext">EvaluateJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-EvaluateJavaScriptInContext"><strong>EvaluateJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-ExecuteJavaScript"><strong>ExecuteJavaScript</strong></a>(self, statement, timeout<font color="#909090">=90</font>)</dt><dd><tt>Executes&nbsp;statement&nbsp;in&nbsp;JavaScript.&nbsp;Does&nbsp;not&nbsp;return&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;statement&nbsp;failed&nbsp;to&nbsp;evaluate,&nbsp;EvaluateException&nbsp;will&nbsp;be&nbsp;raised.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#WebContents-ExecuteJavaScriptInContext">ExecuteJavaScriptInContext</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-ExecuteJavaScriptInContext"><strong>ExecuteJavaScriptInContext</strong></a>(self, expr, context_id, timeout<font color="#909090">=90</font>)</dt><dd><tt>Similar&nbsp;to&nbsp;ExecuteJavaScript,&nbsp;except&nbsp;context_id&nbsp;can&nbsp;refer&nbsp;to&nbsp;an&nbsp;iframe.<br>
-The&nbsp;main&nbsp;page&nbsp;has&nbsp;context_id=1,&nbsp;the&nbsp;first&nbsp;iframe&nbsp;context_id=2,&nbsp;etc.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.EvaluateException<br>
-&nbsp;&nbsp;exceptions.WebSocketDisconnected<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-GetUrl"><strong>GetUrl</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;URL&nbsp;to&nbsp;which&nbsp;the&nbsp;<a href="#WebContents">WebContents</a>&nbsp;is&nbsp;connected.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-GetWebviewContexts"><strong>GetWebviewContexts</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;webview&nbsp;contexts&nbsp;within&nbsp;the&nbsp;current&nbsp;inspector&nbsp;backend.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;<a href="#WebContents">WebContents</a>&nbsp;objects&nbsp;representing&nbsp;the&nbsp;webview&nbsp;contexts.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;If&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;in&nbsp;inspector&nbsp;backend&nbsp;connection.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-HasReachedQuiescence"><strong>HasReachedQuiescence</strong></a>(self)</dt><dd><tt>Determine&nbsp;whether&nbsp;the&nbsp;page&nbsp;has&nbsp;reached&nbsp;quiescence&nbsp;after&nbsp;loading.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;2&nbsp;seconds&nbsp;have&nbsp;passed&nbsp;since&nbsp;last&nbsp;resource&nbsp;received,&nbsp;false<br>
-&nbsp;&nbsp;otherwise.<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#WebContents-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-IsAlive"><strong>IsAlive</strong></a>(self)</dt><dd><tt>Whether&nbsp;the&nbsp;<a href="#WebContents">WebContents</a>&nbsp;is&nbsp;still&nbsp;operating&nbsp;normally.<br>
-&nbsp;<br>
-Since&nbsp;<a href="#WebContents">WebContents</a>&nbsp;function&nbsp;asynchronously,&nbsp;this&nbsp;method&nbsp;does&nbsp;not&nbsp;guarantee<br>
-that&nbsp;the&nbsp;<a href="#WebContents">WebContents</a>&nbsp;will&nbsp;still&nbsp;be&nbsp;alive&nbsp;at&nbsp;any&nbsp;point&nbsp;in&nbsp;the&nbsp;future.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;boolean&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;<a href="#WebContents">WebContents</a>&nbsp;is&nbsp;opearting&nbsp;normally.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-Navigate"><strong>Navigate</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout<font color="#909090">=90</font>)</dt><dd><tt>Navigates&nbsp;to&nbsp;url.<br>
-&nbsp;<br>
-If&nbsp;|script_to_evaluate_on_commit|&nbsp;is&nbsp;given,&nbsp;the&nbsp;script&nbsp;source&nbsp;string&nbsp;will&nbsp;be<br>
-evaluated&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;committed.&nbsp;This&nbsp;is&nbsp;after&nbsp;the&nbsp;context&nbsp;of<br>
-the&nbsp;page&nbsp;exists,&nbsp;but&nbsp;before&nbsp;any&nbsp;script&nbsp;on&nbsp;the&nbsp;page&nbsp;itself&nbsp;has&nbsp;executed.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-StartTimelineRecording"><strong>StartTimelineRecording</strong></a>(self)</dt><dd><tt>Starts&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-StopTimelineRecording"><strong>StopTimelineRecording</strong></a>(self)</dt><dd><tt>Stops&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-SynthesizeScrollGesture"><strong>SynthesizeScrollGesture</strong></a>(self, x<font color="#909090">=100</font>, y<font color="#909090">=800</font>, xDistance<font color="#909090">=0</font>, yDistance<font color="#909090">=-500</font>, xOverscroll<font color="#909090">=None</font>, yOverscroll<font color="#909090">=None</font>, preventFling<font color="#909090">=True</font>, speed<font color="#909090">=None</font>, gestureSourceType<font color="#909090">=None</font>, repeatCount<font color="#909090">=None</font>, repeatDelayMs<font color="#909090">=None</font>, interactionMarkerName<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;an&nbsp;inspector&nbsp;command&nbsp;that&nbsp;causes&nbsp;a&nbsp;repeatable&nbsp;browser&nbsp;driven&nbsp;scroll.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x:&nbsp;X&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;y:&nbsp;Y&nbsp;coordinate&nbsp;of&nbsp;the&nbsp;start&nbsp;of&nbsp;the&nbsp;gesture&nbsp;in&nbsp;CSS&nbsp;pixels.<br>
-&nbsp;&nbsp;xDistance:&nbsp;Distance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;X&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;left).<br>
-&nbsp;&nbsp;yDistance:&nbsp;Ddistance&nbsp;to&nbsp;scroll&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis&nbsp;(positive&nbsp;to&nbsp;scroll&nbsp;up).<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;X&nbsp;axis.<br>
-&nbsp;&nbsp;xOverscroll:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back&nbsp;along&nbsp;the&nbsp;Y&nbsp;axis.<br>
-&nbsp;&nbsp;preventFling:&nbsp;Prevents&nbsp;a&nbsp;fling&nbsp;gesture.<br>
-&nbsp;&nbsp;speed:&nbsp;Swipe&nbsp;speed&nbsp;in&nbsp;pixels&nbsp;per&nbsp;second.<br>
-&nbsp;&nbsp;gestureSourceType:&nbsp;Which&nbsp;type&nbsp;of&nbsp;input&nbsp;events&nbsp;to&nbsp;be&nbsp;generated.<br>
-&nbsp;&nbsp;repeatCount:&nbsp;Number&nbsp;of&nbsp;additional&nbsp;repeats&nbsp;beyond&nbsp;the&nbsp;first&nbsp;scroll.<br>
-&nbsp;&nbsp;repeatDelayMs:&nbsp;Number&nbsp;of&nbsp;milliseconds&nbsp;delay&nbsp;between&nbsp;each&nbsp;repeat.<br>
-&nbsp;&nbsp;interactionMarkerName:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;interaction&nbsp;markers&nbsp;to&nbsp;generate.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-WaitForDocumentReadyStateToBeComplete"><strong>WaitForDocumentReadyStateToBeComplete</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;finish&nbsp;loading.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#WebContents-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-WaitForDocumentReadyStateToBeInteractiveOrBetter"><strong>WaitForDocumentReadyStateToBeInteractiveOrBetter</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;document&nbsp;to&nbsp;be&nbsp;interactive.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#WebContents-WaitForJavaScriptExpression">WaitForJavaScriptExpression</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list<br>
-&nbsp;&nbsp;of&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-WaitForJavaScriptExpression"><strong>WaitForJavaScriptExpression</strong></a>(self, expr, timeout, dump_page_state_on_timeout<font color="#909090">=True</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;given&nbsp;JavaScript&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;robust&nbsp;against&nbsp;any&nbsp;given&nbsp;Evaluation&nbsp;timing&nbsp;out.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;expr:&nbsp;The&nbsp;expression&nbsp;to&nbsp;evaluate.<br>
-&nbsp;&nbsp;timeout:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;expression&nbsp;to&nbsp;be&nbsp;True.<br>
-&nbsp;&nbsp;dump_page_state_on_timeout:&nbsp;Whether&nbsp;to&nbsp;provide&nbsp;additional&nbsp;information&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page&nbsp;state&nbsp;if&nbsp;a&nbsp;TimeoutException&nbsp;is&nbsp;thrown.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException:&nbsp;On&nbsp;a&nbsp;timeout.<br>
-&nbsp;&nbsp;exceptions.Error:&nbsp;See&nbsp;<a href="#WebContents-EvaluateJavaScript">EvaluateJavaScript</a>()&nbsp;for&nbsp;a&nbsp;detailed&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;possible&nbsp;exceptions.</tt></dd></dl>
-
-<dl><dt><a name="WebContents-WaitForNavigate"><strong>WaitForNavigate</strong></a>(self, timeout<font color="#909090">=90</font>)</dt><dd><tt>Waits&nbsp;for&nbsp;the&nbsp;navigation&nbsp;to&nbsp;complete.<br>
-&nbsp;<br>
-The&nbsp;current&nbsp;page&nbsp;is&nbsp;expect&nbsp;to&nbsp;be&nbsp;in&nbsp;a&nbsp;navigation.<br>
-This&nbsp;function&nbsp;returns&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;complete&nbsp;or&nbsp;when<br>
-the&nbsp;timeout&nbsp;has&nbsp;been&nbsp;exceeded.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;exceptions.TimeoutException<br>
-&nbsp;&nbsp;exceptions.DevtoolsTargetCrashException</tt></dd></dl>
-
-<dl><dt><a name="WebContents-__init__"><strong>__init__</strong></a>(self, inspector_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-<dd><tt>Return&nbsp;the&nbsp;unique&nbsp;id&nbsp;string&nbsp;for&nbsp;this&nbsp;tab&nbsp;object.</tt></dd>
-</dl>
-<dl><dt><strong>message_output_stream</strong></dt>
-</dl>
-<dl><dt><strong>timeline_model</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEFAULT_WEB_CONTENTS_TIMEOUT</strong> = 90</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.android_forwarder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.android_forwarder.html
deleted file mode 100644
index eff075e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.android_forwarder.html
+++ /dev/null
@@ -1,202 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.forwarders.android_forwarder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.forwarders.html"><font color="#ffffff">forwarders</font></a>.android_forwarder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/forwarders/android_forwarder.py">telemetry/internal/forwarders/android_forwarder.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.android_device.html">telemetry.internal.platform.android_device</a><br>
-<a href="atexit.html">atexit</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-</td><td width="25%" valign=top><a href="devil.android.device_utils.html">devil.android.device_utils</a><br>
-<a href="pylib.forwarder.html">pylib.forwarder</a><br>
-<a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="re.html">re</a><br>
-<a href="socket.html">socket</a><br>
-</td><td width="25%" valign=top><a href="struct.html">struct</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidRndisConfigurator">AndroidRndisConfigurator</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidForwarder">AndroidForwarder</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidRndisForwarder">AndroidRndisForwarder</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidForwarderFactory">AndroidForwarderFactory</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidForwarder">class <strong>AndroidForwarder</strong></a>(<a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidForwarder">AndroidForwarder</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidForwarder-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidForwarder-__init__"><strong>__init__</strong></a>(self, device, port_pairs)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-<dl><dt><strong>host_port</strong></dt>
-</dl>
-<dl><dt><strong>port_pairs</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidForwarderFactory">class <strong>AndroidForwarderFactory</strong></a>(<a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidForwarderFactory">AndroidForwarderFactory</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidForwarderFactory-Create"><strong>Create</strong></a>(self, port_pairs)</dt></dl>
-
-<dl><dt><a name="AndroidForwarderFactory-__init__"><strong>__init__</strong></a>(self, device, use_rndis)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>does_forwarder_override_dns</strong></dt>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidRndisConfigurator">class <strong>AndroidRndisConfigurator</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Configures&nbsp;a&nbsp;linux&nbsp;host&nbsp;to&nbsp;connect&nbsp;to&nbsp;an&nbsp;android&nbsp;device&nbsp;via&nbsp;RNDIS.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;we&nbsp;intentionally&nbsp;leave&nbsp;RNDIS&nbsp;running&nbsp;on&nbsp;the&nbsp;device.&nbsp;This&nbsp;is<br>
-because&nbsp;the&nbsp;setup&nbsp;is&nbsp;slow&nbsp;and&nbsp;potentially&nbsp;flaky&nbsp;and&nbsp;leaving&nbsp;it&nbsp;running<br>
-doesn't&nbsp;seem&nbsp;to&nbsp;interfere&nbsp;with&nbsp;any&nbsp;other&nbsp;developer&nbsp;or&nbsp;bot&nbsp;use-cases.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AndroidRndisConfigurator-OverrideRoutingPolicy"><strong>OverrideRoutingPolicy</strong></a>(self)</dt><dd><tt>Override&nbsp;any&nbsp;routing&nbsp;policy&nbsp;that&nbsp;could&nbsp;prevent<br>
-packets&nbsp;from&nbsp;reaching&nbsp;the&nbsp;rndis&nbsp;interface</tt></dd></dl>
-
-<dl><dt><a name="AndroidRndisConfigurator-RestoreRoutingPolicy"><strong>RestoreRoutingPolicy</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidRndisConfigurator-__init__"><strong>__init__</strong></a>(self, device)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidRndisForwarder">class <strong>AndroidRndisForwarder</strong></a>(<a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Forwards&nbsp;traffic&nbsp;using&nbsp;RNDIS.&nbsp;Assumes&nbsp;the&nbsp;device&nbsp;has&nbsp;root&nbsp;access.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.android_forwarder.html#AndroidRndisForwarder">AndroidRndisForwarder</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidRndisForwarder-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidRndisForwarder-__init__"><strong>__init__</strong></a>(self, device, rndis_configurator, port_pairs)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>host_port</strong></dt>
-</dl>
-<dl><dt><strong>port_pairs</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.cros_forwarder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.cros_forwarder.html
deleted file mode 100644
index 7c7b9ae..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.cros_forwarder.html
+++ /dev/null
@@ -1,116 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.forwarders.cros_forwarder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.forwarders.html"><font color="#ffffff">forwarders</font></a>.cros_forwarder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/forwarders/cros_forwarder.py">telemetry/internal/forwarders/cros_forwarder.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.forwarders.do_nothing_forwarder.html">telemetry.internal.forwarders.do_nothing_forwarder</a><br>
-<a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.cros_forwarder.html#CrOsSshForwarder">CrOsSshForwarder</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.cros_forwarder.html#CrOsForwarderFactory">CrOsForwarderFactory</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOsForwarderFactory">class <strong>CrOsForwarderFactory</strong></a>(<a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.cros_forwarder.html#CrOsForwarderFactory">CrOsForwarderFactory</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrOsForwarderFactory-Create"><strong>Create</strong></a>(self, port_pairs, use_remote_port_forwarding<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;pylint:&nbsp;disable=arguments-differ</tt></dd></dl>
-
-<dl><dt><a name="CrOsForwarderFactory-__init__"><strong>__init__</strong></a>(self, cri)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>does_forwarder_override_dns</strong></dt>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOsSshForwarder">class <strong>CrOsSshForwarder</strong></a>(<a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.cros_forwarder.html#CrOsSshForwarder">CrOsSshForwarder</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrOsSshForwarder-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrOsSshForwarder-__init__"><strong>__init__</strong></a>(self, cri, use_remote_port_forwarding, port_pairs)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>host_port</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-<dl><dt><strong>port_pairs</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.do_nothing_forwarder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.do_nothing_forwarder.html
deleted file mode 100644
index ad535fc..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.do_nothing_forwarder.html
+++ /dev/null
@@ -1,316 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.forwarders.do_nothing_forwarder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.forwarders.html"><font color="#ffffff">forwarders</font></a>.do_nothing_forwarder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/forwarders/do_nothing_forwarder.py">telemetry/internal/forwarders/do_nothing_forwarder.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="contextlib.html">contextlib</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="socket.html">socket</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#ConnectionError">ConnectionError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#PortsMismatchError">PortsMismatchError</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#DoNothingForwarder">DoNothingForwarder</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#DoNothingForwarderFactory">DoNothingForwarderFactory</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ConnectionError">class <strong>ConnectionError</strong></a>(<a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Raised&nbsp;when&nbsp;unable&nbsp;to&nbsp;connect&nbsp;to&nbsp;local&nbsp;TCP&nbsp;ports.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#ConnectionError">ConnectionError</a></dd>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ConnectionError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ConnectionError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ConnectionError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ConnectionError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ConnectionError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ConnectionError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ConnectionError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DoNothingForwarder">class <strong>DoNothingForwarder</strong></a>(<a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Check&nbsp;that&nbsp;no&nbsp;forwarding&nbsp;is&nbsp;needed&nbsp;for&nbsp;the&nbsp;given&nbsp;port&nbsp;pairs.<br>
-&nbsp;<br>
-The&nbsp;local&nbsp;and&nbsp;remote&nbsp;ports&nbsp;must&nbsp;be&nbsp;equal.&nbsp;Otherwise,&nbsp;the&nbsp;"do&nbsp;nothing"<br>
-forwarder&nbsp;does&nbsp;not&nbsp;make&nbsp;sense.&nbsp;(Raises&nbsp;<a href="#PortsMismatchError">PortsMismatchError</a>.)<br>
-&nbsp;<br>
-Also,&nbsp;check&nbsp;that&nbsp;all&nbsp;TCP&nbsp;ports&nbsp;support&nbsp;connections.&nbsp;&nbsp;(Raises&nbsp;<a href="#ConnectionError">ConnectionError</a>.)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#DoNothingForwarder">DoNothingForwarder</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DoNothingForwarder-__init__"><strong>__init__</strong></a>(self, port_pairs)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>:<br>
-<dl><dt><a name="DoNothingForwarder-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#Forwarder">telemetry.internal.forwarders.Forwarder</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-<dl><dt><strong>host_port</strong></dt>
-</dl>
-<dl><dt><strong>port_pairs</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DoNothingForwarderFactory">class <strong>DoNothingForwarderFactory</strong></a>(<a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#DoNothingForwarderFactory">DoNothingForwarderFactory</a></dd>
-<dd><a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DoNothingForwarderFactory-Create"><strong>Create</strong></a>(self, port_pairs)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.html#ForwarderFactory">telemetry.internal.forwarders.ForwarderFactory</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>does_forwarder_override_dns</strong></dt>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Error">class <strong>Error</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Base&nbsp;class&nbsp;for&nbsp;exceptions&nbsp;in&nbsp;this&nbsp;module.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="Error-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Error-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="Error-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Error-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Error-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="Error-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="Error-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="Error-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="Error-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="Error-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="Error-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#Error-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="Error-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PortsMismatchError">class <strong>PortsMismatchError</strong></a>(<a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Raised&nbsp;when&nbsp;local&nbsp;and&nbsp;remote&nbsp;ports&nbsp;are&nbsp;not&nbsp;equal.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#PortsMismatchError">PortsMismatchError</a></dd>
-<dd><a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.forwarders.do_nothing_forwarder.html#Error">Error</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="PortsMismatchError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#PortsMismatchError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="PortsMismatchError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PortsMismatchError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="PortsMismatchError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#PortsMismatchError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="PortsMismatchError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.html b/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.html
deleted file mode 100644
index bf3f7d5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.forwarders.html
+++ /dev/null
@@ -1,293 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.forwarders</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.forwarders</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/forwarders/__init__.py">telemetry/internal/forwarders/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.forwarders.android_forwarder.html">android_forwarder</a><br>
-<a href="telemetry.internal.forwarders.cros_forwarder.html">cros_forwarder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.forwarders.cros_forwarder_unittest.html">cros_forwarder_unittest</a><br>
-<a href="telemetry.internal.forwarders.do_nothing_forwarder.html">do_nothing_forwarder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.forwarders.do_nothing_forwarder_unittest.html">do_nothing_forwarder_unittest</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#Forwarder">Forwarder</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#ForwarderFactory">ForwarderFactory</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#tuple">__builtin__.tuple</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#PortPair">PortPair</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.forwarders.html#PortPairs">PortPairs</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Forwarder">class <strong>Forwarder</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Forwarder-Close"><strong>Close</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Forwarder-__init__"><strong>__init__</strong></a>(self, port_pairs)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-<dl><dt><strong>host_port</strong></dt>
-</dl>
-<dl><dt><strong>port_pairs</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ForwarderFactory">class <strong>ForwarderFactory</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ForwarderFactory-Create"><strong>Create</strong></a>(self, port_pairs)</dt><dd><tt>Creates&nbsp;a&nbsp;forwarder&nbsp;that&nbsp;maps&nbsp;remote&nbsp;(device)&nbsp;&lt;-&gt;&nbsp;local&nbsp;(host)&nbsp;ports.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;port_pairs:&nbsp;A&nbsp;<a href="#PortPairs">PortPairs</a>&nbsp;instance&nbsp;that&nbsp;consists&nbsp;of&nbsp;a&nbsp;<a href="#PortPair">PortPair</a>&nbsp;mapping<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;each&nbsp;protocol.&nbsp;http&nbsp;is&nbsp;required.&nbsp;https&nbsp;and&nbsp;dns&nbsp;may&nbsp;be&nbsp;None.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>does_forwarder_override_dns</strong></dt>
-</dl>
-<dl><dt><strong>host_ip</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PortPair">class <strong>PortPair</strong></a>(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#PortPair">PortPair</a>(local_port,&nbsp;remote_port)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.html#PortPair">PortPair</a></dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PortPair-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;<a href="__builtin__.html#tuple">tuple</a>.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="PortPair-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="PortPair-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#PortPair">PortPair</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="PortPair-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#PortPair">PortPair</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="PortPair-__new__"><strong>__new__</strong></a>(_cls, local_port, remote_port)</dt><dd><tt>Create&nbsp;new&nbsp;instance&nbsp;of&nbsp;<a href="#PortPair">PortPair</a>(local_port,&nbsp;remote_port)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd>
-</dl>
-<dl><dt><strong>local_port</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<dl><dt><strong>remote_port</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>_fields</strong> = ('local_port', 'remote_port')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="PortPair-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPair-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="PortPair-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#PortPair-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="PortPair-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#PortPair-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PortPair-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#PortPair-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PortPairs">class <strong>PortPairs</strong></a>(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#PortPairs">PortPairs</a>(http,&nbsp;https,&nbsp;dns)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.forwarders.html#PortPairs">PortPairs</a></dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PortPairs-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;<a href="__builtin__.html#tuple">tuple</a>.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#PortPairs">PortPairs</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="PortPairs-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#PortPairs">PortPairs</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="PortPairs-__new__"><strong>__new__</strong></a>(_cls, http, https, dns)</dt><dd><tt>Create&nbsp;new&nbsp;instance&nbsp;of&nbsp;<a href="#PortPairs">PortPairs</a>(http,&nbsp;https,&nbsp;dns)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd>
-</dl>
-<dl><dt><strong>dns</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;2</tt></dd>
-</dl>
-<dl><dt><strong>http</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<dl><dt><strong>https</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>_fields</strong> = ('http', 'https', 'dns')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="PortPairs-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#PortPairs-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#PortPairs-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#PortPairs-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="PortPairs-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#PortPairs-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.html b/catapult/telemetry/docs/pydoc/telemetry.internal.html
deleted file mode 100644
index cd82947..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.internal</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/__init__.py">telemetry/internal/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.actions.html"><strong>actions</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.app.html"><strong>app</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.backends.html"><strong>backends</strong>&nbsp;(package)</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.browser.html"><strong>browser</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.forwarders.html"><strong>forwarders</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.image_processing.html"><strong>image_processing</strong>&nbsp;(package)</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.html"><strong>platform</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.results.html"><strong>results</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.story_runner.html">story_runner</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.story_runner_unittest.html">story_runner_unittest</a><br>
-<a href="telemetry.internal.testing.html"><strong>testing</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.util.html"><strong>util</strong>&nbsp;(package)</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing._bitmap.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing._bitmap.html
deleted file mode 100644
index 2c3f377..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing._bitmap.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing._bitmap</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>._bitmap</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/_bitmap.py">telemetry/internal/image_processing/_bitmap.py</a></font></td></tr></table>
-    <p><tt><a href="#Bitmap">Bitmap</a>&nbsp;is&nbsp;a&nbsp;basic&nbsp;wrapper&nbsp;for&nbsp;image&nbsp;pixels.&nbsp;It&nbsp;includes&nbsp;some&nbsp;basic&nbsp;processing<br>
-tools:&nbsp;crop,&nbsp;find&nbsp;bounding&nbsp;box&nbsp;of&nbsp;a&nbsp;color&nbsp;and&nbsp;compute&nbsp;histogram&nbsp;of&nbsp;color&nbsp;values.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="array.html">array</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="cStringIO.html">cStringIO</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.color_histogram.html">telemetry.util.color_histogram</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="png.html">png</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.rgba_color.html">telemetry.util.rgba_color</a><br>
-<a href="struct.html">struct</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing._bitmap.html#Bitmap">Bitmap</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Bitmap">class <strong>Bitmap</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Utilities&nbsp;for&nbsp;parsing&nbsp;and&nbsp;inspecting&nbsp;a&nbsp;bitmap.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Bitmap-ColorHistogram"><strong>ColorHistogram</strong></a>(self, ignore_color<font color="#909090">=None</font>, tolerance<font color="#909090">=0</font>)</dt></dl>
-
-<dl><dt><a name="Bitmap-Crop"><strong>Crop</strong></a>(self, left, top, width, height)</dt></dl>
-
-<dl><dt><a name="Bitmap-Diff"><strong>Diff</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="Bitmap-GetBoundingBox"><strong>GetBoundingBox</strong></a>(self, color, tolerance<font color="#909090">=0</font>)</dt></dl>
-
-<dl><dt><a name="Bitmap-GetPixelColor"><strong>GetPixelColor</strong></a>(self, x, y)</dt></dl>
-
-<dl><dt><a name="Bitmap-IsEqual"><strong>IsEqual</strong></a>(self, other, tolerance<font color="#909090">=0</font>)</dt></dl>
-
-<dl><dt><a name="Bitmap-WritePngFile"><strong>WritePngFile</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="Bitmap-__init__"><strong>__init__</strong></a>(self, bpp, width, height, pixels, metadata<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="Bitmap-FromPng"><strong>FromPng</strong></a>(png_data)</dt></dl>
-
-<dl><dt><a name="Bitmap-FromPngFile"><strong>FromPngFile</strong></a>(path)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>bpp</strong></dt>
-</dl>
-<dl><dt><strong>height</strong></dt>
-</dl>
-<dl><dt><strong>metadata</strong></dt>
-</dl>
-<dl><dt><strong>pixels</strong></dt>
-</dl>
-<dl><dt><strong>width</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.cv_util.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.cv_util.html
deleted file mode 100644
index 68c1a5e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.cv_util.html
+++ /dev/null
@@ -1,50 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.cv_util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.cv_util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/cv_util.py">telemetry/internal/image_processing/cv_util.py</a></font></td></tr></table>
-    <p><tt>This&nbsp;module&nbsp;provides&nbsp;implementations&nbsp;of&nbsp;common&nbsp;computer&nbsp;Vision&nbsp;operations.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-</td><td width="25%" valign=top><a href="numpy.html">numpy</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AreLinesOrthogonal"><strong>AreLinesOrthogonal</strong></a>(line1, line2, tolerance)</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;lines&nbsp;are&nbsp;within&nbsp;tolerance&nbsp;radians&nbsp;of&nbsp;being&nbsp;orthogonal.</tt></dd></dl>
- <dl><dt><a name="-ExtendLines"><strong>ExtendLines</strong></a>(lines, length)</dt><dd><tt>Extends&nbsp;lines&nbsp;in&nbsp;an&nbsp;array&nbsp;to&nbsp;a&nbsp;given&nbsp;length,&nbsp;maintaining&nbsp;the&nbsp;center<br>
-point.&nbsp;Does&nbsp;not&nbsp;necessarily&nbsp;maintain&nbsp;point&nbsp;order.</tt></dd></dl>
- <dl><dt><a name="-FindLineIntersection"><strong>FindLineIntersection</strong></a>(line1, line2)</dt><dd><tt>If&nbsp;the&nbsp;line&nbsp;segments&nbsp;intersect,&nbsp;returns&nbsp;True&nbsp;and&nbsp;their&nbsp;intersection.<br>
-Otherwise,&nbsp;returns&nbsp;False&nbsp;and&nbsp;the&nbsp;intersection&nbsp;of&nbsp;the&nbsp;line&nbsp;segments&nbsp;if&nbsp;they<br>
-were&nbsp;to&nbsp;be&nbsp;extended.</tt></dd></dl>
- <dl><dt><a name="-IsPointApproxOnLine"><strong>IsPointApproxOnLine</strong></a>(point, line, tolerance<font color="#909090">=1</font>)</dt><dd><tt>Approximates&nbsp;distance&nbsp;between&nbsp;point&nbsp;and&nbsp;line&nbsp;for&nbsp;small&nbsp;distances&nbsp;using<br>
-the&nbsp;determinant&nbsp;and&nbsp;checks&nbsp;whether&nbsp;it's&nbsp;within&nbsp;the&nbsp;tolerance.&nbsp;Tolerance&nbsp;is<br>
-an&nbsp;approximate&nbsp;distance&nbsp;in&nbsp;pixels,&nbsp;precision&nbsp;decreases&nbsp;with&nbsp;distance.</tt></dd></dl>
- <dl><dt><a name="-SqDistance"><strong>SqDistance</strong></a>(point1, point2)</dt><dd><tt>Computes&nbsp;the&nbsp;square&nbsp;of&nbsp;the&nbsp;distance&nbsp;between&nbsp;two&nbsp;points.</tt></dd></dl>
- <dl><dt><a name="-SqDistances"><strong>SqDistances</strong></a>(points1, points2)</dt><dd><tt>Computes&nbsp;the&nbsp;square&nbsp;of&nbsp;the&nbsp;distance&nbsp;between&nbsp;two&nbsp;sets&nbsp;of&nbsp;points,&nbsp;or&nbsp;a<br>
-set&nbsp;of&nbsp;points&nbsp;and&nbsp;a&nbsp;point.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>division</strong> = _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.fake_frame_generator.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.fake_frame_generator.html
deleted file mode 100644
index 249a327..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.fake_frame_generator.html
+++ /dev/null
@@ -1,114 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.fake_frame_generator</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.fake_frame_generator</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/fake_frame_generator.py">telemetry/internal/image_processing/fake_frame_generator.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.frame_generator.html">telemetry.internal.image_processing.frame_generator</a><br>
-</td><td width="25%" valign=top><a href="numpy.html">numpy</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.fake_frame_generator.html#FakeFrameGenerator">FakeFrameGenerator</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakeFrameGenerator">class <strong>FakeFrameGenerator</strong></a>(<a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Fakes&nbsp;a&nbsp;Frame&nbsp;Generator,&nbsp;for&nbsp;testing.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;_frame_index:&nbsp;A&nbsp;frame&nbsp;read&nbsp;counter.<br>
-&nbsp;&nbsp;_timestamps:&nbsp;A&nbsp;generator&nbsp;of&nbsp;timestamps&nbsp;to&nbsp;return,&nbsp;or&nbsp;None.<br>
-&nbsp;&nbsp;_timestamp:&nbsp;The&nbsp;current&nbsp;timestamp.<br>
-&nbsp;&nbsp;_dimensions:&nbsp;The&nbsp;dimensions&nbsp;to&nbsp;return.<br>
-&nbsp;&nbsp;_channels:&nbsp;The&nbsp;number&nbsp;of&nbsp;color&nbsp;channels&nbsp;to&nbsp;return&nbsp;in&nbsp;the&nbsp;generated&nbsp;frames.<br>
-&nbsp;&nbsp;_frames:&nbsp;The&nbsp;number&nbsp;of&nbsp;frames&nbsp;to&nbsp;return&nbsp;before&nbsp;fake&nbsp;EOF.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.image_processing.fake_frame_generator.html#FakeFrameGenerator">FakeFrameGenerator</a></dd>
-<dd><a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FakeFrameGenerator-__init__"><strong>__init__</strong></a>(self, frames<font color="#909090">=1e+16</font>, dimensions<font color="#909090">=(320, 240)</font>, channels<font color="#909090">=3</font>, timestamps<font color="#909090">=&lt;generator object &lt;genexpr&gt;&gt;</font>)</dt><dd><tt>Initializes&nbsp;the&nbsp;<a href="#FakeFrameGenerator">FakeFrameGenerator</a>&nbsp;object.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;frames:&nbsp;int,&nbsp;The&nbsp;number&nbsp;of&nbsp;frames&nbsp;to&nbsp;return&nbsp;before&nbsp;fake&nbsp;EOF.<br>
-&nbsp;&nbsp;dimensions:&nbsp;(int,&nbsp;int),&nbsp;The&nbsp;dimensions&nbsp;to&nbsp;return.<br>
-&nbsp;&nbsp;timestamps:&nbsp;generator,&nbsp;A&nbsp;generator&nbsp;of&nbsp;timestamps&nbsp;to&nbsp;return.&nbsp;The&nbsp;default<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;is&nbsp;an&nbsp;infinite&nbsp;0&nbsp;generator.<br>
-&nbsp;&nbsp;channels:&nbsp;int,&nbsp;The&nbsp;number&nbsp;of&nbsp;color&nbsp;channels&nbsp;to&nbsp;return&nbsp;in&nbsp;the&nbsp;generated<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frames,&nbsp;1&nbsp;for&nbsp;greyscale,&nbsp;3&nbsp;for&nbsp;RGB.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>CurrentFrameNumber</strong></dt>
-</dl>
-<dl><dt><strong>CurrentTimestamp</strong></dt>
-</dl>
-<dl><dt><strong>Dimensions</strong></dt>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>:<br>
-<dl><dt><strong>Generator</strong></dt>
-<dd><tt>Returns:<br>
-A&nbsp;reference&nbsp;to&nbsp;the&nbsp;created&nbsp;generator.</tt></dd>
-</dl>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.frame_generator.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.frame_generator.html
deleted file mode 100644
index 8cfa3cc..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.frame_generator.html
+++ /dev/null
@@ -1,160 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.frame_generator</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.frame_generator</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/frame_generator.py">telemetry/internal/image_processing/frame_generator.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="abc.html">abc</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">FrameGenerator</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.frame_generator.html#FrameReadError">FrameReadError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FrameGenerator">class <strong>FrameGenerator</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Defines&nbsp;an&nbsp;interface&nbsp;for&nbsp;reading&nbsp;input&nbsp;frames.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;_generator:&nbsp;A&nbsp;reference&nbsp;to&nbsp;the&nbsp;created&nbsp;generator.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FrameGenerator-__init__"><strong>__init__</strong></a>(self)</dt><dd><tt>Initializes&nbsp;the&nbsp;<a href="#FrameGenerator">FrameGenerator</a>&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>CurrentFrameNumber</strong></dt>
-<dd><tt>Returns:<br>
-int,&nbsp;The&nbsp;frame&nbsp;index&nbsp;of&nbsp;the&nbsp;current&nbsp;frame.</tt></dd>
-</dl>
-<dl><dt><strong>CurrentTimestamp</strong></dt>
-<dd><tt>Returns:<br>
-float,&nbsp;The&nbsp;timestamp&nbsp;of&nbsp;the&nbsp;current&nbsp;frame&nbsp;in&nbsp;milliseconds.</tt></dd>
-</dl>
-<dl><dt><strong>Dimensions</strong></dt>
-<dd><tt>Returns:<br>
-The&nbsp;dimensions&nbsp;of&nbsp;the&nbsp;frame&nbsp;sequence&nbsp;as&nbsp;a&nbsp;tuple&nbsp;int&nbsp;(width,&nbsp;height).<br>
-This&nbsp;value&nbsp;should&nbsp;be&nbsp;constant&nbsp;across&nbsp;frames.</tt></dd>
-</dl>
-<dl><dt><strong>Generator</strong></dt>
-<dd><tt>Returns:<br>
-A&nbsp;reference&nbsp;to&nbsp;the&nbsp;created&nbsp;generator.</tt></dd>
-</dl>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset(['CurrentFrameNumber', 'CurrentTimestamp', 'Dimensions', '_CreateGenerator'])</dl>
-
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FrameReadError">class <strong>FrameReadError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.image_processing.frame_generator.html#FrameReadError">FrameReadError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="FrameReadError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#FrameReadError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="FrameReadError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="FrameReadError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="FrameReadError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#FrameReadError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="FrameReadError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.html
deleted file mode 100644
index 5d9a36a..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.image_processing</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.image_processing</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/__init__.py">telemetry/internal/image_processing/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.image_processing._bitmap.html">_bitmap</a><br>
-<a href="telemetry.internal.image_processing.cv_util.html">cv_util</a><br>
-<a href="telemetry.internal.image_processing.cv_util_unittest.html">cv_util_unittest</a><br>
-<a href="telemetry.internal.image_processing.fake_frame_generator.html">fake_frame_generator</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.frame_generator.html">frame_generator</a><br>
-<a href="telemetry.internal.image_processing.image_util_bitmap_impl.html">image_util_bitmap_impl</a><br>
-<a href="telemetry.internal.image_processing.image_util_numpy_impl.html">image_util_numpy_impl</a><br>
-<a href="telemetry.internal.image_processing.screen_finder.html">screen_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.screen_finder_unittest.html">screen_finder_unittest</a><br>
-<a href="telemetry.internal.image_processing.video.html">video</a><br>
-<a href="telemetry.internal.image_processing.video_file_frame_generator.html">video_file_frame_generator</a><br>
-<a href="telemetry.internal.image_processing.video_file_frame_generator_unittest.html">video_file_frame_generator_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.video_unittest.html">video_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.image_util_bitmap_impl.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.image_util_bitmap_impl.html
deleted file mode 100644
index b92e1c8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.image_util_bitmap_impl.html
+++ /dev/null
@@ -1,53 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.image_util_bitmap_impl</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.image_util_bitmap_impl</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/image_util_bitmap_impl.py">telemetry/internal/image_processing/image_util_bitmap_impl.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.image_processing._bitmap.html">telemetry.internal.image_processing._bitmap</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AreEqual"><strong>AreEqual</strong></a>(bitmap1, bitmap2, tolerance, _)</dt></dl>
- <dl><dt><a name="-Channels"><strong>Channels</strong></a>(bitmap)</dt></dl>
- <dl><dt><a name="-Crop"><strong>Crop</strong></a>(bitmap, left, top, width, height)</dt></dl>
- <dl><dt><a name="-Diff"><strong>Diff</strong></a>(bitmap1, bitmap2)</dt></dl>
- <dl><dt><a name="-FromPng"><strong>FromPng</strong></a>(png_data)</dt></dl>
- <dl><dt><a name="-FromPngFile"><strong>FromPngFile</strong></a>(path)</dt></dl>
- <dl><dt><a name="-FromRGBPixels"><strong>FromRGBPixels</strong></a>(width, height, pixels, bpp)</dt></dl>
- <dl><dt><a name="-GetBoundingBox"><strong>GetBoundingBox</strong></a>(bitmap, color, tolerance)</dt></dl>
- <dl><dt><a name="-GetColorHistogram"><strong>GetColorHistogram</strong></a>(bitmap, ignore_color, tolerance)</dt></dl>
- <dl><dt><a name="-GetPixelColor"><strong>GetPixelColor</strong></a>(bitmap, x, y)</dt></dl>
- <dl><dt><a name="-Height"><strong>Height</strong></a>(bitmap)</dt></dl>
- <dl><dt><a name="-Pixels"><strong>Pixels</strong></a>(bitmap)</dt></dl>
- <dl><dt><a name="-Width"><strong>Width</strong></a>(bitmap)</dt></dl>
- <dl><dt><a name="-WritePngFile"><strong>WritePngFile</strong></a>(bitmap, path)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>division</strong> = _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.image_util_numpy_impl.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.image_util_numpy_impl.html
deleted file mode 100644
index c5786d5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.image_util_numpy_impl.html
+++ /dev/null
@@ -1,58 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.image_util_numpy_impl</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.image_util_numpy_impl</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/image_util_numpy_impl.py">telemetry/internal/image_processing/image_util_numpy_impl.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.util.color_histogram.html">telemetry.util.color_histogram</a><br>
-<a href="cv2.html">cv2</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-<a href="numpy.html">numpy</a><br>
-</td><td width="25%" valign=top><a href="png.html">png</a><br>
-<a href="telemetry.util.rgba_color.html">telemetry.util.rgba_color</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AreEqual"><strong>AreEqual</strong></a>(image1, image2, tolerance, likely_equal)</dt></dl>
- <dl><dt><a name="-Channels"><strong>Channels</strong></a>(image)</dt></dl>
- <dl><dt><a name="-Crop"><strong>Crop</strong></a>(image, left, top, width, height)</dt></dl>
- <dl><dt><a name="-Diff"><strong>Diff</strong></a>(image1, image2)</dt></dl>
- <dl><dt><a name="-FromPng"><strong>FromPng</strong></a>(png_data)</dt></dl>
- <dl><dt><a name="-FromPngFile"><strong>FromPngFile</strong></a>(path)</dt></dl>
- <dl><dt><a name="-FromRGBPixels"><strong>FromRGBPixels</strong></a>(width, height, pixels, bpp)</dt></dl>
- <dl><dt><a name="-GetBoundingBox"><strong>GetBoundingBox</strong></a>(image, color, tolerance)</dt></dl>
- <dl><dt><a name="-GetColorHistogram"><strong>GetColorHistogram</strong></a>(image, ignore_color, tolerance)</dt></dl>
- <dl><dt><a name="-GetPixelColor"><strong>GetPixelColor</strong></a>(image, x, y)</dt></dl>
- <dl><dt><a name="-Height"><strong>Height</strong></a>(image)</dt></dl>
- <dl><dt><a name="-Pixels"><strong>Pixels</strong></a>(image)</dt></dl>
- <dl><dt><a name="-Width"><strong>Width</strong></a>(image)</dt></dl>
- <dl><dt><a name="-WritePngFile"><strong>WritePngFile</strong></a>(image, path)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>division</strong> = _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.screen_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.screen_finder.html
deleted file mode 100644
index a635519..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.screen_finder.html
+++ /dev/null
@@ -1,168 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.screen_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.screen_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/screen_finder.py">telemetry/internal/image_processing/screen_finder.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.<br>
-#<br>
-#&nbsp;This&nbsp;script&nbsp;attempts&nbsp;to&nbsp;detect&nbsp;the&nbsp;region&nbsp;of&nbsp;a&nbsp;camera's&nbsp;field&nbsp;of&nbsp;view&nbsp;that<br>
-#&nbsp;contains&nbsp;the&nbsp;screen&nbsp;of&nbsp;the&nbsp;device&nbsp;we&nbsp;are&nbsp;testing.<br>
-#<br>
-#&nbsp;Usage:&nbsp;./screen_finder.py&nbsp;path_to_video&nbsp;0&nbsp;0&nbsp;--verbose</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="copy.html">copy</a><br>
-<a href="cv2.html">cv2</a><br>
-<a href="telemetry.internal.image_processing.cv_util.html">telemetry.internal.image_processing.cv_util</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-<a href="telemetry.internal.image_processing.frame_generator.html">telemetry.internal.image_processing.frame_generator</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="numpy.html">numpy</a><br>
-<a href="os.html">os</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.video_file_frame_generator.html">telemetry.internal.image_processing.video_file_frame_generator</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.screen_finder.html#ScreenFinder">ScreenFinder</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ScreenFinder">class <strong>ScreenFinder</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Finds&nbsp;and&nbsp;extracts&nbsp;device&nbsp;screens&nbsp;from&nbsp;video.<br>
-&nbsp;<br>
-Sample&nbsp;Usage:<br>
-&nbsp;&nbsp;sf&nbsp;=&nbsp;<a href="#ScreenFinder">ScreenFinder</a>(sys.argv[1])<br>
-&nbsp;&nbsp;while&nbsp;sf.<a href="#ScreenFinder-HasNext">HasNext</a>():<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ret,&nbsp;screen&nbsp;=&nbsp;sf.<a href="#ScreenFinder-GetNext">GetNext</a>()<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;_lost_corners:&nbsp;Each&nbsp;index&nbsp;represents&nbsp;whether&nbsp;or&nbsp;not&nbsp;we&nbsp;lost&nbsp;track&nbsp;of&nbsp;that<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;corner&nbsp;on&nbsp;the&nbsp;previous&nbsp;frame.&nbsp;Ordered&nbsp;by&nbsp;[top-right,&nbsp;top-left,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;bottom-left,&nbsp;bottom-right]<br>
-&nbsp;&nbsp;_frame:&nbsp;An&nbsp;unmodified&nbsp;copy&nbsp;of&nbsp;the&nbsp;frame&nbsp;we're&nbsp;currently&nbsp;processing.<br>
-&nbsp;&nbsp;_frame_debug:&nbsp;A&nbsp;copy&nbsp;of&nbsp;the&nbsp;frame&nbsp;we're&nbsp;currently&nbsp;processing,&nbsp;may&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;modified&nbsp;at&nbsp;any&nbsp;time,&nbsp;used&nbsp;for&nbsp;debugging.<br>
-&nbsp;&nbsp;_frame_grey:&nbsp;A&nbsp;greyscale&nbsp;copy&nbsp;of&nbsp;the&nbsp;frame&nbsp;we're&nbsp;currently&nbsp;processing.<br>
-&nbsp;&nbsp;_frame_edges:&nbsp;A&nbsp;Canny&nbsp;Edge&nbsp;detected&nbsp;copy&nbsp;of&nbsp;the&nbsp;frame&nbsp;we're&nbsp;currently<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processing.<br>
-&nbsp;&nbsp;_screen_size:&nbsp;The&nbsp;size&nbsp;of&nbsp;device&nbsp;screen&nbsp;in&nbsp;the&nbsp;video&nbsp;when&nbsp;first&nbsp;detected.<br>
-&nbsp;&nbsp;_avg_corners:&nbsp;Exponentially&nbsp;weighted&nbsp;average&nbsp;of&nbsp;the&nbsp;previous&nbsp;corner<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;locations.<br>
-&nbsp;&nbsp;_prev_corners:&nbsp;The&nbsp;location&nbsp;of&nbsp;the&nbsp;corners&nbsp;in&nbsp;the&nbsp;previous&nbsp;frame.<br>
-&nbsp;&nbsp;_lost_corner_frames:&nbsp;A&nbsp;counter&nbsp;of&nbsp;the&nbsp;number&nbsp;of&nbsp;successive&nbsp;frames&nbsp;in&nbsp;which<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;we've&nbsp;lost&nbsp;a&nbsp;corner&nbsp;location.<br>
-&nbsp;&nbsp;_border:&nbsp;See&nbsp;|border|&nbsp;above.<br>
-&nbsp;&nbsp;_min_line_length:&nbsp;The&nbsp;minimum&nbsp;length&nbsp;a&nbsp;line&nbsp;must&nbsp;be&nbsp;before&nbsp;we&nbsp;consider&nbsp;it<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;possible&nbsp;screen&nbsp;edge.<br>
-&nbsp;&nbsp;_frame_generator:&nbsp;See&nbsp;|frame_generator|&nbsp;above.<br>
-&nbsp;&nbsp;_width,&nbsp;_height:&nbsp;The&nbsp;width&nbsp;and&nbsp;height&nbsp;of&nbsp;the&nbsp;frame.<br>
-&nbsp;&nbsp;_anglesp5,&nbsp;_anglesm5:&nbsp;The&nbsp;angles&nbsp;for&nbsp;each&nbsp;point&nbsp;we&nbsp;look&nbsp;at&nbsp;in&nbsp;the&nbsp;grid<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;when&nbsp;computing&nbsp;brightness,&nbsp;constant&nbsp;across&nbsp;frames.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ScreenFinder-GetNext"><strong>GetNext</strong></a>(self)</dt><dd><tt>Gets&nbsp;the&nbsp;next&nbsp;screen&nbsp;image.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;numpy&nbsp;matrix&nbsp;containing&nbsp;the&nbsp;screen&nbsp;surrounded&nbsp;by&nbsp;the&nbsp;number&nbsp;of&nbsp;border<br>
-&nbsp;&nbsp;pixels&nbsp;specified&nbsp;in&nbsp;initialization,&nbsp;and&nbsp;the&nbsp;location&nbsp;of&nbsp;the&nbsp;detected<br>
-&nbsp;&nbsp;screen&nbsp;corners&nbsp;in&nbsp;the&nbsp;current&nbsp;frame,&nbsp;if&nbsp;a&nbsp;screen&nbsp;is&nbsp;found.&nbsp;The&nbsp;returned<br>
-&nbsp;&nbsp;screen&nbsp;is&nbsp;guaranteed&nbsp;to&nbsp;be&nbsp;the&nbsp;same&nbsp;size&nbsp;at&nbsp;each&nbsp;frame.<br>
-&nbsp;&nbsp;'None'&nbsp;and&nbsp;'None'&nbsp;if&nbsp;no&nbsp;screen&nbsp;was&nbsp;found&nbsp;on&nbsp;the&nbsp;current&nbsp;frame.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;FrameReadError:&nbsp;An&nbsp;error&nbsp;occurred&nbsp;in&nbsp;the&nbsp;FrameGenerator.<br>
-&nbsp;&nbsp;RuntimeError:&nbsp;This&nbsp;method&nbsp;was&nbsp;called&nbsp;when&nbsp;no&nbsp;frames&nbsp;were&nbsp;available.</tt></dd></dl>
-
-<dl><dt><a name="ScreenFinder-HasNext"><strong>HasNext</strong></a>(self)</dt><dd><tt>True&nbsp;if&nbsp;there&nbsp;are&nbsp;more&nbsp;frames&nbsp;available&nbsp;to&nbsp;process.</tt></dd></dl>
-
-<dl><dt><a name="ScreenFinder-__init__"><strong>__init__</strong></a>(self, frame_generator, border<font color="#909090">=5</font>)</dt><dd><tt>Initializes&nbsp;the&nbsp;<a href="#ScreenFinder">ScreenFinder</a>&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;frame_generator:&nbsp;FrameGenerator,&nbsp;An&nbsp;initialized&nbsp;Video&nbsp;Frame&nbsp;Generator.<br>
-&nbsp;&nbsp;border:&nbsp;int,&nbsp;number&nbsp;of&nbsp;pixels&nbsp;of&nbsp;border&nbsp;to&nbsp;be&nbsp;kept&nbsp;when&nbsp;cropping&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detected&nbsp;screen.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;FrameReadError:&nbsp;The&nbsp;frame&nbsp;generator&nbsp;may&nbsp;output&nbsp;a&nbsp;read&nbsp;error&nbsp;during<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;initialization.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>CANNY_HYSTERESIS_THRESH_HIGH</strong> = 500</dl>
-
-<dl><dt><strong>CANNY_HYSTERESIS_THRESH_LOW</strong> = 300</dl>
-
-<dl><dt><strong>CORNER_AVERAGE_WEIGHT</strong> = 0.5</dl>
-
-<dl><dt><strong>CornerData</strong> = &lt;class 'telemetry.internal.image_processing.screen_finder.CornerData'&gt;</dl>
-
-<dl><dt><strong>DEBUG</strong> = False</dl>
-
-<dl><dt><strong>MAX_INTERFRAME_MOTION</strong> = 25</dl>
-
-<dl><dt><strong>MIN_CORNER_ABSOLUTE_BRIGHTNESS</strong> = 60</dl>
-
-<dl><dt><strong>MIN_RELATIVE_BRIGHTNESS_FACTOR</strong> = 1.5</dl>
-
-<dl><dt><strong>MIN_SCREEN_WIDTH</strong> = 40</dl>
-
-<dl><dt><strong>RESET_AFTER_N_BAD_FRAMES</strong> = 2</dl>
-
-<dl><dt><strong>SMALL_ANGLE</strong> = 0.08726646259971647</dl>
-
-<dl><dt><strong>ScreenNotFoundError</strong> = &lt;class 'telemetry.internal.image_processing.screen_finder.ScreenNotFoundError'&gt;</dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-main"><strong>main</strong></a>()</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>division</strong> = _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.video.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.video.html
deleted file mode 100644
index 03367f9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.video.html
+++ /dev/null
@@ -1,152 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.video</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.video</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/video.py">telemetry/internal/image_processing/video.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="telemetry.util.image_util.html">telemetry.util.image_util</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.util.rgba_color.html">telemetry.util.rgba_color</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.video.html#Video">Video</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.video.html#BoundingBoxNotFoundException">BoundingBoxNotFoundException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BoundingBoxNotFoundException">class <strong>BoundingBoxNotFoundException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.image_processing.video.html#BoundingBoxNotFoundException">BoundingBoxNotFoundException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="BoundingBoxNotFoundException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#BoundingBoxNotFoundException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="BoundingBoxNotFoundException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#BoundingBoxNotFoundException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="BoundingBoxNotFoundException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Video">class <strong>Video</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Utilities&nbsp;for&nbsp;storing&nbsp;and&nbsp;interacting&nbsp;with&nbsp;the&nbsp;video&nbsp;capture.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Video-GetVideoFrameIter"><strong>GetVideoFrameIter</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;iteration&nbsp;for&nbsp;processing&nbsp;the&nbsp;video&nbsp;capture.<br>
-&nbsp;<br>
-This&nbsp;looks&nbsp;for&nbsp;the&nbsp;initial&nbsp;color&nbsp;flash&nbsp;in&nbsp;the&nbsp;first&nbsp;frame&nbsp;to&nbsp;establish&nbsp;the<br>
-tab&nbsp;content&nbsp;boundaries&nbsp;and&nbsp;then&nbsp;omits&nbsp;all&nbsp;frames&nbsp;displaying&nbsp;the&nbsp;flash.<br>
-&nbsp;<br>
-Yields:<br>
-&nbsp;&nbsp;(time_ms,&nbsp;image)&nbsp;tuples&nbsp;representing&nbsp;each&nbsp;video&nbsp;keyframe.&nbsp;Only&nbsp;the&nbsp;first<br>
-&nbsp;&nbsp;frame&nbsp;is&nbsp;a&nbsp;run&nbsp;of&nbsp;sequential&nbsp;duplicate&nbsp;bitmaps&nbsp;is&nbsp;typically&nbsp;included.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;time_ms&nbsp;is&nbsp;milliseconds&nbsp;since&nbsp;navigationStart.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;image&nbsp;may&nbsp;be&nbsp;a&nbsp;telemetry.core.Bitmap,&nbsp;or&nbsp;a&nbsp;numpy&nbsp;array&nbsp;depending&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;whether&nbsp;numpy&nbsp;is&nbsp;installed.</tt></dd></dl>
-
-<dl><dt><a name="Video-UploadToCloudStorage"><strong>UploadToCloudStorage</strong></a>(self, bucket, target_path)</dt><dd><tt>Uploads&nbsp;video&nbsp;file&nbsp;to&nbsp;cloud&nbsp;storage.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;target_path:&nbsp;Path&nbsp;indicating&nbsp;where&nbsp;to&nbsp;store&nbsp;the&nbsp;file&nbsp;in&nbsp;cloud&nbsp;storage.</tt></dd></dl>
-
-<dl><dt><a name="Video-__init__"><strong>__init__</strong></a>(self, video_file_obj)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>HIGHLIGHT_ORANGE_FRAME</strong> = RgbaColor(r=222, g=100, b=13, a=255)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.video_file_frame_generator.html b/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.video_file_frame_generator.html
deleted file mode 100644
index 72fbbe5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.image_processing.video_file_frame_generator.html
+++ /dev/null
@@ -1,118 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.image_processing.video_file_frame_generator</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.image_processing.html"><font color="#ffffff">image_processing</font></a>.video_file_frame_generator</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/image_processing/video_file_frame_generator.py">telemetry/internal/image_processing/video_file_frame_generator.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="cv2.html">cv2</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.frame_generator.html">telemetry.internal.image_processing.frame_generator</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.image_processing.video_file_frame_generator.html#VideoFileFrameGenerator">VideoFileFrameGenerator</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="VideoFileFrameGenerator">class <strong>VideoFileFrameGenerator</strong></a>(<a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;a&nbsp;Frame&nbsp;Generator&nbsp;for&nbsp;a&nbsp;video&nbsp;file.<br>
-&nbsp;<br>
-Sample&nbsp;Usage:<br>
-&nbsp;&nbsp;generator&nbsp;=&nbsp;<a href="#VideoFileFrameGenerator">VideoFileFrameGenerator</a>(sys.argv[1]).GetGenerator()<br>
-&nbsp;&nbsp;for&nbsp;frame&nbsp;in&nbsp;generator:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;#&nbsp;Do&nbsp;something<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;_capture:&nbsp;The&nbsp;openCV&nbsp;video&nbsp;capture.<br>
-&nbsp;&nbsp;_frame_count:&nbsp;The&nbsp;number&nbsp;of&nbsp;frames&nbsp;in&nbsp;the&nbsp;video&nbsp;capture.<br>
-&nbsp;&nbsp;_frame_index:&nbsp;The&nbsp;frame&nbsp;number&nbsp;of&nbsp;the&nbsp;current&nbsp;frame.<br>
-&nbsp;&nbsp;_timestamp:&nbsp;The&nbsp;timestamp&nbsp;of&nbsp;the&nbsp;current&nbsp;frame.<br>
-&nbsp;&nbsp;_dimensions:&nbsp;The&nbsp;dimensions&nbsp;of&nbsp;the&nbsp;video&nbsp;capture.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.image_processing.video_file_frame_generator.html#VideoFileFrameGenerator">VideoFileFrameGenerator</a></dd>
-<dd><a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="VideoFileFrameGenerator-__init__"><strong>__init__</strong></a>(self, video_filename, start_frame_index<font color="#909090">=0</font>)</dt><dd><tt>Initializes&nbsp;the&nbsp;<a href="#VideoFileFrameGenerator">VideoFileFrameGenerator</a>&nbsp;object.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;video_filename:&nbsp;str,&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;video&nbsp;file.<br>
-&nbsp;&nbsp;start_frame_index:&nbsp;int,&nbsp;The&nbsp;number&nbsp;of&nbsp;frames&nbsp;to&nbsp;skip&nbsp;at&nbsp;the&nbsp;start&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;FrameReadError:&nbsp;A&nbsp;read&nbsp;error&nbsp;occurred&nbsp;during&nbsp;initialization.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>CurrentFrameNumber</strong></dt>
-</dl>
-<dl><dt><strong>CurrentTimestamp</strong></dt>
-</dl>
-<dl><dt><strong>Dimensions</strong></dt>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>:<br>
-<dl><dt><strong>Generator</strong></dt>
-<dd><tt>Returns:<br>
-A&nbsp;reference&nbsp;to&nbsp;the&nbsp;created&nbsp;generator.</tt></dd>
-</dl>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="telemetry.internal.image_processing.frame_generator.html#FrameGenerator">telemetry.internal.image_processing.frame_generator.FrameGenerator</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.android_device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.android_device.html
deleted file mode 100644
index 8a13a01..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.android_device.html
+++ /dev/null
@@ -1,111 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.android_device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.android_device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/android_device.py">telemetry/internal/platform/android_device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="pylib.constants.html">pylib.constants</a><br>
-<a href="telemetry.internal.platform.device.html">telemetry.internal.platform.device</a><br>
-<a href="devil.android.device_blacklist.html">devil.android.device_blacklist</a><br>
-</td><td width="25%" valign=top><a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-<a href="devil.android.device_utils.html">devil.android.device_utils</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.monsoon.html">telemetry.internal.platform.profiler.monsoon</a><br>
-<a href="os.html">os</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.android_device.html#AndroidDevice">AndroidDevice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidDevice">class <strong>AndroidDevice</strong></a>(<a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Class&nbsp;represents&nbsp;information&nbsp;for&nbsp;connecting&nbsp;to&nbsp;an&nbsp;android&nbsp;device.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;device_id:&nbsp;the&nbsp;device's&nbsp;serial&nbsp;string&nbsp;created&nbsp;by&nbsp;adb&nbsp;to&nbsp;uniquely<br>
-&nbsp;&nbsp;&nbsp;&nbsp;identify&nbsp;an&nbsp;emulator/device&nbsp;instance.&nbsp;This&nbsp;string&nbsp;can&nbsp;be&nbsp;found&nbsp;by&nbsp;running<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'adb&nbsp;devices'&nbsp;command<br>
-&nbsp;&nbsp;enable_performance_mode:&nbsp;when&nbsp;this&nbsp;is&nbsp;set&nbsp;to&nbsp;True,&nbsp;android&nbsp;platform&nbsp;will&nbsp;be<br>
-&nbsp;&nbsp;set&nbsp;to&nbsp;high&nbsp;performance&nbsp;mode&nbsp;after&nbsp;browser&nbsp;is&nbsp;started.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.android_device.html#AndroidDevice">AndroidDevice</a></dd>
-<dd><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidDevice-__init__"><strong>__init__</strong></a>(self, device_id, enable_performance_mode<font color="#909090">=True</font>)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="AndroidDevice-GetAllConnectedDevices"><strong>GetAllConnectedDevices</strong></a>(cls, blacklist)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>device_id</strong></dt>
-</dl>
-<dl><dt><strong>enable_performance_mode</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>guid</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CanDiscoverDevices"><strong>CanDiscoverDevices</strong></a>()</dt><dd><tt>Returns&nbsp;true&nbsp;if&nbsp;devices&nbsp;are&nbsp;discoverable&nbsp;via&nbsp;adb.</tt></dd></dl>
- <dl><dt><a name="-FindAllAvailableDevices"><strong>FindAllAvailableDevices</strong></a>(options)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;devices.</tt></dd></dl>
- <dl><dt><a name="-GetDevice"><strong>GetDevice</strong></a>(finder_options)</dt><dd><tt>Return&nbsp;a&nbsp;Platform&nbsp;instance&nbsp;for&nbsp;the&nbsp;device&nbsp;specified&nbsp;by&nbsp;|finder_options|.</tt></dd></dl>
- <dl><dt><a name="-GetDeviceSerials"><strong>GetDeviceSerials</strong></a>(blacklist)</dt><dd><tt>Return&nbsp;the&nbsp;list&nbsp;of&nbsp;device&nbsp;serials&nbsp;of&nbsp;healthy&nbsp;devices.<br>
-&nbsp;<br>
-If&nbsp;a&nbsp;preferred&nbsp;device&nbsp;has&nbsp;been&nbsp;set&nbsp;with&nbsp;ANDROID_SERIAL,&nbsp;it&nbsp;will&nbsp;be&nbsp;first&nbsp;in<br>
-the&nbsp;returned&nbsp;list.&nbsp;The&nbsp;arguments&nbsp;specify&nbsp;what&nbsp;devices&nbsp;to&nbsp;include&nbsp;in&nbsp;the&nbsp;list.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.android_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.android_platform_backend.html
deleted file mode 100644
index 5c3c211..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.android_platform_backend.html
+++ /dev/null
@@ -1,381 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.android_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.android_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/android_platform_backend.py">telemetry/internal/platform/android_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="adb_install_cert.html">adb_install_cert</a><br>
-<a href="telemetry.internal.platform.android_device.html">telemetry.internal.platform.android_device</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html">telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor</a><br>
-<a href="telemetry.internal.forwarders.android_forwarder.html">telemetry.internal.forwarders.android_forwarder</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html">telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor</a><br>
-<a href="telemetry.core.android_platform.html">telemetry.core.android_platform</a><br>
-<a href="telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html">telemetry.internal.platform.profiler.android_prebuilt_profiler_helper</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_temperature_monitor.html">telemetry.internal.platform.power_monitor.android_temperature_monitor</a><br>
-<a href="devil.android.battery_utils.html">devil.android.battery_utils</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-</td><td width="25%" valign=top><a href="devil.android.perf.cache_control.html">devil.android.perf.cache_control</a><br>
-<a href="certutils.html">certutils</a><br>
-<a href="pylib.constants.html">pylib.constants</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-<a href="devil.android.device_utils.html">devil.android.device_utils</a><br>
-<a href="telemetry.internal.util.exception_formatter.html">telemetry.internal.util.exception_formatter</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-<a href="telemetry.internal.platform.linux_based_platform_backend.html">telemetry.internal.platform.linux_based_platform_backend</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.internal.platform.power_monitor.monsoon_power_monitor.html">telemetry.internal.platform.power_monitor.monsoon_power_monitor</a><br>
-<a href="os.html">os</a><br>
-<a href="devil.android.perf.perf_control.html">devil.android.perf.perf_control</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="platformsettings.html">platformsettings</a><br>
-<a href="telemetry.internal.platform.power_monitor.power_monitor_controller.html">telemetry.internal.platform.power_monitor.power_monitor_controller</a><br>
-<a href="psutil.html">psutil</a><br>
-<a href="re.html">re</a><br>
-<a href="pylib.screenshot.html">pylib.screenshot</a><br>
-</td><td width="25%" valign=top><a href="shutil.html">shutil</a><br>
-<a href="stat.html">stat</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="devil.android.perf.surface_stats_collector.html">devil.android.perf.surface_stats_collector</a><br>
-<a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html">telemetry.internal.platform.power_monitor.sysfs_power_monitor</a><br>
-<a href="tempfile.html">tempfile</a><br>
-<a href="devil.android.perf.thermal_throttle.html">devil.android.perf.thermal_throttle</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="devil.android.sdk.version_codes.html">devil.android.sdk.version_codes</a><br>
-<a href="telemetry.internal.image_processing.video.html">telemetry.internal.image_processing.video</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.android_platform_backend.html#AndroidPlatformBackend">AndroidPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidPlatformBackend">class <strong>AndroidPlatformBackend</strong></a>(<a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.android_platform_backend.html#AndroidPlatformBackend">AndroidPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-DismissCrashDialogIfNeeded"><strong>DismissCrashDialogIfNeeded</strong></a>(self)</dt><dd><tt>Dismiss&nbsp;any&nbsp;error&nbsp;dialogs.<br>
-&nbsp;<br>
-Limit&nbsp;the&nbsp;number&nbsp;in&nbsp;case&nbsp;we&nbsp;have&nbsp;an&nbsp;error&nbsp;loop&nbsp;or&nbsp;we&nbsp;are&nbsp;failing&nbsp;to&nbsp;dismiss.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-ForwardHostToDevice"><strong>ForwardHostToDevice</strong></a>(self, host_port, device_port)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, fname)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetStackTrace"><strong>GetStackTrace</strong></a>(self, target_arch)</dt><dd><tt>Returns&nbsp;stack&nbsp;trace.<br>
-&nbsp;<br>
-The&nbsp;stack&nbsp;trace&nbsp;consists&nbsp;of&nbsp;raw&nbsp;logcat&nbsp;dump,&nbsp;logcat&nbsp;dump&nbsp;with&nbsp;symbols,<br>
-and&nbsp;stack&nbsp;info&nbsp;from&nbsp;tomstone&nbsp;files.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;target_arch:&nbsp;String&nbsp;specifying&nbsp;device&nbsp;architecture&nbsp;(eg.&nbsp;arm,&nbsp;arm64,&nbsp;mips,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;x86,&nbsp;x86_64)</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetStandardOutput"><strong>GetStandardOutput</strong></a>(self, number_of_lines<font color="#909090">=500</font>)</dt><dd><tt>Returns&nbsp;most&nbsp;recent&nbsp;lines&nbsp;of&nbsp;logcat&nbsp;dump.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;number_of_lines:&nbsp;Number&nbsp;of&nbsp;lines&nbsp;of&nbsp;log&nbsp;to&nbsp;return.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-InstallTestCa"><strong>InstallTestCa</strong></a>(self)</dt><dd><tt>Install&nbsp;a&nbsp;randomly&nbsp;generated&nbsp;root&nbsp;CA&nbsp;on&nbsp;the&nbsp;android&nbsp;device.<br>
-&nbsp;<br>
-This&nbsp;allows&nbsp;transparent&nbsp;HTTPS&nbsp;testing&nbsp;with&nbsp;WPR&nbsp;server&nbsp;without&nbsp;need<br>
-to&nbsp;tweak&nbsp;application&nbsp;network&nbsp;stack.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsAppRunning"><strong>IsAppRunning</strong></a>(self, process_name)</dt><dd><tt>Determine&nbsp;if&nbsp;the&nbsp;given&nbsp;process&nbsp;is&nbsp;running.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;process_name:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;process.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsScreenLocked"><strong>IsScreenLocked</strong></a>(self)</dt><dd><tt>Determines&nbsp;if&nbsp;device&nbsp;screen&nbsp;is&nbsp;locked.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsScreenOn"><strong>IsScreenOn</strong></a>(self)</dt><dd><tt>Determines&nbsp;if&nbsp;device&nbsp;screen&nbsp;is&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-KillApplication"><strong>KillApplication</strong></a>(self, application)</dt><dd><tt>Kill&nbsp;the&nbsp;given&nbsp;|application|.<br>
-&nbsp;<br>
-Might&nbsp;be&nbsp;used&nbsp;instead&nbsp;of&nbsp;ForceStop&nbsp;for&nbsp;efficiency&nbsp;reasons.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;application:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application&nbsp;to&nbsp;kill.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt><dd><tt>Launches&nbsp;the&nbsp;given&nbsp;|application|&nbsp;with&nbsp;a&nbsp;list&nbsp;of&nbsp;|parameters|&nbsp;on&nbsp;the&nbsp;OS.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;application:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application&nbsp;to&nbsp;launch.<br>
-&nbsp;&nbsp;parameters:&nbsp;A&nbsp;list&nbsp;of&nbsp;parameters&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;ActivityManager.<br>
-&nbsp;&nbsp;elevate_privilege:&nbsp;Currently&nbsp;unimplemented&nbsp;on&nbsp;Android.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, device_path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Return&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;device.<br>
-This&nbsp;method&nbsp;is&nbsp;the&nbsp;same&nbsp;as<br>
-devil.android.device_utils.DeviceUtils.PathExists.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-PullProfile"><strong>PullProfile</strong></a>(self, package, output_profile_path)</dt><dd><tt>Copy&nbsp;application&nbsp;profile&nbsp;from&nbsp;device&nbsp;to&nbsp;host&nbsp;machine.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;package:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application&nbsp;for&nbsp;which&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;profile&nbsp;is&nbsp;to&nbsp;be&nbsp;copied.<br>
-&nbsp;&nbsp;output_profile_dir:&nbsp;Location&nbsp;where&nbsp;profile&nbsp;to&nbsp;be&nbsp;stored&nbsp;on&nbsp;host&nbsp;machine.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt><dd><tt>Purges&nbsp;the&nbsp;unpinned&nbsp;ashmem&nbsp;memory&nbsp;for&nbsp;the&nbsp;whole&nbsp;system.<br>
-&nbsp;<br>
-This&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;make&nbsp;memory&nbsp;measurements&nbsp;more&nbsp;stable.&nbsp;Requires&nbsp;root.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-PushProfile"><strong>PushProfile</strong></a>(self, package, new_profile_dir)</dt><dd><tt>Replace&nbsp;application&nbsp;profile&nbsp;with&nbsp;files&nbsp;found&nbsp;on&nbsp;host&nbsp;machine.<br>
-&nbsp;<br>
-Pushing&nbsp;the&nbsp;profile&nbsp;is&nbsp;slow,&nbsp;so&nbsp;we&nbsp;don't&nbsp;want&nbsp;to&nbsp;do&nbsp;it&nbsp;every&nbsp;time.<br>
-Avoid&nbsp;this&nbsp;by&nbsp;pushing&nbsp;to&nbsp;a&nbsp;safe&nbsp;location&nbsp;using&nbsp;PushChangedFiles,&nbsp;and<br>
-then&nbsp;copying&nbsp;into&nbsp;the&nbsp;correct&nbsp;location&nbsp;on&nbsp;each&nbsp;test&nbsp;run.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;package:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application&nbsp;for&nbsp;which&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;profile&nbsp;is&nbsp;to&nbsp;be&nbsp;updated.<br>
-&nbsp;&nbsp;new_profile_dir:&nbsp;Location&nbsp;where&nbsp;profile&nbsp;to&nbsp;be&nbsp;pushed&nbsp;is&nbsp;stored&nbsp;on&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;host&nbsp;machine.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-RemoveProfile"><strong>RemoveProfile</strong></a>(self, package, ignore_list)</dt><dd><tt>Delete&nbsp;application&nbsp;profile&nbsp;on&nbsp;device.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;package:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application&nbsp;for&nbsp;which&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;profile&nbsp;is&nbsp;to&nbsp;be&nbsp;deleted.<br>
-&nbsp;&nbsp;ignore_list:&nbsp;List&nbsp;of&nbsp;files&nbsp;to&nbsp;keep.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-RemoveTestCa"><strong>RemoveTestCa</strong></a>(self)</dt><dd><tt>Remove&nbsp;root&nbsp;CA&nbsp;generated&nbsp;by&nbsp;previous&nbsp;call&nbsp;to&nbsp;<a href="#AndroidPlatformBackend-InstallTestCa">InstallTestCa</a>().<br>
-&nbsp;<br>
-Removes&nbsp;the&nbsp;test&nbsp;root&nbsp;certificate&nbsp;from&nbsp;both&nbsp;the&nbsp;device&nbsp;and&nbsp;host&nbsp;machine.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, command)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-SetDebugApp"><strong>SetDebugApp</strong></a>(self, package)</dt><dd><tt>Set&nbsp;application&nbsp;to&nbsp;debugging.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;package:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-SetGraphicsMemoryTrackingEnabled"><strong>SetGraphicsMemoryTrackingEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-SetRelaxSslCheck"><strong>SetRelaxSslCheck</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt><dd><tt>Starts&nbsp;the&nbsp;video&nbsp;capture&nbsp;at&nbsp;specified&nbsp;bitrate.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StopApplication"><strong>StopApplication</strong></a>(self, application)</dt><dd><tt>Stop&nbsp;the&nbsp;given&nbsp;|application|.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;application:&nbsp;The&nbsp;full&nbsp;package&nbsp;name&nbsp;string&nbsp;of&nbsp;the&nbsp;application&nbsp;to&nbsp;stop.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StopForwardingHost"><strong>StopForwardingHost</strong></a>(self, host_port)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-__init__"><strong>__init__</strong></a>(self, device, finder_options)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="AndroidPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="AndroidPlatformBackend-ParseCStateSample"><strong>ParseCStateSample</strong></a>(sample)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>device</strong></dt>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_test_ca_installed</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>log_file_path</strong></dt>
-</dl>
-<dl><dt><strong>use_rndis_forwarder</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-<dd><tt>Path&nbsp;to&nbsp;root&nbsp;certificate&nbsp;installed&nbsp;on&nbsp;browser&nbsp;(or&nbsp;None).<br>
-&nbsp;<br>
-If&nbsp;this&nbsp;is&nbsp;set,&nbsp;web&nbsp;page&nbsp;replay&nbsp;will&nbsp;use&nbsp;it&nbsp;to&nbsp;sign&nbsp;HTTPS&nbsp;responses.</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>:<br>
-<dl><dt><a name="AndroidPlatformBackend-GetClockTicks"><strong>GetClockTicks</strong></a>(*args, **kwargs)</dt><dd><tt>Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;clock&nbsp;ticks&nbsp;per&nbsp;second.<br>
-&nbsp;<br>
-The&nbsp;proper&nbsp;way&nbsp;is&nbsp;to&nbsp;call&nbsp;os.sysconf('SC_CLK_TCK')&nbsp;but&nbsp;that&nbsp;is&nbsp;not&nbsp;easy&nbsp;to<br>
-do&nbsp;on&nbsp;Android/CrOS.&nbsp;In&nbsp;practice,&nbsp;nearly&nbsp;all&nbsp;Linux&nbsp;machines&nbsp;have&nbsp;a&nbsp;USER_HZ<br>
-of&nbsp;100,&nbsp;so&nbsp;just&nbsp;return&nbsp;that.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt><dd><tt>#&nbsp;Get&nbsp;the&nbsp;commit&nbsp;charge&nbsp;in&nbsp;kB.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(*args, **kwargs)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="AndroidPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="AndroidPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="AndroidPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;is&nbsp;the&nbsp;platform&nbsp;backend&nbsp;to&nbsp;be&nbsp;used<br>
-for&nbsp;the&nbsp;host&nbsp;device&nbsp;which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.cros_device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.cros_device.html
deleted file mode 100644
index 026a1e3..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.cros_device.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.cros_device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.cros_device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/cros_device.py">telemetry/internal/platform/cros_device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.cros_interface.html">telemetry.core.cros_interface</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.device.html">telemetry.internal.platform.device</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.cros_device.html#CrOSDevice">CrOSDevice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrOSDevice">class <strong>CrOSDevice</strong></a>(<a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.cros_device.html#CrOSDevice">CrOSDevice</a></dd>
-<dd><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrOSDevice-__init__"><strong>__init__</strong></a>(self, host_name, ssh_port, ssh_identity<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="CrOSDevice-GetAllConnectedDevices"><strong>GetAllConnectedDevices</strong></a>(cls, blacklist)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>host_name</strong></dt>
-</dl>
-<dl><dt><strong>ssh_identity</strong></dt>
-</dl>
-<dl><dt><strong>ssh_port</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>guid</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindAllAvailableDevices"><strong>FindAllAvailableDevices</strong></a>(options)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;device&nbsp;types.</tt></dd></dl>
- <dl><dt><a name="-IsRunningOnCrOS"><strong>IsRunningOnCrOS</strong></a>()</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.cros_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.cros_platform_backend.html
deleted file mode 100644
index 926b020..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.cros_platform_backend.html
+++ /dev/null
@@ -1,246 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.cros_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.cros_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/cros_platform_backend.py">telemetry/internal/platform/cros_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.cros_device.html">telemetry.internal.platform.cros_device</a><br>
-<a href="telemetry.internal.forwarders.cros_forwarder.html">telemetry.internal.forwarders.cros_forwarder</a><br>
-<a href="telemetry.core.cros_interface.html">telemetry.core.cros_interface</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.cros_power_monitor.html">telemetry.internal.platform.power_monitor.cros_power_monitor</a><br>
-<a href="telemetry.internal.platform.linux_based_platform_backend.html">telemetry.internal.platform.linux_based_platform_backend</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.util.ps_util.html">telemetry.internal.util.ps_util</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.cros_platform_backend.html#CrosPlatformBackend">CrosPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrosPlatformBackend">class <strong>CrosPlatformBackend</strong></a>(<a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.cros_platform_backend.html#CrosPlatformBackend">CrosPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrosPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;child&nbsp;pids&nbsp;of&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, filename)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-__init__"><strong>__init__</strong></a>(self, device<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="CrosPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="CrosPlatformBackend-ParseCStateSample"><strong>ParseCStateSample</strong></a>(sample)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>cri</strong></dt>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>:<br>
-<dl><dt><a name="CrosPlatformBackend-GetClockTicks"><strong>GetClockTicks</strong></a>(*args, **kwargs)</dt><dd><tt>Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;clock&nbsp;ticks&nbsp;per&nbsp;second.<br>
-&nbsp;<br>
-The&nbsp;proper&nbsp;way&nbsp;is&nbsp;to&nbsp;call&nbsp;os.sysconf('SC_CLK_TCK')&nbsp;but&nbsp;that&nbsp;is&nbsp;not&nbsp;easy&nbsp;to<br>
-do&nbsp;on&nbsp;Android/CrOS.&nbsp;In&nbsp;practice,&nbsp;nearly&nbsp;all&nbsp;Linux&nbsp;machines&nbsp;have&nbsp;a&nbsp;USER_HZ<br>
-of&nbsp;100,&nbsp;so&nbsp;just&nbsp;return&nbsp;that.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt><dd><tt>#&nbsp;Get&nbsp;the&nbsp;commit&nbsp;charge&nbsp;in&nbsp;kB.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(*args, **kwargs)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="CrosPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="CrosPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="CrosPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.desktop_device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.desktop_device.html
deleted file mode 100644
index 8f6cfc8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.desktop_device.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.desktop_device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.desktop_device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/desktop_device.py">telemetry/internal/platform/desktop_device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.device.html">telemetry.internal.platform.device</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.desktop_device.html#DesktopDevice">DesktopDevice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DesktopDevice">class <strong>DesktopDevice</strong></a>(<a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.desktop_device.html#DesktopDevice">DesktopDevice</a></dd>
-<dd><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DesktopDevice-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="DesktopDevice-GetAllConnectedDevices"><strong>GetAllConnectedDevices</strong></a>(cls, blacklist)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>guid</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindAllAvailableDevices"><strong>FindAllAvailableDevices</strong></a>(_)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;devices.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.desktop_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.desktop_platform_backend.html
deleted file mode 100644
index fe3c387..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.desktop_platform_backend.html
+++ /dev/null
@@ -1,233 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.desktop_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.desktop_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/desktop_platform_backend.py">telemetry/internal/platform/desktop_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.platform_backend.html">telemetry.internal.platform.platform_backend</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">DesktopPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DesktopPlatformBackend">class <strong>DesktopPlatformBackend</strong></a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">DesktopPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DesktopPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="DesktopPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-__init__"><strong>__init__</strong></a>(self, device<font color="#909090">=None</font>)</dt><dd><tt>Initalize&nbsp;an&nbsp;instance&nbsp;of&nbsp;<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">PlatformBackend</a>&nbsp;from&nbsp;a&nbsp;device&nbsp;optionally.<br>
-Call&nbsp;sites&nbsp;need&nbsp;to&nbsp;use&nbsp;SupportsDevice&nbsp;before&nbsp;intialization&nbsp;to&nbsp;check<br>
-whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;the&nbsp;device.<br>
-If&nbsp;device&nbsp;is&nbsp;None,&nbsp;this&nbsp;constructor&nbsp;returns&nbsp;the&nbsp;host&nbsp;platform&nbsp;backend<br>
-which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.platform.device.Device.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="DesktopPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;is&nbsp;the&nbsp;platform&nbsp;backend&nbsp;to&nbsp;be&nbsp;used<br>
-for&nbsp;the&nbsp;host&nbsp;device&nbsp;which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="DesktopPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.device.html
deleted file mode 100644
index e8459be..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.device.html
+++ /dev/null
@@ -1,68 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/device.py">telemetry/internal/platform/device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.device.html#Device">Device</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Device">class <strong>Device</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;base&nbsp;class&nbsp;of&nbsp;devices.<br>
-A&nbsp;device&nbsp;instance&nbsp;contains&nbsp;all&nbsp;the&nbsp;necessary&nbsp;information&nbsp;for&nbsp;constructing<br>
-a&nbsp;platform&nbsp;backend&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;for&nbsp;remote&nbsp;platforms.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;name:&nbsp;A&nbsp;device&nbsp;name&nbsp;string&nbsp;in&nbsp;human-understandable&nbsp;term.<br>
-&nbsp;&nbsp;guid:&nbsp;A&nbsp;unique&nbsp;id&nbsp;of&nbsp;the&nbsp;device.&nbsp;Subclass&nbsp;of&nbsp;device&nbsp;must&nbsp;specify&nbsp;this<br>
-&nbsp;&nbsp;&nbsp;&nbsp;id&nbsp;properly&nbsp;so&nbsp;that&nbsp;device&nbsp;objects&nbsp;to&nbsp;a&nbsp;same&nbsp;actual&nbsp;device&nbsp;must&nbsp;have&nbsp;same<br>
-&nbsp;&nbsp;&nbsp;&nbsp;guid.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Device-__init__"><strong>__init__</strong></a>(self, name, guid)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Device-GetAllConnectedDevices"><strong>GetAllConnectedDevices</strong></a>(cls, blacklist)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>guid</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.device_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.device_finder.html
deleted file mode 100644
index 3a37b75..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.device_finder.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.device_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.device_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/device_finder.py">telemetry/internal/platform/device_finder.py</a></font></td></tr></table>
-    <p><tt>Finds&nbsp;devices&nbsp;that&nbsp;can&nbsp;be&nbsp;controlled&nbsp;by&nbsp;telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.android_device.html">telemetry.internal.platform.android_device</a><br>
-<a href="telemetry.internal.platform.cros_device.html">telemetry.internal.platform.cros_device</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.desktop_device.html">telemetry.internal.platform.desktop_device</a><br>
-<a href="telemetry.internal.platform.ios_device.html">telemetry.internal.platform.ios_device</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.trybot_device.html">telemetry.internal.platform.trybot_device</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetDevicesMatchingOptions"><strong>GetDevicesMatchingOptions</strong></a>(options)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;devices&nbsp;matching&nbsp;the&nbsp;options.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEVICES</strong> = [&lt;module 'telemetry.internal.platform.android_dev.../telemetry/internal/platform/android_device.pyc'&gt;, &lt;module 'telemetry.internal.platform.cros_device...try/telemetry/internal/platform/cros_device.pyc'&gt;, &lt;module 'telemetry.internal.platform.desktop_dev.../telemetry/internal/platform/desktop_device.pyc'&gt;, &lt;module 'telemetry.internal.platform.ios_device'...etry/telemetry/internal/platform/ios_device.pyc'&gt;, &lt;module 'telemetry.internal.platform.trybot_devi...y/telemetry/internal/platform/trybot_device.pyc'&gt;]</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.gpu_device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.gpu_device.html
deleted file mode 100644
index 34f3fc9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.gpu_device.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.gpu_device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.gpu_device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/gpu_device.py">telemetry/internal/platform/gpu_device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.gpu_device.html#GPUDevice">GPUDevice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GPUDevice">class <strong>GPUDevice</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;information&nbsp;about&nbsp;an&nbsp;individual&nbsp;GPU&nbsp;device.<br>
-&nbsp;<br>
-On&nbsp;platforms&nbsp;which&nbsp;support&nbsp;them,&nbsp;the&nbsp;vendor_id&nbsp;and&nbsp;device_id&nbsp;are<br>
-PCI&nbsp;IDs.&nbsp;On&nbsp;other&nbsp;platforms,&nbsp;the&nbsp;vendor_string&nbsp;and&nbsp;device_string<br>
-are&nbsp;platform-dependent&nbsp;strings.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="GPUDevice-__init__"><strong>__init__</strong></a>(self, vendor_id, device_id, vendor_string, device_string)</dt></dl>
-
-<dl><dt><a name="GPUDevice-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="GPUDevice-FromDict"><strong>FromDict</strong></a>(cls, attrs)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="#GPUDevice">GPUDevice</a>&nbsp;from&nbsp;a&nbsp;dictionary.&nbsp;Requires&nbsp;the<br>
-following&nbsp;attributes&nbsp;to&nbsp;be&nbsp;present&nbsp;in&nbsp;the&nbsp;dictionary:<br>
-&nbsp;<br>
-&nbsp;&nbsp;vendor_id<br>
-&nbsp;&nbsp;device_id<br>
-&nbsp;&nbsp;vendor_string<br>
-&nbsp;&nbsp;device_string<br>
-&nbsp;<br>
-Raises&nbsp;an&nbsp;exception&nbsp;if&nbsp;any&nbsp;attributes&nbsp;are&nbsp;missing.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>device_id</strong></dt>
-<dd><tt>The&nbsp;GPU&nbsp;device's&nbsp;PCI&nbsp;ID&nbsp;as&nbsp;a&nbsp;number,&nbsp;or&nbsp;0&nbsp;if&nbsp;not&nbsp;available.<br>
-&nbsp;<br>
-Most&nbsp;desktop&nbsp;machines&nbsp;supply&nbsp;this&nbsp;information&nbsp;rather&nbsp;than&nbsp;the<br>
-vendor&nbsp;and&nbsp;device&nbsp;strings.</tt></dd>
-</dl>
-<dl><dt><strong>device_string</strong></dt>
-<dd><tt>The&nbsp;GPU&nbsp;device's&nbsp;name&nbsp;as&nbsp;a&nbsp;string,&nbsp;or&nbsp;the&nbsp;empty&nbsp;string&nbsp;if&nbsp;not<br>
-available.<br>
-&nbsp;<br>
-Most&nbsp;mobile&nbsp;devices&nbsp;supply&nbsp;this&nbsp;information&nbsp;rather&nbsp;than&nbsp;the&nbsp;PCI<br>
-IDs.</tt></dd>
-</dl>
-<dl><dt><strong>vendor_id</strong></dt>
-<dd><tt>The&nbsp;GPU&nbsp;vendor's&nbsp;PCI&nbsp;ID&nbsp;as&nbsp;a&nbsp;number,&nbsp;or&nbsp;0&nbsp;if&nbsp;not&nbsp;available.<br>
-&nbsp;<br>
-Most&nbsp;desktop&nbsp;machines&nbsp;supply&nbsp;this&nbsp;information&nbsp;rather&nbsp;than&nbsp;the<br>
-vendor&nbsp;and&nbsp;device&nbsp;strings.</tt></dd>
-</dl>
-<dl><dt><strong>vendor_string</strong></dt>
-<dd><tt>The&nbsp;GPU&nbsp;vendor's&nbsp;name&nbsp;as&nbsp;a&nbsp;string,&nbsp;or&nbsp;the&nbsp;empty&nbsp;string&nbsp;if&nbsp;not<br>
-available.<br>
-&nbsp;<br>
-Most&nbsp;mobile&nbsp;devices&nbsp;supply&nbsp;this&nbsp;information&nbsp;rather&nbsp;than&nbsp;the&nbsp;PCI<br>
-IDs.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.gpu_info.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.gpu_info.html
deleted file mode 100644
index 45b8d04..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.gpu_info.html
+++ /dev/null
@@ -1,93 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.gpu_info</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.gpu_info</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/gpu_info.py">telemetry/internal/platform/gpu_info.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.gpu_device.html">telemetry.internal.platform.gpu_device</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.gpu_info.html#GPUInfo">GPUInfo</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GPUInfo">class <strong>GPUInfo</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;information&nbsp;about&nbsp;the&nbsp;GPUs&nbsp;on&nbsp;the&nbsp;system.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="GPUInfo-__init__"><strong>__init__</strong></a>(self, device_array, aux_attributes, feature_status, driver_bug_workarounds)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="GPUInfo-FromDict"><strong>FromDict</strong></a>(cls, attrs)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="#GPUInfo">GPUInfo</a>&nbsp;from&nbsp;a&nbsp;dictionary&nbsp;of&nbsp;attributes.<br>
-&nbsp;<br>
-Attributes&nbsp;currently&nbsp;required&nbsp;to&nbsp;be&nbsp;present&nbsp;in&nbsp;the&nbsp;dictionary:<br>
-&nbsp;&nbsp;devices&nbsp;(array&nbsp;of&nbsp;dictionaries,&nbsp;each&nbsp;of&nbsp;which&nbsp;contains<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GPUDevice's&nbsp;required&nbsp;attributes)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>aux_attributes</strong></dt>
-<dd><tt>Returns&nbsp;a&nbsp;dictionary&nbsp;of&nbsp;auxiliary,&nbsp;optional,&nbsp;attributes.<br>
-&nbsp;<br>
-On&nbsp;the&nbsp;Chrome&nbsp;browser,&nbsp;for&nbsp;example,&nbsp;this&nbsp;dictionary&nbsp;contains:<br>
-&nbsp;&nbsp;optimus&nbsp;(boolean)<br>
-&nbsp;&nbsp;amd_switchable&nbsp;(boolean)<br>
-&nbsp;&nbsp;lenovo_dcute&nbsp;(boolean)<br>
-&nbsp;&nbsp;driver_vendor&nbsp;(string)<br>
-&nbsp;&nbsp;driver_version&nbsp;(string)<br>
-&nbsp;&nbsp;driver_date&nbsp;(string)<br>
-&nbsp;&nbsp;gl_version_string&nbsp;(string)<br>
-&nbsp;&nbsp;gl_vendor&nbsp;(string)<br>
-&nbsp;&nbsp;gl_renderer&nbsp;(string)<br>
-&nbsp;&nbsp;gl_extensions&nbsp;(string)<br>
-&nbsp;&nbsp;display_link_version&nbsp;(string)</tt></dd>
-</dl>
-<dl><dt><strong>devices</strong></dt>
-<dd><tt>An&nbsp;array&nbsp;of&nbsp;GPUDevices.&nbsp;Element&nbsp;0&nbsp;is&nbsp;the&nbsp;primary&nbsp;GPU&nbsp;on&nbsp;the&nbsp;system.</tt></dd>
-</dl>
-<dl><dt><strong>driver_bug_workarounds</strong></dt>
-<dd><tt>Returns&nbsp;an&nbsp;optional&nbsp;array&nbsp;of&nbsp;driver&nbsp;bug&nbsp;workarounds.</tt></dd>
-</dl>
-<dl><dt><strong>feature_status</strong></dt>
-<dd><tt>Returns&nbsp;an&nbsp;optional&nbsp;dictionary&nbsp;of&nbsp;graphics&nbsp;features&nbsp;and&nbsp;their&nbsp;status.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.html
deleted file mode 100644
index 2e717fd..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.html
+++ /dev/null
@@ -1,63 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.platform</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.platform</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/__init__.py">telemetry/internal/platform/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.android_device.html">android_device</a><br>
-<a href="telemetry.internal.platform.android_device_unittest.html">android_device_unittest</a><br>
-<a href="telemetry.internal.platform.android_platform_backend.html">android_platform_backend</a><br>
-<a href="telemetry.internal.platform.android_platform_backend_unittest.html">android_platform_backend_unittest</a><br>
-<a href="telemetry.internal.platform.cros_device.html">cros_device</a><br>
-<a href="telemetry.internal.platform.cros_platform_backend.html">cros_platform_backend</a><br>
-<a href="telemetry.internal.platform.cros_platform_backend_unittest.html">cros_platform_backend_unittest</a><br>
-<a href="telemetry.internal.platform.desktop_device.html">desktop_device</a><br>
-<a href="telemetry.internal.platform.desktop_platform_backend.html">desktop_platform_backend</a><br>
-<a href="telemetry.internal.platform.device.html">device</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.device_finder.html">device_finder</a><br>
-<a href="telemetry.internal.platform.gpu_device.html">gpu_device</a><br>
-<a href="telemetry.internal.platform.gpu_device_unittest.html">gpu_device_unittest</a><br>
-<a href="telemetry.internal.platform.gpu_info.html">gpu_info</a><br>
-<a href="telemetry.internal.platform.gpu_info_unittest.html">gpu_info_unittest</a><br>
-<a href="telemetry.internal.platform.ios_device.html">ios_device</a><br>
-<a href="telemetry.internal.platform.ios_platform_backend.html">ios_platform_backend</a><br>
-<a href="telemetry.internal.platform.linux_based_platform_backend.html">linux_based_platform_backend</a><br>
-<a href="telemetry.internal.platform.linux_based_platform_backend_unittest.html">linux_based_platform_backend_unittest</a><br>
-<a href="telemetry.internal.platform.linux_platform_backend.html">linux_platform_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.linux_platform_backend_unittest.html">linux_platform_backend_unittest</a><br>
-<a href="telemetry.internal.platform.mac_platform_backend.html">mac_platform_backend</a><br>
-<a href="telemetry.internal.platform.mac_platform_backend_unittest.html">mac_platform_backend_unittest</a><br>
-<a href="telemetry.internal.platform.msr_server_win.html">msr_server_win</a><br>
-<a href="telemetry.internal.platform.network_controller_backend.html">network_controller_backend</a><br>
-<a href="telemetry.internal.platform.network_controller_backend_unittest.html">network_controller_backend_unittest</a><br>
-<a href="telemetry.internal.platform.platform_backend.html">platform_backend</a><br>
-<a href="telemetry.internal.platform.platform_backend_unittest.html">platform_backend_unittest</a><br>
-<a href="telemetry.internal.platform.posix_platform_backend.html">posix_platform_backend</a><br>
-<a href="telemetry.internal.platform.posix_platform_backend_unittest.html">posix_platform_backend_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html"><strong>power_monitor</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.platform.profiler.html"><strong>profiler</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.platform.profiling_controller_backend.html">profiling_controller_backend</a><br>
-<a href="telemetry.internal.platform.system_info.html">system_info</a><br>
-<a href="telemetry.internal.platform.system_info_unittest.html">system_info_unittest</a><br>
-<a href="telemetry.internal.platform.tracing_agent.html"><strong>tracing_agent</strong>&nbsp;(package)</a><br>
-<a href="telemetry.internal.platform.tracing_controller_backend.html">tracing_controller_backend</a><br>
-<a href="telemetry.internal.platform.trybot_device.html">trybot_device</a><br>
-<a href="telemetry.internal.platform.win_platform_backend.html">win_platform_backend</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.ios_device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.ios_device.html
deleted file mode 100644
index 679e5e8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.ios_device.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.ios_device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.ios_device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/ios_device.py">telemetry/internal/platform/ios_device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.device.html">telemetry.internal.platform.device</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.ios_device.html#IOSDevice">IOSDevice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IOSDevice">class <strong>IOSDevice</strong></a>(<a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.ios_device.html#IOSDevice">IOSDevice</a></dd>
-<dd><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="IOSDevice-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="IOSDevice-GetAllConnectedDevices"><strong>GetAllConnectedDevices</strong></a>(cls, blacklist)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>guid</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindAllAvailableDevices"><strong>FindAllAvailableDevices</strong></a>(options)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;devices.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>IOSSIM_BUILD_DIRECTORIES</strong> = ['Debug-iphonesimulator', 'Profile-iphonesimulator', 'Release-iphonesimulator']</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.ios_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.ios_platform_backend.html
deleted file mode 100644
index 41566e8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.ios_platform_backend.html
+++ /dev/null
@@ -1,244 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.ios_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.ios_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/ios_platform_backend.py">telemetry/internal/platform/ios_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.posix_platform_backend.html">telemetry.internal.platform.posix_platform_backend</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>(<a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.ios_platform_backend.html#IosPlatformBackend">IosPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IosPlatformBackend">class <strong>IosPlatformBackend</strong></a>(<a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#TODO(baxley):&nbsp;Put&nbsp;in&nbsp;real&nbsp;values.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.ios_platform_backend.html#IosPlatformBackend">IosPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="IosPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>:<br>
-<dl><dt><a name="IosPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;child&nbsp;pids&nbsp;of&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt><dd><tt>Returns&nbsp;output&nbsp;of&nbsp;the&nbsp;'ps'&nbsp;command&nbsp;as&nbsp;a&nbsp;list&nbsp;of&nbsp;lines.<br>
-Subclass&nbsp;should&nbsp;override&nbsp;this&nbsp;function.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;columns:&nbsp;A&nbsp;list&nbsp;of&nbsp;require&nbsp;columns,&nbsp;e.g.,&nbsp;['pid',&nbsp;'pss'].<br>
-&nbsp;&nbsp;pid:&nbsp;If&nbsp;not&nbsp;None,&nbsp;returns&nbsp;only&nbsp;the&nbsp;information&nbsp;of&nbsp;the&nbsp;process<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;the&nbsp;pid.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, args)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>:<br>
-<dl><dt><a name="IosPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="IosPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="IosPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="IosPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;is&nbsp;the&nbsp;platform&nbsp;backend&nbsp;to&nbsp;be&nbsp;used<br>
-for&nbsp;the&nbsp;host&nbsp;device&nbsp;which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="IosPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.linux_based_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.linux_based_platform_backend.html
deleted file mode 100644
index bba8356..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.linux_based_platform_backend.html
+++ /dev/null
@@ -1,278 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.linux_based_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.linux_based_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/linux_based_platform_backend.py">telemetry/internal/platform/linux_based_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.platform_backend.html">telemetry.internal.platform.platform_backend</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="resource.html">resource</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">LinuxBasedPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LinuxBasedPlatformBackend">class <strong>LinuxBasedPlatformBackend</strong></a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Abstract&nbsp;platform&nbsp;containing&nbsp;functionality&nbsp;shared&nbsp;by&nbsp;all&nbsp;Linux&nbsp;based&nbsp;OSes.<br>
-&nbsp;<br>
-This&nbsp;includes&nbsp;Android&nbsp;and&nbsp;ChromeOS.<br>
-&nbsp;<br>
-Subclasses&nbsp;must&nbsp;implement&nbsp;RunCommand,&nbsp;GetFileContents,&nbsp;GetPsOutput,&nbsp;and<br>
-ParseCStateSample.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">LinuxBasedPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="LinuxBasedPlatformBackend-GetClockTicks"><strong>GetClockTicks</strong></a>(*args, **kwargs)</dt><dd><tt>Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;clock&nbsp;ticks&nbsp;per&nbsp;second.<br>
-&nbsp;<br>
-The&nbsp;proper&nbsp;way&nbsp;is&nbsp;to&nbsp;call&nbsp;os.sysconf('SC_CLK_TCK')&nbsp;but&nbsp;that&nbsp;is&nbsp;not&nbsp;easy&nbsp;to<br>
-do&nbsp;on&nbsp;Android/CrOS.&nbsp;In&nbsp;practice,&nbsp;nearly&nbsp;all&nbsp;Linux&nbsp;machines&nbsp;have&nbsp;a&nbsp;USER_HZ<br>
-of&nbsp;100,&nbsp;so&nbsp;just&nbsp;return&nbsp;that.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, filename)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt><dd><tt>#&nbsp;Get&nbsp;the&nbsp;commit&nbsp;charge&nbsp;in&nbsp;kB.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, cmd)</dt><dd><tt>Runs&nbsp;the&nbsp;specified&nbsp;command.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;cmd:&nbsp;A&nbsp;list&nbsp;of&nbsp;program&nbsp;arguments&nbsp;or&nbsp;the&nbsp;path&nbsp;string&nbsp;of&nbsp;the&nbsp;program.<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;string&nbsp;whose&nbsp;content&nbsp;is&nbsp;the&nbsp;output&nbsp;of&nbsp;the&nbsp;command.</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="LinuxBasedPlatformBackend-ParseCStateSample"><strong>ParseCStateSample</strong></a>(sample)</dt><dd><tt>Parse&nbsp;a&nbsp;single&nbsp;c-state&nbsp;residency&nbsp;sample.<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sample:&nbsp;A&nbsp;sample&nbsp;of&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;to&nbsp;be&nbsp;parsed.&nbsp;Organized&nbsp;as<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;CPU&nbsp;name&nbsp;to&nbsp;a&nbsp;string&nbsp;containing&nbsp;all&nbsp;c-state<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;names,&nbsp;the&nbsp;times&nbsp;in&nbsp;each&nbsp;state,&nbsp;the&nbsp;latency&nbsp;of&nbsp;each&nbsp;state,&nbsp;and&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time&nbsp;at&nbsp;which&nbsp;the&nbsp;sample&nbsp;was&nbsp;taken&nbsp;all&nbsp;separated&nbsp;by&nbsp;newlines.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ex:&nbsp;{'cpu0':&nbsp;'C0<br>
-C1<br>
-5000<br>
-2000<br>
-20<br>
-30<br>
-1406673171'}<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;associating&nbsp;a&nbsp;c-state&nbsp;with&nbsp;a&nbsp;time.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="LinuxBasedPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-__init__"><strong>__init__</strong></a>(self, device<font color="#909090">=None</font>)</dt><dd><tt>Initalize&nbsp;an&nbsp;instance&nbsp;of&nbsp;<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">PlatformBackend</a>&nbsp;from&nbsp;a&nbsp;device&nbsp;optionally.<br>
-Call&nbsp;sites&nbsp;need&nbsp;to&nbsp;use&nbsp;SupportsDevice&nbsp;before&nbsp;intialization&nbsp;to&nbsp;check<br>
-whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;the&nbsp;device.<br>
-If&nbsp;device&nbsp;is&nbsp;None,&nbsp;this&nbsp;constructor&nbsp;returns&nbsp;the&nbsp;host&nbsp;platform&nbsp;backend<br>
-which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.platform.device.Device.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="LinuxBasedPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;is&nbsp;the&nbsp;platform&nbsp;backend&nbsp;to&nbsp;be&nbsp;used<br>
-for&nbsp;the&nbsp;host&nbsp;device&nbsp;which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="LinuxBasedPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.linux_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.linux_platform_backend.html
deleted file mode 100644
index 9539096..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.linux_platform_backend.html
+++ /dev/null
@@ -1,280 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.linux_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.linux_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/linux_platform_backend.py">telemetry/internal/platform/linux_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.platform.linux_based_platform_backend.html">telemetry.internal.platform.linux_based_platform_backend</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html">telemetry.internal.platform.power_monitor.msr_power_monitor</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.core.os_version.html">telemetry.core.os_version</a><br>
-</td><td width="25%" valign=top><a href="platform.html">platform</a><br>
-<a href="telemetry.internal.platform.posix_platform_backend.html">telemetry.internal.platform.posix_platform_backend</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.linux_platform_backend.html#LinuxPlatformBackend">LinuxPlatformBackend</a>(<a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>, <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>)
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>(<a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.linux_platform_backend.html#LinuxPlatformBackend">LinuxPlatformBackend</a>(<a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>, <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>)
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LinuxPlatformBackend">class <strong>LinuxPlatformBackend</strong></a>(<a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>, <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.linux_platform_backend.html#LinuxPlatformBackend">LinuxPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="LinuxPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="LinuxPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>:<br>
-<dl><dt><a name="LinuxPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;child&nbsp;pids&nbsp;of&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt><dd><tt>Returns&nbsp;output&nbsp;of&nbsp;the&nbsp;'ps'&nbsp;command&nbsp;as&nbsp;a&nbsp;list&nbsp;of&nbsp;lines.<br>
-Subclass&nbsp;should&nbsp;override&nbsp;this&nbsp;function.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;columns:&nbsp;A&nbsp;list&nbsp;of&nbsp;require&nbsp;columns,&nbsp;e.g.,&nbsp;['pid',&nbsp;'pss'].<br>
-&nbsp;&nbsp;pid:&nbsp;If&nbsp;not&nbsp;None,&nbsp;returns&nbsp;only&nbsp;the&nbsp;information&nbsp;of&nbsp;the&nbsp;process<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;the&nbsp;pid.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, args)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>:<br>
-<dl><dt><a name="LinuxPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>:<br>
-<dl><dt><a name="LinuxPlatformBackend-GetClockTicks"><strong>GetClockTicks</strong></a>(*args, **kwargs)</dt><dd><tt>Returns&nbsp;the&nbsp;number&nbsp;of&nbsp;clock&nbsp;ticks&nbsp;per&nbsp;second.<br>
-&nbsp;<br>
-The&nbsp;proper&nbsp;way&nbsp;is&nbsp;to&nbsp;call&nbsp;os.sysconf('SC_CLK_TCK')&nbsp;but&nbsp;that&nbsp;is&nbsp;not&nbsp;easy&nbsp;to<br>
-do&nbsp;on&nbsp;Android/CrOS.&nbsp;In&nbsp;practice,&nbsp;nearly&nbsp;all&nbsp;Linux&nbsp;machines&nbsp;have&nbsp;a&nbsp;USER_HZ<br>
-of&nbsp;100,&nbsp;so&nbsp;just&nbsp;return&nbsp;that.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt><dd><tt>#&nbsp;Get&nbsp;the&nbsp;commit&nbsp;charge&nbsp;in&nbsp;kB.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(*args, **kwargs)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.internal.platform.linux_based_platform_backend.html#LinuxBasedPlatformBackend">telemetry.internal.platform.linux_based_platform_backend.LinuxBasedPlatformBackend</a>:<br>
-<dl><dt><a name="LinuxPlatformBackend-ParseCStateSample"><strong>ParseCStateSample</strong></a>(sample)</dt><dd><tt>Parse&nbsp;a&nbsp;single&nbsp;c-state&nbsp;residency&nbsp;sample.<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sample:&nbsp;A&nbsp;sample&nbsp;of&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;to&nbsp;be&nbsp;parsed.&nbsp;Organized&nbsp;as<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;CPU&nbsp;name&nbsp;to&nbsp;a&nbsp;string&nbsp;containing&nbsp;all&nbsp;c-state<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;names,&nbsp;the&nbsp;times&nbsp;in&nbsp;each&nbsp;state,&nbsp;the&nbsp;latency&nbsp;of&nbsp;each&nbsp;state,&nbsp;and&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time&nbsp;at&nbsp;which&nbsp;the&nbsp;sample&nbsp;was&nbsp;taken&nbsp;all&nbsp;separated&nbsp;by&nbsp;newlines.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Ex:&nbsp;{'cpu0':&nbsp;'C0<br>
-C1<br>
-5000<br>
-2000<br>
-20<br>
-30<br>
-1406673171'}<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;associating&nbsp;a&nbsp;c-state&nbsp;with&nbsp;a&nbsp;time.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="LinuxPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="LinuxPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="LinuxPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.mac_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.mac_platform_backend.html
deleted file mode 100644
index f5772ee..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.mac_platform_backend.html
+++ /dev/null
@@ -1,253 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.mac_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.mac_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/mac_platform_backend.py">telemetry/internal/platform/mac_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ctypes.html">ctypes</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.os_version.html">telemetry.core.os_version</a><br>
-<a href="platform.html">platform</a><br>
-<a href="telemetry.internal.platform.posix_platform_backend.html">telemetry.internal.platform.posix_platform_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html">telemetry.internal.platform.power_monitor.powermetrics_power_monitor</a><br>
-<a href="telemetry.util.process_statistic_timeline_data.html">telemetry.util.process_statistic_timeline_data</a><br>
-<a href="resource.html">resource</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-<a href="time.html">time</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>(<a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.mac_platform_backend.html#MacPlatformBackend">MacPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MacPlatformBackend">class <strong>MacPlatformBackend</strong></a>(<a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.mac_platform_backend.html#MacPlatformBackend">MacPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MacPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt><dd><tt>Returns&nbsp;a&nbsp;dict&nbsp;of&nbsp;cpu&nbsp;statistics&nbsp;for&nbsp;the&nbsp;process&nbsp;represented&nbsp;by&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt><dd><tt>Return&nbsp;current&nbsp;timestamp&nbsp;in&nbsp;seconds.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="MacPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">telemetry.internal.platform.posix_platform_backend.PosixPlatformBackend</a>:<br>
-<dl><dt><a name="MacPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;child&nbsp;pids&nbsp;of&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt><dd><tt>Returns&nbsp;output&nbsp;of&nbsp;the&nbsp;'ps'&nbsp;command&nbsp;as&nbsp;a&nbsp;list&nbsp;of&nbsp;lines.<br>
-Subclass&nbsp;should&nbsp;override&nbsp;this&nbsp;function.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;columns:&nbsp;A&nbsp;list&nbsp;of&nbsp;require&nbsp;columns,&nbsp;e.g.,&nbsp;['pid',&nbsp;'pss'].<br>
-&nbsp;&nbsp;pid:&nbsp;If&nbsp;not&nbsp;None,&nbsp;returns&nbsp;only&nbsp;the&nbsp;information&nbsp;of&nbsp;the&nbsp;process<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;the&nbsp;pid.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, args)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>:<br>
-<dl><dt><a name="MacPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="MacPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="MacPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="MacPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="MacPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.msr_server_win.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.msr_server_win.html
deleted file mode 100644
index 3f42f64..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.msr_server_win.html
+++ /dev/null
@@ -1,184 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.msr_server_win</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.msr_server_win</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/msr_server_win.py">telemetry/internal/platform/msr_server_win.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;server&nbsp;that&nbsp;serves&nbsp;MSR&nbsp;values&nbsp;over&nbsp;TCP.&nbsp;Takes&nbsp;a&nbsp;port&nbsp;as&nbsp;its&nbsp;sole&nbsp;parameter.<br>
-&nbsp;<br>
-The&nbsp;reference&nbsp;client&nbsp;for&nbsp;this&nbsp;server&nbsp;is&nbsp;msr_power_monitor.MsrPowerMonitor.<br>
-&nbsp;<br>
-Must&nbsp;be&nbsp;run&nbsp;as&nbsp;Administrator.&nbsp;We&nbsp;use&nbsp;TCP&nbsp;instead&nbsp;of&nbsp;named&nbsp;pipes&nbsp;or&nbsp;another&nbsp;IPC<br>
-to&nbsp;avoid&nbsp;dealing&nbsp;with&nbsp;the&nbsp;pipe&nbsp;security&nbsp;mechanisms.&nbsp;We&nbsp;take&nbsp;the&nbsp;port&nbsp;as&nbsp;a<br>
-parameter&nbsp;instead&nbsp;of&nbsp;choosing&nbsp;one,&nbsp;because&nbsp;it's&nbsp;hard&nbsp;to&nbsp;communicate&nbsp;the&nbsp;port<br>
-number&nbsp;across&nbsp;integrity&nbsp;levels.<br>
-&nbsp;<br>
-Requires&nbsp;WinRing0&nbsp;to&nbsp;be&nbsp;installed&nbsp;in&nbsp;the&nbsp;Python&nbsp;directory.<br>
-msr_power_monitor.MsrPowerMonitor&nbsp;does&nbsp;this&nbsp;if&nbsp;needed.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="SocketServer.html">SocketServer</a><br>
-<a href="argparse.html">argparse</a><br>
-</td><td width="25%" valign=top><a href="ctypes.html">ctypes</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="struct.html">struct</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a>(<a href="SocketServer.html#BaseRequestHandler">SocketServer.BaseRequestHandler</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.msr_server_win.html#MsrRequestHandler">MsrRequestHandler</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#OSError">exceptions.OSError</a>(<a href="exceptions.html#EnvironmentError">exceptions.EnvironmentError</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.msr_server_win.html#WinRing0Error">WinRing0Error</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MsrRequestHandler">class <strong>MsrRequestHandler</strong></a>(<a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.msr_server_win.html#MsrRequestHandler">MsrRequestHandler</a></dd>
-<dd><a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a></dd>
-<dd><a href="SocketServer.html#BaseRequestHandler">SocketServer.BaseRequestHandler</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MsrRequestHandler-handle"><strong>handle</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a>:<br>
-<dl><dt><a name="MsrRequestHandler-finish"><strong>finish</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MsrRequestHandler-setup"><strong>setup</strong></a>(self)</dt></dl>
-
-<hr>
-Data and other attributes inherited from <a href="SocketServer.html#StreamRequestHandler">SocketServer.StreamRequestHandler</a>:<br>
-<dl><dt><strong>disable_nagle_algorithm</strong> = False</dl>
-
-<dl><dt><strong>rbufsize</strong> = -1</dl>
-
-<dl><dt><strong>timeout</strong> = None</dl>
-
-<dl><dt><strong>wbufsize</strong> = 0</dl>
-
-<hr>
-Methods inherited from <a href="SocketServer.html#BaseRequestHandler">SocketServer.BaseRequestHandler</a>:<br>
-<dl><dt><a name="MsrRequestHandler-__init__"><strong>__init__</strong></a>(self, request, client_address, server)</dt></dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WinRing0Error">class <strong>WinRing0Error</strong></a>(<a href="exceptions.html#OSError">exceptions.OSError</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.msr_server_win.html#WinRing0Error">WinRing0Error</a></dd>
-<dd><a href="exceptions.html#OSError">exceptions.OSError</a></dd>
-<dd><a href="exceptions.html#EnvironmentError">exceptions.EnvironmentError</a></dd>
-<dd><a href="exceptions.html#StandardError">exceptions.StandardError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#OSError">exceptions.OSError</a>:<br>
-<dl><dt><a name="WinRing0Error-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#OSError">exceptions.OSError</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#WinRing0Error-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#EnvironmentError">exceptions.EnvironmentError</a>:<br>
-<dl><dt><a name="WinRing0Error-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="WinRing0Error-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#EnvironmentError">exceptions.EnvironmentError</a>:<br>
-<dl><dt><strong>errno</strong></dt>
-<dd><tt>exception&nbsp;errno</tt></dd>
-</dl>
-<dl><dt><strong>filename</strong></dt>
-<dd><tt>exception&nbsp;filename</tt></dd>
-</dl>
-<dl><dt><strong>strerror</strong></dt>
-<dd><tt>exception&nbsp;strerror</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="WinRing0Error-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="WinRing0Error-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="WinRing0Error-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="WinRing0Error-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="WinRing0Error-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="WinRing0Error-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#WinRing0Error-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="WinRing0Error-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="WinRing0Error-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-main"><strong>main</strong></a>()</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>WINRING0_STATUS_MESSAGES</strong> = ('No error', 'Unsupported platform', 'Driver not loaded. You may need to run as Administrator', 'Driver not found', 'Driver unloaded by other process', 'Driver not loaded because of executing on Network Drive', 'Unknown error')</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.network_controller_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.network_controller_backend.html
deleted file mode 100644
index 2525f4d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.network_controller_backend.html
+++ /dev/null
@@ -1,225 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.network_controller_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.network_controller_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/network_controller_backend.py">telemetry/internal/platform/network_controller_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.forwarders.html">telemetry.internal.forwarders</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.webpagereplay.html">telemetry.internal.util.webpagereplay</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.network_controller_backend.html#NetworkControllerBackend">NetworkControllerBackend</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.network_controller_backend.html#ArchiveDoesNotExistError">ArchiveDoesNotExistError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.platform.network_controller_backend.html#ReplayAndBrowserPortsError">ReplayAndBrowserPortsError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ArchiveDoesNotExistError">class <strong>ArchiveDoesNotExistError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Raised&nbsp;when&nbsp;the&nbsp;archive&nbsp;path&nbsp;does&nbsp;not&nbsp;exist&nbsp;for&nbsp;replay&nbsp;mode.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.network_controller_backend.html#ArchiveDoesNotExistError">ArchiveDoesNotExistError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ArchiveDoesNotExistError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ArchiveDoesNotExistError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ArchiveDoesNotExistError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveDoesNotExistError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ArchiveDoesNotExistError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NetworkControllerBackend">class <strong>NetworkControllerBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Control&nbsp;network&nbsp;settings&nbsp;and&nbsp;servers&nbsp;to&nbsp;simulate&nbsp;the&nbsp;Web.<br>
-&nbsp;<br>
-Network&nbsp;changes&nbsp;include&nbsp;forwarding&nbsp;device&nbsp;ports&nbsp;to&nbsp;host&nbsp;platform&nbsp;ports.<br>
-Web&nbsp;Page&nbsp;Replay&nbsp;is&nbsp;used&nbsp;to&nbsp;record&nbsp;and&nbsp;replay&nbsp;HTTP/HTTPS&nbsp;responses.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="NetworkControllerBackend-SetReplayArgs"><strong>SetReplayArgs</strong></a>(self, archive_path, wpr_mode, netsim, extra_wpr_args, make_javascript_deterministic<font color="#909090">=False</font>)</dt><dd><tt>Save&nbsp;the&nbsp;arguments&nbsp;needed&nbsp;for&nbsp;replay.<br>
-&nbsp;<br>
-To&nbsp;make&nbsp;the&nbsp;settings&nbsp;effective,&nbsp;this&nbsp;call&nbsp;must&nbsp;be&nbsp;followed&nbsp;by&nbsp;a&nbsp;call<br>
-to&nbsp;UpdateReplay.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;archive_path:&nbsp;a&nbsp;path&nbsp;to&nbsp;a&nbsp;specific&nbsp;WPR&nbsp;archive.<br>
-&nbsp;&nbsp;wpr_mode:&nbsp;one&nbsp;of&nbsp;wpr_modes.WPR_OFF,&nbsp;wpr_modes.WPR_APPEND,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wpr_modes.WPR_REPLAY,&nbsp;or&nbsp;wpr_modes.WPR_RECORD.<br>
-&nbsp;&nbsp;netsim:&nbsp;a&nbsp;net_config&nbsp;string&nbsp;('dialup',&nbsp;'3g',&nbsp;'dsl',&nbsp;'cable',&nbsp;or&nbsp;'fios').<br>
-&nbsp;&nbsp;extra_wpr_args:&nbsp;a&nbsp;list&nbsp;of&nbsp;addtional&nbsp;replay&nbsp;args&nbsp;(or&nbsp;an&nbsp;empty&nbsp;list).<br>
-&nbsp;&nbsp;make_javascript_deterministic:&nbsp;True&nbsp;if&nbsp;replay&nbsp;should&nbsp;inject&nbsp;a&nbsp;script<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;make&nbsp;JavaScript&nbsp;behave&nbsp;deterministically&nbsp;(e.g.,&nbsp;override&nbsp;Date()).</tt></dd></dl>
-
-<dl><dt><a name="NetworkControllerBackend-StopReplay"><strong>StopReplay</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="NetworkControllerBackend-UpdateReplay"><strong>UpdateReplay</strong></a>(self, browser_backend<font color="#909090">=None</font>)</dt><dd><tt>Start&nbsp;or&nbsp;reuse&nbsp;Web&nbsp;Page&nbsp;Replay.<br>
-&nbsp;<br>
-UpdateReplay&nbsp;must&nbsp;be&nbsp;called&nbsp;after&nbsp;every&nbsp;call&nbsp;to&nbsp;SetReplayArgs.<br>
-&nbsp;<br>
-TODO(slamm):&nbsp;Update&nbsp;replay&nbsp;in&nbsp;SetReplayArgs&nbsp;once&nbsp;the&nbsp;browser_backend<br>
-&nbsp;&nbsp;&nbsp;&nbsp;dependencies&nbsp;move&nbsp;to&nbsp;platform.&nbsp;https://crbug.com/423962<br>
-&nbsp;&nbsp;&nbsp;&nbsp;browser_backend&nbsp;properties&nbsp;used:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;Input:&nbsp;wpr_port_pairs<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;Output:&nbsp;wpr_port_pairs&nbsp;(browser&nbsp;uses&nbsp;for&nbsp;--testing-fixed-*&nbsp;flags).<br>
-Args:<br>
-&nbsp;&nbsp;browser_backend:&nbsp;instance&nbsp;of&nbsp;telemetry.core.backends.browser_backend</tt></dd></dl>
-
-<dl><dt><a name="NetworkControllerBackend-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ReplayAndBrowserPortsError">class <strong>ReplayAndBrowserPortsError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Raised&nbsp;an&nbsp;existing&nbsp;browser&nbsp;would&nbsp;get&nbsp;different&nbsp;remote&nbsp;replay&nbsp;ports.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.network_controller_backend.html#ReplayAndBrowserPortsError">ReplayAndBrowserPortsError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ReplayAndBrowserPortsError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ReplayAndBrowserPortsError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ReplayAndBrowserPortsError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayAndBrowserPortsError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayAndBrowserPortsError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.platform_backend.html
deleted file mode 100644
index 41c9bfa..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.platform_backend.html
+++ /dev/null
@@ -1,225 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/platform_backend.py">telemetry/internal/platform/platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.forwarders.do_nothing_forwarder.html">telemetry.internal.forwarders.do_nothing_forwarder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.network_controller_backend.html">telemetry.internal.platform.network_controller_backend</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_controller_backend.html">telemetry.internal.platform.tracing_controller_backend</a><br>
-</td><td width="25%" valign=top><a href="weakref.html">weakref</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">PlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PlatformBackend">class <strong>PlatformBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="PlatformBackend-__init__"><strong>__init__</strong></a>(self, device<font color="#909090">=None</font>)</dt><dd><tt>Initalize&nbsp;an&nbsp;instance&nbsp;of&nbsp;<a href="#PlatformBackend">PlatformBackend</a>&nbsp;from&nbsp;a&nbsp;device&nbsp;optionally.<br>
-Call&nbsp;sites&nbsp;need&nbsp;to&nbsp;use&nbsp;SupportsDevice&nbsp;before&nbsp;intialization&nbsp;to&nbsp;check<br>
-whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;the&nbsp;device.<br>
-If&nbsp;device&nbsp;is&nbsp;None,&nbsp;this&nbsp;constructor&nbsp;returns&nbsp;the&nbsp;host&nbsp;platform&nbsp;backend<br>
-which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.platform.device.Device.</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="PlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="PlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;is&nbsp;the&nbsp;platform&nbsp;backend&nbsp;to&nbsp;be&nbsp;used<br>
-for&nbsp;the&nbsp;host&nbsp;device&nbsp;which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="PlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.posix_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.posix_platform_backend.html
deleted file mode 100644
index cabca16..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.posix_platform_backend.html
+++ /dev/null
@@ -1,253 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.posix_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.posix_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/posix_platform_backend.py">telemetry/internal/platform/posix_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.desktop_platform_backend.html">telemetry.internal.platform.desktop_platform_backend</a><br>
-<a href="distutils.html">distutils</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.internal.util.ps_util.html">telemetry.internal.util.ps_util</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="stat.html">stat</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">PosixPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PosixPlatformBackend">class <strong>PosixPlatformBackend</strong></a>(<a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.posix_platform_backend.html#PosixPlatformBackend">PosixPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PosixPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;child&nbsp;pids&nbsp;of&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetFileContents"><strong>GetFileContents</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetPsOutput"><strong>GetPsOutput</strong></a>(self, columns, pid<font color="#909090">=None</font>)</dt><dd><tt>Returns&nbsp;output&nbsp;of&nbsp;the&nbsp;'ps'&nbsp;command&nbsp;as&nbsp;a&nbsp;list&nbsp;of&nbsp;lines.<br>
-Subclass&nbsp;should&nbsp;override&nbsp;this&nbsp;function.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;columns:&nbsp;A&nbsp;list&nbsp;of&nbsp;require&nbsp;columns,&nbsp;e.g.,&nbsp;['pid',&nbsp;'pss'].<br>
-&nbsp;&nbsp;pid:&nbsp;If&nbsp;not&nbsp;None,&nbsp;returns&nbsp;only&nbsp;the&nbsp;information&nbsp;of&nbsp;the&nbsp;process<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;the&nbsp;pid.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-RunCommand"><strong>RunCommand</strong></a>(self, args)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>:<br>
-<dl><dt><a name="PosixPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="PosixPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt><dd><tt>Cooperatively&nbsp;shut&nbsp;down&nbsp;the&nbsp;given&nbsp;process&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;<br>
-Currently&nbsp;this&nbsp;is&nbsp;only&nbsp;implemented&nbsp;on&nbsp;Windows.&nbsp;See<br>
-crbug.com/424024&nbsp;for&nbsp;background&nbsp;on&nbsp;why&nbsp;it&nbsp;was&nbsp;added.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;proc:&nbsp;a&nbsp;process&nbsp;object&nbsp;returned&nbsp;from&nbsp;subprocess.Popen.<br>
-&nbsp;&nbsp;app_name:&nbsp;on&nbsp;Windows,&nbsp;is&nbsp;the&nbsp;prefix&nbsp;of&nbsp;the&nbsp;application's&nbsp;window<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;name&nbsp;that&nbsp;should&nbsp;be&nbsp;searched&nbsp;for.&nbsp;This&nbsp;helps&nbsp;ensure<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;that&nbsp;only&nbsp;the&nbsp;application's&nbsp;windows&nbsp;are&nbsp;closed.<br>
-&nbsp;<br>
-Returns&nbsp;True&nbsp;if&nbsp;it&nbsp;is&nbsp;believed&nbsp;the&nbsp;attempt&nbsp;succeeded.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt><dd><tt>Indicates&nbsp;whether&nbsp;CooperativelyShutdown,&nbsp;below,&nbsp;is&nbsp;supported.<br>
-It&nbsp;is&nbsp;not&nbsp;necessary&nbsp;to&nbsp;implement&nbsp;it&nbsp;on&nbsp;all&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt><dd><tt>Read&nbsp;a&nbsp;CPU&nbsp;model-specific&nbsp;register&nbsp;(MSR).<br>
-&nbsp;<br>
-Which&nbsp;MSRs&nbsp;are&nbsp;available&nbsp;depends&nbsp;on&nbsp;the&nbsp;CPU&nbsp;model.<br>
-On&nbsp;systems&nbsp;with&nbsp;multiple&nbsp;CPUs,&nbsp;this&nbsp;function&nbsp;may&nbsp;run&nbsp;on&nbsp;any&nbsp;CPU.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;msr_number:&nbsp;The&nbsp;number&nbsp;of&nbsp;the&nbsp;register&nbsp;to&nbsp;read.<br>
-&nbsp;&nbsp;start:&nbsp;The&nbsp;least&nbsp;significant&nbsp;bit&nbsp;to&nbsp;read,&nbsp;zero-indexed.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(Said&nbsp;another&nbsp;way,&nbsp;the&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;right-shift&nbsp;the&nbsp;MSR&nbsp;value.)<br>
-&nbsp;&nbsp;length:&nbsp;The&nbsp;number&nbsp;of&nbsp;bits&nbsp;to&nbsp;read.&nbsp;MSRs&nbsp;are&nbsp;64&nbsp;bits,&nbsp;even&nbsp;on&nbsp;32-bit&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-__init__"><strong>__init__</strong></a>(self, device<font color="#909090">=None</font>)</dt><dd><tt>Initalize&nbsp;an&nbsp;instance&nbsp;of&nbsp;PlatformBackend&nbsp;from&nbsp;a&nbsp;device&nbsp;optionally.<br>
-Call&nbsp;sites&nbsp;need&nbsp;to&nbsp;use&nbsp;SupportsDevice&nbsp;before&nbsp;intialization&nbsp;to&nbsp;check<br>
-whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;the&nbsp;device.<br>
-If&nbsp;device&nbsp;is&nbsp;None,&nbsp;this&nbsp;constructor&nbsp;returns&nbsp;the&nbsp;host&nbsp;platform&nbsp;backend<br>
-which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.platform.device.Device.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="PosixPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="PosixPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;is&nbsp;the&nbsp;platform&nbsp;backend&nbsp;to&nbsp;be&nbsp;used<br>
-for&nbsp;the&nbsp;host&nbsp;device&nbsp;which&nbsp;telemetry&nbsp;is&nbsp;running&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="PosixPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html
deleted file mode 100644
index 42a5df9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.android_dumpsys_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor.py">telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="csv.html">csv</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html#DumpsysPowerMonitor">DumpsysPowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DumpsysPowerMonitor">class <strong>DumpsysPowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">PowerMonitor</a>&nbsp;that&nbsp;relies&nbsp;on&nbsp;the&nbsp;dumpsys&nbsp;batterystats&nbsp;to&nbsp;monitor&nbsp;the&nbsp;power<br>
-consumption&nbsp;of&nbsp;a&nbsp;single&nbsp;android&nbsp;application.&nbsp;This&nbsp;measure&nbsp;uses&nbsp;a&nbsp;heuristic<br>
-and&nbsp;is&nbsp;the&nbsp;same&nbsp;information&nbsp;end-users&nbsp;see&nbsp;with&nbsp;the&nbsp;battery&nbsp;application.<br>
-Available&nbsp;on&nbsp;Android&nbsp;L&nbsp;and&nbsp;higher&nbsp;releases.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html#DumpsysPowerMonitor">DumpsysPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DumpsysPowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DumpsysPowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="DumpsysPowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DumpsysPowerMonitor-__init__"><strong>__init__</strong></a>(self, battery, platform_backend)</dt><dd><tt>Constructor.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;battery:&nbsp;A&nbsp;BatteryUtil&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;platform_backend:&nbsp;A&nbsp;LinuxBasedPlatformBackend&nbsp;instance.</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="DumpsysPowerMonitor-ProcessPowerData"><strong>ProcessPowerData</strong></a>(power_data, voltage, package)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="DumpsysPowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html
deleted file mode 100644
index dd28987..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.android_fuelgauge_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor.py">telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html#FuelGaugePowerMonitor">FuelGaugePowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FuelGaugePowerMonitor">class <strong>FuelGaugePowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">PowerMonitor</a>&nbsp;that&nbsp;relies&nbsp;on&nbsp;the&nbsp;fuel&nbsp;gauge&nbsp;chips&nbsp;to&nbsp;monitor&nbsp;the&nbsp;power<br>
-consumption&nbsp;of&nbsp;a&nbsp;android&nbsp;device.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html#FuelGaugePowerMonitor">FuelGaugePowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FuelGaugePowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FuelGaugePowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="FuelGaugePowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FuelGaugePowerMonitor-__init__"><strong>__init__</strong></a>(self, battery, platform_backend)</dt><dd><tt>Constructor.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;battery:&nbsp;A&nbsp;BatteryUtil&nbsp;instance.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;platform_backend:&nbsp;A&nbsp;LinuxBasedPlatformBackend&nbsp;instance.</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="FuelGaugePowerMonitor-ProcessPowerData"><strong>ProcessPowerData</strong></a>(voltage, fuel_gauge_delta)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="FuelGaugePowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_temperature_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_temperature_monitor.html
deleted file mode 100644
index b663ab9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.android_temperature_monitor.html
+++ /dev/null
@@ -1,79 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.android_temperature_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.android_temperature_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/android_temperature_monitor.py">telemetry/internal/platform/power_monitor/android_temperature_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.android_temperature_monitor.html#AndroidTemperatureMonitor">AndroidTemperatureMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidTemperatureMonitor">class <strong>AndroidTemperatureMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Returns&nbsp;temperature&nbsp;results&nbsp;in&nbsp;power&nbsp;monitor&nbsp;dictionary&nbsp;format.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.android_temperature_monitor.html#AndroidTemperatureMonitor">AndroidTemperatureMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidTemperatureMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidTemperatureMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="AndroidTemperatureMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidTemperatureMonitor-__init__"><strong>__init__</strong></a>(self, device)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="AndroidTemperatureMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.cros_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.cros_power_monitor.html
deleted file mode 100644
index e3688ed..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.cros_power_monitor.html
+++ /dev/null
@@ -1,171 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.cros_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.cros_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/cros_power_monitor.py">telemetry/internal/platform/power_monitor/cros_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html">telemetry.internal.platform.power_monitor.sysfs_power_monitor</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">telemetry.internal.platform.power_monitor.sysfs_power_monitor.SysfsPowerMonitor</a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.cros_power_monitor.html#CrosPowerMonitor">CrosPowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CrosPowerMonitor">class <strong>CrosPowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">telemetry.internal.platform.power_monitor.sysfs_power_monitor.SysfsPowerMonitor</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>PowerMonitor&nbsp;that&nbsp;relies&nbsp;on&nbsp;'dump_power_status'&nbsp;to&nbsp;monitor&nbsp;power<br>
-consumption&nbsp;of&nbsp;a&nbsp;single&nbsp;ChromeOS&nbsp;application.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.cros_power_monitor.html#CrosPowerMonitor">CrosPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">telemetry.internal.platform.power_monitor.sysfs_power_monitor.SysfsPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CrosPowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="CrosPowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="CrosPowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CrosPowerMonitor-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt><dd><tt>Constructor.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;platform_backend:&nbsp;A&nbsp;LinuxBasedPlatformBackend&nbsp;object.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_initial_power:&nbsp;The&nbsp;result&nbsp;of&nbsp;'dump_power_status'&nbsp;before&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_start_time:&nbsp;The&nbsp;epoch&nbsp;time&nbsp;at&nbsp;which&nbsp;the&nbsp;test&nbsp;starts&nbsp;executing.</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="CrosPowerMonitor-IsOnBatteryPower"><strong>IsOnBatteryPower</strong></a>(status, board)</dt><dd><tt>Determines&nbsp;if&nbsp;the&nbsp;devices&nbsp;is&nbsp;being&nbsp;charged.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;status:&nbsp;The&nbsp;parsed&nbsp;result&nbsp;of&nbsp;'dump_power_status'<br>
-&nbsp;&nbsp;&nbsp;&nbsp;board:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;board&nbsp;running&nbsp;the&nbsp;test.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;True&nbsp;if&nbsp;the&nbsp;device&nbsp;is&nbsp;on&nbsp;battery&nbsp;power;&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<dl><dt><a name="CrosPowerMonitor-ParsePower"><strong>ParsePower</strong></a>(initial_stats, final_stats, length_h)</dt><dd><tt>Parse&nbsp;output&nbsp;of&nbsp;'dump_power_status'<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;initial_stats:&nbsp;The&nbsp;output&nbsp;of&nbsp;'dump_power_status'&nbsp;before&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;final_stats:&nbsp;The&nbsp;output&nbsp;of&nbsp;'dump_power_status'&nbsp;after&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;length_h:&nbsp;The&nbsp;length&nbsp;of&nbsp;the&nbsp;test&nbsp;in&nbsp;hours.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;in&nbsp;the&nbsp;format&nbsp;returned&nbsp;by&nbsp;<a href="#CrosPowerMonitor-StopMonitoringPower">StopMonitoringPower</a>().</tt></dd></dl>
-
-<dl><dt><a name="CrosPowerMonitor-ParsePowerStatus"><strong>ParsePowerStatus</strong></a>(sample)</dt><dd><tt>Parses&nbsp;'dump_power_status'&nbsp;command&nbsp;output.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;sample:&nbsp;The&nbsp;output&nbsp;of&nbsp;'dump_power_status'<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;all&nbsp;fields&nbsp;from&nbsp;'dump_power_status'</tt></dd></dl>
-
-<dl><dt><a name="CrosPowerMonitor-SplitSample"><strong>SplitSample</strong></a>(sample)</dt><dd><tt>Splits&nbsp;a&nbsp;power&nbsp;and&nbsp;time&nbsp;sample&nbsp;into&nbsp;the&nbsp;two&nbsp;separate&nbsp;values.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;sample:&nbsp;The&nbsp;result&nbsp;of&nbsp;calling&nbsp;'dump_power_status;&nbsp;date&nbsp;+%s'&nbsp;on&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;tuple&nbsp;of&nbsp;power&nbsp;sample&nbsp;and&nbsp;epoch&nbsp;time&nbsp;of&nbsp;the&nbsp;sample.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">telemetry.internal.platform.power_monitor.sysfs_power_monitor.SysfsPowerMonitor</a>:<br>
-<dl><dt><a name="CrosPowerMonitor-GetCpuFreq"><strong>GetCpuFreq</strong></a>(self)</dt><dd><tt>Retrieve&nbsp;CPU&nbsp;frequency&nbsp;times&nbsp;from&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;frequency&nbsp;times&nbsp;for&nbsp;each&nbsp;CPU.</tt></dd></dl>
-
-<dl><dt><a name="CrosPowerMonitor-GetCpuState"><strong>GetCpuState</strong></a>(self)</dt><dd><tt>Retrieve&nbsp;CPU&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;from&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;for&nbsp;each&nbsp;CPU.</tt></dd></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">telemetry.internal.platform.power_monitor.sysfs_power_monitor.SysfsPowerMonitor</a>:<br>
-<dl><dt><a name="CrosPowerMonitor-CombineResults"><strong>CombineResults</strong></a>(cpu_stats, power_stats)</dt><dd><tt>Add&nbsp;frequency&nbsp;and&nbsp;c-state&nbsp;residency&nbsp;data&nbsp;to&nbsp;the&nbsp;power&nbsp;data.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;cpu_stats:&nbsp;Dictionary&nbsp;containing&nbsp;CPU&nbsp;statistics.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;power_stats:&nbsp;Dictionary&nbsp;containing&nbsp;power&nbsp;statistics.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;in&nbsp;the&nbsp;format&nbsp;returned&nbsp;by&nbsp;StopMonitoringPower.</tt></dd></dl>
-
-<dl><dt><a name="CrosPowerMonitor-ComputeCpuStats"><strong>ComputeCpuStats</strong></a>(initial, final)</dt><dd><tt>Parse&nbsp;the&nbsp;CPU&nbsp;c-state&nbsp;and&nbsp;frequency&nbsp;values&nbsp;saved&nbsp;during&nbsp;monitoring.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;initial:&nbsp;The&nbsp;parsed&nbsp;dictionary&nbsp;of&nbsp;initial&nbsp;statistics&nbsp;to&nbsp;be&nbsp;converted<br>
-&nbsp;&nbsp;&nbsp;&nbsp;into&nbsp;percentages.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;final:&nbsp;The&nbsp;parsed&nbsp;dictionary&nbsp;of&nbsp;final&nbsp;statistics&nbsp;to&nbsp;be&nbsp;converted<br>
-&nbsp;&nbsp;&nbsp;&nbsp;into&nbsp;percentages.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;percentages&nbsp;for&nbsp;each&nbsp;CPU&nbsp;as&nbsp;well&nbsp;as&nbsp;an&nbsp;average<br>
-&nbsp;&nbsp;&nbsp;&nbsp;across&nbsp;all&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="CrosPowerMonitor-ParseFreqSample"><strong>ParseFreqSample</strong></a>(sample)</dt><dd><tt>Parse&nbsp;a&nbsp;single&nbsp;frequency&nbsp;sample.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;sample:&nbsp;The&nbsp;single&nbsp;sample&nbsp;of&nbsp;frequency&nbsp;data&nbsp;to&nbsp;be&nbsp;parsed.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;dictionary&nbsp;associating&nbsp;a&nbsp;frequency&nbsp;with&nbsp;a&nbsp;time.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="CrosPowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.html
deleted file mode 100644
index bc7461c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.platform.power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/__init__.py">telemetry/internal/platform/power_monitor/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor.html">android_dumpsys_power_monitor</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_dumpsys_power_monitor_unittest.html">android_dumpsys_power_monitor_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor.html">android_fuelgauge_power_monitor</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_fuelgauge_power_monitor_unittest.html">android_fuelgauge_power_monitor_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.android_temperature_monitor.html">android_temperature_monitor</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.android_temperature_monitor_unittest.html">android_temperature_monitor_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.cros_power_monitor.html">cros_power_monitor</a><br>
-<a href="telemetry.internal.platform.power_monitor.cros_power_monitor_unittest.html">cros_power_monitor_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.monsoon_power_monitor.html">monsoon_power_monitor</a><br>
-<a href="telemetry.internal.platform.power_monitor.monsoon_power_monitor_unittest.html">monsoon_power_monitor_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html">msr_power_monitor</a><br>
-<a href="telemetry.internal.platform.power_monitor.msr_power_monitor_unittest.html">msr_power_monitor_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.power_monitor_controller.html">power_monitor_controller</a><br>
-<a href="telemetry.internal.platform.power_monitor.power_monitor_controller_unittest.html">power_monitor_controller_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html">powermetrics_power_monitor</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.powermetrics_power_monitor_unittest.html">powermetrics_power_monitor_unittest</a><br>
-<a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html">sysfs_power_monitor</a><br>
-<a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor_unittest.html">sysfs_power_monitor_unittest</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">PowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PowerMonitor">class <strong>PowerMonitor</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;power&nbsp;profiler.<br>
-&nbsp;<br>
-Provides&nbsp;an&nbsp;interface&nbsp;to&nbsp;register&nbsp;power&nbsp;consumption&nbsp;during&nbsp;a&nbsp;test.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<dl><dt><a name="PowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;power&nbsp;can&nbsp;be&nbsp;monitored&nbsp;asynchronously&nbsp;via<br>
-<a href="#PowerMonitor-StartMonitoringPower">StartMonitoringPower</a>()&nbsp;and&nbsp;<a href="#PowerMonitor-StopMonitoringPower">StopMonitoringPower</a>().</tt></dd></dl>
-
-<dl><dt><a name="PowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt><dd><tt>Starts&nbsp;monitoring&nbsp;power&nbsp;utilization&nbsp;statistics.<br>
-&nbsp;<br>
-See&nbsp;Platform#StartMonitoringPower&nbsp;for&nbsp;the&nbsp;arguments&nbsp;format.</tt></dd></dl>
-
-<dl><dt><a name="PowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt><dd><tt>Stops&nbsp;monitoring&nbsp;power&nbsp;utilization&nbsp;and&nbsp;returns&nbsp;collects&nbsp;stats<br>
-&nbsp;<br>
-See&nbsp;Platform#StopMonitoringPower&nbsp;for&nbsp;the&nbsp;return&nbsp;format.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.monsoon_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.monsoon_power_monitor.html
deleted file mode 100644
index fa24e9c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.monsoon_power_monitor.html
+++ /dev/null
@@ -1,89 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.monsoon_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.monsoon_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/monsoon_power_monitor.py">telemetry/internal/platform/power_monitor/monsoon_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.monsoon.html">telemetry.internal.platform.profiler.monsoon</a><br>
-<a href="multiprocessing.html">multiprocessing</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.monsoon_power_monitor.html#MonsoonPowerMonitor">MonsoonPowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MonsoonPowerMonitor">class <strong>MonsoonPowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.monsoon_power_monitor.html#MonsoonPowerMonitor">MonsoonPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MonsoonPowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MonsoonPowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MonsoonPowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MonsoonPowerMonitor-__init__"><strong>__init__</strong></a>(self, _, platform_backend)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="MonsoonPowerMonitor-ParseSamplingOutput"><strong>ParseSamplingOutput</strong></a>(powermonitor_output)</dt><dd><tt>Parse&nbsp;the&nbsp;output&nbsp;of&nbsp;of&nbsp;the&nbsp;samples&nbsp;collector&nbsp;process.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;in&nbsp;the&nbsp;format&nbsp;returned&nbsp;by&nbsp;<a href="#MonsoonPowerMonitor-StopMonitoringPower">StopMonitoringPower</a>().</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="MonsoonPowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.msr_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.msr_power_monitor.html
deleted file mode 100644
index b050d36..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.msr_power_monitor.html
+++ /dev/null
@@ -1,177 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.msr_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.msr_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/msr_power_monitor.py">telemetry/internal/platform/power_monitor/msr_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="platform.html">platform</a><br>
-<a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitorLinux">MsrPowerMonitorLinux</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitorWin">MsrPowerMonitorWin</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MsrPowerMonitor">class <strong>MsrPowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MsrPowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitor-__init__"><strong>__init__</strong></a>(self, backend)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="MsrPowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MsrPowerMonitorLinux">class <strong>MsrPowerMonitorLinux</strong></a>(<a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitorLinux">MsrPowerMonitorLinux</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MsrPowerMonitorLinux-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a>:<br>
-<dl><dt><a name="MsrPowerMonitorLinux-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitorLinux-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitorLinux-__init__"><strong>__init__</strong></a>(self, backend)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="MsrPowerMonitorLinux-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MsrPowerMonitorWin">class <strong>MsrPowerMonitorWin</strong></a>(<a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitorWin">MsrPowerMonitorWin</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MsrPowerMonitorWin-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitorWin-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html#MsrPowerMonitor">MsrPowerMonitor</a>:<br>
-<dl><dt><a name="MsrPowerMonitorWin-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="MsrPowerMonitorWin-__init__"><strong>__init__</strong></a>(self, backend)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="MsrPowerMonitorWin-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>IA32_PACKAGE_THERM_STATUS</strong> = 433<br>
-<strong>IA32_TEMPERATURE_TARGET</strong> = 418<br>
-<strong>MSR_DRAM_ENERGY_STATUS</strong> = 1561<br>
-<strong>MSR_PKG_ENERGY_STATUS</strong> = 1553<br>
-<strong>MSR_PP0_ENERGY_STATUS</strong> = 1593<br>
-<strong>MSR_PP1_ENERGY_STATUS</strong> = 1601<br>
-<strong>MSR_RAPL_POWER_UNIT</strong> = 1542</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.power_monitor_controller.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.power_monitor_controller.html
deleted file mode 100644
index e1ba28c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.power_monitor_controller.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.power_monitor_controller</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.power_monitor_controller</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/power_monitor_controller.py">telemetry/internal/platform/power_monitor/power_monitor_controller.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="atexit.html">atexit</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.power_monitor_controller.html#PowerMonitorController">PowerMonitorController</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PowerMonitorController">class <strong>PowerMonitorController</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">PowerMonitor</a>&nbsp;that&nbsp;acts&nbsp;as&nbsp;facade&nbsp;for&nbsp;a&nbsp;list&nbsp;of&nbsp;<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">PowerMonitor</a>&nbsp;objects&nbsp;and&nbsp;uses<br>
-the&nbsp;first&nbsp;available&nbsp;one.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.power_monitor_controller.html#PowerMonitorController">PowerMonitorController</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PowerMonitorController-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PowerMonitorController-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="PowerMonitorController-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PowerMonitorController-__init__"><strong>__init__</strong></a>(self, power_monitors, battery)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="PowerMonitorController-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html
deleted file mode 100644
index 7698b43..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html
+++ /dev/null
@@ -1,98 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.powermetrics_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.powermetrics_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py">telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.core.os_version.html">telemetry.core.os_version</a><br>
-<a href="plistlib.html">plistlib</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-<a href="shutil.html">shutil</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="xml.html">xml</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html#PowerMetricsPowerMonitor">PowerMetricsPowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PowerMetricsPowerMonitor">class <strong>PowerMetricsPowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.powermetrics_power_monitor.html#PowerMetricsPowerMonitor">PowerMetricsPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PowerMetricsPowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PowerMetricsPowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="PowerMetricsPowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PowerMetricsPowerMonitor-__init__"><strong>__init__</strong></a>(self, backend)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="PowerMetricsPowerMonitor-ParsePowerMetricsOutput"><strong>ParsePowerMetricsOutput</strong></a>(powermetrics_output)</dt><dd><tt>Parse&nbsp;output&nbsp;of&nbsp;powermetrics&nbsp;command&nbsp;line&nbsp;utility.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;in&nbsp;the&nbsp;format&nbsp;returned&nbsp;by&nbsp;<a href="#PowerMetricsPowerMonitor-StopMonitoringPower">StopMonitoringPower</a>()&nbsp;or&nbsp;None<br>
-&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;|powermetrics_output|&nbsp;is&nbsp;empty&nbsp;-&nbsp;crbug.com/353250&nbsp;.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>binary_path</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="PowerMetricsPowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.sysfs_power_monitor.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.sysfs_power_monitor.html
deleted file mode 100644
index 82bec24..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.power_monitor.sysfs_power_monitor.html
+++ /dev/null
@@ -1,147 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.power_monitor.sysfs_power_monitor</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.power_monitor.html"><font color="#ffffff">power_monitor</font></a>.sysfs_power_monitor</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/power_monitor/sysfs_power_monitor.py">telemetry/internal/platform/power_monitor/sysfs_power_monitor.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.power_monitor.html">telemetry.internal.platform.power_monitor</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">SysfsPowerMonitor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SysfsPowerMonitor">class <strong>SysfsPowerMonitor</strong></a>(<a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">PowerMonitor</a>&nbsp;that&nbsp;relies&nbsp;on&nbsp;sysfs&nbsp;to&nbsp;monitor&nbsp;CPU&nbsp;statistics&nbsp;on&nbsp;several<br>
-different&nbsp;platforms.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.power_monitor.sysfs_power_monitor.html#SysfsPowerMonitor">SysfsPowerMonitor</a></dd>
-<dd><a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SysfsPowerMonitor-CanMonitorPower"><strong>CanMonitorPower</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-GetCpuFreq"><strong>GetCpuFreq</strong></a>(self)</dt><dd><tt>Retrieve&nbsp;CPU&nbsp;frequency&nbsp;times&nbsp;from&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;frequency&nbsp;times&nbsp;for&nbsp;each&nbsp;CPU.</tt></dd></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-GetCpuState"><strong>GetCpuState</strong></a>(self)</dt><dd><tt>Retrieve&nbsp;CPU&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;from&nbsp;the&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;for&nbsp;each&nbsp;CPU.</tt></dd></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, _browser)</dt></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-__init__"><strong>__init__</strong></a>(self, linux_based_platform_backend, standalone<font color="#909090">=False</font>)</dt><dd><tt>Constructor.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;linux_based_platform_backend:&nbsp;A&nbsp;LinuxBasedPlatformBackend&nbsp;object.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;standalone:&nbsp;If&nbsp;it&nbsp;is&nbsp;not&nbsp;wrapping&nbsp;another&nbsp;monitor,&nbsp;set&nbsp;to&nbsp;True.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_cpus:&nbsp;A&nbsp;list&nbsp;of&nbsp;the&nbsp;CPUs&nbsp;on&nbsp;the&nbsp;target&nbsp;device.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_end_time:&nbsp;The&nbsp;time&nbsp;the&nbsp;test&nbsp;stopped&nbsp;monitoring&nbsp;power.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_final_cstate:&nbsp;The&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;after&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_final_freq:&nbsp;The&nbsp;CPU&nbsp;frequency&nbsp;times&nbsp;after&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_initial_cstate:&nbsp;The&nbsp;c-state&nbsp;residency&nbsp;times&nbsp;before&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_initial_freq:&nbsp;The&nbsp;CPU&nbsp;frequency&nbsp;times&nbsp;before&nbsp;the&nbsp;test.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_platform:&nbsp;A&nbsp;LinuxBasedPlatformBackend&nbsp;object&nbsp;associated&nbsp;with&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;target&nbsp;platform.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;_start_time:&nbsp;The&nbsp;time&nbsp;the&nbsp;test&nbsp;started&nbsp;monitoring&nbsp;power.</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="SysfsPowerMonitor-CombineResults"><strong>CombineResults</strong></a>(cpu_stats, power_stats)</dt><dd><tt>Add&nbsp;frequency&nbsp;and&nbsp;c-state&nbsp;residency&nbsp;data&nbsp;to&nbsp;the&nbsp;power&nbsp;data.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;cpu_stats:&nbsp;Dictionary&nbsp;containing&nbsp;CPU&nbsp;statistics.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;power_stats:&nbsp;Dictionary&nbsp;containing&nbsp;power&nbsp;statistics.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;in&nbsp;the&nbsp;format&nbsp;returned&nbsp;by&nbsp;StopMonitoringPower.</tt></dd></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-ComputeCpuStats"><strong>ComputeCpuStats</strong></a>(initial, final)</dt><dd><tt>Parse&nbsp;the&nbsp;CPU&nbsp;c-state&nbsp;and&nbsp;frequency&nbsp;values&nbsp;saved&nbsp;during&nbsp;monitoring.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;initial:&nbsp;The&nbsp;parsed&nbsp;dictionary&nbsp;of&nbsp;initial&nbsp;statistics&nbsp;to&nbsp;be&nbsp;converted<br>
-&nbsp;&nbsp;&nbsp;&nbsp;into&nbsp;percentages.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;final:&nbsp;The&nbsp;parsed&nbsp;dictionary&nbsp;of&nbsp;final&nbsp;statistics&nbsp;to&nbsp;be&nbsp;converted<br>
-&nbsp;&nbsp;&nbsp;&nbsp;into&nbsp;percentages.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;Dictionary&nbsp;containing&nbsp;percentages&nbsp;for&nbsp;each&nbsp;CPU&nbsp;as&nbsp;well&nbsp;as&nbsp;an&nbsp;average<br>
-&nbsp;&nbsp;&nbsp;&nbsp;across&nbsp;all&nbsp;CPUs.</tt></dd></dl>
-
-<dl><dt><a name="SysfsPowerMonitor-ParseFreqSample"><strong>ParseFreqSample</strong></a>(sample)</dt><dd><tt>Parse&nbsp;a&nbsp;single&nbsp;frequency&nbsp;sample.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;sample:&nbsp;The&nbsp;single&nbsp;sample&nbsp;of&nbsp;frequency&nbsp;data&nbsp;to&nbsp;be&nbsp;parsed.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;A&nbsp;dictionary&nbsp;associating&nbsp;a&nbsp;frequency&nbsp;with&nbsp;a&nbsp;time.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><a name="SysfsPowerMonitor-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;power&nbsp;monitor&nbsp;can&nbsp;measure&nbsp;power&nbsp;for&nbsp;the&nbsp;target<br>
-application&nbsp;in&nbsp;isolation.&nbsp;False&nbsp;if&nbsp;power&nbsp;measurement&nbsp;is&nbsp;for&nbsp;full&nbsp;system<br>
-energy&nbsp;consumption.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.power_monitor.html#PowerMonitor">telemetry.internal.platform.power_monitor.PowerMonitor</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>CPU_PATH</strong> = '/sys/devices/system/cpu/'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html
deleted file mode 100644
index 967106d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html
+++ /dev/null
@@ -1,35 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.android_prebuilt_profiler_helper</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.android_prebuilt_profiler_helper</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/android_prebuilt_profiler_helper.py">telemetry/internal/platform/profiler/android_prebuilt_profiler_helper.py</a></font></td></tr></table>
-    <p><tt>Android-specific,&nbsp;installs&nbsp;pre-built&nbsp;profilers.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-</td><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetDevicePath"><strong>GetDevicePath</strong></a>(profiler_binary)</dt></dl>
- <dl><dt><a name="-InstallOnDevice"><strong>InstallOnDevice</strong></a>(*args, **kwargs)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_profiling_helper.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_profiling_helper.html
deleted file mode 100644
index fed15b2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_profiling_helper.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.android_profiling_helper</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.android_profiling_helper</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/android_profiling_helper.py">telemetry/internal/platform/profiler/android_profiling_helper.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html">telemetry.internal.platform.profiler.android_prebuilt_profiler_helper</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="glob.html">glob</a><br>
-</td><td width="25%" valign=top><a href="hashlib.html">hashlib</a><br>
-<a href="logging.html">logging</a><br>
-<a href="devil.android.md5sum.html">devil.android.md5sum</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="platform.html">platform</a><br>
-<a href="re.html">re</a><br>
-<a href="shutil.html">shutil</a><br>
-<a href="sqlite3.html">sqlite3</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CreateSymFs"><strong>CreateSymFs</strong></a>(device, symfs_dir, libraries, use_symlinks<font color="#909090">=True</font>)</dt><dd><tt>Creates&nbsp;a&nbsp;symfs&nbsp;directory&nbsp;to&nbsp;be&nbsp;used&nbsp;for&nbsp;symbolizing&nbsp;profiles.<br>
-&nbsp;<br>
-Prepares&nbsp;a&nbsp;set&nbsp;of&nbsp;files&nbsp;("symfs")&nbsp;to&nbsp;be&nbsp;used&nbsp;with&nbsp;profilers&nbsp;such&nbsp;as&nbsp;perf&nbsp;for<br>
-converting&nbsp;binary&nbsp;addresses&nbsp;into&nbsp;human&nbsp;readable&nbsp;function&nbsp;names.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;DeviceUtils&nbsp;instance&nbsp;identifying&nbsp;the&nbsp;target&nbsp;device.<br>
-&nbsp;&nbsp;symfs_dir:&nbsp;Path&nbsp;where&nbsp;the&nbsp;symfs&nbsp;should&nbsp;be&nbsp;created.<br>
-&nbsp;&nbsp;libraries:&nbsp;Set&nbsp;of&nbsp;library&nbsp;file&nbsp;names&nbsp;that&nbsp;should&nbsp;be&nbsp;included&nbsp;in&nbsp;the&nbsp;symfs.<br>
-&nbsp;&nbsp;use_symlinks:&nbsp;If&nbsp;True,&nbsp;link&nbsp;instead&nbsp;of&nbsp;copy&nbsp;unstripped&nbsp;libraries&nbsp;into&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;symfs.&nbsp;This&nbsp;will&nbsp;speed&nbsp;up&nbsp;the&nbsp;operation,&nbsp;but&nbsp;the&nbsp;resulting&nbsp;symfs&nbsp;will&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;longer&nbsp;be&nbsp;valid&nbsp;if&nbsp;the&nbsp;linked&nbsp;files&nbsp;are&nbsp;modified,&nbsp;e.g.,&nbsp;by&nbsp;rebuilding.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;absolute&nbsp;path&nbsp;to&nbsp;the&nbsp;kernel&nbsp;symbols&nbsp;within&nbsp;the&nbsp;created&nbsp;symfs.</tt></dd></dl>
- <dl><dt><a name="-GetPerfhostName"><strong>GetPerfhostName</strong></a>(*args, **kwargs)</dt></dl>
- <dl><dt><a name="-GetRequiredLibrariesForPerfProfile"><strong>GetRequiredLibrariesForPerfProfile</strong></a>(profile_file)</dt><dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;libraries&nbsp;necessary&nbsp;to&nbsp;symbolize&nbsp;a&nbsp;given&nbsp;perf&nbsp;profile.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;profile_file:&nbsp;Path&nbsp;to&nbsp;perf&nbsp;profile&nbsp;to&nbsp;analyse.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;set&nbsp;of&nbsp;required&nbsp;library&nbsp;file&nbsp;names.</tt></dd></dl>
- <dl><dt><a name="-GetRequiredLibrariesForVTuneProfile"><strong>GetRequiredLibrariesForVTuneProfile</strong></a>(profile_file)</dt><dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;libraries&nbsp;necessary&nbsp;to&nbsp;symbolize&nbsp;a&nbsp;given&nbsp;VTune&nbsp;profile.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;profile_file:&nbsp;Path&nbsp;to&nbsp;VTune&nbsp;profile&nbsp;to&nbsp;analyse.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;set&nbsp;of&nbsp;required&nbsp;library&nbsp;file&nbsp;names.</tt></dd></dl>
- <dl><dt><a name="-GetToolchainBinaryPath"><strong>GetToolchainBinaryPath</strong></a>(library_file, binary_name)</dt><dd><tt>Return&nbsp;the&nbsp;path&nbsp;to&nbsp;an&nbsp;Android&nbsp;toolchain&nbsp;binary&nbsp;on&nbsp;the&nbsp;host.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;library_file:&nbsp;ELF&nbsp;library&nbsp;which&nbsp;is&nbsp;used&nbsp;to&nbsp;identify&nbsp;the&nbsp;used&nbsp;ABI,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;architecture&nbsp;and&nbsp;toolchain.<br>
-&nbsp;&nbsp;binary_name:&nbsp;Binary&nbsp;to&nbsp;search&nbsp;for,&nbsp;e.g.,&nbsp;'objdump'<br>
-Returns:<br>
-&nbsp;&nbsp;Full&nbsp;path&nbsp;to&nbsp;binary&nbsp;or&nbsp;None&nbsp;if&nbsp;the&nbsp;binary&nbsp;was&nbsp;not&nbsp;found.</tt></dd></dl>
- <dl><dt><a name="-PrepareDeviceForPerf"><strong>PrepareDeviceForPerf</strong></a>(device)</dt><dd><tt>Set&nbsp;up&nbsp;a&nbsp;device&nbsp;for&nbsp;running&nbsp;perf.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;device:&nbsp;DeviceUtils&nbsp;instance&nbsp;identifying&nbsp;the&nbsp;target&nbsp;device.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;installed&nbsp;perf&nbsp;binary&nbsp;on&nbsp;the&nbsp;device.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_screen_recorder_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_screen_recorder_profiler.html
deleted file mode 100644
index b0fd553..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_screen_recorder_profiler.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.android_screen_recorder_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.android_screen_recorder_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/android_screen_recorder_profiler.py">telemetry/internal/platform/profiler/android_screen_recorder_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="pylib.screenshot.html">pylib.screenshot</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.android_screen_recorder_profiler.html#AndroidScreenRecordingProfiler">AndroidScreenRecordingProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidScreenRecordingProfiler">class <strong>AndroidScreenRecordingProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Captures&nbsp;a&nbsp;screen&nbsp;recording&nbsp;on&nbsp;Android.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.android_screen_recorder_profiler.html#AndroidScreenRecordingProfiler">AndroidScreenRecordingProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidScreenRecordingProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidScreenRecordingProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="AndroidScreenRecordingProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="AndroidScreenRecordingProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="AndroidScreenRecordingProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="AndroidScreenRecordingProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_systrace_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_systrace_profiler.html
deleted file mode 100644
index eeb0060..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_systrace_profiler.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.android_systrace_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.android_systrace_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/android_systrace_profiler.py">telemetry/internal/platform/profiler/android_systrace_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="StringIO.html">StringIO</a><br>
-<a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.tracing_options.html">telemetry.timeline.tracing_options</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="zipfile.html">zipfile</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.android_systrace_profiler.html#AndroidSystraceProfiler">AndroidSystraceProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidSystraceProfiler">class <strong>AndroidSystraceProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Collects&nbsp;a&nbsp;Systrace&nbsp;on&nbsp;Android.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.android_systrace_profiler.html#AndroidSystraceProfiler">AndroidSystraceProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidSystraceProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidSystraceProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state, device<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="AndroidSystraceProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="AndroidSystraceProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="AndroidSystraceProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="AndroidSystraceProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_traceview_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_traceview_profiler.html
deleted file mode 100644
index 38987a7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.android_traceview_profiler.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.android_traceview_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.android_traceview_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/android_traceview_profiler.py">telemetry/internal/platform/profiler/android_traceview_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-<a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.android_traceview_profiler.html#AndroidTraceviewProfiler">AndroidTraceviewProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AndroidTraceviewProfiler">class <strong>AndroidTraceviewProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Collects&nbsp;a&nbsp;Traceview&nbsp;on&nbsp;Android.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.android_traceview_profiler.html#AndroidTraceviewProfiler">AndroidTraceviewProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AndroidTraceviewProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AndroidTraceviewProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="AndroidTraceviewProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="AndroidTraceviewProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="AndroidTraceviewProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="AndroidTraceviewProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.html
deleted file mode 100644
index 36d9229..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.html
+++ /dev/null
@@ -1,105 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.platform.profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/__init__.py">telemetry/internal/platform/profiler/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html">android_prebuilt_profiler_helper</a><br>
-<a href="telemetry.internal.platform.profiler.android_profiling_helper.html">android_profiling_helper</a><br>
-<a href="telemetry.internal.platform.profiler.android_profiling_helper_unittest.html">android_profiling_helper_unittest</a><br>
-<a href="telemetry.internal.platform.profiler.android_screen_recorder_profiler.html">android_screen_recorder_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.android_screen_recorder_profiler_unittest.html">android_screen_recorder_profiler_unittest</a><br>
-<a href="telemetry.internal.platform.profiler.android_systrace_profiler.html">android_systrace_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.android_systrace_profiler_unittest.html">android_systrace_profiler_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.android_traceview_profiler.html">android_traceview_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.iprofiler_profiler.html">iprofiler_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.java_heap_profiler.html">java_heap_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.monsoon.html">monsoon</a><br>
-<a href="telemetry.internal.platform.profiler.monsoon_profiler.html">monsoon_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.netlog_profiler.html">netlog_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.oomkiller_profiler.html">oomkiller_profiler</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.perf_profiler.html">perf_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.perf_profiler_unittest.html">perf_profiler_unittest</a><br>
-<a href="telemetry.internal.platform.profiler.profiler_finder.html">profiler_finder</a><br>
-<a href="telemetry.internal.platform.profiler.sample_profiler.html">sample_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.strace_profiler.html">strace_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.tcmalloc_heap_profiler.html">tcmalloc_heap_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.tcpdump_profiler.html">tcpdump_profiler</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.trace_profiler.html">trace_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.trace_profiler_unittest.html">trace_profiler_unittest</a><br>
-<a href="telemetry.internal.platform.profiler.v8_profiler.html">v8_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.vtune_profiler.html">vtune_profiler</a><br>
-<a href="telemetry.internal.platform.profiler.vtune_profiler_unittest.html">vtune_profiler_unittest</a><br>
-<a href="telemetry.internal.platform.profiler.win_pgo_profiler.html">win_pgo_profiler</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">Profiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Profiler">class <strong>Profiler</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;sampling&nbsp;profiler&nbsp;provided&nbsp;by&nbsp;the&nbsp;platform.<br>
-&nbsp;<br>
-A&nbsp;profiler&nbsp;is&nbsp;started&nbsp;on&nbsp;its&nbsp;constructor,&nbsp;and&nbsp;should<br>
-gather&nbsp;data&nbsp;until&nbsp;<a href="#Profiler-CollectProfile">CollectProfile</a>().<br>
-The&nbsp;life&nbsp;cycle&nbsp;is&nbsp;normally&nbsp;tied&nbsp;to&nbsp;a&nbsp;single&nbsp;page,<br>
-i.e.,&nbsp;multiple&nbsp;profilers&nbsp;will&nbsp;be&nbsp;created&nbsp;for&nbsp;a&nbsp;page&nbsp;set.<br>
-<a href="#Profiler-WillCloseBrowser">WillCloseBrowser</a>()&nbsp;is&nbsp;called&nbsp;right&nbsp;before&nbsp;the&nbsp;browser<br>
-is&nbsp;closed&nbsp;to&nbsp;allow&nbsp;any&nbsp;further&nbsp;cleanup.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Profiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt><dd><tt>Collect&nbsp;the&nbsp;profile&nbsp;from&nbsp;the&nbsp;profiler.</tt></dd></dl>
-
-<dl><dt><a name="Profiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Profiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="Profiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<dl><dt><a name="Profiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>True&nbsp;iff&nbsp;this&nbsp;profiler&nbsp;is&nbsp;currently&nbsp;supported&nbsp;by&nbsp;the&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="Profiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>User-friendly&nbsp;name&nbsp;of&nbsp;this&nbsp;profiler.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.iprofiler_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.iprofiler_profiler.html
deleted file mode 100644
index 3a406de..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.iprofiler_profiler.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.iprofiler_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.iprofiler_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/iprofiler_profiler.py">telemetry/internal/platform/profiler/iprofiler_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="pexpect.html">pexpect</a><br>
-<a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="signal.html">signal</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.iprofiler_profiler.html#IprofilerProfiler">IprofilerProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IprofilerProfiler">class <strong>IprofilerProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.iprofiler_profiler.html#IprofilerProfiler">IprofilerProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="IprofilerProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="IprofilerProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="IprofilerProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="IprofilerProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="IprofilerProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="IprofilerProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.java_heap_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.java_heap_profiler.html
deleted file mode 100644
index 250501b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.java_heap_profiler.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.java_heap_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.java_heap_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/java_heap_profiler.py">telemetry/internal/platform/profiler/java_heap_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-<a href="pylib.constants.html">pylib.constants</a><br>
-<a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-<a href="threading.html">threading</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.java_heap_profiler.html#JavaHeapProfiler">JavaHeapProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="JavaHeapProfiler">class <strong>JavaHeapProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Android-specific,&nbsp;trigger&nbsp;and&nbsp;fetch&nbsp;java&nbsp;heap&nbsp;dumps.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.java_heap_profiler.html#JavaHeapProfiler">JavaHeapProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="JavaHeapProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="JavaHeapProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="JavaHeapProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="JavaHeapProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="JavaHeapProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="JavaHeapProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.monsoon.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.monsoon.html
deleted file mode 100644
index 9b8a4df..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.monsoon.html
+++ /dev/null
@@ -1,194 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.monsoon</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.monsoon</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/monsoon.py">telemetry/internal/platform/profiler/monsoon.py</a></font></td></tr></table>
-    <p><tt>Interface&nbsp;for&nbsp;a&nbsp;USB-connected&nbsp;<a href="#Monsoon">Monsoon</a>&nbsp;power&nbsp;meter.<br>
-&nbsp;<br>
-<a href="http://msoon.com/LabEquipment/PowerMonitor/">http://msoon.com/LabEquipment/PowerMonitor/</a><br>
-Currently&nbsp;Unix-only.&nbsp;Relies&nbsp;on&nbsp;fcntl,&nbsp;/dev,&nbsp;and&nbsp;/tmp.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="select.html">select</a><br>
-</td><td width="25%" valign=top><a href="serial.html">serial</a><br>
-<a href="struct.html">struct</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.monsoon.html#Monsoon">Monsoon</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#tuple">__builtin__.tuple</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.monsoon.html#Power">Power</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Monsoon">class <strong>Monsoon</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;a&nbsp;simple&nbsp;class&nbsp;to&nbsp;use&nbsp;the&nbsp;power&nbsp;meter.<br>
-&nbsp;<br>
-mon&nbsp;=&nbsp;monsoon.<a href="#Monsoon">Monsoon</a>()<br>
-mon.<a href="#Monsoon-SetVoltage">SetVoltage</a>(3.7)<br>
-mon.<a href="#Monsoon-StartDataCollection">StartDataCollection</a>()<br>
-mydata&nbsp;=&nbsp;[]<br>
-while&nbsp;len(mydata)&nbsp;&lt;&nbsp;1000:<br>
-&nbsp;&nbsp;mydata.extend(mon.<a href="#Monsoon-CollectData">CollectData</a>())<br>
-mon.<a href="#Monsoon-StopDataCollection">StopDataCollection</a>()<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Monsoon-CollectData"><strong>CollectData</strong></a>(self)</dt><dd><tt>Return&nbsp;some&nbsp;current&nbsp;samples.&nbsp;&nbsp;Call&nbsp;<a href="#Monsoon-StartDataCollection">StartDataCollection</a>()&nbsp;first.</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-GetStatus"><strong>GetStatus</strong></a>(self)</dt><dd><tt>Requests&nbsp;and&nbsp;waits&nbsp;for&nbsp;status.&nbsp;&nbsp;Returns&nbsp;status&nbsp;dictionary.</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-SetMaxCurrent"><strong>SetMaxCurrent</strong></a>(self, a)</dt><dd><tt>Set&nbsp;the&nbsp;max&nbsp;output&nbsp;current.&nbsp;the&nbsp;unit&nbsp;of&nbsp;|a|&nbsp;:&nbsp;Amperes</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-SetStartupCurrent"><strong>SetStartupCurrent</strong></a>(self, a)</dt><dd><tt>Set&nbsp;the&nbsp;max&nbsp;startup&nbsp;output&nbsp;current.&nbsp;the&nbsp;unit&nbsp;of&nbsp;|a|&nbsp;:&nbsp;Amperes</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-SetUsbPassthrough"><strong>SetUsbPassthrough</strong></a>(self, val)</dt><dd><tt>Set&nbsp;the&nbsp;USB&nbsp;passthrough&nbsp;mode:&nbsp;0&nbsp;=&nbsp;off,&nbsp;1&nbsp;=&nbsp;on,&nbsp;&nbsp;2&nbsp;=&nbsp;auto.</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-SetVoltage"><strong>SetVoltage</strong></a>(self, v)</dt><dd><tt>Set&nbsp;the&nbsp;output&nbsp;voltage,&nbsp;0&nbsp;to&nbsp;disable.</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-StartDataCollection"><strong>StartDataCollection</strong></a>(self)</dt><dd><tt>Tell&nbsp;the&nbsp;device&nbsp;to&nbsp;start&nbsp;collecting&nbsp;and&nbsp;sending&nbsp;measurement&nbsp;data.</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-StopDataCollection"><strong>StopDataCollection</strong></a>(self)</dt><dd><tt>Tell&nbsp;the&nbsp;device&nbsp;to&nbsp;stop&nbsp;collecting&nbsp;measurement&nbsp;data.</tt></dd></dl>
-
-<dl><dt><a name="Monsoon-__init__"><strong>__init__</strong></a>(self, device<font color="#909090">=None</font>, serialno<font color="#909090">=None</font>, wait<font color="#909090">=True</font>)</dt><dd><tt>Establish&nbsp;a&nbsp;connection&nbsp;to&nbsp;a&nbsp;<a href="#Monsoon">Monsoon</a>.<br>
-&nbsp;<br>
-By&nbsp;default,&nbsp;opens&nbsp;the&nbsp;first&nbsp;available&nbsp;port,&nbsp;waiting&nbsp;if&nbsp;none&nbsp;are&nbsp;ready.<br>
-A&nbsp;particular&nbsp;port&nbsp;can&nbsp;be&nbsp;specified&nbsp;with&nbsp;'device',&nbsp;or&nbsp;a&nbsp;particular&nbsp;<a href="#Monsoon">Monsoon</a><br>
-can&nbsp;be&nbsp;specified&nbsp;with&nbsp;'serialno'&nbsp;(using&nbsp;the&nbsp;number&nbsp;printed&nbsp;on&nbsp;its&nbsp;back).<br>
-With&nbsp;wait=False,&nbsp;IOError&nbsp;is&nbsp;thrown&nbsp;if&nbsp;a&nbsp;device&nbsp;is&nbsp;not&nbsp;immediately&nbsp;available.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Power">class <strong>Power</strong></a>(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#Power">Power</a>(amps,&nbsp;volts)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.monsoon.html#Power">Power</a></dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Power-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;<a href="__builtin__.html#tuple">tuple</a>.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="Power-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="Power-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="Power-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="Power-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#Power">Power</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Power-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#Power">Power</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="Power-__new__"><strong>__new__</strong></a>(_cls, amps, volts)</dt><dd><tt>Create&nbsp;new&nbsp;instance&nbsp;of&nbsp;<a href="#Power">Power</a>(amps,&nbsp;volts)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd>
-</dl>
-<dl><dt><strong>amps</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<dl><dt><strong>volts</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>_fields</strong> = ('amps', 'volts')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="Power-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="Power-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="Power-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="Power-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="Power-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Power-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="Power-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="Power-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="Power-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="Power-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="Power-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="Power-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="Power-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="Power-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="Power-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="Power-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#Power-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="Power-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#Power-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="Power-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#Power-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="Power-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#Power-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.monsoon_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.monsoon_profiler.html
deleted file mode 100644
index a360bb1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.monsoon_profiler.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.monsoon_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.monsoon_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/monsoon_profiler.py">telemetry/internal/platform/profiler/monsoon_profiler.py</a></font></td></tr></table>
-    <p><tt><a href="telemetry.internal.platform.profiler.html#Profiler">Profiler</a>&nbsp;using&nbsp;data&nbsp;collected&nbsp;from&nbsp;a&nbsp;Monsoon&nbsp;power&nbsp;meter.<br>
-&nbsp;<br>
-<a href="http://msoon.com/LabEquipment/PowerMonitor/">http://msoon.com/LabEquipment/PowerMonitor/</a><br>
-Data&nbsp;collected&nbsp;is&nbsp;a&nbsp;namedtuple&nbsp;of&nbsp;(amps,&nbsp;volts),&nbsp;at&nbsp;5000&nbsp;samples/second.<br>
-Output&nbsp;graph&nbsp;plots&nbsp;power&nbsp;in&nbsp;watts&nbsp;over&nbsp;time&nbsp;in&nbsp;seconds.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="csv.html">csv</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.monsoon.html">telemetry.internal.platform.profiler.monsoon</a><br>
-<a href="multiprocessing.html">multiprocessing</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="telemetry.util.statistics.html">telemetry.util.statistics</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.monsoon_profiler.html#MonsoonProfiler">MonsoonProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MonsoonProfiler">class <strong>MonsoonProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.monsoon_profiler.html#MonsoonProfiler">MonsoonProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MonsoonProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MonsoonProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="MonsoonProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="MonsoonProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="MonsoonProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="MonsoonProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.netlog_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.netlog_profiler.html
deleted file mode 100644
index 60b7031..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.netlog_profiler.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.netlog_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.netlog_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/netlog_profiler.py">telemetry/internal/platform/profiler/netlog_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.netlog_profiler.html#NetLogProfiler">NetLogProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NetLogProfiler">class <strong>NetLogProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.netlog_profiler.html#NetLogProfiler">NetLogProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="NetLogProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="NetLogProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="NetLogProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="NetLogProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="NetLogProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="NetLogProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.oomkiller_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.oomkiller_profiler.html
deleted file mode 100644
index 98adf55..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.oomkiller_profiler.html
+++ /dev/null
@@ -1,151 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.oomkiller_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.oomkiller_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/oomkiller_profiler.py">telemetry/internal/platform/profiler/oomkiller_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-</td><td width="25%" valign=top><a href="devil.android.sdk.intent.html">devil.android.sdk.intent</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.oomkiller_profiler.html#UnableToFindApplicationException">UnableToFindApplicationException</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.oomkiller_profiler.html#OOMKillerProfiler">OOMKillerProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="OOMKillerProfiler">class <strong>OOMKillerProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Android-specific,&nbsp;Launch&nbsp;the&nbsp;music&nbsp;application&nbsp;and&nbsp;check&nbsp;it&nbsp;is&nbsp;still&nbsp;alive<br>
-at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;run.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.oomkiller_profiler.html#OOMKillerProfiler">OOMKillerProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="OOMKillerProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="OOMKillerProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="OOMKillerProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="OOMKillerProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="OOMKillerProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="OOMKillerProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="UnableToFindApplicationException">class <strong>UnableToFindApplicationException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="exceptions.html#Exception">Exception</a>&nbsp;when&nbsp;unable&nbsp;to&nbsp;find&nbsp;a&nbsp;launched&nbsp;application<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.oomkiller_profiler.html#UnableToFindApplicationException">UnableToFindApplicationException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="UnableToFindApplicationException-__init__"><strong>__init__</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#UnableToFindApplicationException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="UnableToFindApplicationException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#UnableToFindApplicationException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#UnableToFindApplicationException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#UnableToFindApplicationException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#UnableToFindApplicationException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#UnableToFindApplicationException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#UnableToFindApplicationException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="UnableToFindApplicationException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.perf_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.perf_profiler.html
deleted file mode 100644
index 0cea1c7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.perf_profiler.html
+++ /dev/null
@@ -1,93 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.perf_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.perf_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/perf_profiler.py">telemetry/internal/platform/profiler/perf_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.android_profiling_helper.html">telemetry.internal.platform.profiler.android_profiling_helper</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="devil.android.device_errors.html">devil.android.device_errors</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="devil.android.perf.perf_control.html">devil.android.perf.perf_control</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="signal.html">signal</a><br>
-<a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="tempfile.html">tempfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.perf_profiler.html#PerfProfiler">PerfProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PerfProfiler">class <strong>PerfProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.perf_profiler.html#PerfProfiler">PerfProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PerfProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PerfProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="PerfProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="PerfProfiler-GetTopSamples"><strong>GetTopSamples</strong></a>(cls, file_name, number)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Parses&nbsp;the&nbsp;perf&nbsp;generated&nbsp;profile&nbsp;in&nbsp;|file_name|&nbsp;and&nbsp;returns&nbsp;a<br>
-{function:&nbsp;period}&nbsp;dict&nbsp;of&nbsp;the&nbsp;|number|&nbsp;hottests&nbsp;functions.</tt></dd></dl>
-
-<dl><dt><a name="PerfProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="PerfProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="PerfProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.profiler_finder.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.profiler_finder.html
deleted file mode 100644
index ba02cbf..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.profiler_finder.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.profiler_finder</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.profiler_finder</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/profiler_finder.py">telemetry/internal/platform/profiler/profiler_finder.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindProfiler"><strong>FindProfiler</strong></a>(name)</dt></dl>
- <dl><dt><a name="-GetAllAvailableProfilers"><strong>GetAllAvailableProfilers</strong></a>()</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.sample_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.sample_profiler.html
deleted file mode 100644
index f6823e4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.sample_profiler.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.sample_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.sample_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/sample_profiler.py">telemetry/internal/platform/profiler/sample_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="signal.html">signal</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.sample_profiler.html#SampleProfiler">SampleProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SampleProfiler">class <strong>SampleProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.sample_profiler.html#SampleProfiler">SampleProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SampleProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SampleProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="SampleProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="SampleProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="SampleProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="SampleProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.strace_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.strace_profiler.html
deleted file mode 100644
index 117ee86..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.strace_profiler.html
+++ /dev/null
@@ -1,87 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.strace_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.strace_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/strace_profiler.py">telemetry/internal/platform/profiler/strace_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="logging.html">logging</a><br>
-<a href="telemetry.timeline.model.html">telemetry.timeline.model</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="re.html">re</a><br>
-<a href="signal.html">signal</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.strace_profiler.html#StraceProfiler">StraceProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StraceProfiler">class <strong>StraceProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.strace_profiler.html#StraceProfiler">StraceProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="StraceProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StraceProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="StraceProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="StraceProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="StraceProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="StraceProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.tcmalloc_heap_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.tcmalloc_heap_profiler.html
deleted file mode 100644
index bb392e1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.tcmalloc_heap_profiler.html
+++ /dev/null
@@ -1,82 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.tcmalloc_heap_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.tcmalloc_heap_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/tcmalloc_heap_profiler.py">telemetry/internal/platform/profiler/tcmalloc_heap_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.backends.chrome.android_browser_finder.html">telemetry.internal.backends.chrome.android_browser_finder</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.tcmalloc_heap_profiler.html#TCMallocHeapProfiler">TCMallocHeapProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TCMallocHeapProfiler">class <strong>TCMallocHeapProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;Factory&nbsp;to&nbsp;instantiate&nbsp;the&nbsp;platform-specific&nbsp;profiler.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.tcmalloc_heap_profiler.html#TCMallocHeapProfiler">TCMallocHeapProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TCMallocHeapProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TCMallocHeapProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TCMallocHeapProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TCMallocHeapProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TCMallocHeapProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TCMallocHeapProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.tcpdump_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.tcpdump_profiler.html
deleted file mode 100644
index 4b0f44c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.tcpdump_profiler.html
+++ /dev/null
@@ -1,87 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.tcpdump_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.tcpdump_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/tcpdump_profiler.py">telemetry/internal/platform/profiler/tcpdump_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.android_prebuilt_profiler_helper.html">telemetry.internal.platform.profiler.android_prebuilt_profiler_helper</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="signal.html">signal</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.tcpdump_profiler.html#TCPDumpProfiler">TCPDumpProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TCPDumpProfiler">class <strong>TCPDumpProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;Factory&nbsp;to&nbsp;instantiate&nbsp;the&nbsp;platform-specific&nbsp;profiler.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.tcpdump_profiler.html#TCPDumpProfiler">TCPDumpProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TCPDumpProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TCPDumpProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TCPDumpProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TCPDumpProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="TCPDumpProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="TCPDumpProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.trace_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.trace_profiler.html
deleted file mode 100644
index 38b36e0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.trace_profiler.html
+++ /dev/null
@@ -1,175 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.trace_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.trace_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/trace_profiler.py">telemetry/internal/platform/profiler/trace_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="StringIO.html">StringIO</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.tracing_options.html">telemetry.timeline.tracing_options</a><br>
-<a href="zipfile.html">zipfile</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceAllProfiler">TraceAllProfiler</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceDetailedProfiler">TraceDetailedProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceAllProfiler">class <strong>TraceAllProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceAllProfiler">TraceAllProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TraceAllProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TraceAllProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>:<br>
-<dl><dt><a name="TraceAllProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>:<br>
-<dl><dt><a name="TraceAllProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="TraceAllProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="TraceAllProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceDetailedProfiler">class <strong>TraceDetailedProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceDetailedProfiler">TraceDetailedProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TraceDetailedProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TraceDetailedProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>:<br>
-<dl><dt><a name="TraceDetailedProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a>:<br>
-<dl><dt><a name="TraceDetailedProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="TraceDetailedProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="TraceDetailedProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceProfiler">class <strong>TraceProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.trace_profiler.html#TraceProfiler">TraceProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TraceProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state, categories<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TraceProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TraceProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="TraceProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;Browser's&nbsp;options&nbsp;before&nbsp;it&nbsp;is&nbsp;created.</tt></dd></dl>
-
-<dl><dt><a name="TraceProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.v8_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.v8_profiler.html
deleted file mode 100644
index ff563d4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.v8_profiler.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.v8_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.v8_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/v8_profiler.py">telemetry/internal/platform/profiler/v8_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="tempfile.html">tempfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.v8_profiler.html#V8Profiler">V8Profiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="V8Profiler">class <strong>V8Profiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.v8_profiler.html#V8Profiler">V8Profiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="V8Profiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="V8Profiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="V8Profiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="V8Profiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="V8Profiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="V8Profiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.vtune_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.vtune_profiler.html
deleted file mode 100644
index ebafcb6..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.vtune_profiler.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.vtune_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.vtune_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/vtune_profiler.py">telemetry/internal/platform/profiler/vtune_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.android_profiling_helper.html">telemetry.internal.platform.profiler.android_profiling_helper</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.vtune_profiler.html#VTuneProfiler">VTuneProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="VTuneProfiler">class <strong>VTuneProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.vtune_profiler.html#VTuneProfiler">VTuneProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="VTuneProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="VTuneProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="VTuneProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="VTuneProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="VTuneProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="VTuneProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.win_pgo_profiler.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.win_pgo_profiler.html
deleted file mode 100644
index 09063e4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiler.win_pgo_profiler.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiler.win_pgo_profiler</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.profiler.html"><font color="#ffffff">profiler</font></a>.win_pgo_profiler</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiler/win_pgo_profiler.py">telemetry/internal/platform/profiler/win_pgo_profiler.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="glob.html">glob</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.html">telemetry.internal.platform.profiler</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiler.win_pgo_profiler.html#WinPGOProfiler">WinPGOProfiler</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WinPGOProfiler">class <strong>WinPGOProfiler</strong></a>(<a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;profiler&nbsp;that&nbsp;run&nbsp;the&nbsp;Visual&nbsp;Studio&nbsp;PGO&nbsp;utility&nbsp;'pgosweep.exe'&nbsp;before<br>
-terminating&nbsp;a&nbsp;browser&nbsp;or&nbsp;a&nbsp;renderer&nbsp;process.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.profiler.win_pgo_profiler.html#WinPGOProfiler">WinPGOProfiler</a></dd>
-<dd><a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="WinPGOProfiler-CollectProfile"><strong>CollectProfile</strong></a>(self)</dt><dd><tt>Collect&nbsp;the&nbsp;profile&nbsp;data&nbsp;for&nbsp;the&nbsp;current&nbsp;processes.</tt></dd></dl>
-
-<dl><dt><a name="WinPGOProfiler-__init__"><strong>__init__</strong></a>(self, browser_backend, platform_backend, output_path, state)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="WinPGOProfiler-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, browser_type, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="WinPGOProfiler-is_supported"><strong>is_supported</strong></a>(cls, browser_type)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="WinPGOProfiler-name"><strong>name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><a name="WinPGOProfiler-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(cls, browser_backend, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;stopped.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.profiler.html#Profiler">telemetry.internal.platform.profiler.Profiler</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiling_controller_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiling_controller_backend.html
deleted file mode 100644
index b0abf19..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.profiling_controller_backend.html
+++ /dev/null
@@ -1,68 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.profiling_controller_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.profiling_controller_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/profiling_controller_backend.py">telemetry/internal/platform/profiling_controller_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.profiler_finder.html">telemetry.internal.platform.profiler.profiler_finder</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.profiling_controller_backend.html#ProfilingControllerBackend">ProfilingControllerBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProfilingControllerBackend">class <strong>ProfilingControllerBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ProfilingControllerBackend-Start"><strong>Start</strong></a>(self, profiler_name, base_output_file)</dt><dd><tt>Starts&nbsp;profiling&nbsp;using&nbsp;|profiler_name|.&nbsp;Results&nbsp;are&nbsp;saved&nbsp;to<br>
-|base_output_file|.&lt;process_name&gt;.</tt></dd></dl>
-
-<dl><dt><a name="ProfilingControllerBackend-Stop"><strong>Stop</strong></a>(self)</dt><dd><tt>Stops&nbsp;all&nbsp;active&nbsp;profilers&nbsp;and&nbsp;saves&nbsp;their&nbsp;results.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;filenames&nbsp;produced&nbsp;by&nbsp;the&nbsp;profiler.</tt></dd></dl>
-
-<dl><dt><a name="ProfilingControllerBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ProfilingControllerBackend-__init__"><strong>__init__</strong></a>(self, platform_backend, browser_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.system_info.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.system_info.html
deleted file mode 100644
index d20e988..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.system_info.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.system_info</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.system_info</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/system_info.py">telemetry/internal/platform/system_info.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.gpu_info.html">telemetry.internal.platform.gpu_info</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.system_info.html#SystemInfo">SystemInfo</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SystemInfo">class <strong>SystemInfo</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Provides&nbsp;low-level&nbsp;system&nbsp;information.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="SystemInfo-__init__"><strong>__init__</strong></a>(self, model_name, gpu_dict)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="SystemInfo-FromDict"><strong>FromDict</strong></a>(cls, attrs)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="#SystemInfo">SystemInfo</a>&nbsp;from&nbsp;a&nbsp;dictionary&nbsp;of&nbsp;attributes.<br>
-Attributes&nbsp;currently&nbsp;required&nbsp;to&nbsp;be&nbsp;present&nbsp;in&nbsp;the&nbsp;dictionary:<br>
-&nbsp;<br>
-&nbsp;&nbsp;model_name&nbsp;(string):&nbsp;a&nbsp;platform-dependent&nbsp;string<br>
-&nbsp;&nbsp;&nbsp;&nbsp;describing&nbsp;the&nbsp;model&nbsp;of&nbsp;machine,&nbsp;or&nbsp;the&nbsp;empty&nbsp;string&nbsp;if&nbsp;not<br>
-&nbsp;&nbsp;&nbsp;&nbsp;supported.<br>
-&nbsp;&nbsp;gpu&nbsp;(<a href="__builtin__.html#object">object</a>&nbsp;containing&nbsp;GPUInfo's&nbsp;required&nbsp;attributes)</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>gpu</strong></dt>
-<dd><tt>A&nbsp;GPUInfo&nbsp;object&nbsp;describing&nbsp;the&nbsp;graphics&nbsp;processor(s)&nbsp;on&nbsp;the&nbsp;system.</tt></dd>
-</dl>
-<dl><dt><strong>model_name</strong></dt>
-<dd><tt>A&nbsp;string&nbsp;describing&nbsp;the&nbsp;machine&nbsp;model.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;a&nbsp;highly&nbsp;platform-dependent&nbsp;value&nbsp;and&nbsp;not&nbsp;currently<br>
-specified&nbsp;for&nbsp;any&nbsp;machine&nbsp;type&nbsp;aside&nbsp;from&nbsp;Macs.&nbsp;On&nbsp;Mac&nbsp;OS,&nbsp;this<br>
-is&nbsp;the&nbsp;model&nbsp;identifier,&nbsp;reformatted&nbsp;slightly;&nbsp;for&nbsp;example,<br>
-'MacBookPro&nbsp;10.1'.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html
deleted file mode 100644
index 150718c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html
+++ /dev/null
@@ -1,211 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.tracing_agent.chrome_tracing_agent</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.tracing_agent.html"><font color="#ffffff">tracing_agent</font></a>.chrome_tracing_agent</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/tracing_agent/chrome_tracing_agent.py">telemetry/internal/platform/tracing_agent/chrome_tracing_agent.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager.html">telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager</a><br>
-<a href="os.html">os</a><br>
-<a href="shutil.html">shutil</a><br>
-</td><td width="25%" valign=top><a href="stat.html">stat</a><br>
-<a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top><a href="traceback.html">traceback</a><br>
-<a href="telemetry.internal.platform.tracing_agent.html">telemetry.internal.platform.tracing_agent</a><br>
-<a href="telemetry.timeline.tracing_config.html">telemetry.timeline.tracing_config</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html#ChromeTracingStartedError">ChromeTracingStartedError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html#ChromeTracingStoppedError">ChromeTracingStoppedError</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html#ChromeTracingAgent">ChromeTracingAgent</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChromeTracingAgent">class <strong>ChromeTracingAgent</strong></a>(<a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html#ChromeTracingAgent">ChromeTracingAgent</a></dd>
-<dd><a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ChromeTracingAgent-Start"><strong>Start</strong></a>(self, trace_options, category_filter, timeout)</dt></dl>
-
-<dl><dt><a name="ChromeTracingAgent-Stop"><strong>Stop</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="ChromeTracingAgent-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="ChromeTracingAgent-IsStartupTracingSupported"><strong>IsStartupTracingSupported</strong></a>(cls, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="ChromeTracingAgent-IsSupported"><strong>IsSupported</strong></a>(cls, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>trace_config</strong></dt>
-</dl>
-<dl><dt><strong>trace_config_file</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChromeTracingStartedError">class <strong>ChromeTracingStartedError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html#ChromeTracingStartedError">ChromeTracingStartedError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ChromeTracingStartedError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ChromeTracingStartedError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ChromeTracingStartedError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStartedError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStartedError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChromeTracingStoppedError">class <strong>ChromeTracingStoppedError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html#ChromeTracingStoppedError">ChromeTracingStoppedError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ChromeTracingStoppedError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ChromeTracingStoppedError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ChromeTracingStoppedError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ChromeTracingStoppedError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ChromeTracingStoppedError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager.html
deleted file mode 100644
index ef6e46e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.tracing_agent.html"><font color="#ffffff">tracing_agent</font></a>.chrome_tracing_devtools_manager</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/tracing_agent/chrome_tracing_devtools_manager.py">telemetry/internal/platform/tracing_agent/chrome_tracing_devtools_manager.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetActiveDevToolsClients"><strong>GetActiveDevToolsClients</strong></a>(platform_backend)</dt><dd><tt>Get&nbsp;DevTools&nbsp;clients&nbsp;that&nbsp;are&nbsp;still&nbsp;connectable.</tt></dd></dl>
- <dl><dt><a name="-GetDevToolsClients"><strong>GetDevToolsClients</strong></a>(platform_backend)</dt><dd><tt>Get&nbsp;DevTools&nbsp;clients&nbsp;including&nbsp;the&nbsp;ones&nbsp;that&nbsp;are&nbsp;no&nbsp;longer&nbsp;connectable.</tt></dd></dl>
- <dl><dt><a name="-IsSupported"><strong>IsSupported</strong></a>(platform_backend)</dt></dl>
- <dl><dt><a name="-RegisterDevToolsClient"><strong>RegisterDevToolsClient</strong></a>(devtools_client_backend, platform_backend)</dt><dd><tt>Register&nbsp;DevTools&nbsp;client<br>
-&nbsp;<br>
-This&nbsp;should&nbsp;only&nbsp;be&nbsp;called&nbsp;from&nbsp;DevToolsClientBackend&nbsp;when&nbsp;it&nbsp;is&nbsp;initialized.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.display_tracing_agent.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.display_tracing_agent.html
deleted file mode 100644
index 1707a83..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.display_tracing_agent.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.tracing_agent.display_tracing_agent</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.<a href="telemetry.internal.platform.tracing_agent.html"><font color="#ffffff">tracing_agent</font></a>.display_tracing_agent</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/tracing_agent/display_tracing_agent.py">telemetry/internal/platform/tracing_agent/display_tracing_agent.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.html">telemetry.internal.platform.tracing_agent</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.display_tracing_agent.html#DisplayTracingAgent">DisplayTracingAgent</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DisplayTracingAgent">class <strong>DisplayTracingAgent</strong></a>(<a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.tracing_agent.display_tracing_agent.html#DisplayTracingAgent">DisplayTracingAgent</a></dd>
-<dd><a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DisplayTracingAgent-Start"><strong>Start</strong></a>(self, trace_options, category_filter, _timeout)</dt></dl>
-
-<dl><dt><a name="DisplayTracingAgent-Stop"><strong>Stop</strong></a>(self, trace_data_builder)</dt></dl>
-
-<dl><dt><a name="DisplayTracingAgent-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="DisplayTracingAgent-IsSupported"><strong>IsSupported</strong></a>(cls, platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">telemetry.internal.platform.tracing_agent.TracingAgent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.html
deleted file mode 100644
index dbf6213..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_agent.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.platform.tracing_agent</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.tracing_agent</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/tracing_agent/__init__.py">telemetry/internal/platform/tracing_agent/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html">chrome_tracing_agent</a><br>
-<a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent_unittest.html">chrome_tracing_agent_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_devtools_manager.html">chrome_tracing_devtools_manager</a><br>
-<a href="telemetry.internal.platform.tracing_agent.display_tracing_agent.html">display_tracing_agent</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.display_tracing_agent_unittest.html">display_tracing_agent_unittest</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_agent.html#TracingAgent">TracingAgent</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingAgent">class <strong>TracingAgent</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;tracing&nbsp;agent&nbsp;provided&nbsp;by&nbsp;the&nbsp;platform.<br>
-&nbsp;<br>
-A&nbsp;tracing&nbsp;agent&nbsp;can&nbsp;gather&nbsp;data&nbsp;with&nbsp;<a href="#TracingAgent-Start">Start</a>()&nbsp;until&nbsp;<a href="#TracingAgent-Stop">Stop</a>().<br>
-Before&nbsp;constructing&nbsp;an&nbsp;<a href="#TracingAgent">TracingAgent</a>,&nbsp;check&nbsp;whether&nbsp;it's&nbsp;supported&nbsp;on&nbsp;the<br>
-platform&nbsp;with&nbsp;IsSupported&nbsp;method&nbsp;first.<br>
-&nbsp;<br>
-NOTE:&nbsp;All&nbsp;subclasses&nbsp;of&nbsp;<a href="#TracingAgent">TracingAgent</a>&nbsp;must&nbsp;not&nbsp;change&nbsp;the&nbsp;constructor's<br>
-parameters&nbsp;so&nbsp;the&nbsp;agents&nbsp;can&nbsp;be&nbsp;dynamically&nbsp;constructed&nbsp;in<br>
-tracing_controller_backend.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingAgent-Start"><strong>Start</strong></a>(self, trace_options, category_filter, timeout)</dt><dd><tt>Override&nbsp;to&nbsp;add&nbsp;tracing&nbsp;agent's&nbsp;custom&nbsp;logic&nbsp;to&nbsp;start&nbsp;tracing.<br>
-&nbsp;<br>
-Depending&nbsp;on&nbsp;trace_options&nbsp;and&nbsp;category_filter,&nbsp;the&nbsp;tracing&nbsp;agent&nbsp;may&nbsp;choose<br>
-to&nbsp;start&nbsp;or&nbsp;not&nbsp;start&nbsp;tracing.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;trace_options:&nbsp;an&nbsp;instance&nbsp;of&nbsp;tracing_options.TracingOptions&nbsp;that<br>
-&nbsp;&nbsp;&nbsp;&nbsp;control&nbsp;which&nbsp;core&nbsp;tracing&nbsp;systems&nbsp;should&nbsp;be&nbsp;enabled.<br>
-&nbsp;&nbsp;category_filter:&nbsp;an&nbsp;instance&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tracing_category_filter.TracingCategoryFilter<br>
-&nbsp;&nbsp;timeout:&nbsp;number&nbsp;of&nbsp;seconds&nbsp;that&nbsp;this&nbsp;tracing&nbsp;agent&nbsp;should&nbsp;try&nbsp;to&nbsp;start<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tracing&nbsp;until&nbsp;time&nbsp;out.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;tracing&nbsp;agent&nbsp;started&nbsp;succesfully.</tt></dd></dl>
-
-<dl><dt><a name="TracingAgent-Stop"><strong>Stop</strong></a>(self, trace_data_builder)</dt><dd><tt>Override&nbsp;to&nbsp;add&nbsp;tracing&nbsp;agent's&nbsp;custom&nbsp;logic&nbsp;to&nbsp;stop&nbsp;tracing.<br>
-&nbsp;<br>
-<a href="#TracingAgent-Stop">Stop</a>()&nbsp;should&nbsp;guarantee&nbsp;tracing&nbsp;is&nbsp;stopped,&nbsp;even&nbsp;if&nbsp;there&nbsp;may&nbsp;be&nbsp;exception.</tt></dd></dl>
-
-<dl><dt><a name="TracingAgent-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TracingAgent-IsSupported"><strong>IsSupported</strong></a>(cls, _platform_backend)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_controller_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_controller_backend.html
deleted file mode 100644
index 1059365..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.tracing_controller_backend.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.tracing_controller_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.tracing_controller_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/tracing_controller_backend.py">telemetry/internal/platform/tracing_controller_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.chrome_tracing_agent.html">telemetry.internal.platform.tracing_agent.chrome_tracing_agent</a><br>
-<a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-<a href="traceback.html">traceback</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.tracing_agent.html">telemetry.internal.platform.tracing_agent</a><br>
-<a href="telemetry.timeline.tracing_category_filter.html">telemetry.timeline.tracing_category_filter</a><br>
-<a href="telemetry.timeline.tracing_options.html">telemetry.timeline.tracing_options</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_controller_backend.html#TracingControllerBackend">TracingControllerBackend</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.tracing_controller_backend.html#TracingControllerStoppedError">TracingControllerStoppedError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingControllerBackend">class <strong>TracingControllerBackend</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingControllerBackend-GetChromeTraceConfig"><strong>GetChromeTraceConfig</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingControllerBackend-GetChromeTraceConfigFile"><strong>GetChromeTraceConfigFile</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingControllerBackend-IsChromeTracingSupported"><strong>IsChromeTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingControllerBackend-Start"><strong>Start</strong></a>(self, trace_options, category_filter, timeout)</dt></dl>
-
-<dl><dt><a name="TracingControllerBackend-Stop"><strong>Stop</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingControllerBackend-__init__"><strong>__init__</strong></a>(self, platform_backend)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_tracing_running</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingControllerStoppedError">class <strong>TracingControllerStoppedError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.tracing_controller_backend.html#TracingControllerStoppedError">TracingControllerStoppedError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TracingControllerStoppedError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TracingControllerStoppedError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TracingControllerStoppedError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TracingControllerStoppedError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TracingControllerStoppedError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.trybot_device.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.trybot_device.html
deleted file mode 100644
index 34b3388..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.trybot_device.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.trybot_device</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.trybot_device</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/trybot_device.py">telemetry/internal/platform/trybot_device.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.platform.device.html">telemetry.internal.platform.device</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.trybot_device.html#TrybotDevice">TrybotDevice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TrybotDevice">class <strong>TrybotDevice</strong></a>(<a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.trybot_device.html#TrybotDevice">TrybotDevice</a></dd>
-<dd><a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TrybotDevice-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TrybotDevice-GetAllConnectedDevices"><strong>GetAllConnectedDevices</strong></a>(cls, blacklist)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.device.html#Device">telemetry.internal.platform.device.Device</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>guid</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindAllAvailableDevices"><strong>FindAllAvailableDevices</strong></a>(_)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;available&nbsp;devices.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.win_platform_backend.html b/catapult/telemetry/docs/pydoc/telemetry.internal.platform.win_platform_backend.html
deleted file mode 100644
index d08b9ea..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.platform.win_platform_backend.html
+++ /dev/null
@@ -1,261 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.platform.win_platform_backend</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.platform.html"><font color="#ffffff">platform</font></a>.win_platform_backend</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/platform/win_platform_backend.py">telemetry/internal/platform/win_platform_backend.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="atexit.html">atexit</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="collections.html">collections</a><br>
-<a href="contextlib.html">contextlib</a><br>
-<a href="ctypes.html">ctypes</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.desktop_platform_backend.html">telemetry.internal.platform.desktop_platform_backend</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-<a href="telemetry.internal.platform.power_monitor.msr_power_monitor.html">telemetry.internal.platform.power_monitor.msr_power_monitor</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.core.os_version.html">telemetry.core.os_version</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-<a href="platform.html">platform</a><br>
-<a href="re.html">re</a><br>
-<a href="socket.html">socket</a><br>
-<a href="struct.html">struct</a><br>
-<a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="time.html">time</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="zipfile.html">zipfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>(<a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.win_platform_backend.html#WinPlatformBackend">WinPlatformBackend</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WinPlatformBackend">class <strong>WinPlatformBackend</strong></a>(<a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.platform.win_platform_backend.html#WinPlatformBackend">WinPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a></dd>
-<dd><a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="WinPlatformBackend-CanFlushIndividualFilesFromSystemCache"><strong>CanFlushIndividualFilesFromSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CanMeasurePerApplicationPower"><strong>CanMeasurePerApplicationPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CanMonitorPower"><strong>CanMonitorPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CloseMsrServer"><strong>CloseMsrServer</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CooperativelyShutdown"><strong>CooperativelyShutdown</strong></a>(self, proc, app_name)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetArchName"><strong>GetArchName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetChildPids"><strong>GetChildPids</strong></a>(self, pid)</dt><dd><tt>Retunds&nbsp;a&nbsp;list&nbsp;of&nbsp;child&nbsp;pids&nbsp;of&nbsp;|pid|.</tt></dd></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetCommandLine"><strong>GetCommandLine</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetCpuStats"><strong>GetCpuStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetCpuTimestamp"><strong>GetCpuTimestamp</strong></a>(self)</dt><dd><tt>Return&nbsp;current&nbsp;timestamp&nbsp;in&nbsp;seconds.</tt></dd></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetMemoryStats"><strong>GetMemoryStats</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetOSVersionName"><strong>GetOSVersionName</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetSystemCommitCharge"><strong>GetSystemCommitCharge</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetSystemProcessInfo"><strong>GetSystemProcessInfo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetSystemTotalPhysicalMemory"><strong>GetSystemTotalPhysicalMemory</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-IsCooperativeShutdownSupported"><strong>IsCooperativeShutdownSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-IsCurrentProcessElevated"><strong>IsCurrentProcessElevated</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-KillProcess"><strong>KillProcess</strong></a>(self, pid, kill_process_tree<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-LaunchApplication"><strong>LaunchApplication</strong></a>(self, application, parameters<font color="#909090">=None</font>, elevate_privilege<font color="#909090">=False</font>)</dt><dd><tt>Launch&nbsp;an&nbsp;application.&nbsp;Returns&nbsp;a&nbsp;PyHANDLE&nbsp;object.</tt></dd></dl>
-
-<dl><dt><a name="WinPlatformBackend-ReadMsr"><strong>ReadMsr</strong></a>(self, msr_number, start<font color="#909090">=0</font>, length<font color="#909090">=64</font>)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-StartMonitoringPower"><strong>StartMonitoringPower</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-StopMonitoringPower"><strong>StopMonitoringPower</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-close"><strong>close</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="WinPlatformBackend-IsPlatformBackendForHost"><strong>IsPlatformBackendForHost</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.desktop_platform_backend.html#DesktopPlatformBackend">telemetry.internal.platform.desktop_platform_backend.DesktopPlatformBackend</a>:<br>
-<dl><dt><a name="WinPlatformBackend-FlushSystemCacheForDirectory"><strong>FlushSystemCacheForDirectory</strong></a>(self, directory)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="WinPlatformBackend-CanCaptureVideo"><strong>CanCaptureVideo</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CanLaunchApplication"><strong>CanLaunchApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CanMonitorNetworkData"><strong>CanMonitorNetworkData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-DidCreateBrowser"><strong>DidCreateBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-FlushDnsCache"><strong>FlushDnsCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-FlushEntireSystemCache"><strong>FlushEntireSystemCache</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetNetworkData"><strong>GetNetworkData</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-GetRemotePort"><strong>GetRemotePort</strong></a>(self, port)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-InitPlatformBackend"><strong>InitPlatformBackend</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-InstallApplication"><strong>InstallApplication</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-IsApplicationRunning"><strong>IsApplicationRunning</strong></a>(self, application)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-IsDisplayTracingSupported"><strong>IsDisplayTracingSupported</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-PathExists"><strong>PathExists</strong></a>(self, path, timeout<font color="#909090">=None</font>, retries<font color="#909090">=None</font>)</dt><dd><tt>Tests&nbsp;whether&nbsp;the&nbsp;given&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;path&nbsp;in&nbsp;request.<br>
-&nbsp;&nbsp;timeout:&nbsp;timeout.<br>
-&nbsp;&nbsp;retries:&nbsp;num&nbsp;of&nbsp;retries.<br>
-Return:<br>
-&nbsp;&nbsp;Whether&nbsp;the&nbsp;path&nbsp;exists&nbsp;on&nbsp;the&nbsp;target&nbsp;platform.</tt></dd></dl>
-
-<dl><dt><a name="WinPlatformBackend-PurgeUnpinnedMemory"><strong>PurgeUnpinnedMemory</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-SetFullPerformanceModeEnabled"><strong>SetFullPerformanceModeEnabled</strong></a>(self, enabled)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-SetPlatform"><strong>SetPlatform</strong></a>(self, platform)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-StartDisplayTracing"><strong>StartDisplayTracing</strong></a>(self)</dt><dd><tt>Start&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="WinPlatformBackend-StartVideoCapture"><strong>StartVideoCapture</strong></a>(self, min_bitrate_mbps)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-StopDisplayTracing"><strong>StopDisplayTracing</strong></a>(self)</dt><dd><tt>Stop&nbsp;gathering&nbsp;a&nbsp;trace&nbsp;with&nbsp;frame&nbsp;timestamps&nbsp;close&nbsp;to&nbsp;physical&nbsp;display.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;raw&nbsp;tracing&nbsp;events&nbsp;that&nbsp;contains&nbsp;the&nbsp;timestamps&nbsp;of&nbsp;physical<br>
-display.</tt></dd></dl>
-
-<dl><dt><a name="WinPlatformBackend-StopVideoCapture"><strong>StopVideoCapture</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-WillCloseBrowser"><strong>WillCloseBrowser</strong></a>(self, browser, browser_backend)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><a name="WinPlatformBackend-CreatePlatformForDevice"><strong>CreatePlatformForDevice</strong></a>(cls, device, finder_options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="WinPlatformBackend-SupportsDevice"><strong>SupportsDevice</strong></a>(cls, device)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;whether&nbsp;this&nbsp;platform&nbsp;backend&nbsp;supports&nbsp;intialization&nbsp;from&nbsp;the<br>
-device.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.platform_backend.html#PlatformBackend">telemetry.internal.platform.platform_backend.PlatformBackend</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>forwarder_factory</strong></dt>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>is_video_capture_running</strong></dt>
-</dl>
-<dl><dt><strong>network_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<dl><dt><strong>running_browser_backends</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller_backend</strong></dt>
-</dl>
-<dl><dt><strong>wpr_ca_cert_path</strong></dt>
-</dl>
-<dl><dt><strong>wpr_http_device_port</strong></dt>
-</dl>
-<dl><dt><strong>wpr_https_device_port</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-TerminateProcess"><strong>TerminateProcess</strong></a>(process_handle)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>pywintypes</strong> = None<br>
-<strong>shell</strong> = None<br>
-<strong>shellcon</strong> = None<br>
-<strong>win32api</strong> = None<br>
-<strong>win32con</strong> = None<br>
-<strong>win32gui</strong> = None<br>
-<strong>win32process</strong> = None<br>
-<strong>win32security</strong> = None</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.buildbot_output_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.buildbot_output_formatter.html
deleted file mode 100644
index 7b4addb..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.buildbot_output_formatter.html
+++ /dev/null
@@ -1,75 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.buildbot_output_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.buildbot_output_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/buildbot_output_formatter.py">telemetry/internal/results/buildbot_output_formatter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.results.output_formatter.html">telemetry.internal.results.output_formatter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.perf_tests_helper.html">telemetry.util.perf_tests_helper</a><br>
-<a href="telemetry.value.summary.html">telemetry.value.summary</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.buildbot_output_formatter.html#BuildbotOutputFormatter">BuildbotOutputFormatter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BuildbotOutputFormatter">class <strong>BuildbotOutputFormatter</strong></a>(<a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.results.buildbot_output_formatter.html#BuildbotOutputFormatter">BuildbotOutputFormatter</a></dd>
-<dd><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="BuildbotOutputFormatter-Format"><strong>Format</strong></a>(self, page_test_results)</dt><dd><tt>Print&nbsp;summary&nbsp;data&nbsp;in&nbsp;a&nbsp;format&nbsp;expected&nbsp;by&nbsp;buildbot&nbsp;for&nbsp;perf&nbsp;dashboards.<br>
-&nbsp;<br>
-If&nbsp;any&nbsp;failed&nbsp;pages&nbsp;exist,&nbsp;only&nbsp;output&nbsp;individual&nbsp;page&nbsp;results,&nbsp;and&nbsp;do<br>
-not&nbsp;output&nbsp;any&nbsp;average&nbsp;data.</tt></dd></dl>
-
-<dl><dt><a name="BuildbotOutputFormatter-__init__"><strong>__init__</strong></a>(*args, **kwargs)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.chart_json_output_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.chart_json_output_formatter.html
deleted file mode 100644
index 2953e7f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.chart_json_output_formatter.html
+++ /dev/null
@@ -1,99 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.chart_json_output_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.chart_json_output_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/chart_json_output_formatter.py">telemetry/internal/results/chart_json_output_formatter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="itertools.html">itertools</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="telemetry.internal.results.output_formatter.html">telemetry.internal.results.output_formatter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.summary.html">telemetry.value.summary</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.chart_json_output_formatter.html#ChartJsonOutputFormatter">ChartJsonOutputFormatter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ChartJsonOutputFormatter">class <strong>ChartJsonOutputFormatter</strong></a>(<a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;TODO(eakuefner):&nbsp;Transition&nbsp;this&nbsp;to&nbsp;translate&nbsp;Telemetry&nbsp;JSON.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.results.chart_json_output_formatter.html#ChartJsonOutputFormatter">ChartJsonOutputFormatter</a></dd>
-<dd><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ChartJsonOutputFormatter-Format"><strong>Format</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="ChartJsonOutputFormatter-__init__"><strong>__init__</strong></a>(self, output_stream, benchmark_metadata)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ResultsAsChartDict"><strong>ResultsAsChartDict</strong></a>(benchmark_metadata, page_specific_values, summary_values)</dt><dd><tt>Produces&nbsp;a&nbsp;dict&nbsp;for&nbsp;serialization&nbsp;to&nbsp;Chart&nbsp;JSON&nbsp;format&nbsp;from&nbsp;raw&nbsp;values.<br>
-&nbsp;<br>
-Chart&nbsp;JSON&nbsp;is&nbsp;a&nbsp;transformation&nbsp;of&nbsp;the&nbsp;basic&nbsp;Telemetry&nbsp;JSON&nbsp;format&nbsp;that<br>
-removes&nbsp;the&nbsp;page&nbsp;map,&nbsp;summarizes&nbsp;the&nbsp;raw&nbsp;values,&nbsp;and&nbsp;organizes&nbsp;the&nbsp;results<br>
-by&nbsp;chart&nbsp;and&nbsp;trace&nbsp;name.&nbsp;This&nbsp;function&nbsp;takes&nbsp;the&nbsp;key&nbsp;pieces&nbsp;of&nbsp;data&nbsp;needed&nbsp;to<br>
-perform&nbsp;this&nbsp;transformation&nbsp;(namely,&nbsp;lists&nbsp;of&nbsp;values&nbsp;and&nbsp;a&nbsp;benchmark&nbsp;metadata<br>
-object)&nbsp;and&nbsp;processes&nbsp;them&nbsp;into&nbsp;a&nbsp;dict&nbsp;which&nbsp;can&nbsp;be&nbsp;serialized&nbsp;using&nbsp;the&nbsp;json<br>
-module.<br>
-&nbsp;<br>
-Design&nbsp;doc&nbsp;for&nbsp;schema:&nbsp;<a href="http://goo.gl/kOtf1Y">http://goo.gl/kOtf1Y</a><br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page_specific_values:&nbsp;list&nbsp;of&nbsp;page-specific&nbsp;values<br>
-&nbsp;&nbsp;summary_values:&nbsp;list&nbsp;of&nbsp;summary&nbsp;values<br>
-&nbsp;&nbsp;benchmark_metadata:&nbsp;a&nbsp;benchmark.BenchmarkMetadata&nbsp;object<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;Chart&nbsp;JSON&nbsp;dict&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;given&nbsp;data.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.csv_pivot_table_output_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.csv_pivot_table_output_formatter.html
deleted file mode 100644
index ccde6e6..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.csv_pivot_table_output_formatter.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.csv_pivot_table_output_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.csv_pivot_table_output_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/csv_pivot_table_output_formatter.py">telemetry/internal/results/csv_pivot_table_output_formatter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="csv.html">csv</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.output_formatter.html">telemetry.internal.results.output_formatter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.csv_pivot_table_output_formatter.html#CsvPivotTableOutputFormatter">CsvPivotTableOutputFormatter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CsvPivotTableOutputFormatter">class <strong>CsvPivotTableOutputFormatter</strong></a>(<a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Output&nbsp;the&nbsp;results&nbsp;as&nbsp;CSV&nbsp;suitable&nbsp;for&nbsp;reading&nbsp;into&nbsp;a&nbsp;spreadsheet.<br>
-&nbsp;<br>
-This&nbsp;will&nbsp;write&nbsp;a&nbsp;header&nbsp;row,&nbsp;and&nbsp;one&nbsp;row&nbsp;for&nbsp;each&nbsp;value.&nbsp;Each&nbsp;value&nbsp;row<br>
-contains&nbsp;the&nbsp;value&nbsp;and&nbsp;unit,&nbsp;identifies&nbsp;the&nbsp;value&nbsp;(story_set,&nbsp;page,&nbsp;name),&nbsp;and<br>
-(optionally)&nbsp;data&nbsp;from&nbsp;--output-trace-tag.&nbsp;This&nbsp;format&nbsp;matches&nbsp;what<br>
-spreadsheet&nbsp;programs&nbsp;expect&nbsp;as&nbsp;input&nbsp;for&nbsp;a&nbsp;"pivot&nbsp;table".<br>
-&nbsp;<br>
-A&nbsp;trace&nbsp;tag&nbsp;(--output-trace-tag)&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;tag&nbsp;each&nbsp;value,&nbsp;to&nbsp;allow<br>
-easy&nbsp;combination&nbsp;of&nbsp;the&nbsp;resulting&nbsp;CSVs&nbsp;from&nbsp;several&nbsp;runs.<br>
-If&nbsp;the&nbsp;trace_tag&nbsp;contains&nbsp;a&nbsp;comma,&nbsp;it&nbsp;will&nbsp;be&nbsp;written&nbsp;as&nbsp;several<br>
-comma-separated&nbsp;values.<br>
-&nbsp;<br>
-This&nbsp;class&nbsp;only&nbsp;processes&nbsp;scalar&nbsp;values.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.results.csv_pivot_table_output_formatter.html#CsvPivotTableOutputFormatter">CsvPivotTableOutputFormatter</a></dd>
-<dd><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="CsvPivotTableOutputFormatter-Format"><strong>Format</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="CsvPivotTableOutputFormatter-__init__"><strong>__init__</strong></a>(self, output_stream, trace_tag<font color="#909090">=''</font>)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>FIELDS</strong> = ['story_set', 'page', 'name', 'value', 'units', 'run_index']</dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.gtest_progress_reporter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.gtest_progress_reporter.html
deleted file mode 100644
index e96b455..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.gtest_progress_reporter.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.gtest_progress_reporter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.gtest_progress_reporter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/gtest_progress_reporter.py">telemetry/internal/results/gtest_progress_reporter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.failure.html">telemetry.value.failure</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.progress_reporter.html">telemetry.internal.results.progress_reporter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.skip.html">telemetry.value.skip</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.progress_reporter.html#ProgressReporter">telemetry.internal.results.progress_reporter.ProgressReporter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.gtest_progress_reporter.html#GTestProgressReporter">GTestProgressReporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GTestProgressReporter">class <strong>GTestProgressReporter</strong></a>(<a href="telemetry.internal.results.progress_reporter.html#ProgressReporter">telemetry.internal.results.progress_reporter.ProgressReporter</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;progress&nbsp;reporter&nbsp;that&nbsp;outputs&nbsp;the&nbsp;progress&nbsp;report&nbsp;in&nbsp;gtest&nbsp;style.<br>
-&nbsp;<br>
-Be&nbsp;careful&nbsp;each&nbsp;print&nbsp;should&nbsp;only&nbsp;handle&nbsp;one&nbsp;string.&nbsp;Otherwise,&nbsp;the&nbsp;output<br>
-might&nbsp;be&nbsp;interrupted&nbsp;by&nbsp;Chrome&nbsp;logging,&nbsp;and&nbsp;the&nbsp;output&nbsp;interpretation&nbsp;might<br>
-be&nbsp;incorrect.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;&gt;&gt;&nbsp;self.<strong>_output_stream</strong>,&nbsp;"[&nbsp;OK&nbsp;]",&nbsp;testname<br>
-should&nbsp;be&nbsp;written&nbsp;as<br>
-&nbsp;&nbsp;&nbsp;&nbsp;print&nbsp;&gt;&gt;&nbsp;self.<strong>_output_stream</strong>,&nbsp;"[&nbsp;OK&nbsp;]&nbsp;%s"&nbsp;%&nbsp;testname<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.results.gtest_progress_reporter.html#GTestProgressReporter">GTestProgressReporter</a></dd>
-<dd><a href="telemetry.internal.results.progress_reporter.html#ProgressReporter">telemetry.internal.results.progress_reporter.ProgressReporter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="GTestProgressReporter-DidAddValue"><strong>DidAddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-DidFinishAllTests"><strong>DidFinishAllTests</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-DidRunPage"><strong>DidRunPage</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-WillRunPage"><strong>WillRunPage</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-__init__"><strong>__init__</strong></a>(self, output_stream, output_skipped_tests_summary<font color="#909090">=False</font>)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.progress_reporter.html#ProgressReporter">telemetry.internal.results.progress_reporter.ProgressReporter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.html
deleted file mode 100644
index a17726b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.results</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.results</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/__init__.py">telemetry/internal/results/__init__.py</a></font></td></tr></table>
-    <p><tt>The&nbsp;PageTestResults&nbsp;hierarchy&nbsp;provides&nbsp;a&nbsp;way&nbsp;of&nbsp;representing&nbsp;the&nbsp;results&nbsp;of<br>
-running&nbsp;the&nbsp;test&nbsp;or&nbsp;measurement&nbsp;on&nbsp;pages.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.results.base_test_results_unittest.html">base_test_results_unittest</a><br>
-<a href="telemetry.internal.results.buildbot_output_formatter.html">buildbot_output_formatter</a><br>
-<a href="telemetry.internal.results.buildbot_output_formatter_unittest.html">buildbot_output_formatter_unittest</a><br>
-<a href="telemetry.internal.results.chart_json_output_formatter.html">chart_json_output_formatter</a><br>
-<a href="telemetry.internal.results.chart_json_output_formatter_unittest.html">chart_json_output_formatter_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.csv_pivot_table_output_formatter.html">csv_pivot_table_output_formatter</a><br>
-<a href="telemetry.internal.results.csv_pivot_table_output_formatter_unittest.html">csv_pivot_table_output_formatter_unittest</a><br>
-<a href="telemetry.internal.results.gtest_progress_reporter.html">gtest_progress_reporter</a><br>
-<a href="telemetry.internal.results.gtest_progress_reporter_unittest.html">gtest_progress_reporter_unittest</a><br>
-<a href="telemetry.internal.results.html_output_formatter.html">html_output_formatter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.html_output_formatter_unittest.html">html_output_formatter_unittest</a><br>
-<a href="telemetry.internal.results.json_output_formatter.html">json_output_formatter</a><br>
-<a href="telemetry.internal.results.json_output_formatter_unittest.html">json_output_formatter_unittest</a><br>
-<a href="telemetry.internal.results.output_formatter.html">output_formatter</a><br>
-<a href="telemetry.internal.results.page_test_results.html">page_test_results</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.page_test_results_unittest.html">page_test_results_unittest</a><br>
-<a href="telemetry.internal.results.progress_reporter.html">progress_reporter</a><br>
-<a href="telemetry.internal.results.results_options.html">results_options</a><br>
-<a href="telemetry.internal.results.story_run.html">story_run</a><br>
-<a href="telemetry.internal.results.story_run_unittest.html">story_run_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.html_output_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.html_output_formatter.html
deleted file mode 100644
index 170dfc6..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.html_output_formatter.html
+++ /dev/null
@@ -1,84 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.html_output_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.html_output_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/html_output_formatter.py">telemetry/internal/results/html_output_formatter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.results.chart_json_output_formatter.html">telemetry.internal.results.chart_json_output_formatter</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="datetime.html">datetime</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.internal.results.output_formatter.html">telemetry.internal.results.output_formatter</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="telemetry.value.html">telemetry.value</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.html_output_formatter.html#HtmlOutputFormatter">HtmlOutputFormatter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="HtmlOutputFormatter">class <strong>HtmlOutputFormatter</strong></a>(<a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;TODO(eakuefner):&nbsp;rewrite&nbsp;template&nbsp;to&nbsp;use&nbsp;Telemetry&nbsp;JSON&nbsp;directly<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.results.html_output_formatter.html#HtmlOutputFormatter">HtmlOutputFormatter</a></dd>
-<dd><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="HtmlOutputFormatter-Format"><strong>Format</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="HtmlOutputFormatter-GetCombinedResults"><strong>GetCombinedResults</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HtmlOutputFormatter-GetResults"><strong>GetResults</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HtmlOutputFormatter-__init__"><strong>__init__</strong></a>(self, output_stream, metadata, reset_results, upload_results, browser_type, results_label<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.json_output_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.json_output_formatter.html
deleted file mode 100644
index f1d4dc9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.json_output_formatter.html
+++ /dev/null
@@ -1,90 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.json_output_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.json_output_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/json_output_formatter.py">telemetry/internal/results/json_output_formatter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.output_formatter.html">telemetry.internal.results.output_formatter</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.json_output_formatter.html#JsonOutputFormatter">JsonOutputFormatter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="JsonOutputFormatter">class <strong>JsonOutputFormatter</strong></a>(<a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.results.json_output_formatter.html#JsonOutputFormatter">JsonOutputFormatter</a></dd>
-<dd><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="JsonOutputFormatter-Format"><strong>Format</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="JsonOutputFormatter-__init__"><strong>__init__</strong></a>(self, output_stream, benchmark_metadata)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>benchmark_metadata</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.output_formatter.html#OutputFormatter">telemetry.internal.results.output_formatter.OutputFormatter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ResultsAsDict"><strong>ResultsAsDict</strong></a>(page_test_results, benchmark_metadata)</dt><dd><tt>Takes&nbsp;PageTestResults&nbsp;to&nbsp;a&nbsp;dict&nbsp;serializable&nbsp;to&nbsp;JSON.<br>
-&nbsp;<br>
-To&nbsp;serialize&nbsp;results&nbsp;as&nbsp;JSON&nbsp;we&nbsp;first&nbsp;convert&nbsp;them&nbsp;to&nbsp;a&nbsp;dict&nbsp;that&nbsp;can&nbsp;be<br>
-serialized&nbsp;by&nbsp;the&nbsp;json&nbsp;module.&nbsp;It&nbsp;also&nbsp;requires&nbsp;a&nbsp;benchmark_metadat&nbsp;object<br>
-for&nbsp;metadata&nbsp;to&nbsp;be&nbsp;integrated&nbsp;into&nbsp;the&nbsp;results&nbsp;(currently&nbsp;the&nbsp;benchmark<br>
-name).&nbsp;This&nbsp;function&nbsp;will&nbsp;also&nbsp;output&nbsp;trace&nbsp;files&nbsp;if&nbsp;they&nbsp;exist.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page_test_results:&nbsp;a&nbsp;PageTestResults&nbsp;object<br>
-&nbsp;&nbsp;benchmark_metadata:&nbsp;a&nbsp;benchmark.BenchmarkMetadata&nbsp;object</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.output_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.output_formatter.html
deleted file mode 100644
index 2588947..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.output_formatter.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.output_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.output_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/output_formatter.py">telemetry/internal/results/output_formatter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.output_formatter.html#OutputFormatter">OutputFormatter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="OutputFormatter">class <strong>OutputFormatter</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;formatter&nbsp;for&nbsp;PageTestResults.<br>
-&nbsp;<br>
-An&nbsp;<a href="#OutputFormatter">OutputFormatter</a>&nbsp;takes&nbsp;PageTestResults,&nbsp;formats&nbsp;the&nbsp;results<br>
-(telemetry.value.Value&nbsp;instances),&nbsp;and&nbsp;output&nbsp;the&nbsp;formatted&nbsp;results<br>
-in&nbsp;the&nbsp;given&nbsp;output&nbsp;stream.<br>
-&nbsp;<br>
-Examples&nbsp;of&nbsp;output&nbsp;formatter:&nbsp;CsvOutputFormatter&nbsp;produces&nbsp;results&nbsp;in<br>
-CSV&nbsp;format.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="OutputFormatter-Format"><strong>Format</strong></a>(self, page_test_results)</dt><dd><tt>Formats&nbsp;the&nbsp;given&nbsp;PageTestResults&nbsp;into&nbsp;the&nbsp;output&nbsp;stream.<br>
-&nbsp;<br>
-This&nbsp;will&nbsp;be&nbsp;called&nbsp;once&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;a&nbsp;benchmark.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page_test_results:&nbsp;A&nbsp;PageTestResults&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;containing&nbsp;all&nbsp;results<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;from&nbsp;the&nbsp;current&nbsp;benchmark&nbsp;run.</tt></dd></dl>
-
-<dl><dt><a name="OutputFormatter-__init__"><strong>__init__</strong></a>(self, output_stream)</dt><dd><tt>Constructs&nbsp;a&nbsp;new&nbsp;formatter&nbsp;that&nbsp;writes&nbsp;to&nbsp;the&nbsp;output_stream.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;output_stream:&nbsp;The&nbsp;stream&nbsp;to&nbsp;write&nbsp;the&nbsp;formatted&nbsp;output&nbsp;to.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_stream</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.page_test_results.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.page_test_results.html
deleted file mode 100644
index 45c0ee5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.page_test_results.html
+++ /dev/null
@@ -1,152 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.page_test_results</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.page_test_results</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/page_test_results.py">telemetry/internal/results/page_test_results.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="collections.html">collections</a><br>
-<a href="copy.html">copy</a><br>
-<a href="datetime.html">datetime</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.failure.html">telemetry.value.failure</a><br>
-<a href="telemetry.internal.results.json_output_formatter.html">telemetry.internal.results.json_output_formatter</a><br>
-<a href="logging.html">logging</a><br>
-<a href="random.html">random</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.progress_reporter.html">telemetry.internal.results.progress_reporter</a><br>
-<a href="telemetry.value.skip.html">telemetry.value.skip</a><br>
-<a href="telemetry.internal.results.story_run.html">telemetry.internal.results.story_run</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.trace.html">telemetry.value.trace</a><br>
-<a href="traceback.html">traceback</a><br>
-<a href="telemetry.value.html">telemetry.value</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.page_test_results.html#PageTestResults">PageTestResults</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PageTestResults">class <strong>PageTestResults</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PageTestResults-AddProfilingFile"><strong>AddProfilingFile</strong></a>(self, page, file_handle)</dt></dl>
-
-<dl><dt><a name="PageTestResults-AddSummaryValue"><strong>AddSummaryValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="PageTestResults-AddValue"><strong>AddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="PageTestResults-CleanUp"><strong>CleanUp</strong></a>(self)</dt><dd><tt>Clean&nbsp;up&nbsp;any&nbsp;TraceValues&nbsp;contained&nbsp;within&nbsp;this&nbsp;results&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
-
-<dl><dt><a name="PageTestResults-DidRunPage"><strong>DidRunPage</strong></a>(self, page)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;page:&nbsp;The&nbsp;current&nbsp;page&nbsp;under&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="PageTestResults-FindAllPageSpecificValuesFromIRNamed"><strong>FindAllPageSpecificValuesFromIRNamed</strong></a>(self, tir_label, value_name)</dt></dl>
-
-<dl><dt><a name="PageTestResults-FindAllPageSpecificValuesNamed"><strong>FindAllPageSpecificValuesNamed</strong></a>(self, value_name)</dt></dl>
-
-<dl><dt><a name="PageTestResults-FindAllTraceValues"><strong>FindAllTraceValues</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestResults-FindPageSpecificValuesForPage"><strong>FindPageSpecificValuesForPage</strong></a>(self, page, value_name)</dt></dl>
-
-<dl><dt><a name="PageTestResults-FindValues"><strong>FindValues</strong></a>(self, predicate)</dt><dd><tt>Finds&nbsp;all&nbsp;values&nbsp;matching&nbsp;the&nbsp;specified&nbsp;predicate.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;predicate:&nbsp;A&nbsp;function&nbsp;that&nbsp;takes&nbsp;a&nbsp;Value&nbsp;and&nbsp;returns&nbsp;a&nbsp;bool.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;values&nbsp;matching&nbsp;|predicate|.</tt></dd></dl>
-
-<dl><dt><a name="PageTestResults-PrintSummary"><strong>PrintSummary</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestResults-UploadProfilingFilesToCloud"><strong>UploadProfilingFilesToCloud</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="PageTestResults-UploadTraceFilesToCloud"><strong>UploadTraceFilesToCloud</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="PageTestResults-WillRunPage"><strong>WillRunPage</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="PageTestResults-__copy__"><strong>__copy__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestResults-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestResults-__exit__"><strong>__exit__</strong></a>(self, _, __, ___)</dt></dl>
-
-<dl><dt><a name="PageTestResults-__init__"><strong>__init__</strong></a>(self, output_formatters<font color="#909090">=None</font>, progress_reporter<font color="#909090">=None</font>, trace_tag<font color="#909090">=''</font>, output_dir<font color="#909090">=None</font>, value_can_be_added_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;output_formatters:&nbsp;A&nbsp;list&nbsp;of&nbsp;output&nbsp;formatters.&nbsp;The&nbsp;output<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;formatters&nbsp;are&nbsp;typically&nbsp;used&nbsp;to&nbsp;format&nbsp;the&nbsp;test&nbsp;results,&nbsp;such<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;CsvPivotTableOutputFormatter,&nbsp;which&nbsp;output&nbsp;the&nbsp;test&nbsp;results&nbsp;as&nbsp;CSV.<br>
-&nbsp;&nbsp;progress_reporter:&nbsp;An&nbsp;instance&nbsp;of&nbsp;progress_reporter.ProgressReporter,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;used&nbsp;to&nbsp;output&nbsp;test&nbsp;status/results&nbsp;progressively.<br>
-&nbsp;&nbsp;trace_tag:&nbsp;A&nbsp;string&nbsp;to&nbsp;append&nbsp;to&nbsp;the&nbsp;buildbot&nbsp;trace&nbsp;name.&nbsp;Currently&nbsp;only<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;used&nbsp;for&nbsp;buildbot.<br>
-&nbsp;&nbsp;output_dir:&nbsp;A&nbsp;string&nbsp;specified&nbsp;the&nbsp;directory&nbsp;where&nbsp;to&nbsp;store&nbsp;the&nbsp;test<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;artifacts,&nbsp;e.g:&nbsp;trace,&nbsp;videos,...<br>
-&nbsp;&nbsp;value_can_be_added_predicate:&nbsp;A&nbsp;function&nbsp;that&nbsp;takes&nbsp;two&nbsp;arguments:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;value.Value&nbsp;instance&nbsp;(except&nbsp;failure.FailureValue,&nbsp;skip.SkipValue<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;trace.TraceValue)&nbsp;and&nbsp;a&nbsp;boolean&nbsp;(True&nbsp;when&nbsp;the&nbsp;value&nbsp;is&nbsp;part&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;first&nbsp;result&nbsp;for&nbsp;the&nbsp;story).&nbsp;It&nbsp;returns&nbsp;True&nbsp;if&nbsp;the&nbsp;value<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;can&nbsp;be&nbsp;added&nbsp;to&nbsp;the&nbsp;test&nbsp;results&nbsp;and&nbsp;False&nbsp;otherwise.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>all_page_runs</strong></dt>
-</dl>
-<dl><dt><strong>all_page_specific_values</strong></dt>
-</dl>
-<dl><dt><strong>all_summary_values</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_page_run</strong></dt>
-</dl>
-<dl><dt><strong>failures</strong></dt>
-</dl>
-<dl><dt><strong>pages_that_failed</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;failed&nbsp;pages.</tt></dd>
-</dl>
-<dl><dt><strong>pages_that_succeeded</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;pages&nbsp;that&nbsp;succeeded.</tt></dd>
-</dl>
-<dl><dt><strong>pages_to_profiling_files</strong></dt>
-</dl>
-<dl><dt><strong>pages_to_profiling_files_cloud_url</strong></dt>
-</dl>
-<dl><dt><strong>serialized_trace_file_ids_to_paths</strong></dt>
-</dl>
-<dl><dt><strong>skipped_values</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.progress_reporter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.progress_reporter.html
deleted file mode 100644
index 6d9ae69..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.progress_reporter.html
+++ /dev/null
@@ -1,65 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.progress_reporter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.progress_reporter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/progress_reporter.py">telemetry/internal/results/progress_reporter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.progress_reporter.html#ProgressReporter">ProgressReporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProgressReporter">class <strong>ProgressReporter</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;class&nbsp;that&nbsp;reports&nbsp;progress&nbsp;of&nbsp;a&nbsp;benchmark.<br>
-&nbsp;<br>
-The&nbsp;reporter&nbsp;produces&nbsp;output&nbsp;whenever&nbsp;a&nbsp;significant&nbsp;event&nbsp;happens<br>
-during&nbsp;the&nbsp;progress&nbsp;of&nbsp;a&nbsp;benchmark,&nbsp;including&nbsp;(but&nbsp;not&nbsp;limited&nbsp;to):<br>
-when&nbsp;a&nbsp;page&nbsp;run&nbsp;is&nbsp;started,&nbsp;when&nbsp;a&nbsp;page&nbsp;run&nbsp;finished,&nbsp;any&nbsp;failures<br>
-during&nbsp;a&nbsp;page&nbsp;run.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;outputs&nbsp;nothing.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ProgressReporter-DidAddValue"><strong>DidAddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-DidFinishAllTests"><strong>DidFinishAllTests</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-DidRunPage"><strong>DidRunPage</strong></a>(self, page_test_results)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-WillRunPage"><strong>WillRunPage</strong></a>(self, page_test_results)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.results_options.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.results_options.html
deleted file mode 100644
index a565e54..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.results_options.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.results_options</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.results_options</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/results_options.py">telemetry/internal/results/results_options.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.results.buildbot_output_formatter.html">telemetry.internal.results.buildbot_output_formatter</a><br>
-<a href="telemetry.internal.results.chart_json_output_formatter.html">telemetry.internal.results.chart_json_output_formatter</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="telemetry.internal.results.csv_pivot_table_output_formatter.html">telemetry.internal.results.csv_pivot_table_output_formatter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.gtest_progress_reporter.html">telemetry.internal.results.gtest_progress_reporter</a><br>
-<a href="telemetry.internal.results.html_output_formatter.html">telemetry.internal.results.html_output_formatter</a><br>
-<a href="telemetry.internal.results.json_output_formatter.html">telemetry.internal.results.json_output_formatter</a><br>
-<a href="optparse.html">optparse</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.internal.results.page_test_results.html">telemetry.internal.results.page_test_results</a><br>
-<a href="telemetry.internal.results.progress_reporter.html">telemetry.internal.results.progress_reporter</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AddResultsOptions"><strong>AddResultsOptions</strong></a>(parser)</dt></dl>
- <dl><dt><a name="-CreateResults"><strong>CreateResults</strong></a>(benchmark_metadata, options, value_can_be_added_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;options:&nbsp;Contains&nbsp;the&nbsp;options&nbsp;specified&nbsp;in&nbsp;AddResultsOptions.</tt></dd></dl>
- <dl><dt><a name="-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(parser, args)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.results.story_run.html b/catapult/telemetry/docs/pydoc/telemetry.internal.results.story_run.html
deleted file mode 100644
index f703b68..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.results.story_run.html
+++ /dev/null
@@ -1,83 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.results.story_run</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.results.html"><font color="#ffffff">results</font></a>.story_run</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/results/story_run.py">telemetry/internal/results/story_run.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.failure.html">telemetry.value.failure</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.skip.html">telemetry.value.skip</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.story_run.html#StoryRun">StoryRun</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StoryRun">class <strong>StoryRun</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="StoryRun-AddValue"><strong>AddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="StoryRun-__init__"><strong>__init__</strong></a>(self, story)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>failed</strong></dt>
-<dd><tt>Whether&nbsp;the&nbsp;current&nbsp;run&nbsp;failed.<br>
-&nbsp;<br>
-To&nbsp;be&nbsp;precise:&nbsp;returns&nbsp;true&nbsp;if&nbsp;there&nbsp;is&nbsp;a&nbsp;FailureValue&nbsp;but&nbsp;not<br>
-SkipValue&nbsp;in&nbsp;self.<strong>values</strong>.</tt></dd>
-</dl>
-<dl><dt><strong>ok</strong></dt>
-<dd><tt>Whether&nbsp;the&nbsp;current&nbsp;run&nbsp;is&nbsp;still&nbsp;ok.<br>
-&nbsp;<br>
-To&nbsp;be&nbsp;precise:&nbsp;returns&nbsp;true&nbsp;if&nbsp;there&nbsp;is&nbsp;neither&nbsp;FailureValue&nbsp;nor<br>
-SkipValue&nbsp;in&nbsp;self.<strong>values</strong>.</tt></dd>
-</dl>
-<dl><dt><strong>skipped</strong></dt>
-<dd><tt>Whether&nbsp;the&nbsp;current&nbsp;run&nbsp;is&nbsp;being&nbsp;skipped.<br>
-&nbsp;<br>
-To&nbsp;be&nbsp;precise:&nbsp;returns&nbsp;true&nbsp;if&nbsp;there&nbsp;is&nbsp;any&nbsp;SkipValue&nbsp;in&nbsp;self.<strong>values</strong>.</tt></dd>
-</dl>
-<dl><dt><strong>story</strong></dt>
-</dl>
-<dl><dt><strong>values</strong></dt>
-<dd><tt>The&nbsp;values&nbsp;that&nbsp;correspond&nbsp;to&nbsp;this&nbsp;story&nbsp;run.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.story_runner.html b/catapult/telemetry/docs/pydoc/telemetry.internal.story_runner.html
deleted file mode 100644
index dabb2a7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.story_runner.html
+++ /dev/null
@@ -1,178 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.story_runner</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.story_runner</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/story_runner.py">telemetry/internal/story_runner.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="telemetry.internal.util.exception_formatter.html">telemetry.internal.util.exception_formatter</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.value.failure.html">telemetry.value.failure</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="optparse.html">optparse</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.page.html">telemetry.page</a><br>
-<a href="telemetry.internal.actions.page_action.html">telemetry.internal.actions.page_action</a><br>
-</td><td width="25%" valign=top><a href="telemetry.page.page_test.html">telemetry.page.page_test</a><br>
-<a href="telemetry.internal.results.results_options.html">telemetry.internal.results.results_options</a><br>
-<a href="telemetry.value.skip.html">telemetry.value.skip</a><br>
-<a href="telemetry.story.html">telemetry.story</a><br>
-<a href="telemetry.web_perf.story_test.html">telemetry.web_perf.story_test</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="time.html">time</a><br>
-<a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.story_runner.html#StoryGroup">StoryGroup</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.story_runner.html#ArchiveError">ArchiveError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ArchiveError">class <strong>ArchiveError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.story_runner.html#ArchiveError">ArchiveError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ArchiveError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ArchiveError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ArchiveError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ArchiveError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ArchiveError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StoryGroup">class <strong>StoryGroup</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="StoryGroup-AddStory"><strong>AddStory</strong></a>(self, story)</dt></dl>
-
-<dl><dt><a name="StoryGroup-__init__"><strong>__init__</strong></a>(self, shared_state_class)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>shared_state_class</strong></dt>
-</dl>
-<dl><dt><strong>stories</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(parser)</dt></dl>
- <dl><dt><a name="-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(parser, args)</dt></dl>
- <dl><dt><a name="-Run"><strong>Run</strong></a>(test, story_set, finder_options, results, max_failures<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;a&nbsp;given&nbsp;test&nbsp;against&nbsp;a&nbsp;given&nbsp;page_set&nbsp;with&nbsp;the&nbsp;given&nbsp;options.<br>
-&nbsp;<br>
-Stop&nbsp;execution&nbsp;for&nbsp;unexpected&nbsp;exceptions&nbsp;such&nbsp;as&nbsp;KeyboardInterrupt.<br>
-We&nbsp;"white&nbsp;list"&nbsp;certain&nbsp;exceptions&nbsp;for&nbsp;which&nbsp;the&nbsp;story&nbsp;runner<br>
-can&nbsp;continue&nbsp;running&nbsp;the&nbsp;remaining&nbsp;stories.</tt></dd></dl>
- <dl><dt><a name="-RunBenchmark"><strong>RunBenchmark</strong></a>(benchmark, finder_options)</dt><dd><tt>Run&nbsp;this&nbsp;test&nbsp;with&nbsp;the&nbsp;given&nbsp;options.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;number&nbsp;of&nbsp;failure&nbsp;values&nbsp;(up&nbsp;to&nbsp;254)&nbsp;or&nbsp;255&nbsp;if&nbsp;there&nbsp;is&nbsp;an&nbsp;uncaught<br>
-&nbsp;&nbsp;exception.</tt></dd></dl>
- <dl><dt><a name="-StoriesGroupedByStateClass"><strong>StoriesGroupedByStateClass</strong></a>(story_set, allow_multiple_groups)</dt><dd><tt>Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;story&nbsp;groups&nbsp;which&nbsp;each&nbsp;contains&nbsp;stories&nbsp;with<br>
-the&nbsp;same&nbsp;shared_state_class.<br>
-&nbsp;<br>
-Example:<br>
-&nbsp;&nbsp;Assume&nbsp;A1,&nbsp;A2,&nbsp;A3&nbsp;are&nbsp;stories&nbsp;with&nbsp;same&nbsp;shared&nbsp;story&nbsp;class,&nbsp;and<br>
-&nbsp;&nbsp;similar&nbsp;for&nbsp;B1,&nbsp;B2.<br>
-&nbsp;&nbsp;If&nbsp;their&nbsp;orders&nbsp;in&nbsp;story&nbsp;set&nbsp;is&nbsp;A1&nbsp;A2&nbsp;B1&nbsp;B2&nbsp;A3,&nbsp;then&nbsp;the&nbsp;grouping&nbsp;will<br>
-&nbsp;&nbsp;be&nbsp;[A1&nbsp;A2]&nbsp;[B1&nbsp;B2]&nbsp;[A3].<br>
-&nbsp;<br>
-It's&nbsp;purposefully&nbsp;done&nbsp;this&nbsp;way&nbsp;to&nbsp;make&nbsp;sure&nbsp;that&nbsp;order&nbsp;of<br>
-stories&nbsp;are&nbsp;the&nbsp;same&nbsp;of&nbsp;that&nbsp;defined&nbsp;in&nbsp;story_set.&nbsp;It's&nbsp;recommended&nbsp;that<br>
-stories&nbsp;with&nbsp;the&nbsp;same&nbsp;states&nbsp;should&nbsp;be&nbsp;arranged&nbsp;next&nbsp;to&nbsp;each&nbsp;others&nbsp;in<br>
-story&nbsp;sets&nbsp;to&nbsp;reduce&nbsp;the&nbsp;overhead&nbsp;of&nbsp;setting&nbsp;up&nbsp;&amp;&nbsp;tearing&nbsp;down&nbsp;the<br>
-shared&nbsp;story&nbsp;state.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html
deleted file mode 100644
index b821f2f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html
+++ /dev/null
@@ -1,220 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.testing.discoverable_classes.another_discover_dummyclass</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.<a href="telemetry.internal.testing.discoverable_classes.html"><font color="#ffffff">discoverable_classes</font></a>.another_discover_dummyclass</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/discoverable_classes/another_discover_dummyclass.py">telemetry/internal/testing/discoverable_classes/another_discover_dummyclass.py</a></font></td></tr></table>
-    <p><tt>More&nbsp;dummy&nbsp;exception&nbsp;subclasses&nbsp;used&nbsp;by&nbsp;core/discover.py's&nbsp;unit&nbsp;tests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html">telemetry.internal.testing.discoverable_classes.discover_dummyclass</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a>(<a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#DummyExceptionImpl1">DummyExceptionImpl1</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#DummyExceptionImpl2">DummyExceptionImpl2</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#DummyExceptionWithParameterImpl1">DummyExceptionWithParameterImpl1</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DummyExceptionImpl1">class <strong>DummyExceptionImpl1</strong></a>(<a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#DummyExceptionImpl1">DummyExceptionImpl1</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DummyExceptionImpl1-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DummyExceptionImpl1-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DummyExceptionImpl1-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl1-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl1-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DummyExceptionImpl2">class <strong>DummyExceptionImpl2</strong></a>(<a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#DummyExceptionImpl2">DummyExceptionImpl2</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DummyExceptionImpl2-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DummyExceptionImpl2-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DummyExceptionImpl2-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionImpl2-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionImpl2-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DummyExceptionWithParameterImpl1">class <strong>DummyExceptionWithParameterImpl1</strong></a>(<a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#DummyExceptionWithParameterImpl1">DummyExceptionWithParameterImpl1</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html#_PrivateDummyException">_PrivateDummyException</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__init__"><strong>__init__</strong></a>(self, parameter)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DummyExceptionWithParameterImpl1-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl1-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl1-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.discover_dummyclass.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.discover_dummyclass.html
deleted file mode 100644
index 8349ad3..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.discover_dummyclass.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.testing.discoverable_classes.discover_dummyclass</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.<a href="telemetry.internal.testing.discoverable_classes.html"><font color="#ffffff">discoverable_classes</font></a>.discover_dummyclass</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/discoverable_classes/discover_dummyclass.py">telemetry/internal/testing/discoverable_classes/discover_dummyclass.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;dummy&nbsp;exception&nbsp;subclass&nbsp;used&nbsp;by&nbsp;core/discover.py's&nbsp;unit&nbsp;tests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">DummyException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DummyException">class <strong>DummyException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">DummyException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DummyException-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DummyException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DummyException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.html
deleted file mode 100644
index c04239e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.testing.discoverable_classes</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.discoverable_classes</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/discoverable_classes/__init__.py">telemetry/internal/testing/discoverable_classes/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.testing.discoverable_classes.another_discover_dummyclass.html">another_discover_dummyclass</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html">discover_dummyclass</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass.html">parameter_discover_dummyclass</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass.html
deleted file mode 100644
index ab5a37d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass.html
+++ /dev/null
@@ -1,97 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.<a href="telemetry.internal.testing.discoverable_classes.html"><font color="#ffffff">discoverable_classes</font></a>.parameter_discover_dummyclass</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/discoverable_classes/parameter_discover_dummyclass.py">telemetry/internal/testing/discoverable_classes/parameter_discover_dummyclass.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;dummy&nbsp;exception&nbsp;subclass&nbsp;used&nbsp;by&nbsp;core/discover.py's&nbsp;unit&nbsp;tests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html">telemetry.internal.testing.discoverable_classes.discover_dummyclass</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass.html#DummyExceptionWithParameterImpl2">DummyExceptionWithParameterImpl2</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DummyExceptionWithParameterImpl2">class <strong>DummyExceptionWithParameterImpl2</strong></a>(<a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.discoverable_classes.parameter_discover_dummyclass.html#DummyExceptionWithParameterImpl2">DummyExceptionWithParameterImpl2</a></dd>
-<dd><a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__init__"><strong>__init__</strong></a>(self, parameter1, parameter2)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.testing.discoverable_classes.discover_dummyclass.html#DummyException">telemetry.internal.testing.discoverable_classes.discover_dummyclass.DummyException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#DummyExceptionWithParameterImpl2-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#DummyExceptionWithParameterImpl2-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="DummyExceptionWithParameterImpl2-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.html
deleted file mode 100644
index b7291d0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.testing</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.testing</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/__init__.py">telemetry/internal/testing/__init__.py</a></font></td></tr></table>
-    <p></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.testing.discoverable_classes.html"><strong>discoverable_classes</strong>&nbsp;(package)</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.testing.page_sets.html"><strong>page_sets</strong>&nbsp;(package)</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.testing.pages.html"><strong>pages</strong>&nbsp;(package)</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.testing.system_stub_test_module.html">system_stub_test_module</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.page_sets.example_domain.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.page_sets.example_domain.html
deleted file mode 100644
index 788e175..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.page_sets.example_domain.html
+++ /dev/null
@@ -1,129 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.testing.page_sets.example_domain</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.<a href="telemetry.internal.testing.page_sets.html"><font color="#ffffff">page_sets</font></a>.example_domain</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/page_sets/example_domain.py">telemetry/internal/testing/page_sets/example_domain.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.page.page.html">telemetry.page.page</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.html">telemetry.story</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.story_set.html#StorySet">telemetry.story.story_set.StorySet</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.page_sets.example_domain.html#ExampleDomainPageSet">ExampleDomainPageSet</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExampleDomainPageSet">class <strong>ExampleDomainPageSet</strong></a>(<a href="telemetry.story.story_set.html#StorySet">telemetry.story.story_set.StorySet</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.page_sets.example_domain.html#ExampleDomainPageSet">ExampleDomainPageSet</a></dd>
-<dd><a href="telemetry.story.story_set.html#StorySet">telemetry.story.story_set.StorySet</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ExampleDomainPageSet-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.story.story_set.html#StorySet">telemetry.story.story_set.StorySet</a>:<br>
-<dl><dt><a name="ExampleDomainPageSet-AddStory"><strong>AddStory</strong></a>(self, story)</dt></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-RemoveStory"><strong>RemoveStory</strong></a>(self, story)</dt><dd><tt>Removes&nbsp;a&nbsp;Story.<br>
-&nbsp;<br>
-Allows&nbsp;the&nbsp;stories&nbsp;to&nbsp;be&nbsp;filtered.</tt></dd></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-WprFilePathForStory"><strong>WprFilePathForStory</strong></a>(self, story)</dt><dd><tt>Convenient&nbsp;function&nbsp;to&nbsp;retrieve&nbsp;WPR&nbsp;archive&nbsp;file&nbsp;path.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;story:&nbsp;The&nbsp;Story&nbsp;to&nbsp;look&nbsp;up.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;WPR&nbsp;archive&nbsp;file&nbsp;path&nbsp;for&nbsp;the&nbsp;given&nbsp;Story,&nbsp;if&nbsp;found.<br>
-&nbsp;&nbsp;Otherwise,&nbsp;None.</tt></dd></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-__getitem__"><strong>__getitem__</strong></a>(self, key)</dt></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-__setitem__"><strong>__setitem__</strong></a>(self, key, value)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.story.story_set.html#StorySet">telemetry.story.story_set.StorySet</a>:<br>
-<dl><dt><a name="ExampleDomainPageSet-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Return&nbsp;a&nbsp;string&nbsp;explaining&nbsp;in&nbsp;human-understandable&nbsp;terms&nbsp;what&nbsp;this<br>
-story&nbsp;represents.<br>
-Note&nbsp;that&nbsp;this&nbsp;should&nbsp;be&nbsp;a&nbsp;classmethod&nbsp;so&nbsp;the&nbsp;benchmark_runner&nbsp;script&nbsp;can<br>
-display&nbsp;stories'&nbsp;names&nbsp;along&nbsp;with&nbsp;their&nbsp;descriptions&nbsp;in&nbsp;the&nbsp;list&nbsp;command.</tt></dd></dl>
-
-<dl><dt><a name="ExampleDomainPageSet-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;the&nbsp;string&nbsp;name&nbsp;of&nbsp;this&nbsp;<a href="telemetry.story.story_set.html#StorySet">StorySet</a>.<br>
-Note&nbsp;that&nbsp;this&nbsp;should&nbsp;be&nbsp;a&nbsp;classmethod&nbsp;so&nbsp;the&nbsp;benchmark_runner&nbsp;script&nbsp;can<br>
-match&nbsp;the&nbsp;story&nbsp;class&nbsp;with&nbsp;its&nbsp;name&nbsp;specified&nbsp;in&nbsp;the&nbsp;run&nbsp;command:<br>
-'Run&nbsp;&lt;User&nbsp;story&nbsp;test&nbsp;name&gt;&nbsp;&lt;User&nbsp;story&nbsp;class&nbsp;name&gt;'</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.story.story_set.html#StorySet">telemetry.story.story_set.StorySet</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>allow_mixed_story_states</strong></dt>
-<dd><tt>True&nbsp;iff&nbsp;Stories&nbsp;are&nbsp;allowed&nbsp;to&nbsp;have&nbsp;different&nbsp;StoryState&nbsp;classes.<br>
-&nbsp;<br>
-There&nbsp;are&nbsp;no&nbsp;checks&nbsp;in&nbsp;place&nbsp;for&nbsp;determining&nbsp;if&nbsp;SharedStates&nbsp;are<br>
-being&nbsp;assigned&nbsp;correctly&nbsp;to&nbsp;all&nbsp;Stories&nbsp;in&nbsp;a&nbsp;given&nbsp;StorySet.&nbsp;The<br>
-majority&nbsp;of&nbsp;test&nbsp;cases&nbsp;should&nbsp;not&nbsp;need&nbsp;the&nbsp;ability&nbsp;to&nbsp;have&nbsp;multiple<br>
-SharedStates,&nbsp;which&nbsp;usually&nbsp;implies&nbsp;you&nbsp;should&nbsp;be&nbsp;writing&nbsp;multiple<br>
-benchmarks&nbsp;instead.&nbsp;We&nbsp;provide&nbsp;errors&nbsp;to&nbsp;avoid&nbsp;accidentally&nbsp;assigning<br>
-or&nbsp;defaulting&nbsp;to&nbsp;the&nbsp;wrong&nbsp;SharedState.<br>
-Override&nbsp;at&nbsp;your&nbsp;own&nbsp;risk.&nbsp;Here&nbsp;be&nbsp;dragons.</tt></dd>
-</dl>
-<dl><dt><strong>archive_data_file</strong></dt>
-</dl>
-<dl><dt><strong>base_dir</strong></dt>
-<dd><tt>The&nbsp;base&nbsp;directory&nbsp;to&nbsp;resolve&nbsp;archive_data_file.<br>
-&nbsp;<br>
-This&nbsp;defaults&nbsp;to&nbsp;the&nbsp;directory&nbsp;containing&nbsp;the&nbsp;StorySet&nbsp;instance's&nbsp;class.</tt></dd>
-</dl>
-<dl><dt><strong>bucket</strong></dt>
-</dl>
-<dl><dt><strong>file_path</strong></dt>
-</dl>
-<dl><dt><strong>serving_dirs</strong></dt>
-</dl>
-<dl><dt><strong>wpr_archive_info</strong></dt>
-<dd><tt>Lazily&nbsp;constructs&nbsp;wpr_archive_info&nbsp;if&nbsp;it's&nbsp;not&nbsp;set&nbsp;and&nbsp;returns&nbsp;it.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.page_sets.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.page_sets.html
deleted file mode 100644
index 5ce64b4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.page_sets.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.testing.page_sets</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.page_sets</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/page_sets/__init__.py">telemetry/internal/testing/page_sets/__init__.py</a></font></td></tr></table>
-    <p></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.testing.page_sets.example_domain.html">example_domain</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.pages.external_page.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.pages.external_page.html
deleted file mode 100644
index 5f0c00c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.pages.external_page.html
+++ /dev/null
@@ -1,130 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.testing.pages.external_page</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.<a href="telemetry.internal.testing.pages.html"><font color="#ffffff">pages</font></a>.external_page</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/pages/external_page.py">telemetry/internal/testing/pages/external_page.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.html#Page">telemetry.page.Page</a>(<a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.pages.external_page.html#ExternalPage">ExternalPage</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ExternalPage">class <strong>ExternalPage</strong></a>(<a href="telemetry.page.html#Page">telemetry.page.Page</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.testing.pages.external_page.html#ExternalPage">ExternalPage</a></dd>
-<dd><a href="telemetry.page.html#Page">telemetry.page.Page</a></dd>
-<dd><a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ExternalPage-__init__"><strong>__init__</strong></a>(self, ps)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.page.html#Page">telemetry.page.Page</a>:<br>
-<dl><dt><a name="ExternalPage-AddCustomizeBrowserOptions"><strong>AddCustomizeBrowserOptions</strong></a>(self, options)</dt><dd><tt>Inherit&nbsp;page&nbsp;overrides&nbsp;this&nbsp;to&nbsp;add&nbsp;customized&nbsp;browser&nbsp;options.</tt></dd></dl>
-
-<dl><dt><a name="ExternalPage-AsDict"><strong>AsDict</strong></a>(self)</dt><dd><tt>Converts&nbsp;a&nbsp;page&nbsp;object&nbsp;to&nbsp;a&nbsp;dict&nbsp;suitable&nbsp;for&nbsp;JSON&nbsp;output.</tt></dd></dl>
-
-<dl><dt><a name="ExternalPage-GetSyntheticDelayCategories"><strong>GetSyntheticDelayCategories</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ExternalPage-Run"><strong>Run</strong></a>(self, shared_state)</dt></dl>
-
-<dl><dt><a name="ExternalPage-RunNavigateSteps"><strong>RunNavigateSteps</strong></a>(self, action_runner)</dt></dl>
-
-<dl><dt><a name="ExternalPage-RunPageInteractions"><strong>RunPageInteractions</strong></a>(self, action_runner)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;define&nbsp;custom&nbsp;interactions&nbsp;with&nbsp;the&nbsp;page.<br>
-e.g:<br>
-&nbsp;&nbsp;def&nbsp;<a href="#ExternalPage-RunPageInteractions">RunPageInteractions</a>(self,&nbsp;action_runner):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.ScrollPage()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.TapElement(text='Next')</tt></dd></dl>
-
-<dl><dt><a name="ExternalPage-__cmp__"><strong>__cmp__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="ExternalPage-__lt__"><strong>__lt__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="ExternalPage-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.html#Page">telemetry.page.Page</a>:<br>
-<dl><dt><strong>base_dir</strong></dt>
-</dl>
-<dl><dt><strong>credentials_path</strong></dt>
-</dl>
-<dl><dt><strong>display_name</strong></dt>
-</dl>
-<dl><dt><strong>file_path</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;path&nbsp;of&nbsp;the&nbsp;file,&nbsp;stripping&nbsp;the&nbsp;scheme&nbsp;and&nbsp;query&nbsp;string.</tt></dd>
-</dl>
-<dl><dt><strong>file_path_url</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;file&nbsp;path,&nbsp;including&nbsp;the&nbsp;params,&nbsp;query,&nbsp;and&nbsp;fragment.</tt></dd>
-</dl>
-<dl><dt><strong>file_path_url_with_scheme</strong></dt>
-</dl>
-<dl><dt><strong>is_file</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;URL&nbsp;points&nbsp;to&nbsp;a&nbsp;file.</tt></dd>
-</dl>
-<dl><dt><strong>page_set</strong></dt>
-</dl>
-<dl><dt><strong>serving_dir</strong></dt>
-</dl>
-<dl><dt><strong>startup_url</strong></dt>
-</dl>
-<dl><dt><strong>story_set</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>file_safe_name</strong></dt>
-<dd><tt>A&nbsp;version&nbsp;of&nbsp;display_name&nbsp;that's&nbsp;safe&nbsp;to&nbsp;use&nbsp;as&nbsp;a&nbsp;filename.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;sanitizes&nbsp;special&nbsp;characters&nbsp;with&nbsp;underscores,<br>
-but&nbsp;it's&nbsp;okay&nbsp;to&nbsp;override&nbsp;it&nbsp;with&nbsp;a&nbsp;more&nbsp;specific&nbsp;implementation&nbsp;in<br>
-subclasses.</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-<dl><dt><strong>is_local</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;story&nbsp;does&nbsp;not&nbsp;require&nbsp;network.</tt></dd>
-</dl>
-<dl><dt><strong>labels</strong></dt>
-</dl>
-<dl><dt><strong>make_javascript_deterministic</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>shared_state_class</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.pages.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.pages.html
deleted file mode 100644
index a21c90c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.pages.html
+++ /dev/null
@@ -1,23 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.testing.pages</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.pages</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/pages/__init__.py">telemetry/internal/testing/pages/__init__.py</a></font></td></tr></table>
-    <p></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.testing.pages.external_page.html">external_page</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.system_stub_test_module.html b/catapult/telemetry/docs/pydoc/telemetry.internal.testing.system_stub_test_module.html
deleted file mode 100644
index f5969be..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.testing.system_stub_test_module.html
+++ /dev/null
@@ -1,54 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.testing.system_stub_test_module</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.testing.html"><font color="#ffffff">testing</font></a>.system_stub_test_module</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/testing/system_stub_test_module.py">telemetry/internal/testing/system_stub_test_module.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.testing.system_stub_test_module.html#SystemStubTest">SystemStubTest</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SystemStubTest">class <strong>SystemStubTest</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Static methods defined here:<br>
-<dl><dt><a name="SystemStubTest-TestOpen"><strong>TestOpen</strong></a>(file_path)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.binary_manager.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.binary_manager.html
deleted file mode 100644
index 3ad540f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.binary_manager.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.binary_manager</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.binary_manager</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/binary_manager.py">telemetry/internal/util/binary_manager.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="catapult_base.dependency_manager.html">catapult_base.dependency_manager</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FetchPath"><strong>FetchPath</strong></a>(binary_name, arch, platform)</dt><dd><tt>Return&nbsp;a&nbsp;path&nbsp;to&nbsp;the&nbsp;appropriate&nbsp;executable&nbsp;for&nbsp;&lt;binary_name&gt;,&nbsp;downloading<br>
-from&nbsp;cloud&nbsp;storage&nbsp;if&nbsp;needed,&nbsp;or&nbsp;None&nbsp;if&nbsp;it&nbsp;cannot&nbsp;be&nbsp;found.</tt></dd></dl>
- <dl><dt><a name="-InitDependencyManager"><strong>InitDependencyManager</strong></a>(environment_config)</dt></dl>
- <dl><dt><a name="-LocalPath"><strong>LocalPath</strong></a>(binary_name, arch, platform)</dt><dd><tt>Return&nbsp;a&nbsp;local&nbsp;path&nbsp;to&nbsp;the&nbsp;given&nbsp;binary&nbsp;name,&nbsp;or&nbsp;None&nbsp;if&nbsp;an&nbsp;executable<br>
-cannot&nbsp;be&nbsp;found.&nbsp;Will&nbsp;not&nbsp;download&nbsp;the&nbsp;executable.</tt></dd></dl>
- <dl><dt><a name="-NeedsInit"><strong>NeedsInit</strong></a>()</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>TELEMETRY_PROJECT_CONFIG</strong> = '/usr/local/google/home/nednguyen/projects/chromi...metry/telemetry/internal/binary_dependencies.json'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.bootstrap.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.bootstrap.html
deleted file mode 100644
index c025b3c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.bootstrap.html
+++ /dev/null
@@ -1,124 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.bootstrap</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.bootstrap</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/bootstrap.py">telemetry/internal/util/bootstrap.py</a></font></td></tr></table>
-    <p><tt>Bootstrap&nbsp;Chrome&nbsp;Telemetry&nbsp;by&nbsp;downloading&nbsp;all&nbsp;its&nbsp;files&nbsp;from&nbsp;SVN&nbsp;servers.<br>
-&nbsp;<br>
-Requires&nbsp;a&nbsp;DEPS&nbsp;file&nbsp;to&nbsp;specify&nbsp;which&nbsp;directories&nbsp;on&nbsp;which&nbsp;SVN&nbsp;servers<br>
-are&nbsp;required&nbsp;to&nbsp;run&nbsp;Telemetry.&nbsp;Format&nbsp;of&nbsp;that&nbsp;DEPS&nbsp;file&nbsp;is&nbsp;a&nbsp;subset&nbsp;of&nbsp;the<br>
-normal&nbsp;DEPS&nbsp;file&nbsp;format[1];&nbsp;currently&nbsp;only&nbsp;only&nbsp;the&nbsp;"deps"&nbsp;dictionary&nbsp;is<br>
-supported&nbsp;and&nbsp;nothing&nbsp;else.<br>
-&nbsp;<br>
-Fetches&nbsp;all&nbsp;files&nbsp;in&nbsp;the&nbsp;specified&nbsp;directories&nbsp;using&nbsp;WebDAV&nbsp;(SVN&nbsp;is&nbsp;WebDAV&nbsp;under<br>
-the&nbsp;hood).<br>
-&nbsp;<br>
-[1]&nbsp;<a href="http://dev.chromium.org/developers/how-tos/depottools#TOC-DEPS-file">http://dev.chromium.org/developers/how-tos/depottools#TOC-DEPS-file</a></tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="imp.html">imp</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="urllib.html">urllib</a><br>
-</td><td width="25%" valign=top><a href="urlparse.html">urlparse</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.bootstrap.html#DAVClientWrapper">DAVClientWrapper</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DAVClientWrapper">class <strong>DAVClientWrapper</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Knows&nbsp;how&nbsp;to&nbsp;retrieve&nbsp;subdirectories&nbsp;and&nbsp;files&nbsp;from&nbsp;WebDAV/SVN&nbsp;servers.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="DAVClientWrapper-GetDirList"><strong>GetDirList</strong></a>(self, path)</dt><dd><tt>Returns&nbsp;string&nbsp;names&nbsp;of&nbsp;all&nbsp;files&nbsp;and&nbsp;subdirs&nbsp;of&nbsp;path&nbsp;on&nbsp;the&nbsp;server.</tt></dd></dl>
-
-<dl><dt><a name="DAVClientWrapper-IsFile"><strong>IsFile</strong></a>(self, path)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;path&nbsp;is&nbsp;a&nbsp;file&nbsp;on&nbsp;the&nbsp;server,&nbsp;False&nbsp;if&nbsp;directory.</tt></dd></dl>
-
-<dl><dt><a name="DAVClientWrapper-Traverse"><strong>Traverse</strong></a>(self, src_path, dst_path)</dt><dd><tt>Walks&nbsp;the&nbsp;directory&nbsp;hierarchy&nbsp;pointed&nbsp;to&nbsp;by&nbsp;src_path&nbsp;download&nbsp;all&nbsp;files.<br>
-&nbsp;<br>
-Recursively&nbsp;walks&nbsp;src_path&nbsp;and&nbsp;saves&nbsp;all&nbsp;files&nbsp;and&nbsp;subfolders&nbsp;into<br>
-dst_path.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;src_path:&nbsp;string&nbsp;path&nbsp;on&nbsp;SVN&nbsp;server&nbsp;to&nbsp;save&nbsp;(absolute&nbsp;path&nbsp;on&nbsp;server).<br>
-&nbsp;&nbsp;dest_path:&nbsp;string&nbsp;local&nbsp;path&nbsp;(relative&nbsp;or&nbsp;absolute)&nbsp;to&nbsp;save&nbsp;to.</tt></dd></dl>
-
-<dl><dt><a name="DAVClientWrapper-__init__"><strong>__init__</strong></a>(self, root_url)</dt><dd><tt>Initialize&nbsp;SVN&nbsp;server&nbsp;root_url,&nbsp;save&nbsp;files&nbsp;to&nbsp;local&nbsp;dest_dir.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;root_url:&nbsp;string&nbsp;url&nbsp;of&nbsp;SVN/WebDAV&nbsp;server</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-DownloadDeps"><strong>DownloadDeps</strong></a>(destination_dir, url)</dt><dd><tt>Saves&nbsp;all&nbsp;the&nbsp;dependencies&nbsp;in&nbsp;deps_path.<br>
-&nbsp;<br>
-Opens&nbsp;and&nbsp;reads&nbsp;url,&nbsp;assuming&nbsp;the&nbsp;contents&nbsp;are&nbsp;in&nbsp;the&nbsp;simple&nbsp;DEPS-like&nbsp;file<br>
-format&nbsp;specified&nbsp;in&nbsp;the&nbsp;header&nbsp;of&nbsp;this&nbsp;file,&nbsp;then&nbsp;download&nbsp;all<br>
-files/directories&nbsp;listed&nbsp;to&nbsp;the&nbsp;destination_dir.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;destination_dir:&nbsp;String&nbsp;path&nbsp;to&nbsp;directory&nbsp;to&nbsp;download&nbsp;files&nbsp;into.<br>
-&nbsp;&nbsp;url:&nbsp;URL&nbsp;containing&nbsp;deps&nbsp;information&nbsp;to&nbsp;be&nbsp;evaluated.</tt></dd></dl>
- <dl><dt><a name="-ListAllDepsPaths"><strong>ListAllDepsPaths</strong></a>(deps_file)</dt><dd><tt>Recursively&nbsp;returns&nbsp;a&nbsp;list&nbsp;of&nbsp;all&nbsp;paths&nbsp;indicated&nbsp;in&nbsp;this&nbsp;deps&nbsp;file.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;this&nbsp;discards&nbsp;information&nbsp;about&nbsp;where&nbsp;path&nbsp;dependencies&nbsp;come&nbsp;from,<br>
-so&nbsp;this&nbsp;is&nbsp;only&nbsp;useful&nbsp;in&nbsp;the&nbsp;context&nbsp;of&nbsp;a&nbsp;Chromium&nbsp;source&nbsp;checkout&nbsp;that&nbsp;has<br>
-already&nbsp;fetched&nbsp;all&nbsp;dependencies.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;deps_file:&nbsp;File&nbsp;containing&nbsp;deps&nbsp;information&nbsp;to&nbsp;be&nbsp;evaluated,&nbsp;in&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format&nbsp;given&nbsp;in&nbsp;the&nbsp;header&nbsp;of&nbsp;this&nbsp;file.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;string&nbsp;paths&nbsp;starting&nbsp;under&nbsp;src&nbsp;that&nbsp;are&nbsp;required&nbsp;by&nbsp;the<br>
-&nbsp;&nbsp;given&nbsp;deps&nbsp;file,&nbsp;and&nbsp;all&nbsp;of&nbsp;its&nbsp;sub-dependencies.&nbsp;This&nbsp;amounts&nbsp;to<br>
-&nbsp;&nbsp;the&nbsp;keys&nbsp;of&nbsp;the&nbsp;'deps'&nbsp;dictionary.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>davclient</strong> = None</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.camel_case.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.camel_case.html
deleted file mode 100644
index 5aeb7cc..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.camel_case.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.camel_case</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.camel_case</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/camel_case.py">telemetry/internal/util/camel_case.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ToUnderscore"><strong>ToUnderscore</strong></a>(obj)</dt><dd><tt>Converts&nbsp;a&nbsp;string,&nbsp;list,&nbsp;or&nbsp;dict&nbsp;from&nbsp;camelCase&nbsp;to&nbsp;lower_with_underscores.<br>
-&nbsp;<br>
-Descends&nbsp;recursively&nbsp;into&nbsp;lists&nbsp;and&nbsp;dicts,&nbsp;converting&nbsp;all&nbsp;dict&nbsp;keys.<br>
-Returns&nbsp;a&nbsp;newly&nbsp;allocated&nbsp;object&nbsp;of&nbsp;the&nbsp;same&nbsp;structure&nbsp;as&nbsp;the&nbsp;input.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.classes.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.classes.html
deleted file mode 100644
index edac79e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.classes.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.classes</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.classes</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/classes.py">telemetry/internal/util/classes.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-IsDirectlyConstructable"><strong>IsDirectlyConstructable</strong></a>(cls)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;instance&nbsp;of&nbsp;|cls|&nbsp;can&nbsp;be&nbsp;construct&nbsp;without&nbsp;arguments.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.command_line.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.command_line.html
deleted file mode 100644
index e72ea18..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.command_line.html
+++ /dev/null
@@ -1,243 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.command_line</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.command_line</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/command_line.py">telemetry/internal/util/command_line.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="argparse.html">argparse</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.camel_case.html">telemetry.internal.util.camel_case</a><br>
-</td><td width="25%" valign=top><a href="difflib.html">difflib</a><br>
-</td><td width="25%" valign=top><a href="optparse.html">optparse</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#Command">Command</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#OptparseCommand">OptparseCommand</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#SubcommandCommand">SubcommandCommand</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ArgumentHandlerMixIn">class <strong>ArgumentHandlerMixIn</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;structured&nbsp;way&nbsp;to&nbsp;handle&nbsp;command-line&nbsp;arguments.<br>
-&nbsp;<br>
-In&nbsp;AddCommandLineArgs,&nbsp;add&nbsp;command-line&nbsp;arguments.<br>
-In&nbsp;ProcessCommandLineArgs,&nbsp;validate&nbsp;them&nbsp;and&nbsp;store&nbsp;them&nbsp;in&nbsp;a&nbsp;private&nbsp;class<br>
-variable.&nbsp;This&nbsp;way,&nbsp;each&nbsp;class&nbsp;encapsulates&nbsp;its&nbsp;own&nbsp;arguments,&nbsp;without&nbsp;needing<br>
-to&nbsp;pass&nbsp;an&nbsp;arguments&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;around&nbsp;everywhere.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Class methods defined here:<br>
-<dl><dt><a name="ArgumentHandlerMixIn-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;accept&nbsp;custom&nbsp;command-line&nbsp;arguments.</tt></dd></dl>
-
-<dl><dt><a name="ArgumentHandlerMixIn-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;process&nbsp;command-line&nbsp;arguments.<br>
-&nbsp;<br>
-We&nbsp;pass&nbsp;in&nbsp;parser&nbsp;so&nbsp;we&nbsp;can&nbsp;call&nbsp;parser.error().</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Command">class <strong>Command</strong></a>(<a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;abstraction&nbsp;for&nbsp;things&nbsp;that&nbsp;run&nbsp;from&nbsp;the&nbsp;command-line.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.command_line.html#Command">Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Command-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Command-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Command-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="Command-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a>:<br>
-<dl><dt><a name="Command-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;accept&nbsp;custom&nbsp;command-line&nbsp;arguments.</tt></dd></dl>
-
-<dl><dt><a name="Command-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;process&nbsp;command-line&nbsp;arguments.<br>
-&nbsp;<br>
-We&nbsp;pass&nbsp;in&nbsp;parser&nbsp;so&nbsp;we&nbsp;can&nbsp;call&nbsp;parser.error().</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="OptparseCommand">class <strong>OptparseCommand</strong></a>(<a href="telemetry.internal.util.command_line.html#Command">Command</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;TODO:&nbsp;Convert&nbsp;everything&nbsp;to&nbsp;argparse.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.command_line.html#OptparseCommand">OptparseCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="OptparseCommand-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="OptparseCommand-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="OptparseCommand-CreateParser"><strong>CreateParser</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="OptparseCommand-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args, environment)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="OptparseCommand-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>usage</strong> = ''</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">Command</a>:<br>
-<dl><dt><a name="OptparseCommand-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="OptparseCommand-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SubcommandCommand">class <strong>SubcommandCommand</strong></a>(<a href="telemetry.internal.util.command_line.html#Command">Command</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Combines&nbsp;Commands&nbsp;into&nbsp;one&nbsp;big&nbsp;command&nbsp;with&nbsp;sub-commands.<br>
-&nbsp;<br>
-E.g.&nbsp;"svn&nbsp;checkout",&nbsp;"svn&nbsp;update",&nbsp;and&nbsp;"svn&nbsp;commit"&nbsp;are&nbsp;separate&nbsp;sub-commands.<br>
-&nbsp;<br>
-Example&nbsp;usage:<br>
-&nbsp;&nbsp;class&nbsp;MyCommand(command_line.<a href="#SubcommandCommand">SubcommandCommand</a>):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;commands&nbsp;=&nbsp;(Help,&nbsp;List,&nbsp;Run)<br>
-&nbsp;<br>
-&nbsp;&nbsp;if&nbsp;__name__&nbsp;==&nbsp;'__main__':<br>
-&nbsp;&nbsp;&nbsp;&nbsp;sys.exit(MyCommand.<a href="#SubcommandCommand-main">main</a>())<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.command_line.html#SubcommandCommand">SubcommandCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SubcommandCommand-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="SubcommandCommand-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="SubcommandCommand-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>commands</strong> = ()</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">Command</a>:<br>
-<dl><dt><a name="SubcommandCommand-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="SubcommandCommand-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="SubcommandCommand-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetMostLikelyMatchedObject"><strong>GetMostLikelyMatchedObject</strong></a>(objects, target_name, name_func<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, matched_score_threshold<font color="#909090">=0.4</font>)</dt><dd><tt>Matches&nbsp;objects&nbsp;whose&nbsp;names&nbsp;are&nbsp;most&nbsp;likely&nbsp;matched&nbsp;with&nbsp;target.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;objects:&nbsp;list&nbsp;of&nbsp;objects&nbsp;to&nbsp;match.<br>
-&nbsp;&nbsp;target_name:&nbsp;name&nbsp;to&nbsp;match.<br>
-&nbsp;&nbsp;name_func:&nbsp;function&nbsp;to&nbsp;get&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;name&nbsp;to&nbsp;match.&nbsp;Default&nbsp;bypass.<br>
-&nbsp;&nbsp;matched_score_threshold:&nbsp;threshold&nbsp;of&nbsp;likelihood&nbsp;to&nbsp;match.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;objects&nbsp;whose&nbsp;names&nbsp;are&nbsp;likely&nbsp;target_name.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.exception_formatter.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.exception_formatter.html
deleted file mode 100644
index f740f7f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.exception_formatter.html
+++ /dev/null
@@ -1,37 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.exception_formatter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.exception_formatter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/exception_formatter.py">telemetry/internal/util/exception_formatter.py</a></font></td></tr></table>
-    <p><tt>Print&nbsp;prettier&nbsp;and&nbsp;more&nbsp;detailed&nbsp;exceptions.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="math.html">math</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="traceback.html">traceback</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-PrintFormattedException"><strong>PrintFormattedException</strong></a>(exception_class<font color="#909090">=None</font>, exception<font color="#909090">=None</font>, tb<font color="#909090">=None</font>, msg<font color="#909090">=None</font>)</dt></dl>
- <dl><dt><a name="-PrintFormattedFrame"><strong>PrintFormattedFrame</strong></a>(frame, exception_string<font color="#909090">=None</font>)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.external_modules.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.external_modules.html
deleted file mode 100644
index 88bc19c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.external_modules.html
+++ /dev/null
@@ -1,50 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.external_modules</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.external_modules</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/external_modules.py">telemetry/internal/util/external_modules.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="importlib.html">importlib</a><br>
-</td><td width="25%" valign=top><a href="distutils.version.html">distutils.version</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ImportOptionalModule"><strong>ImportOptionalModule</strong></a>(module)</dt><dd><tt>Tries&nbsp;to&nbsp;import&nbsp;the&nbsp;desired&nbsp;module.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;module&nbsp;if&nbsp;successful,&nbsp;None&nbsp;if&nbsp;not.</tt></dd></dl>
- <dl><dt><a name="-ImportRequiredModule"><strong>ImportRequiredModule</strong></a>(module)</dt><dd><tt>Tries&nbsp;to&nbsp;import&nbsp;the&nbsp;desired&nbsp;module.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;module&nbsp;on&nbsp;success,&nbsp;raises&nbsp;error&nbsp;on&nbsp;failure.<br>
-Raises:<br>
-&nbsp;&nbsp;ImportError:&nbsp;The&nbsp;import&nbsp;failed.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>MODULES</strong> = {'cv2': (StrictVersion ('2.4.8'), StrictVersion ('3.0')), 'numpy': (StrictVersion ('1.6.1'), None), 'psutil': (StrictVersion ('0.5'), None)}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.file_handle.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.file_handle.html
deleted file mode 100644
index 6d0a692..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.file_handle.html
+++ /dev/null
@@ -1,95 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.file_handle</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.file_handle</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/file_handle.py">telemetry/internal/util/file_handle.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.file_handle.html#FileHandle">FileHandle</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FileHandle">class <strong>FileHandle</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FileHandle-GetAbsPath"><strong>GetAbsPath</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;path&nbsp;to&nbsp;the&nbsp;pointed-to&nbsp;file&nbsp;relative&nbsp;to&nbsp;the&nbsp;given&nbsp;start&nbsp;path.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;start:&nbsp;A&nbsp;string&nbsp;representing&nbsp;a&nbsp;starting&nbsp;path.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;string&nbsp;giving&nbsp;the&nbsp;relative&nbsp;path&nbsp;from&nbsp;path&nbsp;to&nbsp;this&nbsp;file.</tt></dd></dl>
-
-<dl><dt><a name="FileHandle-__init__"><strong>__init__</strong></a>(self, temp_file<font color="#909090">=None</font>, absolute_path<font color="#909090">=None</font>)</dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="#FileHandle">FileHandle</a>&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;<br>
-This&nbsp;constructor&nbsp;should&nbsp;not&nbsp;be&nbsp;used&nbsp;by&nbsp;the&nbsp;user;&nbsp;rather&nbsp;it&nbsp;is&nbsp;preferred&nbsp;to<br>
-use&nbsp;the&nbsp;module-level&nbsp;GetAbsPath&nbsp;and&nbsp;FromTempFile&nbsp;functions.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;temp_file:&nbsp;An&nbsp;instance&nbsp;of&nbsp;a&nbsp;temporary&nbsp;file&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;&nbsp;absolute_path:&nbsp;A&nbsp;path;&nbsp;should&nbsp;not&nbsp;be&nbsp;passed&nbsp;if&nbsp;tempfile&nbsp;is&nbsp;and&nbsp;vice-versa.<br>
-&nbsp;&nbsp;extension:&nbsp;A&nbsp;string&nbsp;that&nbsp;specifies&nbsp;the&nbsp;file&nbsp;extension.&nbsp;It&nbsp;must&nbsp;starts&nbsp;with<br>
-&nbsp;&nbsp;&nbsp;&nbsp;".".</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>extension</strong></dt>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FromFilePath"><strong>FromFilePath</strong></a>(path)</dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="#FileHandle">FileHandle</a>&nbsp;from&nbsp;an&nbsp;absolute&nbsp;file&nbsp;path.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;A&nbsp;string&nbsp;giving&nbsp;the&nbsp;absolute&nbsp;path&nbsp;to&nbsp;a&nbsp;file.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;<a href="#FileHandle">FileHandle</a>&nbsp;referring&nbsp;to&nbsp;the&nbsp;file&nbsp;at&nbsp;the&nbsp;specified&nbsp;path.</tt></dd></dl>
- <dl><dt><a name="-FromTempFile"><strong>FromTempFile</strong></a>(temp_file)</dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="#FileHandle">FileHandle</a>&nbsp;pointing&nbsp;to&nbsp;a&nbsp;temporary&nbsp;file.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;<a href="#FileHandle">FileHandle</a>&nbsp;referring&nbsp;to&nbsp;a&nbsp;named&nbsp;temporary&nbsp;file.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.find_dependencies.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.find_dependencies.html
deleted file mode 100644
index 5187ee5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.find_dependencies.html
+++ /dev/null
@@ -1,123 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.find_dependencies</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.find_dependencies</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/find_dependencies.py">telemetry/internal/util/find_dependencies.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.benchmark.html">telemetry.benchmark</a><br>
-<a href="telemetry.internal.util.bootstrap.html">telemetry.internal.util.bootstrap</a><br>
-<a href="telemetry.internal.util.command_line.html">telemetry.internal.util.command_line</a><br>
-<a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-</td><td width="25%" valign=top><a href="fnmatch.html">fnmatch</a><br>
-<a href="imp.html">imp</a><br>
-<a href="logging.html">logging</a><br>
-<a href="modulegraph.modulegraph.html">modulegraph.modulegraph</a><br>
-</td><td width="25%" valign=top><a href="optparse.html">optparse</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-<a href="telemetry.internal.util.path_set.html">telemetry.internal.util.path_set</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="zipfile.html">zipfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>(<a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.find_dependencies.html#FindDependenciesCommand">FindDependenciesCommand</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FindDependenciesCommand">class <strong>FindDependenciesCommand</strong></a>(<a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Prints&nbsp;all&nbsp;dependencies<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.find_dependencies.html#FindDependenciesCommand">FindDependenciesCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FindDependenciesCommand-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="FindDependenciesCommand-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser, _)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="FindDependenciesCommand-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args, _)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>:<br>
-<dl><dt><a name="FindDependenciesCommand-CreateParser"><strong>CreateParser</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="FindDependenciesCommand-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Main&nbsp;method&nbsp;to&nbsp;run&nbsp;this&nbsp;command&nbsp;as&nbsp;a&nbsp;standalone&nbsp;script.</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>:<br>
-<dl><dt><strong>usage</strong> = ''</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>:<br>
-<dl><dt><a name="FindDependenciesCommand-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="FindDependenciesCommand-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindBootstrapDependencies"><strong>FindBootstrapDependencies</strong></a>(base_dir)</dt></dl>
- <dl><dt><a name="-FindDependencies"><strong>FindDependencies</strong></a>(target_paths, options)</dt></dl>
- <dl><dt><a name="-FindExcludedFiles"><strong>FindExcludedFiles</strong></a>(files, options)</dt></dl>
- <dl><dt><a name="-FindPageSetDependencies"><strong>FindPageSetDependencies</strong></a>(base_dir)</dt></dl>
- <dl><dt><a name="-FindPythonDependencies"><strong>FindPythonDependencies</strong></a>(module_path)</dt></dl>
- <dl><dt><a name="-ZipDependencies"><strong>ZipDependencies</strong></a>(target_paths, dependencies, options)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEPS_FILE</strong> = 'bootstrap_deps'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.global_hooks.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.global_hooks.html
deleted file mode 100644
index 10681f4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.global_hooks.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.global_hooks</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.global_hooks</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/global_hooks.py">telemetry/internal/util/global_hooks.py</a></font></td></tr></table>
-    <p><tt>Hooks&nbsp;that&nbsp;apply&nbsp;globally&nbsp;to&nbsp;all&nbsp;scripts&nbsp;that&nbsp;import&nbsp;or&nbsp;use&nbsp;Telemetry.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.exception_formatter.html">telemetry.internal.util.exception_formatter</a><br>
-</td><td width="25%" valign=top><a href="signal.html">signal</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-InstallHooks"><strong>InstallHooks</strong></a>()</dt></dl>
- <dl><dt><a name="-InstallStackDumpOnSigusr1"><strong>InstallStackDumpOnSigusr1</strong></a>()</dt><dd><tt>Catch&nbsp;SIGUSR1&nbsp;and&nbsp;print&nbsp;a&nbsp;stack&nbsp;trace.</tt></dd></dl>
- <dl><dt><a name="-InstallTerminationHook"><strong>InstallTerminationHook</strong></a>()</dt><dd><tt>Catch&nbsp;SIGTERM,&nbsp;print&nbsp;a&nbsp;stack&nbsp;trace,&nbsp;and&nbsp;exit.</tt></dd></dl>
- <dl><dt><a name="-InstallUnhandledExceptionFormatter"><strong>InstallUnhandledExceptionFormatter</strong></a>()</dt><dd><tt>Print&nbsp;prettier&nbsp;exceptions&nbsp;that&nbsp;also&nbsp;contain&nbsp;the&nbsp;stack&nbsp;frame's&nbsp;locals.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.html
deleted file mode 100644
index bc906a0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.internal.util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/__init__.py">telemetry/internal/util/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">binary_manager</a><br>
-<a href="telemetry.internal.util.binary_manager_unittest.html">binary_manager_unittest</a><br>
-<a href="telemetry.internal.util.bootstrap.html">bootstrap</a><br>
-<a href="telemetry.internal.util.camel_case.html">camel_case</a><br>
-<a href="telemetry.internal.util.camel_case_unittest.html">camel_case_unittest</a><br>
-<a href="telemetry.internal.util.classes.html">classes</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.classes_unittest.html">classes_unittest</a><br>
-<a href="telemetry.internal.util.command_line.html">command_line</a><br>
-<a href="telemetry.internal.util.command_line_unittest.html">command_line_unittest</a><br>
-<a href="telemetry.internal.util.exception_formatter.html">exception_formatter</a><br>
-<a href="telemetry.internal.util.external_modules.html">external_modules</a><br>
-<a href="telemetry.internal.util.file_handle.html">file_handle</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.file_handle_unittest.html">file_handle_unittest</a><br>
-<a href="telemetry.internal.util.find_dependencies.html">find_dependencies</a><br>
-<a href="telemetry.internal.util.find_dependencies_unittest.html">find_dependencies_unittest</a><br>
-<a href="telemetry.internal.util.global_hooks.html">global_hooks</a><br>
-<a href="telemetry.internal.util.path.html">path</a><br>
-<a href="telemetry.internal.util.path_set.html">path_set</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path_set_unittest.html">path_set_unittest</a><br>
-<a href="telemetry.internal.util.path_unittest.html">path_unittest</a><br>
-<a href="telemetry.internal.util.ps_util.html">ps_util</a><br>
-<a href="telemetry.internal.util.webpagereplay.html">webpagereplay</a><br>
-<a href="telemetry.internal.util.webpagereplay_unittest.html">webpagereplay_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.path.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.path.html
deleted file mode 100644
index a1c3389..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.path.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.path</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.path</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/path.py">telemetry/internal/util/path.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FindInstalledWindowsApplication"><strong>FindInstalledWindowsApplication</strong></a>(application_path)</dt><dd><tt>Search&nbsp;common&nbsp;Windows&nbsp;installation&nbsp;directories&nbsp;for&nbsp;an&nbsp;application.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;application_path:&nbsp;Path&nbsp;to&nbsp;application&nbsp;relative&nbsp;from&nbsp;installation&nbsp;location.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;string&nbsp;representing&nbsp;the&nbsp;full&nbsp;path,&nbsp;or&nbsp;None&nbsp;if&nbsp;not&nbsp;found.</tt></dd></dl>
- <dl><dt><a name="-IsExecutable"><strong>IsExecutable</strong></a>(path)</dt></dl>
- <dl><dt><a name="-IsSubpath"><strong>IsSubpath</strong></a>(subpath, superpath)</dt><dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;subpath&nbsp;is&nbsp;or&nbsp;is&nbsp;in&nbsp;superpath.</tt></dd></dl>
- <dl><dt><a name="-ListFiles"><strong>ListFiles</strong></a>(base_directory, should_include_dir<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, should_include_file<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.path_set.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.path_set.html
deleted file mode 100644
index 1e96faa..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.path_set.html
+++ /dev/null
@@ -1,150 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.path_set</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.path_set</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/path_set.py">telemetry/internal/util/path_set.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="_abcoll.html#MutableSet">_abcoll.MutableSet</a>(<a href="_abcoll.html#Set">_abcoll.Set</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.path_set.html#PathSet">PathSet</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PathSet">class <strong>PathSet</strong></a>(<a href="_abcoll.html#MutableSet">_abcoll.MutableSet</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;set&nbsp;of&nbsp;paths.<br>
-&nbsp;<br>
-All&nbsp;mutation&nbsp;methods&nbsp;can&nbsp;take&nbsp;both&nbsp;directories&nbsp;or&nbsp;individual&nbsp;files,&nbsp;but&nbsp;the<br>
-iterator&nbsp;yields&nbsp;the&nbsp;individual&nbsp;files.&nbsp;All&nbsp;paths&nbsp;are&nbsp;automatically&nbsp;normalized.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.path_set.html#PathSet">PathSet</a></dd>
-<dd><a href="_abcoll.html#MutableSet">_abcoll.MutableSet</a></dd>
-<dd><a href="_abcoll.html#Set">_abcoll.Set</a></dd>
-<dd><a href="_abcoll.html#Sized">_abcoll.Sized</a></dd>
-<dd><a href="_abcoll.html#Iterable">_abcoll.Iterable</a></dd>
-<dd><a href="_abcoll.html#Container">_abcoll.Container</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PathSet-__contains__"><strong>__contains__</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="PathSet-__init__"><strong>__init__</strong></a>(self, iterable<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="PathSet-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PathSet-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PathSet-add"><strong>add</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="PathSet-discard"><strong>discard</strong></a>(self, path)</dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>__abstractmethods__</strong> = frozenset([])</dl>
-
-<hr>
-Methods inherited from <a href="_abcoll.html#MutableSet">_abcoll.MutableSet</a>:<br>
-<dl><dt><a name="PathSet-__iand__"><strong>__iand__</strong></a>(self, it)</dt></dl>
-
-<dl><dt><a name="PathSet-__ior__"><strong>__ior__</strong></a>(self, it)</dt></dl>
-
-<dl><dt><a name="PathSet-__isub__"><strong>__isub__</strong></a>(self, it)</dt></dl>
-
-<dl><dt><a name="PathSet-__ixor__"><strong>__ixor__</strong></a>(self, it)</dt></dl>
-
-<dl><dt><a name="PathSet-clear"><strong>clear</strong></a>(self)</dt><dd><tt>This&nbsp;is&nbsp;slow&nbsp;(creates&nbsp;N&nbsp;new&nbsp;iterators!)&nbsp;but&nbsp;effective.</tt></dd></dl>
-
-<dl><dt><a name="PathSet-pop"><strong>pop</strong></a>(self)</dt><dd><tt>Return&nbsp;the&nbsp;popped&nbsp;value.&nbsp;&nbsp;Raise&nbsp;KeyError&nbsp;if&nbsp;empty.</tt></dd></dl>
-
-<dl><dt><a name="PathSet-remove"><strong>remove</strong></a>(self, value)</dt><dd><tt>Remove&nbsp;an&nbsp;element.&nbsp;If&nbsp;not&nbsp;a&nbsp;member,&nbsp;raise&nbsp;a&nbsp;KeyError.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="_abcoll.html#Set">_abcoll.Set</a>:<br>
-<dl><dt><a name="PathSet-__and__"><strong>__and__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__ge__"><strong>__ge__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__gt__"><strong>__gt__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__le__"><strong>__le__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__lt__"><strong>__lt__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__or__"><strong>__or__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__sub__"><strong>__sub__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-__xor__"><strong>__xor__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PathSet-isdisjoint"><strong>isdisjoint</strong></a>(self, other)</dt><dd><tt>Return&nbsp;True&nbsp;if&nbsp;two&nbsp;sets&nbsp;have&nbsp;a&nbsp;null&nbsp;intersection.</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Set">_abcoll.Set</a>:<br>
-<dl><dt><strong>__hash__</strong> = None</dl>
-
-<hr>
-Class methods inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><a name="PathSet-__subclasshook__"><strong>__subclasshook__</strong></a>(cls, C)<font color="#909090"><font face="helvetica, arial"> from <a href="abc.html#ABCMeta">abc.ABCMeta</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="_abcoll.html#Sized">_abcoll.Sized</a>:<br>
-<dl><dt><strong>__metaclass__</strong> = &lt;class 'abc.ABCMeta'&gt;<dd><tt>Metaclass&nbsp;for&nbsp;defining&nbsp;Abstract&nbsp;Base&nbsp;Classes&nbsp;(ABCs).<br>
-&nbsp;<br>
-Use&nbsp;this&nbsp;metaclass&nbsp;to&nbsp;create&nbsp;an&nbsp;ABC.&nbsp;&nbsp;An&nbsp;ABC&nbsp;can&nbsp;be&nbsp;subclassed<br>
-directly,&nbsp;and&nbsp;then&nbsp;acts&nbsp;as&nbsp;a&nbsp;mix-in&nbsp;class.&nbsp;&nbsp;You&nbsp;can&nbsp;also&nbsp;register<br>
-unrelated&nbsp;concrete&nbsp;classes&nbsp;(even&nbsp;built-in&nbsp;classes)&nbsp;and&nbsp;unrelated<br>
-ABCs&nbsp;as&nbsp;'virtual&nbsp;subclasses'&nbsp;--&nbsp;these&nbsp;and&nbsp;their&nbsp;descendants&nbsp;will<br>
-be&nbsp;considered&nbsp;subclasses&nbsp;of&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;by&nbsp;the&nbsp;built-in<br>
-issubclass()&nbsp;function,&nbsp;but&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;won't&nbsp;show&nbsp;up&nbsp;in<br>
-their&nbsp;MRO&nbsp;(Method&nbsp;Resolution&nbsp;Order)&nbsp;nor&nbsp;will&nbsp;method<br>
-implementations&nbsp;defined&nbsp;by&nbsp;the&nbsp;registering&nbsp;ABC&nbsp;be&nbsp;callable&nbsp;(not<br>
-even&nbsp;via&nbsp;super()).</tt></dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.ps_util.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.ps_util.html
deleted file mode 100644
index 753536a..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.ps_util.html
+++ /dev/null
@@ -1,51 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.ps_util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.ps_util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/ps_util.py">telemetry/internal/util/ps_util.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="atexit.html">atexit</a><br>
-</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-EnableListingStrayProcessesUponExitHook"><strong>EnableListingStrayProcessesUponExitHook</strong></a>()</dt></dl>
- <dl><dt><a name="-GetChildPids"><strong>GetChildPids</strong></a>(processes, pid)</dt><dd><tt>Returns&nbsp;all&nbsp;child&nbsp;processes&nbsp;of&nbsp;|pid|&nbsp;from&nbsp;the&nbsp;given&nbsp;|processes|&nbsp;list.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;processes:&nbsp;A&nbsp;tuple&nbsp;of&nbsp;(pid,&nbsp;ppid,&nbsp;state)&nbsp;as&nbsp;generated&nbsp;by&nbsp;ps.<br>
-&nbsp;&nbsp;pid:&nbsp;The&nbsp;pid&nbsp;for&nbsp;which&nbsp;to&nbsp;get&nbsp;children.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;child&nbsp;pids.</tt></dd></dl>
- <dl><dt><a name="-GetPsOutputWithPlatformBackend"><strong>GetPsOutputWithPlatformBackend</strong></a>(platform_backend, columns, pid)</dt><dd><tt>Returns&nbsp;output&nbsp;of&nbsp;the&nbsp;'ps'&nbsp;command&nbsp;as&nbsp;a&nbsp;list&nbsp;of&nbsp;lines.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;platform_backend:&nbsp;The&nbsp;platform&nbsp;backend&nbsp;(LinuxBasedPlatformBackend&nbsp;or<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PosixPlatformBackend).<br>
-&nbsp;&nbsp;columns:&nbsp;A&nbsp;list&nbsp;of&nbsp;require&nbsp;columns,&nbsp;e.g.,&nbsp;['pid',&nbsp;'pss'].<br>
-&nbsp;&nbsp;pid:&nbsp;If&nbsp;not&nbsp;None,&nbsp;returns&nbsp;only&nbsp;the&nbsp;information&nbsp;of&nbsp;the&nbsp;process&nbsp;with&nbsp;the&nbsp;pid.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.internal.util.webpagereplay.html b/catapult/telemetry/docs/pydoc/telemetry.internal.util.webpagereplay.html
deleted file mode 100644
index 0eec669..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.internal.util.webpagereplay.html
+++ /dev/null
@@ -1,294 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.internal.util.webpagereplay</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.internal.html"><font color="#ffffff">internal</font></a>.<a href="telemetry.internal.util.html"><font color="#ffffff">util</font></a>.webpagereplay</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/internal/util/webpagereplay.py">telemetry/internal/util/webpagereplay.py</a></font></td></tr></table>
-    <p><tt>Start&nbsp;and&nbsp;stop&nbsp;Web&nbsp;Page&nbsp;Replay.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="atexit.html">atexit</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="re.html">re</a><br>
-<a href="signal.html">signal</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-<a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-</td><td width="25%" valign=top><a href="urllib.html">urllib</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.webpagereplay.html#ReplayServer">ReplayServer</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.webpagereplay.html#ReplayNotFoundError">ReplayNotFoundError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.internal.util.webpagereplay.html#ReplayNotStartedError">ReplayNotStartedError</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ReplayError">class <strong>ReplayError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Catch-all&nbsp;exception&nbsp;for&nbsp;the&nbsp;module.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ReplayError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ReplayError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ReplayError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ReplayNotFoundError">class <strong>ReplayNotFoundError</strong></a>(<a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.webpagereplay.html#ReplayNotFoundError">ReplayNotFoundError</a></dd>
-<dd><a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ReplayNotFoundError-__init__"><strong>__init__</strong></a>(self, label, path)</dt></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ReplayNotFoundError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ReplayNotFoundError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotFoundError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotFoundError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotFoundError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotFoundError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotFoundError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotFoundError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayNotFoundError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ReplayNotStartedError">class <strong>ReplayNotStartedError</strong></a>(<a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.internal.util.webpagereplay.html#ReplayNotStartedError">ReplayNotStartedError</a></dd>
-<dd><a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.webpagereplay.html#ReplayError">ReplayError</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ReplayNotStartedError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ReplayNotStartedError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ReplayNotStartedError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ReplayNotStartedError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ReplayNotStartedError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ReplayServer">class <strong>ReplayServer</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Start&nbsp;and&nbsp;Stop&nbsp;Web&nbsp;Page&nbsp;Replay.<br>
-&nbsp;<br>
-Web&nbsp;Page&nbsp;Replay&nbsp;is&nbsp;a&nbsp;proxy&nbsp;that&nbsp;can&nbsp;record&nbsp;and&nbsp;"replay"&nbsp;web&nbsp;pages&nbsp;with<br>
-simulated&nbsp;network&nbsp;characteristics&nbsp;--&nbsp;without&nbsp;having&nbsp;to&nbsp;edit&nbsp;the&nbsp;pages<br>
-by&nbsp;hand.&nbsp;With&nbsp;WPR,&nbsp;tests&nbsp;can&nbsp;use&nbsp;"real"&nbsp;web&nbsp;content,&nbsp;and&nbsp;catch<br>
-performance&nbsp;issues&nbsp;that&nbsp;may&nbsp;result&nbsp;from&nbsp;introducing&nbsp;network&nbsp;delays&nbsp;and<br>
-bandwidth&nbsp;throttling.<br>
-&nbsp;<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#ReplayServer">ReplayServer</a>(archive_path):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NavigateToURL(start_url)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;WaitUntil(...)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ReplayServer-StartServer"><strong>StartServer</strong></a>(self)</dt><dd><tt>Start&nbsp;Web&nbsp;Page&nbsp;Replay&nbsp;and&nbsp;verify&nbsp;that&nbsp;it&nbsp;started.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;(HTTP_PORT,&nbsp;HTTPS_PORT,&nbsp;DNS_PORT)&nbsp;&nbsp;#&nbsp;DNS_PORT&nbsp;is&nbsp;None&nbsp;if&nbsp;unused.<br>
-Raises:<br>
-&nbsp;&nbsp;<a href="#ReplayNotStartedError">ReplayNotStartedError</a>:&nbsp;if&nbsp;Replay&nbsp;start-up&nbsp;fails.</tt></dd></dl>
-
-<dl><dt><a name="ReplayServer-StopServer"><strong>StopServer</strong></a>(self)</dt><dd><tt>Stop&nbsp;Web&nbsp;Page&nbsp;Replay.</tt></dd></dl>
-
-<dl><dt><a name="ReplayServer-__enter__"><strong>__enter__</strong></a>(self)</dt><dd><tt>Add&nbsp;support&nbsp;for&nbsp;with-statement.</tt></dd></dl>
-
-<dl><dt><a name="ReplayServer-__exit__"><strong>__exit__</strong></a>(self, unused_exc_type, unused_exc_val, unused_exc_tb)</dt><dd><tt>Add&nbsp;support&nbsp;for&nbsp;with-statement.</tt></dd></dl>
-
-<dl><dt><a name="ReplayServer-__init__"><strong>__init__</strong></a>(self, archive_path, replay_host, http_port, https_port, dns_port, replay_options)</dt><dd><tt>Initialize&nbsp;<a href="#ReplayServer">ReplayServer</a>.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;archive_path:&nbsp;a&nbsp;path&nbsp;to&nbsp;a&nbsp;specific&nbsp;WPR&nbsp;archive&nbsp;(required).<br>
-&nbsp;&nbsp;replay_host:&nbsp;the&nbsp;hostname&nbsp;to&nbsp;serve&nbsp;traffic.<br>
-&nbsp;&nbsp;http_port:&nbsp;an&nbsp;integer&nbsp;port&nbsp;on&nbsp;which&nbsp;to&nbsp;serve&nbsp;HTTP&nbsp;traffic.&nbsp;May&nbsp;be&nbsp;zero<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;let&nbsp;the&nbsp;OS&nbsp;choose&nbsp;an&nbsp;available&nbsp;port.<br>
-&nbsp;&nbsp;https_port:&nbsp;an&nbsp;integer&nbsp;port&nbsp;on&nbsp;which&nbsp;to&nbsp;serve&nbsp;HTTPS&nbsp;traffic.&nbsp;May&nbsp;be&nbsp;zero<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;let&nbsp;the&nbsp;OS&nbsp;choose&nbsp;an&nbsp;available&nbsp;port.<br>
-&nbsp;&nbsp;dns_port:&nbsp;an&nbsp;integer&nbsp;port&nbsp;on&nbsp;which&nbsp;to&nbsp;serve&nbsp;DNS&nbsp;traffic.&nbsp;May&nbsp;be&nbsp;zero<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;let&nbsp;the&nbsp;OS&nbsp;choose&nbsp;an&nbsp;available&nbsp;port.&nbsp;If&nbsp;None&nbsp;DNS&nbsp;forwarding&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;disabled.<br>
-&nbsp;&nbsp;replay_options:&nbsp;an&nbsp;iterable&nbsp;of&nbsp;options&nbsp;strings&nbsp;to&nbsp;forward&nbsp;to&nbsp;replay.py.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.page.action_runner.html b/catapult/telemetry/docs/pydoc/telemetry.page.action_runner.html
deleted file mode 100644
index 5ea1353..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.page.action_runner.html
+++ /dev/null
@@ -1,536 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.page.action_runner</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.page.html"><font color="#ffffff">page</font></a>.action_runner</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/page/action_runner.py">telemetry/page/action_runner.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="time.html">time</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.timeline_interaction_record.html">telemetry.web_perf.timeline_interaction_record</a><br>
-</td><td width="25%" valign=top><a href="urlparse.html">urlparse</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.action_runner.html#ActionRunner">ActionRunner</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.page.action_runner.html#Interaction">Interaction</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ActionRunner">class <strong>ActionRunner</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ActionRunner-ClickElement"><strong>ClickElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>)</dt><dd><tt>Click&nbsp;an&nbsp;element.<br>
-&nbsp;<br>
-The&nbsp;element&nbsp;may&nbsp;be&nbsp;selected&nbsp;via&nbsp;selector,&nbsp;text,&nbsp;or&nbsp;element_function.<br>
-Only&nbsp;one&nbsp;of&nbsp;these&nbsp;arguments&nbsp;must&nbsp;be&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;})()'.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-CreateGestureInteraction"><strong>CreateGestureInteraction</strong></a>(self, label, repeatable<font color="#909090">=False</font>)</dt><dd><tt>Create&nbsp;an&nbsp;action.<a href="#Interaction">Interaction</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;that&nbsp;issues&nbsp;gesture-based<br>
-interaction&nbsp;record.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;similar&nbsp;to&nbsp;normal&nbsp;interaction&nbsp;record,&nbsp;but&nbsp;it&nbsp;will<br>
-auto-narrow&nbsp;the&nbsp;interaction&nbsp;time&nbsp;period&nbsp;to&nbsp;only&nbsp;include&nbsp;the<br>
-synthetic&nbsp;gesture&nbsp;event&nbsp;output&nbsp;by&nbsp;Chrome.&nbsp;This&nbsp;is&nbsp;typically&nbsp;use&nbsp;to<br>
-reduce&nbsp;noise&nbsp;in&nbsp;gesture-based&nbsp;analysis&nbsp;(e.g.,&nbsp;analysis&nbsp;for&nbsp;a<br>
-swipe/scroll).<br>
-&nbsp;<br>
-The&nbsp;interaction&nbsp;record&nbsp;label&nbsp;will&nbsp;be&nbsp;prepended&nbsp;with&nbsp;'Gesture_'.<br>
-&nbsp;<br>
-e.g:<br>
-&nbsp;&nbsp;with&nbsp;action_runner.<a href="#ActionRunner-CreateGestureInteraction">CreateGestureInteraction</a>('Scroll-1'):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.<a href="#ActionRunner-ScrollPage">ScrollPage</a>()<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;label:&nbsp;A&nbsp;label&nbsp;for&nbsp;this&nbsp;particular&nbsp;interaction.&nbsp;This&nbsp;can&nbsp;be&nbsp;any<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user-defined&nbsp;string,&nbsp;but&nbsp;must&nbsp;not&nbsp;contain&nbsp;'/'.<br>
-&nbsp;&nbsp;repeatable:&nbsp;Whether&nbsp;other&nbsp;interactions&nbsp;may&nbsp;use&nbsp;the&nbsp;same&nbsp;logical&nbsp;name<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;this&nbsp;interaction.&nbsp;All&nbsp;interactions&nbsp;with&nbsp;the&nbsp;same&nbsp;logical&nbsp;name&nbsp;must<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;have&nbsp;the&nbsp;same&nbsp;flags.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;An&nbsp;instance&nbsp;of&nbsp;action_runner.<a href="#Interaction">Interaction</a></tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-CreateInteraction"><strong>CreateInteraction</strong></a>(self, label, repeatable<font color="#909090">=False</font>)</dt><dd><tt>Create&nbsp;an&nbsp;action.<a href="#Interaction">Interaction</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;that&nbsp;issues&nbsp;interaction&nbsp;record.<br>
-&nbsp;<br>
-An&nbsp;interaction&nbsp;record&nbsp;is&nbsp;a&nbsp;labeled&nbsp;time&nbsp;period&nbsp;containing<br>
-interaction&nbsp;that&nbsp;developers&nbsp;care&nbsp;about.&nbsp;Each&nbsp;set&nbsp;of&nbsp;metrics<br>
-specified&nbsp;in&nbsp;flags&nbsp;will&nbsp;be&nbsp;calculated&nbsp;for&nbsp;this&nbsp;time&nbsp;period.<br>
-&nbsp;<br>
-To&nbsp;mark&nbsp;the&nbsp;start&nbsp;of&nbsp;interaction&nbsp;record,&nbsp;call&nbsp;Begin()&nbsp;method&nbsp;on&nbsp;the&nbsp;returned<br>
-<a href="__builtin__.html#object">object</a>.&nbsp;To&nbsp;mark&nbsp;the&nbsp;finish&nbsp;of&nbsp;interaction&nbsp;record,&nbsp;call&nbsp;End()&nbsp;method&nbsp;on<br>
-it.&nbsp;Or&nbsp;better&nbsp;yet,&nbsp;use&nbsp;the&nbsp;with&nbsp;statement&nbsp;to&nbsp;create&nbsp;an<br>
-interaction&nbsp;record&nbsp;that&nbsp;covers&nbsp;the&nbsp;actions&nbsp;in&nbsp;the&nbsp;with&nbsp;block.<br>
-&nbsp;<br>
-e.g:<br>
-&nbsp;&nbsp;with&nbsp;action_runner.<a href="#ActionRunner-CreateInteraction">CreateInteraction</a>('Animation-1'):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.<a href="#ActionRunner-TapElement">TapElement</a>(...)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.<a href="#ActionRunner-WaitForJavaScriptCondition">WaitForJavaScriptCondition</a>(...)<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;label:&nbsp;A&nbsp;label&nbsp;for&nbsp;this&nbsp;particular&nbsp;interaction.&nbsp;This&nbsp;can&nbsp;be&nbsp;any<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user-defined&nbsp;string,&nbsp;but&nbsp;must&nbsp;not&nbsp;contain&nbsp;'/'.<br>
-&nbsp;&nbsp;repeatable:&nbsp;Whether&nbsp;other&nbsp;interactions&nbsp;may&nbsp;use&nbsp;the&nbsp;same&nbsp;logical&nbsp;name<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;as&nbsp;this&nbsp;interaction.&nbsp;All&nbsp;interactions&nbsp;with&nbsp;the&nbsp;same&nbsp;logical&nbsp;name&nbsp;must<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;have&nbsp;the&nbsp;same&nbsp;flags.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;An&nbsp;instance&nbsp;of&nbsp;action_runner.<a href="#Interaction">Interaction</a></tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-DragPage"><strong>DragPage</strong></a>(self, left_start_ratio, top_start_ratio, left_end_ratio, top_end_ratio, speed_in_pixels_per_second<font color="#909090">=800</font>, use_touch<font color="#909090">=False</font>, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>)</dt><dd><tt>Perform&nbsp;a&nbsp;drag&nbsp;gesture&nbsp;on&nbsp;the&nbsp;page.<br>
-&nbsp;<br>
-You&nbsp;should&nbsp;specify&nbsp;a&nbsp;start&nbsp;and&nbsp;an&nbsp;end&nbsp;point&nbsp;in&nbsp;ratios&nbsp;of&nbsp;page&nbsp;width&nbsp;and<br>
-height&nbsp;(see&nbsp;drag.js&nbsp;for&nbsp;full&nbsp;implementation).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;left_end_ratio:&nbsp;The&nbsp;horizontal&nbsp;ending&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_end_ratio:&nbsp;The&nbsp;vertical&nbsp;ending&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).<br>
-&nbsp;&nbsp;use_touch:&nbsp;Whether&nbsp;dragging&nbsp;should&nbsp;be&nbsp;done&nbsp;with&nbsp;touch&nbsp;input.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-EvaluateJavaScript"><strong>EvaluateJavaScript</strong></a>(self, expression)</dt><dd><tt>Returns&nbsp;the&nbsp;evaluation&nbsp;result&nbsp;of&nbsp;the&nbsp;given&nbsp;JavaScript&nbsp;expression.<br>
-&nbsp;<br>
-The&nbsp;evaluation&nbsp;results&nbsp;must&nbsp;be&nbsp;convertible&nbsp;to&nbsp;JSON.&nbsp;If&nbsp;the&nbsp;result<br>
-is&nbsp;not&nbsp;needed,&nbsp;use&nbsp;ExecuteJavaScript&nbsp;instead.<br>
-&nbsp;<br>
-Example:&nbsp;num&nbsp;=&nbsp;runner.<a href="#ActionRunner-EvaluateJavaScript">EvaluateJavaScript</a>('document.location.href')<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;expression:&nbsp;The&nbsp;expression&nbsp;to&nbsp;evaluate&nbsp;(provided&nbsp;as&nbsp;string).<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;EvaluationException:&nbsp;The&nbsp;statement&nbsp;expression&nbsp;failed&nbsp;to&nbsp;execute<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;or&nbsp;the&nbsp;evaluation&nbsp;result&nbsp;can&nbsp;not&nbsp;be&nbsp;JSON-ized.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ExecuteJavaScript"><strong>ExecuteJavaScript</strong></a>(self, statement)</dt><dd><tt>Executes&nbsp;a&nbsp;given&nbsp;JavaScript&nbsp;expression.&nbsp;Does&nbsp;not&nbsp;return&nbsp;the&nbsp;result.<br>
-&nbsp;<br>
-Example:&nbsp;runner.<a href="#ActionRunner-ExecuteJavaScript">ExecuteJavaScript</a>('var&nbsp;foo&nbsp;=&nbsp;1;');<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;statement:&nbsp;The&nbsp;statement&nbsp;to&nbsp;execute&nbsp;(provided&nbsp;as&nbsp;string).<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;EvaluationException:&nbsp;The&nbsp;statement&nbsp;failed&nbsp;to&nbsp;execute.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ForceGarbageCollection"><strong>ForceGarbageCollection</strong></a>(self)</dt><dd><tt>Forces&nbsp;JavaScript&nbsp;garbage&nbsp;collection&nbsp;on&nbsp;the&nbsp;page.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-LoadMedia"><strong>LoadMedia</strong></a>(self, selector<font color="#909090">=None</font>, event_timeout_in_seconds<font color="#909090">=0</font>, event_to_await<font color="#909090">='canplaythrough'</font>)</dt><dd><tt>Invokes&nbsp;load()&nbsp;on&nbsp;media&nbsp;elements&nbsp;and&nbsp;awaits&nbsp;an&nbsp;event.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.&nbsp;If&nbsp;none&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;specified,&nbsp;play&nbsp;the&nbsp;first&nbsp;media&nbsp;element&nbsp;on&nbsp;the&nbsp;page.&nbsp;If&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selector&nbsp;matches&nbsp;more&nbsp;than&nbsp;1&nbsp;media&nbsp;element,&nbsp;all&nbsp;of&nbsp;them&nbsp;will<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;played.<br>
-&nbsp;&nbsp;event_timeout_in_seconds:&nbsp;Maximum&nbsp;waiting&nbsp;time&nbsp;for&nbsp;the&nbsp;event&nbsp;to&nbsp;be&nbsp;fired.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.<br>
-&nbsp;&nbsp;event_to_await:&nbsp;Which&nbsp;event&nbsp;to&nbsp;await.&nbsp;For&nbsp;example:&nbsp;'canplaythrough'&nbsp;or<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'loadedmetadata'.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;TimeoutException:&nbsp;If&nbsp;the&nbsp;maximum&nbsp;waiting&nbsp;time&nbsp;is&nbsp;exceeded.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-LoopMedia"><strong>LoopMedia</strong></a>(self, loop_count, selector<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=None</font>)</dt><dd><tt>Loops&nbsp;a&nbsp;media&nbsp;playback.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;loop_count:&nbsp;The&nbsp;number&nbsp;of&nbsp;times&nbsp;to&nbsp;loop&nbsp;the&nbsp;playback.<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.&nbsp;If&nbsp;none&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;specified,&nbsp;loop&nbsp;the&nbsp;first&nbsp;media&nbsp;element&nbsp;on&nbsp;the&nbsp;page.&nbsp;If&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selector&nbsp;matches&nbsp;more&nbsp;than&nbsp;1&nbsp;media&nbsp;element,&nbsp;all&nbsp;of&nbsp;them&nbsp;will<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;looped.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Maximum&nbsp;waiting&nbsp;time&nbsp;for&nbsp;the&nbsp;looped&nbsp;playback&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;complete.&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.&nbsp;None&nbsp;(the&nbsp;default)&nbsp;means&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;wait&nbsp;loop_count&nbsp;*&nbsp;60&nbsp;seconds.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;TimeoutException:&nbsp;If&nbsp;the&nbsp;maximum&nbsp;waiting&nbsp;time&nbsp;is&nbsp;exceeded.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-MouseClick"><strong>MouseClick</strong></a>(self, selector<font color="#909090">=None</font>)</dt><dd><tt>Mouse&nbsp;click&nbsp;the&nbsp;given&nbsp;element.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-Navigate"><strong>Navigate</strong></a>(self, url, script_to_evaluate_on_commit<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=60</font>)</dt><dd><tt>Navigates&nbsp;to&nbsp;url.<br>
-&nbsp;<br>
-If&nbsp;|script_to_evaluate_on_commit|&nbsp;is&nbsp;given,&nbsp;the&nbsp;script&nbsp;source&nbsp;string&nbsp;will&nbsp;be<br>
-evaluated&nbsp;when&nbsp;the&nbsp;navigation&nbsp;is&nbsp;committed.&nbsp;This&nbsp;is&nbsp;after&nbsp;the&nbsp;context&nbsp;of<br>
-the&nbsp;page&nbsp;exists,&nbsp;but&nbsp;before&nbsp;any&nbsp;script&nbsp;on&nbsp;the&nbsp;page&nbsp;itself&nbsp;has&nbsp;executed.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-PauseInteractive"><strong>PauseInteractive</strong></a>(self)</dt><dd><tt>Pause&nbsp;the&nbsp;page&nbsp;execution&nbsp;and&nbsp;wait&nbsp;for&nbsp;terminal&nbsp;interaction.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;typically&nbsp;used&nbsp;for&nbsp;debugging.&nbsp;You&nbsp;can&nbsp;use&nbsp;this&nbsp;to&nbsp;pause<br>
-the&nbsp;page&nbsp;execution&nbsp;and&nbsp;inspect&nbsp;the&nbsp;browser&nbsp;state&nbsp;before<br>
-continuing.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-PinchElement"><strong>PinchElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_anchor_ratio<font color="#909090">=0.5</font>, top_anchor_ratio<font color="#909090">=0.5</font>, scale_factor<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>)</dt><dd><tt>Perform&nbsp;the&nbsp;pinch&nbsp;gesture&nbsp;on&nbsp;an&nbsp;element.<br>
-&nbsp;<br>
-It&nbsp;computes&nbsp;the&nbsp;pinch&nbsp;gesture&nbsp;automatically&nbsp;based&nbsp;on&nbsp;the&nbsp;anchor<br>
-coordinate&nbsp;and&nbsp;the&nbsp;scale&nbsp;factor.&nbsp;The&nbsp;scale&nbsp;factor&nbsp;is&nbsp;the&nbsp;ratio&nbsp;of<br>
-of&nbsp;the&nbsp;final&nbsp;span&nbsp;and&nbsp;the&nbsp;initial&nbsp;span&nbsp;of&nbsp;the&nbsp;gesture.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;}'.<br>
-&nbsp;&nbsp;left_anchor_ratio:&nbsp;The&nbsp;horizontal&nbsp;pinch&nbsp;anchor&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;top_anchor_ratio:&nbsp;The&nbsp;vertical&nbsp;pinch&nbsp;anchor&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;scale_factor:&nbsp;The&nbsp;ratio&nbsp;of&nbsp;the&nbsp;final&nbsp;span&nbsp;to&nbsp;the&nbsp;initial&nbsp;span.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;default&nbsp;scale&nbsp;factor&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.0&nbsp;/&nbsp;(window.outerWidth/window.innerWidth).<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-PinchPage"><strong>PinchPage</strong></a>(self, left_anchor_ratio<font color="#909090">=0.5</font>, top_anchor_ratio<font color="#909090">=0.5</font>, scale_factor<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>)</dt><dd><tt>Perform&nbsp;the&nbsp;pinch&nbsp;gesture&nbsp;on&nbsp;the&nbsp;page.<br>
-&nbsp;<br>
-It&nbsp;computes&nbsp;the&nbsp;pinch&nbsp;gesture&nbsp;automatically&nbsp;based&nbsp;on&nbsp;the&nbsp;anchor<br>
-coordinate&nbsp;and&nbsp;the&nbsp;scale&nbsp;factor.&nbsp;The&nbsp;scale&nbsp;factor&nbsp;is&nbsp;the&nbsp;ratio&nbsp;of<br>
-of&nbsp;the&nbsp;final&nbsp;span&nbsp;and&nbsp;the&nbsp;initial&nbsp;span&nbsp;of&nbsp;the&nbsp;gesture.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;left_anchor_ratio:&nbsp;The&nbsp;horizontal&nbsp;pinch&nbsp;anchor&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_anchor_ratio:&nbsp;The&nbsp;vertical&nbsp;pinch&nbsp;anchor&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;scale_factor:&nbsp;The&nbsp;ratio&nbsp;of&nbsp;the&nbsp;final&nbsp;span&nbsp;to&nbsp;the&nbsp;initial&nbsp;span.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;default&nbsp;scale&nbsp;factor&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3.0&nbsp;/&nbsp;(window.outerWidth/window.innerWidth).<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-PlayMedia"><strong>PlayMedia</strong></a>(self, selector<font color="#909090">=None</font>, playing_event_timeout_in_seconds<font color="#909090">=0</font>, ended_event_timeout_in_seconds<font color="#909090">=0</font>)</dt><dd><tt>Invokes&nbsp;the&nbsp;"play"&nbsp;action&nbsp;on&nbsp;media&nbsp;elements&nbsp;(such&nbsp;as&nbsp;video).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.&nbsp;If&nbsp;none&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;specified,&nbsp;play&nbsp;the&nbsp;first&nbsp;media&nbsp;element&nbsp;on&nbsp;the&nbsp;page.&nbsp;If&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selector&nbsp;matches&nbsp;more&nbsp;than&nbsp;1&nbsp;media&nbsp;element,&nbsp;all&nbsp;of&nbsp;them&nbsp;will<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;played.<br>
-&nbsp;&nbsp;playing_event_timeout_in_seconds:&nbsp;Maximum&nbsp;waiting&nbsp;time&nbsp;for&nbsp;the&nbsp;"playing"<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event&nbsp;(dispatched&nbsp;when&nbsp;the&nbsp;media&nbsp;begins&nbsp;to&nbsp;play)&nbsp;to&nbsp;be&nbsp;fired.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.<br>
-&nbsp;&nbsp;ended_event_timeout_in_seconds:&nbsp;Maximum&nbsp;waiting&nbsp;time&nbsp;for&nbsp;the&nbsp;"ended"<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;event&nbsp;(dispatched&nbsp;when&nbsp;playback&nbsp;completes)&nbsp;to&nbsp;be&nbsp;fired.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;TimeoutException:&nbsp;If&nbsp;the&nbsp;maximum&nbsp;waiting&nbsp;time&nbsp;is&nbsp;exceeded.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ReloadPage"><strong>ReloadPage</strong></a>(self)</dt><dd><tt>Reloads&nbsp;the&nbsp;page.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-RepaintContinuously"><strong>RepaintContinuously</strong></a>(self, seconds)</dt><dd><tt>Continuously&nbsp;repaints&nbsp;the&nbsp;visible&nbsp;content.<br>
-&nbsp;<br>
-It&nbsp;does&nbsp;this&nbsp;by&nbsp;requesting&nbsp;animation&nbsp;frames&nbsp;until&nbsp;the&nbsp;given&nbsp;number<br>
-of&nbsp;seconds&nbsp;have&nbsp;elapsed&nbsp;AND&nbsp;at&nbsp;least&nbsp;three&nbsp;RAFs&nbsp;have&nbsp;been<br>
-fired.&nbsp;Times&nbsp;out&nbsp;after&nbsp;max(60,&nbsp;self.<strong>seconds</strong>),&nbsp;if&nbsp;less&nbsp;than&nbsp;three<br>
-RAFs&nbsp;were&nbsp;fired.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-RepeatableBrowserDrivenScroll"><strong>RepeatableBrowserDrivenScroll</strong></a>(self, x_scroll_distance_ratio<font color="#909090">=0.0</font>, y_scroll_distance_ratio<font color="#909090">=0.5</font>, repeat_count<font color="#909090">=0</font>, repeat_delay_ms<font color="#909090">=250</font>)</dt><dd><tt>Perform&nbsp;a&nbsp;browser&nbsp;driven&nbsp;repeatable&nbsp;scroll&nbsp;gesture.<br>
-&nbsp;<br>
-The&nbsp;scroll&nbsp;gesture&nbsp;is&nbsp;driven&nbsp;from&nbsp;the&nbsp;browser,&nbsp;this&nbsp;is&nbsp;useful&nbsp;because&nbsp;the<br>
-main&nbsp;thread&nbsp;often&nbsp;isn't&nbsp;resposive&nbsp;but&nbsp;the&nbsp;browser&nbsp;process&nbsp;usually&nbsp;is,&nbsp;so&nbsp;the<br>
-delay&nbsp;between&nbsp;the&nbsp;scroll&nbsp;gestures&nbsp;should&nbsp;be&nbsp;consistent.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;x_scroll_distance_ratio:&nbsp;The&nbsp;horizontal&nbsp;lenght&nbsp;of&nbsp;the&nbsp;scroll&nbsp;as&nbsp;a&nbsp;fraction<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;the&nbsp;screen&nbsp;width.<br>
-&nbsp;&nbsp;y_scroll_distance_ratio:&nbsp;The&nbsp;vertical&nbsp;lenght&nbsp;of&nbsp;the&nbsp;scroll&nbsp;as&nbsp;a&nbsp;fraction<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;of&nbsp;the&nbsp;screen&nbsp;height.<br>
-&nbsp;&nbsp;repeat_count:&nbsp;The&nbsp;number&nbsp;of&nbsp;additional&nbsp;times&nbsp;to&nbsp;repeat&nbsp;the&nbsp;gesture.<br>
-&nbsp;&nbsp;repeat_delay_ms:&nbsp;The&nbsp;delay&nbsp;in&nbsp;milliseconds&nbsp;between&nbsp;each&nbsp;scroll&nbsp;gesture.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ScrollBounceElement"><strong>ScrollBounceElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='down'</font>, distance<font color="#909090">=100</font>, overscroll<font color="#909090">=10</font>, repeat_count<font color="#909090">=10</font>, speed_in_pixels_per_second<font color="#909090">=400</font>)</dt><dd><tt>Perform&nbsp;scroll&nbsp;bounce&nbsp;gesture&nbsp;on&nbsp;the&nbsp;element.<br>
-&nbsp;<br>
-This&nbsp;gesture&nbsp;scrolls&nbsp;on&nbsp;the&nbsp;element&nbsp;by&nbsp;the&nbsp;number&nbsp;of&nbsp;pixels&nbsp;specified&nbsp;in<br>
-distance,&nbsp;in&nbsp;the&nbsp;given&nbsp;direction,&nbsp;followed&nbsp;by&nbsp;a&nbsp;scroll&nbsp;by<br>
-(distance&nbsp;+&nbsp;overscroll)&nbsp;pixels&nbsp;in&nbsp;the&nbsp;opposite&nbsp;direction.<br>
-The&nbsp;above&nbsp;gesture&nbsp;is&nbsp;repeated&nbsp;repeat_count&nbsp;times.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;}'.<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;direction:&nbsp;The&nbsp;direction&nbsp;of&nbsp;scroll,&nbsp;either&nbsp;'left',&nbsp;'right',<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'up',&nbsp;'down',&nbsp;'upleft',&nbsp;'upright',&nbsp;'downleft',&nbsp;or&nbsp;'downright'<br>
-&nbsp;&nbsp;distance:&nbsp;The&nbsp;distance&nbsp;to&nbsp;scroll&nbsp;(in&nbsp;pixel).<br>
-&nbsp;&nbsp;overscroll:&nbsp;The&nbsp;number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back,&nbsp;in<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addition&nbsp;to&nbsp;the&nbsp;givendistance.<br>
-&nbsp;&nbsp;repeat_count:&nbsp;How&nbsp;often&nbsp;we&nbsp;want&nbsp;to&nbsp;repeat&nbsp;the&nbsp;full&nbsp;gesture.<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ScrollBouncePage"><strong>ScrollBouncePage</strong></a>(self, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='down'</font>, distance<font color="#909090">=100</font>, overscroll<font color="#909090">=10</font>, repeat_count<font color="#909090">=10</font>, speed_in_pixels_per_second<font color="#909090">=400</font>)</dt><dd><tt>Perform&nbsp;scroll&nbsp;bounce&nbsp;gesture&nbsp;on&nbsp;the&nbsp;page.<br>
-&nbsp;<br>
-This&nbsp;gesture&nbsp;scrolls&nbsp;the&nbsp;page&nbsp;by&nbsp;the&nbsp;number&nbsp;of&nbsp;pixels&nbsp;specified&nbsp;in<br>
-distance,&nbsp;in&nbsp;the&nbsp;given&nbsp;direction,&nbsp;followed&nbsp;by&nbsp;a&nbsp;scroll&nbsp;by<br>
-(distance&nbsp;+&nbsp;overscroll)&nbsp;pixels&nbsp;in&nbsp;the&nbsp;opposite&nbsp;direction.<br>
-The&nbsp;above&nbsp;gesture&nbsp;is&nbsp;repeated&nbsp;repeat_count&nbsp;times.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;direction:&nbsp;The&nbsp;direction&nbsp;of&nbsp;scroll,&nbsp;either&nbsp;'left',&nbsp;'right',<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'up',&nbsp;'down',&nbsp;'upleft',&nbsp;'upright',&nbsp;'downleft',&nbsp;or&nbsp;'downright'<br>
-&nbsp;&nbsp;distance:&nbsp;The&nbsp;distance&nbsp;to&nbsp;scroll&nbsp;(in&nbsp;pixel).<br>
-&nbsp;&nbsp;overscroll:&nbsp;The&nbsp;number&nbsp;of&nbsp;additional&nbsp;pixels&nbsp;to&nbsp;scroll&nbsp;back,&nbsp;in<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;addition&nbsp;to&nbsp;the&nbsp;givendistance.<br>
-&nbsp;&nbsp;repeat_count:&nbsp;How&nbsp;often&nbsp;we&nbsp;want&nbsp;to&nbsp;repeat&nbsp;the&nbsp;full&nbsp;gesture.<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ScrollElement"><strong>ScrollElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='down'</font>, distance<font color="#909090">=None</font>, distance_expr<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>, use_touch<font color="#909090">=False</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt><dd><tt>Perform&nbsp;scroll&nbsp;gesture&nbsp;on&nbsp;the&nbsp;element.<br>
-&nbsp;<br>
-The&nbsp;element&nbsp;may&nbsp;be&nbsp;selected&nbsp;via&nbsp;selector,&nbsp;text,&nbsp;or&nbsp;element_function.<br>
-Only&nbsp;one&nbsp;of&nbsp;these&nbsp;arguments&nbsp;must&nbsp;be&nbsp;specified.<br>
-&nbsp;<br>
-You&nbsp;may&nbsp;specify&nbsp;distance&nbsp;or&nbsp;distance_expr,&nbsp;but&nbsp;not&nbsp;both.&nbsp;If<br>
-neither&nbsp;is&nbsp;specified,&nbsp;the&nbsp;default&nbsp;scroll&nbsp;distance&nbsp;is&nbsp;variable<br>
-depending&nbsp;on&nbsp;direction&nbsp;(see&nbsp;scroll.js&nbsp;for&nbsp;full&nbsp;implementation).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;}'.<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;direction:&nbsp;The&nbsp;direction&nbsp;of&nbsp;scroll,&nbsp;either&nbsp;'left',&nbsp;'right',<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'up',&nbsp;'down',&nbsp;'upleft',&nbsp;'upright',&nbsp;'downleft',&nbsp;or&nbsp;'downright'<br>
-&nbsp;&nbsp;distance:&nbsp;The&nbsp;distance&nbsp;to&nbsp;scroll&nbsp;(in&nbsp;pixel).<br>
-&nbsp;&nbsp;distance_expr:&nbsp;A&nbsp;JavaScript&nbsp;expression&nbsp;(as&nbsp;string)&nbsp;that&nbsp;can&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evaluated&nbsp;to&nbsp;compute&nbsp;scroll&nbsp;distance.&nbsp;Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'window.scrollTop'&nbsp;or&nbsp;'(function()&nbsp;{&nbsp;return&nbsp;crazyMath();&nbsp;})()'.<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).<br>
-&nbsp;&nbsp;use_touch:&nbsp;Whether&nbsp;scrolling&nbsp;should&nbsp;be&nbsp;done&nbsp;with&nbsp;touch&nbsp;input.<br>
-&nbsp;&nbsp;synthetic_gesture_source:&nbsp;the&nbsp;source&nbsp;input&nbsp;device&nbsp;type&nbsp;for&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synthetic&nbsp;gesture:&nbsp;'DEFAULT',&nbsp;'TOUCH'&nbsp;or&nbsp;'MOUSE'.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-ScrollPage"><strong>ScrollPage</strong></a>(self, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='down'</font>, distance<font color="#909090">=None</font>, distance_expr<font color="#909090">=None</font>, speed_in_pixels_per_second<font color="#909090">=800</font>, use_touch<font color="#909090">=False</font>, synthetic_gesture_source<font color="#909090">='DEFAULT'</font>)</dt><dd><tt>Perform&nbsp;scroll&nbsp;gesture&nbsp;on&nbsp;the&nbsp;page.<br>
-&nbsp;<br>
-You&nbsp;may&nbsp;specify&nbsp;distance&nbsp;or&nbsp;distance_expr,&nbsp;but&nbsp;not&nbsp;both.&nbsp;If<br>
-neither&nbsp;is&nbsp;specified,&nbsp;the&nbsp;default&nbsp;scroll&nbsp;distance&nbsp;is&nbsp;variable<br>
-depending&nbsp;on&nbsp;direction&nbsp;(see&nbsp;scroll.js&nbsp;for&nbsp;full&nbsp;implementation).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;direction:&nbsp;The&nbsp;direction&nbsp;of&nbsp;scroll,&nbsp;either&nbsp;'left',&nbsp;'right',<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'up',&nbsp;'down',&nbsp;'upleft',&nbsp;'upright',&nbsp;'downleft',&nbsp;or&nbsp;'downright'<br>
-&nbsp;&nbsp;distance:&nbsp;The&nbsp;distance&nbsp;to&nbsp;scroll&nbsp;(in&nbsp;pixel).<br>
-&nbsp;&nbsp;distance_expr:&nbsp;A&nbsp;JavaScript&nbsp;expression&nbsp;(as&nbsp;string)&nbsp;that&nbsp;can&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;evaluated&nbsp;to&nbsp;compute&nbsp;scroll&nbsp;distance.&nbsp;Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'window.scrollTop'&nbsp;or&nbsp;'(function()&nbsp;{&nbsp;return&nbsp;crazyMath();&nbsp;})()'.<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).<br>
-&nbsp;&nbsp;use_touch:&nbsp;Whether&nbsp;scrolling&nbsp;should&nbsp;be&nbsp;done&nbsp;with&nbsp;touch&nbsp;input.<br>
-&nbsp;&nbsp;synthetic_gesture_source:&nbsp;the&nbsp;source&nbsp;input&nbsp;device&nbsp;type&nbsp;for&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;synthetic&nbsp;gesture:&nbsp;'DEFAULT',&nbsp;'TOUCH'&nbsp;or&nbsp;'MOUSE'.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-SeekMedia"><strong>SeekMedia</strong></a>(self, seconds, selector<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=0</font>, log_time<font color="#909090">=True</font>, label<font color="#909090">=''</font>)</dt><dd><tt>Performs&nbsp;a&nbsp;seek&nbsp;action&nbsp;on&nbsp;media&nbsp;elements&nbsp;(such&nbsp;as&nbsp;video).<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;seconds:&nbsp;The&nbsp;media&nbsp;time&nbsp;to&nbsp;seek&nbsp;to.<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.&nbsp;If&nbsp;none&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;specified,&nbsp;seek&nbsp;the&nbsp;first&nbsp;media&nbsp;element&nbsp;on&nbsp;the&nbsp;page.&nbsp;If&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;selector&nbsp;matches&nbsp;more&nbsp;than&nbsp;1&nbsp;media&nbsp;element,&nbsp;all&nbsp;of&nbsp;them&nbsp;will<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;seeked.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;Maximum&nbsp;waiting&nbsp;time&nbsp;for&nbsp;the&nbsp;"seeked"&nbsp;event<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(dispatched&nbsp;when&nbsp;the&nbsp;seeked&nbsp;operation&nbsp;completes)&nbsp;to&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fired.&nbsp;&nbsp;0&nbsp;means&nbsp;do&nbsp;not&nbsp;wait.<br>
-&nbsp;&nbsp;log_time:&nbsp;Whether&nbsp;to&nbsp;log&nbsp;the&nbsp;seek&nbsp;time&nbsp;for&nbsp;the&nbsp;perf<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;measurement.&nbsp;Useful&nbsp;when&nbsp;performing&nbsp;multiple&nbsp;seek.<br>
-&nbsp;&nbsp;label:&nbsp;A&nbsp;suffix&nbsp;string&nbsp;to&nbsp;name&nbsp;the&nbsp;seek&nbsp;perf&nbsp;measurement.<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;TimeoutException:&nbsp;If&nbsp;the&nbsp;maximum&nbsp;waiting&nbsp;time&nbsp;is&nbsp;exceeded.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-SwipeElement"><strong>SwipeElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='left'</font>, distance<font color="#909090">=100</font>, speed_in_pixels_per_second<font color="#909090">=800</font>)</dt><dd><tt>Perform&nbsp;swipe&nbsp;gesture&nbsp;on&nbsp;the&nbsp;element.<br>
-&nbsp;<br>
-The&nbsp;element&nbsp;may&nbsp;be&nbsp;selected&nbsp;via&nbsp;selector,&nbsp;text,&nbsp;or&nbsp;element_function.<br>
-Only&nbsp;one&nbsp;of&nbsp;these&nbsp;arguments&nbsp;must&nbsp;be&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;}'.<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;direction:&nbsp;The&nbsp;direction&nbsp;of&nbsp;swipe,&nbsp;either&nbsp;'left',&nbsp;'right',<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'up',&nbsp;or&nbsp;'down'<br>
-&nbsp;&nbsp;distance:&nbsp;The&nbsp;distance&nbsp;to&nbsp;swipe&nbsp;(in&nbsp;pixel).<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-SwipePage"><strong>SwipePage</strong></a>(self, left_start_ratio<font color="#909090">=0.5</font>, top_start_ratio<font color="#909090">=0.5</font>, direction<font color="#909090">='left'</font>, distance<font color="#909090">=100</font>, speed_in_pixels_per_second<font color="#909090">=800</font>)</dt><dd><tt>Perform&nbsp;swipe&nbsp;gesture&nbsp;on&nbsp;the&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;left_start_ratio:&nbsp;The&nbsp;horizontal&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;top_start_ratio:&nbsp;The&nbsp;vertical&nbsp;starting&nbsp;coordinate&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;gesture,&nbsp;as&nbsp;a&nbsp;ratio&nbsp;of&nbsp;the&nbsp;visible&nbsp;bounding&nbsp;rectangle&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;document.body.<br>
-&nbsp;&nbsp;direction:&nbsp;The&nbsp;direction&nbsp;of&nbsp;swipe,&nbsp;either&nbsp;'left',&nbsp;'right',<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'up',&nbsp;or&nbsp;'down'<br>
-&nbsp;&nbsp;distance:&nbsp;The&nbsp;distance&nbsp;to&nbsp;swipe&nbsp;(in&nbsp;pixel).<br>
-&nbsp;&nbsp;speed_in_pixels_per_second:&nbsp;The&nbsp;speed&nbsp;of&nbsp;the&nbsp;gesture&nbsp;(in&nbsp;pixels/s).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-TapElement"><strong>TapElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>)</dt><dd><tt>Tap&nbsp;an&nbsp;element.<br>
-&nbsp;<br>
-The&nbsp;element&nbsp;may&nbsp;be&nbsp;selected&nbsp;via&nbsp;selector,&nbsp;text,&nbsp;or&nbsp;element_function.<br>
-Only&nbsp;one&nbsp;of&nbsp;these&nbsp;arguments&nbsp;must&nbsp;be&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;})()'.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-Wait"><strong>Wait</strong></a>(self, seconds)</dt><dd><tt>Wait&nbsp;for&nbsp;the&nbsp;number&nbsp;of&nbsp;seconds&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;seconds:&nbsp;The&nbsp;number&nbsp;of&nbsp;seconds&nbsp;to&nbsp;wait.</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-WaitForElement"><strong>WaitForElement</strong></a>(self, selector<font color="#909090">=None</font>, text<font color="#909090">=None</font>, element_function<font color="#909090">=None</font>, timeout_in_seconds<font color="#909090">=60</font>)</dt><dd><tt>Wait&nbsp;for&nbsp;an&nbsp;element&nbsp;to&nbsp;appear&nbsp;in&nbsp;the&nbsp;document.<br>
-&nbsp;<br>
-The&nbsp;element&nbsp;may&nbsp;be&nbsp;selected&nbsp;via&nbsp;selector,&nbsp;text,&nbsp;or&nbsp;element_function.<br>
-Only&nbsp;one&nbsp;of&nbsp;these&nbsp;arguments&nbsp;must&nbsp;be&nbsp;specified.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;selector:&nbsp;A&nbsp;CSS&nbsp;selector&nbsp;describing&nbsp;the&nbsp;element.<br>
-&nbsp;&nbsp;text:&nbsp;The&nbsp;element&nbsp;must&nbsp;contains&nbsp;this&nbsp;exact&nbsp;text.<br>
-&nbsp;&nbsp;element_function:&nbsp;A&nbsp;JavaScript&nbsp;function&nbsp;(as&nbsp;string)&nbsp;that&nbsp;is&nbsp;used<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;retrieve&nbsp;the&nbsp;element.&nbsp;For&nbsp;example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'(function()&nbsp;{&nbsp;return&nbsp;foo.element;&nbsp;})()'.<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;The&nbsp;timeout&nbsp;in&nbsp;seconds&nbsp;(default&nbsp;to&nbsp;60).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-WaitForJavaScriptCondition"><strong>WaitForJavaScriptCondition</strong></a>(self, condition, timeout_in_seconds<font color="#909090">=60</font>)</dt><dd><tt>Wait&nbsp;for&nbsp;a&nbsp;JavaScript&nbsp;condition&nbsp;to&nbsp;become&nbsp;true.<br>
-&nbsp;<br>
-Example:&nbsp;runner.<a href="#ActionRunner-WaitForJavaScriptCondition">WaitForJavaScriptCondition</a>('window.foo&nbsp;==&nbsp;10');<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;condition:&nbsp;The&nbsp;JavaScript&nbsp;condition&nbsp;(as&nbsp;string).<br>
-&nbsp;&nbsp;timeout_in_seconds:&nbsp;The&nbsp;timeout&nbsp;in&nbsp;seconds&nbsp;(default&nbsp;to&nbsp;60).</tt></dd></dl>
-
-<dl><dt><a name="ActionRunner-WaitForNavigate"><strong>WaitForNavigate</strong></a>(self, timeout_in_seconds_seconds<font color="#909090">=60</font>)</dt></dl>
-
-<dl><dt><a name="ActionRunner-__init__"><strong>__init__</strong></a>(self, tab, skip_waits<font color="#909090">=False</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>tab</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;tab&nbsp;on&nbsp;which&nbsp;actions&nbsp;are&nbsp;performed.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Interaction">class <strong>Interaction</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Interaction-Begin"><strong>Begin</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Interaction-End"><strong>End</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Interaction-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Interaction-__exit__"><strong>__exit__</strong></a>(self, exc_type, exc_value, traceback)</dt></dl>
-
-<dl><dt><a name="Interaction-__init__"><strong>__init__</strong></a>(self, action_runner, label, flags)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>GESTURE_SOURCE_DEFAULT</strong> = 'DEFAULT'<br>
-<strong>SUPPORTED_GESTURE_SOURCES</strong> = ('DEFAULT', 'MOUSE', 'TOUCH')</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.page.html b/catapult/telemetry/docs/pydoc/telemetry.page.html
deleted file mode 100644
index e403666..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.page.html
+++ /dev/null
@@ -1,142 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.page</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.page</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/page/__init__.py">telemetry/page/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.page.action_runner.html">action_runner</a><br>
-<a href="telemetry.page.page.html">page</a><br>
-</td><td width="25%" valign=top><a href="telemetry.page.page_run_end_to_end_unittest.html">page_run_end_to_end_unittest</a><br>
-<a href="telemetry.page.page_test.html">page_test</a><br>
-</td><td width="25%" valign=top><a href="telemetry.page.page_test_unittest.html">page_test_unittest</a><br>
-<a href="telemetry.page.page_unittest.html">page_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.page.shared_page_state.html">shared_page_state</a><br>
-<a href="telemetry.page.shared_page_state_unittest.html">shared_page_state_unittest</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.html#Page">Page</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Page">class <strong>Page</strong></a>(<a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.html#Page">Page</a></dd>
-<dd><a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Page-AddCustomizeBrowserOptions"><strong>AddCustomizeBrowserOptions</strong></a>(self, options)</dt><dd><tt>Inherit&nbsp;page&nbsp;overrides&nbsp;this&nbsp;to&nbsp;add&nbsp;customized&nbsp;browser&nbsp;options.</tt></dd></dl>
-
-<dl><dt><a name="Page-AsDict"><strong>AsDict</strong></a>(self)</dt><dd><tt>Converts&nbsp;a&nbsp;page&nbsp;object&nbsp;to&nbsp;a&nbsp;dict&nbsp;suitable&nbsp;for&nbsp;JSON&nbsp;output.</tt></dd></dl>
-
-<dl><dt><a name="Page-GetSyntheticDelayCategories"><strong>GetSyntheticDelayCategories</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Page-Run"><strong>Run</strong></a>(self, shared_state)</dt></dl>
-
-<dl><dt><a name="Page-RunNavigateSteps"><strong>RunNavigateSteps</strong></a>(self, action_runner)</dt></dl>
-
-<dl><dt><a name="Page-RunPageInteractions"><strong>RunPageInteractions</strong></a>(self, action_runner)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;define&nbsp;custom&nbsp;interactions&nbsp;with&nbsp;the&nbsp;page.<br>
-e.g:<br>
-&nbsp;&nbsp;def&nbsp;<a href="#Page-RunPageInteractions">RunPageInteractions</a>(self,&nbsp;action_runner):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.ScrollPage()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;action_runner.TapElement(text='Next')</tt></dd></dl>
-
-<dl><dt><a name="Page-__cmp__"><strong>__cmp__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="Page-__init__"><strong>__init__</strong></a>(self, url, page_set<font color="#909090">=None</font>, base_dir<font color="#909090">=None</font>, name<font color="#909090">=''</font>, credentials_path<font color="#909090">=None</font>, credentials_bucket<font color="#909090">='chromium-telemetry'</font>, labels<font color="#909090">=None</font>, startup_url<font color="#909090">=''</font>, make_javascript_deterministic<font color="#909090">=True</font>, shared_page_state_class<font color="#909090">=&lt;class 'telemetry.page.shared_page_state.SharedPageState'&gt;</font>)</dt></dl>
-
-<dl><dt><a name="Page-__lt__"><strong>__lt__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="Page-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>base_dir</strong></dt>
-</dl>
-<dl><dt><strong>credentials_path</strong></dt>
-</dl>
-<dl><dt><strong>display_name</strong></dt>
-</dl>
-<dl><dt><strong>file_path</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;path&nbsp;of&nbsp;the&nbsp;file,&nbsp;stripping&nbsp;the&nbsp;scheme&nbsp;and&nbsp;query&nbsp;string.</tt></dd>
-</dl>
-<dl><dt><strong>file_path_url</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;file&nbsp;path,&nbsp;including&nbsp;the&nbsp;params,&nbsp;query,&nbsp;and&nbsp;fragment.</tt></dd>
-</dl>
-<dl><dt><strong>file_path_url_with_scheme</strong></dt>
-</dl>
-<dl><dt><strong>is_file</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;URL&nbsp;points&nbsp;to&nbsp;a&nbsp;file.</tt></dd>
-</dl>
-<dl><dt><strong>page_set</strong></dt>
-</dl>
-<dl><dt><strong>serving_dir</strong></dt>
-</dl>
-<dl><dt><strong>startup_url</strong></dt>
-</dl>
-<dl><dt><strong>story_set</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>file_safe_name</strong></dt>
-<dd><tt>A&nbsp;version&nbsp;of&nbsp;display_name&nbsp;that's&nbsp;safe&nbsp;to&nbsp;use&nbsp;as&nbsp;a&nbsp;filename.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;sanitizes&nbsp;special&nbsp;characters&nbsp;with&nbsp;underscores,<br>
-but&nbsp;it's&nbsp;okay&nbsp;to&nbsp;override&nbsp;it&nbsp;with&nbsp;a&nbsp;more&nbsp;specific&nbsp;implementation&nbsp;in<br>
-subclasses.</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-<dl><dt><strong>is_local</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;story&nbsp;does&nbsp;not&nbsp;require&nbsp;network.</tt></dd>
-</dl>
-<dl><dt><strong>labels</strong></dt>
-</dl>
-<dl><dt><strong>make_javascript_deterministic</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>shared_state_class</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.page.page.html b/catapult/telemetry/docs/pydoc/telemetry.page.page.html
deleted file mode 100644
index 8ef184a..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.page.page.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.page.page</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.page.html"><font color="#ffffff">page</font></a>.page</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/page/page.py">telemetry/page/page.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.page.html">telemetry.page</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.page.page_test.html b/catapult/telemetry/docs/pydoc/telemetry.page.page_test.html
deleted file mode 100644
index b335e1c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.page.page_test.html
+++ /dev/null
@@ -1,350 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.page.page_test</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.page.html"><font color="#ffffff">page</font></a>.page_test</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/page/page_test.py">telemetry/page/page_test.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.page.action_runner.html">telemetry.page.action_runner</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.page_test.html#PageTest">PageTest</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.page_test.html#MultiTabTestAppCrashError">MultiTabTestAppCrashError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.page.page_test.html#TestNotSupportedOnPlatformError">TestNotSupportedOnPlatformError</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.story_test.html#Failure">telemetry.web_perf.story_test.Failure</a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.page_test.html#MeasurementFailure">MeasurementFailure</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MeasurementFailure">class <strong>MeasurementFailure</strong></a>(<a href="telemetry.web_perf.story_test.html#Failure">telemetry.web_perf.story_test.Failure</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#PageTest">PageTest</a>&nbsp;<a href="exceptions.html#Exception">Exception</a>&nbsp;raised&nbsp;when&nbsp;an&nbsp;undesired&nbsp;but&nbsp;designed-for&nbsp;problem.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.page_test.html#MeasurementFailure">MeasurementFailure</a></dd>
-<dd><a href="telemetry.web_perf.story_test.html#Failure">telemetry.web_perf.story_test.Failure</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.story_test.html#Failure">telemetry.web_perf.story_test.Failure</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MeasurementFailure-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MeasurementFailure-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MeasurementFailure-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MeasurementFailure-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MeasurementFailure-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MeasurementFailure-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MeasurementFailure-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MultiTabTestAppCrashError">class <strong>MultiTabTestAppCrashError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#PageTest">PageTest</a>&nbsp;<a href="exceptions.html#Exception">Exception</a>&nbsp;raised&nbsp;after&nbsp;browser&nbsp;or&nbsp;tab&nbsp;crash&nbsp;for&nbsp;multi-tab&nbsp;tests.<br>
-&nbsp;<br>
-Used&nbsp;to&nbsp;abort&nbsp;the&nbsp;test&nbsp;rather&nbsp;than&nbsp;try&nbsp;to&nbsp;recover&nbsp;from&nbsp;an&nbsp;unknown&nbsp;state.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.page_test.html#MultiTabTestAppCrashError">MultiTabTestAppCrashError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MultiTabTestAppCrashError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MultiTabTestAppCrashError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MultiTabTestAppCrashError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MultiTabTestAppCrashError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MultiTabTestAppCrashError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PageTest">class <strong>PageTest</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;class&nbsp;styled&nbsp;on&nbsp;unittest.TestCase&nbsp;for&nbsp;creating&nbsp;page-specific&nbsp;tests.<br>
-&nbsp;<br>
-Test&nbsp;should&nbsp;override&nbsp;ValidateAndMeasurePage&nbsp;to&nbsp;perform&nbsp;test<br>
-validation&nbsp;and&nbsp;page&nbsp;measurement&nbsp;as&nbsp;necessary.<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;class&nbsp;BodyChildElementMeasurement(<a href="#PageTest">PageTest</a>):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def&nbsp;<a href="#PageTest-ValidateAndMeasurePage">ValidateAndMeasurePage</a>(self,&nbsp;page,&nbsp;tab,&nbsp;results):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;body_child_count&nbsp;=&nbsp;tab.EvaluateJavaScript(<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'document.body.children.length')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;results.AddValue(scalar.ScalarValue(<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;page,&nbsp;'body_children',&nbsp;'count',&nbsp;body_child_count))<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PageTest-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(self, options)</dt><dd><tt>Override&nbsp;to&nbsp;add&nbsp;test-specific&nbsp;options&nbsp;to&nbsp;the&nbsp;BrowserOptions&nbsp;<a href="__builtin__.html#object">object</a></tt></dd></dl>
-
-<dl><dt><a name="PageTest-DidNavigateToPage"><strong>DidNavigateToPage</strong></a>(self, page, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;operations&nbsp;right&nbsp;after&nbsp;the&nbsp;page&nbsp;is&nbsp;navigated&nbsp;and&nbsp;after<br>
-all&nbsp;waiting&nbsp;for&nbsp;completion&nbsp;has&nbsp;occurred.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-DidRunPage"><strong>DidRunPage</strong></a>(self, platform)</dt><dd><tt>Called&nbsp;after&nbsp;the&nbsp;test&nbsp;run&nbsp;method&nbsp;was&nbsp;run,&nbsp;even&nbsp;if&nbsp;it&nbsp;failed.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser)</dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;browser&nbsp;right&nbsp;after&nbsp;it&nbsp;has&nbsp;launched.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-RestartBrowserBeforeEachPage"><strong>RestartBrowserBeforeEachPage</strong></a>(self)</dt><dd><tt>Should&nbsp;the&nbsp;browser&nbsp;be&nbsp;restarted&nbsp;for&nbsp;the&nbsp;page?<br>
-&nbsp;<br>
-This&nbsp;returns&nbsp;true&nbsp;if&nbsp;the&nbsp;test&nbsp;needs&nbsp;to&nbsp;unconditionally&nbsp;restart&nbsp;the<br>
-browser&nbsp;for&nbsp;each&nbsp;page.&nbsp;It&nbsp;may&nbsp;be&nbsp;called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;started.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-RunNavigateSteps"><strong>RunNavigateSteps</strong></a>(self, page, tab)</dt><dd><tt>Navigates&nbsp;the&nbsp;tab&nbsp;to&nbsp;the&nbsp;page&nbsp;URL&nbsp;attribute.<br>
-&nbsp;<br>
-Runs&nbsp;the&nbsp;'navigate_steps'&nbsp;page&nbsp;attribute&nbsp;as&nbsp;a&nbsp;compound&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-SetOptions"><strong>SetOptions</strong></a>(self, options)</dt><dd><tt>Sets&nbsp;the&nbsp;BrowserFinderOptions&nbsp;instance&nbsp;to&nbsp;use.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-StopBrowserAfterPage"><strong>StopBrowserAfterPage</strong></a>(self, browser, page)</dt><dd><tt>Should&nbsp;the&nbsp;browser&nbsp;be&nbsp;stopped&nbsp;after&nbsp;the&nbsp;page&nbsp;is&nbsp;run?<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;called&nbsp;after&nbsp;a&nbsp;page&nbsp;is&nbsp;run&nbsp;to&nbsp;decide&nbsp;whether&nbsp;the&nbsp;browser&nbsp;needs&nbsp;to<br>
-be&nbsp;stopped&nbsp;to&nbsp;clean&nbsp;up&nbsp;its&nbsp;state.&nbsp;If&nbsp;it&nbsp;is&nbsp;stopped,&nbsp;then&nbsp;it&nbsp;will&nbsp;be<br>
-restarted&nbsp;to&nbsp;run&nbsp;the&nbsp;next&nbsp;page.<br>
-&nbsp;<br>
-A&nbsp;test&nbsp;that&nbsp;overrides&nbsp;this&nbsp;can&nbsp;look&nbsp;at&nbsp;both&nbsp;the&nbsp;page&nbsp;and&nbsp;the&nbsp;browser&nbsp;to<br>
-decide&nbsp;whether&nbsp;it&nbsp;needs&nbsp;to&nbsp;stop&nbsp;the&nbsp;browser.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-TabForPage"><strong>TabForPage</strong></a>(self, page, browser)</dt><dd><tt>Override&nbsp;to&nbsp;select&nbsp;a&nbsp;different&nbsp;tab&nbsp;for&nbsp;the&nbsp;page.&nbsp;&nbsp;For&nbsp;instance,&nbsp;to<br>
-create&nbsp;a&nbsp;new&nbsp;tab&nbsp;for&nbsp;every&nbsp;page,&nbsp;return&nbsp;browser.tabs.New().</tt></dd></dl>
-
-<dl><dt><a name="PageTest-ValidateAndMeasurePage"><strong>ValidateAndMeasurePage</strong></a>(self, page, tab, results)</dt><dd><tt>Override&nbsp;to&nbsp;check&nbsp;test&nbsp;assertions&nbsp;and&nbsp;perform&nbsp;measurement.<br>
-&nbsp;<br>
-When&nbsp;adding&nbsp;measurement&nbsp;results,&nbsp;call&nbsp;results.AddValue(...)&nbsp;for<br>
-each&nbsp;result.&nbsp;Raise&nbsp;an&nbsp;exception&nbsp;or&nbsp;add&nbsp;a&nbsp;failure.FailureValue&nbsp;on<br>
-failure.&nbsp;page_test.py&nbsp;also&nbsp;provides&nbsp;several&nbsp;base&nbsp;exception&nbsp;classes<br>
-to&nbsp;use.<br>
-&nbsp;<br>
-Prefer&nbsp;metric&nbsp;value&nbsp;names&nbsp;that&nbsp;are&nbsp;in&nbsp;accordance&nbsp;with&nbsp;python<br>
-variable&nbsp;style.&nbsp;e.g.,&nbsp;metric_name.&nbsp;The&nbsp;name&nbsp;'url'&nbsp;must&nbsp;not&nbsp;be&nbsp;used.<br>
-&nbsp;<br>
-Put&nbsp;together:<br>
-&nbsp;&nbsp;def&nbsp;<a href="#PageTest-ValidateAndMeasurePage">ValidateAndMeasurePage</a>(self,&nbsp;page,&nbsp;tab,&nbsp;results):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;res&nbsp;=&nbsp;tab.EvaluateJavaScript('2+2')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;res&nbsp;!=&nbsp;4:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;raise&nbsp;<a href="exceptions.html#Exception">Exception</a>('Oh,&nbsp;wow.')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;results.AddValue(scalar.ScalarValue(<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;page,&nbsp;'two_plus_two',&nbsp;'count',&nbsp;res))<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page:&nbsp;A&nbsp;telemetry.page.Page&nbsp;instance.<br>
-&nbsp;&nbsp;tab:&nbsp;A&nbsp;telemetry.core.Tab&nbsp;instance.<br>
-&nbsp;&nbsp;results:&nbsp;A&nbsp;telemetry.results.PageTestResults&nbsp;instance.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-WillNavigateToPage"><strong>WillNavigateToPage</strong></a>(self, page, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;operations&nbsp;before&nbsp;the&nbsp;page&nbsp;is&nbsp;navigated,&nbsp;notably&nbsp;Telemetry<br>
-will&nbsp;already&nbsp;have&nbsp;performed&nbsp;the&nbsp;following&nbsp;operations&nbsp;on&nbsp;the&nbsp;browser&nbsp;before<br>
-calling&nbsp;this&nbsp;function:<br>
-*&nbsp;Ensure&nbsp;only&nbsp;one&nbsp;tab&nbsp;is&nbsp;open.<br>
-*&nbsp;Call&nbsp;WaitForDocumentReadyStateToComplete&nbsp;on&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-WillStartBrowser"><strong>WillStartBrowser</strong></a>(self, platform)</dt><dd><tt>Override&nbsp;to&nbsp;manipulate&nbsp;the&nbsp;browser&nbsp;environment&nbsp;before&nbsp;it&nbsp;launches.</tt></dd></dl>
-
-<dl><dt><a name="PageTest-__init__"><strong>__init__</strong></a>(self, needs_browser_restart_after_each_page<font color="#909090">=False</font>, clear_cache_before_each_run<font color="#909090">=False</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>clear_cache_before_each_run</strong></dt>
-<dd><tt>When&nbsp;set&nbsp;to&nbsp;True,&nbsp;the&nbsp;browser's&nbsp;disk&nbsp;and&nbsp;memory&nbsp;cache&nbsp;will&nbsp;be&nbsp;cleared<br>
-before&nbsp;each&nbsp;run.</tt></dd>
-</dl>
-<dl><dt><strong>close_tabs_before_run</strong></dt>
-<dd><tt>When&nbsp;set&nbsp;to&nbsp;True,&nbsp;all&nbsp;tabs&nbsp;are&nbsp;closed&nbsp;before&nbsp;running&nbsp;the&nbsp;test&nbsp;for&nbsp;the<br>
-first&nbsp;time.</tt></dd>
-</dl>
-<dl><dt><strong>is_multi_tab_test</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;test&nbsp;opens&nbsp;multiple&nbsp;tabs.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;test&nbsp;overrides&nbsp;TabForPage,&nbsp;it&nbsp;is&nbsp;deemed&nbsp;a&nbsp;multi-tab&nbsp;test.<br>
-Multi-tab&nbsp;tests&nbsp;do&nbsp;not&nbsp;retry&nbsp;after&nbsp;tab&nbsp;or&nbsp;browser&nbsp;crashes,&nbsp;whereas,<br>
-single-tab&nbsp;tests&nbsp;too.&nbsp;That&nbsp;is&nbsp;because&nbsp;the&nbsp;state&nbsp;of&nbsp;multi-tab&nbsp;tests<br>
-(e.g.,&nbsp;how&nbsp;many&nbsp;tabs&nbsp;are&nbsp;open,&nbsp;etc.)&nbsp;is&nbsp;unknown&nbsp;after&nbsp;crashes.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TestNotSupportedOnPlatformError">class <strong>TestNotSupportedOnPlatformError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#PageTest">PageTest</a>&nbsp;<a href="exceptions.html#Exception">Exception</a>&nbsp;raised&nbsp;when&nbsp;a&nbsp;required&nbsp;feature&nbsp;is&nbsp;unavailable.<br>
-&nbsp;<br>
-The&nbsp;feature&nbsp;required&nbsp;to&nbsp;run&nbsp;the&nbsp;test&nbsp;could&nbsp;be&nbsp;part&nbsp;of&nbsp;the&nbsp;platform,<br>
-hardware&nbsp;configuration,&nbsp;or&nbsp;browser.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.page_test.html#TestNotSupportedOnPlatformError">TestNotSupportedOnPlatformError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TestNotSupportedOnPlatformError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TestNotSupportedOnPlatformError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TestNotSupportedOnPlatformError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TestNotSupportedOnPlatformError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TestNotSupportedOnPlatformError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.page.shared_page_state.html b/catapult/telemetry/docs/pydoc/telemetry.page.shared_page_state.html
deleted file mode 100644
index 326d143..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.page.shared_page_state.html
+++ /dev/null
@@ -1,385 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.page.shared_page_state</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.page.html"><font color="#ffffff">page</font></a>.shared_page_state</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/page/shared_page_state.py">telemetry/page/shared_page_state.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="telemetry.internal.browser.browser_finder_exceptions.html">telemetry.internal.browser.browser_finder_exceptions</a><br>
-<a href="telemetry.internal.browser.browser_info.html">telemetry.internal.browser.browser_info</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.util.exception_formatter.html">telemetry.internal.util.exception_formatter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.internal.util.file_handle.html">telemetry.internal.util.file_handle</a><br>
-<a href="telemetry.util.image_util.html">telemetry.util.image_util</a><br>
-<a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-<a href="telemetry.page.page_test.html">telemetry.page.page_test</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.platform.profiler.profiler_finder.html">telemetry.internal.platform.profiler.profiler_finder</a><br>
-<a href="shutil.html">shutil</a><br>
-<a href="telemetry.story.html">telemetry.story</a><br>
-<a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-<a href="telemetry.web_perf.timeline_based_measurement.html">telemetry.web_perf.timeline_based_measurement</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-<a href="zipfile.html">zipfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.shared_page_state.html#Shared10InchTabletPageState">Shared10InchTabletPageState</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.page.shared_page_state.html#SharedDesktopPageState">SharedDesktopPageState</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.page.shared_page_state.html#SharedMobilePageState">SharedMobilePageState</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.page.shared_page_state.html#SharedTabletPageState">SharedTabletPageState</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Shared10InchTabletPageState">class <strong>Shared10InchTabletPageState</strong></a>(<a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.shared_page_state.html#Shared10InchTabletPageState">Shared10InchTabletPageState</a></dd>
-<dd><a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><a name="Shared10InchTabletPageState-CanRunOnBrowser"><strong>CanRunOnBrowser</strong></a>(self, browser_info, page)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;return&nbsp;whether&nbsp;the&nbsp;browser&nbsp;brought&nbsp;up&nbsp;by&nbsp;this&nbsp;state<br>
-instance&nbsp;is&nbsp;suitable&nbsp;for&nbsp;running&nbsp;the&nbsp;given&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_info:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.browser_info.BrowserInfo<br>
-&nbsp;&nbsp;page:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.page.Page</tt></dd></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-CanRunStory"><strong>CanRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-GetPregeneratedProfileArchiveDir"><strong>GetPregeneratedProfileArchiveDir</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-SetPregeneratedProfileArchiveDir"><strong>SetPregeneratedProfileArchiveDir</strong></a>(self, archive_path)</dt><dd><tt>Benchmarks&nbsp;can&nbsp;set&nbsp;a&nbsp;pre-generated&nbsp;profile&nbsp;archive&nbsp;to&nbsp;indicate&nbsp;that&nbsp;when<br>
-Chrome&nbsp;is&nbsp;launched,&nbsp;it&nbsp;should&nbsp;have&nbsp;a&nbsp;--user-data-dir&nbsp;set&nbsp;to&nbsp;the<br>
-pregenerated&nbsp;profile,&nbsp;rather&nbsp;than&nbsp;to&nbsp;an&nbsp;empty&nbsp;profile.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;invoked&nbsp;with&nbsp;the&nbsp;option&nbsp;--profile-dir=&lt;dir&gt;,&nbsp;that<br>
-option&nbsp;overrides&nbsp;this&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-TearDownState"><strong>TearDownState</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-WillRunStory"><strong>WillRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="Shared10InchTabletPageState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_tab</strong></dt>
-</dl>
-<dl><dt><strong>page_test</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SharedDesktopPageState">class <strong>SharedDesktopPageState</strong></a>(<a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.shared_page_state.html#SharedDesktopPageState">SharedDesktopPageState</a></dd>
-<dd><a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><a name="SharedDesktopPageState-CanRunOnBrowser"><strong>CanRunOnBrowser</strong></a>(self, browser_info, page)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;return&nbsp;whether&nbsp;the&nbsp;browser&nbsp;brought&nbsp;up&nbsp;by&nbsp;this&nbsp;state<br>
-instance&nbsp;is&nbsp;suitable&nbsp;for&nbsp;running&nbsp;the&nbsp;given&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_info:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.browser_info.BrowserInfo<br>
-&nbsp;&nbsp;page:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.page.Page</tt></dd></dl>
-
-<dl><dt><a name="SharedDesktopPageState-CanRunStory"><strong>CanRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedDesktopPageState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedDesktopPageState-GetPregeneratedProfileArchiveDir"><strong>GetPregeneratedProfileArchiveDir</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedDesktopPageState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedDesktopPageState-SetPregeneratedProfileArchiveDir"><strong>SetPregeneratedProfileArchiveDir</strong></a>(self, archive_path)</dt><dd><tt>Benchmarks&nbsp;can&nbsp;set&nbsp;a&nbsp;pre-generated&nbsp;profile&nbsp;archive&nbsp;to&nbsp;indicate&nbsp;that&nbsp;when<br>
-Chrome&nbsp;is&nbsp;launched,&nbsp;it&nbsp;should&nbsp;have&nbsp;a&nbsp;--user-data-dir&nbsp;set&nbsp;to&nbsp;the<br>
-pregenerated&nbsp;profile,&nbsp;rather&nbsp;than&nbsp;to&nbsp;an&nbsp;empty&nbsp;profile.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;invoked&nbsp;with&nbsp;the&nbsp;option&nbsp;--profile-dir=&lt;dir&gt;,&nbsp;that<br>
-option&nbsp;overrides&nbsp;this&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="SharedDesktopPageState-TearDownState"><strong>TearDownState</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedDesktopPageState-WillRunStory"><strong>WillRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedDesktopPageState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_tab</strong></dt>
-</dl>
-<dl><dt><strong>page_test</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SharedMobilePageState">class <strong>SharedMobilePageState</strong></a>(<a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.shared_page_state.html#SharedMobilePageState">SharedMobilePageState</a></dd>
-<dd><a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><a name="SharedMobilePageState-CanRunOnBrowser"><strong>CanRunOnBrowser</strong></a>(self, browser_info, page)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;return&nbsp;whether&nbsp;the&nbsp;browser&nbsp;brought&nbsp;up&nbsp;by&nbsp;this&nbsp;state<br>
-instance&nbsp;is&nbsp;suitable&nbsp;for&nbsp;running&nbsp;the&nbsp;given&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_info:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.browser_info.BrowserInfo<br>
-&nbsp;&nbsp;page:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.page.Page</tt></dd></dl>
-
-<dl><dt><a name="SharedMobilePageState-CanRunStory"><strong>CanRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedMobilePageState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedMobilePageState-GetPregeneratedProfileArchiveDir"><strong>GetPregeneratedProfileArchiveDir</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedMobilePageState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedMobilePageState-SetPregeneratedProfileArchiveDir"><strong>SetPregeneratedProfileArchiveDir</strong></a>(self, archive_path)</dt><dd><tt>Benchmarks&nbsp;can&nbsp;set&nbsp;a&nbsp;pre-generated&nbsp;profile&nbsp;archive&nbsp;to&nbsp;indicate&nbsp;that&nbsp;when<br>
-Chrome&nbsp;is&nbsp;launched,&nbsp;it&nbsp;should&nbsp;have&nbsp;a&nbsp;--user-data-dir&nbsp;set&nbsp;to&nbsp;the<br>
-pregenerated&nbsp;profile,&nbsp;rather&nbsp;than&nbsp;to&nbsp;an&nbsp;empty&nbsp;profile.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;invoked&nbsp;with&nbsp;the&nbsp;option&nbsp;--profile-dir=&lt;dir&gt;,&nbsp;that<br>
-option&nbsp;overrides&nbsp;this&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="SharedMobilePageState-TearDownState"><strong>TearDownState</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedMobilePageState-WillRunStory"><strong>WillRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedMobilePageState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_tab</strong></dt>
-</dl>
-<dl><dt><strong>page_test</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SharedPageState">class <strong>SharedPageState</strong></a>(<a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>This&nbsp;class&nbsp;contains&nbsp;all&nbsp;specific&nbsp;logic&nbsp;necessary&nbsp;to&nbsp;run&nbsp;a&nbsp;Chrome&nbsp;browser<br>
-benchmark.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SharedPageState-CanRunOnBrowser"><strong>CanRunOnBrowser</strong></a>(self, browser_info, page)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;return&nbsp;whether&nbsp;the&nbsp;browser&nbsp;brought&nbsp;up&nbsp;by&nbsp;this&nbsp;state<br>
-instance&nbsp;is&nbsp;suitable&nbsp;for&nbsp;running&nbsp;the&nbsp;given&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_info:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.browser_info.BrowserInfo<br>
-&nbsp;&nbsp;page:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.page.Page</tt></dd></dl>
-
-<dl><dt><a name="SharedPageState-CanRunStory"><strong>CanRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedPageState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedPageState-GetPregeneratedProfileArchiveDir"><strong>GetPregeneratedProfileArchiveDir</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedPageState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedPageState-SetPregeneratedProfileArchiveDir"><strong>SetPregeneratedProfileArchiveDir</strong></a>(self, archive_path)</dt><dd><tt>Benchmarks&nbsp;can&nbsp;set&nbsp;a&nbsp;pre-generated&nbsp;profile&nbsp;archive&nbsp;to&nbsp;indicate&nbsp;that&nbsp;when<br>
-Chrome&nbsp;is&nbsp;launched,&nbsp;it&nbsp;should&nbsp;have&nbsp;a&nbsp;--user-data-dir&nbsp;set&nbsp;to&nbsp;the<br>
-pregenerated&nbsp;profile,&nbsp;rather&nbsp;than&nbsp;to&nbsp;an&nbsp;empty&nbsp;profile.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;invoked&nbsp;with&nbsp;the&nbsp;option&nbsp;--profile-dir=&lt;dir&gt;,&nbsp;that<br>
-option&nbsp;overrides&nbsp;this&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="SharedPageState-TearDownState"><strong>TearDownState</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedPageState-WillRunStory"><strong>WillRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedPageState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_tab</strong></dt>
-</dl>
-<dl><dt><strong>page_test</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SharedTabletPageState">class <strong>SharedTabletPageState</strong></a>(<a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.page.shared_page_state.html#SharedTabletPageState">SharedTabletPageState</a></dd>
-<dd><a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><a name="SharedTabletPageState-CanRunOnBrowser"><strong>CanRunOnBrowser</strong></a>(self, browser_info, page)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;return&nbsp;whether&nbsp;the&nbsp;browser&nbsp;brought&nbsp;up&nbsp;by&nbsp;this&nbsp;state<br>
-instance&nbsp;is&nbsp;suitable&nbsp;for&nbsp;running&nbsp;the&nbsp;given&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_info:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.browser_info.BrowserInfo<br>
-&nbsp;&nbsp;page:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.page.Page</tt></dd></dl>
-
-<dl><dt><a name="SharedTabletPageState-CanRunStory"><strong>CanRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedTabletPageState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedTabletPageState-GetPregeneratedProfileArchiveDir"><strong>GetPregeneratedProfileArchiveDir</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedTabletPageState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="SharedTabletPageState-SetPregeneratedProfileArchiveDir"><strong>SetPregeneratedProfileArchiveDir</strong></a>(self, archive_path)</dt><dd><tt>Benchmarks&nbsp;can&nbsp;set&nbsp;a&nbsp;pre-generated&nbsp;profile&nbsp;archive&nbsp;to&nbsp;indicate&nbsp;that&nbsp;when<br>
-Chrome&nbsp;is&nbsp;launched,&nbsp;it&nbsp;should&nbsp;have&nbsp;a&nbsp;--user-data-dir&nbsp;set&nbsp;to&nbsp;the<br>
-pregenerated&nbsp;profile,&nbsp;rather&nbsp;than&nbsp;to&nbsp;an&nbsp;empty&nbsp;profile.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;invoked&nbsp;with&nbsp;the&nbsp;option&nbsp;--profile-dir=&lt;dir&gt;,&nbsp;that<br>
-option&nbsp;overrides&nbsp;this&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="SharedTabletPageState-TearDownState"><strong>TearDownState</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SharedTabletPageState-WillRunStory"><strong>WillRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="SharedTabletPageState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">SharedPageState</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_tab</strong></dt>
-</dl>
-<dl><dt><strong>page_test</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.project_config.html b/catapult/telemetry/docs/pydoc/telemetry.project_config.html
deleted file mode 100644
index 111ea3e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.project_config.html
+++ /dev/null
@@ -1,73 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.project_config</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.project_config</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/project_config.py">telemetry/project_config.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.project_config.html#ProjectConfig">ProjectConfig</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProjectConfig">class <strong>ProjectConfig</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Contains&nbsp;information&nbsp;about&nbsp;the&nbsp;benchmark&nbsp;runtime&nbsp;environment.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;top_level_dir:&nbsp;A&nbsp;dir&nbsp;that&nbsp;contains&nbsp;benchmark,&nbsp;page&nbsp;test,&nbsp;and/or&nbsp;story<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set&nbsp;dirs&nbsp;and&nbsp;associated&nbsp;artifacts.<br>
-&nbsp;&nbsp;benchmark_dirs:&nbsp;A&nbsp;list&nbsp;of&nbsp;dirs&nbsp;containing&nbsp;benchmarks.<br>
-&nbsp;&nbsp;benchmark_aliases:&nbsp;A&nbsp;dict&nbsp;of&nbsp;name:alias&nbsp;string&nbsp;pairs&nbsp;to&nbsp;be&nbsp;matched&nbsp;against<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exactly&nbsp;during&nbsp;benchmark&nbsp;selection.<br>
-&nbsp;&nbsp;client_config:&nbsp;A&nbsp;path&nbsp;to&nbsp;a&nbsp;ProjectDependencies&nbsp;json&nbsp;file.<br>
-&nbsp;&nbsp;default_chrome_root:&nbsp;A&nbsp;path&nbsp;to&nbsp;chromium&nbsp;source&nbsp;directory.&nbsp;Many&nbsp;telemetry<br>
-&nbsp;&nbsp;&nbsp;&nbsp;features&nbsp;depend&nbsp;on&nbsp;chromium&nbsp;source&nbsp;tree's&nbsp;presence&nbsp;and&nbsp;those&nbsp;won't&nbsp;work<br>
-&nbsp;&nbsp;&nbsp;&nbsp;in&nbsp;case&nbsp;this&nbsp;is&nbsp;not&nbsp;specified.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ProjectConfig-__init__"><strong>__init__</strong></a>(self, top_level_dir, benchmark_dirs<font color="#909090">=None</font>, benchmark_aliases<font color="#909090">=None</font>, client_config<font color="#909090">=None</font>, default_chrome_root<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>benchmark_aliases</strong></dt>
-</dl>
-<dl><dt><strong>benchmark_dirs</strong></dt>
-</dl>
-<dl><dt><strong>client_config</strong></dt>
-</dl>
-<dl><dt><strong>default_chrome_root</strong></dt>
-</dl>
-<dl><dt><strong>top_level_dir</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.record_wpr.html b/catapult/telemetry/docs/pydoc/telemetry.record_wpr.html
deleted file mode 100644
index a762abd..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.record_wpr.html
+++ /dev/null
@@ -1,173 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.record_wpr</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.record_wpr</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/record_wpr.py">telemetry/record_wpr.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="argparse.html">argparse</a><br>
-<a href="telemetry.benchmark.html">telemetry.benchmark</a><br>
-<a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="telemetry.internal.browser.browser_options.html">telemetry.internal.browser.browser_options</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.command_line.html">telemetry.internal.util.command_line</a><br>
-<a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-<a href="logging.html">logging</a><br>
-<a href="telemetry.page.page_test.html">telemetry.page.page_test</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.results_options.html">telemetry.internal.results.results_options</a><br>
-<a href="telemetry.story.html">telemetry.story</a><br>
-<a href="telemetry.internal.story_runner.html">telemetry.internal.story_runner</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-<a href="telemetry.util.wpr_modes.html">telemetry.util.wpr_modes</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.record_wpr.html#WprRecorder">WprRecorder</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.record_wpr.html#RecorderPageTest">RecorderPageTest</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RecorderPageTest">class <strong>RecorderPageTest</strong></a>(<a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.record_wpr.html#RecorderPageTest">RecorderPageTest</a></dd>
-<dd><a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="RecorderPageTest-CleanUpAfterPage"><strong>CleanUpAfterPage</strong></a>(self, page, tab)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(self, options)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-DidNavigateToPage"><strong>DidNavigateToPage</strong></a>(self, page, tab)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-RunNavigateSteps"><strong>RunNavigateSteps</strong></a>(self, page, tab)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-ValidateAndMeasurePage"><strong>ValidateAndMeasurePage</strong></a>(self, page, tab, results)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-WillNavigateToPage"><strong>WillNavigateToPage</strong></a>(self, page, tab)</dt><dd><tt>Override&nbsp;to&nbsp;ensure&nbsp;all&nbsp;resources&nbsp;are&nbsp;fetched&nbsp;from&nbsp;network.</tt></dd></dl>
-
-<dl><dt><a name="RecorderPageTest-WillStartBrowser"><strong>WillStartBrowser</strong></a>(self, browser)</dt></dl>
-
-<dl><dt><a name="RecorderPageTest-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>:<br>
-<dl><dt><a name="RecorderPageTest-DidRunPage"><strong>DidRunPage</strong></a>(self, platform)</dt><dd><tt>Called&nbsp;after&nbsp;the&nbsp;test&nbsp;run&nbsp;method&nbsp;was&nbsp;run,&nbsp;even&nbsp;if&nbsp;it&nbsp;failed.</tt></dd></dl>
-
-<dl><dt><a name="RecorderPageTest-RestartBrowserBeforeEachPage"><strong>RestartBrowserBeforeEachPage</strong></a>(self)</dt><dd><tt>Should&nbsp;the&nbsp;browser&nbsp;be&nbsp;restarted&nbsp;for&nbsp;the&nbsp;page?<br>
-&nbsp;<br>
-This&nbsp;returns&nbsp;true&nbsp;if&nbsp;the&nbsp;test&nbsp;needs&nbsp;to&nbsp;unconditionally&nbsp;restart&nbsp;the<br>
-browser&nbsp;for&nbsp;each&nbsp;page.&nbsp;It&nbsp;may&nbsp;be&nbsp;called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;started.</tt></dd></dl>
-
-<dl><dt><a name="RecorderPageTest-SetOptions"><strong>SetOptions</strong></a>(self, options)</dt><dd><tt>Sets&nbsp;the&nbsp;BrowserFinderOptions&nbsp;instance&nbsp;to&nbsp;use.</tt></dd></dl>
-
-<dl><dt><a name="RecorderPageTest-StopBrowserAfterPage"><strong>StopBrowserAfterPage</strong></a>(self, browser, page)</dt><dd><tt>Should&nbsp;the&nbsp;browser&nbsp;be&nbsp;stopped&nbsp;after&nbsp;the&nbsp;page&nbsp;is&nbsp;run?<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;called&nbsp;after&nbsp;a&nbsp;page&nbsp;is&nbsp;run&nbsp;to&nbsp;decide&nbsp;whether&nbsp;the&nbsp;browser&nbsp;needs&nbsp;to<br>
-be&nbsp;stopped&nbsp;to&nbsp;clean&nbsp;up&nbsp;its&nbsp;state.&nbsp;If&nbsp;it&nbsp;is&nbsp;stopped,&nbsp;then&nbsp;it&nbsp;will&nbsp;be<br>
-restarted&nbsp;to&nbsp;run&nbsp;the&nbsp;next&nbsp;page.<br>
-&nbsp;<br>
-A&nbsp;test&nbsp;that&nbsp;overrides&nbsp;this&nbsp;can&nbsp;look&nbsp;at&nbsp;both&nbsp;the&nbsp;page&nbsp;and&nbsp;the&nbsp;browser&nbsp;to<br>
-decide&nbsp;whether&nbsp;it&nbsp;needs&nbsp;to&nbsp;stop&nbsp;the&nbsp;browser.</tt></dd></dl>
-
-<dl><dt><a name="RecorderPageTest-TabForPage"><strong>TabForPage</strong></a>(self, page, browser)</dt><dd><tt>Override&nbsp;to&nbsp;select&nbsp;a&nbsp;different&nbsp;tab&nbsp;for&nbsp;the&nbsp;page.&nbsp;&nbsp;For&nbsp;instance,&nbsp;to<br>
-create&nbsp;a&nbsp;new&nbsp;tab&nbsp;for&nbsp;every&nbsp;page,&nbsp;return&nbsp;browser.tabs.New().</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>clear_cache_before_each_run</strong></dt>
-<dd><tt>When&nbsp;set&nbsp;to&nbsp;True,&nbsp;the&nbsp;browser's&nbsp;disk&nbsp;and&nbsp;memory&nbsp;cache&nbsp;will&nbsp;be&nbsp;cleared<br>
-before&nbsp;each&nbsp;run.</tt></dd>
-</dl>
-<dl><dt><strong>close_tabs_before_run</strong></dt>
-<dd><tt>When&nbsp;set&nbsp;to&nbsp;True,&nbsp;all&nbsp;tabs&nbsp;are&nbsp;closed&nbsp;before&nbsp;running&nbsp;the&nbsp;test&nbsp;for&nbsp;the<br>
-first&nbsp;time.</tt></dd>
-</dl>
-<dl><dt><strong>is_multi_tab_test</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;test&nbsp;opens&nbsp;multiple&nbsp;tabs.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;test&nbsp;overrides&nbsp;TabForPage,&nbsp;it&nbsp;is&nbsp;deemed&nbsp;a&nbsp;multi-tab&nbsp;test.<br>
-Multi-tab&nbsp;tests&nbsp;do&nbsp;not&nbsp;retry&nbsp;after&nbsp;tab&nbsp;or&nbsp;browser&nbsp;crashes,&nbsp;whereas,<br>
-single-tab&nbsp;tests&nbsp;too.&nbsp;That&nbsp;is&nbsp;because&nbsp;the&nbsp;state&nbsp;of&nbsp;multi-tab&nbsp;tests<br>
-(e.g.,&nbsp;how&nbsp;many&nbsp;tabs&nbsp;are&nbsp;open,&nbsp;etc.)&nbsp;is&nbsp;unknown&nbsp;after&nbsp;crashes.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WprRecorder">class <strong>WprRecorder</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="WprRecorder-CreateResults"><strong>CreateResults</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="WprRecorder-HandleResults"><strong>HandleResults</strong></a>(self, results, upload_to_cloud_storage)</dt></dl>
-
-<dl><dt><a name="WprRecorder-Record"><strong>Record</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="WprRecorder-__init__"><strong>__init__</strong></a>(self, base_dir, target, args<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>options</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-Main"><strong>Main</strong></a>(base_dir)</dt><dd><tt>#&nbsp;TODO(nednguyen):&nbsp;use&nbsp;benchmark.Environment&nbsp;instead&nbsp;of&nbsp;base_dir&nbsp;for&nbsp;discovering<br>
-#&nbsp;benchmark&nbsp;&amp;&nbsp;story&nbsp;classes.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.story.html b/catapult/telemetry/docs/pydoc/telemetry.story.html
deleted file mode 100644
index af7ef2b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.story.html
+++ /dev/null
@@ -1,40 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.story</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.story</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/story/__init__.py">telemetry/story/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.story.shared_state.html">shared_state</a><br>
-<a href="telemetry.story.story.html">story</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.story_filter.html">story_filter</a><br>
-<a href="telemetry.story.story_filter_unittest.html">story_filter_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.story_set.html">story_set</a><br>
-<a href="telemetry.story.story_set_unittest.html">story_set_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.story_unittest.html">story_unittest</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>INTERNAL_BUCKET</strong> = 'chrome-telemetry'<br>
-<strong>PARTNER_BUCKET</strong> = 'chrome-partner-telemetry'<br>
-<strong>PUBLIC_BUCKET</strong> = 'chromium-telemetry'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.story.shared_state.html b/catapult/telemetry/docs/pydoc/telemetry.story.shared_state.html
deleted file mode 100644
index b078cb0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.story.shared_state.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.story.shared_state</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.story.html"><font color="#ffffff">story</font></a>.shared_state</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/story/shared_state.py">telemetry/story/shared_state.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.shared_state.html#SharedState">SharedState</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SharedState">class <strong>SharedState</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;class&nbsp;that&nbsp;manages&nbsp;the&nbsp;test&nbsp;state&nbsp;across&nbsp;multiple&nbsp;stories.<br>
-It's&nbsp;styled&nbsp;on&nbsp;unittest.TestCase&nbsp;for&nbsp;handling&nbsp;test&nbsp;setup&nbsp;&amp;&nbsp;teardown&nbsp;logic.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="SharedState-CanRunStory"><strong>CanRunStory</strong></a>(self, story)</dt><dd><tt>Indicate&nbsp;whether&nbsp;the&nbsp;story&nbsp;can&nbsp;be&nbsp;run&nbsp;in&nbsp;the&nbsp;current&nbsp;configuration.<br>
-This&nbsp;is&nbsp;called&nbsp;after&nbsp;WillRunStory&nbsp;and&nbsp;before&nbsp;RunStory.&nbsp;Return&nbsp;True<br>
-if&nbsp;the&nbsp;story&nbsp;should&nbsp;be&nbsp;run,&nbsp;and&nbsp;False&nbsp;if&nbsp;it&nbsp;should&nbsp;be&nbsp;skipped.<br>
-Most&nbsp;subclasses&nbsp;will&nbsp;probably&nbsp;want&nbsp;to&nbsp;override&nbsp;this&nbsp;to&nbsp;always<br>
-return&nbsp;True.<br>
-Args:<br>
-&nbsp;&nbsp;story:&nbsp;a&nbsp;story.Story&nbsp;instance.</tt></dd></dl>
-
-<dl><dt><a name="SharedState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;after&nbsp;running&nbsp;each&nbsp;of&nbsp;all&nbsp;stories&nbsp;that<br>
-share&nbsp;this&nbsp;same&nbsp;state.<br>
-This&nbsp;method&nbsp;is&nbsp;styled&nbsp;on&nbsp;unittest.TestCase.tearDown.</tt></dd></dl>
-
-<dl><dt><a name="SharedState-RunStory"><strong>RunStory</strong></a>(self, results)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;before&nbsp;running&nbsp;each&nbsp;one&nbsp;of&nbsp;all&nbsp;stories<br>
-that&nbsp;share&nbsp;this&nbsp;same&nbsp;state.<br>
-This&nbsp;method&nbsp;is&nbsp;styled&nbsp;on&nbsp;unittest.TestCase.run.</tt></dd></dl>
-
-<dl><dt><a name="SharedState-TearDownState"><strong>TearDownState</strong></a>(self)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;after&nbsp;running&nbsp;multiple&nbsp;stories&nbsp;that<br>
-share&nbsp;this&nbsp;same&nbsp;state.<br>
-This&nbsp;method&nbsp;is&nbsp;styled&nbsp;on&nbsp;unittest.TestCase.tearDownClass.</tt></dd></dl>
-
-<dl><dt><a name="SharedState-WillRunStory"><strong>WillRunStory</strong></a>(self, story)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;before&nbsp;running&nbsp;each&nbsp;one&nbsp;of&nbsp;all&nbsp;stories<br>
-that&nbsp;share&nbsp;this&nbsp;same&nbsp;state.<br>
-This&nbsp;method&nbsp;is&nbsp;styled&nbsp;on&nbsp;unittest.TestCase.setUp.</tt></dd></dl>
-
-<dl><dt><a name="SharedState-__init__"><strong>__init__</strong></a>(self, test, options, story_set)</dt><dd><tt>This&nbsp;method&nbsp;is&nbsp;styled&nbsp;on&nbsp;unittest.TestCase.setUpClass.<br>
-Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;before&nbsp;running&nbsp;stories&nbsp;that<br>
-share&nbsp;this&nbsp;same&nbsp;state.<br>
-Args:<br>
-&nbsp;&nbsp;test:&nbsp;a&nbsp;page_test.PageTest&nbsp;or&nbsp;story_test.StoryTest&nbsp;instance.<br>
-&nbsp;&nbsp;options:&nbsp;a&nbsp;BrowserFinderOptions&nbsp;instance&nbsp;that&nbsp;contains&nbsp;command&nbsp;line<br>
-&nbsp;&nbsp;&nbsp;&nbsp;options.<br>
-&nbsp;&nbsp;story_set:&nbsp;a&nbsp;story.StorySet&nbsp;instance.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-<dd><tt>Override&nbsp;to&nbsp;return&nbsp;the&nbsp;platform&nbsp;which&nbsp;stories&nbsp;that&nbsp;share&nbsp;this&nbsp;same<br>
-state&nbsp;will&nbsp;be&nbsp;run&nbsp;on.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.story.story.html b/catapult/telemetry/docs/pydoc/telemetry.story.story.html
deleted file mode 100644
index de69c84..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.story.story.html
+++ /dev/null
@@ -1,111 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.story.story</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.story.html"><font color="#ffffff">story</font></a>.story</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/story/story.py">telemetry/story/story.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.shared_state.html">telemetry.story.shared_state</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.story.html#Story">Story</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Story">class <strong>Story</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;class&nbsp;styled&nbsp;on&nbsp;unittest.TestCase&nbsp;for&nbsp;creating&nbsp;story&nbsp;tests.<br>
-&nbsp;<br>
-Tests&nbsp;should&nbsp;override&nbsp;Run&nbsp;to&nbsp;maybe&nbsp;start&nbsp;the&nbsp;application&nbsp;and&nbsp;perform&nbsp;actions<br>
-on&nbsp;it.&nbsp;To&nbsp;share&nbsp;state&nbsp;between&nbsp;different&nbsp;tests,&nbsp;one&nbsp;can&nbsp;define&nbsp;a<br>
-shared_state&nbsp;which&nbsp;contains&nbsp;hooks&nbsp;that&nbsp;will&nbsp;be&nbsp;called&nbsp;before&nbsp;and<br>
-after&nbsp;mutiple&nbsp;stories&nbsp;run&nbsp;and&nbsp;in&nbsp;between&nbsp;runs.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;shared_state_class:&nbsp;subclass&nbsp;of&nbsp;telemetry.story.shared_state.SharedState.<br>
-&nbsp;&nbsp;name:&nbsp;string&nbsp;name&nbsp;of&nbsp;this&nbsp;story&nbsp;that&nbsp;can&nbsp;be&nbsp;used&nbsp;for&nbsp;identifying&nbsp;this&nbsp;story<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in&nbsp;results&nbsp;output.<br>
-&nbsp;&nbsp;labels:&nbsp;A&nbsp;list&nbsp;or&nbsp;set&nbsp;of&nbsp;string&nbsp;labels&nbsp;that&nbsp;are&nbsp;used&nbsp;for&nbsp;filtering.&nbsp;See<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;story.story_filter&nbsp;for&nbsp;more&nbsp;information.<br>
-&nbsp;&nbsp;is_local:&nbsp;If&nbsp;True,&nbsp;the&nbsp;story&nbsp;does&nbsp;not&nbsp;require&nbsp;network.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Story-AsDict"><strong>AsDict</strong></a>(self)</dt><dd><tt>Converts&nbsp;a&nbsp;story&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;to&nbsp;a&nbsp;dict&nbsp;suitable&nbsp;for&nbsp;JSON&nbsp;output.</tt></dd></dl>
-
-<dl><dt><a name="Story-Run"><strong>Run</strong></a>(self, shared_state)</dt><dd><tt>Execute&nbsp;the&nbsp;interactions&nbsp;with&nbsp;the&nbsp;applications&nbsp;and/or&nbsp;platforms.</tt></dd></dl>
-
-<dl><dt><a name="Story-__init__"><strong>__init__</strong></a>(self, shared_state_class, name<font color="#909090">=''</font>, labels<font color="#909090">=None</font>, is_local<font color="#909090">=False</font>, make_javascript_deterministic<font color="#909090">=True</font>)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;make_javascript_deterministic:&nbsp;Whether&nbsp;JavaScript&nbsp;performed&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page&nbsp;is&nbsp;made&nbsp;deterministic&nbsp;across&nbsp;multiple&nbsp;runs.&nbsp;This<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;requires&nbsp;that&nbsp;the&nbsp;web&nbsp;content&nbsp;is&nbsp;served&nbsp;via&nbsp;Web&nbsp;Page&nbsp;Replay<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;take&nbsp;effect.&nbsp;This&nbsp;setting&nbsp;does&nbsp;not&nbsp;affect&nbsp;stories&nbsp;containing&nbsp;no&nbsp;web<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;or&nbsp;where&nbsp;the&nbsp;HTTP&nbsp;MIME&nbsp;type&nbsp;is&nbsp;not&nbsp;text/html.See&nbsp;also:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_InjectScripts&nbsp;method&nbsp;in&nbsp;third_party/webpagereplay/httpclient.py.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>display_name</strong></dt>
-</dl>
-<dl><dt><strong>file_safe_name</strong></dt>
-<dd><tt>A&nbsp;version&nbsp;of&nbsp;display_name&nbsp;that's&nbsp;safe&nbsp;to&nbsp;use&nbsp;as&nbsp;a&nbsp;filename.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;sanitizes&nbsp;special&nbsp;characters&nbsp;with&nbsp;underscores,<br>
-but&nbsp;it's&nbsp;okay&nbsp;to&nbsp;override&nbsp;it&nbsp;with&nbsp;a&nbsp;more&nbsp;specific&nbsp;implementation&nbsp;in<br>
-subclasses.</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-<dl><dt><strong>is_local</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;story&nbsp;does&nbsp;not&nbsp;require&nbsp;network.</tt></dd>
-</dl>
-<dl><dt><strong>labels</strong></dt>
-</dl>
-<dl><dt><strong>make_javascript_deterministic</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>serving_dir</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;absolute&nbsp;path&nbsp;to&nbsp;a&nbsp;directory&nbsp;with&nbsp;hash&nbsp;files&nbsp;to&nbsp;data&nbsp;that<br>
-should&nbsp;be&nbsp;updated&nbsp;from&nbsp;cloud&nbsp;storage,&nbsp;or&nbsp;None&nbsp;if&nbsp;no&nbsp;files&nbsp;need&nbsp;to&nbsp;be<br>
-updated.</tt></dd>
-</dl>
-<dl><dt><strong>shared_state_class</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.story.story_filter.html b/catapult/telemetry/docs/pydoc/telemetry.story.story_filter.html
deleted file mode 100644
index 6ed1bd2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.story.story_filter.html
+++ /dev/null
@@ -1,72 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.story.story_filter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.story.html"><font color="#ffffff">story</font></a>.story_filter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/story/story_filter.py">telemetry/story/story_filter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.command_line.html">telemetry.internal.util.command_line</a><br>
-</td><td width="25%" valign=top><a href="optparse.html">optparse</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.story_filter.html#StoryFilter">StoryFilter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StoryFilter">class <strong>StoryFilter</strong></a>(<a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Filters&nbsp;stories&nbsp;in&nbsp;the&nbsp;story&nbsp;set&nbsp;based&nbsp;on&nbsp;command-line&nbsp;flags.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.story.story_filter.html#StoryFilter">StoryFilter</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="StoryFilter-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="StoryFilter-IsSelected"><strong>IsSelected</strong></a>(cls, story)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="StoryFilter-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.story.story_set.html b/catapult/telemetry/docs/pydoc/telemetry.story.story_set.html
deleted file mode 100644
index 73e8ec6..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.story.story_set.html
+++ /dev/null
@@ -1,139 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.story.story_set</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.story.html"><font color="#ffffff">story</font></a>.story_set</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/story/story_set.py">telemetry/story/story_set.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.wpr.archive_info.html">telemetry.wpr.archive_info</a><br>
-</td><td width="25%" valign=top><a href="inspect.html">inspect</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.story.html">telemetry.story.story</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.story.story_set.html#StorySet">StorySet</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StorySet">class <strong>StorySet</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;collection&nbsp;of&nbsp;stories.<br>
-&nbsp;<br>
-A&nbsp;typical&nbsp;usage&nbsp;of&nbsp;<a href="#StorySet">StorySet</a>&nbsp;would&nbsp;be&nbsp;to&nbsp;subclass&nbsp;it&nbsp;and&nbsp;then&nbsp;call<br>
-AddStory&nbsp;for&nbsp;each&nbsp;Story.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="StorySet-AddStory"><strong>AddStory</strong></a>(self, story)</dt></dl>
-
-<dl><dt><a name="StorySet-RemoveStory"><strong>RemoveStory</strong></a>(self, story)</dt><dd><tt>Removes&nbsp;a&nbsp;Story.<br>
-&nbsp;<br>
-Allows&nbsp;the&nbsp;stories&nbsp;to&nbsp;be&nbsp;filtered.</tt></dd></dl>
-
-<dl><dt><a name="StorySet-WprFilePathForStory"><strong>WprFilePathForStory</strong></a>(self, story)</dt><dd><tt>Convenient&nbsp;function&nbsp;to&nbsp;retrieve&nbsp;WPR&nbsp;archive&nbsp;file&nbsp;path.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;story:&nbsp;The&nbsp;Story&nbsp;to&nbsp;look&nbsp;up.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;WPR&nbsp;archive&nbsp;file&nbsp;path&nbsp;for&nbsp;the&nbsp;given&nbsp;Story,&nbsp;if&nbsp;found.<br>
-&nbsp;&nbsp;Otherwise,&nbsp;None.</tt></dd></dl>
-
-<dl><dt><a name="StorySet-__getitem__"><strong>__getitem__</strong></a>(self, key)</dt></dl>
-
-<dl><dt><a name="StorySet-__init__"><strong>__init__</strong></a>(self, archive_data_file<font color="#909090">=''</font>, cloud_storage_bucket<font color="#909090">=None</font>, base_dir<font color="#909090">=None</font>, serving_dirs<font color="#909090">=None</font>)</dt><dd><tt>Creates&nbsp;a&nbsp;new&nbsp;<a href="#StorySet">StorySet</a>.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;archive_data_file:&nbsp;The&nbsp;path&nbsp;to&nbsp;Web&nbsp;Page&nbsp;Replay's&nbsp;archive&nbsp;data,&nbsp;relative<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;self.<strong>base_dir</strong>.<br>
-&nbsp;&nbsp;cloud_storage_bucket:&nbsp;The&nbsp;cloud&nbsp;storage&nbsp;bucket&nbsp;used&nbsp;to&nbsp;download<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Web&nbsp;Page&nbsp;Replay's&nbsp;archive&nbsp;data.&nbsp;Valid&nbsp;values&nbsp;are:&nbsp;None,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;story.PUBLIC_BUCKET,&nbsp;story.PARTNER_BUCKET,&nbsp;or&nbsp;story.INTERNAL_BUCKET<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(defined&nbsp;in&nbsp;telemetry.util.cloud_storage).<br>
-&nbsp;&nbsp;serving_dirs:&nbsp;A&nbsp;set&nbsp;of&nbsp;paths,&nbsp;relative&nbsp;to&nbsp;self.<strong>base_dir</strong>,&nbsp;to&nbsp;directories<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;containing&nbsp;hash&nbsp;files&nbsp;for&nbsp;non-wpr&nbsp;archive&nbsp;data&nbsp;stored&nbsp;in&nbsp;cloud<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;storage.</tt></dd></dl>
-
-<dl><dt><a name="StorySet-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySet-__len__"><strong>__len__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySet-__setitem__"><strong>__setitem__</strong></a>(self, key, value)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="StorySet-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Return&nbsp;a&nbsp;string&nbsp;explaining&nbsp;in&nbsp;human-understandable&nbsp;terms&nbsp;what&nbsp;this<br>
-story&nbsp;represents.<br>
-Note&nbsp;that&nbsp;this&nbsp;should&nbsp;be&nbsp;a&nbsp;classmethod&nbsp;so&nbsp;the&nbsp;benchmark_runner&nbsp;script&nbsp;can<br>
-display&nbsp;stories'&nbsp;names&nbsp;along&nbsp;with&nbsp;their&nbsp;descriptions&nbsp;in&nbsp;the&nbsp;list&nbsp;command.</tt></dd></dl>
-
-<dl><dt><a name="StorySet-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Returns&nbsp;the&nbsp;string&nbsp;name&nbsp;of&nbsp;this&nbsp;<a href="#StorySet">StorySet</a>.<br>
-Note&nbsp;that&nbsp;this&nbsp;should&nbsp;be&nbsp;a&nbsp;classmethod&nbsp;so&nbsp;the&nbsp;benchmark_runner&nbsp;script&nbsp;can<br>
-match&nbsp;the&nbsp;story&nbsp;class&nbsp;with&nbsp;its&nbsp;name&nbsp;specified&nbsp;in&nbsp;the&nbsp;run&nbsp;command:<br>
-'Run&nbsp;&lt;User&nbsp;story&nbsp;test&nbsp;name&gt;&nbsp;&lt;User&nbsp;story&nbsp;class&nbsp;name&gt;'</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>allow_mixed_story_states</strong></dt>
-<dd><tt>True&nbsp;iff&nbsp;Stories&nbsp;are&nbsp;allowed&nbsp;to&nbsp;have&nbsp;different&nbsp;StoryState&nbsp;classes.<br>
-&nbsp;<br>
-There&nbsp;are&nbsp;no&nbsp;checks&nbsp;in&nbsp;place&nbsp;for&nbsp;determining&nbsp;if&nbsp;SharedStates&nbsp;are<br>
-being&nbsp;assigned&nbsp;correctly&nbsp;to&nbsp;all&nbsp;Stories&nbsp;in&nbsp;a&nbsp;given&nbsp;StorySet.&nbsp;The<br>
-majority&nbsp;of&nbsp;test&nbsp;cases&nbsp;should&nbsp;not&nbsp;need&nbsp;the&nbsp;ability&nbsp;to&nbsp;have&nbsp;multiple<br>
-SharedStates,&nbsp;which&nbsp;usually&nbsp;implies&nbsp;you&nbsp;should&nbsp;be&nbsp;writing&nbsp;multiple<br>
-benchmarks&nbsp;instead.&nbsp;We&nbsp;provide&nbsp;errors&nbsp;to&nbsp;avoid&nbsp;accidentally&nbsp;assigning<br>
-or&nbsp;defaulting&nbsp;to&nbsp;the&nbsp;wrong&nbsp;SharedState.<br>
-Override&nbsp;at&nbsp;your&nbsp;own&nbsp;risk.&nbsp;Here&nbsp;be&nbsp;dragons.</tt></dd>
-</dl>
-<dl><dt><strong>archive_data_file</strong></dt>
-</dl>
-<dl><dt><strong>base_dir</strong></dt>
-<dd><tt>The&nbsp;base&nbsp;directory&nbsp;to&nbsp;resolve&nbsp;archive_data_file.<br>
-&nbsp;<br>
-This&nbsp;defaults&nbsp;to&nbsp;the&nbsp;directory&nbsp;containing&nbsp;the&nbsp;StorySet&nbsp;instance's&nbsp;class.</tt></dd>
-</dl>
-<dl><dt><strong>bucket</strong></dt>
-</dl>
-<dl><dt><strong>file_path</strong></dt>
-</dl>
-<dl><dt><strong>serving_dirs</strong></dt>
-</dl>
-<dl><dt><strong>wpr_archive_info</strong></dt>
-<dd><tt>Lazily&nbsp;constructs&nbsp;wpr_archive_info&nbsp;if&nbsp;it's&nbsp;not&nbsp;set&nbsp;and&nbsp;returns&nbsp;it.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.browser_test_case.html b/catapult/telemetry/docs/pydoc/telemetry.testing.browser_test_case.html
deleted file mode 100644
index 05e5d4f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.browser_test_case.html
+++ /dev/null
@@ -1,355 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.browser_test_case</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.browser_test_case</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/browser_test_case.py">telemetry/testing/browser_test_case.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-</td><td width="25%" valign=top><a href="unittest.html">unittest</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="unittest.case.html#TestCase">unittest.case.TestCase</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.browser_test_case.html#BrowserTestCase">BrowserTestCase</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BrowserTestCase">class <strong>BrowserTestCase</strong></a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.browser_test_case.html#BrowserTestCase">BrowserTestCase</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="BrowserTestCase-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;add&nbsp;test-specific&nbsp;options&nbsp;to&nbsp;the&nbsp;BrowserOptions&nbsp;object</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-UrlOfUnittestFile"><strong>UrlOfUnittestFile</strong></a>(cls, filename)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="BrowserTestCase-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="BrowserTestCase-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="BrowserTestCase-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-__init__"><strong>__init__</strong></a>(self, methodName<font color="#909090">='runTest'</font>)</dt><dd><tt>Create&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;class&nbsp;that&nbsp;will&nbsp;use&nbsp;the&nbsp;named&nbsp;test<br>
-method&nbsp;when&nbsp;executed.&nbsp;Raises&nbsp;a&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;instance&nbsp;does<br>
-not&nbsp;have&nbsp;a&nbsp;method&nbsp;with&nbsp;the&nbsp;specified&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#BrowserTestCase-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#BrowserTestCase-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#BrowserTestCase-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#BrowserTestCase-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#BrowserTestCase-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#BrowserTestCase-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="BrowserTestCase-setUp"><strong>setUp</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;the&nbsp;test&nbsp;fixture&nbsp;before&nbsp;exercising&nbsp;it.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="BrowserTestCase-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-teardown_browser"><strong>teardown_browser</strong></a>()</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>current_browser</strong> = None<br>
-<strong>current_browser_options</strong> = None</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.disabled_cases.html b/catapult/telemetry/docs/pydoc/telemetry.testing.disabled_cases.html
deleted file mode 100644
index d3982bb..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.disabled_cases.html
+++ /dev/null
@@ -1,363 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.disabled_cases</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.disabled_cases</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/disabled_cases.py">telemetry/testing/disabled_cases.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="unittest.html">unittest</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="unittest.case.html#TestCase">unittest.case.TestCase</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.disabled_cases.html#DisabledCases">DisabledCases</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="DisabledCases">class <strong>DisabledCases</strong></a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;These&nbsp;are&nbsp;not&nbsp;real&nbsp;unittests.<br>
-#&nbsp;They&nbsp;are&nbsp;merely&nbsp;to&nbsp;test&nbsp;our&nbsp;Enable/Disable&nbsp;annotations.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.disabled_cases.html#DisabledCases">DisabledCases</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="DisabledCases-testAllDisabled"><strong>testAllDisabled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testAllEnabled"><strong>testAllEnabled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testChromeOSOnly"><strong>testChromeOSOnly</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testHasTabs"><strong>testHasTabs</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testMacOnly"><strong>testMacOnly</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testMavericksOnly"><strong>testMavericksOnly</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testNoChromeOS"><strong>testNoChromeOS</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testNoMac"><strong>testNoMac</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testNoMavericks"><strong>testNoMavericks</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testNoSystem"><strong>testNoSystem</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testNoWinLinux"><strong>testNoWinLinux</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testSystemOnly"><strong>testSystemOnly</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-testWinOrLinuxOnly"><strong>testWinOrLinuxOnly</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="DisabledCases-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="DisabledCases-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="DisabledCases-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-__init__"><strong>__init__</strong></a>(self, methodName<font color="#909090">='runTest'</font>)</dt><dd><tt>Create&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;class&nbsp;that&nbsp;will&nbsp;use&nbsp;the&nbsp;named&nbsp;test<br>
-method&nbsp;when&nbsp;executed.&nbsp;Raises&nbsp;a&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;instance&nbsp;does<br>
-not&nbsp;have&nbsp;a&nbsp;method&nbsp;with&nbsp;the&nbsp;specified&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="DisabledCases-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#DisabledCases-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="DisabledCases-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#DisabledCases-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#DisabledCases-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#DisabledCases-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#DisabledCases-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#DisabledCases-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="DisabledCases-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="DisabledCases-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="DisabledCases-setUp"><strong>setUp</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;the&nbsp;test&nbsp;fixture&nbsp;before&nbsp;exercising&nbsp;it.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="DisabledCases-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;class&nbsp;fixture&nbsp;before&nbsp;running&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<dl><dt><a name="DisabledCases-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;class&nbsp;fixture&nbsp;after&nbsp;running&nbsp;all&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.fakes.html b/catapult/telemetry/docs/pydoc/telemetry.testing.fakes.html
deleted file mode 100644
index bc998a1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.fakes.html
+++ /dev/null
@@ -1,367 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.testing.fakes</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.fakes</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/fakes/__init__.py">telemetry/testing/fakes/__init__.py</a></font></td></tr></table>
-    <p><tt>Provides&nbsp;fakes&nbsp;for&nbsp;several&nbsp;of&nbsp;Telemetry's&nbsp;internal&nbsp;objects.<br>
-&nbsp;<br>
-These&nbsp;allow&nbsp;code&nbsp;like&nbsp;story_runner&nbsp;and&nbsp;Benchmark&nbsp;to&nbsp;be&nbsp;run&nbsp;and&nbsp;tested<br>
-without&nbsp;compiling&nbsp;or&nbsp;starting&nbsp;a&nbsp;browser.&nbsp;Class&nbsp;names&nbsp;prepended&nbsp;with&nbsp;an<br>
-underscore&nbsp;are&nbsp;intended&nbsp;to&nbsp;be&nbsp;implementation&nbsp;details,&nbsp;and&nbsp;should&nbsp;not<br>
-be&nbsp;subclassed;&nbsp;however,&nbsp;some,&nbsp;like&nbsp;_FakeBrowser,&nbsp;have&nbsp;public&nbsp;APIs&nbsp;that<br>
-may&nbsp;need&nbsp;to&nbsp;be&nbsp;called&nbsp;in&nbsp;tests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakeHTTPServer">FakeHTTPServer</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakeInspectorWebsocket">FakeInspectorWebsocket</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakePlatform">FakePlatform</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakeLinuxPlatform">FakeLinuxPlatform</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakePossibleBrowser">FakePossibleBrowser</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.platform.system_info.html#SystemInfo">telemetry.internal.platform.system_info.SystemInfo</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakeSystemInfo">FakeSystemInfo</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.page.shared_page_state.html#SharedPageState">telemetry.page.shared_page_state.SharedPageState</a>(<a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.fakes.html#FakeSharedPageState">FakeSharedPageState</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakeHTTPServer">class <strong>FakeHTTPServer</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FakeHTTPServer-UrlOf"><strong>UrlOf</strong></a>(self, url)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakeInspectorWebsocket">class <strong>FakeInspectorWebsocket</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FakeInspectorWebsocket-AddAsyncResponse"><strong>AddAsyncResponse</strong></a>(self, method, result, time)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-AddEvent"><strong>AddEvent</strong></a>(self, method, params, time)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-AddResponseHandler"><strong>AddResponseHandler</strong></a>(self, method, handler)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-AsyncRequest"><strong>AsyncRequest</strong></a>(self, request, callback)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-Connect"><strong>Connect</strong></a>(self, _)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-DispatchNotifications"><strong>DispatchNotifications</strong></a>(self, timeout)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-RegisterDomain"><strong>RegisterDomain</strong></a>(self, _, handler)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-SendAndIgnoreResponse"><strong>SendAndIgnoreResponse</strong></a>(self, request)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-SyncRequest"><strong>SyncRequest</strong></a>(self, request, *_args, **_kwargs)</dt></dl>
-
-<dl><dt><a name="FakeInspectorWebsocket-__init__"><strong>__init__</strong></a>(self, mock_timer)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakeLinuxPlatform">class <strong>FakeLinuxPlatform</strong></a>(<a href="telemetry.testing.fakes.html#FakePlatform">FakePlatform</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.fakes.html#FakeLinuxPlatform">FakeLinuxPlatform</a></dd>
-<dd><a href="telemetry.testing.fakes.html#FakePlatform">FakePlatform</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FakeLinuxPlatform-CanTakeScreenshot"><strong>CanTakeScreenshot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-SetHTTPServerDirectories"><strong>SetHTTPServerDirectories</strong></a>(self, paths)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-TakeScreenshot"><strong>TakeScreenshot</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.testing.fakes.html#FakePlatform">FakePlatform</a>:<br>
-<dl><dt><a name="FakeLinuxPlatform-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeLinuxPlatform-StopAllLocalServers"><strong>StopAllLocalServers</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.testing.fakes.html#FakePlatform">FakePlatform</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>network_controller</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakePlatform">class <strong>FakePlatform</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FakePlatform-CanMonitorThermalThrottling"><strong>CanMonitorThermalThrottling</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-GetArchName"><strong>GetArchName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-GetDeviceTypeName"><strong>GetDeviceTypeName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-GetOSName"><strong>GetOSName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-GetOSVersionName"><strong>GetOSVersionName</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-HasBeenThermallyThrottled"><strong>HasBeenThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-IsThermallyThrottled"><strong>IsThermallyThrottled</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePlatform-StopAllLocalServers"><strong>StopAllLocalServers</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>is_host_platform</strong></dt>
-</dl>
-<dl><dt><strong>network_controller</strong></dt>
-</dl>
-<dl><dt><strong>tracing_controller</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakePossibleBrowser">class <strong>FakePossibleBrowser</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="FakePossibleBrowser-Create"><strong>Create</strong></a>(self, finder_options)</dt></dl>
-
-<dl><dt><a name="FakePossibleBrowser-IsRemote"><strong>IsRemote</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakePossibleBrowser-SetCredentialsPath"><strong>SetCredentialsPath</strong></a>(self, _)</dt></dl>
-
-<dl><dt><a name="FakePossibleBrowser-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-<dd><tt>The&nbsp;platform&nbsp;object&nbsp;from&nbsp;the&nbsp;returned&nbsp;browser.<br>
-&nbsp;<br>
-To&nbsp;change&nbsp;this&nbsp;or&nbsp;set&nbsp;it&nbsp;up,&nbsp;change&nbsp;the&nbsp;returned&nbsp;browser's<br>
-platform.</tt></dd>
-</dl>
-<dl><dt><strong>returned_browser</strong></dt>
-<dd><tt>The&nbsp;browser&nbsp;object&nbsp;that&nbsp;will&nbsp;be&nbsp;returned&nbsp;through&nbsp;later&nbsp;API&nbsp;calls.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakeSharedPageState">class <strong>FakeSharedPageState</strong></a>(<a href="telemetry.page.shared_page_state.html#SharedPageState">telemetry.page.shared_page_state.SharedPageState</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.fakes.html#FakeSharedPageState">FakeSharedPageState</a></dd>
-<dd><a href="telemetry.page.shared_page_state.html#SharedPageState">telemetry.page.shared_page_state.SharedPageState</a></dd>
-<dd><a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FakeSharedPageState-ConfigurePossibleBrowser"><strong>ConfigurePossibleBrowser</strong></a>(self, possible_browser)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;configure&nbsp;the&nbsp;PossibleBrowser.<br>
-&nbsp;<br>
-Can&nbsp;make&nbsp;changes&nbsp;to&nbsp;the&nbsp;browser's&nbsp;configuration&nbsp;here&nbsp;via&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;possible_browser.returned_browser.returned_system_info&nbsp;=&nbsp;...</tt></dd></dl>
-
-<dl><dt><a name="FakeSharedPageState-DidRunStory"><strong>DidRunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="FakeSharedPageState-__init__"><strong>__init__</strong></a>(self, test, finder_options, story_set)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">telemetry.page.shared_page_state.SharedPageState</a>:<br>
-<dl><dt><a name="FakeSharedPageState-CanRunOnBrowser"><strong>CanRunOnBrowser</strong></a>(self, browser_info, page)</dt><dd><tt>Override&nbsp;this&nbsp;to&nbsp;return&nbsp;whether&nbsp;the&nbsp;browser&nbsp;brought&nbsp;up&nbsp;by&nbsp;this&nbsp;state<br>
-instance&nbsp;is&nbsp;suitable&nbsp;for&nbsp;running&nbsp;the&nbsp;given&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;browser_info:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.core.browser_info.BrowserInfo<br>
-&nbsp;&nbsp;page:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.page.Page</tt></dd></dl>
-
-<dl><dt><a name="FakeSharedPageState-CanRunStory"><strong>CanRunStory</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="FakeSharedPageState-GetPregeneratedProfileArchiveDir"><strong>GetPregeneratedProfileArchiveDir</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeSharedPageState-RunStory"><strong>RunStory</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="FakeSharedPageState-SetPregeneratedProfileArchiveDir"><strong>SetPregeneratedProfileArchiveDir</strong></a>(self, archive_path)</dt><dd><tt>Benchmarks&nbsp;can&nbsp;set&nbsp;a&nbsp;pre-generated&nbsp;profile&nbsp;archive&nbsp;to&nbsp;indicate&nbsp;that&nbsp;when<br>
-Chrome&nbsp;is&nbsp;launched,&nbsp;it&nbsp;should&nbsp;have&nbsp;a&nbsp;--user-data-dir&nbsp;set&nbsp;to&nbsp;the<br>
-pregenerated&nbsp;profile,&nbsp;rather&nbsp;than&nbsp;to&nbsp;an&nbsp;empty&nbsp;profile.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;benchmark&nbsp;is&nbsp;invoked&nbsp;with&nbsp;the&nbsp;option&nbsp;--profile-dir=&lt;dir&gt;,&nbsp;that<br>
-option&nbsp;overrides&nbsp;this&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="FakeSharedPageState-TearDownState"><strong>TearDownState</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FakeSharedPageState-WillRunStory"><strong>WillRunStory</strong></a>(self, page)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.shared_page_state.html#SharedPageState">telemetry.page.shared_page_state.SharedPageState</a>:<br>
-<dl><dt><strong>browser</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_tab</strong></dt>
-</dl>
-<dl><dt><strong>page_test</strong></dt>
-</dl>
-<dl><dt><strong>platform</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.shared_state.html#SharedState">telemetry.story.shared_state.SharedState</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FakeSystemInfo">class <strong>FakeSystemInfo</strong></a>(<a href="telemetry.internal.platform.system_info.html#SystemInfo">telemetry.internal.platform.system_info.SystemInfo</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.fakes.html#FakeSystemInfo">FakeSystemInfo</a></dd>
-<dd><a href="telemetry.internal.platform.system_info.html#SystemInfo">telemetry.internal.platform.system_info.SystemInfo</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FakeSystemInfo-__init__"><strong>__init__</strong></a>(self, model_name<font color="#909090">=''</font>, gpu_dict<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.platform.system_info.html#SystemInfo">telemetry.internal.platform.system_info.SystemInfo</a>:<br>
-<dl><dt><a name="FakeSystemInfo-FromDict"><strong>FromDict</strong></a>(cls, attrs)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Constructs&nbsp;a&nbsp;<a href="telemetry.internal.platform.system_info.html#SystemInfo">SystemInfo</a>&nbsp;from&nbsp;a&nbsp;dictionary&nbsp;of&nbsp;attributes.<br>
-Attributes&nbsp;currently&nbsp;required&nbsp;to&nbsp;be&nbsp;present&nbsp;in&nbsp;the&nbsp;dictionary:<br>
-&nbsp;<br>
-&nbsp;&nbsp;model_name&nbsp;(string):&nbsp;a&nbsp;platform-dependent&nbsp;string<br>
-&nbsp;&nbsp;&nbsp;&nbsp;describing&nbsp;the&nbsp;model&nbsp;of&nbsp;machine,&nbsp;or&nbsp;the&nbsp;empty&nbsp;string&nbsp;if&nbsp;not<br>
-&nbsp;&nbsp;&nbsp;&nbsp;supported.<br>
-&nbsp;&nbsp;gpu&nbsp;(<a href="__builtin__.html#object">object</a>&nbsp;containing&nbsp;GPUInfo's&nbsp;required&nbsp;attributes)</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.platform.system_info.html#SystemInfo">telemetry.internal.platform.system_info.SystemInfo</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>gpu</strong></dt>
-<dd><tt>A&nbsp;GPUInfo&nbsp;object&nbsp;describing&nbsp;the&nbsp;graphics&nbsp;processor(s)&nbsp;on&nbsp;the&nbsp;system.</tt></dd>
-</dl>
-<dl><dt><strong>model_name</strong></dt>
-<dd><tt>A&nbsp;string&nbsp;describing&nbsp;the&nbsp;machine&nbsp;model.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;a&nbsp;highly&nbsp;platform-dependent&nbsp;value&nbsp;and&nbsp;not&nbsp;currently<br>
-specified&nbsp;for&nbsp;any&nbsp;machine&nbsp;type&nbsp;aside&nbsp;from&nbsp;Macs.&nbsp;On&nbsp;Mac&nbsp;OS,&nbsp;this<br>
-is&nbsp;the&nbsp;model&nbsp;identifier,&nbsp;reformatted&nbsp;slightly;&nbsp;for&nbsp;example,<br>
-'MacBookPro&nbsp;10.1'.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CreateBrowserFinderOptions"><strong>CreateBrowserFinderOptions</strong></a>(browser_type<font color="#909090">=None</font>)</dt><dd><tt>Creates&nbsp;fake&nbsp;browser&nbsp;finder&nbsp;options&nbsp;for&nbsp;discovering&nbsp;a&nbsp;browser.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.gtest_progress_reporter.html b/catapult/telemetry/docs/pydoc/telemetry.testing.gtest_progress_reporter.html
deleted file mode 100644
index 99b8a57..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.gtest_progress_reporter.html
+++ /dev/null
@@ -1,90 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.gtest_progress_reporter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.gtest_progress_reporter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/gtest_progress_reporter.py">telemetry/testing/gtest_progress_reporter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.exception_formatter.html">telemetry.internal.util.exception_formatter</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.testing.progress_reporter.html">telemetry.testing.progress_reporter</a><br>
-<a href="time.html">time</a><br>
-</td><td width="25%" valign=top><a href="unittest.html">unittest</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.progress_reporter.html#ProgressReporter">telemetry.testing.progress_reporter.ProgressReporter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.gtest_progress_reporter.html#GTestProgressReporter">GTestProgressReporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GTestProgressReporter">class <strong>GTestProgressReporter</strong></a>(<a href="telemetry.testing.progress_reporter.html#ProgressReporter">telemetry.testing.progress_reporter.ProgressReporter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.gtest_progress_reporter.html#GTestProgressReporter">GTestProgressReporter</a></dd>
-<dd><a href="telemetry.testing.progress_reporter.html#ProgressReporter">telemetry.testing.progress_reporter.ProgressReporter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="GTestProgressReporter-Error"><strong>Error</strong></a>(self, test, err)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-Failure"><strong>Failure</strong></a>(self, test, err)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-Skip"><strong>Skip</strong></a>(self, test, reason)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-StartTest"><strong>StartTest</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-StartTestSuite"><strong>StartTestSuite</strong></a>(self, suite)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-StopTestRun"><strong>StopTestRun</strong></a>(self, result)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-StopTestSuite"><strong>StopTestSuite</strong></a>(self, suite)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-Success"><strong>Success</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-__init__"><strong>__init__</strong></a>(self, output_stream)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.testing.progress_reporter.html#ProgressReporter">telemetry.testing.progress_reporter.ProgressReporter</a>:<br>
-<dl><dt><a name="GTestProgressReporter-StartTestRun"><strong>StartTestRun</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="GTestProgressReporter-StopTest"><strong>StopTest</strong></a>(self, test)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.testing.progress_reporter.html#ProgressReporter">telemetry.testing.progress_reporter.ProgressReporter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.html b/catapult/telemetry/docs/pydoc/telemetry.testing.html
deleted file mode 100644
index e27124c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.html
+++ /dev/null
@@ -1,47 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.testing</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.testing</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/__init__.py">telemetry/testing/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.testing.browser_test_case.html">browser_test_case</a><br>
-<a href="telemetry.testing.decorators_unittest.html">decorators_unittest</a><br>
-<a href="telemetry.testing.disabled_cases.html">disabled_cases</a><br>
-<a href="telemetry.testing.fakes.html"><strong>fakes</strong>&nbsp;(package)</a><br>
-<a href="telemetry.testing.gtest_progress_reporter.html">gtest_progress_reporter</a><br>
-<a href="telemetry.testing.gtest_progress_reporter_unittest.html">gtest_progress_reporter_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.testing.internal.html"><strong>internal</strong>&nbsp;(package)</a><br>
-<a href="telemetry.testing.options_for_unittests.html">options_for_unittests</a><br>
-<a href="telemetry.testing.page_test_test_case.html">page_test_test_case</a><br>
-<a href="telemetry.testing.progress_reporter.html">progress_reporter</a><br>
-<a href="telemetry.testing.progress_reporter_unittest.html">progress_reporter_unittest</a><br>
-<a href="telemetry.testing.run_chromeos_tests.html">run_chromeos_tests</a><br>
-</td><td width="25%" valign=top><a href="telemetry.testing.run_tests.html">run_tests</a><br>
-<a href="telemetry.testing.run_tests_unittest.html">run_tests_unittest</a><br>
-<a href="telemetry.testing.simple_mock.html">simple_mock</a><br>
-<a href="telemetry.testing.simple_mock_unittest.html">simple_mock_unittest</a><br>
-<a href="telemetry.testing.story_set_smoke_test.html">story_set_smoke_test</a><br>
-<a href="telemetry.testing.stream.html">stream</a><br>
-</td><td width="25%" valign=top><a href="telemetry.testing.system_stub.html">system_stub</a><br>
-<a href="telemetry.testing.system_stub_unittest.html">system_stub_unittest</a><br>
-<a href="telemetry.testing.tab_test_case.html">tab_test_case</a><br>
-<a href="telemetry.testing.test_page_test_results.html">test_page_test_results</a><br>
-<a href="telemetry.testing.unittest_runner.html">unittest_runner</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.internal.fake_gpu_info.html b/catapult/telemetry/docs/pydoc/telemetry.testing.internal.fake_gpu_info.html
deleted file mode 100644
index 7407598..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.internal.fake_gpu_info.html
+++ /dev/null
@@ -1,24 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.internal.fake_gpu_info</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.<a href="telemetry.testing.internal.html"><font color="#ffffff">internal</font></a>.fake_gpu_info</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/internal/fake_gpu_info.py">telemetry/testing/internal/fake_gpu_info.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>FAKE_GPU_INFO</strong> = {'aux_attributes': {'adapter_luid': 0.0, 'amd_switchable': False, 'basic_info_state': 1, 'can_lose_context': False, 'context_info_state': 1, 'direct_rendering': True, 'driver_date': '', 'driver_vendor': 'NVIDIA', 'driver_version': '331.79', 'gl_extensions': 'GL_AMD_multi_draw_indirect GL_ARB_arrays_of_arra..._depth_texture GL_SGIX_shadow GL_SUN_slice_accum ', ...}, 'devices': [{'device_id': 3576.0, 'device_string': '', 'vendor_id': 4318.0, 'vendor_string': ''}], 'driver_bug_workarounds': ['clear_uniforms_before_first_program_use', 'disable_gl_path_rendering', 'init_gl_position_in_vertex_shader', 'init_vertex_attributes', 'remove_pow_with_constant_exponent', 'scalarize_vec_and_mat_constructor_args', 'use_current_program_after_successful_link', 'use_virtualized_gl_contexts'], 'feature_status': {'2d_canvas': 'unavailable_software', 'flash_3d': 'enabled', 'flash_stage3d': 'enabled', 'flash_stage3d_baseline': 'enabled', 'gpu_compositing': 'enabled', 'multiple_raster_threads': 'enabled_on', 'rasterization': 'disabled_software', 'video_decode': 'unavailable_software', 'video_encode': 'enabled', 'webgl': 'enabled'}}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.internal.html b/catapult/telemetry/docs/pydoc/telemetry.testing.internal.html
deleted file mode 100644
index df23179..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.internal.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.testing.internal</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.internal</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/internal/__init__.py">telemetry/testing/internal/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.testing.internal.fake_gpu_info.html">fake_gpu_info</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.options_for_unittests.html b/catapult/telemetry/docs/pydoc/telemetry.testing.options_for_unittests.html
deleted file mode 100644
index f07a4df..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.options_for_unittests.html
+++ /dev/null
@@ -1,32 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.options_for_unittests</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.options_for_unittests</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/options_for_unittests.py">telemetry/testing/options_for_unittests.py</a></font></td></tr></table>
-    <p><tt>This&nbsp;module&nbsp;provides&nbsp;the&nbsp;global&nbsp;variable&nbsp;options_for_unittests.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;set&nbsp;to&nbsp;a&nbsp;BrowserOptions&nbsp;object&nbsp;by&nbsp;the&nbsp;test&nbsp;harness,&nbsp;or&nbsp;None<br>
-if&nbsp;unit&nbsp;tests&nbsp;are&nbsp;not&nbsp;running.<br>
-&nbsp;<br>
-This&nbsp;allows&nbsp;multiple&nbsp;unit&nbsp;tests&nbsp;to&nbsp;use&nbsp;a&nbsp;specific<br>
-browser,&nbsp;in&nbsp;face&nbsp;of&nbsp;multiple&nbsp;options.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AreSet"><strong>AreSet</strong></a>()</dt></dl>
- <dl><dt><a name="-GetCopy"><strong>GetCopy</strong></a>()</dt></dl>
- <dl><dt><a name="-Pop"><strong>Pop</strong></a>()</dt></dl>
- <dl><dt><a name="-Push"><strong>Push</strong></a>(options)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.page_test_test_case.html b/catapult/telemetry/docs/pydoc/telemetry.testing.page_test_test_case.html
deleted file mode 100644
index 6cad5ca..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.page_test_test_case.html
+++ /dev/null
@@ -1,490 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.page_test_test_case</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.page_test_test_case</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/page_test_test_case.py">telemetry/testing/page_test_test_case.py</a></font></td></tr></table>
-    <p><tt>Provide&nbsp;a&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;base&nbsp;class&nbsp;for&nbsp;PageTest&nbsp;subclasses'&nbsp;unittests.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.benchmark.html">telemetry.benchmark</a><br>
-<a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-<a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-</td><td width="25%" valign=top><a href="telemetry.page.page.html">telemetry.page.page</a><br>
-<a href="telemetry.page.page_test.html">telemetry.page.page_test</a><br>
-<a href="telemetry.internal.results.results_options.html">telemetry.internal.results.results_options</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.html">telemetry.story</a><br>
-<a href="telemetry.internal.story_runner.html">telemetry.internal.story_runner</a><br>
-<a href="unittest.html">unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.benchmark.html#BenchmarkMetadata">telemetry.benchmark.BenchmarkMetadata</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.page_test_test_case.html#EmptyMetadataForTest">EmptyMetadataForTest</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.page.html#Page">telemetry.page.Page</a>(<a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.page_test_test_case.html#BasicTestPage">BasicTestPage</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="unittest.case.html#TestCase">unittest.case.TestCase</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.page_test_test_case.html#PageTestTestCase">PageTestTestCase</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BasicTestPage">class <strong>BasicTestPage</strong></a>(<a href="telemetry.page.html#Page">telemetry.page.Page</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.page_test_test_case.html#BasicTestPage">BasicTestPage</a></dd>
-<dd><a href="telemetry.page.html#Page">telemetry.page.Page</a></dd>
-<dd><a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="BasicTestPage-RunPageInteractions"><strong>RunPageInteractions</strong></a>(self, action_runner)</dt></dl>
-
-<dl><dt><a name="BasicTestPage-__init__"><strong>__init__</strong></a>(self, url, story_set, base_dir)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.page.html#Page">telemetry.page.Page</a>:<br>
-<dl><dt><a name="BasicTestPage-AddCustomizeBrowserOptions"><strong>AddCustomizeBrowserOptions</strong></a>(self, options)</dt><dd><tt>Inherit&nbsp;page&nbsp;overrides&nbsp;this&nbsp;to&nbsp;add&nbsp;customized&nbsp;browser&nbsp;options.</tt></dd></dl>
-
-<dl><dt><a name="BasicTestPage-AsDict"><strong>AsDict</strong></a>(self)</dt><dd><tt>Converts&nbsp;a&nbsp;page&nbsp;object&nbsp;to&nbsp;a&nbsp;dict&nbsp;suitable&nbsp;for&nbsp;JSON&nbsp;output.</tt></dd></dl>
-
-<dl><dt><a name="BasicTestPage-GetSyntheticDelayCategories"><strong>GetSyntheticDelayCategories</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="BasicTestPage-Run"><strong>Run</strong></a>(self, shared_state)</dt></dl>
-
-<dl><dt><a name="BasicTestPage-RunNavigateSteps"><strong>RunNavigateSteps</strong></a>(self, action_runner)</dt></dl>
-
-<dl><dt><a name="BasicTestPage-__cmp__"><strong>__cmp__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="BasicTestPage-__lt__"><strong>__lt__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="BasicTestPage-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.html#Page">telemetry.page.Page</a>:<br>
-<dl><dt><strong>base_dir</strong></dt>
-</dl>
-<dl><dt><strong>credentials_path</strong></dt>
-</dl>
-<dl><dt><strong>display_name</strong></dt>
-</dl>
-<dl><dt><strong>file_path</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;path&nbsp;of&nbsp;the&nbsp;file,&nbsp;stripping&nbsp;the&nbsp;scheme&nbsp;and&nbsp;query&nbsp;string.</tt></dd>
-</dl>
-<dl><dt><strong>file_path_url</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;file&nbsp;path,&nbsp;including&nbsp;the&nbsp;params,&nbsp;query,&nbsp;and&nbsp;fragment.</tt></dd>
-</dl>
-<dl><dt><strong>file_path_url_with_scheme</strong></dt>
-</dl>
-<dl><dt><strong>is_file</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;URL&nbsp;points&nbsp;to&nbsp;a&nbsp;file.</tt></dd>
-</dl>
-<dl><dt><strong>page_set</strong></dt>
-</dl>
-<dl><dt><strong>serving_dir</strong></dt>
-</dl>
-<dl><dt><strong>startup_url</strong></dt>
-</dl>
-<dl><dt><strong>story_set</strong></dt>
-</dl>
-<dl><dt><strong>url</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.story.story.html#Story">telemetry.story.story.Story</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>file_safe_name</strong></dt>
-<dd><tt>A&nbsp;version&nbsp;of&nbsp;display_name&nbsp;that's&nbsp;safe&nbsp;to&nbsp;use&nbsp;as&nbsp;a&nbsp;filename.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;sanitizes&nbsp;special&nbsp;characters&nbsp;with&nbsp;underscores,<br>
-but&nbsp;it's&nbsp;okay&nbsp;to&nbsp;override&nbsp;it&nbsp;with&nbsp;a&nbsp;more&nbsp;specific&nbsp;implementation&nbsp;in<br>
-subclasses.</tt></dd>
-</dl>
-<dl><dt><strong>id</strong></dt>
-</dl>
-<dl><dt><strong>is_local</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;iff&nbsp;this&nbsp;story&nbsp;does&nbsp;not&nbsp;require&nbsp;network.</tt></dd>
-</dl>
-<dl><dt><strong>labels</strong></dt>
-</dl>
-<dl><dt><strong>make_javascript_deterministic</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>shared_state_class</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="EmptyMetadataForTest">class <strong>EmptyMetadataForTest</strong></a>(<a href="telemetry.benchmark.html#BenchmarkMetadata">telemetry.benchmark.BenchmarkMetadata</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.page_test_test_case.html#EmptyMetadataForTest">EmptyMetadataForTest</a></dd>
-<dd><a href="telemetry.benchmark.html#BenchmarkMetadata">telemetry.benchmark.BenchmarkMetadata</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="EmptyMetadataForTest-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.benchmark.html#BenchmarkMetadata">telemetry.benchmark.BenchmarkMetadata</a>:<br>
-<dl><dt><a name="EmptyMetadataForTest-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.benchmark.html#BenchmarkMetadata">telemetry.benchmark.BenchmarkMetadata</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>description</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>rerun_options</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PageTestTestCase">class <strong>PageTestTestCase</strong></a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;base&nbsp;class&nbsp;to&nbsp;simplify&nbsp;writing&nbsp;unit&nbsp;tests&nbsp;for&nbsp;PageTest&nbsp;subclasses.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.page_test_test_case.html#PageTestTestCase">PageTestTestCase</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="PageTestTestCase-CreateEmptyPageSet"><strong>CreateEmptyPageSet</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-CreateStorySetFromFileInUnittestDataDir"><strong>CreateStorySetFromFileInUnittestDataDir</strong></a>(self, test_filename)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-RunMeasurement"><strong>RunMeasurement</strong></a>(self, measurement, ps, options<font color="#909090">=None</font>)</dt><dd><tt>Runs&nbsp;a&nbsp;measurement&nbsp;against&nbsp;a&nbsp;pageset,&nbsp;returning&nbsp;the&nbsp;rows&nbsp;its&nbsp;outputs.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-TestTracingCleanedUp"><strong>TestTracingCleanedUp</strong></a>(self, measurement_class, options<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="PageTestTestCase-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-__init__"><strong>__init__</strong></a>(self, methodName<font color="#909090">='runTest'</font>)</dt><dd><tt>Create&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;class&nbsp;that&nbsp;will&nbsp;use&nbsp;the&nbsp;named&nbsp;test<br>
-method&nbsp;when&nbsp;executed.&nbsp;Raises&nbsp;a&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;instance&nbsp;does<br>
-not&nbsp;have&nbsp;a&nbsp;method&nbsp;with&nbsp;the&nbsp;specified&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#PageTestTestCase-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#PageTestTestCase-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#PageTestTestCase-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#PageTestTestCase-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#PageTestTestCase-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#PageTestTestCase-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="PageTestTestCase-setUp"><strong>setUp</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;the&nbsp;test&nbsp;fixture&nbsp;before&nbsp;exercising&nbsp;it.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="PageTestTestCase-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;class&nbsp;fixture&nbsp;before&nbsp;running&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<dl><dt><a name="PageTestTestCase-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;class&nbsp;fixture&nbsp;after&nbsp;running&nbsp;all&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.progress_reporter.html b/catapult/telemetry/docs/pydoc/telemetry.testing.progress_reporter.html
deleted file mode 100644
index 8f92ace..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.progress_reporter.html
+++ /dev/null
@@ -1,229 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.progress_reporter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.progress_reporter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/progress_reporter.py">telemetry/testing/progress_reporter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.path.html">telemetry.internal.util.path</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="unittest.html">unittest</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.progress_reporter.html#ProgressReporter">ProgressReporter</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.progress_reporter.html#TestRunner">TestRunner</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="unittest.result.html#TestResult">unittest.result.TestResult</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.progress_reporter.html#TestResult">TestResult</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="unittest.suite.html#TestSuite">unittest.suite.TestSuite</a>(<a href="unittest.suite.html#BaseTestSuite">unittest.suite.BaseTestSuite</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.progress_reporter.html#TestSuite">TestSuite</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProgressReporter">class <strong>ProgressReporter</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ProgressReporter-Error"><strong>Error</strong></a>(self, test, err)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-Failure"><strong>Failure</strong></a>(self, test, err)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-Skip"><strong>Skip</strong></a>(self, test, reason)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-StartTest"><strong>StartTest</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-StartTestRun"><strong>StartTestRun</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-StartTestSuite"><strong>StartTestSuite</strong></a>(self, suite)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-StopTest"><strong>StopTest</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-StopTestRun"><strong>StopTestRun</strong></a>(self, result)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-StopTestSuite"><strong>StopTestSuite</strong></a>(self, suite)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-Success"><strong>Success</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="ProgressReporter-__init__"><strong>__init__</strong></a>(self, output_stream)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TestResult">class <strong>TestResult</strong></a>(<a href="unittest.result.html#TestResult">unittest.result.TestResult</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.progress_reporter.html#TestResult">TestResult</a></dd>
-<dd><a href="unittest.result.html#TestResult">unittest.result.TestResult</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TestResult-__init__"><strong>__init__</strong></a>(self, progress_reporters)</dt></dl>
-
-<dl><dt><a name="TestResult-addError"><strong>addError</strong></a>(self, test, err)</dt></dl>
-
-<dl><dt><a name="TestResult-addFailure"><strong>addFailure</strong></a>(self, test, err)</dt></dl>
-
-<dl><dt><a name="TestResult-addSkip"><strong>addSkip</strong></a>(self, test, reason)</dt></dl>
-
-<dl><dt><a name="TestResult-addSuccess"><strong>addSuccess</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="TestResult-startTest"><strong>startTest</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="TestResult-startTestRun"><strong>startTestRun</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestResult-startTestSuite"><strong>startTestSuite</strong></a>(self, suite)</dt></dl>
-
-<dl><dt><a name="TestResult-stopTest"><strong>stopTest</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="TestResult-stopTestRun"><strong>stopTestRun</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestResult-stopTestSuite"><strong>stopTestSuite</strong></a>(self, suite)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>failures_and_errors</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="unittest.result.html#TestResult">unittest.result.TestResult</a>:<br>
-<dl><dt><a name="TestResult-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestResult-addExpectedFailure"><strong>addExpectedFailure</strong></a>(self, test, err)</dt><dd><tt>Called&nbsp;when&nbsp;an&nbsp;expected&nbsp;failure/error&nbsp;occured.</tt></dd></dl>
-
-<dl><dt><a name="TestResult-addUnexpectedSuccess"><strong>addUnexpectedSuccess</strong></a>(self, *args, **kw)</dt><dd><tt>Called&nbsp;when&nbsp;a&nbsp;test&nbsp;was&nbsp;expected&nbsp;to&nbsp;fail,&nbsp;but&nbsp;succeed.</tt></dd></dl>
-
-<dl><dt><a name="TestResult-printErrors"><strong>printErrors</strong></a>(self)</dt><dd><tt>Called&nbsp;by&nbsp;<a href="#TestRunner">TestRunner</a>&nbsp;after&nbsp;test&nbsp;run</tt></dd></dl>
-
-<dl><dt><a name="TestResult-stop"><strong>stop</strong></a>(self)</dt><dd><tt>Indicates&nbsp;that&nbsp;the&nbsp;tests&nbsp;should&nbsp;be&nbsp;aborted</tt></dd></dl>
-
-<dl><dt><a name="TestResult-wasSuccessful"><strong>wasSuccessful</strong></a>(self)</dt><dd><tt>Tells&nbsp;whether&nbsp;or&nbsp;not&nbsp;this&nbsp;result&nbsp;was&nbsp;a&nbsp;success</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.result.html#TestResult">unittest.result.TestResult</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TestRunner">class <strong>TestRunner</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TestRunner-run"><strong>run</strong></a>(self, test, progress_reporters, repeat_count, args)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TestSuite">class <strong>TestSuite</strong></a>(<a href="unittest.suite.html#TestSuite">unittest.suite.TestSuite</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#TestSuite">TestSuite</a>&nbsp;that&nbsp;can&nbsp;delegate&nbsp;start&nbsp;and&nbsp;stop&nbsp;calls&nbsp;to&nbsp;a&nbsp;<a href="#TestResult">TestResult</a>&nbsp;<a href="__builtin__.html#object">object</a>.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.progress_reporter.html#TestSuite">TestSuite</a></dd>
-<dd><a href="unittest.suite.html#TestSuite">unittest.suite.TestSuite</a></dd>
-<dd><a href="unittest.suite.html#BaseTestSuite">unittest.suite.BaseTestSuite</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TestSuite-run"><strong>run</strong></a>(self, result)</dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.suite.html#TestSuite">unittest.suite.TestSuite</a>:<br>
-<dl><dt><a name="TestSuite-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;tests&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;<a href="#TestResult">TestResult</a></tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="unittest.suite.html#BaseTestSuite">unittest.suite.BaseTestSuite</a>:<br>
-<dl><dt><a name="TestSuite-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="TestSuite-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="TestSuite-__init__"><strong>__init__</strong></a>(self, tests<font color="#909090">=()</font>)</dt></dl>
-
-<dl><dt><a name="TestSuite-__iter__"><strong>__iter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestSuite-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="TestSuite-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestSuite-addTest"><strong>addTest</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="TestSuite-addTests"><strong>addTests</strong></a>(self, tests)</dt></dl>
-
-<dl><dt><a name="TestSuite-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.suite.html#BaseTestSuite">unittest.suite.BaseTestSuite</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.suite.html#BaseTestSuite">unittest.suite.BaseTestSuite</a>:<br>
-<dl><dt><strong>__hash__</strong> = None</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.run_chromeos_tests.html b/catapult/telemetry/docs/pydoc/telemetry.testing.run_chromeos_tests.html
deleted file mode 100644
index ad96cd2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.run_chromeos_tests.html
+++ /dev/null
@@ -1,39 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.run_chromeos_tests</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.run_chromeos_tests</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/run_chromeos_tests.py">telemetry/testing/run_chromeos_tests.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.testing.run_tests.html">telemetry.testing.run_tests</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-RunChromeOSTests"><strong>RunChromeOSTests</strong></a>(browser_type, tests_to_run)</dt><dd><tt>Run&nbsp;ChromeOS&nbsp;tests.<br>
-Args:<br>
-&nbsp;&nbsp;|browser_type|:&nbsp;string&nbsp;specifies&nbsp;which&nbsp;browser&nbsp;type&nbsp;to&nbsp;use.<br>
-&nbsp;&nbsp;|tests_to_run|:&nbsp;a&nbsp;list&nbsp;of&nbsp;tuples&nbsp;(top_level_dir,&nbsp;unit_tests),&nbsp;whereas<br>
-&nbsp;&nbsp;&nbsp;&nbsp;|top_level_dir|&nbsp;specifies&nbsp;the&nbsp;top&nbsp;level&nbsp;directory&nbsp;for&nbsp;running&nbsp;tests,&nbsp;and<br>
-&nbsp;&nbsp;&nbsp;&nbsp;|unit_tests|&nbsp;is&nbsp;a&nbsp;list&nbsp;of&nbsp;string&nbsp;test&nbsp;names&nbsp;to&nbsp;run.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.run_tests.html b/catapult/telemetry/docs/pydoc/telemetry.testing.run_tests.html
deleted file mode 100644
index ab9085d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.run_tests.html
+++ /dev/null
@@ -1,112 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.run_tests</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.run_tests</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/run_tests.py">telemetry/testing/run_tests.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-<a href="telemetry.internal.browser.browser_finder.html">telemetry.internal.browser.browser_finder</a><br>
-<a href="telemetry.internal.browser.browser_finder_exceptions.html">telemetry.internal.browser.browser_finder_exceptions</a><br>
-<a href="telemetry.internal.browser.browser_options.html">telemetry.internal.browser.browser_options</a><br>
-</td><td width="25%" valign=top><a href="telemetry.testing.browser_test_case.html">telemetry.testing.browser_test_case</a><br>
-<a href="telemetry.internal.util.command_line.html">telemetry.internal.util.command_line</a><br>
-<a href="telemetry.decorators.html">telemetry.decorators</a><br>
-<a href="telemetry.internal.platform.device_finder.html">telemetry.internal.platform.device_finder</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.testing.options_for_unittests.html">telemetry.testing.options_for_unittests</a><br>
-<a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-<a href="telemetry.internal.util.ps_util.html">telemetry.internal.util.ps_util</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="typ.html">typ</a><br>
-<a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>(<a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.run_tests.html#RunTestsCommand">RunTestsCommand</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RunTestsCommand">class <strong>RunTestsCommand</strong></a>(<a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Run&nbsp;unit&nbsp;tests<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.run_tests.html#RunTestsCommand">RunTestsCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#OptparseCommand">telemetry.internal.util.command_line.OptparseCommand</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a></dd>
-<dd><a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="RunTestsCommand-Run"><strong>Run</strong></a>(self, args)</dt></dl>
-
-<dl><dt><a name="RunTestsCommand-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="RunTestsCommand-AddCommandLineArgs"><strong>AddCommandLineArgs</strong></a>(cls, parser, _)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="RunTestsCommand-CreateParser"><strong>CreateParser</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="RunTestsCommand-ProcessCommandLineArgs"><strong>ProcessCommandLineArgs</strong></a>(cls, parser, args, _)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="RunTestsCommand-main"><strong>main</strong></a>(cls, args<font color="#909090">=None</font>, stream<font color="#909090">=None</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>usage</strong> = '[test_name ...] [&lt;options&gt;]'</dl>
-
-<hr>
-Class methods inherited from <a href="telemetry.internal.util.command_line.html#Command">telemetry.internal.util.command_line.Command</a>:<br>
-<dl><dt><a name="RunTestsCommand-Description"><strong>Description</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="RunTestsCommand-Name"><strong>Name</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.util.command_line.html#ArgumentHandlerMixIn">telemetry.internal.util.command_line.ArgumentHandlerMixIn</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetClassifier"><strong>GetClassifier</strong></a>(args, possible_browser)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.simple_mock.html b/catapult/telemetry/docs/pydoc/telemetry.testing.simple_mock.html
deleted file mode 100644
index e3a991f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.simple_mock.html
+++ /dev/null
@@ -1,142 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.simple_mock</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.simple_mock</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/simple_mock.py">telemetry/testing/simple_mock.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;very&nbsp;very&nbsp;simple&nbsp;mock&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;harness.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.simple_mock.html#MockFunctionCall">MockFunctionCall</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.simple_mock.html#MockObject">MockObject</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.simple_mock.html#MockTimer">MockTimer</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.simple_mock.html#MockTrace">MockTrace</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MockFunctionCall">class <strong>MockFunctionCall</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MockFunctionCall-VerifyEquals"><strong>VerifyEquals</strong></a>(self, got)</dt></dl>
-
-<dl><dt><a name="MockFunctionCall-WhenCalled"><strong>WhenCalled</strong></a>(self, handler)</dt></dl>
-
-<dl><dt><a name="MockFunctionCall-WillReturn"><strong>WillReturn</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="MockFunctionCall-WithArgs"><strong>WithArgs</strong></a>(self, *args)</dt></dl>
-
-<dl><dt><a name="MockFunctionCall-__init__"><strong>__init__</strong></a>(self, name)</dt></dl>
-
-<dl><dt><a name="MockFunctionCall-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MockObject">class <strong>MockObject</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MockObject-ExpectCall"><strong>ExpectCall</strong></a>(self, func_name, *args)</dt></dl>
-
-<dl><dt><a name="MockObject-SetAttribute"><strong>SetAttribute</strong></a>(self, name, value)</dt></dl>
-
-<dl><dt><a name="MockObject-__init__"><strong>__init__</strong></a>(self, parent_mock<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="MockObject-__setattr__"><strong>__setattr__</strong></a>(self, name, value)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MockTimer">class <strong>MockTimer</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;mock&nbsp;timer&nbsp;to&nbsp;fake&nbsp;out&nbsp;the&nbsp;timing&nbsp;for&nbsp;a&nbsp;module.<br>
-Args:<br>
-&nbsp;&nbsp;module:&nbsp;module&nbsp;to&nbsp;fake&nbsp;out&nbsp;the&nbsp;time<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MockTimer-Restore"><strong>Restore</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MockTimer-SetTime"><strong>SetTime</strong></a>(self, time)</dt></dl>
-
-<dl><dt><a name="MockTimer-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MockTimer-__init__"><strong>__init__</strong></a>(self, module<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="MockTimer-sleep"><strong>sleep</strong></a>(self, time)</dt></dl>
-
-<dl><dt><a name="MockTimer-time"><strong>time</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MockTrace">class <strong>MockTrace</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MockTrace-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DONT_CARE</strong> = ''</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.story_set_smoke_test.html b/catapult/telemetry/docs/pydoc/telemetry.testing.story_set_smoke_test.html
deleted file mode 100644
index 22dd8ef..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.story_set_smoke_test.html
+++ /dev/null
@@ -1,360 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.story_set_smoke_test</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.story_set_smoke_test</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/story_set_smoke_test.py">telemetry/testing/story_set_smoke_test.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.wpr.archive_info.html">telemetry.wpr.archive_info</a><br>
-<a href="telemetry.internal.browser.browser_credentials.html">telemetry.internal.browser.browser_credentials</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.discover.html">telemetry.core.discover</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="os.html">os</a><br>
-<a href="telemetry.page.html">telemetry.page</a><br>
-</td><td width="25%" valign=top><a href="telemetry.story.html">telemetry.story</a><br>
-<a href="unittest.html">unittest</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="unittest.case.html#TestCase">unittest.case.TestCase</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.story_set_smoke_test.html#StorySetSmokeTest">StorySetSmokeTest</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StorySetSmokeTest">class <strong>StorySetSmokeTest</strong></a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.story_set_smoke_test.html#StorySetSmokeTest">StorySetSmokeTest</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="StorySetSmokeTest-CheckArchive"><strong>CheckArchive</strong></a>(self, story_set)</dt><dd><tt>Verify&nbsp;that&nbsp;all&nbsp;URLs&nbsp;of&nbsp;pages&nbsp;in&nbsp;story_set&nbsp;have&nbsp;an&nbsp;associated&nbsp;archive.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-CheckAttributes"><strong>CheckAttributes</strong></a>(self, story_set)</dt><dd><tt>Verify&nbsp;that&nbsp;story_set&nbsp;and&nbsp;its&nbsp;stories&nbsp;base&nbsp;attributes&nbsp;have&nbsp;the&nbsp;right<br>
-types.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-CheckAttributesOfStoryBasicAttributes"><strong>CheckAttributesOfStoryBasicAttributes</strong></a>(self, story)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-CheckAttributesOfStorySetBasicAttributes"><strong>CheckAttributesOfStorySetBasicAttributes</strong></a>(self, story_set)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-CheckCredentials"><strong>CheckCredentials</strong></a>(self, story_set)</dt><dd><tt>Verify&nbsp;that&nbsp;all&nbsp;pages&nbsp;in&nbsp;story_set&nbsp;use&nbsp;proper&nbsp;credentials</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-CheckSharedStates"><strong>CheckSharedStates</strong></a>(self, story_set)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-GetAllStorySetClasses"><strong>GetAllStorySetClasses</strong></a>(self, story_sets_dir, top_level_dir)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-RunSmokeTest"><strong>RunSmokeTest</strong></a>(self, story_sets_dir, top_level_dir)</dt><dd><tt>Run&nbsp;smoke&nbsp;test&nbsp;on&nbsp;all&nbsp;story&nbsp;sets&nbsp;in&nbsp;story_sets_dir.<br>
-&nbsp;<br>
-Subclass&nbsp;of&nbsp;<a href="#StorySetSmokeTest">StorySetSmokeTest</a>&nbsp;is&nbsp;supposed&nbsp;to&nbsp;call&nbsp;this&nbsp;in&nbsp;some&nbsp;test<br>
-method&nbsp;to&nbsp;run&nbsp;smoke&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-setUp"><strong>setUp</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="StorySetSmokeTest-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-__init__"><strong>__init__</strong></a>(self, methodName<font color="#909090">='runTest'</font>)</dt><dd><tt>Create&nbsp;an&nbsp;instance&nbsp;of&nbsp;the&nbsp;class&nbsp;that&nbsp;will&nbsp;use&nbsp;the&nbsp;named&nbsp;test<br>
-method&nbsp;when&nbsp;executed.&nbsp;Raises&nbsp;a&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;instance&nbsp;does<br>
-not&nbsp;have&nbsp;a&nbsp;method&nbsp;with&nbsp;the&nbsp;specified&nbsp;name.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;<a href="unittest.case.html#TestCase">TestCase</a>&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#StorySetSmokeTest-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#StorySetSmokeTest-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#StorySetSmokeTest-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#StorySetSmokeTest-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#StorySetSmokeTest-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#StorySetSmokeTest-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="StorySetSmokeTest-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Class methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="StorySetSmokeTest-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;setting&nbsp;up&nbsp;class&nbsp;fixture&nbsp;before&nbsp;running&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<dl><dt><a name="StorySetSmokeTest-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;class&nbsp;fixture&nbsp;after&nbsp;running&nbsp;all&nbsp;tests&nbsp;in&nbsp;the&nbsp;class.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.stream.html b/catapult/telemetry/docs/pydoc/telemetry.testing.stream.html
deleted file mode 100644
index c0fc4a0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.stream.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.stream</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.stream</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/stream.py">telemetry/testing/stream.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.stream.html#TestOutputStream">TestOutputStream</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TestOutputStream">class <strong>TestOutputStream</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TestOutputStream-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestOutputStream-flush"><strong>flush</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestOutputStream-write"><strong>write</strong></a>(self, data)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>output_data</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.system_stub.html b/catapult/telemetry/docs/pydoc/telemetry.testing.system_stub.html
deleted file mode 100644
index c6c9055..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.system_stub.html
+++ /dev/null
@@ -1,446 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.system_stub</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.system_stub</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/system_stub.py">telemetry/testing/system_stub.py</a></font></td></tr></table>
-    <p><tt>Provides&nbsp;stubs&nbsp;for&nbsp;os,&nbsp;sys&nbsp;and&nbsp;subprocess&nbsp;for&nbsp;testing<br>
-&nbsp;<br>
-This&nbsp;test&nbsp;allows&nbsp;one&nbsp;to&nbsp;test&nbsp;code&nbsp;that&nbsp;itself&nbsp;uses&nbsp;os,&nbsp;sys,&nbsp;and&nbsp;subprocess.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="ntpath.html">ntpath</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="posixpath.html">posixpath</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="shlex.html">shlex</a><br>
-<a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#AdbDevice">AdbDevice</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#AdbInstallCertStub">AdbInstallCertStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#CertUtilsStub">CertUtilsStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#CloudStorageModuleStub">CloudStorageModuleStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#LoggingStub">LoggingStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#OpenFunctionStub">OpenFunctionStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#OsModuleStub">OsModuleStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#Override">Override</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#PerfControlModuleStub">PerfControlModuleStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#PlatformSettingsStub">PlatformSettingsStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#RawInputFunctionStub">RawInputFunctionStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#SubprocessModuleStub">SubprocessModuleStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#SysModuleStub">SysModuleStub</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.testing.system_stub.html#ThermalThrottleModuleStub">ThermalThrottleModuleStub</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AdbDevice">class <strong>AdbDevice</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="AdbDevice-FileExists"><strong>FileExists</strong></a>(self, _)</dt></dl>
-
-<dl><dt><a name="AdbDevice-GetProp"><strong>GetProp</strong></a>(self, property_name)</dt></dl>
-
-<dl><dt><a name="AdbDevice-HasRoot"><strong>HasRoot</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AdbDevice-NeedsSU"><strong>NeedsSU</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AdbDevice-ReadFile"><strong>ReadFile</strong></a>(self, device_path, as_root<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="AdbDevice-RunShellCommand"><strong>RunShellCommand</strong></a>(self, args, **_kwargs)</dt></dl>
-
-<dl><dt><a name="AdbDevice-SetProp"><strong>SetProp</strong></a>(self, property_name, property_value)</dt></dl>
-
-<dl><dt><a name="AdbDevice-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AdbInstallCertStub">class <strong>AdbInstallCertStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>AndroidCertInstaller</strong> = &lt;class 'telemetry.testing.system_stub.AndroidCertInstaller'&gt;</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CertUtilsStub">class <strong>CertUtilsStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Static methods defined here:<br>
-<dl><dt><a name="CertUtilsStub-generate_dummy_ca_cert"><strong>generate_dummy_ca_cert</strong></a>()</dt></dl>
-
-<dl><dt><a name="CertUtilsStub-write_dummy_ca_cert"><strong>write_dummy_ca_cert</strong></a>(_ca_cert_str, _key_str, cert_path)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>openssl_import_error</strong> = None</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CloudStorageModuleStub">class <strong>CloudStorageModuleStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="CloudStorageModuleStub-CalculateHash"><strong>CalculateHash</strong></a>(self, file_path)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-ChangeRemoteHashForTesting"><strong>ChangeRemoteHashForTesting</strong></a>(self, bucket, remote_path, new_hash)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-CheckPermissionLevelForBucket"><strong>CheckPermissionLevelForBucket</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-Exists"><strong>Exists</strong></a>(self, bucket, remote_path)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-Get"><strong>Get</strong></a>(self, bucket, remote_path, local_path)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-GetFilesInDirectoryIfChanged"><strong>GetFilesInDirectoryIfChanged</strong></a>(self, directory, bucket)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-GetHelper"><strong>GetHelper</strong></a>(self, bucket, remote_path, local_path, only_if_changed)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-GetIfChanged"><strong>GetIfChanged</strong></a>(self, local_path, bucket<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-GetLocalDataFiles"><strong>GetLocalDataFiles</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-GetLocalHashFiles"><strong>GetLocalHashFiles</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-GetRemotePathsForTesting"><strong>GetRemotePathsForTesting</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-Insert"><strong>Insert</strong></a>(self, bucket, remote_path, local_path)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-List"><strong>List</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-ReadHash"><strong>ReadHash</strong></a>(self, hash_path)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-SetCalculatedHashesForTesting"><strong>SetCalculatedHashesForTesting</strong></a>(self, calculated_hash_dictionary)</dt><dd><tt>#&nbsp;Set&nbsp;a&nbsp;dictionary&nbsp;of&nbsp;data&nbsp;files&nbsp;and&nbsp;their&nbsp;"calculated"&nbsp;hashes.</tt></dd></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-SetHashFileContentsForTesting"><strong>SetHashFileContentsForTesting</strong></a>(self, hash_file_dictionary)</dt><dd><tt>#&nbsp;Set&nbsp;a&nbsp;dictionary&nbsp;of&nbsp;hash&nbsp;files&nbsp;and&nbsp;the&nbsp;hashes&nbsp;they&nbsp;should&nbsp;contain.</tt></dd></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-SetPermissionLevelForTesting"><strong>SetPermissionLevelForTesting</strong></a>(self, permission_level)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-SetRemotePathsForTesting"><strong>SetRemotePathsForTesting</strong></a>(self, remote_path_dict<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="CloudStorageModuleStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>BUCKET_ALIASES</strong> = {'internal': 'chrome-telemetry', 'partner': 'chrome-partner-telemetry', 'public': 'chromium-telemetry'}</dl>
-
-<dl><dt><strong>CREDENTIALS_ERROR_PERMISSION</strong> = -1</dl>
-
-<dl><dt><strong>CloudStorageError</strong> = &lt;class 'telemetry.testing.system_stub.CloudStorageError'&gt;</dl>
-
-<dl><dt><strong>CredentialsError</strong> = &lt;class 'telemetry.testing.system_stub.CredentialsError'&gt;</dl>
-
-<dl><dt><strong>INTERNAL_BUCKET</strong> = 'chrome-telemetry'</dl>
-
-<dl><dt><strong>INTERNAL_PERMISSION</strong> = 2</dl>
-
-<dl><dt><strong>NotFoundError</strong> = &lt;class 'telemetry.testing.system_stub.NotFoundError'&gt;</dl>
-
-<dl><dt><strong>PARTNER_BUCKET</strong> = 'chrome-partner-telemetry'</dl>
-
-<dl><dt><strong>PARTNER_PERMISSION</strong> = 1</dl>
-
-<dl><dt><strong>PUBLIC_BUCKET</strong> = 'chromium-telemetry'</dl>
-
-<dl><dt><strong>PUBLIC_PERMISSION</strong> = 0</dl>
-
-<dl><dt><strong>PermissionError</strong> = &lt;class 'telemetry.testing.system_stub.PermissionError'&gt;</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LoggingStub">class <strong>LoggingStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="LoggingStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="LoggingStub-error"><strong>error</strong></a>(self, msg, *args)</dt></dl>
-
-<dl><dt><a name="LoggingStub-info"><strong>info</strong></a>(self, msg, *args)</dt></dl>
-
-<dl><dt><a name="LoggingStub-warn"><strong>warn</strong></a>(self, msg, *args)</dt></dl>
-
-<dl><dt><a name="LoggingStub-warning"><strong>warning</strong></a>(self, msg, *args)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="OpenFunctionStub">class <strong>OpenFunctionStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="OpenFunctionStub-__call__"><strong>__call__</strong></a>(self, name, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="OpenFunctionStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>FileStub</strong> = &lt;class 'telemetry.testing.system_stub.FileStub'&gt;</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="OsModuleStub">class <strong>OsModuleStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="OsModuleStub-__init__"><strong>__init__</strong></a>(self, sys_module<font color="#909090">=&lt;module 'sys' (built-in)&gt;</font>)</dt></dl>
-
-<dl><dt><a name="OsModuleStub-access"><strong>access</strong></a>(self, path, _)</dt></dl>
-
-<dl><dt><a name="OsModuleStub-chdir"><strong>chdir</strong></a>(self, path)</dt></dl>
-
-<dl><dt><a name="OsModuleStub-getenv"><strong>getenv</strong></a>(self, name, value<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="OsModuleStub-walk"><strong>walk</strong></a>(self, top)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>OsEnvironModuleStub</strong> = &lt;class 'telemetry.testing.system_stub.OsEnvironModuleStub'&gt;</dl>
-
-<dl><dt><strong>OsPathModuleStub</strong> = &lt;class 'telemetry.testing.system_stub.OsPathModuleStub'&gt;</dl>
-
-<dl><dt><strong>X_OK</strong> = 1</dl>
-
-<dl><dt><strong>pathsep</strong> = ':'</dl>
-
-<dl><dt><strong>sep</strong> = '/'</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Override">class <strong>Override</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Override-Restore"><strong>Restore</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Override-__del__"><strong>__del__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Override-__init__"><strong>__init__</strong></a>(self, base_module, module_list)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PerfControlModuleStub">class <strong>PerfControlModuleStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="PerfControlModuleStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>PerfControlStub</strong> = &lt;class 'telemetry.testing.system_stub.PerfControlStub'&gt;</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="PlatformSettingsStub">class <strong>PlatformSettingsStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Static methods defined here:<br>
-<dl><dt><a name="PlatformSettingsStub-HasSniSupport"><strong>HasSniSupport</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RawInputFunctionStub">class <strong>RawInputFunctionStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="RawInputFunctionStub-__call__"><strong>__call__</strong></a>(self, name, *args, **kwargs)</dt></dl>
-
-<dl><dt><a name="RawInputFunctionStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SubprocessModuleStub">class <strong>SubprocessModuleStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="SubprocessModuleStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SubprocessModuleStub-call"><strong>call</strong></a>(self, *args, **kwargs)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>PopenStub</strong> = &lt;class 'telemetry.testing.system_stub.PopenStub'&gt;</dl>
-
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SysModuleStub">class <strong>SysModuleStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="SysModuleStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ThermalThrottleModuleStub">class <strong>ThermalThrottleModuleStub</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ThermalThrottleModuleStub-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>ThermalThrottleStub</strong> = &lt;class 'telemetry.testing.system_stub.ThermalThrottleStub'&gt;</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.tab_test_case.html b/catapult/telemetry/docs/pydoc/telemetry.testing.tab_test_case.html
deleted file mode 100644
index b649ee2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.tab_test_case.html
+++ /dev/null
@@ -1,345 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.tab_test_case</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.tab_test_case</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/tab_test_case.py">telemetry/testing/tab_test_case.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.testing.browser_test_case.html">telemetry.testing.browser_test_case</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.browser_test_case.html#BrowserTestCase">telemetry.testing.browser_test_case.BrowserTestCase</a>(<a href="unittest.case.html#TestCase">unittest.case.TestCase</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.tab_test_case.html#TabTestCase">TabTestCase</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TabTestCase">class <strong>TabTestCase</strong></a>(<a href="telemetry.testing.browser_test_case.html#BrowserTestCase">telemetry.testing.browser_test_case.BrowserTestCase</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.tab_test_case.html#TabTestCase">TabTestCase</a></dd>
-<dd><a href="telemetry.testing.browser_test_case.html#BrowserTestCase">telemetry.testing.browser_test_case.BrowserTestCase</a></dd>
-<dd><a href="unittest.case.html#TestCase">unittest.case.TestCase</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TabTestCase-Navigate"><strong>Navigate</strong></a>(self, filename, script_to_evaluate_on_commit<font color="#909090">=None</font>)</dt><dd><tt>Navigates&nbsp;|tab|&nbsp;to&nbsp;|filename|&nbsp;in&nbsp;the&nbsp;unittest&nbsp;data&nbsp;directory.<br>
-&nbsp;<br>
-Also&nbsp;sets&nbsp;up&nbsp;http&nbsp;server&nbsp;to&nbsp;point&nbsp;to&nbsp;the&nbsp;unittest&nbsp;data&nbsp;directory.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-__init__"><strong>__init__</strong></a>(self, *args)</dt></dl>
-
-<dl><dt><a name="TabTestCase-setUp"><strong>setUp</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>tabs</strong></dt>
-</dl>
-<hr>
-Class methods inherited from <a href="telemetry.testing.browser_test_case.html#BrowserTestCase">telemetry.testing.browser_test_case.BrowserTestCase</a>:<br>
-<dl><dt><a name="TabTestCase-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(cls, options)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Override&nbsp;to&nbsp;add&nbsp;test-specific&nbsp;options&nbsp;to&nbsp;the&nbsp;BrowserOptions&nbsp;object</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-UrlOfUnittestFile"><strong>UrlOfUnittestFile</strong></a>(cls, filename)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TabTestCase-setUpClass"><strong>setUpClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TabTestCase-tearDownClass"><strong>tearDownClass</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Methods inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><a name="TabTestCase-__call__"><strong>__call__</strong></a>(self, *args, **kwds)</dt></dl>
-
-<dl><dt><a name="TabTestCase-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="TabTestCase-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabTestCase-__ne__"><strong>__ne__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="TabTestCase-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabTestCase-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabTestCase-addCleanup"><strong>addCleanup</strong></a>(self, function, *args, **kwargs)</dt><dd><tt>Add&nbsp;a&nbsp;function,&nbsp;with&nbsp;arguments,&nbsp;to&nbsp;be&nbsp;called&nbsp;when&nbsp;the&nbsp;test&nbsp;is<br>
-completed.&nbsp;Functions&nbsp;added&nbsp;are&nbsp;called&nbsp;on&nbsp;a&nbsp;LIFO&nbsp;basis&nbsp;and&nbsp;are<br>
-called&nbsp;after&nbsp;tearDown&nbsp;on&nbsp;test&nbsp;failure&nbsp;or&nbsp;success.<br>
-&nbsp;<br>
-Cleanup&nbsp;items&nbsp;are&nbsp;called&nbsp;even&nbsp;if&nbsp;setUp&nbsp;fails&nbsp;(unlike&nbsp;tearDown).</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-addTypeEqualityFunc"><strong>addTypeEqualityFunc</strong></a>(self, typeobj, function)</dt><dd><tt>Add&nbsp;a&nbsp;type&nbsp;specific&nbsp;assertEqual&nbsp;style&nbsp;function&nbsp;to&nbsp;compare&nbsp;a&nbsp;type.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;is&nbsp;for&nbsp;use&nbsp;by&nbsp;TestCase&nbsp;subclasses&nbsp;that&nbsp;need&nbsp;to&nbsp;register<br>
-their&nbsp;own&nbsp;type&nbsp;equality&nbsp;functions&nbsp;to&nbsp;provide&nbsp;nicer&nbsp;error&nbsp;messages.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;typeobj:&nbsp;The&nbsp;data&nbsp;type&nbsp;to&nbsp;call&nbsp;this&nbsp;function&nbsp;on&nbsp;when&nbsp;both&nbsp;values<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;are&nbsp;of&nbsp;the&nbsp;same&nbsp;type&nbsp;in&nbsp;<a href="#TabTestCase-assertEqual">assertEqual</a>().<br>
-&nbsp;&nbsp;&nbsp;&nbsp;function:&nbsp;The&nbsp;callable&nbsp;taking&nbsp;two&nbsp;arguments&nbsp;and&nbsp;an&nbsp;optional<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;msg=&nbsp;argument&nbsp;that&nbsp;raises&nbsp;self.<strong>failureException</strong>&nbsp;with&nbsp;a<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;useful&nbsp;error&nbsp;message&nbsp;when&nbsp;the&nbsp;two&nbsp;arguments&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertAlmostEqual"><strong>assertAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertAlmostEquals"><strong>assertAlmostEquals</strong></a> = assertAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;more&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;two&nbsp;objects&nbsp;compare&nbsp;equal&nbsp;then&nbsp;they&nbsp;will&nbsp;automatically<br>
-compare&nbsp;almost&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertDictContainsSubset"><strong>assertDictContainsSubset</strong></a>(self, expected, actual, msg<font color="#909090">=None</font>)</dt><dd><tt>Checks&nbsp;whether&nbsp;actual&nbsp;is&nbsp;a&nbsp;superset&nbsp;of&nbsp;expected.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertDictEqual"><strong>assertDictEqual</strong></a>(self, d1, d2, msg<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="TabTestCase-assertEqual"><strong>assertEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertEquals"><strong>assertEquals</strong></a> = assertEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;unequal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'=='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertFalse"><strong>assertFalse</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;false.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertGreater"><strong>assertGreater</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertGreaterEqual"><strong>assertGreaterEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;&gt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertIn"><strong>assertIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertIs"><strong>assertIs</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertIsInstance"><strong>assertIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(isinstance(obj,&nbsp;cls)),&nbsp;with&nbsp;a&nbsp;nicer<br>
-default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertIsNone"><strong>assertIsNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Same&nbsp;as&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(obj&nbsp;is&nbsp;None),&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertIsNot"><strong>assertIsNot</strong></a>(self, expr1, expr2, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;is&nbsp;not&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertIsNotNone"><strong>assertIsNotNone</strong></a>(self, obj, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsNone.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertItemsEqual"><strong>assertItemsEqual</strong></a>(self, expected_seq, actual_seq, msg<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;unordered&nbsp;sequence&nbsp;specific&nbsp;comparison.&nbsp;It&nbsp;asserts&nbsp;that<br>
-actual_seq&nbsp;and&nbsp;expected_seq&nbsp;have&nbsp;the&nbsp;same&nbsp;element&nbsp;counts.<br>
-Equivalent&nbsp;to::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#TabTestCase-assertEqual">assertEqual</a>(Counter(iter(actual_seq)),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Counter(iter(expected_seq)))<br>
-&nbsp;<br>
-Asserts&nbsp;that&nbsp;each&nbsp;element&nbsp;has&nbsp;the&nbsp;same&nbsp;count&nbsp;in&nbsp;both&nbsp;sequences.<br>
-Example:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;1,&nbsp;1]&nbsp;and&nbsp;[1,&nbsp;0,&nbsp;1]&nbsp;compare&nbsp;equal.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;[0,&nbsp;0,&nbsp;1]&nbsp;and&nbsp;[0,&nbsp;1]&nbsp;compare&nbsp;unequal.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertLess"><strong>assertLess</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertLessEqual"><strong>assertLessEqual</strong></a>(self, a, b, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;&lt;=&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertListEqual"><strong>assertListEqual</strong></a>(self, list1, list2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;list-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list1:&nbsp;The&nbsp;first&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;list2:&nbsp;The&nbsp;second&nbsp;list&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertMultiLineEqual"><strong>assertMultiLineEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Assert&nbsp;that&nbsp;two&nbsp;multi-line&nbsp;strings&nbsp;are&nbsp;equal.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotAlmostEqual"><strong>assertNotAlmostEqual</strong></a>(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotAlmostEquals"><strong>assertNotAlmostEquals</strong></a> = assertNotAlmostEqual(self, first, second, places<font color="#909090">=None</font>, msg<font color="#909090">=None</font>, delta<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;their<br>
-difference&nbsp;rounded&nbsp;to&nbsp;the&nbsp;given&nbsp;number&nbsp;of&nbsp;decimal&nbsp;places<br>
-(default&nbsp;7)&nbsp;and&nbsp;comparing&nbsp;to&nbsp;zero,&nbsp;or&nbsp;by&nbsp;comparing&nbsp;that&nbsp;the<br>
-between&nbsp;the&nbsp;two&nbsp;objects&nbsp;is&nbsp;less&nbsp;than&nbsp;the&nbsp;given&nbsp;delta.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;decimal&nbsp;places&nbsp;(from&nbsp;zero)&nbsp;are&nbsp;usually&nbsp;not&nbsp;the&nbsp;same<br>
-as&nbsp;significant&nbsp;digits&nbsp;(measured&nbsp;from&nbsp;the&nbsp;most&nbsp;signficant&nbsp;digit).<br>
-&nbsp;<br>
-Objects&nbsp;that&nbsp;are&nbsp;equal&nbsp;automatically&nbsp;fail.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotEqual"><strong>assertNotEqual</strong></a>(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotEquals"><strong>assertNotEquals</strong></a> = assertNotEqual(self, first, second, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;if&nbsp;the&nbsp;two&nbsp;objects&nbsp;are&nbsp;equal&nbsp;as&nbsp;determined&nbsp;by&nbsp;the&nbsp;'!='<br>
-operator.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotIn"><strong>assertNotIn</strong></a>(self, member, container, msg<font color="#909090">=None</font>)</dt><dd><tt>Just&nbsp;like&nbsp;<a href="#TabTestCase-assertTrue">assertTrue</a>(a&nbsp;not&nbsp;in&nbsp;b),&nbsp;but&nbsp;with&nbsp;a&nbsp;nicer&nbsp;default&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotIsInstance"><strong>assertNotIsInstance</strong></a>(self, obj, cls, msg<font color="#909090">=None</font>)</dt><dd><tt>Included&nbsp;for&nbsp;symmetry&nbsp;with&nbsp;assertIsInstance.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertNotRegexpMatches"><strong>assertNotRegexpMatches</strong></a>(self, text, unexpected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;if&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertRaises"><strong>assertRaises</strong></a>(self, excClass, callableObj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Fail&nbsp;unless&nbsp;an&nbsp;exception&nbsp;of&nbsp;class&nbsp;excClass&nbsp;is&nbsp;raised<br>
-by&nbsp;callableObj&nbsp;when&nbsp;invoked&nbsp;with&nbsp;arguments&nbsp;args&nbsp;and&nbsp;keyword<br>
-arguments&nbsp;kwargs.&nbsp;If&nbsp;a&nbsp;different&nbsp;type&nbsp;of&nbsp;exception&nbsp;is<br>
-raised,&nbsp;it&nbsp;will&nbsp;not&nbsp;be&nbsp;caught,&nbsp;and&nbsp;the&nbsp;test&nbsp;case&nbsp;will&nbsp;be<br>
-deemed&nbsp;to&nbsp;have&nbsp;suffered&nbsp;an&nbsp;error,&nbsp;exactly&nbsp;as&nbsp;for&nbsp;an<br>
-unexpected&nbsp;exception.<br>
-&nbsp;<br>
-If&nbsp;called&nbsp;with&nbsp;callableObj&nbsp;omitted&nbsp;or&nbsp;None,&nbsp;will&nbsp;return&nbsp;a<br>
-context&nbsp;object&nbsp;used&nbsp;like&nbsp;this::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#TabTestCase-assertRaises">assertRaises</a>(SomeException):<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;<br>
-The&nbsp;context&nbsp;manager&nbsp;keeps&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;exception&nbsp;as<br>
-the&nbsp;'exception'&nbsp;attribute.&nbsp;This&nbsp;allows&nbsp;you&nbsp;to&nbsp;inspect&nbsp;the<br>
-exception&nbsp;after&nbsp;the&nbsp;assertion::<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;<a href="#TabTestCase-assertRaises">assertRaises</a>(SomeException)&nbsp;as&nbsp;cm:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;do_something()<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the_exception&nbsp;=&nbsp;cm.exception<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#TabTestCase-assertEqual">assertEqual</a>(the_exception.error_code,&nbsp;3)</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertRaisesRegexp"><strong>assertRaisesRegexp</strong></a>(self, expected_exception, expected_regexp, callable_obj<font color="#909090">=None</font>, *args, **kwargs)</dt><dd><tt>Asserts&nbsp;that&nbsp;the&nbsp;message&nbsp;in&nbsp;a&nbsp;raised&nbsp;exception&nbsp;matches&nbsp;a&nbsp;regexp.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_exception:&nbsp;Exception&nbsp;class&nbsp;expected&nbsp;to&nbsp;be&nbsp;raised.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;expected_regexp:&nbsp;Regexp&nbsp;(re&nbsp;pattern&nbsp;object&nbsp;or&nbsp;string)&nbsp;expected<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;error&nbsp;message.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;callable_obj:&nbsp;Function&nbsp;to&nbsp;be&nbsp;called.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;args:&nbsp;Extra&nbsp;args.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;kwargs:&nbsp;Extra&nbsp;kwargs.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertRegexpMatches"><strong>assertRegexpMatches</strong></a>(self, text, expected_regexp, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;the&nbsp;test&nbsp;unless&nbsp;the&nbsp;text&nbsp;matches&nbsp;the&nbsp;regular&nbsp;expression.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertSequenceEqual"><strong>assertSequenceEqual</strong></a>(self, seq1, seq2, msg<font color="#909090">=None</font>, seq_type<font color="#909090">=None</font>)</dt><dd><tt>An&nbsp;equality&nbsp;assertion&nbsp;for&nbsp;ordered&nbsp;sequences&nbsp;(like&nbsp;lists&nbsp;and&nbsp;tuples).<br>
-&nbsp;<br>
-For&nbsp;the&nbsp;purposes&nbsp;of&nbsp;this&nbsp;function,&nbsp;a&nbsp;valid&nbsp;ordered&nbsp;sequence&nbsp;type&nbsp;is&nbsp;one<br>
-which&nbsp;can&nbsp;be&nbsp;indexed,&nbsp;has&nbsp;a&nbsp;length,&nbsp;and&nbsp;has&nbsp;an&nbsp;equality&nbsp;operator.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq1:&nbsp;The&nbsp;first&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq2:&nbsp;The&nbsp;second&nbsp;sequence&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;seq_type:&nbsp;The&nbsp;expected&nbsp;datatype&nbsp;of&nbsp;the&nbsp;sequences,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;datatype&nbsp;should&nbsp;be&nbsp;enforced.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertSetEqual"><strong>assertSetEqual</strong></a>(self, set1, set2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;set-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set1:&nbsp;The&nbsp;first&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;set2:&nbsp;The&nbsp;second&nbsp;set&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.<br>
-&nbsp;<br>
-assertSetEqual&nbsp;uses&nbsp;ducktyping&nbsp;to&nbsp;support&nbsp;different&nbsp;types&nbsp;of&nbsp;sets,&nbsp;and<br>
-is&nbsp;optimized&nbsp;for&nbsp;sets&nbsp;specifically&nbsp;(parameters&nbsp;must&nbsp;support&nbsp;a<br>
-difference&nbsp;method).</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertTrue"><strong>assertTrue</strong></a>(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assertTupleEqual"><strong>assertTupleEqual</strong></a>(self, tuple1, tuple2, msg<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;tuple-specific&nbsp;equality&nbsp;assertion.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple1:&nbsp;The&nbsp;first&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;tuple2:&nbsp;The&nbsp;second&nbsp;tuple&nbsp;to&nbsp;compare.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;msg:&nbsp;Optional&nbsp;message&nbsp;to&nbsp;use&nbsp;on&nbsp;failure&nbsp;instead&nbsp;of&nbsp;a&nbsp;list&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;differences.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-assert_"><strong>assert_</strong></a> = assertTrue(self, expr, msg<font color="#909090">=None</font>)</dt><dd><tt>Check&nbsp;that&nbsp;the&nbsp;expression&nbsp;is&nbsp;true.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-countTestCases"><strong>countTestCases</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabTestCase-debug"><strong>debug</strong></a>(self)</dt><dd><tt>Run&nbsp;the&nbsp;test&nbsp;without&nbsp;collecting&nbsp;errors&nbsp;in&nbsp;a&nbsp;TestResult</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-defaultTestResult"><strong>defaultTestResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabTestCase-doCleanups"><strong>doCleanups</strong></a>(self)</dt><dd><tt>Execute&nbsp;all&nbsp;cleanup&nbsp;functions.&nbsp;Normally&nbsp;called&nbsp;for&nbsp;you&nbsp;after<br>
-tearDown.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-fail"><strong>fail</strong></a>(self, msg<font color="#909090">=None</font>)</dt><dd><tt>Fail&nbsp;immediately,&nbsp;with&nbsp;the&nbsp;given&nbsp;message.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-failIf"><strong>failIf</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-failIfAlmostEqual"><strong>failIfAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-failIfEqual"><strong>failIfEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-failUnless"><strong>failUnless</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-failUnlessAlmostEqual"><strong>failUnlessAlmostEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-failUnlessEqual"><strong>failUnlessEqual</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-failUnlessRaises"><strong>failUnlessRaises</strong></a> = deprecated_func(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TabTestCase-id"><strong>id</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabTestCase-run"><strong>run</strong></a>(self, result<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="TabTestCase-shortDescription"><strong>shortDescription</strong></a>(self)</dt><dd><tt>Returns&nbsp;a&nbsp;one-line&nbsp;description&nbsp;of&nbsp;the&nbsp;test,&nbsp;or&nbsp;None&nbsp;if&nbsp;no<br>
-description&nbsp;has&nbsp;been&nbsp;provided.<br>
-&nbsp;<br>
-The&nbsp;default&nbsp;implementation&nbsp;of&nbsp;this&nbsp;method&nbsp;returns&nbsp;the&nbsp;first&nbsp;line&nbsp;of<br>
-the&nbsp;specified&nbsp;test&nbsp;method's&nbsp;docstring.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-skipTest"><strong>skipTest</strong></a>(self, reason)</dt><dd><tt>Skip&nbsp;this&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="TabTestCase-tearDown"><strong>tearDown</strong></a>(self)</dt><dd><tt>Hook&nbsp;method&nbsp;for&nbsp;deconstructing&nbsp;the&nbsp;test&nbsp;fixture&nbsp;after&nbsp;testing&nbsp;it.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="unittest.case.html#TestCase">unittest.case.TestCase</a>:<br>
-<dl><dt><strong>failureException</strong> = &lt;type 'exceptions.AssertionError'&gt;<dd><tt>Assertion&nbsp;failed.</tt></dl>
-
-<dl><dt><strong>longMessage</strong> = False</dl>
-
-<dl><dt><strong>maxDiff</strong> = 640</dl>
-
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.test_page_test_results.html b/catapult/telemetry/docs/pydoc/telemetry.testing.test_page_test_results.html
deleted file mode 100644
index 0766204..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.test_page_test_results.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.test_page_test_results</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.test_page_test_results</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/test_page_test_results.py">telemetry/testing/test_page_test_results.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.page.page.html">telemetry.page.page</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.results.page_test_results.html">telemetry.internal.results.page_test_results</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.internal.results.page_test_results.html#PageTestResults">telemetry.internal.results.page_test_results.PageTestResults</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.testing.test_page_test_results.html#TestPageTestResults">TestPageTestResults</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TestPageTestResults">class <strong>TestPageTestResults</strong></a>(<a href="telemetry.internal.results.page_test_results.html#PageTestResults">telemetry.internal.results.page_test_results.PageTestResults</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.testing.test_page_test_results.html#TestPageTestResults">TestPageTestResults</a></dd>
-<dd><a href="telemetry.internal.results.page_test_results.html#PageTestResults">telemetry.internal.results.page_test_results.PageTestResults</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TestPageTestResults-AssertHasPageSpecificListOfScalarValues"><strong>AssertHasPageSpecificListOfScalarValues</strong></a>(self, name, units, expected_values)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-AssertHasPageSpecificScalarValue"><strong>AssertHasPageSpecificScalarValue</strong></a>(self, name, units, expected_value)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-GetPageSpecificValueNamed"><strong>GetPageSpecificValueNamed</strong></a>(self, name)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-__init__"><strong>__init__</strong></a>(self, test)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-__str__"><strong>__str__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.internal.results.page_test_results.html#PageTestResults">telemetry.internal.results.page_test_results.PageTestResults</a>:<br>
-<dl><dt><a name="TestPageTestResults-AddProfilingFile"><strong>AddProfilingFile</strong></a>(self, page, file_handle)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-AddSummaryValue"><strong>AddSummaryValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-AddValue"><strong>AddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-CleanUp"><strong>CleanUp</strong></a>(self)</dt><dd><tt>Clean&nbsp;up&nbsp;any&nbsp;TraceValues&nbsp;contained&nbsp;within&nbsp;this&nbsp;results&nbsp;object.</tt></dd></dl>
-
-<dl><dt><a name="TestPageTestResults-DidRunPage"><strong>DidRunPage</strong></a>(self, page)</dt><dd><tt>Args:<br>
-&nbsp;&nbsp;page:&nbsp;The&nbsp;current&nbsp;page&nbsp;under&nbsp;test.</tt></dd></dl>
-
-<dl><dt><a name="TestPageTestResults-FindAllPageSpecificValuesFromIRNamed"><strong>FindAllPageSpecificValuesFromIRNamed</strong></a>(self, tir_label, value_name)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-FindAllPageSpecificValuesNamed"><strong>FindAllPageSpecificValuesNamed</strong></a>(self, value_name)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-FindAllTraceValues"><strong>FindAllTraceValues</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-FindPageSpecificValuesForPage"><strong>FindPageSpecificValuesForPage</strong></a>(self, page, value_name)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-FindValues"><strong>FindValues</strong></a>(self, predicate)</dt><dd><tt>Finds&nbsp;all&nbsp;values&nbsp;matching&nbsp;the&nbsp;specified&nbsp;predicate.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;predicate:&nbsp;A&nbsp;function&nbsp;that&nbsp;takes&nbsp;a&nbsp;Value&nbsp;and&nbsp;returns&nbsp;a&nbsp;bool.<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;of&nbsp;values&nbsp;matching&nbsp;|predicate|.</tt></dd></dl>
-
-<dl><dt><a name="TestPageTestResults-PrintSummary"><strong>PrintSummary</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-UploadProfilingFilesToCloud"><strong>UploadProfilingFilesToCloud</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-UploadTraceFilesToCloud"><strong>UploadTraceFilesToCloud</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-WillRunPage"><strong>WillRunPage</strong></a>(self, page)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-__copy__"><strong>__copy__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TestPageTestResults-__exit__"><strong>__exit__</strong></a>(self, _, __, ___)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.internal.results.page_test_results.html#PageTestResults">telemetry.internal.results.page_test_results.PageTestResults</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>all_page_runs</strong></dt>
-</dl>
-<dl><dt><strong>all_page_specific_values</strong></dt>
-</dl>
-<dl><dt><strong>all_summary_values</strong></dt>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-<dl><dt><strong>current_page_run</strong></dt>
-</dl>
-<dl><dt><strong>failures</strong></dt>
-</dl>
-<dl><dt><strong>pages_that_failed</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;failed&nbsp;pages.</tt></dd>
-</dl>
-<dl><dt><strong>pages_that_succeeded</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;set&nbsp;of&nbsp;pages&nbsp;that&nbsp;succeeded.</tt></dd>
-</dl>
-<dl><dt><strong>pages_to_profiling_files</strong></dt>
-</dl>
-<dl><dt><strong>pages_to_profiling_files_cloud_url</strong></dt>
-</dl>
-<dl><dt><strong>serialized_trace_file_ids_to_paths</strong></dt>
-</dl>
-<dl><dt><strong>skipped_values</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.testing.unittest_runner.html b/catapult/telemetry/docs/pydoc/telemetry.testing.unittest_runner.html
deleted file mode 100644
index b34d2d2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.testing.unittest_runner.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.testing.unittest_runner</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.testing.html"><font color="#ffffff">testing</font></a>.unittest_runner</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/testing/unittest_runner.py">telemetry/testing/unittest_runner.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.util.html">telemetry.core.util</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-Run"><strong>Run</strong></a>(project_config, no_browser<font color="#909090">=False</font>, stream<font color="#909090">=None</font>)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.async_slice.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.async_slice.html
deleted file mode 100644
index 0ce0b23..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.async_slice.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.async_slice</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.async_slice</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/async_slice.py">telemetry/timeline/async_slice.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.event.html">telemetry.timeline.event</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.async_slice.html#AsyncSlice">AsyncSlice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="AsyncSlice">class <strong>AsyncSlice</strong></a>(<a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;<a href="#AsyncSlice">AsyncSlice</a>&nbsp;represents&nbsp;an&nbsp;interval&nbsp;of&nbsp;time&nbsp;during&nbsp;which&nbsp;an<br>
-asynchronous&nbsp;operation&nbsp;is&nbsp;in&nbsp;progress.&nbsp;An&nbsp;<a href="#AsyncSlice">AsyncSlice</a>&nbsp;consumes&nbsp;no&nbsp;CPU&nbsp;time<br>
-itself&nbsp;and&nbsp;so&nbsp;is&nbsp;only&nbsp;associated&nbsp;with&nbsp;Threads&nbsp;at&nbsp;its&nbsp;start&nbsp;and&nbsp;end&nbsp;point.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.async_slice.html#AsyncSlice">AsyncSlice</a></dd>
-<dd><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="AsyncSlice-AddSubSlice"><strong>AddSubSlice</strong></a>(self, sub_slice)</dt></dl>
-
-<dl><dt><a name="AsyncSlice-IterEventsInThisContainerRecrusively"><strong>IterEventsInThisContainerRecrusively</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="AsyncSlice-__init__"><strong>__init__</strong></a>(self, category, name, timestamp, args<font color="#909090">=None</font>, duration<font color="#909090">=0</font>, start_thread<font color="#909090">=None</font>, end_thread<font color="#909090">=None</font>, thread_start<font color="#909090">=None</font>, thread_duration<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><a name="AsyncSlice-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>has_thread_timestamps</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-<dd><tt>Thread-specific&nbsp;CPU&nbsp;time&nbsp;when&nbsp;this&nbsp;event&nbsp;ended.<br>
-&nbsp;<br>
-May&nbsp;be&nbsp;None&nbsp;if&nbsp;the&nbsp;trace&nbsp;event&nbsp;didn't&nbsp;have&nbsp;thread&nbsp;time&nbsp;data.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.bounds.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.bounds.html
deleted file mode 100644
index 6c705b4..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.bounds.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.bounds</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.bounds</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/bounds.py">telemetry/timeline/bounds.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.bounds.html#Bounds">Bounds</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Bounds">class <strong>Bounds</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;min-max&nbsp;bounds.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Bounds-AddBounds"><strong>AddBounds</strong></a>(self, bounds)</dt></dl>
-
-<dl><dt><a name="Bounds-AddEvent"><strong>AddEvent</strong></a>(self, event)</dt></dl>
-
-<dl><dt><a name="Bounds-AddValue"><strong>AddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="Bounds-Contains"><strong>Contains</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="Bounds-ContainsInterval"><strong>ContainsInterval</strong></a>(self, start, end)</dt></dl>
-
-<dl><dt><a name="Bounds-Intersects"><strong>Intersects</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="Bounds-Reset"><strong>Reset</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Bounds-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Bounds-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="Bounds-CompareByMinTimes"><strong>CompareByMinTimes</strong></a>(a, b)</dt></dl>
-
-<dl><dt><a name="Bounds-CreateFromEvent"><strong>CreateFromEvent</strong></a>(event)</dt></dl>
-
-<dl><dt><a name="Bounds-GetOverlap"><strong>GetOverlap</strong></a>(first_bounds_min, first_bounds_max, second_bounds_min, second_bounds_max)</dt></dl>
-
-<dl><dt><a name="Bounds-GetOverlapBetweenBounds"><strong>GetOverlapBetweenBounds</strong></a>(first_bounds, second_bounds)</dt><dd><tt>Compute&nbsp;the&nbsp;overlap&nbsp;duration&nbsp;between&nbsp;first_bounds&nbsp;and&nbsp;second_bounds.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>bounds</strong></dt>
-</dl>
-<dl><dt><strong>center</strong></dt>
-</dl>
-<dl><dt><strong>is_empty</strong></dt>
-</dl>
-<dl><dt><strong>max</strong></dt>
-</dl>
-<dl><dt><strong>min</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.counter.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.counter.html
deleted file mode 100644
index 321bffe..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.counter.html
+++ /dev/null
@@ -1,165 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.counter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.counter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/counter.py">telemetry/timeline/counter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.event_container.html">telemetry.timeline.event_container</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.counter.html#CounterSample">CounterSample</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.counter.html#Counter">Counter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Counter">class <strong>Counter</strong></a>(<a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Stores&nbsp;all&nbsp;the&nbsp;samples&nbsp;for&nbsp;a&nbsp;given&nbsp;counter.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.counter.html#Counter">Counter</a></dd>
-<dd><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Counter-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Counter-IterChildContainers"><strong>IterChildContainers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Counter-IterEventsInThisContainer"><strong>IterEventsInThisContainer</strong></a>(self, event_type_predicate, event_predicate)</dt></dl>
-
-<dl><dt><a name="Counter-__init__"><strong>__init__</strong></a>(self, parent, category, name)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>num_samples</strong></dt>
-</dl>
-<dl><dt><strong>num_series</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="Counter-GetAllEvents"><strong>GetAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;List&nbsp;versions.&nbsp;These&nbsp;should&nbsp;always&nbsp;be&nbsp;simple&nbsp;expressions&nbsp;that&nbsp;list()&nbsp;on<br>
-#&nbsp;an&nbsp;underlying&nbsp;iter&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="Counter-GetAllEventsOfName"><strong>GetAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-GetAllToplevelSlicesOfName"><strong>GetAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllAsyncSlicesOfName"><strong>IterAllAsyncSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllAsyncSlicesStartsWithName"><strong>IterAllAsyncSlicesStartsWithName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllEvents"><strong>IterAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>, event_type_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, event_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Iterates&nbsp;all&nbsp;events&nbsp;in&nbsp;this&nbsp;container,&nbsp;pre-filtered&nbsp;by&nbsp;two&nbsp;predicates.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;<a href="__builtin__.html#object">object</a>,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])</tt></dd></dl>
-
-<dl><dt><a name="Counter-IterAllEventsOfName"><strong>IterAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;Helper&nbsp;functions&nbsp;for&nbsp;finding&nbsp;common&nbsp;kinds&nbsp;of&nbsp;events.&nbsp;Must&nbsp;always&nbsp;take&nbsp;an<br>
-#&nbsp;optinal&nbsp;recurisve&nbsp;parameter&nbsp;and&nbsp;be&nbsp;implemented&nbsp;in&nbsp;terms&nbsp;fo&nbsp;IterAllEvents.</tt></dd></dl>
-
-<dl><dt><a name="Counter-IterAllFlowEvents"><strong>IterAllFlowEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllSlices"><strong>IterAllSlices</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllSlicesInRange"><strong>IterAllSlicesInRange</strong></a>(self, start, end, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllSlicesOfName"><strong>IterAllSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Counter-IterAllToplevelSlicesOfName"><strong>IterAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="Counter-IsAsyncSlice"><strong>IsAsyncSlice</strong></a>(t)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="CounterSample">class <strong>CounterSample</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;Doesn't&nbsp;inherit&nbsp;from&nbsp;TimelineEvent&nbsp;because&nbsp;its&nbsp;only&nbsp;a&nbsp;temporary&nbsp;wrapper&nbsp;of&nbsp;a<br>
-#&nbsp;counter&nbsp;sample&nbsp;into&nbsp;an&nbsp;event.&nbsp;During&nbsp;stable&nbsp;operation,&nbsp;the&nbsp;samples&nbsp;are&nbsp;stored<br>
-#&nbsp;a&nbsp;dense&nbsp;array&nbsp;of&nbsp;values&nbsp;rather&nbsp;than&nbsp;in&nbsp;the&nbsp;long-form&nbsp;done&nbsp;by&nbsp;an&nbsp;Event.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="CounterSample-__init__"><strong>__init__</strong></a>(self, counter, sample_index)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>category</strong></dt>
-</dl>
-<dl><dt><strong>duration</strong></dt>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>name</strong></dt>
-</dl>
-<dl><dt><strong>start</strong></dt>
-</dl>
-<dl><dt><strong>thread_duration</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-</dl>
-<dl><dt><strong>thread_start</strong></dt>
-</dl>
-<dl><dt><strong>value</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.event.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.event.html
deleted file mode 100644
index 659e231..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.event.html
+++ /dev/null
@@ -1,70 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.event</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.event</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/event.py">telemetry/timeline/event.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event.html#TimelineEvent">TimelineEvent</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineEvent">class <strong>TimelineEvent</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;timeline&nbsp;event.<br>
-&nbsp;<br>
-thread_start,&nbsp;thread_duration&nbsp;and&nbsp;thread_end&nbsp;are&nbsp;the&nbsp;start&nbsp;time,&nbsp;duration<br>
-and&nbsp;end&nbsp;time&nbsp;of&nbsp;this&nbsp;event&nbsp;as&nbsp;measured&nbsp;by&nbsp;the&nbsp;thread-specific&nbsp;CPU&nbsp;clock<br>
-(ticking&nbsp;when&nbsp;the&nbsp;thread&nbsp;is&nbsp;actually&nbsp;scheduled).&nbsp;Thread&nbsp;time&nbsp;is&nbsp;optional<br>
-on&nbsp;trace&nbsp;events&nbsp;and&nbsp;the&nbsp;corresponding&nbsp;attributes&nbsp;in&nbsp;<a href="#TimelineEvent">TimelineEvent</a>&nbsp;will&nbsp;be<br>
-set&nbsp;to&nbsp;None&nbsp;(not&nbsp;0)&nbsp;if&nbsp;not&nbsp;present.&nbsp;Users&nbsp;of&nbsp;this&nbsp;class&nbsp;need&nbsp;to&nbsp;properly<br>
-handle&nbsp;this&nbsp;case.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimelineEvent-__init__"><strong>__init__</strong></a>(self, category, name, start, duration, thread_start<font color="#909090">=None</font>, thread_duration<font color="#909090">=None</font>, args<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEvent-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>has_thread_timestamps</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-<dd><tt>Thread-specific&nbsp;CPU&nbsp;time&nbsp;when&nbsp;this&nbsp;event&nbsp;ended.<br>
-&nbsp;<br>
-May&nbsp;be&nbsp;None&nbsp;if&nbsp;the&nbsp;trace&nbsp;event&nbsp;didn't&nbsp;have&nbsp;thread&nbsp;time&nbsp;data.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.event_container.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.event_container.html
deleted file mode 100644
index 11f6ea2..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.event_container.html
+++ /dev/null
@@ -1,118 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.event_container</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.event_container</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/event_container.py">telemetry/timeline/event_container.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.async_slice.html">telemetry.timeline.async_slice</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.flow_event.html">telemetry.timeline.flow_event</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.slice.html">telemetry.timeline.slice</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event_container.html#TimelineEventContainer">TimelineEventContainer</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineEventContainer">class <strong>TimelineEventContainer</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;a&nbsp;container&nbsp;for&nbsp;events.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimelineEventContainer-GetAllEvents"><strong>GetAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;List&nbsp;versions.&nbsp;These&nbsp;should&nbsp;always&nbsp;be&nbsp;simple&nbsp;expressions&nbsp;that&nbsp;list()&nbsp;on<br>
-#&nbsp;an&nbsp;underlying&nbsp;iter&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="TimelineEventContainer-GetAllEventsOfName"><strong>GetAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-GetAllToplevelSlicesOfName"><strong>GetAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllAsyncSlicesOfName"><strong>IterAllAsyncSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllAsyncSlicesStartsWithName"><strong>IterAllAsyncSlicesStartsWithName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllEvents"><strong>IterAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>, event_type_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, event_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Iterates&nbsp;all&nbsp;events&nbsp;in&nbsp;this&nbsp;container,&nbsp;pre-filtered&nbsp;by&nbsp;two&nbsp;predicates.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;<a href="__builtin__.html#object">object</a>,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])</tt></dd></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllEventsOfName"><strong>IterAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;Helper&nbsp;functions&nbsp;for&nbsp;finding&nbsp;common&nbsp;kinds&nbsp;of&nbsp;events.&nbsp;Must&nbsp;always&nbsp;take&nbsp;an<br>
-#&nbsp;optinal&nbsp;recurisve&nbsp;parameter&nbsp;and&nbsp;be&nbsp;implemented&nbsp;in&nbsp;terms&nbsp;fo&nbsp;IterAllEvents.</tt></dd></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllFlowEvents"><strong>IterAllFlowEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllSlices"><strong>IterAllSlices</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllSlicesInRange"><strong>IterAllSlicesInRange</strong></a>(self, start, end, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllSlicesOfName"><strong>IterAllSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterAllToplevelSlicesOfName"><strong>IterAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterChildContainers"><strong>IterChildContainers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineEventContainer-IterEventsInThisContainer"><strong>IterEventsInThisContainer</strong></a>(self, event_type_predicate, event_predicate)</dt><dd><tt>Iterates&nbsp;all&nbsp;the&nbsp;TimelineEvents&nbsp;in&nbsp;this&nbsp;container.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;<a href="__builtin__.html#object">object</a>,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])<br>
-&nbsp;<br>
-DO&nbsp;NOT&nbsp;ASSUME&nbsp;that&nbsp;the&nbsp;event_type_predicate&nbsp;will&nbsp;be&nbsp;called&nbsp;for&nbsp;every&nbsp;event<br>
-found.&nbsp;The&nbsp;relative&nbsp;calling&nbsp;order&nbsp;of&nbsp;the&nbsp;two&nbsp;is&nbsp;left&nbsp;up&nbsp;to&nbsp;the&nbsp;implementer<br>
-of&nbsp;the&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="TimelineEventContainer-__init__"><strong>__init__</strong></a>(self, name, parent)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TimelineEventContainer-IsAsyncSlice"><strong>IsAsyncSlice</strong></a>(t)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.flow_event.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.flow_event.html
deleted file mode 100644
index 9dbdf97..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.flow_event.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.flow_event</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.flow_event</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/flow_event.py">telemetry/timeline/flow_event.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.event.html">telemetry.timeline.event</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.flow_event.html#FlowEvent">FlowEvent</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FlowEvent">class <strong>FlowEvent</strong></a>(<a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;<a href="#FlowEvent">FlowEvent</a>&nbsp;represents&nbsp;an&nbsp;interval&nbsp;of&nbsp;time&nbsp;plus&nbsp;parameters&nbsp;associated<br>
-with&nbsp;that&nbsp;interval.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.flow_event.html#FlowEvent">FlowEvent</a></dd>
-<dd><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FlowEvent-__init__"><strong>__init__</strong></a>(self, category, event_id, name, start, args<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><a name="FlowEvent-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>has_thread_timestamps</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-<dd><tt>Thread-specific&nbsp;CPU&nbsp;time&nbsp;when&nbsp;this&nbsp;event&nbsp;ended.<br>
-&nbsp;<br>
-May&nbsp;be&nbsp;None&nbsp;if&nbsp;the&nbsp;trace&nbsp;event&nbsp;didn't&nbsp;have&nbsp;thread&nbsp;time&nbsp;data.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.html
deleted file mode 100644
index b7b797c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.html
+++ /dev/null
@@ -1,56 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.timeline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.timeline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/__init__.py">telemetry/timeline/__init__.py</a></font></td></tr></table>
-    <p></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.async_slice.html">async_slice</a><br>
-<a href="telemetry.timeline.bounds.html">bounds</a><br>
-<a href="telemetry.timeline.bounds_unittest.html">bounds_unittest</a><br>
-<a href="telemetry.timeline.counter.html">counter</a><br>
-<a href="telemetry.timeline.counter_unittest.html">counter_unittest</a><br>
-<a href="telemetry.timeline.event.html">event</a><br>
-<a href="telemetry.timeline.event_container.html">event_container</a><br>
-<a href="telemetry.timeline.event_unittest.html">event_unittest</a><br>
-<a href="telemetry.timeline.flow_event.html">flow_event</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.importer.html">importer</a><br>
-<a href="telemetry.timeline.inspector_importer.html">inspector_importer</a><br>
-<a href="telemetry.timeline.inspector_importer_unittest.html">inspector_importer_unittest</a><br>
-<a href="telemetry.timeline.memory_dump_event.html">memory_dump_event</a><br>
-<a href="telemetry.timeline.memory_dump_event_unittest.html">memory_dump_event_unittest</a><br>
-<a href="telemetry.timeline.model.html">model</a><br>
-<a href="telemetry.timeline.model_unittest.html">model_unittest</a><br>
-<a href="telemetry.timeline.process.html">process</a><br>
-<a href="telemetry.timeline.sample.html">sample</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.slice.html">slice</a><br>
-<a href="telemetry.timeline.slice_unittest.html">slice_unittest</a><br>
-<a href="telemetry.timeline.surface_flinger_importer.html">surface_flinger_importer</a><br>
-<a href="telemetry.timeline.tab_id_importer.html">tab_id_importer</a><br>
-<a href="telemetry.timeline.tab_id_importer_unittest.html">tab_id_importer_unittest</a><br>
-<a href="telemetry.timeline.thread.html">thread</a><br>
-<a href="telemetry.timeline.thread_unittest.html">thread_unittest</a><br>
-<a href="telemetry.timeline.trace_data.html">trace_data</a><br>
-<a href="telemetry.timeline.trace_data_unittest.html">trace_data_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_event_importer.html">trace_event_importer</a><br>
-<a href="telemetry.timeline.trace_event_importer_unittest.html">trace_event_importer_unittest</a><br>
-<a href="telemetry.timeline.tracing_category_filter.html">tracing_category_filter</a><br>
-<a href="telemetry.timeline.tracing_category_filter_unittest.html">tracing_category_filter_unittest</a><br>
-<a href="telemetry.timeline.tracing_config.html">tracing_config</a><br>
-<a href="telemetry.timeline.tracing_config_unittest.html">tracing_config_unittest</a><br>
-<a href="telemetry.timeline.tracing_options.html">tracing_options</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.importer.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.importer.html
deleted file mode 100644
index b330a1b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.importer.html
+++ /dev/null
@@ -1,61 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.importer</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.importer</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/importer.py">telemetry/timeline/importer.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.importer.html#TimelineImporter">TimelineImporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineImporter">class <strong>TimelineImporter</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Reads&nbsp;TraceData&nbsp;and&nbsp;populates&nbsp;timeline&nbsp;model&nbsp;with&nbsp;what&nbsp;it&nbsp;finds.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimelineImporter-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt><dd><tt>Called&nbsp;after&nbsp;all&nbsp;other&nbsp;importers&nbsp;for&nbsp;the&nbsp;model&nbsp;are&nbsp;run.</tt></dd></dl>
-
-<dl><dt><a name="TimelineImporter-ImportEvents"><strong>ImportEvents</strong></a>(self)</dt><dd><tt>Processes&nbsp;the&nbsp;event&nbsp;data&nbsp;in&nbsp;the&nbsp;wrapper&nbsp;and&nbsp;creates&nbsp;and&nbsp;adds<br>
-new&nbsp;timeline&nbsp;events&nbsp;to&nbsp;the&nbsp;model</tt></dd></dl>
-
-<dl><dt><a name="TimelineImporter-__init__"><strong>__init__</strong></a>(self, model, trace_data, import_order)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TimelineImporter-GetSupportedPart"><strong>GetSupportedPart</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.inspector_importer.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.inspector_importer.html
deleted file mode 100644
index fe808e8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.inspector_importer.html
+++ /dev/null
@@ -1,77 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.inspector_importer</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.inspector_importer</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/inspector_importer.py">telemetry/timeline/inspector_importer.py</a></font></td></tr></table>
-    <p><tt>Imports&nbsp;event&nbsp;data&nbsp;obtained&nbsp;from&nbsp;the&nbsp;inspector's&nbsp;timeline.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.importer.html">telemetry.timeline.importer</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.thread.html">telemetry.timeline.thread</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.slice.html">telemetry.timeline.slice</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.inspector_importer.html#InspectorTimelineImporter">InspectorTimelineImporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InspectorTimelineImporter">class <strong>InspectorTimelineImporter</strong></a>(<a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.inspector_importer.html#InspectorTimelineImporter">InspectorTimelineImporter</a></dd>
-<dd><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="InspectorTimelineImporter-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorTimelineImporter-ImportEvents"><strong>ImportEvents</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="InspectorTimelineImporter-__init__"><strong>__init__</strong></a>(self, model, trace_data)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="InspectorTimelineImporter-AddRawEventToThreadRecursive"><strong>AddRawEventToThreadRecursive</strong></a>(thread, raw_inspector_event)</dt></dl>
-
-<dl><dt><a name="InspectorTimelineImporter-GetSupportedPart"><strong>GetSupportedPart</strong></a>()</dt></dl>
-
-<dl><dt><a name="InspectorTimelineImporter-RawEventToTimelineEvent"><strong>RawEventToTimelineEvent</strong></a>(raw_inspector_event)</dt><dd><tt>Converts&nbsp;raw_inspector_event&nbsp;to&nbsp;TimelineEvent.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.memory_dump_event.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.memory_dump_event.html
deleted file mode 100644
index 52c8034..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.memory_dump_event.html
+++ /dev/null
@@ -1,231 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.memory_dump_event</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.memory_dump_event</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/memory_dump_event.py">telemetry/timeline/memory_dump_event.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="posixpath.html">posixpath</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.event.html">telemetry.timeline.event</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.memory_dump_event.html#GlobalMemoryDump">GlobalMemoryDump</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.timeline.memory_dump_event.html#MemoryBucket">MemoryBucket</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.timeline.memory_dump_event.html#MmapCategory">MmapCategory</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.memory_dump_event.html#ProcessMemoryDumpEvent">ProcessMemoryDumpEvent</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GlobalMemoryDump">class <strong>GlobalMemoryDump</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Object&nbsp;to&nbsp;aggregate&nbsp;individual&nbsp;process&nbsp;dumps&nbsp;with&nbsp;the&nbsp;same&nbsp;dump&nbsp;id.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;process_dumps:&nbsp;A&nbsp;sequence&nbsp;of&nbsp;<a href="#ProcessMemoryDumpEvent">ProcessMemoryDumpEvent</a>&nbsp;objects,&nbsp;all&nbsp;sharing<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;same&nbsp;global&nbsp;dump&nbsp;id.<br>
-&nbsp;<br>
-Attributes:<br>
-&nbsp;&nbsp;dump_id:&nbsp;A&nbsp;string&nbsp;identifying&nbsp;this&nbsp;dump.<br>
-&nbsp;&nbsp;has_mmaps:&nbsp;True&nbsp;if&nbsp;the&nbsp;memory&nbsp;dump&nbsp;has&nbsp;mmaps&nbsp;information.&nbsp;If&nbsp;False&nbsp;then<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMemoryUsage&nbsp;will&nbsp;report&nbsp;all&nbsp;zeros.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="GlobalMemoryDump-GetMemoryUsage"><strong>GetMemoryUsage</strong></a>(self)</dt><dd><tt>Get&nbsp;the&nbsp;aggregated&nbsp;memory&nbsp;usage&nbsp;over&nbsp;all&nbsp;processes&nbsp;in&nbsp;this&nbsp;dump.</tt></dd></dl>
-
-<dl><dt><a name="GlobalMemoryDump-IterProcessMemoryDumps"><strong>IterProcessMemoryDumps</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="GlobalMemoryDump-__init__"><strong>__init__</strong></a>(self, process_dumps)</dt></dl>
-
-<dl><dt><a name="GlobalMemoryDump-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>duration</strong></dt>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>start</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryBucket">class <strong>MemoryBucket</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Simple&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;to&nbsp;hold&nbsp;and&nbsp;aggregate&nbsp;memory&nbsp;values.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MemoryBucket-AddRegion"><strong>AddRegion</strong></a>(self, byte_stats)</dt></dl>
-
-<dl><dt><a name="MemoryBucket-GetValue"><strong>GetValue</strong></a>(self, name)</dt></dl>
-
-<dl><dt><a name="MemoryBucket-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="MemoryBucket-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MmapCategory">class <strong>MmapCategory</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MmapCategory-GetMatchingChild"><strong>GetMatchingChild</strong></a>(self, mapped_file)</dt><dd><tt>Get&nbsp;the&nbsp;first&nbsp;matching&nbsp;sub-category&nbsp;for&nbsp;a&nbsp;given&nbsp;mapped&nbsp;file.<br>
-&nbsp;<br>
-Returns&nbsp;None&nbsp;if&nbsp;the&nbsp;category&nbsp;has&nbsp;no&nbsp;children,&nbsp;or&nbsp;the&nbsp;DefaultCategory&nbsp;if<br>
-it&nbsp;does&nbsp;have&nbsp;children&nbsp;but&nbsp;none&nbsp;of&nbsp;them&nbsp;match.</tt></dd></dl>
-
-<dl><dt><a name="MmapCategory-Match"><strong>Match</strong></a>(self, mapped_file)</dt><dd><tt>Test&nbsp;whether&nbsp;a&nbsp;mapped&nbsp;file&nbsp;matches&nbsp;this&nbsp;category.</tt></dd></dl>
-
-<dl><dt><a name="MmapCategory-__init__"><strong>__init__</strong></a>(self, name, file_pattern, children<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;(sub)category&nbsp;for&nbsp;classifying&nbsp;memory&nbsp;maps.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;name:&nbsp;A&nbsp;string&nbsp;to&nbsp;identify&nbsp;the&nbsp;category.<br>
-&nbsp;&nbsp;file_pattern:&nbsp;A&nbsp;regex&nbsp;pattern,&nbsp;the&nbsp;category&nbsp;will&nbsp;aggregate&nbsp;memory&nbsp;usage<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;all&nbsp;mapped&nbsp;files&nbsp;matching&nbsp;this&nbsp;pattern.<br>
-&nbsp;&nbsp;children:&nbsp;A&nbsp;list&nbsp;of&nbsp;<a href="#MmapCategory">MmapCategory</a>&nbsp;objects,&nbsp;used&nbsp;to&nbsp;sub-categorize&nbsp;memory<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;usage.</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="MmapCategory-DefaultCategory"><strong>DefaultCategory</strong></a>(cls)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>An&nbsp;implicit&nbsp;'Others'&nbsp;match-all&nbsp;category&nbsp;with&nbsp;no&nbsp;children.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProcessMemoryDumpEvent">class <strong>ProcessMemoryDumpEvent</strong></a>(<a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;memory&nbsp;dump&nbsp;event&nbsp;belonging&nbsp;to&nbsp;a&nbsp;single&nbsp;timeline.Process&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;<br>
-It's&nbsp;a&nbsp;subclass&nbsp;of&nbsp;telemetry's&nbsp;<a href="telemetry.timeline.event.html#TimelineEvent">TimelineEvent</a>&nbsp;so&nbsp;it&nbsp;can&nbsp;be&nbsp;included&nbsp;in<br>
-the&nbsp;stream&nbsp;of&nbsp;events&nbsp;contained&nbsp;in&nbsp;timeline.model&nbsp;objects,&nbsp;and&nbsp;have&nbsp;its<br>
-timing&nbsp;correlated&nbsp;with&nbsp;that&nbsp;of&nbsp;other&nbsp;events&nbsp;in&nbsp;the&nbsp;model.<br>
-&nbsp;<br>
-Properties:<br>
-&nbsp;&nbsp;dump_id:&nbsp;A&nbsp;string&nbsp;to&nbsp;identify&nbsp;events&nbsp;belonging&nbsp;to&nbsp;the&nbsp;same&nbsp;global&nbsp;dump.<br>
-&nbsp;&nbsp;process:&nbsp;The&nbsp;timeline.Process&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;that&nbsp;owns&nbsp;this&nbsp;memory&nbsp;dump&nbsp;event.<br>
-&nbsp;&nbsp;has_mmaps:&nbsp;True&nbsp;if&nbsp;the&nbsp;memory&nbsp;dump&nbsp;has&nbsp;mmaps&nbsp;information.&nbsp;If&nbsp;False&nbsp;then<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GetMemoryUsage&nbsp;will&nbsp;report&nbsp;all&nbsp;zeros.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.memory_dump_event.html#ProcessMemoryDumpEvent">ProcessMemoryDumpEvent</a></dd>
-<dd><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ProcessMemoryDumpEvent-GetMemoryBucket"><strong>GetMemoryBucket</strong></a>(self, path)</dt><dd><tt>Return&nbsp;the&nbsp;<a href="#MemoryBucket">MemoryBucket</a>&nbsp;associated&nbsp;with&nbsp;a&nbsp;category&nbsp;path.<br>
-&nbsp;<br>
-An&nbsp;empty&nbsp;bucket&nbsp;will&nbsp;be&nbsp;created&nbsp;if&nbsp;the&nbsp;path&nbsp;does&nbsp;not&nbsp;already&nbsp;exist.<br>
-&nbsp;<br>
-path:&nbsp;A&nbsp;string&nbsp;with&nbsp;path&nbsp;in&nbsp;the&nbsp;classification&nbsp;tree,&nbsp;e.g.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'/Android/Java&nbsp;runtime/Cache'.&nbsp;Note:&nbsp;no&nbsp;trailing&nbsp;slash,&nbsp;except&nbsp;for<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;root&nbsp;path&nbsp;'/'.</tt></dd></dl>
-
-<dl><dt><a name="ProcessMemoryDumpEvent-GetMemoryUsage"><strong>GetMemoryUsage</strong></a>(self)</dt><dd><tt>Get&nbsp;a&nbsp;dictionary&nbsp;with&nbsp;the&nbsp;memory&nbsp;usage&nbsp;of&nbsp;this&nbsp;process.</tt></dd></dl>
-
-<dl><dt><a name="ProcessMemoryDumpEvent-GetMemoryValue"><strong>GetMemoryValue</strong></a>(self, category_path, discount_tracing<font color="#909090">=False</font>)</dt><dd><tt>Return&nbsp;a&nbsp;specific&nbsp;value&nbsp;from&nbsp;within&nbsp;a&nbsp;<a href="#MemoryBucket">MemoryBucket</a>.<br>
-&nbsp;<br>
-category_path:&nbsp;A&nbsp;string&nbsp;composed&nbsp;of&nbsp;a&nbsp;path&nbsp;in&nbsp;the&nbsp;classification&nbsp;tree,<br>
-&nbsp;&nbsp;&nbsp;&nbsp;followed&nbsp;by&nbsp;a&nbsp;'.',&nbsp;followed&nbsp;by&nbsp;a&nbsp;specific&nbsp;bucket&nbsp;value,&nbsp;e.g.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;'/Android/Java&nbsp;runtime/Cache.private_dirty_resident'.<br>
-discount_tracing:&nbsp;A&nbsp;boolean&nbsp;indicating&nbsp;whether&nbsp;the&nbsp;returned&nbsp;value&nbsp;should<br>
-&nbsp;&nbsp;&nbsp;&nbsp;be&nbsp;discounted&nbsp;by&nbsp;the&nbsp;resident&nbsp;size&nbsp;of&nbsp;the&nbsp;tracing&nbsp;allocator.</tt></dd></dl>
-
-<dl><dt><a name="ProcessMemoryDumpEvent-__init__"><strong>__init__</strong></a>(self, process, event)</dt></dl>
-
-<dl><dt><a name="ProcessMemoryDumpEvent-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>process_name</strong></dt>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>has_thread_timestamps</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-<dd><tt>Thread-specific&nbsp;CPU&nbsp;time&nbsp;when&nbsp;this&nbsp;event&nbsp;ended.<br>
-&nbsp;<br>
-May&nbsp;be&nbsp;None&nbsp;if&nbsp;the&nbsp;trace&nbsp;event&nbsp;didn't&nbsp;have&nbsp;thread&nbsp;time&nbsp;data.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>BUCKET_ATTRS</strong> = {'private_clean_resident': 'pc', 'private_dirty_resident': 'pd', 'proportional_resident': 'pss', 'shared_clean_resident': 'sc', 'shared_dirty_resident': 'sd', 'swapped': 'sw'}<br>
-<strong>MMAPS_METRICS</strong> = {'mmaps_ashmem': ('/Android/Ashmem.proportional_resident', False), 'mmaps_java_heap': ('/Android/Java runtime/Spaces.proportional_resident', False), 'mmaps_native_heap': ('/Native heap.proportional_resident', True), 'mmaps_overall_pss': ('/.proportional_resident', True), 'mmaps_private_dirty': ('/.private_dirty_resident', True)}<br>
-<strong>ROOT_CATEGORY</strong> = &lt;telemetry.timeline.memory_dump_event.MmapCategory object&gt;</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.model.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.model.html
deleted file mode 100644
index a11a530..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.model.html
+++ /dev/null
@@ -1,314 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.model</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.model</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/model.py">telemetry/timeline/model.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;container&nbsp;for&nbsp;timeline-based&nbsp;events&nbsp;and&nbsp;traces&nbsp;and&nbsp;can&nbsp;handle&nbsp;importing<br>
-raw&nbsp;event&nbsp;data&nbsp;from&nbsp;different&nbsp;sources.&nbsp;This&nbsp;model&nbsp;closely&nbsp;resembles&nbsp;that&nbsp;in&nbsp;the<br>
-trace_viewer&nbsp;project:<br>
-https://code.google.com/p/trace-viewer/</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.async_slice.html">telemetry.timeline.async_slice</a><br>
-<a href="telemetry.timeline.bounds.html">telemetry.timeline.bounds</a><br>
-<a href="telemetry.timeline.event_container.html">telemetry.timeline.event_container</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.inspector_importer.html">telemetry.timeline.inspector_importer</a><br>
-<a href="telemetry.timeline.process.html">telemetry.timeline.process</a><br>
-<a href="telemetry.timeline.slice.html">telemetry.timeline.slice</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.surface_flinger_importer.html">telemetry.timeline.surface_flinger_importer</a><br>
-<a href="telemetry.timeline.tab_id_importer.html">telemetry.timeline.tab_id_importer</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_event_importer.html">telemetry.timeline.trace_event_importer</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.model.html#MarkerMismatchError">MarkerMismatchError</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.timeline.model.html#MarkerOverlapError">MarkerOverlapError</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.model.html#TimelineModel">TimelineModel</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MarkerMismatchError">class <strong>MarkerMismatchError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.model.html#MarkerMismatchError">MarkerMismatchError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MarkerMismatchError-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MarkerMismatchError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MarkerMismatchError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MarkerMismatchError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MarkerMismatchError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerMismatchError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MarkerMismatchError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MarkerOverlapError">class <strong>MarkerOverlapError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.model.html#MarkerOverlapError">MarkerOverlapError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MarkerOverlapError-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MarkerOverlapError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MarkerOverlapError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MarkerOverlapError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MarkerOverlapError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MarkerOverlapError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MarkerOverlapError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineModel">class <strong>TimelineModel</strong></a>(<a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.model.html#TimelineModel">TimelineModel</a></dd>
-<dd><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TimelineModel-AddMappingFromTabIdToRendererThread"><strong>AddMappingFromTabIdToRendererThread</strong></a>(self, tab_id, renderer_thread)</dt></dl>
-
-<dl><dt><a name="TimelineModel-FinalizeImport"><strong>FinalizeImport</strong></a>(self, shift_world_to_zero<font color="#909090">=False</font>, importers<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-FindTimelineMarkers"><strong>FindTimelineMarkers</strong></a>(self, timeline_marker_names)</dt><dd><tt>Find&nbsp;the&nbsp;timeline&nbsp;events&nbsp;with&nbsp;the&nbsp;given&nbsp;names.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;number&nbsp;and&nbsp;order&nbsp;of&nbsp;events&nbsp;found&nbsp;does&nbsp;not&nbsp;match&nbsp;the&nbsp;names,<br>
-raise&nbsp;an&nbsp;error.</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-GetAllProcesses"><strong>GetAllProcesses</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineModel-GetAllThreads"><strong>GetAllThreads</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineModel-GetOrCreateProcess"><strong>GetOrCreateProcess</strong></a>(self, pid)</dt></dl>
-
-<dl><dt><a name="TimelineModel-GetRendererProcessFromTabId"><strong>GetRendererProcessFromTabId</strong></a>(self, tab_id)</dt></dl>
-
-<dl><dt><a name="TimelineModel-GetRendererThreadFromTabId"><strong>GetRendererThreadFromTabId</strong></a>(self, tab_id)</dt></dl>
-
-<dl><dt><a name="TimelineModel-ImportTraces"><strong>ImportTraces</strong></a>(self, trace_data, shift_world_to_zero<font color="#909090">=True</font>)</dt><dd><tt>Populates&nbsp;the&nbsp;model&nbsp;with&nbsp;the&nbsp;provided&nbsp;trace&nbsp;data.<br>
-&nbsp;<br>
-trace_data&nbsp;must&nbsp;be&nbsp;an&nbsp;instance&nbsp;of&nbsp;TraceData.<br>
-&nbsp;<br>
-Passing&nbsp;shift_world_to_zero=True&nbsp;causes&nbsp;the&nbsp;events&nbsp;to&nbsp;be&nbsp;shifted&nbsp;such&nbsp;that<br>
-the&nbsp;first&nbsp;event&nbsp;starts&nbsp;at&nbsp;time&nbsp;0.</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-IterChildContainers"><strong>IterChildContainers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterGlobalMemoryDumps"><strong>IterGlobalMemoryDumps</strong></a>(self)</dt><dd><tt>Iterate&nbsp;over&nbsp;the&nbsp;memory&nbsp;dump&nbsp;events&nbsp;of&nbsp;this&nbsp;model.</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-SetGlobalMemoryDumps"><strong>SetGlobalMemoryDumps</strong></a>(self, global_memory_dumps)</dt><dd><tt>Populates&nbsp;the&nbsp;model&nbsp;with&nbsp;a&nbsp;sequence&nbsp;of&nbsp;GlobalMemoryDump&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-ShiftWorldToZero"><strong>ShiftWorldToZero</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineModel-UpdateBounds"><strong>UpdateBounds</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TimelineModel-__init__"><strong>__init__</strong></a>(self, trace_data<font color="#909090">=None</font>, shift_world_to_zero<font color="#909090">=True</font>)</dt><dd><tt>Initializes&nbsp;a&nbsp;<a href="#TimelineModel">TimelineModel</a>.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;trace_data:&nbsp;trace_data.TraceData&nbsp;containing&nbsp;events&nbsp;to&nbsp;import<br>
-&nbsp;&nbsp;&nbsp;&nbsp;shift_world_to_zero:&nbsp;If&nbsp;true,&nbsp;the&nbsp;events&nbsp;will&nbsp;be&nbsp;shifted&nbsp;such&nbsp;that&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;first&nbsp;event&nbsp;starts&nbsp;at&nbsp;time&nbsp;0.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>bounds</strong></dt>
-</dl>
-<dl><dt><strong>browser_process</strong></dt>
-</dl>
-<dl><dt><strong>gpu_process</strong></dt>
-</dl>
-<dl><dt><strong>processes</strong></dt>
-</dl>
-<dl><dt><strong>surface_flinger_process</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="TimelineModel-GetAllEvents"><strong>GetAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;List&nbsp;versions.&nbsp;These&nbsp;should&nbsp;always&nbsp;be&nbsp;simple&nbsp;expressions&nbsp;that&nbsp;list()&nbsp;on<br>
-#&nbsp;an&nbsp;underlying&nbsp;iter&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-GetAllEventsOfName"><strong>GetAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-GetAllToplevelSlicesOfName"><strong>GetAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllAsyncSlicesOfName"><strong>IterAllAsyncSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllAsyncSlicesStartsWithName"><strong>IterAllAsyncSlicesStartsWithName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllEvents"><strong>IterAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>, event_type_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, event_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Iterates&nbsp;all&nbsp;events&nbsp;in&nbsp;this&nbsp;container,&nbsp;pre-filtered&nbsp;by&nbsp;two&nbsp;predicates.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;object,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-IterAllEventsOfName"><strong>IterAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;Helper&nbsp;functions&nbsp;for&nbsp;finding&nbsp;common&nbsp;kinds&nbsp;of&nbsp;events.&nbsp;Must&nbsp;always&nbsp;take&nbsp;an<br>
-#&nbsp;optinal&nbsp;recurisve&nbsp;parameter&nbsp;and&nbsp;be&nbsp;implemented&nbsp;in&nbsp;terms&nbsp;fo&nbsp;IterAllEvents.</tt></dd></dl>
-
-<dl><dt><a name="TimelineModel-IterAllFlowEvents"><strong>IterAllFlowEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllSlices"><strong>IterAllSlices</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllSlicesInRange"><strong>IterAllSlicesInRange</strong></a>(self, start, end, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllSlicesOfName"><strong>IterAllSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterAllToplevelSlicesOfName"><strong>IterAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="TimelineModel-IterEventsInThisContainer"><strong>IterEventsInThisContainer</strong></a>(self, event_type_predicate, event_predicate)</dt><dd><tt>Iterates&nbsp;all&nbsp;the&nbsp;TimelineEvents&nbsp;in&nbsp;this&nbsp;container.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;object,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])<br>
-&nbsp;<br>
-DO&nbsp;NOT&nbsp;ASSUME&nbsp;that&nbsp;the&nbsp;event_type_predicate&nbsp;will&nbsp;be&nbsp;called&nbsp;for&nbsp;every&nbsp;event<br>
-found.&nbsp;The&nbsp;relative&nbsp;calling&nbsp;order&nbsp;of&nbsp;the&nbsp;two&nbsp;is&nbsp;left&nbsp;up&nbsp;to&nbsp;the&nbsp;implementer<br>
-of&nbsp;the&nbsp;method.</tt></dd></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="TimelineModel-IsAsyncSlice"><strong>IsAsyncSlice</strong></a>(t)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-IsSliceOrAsyncSlice"><strong>IsSliceOrAsyncSlice</strong></a>(t)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.process.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.process.html
deleted file mode 100644
index e3bda6e..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.process.html
+++ /dev/null
@@ -1,139 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.process</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.process</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/process.py">telemetry/timeline/process.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.event_container.html">telemetry.timeline.event_container</a><br>
-<a href="telemetry.timeline.event.html">telemetry.timeline.event</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.memory_dump_event.html">telemetry.timeline.memory_dump_event</a><br>
-<a href="telemetry.timeline.counter.html">telemetry.timeline.counter</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.thread.html">telemetry.timeline.thread</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.process.html#Process">Process</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Process">class <strong>Process</strong></a>(<a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>The&nbsp;<a href="#Process">Process</a>&nbsp;represents&nbsp;a&nbsp;single&nbsp;userland&nbsp;process&nbsp;in&nbsp;the&nbsp;trace.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.process.html#Process">Process</a></dd>
-<dd><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Process-AddMemoryDumpEvent"><strong>AddMemoryDumpEvent</strong></a>(self, memory_dump)</dt><dd><tt>Add&nbsp;a&nbsp;ProcessMemoryDumpEvent&nbsp;to&nbsp;this&nbsp;process.</tt></dd></dl>
-
-<dl><dt><a name="Process-AutoCloseOpenSlices"><strong>AutoCloseOpenSlices</strong></a>(self, max_timestamp, thread_time_bounds)</dt></dl>
-
-<dl><dt><a name="Process-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Process-GetCounter"><strong>GetCounter</strong></a>(self, category, name)</dt></dl>
-
-<dl><dt><a name="Process-GetOrCreateCounter"><strong>GetOrCreateCounter</strong></a>(self, category, name)</dt></dl>
-
-<dl><dt><a name="Process-GetOrCreateThread"><strong>GetOrCreateThread</strong></a>(self, tid)</dt></dl>
-
-<dl><dt><a name="Process-IterChildContainers"><strong>IterChildContainers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Process-IterEventsInThisContainer"><strong>IterEventsInThisContainer</strong></a>(self, event_type_predicate, event_predicate)</dt></dl>
-
-<dl><dt><a name="Process-SetTraceBufferOverflowTimestamp"><strong>SetTraceBufferOverflowTimestamp</strong></a>(self, timestamp)</dt></dl>
-
-<dl><dt><a name="Process-__init__"><strong>__init__</strong></a>(self, parent, pid)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>counters</strong></dt>
-</dl>
-<dl><dt><strong>threads</strong></dt>
-</dl>
-<dl><dt><strong>trace_buffer_did_overflow</strong></dt>
-</dl>
-<dl><dt><strong>trace_buffer_overflow_event</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="Process-GetAllEvents"><strong>GetAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;List&nbsp;versions.&nbsp;These&nbsp;should&nbsp;always&nbsp;be&nbsp;simple&nbsp;expressions&nbsp;that&nbsp;list()&nbsp;on<br>
-#&nbsp;an&nbsp;underlying&nbsp;iter&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="Process-GetAllEventsOfName"><strong>GetAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-GetAllToplevelSlicesOfName"><strong>GetAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllAsyncSlicesOfName"><strong>IterAllAsyncSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllAsyncSlicesStartsWithName"><strong>IterAllAsyncSlicesStartsWithName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllEvents"><strong>IterAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>, event_type_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, event_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Iterates&nbsp;all&nbsp;events&nbsp;in&nbsp;this&nbsp;container,&nbsp;pre-filtered&nbsp;by&nbsp;two&nbsp;predicates.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;object,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])</tt></dd></dl>
-
-<dl><dt><a name="Process-IterAllEventsOfName"><strong>IterAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;Helper&nbsp;functions&nbsp;for&nbsp;finding&nbsp;common&nbsp;kinds&nbsp;of&nbsp;events.&nbsp;Must&nbsp;always&nbsp;take&nbsp;an<br>
-#&nbsp;optinal&nbsp;recurisve&nbsp;parameter&nbsp;and&nbsp;be&nbsp;implemented&nbsp;in&nbsp;terms&nbsp;fo&nbsp;IterAllEvents.</tt></dd></dl>
-
-<dl><dt><a name="Process-IterAllFlowEvents"><strong>IterAllFlowEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllSlices"><strong>IterAllSlices</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllSlicesInRange"><strong>IterAllSlicesInRange</strong></a>(self, start, end, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllSlicesOfName"><strong>IterAllSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Process-IterAllToplevelSlicesOfName"><strong>IterAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="Process-IsAsyncSlice"><strong>IsAsyncSlice</strong></a>(t)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.sample.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.sample.html
deleted file mode 100644
index 2206d48..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.sample.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.sample</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.sample</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/sample.py">telemetry/timeline/sample.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.event.html">telemetry.timeline.event</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.sample.html#Sample">Sample</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Sample">class <strong>Sample</strong></a>(<a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;<a href="#Sample">Sample</a>&nbsp;represents&nbsp;a&nbsp;sample&nbsp;taken&nbsp;at&nbsp;an&nbsp;instant&nbsp;in&nbsp;time<br>
-plus&nbsp;parameters&nbsp;associated&nbsp;with&nbsp;that&nbsp;sample.<br>
-&nbsp;<br>
-NOTE:&nbsp;The&nbsp;<a href="#Sample">Sample</a>&nbsp;class&nbsp;implements&nbsp;the&nbsp;same&nbsp;interface&nbsp;as<br>
-Slice.&nbsp;These&nbsp;must&nbsp;be&nbsp;kept&nbsp;in&nbsp;sync.<br>
-&nbsp;<br>
-All&nbsp;time&nbsp;units&nbsp;are&nbsp;stored&nbsp;in&nbsp;milliseconds.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.sample.html#Sample">Sample</a></dd>
-<dd><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Sample-__init__"><strong>__init__</strong></a>(self, parent_thread, category, name, timestamp, args<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><a name="Sample-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>has_thread_timestamps</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-<dd><tt>Thread-specific&nbsp;CPU&nbsp;time&nbsp;when&nbsp;this&nbsp;event&nbsp;ended.<br>
-&nbsp;<br>
-May&nbsp;be&nbsp;None&nbsp;if&nbsp;the&nbsp;trace&nbsp;event&nbsp;didn't&nbsp;have&nbsp;thread&nbsp;time&nbsp;data.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.slice.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.slice.html
deleted file mode 100644
index 4e63552..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.slice.html
+++ /dev/null
@@ -1,103 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.slice</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.slice</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/slice.py">telemetry/timeline/slice.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.event.html">telemetry.timeline.event</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.slice.html#Slice">Slice</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Slice">class <strong>Slice</strong></a>(<a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;<a href="#Slice">Slice</a>&nbsp;represents&nbsp;an&nbsp;interval&nbsp;of&nbsp;time&nbsp;plus&nbsp;parameters&nbsp;associated<br>
-with&nbsp;that&nbsp;interval.<br>
-&nbsp;<br>
-NOTE:&nbsp;The&nbsp;Sample&nbsp;class&nbsp;implements&nbsp;the&nbsp;same&nbsp;interface&nbsp;as<br>
-<a href="#Slice">Slice</a>.&nbsp;These&nbsp;must&nbsp;be&nbsp;kept&nbsp;in&nbsp;sync.<br>
-&nbsp;<br>
-All&nbsp;time&nbsp;units&nbsp;are&nbsp;stored&nbsp;in&nbsp;milliseconds.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.slice.html#Slice">Slice</a></dd>
-<dd><a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Slice-AddSubSlice"><strong>AddSubSlice</strong></a>(self, sub_slice)</dt></dl>
-
-<dl><dt><a name="Slice-GetAllSubSlices"><strong>GetAllSubSlices</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Slice-GetAllSubSlicesOfName"><strong>GetAllSubSlicesOfName</strong></a>(self, name)</dt></dl>
-
-<dl><dt><a name="Slice-IterEventsInThisContainerRecrusively"><strong>IterEventsInThisContainerRecrusively</strong></a>(self, stack<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="Slice-__init__"><strong>__init__</strong></a>(self, parent_thread, category, name, timestamp, duration<font color="#909090">=0</font>, thread_timestamp<font color="#909090">=None</font>, thread_duration<font color="#909090">=None</font>, args<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>self_thread_time</strong></dt>
-<dd><tt>Thread&nbsp;(scheduled)&nbsp;time&nbsp;spent&nbsp;in&nbsp;this&nbsp;function&nbsp;less&nbsp;any&nbsp;thread&nbsp;time&nbsp;spent<br>
-in&nbsp;child&nbsp;events.&nbsp;Returns&nbsp;None&nbsp;if&nbsp;the&nbsp;slice&nbsp;or&nbsp;any&nbsp;of&nbsp;its&nbsp;children&nbsp;does&nbsp;not<br>
-have&nbsp;a&nbsp;thread_duration&nbsp;value.</tt></dd>
-</dl>
-<dl><dt><strong>self_time</strong></dt>
-<dd><tt>Time&nbsp;spent&nbsp;in&nbsp;this&nbsp;function&nbsp;less&nbsp;any&nbsp;time&nbsp;spent&nbsp;in&nbsp;child&nbsp;events.</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><a name="Slice-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event.html#TimelineEvent">telemetry.timeline.event.TimelineEvent</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>has_thread_timestamps</strong></dt>
-</dl>
-<dl><dt><strong>thread_end</strong></dt>
-<dd><tt>Thread-specific&nbsp;CPU&nbsp;time&nbsp;when&nbsp;this&nbsp;event&nbsp;ended.<br>
-&nbsp;<br>
-May&nbsp;be&nbsp;None&nbsp;if&nbsp;the&nbsp;trace&nbsp;event&nbsp;didn't&nbsp;have&nbsp;thread&nbsp;time&nbsp;data.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.surface_flinger_importer.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.surface_flinger_importer.html
deleted file mode 100644
index 0e98a27..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.surface_flinger_importer.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.surface_flinger_importer</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.surface_flinger_importer</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/surface_flinger_importer.py">telemetry/timeline/surface_flinger_importer.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.importer.html">telemetry.timeline.importer</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.surface_flinger_importer.html#SurfaceFlingerTimelineImporter">SurfaceFlingerTimelineImporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SurfaceFlingerTimelineImporter">class <strong>SurfaceFlingerTimelineImporter</strong></a>(<a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.surface_flinger_importer.html#SurfaceFlingerTimelineImporter">SurfaceFlingerTimelineImporter</a></dd>
-<dd><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SurfaceFlingerTimelineImporter-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt><dd><tt>Called&nbsp;by&nbsp;the&nbsp;Model&nbsp;after&nbsp;all&nbsp;other&nbsp;importers&nbsp;have&nbsp;imported&nbsp;their<br>
-events.</tt></dd></dl>
-
-<dl><dt><a name="SurfaceFlingerTimelineImporter-ImportEvents"><strong>ImportEvents</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SurfaceFlingerTimelineImporter-__init__"><strong>__init__</strong></a>(self, model, trace_data)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="SurfaceFlingerTimelineImporter-GetSupportedPart"><strong>GetSupportedPart</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.tab_id_importer.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.tab_id_importer.html
deleted file mode 100644
index 5eaad09..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.tab_id_importer.html
+++ /dev/null
@@ -1,138 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.tab_id_importer</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.tab_id_importer</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/tab_id_importer.py">telemetry/timeline/tab_id_importer.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.importer.html">telemetry.timeline.importer</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.tab_id_importer.html#TraceBufferOverflowException">TraceBufferOverflowException</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.tab_id_importer.html#TabIdImporter">TabIdImporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TabIdImporter">class <strong>TabIdImporter</strong></a>(<a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.tab_id_importer.html#TabIdImporter">TabIdImporter</a></dd>
-<dd><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TabIdImporter-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabIdImporter-ImportEvents"><strong>ImportEvents</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TabIdImporter-__init__"><strong>__init__</strong></a>(self, model, trace_data)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TabIdImporter-GetSupportedPart"><strong>GetSupportedPart</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceBufferOverflowException">class <strong>TraceBufferOverflowException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.tab_id_importer.html#TraceBufferOverflowException">TraceBufferOverflowException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TraceBufferOverflowException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TraceBufferOverflowException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TraceBufferOverflowException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TraceBufferOverflowException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TraceBufferOverflowException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.thread.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.thread.html
deleted file mode 100644
index 09b8513..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.thread.html
+++ /dev/null
@@ -1,168 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.thread</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.thread</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/thread.py">telemetry/timeline/thread.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.async_slice.html">telemetry.timeline.async_slice</a><br>
-<a href="telemetry.timeline.event_container.html">telemetry.timeline.event_container</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.flow_event.html">telemetry.timeline.flow_event</a><br>
-<a href="telemetry.timeline.sample.html">telemetry.timeline.sample</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.slice.html">telemetry.timeline.slice</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.thread.html#Thread">Thread</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Thread">class <strong>Thread</strong></a>(<a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;<a href="#Thread">Thread</a>&nbsp;stores&nbsp;all&nbsp;the&nbsp;trace&nbsp;events&nbsp;collected&nbsp;for&nbsp;a&nbsp;particular<br>
-thread.&nbsp;We&nbsp;organize&nbsp;the&nbsp;synchronous&nbsp;slices&nbsp;on&nbsp;a&nbsp;thread&nbsp;by&nbsp;"subrows,"&nbsp;where<br>
-subrow&nbsp;0&nbsp;has&nbsp;all&nbsp;the&nbsp;root&nbsp;slices,&nbsp;subrow&nbsp;1&nbsp;those&nbsp;nested&nbsp;1&nbsp;deep,&nbsp;and&nbsp;so&nbsp;on.<br>
-The&nbsp;asynchronous&nbsp;slices&nbsp;are&nbsp;stored&nbsp;in&nbsp;an&nbsp;AsyncSliceGroup&nbsp;object.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.thread.html#Thread">Thread</a></dd>
-<dd><a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="Thread-AddAsyncSlice"><strong>AddAsyncSlice</strong></a>(self, async_slice)</dt></dl>
-
-<dl><dt><a name="Thread-AddFlowEvent"><strong>AddFlowEvent</strong></a>(self, flow_event)</dt></dl>
-
-<dl><dt><a name="Thread-AddSample"><strong>AddSample</strong></a>(self, category, name, timestamp, args<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="Thread-AutoCloseOpenSlices"><strong>AutoCloseOpenSlices</strong></a>(self, max_timestamp, max_thread_timestamp)</dt></dl>
-
-<dl><dt><a name="Thread-BeginSlice"><strong>BeginSlice</strong></a>(self, category, name, timestamp, thread_timestamp<font color="#909090">=None</font>, args<font color="#909090">=None</font>)</dt><dd><tt>Opens&nbsp;a&nbsp;new&nbsp;slice&nbsp;for&nbsp;the&nbsp;thread.<br>
-Calls&nbsp;to&nbsp;beginSlice&nbsp;and&nbsp;endSlice&nbsp;must&nbsp;be&nbsp;made&nbsp;with<br>
-non-monotonically-decreasing&nbsp;timestamps.<br>
-&nbsp;<br>
-*&nbsp;category:&nbsp;Category&nbsp;to&nbsp;which&nbsp;the&nbsp;slice&nbsp;belongs.<br>
-*&nbsp;name:&nbsp;Name&nbsp;of&nbsp;the&nbsp;slice&nbsp;to&nbsp;add.<br>
-*&nbsp;timestamp:&nbsp;The&nbsp;timetsamp&nbsp;of&nbsp;the&nbsp;slice,&nbsp;in&nbsp;milliseconds.<br>
-*&nbsp;thread_timestamp:&nbsp;<a href="#Thread">Thread</a>&nbsp;specific&nbsp;clock&nbsp;(scheduled)&nbsp;timestamp&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;slice,&nbsp;in&nbsp;milliseconds.<br>
-*&nbsp;args:&nbsp;Arguments&nbsp;associated&nbsp;with<br>
-&nbsp;<br>
-Returns&nbsp;newly&nbsp;opened&nbsp;slice</tt></dd></dl>
-
-<dl><dt><a name="Thread-EndSlice"><strong>EndSlice</strong></a>(self, end_timestamp, end_thread_timestamp<font color="#909090">=None</font>)</dt><dd><tt>Ends&nbsp;the&nbsp;last&nbsp;begun&nbsp;slice&nbsp;in&nbsp;this&nbsp;group&nbsp;and&nbsp;pushes&nbsp;it&nbsp;onto&nbsp;the&nbsp;slice<br>
-array.<br>
-&nbsp;<br>
-*&nbsp;end_timestamp:&nbsp;Timestamp&nbsp;when&nbsp;the&nbsp;slice&nbsp;ended&nbsp;in&nbsp;milliseconds<br>
-*&nbsp;end_thread_timestamp:&nbsp;Timestamp&nbsp;when&nbsp;the&nbsp;scheduled&nbsp;time&nbsp;of&nbsp;the&nbsp;slice&nbsp;ended<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;in&nbsp;milliseconds<br>
-&nbsp;<br>
-returns&nbsp;completed&nbsp;slice.</tt></dd></dl>
-
-<dl><dt><a name="Thread-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Thread-IsTimestampValidForBeginOrEnd"><strong>IsTimestampValidForBeginOrEnd</strong></a>(self, timestamp)</dt></dl>
-
-<dl><dt><a name="Thread-IterChildContainers"><strong>IterChildContainers</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Thread-IterEventsInThisContainer"><strong>IterEventsInThisContainer</strong></a>(self, event_type_predicate, event_predicate)</dt></dl>
-
-<dl><dt><a name="Thread-PushCompleteSlice"><strong>PushCompleteSlice</strong></a>(self, category, name, timestamp, duration, thread_timestamp, thread_duration, args<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="Thread-PushSlice"><strong>PushSlice</strong></a>(self, new_slice)</dt></dl>
-
-<dl><dt><a name="Thread-__init__"><strong>__init__</strong></a>(self, process, tid)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>all_slices</strong></dt>
-</dl>
-<dl><dt><strong>async_slices</strong></dt>
-</dl>
-<dl><dt><strong>open_slice_count</strong></dt>
-</dl>
-<dl><dt><strong>samples</strong></dt>
-</dl>
-<dl><dt><strong>toplevel_slices</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="Thread-GetAllEvents"><strong>GetAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;List&nbsp;versions.&nbsp;These&nbsp;should&nbsp;always&nbsp;be&nbsp;simple&nbsp;expressions&nbsp;that&nbsp;list()&nbsp;on<br>
-#&nbsp;an&nbsp;underlying&nbsp;iter&nbsp;method.</tt></dd></dl>
-
-<dl><dt><a name="Thread-GetAllEventsOfName"><strong>GetAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-GetAllToplevelSlicesOfName"><strong>GetAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllAsyncSlicesOfName"><strong>IterAllAsyncSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllAsyncSlicesStartsWithName"><strong>IterAllAsyncSlicesStartsWithName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllEvents"><strong>IterAllEvents</strong></a>(self, recursive<font color="#909090">=True</font>, event_type_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>, event_predicate<font color="#909090">=&lt;function &lt;lambda&gt;&gt;</font>)</dt><dd><tt>Iterates&nbsp;all&nbsp;events&nbsp;in&nbsp;this&nbsp;container,&nbsp;pre-filtered&nbsp;by&nbsp;two&nbsp;predicates.<br>
-&nbsp;<br>
-Only&nbsp;events&nbsp;with&nbsp;a&nbsp;type&nbsp;matching&nbsp;event_type_predicate&nbsp;AND&nbsp;matching&nbsp;event<br>
-event_predicate&nbsp;will&nbsp;be&nbsp;yielded.<br>
-&nbsp;<br>
-event_type_predicate&nbsp;is&nbsp;given&nbsp;an&nbsp;actual&nbsp;type&nbsp;object,&nbsp;e.g.:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_type_predicate(slice_module.Slice)<br>
-&nbsp;<br>
-event_predicate&nbsp;is&nbsp;given&nbsp;actual&nbsp;events:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;event_predicate(thread.slices[7])</tt></dd></dl>
-
-<dl><dt><a name="Thread-IterAllEventsOfName"><strong>IterAllEventsOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt><dd><tt>#&nbsp;Helper&nbsp;functions&nbsp;for&nbsp;finding&nbsp;common&nbsp;kinds&nbsp;of&nbsp;events.&nbsp;Must&nbsp;always&nbsp;take&nbsp;an<br>
-#&nbsp;optinal&nbsp;recurisve&nbsp;parameter&nbsp;and&nbsp;be&nbsp;implemented&nbsp;in&nbsp;terms&nbsp;fo&nbsp;IterAllEvents.</tt></dd></dl>
-
-<dl><dt><a name="Thread-IterAllFlowEvents"><strong>IterAllFlowEvents</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllSlices"><strong>IterAllSlices</strong></a>(self, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllSlicesInRange"><strong>IterAllSlicesInRange</strong></a>(self, start, end, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllSlicesOfName"><strong>IterAllSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<dl><dt><a name="Thread-IterAllToplevelSlicesOfName"><strong>IterAllToplevelSlicesOfName</strong></a>(self, name, recursive<font color="#909090">=True</font>)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><a name="Thread-IsAsyncSlice"><strong>IsAsyncSlice</strong></a>(t)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.event_container.html#TimelineEventContainer">telemetry.timeline.event_container.TimelineEventContainer</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.trace_data.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.trace_data.html
deleted file mode 100644
index 26ed691..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.trace_data.html
+++ /dev/null
@@ -1,232 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.trace_data</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.trace_data</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/trace_data.py">telemetry/timeline/trace_data.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="json.html">json</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.trace_data.html#TraceData">TraceData</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.timeline.trace_data.html#TraceDataBuilder">TraceDataBuilder</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.timeline.trace_data.html#TraceDataPart">TraceDataPart</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.trace_data.html#NonSerializableTraceData">NonSerializableTraceData</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NonSerializableTraceData">class <strong>NonSerializableTraceData</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Raised&nbsp;when&nbsp;raw&nbsp;trace&nbsp;data&nbsp;cannot&nbsp;be&nbsp;serialized&nbsp;to&nbsp;<a href="#TraceData">TraceData</a>.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.trace_data.html#NonSerializableTraceData">NonSerializableTraceData</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="NonSerializableTraceData-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#NonSerializableTraceData-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="NonSerializableTraceData-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#NonSerializableTraceData-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="NonSerializableTraceData-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceData">class <strong>TraceData</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Validates,&nbsp;parses,&nbsp;and&nbsp;serializes&nbsp;raw&nbsp;data.<br>
-&nbsp;<br>
-NOTE:&nbsp;raw&nbsp;data&nbsp;must&nbsp;only&nbsp;include&nbsp;primitive&nbsp;objects!<br>
-By&nbsp;design,&nbsp;<a href="#TraceData">TraceData</a>&nbsp;must&nbsp;contain&nbsp;only&nbsp;data&nbsp;that&nbsp;is&nbsp;BOTH&nbsp;json-serializable<br>
-to&nbsp;a&nbsp;file,&nbsp;AND&nbsp;restorable&nbsp;once&nbsp;again&nbsp;from&nbsp;that&nbsp;file&nbsp;into&nbsp;<a href="#TraceData">TraceData</a>&nbsp;without<br>
-assistance&nbsp;from&nbsp;other&nbsp;classes.<br>
-&nbsp;<br>
-Raw&nbsp;data&nbsp;can&nbsp;be&nbsp;one&nbsp;of&nbsp;three&nbsp;standard&nbsp;trace_event&nbsp;formats:<br>
-1.&nbsp;Trace&nbsp;container&nbsp;format:&nbsp;a&nbsp;json-parseable&nbsp;dict.<br>
-2.&nbsp;A&nbsp;json-parseable&nbsp;array:&nbsp;assumed&nbsp;to&nbsp;be&nbsp;chrome&nbsp;trace&nbsp;data.<br>
-3.&nbsp;A&nbsp;json-parseable&nbsp;array&nbsp;missing&nbsp;the&nbsp;final&nbsp;']':&nbsp;assumed&nbsp;to&nbsp;be&nbsp;chrome&nbsp;trace<br>
-&nbsp;&nbsp;&nbsp;data.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TraceData-GetEventsFor"><strong>GetEventsFor</strong></a>(self, part)</dt></dl>
-
-<dl><dt><a name="TraceData-HasEventsFor"><strong>HasEventsFor</strong></a>(self, part)</dt></dl>
-
-<dl><dt><a name="TraceData-Serialize"><strong>Serialize</strong></a>(self, f, gzip_result<font color="#909090">=False</font>)</dt><dd><tt>Serializes&nbsp;the&nbsp;trace&nbsp;result&nbsp;to&nbsp;a&nbsp;file-like&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;<br>
-Always&nbsp;writes&nbsp;in&nbsp;the&nbsp;trace&nbsp;container&nbsp;format.</tt></dd></dl>
-
-<dl><dt><a name="TraceData-__init__"><strong>__init__</strong></a>(self, raw_data<font color="#909090">=None</font>)</dt><dd><tt>Creates&nbsp;<a href="#TraceData">TraceData</a>&nbsp;from&nbsp;the&nbsp;given&nbsp;data.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>active_parts</strong></dt>
-</dl>
-<dl><dt><strong>events_are_safely_mutable</strong></dt>
-<dd><tt>Returns&nbsp;true&nbsp;if&nbsp;the&nbsp;events&nbsp;in&nbsp;this&nbsp;value&nbsp;are&nbsp;completely&nbsp;sealed.<br>
-&nbsp;<br>
-Some&nbsp;importers&nbsp;want&nbsp;to&nbsp;take&nbsp;complex&nbsp;fields&nbsp;out&nbsp;of&nbsp;the&nbsp;TraceData&nbsp;and&nbsp;add<br>
-them&nbsp;to&nbsp;the&nbsp;model,&nbsp;changing&nbsp;them&nbsp;subtly&nbsp;as&nbsp;they&nbsp;do&nbsp;so.&nbsp;If&nbsp;the&nbsp;TraceData<br>
-was&nbsp;constructed&nbsp;with&nbsp;data&nbsp;that&nbsp;is&nbsp;shared&nbsp;with&nbsp;something&nbsp;outside&nbsp;the&nbsp;trace<br>
-data,&nbsp;for&nbsp;instance&nbsp;a&nbsp;test&nbsp;harness,&nbsp;then&nbsp;this&nbsp;mutation&nbsp;is&nbsp;unexpected.&nbsp;But,<br>
-if&nbsp;the&nbsp;values&nbsp;are&nbsp;sealed,&nbsp;then&nbsp;mutating&nbsp;the&nbsp;events&nbsp;is&nbsp;a&nbsp;lot&nbsp;faster.<br>
-&nbsp;<br>
-We&nbsp;know&nbsp;if&nbsp;events&nbsp;are&nbsp;sealed&nbsp;if&nbsp;the&nbsp;value&nbsp;came&nbsp;from&nbsp;a&nbsp;string,&nbsp;or&nbsp;if&nbsp;the<br>
-value&nbsp;came&nbsp;from&nbsp;a&nbsp;TraceDataBuilder.</tt></dd>
-</dl>
-<dl><dt><strong>metadata_records</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceDataBuilder">class <strong>TraceDataBuilder</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#TraceDataBuilder">TraceDataBuilder</a>&nbsp;helps&nbsp;build&nbsp;up&nbsp;a&nbsp;trace&nbsp;from&nbsp;multiple&nbsp;trace&nbsp;agents.<br>
-&nbsp;<br>
-<a href="#TraceData">TraceData</a>&nbsp;is&nbsp;supposed&nbsp;to&nbsp;be&nbsp;immutable,&nbsp;but&nbsp;it&nbsp;is&nbsp;useful&nbsp;during&nbsp;recording&nbsp;to<br>
-have&nbsp;a&nbsp;mutable&nbsp;version.&nbsp;That&nbsp;is&nbsp;<a href="#TraceDataBuilder">TraceDataBuilder</a>.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TraceDataBuilder-AddEventsTo"><strong>AddEventsTo</strong></a>(self, part, events)</dt><dd><tt>Note:&nbsp;this&nbsp;won't&nbsp;work&nbsp;when&nbsp;called&nbsp;from&nbsp;multiple&nbsp;browsers.<br>
-&nbsp;<br>
-Each&nbsp;browser's&nbsp;trace_event_impl&nbsp;zeros&nbsp;its&nbsp;timestamps&nbsp;when&nbsp;it&nbsp;writes&nbsp;them<br>
-out&nbsp;and&nbsp;doesn't&nbsp;write&nbsp;a&nbsp;timebase&nbsp;that&nbsp;can&nbsp;be&nbsp;used&nbsp;to&nbsp;re-sync&nbsp;them.</tt></dd></dl>
-
-<dl><dt><a name="TraceDataBuilder-AsData"><strong>AsData</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceDataBuilder-HasEventsFor"><strong>HasEventsFor</strong></a>(self, part)</dt></dl>
-
-<dl><dt><a name="TraceDataBuilder-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceDataPart">class <strong>TraceDataPart</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#TraceData">TraceData</a>&nbsp;can&nbsp;have&nbsp;a&nbsp;variety&nbsp;of&nbsp;events.<br>
-&nbsp;<br>
-These&nbsp;are&nbsp;called&nbsp;"parts"&nbsp;and&nbsp;are&nbsp;accessed&nbsp;by&nbsp;the&nbsp;following&nbsp;fixed&nbsp;field&nbsp;names.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TraceDataPart-__init__"><strong>__init__</strong></a>(self, raw_field_name)</dt></dl>
-
-<dl><dt><a name="TraceDataPart-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>raw_field_name</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ALL_TRACE_PARTS</strong> = set([TraceDataPart("traceEvents"), TraceDataPart("inspectorTimelineEvents"), TraceDataPart("surfaceFlinger"), TraceDataPart("tabIds")])<br>
-<strong>CHROME_TRACE_PART</strong> = TraceDataPart("traceEvents")<br>
-<strong>INSPECTOR_TRACE_PART</strong> = TraceDataPart("inspectorTimelineEvents")<br>
-<strong>SURFACE_FLINGER_PART</strong> = TraceDataPart("surfaceFlinger")<br>
-<strong>TAB_ID_PART</strong> = TraceDataPart("tabIds")</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.trace_event_importer.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.trace_event_importer.html
deleted file mode 100644
index 897503f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.trace_event_importer.html
+++ /dev/null
@@ -1,81 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.trace_event_importer</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.trace_event_importer</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/trace_event_importer.py">telemetry/timeline/trace_event_importer.py</a></font></td></tr></table>
-    <p><tt>TraceEventImporter&nbsp;imports&nbsp;TraceEvent-formatted&nbsp;data<br>
-into&nbsp;the&nbsp;provided&nbsp;model.<br>
-This&nbsp;is&nbsp;a&nbsp;port&nbsp;of&nbsp;the&nbsp;trace&nbsp;event&nbsp;importer&nbsp;from<br>
-https://code.google.com/p/trace-viewer/</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="copy.html">copy</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.importer.html">telemetry.timeline.importer</a><br>
-<a href="telemetry.timeline.memory_dump_event.html">telemetry.timeline.memory_dump_event</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-<a href="telemetry.timeline.async_slice.html">telemetry.timeline.async_slice</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.flow_event.html">telemetry.timeline.flow_event</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.trace_event_importer.html#TraceEventTimelineImporter">TraceEventTimelineImporter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceEventTimelineImporter">class <strong>TraceEventTimelineImporter</strong></a>(<a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.timeline.trace_event_importer.html#TraceEventTimelineImporter">TraceEventTimelineImporter</a></dd>
-<dd><a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TraceEventTimelineImporter-FinalizeImport"><strong>FinalizeImport</strong></a>(self)</dt><dd><tt>Called&nbsp;by&nbsp;the&nbsp;Model&nbsp;after&nbsp;all&nbsp;other&nbsp;importers&nbsp;have&nbsp;imported&nbsp;their<br>
-events.</tt></dd></dl>
-
-<dl><dt><a name="TraceEventTimelineImporter-ImportEvents"><strong>ImportEvents</strong></a>(self)</dt><dd><tt>Walks&nbsp;through&nbsp;the&nbsp;events_&nbsp;list&nbsp;and&nbsp;outputs&nbsp;the&nbsp;structures&nbsp;discovered&nbsp;to<br>
-model_.</tt></dd></dl>
-
-<dl><dt><a name="TraceEventTimelineImporter-__init__"><strong>__init__</strong></a>(self, model, trace_data)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TraceEventTimelineImporter-GetSupportedPart"><strong>GetSupportedPart</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.timeline.importer.html#TimelineImporter">telemetry.timeline.importer.TimelineImporter</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_category_filter.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_category_filter.html
deleted file mode 100644
index 2d4bea6..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_category_filter.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.tracing_category_filter</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.tracing_category_filter</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/tracing_category_filter.py">telemetry/timeline/tracing_category_filter.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.tracing_category_filter.html#TracingCategoryFilter">TracingCategoryFilter</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingCategoryFilter">class <strong>TracingCategoryFilter</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;set&nbsp;of&nbsp;included&nbsp;and&nbsp;excluded&nbsp;categories&nbsp;that&nbsp;should&nbsp;be&nbsp;traced.<br>
-&nbsp;<br>
-The&nbsp;TraceCategoryFilter&nbsp;allows&nbsp;fine&nbsp;tuning&nbsp;of&nbsp;what&nbsp;data&nbsp;is&nbsp;traced.&nbsp;Basic<br>
-choice&nbsp;of&nbsp;which&nbsp;tracers&nbsp;to&nbsp;use&nbsp;is&nbsp;done&nbsp;by&nbsp;TracingOptions.<br>
-&nbsp;<br>
-Providing&nbsp;filter_string=None&nbsp;gives&nbsp;the&nbsp;default&nbsp;category&nbsp;filter,&nbsp;which&nbsp;leaves<br>
-what&nbsp;to&nbsp;trace&nbsp;up&nbsp;to&nbsp;the&nbsp;individual&nbsp;trace&nbsp;systems.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingCategoryFilter-AddExcludedCategory"><strong>AddExcludedCategory</strong></a>(self, category_glob)</dt><dd><tt>Explicitly&nbsp;disables&nbsp;anything&nbsp;matching&nbsp;category_glob.</tt></dd></dl>
-
-<dl><dt><a name="TracingCategoryFilter-AddIncludedCategory"><strong>AddIncludedCategory</strong></a>(self, category_glob)</dt><dd><tt>Explicitly&nbsp;enables&nbsp;anything&nbsp;matching&nbsp;category_glob.</tt></dd></dl>
-
-<dl><dt><a name="TracingCategoryFilter-AddSyntheticDelay"><strong>AddSyntheticDelay</strong></a>(self, delay)</dt></dl>
-
-<dl><dt><a name="TracingCategoryFilter-GetDictForChromeTracing"><strong>GetDictForChromeTracing</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingCategoryFilter-IsSubset"><strong>IsSubset</strong></a>(self, other)</dt><dd><tt>Determine&nbsp;if&nbsp;filter&nbsp;A&nbsp;(self)&nbsp;is&nbsp;a&nbsp;subset&nbsp;of&nbsp;filter&nbsp;B&nbsp;(other).<br>
-Returns&nbsp;True&nbsp;if&nbsp;A&nbsp;is&nbsp;a&nbsp;subset&nbsp;of&nbsp;B,&nbsp;False&nbsp;if&nbsp;A&nbsp;is&nbsp;not&nbsp;a&nbsp;subset&nbsp;of&nbsp;B,<br>
-and&nbsp;None&nbsp;if&nbsp;we&nbsp;can't&nbsp;tell&nbsp;for&nbsp;sure.</tt></dd></dl>
-
-<dl><dt><a name="TracingCategoryFilter-__init__"><strong>__init__</strong></a>(self, filter_string<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>disabled_by_default_categories</strong></dt>
-</dl>
-<dl><dt><strong>excluded_categories</strong></dt>
-</dl>
-<dl><dt><strong>filter_string</strong></dt>
-</dl>
-<dl><dt><strong>included_categories</strong></dt>
-</dl>
-<dl><dt><strong>stable_filter_string</strong></dt>
-</dl>
-<dl><dt><strong>synthetic_delays</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-CreateDebugOverheadFilter"><strong>CreateDebugOverheadFilter</strong></a>()</dt><dd><tt>Returns&nbsp;a&nbsp;filter&nbsp;with&nbsp;as&nbsp;many&nbsp;traces&nbsp;enabled&nbsp;as&nbsp;is&nbsp;useful.</tt></dd></dl>
- <dl><dt><a name="-CreateMinimalOverheadFilter"><strong>CreateMinimalOverheadFilter</strong></a>()</dt><dd><tt>Returns&nbsp;a&nbsp;filter&nbsp;with&nbsp;the&nbsp;best-effort&nbsp;amount&nbsp;of&nbsp;overhead.</tt></dd></dl>
- <dl><dt><a name="-CreateNoOverheadFilter"><strong>CreateNoOverheadFilter</strong></a>()</dt><dd><tt>Returns&nbsp;a&nbsp;filter&nbsp;with&nbsp;the&nbsp;least&nbsp;overhead&nbsp;possible.<br>
-&nbsp;<br>
-This&nbsp;contains&nbsp;no&nbsp;sub-traces&nbsp;of&nbsp;thread&nbsp;tasks,&nbsp;so&nbsp;it's&nbsp;only&nbsp;useful&nbsp;for<br>
-capturing&nbsp;the&nbsp;cpu-time&nbsp;spent&nbsp;on&nbsp;threads&nbsp;(as&nbsp;well&nbsp;as&nbsp;needed&nbsp;benchmark<br>
-traces).<br>
-&nbsp;<br>
-FIXME:&nbsp;Remove&nbsp;webkit.console&nbsp;when&nbsp;blink.console&nbsp;lands&nbsp;in&nbsp;chromium&nbsp;and<br>
-the&nbsp;ref&nbsp;builds&nbsp;are&nbsp;updated.&nbsp;crbug.com/386847</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_config.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_config.html
deleted file mode 100644
index 2208080..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_config.html
+++ /dev/null
@@ -1,69 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.tracing_config</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.tracing_config</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/tracing_config.py">telemetry/timeline/tracing_config.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="json.html">json</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.tracing_config.html#TracingConfig">TracingConfig</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingConfig">class <strong>TracingConfig</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Tracing&nbsp;config&nbsp;is&nbsp;the&nbsp;configuration&nbsp;for&nbsp;Chrome&nbsp;tracing.<br>
-&nbsp;<br>
-This&nbsp;produces&nbsp;the&nbsp;trace&nbsp;config&nbsp;JSON&nbsp;string&nbsp;for&nbsp;Chrome&nbsp;tracing.&nbsp;For&nbsp;the&nbsp;details<br>
-about&nbsp;the&nbsp;JSON&nbsp;string&nbsp;format,&nbsp;see&nbsp;base/trace_event/trace_config.h.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingConfig-GetTraceConfigJsonString"><strong>GetTraceConfigJsonString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingConfig-__init__"><strong>__init__</strong></a>(self, tracing_options, tracing_category_filter)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>tracing_category_filter</strong></dt>
-</dl>
-<dl><dt><strong>tracing_options</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_options.html b/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_options.html
deleted file mode 100644
index 9db89e5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.timeline.tracing_options.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.timeline.tracing_options</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.timeline.html"><font color="#ffffff">timeline</font></a>.tracing_options</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/timeline/tracing_options.py">telemetry/timeline/tracing_options.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.timeline.tracing_options.html#TracingOptions">TracingOptions</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TracingOptions">class <strong>TracingOptions</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Tracing&nbsp;options&nbsp;control&nbsp;which&nbsp;core&nbsp;tracing&nbsp;systems&nbsp;should&nbsp;be&nbsp;enabled.<br>
-&nbsp;<br>
-This&nbsp;simply&nbsp;turns&nbsp;on&nbsp;those&nbsp;systems.&nbsp;If&nbsp;those&nbsp;systems&nbsp;have&nbsp;additional&nbsp;options,<br>
-e.g.&nbsp;what&nbsp;to&nbsp;trace,&nbsp;then&nbsp;they&nbsp;are&nbsp;typically&nbsp;configured&nbsp;by&nbsp;adding<br>
-categories&nbsp;to&nbsp;the&nbsp;TracingCategoryFilter.<br>
-&nbsp;<br>
-Options:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;enable_chrome_trace:&nbsp;a&nbsp;boolean&nbsp;that&nbsp;specifies&nbsp;whether&nbsp;to&nbsp;enable<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;chrome&nbsp;tracing.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;enable_platform_display_trace:&nbsp;a&nbsp;boolean&nbsp;that&nbsp;specifies&nbsp;whether&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;platform&nbsp;display&nbsp;tracing.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;enable_android_graphics_memtrack:&nbsp;a&nbsp;boolean&nbsp;that&nbsp;specifies&nbsp;whether<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;to&nbsp;enable&nbsp;the&nbsp;memtrack_helper&nbsp;daemon&nbsp;to&nbsp;track&nbsp;graphics&nbsp;memory&nbsp;on<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Android&nbsp;(see&nbsp;goo.gl/4Y30p9).&nbsp;Doesn't&nbsp;have&nbsp;any&nbsp;effects&nbsp;on&nbsp;other&nbsp;OSs.<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;The&nbsp;following&nbsp;ones&nbsp;are&nbsp;specific&nbsp;to&nbsp;chrome&nbsp;tracing.&nbsp;See<br>
-&nbsp;&nbsp;&nbsp;&nbsp;base/trace_event/trace_config.h&nbsp;for&nbsp;more&nbsp;information.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record_mode:&nbsp;can&nbsp;be&nbsp;any&nbsp;mode&nbsp;in&nbsp;RECORD_MODES.&nbsp;This&nbsp;corresponds&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record&nbsp;modes&nbsp;in&nbsp;chrome.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;enable_systrace:&nbsp;a&nbsp;boolean&nbsp;that&nbsp;specifies&nbsp;whether&nbsp;to&nbsp;enable&nbsp;systrace.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TracingOptions-GetDictForChromeTracing"><strong>GetDictForChromeTracing</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TracingOptions-GetTraceOptionsStringForChromeDevtool"><strong>GetTraceOptionsStringForChromeDevtool</strong></a>(self)</dt><dd><tt>Map&nbsp;Chrome&nbsp;tracing&nbsp;options&nbsp;in&nbsp;Telemetry&nbsp;to&nbsp;the&nbsp;DevTools&nbsp;API&nbsp;string.</tt></dd></dl>
-
-<dl><dt><a name="TracingOptions-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>enable_systrace</strong></dt>
-</dl>
-<dl><dt><strong>record_mode</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ECHO_TO_CONSOLE</strong> = 'trace-to-console'<br>
-<strong>ENABLE_SYSTRACE</strong> = 'enable-systrace'<br>
-<strong>RECORD_AS_MUCH_AS_POSSIBLE</strong> = 'record-as-much-as-possible'<br>
-<strong>RECORD_CONTINUOUSLY</strong> = 'record-continuously'<br>
-<strong>RECORD_MODES</strong> = ['record-until-full', 'record-continuously', 'record-as-much-as-possible', 'trace-to-console']<br>
-<strong>RECORD_UNTIL_FULL</strong> = 'record-until-full'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.color_histogram.html b/catapult/telemetry/docs/pydoc/telemetry.util.color_histogram.html
deleted file mode 100644
index f52aaba..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.color_histogram.html
+++ /dev/null
@@ -1,159 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.color_histogram</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.color_histogram</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/color_histogram.py">telemetry/util/color_histogram.py</a></font></td></tr></table>
-    <p><tt>Color&nbsp;Histograms&nbsp;and&nbsp;implementations&nbsp;of&nbsp;functions&nbsp;operating&nbsp;on&nbsp;them.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-</td><td width="25%" valign=top><a href="numpy.html">numpy</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial">ColorHistogram(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.util.color_histogram.html#ColorHistogram">ColorHistogram</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ColorHistogram">class <strong>ColorHistogram</strong></a>(ColorHistogram)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.util.color_histogram.html#ColorHistogram">ColorHistogram</a></dd>
-<dd>ColorHistogram</dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ColorHistogram-Distance"><strong>Distance</strong></a>(self, other)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="ColorHistogram-__new__"><strong>__new__</strong></a>(cls, r, g, b, default_color<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from ColorHistogram:<br>
-<dl><dt><a name="ColorHistogram-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;tuple.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#ColorHistogram">ColorHistogram</a>&nbsp;object&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods inherited from ColorHistogram:<br>
-<dl><dt><a name="ColorHistogram-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#ColorHistogram">ColorHistogram</a>&nbsp;object&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from ColorHistogram:<br>
-<dl><dt><strong>b</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;2</tt></dd>
-</dl>
-<dl><dt><strong>default_color</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;3</tt></dd>
-</dl>
-<dl><dt><strong>g</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<dl><dt><strong>r</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from ColorHistogram:<br>
-<dl><dt><strong>_fields</strong> = ('r', 'g', 'b', 'default_color')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="ColorHistogram-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#ColorHistogram-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#ColorHistogram-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#ColorHistogram-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ColorHistogram-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#ColorHistogram-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-HistogramDistance"><strong>HistogramDistance</strong></a>(hist1, hist2, default_color<font color="#909090">=None</font>)</dt><dd><tt>Earth&nbsp;mover's&nbsp;distance.<br>
-<a href="http://en.wikipedia.org/wiki/Earth_mover's_distance">http://en.wikipedia.org/wiki/Earth_mover's_distance</a></tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>division</strong> = _Feature((2, 2, 0, 'alpha', 2), (3, 0, 0, 'alpha', 0), 8192)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.html b/catapult/telemetry/docs/pydoc/telemetry.util.html
deleted file mode 100644
index b8777e7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.html
+++ /dev/null
@@ -1,36 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/__init__.py">telemetry/util/__init__.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;library&nbsp;for&nbsp;bootstrapping&nbsp;Telemetry&nbsp;preformance&nbsp;testing.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.util.color_histogram.html">color_histogram</a><br>
-<a href="telemetry.util.color_histogram_unittest.html">color_histogram_unittest</a><br>
-<a href="telemetry.util.image_util.html">image_util</a><br>
-<a href="telemetry.util.image_util_unittest.html">image_util_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.mac.html"><strong>mac</strong>&nbsp;(package)</a><br>
-<a href="telemetry.util.perf_result_data_type.html">perf_result_data_type</a><br>
-<a href="telemetry.util.perf_tests_helper.html">perf_tests_helper</a><br>
-<a href="telemetry.util.perf_tests_results_helper.html">perf_tests_results_helper</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.process_statistic_timeline_data.html">process_statistic_timeline_data</a><br>
-<a href="telemetry.util.process_statistic_timeline_data_unittest.html">process_statistic_timeline_data_unittest</a><br>
-<a href="telemetry.util.rgba_color.html">rgba_color</a><br>
-<a href="telemetry.util.statistics.html">statistics</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.statistics_unittest.html">statistics_unittest</a><br>
-<a href="telemetry.util.wpr_modes.html">wpr_modes</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.image_util.html b/catapult/telemetry/docs/pydoc/telemetry.util.image_util.html
deleted file mode 100644
index 6e94ebe..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.image_util.html
+++ /dev/null
@@ -1,90 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.image_util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.image_util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/image_util.py">telemetry/util/image_util.py</a></font></td></tr></table>
-    <p><tt>Provides&nbsp;implementations&nbsp;of&nbsp;basic&nbsp;image&nbsp;processing&nbsp;functions.<br>
-&nbsp;<br>
-Implements&nbsp;basic&nbsp;image&nbsp;processing&nbsp;functions,&nbsp;such&nbsp;as&nbsp;reading/writing&nbsp;images,<br>
-cropping,&nbsp;finding&nbsp;the&nbsp;bounding&nbsp;box&nbsp;of&nbsp;a&nbsp;color&nbsp;and&nbsp;diffing&nbsp;images.<br>
-&nbsp;<br>
-When&nbsp;numpy&nbsp;is&nbsp;present,&nbsp;image_util_numpy_impl&nbsp;is&nbsp;used&nbsp;for&nbsp;the&nbsp;implementation&nbsp;of<br>
-this&nbsp;interface.&nbsp;The&nbsp;old&nbsp;bitmap&nbsp;implementation&nbsp;(image_util_bitmap_impl)&nbsp;is&nbsp;used<br>
-as&nbsp;a&nbsp;fallback&nbsp;when&nbsp;numpy&nbsp;is&nbsp;not&nbsp;present.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="base64.html">base64</a><br>
-<a href="telemetry.internal.util.external_modules.html">telemetry.internal.util.external_modules</a><br>
-</td><td width="25%" valign=top><a href="telemetry.internal.image_processing.image_util_numpy_impl.html">telemetry.internal.image_processing.image_util_numpy_impl</a><br>
-<a href="telemetry.internal.image_processing.image_util_numpy_impl.html">telemetry.internal.image_processing.image_util_numpy_impl</a><br>
-</td><td width="25%" valign=top><a href="numpy.html">numpy</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AreEqual"><strong>AreEqual</strong></a>(image1, image2, tolerance<font color="#909090">=0</font>, likely_equal<font color="#909090">=True</font>)</dt><dd><tt>Determines&nbsp;whether&nbsp;two&nbsp;images&nbsp;are&nbsp;identical&nbsp;within&nbsp;a&nbsp;given&nbsp;tolerance.<br>
-Setting&nbsp;likely_equal&nbsp;to&nbsp;False&nbsp;enables&nbsp;short-circuit&nbsp;equality&nbsp;testing,&nbsp;which<br>
-is&nbsp;about&nbsp;2-3x&nbsp;slower&nbsp;for&nbsp;equal&nbsp;images,&nbsp;but&nbsp;can&nbsp;be&nbsp;image&nbsp;height&nbsp;times&nbsp;faster<br>
-if&nbsp;the&nbsp;images&nbsp;are&nbsp;not&nbsp;equal.</tt></dd></dl>
- <dl><dt><a name="-Channels"><strong>Channels</strong></a>(image)</dt><dd><tt>Number&nbsp;of&nbsp;color&nbsp;channels&nbsp;in&nbsp;the&nbsp;image.</tt></dd></dl>
- <dl><dt><a name="-Crop"><strong>Crop</strong></a>(image, left, top, width, height)</dt><dd><tt>Crops&nbsp;the&nbsp;current&nbsp;image&nbsp;down&nbsp;to&nbsp;the&nbsp;specified&nbsp;box.</tt></dd></dl>
- <dl><dt><a name="-Diff"><strong>Diff</strong></a>(image1, image2)</dt><dd><tt>Returns&nbsp;a&nbsp;new&nbsp;image&nbsp;that&nbsp;represents&nbsp;the&nbsp;difference&nbsp;between&nbsp;this&nbsp;image<br>
-and&nbsp;another&nbsp;image.</tt></dd></dl>
- <dl><dt><a name="-FromBase64Png"><strong>FromBase64Png</strong></a>(base64_png)</dt><dd><tt>Create&nbsp;an&nbsp;image&nbsp;from&nbsp;raw&nbsp;PNG&nbsp;data&nbsp;encoded&nbsp;in&nbsp;base64.</tt></dd></dl>
- <dl><dt><a name="-FromPng"><strong>FromPng</strong></a>(png_data)</dt><dd><tt>Create&nbsp;an&nbsp;image&nbsp;from&nbsp;raw&nbsp;PNG&nbsp;data.</tt></dd></dl>
- <dl><dt><a name="-FromPngFile"><strong>FromPngFile</strong></a>(path)</dt><dd><tt>Create&nbsp;an&nbsp;image&nbsp;from&nbsp;a&nbsp;PNG&nbsp;file.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;path:&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;PNG&nbsp;file.</tt></dd></dl>
- <dl><dt><a name="-FromRGBPixels"><strong>FromRGBPixels</strong></a>(width, height, pixels, bpp<font color="#909090">=3</font>)</dt><dd><tt>Create&nbsp;an&nbsp;image&nbsp;from&nbsp;an&nbsp;array&nbsp;of&nbsp;rgb&nbsp;pixels.<br>
-&nbsp;<br>
-Ignores&nbsp;alpha&nbsp;channel&nbsp;if&nbsp;present.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;width,&nbsp;height:&nbsp;int,&nbsp;the&nbsp;width&nbsp;and&nbsp;height&nbsp;of&nbsp;the&nbsp;image.<br>
-&nbsp;&nbsp;pixels:&nbsp;The&nbsp;flat&nbsp;array&nbsp;of&nbsp;pixels&nbsp;in&nbsp;the&nbsp;form&nbsp;of&nbsp;[r,g,b[,a],r,g,b[,a],...]<br>
-&nbsp;&nbsp;bpp:&nbsp;3&nbsp;for&nbsp;RGB,&nbsp;4&nbsp;for&nbsp;RGBA.</tt></dd></dl>
- <dl><dt><a name="-GetBoundingBox"><strong>GetBoundingBox</strong></a>(image, color, tolerance<font color="#909090">=0</font>)</dt><dd><tt>Finds&nbsp;the&nbsp;minimum&nbsp;box&nbsp;surrounding&nbsp;all&nbsp;occurrences&nbsp;of&nbsp;bgr&nbsp;|color|.<br>
-&nbsp;<br>
-Ignores&nbsp;the&nbsp;alpha&nbsp;channel.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;color:&nbsp;RbgaColor,&nbsp;bounding&nbsp;box&nbsp;color.<br>
-&nbsp;&nbsp;tolerance:&nbsp;int,&nbsp;per-channel&nbsp;tolerance&nbsp;for&nbsp;the&nbsp;bounding&nbsp;box&nbsp;color.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;(top,&nbsp;left,&nbsp;width,&nbsp;height),&nbsp;match_count</tt></dd></dl>
- <dl><dt><a name="-GetColorHistogram"><strong>GetColorHistogram</strong></a>(image, ignore_color<font color="#909090">=None</font>, tolerance<font color="#909090">=0</font>)</dt><dd><tt>Computes&nbsp;a&nbsp;histogram&nbsp;of&nbsp;the&nbsp;pixel&nbsp;colors&nbsp;in&nbsp;this&nbsp;image.<br>
-Args:<br>
-&nbsp;&nbsp;ignore_color:&nbsp;An&nbsp;RgbaColor&nbsp;to&nbsp;exclude&nbsp;from&nbsp;the&nbsp;bucket&nbsp;counts.<br>
-&nbsp;&nbsp;tolerance:&nbsp;A&nbsp;tolerance&nbsp;for&nbsp;the&nbsp;ignore_color.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;ColorHistogram&nbsp;namedtuple&nbsp;with&nbsp;256&nbsp;integers&nbsp;in&nbsp;each&nbsp;field:&nbsp;r,&nbsp;g,&nbsp;and&nbsp;b.</tt></dd></dl>
- <dl><dt><a name="-GetPixelColor"><strong>GetPixelColor</strong></a>(image, x, y)</dt><dd><tt>Returns&nbsp;a&nbsp;RgbaColor&nbsp;for&nbsp;the&nbsp;pixel&nbsp;at&nbsp;(x,&nbsp;y).</tt></dd></dl>
- <dl><dt><a name="-Height"><strong>Height</strong></a>(image)</dt><dd><tt>Height&nbsp;of&nbsp;the&nbsp;image.</tt></dd></dl>
- <dl><dt><a name="-Pixels"><strong>Pixels</strong></a>(image)</dt><dd><tt>Flat&nbsp;RGB&nbsp;pixel&nbsp;array&nbsp;of&nbsp;the&nbsp;image.</tt></dd></dl>
- <dl><dt><a name="-Width"><strong>Width</strong></a>(image)</dt><dd><tt>Width&nbsp;of&nbsp;the&nbsp;image.</tt></dd></dl>
- <dl><dt><a name="-WritePngFile"><strong>WritePngFile</strong></a>(image, path)</dt><dd><tt>Write&nbsp;an&nbsp;image&nbsp;to&nbsp;a&nbsp;PNG&nbsp;file.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;image:&nbsp;an&nbsp;image&nbsp;object.<br>
-&nbsp;&nbsp;path:&nbsp;The&nbsp;path&nbsp;to&nbsp;the&nbsp;PNG&nbsp;file.&nbsp;Must&nbsp;end&nbsp;in&nbsp;'png'&nbsp;or&nbsp;an<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AssertionError&nbsp;will&nbsp;be&nbsp;raised.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.mac.html b/catapult/telemetry/docs/pydoc/telemetry.util.mac.html
deleted file mode 100644
index 6d999cf..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.mac.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.util.mac</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.mac</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/mac/__init__.py">telemetry/util/mac/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.util.mac.keychain_helper.html">keychain_helper</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.mac.keychain_helper.html b/catapult/telemetry/docs/pydoc/telemetry.util.mac.keychain_helper.html
deleted file mode 100644
index 870469d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.mac.keychain_helper.html
+++ /dev/null
@@ -1,43 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.mac.keychain_helper</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.<a href="telemetry.util.mac.html"><font color="#ffffff">mac</font></a>.keychain_helper</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/mac/keychain_helper.py">telemetry/util/mac/keychain_helper.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.internal.util.binary_manager.html">telemetry.internal.util.binary_manager</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.os_version.html">telemetry.core.os_version</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.platform.html">telemetry.core.platform</a><br>
-</td><td width="25%" valign=top><a href="subprocess.html">subprocess</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-DoesKeychainHaveTimeout"><strong>DoesKeychainHaveTimeout</strong></a>()</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;keychain&nbsp;will&nbsp;lock&nbsp;itself&nbsp;have&nbsp;a&nbsp;period&nbsp;of&nbsp;time.<br>
-&nbsp;<br>
-This&nbsp;method&nbsp;will&nbsp;trigger&nbsp;a&nbsp;blocking,&nbsp;modal&nbsp;dialog&nbsp;if&nbsp;the&nbsp;keychain&nbsp;is<br>
-locked.</tt></dd></dl>
- <dl><dt><a name="-IsKeychainConfiguredForBotsWithChrome"><strong>IsKeychainConfiguredForBotsWithChrome</strong></a>()</dt></dl>
- <dl><dt><a name="-IsKeychainConfiguredForBotsWithChromium"><strong>IsKeychainConfiguredForBotsWithChromium</strong></a>()</dt></dl>
- <dl><dt><a name="-IsKeychainLocked"><strong>IsKeychainLocked</strong></a>()</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;keychain&nbsp;is&nbsp;locked,&nbsp;or&nbsp;if&nbsp;there&nbsp;is&nbsp;an&nbsp;error&nbsp;determining<br>
-the&nbsp;keychain&nbsp;state.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.perf_result_data_type.html b/catapult/telemetry/docs/pydoc/telemetry.util.perf_result_data_type.html
deleted file mode 100644
index 5265b99..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.perf_result_data_type.html
+++ /dev/null
@@ -1,38 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.perf_result_data_type</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.perf_result_data_type</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/perf_result_data_type.py">telemetry/util/perf_result_data_type.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-IsHistogram"><strong>IsHistogram</strong></a>(datatype)</dt></dl>
- <dl><dt><a name="-IsValidType"><strong>IsValidType</strong></a>(datatype)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ALL_TYPES</strong> = ['default', 'unimportant', 'histogram', 'unimportant-histogram', 'informational']<br>
-<strong>DEFAULT</strong> = 'default'<br>
-<strong>HISTOGRAM</strong> = 'histogram'<br>
-<strong>INFORMATIONAL</strong> = 'informational'<br>
-<strong>UNIMPORTANT</strong> = 'unimportant'<br>
-<strong>UNIMPORTANT_HISTOGRAM</strong> = 'unimportant-histogram'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.perf_tests_helper.html b/catapult/telemetry/docs/pydoc/telemetry.util.perf_tests_helper.html
deleted file mode 100644
index 6feac66..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.perf_tests_helper.html
+++ /dev/null
@@ -1,25 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.perf_tests_helper</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.perf_tests_helper</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/perf_tests_helper.py">telemetry/util/perf_tests_helper.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.util.perf_tests_results_helper.html">telemetry.util.perf_tests_results_helper</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.perf_tests_results_helper.html b/catapult/telemetry/docs/pydoc/telemetry.util.perf_tests_results_helper.html
deleted file mode 100644
index e8bb07b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.perf_tests_results_helper.html
+++ /dev/null
@@ -1,68 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.perf_tests_results_helper</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.perf_tests_results_helper</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/perf_tests_results_helper.py">telemetry/util/perf_tests_results_helper.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="json.html">json</a><br>
-<a href="math.html">math</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.perf_result_data_type.html">telemetry.util.perf_result_data_type</a><br>
-<a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-FlattenList"><strong>FlattenList</strong></a>(values)</dt><dd><tt>Returns&nbsp;a&nbsp;simple&nbsp;list&nbsp;without&nbsp;sub-lists.</tt></dd></dl>
- <dl><dt><a name="-GeomMeanAndStdDevFromHistogram"><strong>GeomMeanAndStdDevFromHistogram</strong></a>(histogram_json)</dt></dl>
- <dl><dt><a name="-PrintPages"><strong>PrintPages</strong></a>(page_list)</dt><dd><tt>Prints&nbsp;list&nbsp;of&nbsp;pages&nbsp;to&nbsp;stdout&nbsp;in&nbsp;the&nbsp;format&nbsp;required&nbsp;by&nbsp;perf&nbsp;tests.</tt></dd></dl>
- <dl><dt><a name="-PrintPerfResult"><strong>PrintPerfResult</strong></a>(measurement, trace, values, units, result_type<font color="#909090">='default'</font>, print_to_stdout<font color="#909090">=True</font>)</dt><dd><tt>Prints&nbsp;numerical&nbsp;data&nbsp;to&nbsp;stdout&nbsp;in&nbsp;the&nbsp;format&nbsp;required&nbsp;by&nbsp;perf&nbsp;tests.<br>
-&nbsp;<br>
-The&nbsp;string&nbsp;args&nbsp;may&nbsp;be&nbsp;empty&nbsp;but&nbsp;they&nbsp;must&nbsp;not&nbsp;contain&nbsp;any&nbsp;colons&nbsp;(:)&nbsp;or<br>
-equals&nbsp;signs&nbsp;(=).<br>
-This&nbsp;is&nbsp;parsed&nbsp;by&nbsp;the&nbsp;buildbot&nbsp;using:<br>
-<a href="http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/slave/process_log_utils.py">http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/slave/process_log_utils.py</a><br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;measurement:&nbsp;A&nbsp;description&nbsp;of&nbsp;the&nbsp;quantity&nbsp;being&nbsp;measured,&nbsp;e.g.&nbsp;"vm_peak".<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;the&nbsp;dashboard,&nbsp;this&nbsp;maps&nbsp;to&nbsp;a&nbsp;particular&nbsp;graph.&nbsp;Mandatory.<br>
-&nbsp;&nbsp;trace:&nbsp;A&nbsp;description&nbsp;of&nbsp;the&nbsp;particular&nbsp;data&nbsp;point,&nbsp;e.g.&nbsp;"reference".<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;On&nbsp;the&nbsp;dashboard,&nbsp;this&nbsp;maps&nbsp;to&nbsp;a&nbsp;particular&nbsp;"line"&nbsp;in&nbsp;the&nbsp;graph.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mandatory.<br>
-&nbsp;&nbsp;values:&nbsp;A&nbsp;list&nbsp;of&nbsp;numeric&nbsp;measured&nbsp;values.&nbsp;An&nbsp;N-dimensional&nbsp;list&nbsp;will&nbsp;be<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;flattened&nbsp;and&nbsp;treated&nbsp;as&nbsp;a&nbsp;simple&nbsp;list.<br>
-&nbsp;&nbsp;units:&nbsp;A&nbsp;description&nbsp;of&nbsp;the&nbsp;units&nbsp;of&nbsp;measure,&nbsp;e.g.&nbsp;"bytes".<br>
-&nbsp;&nbsp;result_type:&nbsp;Accepts&nbsp;values&nbsp;of&nbsp;perf_result_data_type.ALL_TYPES.<br>
-&nbsp;&nbsp;print_to_stdout:&nbsp;If&nbsp;True,&nbsp;prints&nbsp;the&nbsp;output&nbsp;in&nbsp;stdout&nbsp;instead&nbsp;of&nbsp;returning<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;output&nbsp;to&nbsp;caller.<br>
-&nbsp;<br>
-&nbsp;&nbsp;Returns:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;of&nbsp;the&nbsp;formated&nbsp;perf&nbsp;result.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>RESULT_TYPES</strong> = {'default': '*RESULT ', 'histogram': '*HISTOGRAM ', 'informational': '', 'unimportant': 'RESULT ', 'unimportant-histogram': 'HISTOGRAM '}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.process_statistic_timeline_data.html b/catapult/telemetry/docs/pydoc/telemetry.util.process_statistic_timeline_data.html
deleted file mode 100644
index 3695c0c..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.process_statistic_timeline_data.html
+++ /dev/null
@@ -1,114 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.process_statistic_timeline_data</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.process_statistic_timeline_data</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/process_statistic_timeline_data.py">telemetry/util/process_statistic_timeline_data.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.util.process_statistic_timeline_data.html#ProcessStatisticTimelineData">ProcessStatisticTimelineData</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.util.process_statistic_timeline_data.html#IdleWakeupTimelineData">IdleWakeupTimelineData</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IdleWakeupTimelineData">class <strong>IdleWakeupTimelineData</strong></a>(<a href="telemetry.util.process_statistic_timeline_data.html#ProcessStatisticTimelineData">ProcessStatisticTimelineData</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;<a href="#ProcessStatisticTimelineData">ProcessStatisticTimelineData</a>&nbsp;to&nbsp;hold&nbsp;idle&nbsp;wakeups.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.util.process_statistic_timeline_data.html#IdleWakeupTimelineData">IdleWakeupTimelineData</a></dd>
-<dd><a href="telemetry.util.process_statistic_timeline_data.html#ProcessStatisticTimelineData">ProcessStatisticTimelineData</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.util.process_statistic_timeline_data.html#ProcessStatisticTimelineData">ProcessStatisticTimelineData</a>:<br>
-<dl><dt><a name="IdleWakeupTimelineData-__add__"><strong>__add__</strong></a>(self, other)</dt><dd><tt>The&nbsp;result&nbsp;contains&nbsp;pids&nbsp;from&nbsp;both&nbsp;|self|&nbsp;and&nbsp;|other|,&nbsp;if&nbsp;duplicate<br>
-pids&nbsp;are&nbsp;found&nbsp;between&nbsp;objects,&nbsp;an&nbsp;error&nbsp;will&nbsp;occur.</tt></dd></dl>
-
-<dl><dt><a name="IdleWakeupTimelineData-__init__"><strong>__init__</strong></a>(self, pid, value)</dt></dl>
-
-<dl><dt><a name="IdleWakeupTimelineData-__sub__"><strong>__sub__</strong></a>(self, other)</dt><dd><tt>The&nbsp;results&nbsp;of&nbsp;subtraction&nbsp;is&nbsp;an&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;holding&nbsp;only&nbsp;the&nbsp;pids&nbsp;contained<br>
-in&nbsp;|self|.<br>
-&nbsp;<br>
-The&nbsp;motivation&nbsp;is&nbsp;that&nbsp;some&nbsp;processes&nbsp;may&nbsp;have&nbsp;died&nbsp;between&nbsp;two&nbsp;consecutive<br>
-measurements.&nbsp;The&nbsp;desired&nbsp;behavior&nbsp;is&nbsp;to&nbsp;only&nbsp;make&nbsp;calculations&nbsp;based&nbsp;on<br>
-the&nbsp;processes&nbsp;that&nbsp;are&nbsp;alive&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;second&nbsp;measurement.</tt></dd></dl>
-
-<dl><dt><a name="IdleWakeupTimelineData-total_sum"><strong>total_sum</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;sum&nbsp;of&nbsp;all&nbsp;values&nbsp;contained&nbsp;by&nbsp;this&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.util.process_statistic_timeline_data.html#ProcessStatisticTimelineData">ProcessStatisticTimelineData</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>value_by_pid</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ProcessStatisticTimelineData">class <strong>ProcessStatisticTimelineData</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Holds&nbsp;value&nbsp;of&nbsp;a&nbsp;stat&nbsp;for&nbsp;one&nbsp;or&nbsp;more&nbsp;processes.<br>
-&nbsp;<br>
-This&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;can&nbsp;hold&nbsp;a&nbsp;value&nbsp;for&nbsp;more&nbsp;than&nbsp;one&nbsp;pid&nbsp;by&nbsp;adding&nbsp;another<br>
-<a href="__builtin__.html#object">object</a>.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ProcessStatisticTimelineData-__add__"><strong>__add__</strong></a>(self, other)</dt><dd><tt>The&nbsp;result&nbsp;contains&nbsp;pids&nbsp;from&nbsp;both&nbsp;|self|&nbsp;and&nbsp;|other|,&nbsp;if&nbsp;duplicate<br>
-pids&nbsp;are&nbsp;found&nbsp;between&nbsp;objects,&nbsp;an&nbsp;error&nbsp;will&nbsp;occur.</tt></dd></dl>
-
-<dl><dt><a name="ProcessStatisticTimelineData-__init__"><strong>__init__</strong></a>(self, pid, value)</dt></dl>
-
-<dl><dt><a name="ProcessStatisticTimelineData-__sub__"><strong>__sub__</strong></a>(self, other)</dt><dd><tt>The&nbsp;results&nbsp;of&nbsp;subtraction&nbsp;is&nbsp;an&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;holding&nbsp;only&nbsp;the&nbsp;pids&nbsp;contained<br>
-in&nbsp;|self|.<br>
-&nbsp;<br>
-The&nbsp;motivation&nbsp;is&nbsp;that&nbsp;some&nbsp;processes&nbsp;may&nbsp;have&nbsp;died&nbsp;between&nbsp;two&nbsp;consecutive<br>
-measurements.&nbsp;The&nbsp;desired&nbsp;behavior&nbsp;is&nbsp;to&nbsp;only&nbsp;make&nbsp;calculations&nbsp;based&nbsp;on<br>
-the&nbsp;processes&nbsp;that&nbsp;are&nbsp;alive&nbsp;at&nbsp;the&nbsp;end&nbsp;of&nbsp;the&nbsp;second&nbsp;measurement.</tt></dd></dl>
-
-<dl><dt><a name="ProcessStatisticTimelineData-total_sum"><strong>total_sum</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;sum&nbsp;of&nbsp;all&nbsp;values&nbsp;contained&nbsp;by&nbsp;this&nbsp;<a href="__builtin__.html#object">object</a>.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>value_by_pid</strong></dt>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.rgba_color.html b/catapult/telemetry/docs/pydoc/telemetry.util.rgba_color.html
deleted file mode 100644
index 737d51f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.rgba_color.html
+++ /dev/null
@@ -1,160 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.rgba_color</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.rgba_color</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/rgba_color.py">telemetry/util/rgba_color.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial">RgbaColor(<a href="__builtin__.html#tuple">__builtin__.tuple</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.util.rgba_color.html#RgbaColor">RgbaColor</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RgbaColor">class <strong>RgbaColor</strong></a>(RgbaColor)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Encapsulates&nbsp;an&nbsp;RGBA&nbsp;color&nbsp;retrieved&nbsp;from&nbsp;an&nbsp;image.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.util.rgba_color.html#RgbaColor">RgbaColor</a></dd>
-<dd>RgbaColor</dd>
-<dd><a href="__builtin__.html#tuple">__builtin__.tuple</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="RgbaColor-AssertIsRGB"><strong>AssertIsRGB</strong></a>(self, r, g, b, tolerance<font color="#909090">=0</font>)</dt></dl>
-
-<dl><dt><a name="RgbaColor-AssertIsRGBA"><strong>AssertIsRGBA</strong></a>(self, r, g, b, a, tolerance<font color="#909090">=0</font>)</dt></dl>
-
-<dl><dt><a name="RgbaColor-IsEqual"><strong>IsEqual</strong></a>(self, expected_color, tolerance<font color="#909090">=0</font>)</dt><dd><tt>Verifies&nbsp;that&nbsp;the&nbsp;color&nbsp;is&nbsp;within&nbsp;a&nbsp;given&nbsp;tolerance&nbsp;of<br>
-the&nbsp;expected&nbsp;color.</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__int__"><strong>__int__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="RgbaColor-__new__"><strong>__new__</strong></a>(cls, r, g, b, a<font color="#909090">=255</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from RgbaColor:<br>
-<dl><dt><a name="RgbaColor-__getnewargs__"><strong>__getnewargs__</strong></a>(self)</dt><dd><tt>Return&nbsp;self&nbsp;as&nbsp;a&nbsp;plain&nbsp;tuple.&nbsp;&nbsp;Used&nbsp;by&nbsp;copy&nbsp;and&nbsp;pickle.</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__getstate__"><strong>__getstate__</strong></a>(self)</dt><dd><tt>Exclude&nbsp;the&nbsp;OrderedDict&nbsp;from&nbsp;pickling</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__repr__"><strong>__repr__</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;nicely&nbsp;formatted&nbsp;representation&nbsp;string</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-_asdict"><strong>_asdict</strong></a>(self)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;OrderedDict&nbsp;which&nbsp;maps&nbsp;field&nbsp;names&nbsp;to&nbsp;their&nbsp;values</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-_replace"><strong>_replace</strong></a>(_self, **kwds)</dt><dd><tt>Return&nbsp;a&nbsp;new&nbsp;<a href="#RgbaColor">RgbaColor</a>&nbsp;object&nbsp;replacing&nbsp;specified&nbsp;fields&nbsp;with&nbsp;new&nbsp;values</tt></dd></dl>
-
-<hr>
-Class methods inherited from RgbaColor:<br>
-<dl><dt><a name="RgbaColor-_make"><strong>_make</strong></a>(cls, iterable, new<font color="#909090">=&lt;built-in method __new__ of type object&gt;</font>, len<font color="#909090">=&lt;built-in function len&gt;</font>)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Make&nbsp;a&nbsp;new&nbsp;<a href="#RgbaColor">RgbaColor</a>&nbsp;object&nbsp;from&nbsp;a&nbsp;sequence&nbsp;or&nbsp;iterable</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from RgbaColor:<br>
-<dl><dt><strong>a</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;3</tt></dd>
-</dl>
-<dl><dt><strong>b</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;2</tt></dd>
-</dl>
-<dl><dt><strong>g</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;1</tt></dd>
-</dl>
-<dl><dt><strong>r</strong></dt>
-<dd><tt>Alias&nbsp;for&nbsp;field&nbsp;number&nbsp;0</tt></dd>
-</dl>
-<hr>
-Data and other attributes inherited from RgbaColor:<br>
-<dl><dt><strong>_fields</strong> = ('r', 'g', 'b', 'a')</dl>
-
-<hr>
-Methods inherited from <a href="__builtin__.html#tuple">__builtin__.tuple</a>:<br>
-<dl><dt><a name="RgbaColor-__add__"><strong>__add__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__add__">__add__</a>(y)&nbsp;&lt;==&gt;&nbsp;x+y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__contains__"><strong>__contains__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__contains__">__contains__</a>(y)&nbsp;&lt;==&gt;&nbsp;y&nbsp;in&nbsp;x</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__eq__"><strong>__eq__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__eq__">__eq__</a>(y)&nbsp;&lt;==&gt;&nbsp;x==y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__ge__"><strong>__ge__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__ge__">__ge__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;=y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__gt__"><strong>__gt__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__gt__">__gt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&gt;y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__hash__"><strong>__hash__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__hash__">__hash__</a>()&nbsp;&lt;==&gt;&nbsp;hash(x)</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__iter__"><strong>__iter__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__iter__">__iter__</a>()&nbsp;&lt;==&gt;&nbsp;iter(x)</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__le__"><strong>__le__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__le__">__le__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;=y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__len__"><strong>__len__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__len__">__len__</a>()&nbsp;&lt;==&gt;&nbsp;len(x)</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__lt__"><strong>__lt__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__lt__">__lt__</a>(y)&nbsp;&lt;==&gt;&nbsp;x&lt;y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__mul__"><strong>__mul__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__mul__">__mul__</a>(n)&nbsp;&lt;==&gt;&nbsp;x*n</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__ne__"><strong>__ne__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__ne__">__ne__</a>(y)&nbsp;&lt;==&gt;&nbsp;x!=y</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__rmul__"><strong>__rmul__</strong></a>(...)</dt><dd><tt>x.<a href="#RgbaColor-__rmul__">__rmul__</a>(n)&nbsp;&lt;==&gt;&nbsp;n*x</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-__sizeof__"><strong>__sizeof__</strong></a>(...)</dt><dd><tt>T.<a href="#RgbaColor-__sizeof__">__sizeof__</a>()&nbsp;--&nbsp;size&nbsp;of&nbsp;T&nbsp;in&nbsp;memory,&nbsp;in&nbsp;bytes</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-count"><strong>count</strong></a>(...)</dt><dd><tt>T.<a href="#RgbaColor-count">count</a>(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="RgbaColor-index"><strong>index</strong></a>(...)</dt><dd><tt>T.<a href="#RgbaColor-index">index</a>(value,&nbsp;[start,&nbsp;[stop]])&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;first&nbsp;index&nbsp;of&nbsp;value.<br>
-Raises&nbsp;ValueError&nbsp;if&nbsp;the&nbsp;value&nbsp;is&nbsp;not&nbsp;present.</tt></dd></dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>WEB_PAGE_TEST_ORANGE</strong> = RgbaColor(r=222, g=100, b=13, a=255)<br>
-<strong>WHITE</strong> = RgbaColor(r=255, g=255, b=255, a=255)</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.statistics.html b/catapult/telemetry/docs/pydoc/telemetry.util.statistics.html
deleted file mode 100644
index 5f939a5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.statistics.html
+++ /dev/null
@@ -1,137 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.statistics</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.statistics</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/statistics.py">telemetry/util/statistics.py</a></font></td></tr></table>
-    <p><tt>A&nbsp;collection&nbsp;of&nbsp;statistical&nbsp;utility&nbsp;functions&nbsp;to&nbsp;be&nbsp;used&nbsp;by&nbsp;metrics.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="math.html">math</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ArithmeticMean"><strong>ArithmeticMean</strong></a>(data)</dt><dd><tt>Calculates&nbsp;arithmetic&nbsp;mean.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;data:&nbsp;A&nbsp;list&nbsp;of&nbsp;samples.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;arithmetic&nbsp;mean&nbsp;value,&nbsp;or&nbsp;0&nbsp;if&nbsp;the&nbsp;list&nbsp;is&nbsp;empty.</tt></dd></dl>
- <dl><dt><a name="-Clamp"><strong>Clamp</strong></a>(value, low<font color="#909090">=0.0</font>, high<font color="#909090">=1.0</font>)</dt><dd><tt>Clamp&nbsp;a&nbsp;value&nbsp;between&nbsp;some&nbsp;low&nbsp;and&nbsp;high&nbsp;value.</tt></dd></dl>
- <dl><dt><a name="-Discrepancy"><strong>Discrepancy</strong></a>(samples, location_count<font color="#909090">=None</font>)</dt><dd><tt>Computes&nbsp;the&nbsp;discrepancy&nbsp;of&nbsp;a&nbsp;set&nbsp;of&nbsp;1D&nbsp;samples&nbsp;from&nbsp;the&nbsp;interval&nbsp;[0,1].<br>
-&nbsp;<br>
-The&nbsp;samples&nbsp;must&nbsp;be&nbsp;sorted.&nbsp;We&nbsp;define&nbsp;the&nbsp;discrepancy&nbsp;of&nbsp;an&nbsp;empty&nbsp;set<br>
-of&nbsp;samples&nbsp;to&nbsp;be&nbsp;zero.<br>
-&nbsp;<br>
-<a href="http://en.wikipedia.org/wiki/Low-discrepancy_sequence">http://en.wikipedia.org/wiki/Low-discrepancy_sequence</a><br>
-<a href="http://mathworld.wolfram.com/Discrepancy.html">http://mathworld.wolfram.com/Discrepancy.html</a></tt></dd></dl>
- <dl><dt><a name="-DivideIfPossibleOrZero"><strong>DivideIfPossibleOrZero</strong></a>(numerator, denominator)</dt><dd><tt>Returns&nbsp;the&nbsp;quotient,&nbsp;or&nbsp;zero&nbsp;if&nbsp;the&nbsp;denominator&nbsp;is&nbsp;zero.</tt></dd></dl>
- <dl><dt><a name="-DurationsDiscrepancy"><strong>DurationsDiscrepancy</strong></a>(durations, absolute<font color="#909090">=True</font>, location_count<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;discrepancy&nbsp;based&nbsp;metric&nbsp;for&nbsp;measuring&nbsp;duration&nbsp;jank.<br>
-&nbsp;<br>
-DurationsDiscrepancy&nbsp;computes&nbsp;a&nbsp;jank&nbsp;metric&nbsp;which&nbsp;measures&nbsp;how&nbsp;irregular&nbsp;a<br>
-given&nbsp;sequence&nbsp;of&nbsp;intervals&nbsp;is.&nbsp;In&nbsp;order&nbsp;to&nbsp;minimize&nbsp;jank,&nbsp;each&nbsp;duration<br>
-should&nbsp;be&nbsp;equally&nbsp;long.&nbsp;This&nbsp;is&nbsp;similar&nbsp;to&nbsp;how&nbsp;timestamp&nbsp;jank&nbsp;works,<br>
-and&nbsp;we&nbsp;therefore&nbsp;reuse&nbsp;the&nbsp;timestamp&nbsp;discrepancy&nbsp;function&nbsp;above&nbsp;to&nbsp;compute&nbsp;a<br>
-similar&nbsp;duration&nbsp;discrepancy&nbsp;number.<br>
-&nbsp;<br>
-Because&nbsp;timestamp&nbsp;discrepancy&nbsp;is&nbsp;defined&nbsp;in&nbsp;terms&nbsp;of&nbsp;timestamps,&nbsp;we&nbsp;first<br>
-convert&nbsp;the&nbsp;list&nbsp;of&nbsp;durations&nbsp;to&nbsp;monotonically&nbsp;increasing&nbsp;timestamps.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;durations:&nbsp;List&nbsp;of&nbsp;interval&nbsp;lengths&nbsp;in&nbsp;milliseconds.<br>
-&nbsp;&nbsp;absolute:&nbsp;See&nbsp;TimestampsDiscrepancy.<br>
-&nbsp;&nbsp;interval_multiplier:&nbsp;See&nbsp;TimestampsDiscrepancy.</tt></dd></dl>
- <dl><dt><a name="-GeneralizedMean"><strong>GeneralizedMean</strong></a>(values, exponent)</dt><dd><tt>See&nbsp;<a href="http://en.wikipedia.org/wiki/Generalized_mean">http://en.wikipedia.org/wiki/Generalized_mean</a></tt></dd></dl>
- <dl><dt><a name="-GeometricMean"><strong>GeometricMean</strong></a>(values)</dt><dd><tt>Compute&nbsp;a&nbsp;rounded&nbsp;geometric&nbsp;mean&nbsp;from&nbsp;an&nbsp;array&nbsp;of&nbsp;values.</tt></dd></dl>
- <dl><dt><a name="-Median"><strong>Median</strong></a>(values)</dt><dd><tt>Gets&nbsp;the&nbsp;median&nbsp;of&nbsp;a&nbsp;list&nbsp;of&nbsp;values.</tt></dd></dl>
- <dl><dt><a name="-NormalizeSamples"><strong>NormalizeSamples</strong></a>(samples)</dt><dd><tt>Sorts&nbsp;the&nbsp;samples,&nbsp;and&nbsp;map&nbsp;them&nbsp;linearly&nbsp;to&nbsp;the&nbsp;range&nbsp;[0,1].<br>
-&nbsp;<br>
-They're&nbsp;mapped&nbsp;such&nbsp;that&nbsp;for&nbsp;the&nbsp;N&nbsp;samples,&nbsp;the&nbsp;first&nbsp;sample&nbsp;is&nbsp;0.5/N&nbsp;and&nbsp;the<br>
-last&nbsp;sample&nbsp;is&nbsp;(N-0.5)/N.<br>
-&nbsp;<br>
-Background:&nbsp;The&nbsp;discrepancy&nbsp;of&nbsp;the&nbsp;sample&nbsp;set&nbsp;i/(N-1);&nbsp;i=0,&nbsp;...,&nbsp;N-1&nbsp;is&nbsp;2/N,<br>
-twice&nbsp;the&nbsp;discrepancy&nbsp;of&nbsp;the&nbsp;sample&nbsp;set&nbsp;(i+1/2)/N;&nbsp;i=0,&nbsp;...,&nbsp;N-1.&nbsp;In&nbsp;our&nbsp;case<br>
-we&nbsp;don't&nbsp;want&nbsp;to&nbsp;distinguish&nbsp;between&nbsp;these&nbsp;two&nbsp;cases,&nbsp;as&nbsp;our&nbsp;original&nbsp;domain<br>
-is&nbsp;not&nbsp;bounded&nbsp;(it&nbsp;is&nbsp;for&nbsp;Monte&nbsp;Carlo&nbsp;integration,&nbsp;where&nbsp;discrepancy&nbsp;was<br>
-first&nbsp;used).</tt></dd></dl>
- <dl><dt><a name="-Percentile"><strong>Percentile</strong></a>(values, percentile)</dt><dd><tt>Calculates&nbsp;the&nbsp;value&nbsp;below&nbsp;which&nbsp;a&nbsp;given&nbsp;percentage&nbsp;of&nbsp;values&nbsp;fall.<br>
-&nbsp;<br>
-For&nbsp;example,&nbsp;if&nbsp;17%&nbsp;of&nbsp;the&nbsp;values&nbsp;are&nbsp;less&nbsp;than&nbsp;5.0,&nbsp;then&nbsp;5.0&nbsp;is&nbsp;the&nbsp;17th<br>
-percentile&nbsp;for&nbsp;this&nbsp;set&nbsp;of&nbsp;values.&nbsp;When&nbsp;the&nbsp;percentage&nbsp;doesn't&nbsp;exactly<br>
-match&nbsp;a&nbsp;rank&nbsp;in&nbsp;the&nbsp;list&nbsp;of&nbsp;values,&nbsp;the&nbsp;percentile&nbsp;is&nbsp;computed&nbsp;using&nbsp;linear<br>
-interpolation&nbsp;between&nbsp;closest&nbsp;ranks.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;values:&nbsp;A&nbsp;list&nbsp;of&nbsp;numerical&nbsp;values.<br>
-&nbsp;&nbsp;percentile:&nbsp;A&nbsp;number&nbsp;between&nbsp;0&nbsp;and&nbsp;100.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;Nth&nbsp;percentile&nbsp;for&nbsp;the&nbsp;list&nbsp;of&nbsp;values,&nbsp;where&nbsp;N&nbsp;is&nbsp;the&nbsp;given&nbsp;percentage.</tt></dd></dl>
- <dl><dt><a name="-StandardDeviation"><strong>StandardDeviation</strong></a>(data)</dt><dd><tt>Calculates&nbsp;the&nbsp;standard&nbsp;deviation.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;data:&nbsp;A&nbsp;list&nbsp;of&nbsp;samples.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;standard&nbsp;deviation&nbsp;of&nbsp;the&nbsp;samples&nbsp;provided.</tt></dd></dl>
- <dl><dt><a name="-TimestampsDiscrepancy"><strong>TimestampsDiscrepancy</strong></a>(timestamps, absolute<font color="#909090">=True</font>, location_count<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;discrepancy&nbsp;based&nbsp;metric&nbsp;for&nbsp;measuring&nbsp;timestamp&nbsp;jank.<br>
-&nbsp;<br>
-TimestampsDiscrepancy&nbsp;quantifies&nbsp;the&nbsp;largest&nbsp;area&nbsp;of&nbsp;jank&nbsp;observed&nbsp;in&nbsp;a&nbsp;series<br>
-of&nbsp;timestamps.&nbsp;&nbsp;Note&nbsp;that&nbsp;this&nbsp;is&nbsp;different&nbsp;from&nbsp;metrics&nbsp;based&nbsp;on&nbsp;the<br>
-max_time_interval.&nbsp;For&nbsp;example,&nbsp;the&nbsp;time&nbsp;stamp&nbsp;series&nbsp;A&nbsp;=&nbsp;[0,1,2,3,5,6]&nbsp;and<br>
-B&nbsp;=&nbsp;[0,1,2,3,5,7]&nbsp;have&nbsp;the&nbsp;same&nbsp;max_time_interval&nbsp;=&nbsp;2,&nbsp;but<br>
-<a href="#-Discrepancy">Discrepancy</a>(B)&nbsp;&gt;&nbsp;<a href="#-Discrepancy">Discrepancy</a>(A).<br>
-&nbsp;<br>
-Two&nbsp;variants&nbsp;of&nbsp;discrepancy&nbsp;can&nbsp;be&nbsp;computed:<br>
-&nbsp;<br>
-Relative&nbsp;discrepancy&nbsp;is&nbsp;following&nbsp;the&nbsp;original&nbsp;definition&nbsp;of<br>
-discrepancy.&nbsp;It&nbsp;characterized&nbsp;the&nbsp;largest&nbsp;area&nbsp;of&nbsp;jank,&nbsp;relative&nbsp;to&nbsp;the<br>
-duration&nbsp;of&nbsp;the&nbsp;entire&nbsp;time&nbsp;stamp&nbsp;series.&nbsp;&nbsp;We&nbsp;normalize&nbsp;the&nbsp;raw&nbsp;results,<br>
-because&nbsp;the&nbsp;best&nbsp;case&nbsp;discrepancy&nbsp;for&nbsp;a&nbsp;set&nbsp;of&nbsp;N&nbsp;samples&nbsp;is&nbsp;1/N&nbsp;(for<br>
-equally&nbsp;spaced&nbsp;samples),&nbsp;and&nbsp;we&nbsp;want&nbsp;our&nbsp;metric&nbsp;to&nbsp;report&nbsp;0.0&nbsp;in&nbsp;that<br>
-case.<br>
-&nbsp;<br>
-Absolute&nbsp;discrepancy&nbsp;also&nbsp;characterizes&nbsp;the&nbsp;largest&nbsp;area&nbsp;of&nbsp;jank,&nbsp;but&nbsp;its<br>
-value&nbsp;wouldn't&nbsp;change&nbsp;(except&nbsp;for&nbsp;imprecisions&nbsp;due&nbsp;to&nbsp;a&nbsp;low<br>
-|interval_multiplier|)&nbsp;if&nbsp;additional&nbsp;'good'&nbsp;intervals&nbsp;were&nbsp;added&nbsp;to&nbsp;an<br>
-exisiting&nbsp;list&nbsp;of&nbsp;time&nbsp;stamps.&nbsp;&nbsp;Its&nbsp;range&nbsp;is&nbsp;[0,inf]&nbsp;and&nbsp;the&nbsp;unit&nbsp;is<br>
-milliseconds.<br>
-&nbsp;<br>
-The&nbsp;time&nbsp;stamp&nbsp;series&nbsp;C&nbsp;=&nbsp;[0,2,3,4]&nbsp;and&nbsp;D&nbsp;=&nbsp;[0,2,3,4,5]&nbsp;have&nbsp;the&nbsp;same<br>
-absolute&nbsp;discrepancy,&nbsp;but&nbsp;D&nbsp;has&nbsp;lower&nbsp;relative&nbsp;discrepancy&nbsp;than&nbsp;C.<br>
-&nbsp;<br>
-|timestamps|&nbsp;may&nbsp;be&nbsp;a&nbsp;list&nbsp;of&nbsp;lists&nbsp;S&nbsp;=&nbsp;[S_1,&nbsp;S_2,&nbsp;...,&nbsp;S_N],&nbsp;where&nbsp;each<br>
-S_i&nbsp;is&nbsp;a&nbsp;time&nbsp;stamp&nbsp;series.&nbsp;In&nbsp;that&nbsp;case,&nbsp;the&nbsp;discrepancy&nbsp;D(S)&nbsp;is:<br>
-D(S)&nbsp;=&nbsp;max(D(S_1),&nbsp;D(S_2),&nbsp;...,&nbsp;D(S_N))</tt></dd></dl>
- <dl><dt><a name="-Total"><strong>Total</strong></a>(data)</dt><dd><tt>Returns&nbsp;the&nbsp;float&nbsp;value&nbsp;of&nbsp;a&nbsp;number&nbsp;or&nbsp;the&nbsp;sum&nbsp;of&nbsp;a&nbsp;list.</tt></dd></dl>
- <dl><dt><a name="-TrapezoidalRule"><strong>TrapezoidalRule</strong></a>(data, dx)</dt><dd><tt>Calculate&nbsp;the&nbsp;integral&nbsp;according&nbsp;to&nbsp;the&nbsp;trapezoidal&nbsp;rule<br>
-&nbsp;<br>
-TrapezoidalRule&nbsp;approximates&nbsp;the&nbsp;definite&nbsp;integral&nbsp;of&nbsp;f&nbsp;from&nbsp;a&nbsp;to&nbsp;b&nbsp;by<br>
-the&nbsp;composite&nbsp;trapezoidal&nbsp;rule,&nbsp;using&nbsp;n&nbsp;subintervals.<br>
-<a href="http://en.wikipedia.org/wiki/Trapezoidal_rule#Uniform_grid">http://en.wikipedia.org/wiki/Trapezoidal_rule#Uniform_grid</a><br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;data:&nbsp;A&nbsp;list&nbsp;of&nbsp;samples<br>
-&nbsp;&nbsp;dx:&nbsp;The&nbsp;uniform&nbsp;distance&nbsp;along&nbsp;the&nbsp;x&nbsp;axis&nbsp;between&nbsp;any&nbsp;two&nbsp;samples<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;area&nbsp;under&nbsp;the&nbsp;curve&nbsp;defined&nbsp;by&nbsp;the&nbsp;samples&nbsp;and&nbsp;the&nbsp;uniform&nbsp;distance<br>
-&nbsp;&nbsp;according&nbsp;to&nbsp;the&nbsp;trapezoidal&nbsp;rule.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.util.wpr_modes.html b/catapult/telemetry/docs/pydoc/telemetry.util.wpr_modes.html
deleted file mode 100644
index dcbd842..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.util.wpr_modes.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.util.wpr_modes</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.util.html"><font color="#ffffff">util</font></a>.wpr_modes</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/util/wpr_modes.py">telemetry/util/wpr_modes.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2012&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>WPR_APPEND</strong> = 'wpr-append'<br>
-<strong>WPR_OFF</strong> = 'wpr-off'<br>
-<strong>WPR_RECORD</strong> = 'wpr-record'<br>
-<strong>WPR_REPLAY</strong> = 'wpr-replay'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.failure.html b/catapult/telemetry/docs/pydoc/telemetry.value.failure.html
deleted file mode 100644
index 68868c8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.failure.html
+++ /dev/null
@@ -1,151 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.failure</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.failure</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/failure.py">telemetry/value/failure.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="sys.html">sys</a><br>
-</td><td width="25%" valign=top><a href="traceback.html">traceback</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.html#Value">telemetry.value.Value</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.failure.html#FailureValue">FailureValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="FailureValue">class <strong>FailureValue</strong></a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.failure.html#FailureValue">FailureValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="FailureValue-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FailureValue-__init__"><strong>__init__</strong></a>(self, page, exc_info, description<font color="#909090">=None</font>, tir_label<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;value&nbsp;representing&nbsp;a&nbsp;failure&nbsp;when&nbsp;running&nbsp;the&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page:&nbsp;The&nbsp;page&nbsp;where&nbsp;this&nbsp;failure&nbsp;occurs.<br>
-&nbsp;&nbsp;exc_info:&nbsp;The&nbsp;exception&nbsp;info&nbsp;(sys.<a href="#FailureValue-exc_info">exc_info</a>())&nbsp;corresponding&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this&nbsp;failure.</tt></dd></dl>
-
-<dl><dt><a name="FailureValue-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="FailureValue-FromMessage"><strong>FromMessage</strong></a>(cls, page, message)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Creates&nbsp;a&nbsp;failure&nbsp;value&nbsp;for&nbsp;a&nbsp;given&nbsp;string&nbsp;message.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page:&nbsp;The&nbsp;page&nbsp;where&nbsp;this&nbsp;failure&nbsp;occurs.<br>
-&nbsp;&nbsp;message:&nbsp;A&nbsp;string&nbsp;message&nbsp;describing&nbsp;the&nbsp;failure.</tt></dd></dl>
-
-<dl><dt><a name="FailureValue-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="FailureValue-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="FailureValue-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>exc_info</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="FailureValue-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="FailureValue-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="FailureValue-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="FailureValue-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="FailureValue-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="FailureValue-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#FailureValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="FailureValue-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#FailureValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetStringFromExcInfo"><strong>GetStringFromExcInfo</strong></a>(exc_info)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.histogram.html b/catapult/telemetry/docs/pydoc/telemetry.value.histogram.html
deleted file mode 100644
index 9b6c3c1..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.histogram.html
+++ /dev/null
@@ -1,167 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.histogram</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.histogram</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/histogram.py">telemetry/value/histogram.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.histogram_util.html">telemetry.value.histogram_util</a><br>
-<a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.perf_tests_helper.html">telemetry.util.perf_tests_helper</a><br>
-<a href="telemetry.value.summarizable.html">telemetry.value.summarizable</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.histogram.html#HistogramValueBucket">HistogramValueBucket</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.histogram.html#HistogramValue">HistogramValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="HistogramValue">class <strong>HistogramValue</strong></a>(<a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.histogram.html#HistogramValue">HistogramValue</a></dd>
-<dd><a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="HistogramValue-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValue-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt></dl>
-
-<dl><dt><a name="HistogramValue-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValue-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValue-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValue-ToJSONString"><strong>ToJSONString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValue-__init__"><strong>__init__</strong></a>(self, page, name, units, raw_value<font color="#909090">=None</font>, raw_value_json<font color="#909090">=None</font>, important<font color="#909090">=True</font>, description<font color="#909090">=None</font>, tir_label<font color="#909090">=None</font>, improvement_direction<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="HistogramValue-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="HistogramValue-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="HistogramValue-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="HistogramValue-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt></dl>
-
-<dl><dt><a name="HistogramValue-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>:<br>
-<dl><dt><a name="HistogramValue-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>:<br>
-<dl><dt><strong>improvement_direction</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="HistogramValue-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="HistogramValue-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValue-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="HistogramValue-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="HistogramValue-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="HistogramValue-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#HistogramValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="HistogramValue-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#HistogramValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="HistogramValueBucket">class <strong>HistogramValueBucket</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="HistogramValueBucket-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValueBucket-ToJSONString"><strong>ToJSONString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="HistogramValueBucket-__init__"><strong>__init__</strong></a>(self, low, high, count<font color="#909090">=0</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.histogram_util.html b/catapult/telemetry/docs/pydoc/telemetry.value.histogram_util.html
deleted file mode 100644
index 745510d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.histogram_util.html
+++ /dev/null
@@ -1,60 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.histogram_util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.histogram_util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/histogram_util.py">telemetry/value/histogram_util.py</a></font></td></tr></table>
-    <p><tt>This&nbsp;is&nbsp;a&nbsp;helper&nbsp;module&nbsp;to&nbsp;get&nbsp;and&nbsp;manipulate&nbsp;histogram&nbsp;data.<br>
-&nbsp;<br>
-The&nbsp;histogram&nbsp;data&nbsp;is&nbsp;the&nbsp;same&nbsp;data&nbsp;as&nbsp;is&nbsp;visible&nbsp;from&nbsp;"chrome://histograms".<br>
-More&nbsp;information&nbsp;can&nbsp;be&nbsp;found&nbsp;at:&nbsp;chromium/src/base/metrics/histogram.h</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="telemetry.core.exceptions.html">telemetry.core.exceptions</a><br>
-</td><td width="25%" valign=top><a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AddHistograms"><strong>AddHistograms</strong></a>(histogram_jsons)</dt><dd><tt>Adds&nbsp;histograms&nbsp;together.&nbsp;Used&nbsp;for&nbsp;aggregating&nbsp;data.<br>
-&nbsp;<br>
-The&nbsp;parameter&nbsp;is&nbsp;a&nbsp;list&nbsp;of&nbsp;json&nbsp;serializations&nbsp;and&nbsp;the&nbsp;returned&nbsp;result&nbsp;is&nbsp;a<br>
-json&nbsp;serialization&nbsp;too.<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;the&nbsp;histograms&nbsp;to&nbsp;be&nbsp;added&nbsp;together&nbsp;are&nbsp;typically&nbsp;from&nbsp;different<br>
-processes.</tt></dd></dl>
- <dl><dt><a name="-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(options)</dt><dd><tt>Allows&nbsp;histogram&nbsp;collection.</tt></dd></dl>
- <dl><dt><a name="-GetHistogram"><strong>GetHistogram</strong></a>(histogram_type, histogram_name, tab)</dt><dd><tt>Get&nbsp;a&nbsp;json&nbsp;serialization&nbsp;of&nbsp;a&nbsp;histogram.</tt></dd></dl>
- <dl><dt><a name="-GetHistogramBucketsFromJson"><strong>GetHistogramBucketsFromJson</strong></a>(histogram_json)</dt></dl>
- <dl><dt><a name="-GetHistogramBucketsFromRawValue"><strong>GetHistogramBucketsFromRawValue</strong></a>(raw_value)</dt></dl>
- <dl><dt><a name="-GetHistogramCount"><strong>GetHistogramCount</strong></a>(histogram_type, histogram_name, tab)</dt><dd><tt>Get&nbsp;the&nbsp;count&nbsp;of&nbsp;events&nbsp;for&nbsp;the&nbsp;given&nbsp;histograms.</tt></dd></dl>
- <dl><dt><a name="-GetHistogramSum"><strong>GetHistogramSum</strong></a>(histogram_type, histogram_name, tab)</dt><dd><tt>Get&nbsp;the&nbsp;sum&nbsp;of&nbsp;events&nbsp;for&nbsp;the&nbsp;given&nbsp;histograms.</tt></dd></dl>
- <dl><dt><a name="-SubtractHistogram"><strong>SubtractHistogram</strong></a>(histogram_json, start_histogram_json)</dt><dd><tt>Subtracts&nbsp;a&nbsp;previous&nbsp;histogram&nbsp;from&nbsp;a&nbsp;histogram.<br>
-&nbsp;<br>
-Both&nbsp;parameters&nbsp;and&nbsp;the&nbsp;returned&nbsp;result&nbsp;are&nbsp;json&nbsp;serializations.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>BROWSER_HISTOGRAM</strong> = 'browser_histogram'<br>
-<strong>RENDERER_HISTOGRAM</strong> = 'renderer_histogram'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.html b/catapult/telemetry/docs/pydoc/telemetry.value.html
deleted file mode 100644
index 8d397fd..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.html
+++ /dev/null
@@ -1,235 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.value</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.value</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/__init__.py">telemetry/value/__init__.py</a></font></td></tr></table>
-    <p><tt>The&nbsp;<a href="#Value">Value</a>&nbsp;hierarchy&nbsp;provides&nbsp;a&nbsp;way&nbsp;of&nbsp;representing&nbsp;the&nbsp;values&nbsp;measurements<br>
-produce&nbsp;such&nbsp;that&nbsp;they&nbsp;can&nbsp;be&nbsp;merged&nbsp;across&nbsp;runs,&nbsp;grouped&nbsp;by&nbsp;page,&nbsp;and&nbsp;output<br>
-to&nbsp;different&nbsp;targets.<br>
-&nbsp;<br>
-The&nbsp;core&nbsp;<a href="#Value">Value</a>&nbsp;concept&nbsp;provides&nbsp;the&nbsp;basic&nbsp;functionality:<br>
--&nbsp;association&nbsp;with&nbsp;a&nbsp;page,&nbsp;may&nbsp;be&nbsp;none<br>
--&nbsp;naming&nbsp;and&nbsp;units<br>
--&nbsp;importance&nbsp;tracking&nbsp;[whether&nbsp;a&nbsp;value&nbsp;will&nbsp;show&nbsp;up&nbsp;on&nbsp;a&nbsp;waterfall&nbsp;or&nbsp;output<br>
-&nbsp;&nbsp;file&nbsp;by&nbsp;default]<br>
--&nbsp;other&nbsp;metadata,&nbsp;such&nbsp;as&nbsp;a&nbsp;description&nbsp;of&nbsp;what&nbsp;was&nbsp;measured<br>
--&nbsp;default&nbsp;conversion&nbsp;to&nbsp;scalar&nbsp;and&nbsp;string<br>
--&nbsp;merging&nbsp;properties<br>
-&nbsp;<br>
-A&nbsp;page&nbsp;may&nbsp;actually&nbsp;run&nbsp;a&nbsp;few&nbsp;times&nbsp;during&nbsp;a&nbsp;single&nbsp;telemetry&nbsp;session.<br>
-Downstream&nbsp;consumers&nbsp;of&nbsp;test&nbsp;results&nbsp;typically&nbsp;want&nbsp;to&nbsp;group&nbsp;these&nbsp;runs<br>
-together,&nbsp;then&nbsp;compute&nbsp;summary&nbsp;statistics&nbsp;across&nbsp;runs.&nbsp;<a href="#Value">Value</a>&nbsp;provides&nbsp;the<br>
-Merge*&nbsp;family&nbsp;of&nbsp;methods&nbsp;for&nbsp;this&nbsp;kind&nbsp;of&nbsp;aggregation.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.failure.html">failure</a><br>
-<a href="telemetry.value.failure_unittest.html">failure_unittest</a><br>
-<a href="telemetry.value.histogram.html">histogram</a><br>
-<a href="telemetry.value.histogram_unittest.html">histogram_unittest</a><br>
-<a href="telemetry.value.histogram_util.html">histogram_util</a><br>
-<a href="telemetry.value.histogram_util_unittest.html">histogram_util_unittest</a><br>
-<a href="telemetry.value.improvement_direction.html">improvement_direction</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">list_of_scalar_values</a><br>
-<a href="telemetry.value.list_of_scalar_values_unittest.html">list_of_scalar_values_unittest</a><br>
-<a href="telemetry.value.list_of_string_values.html">list_of_string_values</a><br>
-<a href="telemetry.value.list_of_string_values_unittest.html">list_of_string_values_unittest</a><br>
-<a href="telemetry.value.merge_values.html">merge_values</a><br>
-<a href="telemetry.value.merge_values_unittest.html">merge_values_unittest</a><br>
-<a href="telemetry.value.none_values.html">none_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.scalar.html">scalar</a><br>
-<a href="telemetry.value.scalar_unittest.html">scalar_unittest</a><br>
-<a href="telemetry.value.skip.html">skip</a><br>
-<a href="telemetry.value.skip_unittest.html">skip_unittest</a><br>
-<a href="telemetry.value.string.html">string</a><br>
-<a href="telemetry.value.string_unittest.html">string_unittest</a><br>
-<a href="telemetry.value.summarizable.html">summarizable</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.summary.html">summary</a><br>
-<a href="telemetry.value.summary_unittest.html">summary_unittest</a><br>
-<a href="telemetry.value.trace.html">trace</a><br>
-<a href="telemetry.value.trace_unittest.html">trace_unittest</a><br>
-<a href="telemetry.value.value_unittest.html">value_unittest</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.html#Value">Value</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Value">class <strong>Value</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>An&nbsp;abstract&nbsp;value&nbsp;produced&nbsp;by&nbsp;a&nbsp;telemetry&nbsp;page&nbsp;test.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Value-AsDict"><strong>AsDict</strong></a>(self)</dt><dd><tt>Pre-serializes&nbsp;a&nbsp;value&nbsp;to&nbsp;a&nbsp;dict&nbsp;for&nbsp;output&nbsp;as&nbsp;JSON.</tt></dd></dl>
-
-<dl><dt><a name="Value-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Value-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt><dd><tt>Returns&nbsp;the&nbsp;buildbot's&nbsp;equivalent&nbsp;data_type.<br>
-&nbsp;<br>
-This&nbsp;should&nbsp;be&nbsp;one&nbsp;of&nbsp;the&nbsp;values&nbsp;accepted&nbsp;by&nbsp;perf_tests_results_helper.py.</tt></dd></dl>
-
-<dl><dt><a name="Value-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;buildbot's&nbsp;equivalent&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="Value-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="Value-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Value-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt><dd><tt>Gets&nbsp;a&nbsp;single&nbsp;scalar&nbsp;value&nbsp;that&nbsp;best-represents&nbsp;this&nbsp;value.<br>
-&nbsp;<br>
-Returns&nbsp;None&nbsp;if&nbsp;not&nbsp;possible.</tt></dd></dl>
-
-<dl><dt><a name="Value-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt><dd><tt>Gets&nbsp;a&nbsp;string&nbsp;value&nbsp;that&nbsp;best-represents&nbsp;this&nbsp;value.<br>
-&nbsp;<br>
-Returns&nbsp;None&nbsp;if&nbsp;not&nbsp;possible.</tt></dd></dl>
-
-<dl><dt><a name="Value-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="Value-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="Value-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Value-__init__"><strong>__init__</strong></a>(self, page, name, units, important, description, tir_label)</dt><dd><tt>A&nbsp;generic&nbsp;<a href="#Value">Value</a>&nbsp;<a href="__builtin__.html#object">object</a>.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page:&nbsp;A&nbsp;Page&nbsp;<a href="__builtin__.html#object">object</a>,&nbsp;may&nbsp;be&nbsp;given&nbsp;as&nbsp;None&nbsp;to&nbsp;indicate&nbsp;that&nbsp;the&nbsp;value<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;represents&nbsp;results&nbsp;for&nbsp;multiple&nbsp;pages.<br>
-&nbsp;&nbsp;name:&nbsp;A&nbsp;value&nbsp;name&nbsp;string,&nbsp;may&nbsp;contain&nbsp;a&nbsp;dot.&nbsp;Values&nbsp;from&nbsp;the&nbsp;same&nbsp;test<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;with&nbsp;the&nbsp;same&nbsp;prefix&nbsp;before&nbsp;the&nbsp;dot&nbsp;may&nbsp;be&nbsp;considered&nbsp;to&nbsp;belong&nbsp;to<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;same&nbsp;chart.<br>
-&nbsp;&nbsp;units:&nbsp;A&nbsp;units&nbsp;string.<br>
-&nbsp;&nbsp;important:&nbsp;Whether&nbsp;the&nbsp;value&nbsp;is&nbsp;"important".&nbsp;Causes&nbsp;the&nbsp;value&nbsp;to&nbsp;appear<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;by&nbsp;default&nbsp;in&nbsp;downstream&nbsp;UIs.<br>
-&nbsp;&nbsp;description:&nbsp;A&nbsp;string&nbsp;explaining&nbsp;in&nbsp;human-understandable&nbsp;terms&nbsp;what&nbsp;this<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;value&nbsp;represents.<br>
-&nbsp;&nbsp;tir_label:&nbsp;The&nbsp;string&nbsp;label&nbsp;of&nbsp;the&nbsp;TimelineInteractionRecord&nbsp;with<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;which&nbsp;this&nbsp;value&nbsp;is&nbsp;associated.</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="Value-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Combines&nbsp;the&nbsp;provided&nbsp;values&nbsp;into&nbsp;a&nbsp;single&nbsp;compound&nbsp;value.<br>
-&nbsp;<br>
-When&nbsp;a&nbsp;full&nbsp;pageset&nbsp;runs,&nbsp;a&nbsp;single&nbsp;value_name&nbsp;will&nbsp;usually&nbsp;end&nbsp;up&nbsp;getting<br>
-collected&nbsp;for&nbsp;multiple&nbsp;pages.&nbsp;For&nbsp;instance,&nbsp;we&nbsp;may&nbsp;end&nbsp;up&nbsp;with<br>
-&nbsp;&nbsp;&nbsp;[ScalarValue(page1,&nbsp;'a',&nbsp;&nbsp;1),<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page2,&nbsp;'a',&nbsp;&nbsp;2)]<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;takes&nbsp;in&nbsp;the&nbsp;values&nbsp;of&nbsp;the&nbsp;same&nbsp;name,&nbsp;but&nbsp;across&nbsp;multiple<br>
-pages,&nbsp;and&nbsp;produces&nbsp;a&nbsp;single&nbsp;summary&nbsp;result&nbsp;value.&nbsp;In&nbsp;this&nbsp;instance,&nbsp;it<br>
-could&nbsp;produce&nbsp;a&nbsp;ScalarValue(None,&nbsp;'a',&nbsp;1.5)&nbsp;to&nbsp;indicate&nbsp;averaging,&nbsp;or&nbsp;even<br>
-ListOfScalarValues(None,&nbsp;'a',&nbsp;[1,&nbsp;2])&nbsp;if&nbsp;concatenated&nbsp;output&nbsp;was&nbsp;desired.<br>
-&nbsp;<br>
-Some&nbsp;results&nbsp;are&nbsp;so&nbsp;specific&nbsp;to&nbsp;a&nbsp;page&nbsp;that&nbsp;they&nbsp;make&nbsp;no&nbsp;sense&nbsp;when<br>
-aggregated&nbsp;across&nbsp;pages.&nbsp;If&nbsp;merging&nbsp;values&nbsp;of&nbsp;this&nbsp;type&nbsp;across&nbsp;pages&nbsp;is<br>
-non-sensical,&nbsp;this&nbsp;method&nbsp;may&nbsp;return&nbsp;None.</tt></dd></dl>
-
-<dl><dt><a name="Value-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Combines&nbsp;the&nbsp;provided&nbsp;list&nbsp;of&nbsp;values&nbsp;into&nbsp;a&nbsp;single&nbsp;compound&nbsp;value.<br>
-&nbsp;<br>
-When&nbsp;a&nbsp;page&nbsp;runs&nbsp;multiple&nbsp;times,&nbsp;it&nbsp;may&nbsp;produce&nbsp;multiple&nbsp;values.&nbsp;This<br>
-function&nbsp;is&nbsp;given&nbsp;the&nbsp;same-named&nbsp;values&nbsp;across&nbsp;the&nbsp;multiple&nbsp;runs,&nbsp;and&nbsp;has<br>
-the&nbsp;responsibility&nbsp;of&nbsp;producing&nbsp;a&nbsp;single&nbsp;result.<br>
-&nbsp;<br>
-It&nbsp;must&nbsp;return&nbsp;a&nbsp;single&nbsp;<a href="#Value">Value</a>.&nbsp;If&nbsp;merging&nbsp;does&nbsp;not&nbsp;make&nbsp;sense,&nbsp;the<br>
-implementation&nbsp;must&nbsp;pick&nbsp;a&nbsp;representative&nbsp;value&nbsp;from&nbsp;one&nbsp;of&nbsp;the&nbsp;runs.<br>
-&nbsp;<br>
-For&nbsp;instance,&nbsp;it&nbsp;may&nbsp;be&nbsp;given<br>
-&nbsp;&nbsp;&nbsp;&nbsp;[ScalarValue(page,&nbsp;'a',&nbsp;1),&nbsp;ScalarValue(page,&nbsp;'a',&nbsp;2)]<br>
-and&nbsp;it&nbsp;might&nbsp;produce<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page,&nbsp;'a',&nbsp;[1,&nbsp;2])</tt></dd></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="Value-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;a&nbsp;value&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-<a href="#Value">Value</a>&nbsp;dicts&nbsp;are&nbsp;produced&nbsp;by&nbsp;serialization&nbsp;to&nbsp;JSON,&nbsp;and&nbsp;must&nbsp;be&nbsp;accompanied<br>
-by&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages,&nbsp;also&nbsp;produced&nbsp;by&nbsp;serialization,&nbsp;in<br>
-order&nbsp;to&nbsp;be&nbsp;completely&nbsp;deserialized.&nbsp;If&nbsp;deserializing&nbsp;multiple&nbsp;values,&nbsp;use<br>
-ListOfValuesFromListOfDicts&nbsp;instead.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#Value-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="Value-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#Value-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="Value-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt><dd><tt>Gets&nbsp;the&nbsp;typename&nbsp;for&nbsp;serialization&nbsp;to&nbsp;JSON&nbsp;using&nbsp;AsDict.</tt></dd></dl>
-
-<dl><dt><a name="Value-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#Value-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ValueNameFromTraceAndChartName"><strong>ValueNameFromTraceAndChartName</strong></a>(trace_name, chart_name<font color="#909090">=None</font>)</dt><dd><tt>Mangles&nbsp;a&nbsp;trace&nbsp;name&nbsp;plus&nbsp;optional&nbsp;chart&nbsp;name&nbsp;into&nbsp;a&nbsp;standard&nbsp;string.<br>
-&nbsp;<br>
-A&nbsp;value&nbsp;might&nbsp;just&nbsp;be&nbsp;a&nbsp;bareword&nbsp;name,&nbsp;e.g.&nbsp;numPixels.&nbsp;In&nbsp;that&nbsp;case,&nbsp;its<br>
-chart&nbsp;may&nbsp;be&nbsp;None.<br>
-&nbsp;<br>
-But,&nbsp;a&nbsp;value&nbsp;might&nbsp;also&nbsp;be&nbsp;intended&nbsp;for&nbsp;display&nbsp;with&nbsp;other&nbsp;values,&nbsp;in&nbsp;which<br>
-case&nbsp;the&nbsp;chart&nbsp;name&nbsp;indicates&nbsp;that&nbsp;grouping.&nbsp;So,&nbsp;you&nbsp;might&nbsp;have<br>
-screen.numPixels,&nbsp;screen.resolution,&nbsp;where&nbsp;chartName='screen'.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT</strong> = 'merged-pages-result-output-context'<br>
-<strong>CONCATENATE</strong> = 'concatenate'<br>
-<strong>PER_PAGE_RESULT_OUTPUT_CONTEXT</strong> = 'per-page-result-output-context'<br>
-<strong>PICK_FIRST</strong> = 'pick-first'<br>
-<strong>SUMMARY_RESULT_OUTPUT_CONTEXT</strong> = 'summary-result-output-context'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.improvement_direction.html b/catapult/telemetry/docs/pydoc/telemetry.value.improvement_direction.html
deleted file mode 100644
index 8f4b222..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.improvement_direction.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.improvement_direction</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.improvement_direction</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/improvement_direction.py">telemetry/value/improvement_direction.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-IsValid"><strong>IsValid</strong></a>(improvement_direction)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DOWN</strong> = 'down'<br>
-<strong>UP</strong> = 'up'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.list_of_scalar_values.html b/catapult/telemetry/docs/pydoc/telemetry.value.list_of_scalar_values.html
deleted file mode 100644
index ec9dc88..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.list_of_scalar_values.html
+++ /dev/null
@@ -1,173 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.list_of_scalar_values</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.list_of_scalar_values</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/list_of_scalar_values.py">telemetry/value/list_of_scalar_values.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="math.html">math</a><br>
-<a href="telemetry.value.none_values.html">telemetry.value.none_values</a><br>
-</td><td width="25%" valign=top><a href="numbers.html">numbers</a><br>
-<a href="telemetry.value.summarizable.html">telemetry.value.summarizable</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.list_of_scalar_values.html#ListOfScalarValues">ListOfScalarValues</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ListOfScalarValues">class <strong>ListOfScalarValues</strong></a>(<a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#ListOfScalarValues">ListOfScalarValues</a>&nbsp;represents&nbsp;a&nbsp;list&nbsp;of&nbsp;numbers.<br>
-&nbsp;<br>
-By&nbsp;default,&nbsp;std&nbsp;is&nbsp;the&nbsp;standard&nbsp;deviation&nbsp;of&nbsp;all&nbsp;numbers&nbsp;in&nbsp;the&nbsp;list.&nbsp;Std&nbsp;can<br>
-also&nbsp;be&nbsp;specified&nbsp;in&nbsp;the&nbsp;constructor&nbsp;if&nbsp;the&nbsp;numbers&nbsp;are&nbsp;not&nbsp;from&nbsp;the&nbsp;same<br>
-population.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.list_of_scalar_values.html#ListOfScalarValues">ListOfScalarValues</a></dd>
-<dd><a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ListOfScalarValues-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-__init__"><strong>__init__</strong></a>(self, page, name, units, values, important<font color="#909090">=True</font>, description<font color="#909090">=None</font>, tir_label<font color="#909090">=None</font>, none_value_reason<font color="#909090">=None</font>, std<font color="#909090">=None</font>, same_page_merge_policy<font color="#909090">='concatenate'</font>, improvement_direction<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="ListOfScalarValues-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="ListOfScalarValues-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>std</strong></dt>
-</dl>
-<dl><dt><strong>variance</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>:<br>
-<dl><dt><a name="ListOfScalarValues-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>:<br>
-<dl><dt><strong>improvement_direction</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="ListOfScalarValues-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="ListOfScalarValues-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="ListOfScalarValues-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#ListOfScalarValues-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="ListOfScalarValues-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#ListOfScalarValues-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-PooledStandardDeviation"><strong>PooledStandardDeviation</strong></a>(list_of_samples, list_of_variances<font color="#909090">=None</font>)</dt><dd><tt>Compute&nbsp;standard&nbsp;deviation&nbsp;for&nbsp;a&nbsp;list&nbsp;of&nbsp;samples.<br>
-&nbsp;<br>
-See:&nbsp;https://en.wikipedia.org/wiki/Pooled_variance&nbsp;for&nbsp;the&nbsp;formula.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;list_of_samples:&nbsp;a&nbsp;list&nbsp;of&nbsp;lists,&nbsp;each&nbsp;is&nbsp;a&nbsp;list&nbsp;of&nbsp;numbers.<br>
-&nbsp;&nbsp;list_of_variances:&nbsp;a&nbsp;list&nbsp;of&nbsp;numbers,&nbsp;the&nbsp;i-th&nbsp;element&nbsp;is&nbsp;the&nbsp;variance&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;i-th&nbsp;sample&nbsp;in&nbsp;list_of_samples.&nbsp;If&nbsp;this&nbsp;is&nbsp;None,&nbsp;we&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;<a href="#-Variance">Variance</a>(sample)&nbsp;to&nbsp;get&nbsp;the&nbsp;variance&nbsp;of&nbsp;the&nbsp;i-th&nbsp;sample.</tt></dd></dl>
- <dl><dt><a name="-StandardDeviation"><strong>StandardDeviation</strong></a>(sample)</dt><dd><tt>Compute&nbsp;standard&nbsp;deviation&nbsp;for&nbsp;a&nbsp;list&nbsp;of&nbsp;numbers.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;sample:&nbsp;a&nbsp;list&nbsp;of&nbsp;numbers.</tt></dd></dl>
- <dl><dt><a name="-Variance"><strong>Variance</strong></a>(sample)</dt><dd><tt>Compute&nbsp;the&nbsp;population&nbsp;variance.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;sample:&nbsp;a&nbsp;list&nbsp;of&nbsp;numbers.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.merge_values.html b/catapult/telemetry/docs/pydoc/telemetry.value.merge_values.html
deleted file mode 100644
index 2939fca..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.merge_values.html
+++ /dev/null
@@ -1,90 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.merge_values</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.merge_values</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/merge_values.py">telemetry/value/merge_values.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.failure.html">telemetry.value.failure</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.skip.html">telemetry.value.skip</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-DefaultKeyFunc"><strong>DefaultKeyFunc</strong></a>(value)</dt><dd><tt>Keys&nbsp;values&nbsp;in&nbsp;a&nbsp;standard&nbsp;way&nbsp;for&nbsp;grouping&nbsp;in&nbsp;merging&nbsp;and&nbsp;summary.<br>
-&nbsp;<br>
-Merging&nbsp;and&nbsp;summarization&nbsp;can&nbsp;be&nbsp;parameterized&nbsp;by&nbsp;a&nbsp;function&nbsp;that&nbsp;groups<br>
-values&nbsp;into&nbsp;equivalence&nbsp;classes.&nbsp;Any&nbsp;function&nbsp;that&nbsp;returns&nbsp;a&nbsp;comparable<br>
-object&nbsp;can&nbsp;be&nbsp;used&nbsp;as&nbsp;a&nbsp;key_func,&nbsp;but&nbsp;merge_values&nbsp;and&nbsp;summary&nbsp;both&nbsp;use&nbsp;this<br>
-function&nbsp;by&nbsp;default,&nbsp;to&nbsp;allow&nbsp;the&nbsp;default&nbsp;grouping&nbsp;to&nbsp;change&nbsp;as&nbsp;Telemtry&nbsp;does.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;value:&nbsp;A&nbsp;Telemetry&nbsp;Value&nbsp;instance<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;comparable&nbsp;object&nbsp;used&nbsp;to&nbsp;group&nbsp;values.</tt></dd></dl>
- <dl><dt><a name="-GroupStably"><strong>GroupStably</strong></a>(all_values, key_func)</dt><dd><tt>Groups&nbsp;an&nbsp;array&nbsp;by&nbsp;key_func,&nbsp;with&nbsp;the&nbsp;groups&nbsp;returned&nbsp;in&nbsp;a&nbsp;stable&nbsp;order.<br>
-&nbsp;<br>
-Returns&nbsp;a&nbsp;list&nbsp;of&nbsp;groups.</tt></dd></dl>
- <dl><dt><a name="-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(all_values, key_func<font color="#909090">=&lt;function DefaultKeyFunc&gt;</font>)</dt><dd><tt>Merges&nbsp;values&nbsp;that&nbsp;measure&nbsp;the&nbsp;same&nbsp;thing&nbsp;on&nbsp;different&nbsp;pages.<br>
-&nbsp;<br>
-After&nbsp;using&nbsp;MergeLikeValuesFromSamePage,&nbsp;one&nbsp;still&nbsp;ends&nbsp;up&nbsp;with&nbsp;values&nbsp;from<br>
-different&nbsp;pages:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'x',&nbsp;1,&nbsp;'foo')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'y',&nbsp;30,&nbsp;'bar')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page2,&nbsp;'x',&nbsp;2,&nbsp;'foo')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page2,&nbsp;'y',&nbsp;40,&nbsp;'baz')<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;will&nbsp;group&nbsp;values&nbsp;with&nbsp;the&nbsp;same&nbsp;name&nbsp;and&nbsp;tir_label&nbsp;together:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(None,&nbsp;'x',&nbsp;[1,&nbsp;2],&nbsp;'foo')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(None,&nbsp;'y',&nbsp;[30],&nbsp;'bar')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(None,&nbsp;'y',&nbsp;[40],&nbsp;'baz')<br>
-&nbsp;<br>
-The&nbsp;workhorse&nbsp;of&nbsp;this&nbsp;code&nbsp;is&nbsp;Value.MergeLikeValuesFromDifferentPages.<br>
-&nbsp;<br>
-Not&nbsp;all&nbsp;values&nbsp;that&nbsp;go&nbsp;into&nbsp;this&nbsp;function&nbsp;will&nbsp;come&nbsp;out:&nbsp;not&nbsp;every&nbsp;value&nbsp;can<br>
-be&nbsp;merged&nbsp;across&nbsp;pages.&nbsp;Values&nbsp;whose&nbsp;MergeLikeValuesFromDifferentPages&nbsp;returns<br>
-None&nbsp;will&nbsp;be&nbsp;omitted&nbsp;from&nbsp;the&nbsp;results.<br>
-&nbsp;<br>
-This&nbsp;requires&nbsp;(but&nbsp;assumes)&nbsp;that&nbsp;the&nbsp;values&nbsp;passed&nbsp;in&nbsp;with&nbsp;the&nbsp;same&nbsp;name&nbsp;pass<br>
-the&nbsp;Value.IsMergableWith&nbsp;test.&nbsp;If&nbsp;this&nbsp;is&nbsp;not&nbsp;obeyed,&nbsp;the&nbsp;results<br>
-will&nbsp;be&nbsp;undefined.</tt></dd></dl>
- <dl><dt><a name="-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(all_values, key_func<font color="#909090">=&lt;function DefaultKeyFunc&gt;</font>)</dt><dd><tt>Merges&nbsp;values&nbsp;that&nbsp;measure&nbsp;the&nbsp;same&nbsp;thing&nbsp;on&nbsp;the&nbsp;same&nbsp;page.<br>
-&nbsp;<br>
-A&nbsp;page&nbsp;may&nbsp;end&nbsp;up&nbsp;being&nbsp;measured&nbsp;multiple&nbsp;times,&nbsp;meaning&nbsp;that&nbsp;we&nbsp;may&nbsp;end&nbsp;up<br>
-with&nbsp;something&nbsp;like&nbsp;this:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'x',&nbsp;1,&nbsp;'foo')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page2,&nbsp;'x',&nbsp;4,&nbsp;'bar')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'x',&nbsp;2,&nbsp;'foo')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page2,&nbsp;'x',&nbsp;5,&nbsp;'baz')<br>
-&nbsp;<br>
-This&nbsp;function&nbsp;will&nbsp;produce:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page1,&nbsp;'x',&nbsp;[1,&nbsp;2],&nbsp;'foo')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page2,&nbsp;'x',&nbsp;[4],&nbsp;'bar')<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page2,&nbsp;'x',&nbsp;[5],&nbsp;'baz')<br>
-&nbsp;<br>
-The&nbsp;workhorse&nbsp;of&nbsp;this&nbsp;code&nbsp;is&nbsp;Value.MergeLikeValuesFromSamePage.<br>
-&nbsp;<br>
-This&nbsp;requires&nbsp;(but&nbsp;assumes)&nbsp;that&nbsp;the&nbsp;values&nbsp;passed&nbsp;in&nbsp;with&nbsp;the&nbsp;same&nbsp;grouping<br>
-key&nbsp;pass&nbsp;the&nbsp;Value.IsMergableWith&nbsp;test.&nbsp;If&nbsp;this&nbsp;is&nbsp;not&nbsp;obeyed,&nbsp;the<br>
-results&nbsp;will&nbsp;be&nbsp;undefined.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.none_values.html b/catapult/telemetry/docs/pydoc/telemetry.value.none_values.html
deleted file mode 100644
index f2df036..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.none_values.html
+++ /dev/null
@@ -1,168 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.none_values</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.none_values</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/none_values.py">telemetry/value/none_values.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.none_values.html#NoneValueMissingReason">NoneValueMissingReason</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.value.none_values.html#ValueMustHaveNoneValue">ValueMustHaveNoneValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NoneValueMissingReason">class <strong>NoneValueMissingReason</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.none_values.html#NoneValueMissingReason">NoneValueMissingReason</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="NoneValueMissingReason-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#NoneValueMissingReason-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="NoneValueMissingReason-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#NoneValueMissingReason-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="NoneValueMissingReason-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ValueMustHaveNoneValue">class <strong>ValueMustHaveNoneValue</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.none_values.html#ValueMustHaveNoneValue">ValueMustHaveNoneValue</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ValueMustHaveNoneValue-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ValueMustHaveNoneValue-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;object&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ValueMustHaveNoneValue-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ValueMustHaveNoneValue-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ValueMustHaveNoneValue-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ValidateNoneValueReason"><strong>ValidateNoneValueReason</strong></a>(value, none_value_reason)</dt><dd><tt>Ensures&nbsp;that&nbsp;the&nbsp;none_value_reason&nbsp;is&nbsp;appropriate&nbsp;for&nbsp;the&nbsp;given&nbsp;value.<br>
-&nbsp;<br>
-There&nbsp;is&nbsp;a&nbsp;logical&nbsp;equality&nbsp;between&nbsp;having&nbsp;a&nbsp;value&nbsp;of&nbsp;None&nbsp;and&nbsp;having&nbsp;a<br>
-reason&nbsp;for&nbsp;being&nbsp;None.&nbsp;That&nbsp;is&nbsp;to&nbsp;say,&nbsp;value&nbsp;is&nbsp;None&nbsp;if&nbsp;and&nbsp;only&nbsp;if<br>
-none_value_reason&nbsp;is&nbsp;a&nbsp;string.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>MERGE_FAILURE_REASON</strong> = 'Merging values containing a None value results in a None value.'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.scalar.html b/catapult/telemetry/docs/pydoc/telemetry.value.scalar.html
deleted file mode 100644
index 1ffc353..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.scalar.html
+++ /dev/null
@@ -1,141 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.scalar</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.scalar</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/scalar.py">telemetry/value/scalar.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-<a href="telemetry.value.none_values.html">telemetry.value.none_values</a><br>
-</td><td width="25%" valign=top><a href="numbers.html">numbers</a><br>
-<a href="telemetry.value.summarizable.html">telemetry.value.summarizable</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.scalar.html#ScalarValue">ScalarValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ScalarValue">class <strong>ScalarValue</strong></a>(<a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.scalar.html#ScalarValue">ScalarValue</a></dd>
-<dd><a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ScalarValue-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ScalarValue-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt></dl>
-
-<dl><dt><a name="ScalarValue-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ScalarValue-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ScalarValue-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ScalarValue-__init__"><strong>__init__</strong></a>(self, page, name, units, value, important<font color="#909090">=True</font>, description<font color="#909090">=None</font>, tir_label<font color="#909090">=None</font>, none_value_reason<font color="#909090">=None</font>, improvement_direction<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;single&nbsp;value&nbsp;(float&nbsp;or&nbsp;integer)&nbsp;result&nbsp;from&nbsp;a&nbsp;test.<br>
-&nbsp;<br>
-A&nbsp;test&nbsp;that&nbsp;counts&nbsp;the&nbsp;number&nbsp;of&nbsp;DOM&nbsp;elements&nbsp;in&nbsp;a&nbsp;page&nbsp;might&nbsp;produce&nbsp;a<br>
-scalar&nbsp;value:<br>
-&nbsp;&nbsp;&nbsp;<a href="#ScalarValue">ScalarValue</a>(page,&nbsp;'num_dom_elements',&nbsp;'count',&nbsp;num_elements)</tt></dd></dl>
-
-<dl><dt><a name="ScalarValue-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="ScalarValue-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="ScalarValue-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="ScalarValue-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt></dl>
-
-<dl><dt><a name="ScalarValue-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>:<br>
-<dl><dt><a name="ScalarValue-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.summarizable.html#SummarizableValue">telemetry.value.summarizable.SummarizableValue</a>:<br>
-<dl><dt><strong>improvement_direction</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="ScalarValue-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="ScalarValue-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="ScalarValue-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="ScalarValue-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="ScalarValue-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="ScalarValue-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#ScalarValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="ScalarValue-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#ScalarValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.skip.html b/catapult/telemetry/docs/pydoc/telemetry.value.skip.html
deleted file mode 100644
index 13b67eb..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.skip.html
+++ /dev/null
@@ -1,134 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.skip</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.skip</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/skip.py">telemetry/value/skip.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.html#Value">telemetry.value.Value</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.skip.html#SkipValue">SkipValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SkipValue">class <strong>SkipValue</strong></a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.skip.html#SkipValue">SkipValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SkipValue-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SkipValue-__init__"><strong>__init__</strong></a>(self, page, reason, description<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;value&nbsp;representing&nbsp;a&nbsp;skipped&nbsp;page.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;page:&nbsp;The&nbsp;skipped&nbsp;page&nbsp;object.<br>
-&nbsp;&nbsp;reason:&nbsp;The&nbsp;string&nbsp;reason&nbsp;the&nbsp;page&nbsp;was&nbsp;skipped.</tt></dd></dl>
-
-<dl><dt><a name="SkipValue-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="SkipValue-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="SkipValue-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="SkipValue-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>reason</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="SkipValue-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SkipValue-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="SkipValue-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="SkipValue-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="SkipValue-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="SkipValue-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#SkipValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="SkipValue-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#SkipValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.summarizable.html b/catapult/telemetry/docs/pydoc/telemetry.value.summarizable.html
deleted file mode 100644
index 61d3ba0..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.summarizable.html
+++ /dev/null
@@ -1,142 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.summarizable</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.summarizable</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/summarizable.py">telemetry/value/summarizable.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.html#Value">telemetry.value.Value</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.summarizable.html#SummarizableValue">SummarizableValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SummarizableValue">class <strong>SummarizableValue</strong></a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.summarizable.html#SummarizableValue">SummarizableValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SummarizableValue-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SummarizableValue-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SummarizableValue-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt><dd><tt>Returns&nbsp;the&nbsp;buildbot's&nbsp;equivalent&nbsp;data_type.<br>
-&nbsp;<br>
-This&nbsp;should&nbsp;be&nbsp;one&nbsp;of&nbsp;the&nbsp;values&nbsp;accepted&nbsp;by&nbsp;perf_tests_results_helper.py.</tt></dd></dl>
-
-<dl><dt><a name="SummarizableValue-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt><dd><tt>Returns&nbsp;the&nbsp;buildbot's&nbsp;equivalent&nbsp;value.</tt></dd></dl>
-
-<dl><dt><a name="SummarizableValue-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt><dd><tt>Gets&nbsp;a&nbsp;single&nbsp;scalar&nbsp;value&nbsp;that&nbsp;best-represents&nbsp;this&nbsp;value.<br>
-&nbsp;<br>
-Returns&nbsp;None&nbsp;if&nbsp;not&nbsp;possible.</tt></dd></dl>
-
-<dl><dt><a name="SummarizableValue-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt><dd><tt>Gets&nbsp;a&nbsp;string&nbsp;value&nbsp;that&nbsp;best-represents&nbsp;this&nbsp;value.<br>
-&nbsp;<br>
-Returns&nbsp;None&nbsp;if&nbsp;not&nbsp;possible.</tt></dd></dl>
-
-<dl><dt><a name="SummarizableValue-__init__"><strong>__init__</strong></a>(self, page, name, units, important, description, tir_label, improvement_direction)</dt><dd><tt>A&nbsp;summarizable&nbsp;value&nbsp;result&nbsp;from&nbsp;a&nbsp;test.</tt></dd></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="SummarizableValue-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="SummarizableValue-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="SummarizableValue-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>improvement_direction</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="SummarizableValue-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="SummarizableValue-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="SummarizableValue-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="SummarizableValue-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="SummarizableValue-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="SummarizableValue-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;a&nbsp;value&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-<a href="telemetry.value.html#Value">Value</a>&nbsp;dicts&nbsp;are&nbsp;produced&nbsp;by&nbsp;serialization&nbsp;to&nbsp;JSON,&nbsp;and&nbsp;must&nbsp;be&nbsp;accompanied<br>
-by&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages,&nbsp;also&nbsp;produced&nbsp;by&nbsp;serialization,&nbsp;in<br>
-order&nbsp;to&nbsp;be&nbsp;completely&nbsp;deserialized.&nbsp;If&nbsp;deserializing&nbsp;multiple&nbsp;values,&nbsp;use<br>
-ListOfValuesFromListOfDicts&nbsp;instead.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#SummarizableValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="SummarizableValue-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#SummarizableValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="SummarizableValue-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#SummarizableValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.summary.html b/catapult/telemetry/docs/pydoc/telemetry.value.summary.html
deleted file mode 100644
index 8d2b9eb..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.summary.html
+++ /dev/null
@@ -1,94 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.summary</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.summary</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/summary.py">telemetry/value/summary.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.failure.html">telemetry.value.failure</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.merge_values.html">telemetry.value.merge_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.skip.html">telemetry.value.skip</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.summary.html#Summary">Summary</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Summary">class <strong>Summary</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Computes&nbsp;summary&nbsp;values&nbsp;from&nbsp;the&nbsp;per-page-run&nbsp;values&nbsp;produced&nbsp;by&nbsp;a&nbsp;test.<br>
-&nbsp;<br>
-Some&nbsp;telemetry&nbsp;benchmark&nbsp;repeat&nbsp;a&nbsp;number&nbsp;of&nbsp;times&nbsp;in&nbsp;order&nbsp;to&nbsp;get&nbsp;a&nbsp;reliable<br>
-measurement.&nbsp;The&nbsp;test&nbsp;does&nbsp;not&nbsp;have&nbsp;to&nbsp;handle&nbsp;merging&nbsp;of&nbsp;these&nbsp;runs:<br>
-summarizer&nbsp;does&nbsp;it&nbsp;for&nbsp;you.<br>
-&nbsp;<br>
-For&nbsp;instance,&nbsp;if&nbsp;two&nbsp;pages&nbsp;run,&nbsp;3&nbsp;and&nbsp;1&nbsp;time&nbsp;respectively:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'foo',&nbsp;units='ms',&nbsp;1)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'foo',&nbsp;units='ms',&nbsp;1)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page1,&nbsp;'foo',&nbsp;units='ms',&nbsp;1)<br>
-&nbsp;&nbsp;&nbsp;&nbsp;ScalarValue(page2,&nbsp;'foo',&nbsp;units='ms',&nbsp;2)<br>
-&nbsp;<br>
-Then&nbsp;summarizer&nbsp;will&nbsp;produce&nbsp;two&nbsp;sets&nbsp;of&nbsp;values.&nbsp;First,<br>
-computed_per_page_values:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;[<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page1,&nbsp;'foo',&nbsp;units='ms',&nbsp;[1,1,1])],<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page2,&nbsp;'foo',&nbsp;units='ms',&nbsp;[2])]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;]<br>
-&nbsp;<br>
-In&nbsp;addition,&nbsp;it&nbsp;will&nbsp;produce&nbsp;a&nbsp;summary&nbsp;value:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;[<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ListOfScalarValues(page=None,&nbsp;'foo',&nbsp;units='ms',&nbsp;[1,1,1,2])]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;]<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Summary-__init__"><strong>__init__</strong></a>(self, all_page_specific_values, key_func<font color="#909090">=&lt;function DefaultKeyFunc&gt;</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>computed_per_page_values</strong></dt>
-</dl>
-<dl><dt><strong>computed_summary_values</strong></dt>
-</dl>
-<dl><dt><strong>interleaved_computed_per_page_values_and_summaries</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;computed&nbsp;per&nbsp;page&nbsp;values&nbsp;and&nbsp;summary&nbsp;values&nbsp;interleaved.<br>
-&nbsp;<br>
-All&nbsp;the&nbsp;results&nbsp;for&nbsp;a&nbsp;given&nbsp;name&nbsp;are&nbsp;printed&nbsp;together.&nbsp;First&nbsp;per&nbsp;page<br>
-values,&nbsp;then&nbsp;summary&nbsp;values.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.value.trace.html b/catapult/telemetry/docs/pydoc/telemetry.value.trace.html
deleted file mode 100644
index 3e1353a..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.value.trace.html
+++ /dev/null
@@ -1,168 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.value.trace</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.value.html"><font color="#ffffff">value</font></a>.trace</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/value/trace.py">telemetry/value/trace.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="StringIO.html">StringIO</a><br>
-<a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="datetime.html">datetime</a><br>
-<a href="telemetry.internal.util.file_handle.html">telemetry.internal.util.file_handle</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-<a href="random.html">random</a><br>
-<a href="shutil.html">shutil</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="tempfile.html">tempfile</a><br>
-<a href="tracing_build.trace2html.html">tracing_build.trace2html</a><br>
-<a href="telemetry.timeline.trace_data.html">telemetry.timeline.trace_data</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.html">telemetry.value</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.html#Value">telemetry.value.Value</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.value.trace.html#TraceValue">TraceValue</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceValue">class <strong>TraceValue</strong></a>(<a href="telemetry.value.html#Value">telemetry.value.Value</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.value.trace.html#TraceValue">TraceValue</a></dd>
-<dd><a href="telemetry.value.html#Value">telemetry.value.Value</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TraceValue-AsDict"><strong>AsDict</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-CleanUp"><strong>CleanUp</strong></a>(self)</dt><dd><tt>Cleans&nbsp;up&nbsp;tempfile&nbsp;after&nbsp;it&nbsp;is&nbsp;no&nbsp;longer&nbsp;needed.<br>
-&nbsp;<br>
-A&nbsp;cleaned&nbsp;up&nbsp;<a href="#TraceValue">TraceValue</a>&nbsp;cannot&nbsp;be&nbsp;used&nbsp;for&nbsp;further&nbsp;operations.&nbsp;<a href="#TraceValue-CleanUp">CleanUp</a>()<br>
-may&nbsp;be&nbsp;called&nbsp;more&nbsp;than&nbsp;once&nbsp;without&nbsp;error.</tt></dd></dl>
-
-<dl><dt><a name="TraceValue-GetBuildbotDataType"><strong>GetBuildbotDataType</strong></a>(self, output_context)</dt></dl>
-
-<dl><dt><a name="TraceValue-GetBuildbotValue"><strong>GetBuildbotValue</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-GetRepresentativeNumber"><strong>GetRepresentativeNumber</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-GetRepresentativeString"><strong>GetRepresentativeString</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-Serialize"><strong>Serialize</strong></a>(self, dir_path)</dt></dl>
-
-<dl><dt><a name="TraceValue-UploadToCloud"><strong>UploadToCloud</strong></a>(self, bucket)</dt></dl>
-
-<dl><dt><a name="TraceValue-__enter__"><strong>__enter__</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-__exit__"><strong>__exit__</strong></a>(self, _, __, ___)</dt></dl>
-
-<dl><dt><a name="TraceValue-__init__"><strong>__init__</strong></a>(self, page, trace_data, important<font color="#909090">=False</font>, description<font color="#909090">=None</font>)</dt><dd><tt>A&nbsp;value&nbsp;that&nbsp;contains&nbsp;a&nbsp;TraceData&nbsp;object&nbsp;and&nbsp;knows&nbsp;how&nbsp;to<br>
-output&nbsp;it.<br>
-&nbsp;<br>
-Adding&nbsp;TraceValues&nbsp;and&nbsp;outputting&nbsp;as&nbsp;JSON&nbsp;will&nbsp;produce&nbsp;a&nbsp;directory&nbsp;full&nbsp;of<br>
-HTML&nbsp;files&nbsp;called&nbsp;trace_files.&nbsp;Outputting&nbsp;as&nbsp;chart&nbsp;JSON&nbsp;will&nbsp;also&nbsp;produce<br>
-an&nbsp;index,&nbsp;files.html,&nbsp;linking&nbsp;to&nbsp;each&nbsp;of&nbsp;these&nbsp;files.</tt></dd></dl>
-
-<dl><dt><a name="TraceValue-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TraceValue-MergeLikeValuesFromDifferentPages"><strong>MergeLikeValuesFromDifferentPages</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<dl><dt><a name="TraceValue-MergeLikeValuesFromSamePage"><strong>MergeLikeValuesFromSamePage</strong></a>(cls, values)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TraceValue-GetJSONTypeName"><strong>GetJSONTypeName</strong></a>()</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>cleaned_up</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="TraceValue-AsDictWithoutBaseClassEntries"><strong>AsDictWithoutBaseClassEntries</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-GetChartAndTraceNameForComputedSummaryResult"><strong>GetChartAndTraceNameForComputedSummaryResult</strong></a>(self, trace_tag)</dt></dl>
-
-<dl><dt><a name="TraceValue-GetChartAndTraceNameForPerPageResult"><strong>GetChartAndTraceNameForPerPageResult</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="TraceValue-IsMergableWith"><strong>IsMergableWith</strong></a>(self, that)</dt></dl>
-
-<dl><dt><a name="TraceValue-__eq__"><strong>__eq__</strong></a>(self, other)</dt></dl>
-
-<dl><dt><a name="TraceValue-__hash__"><strong>__hash__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><a name="TraceValue-FromDict"><strong>FromDict</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;a&nbsp;value&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-<a href="telemetry.value.html#Value">Value</a>&nbsp;dicts&nbsp;are&nbsp;produced&nbsp;by&nbsp;serialization&nbsp;to&nbsp;JSON,&nbsp;and&nbsp;must&nbsp;be&nbsp;accompanied<br>
-by&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages,&nbsp;also&nbsp;produced&nbsp;by&nbsp;serialization,&nbsp;in<br>
-order&nbsp;to&nbsp;be&nbsp;completely&nbsp;deserialized.&nbsp;If&nbsp;deserializing&nbsp;multiple&nbsp;values,&nbsp;use<br>
-ListOfValuesFromListOfDicts&nbsp;instead.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#TraceValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="TraceValue-GetConstructorKwArgs"><strong>GetConstructorKwArgs</strong></a>(value_dict, page_dict)</dt><dd><tt>Produces&nbsp;constructor&nbsp;arguments&nbsp;from&nbsp;a&nbsp;value&nbsp;dict&nbsp;and&nbsp;a&nbsp;page&nbsp;dict.<br>
-&nbsp;<br>
-Takes&nbsp;a&nbsp;dict&nbsp;parsed&nbsp;from&nbsp;JSON&nbsp;and&nbsp;an&nbsp;index&nbsp;of&nbsp;pages&nbsp;and&nbsp;recovers&nbsp;the<br>
-keyword&nbsp;arguments&nbsp;to&nbsp;be&nbsp;passed&nbsp;to&nbsp;the&nbsp;constructor&nbsp;for&nbsp;deserializing&nbsp;the<br>
-dict.<br>
-&nbsp;<br>
-value_dict:&nbsp;a&nbsp;dictionary&nbsp;produced&nbsp;by&nbsp;<a href="#TraceValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<dl><dt><a name="TraceValue-ListOfValuesFromListOfDicts"><strong>ListOfValuesFromListOfDicts</strong></a>(value_dicts, page_dict)</dt><dd><tt>Takes&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;to&nbsp;values.<br>
-&nbsp;<br>
-Given&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;AsDict,&nbsp;this&nbsp;method<br>
-deserializes&nbsp;the&nbsp;dicts&nbsp;given&nbsp;a&nbsp;dict&nbsp;mapping&nbsp;page&nbsp;IDs&nbsp;to&nbsp;pages.<br>
-This&nbsp;method&nbsp;performs&nbsp;memoization&nbsp;for&nbsp;deserializing&nbsp;a&nbsp;list&nbsp;of&nbsp;values<br>
-efficiently,&nbsp;where&nbsp;FromDict&nbsp;is&nbsp;meant&nbsp;to&nbsp;handle&nbsp;one-offs.<br>
-&nbsp;<br>
-values:&nbsp;a&nbsp;list&nbsp;of&nbsp;value&nbsp;dicts&nbsp;produced&nbsp;by&nbsp;<a href="#TraceValue-AsDict">AsDict</a>()&nbsp;on&nbsp;a&nbsp;value&nbsp;subclass.<br>
-page_dict:&nbsp;a&nbsp;dictionary&nbsp;mapping&nbsp;IDs&nbsp;to&nbsp;page&nbsp;objects.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.value.html#Value">telemetry.value.Value</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>name_suffix</strong></dt>
-<dd><tt>Returns&nbsp;the&nbsp;string&nbsp;after&nbsp;a&nbsp;.&nbsp;in&nbsp;the&nbsp;name,&nbsp;or&nbsp;the&nbsp;full&nbsp;name&nbsp;otherwise.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.html
deleted file mode 100644
index 1a609e9..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.html
+++ /dev/null
@@ -1,33 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.web_perf</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.web_perf</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/__init__.py">telemetry/web_perf/__init__.py</a></font></td></tr></table>
-    <p><tt>The&nbsp;web_perf&nbsp;module&nbsp;provides&nbsp;utilities&nbsp;and&nbsp;measurements&nbsp;for&nbsp;benchmarking&nbsp;web<br>
-app's&nbsp;performance.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.web_perf.metrics.html"><strong>metrics</strong>&nbsp;(package)</a><br>
-<a href="telemetry.web_perf.smooth_gesture_util.html">smooth_gesture_util</a><br>
-<a href="telemetry.web_perf.smooth_gesture_util_unittest.html">smooth_gesture_util_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.story_test.html">story_test</a><br>
-<a href="telemetry.web_perf.timeline_based_measurement.html">timeline_based_measurement</a><br>
-<a href="telemetry.web_perf.timeline_based_measurement_unittest.html">timeline_based_measurement_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.timeline_based_page_test.html">timeline_based_page_test</a><br>
-<a href="telemetry.web_perf.timeline_based_page_test_unittest.html">timeline_based_page_test_unittest</a><br>
-<a href="telemetry.web_perf.timeline_interaction_record.html">timeline_interaction_record</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.timeline_interaction_record_unittest.html">timeline_interaction_record_unittest</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.blob_timeline.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.blob_timeline.html
deleted file mode 100644
index 5bd7910..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.blob_timeline.html
+++ /dev/null
@@ -1,104 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.blob_timeline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.blob_timeline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/blob_timeline.py">telemetry/web_perf/metrics/blob_timeline.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.blob_timeline.html#BlobTimelineMetric">BlobTimelineMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="BlobTimelineMetric">class <strong>BlobTimelineMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#BlobTimelineMetric">BlobTimelineMetric</a>&nbsp;reports&nbsp;timing&nbsp;information&nbsp;about&nbsp;blob&nbsp;storage.<br>
-&nbsp;<br>
-The&nbsp;following&nbsp;metrics&nbsp;are&nbsp;added&nbsp;to&nbsp;the&nbsp;results:<br>
-&nbsp;&nbsp;*&nbsp;blob&nbsp;write&nbsp;times&nbsp;(blob_writes)<br>
-&nbsp;&nbsp;*&nbsp;blob&nbsp;read&nbsp;times&nbsp;(blob_reads)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.blob_timeline.html#BlobTimelineMetric">BlobTimelineMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="BlobTimelineMetric-AddResults"><strong>AddResults</strong></a>(self, model, renderer_thread, interactions, results)</dt></dl>
-
-<dl><dt><a name="BlobTimelineMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="BlobTimelineMetric-IsEventInInteraction"><strong>IsEventInInteraction</strong></a>(event, interaction)</dt></dl>
-
-<dl><dt><a name="BlobTimelineMetric-IsReadEvent"><strong>IsReadEvent</strong></a>(event)</dt></dl>
-
-<dl><dt><a name="BlobTimelineMetric-IsWriteEvent"><strong>IsWriteEvent</strong></a>(event)</dt></dl>
-
-<dl><dt><a name="BlobTimelineMetric-ThreadDurationIfPresent"><strong>ThreadDurationIfPresent</strong></a>(event)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="BlobTimelineMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="BlobTimelineMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>READ_EVENT_NAME</strong> = 'BlobRequest'<br>
-<strong>WRITE_EVENT_NAME</strong> = 'Registry::RegisterBlob'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.gpu_timeline.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.gpu_timeline.html
deleted file mode 100644
index 596a628..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.gpu_timeline.html
+++ /dev/null
@@ -1,112 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.gpu_timeline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.gpu_timeline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/gpu_timeline.py">telemetry/web_perf/metrics/gpu_timeline.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-<a href="math.html">math</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.model.html">telemetry.timeline.model</a><br>
-<a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-</td><td width="25%" valign=top><a href="sys.html">sys</a><br>
-<a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.gpu_timeline.html#GPUTimelineMetric">GPUTimelineMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="GPUTimelineMetric">class <strong>GPUTimelineMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Computes&nbsp;GPU&nbsp;based&nbsp;metrics.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.gpu_timeline.html#GPUTimelineMetric">GPUTimelineMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="GPUTimelineMetric-AddResults"><strong>AddResults</strong></a>(self, model, _, interaction_records, results)</dt></dl>
-
-<dl><dt><a name="GPUTimelineMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="GPUTimelineMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="GPUTimelineMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-TimelineName"><strong>TimelineName</strong></a>(name, source_type, value_type)</dt><dd><tt>Constructs&nbsp;the&nbsp;standard&nbsp;name&nbsp;given&nbsp;in&nbsp;the&nbsp;timeline.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;name:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;timeline,&nbsp;for&nbsp;example&nbsp;"total",&nbsp;or&nbsp;"render_compositor".<br>
-&nbsp;&nbsp;source_type:&nbsp;One&nbsp;of&nbsp;"cpu",&nbsp;"gpu"&nbsp;or&nbsp;None.&nbsp;None&nbsp;is&nbsp;only&nbsp;used&nbsp;for&nbsp;total&nbsp;times.<br>
-&nbsp;&nbsp;value_type:&nbsp;the&nbsp;type&nbsp;of&nbsp;value.&nbsp;For&nbsp;example&nbsp;"mean",&nbsp;"stddev"...etc.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEVICE_FRAME_END_MARKER</strong> = ('disabled-by-default-gpu.device', 'SwapBuffer')<br>
-<strong>SERVICE_FRAME_END_MARKER</strong> = ('disabled-by-default-gpu.service', 'SwapBuffer')<br>
-<strong>TOPLEVEL_DEVICE_CATEGORY</strong> = 'disabled-by-default-gpu.device'<br>
-<strong>TOPLEVEL_GL_CATEGORY</strong> = 'gpu_toplevel'<br>
-<strong>TOPLEVEL_SERVICE_CATEGORY</strong> = 'disabled-by-default-gpu.service'<br>
-<strong>TRACKED_GL_CONTEXT_NAME</strong> = {'BrowserCompositor': 'browser_compositor', 'Compositor': 'browser_compositor', 'RenderCompositor': 'render_compositor'}</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.html
deleted file mode 100644
index 40c9200..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.html
+++ /dev/null
@@ -1,51 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.web_perf.metrics</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.metrics</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/__init__.py">telemetry/web_perf/metrics/__init__.py</a></font></td></tr></table>
-    <p><tt>The&nbsp;web_perf.metrics&nbsp;module&nbsp;provides&nbsp;metrics&nbsp;for&nbsp;analyzing&nbsp;web&nbsp;performance.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.web_perf.metrics.blob_timeline.html">blob_timeline</a><br>
-<a href="telemetry.web_perf.metrics.blob_timeline_unittest.html">blob_timeline_unittest</a><br>
-<a href="telemetry.web_perf.metrics.gpu_timeline.html">gpu_timeline</a><br>
-<a href="telemetry.web_perf.metrics.gpu_timeline_unittest.html">gpu_timeline_unittest</a><br>
-<a href="telemetry.web_perf.metrics.indexeddb_timeline.html">indexeddb_timeline</a><br>
-<a href="telemetry.web_perf.metrics.layout.html">layout</a><br>
-<a href="telemetry.web_perf.metrics.mainthread_jank_stats.html">mainthread_jank_stats</a><br>
-<a href="telemetry.web_perf.metrics.mainthread_jank_stats_unittest.html">mainthread_jank_stats_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.memory_timeline.html">memory_timeline</a><br>
-<a href="telemetry.web_perf.metrics.memory_timeline_unittest.html">memory_timeline_unittest</a><br>
-<a href="telemetry.web_perf.metrics.rendering_frame.html">rendering_frame</a><br>
-<a href="telemetry.web_perf.metrics.rendering_frame_unittest.html">rendering_frame_unittest</a><br>
-<a href="telemetry.web_perf.metrics.rendering_stats.html">rendering_stats</a><br>
-<a href="telemetry.web_perf.metrics.rendering_stats_unittest.html">rendering_stats_unittest</a><br>
-<a href="telemetry.web_perf.metrics.responsiveness_metric.html">responsiveness_metric</a><br>
-<a href="telemetry.web_perf.metrics.single_event.html">single_event</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.single_event_unittest.html">single_event_unittest</a><br>
-<a href="telemetry.web_perf.metrics.smoothness.html">smoothness</a><br>
-<a href="telemetry.web_perf.metrics.smoothness_unittest.html">smoothness_unittest</a><br>
-<a href="telemetry.web_perf.metrics.text_selection.html">text_selection</a><br>
-<a href="telemetry.web_perf.metrics.timeline_based_metric.html">timeline_based_metric</a><br>
-<a href="telemetry.web_perf.metrics.timeline_based_metric_unittest.html">timeline_based_metric_unittest</a><br>
-<a href="telemetry.web_perf.metrics.trace_event_stats.html">trace_event_stats</a><br>
-<a href="telemetry.web_perf.metrics.trace_event_stats_unittest.html">trace_event_stats_unittest</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.v8_gc_latency.html">v8_gc_latency</a><br>
-<a href="telemetry.web_perf.metrics.v8_gc_latency_unittest.html">v8_gc_latency_unittest</a><br>
-<a href="telemetry.web_perf.metrics.webrtc_rendering_stats.html">webrtc_rendering_stats</a><br>
-<a href="telemetry.web_perf.metrics.webrtc_rendering_stats_unittest.html">webrtc_rendering_stats_unittest</a><br>
-<a href="telemetry.web_perf.metrics.webrtc_rendering_timeline.html">webrtc_rendering_timeline</a><br>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.indexeddb_timeline.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.indexeddb_timeline.html
deleted file mode 100644
index 7509b9b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.indexeddb_timeline.html
+++ /dev/null
@@ -1,80 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.indexeddb_timeline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.indexeddb_timeline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/indexeddb_timeline.py">telemetry/web_perf/metrics/indexeddb_timeline.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.indexeddb_timeline.html#IndexedDBTimelineMetric">IndexedDBTimelineMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="IndexedDBTimelineMetric">class <strong>IndexedDBTimelineMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Metrics&nbsp;for&nbsp;IndexedDB&nbsp;operations.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.indexeddb_timeline.html#IndexedDBTimelineMetric">IndexedDBTimelineMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="IndexedDBTimelineMetric-AddResults"><strong>AddResults</strong></a>(self, model, renderer_process, interactions, results)</dt></dl>
-
-<dl><dt><a name="IndexedDBTimelineMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="IndexedDBTimelineMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="IndexedDBTimelineMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.layout.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.layout.html
deleted file mode 100644
index 470bac7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.layout.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.layout</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.layout</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/layout.py">telemetry/web_perf/metrics/layout.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.web_perf.metrics.single_event.html">telemetry.web_perf.metrics.single_event</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.layout.html#LayoutMetric">LayoutMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="LayoutMetric">class <strong>LayoutMetric</strong></a>(<a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Reports&nbsp;directly&nbsp;durations&nbsp;of&nbsp;FrameView::performLayout&nbsp;events.<br>
-&nbsp;<br>
-&nbsp;&nbsp;layout:&nbsp;Durations&nbsp;of&nbsp;FrameView::performLayout&nbsp;events&nbsp;that&nbsp;were&nbsp;caused&nbsp;by&nbsp;and<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;start&nbsp;during&nbsp;user&nbsp;interaction.<br>
-&nbsp;<br>
-Layout&nbsp;happens&nbsp;no&nbsp;more&nbsp;than&nbsp;once&nbsp;per&nbsp;frame,&nbsp;so&nbsp;per-frame-ness&nbsp;is&nbsp;implied.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.layout.html#LayoutMetric">LayoutMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="LayoutMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a>:<br>
-<dl><dt><a name="LayoutMetric-AddResults"><strong>AddResults</strong></a>(self, _model, renderer_thread, interactions, results)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="LayoutMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="LayoutMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>EVENT_NAME</strong> = 'FrameView::performLayout'<br>
-<strong>METRIC_NAME</strong> = 'layout'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.mainthread_jank_stats.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.mainthread_jank_stats.html
deleted file mode 100644
index 9b1d0cc..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.mainthread_jank_stats.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.mainthread_jank_stats</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.mainthread_jank_stats</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/mainthread_jank_stats.py">telemetry/web_perf/metrics/mainthread_jank_stats.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.mainthread_jank_stats.html#MainthreadJankStats">MainthreadJankStats</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MainthreadJankStats">class <strong>MainthreadJankStats</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Utility&nbsp;class&nbsp;for&nbsp;extracting&nbsp;main&nbsp;thread&nbsp;jank&nbsp;statistics&nbsp;from&nbsp;the&nbsp;timeline<br>
-(or&nbsp;other&nbsp;loggin&nbsp;facilities),&nbsp;and&nbsp;providing&nbsp;them&nbsp;in&nbsp;a&nbsp;common&nbsp;format&nbsp;to<br>
-classes&nbsp;that&nbsp;compute&nbsp;benchmark&nbsp;metrics&nbsp;from&nbsp;this&nbsp;data.<br>
-&nbsp;<br>
-&nbsp;&nbsp;total_big_jank_thread_time&nbsp;is&nbsp;the&nbsp;total&nbsp;thread&nbsp;duration&nbsp;of&nbsp;all&nbsp;top<br>
-&nbsp;&nbsp;slices&nbsp;whose&nbsp;thread&nbsp;time&nbsp;ranges&nbsp;overlapped&nbsp;with&nbsp;any&nbsp;thread&nbsp;time&nbsp;ranges&nbsp;of<br>
-&nbsp;&nbsp;the&nbsp;records&nbsp;and&nbsp;the&nbsp;overlapped&nbsp;thread&nbsp;duration&nbsp;is&nbsp;greater&nbsp;than&nbsp;or&nbsp;equal<br>
-&nbsp;&nbsp;USER_PERCEIVABLE_DELAY_THRESHOLD_MS.<br>
-&nbsp;<br>
-&nbsp;&nbsp;biggest_jank_thread_time&nbsp;is&nbsp;the&nbsp;biggest&nbsp;thread&nbsp;duration&nbsp;of&nbsp;all<br>
-&nbsp;&nbsp;top&nbsp;slices&nbsp;whose&nbsp;thread&nbsp;time&nbsp;ranges&nbsp;overlapped&nbsp;with&nbsp;any&nbsp;of&nbsp;records'&nbsp;thread<br>
-&nbsp;&nbsp;time&nbsp;ranges.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="MainthreadJankStats-__init__"><strong>__init__</strong></a>(self, renderer_thread, interaction_records)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>biggest_jank_thread_time</strong></dt>
-</dl>
-<dl><dt><strong>total_big_jank_thread_time</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>USER_PERCEIVABLE_DELAY_THRESHOLD_MS</strong> = 50</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.memory_timeline.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.memory_timeline.html
deleted file mode 100644
index a1d2520..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.memory_timeline.html
+++ /dev/null
@@ -1,91 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.memory_timeline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.memory_timeline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/memory_timeline.py">telemetry/web_perf/metrics/memory_timeline.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-<a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-<a href="telemetry.timeline.memory_dump_event.html">telemetry.timeline.memory_dump_event</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.memory_timeline.html#MemoryTimelineMetric">MemoryTimelineMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MemoryTimelineMetric">class <strong>MemoryTimelineMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#MemoryTimelineMetric">MemoryTimelineMetric</a>&nbsp;reports&nbsp;summary&nbsp;stats&nbsp;from&nbsp;memory&nbsp;dump&nbsp;events.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.memory_timeline.html#MemoryTimelineMetric">MemoryTimelineMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="MemoryTimelineMetric-AddResults"><strong>AddResults</strong></a>(self, model, _renderer_thread, interactions, results)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="MemoryTimelineMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimelineMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<dl><dt><a name="MemoryTimelineMetric-__init__"><strong>__init__</strong></a>(self)</dt><dd><tt>Computes&nbsp;metrics&nbsp;from&nbsp;a&nbsp;telemetry.timeline&nbsp;Model&nbsp;and&nbsp;a&nbsp;range</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>DEFAULT_METRICS</strong> = ['mmaps_ashmem', 'mmaps_private_dirty', 'mmaps_overall_pss', 'mmaps_native_heap', 'mmaps_java_heap']</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.rendering_frame.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.rendering_frame.html
deleted file mode 100644
index f3e3688..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.rendering_frame.html
+++ /dev/null
@@ -1,206 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.rendering_frame</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.rendering_frame</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/rendering_frame.py">telemetry/web_perf/metrics/rendering_frame.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.timeline.bounds.html">telemetry.timeline.bounds</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.slice.html">telemetry.timeline.slice</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.rendering_frame.html#RenderingFrame">RenderingFrame</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.rendering_frame.html#MissingData">MissingData</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.rendering_frame.html#NoBeginFrameIdException">NoBeginFrameIdException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="MissingData">class <strong>MissingData</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.rendering_frame.html#MissingData">MissingData</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="MissingData-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#MissingData-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="MissingData-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MissingData-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="MissingData-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#MissingData-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="MissingData-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NoBeginFrameIdException">class <strong>NoBeginFrameIdException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.rendering_frame.html#NoBeginFrameIdException">NoBeginFrameIdException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="NoBeginFrameIdException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#NoBeginFrameIdException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="NoBeginFrameIdException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#NoBeginFrameIdException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="NoBeginFrameIdException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RenderingFrame">class <strong>RenderingFrame</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Object&nbsp;with&nbsp;information&nbsp;about&nbsp;the&nbsp;triggering&nbsp;of&nbsp;a&nbsp;BeginMainFrame&nbsp;event.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="RenderingFrame-__init__"><strong>__init__</strong></a>(self, events)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="RenderingFrame-IsEventUseful"><strong>IsEventUseful</strong></a>(event)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>bounds</strong></dt>
-</dl>
-<dl><dt><strong>queueing_duration</strong></dt>
-</dl>
-<hr>
-Data and other attributes defined here:<br>
-<dl><dt><strong>begin_main_frame_event</strong> = 'ThreadProxy::BeginMainFrame'</dl>
-
-<dl><dt><strong>send_begin_frame_event</strong> = 'ThreadProxy::ScheduledActionSendBeginMainFrame'</dl>
-
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetFrameEventsInsideRange"><strong>GetFrameEventsInsideRange</strong></a>(renderer_process, timeline_range)</dt><dd><tt>Returns&nbsp;RenderingFrames&nbsp;for&nbsp;all&nbsp;relevant&nbsp;events&nbsp;in&nbsp;the&nbsp;timeline_range.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.rendering_stats.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.rendering_stats.html
deleted file mode 100644
index 721b672..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.rendering_stats.html
+++ /dev/null
@@ -1,120 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.rendering_stats</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.rendering_stats</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/rendering_stats.py">telemetry/web_perf/metrics/rendering_stats.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="itertools.html">itertools</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.rendering_frame.html">telemetry.web_perf.metrics.rendering_frame</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.rendering_stats.html#RenderingStats">RenderingStats</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="RenderingStats">class <strong>RenderingStats</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="RenderingStats-__init__"><strong>__init__</strong></a>(self, renderer_process, browser_process, surface_flinger_process, timeline_ranges)</dt><dd><tt>Utility&nbsp;class&nbsp;for&nbsp;extracting&nbsp;rendering&nbsp;statistics&nbsp;from&nbsp;the&nbsp;timeline&nbsp;(or<br>
-other&nbsp;loggin&nbsp;facilities),&nbsp;and&nbsp;providing&nbsp;them&nbsp;in&nbsp;a&nbsp;common&nbsp;format&nbsp;to&nbsp;classes<br>
-that&nbsp;compute&nbsp;benchmark&nbsp;metrics&nbsp;from&nbsp;this&nbsp;data.<br>
-&nbsp;<br>
-Stats&nbsp;are&nbsp;lists&nbsp;of&nbsp;lists&nbsp;of&nbsp;numbers.&nbsp;The&nbsp;outer&nbsp;list&nbsp;stores&nbsp;one&nbsp;list&nbsp;per<br>
-timeline&nbsp;range.<br>
-&nbsp;<br>
-All&nbsp;*_time&nbsp;values&nbsp;are&nbsp;measured&nbsp;in&nbsp;milliseconds.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-ComputeEventLatencies"><strong>ComputeEventLatencies</strong></a>(input_events)</dt><dd><tt>Compute&nbsp;input&nbsp;event&nbsp;latencies.<br>
-&nbsp;<br>
-Input&nbsp;event&nbsp;latency&nbsp;is&nbsp;the&nbsp;time&nbsp;from&nbsp;when&nbsp;the&nbsp;input&nbsp;event&nbsp;is&nbsp;created&nbsp;to<br>
-when&nbsp;its&nbsp;resulted&nbsp;page&nbsp;is&nbsp;swap&nbsp;buffered.<br>
-Input&nbsp;event&nbsp;on&nbsp;differnt&nbsp;platforms&nbsp;uses&nbsp;different&nbsp;LatencyInfo&nbsp;component&nbsp;to<br>
-record&nbsp;its&nbsp;creation&nbsp;timestamp.&nbsp;We&nbsp;go&nbsp;through&nbsp;the&nbsp;following&nbsp;component&nbsp;list<br>
-to&nbsp;find&nbsp;the&nbsp;creation&nbsp;timestamp:<br>
-1.&nbsp;INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT&nbsp;--&nbsp;when&nbsp;event&nbsp;is&nbsp;created&nbsp;in&nbsp;OS<br>
-2.&nbsp;INPUT_EVENT_LATENCY_UI_COMPONENT&nbsp;--&nbsp;when&nbsp;event&nbsp;reaches&nbsp;Chrome<br>
-3.&nbsp;INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT&nbsp;--&nbsp;when&nbsp;event&nbsp;reaches&nbsp;RenderWidget<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;latency&nbsp;starts&nbsp;with&nbsp;a<br>
-LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT&nbsp;component,&nbsp;then&nbsp;it&nbsp;is<br>
-classified&nbsp;as&nbsp;a&nbsp;scroll&nbsp;update&nbsp;instead&nbsp;of&nbsp;a&nbsp;normal&nbsp;input&nbsp;latency&nbsp;measure.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;A&nbsp;list&nbsp;sorted&nbsp;by&nbsp;increasing&nbsp;start&nbsp;time&nbsp;of&nbsp;latencies&nbsp;which&nbsp;are&nbsp;tuples&nbsp;of<br>
-&nbsp;&nbsp;(input_event_name,&nbsp;latency_in_ms).</tt></dd></dl>
- <dl><dt><a name="-GetLatencyEvents"><strong>GetLatencyEvents</strong></a>(process, timeline_range)</dt><dd><tt>Get&nbsp;LatencyInfo&nbsp;trace&nbsp;events&nbsp;from&nbsp;the&nbsp;process's&nbsp;trace&nbsp;buffer&nbsp;that&nbsp;are<br>
-&nbsp;&nbsp;&nbsp;within&nbsp;the&nbsp;timeline_range.<br>
-&nbsp;<br>
-Input&nbsp;events&nbsp;dump&nbsp;their&nbsp;LatencyInfo&nbsp;into&nbsp;trace&nbsp;buffer&nbsp;as&nbsp;async&nbsp;trace&nbsp;event<br>
-of&nbsp;name&nbsp;starting&nbsp;with&nbsp;"InputLatency".&nbsp;Non-input&nbsp;events&nbsp;with&nbsp;name&nbsp;starting<br>
-with&nbsp;"Latency".&nbsp;The&nbsp;trace&nbsp;event&nbsp;has&nbsp;a&nbsp;memeber&nbsp;'data'&nbsp;containing&nbsp;its&nbsp;latency<br>
-history.</tt></dd></dl>
- <dl><dt><a name="-GetTimestampEventName"><strong>GetTimestampEventName</strong></a>(process)</dt><dd><tt>Returns&nbsp;the&nbsp;name&nbsp;of&nbsp;the&nbsp;events&nbsp;used&nbsp;to&nbsp;count&nbsp;frame&nbsp;timestamps.</tt></dd></dl>
- <dl><dt><a name="-HasRenderingStats"><strong>HasRenderingStats</strong></a>(process)</dt><dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;process&nbsp;contains&nbsp;at&nbsp;least&nbsp;one<br>
-BenchmarkInstrumentation::*<a href="#RenderingStats">RenderingStats</a>&nbsp;event&nbsp;with&nbsp;a&nbsp;frame.</tt></dd></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>APPROXIMATED_PIXEL_ERROR</strong> = 'approximated_pixel_percentages'<br>
-<strong>APPROXIMATED_VISIBLE_CONTENT_DATA</strong> = 'approximated_visible_content_area'<br>
-<strong>BEGIN_COMP_NAME</strong> = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT'<br>
-<strong>BEGIN_SCROLL_UPDATE_COMP_NAME</strong> = 'LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT'<br>
-<strong>CHECKERBOARDED_PIXEL_ERROR</strong> = 'checkerboarded_pixel_percentages'<br>
-<strong>CHECKERBOARDED_VISIBLE_CONTENT_DATA</strong> = 'checkerboarded_visible_content_area'<br>
-<strong>END_COMP_NAME</strong> = 'INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT'<br>
-<strong>FORWARD_SCROLL_UPDATE_COMP_NAME</strong> = 'INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT'<br>
-<strong>GESTURE_SCROLL_UPDATE_EVENT_NAME</strong> = 'InputLatency::GestureScrollUpdate'<br>
-<strong>MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME</strong> = 'Latency::ScrollUpdate'<br>
-<strong>ORIGINAL_COMP_NAME</strong> = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'<br>
-<strong>UI_COMP_NAME</strong> = 'INPUT_EVENT_LATENCY_UI_COMPONENT'<br>
-<strong>VISIBLE_CONTENT_DATA</strong> = 'visible_content_area'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.responsiveness_metric.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.responsiveness_metric.html
deleted file mode 100644
index 0d8d702..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.responsiveness_metric.html
+++ /dev/null
@@ -1,96 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.responsiveness_metric</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.responsiveness_metric</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/responsiveness_metric.py">telemetry/web_perf/metrics/responsiveness_metric.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.mainthread_jank_stats.html">telemetry.web_perf.metrics.mainthread_jank_stats</a><br>
-<a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-<a href="telemetry.web_perf.timeline_interaction_record.html">telemetry.web_perf.timeline_interaction_record</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.responsiveness_metric.html#ResponsivenessMetric">ResponsivenessMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ResponsivenessMetric">class <strong>ResponsivenessMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Computes&nbsp;metrics&nbsp;that&nbsp;measure&nbsp;respsonsiveness&nbsp;on&nbsp;the&nbsp;record&nbsp;ranges.<br>
-&nbsp;<br>
-&nbsp;total_big_jank_thread_time&nbsp;is&nbsp;the&nbsp;total&nbsp;thread&nbsp;duration&nbsp;of&nbsp;all&nbsp;top<br>
-&nbsp;slices&nbsp;whose&nbsp;thread&nbsp;time&nbsp;ranges&nbsp;overlapped&nbsp;with&nbsp;any&nbsp;thread&nbsp;time&nbsp;ranges&nbsp;of<br>
-&nbsp;the&nbsp;records&nbsp;and&nbsp;the&nbsp;overlapped&nbsp;thread&nbsp;duration&nbsp;is&nbsp;greater&nbsp;than&nbsp;or&nbsp;equal<br>
-&nbsp;USER_PERCEIVABLE_DELAY_THRESHOLD_MS.<br>
-&nbsp;<br>
-&nbsp;biggest_jank_thread_time&nbsp;is&nbsp;the&nbsp;biggest&nbsp;thread&nbsp;duration&nbsp;of&nbsp;all<br>
-&nbsp;top&nbsp;slices&nbsp;whose&nbsp;thread&nbsp;time&nbsp;ranges&nbsp;overlapped&nbsp;with&nbsp;any&nbsp;of&nbsp;records'&nbsp;thread<br>
-&nbsp;time&nbsp;ranges.<br>
-&nbsp;<br>
-All&nbsp;*_time&nbsp;values&nbsp;are&nbsp;measured&nbsp;in&nbsp;milliseconds.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.responsiveness_metric.html#ResponsivenessMetric">ResponsivenessMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="ResponsivenessMetric-AddResults"><strong>AddResults</strong></a>(self, _, renderer_thread, interaction_records, results)</dt></dl>
-
-<dl><dt><a name="ResponsivenessMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="ResponsivenessMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="ResponsivenessMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.single_event.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.single_event.html
deleted file mode 100644
index 7f4e43b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.single_event.html
+++ /dev/null
@@ -1,27 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.single_event</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.single_event</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/single_event.py">telemetry/web_perf/metrics/single_event.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.smoothness.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.smoothness.html
deleted file mode 100644
index 5081ad7..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.smoothness.html
+++ /dev/null
@@ -1,112 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.smoothness</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.smoothness</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/smoothness.py">telemetry/web_perf/metrics/smoothness.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-<a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.util.perf_tests_helper.html">telemetry.util.perf_tests_helper</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.rendering_stats.html">telemetry.web_perf.metrics.rendering_stats</a><br>
-<a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.statistics.html">telemetry.util.statistics</a><br>
-<a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.smoothness.html#SmoothnessMetric">SmoothnessMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="SmoothnessMetric">class <strong>SmoothnessMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Computes&nbsp;metrics&nbsp;that&nbsp;measure&nbsp;smoothness&nbsp;of&nbsp;animations&nbsp;over&nbsp;given&nbsp;ranges.<br>
-&nbsp;<br>
-Animations&nbsp;are&nbsp;typically&nbsp;considered&nbsp;smooth&nbsp;if&nbsp;the&nbsp;frame&nbsp;rates&nbsp;are&nbsp;close&nbsp;to<br>
-60&nbsp;frames&nbsp;per&nbsp;second&nbsp;(fps)&nbsp;and&nbsp;uniformly&nbsp;distributed&nbsp;over&nbsp;the&nbsp;sequence.&nbsp;To<br>
-determine&nbsp;if&nbsp;a&nbsp;timeline&nbsp;range&nbsp;contains&nbsp;a&nbsp;smooth&nbsp;animation,&nbsp;we&nbsp;update&nbsp;the<br>
-results&nbsp;object&nbsp;with&nbsp;several&nbsp;representative&nbsp;metrics:<br>
-&nbsp;<br>
-&nbsp;&nbsp;frame_times:&nbsp;A&nbsp;list&nbsp;of&nbsp;raw&nbsp;frame&nbsp;times<br>
-&nbsp;&nbsp;mean_frame_time:&nbsp;The&nbsp;arithmetic&nbsp;mean&nbsp;of&nbsp;frame&nbsp;times<br>
-&nbsp;&nbsp;percentage_smooth:&nbsp;Percentage&nbsp;of&nbsp;frames&nbsp;that&nbsp;were&nbsp;hitting&nbsp;60&nbsp;FPS.<br>
-&nbsp;&nbsp;frame_time_discrepancy:&nbsp;The&nbsp;absolute&nbsp;discrepancy&nbsp;of&nbsp;frame&nbsp;timestamps<br>
-&nbsp;&nbsp;mean_pixels_approximated:&nbsp;The&nbsp;mean&nbsp;percentage&nbsp;of&nbsp;pixels&nbsp;approximated<br>
-&nbsp;&nbsp;queueing_durations:&nbsp;The&nbsp;queueing&nbsp;delay&nbsp;between&nbsp;compositor&nbsp;&amp;&nbsp;main&nbsp;threads<br>
-&nbsp;<br>
-Note&nbsp;that&nbsp;if&nbsp;any&nbsp;of&nbsp;the&nbsp;interaction&nbsp;records&nbsp;provided&nbsp;to&nbsp;AddResults&nbsp;have&nbsp;less<br>
-than&nbsp;2&nbsp;frames,&nbsp;we&nbsp;will&nbsp;return&nbsp;telemetry&nbsp;values&nbsp;with&nbsp;None&nbsp;values&nbsp;for&nbsp;each&nbsp;of<br>
-the&nbsp;smoothness&nbsp;metrics.&nbsp;Similarly,&nbsp;older&nbsp;browsers&nbsp;without&nbsp;support&nbsp;for<br>
-tracking&nbsp;the&nbsp;BeginMainFrame&nbsp;events&nbsp;will&nbsp;report&nbsp;a&nbsp;ListOfScalarValues&nbsp;with&nbsp;a<br>
-None&nbsp;value&nbsp;for&nbsp;the&nbsp;queueing&nbsp;duration&nbsp;metric.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.smoothness.html#SmoothnessMetric">SmoothnessMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="SmoothnessMetric-AddResults"><strong>AddResults</strong></a>(self, model, renderer_thread, interaction_records, results)</dt></dl>
-
-<dl><dt><a name="SmoothnessMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="SmoothnessMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="SmoothnessMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>NOT_ENOUGH_FRAMES_MESSAGE</strong> = "Not enough frames for smoothness metrics (at lea...der extremely slow<font color="#c040c0">\n</font>- Pages that can't be scrolled"</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.text_selection.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.text_selection.html
deleted file mode 100644
index 9418ac5..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.text_selection.html
+++ /dev/null
@@ -1,92 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.text_selection</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.text_selection</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/text_selection.py">telemetry/web_perf/metrics/text_selection.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.web_perf.metrics.single_event.html">telemetry.web_perf.metrics.single_event</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.text_selection.html#TextSelectionMetric">TextSelectionMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TextSelectionMetric">class <strong>TextSelectionMetric</strong></a>(<a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Reports&nbsp;directly&nbsp;durations&nbsp;of&nbsp;WebLocalFrameImpl::moveRangeSelectionExtent<br>
-events&nbsp;associated&nbsp;with&nbsp;moving&nbsp;a&nbsp;selection&nbsp;extent.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.text_selection.html#TextSelectionMetric">TextSelectionMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TextSelectionMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.single_event.html#_SingleEventMetric">telemetry.web_perf.metrics.single_event._SingleEventMetric</a>:<br>
-<dl><dt><a name="TextSelectionMetric-AddResults"><strong>AddResults</strong></a>(self, _model, renderer_thread, interactions, results)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="TextSelectionMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="TextSelectionMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>EVENT_NAME</strong> = 'WebLocalFrameImpl::moveRangeSelectionExtent'<br>
-<strong>METRIC_NAME</strong> = 'text-selection'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.timeline_based_metric.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.timeline_based_metric.html
deleted file mode 100644
index c0f1ed6..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.timeline_based_metric.html
+++ /dev/null
@@ -1,157 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.timeline_based_metric</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.timeline_based_metric</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/timeline_based_metric.py">telemetry/web_perf/metrics/timeline_based_metric.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">TimelineBasedMetric</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetricException">TimelineBasedMetricException</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineBasedMetric">class <strong>TimelineBasedMetric</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimelineBasedMetric-AddResults"><strong>AddResults</strong></a>(self, model, renderer_thread, interaction_records, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;for&nbsp;the&nbsp;interaction_records'&nbsp;time&nbsp;ranges.<br>
-&nbsp;<br>
-The&nbsp;override&nbsp;of&nbsp;this&nbsp;method&nbsp;should&nbsp;compute&nbsp;results&nbsp;on&nbsp;the&nbsp;data&nbsp;**only**<br>
-within&nbsp;the&nbsp;interaction_records'&nbsp;start&nbsp;and&nbsp;end&nbsp;time&nbsp;ranges.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;interaction_records:&nbsp;A&nbsp;list&nbsp;of&nbsp;instances&nbsp;of&nbsp;TimelineInteractionRecord.&nbsp;If<br>
-&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;override&nbsp;of&nbsp;this&nbsp;method&nbsp;doesn't&nbsp;support&nbsp;overlapped&nbsp;ranges,&nbsp;use<br>
-&nbsp;&nbsp;&nbsp;&nbsp;VerifyNonOverlappedRecords&nbsp;to&nbsp;check&nbsp;that&nbsp;no&nbsp;records&nbsp;are&nbsp;overlapped.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetric-__init__"><strong>__init__</strong></a>(self)</dt><dd><tt>Computes&nbsp;metrics&nbsp;from&nbsp;a&nbsp;telemetry.timeline&nbsp;Model&nbsp;and&nbsp;a&nbsp;range</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineBasedMetricException">class <strong>TimelineBasedMetricException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="exceptions.html#Exception">Exception</a>&nbsp;that&nbsp;can&nbsp;be&nbsp;thrown&nbsp;from&nbsp;metrics&nbsp;that&nbsp;implements<br>
-<a href="#TimelineBasedMetric">TimelineBasedMetric</a>&nbsp;to&nbsp;indicate&nbsp;a&nbsp;problem&nbsp;arised&nbsp;when&nbsp;computing&nbsp;the&nbsp;metric.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetricException">TimelineBasedMetricException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="TimelineBasedMetricException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#TimelineBasedMetricException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="TimelineBasedMetricException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#TimelineBasedMetricException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMetricException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-IsEventInInteractions"><strong>IsEventInInteractions</strong></a>(event, interaction_records)</dt><dd><tt>Return&nbsp;True&nbsp;if&nbsp;event&nbsp;is&nbsp;in&nbsp;any&nbsp;of&nbsp;the&nbsp;interaction&nbsp;records'&nbsp;time&nbsp;range.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;event:&nbsp;an&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.event.TimelineEvent.<br>
-&nbsp;&nbsp;interaction_records:&nbsp;a&nbsp;list&nbsp;of&nbsp;interaction&nbsp;records,&nbsp;whereas&nbsp;each&nbsp;record&nbsp;is<br>
-&nbsp;&nbsp;&nbsp;&nbsp;an&nbsp;instance&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;telemetry.web_perf.timeline_interaction_record.TimelineInteractionRecord.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;True&nbsp;if&nbsp;|event|'s&nbsp;start&nbsp;&amp;&nbsp;end&nbsp;time&nbsp;is&nbsp;in&nbsp;any&nbsp;of&nbsp;the&nbsp;|interaction_records|'s<br>
-&nbsp;&nbsp;time&nbsp;range.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.trace_event_stats.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.trace_event_stats.html
deleted file mode 100644
index 013c785..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.trace_event_stats.html
+++ /dev/null
@@ -1,107 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.trace_event_stats</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.trace_event_stats</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/trace_event_stats.py">telemetry/web_perf/metrics/trace_event_stats.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="collections.html">collections</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.trace_event_stats.html#TraceEventStats">TraceEventStats</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.trace_event_stats.html#TraceEventStatsInput">TraceEventStatsInput</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceEventStats">class <strong>TraceEventStats</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Reports&nbsp;durations&nbsp;and&nbsp;counts&nbsp;of&nbsp;given&nbsp;trace&nbsp;events.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TraceEventStats-AddInput"><strong>AddInput</strong></a>(self, trace_event_aggregator_input)</dt></dl>
-
-<dl><dt><a name="TraceEventStats-AddResults"><strong>AddResults</strong></a>(self, model, renderer_process, interactions, results)</dt></dl>
-
-<dl><dt><a name="TraceEventStats-__init__"><strong>__init__</strong></a>(self, trace_event_aggregator_inputs<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TraceEventStats-ThreadDurationIfPresent"><strong>ThreadDurationIfPresent</strong></a>(event)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TraceEventStatsInput">class <strong>TraceEventStatsInput</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Input&nbsp;for&nbsp;the&nbsp;<a href="#TraceEventStats">TraceEventStats</a>.<br>
-Using&nbsp;this&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;<a href="#TraceEventStats">TraceEventStats</a>&nbsp;will&nbsp;include&nbsp;two&nbsp;metrics,&nbsp;one&nbsp;with&nbsp;a<br>
-list&nbsp;of&nbsp;times&nbsp;of&nbsp;the&nbsp;given&nbsp;event,&nbsp;and&nbsp;one&nbsp;for&nbsp;the&nbsp;count&nbsp;of&nbsp;the&nbsp;events,&nbsp;named<br>
-`metric_name&nbsp;+&nbsp;'-count'`.<br>
-Args:<br>
-&nbsp;&nbsp;event_category:&nbsp;The&nbsp;category&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;track.<br>
-&nbsp;&nbsp;event_name:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;event&nbsp;to&nbsp;track.<br>
-&nbsp;&nbsp;metric_name:&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;metric&nbsp;name,&nbsp;which&nbsp;accumulates&nbsp;all&nbsp;of&nbsp;the<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;times&nbsp;of&nbsp;the&nbsp;events.<br>
-&nbsp;&nbsp;metric_description:&nbsp;Description&nbsp;of&nbsp;the&nbsp;metric.<br>
-&nbsp;&nbsp;units:&nbsp;Units&nbsp;for&nbsp;the&nbsp;metric.<br>
-&nbsp;&nbsp;process_name:&nbsp;(optional)&nbsp;The&nbsp;name&nbsp;of&nbsp;the&nbsp;process&nbsp;to&nbsp;inspect&nbsp;for&nbsp;the&nbsp;trace<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;events.&nbsp;Defaults&nbsp;to&nbsp;'Renderer'.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TraceEventStatsInput-__init__"><strong>__init__</strong></a>(self, event_category, event_name, metric_name, metric_description, units, process_name<font color="#909090">='Renderer'</font>)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="TraceEventStatsInput-GetEventId"><strong>GetEventId</strong></a>(event_category, event_name)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.v8_gc_latency.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.v8_gc_latency.html
deleted file mode 100644
index 15c3257..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.v8_gc_latency.html
+++ /dev/null
@@ -1,110 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.v8_gc_latency</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.v8_gc_latency</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/v8_gc_latency.py">telemetry/web_perf/metrics/v8_gc_latency.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-<a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-<a href="telemetry.util.statistics.html">telemetry.util.statistics</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.v8_gc_latency.html#V8EventStat">V8EventStat</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.v8_gc_latency.html#V8GCLatency">V8GCLatency</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="V8EventStat">class <strong>V8EventStat</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="V8EventStat-__init__"><strong>__init__</strong></a>(self, src_event_name, result_name, result_description)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>percentage_thread_duration_during_idle</strong></dt>
-</dl>
-<dl><dt><strong>thread_duration_outside_idle</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="V8GCLatency">class <strong>V8GCLatency</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.v8_gc_latency.html#V8GCLatency">V8GCLatency</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="V8GCLatency-AddResults"><strong>AddResults</strong></a>(self, model, renderer_thread, interaction_records, results)</dt></dl>
-
-<dl><dt><a name="V8GCLatency-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="V8GCLatency-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="V8GCLatency-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.webrtc_rendering_stats.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.webrtc_rendering_stats.html
deleted file mode 100644
index 3334d5f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.webrtc_rendering_stats.html
+++ /dev/null
@@ -1,98 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.webrtc_rendering_stats</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.webrtc_rendering_stats</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/webrtc_rendering_stats.py">telemetry/web_perf/metrics/webrtc_rendering_stats.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="logging.html">logging</a><br>
-</td><td width="25%" valign=top><a href="telemetry.util.statistics.html">telemetry.util.statistics</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.webrtc_rendering_stats.html#TimeStats">TimeStats</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.webrtc_rendering_stats.html#WebMediaPlayerMsRenderingStats">WebMediaPlayerMsRenderingStats</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimeStats">class <strong>TimeStats</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Stats&nbsp;container&nbsp;for&nbsp;webrtc&nbsp;rendering&nbsp;metrics.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimeStats-__init__"><strong>__init__</strong></a>(self, drift_time<font color="#909090">=None</font>, mean_drift_time<font color="#909090">=None</font>, std_dev_drift_time<font color="#909090">=None</font>, percent_badly_out_of_sync<font color="#909090">=None</font>, percent_out_of_sync<font color="#909090">=None</font>, smoothness_score<font color="#909090">=None</font>, freezing_score<font color="#909090">=None</font>, rendering_length_error<font color="#909090">=None</font>, fps<font color="#909090">=None</font>, frame_distribution<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebMediaPlayerMsRenderingStats">class <strong>WebMediaPlayerMsRenderingStats</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Analyzes&nbsp;events&nbsp;of&nbsp;WebMediaPlayerMs&nbsp;type.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="WebMediaPlayerMsRenderingStats-GetTimeStats"><strong>GetTimeStats</strong></a>(self)</dt><dd><tt>Calculate&nbsp;time&nbsp;stamp&nbsp;stats&nbsp;for&nbsp;all&nbsp;remote&nbsp;stream&nbsp;events.</tt></dd></dl>
-
-<dl><dt><a name="WebMediaPlayerMsRenderingStats-__init__"><strong>__init__</strong></a>(self, events)</dt><dd><tt>Save&nbsp;relevant&nbsp;events&nbsp;according&nbsp;to&nbsp;their&nbsp;stream.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ACTUAL_RENDER_BEGIN</strong> = 'Actual Render Begin'<br>
-<strong>ACTUAL_RENDER_END</strong> = 'Actual Render End'<br>
-<strong>DISPLAY_HERTZ</strong> = 60.0<br>
-<strong>FROZEN_THRESHOLD</strong> = 6<br>
-<strong>IDEAL_RENDER_INSTANT</strong> = 'Ideal Render Instant'<br>
-<strong>SERIAL</strong> = 'Serial'<br>
-<strong>SEVERITY</strong> = 3<br>
-<strong>VSYNC_DURATION</strong> = 16666.666666666668</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.webrtc_rendering_timeline.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.webrtc_rendering_timeline.html
deleted file mode 100644
index d9cdd5d..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.metrics.webrtc_rendering_timeline.html
+++ /dev/null
@@ -1,104 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.metrics.webrtc_rendering_timeline</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.<a href="telemetry.web_perf.metrics.html"><font color="#ffffff">metrics</font></a>.webrtc_rendering_timeline</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/metrics/webrtc_rendering_timeline.py">telemetry/web_perf/metrics/webrtc_rendering_timeline.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.value.improvement_direction.html">telemetry.value.improvement_direction</a><br>
-<a href="telemetry.value.list_of_scalar_values.html">telemetry.value.list_of_scalar_values</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.scalar.html">telemetry.value.scalar</a><br>
-<a href="telemetry.web_perf.metrics.webrtc_rendering_stats.html">telemetry.web_perf.metrics.webrtc_rendering_stats</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.metrics.webrtc_rendering_timeline.html#WebRtcRenderingTimelineMetric">WebRtcRenderingTimelineMetric</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WebRtcRenderingTimelineMetric">class <strong>WebRtcRenderingTimelineMetric</strong></a>(<a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>WebrtcRenderingTimelineMetric&nbsp;calculates&nbsp;metric&nbsp;for&nbsp;WebMediaPlayerMS.<br>
-&nbsp;<br>
-The&nbsp;following&nbsp;metrics&nbsp;are&nbsp;added&nbsp;to&nbsp;the&nbsp;results:<br>
-&nbsp;&nbsp;WebRTCRendering_drift_time&nbsp;us<br>
-&nbsp;&nbsp;WebRTCRendering_percent_badly_out_of_sync&nbsp;%<br>
-&nbsp;&nbsp;WebRTCRendering_percent_out_of_sync&nbsp;%<br>
-&nbsp;&nbsp;WebRTCRendering_fps&nbsp;FPS<br>
-&nbsp;&nbsp;WebRTCRendering_smoothness_score&nbsp;%<br>
-&nbsp;&nbsp;WebRTCRendering_freezing_score&nbsp;%<br>
-&nbsp;&nbsp;WebRTCRendering_rendering_length_error&nbsp;%<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.metrics.webrtc_rendering_timeline.html#WebRtcRenderingTimelineMetric">WebRtcRenderingTimelineMetric</a></dd>
-<dd><a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="WebRtcRenderingTimelineMetric-AddResults"><strong>AddResults</strong></a>(self, model, renderer_thread, interactions, results)</dt><dd><tt>Adding&nbsp;metrics&nbsp;to&nbsp;the&nbsp;results.</tt></dd></dl>
-
-<dl><dt><a name="WebRtcRenderingTimelineMetric-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Static methods defined here:<br>
-<dl><dt><a name="WebRtcRenderingTimelineMetric-IsMediaPlayerMSEvent"><strong>IsMediaPlayerMSEvent</strong></a>(event)</dt><dd><tt>Verify&nbsp;that&nbsp;the&nbsp;event&nbsp;is&nbsp;a&nbsp;webmediaplayerMS&nbsp;event.</tt></dd></dl>
-
-<hr>
-Methods inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><a name="WebRtcRenderingTimelineMetric-AddWholeTraceResults"><strong>AddWholeTraceResults</strong></a>(self, model, results)</dt><dd><tt>Computes&nbsp;and&nbsp;adds&nbsp;metrics&nbsp;corresponding&nbsp;to&nbsp;the&nbsp;entire&nbsp;trace.<br>
-&nbsp;<br>
-Override&nbsp;this&nbsp;method&nbsp;to&nbsp;compute&nbsp;results&nbsp;that&nbsp;correspond&nbsp;to&nbsp;the&nbsp;whole&nbsp;trace.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;model:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.model.TimelineModel.<br>
-&nbsp;&nbsp;results:&nbsp;An&nbsp;instance&nbsp;of&nbsp;page.PageTestResults.</tt></dd></dl>
-
-<dl><dt><a name="WebRtcRenderingTimelineMetric-VerifyNonOverlappedRecords"><strong>VerifyNonOverlappedRecords</strong></a>(self, interaction_records)</dt><dd><tt>This&nbsp;raises&nbsp;exceptions&nbsp;if&nbsp;interaction_records&nbsp;contain&nbsp;overlapped&nbsp;ranges.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.metrics.timeline_based_metric.html#TimelineBasedMetric">telemetry.web_perf.metrics.timeline_based_metric.TimelineBasedMetric</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>WEB_MEDIA_PLAYER_MS_EVENT</strong> = 'WebMediaPlayerMS::UpdateCurrentFrame'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.smooth_gesture_util.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.smooth_gesture_util.html
deleted file mode 100644
index 06743f8..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.smooth_gesture_util.html
+++ /dev/null
@@ -1,42 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.smooth_gesture_util</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.smooth_gesture_util</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/smooth_gesture_util.py">telemetry/web_perf/smooth_gesture_util.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="copy.html">copy</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.timeline_interaction_record.html">telemetry.web_perf.timeline_interaction_record</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetAdjustedInteractionIfContainGesture"><strong>GetAdjustedInteractionIfContainGesture</strong></a>(timeline, interaction_record)</dt><dd><tt>Returns&nbsp;a&nbsp;new&nbsp;interaction&nbsp;record&nbsp;if&nbsp;interaction_record&nbsp;contains&nbsp;geture<br>
-whose&nbsp;time&nbsp;range&nbsp;that&nbsp;overlaps&nbsp;with&nbsp;interaction_record's&nbsp;range.&nbsp;If&nbsp;not,<br>
-returns&nbsp;a&nbsp;clone&nbsp;of&nbsp;original&nbsp;interaction_record.<br>
-The&nbsp;synthetic&nbsp;gesture&nbsp;controller&nbsp;inserts&nbsp;a&nbsp;trace&nbsp;marker&nbsp;to&nbsp;precisely<br>
-demarcate&nbsp;when&nbsp;the&nbsp;gesture&nbsp;was&nbsp;running.&nbsp;We&nbsp;check&nbsp;for&nbsp;overlap,&nbsp;not&nbsp;inclusion,<br>
-because&nbsp;gesture_actions&nbsp;can&nbsp;start/end&nbsp;slightly&nbsp;outside&nbsp;the&nbsp;telemetry&nbsp;markers<br>
-on&nbsp;Windows.&nbsp;This&nbsp;problem&nbsp;is&nbsp;probably&nbsp;caused&nbsp;by&nbsp;a&nbsp;race&nbsp;condition&nbsp;between<br>
-the&nbsp;browser&nbsp;and&nbsp;renderer&nbsp;process&nbsp;submitting&nbsp;the&nbsp;trace&nbsp;events&nbsp;for&nbsp;the<br>
-markers.</tt></dd></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.story_test.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.story_test.html
deleted file mode 100644
index 762e837..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.story_test.html
+++ /dev/null
@@ -1,144 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.story_test</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.story_test</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/story_test.py">telemetry/web_perf/story_test.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.story_test.html#StoryTest">StoryTest</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.story_test.html#Failure">Failure</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Failure">class <strong>Failure</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="#StoryTest">StoryTest</a>&nbsp;<a href="exceptions.html#Exception">Exception</a>&nbsp;raised&nbsp;when&nbsp;an&nbsp;undesired&nbsp;but&nbsp;designed-for&nbsp;problem.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.story_test.html#Failure">Failure</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="Failure-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#Failure-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="Failure-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Failure-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="Failure-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="Failure-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="Failure-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="Failure-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="Failure-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="Failure-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="Failure-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#Failure-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="Failure-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="StoryTest">class <strong>StoryTest</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;class&nbsp;for&nbsp;creating&nbsp;story&nbsp;tests.<br>
-&nbsp;<br>
-The&nbsp;overall&nbsp;test&nbsp;run&nbsp;control&nbsp;flow&nbsp;follows&nbsp;this&nbsp;order:<br>
-&nbsp;&nbsp;test.WillRunStory<br>
-&nbsp;&nbsp;state.WillRunStory<br>
-&nbsp;&nbsp;state.RunStory<br>
-&nbsp;&nbsp;test.Measure<br>
-&nbsp;&nbsp;state.DidRunStory<br>
-&nbsp;&nbsp;test.DidRunStory<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="StoryTest-DidRunStory"><strong>DidRunStory</strong></a>(self, platform)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;after&nbsp;running&nbsp;the&nbsp;story,&nbsp;e.g.,&nbsp;clean&nbsp;up.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;run&nbsp;after&nbsp;state.DidRunStory.&nbsp;And&nbsp;this&nbsp;is&nbsp;always&nbsp;called&nbsp;even&nbsp;if&nbsp;the<br>
-test&nbsp;run&nbsp;failed.<br>
-Args:<br>
-&nbsp;&nbsp;platform:&nbsp;The&nbsp;platform&nbsp;that&nbsp;the&nbsp;story&nbsp;will&nbsp;run&nbsp;on.</tt></dd></dl>
-
-<dl><dt><a name="StoryTest-Measure"><strong>Measure</strong></a>(self, platform, results)</dt><dd><tt>Override&nbsp;to&nbsp;take&nbsp;the&nbsp;measurement.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;run&nbsp;only&nbsp;if&nbsp;state.RunStory&nbsp;is&nbsp;successful.<br>
-Args:<br>
-&nbsp;&nbsp;platform:&nbsp;The&nbsp;platform&nbsp;that&nbsp;the&nbsp;story&nbsp;will&nbsp;run&nbsp;on.<br>
-&nbsp;&nbsp;results:&nbsp;The&nbsp;results&nbsp;of&nbsp;running&nbsp;the&nbsp;story.</tt></dd></dl>
-
-<dl><dt><a name="StoryTest-WillRunStory"><strong>WillRunStory</strong></a>(self, platform)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;any&nbsp;action&nbsp;before&nbsp;running&nbsp;the&nbsp;story.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;run&nbsp;before&nbsp;state.WillRunStory.<br>
-Args:<br>
-&nbsp;&nbsp;platform:&nbsp;The&nbsp;platform&nbsp;that&nbsp;the&nbsp;story&nbsp;will&nbsp;run&nbsp;on.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_based_measurement.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_based_measurement.html
deleted file mode 100644
index 0761e8f..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_based_measurement.html
+++ /dev/null
@@ -1,269 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.timeline_based_measurement</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.timeline_based_measurement</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/timeline_based_measurement.py">telemetry/web_perf/timeline_based_measurement.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.web_perf.metrics.blob_timeline.html">telemetry.web_perf.metrics.blob_timeline</a><br>
-<a href="collections.html">collections</a><br>
-<a href="telemetry.web_perf.metrics.gpu_timeline.html">telemetry.web_perf.metrics.gpu_timeline</a><br>
-<a href="telemetry.web_perf.metrics.indexeddb_timeline.html">telemetry.web_perf.metrics.indexeddb_timeline</a><br>
-<a href="telemetry.web_perf.metrics.layout.html">telemetry.web_perf.metrics.layout</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="telemetry.web_perf.metrics.memory_timeline.html">telemetry.web_perf.metrics.memory_timeline</a><br>
-<a href="telemetry.timeline.model.html">telemetry.timeline.model</a><br>
-<a href="telemetry.web_perf.metrics.responsiveness_metric.html">telemetry.web_perf.metrics.responsiveness_metric</a><br>
-<a href="telemetry.web_perf.smooth_gesture_util.html">telemetry.web_perf.smooth_gesture_util</a><br>
-</td><td width="25%" valign=top><a href="telemetry.web_perf.metrics.smoothness.html">telemetry.web_perf.metrics.smoothness</a><br>
-<a href="telemetry.web_perf.story_test.html">telemetry.web_perf.story_test</a><br>
-<a href="telemetry.web_perf.metrics.text_selection.html">telemetry.web_perf.metrics.text_selection</a><br>
-<a href="telemetry.web_perf.metrics.timeline_based_metric.html">telemetry.web_perf.metrics.timeline_based_metric</a><br>
-<a href="telemetry.web_perf.timeline_interaction_record.html">telemetry.web_perf.timeline_interaction_record</a><br>
-</td><td width="25%" valign=top><a href="telemetry.value.trace.html">telemetry.value.trace</a><br>
-<a href="telemetry.timeline.tracing_category_filter.html">telemetry.timeline.tracing_category_filter</a><br>
-<a href="telemetry.timeline.tracing_options.html">telemetry.timeline.tracing_options</a><br>
-<a href="telemetry.web_perf.metrics.webrtc_rendering_timeline.html">telemetry.web_perf.metrics.webrtc_rendering_timeline</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_based_measurement.html#Options">Options</a>
-</font></dt><dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_based_measurement.html#ResultsWrapperInterface">ResultsWrapperInterface</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_based_measurement.html#InvalidInteractions">InvalidInteractions</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.story_test.html#StoryTest">telemetry.web_perf.story_test.StoryTest</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_based_measurement.html#TimelineBasedMeasurement">TimelineBasedMeasurement</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="InvalidInteractions">class <strong>InvalidInteractions</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.timeline_based_measurement.html#InvalidInteractions">InvalidInteractions</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="InvalidInteractions-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#InvalidInteractions-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="InvalidInteractions-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InvalidInteractions-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="InvalidInteractions-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#InvalidInteractions-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="InvalidInteractions-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="Options">class <strong>Options</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>A&nbsp;class&nbsp;to&nbsp;be&nbsp;used&nbsp;to&nbsp;configure&nbsp;<a href="#TimelineBasedMeasurement">TimelineBasedMeasurement</a>.<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;created&nbsp;and&nbsp;returned&nbsp;by<br>
-Benchmark.CreateTimelineBasedMeasurementOptions.<br>
-&nbsp;<br>
-By&nbsp;default,&nbsp;all&nbsp;the&nbsp;timeline&nbsp;based&nbsp;metrics&nbsp;in&nbsp;telemetry/web_perf/metrics&nbsp;are<br>
-used&nbsp;(see&nbsp;_GetAllTimelineBasedMetrics&nbsp;above).<br>
-To&nbsp;customize&nbsp;your&nbsp;metric&nbsp;needs,&nbsp;use&nbsp;<a href="#Options-SetTimelineBasedMetrics">SetTimelineBasedMetrics</a>().<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="Options-ExtendTraceCategoryFilter"><strong>ExtendTraceCategoryFilter</strong></a>(self, filters)</dt></dl>
-
-<dl><dt><a name="Options-GetTimelineBasedMetrics"><strong>GetTimelineBasedMetrics</strong></a>(self)</dt></dl>
-
-<dl><dt><a name="Options-SetTimelineBasedMetrics"><strong>SetTimelineBasedMetrics</strong></a>(self, metrics)</dt></dl>
-
-<dl><dt><a name="Options-__init__"><strong>__init__</strong></a>(self, overhead_level<font color="#909090">='no-overhead'</font>)</dt><dd><tt>As&nbsp;the&nbsp;amount&nbsp;of&nbsp;instrumentation&nbsp;increases,&nbsp;so&nbsp;does&nbsp;the&nbsp;overhead.<br>
-The&nbsp;user&nbsp;of&nbsp;the&nbsp;measurement&nbsp;chooses&nbsp;the&nbsp;overhead&nbsp;level&nbsp;that&nbsp;is&nbsp;appropriate,<br>
-and&nbsp;the&nbsp;tracing&nbsp;is&nbsp;filtered&nbsp;accordingly.<br>
-&nbsp;<br>
-overhead_level:&nbsp;Can&nbsp;either&nbsp;be&nbsp;a&nbsp;custom&nbsp;TracingCategoryFilter&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;or<br>
-&nbsp;&nbsp;&nbsp;&nbsp;one&nbsp;of&nbsp;NO_OVERHEAD_LEVEL,&nbsp;MINIMAL_OVERHEAD_LEVEL&nbsp;or<br>
-&nbsp;&nbsp;&nbsp;&nbsp;DEBUG_OVERHEAD_LEVEL.</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>category_filter</strong></dt>
-</dl>
-<dl><dt><strong>tracing_options</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ResultsWrapperInterface">class <strong>ResultsWrapperInterface</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>#&nbsp;TODO(nednguyen):&nbsp;Get&nbsp;rid&nbsp;of&nbsp;this&nbsp;results&nbsp;wrapper&nbsp;hack&nbsp;after&nbsp;we&nbsp;add&nbsp;interaction<br>
-#&nbsp;record&nbsp;to&nbsp;telemetry&nbsp;value&nbsp;system&nbsp;(crbug.com/453109)<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="ResultsWrapperInterface-AddValue"><strong>AddValue</strong></a>(self, value)</dt></dl>
-
-<dl><dt><a name="ResultsWrapperInterface-SetResults"><strong>SetResults</strong></a>(self, results)</dt></dl>
-
-<dl><dt><a name="ResultsWrapperInterface-SetTirLabel"><strong>SetTirLabel</strong></a>(self, tir_label)</dt></dl>
-
-<dl><dt><a name="ResultsWrapperInterface-__init__"><strong>__init__</strong></a>(self)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>current_page</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineBasedMeasurement">class <strong>TimelineBasedMeasurement</strong></a>(<a href="telemetry.web_perf.story_test.html#StoryTest">telemetry.web_perf.story_test.StoryTest</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Collects&nbsp;multiple&nbsp;metrics&nbsp;based&nbsp;on&nbsp;their&nbsp;interaction&nbsp;records.<br>
-&nbsp;<br>
-A&nbsp;timeline&nbsp;based&nbsp;measurement&nbsp;shifts&nbsp;the&nbsp;burden&nbsp;of&nbsp;what&nbsp;metrics&nbsp;to&nbsp;collect&nbsp;onto<br>
-the&nbsp;story&nbsp;under&nbsp;test.&nbsp;Instead&nbsp;of&nbsp;the&nbsp;measurement<br>
-having&nbsp;a&nbsp;fixed&nbsp;set&nbsp;of&nbsp;values&nbsp;it&nbsp;collects,&nbsp;the&nbsp;story&nbsp;being&nbsp;tested<br>
-issues&nbsp;(via&nbsp;javascript)&nbsp;an&nbsp;Interaction&nbsp;record&nbsp;into&nbsp;the&nbsp;user&nbsp;timing&nbsp;API&nbsp;that<br>
-describing&nbsp;what&nbsp;is&nbsp;happening&nbsp;at&nbsp;that&nbsp;time,&nbsp;as&nbsp;well&nbsp;as&nbsp;a&nbsp;standardized&nbsp;set<br>
-of&nbsp;flags&nbsp;describing&nbsp;the&nbsp;semantics&nbsp;of&nbsp;the&nbsp;work&nbsp;being&nbsp;done.&nbsp;The<br>
-<a href="#TimelineBasedMeasurement">TimelineBasedMeasurement</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;collects&nbsp;a&nbsp;trace&nbsp;that&nbsp;includes&nbsp;both&nbsp;these<br>
-interaction&nbsp;records,&nbsp;and&nbsp;a&nbsp;user-chosen&nbsp;amount&nbsp;of&nbsp;performance&nbsp;data&nbsp;using<br>
-Telemetry's&nbsp;various&nbsp;timeline-producing&nbsp;APIs,&nbsp;tracing&nbsp;especially.<br>
-&nbsp;<br>
-It&nbsp;then&nbsp;passes&nbsp;the&nbsp;recorded&nbsp;timeline&nbsp;to&nbsp;different&nbsp;TimelineBasedMetrics&nbsp;based<br>
-on&nbsp;those&nbsp;flags.&nbsp;As&nbsp;an&nbsp;example,&nbsp;this&nbsp;allows&nbsp;a&nbsp;single&nbsp;story&nbsp;run&nbsp;to&nbsp;produce<br>
-load&nbsp;timing&nbsp;data,&nbsp;smoothness&nbsp;data,&nbsp;critical&nbsp;jank&nbsp;information&nbsp;and&nbsp;overall&nbsp;cpu<br>
-usage&nbsp;information.<br>
-&nbsp;<br>
-For&nbsp;information&nbsp;on&nbsp;how&nbsp;to&nbsp;mark&nbsp;up&nbsp;a&nbsp;page&nbsp;to&nbsp;work&nbsp;with<br>
-<a href="#TimelineBasedMeasurement">TimelineBasedMeasurement</a>,&nbsp;refer&nbsp;to&nbsp;the<br>
-perf.metrics.timeline_interaction_record&nbsp;module.<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;&nbsp;&nbsp;options:&nbsp;an&nbsp;instance&nbsp;of&nbsp;timeline_based_measurement.<a href="#Options">Options</a>.<br>
-&nbsp;&nbsp;&nbsp;&nbsp;results_wrapper:&nbsp;A&nbsp;class&nbsp;that&nbsp;has&nbsp;the&nbsp;__init__&nbsp;method&nbsp;takes&nbsp;in<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;the&nbsp;page_test_results&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;and&nbsp;the&nbsp;interaction&nbsp;record&nbsp;label.&nbsp;This<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class&nbsp;follows&nbsp;the&nbsp;<a href="#ResultsWrapperInterface">ResultsWrapperInterface</a>.&nbsp;Note:&nbsp;this&nbsp;class&nbsp;is&nbsp;not<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;supported&nbsp;long&nbsp;term&nbsp;and&nbsp;to&nbsp;be&nbsp;removed&nbsp;when&nbsp;crbug.com/453109&nbsp;is&nbsp;resolved.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.timeline_based_measurement.html#TimelineBasedMeasurement">TimelineBasedMeasurement</a></dd>
-<dd><a href="telemetry.web_perf.story_test.html#StoryTest">telemetry.web_perf.story_test.StoryTest</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TimelineBasedMeasurement-DidRunStory"><strong>DidRunStory</strong></a>(self, platform)</dt><dd><tt>Clean&nbsp;up&nbsp;after&nbsp;running&nbsp;the&nbsp;story.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMeasurement-Measure"><strong>Measure</strong></a>(self, platform, results)</dt><dd><tt>Collect&nbsp;all&nbsp;possible&nbsp;metrics&nbsp;and&nbsp;added&nbsp;them&nbsp;to&nbsp;results.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMeasurement-WillRunStory"><strong>WillRunStory</strong></a>(self, platform)</dt><dd><tt>Configure&nbsp;and&nbsp;start&nbsp;tracing.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedMeasurement-__init__"><strong>__init__</strong></a>(self, options, results_wrapper<font color="#909090">=None</font>)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.story_test.html#StoryTest">telemetry.web_perf.story_test.StoryTest</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>ALL_OVERHEAD_LEVELS</strong> = ['no-overhead', 'minimal-overhead', 'debug-overhead']<br>
-<strong>DEBUG_OVERHEAD_LEVEL</strong> = 'debug-overhead'<br>
-<strong>MINIMAL_OVERHEAD_LEVEL</strong> = 'minimal-overhead'<br>
-<strong>NO_OVERHEAD_LEVEL</strong> = 'no-overhead'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_based_page_test.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_based_page_test.html
deleted file mode 100644
index e3cbb38..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_based_page_test.html
+++ /dev/null
@@ -1,136 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.timeline_based_page_test</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.timeline_based_page_test</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/timeline_based_page_test.py">telemetry/web_perf/timeline_based_page_test.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;(c)&nbsp;2015&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.page.page_test.html">telemetry.page.page_test</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>(<a href="__builtin__.html#object">__builtin__.object</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_based_page_test.html#TimelineBasedPageTest">TimelineBasedPageTest</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineBasedPageTest">class <strong>TimelineBasedPageTest</strong></a>(<a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Page&nbsp;test&nbsp;that&nbsp;collects&nbsp;metrics&nbsp;with&nbsp;TimelineBasedMeasurement.<br>
-&nbsp;<br>
-WillRunStory(),&nbsp;Measure()&nbsp;and&nbsp;DidRunStory()&nbsp;are&nbsp;all&nbsp;done&nbsp;in&nbsp;story_runner<br>
-explicitly.&nbsp;We&nbsp;still&nbsp;need&nbsp;this&nbsp;wrapper&nbsp;around&nbsp;<a href="telemetry.page.page_test.html#PageTest">PageTest</a>&nbsp;because&nbsp;it&nbsp;executes<br>
-some&nbsp;browser&nbsp;related&nbsp;functions&nbsp;in&nbsp;the&nbsp;parent&nbsp;class,&nbsp;which&nbsp;is&nbsp;needed&nbsp;by<br>
-Timeline&nbsp;Based&nbsp;Measurement&nbsp;benchmarks.&nbsp;This&nbsp;class&nbsp;will&nbsp;be&nbsp;removed&nbsp;after<br>
-page_test's&nbsp;hooks&nbsp;are&nbsp;fully&nbsp;removed.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.timeline_based_page_test.html#TimelineBasedPageTest">TimelineBasedPageTest</a></dd>
-<dd><a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Methods defined here:<br>
-<dl><dt><a name="TimelineBasedPageTest-ValidateAndMeasurePage"><strong>ValidateAndMeasurePage</strong></a>(self, page, tab, results)</dt><dd><tt>Collect&nbsp;all&nbsp;possible&nbsp;metrics&nbsp;and&nbsp;added&nbsp;them&nbsp;to&nbsp;results.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-__init__"><strong>__init__</strong></a>(self, tbm)</dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>measurement</strong></dt>
-</dl>
-<hr>
-Methods inherited from <a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>:<br>
-<dl><dt><a name="TimelineBasedPageTest-CustomizeBrowserOptions"><strong>CustomizeBrowserOptions</strong></a>(self, options)</dt><dd><tt>Override&nbsp;to&nbsp;add&nbsp;test-specific&nbsp;options&nbsp;to&nbsp;the&nbsp;BrowserOptions&nbsp;object</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-DidNavigateToPage"><strong>DidNavigateToPage</strong></a>(self, page, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;operations&nbsp;right&nbsp;after&nbsp;the&nbsp;page&nbsp;is&nbsp;navigated&nbsp;and&nbsp;after<br>
-all&nbsp;waiting&nbsp;for&nbsp;completion&nbsp;has&nbsp;occurred.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-DidRunPage"><strong>DidRunPage</strong></a>(self, platform)</dt><dd><tt>Called&nbsp;after&nbsp;the&nbsp;test&nbsp;run&nbsp;method&nbsp;was&nbsp;run,&nbsp;even&nbsp;if&nbsp;it&nbsp;failed.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-DidStartBrowser"><strong>DidStartBrowser</strong></a>(self, browser)</dt><dd><tt>Override&nbsp;to&nbsp;customize&nbsp;the&nbsp;browser&nbsp;right&nbsp;after&nbsp;it&nbsp;has&nbsp;launched.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-RestartBrowserBeforeEachPage"><strong>RestartBrowserBeforeEachPage</strong></a>(self)</dt><dd><tt>Should&nbsp;the&nbsp;browser&nbsp;be&nbsp;restarted&nbsp;for&nbsp;the&nbsp;page?<br>
-&nbsp;<br>
-This&nbsp;returns&nbsp;true&nbsp;if&nbsp;the&nbsp;test&nbsp;needs&nbsp;to&nbsp;unconditionally&nbsp;restart&nbsp;the<br>
-browser&nbsp;for&nbsp;each&nbsp;page.&nbsp;It&nbsp;may&nbsp;be&nbsp;called&nbsp;before&nbsp;the&nbsp;browser&nbsp;is&nbsp;started.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-RunNavigateSteps"><strong>RunNavigateSteps</strong></a>(self, page, tab)</dt><dd><tt>Navigates&nbsp;the&nbsp;tab&nbsp;to&nbsp;the&nbsp;page&nbsp;URL&nbsp;attribute.<br>
-&nbsp;<br>
-Runs&nbsp;the&nbsp;'navigate_steps'&nbsp;page&nbsp;attribute&nbsp;as&nbsp;a&nbsp;compound&nbsp;action.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-SetOptions"><strong>SetOptions</strong></a>(self, options)</dt><dd><tt>Sets&nbsp;the&nbsp;BrowserFinderOptions&nbsp;instance&nbsp;to&nbsp;use.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-StopBrowserAfterPage"><strong>StopBrowserAfterPage</strong></a>(self, browser, page)</dt><dd><tt>Should&nbsp;the&nbsp;browser&nbsp;be&nbsp;stopped&nbsp;after&nbsp;the&nbsp;page&nbsp;is&nbsp;run?<br>
-&nbsp;<br>
-This&nbsp;is&nbsp;called&nbsp;after&nbsp;a&nbsp;page&nbsp;is&nbsp;run&nbsp;to&nbsp;decide&nbsp;whether&nbsp;the&nbsp;browser&nbsp;needs&nbsp;to<br>
-be&nbsp;stopped&nbsp;to&nbsp;clean&nbsp;up&nbsp;its&nbsp;state.&nbsp;If&nbsp;it&nbsp;is&nbsp;stopped,&nbsp;then&nbsp;it&nbsp;will&nbsp;be<br>
-restarted&nbsp;to&nbsp;run&nbsp;the&nbsp;next&nbsp;page.<br>
-&nbsp;<br>
-A&nbsp;test&nbsp;that&nbsp;overrides&nbsp;this&nbsp;can&nbsp;look&nbsp;at&nbsp;both&nbsp;the&nbsp;page&nbsp;and&nbsp;the&nbsp;browser&nbsp;to<br>
-decide&nbsp;whether&nbsp;it&nbsp;needs&nbsp;to&nbsp;stop&nbsp;the&nbsp;browser.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-TabForPage"><strong>TabForPage</strong></a>(self, page, browser)</dt><dd><tt>Override&nbsp;to&nbsp;select&nbsp;a&nbsp;different&nbsp;tab&nbsp;for&nbsp;the&nbsp;page.&nbsp;&nbsp;For&nbsp;instance,&nbsp;to<br>
-create&nbsp;a&nbsp;new&nbsp;tab&nbsp;for&nbsp;every&nbsp;page,&nbsp;return&nbsp;browser.tabs.New().</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-WillNavigateToPage"><strong>WillNavigateToPage</strong></a>(self, page, tab)</dt><dd><tt>Override&nbsp;to&nbsp;do&nbsp;operations&nbsp;before&nbsp;the&nbsp;page&nbsp;is&nbsp;navigated,&nbsp;notably&nbsp;Telemetry<br>
-will&nbsp;already&nbsp;have&nbsp;performed&nbsp;the&nbsp;following&nbsp;operations&nbsp;on&nbsp;the&nbsp;browser&nbsp;before<br>
-calling&nbsp;this&nbsp;function:<br>
-*&nbsp;Ensure&nbsp;only&nbsp;one&nbsp;tab&nbsp;is&nbsp;open.<br>
-*&nbsp;Call&nbsp;WaitForDocumentReadyStateToComplete&nbsp;on&nbsp;the&nbsp;tab.</tt></dd></dl>
-
-<dl><dt><a name="TimelineBasedPageTest-WillStartBrowser"><strong>WillStartBrowser</strong></a>(self, platform)</dt><dd><tt>Override&nbsp;to&nbsp;manipulate&nbsp;the&nbsp;browser&nbsp;environment&nbsp;before&nbsp;it&nbsp;launches.</tt></dd></dl>
-
-<hr>
-Data descriptors inherited from <a href="telemetry.page.page_test.html#PageTest">telemetry.page.page_test.PageTest</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>clear_cache_before_each_run</strong></dt>
-<dd><tt>When&nbsp;set&nbsp;to&nbsp;True,&nbsp;the&nbsp;browser's&nbsp;disk&nbsp;and&nbsp;memory&nbsp;cache&nbsp;will&nbsp;be&nbsp;cleared<br>
-before&nbsp;each&nbsp;run.</tt></dd>
-</dl>
-<dl><dt><strong>close_tabs_before_run</strong></dt>
-<dd><tt>When&nbsp;set&nbsp;to&nbsp;True,&nbsp;all&nbsp;tabs&nbsp;are&nbsp;closed&nbsp;before&nbsp;running&nbsp;the&nbsp;test&nbsp;for&nbsp;the<br>
-first&nbsp;time.</tt></dd>
-</dl>
-<dl><dt><strong>is_multi_tab_test</strong></dt>
-<dd><tt>Returns&nbsp;True&nbsp;if&nbsp;the&nbsp;test&nbsp;opens&nbsp;multiple&nbsp;tabs.<br>
-&nbsp;<br>
-If&nbsp;the&nbsp;test&nbsp;overrides&nbsp;TabForPage,&nbsp;it&nbsp;is&nbsp;deemed&nbsp;a&nbsp;multi-tab&nbsp;test.<br>
-Multi-tab&nbsp;tests&nbsp;do&nbsp;not&nbsp;retry&nbsp;after&nbsp;tab&nbsp;or&nbsp;browser&nbsp;crashes,&nbsp;whereas,<br>
-single-tab&nbsp;tests&nbsp;too.&nbsp;That&nbsp;is&nbsp;because&nbsp;the&nbsp;state&nbsp;of&nbsp;multi-tab&nbsp;tests<br>
-(e.g.,&nbsp;how&nbsp;many&nbsp;tabs&nbsp;are&nbsp;open,&nbsp;etc.)&nbsp;is&nbsp;unknown&nbsp;after&nbsp;crashes.</tt></dd>
-</dl>
-</td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_interaction_record.html b/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_interaction_record.html
deleted file mode 100644
index 34a1639..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.web_perf.timeline_interaction_record.html
+++ /dev/null
@@ -1,317 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.web_perf.timeline_interaction_record</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.web_perf.html"><font color="#ffffff">web_perf</font></a>.timeline_interaction_record</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/web_perf/timeline_interaction_record.py">telemetry/web_perf/timeline_interaction_record.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.decorators.html">telemetry.decorators</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-</td><td width="25%" valign=top><a href="telemetry.timeline.bounds.html">telemetry.timeline.bounds</a><br>
-</td><td width="25%" valign=top></td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_interaction_record.html#TimelineInteractionRecord">TimelineInteractionRecord</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_interaction_record.html#ThreadTimeRangeOverlappedException">ThreadTimeRangeOverlappedException</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.web_perf.timeline_interaction_record.html#NoThreadTimeDataException">NoThreadTimeDataException</a>
-</font></dt></dl>
-</dd>
-</dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="NoThreadTimeDataException">class <strong>NoThreadTimeDataException</strong></a>(<a href="telemetry.web_perf.timeline_interaction_record.html#ThreadTimeRangeOverlappedException">ThreadTimeRangeOverlappedException</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="exceptions.html#Exception">Exception</a>&nbsp;that&nbsp;can&nbsp;be&nbsp;thrown&nbsp;if&nbsp;there&nbsp;is&nbsp;not&nbsp;sufficient&nbsp;thread&nbsp;time&nbsp;data<br>
-to&nbsp;compute&nbsp;the&nbsp;overlapped&nbsp;thread&nbsp;time&nbsp;range.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.timeline_interaction_record.html#NoThreadTimeDataException">NoThreadTimeDataException</a></dd>
-<dd><a href="telemetry.web_perf.timeline_interaction_record.html#ThreadTimeRangeOverlappedException">ThreadTimeRangeOverlappedException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors inherited from <a href="telemetry.web_perf.timeline_interaction_record.html#ThreadTimeRangeOverlappedException">ThreadTimeRangeOverlappedException</a>:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="NoThreadTimeDataException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#NoThreadTimeDataException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="NoThreadTimeDataException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#NoThreadTimeDataException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="NoThreadTimeDataException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ThreadTimeRangeOverlappedException">class <strong>ThreadTimeRangeOverlappedException</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt><a href="exceptions.html#Exception">Exception</a>&nbsp;that&nbsp;can&nbsp;be&nbsp;thrown&nbsp;when&nbsp;computing&nbsp;overlapped&nbsp;thread&nbsp;time&nbsp;range<br>
-with&nbsp;other&nbsp;events.<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.web_perf.timeline_interaction_record.html#ThreadTimeRangeOverlappedException">ThreadTimeRangeOverlappedException</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ThreadTimeRangeOverlappedException-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ThreadTimeRangeOverlappedException-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ThreadTimeRangeOverlappedException-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="TimelineInteractionRecord">class <strong>TimelineInteractionRecord</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
-<td colspan=2><tt>Represents&nbsp;an&nbsp;interaction&nbsp;that&nbsp;took&nbsp;place&nbsp;during&nbsp;a&nbsp;timeline&nbsp;recording.<br>
-&nbsp;<br>
-As&nbsp;a&nbsp;page&nbsp;runs,&nbsp;typically&nbsp;a&nbsp;number&nbsp;of&nbsp;different&nbsp;(simulated)&nbsp;user&nbsp;interactions<br>
-take&nbsp;place.&nbsp;For&nbsp;instance,&nbsp;a&nbsp;user&nbsp;might&nbsp;click&nbsp;a&nbsp;button&nbsp;in&nbsp;a&nbsp;mail&nbsp;app&nbsp;causing&nbsp;a<br>
-popup&nbsp;to&nbsp;animate&nbsp;in.&nbsp;Then&nbsp;they&nbsp;might&nbsp;press&nbsp;another&nbsp;button&nbsp;that&nbsp;sends&nbsp;data&nbsp;to&nbsp;a<br>
-server&nbsp;and&nbsp;simultaneously&nbsp;closes&nbsp;the&nbsp;popup&nbsp;without&nbsp;an&nbsp;animation.&nbsp;These&nbsp;are&nbsp;two<br>
-interactions.<br>
-&nbsp;<br>
-From&nbsp;the&nbsp;point&nbsp;of&nbsp;view&nbsp;of&nbsp;the&nbsp;page,&nbsp;each&nbsp;interaction&nbsp;might&nbsp;have&nbsp;a&nbsp;different<br>
-label:&nbsp;ClickComposeButton&nbsp;and&nbsp;SendEmail,&nbsp;for&nbsp;instance.&nbsp;From&nbsp;the&nbsp;point<br>
-of&nbsp;view&nbsp;of&nbsp;the&nbsp;benchmarking&nbsp;harness,&nbsp;the&nbsp;labels&nbsp;aren't&nbsp;so&nbsp;interesting&nbsp;as&nbsp;what<br>
-the&nbsp;performance&nbsp;expectations&nbsp;are&nbsp;for&nbsp;that&nbsp;interaction:&nbsp;was&nbsp;it&nbsp;loading<br>
-resources&nbsp;from&nbsp;the&nbsp;network?&nbsp;was&nbsp;there&nbsp;an&nbsp;animation?<br>
-&nbsp;<br>
-Determining&nbsp;these&nbsp;things&nbsp;is&nbsp;hard&nbsp;to&nbsp;do,&nbsp;simply&nbsp;by&nbsp;observing&nbsp;the&nbsp;state&nbsp;given&nbsp;to<br>
-a&nbsp;page&nbsp;from&nbsp;javascript.&nbsp;There&nbsp;are&nbsp;hints,&nbsp;for&nbsp;instance&nbsp;if&nbsp;network&nbsp;requests&nbsp;are<br>
-sent,&nbsp;or&nbsp;if&nbsp;a&nbsp;CSS&nbsp;animation&nbsp;is&nbsp;pending.&nbsp;But&nbsp;this&nbsp;is&nbsp;by&nbsp;no&nbsp;means&nbsp;a&nbsp;complete<br>
-story.<br>
-&nbsp;<br>
-Instead,&nbsp;we&nbsp;expect&nbsp;pages&nbsp;to&nbsp;mark&nbsp;up&nbsp;the&nbsp;timeline&nbsp;what&nbsp;they&nbsp;are&nbsp;doing,&nbsp;with<br>
-label&nbsp;and&nbsp;flags&nbsp;indicating&nbsp;the&nbsp;semantics&nbsp;of&nbsp;that&nbsp;interaction.&nbsp;This<br>
-is&nbsp;currently&nbsp;done&nbsp;by&nbsp;pushing&nbsp;markers&nbsp;into&nbsp;the&nbsp;console.time/timeEnd&nbsp;API:&nbsp;this<br>
-for&nbsp;instance&nbsp;can&nbsp;be&nbsp;issued&nbsp;in&nbsp;JS:<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;var&nbsp;str&nbsp;=&nbsp;'Interaction.SendEmail';<br>
-&nbsp;&nbsp;&nbsp;console.time(str);<br>
-&nbsp;&nbsp;&nbsp;setTimeout(function()&nbsp;{<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;console.timeEnd(str);<br>
-&nbsp;&nbsp;&nbsp;},&nbsp;1000);<br>
-&nbsp;<br>
-When&nbsp;run&nbsp;with&nbsp;perf.measurements.timeline_based_measurement&nbsp;running,&nbsp;this&nbsp;will<br>
-then&nbsp;cause&nbsp;a&nbsp;<a href="#TimelineInteractionRecord">TimelineInteractionRecord</a>&nbsp;to&nbsp;be&nbsp;created&nbsp;for&nbsp;this&nbsp;range&nbsp;with<br>
-all&nbsp;metrics&nbsp;reported&nbsp;for&nbsp;the&nbsp;marked&nbsp;up&nbsp;1000ms&nbsp;time-range.<br>
-&nbsp;<br>
-The&nbsp;valid&nbsp;interaction&nbsp;flags&nbsp;are:<br>
-&nbsp;&nbsp;&nbsp;*&nbsp;repeatable:&nbsp;Allows&nbsp;other&nbsp;interactions&nbsp;to&nbsp;use&nbsp;the&nbsp;same&nbsp;label<br>&nbsp;</tt></td></tr>
-<tr><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="TimelineInteractionRecord-GetBounds"><strong>GetBounds</strong></a>(*args, **kwargs)</dt></dl>
-
-<dl><dt><a name="TimelineInteractionRecord-GetOverlappedThreadTimeForSlice"><strong>GetOverlappedThreadTimeForSlice</strong></a>(self, timeline_slice)</dt><dd><tt>Get&nbsp;the&nbsp;thread&nbsp;duration&nbsp;of&nbsp;timeline_slice&nbsp;that&nbsp;overlaps&nbsp;with&nbsp;this&nbsp;record.<br>
-&nbsp;<br>
-There&nbsp;are&nbsp;two&nbsp;cases&nbsp;:<br>
-&nbsp;<br>
-Case&nbsp;1:&nbsp;timeline_slice&nbsp;runs&nbsp;in&nbsp;the&nbsp;same&nbsp;thread&nbsp;as&nbsp;the&nbsp;record.<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timeline_slice&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br>
-&nbsp;&nbsp;THREAD&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record&nbsp;starts&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record&nbsp;ends<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(relative&nbsp;order&nbsp;in&nbsp;thread&nbsp;time)<br>
-&nbsp;<br>
-&nbsp;&nbsp;As&nbsp;the&nbsp;thread&nbsp;timestamps&nbsp;in&nbsp;timeline_slice&nbsp;and&nbsp;record&nbsp;are&nbsp;consistent,&nbsp;we<br>
-&nbsp;&nbsp;simply&nbsp;use&nbsp;them&nbsp;to&nbsp;compute&nbsp;the&nbsp;overlap.<br>
-&nbsp;<br>
-Case&nbsp;2:&nbsp;timeline_slice&nbsp;runs&nbsp;in&nbsp;a&nbsp;different&nbsp;thread&nbsp;from&nbsp;the&nbsp;record's.<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br>
-&nbsp;&nbsp;THREAD&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;timeline_slice&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;]<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br>
-&nbsp;&nbsp;THREAD&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record&nbsp;starts&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;record&nbsp;ends<br>
-&nbsp;<br>
-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(relative&nbsp;order&nbsp;in&nbsp;wall-time)<br>
-&nbsp;<br>
-&nbsp;&nbsp;Unlike&nbsp;case&nbsp;1,&nbsp;thread&nbsp;timestamps&nbsp;of&nbsp;a&nbsp;thread&nbsp;are&nbsp;measured&nbsp;by&nbsp;its<br>
-&nbsp;&nbsp;thread-specific&nbsp;clock,&nbsp;which&nbsp;is&nbsp;inconsistent&nbsp;with&nbsp;that&nbsp;of&nbsp;the&nbsp;other<br>
-&nbsp;&nbsp;thread,&nbsp;and&nbsp;thus&nbsp;can't&nbsp;be&nbsp;used&nbsp;to&nbsp;compute&nbsp;the&nbsp;overlapped&nbsp;thread&nbsp;duration.<br>
-&nbsp;&nbsp;Hence,&nbsp;we&nbsp;use&nbsp;a&nbsp;heuristic&nbsp;to&nbsp;compute&nbsp;the&nbsp;overlap&nbsp;(see<br>
-&nbsp;&nbsp;_GetOverlappedThreadTimeForSliceInDifferentThread&nbsp;for&nbsp;more&nbsp;details)<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;timeline_slice:&nbsp;An&nbsp;instance&nbsp;of&nbsp;telemetry.timeline.slice.Slice</tt></dd></dl>
-
-<dl><dt><a name="TimelineInteractionRecord-__init__"><strong>__init__</strong></a>(self, label, start, end, async_event<font color="#909090">=None</font>, flags<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="TimelineInteractionRecord-__repr__"><strong>__repr__</strong></a>(self)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="TimelineInteractionRecord-FromAsyncEvent"><strong>FromAsyncEvent</strong></a>(cls, async_event)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt><dd><tt>Construct&nbsp;an&nbsp;timeline_interaction_record&nbsp;from&nbsp;an&nbsp;async&nbsp;event.<br>
-Args:<br>
-&nbsp;&nbsp;async_event:&nbsp;An&nbsp;instance&nbsp;of<br>
-&nbsp;&nbsp;&nbsp;&nbsp;telemetry.timeline.async_slices.AsyncSlice</tt></dd></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>end</strong></dt>
-</dl>
-<dl><dt><strong>label</strong></dt>
-</dl>
-<dl><dt><strong>repeatable</strong></dt>
-</dl>
-<dl><dt><strong>start</strong></dt>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-GetJavaScriptMarker"><strong>GetJavaScriptMarker</strong></a>(label, flags)</dt><dd><tt>Computes&nbsp;the&nbsp;marker&nbsp;string&nbsp;of&nbsp;an&nbsp;interaction&nbsp;record.<br>
-&nbsp;<br>
-This&nbsp;marker&nbsp;string&nbsp;can&nbsp;be&nbsp;used&nbsp;with&nbsp;JavaScript&nbsp;API&nbsp;console.time()<br>
-and&nbsp;console.timeEnd()&nbsp;to&nbsp;mark&nbsp;the&nbsp;beginning&nbsp;and&nbsp;end&nbsp;of&nbsp;the<br>
-interaction&nbsp;record..<br>
-&nbsp;<br>
-Args:<br>
-&nbsp;&nbsp;label:&nbsp;The&nbsp;label&nbsp;used&nbsp;to&nbsp;identify&nbsp;the&nbsp;interaction&nbsp;record.<br>
-&nbsp;&nbsp;flags:&nbsp;the&nbsp;flags&nbsp;for&nbsp;the&nbsp;interaction&nbsp;record&nbsp;see&nbsp;FLAGS&nbsp;above.<br>
-&nbsp;<br>
-Returns:<br>
-&nbsp;&nbsp;The&nbsp;interaction&nbsp;record&nbsp;marker&nbsp;string&nbsp;(e.g.,&nbsp;Interaction.Label/flag1,flag2).<br>
-&nbsp;<br>
-Raises:<br>
-&nbsp;&nbsp;AssertionError:&nbsp;If&nbsp;one&nbsp;or&nbsp;more&nbsp;of&nbsp;the&nbsp;flags&nbsp;is&nbsp;unrecognized.</tt></dd></dl>
- <dl><dt><a name="-IsTimelineInteractionRecord"><strong>IsTimelineInteractionRecord</strong></a>(event_name)</dt></dl>
-</td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#55aa55">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><strong>FLAGS</strong> = ['repeatable']<br>
-<strong>REPEATABLE</strong> = 'repeatable'</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.wpr.archive_info.html b/catapult/telemetry/docs/pydoc/telemetry.wpr.archive_info.html
deleted file mode 100644
index 300d278..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.wpr.archive_info.html
+++ /dev/null
@@ -1,157 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: module telemetry.wpr.archive_info</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.<a href="telemetry.wpr.html"><font color="#ffffff">wpr</font></a>.archive_info</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/wpr/archive_info.py">telemetry/wpr/archive_info.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2013&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Modules</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="catapult_base.cloud_storage.html">catapult_base.cloud_storage</a><br>
-<a href="json.html">json</a><br>
-</td><td width="25%" valign=top><a href="logging.html">logging</a><br>
-<a href="os.html">os</a><br>
-</td><td width="25%" valign=top><a href="re.html">re</a><br>
-<a href="shutil.html">shutil</a><br>
-</td><td width="25%" valign=top><a href="tempfile.html">tempfile</a><br>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ee77aa">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl>
-<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.wpr.archive_info.html#WprArchiveInfo">WprArchiveInfo</a>
-</font></dt></dl>
-</dd>
-<dt><font face="helvetica, arial"><a href="exceptions.html#Exception">exceptions.Exception</a>(<a href="exceptions.html#BaseException">exceptions.BaseException</a>)
-</font></dt><dd>
-<dl>
-<dt><font face="helvetica, arial"><a href="telemetry.wpr.archive_info.html#ArchiveError">ArchiveError</a>
-</font></dt></dl>
-</dd>
-</dl>
- <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="ArchiveError">class <strong>ArchiveError</strong></a>(<a href="exceptions.html#Exception">exceptions.Exception</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt>Method resolution order:</dt>
-<dd><a href="telemetry.wpr.archive_info.html#ArchiveError">ArchiveError</a></dd>
-<dd><a href="exceptions.html#Exception">exceptions.Exception</a></dd>
-<dd><a href="exceptions.html#BaseException">exceptions.BaseException</a></dd>
-<dd><a href="__builtin__.html#object">__builtin__.object</a></dd>
-</dl>
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<hr>
-Methods inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><a name="ArchiveError-__init__"><strong>__init__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__init__">__init__</a>(...)&nbsp;initializes&nbsp;x;&nbsp;see&nbsp;help(type(x))&nbsp;for&nbsp;signature</tt></dd></dl>
-
-<hr>
-Data and other attributes inherited from <a href="exceptions.html#Exception">exceptions.Exception</a>:<br>
-<dl><dt><strong>__new__</strong> = &lt;built-in method __new__ of type object&gt;<dd><tt>T.<a href="#ArchiveError-__new__">__new__</a>(S,&nbsp;...)&nbsp;-&gt;&nbsp;a&nbsp;new&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;with&nbsp;type&nbsp;S,&nbsp;a&nbsp;subtype&nbsp;of&nbsp;T</tt></dl>
-
-<hr>
-Methods inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><a name="ArchiveError-__delattr__"><strong>__delattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__delattr__">__delattr__</a>('name')&nbsp;&lt;==&gt;&nbsp;del&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__getattribute__"><strong>__getattribute__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__getattribute__">__getattribute__</a>('name')&nbsp;&lt;==&gt;&nbsp;x.name</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__getitem__"><strong>__getitem__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__getitem__">__getitem__</a>(y)&nbsp;&lt;==&gt;&nbsp;x[y]</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__getslice__"><strong>__getslice__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__getslice__">__getslice__</a>(i,&nbsp;j)&nbsp;&lt;==&gt;&nbsp;x[i:j]<br>
-&nbsp;<br>
-Use&nbsp;of&nbsp;negative&nbsp;indices&nbsp;is&nbsp;not&nbsp;supported.</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__reduce__"><strong>__reduce__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ArchiveError-__repr__"><strong>__repr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__repr__">__repr__</a>()&nbsp;&lt;==&gt;&nbsp;repr(x)</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__setattr__"><strong>__setattr__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__setattr__">__setattr__</a>('name',&nbsp;value)&nbsp;&lt;==&gt;&nbsp;x.name&nbsp;=&nbsp;value</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__setstate__"><strong>__setstate__</strong></a>(...)</dt></dl>
-
-<dl><dt><a name="ArchiveError-__str__"><strong>__str__</strong></a>(...)</dt><dd><tt>x.<a href="#ArchiveError-__str__">__str__</a>()&nbsp;&lt;==&gt;&nbsp;str(x)</tt></dd></dl>
-
-<dl><dt><a name="ArchiveError-__unicode__"><strong>__unicode__</strong></a>(...)</dt></dl>
-
-<hr>
-Data descriptors inherited from <a href="exceptions.html#BaseException">exceptions.BaseException</a>:<br>
-<dl><dt><strong>__dict__</strong></dt>
-</dl>
-<dl><dt><strong>args</strong></dt>
-</dl>
-<dl><dt><strong>message</strong></dt>
-</dl>
-</td></tr></table> <p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#ffc8d8">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#000000" face="helvetica, arial"><a name="WprArchiveInfo">class <strong>WprArchiveInfo</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>
-    
-<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%">Methods defined here:<br>
-<dl><dt><a name="WprArchiveInfo-AddNewTemporaryRecording"><strong>AddNewTemporaryRecording</strong></a>(self, temp_wpr_file_path<font color="#909090">=None</font>)</dt></dl>
-
-<dl><dt><a name="WprArchiveInfo-AddRecordedStories"><strong>AddRecordedStories</strong></a>(self, stories, upload_to_cloud_storage<font color="#909090">=False</font>)</dt></dl>
-
-<dl><dt><a name="WprArchiveInfo-DownloadArchivesIfNeeded"><strong>DownloadArchivesIfNeeded</strong></a>(self)</dt><dd><tt>Downloads&nbsp;archives&nbsp;iff&nbsp;the&nbsp;Archive&nbsp;has&nbsp;a&nbsp;bucket&nbsp;parameter&nbsp;and&nbsp;the&nbsp;user<br>
-has&nbsp;permission&nbsp;to&nbsp;access&nbsp;the&nbsp;bucket.<br>
-&nbsp;<br>
-Raises&nbsp;cloud&nbsp;storage&nbsp;Permissions&nbsp;or&nbsp;Credentials&nbsp;error&nbsp;when&nbsp;there&nbsp;is&nbsp;no<br>
-local&nbsp;copy&nbsp;of&nbsp;the&nbsp;archive&nbsp;and&nbsp;the&nbsp;user&nbsp;doesn't&nbsp;have&nbsp;permission&nbsp;to&nbsp;access<br>
-the&nbsp;archive's&nbsp;bucket.<br>
-&nbsp;<br>
-Warns&nbsp;when&nbsp;a&nbsp;bucket&nbsp;is&nbsp;not&nbsp;specified&nbsp;or&nbsp;when&nbsp;the&nbsp;user&nbsp;doesn't&nbsp;have<br>
-permission&nbsp;to&nbsp;access&nbsp;the&nbsp;archive's&nbsp;bucket&nbsp;but&nbsp;a&nbsp;local&nbsp;copy&nbsp;of&nbsp;the&nbsp;archive<br>
-exists.</tt></dd></dl>
-
-<dl><dt><a name="WprArchiveInfo-WprFilePathForStory"><strong>WprFilePathForStory</strong></a>(self, story)</dt></dl>
-
-<dl><dt><a name="WprArchiveInfo-__init__"><strong>__init__</strong></a>(self, file_path, data, bucket)</dt></dl>
-
-<hr>
-Class methods defined here:<br>
-<dl><dt><a name="WprArchiveInfo-FromFile"><strong>FromFile</strong></a>(cls, file_path, bucket)<font color="#909090"><font face="helvetica, arial"> from <a href="__builtin__.html#type">__builtin__.type</a></font></font></dt></dl>
-
-<hr>
-Data descriptors defined here:<br>
-<dl><dt><strong>__dict__</strong></dt>
-<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-<dl><dt><strong>__weakref__</strong></dt>
-<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
-</dl>
-</td></tr></table></td></tr></table><p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#eeaa77">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><dl><dt><a name="-AssertValidCloudStorageBucket"><strong>AssertValidCloudStorageBucket</strong></a>(bucket)</dt></dl>
-</td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/pydoc/telemetry.wpr.html b/catapult/telemetry/docs/pydoc/telemetry.wpr.html
deleted file mode 100644
index 70e4a8b..0000000
--- a/catapult/telemetry/docs/pydoc/telemetry.wpr.html
+++ /dev/null
@@ -1,26 +0,0 @@
-
-<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html><head><title>Python: package telemetry.wpr</title>
-<meta charset="utf-8">
-</head><body bgcolor="#f0f0f8">
-
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
-<tr bgcolor="#7799ee">
-<td valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="telemetry.html"><font color="#ffffff">telemetry</font></a>.wpr</strong></big></big></font></td
-><td align=right valign=bottom
-><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="../telemetry/wpr/__init__.py">telemetry/wpr/__init__.py</a></font></td></tr></table>
-    <p><tt>#&nbsp;Copyright&nbsp;2014&nbsp;The&nbsp;Chromium&nbsp;Authors.&nbsp;All&nbsp;rights&nbsp;reserved.<br>
-#&nbsp;Use&nbsp;of&nbsp;this&nbsp;source&nbsp;code&nbsp;is&nbsp;governed&nbsp;by&nbsp;a&nbsp;BSD-style&nbsp;license&nbsp;that&nbsp;can&nbsp;be<br>
-#&nbsp;found&nbsp;in&nbsp;the&nbsp;LICENSE&nbsp;file.</tt></p>
-<p>
-<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
-<tr bgcolor="#aa55cc">
-<td colspan=3 valign=bottom>&nbsp;<br>
-<font color="#ffffff" face="helvetica, arial"><big><strong>Package Contents</strong></big></font></td></tr>
-    
-<tr><td bgcolor="#aa55cc"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
-<td width="100%"><table width="100%" summary="list"><tr><td width="25%" valign=top><a href="telemetry.wpr.archive_info.html">archive_info</a><br>
-</td><td width="25%" valign=top><a href="telemetry.wpr.archive_info_unittest.html">archive_info_unittest</a><br>
-</td><td width="25%" valign=top></td><td width="25%" valign=top></td></tr></table></td></tr></table>
-</body></html>
\ No newline at end of file
diff --git a/catapult/telemetry/docs/run_benchmarks_locally.md b/catapult/telemetry/docs/run_benchmarks_locally.md
deleted file mode 100644
index c59a4b0..0000000
--- a/catapult/telemetry/docs/run_benchmarks_locally.md
+++ /dev/null
@@ -1,116 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file.
--->
-
-# Telemetry: Run Benchmarks Locally
-
-## Set Up
-
-If you don't have a Chromium checkout, download the
-[latest Telemetry archive](https://storage.googleapis.com/chromium-telemetry/snapshots/telemetry.zip).
-Unzip the archive. If you're running on Mac OS X, you're all set! For
-Windows, Linux, Android, or Chrome OS, read on.
-
-#### Windows
-
-Some benchmarks require you to have
-[pywin32](http://sourceforge.net/projects/pywin32/files/pywin32/Build%20219/).
-Be sure to install a version that matches the version and bitness of the Python
-you have installed.
-
-#### Linux
-
-Telemetry on Linux tries to scan for attached Android devices with
-[adb](https://developer.android.com/tools/help/adb.html).
-The included adb binary is 32-bit. On 64-bit machines, you need to install the
-libstdc++6:i386 package.
-
-#### Android
-
-Running on Android is supported with a Linux or Mac OS X host. Windows is not
-yet supported. There are also a few additional steps to set up:
-
-  1. Telemetry requires [adb](http://developer.android.com/tools/help/adb.html).
-     If you're running from the zip archive, adb is already included. But if
-     you're running with a Chromium checkout, ensure your .gclient file contains
-     target\_os = ['android'], then resync your code.
-  2. If running from an OS X host, you need to run ADB as root. First, you need
-     to install a "userdebug" build of Android on your device. Then run adb
-     root. Sometimes you may also need to run adb remount.
-  3. Enable [debugging over USB](http://developer.android.com/tools/device.html)
-     on your device.
-  4. You can get the name of your device with `adb devices` and use it with
-     Telemetry via --device=<device\_name>.
-
-#### Chrome OS
-
-See [Running Telemetry on Chrome OS](http://www.chromium.org/developers/telemetry/running-telemetry-on-chrome-os).
-
-## Benchmark Commands
-
-Telemetry benchmarks can be run with run\_benchmark.
-
-In the Telemetry zip archive, this is located at `telemetry/run_benchmark`.
-
-In the Chromium source tree, this is located at `src/tools/perf/run_benchmark`.
-
-#### Running a benchmark
-
-List the available benchmarks with `telemetry/run_benchmark list`.
-
-Here's an example for running a particular benchmark:
-
-`telemetry/run_benchmark --browser=canary smoothness.top_25_smooth`
-
-#### Running on another browser
-
-To list available browsers, use:
-
-`telemetry/run_benchmark --browser=list`
-
-For ease of use, you can use default system browsers on desktop:
-
-`telemetry/run_benchmark --browser=system`
-
-and on Android:
-
-`telemetry/run_benchmark --browser=android-system-chrome`
-
-If you're running telemetry from within a Chromium checkout, the release and
-debug browsers are what's built in out/Release and out/Debug, respectively.
-
-To run a specific browser executable:
-
-`telemetry/run_benchmark --browser=exact --browser-executable=/path/to/binary`
-
-To run on a Chromebook:
-
-`telemetry/run_benchmark --browser=cros-chrome --remote=[ip_address]`
-
-#### Options
-
-To see all options, run:
-
-`telemetry/run_benchmark run --help`
-
-Use --pageset-repeat to run the test repeatedly. For example:
-
-`telemetry/run_benchmark smoothness.top_25 --pageset-repeat=30`
-
-If you want to re-generate HTML results and add label, you can do this locally
-by using the parameters `--reset-results --results-label="foo"`
-
-`telemetry/run_benchmark smoothness.top_25 --reset-results
---results-label="foo"`
-
-####Comparing Two Runs
-
-`telemetry/run_benchmark some_test --browser-executable=path/to/version/1
---reset-results --results-label="Version 1"`
-
-`telemetry/run_benchmark some_test --browser-executable=path/to/version/2
---results-label="Version 2"`
-
-The results will be written to in the `results.html` file in the same location
-of the `run_benchmark` script.
diff --git a/catapult/telemetry/examples/benchmarks/__init__.py b/catapult/telemetry/examples/benchmarks/__init__.py
deleted file mode 100644
index b7bc89c..0000000
--- a/catapult/telemetry/examples/benchmarks/__init__.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-# Since this is an example of telemetry benchmarks in top level telemetry
-# folder, we include the top level telemetry dir to sys.path so we can import
-# from telemetry directly in the other modules.
-sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
diff --git a/catapult/telemetry/examples/benchmarks/simple_story_set.py b/catapult/telemetry/examples/benchmarks/simple_story_set.py
deleted file mode 100644
index f33434d..0000000
--- a/catapult/telemetry/examples/benchmarks/simple_story_set.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import story
-from telemetry import page
-
-
-class ExamplePage(page.Page):
-
-  def __init__(self, page_set):
-    super(ExamplePage, self).__init__(
-        url='https://google.com/search?q=lemon',
-        page_set=page_set)
-
-  def RunPageInteractions(self, action_runner):
-    # To see all the web APIs that action_runner supports, see:
-    # telemetry.page.action_runner module.
-
-    action_runner.Wait(0.5)
-    # Create interaction record will create a region of interest in tracing that
-    # cover the wait, tap, and scroll actions nested in the block below.
-    with action_runner.CreateInteraction('Scroll-And-Tap'):
-      action_runner.Wait(0.3)
-      action_runner.ScrollPage()
-      action_runner.TapElement(text='Next')
-    action_runner.Wait(1)
-    with action_runner.CreateInteraction('Scroll'):
-      action_runner.ScrollPage()
-    with action_runner.CreateInteraction('Wait-two'):
-      action_runner.Wait(1)
-
-
-class SimpleStorySet(story.StorySet):
-  def __init__(self):
-    super(SimpleStorySet, self).__init__(
-        archive_data_file='data/simple_story_set.json',
-        cloud_storage_bucket=story.PARTNER_BUCKET)
-    self.AddStory(ExamplePage(self))
diff --git a/catapult/telemetry/examples/benchmarks/tbm_benchmark.py b/catapult/telemetry/examples/benchmarks/tbm_benchmark.py
deleted file mode 100644
index f7d1845..0000000
--- a/catapult/telemetry/examples/benchmarks/tbm_benchmark.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry import benchmark
-from telemetry.web_perf import timeline_based_measurement
-
-from benchmarks import simple_story_set
-
-class TBMSample(benchmark.Benchmark):
-
-  def CreateStorySet(self, options):
-    return simple_story_set.SimpleStorySet()
-
-  def CreateTimelineBasedMeasurementOptions(self):
-    options = timeline_based_measurement.Options()
-    options.SetTimelineBasedMetrics(['sample_metric.html'])
-    return options
-
-  @classmethod
-  def Name(cls):
-    return 'tbm_sample.tbm_sample'
diff --git a/catapult/telemetry/examples/browser_tests/__init__.py b/catapult/telemetry/examples/browser_tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/examples/browser_tests/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/examples/browser_tests/failed_tests.py b/catapult/telemetry/examples/browser_tests/failed_tests.py
deleted file mode 100644
index 516d181..0000000
--- a/catapult/telemetry/examples/browser_tests/failed_tests.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-
-from telemetry.testing import serially_executed_browser_test_case
-
-
-class SetUpClassFailedTest(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  @classmethod
-  def setUpClass(cls):
-    raise Exception
-
-  @classmethod
-  def GenerateTestCases_DummyTest(cls, options):
-    del options  # Unused.
-    for i in xrange(0, 3):
-      yield 'dummy_test_%i' % i, ()
-
-  def DummyTest(self):
-    pass
-
-
-class TearDownClassFailedTest(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  @classmethod
-  def tearDownClass(cls):
-    raise Exception
-
-  @classmethod
-  def GenerateTestCases_DummyTest(cls, options):
-    del options  # Unused.
-    for i in xrange(0, 3):
-      yield 'dummy_test_%i' % i, ()
-
-  def DummyTest(self):
-    pass
-
-
-def load_tests(loader, tests, pattern):
-  del loader, tests, pattern  # Unused.
-  return serially_executed_browser_test_case.LoadAllTestsInModule(
-      sys.modules[__name__])
diff --git a/catapult/telemetry/examples/browser_tests/pages/page_with_clickables.html b/catapult/telemetry/examples/browser_tests/pages/page_with_clickables.html
deleted file mode 100644
index e33c120..0000000
--- a/catapult/telemetry/examples/browser_tests/pages/page_with_clickables.html
+++ /dev/null
@@ -1,17 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-<div id="test">Click/tap me</div>
-<script>
-'use strict';
-var el = document.getElementById('test');
-var valueSettableByTest = 0;
-var valueToTest = 0;
-el.addEventListener('click', function() {
-  valueToTest = valueSettableByTest;
-});
-</script>
-</body>
-</html>
diff --git a/catapult/telemetry/examples/browser_tests/pages/page_with_link.html b/catapult/telemetry/examples/browser_tests/pages/page_with_link.html
deleted file mode 100644
index dc3c008..0000000
--- a/catapult/telemetry/examples/browser_tests/pages/page_with_link.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-<a id="clickme" href="blank.html">Click me</a>
-</body>
-</html>
diff --git a/catapult/telemetry/examples/browser_tests/process_tests.py b/catapult/telemetry/examples/browser_tests/process_tests.py
deleted file mode 100644
index ada3517..0000000
--- a/catapult/telemetry/examples/browser_tests/process_tests.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-
-from telemetry.testing import serially_executed_browser_test_case
-
-
-class FailIfSetUpProcessCalledTwice(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-  count = 0
-
-  @classmethod
-  def SetUpProcess(cls):
-    cls.count += 1
-    if cls.count >= 2:
-      assert False, 'This should not be called more than once'
-
-  @classmethod
-  def GenerateTestCases_DummyTest(cls, options):
-    del options  # Unused.
-    for i in xrange(0, 3):
-      yield 'Dummy_%i' % i, ()
-
-  def DummyTest(self):
-    pass
-
-
-class FailIfTearDownProcessCalledTwice(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-  count = 0
-
-  @classmethod
-  def TearDownProcess(cls):
-    cls.count += 1
-    if cls.count >= 2:
-      assert False, 'This should not be called more than once'
-
-  @classmethod
-  def GenerateTestCases_DummyTest(cls, options):
-    del options  # Unused.
-    for i in xrange(0, 3):
-      yield 'Dummy_%i' % i, ()
-
-  def DummyTest(self):
-    pass
-
-
-def load_tests(loader, tests, pattern):
-  del loader, tests, pattern  # Unused.
-  return serially_executed_browser_test_case.LoadAllTestsInModule(
-      sys.modules[__name__])
diff --git a/catapult/telemetry/examples/browser_tests/sample_unittest.py b/catapult/telemetry/examples/browser_tests/sample_unittest.py
deleted file mode 100644
index fcae258..0000000
--- a/catapult/telemetry/examples/browser_tests/sample_unittest.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-class SampleUnittest(unittest.TestCase):
-  def testPassing(self):
-    self.assertTrue(1 + 1)
-
-  def testFailing(self):
-    self.assertFalse(True or False)
diff --git a/catapult/telemetry/examples/browser_tests/simple_browser_test.py b/catapult/telemetry/examples/browser_tests/simple_browser_test.py
deleted file mode 100644
index 82df3aa..0000000
--- a/catapult/telemetry/examples/browser_tests/simple_browser_test.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-import os
-
-from telemetry.testing import serially_executed_browser_test_case
-
-
-def ConvertPathToTestName(url):
-  return url.replace('.', '_')
-
-
-class SimpleBrowserTest(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  @classmethod
-  def GenerateTestCases_JavascriptTest(cls, options):
-    del options  # unused
-    for path in ['page_with_link.html', 'page_with_clickables.html']:
-      yield 'add_1_and_2_' + ConvertPathToTestName(path), (path, 1, 2, 3)
-
-  @classmethod
-  def SetUpProcess(cls):
-    super(cls, SimpleBrowserTest).SetUpProcess()
-    cls.SetBrowserOptions(cls._finder_options)
-    cls.StartBrowser()
-    cls.action_runner = cls.browser.tabs[0].action_runner
-    cls.SetStaticServerDirs(
-        [os.path.join(os.path.abspath(__file__), '..', 'pages')])
-
-  def JavascriptTest(self, file_path, num_1, num_2, expected_sum):
-    url = self.UrlOfStaticFilePath(file_path)
-    self.action_runner.Navigate(url)
-    actual_sum = self.action_runner.EvaluateJavaScript(
-        '{{ num_1 }} + {{ num_2 }}', num_1=num_1, num_2=num_2)
-    self.assertEquals(expected_sum, actual_sum)
-
-  def TestClickablePage(self):
-    url = self.UrlOfStaticFilePath('page_with_clickables.html')
-    self.action_runner.Navigate(url)
-    self.action_runner.ExecuteJavaScript('valueSettableByTest = 1997')
-    self.action_runner.ClickElement(text='Click/tap me')
-    self.assertEqual(
-        1997, self.action_runner.EvaluateJavaScript('valueToTest'))
-
-  def TestAndroidUI(self):
-    if self.platform.GetOSName() != 'android':
-      self.skipTest('The test is for android only')
-    url = self.UrlOfStaticFilePath('page_with_clickables.html')
-    # Nativgate to page_with_clickables.html
-    self.action_runner.Navigate(url)
-    # Click on history
-    self.platform.system_ui.WaitForUiNode(
-        resource_id='com.google.android.apps.chrome:id/menu_button')
-    self.platform.system_ui.GetUiNode(
-        resource_id='com.google.android.apps.chrome:id/menu_button').Tap()
-    self.platform.system_ui.WaitForUiNode(content_desc='History')
-    self.platform.system_ui.GetUiNode(content_desc='History').Tap()
-    # Click on the first entry of the history (page_with_clickables.html)
-    self.action_runner.WaitForElement('#id-0')
-    self.action_runner.ClickElement('#id-0')
-    # Verify that the page's js is interactable
-    self.action_runner.WaitForElement(text='Click/tap me')
-    self.action_runner.ExecuteJavaScript('valueSettableByTest = 1997')
-    self.action_runner.ClickElement(text='Click/tap me')
-    self.assertEqual(
-        1997, self.action_runner.EvaluateJavaScript('valueToTest'))
-
-
-def load_tests(loader, tests, pattern):
-  del loader, tests, pattern  # Unused.
-  return serially_executed_browser_test_case.LoadAllTestsInModule(
-      sys.modules[__name__])
diff --git a/catapult/telemetry/examples/browser_tests/simple_numeric_test.py b/catapult/telemetry/examples/browser_tests/simple_numeric_test.py
deleted file mode 100644
index e301a1b..0000000
--- a/catapult/telemetry/examples/browser_tests/simple_numeric_test.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import string
-import sys
-import time
-
-from telemetry.testing import serially_executed_browser_test_case
-
-
-_prev_test_name = None
-
-class SimpleTest(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  @classmethod
-  def AddCommandlineArgs(cls, parser):
-    parser.add_option('--adder-sum', type=int, default=5)
-
-  def setUp(self):
-    self.extra = 5
-
-  @classmethod
-  def GenerateTestCases_AdderTest(cls, options):
-    yield 'add_1_and_2', (1, 2, options.adder_sum)
-    yield 'add_2_and_3', (2, 3, options.adder_sum)
-    yield 'add_7_and_3', (7, 3, options.adder_sum)
-    # Filtered out in browser_test_runner_unittest.py
-    yield 'dontrun_add_1_and_2', (1, 2, options.adder_sum)
-
-  @classmethod
-  def GenerateTestCases_AlphabeticalTest(cls, options):
-    del options  # unused
-    prefix = 'Alphabetical_'
-    test_names = []
-    for character in string.lowercase[:26]:
-      test_names.append(prefix + character)
-    for character in string.uppercase[:26]:
-      test_names.append(prefix + character)
-    for num in xrange(20):
-      test_names.append(prefix + str(num))
-
-    # Shuffle |test_names| so the tests will be generated in a random order.
-    test_names = (test_names[25:40] + test_names[40:70] + test_names[:25] +
-                  test_names[70:])
-    for t in test_names:
-      yield t, ()
-
-  def AlphabeticalTest(self):
-    test_name = self.id()
-    global _prev_test_name
-    self.assertLess(_prev_test_name, test_name)
-    _prev_test_name = test_name
-
-  def AdderTest(self, a, b, partial_sum):
-    self.assertEqual(a + b, partial_sum)
-
-  @classmethod
-  def GenerateTestCases_MultiplierTest(cls, options):
-    del options  # unused
-    yield 'multiplier_simple', (10, 2, 4)
-    yield 'multiplier_simple_2', (2, 3, 5)
-    yield 'multiplier_simple_3', (10, 3, 6)
-    # Filtered out in browser_test_runner_unittest.py
-    yield 'dontrun_multiplier_simple', (10, 2, 4)
-
-  def MultiplierTest(self, a, b, partial_sum):
-    self.assertEqual(a * b, partial_sum * self.extra)
-
-  def TestSimple(self):
-    time.sleep(0.5)
-    self.assertEqual(1, self.extra)
-
-  def TestException(self):
-    raise Exception('Expected exception')
-
-
-def load_tests(loader, tests, pattern):
-  del loader, tests, pattern  # Unused.
-  return serially_executed_browser_test_case.LoadAllTestsInModule(
-      sys.modules[__name__])
diff --git a/catapult/telemetry/examples/browser_tests/simple_sharding_test.py b/catapult/telemetry/examples/browser_tests/simple_sharding_test.py
deleted file mode 100644
index fdb78a9..0000000
--- a/catapult/telemetry/examples/browser_tests/simple_sharding_test.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-
-from telemetry.testing import serially_executed_browser_test_case
-
-
-class SimpleShardingTest(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  def Test1(self):
-    pass
-
-  def Test2(self):
-    pass
-
-  def Test3(self):
-    pass
-
-  @classmethod
-  def GenerateTestCases_PassingTest(cls, options):
-    del options  # unused
-    for i in xrange(10):
-      yield 'passing_test_' + str(i), (i,)
-
-  def PassingTest(self, a):
-    self.assertGreaterEqual(a, 0)
-
-
-def load_tests(loader, tests, pattern):
-  del loader, tests, pattern  # Unused.
-  return serially_executed_browser_test_case.LoadAllTestsInModule(
-      sys.modules[__name__])
diff --git a/catapult/telemetry/examples/credentials_example.json b/catapult/telemetry/examples/credentials_example.json
deleted file mode 100644
index b3978b6..0000000
--- a/catapult/telemetry/examples/credentials_example.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "google": {
-    "username": "<your google account here>",
-    "password": "<your google password here>"
-  },
-  "facebook": {
-    "username": "<your google account here>",
-    "password": "<your google password here>"
-  }
-}
diff --git a/catapult/telemetry/examples/run_benchmark b/catapult/telemetry/examples/run_benchmark
deleted file mode 100755
index f24a386..0000000
--- a/catapult/telemetry/examples/run_benchmark
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import sys
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from telemetry import benchmark_runner
-from telemetry import project_config
-
-def main():
-  top_level_dir = os.path.dirname(__file__)
-  config = project_config.ProjectConfig(
-      top_level_dir=top_level_dir,
-      benchmark_dirs=[os.path.join(top_level_dir, 'benchmarks')])
-  return benchmark_runner.main(config)
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/catapult/telemetry/json_format b/catapult/telemetry/json_format
deleted file mode 100755
index 401594d..0000000
--- a/catapult/telemetry/json_format
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import argparse
-import json
-import os
-import sys
-
-
-def GetFormattedJSONString(file_path):
- with open(file_path, 'r') as f:
-    json_obj = json.load(f)
-    file_content = f.read()
- return json.dumps(
-     json_obj, indent=2, sort_keys=True, separators=(',', ': '))
-
-
-def ValidateJSONFormat(file_path):
- with open(file_path, 'r') as f:
-    file_content = f.read()
- if file_content != GetFormattedJSONString(file_path):
-   raise Exception(
-       'Reformat your JSON file by running: %s --format %s' %
-       (__file__, file_path))
- print >> sys.stdout, ('%s passes the JSON format validation' % file_path)
-
-
-def Format(file_path):
-  formatted_JSON_string = GetFormattedJSONString(file_path)
-  with open(file_path, 'w') as f:
-    f.write(formatted_JSON_string)
-
-
-def Main(args):
-  description = """A JSON formatting tool.
-
-  This is a tool that validate and reformats JSON file so that it complies with
-  a certain style. The JSON style imposed by this tool is:
-    * JSON array elements and object members are indented with 2 spaces.
-    * Dictionaries objects are sorted by key.
-    * Items are sperated by ', ' and ': '.
-  """
-  parser = argparse.ArgumentParser(
-      description=description, formatter_class=argparse.RawTextHelpFormatter)
-  parser.add_argument('file_path', type=str, help='The path to JSON file.')
-  parser.add_argument('--format', action='store_true', default=False,
-                      help='Format the JSON file.')
-  options = parser.parse_args(args)
-  if options.format:
-    Format(options.file_path)
-    return 0
-  ValidateJSONFormat(options.file_path)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main(sys.argv[1:]))
diff --git a/catapult/telemetry/list_telemetry_unittests b/catapult/telemetry/list_telemetry_unittests
deleted file mode 100755
index 8f420c6..0000000
--- a/catapult/telemetry/list_telemetry_unittests
+++ /dev/null
@@ -1,70 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import sys
-
-
-def _ExtractQueuedTestName(line):
-  _, test_name, _ = line.split(' ')
-  return test_name
-
-
-def _ExtractPassedTestNameAndTime(line):
-  _, test_name, _, test_time_string = line.split(' ')
-  if test_time_string.endswith(':'):
-    test_time = float(test_time_string[:-2])
-  else:
-    test_time = float(test_time_string[:-1])
-  return test_name, test_time
-
-
-def _IsQueued(line):
-  return line.endswith(' queued')
-
-
-def _IsPassed(line):
-  return 'passed' in line.split(' ')
-
-
-def _ProcessLogFile(file_path):
-  passed_unittests = []
-  queued_unittests = []
-  with open(file_path, 'r') as f:
-    for line in f:
-      line = line.strip()
-      if not line.startswith('['):
-        continue
-      if _IsQueued(line):
-        queued_unittests.append(_ExtractQueuedTestName(line))
-      elif _IsPassed(line):
-        passed_unittests.append(_ExtractPassedTestNameAndTime(line))
-  queued_unittests.sort()
-  passed_unittests.sort(key=lambda v: -v[1])
-  return queued_unittests, passed_unittests
-
-
-def main(args):
-  parser = argparse.ArgumentParser(
-      description=('Process telemetry unittests log to print out passed '
-                   'or queued tests.'))
-  parser.add_argument(
-      'filepath', help='path to log file of telemetry unittest')
-  parser.add_argument(
-      '-q', '--list-queued-tests', action='store_true',
-      help='Also list all the queued telemetry unittests')
-  options = parser.parse_args(args)
-  queued_unittests, passed_unittests = _ProcessLogFile(options.filepath)
-  print 'All passed telemetry unittests:\n'
-  for test, time in passed_unittests:
-      print test, time
-  if options.list_queued_tests:
-    print 'All queued telemetry unittests:\n'
-    print '\n'.join(queued_unittests)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main(sys.argv[1:]))
diff --git a/catapult/telemetry/pylintrc b/catapult/telemetry/pylintrc
deleted file mode 100644
index 7be28e2..0000000
--- a/catapult/telemetry/pylintrc
+++ /dev/null
@@ -1,75 +0,0 @@
-[MESSAGES CONTROL]
-
-# Disable the message, report, category or checker with the given id(s).
-# TODO(telemetry-team): Shrink this list to as small as possible.
-disable=
-  design,
-  similarities,
-
-  abstract-class-little-used,
-  abstract-class-not-used,
-  bad-builtin,
-  bad-continuation,
-  broad-except,
-  fixme,
-  global-statement,
-  interface-not-implemented,
-  invalid-name,
-  locally-disabled,
-  locally-enabled,
-  logging-not-lazy,
-  missing-docstring,
-  no-member,
-  no-self-use,
-  protected-access,
-  star-args,
-  too-many-function-args
-
-
-[REPORTS]
-
-# Don't write out full reports, just messages.
-reports=no
-
-
-[BASIC]
-
-# Regular expression which should only match correct function names.
-function-rgx=^(?:(?P<exempt>setUp|tearDown|setUpModule|tearDownModule)|(?P<camel_case>_?[A-Z][a-zA-Z0-9]*))$
-
-# Regular expression which should only match correct method names.
-method-rgx=^(?:(?P<exempt>_[a-z0-9_]+__|get|post|runTest|setUp|tearDown|setUpTestCase|tearDownTestCase|setupSelf|tearDownClass|setUpClass)|(?P<camel_case>(_{0,2}|test|assert)[A-Z][a-zA-Z0-9_]*))$
-
-# Regular expression which should only match correct argument names.
-argument-rgx=^[a-z][a-z0-9_]*$
-
-# Regular expression which should only match correct variable names.
-variable-rgx=^[a-z][a-z0-9_]*$
-
-# Good variable names which should always be accepted, separated by a comma.
-good-names=main,_
-
-# List of builtins function names that should not be used, separated by a comma.
-bad-functions=apply,input,reduce
-
-
-[VARIABLES]
-
-# Tells wether we should check for unused import in __init__ files.
-init-import=no
-
-# A regular expression matching names used for dummy variables (i.e. not used).
-dummy-variables-rgx=^\*{0,2}(_$|unused_)
-
-
-[TYPECHECK]
-
-# Tells wether missing members accessed in mixin class should be ignored. A
-# mixin class is detected if its name ends with "mixin" (case insensitive).
-ignore-mixin-members=yes
-
-
-[FORMAT]
-
-# We use two spaces for indents, instead of the usual four spaces or tab.
-indent-string='  '
diff --git a/catapult/telemetry/support/html_output/results-template.html b/catapult/telemetry/support/html_output/results-template.html
deleted file mode 100644
index a6a5655..0000000
--- a/catapult/telemetry/support/html_output/results-template.html
+++ /dev/null
@@ -1,1488 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>Telemetry Performance Test Results</title>
-<style type="text/css">
-
-section {
-    background: white;
-    padding: 10px;
-    position: relative;
-}
-
-.collapsed:before {
-    color: #ccc;
-    content: '\25B8\00A0';
-}
-
-.expanded:before {
-    color: #eee;
-    content: '\25BE\00A0';
-}
-
-.line-plots {
-    padding-left: 25px;
-}
-
-.line-plots > div {
-    display: inline-block;
-    width: 90px;
-    height: 40px;
-    margin-right: 10px;
-}
-
-.lage-line-plots {
-    padding-left: 25px;
-}
-
-.large-line-plots > div, .histogram-plots > div {
-    display: inline-block;
-    width: 400px;
-    height: 200px;
-    margin-right: 10px;
-}
-
-.large-line-plot-labels > div, .histogram-plot-labels > div {
-    display: inline-block;
-    width: 400px;
-    height: 11px;
-    margin-right: 10px;
-    color: #545454;
-    text-align: center;
-    font-size: 11px;
-}
-
-.closeButton {
-    display: inline-block;
-    background: #eee;
-    background: linear-gradient(rgb(220, 220, 220), rgb(255, 255, 255));
-    border: inset 1px #ddd;
-    border-radius: 4px;
-    float: right;
-    font-size: small;
-    -webkit-user-select: none;
-    font-weight: bold;
-    padding: 1px 4px;
-}
-
-.closeButton:hover {
-    background: #F09C9C;
-}
-
-.label {
-    cursor: text;
-}
-
-.label:hover {
-    background: #ffcc66;
-}
-
-section h1 {
-    text-align: center;
-    font-size: 1em;
-}
-
-section .tooltip {
-    position: absolute;
-    text-align: center;
-    background: #ffcc66;
-    border-radius: 5px;
-    padding: 0px 5px;
-}
-
-body {
-    padding: 0px;
-    margin: 0px;
-    font-family: sans-serif;
-}
-
-table {
-    background: white;
-    width: 100%;
-}
-
-table, td, th {
-    border-collapse: collapse;
-    padding: 5px;
-    white-space: nowrap;
-}
-
-.highlight:hover {
-   color: #202020;
-   background: #e0e0e0;
-}
-
-.nestedRow {
-    background: #f8f8f8;
-}
-
-.importantNestedRow {
-    background: #e0e0e0;
-    font-weight: bold;
-}
-
-table td {
-    position: relative;
-}
-
-th, td {
-    cursor: pointer;
-    cursor: hand;
-}
-
-th {
-    background: #e6eeee;
-    background: linear-gradient(rgb(244, 244, 244), rgb(217, 217, 217));
-    border: 1px solid #ccc;
-}
-
-th.sortUp:after {
-    content: ' \25BE';
-}
-
-th.sortDown:after {
-    content: ' \25B4';
-}
-
-td.comparison, td.result {
-    text-align: right;
-}
-
-td.better {
-    color: #6c6;
-}
-
-td.fadeOut {
-    opacity: 0.5;
-}
-
-td.unknown {
-    color: #ccc;
-}
-
-td.worse {
-    color: #c66;
-}
-
-td.reference {
-    font-style: italic;
-    font-weight: bold;
-    color: #444;
-}
-
-td.missing {
-    color: #ccc;
-    text-align: center;
-}
-
-td.missingReference {
-    color: #ccc;
-    text-align: center;
-    font-style: italic;
-}
-
-.checkbox {
-    display: inline-block;
-    background: #eee;
-    background: linear-gradient(rgb(220, 220, 220), rgb(200, 200, 200));
-    border: inset 1px #ddd;
-    border-radius: 5px;
-    margin: 10px;
-    font-size: small;
-    cursor: pointer;
-    cursor: hand;
-    -webkit-user-select: none;
-    font-weight: bold;
-}
-
-.checkbox span {
-    display: inline-block;
-    line-height: 100%;
-    padding: 5px 8px;
-    border: outset 1px transparent;
-}
-
-.checkbox .checked {
-    background: #e6eeee;
-    background: linear-gradient(rgb(255, 255, 255), rgb(235, 235, 235));
-    border: outset 1px #eee;
-    border-radius: 5px;
-}
-
-.openAllButton {
-    display: inline-block;
-    colour: #6c6
-    background: #eee;
-    background: linear-gradient(rgb(220, 220, 220), rgb(255, 255, 255));
-    border: inset 1px #ddd;
-    border-radius: 5px;
-    float: left;
-    font-size: small;
-    -webkit-user-select: none;
-    font-weight: bold;
-    padding: 1px 4px;
-}
-
-.openAllButton:hover {
-    background: #60f060;
-}
-
-.closeAllButton {
-    display: inline-block;
-    colour: #c66
-    background: #eee;
-    background: linear-gradient(rgb(220, 220, 220),rgb(255, 255, 255));
-    border: inset 1px #ddd;
-    border-radius: 5px;
-    float: left;
-    font-size: small;
-    -webkit-user-select: none;
-    font-weight: bold;
-    padding: 1px 4px;
-}
-
-.closeAllButton:hover {
-    background: #f04040;
-}
-
-</style>
-</head>
-<body onload="init()">
-<div style="padding: 0 10px; white-space: nowrap;">
-Result <span id="time-memory" class="checkbox"></span>
-Reference <span id="reference" class="checkbox"></span>
-Style <span id="scatter-line" class="checkbox"><span class="checked">Scatter</span><span>Line</span></span>
-<span class="checkbox"><span class="checked" id="undelete">Undelete</span></span><br>
-Run your test with --reset-results to clear all runs
-</div>
-<table id="container"></table>
-<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
-<script>
-%plugins%
-</script>
-<script>
-
-var EXPANDED = true;
-var COLLAPSED = false;
-var SMALLEST_PERCENT_DISPLAYED = 0.01;
-var INVISIBLE = false;
-var VISIBLE = true;
-var COMPARISON_SUFFIX = '_compare';
-var SORT_DOWN_CLASS = 'sortDown';
-var SORT_UP_CLASS = 'sortUp';
-var BETTER_CLASS = 'better';
-var WORSE_CLASS = 'worse';
-var UNKNOWN_CLASS = 'unknown'
-// px Indentation for graphs
-var GRAPH_INDENT = 64;
-var PADDING_UNDER_GRAPH = 5;
-// px Indentation for nested children left-margins
-var INDENTATION = 40;
-
-function TestResult(metric, values, associatedRun, std, degreesOfFreedom) {
-    if (values) {
-        if (values[0] instanceof Array) {
-            var flattenedValues = [];
-            for (var i = 0; i < values.length; i++)
-                flattenedValues = flattenedValues.concat(values[i]);
-            values = flattenedValues;
-        }
-
-        if (jQuery.type(values[0]) === 'string') {
-            try {
-                var current = JSON.parse(values[0]);
-                if (current.params.type === 'HISTOGRAM') {
-                    this.histogramValues = current;
-                    // Histogram results have no values (per se). Instead we calculate
-                    // the values from the histogram bins.
-                    var values = [];
-                    var buckets = current.buckets
-                    for (var i = 0; i < buckets.length; i++) {
-                        var bucket = buckets[i];
-                        var bucket_mean = (bucket.high + bucket.low) / 2;
-                        for (var b = 0; b < bucket.count; b++) {
-                            values.push(bucket_mean);
-                        }
-                    }
-                }
-            }
-            catch (e) {
-                console.error(e, e.stack);
-            }
-        }
-    } else {
-        values = [];
-    }
-
-    this.test = function() { return metric; }
-    this.values = function() { return values.map(function(value) { return metric.scalingFactor() * value; }); }
-    this.unscaledMean = function() { return Statistics.sum(values) / values.length; }
-    this.mean = function() { return metric.scalingFactor() * this.unscaledMean(); }
-    this.min = function() { return metric.scalingFactor() * Statistics.min(values); }
-    this.max = function() { return metric.scalingFactor() * Statistics.max(values); }
-    this.confidenceIntervalDelta = function() {
-        if (std !== undefined) {
-            return metric.scalingFactor() * Statistics.confidenceIntervalDeltaFromStd(0.95, values.length,
-                std, degreesOfFreedom);
-        }
-        return metric.scalingFactor() * Statistics.confidenceIntervalDelta(0.95, values.length,
-            Statistics.sum(values), Statistics.squareSum(values));
-    }
-    this.confidenceIntervalDeltaRatio = function() { return this.confidenceIntervalDelta() / this.mean(); }
-    this.percentDifference = function(other) {
-        if (other === undefined) {
-            return undefined;
-        }
-        return (other.unscaledMean() - this.unscaledMean()) / this.unscaledMean();
-    }
-    this.isStatisticallySignificant = function(other) {
-        if (other === undefined) {
-            return false;
-        }
-        var diff = Math.abs(other.mean() - this.mean());
-        return diff > this.confidenceIntervalDelta() && diff > other.confidenceIntervalDelta();
-    }
-    this.run = function() { return associatedRun; }
-}
-
-function TestRun(entry) {
-    this.id = function() { return entry['buildTime'].replace(/[:.-]/g,''); }
-    this.label = function() {
-        if (labelKey in localStorage)
-            return localStorage[labelKey];
-        return entry['label'];
-    }
-    this.setLabel = function(label) { localStorage[labelKey] = label; }
-    this.isHidden = function() { return localStorage[hiddenKey]; }
-    this.hide = function() { localStorage[hiddenKey] = true; }
-    this.show = function() { localStorage.removeItem(hiddenKey); }
-    this.description = function() {
-        return new Date(entry['buildTime']).toLocaleString() + '\n' + entry['platform'] + ' ' + this.label();
-    }
-
-    var labelKey = 'telemetry_label_' + this.id();
-    var hiddenKey = 'telemetry_hide_' + this.id();
-}
-
-function PerfTestMetric(name, metric, unit, isImportant) {
-    var testResults = [];
-    var cachedUnit = null;
-    var cachedScalingFactor = null;
-
-    // We can't do this in TestResult because all results for each test need to share the same unit and the same scaling factor.
-    function computeScalingFactorIfNeeded() {
-        // FIXME: We shouldn't be adjusting units on every test result.
-        // We can only do this on the first test.
-        if (!testResults.length || cachedUnit)
-            return;
-
-        var mean = testResults[0].unscaledMean(); // FIXME: We should look at all values.
-        var kilo = unit == 'bytes' ? 1024 : 1000;
-        if (mean > 10 * kilo * kilo && unit != 'ms') {
-            cachedScalingFactor = 1 / kilo / kilo;
-            cachedUnit = 'M ' + unit;
-        } else if (mean > 10 * kilo) {
-            cachedScalingFactor = 1 / kilo;
-            cachedUnit = unit == 'ms' ? 's' : ('K ' + unit);
-        } else {
-            cachedScalingFactor = 1;
-            cachedUnit = unit;
-        }
-    }
-
-    this.name = function() { return name + ':' + metric; }
-    this.isImportant = isImportant;
-    this.isMemoryTest = function() {
-        return (unit == 'kb' ||
-                unit == 'KB' ||
-                unit == 'MB' ||
-                unit == 'bytes' ||
-                unit == 'count' ||
-                !metric.indexOf('V8.'));
-    }
-    this.addResult = function(newResult) {
-        testResults.push(newResult);
-        cachedUnit = null;
-        cachedScalingFactor = null;
-    }
-    this.results = function() { return testResults; }
-    this.scalingFactor = function() {
-        computeScalingFactorIfNeeded();
-        return cachedScalingFactor;
-    }
-    this.unit = function() {
-        computeScalingFactorIfNeeded();
-        return cachedUnit;
-    }
-    this.biggerIsBetter = function() {
-        if (window.unitToBiggerIsBetter == undefined) {
-            window.unitToBiggerIsBetter = {};
-            var units = JSON.parse(document.getElementById('units-json').textContent);
-            for (var u in units) {
-                if (units[u].improvement_direction == 'up') {
-                    window.unitToBiggerIsBetter[u] = true;
-                }
-            }
-        }
-        return window.unitToBiggerIsBetter[unit];
-    }
-}
-
-function UndeleteManager() {
-    var key = 'telemetry_undeleteIds'
-    var undeleteIds = localStorage[key];
-    if (undeleteIds) {
-        undeleteIds = JSON.parse(undeleteIds);
-    } else {
-        undeleteIds = [];
-    }
-
-    this.ondelete = function(id) {
-        undeleteIds.push(id);
-        localStorage[key] = JSON.stringify(undeleteIds);
-    }
-    this.undeleteMostRecent = function() {
-        if (!this.mostRecentlyDeletedId())
-            return;
-        undeleteIds.pop();
-        localStorage[key] = JSON.stringify(undeleteIds);
-    }
-    this.mostRecentlyDeletedId = function() {
-        if (!undeleteIds.length)
-            return undefined;
-        return undeleteIds[undeleteIds.length-1];
-    }
-}
-var undeleteManager = new UndeleteManager();
-
-var plotColor = 'rgb(230,50,50)';
-var subpointsPlotOptions = {
-    lines: {show:true, lineWidth: 0},
-    color: plotColor,
-    points: {show: true, radius: 1},
-    bars: {show: false}};
-
-var mainPlotOptions = {
-    xaxis: {
-        min: -0.5,
-        tickSize: 1,
-    },
-    crosshair: { mode: 'y' },
-    series: { shadowSize: 0 },
-    bars: {show: true, align: 'center', barWidth: 0.5},
-    lines: { show: false },
-    points: { show: true },
-    grid: {
-        borderWidth: 1,
-        borderColor: '#ccc',
-        backgroundColor: '#fff',
-        hoverable: true,
-        autoHighlight: false,
-    }
-};
-
-var linePlotOptions = {
-    yaxis: { show: false },
-    xaxis: { show: false },
-    lines: { show: true },
-    grid: { borderWidth: 1, borderColor: '#ccc' },
-    colors: [ plotColor ]
-};
-
-var largeLinePlotOptions = {
-    xaxis: {
-        show: true,
-        tickDecimals: 0,
-    },
-    lines: { show: true },
-    grid: { borderWidth: 1, borderColor: '#ccc' },
-    colors: [ plotColor ]
-};
-
-var histogramPlotOptions = {
-    bars: {show: true, fill: 1}
-};
-
-function createPlot(container, test, useLargeLinePlots) {
-    if (test.results()[0].histogramValues) {
-        var section = $('<section><div class="histogram-plots"></div>'
-            + '<div class="histogram-plot-labels"></div>'
-            + '<span class="tooltip"></span></section>');
-        $(container).append(section);
-        attachHistogramPlots(test, section.children('.histogram-plots'));
-    }
-    else if (useLargeLinePlots) {
-        var section = $('<section><div class="large-line-plots"></div>'
-            + '<div class="large-line-plot-labels"></div>'
-            + '<span class="tooltip"></span></section>');
-        $(container).append(section);
-        attachLinePlots(test, section.children('.large-line-plots'), useLargeLinePlots);
-        attachLinePlotLabels(test, section.children('.large-line-plot-labels'));
-    } else {
-        var section = $('<section><div class="plot"></div><div class="line-plots"></div>'
-            + '<span class="tooltip"></span></section>');
-        section.children('.plot').css({'width': (100 * test.results().length + 25) + 'px', 'height': '300px'});
-        $(container).append(section);
-
-        var plotContainer = section.children('.plot');
-        var minIsZero = true;
-        attachPlot(test, plotContainer, minIsZero);
-
-        attachLinePlots(test, section.children('.line-plots'), useLargeLinePlots);
-
-        var tooltip = section.children('.tooltip');
-        plotContainer.bind('plothover', function(event, position, item) {
-            if (item) {
-                var postfix = item.series.id ? ' (' + item.series.id + ')' : '';
-                tooltip.html(item.datapoint[1].toPrecision(4) + postfix);
-                var sectionOffset = $(section).offset();
-                tooltip.css({left: item.pageX - sectionOffset.left - tooltip.outerWidth() / 2, top: item.pageY - sectionOffset.top + 10});
-                tooltip.fadeIn(200);
-            } else
-                tooltip.hide();
-        });
-        plotContainer.mouseout(function() {
-            tooltip.hide();
-        });
-        plotContainer.click(function(event) {
-            event.preventDefault();
-            minIsZero = !minIsZero;
-            attachPlot(test, plotContainer, minIsZero);
-        });
-    }
-    return section;
-}
-
-function attachLinePlots(test, container, useLargeLinePlots) {
-    var results = test.results();
-    var attachedPlot = false;
-
-    if (useLargeLinePlots) {
-        var maximum = 0;
-        for (var i = 0; i < results.length; i++) {
-            var values = results[i].values();
-            if (!values)
-                continue;
-            var local_max = Math.max.apply(Math, values);
-            if (local_max > maximum)
-                maximum = local_max;
-        }
-    }
-
-    for (var i = 0; i < results.length; i++) {
-        container.append('<div></div>');
-        var values = results[i].values();
-        if (!values)
-            continue;
-        attachedPlot = true;
-
-        if (useLargeLinePlots) {
-            var options = $.extend(true, {}, largeLinePlotOptions,
-                               {yaxis: {min: 0.0, max: maximum},
-                                xaxis: {min: 0.0, max: values.length - 1},
-                                points: {show: (values.length < 2) ? true : false}});
-        } else {
-            var options = $.extend(true, {}, linePlotOptions,
-                               {yaxis: {min: Math.min.apply(Math, values) * 0.9, max: Math.max.apply(Math, values) * 1.1},
-                                xaxis: {min: -0.5, max: values.length - 0.5},
-                                points: {show: (values.length < 2) ? true : false}});
-        }
-        $.plot(container.children().last(), [values.map(function(value, index) { return [index, value]; })], options);
-    }
-    if (!attachedPlot)
-        container.children().remove();
-}
-
-function attachHistogramPlots(test, container) {
-    var results = test.results();
-    var attachedPlot = false;
-
-    for (var i = 0; i < results.length; i++) {
-        container.append('<div></div>');
-        var histogram = results[i].histogramValues
-        if (!histogram)
-            continue;
-        attachedPlot = true;
-
-        var buckets = histogram.buckets
-        var bucket;
-        var max_count = 0;
-        for (var j = 0; j < buckets.length; j++) {
-            bucket = buckets[j];
-            max_count = Math.max(max_count, bucket.count);
-        }
-        var xmax = bucket.high * 1.1;
-        var ymax = max_count * 1.1;
-
-        var options = $.extend(true, {}, histogramPlotOptions,
-                           {yaxis: {min: 0.0, max: ymax},
-                            xaxis: {min: histogram.params.min, max: xmax}});
-        var plot = $.plot(container.children().last(), [[]], options);
-        // Flot only supports fixed with bars and our histogram's buckets are
-        // variable width, so we need to do our own bar drawing.
-        var ctx = plot.getCanvas().getContext("2d");
-        ctx.lineWidth="1";
-        ctx.fillStyle = "rgba(255, 0, 0, 0.2)";
-        ctx.strokeStyle="red";
-        for (var j = 0; j < buckets.length; j++) {
-            bucket = buckets[j];
-            var bl = plot.pointOffset({ x: bucket.low, y: 0});
-            var tr = plot.pointOffset({ x: bucket.high, y: bucket.count});
-            ctx.fillRect(bl.left, bl.top, tr.left - bl.left, tr.top - bl.top);
-            ctx.strokeRect(bl.left, bl.top, tr.left - bl.left, tr.top - bl.top);
-        }
-    }
-    if (!attachedPlot)
-        container.children().remove();
-}
-
-function attachLinePlotLabels(test, container) {
-    var results = test.results();
-    var attachedPlot = false;
-    for (var i = 0; i < results.length; i++) {
-        container.append('<div>' + results[i].run().label() + '</div>');
-    }
-}
-
-function attachPlot(test, plotContainer, minIsZero) {
-    var results = test.results();
-
-    var values = results.reduce(function(values, result, index) {
-        var newValues = result.values();
-        return newValues ? values.concat(newValues.map(function(value) { return [index, value]; })) : values;
-    }, []);
-
-    var plotData = [$.extend(true, {}, subpointsPlotOptions, {data: values})];
-    plotData.push({id: '&mu;', data: results.map(function(result, index) { return [index, result.mean()]; }), color: plotColor});
-
-    var overallMax = Statistics.max(results.map(function(result, index) { return result.max(); }));
-    var overallMin = Statistics.min(results.map(function(result, index) { return result.min(); }));
-    var margin = (overallMax - overallMin) * 0.1;
-    var currentPlotOptions = $.extend(true, {}, mainPlotOptions, {yaxis: {
-        min: minIsZero ? 0 : overallMin - margin,
-        max: minIsZero ? overallMax * 1.1 : overallMax + margin}});
-
-    currentPlotOptions.xaxis.max = results.length - 0.5;
-    currentPlotOptions.xaxis.ticks = results.map(function(result, index) { return [index, result.run().label()]; });
-
-    $.plot(plotContainer, plotData, currentPlotOptions);
-}
-
-function toFixedWidthPrecision(value) {
-    var decimal = value.toFixed(2);
-    return decimal;
-}
-
-function formatPercentage(fraction) {
-    var percentage = fraction * 100;
-    return (fraction * 100).toFixed(2) + '%';
-}
-
-function setUpSortClicks(runs)
-{
-    $('#nameColumn').click(sortByName);
-
-    $('#unitColumn').click(sortByUnit);
-
-    runs.forEach(function(run) {
-        $('#' + run.id()).click(sortByResult);
-        $('#' + run.id() + COMPARISON_SUFFIX).click(sortByReference);
-     });
-}
-
-function TestTypeSelector(tests) {
-    this.recognizers = {
-        'Time': function(test) { return !test.isMemoryTest(); },
-        'Memory': function(test) { return test.isMemoryTest(); }
-    };
-    this.testTypeNames = this.generateUsedTestTypeNames(tests);
-    // Default to selecting the first test-type name in the list.
-    this.testTypeName = this.testTypeNames[0];
-}
-
-TestTypeSelector.prototype = {
-    set testTypeName(testTypeName) {
-        this._testTypeName = testTypeName;
-        this.shouldShowTest = this.recognizers[testTypeName];
-    },
-
-    generateUsedTestTypeNames: function(allTests) {
-        var testTypeNames = [];
-
-        for (var recognizedTestName in this.recognizers) {
-            var recognizes = this.recognizers[recognizedTestName];
-            for (var testName in allTests) {
-                var test = allTests[testName];
-                if (recognizes(test)) {
-                    testTypeNames.push(recognizedTestName);
-                    break;
-                }
-            }
-        }
-
-        if (testTypeNames.length === 0) {
-            // No test types we recognize, add 'No Results' with a dummy recognizer.
-            var noResults = 'No Results';
-            this.recognizers[noResults] = function() { return false; };
-            testTypeNames.push(noResults);
-        } else if (testTypeNames.length > 1) {
-            // We have more than one test type, so add 'All' with a recognizer that always succeeds.
-            var allResults = 'All';
-            this.recognizers[allResults] = function() { return true; };
-            testTypeNames.push(allResults);
-        }
-
-        return testTypeNames;
-    },
-
-    buildButtonHTMLForUsedTestTypes: function() {
-        var selectedTestTypeName = this._testTypeName;
-        // Build spans for all recognised test names with the selected test highlighted.
-        return this.testTypeNames.map(function(testTypeName) {
-            var classAttribute = testTypeName === selectedTestTypeName ? ' class=checked' : '';
-            return '<span' + classAttribute + '>' + testTypeName + '</span>';
-        }).join('');
-    }
-};
-
-var topLevelRows;
-var allTableRows;
-
-function displayTable(tests, runs, testTypeSelector, referenceIndex, useLargeLinePlots) {
-    var resultHeaders = runs.map(function(run, index) {
-         var header = '<th id="' + run.id() + '" ' +
-                          'colspan=2 ' +
-                          'title="' + run.description() + '">' +
-                      '<span class="label" ' +
-                          'title="Edit run label">' +
-                          run.label() +
-                      '</span>' +
-                      '<div class="closeButton" ' +
-                          'title="Delete run">' +
-                          '&times;' +
-                      '</div>' +
-                  '</th>';
-                if (index !== referenceIndex) {
-                  header += '<th id="' + run.id() + COMPARISON_SUFFIX + '" ' +
-                                'title="Sort by better/worse">' +
-                                '&Delta;' +
-                                '</th>';
-                }
-         return header;
-    });
-
-    resultHeaders = resultHeaders.join('');
-
-    htmlString = '<thead>' +
-                     '<tr>' +
-                         '<th id="nameColumn">' +
-                             '<div class="openAllButton" ' +
-                                  'title="Open all rows or graphs">' +
-                                 'Open All' +
-                              '</div>' +
-                              '<div class="closeAllButton" ' +
-                                   'title="Close all rows">' +
-                                  'Close All' +
-                              '</div>' +
-                              'Test' +
-                          '</th>' +
-                          '<th id="unitColumn">' +
-                              'Unit' +
-                          '</th>' +
-                          resultHeaders +
-                     '</tr>' +
-                 '</head>' +
-                 '<tbody>' +
-                 '</tbody>';
-
-    $('#container').html(htmlString);
-
-    var testNames = [];
-    for (testName in tests)
-        testNames.push(testName);
-
-    allTableRows = [];
-    testNames.forEach(function(testName) {
-        var test = tests[testName];
-        if (testTypeSelector.shouldShowTest(test)) {
-            allTableRows.push(new TableRow(runs, test, referenceIndex, useLargeLinePlots));
-        }
-    });
-
-    // Build a list of top level rows with attached children
-    topLevelRows = [];
-    allTableRows.forEach(function(row) {
-        // Add us to top level if we are a top-level row...
-        if (row.hasNoURL) {
-            topLevelRows.push(row);
-            // Add a duplicate child row that holds the graph for the parent
-            var graphHolder = new TableRow(runs, row.test, referenceIndex, useLargeLinePlots);
-            graphHolder.isImportant = true;
-            graphHolder.URL = 'Summary';
-            graphHolder.hideRowData();
-            allTableRows.push(graphHolder);
-            row.addNestedChild(graphHolder);
-            return;
-        }
-
-        // ...or add us to our parent if we have one ...
-        for (var i = 0; i < allTableRows.length; i++) {
-            if (allTableRows[i].isParentOf(row)) {
-                allTableRows[i].addNestedChild(row);
-                return;
-            }
-        }
-
-        // ...otherwise this result is orphaned, display it at top level with a graph
-        row.hasGraph = true;
-        topLevelRows.push(row);
-    });
-
-    buildTable(topLevelRows);
-
-    $('.closeButton').click(function(event) {
-        for (var i = 0; i < runs.length; i++) {
-            if (runs[i].id() == event.target.parentNode.id) {
-                runs[i].hide();
-                undeleteManager.ondelete(runs[i].id());
-                location.reload();
-                break;
-            }
-        }
-        event.stopPropagation();
-    });
-
-    $('.closeAllButton').click(function(event) {
-        for (var i = 0; i < allTableRows.length; i++) {
-            allTableRows[i].closeRow();
-        }
-        event.stopPropagation();
-    });
-
-    $('.openAllButton').click(function(event) {
-        for (var i = 0; i < topLevelRows.length; i++) {
-            topLevelRows[i].openRow();
-        }
-        event.stopPropagation();
-    });
-
-    setUpSortClicks(runs);
-
-    $('.label').click(function(event) {
-        for (var i = 0; i < runs.length; i++) {
-            if (runs[i].id() == event.target.parentNode.id) {
-                $(event.target).replaceWith('<input id="labelEditor" type="text" value="' + runs[i].label()  + '">');
-                $('#labelEditor').focusout(function() {
-                    runs[i].setLabel(this.value);
-                    location.reload();
-                });
-                $('#labelEditor').keypress(function(event) {
-                    if (event.which == 13) {
-                        runs[i].setLabel(this.value);
-                        location.reload();
-                    }
-                });
-                $('#labelEditor').click(function(event) {
-                    event.stopPropagation();
-                });
-                $('#labelEditor').mousedown(function(event) {
-                    event.stopPropagation();
-                });
-                $('#labelEditor').select();
-                break;
-            }
-        }
-        event.stopPropagation();
-    });
-}
-
-function validForSorting(row) {
-    return ($.type(row.sortValue) === 'string') || !isNaN(row.sortValue);
-}
-
-var sortDirection = 1;
-
-function sortRows(rows) {
-    rows.sort(
-        function(rowA,rowB) {
-            if (validForSorting(rowA) !== validForSorting(rowB)) {
-                // Sort valid values upwards when compared to invalid
-                if (validForSorting(rowA)) {
-                    return -1;
-                }
-                if (validForSorting(rowB)) {
-                    return 1;
-                }
-            }
-
-            // Some rows always sort to the top
-            if (rowA.isImportant) {
-                return -1;
-            }
-            if (rowB.isImportant) {
-                return 1;
-            }
-
-            if (rowA.sortValue === rowB.sortValue) {
-                // Sort identical values by name to keep the sort stable,
-                // always keep name alphabetical (even if a & b sort values
-                // are invalid)
-                return rowA.test.name() > rowB.test.name() ? 1 : -1;
-            }
-
-            return rowA.sortValue > rowB.sortValue ? sortDirection : -sortDirection;
-         } );
-
-    // Sort the rows' children
-    rows.forEach(function(row) {
-        sortRows(row.children);
-    });
-}
-
-function buildTable(rows) {
-   rows.forEach(function(row) {
-     row.removeFromPage();
-   });
-
-   sortRows(rows);
-
-   rows.forEach(function(row) {
-     row.addToPage();
-   });
-}
-
-var activeSortHeaderElement = undefined;
-var columnSortDirection = {};
-
-function determineColumnSortDirection(element) {
-  columnDirection = columnSortDirection[element.id];
-
-  if (columnDirection === undefined) {
-    // First time we've sorted this row, default to down
-    columnSortDirection[element.id] = SORT_DOWN_CLASS;
-  } else if (element === activeSortHeaderElement) {
-    // Clicking on same header again, swap direction
-    columnSortDirection[element.id] = (columnDirection === SORT_UP_CLASS) ? SORT_DOWN_CLASS : SORT_UP_CLASS;
-  }
-}
-
-function updateSortDirection(element) {
-    // Remove old header's sort arrow
-    if (activeSortHeaderElement !== undefined) {
-        activeSortHeaderElement.classList.remove(columnSortDirection[activeSortHeaderElement.id]);
-    }
-
-    determineColumnSortDirection(element);
-
-    sortDirection = (columnSortDirection[element.id] === SORT_UP_CLASS) ? 1 : -1;
-
-    // Add new header's sort arrow
-    element.classList.add(columnSortDirection[element.id]);
-    activeSortHeaderElement = element;
-}
-
-function sortByName(event) {
-    updateSortDirection(event.toElement);
-
-    allTableRows.forEach(function(row) {
-       row.prepareToSortByName();
-    });
-
-    buildTable(topLevelRows);
-}
-
-function sortByUnit(event) {
-    updateSortDirection(event.toElement);
-
-    allTableRows.forEach(function(row) {
-        row.prepareToSortByUnit();
-    });
-
-    buildTable(topLevelRows);
-}
-
-function sortByResult(event) {
-    updateSortDirection(event.toElement);
-
-    var runId = event.target.id;
-
-    allTableRows.forEach(function(row) {
-        row.prepareToSortByTestResults(runId);
-    });
-
-    buildTable(topLevelRows);
-}
-
-function sortByReference(event) {
-    updateSortDirection(event.toElement);
-
-    // The element ID has _compare appended to allow us to set up a click event
-    // remove the _compare to return a useful Id
-    var runIdWithCompare = event.target.id;
-    var runId = runIdWithCompare.split('_')[0];
-
-    allTableRows.forEach(function(row) {
-        row.prepareToSortRelativeToReference(runId);
-    });
-
-    buildTable(topLevelRows);
-}
-
-function linearRegression(points) {
-    // Implement http://www.easycalculation.com/statistics/learn-correlation.php.
-    // x = magnitude
-    // y = iterations
-    var sumX = 0;
-    var sumY = 0;
-    var sumXSquared = 0;
-    var sumYSquared = 0;
-    var sumXTimesY = 0;
-
-    for (var i = 0; i < points.length; i++) {
-        var x = i;
-        var y = points[i];
-        sumX += x;
-        sumY += y;
-        sumXSquared += x * x;
-        sumYSquared += y * y;
-        sumXTimesY += x * y;
-    }
-
-    var r = (points.length * sumXTimesY - sumX * sumY) /
-        Math.sqrt((points.length * sumXSquared - sumX * sumX) *
-                  (points.length * sumYSquared - sumY * sumY));
-
-    if (isNaN(r) || r == Math.Infinity)
-        r = 0;
-
-    var slope = (points.length * sumXTimesY - sumX * sumY) / (points.length * sumXSquared - sumX * sumX);
-    var intercept = sumY / points.length - slope * sumX / points.length;
-    return {slope: slope, intercept: intercept, rSquared: r * r};
-}
-
-var warningSign = '<svg viewBox="0 0 100 100" style="width: 18px; height: 18px; vertical-align: bottom;" version="1.1">'
-    + '<polygon fill="red" points="50,10 90,80 10,80 50,10" stroke="red" stroke-width="10" stroke-linejoin="round" />'
-    + '<polygon fill="white" points="47,30 48,29, 50, 28.7, 52,29 53,30 50,60" stroke="white" stroke-width="10" stroke-linejoin="round" />'
-    + '<circle cx="50" cy="73" r="6" fill="white" />'
-    + '</svg>';
-
-function TableRow(runs, test, referenceIndex, useLargeLinePlots) {
-    this.runs = runs;
-    this.test = test;
-    this.referenceIndex = referenceIndex;
-    this.useLargeLinePlots = useLargeLinePlots;
-    this.children = [];
-
-    this.tableRow = $('<tr class="highlight">' +
-                            '<td class="test collapsed" >' +
-                                this.test.name() +
-                            '</td>' +
-                            '<td class="unit">' +
-                                this.test.unit() +
-                            '</td>' +
-                      '</tr>');
-
-    var runIndex = 0;
-    var results = this.test.results();
-    var referenceResult = undefined;
-
-    this.resultIndexMap = {};
-    for (var i = 0; i < results.length; i++) {
-        while (this.runs[runIndex] !== results[i].run())
-            runIndex++;
-        if (runIndex === this.referenceIndex)
-            referenceResult = results[i];
-        this.resultIndexMap[runIndex] = i;
-    }
-    for (var i = 0; i < this.runs.length; i++) {
-        var resultIndex = this.resultIndexMap[i];
-        if (resultIndex === undefined)
-            this.tableRow.append(this.markupForMissingRun(i == this.referenceIndex));
-        else
-            this.tableRow.append(this.markupForRun(results[resultIndex], referenceResult));
-    }
-
-    // Use the test name (without URL) to bind parents and their children
-    var nameAndURL = this.test.name().split('.');
-    var benchmarkName = nameAndURL.shift();
-    this.testName = nameAndURL.shift();
-    this.hasNoURL = (nameAndURL.length === 0);
-
-    if (!this.hasNoURL) {
-        // Re-join the URL
-        this.URL = nameAndURL.join('.');
-    }
-
-    this.isImportant = false;
-    this.hasGraph = false;
-    this.currentIndentationClass = ''
-    this.indentLevel = 0;
-    this.setRowNestedState(COLLAPSED);
-    this.setVisibility(VISIBLE);
-    this.prepareToSortByName();
-}
-
-TableRow.prototype.hideRowData = function() {
-    data = this.tableRow.children('td');
-
-    for (index in data) {
-        if (index > 0) {
-            // Blank out everything except the test name
-            data[index].innerHTML = '';
-        }
-    }
-}
-
-TableRow.prototype.prepareToSortByTestResults = function(runId) {
-    var testResults = this.test.results();
-    // Find the column in this row that matches the runId and prepare to
-    // sort by the mean of that test.
-    for (index in testResults) {
-        sourceId = testResults[index].run().id();
-        if (runId === sourceId) {
-            this.sortValue = testResults[index].mean();
-            return;
-        }
-    }
-    // This row doesn't have any results for the passed runId
-    this.sortValue = undefined;
-}
-
-TableRow.prototype.prepareToSortRelativeToReference = function(runId) {
-    var testResults = this.test.results();
-
-    // Get index of test results that correspond to the reference column.
-    var remappedReferenceIndex = this.resultIndexMap[this.referenceIndex];
-
-    if (remappedReferenceIndex === undefined) {
-        // This test has no results in the reference run.
-        this.sortValue = undefined;
-        return;
-    }
-
-    otherResults = testResults[remappedReferenceIndex];
-
-    // Find the column in this row that matches the runId and prepare to
-    // sort by the difference from the reference.
-    for (index in testResults) {
-        sourceId = testResults[index].run().id();
-        if (runId === sourceId) {
-            this.sortValue = testResults[index].percentDifference(otherResults);
-            if (this.test.biggerIsBetter()) {
-                // For this test bigger is not better
-                this.sortValue = -this.sortValue;
-            }
-            return;
-        }
-    }
-    // This row doesn't have any results for the passed runId
-    this.sortValue = undefined;
-}
-
-TableRow.prototype.prepareToSortByUnit = function() {
-    this.sortValue = this.test.unit().toLowerCase();
-}
-
-TableRow.prototype.prepareToSortByName = function() {
-    this.sortValue = this.test.name().toLowerCase();
-}
-
-TableRow.prototype.isParentOf = function(row) {
-    return this.hasNoURL && (this.testName === row.testName);
-}
-
-TableRow.prototype.addNestedChild = function(child) {
-    this.children.push(child);
-
-    // Indent child one step in from parent
-    child.indentLevel = this.indentLevel + INDENTATION;
-    child.hasGraph = true;
-    // Start child off as hidden (i.e. collapsed inside parent)
-    child.setVisibility(INVISIBLE);
-    child.updateIndentation();
-    // Show URL in the title column
-    child.tableRow.children()[0].innerHTML = child.URL;
-    // Set up class to change background colour of nested rows
-    if (child.isImportant) {
-        child.tableRow.addClass('importantNestedRow');
-    } else {
-        child.tableRow.addClass('nestedRow');
-    }
-}
-
-TableRow.prototype.setVisibility = function(visibility) {
-     this.visibility = visibility;
-     this.tableRow[0].style.display = (visibility === INVISIBLE) ? 'none' : '';
-}
-
-TableRow.prototype.setRowNestedState = function(newState) {
-    this.rowState = newState;
-    this.updateIndentation();
-}
-
-TableRow.prototype.updateIndentation = function() {
-    var element = this.tableRow.children('td').first();
-
-    element.removeClass(this.currentIndentationClass);
-
-    this.currentIndentationClass = (this.rowState === COLLAPSED) ? 'collapsed' : 'expanded';
-
-    element[0].style.marginLeft = this.indentLevel.toString() + 'px';
-    element[0].style.float = 'left';
-
-    element.addClass(this.currentIndentationClass);
-}
-
-TableRow.prototype.addToPage = function() {
-    $('#container').children('tbody').last().append(this.tableRow);
-
-    // Set up click callback
-    var owningObject = this;
-    this.tableRow.click(function(event) {
-        event.preventDefault();
-        owningObject.toggle();
-    });
-
-    // Add children to the page too
-    this.children.forEach(function(child) {
-        child.addToPage();
-    });
-}
-
-TableRow.prototype.removeFromPage = function() {
-    // Remove children
-    this.children.forEach(function(child) {
-        child.removeFromPage();
-    });
-    // Remove us
-    this.tableRow.remove();
-}
-
-
-TableRow.prototype.markupForRun = function(result, referenceResult) {
-    var comparisonCell = '';
-    var shouldCompare = result !== referenceResult;
-    if (shouldCompare) {
-        var comparisonText = '';
-        var className = '';
-
-        if (referenceResult) {
-            var percentDifference = referenceResult.percentDifference(result);
-            if (isNaN(percentDifference)) {
-                comparisonText = 'Unknown';
-                className = UNKNOWN_CLASS;
-            } else if (Math.abs(percentDifference) < SMALLEST_PERCENT_DISPLAYED) {
-                comparisonText = 'Equal';
-                // Show equal values in green
-                className = BETTER_CLASS;
-            } else {
-                var better = this.test.biggerIsBetter() ? percentDifference > 0 : percentDifference < 0;
-                comparisonText = formatPercentage(Math.abs(percentDifference)) + (better ? ' Better' : ' Worse');
-                className = better ? BETTER_CLASS : WORSE_CLASS;
-            }
-
-            if (!referenceResult.isStatisticallySignificant(result)) {
-                // Put result in brackets and fade if not statistically significant
-                className += ' fadeOut';
-                comparisonText = '(' + comparisonText + ')';
-            }
-        }
-        comparisonCell = '<td class="comparison ' + className + '">' + comparisonText + '</td>';
-    }
-
-    var values = result.values();
-    var warning = '';
-    var regressionAnalysis = '';
-    if (result.histogramValues) {
-        // Don't calculate regression result for histograms.
-    } else if (values && values.length > 3) {
-        regressionResult = linearRegression(values);
-        regressionAnalysis = 'slope=' + toFixedWidthPrecision(regressionResult.slope)
-            + ', R^2=' + toFixedWidthPrecision(regressionResult.rSquared);
-        if (regressionResult.rSquared > 0.6 && Math.abs(regressionResult.slope) > 0.01) {
-            warning = ' <span class="regression-warning" title="Detected a time dependency with ' + regressionAnalysis + '">' + warningSign + ' </span>';
-        }
-    }
-
-    var referenceClass = shouldCompare ? '' : 'reference';
-
-    var statistics = '&sigma;=' + toFixedWidthPrecision(result.confidenceIntervalDelta()) + ', min=' + toFixedWidthPrecision(result.min())
-     + ', max=' + toFixedWidthPrecision(result.max()) + '\n' + regressionAnalysis;
-
-    var confidence;
-    if (isNaN(result.confidenceIntervalDeltaRatio())) {
-        // Don't bother showing +- Nan as it is meaningless
-        confidence = '';
-    } else {
-        confidence = '&plusmn; ' + formatPercentage(result.confidenceIntervalDeltaRatio());
-    }
-
-    return '<td class="result ' + referenceClass + '" title="' + statistics + '">' + toFixedWidthPrecision(result.mean())
-        + '</td><td class="confidenceIntervalDelta ' + referenceClass + '" title="' + statistics + '">' + confidence + warning + '</td>' + comparisonCell;
-}
-
-TableRow.prototype.markupForMissingRun = function(isReference) {
-    if (isReference) {
-        return '<td colspan=2 class="missingReference">Missing</td>';
-    }
-    return '<td colspan=3 class="missing">Missing</td>';
-}
-
-TableRow.prototype.openRow = function() {
-    if (this.rowState === EXPANDED) {
-        // If we're already expanded, open our children instead
-        this.children.forEach(function(child) {
-            child.openRow();
-        });
-        return;
-    }
-
-    this.setRowNestedState(EXPANDED);
-
-    if (this.hasGraph) {
-        var firstCell = this.tableRow.children('td').first();
-        var plot = createPlot(firstCell, this.test, this.useLargeLinePlots);
-        plot.css({'position': 'absolute', 'z-index': 2});
-        var offset = this.tableRow.offset();
-        offset.left += GRAPH_INDENT;
-        offset.top += this.tableRow.outerHeight();
-        plot.offset(offset);
-        this.tableRow.children('td').css({'padding-bottom': plot.outerHeight() + PADDING_UNDER_GRAPH});
-    }
-
-    this.children.forEach(function(child) {
-        child.setVisibility(VISIBLE);
-    });
-
-    if (this.children.length === 1) {
-        // If we only have a single child...
-        var child = this.children[0];
-        if (child.isImportant) {
-          // ... and it is important (i.e. the summary row) just open it when
-          // parent is opened to save needless clicking
-          child.openRow();
-        }
-    }
-}
-
-TableRow.prototype.closeRow = function() {
-    if (this.rowState === COLLAPSED) {
-        return;
-    }
-
-    this.setRowNestedState(COLLAPSED);
-
-    if (this.hasGraph) {
-        var firstCell = this.tableRow.children('td').first();
-        firstCell.children('section').remove();
-        this.tableRow.children('td').css({'padding-bottom': ''});
-    }
-
-    this.children.forEach(function(child) {
-        // Make children invisible, but leave their collapsed status alone
-        child.setVisibility(INVISIBLE);
-    });
-}
-
-TableRow.prototype.toggle = function() {
-    if (this.rowState === EXPANDED) {
-        this.closeRow();
-    } else {
-        this.openRow();
-    }
-    return false;
-}
-
-function init() {
-    var runs = [];
-    var metrics = {};
-    var deletedRunsById = {};
-    $.each(JSON.parse(document.getElementById('results-json').textContent), function(index, entry) {
-        var run = new TestRun(entry);
-        if (run.isHidden()) {
-            deletedRunsById[run.id()] = run;
-            return;
-        }
-
-        runs.push(run);
-
-        function addTests(tests) {
-            for (var testName in tests) {
-                var rawMetrics = tests[testName].metrics;
-
-                for (var metricName in rawMetrics) {
-                    var fullMetricName = testName + ':' + metricName;
-                    var metric = metrics[fullMetricName];
-                    if (!metric) {
-                        metric = new PerfTestMetric(testName, metricName, rawMetrics[metricName].units, rawMetrics[metricName].important);
-                        metrics[fullMetricName] = metric;
-                    }
-                    // std & degrees_of_freedom could be undefined
-                    metric.addResult(
-                        new TestResult(metric, rawMetrics[metricName].current,
-                            run, rawMetrics[metricName]['std'], rawMetrics[metricName]['degrees_of_freedom']));
-                }
-            }
-        }
-
-        addTests(entry.tests);
-    });
-
-    var useLargeLinePlots = false;
-    var referenceIndex = 0;
-
-    var testTypeSelector = new TestTypeSelector(metrics);
-    var buttonHTML = testTypeSelector.buildButtonHTMLForUsedTestTypes();
-    $('#time-memory').append(buttonHTML);
-
-    $('#scatter-line').bind('change', function(event, checkedElement) {
-        useLargeLinePlots = checkedElement.textContent == 'Line';
-        displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
-    });
-
-    runs.map(function(run, index) {
-        $('#reference').append('<span value="' + index + '"' + (index == referenceIndex ? ' class="checked"' : '') + ' title="' + run.description() + '">' + run.label() + '</span>');
-    })
-
-    $('#time-memory').bind('change', function(event, checkedElement) {
-        testTypeSelector.testTypeName = checkedElement.textContent;
-        displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
-    });
-
-    $('#reference').bind('change', function(event, checkedElement) {
-        referenceIndex = parseInt(checkedElement.getAttribute('value'));
-        displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
-    });
-
-    displayTable(metrics, runs, testTypeSelector, referenceIndex, useLargeLinePlots);
-
-    $('.checkbox').each(function(index, checkbox) {
-        $(checkbox).children('span').click(function(event) {
-            if ($(this).hasClass('checked'))
-                return;
-            $(checkbox).children('span').removeClass('checked');
-            $(this).addClass('checked');
-            $(checkbox).trigger('change', $(this));
-        });
-    });
-
-    runToUndelete = deletedRunsById[undeleteManager.mostRecentlyDeletedId()];
-
-    if (runToUndelete) {
-        $('#undelete').html('Undelete ' + runToUndelete.label());
-        $('#undelete').attr('title', runToUndelete.description());
-        $('#undelete').click(function(event) {
-            runToUndelete.show();
-            undeleteManager.undeleteMostRecent();
-            location.reload();
-        });
-    } else {
-        $('#undelete').hide();
-    }
-}
-
-</script>
-<script id="results-json" type="application/json">%json_results%</script>
-<script id="units-json" type="application/json">%json_units%</script>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry.gyp b/catapult/telemetry/telemetry.gyp
deleted file mode 100644
index 02ecd8d..0000000
--- a/catapult/telemetry/telemetry.gyp
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
-  'targets': [
-    {
-      'target_name': 'bitmaptools',
-      'type': 'executable',
-      'sources': [
-        'telemetry/internal/image_processing/bitmaptools.cc',
-      ],
-      'toolsets': ['host'],
-    },
-  ],
-}
diff --git a/catapult/telemetry/telemetry.isolate b/catapult/telemetry/telemetry.isolate
deleted file mode 100644
index 829efec..0000000
--- a/catapult/telemetry/telemetry.isolate
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright (c) 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
-  'conditions': [
-    ['OS=="android" or OS=="linux" or OS=="mac" or OS=="win"', {
-      'variables': {
-        'files': [
-          # For now, just include the whole catapult directory.
-          # TODO(nednguyen, aiolos): only include what telemetry needs.
-          # https://github.com/catapult-project/catapult/issues/1953
-          '../',
-          # For Telemetry's screenshot support.
-          '<(PRODUCT_DIR)/bitmaptools<(EXECUTABLE_SUFFIX)',
-        ],
-      },
-    }],
-  ]
-}
diff --git a/catapult/telemetry/telemetry/__init__.py b/catapult/telemetry/telemetry/__init__.py
deleted file mode 100644
index e91b2f8..0000000
--- a/catapult/telemetry/telemetry/__init__.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A library for cross-platform browser tests."""
-import os
-import sys
-
-
-# Ensure Python >= 2.7.
-if sys.version_info < (2, 7):
-  print >> sys.stderr, 'Need Python 2.7 or greater.'
-  sys.exit(-1)
-
-
-def _JoinPath(*path_parts):
-  return os.path.abspath(os.path.join(*path_parts))
-
-
-def _AddDirToPythonPath(*path_parts):
-  path = _JoinPath(*path_parts)
-  assert os.path.isdir(path), 'Not a valid path: %s' % path
-  if path not in sys.path:
-    # Some call sites that use Telemetry assume that sys.path[0] is the
-    # directory containing the script, so we add these extra paths to right
-    # after sys.path[0].
-    sys.path.insert(1, path)
-
-
-# Add Catapult dependencies to our path.
-# util depends on py_utils, so we can't use it to get the catapult dir.
-_CATAPULT_DIR = os.path.join(
-    os.path.dirname(os.path.abspath(__file__)), '..', '..')
-_AddDirToPythonPath(_CATAPULT_DIR, 'common', 'py_utils')
-_AddDirToPythonPath(_CATAPULT_DIR, 'dependency_manager')
-_AddDirToPythonPath(_CATAPULT_DIR, 'devil')
-_AddDirToPythonPath(_CATAPULT_DIR, 'systrace')
-_AddDirToPythonPath(_CATAPULT_DIR, 'tracing')
-_AddDirToPythonPath(_CATAPULT_DIR, 'common', 'py_trace_event')
-_AddDirToPythonPath(_CATAPULT_DIR, 'common', 'battor')
-_AddDirToPythonPath(_CATAPULT_DIR, 'tracing', 'tracing_build')
-_AddDirToPythonPath(_CATAPULT_DIR, 'third_party', 'py_vulcanize')
-
-
-from telemetry.core import util
-from telemetry.internal.util import global_hooks
-
-# Add Catapult third party dependencies into our path.
-_AddDirToPythonPath(util.GetCatapultThirdPartyDir(), 'typ')
-# Required by websocket-client.
-_AddDirToPythonPath(util.GetCatapultThirdPartyDir(), 'six')
-
-# Add Telemetry third party dependencies into our path.
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'altgraph')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'mock')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'modulegraph')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'mox3')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'png')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'pyfakefs')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'pyserial')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'web-page-replay')
-_AddDirToPythonPath(util.GetTelemetryThirdPartyDir(), 'websocket-client')
-
-# Install Telemtry global hooks.
-global_hooks.InstallHooks()
diff --git a/catapult/telemetry/telemetry/android/__init__.py b/catapult/telemetry/telemetry/android/__init__.py
deleted file mode 100644
index 6bd5e3a..0000000
--- a/catapult/telemetry/telemetry/android/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.android.android_story import AndroidStory
-from telemetry.android.shared_android_state import SharedAndroidState
diff --git a/catapult/telemetry/telemetry/android/android_story.py b/catapult/telemetry/telemetry/android/android_story.py
deleted file mode 100644
index 9949e79..0000000
--- a/catapult/telemetry/telemetry/android/android_story.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.android import shared_android_state
-from telemetry import story
-
-class AndroidStory(story.Story):
-  def __init__(self, start_intent, is_app_ready_predicate=None,
-               name='', tags=None, is_local=False):
-    """Creates a new story for Android app.
-
-    Args:
-      start_intent: See AndroidPlatform.LaunchAndroidApplication.
-      is_app_ready_predicate: See AndroidPlatform.LaunchAndroidApplication.
-      name: See Story.__init__.
-      tags: See Story.__init__
-      is_app_ready_predicate: See Story.__init__.
-    """
-    super(AndroidStory, self).__init__(
-        shared_android_state.SharedAndroidState, name=name, tags=tags,
-        is_local=is_local)
-    self.start_intent = start_intent
-    self.is_app_ready_predicate = is_app_ready_predicate
-
-  def Run(self, shared_state):
-    """Execute the interactions with the applications."""
-    raise NotImplementedError
diff --git a/catapult/telemetry/telemetry/android/shared_android_state.py b/catapult/telemetry/telemetry/android/shared_android_state.py
deleted file mode 100644
index d5a4e69..0000000
--- a/catapult/telemetry/telemetry/android/shared_android_state.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.core import android_platform
-from telemetry.core import platform
-from telemetry.internal.platform import android_device
-from telemetry import story as story_module
-from telemetry.web_perf import timeline_based_measurement
-
-
-class SharedAndroidState(story_module.SharedState):
-  """Manage test state/transitions across multiple android.AndroidStory's.
-
-  WARNING: the class is not ready for public consumption.
-  Email telemetry@chromium.org if you feel like you must use it.
-  """
-
-  def __init__(self, test, finder_options, story_set):
-    """This method is styled on unittest.TestCase.setUpClass.
-
-    Args:
-      test: a web_perf.TimelineBasedMeasurement instance.
-      options: a BrowserFinderOptions instance with command line options.
-      story_set: a story.StorySet instance.
-    """
-    super(SharedAndroidState, self).__init__(test, finder_options, story_set)
-    if not isinstance(
-        test, timeline_based_measurement.TimelineBasedMeasurement):
-      raise ValueError(
-          'SharedAndroidState only accepts TimelineBasedMeasurement tests'
-          ' (not %s).' % test.__class__)
-    self._test = test
-    self._finder_options = finder_options
-    self._android_app = None
-    self._current_story = None
-    device = android_device.GetDevice(finder_options)
-    assert device, 'Android device required.'
-    self._android_platform = platform.GetPlatformForDevice(
-        device, finder_options)
-    assert self._android_platform, 'Unable to create android platform.'
-    assert isinstance(
-        self._android_platform, android_platform.AndroidPlatform)
-
-  @property
-  def app(self):
-    return self._android_app
-
-  @property
-  def platform(self):
-    return self._android_platform
-
-  def WillRunStory(self, story):
-    assert not self._android_app
-    self._current_story = story
-    self._android_app = self._android_platform.LaunchAndroidApplication(
-        story.start_intent, story.is_app_ready_predicate)
-    self._test.WillRunStory(self._android_platform.tracing_controller)
-
-  def CanRunStory(self, story):
-    """This does not apply to android app stories."""
-    return True
-
-  def RunStory(self, results):
-    self._current_story.Run(self)
-    self._test.Measure(self._android_platform.tracing_controller, results)
-
-  def DidRunStory(self, results):
-    self._test.DidRunStory(self._android_platform.tracing_controller)
-    if self._android_app:
-      self._android_app.Close()
-      self._android_app = None
-
-  def TearDownState(self):
-    """Tear down anything created in the __init__ method that is not needed.
-
-    Currently, there is no clean-up needed from SharedAndroidState.__init__.
-    """
-    pass
-
-  def DumpStateUponFailure(self, story, results):
-    # TODO: Dump the state of the Android app.
-    pass
diff --git a/catapult/telemetry/telemetry/benchmark.py b/catapult/telemetry/telemetry/benchmark.py
deleted file mode 100644
index 3cf78ff..0000000
--- a/catapult/telemetry/telemetry/benchmark.py
+++ /dev/null
@@ -1,274 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-
-from telemetry import decorators
-from telemetry.internal import story_runner
-from telemetry.internal.util import command_line
-from telemetry.page import legacy_page_test
-from telemetry.web_perf import timeline_based_measurement
-
-Disabled = decorators.Disabled
-Enabled = decorators.Enabled
-Owner = decorators.Owner
-
-class InvalidOptionsError(Exception):
-  """Raised for invalid benchmark options."""
-  pass
-
-
-class BenchmarkMetadata(object):
-  def __init__(self, name, description='', rerun_options=None):
-    self._name = name
-    self._description = description
-    self._rerun_options = rerun_options
-
-  @property
-  def name(self):
-    return self._name
-
-  @property
-  def description(self):
-    return self._description
-
-  @property
-  def rerun_options(self):
-    return self._rerun_options
-
-  def AsDict(self):
-    return {
-      'type': 'telemetry_benchmark',
-      'name': self._name,
-      'description': self._description,
-      'rerun_options': self._rerun_options,
-    }
-
-
-class Benchmark(command_line.Command):
-  """Base class for a Telemetry benchmark.
-
-  A benchmark packages a measurement and a PageSet together.
-  Benchmarks default to using TBM unless you override the value of
-  Benchmark.test, or override the CreatePageTest method.
-
-  New benchmarks should override CreateStorySet.
-  """
-  options = {}
-  page_set = None
-  test = timeline_based_measurement.TimelineBasedMeasurement
-
-  def __init__(self, max_failures=None):
-    """Creates a new Benchmark.
-
-    Args:
-      max_failures: The number of story run's failures before bailing
-          from executing subsequent page runs. If None, we never bail.
-    """
-    self._max_failures = max_failures
-    self._has_original_tbm_options = (
-        self.CreateTimelineBasedMeasurementOptions.__func__ ==
-        Benchmark.CreateTimelineBasedMeasurementOptions.__func__)
-    has_original_create_page_test = (
-        self.CreatePageTest.__func__ == Benchmark.CreatePageTest.__func__)
-    assert self._has_original_tbm_options or has_original_create_page_test, (
-        'Cannot override both CreatePageTest and '
-        'CreateTimelineBasedMeasurementOptions.')
-
-  # pylint: disable=unused-argument
-  @classmethod
-  def ShouldDisable(cls, possible_browser):
-    """Override this method to disable a benchmark under specific conditions.
-
-     Supports logic too complex for simple Enabled and Disabled decorators.
-     Decorators are still respected in cases where this function returns False.
-     """
-    return False
-
-  def Run(self, finder_options):
-    """Do not override this method."""
-    return story_runner.RunBenchmark(self, finder_options)
-
-  @property
-  def max_failures(self):
-    return self._max_failures
-
-  @classmethod
-  def Name(cls):
-    return '%s.%s' % (cls.__module__.split('.')[-1], cls.__name__)
-
-  @classmethod
-  def ShouldTearDownStateAfterEachStoryRun(cls):
-    """Override to specify whether to tear down state after each story run.
-
-    Tearing down all states after each story run, e.g., clearing profiles,
-    stopping the browser, stopping local server, etc. So the browser will not be
-    reused among multiple stories. This is particularly useful to get the
-    startup part of launching the browser in each story.
-
-    This should only be used by TimelineBasedMeasurement (TBM) benchmarks, but
-    not by PageTest based benchmarks.
-    """
-    return True
-
-  # NOTE: this is a temporary workaround for crbug.com/645329, do not rely on
-  # this as a stable public API as we may remove this without public notice.
-  @classmethod
-  def IsShouldTearDownStateAfterEachStoryRunOverriden(cls):
-    return (cls.ShouldTearDownStateAfterEachStoryRun.__func__ !=
-            Benchmark.ShouldTearDownStateAfterEachStoryRun.__func__)
-
-  @classmethod
-  def ShouldTearDownStateAfterEachStorySetRun(cls):
-    """Override to specify whether to tear down state after each story set run.
-
-    Defaults to True in order to reset the state and make individual story set
-    repeats more independent of each other. The intended effect is to average
-    out noise in measurements between repeats.
-
-    Long running benchmarks willing to stess test the browser and have it run
-    for long periods of time may switch this value to False.
-
-    This should only be used by TimelineBasedMeasurement (TBM) benchmarks, but
-    not by PageTest based benchmarks.
-    """
-    return True
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    group = optparse.OptionGroup(parser, '%s test options' % cls.Name())
-    cls.AddBenchmarkCommandLineArgs(group)
-
-    if cls.HasTraceRerunDebugOption():
-      group.add_option(
-          '--rerun-with-debug-trace',
-          action='store_true',
-          help='Rerun option that enables more extensive tracing.')
-
-    if group.option_list:
-      parser.add_option_group(group)
-
-  @classmethod
-  def AddBenchmarkCommandLineArgs(cls, group):
-    del group  # unused
-
-  @classmethod
-  def HasTraceRerunDebugOption(cls):
-    return False
-
-  def GetTraceRerunCommands(self):
-    if self.HasTraceRerunDebugOption():
-      return [['Debug Trace', '--rerun-with-debug-trace']]
-    return []
-
-  def SetupTraceRerunOptions(self, browser_options, tbm_options):
-    if self.HasTraceRerunDebugOption():
-      if browser_options.rerun_with_debug_trace:
-        self.SetupBenchmarkDebugTraceRerunOptions(tbm_options)
-      else:
-        self.SetupBenchmarkDefaultTraceRerunOptions(tbm_options)
-
-  def SetupBenchmarkDefaultTraceRerunOptions(self, tbm_options):
-    """Setup tracing categories associated with default trace option."""
-
-  def SetupBenchmarkDebugTraceRerunOptions(self, tbm_options):
-    """Setup tracing categories associated with debug trace option."""
-
-  @classmethod
-  def SetArgumentDefaults(cls, parser):
-    default_values = parser.get_default_values()
-    invalid_options = [
-        o for o in cls.options if not hasattr(default_values, o)]
-    if invalid_options:
-      raise InvalidOptionsError('Invalid benchmark options: %s',
-                                ', '.join(invalid_options))
-    parser.set_defaults(**cls.options)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    pass
-
-  # pylint: disable=unused-argument
-  @classmethod
-  def ValueCanBeAddedPredicate(cls, value, is_first_result):
-    """Returns whether |value| can be added to the test results.
-
-    Override this method to customize the logic of adding values to test
-    results.
-
-    Args:
-      value: a value.Value instance (except failure.FailureValue,
-        skip.SkipValue or trace.TraceValue which will always be added).
-      is_first_result: True if |value| is the first result for its
-          corresponding story.
-
-    Returns:
-      True if |value| should be added to the test results.
-      Otherwise, it returns False.
-    """
-    return True
-
-  def CustomizeBrowserOptions(self, options):
-    """Add browser options that are required by this benchmark."""
-
-  def GetMetadata(self):
-    return BenchmarkMetadata(
-        self.Name(), self.__doc__, self.GetTraceRerunCommands())
-
-  def CreateTimelineBasedMeasurementOptions(self):
-    """Return the TimelineBasedMeasurementOptions for this Benchmark.
-
-    Override this method to configure a TimelineBasedMeasurement benchmark.
-    Otherwise, override CreatePageTest for PageTest tests. Do not override
-    both methods.
-    """
-    return timeline_based_measurement.Options()
-
-  def CreatePageTest(self, options):  # pylint: disable=unused-argument
-    """Return the PageTest for this Benchmark.
-
-    Override this method for PageTest tests.
-    Override, override CreateTimelineBasedMeasurementOptions to configure
-    TimelineBasedMeasurement tests. Do not override both methods.
-
-    Args:
-      options: a browser_options.BrowserFinderOptions instance
-    Returns:
-      |test()| if |test| is a PageTest class.
-      Otherwise, a TimelineBasedMeasurement instance.
-    """
-    is_page_test = issubclass(self.test, legacy_page_test.LegacyPageTest)
-    is_tbm = self.test == timeline_based_measurement.TimelineBasedMeasurement
-    if not is_page_test and not is_tbm:
-      raise TypeError('"%s" is not a PageTest or a TimelineBasedMeasurement.' %
-                      self.test.__name__)
-    if is_page_test:
-      assert self._has_original_tbm_options, (
-          'Cannot override CreateTimelineBasedMeasurementOptions '
-          'with a PageTest.')
-      return self.test()  # pylint: disable=no-value-for-parameter
-
-    opts = self.CreateTimelineBasedMeasurementOptions()
-    self.SetupTraceRerunOptions(options, opts)
-    return timeline_based_measurement.TimelineBasedMeasurement(opts)
-
-  def CreateStorySet(self, options):
-    """Creates the instance of StorySet used to run the benchmark.
-
-    Can be overridden by subclasses.
-    """
-    del options  # unused
-    # TODO(aiolos, nednguyen, eakufner): replace class attribute page_set with
-    # story_set.
-    if not self.page_set:
-      raise NotImplementedError('This test has no "page_set" attribute.')
-    return self.page_set()  # pylint: disable=not-callable
-
-
-def AddCommandLineArgs(parser):
-  story_runner.AddCommandLineArgs(parser)
-
-
-def ProcessCommandLineArgs(parser, args):
-  story_runner.ProcessCommandLineArgs(parser, args)
diff --git a/catapult/telemetry/telemetry/benchmark_run_unittest.py b/catapult/telemetry/telemetry/benchmark_run_unittest.py
deleted file mode 100644
index ab6b741..0000000
--- a/catapult/telemetry/telemetry/benchmark_run_unittest.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import benchmark as benchmark_module
-from telemetry import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry import story as story_module
-from telemetry.testing import fakes
-import mock
-
-
-# pylint: disable=abstract-method
-class DummyPageTest(legacy_page_test.LegacyPageTest):
-  def __init__(self):
-    super(DummyPageTest, self).__init__()
-    # Without disabling the above warning, this complains that
-    # ValidateAndMeasurePage is abstract; but defining it complains
-    # that its definition is overridden here.
-    self.ValidateAndMeasurePage = mock.Mock()
-
-
-# More end-to-end tests of Benchmark, shared_page_state and associated
-# classes using telemetry.testing.fakes, to avoid needing to construct
-# a real browser instance.
-
-class FakePage(page_module.Page):
-  def __init__(self, page_set):
-    super(FakePage, self).__init__(
-      url='http://nonexistentserver.com/nonexistentpage.html',
-      page_set=page_set,
-      shared_page_state_class=fakes.FakeSharedPageState)
-    self.RunNavigateSteps = mock.Mock()
-    self.RunPageInteractions = mock.Mock()
-
-class FakeBenchmark(benchmark_module.Benchmark):
-  def __init__(self, max_failures=None):
-    super(FakeBenchmark, self).__init__(max_failures)
-    self._fake_pages = []
-    self._fake_story_set = story_module.StorySet()
-    self._created_story_set = False
-    self.validator = DummyPageTest()
-
-  def CreatePageTest(self, options):
-    return self.validator
-
-  def GetFakeStorySet(self):
-    return self._fake_story_set
-
-  def AddFakePage(self, page):
-    if self._created_story_set:
-      raise Exception('Can not add any more fake pages')
-    self._fake_pages.append(page)
-
-  def CreateStorySet(self, options):
-    if self._created_story_set:
-      raise Exception('Can only create the story set once per FakeBenchmark')
-    for page in self._fake_pages:
-      self._fake_story_set.AddStory(page)
-    self._created_story_set = True
-    return self._fake_story_set
-
-
-class FailingPage(FakePage):
-  def __init__(self, page_set):
-    super(FailingPage, self).__init__(page_set)
-    self.RunNavigateSteps.side_effect = Exception('Deliberate exception')
-
-
-class BenchmarkRunTest(unittest.TestCase):
-  def setupBenchmark(self):
-    finder_options = fakes.CreateBrowserFinderOptions()
-    finder_options.browser_options.platform = fakes.FakeLinuxPlatform()
-    finder_options.output_formats = ['none']
-    finder_options.suppress_gtest_report = True
-    finder_options.output_dir = None
-    finder_options.upload_bucket = 'public'
-    finder_options.upload_results = False
-    benchmarkclass = FakeBenchmark
-    parser = finder_options.CreateParser()
-    benchmark_module.AddCommandLineArgs(parser)
-    benchmarkclass.AddCommandLineArgs(parser)
-    options, _ = parser.parse_args([])
-    benchmark_module.ProcessCommandLineArgs(parser, options)
-    benchmarkclass.ProcessCommandLineArgs(parser, options)
-    benchmark = benchmarkclass()
-    return benchmark, finder_options
-
-  def testPassingPage(self):
-    benchmark, finder_options = self.setupBenchmark()
-    manager = mock.Mock()
-    page = FakePage(benchmark.GetFakeStorySet())
-    page.RunNavigateSteps = manager.page.RunNavigateSteps
-    page.RunPageInteractions = manager.page.RunPageInteractions
-    benchmark.validator.ValidateAndMeasurePage = (
-      manager.validator.ValidateAndMeasurePage)
-    benchmark.AddFakePage(page)
-    self.assertEqual(benchmark.Run(finder_options), 0,
-                     'Test should run with no errors')
-    expected = [mock.call.page.RunNavigateSteps(mock.ANY),
-                mock.call.page.RunPageInteractions(mock.ANY),
-                mock.call.validator.ValidateAndMeasurePage(
-                  page, mock.ANY, mock.ANY)]
-    self.assertTrue(manager.mock_calls == expected)
-
-
-  def testFailingPage(self):
-    benchmark, finder_options = self.setupBenchmark()
-    page = FailingPage(benchmark.GetFakeStorySet())
-    benchmark.AddFakePage(page)
-    self.assertNotEqual(benchmark.Run(finder_options), 0, 'Test should fail')
-    self.assertFalse(page.RunPageInteractions.called)
diff --git a/catapult/telemetry/telemetry/benchmark_runner.py b/catapult/telemetry/telemetry/benchmark_runner.py
deleted file mode 100644
index ae5020e..0000000
--- a/catapult/telemetry/telemetry/benchmark_runner.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Parses the command line, discovers the appropriate benchmarks, and runs them.
-
-Handles benchmark configuration, but all the logic for
-actually running the benchmark is in Benchmark and PageRunner."""
-
-import argparse
-import json
-import logging
-import os
-import sys
-
-from telemetry import benchmark
-from telemetry.core import discover
-from telemetry import decorators
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import browser_options
-from telemetry.internal.util import binary_manager
-from telemetry.internal.util import command_line
-from telemetry.internal.util import ps_util
-from telemetry.util import matching
-from telemetry.util import bot_utils
-
-
-# Right now, we only have one of each of our power perf bots. This means that
-# all eligible Telemetry benchmarks are run unsharded, which results in very
-# long (12h) cycle times. We'd like to reduce the number of tests that we run
-# on each bot drastically until we get more of the same hardware to shard tests
-# with, but we can't do so until we've verified that the hardware configuration
-# is a viable one for Chrome Telemetry tests. This is done by seeing at least
-# one all-green test run. As this happens for each bot, we'll add it to this
-# whitelist, making it eligible to run only BattOr power tests.
-GOOD_POWER_PERF_BOT_WHITELIST = [
-  "Mac Power Dual-GPU Perf",
-  "Mac Power Low-End Perf"
-]
-
-
-DEFAULT_LOG_FORMAT = (
-  '(%(levelname)s) %(asctime)s %(module)s.%(funcName)s:%(lineno)d  '
-  '%(message)s')
-
-
-def _IsBenchmarkEnabled(benchmark_class, possible_browser):
-  return (issubclass(benchmark_class, benchmark.Benchmark) and
-          decorators.IsBenchmarkEnabled(benchmark_class, possible_browser))
-
-
-def PrintBenchmarkList(benchmarks, possible_browser, output_pipe=sys.stdout):
-  """ Print benchmarks that are not filtered in the same order of benchmarks in
-  the |benchmarks| list.
-
-  Args:
-    benchmarks: the list of benchmarks to be printed (in the same order of the
-      list).
-    possible_browser: the possible_browser instance that's used for checking
-      which benchmarks are enabled.
-    output_pipe: the stream in which benchmarks are printed on.
-  """
-  if not benchmarks:
-    print >> output_pipe, 'No benchmarks found!'
-    return
-
-  bad_benchmark = next(
-    (b for b in benchmarks if not issubclass(b, benchmark.Benchmark)), None)
-  assert bad_benchmark is None, (
-    '|benchmarks| param contains non benchmark class: %s' % bad_benchmark)
-
-  # Align the benchmark names to the longest one.
-  format_string = '  %%-%ds %%s' % max(len(b.Name()) for b in benchmarks)
-  disabled_benchmarks = []
-
-  print >> output_pipe, 'Available benchmarks %sare:' % (
-      'for %s ' % possible_browser.browser_type if possible_browser else '')
-
-  # Sort the benchmarks by benchmark name.
-  benchmarks = sorted(benchmarks, key=lambda b: b.Name())
-  for b in benchmarks:
-    if not possible_browser or _IsBenchmarkEnabled(b, possible_browser):
-      print >> output_pipe, format_string % (b.Name(), b.Description())
-    else:
-      disabled_benchmarks.append(b)
-
-  if disabled_benchmarks:
-    print >> output_pipe, (
-        '\nDisabled benchmarks for %s are (force run with -d):' %
-        possible_browser.browser_type)
-    for b in disabled_benchmarks:
-      print >> output_pipe, format_string % (b.Name(), b.Description())
-  print >> output_pipe, (
-      'Pass --browser to list benchmarks for another browser.\n')
-
-
-class Help(command_line.OptparseCommand):
-  """Display help information about a command"""
-
-  usage = '[command]'
-
-  def __init__(self, commands):
-    self._all_commands = commands
-
-  def Run(self, args):
-    if len(args.positional_args) == 1:
-      commands = _MatchingCommands(args.positional_args[0], self._all_commands)
-      if len(commands) == 1:
-        command = commands[0]
-        parser = command.CreateParser()
-        command.AddCommandLineArgs(parser, None)
-        parser.print_help()
-        return 0
-
-    print >> sys.stderr, ('usage: %s [command] [<options>]' % _ScriptName())
-    print >> sys.stderr, 'Available commands are:'
-    for command in self._all_commands:
-      print >> sys.stderr, '  %-10s %s' % (
-          command.Name(), command.Description())
-    print >> sys.stderr, ('"%s help <command>" to see usage information '
-                          'for a specific command.' % _ScriptName())
-    return 0
-
-
-class List(command_line.OptparseCommand):
-  """Lists the available benchmarks"""
-
-  usage = '[benchmark_name] [<options>]'
-
-  @classmethod
-  def CreateParser(cls):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser('%%prog %s %s' % (cls.Name(), cls.usage))
-    return parser
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser, _):
-    parser.add_option('-j', '--json-output-file', type='string')
-    parser.add_option('-n', '--num-shards', type='int', default=1)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args, environment):
-    if not args.positional_args:
-      args.benchmarks = _Benchmarks(environment)
-    elif len(args.positional_args) == 1:
-      args.benchmarks = _MatchBenchmarkName(args.positional_args[0],
-                                            environment, exact_matches=False)
-    else:
-      parser.error('Must provide at most one benchmark name.')
-
-  def Run(self, args):
-    # Set at least log info level for List command.
-    # TODO(nedn): remove this once crbug.com/656224 is resolved. The recipe
-    # should be change to use verbose logging instead.
-    logging.getLogger().setLevel(logging.INFO)
-    possible_browser = browser_finder.FindBrowser(args)
-    if args.browser_type in (
-        'release', 'release_x64', 'debug', 'debug_x64', 'canary',
-        'android-chromium', 'android-chrome'):
-      args.browser_type = 'reference'
-      possible_reference_browser = browser_finder.FindBrowser(args)
-    else:
-      possible_reference_browser = None
-    if args.json_output_file:
-      with open(args.json_output_file, 'w') as f:
-        f.write(_GetJsonBenchmarkList(possible_browser,
-                                      possible_reference_browser,
-                                      args.benchmarks, args.num_shards))
-    else:
-      PrintBenchmarkList(args.benchmarks, possible_browser)
-    return 0
-
-
-class Run(command_line.OptparseCommand):
-  """Run one or more benchmarks (default)"""
-
-  usage = 'benchmark_name [page_set] [<options>]'
-
-  @classmethod
-  def CreateParser(cls):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser('%%prog %s %s' % (cls.Name(), cls.usage))
-    return parser
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser, environment):
-    benchmark.AddCommandLineArgs(parser)
-
-    # Allow benchmarks to add their own command line options.
-    matching_benchmarks = []
-    for arg in sys.argv[1:]:
-      matching_benchmarks += _MatchBenchmarkName(arg, environment)
-
-    if matching_benchmarks:
-      # TODO(dtu): After move to argparse, add command-line args for all
-      # benchmarks to subparser. Using subparsers will avoid duplicate
-      # arguments.
-      matching_benchmark = matching_benchmarks.pop()
-      matching_benchmark.AddCommandLineArgs(parser)
-      # The benchmark's options override the defaults!
-      matching_benchmark.SetArgumentDefaults(parser)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args, environment):
-    all_benchmarks = _Benchmarks(environment)
-    if not args.positional_args:
-      possible_browser = (
-          browser_finder.FindBrowser(args) if args.browser_type else None)
-      PrintBenchmarkList(all_benchmarks, possible_browser)
-      sys.exit(-1)
-
-    input_benchmark_name = args.positional_args[0]
-    matching_benchmarks = _MatchBenchmarkName(input_benchmark_name, environment)
-    if not matching_benchmarks:
-      print >> sys.stderr, 'No benchmark named "%s".' % input_benchmark_name
-      print >> sys.stderr
-      most_likely_matched_benchmarks = matching.GetMostLikelyMatchedObject(
-          all_benchmarks, input_benchmark_name, lambda x: x.Name())
-      if most_likely_matched_benchmarks:
-        print >> sys.stderr, 'Do you mean any of those benchmarks below?'
-        PrintBenchmarkList(most_likely_matched_benchmarks, None, sys.stderr)
-      sys.exit(-1)
-
-    if len(matching_benchmarks) > 1:
-      print >> sys.stderr, ('Multiple benchmarks named "%s".' %
-                            input_benchmark_name)
-      print >> sys.stderr, 'Did you mean one of these?'
-      print >> sys.stderr
-      PrintBenchmarkList(matching_benchmarks, None, sys.stderr)
-      sys.exit(-1)
-
-    benchmark_class = matching_benchmarks.pop()
-    if len(args.positional_args) > 1:
-      parser.error('Too many arguments.')
-
-    assert issubclass(benchmark_class, benchmark.Benchmark), (
-        'Trying to run a non-Benchmark?!')
-
-    benchmark.ProcessCommandLineArgs(parser, args)
-    benchmark_class.ProcessCommandLineArgs(parser, args)
-
-    cls._benchmark = benchmark_class
-
-  def Run(self, args):
-    return min(255, self._benchmark().Run(args))
-
-
-def _ScriptName():
-  return os.path.basename(sys.argv[0])
-
-
-def _MatchingCommands(string, commands):
-  return [command for command in commands
-         if command.Name().startswith(string)]
-
-@decorators.Cache
-def _Benchmarks(environment):
-  benchmarks = []
-  for search_dir in environment.benchmark_dirs:
-    benchmarks += discover.DiscoverClasses(search_dir,
-                                           environment.top_level_dir,
-                                           benchmark.Benchmark,
-                                           index_by_class_name=True).values()
-  return benchmarks
-
-def _MatchBenchmarkName(input_benchmark_name, environment, exact_matches=True):
-  def _Matches(input_string, search_string):
-    if search_string.startswith(input_string):
-      return True
-    for part in search_string.split('.'):
-      if part.startswith(input_string):
-        return True
-    return False
-
-  # Exact matching.
-  if exact_matches:
-    # Don't add aliases to search dict, only allow exact matching for them.
-    if input_benchmark_name in environment.benchmark_aliases:
-      exact_match = environment.benchmark_aliases[input_benchmark_name]
-    else:
-      exact_match = input_benchmark_name
-
-    for benchmark_class in _Benchmarks(environment):
-      if exact_match == benchmark_class.Name():
-        return [benchmark_class]
-    return []
-
-  # Fuzzy matching.
-  return [benchmark_class for benchmark_class in _Benchmarks(environment)
-          if _Matches(input_benchmark_name, benchmark_class.Name())]
-
-
-def GetBenchmarkByName(name, environment):
-  matched = _MatchBenchmarkName(name, environment, exact_matches=True)
-  # With exact_matches, len(matched) is either 0 or 1.
-  if len(matched) == 0:
-    return None
-  return matched[0]
-
-
-def _GetJsonBenchmarkList(possible_browser, possible_reference_browser,
-                          benchmark_classes, num_shards):
-  """Returns a list of all enabled benchmarks in a JSON format expected by
-  buildbots.
-
-  JSON format:
-  { "version": <int>,
-    "steps": {
-      <string>: {
-        "device_affinity": <int>,
-        "cmd": <string>,
-        "perf_dashboard_id": <string>,
-      },
-      ...
-    }
-  }
-  """
-  # TODO(charliea): Remove this once we have more power perf bots.
-  only_run_battor_benchmarks = False
-  print 'Environment variables: ', os.environ
-  if os.environ.get('BUILDBOT_BUILDERNAME') in GOOD_POWER_PERF_BOT_WHITELIST:
-    only_run_battor_benchmarks = True
-
-  output = {
-    'version': 1,
-    'steps': {
-    }
-  }
-  for benchmark_class in benchmark_classes:
-    if not _IsBenchmarkEnabled(benchmark_class, possible_browser):
-      continue
-
-    base_name = benchmark_class.Name()
-    # TODO(charliea): Remove this once we have more power perf bots.
-    # Only run battor power benchmarks to reduce the cycle time of this bot.
-    # TODO(rnephew): Enable media.* and power.* tests when Mac BattOr issue
-    # is solved.
-    if only_run_battor_benchmarks and not base_name.startswith('battor'):
-      continue
-    base_cmd = [sys.executable, os.path.realpath(sys.argv[0]),
-                '-v', '--output-format=chartjson', '--upload-results',
-                base_name]
-    perf_dashboard_id = base_name
-
-    device_affinity = bot_utils.GetDeviceAffinity(num_shards, base_name)
-
-    output['steps'][base_name] = {
-      'cmd': ' '.join(base_cmd + [
-            '--browser=%s' % possible_browser.browser_type]),
-      'device_affinity': device_affinity,
-      'perf_dashboard_id': perf_dashboard_id,
-    }
-    if (possible_reference_browser and
-        _IsBenchmarkEnabled(benchmark_class, possible_reference_browser)):
-      output['steps'][base_name + '.reference'] = {
-        'cmd': ' '.join(base_cmd + [
-              '--browser=reference', '--output-trace-tag=_ref']),
-        'device_affinity': device_affinity,
-        'perf_dashboard_id': perf_dashboard_id,
-      }
-
-  return json.dumps(output, indent=2, sort_keys=True)
-
-
-def main(environment, extra_commands=None, **log_config_kwargs):
-  # The log level is set in browser_options.
-  log_config_kwargs.pop('level', None)
-  log_config_kwargs.setdefault('format', DEFAULT_LOG_FORMAT)
-  logging.basicConfig(**log_config_kwargs)
-
-  ps_util.EnableListingStrayProcessesUponExitHook()
-
-  # Get the command name from the command line.
-  if len(sys.argv) > 1 and sys.argv[1] == '--help':
-    sys.argv[1] = 'help'
-
-  command_name = 'run'
-  for arg in sys.argv[1:]:
-    if not arg.startswith('-'):
-      command_name = arg
-      break
-
-  # TODO(eakuefner): Remove this hack after we port to argparse.
-  if command_name == 'help' and len(sys.argv) > 2 and sys.argv[2] == 'run':
-    command_name = 'run'
-    sys.argv[2] = '--help'
-
-  if extra_commands is None:
-    extra_commands = []
-  all_commands = [Help, List, Run] + extra_commands
-
-  # Validate and interpret the command name.
-  commands = _MatchingCommands(command_name, all_commands)
-  if len(commands) > 1:
-    print >> sys.stderr, ('"%s" is not a %s command. Did you mean one of these?'
-                          % (command_name, _ScriptName()))
-    for command in commands:
-      print >> sys.stderr, '  %-10s %s' % (
-          command.Name(), command.Description())
-    return 1
-  if commands:
-    command = commands[0]
-  else:
-    command = Run
-
-  binary_manager.InitDependencyManager(environment.client_configs)
-
-  # Parse and run the command.
-  parser = command.CreateParser()
-  command.AddCommandLineArgs(parser, environment)
-
-  # Set the default chrome root variable.
-  parser.set_defaults(chrome_root=environment.default_chrome_root)
-
-
-  if isinstance(parser, argparse.ArgumentParser):
-    commandline_args = sys.argv[1:]
-    options, args = parser.parse_known_args(commandline_args[1:])
-    command.ProcessCommandLineArgs(parser, options, args, environment)
-  else:
-    options, args = parser.parse_args()
-    if commands:
-      args = args[1:]
-    options.positional_args = args
-    command.ProcessCommandLineArgs(parser, options, environment)
-
-  if command == Help:
-    command_instance = command(all_commands)
-  else:
-    command_instance = command()
-  if isinstance(command_instance, command_line.OptparseCommand):
-    return command_instance.Run(options)
-  else:
-    return command_instance.Run(options, args)
diff --git a/catapult/telemetry/telemetry/benchmark_runner_unittest.py b/catapult/telemetry/telemetry/benchmark_runner_unittest.py
deleted file mode 100644
index 618b6d5..0000000
--- a/catapult/telemetry/telemetry/benchmark_runner_unittest.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import benchmark
-from telemetry import benchmark_runner
-from telemetry.testing import stream
-import mock
-
-
-class BenchmarkFoo(benchmark.Benchmark):
-  """ Benchmark Foo for testing."""
-
-  @classmethod
-  def Name(cls):
-    return 'FooBenchmark'
-
-
-class BenchmarkBar(benchmark.Benchmark):
-  """ Benchmark Bar for testing long description line."""
-
-  @classmethod
-  def Name(cls):
-    return 'BarBenchmarkkkkk'
-
-class UnusualBenchmark(benchmark.Benchmark):
-  @classmethod
-  def Name(cls):
-    return 'I have a very unusual name'
-
-
-class BenchmarkRunnerUnittest(unittest.TestCase):
-  def setUp(self):
-    self._stream = stream.TestOutputStream()
-    self._mock_possible_browser = mock.MagicMock()
-    self._mock_possible_browser.browser_type = 'TestBrowser'
-
-  def testPrintBenchmarkListWithNoDisabledBenchmark(self):
-    expected_printed_stream = (
-        'Available benchmarks for TestBrowser are:\n'
-        '  BarBenchmarkkkkk  Benchmark Bar for testing long description line.\n'
-        '  FooBenchmark      Benchmark Foo for testing.\n'
-        'Pass --browser to list benchmarks for another browser.\n\n')
-    with mock.patch('telemetry.benchmark_runner.decorators') as mock_module:
-      mock_module.IsEnabled.return_value = (True, None)
-      benchmark_runner.PrintBenchmarkList(
-        [BenchmarkFoo, BenchmarkBar], self._mock_possible_browser, self._stream)
-      self.assertEquals(expected_printed_stream, self._stream.output_data)
-
-  def testPrintBenchmarkListWithOneDisabledBenchmark(self):
-    expected_printed_stream = (
-        'Available benchmarks for TestBrowser are:\n'
-        '  FooBenchmark      Benchmark Foo for testing.\n'
-        '\n'
-        'Disabled benchmarks for TestBrowser are (force run with -d):\n'
-        '  BarBenchmarkkkkk  Benchmark Bar for testing long description line.\n'
-        'Pass --browser to list benchmarks for another browser.\n\n')
-    with mock.patch('telemetry.benchmark_runner.decorators') as mock_module:
-      def FakeIsEnabled(benchmark_class, _):
-        if benchmark_class is BenchmarkFoo:
-          return True
-        else:
-          return False
-
-      mock_module.IsBenchmarkEnabled = FakeIsEnabled
-      benchmark_runner.PrintBenchmarkList(
-        [BenchmarkFoo, BenchmarkBar], self._mock_possible_browser, self._stream)
-      self.assertEquals(expected_printed_stream, self._stream.output_data)
-
-  def testShouldDisable(self):
-    """Ensure that overridden ShouldDisable class methods are respected."""
-    expected_printed_stream = (
-        'Available benchmarks for TestBrowser are:\n'
-        '  BarBenchmarkkkkk  Benchmark Bar for testing long description line.\n'
-        '\n'
-        'Disabled benchmarks for TestBrowser are (force run with -d):\n'
-        '  FooBenchmark      Benchmark Foo for testing.\n'
-        'Pass --browser to list benchmarks for another browser.\n\n')
-    @classmethod
-    def FakeShouldDisable(cls, possible_browser):
-      del possible_browser  # unused
-      return cls is BenchmarkFoo
-    BenchmarkFoo.ShouldDisable = FakeShouldDisable
-    BenchmarkBar.ShouldDisable = FakeShouldDisable
-    benchmark_runner.PrintBenchmarkList(
-      [BenchmarkFoo, BenchmarkBar], self._mock_possible_browser, self._stream)
-    self.assertEquals(expected_printed_stream, self._stream.output_data)
-
-  def testShouldDisableComplex(self):
-    """Ensure that browser-dependent ShouldDisable overrides are respected."""
-    expected_printed_stream = (
-        # Expected output for 'TestBrowser':
-        'Available benchmarks for TestBrowser are:\n'
-        '  FooBenchmark      Benchmark Foo for testing.\n'
-        '\n'
-        'Disabled benchmarks for TestBrowser are (force run with -d):\n'
-        '  BarBenchmarkkkkk  Benchmark Bar for testing long description line.\n'
-        'Pass --browser to list benchmarks for another browser.\n\n'
-        # Expected output for 'MockBrowser':
-        'Available benchmarks for MockBrowser are:\n'
-        '  BarBenchmarkkkkk  Benchmark Bar for testing long description line.\n'
-        '  FooBenchmark      Benchmark Foo for testing.\n'
-        'Pass --browser to list benchmarks for another browser.\n\n')
-    @classmethod
-    def FakeShouldDisable(cls, possible_browser):
-      return cls is BenchmarkBar and not 'Mock' in possible_browser.browser_type
-    BenchmarkFoo.ShouldDisable = FakeShouldDisable
-    BenchmarkBar.ShouldDisable = FakeShouldDisable
-    benchmark_runner.PrintBenchmarkList(
-      [BenchmarkFoo, BenchmarkBar], self._mock_possible_browser, self._stream)
-    self._mock_possible_browser.browser_type = 'MockBrowser'
-    benchmark_runner.PrintBenchmarkList(
-      [BenchmarkFoo, BenchmarkBar], self._mock_possible_browser, self._stream)
-    self.assertEquals(expected_printed_stream, self._stream.output_data)
diff --git a/catapult/telemetry/telemetry/benchmark_unittest.py b/catapult/telemetry/telemetry/benchmark_unittest.py
deleted file mode 100644
index cb23c6f..0000000
--- a/catapult/telemetry/telemetry/benchmark_unittest.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-import unittest
-
-from telemetry import android
-from telemetry import benchmark
-from telemetry.testing import options_for_unittests
-from telemetry.internal import story_runner
-from telemetry import page
-from telemetry.page import legacy_page_test
-from telemetry.page import shared_page_state
-from telemetry import story as story_module
-from telemetry.web_perf import timeline_based_measurement
-
-
-class DummyPageTest(legacy_page_test.LegacyPageTest):
-  def ValidateAndMeasurePage(self, *_):
-    pass
-
-
-class TestBenchmark(benchmark.Benchmark):
-  def __init__(self, story):
-    super(TestBenchmark, self).__init__()
-    self._story_set = story_module.StorySet()
-    self._story_set.AddStory(story)
-
-  def CreatePageTest(self, _):
-    return DummyPageTest()
-
-  def CreateStorySet(self, _):
-    return self._story_set
-
-
-class BenchmarkTest(unittest.TestCase):
-
-  def testPageTestWithIncompatibleStory(self):
-    b = TestBenchmark(story_module.Story(
-        shared_state_class=shared_page_state.SharedPageState))
-    with self.assertRaisesRegexp(
-        Exception, 'containing only telemetry.page.Page stories'):
-      b.Run(options_for_unittests.GetCopy())
-
-    state_class = story_module.SharedState
-    b = TestBenchmark(story_module.Story(
-        shared_state_class=state_class))
-    with self.assertRaisesRegexp(
-        Exception, 'containing only telemetry.page.Page stories'):
-      b.Run(options_for_unittests.GetCopy())
-
-    b = TestBenchmark(android.AndroidStory(start_intent=None))
-    with self.assertRaisesRegexp(
-        Exception, 'containing only telemetry.page.Page stories'):
-      b.Run(options_for_unittests.GetCopy())
-
-  def testPageTestWithCompatibleStory(self):
-    original_run_fn = story_runner.Run
-    was_run = [False]
-    def RunStub(*arg, **kwargs):
-      del arg, kwargs
-      was_run[0] = True
-    story_runner.Run = RunStub
-
-    try:
-      options = options_for_unittests.GetCopy()
-      options.output_formats = ['none']
-      options.suppress_gtest_report = True
-      parser = optparse.OptionParser()
-      benchmark.AddCommandLineArgs(parser)
-      options.MergeDefaultValues(parser.get_default_values())
-
-      b = TestBenchmark(page.Page(url='about:blank'))
-      b.Run(options)
-    finally:
-      story_runner.Run = original_run_fn
-
-    self.assertTrue(was_run[0])
-
-  def testOverriddenTbmOptionsAndPageTestRaises(self):
-    class FakeTimelineBasedMeasurementOptions(object):
-      pass
-
-    class OverrideBothBenchmark(benchmark.Benchmark):
-      def CreatePageTest(self, _):
-        return DummyPageTest()
-      def CreateTimelineBasedMeasurementOptions(self):
-        return FakeTimelineBasedMeasurementOptions()
-
-    assertion_regex = (
-        'Cannot override both CreatePageTest and '
-        'CreateTimelineBasedMeasurementOptions')
-    with self.assertRaisesRegexp(AssertionError, assertion_regex):
-      OverrideBothBenchmark()
-
-  def testBenchmarkMakesTbmTestByDefault(self):
-    class DefaultTbmBenchmark(benchmark.Benchmark):
-      pass
-
-    self.assertIsInstance(
-        DefaultTbmBenchmark().CreatePageTest(options=None),
-        timeline_based_measurement.TimelineBasedMeasurement)
-
-  def testUnknownTestTypeRaises(self):
-    class UnknownTestType(object):
-      pass
-    class UnknownTestTypeBenchmark(benchmark.Benchmark):
-      test = UnknownTestType
-
-    type_error_regex = (
-        '"UnknownTestType" is not a PageTest or a TimelineBasedMeasurement')
-    with self.assertRaisesRegexp(TypeError, type_error_regex):
-      UnknownTestTypeBenchmark().CreatePageTest(options=None)
-
-  def testOverriddenTbmOptionsAndPageTestTestAttributeRaises(self):
-    class FakeTimelineBasedMeasurementOptions(object):
-      pass
-
-    class OverrideOptionsOnPageTestBenchmark(benchmark.Benchmark):
-      test = DummyPageTest
-      def CreateTimelineBasedMeasurementOptions(self):
-        return FakeTimelineBasedMeasurementOptions()
-
-    assertion_regex = (
-        'Cannot override CreateTimelineBasedMeasurementOptions '
-        'with a PageTest')
-    with self.assertRaisesRegexp(AssertionError, assertion_regex):
-      OverrideOptionsOnPageTestBenchmark().CreatePageTest(options=None)
-
-  def testBenchmarkPredicate(self):
-    class PredicateBenchmark(TestBenchmark):
-      @classmethod
-      def ValueCanBeAddedPredicate(cls, value, is_first_result):
-        return False
-
-    original_run_fn = story_runner.Run
-    validPredicate = [False]
-
-    def RunStub(test, story_set_module, finder_options, results,
-                *args, **kwargs): # pylint: disable=unused-argument
-      predicate = results._value_can_be_added_predicate
-      valid = predicate == PredicateBenchmark.ValueCanBeAddedPredicate
-      validPredicate[0] = valid
-
-    story_runner.Run = RunStub
-
-    try:
-      options = options_for_unittests.GetCopy()
-      options.output_formats = ['none']
-      options.suppress_gtest_report = True
-      parser = optparse.OptionParser()
-      benchmark.AddCommandLineArgs(parser)
-      options.MergeDefaultValues(parser.get_default_values())
-
-      b = PredicateBenchmark(page.Page(url='about:blank'))
-      b.Run(options)
-    finally:
-      story_runner.Run = original_run_fn
-
-    self.assertTrue(validPredicate[0])
diff --git a/catapult/telemetry/telemetry/core/__init__.py b/catapult/telemetry/telemetry/core/__init__.py
deleted file mode 100644
index efcc9c3..0000000
--- a/catapult/telemetry/telemetry/core/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/core/android_action_runner.py b/catapult/telemetry/telemetry/core/android_action_runner.py
deleted file mode 100644
index 07fdccb..0000000
--- a/catapult/telemetry/telemetry/core/android_action_runner.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-
-from devil.android.sdk import keyevent
-
-import py_utils
-
-
-class ActionNotSupported(Exception):
-  pass
-
-
-class AndroidActionRunner(object):
-  """Provides an API for interacting with an android device.
-
-  This makes use of functionality provided by the android input command. None
-  of the gestures here are guaranteed to be performant for telemetry tests and
-  there is no official support for this API.
-
-  TODO(ariblue): Replace this API with a better implementation for interacting
-  with native components.
-  """
-
-  def __init__(self, platform_backend):
-    self._platform_backend = platform_backend
-
-  def SmoothScrollBy(self, left_start_coord, top_start_coord, direction,
-                     scroll_distance):
-    """Perform gesture to scroll down on the android device.
-    """
-    if direction not in ['down', 'up', 'left', 'right']:
-      raise ActionNotSupported('Invalid scroll direction: %s' % direction)
-
-    # This velocity is slower so that the exact distance we specify is the
-    # distance the page travels.
-    duration = scroll_distance
-
-    # Note that the default behavior is swiping up for scrolling down.
-    if direction == 'down':
-      left_end_coord = left_start_coord
-      top_end_coord = top_start_coord - scroll_distance
-    elif direction == 'up':
-      left_end_coord = left_start_coord
-      top_end_coord = top_start_coord + scroll_distance
-    elif direction == 'right':
-      left_end_coord = left_start_coord - scroll_distance
-      top_end_coord = top_start_coord
-    elif direction == 'left':
-      left_end_coord = left_start_coord + scroll_distance
-      top_end_coord = top_start_coord
-
-    self.InputSwipe(left_start_coord, top_start_coord, left_end_coord,
-                    top_end_coord, duration)
-
-  def Wait(self, seconds):
-    """Wait for the number of seconds specified.
-
-    Args:
-      seconds: The number of seconds to wait.
-    """
-    time.sleep(seconds)
-
-  def InputText(self, string):
-    """Convert the characters of the string into key events and send to device.
-
-    Args:
-      string: The string to send to the device.
-    """
-    self._platform_backend.device.RunShellCommand(
-        ['input', 'text', string], check_return=True)
-
-  def InputKeyEvent(self, keycode):
-    """Send a single key input to the device.
-
-    See the devil.android.sdk.keyevent module for suitable keycode values.
-
-    Args:
-      keycode: A key code number that will be sent to the device.
-    """
-    self._platform_backend.device.SendKeyEvent(keycode)
-
-  def InputTap(self, x_coord, y_coord):
-    """Perform a tap input at the given coordinates.
-
-    Args:
-      x_coord: The x coordinate of the tap event.
-      y_coord: The y coordinate of the tap event.
-    """
-    self._platform_backend.device.RunShellCommand(
-        ['input', 'tap', str(x_coord), str(y_coord)], check_return=True)
-
-  def InputSwipe(self, left_start_coord, top_start_coord, left_end_coord,
-                 top_end_coord, duration):
-    """Perform a swipe input.
-
-    Args:
-      left_start_coord: The horizontal starting coordinate of the gesture
-      top_start_coord: The vertical starting coordinate of the gesture
-      left_end_coord: The horizontal ending coordinate of the gesture
-      top_end_coord: The vertical ending coordinate of the gesture
-      duration: The length of time of the swipe in milliseconds
-    """
-    cmd = ['input', 'swipe']
-    cmd.expand(str(x) for x in (left_start_coord, top_start_coord,
-                                left_end_coord, top_end_coord, duration))
-    self._platform_backend.device.RunShellCommand(cmd, check_return=True)
-
-  def InputPress(self):
-    """Perform a press input."""
-    self._platform_backend.device.RunShellCommand(
-        ['input', 'press'], check_return=True)
-
-  def InputRoll(self, dx, dy):
-    """Perform a roll input. This sends a simple zero-pressure move event.
-
-    Args:
-      dx: Change in the x coordinate due to move.
-      dy: Change in the y coordinate due to move.
-    """
-    self._platform_backend.device.RunShellCommand(
-        ['input', 'roll', str(dx), str(dy)], check_return=True)
-
-  def TurnScreenOn(self):
-    """If device screen is off, turn screen on.
-    If the screen is already on, log a warning and return immediately.
-
-    Raises:
-      Timeout: If the screen is off and device fails to turn screen on.
-    """
-    self._platform_backend.device.SetScreen(True)
-    py_utils.WaitFor(self._platform_backend.device.IsScreenOn, 5)
-
-  def TurnScreenOff(self):
-    """If device screen is on, turn screen off.
-    If the screen is already off, log a warning and return immediately.
-
-    Raises:
-      Timeout: If the screen is on and device fails to turn screen off.
-    """
-
-    def is_screen_off():
-      return not self._platform_backend.device.IsScreenOn()
-
-    self._platform_backend.device.SetScreen(False)
-    py_utils.WaitFor(is_screen_off, 5)
-
-  def UnlockScreen(self):
-    """If device screen is locked, unlocks it.
-    If the device is not locked, log a warning and return immediately.
-
-    Raises:
-      Timeout: If device fails to unlock screen.
-    """
-
-    def is_screen_unlocked():
-      return not self._platform_backend.IsScreenLocked()
-
-    if self._platform_backend.IsScreenLocked():
-      self.InputKeyEvent(keyevent.KEYCODE_MENU)
-    else:
-      logging.warning('Screen not locked when expected.')
-      return
-
-    py_utils.WaitFor(is_screen_unlocked, 5)
diff --git a/catapult/telemetry/telemetry/core/android_platform.py b/catapult/telemetry/telemetry/core/android_platform.py
deleted file mode 100644
index b2e7e84..0000000
--- a/catapult/telemetry/telemetry/core/android_platform.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import android_action_runner
-from telemetry.core import platform
-from telemetry.internal.app import android_app
-from telemetry.internal.backends import android_app_backend
-
-
-class AndroidPlatform(platform.Platform):
-
-  def __init__(self, platform_backend):
-    super(AndroidPlatform, self).__init__(platform_backend)
-    self._android_action_runner = android_action_runner.AndroidActionRunner(
-        platform_backend)
-
-  def Initialize(self):
-    self._platform_backend.Initialize()
-
-  @property
-  def android_action_runner(self):
-    return self._android_action_runner
-
-  @property
-  def system_ui(self):
-    """Returns an AppUi object to interact with Android's system UI.
-
-    See devil.android.app_ui for the documentation of the API provided.
-    """
-    return self._platform_backend.GetSystemUi()
-
-  def IsSvelte(self):
-    return self._platform_backend.IsSvelte()
-
-  def LaunchAndroidApplication(self,
-                               start_intent,
-                               is_app_ready_predicate=None,
-                               app_has_webviews=True):
-    """Launches an Android application given the intent.
-
-    Args:
-      start_intent: The intent to use to start the app.
-      is_app_ready_predicate: A predicate function to determine
-          whether the app is ready. This is a function that takes an
-          AndroidApp instance and return a boolean. When it is not passed in,
-          the app is ready when the intent to launch it is completed.
-      app_has_webviews: A boolean indicating whether the app is expected to
-          contain any WebViews. If True, the app will be launched with
-          appropriate webview flags, and the GetWebViews method of the returned
-          object may be used to access them.
-
-    Returns:
-      A reference to the android_app launched.
-    """
-    self._platform_backend.DismissCrashDialogIfNeeded()
-    app_backend = android_app_backend.AndroidAppBackend(
-        self._platform_backend, start_intent, is_app_ready_predicate,
-        app_has_webviews)
-    return android_app.AndroidApp(app_backend, self._platform_backend)
diff --git a/catapult/telemetry/telemetry/core/cros_interface.py b/catapult/telemetry/telemetry/core/cros_interface.py
deleted file mode 100644
index bf98d3f..0000000
--- a/catapult/telemetry/telemetry/core/cros_interface.py
+++ /dev/null
@@ -1,570 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""A wrapper around ssh for common operations on a CrOS-based device"""
-import logging
-import os
-import re
-import shutil
-import stat
-import subprocess
-import tempfile
-
-# Some developers' workflow includes running the Chrome process from
-# /usr/local/... instead of the default location. We have to check for both
-# paths in order to support this workflow.
-_CHROME_PROCESS_REGEX = [re.compile(r'^/opt/google/chrome/chrome '),
-                         re.compile(r'^/usr/local/?.*/chrome/chrome ')]
-
-
-def RunCmd(args, cwd=None, quiet=False):
-  """Opens a subprocess to execute a program and returns its return value.
-
-  Args:
-    args: A string or a sequence of program arguments. The program to execute is
-      the string or the first item in the args sequence.
-    cwd: If not None, the subprocess's current directory will be changed to
-      |cwd| before it's executed.
-
-  Returns:
-    Return code from the command execution.
-  """
-  if not quiet:
-    logging.debug(' '.join(args) + ' ' + (cwd or ''))
-  with open(os.devnull, 'w') as devnull:
-    p = subprocess.Popen(args=args,
-                         cwd=cwd,
-                         stdout=devnull,
-                         stderr=devnull,
-                         stdin=devnull,
-                         shell=False)
-    return p.wait()
-
-
-def GetAllCmdOutput(args, cwd=None, quiet=False):
-  """Open a subprocess to execute a program and returns its output.
-
-  Args:
-    args: A string or a sequence of program arguments. The program to execute is
-      the string or the first item in the args sequence.
-    cwd: If not None, the subprocess's current directory will be changed to
-      |cwd| before it's executed.
-
-  Returns:
-    Captures and returns the command's stdout.
-    Prints the command's stderr to logger (which defaults to stdout).
-  """
-  if not quiet:
-    logging.debug(' '.join(args) + ' ' + (cwd or ''))
-  with open(os.devnull, 'w') as devnull:
-    p = subprocess.Popen(args=args,
-                         cwd=cwd,
-                         stdout=subprocess.PIPE,
-                         stderr=subprocess.PIPE,
-                         stdin=devnull)
-    stdout, stderr = p.communicate()
-    if not quiet:
-      logging.debug(' > stdout=[%s], stderr=[%s]', stdout, stderr)
-    return stdout, stderr
-
-
-def HasSSH():
-  try:
-    RunCmd(['ssh'], quiet=True)
-    RunCmd(['scp'], quiet=True)
-    logging.debug("HasSSH()->True")
-    return True
-  except OSError:
-    logging.debug("HasSSH()->False")
-    return False
-
-
-class LoginException(Exception):
-  pass
-
-
-class KeylessLoginRequiredException(LoginException):
-  pass
-
-
-class DNSFailureException(LoginException):
-  pass
-
-
-class CrOSInterface(object):
-
-  def __init__(self, hostname=None, ssh_port=None, ssh_identity=None):
-    self._hostname = hostname
-    self._ssh_port = ssh_port
-
-    # List of ports generated from GetRemotePort() that may not be in use yet.
-    self._reserved_ports = []
-
-    if self.local:
-      return
-
-    self._ssh_identity = None
-    self._ssh_args = ['-o ConnectTimeout=5', '-o StrictHostKeyChecking=no',
-                      '-o KbdInteractiveAuthentication=no',
-                      '-o PreferredAuthentications=publickey',
-                      '-o UserKnownHostsFile=/dev/null', '-o ControlMaster=no']
-
-    if ssh_identity:
-      self._ssh_identity = os.path.abspath(os.path.expanduser(ssh_identity))
-      os.chmod(self._ssh_identity, stat.S_IREAD)
-
-    # Establish master SSH connection using ControlPersist.
-    # Since only one test will be run on a remote host at a time,
-    # the control socket filename can be telemetry@hostname.
-    self._ssh_control_file = '/tmp/' + 'telemetry' + '@' + hostname
-    with open(os.devnull, 'w') as devnull:
-      subprocess.call(
-          self.FormSSHCommandLine(['-M', '-o ControlPersist=yes']),
-          stdin=devnull,
-          stdout=devnull,
-          stderr=devnull)
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, *args):
-    self.CloseConnection()
-
-  @property
-  def local(self):
-    return not self._hostname
-
-  @property
-  def hostname(self):
-    return self._hostname
-
-  @property
-  def ssh_port(self):
-    return self._ssh_port
-
-  def FormSSHCommandLine(self, args, extra_ssh_args=None):
-    """Constructs a subprocess-suitable command line for `ssh'.
-    """
-    if self.local:
-      # We run the command through the shell locally for consistency with
-      # how commands are run through SSH (crbug.com/239161). This work
-      # around will be unnecessary once we implement a persistent SSH
-      # connection to run remote commands (crbug.com/239607).
-      return ['sh', '-c', " ".join(args)]
-
-    full_args = ['ssh', '-o ForwardX11=no', '-o ForwardX11Trusted=no', '-n',
-                 '-S', self._ssh_control_file] + self._ssh_args
-    if self._ssh_identity is not None:
-      full_args.extend(['-i', self._ssh_identity])
-    if extra_ssh_args:
-      full_args.extend(extra_ssh_args)
-    full_args.append('root@%s' % self._hostname)
-    full_args.append('-p%d' % self._ssh_port)
-    full_args.extend(args)
-    return full_args
-
-  def _FormSCPCommandLine(self, src, dst, extra_scp_args=None):
-    """Constructs a subprocess-suitable command line for `scp'.
-
-    Note: this function is not designed to work with IPv6 addresses, which need
-    to have their addresses enclosed in brackets and a '-6' flag supplied
-    in order to be properly parsed by `scp'.
-    """
-    assert not self.local, "Cannot use SCP on local target."
-
-    args = ['scp', '-P', str(self._ssh_port)] + self._ssh_args
-    if self._ssh_identity:
-      args.extend(['-i', self._ssh_identity])
-    if extra_scp_args:
-      args.extend(extra_scp_args)
-    args += [src, dst]
-    return args
-
-  def _FormSCPToRemote(self,
-                       source,
-                       remote_dest,
-                       extra_scp_args=None,
-                       user='root'):
-    return self._FormSCPCommandLine(source,
-                                    '%s@%s:%s' % (user, self._hostname,
-                                                  remote_dest),
-                                    extra_scp_args=extra_scp_args)
-
-  def _FormSCPFromRemote(self,
-                         remote_source,
-                         dest,
-                         extra_scp_args=None,
-                         user='root'):
-    return self._FormSCPCommandLine('%s@%s:%s' % (user, self._hostname,
-                                                  remote_source),
-                                    dest,
-                                    extra_scp_args=extra_scp_args)
-
-  def _RemoveSSHWarnings(self, toClean):
-    """Removes specific ssh warning lines from a string.
-
-    Args:
-      toClean: A string that may be containing multiple lines.
-
-    Returns:
-      A copy of toClean with all the Warning lines removed.
-    """
-    # Remove the Warning about connecting to a new host for the first time.
-    return re.sub(
-        r'Warning: Permanently added [^\n]* to the list of known hosts.\s\n',
-        '', toClean)
-
-  def RunCmdOnDevice(self, args, cwd=None, quiet=False):
-    stdout, stderr = GetAllCmdOutput(
-        self.FormSSHCommandLine(args),
-        cwd,
-        quiet=quiet)
-    # The initial login will add the host to the hosts file but will also print
-    # a warning to stderr that we need to remove.
-    stderr = self._RemoveSSHWarnings(stderr)
-    return stdout, stderr
-
-  def TryLogin(self):
-    logging.debug('TryLogin()')
-    assert not self.local
-    stdout, stderr = self.RunCmdOnDevice(['echo', '$USER'], quiet=True)
-    if stderr != '':
-      if 'Host key verification failed' in stderr:
-        raise LoginException(('%s host key verification failed. ' +
-                              'SSH to it manually to fix connectivity.') %
-                             self._hostname)
-      if 'Operation timed out' in stderr:
-        raise LoginException('Timed out while logging into %s' % self._hostname)
-      if 'UNPROTECTED PRIVATE KEY FILE!' in stderr:
-        raise LoginException('Permissions for %s are too open. To fix this,\n'
-                             'chmod 600 %s' % (self._ssh_identity,
-                                               self._ssh_identity))
-      if 'Permission denied (publickey,keyboard-interactive)' in stderr:
-        raise KeylessLoginRequiredException('Need to set up ssh auth for %s' %
-                                            self._hostname)
-      if 'Could not resolve hostname' in stderr:
-        raise DNSFailureException('Unable to resolve the hostname for: %s' %
-                                  self._hostname)
-      raise LoginException('While logging into %s, got %s' % (self._hostname,
-                                                              stderr))
-    if stdout != 'root\n':
-      raise LoginException('Logged into %s, expected $USER=root, but got %s.' %
-                           (self._hostname, stdout))
-
-  def FileExistsOnDevice(self, file_name):
-    if self.local:
-      return os.path.exists(file_name)
-
-    stdout, stderr = self.RunCmdOnDevice(
-        [
-            'if', 'test', '-e', file_name, ';', 'then', 'echo', '1', ';', 'fi'
-        ],
-        quiet=True)
-    if stderr != '':
-      if "Connection timed out" in stderr:
-        raise OSError('Machine wasn\'t responding to ssh: %s' % stderr)
-      raise OSError('Unexpected error: %s' % stderr)
-    exists = stdout == '1\n'
-    logging.debug("FileExistsOnDevice(<text>, %s)->%s" % (file_name, exists))
-    return exists
-
-  def PushFile(self, filename, remote_filename):
-    if self.local:
-      args = ['cp', '-r', filename, remote_filename]
-      stdout, stderr = GetAllCmdOutput(args, quiet=True)
-      if stderr != '':
-        raise OSError('No such file or directory %s' % stderr)
-      return
-
-    args = self._FormSCPToRemote(
-        os.path.abspath(filename),
-        remote_filename,
-        extra_scp_args=['-r'])
-
-    stdout, stderr = GetAllCmdOutput(args, quiet=True)
-    stderr = self._RemoveSSHWarnings(stderr)
-    if stderr != '':
-      raise OSError('No such file or directory %s' % stderr)
-
-  def PushContents(self, text, remote_filename):
-    logging.debug("PushContents(<text>, %s)" % remote_filename)
-    with tempfile.NamedTemporaryFile() as f:
-      f.write(text)
-      f.flush()
-      self.PushFile(f.name, remote_filename)
-
-  def GetFile(self, filename, destfile=None):
-    """Copies a local file |filename| to |destfile| on the device.
-
-    Args:
-      filename: The name of the local source file.
-      destfile: The name of the file to copy to, and if it is not specified
-        then it is the basename of the source file.
-
-    """
-    logging.debug("GetFile(%s, %s)" % (filename, destfile))
-    if self.local:
-      if destfile is not None and destfile != filename:
-        shutil.copyfile(filename, destfile)
-        return
-      else:
-        raise OSError('No such file or directory %s' % filename)
-
-    if destfile is None:
-      destfile = os.path.basename(filename)
-    args = self._FormSCPFromRemote(filename, os.path.abspath(destfile))
-
-    stdout, stderr = GetAllCmdOutput(args, quiet=True)
-    stderr = self._RemoveSSHWarnings(stderr)
-    if stderr != '':
-      raise OSError('No such file or directory %s' % stderr)
-
-  def GetFileContents(self, filename):
-    """Get the contents of a file on the device.
-
-    Args:
-      filename: The name of the file on the device.
-
-    Returns:
-      A string containing the contents of the file.
-    """
-    with tempfile.NamedTemporaryFile() as t:
-      self.GetFile(filename, t.name)
-      with open(t.name, 'r') as f2:
-        res = f2.read()
-        logging.debug("GetFileContents(%s)->%s" % (filename, res))
-        return res
-
-  def HasSystemd(self):
-    """Return True or False to indicate if systemd is used.
-
-    Note: This function checks to see if the 'systemctl' utilitary
-    is installed. This is only installed along with the systemd daemon.
-    """
-    _, stderr = self.RunCmdOnDevice(['systemctl'], quiet=True)
-    return stderr == ''
-
-  def ListProcesses(self):
-    """Returns (pid, cmd, ppid, state) of all processes on the device."""
-    stdout, stderr = self.RunCmdOnDevice(
-        [
-            '/bin/ps', '--no-headers', '-A', '-o', 'pid,ppid,args:4096,state'
-        ],
-        quiet=True)
-    assert stderr == '', stderr
-    procs = []
-    for l in stdout.split('\n'):
-      if l == '':
-        continue
-      m = re.match(r'^\s*(\d+)\s+(\d+)\s+(.+)\s+(.+)', l, re.DOTALL)
-      assert m
-      procs.append((int(m.group(1)), m.group(3).rstrip(), int(m.group(2)),
-                    m.group(4)))
-    logging.debug("ListProcesses(<predicate>)->[%i processes]" % len(procs))
-    return procs
-
-  def _GetSessionManagerPid(self, procs):
-    """Returns the pid of the session_manager process, given the list of
-    processes."""
-    for pid, process, _, _ in procs:
-      argv = process.split()
-      if argv and os.path.basename(argv[0]) == 'session_manager':
-        return pid
-    return None
-
-  def GetChromeProcess(self):
-    """Locates the the main chrome browser process.
-
-    Chrome on cros is usually in /opt/google/chrome, but could be in
-    /usr/local/ for developer workflows - debug chrome is too large to fit on
-    rootfs.
-
-    Chrome spawns multiple processes for renderers. pids wrap around after they
-    are exhausted so looking for the smallest pid is not always correct. We
-    locate the session_manager's pid, and look for the chrome process that's an
-    immediate child. This is the main browser process.
-    """
-    procs = self.ListProcesses()
-    session_manager_pid = self._GetSessionManagerPid(procs)
-    if not session_manager_pid:
-      return None
-
-    # Find the chrome process that is the child of the session_manager.
-    for pid, process, ppid, _ in procs:
-      if ppid != session_manager_pid:
-        continue
-      for regex in _CHROME_PROCESS_REGEX:
-        path_match = re.match(regex, process)
-        if path_match is not None:
-          return {'pid': pid, 'path': path_match.group(), 'args': process}
-    return None
-
-  def GetChromePid(self):
-    """Returns pid of main chrome browser process."""
-    result = self.GetChromeProcess()
-    if result and 'pid' in result:
-      return result['pid']
-    return None
-
-  def RmRF(self, filename):
-    logging.debug("rm -rf %s" % filename)
-    self.RunCmdOnDevice(['rm', '-rf', filename], quiet=True)
-
-  def Chown(self, filename):
-    self.RunCmdOnDevice(['chown', '-R', 'chronos:chronos', filename])
-
-  def KillAllMatching(self, predicate):
-    kills = ['kill', '-KILL']
-    for pid, cmd, _, _ in self.ListProcesses():
-      if predicate(cmd):
-        logging.info('Killing %s, pid %d' % cmd, pid)
-        kills.append(pid)
-    logging.debug("KillAllMatching(<predicate>)->%i" % (len(kills) - 2))
-    if len(kills) > 2:
-      self.RunCmdOnDevice(kills, quiet=True)
-    return len(kills) - 2
-
-  def IsServiceRunning(self, service_name):
-    """Check with the init daemon if the given service is running."""
-    if self.HasSystemd():
-      # Querying for the pid of the service will return 'MainPID=0' if
-      # the service is not running.
-      stdout, stderr = self.RunCmdOnDevice(
-          ['systemctl', 'show', '-p', 'MainPID', service_name], quiet=True)
-      running = int(stdout.split('=')[1]) != 0
-    else:
-      stdout, stderr = self.RunCmdOnDevice(['status', service_name], quiet=True)
-      running = 'running, process' in stdout
-    assert stderr == '', stderr
-    logging.debug("IsServiceRunning(%s)->%s" % (service_name, running))
-    return running
-
-  def GetRemotePort(self):
-    netstat = self.RunCmdOnDevice(['netstat', '-ant'])
-    netstat = netstat[0].split('\n')
-    ports_in_use = []
-
-    for line in netstat[2:]:
-      if not line:
-        continue
-      address_in_use = line.split()[3]
-      port_in_use = address_in_use.split(':')[-1]
-      ports_in_use.append(int(port_in_use))
-
-    ports_in_use.extend(self._reserved_ports)
-
-    new_port = sorted(ports_in_use)[-1] + 1
-    self._reserved_ports.append(new_port)
-
-    return new_port
-
-  def IsHTTPServerRunningOnPort(self, port):
-    wget_output = self.RunCmdOnDevice(['wget', 'localhost:%i' % (port), '-T1',
-                                       '-t1'])
-
-    if 'Connection refused' in wget_output[1]:
-      return False
-
-    return True
-
-  def _GetMountSourceAndTarget(self, path):
-    df_out, _ = self.RunCmdOnDevice(['/bin/df', '--output=source,target', path])
-    df_ary = df_out.split('\n')
-    # 3 lines for title, mount info, and empty line.
-    if len(df_ary) == 3:
-      line_ary = df_ary[1].split()
-      return line_ary if len(line_ary) == 2 else None
-    return None
-
-  def FilesystemMountedAt(self, path):
-    """Returns the filesystem mounted at |path|"""
-    mount_info = self._GetMountSourceAndTarget(path)
-    return mount_info[0] if mount_info else None
-
-  def CryptohomePath(self, user):
-    """Returns the cryptohome mount point for |user|."""
-    stdout, stderr = self.RunCmdOnDevice(['cryptohome-path', 'user', "'%s'" %
-                                          user])
-    if stderr != '':
-      raise OSError('cryptohome-path failed: %s' % stderr)
-    return stdout.rstrip()
-
-  def IsCryptohomeMounted(self, username, is_guest):
-    """Returns True iff |user|'s cryptohome is mounted."""
-    profile_path = self.CryptohomePath(username)
-    mount_info = self._GetMountSourceAndTarget(profile_path)
-    if mount_info:
-      # Checks if the filesytem at |profile_path| is mounted on |profile_path|
-      # itself. Before mounting cryptohome, it shows an upper directory (/home).
-      is_guestfs = (mount_info[0] == 'guestfs')
-      return is_guestfs == is_guest and mount_info[1] == profile_path
-    return False
-
-  def TakeScreenshot(self, file_path):
-    stdout, stderr = self.RunCmdOnDevice(
-        ['/usr/local/autotest/bin/screenshot.py', file_path])
-    return stdout == '' and stderr == ''
-
-  def TakeScreenshotWithPrefix(self, screenshot_prefix):
-    """Takes a screenshot, useful for debugging failures."""
-    # TODO(achuith): Find a better location for screenshots. Cros autotests
-    # upload everything in /var/log so use /var/log/screenshots for now.
-    SCREENSHOT_DIR = '/var/log/screenshots/'
-    SCREENSHOT_EXT = '.png'
-
-    self.RunCmdOnDevice(['mkdir', '-p', SCREENSHOT_DIR])
-    # Large number of screenshots can increase hardware lab bandwidth
-    # dramatically, so keep this number low. crbug.com/524814.
-    for i in xrange(2):
-      screenshot_file = ('%s%s-%d%s' %
-                         (SCREENSHOT_DIR, screenshot_prefix, i, SCREENSHOT_EXT))
-      if not self.FileExistsOnDevice(screenshot_file):
-        return self.TakeScreenshot(screenshot_file)
-    logging.warning('screenshot directory full.')
-    return False
-
-  def GetArchName(self):
-    return self.RunCmdOnDevice(['uname', '-m'])[0]
-
-  def IsRunningOnVM(self):
-    return self.RunCmdOnDevice(['crossystem', 'inside_vm'])[0] != '0'
-
-  def LsbReleaseValue(self, key, default):
-    """/etc/lsb-release is a file with key=value pairs."""
-    lines = self.GetFileContents('/etc/lsb-release').split('\n')
-    for l in lines:
-      m = re.match(r'([^=]*)=(.*)', l)
-      if m and m.group(1) == key:
-        return m.group(2)
-    return default
-
-  def GetDeviceTypeName(self):
-    """DEVICETYPE in /etc/lsb-release is CHROMEBOOK, CHROMEBIT, etc."""
-    return self.LsbReleaseValue(key='DEVICETYPE', default='CHROMEBOOK')
-
-  def RestartUI(self, clear_enterprise_policy):
-    logging.info('(Re)starting the ui (logs the user out)')
-    start_cmd = ['start', 'ui']
-    restart_cmd = ['restart', 'ui']
-    stop_cmd = ['stop', 'ui']
-    if self.HasSystemd():
-      start_cmd.insert(0, 'systemctl')
-      restart_cmd.insert(0, 'systemctl')
-      stop_cmd.insert(0, 'systemctl')
-    if clear_enterprise_policy:
-      self.RunCmdOnDevice(stop_cmd)
-      self.RmRF('/var/lib/whitelist/*')
-      self.RmRF(r'/home/chronos/Local\ State')
-
-    if self.IsServiceRunning('ui'):
-      self.RunCmdOnDevice(restart_cmd)
-    else:
-      self.RunCmdOnDevice(start_cmd)
-
-  def CloseConnection(self):
-    if not self.local:
-      with open(os.devnull, 'w') as devnull:
-        subprocess.call(
-            self.FormSSHCommandLine(['-O', 'exit', self._hostname]),
-            stdout=devnull,
-            stderr=devnull)
diff --git a/catapult/telemetry/telemetry/core/cros_interface_unittest.py b/catapult/telemetry/telemetry/core/cros_interface_unittest.py
deleted file mode 100644
index 268bd52..0000000
--- a/catapult/telemetry/telemetry/core/cros_interface_unittest.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO(nduca): Rewrite what some of these tests to use mocks instead of
-# actually talking to the device. This would improve our coverage quite
-# a bit.
-
-import socket
-import tempfile
-import unittest
-import mock
-
-from telemetry.core import cros_interface
-from telemetry import decorators
-from telemetry.internal import forwarders
-from telemetry.internal.forwarders import cros_forwarder
-from telemetry.testing import options_for_unittests
-
-
-class CrOSInterfaceTest(unittest.TestCase):
-
-  def _GetCRI(self):
-    remote = options_for_unittests.GetCopy().cros_remote
-    remote_ssh_port = options_for_unittests.GetCopy().cros_remote_ssh_port
-    return cros_interface.CrOSInterface(
-        remote, remote_ssh_port,
-        options_for_unittests.GetCopy().cros_ssh_identity)
-
-  @decorators.Enabled('chromeos')
-  def testPushContents(self):
-    with self._GetCRI() as cri:
-      tmp_file = '/tmp/testPushContents'
-      test_contents = 'hello world'
-      cri.RmRF(tmp_file)
-      cri.PushContents(test_contents, tmp_file)
-      contents = cri.GetFileContents(tmp_file)
-      self.assertEquals(contents, test_contents)
-
-  @decorators.Enabled('chromeos')
-  def testExists(self):
-    with self._GetCRI() as cri:
-      self.assertTrue(cri.FileExistsOnDevice('/proc/cpuinfo'))
-      self.assertTrue(cri.FileExistsOnDevice('/etc/passwd'))
-      self.assertFalse(cri.FileExistsOnDevice('/etc/sdlfsdjflskfjsflj'))
-
-  @decorators.Enabled('chromeos')
-  def testGetFileContents(self):
-    with self._GetCRI() as cri:
-      hosts = cri.GetFileContents('/etc/lsb-release')
-      self.assertTrue('CHROMEOS' in hosts)
-
-  @decorators.Enabled('chromeos')
-  def testGetFile(self):  # pylint: disable=no-self-use
-    with self._GetCRI() as cri:
-      f = tempfile.NamedTemporaryFile()
-      cri.GetFile('/etc/lsb-release', f.name)
-      with open(f.name, 'r') as f2:
-        res = f2.read()
-        self.assertTrue('CHROMEOS' in res)
-
-  @decorators.Enabled('chromeos')
-  def testGetFileNonExistent(self):
-    with self._GetCRI() as cri:
-      f = tempfile.NamedTemporaryFile()
-      cri.PushContents('testGetFileNonExistent', f.name)
-      cri.RmRF(f.name)
-      self.assertRaises(OSError, lambda: cri.GetFile(f.name))
-
-  @decorators.Enabled('chromeos')
-  def testIsServiceRunning(self):
-    with self._GetCRI() as cri:
-      self.assertTrue(cri.IsServiceRunning('openssh-server'))
-
-  # TODO(achuith): Fix this test. crbug.com/619767.
-  @decorators.Disabled('all')
-  def testGetRemotePortAndIsHTTPServerRunningOnPort(self):
-    with self._GetCRI() as cri:
-      # Create local server.
-      sock = socket.socket()
-      sock.bind(('', 0))
-      port = sock.getsockname()[1]
-      sock.listen(0)
-
-      # Get remote port and ensure that it was unused.
-      remote_port = cri.GetRemotePort()
-      self.assertFalse(cri.IsHTTPServerRunningOnPort(remote_port))
-
-      # Forward local server's port to remote device's remote_port.
-      forwarder = cros_forwarder.CrOsForwarderFactory(cri).Create(
-          forwarders.PortPairs(http=forwarders.PortPair(port, remote_port),
-                               https=None,
-                               dns=None))
-
-      # At this point, remote device should be able to connect to local server.
-      self.assertTrue(cri.IsHTTPServerRunningOnPort(remote_port))
-
-      # Next remote port shouldn't be the same as remote_port, since remote_port
-      # is now in use.
-      self.assertTrue(cri.GetRemotePort() != remote_port)
-
-      # Close forwarder and local server ports.
-      forwarder.Close()
-      sock.close()
-
-      # Device should no longer be able to connect to remote_port since it is no
-      # longer in use.
-      self.assertFalse(cri.IsHTTPServerRunningOnPort(remote_port))
-
-  @decorators.Enabled('chromeos')
-  def testGetRemotePortReservedPorts(self):
-    with self._GetCRI() as cri:
-      # Should return 2 separate ports even though the first one isn't
-      # technically being used yet.
-      remote_port_1 = cri.GetRemotePort()
-      remote_port_2 = cri.GetRemotePort()
-
-      self.assertTrue(remote_port_1 != remote_port_2)
-
-  # TODO(achuith): Doesn't work in VMs.
-  @decorators.Disabled('all')
-  def testTakeScreenshotWithPrefix(self):
-    with self._GetCRI() as cri:
-      def _Cleanup():
-        cri.RmRF('/var/log/screenshots/test-prefix*')
-
-      _Cleanup()
-      self.assertTrue(cri.TakeScreenshotWithPrefix('test-prefix'))
-      self.assertTrue(cri.FileExistsOnDevice(
-          '/var/log/screenshots/test-prefix-0.png'))
-      _Cleanup()
-
-  @decorators.Enabled('chromeos')
-  def testLsbReleaseValue(self):
-    with self._GetCRI() as cri:
-      build_num = cri.LsbReleaseValue('CHROMEOS_RELEASE_BUILD_NUMBER', None)
-      self.assertTrue(build_num.isdigit())
-      device_type = cri.GetDeviceTypeName()
-      self.assertTrue(device_type.isalpha())
-
-  @decorators.Enabled('chromeos')
-  def testEscapeCmdArguments(self):
-    """Commands and their arguments that are executed through the cros
-    interface should follow bash syntax. This test needs to run on remotely
-    and locally on the device to check for consistency.
-    """
-    options = options_for_unittests.GetCopy()
-    with cros_interface.CrOSInterface(options.cros_remote,
-                                      options.cros_remote_ssh_port,
-                                      options.cros_ssh_identity) as cri:
-
-      # Check arguments with no special characters
-      stdout, _ = cri.RunCmdOnDevice(['echo', '--arg1=value1', '--arg2=value2',
-                                      '--arg3="value3"'])
-      assert stdout.strip() == '--arg1=value1 --arg2=value2 --arg3=value3'
-
-      # Check argument with special characters escaped
-      stdout, _ = cri.RunCmdOnDevice(['echo', '--arg=A\\; echo \\"B\\"'])
-      assert stdout.strip() == '--arg=A; echo "B"'
-
-      # Check argument with special characters in quotes
-      stdout, _ = cri.RunCmdOnDevice(['echo', "--arg='$HOME;;$PATH'"])
-      assert stdout.strip() == "--arg=$HOME;;$PATH"
-
-  @decorators.Enabled('chromeos')
-  @mock.patch.object(cros_interface.CrOSInterface, 'RunCmdOnDevice')
-  def testTryLoginSuccess(self, mock_run_cmd):
-    mock_run_cmd.return_value = ('root\n', '')
-    cri = cros_interface.CrOSInterface(
-        "testhostname", 22, options_for_unittests.GetCopy().cros_ssh_identity)
-    cri.TryLogin()
-    mock_run_cmd.assert_called_once_with(['echo', '$USER'], quiet=True)
-
-  @decorators.Enabled('chromeos')
-  @mock.patch.object(cros_interface.CrOSInterface, 'RunCmdOnDevice')
-  def testTryLoginStderr(self, mock_run_cmd):
-    cri = cros_interface.CrOSInterface(
-        "testhostname", 22, options_for_unittests.GetCopy().cros_ssh_identity)
-
-    mock_run_cmd.return_value = ('', 'Host key verification failed')
-    self.assertRaises(cros_interface.LoginException, cri.TryLogin)
-    self.assertRaisesRegexp(cros_interface.LoginException,
-                            r'.*host key verification failed..*', cri.TryLogin)
-
-    mock_run_cmd.return_value = ('', 'Operation timed out')
-    self.assertRaisesRegexp(cros_interface.LoginException,
-                            r'Timed out while logging into.*', cri.TryLogin)
-
-    mock_run_cmd.return_value = ('', 'UNPROTECTED PRIVATE KEY FILE!')
-    self.assertRaisesRegexp(cros_interface.LoginException,
-                            r'Permissions for .* are too open. To fix this.*',
-                            cri.TryLogin)
-
-    mock_run_cmd.return_value = (
-        '', 'Permission denied (publickey,keyboard-interactive)')
-    self.assertRaisesRegexp(cros_interface.KeylessLoginRequiredException,
-                            r'Need to set up ssh auth for .*', cri.TryLogin)
-
-    mock_run_cmd.return_value = ('', 'Fallback error case')
-    self.assertRaisesRegexp(cros_interface.LoginException,
-                            r'While logging into .*, got .*', cri.TryLogin)
-
-    mock_run_cmd.return_value = ('', 'Could not resolve hostname')
-    self.assertRaisesRegexp(cros_interface.DNSFailureException,
-                            r'Unable to resolve the hostname for:.*',
-                            cri.TryLogin)
-
-  @decorators.Enabled('chromeos')
-  @mock.patch.object(cros_interface.CrOSInterface, 'RunCmdOnDevice')
-  def testTryLoginStdout(self, mock_run_cmd):
-    mock_run_cmd.return_value = ('notrooot', '')
-    cri = cros_interface.CrOSInterface(
-        "testhostname", 22, options_for_unittests.GetCopy().cros_ssh_identity)
-    self.assertRaisesRegexp(cros_interface.LoginException,
-                            r'Logged into .*, expected \$USER=root, but got .*',
-                            cri.TryLogin)
-
-  @decorators.Enabled('chromeos')
-  @mock.patch.object(cros_interface.CrOSInterface, 'RunCmdOnDevice')
-  def testIsCryptohomeMounted(self, mock_run_cmd):
-    # The device's mount state is checked by the command
-    #   /bin/df --someoption `cryptohome-path user $username`.
-    # The following mock replaces RunCmdOnDevice() to return mocked mount states
-    # from the command execution.
-    def mockRunCmdOnDevice(args):
-      if args[0] == 'cryptohome-path':
-        return ('/home/user/%s' % args[2], '')
-      elif args[0] == '/bin/df':
-        if 'unmount' in args[2]:
-          # For the user unmount@gmail.com, returns the unmounted state.
-          source, target = '/dev/sda1', '/home'
-        elif 'mount' in args[2]:
-          # For the user mount@gmail.com, returns the mounted state.
-          source, target = '/dev/sda1', args[2]
-        elif 'guest' in args[2]:
-          # For the user $guest, returns the guest-mounted state.
-          source, target = 'guestfs', args[2]
-        return ('Filesystem Mounted on\n%s %s\n' % (source, target), '')
-    mock_run_cmd.side_effect = mockRunCmdOnDevice
-
-    cri = cros_interface.CrOSInterface(
-        "testhostname", 22, options_for_unittests.GetCopy().cros_ssh_identity)
-    # Returns False if the user's cryptohome is not mounted.
-    self.assertFalse(cri.IsCryptohomeMounted('unmount@gmail.com', False))
-    # Returns True if the user's cryptohome is mounted.
-    self.assertTrue(cri.IsCryptohomeMounted('mount@gmail.com', False))
-    # Returns True if the guest cryptohome is mounted.
-    self.assertTrue(cri.IsCryptohomeMounted('$guest', True))
-    # Sanity check. Returns False if the |is_guest| parameter does not match
-    # with whether or not the user is really a guest.
-    self.assertFalse(cri.IsCryptohomeMounted('unmount@gmail.com', True))
-    self.assertFalse(cri.IsCryptohomeMounted('mount@gmail.com', True))
-    self.assertFalse(cri.IsCryptohomeMounted('$guest', False))
diff --git a/catapult/telemetry/telemetry/core/discover.py b/catapult/telemetry/telemetry/core/discover.py
deleted file mode 100644
index 7eb667c..0000000
--- a/catapult/telemetry/telemetry/core/discover.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import fnmatch
-import inspect
-import os
-import re
-import sys
-
-from telemetry.internal.util import camel_case
-from telemetry.internal.util import classes as classes_module
-
-
-def DiscoverModules(start_dir, top_level_dir, pattern='*'):
-  """Discover all modules in |start_dir| which match |pattern|.
-
-  Args:
-    start_dir: The directory to recursively search.
-    top_level_dir: The top level of the package, for importing.
-    pattern: Unix shell-style pattern for filtering the filenames to import.
-
-  Returns:
-    list of modules.
-  """
-  # start_dir and top_level_dir must be consistent with each other.
-  start_dir = os.path.realpath(start_dir)
-  top_level_dir = os.path.realpath(top_level_dir)
-
-  modules = []
-  sub_paths = list(os.walk(start_dir))
-  # We sort the directories & file paths to ensure a deterministic ordering when
-  # traversing |top_level_dir|.
-  sub_paths.sort(key=lambda paths_tuple: paths_tuple[0])
-  for dir_path, _, filenames in sub_paths:
-    # Sort the directories to walk recursively by the directory path.
-    filenames.sort()
-    for filename in filenames:
-      # Filter out unwanted filenames.
-      if filename.startswith('.') or filename.startswith('_'):
-        continue
-      if os.path.splitext(filename)[1] != '.py':
-        continue
-      if not fnmatch.fnmatch(filename, pattern):
-        continue
-
-      # Find the module.
-      module_rel_path = os.path.relpath(
-          os.path.join(dir_path, filename), top_level_dir)
-      module_name = re.sub(r'[/\\]', '.', os.path.splitext(module_rel_path)[0])
-
-      # Import the module.
-      try:
-        # Make sure that top_level_dir is the first path in the sys.path in case
-        # there are naming conflict in module parts.
-        original_sys_path = sys.path[:]
-        sys.path.insert(0, top_level_dir)
-        module = __import__(module_name, fromlist=[True])
-        modules.append(module)
-      finally:
-        sys.path = original_sys_path
-  return modules
-
-
-def AssertNoKeyConflicts(classes_by_key_1, classes_by_key_2):
-  for k in classes_by_key_1:
-    if k in classes_by_key_2:
-      assert classes_by_key_1[k] is classes_by_key_2[k], (
-          'Found conflicting classes for the same key: '
-          'key=%s, class_1=%s, class_2=%s' % (
-              k, classes_by_key_1[k], classes_by_key_2[k]))
-
-
-# TODO(dtu): Normalize all discoverable classes to have corresponding module
-# and class names, then always index by class name.
-def DiscoverClasses(start_dir,
-                    top_level_dir,
-                    base_class,
-                    pattern='*',
-                    index_by_class_name=True,
-                    directly_constructable=False):
-  """Discover all classes in |start_dir| which subclass |base_class|.
-
-  Base classes that contain subclasses are ignored by default.
-
-  Args:
-    start_dir: The directory to recursively search.
-    top_level_dir: The top level of the package, for importing.
-    base_class: The base class to search for.
-    pattern: Unix shell-style pattern for filtering the filenames to import.
-    index_by_class_name: If True, use class name converted to
-        lowercase_with_underscores instead of module name in return dict keys.
-    directly_constructable: If True, will only return classes that can be
-        constructed without arguments
-
-  Returns:
-    dict of {module_name: class} or {underscored_class_name: class}
-  """
-  modules = DiscoverModules(start_dir, top_level_dir, pattern)
-  classes = {}
-  for module in modules:
-    new_classes = DiscoverClassesInModule(
-        module, base_class, index_by_class_name, directly_constructable)
-    # TODO(nednguyen): we should remove index_by_class_name once
-    # benchmark_smoke_unittest in chromium/src/tools/perf no longer relied
-    # naming collisions to reduce the number of smoked benchmark tests.
-    # crbug.com/548652
-    if index_by_class_name:
-      AssertNoKeyConflicts(classes, new_classes)
-    classes = dict(classes.items() + new_classes.items())
-  return classes
-
-
-# TODO(nednguyen): we should remove index_by_class_name once
-# benchmark_smoke_unittest in chromium/src/tools/perf no longer relied
-# naming collisions to reduce the number of smoked benchmark tests.
-# crbug.com/548652
-def DiscoverClassesInModule(module,
-                            base_class,
-                            index_by_class_name=False,
-                            directly_constructable=False):
-  """Discover all classes in |module| which subclass |base_class|.
-
-  Base classes that contain subclasses are ignored by default.
-
-  Args:
-    module: The module to search.
-    base_class: The base class to search for.
-    index_by_class_name: If True, use class name converted to
-        lowercase_with_underscores instead of module name in return dict keys.
-
-  Returns:
-    dict of {module_name: class} or {underscored_class_name: class}
-  """
-  classes = {}
-  for _, obj in inspect.getmembers(module):
-    # Ensure object is a class.
-    if not inspect.isclass(obj):
-      continue
-    # Include only subclasses of base_class.
-    if not issubclass(obj, base_class):
-      continue
-    # Exclude the base_class itself.
-    if obj is base_class:
-      continue
-    # Exclude protected or private classes.
-    if obj.__name__.startswith('_'):
-      continue
-    # Include only the module in which the class is defined.
-    # If a class is imported by another module, exclude those duplicates.
-    if obj.__module__ != module.__name__:
-      continue
-
-    if index_by_class_name:
-      key_name = camel_case.ToUnderscore(obj.__name__)
-    else:
-      key_name = module.__name__.split('.')[-1]
-    if (not directly_constructable or
-        classes_module.IsDirectlyConstructable(obj)):
-      if key_name in classes and index_by_class_name:
-        assert classes[key_name] is obj, (
-          'Duplicate key_name with different objs detected: '
-          'key=%s, obj1=%s, obj2=%s' % (key_name, classes[key_name], obj))
-      else:
-        classes[key_name] = obj
-
-  return classes
-
-
-_counter = [0]
-
-
-def _GetUniqueModuleName():
-  _counter[0] += 1
-  return "module_" + str(_counter[0])
diff --git a/catapult/telemetry/telemetry/core/discover_unittest.py b/catapult/telemetry/telemetry/core/discover_unittest.py
deleted file mode 100644
index bb6785c..0000000
--- a/catapult/telemetry/telemetry/core/discover_unittest.py
+++ /dev/null
@@ -1,109 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import unittest
-
-from telemetry.core import discover
-from telemetry.core import util
-
-
-class DiscoverTest(unittest.TestCase):
-
-  def setUp(self):
-    self._base_dir = util.GetUnittestDataDir()
-    self._start_dir = os.path.join(self._base_dir, 'discoverable_classes')
-    self._base_class = Exception
-
-  def testDiscoverClassesWithIndexByModuleName(self):
-    classes = discover.DiscoverClasses(self._start_dir,
-                                       self._base_dir,
-                                       self._base_class,
-                                       index_by_class_name=False)
-
-    actual_classes = dict((name, cls.__name__)
-                          for name, cls in classes.iteritems())
-    expected_classes = {
-        'another_discover_dummyclass': 'DummyExceptionWithParameterImpl1',
-        'discover_dummyclass': 'DummyException',
-        'parameter_discover_dummyclass': 'DummyExceptionWithParameterImpl2'
-    }
-    self.assertEqual(actual_classes, expected_classes)
-
-  def testDiscoverDirectlyConstructableClassesWithIndexByClassName(self):
-    classes = discover.DiscoverClasses(self._start_dir,
-                                       self._base_dir,
-                                       self._base_class,
-                                       directly_constructable=True)
-
-    actual_classes = dict((name, cls.__name__)
-                          for name, cls in classes.iteritems())
-    expected_classes = {
-        'dummy_exception': 'DummyException',
-        'dummy_exception_impl1': 'DummyExceptionImpl1',
-        'dummy_exception_impl2': 'DummyExceptionImpl2',
-    }
-    self.assertEqual(actual_classes, expected_classes)
-
-  def testDiscoverClassesWithIndexByClassName(self):
-    classes = discover.DiscoverClasses(self._start_dir, self._base_dir,
-                                       self._base_class)
-
-    actual_classes = dict((name, cls.__name__)
-                          for name, cls in classes.iteritems())
-    expected_classes = {
-        'dummy_exception': 'DummyException',
-        'dummy_exception_impl1': 'DummyExceptionImpl1',
-        'dummy_exception_impl2': 'DummyExceptionImpl2',
-        'dummy_exception_with_parameter_impl1':
-            'DummyExceptionWithParameterImpl1',
-        'dummy_exception_with_parameter_impl2':
-            'DummyExceptionWithParameterImpl2'
-    }
-    self.assertEqual(actual_classes, expected_classes)
-
-  def testDiscoverClassesWithPatternAndIndexByModule(self):
-    classes = discover.DiscoverClasses(self._start_dir,
-                                       self._base_dir,
-                                       self._base_class,
-                                       pattern='another*',
-                                       index_by_class_name=False)
-
-    actual_classes = dict((name, cls.__name__)
-                          for name, cls in classes.iteritems())
-    expected_classes = {
-        'another_discover_dummyclass': 'DummyExceptionWithParameterImpl1'
-    }
-    self.assertEqual(actual_classes, expected_classes)
-
-  def testDiscoverDirectlyConstructableClassesWithPatternAndIndexByClassName(
-      self):
-    classes = discover.DiscoverClasses(self._start_dir,
-                                       self._base_dir,
-                                       self._base_class,
-                                       pattern='another*',
-                                       directly_constructable=True)
-
-    actual_classes = dict((name, cls.__name__)
-                          for name, cls in classes.iteritems())
-    expected_classes = {
-        'dummy_exception_impl1': 'DummyExceptionImpl1',
-        'dummy_exception_impl2': 'DummyExceptionImpl2',
-    }
-    self.assertEqual(actual_classes, expected_classes)
-
-  def testDiscoverClassesWithPatternAndIndexByClassName(self):
-    classes = discover.DiscoverClasses(self._start_dir,
-                                       self._base_dir,
-                                       self._base_class,
-                                       pattern='another*')
-
-    actual_classes = dict((name, cls.__name__)
-                          for name, cls in classes.iteritems())
-    expected_classes = {
-        'dummy_exception_impl1': 'DummyExceptionImpl1',
-        'dummy_exception_impl2': 'DummyExceptionImpl2',
-        'dummy_exception_with_parameter_impl1':
-            'DummyExceptionWithParameterImpl1',
-    }
-    self.assertEqual(actual_classes, expected_classes)
diff --git a/catapult/telemetry/telemetry/core/exceptions.py b/catapult/telemetry/telemetry/core/exceptions.py
deleted file mode 100644
index 1038256..0000000
--- a/catapult/telemetry/telemetry/core/exceptions.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-import sys
-
-
-class Error(Exception):
-  """Base class for Telemetry exceptions."""
-
-  def __init__(self, msg=''):
-    super(Error, self).__init__(msg)
-    self._debugging_messages = []
-
-  def AddDebuggingMessage(self, msg):
-    """Adds a message to the description of the exception.
-
-    Many Telemetry exceptions arise from failures in another application. These
-    failures are difficult to pinpoint. This method allows Telemetry classes to
-    append useful debugging information to the exception. This method also logs
-    information about the location from where it was called.
-    """
-    frame = sys._getframe(1)
-    line_number = frame.f_lineno
-    file_name = frame.f_code.co_filename
-    function_name = frame.f_code.co_name
-    call_site = '%s:%s %s' % (file_name, line_number, function_name)
-    annotated_message = '(%s) %s' % (call_site, msg)
-
-    self._debugging_messages.append(annotated_message)
-
-  def __str__(self):
-    divider = '\n' + '*' * 80 + '\n'
-    output = super(Error, self).__str__()
-    for message in self._debugging_messages:
-      output += divider
-      output += message
-    return output
-
-
-class PlatformError(Error):
-  """ Represents an exception thrown when constructing platform. """
-
-
-class TimeoutException(Error):
-  """The operation failed to complete because of a timeout.
-
-  It is possible that waiting for a longer period of time would result in a
-  successful operation.
-  """
-  pass
-
-
-class AppCrashException(Error):
-
-  def __init__(self, app=None, msg=''):
-    super(AppCrashException, self).__init__(msg)
-    self._msg = msg
-    self._is_valid_dump = False
-    self._stack_trace = []
-    self._app_stdout = []
-    self._minidump_path = ''
-    self._system_log = '(Not implemented)'
-    if app:
-      try:
-        system_log = app.platform.GetSystemLog()
-        if system_log:
-          self._system_log = system_log
-        self._is_valid_dump, trace_output = app.GetStackTrace()
-        self._stack_trace = trace_output.splitlines()
-        self._minidump_path = app.GetMostRecentMinidumpPath()
-      except Exception as err:
-        logging.error('Problem when trying to gather stack trace: %s' % err)
-      try:
-        self._app_stdout = app.GetStandardOutput().splitlines()
-      except Exception as err:
-        logging.error('Problem when trying to gather standard output: %s' % err)
-
-  @property
-  def stack_trace(self):
-    return self._stack_trace
-
-  @property
-  def minidump_path(self):
-    return self._minidump_path
-
-  @property
-  def is_valid_dump(self):
-    return self._is_valid_dump
-
-  def __str__(self):
-    divider = '*' * 80
-    debug_messages = []
-    debug_messages.append(super(AppCrashException, self).__str__())
-    debug_messages.append('Found Minidump: %s' % self._is_valid_dump)
-    debug_messages.append('Stack Trace:')
-    debug_messages.append(divider)
-    debug_messages.extend(('\t%s' % l) for l in self._stack_trace)
-    debug_messages.append(divider)
-    debug_messages.append('Standard output:')
-    debug_messages.append(divider)
-    debug_messages.extend(('\t%s' % l) for l in self._app_stdout)
-    debug_messages.append(divider)
-    debug_messages.append('System log:')
-    debug_messages.append(self._system_log)
-    return '\n'.join(debug_messages)
-
-class DevtoolsTargetCrashException(AppCrashException):
-  """Represents a crash of the current devtools target but not the overall app.
-
-  This can be a tab or a WebView. In this state, the tab/WebView is
-  gone, but the underlying browser is still alive.
-  """
-
-  def __init__(self, app, msg='Devtools target crashed'):
-    super(DevtoolsTargetCrashException, self).__init__(app, msg)
-
-
-class BrowserGoneException(AppCrashException):
-  """Represents a crash of the entire browser.
-
-  In this state, all bets are pretty much off."""
-
-  def __init__(self, app, msg='Browser crashed'):
-    super(BrowserGoneException, self).__init__(app, msg)
-
-
-class BrowserConnectionGoneException(BrowserGoneException):
-  """Represents a browser that still exists but cannot be reached."""
-
-  def __init__(self, app, msg='Browser exists but the connection is gone'):
-    super(BrowserConnectionGoneException, self).__init__(app, msg)
-
-
-class ProcessGoneException(Error):
-  """Represents a process that no longer exists for an unknown reason."""
-
-
-class IntentionalException(Error):
-  """Represent an exception raised by a unittest which is not printed."""
-
-
-class InitializationError(Error):
-
-  def __init__(self, string):
-    super(InitializationError, self).__init__(string)
-
-
-class LoginException(Error):
-  pass
-
-
-class EvaluateException(Error):
-  def __init__(self, text='', class_name='', description=None):
-    super(EvaluateException, self).__init__(text)
-    self._class_name = class_name
-    self._description = description
-
-  def __str__(self):
-    output = super(EvaluateException, self).__str__()
-    if self._class_name and self._description:
-      output += '%s:\n%s' % (self._class_name, self._description)
-    return output
-
-
-class ProfilingException(Error):
-  pass
-
-
-class PathMissingError(Error):
-  """ Represents an exception thrown when an expected path doesn't exist. """
-
-
-class UnknownPackageError(Error):
-  """ Represents an exception when encountering an unsupported Android APK. """
-
-
-class PackageDetectionError(Error):
-  """ Represents an error when parsing an Android APK's package. """
-
-
-class AndroidDeviceParsingError(Error):
-  """Represents an error when parsing output from an android device"""
diff --git a/catapult/telemetry/telemetry/core/local_server.py b/catapult/telemetry/telemetry/core/local_server.py
deleted file mode 100644
index a734174..0000000
--- a/catapult/telemetry/telemetry/core/local_server.py
+++ /dev/null
@@ -1,218 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO(aiolos): this should be moved to catapult/base after the repo move.
-# It is used by tracing in tvcm/browser_controller.
-import collections
-import json
-import os
-import re
-import subprocess
-import sys
-
-from telemetry.core import util
-
-NamedPort = collections.namedtuple('NamedPort', ['name', 'port'])
-
-
-class LocalServerBackend(object):
-
-  def __init__(self):
-    pass
-
-  def StartAndGetNamedPorts(self, args):
-    """Starts the actual server and obtains any sockets on which it
-    should listen.
-
-    Returns a list of NamedPort on which this backend is listening.
-    """
-    raise NotImplementedError()
-
-  def ServeForever(self):
-    raise NotImplementedError()
-
-
-class LocalServer(object):
-
-  def __init__(self, server_backend_class):
-    assert LocalServerBackend in server_backend_class.__bases__
-    server_module_name = server_backend_class.__module__
-    assert server_module_name in sys.modules, \
-        'The server class\' module must be findable via sys.modules'
-    assert getattr(sys.modules[server_module_name],
-                   server_backend_class.__name__), \
-        'The server class must getattrable from its __module__ by its __name__'
-
-    self._server_backend_class = server_backend_class
-    self._subprocess = None
-    self._devnull = None
-    self._local_server_controller = None
-    self.host_ip = None
-    self.port = None
-
-  def Start(self, local_server_controller):
-    assert self._subprocess == None
-    self._local_server_controller = local_server_controller
-
-    self.host_ip = local_server_controller.host_ip
-
-    server_args = self.GetBackendStartupArgs()
-    server_args_as_json = json.dumps(server_args)
-    server_module_name = self._server_backend_class.__module__
-
-    self._devnull = open(os.devnull, 'w')
-    cmd = [
-        sys.executable,
-        '-m',
-        __name__,
-        'run_backend',
-        server_module_name,
-        self._server_backend_class.__name__,
-        server_args_as_json,
-    ]
-
-    env = os.environ.copy()
-    env['PYTHONPATH'] = os.pathsep.join(sys.path)
-
-    self._subprocess = subprocess.Popen(cmd,
-                                        cwd=util.GetTelemetryDir(),
-                                        env=env,
-                                        stdout=subprocess.PIPE)
-
-    named_ports = self._GetNamedPortsFromBackend()
-    http_port = None
-    for p in named_ports:
-      if p.name == 'http':
-        http_port = p.port
-    assert http_port and len(named_ports) == 1, (
-        'Only http port is supported: %s' % named_ports)
-    self.port = http_port
-
-  def _GetNamedPortsFromBackend(self):
-    named_ports_json = None
-    named_ports_re = re.compile('LocalServerBackend started: (?P<port>.+)')
-    # TODO: This will hang if the subprocess doesn't print the correct output.
-    while self._subprocess.poll() == None:
-      m = named_ports_re.match(self._subprocess.stdout.readline())
-      if m:
-        named_ports_json = m.group('port')
-        break
-
-    if not named_ports_json:
-      raise Exception('Server process died prematurely ' +
-                      'without giving us port pairs.')
-    return [NamedPort(**pair) for pair in json.loads(named_ports_json.lower())]
-
-  @property
-  def is_running(self):
-    return self._subprocess != None
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, *args):
-    self.Close()
-
-  def __del__(self):
-    self.Close()
-
-  def Close(self):
-    if self._subprocess:
-      # TODO(tonyg): Should this block until it goes away?
-      self._subprocess.kill()
-      self._subprocess = None
-    if self._devnull:
-      self._devnull.close()
-      self._devnull = None
-    if self._local_server_controller:
-      self._local_server_controller.ServerDidClose(self)
-      self._local_server_controller = None
-
-  def GetBackendStartupArgs(self):
-    """Returns whatever arguments are required to start up the backend"""
-    raise NotImplementedError()
-
-
-class LocalServerController(object):
-  """Manages the list of running servers
-
-  This class manages the running servers, but also provides an isolation layer
-  to prevent LocalServer subclasses from accessing the browser backend directly.
-
-  """
-
-  def __init__(self, platform_backend):
-    self._platform_backend = platform_backend
-    self._local_servers_by_class = {}
-    self.host_ip = self._platform_backend.forwarder_factory.host_ip
-
-  def StartServer(self, server):
-    assert not server.is_running, 'Server already started'
-    assert self._platform_backend.network_controller_backend.is_initialized
-    assert isinstance(server, LocalServer)
-    if server.__class__ in self._local_servers_by_class:
-      raise Exception(
-          'Cannot have two servers of the same class running at once. ' +
-          'Locate the existing one and use it, or call Close() on it.')
-
-    server.Start(self)
-    self._local_servers_by_class[server.__class__] = server
-
-  def GetRunningServer(self, server_class, default_value):
-    return self._local_servers_by_class.get(server_class, default_value)
-
-  @property
-  def local_servers(self):
-    return self._local_servers_by_class.values()
-
-  def Close(self):
-    while len(self._local_servers_by_class):
-      server = self._local_servers_by_class.itervalues().next()
-      try:
-        server.Close()
-      except Exception:
-        import traceback
-        traceback.print_exc()
-
-  def GetRemotePort(self, port):
-    return self._platform_backend.GetRemotePort(port)
-
-  def ServerDidClose(self, server):
-    del self._local_servers_by_class[server.__class__]
-
-
-def _LocalServerBackendMain(args):
-  assert len(args) == 4
-  (cmd, server_module_name, server_backend_class_name,
-   server_args_as_json) = args[:4]
-  assert cmd == 'run_backend'
-  server_module = __import__(server_module_name, fromlist=[True])
-  server_backend_class = getattr(server_module, server_backend_class_name)
-  server = server_backend_class()
-
-  server_args = json.loads(server_args_as_json)
-
-  named_ports = server.StartAndGetNamedPorts(server_args)
-  assert isinstance(named_ports, list)
-  for named_port in named_ports:
-    assert isinstance(named_port, NamedPort)
-
-  # Note: This message is scraped by the parent process'
-  # _GetNamedPortsFromBackend(). Do **not** change it.
-  # pylint: disable=protected-access
-  print 'LocalServerBackend started: %s' % json.dumps([pair._asdict()
-                                                       for pair in named_ports])
-  sys.stdout.flush()
-
-  return server.ServeForever()
-
-
-if __name__ == '__main__':
-  # This trick is needed because local_server.NamedPort is not the
-  # same as sys.modules['__main__'].NamedPort. The module itself is loaded
-  # twice, basically.
-  from telemetry.core import local_server  # pylint: disable=import-self
-  sys.exit(
-      local_server._LocalServerBackendMain(  # pylint: disable=protected-access
-          sys.argv[1:]))
diff --git a/catapult/telemetry/telemetry/core/local_server_unittest.py b/catapult/telemetry/telemetry/core/local_server_unittest.py
deleted file mode 100644
index 46ff85c..0000000
--- a/catapult/telemetry/telemetry/core/local_server_unittest.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import BaseHTTPServer
-import SimpleHTTPServer
-
-from telemetry import decorators
-from telemetry.core import local_server
-from telemetry.testing import tab_test_case
-
-
-class SimpleLocalServerBackendRequestHandler(
-    SimpleHTTPServer.SimpleHTTPRequestHandler):
-
-  def do_GET(self):
-    msg = """<!DOCTYPE html>
-<html>
-<body>
-hello world
-</body>
-"""
-
-    self.send_response(200)
-    self.send_header('Content-Type', 'text/html')
-    self.send_header('Content-Length', len(msg))
-    self.end_headers()
-    self.wfile.write(msg)
-
-  def log_request(self, code='-', size='-'):
-    pass
-
-
-class SimpleLocalServerBackend(BaseHTTPServer.HTTPServer,
-                               local_server.LocalServerBackend):
-
-  def __init__(self):
-    BaseHTTPServer.HTTPServer.__init__(self, ('127.0.0.1', 0),
-                                       SimpleLocalServerBackendRequestHandler)
-    local_server.LocalServerBackend.__init__(self)
-
-  def StartAndGetNamedPorts(self, args):
-    assert 'hello' in args
-    assert args['hello'] == 'world'
-    return [local_server.NamedPort('http', self.server_address[1])]
-
-  def ServeForever(self):
-    self.serve_forever()
-
-
-class SimpleLocalServer(local_server.LocalServer):
-
-  def __init__(self):
-    super(SimpleLocalServer, self).__init__(SimpleLocalServerBackend)
-
-  def GetBackendStartupArgs(self):
-    return {'hello': 'world'}
-
-  @property
-  def url(self):
-    return self.forwarder.url + '/'
-
-
-class LocalServerUnittest(tab_test_case.TabTestCase):
-
-  @classmethod
-  def setUpClass(cls):
-    super(LocalServerUnittest, cls).setUpClass()
-    cls._server = SimpleLocalServer()
-    cls._platform.StartLocalServer(cls._server)
-
-  @decorators.Disabled('all') # https://crbug.com/570955
-  def testLocalServer(self):
-    self.assertTrue(self._server in self._platform.local_servers)
-    self._tab.Navigate(self._server.url)
-    self._tab.WaitForDocumentReadyStateToBeComplete()
-    body_text = self._tab.EvaluateJavaScript('document.body.textContent')
-    body_text = body_text.strip()
-    self.assertEquals('hello world', body_text)
-
-  @decorators.Disabled('all') # https://crbug.com/570955
-  def testStartingAndRestarting(self):
-    server2 = SimpleLocalServer()
-    self.assertRaises(Exception,
-                      lambda: self._platform.StartLocalServer(server2))
-
-    self._server.Close()
-    self.assertTrue(self._server not in self._platform.local_servers)
-
-    self._platform.StartLocalServer(server2)
diff --git a/catapult/telemetry/telemetry/core/memory_cache_http_server.py b/catapult/telemetry/telemetry/core/memory_cache_http_server.py
deleted file mode 100644
index 336e6ec..0000000
--- a/catapult/telemetry/telemetry/core/memory_cache_http_server.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import BaseHTTPServer
-from collections import namedtuple
-import errno
-import gzip
-import mimetypes
-import os
-import SimpleHTTPServer
-import socket
-import SocketServer
-import StringIO
-import sys
-import urlparse
-
-from telemetry.core import local_server
-
-ByteRange = namedtuple('ByteRange', ['from_byte', 'to_byte'])
-ResourceAndRange = namedtuple('ResourceAndRange', ['resource', 'byte_range'])
-
-
-class MemoryCacheHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
-
-  protocol_version = 'HTTP/1.1'  # override BaseHTTPServer setting
-  wbufsize = -1  # override StreamRequestHandler (a base class) setting
-
-  def handle(self):
-    try:
-      BaseHTTPServer.BaseHTTPRequestHandler.handle(self)
-    except socket.error as e:
-      # Connection reset errors happen all the time due to the browser closing
-      # without terminating the connection properly.  They can be safely
-      # ignored.
-      if e[0] != errno.ECONNRESET:
-        raise
-
-  def do_GET(self):
-    """Serve a GET request."""
-    resource_range = self.SendHead()
-
-    if not resource_range or not resource_range.resource:
-      return
-    response = resource_range.resource['response']
-
-    if not resource_range.byte_range:
-      self.wfile.write(response)
-      return
-
-    start_index = resource_range.byte_range.from_byte
-    end_index = resource_range.byte_range.to_byte
-    self.wfile.write(response[start_index:end_index + 1])
-
-  def do_HEAD(self):
-    """Serve a HEAD request."""
-    self.SendHead()
-
-  def log_error(self, fmt, *args):
-    pass
-
-  def log_request(self, code='-', size='-'):
-    # Don't spam the console unless it is important.
-    pass
-
-  def SendHead(self):
-    path = os.path.realpath(self.translate_path(self.path))
-    if path not in self.server.resource_map:
-      self.send_error(404, 'File not found')
-      return None
-
-    resource = self.server.resource_map[path]
-    total_num_of_bytes = resource['content-length']
-    byte_range = self.GetByteRange(total_num_of_bytes)
-    if byte_range:
-      # request specified a range, so set response code to 206.
-      self.send_response(206)
-      self.send_header('Content-Range', 'bytes %d-%d/%d' %
-                       (byte_range.from_byte, byte_range.to_byte,
-                        total_num_of_bytes))
-      total_num_of_bytes = byte_range.to_byte - byte_range.from_byte + 1
-    else:
-      self.send_response(200)
-
-    self.send_header('Content-Length', str(total_num_of_bytes))
-    self.send_header('Content-Type', resource['content-type'])
-    self.send_header('Last-Modified',
-                     self.date_time_string(resource['last-modified']))
-    if resource['zipped']:
-      self.send_header('Content-Encoding', 'gzip')
-    self.end_headers()
-    return ResourceAndRange(resource, byte_range)
-
-  def GetByteRange(self, total_num_of_bytes):
-    """Parse the header and get the range values specified.
-
-    Args:
-      total_num_of_bytes: Total # of bytes in requested resource,
-      used to calculate upper range limit.
-    Returns:
-      A ByteRange namedtuple object with the requested byte-range values.
-      If no Range is explicitly requested or there is a failure parsing,
-      return None.
-      If range specified is in the format "N-", return N-END. Refer to
-      http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html for details.
-      If upper range limit is greater than total # of bytes, return upper index.
-    """
-
-    range_header = self.headers.getheader('Range')
-    if range_header is None:
-      return None
-    if not range_header.startswith('bytes='):
-      return None
-
-    # The range header is expected to be a string in this format:
-    # bytes=0-1
-    # Get the upper and lower limits of the specified byte-range.
-    # We've already confirmed that range_header starts with 'bytes='.
-    byte_range_values = range_header[len('bytes='):].split('-')
-    from_byte = 0
-    to_byte = 0
-
-    if len(byte_range_values) == 2:
-      # If to_range is not defined return all bytes starting from from_byte.
-      to_byte = (int(byte_range_values[1]) if byte_range_values[1] else
-                 total_num_of_bytes - 1)
-      # If from_range is not defined return last 'to_byte' bytes.
-      from_byte = (int(byte_range_values[0]) if byte_range_values[0] else
-                   total_num_of_bytes - to_byte)
-    else:
-      return None
-
-    # Do some validation.
-    if from_byte < 0:
-      return None
-
-    # Make to_byte the end byte by default in edge cases.
-    if to_byte < from_byte or to_byte >= total_num_of_bytes:
-      to_byte = total_num_of_bytes - 1
-
-    return ByteRange(from_byte, to_byte)
-
-
-class _MemoryCacheHTTPServerImpl(SocketServer.ThreadingMixIn,
-                                 BaseHTTPServer.HTTPServer):
-  # Increase the request queue size. The default value, 5, is set in
-  # SocketServer.TCPServer (the parent of BaseHTTPServer.HTTPServer).
-  # Since we're intercepting many domains through this single server,
-  # it is quite possible to get more than 5 concurrent requests.
-  request_queue_size = 128
-
-  # Don't prevent python from exiting when there is thread activity.
-  daemon_threads = True
-
-  def __init__(self, host_port, handler, paths):
-    BaseHTTPServer.HTTPServer.__init__(self, host_port, handler)
-    self.resource_map = {}
-    for path in paths:
-      if os.path.isdir(path):
-        self.AddDirectoryToResourceMap(path)
-      else:
-        self.AddFileToResourceMap(path)
-
-  def AddDirectoryToResourceMap(self, directory_path):
-    """Loads all files in directory_path into the in-memory resource map."""
-    for root, dirs, files in os.walk(directory_path):
-      # Skip hidden files and folders (like .svn and .git).
-      files = [f for f in files if f[0] != '.']
-      dirs[:] = [d for d in dirs if d[0] != '.']
-
-      for f in files:
-        file_path = os.path.join(root, f)
-        if not os.path.exists(file_path):  # Allow for '.#' files
-          continue
-        self.AddFileToResourceMap(file_path)
-
-  def AddFileToResourceMap(self, file_path):
-    """Loads file_path into the in-memory resource map."""
-    file_path = os.path.realpath(file_path)
-    if file_path in self.resource_map:
-      return
-
-    with open(file_path, 'rb') as fd:
-      response = fd.read()
-      fs = os.fstat(fd.fileno())
-    content_type = mimetypes.guess_type(file_path)[0]
-    zipped = False
-    if content_type in ['text/html', 'text/css', 'application/javascript']:
-      zipped = True
-      sio = StringIO.StringIO()
-      gzf = gzip.GzipFile(fileobj=sio, compresslevel=9, mode='wb')
-      gzf.write(response)
-      gzf.close()
-      response = sio.getvalue()
-      sio.close()
-    self.resource_map[file_path] = {
-        'content-type': content_type,
-        'content-length': len(response),
-        'last-modified': fs.st_mtime,
-        'response': response,
-        'zipped': zipped
-    }
-
-    index = 'index.html'
-    if os.path.basename(file_path) == index:
-      dir_path = os.path.dirname(file_path)
-      self.resource_map[dir_path] = self.resource_map[file_path]
-
-
-class MemoryCacheHTTPServerBackend(local_server.LocalServerBackend):
-
-  def __init__(self):
-    super(MemoryCacheHTTPServerBackend, self).__init__()
-    self._httpd = None
-
-  def StartAndGetNamedPorts(self, args):
-    base_dir = args['base_dir']
-    os.chdir(base_dir)
-
-    paths = args['paths']
-    for path in paths:
-      if not os.path.realpath(path).startswith(os.path.realpath(os.getcwd())):
-        print >> sys.stderr, '"%s" is not under the cwd.' % path
-        sys.exit(1)
-
-    server_address = (args['host'], args['port'])
-    MemoryCacheHTTPRequestHandler.protocol_version = 'HTTP/1.1'
-    self._httpd = _MemoryCacheHTTPServerImpl(
-        server_address, MemoryCacheHTTPRequestHandler, paths)
-    return [local_server.NamedPort('http', self._httpd.server_address[1])]
-
-  def ServeForever(self):
-    return self._httpd.serve_forever()
-
-
-class MemoryCacheHTTPServer(local_server.LocalServer):
-
-  def __init__(self, paths):
-    super(MemoryCacheHTTPServer, self).__init__(MemoryCacheHTTPServerBackend)
-    self._base_dir = None
-
-    for path in paths:
-      assert os.path.exists(path), '%s does not exist.' % path
-
-    paths = list(paths)
-    self._paths = paths
-
-    self._paths_as_set = set(map(os.path.realpath, paths))
-
-    common_prefix = os.path.commonprefix(paths)
-    if os.path.isdir(common_prefix):
-      self._base_dir = common_prefix
-    else:
-      self._base_dir = os.path.dirname(common_prefix)
-
-  def GetBackendStartupArgs(self):
-    return {'base_dir': self._base_dir,
-            'paths': self._paths,
-            'host': self.host_ip,
-            'port': 0}
-
-  @property
-  def paths(self):
-    return self._paths_as_set
-
-  @property
-  def url(self):
-    return 'http://127.0.0.1:%s' % self.port
-
-  def UrlOf(self, path):
-    if os.path.isabs(path):
-      relative_path = os.path.relpath(path, self._base_dir)
-    else:
-      relative_path = path
-    # Preserve trailing slash or backslash.
-    # It doesn't matter in a file path, but it does matter in a URL.
-    if path.endswith(os.sep) or (os.altsep and path.endswith(os.altsep)):
-      relative_path += '/'
-    return urlparse.urljoin(self.url, relative_path.replace(os.sep, '/'))
diff --git a/catapult/telemetry/telemetry/core/memory_cache_http_server_unittest.py b/catapult/telemetry/telemetry/core/memory_cache_http_server_unittest.py
deleted file mode 100644
index 9a74a1b..0000000
--- a/catapult/telemetry/telemetry/core/memory_cache_http_server_unittest.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.core import util
-from telemetry.testing import tab_test_case
-
-
-class MemoryCacheHTTPServerTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    super(MemoryCacheHTTPServerTest, self).setUp()
-    self._test_filename = 'bear.webm'
-    _test_file = os.path.join(util.GetUnittestDataDir(), 'bear.webm')
-    self._test_file_size = os.stat(_test_file).st_size
-
-  def testBasicHostingAndRangeRequests(self):
-    self.Navigate('blank.html')
-    x = self._tab.EvaluateJavaScript('document.body.innerHTML')
-    x = x.strip()
-
-    # Test basic html hosting.
-    self.assertEquals(x, 'Hello world')
-
-    file_size = self._test_file_size
-    last_byte = file_size - 1
-    # Test byte range request: no end byte.
-    self.CheckContentHeaders('0-', '0-%d' % last_byte, file_size)
-
-    # Test byte range request: greater than zero start byte.
-    self.CheckContentHeaders('100-', '100-%d' % last_byte, file_size - 100)
-
-    # Test byte range request: explicit byte range.
-    self.CheckContentHeaders('2-500', '2-500', '499')
-
-    # Test byte range request: no start byte.
-    self.CheckContentHeaders('-228', '%d-%d' % (file_size - 228, last_byte),
-                             '228')
-
-    # Test byte range request: end byte less than start byte.
-    self.CheckContentHeaders('100-5', '100-%d' % last_byte, file_size - 100)
-
-  def CheckContentHeaders(self, content_range_request, content_range_response,
-                          content_length_response):
-    self._tab.ExecuteJavaScript("""
-        var loaded = false;
-        var xmlhttp = new XMLHttpRequest();
-        xmlhttp.onload = function(e) {
-          loaded = true;
-        };
-        // Avoid cached content by appending unique URL param.
-        xmlhttp.open('GET', {{ url }} + "?t=" + Date.now(), true);
-        xmlhttp.setRequestHeader('Range', {{ range }});
-        xmlhttp.send();
-        """,
-        url=self.UrlOfUnittestFile(self._test_filename),
-        range='bytes=%s' % content_range_request)
-    self._tab.WaitForJavaScriptCondition('loaded', timeout=5)
-    content_range = self._tab.EvaluateJavaScript(
-        'xmlhttp.getResponseHeader("Content-Range");')
-    content_range_response = 'bytes %s/%d' % (content_range_response,
-                                              self._test_file_size)
-    self.assertEquals(content_range, content_range_response)
-    content_length = self._tab.EvaluateJavaScript(
-        'xmlhttp.getResponseHeader("Content-Length");')
-    self.assertEquals(content_length, str(content_length_response))
-
-  def testAbsoluteAndRelativePathsYieldSameURL(self):
-    test_file_rel_path = 'green_rect.html'
-    test_file_abs_path = os.path.abspath(os.path.join(util.GetUnittestDataDir(),
-                                                      test_file_rel_path))
-    # It's necessary to bypass self.UrlOfUnittestFile since that
-    # concatenates the unittest directory on to the incoming path,
-    # causing the same code path to be taken in both cases.
-    self._platform.SetHTTPServerDirectories(util.GetUnittestDataDir())
-    self.assertEquals(
-      self._platform.http_server.UrlOf(test_file_rel_path),
-      self._platform.http_server.UrlOf(test_file_abs_path))
diff --git a/catapult/telemetry/telemetry/core/network_controller.py b/catapult/telemetry/telemetry/core/network_controller.py
deleted file mode 100644
index da2e55a..0000000
--- a/catapult/telemetry/telemetry/core/network_controller.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from py_trace_event import trace_event
-
-
-class NetworkController(object):
-  """Control network settings and servers to simulate the Web.
-
-  Network changes include forwarding device ports to host platform ports.
-  Web Page Replay is used to record and replay HTTP/HTTPS responses.
-  """
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def __init__(self, network_controller_backend):
-    self._network_controller_backend = network_controller_backend
-
-  def InitializeIfNeeded(self, use_live_traffic=False):
-    self._network_controller_backend.InitializeIfNeeded(use_live_traffic)
-
-  def Open(self, wpr_mode, extra_wpr_args):
-    self._network_controller_backend.Open(wpr_mode, extra_wpr_args)
-
-  def UpdateTrafficSettings(self, round_trip_latency_ms=None,
-      download_bandwidth_kbps=None, upload_bandwidth_kbps=None):
-    self._network_controller_backend.ts_proxy_server.UpdateTrafficSettings(
-      round_trip_latency_ms, download_bandwidth_kbps, upload_bandwidth_kbps)
-
-  @property
-  def is_open(self):
-    return self._network_controller_backend.is_open
-
-  def Close(self):
-    self._network_controller_backend.Close()
-
-  def StartReplay(self, archive_path, make_javascript_deterministic=False):
-    self._network_controller_backend.StartReplay(
-        archive_path, make_javascript_deterministic)
-
-  def StopReplay(self):
-    self._network_controller_backend.StopReplay()
diff --git a/catapult/telemetry/telemetry/core/os_version.py b/catapult/telemetry/telemetry/core/os_version.py
deleted file mode 100644
index 57285c1..0000000
--- a/catapult/telemetry/telemetry/core/os_version.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=protected-access
-
-
-class OSVersion(str):
-  def __new__(cls, friendly_name, sortable_name):
-    version = str.__new__(cls, friendly_name)
-    version._sortable_name = sortable_name
-    return version
-
-  def __lt__(self, other):
-    return self._sortable_name < other._sortable_name
-
-  def __gt__(self, other):
-    return self._sortable_name > other._sortable_name
-
-  def __le__(self, other):
-    return self._sortable_name <= other._sortable_name
-
-  def __ge__(self, other):
-    return self._sortable_name >= other._sortable_name
-
-
-XP = OSVersion('xp', 5.1)
-VISTA = OSVersion('vista', 6.0)
-WIN7 = OSVersion('win7', 6.1)
-WIN8 = OSVersion('win8', 6.2)
-WIN81 = OSVersion('win8.1', 6.3)
-WIN10 = OSVersion('win10', 10)
-
-LEOPARD = OSVersion('leopard', 105)
-SNOWLEOPARD = OSVersion('snowleopard', 106)
-LION = OSVersion('lion', 107)
-MOUNTAINLION = OSVersion('mountainlion', 108)
-MAVERICKS = OSVersion('mavericks', 109)
-YOSEMITE = OSVersion('yosemite', 1010)
-ELCAPITAN = OSVersion('elcapitan', 1011)
-SIERRA = OSVersion('sierra', 1012)
diff --git a/catapult/telemetry/telemetry/core/platform.py b/catapult/telemetry/telemetry/core/platform.py
deleted file mode 100644
index 7435c4e..0000000
--- a/catapult/telemetry/telemetry/core/platform.py
+++ /dev/null
@@ -1,425 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging as real_logging
-import os
-import sys
-
-from telemetry.core import discover
-from telemetry.core import local_server
-from telemetry.core import memory_cache_http_server
-from telemetry.core import network_controller
-from telemetry.core import tracing_controller
-from telemetry.core import util
-from telemetry.internal.platform import (platform_backend as
-                                         platform_backend_module)
-
-_host_platform = None
-# Remote platform is a dictionary from device ids to remote platform instances.
-_remote_platforms = {}
-
-
-def _InitHostPlatformIfNeeded():
-  global _host_platform
-  if _host_platform:
-    return
-  backend = None
-  backends = _IterAllPlatformBackendClasses()
-  for platform_backend_class in backends:
-    if platform_backend_class.IsPlatformBackendForHost():
-      backend = platform_backend_class()
-      break
-  if not backend:
-    raise NotImplementedError()
-  _host_platform = Platform(backend)
-
-
-def GetHostPlatform():
-  _InitHostPlatformIfNeeded()
-  return _host_platform
-
-
-def _IterAllPlatformBackendClasses():
-  platform_dir = os.path.dirname(os.path.realpath(
-      platform_backend_module.__file__))
-  return discover.DiscoverClasses(
-      platform_dir, util.GetTelemetryDir(),
-      platform_backend_module.PlatformBackend).itervalues()
-
-
-def GetPlatformForDevice(device, finder_options, logging=real_logging):
-  """ Returns a platform instance for the device.
-    Args:
-      device: a device.Device instance.
-  """
-  if device.guid in _remote_platforms:
-    return _remote_platforms[device.guid]
-  try:
-    for platform_backend_class in _IterAllPlatformBackendClasses():
-      if platform_backend_class.SupportsDevice(device):
-        _remote_platforms[device.guid] = (
-            platform_backend_class.CreatePlatformForDevice(device,
-                                                           finder_options))
-        return _remote_platforms[device.guid]
-    return None
-  except Exception:
-    current_exception = sys.exc_info()
-    logging.error('Fail to create platform instance for %s.', device.name)
-    raise current_exception[0], current_exception[1], current_exception[2]
-
-
-class Platform(object):
-  """The platform that the target browser is running on.
-
-  Provides a limited interface to interact with the platform itself, where
-  possible. It's important to note that platforms may not provide a specific
-  API, so check with IsFooBar() for availability.
-  """
-
-  def __init__(self, platform_backend):
-    self._platform_backend = platform_backend
-    self._platform_backend.InitPlatformBackend()
-    self._platform_backend.SetPlatform(self)
-    self._network_controller = network_controller.NetworkController(
-        self._platform_backend.network_controller_backend)
-    self._tracing_controller = tracing_controller.TracingController(
-        self._platform_backend.tracing_controller_backend)
-    self._local_server_controller = local_server.LocalServerController(
-        self._platform_backend)
-    self._is_monitoring_power = False
-
-  @property
-  def is_host_platform(self):
-    return self == GetHostPlatform()
-
-  @property
-  def network_controller(self):
-    """Control network settings and servers to simulate the Web."""
-    return self._network_controller
-
-  @property
-  def tracing_controller(self):
-    return self._tracing_controller
-
-  def Initialize(self):
-    pass
-
-  def CanMonitorThermalThrottling(self):
-    """Platforms may be able to detect thermal throttling.
-
-    Some fan-less computers go into a reduced performance mode when their heat
-    exceeds a certain threshold. Performance tests in particular should use this
-    API to detect if this has happened and interpret results accordingly.
-    """
-    return self._platform_backend.CanMonitorThermalThrottling()
-
-  def GetSystemLog(self):
-    return self._platform_backend.GetSystemLog()
-
-  def IsThermallyThrottled(self):
-    """Returns True if the device is currently thermally throttled."""
-    return self._platform_backend.IsThermallyThrottled()
-
-  def HasBeenThermallyThrottled(self):
-    """Returns True if the device has been thermally throttled."""
-    return self._platform_backend.HasBeenThermallyThrottled()
-
-  def GetDeviceTypeName(self):
-    """Returns a string description of the Platform device, or None.
-
-    Examples: Nexus 7, Nexus 6, Desktop"""
-    return self._platform_backend.GetDeviceTypeName()
-
-  def GetArchName(self):
-    """Returns a string description of the Platform architecture.
-
-    Examples: x86_64 (posix), AMD64 (win), armeabi-v7a, x86"""
-    return self._platform_backend.GetArchName()
-
-  def GetOSName(self):
-    """Returns a string description of the Platform OS.
-
-    Examples: WIN, MAC, LINUX, CHROMEOS"""
-    return self._platform_backend.GetOSName()
-
-  def GetOSVersionName(self):
-    """Returns a logically sortable, string-like description of the Platform OS
-    version.
-
-    Examples: VISTA, WIN7, LION, MOUNTAINLION"""
-    return self._platform_backend.GetOSVersionName()
-
-  def GetOSVersionNumber(self):
-    """Returns an integer description of the Platform OS major version.
-
-    Examples: On Mac, 13 for Mavericks, 14 for Yosemite."""
-    return self._platform_backend.GetOSVersionNumber()
-
-  def GetSystemTotalPhysicalMemory(self):
-    """Returns an integer with the total physical memory in bytes."""
-    return self._platform_backend.GetSystemTotalPhysicalMemory()
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    """Returns true if the disk cache can be flushed for specific files."""
-    return self._platform_backend.CanFlushIndividualFilesFromSystemCache()
-
-  def SupportFlushEntireSystemCache(self):
-    """Returns true if entire system cache can be flushed.
-
-    Also checks that platform has required privilegues to flush system caches.
-    """
-    return self._platform_backend.SupportFlushEntireSystemCache()
-
-  def FlushEntireSystemCache(self):
-    """Flushes the OS's file cache completely.
-
-    This function may require root or administrator access. Clients should
-    call SupportFlushEntireSystemCache to check first.
-    """
-    return self._platform_backend.FlushEntireSystemCache()
-
-  def FlushSystemCacheForDirectory(self, directory):
-    """Flushes the OS's file cache for the specified directory.
-
-    This function does not require root or administrator access."""
-    return self._platform_backend.FlushSystemCacheForDirectory(directory)
-
-  def FlushDnsCache(self):
-    """Flushes the OS's DNS cache completely.
-
-    This function may require root or administrator access."""
-    return self._platform_backend.FlushDnsCache()
-
-  def LaunchApplication(self,
-                        application,
-                        parameters=None,
-                        elevate_privilege=False):
-    """"Launches the given |application| with a list of |parameters| on the OS.
-
-    Set |elevate_privilege| to launch the application with root or admin rights.
-
-    Returns:
-      A popen style process handle for host platforms.
-    """
-    return self._platform_backend.LaunchApplication(
-        application,
-        parameters,
-        elevate_privilege=elevate_privilege)
-
-  def IsApplicationRunning(self, application):
-    """Returns whether an application is currently running."""
-    return self._platform_backend.IsApplicationRunning(application)
-
-  def CanLaunchApplication(self, application):
-    """Returns whether the platform can launch the given application."""
-    return self._platform_backend.CanLaunchApplication(application)
-
-  def InstallApplication(self, application):
-    """Installs the given application."""
-    return self._platform_backend.InstallApplication(application)
-
-  def CanCaptureVideo(self):
-    """Returns a bool indicating whether the platform supports video capture."""
-    return self._platform_backend.CanCaptureVideo()
-
-  def StartVideoCapture(self, min_bitrate_mbps):
-    """Starts capturing video.
-
-    Outer framing may be included (from the OS, browser window, and webcam).
-
-    Args:
-      min_bitrate_mbps: The minimum capture bitrate in MegaBits Per Second.
-          The platform is free to deliver a higher bitrate if it can do so
-          without increasing overhead.
-
-    Raises:
-      ValueError if the required |min_bitrate_mbps| can't be achieved.
-    """
-    return self._platform_backend.StartVideoCapture(min_bitrate_mbps)
-
-  def StopVideoCapture(self):
-    """Stops capturing video.
-
-    Returns:
-      A telemetry.core.video.Video object.
-    """
-    return self._platform_backend.StopVideoCapture()
-
-  def CanMonitorPower(self):
-    """Returns True iff power can be monitored asynchronously via
-    StartMonitoringPower() and StopMonitoringPower().
-    """
-    return self._platform_backend.CanMonitorPower()
-
-  def CanMeasurePerApplicationPower(self):
-    """Returns True if the power monitor can measure power for the target
-    application in isolation. False if power measurement is for full system
-    energy consumption."""
-    return self._platform_backend.CanMeasurePerApplicationPower()
-
-  def StartMonitoringPower(self, browser):
-    """Starts monitoring power utilization statistics.
-
-    Args:
-      browser: The browser to monitor.
-    """
-    assert self._platform_backend.CanMonitorPower()
-    self._platform_backend.StartMonitoringPower(browser)
-    self._is_monitoring_power = True
-
-  def StopMonitoringPower(self):
-    """Stops monitoring power utilization and returns stats
-
-    Returns:
-      None if power measurement failed for some reason, otherwise a dict of
-      power utilization statistics containing: {
-        # An identifier for the data provider. Allows to evaluate the precision
-        # of the data. Example values: monsoon, powermetrics, ds2784
-        'identifier': identifier,
-
-        # The instantaneous power (voltage * current) reading in milliwatts at
-        # each sample.
-        'power_samples_mw':  [mw0, mw1, ..., mwN],
-
-        # The full system energy consumption during the sampling period in
-        # milliwatt hours. May be estimated by integrating power samples or may
-        # be exact on supported hardware.
-        'energy_consumption_mwh': mwh,
-
-        # The target application's energy consumption during the sampling period
-        # in milliwatt hours. Should be returned iff
-        # CanMeasurePerApplicationPower() return true.
-        'application_energy_consumption_mwh': mwh,
-
-        # A platform-specific dictionary of additional details about the
-        # utilization of individual hardware components.
-        component_utilization: {
-          ...
-        }
-        # Platform-specific data not attributed to any particular hardware
-        # component.
-        platform_info: {
-
-          # Device-specific onboard temperature sensor.
-          'average_temperature_c': c,
-
-           ...
-        }
-
-      }
-    """
-    ret_val = self._platform_backend.StopMonitoringPower()
-    self._is_monitoring_power = False
-    return ret_val
-
-  def IsMonitoringPower(self):
-    """Returns true if power is currently being monitored, false otherwise."""
-    # TODO(rnephew): Remove when crbug.com/553601 is solved.
-    real_logging.info('IsMonitoringPower: %s', self._is_monitoring_power)
-    return self._is_monitoring_power
-
-  def CanMonitorNetworkData(self):
-    """Returns true if network data can be retrieved, false otherwise."""
-    return self._platform_backend.CanMonitorNetworkData()
-
-  def GetNetworkData(self, browser):
-    """Get current network data.
-    Returns:
-      Tuple of (sent_data, received_data) in kb if data can be found,
-      None otherwise.
-    """
-    assert browser.platform == self
-    return self._platform_backend.GetNetworkData(browser)
-
-  def IsCooperativeShutdownSupported(self):
-    """Indicates whether CooperativelyShutdown, below, is supported.
-    It is not necessary to implement it on all platforms."""
-    return self._platform_backend.IsCooperativeShutdownSupported()
-
-  def CooperativelyShutdown(self, proc, app_name):
-    """Cooperatively shut down the given process from subprocess.Popen.
-
-    Currently this is only implemented on Windows. See
-    crbug.com/424024 for background on why it was added.
-
-    Args:
-      proc: a process object returned from subprocess.Popen.
-      app_name: on Windows, is the prefix of the application's window
-          class name that should be searched for. This helps ensure
-          that only the application's windows are closed.
-
-    Returns True if it is believed the attempt succeeded.
-    """
-    return self._platform_backend.CooperativelyShutdown(proc, app_name)
-
-  def CanTakeScreenshot(self):
-    return self._platform_backend.CanTakeScreenshot()
-
-  # TODO(nednguyen): Implement this on Mac, Linux & Win. (crbug.com/369490)
-  def TakeScreenshot(self, file_path):
-    """ Takes a screenshot of the platform and save to |file_path|.
-
-    Note that this method may not be supported on all platform, so check with
-    CanTakeScreenshot before calling this.
-
-    Args:
-      file_path: Where to save the screenshot to. If the platform is remote,
-        |file_path| is the path on the host platform.
-
-    Returns True if it is believed the attempt succeeded.
-    """
-    return self._platform_backend.TakeScreenshot(file_path)
-
-  def StartLocalServer(self, server):
-    """Starts a LocalServer and associates it with this platform.
-    |server.Close()| should be called manually to close the started server.
-    """
-    self._local_server_controller.StartServer(server)
-
-  @property
-  def http_server(self):
-    return self._local_server_controller.GetRunningServer(
-        memory_cache_http_server.MemoryCacheHTTPServer, None)
-
-  def SetHTTPServerDirectories(self, paths):
-    """Returns True if the HTTP server was started, False otherwise."""
-    if isinstance(paths, basestring):
-      paths = set([paths])
-    paths = set(os.path.realpath(p) for p in paths)
-
-    # If any path is in a subdirectory of another, remove the subdirectory.
-    duplicates = set()
-    for parent_path in paths:
-      for sub_path in paths:
-        if parent_path == sub_path:
-          continue
-        if os.path.commonprefix((parent_path, sub_path)) == parent_path:
-          duplicates.add(sub_path)
-    paths -= duplicates
-
-    if self.http_server:
-      if paths and self.http_server.paths == paths:
-        return False
-
-      self.http_server.Close()
-
-    if not paths:
-      return False
-
-    server = memory_cache_http_server.MemoryCacheHTTPServer(paths)
-    self.StartLocalServer(server)
-    return True
-
-  def StopAllLocalServers(self):
-    self._local_server_controller.Close()
-
-  @property
-  def local_servers(self):
-    """Returns the currently running local servers."""
-    return self._local_server_controller.local_servers
-
-  def HasBattOrConnected(self):
-    return  self._platform_backend.HasBattOrConnected()
-
-  def WaitForTemperature(self, temp):
-    return self._platform_backend.WaitForTemperature(temp)
diff --git a/catapult/telemetry/telemetry/core/platform_unittest.py b/catapult/telemetry/telemetry/core/platform_unittest.py
deleted file mode 100644
index 5a838d2..0000000
--- a/catapult/telemetry/telemetry/core/platform_unittest.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import tempfile
-
-from telemetry import decorators
-from telemetry.core import os_version
-from telemetry.util import image_util
-from telemetry.testing import tab_test_case
-
-
-class PlatformScreenshotTest(tab_test_case.TabTestCase):
-
-  def testScreenshotSupported(self):
-    if self._platform.GetOSName() == 'android':
-      self.assertTrue(self._platform.CanTakeScreenshot())
-
-  # Run this test in serial to avoid multiple browsers pop up on the screen.
-  @decorators.Isolated
-  @decorators.Disabled('linux')  # crbug.com/563656
-  @decorators.Disabled('mac')  # crbug.com/660587
-  def testScreenshot(self):
-    if not self._platform.CanTakeScreenshot():
-      self.skipTest('Platform does not support screenshots, skipping test.')
-    # Skip the test on Mac 10.5, 10.6, 10.7 because png format isn't
-    # recognizable on Mac < 10.8 (crbug.com/369490#c13)
-    if (self._platform.GetOSName() == 'mac' and
-        self._platform.GetOSVersionName() in
-        (os_version.LEOPARD, os_version.SNOWLEOPARD, os_version.LION)):
-      self.skipTest('OS X version %s too old' % self._platform.GetOSName())
-    tf = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
-    tf.close()
-    try:
-      self.Navigate('screenshot_test.html')
-      self._platform.TakeScreenshot(tf.name)
-      # Assert that screenshot image contains the color of the triangle defined
-      # in screenshot_test.html.
-      img = image_util.FromPngFile(tf.name)
-      screenshot_pixels = image_util.Pixels(img)
-      special_colored_pixel = bytearray([217, 115, 43])
-      self.assertTrue(special_colored_pixel in screenshot_pixels)
-    finally:
-      os.remove(tf.name)
diff --git a/catapult/telemetry/telemetry/core/profiling_controller.py b/catapult/telemetry/telemetry/core/profiling_controller.py
deleted file mode 100644
index 0e008a7..0000000
--- a/catapult/telemetry/telemetry/core/profiling_controller.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class ProfilingController(object):
-
-  def __init__(self, profiling_controller_backend):
-    self._profiling_controller_backend = profiling_controller_backend
-
-  def Start(self, profiler_name, base_output_file):
-    self._profiling_controller_backend.Start(profiler_name, base_output_file)
-
-  def Stop(self):
-    return self._profiling_controller_backend.Stop()
diff --git a/catapult/telemetry/telemetry/core/tracing_controller.py b/catapult/telemetry/telemetry/core/tracing_controller.py
deleted file mode 100644
index 1e26f7e..0000000
--- a/catapult/telemetry/telemetry/core/tracing_controller.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.platform import tracing_agent
-
-
-class TracingController(tracing_agent.TracingAgent):
-
-  def __init__(self, tracing_controller_backend):
-    """Provides control of the tracing systems supported by telemetry."""
-    super(TracingController, self).__init__(
-        tracing_controller_backend._platform_backend)
-    self._tracing_controller_backend = tracing_controller_backend
-
-  @property
-  def telemetry_info(self):
-    return self._tracing_controller_backend.telemetry_info
-
-  @telemetry_info.setter
-  def telemetry_info(self, ii):
-    self._tracing_controller_backend.telemetry_info = ii
-
-  def StartTracing(self, tracing_config, timeout=10):
-    """Starts tracing.
-
-    tracing config contains both tracing options and category filters.
-
-    trace_options specifies which tracing systems to activate. Category filter
-    allows fine-tuning of the data that are collected by the selected tracing
-    systems.
-
-    Some tracers are process-specific, e.g. chrome tracing, but are not
-    guaranteed to be supported. In order to support tracing of these kinds of
-    tracers, Start will succeed *always*, even if the tracing systems you have
-    requested are not supported.
-
-    If you absolutely require a particular tracer to exist, then check
-    for its support after you have started the process in question. Or, have
-    your code fail gracefully when the data you require is not present in the
-    resulting trace.
-    """
-    self._tracing_controller_backend.StartTracing(tracing_config, timeout)
-
-  def StopTracing(self):
-    """Stops tracing and returns a TraceValue."""
-    return self._tracing_controller_backend.StopTracing()
-
-  def FlushTracing(self):
-    """Flush tracing buffer and continue tracing.
-
-    Warning: This method is a temporary hack to enable multi-tab benchmarks
-    (see https://goo.gl/8Gjstr). Please contact Telemetry owners before using
-    it.
-    """
-    self._tracing_controller_backend.FlushTracing()
-
-  @property
-  def is_tracing_running(self):
-    return self._tracing_controller_backend.is_tracing_running
-
-  def IsChromeTracingSupported(self):
-    """Returns whether chrome tracing is supported."""
-    return self._tracing_controller_backend.IsChromeTracingSupported()
-
-  def StartAgentTracing(self, config, timeout=10):
-    """ Starts agent tracing for tracing controller"""
-    return self._tracing_controller_backend.StartAgentTracing(config, timeout)
-
-  def StopAgentTracing(self):
-    """ Stops agent tracing for tracing controller. """
-    return self._tracing_controller_backend.StopAgentTracing()
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    """ Collect tracing data. """
-    return self._tracing_controller_backend.CollectTraceData(trace_data_builder,
-                                                             timeout=timeout)
-
-  def SupportsExplicitClockSync(self):
-    return self._tracing_controller_backend.SupportsExplicitClockSync()
-
-  def RecordClockSyncMarker(self, sync_id,
-                            record_controller_clocksync_marker_callback):
-    return self._tracing_controller_backend.RecordClockSyncMarker(
-        sync_id, record_controller_clocksync_marker_callback)
-
-  def ClearStateIfNeeded(self):
-    """Clear tracing state if needed."""
-    self._tracing_controller_backend.ClearStateIfNeeded()
diff --git a/catapult/telemetry/telemetry/core/tracing_controller_unittest.py b/catapult/telemetry/telemetry/core/tracing_controller_unittest.py
deleted file mode 100644
index aaf6de6..0000000
--- a/catapult/telemetry/telemetry/core/tracing_controller_unittest.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-
-from battor import battor_wrapper
-from telemetry import decorators
-from telemetry.core import platform as platform_module
-from telemetry.testing import browser_test_case
-from telemetry.testing import tab_test_case
-from telemetry.timeline import model as model_module
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TracingControllerTest(tab_test_case.TabTestCase):
-
-  @decorators.Isolated
-  def testExceptionRaisedInStopTracing(self):
-    tracing_controller = self._tab.browser.platform.tracing_controller
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    tracing_controller.StartTracing(config)
-
-    self.Navigate('blank.html')
-
-    def _FakeStopChromeTracing(*args):
-      del args  # Unused
-      raise Exception('Intentional Tracing Exception')
-
-    self._tab._inspector_backend._devtools_client.StopChromeTracing = (
-      _FakeStopChromeTracing)
-    with self.assertRaisesRegexp(Exception, 'Intentional Tracing Exception'):
-      tracing_controller.StopTracing()
-
-    # Tracing is stopped even if there is exception.
-    self.assertFalse(tracing_controller.is_tracing_running)
-
-
-  @decorators.Isolated
-  def testGotTrace(self):
-    tracing_controller = self._browser.platform.tracing_controller
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    tracing_controller.StartTracing(config)
-
-    trace_data = tracing_controller.StopTracing()
-    # Test that trace data is parsable
-    model = model_module.TimelineModel(trace_data)
-    assert len(model.processes) > 0
-
-  @decorators.Isolated
-  def testStartAndStopTraceMultipleTimes(self):
-    tracing_controller = self._browser.platform.tracing_controller
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    tracing_controller.StartTracing(config)
-    self.assertFalse(tracing_controller.StartTracing(config))
-
-    trace_data = tracing_controller.StopTracing()
-    # Test that trace data is parsable
-    model_module.TimelineModel(trace_data)
-    self.assertFalse(tracing_controller.is_tracing_running)
-    # Calling stop again will raise exception
-    self.assertRaises(Exception, tracing_controller.StopTracing)
-
-  @decorators.Isolated
-  def testFlushTracing(self):
-    SUBTRACE_COUNT = 5
-
-    tab = self._browser.tabs[0]
-    def InjectMarker(index):
-      marker = 'test-marker-%d' % index
-      tab.EvaluateJavaScript('console.time({{ marker }});', marker=marker)
-      tab.EvaluateJavaScript('console.timeEnd({{ marker }});', marker=marker)
-
-    # Set up the tracing config.
-    tracing_controller = self._browser.platform.tracing_controller
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-
-    # Start tracing and inject a unique marker into the sub-trace.
-    tracing_controller.StartTracing(config)
-    self.assertTrue(tracing_controller.is_tracing_running)
-    InjectMarker(0)
-
-    # Flush tracing |SUBTRACE_COUNT - 1| times and inject a unique marker into
-    # the sub-trace each time.
-    for i in xrange(1, SUBTRACE_COUNT):
-      tracing_controller.FlushTracing()
-      self.assertTrue(tracing_controller.is_tracing_running)
-      InjectMarker(i)
-
-    # Stop tracing.
-    trace_data = tracing_controller.StopTracing()
-    self.assertFalse(tracing_controller.is_tracing_running)
-
-    # Test that trace data is parsable
-    model = model_module.TimelineModel(trace_data)
-
-    # Check that the markers 'test-marker-0', 'flush-tracing', 'test-marker-1',
-    # ..., 'flush-tracing', 'test-marker-|SUBTRACE_COUNT - 1|' are monotonic.
-    custom_markers = [marker for i in xrange(SUBTRACE_COUNT)
-                      for marker in model.FindTimelineMarkers(
-                          'test-marker-%d' % i)]
-    flush_markers = model.FindTimelineMarkers(
-        ['flush-tracing'] * (SUBTRACE_COUNT - 1))
-    markers = [marker for group in zip(custom_markers, flush_markers)
-               for marker in group] + custom_markers[-1:]
-
-    self.assertEquals(len(custom_markers), SUBTRACE_COUNT)
-    self.assertEquals(len(flush_markers), SUBTRACE_COUNT - 1)
-    self.assertEquals(len(markers), 2 * SUBTRACE_COUNT - 1)
-
-    for i in xrange(1, len(markers)):
-      self.assertLess(markers[i - 1].end, markers[i].start)
-
-  def _StartupTracing(self, platform):
-    # Stop browser
-    browser_test_case.teardown_browser()
-
-    # Start tracing
-    self.assertFalse(platform.tracing_controller.is_tracing_running)
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    platform.tracing_controller.StartTracing(config)
-    self.assertTrue(platform.tracing_controller.is_tracing_running)
-
-    try:
-      # Start browser
-      self.setUpClass()
-      self._browser.tabs[0].Navigate('about:blank')
-      self._browser.tabs[0].WaitForDocumentReadyStateToBeInteractiveOrBetter()
-      self.assertEquals(platform, self._browser.platform)
-
-      # Calling start tracing again will return False
-      self.assertFalse(platform.tracing_controller.StartTracing(config))
-
-      trace_data = platform.tracing_controller.StopTracing()
-      # Test that trace data is parsable
-      model_module.TimelineModel(trace_data)
-      self.assertFalse(platform.tracing_controller.is_tracing_running)
-      # Calling stop tracing again will raise exception
-      self.assertRaises(Exception, platform.tracing_controller.StopTracing)
-    finally:
-      if platform.tracing_controller.is_tracing_running:
-        platform.tracing_controller.StopTracing()
-      if self._browser:
-        self._browser.Close()
-        self._browser = None
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  @decorators.Isolated
-  def testStartupTracingOnAndroid(self):
-    self._StartupTracing(self._browser.platform)
-
-  @decorators.Enabled('chromeos')
-  @decorators.Isolated
-  def testStartupTracingOnCrOS(self):
-    self._StartupTracing(self._browser.platform)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  @decorators.Isolated
-  def testStartupTracingOnDesktop(self):
-    self._StartupTracing(platform_module.GetHostPlatform())
-
-  @decorators.Disabled('linux')  # crbug.com/673761
-  def testBattOrTracing(self):
-    test_platform = self._browser.platform.GetOSName()
-    device = (self._browser.platform._platform_backend.device
-              if test_platform == 'android' else None)
-    if (not battor_wrapper.IsBattOrConnected(test_platform,
-                                             android_device=device)):
-      return # Do not run the test if no BattOr is connected.
-
-    tracing_controller = self._browser.platform.tracing_controller
-    config = tracing_config.TracingConfig()
-    config.enable_battor_trace = True
-    tracing_controller.StartTracing(config)
-    # We wait 1s before starting and stopping tracing to avoid crbug.com/602266,
-    # which would cause a crash otherwise.
-    time.sleep(1)
-    trace_data = tracing_controller.StopTracing()
-    self.assertTrue(
-        trace_data.HasTracesFor(trace_data_module.BATTOR_TRACE_PART))
diff --git a/catapult/telemetry/telemetry/core/util.py b/catapult/telemetry/telemetry/core/util.py
deleted file mode 100644
index cf44603..0000000
--- a/catapult/telemetry/telemetry/core/util.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import glob
-import imp
-import os
-import socket
-import sys
-
-from telemetry import decorators
-
-import py_utils as catapult_util  # pylint: disable=import-error
-
-
-IsRunningOnCrosDevice = catapult_util.IsRunningOnCrosDevice
-GetCatapultDir = catapult_util.GetCatapultDir
-
-
-def GetBaseDir():
-  main_module = sys.modules['__main__']
-  if hasattr(main_module, '__file__'):
-    return os.path.dirname(os.path.abspath(main_module.__file__))
-  else:
-    return os.getcwd()
-
-
-def GetCatapultThirdPartyDir():
-  return os.path.normpath(os.path.join(GetCatapultDir(), 'third_party'))
-
-
-def GetTelemetryDir():
-  return os.path.normpath(os.path.join(
-      os.path.abspath(__file__), '..', '..', '..'))
-
-
-def GetTelemetryThirdPartyDir():
-  return os.path.join(GetTelemetryDir(), 'third_party')
-
-
-def GetUnittestDataDir():
-  return os.path.join(GetTelemetryDir(), 'telemetry', 'internal', 'testing')
-
-
-def GetChromiumSrcDir():
-  return os.path.normpath(os.path.join(GetTelemetryDir(), '..', '..', '..'))
-
-
-_counter = [0]
-
-
-def _GetUniqueModuleName():
-  _counter[0] += 1
-  return "page_set_module_" + str(_counter[0])
-
-
-def GetPythonPageSetModule(file_path):
-  return imp.load_source(_GetUniqueModuleName(), file_path)
-
-
-@decorators.Deprecated(
-    2017, 6, 1,
-    'telemetry.core.utils.WaitFor() is being deprecated. Please use '
-    'catapult.common.py_utils.WaitFor() instead.')
-def WaitFor(condition, timeout):
-  return catapult_util.WaitFor(condition, timeout)
-
-
-class PortKeeper(object):
-  """Port keeper hold an available port on the system.
-
-  Before actually use the port, you must call Release().
-  """
-
-  def __init__(self):
-    self._temp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    self._temp_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-    self._temp_socket.bind(('', 0))
-    self._port = self._temp_socket.getsockname()[1]
-
-  @property
-  def port(self):
-    return self._port
-
-  def Release(self):
-    assert self._temp_socket, 'Already released'
-    self._temp_socket.close()
-    self._temp_socket = None
-
-
-def GetUnreservedAvailableLocalPort():
-  """Returns an available port on the system.
-
-  WARNING: This method does not reserve the port it returns, so it may be used
-  by something else before you get to use it. This can lead to flake.
-  """
-  tmp = socket.socket()
-  tmp.bind(('', 0))
-  port = tmp.getsockname()[1]
-  tmp.close()
-
-  return port
-
-
-def GetBuildDirectories(chrome_root=None):
-  """Yields all combination of Chromium build output directories."""
-  # chrome_root can be set to something else via --chrome-root.
-  if not chrome_root:
-    chrome_root = GetChromiumSrcDir()
-
-  # CHROMIUM_OUTPUT_DIR can be set by --chromium-output-directory.
-  output_dir = os.environ.get('CHROMIUM_OUTPUT_DIR')
-  if output_dir:
-    yield os.path.join(chrome_root, output_dir)
-  elif os.path.exists('build.ninja'):
-    yield os.getcwd()
-  else:
-    out_dir = os.environ.get('CHROMIUM_OUT_DIR')
-    if out_dir:
-      build_dirs = [out_dir]
-    else:
-      build_dirs = ['build',
-                    'out',
-                    'xcodebuild']
-
-    build_types = ['Debug', 'Debug_x64', 'Release', 'Release_x64', 'Default']
-
-    for build_dir in build_dirs:
-      for build_type in build_types:
-        yield os.path.join(chrome_root, build_dir, build_type)
-
-
-def GetSequentialFileName(base_name):
-  """Returns the next sequential file name based on |base_name| and the
-  existing files. base_name should not contain extension.
-  e.g: if base_name is /tmp/test, and /tmp/test_000.json,
-  /tmp/test_001.mp3 exist, this returns /tmp/test_002. In case no
-  other sequential file name exist, this will return /tmp/test_000
-  """
-  name, ext = os.path.splitext(base_name)
-  assert ext == '', 'base_name cannot contain file extension.'
-  index = 0
-  while True:
-    output_name = '%s_%03d' % (name, index)
-    if not glob.glob(output_name + '.*'):
-      break
-    index = index + 1
-  return output_name
diff --git a/catapult/telemetry/telemetry/core/util_unittest.py b/catapult/telemetry/telemetry/core/util_unittest.py
deleted file mode 100644
index 75110ad..0000000
--- a/catapult/telemetry/telemetry/core/util_unittest.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import shutil
-import tempfile
-import unittest
-
-from telemetry.core import util
-
-
-class TestGetSequentialFileName(unittest.TestCase):
-
-  def __init__(self, *args, **kwargs):
-    super(TestGetSequentialFileName, self).__init__(*args, **kwargs)
-    self.test_directory = None
-
-  def setUp(self):
-    self.test_directory = tempfile.mkdtemp()
-
-  def testGetSequentialFileNameNoOtherSequentialFile(self):
-    next_json_test_file_path = util.GetSequentialFileName(os.path.join(
-        self.test_directory, 'test'))
-    self.assertEquals(
-        os.path.join(self.test_directory, 'test_000'), next_json_test_file_path)
-
-  def testGetSequentialFileNameWithOtherSequentialFiles(self):
-    # Create test_000.json, test_001.json, test_002.json in test directory.
-    for i in xrange(3):
-      with open(
-          os.path.join(self.test_directory, 'test_%03d.json' % i), 'w') as _:
-        pass
-    next_json_test_file_path = util.GetSequentialFileName(os.path.join(
-        self.test_directory, 'test'))
-    self.assertEquals(
-        os.path.join(self.test_directory, 'test_003'), next_json_test_file_path)
-
-  def tearDown(self):
-    shutil.rmtree(self.test_directory)
diff --git a/catapult/telemetry/telemetry/decorators.py b/catapult/telemetry/telemetry/decorators.py
deleted file mode 100644
index 1192782..0000000
--- a/catapult/telemetry/telemetry/decorators.py
+++ /dev/null
@@ -1,343 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-# pylint: disable=protected-access
-
-import datetime
-import functools
-import os
-import inspect
-import types
-import warnings
-
-
-def Cache(obj):
-  """Decorator for caching read-only properties.
-
-  Example usage (always returns the same Foo instance):
-    @Cache
-    def CreateFoo():
-      return Foo()
-
-  If CreateFoo() accepts parameters, a separate cached value is maintained
-  for each unique parameter combination.
-
-  Cached methods maintain their cache for the lifetime of the /instance/, while
-  cached functions maintain their cache for the lifetime of the /module/.
-  """
-  @functools.wraps(obj)
-  def Cacher(*args, **kwargs):
-    cacher = args[0] if inspect.getargspec(obj).args[:1] == ['self'] else obj
-    cacher.__cache = cacher.__cache if hasattr(cacher, '__cache') else {}
-    key = str(obj) + str(args) + str(kwargs)
-    if key not in cacher.__cache:
-      cacher.__cache[key] = obj(*args, **kwargs)
-    return cacher.__cache[key]
-  return Cacher
-
-
-class Deprecated(object):
-
-  def __init__(self, year, month, day, extra_guidance=''):
-    self._date_of_support_removal = datetime.date(year, month, day)
-    self._extra_guidance = extra_guidance
-
-  def _DisplayWarningMessage(self, target):
-    target_str = ''
-    if isinstance(target, types.FunctionType):
-      target_str = 'Function %s' % target.__name__
-    else:
-      target_str = 'Class %s' % target.__name__
-    warnings.warn('%s is deprecated. It will no longer be supported on %s. '
-                  'Please remove it or switch to an alternative before '
-                  'that time. %s\n'
-                  % (target_str,
-                     self._date_of_support_removal.strftime('%B %d, %Y'),
-                     self._extra_guidance),
-                  stacklevel=self._ComputeStackLevel())
-
-  def _ComputeStackLevel(self):
-    this_file, _ = os.path.splitext(__file__)
-    frame = inspect.currentframe()
-    i = 0
-    while True:
-      filename = frame.f_code.co_filename
-      if not filename.startswith(this_file):
-        return i
-      frame = frame.f_back
-      i += 1
-
-  def __call__(self, target):
-    if isinstance(target, types.FunctionType):
-      @functools.wraps(target)
-      def wrapper(*args, **kwargs):
-        self._DisplayWarningMessage(target)
-        return target(*args, **kwargs)
-      return wrapper
-    elif inspect.isclass(target):
-      original_ctor = target.__init__
-
-      # We have to handle case original_ctor is object.__init__ separately
-      # since object.__init__ does not have __module__ defined, which
-      # cause functools.wraps() to raise exception.
-      if original_ctor == object.__init__:
-        def new_ctor(*args, **kwargs):
-          self._DisplayWarningMessage(target)
-          return original_ctor(*args, **kwargs)
-      else:
-        @functools.wraps(original_ctor)
-        def new_ctor(*args, **kwargs):
-          self._DisplayWarningMessage(target)
-          return original_ctor(*args, **kwargs)
-
-      target.__init__ = new_ctor
-      return target
-    else:
-      raise TypeError('@Deprecated is only applicable to functions or classes')
-
-
-def Disabled(*args):
-  """Decorator for disabling tests/benchmarks.
-
-
-  If args are given, the test will be disabled if ANY of the args match the
-  browser type, OS name or OS version:
-    @Disabled('canary')        # Disabled for canary browsers
-    @Disabled('win')           # Disabled on Windows.
-    @Disabled('win', 'linux')  # Disabled on both Windows and Linux.
-    @Disabled('mavericks')     # Disabled on Mac Mavericks (10.9) only.
-    @Disabled('all')  # Unconditionally disabled.
-  """
-  def _Disabled(func):
-    disabled_attr_name = DisabledAttributeName(func)
-    if not hasattr(func, disabled_attr_name):
-      setattr(func, disabled_attr_name, set())
-    disabled_set = getattr(func, disabled_attr_name)
-    disabled_set.update(disabled_strings)
-    setattr(func, disabled_attr_name, disabled_set)
-    return func
-  assert args, (
-      "@Disabled(...) requires arguments. Use @Disabled('all') if you want to "
-      'unconditionally disable the test.')
-  assert not callable(args[0]), 'Please use @Disabled(..).'
-  disabled_strings = list(args)
-  for disabled_string in disabled_strings:
-    # TODO(tonyg): Validate that these strings are recognized.
-    assert isinstance(disabled_string, str), '@Disabled accepts a list of strs'
-  return _Disabled
-
-
-def Enabled(*args):
-  """Decorator for enabling tests/benchmarks.
-
-  The test will be enabled if ANY of the args match the browser type, OS name
-  or OS version:
-    @Enabled('canary')        # Enabled only for canary browsers
-    @Enabled('win')           # Enabled only on Windows.
-    @Enabled('win', 'linux')  # Enabled only on Windows or Linux.
-    @Enabled('mavericks')     # Enabled only on Mac Mavericks (10.9).
-  """
-  def _Enabled(func):
-    enabled_attr_name = EnabledAttributeName(func)
-    if not hasattr(func, enabled_attr_name):
-      setattr(func, enabled_attr_name, set())
-    enabled_set = getattr(func, enabled_attr_name)
-    enabled_set.update(enabled_strings)
-    setattr(func, enabled_attr_name, enabled_set)
-    return func
-  assert args, '@Enabled(..) requires arguments'
-  assert not callable(args[0]), 'Please use @Enabled(..).'
-  enabled_strings = list(args)
-  for enabled_string in enabled_strings:
-    # TODO(tonyg): Validate that these strings are recognized.
-    assert isinstance(enabled_string, str), '@Enabled accepts a list of strs'
-  return _Enabled
-
-
-def Owner(emails=None, component=None):
-  """Decorator for specifying the owner of a benchmark."""
-  def _Owner(func):
-    owner_attr_name = OwnerAttributeName(func)
-    assert inspect.isclass(func), '@Owner(...) can only be used on classes'
-    if not hasattr(func, owner_attr_name):
-      setattr(func, owner_attr_name, {})
-    owner_dict = getattr(func, owner_attr_name)
-    if emails:
-      assert 'emails' not in owner_dict, 'emails can only be set once'
-      owner_dict['emails'] = emails
-    if component:
-      assert 'component' not in owner_dict, 'component can only be set once'
-      owner_dict['component'] = component
-    setattr(func, owner_attr_name, owner_dict)
-    return func
-  help_text = '@Owner(...) requires emails and/or a component'
-  assert emails or component, help_text
-  if emails:
-    assert isinstance(emails, list), 'emails must be a list of strs'
-    for e in emails:
-      assert isinstance(e, str), 'emails must be a list of strs'
-  return _Owner
-
-
-# TODO(dpranke): Remove if we don't need this.
-def Isolated(*args):
-  """Decorator for noting that tests must be run in isolation.
-
-  The test will be run by itself (not concurrently with any other tests)
-  if ANY of the args match the browser type, OS name, or OS version."""
-  def _Isolated(func):
-    if not isinstance(func, types.FunctionType):
-      func._isolated_strings = isolated_strings
-      return func
-    @functools.wraps(func)
-    def wrapper(*args, **kwargs):
-      func(*args, **kwargs)
-    wrapper._isolated_strings = isolated_strings
-    return wrapper
-  if len(args) == 1 and callable(args[0]):
-    isolated_strings = []
-    return _Isolated(args[0])
-  isolated_strings = list(args)
-  for isolated_string in isolated_strings:
-    # TODO(tonyg): Validate that these strings are recognized.
-    assert isinstance(isolated_string, str), 'Isolated accepts a list of strs'
-  return _Isolated
-
-
-# TODO(nednguyen): Remove this and have call site just use ShouldSkip directly.
-def IsEnabled(test, possible_browser):
-  """Returns True iff |test| is enabled given the |possible_browser|.
-
-  Use to respect the @Enabled / @Disabled decorators.
-
-  Args:
-    test: A function or class that may contain _disabled_strings and/or
-          _enabled_strings attributes.
-    possible_browser: A PossibleBrowser to check whether |test| may run against.
-  """
-  should_skip, msg = ShouldSkip(test, possible_browser)
-  return (not should_skip, msg)
-
-
-def IsBenchmarkEnabled(benchmark, possible_browser):
-  return (not benchmark.ShouldDisable(possible_browser) and
-          IsEnabled(benchmark, possible_browser)[0])
-
-
-def _TestName(test):
-  if inspect.ismethod(test):
-    # On methods, __name__ is "instancemethod", use __func__.__name__ instead.
-    test = test.__func__
-  if hasattr(test, '__name__'):
-    return test.__name__
-  elif hasattr(test, '__class__'):
-    return test.__class__.__name__
-  return str(test)
-
-
-def DisabledAttributeName(test):
-  name = _TestName(test)
-  return '_%s_%s_disabled_strings' % (test.__module__, name)
-
-
-def GetDisabledAttributes(test):
-  disabled_attr_name = DisabledAttributeName(test)
-  if not hasattr(test, disabled_attr_name):
-    return set()
-  return set(getattr(test, disabled_attr_name))
-
-
-def GetEnabledAttributes(test):
-  enabled_attr_name = EnabledAttributeName(test)
-  if not hasattr(test, enabled_attr_name):
-    return set()
-  enabled_strings = set(getattr(test, enabled_attr_name))
-  return enabled_strings
-
-
-def EnabledAttributeName(test):
-  name = _TestName(test)
-  return '_%s_%s_enabled_strings' % (test.__module__, name)
-
-
-def OwnerAttributeName(test):
-  name = _TestName(test)
-  return '_%s_%s_owner' % (test.__module__, name)
-
-
-def GetEmails(test):
-  owner_attr_name = OwnerAttributeName(test)
-  owner = getattr(test, owner_attr_name, {})
-  if 'emails' in owner:
-    return owner['emails']
-  return None
-
-
-def GetComponent(test):
-  owner_attr_name = OwnerAttributeName(test)
-  owner = getattr(test, owner_attr_name, {})
-  if 'component' in owner:
-    return owner['component']
-  return None
-
-
-def ShouldSkip(test, possible_browser):
-  """Returns whether the test should be skipped and the reason for it."""
-  platform_attributes = _PlatformAttributes(possible_browser)
-
-  name = _TestName(test)
-  skip = 'Skipping %s (%s) because' % (name, str(test))
-  running = 'You are running %r.' % platform_attributes
-
-  disabled_attr_name = DisabledAttributeName(test)
-  if hasattr(test, disabled_attr_name):
-    disabled_strings = getattr(test, disabled_attr_name)
-    if 'all' in disabled_strings:
-      return (True, '%s it is unconditionally disabled.' % skip)
-    if set(disabled_strings) & set(platform_attributes):
-      return (True, '%s it is disabled for %s. %s' %
-                      (skip, ' and '.join(disabled_strings), running))
-
-  enabled_attr_name = EnabledAttributeName(test)
-  if hasattr(test, enabled_attr_name):
-    enabled_strings = getattr(test, enabled_attr_name)
-    if 'all' in enabled_strings:
-      return False, None  # No arguments to @Enabled means always enable.
-    if not set(enabled_strings) & set(platform_attributes):
-      return (True, '%s it is only enabled for %s. %s' %
-                      (skip, ' or '.join(enabled_strings), running))
-
-  return False, None
-
-
-def ShouldBeIsolated(test, possible_browser):
-  platform_attributes = _PlatformAttributes(possible_browser)
-  if hasattr(test, '_isolated_strings'):
-    isolated_strings = test._isolated_strings
-    if not isolated_strings:
-      return True # No arguments to @Isolated means always isolate.
-    for isolated_string in isolated_strings:
-      if isolated_string in platform_attributes:
-        return True
-    return False
-  return False
-
-
-def _PlatformAttributes(possible_browser):
-  """Returns a list of platform attribute strings."""
-  attributes = [a.lower() for a in [
-      possible_browser.browser_type,
-      possible_browser.platform.GetOSName(),
-      possible_browser.platform.GetOSVersionName(),
-  ]]
-  if possible_browser.supports_tab_control:
-    attributes.append('has tabs')
-  if 'content-shell' in possible_browser.browser_type:
-    attributes.append('content-shell')
-  if possible_browser.browser_type == 'reference':
-    ref_attributes = []
-    for attribute in attributes:
-      if attribute != 'reference':
-        ref_attributes.append('%s-reference' % attribute)
-    attributes.extend(ref_attributes)
-  return attributes
diff --git a/catapult/telemetry/telemetry/decorators_unittest.py b/catapult/telemetry/telemetry/decorators_unittest.py
deleted file mode 100644
index 1c02648..0000000
--- a/catapult/telemetry/telemetry/decorators_unittest.py
+++ /dev/null
@@ -1,528 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import mock
-
-from telemetry.core import platform
-from telemetry import decorators
-from telemetry.internal.browser import possible_browser
-
-
-class FakeTest(object):
-
-  def SetEnabledStrings(self, enabled_strings):
-    enabled_attr_name = decorators.EnabledAttributeName(self)
-    setattr(self, enabled_attr_name, enabled_strings)
-
-  def SetDisabledStrings(self, disabled_strings):
-    # pylint: disable=attribute-defined-outside-init
-    disabled_attr_name = decorators.DisabledAttributeName(self)
-    setattr(self, disabled_attr_name, disabled_strings)
-
-
-class TestDisableDecorators(unittest.TestCase):
-
-  def testDisabledStringOnFunction(self):
-
-    @decorators.Disabled('bar')
-    def Sum():
-      return 1 + 1
-
-    self.assertEquals({'bar'}, decorators.GetDisabledAttributes(Sum))
-
-    @decorators.Disabled('bar')
-    @decorators.Disabled('baz')
-    @decorators.Disabled('bart', 'baz')
-    def Product():
-      return 1 * 1
-
-    self.assertEquals({'bar', 'bart', 'baz'},
-                      decorators.GetDisabledAttributes(Product))
-
-  def testDisabledStringOnClass(self):
-
-    @decorators.Disabled('windshield')
-    class Ford(object):
-      pass
-
-    self.assertEquals({'windshield'}, decorators.GetDisabledAttributes(Ford))
-
-    @decorators.Disabled('windows', 'Drive')
-    @decorators.Disabled('wheel')
-    @decorators.Disabled('windows')
-    class Honda(object):
-      pass
-
-    self.assertEquals({'windshield'}, decorators.GetDisabledAttributes(Ford))
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetDisabledAttributes(Honda))
-
-  def testDisabledStringOnSubClass(self):
-
-    @decorators.Disabled('windshield')
-    class Car(object):
-      pass
-
-    class Ford(Car):
-      pass
-
-    self.assertEquals({'windshield'}, decorators.GetDisabledAttributes(Car))
-    self.assertFalse(decorators.GetDisabledAttributes(Ford))
-
-    @decorators.Disabled('windows', 'Drive')
-    @decorators.Disabled('wheel')
-    @decorators.Disabled('windows')
-    class Honda(Car):
-      pass
-
-    self.assertFalse(decorators.GetDisabledAttributes(Ford))
-    self.assertEquals({'windshield'}, decorators.GetDisabledAttributes(Car))
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetDisabledAttributes(Honda))
-
-  def testDisabledStringOnMethod(self):
-
-    class Ford(object):
-
-      @decorators.Disabled('windshield')
-      def Drive(self):
-        pass
-
-    self.assertEquals({'windshield'},
-                      decorators.GetDisabledAttributes(Ford().Drive))
-
-    class Honda(object):
-
-      @decorators.Disabled('windows', 'Drive')
-      @decorators.Disabled('wheel')
-      @decorators.Disabled('windows')
-      def Drive(self):
-        pass
-
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetDisabledAttributes(Honda().Drive))
-    self.assertEquals({'windshield'},
-                      decorators.GetDisabledAttributes(Ford().Drive))
-
-    class Accord(Honda):
-
-      def Drive(self):
-        pass
-
-    class Explorer(Ford):
-      pass
-
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetDisabledAttributes(Honda().Drive))
-    self.assertEquals({'windshield'},
-                      decorators.GetDisabledAttributes(Ford().Drive))
-    self.assertEquals({'windshield'},
-                      decorators.GetDisabledAttributes(Explorer().Drive))
-    self.assertFalse(decorators.GetDisabledAttributes(Accord().Drive))
-
-
-class TestEnableDecorators(unittest.TestCase):
-
-  def testEnabledStringOnFunction(self):
-
-    @decorators.Enabled('minus', 'power')
-    def Sum():
-      return 1 + 1
-
-    self.assertEquals({'minus', 'power'}, decorators.GetEnabledAttributes(Sum))
-
-    @decorators.Enabled('dot')
-    @decorators.Enabled('product')
-    @decorators.Enabled('product', 'dot')
-    def Product():
-      return 1 * 1
-
-    self.assertEquals({'dot', 'product'},
-                      decorators.GetEnabledAttributes(Product))
-
-  def testEnabledStringOnClass(self):
-
-    @decorators.Enabled('windshield', 'light')
-    class Ford(object):
-      pass
-
-    self.assertEquals({'windshield', 'light'},
-                      decorators.GetEnabledAttributes(Ford))
-
-    @decorators.Enabled('wheel', 'Drive')
-    @decorators.Enabled('wheel')
-    @decorators.Enabled('windows')
-    class Honda(object):
-      pass
-
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetEnabledAttributes(Honda))
-    self.assertEquals({'windshield', 'light'},
-                      decorators.GetEnabledAttributes(Ford))
-
-  def testEnabledStringOnSubClass(self):
-
-    @decorators.Enabled('windshield')
-    class Car(object):
-      pass
-
-    class Ford(Car):
-      pass
-
-    self.assertEquals({'windshield'}, decorators.GetEnabledAttributes(Car))
-    self.assertFalse(decorators.GetEnabledAttributes(Ford))
-
-    @decorators.Enabled('windows', 'Drive')
-    @decorators.Enabled('wheel')
-    @decorators.Enabled('windows')
-    class Honda(Car):
-      pass
-
-    self.assertFalse(decorators.GetEnabledAttributes(Ford))
-    self.assertEquals({'windshield'}, decorators.GetEnabledAttributes(Car))
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetEnabledAttributes(Honda))
-
-  def testEnabledStringOnMethod(self):
-
-    class Ford(object):
-
-      @decorators.Enabled('windshield')
-      def Drive(self):
-        pass
-
-    self.assertEquals({'windshield'},
-                      decorators.GetEnabledAttributes(Ford().Drive))
-
-    class Honda(object):
-
-      @decorators.Enabled('windows', 'Drive')
-      @decorators.Enabled('wheel', 'Drive')
-      @decorators.Enabled('windows')
-      def Drive(self):
-        pass
-
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetEnabledAttributes(Honda().Drive))
-
-    class Accord(Honda):
-
-      def Drive(self):
-        pass
-
-    class Explorer(Ford):
-      pass
-
-    self.assertEquals({'wheel', 'Drive', 'windows'},
-                      decorators.GetEnabledAttributes(Honda().Drive))
-    self.assertEquals({'windshield'},
-                      decorators.GetEnabledAttributes(Ford().Drive))
-    self.assertEquals({'windshield'},
-                      decorators.GetEnabledAttributes(Explorer().Drive))
-    self.assertFalse(decorators.GetEnabledAttributes(Accord().Drive))
-
-
-class TestOwnerDecorators(unittest.TestCase):
-
-  def testOwnerStringOnClass(self):
-
-    @decorators.Owner(emails=['owner@chromium.org'])
-    class Ford(object):
-      pass
-
-    self.assertEquals(['owner@chromium.org'], decorators.GetEmails(Ford))
-
-    @decorators.Owner(emails=['owner2@chromium.org'])
-    @decorators.Owner(component='component')
-    class Honda(object):
-      pass
-
-    self.assertEquals(['owner2@chromium.org'], decorators.GetEmails(Honda))
-    self.assertEquals('component', decorators.GetComponent(Honda))
-    self.assertEquals(['owner@chromium.org'], decorators.GetEmails(Ford))
-
-
-  def testOwnerStringOnSubClass(self):
-
-    @decorators.Owner(emails=['owner@chromium.org'], component='comp')
-    class Car(object):
-      pass
-
-    class Ford(Car):
-      pass
-
-    self.assertEquals(['owner@chromium.org'], decorators.GetEmails(Car))
-    self.assertEquals('comp', decorators.GetComponent(Car))
-    self.assertFalse(decorators.GetEmails(Ford))
-    self.assertFalse(decorators.GetComponent(Ford))
-
-
-  def testOwnerWithDuplicateAttributeSetting(self):
-
-    with self.assertRaises(AssertionError):
-      @decorators.Owner(emails=['owner2@chromium.org'])
-      @decorators.Owner(emails=['owner@chromium.org'], component='comp')
-      class Car(object):
-        pass
-
-      self.assertEquals(['owner@chromium.org'], decorators.GetEmails(Car))
-
-
-class TestShouldSkip(unittest.TestCase):
-
-  def setUp(self):
-    fake_platform = mock.Mock(spec_set=platform.Platform)
-    fake_platform.GetOSName.return_value = 'os_name'
-    fake_platform.GetOSVersionName.return_value = 'os_version_name'
-
-    self.possible_browser = mock.Mock(spec_set=possible_browser.PossibleBrowser)
-    self.possible_browser.browser_type = 'browser_type'
-    self.possible_browser.platform = fake_platform
-    self.possible_browser.supports_tab_control = False
-
-  def testEnabledStrings(self):
-    test = FakeTest()
-
-    # When no enabled_strings is given, everything should be enabled.
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_name'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_version_name'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_name', 'another_os_name'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name', 'os_name'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name', 'another_os_version_name'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_version_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_name-reference', 'another_os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name-reference', 'os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name-reference',
-                            'another_os_version_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-  def testDisabledStrings(self):
-    test = FakeTest()
-
-    # When no disabled_strings is given, nothing should be disabled.
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_name'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_version_name'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_name', 'another_os_name'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name', 'os_name'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name', 'another_os_version_name'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_version_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_name-reference', 'another_os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name-reference', 'os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name-reference',
-                             'another_os_version_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-  def testReferenceEnabledStrings(self):
-    self.possible_browser.browser_type = 'reference'
-    test = FakeTest()
-
-    # When no enabled_strings is given, everything should be enabled.
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_version_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['os_name-reference', 'another_os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name-reference', 'os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetEnabledStrings(['another_os_name-reference',
-                            'another_os_version_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-  def testReferenceDisabledStrings(self):
-    self.possible_browser.browser_type = 'reference'
-    test = FakeTest()
-
-    # When no disabled_strings is given, nothing should be disabled.
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_version_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['os_name-reference', 'another_os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name-reference', 'os_name-reference'])
-    self.assertTrue(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-    test.SetDisabledStrings(['another_os_name-reference',
-                             'another_os_version_name-reference'])
-    self.assertFalse(decorators.ShouldSkip(test, self.possible_browser)[0])
-
-
-class TestDeprecation(unittest.TestCase):
-
-  @mock.patch('warnings.warn')
-  def testFunctionDeprecation(self, warn_mock):
-
-    @decorators.Deprecated(2015, 12, 1)
-    def Foo(x):
-      return x
-
-    Foo(1)
-    warn_mock.assert_called_with(
-        'Function Foo is deprecated. It will no longer be supported on '
-        'December 01, 2015. Please remove it or switch to an alternative '
-        'before that time. \n',
-        stacklevel=4)
-
-  @mock.patch('warnings.warn')
-  def testMethodDeprecated(self, warn_mock):
-
-    class Bar(object):
-
-      @decorators.Deprecated(2015, 12, 1, 'Testing only.')
-      def Foo(self, x):
-        return x
-
-    Bar().Foo(1)
-    warn_mock.assert_called_with(
-        'Function Foo is deprecated. It will no longer be supported on '
-        'December 01, 2015. Please remove it or switch to an alternative '
-        'before that time. Testing only.\n',
-        stacklevel=4)
-
-  @mock.patch('warnings.warn')
-  def testClassWithoutInitDefinedDeprecated(self, warn_mock):
-
-    @decorators.Deprecated(2015, 12, 1)
-    class Bar(object):
-
-      def Foo(self, x):
-        return x
-
-    Bar().Foo(1)
-    warn_mock.assert_called_with(
-        'Class Bar is deprecated. It will no longer be supported on '
-        'December 01, 2015. Please remove it or switch to an alternative '
-        'before that time. \n',
-        stacklevel=4)
-
-  @mock.patch('warnings.warn')
-  def testClassWithInitDefinedDeprecated(self, warn_mock):
-
-    @decorators.Deprecated(2015, 12, 1)
-    class Bar(object):
-
-      def __init__(self):
-        pass
-
-      def Foo(self, x):
-        return x
-
-    Bar().Foo(1)
-    warn_mock.assert_called_with(
-        'Class Bar is deprecated. It will no longer be supported on '
-        'December 01, 2015. Please remove it or switch to an alternative '
-        'before that time. \n',
-        stacklevel=4)
-
-  @mock.patch('warnings.warn')
-  def testInheritedClassDeprecated(self, warn_mock):
-
-    class Ba(object):
-      pass
-
-    @decorators.Deprecated(2015, 12, 1)
-    class Bar(Ba):
-
-      def Foo(self, x):
-        return x
-
-    class Baz(Bar):
-      pass
-
-    Baz().Foo(1)
-    warn_mock.assert_called_with(
-        'Class Bar is deprecated. It will no longer be supported on '
-        'December 01, 2015. Please remove it or switch to an alternative '
-        'before that time. \n',
-        stacklevel=4)
-
-  def testReturnValue(self):
-
-    class Bar(object):
-
-      @decorators.Deprecated(2015, 12, 1, 'Testing only.')
-      def Foo(self, x):
-        return x
-
-    self.assertEquals(5, Bar().Foo(5))
diff --git a/catapult/telemetry/telemetry/internal/__init__.py b/catapult/telemetry/telemetry/internal/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/actions/__init__.py b/catapult/telemetry/telemetry/internal/actions/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/telemetry/internal/actions/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/telemetry/internal/actions/action_runner.py b/catapult/telemetry/telemetry/internal/actions/action_runner.py
deleted file mode 100644
index ec2a5ea..0000000
--- a/catapult/telemetry/telemetry/internal/actions/action_runner.py
+++ /dev/null
@@ -1,861 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-import urlparse
-
-from telemetry.core import exceptions
-from telemetry.internal.actions.drag import DragAction
-from telemetry.internal.actions.javascript_click import ClickElementAction
-from telemetry.internal.actions.key_event import KeyPressAction
-from telemetry.internal.actions.load_media import LoadMediaAction
-from telemetry.internal.actions.loop import LoopAction
-from telemetry.internal.actions.mouse_click import MouseClickAction
-from telemetry.internal.actions.navigate import NavigateAction
-from telemetry.internal.actions.page_action import GESTURE_SOURCE_DEFAULT
-from telemetry.internal.actions.page_action import SUPPORTED_GESTURE_SOURCES
-from telemetry.internal.actions.pinch import PinchAction
-from telemetry.internal.actions.play import PlayAction
-from telemetry.internal.actions.repaint_continuously import (
-    RepaintContinuouslyAction)
-from telemetry.internal.actions.repeatable_scroll import RepeatableScrollAction
-from telemetry.internal.actions.scroll import ScrollAction
-from telemetry.internal.actions.scroll_bounce import ScrollBounceAction
-from telemetry.internal.actions.scroll_to_element import ScrollToElementAction
-from telemetry.internal.actions.seek import SeekAction
-from telemetry.internal.actions.swipe import SwipeAction
-from telemetry.internal.actions.tap import TapAction
-from telemetry.internal.actions.wait import WaitForElementAction
-from telemetry.web_perf import timeline_interaction_record
-
-from py_trace_event import trace_event
-
-import py_utils
-
-
-_DUMP_WAIT_TIME = 3
-
-
-class ActionRunner(object):
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def __init__(self, tab, skip_waits=False):
-    self._tab = tab
-    self._skip_waits = skip_waits
-
-  @property
-  def tab(self):
-    """Returns the tab on which actions are performed."""
-    return self._tab
-
-  def _RunAction(self, action):
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-
-  def CreateInteraction(self, label, repeatable=False):
-    """ Create an action.Interaction object that issues interaction record.
-
-    An interaction record is a labeled time period containing
-    interaction that developers care about. Each set of metrics
-    specified in flags will be calculated for this time period.
-
-    To mark the start of interaction record, call Begin() method on the returned
-    object. To mark the finish of interaction record, call End() method on
-    it. Or better yet, use the with statement to create an
-    interaction record that covers the actions in the with block.
-
-    e.g:
-      with action_runner.CreateInteraction('Animation-1'):
-        action_runner.TapElement(...)
-        action_runner.WaitForJavaScriptCondition(...)
-
-    Args:
-      label: A label for this particular interaction. This can be any
-          user-defined string, but must not contain '/'.
-      repeatable: Whether other interactions may use the same logical name
-          as this interaction. All interactions with the same logical name must
-          have the same flags.
-
-    Returns:
-      An instance of action_runner.Interaction
-    """
-    flags = []
-    if repeatable:
-      flags.append(timeline_interaction_record.REPEATABLE)
-
-    return Interaction(self, label, flags)
-
-  def CreateGestureInteraction(self, label, repeatable=False):
-    """ Create an action.Interaction object that issues gesture-based
-    interaction record.
-
-    This is similar to normal interaction record, but it will
-    auto-narrow the interaction time period to only include the
-    synthetic gesture event output by Chrome. This is typically use to
-    reduce noise in gesture-based analysis (e.g., analysis for a
-    swipe/scroll).
-
-    The interaction record label will be prepended with 'Gesture_'.
-
-    e.g:
-      with action_runner.CreateGestureInteraction('Scroll-1'):
-        action_runner.ScrollPage()
-
-    Args:
-      label: A label for this particular interaction. This can be any
-          user-defined string, but must not contain '/'.
-      repeatable: Whether other interactions may use the same logical name
-          as this interaction. All interactions with the same logical name must
-          have the same flags.
-
-    Returns:
-      An instance of action_runner.Interaction
-    """
-    return self.CreateInteraction('Gesture_' + label, repeatable)
-
-  def WaitForNetworkQuiescence(self, timeout_in_seconds=10):
-    """ Wait for network quiesence on the page.
-    Args:
-      timeout_in_seconds: maximum amount of time (seconds) to wait for network
-        quiesence unil raising exception.
-
-    Raises:
-      py_utils.TimeoutException when the timeout is reached but the page's
-        network is not quiet.
-    """
-
-    py_utils.WaitFor(self.tab.HasReachedQuiescence, timeout_in_seconds)
-
-  def MeasureMemory(self, deterministic_mode=False):
-    """Add a memory measurement to the trace being recorded.
-
-    Behaves as a no-op if tracing is not enabled.
-
-    TODO(perezju): Also behave as a no-op if tracing is enabled but
-    memory-infra is not.
-
-    Args:
-      deterministic_mode: A boolean indicating whether to attempt or not to
-          control the environment (force GCs, clear caches) before making the
-          measurement in an attempt to obtain more deterministic results.
-
-    Returns:
-      GUID of the generated dump if one was triggered, None otherwise.
-    """
-    platform = self.tab.browser.platform
-    if not platform.tracing_controller.is_tracing_running:
-      logging.warning('Tracing is off. No memory dumps are being recorded.')
-      return None
-    if deterministic_mode:
-      self.Wait(_DUMP_WAIT_TIME)
-      self.ForceGarbageCollection()
-      if platform.SupportFlushEntireSystemCache():
-        platform.FlushEntireSystemCache()
-      self.Wait(_DUMP_WAIT_TIME)
-    dump_id = self.tab.browser.DumpMemory()
-    if not dump_id:
-      raise exceptions.Error('Unable to obtain memory dump')
-    return dump_id
-
-  def Navigate(self, url, script_to_evaluate_on_commit=None,
-               timeout_in_seconds=60):
-    """Navigates to |url|.
-
-    If |script_to_evaluate_on_commit| is given, the script source string will be
-    evaluated when the navigation is committed. This is after the context of
-    the page exists, but before any script on the page itself has executed.
-    """
-    if urlparse.urlparse(url).scheme == 'file':
-      url = self._tab.browser.platform.http_server.UrlOf(url[7:])
-
-    self._RunAction(NavigateAction(
-        url=url,
-        script_to_evaluate_on_commit=script_to_evaluate_on_commit,
-        timeout_in_seconds=timeout_in_seconds))
-
-  def NavigateBack(self):
-    """ Navigate back to the previous page."""
-    self.ExecuteJavaScript('window.history.back()')
-
-  def WaitForNavigate(self, timeout_in_seconds_seconds=60):
-    start_time = time.time()
-    self._tab.WaitForNavigate(timeout_in_seconds_seconds)
-
-    time_left_in_seconds = (start_time + timeout_in_seconds_seconds
-                            - time.time())
-    time_left_in_seconds = max(0, time_left_in_seconds)
-    self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter(
-        time_left_in_seconds)
-
-  def ReloadPage(self):
-    """Reloads the page."""
-    self._tab.ExecuteJavaScript('window.location.reload()')
-    self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-
-  def ExecuteJavaScript(self, *args, **kwargs):
-    """Executes a given JavaScript statement. Does not return the result.
-
-    Example: runner.ExecuteJavaScript('var foo = {{ value }};', value='hi');
-
-    Args:
-      statement: The statement to execute (provided as a string).
-
-    Optional keyword args:
-      timeout: The number of seconds to wait for the statement to execute.
-      Additional keyword arguments provide values to be interpolated within
-          the statement. See telemetry.util.js_template for details.
-
-    Raises:
-      EvaluationException: The statement failed to execute.
-    """
-    return self._tab.ExecuteJavaScript(*args, **kwargs)
-
-  def EvaluateJavaScript(self, *args, **kwargs):
-    """Returns the result of evaluating a given JavaScript expression.
-
-    The evaluation results must be convertible to JSON. If the result
-    is not needed, use ExecuteJavaScript instead.
-
-    Example: runner.ExecuteJavaScript('document.location.href');
-
-    Args:
-      expression: The expression to execute (provided as a string).
-
-    Optional keyword args:
-      timeout: The number of seconds to wait for the expression to evaluate.
-      Additional keyword arguments provide values to be interpolated within
-          the expression. See telemetry.util.js_template for details.
-
-    Raises:
-      EvaluationException: The statement expression failed to execute
-          or the evaluation result can not be JSON-ized.
-    """
-    return self._tab.EvaluateJavaScript(*args, **kwargs)
-
-  def WaitForJavaScriptCondition(self, *args, **kwargs):
-    """Wait for a JavaScript condition to become true.
-
-    Example: runner.WaitForJavaScriptCondition('window.foo == 10');
-
-    Args:
-      condition: The JavaScript condition (provided as string).
-
-    Optional keyword args:
-      timeout: The number in seconds to wait for the condition to become
-          True (default to 60).
-      Additional keyword arguments provide values to be interpolated within
-          the expression. See telemetry.util.js_template for details.
-    """
-    return self._tab.WaitForJavaScriptCondition(*args, **kwargs)
-
-  def Wait(self, seconds):
-    """Wait for the number of seconds specified.
-
-    Args:
-      seconds: The number of seconds to wait.
-    """
-    if not self._skip_waits:
-      time.sleep(seconds)
-
-  def WaitForElement(self, selector=None, text=None, element_function=None,
-                     timeout_in_seconds=60):
-    """Wait for an element to appear in the document.
-
-    The element may be selected via selector, text, or element_function.
-    Only one of these arguments must be specified.
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          '(function() { return foo.element; })()'.
-      timeout_in_seconds: The timeout in seconds (default to 60).
-    """
-    self._RunAction(WaitForElementAction(
-        selector=selector, text=text, element_function=element_function,
-        timeout_in_seconds=timeout_in_seconds))
-
-  def TapElement(self, selector=None, text=None, element_function=None):
-    """Tap an element.
-
-    The element may be selected via selector, text, or element_function.
-    Only one of these arguments must be specified.
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          '(function() { return foo.element; })()'.
-    """
-    self._RunAction(TapAction(
-        selector=selector, text=text, element_function=element_function))
-
-  def ClickElement(self, selector=None, text=None, element_function=None):
-    """Click an element.
-
-    The element may be selected via selector, text, or element_function.
-    Only one of these arguments must be specified.
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          '(function() { return foo.element; })()'.
-    """
-    self._RunAction(ClickElementAction(
-        selector=selector, text=text, element_function=element_function))
-
-  def DragPage(self, left_start_ratio, top_start_ratio, left_end_ratio,
-               top_end_ratio, speed_in_pixels_per_second=800, use_touch=False,
-               selector=None, text=None, element_function=None):
-    """Perform a drag gesture on the page.
-
-    You should specify a start and an end point in ratios of page width and
-    height (see drag.js for full implementation).
-
-    Args:
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      left_end_ratio: The horizontal ending coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_end_ratio: The vertical ending coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-      use_touch: Whether dragging should be done with touch input.
-    """
-    self._RunAction(DragAction(
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        left_end_ratio=left_end_ratio, top_end_ratio=top_end_ratio,
-        speed_in_pixels_per_second=speed_in_pixels_per_second,
-        use_touch=use_touch, selector=selector, text=text,
-        element_function=element_function))
-
-  def PinchPage(self, left_anchor_ratio=0.5, top_anchor_ratio=0.5,
-                scale_factor=None, speed_in_pixels_per_second=800):
-    """Perform the pinch gesture on the page.
-
-    It computes the pinch gesture automatically based on the anchor
-    coordinate and the scale factor. The scale factor is the ratio of
-    of the final span and the initial span of the gesture.
-
-    Args:
-      left_anchor_ratio: The horizontal pinch anchor coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_anchor_ratio: The vertical pinch anchor coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      scale_factor: The ratio of the final span to the initial span.
-          The default scale factor is
-          3.0 / (window.outerWidth/window.innerWidth).
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-    """
-    self._RunAction(PinchAction(
-        left_anchor_ratio=left_anchor_ratio, top_anchor_ratio=top_anchor_ratio,
-        scale_factor=scale_factor,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def PinchElement(self, selector=None, text=None, element_function=None,
-                   left_anchor_ratio=0.5, top_anchor_ratio=0.5,
-                   scale_factor=None, speed_in_pixels_per_second=800):
-    """Perform the pinch gesture on an element.
-
-    It computes the pinch gesture automatically based on the anchor
-    coordinate and the scale factor. The scale factor is the ratio of
-    of the final span and the initial span of the gesture.
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          'function() { return foo.element; }'.
-      left_anchor_ratio: The horizontal pinch anchor coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          the element.
-      top_anchor_ratio: The vertical pinch anchor coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          the element.
-      scale_factor: The ratio of the final span to the initial span.
-          The default scale factor is
-          3.0 / (window.outerWidth/window.innerWidth).
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-    """
-    self._RunAction(PinchAction(
-        selector=selector, text=text, element_function=element_function,
-        left_anchor_ratio=left_anchor_ratio, top_anchor_ratio=top_anchor_ratio,
-        scale_factor=scale_factor,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def ScrollPage(self, left_start_ratio=0.5, top_start_ratio=0.5,
-                 direction='down', distance=None, distance_expr=None,
-                 speed_in_pixels_per_second=800, use_touch=False,
-                 synthetic_gesture_source=GESTURE_SOURCE_DEFAULT):
-    """Perform scroll gesture on the page.
-
-    You may specify distance or distance_expr, but not both. If
-    neither is specified, the default scroll distance is variable
-    depending on direction (see scroll.js for full implementation).
-
-    Args:
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      direction: The direction of scroll, either 'left', 'right',
-          'up', 'down', 'upleft', 'upright', 'downleft', or 'downright'
-      distance: The distance to scroll (in pixel).
-      distance_expr: A JavaScript expression (as string) that can be
-          evaluated to compute scroll distance. Example:
-          'window.scrollTop' or '(function() { return crazyMath(); })()'.
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-      use_touch: Whether scrolling should be done with touch input.
-      synthetic_gesture_source: the source input device type for the
-          synthetic gesture: 'DEFAULT', 'TOUCH' or 'MOUSE'.
-    """
-    assert synthetic_gesture_source in SUPPORTED_GESTURE_SOURCES
-    self._RunAction(ScrollAction(
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        direction=direction, distance=distance, distance_expr=distance_expr,
-        speed_in_pixels_per_second=speed_in_pixels_per_second,
-        use_touch=use_touch, synthetic_gesture_source=synthetic_gesture_source))
-
-  def ScrollPageToElement(self, selector=None, element_function=None,
-                          container_selector=None,
-                          container_element_function=None,
-                          speed_in_pixels_per_second=800):
-    """Perform scroll gesture on container until an element is in view.
-
-    Both the element and the container can be specified by a CSS selector
-    xor a JavaScript function, provided as a string, which returns an element.
-    The element is required so exactly one of selector and element_function
-    must be provided. The container is optional so at most one of
-    container_selector and container_element_function can be provided.
-    The container defaults to document.scrollingElement or document.body if
-    scrollingElement is not set.
-
-    Args:
-      selector: A CSS selector describing the element.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          'function() { return foo.element; }'.
-      container_selector: A CSS selector describing the container element.
-      container_element_function: A JavaScript function (as a string) that is
-          used to retrieve the container element.
-      speed_in_pixels_per_second: Speed to scroll.
-    """
-    self._RunAction(ScrollToElementAction(
-        selector=selector, element_function=element_function,
-        container_selector=container_selector,
-        container_element_function=container_element_function,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def RepeatableBrowserDrivenScroll(self, x_scroll_distance_ratio=0.0,
-                                    y_scroll_distance_ratio=0.5,
-                                    repeat_count=0,
-                                    repeat_delay_ms=250,
-                                    timeout=60,
-                                    prevent_fling=None,
-                                    speed=None):
-    """Perform a browser driven repeatable scroll gesture.
-
-    The scroll gesture is driven from the browser, this is useful because the
-    main thread often isn't resposive but the browser process usually is, so the
-    delay between the scroll gestures should be consistent.
-
-    Args:
-      x_scroll_distance_ratio: The horizontal length of the scroll as a fraction
-          of the screen width.
-      y_scroll_distance_ratio: The vertical length of the scroll as a fraction
-          of the screen height.
-      repeat_count: The number of additional times to repeat the gesture.
-      repeat_delay_ms: The delay in milliseconds between each scroll gesture.
-      prevent_fling: Prevents a fling gesture.
-      speed: Swipe speed in pixels per second.
-    """
-    self._RunAction(RepeatableScrollAction(
-        x_scroll_distance_ratio=x_scroll_distance_ratio,
-        y_scroll_distance_ratio=y_scroll_distance_ratio,
-        repeat_count=repeat_count,
-        repeat_delay_ms=repeat_delay_ms, timeout=timeout,
-        prevent_fling=prevent_fling, speed=speed))
-
-  def ScrollElement(self, selector=None, text=None, element_function=None,
-                    left_start_ratio=0.5, top_start_ratio=0.5,
-                    direction='down', distance=None, distance_expr=None,
-                    speed_in_pixels_per_second=800, use_touch=False,
-                    synthetic_gesture_source=GESTURE_SOURCE_DEFAULT):
-    """Perform scroll gesture on the element.
-
-    The element may be selected via selector, text, or element_function.
-    Only one of these arguments must be specified.
-
-    You may specify distance or distance_expr, but not both. If
-    neither is specified, the default scroll distance is variable
-    depending on direction (see scroll.js for full implementation).
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          'function() { return foo.element; }'.
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          the element.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          the element.
-      direction: The direction of scroll, either 'left', 'right',
-          'up', 'down', 'upleft', 'upright', 'downleft', or 'downright'
-      distance: The distance to scroll (in pixel).
-      distance_expr: A JavaScript expression (as string) that can be
-          evaluated to compute scroll distance. Example:
-          'window.scrollTop' or '(function() { return crazyMath(); })()'.
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-      use_touch: Whether scrolling should be done with touch input.
-      synthetic_gesture_source: the source input device type for the
-          synthetic gesture: 'DEFAULT', 'TOUCH' or 'MOUSE'.
-    """
-    assert synthetic_gesture_source in SUPPORTED_GESTURE_SOURCES
-    self._RunAction(ScrollAction(
-        selector=selector, text=text, element_function=element_function,
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        direction=direction, distance=distance, distance_expr=distance_expr,
-        speed_in_pixels_per_second=speed_in_pixels_per_second,
-        use_touch=use_touch, synthetic_gesture_source=synthetic_gesture_source))
-
-  def ScrollBouncePage(self, left_start_ratio=0.5, top_start_ratio=0.5,
-                       direction='down', distance=100,
-                       overscroll=10, repeat_count=10,
-                       speed_in_pixels_per_second=400):
-    """Perform scroll bounce gesture on the page.
-
-    This gesture scrolls the page by the number of pixels specified in
-    distance, in the given direction, followed by a scroll by
-    (distance + overscroll) pixels in the opposite direction.
-    The above gesture is repeated repeat_count times.
-
-    Args:
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      direction: The direction of scroll, either 'left', 'right',
-          'up', 'down', 'upleft', 'upright', 'downleft', or 'downright'
-      distance: The distance to scroll (in pixel).
-      overscroll: The number of additional pixels to scroll back, in
-          addition to the givendistance.
-      repeat_count: How often we want to repeat the full gesture.
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-    """
-    self._RunAction(ScrollBounceAction(
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        direction=direction, distance=distance,
-        overscroll=overscroll, repeat_count=repeat_count,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def ScrollBounceElement(
-      self, selector=None, text=None, element_function=None,
-      left_start_ratio=0.5, top_start_ratio=0.5,
-      direction='down', distance=100,
-      overscroll=10, repeat_count=10,
-      speed_in_pixels_per_second=400):
-    """Perform scroll bounce gesture on the element.
-
-    This gesture scrolls on the element by the number of pixels specified in
-    distance, in the given direction, followed by a scroll by
-    (distance + overscroll) pixels in the opposite direction.
-    The above gesture is repeated repeat_count times.
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          'function() { return foo.element; }'.
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      direction: The direction of scroll, either 'left', 'right',
-          'up', 'down', 'upleft', 'upright', 'downleft', or 'downright'
-      distance: The distance to scroll (in pixel).
-      overscroll: The number of additional pixels to scroll back, in
-          addition to the given distance.
-      repeat_count: How often we want to repeat the full gesture.
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-    """
-    self._RunAction(ScrollBounceAction(
-        selector=selector, text=text, element_function=element_function,
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        direction=direction, distance=distance,
-        overscroll=overscroll, repeat_count=repeat_count,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def MouseClick(self, selector=None):
-    """Mouse click the given element.
-
-    Args:
-      selector: A CSS selector describing the element.
-    """
-    self._RunAction(MouseClickAction(selector=selector))
-
-  def SwipePage(self, left_start_ratio=0.5, top_start_ratio=0.5,
-                direction='left', distance=100, speed_in_pixels_per_second=800):
-    """Perform swipe gesture on the page.
-
-    Args:
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          document.body.
-      direction: The direction of swipe, either 'left', 'right',
-          'up', or 'down'
-      distance: The distance to swipe (in pixel).
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-    """
-    self._RunAction(SwipeAction(
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        direction=direction, distance=distance,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def SwipeElement(self, selector=None, text=None, element_function=None,
-                   left_start_ratio=0.5, top_start_ratio=0.5,
-                   direction='left', distance=100,
-                   speed_in_pixels_per_second=800):
-    """Perform swipe gesture on the element.
-
-    The element may be selected via selector, text, or element_function.
-    Only one of these arguments must be specified.
-
-    Args:
-      selector: A CSS selector describing the element.
-      text: The element must contains this exact text.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          'function() { return foo.element; }'.
-      left_start_ratio: The horizontal starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          the element.
-      top_start_ratio: The vertical starting coordinate of the
-          gesture, as a ratio of the visible bounding rectangle for
-          the element.
-      direction: The direction of swipe, either 'left', 'right',
-          'up', or 'down'
-      distance: The distance to swipe (in pixel).
-      speed_in_pixels_per_second: The speed of the gesture (in pixels/s).
-    """
-    self._RunAction(SwipeAction(
-        selector=selector, text=text, element_function=element_function,
-        left_start_ratio=left_start_ratio, top_start_ratio=top_start_ratio,
-        direction=direction, distance=distance,
-        speed_in_pixels_per_second=speed_in_pixels_per_second))
-
-  def PressKey(self, key, repeat_count=1, repeat_delay_ms=100, timeout=60):
-    """Perform a key press.
-
-    Args:
-      key: DOM value of the pressed key (e.g. 'PageDown', see
-          https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key).
-      repeat_count: How many times the key should be pressed.
-      repeat_delay_ms: Delay after each keypress (including the last one) in
-          milliseconds.
-    """
-    for _ in xrange(repeat_count):
-      self._RunAction(KeyPressAction(key, timeout=timeout))
-      self.Wait(repeat_delay_ms / 1000.0)
-
-  def EnterText(self, text, character_delay_ms=100, timeout=60):
-    """Enter text by performing key presses.
-
-    Args:
-      text: The text to enter.
-      character_delay_ms: Delay after each keypress (including the last one) in
-          milliseconds.
-    """
-    for c in text:
-      self.PressKey(c, repeat_delay_ms=character_delay_ms, timeout=timeout)
-
-  def LoadMedia(self, selector=None, event_timeout_in_seconds=0,
-                event_to_await='canplaythrough'):
-    """Invokes load() on media elements and awaits an event.
-
-    Args:
-      selector: A CSS selector describing the element. If none is
-          specified, play the first media element on the page. If the
-          selector matches more than 1 media element, all of them will
-          be played.
-      event_timeout_in_seconds: Maximum waiting time for the event to be fired.
-          0 means do not wait.
-      event_to_await: Which event to await. For example: 'canplaythrough' or
-          'loadedmetadata'.
-
-    Raises:
-      TimeoutException: If the maximum waiting time is exceeded.
-    """
-    self._RunAction(LoadMediaAction(
-        selector=selector, timeout_in_seconds=event_timeout_in_seconds,
-        event_to_await=event_to_await))
-
-  def PlayMedia(self, selector=None,
-                playing_event_timeout_in_seconds=0,
-                ended_event_timeout_in_seconds=0):
-    """Invokes the "play" action on media elements (such as video).
-
-    Args:
-      selector: A CSS selector describing the element. If none is
-          specified, play the first media element on the page. If the
-          selector matches more than 1 media element, all of them will
-          be played.
-      playing_event_timeout_in_seconds: Maximum waiting time for the "playing"
-          event (dispatched when the media begins to play) to be fired.
-          0 means do not wait.
-      ended_event_timeout_in_seconds: Maximum waiting time for the "ended"
-          event (dispatched when playback completes) to be fired.
-          0 means do not wait.
-
-    Raises:
-      TimeoutException: If the maximum waiting time is exceeded.
-    """
-    self._RunAction(PlayAction(
-        selector=selector,
-        playing_event_timeout_in_seconds=playing_event_timeout_in_seconds,
-        ended_event_timeout_in_seconds=ended_event_timeout_in_seconds))
-
-  def SeekMedia(self, seconds, selector=None, timeout_in_seconds=0,
-                log_time=True, label=''):
-    """Performs a seek action on media elements (such as video).
-
-    Args:
-      seconds: The media time to seek to.
-      selector: A CSS selector describing the element. If none is
-          specified, seek the first media element on the page. If the
-          selector matches more than 1 media element, all of them will
-          be seeked.
-      timeout_in_seconds: Maximum waiting time for the "seeked" event
-          (dispatched when the seeked operation completes) to be
-          fired.  0 means do not wait.
-      log_time: Whether to log the seek time for the perf
-          measurement. Useful when performing multiple seek.
-      label: A suffix string to name the seek perf measurement.
-
-    Raises:
-      TimeoutException: If the maximum waiting time is exceeded.
-    """
-    self._RunAction(SeekAction(
-        seconds=seconds, selector=selector,
-        timeout_in_seconds=timeout_in_seconds,
-        log_time=log_time, label=label))
-
-  def LoopMedia(self, loop_count, selector=None, timeout_in_seconds=None):
-    """Loops a media playback.
-
-    Args:
-      loop_count: The number of times to loop the playback.
-      selector: A CSS selector describing the element. If none is
-          specified, loop the first media element on the page. If the
-          selector matches more than 1 media element, all of them will
-          be looped.
-      timeout_in_seconds: Maximum waiting time for the looped playback to
-          complete. 0 means do not wait. None (the default) means to
-          wait loop_count * 60 seconds.
-
-    Raises:
-      TimeoutException: If the maximum waiting time is exceeded.
-    """
-    self._RunAction(LoopAction(
-        loop_count=loop_count, selector=selector,
-        timeout_in_seconds=timeout_in_seconds))
-
-  def ForceGarbageCollection(self):
-    """Forces JavaScript garbage collection on the page."""
-    self._tab.CollectGarbage()
-
-  def SimulateMemoryPressureNotification(self, pressure_level):
-    """Simulate memory pressure notification.
-
-    Args:
-      pressure_level: 'moderate' or 'critical'.
-    """
-    self._tab.browser.SimulateMemoryPressureNotification(pressure_level)
-
-  def PauseInteractive(self):
-    """Pause the page execution and wait for terminal interaction.
-
-    This is typically used for debugging. You can use this to pause
-    the page execution and inspect the browser state before
-    continuing.
-    """
-    raw_input("Interacting... Press Enter to continue.")
-
-  def RepaintContinuously(self, seconds):
-    """Continuously repaints the visible content.
-
-    It does this by requesting animation frames until the given number
-    of seconds have elapsed AND at least three RAFs have been
-    fired. Times out after max(60, self.seconds), if less than three
-    RAFs were fired."""
-    self._RunAction(RepaintContinuouslyAction(
-        seconds=0 if self._skip_waits else seconds))
-
-
-class Interaction(object):
-
-  def __init__(self, action_runner, label, flags):
-    assert action_runner
-    assert label
-    assert isinstance(flags, list)
-
-    self._action_runner = action_runner
-    self._label = label
-    self._flags = flags
-    self._started = False
-
-  def __enter__(self):
-    self.Begin()
-    return self
-
-  def __exit__(self, exc_type, exc_value, traceback):
-    if exc_value is None:
-      self.End()
-    else:
-      logging.warning(
-          'Exception was raised in the with statement block, the end of '
-          'interaction record is not marked.')
-
-  def Begin(self):
-    assert not self._started
-    self._started = True
-    self._action_runner.ExecuteJavaScript(
-        'console.time({{ marker }});',
-        marker=timeline_interaction_record.GetJavaScriptMarker(
-            self._label, self._flags))
-
-  def End(self):
-    assert self._started
-    self._started = False
-    self._action_runner.ExecuteJavaScript(
-        'console.timeEnd({{ marker }});',
-        marker=timeline_interaction_record.GetJavaScriptMarker(
-            self._label, self._flags))
diff --git a/catapult/telemetry/telemetry/internal/actions/action_runner_unittest.py b/catapult/telemetry/telemetry/internal/actions/action_runner_unittest.py
deleted file mode 100644
index 1c4c259..0000000
--- a/catapult/telemetry/telemetry/internal/actions/action_runner_unittest.py
+++ /dev/null
@@ -1,470 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import mock
-import unittest
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.actions import action_runner as action_runner_module
-from telemetry.internal.actions import page_action
-from telemetry.testing import tab_test_case
-from telemetry.timeline import chrome_trace_category_filter
-from telemetry.timeline import model
-from telemetry.timeline import tracing_config
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-import py_utils
-
-
-class ActionRunnerInteractionTest(tab_test_case.TabTestCase):
-
-  def GetInteractionRecords(self, trace_data):
-    timeline_model = model.TimelineModel(trace_data)
-    renderer_thread = timeline_model.GetRendererThreadFromTabId(self._tab.id)
-    return [
-        tir_module.TimelineInteractionRecord.FromAsyncEvent(e)
-        for e in renderer_thread.async_slices
-        if tir_module.IsTimelineInteractionRecord(e.name)
-        ]
-
-  def VerifyIssuingInteractionRecords(self, **interaction_kwargs):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('interaction_enabled_page.html')
-    action_runner.Wait(1)
-    config = tracing_config.TracingConfig()
-    config.chrome_trace_config.SetLowOverheadFilter()
-    config.enable_chrome_trace = True
-    self._browser.platform.tracing_controller.StartTracing(config)
-    with action_runner.CreateInteraction('InteractionName',
-                                                 **interaction_kwargs):
-      pass
-    trace_data = self._browser.platform.tracing_controller.StopTracing()
-
-    records = self.GetInteractionRecords(trace_data)
-    self.assertEqual(
-        1, len(records),
-        'Failed to issue the interaction record on the tracing timeline.'
-        ' Trace data:\n%s' % repr(trace_data._raw_data))
-    self.assertEqual('InteractionName', records[0].label)
-    for attribute_name in interaction_kwargs:
-      self.assertTrue(getattr(records[0], attribute_name))
-
-  # Test disabled for android: crbug.com/437057
-  # Test disabled for linux: crbug.com/513874
-  @decorators.Disabled('android', 'chromeos', 'linux')
-  def testIssuingMultipleMeasurementInteractionRecords(self):
-    self.VerifyIssuingInteractionRecords(repeatable=True)
-
-
-class ActionRunnerMeasureMemoryTest(tab_test_case.TabTestCase):
-  def setUp(self):
-    super(ActionRunnerMeasureMemoryTest, self).setUp()
-    self.action_runner = action_runner_module.ActionRunner(self._tab,
-                                                           skip_waits=True)
-    self.Navigate('blank.html')
-
-  def testWithoutTracing(self):
-    with mock.patch.object(self._tab.browser, 'DumpMemory') as mock_method:
-      self.assertIsNone(self.action_runner.MeasureMemory())
-      self.assertFalse(mock_method.called)  # No-op with no tracing.
-
-  def _testWithTracing(self, deterministic_mode=False):
-    trace_memory = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        filter_string='-*,blink.console,disabled-by-default-memory-infra')
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    config.chrome_trace_config.SetCategoryFilter(trace_memory)
-    self._browser.platform.tracing_controller.StartTracing(config)
-    try:
-      dump_id = self.action_runner.MeasureMemory(deterministic_mode)
-    finally:
-      trace_data = self._browser.platform.tracing_controller.StopTracing()
-
-    # If successful, i.e. we haven't balied out due to an exception, check
-    # that we can find our dump in the trace.
-    self.assertIsNotNone(dump_id)
-    timeline_model = model.TimelineModel(trace_data)
-    dump_ids = (d.dump_id for d in timeline_model.IterGlobalMemoryDumps())
-    self.assertIn(dump_id, dump_ids)
-
-  # TODO(perezju): Enable when reference browser is >= M53
-  # https://github.com/catapult-project/catapult/issues/2610
-  @decorators.Disabled('reference')
-  def testDeterministicMode(self):
-    self._testWithTracing(deterministic_mode=True)
-
-  # TODO(perezju): Enable when reference browser is >= M53
-  # https://github.com/catapult-project/catapult/issues/2610
-  @decorators.Disabled('reference')
-  def testRealisticMode(self):
-    with mock.patch.object(
-        self.action_runner, 'ForceGarbageCollection') as mock_method:
-      self._testWithTracing(deterministic_mode=False)
-      self.assertFalse(mock_method.called)  # No forced GC in "realistic" mode.
-
-  def testWithFailedDump(self):
-    with mock.patch.object(self._tab.browser, 'DumpMemory') as mock_method:
-      mock_method.return_value = False  # Dump fails!
-      with self.assertRaises(exceptions.Error):
-        self._testWithTracing()
-
-
-class ActionRunnerTest(tab_test_case.TabTestCase):
-  def testExecuteJavaScript(self):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('blank.html')
-    action_runner.ExecuteJavaScript('var testing = 42;')
-    self.assertEqual(42, self._tab.EvaluateJavaScript('testing'))
-
-  def testWaitForNavigate(self):
-    self.Navigate('page_with_link.html')
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    action_runner.ClickElement('#clickme')
-    action_runner.WaitForNavigate()
-
-    self.assertTrue(self._tab.EvaluateJavaScript(
-        'document.readyState == "interactive" || '
-        'document.readyState == "complete"'))
-    self.assertEqual(
-        self._tab.EvaluateJavaScript('document.location.pathname;'),
-        '/blank.html')
-
-  def testNavigateBack(self):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('page_with_link.html')
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/page_with_link.html"')
-
-    # Test that after 3 navigations & 3 back navs, we have to be back at the
-    # initial page
-    self.Navigate('page_with_swipeables.html')
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/page_with_swipeables.html"')
-
-    self.Navigate('blank.html')
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/blank.html"')
-
-    self.Navigate('page_with_swipeables.html')
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/page_with_swipeables.html"')
-
-    action_runner.NavigateBack()
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/blank.html"')
-
-    action_runner.NavigateBack()
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/page_with_swipeables.html"')
-
-    action_runner.NavigateBack()
-    action_runner.WaitForJavaScriptCondition(
-        'document.location.pathname === "/page_with_link.html"')
-
-  def testWait(self):
-    action_runner = action_runner_module.ActionRunner(self._tab)
-    self.Navigate('blank.html')
-
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() { window.testing = 101; }, 50);')
-    action_runner.Wait(0.1)
-    self.assertEqual(101, self._tab.EvaluateJavaScript('window.testing'))
-
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() { window.testing = 102; }, 100);')
-    action_runner.Wait(0.2)
-    self.assertEqual(102, self._tab.EvaluateJavaScript('window.testing'))
-
-  def testWaitForJavaScriptCondition(self):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('blank.html')
-
-    action_runner.ExecuteJavaScript('window.testing = 219;')
-    action_runner.WaitForJavaScriptCondition(
-        'window.testing == 219', timeout=0.1)
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() { window.testing = 220; }, 50);')
-    action_runner.WaitForJavaScriptCondition(
-        'window.testing == 220', timeout=0.1)
-    self.assertEqual(220, self._tab.EvaluateJavaScript('window.testing'))
-
-  def testWaitForJavaScriptCondition_returnsValue(self):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('blank.html')
-
-    action_runner.ExecuteJavaScript('window.testing = 0;')
-    action_runner.WaitForJavaScriptCondition(
-        'window.testing == 0', timeout=0.1)
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() { window.testing = 42; }, 50);')
-    self.assertEqual(
-        42,
-        action_runner.WaitForJavaScriptCondition('window.testing', timeout=10))
-
-  def testWaitForElement(self):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('blank.html')
-
-    action_runner.ExecuteJavaScript(
-        '(function() {'
-        '  var el = document.createElement("div");'
-        '  el.id = "test1";'
-        '  el.textContent = "foo";'
-        '  document.body.appendChild(el);'
-        '})()')
-    action_runner.WaitForElement('#test1', timeout_in_seconds=0.1)
-    action_runner.WaitForElement(text='foo', timeout_in_seconds=0.1)
-    action_runner.WaitForElement(
-        element_function='document.getElementById("test1")')
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() {'
-        '  var el = document.createElement("div");'
-        '  el.id = "test2";'
-        '  document.body.appendChild(el);'
-        '}, 50)')
-    action_runner.WaitForElement('#test2', timeout_in_seconds=0.1)
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() {'
-        '  document.getElementById("test2").textContent = "bar";'
-        '}, 50)')
-    action_runner.WaitForElement(text='bar', timeout_in_seconds=0.1)
-    action_runner.ExecuteJavaScript(
-        'window.setTimeout(function() {'
-        '  var el = document.createElement("div");'
-        '  el.id = "test3";'
-        '  document.body.appendChild(el);'
-        '}, 50)')
-    action_runner.WaitForElement(
-        element_function='document.getElementById("test3")')
-
-  def testWaitForElementWithWrongText(self):
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    self.Navigate('blank.html')
-
-    action_runner.ExecuteJavaScript(
-        '(function() {'
-        '  var el = document.createElement("div");'
-        '  el.id = "test1";'
-        '  el.textContent = "foo";'
-        '  document.body.appendChild(el);'
-        '})()')
-    action_runner.WaitForElement('#test1', timeout_in_seconds=0.2)
-    def WaitForElement():
-      action_runner.WaitForElement(text='oo', timeout_in_seconds=0.2)
-    self.assertRaises(py_utils.TimeoutException, WaitForElement)
-
-  def testClickElement(self):
-    self.Navigate('page_with_clickables.html')
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-
-    action_runner.ExecuteJavaScript('valueSettableByTest = 1;')
-    action_runner.ClickElement('#test')
-    self.assertEqual(1, action_runner.EvaluateJavaScript('valueToTest'))
-
-    action_runner.ExecuteJavaScript('valueSettableByTest = 2;')
-    action_runner.ClickElement(text='Click/tap me')
-    self.assertEqual(2, action_runner.EvaluateJavaScript('valueToTest'))
-
-    action_runner.ExecuteJavaScript('valueSettableByTest = 3;')
-    action_runner.ClickElement(
-        element_function='document.body.firstElementChild;')
-    self.assertEqual(3, action_runner.EvaluateJavaScript('valueToTest'))
-
-    def WillFail():
-      action_runner.ClickElement('#notfound')
-    self.assertRaises(exceptions.EvaluateException, WillFail)
-
-  @decorators.Disabled('android', 'debug',  # crbug.com/437068
-                       'chromeos',          # crbug.com/483212
-                       'win')               # catapult/issues/2282
-  def testTapElement(self):
-    self.Navigate('page_with_clickables.html')
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-
-    action_runner.ExecuteJavaScript('valueSettableByTest = 1;')
-    action_runner.TapElement('#test')
-    self.assertEqual(1, action_runner.EvaluateJavaScript('valueToTest'))
-
-    action_runner.ExecuteJavaScript('valueSettableByTest = 2;')
-    action_runner.TapElement(text='Click/tap me')
-    self.assertEqual(2, action_runner.EvaluateJavaScript('valueToTest'))
-
-    action_runner.ExecuteJavaScript('valueSettableByTest = 3;')
-    action_runner.TapElement(
-        element_function='document.body.firstElementChild')
-    self.assertEqual(3, action_runner.EvaluateJavaScript('valueToTest'))
-
-    def WillFail():
-      action_runner.TapElement('#notfound')
-    self.assertRaises(exceptions.EvaluateException, WillFail)
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testScrollToElement(self):
-    self.Navigate('page_with_swipeables.html')
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-
-    off_screen_element = 'document.querySelectorAll("#off-screen")[0]'
-    top_bottom_element = 'document.querySelector("#top-bottom")'
-
-    def viewport_comparator(element):
-      return action_runner.EvaluateJavaScript('''
-          (function(elem) {
-            var rect = elem.getBoundingClientRect();
-
-            if (rect.bottom < 0) {
-              // The bottom of the element is above the viewport.
-              return -1;
-            }
-            if (rect.top - window.innerHeight > 0) {
-              // rect.top provides the pixel offset of the element from the
-              // top of the page. Because that exceeds the viewport's height,
-              // we know that the element is below the viewport.
-              return 1;
-            }
-            return 0;
-          })({{ @element }});
-          ''', element=element)
-
-
-    self.assertEqual(viewport_comparator(off_screen_element), 1)
-    action_runner.ScrollPageToElement(selector='#off-screen',
-                                      speed_in_pixels_per_second=5000)
-    self.assertEqual(viewport_comparator(off_screen_element), 0)
-
-    self.assertEqual(viewport_comparator(top_bottom_element), -1)
-    action_runner.ScrollPageToElement(selector='#top-bottom',
-                                      container_selector='body',
-                                      speed_in_pixels_per_second=5000)
-    self.assertEqual(viewport_comparator(top_bottom_element), 0)
-
-  @decorators.Disabled('android',   # crbug.com/437065.
-                       'chromeos')  # crbug.com/483212.
-  def testScroll(self):
-    if not page_action.IsGestureSourceTypeSupported(
-        self._tab, 'touch'):
-      return
-
-    self.Navigate('page_with_swipeables.html')
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-
-    action_runner.ScrollElement(
-        selector='#left-right', direction='right', left_start_ratio=0.9)
-    self.assertTrue(action_runner.EvaluateJavaScript(
-        'document.querySelector("#left-right").scrollLeft') > 75)
-    action_runner.ScrollElement(
-        selector='#top-bottom', direction='down', top_start_ratio=0.9)
-    self.assertTrue(action_runner.EvaluateJavaScript(
-        'document.querySelector("#top-bottom").scrollTop') > 75)
-
-    action_runner.ScrollPage(direction='right', left_start_ratio=0.9,
-                             distance=100)
-    self.assertTrue(action_runner.EvaluateJavaScript(
-        '(document.scrollingElement || document.body).scrollLeft') > 75)
-
-  @decorators.Disabled('android',   # crbug.com/437065.
-                       'chromeos')  # crbug.com/483212.
-  def testSwipe(self):
-    if not page_action.IsGestureSourceTypeSupported(
-        self._tab, 'touch'):
-      return
-
-    self.Navigate('page_with_swipeables.html')
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-
-    action_runner.SwipeElement(
-        selector='#left-right', direction='left', left_start_ratio=0.9)
-    self.assertTrue(action_runner.EvaluateJavaScript(
-        'document.querySelector("#left-right").scrollLeft') > 75)
-    action_runner.SwipeElement(
-        selector='#top-bottom', direction='up', top_start_ratio=0.9)
-    self.assertTrue(action_runner.EvaluateJavaScript(
-        'document.querySelector("#top-bottom").scrollTop') > 75)
-
-    action_runner.SwipePage(direction='left', left_start_ratio=0.9)
-    self.assertTrue(action_runner.EvaluateJavaScript(
-        '(document.scrollingElement || document.body).scrollLeft') > 75)
-
-  def testWaitForNetworkQuiescenceSmoke(self):
-    self.Navigate('blank.html')
-    action_runner = action_runner_module.ActionRunner(self._tab)
-    action_runner.WaitForNetworkQuiescence()
-    self.assertEqual(
-        self._tab.EvaluateJavaScript('document.location.pathname;'),
-        '/blank.html')
-
-  def testEnterText(self):
-    self.Navigate('blank.html')
-    self._tab.ExecuteJavaScript(
-        '(function() {'
-        '  var elem = document.createElement("textarea");'
-        '  document.body.appendChild(elem);'
-        '  elem.focus();'
-        '})();')
-
-    action_runner = action_runner_module.ActionRunner(self._tab,
-                                                      skip_waits=True)
-    action_runner.EnterText('That is boring')  # That is boring|.
-    action_runner.PressKey('Home')  # |That is boring.
-    action_runner.PressKey('ArrowRight', repeat_count=2)  # Th|at is boring.
-    action_runner.PressKey('Delete', repeat_count=2)  # Th| is boring.
-    action_runner.EnterText('is')  # This| is boring.
-    action_runner.PressKey('End')  # This is boring|.
-    action_runner.PressKey('ArrowLeft', repeat_count=3)  # This is bor|ing.
-    action_runner.PressKey('Backspace', repeat_count=3)  # This is |ing.
-    action_runner.EnterText('interest')  # This is interest|ing.
-
-    # Check that the contents of the textarea is correct. It might take a second
-    # until all keystrokes have been handled by the browser (crbug.com/630017).
-    self._tab.WaitForJavaScriptCondition(
-        'document.querySelector("textarea").value === "This is interesting"',
-        timeout=1)
-
-
-class InteractionTest(unittest.TestCase):
-
-  def setUp(self):
-    self.mock_action_runner = mock.Mock(action_runner_module.ActionRunner)
-
-    def expected_js_call(method):
-      return mock.call.ExecuteJavaScript(
-          '%s({{ marker }});' % method, marker='Interaction.ABC')
-
-    self.expected_calls = [
-        expected_js_call('console.time'),
-        expected_js_call('console.timeEnd')]
-
-  def testIssuingInteractionRecordCommand(self):
-    with action_runner_module.Interaction(
-        self.mock_action_runner, label='ABC', flags=[]):
-      pass
-    self.assertEqual(self.expected_calls, self.mock_action_runner.mock_calls)
-
-  def testExceptionRaisedInWithInteraction(self):
-    class FooException(Exception):
-      pass
-    # Test that the Foo exception raised in the with block is propagated to the
-    # caller.
-    with self.assertRaises(FooException):
-      with action_runner_module.Interaction(
-          self.mock_action_runner, label='ABC', flags=[]):
-        raise FooException()
-
-    # Test that the end console.timeEnd(...) isn't called because exception was
-    # raised.
-    self.assertEqual(
-        self.expected_calls[:1], self.mock_action_runner.mock_calls)
diff --git a/catapult/telemetry/telemetry/internal/actions/drag.js b/catapult/telemetry/telemetry/internal/actions/drag.js
deleted file mode 100644
index 8c5613c..0000000
--- a/catapult/telemetry/telemetry/internal/actions/drag.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file provides the DragAction object, which performs drag on a page
-// using given start and end positions:
-//   1. var action = new __DragAction(callback)
-//   2. action.start(drag_options)
-'use strict';
-
-(function() {
-  function DragGestureOptions(opt_options) {
-    this.element_ = opt_options.element;
-    this.left_start_ratio_ = opt_options.left_start_ratio;
-    this.top_start_ratio_ = opt_options.top_start_ratio;
-    this.left_end_ratio_ = opt_options.left_end_ratio;
-    this.top_end_ratio_ = opt_options.top_end_ratio;
-    this.speed_ = opt_options.speed;
-    this.gesture_source_type_ = opt_options.gesture_source_type;
-  }
-
-  function supportedByBrowser() {
-    return !!(window.chrome &&
-              chrome.gpuBenchmarking &&
-              chrome.gpuBenchmarking.smoothDrag &&
-              chrome.gpuBenchmarking.visualViewportHeight &&
-              chrome.gpuBenchmarking.visualViewportWidth);
-  }
-
-  // This class performs drag action using given start and end positions,
-  // by a single drag gesture.
-  function DragAction(opt_callback) {
-    this.beginMeasuringHook = function() {};
-    this.endMeasuringHook = function() {};
-
-    this.callback_ = opt_callback;
-  }
-
-  DragAction.prototype.start = function(opt_options) {
-    this.options_ = new DragGestureOptions(opt_options);
-    requestAnimationFrame(this.startGesture_.bind(this));
-  };
-
-  DragAction.prototype.startGesture_ = function() {
-    this.beginMeasuringHook();
-
-    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
-    var start_left =
-        rect.left + (rect.width * this.options_.left_start_ratio_);
-    var start_top =
-        rect.top + (rect.height * this.options_.top_start_ratio_);
-    var end_left =
-        rect.left + (rect.width * this.options_.left_end_ratio_);
-    var end_top =
-        rect.top + (rect.height * this.options_.top_end_ratio_);
-    chrome.gpuBenchmarking.smoothDrag(
-        start_left, start_top, end_left, end_top,
-        this.onGestureComplete_.bind(this), this.options_.gesture_source_type_,
-        this.options_.speed_);
-  };
-
-  DragAction.prototype.onGestureComplete_ = function() {
-    this.endMeasuringHook();
-
-    // We're done.
-    if (this.callback_)
-      this.callback_();
-  };
-
-  window.__DragAction = DragAction;
-  window.__DragAction_SupportedByBrowser = supportedByBrowser;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/drag.py b/catapult/telemetry/telemetry/internal/actions/drag.py
deleted file mode 100644
index 2a0e6a6..0000000
--- a/catapult/telemetry/telemetry/internal/actions/drag.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A Telemetry page_action that performs the "drag" action on pages.
-
-Action parameters are:
-- selector: If no selector is defined then the action attempts to drag the
-            document element on the page.
-- element_function: CSS selector used to evaluate callback when test completes
-- text: The element with exact text is selected.
-- left_start_ratio: ratio of start point's left coordinate to the element
-                    width.
-- top_start_ratio: ratio of start point's top coordinate to the element height.
-- left_end_ratio: ratio of end point's left coordinate to the element width.
-- left_end_ratio: ratio of end point's top coordinate to the element height.
-- speed_in_pixels_per_second: speed of the drag gesture in pixels per second.
-- use_touch: boolean value to specify if gesture should use touch input or not.
-"""
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.util import js_template
-
-
-class DragAction(page_action.PageAction):
-
-  def __init__(self, selector=None, text=None, element_function=None,
-               left_start_ratio=None, top_start_ratio=None, left_end_ratio=None,
-               top_end_ratio=None, speed_in_pixels_per_second=800,
-               use_touch=False,
-               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
-    super(DragAction, self).__init__()
-    self._selector = selector
-    self._text = text
-    self._element_function = element_function
-    self._left_start_ratio = left_start_ratio
-    self._top_start_ratio = top_start_ratio
-    self._left_end_ratio = left_end_ratio
-    self._top_end_ratio = top_end_ratio
-    self._speed = speed_in_pixels_per_second
-    self._use_touch = use_touch
-    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
-                                      synthetic_gesture_source)
-
-  def WillRunAction(self, tab):
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    utils.InjectJavaScript(tab, 'drag.js')
-
-    # Fail if browser doesn't support synthetic drag gestures.
-    if not tab.EvaluateJavaScript('window.__DragAction_SupportedByBrowser()'):
-      raise page_action.PageActionNotSupported(
-          'Synthetic drag not supported for this browser')
-
-    # Fail if this action requires touch and we can't send touch events.
-    if self._use_touch:
-      if not page_action.IsGestureSourceTypeSupported(tab, 'touch'):
-        raise page_action.PageActionNotSupported(
-            'Touch drag not supported for this browser')
-
-      if (self._synthetic_gesture_source ==
-          'chrome.gpuBenchmarking.MOUSE_INPUT'):
-        raise page_action.PageActionNotSupported(
-            'Drag requires touch on this page but mouse input was requested')
-
-    tab.ExecuteJavaScript('''
-        window.__dragActionDone = false;
-        window.__dragAction = new __DragAction(function() {
-          window.__dragActionDone = true;
-        });''')
-
-  def RunAction(self, tab):
-    if (self._selector is None and self._text is None and
-        self._element_function is None):
-      self._element_function = 'document.body'
-
-    gesture_source_type = 'chrome.gpuBenchmarking.TOUCH_INPUT'
-    if (page_action.IsGestureSourceTypeSupported(tab, 'mouse') and
-        not self._use_touch):
-      gesture_source_type = 'chrome.gpuBenchmarking.MOUSE_INPUT'
-
-    code = js_template.Render('''
-        function(element, info) {
-          if (!element) {
-            throw Error('Cannot find element: ' + info);
-          }
-          window.__dragAction.start({
-            element: element,
-            left_start_ratio: {{ left_start_ratio }},
-            top_start_ratio: {{ top_start_ratio }},
-            left_end_ratio: {{ left_end_ratio }},
-            top_end_ratio: {{ top_end_ratio }},
-            speed: {{ speed }},
-            gesture_source_type: {{ @gesture_source_type }}
-          });
-        }''',
-        left_start_ratio=self._left_start_ratio,
-        top_start_ratio=self._top_start_ratio,
-        left_end_ratio=self._left_end_ratio,
-        top_end_ratio=self._top_end_ratio,
-        speed=self._speed,
-        gesture_source_type=gesture_source_type)
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self._selector, text=self._text,
-        element_function=self._element_function)
-    tab.WaitForJavaScriptCondition('window.__dragActionDone', timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/drag_unittest.py b/catapult/telemetry/telemetry/internal/actions/drag_unittest.py
deleted file mode 100644
index a126c5b..0000000
--- a/catapult/telemetry/telemetry/internal/actions/drag_unittest.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import math
-
-from telemetry import decorators
-from telemetry.internal.actions import drag
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.testing import tab_test_case
-
-
-class DragActionTest(tab_test_case.TabTestCase):
-  def CheckWithinRange(self, value, expected, error_ratio):
-    error_range = abs(expected * error_ratio)
-    return abs(value - expected) <= error_range
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  # crbug.com/483212 (CrOS)
-  @decorators.Disabled('android', 'chromeos')
-  def testDragAction(self):
-    self.Navigate('draggable.html')
-
-    utils.InjectJavaScript(self._tab, 'gesture_common.js')
-
-    div_width = self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetBoundingVisibleRect(document.body).width')
-    div_height = self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetBoundingVisibleRect(document.body).height')
-
-    i = drag.DragAction(left_start_ratio=0.5, top_start_ratio=0.5,
-            left_end_ratio=0.25, top_end_ratio=0.25)
-    try:
-      i.WillRunAction(self._tab)
-    except page_action.PageActionNotSupported:
-      logging.warning('This browser does not support drag gesture. Please try'
-                      ' updating chrome.')
-      return
-
-    self._tab.ExecuteJavaScript('''
-        window.__dragAction.beginMeasuringHook = function() {
-            window.__didBeginMeasuring = true;
-        };
-        window.__dragAction.endMeasuringHook = function() {
-            window.__didEndMeasuring = true;
-        };''')
-    i.RunAction(self._tab)
-
-    self.assertTrue(self._tab.EvaluateJavaScript('window.__didBeginMeasuring'))
-    self.assertTrue(self._tab.EvaluateJavaScript('window.__didEndMeasuring'))
-
-    div_position_x = self._tab.EvaluateJavaScript(
-        'document.getElementById("drag_div").offsetLeft')
-    div_position_y = self._tab.EvaluateJavaScript(
-        'document.getElementById("drag_div").offsetTop')
-
-    # 0.25 is the ratio of displacement to the initial size.
-    expected_x = math.floor(div_width * -0.25)
-    expected_y = math.floor(div_height * -0.25)
-    error_ratio = 0.1
-
-    self.assertTrue(
-        self.CheckWithinRange(div_position_x, expected_x, error_ratio),
-        msg="Moved element's left coordinate: %d, expected: %d" %
-        (div_position_x, expected_x))
-    self.assertTrue(
-        self.CheckWithinRange(div_position_y, expected_y, error_ratio),
-        msg="Moved element's top coordinate: %d, expected: %d" %
-        (div_position_y, expected_y))
diff --git a/catapult/telemetry/telemetry/internal/actions/gesture_common.js b/catapult/telemetry/telemetry/internal/actions/gesture_common.js
deleted file mode 100644
index ec76eba..0000000
--- a/catapult/telemetry/telemetry/internal/actions/gesture_common.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file provides common functionality for synthetic gesture actions.
-'use strict';
-
-(function() {
-
-  // Make sure functions are injected only once.
-  if (window.__GestureCommon_GetBoundingVisibleRect)
-    return;
-
-  // Returns the bounding rectangle wrt to the top-most document.
-  function getBoundingRect(el) {
-    var clientRect = el.getBoundingClientRect();
-    var bound = { left: clientRect.left,
-                  top: clientRect.top,
-                  width: clientRect.width,
-                  height: clientRect.height };
-
-    var frame = el.ownerDocument.defaultView.frameElement;
-    while (frame) {
-      var frameBound = frame.getBoundingClientRect();
-      // This computation doesn't account for more complex CSS transforms on the
-      // frame (e.g. scaling or rotations).
-      bound.left += frameBound.left;
-      bound.top += frameBound.top;
-
-      frame = frame.ownerDocument.frameElement;
-    }
-    return bound;
-  }
-
-  // TODO(ulan): Remove this function once
-  // chrome.gpuBenchmarking.pageScaleFactor is available in reference builds.
-  function getPageScaleFactor() {
-    if (chrome.gpuBenchmarking.pageScaleFactor)
-      return chrome.gpuBenchmarking.pageScaleFactor();
-    return 1;
-  }
-
-  // Zoom-independent window height. See crbug.com/627123 for more details.
-  function getWindowHeight() {
-    return getPageScaleFactor() * chrome.gpuBenchmarking.visualViewportHeight();
-  }
-
-  // Zoom-independent window width. See crbug.com/627123 for more details.
-  function getWindowWidth() {
-    return getPageScaleFactor() * chrome.gpuBenchmarking.visualViewportWidth();
-  }
-
-  function clamp(min, value, max) {
-    return Math.min(Math.max(min, value), max);
-  }
-
-  function getBoundingVisibleRect(el) {
-    // Get the element bounding rect.
-    var rect = getBoundingRect(el);
-
-    // Get the window dimensions.
-    var windowHeight = getWindowHeight();
-    var windowWidth = getWindowWidth();
-
-    // Then clip the rect to the screen size.
-    rect.top = clamp(0, rect.top, windowHeight);
-    rect.left = clamp(0, rect.left, windowWidth);
-    rect.height = clamp(0, rect.height, windowHeight - rect.top);
-    rect.width = clamp(0, rect.width, windowWidth - rect.left);
-
-    return rect;
-  }
-
-  window.__GestureCommon_GetBoundingVisibleRect = getBoundingVisibleRect;
-  window.__GestureCommon_GetWindowHeight = getWindowHeight;
-  window.__GestureCommon_GetWindowWidth = getWindowWidth;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/javascript_click.py b/catapult/telemetry/telemetry/internal/actions/javascript_click.py
deleted file mode 100644
index 3a70e00..0000000
--- a/catapult/telemetry/telemetry/internal/actions/javascript_click.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-
-
-class ClickElementAction(page_action.PageAction):
-  def __init__(self, selector=None, text=None, element_function=None):
-    super(ClickElementAction, self).__init__()
-    self.selector = selector
-    self.text = text
-    self.element_function = element_function
-
-  def RunAction(self, tab):
-    code = '''
-        function(element, errorMsg) {
-          if (!element) {
-            throw Error('Cannot find element: ' + errorMsg);
-          }
-          element.click();
-        }'''
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self.selector, text=self.text,
-        element_function=self.element_function)
diff --git a/catapult/telemetry/telemetry/internal/actions/key_event.py b/catapult/telemetry/telemetry/internal/actions/key_event.py
deleted file mode 100644
index 1558607..0000000
--- a/catapult/telemetry/telemetry/internal/actions/key_event.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import string
-
-from telemetry.internal.actions import page_action
-
-
-# Map from DOM key values
-# (https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) to
-# Windows virtual key codes
-# (https://cs.chromium.org/chromium/src/third_party/WebKit/Source/platform/WindowsKeyboardCodes.h)
-# and their printed representations (if available).
-_KEY_MAP = {}
-
-def _AddSpecialKey(key, windows_virtual_key_code, text=None):
-  assert key not in _KEY_MAP, 'Duplicate key: %s' % key
-  _KEY_MAP[key] = (windows_virtual_key_code, text)
-
-def _AddRegularKey(keys, windows_virtual_key_code):
-  for k in keys:
-    assert k not in _KEY_MAP, 'Duplicate key: %s' % k
-    _KEY_MAP[k] = (windows_virtual_key_code, k)
-
-_AddSpecialKey('PageUp', 0x21)
-_AddSpecialKey('PageDown', 0x22)
-_AddSpecialKey('End', 0x23)
-_AddSpecialKey('Home', 0x24)
-_AddSpecialKey('ArrowLeft', 0x25)
-_AddSpecialKey('ArrowUp', 0x26)
-_AddSpecialKey('ArrowRight', 0x27)
-_AddSpecialKey('ArrowDown', 0x28)
-
-_AddSpecialKey('Return', 0x0D, text='\x0D')
-_AddSpecialKey('Delete', 0x2E, text='\x7F')
-_AddSpecialKey('Backspace', 0x08, text='\x08')
-
-# Letter keys.
-for c in string.ascii_uppercase:
-  _AddRegularKey([c, c.lower()], ord(c))
-
-# Symbol keys.
-_AddRegularKey(';:', 0xBA)
-_AddRegularKey('=+', 0xBB)
-_AddRegularKey(',<', 0xBC)
-_AddRegularKey('-_', 0xBD)
-_AddRegularKey('.>', 0xBE)
-_AddRegularKey('/?', 0xBF)
-_AddRegularKey('`~', 0xC0)
-_AddRegularKey('[{', 0xDB)
-_AddRegularKey('\\|', 0xDC)
-_AddRegularKey(']}', 0xDD)
-_AddRegularKey('\'"', 0xDE)
-
-# Numeric keys.
-_AddRegularKey('0)', 0x30)
-_AddRegularKey('1!', 0x31)
-_AddRegularKey('2@', 0x32)
-_AddRegularKey('3#', 0x33)
-_AddRegularKey('4$', 0x34)
-_AddRegularKey('5%', 0x35)
-_AddRegularKey('6^', 0x36)
-_AddRegularKey('7&', 0x37)
-_AddRegularKey('8*', 0x38)
-_AddRegularKey('9(', 0x39)
-
-# Space.
-_AddRegularKey(' ', 0x20)
-
-
-class KeyPressAction(page_action.PageAction):
-
-  def __init__(self, dom_key, timeout=60):
-    super(KeyPressAction, self).__init__()
-    self._dom_key = dom_key
-    if dom_key not in _KEY_MAP:
-      raise ValueError('No mapping for key: %s' % dom_key)
-    self._windows_virtual_key_code, self._text = _KEY_MAP[dom_key]
-    self._timeout = timeout
-
-  def RunAction(self, tab):
-    tab.DispatchKeyEvent(keyEventType='rawKeyDown',
-                         domKey=self._dom_key,
-                         windowsVirtualKeyCode=self._windows_virtual_key_code,
-                         timeout=self._timeout)
-    if self._text:
-      tab.DispatchKeyEvent(keyEventType='char',
-                           text=self._text,
-                           domKey=self._dom_key,
-                           windowsVirtualKeyCode=ord(self._text),
-                           timeout=self._timeout)
-    tab.DispatchKeyEvent(keyEventType='keyUp',
-                         domKey=self._dom_key,
-                         windowsVirtualKeyCode=self._windows_virtual_key_code,
-                         timeout=self._timeout)
diff --git a/catapult/telemetry/telemetry/internal/actions/key_event_unittest.py b/catapult/telemetry/telemetry/internal/actions/key_event_unittest.py
deleted file mode 100644
index ca35ac1..0000000
--- a/catapult/telemetry/telemetry/internal/actions/key_event_unittest.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-
-from telemetry import decorators
-from telemetry.internal.actions import key_event
-from telemetry.internal.actions import utils
-from telemetry.testing import tab_test_case
-
-
-class KeyPressActionTest(tab_test_case.TabTestCase):
-
-  @property
-  def _scroll_position(self):
-    return self._tab.EvaluateJavaScript(
-        'document.documentElement.scrollTop || document.body.scrollTop')
-
-  @property
-  def _window_height(self):
-    return self._tab.EvaluateJavaScript('__GestureCommon_GetWindowHeight()')
-
-  def _PressKey(self, key):
-    action = key_event.KeyPressAction(key)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('blank.html')
-    utils.InjectJavaScript(self._tab, 'gesture_common.js')
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testPressEndAndHome(self):
-    # Make page taller than the window so it's scrollable.
-    self._tab.ExecuteJavaScript('document.body.style.height ='
-        '(3 * __GestureCommon_GetWindowHeight() + 1) + "px";')
-
-    # Check that the browser is currently showing the top of the page and that
-    # the page has non-trivial height.
-    self.assertEquals(0, self._scroll_position)
-    self.assertLess(50, self._window_height)
-
-    self._PressKey('End')
-
-    # Scroll happens *after* key press returns, so we need to wait a little.
-    time.sleep(1)
-
-    # We can only expect the bottom scroll position to be approximatly equal.
-    self.assertAlmostEqual(2 * self._window_height, self._scroll_position,
-                           delta=20)
-
-    self._PressKey('Home')
-
-    # Scroll happens *after* key press returns, so we need to wait a little.
-    time.sleep(1)
-
-    self.assertEquals(self._scroll_position, 0)
-
-  def testTextEntry(self):
-    # Add an input box to the page.
-    self._tab.ExecuteJavaScript(
-        '(function() {'
-        '  var elem = document.createElement("textarea");'
-        '  document.body.appendChild(elem);'
-        '  elem.focus();'
-        '})();')
-
-    # Simulate typing a sentence.
-    for char in 'Hello, World!':
-      self._PressKey(char)
-
-    # Make changes to the sentence using special keys.
-    for _ in xrange(6):
-      self._PressKey('ArrowLeft')
-    self._PressKey('Backspace')
-    self._PressKey('Return')
-
-    # Check that the contents of the textarea is correct. It might take a second
-    # until all keystrokes have been handled by the browser (crbug.com/630017).
-    self._tab.WaitForJavaScriptCondition(
-        'document.querySelector("textarea").value === "Hello,\\nWorld!"',
-        timeout=1)
-
-  def testPressUnknownKey(self):
-    with self.assertRaises(ValueError):
-      self._PressKey('UnknownKeyName')
diff --git a/catapult/telemetry/telemetry/internal/actions/load_media.js b/catapult/telemetry/telemetry/internal/actions/load_media.js
deleted file mode 100644
index 06479f9..0000000
--- a/catapult/telemetry/telemetry/internal/actions/load_media.js
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-(function() {
-  function loadMediaAndAwait(selector, event_to_await) {
-    var mediaElements = window.__findMediaElements(selector);
-    for (var i = 0; i < mediaElements.length; i++) {
-      console.log('Listening for ' + event_to_await + ' on element: ' +
-                  mediaElements[i].src);
-      registerListeners(mediaElements[i], event_to_await);
-      loadMediaElement(mediaElements[i]);
-    }
-  }
-
-  function loadMediaElement(element) {
-    if (element instanceof HTMLMediaElement) {
-      element.load();
-    } else {
-      throw new Error('Can not load non media elements.');
-    }
-  }
-
-  function registerListeners(element, event_to_await) {
-    window.__registerHTML5ErrorEvents(element);
-    window.__registerHTML5EventCompleted(element, event_to_await);
-  }
-
-  window.__loadMediaAndAwait = loadMediaAndAwait;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/load_media.py b/catapult/telemetry/telemetry/internal/actions/load_media.py
deleted file mode 100644
index 1e69dc1..0000000
--- a/catapult/telemetry/telemetry/internal/actions/load_media.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import exceptions
-from telemetry.internal.actions import media_action
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-
-
-class LoadMediaAction(media_action.MediaAction):
-  """ For calling load() on media elements and waiting for an event to fire.
-  """
-
-  def __init__(self, selector=None, timeout_in_seconds=0,
-               event_to_await='canplaythrough'):
-    super(LoadMediaAction, self).__init__()
-    self._selector = selector or ''
-    self._timeout_in_seconds = timeout_in_seconds
-    self._event_to_await = event_to_await
-
-  def WillRunAction(self, tab):
-    """Load the JS code prior to running the action."""
-    super(LoadMediaAction, self).WillRunAction(tab)
-    utils.InjectJavaScript(tab, 'load_media.js')
-
-  def RunAction(self, tab):
-    try:
-      tab.ExecuteJavaScript(
-          'window.__loadMediaAndAwait({{ selector }}, {{ event }});',
-          selector=self._selector, event=self._event_to_await)
-      if self._timeout_in_seconds > 0:
-        self.WaitForEvent(tab, self._selector, self._event_to_await,
-                          self._timeout_in_seconds)
-    except exceptions.EvaluateException:
-      raise page_action.PageActionFailed('Failed waiting for event "%s" on '
-                                         'elements with selector = %s.' %
-                                         (self._event_to_await, self._selector))
diff --git a/catapult/telemetry/telemetry/internal/actions/load_media_unittest.py b/catapult/telemetry/telemetry/internal/actions/load_media_unittest.py
deleted file mode 100644
index 95347af..0000000
--- a/catapult/telemetry/telemetry/internal/actions/load_media_unittest.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions.load_media import LoadMediaAction
-from telemetry.testing import tab_test_case
-
-import py_utils
-
-
-class LoadMediaActionTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('video_test.html')
-
-  def eventFired(self, selector, event):
-    return self._tab.EvaluateJavaScript(
-        'window.__hasEventCompleted({{ selector }}, {{ event }});',
-        selector=selector, event=event)
-
-  @decorators.Disabled('linux',     # crbug.com/418577
-                       'chromeos')  # crbug.com/632802
-  def testAwaitedEventIsConfigurable(self):
-    """It's possible to wait for different events."""
-    action = LoadMediaAction(selector='#video_1', timeout_in_seconds=0.1,
-                             event_to_await='loadedmetadata')
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-    self.assertTrue(self.eventFired('#video_1', 'loadedmetadata'))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testLoadWithNoSelector(self):
-    """With no selector the first media element is loaded."""
-    action = LoadMediaAction(timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-    self.assertTrue(self.eventFired('#video_1', 'canplaythrough'))
-    self.assertFalse(self.eventFired('#audio_1', 'canplaythrough'))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testLoadWithSelector(self):
-    """Only the element matching the selector is loaded."""
-    action = LoadMediaAction(selector='#audio_1', timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-    self.assertFalse(self.eventFired('#video_1', 'canplaythrough'))
-    self.assertTrue(self.eventFired('#audio_1', 'canplaythrough'))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testLoadWithAllSelector(self):
-    """Both elements are loaded with selector='all'."""
-    action = LoadMediaAction(selector='all', timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-    self.assertTrue(self.eventFired('#video_1', 'canplaythrough'))
-    self.assertTrue(self.eventFired('#audio_1', 'canplaythrough'))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testLoadRaisesAnExceptionOnTimeout(self):
-    """The load action times out if the event does not fire."""
-    action = LoadMediaAction(selector='#video_1', timeout_in_seconds=0.1,
-                             event_to_await='a_nonexistent_event')
-    action.WillRunAction(self._tab)
-    self.assertRaises(py_utils.TimeoutException, action.RunAction, self._tab)
diff --git a/catapult/telemetry/telemetry/internal/actions/loop.js b/catapult/telemetry/telemetry/internal/actions/loop.js
deleted file mode 100644
index f862784..0000000
--- a/catapult/telemetry/telemetry/internal/actions/loop.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file performs actions on media elements.
-(function() {
-  function loopMedia(selector, loopCount) {
-    // Loops media playback `loopCount` times.
-    var mediaElements = window.__findMediaElements(selector);
-    for (var i = 0; i < mediaElements.length; i++) {
-      loop(mediaElements[i], loopCount);
-    }
-  }
-
-  function loop(element, loopCount) {
-    if (element instanceof HTMLMediaElement)
-      loopHTML5Element(element, loopCount);
-    else
-      throw new Error('Can not play non HTML5 media elements.');
-  }
-
-  function loopHTML5Element(element, loopCount) {
-    window.__registerHTML5ErrorEvents(element);
-    element['loop_completed'] = false;
-    var currentLoop = 0;
-    var onLoop = function(e) {
-      ++currentLoop;
-      if (currentLoop == loopCount) {
-        element.pause();
-        element.removeEventListener('seeked', onLoop);
-        element['loop_completed'] = true;
-        // Dispatch endLoopEvent to mark end of looping.
-        var endLoopEvent = document.createEvent('Event');
-        endLoopEvent.initEvent('endLoop', false, false);
-        element.dispatchEvent(endLoopEvent);
-      }
-    };
-
-    element.addEventListener('seeked', onLoop);
-    element.loop = true;
-
-    // Dispatch willLoopEvent to measure loop time.
-    var willLoopEvent = document.createEvent('Event');
-    willLoopEvent.initEvent('willLoop', false, false);
-    willLoopEvent.loopCount = loopCount;
-    element.dispatchEvent(willLoopEvent);
-    // Reset HTML5 player to start playback from beginning.
-    element.load();
-    element.play();
-  }
-
-  window.__loopMedia = loopMedia;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/loop.py b/catapult/telemetry/telemetry/internal/actions/loop.py
deleted file mode 100644
index 3ee7fdc..0000000
--- a/catapult/telemetry/telemetry/internal/actions/loop.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A Telemetry page_action that loops media playback.
-
-Action parameters are:
-- loop_count: The number of times to loop media.
-- selector: If no selector is defined then the action attempts to loop the first
-            media element on the page. If 'all' then loop all media elements.
-- timeout_in_seconds: Timeout to wait for media to loop. Default is
-                      60 sec x loop_count. 0 means do not wait.
-"""
-
-from telemetry.core import exceptions
-from telemetry.internal.actions import media_action
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-
-
-class LoopAction(media_action.MediaAction):
-  def __init__(self, loop_count, selector=None, timeout_in_seconds=None):
-    super(LoopAction, self).__init__()
-    self._loop_count = loop_count
-    self._selector = selector if selector else ''
-    self._timeout_in_seconds = (
-        timeout_in_seconds if timeout_in_seconds else 60 * loop_count)
-
-  def WillRunAction(self, tab):
-    """Load the media metrics JS code prior to running the action."""
-    super(LoopAction, self).WillRunAction(tab)
-    utils.InjectJavaScript(tab, 'loop.js')
-
-  def RunAction(self, tab):
-    try:
-      tab.ExecuteJavaScript(
-          'window.__loopMedia({{ selector }}, {{ loop_count }});',
-          selector=self._selector, loop_count=self._loop_count)
-      if self._timeout_in_seconds > 0:
-        self.WaitForEvent(tab, self._selector, 'loop', self._timeout_in_seconds)
-    except exceptions.EvaluateException:
-      raise page_action.PageActionFailed('Cannot loop media element(s) with '
-                                         'selector = %s.' % self._selector)
diff --git a/catapult/telemetry/telemetry/internal/actions/loop_unittest.py b/catapult/telemetry/telemetry/internal/actions/loop_unittest.py
deleted file mode 100644
index 6438cac..0000000
--- a/catapult/telemetry/telemetry/internal/actions/loop_unittest.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions import loop
-from telemetry.testing import tab_test_case
-
-import py_utils
-
-
-AUDIO_1_LOOP_CHECK = 'window.__hasEventCompleted("#audio_1", "loop");'
-VIDEO_1_LOOP_CHECK = 'window.__hasEventCompleted("#video_1", "loop");'
-
-
-class LoopActionTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('video_test.html')
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testLoopWithNoSelector(self):
-    """Tests that with no selector Loop action loops first media element."""
-    action = loop.LoopAction(loop_count=2, selector='#video_1',
-                             timeout_in_seconds=10)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-    # Assert only first video has played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_LOOP_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_LOOP_CHECK))
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testLoopWithAllSelector(self):
-    """Tests that Loop action loops all video elements with selector='all'."""
-    action = loop.LoopAction(loop_count=2, selector='all',
-                             timeout_in_seconds=10)
-    action.WillRunAction(self._tab)
-    # Both videos not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_LOOP_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_LOOP_CHECK))
-    action.RunAction(self._tab)
-    # Assert all media elements played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_LOOP_CHECK))
-    self.assertTrue(self._tab.EvaluateJavaScript(AUDIO_1_LOOP_CHECK))
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testLoopWaitForLoopTimeout(self):
-    """Tests that wait_for_loop timeout_in_secondss if video does not loop."""
-    action = loop.LoopAction(loop_count=2, selector='#video_1',
-                             timeout_in_seconds=1)
-    action.WillRunAction(self._tab)
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_LOOP_CHECK))
-    self.assertRaises(py_utils.TimeoutException, action.RunAction, self._tab)
diff --git a/catapult/telemetry/telemetry/internal/actions/media_action.js b/catapult/telemetry/telemetry/internal/actions/media_action.js
deleted file mode 100644
index e9df62d..0000000
--- a/catapult/telemetry/telemetry/internal/actions/media_action.js
+++ /dev/null
@@ -1,59 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-
-// This file provides common functions for media actions.
-window.__findMediaElements = function(selector) {
-  // Returns elements matching the selector, otherwise returns the first video
-  // or audio tag element that can be found.
-  // If selector == 'all', returns all media elements.
-  if (selector == 'all') {
-    return document.querySelectorAll('video, audio');
-  } else if (selector) {
-    return document.querySelectorAll(selector);
-  } else {
-    var media = document.getElementsByTagName('video');
-    if (media.length > 0) {
-      return [media[0]];
-    } else {
-      media = document.getElementsByTagName('audio');
-      if (media.length > 0) {
-        return [media[0]];
-      }
-    }
-  }
-  console.error('Could not find any media elements matching: ' + selector);
-  return [];
-};
-
-window.__hasEventCompleted = function(selector, event_name) {
-  // Return true if the event_name fired for media satisfying the selector.
-  var mediaElements = window.__findMediaElements(selector);
-  for (var i = 0; i < mediaElements.length; i++) {
-    if (!mediaElements[i][event_name + '_completed'])
-      return false;
-  }
-  return true;
-};
-
-window.__registerHTML5ErrorEvents = function(element) {
-  // Listens to HTML5 media errors.
-  function onError(e) {
-    window.__error = 'Media error: ' + e.type + ', code:' + e.target.error.code;
-    throw new Error(window.__error);
-  }
-  element.addEventListener('error', onError);
-  element.addEventListener('abort', onError);
-};
-
-window.__registerHTML5EventCompleted = function(element, event_name) {
-  // Logs |even_name| on element when completed.
-  var logEventHappened = function(e) {
-    element[e.type + '_completed'] = true;
-    element.removeEventListener(event_name, logEventHappened);
-  }
-  element.addEventListener(event_name, logEventHappened);
-};
-
-window.__error = null;
diff --git a/catapult/telemetry/telemetry/internal/actions/media_action.py b/catapult/telemetry/telemetry/internal/actions/media_action.py
deleted file mode 100644
index 6c97588..0000000
--- a/catapult/telemetry/telemetry/internal/actions/media_action.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Common media action functions."""
-
-import logging
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-
-import py_utils
-
-
-class MediaAction(page_action.PageAction):
-  def WillRunAction(self, tab):
-    """Loads the common media action JS code prior to running the action."""
-    utils.InjectJavaScript(tab, 'media_action.js')
-
-  def RunAction(self, tab):
-    super(MediaAction, self).RunAction(tab)
-
-  def WaitForEvent(self, tab, selector, event_name, timeout_in_seconds):
-    """Halts media action until the selector's event is fired.
-
-    Args:
-      tab: The tab to check for event on.
-      selector: Media element selector.
-      event_name: Name of the event to check if fired or not.
-      timeout_in_seconds: Timeout to check for event, throws an exception if
-          not fired.
-    """
-    py_utils.WaitFor(
-        lambda: self.HasEventCompletedOrError(tab, selector, event_name),
-        timeout=timeout_in_seconds)
-
-  def HasEventCompletedOrError(self, tab, selector, event_name):
-    if tab.EvaluateJavaScript(
-        'window.__hasEventCompleted({{ selector }}, {{ event_name }});',
-        selector=selector, event_name=event_name):
-      return True
-    error = tab.EvaluateJavaScript('window.__error')
-    if error:
-      logging.error('Detected media error while waiting for %s: %s', event_name,
-                    error)
-      return True
-    return False
diff --git a/catapult/telemetry/telemetry/internal/actions/mouse_click.js b/catapult/telemetry/telemetry/internal/actions/mouse_click.js
deleted file mode 100644
index e85239a..0000000
--- a/catapult/telemetry/telemetry/internal/actions/mouse_click.js
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-(function() {
-  function MouseClickAction(opt_callback) {
-    this.callback_ = opt_callback;
-  }
-
-  MouseClickAction.prototype.start = function(options) {
-    this.click_(options.element);
-  };
-
-  MouseClickAction.prototype.click_ = function(element) {
-    var triggerMouseEvent = this.triggerMouseEvent_;
-    var callback = this.callback_;
-    triggerMouseEvent(element, 'mouseover');
-    triggerMouseEvent(element, 'mousedown');
-    // ~100ms is typical for a mouse click's elapsed time.
-    window.setTimeout(
-      function() {
-        triggerMouseEvent(element, 'mouseup');
-        triggerMouseEvent(element, 'click', callback);
-      }, 100);
-  };
-
-  MouseClickAction.prototype.triggerMouseEvent_ = function(
-      node, eventType, callback) {
-    var clickEvent = document.createEvent('MouseEvents');
-    clickEvent.initEvent(eventType, true, true);
-    node.dispatchEvent(clickEvent);
-    if (callback) {
-      window.setTimeout(callback, 0);
-    }
-  };
-
-  window.__MouseClickAction = MouseClickAction;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/mouse_click.py b/catapult/telemetry/telemetry/internal/actions/mouse_click.py
deleted file mode 100644
index 300bc4b..0000000
--- a/catapult/telemetry/telemetry/internal/actions/mouse_click.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-
-
-class MouseClickAction(page_action.PageAction):
-  def __init__(self, selector=None):
-    super(MouseClickAction, self).__init__()
-    self._selector = selector
-
-  def WillRunAction(self, tab):
-    """Load the mouse click JS code prior to running the action."""
-    super(MouseClickAction, self).WillRunAction(tab)
-    utils.InjectJavaScript(tab, 'mouse_click.js')
-    tab.ExecuteJavaScript("""
-        window.__mouseClickActionDone = false;
-        window.__mouseClickAction = new __MouseClickAction(function() {
-          window.__mouseClickActionDone = true;
-        });""")
-
-  def RunAction(self, tab):
-    code = '''
-        function(element, info) {
-          if (!element) {
-            throw Error('Cannot find element: ' + info);
-          }
-          window.__mouseClickAction.start({
-            element: element
-          });
-        }'''
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self._selector)
-    tab.WaitForJavaScriptCondition('window.__mouseClickActionDone', timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/mouse_click_unittest.py b/catapult/telemetry/telemetry/internal/actions/mouse_click_unittest.py
deleted file mode 100644
index 6ad06c7..0000000
--- a/catapult/telemetry/telemetry/internal/actions/mouse_click_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import exceptions
-from telemetry.internal.actions import mouse_click
-from telemetry.testing import tab_test_case
-
-
-class MouseClickActionTest(tab_test_case.TabTestCase):
-
-  def testMouseClickAction(self):
-    self.Navigate('blank.html')
-
-    self._tab.ExecuteJavaScript("""
-        (function() {
-           function createElement(id, textContent) {
-             var el = document.createElement("div");
-             el.id = id;
-             el.textContent = textContent;
-             document.body.appendChild(el);
-           }
-
-           createElement('test-1', 'foo');
-        })();""")
-    i = mouse_click.MouseClickAction(selector='#test-1')
-    i.WillRunAction(self._tab)
-    i.RunAction(self._tab)
-    self.assertTrue(self._tab.EvaluateJavaScript(
-        'window.__mouseClickActionDone'))
-
-  def testMouseClickActionOnNonExistingElement(self):
-    self.Navigate('blank.html')
-
-    self._tab.ExecuteJavaScript("""
-        (function() {
-           function createElement(id, textContent) {
-             var el = document.createElement("div");
-             el.id = id;
-             el.textContent = textContent;
-             document.body.appendChild(el);
-           }
-
-           createElement('test-1', 'foo');
-        })();""")
-    i = mouse_click.MouseClickAction(selector='#test-2')
-    i.WillRunAction(self._tab)
-    def WillFail():
-      i.RunAction(self._tab)
-    self.assertRaises(exceptions.EvaluateException, WillFail)
diff --git a/catapult/telemetry/telemetry/internal/actions/navigate.py b/catapult/telemetry/telemetry/internal/actions/navigate.py
deleted file mode 100644
index c2a81fd..0000000
--- a/catapult/telemetry/telemetry/internal/actions/navigate.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-
-from telemetry.internal.actions import page_action
-
-
-class NavigateAction(page_action.PageAction):
-  def __init__(self, url, script_to_evaluate_on_commit=None,
-               timeout_in_seconds=60):
-    super(NavigateAction, self).__init__()
-    assert url, 'Must specify url for navigate action'
-    self._url = url
-    self._script_to_evaluate_on_commit = script_to_evaluate_on_commit
-    self._timeout_in_seconds = timeout_in_seconds
-
-  def RunAction(self, tab):
-    start_time = time.time()
-    tab.Navigate(self._url,
-                 self._script_to_evaluate_on_commit,
-                 self._timeout_in_seconds)
-
-    time_left_in_seconds = (start_time + self._timeout_in_seconds
-        - time.time())
-    time_left_in_seconds = max(0, time_left_in_seconds)
-    tab.WaitForDocumentReadyStateToBeInteractiveOrBetter(
-        time_left_in_seconds)
-    tab.WaitForFrameToBeDisplayed()
diff --git a/catapult/telemetry/telemetry/internal/actions/navigate_unittest.py b/catapult/telemetry/telemetry/internal/actions/navigate_unittest.py
deleted file mode 100644
index a327d84..0000000
--- a/catapult/telemetry/telemetry/internal/actions/navigate_unittest.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import navigate
-from telemetry.testing import tab_test_case
-
-
-class NavigateActionTest(tab_test_case.TabTestCase):
-  def testNavigateAction(self):
-    i = navigate.NavigateAction(url=self.UrlOfUnittestFile('blank.html'))
-    i.RunAction(self._tab)
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.location.pathname;'),
-        '/blank.html')
diff --git a/catapult/telemetry/telemetry/internal/actions/page_action.py b/catapult/telemetry/telemetry/internal/actions/page_action.py
deleted file mode 100644
index d85d47a..0000000
--- a/catapult/telemetry/telemetry/internal/actions/page_action.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from py_trace_event import trace_event
-
-from telemetry import decorators
-from telemetry.util import js_template
-
-
-GESTURE_SOURCE_DEFAULT = 'DEFAULT'
-GESTURE_SOURCE_MOUSE = 'MOUSE'
-GESTURE_SOURCE_TOUCH = 'TOUCH'
-SUPPORTED_GESTURE_SOURCES = (GESTURE_SOURCE_DEFAULT,
-                             GESTURE_SOURCE_MOUSE,
-                             GESTURE_SOURCE_TOUCH)
-
-class PageActionNotSupported(Exception):
-  pass
-
-class PageActionFailed(Exception):
-  pass
-
-
-class PageAction(object):
-  """Represents an action that a user might try to perform to a page."""
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def WillRunAction(self, tab):
-    """Override to do action-specific setup before
-    Test.WillRunAction is called."""
-    pass
-
-  def RunAction(self, tab):
-    raise NotImplementedError()
-
-  def CleanUp(self, tab):
-    pass
-
-def EvaluateCallbackWithElement(
-    tab, callback_js, selector=None, text=None, element_function=None,
-    wait=False, timeout_in_seconds=60):
-  """Evaluates the JavaScript callback with the given element.
-
-  The element may be selected via selector, text, or element_function.
-  Only one of these arguments must be specified.
-
-  Returns:
-    The callback's return value, if any. The return value must be
-    convertible to JSON.
-
-  Args:
-    tab: A telemetry.core.Tab object.
-    callback_js: The JavaScript callback to call (as string).
-        The callback receive 2 parameters: the element, and information
-        string about what method was used to retrieve the element.
-        Example: '''
-          function(element, info) {
-            if (!element) {
-              throw Error('Can not find element: ' + info);
-            }
-            element.click()
-          }'''
-    selector: A CSS selector describing the element.
-    text: The element must contains this exact text.
-    element_function: A JavaScript function (as string) that is used
-        to retrieve the element. For example:
-        '(function() { return foo.element; })()'.
-    wait: Whether to wait for the return value to be true.
-    timeout_in_seconds: The timeout for wait (if waiting).
-  """
-  count = 0
-  info_msg = ''
-  if element_function is not None:
-    count = count + 1
-    info_msg = js_template.Render(
-        'using element_function: {{ @code }}', code=element_function)
-  if selector is not None:
-    count = count + 1
-    info_msg = js_template.Render(
-        'using selector {{ selector }}', selector=selector)
-    element_function = js_template.Render(
-        'document.querySelector({{ selector }})', selector=selector)
-  if text is not None:
-    count = count + 1
-    info_msg = js_template.Render(
-        'using exact text match {{ text }}', text=text)
-    element_function = js_template.Render('''
-        (function() {
-          function _findElement(element, text) {
-            if (element.innerHTML == text) {
-              return element;
-            }
-
-            var childNodes = element.childNodes;
-            for (var i = 0, len = childNodes.length; i < len; ++i) {
-              var found = _findElement(childNodes[i], text);
-              if (found) {
-                return found;
-              }
-            }
-            return null;
-          }
-          return _findElement(document, {{ text }});
-        })()''',
-        text=text)
-
-  if count != 1:
-    raise PageActionFailed(
-        'Must specify 1 way to retrieve element, but %s was specified.' % count)
-
-  code = js_template.Render('''
-      (function() {
-        var element = {{ @element_function }};
-        var callback = {{ @callback_js }};
-        return callback(element, {{ info_msg }});
-      })()''',
-      element_function=element_function,
-      callback_js=callback_js,
-      info_msg=info_msg)
-
-  if wait:
-    tab.WaitForJavaScriptCondition(code, timeout=timeout_in_seconds)
-    return True
-  else:
-    return tab.EvaluateJavaScript(code)
-
-
-@decorators.Cache
-def IsGestureSourceTypeSupported(tab, gesture_source_type):
-  # TODO(dominikg): remove once support for
-  #                 'chrome.gpuBenchmarking.gestureSourceTypeSupported' has
-  #                 been rolled into reference build.
-  if tab.EvaluateJavaScript("""
-      typeof chrome.gpuBenchmarking.gestureSourceTypeSupported ===
-          'undefined'"""):
-    return (tab.browser.platform.GetOSName() != 'mac' or
-            gesture_source_type.lower() != 'touch')
-
-  return tab.EvaluateJavaScript("""
-      chrome.gpuBenchmarking.gestureSourceTypeSupported(
-          chrome.gpuBenchmarking.{{ @gesture_source_type }}_INPUT)""",
-      gesture_source_type=gesture_source_type.upper())
diff --git a/catapult/telemetry/telemetry/internal/actions/page_action_unittest.py b/catapult/telemetry/telemetry/internal/actions/page_action_unittest.py
deleted file mode 100644
index 5f37135..0000000
--- a/catapult/telemetry/telemetry/internal/actions/page_action_unittest.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for page_action."""
-
-from telemetry.internal.actions import page_action
-from telemetry.testing import tab_test_case
-
-
-class PageActionTest(tab_test_case.TabTestCase):
-
-  def testEvaluateCallbackWithElement(self):
-    self.Navigate('blank.html')
-    self._tab.action_runner.ExecuteJavaScript('''
-        (function() {
-           function createElement(id, textContent) {
-             var el = document.createElement("div");
-             el.id = id;
-             el.textContent = textContent;
-             document.body.appendChild(el);
-           }
-
-           createElement('test-1', 'foo');
-           createElement('test-2', 'bar');
-           createElement('test-3', 'baz');
-        })();''')
-    self.assertEqual(
-        'foo',
-        page_action.EvaluateCallbackWithElement(
-            self._tab, 'function(el) { return el.textContent; }',
-            selector='#test-1'))
-    self.assertEqual(
-        'bar',
-        page_action.EvaluateCallbackWithElement(
-            self._tab, 'function(el) { return el.textContent; }',
-            text='bar'))
-    self.assertEqual(
-        'baz',
-        page_action.EvaluateCallbackWithElement(
-            self._tab, 'function(el) { return el.textContent; }',
-            element_function='document.getElementById("test-3")'))
-    self.assertEqual(
-        'baz',
-        page_action.EvaluateCallbackWithElement(
-            self._tab, 'function(el) { return el.textContent; }',
-            element_function='''
-                (function() {
-                  return document.getElementById("test-3");
-                })()'''))
-
-    # Test for when the element is not found.
-    self.assertEqual(
-        None,
-        page_action.EvaluateCallbackWithElement(
-            self._tab, 'function(el) { return el; }',
-            element_function='document.getElementById("test-4")'))
-
-    # Test the info message.
-    self.assertEqual(
-        'using selector "#test-1"',
-        page_action.EvaluateCallbackWithElement(
-            self._tab, 'function(el, info) { return info; }',
-            selector='#test-1'))
-
-  def testEvaluateCallbackWithElementWithConflictingParams(self):
-    def Evaluate1():
-      page_action.EvaluateCallbackWithElement(
-          self._tab, 'function() {}', selector='div', text='foo')
-    self.assertRaises(page_action.PageActionFailed, Evaluate1)
-
-    def Evaluate2():
-      page_action.EvaluateCallbackWithElement(
-          self._tab, 'function() {}', selector='div', element_function='foo')
-    self.assertRaises(page_action.PageActionFailed, Evaluate2)
-
-    def Evaluate3():
-      page_action.EvaluateCallbackWithElement(
-          self._tab, 'function() {}', text='foo', element_function='')
-    self.assertRaises(page_action.PageActionFailed, Evaluate3)
diff --git a/catapult/telemetry/telemetry/internal/actions/pinch.js b/catapult/telemetry/telemetry/internal/actions/pinch.js
deleted file mode 100644
index 4abb66e..0000000
--- a/catapult/telemetry/telemetry/internal/actions/pinch.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file provides the PinchAction object, which zooms into or out of a
-// page by a given scale factor:
-//   1. var action = new __PinchAction(callback)
-//   2. action.start(pinch_options)
-'use strict';
-
-(function() {
-
-  function PinchGestureOptions(opt_options) {
-    if (opt_options) {
-      this.element_ = opt_options.element;
-      this.left_anchor_ratio_ = opt_options.left_anchor_ratio;
-      this.top_anchor_ratio_ = opt_options.top_anchor_ratio;
-      this.scale_factor_ = opt_options.scale_factor;
-      this.speed_ = opt_options.speed;
-    } else {
-      this.element_ = document.body;
-      this.left_anchor_ratio_ = 0.5;
-      this.top_anchor_ratio_ = 0.5;
-      this.scale_factor_ = 2.0;
-      this.speed_ = 800;
-    }
-  }
-
-  function supportedByBrowser() {
-    return !!(window.chrome &&
-              chrome.gpuBenchmarking &&
-              chrome.gpuBenchmarking.pinchBy &&
-              chrome.gpuBenchmarking.visualViewportHeight &&
-              chrome.gpuBenchmarking.visualViewportWidth);
-  }
-
-  // This class zooms into or out of a page, given a number of pixels for
-  // the synthetic pinch gesture to cover.
-  function PinchAction(opt_callback) {
-    var self = this;
-
-    this.beginMeasuringHook = function() {};
-    this.endMeasuringHook = function() {};
-
-    this.callback_ = opt_callback;
-  };
-
-  PinchAction.prototype.start = function(opt_options) {
-    this.options_ = new PinchGestureOptions(opt_options);
-
-    requestAnimationFrame(this.startPass_.bind(this));
-  };
-
-  PinchAction.prototype.startPass_ = function() {
-    this.beginMeasuringHook();
-
-    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
-    var anchor_left =
-        rect.left + rect.width * this.options_.left_anchor_ratio_;
-    var anchor_top =
-        rect.top + rect.height * this.options_.top_anchor_ratio_;
-    chrome.gpuBenchmarking.pinchBy(this.options_.scale_factor_,
-                                   anchor_left, anchor_top,
-                                   this.onGestureComplete_.bind(this),
-                                   this.options_.speed_);
-  };
-
-  PinchAction.prototype.onGestureComplete_ = function() {
-    this.endMeasuringHook();
-
-    if (this.callback_)
-      this.callback_();
-  };
-
-  window.__PinchAction = PinchAction;
-  window.__PinchAction_SupportedByBrowser = supportedByBrowser;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/pinch.py b/catapult/telemetry/telemetry/internal/actions/pinch.py
deleted file mode 100644
index 9d81bfb..0000000
--- a/catapult/telemetry/telemetry/internal/actions/pinch.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.util import js_template
-
-
-class PinchAction(page_action.PageAction):
-  def __init__(self, selector=None, text=None, element_function=None,
-               left_anchor_ratio=0.5, top_anchor_ratio=0.5,
-               scale_factor=None, speed_in_pixels_per_second=800,
-               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
-    super(PinchAction, self).__init__()
-    self._selector = selector
-    self._text = text
-    self._element_function = element_function
-    self._left_anchor_ratio = left_anchor_ratio
-    self._top_anchor_ratio = top_anchor_ratio
-    self._scale_factor = scale_factor
-    self._speed = speed_in_pixels_per_second
-    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
-                                      synthetic_gesture_source)
-
-    if (self._selector is None and self._text is None and
-        self._element_function is None):
-      self._element_function = 'document.body'
-
-  def WillRunAction(self, tab):
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    utils.InjectJavaScript(tab, 'pinch.js')
-
-    # Fail if browser doesn't support synthetic pinch gestures.
-    if not tab.EvaluateJavaScript('window.__PinchAction_SupportedByBrowser()'):
-      raise page_action.PageActionNotSupported(
-          'Synthetic pinch not supported for this browser')
-
-    tab.ExecuteJavaScript("""
-        window.__pinchActionDone = false;
-        window.__pinchAction = new __PinchAction(function() {
-          window.__pinchActionDone = true;
-        });""")
-
-  @staticmethod
-  def _GetDefaultScaleFactorForPage(tab):
-    current_scale_factor = tab.EvaluateJavaScript(
-        'window.outerWidth / window.innerWidth')
-    return 3.0 / current_scale_factor
-
-  def RunAction(self, tab):
-    scale_factor = (self._scale_factor if self._scale_factor else
-                    PinchAction._GetDefaultScaleFactorForPage(tab))
-    code = js_template.Render('''
-        function(element, info) {
-          if (!element) {
-            throw Error('Cannot find element: ' + info);
-          }
-          window.__pinchAction.start({
-            element: element,
-            left_anchor_ratio: {{ left_anchor_ratio }},
-            top_anchor_ratio: {{ top_anchor_ratio }},
-            scale_factor: {{ scale_factor }},
-            speed: {{ speed }}
-          });
-        }''',
-        left_anchor_ratio=self._left_anchor_ratio,
-        top_anchor_ratio=self._top_anchor_ratio,
-        scale_factor=scale_factor,
-        speed=self._speed)
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self._selector, text=self._text,
-        element_function=self._element_function)
-    tab.WaitForJavaScriptCondition('window.__pinchActionDone', timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/pinch_unittest.py b/catapult/telemetry/telemetry/internal/actions/pinch_unittest.py
deleted file mode 100644
index 6d2aa50..0000000
--- a/catapult/telemetry/telemetry/internal/actions/pinch_unittest.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.testing import tab_test_case
-
-
-class PinchActionTest(tab_test_case.TabTestCase):
-  def setUp(self):
-    super(PinchActionTest, self).setUp()
-
-  def testPinchByApiCalledWithCorrectArguments(self):
-    self.Navigate('blank.html')
-    if not page_action.IsGestureSourceTypeSupported(self._tab, 'touch'):
-      return
-
-    action_runner = self._tab.action_runner
-    action_runner.ExecuteJavaScript('''
-        chrome.gpuBenchmarking.pinchBy = function(
-            scaleFactor, anchorLeft, anchorTop, callback, speed) {
-          window.__test_scaleFactor = scaleFactor;
-          window.__test_anchorLeft = anchorLeft;
-          window.__test_anchorTop = anchorTop;
-          window.__test_callback = callback;
-          window.__test_speed = speed;
-          window.__pinchActionDone = true;
-        };''')
-    action_runner.PinchPage(scale_factor=2)
-    self.assertEqual(
-        2, action_runner.EvaluateJavaScript('window.__test_scaleFactor'))
-    self.assertTrue(
-        action_runner.EvaluateJavaScript('!isNaN(window.__test_anchorLeft)'))
-    self.assertTrue(
-        action_runner.EvaluateJavaScript('!isNaN(window.__test_anchorTop)'))
-    self.assertTrue(
-        action_runner.EvaluateJavaScript('!!window.__test_callback'))
-    self.assertEqual(
-        800, action_runner.EvaluateJavaScript('window.__test_speed'))
diff --git a/catapult/telemetry/telemetry/internal/actions/play.js b/catapult/telemetry/telemetry/internal/actions/play.js
deleted file mode 100644
index c646d78..0000000
--- a/catapult/telemetry/telemetry/internal/actions/play.js
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file performs actions on media elements.
-(function() {
-  function playMedia(selector) {
-    // Performs the "Play" action on media satisfying selector.
-    var mediaElements = window.__findMediaElements(selector);
-    for (var i = 0; i < mediaElements.length; i++) {
-      console.log('Playing element: ' + mediaElements[i].src);
-      play(mediaElements[i]);
-    }
-  }
-
-  function play(element) {
-    if (element instanceof HTMLMediaElement)
-      playHTML5Element(element);
-    else
-      throw new Error('Can not play non HTML5 media elements.');
-  }
-
-  function playHTML5Element(element) {
-    window.__registerHTML5ErrorEvents(element);
-    window.__registerHTML5EventCompleted(element, 'playing');
-    window.__registerHTML5EventCompleted(element, 'ended');
-
-    var willPlayEvent = document.createEvent('Event');
-    willPlayEvent.initEvent('willPlay', false, false);
-    element.dispatchEvent(willPlayEvent);
-    element.play();
-  }
-
-  window.__playMedia = playMedia;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/play.py b/catapult/telemetry/telemetry/internal/actions/play.py
deleted file mode 100644
index f740195..0000000
--- a/catapult/telemetry/telemetry/internal/actions/play.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A Telemetry page_action that performs the "play" action on media elements.
-
-Media elements can be specified by a selector argument. If no selector is
-defined then then the action attempts to play the first video element or audio
-element on the page. A selector can also be 'all' to play all media elements.
-
-Other arguments to use are: playing_event_timeout_in_seconds and
-ended_event_timeout_in_seconds, which forces the action to wait until
-playing and ended events get fired respectively.
-"""
-
-from telemetry.core import exceptions
-from telemetry.internal.actions import media_action
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-
-
-class PlayAction(media_action.MediaAction):
-  def __init__(self, selector=None,
-               playing_event_timeout_in_seconds=0,
-               ended_event_timeout_in_seconds=0):
-    super(PlayAction, self).__init__()
-    self._selector = selector if selector else ''
-    self._playing_event_timeout_in_seconds = playing_event_timeout_in_seconds
-    self._ended_event_timeout_in_seconds = ended_event_timeout_in_seconds
-
-  def WillRunAction(self, tab):
-    """Load the media metrics JS code prior to running the action."""
-    super(PlayAction, self).WillRunAction(tab)
-    utils.InjectJavaScript(tab, 'play.js')
-
-  def RunAction(self, tab):
-    try:
-      tab.ExecuteJavaScript(
-          'window.__playMedia({{ selector }});', selector=self._selector)
-      # Check if we need to wait for 'playing' event to fire.
-      if self._playing_event_timeout_in_seconds > 0:
-        self.WaitForEvent(tab, self._selector, 'playing',
-                          self._playing_event_timeout_in_seconds)
-      # Check if we need to wait for 'ended' event to fire.
-      if self._ended_event_timeout_in_seconds > 0:
-        self.WaitForEvent(tab, self._selector, 'ended',
-                          self._ended_event_timeout_in_seconds)
-    except exceptions.EvaluateException:
-      raise page_action.PageActionFailed('Cannot play media element(s) with '
-                                         'selector = %s.' % self._selector)
diff --git a/catapult/telemetry/telemetry/internal/actions/play_unittest.py b/catapult/telemetry/telemetry/internal/actions/play_unittest.py
deleted file mode 100644
index c497cf9..0000000
--- a/catapult/telemetry/telemetry/internal/actions/play_unittest.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions import play
-from telemetry.testing import tab_test_case
-
-import py_utils
-
-
-AUDIO_1_PLAYING_CHECK = 'window.__hasEventCompleted("#audio_1", "playing");'
-VIDEO_1_PLAYING_CHECK = 'window.__hasEventCompleted("#video_1", "playing");'
-VIDEO_1_ENDED_CHECK = 'window.__hasEventCompleted("#video_1", "ended");'
-
-
-class PlayActionTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('video_test.html')
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testPlayWithNoSelector(self):
-    """Tests that with no selector Play action plays first video element."""
-    action = play.PlayAction(playing_event_timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    # Both videos not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_PLAYING_CHECK))
-    action.RunAction(self._tab)
-    # Assert only first video has played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_PLAYING_CHECK))
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testPlayWithVideoSelector(self):
-    """Tests that Play action plays video element matching selector."""
-    action = play.PlayAction(selector='#video_1',
-                             playing_event_timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    # Both videos not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_PLAYING_CHECK))
-    action.RunAction(self._tab)
-    # Assert only video matching selector has played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_PLAYING_CHECK))
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testPlayWithAllSelector(self):
-    """Tests that Play action plays all video elements with selector='all'."""
-    action = play.PlayAction(selector='all',
-                             playing_event_timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    # Both videos not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_PLAYING_CHECK))
-    action.RunAction(self._tab)
-    # Assert all media elements played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertTrue(self._tab.EvaluateJavaScript(AUDIO_1_PLAYING_CHECK))
-
-  # http://crbug.com/273887
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testPlayWaitForPlayTimeout(self):
-    """Tests that wait_for_playing timeouts if video does not play."""
-    action = play.PlayAction(selector='#video_1',
-                             playing_event_timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    self._tab.EvaluateJavaScript('document.getElementById("video_1").src = ""')
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertRaises(py_utils.TimeoutException, action.RunAction, self._tab)
-
-  @decorators.Disabled('android', 'linux')  # crbug.com/418577
-  def testPlayWaitForEnded(self):
-    """Tests that wait_for_ended waits for video to end."""
-    action = play.PlayAction(selector='#video_1',
-                             ended_event_timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    # Assert video not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_ENDED_CHECK))
-    action.RunAction(self._tab)
-    # Assert video ended.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_ENDED_CHECK))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testPlayWithoutWaitForEnded(self):
-    """Tests that wait_for_ended waits for video to end."""
-    action = play.PlayAction(selector='#video_1',
-                             ended_event_timeout_in_seconds=0)
-    action.WillRunAction(self._tab)
-    # Assert video not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_ENDED_CHECK))
-    action.RunAction(self._tab)
-    # Assert video did not end.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_ENDED_CHECK))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testPlayWaitForEndedTimeout(self):
-    """Tests that action raises exception if timeout is reached."""
-    action = play.PlayAction(selector='#video_1',
-                             ended_event_timeout_in_seconds=0.1)
-    action.WillRunAction(self._tab)
-    # Assert video not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_PLAYING_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_ENDED_CHECK))
-    self.assertRaises(py_utils.TimeoutException, action.RunAction, self._tab)
-    # Assert video did not end.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_ENDED_CHECK))
diff --git a/catapult/telemetry/telemetry/internal/actions/repaint_continuously.py b/catapult/telemetry/telemetry/internal/actions/repaint_continuously.py
deleted file mode 100644
index e1ad4f3..0000000
--- a/catapult/telemetry/telemetry/internal/actions/repaint_continuously.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-
-from telemetry.internal.actions import page_action
-
-import py_utils
-
-
-class RepaintContinuouslyAction(page_action.PageAction):
-  """Continuously repaints the visible content by requesting animation frames
-  until self.seconds have elapsed AND at least three RAFs have been fired. Times
-  out after max(60, self.seconds), if less than three RAFs were fired.
-  """
-
-  def __init__(self, seconds):
-    super(RepaintContinuouslyAction, self).__init__()
-    self._seconds = seconds
-
-  def RunAction(self, tab):
-    tab.ExecuteJavaScript(
-        'window.__rafCount = 0;'
-        'window.__rafFunction = function() {'
-          'window.__rafCount += 1;'
-          'window.webkitRequestAnimationFrame(window.__rafFunction);'
-        '};'
-        'window.webkitRequestAnimationFrame(window.__rafFunction);')
-
-    # Wait until at least self.seconds have elapsed AND min_rafs have been
-    # fired. Use a hard time-out after 60 seconds (or self.seconds).
-    time.sleep(self._seconds)
-    def HasMinRafs():
-      return tab.EvaluateJavaScript('window.__rafCount;') >= 3
-    py_utils.WaitFor(HasMinRafs, max(60 - self._seconds, 0))
diff --git a/catapult/telemetry/telemetry/internal/actions/repeatable_scroll.py b/catapult/telemetry/telemetry/internal/actions/repeatable_scroll.py
deleted file mode 100644
index 9ed09e0..0000000
--- a/catapult/telemetry/telemetry/internal/actions/repeatable_scroll.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import numbers
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.web_perf import timeline_interaction_record
-
-
-class RepeatableScrollAction(page_action.PageAction):
-
-  def __init__(self, x_scroll_distance_ratio=0.0, y_scroll_distance_ratio=0.5,
-               repeat_count=0, repeat_delay_ms=250, timeout=60,
-               prevent_fling=None, speed=None):
-    super(RepeatableScrollAction, self).__init__()
-    self._x_scroll_distance_ratio = x_scroll_distance_ratio
-    self._y_scroll_distance_ratio = y_scroll_distance_ratio
-    self._repeat_count = repeat_count
-    self._repeat_delay_ms = repeat_delay_ms
-    self._windowsize = []
-    self._timeout = timeout
-    self._prevent_fling = prevent_fling
-    self._speed = speed
-
-  def WillRunAction(self, tab):
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    # Get the dimensions of the screen.
-    self._windowsize = tab.EvaluateJavaScript(
-        '[__GestureCommon_GetWindowWidth(),'
-        ' __GestureCommon_GetWindowHeight()]')
-    assert len(self._windowsize) == 2
-    assert all(isinstance(d, numbers.Number) for d in self._windowsize)
-
-  def RunAction(self, tab):
-    # Set up a browser driven repeating scroll. The delay between the scrolls
-    # should be unaffected by render thread responsivness (or lack there of).
-    tab.SynthesizeScrollGesture(
-        x=int(self._windowsize[0] / 2),
-        y=int(self._windowsize[1] / 2),
-        xDistance=int(self._x_scroll_distance_ratio * self._windowsize[0]),
-        yDistance=int(-self._y_scroll_distance_ratio * self._windowsize[1]),
-        preventFling=self._prevent_fling,
-        speed=self._speed,
-        repeatCount=self._repeat_count,
-        repeatDelayMs=self._repeat_delay_ms,
-        interactionMarkerName=timeline_interaction_record.GetJavaScriptMarker(
-            'Gesture_ScrollAction', [timeline_interaction_record.REPEATABLE]),
-        timeout=self._timeout)
diff --git a/catapult/telemetry/telemetry/internal/actions/repeatable_scroll_unittest.py b/catapult/telemetry/telemetry/internal/actions/repeatable_scroll_unittest.py
deleted file mode 100644
index 675f58b..0000000
--- a/catapult/telemetry/telemetry/internal/actions/repeatable_scroll_unittest.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import repeatable_scroll
-from telemetry.internal.actions import utils
-from telemetry.internal.browser import browser_info as browser_info_module
-from telemetry.testing import tab_test_case
-
-
-class RepeatableScrollActionTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('blank.html')
-    utils.InjectJavaScript(self._tab, 'gesture_common.js')
-
-    # Make page taller than window so it's scrollable.
-    self._tab.ExecuteJavaScript('document.body.style.height ='
-        '(3 * __GestureCommon_GetWindowHeight() + 1) + "px";')
-
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollTop'), 0)
-
-    self._browser_info = browser_info_module.BrowserInfo(self._tab.browser)
-    self._window_height = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetWindowHeight()'))
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testRepeatableScrollActionNoRepeats(self):
-    if not self._browser_info.HasRepeatableSynthesizeScrollGesture():
-      return
-
-    expected_scroll = (self._window_height / 2) - 1
-
-    i = repeatable_scroll.RepeatableScrollAction(y_scroll_distance_ratio=0.5)
-    i.WillRunAction(self._tab)
-
-    i.RunAction(self._tab)
-
-    scroll_position = self._tab.EvaluateJavaScript(
-        'document.scrollingElement.scrollTop')
-    # We can only expect the final scroll position to be approximatly equal.
-    self.assertTrue(abs(scroll_position - expected_scroll) < 20,
-                    msg='scroll_position=%d;expected %d' % (scroll_position,
-                                                            expected_scroll))
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testRepeatableScrollActionTwoRepeats(self):
-    if not self._browser_info.HasRepeatableSynthesizeScrollGesture():
-      return
-
-    expected_scroll = ((self._window_height / 2) - 1) * 3
-
-    i = repeatable_scroll.RepeatableScrollAction(y_scroll_distance_ratio=0.5,
-                                                 repeat_count=2,
-                                                 repeat_delay_ms=1)
-    i.WillRunAction(self._tab)
-
-    i.RunAction(self._tab)
-
-    scroll_position = self._tab.EvaluateJavaScript(
-        'document.scrollingElement.scrollTop')
-    # We can only expect the final scroll position to be approximatly equal.
-    self.assertTrue(abs(scroll_position - expected_scroll) < 20,
-                    msg='scroll_position=%d;expected %d' % (scroll_position,
-                                                            expected_scroll))
-
-  # Regression test for crbug.com/627166
-  # TODO(ulan): enable for Android after catapult:#2475 is fixed.
-  @decorators.Disabled('all')
-  def testRepeatableScrollActionNoRepeatsZoomed(self):
-    if (not self._browser_info.HasRepeatableSynthesizeScrollGesture() or
-        not page_action.IsGestureSourceTypeSupported(self._tab, 'touch')):
-      return
-
-    self._tab.action_runner.PinchPage(scale_factor=0.1)
-
-    inner_height = self._tab.EvaluateJavaScript('window.innerHeight')
-    outer_height = self._tab.EvaluateJavaScript('window.outerHeight')
-
-    self.assertGreater(inner_height, outer_height)
-
-    i = repeatable_scroll.RepeatableScrollAction(y_scroll_distance_ratio=0.5)
-    i.WillRunAction(self._tab)
-    i.RunAction(self._tab)
-    # If scroll coordinates are computed incorrectly Chrome will crash with
-    # [FATAL:synthetic_gesture_target_base.cc(62)] Check failed:
-    # web_touch.touches[i].state != WebTouchPoint::StatePressed ||
-    # PointIsWithinContents(web_touch.touches[i].position.x,
-    # web_touch.touches[i].position.y). Touch coordinates are not within content
-    # bounds on TouchStart.
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll.js b/catapult/telemetry/telemetry/internal/actions/scroll.js
deleted file mode 100644
index 2cc5650..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll.js
+++ /dev/null
@@ -1,149 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file provides the ScrollAction object, which scrolls a page
-// to the bottom or for a specified distance:
-//   1. var action = new __ScrollAction(callback, opt_distance_func)
-//   2. action.start(scroll_options)
-'use strict';
-
-(function() {
-  var MAX_SCROLL_LENGTH_TIME_MS = 6250;
-
-  function ScrollGestureOptions(opt_options) {
-    if (opt_options) {
-      this.element_ = opt_options.element;
-      this.left_start_ratio_ = opt_options.left_start_ratio;
-      this.top_start_ratio_ = opt_options.top_start_ratio;
-      this.direction_ = opt_options.direction;
-      this.speed_ = opt_options.speed;
-      this.gesture_source_type_ = opt_options.gesture_source_type;
-    } else {
-      this.element_ = document.scrollingElement || document.body;
-      this.left_start_ratio_ = 0.5;
-      this.top_start_ratio_ = 0.5;
-      this.direction_ = 'down';
-      this.speed_ = 800;
-      this.gesture_source_type_ = chrome.gpuBenchmarking.DEFAULT_INPUT;
-    }
-  }
-
-  function supportedByBrowser() {
-    return !!(window.chrome &&
-              chrome.gpuBenchmarking &&
-              chrome.gpuBenchmarking.smoothScrollBy &&
-              chrome.gpuBenchmarking.visualViewportHeight &&
-              chrome.gpuBenchmarking.visualViewportWidth);
-  }
-
-  // This class scrolls a page from the top to the bottom once.
-  //
-  // The page is scrolled down by a single scroll gesture.
-  function ScrollAction(opt_callback, opt_distance_func) {
-    var self = this;
-
-    this.beginMeasuringHook = function() {};
-    this.endMeasuringHook = function() {};
-
-    this.callback_ = opt_callback;
-    this.distance_func_ = opt_distance_func;
-  }
-
-  ScrollAction.prototype.getScrollDistanceDown_ = function() {
-    var clientHeight;
-    // clientHeight is "special" for the body element.
-    if (this.element_ == document.body)
-      clientHeight = __GestureCommon_GetWindowHeight();
-    else
-      clientHeight = this.element_.clientHeight;
-
-    return this.element_.scrollHeight -
-           this.element_.scrollTop -
-           clientHeight;
-  };
-
-  ScrollAction.prototype.getScrollDistanceUp_ = function() {
-    return this.element_.scrollTop;
-  };
-
-  ScrollAction.prototype.getScrollDistanceRight_ = function() {
-    var clientWidth;
-    // clientWidth is "special" for the body element.
-    if (this.element_ == document.body)
-      clientWidth = __GestureCommon_GetWindowWidth();
-    else
-      clientWidth = this.element_.clientWidth;
-
-    return this.element_.scrollWidth - this.element_.scrollLeft - clientWidth;
-  };
-
-  ScrollAction.prototype.getScrollDistanceLeft_ = function() {
-    return this.element_.scrollLeft;
-  };
-
-  ScrollAction.prototype.getScrollDistance_ = function() {
-    if (this.distance_func_)
-      return this.distance_func_();
-
-    if (this.options_.direction_ == 'down') {
-      return this.getScrollDistanceDown_();
-    } else if (this.options_.direction_ == 'up') {
-      return this.getScrollDistanceUp_();
-    } else if (this.options_.direction_ == 'right') {
-      return this.getScrollDistanceRight_();
-    } else if (this.options_.direction_ == 'left') {
-      return this.getScrollDistanceLeft_();
-    } else if (this.options_.direction_ == 'upleft') {
-      return Math.min(this.getScrollDistanceUp_(),
-                      this.getScrollDistanceLeft_());
-    } else if (this.options_.direction_ == 'upright') {
-      return Math.min(this.getScrollDistanceUp_(),
-                      this.getScrollDistanceRight_());
-    } else if (this.options_.direction_ == 'downleft') {
-      return Math.min(this.getScrollDistanceDown_(),
-                      this.getScrollDistanceLeft_());
-    } else if (this.options_.direction_ == 'downright') {
-      return Math.min(this.getScrollDistanceDown_(),
-                      this.getScrollDistanceRight_());
-    }
-  };
-
-  ScrollAction.prototype.start = function(opt_options) {
-    this.options_ = new ScrollGestureOptions(opt_options);
-    // Assign this.element_ here instead of constructor, because the constructor
-    // ensures this method will be called after the document is loaded.
-    this.element_ = this.options_.element_;
-    requestAnimationFrame(this.startGesture_.bind(this));
-  };
-
-  ScrollAction.prototype.startGesture_ = function() {
-    this.beginMeasuringHook();
-
-    var max_scroll_length_pixels = (MAX_SCROLL_LENGTH_TIME_MS / 1000) *
-        this.options_.speed_;
-    var distance = Math.min(max_scroll_length_pixels,
-                            this.getScrollDistance_());
-
-    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
-    var start_left =
-        rect.left + rect.width * this.options_.left_start_ratio_;
-    var start_top =
-        rect.top + rect.height * this.options_.top_start_ratio_;
-    chrome.gpuBenchmarking.smoothScrollBy(
-        distance, this.onGestureComplete_.bind(this), start_left, start_top,
-        this.options_.gesture_source_type_, this.options_.direction_,
-        this.options_.speed_);
-  };
-
-  ScrollAction.prototype.onGestureComplete_ = function() {
-    this.endMeasuringHook();
-
-    // We're done.
-    if (this.callback_)
-      this.callback_();
-  };
-
-  window.__ScrollAction = ScrollAction;
-  window.__ScrollAction_SupportedByBrowser = supportedByBrowser;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll.py b/catapult/telemetry/telemetry/internal/actions/scroll.py
deleted file mode 100644
index dc4f165..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.util import js_template
-
-
-class ScrollAction(page_action.PageAction):
-  # TODO(chrishenry): Ignore attributes, to be deleted when usage in
-  # other repo is cleaned up.
-  def __init__(self, selector=None, text=None, element_function=None,
-               left_start_ratio=0.5, top_start_ratio=0.5, direction='down',
-               distance=None, distance_expr=None,
-               speed_in_pixels_per_second=800, use_touch=False,
-               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
-    super(ScrollAction, self).__init__()
-    if direction not in ('down', 'up', 'left', 'right',
-                         'downleft', 'downright',
-                         'upleft', 'upright'):
-      raise page_action.PageActionNotSupported(
-          'Invalid scroll direction: %s' % self.direction)
-    self._selector = selector
-    self._text = text
-    self._element_function = element_function
-    self._left_start_ratio = left_start_ratio
-    self._top_start_ratio = top_start_ratio
-    self._direction = direction
-    self._speed = speed_in_pixels_per_second
-    self._use_touch = use_touch
-    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
-                                      synthetic_gesture_source)
-
-    self._distance_func = js_template.RenderValue(None)
-    if distance:
-      assert not distance_expr
-      distance_expr = str(distance)
-    if distance_expr:
-      self._distance_func = js_template.Render(
-          'function() { return 0 + {{ @expr }}; }', expr=distance_expr)
-
-  def WillRunAction(self, tab):
-    if self._direction in ('downleft', 'downright', 'upleft', 'upright'):
-      # Diagonal scrolling support was added in Chrome branch number 2332.
-      branch_num = (
-          tab.browser._browser_backend.devtools_client.GetChromeBranchNumber())
-      if branch_num < 2332:
-        raise ValueError('Diagonal scrolling requires Chrome branch number'
-                         ' 2332 or later. Found branch number %d' %
-                         branch_num)
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    utils.InjectJavaScript(tab, 'scroll.js')
-
-    # Fail if browser doesn't support synthetic scroll gestures.
-    if not tab.EvaluateJavaScript(
-        'window.__ScrollAction_SupportedByBrowser()'):
-      raise page_action.PageActionNotSupported(
-          'Synthetic scroll not supported for this browser')
-
-    # Fail if this action requires touch and we can't send touch events.
-    if self._use_touch:
-      if not page_action.IsGestureSourceTypeSupported(tab, 'touch'):
-        raise page_action.PageActionNotSupported(
-            'Touch scroll not supported for this browser')
-
-      if (self._synthetic_gesture_source ==
-          'chrome.gpuBenchmarking.MOUSE_INPUT'):
-        raise page_action.PageActionNotSupported(
-            'Scroll requires touch on this page but mouse input was requested')
-
-    tab.ExecuteJavaScript("""
-        window.__scrollActionDone = false;
-        window.__scrollAction = new __ScrollAction(
-            {{ @callback }}, {{ @distance }});""",
-        callback='function() { window.__scrollActionDone = true; }',
-        distance=self._distance_func)
-
-  def RunAction(self, tab):
-    if (self._selector is None and self._text is None and
-        self._element_function is None):
-      self._element_function = '(document.scrollingElement || document.body)'
-
-    gesture_source_type = self._synthetic_gesture_source
-    if self._use_touch:
-      gesture_source_type = 'chrome.gpuBenchmarking.TOUCH_INPUT'
-
-    code = js_template.Render('''
-        function(element, info) {
-          if (!element) {
-            throw Error('Cannot find element: ' + info);
-          }
-          window.__scrollAction.start({
-            element: element,
-            left_start_ratio: {{ left_start_ratio }},
-            top_start_ratio: {{ top_start_ratio }},
-            direction: {{ direction }},
-            speed: {{ speed }},
-            gesture_source_type: {{ @gesture_source_type }}
-          });
-        }''',
-        left_start_ratio=self._left_start_ratio,
-        top_start_ratio=self._top_start_ratio,
-        direction=self._direction,
-        speed=self._speed,
-        gesture_source_type=gesture_source_type)
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self._selector, text=self._text,
-        element_function=self._element_function)
-    tab.WaitForJavaScriptCondition('window.__scrollActionDone', timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll_bounce.js b/catapult/telemetry/telemetry/internal/actions/scroll_bounce.js
deleted file mode 100644
index ec0fc7f..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll_bounce.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-(function() {
-  function supportedByBrowser() {
-    return !!(window.chrome &&
-              chrome.gpuBenchmarking &&
-              chrome.gpuBenchmarking.scrollBounce &&
-              chrome.gpuBenchmarking.visualViewportHeight &&
-              chrome.gpuBenchmarking.visualViewportWidth);
-  }
-
-  function ScrollBounceAction(opt_callback) {
-    var self = this;
-
-    this.beginMeasuringHook = function() {};
-    this.endMeasuringHook = function() {};
-
-    this.callback_ = opt_callback;
-  }
-
-  ScrollBounceAction.prototype.start = function(options) {
-    this.options_ = options;
-    // Assign this.element_ here instead of constructor, because the constructor
-    // ensures this method will be called after the document is loaded.
-    this.element_ = this.options_.element;
-    requestAnimationFrame(this.startGesture_.bind(this));
-  };
-
-  ScrollBounceAction.prototype.startGesture_ = function() {
-    this.beginMeasuringHook();
-
-    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element);
-    var start_left =
-        rect.left + rect.width * this.options_.left_start_ratio;
-    var start_top =
-        rect.top + rect.height * this.options_.top_start_ratio;
-    chrome.gpuBenchmarking.scrollBounce(this.options_.direction,
-                                        this.options_.distance,
-                                        this.options_.overscroll,
-                                        this.options_.repeat_count,
-                                        this.onGestureComplete_.bind(this),
-                                        start_left, start_top,
-                                        this.options_.speed);
-  };
-
-  ScrollBounceAction.prototype.onGestureComplete_ = function() {
-    this.endMeasuringHook();
-
-    // We're done.
-    if (this.callback_)
-      this.callback_();
-  };
-
-  window.__ScrollBounceAction = ScrollBounceAction;
-  window.__ScrollBounceAction_SupportedByBrowser = supportedByBrowser;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll_bounce.py b/catapult/telemetry/telemetry/internal/actions/scroll_bounce.py
deleted file mode 100644
index f293a4f..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll_bounce.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.util import js_template
-
-
-class ScrollBounceAction(page_action.PageAction):
-  def __init__(self, selector=None, text=None, element_function=None,
-               left_start_ratio=0.5, top_start_ratio=0.5,
-               direction='down', distance=100,
-               overscroll=10, repeat_count=10,
-               speed_in_pixels_per_second=400,
-               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
-    super(ScrollBounceAction, self).__init__()
-    if direction not in ['down', 'up', 'left', 'right']:
-      raise page_action.PageActionNotSupported(
-          'Invalid scroll direction: %s' % self.direction)
-    self._selector = selector
-    self._text = text
-    self._element_function = element_function
-    self._left_start_ratio = left_start_ratio
-    self._top_start_ratio = top_start_ratio
-    # Should be big enough to do more than just hide the URL bar.
-    self._distance = distance
-    self._direction = direction
-    # This needs to be < height / repeat_count so we don't walk off the screen.
-    # We also probably don't want to spend more than a couple frames in
-    # overscroll since it may mask any synthetic delays.
-    self._overscroll = overscroll
-    # It's the transitions we really want to stress, make this big.
-    self._repeat_count = repeat_count
-    # 7 pixels per frame should be plenty of frames.
-    self._speed = speed_in_pixels_per_second
-    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
-                                      synthetic_gesture_source)
-
-    if (self._selector is None and self._text is None and
-        self._element_function is None):
-      self._element_function = '(document.scrollingElement || document.body)'
-
-  def WillRunAction(self, tab):
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    utils.InjectJavaScript(tab, 'scroll_bounce.js')
-
-    # Fail if browser doesn't support synthetic scroll bounce gestures.
-    if not tab.EvaluateJavaScript(
-        'window.__ScrollBounceAction_SupportedByBrowser()'):
-      raise page_action.PageActionNotSupported(
-          'Synthetic scroll bounce not supported for this browser')
-
-    # Fail if we can't send touch events (bouncing is really only
-    # interesting for touch)
-    if not page_action.IsGestureSourceTypeSupported(tab, 'touch'):
-      raise page_action.PageActionNotSupported(
-          'Touch scroll not supported for this browser')
-
-    if (self._synthetic_gesture_source ==
-        'chrome.gpuBenchmarking.MOUSE_INPUT'):
-      raise page_action.PageActionNotSupported(
-          'ScrollBounce page action does not support mouse input')
-
-    tab.ExecuteJavaScript("""
-        window.__scrollBounceActionDone = false;
-        window.__scrollBounceAction = new __ScrollBounceAction(
-            function() { window.__scrollBounceActionDone = true; });""")
-
-  def RunAction(self, tab):
-    code = js_template.Render('''
-        function(element, info) {
-          if (!element) {
-            throw Error('Cannot find element: ' + info);
-          }
-          window.__scrollBounceAction.start({
-            element: element,
-            left_start_ratio: {{ left_start_ratio }},
-            top_start_ratio: {{ top_start_ratio }},
-            direction: {{ direction }},
-            distance: {{ distance }},
-            overscroll: {{ overscroll }},
-            repeat_count: {{ repeat_count }},
-            speed: {{ speed }}
-          });
-        }''',
-        left_start_ratio=self._left_start_ratio,
-        top_start_ratio=self._top_start_ratio,
-        direction=self._direction,
-        distance=self._distance,
-        overscroll=self._overscroll,
-        repeat_count=self._repeat_count,
-        speed=self._speed)
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self._selector, text=self._text,
-        element_function=self._element_function)
-    tab.WaitForJavaScriptCondition(
-        'window.__scrollBounceActionDone', timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll_to_element.py b/catapult/telemetry/telemetry/internal/actions/scroll_to_element.py
deleted file mode 100644
index e6c8cd1..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll_to_element.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions.scroll import ScrollAction
-from telemetry.util import js_template
-
-
-class ScrollToElementAction(page_action.PageAction):
-
-
-  def __init__(self, selector=None, element_function=None,
-               container_selector=None, container_element_function=None,
-               speed_in_pixels_per_second=800):
-    """Perform scroll gesture on container until an element is in view.
-
-    Both the element and the container can be specified by a CSS selector
-    xor a JavaScript function, provided as a string, which returns an element.
-    The element is required so exactly one of selector and element_function
-    must be provided. The container is optional so at most one of
-    container_selector and container_element_function can be provided.
-    The container defaults to document.scrollingElement or document.body if
-    scrollingElement is not set.
-
-    Args:
-      selector: A CSS selector describing the element.
-      element_function: A JavaScript function (as string) that is used
-          to retrieve the element. For example:
-          'function() { return foo.element; }'.
-      container_selector: A CSS selector describing the container element.
-      container_element_function: A JavaScript function (as a string) that is
-          used to retrieve the container element.
-      speed_in_pixels_per_second: Speed to scroll.
-    """
-    super(ScrollToElementAction, self).__init__()
-    self._selector = selector
-    self._element_function = element_function
-    self._container_selector = container_selector
-    self._container_element_function = container_element_function
-    self._speed = speed_in_pixels_per_second
-    self._distance = None
-    self._direction = None
-    self._scroller = None
-    assert (self._selector or self._element_function), (
-        'Must have either selector or element function')
-
-  def WillRunAction(self, tab):
-    if self._selector:
-      element = js_template.Render(
-          'document.querySelector({{ selector }})', selector=self._selector)
-    else:
-      element = self._element_function
-
-    self._distance = tab.EvaluateJavaScript('''
-        (function(elem){
-          var rect = elem.getBoundingClientRect();
-          if (rect.bottom < 0) {
-            // The bottom of the element is above the viewport.
-            // Scroll up until the top of the element is on screen.
-            return rect.top - (window.innerHeight / 2);
-          }
-          if (rect.top - window.innerHeight >= 0) {
-            // rect.top provides the pixel offset of the element from the
-            // top of the page. Because that exceeds the viewport's height,
-            // we know that the element is below the viewport.
-            return rect.top - (window.innerHeight / 2);
-          }
-          return 0;
-        })({{ @element }});
-        ''', element=element)
-    self._direction = 'down' if self._distance > 0 else 'up'
-    self._distance = abs(self._distance)
-    self._scroller = ScrollAction(
-        direction=self._direction,
-        selector=self._container_selector,
-        element_function=self._container_element_function,
-        distance=self._distance,
-        speed_in_pixels_per_second=self._speed)
-
-  def RunAction(self, tab):
-    if self._distance == 0:  # Element is already in view.
-      return
-    self._scroller.WillRunAction(tab)
-    self._scroller.RunAction(tab)
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll_to_element_unittest.py b/catapult/telemetry/telemetry/internal/actions/scroll_to_element_unittest.py
deleted file mode 100644
index 10469c5..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll_to_element_unittest.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions import scroll_to_element
-from telemetry.internal.actions import utils
-from telemetry.testing import tab_test_case
-
-
-class ScrollToElementActionTest(tab_test_case.TabTestCase):
-
-  def _MakePageVerticallyScrollable(self):
-    # Make page taller than window so it's scrollable vertically.
-    self._tab.ExecuteJavaScript('document.body.style.height ='
-        '(6 * __GestureCommon_GetWindowHeight() + 1) + "px";')
-
-  def _VisibleAreaOfElement(self, selector='#element'):
-    return self._tab.EvaluateJavaScript("""
-      (function() {
-        var element = document.querySelector({{ selector }});
-        var rect = __GestureCommon_GetBoundingVisibleRect(element);
-        return rect.width * rect.height;
-      })()
-    """, selector=selector)
-
-  def _InsertContainer(self, theid='container'):
-    self._tab.ExecuteJavaScript("""
-      var container = document.createElement("div")
-      container.id = {{ theid }};
-      container.style.position = 'relative';
-      container.style.height = '100%';
-      document.body.appendChild(container);
-    """, theid=theid)
-
-  def _InsertElement(self, theid='element', container_selector='body'):
-    self._tab.ExecuteJavaScript("""
-      var container = document.querySelector({{ container_selector }});
-      var element = document.createElement("div");
-      element.id = {{ theid }};
-      element.textContent = 'My element';
-      element.style.position = 'absolute';
-      element.style.top = (__GestureCommon_GetWindowHeight() * 3) + "px";
-      container.appendChild(element);
-    """, theid=theid, container_selector=container_selector)
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('blank.html')
-    utils.InjectJavaScript(self._tab, 'gesture_common.js')
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testScrollToElement(self):
-    self._MakePageVerticallyScrollable()
-    self._InsertElement()
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollTop'), 0)
-
-    # Before we scroll down the element should not be visible at all.
-    self.assertEquals(self._VisibleAreaOfElement(), 0)
-
-    i = scroll_to_element.ScrollToElementAction(selector='#element')
-    i.WillRunAction(self._tab)
-    i.RunAction(self._tab)
-
-    # After we scroll down at least some of the element should be visible.
-    self.assertGreater(self._VisibleAreaOfElement(selector='#element'), 0)
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testScrollContainerToElement(self):
-    self._MakePageVerticallyScrollable()
-    self._InsertContainer()
-    self._InsertElement(container_selector='#container')
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollTop'), 0)
-
-    # Before we scroll down the element should not be visible at all.
-    self.assertEquals(self._VisibleAreaOfElement(), 0)
-
-    i = scroll_to_element.ScrollToElementAction(
-        selector='#element', container_selector='#container')
-    i.WillRunAction(self._tab)
-    i.RunAction(self._tab)
-
-    # After we scroll down at least some of the element should be visible.
-    self.assertGreater(self._VisibleAreaOfElement(), 0)
diff --git a/catapult/telemetry/telemetry/internal/actions/scroll_unittest.py b/catapult/telemetry/telemetry/internal/actions/scroll_unittest.py
deleted file mode 100644
index b51dd6a..0000000
--- a/catapult/telemetry/telemetry/internal/actions/scroll_unittest.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions import scroll
-from telemetry.internal.actions import utils
-from telemetry.testing import tab_test_case
-
-class ScrollActionTest(tab_test_case.TabTestCase):
-  def _MakePageVerticallyScrollable(self):
-    # Make page taller than window so it's scrollable vertically.
-    self._tab.ExecuteJavaScript('document.body.style.height ='
-        '(3 * __GestureCommon_GetWindowHeight() + 1) + "px";')
-
-  def _MakePageHorizontallyScrollable(self):
-    # Make page wider than window so it's scrollable horizontally.
-    self._tab.ExecuteJavaScript('document.body.style.width ='
-        '(3 * __GestureCommon_GetWindowWidth() + 1) + "px";')
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('blank.html')
-    utils.InjectJavaScript(self._tab, 'gesture_common.js')
-
-  def testScrollAction(self):
-
-    self._MakePageVerticallyScrollable()
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollTop'), 0)
-
-    i = scroll.ScrollAction()
-    i.WillRunAction(self._tab)
-
-    self._tab.ExecuteJavaScript("""
-        window.__scrollAction.beginMeasuringHook = function() {
-            window.__didBeginMeasuring = true;
-        };
-        window.__scrollAction.endMeasuringHook = function() {
-            window.__didEndMeasuring = true;
-        };""")
-    i.RunAction(self._tab)
-
-    self.assertTrue(self._tab.EvaluateJavaScript('window.__didBeginMeasuring'))
-    self.assertTrue(self._tab.EvaluateJavaScript('window.__didEndMeasuring'))
-
-    scroll_position = self._tab.EvaluateJavaScript(
-        'document.scrollingElement.scrollTop')
-    self.assertTrue(scroll_position != 0,
-                    msg='scroll_position=%d;' % (scroll_position))
-
-  # https://github.com/catapult-project/catapult/issues/3099
-  @decorators.Disabled('android')
-  def testDiagonalScrollAction(self):
-    # Diagonal scrolling was not supported in the ScrollAction until Chrome
-    # branch number 2332
-    branch_num = self._tab.browser._browser_backend.devtools_client \
-        .GetChromeBranchNumber()
-    if branch_num < 2332:
-      return
-
-    self._MakePageVerticallyScrollable()
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollTop'), 0)
-
-    self._MakePageHorizontallyScrollable()
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollLeft'),
-        0)
-
-    i = scroll.ScrollAction(direction='downright')
-    i.WillRunAction(self._tab)
-
-    i.RunAction(self._tab)
-
-    viewport_top = self._tab.EvaluateJavaScript(
-        'document.scrollingElement.scrollTop')
-    self.assertTrue(viewport_top != 0, msg='viewport_top=%d;' % viewport_top)
-
-    viewport_left = self._tab.EvaluateJavaScript(
-        'document.scrollingElement.scrollLeft')
-    self.assertTrue(viewport_left != 0, msg='viewport_left=%d;' % viewport_left)
-
-  def testBoundingClientRect(self):
-    # Verify that the rect returned by getBoundingVisibleRect() in scroll.js is
-    # completely contained within the viewport. Scroll events dispatched by the
-    # scrolling API use the center of this rect as their location, and this
-    # location needs to be within the viewport bounds to correctly decide
-    # between main-thread and impl-thread scroll. If the scrollable area were
-    # not clipped to the viewport bounds, then the instance used here (the
-    # scrollable area being more than twice as tall as the viewport) would
-    # result in a scroll location outside of the viewport bounds.
-    self._MakePageVerticallyScrollable()
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollTop'), 0)
-
-    self._MakePageHorizontallyScrollable()
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.scrollingElement.scrollLeft'),
-        0)
-
-    self._tab.ExecuteJavaScript("""
-        window.scrollTo(__GestureCommon_GetWindowWidth(),
-                        __GestureCommon_GetWindowHeight());""")
-
-    rect_top = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetBoundingVisibleRect(document.body).top'))
-    rect_height = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetBoundingVisibleRect(document.body).height'))
-    rect_bottom = rect_top + rect_height
-
-    rect_left = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetBoundingVisibleRect(document.body).left'))
-    rect_width = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetBoundingVisibleRect(document.body).width'))
-    rect_right = rect_left + rect_width
-
-    viewport_height = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetWindowHeight()'))
-    viewport_width = int(self._tab.EvaluateJavaScript(
-        '__GestureCommon_GetWindowWidth()'))
-
-    self.assertTrue(rect_top >= 0,
-        msg='%s >= %s' % (rect_top, 0))
-    self.assertTrue(rect_left >= 0,
-        msg='%s >= %s' % (rect_left, 0))
-    self.assertTrue(rect_bottom <= viewport_height,
-        msg='%s + %s <= %s' % (rect_top, rect_height, viewport_height))
-    self.assertTrue(rect_right <= viewport_width,
-        msg='%s + %s <= %s' % (rect_left, rect_width, viewport_width))
diff --git a/catapult/telemetry/telemetry/internal/actions/seek.js b/catapult/telemetry/telemetry/internal/actions/seek.js
deleted file mode 100644
index baef30c..0000000
--- a/catapult/telemetry/telemetry/internal/actions/seek.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file performs actions on media elements.
-(function() {
-  function seekMedia(selector, seekTime, logSeekTime, seekLabel) {
-    // Performs the "Seek" action on media satisfying selector.
-    var mediaElements = window.__findMediaElements(selector);
-    for (var i = 0; i < mediaElements.length; i++) {
-      if (mediaElements[i] instanceof HTMLMediaElement)
-        seekHTML5Element(mediaElements[i], seekTime, logSeekTime, seekLabel);
-      else
-        throw new Error('Can not seek non HTML5 media elements.');
-    }
-  }
-
-  function seekHTML5Element(element, seekTime, logSeekTime, seekLabel) {
-    function readyForSeek() {
-      seekHTML5ElementPostLoad(element, seekTime, logSeekTime, seekLabel);
-    }
-    if (element.readyState == element.HAVE_NOTHING) {
-      var onLoadedMetaData = function(e) {
-        element.removeEventListener('loadedmetadata', onLoadedMetaData);
-        readyForSeek();
-      };
-      element.addEventListener('loadedmetadata', onLoadedMetaData);
-      element.load();
-    } else {
-      readyForSeek();
-    }
-  }
-
-  function seekHTML5ElementPostLoad(element, seekTime, logSeekTime, seekLabel) {
-    // Reset seek completion since multiple seeks can run on same media element.
-    element['seeked_completed'] = false;
-    window.__registerHTML5ErrorEvents(element);
-    window.__registerHTML5EventCompleted(element, 'seeked');
-
-    if (logSeekTime) {
-      var willSeekEvent = document.createEvent('Event');
-      willSeekEvent.initEvent('willSeek', false, false);
-      if (seekLabel)
-        willSeekEvent.seekLabel = seekLabel;
-      else
-        willSeekEvent.seekLabel = seekTime;
-      element.dispatchEvent(willSeekEvent);
-    }
-    try {
-      element.currentTime = seekTime;
-    } catch (err) {
-      throw new Error('Cannot seek in network state: ' + element.networkState);
-    }
-  }
-
-  window.__seekMedia = seekMedia;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/seek.py b/catapult/telemetry/telemetry/internal/actions/seek.py
deleted file mode 100644
index 6e82b1f..0000000
--- a/catapult/telemetry/telemetry/internal/actions/seek.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A Telemetry page_action that performs the "seek" action on media elements.
-
-Action parameters are:
-- seconds: The media time to seek to. Test fails if not provided.
-- selector: If no selector is defined then the action attempts to seek the first
-            media element on the page. If 'all' then seek all media elements.
-- timeout_in_seconds: Maximum waiting time for the "seeked" event
-                      (dispatched when the seeked operation completes)
-                      to be fired.  0 means do not wait.
-- log_time: If true the seek time is recorded, otherwise media
-            measurement will not be aware of the seek action. Used to
-            perform multiple seeks. Default true.
-- label: A suffix string to name the seek perf measurement.
-"""
-
-from telemetry.core import exceptions
-from telemetry.internal.actions import media_action
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-
-
-class SeekAction(media_action.MediaAction):
-  def __init__(self, seconds, selector=None, timeout_in_seconds=0,
-               log_time=True, label=''):
-    super(SeekAction, self).__init__()
-    self._seconds = seconds
-    self._selector = selector if selector else ''
-    self._timeout_in_seconds = timeout_in_seconds
-    self._log_time = log_time
-    self._label = label
-
-  def WillRunAction(self, tab):
-    """Load the media metrics JS code prior to running the action."""
-    super(SeekAction, self).WillRunAction(tab)
-    utils.InjectJavaScript(tab, 'seek.js')
-
-  def RunAction(self, tab):
-    try:
-      tab.ExecuteJavaScript(
-          'window.__seekMedia('
-              '{{ selector }}, {{ seconds }}, {{ log_time }}, {{ label}});',
-          selector=self._selector,
-          seconds=str(self._seconds),
-          log_time=self._log_time,
-          label=self._label)
-      if self._timeout_in_seconds > 0:
-        self.WaitForEvent(tab, self._selector, 'seeked',
-                          self._timeout_in_seconds)
-    except exceptions.EvaluateException:
-      raise page_action.PageActionFailed('Cannot seek media element(s) with '
-                                         'selector = %s.' % self._selector)
diff --git a/catapult/telemetry/telemetry/internal/actions/seek_unittest.py b/catapult/telemetry/telemetry/internal/actions/seek_unittest.py
deleted file mode 100644
index 80b9689..0000000
--- a/catapult/telemetry/telemetry/internal/actions/seek_unittest.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions import seek
-from telemetry.testing import tab_test_case
-
-import py_utils
-
-
-AUDIO_1_SEEKED_CHECK = 'window.__hasEventCompleted("#audio_1", "seeked");'
-VIDEO_1_SEEKED_CHECK = 'window.__hasEventCompleted("#video_1", "seeked");'
-
-
-class SeekActionTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    tab_test_case.TabTestCase.setUp(self)
-    self.Navigate('video_test.html')
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testSeekWithNoSelector(self):
-    """Tests that with no selector Seek  action seeks first media element."""
-    action = seek.SeekAction(seconds=1, timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-    # Assert only first video has played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_SEEKED_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_SEEKED_CHECK))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testSeekWithVideoSelector(self):
-    """Tests that Seek action seeks video element matching selector."""
-    action = seek.SeekAction(seconds=1, selector='#video_1',
-                             timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    # Both videos not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_SEEKED_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_SEEKED_CHECK))
-    action.RunAction(self._tab)
-    # Assert only video matching selector has played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_SEEKED_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_SEEKED_CHECK))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testSeekWithAllSelector(self):
-    """Tests that Seek action seeks all video elements with selector='all'."""
-    action = seek.SeekAction(seconds=1, selector='all',
-                             timeout_in_seconds=5)
-    action.WillRunAction(self._tab)
-    # Both videos not playing before running action.
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_SEEKED_CHECK))
-    self.assertFalse(self._tab.EvaluateJavaScript(AUDIO_1_SEEKED_CHECK))
-    action.RunAction(self._tab)
-    # Assert all media elements played.
-    self.assertTrue(self._tab.EvaluateJavaScript(VIDEO_1_SEEKED_CHECK))
-    self.assertTrue(self._tab.EvaluateJavaScript(AUDIO_1_SEEKED_CHECK))
-
-  @decorators.Disabled('linux')  # crbug.com/418577
-  def testSeekWaitForSeekTimeout(self):
-    """Tests that wait_for_seeked timeouts if video does not seek."""
-    action = seek.SeekAction(seconds=1, selector='#video_1',
-                             timeout_in_seconds=0.1)
-    action.WillRunAction(self._tab)
-    self._tab.EvaluateJavaScript('document.getElementById("video_1").src = ""')
-    self.assertFalse(self._tab.EvaluateJavaScript(VIDEO_1_SEEKED_CHECK))
-    self.assertRaises(py_utils.TimeoutException, action.RunAction, self._tab)
diff --git a/catapult/telemetry/telemetry/internal/actions/swipe.js b/catapult/telemetry/telemetry/internal/actions/swipe.js
deleted file mode 100644
index 517485c..0000000
--- a/catapult/telemetry/telemetry/internal/actions/swipe.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-(function() {
-  function SwipeGestureOptions(opt_options) {
-    if (opt_options) {
-      this.element_ = opt_options.element;
-      this.left_start_ratio_ = opt_options.left_start_ratio;
-      this.top_start_ratio_ = opt_options.top_start_ratio;
-      this.direction_ = opt_options.direction;
-      this.distance_ = opt_options.distance;
-      this.speed_ = opt_options.speed;
-    } else {
-      this.element_ = document.body;
-      this.left_start_ratio_ = 0.5;
-      this.top_start_ratio_ = 0.5;
-      this.direction_ = 'left';
-      this.distance_ = 0;
-      this.speed_ = 800;
-    }
-  }
-
-  function supportedByBrowser() {
-    return !!(window.chrome &&
-              chrome.gpuBenchmarking &&
-              chrome.gpuBenchmarking.swipe &&
-              chrome.gpuBenchmarking.visualViewportHeight &&
-              chrome.gpuBenchmarking.visualViewportWidth);
-  }
-
-  // This class swipes a page for a specified distance.
-  function SwipeAction(opt_callback) {
-    var self = this;
-
-    this.beginMeasuringHook = function() {};
-    this.endMeasuringHook = function() {};
-
-    this.callback_ = opt_callback;
-  }
-
-  SwipeAction.prototype.start = function(opt_options) {
-    this.options_ = new SwipeGestureOptions(opt_options);
-    // Assign this.element_ here instead of constructor, because the constructor
-    // ensures this method will be called after the document is loaded.
-    this.element_ = this.options_.element_;
-    requestAnimationFrame(this.startGesture_.bind(this));
-  };
-
-  SwipeAction.prototype.startGesture_ = function() {
-    this.beginMeasuringHook();
-
-    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
-    var start_left =
-        rect.left + rect.width * this.options_.left_start_ratio_;
-    var start_top =
-        rect.top + rect.height * this.options_.top_start_ratio_;
-    chrome.gpuBenchmarking.swipe(this.options_.direction_,
-                                 this.options_.distance_,
-                                 this.onGestureComplete_.bind(this),
-                                 start_left, start_top,
-                                 this.options_.speed_);
-  };
-
-  SwipeAction.prototype.onGestureComplete_ = function() {
-    this.endMeasuringHook();
-
-    // We're done.
-    if (this.callback_)
-      this.callback_();
-  };
-
-  window.__SwipeAction = SwipeAction;
-  window.__SwipeAction_SupportedByBrowser = supportedByBrowser;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/swipe.py b/catapult/telemetry/telemetry/internal/actions/swipe.py
deleted file mode 100644
index 1232e3b..0000000
--- a/catapult/telemetry/telemetry/internal/actions/swipe.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.util import js_template
-
-
-class SwipeAction(page_action.PageAction):
-  def __init__(self, selector=None, text=None, element_function=None,
-               left_start_ratio=0.5, top_start_ratio=0.5,
-               direction='left', distance=100, speed_in_pixels_per_second=800,
-               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
-    super(SwipeAction, self).__init__()
-    if direction not in ['down', 'up', 'left', 'right']:
-      raise page_action.PageActionNotSupported(
-          'Invalid swipe direction: %s' % self.direction)
-    self._selector = selector
-    self._text = text
-    self._element_function = element_function
-    self._left_start_ratio = left_start_ratio
-    self._top_start_ratio = top_start_ratio
-    self._direction = direction
-    self._distance = distance
-    self._speed = speed_in_pixels_per_second
-    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
-                                      synthetic_gesture_source)
-
-  def WillRunAction(self, tab):
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    utils.InjectJavaScript(tab, 'swipe.js')
-
-    # Fail if browser doesn't support synthetic swipe gestures.
-    if not tab.EvaluateJavaScript('window.__SwipeAction_SupportedByBrowser()'):
-      raise page_action.PageActionNotSupported(
-          'Synthetic swipe not supported for this browser')
-
-    if (self._synthetic_gesture_source ==
-        'chrome.gpuBenchmarking.MOUSE_INPUT'):
-      raise page_action.PageActionNotSupported(
-          'Swipe page action does not support mouse input')
-
-    if not page_action.IsGestureSourceTypeSupported(tab, 'touch'):
-      raise page_action.PageActionNotSupported(
-          'Touch input not supported for this browser')
-
-    tab.ExecuteJavaScript("""
-        window.__swipeActionDone = false;
-        window.__swipeAction = new __SwipeAction(function() {
-          window.__swipeActionDone = true;
-        });""")
-
-  def RunAction(self, tab):
-    if (self._selector is None and self._text is None and
-        self._element_function is None):
-      self._element_function = '(document.scrollingElement || document.body)'
-    code = js_template.Render('''
-        function(element, info) {
-          if (!element) {
-            throw Error('Cannot find element: ' + info);
-          }
-          window.__swipeAction.start({
-            element: element,
-            left_start_ratio: {{ left_start_ratio }},
-            top_start_ratio: {{ top_start_ratio }},
-            direction: {{ direction }},
-            distance: {{ distance }},
-            speed: {{ speed }}
-          });
-        }''',
-        left_start_ratio=self._left_start_ratio,
-        top_start_ratio=self._top_start_ratio,
-        direction=self._direction,
-        distance=self._distance,
-        speed=self._speed)
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self._selector, text=self._text,
-        element_function=self._element_function)
-    tab.WaitForJavaScriptCondition('window.__swipeActionDone', timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/tap.js b/catapult/telemetry/telemetry/internal/actions/tap.js
deleted file mode 100644
index e8c8b30..0000000
--- a/catapult/telemetry/telemetry/internal/actions/tap.js
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-(function() {
-
-  function TapGestureOptions(opt_options) {
-    if (opt_options) {
-      this.element_ = opt_options.element;
-      this.left_position_percentage_ = opt_options.left_position_percentage;
-      this.top_position_percentage_ = opt_options.top_position_percentage;
-      this.duration_ms_ = opt_options.duration_ms;
-      this.gesture_source_type_ = opt_options.gesture_source_type;
-    } else {
-      this.element_ = document.body;
-      this.left_position_percentage_ = 0.5;
-      this.top_position_percentage_ = 0.5;
-      this.duration_ms_ = 50;
-      this.gesture_source_type_ = chrome.gpuBenchmarking.DEFAULT_INPUT;
-    }
-  }
-
-  function supportedByBrowser() {
-    return !!(window.chrome &&
-              chrome.gpuBenchmarking &&
-              chrome.gpuBenchmarking.tap &&
-              chrome.gpuBenchmarking.visualViewportHeight &&
-              chrome.gpuBenchmarking.visualViewportWidth);
-  }
-
-  function TapAction(opt_callback) {
-    var self = this;
-
-    this.beginMeasuringHook = function() {};
-    this.endMeasuringHook = function() {};
-
-    this.callback_ = opt_callback;
-  }
-
-  TapAction.prototype.start = function(opt_options) {
-    this.options_ = new TapGestureOptions(opt_options);
-    // Assign this.element_ here instead of constructor, because the constructor
-    // ensures this method will be called after the document is loaded.
-    this.element_ = this.options_.element_;
-
-    this.beginMeasuringHook();
-
-    var rect = __GestureCommon_GetBoundingVisibleRect(this.options_.element_);
-    var position_left =
-        rect.left + rect.width * this.options_.left_position_percentage_;
-    var position_top =
-        rect.top + rect.height * this.options_.top_position_percentage_;
-    if (position_left < 0 ||
-        position_left >= __GestureCommon_GetWindowWidth() ||
-        position_top < 0 ||
-        position_top >= __GestureCommon_GetWindowHeight()) {
-      throw new Error('Tap position is off-screen');
-    }
-    chrome.gpuBenchmarking.tap(position_left, position_top,
-                               this.onGestureComplete_.bind(this),
-                               this.options_.duration_ms_,
-                               this.options_.gesture_source_type_);
-  };
-
-  TapAction.prototype.onGestureComplete_ = function() {
-    this.endMeasuringHook();
-
-    // We're done.
-    if (this.callback_)
-      this.callback_();
-  };
-
-  window.__TapAction = TapAction;
-  window.__TapAction_SupportedByBrowser = supportedByBrowser;
-})();
diff --git a/catapult/telemetry/telemetry/internal/actions/tap.py b/catapult/telemetry/telemetry/internal/actions/tap.py
deleted file mode 100644
index 3ad8b7d..0000000
--- a/catapult/telemetry/telemetry/internal/actions/tap.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-from telemetry.internal.actions import utils
-from telemetry.util import js_template
-
-
-class TapAction(page_action.PageAction):
-  def __init__(self, selector=None, text=None, element_function=None,
-               left_position_percentage=0.5, top_position_percentage=0.5,
-               duration_ms=50,
-               synthetic_gesture_source=page_action.GESTURE_SOURCE_DEFAULT):
-    super(TapAction, self).__init__()
-    self.selector = selector
-    self.text = text
-    self.element_function = element_function
-    self.left_position_percentage = left_position_percentage
-    self.top_position_percentage = top_position_percentage
-    self.duration_ms = duration_ms
-    self._synthetic_gesture_source = ('chrome.gpuBenchmarking.%s_INPUT' %
-                                      synthetic_gesture_source)
-
-  def WillRunAction(self, tab):
-    utils.InjectJavaScript(tab, 'gesture_common.js')
-    utils.InjectJavaScript(tab, 'tap.js')
-
-    # Fail if browser doesn't support synthetic tap gestures.
-    if not tab.EvaluateJavaScript('window.__TapAction_SupportedByBrowser()'):
-      raise page_action.PageActionNotSupported(
-          'Synthetic tap not supported for this browser')
-
-    tab.ExecuteJavaScript("""
-        window.__tapActionDone = false;
-        window.__tapAction = new __TapAction(function() {
-          window.__tapActionDone = true;
-        });""")
-
-  def HasElementSelector(self):
-    return (self.element_function is not None or self.selector is not None or
-            self.text is not None)
-
-  def RunAction(self, tab):
-    if not self.HasElementSelector():
-      self.element_function = 'document.body'
-
-    code = js_template.Render('''
-        function(element, errorMsg) {
-          if (!element) {
-            throw Error('Cannot find element: ' + errorMsg);
-          }
-          window.__tapAction.start({
-            element: element,
-            left_position_percentage: {{ left_position_percentage }},
-            top_position_percentage: {{ top_position_percentage }},
-            duration_ms: {{ duration_ms }},
-            gesture_source_type: {{ @gesture_source_type }}
-          });
-        }''',
-        left_position_percentage=self.left_position_percentage,
-        top_position_percentage=self.top_position_percentage,
-        duration_ms=self.duration_ms,
-        gesture_source_type=self._synthetic_gesture_source)
-
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self.selector, text=self.text,
-        element_function=self.element_function)
-    # The second disjunct handles the case where the tap action leads to an
-    # immediate navigation (in which case the expression below might already be
-    # evaluated on the new page).
-    tab.WaitForJavaScriptCondition(
-        'window.__tapActionDone || window.__tapAction === undefined',
-        timeout=60)
diff --git a/catapult/telemetry/telemetry/internal/actions/tap_unittest.py b/catapult/telemetry/telemetry/internal/actions/tap_unittest.py
deleted file mode 100644
index f6708ed..0000000
--- a/catapult/telemetry/telemetry/internal/actions/tap_unittest.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.actions import tap
-from telemetry.testing import tab_test_case
-
-class TapActionTest(tab_test_case.TabTestCase):
-
-  def _PerformTapAction(self, *args, **kwargs):
-    action = tap.TapAction(*args, **kwargs)
-    action.WillRunAction(self._tab)
-    action.RunAction(self._tab)
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  # http://crbug.com/634343 (Windows)
-  @decorators.Disabled('android', 'win')
-  def testTapSinglePage(self):
-    self.Navigate('page_with_clickables.html')
-
-    self._tab.ExecuteJavaScript('valueSettableByTest = 1;')
-    self._PerformTapAction('#test')
-    self.assertEqual(1, self._tab.EvaluateJavaScript('valueToTest'))
-
-    self._tab.ExecuteJavaScript('valueSettableByTest = 2;')
-    self._PerformTapAction(text='Click/tap me')
-    self.assertEqual(2, self._tab.EvaluateJavaScript('valueToTest'))
-
-    self._tab.ExecuteJavaScript('valueSettableByTest = 3;')
-    self._PerformTapAction(element_function='document.body.firstElementChild')
-    self.assertEqual(3, self._tab.EvaluateJavaScript('valueToTest'))
-
-  @decorators.Disabled('win')  # http://crbug.com/634343
-  def testTapNavigate(self):
-    self.Navigate('page_with_link.html')
-    self._PerformTapAction(selector='#clickme')
-    self._tab.WaitForJavaScriptCondition(
-        'document.location.pathname === "/blank.html"', timeout=5)
-    self._tab.WaitForJavaScriptCondition(
-        'document.readyState === "complete"', timeout=5)
diff --git a/catapult/telemetry/telemetry/internal/actions/utils.py b/catapult/telemetry/telemetry/internal/actions/utils.py
deleted file mode 100644
index 8ef5906..0000000
--- a/catapult/telemetry/telemetry/internal/actions/utils.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-
-def InjectJavaScript(tab, jsFileName):
-  with open(os.path.join(os.path.dirname(__file__), jsFileName)) as f:
-    js = f.read()
-    tab.ExecuteJavaScript(js)
diff --git a/catapult/telemetry/telemetry/internal/actions/wait.py b/catapult/telemetry/telemetry/internal/actions/wait.py
deleted file mode 100644
index 3413f3c..0000000
--- a/catapult/telemetry/telemetry/internal/actions/wait.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import page_action
-
-
-class WaitForElementAction(page_action.PageAction):
-  def __init__(self, selector=None, text=None, element_function=None,
-               timeout_in_seconds=60):
-    super(WaitForElementAction, self).__init__()
-    self.selector = selector
-    self.text = text
-    self.element_function = element_function
-    self.timeout_in_seconds = timeout_in_seconds
-
-  def RunAction(self, tab):
-    code = 'function(element) { return element != null; }'
-    page_action.EvaluateCallbackWithElement(
-        tab, code, selector=self.selector, text=self.text,
-        element_function=self.element_function,
-        wait=True, timeout_in_seconds=self.timeout_in_seconds)
diff --git a/catapult/telemetry/telemetry/internal/app/__init__.py b/catapult/telemetry/telemetry/internal/app/__init__.py
deleted file mode 100644
index 0a1d389..0000000
--- a/catapult/telemetry/telemetry/internal/app/__init__.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class App(object):
-  """ A running application instance that can be controlled in a limited way.
-
-  Be sure to clean up after yourself by calling Close() when you are done with
-  the app. Or better yet:
-    with possible_app.Create(options) as app:
-      ... do all your operations on app here
-  """
-  def __init__(self, app_backend, platform_backend):
-    assert platform_backend.platform != None
-    self._app_backend = app_backend
-    self._platform_backend = platform_backend
-    self._app_backend.SetApp(self)
-
-  @property
-  def app_type(self):
-    return self._app_backend.app_type
-
-  @property
-  def platform(self):
-    return self._platform_backend.platform
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, *args):
-    self.Close()
-
-  def Close(self):
-    raise NotImplementedError()
-
-  def GetStandardOutput(self):
-    return self._app_backend.GetStandardOutput()
-
-  def GetStackTrace(self):
-    return self._app_backend.GetStackTrace()
-
-  def GetMostRecentMinidumpPath(self):
-    return self._app_backend.GetMostRecentMinidumpPath()
diff --git a/catapult/telemetry/telemetry/internal/app/android_app.py b/catapult/telemetry/telemetry/internal/app/android_app.py
deleted file mode 100644
index 0cee256..0000000
--- a/catapult/telemetry/telemetry/internal/app/android_app.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal import app
-
-
-class AndroidApp(app.App):
-  """A running android app instance that can be controlled in a limited way.
-
-  Be sure to clean up after yourself by calling Close() when you are done with
-  the app. Or better yet:
-    with possible_android_app.Create(options) as android_app:
-      ... do all your operations on android_app here
-  """
-  def __init__(self, app_backend, platform_backend):
-    super(AndroidApp, self).__init__(app_backend=app_backend,
-                                     platform_backend=platform_backend)
-    self._app_backend.Start()
-
-  @property
-  def ui(self):
-    """Returns an AppUi object to interact with the app's UI.
-
-    See devil.android.app_ui for the documentation of the API provided.
-    """
-    return self._app_backend.GetAppUi()
-
-  def Close(self):
-    self._app_backend.Close()
-
-  def GetProcesses(self):
-    """Returns the current set of processes belonging to this app."""
-    return self._app_backend.GetProcesses()
-
-  def GetProcess(self, subprocess_name):
-    """Returns the process with the specified subprocess name."""
-    return self._app_backend.GetProcess(subprocess_name)
-
-  def GetWebViews(self):
-    """Returns the set of all WebViews belonging to all processes of the app."""
-    return self._app_backend.GetWebViews()
diff --git a/catapult/telemetry/telemetry/internal/app/android_app_unittest.py b/catapult/telemetry/telemetry/internal/app/android_app_unittest.py
deleted file mode 100644
index f63b2e0..0000000
--- a/catapult/telemetry/telemetry/internal/app/android_app_unittest.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-import unittest
-
-from telemetry.core import platform as platform_module
-from telemetry.internal.app import android_app
-from telemetry.internal.backends import android_app_backend
-from telemetry.internal.platform import android_device
-from telemetry.testing import options_for_unittests
-
-from devil.android.sdk import intent
-
-
-class AndroidAppTest(unittest.TestCase):
-  def setUp(self):
-    self._options = options_for_unittests.GetCopy()
-    self._device = android_device.GetDevice(self._options)
-
-  def CreateAndroidApp(self, start_intent):
-    platform = platform_module.GetPlatformForDevice(self._device, self._options)
-    platform_backend = platform._platform_backend
-    app_backend = android_app_backend.AndroidAppBackend(
-        platform_backend, start_intent)
-    return android_app.AndroidApp(app_backend, platform_backend)
-
-  def testWebView(self):
-    if self._device is None:
-      logging.warning('No device found, skipping test.')
-      return
-
-    start_intent = intent.Intent(
-        package='com.google.android.googlequicksearchbox',
-        activity='.SearchActivity',
-        action='com.google.android.googlequicksearchbox.GOOGLE_SEARCH',
-        data=None,
-        extras={'query': 'google'},
-        category=None)
-    search_app = self.CreateAndroidApp(start_intent)
-    search_process = search_app.GetProcess(':search')
-    search_process._UpdateDevToolsClient()
-
-    # TODO(ariblue): Replace the app used in this test with one in which the
-    # setWebContentsDebuggingEnabled method is called on the WebView class.
-    # This will configure webviews for debugging with chrome devtools inspector
-    # and allow us to remove this check.
-    if search_process._devtools_client is None:
-      return
-
-    webview = search_app.GetProcess(':search').GetWebViews().pop()
-    webview.Navigate('https://www.google.com/search?q=flowers')
-    time.sleep(5)
diff --git a/catapult/telemetry/telemetry/internal/app/android_process.py b/catapult/telemetry/telemetry/internal/app/android_process.py
deleted file mode 100644
index 3c9a294..0000000
--- a/catapult/telemetry/telemetry/internal/app/android_process.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.backends.chrome_inspector import devtools_client_backend
-from telemetry.internal.browser import web_contents
-
-try:
-  from devil.android import ports
-except ImportError:
-  ports = None
-
-class WebViewNotFoundException(Exception):
-  pass
-
-class AndroidProcess(object):
-  """Represents a single android process."""
-
-  def __init__(self, app_backend, pid, name):
-    self._app_backend = app_backend
-    self._pid = pid
-    self._name = name
-    self._local_port = ports.AllocateTestServerPort()
-    self._devtools_client = None
-
-  @property
-  def pid(self):
-    return self._pid
-
-  @property
-  def name(self):
-    return self._name
-
-  @property
-  def _remote_devtools_port(self):
-    return 'localabstract:webview_devtools_remote_%s' % str(self.pid)
-
-  def _UpdateDevToolsClient(self):
-    if self._devtools_client is None:
-      self._app_backend.platform_backend.ForwardHostToDevice(
-          self._local_port, self._remote_devtools_port)
-      if devtools_client_backend.IsDevToolsAgentAvailable(
-          self._local_port, self._app_backend):
-        self._devtools_client = devtools_client_backend.DevToolsClientBackend(
-            self._local_port, self._remote_devtools_port, self._app_backend)
-
-  def GetWebViews(self):
-    webviews = []
-    self._UpdateDevToolsClient()
-    if self._devtools_client is not None:
-      devtools_context_map = (
-          self._devtools_client.GetUpdatedInspectableContexts())
-      for context in devtools_context_map.contexts:
-        webviews.append(web_contents.WebContents(
-            devtools_context_map.GetInspectorBackend(context['id'])))
-    return webviews
diff --git a/catapult/telemetry/telemetry/internal/app/possible_app.py b/catapult/telemetry/telemetry/internal/app/possible_app.py
deleted file mode 100644
index ee53f5b..0000000
--- a/catapult/telemetry/telemetry/internal/app/possible_app.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class PossibleApp(object):
-  """A factory class that can be used to create a running instance of app.
-
-  Call Create() to launch the app and begin manipulating it.
-  """
-
-  def __init__(self, app_type, target_os):
-    self._app_type = app_type
-    self._target_os = target_os
-    self._platform = None
-    self._platform_backend = None
-
-  def __repr__(self):
-    return 'PossibleApp(app_type=%s)' % self.app_type
-
-  @property
-  def app_type(self):
-    return self._app_type
-
-  @property
-  def target_os(self):
-    """Target OS, the app will run on."""
-    return self._target_os
-
-  @property
-  def platform(self):
-    self._InitPlatformIfNeeded()
-    return self._platform
-
-  def _InitPlatformIfNeeded(self):
-    raise NotImplementedError()
-
-  def Create(self, finder_options):
-    raise NotImplementedError()
-
-  def SupportsOptions(self, browser_options):
-    """Tests for extension support."""
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/internal/backends/__init__.py b/catapult/telemetry/telemetry/internal/backends/__init__.py
deleted file mode 100644
index 9228df8..0000000
--- a/catapult/telemetry/telemetry/internal/backends/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/backends/android_app_backend.py b/catapult/telemetry/telemetry/internal/backends/android_app_backend.py
deleted file mode 100644
index 1d308cc..0000000
--- a/catapult/telemetry/telemetry/internal/backends/android_app_backend.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-from telemetry.internal.app import android_process
-from telemetry.internal.backends import android_browser_backend_settings
-from telemetry.internal.backends import app_backend
-
-from devil.android import app_ui
-from devil.android import flag_changer
-from devil.android.sdk import intent
-
-import py_utils
-
-
-class AndroidAppBackend(app_backend.AppBackend):
-
-  def __init__(self, android_platform_backend, start_intent,
-               is_app_ready_predicate=None, app_has_webviews=True):
-    super(AndroidAppBackend, self).__init__(
-        start_intent.package, android_platform_backend)
-    self._default_process_name = start_intent.package
-    self._start_intent = start_intent
-    self._is_app_ready_predicate = is_app_ready_predicate
-    self._is_running = False
-    self._app_has_webviews = app_has_webviews
-    self._existing_processes_by_pid = {}
-    self._app_ui = None
-
-  @property
-  def device(self):
-    return self.platform_backend.device
-
-  def GetAppUi(self):
-    if self._app_ui is None:
-      self._app_ui = app_ui.AppUi(self.device, self._start_intent.package)
-    return self._app_ui
-
-  def _LaunchAndWaitForApplication(self):
-    """Launch the app and wait for it to be ready."""
-    def is_app_ready():
-      return self._is_app_ready_predicate(self.app)
-
-    # When "is_app_ready_predicate" is provided, we use it to wait for the
-    # app to become ready, otherwise "blocking=True" is used as a fall back.
-    # TODO(slamm): check if the wait for "ps" check is really needed, or
-    # whether the "blocking=True" fall back is sufficient.
-    has_ready_predicate = self._is_app_ready_predicate is not None
-    self.device.StartActivity(
-        self._start_intent,
-        blocking=not has_ready_predicate,
-        force_stop=True,  # Ensure app was not running.
-    )
-    if has_ready_predicate:
-      py_utils.WaitFor(is_app_ready, timeout=60)
-
-  def Start(self):
-    """Start an Android app and wait for it to finish launching.
-
-    If the app has webviews, the app is launched with the suitable
-    command line arguments.
-
-    AppStory derivations can customize the wait-for-ready-state to wait
-    for a more specific event if needed.
-    """
-    if self._app_has_webviews:
-      webview_startup_args = self.GetWebviewStartupArgs()
-      command_line_name = (
-          android_browser_backend_settings.WebviewBackendSettings(
-              'android-webview')).command_line_name
-      with flag_changer.CustomCommandLineFlags(
-          self.device, command_line_name, webview_startup_args):
-        self._LaunchAndWaitForApplication()
-    else:
-      self._LaunchAndWaitForApplication()
-    self._is_running = True
-
-  def Foreground(self):
-    self.device.StartActivity(
-        intent.Intent(package=self._start_intent.package,
-                      activity=self._start_intent.activity,
-                      action=None,
-                      flags=[intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED]),
-        blocking=True)
-
-  def Background(self):
-    package = 'org.chromium.push_apps_to_background'
-    activity = package + '.PushAppsToBackgroundActivity'
-    self.device.StartActivity(
-        intent.Intent(
-            package=package,
-            activity=activity,
-            action=None,
-            flags=[intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED]),
-        blocking=True)
-
-  def Close(self):
-    self._is_running = False
-    self.platform_backend.KillApplication(self._start_intent.package)
-
-  def IsAppRunning(self):
-    return self._is_running
-
-  def GetStandardOutput(self):
-    raise NotImplementedError
-
-  def GetStackTrace(self):
-    raise NotImplementedError
-
-  def GetProcesses(self, process_filter=None):
-    if process_filter is None:
-      # Match process names of the form: 'process_name[:subprocess]'.
-      process_filter = re.compile(
-          '^%s(:|$)' % re.escape(self._default_process_name)).match
-
-    processes = set()
-    ps_output = self.platform_backend.GetPsOutput(['pid', 'name'])
-    for pid, name in ps_output:
-      if not process_filter(name):
-        continue
-
-      if pid not in self._existing_processes_by_pid:
-        self._existing_processes_by_pid[pid] = android_process.AndroidProcess(
-            self, pid, name)
-      processes.add(self._existing_processes_by_pid[pid])
-    return processes
-
-  def GetProcess(self, subprocess_name):
-    assert subprocess_name.startswith(':')
-    process_name = self._default_process_name + subprocess_name
-    return self.GetProcesses(lambda n: n == process_name).pop()
-
-  def GetWebViews(self):
-    assert self._app_has_webviews
-    webviews = set()
-    for process in self.GetProcesses():
-      webviews.update(process.GetWebViews())
-    return webviews
-
-  def GetWebviewStartupArgs(self):
-    assert self._app_has_webviews
-    args = []
-
-    # Turn on GPU benchmarking extension for all runs. The only side effect of
-    # the extension being on is that render stats are tracked. This is believed
-    # to be effectively free. And, by doing so here, it avoids us having to
-    # programmatically inspect a pageset's actions in order to determine if it
-    # might eventually scroll.
-    args.append('--enable-gpu-benchmarking')
-
-    return args
diff --git a/catapult/telemetry/telemetry/internal/backends/android_app_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/android_app_backend_unittest.py
deleted file mode 100644
index 8140e89..0000000
--- a/catapult/telemetry/telemetry/internal/backends/android_app_backend_unittest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import collections
-import mock
-import unittest
-
-from telemetry.internal.backends import android_app_backend
-from devil.android.sdk import intent as intent_module
-
-
-_FakeAndroidProcess = collections.namedtuple(
-    'AndroidProcess', ['app_backend', 'pid', 'name'])
-
-
-class AndroidAppBackendUnittest(unittest.TestCase):
-
-  def setUp(self):
-    self.platform_backend = mock.Mock()
-    self.start_intent = intent_module.Intent(
-        package='com.example.my_app',
-        activity='com.example.my_app.LaunchMyApp')
-    self.app_backend = android_app_backend.AndroidAppBackend(
-        self.platform_backend, self.start_intent)
-
-  @mock.patch('telemetry.internal.backends.android_app_backend'
-              '.android_process.AndroidProcess', _FakeAndroidProcess)
-  def testGetProcesses(self):
-    # Only processes belonging to 'com.example.my_app' should match.
-    self.platform_backend.GetPsOutput.return_value = [
-      ['1111', 'com.example.my_app'],
-      ['2222', 'com.example.my_appointments_helper'],
-      ['3333', 'com.example.my_app:service'],
-      ['4444', 'com.example.some_other_app'],
-      ['5555', 'com_example_my_app'],
-    ]
-    process_pids = set(p.pid for p in self.app_backend.GetProcesses())
-    self.assertEquals(process_pids, set(['1111', '3333']))
diff --git a/catapult/telemetry/telemetry/internal/backends/android_browser_backend_settings.py b/catapult/telemetry/telemetry/internal/backends/android_browser_backend_settings.py
deleted file mode 100644
index 1151b9a..0000000
--- a/catapult/telemetry/telemetry/internal/backends/android_browser_backend_settings.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-
-
-class AndroidBrowserBackendSettings(object):
-
-  def __init__(self, activity, cmdline_file, package, pseudo_exec_name,
-               supports_tab_control):
-    self._activity = activity
-    self._cmdline_file = cmdline_file
-    self._package = package
-    self._pseudo_exec_name = pseudo_exec_name
-    self._supports_tab_control = supports_tab_control
-
-  @property
-  def activity(self):
-    return self._activity
-
-  @property
-  def package(self):
-    return self._package
-
-  @property
-  def pseudo_exec_name(self):
-    return self._pseudo_exec_name
-
-  @property
-  def supports_tab_control(self):
-    return self._supports_tab_control
-
-  @property
-  def command_line_name(self):
-    return self._cmdline_file
-
-  def GetDevtoolsRemotePort(self, device):
-    raise NotImplementedError()
-
-  @property
-  def profile_ignore_list(self):
-    # Don't delete lib, since it is created by the installer.
-    return ['lib']
-
-
-class ChromeBackendSettings(AndroidBrowserBackendSettings):
-  # Stores a default Preferences file, re-used to speed up "--page-repeat".
-  _default_preferences_file = None
-
-  def __init__(self, package):
-    super(ChromeBackendSettings, self).__init__(
-        activity='com.google.android.apps.chrome.Main',
-        cmdline_file='chrome-command-line',
-        package=package,
-        pseudo_exec_name='chrome',
-        supports_tab_control=True)
-
-  def GetDevtoolsRemotePort(self, device):
-    return 'localabstract:chrome_devtools_remote'
-
-
-class ContentShellBackendSettings(AndroidBrowserBackendSettings):
-  def __init__(self, package):
-    super(ContentShellBackendSettings, self).__init__(
-        activity='org.chromium.content_shell_apk.ContentShellActivity',
-        cmdline_file='content-shell-command-line',
-        package=package,
-        pseudo_exec_name='content_shell',
-        supports_tab_control=False)
-
-  def GetDevtoolsRemotePort(self, device):
-    return 'localabstract:content_shell_devtools_remote'
-
-
-class WebviewBackendSettings(AndroidBrowserBackendSettings):
-  def __init__(self,
-               package,
-               activity='org.chromium.webview_shell.TelemetryActivity',
-               cmdline_file='webview-command-line'):
-    super(WebviewBackendSettings, self).__init__(
-        activity=activity,
-        cmdline_file=cmdline_file,
-        package=package,
-        pseudo_exec_name='webview',
-        supports_tab_control=False)
-
-  def GetDevtoolsRemotePort(self, device):
-    # The DevTools socket name for WebView depends on the activity PID's.
-    retries = 0
-    timeout = 1
-    pid = None
-    while True:
-      pids = device.GetPids(self.package)
-      if not pids or self.package not in pids:
-        time.sleep(timeout)
-        retries += 1
-        timeout *= 2
-        if retries == 4:
-          logging.critical('android_browser_backend: Timeout while waiting for '
-                           'activity %s:%s to come up',
-                           self.package,
-                           self.activity)
-          raise Exception('Timeout waiting for PID.')
-      if len(pids.get(self.package, [])) > 1:
-        raise Exception(
-            'At most one instance of process %s expected but found pids: '
-            '%s' % (self.package, pids))
-      if len(pids.get(self.package, [])) == 1:
-        pid = pids[self.package][0]
-        break
-    return 'localabstract:webview_devtools_remote_%s' % str(pid)
-
-
-class WebviewShellBackendSettings(WebviewBackendSettings):
-  def __init__(self, package):
-    super(WebviewShellBackendSettings, self).__init__(
-        activity='org.chromium.android_webview.shell.AwShellActivity',
-        cmdline_file='android-webview-command-line',
-        package=package)
diff --git a/catapult/telemetry/telemetry/internal/backends/android_browser_backend_settings_unittest.py b/catapult/telemetry/telemetry/internal/backends/android_browser_backend_settings_unittest.py
deleted file mode 100644
index 5b6c6c2..0000000
--- a/catapult/telemetry/telemetry/internal/backends/android_browser_backend_settings_unittest.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import mock
-import unittest
-
-from telemetry.internal.backends import android_browser_backend_settings
-
-
-class AndroidBrowserBackendSettingsUnittest(unittest.TestCase):
-
-  def testWebViewGetDevtoolsRemotePortRetrySuccess(self):
-    mock_device = mock.Mock()
-    mock_device.GetPids.side_effect = [
-        {},
-        {},
-        {'webview.package': ['1111']},
-    ]
-
-    settings = android_browser_backend_settings.WebviewBackendSettings(
-        package='webview.package')
-    with mock.patch('time.sleep', return_value=None):
-      self.assertEquals(
-          settings.GetDevtoolsRemotePort(mock_device),
-          'localabstract:webview_devtools_remote_1111')
-
-  def testWebViewGetDevtoolsRemotePortMultipleProcessesFailure(self):
-    mock_device = mock.Mock()
-    mock_device.GetPids.side_effect = [
-        {'webview.package': ['1111', '2222']}
-    ]
-
-    settings = android_browser_backend_settings.WebviewBackendSettings(
-        package='webview.package')
-    with mock.patch('time.sleep', return_value=None):
-      with self.assertRaises(Exception):
-        settings.GetDevtoolsRemotePort(mock_device)
-
-  def testWebViewGetDevtoolsRemotePortTimeoutFailure(self):
-    mock_device = mock.Mock()
-    mock_device.GetPids.side_effect = [
-        {},
-        {},
-        {},
-        {},
-    ]
-
-    settings = android_browser_backend_settings.WebviewBackendSettings(
-        package='webview.package')
-    with mock.patch('time.sleep', return_value=None) as time_mock:
-      with self.assertRaises(Exception):
-        settings.GetDevtoolsRemotePort(mock_device)
-      time_mock.assert_has_calls(
-          [mock.call(1), mock.call(2), mock.call(4), mock.call(8)])
diff --git a/catapult/telemetry/telemetry/internal/backends/app_backend.py b/catapult/telemetry/telemetry/internal/backends/app_backend.py
deleted file mode 100644
index dadb1c1..0000000
--- a/catapult/telemetry/telemetry/internal/backends/app_backend.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from py_trace_event import trace_event
-
-
-class AppBackend(object):
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def __init__(self, app_type, platform_backend):
-    super(AppBackend, self).__init__()
-    self._app = None
-    self._app_type = app_type
-    self._platform_backend = platform_backend
-
-  def __del__(self):
-    self.Close()
-
-  def SetApp(self, app):
-    self._app = app
-
-  @property
-  def app(self):
-    return self._app
-
-  @property
-  def app_type(self):
-    return self._app_type
-
-  @property
-  def pid(self):
-    raise NotImplementedError
-
-  @property
-  def platform_backend(self):
-    return self._platform_backend
-
-  def Start(self):
-    raise NotImplementedError
-
-  def Foreground(self):
-    # TODO(catapult:#2194): Remove the unnecessary pass below when the method
-    # has been implemented on all concrete subclasses.
-    pass  # pylint: disable=unnecessary-pass
-    raise NotImplementedError
-
-  def Background(self):
-    raise NotImplementedError
-
-  def Close(self):
-    raise NotImplementedError
-
-  def IsAppRunning(self):
-    raise NotImplementedError
-
-  def GetStandardOutput(self):
-    raise NotImplementedError
-
-  def GetStackTrace(self):
-    raise NotImplementedError
-
-  def GetMostRecentMinidumpPath(self):
-    raise NotImplementedError
diff --git a/catapult/telemetry/telemetry/internal/backends/browser_backend.py b/catapult/telemetry/telemetry/internal/backends/browser_backend.py
deleted file mode 100644
index 43e7773..0000000
--- a/catapult/telemetry/telemetry/internal/backends/browser_backend.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import uuid
-import sys
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry import decorators
-from telemetry.internal.backends import app_backend
-from telemetry.internal.browser import web_contents
-from telemetry.internal.platform import profiling_controller_backend
-
-
-class ExtensionsNotSupportedException(Exception):
-  pass
-
-
-class BrowserBackend(app_backend.AppBackend):
-  """A base class for browser backends."""
-
-  def __init__(self, platform_backend, supports_extensions, browser_options,
-               tab_list_backend):
-    assert browser_options.browser_type
-    super(BrowserBackend, self).__init__(
-        browser_options.browser_type, platform_backend)
-    self._supports_extensions = supports_extensions
-    self.browser_options = browser_options
-    self._tab_list_backend_class = tab_list_backend
-    self._profiling_controller_backend = (
-        profiling_controller_backend.ProfilingControllerBackend(
-          platform_backend, self))
-
-  def SetBrowser(self, browser):
-    super(BrowserBackend, self).SetApp(app=browser)
-
-  @property
-  def log_file_path(self):
-    # Specific browser backend is responsible for overriding this properly.
-    raise NotImplementedError
-
-  def GetLogFileContents(self):
-    if not self.log_file_path:
-      return 'No log file'
-    with file(self.log_file_path) as f:
-      return f.read()
-
-  def UploadLogsToCloudStorage(self):
-    """ Uploading log files produce by this browser instance to cloud storage.
-
-    Check supports_uploading_logs before calling this method.
-    """
-    assert self.supports_uploading_logs
-    remote_path = (self.browser_options.logs_cloud_remote_path or
-                   'log_%s' % uuid.uuid4())
-    cloud_url = cloud_storage.Insert(
-        bucket=self.browser_options.logs_cloud_bucket,
-        remote_path=remote_path,
-        local_path=self.log_file_path)
-    sys.stderr.write('Uploading browser log to %s\n' % cloud_url)
-
-  @property
-  def browser(self):
-    return self.app
-
-  @property
-  def profiling_controller_backend(self):
-    return self._profiling_controller_backend
-
-  @property
-  def browser_type(self):
-    return self.app_type
-
-  @property
-  def supports_uploading_logs(self):
-    # Specific browser backend is responsible for overriding this properly.
-    return False
-
-  @property
-  def supports_extensions(self):
-    """True if this browser backend supports extensions."""
-    return self._supports_extensions
-
-  @property
-  def supports_tab_control(self):
-    raise NotImplementedError()
-
-  @property
-  @decorators.Cache
-  def tab_list_backend(self):
-    return self._tab_list_backend_class(self)
-
-  @property
-  def supports_tracing(self):
-    raise NotImplementedError()
-
-  @property
-  def supports_system_info(self):
-    return False
-
-  def StartTracing(self, trace_options,
-                   timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    raise NotImplementedError()
-
-  def StopTracing(self):
-    raise NotImplementedError()
-
-  def CollectTracingData(self, trace_data_builder):
-    raise NotImplementedError()
-
-  def Start(self):
-    raise NotImplementedError()
-
-  def IsBrowserRunning(self):
-    raise NotImplementedError()
-
-  def IsAppRunning(self):
-    return self.IsBrowserRunning()
-
-  def GetStandardOutput(self):
-    raise NotImplementedError()
-
-  def GetStackTrace(self):
-    raise NotImplementedError()
-
-  def GetMostRecentMinidumpPath(self):
-    raise NotImplementedError()
-
-  def GetAllMinidumpPaths(self):
-    raise NotImplementedError()
-
-  def GetAllUnsymbolizedMinidumpPaths(self):
-    raise NotImplementedError()
-
-  def SymbolizeMinidump(self, minidump_path):
-    raise NotImplementedError()
-
-  def GetSystemInfo(self):
-    raise NotImplementedError()
-
-  @property
-  def supports_memory_dumping(self):
-    return False
-
-  def DumpMemory(self, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    raise NotImplementedError()
-
-  @property
-  def supports_overriding_memory_pressure_notifications(self):
-    return False
-
-  def SetMemoryPressureNotificationsSuppressed(
-      self, suppressed, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    raise NotImplementedError()
-
-  def SimulateMemoryPressureNotification(
-      self, pressure_level, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    raise NotImplementedError()
-
-  @property
-  def supports_cpu_metrics(self):
-    raise NotImplementedError()
-
-  @property
-  def supports_memory_metrics(self):
-    raise NotImplementedError()
-
-  @property
-  def supports_power_metrics(self):
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/internal/backends/browser_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/browser_backend_unittest.py
deleted file mode 100644
index 702c967..0000000
--- a/catapult/telemetry/telemetry/internal/backends/browser_backend_unittest.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import tempfile
-import unittest
-
-from telemetry.internal.backends import browser_backend
-from telemetry.testing import options_for_unittests
-import mock
-
-
-class BrowserBackendLogsUploadingUnittest(unittest.TestCase):
-  def testUploadingToCLoudStorage(self):
-    temp_file = tempfile.NamedTemporaryFile(delete=False)
-    temp_file_name = temp_file.name
-    try:
-      temp_file.write('This is a\ntest log file.\n')
-      temp_file.close()
-
-      # pylint: disable=abstract-method
-      class FakeBrowserBackend(browser_backend.BrowserBackend):
-        @property
-        def supports_uploading_logs(self):
-          return True
-
-        @property
-        def log_file_path(self):
-          return temp_file_name
-
-      options = options_for_unittests.GetCopy()
-      options.browser_options.logging_verbosity = (
-          options.browser_options.VERBOSE_LOGGING)
-      options.browser_options.logs_cloud_bucket = 'ABC'
-      options.browser_options.logs_cloud_remote_path = 'def'
-
-      b = FakeBrowserBackend(None, False, options.browser_options, None)
-      self.assertEquals(b.GetLogFileContents(), 'This is a\ntest log file.\n')
-      with mock.patch('py_utils.cloud_storage.Insert') as mock_insert:
-        b.UploadLogsToCloudStorage()
-        mock_insert.assert_called_with(
-            bucket='ABC', remote_path='def', local_path=temp_file_name)
-    finally:
-      os.remove(temp_file_name)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/__init__.py b/catapult/telemetry/telemetry/internal/backends/chrome/__init__.py
deleted file mode 100644
index 9228df8..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py
deleted file mode 100644
index 763f965..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_backend.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import subprocess
-
-from telemetry.core import exceptions
-from telemetry.internal.platform import android_platform_backend as \
-  android_platform_backend_module
-from telemetry.core import util
-from telemetry.internal.backends import browser_backend
-from telemetry.internal.backends.chrome import chrome_browser_backend
-from telemetry.internal.browser import user_agent
-
-from devil.android import app_ui
-from devil.android import flag_changer
-from devil.android.sdk import intent
-
-
-class AndroidBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
-  """The backend for controlling a browser instance running on Android."""
-  def __init__(self, android_platform_backend, browser_options,
-               backend_settings):
-    assert isinstance(android_platform_backend,
-                      android_platform_backend_module.AndroidPlatformBackend)
-    super(AndroidBrowserBackend, self).__init__(
-        android_platform_backend,
-        supports_tab_control=backend_settings.supports_tab_control,
-        supports_extensions=False, browser_options=browser_options)
-
-    self._port_keeper = util.PortKeeper()
-    # Use the port hold by _port_keeper by default.
-    self._port = self._port_keeper.port
-
-    extensions_to_load = browser_options.extensions_to_load
-
-    if len(extensions_to_load) > 0:
-      raise browser_backend.ExtensionsNotSupportedException(
-          'Android browser does not support extensions.')
-
-    # Initialize fields so that an explosion during init doesn't break in Close.
-    self._backend_settings = backend_settings
-    self._saved_sslflag = ''
-
-    # Stop old browser, if any.
-    self._StopBrowser()
-
-    if self.device.HasRoot() or self.device.NeedsSU():
-      if self.browser_options.profile_dir:
-        self.platform_backend.PushProfile(
-            self._backend_settings.package,
-            self.browser_options.profile_dir)
-      elif not self.browser_options.dont_override_profile:
-        self.platform_backend.RemoveProfile(
-            self._backend_settings.package,
-            self._backend_settings.profile_ignore_list)
-
-    # Set the debug app if needed.
-    self.platform_backend.SetDebugApp(self._backend_settings.package)
-
-  @property
-  def log_file_path(self):
-    return None
-
-  @property
-  def device(self):
-    return self.platform_backend.device
-
-  def _StopBrowser(self):
-    # Note: it's important to stop and _not_ kill the browser app, since
-    # stopping also clears the app state in Android's activity manager.
-    self.platform_backend.StopApplication(self._backend_settings.package)
-
-  def Start(self):
-    self.device.adb.Logcat(clear=True)
-    if self.browser_options.startup_url:
-      url = self.browser_options.startup_url
-    elif self.browser_options.profile_dir:
-      url = None
-    else:
-      # If we have no existing tabs start with a blank page since default
-      # startup with the NTP can lead to race conditions with Telemetry
-      url = 'about:blank'
-
-    self.platform_backend.DismissCrashDialogIfNeeded()
-
-    user_agent_dict = user_agent.GetChromeUserAgentDictFromType(
-        self.browser_options.browser_user_agent_type)
-
-    browser_startup_args = self.GetBrowserStartupArgs()
-    command_line_name = self._backend_settings.command_line_name
-    with flag_changer.CustomCommandLineFlags(
-        self.device, command_line_name, browser_startup_args):
-      self.device.StartActivity(
-          intent.Intent(package=self._backend_settings.package,
-                        activity=self._backend_settings.activity,
-                        action=None, data=url, category=None,
-                        extras=user_agent_dict),
-          blocking=True)
-
-      # TODO(crbug.com/404771): Move port forwarding to network_controller.
-      remote_devtools_port = self._backend_settings.GetDevtoolsRemotePort(
-          self.device)
-      try:
-        # Release reserved port right before forwarding host to device.
-        self._port_keeper.Release()
-        assert self._port == self._port_keeper.port, (
-          'Android browser backend must use reserved port by _port_keeper')
-        self.platform_backend.ForwardHostToDevice(
-            self._port, remote_devtools_port)
-      except Exception:
-        logging.exception('Failed to forward %s to %s.',
-            str(self._port), str(remote_devtools_port))
-        logging.warning('Currently forwarding:')
-        try:
-          for line in self.device.adb.ForwardList().splitlines():
-            logging.warning('  %s', line)
-        except Exception:
-          logging.warning('Exception raised while listing forwarded '
-                          'connections.')
-
-        logging.warning('Host tcp ports in use:')
-        try:
-          for line in subprocess.check_output(['netstat', '-t']).splitlines():
-            logging.warning('  %s', line)
-        except Exception:
-          logging.warning('Exception raised while listing tcp ports.')
-
-        logging.warning('Device unix domain sockets in use:')
-        try:
-          for line in self.device.ReadFile('/proc/net/unix', as_root=True,
-                                           force_pull=True).splitlines():
-            logging.warning('  %s', line)
-        except Exception:
-          logging.warning('Exception raised while listing unix domain sockets.')
-
-        raise
-
-      try:
-        self._WaitForBrowserToComeUp()
-        self._InitDevtoolsClientBackend(remote_devtools_port)
-      except exceptions.BrowserGoneException:
-        logging.critical('Failed to connect to browser.')
-        if not (self.device.HasRoot() or self.device.NeedsSU()):
-          logging.critical(
-            'Resolve this by either: '
-            '(1) Flashing to a userdebug build OR '
-            '(2) Manually enabling web debugging in Chrome at '
-            'Settings > Developer tools > Enable USB Web debugging.')
-        self.Close()
-        raise
-      except:
-        self.Close()
-        raise
-
-  def Foreground(self):
-    package = self._backend_settings.package
-    activity = self._backend_settings.activity
-    self.device.StartActivity(
-        intent.Intent(package=package,
-                      activity=activity,
-                      action=None,
-                      flags=[intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED]),
-        blocking=False)
-    # TODO(crbug.com/601052): The following waits for any UI node for the
-    # package launched to appear on the screen. When the referenced bug is
-    # fixed, remove this workaround and just switch blocking above to True.
-    try:
-      app_ui.AppUi(self.device).WaitForUiNode(package=package)
-    except Exception:
-      raise exceptions.BrowserGoneException(self.browser,
-          'Timed out waiting for browser to come back foreground.')
-
-  def Background(self):
-    package = 'org.chromium.push_apps_to_background'
-    activity = package + '.PushAppsToBackgroundActivity'
-    self.device.StartActivity(
-        intent.Intent(
-            package=package,
-            activity=activity,
-            action=None,
-            flags=[intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED]),
-        blocking=True)
-
-  def GetBrowserStartupArgs(self):
-    args = super(AndroidBrowserBackend, self).GetBrowserStartupArgs()
-    args.append('--enable-remote-debugging')
-    args.append('--disable-fre')
-    args.append('--disable-external-intent-requests')
-    return args
-
-  @property
-  def pid(self):
-    pids = self.device.GetPids(self._backend_settings.package)
-    if not pids or self._backend_settings.package not in pids:
-      raise exceptions.BrowserGoneException(self.browser)
-    if len(pids[self._backend_settings.package]) > 1:
-      raise Exception(
-          'At most one instance of process %s expected but found pids: '
-          '%s' % (self._backend_settings.package, pids))
-    return int(pids[self._backend_settings.package][0])
-
-  @property
-  def browser_directory(self):
-    return None
-
-  @property
-  def profile_directory(self):
-    return self._backend_settings.profile_dir
-
-  @property
-  def package(self):
-    return self._backend_settings.package
-
-  @property
-  def activity(self):
-    return self._backend_settings.activity
-
-  def __del__(self):
-    self.Close()
-
-  def Close(self):
-    super(AndroidBrowserBackend, self).Close()
-
-    self._StopBrowser()
-
-    self.platform_backend.StopForwardingHost(self._port)
-
-    if self._output_profile_path:
-      self.platform_backend.PullProfile(
-          self._backend_settings.package, self._output_profile_path)
-
-  def IsBrowserRunning(self):
-    return self.platform_backend.IsAppRunning(self._backend_settings.package)
-
-  def GetStandardOutput(self):
-    return self.platform_backend.GetStandardOutput()
-
-  def GetStackTrace(self):
-    return self.platform_backend.GetStackTrace()
-
-  def GetMostRecentMinidumpPath(self):
-    return None
-
-  def GetAllMinidumpPaths(self):
-    return None
-
-  def GetAllUnsymbolizedMinidumpPaths(self):
-    return None
-
-  def SymbolizeMinidump(self, minidump_path):
-    return None
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_finder.py b/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_finder.py
deleted file mode 100644
index 188a3e3..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_finder.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Finds android browsers that can be controlled by telemetry."""
-
-import logging
-import os
-import subprocess
-import sys
-
-from py_utils import dependency_util
-from devil import base_error
-from devil.android import apk_helper
-
-from telemetry.core import exceptions
-from telemetry.core import platform
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.backends import android_browser_backend_settings
-from telemetry.internal.backends.chrome import android_browser_backend
-from telemetry.internal.browser import browser
-from telemetry.internal.browser import possible_browser
-from telemetry.internal.platform import android_device
-from telemetry.internal.util import binary_manager
-
-
-CHROME_PACKAGE_NAMES = {
-  'android-content-shell':
-      ['org.chromium.content_shell_apk',
-       android_browser_backend_settings.ContentShellBackendSettings,
-       'ContentShell.apk'],
-  'android-webview':
-      ['org.chromium.webview_shell',
-       android_browser_backend_settings.WebviewBackendSettings,
-       None],
-  'android-webview-shell':
-      ['org.chromium.android_webview.shell',
-       android_browser_backend_settings.WebviewShellBackendSettings,
-       'AndroidWebView.apk'],
-  'android-chromium':
-      ['org.chromium.chrome',
-       android_browser_backend_settings.ChromeBackendSettings,
-       'ChromePublic.apk'],
-  'android-chrome':
-      ['com.google.android.apps.chrome',
-       android_browser_backend_settings.ChromeBackendSettings,
-       'Chrome.apk'],
-  'android-chrome-work':
-      ['com.chrome.work',
-       android_browser_backend_settings.ChromeBackendSettings,
-       None],
-  'android-chrome-beta':
-      ['com.chrome.beta',
-       android_browser_backend_settings.ChromeBackendSettings,
-       None],
-  'android-chrome-dev':
-      ['com.chrome.dev',
-       android_browser_backend_settings.ChromeBackendSettings,
-       None],
-  'android-chrome-canary':
-      ['com.chrome.canary',
-       android_browser_backend_settings.ChromeBackendSettings,
-       None],
-  'android-system-chrome':
-      ['com.android.chrome',
-       android_browser_backend_settings.ChromeBackendSettings,
-       None],
-}
-
-
-class PossibleAndroidBrowser(possible_browser.PossibleBrowser):
-  """A launchable android browser instance."""
-  def __init__(self, browser_type, finder_options, android_platform,
-               backend_settings, apk_name):
-    super(PossibleAndroidBrowser, self).__init__(
-        browser_type, 'android', backend_settings.supports_tab_control)
-    assert browser_type in FindAllBrowserTypes(finder_options), (
-        'Please add %s to android_browser_finder.FindAllBrowserTypes' %
-         browser_type)
-    self._platform = android_platform
-    self._platform_backend = (
-        android_platform._platform_backend)  # pylint: disable=protected-access
-    self._backend_settings = backend_settings
-    self._local_apk = None
-
-    if browser_type == 'exact':
-      if not os.path.exists(apk_name):
-        raise exceptions.PathMissingError(
-            'Unable to find exact apk %s specified by --browser-executable' %
-            apk_name)
-      self._local_apk = apk_name
-    elif browser_type == 'reference':
-      if not os.path.exists(apk_name):
-        raise exceptions.PathMissingError(
-            'Unable to find reference apk at expected location %s.' % apk_name)
-      self._local_apk = apk_name
-    elif apk_name:
-      assert finder_options.chrome_root, (
-          'Must specify Chromium source to use apk_name')
-      chrome_root = finder_options.chrome_root
-      candidate_apks = []
-      for build_path in util.GetBuildDirectories(chrome_root):
-        apk_full_name = os.path.join(build_path, 'apks', apk_name)
-        if os.path.exists(apk_full_name):
-          last_changed = os.path.getmtime(apk_full_name)
-          candidate_apks.append((last_changed, apk_full_name))
-
-      if candidate_apks:
-        # Find the candidate .apk with the latest modification time.
-        newest_apk_path = sorted(candidate_apks)[-1][1]
-        self._local_apk = newest_apk_path
-
-  def __repr__(self):
-    return 'PossibleAndroidBrowser(browser_type=%s)' % self.browser_type
-
-  def _InitPlatformIfNeeded(self):
-    pass
-
-  def Create(self, finder_options):
-    self._InitPlatformIfNeeded()
-    browser_backend = android_browser_backend.AndroidBrowserBackend(
-        self._platform_backend,
-        finder_options.browser_options, self._backend_settings)
-    try:
-      return browser.Browser(
-          browser_backend, self._platform_backend, self._credentials_path)
-    except Exception:
-      logging.exception('Failure while creating Android browser.')
-      original_exception = sys.exc_info()
-      try:
-        browser_backend.Close()
-      except Exception:
-        logging.exception('Secondary failure while closing browser backend.')
-
-      raise original_exception[0], original_exception[1], original_exception[2]
-
-  def SupportsOptions(self, browser_options):
-    if len(browser_options.extensions_to_load) != 0:
-      return False
-    return True
-
-  def HaveLocalAPK(self):
-    return self._local_apk and os.path.exists(self._local_apk)
-
-  @decorators.Cache
-  def UpdateExecutableIfNeeded(self):
-    if self.HaveLocalAPK():
-      logging.warn('Installing %s on device if needed.' % self._local_apk)
-      self.platform.InstallApplication(self._local_apk)
-
-  def last_modification_time(self):
-    if self.HaveLocalAPK():
-      return os.path.getmtime(self._local_apk)
-    return -1
-
-
-def SelectDefaultBrowser(possible_browsers):
-  """Return the newest possible browser."""
-  if not possible_browsers:
-    return None
-  return max(possible_browsers, key=lambda b: b.last_modification_time())
-
-
-def CanFindAvailableBrowsers():
-  return android_device.CanDiscoverDevices()
-
-
-def CanPossiblyHandlePath(target_path):
-  return os.path.splitext(target_path.lower())[1] == '.apk'
-
-
-def FindAllBrowserTypes(options):
-  del options  # unused
-  return CHROME_PACKAGE_NAMES.keys() + ['exact', 'reference']
-
-
-def _FindAllPossibleBrowsers(finder_options, android_platform):
-  """Testable version of FindAllAvailableBrowsers."""
-  if not android_platform:
-    return []
-  possible_browsers = []
-
-  # Add the exact APK if given.
-  if (finder_options.browser_executable and
-      CanPossiblyHandlePath(finder_options.browser_executable)):
-    apk_name = os.path.basename(finder_options.browser_executable)
-    normalized_path = os.path.expanduser(finder_options.browser_executable)
-    exact_package = apk_helper.GetPackageName(normalized_path)
-    package_info = next(
-        (info for info in CHROME_PACKAGE_NAMES.itervalues()
-         if info[0] == exact_package or info[2] == apk_name), None)
-
-    # It is okay if the APK name or package doesn't match any of known chrome
-    # browser APKs, since it may be of a different browser.
-    if package_info:
-      if not exact_package:
-        raise exceptions.PackageDetectionError(
-            'Unable to find package for %s specified by --browser-executable' %
-            normalized_path)
-
-      [package, backend_settings, _] = package_info
-      if package == exact_package:
-        possible_browsers.append(PossibleAndroidBrowser(
-            'exact',
-            finder_options,
-            android_platform,
-            backend_settings(package),
-            normalized_path))
-      else:
-        raise exceptions.UnknownPackageError(
-            '%s specified by --browser-executable has an unknown package: %s' %
-            (normalized_path, exact_package))
-
-  # Add the reference build if found.
-  os_version = dependency_util.GetChromeApkOsVersion(
-      android_platform.GetOSVersionName())
-  arch = android_platform.GetArchName()
-  try:
-    reference_build = binary_manager.FetchPath(
-        'chrome_stable', arch, 'android', os_version)
-  except (binary_manager.NoPathFoundError,
-          binary_manager.CloudStorageError):
-    reference_build = None
-
-  if reference_build and os.path.exists(reference_build):
-    # TODO(aiolos): how do we stably map the android chrome_stable apk to the
-    # correct package name?
-    package, backend_settings, _ = CHROME_PACKAGE_NAMES['android-chrome']
-    possible_browsers.append(PossibleAndroidBrowser(
-        'reference',
-        finder_options,
-        android_platform,
-        backend_settings(package),
-        reference_build))
-
-  # Add any known local versions.
-  for name, package_info in CHROME_PACKAGE_NAMES.iteritems():
-    package, backend_settings, apk_name = package_info
-    if apk_name and not finder_options.chrome_root:
-      continue
-    b = PossibleAndroidBrowser(name,
-                               finder_options,
-                               android_platform,
-                               backend_settings(package),
-                               apk_name)
-    if b.platform.CanLaunchApplication(package) or b.HaveLocalAPK():
-      possible_browsers.append(b)
-  return possible_browsers
-
-
-def FindAllAvailableBrowsers(finder_options, device):
-  """Finds all the possible browsers on one device.
-
-  The device is either the only device on the host platform,
-  or |finder_options| specifies a particular device.
-  """
-  if not isinstance(device, android_device.AndroidDevice):
-    return []
-
-  try:
-    android_platform = platform.GetPlatformForDevice(device, finder_options)
-    return _FindAllPossibleBrowsers(finder_options, android_platform)
-  except base_error.BaseError as e:
-    logging.error('Unable to find browsers on %s: %s', device.device_id, str(e))
-    ps_output = subprocess.check_output(['ps', '-ef'])
-    logging.error('Ongoing processes:\n%s', ps_output)
-  return []
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_finder_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_finder_unittest.py
deleted file mode 100644
index 7425e57..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/android_browser_finder_unittest.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-import mock
-from pyfakefs import fake_filesystem_unittest
-
-from telemetry.core import android_platform
-from telemetry.internal.backends.chrome import android_browser_finder
-from telemetry.internal.platform import android_platform_backend
-from telemetry.internal.util import binary_manager
-from telemetry.testing import options_for_unittests
-
-
-def FakeFetchPath(dependency, arch, os_name, os_version=None):
-  return os.path.join(
-      'dependency_dir', dependency, '%s_%s_%s.apk' % (
-        os_name, os_version, arch))
-
-
-class AndroidBrowserFinderTest(fake_filesystem_unittest.TestCase):
-  def setUp(self):
-    self.finder_options = options_for_unittests.GetCopy()
-    # Mock out what's needed for testing with exact APKs
-    self.setUpPyfakefs()
-    self._fetch_path_patcher = mock.patch(
-        'telemetry.internal.backends.chrome.android_browser_finder.binary_manager.FetchPath',  # pylint: disable=line-too-long
-        FakeFetchPath)
-    self._fetch_path_mock = self._fetch_path_patcher.start()
-    self._get_package_name_patcher = mock.patch(
-        'devil.android.apk_helper.GetPackageName')
-    self._get_package_name_mock = self._get_package_name_patcher.start()
-    self.fake_platform = mock.Mock(spec=android_platform.AndroidPlatform)
-    self.fake_platform.CanLaunchApplication.return_value = True
-    self.fake_platform._platform_backend = mock.create_autospec(
-        android_platform_backend, spec_set=True)
-    self.fake_platform.GetOSVersionName.return_value = 'L23ds5'
-    self.fake_platform.GetArchName.return_value = 'armeabi-v7a'
-    # The android_browser_finder converts the os version name to 'k' or 'l'
-    self.expected_reference_build = FakeFetchPath(
-        'chrome_stable', 'armeabi-v7a', 'android', 'l')
-
-  def tearDown(self):
-    self.tearDownPyfakefs()
-    self._get_package_name_patcher.stop()
-    self._fetch_path_patcher.stop()
-
-  def testNoPlatformReturnsEmptyList(self):
-    fake_platform = None
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, fake_platform)
-    self.assertEqual([], possible_browsers)
-
-  def testCanLaunchAlwaysTrueReturnsAllExceptExactAndReference(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    all_types = set(
-        android_browser_finder.FindAllBrowserTypes(self.finder_options))
-    expected_types = all_types - set(('exact', 'reference'))
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, self.fake_platform)
-    self.assertEqual(
-        expected_types,
-        set([b.browser_type for b in possible_browsers]))
-
-  def testCanLaunchAlwaysTrueReturnsAllExceptExact(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    self.fs.CreateFile(self.expected_reference_build)
-    all_types = set(
-        android_browser_finder.FindAllBrowserTypes(self.finder_options))
-    expected_types = all_types - set(('exact',))
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, self.fake_platform)
-    self.assertEqual(
-        expected_types,
-        set([b.browser_type for b in possible_browsers]))
-
-  def testCanLaunchAlwaysTrueWithExactApkReturnsAll(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    self.fs.CreateFile(
-        '/foo/ContentShell.apk')
-    self.fs.CreateFile(self.expected_reference_build)
-    self.finder_options.browser_executable = '/foo/ContentShell.apk'
-    self._get_package_name_mock.return_value = 'org.chromium.content_shell_apk'
-
-    expected_types = set(
-        android_browser_finder.FindAllBrowserTypes(self.finder_options))
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, self.fake_platform)
-    self.assertEqual(
-        expected_types,
-        set([b.browser_type for b in possible_browsers]))
-
-  def testErrorWithUnknownExactApk(self):
-    self.fs.CreateFile(
-        '/foo/ContentShell.apk')
-    self.finder_options.browser_executable = '/foo/ContentShell.apk'
-    self._get_package_name_mock.return_value = 'org.unknown.app'
-
-    self.assertRaises(Exception,
-        android_browser_finder._FindAllPossibleBrowsers,
-        self.finder_options, self.fake_platform)
-
-  def testErrorWithNonExistantExactApk(self):
-    self.finder_options.browser_executable = '/foo/ContentShell.apk'
-    self._get_package_name_mock.return_value = 'org.chromium.content_shell_apk'
-
-    self.assertRaises(Exception,
-        android_browser_finder._FindAllPossibleBrowsers,
-        self.finder_options, self.fake_platform)
-
-  def testNoErrorWithUnrecognizedApkName(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    self.fs.CreateFile(
-        '/foo/unknown.apk')
-    self.finder_options.browser_executable = '/foo/unknown.apk'
-
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, self.fake_platform)
-    self.assertNotIn('exact', [b.browser_type for b in possible_browsers])
-
-  def testCanLaunchExactWithUnrecognizedApkNameButKnownPackageName(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    self.fs.CreateFile(
-        '/foo/MyFooBrowser.apk')
-    self._get_package_name_mock.return_value = 'org.chromium.chrome'
-    self.finder_options.browser_executable = '/foo/MyFooBrowser.apk'
-
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, self.fake_platform)
-    self.assertIn('exact', [b.browser_type for b in possible_browsers])
-
-  def testNoErrorWithMissingReferenceBuild(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-      self.finder_options, self.fake_platform)
-    self.assertNotIn('reference', [b.browser_type for b in possible_browsers])
-
-  def testNoErrorWithReferenceBuildCloudStorageError(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    with mock.patch(
-        'telemetry.internal.backends.chrome.android_browser_finder.binary_manager.FetchPath',  # pylint: disable=line-too-long
-        side_effect=binary_manager.CloudStorageError):
-      possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-        self.finder_options, self.fake_platform)
-    self.assertNotIn('reference', [b.browser_type for b in possible_browsers])
-
-  def testNoErrorWithReferenceBuildNoPathFoundError(self):
-    if not self.finder_options.chrome_root:
-      self.skipTest('--chrome-root is not specified, skip the test')
-    self._fetch_path_mock.side_effect = binary_manager.NoPathFoundError
-    possible_browsers = android_browser_finder._FindAllPossibleBrowsers(
-      self.finder_options, self.fake_platform)
-    self.assertNotIn('reference', [b.browser_type for b in possible_browsers])
-
-
-class FakePossibleBrowser(object):
-  def __init__(self, last_modification_time):
-    self._last_modification_time = last_modification_time
-
-  def last_modification_time(self):
-    return self._last_modification_time
-
-
-class SelectDefaultBrowserTest(unittest.TestCase):
-  def testEmptyListGivesNone(self):
-    self.assertIsNone(android_browser_finder.SelectDefaultBrowser([]))
-
-  def testSinglePossibleReturnsSame(self):
-    possible_browsers = [FakePossibleBrowser(last_modification_time=1)]
-    self.assertIs(
-      possible_browsers[0],
-      android_browser_finder.SelectDefaultBrowser(possible_browsers))
-
-  def testListGivesNewest(self):
-    possible_browsers = [
-        FakePossibleBrowser(last_modification_time=2),
-        FakePossibleBrowser(last_modification_time=3),  # newest
-        FakePossibleBrowser(last_modification_time=1),
-        ]
-    self.assertIs(
-      possible_browsers[1],
-      android_browser_finder.SelectDefaultBrowser(possible_browsers))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py
deleted file mode 100644
index 80d2cf3..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend.py
+++ /dev/null
@@ -1,310 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import pprint
-import shlex
-import sys
-
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.backends import browser_backend
-from telemetry.internal.backends.chrome import extension_backend
-from telemetry.internal.backends.chrome import system_info_backend
-from telemetry.internal.backends.chrome import tab_list_backend
-from telemetry.internal.backends.chrome_inspector import devtools_client_backend
-from telemetry.internal.browser import user_agent
-from telemetry.internal.browser import web_contents
-from telemetry.testing import options_for_unittests
-
-import py_utils
-
-
-class ChromeBrowserBackend(browser_backend.BrowserBackend):
-  """An abstract class for chrome browser backends. Provides basic functionality
-  once a remote-debugger port has been established."""
-  # It is OK to have abstract methods. pylint: disable=abstract-method
-
-  def __init__(self, platform_backend, supports_tab_control,
-               supports_extensions, browser_options):
-    super(ChromeBrowserBackend, self).__init__(
-        platform_backend=platform_backend,
-        supports_extensions=supports_extensions,
-        browser_options=browser_options,
-        tab_list_backend=tab_list_backend.TabListBackend)
-    self._port = None
-
-    self._supports_tab_control = supports_tab_control
-    self._devtools_client = None
-    self._system_info_backend = None
-
-    self._output_profile_path = browser_options.output_profile_path
-    self._extensions_to_load = browser_options.extensions_to_load
-
-    if (self.browser_options.dont_override_profile and
-        not options_for_unittests.AreSet()):
-      sys.stderr.write('Warning: Not overriding profile. This can cause '
-                       'unexpected effects due to profile-specific settings, '
-                       'such as about:flags settings, cookies, and '
-                       'extensions.\n')
-
-  @property
-  def devtools_client(self):
-    return self._devtools_client
-
-  @property
-  @decorators.Cache
-  def extension_backend(self):
-    if not self.supports_extensions:
-      return None
-    return extension_backend.ExtensionBackendDict(self)
-
-  def _ArgsNeedProxyServer(self, args):
-    """Returns True if args for Chrome indicate the need for proxy server."""
-    if '--enable-spdy-proxy-auth' in args:
-      return True
-    return [arg for arg in args if arg.startswith('--proxy-server=')]
-
-  def GetBrowserStartupArgs(self):
-    assert not '--no-proxy-server' in self.browser_options.extra_browser_args, (
-        '--no-proxy-server flag is disallowed as Chrome needs to be route to '
-        'ts_proxy_server')
-    args = []
-    args.extend(self.browser_options.extra_browser_args)
-    args.append('--enable-net-benchmarking')
-    args.append('--metrics-recording-only')
-    args.append('--no-default-browser-check')
-    args.append('--no-first-run')
-
-    # Turn on GPU benchmarking extension for all runs. The only side effect of
-    # the extension being on is that render stats are tracked. This is believed
-    # to be effectively free. And, by doing so here, it avoids us having to
-    # programmatically inspect a pageset's actions in order to determine if it
-    # might eventually scroll.
-    args.append('--enable-gpu-benchmarking')
-
-    if self.browser_options.disable_background_networking:
-      args.append('--disable-background-networking')
-    args.extend(self.GetReplayBrowserStartupArgs())
-    args.extend(user_agent.GetChromeUserAgentArgumentFromType(
-        self.browser_options.browser_user_agent_type))
-
-    extensions = [extension.local_path
-                  for extension in self._extensions_to_load]
-    extension_str = ','.join(extensions)
-    if len(extensions) > 0:
-      args.append('--load-extension=%s' % extension_str)
-
-    if self.browser_options.disable_component_extensions_with_background_pages:
-      args.append('--disable-component-extensions-with-background-pages')
-
-    # Disables the start page, as well as other external apps that can
-    # steal focus or make measurements inconsistent.
-    if self.browser_options.disable_default_apps:
-      args.append('--disable-default-apps')
-
-    # Disable the search geolocation disclosure infobar, as it is only shown a
-    # small number of times to users and should not be part of perf comparisons.
-    args.append('--disable-search-geolocation-disclosure')
-
-    if (self.browser_options.logging_verbosity ==
-        self.browser_options.NON_VERBOSE_LOGGING):
-      args.extend(['--enable-logging', '--v=0'])
-    elif (self.browser_options.logging_verbosity ==
-          self.browser_options.VERBOSE_LOGGING):
-      args.extend(['--enable-logging', '--v=1'])
-
-    return args
-
-  def GetReplayBrowserStartupArgs(self):
-    replay_args = []
-    network_backend = self.platform_backend.network_controller_backend
-    if not network_backend.is_initialized:
-      return []
-    proxy_port = network_backend.forwarder.port_pair.remote_port
-    replay_args.append('--proxy-server=socks://localhost:%s' % proxy_port)
-    if not network_backend.is_test_ca_installed:
-      # Ignore certificate errors if the platform backend has not created
-      # and installed a root certificate.
-      replay_args.append('--ignore-certificate-errors')
-    return replay_args
-
-  def HasBrowserFinishedLaunching(self):
-    assert self._port, 'No DevTools port info available.'
-    return devtools_client_backend.IsDevToolsAgentAvailable(self._port, self)
-
-  def _InitDevtoolsClientBackend(self, remote_devtools_port=None):
-    """ Initiate the devtool client backend which allow browser connection
-    through browser' devtool.
-
-    Args:
-      remote_devtools_port: The remote devtools port, if
-          any. Otherwise assumed to be the same as self._port.
-    """
-    assert not self._devtools_client, (
-        'Devtool client backend cannot be init twice')
-    self._devtools_client = devtools_client_backend.DevToolsClientBackend(
-        self._port, remote_devtools_port or self._port, self)
-
-  def _WaitForBrowserToComeUp(self):
-    """ Wait for browser to come up. """
-    try:
-      timeout = self.browser_options.browser_startup_timeout
-      py_utils.WaitFor(self.HasBrowserFinishedLaunching, timeout=timeout)
-    except (py_utils.TimeoutException, exceptions.ProcessGoneException) as e:
-      if not self.IsBrowserRunning():
-        raise exceptions.BrowserGoneException(self.browser, e)
-      raise exceptions.BrowserConnectionGoneException(self.browser, e)
-
-  def _WaitForExtensionsToLoad(self):
-    """ Wait for all extensions to load.
-    Be sure to check whether the browser_backend supports_extensions before
-    calling this method.
-    """
-    assert self._supports_extensions
-    assert self._devtools_client, (
-        'Waiting for extensions required devtool client to be initiated first')
-    try:
-      py_utils.WaitFor(self._AllExtensionsLoaded, timeout=60)
-    except py_utils.TimeoutException:
-      logging.error('ExtensionsToLoad: ' +
-          repr([e.extension_id for e in self._extensions_to_load]))
-      logging.error('Extension list: ' +
-          pprint.pformat(self.extension_backend, indent=4))
-      raise
-
-  def _AllExtensionsLoaded(self):
-    # Extension pages are loaded from an about:blank page,
-    # so we need to check that the document URL is the extension
-    # page in addition to the ready state.
-    for e in self._extensions_to_load:
-      try:
-        extension_objects = self.extension_backend[e.extension_id]
-      except KeyError:
-        return False
-      for extension_object in extension_objects:
-        try:
-          res = extension_object.EvaluateJavaScript("""
-              document.URL.lastIndexOf({{ url }}, 0) == 0 &&
-              (document.readyState == 'complete' ||
-               document.readyState == 'interactive')
-              """,
-              url='chrome-extension://%s/' % e.extension_id)
-        except exceptions.EvaluateException:
-          # If the inspected page is not ready, we will get an error
-          # when we evaluate a JS expression, but we can just keep polling
-          # until the page is ready (crbug.com/251913).
-          res = None
-
-        # TODO(tengs): We don't have full support for getting the Chrome
-        # version before launch, so for now we use a generic workaround to
-        # check for an extension binding bug in old versions of Chrome.
-        # See crbug.com/263162 for details.
-        if res and extension_object.EvaluateJavaScript(
-            'chrome.runtime == null'):
-          extension_object.Reload()
-        if not res:
-          return False
-    return True
-
-  @property
-  def browser_directory(self):
-    raise NotImplementedError()
-
-  @property
-  def profile_directory(self):
-    raise NotImplementedError()
-
-  @property
-  def supports_tab_control(self):
-    return self._supports_tab_control
-
-  @property
-  def supports_tracing(self):
-    return True
-
-  def StartTracing(self, trace_options,
-                   timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    """
-    Args:
-        trace_options: An tracing_options.TracingOptions instance.
-    """
-    return self.devtools_client.StartChromeTracing(trace_options, timeout)
-
-  def StopTracing(self):
-    self.devtools_client.StopChromeTracing()
-
-  def CollectTracingData(self, trace_data_builder):
-    self.devtools_client.CollectChromeTracingData(trace_data_builder)
-
-  def GetProcessName(self, cmd_line):
-    """Returns a user-friendly name for the process of the given |cmd_line|."""
-    if not cmd_line:
-      # TODO(tonyg): Eventually we should make all of these known and add an
-      # assertion.
-      return 'unknown'
-    if 'nacl_helper_bootstrap' in cmd_line:
-      return 'nacl_helper_bootstrap'
-    if ':sandboxed_process' in cmd_line:
-      return 'renderer'
-    if ':privileged_process' in cmd_line:
-      return 'gpu-process'
-    args = shlex.split(cmd_line)
-    types = [arg.split('=')[1] for arg in args if arg.startswith('--type=')]
-    if not types:
-      return 'browser'
-    return types[0]
-
-  def Close(self):
-    if self._devtools_client:
-      self._devtools_client.Close()
-      self._devtools_client = None
-
-  @property
-  def supports_system_info(self):
-    return self.GetSystemInfo() != None
-
-  def GetSystemInfo(self):
-    if self._system_info_backend is None:
-      self._system_info_backend = system_info_backend.SystemInfoBackend(
-          self._port)
-    # TODO(crbug.com/706336): Remove this condional branch once crbug.com/704024
-    # is fixed.
-    if util.IsRunningOnCrosDevice():
-      return self._system_info_backend.GetSystemInfo(timeout=30)
-    return self._system_info_backend.GetSystemInfo()
-
-  @property
-  def supports_memory_dumping(self):
-    return True
-
-  def DumpMemory(self, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    return self.devtools_client.DumpMemory(timeout)
-
-  @property
-  def supports_overriding_memory_pressure_notifications(self):
-    return True
-
-  def SetMemoryPressureNotificationsSuppressed(
-      self, suppressed, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    self.devtools_client.SetMemoryPressureNotificationsSuppressed(
-        suppressed, timeout)
-
-  def SimulateMemoryPressureNotification(
-      self, pressure_level, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    self.devtools_client.SimulateMemoryPressureNotification(
-        pressure_level, timeout)
-
-  @property
-  def supports_cpu_metrics(self):
-    return True
-
-  @property
-  def supports_memory_metrics(self):
-    return True
-
-  @property
-  def supports_power_metrics(self):
-    return True
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend_unittest.py
deleted file mode 100644
index a1691aa..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/chrome_browser_backend_unittest.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-import mock
-
-from telemetry.internal import forwarders
-from telemetry.internal.backends.chrome import chrome_browser_backend
-from telemetry.internal.browser import browser_options as browser_options_module
-from telemetry.util import wpr_modes
-
-
-class FakePlatformBackend(object):
-  def __init__(self, is_initialized, local_ts_proxy_port, remote_port,
-               is_host_platform):
-    self.is_host_platform = is_host_platform
-
-    self.forwarder_factory = mock.Mock()
-
-    self.network_controller_backend = mock.Mock()
-    self.network_controller_backend.is_initialized = is_initialized
-    if is_initialized:
-      self.network_controller_backend.forwarder.port_pair = forwarders.PortPair(
-          local_port=local_ts_proxy_port, remote_port=remote_port)
-    else:
-      self.network_controller_backend.forwarder = None
-    self.network_controller_backend.host_ip = '127.0.0.1'
-    self.network_controller_backend.is_test_ca_installed = False
-
-
-class FakeBrowserOptions(browser_options_module.BrowserOptions):
-  def __init__(self, wpr_mode=wpr_modes.WPR_OFF):
-    super(FakeBrowserOptions, self).__init__()
-    self.wpr_mode = wpr_mode
-    self.browser_type = 'chrome'
-    self.browser_user_agent_type = 'desktop'
-    self.disable_background_networking = False
-    self.disable_component_extensions_with_background_pages = False
-    self.disable_default_apps = False
-
-
-class TestChromeBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
-  # The test does not need to define the abstract methods.
-  # pylint: disable=abstract-method
-
-  def __init__(self, browser_options,
-               local_ts_proxy_port=None,
-               remote_port=None,
-               is_running_locally=False):
-    browser_options.extensions_to_load = []
-    browser_options.output_profile_path = None
-    super(TestChromeBrowserBackend, self).__init__(
-        platform_backend=FakePlatformBackend(
-            browser_options.wpr_mode != wpr_modes.WPR_OFF,
-            local_ts_proxy_port, remote_port, is_running_locally),
-        supports_tab_control=False,
-        supports_extensions=False,
-        browser_options=browser_options)
-
-
-class ReplayStartupArgsTest(unittest.TestCase):
-  """Test expected inputs for GetReplayBrowserStartupArgs."""
-
-  def testReplayOffGivesEmptyArgs(self):
-    browser_options = FakeBrowserOptions()
-    browser_backend = TestChromeBrowserBackend(browser_options)
-    self.assertEqual([], browser_backend.GetReplayBrowserStartupArgs())
-
-  def BasicArgsHelper(self, is_running_locally):
-    browser_options = FakeBrowserOptions(wpr_mode=wpr_modes.WPR_REPLAY)
-    browser_backend = TestChromeBrowserBackend(
-        browser_options,
-        local_ts_proxy_port=567,
-        remote_port=789,
-        is_running_locally=is_running_locally)
-    expected_args = [
-        '--ignore-certificate-errors',
-        '--proxy-server=socks://localhost:789',
-        ]
-    self.assertEqual(
-        expected_args,
-        sorted(browser_backend.GetReplayBrowserStartupArgs()))
-
-  def testBasicArgs(self):
-    # The result is the same regardless of whether running locally.
-    self.BasicArgsHelper(is_running_locally=True)
-    self.BasicArgsHelper(is_running_locally=False)
-
-  def testReplayNotActive(self):
-    browser_options = FakeBrowserOptions(wpr_mode=wpr_modes.WPR_OFF)
-    browser_backend = TestChromeBrowserBackend(
-        browser_options,
-        local_ts_proxy_port=567,
-        remote_port=789,
-        is_running_locally=True)
-    expected_args = []
-    self.assertEqual(
-        expected_args,
-        sorted(browser_backend.GetReplayBrowserStartupArgs()))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/main.html b/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/main.html
deleted file mode 100644
index 07a643c..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/main.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta charset="utf-8">
-    <script src="main.js"></script>
-  </head>
-  <body>
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/main.js b/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/main.js
deleted file mode 100644
index 7d21eb3..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/main.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var PARENT_PAGE = 'chrome://oobe/';
-
-var msg = {
-  'method': 'loginUILoaded'
-};
-window.parent.postMessage(msg, PARENT_PAGE);
-
-var msg = {
-  'method': 'completeLogin',
-  'email': 'test@test.test',
-  'gaiaId': '12345',
-  'password': ''
-};
-window.parent.postMessage(msg, PARENT_PAGE);
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/manifest.json b/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/manifest.json
deleted file mode 100644
index ec809c6..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/chromeos_login_ext/manifest.json
+++ /dev/null
@@ -1,16 +0,0 @@
-{
-  // chrome-extension://mfffpogegjflfpflabcdkioaeobkgjik/
-  "key": "MIGdMA0GCSqGSIb3DQEBAQUAA4GLADCBhwKBgQC4L17nAfeTd6Xhtx96WhQ6DSr8KdHeQmfzgCkieKLCgUkWdwB9G1DCuh0EPMDn1MdtSwUAT7xE36APEzi0X/UpKjOVyX8tCC3aQcLoRAE0aJAvCcGwK7qIaQaczHmHKvPC2lrRdzSoMMTC5esvHX+ZqIBMi123FOL0dGW6OPKzIwIBIw==",
-  "name": "GaiaDummyAuthExtension",
-  "version": "0.0.1",
-  "manifest_version": 2,
-  "content_security_policy": "default-src 'self' blob: filesystem:; script-src 'self' blob: filesystem:; style-src 'self' blob: filesystem: 'unsafe-inline'",
-  "description": "GAIA Dummy Component Extension",
-  "web_accessible_resources": [
-    "main.html",
-    "main.js"
-  ],
-  "permissions": [
-      "chrome://oobe/"
-  ]
-}
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_backend.py
deleted file mode 100644
index 4ff1b19..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_backend.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.backends.chrome import chrome_browser_backend
-from telemetry.internal.backends.chrome import misc_web_contents_backend
-from telemetry.internal import forwarders
-
-import py_utils
-
-
-class CrOSBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
-  def __init__(self, cros_platform_backend, browser_options, cri, is_guest):
-    super(CrOSBrowserBackend, self).__init__(
-        cros_platform_backend, supports_tab_control=True,
-        supports_extensions=not is_guest,
-        browser_options=browser_options)
-    assert browser_options.IsCrosBrowserOptions()
-    # Initialize fields so that an explosion during init doesn't break in Close.
-    self._cri = cri
-    self._is_guest = is_guest
-    self._forwarder = None
-    self._remote_debugging_port = self._cri.GetRemotePort()
-    self._port = self._remote_debugging_port
-
-    extensions_to_load = browser_options.extensions_to_load
-
-    # Copy extensions to temp directories on the device.
-    # Note that we also perform this copy locally to ensure that
-    # the owner of the extensions is set to chronos.
-    for e in extensions_to_load:
-      extension_dir = cri.RunCmdOnDevice(
-          ['mktemp', '-d', '/tmp/extension_XXXXX'])[0].rstrip()
-      e.local_path = os.path.join(extension_dir, os.path.basename(e.path))
-      cri.PushFile(e.path, extension_dir)
-      cri.Chown(extension_dir)
-
-    self._cri.RestartUI(self.browser_options.clear_enterprise_policy)
-    py_utils.WaitFor(self.IsBrowserRunning, 20)
-
-    # Delete test user's cryptohome vault (user data directory).
-    if not self.browser_options.dont_override_profile:
-      self._cri.RunCmdOnDevice(['cryptohome', '--action=remove', '--force',
-                                '--user=%s' % self._username])
-
-  @property
-  def log_file_path(self):
-    return None
-
-  def GetBrowserStartupArgs(self):
-    args = super(CrOSBrowserBackend, self).GetBrowserStartupArgs()
-
-    logging_patterns = ['*/chromeos/net/*',
-                        '*/chromeos/login/*',
-                        'chrome_browser_main_posix']
-    vmodule = '--vmodule='
-    for pattern in logging_patterns:
-      vmodule += '%s=2,' % pattern
-    vmodule = vmodule.rstrip(',')
-
-    args.extend([
-            '--enable-smooth-scrolling',
-            '--enable-threaded-compositing',
-            # Allow devtools to connect to chrome.
-            '--remote-debugging-port=%i' % self._remote_debugging_port,
-            # Open a maximized window.
-            '--start-maximized',
-            # Disable system startup sound.
-            '--ash-disable-system-sounds',
-            # Ignore DMServer errors for policy fetches.
-            '--allow-failed-policy-fetch-for-test',
-            # Skip user image selection screen, and post login screens.
-            '--oobe-skip-postlogin',
-            # Debug logging.
-            vmodule])
-
-    # Disable GAIA services unless we're using GAIA login, or if there's an
-    # explicit request for it.
-    if (self.browser_options.disable_gaia_services and
-        not self.browser_options.gaia_login):
-      args.append('--disable-gaia-services')
-
-    trace_config_file = (self.platform_backend.tracing_controller_backend
-                         .GetChromeTraceConfigFile())
-    if trace_config_file:
-      args.append('--trace-config-file=%s' % trace_config_file)
-
-    return args
-
-  @property
-  def pid(self):
-    return self._cri.GetChromePid()
-
-  @property
-  def browser_directory(self):
-    result = self._cri.GetChromeProcess()
-    if result and 'path' in result:
-      return os.path.dirname(result['path'])
-    return None
-
-  @property
-  def profile_directory(self):
-    return '/home/chronos/Default'
-
-  def __del__(self):
-    self.Close()
-
-  def Start(self):
-    # Escape all commas in the startup arguments we pass to Chrome
-    # because dbus-send delimits array elements by commas
-    startup_args = [a.replace(',', '\\,') for a in self.GetBrowserStartupArgs()]
-
-    # Restart Chrome with the login extension and remote debugging.
-    pid = self.pid
-    logging.info('Restarting Chrome (pid=%d) with remote port', pid)
-    args = ['dbus-send', '--system', '--type=method_call',
-            '--dest=org.chromium.SessionManager',
-            '/org/chromium/SessionManager',
-            'org.chromium.SessionManagerInterface.EnableChromeTesting',
-            'boolean:true',
-            'array:string:"%s"' % ','.join(startup_args)]
-    logging.info(' '.join(args))
-    self._cri.RunCmdOnDevice(args)
-
-    if not self._cri.local:
-      # TODO(crbug.com/404771): Move port forwarding to network_controller.
-      self._port = util.GetUnreservedAvailableLocalPort()
-      self._forwarder = self._platform_backend.forwarder_factory.Create(
-          forwarders.PortPair(self._port, self._remote_debugging_port),
-          use_remote_port_forwarding=False)
-
-    # Wait for new chrome and oobe.
-    py_utils.WaitFor(lambda: pid != self.pid, 15)
-    self._WaitForBrowserToComeUp()
-    self._InitDevtoolsClientBackend(
-        remote_devtools_port=self._remote_debugging_port)
-    py_utils.WaitFor(lambda: self.oobe_exists, 30)
-
-    if self.browser_options.auto_login:
-      if self._is_guest:
-        pid = self.pid
-        self.oobe.NavigateGuestLogin()
-        # Guest browsing shuts down the current browser and launches an
-        # incognito browser in a separate process, which we need to wait for.
-        try:
-          # TODO(achuith): Reduce this timeout to 15 sec after crbug.com/631640
-          # is resolved.
-          py_utils.WaitFor(lambda: pid != self.pid, 60)
-        except py_utils.TimeoutException:
-          self._RaiseOnLoginFailure(
-              'Failed to restart browser in guest mode (pid %d).' % pid)
-
-      elif self.browser_options.gaia_login:
-        self.oobe.NavigateGaiaLogin(self._username, self._password)
-      else:
-        self.oobe.NavigateFakeLogin(self._username, self._password,
-            self._gaia_id, not self.browser_options.disable_gaia_services)
-
-      try:
-        self._WaitForLogin()
-      except py_utils.TimeoutException:
-        self._RaiseOnLoginFailure('Timed out going through login screen. '
-                                  + self._GetLoginStatus())
-
-    logging.info('Browser is up!')
-
-  def Background(self):
-    raise NotImplementedError
-
-  def Close(self):
-    super(CrOSBrowserBackend, self).Close()
-
-    if self._cri:
-      self._cri.RestartUI(False) # Logs out.
-      self._cri.CloseConnection()
-
-    py_utils.WaitFor(lambda: not self._IsCryptohomeMounted(), 180)
-
-    if self._forwarder:
-      self._forwarder.Close()
-      self._forwarder = None
-
-    if self._cri:
-      for e in self._extensions_to_load:
-        self._cri.RmRF(os.path.dirname(e.local_path))
-
-    self._cri = None
-
-  def IsBrowserRunning(self):
-    return bool(self.pid)
-
-  def GetStandardOutput(self):
-    return 'Cannot get standard output on CrOS'
-
-  def GetStackTrace(self):
-    return (False, 'Cannot get stack trace on CrOS')
-
-  def GetMostRecentMinidumpPath(self):
-    return None
-
-  def GetAllMinidumpPaths(self):
-    return None
-
-  def GetAllUnsymbolizedMinidumpPaths(self):
-    return None
-
-  def SymbolizeMinidump(self, minidump_path):
-    return None
-
-  @property
-  @decorators.Cache
-  def misc_web_contents_backend(self):
-    """Access to chrome://oobe/login page."""
-    return misc_web_contents_backend.MiscWebContentsBackend(self)
-
-  @property
-  def oobe(self):
-    return self.misc_web_contents_backend.GetOobe()
-
-  @property
-  def oobe_exists(self):
-    return self.misc_web_contents_backend.oobe_exists
-
-  @property
-  def _username(self):
-    return self.browser_options.username
-
-  @property
-  def _password(self):
-    return self.browser_options.password
-
-  @property
-  def _gaia_id(self):
-    return self.browser_options.gaia_id
-
-  def _IsCryptohomeMounted(self):
-    username = '$guest' if self._is_guest else self._username
-    return self._cri.IsCryptohomeMounted(username, self._is_guest)
-
-  def _GetLoginStatus(self):
-    """Returns login status. If logged in, empty string is returned."""
-    status = ''
-    if not self._IsCryptohomeMounted():
-      status += 'Cryptohome not mounted. '
-    if not self.HasBrowserFinishedLaunching():
-      status += 'Browser didn\'t launch. '
-    if self.oobe_exists:
-      status += 'OOBE not dismissed.'
-    return status
-
-  def _IsLoggedIn(self):
-    """Returns True if cryptohome has mounted, the browser is
-    responsive to devtools requests, and the oobe has been dismissed."""
-    return not self._GetLoginStatus()
-
-  def _WaitForLogin(self):
-    # Wait for cryptohome to mount.
-    py_utils.WaitFor(self._IsLoggedIn, 900)
-
-    # For incognito mode, the session manager actually relaunches chrome with
-    # new arguments, so we have to wait for the browser to come up.
-    self._WaitForBrowserToComeUp()
-
-    # Wait for extensions to load.
-    if self._supports_extensions:
-      self._WaitForExtensionsToLoad()
-
-  def _RaiseOnLoginFailure(self, error):
-    if self._platform_backend.CanTakeScreenshot():
-      self._cri.TakeScreenshotWithPrefix('login-screen')
-    raise exceptions.LoginException(error)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_finder.py b/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_finder.py
deleted file mode 100644
index 2c72ca7..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_finder.py
+++ /dev/null
@@ -1,122 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Finds CrOS browsers that can be controlled by telemetry."""
-
-import logging
-
-from telemetry.core import cros_interface
-from telemetry.core import platform as platform_module
-from telemetry.internal.backends.chrome import cros_browser_backend
-from telemetry.internal.backends.chrome import cros_browser_with_oobe
-from telemetry.internal.browser import browser
-from telemetry.internal.browser import browser_finder_exceptions
-from telemetry.internal.browser import possible_browser
-from telemetry.internal.platform import cros_device
-
-
-class PossibleCrOSBrowser(possible_browser.PossibleBrowser):
-  """A launchable CrOS browser instance."""
-  def __init__(self, browser_type, finder_options, cros_platform, is_guest):
-    super(PossibleCrOSBrowser, self).__init__(browser_type, 'cros', True)
-    assert browser_type in FindAllBrowserTypes(finder_options), (
-        'Please add %s to cros_browser_finder.FindAllBrowserTypes()' %
-         browser_type)
-    self._platform = cros_platform
-    self._platform_backend = (
-        cros_platform._platform_backend)  # pylint: disable=protected-access
-    self._is_guest = is_guest
-
-  def __repr__(self):
-    return 'PossibleCrOSBrowser(browser_type=%s)' % self.browser_type
-
-  def _InitPlatformIfNeeded(self):
-    pass
-
-  def Create(self, finder_options):
-    if finder_options.browser_options.output_profile_path:
-      raise NotImplementedError(
-          'Profile generation is not yet supported on CrOS.')
-
-    browser_options = finder_options.browser_options
-    browser_backend = cros_browser_backend.CrOSBrowserBackend(
-        self._platform_backend, browser_options, self._platform_backend.cri,
-        self._is_guest)
-    if browser_options.create_browser_with_oobe:
-      return cros_browser_with_oobe.CrOSBrowserWithOOBE(
-          browser_backend,
-          self._platform_backend,
-          self._credentials_path)
-    return browser.Browser(
-        browser_backend, self._platform_backend, self._credentials_path)
-
-  def SupportsOptions(self, browser_options):
-    return (len(browser_options.extensions_to_load) == 0) or not self._is_guest
-
-  def UpdateExecutableIfNeeded(self):
-    pass
-
-def SelectDefaultBrowser(possible_browsers):
-  if cros_device.IsRunningOnCrOS():
-    for b in possible_browsers:
-      if b.browser_type == 'system':
-        return b
-  return None
-
-def CanFindAvailableBrowsers(finder_options):
-  return (cros_device.IsRunningOnCrOS() or
-          finder_options.cros_remote or
-          cros_interface.HasSSH())
-
-def FindAllBrowserTypes(_):
-  return [
-      'cros-chrome',
-      'cros-chrome-guest',
-      'system',
-      'system-guest',
-  ]
-
-def FindAllAvailableBrowsers(finder_options, device):
-  """Finds all available CrOS browsers, locally and remotely."""
-  browsers = []
-  if not isinstance(device, cros_device.CrOSDevice):
-    return browsers
-
-  if cros_device.IsRunningOnCrOS():
-    browsers = [PossibleCrOSBrowser('system', finder_options,
-                                    platform_module.GetHostPlatform(),
-                                    is_guest=False),
-                PossibleCrOSBrowser('system-guest', finder_options,
-                                    platform_module.GetHostPlatform(),
-                                    is_guest=True)]
-
-  # Check ssh
-  try:
-    platform = platform_module.GetPlatformForDevice(device, finder_options)
-  except cros_interface.LoginException, ex:
-    if isinstance(ex, cros_interface.KeylessLoginRequiredException):
-      logging.warn('Could not ssh into %s. Your device must be configured',
-                   finder_options.cros_remote)
-      logging.warn('to allow passwordless login as root.')
-      logging.warn('For a test-build device, pass this to your script:')
-      logging.warn('   --identity $(CHROMITE)/ssh_keys/testing_rsa')
-      logging.warn('')
-      logging.warn('For a developer-mode device, the steps are:')
-      logging.warn(' - Ensure you have an id_rsa.pub (etc) on this computer')
-      logging.warn(' - On the chromebook:')
-      logging.warn('   -  Control-Alt-T; shell; sudo -s')
-      logging.warn('   -  openssh-server start')
-      logging.warn('   -  scp <this machine>:.ssh/id_rsa.pub /tmp/')
-      logging.warn('   -  mkdir /root/.ssh')
-      logging.warn('   -  chown go-rx /root/.ssh')
-      logging.warn('   -  cat /tmp/id_rsa.pub >> /root/.ssh/authorized_keys')
-      logging.warn('   -  chown 0600 /root/.ssh/authorized_keys')
-    raise browser_finder_exceptions.BrowserFinderException(str(ex))
-
-  browsers.extend([PossibleCrOSBrowser('cros-chrome', finder_options,
-                                       platform, is_guest=False),
-                   PossibleCrOSBrowser('cros-chrome-guest',
-                                       finder_options, platform,
-                                       is_guest=True)])
-  return browsers
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_finder_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_finder_unittest.py
deleted file mode 100644
index d467819..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_finder_unittest.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO(nduca): Add basic unit test for cros_browser_finder.
-#
-# Here, we should mock the cros_interface module (assuming its working) and
-# verify that the finder does the right thing. Because the finder delegates most
-# of its work to the CRI, the test code here is going to be comparatively
-# simple.
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_with_oobe.py b/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_with_oobe.py
deleted file mode 100644
index 127a180..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/cros_browser_with_oobe.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.backends.chrome import cros_browser_backend
-from telemetry.internal.browser import browser
-
-
-class CrOSBrowserWithOOBE(browser.Browser):
-  """Cros-specific browser."""
-  def __init__(self, backend, platform_backend, credentials_path):
-    assert isinstance(backend, cros_browser_backend.CrOSBrowserBackend)
-    super(CrOSBrowserWithOOBE, self).__init__(
-        backend, platform_backend, credentials_path)
-
-  @property
-  def oobe(self):
-    """The login webui (also serves as ui for screenlock and
-    out-of-box-experience).
-    """
-    return self._browser_backend.oobe
-
-  @property
-  def oobe_exists(self):
-    """True if the login/oobe/screenlock webui exists. This is more lightweight
-    than accessing the oobe property.
-    """
-    return self._browser_backend.oobe_exists
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/cros_test_case.py b/catapult/telemetry/telemetry/internal/backends/chrome/cros_test_case.py
deleted file mode 100644
index 259157b..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/cros_test_case.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry.core import cros_interface
-from telemetry.core import util
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import extension_to_load
-from telemetry.testing import options_for_unittests
-
-
-class CrOSTestCase(unittest.TestCase):
-  def setUp(self):
-    options = options_for_unittests.GetCopy()
-    self._cri = cros_interface.CrOSInterface(options.cros_remote,
-                                             options.cros_remote_ssh_port,
-                                             options.cros_ssh_identity)
-    self._is_guest = options.browser_type == 'cros-chrome-guest'
-    self._username = options.browser_options.username
-    self._password = options.browser_options.password
-    self._gaia_id = options.browser_options.gaia_id
-    self._load_extension = None
-
-  def _CreateBrowser(self, autotest_ext=False, auto_login=True,
-                     gaia_login=False, username=None, password=None,
-                     gaia_id=None, dont_override_profile=False):
-    """Finds and creates a browser for tests. if autotest_ext is True,
-    also loads the autotest extension"""
-    options = options_for_unittests.GetCopy()
-
-    if autotest_ext:
-      extension_path = os.path.join(util.GetUnittestDataDir(), 'autotest_ext')
-      assert os.path.isdir(extension_path)
-      self._load_extension = extension_to_load.ExtensionToLoad(
-          path=extension_path,
-          browser_type=options.browser_type)
-      options.browser_options.extensions_to_load = [self._load_extension]
-
-    browser_to_create = browser_finder.FindBrowser(options)
-    self.assertTrue(browser_to_create)
-    browser_options = options.browser_options
-    browser_options.create_browser_with_oobe = True
-    browser_options.auto_login = auto_login
-    browser_options.gaia_login = gaia_login
-    browser_options.dont_override_profile = dont_override_profile
-    if username is not None:
-      browser_options.username = username
-    if password is not None:
-      browser_options.password = password
-    if gaia_id is not None:
-      browser_options.gaia_id = gaia_id
-
-    return browser_to_create.Create(options)
-
-  def _GetAutotestExtension(self, browser):
-    """Returns the autotest extension instance"""
-    extension = browser.extensions[self._load_extension]
-    self.assertTrue(extension)
-    return extension
-
-  def _IsCryptohomeMounted(self):
-    """Returns True if cryptohome is mounted. as determined by the cmd
-    cryptohome --action=is_mounted"""
-    return self._cri.RunCmdOnDevice(
-        ['/usr/sbin/cryptohome', '--action=is_mounted'])[0].strip() == 'true'
-
-  def _GetLoginStatus(self, browser):
-    extension = self._GetAutotestExtension(browser)
-    self.assertTrue(extension.EvaluateJavaScript(
-        "typeof('chrome.autotestPrivate') != 'undefined'"))
-    extension.ExecuteJavaScript('''
-        window.__login_status = null;
-        chrome.autotestPrivate.loginStatus(function(s) {
-          window.__login_status = s;
-        });
-    ''')
-    return extension.WaitForJavaScriptCondition(
-        'window.__login_status', timeout=10)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/cros_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/cros_unittest.py
deleted file mode 100644
index 6581046..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/cros_unittest.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import urllib2
-import os
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.backends.chrome import cros_test_case
-
-import py_utils
-
-
-class CrOSCryptohomeTest(cros_test_case.CrOSTestCase):
-  @decorators.Enabled('chromeos')
-  def testCryptohome(self):
-    """Verifies cryptohome mount status for regular and guest user and when
-    logged out"""
-    with self._CreateBrowser() as b:
-      self.assertEquals(1, len(b.tabs))
-      self.assertTrue(b.tabs[0].url)
-      self.assertTrue(self._IsCryptohomeMounted())
-      self.assertTrue(
-          self._cri.IsCryptohomeMounted(self._username, self._is_guest))
-
-      # TODO(achuith): Remove dependency on /home/chronos/user.
-      chronos_fs = self._cri.FilesystemMountedAt('/home/chronos/user')
-      self.assertTrue(chronos_fs)
-      if self._is_guest:
-        self.assertEquals(chronos_fs, 'guestfs')
-      else:
-        crypto_fs = self._cri.FilesystemMountedAt(
-            self._cri.CryptohomePath(self._username))
-        self.assertEquals(crypto_fs, chronos_fs)
-
-    self.assertFalse(self._IsCryptohomeMounted())
-    self.assertFalse(
-        self._cri.IsCryptohomeMounted(self._username, self._is_guest))
-    self.assertEquals(self._cri.FilesystemMountedAt('/home/chronos/user'),
-                      '/dev/mapper/encstateful')
-
-
-class CrOSLoginTest(cros_test_case.CrOSTestCase):
-  def _GetCredentials(self, credentials=None):
-    """Read username and password from credentials.txt. The file is a single
-    line of the format username:password. Alternatively, |credentials| is used,
-    also of the same format."""
-    credentials_file = os.path.join(os.path.dirname(__file__),
-                                    'credentials.txt')
-    if not credentials and os.path.exists(credentials_file):
-      with open(credentials_file) as f:
-        credentials = f.read().strip()
-
-    if not credentials:
-      return (None, None)
-
-    user, password = credentials.split(':')
-    # Canonicalize.
-    if user.find('@') == -1:
-      username = user
-      domain = 'gmail.com'
-    else:
-      username, domain = user.split('@')
-
-    # Remove dots.
-    if domain == 'gmail.com':
-      username = username.replace('.', '')
-    return ('%s@%s' % (username, domain), password)
-
-  @decorators.Enabled('chromeos')
-  def testGetCredentials(self):
-    (username, password) = self._GetCredentials('user.1:foo.1')
-    self.assertEquals(username, 'user1@gmail.com')
-    self.assertEquals(password, 'foo.1')
-
-    (username, password) = self._GetCredentials('user.1@chromium.org:bar.1')
-    self.assertEquals(username, 'user.1@chromium.org')
-    self.assertEquals(password, 'bar.1')
-
-  @decorators.Enabled('chromeos')
-  def testLoginStatus(self):
-    """Tests autotestPrivate.loginStatus"""
-    if self._is_guest:
-      return
-    with self._CreateBrowser(autotest_ext=True) as b:
-      login_status = self._GetLoginStatus(b)
-      self.assertEquals(type(login_status), dict)
-
-      self.assertEquals(not self._is_guest, login_status['isRegularUser'])
-      self.assertEquals(self._is_guest, login_status['isGuest'])
-      self.assertEquals(login_status['email'], self._username)
-      self.assertFalse(login_status['isScreenLocked'])
-
-  @decorators.Enabled('chromeos')
-  def testLogout(self):
-    """Tests autotestPrivate.logout"""
-    if self._is_guest:
-      return
-    with self._CreateBrowser(autotest_ext=True) as b:
-      extension = self._GetAutotestExtension(b)
-      try:
-        extension.ExecuteJavaScript('chrome.autotestPrivate.logout();')
-      except exceptions.Error:
-        pass
-      py_utils.WaitFor(lambda: not self._IsCryptohomeMounted(), 20)
-
-  @decorators.Disabled('all')
-  def testGaiaLogin(self):
-    """Tests gaia login. Use credentials in credentials.txt if it exists,
-    otherwise use powerloadtest."""
-    if self._is_guest:
-      return
-    username, password = self._GetCredentials()
-    if not username or not password:
-      username = 'powerloadtest@gmail.com'
-      password = urllib2.urlopen(
-          'https://sites.google.com/a/chromium.org/dev/chromium-os/testing/'
-          'power-testing/pltp/pltp').read().rstrip()
-    with self._CreateBrowser(gaia_login=True,
-                             username=username,
-                             password=password):
-      self.assertTrue(py_utils.WaitFor(self._IsCryptohomeMounted, 10))
-
-  @decorators.Enabled('chromeos')
-  def testEnterpriseEnroll(self):
-    """Tests enterprise enrollment. Credentials are expected to be found in a
-    credentials.txt file. The account must be from an enterprise domain and
-    have device enrollment permission. The device must be unowned."""
-    if self._is_guest:
-      return
-
-    username, password = self._GetCredentials()
-    if not username or not password:
-      return
-    # Enroll the device.
-    with self._CreateBrowser(auto_login=False) as browser:
-      browser.oobe.NavigateGaiaLogin(username, password,
-                                     enterprise_enroll=True,
-                                     for_user_triggered_enrollment=True)
-
-    # Check for the existence of the device policy file.
-    self.assertTrue(py_utils.WaitFor(lambda: self._cri.FileExistsOnDevice(
-        '/home/.shadow/install_attributes.pb'), 15))
-
-
-class CrOSScreenLockerTest(cros_test_case.CrOSTestCase):
-  def _IsScreenLocked(self, browser):
-    return self._GetLoginStatus(browser)['isScreenLocked']
-
-  def _LockScreen(self, browser):
-    self.assertFalse(self._IsScreenLocked(browser))
-
-    extension = self._GetAutotestExtension(browser)
-    self.assertTrue(extension.EvaluateJavaScript(
-        "typeof chrome.autotestPrivate.lockScreen == 'function'"))
-    logging.info('Locking screen')
-    extension.ExecuteJavaScript('chrome.autotestPrivate.lockScreen();')
-
-    logging.info('Waiting for the lock screen')
-    def ScreenLocked():
-      return (browser.oobe_exists and
-          browser.oobe.EvaluateJavaScript("typeof Oobe == 'function'") and
-          browser.oobe.EvaluateJavaScript(
-              "typeof Oobe.authenticateForTesting == 'function'"))
-    py_utils.WaitFor(ScreenLocked, 10)
-    self.assertTrue(self._IsScreenLocked(browser))
-
-  def _AttemptUnlockBadPassword(self, browser):
-    logging.info('Trying a bad password')
-    def ErrorBubbleVisible():
-      return not browser.oobe.EvaluateJavaScript(
-          "document.getElementById('bubble').hidden")
-
-    self.assertFalse(ErrorBubbleVisible())
-    browser.oobe.ExecuteJavaScript(
-        "Oobe.authenticateForTesting({{ username }}, 'bad');",
-        username=self._username)
-    py_utils.WaitFor(ErrorBubbleVisible, 10)
-    self.assertTrue(self._IsScreenLocked(browser))
-
-  def _UnlockScreen(self, browser):
-    logging.info('Unlocking')
-    browser.oobe.ExecuteJavaScript(
-        'Oobe.authenticateForTesting({{ username }}, {{ password }});',
-        username=self._username, password=self._password)
-    py_utils.WaitFor(lambda: not browser.oobe_exists, 10)
-    self.assertFalse(self._IsScreenLocked(browser))
-
-  @decorators.Disabled('all')
-  def testScreenLock(self):
-    """Tests autotestPrivate.screenLock"""
-    if self._is_guest:
-      return
-    with self._CreateBrowser(autotest_ext=True) as browser:
-      self._LockScreen(browser)
-      self._AttemptUnlockBadPassword(browser)
-      self._UnlockScreen(browser)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/crx_id.py b/catapult/telemetry/telemetry/internal/backends/chrome/crx_id.py
deleted file mode 100644
index 21d17a2..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/crx_id.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-""" Read a CRX file and write out the App ID and the Full Hash of the ID.
-See: http://code.google.com/chrome/extensions/crx.html
-and 'http://stackoverflow.com/questions/'
-  + '1882981/google-chrome-alphanumeric-hashes-to-identify-extensions'
-for docs on the format.
-"""
-
-import base64
-import os
-import hashlib
-import json
-
-EXPECTED_CRX_MAGIC_NUM = 'Cr24'
-EXPECTED_CRX_VERSION = 2
-
-def HexToInt(hex_chars):
-  """ Convert bytes like \xab -> 171 """
-  val = 0
-  for i in xrange(len(hex_chars)):
-    val += pow(256, i) * ord(hex_chars[i])
-  return val
-
-def HexToMPDecimal(hex_chars):
-  """ Convert bytes to an MPDecimal string. Example \x00 -> "aa"
-      This gives us the AppID for a chrome extension.
-  """
-  result = ''
-  base = ord('a')
-  for i in xrange(len(hex_chars)):
-    value = ord(hex_chars[i])
-    dig1 = value / 16
-    dig2 = value % 16
-    result += chr(dig1 + base)
-    result += chr(dig2 + base)
-  return result
-
-def HexTo256(hex_chars):
-  """ Convert bytes to pairs of hex digits. E.g., \x00\x11 -> "{0x00, 0x11}"
-      The format is taylored for copy and paste into C code:
-      const uint8 sha256_hash[] = { ... }; """
-  result = []
-  for i in xrange(len(hex_chars)):
-    value = ord(hex_chars[i])
-    dig1 = value / 16
-    dig2 = value % 16
-    result.append('0x' + hex(dig1)[2:] + hex(dig2)[2:])
-  return '{%s}' % ', '.join(result)
-
-def GetPublicKeyPacked(f):
-  magic_num = f.read(4)
-  if magic_num != EXPECTED_CRX_MAGIC_NUM:
-    raise Exception('Invalid magic number: %s (expecting %s)' %
-                    (magic_num,
-                     EXPECTED_CRX_MAGIC_NUM))
-  version = f.read(4)
-  if not version[0] != EXPECTED_CRX_VERSION:
-    raise Exception('Invalid version number: %s (expecting %s)' %
-                    (version,
-                     EXPECTED_CRX_VERSION))
-  pub_key_len_bytes = HexToInt(f.read(4))
-  f.read(4)
-  return f.read(pub_key_len_bytes)
-
-def GetPublicKeyFromPath(filepath, is_win_path=False):
-  # Normalize the path for windows to have capital drive letters.
-  # We intentionally don't check if sys.platform == 'win32' and just
-  # check if this looks like drive letter so that we can test this
-  # even on posix systems.
-  if (len(filepath) >= 2 and
-      filepath[0].islower() and
-      filepath[1] == ':'):
-    filepath = filepath[0].upper() + filepath[1:]
-
-  # On Windows, filepaths are encoded using UTF-16, little endian byte order,
-  # using "wide characters" that are 16 bits in size. On POSIX systems, the
-  # encoding is generally UTF-8, which has the property of being equivalent to
-  # ASCII when only ASCII characters are in the path.
-  if is_win_path:
-    filepath = filepath.encode('utf-16le')
-
-  return filepath
-
-def GetPublicKeyUnpacked(f, filepath):
-  manifest = json.load(f)
-  if 'key' not in manifest:
-    # Use the path as the public key.
-    # See Extension::GenerateIdForPath in extension.cc
-    return GetPublicKeyFromPath(filepath)
-  else:
-    return base64.standard_b64decode(manifest['key'])
-
-def HasPublicKey(filename):
-  if os.path.isdir(filename):
-    with open(os.path.join(filename, 'manifest.json'), 'rb') as f:
-      manifest = json.load(f)
-      return 'key' in manifest
-  return False
-
-def GetPublicKey(filename, from_file_path, is_win_path=False):
-  if from_file_path:
-    return GetPublicKeyFromPath(
-        filename, is_win_path=is_win_path)
-
-  pub_key = ''
-  if os.path.isdir(filename):
-    # Assume it's an unpacked extension
-    f = open(os.path.join(filename, 'manifest.json'), 'rb')
-    pub_key = GetPublicKeyUnpacked(f, filename)
-    f.close()
-  else:
-    # Assume it's a packed extension.
-    f = open(filename, 'rb')
-    pub_key = GetPublicKeyPacked(f)
-    f.close()
-  return pub_key
-
-def GetCRXHash(filename, from_file_path=False, is_win_path=False):
-  pub_key = GetPublicKey(filename, from_file_path, is_win_path=is_win_path)
-  pub_key_hash = hashlib.sha256(pub_key).digest()
-  return HexTo256(pub_key_hash)
-
-def GetCRXAppID(filename, from_file_path=False, is_win_path=False):
-  pub_key = GetPublicKey(filename, from_file_path, is_win_path=is_win_path)
-  pub_key_hash = hashlib.sha256(pub_key).digest()
-  # AppID is the MPDecimal of only the first 128 bits of the hash.
-  return HexToMPDecimal(pub_key_hash[:128/8])
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/crx_id_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/crx_id_unittest.py
deleted file mode 100644
index 9cea905..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/crx_id_unittest.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import shutil
-import unittest
-import tempfile
-
-from telemetry.core import util
-from telemetry.internal.backends.chrome import crx_id
-
-
-class CrxIdUnittest(unittest.TestCase):
-  CRX_ID_DIR = util.GetUnittestDataDir()
-  PACKED_CRX = os.path.join(CRX_ID_DIR,
-                            'jebgalgnebhfojomionfpkfelancnnkf.crx')
-
-  PACKED_APP_ID = 'jebgalgnebhfojomionfpkfelancnnkf'
-  PACKED_HASH_BYTES = \
-      '{0x94, 0x16, 0x0b, 0x6d, 0x41, 0x75, 0xe9, 0xec,' \
-      ' 0x8e, 0xd5, 0xfa, 0x54, 0xb0, 0xd2, 0xdd, 0xa5,' \
-      ' 0x6e, 0x05, 0x6b, 0xe8, 0x73, 0x47, 0xf6, 0xc4,' \
-      ' 0x11, 0x9f, 0xbc, 0xb3, 0x09, 0xb3, 0x5b, 0x40}'
-
-  UNPACKED_APP_ID = 'cbcdidchbppangcjoddlpdjlenngjldk'
-  UNPACKED_HASH_BYTES = \
-      '{0x21, 0x23, 0x83, 0x27, 0x1f, 0xf0, 0xd6, 0x29,' \
-      ' 0xe3, 0x3b, 0xf3, 0x9b, 0x4d, 0xd6, 0x9b, 0x3a,' \
-      ' 0xff, 0x7d, 0x6b, 0xc4, 0x78, 0x30, 0x47, 0xa6,' \
-      ' 0x23, 0x12, 0x72, 0x84, 0x9b, 0x9a, 0xf6, 0x3c}'
-
-
-  def testPackedHashAppId(self):
-    """ Test the output generated for a canned, packed CRX. """
-    self.assertEqual(crx_id.GetCRXAppID(self.PACKED_CRX),
-                     self.PACKED_APP_ID)
-    self.assertEqual(crx_id.GetCRXHash(self.PACKED_CRX),
-                     self.PACKED_HASH_BYTES)
-
-
-  def testUnpackedHashAppId(self):
-    """ Test the output generated for a canned, unpacked extension. """
-    unpacked_test_manifest_path = os.path.join(
-        self.CRX_ID_DIR, 'manifest_with_key.json')
-    temp_unpacked_crx = tempfile.mkdtemp()
-    shutil.copy2(unpacked_test_manifest_path,
-                 os.path.join(temp_unpacked_crx, 'manifest.json'))
-    self.assertEqual(crx_id.GetCRXAppID(temp_unpacked_crx),
-                     self.UNPACKED_APP_ID)
-    self.assertEqual(crx_id.GetCRXHash(temp_unpacked_crx),
-                     self.UNPACKED_HASH_BYTES)
-    self.assertTrue(crx_id.HasPublicKey(temp_unpacked_crx))
-    shutil.rmtree(temp_unpacked_crx)
-
-
-  def testFromFilePath(self):
-    """ Test calculation of extension id from file paths. """
-    self.assertEqual(crx_id.GetCRXAppID('/tmp/temp_extension',
-                                        from_file_path=True),
-                     'ajbbicncdkdlchpjplgjaglppbcbmaji')
-
-
-  def testFromWindowsPath(self):
-    self.assertEqual(crx_id.GetCRXAppID(r'D:\Documents\chrome\test_extension',
-                                        from_file_path=True,
-                                        is_win_path=True),
-                     'fegemedmbnhglnecjgbdhekaghkccplm')
-
-    # Test drive letter normalization.
-    kWinPathId = 'aiinlcdagjihibappcdnnhcccdokjlaf'
-    self.assertEqual(crx_id.GetCRXAppID(r'c:\temp_extension',
-                                        from_file_path=True,
-                                        is_win_path=True),
-                     kWinPathId)
-    self.assertEqual(crx_id.GetCRXAppID(r'C:\temp_extension',
-                                        from_file_path=True,
-                                        is_win_path=True),
-                     kWinPathId)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_backend.py
deleted file mode 100644
index 034b483..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_backend.py
+++ /dev/null
@@ -1,648 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import datetime
-import glob
-import heapq
-import logging
-import os
-import os.path
-import random
-import re
-import shutil
-import subprocess as subprocess
-import sys
-import tempfile
-import time
-
-import py_utils
-from py_utils import cloud_storage  # pylint: disable=import-error
-import dependency_manager  # pylint: disable=import-error
-
-from telemetry.internal.util import binary_manager
-from telemetry.core import exceptions
-from telemetry.internal.backends import browser_backend
-from telemetry.internal.backends.chrome import chrome_browser_backend
-from telemetry.internal.util import path
-
-
-def ParseCrashpadDateTime(date_time_str):
-  # Python strptime does not support time zone parsing, strip it.
-  date_time_parts = date_time_str.split()
-  if len(date_time_parts) >= 3:
-    date_time_str = ' '.join(date_time_parts[:2])
-  return datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S')
-
-
-def GetSymbolBinaries(minidump, arch_name, os_name):
-  # Returns binary file where symbols are located.
-  minidump_dump = binary_manager.FetchPath('minidump_dump', arch_name, os_name)
-  assert minidump_dump
-
-  symbol_binaries = []
-
-  minidump_cmd = [minidump_dump, minidump]
-  try:
-    with open(os.devnull, 'wb') as DEVNULL:
-      minidump_output = subprocess.check_output(minidump_cmd, stderr=DEVNULL)
-  except subprocess.CalledProcessError as e:
-    # For some reason minidump_dump always fails despite successful dumping.
-    minidump_output = e.output
-
-  minidump_binary_re = re.compile(r'\W+\(code_file\)\W+=\W\"(.*)\"')
-  for minidump_line in minidump_output.splitlines():
-    line_match = minidump_binary_re.match(minidump_line)
-    if line_match:
-      binary_path = line_match.group(1)
-      if not os.path.isfile(binary_path):
-        continue
-
-      # Filter out system binaries.
-      if (binary_path.startswith('/usr/lib/') or
-          binary_path.startswith('/System/Library/') or
-          binary_path.startswith('/lib/')):
-        continue
-
-      # Filter out other binary file types which have no symbols.
-      if (binary_path.endswith('.pak') or
-          binary_path.endswith('.bin') or
-          binary_path.endswith('.dat') or
-          binary_path.endswith('.ttf')):
-        continue
-
-      symbol_binaries.append(binary_path)
-  return symbol_binaries
-
-
-def GenerateBreakpadSymbols(minidump, arch, os_name, symbols_dir, browser_dir):
-  logging.info('Dumping breakpad symbols.')
-  generate_breakpad_symbols_command = binary_manager.FetchPath(
-      'generate_breakpad_symbols', arch, os_name)
-  if not generate_breakpad_symbols_command:
-    return
-
-  for binary_path in GetSymbolBinaries(minidump, arch, os_name):
-    cmd = [
-        sys.executable,
-        generate_breakpad_symbols_command,
-        '--binary=%s' % binary_path,
-        '--symbols-dir=%s' % symbols_dir,
-        '--build-dir=%s' % browser_dir,
-        ]
-
-    try:
-      subprocess.check_call(cmd, stderr=open(os.devnull, 'w'))
-    except subprocess.CalledProcessError:
-      logging.warning('Failed to execute "%s"' % ' '.join(cmd))
-      return
-
-
-class DesktopBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
-  """The backend for controlling a locally-executed browser instance, on Linux,
-  Mac or Windows.
-  """
-  def __init__(self, desktop_platform_backend, browser_options, executable,
-               flash_path, is_content_shell, browser_directory):
-    super(DesktopBrowserBackend, self).__init__(
-        desktop_platform_backend,
-        supports_tab_control=not is_content_shell,
-        supports_extensions=not is_content_shell,
-        browser_options=browser_options)
-
-    # Initialize fields so that an explosion during init doesn't break in Close.
-    self._proc = None
-    self._tmp_profile_dir = None
-    self._tmp_output_file = None
-    self._most_recent_symbolized_minidump_paths = set([])
-    self._minidump_path_crashpad_retrieval = {}
-
-    self._executable = executable
-    if not self._executable:
-      raise Exception('Cannot create browser, no executable found!')
-
-    assert not flash_path or os.path.exists(flash_path)
-    self._flash_path = flash_path
-
-    self._is_content_shell = is_content_shell
-
-    extensions_to_load = browser_options.extensions_to_load
-
-    if len(extensions_to_load) > 0 and is_content_shell:
-      raise browser_backend.ExtensionsNotSupportedException(
-          'Content shell does not support extensions.')
-
-    self._browser_directory = browser_directory
-    self._port = None
-    self._tmp_minidump_dir = tempfile.mkdtemp()
-    if self.is_logging_enabled:
-      self._log_file_path = os.path.join(tempfile.mkdtemp(), 'chrome.log')
-    else:
-      self._log_file_path = None
-
-    self._SetupProfile()
-
-  @property
-  def is_logging_enabled(self):
-    return self.browser_options.logging_verbosity in [
-        self.browser_options.NON_VERBOSE_LOGGING,
-        self.browser_options.VERBOSE_LOGGING]
-
-  @property
-  def log_file_path(self):
-    return self._log_file_path
-
-  @property
-  def supports_uploading_logs(self):
-    return (self.browser_options.logs_cloud_bucket and self.log_file_path and
-            os.path.isfile(self.log_file_path))
-
-  def _SetupProfile(self):
-    if not self.browser_options.dont_override_profile:
-      if self._output_profile_path:
-        self._tmp_profile_dir = self._output_profile_path
-      else:
-        self._tmp_profile_dir = tempfile.mkdtemp()
-
-      profile_dir = self.browser_options.profile_dir
-      if profile_dir:
-        assert self._tmp_profile_dir != profile_dir
-        if self._is_content_shell:
-          logging.critical('Profiles cannot be used with content shell')
-          sys.exit(1)
-        logging.info("Using profile directory:'%s'." % profile_dir)
-        shutil.rmtree(self._tmp_profile_dir)
-        shutil.copytree(profile_dir, self._tmp_profile_dir)
-    # No matter whether we're using an existing profile directory or
-    # creating a new one, always delete the well-known file containing
-    # the active DevTools port number.
-    port_file = self._GetDevToolsActivePortPath()
-    if os.path.isfile(port_file):
-      try:
-        os.remove(port_file)
-      except Exception as e:
-        logging.critical('Unable to remove DevToolsActivePort file: %s' % e)
-        sys.exit(1)
-
-  def _GetDevToolsActivePortPath(self):
-    return os.path.join(self.profile_directory, 'DevToolsActivePort')
-
-  def _GetCdbPath(self):
-    # cdb.exe might have been co-located with the browser's executable
-    # during the build, but that's not a certainty. (This is only done
-    # in Chromium builds on the bots, which is why it's not a hard
-    # requirement.) See if it's available.
-    colocated_cdb = os.path.join(self._browser_directory, 'cdb', 'cdb.exe')
-    if path.IsExecutable(colocated_cdb):
-      return colocated_cdb
-    possible_paths = (
-        # Installed copies of the Windows SDK.
-        os.path.join('Windows Kits', '*', 'Debuggers', 'x86'),
-        os.path.join('Windows Kits', '*', 'Debuggers', 'x64'),
-        # Old copies of the Debugging Tools for Windows.
-        'Debugging Tools For Windows',
-        'Debugging Tools For Windows (x86)',
-        'Debugging Tools For Windows (x64)',
-        # The hermetic copy of the Windows toolchain in depot_tools.
-        os.path.join('win_toolchain', 'vs_files', '*', 'win_sdk',
-                     'Debuggers', 'x86'),
-        os.path.join('win_toolchain', 'vs_files', '*', 'win_sdk',
-                     'Debuggers', 'x64'),
-    )
-    for possible_path in possible_paths:
-      app_path = os.path.join(possible_path, 'cdb.exe')
-      app_path = path.FindInstalledWindowsApplication(app_path)
-      if app_path:
-        return app_path
-    return None
-
-  def HasBrowserFinishedLaunching(self):
-    # In addition to the functional check performed by the base class, quickly
-    # check if the browser process is still alive.
-    if not self.IsBrowserRunning():
-      raise exceptions.ProcessGoneException(
-          "Return code: %d" % self._proc.returncode)
-    # Start DevTools on an ephemeral port and wait for the well-known file
-    # containing the port number to exist.
-    port_file = self._GetDevToolsActivePortPath()
-    if not os.path.isfile(port_file):
-      # File isn't ready yet. Return false. Will retry.
-      return False
-    # Attempt to avoid reading the file until it's populated.
-    got_port = False
-    try:
-      if os.stat(port_file).st_size > 0:
-        with open(port_file) as f:
-          port_string = f.read()
-          self._port = int(port_string)
-          logging.info('Discovered ephemeral port %s' % self._port)
-          got_port = True
-    except Exception:
-      # Both stat and open can throw exceptions.
-      pass
-    if not got_port:
-      # File isn't ready yet. Return false. Will retry.
-      return False
-    return super(DesktopBrowserBackend, self).HasBrowserFinishedLaunching()
-
-  def GetBrowserStartupArgs(self):
-    args = super(DesktopBrowserBackend, self).GetBrowserStartupArgs()
-    self._port = 0
-    logging.info('Requested remote debugging port: %d' % self._port)
-    args.append('--remote-debugging-port=%i' % self._port)
-    args.append('--enable-crash-reporter-for-testing')
-    args.append('--disable-component-update')
-    if not self._is_content_shell:
-      args.append('--window-size=1280,1024')
-      if self._flash_path:
-        args.append('--ppapi-flash-path=%s' % self._flash_path)
-        # Also specify the version of Flash as a large version, so that it is
-        # not overridden by the bundled or component-updated version of Flash.
-        args.append('--ppapi-flash-version=99.9.999.999')
-      if not self.browser_options.dont_override_profile:
-        args.append('--user-data-dir=%s' % self._tmp_profile_dir)
-    else:
-      args.append('--data-path=%s' % self._tmp_profile_dir)
-
-    trace_config_file = (self.platform_backend.tracing_controller_backend
-                         .GetChromeTraceConfigFile())
-    if trace_config_file:
-      args.append('--trace-config-file=%s' % trace_config_file)
-    return args
-
-  def Start(self):
-    assert not self._proc, 'Must call Close() before Start()'
-
-    # macOS displays a blocking crash resume dialog that we need to suppress.
-    if self.browser.platform.GetOSName() == 'mac':
-      subprocess.call(['defaults', 'write', '-app', self._executable,
-                       'NSQuitAlwaysKeepsWindows', '-bool', 'false'])
-
-
-    args = [self._executable]
-    args.extend(self.GetBrowserStartupArgs())
-    if self.browser_options.startup_url:
-      args.append(self.browser_options.startup_url)
-    env = os.environ.copy()
-    env['CHROME_HEADLESS'] = '1'  # Don't upload minidumps.
-    env['BREAKPAD_DUMP_LOCATION'] = self._tmp_minidump_dir
-    if self.is_logging_enabled:
-      sys.stderr.write(
-        'Chrome log file will be saved in %s\n' % self.log_file_path)
-      env['CHROME_LOG_FILE'] = self.log_file_path
-    logging.info('Starting Chrome %s', args)
-    if not self.browser_options.show_stdout:
-      self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
-      self._proc = subprocess.Popen(
-          args, stdout=self._tmp_output_file, stderr=subprocess.STDOUT, env=env)
-    else:
-      self._proc = subprocess.Popen(args, env=env)
-
-    try:
-      self._WaitForBrowserToComeUp()
-      # browser is foregrounded by default on Windows and Linux, but not Mac.
-      if self.browser.platform.GetOSName() == 'mac':
-        subprocess.Popen([
-          'osascript', '-e', ('tell application "%s" to activate' %
-                              self._executable)])
-      self._InitDevtoolsClientBackend()
-      if self._supports_extensions:
-        self._WaitForExtensionsToLoad()
-    except:
-      self.Close()
-      raise
-
-  @property
-  def pid(self):
-    if self._proc:
-      return self._proc.pid
-    return None
-
-  @property
-  def browser_directory(self):
-    return self._browser_directory
-
-  @property
-  def profile_directory(self):
-    return self._tmp_profile_dir
-
-  def IsBrowserRunning(self):
-    return self._proc and self._proc.poll() == None
-
-  def GetStandardOutput(self):
-    if not self._tmp_output_file:
-      if self.browser_options.show_stdout:
-        # This can happen in the case that loading the Chrome binary fails.
-        # We print rather than using logging here, because that makes a
-        # recursive call to this function.
-        print >> sys.stderr, "Can't get standard output with --show-stdout"
-      return ''
-    self._tmp_output_file.flush()
-    try:
-      with open(self._tmp_output_file.name) as f:
-        return f.read()
-    except IOError:
-      return ''
-
-  def _MinidumpObtainedFromCrashpad(self, minidump):
-    if minidump in self._minidump_path_crashpad_retrieval:
-      return self._minidump_path_crashpad_retrieval[minidump]
-    # Default to crashpad where we hope to be eventually
-    return True
-
-  def _GetAllCrashpadMinidumps(self):
-    if not self._tmp_minidump_dir:
-      logging.warning('No _tmp_minidump_dir; browser already closed?')
-      return None
-    os_name = self.browser.platform.GetOSName()
-    arch_name = self.browser.platform.GetArchName()
-    try:
-      crashpad_database_util = binary_manager.FetchPath(
-          'crashpad_database_util', arch_name, os_name)
-      if not crashpad_database_util:
-        logging.warning('No crashpad_database_util found')
-        return None
-    except dependency_manager.NoPathFoundError:
-      logging.warning('No path to crashpad_database_util found')
-      return None
-
-    logging.info('Found crashpad_database_util')
-
-    report_output = subprocess.check_output([
-        crashpad_database_util, '--database=' + self._tmp_minidump_dir,
-        '--show-pending-reports', '--show-completed-reports',
-        '--show-all-report-info'])
-
-    last_indentation = -1
-    reports_list = []
-    report_dict = {}
-    for report_line in report_output.splitlines():
-      # Report values are grouped together by the same indentation level.
-      current_indentation = 0
-      for report_char in report_line:
-        if not report_char.isspace():
-          break
-        current_indentation += 1
-
-      # Decrease in indentation level indicates a new report is being printed.
-      if current_indentation >= last_indentation:
-        report_key, report_value = report_line.split(':', 1)
-        if report_value:
-          report_dict[report_key.strip()] = report_value.strip()
-      elif report_dict:
-        try:
-          report_time = ParseCrashpadDateTime(report_dict['Creation time'])
-          report_path = report_dict['Path'].strip()
-          reports_list.append((report_time, report_path))
-        except (ValueError, KeyError) as e:
-          logging.warning('Crashpad report expected valid keys'
-                          ' "Path" and "Creation time": %s', e)
-        finally:
-          report_dict = {}
-
-      last_indentation = current_indentation
-
-    # Include the last report.
-    if report_dict:
-      try:
-        report_time = ParseCrashpadDateTime(report_dict['Creation time'])
-        report_path = report_dict['Path'].strip()
-        reports_list.append((report_time, report_path))
-      except (ValueError, KeyError) as e:
-        logging.warning('Crashpad report expected valid keys'
-                          ' "Path" and "Creation time": %s', e)
-
-    return reports_list
-
-  def _GetMostRecentCrashpadMinidump(self):
-    reports_list = self._GetAllCrashpadMinidumps()
-    if reports_list:
-      _, most_recent_report_path = max(reports_list)
-      return most_recent_report_path
-
-    return None
-
-  def _GetBreakPadMinidumpPaths(self):
-    if not self._tmp_minidump_dir:
-      logging.warning('No _tmp_minidump_dir; browser already closed?')
-      return None
-    return glob.glob(os.path.join(self._tmp_minidump_dir, '*.dmp'))
-
-  def _GetMostRecentMinidump(self):
-    # Crashpad dump layout will be the standard eventually, check it first.
-    crashpad_dump = True
-    most_recent_dump = self._GetMostRecentCrashpadMinidump()
-
-    # Typical breakpad format is simply dump files in a folder.
-    if not most_recent_dump:
-      crashpad_dump = False
-      logging.info('No minidump found via crashpad_database_util')
-      dumps = self._GetBreakPadMinidumpPaths()
-      if dumps:
-        most_recent_dump = heapq.nlargest(1, dumps, os.path.getmtime)[0]
-        if most_recent_dump:
-          logging.info('Found minidump via globbing in minidump dir')
-
-    # As a sanity check, make sure the crash dump is recent.
-    if (most_recent_dump and
-        os.path.getmtime(most_recent_dump) < (time.time() - (5 * 60))):
-      logging.warning('Crash dump is older than 5 minutes. May not be correct.')
-
-    self._minidump_path_crashpad_retrieval[most_recent_dump] = crashpad_dump
-    return most_recent_dump
-
-  def _IsExecutableStripped(self):
-    if self.browser.platform.GetOSName() == 'mac':
-      try:
-        symbols = subprocess.check_output(['/usr/bin/nm', self._executable])
-      except subprocess.CalledProcessError as err:
-        logging.warning('Error when checking whether executable is stripped: %s'
-                        % err.output)
-        # Just assume that binary is stripped to skip breakpad symbol generation
-        # if this check failed.
-        return True
-      num_symbols = len(symbols.splitlines())
-      # We assume that if there are more than 10 symbols the executable is not
-      # stripped.
-      return num_symbols < 10
-    else:
-      return False
-
-  def _GetStackFromMinidump(self, minidump):
-    os_name = self.browser.platform.GetOSName()
-    if os_name == 'win':
-      cdb = self._GetCdbPath()
-      if not cdb:
-        logging.warning('cdb.exe not found.')
-        return None
-      # Move to the thread which triggered the exception (".ecxr"). Then include
-      # a description of the exception (".lastevent"). Also include all the
-      # threads' stacks ("~*kb30") as well as the ostensibly crashed stack
-      # associated with the exception context record ("kb30"). Note that stack
-      # dumps, including that for the crashed thread, may not be as precise as
-      # the one starting from the exception context record.
-      # Specify kb instead of k in order to get four arguments listed, for
-      # easier diagnosis from stacks.
-      output = subprocess.check_output([cdb, '-y', self._browser_directory,
-                                        '-c', '.ecxr;.lastevent;kb30;~*kb30;q',
-                                        '-z', minidump])
-      # The output we care about starts with "Last event:" or possibly
-      # other things we haven't seen yet. If we can't find the start of the
-      # last event entry, include output from the beginning.
-      info_start = 0
-      info_start_match = re.search("Last event:", output, re.MULTILINE)
-      if info_start_match:
-        info_start = info_start_match.start()
-      info_end = output.find('quit:')
-      return output[info_start:info_end]
-
-    arch_name = self.browser.platform.GetArchName()
-    stackwalk = binary_manager.FetchPath(
-        'minidump_stackwalk', arch_name, os_name)
-    if not stackwalk:
-      logging.warning('minidump_stackwalk binary not found.')
-      return None
-    # We only want this logic on linux platforms that are still using breakpad.
-    # See crbug.com/667475
-    if not self._MinidumpObtainedFromCrashpad(minidump):
-      with open(minidump, 'rb') as infile:
-        minidump += '.stripped'
-        with open(minidump, 'wb') as outfile:
-          outfile.write(''.join(infile.read().partition('MDMP')[1:]))
-
-    symbols_path = os.path.join(self._tmp_minidump_dir, 'symbols')
-    GenerateBreakpadSymbols(minidump, arch_name, os_name,
-                            symbols_path, self._browser_directory)
-
-    return subprocess.check_output([stackwalk, minidump, symbols_path],
-                                   stderr=open(os.devnull, 'w'))
-
-  def _UploadMinidumpToCloudStorage(self, minidump_path):
-    """ Upload minidump_path to cloud storage and return the cloud storage url.
-    """
-    remote_path = ('minidump-%s-%i.dmp' %
-                   (datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'),
-                    random.randint(0, 1000000)))
-    try:
-      return cloud_storage.Insert(cloud_storage.TELEMETRY_OUTPUT, remote_path,
-                                  minidump_path)
-    except cloud_storage.CloudStorageError as err:
-      logging.error('Cloud storage error while trying to upload dump: %s' %
-                    repr(err))
-      return '<Missing link>'
-
-  def GetStackTrace(self):
-    """Returns a stack trace if a valid minidump is found, will return a tuple
-       (valid, output) where valid will be True if a valid minidump was found
-       and output will contain either an error message or the attempt to
-       symbolize the minidump if one was found.
-    """
-    most_recent_dump = self._GetMostRecentMinidump()
-    if not most_recent_dump:
-      return (False, 'No crash dump found.')
-    logging.info('Minidump found: %s' % most_recent_dump)
-    return self._InternalSymbolizeMinidump(most_recent_dump)
-
-  def GetMostRecentMinidumpPath(self):
-    return self._GetMostRecentMinidump()
-
-  def GetAllMinidumpPaths(self):
-    reports_list = self._GetAllCrashpadMinidumps()
-    if reports_list:
-      for report in reports_list:
-        self._minidump_path_crashpad_retrieval[report[1]] = True
-      return [report[1] for report in reports_list]
-    else:
-      logging.info('No minidump found via crashpad_database_util')
-      dumps = self._GetBreakPadMinidumpPaths()
-      if dumps:
-        logging.info('Found minidump via globbing in minidump dir')
-        for dump in dumps:
-          self._minidump_path_crashpad_retrieval[dump] = False
-        return dumps
-      return []
-
-  def GetAllUnsymbolizedMinidumpPaths(self):
-    minidump_paths = set(self.GetAllMinidumpPaths())
-    # If we have already symbolized paths remove them from the list
-    unsymbolized_paths = (minidump_paths
-      - self._most_recent_symbolized_minidump_paths)
-    return list(unsymbolized_paths)
-
-  def SymbolizeMinidump(self, minidump_path):
-    return self._InternalSymbolizeMinidump(minidump_path)
-
-  def _InternalSymbolizeMinidump(self, minidump_path):
-    cloud_storage_link = self._UploadMinidumpToCloudStorage(minidump_path)
-
-    stack = self._GetStackFromMinidump(minidump_path)
-    if not stack:
-      error_message = ('Failed to symbolize minidump. Raw stack is uploaded to'
-                       ' cloud storage: %s.' % cloud_storage_link)
-      return (False, error_message)
-
-    self._most_recent_symbolized_minidump_paths.add(minidump_path)
-    return (True, stack)
-
-  def __del__(self):
-    self.Close()
-
-  def _TryCooperativeShutdown(self):
-    if self.browser.platform.IsCooperativeShutdownSupported():
-      # Ideally there would be a portable, cooperative shutdown
-      # mechanism for the browser. This seems difficult to do
-      # correctly for all embedders of the content API. The only known
-      # problem with unclean shutdown of the browser process is on
-      # Windows, where suspended child processes frequently leak. For
-      # now, just solve this particular problem. See Issue 424024.
-      if self.browser.platform.CooperativelyShutdown(self._proc, "chrome"):
-        try:
-          py_utils.WaitFor(lambda: not self.IsBrowserRunning(), timeout=5)
-          logging.info('Successfully shut down browser cooperatively')
-        except py_utils.TimeoutException as e:
-          logging.warning('Failed to cooperatively shutdown. ' +
-                          'Proceeding to terminate: ' + str(e))
-
-  def Background(self):
-    raise NotImplementedError
-
-  def Close(self):
-    super(DesktopBrowserBackend, self).Close()
-
-    # First, try to cooperatively shutdown.
-    if self.IsBrowserRunning():
-      self._TryCooperativeShutdown()
-
-    # Second, try to politely shutdown with SIGTERM.
-    if self.IsBrowserRunning():
-      self._proc.terminate()
-      try:
-        py_utils.WaitFor(lambda: not self.IsBrowserRunning(), timeout=5)
-        self._proc = None
-      except py_utils.TimeoutException:
-        logging.warning('Failed to gracefully shutdown.')
-
-    # Shutdown aggressively if all above failed.
-    if self.IsBrowserRunning():
-      logging.warning('Proceed to kill the browser.')
-      self._proc.kill()
-    self._proc = None
-
-    if self._output_profile_path:
-      # If we need the output then double check that it exists.
-      if not (self._tmp_profile_dir and os.path.exists(self._tmp_profile_dir)):
-        raise Exception("No profile directory generated by Chrome: '%s'." %
-            self._tmp_profile_dir)
-    else:
-      # If we don't need the profile after the run then cleanup.
-      if self._tmp_profile_dir and os.path.exists(self._tmp_profile_dir):
-        shutil.rmtree(self._tmp_profile_dir, ignore_errors=True)
-        self._tmp_profile_dir = None
-
-    if self._tmp_output_file:
-      self._tmp_output_file.close()
-      self._tmp_output_file = None
-
-    if self._tmp_minidump_dir:
-      shutil.rmtree(self._tmp_minidump_dir, ignore_errors=True)
-      self._tmp_minidump_dir = None
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_finder.py b/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_finder.py
deleted file mode 100644
index e2cedb7..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_finder.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Finds desktop browsers that can be controlled by telemetry."""
-
-import logging
-import os
-import sys
-
-import dependency_manager  # pylint: disable=import-error
-
-from telemetry.core import exceptions
-from telemetry.core import platform as platform_module
-from telemetry.internal.backends.chrome import desktop_browser_backend
-from telemetry.internal.browser import browser
-from telemetry.internal.browser import possible_browser
-from telemetry.internal.platform import desktop_device
-from telemetry.internal.util import binary_manager
-# This is a workaround for https://goo.gl/1tGNgd
-from telemetry.internal.util import path as path_module
-
-
-class PossibleDesktopBrowser(possible_browser.PossibleBrowser):
-  """A desktop browser that can be controlled."""
-
-  def __init__(self, browser_type, finder_options, executable, flash_path,
-               is_content_shell, browser_directory, is_local_build=False):
-    target_os = sys.platform.lower()
-    super(PossibleDesktopBrowser, self).__init__(
-        browser_type, target_os, not is_content_shell)
-    assert browser_type in FindAllBrowserTypes(finder_options), (
-        'Please add %s to desktop_browser_finder.FindAllBrowserTypes' %
-        browser_type)
-    self._local_executable = executable
-    self._flash_path = flash_path
-    self._is_content_shell = is_content_shell
-    self._browser_directory = browser_directory
-    self.is_local_build = is_local_build
-
-  def __repr__(self):
-    return 'PossibleDesktopBrowser(type=%s, executable=%s, flash=%s)' % (
-        self.browser_type, self._local_executable, self._flash_path)
-
-  def _InitPlatformIfNeeded(self):
-    if self._platform:
-      return
-
-    self._platform = platform_module.GetHostPlatform()
-
-    # pylint: disable=protected-access
-    self._platform_backend = self._platform._platform_backend
-
-  def Create(self, finder_options):
-    if self._flash_path and not os.path.exists(self._flash_path):
-      logging.warning(
-          'Could not find Flash at %s. Continuing without Flash.\n'
-          'To run with Flash, check it out via http://go/read-src-internal',
-          self._flash_path)
-      self._flash_path = None
-
-    self._InitPlatformIfNeeded()
-
-    browser_backend = desktop_browser_backend.DesktopBrowserBackend(
-        self._platform_backend,
-        finder_options.browser_options, self._local_executable,
-        self._flash_path, self._is_content_shell, self._browser_directory)
-    return browser.Browser(
-        browser_backend, self._platform_backend, self._credentials_path)
-
-  def SupportsOptions(self, browser_options):
-    if ((len(browser_options.extensions_to_load) != 0)
-        and self._is_content_shell):
-      return False
-    return True
-
-  def UpdateExecutableIfNeeded(self):
-    pass
-
-  def last_modification_time(self):
-    if os.path.exists(self._local_executable):
-      return os.path.getmtime(self._local_executable)
-    return -1
-
-def SelectDefaultBrowser(possible_browsers):
-  local_builds_by_date = [
-      b for b in sorted(possible_browsers,
-                        key=lambda b: b.last_modification_time())
-      if b.is_local_build]
-  if local_builds_by_date:
-    return local_builds_by_date[-1]
-  return None
-
-def CanFindAvailableBrowsers():
-  return not platform_module.GetHostPlatform().GetOSName() == 'chromeos'
-
-def CanPossiblyHandlePath(target_path):
-  _, extension = os.path.splitext(target_path.lower())
-  if sys.platform == 'darwin' or sys.platform.startswith('linux'):
-    return not extension
-  elif sys.platform.startswith('win'):
-    return extension == '.exe'
-  return False
-
-def FindAllBrowserTypes(_):
-  return [
-      'exact',
-      'reference',
-      'release',
-      'release_x64',
-      'debug',
-      'debug_x64',
-      'default',
-      'stable',
-      'beta',
-      'dev',
-      'canary',
-      'content-shell-debug',
-      'content-shell-debug_x64',
-      'content-shell-release',
-      'content-shell-release_x64',
-      'content-shell-default',
-      'system']
-
-def FindAllAvailableBrowsers(finder_options, device):
-  """Finds all the desktop browsers available on this machine."""
-  if not isinstance(device, desktop_device.DesktopDevice):
-    return []
-
-  browsers = []
-
-  if not CanFindAvailableBrowsers():
-    return []
-
-  has_x11_display = True
-  if (sys.platform.startswith('linux') and
-      os.getenv('DISPLAY') == None):
-    has_x11_display = False
-
-  os_name = platform_module.GetHostPlatform().GetOSName()
-  arch_name = platform_module.GetHostPlatform().GetArchName()
-  try:
-    flash_path = binary_manager.LocalPath('flash', arch_name, os_name)
-  except dependency_manager.NoPathFoundError:
-    flash_path = None
-    logging.warning(
-        'Chrome build location for %s_%s not found. Browser will be run '
-        'without Flash.', os_name, arch_name)
-
-  chromium_app_names = []
-  if sys.platform == 'darwin':
-    chromium_app_names.append('Chromium.app/Contents/MacOS/Chromium')
-    chromium_app_names.append('Google Chrome.app/Contents/MacOS/Google Chrome')
-    content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell'
-  elif sys.platform.startswith('linux'):
-    chromium_app_names.append('chrome')
-    content_shell_app_name = 'content_shell'
-  elif sys.platform.startswith('win'):
-    chromium_app_names.append('chrome.exe')
-    content_shell_app_name = 'content_shell.exe'
-  else:
-    raise Exception('Platform not recognized')
-
-  # Add the explicit browser executable if given and we can handle it.
-  if (finder_options.browser_executable and
-      CanPossiblyHandlePath(finder_options.browser_executable)):
-    is_content_shell = finder_options.browser_executable.endswith(
-        content_shell_app_name)
-    is_chrome_or_chromium = len([x for x in chromium_app_names if
-        finder_options.browser_executable.endswith(x)]) != 0
-
-    # It is okay if the executable name doesn't match any of known chrome
-    # browser executables, since it may be of a different browser.
-    if is_chrome_or_chromium or is_content_shell:
-      normalized_executable = os.path.expanduser(
-          finder_options.browser_executable)
-      if path_module.IsExecutable(normalized_executable):
-        browser_directory = os.path.dirname(finder_options.browser_executable)
-        browsers.append(PossibleDesktopBrowser(
-            'exact', finder_options, normalized_executable, flash_path,
-            is_content_shell,
-            browser_directory))
-      else:
-        raise exceptions.PathMissingError(
-            '%s specified by --browser-executable does not exist or is not '
-            'executable' %
-            normalized_executable)
-
-  def AddIfFound(browser_type, build_path, app_name, content_shell):
-    app = os.path.join(build_path, app_name)
-    if path_module.IsExecutable(app):
-      browsers.append(PossibleDesktopBrowser(
-          browser_type, finder_options, app, flash_path,
-          content_shell, build_path, is_local_build=True))
-      return True
-    return False
-
-  # Add local builds
-  for build_path in path_module.GetBuildDirectories(finder_options.chrome_root):
-    # TODO(agrieve): Extract browser_type from args.gn's is_debug.
-    browser_type = os.path.basename(build_path).lower()
-    for chromium_app_name in chromium_app_names:
-      AddIfFound(browser_type, build_path, chromium_app_name, False)
-    AddIfFound('content-shell-' + browser_type, build_path,
-               content_shell_app_name, True)
-
-  reference_build = None
-  if finder_options.browser_type == 'reference':
-    # Reference builds are only available in a Chromium checkout. We should not
-    # raise an error just because they don't exist.
-    os_name = platform_module.GetHostPlatform().GetOSName()
-    arch_name = platform_module.GetHostPlatform().GetArchName()
-    reference_build = binary_manager.FetchPath(
-        'chrome_stable', arch_name, os_name)
-
-  # Mac-specific options.
-  if sys.platform == 'darwin':
-    mac_canary_root = '/Applications/Google Chrome Canary.app/'
-    mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary'
-    mac_system_root = '/Applications/Google Chrome.app'
-    mac_system = mac_system_root + '/Contents/MacOS/Google Chrome'
-    if path_module.IsExecutable(mac_canary):
-      browsers.append(PossibleDesktopBrowser('canary', finder_options,
-                                             mac_canary, None, False,
-                                             mac_canary_root))
-
-    if path_module.IsExecutable(mac_system):
-      browsers.append(PossibleDesktopBrowser('system', finder_options,
-                                             mac_system, None, False,
-                                             mac_system_root))
-
-    if reference_build and path_module.IsExecutable(reference_build):
-      reference_root = os.path.dirname(os.path.dirname(os.path.dirname(
-          reference_build)))
-      browsers.append(PossibleDesktopBrowser('reference', finder_options,
-                                             reference_build, None, False,
-                                             reference_root))
-
-  # Linux specific options.
-  if sys.platform.startswith('linux'):
-    versions = {
-        'system': os.path.split(os.path.realpath('/usr/bin/google-chrome'))[0],
-        'stable': '/opt/google/chrome',
-        'beta': '/opt/google/chrome-beta',
-        'dev': '/opt/google/chrome-unstable'
-    }
-
-    for version, root in versions.iteritems():
-      browser_path = os.path.join(root, 'chrome')
-      if path_module.IsExecutable(browser_path):
-        browsers.append(PossibleDesktopBrowser(version, finder_options,
-                                               browser_path, None, False, root))
-    if reference_build and path_module.IsExecutable(reference_build):
-      reference_root = os.path.dirname(reference_build)
-      browsers.append(PossibleDesktopBrowser('reference', finder_options,
-                                             reference_build, None, False,
-                                             reference_root))
-
-  # Win32-specific options.
-  if sys.platform.startswith('win'):
-    app_paths = [
-        ('system', os.path.join('Google', 'Chrome', 'Application')),
-        ('canary', os.path.join('Google', 'Chrome SxS', 'Application')),
-    ]
-    if reference_build:
-      app_paths.append(
-          ('reference', os.path.dirname(reference_build)))
-
-    for browser_name, app_path in app_paths:
-      for chromium_app_name in chromium_app_names:
-        full_path = path_module.FindInstalledWindowsApplication(
-            os.path.join(app_path, chromium_app_name))
-        if full_path:
-          browsers.append(PossibleDesktopBrowser(
-              browser_name, finder_options, full_path,
-              None, False, os.path.dirname(full_path)))
-
-  has_ozone_platform = False
-  for arg in finder_options.browser_options.extra_browser_args:
-    if "--ozone-platform" in arg:
-      has_ozone_platform = True
-
-  if len(browsers) and not has_x11_display and not has_ozone_platform:
-    logging.warning(
-      'Found (%s), but you do not have a DISPLAY environment set.' %
-      ','.join([b.browser_type for b in browsers]))
-    return []
-
-  return browsers
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_finder_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_finder_unittest.py
deleted file mode 100644
index c6c630e..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/desktop_browser_finder_unittest.py
+++ /dev/null
@@ -1,298 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import stat
-import unittest
-
-from pyfakefs import fake_filesystem_unittest
-
-from telemetry.core import platform
-from telemetry.core import util
-from telemetry.internal.backends.chrome import desktop_browser_finder
-from telemetry.internal.browser import browser_options
-from telemetry.internal.platform import desktop_device
-from telemetry.testing import system_stub
-
-
-# This file verifies the logic for finding a browser instance on all platforms
-# at once. It does so by providing stubs for the OS/sys/subprocess primitives
-# that the underlying finding logic usually uses to locate a suitable browser.
-# We prefer this approach to having to run the same test on every platform on
-# which we want this code to work.
-
-class FindTestBase(unittest.TestCase):
-  def setUp(self):
-    self._finder_options = browser_options.BrowserFinderOptions()
-    self._finder_options.chrome_root = '../../../'
-    self._finder_stubs = system_stub.Override(desktop_browser_finder,
-                                              ['os', 'subprocess', 'sys'])
-    self._path_stubs = system_stub.Override(
-        desktop_browser_finder.path_module, ['os', 'sys'])
-    self._catapult_path_stubs = system_stub.Override(
-        desktop_browser_finder.path_module.catapult_util, ['os', 'sys'])
-    self._util_stubs = system_stub.Override(util, ['os', 'sys'])
-
-  def tearDown(self):
-    self._finder_stubs.Restore()
-    self._path_stubs.Restore()
-    self._catapult_path_stubs.Restore()
-    self._util_stubs.Restore()
-
-  @property
-  def _files(self):
-    return self._catapult_path_stubs.os.path.files
-
-  def DoFindAll(self):
-    return desktop_browser_finder.FindAllAvailableBrowsers(
-      self._finder_options, desktop_device.DesktopDevice())
-
-  def DoFindAllTypes(self):
-    browsers = self.DoFindAll()
-    return [b.browser_type for b in browsers]
-
-  def CanFindAvailableBrowsers(self):
-    return desktop_browser_finder.CanFindAvailableBrowsers()
-
-
-def has_type(array, browser_type):
-  return len([x for x in array if x.browser_type == browser_type]) != 0
-
-
-class FindSystemTest(FindTestBase):
-  def setUp(self):
-    super(FindSystemTest, self).setUp()
-    self._finder_stubs.sys.platform = 'win32'
-    self._path_stubs.sys.platform = 'win32'
-    self._util_stubs.sys.platform = 'win32'
-
-  def testFindProgramFiles(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append(
-        'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe')
-    self._path_stubs.os.program_files = 'C:\\Program Files'
-    self.assertIn('system', self.DoFindAllTypes())
-
-  def testFindProgramFilesX86(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append(
-        'C:\\Program Files(x86)\\Google\\Chrome\\Application\\chrome.exe')
-    self._path_stubs.os.program_files_x86 = 'C:\\Program Files(x86)'
-    self.assertIn('system', self.DoFindAllTypes())
-
-  def testFindLocalAppData(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append(
-        'C:\\Local App Data\\Google\\Chrome\\Application\\chrome.exe')
-    self._path_stubs.os.local_app_data = 'C:\\Local App Data'
-    self.assertIn('system', self.DoFindAllTypes())
-
-
-class FindLocalBuildsTest(FindTestBase):
-  def setUp(self):
-    super(FindLocalBuildsTest, self).setUp()
-    self._finder_stubs.sys.platform = 'win32'
-    self._path_stubs.sys.platform = 'win32'
-    self._util_stubs.sys.platform = 'win32'
-
-  def testFindBuild(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append('..\\..\\..\\build\\Release\\chrome.exe')
-    self.assertIn('release', self.DoFindAllTypes())
-
-  def testFindOut(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append('..\\..\\..\\out\\Release\\chrome.exe')
-    self.assertIn('release', self.DoFindAllTypes())
-
-  def testFindXcodebuild(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append('..\\..\\..\\xcodebuild\\Release\\chrome.exe')
-    self.assertIn('release', self.DoFindAllTypes())
-
-
-class OSXFindTest(FindTestBase):
-  def setUp(self):
-    super(OSXFindTest, self).setUp()
-    self._finder_stubs.sys.platform = 'darwin'
-    self._path_stubs.sys.platform = 'darwin'
-    self._util_stubs.sys.platform = 'darwin'
-    self._files.append('/Applications/Google Chrome Canary.app/'
-                       'Contents/MacOS/Google Chrome Canary')
-    self._files.append('/Applications/Google Chrome.app/' +
-                       'Contents/MacOS/Google Chrome')
-    self._files.append(
-      '../../../out/Release/Chromium.app/Contents/MacOS/Chromium')
-    self._files.append(
-      '../../../out/Debug/Chromium.app/Contents/MacOS/Chromium')
-    self._files.append(
-      '../../../out/Release/Content Shell.app/Contents/MacOS/Content Shell')
-    self._files.append(
-      '../../../out/Debug/Content Shell.app/Contents/MacOS/Content Shell')
-
-  def testFindAll(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    types = self.DoFindAllTypes()
-    self.assertEquals(
-      set(types),
-      set(['debug', 'release',
-           'content-shell-debug', 'content-shell-release',
-           'canary', 'system']))
-
-  def testFindExact(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append(
-      '../../../foo1/Chromium.app/Contents/MacOS/Chromium')
-    self._finder_options.browser_executable = (
-        '../../../foo1/Chromium.app/Contents/MacOS/Chromium')
-    types = self.DoFindAllTypes()
-    self.assertTrue('exact' in types)
-
-  def testCannotFindExact(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append(
-      '../../../foo1/Chromium.app/Contents/MacOS/Chromium')
-    self._finder_options.browser_executable = (
-        '../../../foo2/Chromium.app/Contents/MacOS/Chromium')
-    self.assertRaises(Exception, self.DoFindAllTypes)
-
-class LinuxFindTest(fake_filesystem_unittest.TestCase):
-
-  def setUp(self):
-    if not platform.GetHostPlatform().GetOSName() == 'linux':
-      self.skipTest('Not running on Linux')
-    self.setUpPyfakefs()
-
-    self._finder_options = browser_options.BrowserFinderOptions()
-    self._finder_options.chrome_root = '/src/'
-
-  def CreateBrowser(self, path):
-    self.fs.CreateFile(path)
-    os.chmod(path, stat.S_IXUSR)
-
-  def DoFindAll(self):
-    return desktop_browser_finder.FindAllAvailableBrowsers(
-        self._finder_options, desktop_device.DesktopDevice())
-
-  def DoFindAllTypes(self):
-    return [b.browser_type for b in self.DoFindAll()]
-
-  def testFindAllWithCheckout(self):
-    for target in ['Release', 'Debug']:
-      for browser in ['chrome', 'content_shell']:
-        self.CreateBrowser('/src/out/%s/%s' % (target, browser))
-
-    self.assertEquals(
-        set(self.DoFindAllTypes()),
-        {'debug', 'release', 'content-shell-debug', 'content-shell-release'})
-
-  def testFindAllFailsIfNotExecutable(self):
-    self.fs.CreateFile('/src/out/Release/chrome')
-
-    self.assertFalse(self.DoFindAllTypes())
-
-  def testFindWithProvidedExecutable(self):
-    self.CreateBrowser('/foo/chrome')
-    self._finder_options.browser_executable = '/foo/chrome'
-    self.assertIn('exact', self.DoFindAllTypes())
-
-  def testFindWithProvidedApk(self):
-    self._finder_options.browser_executable = '/foo/chrome.apk'
-    self.assertNotIn('exact', self.DoFindAllTypes())
-
-  def testNoErrorWithNonChromeExecutableName(self):
-    self.fs.CreateFile('/foo/another_browser')
-    self._finder_options.browser_executable = '/foo/another_browser'
-    self.assertNotIn('exact', self.DoFindAllTypes())
-
-  def testFindAllWithInstalled(self):
-    official_names = ['chrome', 'chrome-beta', 'chrome-unstable']
-
-    for name in official_names:
-      self.CreateBrowser('/opt/google/%s/chrome' % name)
-
-    self.assertEquals(set(self.DoFindAllTypes()), {'stable', 'beta', 'dev'})
-
-  def testFindAllSystem(self):
-    self.CreateBrowser('/opt/google/chrome/chrome')
-    os.symlink('/opt/google/chrome/chrome', '/usr/bin/google-chrome')
-
-    self.assertEquals(set(self.DoFindAllTypes()), {'system', 'stable'})
-
-  def testFindAllSystemIsBeta(self):
-    self.CreateBrowser('/opt/google/chrome/chrome')
-    self.CreateBrowser('/opt/google/chrome-beta/chrome')
-    os.symlink('/opt/google/chrome-beta/chrome', '/usr/bin/google-chrome')
-
-    google_chrome = [browser for browser in self.DoFindAll()
-                     if browser.browser_type == 'system'][0]
-    self.assertEquals('/opt/google/chrome-beta',
-                      google_chrome._browser_directory)
-
-
-class WinFindTest(FindTestBase):
-  def setUp(self):
-    super(WinFindTest, self).setUp()
-
-    self._finder_stubs.sys.platform = 'win32'
-    self._path_stubs.sys.platform = 'win32'
-    self._util_stubs.sys.platform = 'win32'
-    self._path_stubs.os.local_app_data = 'c:\\Users\\Someone\\AppData\\Local'
-    self._files.append('c:\\tmp\\chrome.exe')
-    self._files.append('..\\..\\..\\build\\Release\\chrome.exe')
-    self._files.append('..\\..\\..\\build\\Debug\\chrome.exe')
-    self._files.append('..\\..\\..\\build\\Release\\content_shell.exe')
-    self._files.append('..\\..\\..\\build\\Debug\\content_shell.exe')
-    self._files.append(self._path_stubs.os.local_app_data + '\\' +
-                       'Google\\Chrome\\Application\\chrome.exe')
-    self._files.append(self._path_stubs.os.local_app_data + '\\' +
-                       'Google\\Chrome SxS\\Application\\chrome.exe')
-
-  def testFindAllGivenDefaults(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    types = self.DoFindAllTypes()
-    self.assertEquals(set(types),
-                      set(['debug', 'release',
-                           'content-shell-debug', 'content-shell-release',
-                           'system', 'canary']))
-
-  def testFindAllWithExact(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._finder_options.browser_executable = 'c:\\tmp\\chrome.exe'
-    types = self.DoFindAllTypes()
-    self.assertEquals(
-        set(types),
-        set(['exact',
-             'debug', 'release',
-             'content-shell-debug', 'content-shell-release',
-             'system', 'canary']))
-
-  def testNoErrorWithUnrecognizedExecutableName(self):
-    if not self.CanFindAvailableBrowsers():
-      return
-
-    self._files.append('c:\\foo\\another_browser.exe')
-    self._finder_options.browser_dir = 'c:\\foo\\another_browser.exe'
-    self.assertNotIn('exact', self.DoFindAllTypes())
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/extension_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/extension_backend.py
deleted file mode 100644
index b6abd97..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/extension_backend.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-
-from telemetry.internal.backends.chrome_inspector import inspector_backend_list
-from telemetry.internal.browser import extension_page
-
-
-class ExtensionBackendList(inspector_backend_list.InspectorBackendList):
-  """A dynamic sequence of extension_page.ExtensionPages."""
-
-  def __init__(self, browser_backend):
-    super(ExtensionBackendList, self).__init__(browser_backend)
-
-  def ShouldIncludeContext(self, context):
-    return context['url'].startswith('chrome-extension://')
-
-  def CreateWrapper(self, inspector_backend):
-    return extension_page.ExtensionPage(inspector_backend)
-
-class ExtensionBackendDict(collections.Mapping):
-  """A dynamic mapping of extension_id to extension_page.ExtensionPages."""
-
-  def __init__(self, browser_backend):
-    self._extension_backend_list = ExtensionBackendList(browser_backend)
-
-  def __getitem__(self, extension_id):
-    extensions = []
-    for context_id in self._extension_backend_list.IterContextIds():
-      if self.ContextIdToExtensionId(context_id) == extension_id:
-        extensions.append(
-            self._extension_backend_list.GetBackendFromContextId(context_id))
-    if not extensions:
-      raise KeyError('Cannot find an extension with id=%s' % extension_id)
-    return extensions
-
-  def __iter__(self):
-    for context_id in self._extension_backend_list.IterContextIds():
-      yield self._extension_backend_list.GetBackendFromContextId(context_id)
-
-  def __len__(self):
-    return len(self._extension_backend_list)
-
-  def ContextIdToExtensionId(self, context_id):
-    context = self._extension_backend_list.GetContextInfo(context_id)
-    return extension_page.UrlToExtensionId(context['url'])
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_backend.py
deleted file mode 100644
index fac37cb..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_backend.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import contextlib
-import json
-import logging
-import re
-import urllib2
-
-from telemetry.internal.backends.chrome import chrome_browser_backend
-from telemetry.internal.backends.chrome import system_info_backend
-
-import py_utils
-
-
-class IosBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
-  _DEBUGGER_URL_BUILDER = 'ws://localhost:%i/devtools/page/%i'
-  _DEBUGGER_URL_REGEX = r'ws://localhost:(\d+)/devtools/page/(\d+)'
-  _DEVICE_LIST_URL = 'http://localhost:9221/json'
-
-  def __init__(self, ios_platform_backend, browser_options):
-    browser_options.output_profile_path = '.'
-    super(IosBrowserBackend, self).__init__(
-        ios_platform_backend,
-        supports_tab_control=False,
-        supports_extensions=False,
-        browser_options=browser_options)
-    self._webviews = []
-    self._port = None
-    self._page = None
-    self._system_info_backend = None
-    self.UpdateRunningBrowsersInfo()
-
-  def UpdateRunningBrowsersInfo(self):
-    """ Refresh to match current state of the running browser.
-    """
-    device_urls = self.GetDeviceUrls()
-    urls = self.GetWebSocketDebuggerUrls(device_urls)
-    for url in urls:
-      m = re.match(self._DEBUGGER_URL_REGEX, url)
-      if m:
-        self._webviews.append([int(m.group(1)), int(m.group(2))])
-      else:
-        logging.error('Unexpected url format: %s' % url)
-
-    # TODO(baxley): For now, grab first item from |_webviews|. Ideally, we'd
-    # prefer to have the currently displayed tab, or something similar.
-    if self._webviews:
-      self._port = self._webviews[0][0]
-      self._page = self._webviews[0][1]
-
-  def GetDeviceUrls(self):
-    device_urls = []
-    try:
-      with contextlib.closing(
-          urllib2.urlopen(self._DEVICE_LIST_URL)) as device_list:
-        json_urls = device_list.read()
-        device_urls = json.loads(json_urls)
-        if not device_urls:
-          logging.debug('No iOS devices found. Will not try searching for iOS '
-                        'browsers.')
-          return []
-    except urllib2.URLError as e:
-      logging.debug('Error communicating with iOS device.')
-      logging.debug(str(e))
-      return []
-    return device_urls
-
-  def GetWebSocketDebuggerUrls(self, device_urls):
-    """ Get a list of the websocket debugger URLs to communicate with
-        all running UIWebViews.
-    """
-    data = []
-    # Loop through all devices.
-    for d in device_urls:
-      def GetData():
-        try:
-          with contextlib.closing(
-              # pylint: disable=cell-var-from-loop
-              urllib2.urlopen('http://%s/json' % d['url'])) as f:
-            json_result = f.read()
-            data = json.loads(json_result)
-            return data
-        except urllib2.URLError as e:
-          logging.debug('Error communicating with iOS device.')
-          logging.debug(e)
-          return False
-      try:
-        # Retry a few times since it can take a few seconds for this API to be
-        # ready, if ios_webkit_debug_proxy is just launched.
-        data = py_utils.WaitFor(GetData, 5)
-      except py_utils.TimeoutException as e:
-        logging.debug('Timeout retrieving data from iOS device')
-        logging.debug(e)
-        return []
-
-    # Find all running UIWebViews.
-    debug_urls = []
-    for j in data:
-      debug_urls.append(j['webSocketDebuggerUrl'])
-
-    return debug_urls
-
-  def GetSystemInfo(self):
-    if self._system_info_backend is None:
-      self._system_info_backend = system_info_backend.SystemInfoBackend(
-          self._port, self._page)
-    return self._system_info_backend.GetSystemInfo()
-
-  def IsBrowserRunning(self):
-    return bool(self._webviews)
-
-  #TODO(baxley): The following were stubbed out to get the sunspider benchmark
-  # running. These should be implemented.
-  @property
-  def browser_directory(self):
-    logging.warn('Not implemented')
-    return None
-
-  @property
-  def profile_directory(self):
-    logging.warn('Not implemented')
-    return None
-
-  def Start(self):
-    logging.warn('Not implemented')
-
-  def extension_backend(self):
-    logging.warn('Not implemented')
-    return None
-
-  def GetBrowserStartupArgs(self):
-    logging.warn('Not implemented')
-    return None
-
-  def HasBrowserFinishedLaunching(self):
-    logging.warn('Not implemented')
-    return False
-
-  def GetStandardOutput(self):
-    raise NotImplementedError()
-
-  def GetStackTrace(self):
-    raise NotImplementedError()
-
-  def GetMostRecentMinidumpPath(self):
-    return None
-
-  def GetAllMinidumpPaths(self):
-    return None
-
-  def GetAllUnsymbolizedMinidumpPaths(self):
-    return None
-
-  def SymbolizeMinidump(self, minidump_path):
-    return None
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_finder.py b/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_finder.py
deleted file mode 100644
index c4e98f3..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_finder.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Finds iOS browsers that can be controlled by telemetry."""
-
-import logging
-import re
-
-from telemetry.core import platform
-from telemetry.internal.backends.chrome import ios_browser_backend
-from telemetry.internal.backends.chrome_inspector import inspector_backend
-from telemetry.internal.browser import browser
-from telemetry.internal.browser import possible_browser
-from telemetry.internal.platform import ios_device
-from telemetry.internal.platform import ios_platform_backend
-
-
-# Key matches output from ios-webkit-debug-proxy and the value is a readable
-# description of the browser.
-IOS_BROWSERS = {'CriOS': 'ios-chrome', 'Version': 'ios-safari'}
-DEVICE_LIST_URL = 'http://127.0.0.1:9221/json'
-IOS_WEBKIT_DEBUG_PROXY = 'ios_webkit_debug_proxy'
-
-
-class PossibleIOSBrowser(possible_browser.PossibleBrowser):
-
-  """A running iOS browser instance."""
-  def __init__(self, browser_type, _):
-    super(PossibleIOSBrowser, self).__init__(browser_type, 'ios', True)
-
-  # TODO(baxley): Implement the following methods for iOS.
-  def Create(self, finder_options):
-    browser_backend = ios_browser_backend.IosBrowserBackend(
-        self._platform_backend, finder_options.browser_options)
-    return browser.Browser(
-        browser_backend, self._platform_backend, self._credentials_path)
-
-  def SupportsOptions(self, browser_options):
-    #TODO(baxley): Implement me.
-    return True
-
-  def UpdateExecutableIfNeeded(self):
-    #TODO(baxley): Implement me.
-    pass
-
-  def _InitPlatformIfNeeded(self):
-    if self._platform:
-      return
-
-    self._platform_backend = ios_platform_backend.IosPlatformBackend()
-    self._platform = platform.Platform(self._platform_backend)
-
-def SelectDefaultBrowser(_):
-  return None  # TODO(baxley): Implement me.
-
-
-def CanFindAvailableBrowsers():
-  # TODO(baxley): Add support for all platforms possible. Probably Linux,
-  # probably not Windows.
-  return platform.GetHostPlatform().GetOSName() == 'mac'
-
-
-def FindAllBrowserTypes(_):
-  return IOS_BROWSERS.values()
-
-
-def FindAllAvailableBrowsers(finder_options, device):
-  """Find all running iOS browsers on connected devices."""
-  if not isinstance(device, ios_device.IOSDevice):
-    return []
-
-  if not CanFindAvailableBrowsers():
-    return []
-
-  options = finder_options.browser_options
-
-  options.browser_type = 'ios-chrome'
-  host = platform.GetHostPlatform()
-  backend = ios_browser_backend.IosBrowserBackend(host, options)
-  # TODO(baxley): Use idevice to wake up device or log debug statement.
-  if not host.IsApplicationRunning(IOS_WEBKIT_DEBUG_PROXY):
-    host.LaunchApplication(IOS_WEBKIT_DEBUG_PROXY)
-    if not host.IsApplicationRunning(IOS_WEBKIT_DEBUG_PROXY):
-      return []
-
-  device_urls = backend.GetDeviceUrls()
-  if not device_urls:
-    logging.debug('Could not find any devices over %s.'
-                  % IOS_WEBKIT_DEBUG_PROXY)
-    return []
-
-  debug_urls = backend.GetWebSocketDebuggerUrls(device_urls)
-
-  # Get the userAgent for each UIWebView to find the browsers.
-  browser_pattern = (r'\)\s(%s)\/(\d+[\.\d]*)\sMobile'
-                     % '|'.join(IOS_BROWSERS.keys()))
-  browser_types = set()
-  for url in debug_urls:
-    context = {'webSocketDebuggerUrl': url, 'id': 1}
-    try:
-      inspector = inspector_backend.InspectorBackend(
-          backend.app, backend.devtools_client, context)
-      res = inspector.EvaluateJavaScript("navigator.userAgent")
-    finally:
-      inspector.Disconnect()
-    match_browsers = re.search(browser_pattern, res)
-    if match_browsers:
-      browser_types.add(match_browsers.group(1))
-
-  browsers = []
-  for browser_type in browser_types:
-    browsers.append(PossibleIOSBrowser(IOS_BROWSERS[browser_type],
-                                       finder_options))
-  return list(browsers)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_finder_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_finder_unittest.py
deleted file mode 100644
index b5b6756..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/ios_browser_finder_unittest.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.backends.chrome import ios_browser_finder
-from telemetry.internal.browser import browser_options
-from telemetry.internal.platform import ios_device
-
-
-class IosBrowserFinderUnitTest(unittest.TestCase):
-  # TODO(baxley): Currently the tests require a device with Chrome running.
-  # This should be stubbed out so it runs on any system, with no device
-  # dependencies.
-  @decorators.Enabled('ios')
-  def testFindIosChrome(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    browsers = ios_browser_finder.FindAllAvailableBrowsers(
-      finder_options, ios_device.IOSDevice())
-    self.assertTrue(browsers)
-    for browser in browsers:
-      self.assertEqual('ios-chrome', browser.browser_type)
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/misc_web_contents_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/misc_web_contents_backend.py
deleted file mode 100644
index c2babbd..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/misc_web_contents_backend.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import exceptions
-from telemetry.internal.backends.chrome import oobe
-from telemetry.internal.backends.chrome_inspector import inspector_backend_list
-
-
-class MiscWebContentsBackend(inspector_backend_list.InspectorBackendList):
-  """A dynamic sequence of web contents not related to tabs and extensions.
-
-  Provides acccess to chrome://oobe/login page.
-  """
-
-  def __init__(self, browser_backend):
-    super(MiscWebContentsBackend, self).__init__(browser_backend)
-
-  @property
-  def oobe_exists(self):
-    """Lightweight property to determine if the oobe webui is visible."""
-    try:
-      return bool(len(self))
-    except exceptions.Error:
-      return False
-
-  def GetOobe(self):
-    if not len(self):
-      return None
-    return self[0]
-
-  def ShouldIncludeContext(self, context):
-    return context.get('url').startswith('chrome://oobe')
-
-  def CreateWrapper(self, inspector_backend):
-    return oobe.Oobe(inspector_backend)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/oobe.py b/catapult/telemetry/telemetry/internal/backends/chrome/oobe.py
deleted file mode 100644
index fff4278..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/oobe.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from functools import partial
-import logging
-
-from telemetry.core import exceptions
-from telemetry.internal.browser import web_contents
-
-import py_utils
-
-
-class Oobe(web_contents.WebContents):
-  def __init__(self, inspector_backend):
-    super(Oobe, self).__init__(inspector_backend)
-
-  def _GaiaIFrameContext(self):
-    max_context_id = self.EnableAllContexts()
-    logging.debug('%d contexts in Gaia page' % max_context_id)
-    for gaia_iframe_context in range(max_context_id + 1):
-      try:
-        if self.EvaluateJavaScript(
-            "document.readyState == 'complete' && "
-            "document.getElementById('Email') != null",
-            context_id=gaia_iframe_context):
-          return gaia_iframe_context
-      except exceptions.EvaluateException:
-        pass
-    return None
-
-  def _GaiaWebviewContext(self):
-    webview_contexts = self.GetWebviewContexts()
-    if webview_contexts:
-      return webview_contexts[0]
-    return None
-
-  def _ExecuteOobeApi(self, api, *args):
-    logging.info('Invoking %s' % api)
-    self.WaitForJavaScriptCondition("typeof Oobe == 'function'", timeout=120)
-
-    if self.EvaluateJavaScript(
-        "typeof {{ @api }} == 'undefined'", api=api):
-      raise exceptions.LoginException('%s js api missing' % api)
-
-    # Example values:
-    #   |api|:    'doLogin'
-    #   |args|:   ['username', 'pass', True]
-    #   Executes: 'doLogin("username", "pass", true)'
-    self.ExecuteJavaScript('{{ @f }}({{ *args }})', f=api, args=args)
-
-  def NavigateGuestLogin(self):
-    """Logs in as guest."""
-    self._ExecuteOobeApi('Oobe.guestLoginForTesting')
-
-  def NavigateFakeLogin(self, username, password, gaia_id,
-                        enterprise_enroll=False):
-    """Fake user login."""
-    self._ExecuteOobeApi('Oobe.loginForTesting', username, password, gaia_id,
-                         enterprise_enroll)
-
-  def NavigateGaiaLogin(self, username, password,
-                        enterprise_enroll=False,
-                        for_user_triggered_enrollment=False):
-    """Logs in using the GAIA webview or IFrame, whichever is
-    present. |enterprise_enroll| allows for enterprise enrollment.
-    |for_user_triggered_enrollment| should be False for remora enrollment."""
-    self._ExecuteOobeApi('Oobe.skipToLoginForTesting')
-    if for_user_triggered_enrollment:
-      self._ExecuteOobeApi('Oobe.switchToEnterpriseEnrollmentForTesting')
-
-    self._NavigateGaiaLogin(username, password, enterprise_enroll)
-
-    if enterprise_enroll:
-      self.WaitForJavaScriptCondition(
-          'Oobe.isEnrollmentSuccessfulForTest()', timeout=30)
-      self._ExecuteOobeApi('Oobe.enterpriseEnrollmentDone')
-
-  def _NavigateGaiaLogin(self, username, password, enterprise_enroll):
-    """Invokes NavigateIFrameLogin or NavigateWebViewLogin as appropriate."""
-    def _GetGaiaFunction():
-      if self._GaiaWebviewContext() is not None:
-        return partial(Oobe._NavigateWebViewLogin,
-                       wait_for_close=not enterprise_enroll)
-      elif self._GaiaIFrameContext() is not None:
-        return partial(Oobe._NavigateIFrameLogin,
-                       add_user_for_testing=not enterprise_enroll)
-      return None
-    py_utils.WaitFor(_GetGaiaFunction, 20)(self, username, password)
-
-  def _NavigateIFrameLogin(self, username, password, add_user_for_testing):
-    """Logs into the IFrame-based GAIA screen"""
-    gaia_iframe_context = py_utils.WaitFor(self._GaiaIFrameContext, timeout=30)
-
-    if add_user_for_testing:
-      self._ExecuteOobeApi('Oobe.showAddUserForTesting')
-    self.ExecuteJavaScript("""
-        document.getElementById('Email').value= {{ username }};
-        document.getElementById('Passwd').value= {{ password }};
-        document.getElementById('signIn').click();""",
-        username=username, password=password,
-        context_id=gaia_iframe_context)
-
-  def _NavigateWebViewLogin(self, username, password, wait_for_close):
-    """Logs into the webview-based GAIA screen"""
-    self._NavigateWebViewEntry('identifierId', username, 'identifierNext')
-    self._NavigateWebViewEntry('password', password, 'passwordNext')
-    if wait_for_close:
-      py_utils.WaitFor(lambda: not self._GaiaWebviewContext(), 60)
-
-  def _NavigateWebViewEntry(self, field, value, next_field):
-    self._WaitForField(field)
-    self._WaitForField(next_field)
-    gaia_webview_context = self._GaiaWebviewContext()
-    gaia_webview_context.EvaluateJavaScript("""
-       document.getElementById({{ field }}).value= {{ value }};
-       document.getElementById({{ next_field }}).click()""",
-       field=field, value=value, next_field=next_field)
-
-  def _WaitForField(self, field):
-    gaia_webview_context = py_utils.WaitFor(self._GaiaWebviewContext, 5)
-    py_utils.WaitFor(gaia_webview_context.HasReachedQuiescence, 20)
-    gaia_webview_context.WaitForJavaScriptCondition(
-        "document.getElementById({{ field }}) != null",
-        field=field, timeout=20)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/system_info_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/system_info_backend.py
deleted file mode 100644
index 4f71633..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/system_info_backend.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.platform import system_info
-from telemetry.internal.util import camel_case
-
-
-class SystemInfoBackend(object):
-  def __init__(self, devtools_port, devtools_page=None):
-    self._port = devtools_port
-    self._page = devtools_page
-
-  def GetSystemInfo(self, timeout=10):
-    req = {'method': 'SystemInfo.getInfo'}
-    websocket = inspector_websocket.InspectorWebsocket()
-    try:
-      if self._page:
-        websocket.Connect('ws://127.0.0.1:%i/devtools/page/%i' %
-                          (self._port, self._page), timeout)
-      else:
-        websocket.Connect('ws://127.0.0.1:%i/devtools/browser' % self._port,
-                          timeout)
-      res = websocket.SyncRequest(req, timeout)
-    finally:
-      websocket.Disconnect()
-    if 'error' in res:
-      return None
-    return system_info.SystemInfo.FromDict(
-        camel_case.ToUnderscore(res['result']))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/tab_list_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome/tab_list_backend.py
deleted file mode 100644
index 36e38e3..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/tab_list_backend.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-
-from telemetry.core import exceptions
-from telemetry.internal.backends.chrome_inspector import inspector_backend_list
-from telemetry.internal.browser import tab
-
-import py_utils
-
-
-class TabUnexpectedResponseException(exceptions.DevtoolsTargetCrashException):
-  pass
-
-
-class TabListBackend(inspector_backend_list.InspectorBackendList):
-  """A dynamic sequence of tab.Tabs in UI order."""
-
-  def __init__(self, browser_backend):
-    super(TabListBackend, self).__init__(browser_backend)
-
-  def New(self, timeout):
-    """Makes a new tab.
-
-    Returns:
-      A Tab object.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    if not self._browser_backend.supports_tab_control:
-      raise NotImplementedError("Browser doesn't support tab control.")
-    response = self._browser_backend.devtools_client.RequestNewTab(timeout)
-    try:
-      response = json.loads(response)
-      context_id = response['id']
-    except (KeyError, ValueError):
-      raise TabUnexpectedResponseException(
-          app=self._browser_backend.browser,
-          msg='Received response: %s' % response)
-    return self.GetBackendFromContextId(context_id)
-
-  def CloseTab(self, tab_id, timeout=300):
-    """Closes the tab with the given debugger_url.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-      devtools_client_backend.TabNotFoundError
-      TabUnexpectedResponseException
-      py_utils.TimeoutException
-    """
-    assert self._browser_backend.supports_tab_control
-    # TODO(dtu): crbug.com/160946, allow closing the last tab on some platforms.
-    # For now, just create a new tab before closing the last tab.
-    if len(self) <= 1:
-      self.New(timeout)
-
-    response = self._browser_backend.devtools_client.CloseTab(tab_id, timeout)
-
-    if response != 'Target is closing':
-      raise TabUnexpectedResponseException(
-          app=self._browser_backend.browser,
-          msg='Received response: %s' % response)
-
-    py_utils.WaitFor(lambda: tab_id not in self.IterContextIds(), timeout=5)
-
-  def ActivateTab(self, tab_id, timeout=30):
-    """Activates the tab with the given debugger_url.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-      devtools_client_backend.TabNotFoundError
-      TabUnexpectedResponseException
-    """
-    assert self._browser_backend.supports_tab_control
-
-    response = self._browser_backend.devtools_client.ActivateTab(tab_id,
-                                                                 timeout)
-
-    if response != 'Target activated':
-      raise TabUnexpectedResponseException(
-          app=self._browser_backend.browser,
-          msg='Received response: %s' % response)
-
-  def Get(self, index, ret):
-    """Returns self[index] if it exists, or ret if index is out of bounds."""
-    if len(self) <= index:
-      return ret
-    return self[index]
-
-  def ShouldIncludeContext(self, context):
-    if 'type' in context:
-      return (context['type'] == 'page' or
-              context['url'] == 'chrome://media-router/')
-    # TODO: For compatibility with Chrome before r177683.
-    # This check is not completely correct, see crbug.com/190592.
-    return not context['url'].startswith('chrome-extension://')
-
-  def CreateWrapper(self, inspector_backend):
-    return tab.Tab(inspector_backend, self, self._browser_backend.browser)
-
-  def _HandleDevToolsConnectionError(self, error):
-    if not self._browser_backend.IsAppRunning():
-      error.AddDebuggingMessage('The browser is not running. It probably '
-                                'crashed.')
-    elif not self._browser_backend.HasBrowserFinishedLaunching():
-      error.AddDebuggingMessage('The browser exists but cannot be reached.')
-    else:
-      error.AddDebuggingMessage('The browser exists and can be reached. '
-                                'The devtools target probably crashed.')
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome/tab_list_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome/tab_list_backend_unittest.py
deleted file mode 100644
index 47e3451..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome/tab_list_backend_unittest.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.testing import tab_test_case
-
-
-class TabListBackendTest(tab_test_case.TabTestCase):
-  @decorators.Enabled('has tabs')
-  def testNewTab(self):
-    tabs = set(tab.id for tab in self.tabs)
-    for _ in xrange(10):
-      new_tab_id = self.tabs.New().id
-      self.assertNotIn(new_tab_id, tabs)
-      tabs.add(new_tab_id)
-      new_tabs = set(tab.id for tab in self.tabs)
-      self.assertEqual(tabs, new_tabs)
-
-  @decorators.Enabled('has tabs')
-  def testTabIdMatchesContextId(self):
-    # Ensure that there are two tabs.
-    while len(self.tabs) < 2:
-      self.tabs.New()
-
-    # Check that the tab.id matches context_id.
-    tabs = []
-    for context_id in self.tabs._tab_list_backend.IterContextIds():
-      tab = self.tabs.GetTabById(context_id)
-      self.assertEquals(tab.id, context_id)
-      tabs.append(self.tabs.GetTabById(context_id))
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Enabled('has tabs')
-  @decorators.Disabled('android')
-  def testTabIdStableAfterTabCrash(self):
-    # Ensure that there are two tabs.
-    while len(self.tabs) < 2:
-      self.tabs.New()
-
-    tabs = [t for t in self.tabs]
-
-    # Crash the first tab.
-    self.assertRaises(exceptions.DevtoolsTargetCrashException,
-        lambda: tabs[0].Navigate('chrome://crash'))
-
-    # Fetching the second tab by id should still work. Fetching the first tab
-    # should raise an exception.
-    self.assertEquals(tabs[1], self.tabs.GetTabById(tabs[1].id))
-    self.assertRaises(KeyError, lambda: self.tabs.GetTabById(tabs[0].id))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/__init__.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/__init__.py
deleted file mode 100644
index 83c375c..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""This package contains classes and methods for controlling the chrome
-devtool.
-"""
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_client_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_client_backend.py
deleted file mode 100644
index a10ceb5..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_client_backend.py
+++ /dev/null
@@ -1,491 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import re
-import socket
-import sys
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.backends import browser_backend
-from telemetry.internal.backends.chrome_inspector import devtools_http
-from telemetry.internal.backends.chrome_inspector import inspector_backend
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.backends.chrome_inspector import memory_backend
-from telemetry.internal.backends.chrome_inspector import tracing_backend
-from telemetry.internal.backends.chrome_inspector import websocket
-from telemetry.internal.platform.tracing_agent import chrome_tracing_agent
-from telemetry.internal.platform.tracing_agent import (
-    chrome_tracing_devtools_manager)
-from tracing.trace_data import trace_data as trace_data_module
-
-
-BROWSER_INSPECTOR_WEBSOCKET_URL = 'ws://127.0.0.1:%i/devtools/browser'
-
-
-class TabNotFoundError(exceptions.Error):
-  pass
-
-
-def IsDevToolsAgentAvailable(port, app_backend):
-  """Returns True if a DevTools agent is available on the given port."""
-  if (isinstance(app_backend, browser_backend.BrowserBackend) and
-      app_backend.supports_tracing):
-    inspector_websocket_instance = inspector_websocket.InspectorWebsocket()
-    try:
-      if not _IsInspectorWebsocketAvailable(inspector_websocket_instance, port):
-        return False
-    finally:
-      inspector_websocket_instance.Disconnect()
-
-  devtools_http_instance = devtools_http.DevToolsHttp(port)
-  try:
-    return _IsDevToolsAgentAvailable(devtools_http_instance)
-  finally:
-    devtools_http_instance.Disconnect()
-
-
-def _IsInspectorWebsocketAvailable(inspector_websocket_instance, port):
-  try:
-    inspector_websocket_instance.Connect(
-        BROWSER_INSPECTOR_WEBSOCKET_URL % port, timeout=10)
-  except websocket.WebSocketException:
-    return False
-  except socket.error:
-    return False
-  except Exception as e:
-    sys.stderr.write('Unidentified exception while checking if wesocket is'
-                     'available on port %i. Exception message: %s\n' %
-                     (port, e.message))
-    return False
-  else:
-    return True
-
-
-# TODO(nednguyen): Find a more reliable way to check whether the devtool agent
-# is still alive.
-def _IsDevToolsAgentAvailable(devtools_http_instance):
-  try:
-    devtools_http_instance.Request('')
-  except devtools_http.DevToolsClientConnectionError:
-    return False
-  else:
-    return True
-
-
-class DevToolsClientBackend(object):
-  """An object that communicates with Chrome's devtools.
-
-  This class owns a map of InspectorBackends. It is responsible for creating
-  them and destroying them.
-  """
-  def __init__(self, devtools_port, remote_devtools_port, app_backend):
-    """Creates a new DevToolsClientBackend.
-
-    A DevTools agent must exist on the given devtools_port.
-
-    Args:
-      devtools_port: The port to use to connect to DevTools agent.
-      remote_devtools_port: In some cases (e.g., app running on
-          Android device, devtools_port is the forwarded port on the
-          host platform. We also need to know the remote_devtools_port
-          so that we can uniquely identify the DevTools agent.
-      app_backend: For the app that contains the DevTools agent.
-    """
-    self._devtools_port = devtools_port
-    self._remote_devtools_port = remote_devtools_port
-    self._devtools_http = devtools_http.DevToolsHttp(devtools_port)
-    self._browser_inspector_websocket = None
-    self._tracing_backend = None
-    self._memory_backend = None
-    self._app_backend = app_backend
-    self._devtools_context_map_backend = _DevToolsContextMapBackend(
-        self._app_backend, self)
-
-    self._tab_ids = None
-
-    if not self.supports_tracing:
-      return
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        self, self._app_backend.platform_backend)
-
-    # Telemetry has started Chrome tracing if there is trace config, so start
-    # tracing on this newly created devtools client if needed.
-    trace_config = (self._app_backend.platform_backend
-                    .tracing_controller_backend.GetChromeTraceConfig())
-    if not trace_config:
-      self._CreateTracingBackendIfNeeded(is_tracing_running=False)
-      return
-
-    if self.support_startup_tracing:
-      self._CreateTracingBackendIfNeeded(is_tracing_running=True)
-      return
-
-    self._CreateTracingBackendIfNeeded(is_tracing_running=False)
-    self.StartChromeTracing(trace_config)
-
-  @property
-  def remote_port(self):
-    return self._remote_devtools_port
-
-  @property
-  def supports_tracing(self):
-    if not isinstance(self._app_backend, browser_backend.BrowserBackend):
-      return False
-    return self._app_backend.supports_tracing
-
-  @property
-  def supports_overriding_memory_pressure_notifications(self):
-    if not isinstance(self._app_backend, browser_backend.BrowserBackend):
-      return False
-    return self._app_backend.supports_overriding_memory_pressure_notifications
-
-
-  @property
-  def is_tracing_running(self):
-    if not self.supports_tracing:
-      return False
-    if not self._tracing_backend:
-      return False
-    return self._tracing_backend.is_tracing_running
-
-  @property
-  def support_startup_tracing(self):
-    # Startup tracing with --trace-config-file flag was not supported until
-    # Chromium branch number 2512 (see crrev.com/1309243004 and
-    # crrev.com/1353583002).
-    if not chrome_tracing_agent.ChromeTracingAgent.IsStartupTracingSupported(
-        self._app_backend.platform_backend):
-      return False
-    # TODO(zhenw): Remove this once stable Chrome and reference browser have
-    # passed 2512.
-    return self.GetChromeBranchNumber() >= 2512
-
-  @property
-  def support_modern_devtools_tracing_start_api(self):
-    # Modern DevTools Tracing.start API (via 'traceConfig' parameter) was not
-    # supported until Chromium branch number 2683 (see crrev.com/1808353002).
-    # TODO(petrcermak): Remove this once stable Chrome and reference browser
-    # have passed 2683.
-    return self.GetChromeBranchNumber() >= 2683
-
-  def IsAlive(self):
-    """Whether the DevTools server is available and connectable."""
-    return (self._devtools_http and
-        _IsDevToolsAgentAvailable(self._devtools_http))
-
-  def Close(self):
-    if self._tracing_backend:
-      self._tracing_backend.Close()
-      self._tracing_backend = None
-    if self._memory_backend:
-      self._memory_backend.Close()
-      self._memory_backend = None
-
-    if self._devtools_context_map_backend:
-      self._devtools_context_map_backend.Clear()
-
-    # Close the browser inspector socket last (in case the backend needs to
-    # interact with it before closing).
-    if self._browser_inspector_websocket:
-      self._browser_inspector_websocket.Disconnect()
-      self._browser_inspector_websocket = None
-
-    assert self._devtools_http
-    self._devtools_http.Disconnect()
-    self._devtools_http = None
-
-
-  @decorators.Cache
-  def GetChromeBranchNumber(self):
-    # Detect version information.
-    resp = self._devtools_http.RequestJson('version')
-    if 'Protocol-Version' in resp:
-      if 'Browser' in resp:
-        branch_number_match = re.search(r'Chrome/\d+\.\d+\.(\d+)\.\d+',
-                                        resp['Browser'])
-      else:
-        branch_number_match = re.search(
-            r'Chrome/\d+\.\d+\.(\d+)\.\d+ (Mobile )?Safari',
-            resp['User-Agent'])
-
-      if branch_number_match:
-        branch_number = int(branch_number_match.group(1))
-        if branch_number:
-          return branch_number
-
-    # Branch number can't be determined, so fail any branch number checks.
-    return 0
-
-  def _ListInspectableContexts(self):
-    return self._devtools_http.RequestJson('')
-
-  def RequestNewTab(self, timeout):
-    """Creates a new tab.
-
-    Returns:
-      A JSON string as returned by DevTools. Example:
-      {
-        "description": "",
-        "devtoolsFrontendUrl":
-            "/devtools/inspector.html?ws=host:port/devtools/page/id-string",
-        "id": "id-string",
-        "title": "Page Title",
-        "type": "page",
-        "url": "url",
-        "webSocketDebuggerUrl": "ws://host:port/devtools/page/id-string"
-      }
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    return self._devtools_http.Request('new', timeout=timeout)
-
-  def CloseTab(self, tab_id, timeout):
-    """Closes the tab with the given id.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-      TabNotFoundError
-    """
-    try:
-      return self._devtools_http.Request('close/%s' % tab_id,
-                                         timeout=timeout)
-    except devtools_http.DevToolsClientUrlError:
-      error = TabNotFoundError(
-          'Unable to close tab, tab id not found: %s' % tab_id)
-      raise error, None, sys.exc_info()[2]
-
-  def ActivateTab(self, tab_id, timeout):
-    """Activates the tab with the given id.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-      TabNotFoundError
-    """
-    try:
-      return self._devtools_http.Request('activate/%s' % tab_id,
-                                         timeout=timeout)
-    except devtools_http.DevToolsClientUrlError:
-      error = TabNotFoundError(
-          'Unable to activate tab, tab id not found: %s' % tab_id)
-      raise error, None, sys.exc_info()[2]
-
-  def GetUrl(self, tab_id):
-    """Returns the URL of the tab with |tab_id|, as reported by devtools.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    for c in self._ListInspectableContexts():
-      if c['id'] == tab_id:
-        return c['url']
-    return None
-
-  def IsInspectable(self, tab_id):
-    """Whether the tab with |tab_id| is inspectable, as reported by devtools.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    contexts = self._ListInspectableContexts()
-    return tab_id in [c['id'] for c in contexts]
-
-  def GetUpdatedInspectableContexts(self):
-    """Returns an updated instance of _DevToolsContextMapBackend."""
-    contexts = self._ListInspectableContexts()
-    self._devtools_context_map_backend._Update(contexts)
-    return self._devtools_context_map_backend
-
-  def _CreateTracingBackendIfNeeded(self, is_tracing_running=False):
-    assert self.supports_tracing
-    if not self._tracing_backend:
-      self._CreateAndConnectBrowserInspectorWebsocketIfNeeded()
-      self._tracing_backend = tracing_backend.TracingBackend(
-          self._browser_inspector_websocket, is_tracing_running,
-          self.support_modern_devtools_tracing_start_api)
-
-  def _CreateMemoryBackendIfNeeded(self):
-    assert self.supports_overriding_memory_pressure_notifications
-    if not self._memory_backend:
-      self._CreateAndConnectBrowserInspectorWebsocketIfNeeded()
-      self._memory_backend = memory_backend.MemoryBackend(
-          self._browser_inspector_websocket)
-
-  def _CreateAndConnectBrowserInspectorWebsocketIfNeeded(self):
-    if not self._browser_inspector_websocket:
-      self._browser_inspector_websocket = (
-          inspector_websocket.InspectorWebsocket())
-      self._browser_inspector_websocket.Connect(
-          BROWSER_INSPECTOR_WEBSOCKET_URL % self._devtools_port, timeout=10)
-
-  def IsChromeTracingSupported(self):
-    if not self.supports_tracing:
-      return False
-    self._CreateTracingBackendIfNeeded()
-    return self._tracing_backend.IsTracingSupported()
-
-  def StartChromeTracing(self, trace_config, timeout=10):
-    """
-    Args:
-        trace_config: An tracing_config.TracingConfig instance.
-    """
-    assert trace_config and trace_config.enable_chrome_trace
-    self._CreateTracingBackendIfNeeded()
-    return self._tracing_backend.StartTracing(
-        trace_config.chrome_trace_config, timeout)
-
-  def RecordChromeClockSyncMarker(self, sync_id):
-    assert self.is_tracing_running, 'Tracing must be running to clock sync.'
-    self._tracing_backend.RecordClockSyncMarker(sync_id)
-
-  def StopChromeTracing(self):
-    assert self.is_tracing_running
-    self._tab_ids = []
-    try:
-      context_map = self.GetUpdatedInspectableContexts()
-      for context in context_map.contexts:
-        if context['type'] not in ['iframe', 'page', 'webview']:
-          continue
-        context_id = context['id']
-        backend = context_map.GetInspectorBackend(context_id)
-        backend.EvaluateJavaScript("""
-            console.time({{ backend_id }});
-            console.timeEnd({{ backend_id }});
-            console.time.toString().indexOf('[native code]') != -1;
-            """,
-            backend_id=backend.id)
-        self._tab_ids.append(backend.id)
-    finally:
-      self._tracing_backend.StopTracing()
-
-  def CollectChromeTracingData(self, trace_data_builder, timeout=60):
-    try:
-      trace_data_builder.AddTraceFor(
-          trace_data_module.TAB_ID_PART, self._tab_ids[:])
-      self._tab_ids = None
-    finally:
-      self._tracing_backend.CollectTraceData(trace_data_builder, timeout)
-
-  def DumpMemory(self, timeout=30):
-    """Dumps memory.
-
-    Returns:
-      GUID of the generated dump if successful, None otherwise.
-
-    Raises:
-      TracingTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      TracingUnrecoverableException: If there is a websocket error.
-      TracingUnexpectedResponseException: If the response contains an error
-      or does not contain the expected result.
-    """
-    self._CreateTracingBackendIfNeeded()
-    return self._tracing_backend.DumpMemory(timeout)
-
-  def SetMemoryPressureNotificationsSuppressed(self, suppressed, timeout=30):
-    """Enable/disable suppressing memory pressure notifications.
-
-    Args:
-      suppressed: If true, memory pressure notifications will be suppressed.
-      timeout: The timeout in seconds.
-
-    Raises:
-      MemoryTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      MemoryUnrecoverableException: If there is a websocket error.
-      MemoryUnexpectedResponseException: If the response contains an error
-      or does not contain the expected result.
-    """
-    self._CreateMemoryBackendIfNeeded()
-    return self._memory_backend.SetMemoryPressureNotificationsSuppressed(
-        suppressed, timeout)
-
-  def SimulateMemoryPressureNotification(self, pressure_level, timeout=30):
-    """Simulate a memory pressure notification.
-
-    Args:
-      pressure level: The memory pressure level of the notification ('moderate'
-      or 'critical').
-      timeout: The timeout in seconds.
-
-    Raises:
-      MemoryTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      MemoryUnrecoverableException: If there is a websocket error.
-      MemoryUnexpectedResponseException: If the response contains an error
-      or does not contain the expected result.
-    """
-    self._CreateMemoryBackendIfNeeded()
-    return self._memory_backend.SimulateMemoryPressureNotification(
-        pressure_level, timeout)
-
-
-class _DevToolsContextMapBackend(object):
-  def __init__(self, app_backend, devtools_client):
-    self._app_backend = app_backend
-    self._devtools_client = devtools_client
-    self._contexts = None
-    self._inspector_backends_dict = {}
-
-  @property
-  def contexts(self):
-    """The most up to date contexts data.
-
-    Returned in the order returned by devtools agent."""
-    return self._contexts
-
-  def GetContextInfo(self, context_id):
-    for context in self._contexts:
-      if context['id'] == context_id:
-        return context
-    raise KeyError('Cannot find a context with id=%s' % context_id)
-
-  def GetInspectorBackend(self, context_id):
-    """Gets an InspectorBackend instance for the given context_id.
-
-    This lazily creates InspectorBackend for the context_id if it does
-    not exist yet. Otherwise, it will return the cached instance."""
-    if context_id in self._inspector_backends_dict:
-      return self._inspector_backends_dict[context_id]
-
-    for context in self._contexts:
-      if context['id'] == context_id:
-        new_backend = inspector_backend.InspectorBackend(
-            self._app_backend.app, self._devtools_client, context)
-        self._inspector_backends_dict[context_id] = new_backend
-        return new_backend
-
-    raise KeyError('Cannot find a context with id=%s' % context_id)
-
-  def _Update(self, contexts):
-    # Remove InspectorBackend that is not in the current inspectable
-    # contexts list.
-    context_ids = [context['id'] for context in contexts]
-    for context_id in self._inspector_backends_dict.keys():
-      if context_id not in context_ids:
-        backend = self._inspector_backends_dict[context_id]
-        backend.Disconnect()
-        del self._inspector_backends_dict[context_id]
-
-    valid_contexts = []
-    for context in contexts:
-      # If the context does not have webSocketDebuggerUrl, skip it.
-      # If an InspectorBackend is already created for the tab,
-      # webSocketDebuggerUrl will be missing, and this is expected.
-      context_id = context['id']
-      if context_id not in self._inspector_backends_dict:
-        if 'webSocketDebuggerUrl' not in context:
-          logging.debug('webSocketDebuggerUrl missing, removing %s'
-                        % context_id)
-          continue
-      valid_contexts.append(context)
-    self._contexts = valid_contexts
-
-  def Clear(self):
-    for backend in self._inspector_backends_dict.values():
-      backend.Disconnect()
-    self._inspector_backends_dict = {}
-    self._contexts = None
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_client_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_client_backend_unittest.py
deleted file mode 100644
index 085956a..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_client_backend_unittest.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.testing import browser_test_case
-from telemetry.timeline import model
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data
-
-
-class DevToolsClientBackendTest(browser_test_case.BrowserTestCase):
-  @property
-  def _browser_backend(self):
-    return self._browser._browser_backend
-
-  @property
-  def _devtools_client(self):
-    return self._browser_backend.devtools_client
-
-  def testGetChromeBranchNumber(self):
-    branch_num = self._devtools_client.GetChromeBranchNumber()
-    self.assertIsInstance(branch_num, int)
-    self.assertGreater(branch_num, 0)
-
-  def testIsAlive(self):
-    self.assertTrue(self._devtools_client.IsAlive())
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  # crbug.com/483212 (CrOS)
-  @decorators.Enabled('has tabs')
-  @decorators.Disabled('android', 'chromeos')
-  def testGetUpdatedInspectableContexts(self):
-    self._browser.tabs.New()
-    c1 = self._devtools_client.GetUpdatedInspectableContexts()
-    self.assertEqual(len(c1.contexts), 2)
-    backends1 = [c1.GetInspectorBackend(c['id']) for c in c1.contexts]
-    tabs1 = list(self._browser.tabs)
-
-    c2 = self._devtools_client.GetUpdatedInspectableContexts()
-    self.assertEqual(len(c2.contexts), 2)
-    backends2 = [c2.GetInspectorBackend(c['id']) for c in c2.contexts]
-    tabs2 = list(self._browser.tabs)
-    self.assertEqual(backends2, backends1)
-    self.assertEqual(tabs2, tabs1)
-
-    self._browser.tabs.New()
-    c3 = self._devtools_client.GetUpdatedInspectableContexts()
-    self.assertEqual(len(c3.contexts), 3)
-    backends3 = [c3.GetInspectorBackend(c['id']) for c in c3.contexts]
-    tabs3 = list(self._browser.tabs)
-    self.assertEqual(backends3[1], backends1[0])
-    self.assertEqual(backends3[2], backends1[1])
-    self.assertEqual(tabs3[0], tabs1[0])
-    self.assertEqual(tabs3[1], tabs1[1])
-
-    self._browser.tabs[1].Close()
-    c4 = self._devtools_client.GetUpdatedInspectableContexts()
-    self.assertEqual(len(c4.contexts), 2)
-    backends4 = [c4.GetInspectorBackend(c['id']) for c in c4.contexts]
-    tabs4 = list(self._browser.tabs)
-    self.assertEqual(backends4[0], backends3[0])
-    self.assertEqual(backends4[1], backends3[1])
-    self.assertEqual(tabs4[0], tabs3[0])
-    self.assertEqual(tabs4[1], tabs3[2])
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  # crbug.com/483212 (CrOS)
-  @decorators.Disabled('android', 'chromeos')
-  def testGetUpdatedInspectableContextsUpdateContextsData(self):
-    c1 = self._devtools_client.GetUpdatedInspectableContexts()
-    self.assertEqual(len(c1.contexts), 1)
-    self.assertEqual(c1.contexts[0]['url'], 'about:blank')
-
-    context_id = c1.contexts[0]['id']
-    backend = c1.GetInspectorBackend(context_id)
-    backend.Navigate(self.UrlOfUnittestFile('blank.html'), None, 10)
-    c2 = self._devtools_client.GetUpdatedInspectableContexts()
-    self.assertEqual(len(c2.contexts), 1)
-    self.assertTrue('blank.html' in c2.contexts[0]['url'])
-    self.assertEqual(c2.GetInspectorBackend(context_id), backend)
-
-  def testTracing(self):
-    devtools_client = self._devtools_client
-    if not devtools_client.IsChromeTracingSupported():
-      self.skipTest('Browser does not support tracing, skipping test.')
-
-    # Start Chrome tracing.
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    devtools_client.StartChromeTracing(config)
-
-    # Stop Chrome tracing and check that the resulting data is valid.
-    builder = trace_data.TraceDataBuilder()
-    devtools_client.StopChromeTracing()
-    devtools_client.CollectChromeTracingData(builder)
-    model.TimelineModel(builder.AsData())
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_http.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_http.py
deleted file mode 100644
index fecd768..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_http.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import errno
-import httplib
-import json
-import socket
-import sys
-
-from telemetry.core import exceptions
-
-
-class DevToolsClientConnectionError(exceptions.Error):
-  pass
-
-
-class DevToolsClientUrlError(DevToolsClientConnectionError):
-  pass
-
-
-class DevToolsHttp(object):
-  """A helper class to send and parse DevTools HTTP requests.
-
-  This class maintains a persistent http connection to Chrome devtools.
-  Ideally, owners of instances of this class should call Disconnect() before
-  disposing of the instance. Otherwise, the connection will not be closed until
-  the instance is garbage collected.
-  """
-
-  def __init__(self, devtools_port):
-    self._devtools_port = devtools_port
-    self._conn = None
-
-  def __del__(self):
-    self.Disconnect()
-
-  def _Connect(self, timeout):
-    """Attempts to establish a connection to Chrome devtools."""
-    assert not self._conn
-    try:
-      host_port = '127.0.0.1:%i' % self._devtools_port
-      self._conn = httplib.HTTPConnection(host_port, timeout=timeout)
-    except (socket.error, httplib.HTTPException) as e:
-      raise DevToolsClientConnectionError, (e,), sys.exc_info()[2]
-
-  def Disconnect(self):
-    """Closes the HTTP connection."""
-    if not self._conn:
-      return
-
-    try:
-      self._conn.close()
-    except (socket.error, httplib.HTTPException) as e:
-      raise DevToolsClientConnectionError, (e,), sys.exc_info()[2]
-    finally:
-      self._conn = None
-
-  def Request(self, path, timeout=30):
-    """Sends a request to Chrome devtools.
-
-    This method lazily creates an HTTP connection, if one does not already
-    exist.
-
-    Args:
-      path: The DevTools URL path, without the /json/ prefix.
-      timeout: Timeout defaults to 30 seconds.
-
-    Raises:
-      DevToolsClientConnectionError: If the connection fails.
-    """
-    assert timeout
-
-    if not self._conn:
-      self._Connect(timeout)
-
-    endpoint = '/json'
-    if path:
-      endpoint += '/' + path
-    if self._conn.sock:
-      self._conn.sock.settimeout(timeout)
-    else:
-      self._conn.timeout = timeout
-
-    try:
-      # By default, httplib avoids going through the default system proxy.
-      self._conn.request('GET', endpoint)
-      response = self._conn.getresponse()
-      return response.read()
-    except (socket.error, httplib.HTTPException) as e:
-      self.Disconnect()
-      if isinstance(e, socket.error) and e.errno == errno.ECONNREFUSED:
-        raise DevToolsClientUrlError, (e,), sys.exc_info()[2]
-      raise DevToolsClientConnectionError, (e,), sys.exc_info()[2]
-
-  def RequestJson(self, path, timeout=30):
-    """Sends a request and parse the response as JSON.
-
-    Args:
-      path: The DevTools URL path, without the /json/ prefix.
-      timeout: Timeout defaults to 30 seconds.
-
-    Raises:
-      DevToolsClientConnectionError: If the connection fails.
-      ValueError: If the response is not a valid JSON.
-    """
-    return json.loads(self.Request(path, timeout))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_http_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_http_unittest.py
deleted file mode 100644
index ff397ff..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/devtools_http_unittest.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.backends.chrome_inspector import devtools_http
-
-
-class DevToolsHttpTest(unittest.TestCase):
-
-  def testUrlError(self):
-    with self.assertRaises(devtools_http.DevToolsClientUrlError):
-      devtools_http.DevToolsHttp(1000).Request('')
-
-  def testSocketError(self):
-    with self.assertRaises(devtools_http.DevToolsClientConnectionError) as e:
-      devtools_http.DevToolsHttp(1000).Request('')
-      self.assertnotisinstance(e, devtools_http.devtoolsclienturlerror)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_backend.py
deleted file mode 100644
index 821163d..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_backend.py
+++ /dev/null
@@ -1,508 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import functools
-import logging
-import os
-import socket
-import sys
-
-from py_trace_event import trace_event
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.backends.chrome_inspector import devtools_http
-from telemetry.internal.backends.chrome_inspector import inspector_console
-from telemetry.internal.backends.chrome_inspector import inspector_memory
-from telemetry.internal.backends.chrome_inspector import inspector_page
-from telemetry.internal.backends.chrome_inspector import inspector_runtime
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.backends.chrome_inspector import websocket
-from telemetry.util import js_template
-
-import py_utils
-
-
-def _HandleInspectorWebSocketExceptions(func):
-  """Decorator for converting inspector_websocket exceptions.
-
-  When an inspector_websocket exception is thrown in the original function,
-  this decorator converts it into a telemetry exception and adds debugging
-  information.
-  """
-  @functools.wraps(func)
-  def inner(inspector_backend, *args, **kwargs):
-    try:
-      return func(inspector_backend, *args, **kwargs)
-    except (socket.error, websocket.WebSocketException,
-            inspector_websocket.WebSocketDisconnected) as e:
-      inspector_backend._ConvertExceptionFromInspectorWebsocket(e)
-
-  return inner
-
-
-class InspectorBackend(object):
-  """Class for communicating with a devtools client.
-
-  The owner of an instance of this class is responsible for calling
-  Disconnect() before disposing of the instance.
-  """
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def __init__(self, app, devtools_client, context, timeout=120):
-    self._websocket = inspector_websocket.InspectorWebsocket()
-    self._websocket.RegisterDomain(
-        'Inspector', self._HandleInspectorDomainNotification)
-
-    self._app = app
-    self._devtools_client = devtools_client
-    # Be careful when using the context object, since the data may be
-    # outdated since this is never updated once InspectorBackend is
-    # created. Consider an updating strategy for this. (For an example
-    # of the subtlety, see the logic for self.url property.)
-    self._context = context
-
-    logging.debug('InspectorBackend._Connect() to %s', self.debugger_url)
-    try:
-      self._websocket.Connect(self.debugger_url, timeout)
-      self._console = inspector_console.InspectorConsole(self._websocket)
-      self._memory = inspector_memory.InspectorMemory(self._websocket)
-      self._page = inspector_page.InspectorPage(
-          self._websocket, timeout=timeout)
-      self._runtime = inspector_runtime.InspectorRuntime(self._websocket)
-    except (websocket.WebSocketException, exceptions.TimeoutException,
-            py_utils.TimeoutException) as e:
-      self._ConvertExceptionFromInspectorWebsocket(e)
-
-  def Disconnect(self):
-    """Disconnects the inspector websocket.
-
-    This method intentionally leaves the self._websocket object around, so that
-    future calls it to it will fail with a relevant error.
-    """
-    if self._websocket:
-      self._websocket.Disconnect()
-
-  def __del__(self):
-    self.Disconnect()
-
-  @property
-  def app(self):
-    return self._app
-
-  @property
-  def url(self):
-    """Returns the URL of the tab, as reported by devtools.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    return self._devtools_client.GetUrl(self.id)
-
-  @property
-  def id(self):
-    return self._context['id']
-
-  @property
-  def debugger_url(self):
-    return self._context['webSocketDebuggerUrl']
-
-  def GetWebviewInspectorBackends(self):
-    """Returns a list of InspectorBackend instances associated with webviews.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    inspector_backends = []
-    devtools_context_map = self._devtools_client.GetUpdatedInspectableContexts()
-    for context in devtools_context_map.contexts:
-      if context['type'] == 'webview':
-        inspector_backends.append(
-            devtools_context_map.GetInspectorBackend(context['id']))
-    return inspector_backends
-
-  def IsInspectable(self):
-    """Whether the tab is inspectable, as reported by devtools."""
-    try:
-      return self._devtools_client.IsInspectable(self.id)
-    except devtools_http.DevToolsClientConnectionError:
-      return False
-
-  # Public methods implemented in JavaScript.
-
-  @property
-  @decorators.Cache
-  def screenshot_supported(self):
-    if (self.app.platform.GetOSName() == 'linux' and (
-        os.getenv('DISPLAY') not in [':0', ':0.0'])):
-      # Displays other than 0 mean we are likely running in something like
-      # xvfb where screenshotting doesn't work.
-      return False
-    return True
-
-  @_HandleInspectorWebSocketExceptions
-  def Screenshot(self, timeout):
-    assert self.screenshot_supported, 'Browser does not support screenshotting'
-    return self._page.CaptureScreenshot(timeout)
-
-  # Memory public methods.
-
-  @_HandleInspectorWebSocketExceptions
-  def GetDOMStats(self, timeout):
-    """Gets memory stats from the DOM.
-
-    Raises:
-      inspector_memory.InspectorMemoryException
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    dom_counters = self._memory.GetDOMCounters(timeout)
-    return {
-      'document_count': dom_counters['documents'],
-      'node_count': dom_counters['nodes'],
-      'event_listener_count': dom_counters['jsEventListeners']
-    }
-
-  # Page public methods.
-
-  @_HandleInspectorWebSocketExceptions
-  def WaitForNavigate(self, timeout):
-    self._page.WaitForNavigate(timeout)
-
-  @_HandleInspectorWebSocketExceptions
-  def Navigate(self, url, script_to_evaluate_on_commit, timeout):
-    self._page.Navigate(url, script_to_evaluate_on_commit, timeout)
-
-  @_HandleInspectorWebSocketExceptions
-  def GetCookieByName(self, name, timeout):
-    return self._page.GetCookieByName(name, timeout)
-
-  # Console public methods.
-
-  @_HandleInspectorWebSocketExceptions
-  def GetCurrentConsoleOutputBuffer(self, timeout=10):
-    return self._console.GetCurrentConsoleOutputBuffer(timeout)
-
-  # Runtime public methods.
-
-  @_HandleInspectorWebSocketExceptions
-  def ExecuteJavaScript(self, statement, **kwargs):
-    """Executes a given JavaScript statement. Does not return the result.
-
-    Example: runner.ExecuteJavaScript('var foo = {{ value }};', value='hi');
-
-    Args:
-      statement: The statement to execute (provided as a string).
-
-    Optional keyword args:
-      timeout: The number of seconds to wait for the statement to execute.
-      context_id: The id of an iframe where to execute the code; the main page
-          has context_id=1, the first iframe context_id=2, etc.
-      Additional keyword arguments provide values to be interpolated within
-          the statement. See telemetry.util.js_template for details.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.EvaluationException
-      exceptions.WebSocketException
-      exceptions.DevtoolsTargetCrashException
-    """
-    # Use the default both when timeout=None or the option is ommited.
-    timeout = kwargs.pop('timeout', None) or 60
-    context_id = kwargs.pop('context_id', None)
-    statement = js_template.Render(statement, **kwargs)
-    self._runtime.Execute(statement, context_id, timeout)
-
-  @_HandleInspectorWebSocketExceptions
-  def EvaluateJavaScript(self, expression, **kwargs):
-    """Returns the result of evaluating a given JavaScript expression.
-
-    Example: runner.ExecuteJavaScript('document.location.href');
-
-    Args:
-      expression: The expression to execute (provided as a string).
-
-    Optional keyword args:
-      timeout: The number of seconds to wait for the expression to evaluate.
-      context_id: The id of an iframe where to execute the code; the main page
-          has context_id=1, the first iframe context_id=2, etc.
-      Additional keyword arguments provide values to be interpolated within
-          the expression. See telemetry.util.js_template for details.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.EvaluationException
-      exceptions.WebSocketException
-      exceptions.DevtoolsTargetCrashException
-    """
-    # Use the default both when timeout=None or the option is ommited.
-    timeout = kwargs.pop('timeout', None) or 60
-    context_id = kwargs.pop('context_id', None)
-    expression = js_template.Render(expression, **kwargs)
-    return self._runtime.Evaluate(expression, context_id, timeout)
-
-  def WaitForJavaScriptCondition(self, condition, **kwargs):
-    """Wait for a JavaScript condition to become truthy.
-
-    Example: runner.WaitForJavaScriptCondition('window.foo == 10');
-
-    Args:
-      condition: The JavaScript condition (provided as string).
-
-    Optional keyword args:
-      timeout: The number in seconds to wait for the condition to become
-          True (default to 60).
-      context_id: The id of an iframe where to execute the code; the main page
-          has context_id=1, the first iframe context_id=2, etc.
-      Additional keyword arguments provide values to be interpolated within
-          the expression. See telemetry.util.js_template for details.
-
-    Returns:
-      The value returned by the JavaScript condition that got interpreted as
-      true.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.EvaluationException
-      exceptions.WebSocketException
-      exceptions.DevtoolsTargetCrashException
-    """
-    # Use the default both when timeout=None or the option is ommited.
-    timeout = kwargs.pop('timeout', None) or 60
-    context_id = kwargs.pop('context_id', None)
-    condition = js_template.Render(condition, **kwargs)
-
-    def IsJavaScriptExpressionTrue():
-      return self._runtime.Evaluate(condition, context_id, timeout)
-
-    try:
-      return py_utils.WaitFor(IsJavaScriptExpressionTrue, timeout)
-    except py_utils.TimeoutException as e:
-      # Try to make timeouts a little more actionable by dumping console output.
-      debug_message = None
-      try:
-        debug_message = (
-            'Console output:\n%s' %
-            self.GetCurrentConsoleOutputBuffer())
-      except Exception as e:
-        debug_message = (
-            'Exception thrown when trying to capture console output: %s' %
-            repr(e))
-      raise py_utils.TimeoutException(
-          e.message + '\n' + debug_message)
-
-  @_HandleInspectorWebSocketExceptions
-  def EnableAllContexts(self):
-    """Allows access to iframes.
-
-    Raises:
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._runtime.EnableAllContexts()
-
-  @_HandleInspectorWebSocketExceptions
-  def SynthesizeScrollGesture(self, x=100, y=800, xDistance=0, yDistance=-500,
-                              xOverscroll=None, yOverscroll=None,
-                              preventFling=None, speed=None,
-                              gestureSourceType=None, repeatCount=None,
-                              repeatDelayMs=None, interactionMarkerName=None,
-                              timeout=60):
-    """Runs an inspector command that causes a repeatable browser driven scroll.
-
-    Args:
-      x: X coordinate of the start of the gesture in CSS pixels.
-      y: Y coordinate of the start of the gesture in CSS pixels.
-      xDistance: Distance to scroll along the X axis (positive to scroll left).
-      yDistance: Distance to scroll along the Y axis (positive to scroll up).
-      xOverscroll: Number of additional pixels to scroll back along the X axis.
-      xOverscroll: Number of additional pixels to scroll back along the Y axis.
-      preventFling: Prevents a fling gesture.
-      speed: Swipe speed in pixels per second.
-      gestureSourceType: Which type of input events to be generated.
-      repeatCount: Number of additional repeats beyond the first scroll.
-      repeatDelayMs: Number of milliseconds delay between each repeat.
-      interactionMarkerName: The name of the interaction markers to generate.
-
-    Raises:
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    params = {
-        'x': x,
-        'y': y,
-        'xDistance': xDistance,
-        'yDistance': yDistance
-    }
-
-    if preventFling is not None:
-      params['preventFling'] = preventFling
-
-    if xOverscroll is not None:
-      params['xOverscroll'] = xOverscroll
-
-    if yOverscroll is not None:
-      params['yOverscroll'] = yOverscroll
-
-    if speed is not None:
-      params['speed'] = speed
-
-    if repeatCount is not None:
-      params['repeatCount'] = repeatCount
-
-    if gestureSourceType is not None:
-      params['gestureSourceType'] = gestureSourceType
-
-    if repeatDelayMs is not None:
-      params['repeatDelayMs'] = repeatDelayMs
-
-    if interactionMarkerName is not None:
-      params['interactionMarkerName'] = interactionMarkerName
-
-    scroll_command = {
-      'method': 'Input.synthesizeScrollGesture',
-      'params': params
-    }
-    return self._runtime.RunInspectorCommand(scroll_command, timeout)
-
-  @_HandleInspectorWebSocketExceptions
-  def DispatchKeyEvent(self, keyEventType='char', modifiers=None,
-                       timestamp=None, text=None, unmodifiedText=None,
-                       keyIdentifier=None, domCode=None, domKey=None,
-                       windowsVirtualKeyCode=None, nativeVirtualKeyCode=None,
-                       autoRepeat=None, isKeypad=None, isSystemKey=None,
-                       timeout=60):
-    """Dispatches a key event to the page.
-
-    Args:
-      type: Type of the key event. Allowed values: 'keyDown', 'keyUp',
-          'rawKeyDown', 'char'.
-      modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2,
-          Meta/Command=4, Shift=8 (default: 0).
-      timestamp: Time at which the event occurred. Measured in UTC time in
-          seconds since January 1, 1970 (default: current time).
-      text: Text as generated by processing a virtual key code with a keyboard
-          layout. Not needed for for keyUp and rawKeyDown events (default: '').
-      unmodifiedText: Text that would have been generated by the keyboard if no
-          modifiers were pressed (except for shift). Useful for shortcut
-          (accelerator) key handling (default: "").
-      keyIdentifier: Unique key identifier (e.g., 'U+0041') (default: '').
-      windowsVirtualKeyCode: Windows virtual key code (default: 0).
-      nativeVirtualKeyCode: Native virtual key code (default: 0).
-      autoRepeat: Whether the event was generated from auto repeat (default:
-          False).
-      isKeypad: Whether the event was generated from the keypad (default:
-          False).
-      isSystemKey: Whether the event was a system key event (default: False).
-
-    Raises:
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    params = {
-      'type': keyEventType,
-    }
-
-    if modifiers is not None:
-      params['modifiers'] = modifiers
-    if timestamp is not None:
-      params['timestamp'] = timestamp
-    if text is not None:
-      params['text'] = text
-    if unmodifiedText is not None:
-      params['unmodifiedText'] = unmodifiedText
-    if keyIdentifier is not None:
-      params['keyIdentifier'] = keyIdentifier
-    if domCode is not None:
-      params['code'] = domCode
-    if domKey is not None:
-      params['key'] = domKey
-    if windowsVirtualKeyCode is not None:
-      params['windowsVirtualKeyCode'] = windowsVirtualKeyCode
-    if nativeVirtualKeyCode is not None:
-      params['nativeVirtualKeyCode'] = nativeVirtualKeyCode
-    if autoRepeat is not None:
-      params['autoRepeat'] = autoRepeat
-    if isKeypad is not None:
-      params['isKeypad'] = isKeypad
-    if isSystemKey is not None:
-      params['isSystemKey'] = isSystemKey
-
-    key_command = {
-      'method': 'Input.dispatchKeyEvent',
-      'params': params
-    }
-    return self._runtime.RunInspectorCommand(key_command, timeout)
-
-  # Methods used internally by other backends.
-
-  def _HandleInspectorDomainNotification(self, res):
-    if (res['method'] == 'Inspector.detached' and
-        res.get('params', {}).get('reason', '') == 'replaced_with_devtools'):
-      self._WaitForInspectorToGoAway()
-      return
-    if res['method'] == 'Inspector.targetCrashed':
-      exception = exceptions.DevtoolsTargetCrashException(self.app)
-      self._AddDebuggingInformation(exception)
-      raise exception
-
-  def _WaitForInspectorToGoAway(self):
-    self._websocket.Disconnect()
-    raw_input('The connection to Chrome was lost to the inspector ui.\n'
-              'Please close the inspector and press enter to resume '
-              'Telemetry run...')
-    raise exceptions.DevtoolsTargetCrashException(
-        self.app, 'Devtool connection with the browser was interrupted due to '
-        'the opening of an inspector.')
-
-  def _ConvertExceptionFromInspectorWebsocket(self, error):
-    """Converts an Exception from inspector_websocket.
-
-    This method always raises a Telemetry exception. It appends debugging
-    information. The exact exception raised depends on |error|.
-
-    Args:
-      error: An instance of socket.error or websocket.WebSocketException.
-    Raises:
-      exceptions.TimeoutException: A timeout occurred.
-      exceptions.DevtoolsTargetCrashException: On any other error, the most
-        likely explanation is that the devtool's target crashed.
-    """
-    if isinstance(error, websocket.WebSocketTimeoutException):
-      new_error = exceptions.TimeoutException()
-      new_error.AddDebuggingMessage(exceptions.AppCrashException(
-          self.app, 'The app is probably crashed:\n'))
-    else:
-      new_error = exceptions.DevtoolsTargetCrashException(self.app)
-
-    original_error_msg = 'Original exception:\n' + str(error)
-    new_error.AddDebuggingMessage(original_error_msg)
-    self._AddDebuggingInformation(new_error)
-
-    raise new_error, None, sys.exc_info()[2]
-
-  def _AddDebuggingInformation(self, error):
-    """Adds debugging information to error.
-
-    Args:
-      error: An instance of exceptions.Error.
-    """
-    if self.IsInspectable():
-      msg = (
-          'Received a socket error in the browser connection and the tab '
-          'still exists. The operation probably timed out.'
-      )
-    else:
-      msg = (
-          'Received a socket error in the browser connection and the tab no '
-          'longer exists. The tab probably crashed.'
-      )
-    error.AddDebuggingMessage(msg)
-    error.AddDebuggingMessage('Debugger url: %s' % self.debugger_url)
-
-  @_HandleInspectorWebSocketExceptions
-  def CollectGarbage(self):
-    self._page.CollectGarbage()
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_backend_list.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_backend_list.py
deleted file mode 100644
index 7e1f8fb..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_backend_list.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-from telemetry.core import exceptions
-
-
-def DebuggerUrlToId(debugger_url):
-  return debugger_url.split('/')[-1]
-
-
-class InspectorBackendList(collections.Sequence):
-  """A dynamic sequence of active InspectorBackends."""
-
-  def __init__(self, browser_backend):
-    """Constructor.
-
-    Args:
-      browser_backend: The BrowserBackend instance to query for
-          InspectorBackends.
-    """
-    self._browser_backend = browser_backend
-    self._devtools_context_map_backend = None
-    # A list of filtered contexts.
-    self._filtered_context_ids = []
-    # A cache of inspector backends, by context ID.
-    self._wrapper_dict = {}
-
-  @property
-  def _devtools_client(self):
-    return self._browser_backend.devtools_client
-
-  @property
-  def app(self):
-    return self._browser_backend.app
-
-  def GetContextInfo(self, context_id):
-    return self._devtools_context_map_backend.GetContextInfo(context_id)
-
-  def ShouldIncludeContext(self, _):
-    """Override this method to control which contexts are included."""
-    return True
-
-  def CreateWrapper(self, inspector_backend_instance):
-    """Override to return the wrapper API over InspectorBackend.
-
-    The wrapper API is the public interface for InspectorBackend. It
-    may expose whatever methods are desired on top of that backend.
-    """
-    raise NotImplementedError
-
-  # TODO(nednguyen): Remove this method and turn inspector_backend_list API to
-  # dictionary-like API (crbug.com/398467)
-  def __getitem__(self, index):
-    self._Update()
-    if index >= len(self._filtered_context_ids):
-      raise exceptions.DevtoolsTargetCrashException(
-          self.app,
-          'Web content with index %s may have crashed. '
-          'filtered_context_ids = %s' % (
-              index, repr(self._filtered_context_ids)))
-    context_id = self._filtered_context_ids[index]
-    return self.GetBackendFromContextId(context_id)
-
-  def GetTabById(self, identifier):
-    self._Update()
-    return self.GetBackendFromContextId(identifier)
-
-  def GetBackendFromContextId(self, context_id):
-    self._Update()
-    if context_id not in self._wrapper_dict:
-      try:
-        backend = self._devtools_context_map_backend.GetInspectorBackend(
-            context_id)
-      except exceptions.Error as e:
-        self._HandleDevToolsConnectionError(e)
-        raise e
-      # Propagate KeyError from GetInspectorBackend call.
-
-      wrapper = self.CreateWrapper(backend)
-      self._wrapper_dict[context_id] = wrapper
-    return self._wrapper_dict[context_id]
-
-  def IterContextIds(self):
-    self._Update()
-    return iter(self._filtered_context_ids)
-
-  def __iter__(self):
-    self._Update()
-    for context_id in self._filtered_context_ids:
-      yield self.GetTabById(context_id)
-
-  def __len__(self):
-    self._Update()
-    return len(self._filtered_context_ids)
-
-  def _Update(self):
-    backends_map = self._devtools_client.GetUpdatedInspectableContexts()
-    self._devtools_context_map_backend = backends_map
-
-    # Clear context ids that do not appear in the inspectable contexts.
-    context_ids = [context['id'] for context in backends_map.contexts]
-    self._filtered_context_ids = [context_id
-                                  for context_id in self._filtered_context_ids
-                                  if context_id in context_ids]
-    # Add new context ids.
-    for context in backends_map.contexts:
-      if (context['id'] not in self._filtered_context_ids and
-          self.ShouldIncludeContext(context)):
-        self._filtered_context_ids.append(context['id'])
-
-    # Clean up any backends for contexts that have gone away.
-    for context_id in self._wrapper_dict.keys():
-      if context_id not in self._filtered_context_ids:
-        del self._wrapper_dict[context_id]
-
-  def _HandleDevToolsConnectionError(self, error):
-    """Called when handling errors in connecting to the DevTools websocket.
-
-    This can be overwritten by sub-classes to add more debugging information to
-    errors.
-    """
-    pass
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_console.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_console.py
deleted file mode 100644
index 9657cd1..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_console.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import StringIO
-
-from telemetry.internal.backends.chrome_inspector import websocket
-
-
-class InspectorConsole(object):
-  def __init__(self, inspector_websocket):
-    self._inspector_websocket = inspector_websocket
-    self._inspector_websocket.RegisterDomain('Console', self._OnNotification)
-    self._message_output_stream = None
-    self._last_message = None
-    self._console_enabled = False
-
-  def _OnNotification(self, msg):
-    if msg['method'] == 'Console.messageAdded':
-      assert self._message_output_stream
-      if msg['params']['message']['url'] == 'chrome://newtab/':
-        return
-      self._last_message = '(%s) %s:%i: %s' % (
-        msg['params']['message']['level'],
-        msg['params']['message']['url'],
-        msg['params']['message']['line'],
-        msg['params']['message']['text'])
-      self._message_output_stream.write(
-        '%s\n' % self._last_message)
-
-    elif msg['method'] == 'Console.messageRepeatCountUpdated':
-      if self._message_output_stream:
-        self._message_output_stream.write(
-          '%s\n' % self._last_message)
-
-  def GetCurrentConsoleOutputBuffer(self, timeout=10):
-    self._message_output_stream = StringIO.StringIO()
-    self._EnableConsoleOutputStream(timeout)
-    try:
-      self._inspector_websocket.DispatchNotifications(timeout)
-      return self._message_output_stream.getvalue()
-    except websocket.WebSocketTimeoutException:
-      return self._message_output_stream.getvalue()
-    finally:
-      self._DisableConsoleOutputStream(timeout)
-      self._message_output_stream.close()
-      self._message_output_stream = None
-
-
-  def _EnableConsoleOutputStream(self, timeout):
-    self._inspector_websocket.SyncRequest({'method': 'Console.enable'}, timeout)
-
-  def _DisableConsoleOutputStream(self, timeout):
-    self._inspector_websocket.SyncRequest(
-        {'method': 'Console.disable'}, timeout)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_console_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_console_unittest.py
deleted file mode 100644
index 858568e..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_console_unittest.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-from telemetry.testing import tab_test_case
-
-import py_utils
-
-
-class TabConsoleTest(tab_test_case.TabTestCase):
-  def testConsoleOutputStream(self):
-    self.Navigate('page_that_logs_to_console.html')
-
-    initial = self._tab.EvaluateJavaScript('window.__logCount')
-    def GotLog():
-      current = self._tab.EvaluateJavaScript('window.__logCount')
-      return current > initial
-    py_utils.WaitFor(GotLog, 5)
-
-    console_output = (
-        self._tab._inspector_backend.GetCurrentConsoleOutputBuffer())
-    lines = [l for l in console_output.split('\n') if len(l)]
-
-    self.assertTrue(len(lines) >= 1)
-    for line in lines:
-      prefix = 'http://(.+)/page_that_logs_to_console.html:9'
-      expected_line = r'\(log\) %s: Hello, world' % prefix
-      self.assertTrue(re.match(expected_line, line))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_memory.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_memory.py
deleted file mode 100644
index cd4ddf0..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_memory.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import json
-
-from telemetry.core import exceptions
-
-
-class InspectorMemoryException(exceptions.Error):
-  pass
-
-
-class InspectorMemory(object):
-  """Communicates with the remote inspector's Memory domain."""
-
-  def __init__(self, inspector_websocket):
-    self._inspector_websocket = inspector_websocket
-    self._inspector_websocket.RegisterDomain('Memory', self._OnNotification)
-
-  def _OnNotification(self, msg):
-    pass
-
-  def GetDOMCounters(self, timeout):
-    """Retrieves DOM element counts.
-
-    Args:
-      timeout: The number of seconds to wait for the inspector backend to
-          service the request before timing out.
-
-    Returns:
-      A dictionary containing the counts associated with "nodes", "documents",
-      and "jsEventListeners".
-    Raises:
-      InspectorMemoryException
-      websocket.WebSocketException
-      socket.error
-      exceptions.WebSocketDisconnected
-    """
-    res = self._inspector_websocket.SyncRequest({
-      'method': 'Memory.getDOMCounters'
-    }, timeout)
-    if ('result' not in res or
-        'nodes' not in res['result'] or
-        'documents' not in res['result'] or
-        'jsEventListeners' not in res['result']):
-      raise InspectorMemoryException(
-          'Inspector returned unexpected result for Memory.getDOMCounters:\n' +
-          json.dumps(res, indent=2))
-    return {
-        'nodes': res['result']['nodes'],
-        'documents': res['result']['documents'],
-        'jsEventListeners': res['result']['jsEventListeners']
-    }
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_memory_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_memory_unittest.py
deleted file mode 100644
index 9b7f5e0..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_memory_unittest.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.testing import tab_test_case
-
-
-class InspectorMemoryTest(tab_test_case.TabTestCase):
-
-  @decorators.Enabled('has tabs')
-  def testGetDOMStats(self):
-    # Due to an issue with CrOS, we create a new tab here rather than
-    # using the existing tab to get a consistent starting page on all platforms.
-    self._tab = self._browser.tabs.New()
-
-    self.Navigate('dom_counter_sample.html')
-
-    self._tab.ExecuteJavaScript('gc();')
-
-    # Document_count > 1 indicates that WebCore::Document loaded in Chrome
-    # is leaking! The baseline should exactly match the numbers on:
-    # internal/testing/dom_counter_sample.html
-    # Please contact kouhei@, hajimehoshi@ when rebaselining.
-    counts = self._tab.dom_stats
-    self.assertEqual(counts['document_count'], 1,
-        'Document leak is detected! '+
-        'The previous document is likely retained unexpectedly.')
-    self.assertEqual(counts['node_count'], 14,
-        'Node leak is detected!')
-    self.assertEqual(counts['event_listener_count'], 2,
-        'EventListener leak is detected!')
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.AppendExtraBrowserArgs('--js-flags=--expose-gc')
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_page.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_page.py
deleted file mode 100644
index 0c37347..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_page.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import time
-
-from telemetry.util import image_util
-
-
-class InspectorPage(object):
-  """Class that controls a page connected by an inspector_websocket.
-
-  This class provides utility methods for controlling a page connected by an
-  inspector_websocket. It does not perform any exception handling. All
-  inspector_websocket exceptions must be handled by the caller.
-  """
-  def __init__(self, inspector_websocket, timeout):
-    self._inspector_websocket = inspector_websocket
-    self._inspector_websocket.RegisterDomain('Page', self._OnNotification)
-
-    self._navigation_pending = False
-    self._navigation_url = ''  # Support for legacy backends.
-    self._navigation_frame_id = ''
-    self._navigated_frame_ids = None  # Holds frame ids while navigating.
-    self._script_to_evaluate_on_commit = None
-    # Turn on notifications. We need them to get the Page.frameNavigated event.
-    self._EnablePageNotifications(timeout=timeout)
-
-  def _OnNotification(self, msg):
-    if msg['method'] == 'Page.frameNavigated':
-      url = msg['params']['frame']['url']
-      if not self._navigated_frame_ids == None:
-        frame_id = msg['params']['frame']['id']
-        if self._navigation_frame_id == frame_id:
-          self._navigation_frame_id = ''
-          self._navigated_frame_ids = None
-          self._navigation_pending = False
-        else:
-          self._navigated_frame_ids.add(frame_id)
-      elif self._navigation_url == url:
-        # TODO(tonyg): Remove this when Chrome 38 goes stable.
-        self._navigation_url = ''
-        self._navigation_pending = False
-      elif (not url == 'chrome://newtab/' and not url == 'about:blank'
-        and not 'parentId' in msg['params']['frame']):
-        # Marks the navigation as complete and unblocks the
-        # WaitForNavigate call.
-        self._navigation_pending = False
-
-  def _SetScriptToEvaluateOnCommit(self, source, timeout):
-    existing_source = (self._script_to_evaluate_on_commit and
-                       self._script_to_evaluate_on_commit['source'])
-    if source == existing_source:
-      return
-    if existing_source:
-      request = {
-          'method': 'Page.removeScriptToEvaluateOnLoad',
-          'params': {
-              'identifier': self._script_to_evaluate_on_commit['id'],
-              }
-          }
-      self._inspector_websocket.SyncRequest(request, timeout)
-      self._script_to_evaluate_on_commit = None
-    if source:
-      request = {
-          'method': 'Page.addScriptToEvaluateOnLoad',
-          'params': {
-              'scriptSource': source,
-              }
-          }
-      res = self._inspector_websocket.SyncRequest(request, timeout)
-      self._script_to_evaluate_on_commit = {
-          'id': res['result']['identifier'],
-          'source': source
-          }
-
-  def _EnablePageNotifications(self, timeout=60):
-    request = {
-        'method': 'Page.enable'
-        }
-    res = self._inspector_websocket.SyncRequest(request, timeout)
-    assert len(res['result'].keys()) == 0
-
-  def WaitForNavigate(self, timeout=60):
-    """Waits for the navigation to complete.
-
-    The current page is expect to be in a navigation. This function returns
-    when the navigation is complete or when the timeout has been exceeded.
-    """
-    start_time = time.time()
-    remaining_time = timeout
-    self._navigation_pending = True
-    while self._navigation_pending and remaining_time > 0:
-      remaining_time = max(timeout - (time.time() - start_time), 0.0)
-      self._inspector_websocket.DispatchNotifications(remaining_time)
-
-  def Navigate(self, url, script_to_evaluate_on_commit=None, timeout=60):
-    """Navigates to |url|.
-
-    If |script_to_evaluate_on_commit| is given, the script source string will be
-    evaluated when the navigation is committed. This is after the context of
-    the page exists, but before any script on the page itself has executed.
-    """
-
-    self._SetScriptToEvaluateOnCommit(script_to_evaluate_on_commit, timeout)
-    request = {
-        'method': 'Page.navigate',
-        'params': {
-            'url': url,
-            }
-        }
-    self._navigated_frame_ids = set()
-    res = self._inspector_websocket.SyncRequest(request, timeout)
-    if 'frameId' in res['result']:
-      # Modern backends are returning frameId from Page.navigate.
-      # Use it here to unblock upon precise navigation.
-      frame_id = res['result']['frameId']
-      if self._navigated_frame_ids and frame_id in self._navigated_frame_ids:
-        self._navigated_frame_ids = None
-        return
-      self._navigation_frame_id = frame_id
-    else:
-      # TODO(tonyg): Remove this when Chrome 38 goes stable.
-      self._navigated_frame_ids = None
-      self._navigation_url = url
-    self.WaitForNavigate(timeout)
-
-  def GetCookieByName(self, name, timeout=60):
-    """Returns the value of the cookie by the given |name|."""
-    request = {
-        'method': 'Page.getCookies'
-        }
-    res = self._inspector_websocket.SyncRequest(request, timeout)
-    cookies = res['result']['cookies']
-    for cookie in cookies:
-      if cookie['name'] == name:
-        return cookie['value']
-    return None
-
-  def CaptureScreenshot(self, timeout=60):
-    request = {
-        'method': 'Page.captureScreenshot'
-        }
-    # "Google API are missing..." infobar might cause a viewport resize
-    # which invalidates screenshot request. See crbug.com/459820.
-    for _ in range(2):
-      res = self._inspector_websocket.SyncRequest(request, timeout)
-      if res and ('result' in res) and ('data' in res['result']):
-        return image_util.FromBase64Png(res['result']['data'])
-    return None
-
-  def CollectGarbage(self, timeout=60):
-    request = {
-        'method': 'HeapProfiler.collectGarbage'
-        }
-    res = self._inspector_websocket.SyncRequest(request, timeout)
-    assert 'result' in res
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_page_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_page_unittest.py
deleted file mode 100644
index 935b8df..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_page_unittest.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.testing import tab_test_case
-from telemetry.util import image_util
-
-
-class InspectorPageTest(tab_test_case.TabTestCase):
-  def testPageNavigateToNormalUrl(self):
-    self.Navigate('blank.html')
-
-  def testCustomActionToNavigate(self):
-    self.Navigate('page_with_link.html')
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.location.pathname;'),
-        '/page_with_link.html')
-
-    self._tab.ExecuteJavaScript('document.getElementById("clickme").click();')
-    self._tab.WaitForNavigate()
-
-    self.assertEquals(
-        self._tab.EvaluateJavaScript('document.location.pathname;'),
-        '/blank.html')
-
-  def testGetCookieByName(self):
-    self.Navigate('blank.html')
-    self._tab.ExecuteJavaScript('document.cookie="foo=bar"')
-    self.assertEquals(self._tab.GetCookieByName('foo'), 'bar')
-
-  def testScriptToEvaluateOnCommit(self):
-    self.Navigate('blank.html',
-                  script_to_evaluate_on_commit='var foo = "bar";')
-    self._tab.WaitForDocumentReadyStateToBeComplete()
-    self.assertEquals(self._tab.EvaluateJavaScript('foo'), 'bar')
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testCaptureScreenshot(self):
-    if not self._tab.screenshot_supported:
-      return
-    self.Navigate('green_rect.html')
-    res = image_util.Pixels(self._tab.Screenshot())
-    self.assertEquals(0x00, res[0])
-    self.assertEquals(0xFF, res[1])
-    self.assertEquals(0x00, res[2])
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_runtime.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_runtime.py
deleted file mode 100644
index 7b619c1..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_runtime.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.core import exceptions
-
-
-class InspectorRuntime(object):
-  def __init__(self, inspector_websocket):
-    self._inspector_websocket = inspector_websocket
-    self._inspector_websocket.RegisterDomain('Runtime', self._OnNotification)
-    self._contexts_enabled = False
-    self._max_context_id = None
-
-  def _OnNotification(self, msg):
-    if (self._contexts_enabled and
-        msg['method'] == 'Runtime.executionContextCreated'):
-      self._max_context_id = max(self._max_context_id,
-                                 msg['params']['context']['id'])
-
-  def Execute(self, expr, context_id, timeout):
-    self.Evaluate(expr + '; 0;', context_id, timeout)
-
-  def Evaluate(self, expr, context_id, timeout):
-    """Evaluates a javascript expression and returns the result.
-
-    |context_id| can refer to an iframe. The main page has context_id=1, the
-    first iframe context_id=2, etc.
-
-    Raises:
-      exceptions.EvaluateException
-      exceptions.WebSocketDisconnected
-      websocket.WebSocketException
-      socket.error
-    """
-    request = {
-      'method': 'Runtime.evaluate',
-      'params': {
-        'expression': expr,
-        'returnByValue': True
-        }
-      }
-    if context_id is not None:
-      self.EnableAllContexts()
-      request['params']['contextId'] = context_id
-    res = self._inspector_websocket.SyncRequest(request, timeout)
-    if 'error' in res:
-      raise exceptions.EvaluateException(res['error']['message'])
-
-    if 'exceptionDetails' in res['result']:
-      details = res['result']['exceptionDetails']
-      raise exceptions.EvaluateException(
-          text=details['text'],
-          class_name=details.get('exception', {}).get('className'),
-          description=details.get('exception', {}).get('description'))
-
-    if res['result']['result']['type'] == 'undefined':
-      return None
-    return res['result']['result']['value']
-
-  def EnableAllContexts(self):
-    """Allow access to iframes.
-
-    Raises:
-      exceptions.WebSocketDisconnected
-      websocket.WebSocketException
-      socket.error
-    """
-    if not self._contexts_enabled:
-      self._contexts_enabled = True
-      self._inspector_websocket.SyncRequest({'method': 'Runtime.enable'},
-                                            timeout=30)
-    return self._max_context_id
-
-  def RunInspectorCommand(self, command, timeout):
-    """Runs an inspector command.
-
-    Raises:
-      exceptions.WebSocketDisconnected
-      websocket.WebSocketException
-      socket.error
-    """
-    res = self._inspector_websocket.SyncRequest(command, timeout)
-    return res
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_runtime_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_runtime_unittest.py
deleted file mode 100644
index 1bb8e40..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_runtime_unittest.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import exceptions
-from telemetry.testing import tab_test_case
-
-import py_utils
-
-
-class InspectorRuntimeTest(tab_test_case.TabTestCase):
-  def testRuntimeEvaluateSimple(self):
-    res = self._tab.EvaluateJavaScript('1+1')
-    assert res == 2
-
-  def testRuntimeEvaluateThatFails(self):
-    with self.assertRaises(exceptions.EvaluateException) as ex_context:
-      self._tab.EvaluateJavaScript('var x = 1;\nfsdfsdfsf')
-    exception_message = str(ex_context.exception)
-    self.assertIn('ReferenceError: fsdfsdfsf is not defined', exception_message)
-
-  def testRuntimeEvaluateOfSomethingThatCantJSONize(self):
-
-    def test():
-      self._tab.EvaluateJavaScript("""
-        var cur = {};
-        var root = {next: cur};
-        for (var i = 0; i < 1000; i++) {
-          next = {};
-          cur.next = next;
-          cur = next;
-        }
-        root;""")
-    self.assertRaises(exceptions.EvaluateException, test)
-
-  def testRuntimeExecuteOfSomethingThatCantJSONize(self):
-    self._tab.ExecuteJavaScript('window')
-
-  def testIFrame(self):
-    starting_contexts = self._tab.EnableAllContexts()
-
-    self.Navigate('host.html')
-
-    # Access host page.
-    test_defined_js = "typeof(testVar) != 'undefined'"
-    self._tab.WaitForJavaScriptCondition(test_defined_js, timeout=10)
-
-    py_utils.WaitFor(lambda: self._tab.EnableAllContexts() != starting_contexts,
-                 timeout=10)
-
-    self.assertEquals(self._tab.EvaluateJavaScript('testVar'), 'host')
-
-    def TestVarReady(context_id):
-      """Returns True if the context and testVar are both ready."""
-      try:
-        return self._tab.EvaluateJavaScript(
-            test_defined_js, context_id=context_id)
-      except exceptions.EvaluateException:
-        # This happens when the context is not ready.
-        return False
-
-    def TestVar(context_id):
-      """Waits for testVar and the context to be ready, then returns the value
-      of testVar."""
-      py_utils.WaitFor(lambda: TestVarReady(context_id), timeout=10)
-      return self._tab.EvaluateJavaScript('testVar', context_id=context_id)
-
-    all_contexts = self._tab.EnableAllContexts()
-    # Access parent page using EvaluateJavaScriptInContext.
-    self.assertEquals(TestVar(context_id=all_contexts-3), 'host')
-
-    # Access the iframes without guarantees on which order they loaded.
-    iframe1 = TestVar(context_id=all_contexts-2)
-    iframe2 = TestVar(context_id=all_contexts-1)
-    iframe3 = TestVar(context_id=all_contexts)
-    self.assertEqual(set([iframe1, iframe2, iframe3]),
-                     set(['iframe1', 'iframe2', 'iframe3']))
-
-    # Accessing a non-existent iframe throws an exception.
-    self.assertRaises(exceptions.EvaluateException,
-        lambda: self._tab.EvaluateJavaScript(
-            '1+1', context_id=all_contexts + 1))
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_websocket.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_websocket.py
deleted file mode 100644
index 1fe5c2a..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_websocket.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import errno
-import json
-import logging
-import socket
-import time
-
-from telemetry.core import exceptions
-from telemetry.internal.backends.chrome_inspector import websocket
-
-class WebSocketDisconnected(exceptions.Error):
-  """An attempt was made to use a web socket after it had been disconnected."""
-  pass
-
-
-class InspectorWebsocket(object):
-
-  # See http://www.jsonrpc.org/specification#error_object.
-  METHOD_NOT_FOUND_CODE = -32601
-
-  def __init__(self):
-    """Create a websocket handler for communicating with Inspectors."""
-    self._socket = None
-    self._cur_socket_timeout = 0
-    self._next_request_id = 0
-    self._domain_handlers = {}
-    self._pending_callbacks = dict()
-
-  def RegisterDomain(self, domain_name, notification_handler):
-    """Registers a given domain for handling notification methods.
-
-    For example, given inspector_backend:
-       def OnConsoleNotification(msg):
-          if msg['method'] == 'Console.messageAdded':
-             print msg['params']['message']
-       inspector_backend.RegisterDomain('Console', OnConsoleNotification)
-
-    Args:
-      domain_name: The devtools domain name. E.g., 'Tracing', 'Memory', 'Page'.
-      notification_handler: Handler for devtools notification. Will be
-          called if a devtools notification with matching domain is received
-          via DispatchNotifications. The handler accepts a single paramater:
-          the JSON object representing the notification.
-    """
-    assert domain_name not in self._domain_handlers
-    self._domain_handlers[domain_name] = notification_handler
-
-  def UnregisterDomain(self, domain_name):
-    """Unregisters a previously registered domain."""
-    assert domain_name in self._domain_handlers
-    del self._domain_handlers[domain_name]
-
-  def Connect(self, url, timeout):
-    """Connects the websocket.
-
-    Raises:
-      websocket.WebSocketException
-      socket.error
-    """
-    assert not self._socket
-    self._socket = websocket.create_connection(url, timeout=timeout)
-    self._cur_socket_timeout = 0
-    self._next_request_id = 0
-
-  def Disconnect(self):
-    """Disconnects the inspector websocket.
-
-    Raises:
-      websocket.WebSocketException
-      socket.error
-    """
-    if self._socket:
-      self._socket.close()
-      self._socket = None
-
-  def SendAndIgnoreResponse(self, req):
-    """Sends a request without waiting for a response.
-
-    Raises:
-      websocket.WebSocketException: Error from websocket library.
-      socket.error: Error from websocket library.
-      exceptions.WebSocketDisconnected: The socket was disconnected.
-    """
-    self._SendRequest(req)
-
-  def _SendRequest(self, req):
-    if not self._socket:
-      raise WebSocketDisconnected()
-    req['id'] = self._next_request_id
-    self._next_request_id += 1
-    data = json.dumps(req)
-    self._socket.send(data)
-    if logging.getLogger().isEnabledFor(logging.DEBUG):
-      logging.debug('sent [%s]', json.dumps(req, indent=2, sort_keys=True))
-
-  def SyncRequest(self, req, timeout):
-    """Sends a request and waits for a response.
-
-    Raises:
-      websocket.WebSocketException: Error from websocket library.
-      socket.error: Error from websocket library.
-      exceptions.WebSocketDisconnected: The socket was disconnected.
-    """
-    self._SendRequest(req)
-
-    while True:
-      res = self._Receive(timeout)
-      if 'id' in res and res['id'] == req['id']:
-        return res
-
-  def AsyncRequest(self, req, callback):
-    """Sends an async request and returns immediately.
-
-    Response will be handled in the |callback| later when DispatchNotifications
-    is invoked.
-
-    Args:
-      callback: a function that takes inspector's response as the argument.
-    """
-    self._SendRequest(req)
-    self._pending_callbacks[req['id']] = callback
-
-  def DispatchNotifications(self, timeout):
-    """Waits for responses from the websocket, dispatching them as necessary.
-
-    Raises:
-      websocket.WebSocketException: Error from websocket library.
-      socket.error: Error from websocket library.
-      exceptions.WebSocketDisconnected: The socket was disconnected.
-    """
-    self._Receive(timeout)
-
-  def _SetTimeout(self, timeout):
-    if self._cur_socket_timeout != timeout:
-      self._socket.settimeout(timeout)
-      self._cur_socket_timeout = timeout
-
-  def _Receive(self, timeout):
-    if not self._socket:
-      raise WebSocketDisconnected()
-
-    self._SetTimeout(timeout)
-
-    while True:
-      try:
-        data = self._socket.recv()
-      except socket.error, e:
-        if e.errno == errno.EAGAIN:
-          # Resource is temporarily unavailable. Try again.
-          # See https://code.google.com/p/chromium/issues/detail?id=545853#c3
-          # for more details.
-          time.sleep(0.1)
-        else:
-          raise
-      else:
-        break
-
-    result = json.loads(data)
-    if logging.getLogger().isEnabledFor(logging.DEBUG):
-      logging.debug(
-          'got [%s]', json.dumps(result, indent=2, sort_keys=True))
-    if 'method' in result:
-      self._HandleNotification(result)
-    elif 'id' in result:
-      self._HandleAsyncResponse(result)
-    return result
-
-  def _HandleNotification(self, result):
-    mname = result['method']
-    dot_pos = mname.find('.')
-    domain_name = mname[:dot_pos]
-    if not domain_name in self._domain_handlers:
-      logging.warn('Unhandled inspector message: %s', result)
-      return
-
-    self._domain_handlers[domain_name](result)
-
-  def _HandleAsyncResponse(self, result):
-    callback = self._pending_callbacks.pop(result['id'], None)
-    if callback:
-      callback(result)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_websocket_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_websocket_unittest.py
deleted file mode 100644
index f528589..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/inspector_websocket_unittest.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import errno
-import socket
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.backends.chrome_inspector import websocket
-from telemetry.testing import fakes
-
-
-class FakeSocket(object):
-  """A fake websocket that allows test to send random data."""
-  def __init__(self, fake_timer):
-    self._fake_timer = fake_timer
-    self._responses = []
-    self._timeout = None
-
-  def AddResponse(self, response, time):
-    if self._responses:
-      assert self._responses[-1][1] < time, (
-          'Current response is scheduled earlier than previous response.')
-    self._responses.append((response, time))
-
-  def send(self, data):
-    pass
-
-  def recv(self):
-    if not self._responses:
-      raise Exception('No more recorded responses.')
-
-    response, time = self._responses.pop(0)
-    current_time = self._fake_timer.time()
-    if self._timeout is not None and time - current_time > self._timeout:
-      self._fake_timer.SetTime(current_time + self._timeout + 1)
-      raise websocket.WebSocketTimeoutException()
-
-    self._fake_timer.SetTime(time)
-    if isinstance(response, Exception):
-      raise response
-    return response
-
-  def settimeout(self, timeout):
-    self._timeout = timeout
-
-
-def _DoNothingHandler(elapsed_time):
-  del elapsed_time  # unused
-
-
-class InspectorWebsocketUnittest(unittest.TestCase):
-
-  def setUp(self):
-    self._fake_timer = fakes.FakeTimer()
-
-  def tearDown(self):
-    self._fake_timer.Restore()
-
-  @decorators.Disabled('chromeos', 'mac')  # crbug.com/483212, crbug.com/498950
-  def testDispatchNotification(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    fake_socket = FakeSocket(self._fake_timer)
-    # pylint: disable=protected-access
-    inspector._socket = fake_socket
-
-    results = []
-    def OnTestEvent(result):
-      results.append(result)
-
-    inspector.RegisterDomain('Test', OnTestEvent)
-    fake_socket.AddResponse('{"method": "Test.foo"}', 5)
-    inspector.DispatchNotifications(10)
-    self.assertEqual(1, len(results))
-    self.assertEqual('Test.foo', results[0]['method'])
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testDispatchNotificationTimedOut(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    fake_socket = FakeSocket(self._fake_timer)
-    # pylint: disable=protected-access
-    inspector._socket = fake_socket
-
-    results = []
-    def OnTestEvent(result):
-      results.append(result)
-
-    inspector.RegisterDomain('Test', OnTestEvent)
-    fake_socket.AddResponse('{"method": "Test.foo"}', 11)
-    with self.assertRaises(
-        websocket.WebSocketTimeoutException):
-      inspector.DispatchNotifications(timeout=10)
-    self.assertEqual(0, len(results))
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUnregisterDomain(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    fake_socket = FakeSocket(self._fake_timer)
-    # pylint: disable=protected-access
-    inspector._socket = fake_socket
-
-    results = []
-    def OnTestEvent(result):
-      results.append(result)
-
-    inspector.RegisterDomain('Test', OnTestEvent)
-    inspector.RegisterDomain('Test2', OnTestEvent)
-    inspector.UnregisterDomain('Test')
-
-    fake_socket.AddResponse('{"method": "Test.foo"}', 5)
-    fake_socket.AddResponse('{"method": "Test2.foo"}', 10)
-
-    inspector.DispatchNotifications(10)
-    self.assertEqual(0, len(results))
-
-    inspector.DispatchNotifications(10)
-    self.assertEqual(1, len(results))
-    self.assertEqual('Test2.foo', results[0]['method'])
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUnregisterDomainWithUnregisteredDomain(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    with self.assertRaises(AssertionError):
-      inspector.UnregisterDomain('Test')
-
-  def testAsyncRequest(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    fake_socket = FakeSocket(self._fake_timer)
-    # pylint: disable=protected-access
-    inspector._socket = fake_socket
-    response_count = [0]
-
-    def callback0(response):
-      response_count[0] += 1
-      self.assertEqual(2, response_count[0])
-      self.assertEqual('response1', response['result']['data'])
-
-    def callback1(response):
-      response_count[0] += 1
-      self.assertEqual(1, response_count[0])
-      self.assertEqual('response2', response['result']['data'])
-
-    request1 = {'method': 'Test.foo'}
-    inspector.AsyncRequest(request1, callback0)
-    request2 = {'method': 'Test.foo'}
-    inspector.AsyncRequest(request2, callback1)
-    fake_socket.AddResponse('{"id": 5555555, "result": {}}', 1)
-    inspector.DispatchNotifications(10)
-    self.assertEqual(0, response_count[0])
-    fake_socket.AddResponse(
-        '{"id": %d, "result": {"data": "response2"}}' % request2['id'], 1)
-    fake_socket.AddResponse(
-        '{"id": %d, "result": {"data": "response1"}}' % request1['id'], 2)
-    inspector.DispatchNotifications(10)
-    inspector.DispatchNotifications(10)
-    self.assertEqual(2, response_count[0])
-    fake_socket.AddResponse('{"id": 6666666, "result": {}}', 1)
-    inspector.DispatchNotifications(10)
-    self.assertEqual(2, response_count[0])
-
-  def testEAGAIN(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    fake_socket = FakeSocket(self._fake_timer)
-    # pylint: disable=protected-access
-    inspector._socket = fake_socket
-
-    error = socket.error(errno.EAGAIN, "error string")
-    fake_socket.AddResponse(error, 4)
-    fake_socket.AddResponse('{"asdf": "qwer"}', 5)
-
-    result = inspector._Receive(10)
-    self.assertEqual(result, {"asdf" : "qwer"})
-
-  def testSocketErrorOtherThanEAGAIN(self):
-    inspector = inspector_websocket.InspectorWebsocket()
-    fake_socket = FakeSocket(self._fake_timer)
-    # pylint: disable=protected-access
-    inspector._socket = fake_socket
-
-    error = socket.error(errno.EPIPE, "error string")
-    fake_socket.AddResponse(error, 4)
-
-    with self.assertRaises(socket.error):
-      inspector._Receive(10)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/memory_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/memory_backend.py
deleted file mode 100644
index 430fe73..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/memory_backend.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import socket
-import traceback
-
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.backends.chrome_inspector import websocket
-
-
-class MemoryTimeoutException(Exception):
-  pass
-
-
-class MemoryUnrecoverableException(Exception):
-  pass
-
-
-class MemoryUnexpectedResponseException(Exception):
-  pass
-
-
-class MemoryBackend(object):
-
-  def __init__(self, inspector_socket):
-    self._inspector_websocket = inspector_socket
-
-  def SetMemoryPressureNotificationsSuppressed(self, suppressed, timeout=30):
-    """Enable/disable suppressing memory pressure notifications.
-
-    Args:
-      suppressed: If true, memory pressure notifications will be suppressed.
-      timeout: The timeout in seconds.
-
-    Raises:
-      MemoryTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      MemoryUnrecoverableException: If there is a websocket error.
-      MemoryUnexpectedResponseException: If the response contains an error
-      or does not contain the expected result.
-    """
-    self._SendMemoryRequest('setPressureNotificationsSuppressed',
-                            {'suppressed': suppressed}, timeout)
-
-  def SimulateMemoryPressureNotification(self, pressure_level, timeout=30):
-    """Simulate a memory pressure notification.
-
-    Args:
-      pressure level: The memory pressure level of the notification ('moderate'
-          or 'critical').
-      timeout: The timeout in seconds.
-
-    Raises:
-      MemoryTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      MemoryUnrecoverableException: If there is a websocket error.
-      MemoryUnexpectedResponseException: If the response contains an error
-      or does not contain the expected result.
-    """
-    self._SendMemoryRequest('simulatePressureNotification',
-                            {'level': pressure_level}, timeout)
-
-  def _SendMemoryRequest(self, command, params, timeout):
-    method = 'Memory.%s' % command
-    request = {
-      'method': method,
-      'params': params
-    }
-    try:
-      response = self._inspector_websocket.SyncRequest(request, timeout)
-    except websocket.WebSocketTimeoutException:
-      raise MemoryTimeoutException(
-          'Exception raised while sending a %s request:\n%s' %
-              (method, traceback.format_exc()))
-    except (socket.error, websocket.WebSocketException,
-            inspector_websocket.WebSocketDisconnected):
-      raise MemoryUnrecoverableException(
-          'Exception raised while sending a %s request:\n%s' %
-              (method, traceback.format_exc()))
-
-    if 'error' in response:
-      code = response['error']['code']
-      if code == inspector_websocket.InspectorWebsocket.METHOD_NOT_FOUND_CODE:
-        logging.warning(
-            '%s DevTools method not supported by the browser' % method)
-      else:
-        raise MemoryUnexpectedResponseException(
-            'Inspector returned unexpected response for %s:\n%s' %
-                (method, json.dumps(response, indent=2)))
-
-  def Close(self):
-    self._inspector_websocket = None
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/memory_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/memory_backend_unittest.py
deleted file mode 100644
index e07818f..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/memory_backend_unittest.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import mock
-import unittest
-
-
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.backends.chrome_inspector import memory_backend
-from telemetry.testing import fakes
-from telemetry.testing import tab_test_case
-
-
-class MemoryBackendTest(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    super(MemoryBackendTest, self).setUp()
-    if not self._browser.supports_overriding_memory_pressure_notifications:
-      self.skipTest('Browser does not support overriding memory pressure '
-                    'notification signals, skipping test.')
-
-  def testSetMemoryPressureNotificationsSuppressed(self):
-    def PerformCheck(suppressed):
-      # Check that the method sends the correct DevTools request.
-      with mock.patch.object(inspector_websocket.InspectorWebsocket,
-                             'SyncRequest') as mock_method:
-        self._browser.SetMemoryPressureNotificationsSuppressed(suppressed)
-        self.assertEqual(1, mock_method.call_count)
-        request = mock_method.call_args[0][0]
-        self.assertEqual('Memory.setPressureNotificationsSuppressed',
-                         request['method'])
-        self.assertEqual(suppressed, request['params']['suppressed'])
-
-      # Check that the request and the response from the browser are handled
-      # properly.
-      self._browser.SetMemoryPressureNotificationsSuppressed(suppressed)
-
-    PerformCheck(True)
-    PerformCheck(False)
-
-  def testSimulateMemoryPressureNotification(self):
-    def PerformCheck(pressure_level):
-      # Check that the method sends the correct DevTools request.
-      with mock.patch.object(inspector_websocket.InspectorWebsocket,
-                             'SyncRequest') as mock_method:
-        self._browser.SimulateMemoryPressureNotification(pressure_level)
-        self.assertEqual(1, mock_method.call_count)
-        request = mock_method.call_args[0][0]
-        self.assertEqual('Memory.simulatePressureNotification',
-                         request['method'])
-        self.assertEqual(pressure_level, request['params']['level'])
-
-      # Check that the request and the response from the browser are handled
-      # properly.
-      self._browser.SimulateMemoryPressureNotification(pressure_level)
-
-    PerformCheck('moderate')
-    PerformCheck('critical')
-
-
-class MemoryBackendUnitTest(unittest.TestCase):
-
-  def setUp(self):
-    self._fake_timer = fakes.FakeTimer()
-    self._inspector_socket = fakes.FakeInspectorWebsocket(self._fake_timer)
-
-  def tearDown(self):
-    self._fake_timer.Restore()
-
-  def testSetMemoryPressureNotificationsSuppressedSuccess(self):
-    response_handler = mock.Mock(return_value={'result': {}})
-    self._inspector_socket.AddResponseHandler(
-        'Memory.setPressureNotificationsSuppressed', response_handler)
-    backend = memory_backend.MemoryBackend(self._inspector_socket)
-
-    backend.SetMemoryPressureNotificationsSuppressed(True)
-    self.assertEqual(1, response_handler.call_count)
-    self.assertTrue(response_handler.call_args[0][0]['params']['suppressed'])
-
-    backend.SetMemoryPressureNotificationsSuppressed(False)
-    self.assertEqual(2, response_handler.call_count)
-    self.assertFalse(response_handler.call_args[0][0]['params']['suppressed'])
-
-  def testSetMemoryPressureNotificationsSuppressedFailure(self):
-    response_handler = mock.Mock()
-    backend = memory_backend.MemoryBackend(self._inspector_socket)
-    self._inspector_socket.AddResponseHandler(
-        'Memory.setPressureNotificationsSuppressed', response_handler)
-
-    # If the DevTools method is missing, the backend should fail silently.
-    response_handler.return_value = {
-      'result': {},
-      'error': {
-        'code': -32601  # Method does not exist.
-      }
-    }
-    backend.SetMemoryPressureNotificationsSuppressed(True)
-    self.assertEqual(1, response_handler.call_count)
-
-    # All other errors should raise an exception.
-    response_handler.return_value = {
-      'result': {},
-      'error': {
-        'code': -32602  # Invalid method params.
-      }
-    }
-    self.assertRaises(memory_backend.MemoryUnexpectedResponseException,
-                      backend.SetMemoryPressureNotificationsSuppressed, True)
-
-  def testSimulateMemoryPressureNotificationSuccess(self):
-    response_handler = mock.Mock(return_value={'result': {}})
-    self._inspector_socket.AddResponseHandler(
-        'Memory.simulatePressureNotification', response_handler)
-    backend = memory_backend.MemoryBackend(self._inspector_socket)
-
-    backend.SimulateMemoryPressureNotification('critical')
-    self.assertEqual(1, response_handler.call_count)
-    self.assertEqual('critical',
-                     response_handler.call_args[0][0]['params']['level'])
-
-    backend.SimulateMemoryPressureNotification('moderate')
-    self.assertEqual(2, response_handler.call_count)
-    self.assertEqual('moderate',
-                     response_handler.call_args[0][0]['params']['level'])
-
-  def testSimulateMemoryPressureNotificationFailure(self):
-    response_handler = mock.Mock()
-    backend = memory_backend.MemoryBackend(self._inspector_socket)
-    self._inspector_socket.AddResponseHandler(
-        'Memory.simulatePressureNotification', response_handler)
-
-    # If the DevTools method is missing, the backend should fail silently.
-    response_handler.return_value = {
-      'result': {},
-      'error': {
-        'code': -32601  # Method does not exist.
-      }
-    }
-    backend.SimulateMemoryPressureNotification('critical')
-    self.assertEqual(1, response_handler.call_count)
-
-    # All other errors should raise an exception.
-    response_handler.return_value = {
-      'result': {},
-      'error': {
-        'code': -32602  # Invalid method params.
-      }
-    }
-    self.assertRaises(memory_backend.MemoryUnexpectedResponseException,
-                      backend.SimulateMemoryPressureNotification, 'critical')
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/tracing_backend.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/tracing_backend.py
deleted file mode 100644
index 1a32b87..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/tracing_backend.py
+++ /dev/null
@@ -1,298 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import socket
-import time
-import traceback
-
-from telemetry import decorators
-from telemetry.internal.backends.chrome_inspector import inspector_websocket
-from telemetry.internal.backends.chrome_inspector import websocket
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TracingUnsupportedException(Exception):
-  pass
-
-
-class TracingTimeoutException(Exception):
-  pass
-
-
-class TracingUnrecoverableException(Exception):
-  pass
-
-
-class TracingHasNotRunException(Exception):
-  pass
-
-
-class TracingUnexpectedResponseException(Exception):
-  pass
-
-
-class ClockSyncResponseException(Exception):
-  pass
-
-
-class _DevToolsStreamReader(object):
-  def __init__(self, inspector_socket, stream_handle):
-    self._inspector_websocket = inspector_socket
-    self._handle = stream_handle
-    self._trace_file_handle = None
-    self._callback = None
-
-  def Read(self, callback):
-    # Do not allow the instance of this class to be reused, as
-    # we only read data sequentially at the moment, so a stream
-    # can only be read once.
-    assert not self._callback
-    self._trace_file_handle = trace_data_module.TraceFileHandle()
-    self._trace_file_handle.Open()
-    self._callback = callback
-    self._ReadChunkFromStream()
-    # The below is not a typo -- queue one extra read ahead to avoid latency.
-    self._ReadChunkFromStream()
-
-  def _ReadChunkFromStream(self):
-    # Limit max block size to avoid fragmenting memory in sock.recv(),
-    # (see https://github.com/liris/websocket-client/issues/163 for details)
-    req = {'method': 'IO.read', 'params': {
-        'handle': self._handle, 'size': 32768}}
-    self._inspector_websocket.AsyncRequest(req, self._GotChunkFromStream)
-
-  def _GotChunkFromStream(self, response):
-    # Quietly discard responses from reads queued ahead after EOF.
-    if self._trace_file_handle is None:
-      return
-    if 'error' in response:
-      raise TracingUnrecoverableException(
-          'Reading trace failed: %s' % response['error']['message'])
-    result = response['result']
-    # Convert the trace data that's receive as UTF32 to its native encoding of
-    # UTF8 in order to reduce its size.
-    self._trace_file_handle.AppendTraceData(result['data'].encode('utf8'))
-    if not result.get('eof', False):
-      self._ReadChunkFromStream()
-      return
-    req = {'method': 'IO.close', 'params': {'handle': self._handle}}
-    self._inspector_websocket.SendAndIgnoreResponse(req)
-    self._trace_file_handle.Close()
-    self._callback(self._trace_file_handle)
-    self._trace_file_handle = None
-
-
-class TracingBackend(object):
-
-  _TRACING_DOMAIN = 'Tracing'
-
-  def __init__(self, inspector_socket, is_tracing_running=False,
-               support_modern_devtools_tracing_start_api=False):
-    self._inspector_websocket = inspector_socket
-    self._inspector_websocket.RegisterDomain(
-        self._TRACING_DOMAIN, self._NotificationHandler)
-    self._is_tracing_running = is_tracing_running
-    self._start_issued = False
-    self._can_collect_data = False
-    self._has_received_all_tracing_data = False
-    self._support_modern_devtools_tracing_start_api = (
-        support_modern_devtools_tracing_start_api)
-    self._trace_data_builder = None
-
-  @property
-  def is_tracing_running(self):
-    return self._is_tracing_running
-
-  def StartTracing(self, chrome_trace_config, timeout=10):
-    """When first called, starts tracing, and returns True.
-
-    If called during tracing, tracing is unchanged, and it returns False.
-    """
-    if self.is_tracing_running:
-      return False
-    assert not self._can_collect_data, 'Data not collected from last trace.'
-    # Reset collected tracing data from previous tracing calls.
-
-    if not self.IsTracingSupported():
-      raise TracingUnsupportedException(
-          'Chrome tracing not supported for this app.')
-
-    params = {'transferMode': 'ReturnAsStream'}
-    if self._support_modern_devtools_tracing_start_api:
-      params['traceConfig'] = (
-          chrome_trace_config.GetChromeTraceConfigForDevTools())
-    else:
-      if chrome_trace_config.requires_modern_devtools_tracing_start_api:
-        raise TracingUnsupportedException(
-            'Trace options require modern Tracing.start DevTools API, '
-            'which is NOT supported by the browser')
-      params['categories'], params['options'] = (
-          chrome_trace_config.GetChromeTraceCategoriesAndOptionsForDevTools())
-
-    req = {'method': 'Tracing.start', 'params': params}
-    logging.info('Start Tracing Request: %r', req)
-    response = self._inspector_websocket.SyncRequest(req, timeout)
-
-    if 'error' in response:
-      raise TracingUnexpectedResponseException(
-          'Inspector returned unexpected response for '
-          'Tracing.start:\n' + json.dumps(response, indent=2))
-
-    self._is_tracing_running = True
-    self._start_issued = True
-    return True
-
-  def RecordClockSyncMarker(self, sync_id):
-    assert self.is_tracing_running, 'Tracing must be running to clock sync.'
-    req = {
-      'method': 'Tracing.recordClockSyncMarker',
-      'params': {
-        'syncId': sync_id
-      }
-    }
-    rc = self._inspector_websocket.SyncRequest(req, timeout=2)
-    if 'error' in rc:
-      raise ClockSyncResponseException(rc['error']['message'])
-
-  def StopTracing(self):
-    """Stops tracing and pushes results to the supplied TraceDataBuilder.
-
-    If this is called after tracing has been stopped, trace data from the last
-    tracing run is pushed.
-    """
-    if not self.is_tracing_running:
-      raise TracingHasNotRunException()
-    else:
-      if not self._start_issued:
-        # Tracing is running but start was not issued so, startup tracing must
-        # be in effect. Issue another Tracing.start to update the transfer mode.
-        # TODO(caseq): get rid of it when streaming is the default.
-        params = {
-          'transferMode': 'ReturnAsStream',
-          'traceConfig': {}
-        }
-        req = {'method': 'Tracing.start', 'params': params}
-        self._inspector_websocket.SendAndIgnoreResponse(req)
-
-      req = {'method': 'Tracing.end'}
-      self._inspector_websocket.SendAndIgnoreResponse(req)
-
-    self._is_tracing_running = False
-    self._start_issued = False
-    self._can_collect_data = True
-
-  def DumpMemory(self, timeout=30):
-    """Dumps memory.
-
-    Returns:
-      GUID of the generated dump if successful, None otherwise.
-
-    Raises:
-      TracingTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      TracingUnrecoverableException: If there is a websocket error.
-      TracingUnexpectedResponseException: If the response contains an error
-      or does not contain the expected result.
-    """
-    request = {
-      'method': 'Tracing.requestMemoryDump'
-    }
-    try:
-      response = self._inspector_websocket.SyncRequest(request, timeout)
-    except websocket.WebSocketTimeoutException:
-      raise TracingTimeoutException(
-          'Exception raised while sending a Tracing.requestMemoryDump '
-          'request:\n' + traceback.format_exc())
-    except (socket.error, websocket.WebSocketException,
-            inspector_websocket.WebSocketDisconnected):
-      raise TracingUnrecoverableException(
-          'Exception raised while sending a Tracing.requestMemoryDump '
-          'request:\n' + traceback.format_exc())
-
-
-    if ('error' in response or
-        'result' not in response or
-        'success' not in response['result'] or
-        'dumpGuid' not in response['result']):
-      raise TracingUnexpectedResponseException(
-          'Inspector returned unexpected response for '
-          'Tracing.requestMemoryDump:\n' + json.dumps(response, indent=2))
-
-    result = response['result']
-    return result['dumpGuid'] if result['success'] else None
-
-  def CollectTraceData(self, trace_data_builder, timeout=60):
-    if not self._can_collect_data:
-      raise Exception('Cannot collect before tracing is finished.')
-    self._CollectTracingData(trace_data_builder, timeout)
-    self._can_collect_data = False
-
-  def _CollectTracingData(self, trace_data_builder, timeout):
-    """Collects tracing data. Assumes that Tracing.end has already been sent.
-
-    Args:
-      trace_data_builder: An instance of TraceDataBuilder to put results into.
-      timeout: The timeout in seconds.
-
-    Raises:
-      TracingTimeoutException: If more than |timeout| seconds has passed
-      since the last time any data is received.
-      TracingUnrecoverableException: If there is a websocket error.
-    """
-    self._has_received_all_tracing_data = False
-    start_time = time.time()
-    self._trace_data_builder = trace_data_builder
-    try:
-      while True:
-        try:
-          self._inspector_websocket.DispatchNotifications(timeout)
-          start_time = time.time()
-        except websocket.WebSocketTimeoutException:
-          pass
-        except (socket.error, websocket.WebSocketException):
-          raise TracingUnrecoverableException(
-              'Exception raised while collecting tracing data:\n' +
-                  traceback.format_exc())
-
-        if self._has_received_all_tracing_data:
-          break
-
-        elapsed_time = time.time() - start_time
-        if elapsed_time > timeout:
-          raise TracingTimeoutException(
-              'Only received partial trace data due to timeout after %s '
-              'seconds. If the trace data is big, you may want to increase '
-              'the timeout amount.' % elapsed_time)
-    finally:
-      self._trace_data_builder = None
-
-  def _NotificationHandler(self, res):
-    if 'Tracing.dataCollected' == res.get('method'):
-      value = res.get('params', {}).get('value')
-      self._trace_data_builder.AddTraceFor(
-        trace_data_module.CHROME_TRACE_PART, value)
-    elif 'Tracing.tracingComplete' == res.get('method'):
-      stream_handle = res.get('params', {}).get('stream')
-      if not stream_handle:
-        self._has_received_all_tracing_data = True
-        return
-      reader = _DevToolsStreamReader(self._inspector_websocket, stream_handle)
-      reader.Read(self._ReceivedAllTraceDataFromStream)
-
-  def _ReceivedAllTraceDataFromStream(self, trace_handle):
-    self._trace_data_builder.AddTraceFor(
-        trace_data_module.CHROME_TRACE_PART, trace_handle)
-    self._has_received_all_tracing_data = True
-
-  def Close(self):
-    self._inspector_websocket.UnregisterDomain(self._TRACING_DOMAIN)
-    self._inspector_websocket = None
-
-  @decorators.Cache
-  def IsTracingSupported(self):
-    req = {'method': 'Tracing.hasCompleted'}
-    res = self._inspector_websocket.SyncRequest(req, timeout=10)
-    return not res.get('response')
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/tracing_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/tracing_backend_unittest.py
deleted file mode 100644
index 3f793ee..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/tracing_backend_unittest.py
+++ /dev/null
@@ -1,285 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import timeit
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.backends.chrome_inspector import tracing_backend
-from telemetry.internal.backends.chrome_inspector.tracing_backend import _DevToolsStreamReader
-from telemetry.testing import fakes
-from telemetry.testing import tab_test_case
-from telemetry.timeline import chrome_trace_config
-from telemetry.timeline import model as model_module
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data
-
-
-class TracingBackendTest(tab_test_case.TabTestCase):
-
-  # Number of consecutively requested memory dumps.
-  _REQUESTED_DUMP_COUNT = 3
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.logging_verbosity = options.VERBOSE_LOGGING
-    options.AppendExtraBrowserArgs([
-        # Memory maps currently cannot be retrieved on sandboxed processes.
-        # See crbug.com/461788.
-        '--no-sandbox',
-    ])
-
-  def setUp(self):
-    super(TracingBackendTest, self).setUp()
-    self._tracing_controller = self._browser.platform.tracing_controller
-    if not self._tracing_controller.IsChromeTracingSupported():
-      self.skipTest('Browser does not support tracing, skipping test.')
-    if not self._browser.supports_memory_dumping:
-      self.skipTest('Browser does not support memory dumping, skipping test.')
-
-  # win: https://github.com/catapult-project/catapult/issues/3131.
-  # chromeos: http://crbug.com/622836.
-  @decorators.Disabled('win', 'chromeos')
-  def testDumpMemorySuccess(self):
-    # Check that dumping memory before tracing starts raises an exception.
-    self.assertRaises(Exception, self._browser.DumpMemory)
-
-    # Start tracing with memory dumps enabled.
-    config = tracing_config.TracingConfig()
-    config.chrome_trace_config.category_filter.AddDisabledByDefault(
-        'disabled-by-default-memory-infra')
-    config.chrome_trace_config.SetMemoryDumpConfig(
-        chrome_trace_config.MemoryDumpConfig())
-    config.enable_chrome_trace = True
-    self._tracing_controller.StartTracing(config)
-
-    # Request several memory dumps in a row and test that they were all
-    # successfully created with unique IDs.
-    expected_dump_ids = []
-    for _ in xrange(self._REQUESTED_DUMP_COUNT):
-      dump_id = self._browser.DumpMemory()
-      self.assertIsNotNone(dump_id)
-      self.assertNotIn(dump_id, expected_dump_ids)
-      expected_dump_ids.append(dump_id)
-
-    tracing_data = self._tracing_controller.StopTracing()
-
-    # Check that clock sync data is in tracing data.
-    clock_sync_found = False
-    trace = tracing_data.GetTraceFor(trace_data.CHROME_TRACE_PART)
-    for event in trace['traceEvents']:
-      if event['name'] == 'clock_sync' or 'ClockSyncEvent' in event['name']:
-        clock_sync_found = True
-        break
-    self.assertTrue(clock_sync_found)
-
-    # Check that dumping memory after tracing stopped raises an exception.
-    self.assertRaises(Exception, self._browser.DumpMemory)
-
-    # Test that trace data is parsable.
-    model = model_module.TimelineModel(tracing_data)
-    self.assertGreater(len(model.processes), 0)
-
-    # Test that the resulting model contains the requested memory dumps in the
-    # correct order (and nothing more).
-    actual_dump_ids = [d.dump_id for d in model.IterGlobalMemoryDumps()]
-    self.assertEqual(actual_dump_ids, expected_dump_ids)
-
-  def testDumpMemoryFailure(self):
-    # Check that dumping memory before tracing starts raises an exception.
-    self.assertRaises(Exception, self._browser.DumpMemory)
-
-    # Start tracing with memory dumps disabled.
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    self._tracing_controller.StartTracing(config)
-
-    # Check that the method returns None if the dump was not successful.
-    self.assertIsNone(self._browser.DumpMemory())
-
-    tracing_data = self._tracing_controller.StopTracing()
-
-    # Check that dumping memory after tracing stopped raises an exception.
-    self.assertRaises(Exception, self._browser.DumpMemory)
-
-    # Test that trace data is parsable.
-    model = model_module.TimelineModel(tracing_data)
-    self.assertGreater(len(model.processes), 0)
-
-    # Test that the resulting model contains no memory dumps.
-    self.assertEqual(len(list(model.IterGlobalMemoryDumps())), 0)
-
-
-class TracingBackendUnittest(unittest.TestCase):
-  def setUp(self):
-    self._fake_timer = fakes.FakeTimer(tracing_backend)
-    self._inspector_socket = fakes.FakeInspectorWebsocket(self._fake_timer)
-
-  def tearDown(self):
-    self._fake_timer.Restore()
-
-  def _GetRawChromeTracesFor(self, trace_data_builder):
-    data = trace_data_builder.AsData().GetTracesFor(
-        trace_data.CHROME_TRACE_PART)
-    traces = []
-    for d in data:
-      traces.append(d)
-    return traces
-
-  def testCollectTracingDataTimeout(self):
-    self._inspector_socket.AddEvent(
-        'Tracing.dataCollected', {'value': {'traceEvents': [{'ph': 'B'}]}}, 9)
-    self._inspector_socket.AddEvent(
-        'Tracing.dataCollected', {'value': {'traceEvents': [{'ph': 'E'}]}}, 19)
-    self._inspector_socket.AddEvent('Tracing.tracingComplete', {}, 35)
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-
-    trace_data_builder = trace_data.TraceDataBuilder()
-    # The third response is 16 seconds after the second response, so we expect
-    # a TracingTimeoutException.
-    with self.assertRaises(tracing_backend.TracingTimeoutException):
-      backend._CollectTracingData(trace_data_builder, 10)
-    traces = self._GetRawChromeTracesFor(trace_data_builder)
-    self.assertEqual(2, len(traces))
-    self.assertEqual(1, len(traces[0].get('traceEvents', [])))
-    self.assertEqual(1, len(traces[1].get('traceEvents', [])))
-    self.assertFalse(backend._has_received_all_tracing_data)
-
-  def testCollectTracingDataNoTimeout(self):
-    self._inspector_socket.AddEvent(
-        'Tracing.dataCollected', {'value': {'traceEvents': [{'ph': 'B'}]}}, 9)
-    self._inspector_socket.AddEvent(
-        'Tracing.dataCollected', {'value': {'traceEvents': [{'ph': 'E'}]}}, 14)
-    self._inspector_socket.AddEvent('Tracing.tracingComplete', {}, 19)
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-    trace_data_builder = trace_data.TraceDataBuilder()
-    backend._CollectTracingData(trace_data_builder, 10)
-    traces = self._GetRawChromeTracesFor(trace_data_builder)
-    self.assertEqual(2, len(traces))
-    self.assertEqual(1, len(traces[0].get('traceEvents', [])))
-    self.assertEqual(1, len(traces[1].get('traceEvents', [])))
-    self.assertTrue(backend._has_received_all_tracing_data)
-
-  def testCollectTracingDataFromStreamNoContainer(self):
-    self._inspector_socket.AddEvent(
-        'Tracing.tracingComplete', {'stream': '42'}, 1)
-    self._inspector_socket.AddAsyncResponse(
-        'IO.read', {'data': '{"traceEvents": [{},{},{'}, 2)
-    self._inspector_socket.AddAsyncResponse(
-        'IO.read', {'data': '},{},{}]}', 'eof': True}, 3)
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-    trace_data_builder = trace_data.TraceDataBuilder()
-    backend._CollectTracingData(trace_data_builder, 10)
-    trace_events = self._GetRawChromeTracesFor(trace_data_builder)[0].get(
-        'traceEvents', [])
-    self.assertEqual(5, len(trace_events))
-    self.assertTrue(backend._has_received_all_tracing_data)
-
-  def testCollectTracingDataFromStreamJSONContainer(self):
-    self._inspector_socket.AddEvent(
-        'Tracing.tracingComplete', {'stream': '42'}, 1)
-    self._inspector_socket.AddAsyncResponse(
-        'IO.read', {'data': '{"traceEvents": [{},{},{}],'}, 2)
-    self._inspector_socket.AddAsyncResponse(
-        'IO.read', {'data': '"metadata": {"a": "b"}'}, 3)
-    self._inspector_socket.AddAsyncResponse(
-        'IO.read', {'data': '}', 'eof': True}, 4)
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-    trace_data_builder = trace_data.TraceDataBuilder()
-    backend._CollectTracingData(trace_data_builder, 10)
-    chrome_trace = self._GetRawChromeTracesFor(trace_data_builder)[0]
-
-    self.assertEqual(3, len(chrome_trace.get('traceEvents', [])))
-    self.assertEqual(dict, type(chrome_trace.get('metadata')))
-    self.assertTrue(backend._has_received_all_tracing_data)
-
-  def testDumpMemorySuccess(self):
-    self._inspector_socket.AddResponseHandler(
-        'Tracing.requestMemoryDump',
-        lambda req: {'result': {'success': True, 'dumpGuid': '42abc'}})
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-
-    self.assertEqual(backend.DumpMemory(), '42abc')
-
-  def testDumpMemoryFailure(self):
-    self._inspector_socket.AddResponseHandler(
-        'Tracing.requestMemoryDump',
-        lambda req: {'result': {'success': False, 'dumpGuid': '42abc'}})
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-
-    self.assertIsNone(backend.DumpMemory())
-
-  def testStartTracingFailure(self):
-    self._inspector_socket.AddResponseHandler(
-        'Tracing.start',
-        lambda req: {'error': {'message': 'Tracing is already started'}})
-    self._inspector_socket.AddResponseHandler(
-        'Tracing.hasCompleted', lambda req: {})
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-    config = tracing_config.TracingConfig()
-    self.assertRaisesRegexp(
-        tracing_backend.TracingUnexpectedResponseException,
-        'Tracing is already started',
-        backend.StartTracing, config.chrome_trace_config)
-
-  def testStartTracingWithoutCollection(self):
-    self._inspector_socket.AddResponseHandler('Tracing.start', lambda req: {})
-    self._inspector_socket.AddEvent(
-        'Tracing.dataCollected', {'value': [{'ph': 'B'}]}, 1)
-    self._inspector_socket.AddEvent(
-        'Tracing.dataCollected', {'value': [{'ph': 'E'}]}, 2)
-    self._inspector_socket.AddEvent('Tracing.tracingComplete', {}, 3)
-    self._inspector_socket.AddResponseHandler(
-        'Tracing.hasCompleted', lambda req: {})
-
-    backend = tracing_backend.TracingBackend(self._inspector_socket)
-    config = tracing_config.TracingConfig()
-    backend.StartTracing(config._chrome_trace_config)
-    backend.StopTracing()
-    with self.assertRaisesRegexp(AssertionError, 'Data not collected from .*'):
-      backend.StartTracing(config._chrome_trace_config)
-
-
-class DevToolsStreamPerformanceTest(unittest.TestCase):
-  def setUp(self):
-    self._fake_timer = fakes.FakeTimer(tracing_backend)
-    self._inspector_socket = fakes.FakeInspectorWebsocket(self._fake_timer)
-
-  def _MeasureReadTime(self, count):
-    fake_time = self._fake_timer.time() + 1
-    payload = ','.join(['{}'] * 5000)
-    self._inspector_socket.AddAsyncResponse('IO.read', {'data': '[' + payload},
-                                            fake_time)
-    startClock = timeit.default_timer()
-
-    done = {'done': False}
-    def mark_done(data):
-      del data  # unused
-      done['done'] = True
-
-    reader = _DevToolsStreamReader(self._inspector_socket, 'dummy')
-    reader.Read(mark_done)
-    while not done['done']:
-      fake_time += 1
-      if count > 0:
-        self._inspector_socket.AddAsyncResponse('IO.read', {'data': payload},
-            fake_time)
-      elif count == 0:
-        self._inspector_socket.AddAsyncResponse('IO.read',
-            {'data': payload + ']', 'eof': True}, fake_time)
-      count -= 1
-      self._inspector_socket.DispatchNotifications(10)
-    return timeit.default_timer() - startClock
-
-  def testReadTime(self):
-    n1 = 1000
-    while True:
-      t1 = self._MeasureReadTime(n1)
-      if t1 > 0.01:
-        break
-      n1 *= 5
-    t2 = self._MeasureReadTime(n1 * 10)
-    # Time is an illusion, CPU time is doubly so, allow great deal of tolerance.
-    toleranceFactor = 5
-    self.assertLess(t2, t1 * 10 * toleranceFactor)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/websocket.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/websocket.py
deleted file mode 100644
index 2195cb6..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/websocket.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from __future__ import absolute_import
-
-import socket
-
-# pylint: disable=unused-import
-from websocket import create_connection as _create_connection
-from websocket import WebSocketConnectionClosedException
-from websocket import WebSocketException
-from websocket import WebSocketTimeoutException
-
-
-def create_connection(*args, **kwargs):
-  sockopt = kwargs.get('sockopt', [])
-
-  # By default, we set SO_REUSEADDR on all websockets used by Telemetry.
-  # This prevents spurious address in use errors on Windows.
-  #
-  # TODO(tonyg): We may want to set SO_NODELAY here as well.
-  sockopt.append((socket.SOL_SOCKET, socket.SO_REUSEADDR, 1))
-
-  kwargs['sockopt'] = sockopt
-  return _create_connection(*args, **kwargs)
diff --git a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/websocket_unittest.py b/catapult/telemetry/telemetry/internal/backends/chrome_inspector/websocket_unittest.py
deleted file mode 100644
index 426043e..0000000
--- a/catapult/telemetry/telemetry/internal/backends/chrome_inspector/websocket_unittest.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import base64
-import BaseHTTPServer
-import hashlib
-import socket
-import threading
-import unittest
-
-from telemetry.internal.backends.chrome_inspector import websocket
-
-
-# Minimal handler for a local websocket server.
-class _FakeWebSocketHandler(BaseHTTPServer.BaseHTTPRequestHandler):
-  def do_GET(self):
-    key = self.headers.getheader('Sec-WebSocket-Key')
-
-    value = key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'
-    hashed = base64.encodestring(hashlib.sha1(value).digest()).strip().lower()
-
-    self.send_response(101)
-
-    self.send_header('Sec-Websocket-Accept', hashed)
-    self.send_header('upgrade', 'websocket')
-    self.send_header('connection', 'upgrade')
-    self.end_headers()
-
-    self.wfile.flush()
-
-
-class TestWebSocket(unittest.TestCase):
-  def testExports(self):
-    self.assertNotEqual(websocket.create_connection, None)
-    self.assertNotEqual(websocket.WebSocketException, None)
-    self.assertNotEqual(websocket.WebSocketTimeoutException, None)
-
-  def testSockOpts(self):
-    httpd = BaseHTTPServer.HTTPServer(('127.0.0.1', 0), _FakeWebSocketHandler)
-    ws_url = 'ws://127.0.0.1:%d' % httpd.server_port
-
-    threading.Thread(target=httpd.handle_request).start()
-    ws = websocket.create_connection(ws_url)
-    try:
-      self.assertNotEquals(
-          ws.sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR), 0)
-    finally:
-      ws.close()
-
-    threading.Thread(target=httpd.handle_request).start()
-    ws = websocket.create_connection(
-        ws_url,
-        sockopt=[(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)])
-    try:
-      self.assertNotEquals(
-          ws.sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR), 0)
-      self.assertNotEquals(
-          ws.sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY), 0)
-    finally:
-      ws.close()
diff --git a/catapult/telemetry/telemetry/internal/backends/codepen_credentials_backend.py b/catapult/telemetry/telemetry/internal/backends/codepen_credentials_backend.py
deleted file mode 100644
index 6cd1a57..0000000
--- a/catapult/telemetry/telemetry/internal/backends/codepen_credentials_backend.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.backends import form_based_credentials_backend
-
-
-class CodePenCredentialsBackend(
-    form_based_credentials_backend.FormBasedCredentialsBackend):
-
-  @property
-  def logged_in_javascript(self):
-    """Evaluates to true iff already logged in."""
-    return 'document.querySelector(".login-area") === null'
-
-  @property
-  def credentials_type(self):
-    return 'codepen'
-
-  @property
-  def url(self):
-    return 'https://codepen.io/login'
-
-  @property
-  def login_form_id(self):
-    return 'login-login-form'
-
-  @property
-  def login_button_javascript(self):
-    return """
-        LoginSettings.timeOnPageStartTime = 0;
-        document.getElementById("log-in-button").click();
-        """
-
-  @property
-  def login_input_id(self):
-    return 'login-email-field'
-
-  @property
-  def password_input_id(self):
-    return 'login-password-field_'
diff --git a/catapult/telemetry/telemetry/internal/backends/codepen_credentials_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/codepen_credentials_backend_unittest.py
deleted file mode 100644
index 2dc8ce7..0000000
--- a/catapult/telemetry/telemetry/internal/backends/codepen_credentials_backend_unittest.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.internal.backends import codepen_credentials_backend
-from telemetry.internal.backends \
-      import form_based_credentials_backend_unittest_base
-
-
-class TestCodePenCredentialsBackend(
-    form_based_credentials_backend_unittest_base.
-    FormBasedCredentialsBackendUnitTestBase):
-  def setUp(self):
-    self._credentials_type = 'codepen'
-
-  def testLoginUsingMock(self):
-    backend = codepen_credentials_backend.CodePenCredentialsBackend()
-    self._LoginUsingMock(backend, backend.url, backend.login_input_id,
-                         backend.password_input_id, backend.login_form_id,
-                         backend.logged_in_javascript)
diff --git a/catapult/telemetry/telemetry/internal/backends/facebook_credentials_backend.py b/catapult/telemetry/telemetry/internal/backends/facebook_credentials_backend.py
deleted file mode 100644
index b1a25dc..0000000
--- a/catapult/telemetry/telemetry/internal/backends/facebook_credentials_backend.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.backends import form_based_credentials_backend
-
-
-class FacebookCredentialsBackend(
-    form_based_credentials_backend.FormBasedCredentialsBackend):
-
-  @property
-  def logged_in_javascript(self):
-    """Evaluates to true iff already logged in."""
-    return ('document.getElementById("fbNotificationsList")!== null || '
-            'document.getElementById("m_home_notice")!== null')
-
-  @property
-  def credentials_type(self):
-    return 'facebook'
-
-  @property
-  def url(self):
-    return 'http://www.facebook.com/'
-
-  @property
-  def login_form_id(self):
-    return 'login_form'
-
-  @property
-  def login_input_id(self):
-    return 'email'
-
-  @property
-  def password_input_id(self):
-    return 'pass'
-
-class FacebookCredentialsBackend2(FacebookCredentialsBackend):
-  """ Facebook credential backend for https client. """
-
-  @property
-  def credentials_type(self):
-    return 'facebook2'
-
-  @property
-  def url(self):
-    return 'https://www.facebook.com/'
diff --git a/catapult/telemetry/telemetry/internal/backends/facebook_credentials_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/facebook_credentials_backend_unittest.py
deleted file mode 100644
index bbcd34a..0000000
--- a/catapult/telemetry/telemetry/internal/backends/facebook_credentials_backend_unittest.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.internal.backends import facebook_credentials_backend
-from telemetry.internal.backends \
-       import form_based_credentials_backend_unittest_base
-
-
-class TestFacebookCredentialsBackend(
-    form_based_credentials_backend_unittest_base.
-    FormBasedCredentialsBackendUnitTestBase):
-  def setUp(self):
-    self._credentials_type = 'facebook'
-
-  def testLoginUsingMock(self):
-    backend = facebook_credentials_backend.FacebookCredentialsBackend()
-    self._LoginUsingMock(backend, backend.url, backend.login_input_id,
-                         backend.password_input_id, backend.login_form_id,
-                         backend.logged_in_javascript)
diff --git a/catapult/telemetry/telemetry/internal/backends/form_based_credentials_backend.py b/catapult/telemetry/telemetry/internal/backends/form_based_credentials_backend.py
deleted file mode 100644
index 5fc29e4..0000000
--- a/catapult/telemetry/telemetry/internal/backends/form_based_credentials_backend.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-
-from telemetry import decorators
-
-import py_utils
-
-
-class FormBasedCredentialsBackend(object):
-  def __init__(self):
-    self._logged_in = False
-
-  def IsAlreadyLoggedIn(self, tab):
-    return tab.EvaluateJavaScript(self.logged_in_javascript)
-
-  @property
-  def credentials_type(self):
-    raise NotImplementedError()
-
-  @property
-  def url(self):
-    raise NotImplementedError()
-
-  @property
-  def login_form_id(self):
-    raise NotImplementedError()
-
-  @property
-  def login_button_javascript(self):
-    """Some sites have custom JS to log in."""
-    return None
-
-  @property
-  def login_input_id(self):
-    raise NotImplementedError()
-
-  @property
-  def password_input_id(self):
-    raise NotImplementedError()
-
-  @property
-  def logged_in_javascript(self):
-    """Evaluates to true iff already logged in."""
-    raise NotImplementedError()
-
-  def IsLoggedIn(self):
-    return self._logged_in
-
-  def _ResetLoggedInState(self):
-    """Makes the backend think we're not logged in even though we are.
-    Should only be used in unit tests to simulate --dont-override-profile.
-    """
-    self._logged_in = False
-
-  def _WaitForLoginState(self, action_runner):
-    """Waits until it can detect either the login form, or already logged in."""
-    action_runner.WaitForJavaScriptCondition(
-        '(document.querySelector({{ form_id }}) !== null) || ({{ @code }})',
-        form_id='#' + self.login_form_id, code=self.logged_in_javascript,
-        timeout=60)
-
-  def _SubmitLoginFormAndWait(self, action_runner, tab, username, password):
-    """Submits the login form and waits for the navigation."""
-    tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-    tab.ExecuteJavaScript(
-        'document.querySelector({{ selector }}).value = {{ username }};',
-        selector='#%s #%s' % (self.login_form_id, self.login_input_id),
-        username=username)
-    tab.ExecuteJavaScript(
-        'document.querySelector({{ selector }}).value = {{ password }};',
-        selector='#%s #%s' % (self.login_form_id, self.password_input_id),
-        password=password)
-    if self.login_button_javascript:
-      tab.ExecuteJavaScript(self.login_button_javascript)
-    else:
-      tab.ExecuteJavaScript(
-          'document.getElementById({{ form_id }}).submit();',
-          form_id=self.login_form_id)
-    # Wait for the form element to disappear as confirmation of the navigation.
-    action_runner.WaitForNavigate()
-
-  # pylint: disable=line-too-long
-  @decorators.Deprecated(2017, 5, 5,
-                         'FormBasedCredentialsBackend is deprecated. Use the '
-                         'login helper modules in '
-                         'https://code.google.com/p/chromium/codesearch#chromium/src/tools/perf/page_sets/login_helpers/'
-                         ' instead.')
-  # pylint: enable=line-too-long
-  def LoginNeeded(self, tab, action_runner, config):
-    """Logs in to a test account.
-
-    Raises:
-      RuntimeError: if could not get credential information.
-    """
-    if self._logged_in:
-      return True
-
-    if 'username' not in config or 'password' not in config:
-      message = ('Credentials for "%s" must include username and password.' %
-                 self.credentials_type)
-      raise RuntimeError(message)
-
-    logging.debug('Logging into %s account...' % self.credentials_type)
-
-    if 'url' in config:
-      url = config['url']
-    else:
-      url = self.url
-
-    try:
-      logging.info('Loading %s...', url)
-      tab.Navigate(url)
-      self._WaitForLoginState(action_runner)
-
-      if self.IsAlreadyLoggedIn(tab):
-        self._logged_in = True
-        return True
-
-      self._SubmitLoginFormAndWait(
-          action_runner, tab, config['username'], config['password'])
-
-      self._logged_in = True
-      return True
-    except py_utils.TimeoutException:
-      logging.warning('Timed out while loading: %s', url)
-      return False
-
-  def LoginNoLongerNeeded(self, tab): # pylint: disable=unused-argument
-    assert self._logged_in
diff --git a/catapult/telemetry/telemetry/internal/backends/form_based_credentials_backend_unittest_base.py b/catapult/telemetry/telemetry/internal/backends/form_based_credentials_backend_unittest_base.py
deleted file mode 100644
index 59b4e77..0000000
--- a/catapult/telemetry/telemetry/internal/backends/form_based_credentials_backend_unittest_base.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.testing import simple_mock
-
-_ = simple_mock.DONT_CARE
-
-
-class FormBasedCredentialsBackendUnitTestBase(unittest.TestCase):
-  def setUp(self):
-    self._credentials_type = None
-
-  def testLoginUsingMock(self):
-    raise NotImplementedError()
-
-  def _LoginUsingMock(self, backend, login_page_url, email_element_id,
-                      password_element_id, form_element_id,
-                      already_logged_in_js): # pylint: disable=no-self-use
-    del form_element_id  # Unused.
-    del email_element_id  # Unused.
-    del password_element_id  # Unused.
-    tab = simple_mock.MockObject()
-    ar = simple_mock.MockObject()
-
-    config = {'username': 'blah',
-              'password': 'blargh'}
-
-    tab.ExpectCall('Navigate', login_page_url)
-    tab.ExpectCall(
-        'EvaluateJavaScript', already_logged_in_js).WillReturn(False)
-    tab.ExpectCall('WaitForDocumentReadyStateToBeInteractiveOrBetter')
-
-    ar.ExpectCall(
-        'WaitForJavaScriptCondition',
-        '(document.querySelector({{ form_id }}) !== null) || ({{ @code }})')
-    ar.ExpectCall('WaitForNavigate')
-
-    def VerifyEmail(js):
-      assert '{{ selector }}' in js
-      assert '{{ username }}' in js
-    tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifyEmail)
-
-    def VerifyPw(js):
-      assert '{{ selector }}' in js
-      assert '{{ password }}' in js
-    tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifyPw)
-
-    def VerifySubmit(js):
-      assert '.submit' in js or '.click' in js
-    tab.ExpectCall('ExecuteJavaScript', _).WhenCalled(VerifySubmit)
-
-    # Checking for form still up.
-    tab.ExpectCall('EvaluateJavaScript', _).WillReturn(False)
-
-    backend.LoginNeeded(tab, ar, config)
diff --git a/catapult/telemetry/telemetry/internal/backends/google_credentials_backend.py b/catapult/telemetry/telemetry/internal/backends/google_credentials_backend.py
deleted file mode 100644
index 0c43182..0000000
--- a/catapult/telemetry/telemetry/internal/backends/google_credentials_backend.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.backends import form_based_credentials_backend
-
-
-class GoogleCredentialsBackend(
-    form_based_credentials_backend.FormBasedCredentialsBackend):
-
-  @property
-  def logged_in_javascript(self):
-    """Evaluates to true iff already logged in."""
-    return 'document.getElementById("gb")!== null'
-
-  @property
-  def credentials_type(self):
-    return 'google'
-
-  @property
-  def url(self):
-    # pylint: disable=line-too-long
-    # WPR doesn't support having 2 responses for the same URL (with/without
-    # session cookie), so after login behaviour differs with/without wpr.
-    # Sign-in URL is specified directly to overcome this.
-    return 'https://accounts.google.com/ServiceLogin?continue=https%3A%2F%2Faccounts.google.com%2FManageAccount'
-
-  @property
-  def login_form_id(self):
-    return 'gaia_loginform'
-
-  @property
-  def login_input_id(self):
-    return 'Email'
-
-  @property
-  def password_input_id(self):
-    return 'Passwd'
-
-
-class GoogleCredentialsBackend2(GoogleCredentialsBackend):
-  """ Google credential backend for google2 credential. """
-
-  @property
-  def credentials_type(self):
-    return 'google2'
diff --git a/catapult/telemetry/telemetry/internal/backends/google_credentials_backend_unittest.py b/catapult/telemetry/telemetry/internal/backends/google_credentials_backend_unittest.py
deleted file mode 100644
index b30c051..0000000
--- a/catapult/telemetry/telemetry/internal/backends/google_credentials_backend_unittest.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.internal.backends import\
-       form_based_credentials_backend_unittest_base
-from telemetry.internal.backends import google_credentials_backend
-
-
-class TestGoogleCredentialsBackend(
-    form_based_credentials_backend_unittest_base.
-    FormBasedCredentialsBackendUnitTestBase):
-  def setUp(self):
-    self._credentials_type = 'google'
-
-  def testLoginUsingMock(self):
-    backend = google_credentials_backend.GoogleCredentialsBackend()
-    self._LoginUsingMock(backend, backend.url, backend.login_input_id,
-                         backend.password_input_id, backend.login_form_id,
-                         backend.logged_in_javascript)
diff --git a/catapult/telemetry/telemetry/internal/bin/README.md b/catapult/telemetry/telemetry/internal/bin/README.md
deleted file mode 100644
index eb42425..0000000
--- a/catapult/telemetry/telemetry/internal/bin/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-<!-- Copyright 2015 The Chromium Authors. All rights reserved.
-     Use of this source code is governed by a BSD-style license that can be
-     found in the LICENSE file.
--->
-Do not check files into this folder.
-____________________________________
-Files are downloaded to this folder from cloud storage by the BinaryManager,
-and any local files may be overwritten without warning.
diff --git a/catapult/telemetry/telemetry/internal/binary_dependencies.json b/catapult/telemetry/telemetry/internal/binary_dependencies.json
deleted file mode 100644
index c841c40..0000000
--- a/catapult/telemetry/telemetry/internal/binary_dependencies.json
+++ /dev/null
@@ -1,323 +0,0 @@
-{
-  "config_type": "BaseConfig",
-  "dependencies": {
-    "avconv": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "03896ec9bdc9f1d6fa388f893d8f62f454e7e707",
-          "download_path": "bin/linux/x86_64/avconv"
-        }
-      }
-    },
-    "bitmaptools": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "661ce936b3276f7ec3d687ab62be05b96d796f21",
-          "download_path": "bin/linux/x86_64/bitmaptools"
-        },
-        "mac_x86_64": {
-          "cloud_storage_hash": "c7b1bfc6399dc683058e88dac1ef0f877edea74b",
-          "download_path": "bin/mac/x86_64/bitmaptools"
-        },
-        "win_AMD64": {
-          "cloud_storage_hash": "ac4fee89a51662b9d920bce443c19b9b2929b198",
-          "download_path": "bin/win/AMD64/bitmaptools.exe"
-        },
-        "win_x86": {
-          "cloud_storage_hash": "ac4fee89a51662b9d920bce443c19b9b2929b198",
-          "download_path": "bin/win/x86/bitmaptools.exe"
-        }
-      }
-    },
-    "clear_system_cache": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "20739db88864685f6a0be66879e34a83813352cc",
-          "download_path": "bin/linux/x86_64/clear_system_cache"
-        },
-        "mac_x86_64": {
-          "cloud_storage_hash": "0f0ef42a9223592fa234ee5d248f6216fee2b677",
-          "download_path": "bin/mac/x86_64/clear_system_cache"
-        },
-        "win_AMD64": {
-          "cloud_storage_hash": "afe4fc71151f3aa176bc7137f0f6c9396bc18f3b",
-          "download_path": "bin/win/AMD64/clear_system_cache.exe"
-        }
-      }
-    },
-    "determine_if_keychain_entry_is_decryptable": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "mac_x86_64": {
-          "cloud_storage_hash": "5daabb8e5d485a99efc9139634a8242fa60a25e7",
-          "download_path": "bin/mac/x86_64/determine_if_keychain_entry_is_decryptable"
-        }
-      }
-    },
-    "determine_if_keychain_is_locked": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "mac_x86_64": {
-          "cloud_storage_hash": "13a57efae9a680ac0f160b3567e02e81f4ac493c",
-          "download_path": "bin/mac/x86_64/determine_if_keychain_is_locked"
-        }
-      }
-    },
-    "device_forwarder": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "90cc60cefb497512d95d774045146754c477b433",
-          "download_path": "bin/android/arm64-v8a/device_forwarder"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "3a5ade8fbaffea3b0670bffaa845288db5e4d567",
-          "download_path": "bin/android/armeabi-v7a/device_forwarder"
-        }
-      }
-    },
-    "file_poller": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "fd5b417f78c7f7d9192a98967058709ded1d399d",
-          "download_path": "bin/android/arm64-v8a/file_poller"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "cf5c8fe920378ce30d057e76591d57f63fd31c1a",
-          "download_path": "bin/android/armeabi-v7a/file_poller"
-        }
-      }
-    },
-    "gdb": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm": {
-          "cloud_storage_hash": "9231584d135fb76bb7075d96ce387679de7ada7b",
-          "download_path": "bin/android/arm/arm-linux-androideabi-gdb"
-        },
-        "android_x64": {
-          "cloud_storage_hash": "09177be2fed00b44df0e777932828425440b23b3",
-          "download_path": "bin/android/x64/x86_64-linux-androideabi-gdb"
-        },
-        "android_x86": {
-          "cloud_storage_hash": "bcf02af039713a48b69b89bd7f0f9c81ed8183a4",
-          "download_path": "bin/android/x86/i686-linux-androideabi-gdb"
-        }
-      }
-    },
-    "host_forwarder": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "63653293098d7fe17aa115b147c8d9aa253b0912",
-          "download_path": "bin/linux/x86_64/host_forwarder"
-        }
-      }
-    },
-    "hprof-conv": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "0b14eeee2e2a51cc94e361295379f69ee6f7cf8f",
-          "download_path": "../bin/linux/x86_64/hprof-conv"
-        }
-      }
-    },
-    "ipfw": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "0c96ed5a618083100cb2269e9c0400ef73708351",
-          "download_path": "bin/linux/x86_64/ipfw"
-        }
-      }
-    },
-    "ipfw_mod": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "91d3336cec855d4ed4aafadf7f9d496f3c09b07c",
-          "download_path": "bin/linux/x86_64/ipfw_mod.ko"
-        }
-      }
-    },
-    "md5sum_bin": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "fca070d85c5c732bc6fb098fc061f53474148dc0",
-          "download_path": "bin/android/arm64-v8a/md5sum_bin"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "293c093c4487b2f1cdff6ed8c93b0214e45c4e7c",
-          "download_path": "bin/android/armeabi-v7a/md5sum_bin"
-        }
-      }
-    },
-    "md5sum_bin_host": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "1f5060df87c9332d423bf25a31ffcd4c6c0ef1bf",
-          "download_path": "bin/linux/x86_64/md5sum_bin_host"
-        },
-        "mac_x86_64": {
-          "cloud_storage_hash": "b068e3ba81a1fb7dbfe121edd2dac0c3942eb7e6",
-          "download_path": "bin/mac/x86_64/md5sum_bin_host"
-        }
-      }
-    },
-    "memtrack_helper": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "c80618de34416bb095562df1c4d2fcf725576ba6",
-          "download_path": "bin/android/arm64-v8a/memtrack_helper"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "cb4437cd23e4e34fbf7930c02da496975c281004",
-          "download_path": "bin/android/armeabi-v7a/memtrack_helper"
-        }
-      }
-    },
-    "minidump_dump": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "7e3711b77837f7851f0be5022ecf086f82225809",
-          "download_path": "bin/linux/x86_64/minidump_dump"
-        },
-        "mac_x86_64": {
-          "cloud_storage_hash": "c39bd7a3b9fa6279893b2d759045699d79ce4dcb",
-          "download_path": "bin/mac/x86_64/minidump_dump"
-        }
-      }
-    },
-    "minidump_stackwalk": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "9eac751ac8618d7cc3514792719c05e7722e9bdc",
-          "download_path": "bin/linux/x86_64/minidump_stackwalk"
-        },
-        "mac_x86_64": {
-          "cloud_storage_hash": "76c5983fc9e9316a9d4251ba3e68b955c4fc9bf3",
-          "download_path": "bin/mac/x86_64/minidump_stackwalk"
-        }
-      }
-    },
-    "perf": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "a43abae56791cf7de2b6f0fcbb0f06035b9e4b07",
-          "download_path": "bin/android/arm64-v8a/perf"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "c0173517d500728a8755eefcc1ed26ba31fce13b",
-          "download_path": "bin/android/armeabi-v7a/perf"
-        }
-      }
-    },
-    "perfhost": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "ddb9b3508fe3e8b056071fc7c3d069d13635d371",
-          "download_path": "bin/linux/x86_64/perfhost"
-        }
-      }
-    },
-    "perfhost_precise": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "ddb9b3508fe3e8b056071fc7c3d069d13635d371",
-          "download_path": "bin/linux/x86_64/perfhost_precise"
-        }
-      }
-    },
-    "perfhost_trusty": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "cd0980a3a0b119bc4764bbbac53429e1d9013e70",
-          "download_path": "bin/linux/x86_64/perfhost_trusty"
-        }
-      }
-    },
-    "purge_ashmem": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "fb1ef95e54208564418494b016ac525594370db8",
-          "download_path": "bin/android/arm64-v8a/purge_ashmem"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "9c1a2aad6e92b1f407428a972c8acf036c039287",
-          "download_path": "bin/android/armeabi-v7a/purge_ashmem"
-        }
-      }
-    },
-    "push_apps_to_background_apk": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_arm64-v8a": {
-          "cloud_storage_hash": "5b724ddcb63405d1e23de80da9152bf84e72524d",
-          "download_path": "bin/android/arm64-v8a/PushAppsToBackground.apk"
-        },
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "5b724ddcb63405d1e23de80da9152bf84e72524d",
-          "download_path": "bin/android/armeabi-v7a/PushAppsToBackground.apk"
-        }
-      }
-    },
-    "tcpdump": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "android_armeabi-v7a": {
-          "cloud_storage_hash": "6cf2d56024208a08ceaf3a04ea98d5a362396fca",
-          "download_path": "bin/android/armeabi-v7a/tcpdump"
-        }
-      }
-    },
-    "winring0": {
-      "cloud_storage_base_folder": "binary_dependencies",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "win_AMD64": {
-          "cloud_storage_hash": "978305805fb52d838b3b4b09e9327da81f6973f7",
-          "download_path": "bin/win/AMD64/winring0.zip"
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/browser/__init__.py b/catapult/telemetry/telemetry/internal/browser/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/browser/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/browser/browser.py b/catapult/telemetry/telemetry/internal/browser/browser.py
deleted file mode 100644
index 2d40e64..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser.py
+++ /dev/null
@@ -1,365 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import sys
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.core import exceptions
-from telemetry.core import profiling_controller
-from telemetry import decorators
-from telemetry.internal import app
-from telemetry.internal.backends import browser_backend
-from telemetry.internal.browser import browser_credentials
-from telemetry.internal.browser import extension_dict
-from telemetry.internal.browser import tab_list
-from telemetry.internal.browser import web_contents
-from telemetry.internal.util import exception_formatter
-
-
-class Browser(app.App):
-  """A running browser instance that can be controlled in a limited way.
-
-  To create a browser instance, use browser_finder.FindBrowser.
-
-  Be sure to clean up after yourself by calling Close() when you are done with
-  the browser. Or better yet:
-    browser_to_create = FindBrowser(options)
-    with browser_to_create.Create(options) as browser:
-      ... do all your operations on browser here
-  """
-  def __init__(self, backend, platform_backend, credentials_path):
-    super(Browser, self).__init__(app_backend=backend,
-                                  platform_backend=platform_backend)
-    try:
-      self._browser_backend = backend
-      self._platform_backend = platform_backend
-      self._tabs = tab_list.TabList(backend.tab_list_backend)
-      self.credentials = browser_credentials.BrowserCredentials()
-      self.credentials.credentials_path = credentials_path
-      self._platform_backend.DidCreateBrowser(self, self._browser_backend)
-      browser_options = self._browser_backend.browser_options
-      self.platform.FlushDnsCache()
-      if browser_options.clear_sytem_cache_for_browser_and_profile_on_start:
-        if self.platform.CanFlushIndividualFilesFromSystemCache():
-          self.platform.FlushSystemCacheForDirectory(
-              self._browser_backend.profile_directory)
-          self.platform.FlushSystemCacheForDirectory(
-              self._browser_backend.browser_directory)
-        elif self.platform.SupportFlushEntireSystemCache():
-          self.platform.FlushEntireSystemCache()
-        else:
-          logging.warning('Flush system cache is not supported. ' +
-              'Did not flush system cache.')
-
-      self._browser_backend.SetBrowser(self)
-      self._browser_backend.Start()
-      self._LogBrowserInfo()
-      self._platform_backend.DidStartBrowser(self, self._browser_backend)
-      self._profiling_controller = profiling_controller.ProfilingController(
-          self._browser_backend.profiling_controller_backend)
-    except Exception:
-      exc_info = sys.exc_info()
-      logging.exception('Failure while starting browser backend.')
-      try:
-        self._platform_backend.WillCloseBrowser(self, self._browser_backend)
-      except Exception:
-        exception_formatter.PrintFormattedException(
-            msg='Exception raised while closing platform backend')
-      raise exc_info[0], exc_info[1], exc_info[2]
-
-  @property
-  def profiling_controller(self):
-    return self._profiling_controller
-
-  @property
-  def browser_type(self):
-    return self.app_type
-
-  @property
-  def supports_extensions(self):
-    return self._browser_backend.supports_extensions
-
-  @property
-  def supports_tab_control(self):
-    return self._browser_backend.supports_tab_control
-
-  @property
-  def tabs(self):
-    return self._tabs
-
-  @property
-  def foreground_tab(self):
-    for i in xrange(len(self._tabs)):
-      # The foreground tab is the first (only) one that isn't hidden.
-      # This only works through luck on Android, due to crbug.com/322544
-      # which means that tabs that have never been in the foreground return
-      # document.hidden as false; however in current code the Android foreground
-      # tab is always tab 0, which will be the first one that isn't hidden
-      if self._tabs[i].EvaluateJavaScript('!document.hidden'):
-        return self._tabs[i]
-    raise Exception("No foreground tab found")
-
-  @property
-  @decorators.Cache
-  def extensions(self):
-    if not self.supports_extensions:
-      raise browser_backend.ExtensionsNotSupportedException(
-          'Extensions not supported')
-    return extension_dict.ExtensionDict(self._browser_backend.extension_backend)
-
-  def _LogBrowserInfo(self):
-    logging.info('OS: %s %s',
-                 self._platform_backend.platform.GetOSName(),
-                 self._platform_backend.platform.GetOSVersionName())
-    if self.supports_system_info:
-      system_info = self.GetSystemInfo()
-      if system_info.model_name:
-        logging.info('Model: %s', system_info.model_name)
-      if system_info.gpu:
-        for i, device in enumerate(system_info.gpu.devices):
-          logging.info('GPU device %d: %s', i, device)
-        if system_info.gpu.aux_attributes:
-          logging.info('GPU Attributes:')
-          for k, v in sorted(system_info.gpu.aux_attributes.iteritems()):
-            logging.info('  %-20s: %s', k, v)
-        if system_info.gpu.feature_status:
-          logging.info('Feature Status:')
-          for k, v in sorted(system_info.gpu.feature_status.iteritems()):
-            logging.info('  %-20s: %s', k, v)
-        if system_info.gpu.driver_bug_workarounds:
-          logging.info('Driver Bug Workarounds:')
-          for workaround in system_info.gpu.driver_bug_workarounds:
-            logging.info('  %s', workaround)
-      else:
-        logging.info('No GPU devices')
-    else:
-      logging.warning('System info not supported')
-
-  def _GetStatsCommon(self, pid_stats_function):
-    browser_pid = self._browser_backend.pid
-    result = {
-        'Browser': dict(pid_stats_function(browser_pid), **{'ProcessCount': 1}),
-        'Renderer': {'ProcessCount': 0},
-        'Gpu': {'ProcessCount': 0},
-        'Other': {'ProcessCount': 0}
-    }
-    process_count = 1
-    for child_pid in self._platform_backend.GetChildPids(browser_pid):
-      try:
-        child_cmd_line = self._platform_backend.GetCommandLine(child_pid)
-        child_stats = pid_stats_function(child_pid)
-      except exceptions.ProcessGoneException:
-        # It is perfectly fine for a process to have gone away between calling
-        # GetChildPids() and then further examining it.
-        continue
-      child_process_name = self._browser_backend.GetProcessName(child_cmd_line)
-      process_name_type_key_map = {'gpu-process': 'Gpu', 'renderer': 'Renderer'}
-      if child_process_name in process_name_type_key_map:
-        child_process_type_key = process_name_type_key_map[child_process_name]
-      else:
-        # TODO: identify other process types (zygote, plugin, etc), instead of
-        # lumping them in a single category.
-        child_process_type_key = 'Other'
-      result[child_process_type_key]['ProcessCount'] += 1
-      for k, v in child_stats.iteritems():
-        if k in result[child_process_type_key]:
-          result[child_process_type_key][k] += v
-        else:
-          result[child_process_type_key][k] = v
-      process_count += 1
-    for v in result.itervalues():
-      if v['ProcessCount'] > 1:
-        for k in v.keys():
-          if k.endswith('Peak'):
-            del v[k]
-      del v['ProcessCount']
-    result['ProcessCount'] = process_count
-    return result
-
-  @property
-  def memory_stats(self):
-    """Returns a dict of memory statistics for the browser:
-    { 'Browser': {
-        'VM': R,
-        'VMPeak': S,
-        'WorkingSetSize': T,
-        'WorkingSetSizePeak': U,
-        'ProportionalSetSize': V,
-        'PrivateDirty': W
-      },
-      'Gpu': {
-        'VM': R,
-        'VMPeak': S,
-        'WorkingSetSize': T,
-        'WorkingSetSizePeak': U,
-        'ProportionalSetSize': V,
-        'PrivateDirty': W
-      },
-      'Renderer': {
-        'VM': R,
-        'VMPeak': S,
-        'WorkingSetSize': T,
-        'WorkingSetSizePeak': U,
-        'ProportionalSetSize': V,
-        'PrivateDirty': W
-      },
-      'SystemCommitCharge': X,
-      'SystemTotalPhysicalMemory': Y,
-      'ProcessCount': Z,
-    }
-    Any of the above keys may be missing on a per-platform basis.
-    """
-    self._platform_backend.PurgeUnpinnedMemory()
-    result = self._GetStatsCommon(self._platform_backend.GetMemoryStats)
-    commit_charge = self._platform_backend.GetSystemCommitCharge()
-    if commit_charge:
-      result['SystemCommitCharge'] = commit_charge
-    total = self._platform_backend.GetSystemTotalPhysicalMemory()
-    if total:
-      result['SystemTotalPhysicalMemory'] = total
-    return result
-
-  @property
-  def cpu_stats(self):
-    """Returns a dict of cpu statistics for the system.
-    { 'Browser': {
-        'CpuProcessTime': S,
-        'TotalTime': T
-      },
-      'Gpu': {
-        'CpuProcessTime': S,
-        'TotalTime': T
-      },
-      'Renderer': {
-        'CpuProcessTime': S,
-        'TotalTime': T
-      }
-    }
-    Any of the above keys may be missing on a per-platform basis.
-    """
-    result = self._GetStatsCommon(self._platform_backend.GetCpuStats)
-    del result['ProcessCount']
-
-    # We want a single time value, not the sum for all processes.
-    cpu_timestamp = self._platform_backend.GetCpuTimestamp()
-    for process_type in result:
-      # Skip any process_types that are empty
-      if not len(result[process_type]):
-        continue
-      result[process_type].update(cpu_timestamp)
-    return result
-
-  def Close(self):
-    """Closes this browser."""
-    try:
-      if self._browser_backend.IsBrowserRunning():
-        self._platform_backend.WillCloseBrowser(self, self._browser_backend)
-
-      self._browser_backend.profiling_controller_backend.WillCloseBrowser()
-      if self._browser_backend.supports_uploading_logs:
-        try:
-          self._browser_backend.UploadLogsToCloudStorage()
-        except cloud_storage.CloudStorageError as e:
-          logging.error('Cannot upload browser log: %s' % str(e))
-    finally:
-      self._browser_backend.Close()
-      self.credentials = None
-
-  def Foreground(self):
-    """Ensure the browser application is moved to the foreground."""
-    return self._browser_backend.Foreground()
-
-  def Background(self):
-    """Ensure the browser application is moved to the background."""
-    return self._browser_backend.Background()
-
-  def GetStandardOutput(self):
-    return self._browser_backend.GetStandardOutput()
-
-  def GetLogFileContents(self):
-    return self._browser_backend.GetLogFileContents()
-
-  def GetStackTrace(self):
-    return self._browser_backend.GetStackTrace()
-
-  def GetMostRecentMinidumpPath(self):
-    """Returns the path to the most recent minidump."""
-    return self._browser_backend.GetMostRecentMinidumpPath()
-
-  def GetAllMinidumpPaths(self):
-    """Returns all minidump paths available in the backend."""
-    return self._browser_backend.GetAllMinidumpPaths()
-
-  def GetAllUnsymbolizedMinidumpPaths(self):
-    """Returns paths to all minidumps that have not already been
-    symbolized."""
-    return self._browser_backend.GetAllUnsymbolizedMinidumpPaths()
-
-  def SymbolizeMinidump(self, minidump_path):
-    """Given a minidump path, this method returns a tuple with the
-    first value being whether or not the minidump was able to be
-    symbolized and the second being that symbolized dump when true
-    and error message when false."""
-    return self._browser_backend.SymbolizeMinidump(minidump_path)
-
-  @property
-  def supports_system_info(self):
-    return self._browser_backend.supports_system_info
-
-  def GetSystemInfo(self):
-    """Returns low-level information about the system, if available.
-
-       See the documentation of the SystemInfo class for more details."""
-    return self._browser_backend.GetSystemInfo()
-
-  @property
-  def supports_memory_dumping(self):
-    return self._browser_backend.supports_memory_dumping
-
-  def DumpMemory(self, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    return self._browser_backend.DumpMemory(timeout)
-
-  @property
-  def supports_overriding_memory_pressure_notifications(self):
-    return (
-        self._browser_backend.supports_overriding_memory_pressure_notifications)
-
-  def SetMemoryPressureNotificationsSuppressed(
-      self, suppressed, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    self._browser_backend.SetMemoryPressureNotificationsSuppressed(
-        suppressed, timeout)
-
-  def SimulateMemoryPressureNotification(
-      self, pressure_level, timeout=web_contents.DEFAULT_WEB_CONTENTS_TIMEOUT):
-    self._browser_backend.SimulateMemoryPressureNotification(
-        pressure_level, timeout)
-
-  @property
-  def supports_cpu_metrics(self):
-    return self._browser_backend.supports_cpu_metrics
-
-  @property
-  def supports_memory_metrics(self):
-    return self._browser_backend.supports_memory_metrics
-
-  @property
-  def supports_power_metrics(self):
-    return self._browser_backend.supports_power_metrics
-
-  def DumpStateUponFailure(self):
-    logging.info('*************** BROWSER STANDARD OUTPUT ***************')
-    try:  # pylint: disable=broad-except
-      logging.info(self.GetStandardOutput())
-    except Exception:
-      logging.exception('Failed to get browser standard output:')
-    logging.info('*********** END OF BROWSER STANDARD OUTPUT ************')
-
-    logging.info('********************* BROWSER LOG *********************')
-    try:  # pylint: disable=broad-except
-      logging.info(self.GetLogFileContents())
-    except Exception:
-      logging.exception('Failed to get browser log:')
-    logging.info('***************** END OF BROWSER LOG ******************')
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_credentials.py b/catapult/telemetry/telemetry/internal/browser/browser_credentials.py
deleted file mode 100644
index 38f99c5..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_credentials.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import os
-
-from telemetry.core import util
-from telemetry.internal.backends import codepen_credentials_backend
-from telemetry.internal.backends import facebook_credentials_backend
-from telemetry.internal.backends import google_credentials_backend
-from telemetry.testing import options_for_unittests
-
-
-class CredentialsError(Exception):
-  """Error that can be thrown when logging in."""
-
-
-class BrowserCredentials(object):
-  def __init__(self, backends=None):
-    self._credentials = {}
-    self._credentials_path = None
-    self._extra_credentials = {}
-
-    if backends is None:
-      backends = [
-        codepen_credentials_backend.CodePenCredentialsBackend(),
-        facebook_credentials_backend.FacebookCredentialsBackend(),
-        facebook_credentials_backend.FacebookCredentialsBackend2(),
-        google_credentials_backend.GoogleCredentialsBackend(),
-        google_credentials_backend.GoogleCredentialsBackend2()]
-
-    self._backends = {}
-    for backend in backends:
-      self._backends[backend.credentials_type] = backend
-
-  def AddBackend(self, backend):
-    assert backend.credentials_type not in self._backends
-    self._backends[backend.credentials_type] = backend
-
-  def IsLoggedIn(self, credentials_type):
-    if credentials_type not in self._backends:
-      raise CredentialsError(
-          'Unrecognized credentials type: %s', credentials_type)
-    if credentials_type not in self._credentials:
-      return False
-    return self._backends[credentials_type].IsLoggedIn()
-
-  def CanLogin(self, credentials_type):
-    if credentials_type not in self._backends:
-      raise CredentialsError(
-          'Unrecognized credentials type: %s', credentials_type)
-    return credentials_type in self._credentials
-
-  def LoginNeeded(self, tab, credentials_type):
-    if credentials_type not in self._backends:
-      raise CredentialsError(
-          'Unrecognized credentials type: %s', credentials_type)
-    if credentials_type not in self._credentials:
-      return False
-    runner = tab.action_runner
-    return self._backends[credentials_type].LoginNeeded(
-      tab, runner, self._credentials[credentials_type])
-
-  def LoginNoLongerNeeded(self, tab, credentials_type):
-    assert credentials_type in self._backends
-    self._backends[credentials_type].LoginNoLongerNeeded(tab)
-
-  @property
-  def credentials_path(self):
-    return self._credentials_path
-
-  @credentials_path.setter
-  def credentials_path(self, credentials_path):
-    self._credentials_path = credentials_path
-    self._RebuildCredentials()
-
-  def Add(self, credentials_type, data):
-    if credentials_type not in self._extra_credentials:
-      self._extra_credentials[credentials_type] = {}
-    for k, v in data.items():
-      assert k not in self._extra_credentials[credentials_type]
-      self._extra_credentials[credentials_type][k] = v
-    self._RebuildCredentials()
-
-  def _ResetLoggedInState(self):
-    """Makes the backends think we're not logged in even though we are.
-    Should only be used in unit tests to simulate --dont-override-profile.
-    """
-    for backend in self._backends.keys():
-      # pylint: disable=protected-access
-      self._backends[backend]._ResetLoggedInState()
-
-  def _RebuildCredentials(self):
-    credentials = {}
-    if self._credentials_path == None:
-      pass
-    elif os.path.exists(self._credentials_path):
-      with open(self._credentials_path, 'r') as f:
-        credentials = json.loads(f.read())
-
-    # TODO(nduca): use system keychain, if possible.
-    homedir_credentials_path = os.path.expanduser('~/.telemetry-credentials')
-    homedir_credentials = {}
-
-    if (not options_for_unittests.GetCopy() and
-        os.path.exists(homedir_credentials_path)):
-      logging.info("Found ~/.telemetry-credentials. Its contents will be used "
-                   "when no other credentials can be found.")
-      with open(homedir_credentials_path, 'r') as f:
-        homedir_credentials = json.loads(f.read())
-
-    self._credentials = {}
-    all_keys = set(credentials.keys()).union(
-      homedir_credentials.keys()).union(
-      self._extra_credentials.keys())
-
-    for k in all_keys:
-      if k in credentials:
-        self._credentials[k] = credentials[k]
-      if k in homedir_credentials:
-        logging.info("Will use ~/.telemetry-credentials for %s logins." % k)
-        self._credentials[k] = homedir_credentials[k]
-      if k in self._extra_credentials:
-        self._credentials[k] = self._extra_credentials[k]
-
-  def WarnIfMissingCredentials(self, page):
-    if page.credentials and not self.CanLogin(page.credentials):
-      files_to_tweak = []
-      if page.credentials_path:
-        files_to_tweak.append(page.credentials_path)
-      files_to_tweak.append('~/.telemetry-credentials')
-
-      example_credentials_file = os.path.join(
-          util.GetTelemetryDir(), 'examples', 'credentials_example.json')
-
-      logging.warning("""
-        Credentials for %s were not found. page %s will not be tested.
-
-        To fix this, either follow the instructions to authenticate to gsutil
-        here:
-        http://www.chromium.org/developers/telemetry/upload_to_cloud_storage,
-
-        or add your own credentials to:
-            %s
-        An example credentials file you can copy from is here:
-            %s\n""" % (page.credentials, page, ' or '.join(files_to_tweak),
-                       example_credentials_file))
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_credentials_unittest.py b/catapult/telemetry/telemetry/internal/browser/browser_credentials_unittest.py
deleted file mode 100644
index 79ebcc0..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_credentials_unittest.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import tempfile
-import unittest
-
-from telemetry.internal.browser import browser_credentials
-
-
-SIMPLE_CREDENTIALS_STRING = """
-{
-  "google": {
-    "username": "example",
-    "password": "asdf"
-  }
-}
-"""
-
-class BackendStub(object):
-  def __init__(self, credentials_type):
-    self.login_needed_called = None
-    self.login_no_longer_needed_called = None
-    self.credentials_type = credentials_type
-
-  def LoginNeeded(self, config, _, tab):
-    self.login_needed_called = (config, tab)
-    return True
-
-  def LoginNoLongerNeeded(self, tab):
-    self.login_no_longer_needed_called = (tab, )
-
-
-class TestBrowserCredentials(unittest.TestCase):
-  def testCredentialsInfrastructure(self):
-    google_backend = BackendStub("google")
-    othersite_backend = BackendStub("othersite")
-    browser_cred = browser_credentials.BrowserCredentials(
-      [google_backend,
-       othersite_backend])
-    try:
-      with tempfile.NamedTemporaryFile(delete=False) as f:
-        f.write(SIMPLE_CREDENTIALS_STRING)
-
-      browser_cred.credentials_path = f.name
-
-      # Should true because it has a password and a backend.
-      self.assertTrue(browser_cred.CanLogin('google'))
-
-      # Should be false succeed because it has no password.
-      self.assertFalse(browser_cred.CanLogin('othersite'))
-
-      # Should fail because it has no backend.
-      self.assertRaises(
-        Exception,
-        lambda: browser_cred.CanLogin('foobar'))
-
-      class FakeTab(object):
-        def __init__(self):
-          self.action_runner = None
-
-      tab = FakeTab()
-      ret = browser_cred.LoginNeeded(tab, 'google')
-      self.assertTrue(ret)
-      self.assertTrue(google_backend.login_needed_called is not None)
-      self.assertEqual(tab, google_backend.login_needed_called[0])
-      self.assertEqual("example",
-                       google_backend.login_needed_called[1]["username"])
-      self.assertEqual("asdf",
-                       google_backend.login_needed_called[1]["password"])
-
-      browser_cred.LoginNoLongerNeeded(tab, 'google')
-      self.assertTrue(google_backend.login_no_longer_needed_called is not None)
-      self.assertEqual(tab, google_backend.login_no_longer_needed_called[0])
-    finally:
-      os.remove(f.name)
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_finder.py b/catapult/telemetry/telemetry/internal/browser/browser_finder.py
deleted file mode 100644
index 242f491..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_finder.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Finds browsers that can be controlled by telemetry."""
-
-import logging
-import operator
-
-from telemetry import decorators
-from telemetry.internal.backends.chrome import android_browser_finder
-from telemetry.internal.backends.chrome import cros_browser_finder
-from telemetry.internal.backends.chrome import desktop_browser_finder
-from telemetry.internal.backends.chrome import ios_browser_finder
-from telemetry.internal.browser import browser_finder_exceptions
-from telemetry.internal.platform import device_finder
-
-BROWSER_FINDERS = [
-  desktop_browser_finder,
-  android_browser_finder,
-  cros_browser_finder,
-  ios_browser_finder,
-  ]
-
-
-def FindAllBrowserTypes(options):
-  return reduce(operator.add,
-                [bf.FindAllBrowserTypes(options) for bf in BROWSER_FINDERS])
-
-
-@decorators.Cache
-def FindBrowser(options):
-  """Finds the best PossibleBrowser object given a BrowserOptions object.
-
-  Args:
-    A BrowserOptions object.
-
-  Returns:
-    A PossibleBrowser object.
-
-  Raises:
-    BrowserFinderException: Options improperly set, or an error occurred.
-  """
-  if options.__class__.__name__ == '_FakeBrowserFinderOptions':
-    return options.fake_possible_browser
-  if options.browser_type == 'exact' and options.browser_executable == None:
-    raise browser_finder_exceptions.BrowserFinderException(
-        '--browser=exact requires --browser-executable to be set.')
-  if options.browser_type != 'exact' and options.browser_executable != None:
-    raise browser_finder_exceptions.BrowserFinderException(
-        '--browser-executable requires --browser=exact.')
-
-  if options.browser_type == 'cros-chrome' and options.cros_remote == None:
-    raise browser_finder_exceptions.BrowserFinderException(
-        'browser_type=cros-chrome requires cros_remote be set.')
-  if (options.browser_type != 'cros-chrome' and
-      options.browser_type != 'cros-chrome-guest' and
-      options.cros_remote != None):
-    raise browser_finder_exceptions.BrowserFinderException(
-        '--remote requires --browser=cros-chrome or cros-chrome-guest.')
-
-  devices = device_finder.GetDevicesMatchingOptions(options)
-  browsers = []
-  default_browsers = []
-  for device in devices:
-    for finder in BROWSER_FINDERS:
-      if(options.browser_type and options.browser_type != 'any' and
-         options.browser_type not in finder.FindAllBrowserTypes(options)):
-        continue
-      curr_browsers = finder.FindAllAvailableBrowsers(options, device)
-      new_default_browser = finder.SelectDefaultBrowser(curr_browsers)
-      if new_default_browser:
-        default_browsers.append(new_default_browser)
-      browsers.extend(curr_browsers)
-
-  if options.browser_type == None:
-    if default_browsers:
-      default_browser = sorted(default_browsers,
-                               key=lambda b: b.last_modification_time())[-1]
-
-      logging.warning('--browser omitted. Using most recent local build: %s' %
-                      default_browser.browser_type)
-      default_browser.UpdateExecutableIfNeeded()
-      return default_browser
-
-    if len(browsers) == 1:
-      logging.warning('--browser omitted. Using only available browser: %s' %
-                      browsers[0].browser_type)
-      browsers[0].UpdateExecutableIfNeeded()
-      return browsers[0]
-
-    raise browser_finder_exceptions.BrowserTypeRequiredException(
-        '--browser must be specified. Available browsers:\n%s' %
-        '\n'.join(sorted(set([b.browser_type for b in browsers]))))
-
-  if options.browser_type == 'any':
-    types = FindAllBrowserTypes(options)
-    def CompareBrowsersOnTypePriority(x, y):
-      x_idx = types.index(x.browser_type)
-      y_idx = types.index(y.browser_type)
-      return x_idx - y_idx
-    browsers.sort(CompareBrowsersOnTypePriority)
-    if len(browsers) >= 1:
-      browsers[0].UpdateExecutableIfNeeded()
-      return browsers[0]
-    else:
-      return None
-
-  matching_browsers = [b for b in browsers
-      if b.browser_type == options.browser_type and
-      b.SupportsOptions(options.browser_options)]
-
-  chosen_browser = None
-  if len(matching_browsers) == 1:
-    chosen_browser = matching_browsers[0]
-  elif len(matching_browsers) > 1:
-    logging.warning('Multiple browsers of the same type found: %s' % (
-                    repr(matching_browsers)))
-    chosen_browser = sorted(matching_browsers,
-                            key=lambda b: b.last_modification_time())[-1]
-
-  if chosen_browser:
-    logging.info('Chose browser: %s' % (repr(chosen_browser)))
-    chosen_browser.UpdateExecutableIfNeeded()
-
-  return chosen_browser
-
-
-@decorators.Cache
-def GetAllAvailableBrowsers(options, device):
-  """Returns a list of available browsers on the device.
-
-  Args:
-    options: A BrowserOptions object.
-    device: The target device, which can be None.
-
-  Returns:
-    A list of browser instances.
-
-  Raises:
-    BrowserFinderException: Options are improperly set, or an error occurred.
-  """
-  if not device:
-    return []
-  possible_browsers = []
-  for browser_finder in BROWSER_FINDERS:
-    possible_browsers.extend(
-      browser_finder.FindAllAvailableBrowsers(options, device))
-  return possible_browsers
-
-
-@decorators.Cache
-def GetAllAvailableBrowserTypes(options):
-  """Returns a list of available browser types.
-
-  Args:
-    options: A BrowserOptions object.
-
-  Returns:
-    A list of browser type strings.
-
-  Raises:
-    BrowserFinderException: Options are improperly set, or an error occurred.
-  """
-  devices = device_finder.GetDevicesMatchingOptions(options)
-  possible_browsers = []
-  for device in devices:
-    possible_browsers.extend(GetAllAvailableBrowsers(options, device))
-  type_list = set([browser.browser_type for browser in possible_browsers])
-  # The reference build should be available for mac, linux and win, but the
-  # desktop browser finder won't return it in the list of browsers.
-  for browser in possible_browsers:
-    if (browser.target_os == 'darwin' or browser.target_os.startswith('linux')
-        or browser.target_os.startswith('win')):
-      type_list.add('reference')
-      break
-  type_list = list(type_list)
-  type_list.sort()
-  return type_list
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_finder_exceptions.py b/catapult/telemetry/telemetry/internal/browser/browser_finder_exceptions.py
deleted file mode 100644
index 76fbdcf..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_finder_exceptions.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class BrowserTypeRequiredException(Exception):
-  pass
-
-
-class BrowserFinderException(Exception):
-  pass
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_info.py b/catapult/telemetry/telemetry/internal/browser/browser_info.py
deleted file mode 100644
index 5db7150..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_info.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-_check_webgl_supported_script = """
-(function () {
-  var c = document.createElement('canvas');
-  var gl = c.getContext('webgl', { failIfMajorPerformanceCaveat: true });
-  if (gl == null) {
-    gl = c.getContext('experimental-webgl',
-        { failIfMajorPerformanceCaveat: true });
-    if (gl == null) {
-      return false;
-    }
-  }
-  return true;
-})();
-"""
-
-class BrowserInfo(object):
-  """A wrapper around browser object that allows looking up infos of the
-  browser.
-  """
-  def __init__(self, browser):
-    self._browser = browser
-
-  def HasWebGLSupport(self):
-    result = False
-    # If no tab is opened, open one and close it after evaluate
-    # _check_webgl_supported_script
-    if len(self._browser.tabs) == 0 and self._browser.supports_tab_control:
-      self._browser.tabs.New()
-      tab = self._browser.tabs[0]
-      result = tab.EvaluateJavaScript(_check_webgl_supported_script)
-      tab.Close()
-    elif len(self._browser.tabs) > 0:
-      tab = self._browser.tabs[0]
-      result = tab.EvaluateJavaScript(_check_webgl_supported_script)
-    return result
-
-  def HasFlingGestureSupport(self):
-    # Synthetic fling gestures weren't properly tracked by telemetry until
-    # Chromium branch number 2339 (see crrev.com/1003023002).
-    # TODO(jdduke): Resolve lack of branch number support for content_shell
-    # targets, see crbug.com/470273.
-    branch_num = (
-        self._browser._browser_backend.devtools_client.GetChromeBranchNumber())
-    return branch_num >= 2339
-
-  def HasDiagonalScrollingSupport(self):
-    # Diagonal scrolling was not supported in the ScrollAction until
-    # Chromium branch number 2332
-    branch_num = (
-        self._browser._browser_backend.devtools_client.GetChromeBranchNumber())
-    return branch_num >= 2332
-
-  def HasRepeatableSynthesizeScrollGesture(self):
-    # Repeatable SynthesizeScrollGesture scrolling was not supported until
-    # Chromium branch number 2480
-    branch_num = (
-        self._browser._browser_backend.devtools_client.GetChromeBranchNumber())
-    return branch_num >= 2480
-
-  @property
-  def browser_type(self):
-    return self._browser.browser_type
-
-  @property
-  def browser(self):
-    return self._browser
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_options.py b/catapult/telemetry/telemetry/internal/browser/browser_options.py
deleted file mode 100644
index 67b6d16..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_options.py
+++ /dev/null
@@ -1,470 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import copy
-import logging
-import optparse
-import os
-import shlex
-import socket
-import sys
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.core import platform
-from telemetry.core import util
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import browser_finder_exceptions
-from telemetry.internal.browser import profile_types
-from telemetry.internal.platform import device_finder
-from telemetry.internal.platform import remote_platform_options
-from telemetry.internal.platform.profiler import profiler_finder
-from telemetry.internal.util import binary_manager
-from telemetry.util import wpr_modes
-
-
-class BrowserFinderOptions(optparse.Values):
-  """Options to be used for discovering a browser."""
-
-  def __init__(self, browser_type=None):
-    optparse.Values.__init__(self)
-
-    self.browser_type = browser_type
-    self.browser_executable = None
-    self.chrome_root = None  # Path to src/
-    self.chromium_output_dir = None  # E.g.: out/Debug
-    self.device = None
-    self.cros_ssh_identity = None
-
-    self.cros_remote = None
-
-    self.profiler = None
-    self.verbosity = 0
-
-    self.browser_options = BrowserOptions()
-    self.output_file = None
-
-    self.remote_platform_options = None
-
-    self.no_performance_mode = False
-
-  def __repr__(self):
-    return str(sorted(self.__dict__.items()))
-
-  def Copy(self):
-    return copy.deepcopy(self)
-
-  def CreateParser(self, *args, **kwargs):
-    parser = optparse.OptionParser(*args, **kwargs)
-
-    # Selection group
-    group = optparse.OptionGroup(parser, 'Which browser to use')
-    group.add_option('--browser',
-        dest='browser_type',
-        default=None,
-        help='Browser type to run, '
-             'in order of priority. Supported values: list,%s' %
-             ','.join(browser_finder.FindAllBrowserTypes(self)))
-    group.add_option('--browser-executable',
-        dest='browser_executable',
-        help='The exact browser to run.')
-    group.add_option('--chrome-root',
-        dest='chrome_root',
-        help='Where to look for chrome builds. '
-             'Defaults to searching parent dirs by default.')
-    group.add_option('--chromium-output-directory',
-        dest='chromium_output_dir',
-        help='Where to look for build artifacts. '
-             'Can also be specified by setting environment variable '
-             'CHROMIUM_OUTPUT_DIR.')
-    group.add_option(
-        '--remote',
-        dest='cros_remote',
-        help='The hostname of a remote ChromeOS device to use.')
-    group.add_option(
-        '--remote-ssh-port',
-        type=int,
-        default=socket.getservbyname('ssh'),
-        dest='cros_remote_ssh_port',
-        help='The SSH port of the remote ChromeOS device (requires --remote).')
-    identity = None
-    testing_rsa = os.path.join(
-        util.GetTelemetryThirdPartyDir(), 'chromite', 'ssh_keys', 'testing_rsa')
-    if os.path.exists(testing_rsa):
-      identity = testing_rsa
-    group.add_option('--identity',
-        dest='cros_ssh_identity',
-        default=identity,
-        help='The identity file to use when ssh\'ing into the ChromeOS device')
-    parser.add_option_group(group)
-
-    # Debugging options
-    group = optparse.OptionGroup(parser, 'When things go wrong')
-    profiler_choices = profiler_finder.GetAllAvailableProfilers()
-    group.add_option(
-        '--profiler', default=None, type='choice',
-        choices=profiler_choices,
-        help='Record profiling data using this tool. Supported values: %s. '
-             '(Notice: this flag cannot be used for Timeline Based Measurement '
-             'benchmarks.)' % ', '.join(profiler_choices))
-    group.add_option(
-        '-v', '--verbose', action='count', dest='verbosity',
-        help='Increase verbosity level (repeat as needed)')
-    group.add_option('--print-bootstrap-deps',
-                     action='store_true',
-                     help='Output bootstrap deps list.')
-    parser.add_option_group(group)
-
-    # Platform options
-    group = optparse.OptionGroup(parser, 'Platform options')
-    group.add_option('--no-performance-mode', action='store_true',
-        help='Some platforms run on "full performance mode" where the '
-        'test is executed at maximum CPU speed in order to minimize noise '
-        '(specially important for dashboards / continuous builds). '
-        'This option prevents Telemetry from tweaking such platform settings.')
-    parser.add_option_group(group)
-
-    # Remote platform options
-    group = optparse.OptionGroup(parser, 'Remote platform options')
-    group.add_option('--android-blacklist-file',
-                     help='Device blacklist JSON file.')
-    group.add_option('--device',
-    help='The device ID to use. '
-         'If not specified, only 0 or 1 connected devices are supported. '
-         'If specified as "android", all available Android devices are '
-         'used.')
-    parser.add_option_group(group)
-
-    # Browser options.
-    self.browser_options.AddCommandLineArgs(parser)
-
-    real_parse = parser.parse_args
-    def ParseArgs(args=None):
-      defaults = parser.get_default_values()
-      for k, v in defaults.__dict__.items():
-        if k in self.__dict__ and self.__dict__[k] != None:
-          continue
-        self.__dict__[k] = v
-      ret = real_parse(args, self) # pylint: disable=E1121
-
-      if self.verbosity >= 2:
-        logging.getLogger().setLevel(logging.DEBUG)
-      elif self.verbosity:
-        logging.getLogger().setLevel(logging.INFO)
-      else:
-        logging.getLogger().setLevel(logging.WARNING)
-
-      if self.chromium_output_dir:
-        os.environ['CHROMIUM_OUTPUT_DIR'] = self.chromium_output_dir
-
-      # Parse remote platform options.
-      self.BuildRemotePlatformOptions()
-
-      if self.remote_platform_options.device == 'list':
-        if binary_manager.NeedsInit():
-          binary_manager.InitDependencyManager([])
-        devices = device_finder.GetDevicesMatchingOptions(self)
-        print 'Available devices:'
-        for device in devices:
-          print ' ', device.name
-        sys.exit(0)
-
-      if self.browser_executable and not self.browser_type:
-        self.browser_type = 'exact'
-      if self.browser_type == 'list':
-        if binary_manager.NeedsInit():
-          binary_manager.InitDependencyManager([])
-        devices = device_finder.GetDevicesMatchingOptions(self)
-        if not devices:
-          sys.exit(0)
-        browser_types = {}
-        for device in devices:
-          try:
-            possible_browsers = browser_finder.GetAllAvailableBrowsers(self,
-                                                                       device)
-            browser_types[device.name] = sorted(
-              [browser.browser_type for browser in possible_browsers])
-          except browser_finder_exceptions.BrowserFinderException as ex:
-            print >> sys.stderr, 'ERROR: ', ex
-            sys.exit(1)
-        print 'Available browsers:'
-        if len(browser_types) == 0:
-          print '  No devices were found.'
-        for device_name in sorted(browser_types.keys()):
-          print '  ', device_name
-          for browser_type in browser_types[device_name]:
-            print '    ', browser_type
-        sys.exit(0)
-
-      # Parse browser options.
-      self.browser_options.UpdateFromParseResults(self)
-
-      return ret
-    parser.parse_args = ParseArgs
-    return parser
-
-  # TODO(eakuefner): Factor this out into OptionBuilder pattern
-  def BuildRemotePlatformOptions(self):
-    if self.device or self.android_blacklist_file:
-      self.remote_platform_options = (
-          remote_platform_options.AndroidPlatformOptions(
-              self.device, self.android_blacklist_file))
-
-      # We delete these options because they should live solely in the
-      # AndroidPlatformOptions instance belonging to this class.
-      if self.device:
-        del self.device
-      if self.android_blacklist_file:
-        del self.android_blacklist_file
-    else:
-      self.remote_platform_options = (
-          remote_platform_options.AndroidPlatformOptions())
-
-  def AppendExtraBrowserArgs(self, args):
-    self.browser_options.AppendExtraBrowserArgs(args)
-
-  def MergeDefaultValues(self, defaults):
-    for k, v in defaults.__dict__.items():
-      self.ensure_value(k, v)
-
-class BrowserOptions(object):
-  """Options to be used for launching a browser."""
-
-  # Levels of browser logging.
-  NO_LOGGING = 'none'
-  NON_VERBOSE_LOGGING = 'non-verbose'
-  VERBOSE_LOGGING = 'verbose'
-
-  _LOGGING_LEVELS = (NO_LOGGING, NON_VERBOSE_LOGGING, VERBOSE_LOGGING)
-  _DEFAULT_LOGGING_LEVEL = NO_LOGGING
-
-  def __init__(self):
-    self.browser_type = None
-    self.show_stdout = False
-
-    self.extensions_to_load = []
-
-    # If set, copy the generated profile to this path on exit.
-    self.output_profile_path = None
-
-    # When set to True, the browser will use the default profile.  Telemetry
-    # will not provide an alternate profile directory.
-    self.dont_override_profile = False
-    self.profile_dir = None
-    self.profile_type = None
-    self._extra_browser_args = set()
-    self.extra_wpr_args = []
-    self.wpr_mode = wpr_modes.WPR_OFF
-    self.full_performance_mode = True
-
-    # The amount of time Telemetry should wait for the browser to start.
-    # This property is not exposed as a command line option.
-    self._browser_startup_timeout = 60
-
-    self.disable_background_networking = True
-    self.browser_user_agent_type = None
-
-    self.clear_sytem_cache_for_browser_and_profile_on_start = False
-    self.startup_url = 'about:blank'
-
-    # Background pages of built-in component extensions can interfere with
-    # performance measurements.
-    self.disable_component_extensions_with_background_pages = True
-    # Disable default apps.
-    self.disable_default_apps = True
-
-    self.logging_verbosity = self._DEFAULT_LOGGING_LEVEL
-
-    # The cloud storage bucket & path for uploading logs data produced by the
-    # browser to.
-    # If logs_cloud_remote_path is None, a random remote path is generated every
-    # time the logs data is uploaded.
-    self.logs_cloud_bucket = cloud_storage.TELEMETRY_OUTPUT
-    self.logs_cloud_remote_path = None
-
-    # TODO(danduong): Find a way to store target_os here instead of
-    # finder_options.
-    self._finder_options = None
-
-    # Whether to take screen shot for failed page & put them in telemetry's
-    # profiling results.
-    self.take_screenshot_for_failed_page = False
-
-  def __repr__(self):
-    # This works around the infinite loop caused by the introduction of a
-    # circular reference with _finder_options.
-    obj = self.__dict__.copy()
-    del obj['_finder_options']
-    return str(sorted(obj.items()))
-
-  def IsCrosBrowserOptions(self):
-    return False
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-
-    ############################################################################
-    # Please do not add any more options here without first discussing with    #
-    # a telemetry owner. This is not the right place for platform-specific     #
-    # options.                                                                 #
-    ############################################################################
-
-    group = optparse.OptionGroup(parser, 'Browser options')
-    profile_choices = profile_types.GetProfileTypes()
-    group.add_option('--profile-type',
-        dest='profile_type',
-        type='choice',
-        default='clean',
-        choices=profile_choices,
-        help=('The user profile to use. A clean profile is used by default. '
-              'Supported values: ' + ', '.join(profile_choices)))
-    group.add_option('--profile-dir',
-        dest='profile_dir',
-        help='Profile directory to launch the browser with. '
-             'A clean profile is used by default')
-    group.add_option('--extra-browser-args',
-        dest='extra_browser_args_as_string',
-        help='Additional arguments to pass to the browser when it starts')
-    group.add_option('--extra-wpr-args',
-        dest='extra_wpr_args_as_string',
-        help=('Additional arguments to pass to Web Page Replay. '
-              'See third_party/web-page-replay/replay.py for usage.'))
-    group.add_option('--show-stdout',
-        action='store_true',
-        help='When possible, will display the stdout of the process')
-
-    group.add_option('--browser-logging-verbosity',
-        dest='logging_verbosity',
-        type='choice',
-        choices=cls._LOGGING_LEVELS,
-        help=('Browser logging verbosity. The log file is saved in temp '
-              "directory. Note that logging affects the browser's "
-              'performance. Supported values: %s. Defaults to %s.' % (
-                  ', '.join(cls._LOGGING_LEVELS), cls._DEFAULT_LOGGING_LEVEL)))
-    parser.add_option_group(group)
-
-    group = optparse.OptionGroup(parser, 'Compatibility options')
-    group.add_option('--gtest_output',
-        help='Ignored argument for compatibility with runtest.py harness')
-    parser.add_option_group(group)
-
-  def UpdateFromParseResults(self, finder_options):
-    """Copies our options from finder_options"""
-    browser_options_list = [
-        'extra_browser_args_as_string',
-        'extra_wpr_args_as_string',
-        'profile_dir',
-        'profile_type',
-        'show_stdout',
-        ]
-    for o in browser_options_list:
-      a = getattr(finder_options, o, None)
-      if a is not None:
-        setattr(self, o, a)
-        delattr(finder_options, o)
-
-    self.browser_type = finder_options.browser_type
-    self._finder_options = finder_options
-
-    if hasattr(self, 'extra_browser_args_as_string'):
-      tmp = shlex.split(
-        self.extra_browser_args_as_string)
-      self.AppendExtraBrowserArgs(tmp)
-      delattr(self, 'extra_browser_args_as_string')
-    if hasattr(self, 'extra_wpr_args_as_string'):
-      tmp = shlex.split(
-        self.extra_wpr_args_as_string)
-      self.extra_wpr_args.extend(tmp)
-      delattr(self, 'extra_wpr_args_as_string')
-    if self.profile_type == 'default':
-      self.dont_override_profile = True
-
-    if self.profile_dir and self.profile_type != 'clean':
-      logging.critical(
-          "It's illegal to specify both --profile-type and --profile-dir.\n"
-          "For more information see: http://goo.gl/ngdGD5")
-      sys.exit(1)
-
-    if self.profile_dir and not os.path.isdir(self.profile_dir):
-      logging.critical(
-          "Directory specified by --profile-dir (%s) doesn't exist "
-          "or isn't a directory.\n"
-          "For more information see: http://goo.gl/ngdGD5" % self.profile_dir)
-      sys.exit(1)
-
-    if not self.profile_dir:
-      self.profile_dir = profile_types.GetProfileDir(self.profile_type)
-
-    if getattr(finder_options, 'logging_verbosity'):
-      self.logging_verbosity = finder_options.logging_verbosity
-      delattr(finder_options, 'logging_verbosity')
-
-    # This deferred import is necessary because browser_options is imported in
-    # telemetry/telemetry/__init__.py.
-    finder_options.browser_options = CreateChromeBrowserOptions(self)
-
-  @property
-  def finder_options(self):
-    return self._finder_options
-
-  @property
-  def extra_browser_args(self):
-    return self._extra_browser_args
-
-  @property
-  def browser_startup_timeout(self):
-    return self._browser_startup_timeout
-
-  @browser_startup_timeout.setter
-  def browser_startup_timeout(self, value):
-    self._browser_startup_timeout = value
-
-  def AppendExtraBrowserArgs(self, args):
-    if isinstance(args, list):
-      self._extra_browser_args.update(args)
-    else:
-      self._extra_browser_args.add(args)
-
-
-def CreateChromeBrowserOptions(br_options):
-  browser_type = br_options.browser_type
-
-  if (platform.GetHostPlatform().GetOSName() == 'chromeos' or
-      (browser_type and browser_type.startswith('cros'))):
-    return CrosBrowserOptions(br_options)
-
-  return br_options
-
-
-class ChromeBrowserOptions(BrowserOptions):
-  """Chrome-specific browser options."""
-
-  def __init__(self, br_options):
-    super(ChromeBrowserOptions, self).__init__()
-    # Copy to self.
-    self.__dict__.update(br_options.__dict__)
-
-
-class CrosBrowserOptions(ChromeBrowserOptions):
-  """ChromeOS-specific browser options."""
-
-  def __init__(self, br_options):
-    super(CrosBrowserOptions, self).__init__(br_options)
-    # Create a browser with oobe property.
-    self.create_browser_with_oobe = False
-    # Clear enterprise policy before logging in.
-    self.clear_enterprise_policy = True
-    # Disable GAIA/enterprise services.
-    self.disable_gaia_services = True
-
-    self.auto_login = True
-    self.gaia_login = False
-    self.username = 'test@test.test'
-    self.password = ''
-    self.gaia_id = '12345'
-    # For non-accelerated QEMU VMs.
-    self.browser_startup_timeout = 240
-
-  def IsCrosBrowserOptions(self):
-    return True
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_options_unittest.py b/catapult/telemetry/telemetry/internal/browser/browser_options_unittest.py
deleted file mode 100644
index 08791a5..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_options_unittest.py
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import optparse
-import os
-import unittest
-
-from telemetry.internal.browser import browser_options
-
-
-class BrowserOptionsTest(unittest.TestCase):
-  def testDefaults(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.add_option('-x', action='store', default=3)
-    parser.parse_args(['--browser', 'any'])
-    self.assertEquals(options.x, 3) # pylint: disable=no-member
-
-  def testDefaultsPlusOverride(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.add_option('-x', action='store', default=3)
-    parser.parse_args(['--browser', 'any', '-x', 10])
-    self.assertEquals(options.x, 10) # pylint: disable=no-member
-
-  def testDefaultsDontClobberPresetValue(self):
-    options = browser_options.BrowserFinderOptions()
-    setattr(options, 'x', 7)
-    parser = options.CreateParser()
-    parser.add_option('-x', action='store', default=3)
-    parser.parse_args(['--browser', 'any'])
-    self.assertEquals(options.x, 7) # pylint: disable=no-member
-
-  def testCount0(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.add_option('-x', action='count', dest='v')
-    parser.parse_args(['--browser', 'any'])
-    self.assertEquals(options.v, None) # pylint: disable=no-member
-
-  def testCount2(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.add_option('-x', action='count', dest='v')
-    parser.parse_args(['--browser', 'any', '-xx'])
-    self.assertEquals(options.v, 2) # pylint: disable=no-member
-
-  def testOptparseMutabilityWhenSpecified(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.add_option('-x', dest='verbosity', action='store_true')
-    options_ret, _ = parser.parse_args(['--browser', 'any', '-x'])
-    self.assertEquals(options_ret, options)
-    self.assertTrue(options.verbosity)
-
-  def testOptparseMutabilityWhenNotSpecified(self):
-    options = browser_options.BrowserFinderOptions()
-
-    parser = options.CreateParser()
-    parser.add_option('-x', dest='verbosity', action='store_true')
-    options_ret, _ = parser.parse_args(['--browser', 'any'])
-    self.assertEquals(options_ret, options)
-    self.assertFalse(options.verbosity)
-
-  def testProfileDirDefault(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.parse_args(['--browser', 'any'])
-    self.assertEquals(options.browser_options.profile_dir, None)
-
-  def testProfileDir(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    # Need to use a directory that exists.
-    current_dir = os.path.dirname(__file__)
-    parser.parse_args(['--browser', 'any', '--profile-dir', current_dir])
-    self.assertEquals(options.browser_options.profile_dir, current_dir)
-
-  def testExtraBrowserArgs(self):
-    options = browser_options.BrowserFinderOptions()
-    parser = options.CreateParser()
-    parser.parse_args(['--extra-browser-args=--foo --bar'])
-
-    self.assertEquals(options.browser_options.extra_browser_args,
-                      set(['--foo', '--bar']))
-
-  def testMergeDefaultValues(self):
-    options = browser_options.BrowserFinderOptions()
-    options.already_true = True
-    options.already_false = False
-    options.override_to_true = False
-    options.override_to_false = True
-
-    parser = optparse.OptionParser()
-    parser.add_option('--already_true', action='store_true')
-    parser.add_option('--already_false', action='store_true')
-    parser.add_option('--unset', action='store_true')
-    parser.add_option('--default_true', action='store_true', default=True)
-    parser.add_option('--default_false', action='store_true', default=False)
-    parser.add_option('--override_to_true', action='store_true', default=False)
-    parser.add_option('--override_to_false', action='store_true', default=True)
-
-    options.MergeDefaultValues(parser.get_default_values())
-
-    self.assertTrue(options.already_true)
-    self.assertFalse(options.already_false)
-    self.assertTrue(options.unset is None)
-    self.assertTrue(options.default_true)
-    self.assertFalse(options.default_false)
-    self.assertFalse(options.override_to_true)
-    self.assertTrue(options.override_to_false)
diff --git a/catapult/telemetry/telemetry/internal/browser/browser_unittest.py b/catapult/telemetry/telemetry/internal/browser/browser_unittest.py
deleted file mode 100644
index 02026cc..0000000
--- a/catapult/telemetry/telemetry/internal/browser/browser_unittest.py
+++ /dev/null
@@ -1,284 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import shutil
-import tempfile
-import unittest
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.browser import browser as browser_module
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.platform import gpu_device
-from telemetry.internal.platform import gpu_info
-from telemetry.internal.platform import system_info
-from telemetry.internal.util import path
-from telemetry.testing import browser_test_case
-from telemetry.testing import options_for_unittests
-from telemetry.timeline import tracing_config
-
-import mock
-import py_utils
-
-class IntentionalException(Exception):
-  pass
-
-
-class BrowserTest(browser_test_case.BrowserTestCase):
-  def testBrowserCreation(self):
-    self.assertEquals(1, len(self._browser.tabs))
-
-    # Different browsers boot up to different things.
-    assert self._browser.tabs[0].url
-
-  @decorators.Enabled('has tabs')
-  def testNewCloseTab(self):
-    existing_tab = self._browser.tabs[0]
-    self.assertEquals(1, len(self._browser.tabs))
-    existing_tab_url = existing_tab.url
-
-    new_tab = self._browser.tabs.New()
-    self.assertEquals(2, len(self._browser.tabs))
-    self.assertEquals(existing_tab.url, existing_tab_url)
-    self.assertEquals(new_tab.url, 'about:blank')
-
-    new_tab.Close()
-    self.assertEquals(1, len(self._browser.tabs))
-    self.assertEquals(existing_tab.url, existing_tab_url)
-
-  def testMultipleTabCalls(self):
-    self._browser.tabs[0].Navigate(self.UrlOfUnittestFile('blank.html'))
-    self._browser.tabs[0].WaitForDocumentReadyStateToBeInteractiveOrBetter()
-
-  def testTabCallByReference(self):
-    tab = self._browser.tabs[0]
-    tab.Navigate(self.UrlOfUnittestFile('blank.html'))
-    self._browser.tabs[0].WaitForDocumentReadyStateToBeInteractiveOrBetter()
-
-  @decorators.Enabled('has tabs')
-  def testCloseReferencedTab(self):
-    self._browser.tabs.New()
-    tab = self._browser.tabs[0]
-    tab.Navigate(self.UrlOfUnittestFile('blank.html'))
-    tab.Close()
-    self.assertEquals(1, len(self._browser.tabs))
-
-  @decorators.Enabled('has tabs')
-  def testForegroundTab(self):
-    # Should be only one tab at this stage, so that must be the foreground tab
-    original_tab = self._browser.tabs[0]
-    self.assertEqual(self._browser.foreground_tab, original_tab)
-    new_tab = self._browser.tabs.New()
-    # New tab shouls be foreground tab
-    self.assertEqual(self._browser.foreground_tab, new_tab)
-    # Make sure that activating the background tab makes it the foreground tab
-    original_tab.Activate()
-    self.assertEqual(self._browser.foreground_tab, original_tab)
-    # Closing the current foreground tab should switch the foreground tab to the
-    # other tab
-    original_tab.Close()
-    self.assertEqual(self._browser.foreground_tab, new_tab)
-
-  # This test uses the reference browser and doesn't have access to
-  # helper binaries like crashpad_database_util.
-  @decorators.Enabled('linux')
-  def testGetMinidumpPathOnCrash(self):
-    tab = self._browser.tabs[0]
-    with self.assertRaises(exceptions.AppCrashException):
-      tab.Navigate('chrome://crash', timeout=5)
-    crash_minidump_path = self._browser.GetMostRecentMinidumpPath()
-    self.assertIsNotNone(crash_minidump_path)
-
-  def testGetSystemInfo(self):
-    if not self._browser.supports_system_info:
-      logging.warning(
-          'Browser does not support getting system info, skipping test.')
-      return
-
-    info = self._browser.GetSystemInfo()
-
-    self.assertTrue(isinstance(info, system_info.SystemInfo))
-    self.assertTrue(hasattr(info, 'model_name'))
-    self.assertTrue(hasattr(info, 'gpu'))
-    self.assertTrue(isinstance(info.gpu, gpu_info.GPUInfo))
-    self.assertTrue(hasattr(info.gpu, 'devices'))
-    self.assertTrue(len(info.gpu.devices) > 0)
-    for g in info.gpu.devices:
-      self.assertTrue(isinstance(g, gpu_device.GPUDevice))
-
-  def testGetSystemInfoNotCachedObject(self):
-    if not self._browser.supports_system_info:
-      logging.warning(
-          'Browser does not support getting system info, skipping test.')
-      return
-
-    info_a = self._browser.GetSystemInfo()
-    info_b = self._browser.GetSystemInfo()
-    self.assertFalse(info_a is info_b)
-
-  def testGetSystemTotalMemory(self):
-    self.assertTrue(self._browser.memory_stats['SystemTotalPhysicalMemory'] > 0)
-
-
-  # crbug.com/628836 (CrOS, where system-guest indicates ChromeOS guest)
-  # github.com/catapult-project/catapult/issues/3130 (Windows)
-  @decorators.Disabled('cros-chrome-guest', 'system-guest', 'chromeos', 'win')
-  def testIsTracingRunning(self):
-    tracing_controller = self._browser.platform.tracing_controller
-    if not tracing_controller.IsChromeTracingSupported():
-      return
-    self.assertFalse(tracing_controller.is_tracing_running)
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    tracing_controller.StartTracing(config)
-    self.assertTrue(tracing_controller.is_tracing_running)
-    tracing_controller.StopTracing()
-    self.assertFalse(tracing_controller.is_tracing_running)
-
-
-class CommandLineBrowserTest(browser_test_case.BrowserTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.AppendExtraBrowserArgs('--user-agent=telemetry')
-
-  def testCommandLineOverriding(self):
-    # This test starts the browser with --user-agent=telemetry. This tests
-    # whether the user agent is then set.
-    t = self._browser.tabs[0]
-    t.Navigate(self.UrlOfUnittestFile('blank.html'))
-    t.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-    self.assertEquals(t.EvaluateJavaScript('navigator.userAgent'),
-                      'telemetry')
-
-class DirtyProfileBrowserTest(browser_test_case.BrowserTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.profile_type = 'small_profile'
-
-  @decorators.Disabled('chromeos')  # crbug.com/243912
-  def testDirtyProfileCreation(self):
-    self.assertEquals(1, len(self._browser.tabs))
-
-
-class BrowserLoggingTest(browser_test_case.BrowserTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.logging_verbosity = options.VERBOSE_LOGGING
-
-  @decorators.Disabled('chromeos', 'android')
-  def testLogFileExist(self):
-    self.assertTrue(
-       os.path.isfile(self._browser._browser_backend.log_file_path))
-
-
-def _GenerateBrowserProfile(number_of_tabs):
-  """ Generate a browser profile which browser had |number_of_tabs| number of
-  tabs opened before it was closed.
-      Returns:
-        profile_dir: the directory of profile.
-  """
-  profile_dir = tempfile.mkdtemp()
-  options = options_for_unittests.GetCopy()
-  options.browser_options.output_profile_path = profile_dir
-  browser_to_create = browser_finder.FindBrowser(options)
-  browser_to_create.platform.network_controller.InitializeIfNeeded()
-  try:
-    with browser_to_create.Create(options) as browser:
-      browser.platform.SetHTTPServerDirectories(path.GetUnittestDataDir())
-      blank_file_path = os.path.join(path.GetUnittestDataDir(), 'blank.html')
-      blank_url = browser.platform.http_server.UrlOf(blank_file_path)
-      browser.foreground_tab.Navigate(blank_url)
-      browser.foreground_tab.WaitForDocumentReadyStateToBeComplete()
-      for _ in xrange(number_of_tabs - 1):
-        tab = browser.tabs.New()
-        tab.Navigate(blank_url)
-        tab.WaitForDocumentReadyStateToBeComplete()
-    return profile_dir
-  finally:
-    browser_to_create.platform.network_controller.Close()
-
-
-class BrowserCreationTest(unittest.TestCase):
-  def setUp(self):
-    self.mock_browser_backend = mock.MagicMock()
-    self.mock_platform_backend = mock.MagicMock()
-
-  def testCleanedUpCalledWhenExceptionRaisedInBrowserCreation(self):
-    self.mock_platform_backend.platform.FlushDnsCache.side_effect = (
-        IntentionalException('Boom!'))
-    with self.assertRaises(IntentionalException):
-      browser_module.Browser(
-         self.mock_browser_backend, self.mock_platform_backend,
-         credentials_path=None)
-    self.assertTrue(self.mock_platform_backend.WillCloseBrowser.called)
-
-  def testOriginalExceptionNotSwallow(self):
-    self.mock_platform_backend.platform.FlushDnsCache.side_effect = (
-        IntentionalException('Boom!'))
-    self.mock_platform_backend.WillCloseBrowser.side_effect = (
-        IntentionalException('Cannot close browser!'))
-    with self.assertRaises(IntentionalException) as context:
-      browser_module.Browser(
-         self.mock_browser_backend, self.mock_platform_backend,
-         credentials_path=None)
-    self.assertIn('Boom!', context.exception.message)
-
-
-class BrowserRestoreSessionTest(unittest.TestCase):
-
-  @classmethod
-  def setUpClass(cls):
-    cls._number_of_tabs = 4
-    cls._profile_dir = _GenerateBrowserProfile(cls._number_of_tabs)
-    cls._options = options_for_unittests.GetCopy()
-    cls._options.browser_options.AppendExtraBrowserArgs(
-        ['--restore-last-session'])
-    cls._options.browser_options.profile_dir = cls._profile_dir
-    cls._browser_to_create = browser_finder.FindBrowser(cls._options)
-    cls._browser_to_create.platform.network_controller.InitializeIfNeeded()
-
-  @decorators.Enabled('has tabs')
-  @decorators.Disabled('chromeos', 'win', 'mac')
-  # TODO(nednguyen): Enable this test on windowsn platform
-  def testRestoreBrowserWithMultipleTabs(self):
-    with self._browser_to_create.Create(self._options) as browser:
-      # The number of tabs will be self._number_of_tabs + 1 as it includes the
-      # old tabs and a new blank tab.
-      expected_number_of_tabs = self._number_of_tabs + 1
-      try:
-        py_utils.WaitFor(
-            lambda: len(browser.tabs) == expected_number_of_tabs, 10)
-      except:
-        logging.error('Number of tabs is %s' % len(browser.tabs))
-        raise
-      self.assertEquals(expected_number_of_tabs, len(browser.tabs))
-
-  @classmethod
-  def tearDownClass(cls):
-    cls._browser_to_create.platform.network_controller.Close()
-    shutil.rmtree(cls._profile_dir)
-
-
-class TestBrowserOperationDoNotLeakTempFiles(unittest.TestCase):
-
-  @decorators.Enabled('win', 'mac', 'linux')
-  @decorators.Isolated
-  def testBrowserNotLeakingTempFiles(self):
-    options = options_for_unittests.GetCopy()
-    browser_to_create = browser_finder.FindBrowser(options)
-    self.assertIsNotNone(browser_to_create)
-    before_browser_run_temp_dir_content = os.listdir(tempfile.tempdir)
-    browser_to_create.platform.network_controller.InitializeIfNeeded()
-    try:
-      with browser_to_create.Create(options) as browser:
-        tab = browser.tabs.New()
-        tab.Navigate('about:blank')
-        self.assertEquals(2, tab.EvaluateJavaScript('1 + 1'))
-      after_browser_run_temp_dir_content = os.listdir(tempfile.tempdir)
-      self.assertEqual(before_browser_run_temp_dir_content,
-                       after_browser_run_temp_dir_content)
-    finally:
-      browser_to_create.platform.network_controller.Close()
diff --git a/catapult/telemetry/telemetry/internal/browser/extension_dict.py b/catapult/telemetry/telemetry/internal/browser/extension_dict.py
deleted file mode 100644
index 95742b5..0000000
--- a/catapult/telemetry/telemetry/internal/browser/extension_dict.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.browser import extension_to_load
-
-
-class ExtensionDict(object):
-  """Dictionary of ExtensionPage instances, with extension_id as key."""
-
-  def __init__(self, extension_backend):
-    self._extension_backend = extension_backend
-
-  def __getitem__(self, load_extension):
-    """Given an ExtensionToLoad instance, returns the corresponding
-    ExtensionPage instance."""
-    if not isinstance(load_extension, extension_to_load.ExtensionToLoad):
-      raise TypeError("Input param must be of type ExtensionToLoad")
-    return self.GetByExtensionId(load_extension.extension_id)[0]
-
-  def __contains__(self, load_extension):
-    """Checks if this ExtensionToLoad instance has been loaded"""
-    if not isinstance(load_extension, extension_to_load.ExtensionToLoad):
-      raise TypeError("Input param must be of type ExtensionToLoad")
-    return load_extension.extension_id in self._extension_backend
-
-  def keys(self):
-    return self._extension_backend.keys()
-
-  def GetByExtensionId(self, extension_id):
-    """Returns a list of extensions given an extension id. This is useful for
-    connecting to built-in apps and component extensions."""
-    return self._extension_backend[extension_id]
diff --git a/catapult/telemetry/telemetry/internal/browser/extension_page.py b/catapult/telemetry/telemetry/internal/browser/extension_page.py
deleted file mode 100644
index 350de6c..0000000
--- a/catapult/telemetry/telemetry/internal/browser/extension_page.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-from telemetry.internal.browser import web_contents
-
-
-def UrlToExtensionId(url):
-  return re.match(r"(chrome-extension://)([^/]+)", url).group(2)
-
-
-class ExtensionPage(web_contents.WebContents):
-  """Represents an extension page in the browser"""
-
-  def __init__(self, inspector_backend):
-    super(ExtensionPage, self).__init__(inspector_backend)
-    self.url = inspector_backend.url
-    self.extension_id = UrlToExtensionId(self.url)
-
-  def Reload(self):
-    """Reloading an extension page is used as a workaround for an extension
-    binding bug for old versions of Chrome (crbug.com/263162). After Navigate
-    returns, we are guaranteed that the inspected page is in the correct state.
-    """
-    self._inspector_backend.Navigate(self.url, None, 10)
diff --git a/catapult/telemetry/telemetry/internal/browser/extension_to_load.py b/catapult/telemetry/telemetry/internal/browser/extension_to_load.py
deleted file mode 100644
index bec211c..0000000
--- a/catapult/telemetry/telemetry/internal/browser/extension_to_load.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-
-from telemetry.internal.backends.chrome import crx_id
-
-
-class ExtensionPathNonExistentException(Exception):
-  pass
-
-class MissingPublicKeyException(Exception):
-  pass
-
-class ExtensionToLoad(object):
-  def __init__(self, path, browser_type):
-    if not os.path.isdir(path):
-      raise ExtensionPathNonExistentException(
-          'Extension path not a directory %s' % path)
-    self._path = path
-    self._local_path = path
-    # It is possible that we are running telemetry on Windows targeting
-    # a remote CrOS or Android device. In this case, we need the
-    # browser_type argument to determine how we should encode
-    # the extension path.
-    self._is_win = (os.name == 'nt'
-        and not (browser_type.startswith('android')
-                 or browser_type.startswith('cros')))
-
-  @property
-  def extension_id(self):
-    """Unique extension id of this extension."""
-    if crx_id.HasPublicKey(self._path):
-      # Calculate extension id from the public key.
-      return crx_id.GetCRXAppID(os.path.realpath(self._path))
-    else:
-      # Calculate extension id based on the path on the device.
-      return crx_id.GetCRXAppID(
-          os.path.realpath(self._local_path),
-          from_file_path=True,
-          is_win_path=self._is_win)
-
-  @property
-  def path(self):
-    """Path to extension source directory."""
-    return self._path
-
-  @property
-  def local_path(self):
-    """Path to extension destination directory, for remote instances of
-    chrome"""
-    return self._local_path
-
-  @local_path.setter
-  def local_path(self, local_path):
-    self._local_path = local_path
-
diff --git a/catapult/telemetry/telemetry/internal/browser/extension_unittest.py b/catapult/telemetry/telemetry/internal/browser/extension_unittest.py
deleted file mode 100644
index 514f2a5..0000000
--- a/catapult/telemetry/telemetry/internal/browser/extension_unittest.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import shutil
-import tempfile
-import unittest
-
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import extension_to_load
-from telemetry.testing import options_for_unittests
-
-
-class ExtensionTest(unittest.TestCase):
-  def setUp(self):
-    self._browser = None
-    self._platform = None
-    self._extension = None
-    self._extension_id = None
-
-  def CreateBrowserWithExtension(self, ext_path):
-    extension_path = os.path.join(util.GetUnittestDataDir(), ext_path)
-    options = options_for_unittests.GetCopy()
-    load_extension = extension_to_load.ExtensionToLoad(
-        extension_path, options.browser_type)
-    options.browser_options.extensions_to_load = [load_extension]
-    browser_to_create = browser_finder.FindBrowser(options)
-
-    if not browser_to_create:
-      # May not find a browser that supports extensions.
-      return False
-    self._platform = browser_to_create.platform
-    self._platform.network_controller.InitializeIfNeeded()
-    self._browser = browser_to_create.Create(options)
-    self._extension = self._browser.extensions[load_extension]
-    self._extension_id = load_extension.extension_id
-    self.assertTrue(self._extension)
-    return True
-
-  def tearDown(self):
-    if self._browser:
-      self._browser.Close()
-      self._platform.network_controller.Close()
-
-  def testExtensionBasic(self):
-    """Test ExtensionPage's ExecuteJavaScript and EvaluateJavaScript."""
-    if not self.CreateBrowserWithExtension('simple_extension'):
-      logging.warning('Did not find a browser that supports extensions, '
-                      'skipping test.')
-      return
-    self.assertTrue(
-        self._extension.EvaluateJavaScript('chrome.runtime != null'))
-    self._extension.ExecuteJavaScript('setTestVar("abcdef")')
-    self.assertEquals('abcdef',
-                      self._extension.EvaluateJavaScript('_testVar'))
-
-  def testExtensionGetByExtensionId(self):
-    """Test GetByExtensionId for a simple extension with a background page."""
-    if not self.CreateBrowserWithExtension('simple_extension'):
-      logging.warning('Did not find a browser that supports extensions, '
-                      'skipping test.')
-      return
-    ext = self._browser.extensions.GetByExtensionId(self._extension_id)
-    self.assertEqual(1, len(ext))
-    self.assertEqual(ext[0], self._extension)
-    self.assertTrue(
-        ext[0].EvaluateJavaScript('chrome.runtime != null'))
-
-  @decorators.Disabled('mac')
-  def testWebApp(self):
-    """Tests GetByExtensionId for a web app with multiple pages."""
-    if not self.CreateBrowserWithExtension('simple_app'):
-      logging.warning('Did not find a browser that supports extensions, '
-                      'skipping test.')
-      return
-    extensions = self._browser.extensions.GetByExtensionId(self._extension_id)
-    extension_urls = set([ext.EvaluateJavaScript('location.href;')
-                          for ext in extensions])
-    expected_urls = set(['chrome-extension://' + self._extension_id + '/' + path
-                         for path in ['main.html', 'second.html',
-                                      '_generated_background_page.html']])
-
-    self.assertEqual(expected_urls, extension_urls)
-
-class NonExistentExtensionTest(unittest.TestCase):
-  def testNonExistentExtensionPath(self):
-    """Test that a non-existent extension path will raise an exception."""
-    extension_path = os.path.join(util.GetUnittestDataDir(), 'foo')
-    options = options_for_unittests.GetCopy()
-    self.assertRaises(extension_to_load.ExtensionPathNonExistentException,
-                      lambda: extension_to_load.ExtensionToLoad(
-                          extension_path, options.browser_type))
-
-  def testExtensionNotLoaded(self):
-    """Querying an extension that was not loaded will return None"""
-    extension_path = os.path.join(util.GetUnittestDataDir(), 'simple_extension')
-    options = options_for_unittests.GetCopy()
-    load_extension = extension_to_load.ExtensionToLoad(
-        extension_path, options.browser_type)
-    browser_to_create = browser_finder.FindBrowser(options)
-    try:
-      browser_to_create.platform.network_controller.InitializeIfNeeded()
-      with browser_to_create.Create(options) as b:
-        if b.supports_extensions:
-          self.assertRaises(KeyError, lambda: b.extensions[load_extension])
-    finally:
-      browser_to_create.platform.network_controller.Close()
-
-class MultipleExtensionTest(unittest.TestCase):
-  def setUp(self):
-    """ Copy the manifest and background.js files of simple_extension to a
-    number of temporary directories to load as extensions"""
-    self._extension_dirs = [tempfile.mkdtemp() for _ in range(3)]
-    src_extension_dir = os.path.join(
-        util.GetUnittestDataDir(), 'simple_extension')
-    manifest_path = os.path.join(src_extension_dir, 'manifest.json')
-    script_path = os.path.join(src_extension_dir, 'background.js')
-    for d in self._extension_dirs:
-      shutil.copy(manifest_path, d)
-      shutil.copy(script_path, d)
-    options = options_for_unittests.GetCopy()
-    self._extensions_to_load = [extension_to_load.ExtensionToLoad(
-                                    d, options.browser_type)
-                                for d in self._extension_dirs]
-    options.browser_options.extensions_to_load = self._extensions_to_load
-    browser_to_create = browser_finder.FindBrowser(options)
-    self._platform = None
-    self._browser = None
-    # May not find a browser that supports extensions.
-    if browser_to_create:
-      self._platform = browser_to_create.platform
-      self._platform.network_controller.InitializeIfNeeded()
-      self._browser = browser_to_create.Create(options)
-
-  def tearDown(self):
-    if self._platform:
-      self._platform.network_controller.Close()
-    if self._browser:
-      self._browser.Close()
-    for d in self._extension_dirs:
-      shutil.rmtree(d)
-
-  def testMultipleExtensions(self):
-    if not self._browser:
-      logging.warning('Did not find a browser that supports extensions, '
-                      'skipping test.')
-      return
-
-    # Test contains.
-    loaded_extensions = [e for e in self._extensions_to_load
-                         if e in self._browser.extensions]
-    self.assertEqual(len(loaded_extensions), len(self._extensions_to_load))
-    for load_extension in self._extensions_to_load:
-      extension = self._browser.extensions[load_extension]
-      assert extension
-      self.assertTrue(
-          extension.EvaluateJavaScript('chrome.runtime != null'))
-      extension.ExecuteJavaScript('setTestVar("abcdef")')
-      self.assertEquals('abcdef', extension.EvaluateJavaScript('_testVar'))
-
-
-class WebviewInExtensionTest(ExtensionTest):
-
-  # Flaky on windows, hits an exception: http://crbug.com/508325
-  # Flaky on macOS too: http://crbug.com/661434
-  # ChromeOS: http://crbug.com/674220
-  @decorators.Disabled('win', 'linux', 'mac', 'chromeos')
-  def testWebviewInExtension(self):
-    """Tests GetWebviewContext() for a web app containing <webview> element."""
-    if not self.CreateBrowserWithExtension('webview_app'):
-      logging.warning('Did not find a browser that supports extensions, '
-                      'skipping test.')
-      return
-
-    self._browser.extensions.GetByExtensionId(self._extension_id)
-    webview_contexts = self._extension.GetWebviewContexts()
-    self.assertEquals(1, len(webview_contexts))
-    webview_context = webview_contexts[0]
-    webview_context.WaitForDocumentReadyStateToBeComplete()
-    # Check that the context has the right url from the <webview> element.
-    self.assertTrue(webview_context.GetUrl().startswith('data:'))
-    # Check |test_input_id| element is accessible from the webview context.
-    self.assertTrue(webview_context.EvaluateJavaScript(
-                    'document.getElementById("test_input_id") != null'))
-    # Check that |test_input_id| is not accessible from outside webview context
-    self.assertFalse(self._extension.EvaluateJavaScript(
-                    'document.getElementById("test_input_id") != null'))
diff --git a/catapult/telemetry/telemetry/internal/browser/network_quiescence.js b/catapult/telemetry/telemetry/internal/browser/network_quiescence.js
deleted file mode 100644
index f317d6c..0000000
--- a/catapult/telemetry/telemetry/internal/browser/network_quiescence.js
+++ /dev/null
@@ -1,107 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @fileoverview This file provides a JavaScript helper function that
- * determines when network quiescence has been reached based on the time since
- * the last resource was received.
- */
-(function() {
-
-  // Make executing this code idempotent.
-  if (window.__telemetry_testHasReachedNetworkQuiescence) {
-    return;
-  }
-
-  // Some benchmarks patch window.performance to make it deterministic.
-  // Save the original performance object before it is patched.
-  var real_performance = window.performance;
-
-  // Set the Resource Timing interface functions that will be used below
-  // to use whatever version is available currently regardless of vendor
-  // prefix.
-  real_performance.clearResourceTimings =
-      (real_performance.clearResourceTimings     ||
-       real_performance.mozClearResourceTimings  ||
-       real_performance.msClearResourceTimings   ||
-       real_performance.oClearResourceTimings    ||
-       real_performance.webkitClearResourceTimings);
-
-  real_performance.getEntriesByType =
-      (real_performance.getEntriesByType     ||
-       real_performance.mozGetEntriesByType  ||
-       real_performance.msGetEntriesByType   ||
-       real_performance.oGetEntriesByType    ||
-       real_performance.webkitGetEntriesByType);
-
-  // This variable will available to the function below and it will be
-  // persistent across different function calls. It stores the last
-  // entry in the list of PerformanceResourceTiming objects returned by
-  // real_performance.getEntriesByType('resource').
-  //
-  // The reason for doing it this way is because the buffer for
-  // PerformanceResourceTiming objects has a limit, and once it's full,
-  // new entries are not added. We're only interested in the last entry,
-  // so we can clear new entries when they're added.
-  var lastEntry = null;
-
-  // True when no resource has been loaded from the network for
-  //|QUIESCENCE_TIMEOUT_MS| milliseconds. This value is sticky.
-  var hasReachedQuiesence = false;
-
-  // Time to wait before declaring network quiescence in milliseconds.
-  var QUIESCENCE_TIMEOUT_MS = 2000;
-
-  /**
-   * This method uses the Resource Timing interface, which is described at
-   * http://www.w3.org/TR/resource-timing/. It determines whether the time
-   * since lodading any resources such as images and script files (including
-   * resources requested via XMLHttpRequest) has exceeded a threshold defined
-   # by |QUIESCENCE_TIMEOUT_MS|.
-   *
-   * @return {boolean} True if the time since either the load event, or the last
-   *   resource was received after the load event exceeds the aforementioned
-   *   threshold. This state is sticky, so once this function returns true for a
-   *   given page, it will always return true.
-   */
-  window.__telemetry_testHasReachedNetworkQuiescence = function() {
-    if (hasReachedQuiesence) {
-      return true;
-    }
-
-    if (window.document.readyState !== 'complete') {
-      return false;
-    }
-
-    var resourceTimings = real_performance.getEntriesByType('resource');
-    if (resourceTimings.length > 0) {
-      lastEntry = resourceTimings.pop();
-      real_performance.clearResourceTimings();
-    }
-
-    // The times for performance.now() and in the PerformanceResourceTiming
-    // objects are all in milliseconds since performance.timing.navigationStart,
-    // so we must also get load time in the same terms.
-    var timing = real_performance.timing;
-    var loadTime = timing.loadEventEnd - timing.navigationStart;
-    var lastResponseTimeMs = 0;
-
-    // If there have been no resource timing entries, or the last entry was
-    // before the load event, then use the time since the load event.
-    if (!lastEntry || lastEntry.responseEnd < loadTime) {
-      lastResponseTimeMs = real_performance.now() - loadTime;
-    } else {
-      lastResponseTimeMs = real_performance.now() - lastEntry.responseEnd;
-    }
-
-    if (lastResponseTimeMs >= QUIESCENCE_TIMEOUT_MS) {
-      hasReachedQuiesence = true;
-    }
-
-    return hasReachedQuiesence;
-  }
-
-})();
diff --git a/catapult/telemetry/telemetry/internal/browser/possible_browser.py b/catapult/telemetry/telemetry/internal/browser/possible_browser.py
deleted file mode 100644
index 499bf51..0000000
--- a/catapult/telemetry/telemetry/internal/browser/possible_browser.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.app import possible_app
-
-
-class PossibleBrowser(possible_app.PossibleApp):
-  """A browser that can be controlled.
-
-  Call Create() to launch the browser and begin manipulating it..
-  """
-
-  def __init__(self, browser_type, target_os, supports_tab_control):
-    super(PossibleBrowser, self).__init__(app_type=browser_type,
-                                          target_os=target_os)
-    self._supports_tab_control = supports_tab_control
-    self._credentials_path = None
-
-  def __repr__(self):
-    return 'PossibleBrowser(app_type=%s)' % self.app_type
-
-  @property
-  def browser_type(self):
-    return self.app_type
-
-  @property
-  def supports_tab_control(self):
-    return self._supports_tab_control
-
-  def _InitPlatformIfNeeded(self):
-    raise NotImplementedError()
-
-  def Create(self, finder_options):
-    raise NotImplementedError()
-
-  def SupportsOptions(self, browser_options):
-    """Tests for extension support."""
-    raise NotImplementedError()
-
-  def IsRemote(self):
-    return False
-
-  def RunRemote(self):
-    pass
-
-  def UpdateExecutableIfNeeded(self):
-    pass
-
-  def last_modification_time(self):
-    return -1
-
-  def SetCredentialsPath(self, credentials_path):
-    self._credentials_path = credentials_path
diff --git a/catapult/telemetry/telemetry/internal/browser/profile_types.py b/catapult/telemetry/telemetry/internal/browser/profile_types.py
deleted file mode 100644
index 73a0408..0000000
--- a/catapult/telemetry/telemetry/internal/browser/profile_types.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.core import util
-
-BASE_PROFILE_TYPES = ['clean', 'default']
-
-PROFILE_TYPE_MAPPING = {
-  'typical_user': 'content_scripts1',
-  'power_user': 'extension_webrequest',
-}
-
-def GetProfileTypes():
-  """Returns a list of all command line options that can be specified for
-  profile type."""
-  return BASE_PROFILE_TYPES + PROFILE_TYPE_MAPPING.keys()
-
-def GetProfileDir(profile_type):
-  """Given a |profile_type| (as returned by GetProfileTypes()), return the
-  directory to use for that profile or None if the profile doesn't need a
-  profile directory (e.g. using the browser default profile).
-  """
-  if profile_type in BASE_PROFILE_TYPES:
-    return None
-
-  path = os.path.join(
-      util.GetTelemetryDir(), 'telemetry', 'internal', 'browser_profiles')
-
-  assert os.path.exists(path)
-  return path
diff --git a/catapult/telemetry/telemetry/internal/browser/profile_types_unittest.py b/catapult/telemetry/telemetry/internal/browser/profile_types_unittest.py
deleted file mode 100644
index fd99c1a..0000000
--- a/catapult/telemetry/telemetry/internal/browser/profile_types_unittest.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.internal.browser import profile_types
-
-
-class ProfileTypesTest(unittest.TestCase):
-  def testGetProfileTypes(self):
-    types = profile_types.GetProfileTypes()
-
-    self.assertTrue('clean' in types)
-    self.assertTrue(len(types) > 0)
-
-  def testGetProfileDir(self):
-    self.assertFalse(profile_types.GetProfileDir('typical_user') is None)
diff --git a/catapult/telemetry/telemetry/internal/browser/tab.py b/catapult/telemetry/telemetry/internal/browser/tab.py
deleted file mode 100644
index c847be6..0000000
--- a/catapult/telemetry/telemetry/internal/browser/tab.py
+++ /dev/null
@@ -1,269 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import action_runner
-from telemetry.internal.browser import web_contents
-from telemetry.internal.image_processing import video
-
-DEFAULT_TAB_TIMEOUT = 60
-
-
-class Tab(web_contents.WebContents):
-  """Represents a tab in the browser
-
-  The important parts of the Tab object are in the runtime and page objects.
-  E.g.:
-      # Navigates the tab to a given url.
-      tab.Navigate('http://www.google.com/')
-
-      # Evaluates 1+1 in the tab's JavaScript context.
-      tab.Evaluate('1+1')
-  """
-  def __init__(self, inspector_backend, tab_list_backend, browser):
-    super(Tab, self).__init__(inspector_backend)
-    self._tab_list_backend = tab_list_backend
-    self._browser = browser
-    self._action_runner = action_runner.ActionRunner(self)
-
-  @property
-  def browser(self):
-    """The browser in which this tab resides."""
-    return self._browser
-
-  @property
-  def action_runner(self):
-    return self._action_runner
-
-  @property
-  def url(self):
-    """Returns the URL of the tab, as reported by devtools.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-    """
-    return self._inspector_backend.url
-
-  @property
-  def dom_stats(self):
-    """A dictionary populated with measured DOM statistics.
-
-    Currently this dictionary contains:
-    {
-      'document_count': integer,
-      'node_count': integer,
-      'event_listener_count': integer
-    }
-
-    Raises:
-      inspector_memory.InspectorMemoryException
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    dom_counters = self._inspector_backend.GetDOMStats(
-        timeout=DEFAULT_TAB_TIMEOUT)
-    assert (len(dom_counters) == 3 and
-            all([x in dom_counters for x in ['document_count', 'node_count',
-                                             'event_listener_count']]))
-    return dom_counters
-
-  def Activate(self):
-    """Brings this tab to the foreground asynchronously.
-
-    Not all browsers or browser versions support this method.
-    Be sure to check browser.supports_tab_control.
-
-    Please note: this is asynchronous. There is a delay between this call
-    and the page's documentVisibilityState becoming 'visible', and yet more
-    delay until the actual tab is visible to the user. None of these delays
-    are included in this call.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-      devtools_client_backend.TabNotFoundError
-      tab_list_backend.TabUnexpectedResponseException
-    """
-    self._tab_list_backend.ActivateTab(self.id)
-
-  def Close(self):
-    """Closes this tab.
-
-    Not all browsers or browser versions support this method.
-    Be sure to check browser.supports_tab_control.
-
-    Raises:
-      devtools_http.DevToolsClientConnectionError
-      devtools_client_backend.TabNotFoundError
-      tab_list_backend.TabUnexpectedResponseException
-      exceptions.TimeoutException
-    """
-    self._tab_list_backend.CloseTab(self.id)
-
-  @property
-  def screenshot_supported(self):
-    """True if the browser instance is capable of capturing screenshots."""
-    return self._inspector_backend.screenshot_supported
-
-  def Screenshot(self, timeout=DEFAULT_TAB_TIMEOUT):
-    """Capture a screenshot of the tab's contents.
-
-    Returns:
-      A telemetry.core.Bitmap.
-    Raises:
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.Screenshot(timeout)
-
-  @property
-  def video_capture_supported(self):
-    """True if the browser instance is capable of capturing video."""
-    return self.browser.platform.CanCaptureVideo()
-
-  def Highlight(self, color):
-    """Synchronously highlights entire tab contents with the given RgbaColor.
-
-    TODO(tonyg): It is possible that the z-index hack here might not work for
-    all pages. If this happens, DevTools also provides a method for this.
-
-    Raises:
-      exceptions.EvaluateException
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    screen_save = 'window.__telemetry_screen_%d' % int(color)
-    self.ExecuteJavaScript("""
-        (function() {
-          var screen = document.createElement('div');
-          screen.style.background = {{ color }};
-          screen.style.position = 'fixed';
-          screen.style.top = '0';
-          screen.style.left = '0';
-          screen.style.width = '100%';
-          screen.style.height = '100%';
-          screen.style.zIndex = '2147483638';
-          document.body.appendChild(screen);
-          requestAnimationFrame(function() {
-            requestAnimationFrame(function() {
-              {{ @screen_save }} = screen;
-            });
-          });
-        })();
-        """,
-        color='rgba(%d, %d, %d, %d)' % (color.r, color.g, color.b, color.a),
-        screen_save=screen_save)
-    self.WaitForJavaScriptCondition(
-        '!!{{ @screen_save }}', screen_save=screen_save, timeout=5)
-
-  def ClearHighlight(self, color):
-    """Clears a highlight of the given bitmap.RgbaColor.
-
-    Raises:
-      exceptions.EvaluateException
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    screen_save = 'window.__telemetry_screen_%d' % int(color)
-    self.ExecuteJavaScript("""
-        (function() {
-          document.body.removeChild({{ @screen_save }});
-          requestAnimationFrame(function() {
-            requestAnimationFrame(function() {
-              {{ @screen_save }} = null;
-              console.time('__ClearHighlight.video_capture_start');
-              console.timeEnd('__ClearHighlight.video_capture_start');
-            });
-          });
-        })();
-        """, screen_save=screen_save)
-    self.WaitForJavaScriptCondition(
-        '!{{ @screen_save }}', screen_save=screen_save, timeout=5)
-
-  def StartVideoCapture(self, min_bitrate_mbps,
-                        highlight_bitmap=video.HIGHLIGHT_ORANGE_FRAME):
-    """Starts capturing video of the tab's contents.
-
-    This works by flashing the entire tab contents to a arbitrary color and then
-    starting video recording. When the frames are processed, we can look for
-    that flash as the content bounds.
-
-    Args:
-      min_bitrate_mbps: The minimum caputre bitrate in MegaBits Per Second.
-          The platform is free to deliver a higher bitrate if it can do so
-          without increasing overhead.
-
-    Raises:
-      exceptions.EvaluateException
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-      ValueError: If the required |min_bitrate_mbps| can't be achieved.
-    """
-    self.Highlight(highlight_bitmap)
-    self.browser.platform.StartVideoCapture(min_bitrate_mbps)
-    self.ClearHighlight(highlight_bitmap)
-
-  @property
-  def is_video_capture_running(self):
-    return self.browser.platform.is_video_capture_running
-
-  def StopVideoCapture(self):
-    """Stops recording video of the tab's contents.
-
-    This looks for the initial color flash in the first frame to establish the
-    tab content boundaries and then omits all frames displaying the flash.
-
-    Returns:
-      video: A video object which is a telemetry.core.Video
-    """
-    return self.browser.platform.StopVideoCapture()
-
-  def GetCookieByName(self, name, timeout=DEFAULT_TAB_TIMEOUT):
-    """Returns the value of the cookie by the given |name|.
-
-    Raises:
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.GetCookieByName(name, timeout)
-
-  def CollectGarbage(self):
-    """Forces a garbage collection.
-
-    Raises:
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    self._inspector_backend.CollectGarbage()
-
-  def ClearCache(self, force):
-    """Clears the browser's networking related disk, memory and other caches.
-
-    Args:
-      force: Iff true, navigates to about:blank which destroys the previous
-          renderer, ensuring that even "live" resources in the memory cache are
-          cleared.
-
-    Raises:
-      exceptions.EvaluateException
-      exceptions.WebSocketDisconnected
-      exceptions.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-      errors.DeviceUnresponsiveError
-    """
-    self.browser.platform.FlushDnsCache()
-    self.ExecuteJavaScript("""
-        if (window.chrome && chrome.benchmarking &&
-            chrome.benchmarking.clearCache) {
-          chrome.benchmarking.clearCache();
-          chrome.benchmarking.clearPredictorCache();
-          chrome.benchmarking.clearHostResolverCache();
-        }
-    """)
-    if force:
-      self.Navigate('about:blank')
diff --git a/catapult/telemetry/telemetry/internal/browser/tab_list.py b/catapult/telemetry/telemetry/internal/browser/tab_list.py
deleted file mode 100644
index 99bbaae..0000000
--- a/catapult/telemetry/telemetry/internal/browser/tab_list.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-class TabList(object):
-  def __init__(self, tab_list_backend):
-    self._tab_list_backend = tab_list_backend
-
-  def New(self, timeout=300):
-    return self._tab_list_backend.New(timeout)
-
-  def __iter__(self):
-    return self._tab_list_backend.__iter__()
-
-  def __len__(self):
-    return self._tab_list_backend.__len__()
-
-  def __getitem__(self, index):
-    return self._tab_list_backend.__getitem__(index)
-
-  def GetTabById(self, identifier):
-    """The identifier of a tab can be accessed with tab.id."""
-    return self._tab_list_backend.GetTabById(identifier)
-
diff --git a/catapult/telemetry/telemetry/internal/browser/tab_unittest.py b/catapult/telemetry/telemetry/internal/browser/tab_unittest.py
deleted file mode 100644
index 9170f8b..0000000
--- a/catapult/telemetry/telemetry/internal/browser/tab_unittest.py
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import tempfile
-import time
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.image_processing import video
-from telemetry.testing import tab_test_case
-from telemetry.timeline import model
-from telemetry.timeline import tracing_config
-from telemetry.util import image_util
-from telemetry.util import rgba_color
-
-import py_utils
-
-
-def _IsDocumentVisible(tab):
-  return not tab.EvaluateJavaScript('document.hidden || document.webkitHidden')
-
-
-class FakePlatformBackend(object):
-  def __init__(self):
-    self.platform = FakePlatform()
-
-  def DidStartBrowser(self, _, _2):
-    pass
-
-  def WillCloseBrowser(self, _, _2):
-    pass
-
-
-class FakePlatform(object):
-  def __init__(self):
-    self._is_video_capture_running = False
-
-  #pylint: disable=unused-argument
-  def StartVideoCapture(self, min_bitrate_mbps):
-    self._is_video_capture_running = True
-
-  def StopVideoCapture(self):
-    self._is_video_capture_running = False
-    return video.Video(tempfile.NamedTemporaryFile())
-
-  @property
-  def is_video_capture_running(self):
-    return self._is_video_capture_running
-
-
-class TabTest(tab_test_case.TabTestCase):
-  def testNavigateAndWaitForCompleteState(self):
-    self._tab.Navigate(self.UrlOfUnittestFile('blank.html'))
-    self._tab.WaitForDocumentReadyStateToBeComplete()
-
-  def testNavigateAndWaitForInteractiveState(self):
-    self._tab.Navigate(self.UrlOfUnittestFile('blank.html'))
-    self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-
-  def testTabBrowserIsRightBrowser(self):
-    self.assertEquals(self._tab.browser, self._browser)
-
-  def testRendererCrash(self):
-    self.assertRaises(exceptions.DevtoolsTargetCrashException,
-                      lambda: self._tab.Navigate('chrome://crash',
-                                                 timeout=30))
-
-  def testTimeoutExceptionIncludeConsoleMessage(self):
-    self._tab.EvaluateJavaScript("""
-        window.__set_timeout_called = false;
-        function buggyReference() {
-          window.__set_timeout_called = true;
-          if (window.__one.not_defined === undefined)
-             window.__one = 1;
-        }
-        setTimeout(buggyReference, 200);""")
-    self._tab.WaitForJavaScriptCondition(
-        'window.__set_timeout_called === true', timeout=5)
-    with self.assertRaises(py_utils.TimeoutException) as context:
-      self._tab.WaitForJavaScriptCondition(
-          'window.__one === 1', timeout=1)
-      self.assertIn(
-        ("(error) :5: Uncaught TypeError: Cannot read property 'not_defined' "
-        'of undefined\n'),
-        context.exception.message)
-
-  @decorators.Enabled('has tabs')
-  def testActivateTab(self):
-    py_utils.WaitFor(lambda: _IsDocumentVisible(self._tab), timeout=5)
-    new_tab = self._browser.tabs.New()
-    new_tab.Navigate('about:blank')
-    py_utils.WaitFor(lambda: _IsDocumentVisible(new_tab), timeout=5)
-    self.assertFalse(_IsDocumentVisible(self._tab))
-    self._tab.Activate()
-    py_utils.WaitFor(lambda: _IsDocumentVisible(self._tab), timeout=5)
-    self.assertFalse(_IsDocumentVisible(new_tab))
-
-  def testTabUrl(self):
-    self.assertEquals(self._tab.url, 'about:blank')
-    url = self.UrlOfUnittestFile('blank.html')
-    self._tab.Navigate(url)
-    self.assertEquals(self._tab.url, url)
-
-  #pylint: disable=protected-access
-  def testIsVideoCaptureRunning(self):
-    original_platform_backend = self._tab.browser._platform_backend
-    try:
-      self._tab.browser._platform_backend = FakePlatformBackend()
-      self.assertFalse(self._tab.is_video_capture_running)
-      self._tab.StartVideoCapture(min_bitrate_mbps=2)
-      self.assertTrue(self._tab.is_video_capture_running)
-      self.assertIsNotNone(self._tab.StopVideoCapture())
-      self.assertFalse(self._tab.is_video_capture_running)
-    finally:
-      self._tab.browser._platform_backend = original_platform_backend
-
-  # Test failing on android: http://crbug.com/437057
-  # and mac: http://crbug.com/468675
-  @decorators.Disabled('android', 'chromeos', 'mac')
-  def testHighlight(self):
-    self.assertEquals(self._tab.url, 'about:blank')
-    config = tracing_config.TracingConfig()
-    config.chrome_trace_config.SetLowOverheadFilter()
-    config.enable_chrome_trace = True
-    self._browser.platform.tracing_controller.StartTracing(config)
-    self._tab.Highlight(rgba_color.WEB_PAGE_TEST_ORANGE)
-    self._tab.ClearHighlight(rgba_color.WEB_PAGE_TEST_ORANGE)
-    trace_data = self._browser.platform.tracing_controller.StopTracing()
-    timeline_model = model.TimelineModel(trace_data)
-    renderer_thread = timeline_model.GetRendererThreadFromTabId(
-        self._tab.id)
-    found_video_start_event = False
-    for event in renderer_thread.async_slices:
-      if event.name == '__ClearHighlight.video_capture_start':
-        found_video_start_event = True
-        break
-    self.assertTrue(found_video_start_event)
-
-  @decorators.Enabled('has tabs')
-  @decorators.Disabled('mac', 'linux')  # crbug.com/499207.
-  def testGetRendererThreadFromTabId(self):
-    self.assertEquals(self._tab.url, 'about:blank')
-    # Create 3 tabs. The third tab is closed before we call
-    # tracing_controller.StartTracing.
-    first_tab = self._tab
-    second_tab = self._browser.tabs.New()
-    second_tab.Navigate('about:blank')
-    second_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-    third_tab = self._browser.tabs.New()
-    third_tab.Navigate('about:blank')
-    third_tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-    third_tab.Close()
-    config = tracing_config.TracingConfig()
-    config.chrome_trace_config.SetLowOverheadFilter()
-    config.enable_chrome_trace = True
-    self._browser.platform.tracing_controller.StartTracing(config)
-    first_tab.ExecuteJavaScript('console.time("first-tab-marker");')
-    first_tab.ExecuteJavaScript('console.timeEnd("first-tab-marker");')
-    second_tab.ExecuteJavaScript('console.time("second-tab-marker");')
-    second_tab.ExecuteJavaScript('console.timeEnd("second-tab-marker");')
-    trace_data = self._browser.platform.tracing_controller.StopTracing()
-    timeline_model = model.TimelineModel(trace_data)
-
-    # Assert that the renderer_thread of the first tab contains
-    # 'first-tab-marker'.
-    renderer_thread = timeline_model.GetRendererThreadFromTabId(
-        first_tab.id)
-    first_tab_markers = [
-        renderer_thread.IterAllSlicesOfName('first-tab-marker')]
-    self.assertEquals(1, len(first_tab_markers))
-
-    # Close second tab and assert that the renderer_thread of the second tab
-    # contains 'second-tab-marker'.
-    second_tab.Close()
-    renderer_thread = timeline_model.GetRendererThreadFromTabId(
-        second_tab.id)
-    second_tab_markers = [
-        renderer_thread.IterAllSlicesOfName('second-tab-marker')]
-    self.assertEquals(1, len(second_tab_markers))
-
-    # Third tab wasn't available when we start tracing, so there is no
-    # renderer_thread corresponding to it in the the trace.
-    self.assertIs(None, timeline_model.GetRendererThreadFromTabId(third_tab.id))
-
-  @decorators.Disabled('android') # https://crbug.com/463933
-  def testTabIsAlive(self):
-    self.assertEquals(self._tab.url, 'about:blank')
-    self.assertTrue(self._tab.IsAlive())
-
-    self._tab.Navigate(self.UrlOfUnittestFile('blank.html'))
-    self.assertTrue(self._tab.IsAlive())
-
-    self.assertRaises(exceptions.DevtoolsTargetCrashException,
-        lambda: self._tab.Navigate(self.UrlOfUnittestFile('chrome://crash')))
-    self.assertFalse(self._tab.IsAlive())
-
-
-class GpuTabTest(tab_test_case.TabTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
-
-  # Test flaky on mac: crbug.com/358664, chromeos: crbug.com/483212.
-  @decorators.Disabled('android', 'mac', 'chromeos')
-  @decorators.Disabled('win')  # catapult/issues/2282
-  def testScreenshot(self):
-    if not self._tab.screenshot_supported:
-      logging.warning('Browser does not support screenshots, skipping test.')
-      return
-
-    self.Navigate('green_rect.html')
-    pixel_ratio = self._tab.EvaluateJavaScript('window.devicePixelRatio || 1')
-
-    screenshot = self._tab.Screenshot(5)
-    assert screenshot is not None
-    image_util.GetPixelColor(
-        screenshot, 0 * pixel_ratio, 0 * pixel_ratio).AssertIsRGB(
-            0, 255, 0, tolerance=2)
-    image_util.GetPixelColor(
-        screenshot, 31 * pixel_ratio, 31 * pixel_ratio).AssertIsRGB(
-            0, 255, 0, tolerance=2)
-    image_util.GetPixelColor(
-        screenshot, 32 * pixel_ratio, 32 * pixel_ratio).AssertIsRGB(
-            255, 255, 255, tolerance=2)
-
-
-class MediaRouterDialogTabTest(tab_test_case.TabTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.AppendExtraBrowserArgs('--media-router=1')
-
-  # There is no media router dialog on android/chromeos, it is a desktop-only
-  # feature.
-  @decorators.Disabled('android', 'chromeos')
-  @decorators.Disabled('win')  # catapult/issues/2282
-  def testMediaRouterDialog(self):
-    self._tab.Navigate(self.UrlOfUnittestFile('cast.html'))
-    self._tab.WaitForDocumentReadyStateToBeComplete()
-    self._tab.action_runner.TapElement(selector='#start_session_button')
-    # Wait for media router dialog
-    start_time = time.time()
-    while (time.time() - start_time < 5 and
-           len(self.tabs) != 2):
-      time.sleep(1)
-    self.assertEquals(len(self.tabs), 2)
-    self.assertEquals(self.tabs[1].url, 'chrome://media-router/')
diff --git a/catapult/telemetry/telemetry/internal/browser/user_agent.py b/catapult/telemetry/telemetry/internal/browser/user_agent.py
deleted file mode 100644
index 8e968c9..0000000
--- a/catapult/telemetry/telemetry/internal/browser/user_agent.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-UA_TYPE_MAPPING = {
-  'desktop':
-      'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) '
-      'AppleWebKit/537.36 (KHTML, like Gecko) '
-      'Chrome/40.0.2194.2 Safari/537.36',
-  'mobile':
-      'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) '
-      'AppleWebKit/535.36 (KHTML, like Gecko) Chrome/40.0.2194.2 Mobile '
-      'Safari/535.36',
-  'tablet':
-      'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus 7 Build/IMM76B) '
-      'AppleWebKit/535.36 (KHTML, like Gecko) Chrome/40.0.2194.2 '
-      'Safari/535.36',
-  'tablet_10_inch':
-      'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus 10 Build/IMM76B) '
-      'AppleWebKit/535.36 (KHTML, like Gecko) Chrome/40.0.2194.2 '
-      'Safari/535.36',
-}
-
-
-def GetChromeUserAgentArgumentFromType(user_agent_type):
-  """Returns a chrome user agent based on a user agent type.
-  This is derived from:
-  https://developers.google.com/chrome/mobile/docs/user-agent
-  """
-  if user_agent_type:
-    return ['--user-agent=%s' % UA_TYPE_MAPPING[user_agent_type]]
-  return []
-
-def GetChromeUserAgentDictFromType(user_agent_type):
-  if user_agent_type:
-    return {'userAgent': UA_TYPE_MAPPING[user_agent_type]}
-  return {}
diff --git a/catapult/telemetry/telemetry/internal/browser/user_agent_unittest.py b/catapult/telemetry/telemetry/internal/browser/user_agent_unittest.py
deleted file mode 100644
index 19c5d68..0000000
--- a/catapult/telemetry/telemetry/internal/browser/user_agent_unittest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.internal.browser import user_agent
-from telemetry.testing import tab_test_case
-
-
-class MobileUserAgentTest(tab_test_case.TabTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.browser_user_agent_type = 'mobile'
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUserAgent(self):
-    ua = self._tab.EvaluateJavaScript('window.navigator.userAgent')
-    self.assertEquals(ua, user_agent.UA_TYPE_MAPPING['mobile'])
-
-class TabletUserAgentTest(tab_test_case.TabTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.browser_user_agent_type = 'tablet'
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUserAgent(self):
-    ua = self._tab.EvaluateJavaScript('window.navigator.userAgent')
-    self.assertEquals(ua, user_agent.UA_TYPE_MAPPING['tablet'])
-
-class DesktopUserAgentTest(tab_test_case.TabTestCase):
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    options.browser_user_agent_type = 'desktop'
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUserAgent(self):
-    ua = self._tab.EvaluateJavaScript('window.navigator.userAgent')
-    self.assertEquals(ua, user_agent.UA_TYPE_MAPPING['desktop'])
diff --git a/catapult/telemetry/telemetry/internal/browser/wait_for_frame.js b/catapult/telemetry/telemetry/internal/browser/wait_for_frame.js
deleted file mode 100644
index 761b9ba..0000000
--- a/catapult/telemetry/telemetry/internal/browser/wait_for_frame.js
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-'use strict';
-
-/**
- * @fileoverview This file provides a JavaScript helper function that
- * determines whether at least one frame has passed since the first
- * call of this function with the given request id.
- */
-(function() {
-
-  // Make executing this code idempotent.
-  if (window.__telemetry_testHasFramePassed) {
-    return;
-  }
-
-  // A dictionary which tracks the number of requestAnimationFrame calls that
-  // we are waiting on for the given request id.
-  var pending_frames = {};
-
-  window.__telemetry_testHasFramePassed = function(request_id) {
-    // If we already have pending frames for the given request id, there is
-    // no work to do, just return whether the pending frames have reached 0.
-    if (pending_frames.hasOwnProperty(request_id)) {
-      return pending_frames[request_id] == 0;
-    }
-
-    // We wait for two calls to requestAnimationFrame. When the first
-    // requestAnimationFrame is called, we know that a frame is in the
-    // pipeline. When the second requestAnimationFrame is called, we know that
-    // the first frame has reached the screen.
-    pending_frames[request_id] = 2;
-
-    var wait_for_raf = function() {
-      pending_frames[request_id]--;
-      if (pending_frames[request_id] > 0) {
-        window.requestAnimationFrame(wait_for_raf);
-      }
-    };
-
-    window.requestAnimationFrame(wait_for_raf);
-    return false;
-  };
-})();
diff --git a/catapult/telemetry/telemetry/internal/browser/web_contents.py b/catapult/telemetry/telemetry/internal/browser/web_contents.py
deleted file mode 100644
index 6cef07f..0000000
--- a/catapult/telemetry/telemetry/internal/browser/web_contents.py
+++ /dev/null
@@ -1,326 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.core import exceptions
-
-from py_trace_event import trace_event
-
-DEFAULT_WEB_CONTENTS_TIMEOUT = 90
-
-# TODO(achuith, dtu, nduca): Add unit tests specifically for WebContents,
-# independent of Tab.
-class WebContents(object):
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  """Represents web contents in the browser"""
-  def __init__(self, inspector_backend):
-    self._inspector_backend = inspector_backend
-
-    with open(os.path.join(os.path.dirname(__file__),
-        'network_quiescence.js')) as f:
-      self._quiescence_js = f.read()
-
-    with open(os.path.join(os.path.dirname(__file__),
-        'wait_for_frame.js')) as f:
-      self._wait_for_frame_js = f.read()
-
-    # An incrementing ID used to query frame timing javascript. Using a new id
-    # with each request ensures that previously timed-out wait for frame
-    # requests don't impact new requests.
-    self._wait_for_frame_id = 0
-
-  @property
-  def id(self):
-    """Return the unique id string for this tab object."""
-    return self._inspector_backend.id
-
-  def GetUrl(self):
-    """Returns the URL to which the WebContents is connected.
-
-    Raises:
-      exceptions.Error: If there is an error in inspector backend connection.
-    """
-    return self._inspector_backend.url
-
-  def GetWebviewContexts(self):
-    """Returns a list of webview contexts within the current inspector backend.
-
-    Returns:
-      A list of WebContents objects representing the webview contexts.
-
-    Raises:
-      exceptions.Error: If there is an error in inspector backend connection.
-    """
-    webviews = []
-    inspector_backends = self._inspector_backend.GetWebviewInspectorBackends()
-    for inspector_backend in inspector_backends:
-      webviews.append(WebContents(inspector_backend))
-    return webviews
-
-  def WaitForDocumentReadyStateToBeComplete(self,
-      timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
-    """Waits for the document to finish loading.
-
-    Raises:
-      exceptions.Error: See WaitForJavaScriptCondition() for a detailed list
-      of possible exceptions.
-    """
-
-    self.WaitForJavaScriptCondition(
-        'document.readyState == "complete"', timeout=timeout)
-
-  def WaitForDocumentReadyStateToBeInteractiveOrBetter(self,
-      timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
-    """Waits for the document to be interactive.
-
-    Raises:
-      exceptions.Error: See WaitForJavaScriptCondition() for a detailed list
-      of possible exceptions.
-    """
-    self.WaitForJavaScriptCondition(
-        'document.readyState == "interactive" || '
-        'document.readyState == "complete"', timeout=timeout)
-
-  def WaitForFrameToBeDisplayed(self,
-          timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
-    """Waits for a frame to be displayed before returning.
-
-    Raises:
-      exceptions.Error: See WaitForJavaScriptCondition() for a detailed list
-      of possible exceptions.
-    """
-    # Generate a new id for each call of this function to ensure that we track
-    # each request to wait seperately.
-    self._wait_for_frame_id += 1
-    self.WaitForJavaScriptCondition(
-        '{{ @script }}; window.__telemetry_testHasFramePassed({{ frame_id }})',
-        script=self._wait_for_frame_js,
-        frame_id=str(self._wait_for_frame_id),  # Place id as a str.
-        timeout=timeout)
-
-  def HasReachedQuiescence(self):
-    """Determine whether the page has reached quiescence after loading.
-
-    Returns:
-      True if 2 seconds have passed since last resource received, false
-      otherwise.
-    Raises:
-      exceptions.Error: See EvaluateJavaScript() for a detailed list of
-      possible exceptions.
-    """
-    # Inclusion of the script that provides
-    # window.__telemetry_testHasReachedNetworkQuiescence()
-    # is idempotent, it's run on every call because WebContents doesn't track
-    # page loads and we need to execute anew for every newly loaded page.
-    return self.EvaluateJavaScript(
-        '{{ @script }}; window.__telemetry_testHasReachedNetworkQuiescence()',
-        script=self._quiescence_js)
-
-  def ExecuteJavaScript(self, *args, **kwargs):
-    """Executes a given JavaScript statement. Does not return the result.
-
-    Example: runner.ExecuteJavaScript('var foo = {{ value }};', value='hi');
-
-    Args:
-      statement: The statement to execute (provided as a string).
-
-    Optional keyword args:
-      timeout: The number of seconds to wait for the statement to execute.
-      context_id: The id of an iframe where to execute the code; the main page
-          has context_id=1, the first iframe context_id=2, etc.
-      Additional keyword arguments provide values to be interpolated within
-          the statement. See telemetry.util.js_template for details.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.EvaluationException
-      exceptions.WebSocketException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.ExecuteJavaScript(*args, **kwargs)
-
-  def EvaluateJavaScript(self, *args, **kwargs):
-    """Returns the result of evaluating a given JavaScript expression.
-
-    Example: runner.ExecuteJavaScript('document.location.href');
-
-    Args:
-      expression: The expression to execute (provided as a string).
-
-    Optional keyword args:
-      timeout: The number of seconds to wait for the expression to evaluate.
-      context_id: The id of an iframe where to execute the code; the main page
-          has context_id=1, the first iframe context_id=2, etc.
-      Additional keyword arguments provide values to be interpolated within
-          the expression. See telemetry.util.js_template for details.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.EvaluationException
-      exceptions.WebSocketException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.EvaluateJavaScript(*args, **kwargs)
-
-  def WaitForJavaScriptCondition(self, *args, **kwargs):
-    """Wait for a JavaScript condition to become true.
-
-    Example: runner.WaitForJavaScriptCondition('window.foo == 10');
-
-    Args:
-      condition: The JavaScript condition (provided as string).
-
-    Optional keyword args:
-      timeout: The number in seconds to wait for the condition to become
-          True (default to 60).
-      context_id: The id of an iframe where to execute the code; the main page
-          has context_id=1, the first iframe context_id=2, etc.
-      Additional keyword arguments provide values to be interpolated within
-          the expression. See telemetry.util.js_template for details.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.EvaluationException
-      exceptions.WebSocketException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.WaitForJavaScriptCondition(*args, **kwargs)
-
-  def EnableAllContexts(self):
-    """Enable all contexts in a page. Returns the number of available contexts.
-
-    Raises:
-      exceptions.WebSocketDisconnected
-      py_utils.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.EnableAllContexts()
-
-  def WaitForNavigate(self, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
-    """Waits for the navigation to complete.
-
-    The current page is expect to be in a navigation.
-    This function returns when the navigation is complete or when
-    the timeout has been exceeded.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    self._inspector_backend.WaitForNavigate(timeout)
-
-  def Navigate(self, url, script_to_evaluate_on_commit=None,
-               timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
-    """Navigates to url.
-
-    If |script_to_evaluate_on_commit| is given, the script source string will be
-    evaluated when the navigation is committed. This is after the context of
-    the page exists, but before any script on the page itself has executed.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    self._inspector_backend.Navigate(url, script_to_evaluate_on_commit, timeout)
-
-  def IsAlive(self):
-    """Whether the WebContents is still operating normally.
-
-    Since WebContents function asynchronously, this method does not guarantee
-    that the WebContents will still be alive at any point in the future.
-
-    Returns:
-      A boolean indicating whether the WebContents is opearting normally.
-    """
-    return self._inspector_backend.IsInspectable()
-
-  def CloseConnections(self):
-    """Closes all TCP sockets held open by the browser.
-
-    Raises:
-      exceptions.DevtoolsTargetCrashException if the tab is not alive.
-    """
-    if not self.IsAlive():
-      raise exceptions.DevtoolsTargetCrashException
-    self.ExecuteJavaScript('window.chrome && chrome.benchmarking &&'
-                           'chrome.benchmarking.closeConnections()')
-
-  def SynthesizeScrollGesture(self, x=100, y=800, xDistance=0, yDistance=-500,
-                              xOverscroll=None, yOverscroll=None,
-                              preventFling=None, speed=None,
-                              gestureSourceType=None, repeatCount=None,
-                              repeatDelayMs=None, interactionMarkerName=None,
-                              timeout=60):
-    """Runs an inspector command that causes a repeatable browser driven scroll.
-
-    Args:
-      x: X coordinate of the start of the gesture in CSS pixels.
-      y: Y coordinate of the start of the gesture in CSS pixels.
-      xDistance: Distance to scroll along the X axis (positive to scroll left).
-      yDistance: Ddistance to scroll along the Y axis (positive to scroll up).
-      xOverscroll: Number of additional pixels to scroll back along the X axis.
-      xOverscroll: Number of additional pixels to scroll back along the Y axis.
-      preventFling: Prevents a fling gesture.
-      speed: Swipe speed in pixels per second.
-      gestureSourceType: Which type of input events to be generated.
-      repeatCount: Number of additional repeats beyond the first scroll.
-      repeatDelayMs: Number of milliseconds delay between each repeat.
-      interactionMarkerName: The name of the interaction markers to generate.
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.SynthesizeScrollGesture(
-        x=x, y=y, xDistance=xDistance, yDistance=yDistance,
-        xOverscroll=xOverscroll, yOverscroll=yOverscroll,
-        preventFling=preventFling, speed=speed,
-        gestureSourceType=gestureSourceType, repeatCount=repeatCount,
-        repeatDelayMs=repeatDelayMs,
-        interactionMarkerName=interactionMarkerName,
-        timeout=timeout)
-
-  def DispatchKeyEvent(self, keyEventType='char', modifiers=None,
-                       timestamp=None, text=None, unmodifiedText=None,
-                       keyIdentifier=None, domCode=None, domKey=None,
-                       windowsVirtualKeyCode=None, nativeVirtualKeyCode=None,
-                       autoRepeat=None, isKeypad=None, isSystemKey=None,
-                       timeout=60):
-    """Dispatches a key event to the page.
-
-    Args:
-      type: Type of the key event. Allowed values: 'keyDown', 'keyUp',
-          'rawKeyDown', 'char'.
-      modifiers: Bit field representing pressed modifier keys. Alt=1, Ctrl=2,
-          Meta/Command=4, Shift=8 (default: 0).
-      timestamp: Time at which the event occurred. Measured in UTC time in
-          seconds since January 1, 1970 (default: current time).
-      text: Text as generated by processing a virtual key code with a keyboard
-          layout. Not needed for for keyUp and rawKeyDown events (default: '').
-      unmodifiedText: Text that would have been generated by the keyboard if no
-          modifiers were pressed (except for shift). Useful for shortcut
-          (accelerator) key handling (default: "").
-      keyIdentifier: Unique key identifier (e.g., 'U+0041') (default: '').
-      windowsVirtualKeyCode: Windows virtual key code (default: 0).
-      nativeVirtualKeyCode: Native virtual key code (default: 0).
-      autoRepeat: Whether the event was generated from auto repeat (default:
-          False).
-      isKeypad: Whether the event was generated from the keypad (default:
-          False).
-      isSystemKey: Whether the event was a system key event (default: False).
-
-    Raises:
-      py_utils.TimeoutException
-      exceptions.DevtoolsTargetCrashException
-    """
-    return self._inspector_backend.DispatchKeyEvent(
-        keyEventType=keyEventType, modifiers=modifiers, timestamp=timestamp,
-        text=text, unmodifiedText=unmodifiedText, keyIdentifier=keyIdentifier,
-        domCode=domCode, domKey=domKey,
-        windowsVirtualKeyCode=windowsVirtualKeyCode,
-        nativeVirtualKeyCode=nativeVirtualKeyCode, autoRepeat=autoRepeat,
-        isKeypad=isKeypad, isSystemKey=isSystemKey, timeout=timeout)
diff --git a/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json b/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
deleted file mode 100644
index 56fdb6c..0000000
--- a/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuUZGKCDbff6IRaxa4Pue7PPkxwPaNhGT3JEqppEsNWFjM80imEdqMbf3lrWqEfaHgaNku7nlpwPO1mu3/4Hr+XdNa5MhfnOnuPee4hyTLwOs3Vzz81wpbdzUxZSi2OmqMyI5oTaBYICfNHLwcuc65N5dbt6WKGeKgTpp4v7j7zwIDAQAB",
-  "version": "1.0.0.0",
-  "name": "1 content script",
-  "content_scripts": [
-    { "matches": ["file://*"], "js": ["script.js"] }
-  ]
-}
diff --git a/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script.js b/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script.js
deleted file mode 100644
index afc1cf8..0000000
--- a/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/script.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Useless script just to test injection.
-var x = 1;
-var y = 2;
-var z = 3;
diff --git a/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Preferences b/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Preferences
deleted file mode 100644
index 142e7ff..0000000
--- a/catapult/telemetry/telemetry/internal/browser_profiles/content_scripts1/Default/Preferences
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-   "download": {
-      "directory_upgrade": true,
-      "extensions_to_open": ""
-   },
-   "extensions": {
-      "autoupdate": {
-         "next_check": "12897640036342487"
-      },
-      "settings": {
-         "behllobkkfkfnphdnhnkndlbkcpglgmj": {
-            "active_permissions": {
-               "scriptable_host": [ "file:///*" ]
-            },
-            "granted_permissions": {
-               "scriptable_host": [ "file:///*" ]
-            },
-            "location": 1,
-            "manifest":
-            {
-              "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuUZGKCDbff6IRaxa4Pue7PPkxwPaNhGT3JEqppEsNWFjM80imEdqMbf3lrWqEfaHgaNku7nlpwPO1mu3/4Hr+XdNa5MhfnOnuPee4hyTLwOs3Vzz81wpbdzUxZSi2OmqMyI5oTaBYICfNHLwcuc65N5dbt6WKGeKgTpp4v7j7zwIDAQAB",
-              "version": "1.0.0.0",
-              "name": "1 content script",
-              "content_scripts": [
-                { "matches": ["file://*"], "js": ["script.js"] }
-              ]
-            },
-            "path": "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0",
-            "state": 1
-         }
-      }
-   },
-   "profile": {
-      "exited_cleanly": true,
-      "id": "not-signed-in",
-      "name": "",
-      "nickname": ""
-   },
-   "session": {
-      "startup_urls": [  ]
-   }
-}
diff --git a/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/background.html b/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/background.html
deleted file mode 100644
index d3f9988..0000000
--- a/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/background.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<script>
-var onBefore = chrome.webRequest.onBeforeRequest;
-onBefore.addListener(function(info) {
-  return {"cancel": false};
-}, {urls: ["http://*/*"]}, ['blocking']);
-var onBefore = chrome.webRequest.onBeforeRequest;
-onBefore.addListener(function(info) {
-  return {"cancel": false};
-}, {urls: ["file://*/*"]}, ['blocking']);
-</script>
diff --git a/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json b/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
deleted file mode 100644
index 835bc44..0000000
--- a/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Extensions/behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0/manifest.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuUZGKCDbff6IRaxa4Pue7PPkxwPaNhGT3JEqppEsNWFjM80imEdqMbf3lrWqEfaHgaNku7nlpwPO1mu3/4Hr+XdNa5MhfnOnuPee4hyTLwOs3Vzz81wpbdzUxZSi2OmqMyI5oTaBYICfNHLwcuc65N5dbt6WKGeKgTpp4v7j7zwIDAQAB",
-  "version": "1.0.0.0",
-  "name": "Webrequest",
-  "permissions": ["experimental", "webRequest"],
-  "background": {
-    "page": "background.html"
-  }
-}
diff --git a/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Preferences b/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Preferences
deleted file mode 100644
index e93588e..0000000
--- a/catapult/telemetry/telemetry/internal/browser_profiles/extension_webrequest/Default/Preferences
+++ /dev/null
@@ -1,77 +0,0 @@
-{
-   "browser": {
-      "window_placement": {
-         "bottom": 1150,
-         "left": 10,
-         "maximized": false,
-         "right": 955,
-         "top": 10,
-         "work_area_bottom": 1160,
-         "work_area_left": 0,
-         "work_area_right": 1920,
-         "work_area_top": 0
-      }
-   },
-   "countryid_at_install": 21843,
-   "dns_prefetching": {
-      "host_referral_list": [ 2 ],
-      "startup_list": [ 1 ]
-   },
-   "download": {
-      "directory_upgrade": true,
-      "extensions_to_open": ""
-   },
-   "extensions": {
-      "autoupdate": {
-         "next_check": "12943417068538765"
-      },
-      "chrome_url_overrides": {
-         "bookmarks": [ "chrome-extension://eemcgdkfndhakfknompkggombfjjjeno/main.html" ]
-      },
-      "settings": {
-         "behllobkkfkfnphdnhnkndlbkcpglgmj": {
-            "granted_permissions": {
-               "api": [ "experimental" ],
-               "full": false
-            },
-            "install_time": "12943416715915765",
-            "location": 1,
-            "manifest": {
-               "background": {
-                 "page": "background.html"
-               },
-               "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuUZGKCDbff6IRaxa4Pue7PPkxwPaNhGT3JEqppEsNWFjM80imEdqMbf3lrWqEfaHgaNku7nlpwPO1mu3/4Hr+XdNa5MhfnOnuPee4hyTLwOs3Vzz81wpbdzUxZSi2OmqMyI5oTaBYICfNHLwcuc65N5dbt6WKGeKgTpp4v7j7zwIDAQAB",
-               "name": "Webrequest",
-               "permissions": [ "experimental", "webRequest" ],
-               "version": "1.0.0.0"
-            },
-            "path": "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0",
-            "state": 1
-         }
-      }
-   },
-   "google": {
-      "services": {
-         "username": ""
-      }
-   },
-   "ntp": {
-      "pref_version": 3,
-      "promo_resource_cache_update": "1298943121.229765"
-   },
-   "plugins": {
-      "enabled_internal_pdf3": true
-   },
-   "profile": {
-      "content_settings": {
-         "pref_version": 1
-      },
-      "exited_cleanly": true,
-      "id": "not-signed-in",
-      "name": "",
-      "nickname": ""
-   },
-   "tabs": {
-      "use_vertical_tabs": false
-   }
-}
diff --git a/catapult/telemetry/telemetry/internal/forwarders/__init__.py b/catapult/telemetry/telemetry/internal/forwarders/__init__.py
deleted file mode 100644
index b11fbfe..0000000
--- a/catapult/telemetry/telemetry/internal/forwarders/__init__.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-
-
-PortPair = collections.namedtuple('PortPair', ['local_port', 'remote_port'])
-PortSet = collections.namedtuple('PortSet', ['http', 'https', 'dns'])
-
-
-
-class ForwarderFactory(object):
-
-  def Create(self, port_pair):
-    """Creates a forwarder that maps remote (device) <-> local (host) ports.
-
-    Args:
-      port_pair: A PortPairs instance that consists of a PortPair mapping
-          for each protocol. http is required. https and dns may be None.
-    """
-    raise NotImplementedError()
-
-  @property
-  def host_ip(self):
-    return '127.0.0.1'
-
-
-class Forwarder(object):
-
-  def __init__(self, port_pair):
-    assert port_pair, 'Port mapping is required.'
-    self._port_pair = port_pair
-    self._forwarding = True
-
-  @property
-  def host_port(self):
-    return self._port_pair.remote_port
-
-  @property
-  def host_ip(self):
-    return '127.0.0.1'
-
-  @property
-  def port_pair(self):
-    return self._port_pair
-
-  @property
-  def url(self):
-    assert self.host_ip and self.host_port
-    return 'http://%s:%i' % (self.host_ip, self.host_port)
-
-  def Close(self):
-    self._port_pair = None
-    self._forwarding = False
diff --git a/catapult/telemetry/telemetry/internal/forwarders/android_forwarder.py b/catapult/telemetry/telemetry/internal/forwarders/android_forwarder.py
deleted file mode 100644
index eb20845..0000000
--- a/catapult/telemetry/telemetry/internal/forwarders/android_forwarder.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.util import atexit_with_log
-import logging
-import subprocess
-
-from telemetry.internal import forwarders
-
-try:
-  from devil.android import forwarder
-except ImportError:
-  forwarder = None
-
-
-class AndroidForwarderFactory(forwarders.ForwarderFactory):
-
-  def __init__(self, device):
-    super(AndroidForwarderFactory, self).__init__()
-    self._device = device
-
-  def Create(self, port_pair):
-    try:
-      return AndroidForwarder(self._device, port_pair)
-    except Exception:
-      try:
-        logging.warning('Failed to create forwarder. '
-                        'Currently forwarded connections:')
-        for line in self._device.adb.ForwardList().splitlines():
-          logging.warning('  %s', line)
-      except Exception:
-        logging.warning('Exception raised while listing forwarded connections.')
-
-      logging.warning('Relevant device tcp sockets in use:')
-      try:
-        proc_net_tcp_target = ':%s ' % hex(port_pair.remote_port)[2:]
-        for line in self._device.ReadFile('/proc/net/tcp', as_root=True,
-                                          force_pull=True).splitlines():
-          if proc_net_tcp_target in line:
-            logging.warning('  %s', line)
-      except Exception:
-        logging.warning('Exception raised while listing tcp sockets.')
-
-      logging.warning('Possibly relevant lsof entries:')
-      try:
-        lsof_output = self._device.RunShellCommand(
-            ['lsof'], as_root=True, check_return=True)
-        lsof_target = str(port_pair.remote_port)
-        for line in lsof_output:
-          if lsof_target in line:
-            logging.warning('  %s', line)
-      except Exception:
-        logging.warning('Exception raised running lsof.')
-
-      logging.warning('Alive webpagereplay instances:')
-      try:
-        for line in subprocess.check_output(['ps', '-ef']).splitlines():
-          if 'webpagereplay' in line:
-            logging.warning('  %s', line)
-      except Exception:
-        logging.warning('Exception raised while listing WPR intances.')
-
-      raise
-
-
-class AndroidForwarder(forwarders.Forwarder):
-
-  def __init__(self, device, port_pair):
-    super(AndroidForwarder, self).__init__(port_pair)
-    self._device = device
-    forwarder.Forwarder.Map(
-        [(port_pair.remote_port, port_pair.local_port)], self._device)
-    self._port_pair = (
-        forwarders.PortPair(
-            port_pair.local_port,
-            forwarder.Forwarder.DevicePortForHostPort(port_pair.local_port)))
-    atexit_with_log.Register(self.Close)
-    # TODO(tonyg): Verify that each port can connect to host.
-
-  def Close(self):
-    if self._forwarding:
-      forwarder.Forwarder.UnmapDevicePort(
-          self._port_pair.remote_port, self._device)
-    super(AndroidForwarder, self).Close()
diff --git a/catapult/telemetry/telemetry/internal/forwarders/cros_forwarder.py b/catapult/telemetry/telemetry/internal/forwarders/cros_forwarder.py
deleted file mode 100644
index 4316954..0000000
--- a/catapult/telemetry/telemetry/internal/forwarders/cros_forwarder.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import subprocess
-
-from telemetry.internal import forwarders
-from telemetry.internal.forwarders import do_nothing_forwarder
-
-import py_utils
-
-
-class CrOsForwarderFactory(forwarders.ForwarderFactory):
-
-  def __init__(self, cri):
-    super(CrOsForwarderFactory, self).__init__()
-    self._cri = cri
-
-  # pylint: disable=arguments-differ
-  def Create(self, port_pair, use_remote_port_forwarding=True):
-    if self._cri.local:
-      return do_nothing_forwarder.DoNothingForwarder(port_pair)
-    return CrOsSshForwarder(self._cri, use_remote_port_forwarding, port_pair)
-
-
-class CrOsSshForwarder(forwarders.Forwarder):
-
-  def __init__(self, cri, use_remote_port_forwarding, port_pair):
-    super(CrOsSshForwarder, self).__init__(port_pair)
-    self._cri = cri
-    self._proc = None
-    forwarding_args = self._ForwardingArgs(
-        use_remote_port_forwarding, self.host_ip, port_pair)
-    self._proc = subprocess.Popen(
-        self._cri.FormSSHCommandLine(['sleep', '999999999'], forwarding_args),
-        stdout=subprocess.PIPE,
-        stderr=subprocess.PIPE,
-        stdin=subprocess.PIPE,
-        shell=False)
-    py_utils.WaitFor(
-        lambda: self._cri.IsHTTPServerRunningOnPort(self.host_port), 60)
-    logging.debug('Server started on %s:%d', self.host_ip, self.host_port)
-
-  # pylint: disable=unused-argument
-  @staticmethod
-  def _ForwardingArgs(use_remote_port_forwarding, host_ip, port_pair):
-    if use_remote_port_forwarding:
-      arg_format = '-R{remote_port}:{host_ip}:{local_port}'
-    else:
-      arg_format = '-L{local_port}:{host_ip}:{remote_port}'
-    return [arg_format.format(host_ip=host_ip,
-                              local_port=port_pair.local_port,
-                              remote_port=port_pair.remote_port)]
-
-  @property
-  def host_port(self):
-    return self._port_pair.remote_port
-
-  def Close(self):
-    if self._proc:
-      self._proc.kill()
-      self._proc = None
-    super(CrOsSshForwarder, self).Close()
diff --git a/catapult/telemetry/telemetry/internal/forwarders/cros_forwarder_unittest.py b/catapult/telemetry/telemetry/internal/forwarders/cros_forwarder_unittest.py
deleted file mode 100644
index 809b63e..0000000
--- a/catapult/telemetry/telemetry/internal/forwarders/cros_forwarder_unittest.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal import forwarders
-from telemetry.internal.forwarders import cros_forwarder
-
-# pylint: disable=protected-access
-class ForwardingArgsTest(unittest.TestCase):
-  port_pair = forwarders.PortPair(111, 222)
-
-  def testForwardingArgsReverse(self):
-    forwarding_args = cros_forwarder.CrOsSshForwarder._ForwardingArgs(
-        use_remote_port_forwarding=True, host_ip='5.5.5.5',
-        port_pair=self.port_pair)
-    self.assertEqual(['-R222:5.5.5.5:111'], forwarding_args)
-
-  def testForwardingArgs(self):
-    forwarding_args = cros_forwarder.CrOsSshForwarder._ForwardingArgs(
-        use_remote_port_forwarding=False, host_ip='2.2.2.2',
-        port_pair=self.port_pair)
-    self.assertEqual(['-L111:2.2.2.2:222'], forwarding_args)
diff --git a/catapult/telemetry/telemetry/internal/forwarders/do_nothing_forwarder.py b/catapult/telemetry/telemetry/internal/forwarders/do_nothing_forwarder.py
deleted file mode 100644
index 40cfba3..0000000
--- a/catapult/telemetry/telemetry/internal/forwarders/do_nothing_forwarder.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import contextlib
-import logging
-import socket
-
-from telemetry.internal import forwarders
-
-import py_utils
-
-
-class Error(Exception):
-  """Base class for exceptions in this module."""
-  pass
-
-
-class PortsMismatchError(Error):
-  """Raised when local and remote ports are not equal."""
-  pass
-
-
-class ConnectionError(Error):
-  """Raised when unable to connect to local TCP ports."""
-  pass
-
-
-class DoNothingForwarderFactory(forwarders.ForwarderFactory):
-
-  def Create(self, port_pair):
-    return DoNothingForwarder(port_pair)
-
-
-class DoNothingForwarder(forwarders.Forwarder):
-  """Check that no forwarding is needed for the given port pairs.
-
-  The local and remote ports must be equal. Otherwise, the "do nothing"
-  forwarder does not make sense. (Raises PortsMismatchError.)
-
-  Also, check that all TCP ports support connections.  (Raises ConnectionError.)
-  """
-
-  def __init__(self, port_pair):
-    super(DoNothingForwarder, self).__init__(port_pair)
-    self._CheckPortPair()
-
-  def _CheckPortPair(self):
-    if self._port_pair.local_port != self._port_pair.remote_port:
-      raise PortsMismatchError('Local port forwarding is not supported')
-    try:
-      self._WaitForConnectionEstablished(
-          (self.host_ip, self._port_pair.local_port), timeout=10)
-      logging.debug(
-          'Connection test succeeded for %s:%d',
-          self.host_ip, self._port_pair.local_port)
-    except py_utils.TimeoutException:
-      raise ConnectionError(
-          'Unable to connect to address: %s:%d',
-          self.host_ip, self._port_pair.local_port)
-
-  def _WaitForConnectionEstablished(self, address, timeout):
-    def CanConnect():
-      with contextlib.closing(socket.socket()) as s:
-        return s.connect_ex(address) == 0
-    py_utils.WaitFor(CanConnect, timeout)
diff --git a/catapult/telemetry/telemetry/internal/forwarders/do_nothing_forwarder_unittest.py b/catapult/telemetry/telemetry/internal/forwarders/do_nothing_forwarder_unittest.py
deleted file mode 100644
index 7a17c87..0000000
--- a/catapult/telemetry/telemetry/internal/forwarders/do_nothing_forwarder_unittest.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal import forwarders
-from telemetry.internal.forwarders import do_nothing_forwarder
-
-import py_utils
-
-
-class TestDoNothingForwarder(do_nothing_forwarder.DoNothingForwarder):
-  """Override _WaitForConnect to avoid actual socket connection."""
-
-  def __init__(self, port_pairs):
-    self.connected_addresses = []
-    super(TestDoNothingForwarder, self).__init__(port_pairs)
-
-  def _WaitForConnectionEstablished(self, address, timeout):
-    self.connected_addresses.append(address)
-
-
-class TestErrorDoNothingForwarder(do_nothing_forwarder.DoNothingForwarder):
-  """Simulate a connection error."""
-
-  def _WaitForConnectionEstablished(self, address, timeout):
-    raise py_utils.TimeoutException
-
-
-class CheckPortPairsTest(unittest.TestCase):
-  def testBasicCheck(self):
-    port_pair = forwarders.PortPair(80, 80)
-    f = TestDoNothingForwarder(port_pair)
-    expected_connected_addresses = [
-        ('127.0.0.1', 80),
-        ]
-    self.assertEqual(expected_connected_addresses, f.connected_addresses)
-
-  def testPortMismatchRaisesPortsMismatchError(self):
-    # The do_nothing_forward cannot forward from one port to another.
-    port_pair = forwarders.PortPair(80, 81)
-    with self.assertRaises(do_nothing_forwarder.PortsMismatchError):
-      TestDoNothingForwarder(port_pair)
-
-  def testConnectionTimeoutRaisesConnectionError(self):
-    port_pair = forwarders.PortPair(80, 80)
-    with self.assertRaises(do_nothing_forwarder.ConnectionError):
-      TestErrorDoNothingForwarder(port_pair)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/__init__.py b/catapult/telemetry/telemetry/internal/image_processing/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/image_processing/_bitmap.py b/catapult/telemetry/telemetry/internal/image_processing/_bitmap.py
deleted file mode 100644
index 0ba0908..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/_bitmap.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Bitmap is a basic wrapper for image pixels. It includes some basic processing
-tools: crop, find bounding box of a color and compute histogram of color values.
-"""
-
-import array
-import cStringIO
-import struct
-import subprocess
-import warnings
-
-from telemetry.internal.util import binary_manager
-from telemetry.core import platform
-from telemetry.util import color_histogram
-from telemetry.util import rgba_color
-
-import png
-
-
-class _BitmapTools(object):
-  """Wraps a child process of bitmaptools and allows for one command."""
-  CROP_PIXELS = 0
-  HISTOGRAM = 1
-  BOUNDING_BOX = 2
-
-  def __init__(self, dimensions, pixels):
-    binary = binary_manager.FetchPath(
-        'bitmaptools',
-        platform.GetHostPlatform().GetArchName(),
-        platform.GetHostPlatform().GetOSName())
-    assert binary, 'You must build bitmaptools first!'
-
-    self._popen = subprocess.Popen([binary],
-                                   stdin=subprocess.PIPE,
-                                   stdout=subprocess.PIPE,
-                                   stderr=subprocess.PIPE)
-
-    # dimensions are: bpp, width, height, boxleft, boxtop, boxwidth, boxheight
-    packed_dims = struct.pack('iiiiiii', *dimensions)
-    self._popen.stdin.write(packed_dims)
-    # If we got a list of ints, we need to convert it into a byte buffer.
-    if type(pixels) is not bytearray:
-      pixels = bytearray(pixels)
-    self._popen.stdin.write(pixels)
-
-  def _RunCommand(self, *command):
-    assert not self._popen.stdin.closed, (
-      'Exactly one command allowed per instance of tools.')
-    packed_command = struct.pack('i' * len(command), *command)
-    self._popen.stdin.write(packed_command)
-    self._popen.stdin.close()
-    length_packed = self._popen.stdout.read(struct.calcsize('i'))
-    if not length_packed:
-      raise Exception(self._popen.stderr.read())
-    length = struct.unpack('i', length_packed)[0]
-    return self._popen.stdout.read(length)
-
-  def CropPixels(self):
-    return self._RunCommand(_BitmapTools.CROP_PIXELS)
-
-  def Histogram(self, ignore_color, tolerance):
-    ignore_color_int = -1 if ignore_color is None else int(ignore_color)
-    response = self._RunCommand(_BitmapTools.HISTOGRAM,
-                                ignore_color_int, tolerance)
-    out = array.array('i')
-    out.fromstring(response)
-    assert len(out) == 768, (
-        'The ColorHistogram has the wrong number of buckets: %s' % len(out))
-    return color_histogram.ColorHistogram(out[:256], out[256:512], out[512:],
-                                    ignore_color)
-
-  def BoundingBox(self, color, tolerance):
-    response = self._RunCommand(_BitmapTools.BOUNDING_BOX, int(color),
-                                tolerance)
-    unpacked = struct.unpack('iiiii', response)
-    box, count = unpacked[:4], unpacked[-1]
-    if box[2] < 0 or box[3] < 0:
-      box = None
-    return box, count
-
-
-class Bitmap(object):
-  """Utilities for parsing and inspecting a bitmap."""
-
-  def __init__(self, bpp, width, height, pixels, metadata=None):
-    assert bpp in [3, 4], 'Invalid bytes per pixel'
-    assert width > 0, 'Invalid width'
-    assert height > 0, 'Invalid height'
-    assert pixels, 'Must specify pixels'
-    assert bpp * width * height == len(pixels), 'Dimensions and pixels mismatch'
-
-    self._bpp = bpp
-    self._width = width
-    self._height = height
-    self._pixels = pixels
-    self._metadata = metadata or {}
-    self._crop_box = None
-
-  @property
-  def bpp(self):
-    return self._bpp
-
-  @property
-  def width(self):
-    return self._crop_box[2] if self._crop_box else self._width
-
-  @property
-  def height(self):
-    return self._crop_box[3] if self._crop_box else self._height
-
-  def _PrepareTools(self):
-    """Prepares an instance of _BitmapTools which allows exactly one command.
-    """
-    crop_box = self._crop_box or (0, 0, self._width, self._height)
-    return _BitmapTools((self._bpp, self._width, self._height) + crop_box,
-                        self._pixels)
-
-  @property
-  def pixels(self):
-    if self._crop_box:
-      self._pixels = self._PrepareTools().CropPixels()
-      # pylint: disable=unpacking-non-sequence
-      _, _, self._width, self._height = self._crop_box
-      self._crop_box = None
-    if type(self._pixels) is not bytearray:
-      self._pixels = bytearray(self._pixels)
-    return self._pixels
-
-  @property
-  def metadata(self):
-    self._metadata['size'] = (self.width, self.height)
-    self._metadata['alpha'] = self.bpp == 4
-    self._metadata['bitdepth'] = 8
-    return self._metadata
-
-  def GetPixelColor(self, x, y):
-    pixels = self.pixels
-    base = self._bpp * (y * self._width + x)
-    if self._bpp == 4:
-      return rgba_color.RgbaColor(pixels[base + 0], pixels[base + 1],
-                                  pixels[base + 2], pixels[base + 3])
-    return rgba_color.RgbaColor(pixels[base + 0], pixels[base + 1],
-                                pixels[base + 2])
-
-  @staticmethod
-  def FromPng(png_data):
-    warnings.warn(
-        'Using pure python png decoder, which could be very slow. To speed up, '
-        'consider installing numpy & cv2 (OpenCV).')
-    width, height, pixels, meta = png.Reader(bytes=png_data).read_flat()
-    return Bitmap(4 if meta['alpha'] else 3, width, height, pixels, meta)
-
-  @staticmethod
-  def FromPngFile(path):
-    with open(path, "rb") as f:
-      return Bitmap.FromPng(f.read())
-
-  def WritePngFile(self, path):
-    with open(path, "wb") as f:
-      png.Writer(**self.metadata).write_array(f, self.pixels)
-
-  def IsEqual(self, other, tolerance=0):
-    # Dimensions must be equal
-    if self.width != other.width or self.height != other.height:
-      return False
-
-    # Loop over each pixel and test for equality
-    if tolerance or self.bpp != other.bpp:
-      for y in range(self.height):
-        for x in range(self.width):
-          c0 = self.GetPixelColor(x, y)
-          c1 = other.GetPixelColor(x, y)
-          if not c0.IsEqual(c1, tolerance):
-            return False
-    else:
-      return self.pixels == other.pixels
-
-    return True
-
-  def Diff(self, other):
-    # Output dimensions will be the maximum of the two input dimensions
-    out_width = max(self.width, other.width)
-    out_height = max(self.height, other.height)
-
-    diff = [[0 for x in xrange(out_width * 3)] for x in xrange(out_height)]
-
-    # Loop over each pixel and write out the difference
-    for y in range(out_height):
-      for x in range(out_width):
-        if x < self.width and y < self.height:
-          c0 = self.GetPixelColor(x, y)
-        else:
-          c0 = rgba_color.RgbaColor(0, 0, 0, 0)
-
-        if x < other.width and y < other.height:
-          c1 = other.GetPixelColor(x, y)
-        else:
-          c1 = rgba_color.RgbaColor(0, 0, 0, 0)
-
-        offset = x * 3
-        diff[y][offset] = abs(c0.r - c1.r)
-        diff[y][offset+1] = abs(c0.g - c1.g)
-        diff[y][offset+2] = abs(c0.b - c1.b)
-
-    # This particular method can only save to a file, so the result will be
-    # written into an in-memory buffer and read back into a Bitmap
-    warnings.warn(
-        'Using pure python png decoder, which could be very slow. To speed up, '
-        'consider installing numpy & cv2 (OpenCV).')
-    diff_img = png.from_array(diff, mode='RGB')
-    output = cStringIO.StringIO()
-    try:
-      diff_img.save(output)
-      diff = Bitmap.FromPng(output.getvalue())
-    finally:
-      output.close()
-
-    return diff
-
-  def GetBoundingBox(self, color, tolerance=0):
-    return self._PrepareTools().BoundingBox(color, tolerance)
-
-  def Crop(self, left, top, width, height):
-    cur_box = self._crop_box or (0, 0, self._width, self._height)
-    cur_left, cur_top, cur_width, cur_height = cur_box
-
-    if (left < 0 or top < 0 or
-        (left + width) > cur_width or
-        (top + height) > cur_height):
-      raise ValueError('Invalid dimensions')
-
-    self._crop_box = cur_left + left, cur_top + top, width, height
-    return self
-
-  def ColorHistogram(self, ignore_color=None, tolerance=0):
-    return self._PrepareTools().Histogram(ignore_color, tolerance)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/bitmaptools.cc b/catapult/telemetry/telemetry/internal/image_processing/bitmaptools.cc
deleted file mode 100644
index fd54f28..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/bitmaptools.cc
+++ /dev/null
@@ -1,264 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#if defined(WIN32)
-#include <fcntl.h>
-#include <io.h>
-#endif
-
-enum Commands {
-  CROP_PIXELS = 0,
-  HISTOGRAM = 1,
-  BOUNDING_BOX = 2
-};
-
-bool ReadInt(int* out) {
-  return fread(out, sizeof(*out), 1, stdin) == 1;
-}
-
-void WriteResponse(void* data, int size) {
-  fwrite(&size, sizeof(size), 1, stdout);
-  fwrite(data, size, 1, stdout);
-  fflush(stdout);
-}
-
-struct Box {
-  Box() : left(), top(), right(), bottom() {}
-
-  // Expected input is:
-  // left, top, width, height
-  bool Read() {
-    int width;
-    int height;
-    if (!(ReadInt(&left) && ReadInt(&top) &&
-          ReadInt(&width) && ReadInt(&height))) {
-      fprintf(stderr, "Could not parse Box.\n");
-      return false;
-    }
-    if (left < 0 || top < 0 || width < 0 || height < 0) {
-      fprintf(stderr, "Box dimensions must be non-negative.\n");
-      return false;
-    }
-    right = left + width;
-    bottom = top + height;
-    return true;
-  }
-
-  void Union(int x, int y) {
-    if (left > x) left = x;
-    if (right <= x) right = x + 1;
-    if (top > y) top = y;
-    if (bottom <= y) bottom = y + 1;
-  }
-
-  int width() const { return right - left; }
-  int height() const { return bottom - top; }
-
-  int left;
-  int top;
-  int right;
-  int bottom;
-};
-
-
-// Represents a bitmap buffer with a crop box.
-struct Bitmap {
-  Bitmap() : pixels(NULL) {}
-
-  ~Bitmap() {
-    if (pixels)
-      delete[] pixels;
-  }
-
-  // Expected input is:
-  // bpp, width, height, box, pixels
-  bool Read() {
-    int bpp;
-    int width;
-    int height;
-    if (!(ReadInt(&bpp) && ReadInt(&width) && ReadInt(&height))) {
-      fprintf(stderr, "Could not parse Bitmap initializer.\n");
-      return false;
-    }
-    if (bpp <= 0 || width <= 0 || height <= 0) {
-      fprintf(stderr, "Dimensions must be positive.\n");
-      return false;
-    }
-
-    int size = width * height * bpp;
-
-    row_stride = width * bpp;
-    pixel_stride = bpp;
-    total_size = size;
-    row_size = row_stride;
-
-    if (!box.Read()) {
-      fprintf(stderr, "Expected crop box argument not found.\n");
-      return false;
-    }
-
-    if (box.bottom * row_stride > total_size ||
-        box.right * pixel_stride > row_size) {
-      fprintf(stderr, "Crop box overflows the bitmap.\n");
-      return false;
-    }
-
-    pixels = new unsigned char[size];
-    if (fread(pixels, sizeof(pixels[0]), size, stdin) <
-        static_cast<size_t>(size)) {
-      fprintf(stderr, "Not enough pixels found,\n");
-      return false;
-    }
-
-    total_size = (box.bottom - box.top) * row_stride;
-    row_size = (box.right - box.left) * pixel_stride;
-    data = pixels + box.top * row_stride + box.left * pixel_stride;
-    return true;
-  }
-
-  void WriteCroppedPixels() const {
-    int out_size = row_size * box.height();
-    unsigned char* out = new unsigned char[out_size];
-    unsigned char* dst = out;
-    for (const unsigned char* row = data;
-        row < data + total_size;
-        row += row_stride, dst += row_size) {
-      // No change in pixel_stride, so we can copy whole rows.
-      memcpy(dst, row, row_size);
-    }
-
-    WriteResponse(out, out_size);
-    delete[] out;
-  }
-
-  unsigned char* pixels;
-  Box box;
-  // Points at the top-left pixel in |pixels|.
-  const unsigned char* data;
-  // These counts are in bytes.
-  int row_stride;
-  int pixel_stride;
-  int total_size;
-  int row_size;
-};
-
-
-static inline
-bool PixelsEqual(const unsigned char* pixel1, const unsigned char* pixel2,
-                 int tolerance) {
-  // Note: this works for both RGB and RGBA. Alpha channel is ignored.
-  return (abs(pixel1[0] - pixel2[0]) <= tolerance) &&
-         (abs(pixel1[1] - pixel2[1]) <= tolerance) &&
-         (abs(pixel1[2] - pixel2[2]) <= tolerance);
-}
-
-
-static inline
-bool PixelsEqual(const unsigned char* pixel, int color, int tolerance) {
-  unsigned char pixel2[3] = { color >> 16, color >> 8, color };
-  return PixelsEqual(pixel, pixel2, tolerance);
-}
-
-
-static
-bool Histogram(const Bitmap& bmp) {
-  int ignore_color;
-  int tolerance;
-  if (!(ReadInt(&ignore_color) && ReadInt(&tolerance))) {
-    fprintf(stderr, "Could not parse HISTOGRAM command.\n");
-    return false;
-  }
-
-  const int kLength = 3 * 256;
-  int counts[kLength] = {};
-
-  for (const unsigned char* row = bmp.data; row < bmp.data + bmp.total_size;
-       row += bmp.row_stride) {
-    for (const unsigned char* pixel = row; pixel < row + bmp.row_size;
-       pixel += bmp.pixel_stride) {
-      if (ignore_color >= 0 && PixelsEqual(pixel, ignore_color, tolerance))
-        continue;
-      ++(counts[256 * 0 + pixel[0]]);
-      ++(counts[256 * 1 + pixel[1]]);
-      ++(counts[256 * 2 + pixel[2]]);
-    }
-  }
-
-  WriteResponse(counts, sizeof(counts));
-  return true;
-}
-
-
-static
-bool BoundingBox(const Bitmap& bmp) {
-  int color;
-  int tolerance;
-  if (!(ReadInt(&color) && ReadInt(&tolerance))) {
-    fprintf(stderr, "Could not parse BOUNDING_BOX command.\n");
-    return false;
-  }
-
-  Box box;
-  box.left = bmp.total_size;
-  box.top = bmp.total_size;
-  box.right = 0;
-  box.bottom = 0;
-
-  int count = 0;
-  int y = 0;
-  for (const unsigned char* row = bmp.data; row < bmp.data + bmp.total_size;
-       row += bmp.row_stride, ++y) {
-    int x = 0;
-    for (const unsigned char* pixel = row; pixel < row + bmp.row_size;
-         pixel += bmp.pixel_stride, ++x) {
-      if (!PixelsEqual(pixel, color, tolerance))
-        continue;
-      box.Union(x, y);
-      ++count;
-    }
-  }
-
-  int response[] = { box.left, box.top, box.width(), box.height(), count };
-  WriteResponse(response, sizeof(response));
-  return true;
-}
-
-
-int main() {
-  Bitmap bmp;
-  int command;
-
-#if defined(WIN32)
-  _setmode(_fileno(stdin), _O_BINARY);
-  _setmode(_fileno(stdout), _O_BINARY);
-#else
-  stdin = freopen(NULL, "rb", stdin);
-  stdout = freopen(NULL, "wb", stdout);
-#endif
-
-  if (!bmp.Read()) return -1;
-  if (!ReadInt(&command)) {
-    fprintf(stderr, "Expected command.\n");
-    return -1;
-  }
-  switch (command) {
-    case CROP_PIXELS:
-      bmp.WriteCroppedPixels();
-      break;
-    case BOUNDING_BOX:
-      if (!BoundingBox(bmp)) return -1;
-      break;
-    case HISTOGRAM:
-      if (!Histogram(bmp)) return -1;
-      break;
-    default:
-      fprintf(stderr, "Unrecognized command\n");
-      return -1;
-  }
-  return 0;
-}
diff --git a/catapult/telemetry/telemetry/internal/image_processing/cv_util.py b/catapult/telemetry/telemetry/internal/image_processing/cv_util.py
deleted file mode 100644
index 356c0d6..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/cv_util.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This module provides implementations of common computer Vision operations."""
-
-from __future__ import division
-from telemetry.internal.util import external_modules
-
-np = external_modules.ImportRequiredModule('numpy')
-
-
-def AreLinesOrthogonal(line1, line2, tolerance):
-  """Returns true if lines are within tolerance radians of being orthogonal."""
-  # Map each line onto an angle between 0 and 180.
-  theta1 = np.arctan2(np.float(line1[1] - line1[3]),
-                      np.float(line1[0] - line1[2]))
-  theta2 = np.arctan2(np.float(line2[1] - line2[3]),
-                      np.float(line2[0] - line2[2]))
-  angle2 = abs(theta2 - theta1)
-  if angle2 >= np.pi:
-    angle2 -= np.pi
-  # If the difference between the angles is more than pi/2 - tolerance, the
-  # lines are not orthogonal.
-  return not abs(angle2 - (np.pi / 2.0)) > tolerance
-
-
-def FindLineIntersection(line1, line2):
-  """If the line segments intersect, returns True and their intersection.
-  Otherwise, returns False and the intersection of the line segments if they
-  were to be extended."""
-  # Compute g, and h, the factor by which each line must be extended to
-  # exactly touch the other line. If both are between 0 and 1, then the lines
-  # currently intersect. We use h to compute their intersection.
-  line1p1 = line1[:2]
-  line1p0 = line1[2:]
-  line2p1 = line2[:2]
-  line2p0 = line2[2:]
-  E = np.subtract(line1p1, line1p0)
-  F = np.subtract(line2p1, line2p0)
-  Pe = np.asfarray((-E[1], E[0]))
-  Pf = np.asfarray((-F[1], F[0]))
-  h = np.dot(np.subtract(line1p0, line2p0), Pe)
-  h = np.divide(h, np.dot(F, Pe))
-  g = np.dot(np.subtract(line2p0, line1p0), Pf)
-  g = np.divide(g, np.dot(E, Pf))
-  intersection = np.add(line2p0, np.dot(F, h))
-  intersect = (h >= -0.000001 and h <= 1.000001 and
-               g >= -0.000001 and g <= 1.000001)
-  return intersect, intersection
-
-
-def ExtendLines(lines, length):
-  """Extends lines in an array to a given length, maintaining the center
-  point. Does not necessarily maintain point order."""
-  half_length = length / 2.0
-  angles = np.arctan2(lines[:, 1] - lines[:, 3], lines[:, 0] - lines[:, 2])
-  xoffsets = half_length * np.cos(angles)
-  yoffsets = half_length * np.sin(angles)
-  centerx = (lines[:, 0] + lines[:, 2]) / 2.0
-  centery = (lines[:, 1] + lines[:, 3]) / 2.0
-  lines[:, 0] = centerx - xoffsets
-  lines[:, 2] = centerx + xoffsets
-  lines[:, 1] = centery - yoffsets
-  lines[:, 3] = centery + yoffsets
-  return lines
-
-
-def IsPointApproxOnLine(point, line, tolerance=1):
-  """Approximates distance between point and line for small distances using
-  the determinant and checks whether it's within the tolerance. Tolerance is
-  an approximate distance in pixels, precision decreases with distance."""
-  xd = line[0] - line[2]
-  yd = line[1] - line[3]
-  det = ((xd) * (point[1] - line[3])) - ((yd) * (point[0] - line[2]))
-  tolerance = float(tolerance) * (abs(xd) + abs(yd))
-  return abs(det) * 2.0 <= tolerance
-
-
-def SqDistances(points1, points2):
-  """Computes the square of the distance between two sets of points, or a
-  set of points and a point."""
-  d = np.square(points1 - points2)
-  return d[:, 0] + d[:, 1]
-
-
-def SqDistance(point1, point2):
-  """Computes the square of the distance between two points."""
-  d = np.square(point1 - point2)
-  return d[0] + d[1]
diff --git a/catapult/telemetry/telemetry/internal/image_processing/cv_util_unittest.py b/catapult/telemetry/telemetry/internal/image_processing/cv_util_unittest.py
deleted file mode 100644
index d5d5cd7..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/cv_util_unittest.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.util import external_modules
-
-try:
-  np = external_modules.ImportRequiredModule('numpy')
-except ImportError:
-  pass
-else:
-  class CVUtilTest(unittest.TestCase):
-    def __init__(self, *args, **kwargs):
-      super(CVUtilTest, self).__init__(*args, **kwargs)
-      # Import modules with dependencies that may not be preset in test setup so
-      # that importing this unit test doesn't cause the test runner to raise an
-      # exception.
-      from telemetry.internal.image_processing import cv_util
-      self.cv_util = cv_util
-
-    def testAreLinesOrthogonalish(self):
-      l1 = np.asfarray((0, 0, 1, 0))
-      l2 = np.asfarray((0, 0, 0, 1))
-      self.assertTrue(self.cv_util.AreLinesOrthogonal(l1, l2, 0))
-      self.assertTrue(self.cv_util.AreLinesOrthogonal(l2, l1, 0))
-      self.assertFalse(self.cv_util.AreLinesOrthogonal(l1, l1,
-                                                       np.pi / 2 - 1e-10))
-      self.assertFalse(self.cv_util.AreLinesOrthogonal(l2, l2,
-                                                       np.pi / 2 - 1e-10))
-      self.assertTrue(self.cv_util.AreLinesOrthogonal(l1, l1, np.pi / 2))
-      self.assertTrue(self.cv_util.AreLinesOrthogonal(l2, l2, np.pi / 2))
-
-      l3 = np.asfarray((0, 0, 1, 1))
-      l4 = np.asfarray((1, 1, 0, 0))
-      self.assertFalse(self.cv_util.AreLinesOrthogonal(l3, l4,
-                                                       np.pi / 2 - 1e-10))
-      self.assertTrue(self.cv_util.AreLinesOrthogonal(l3, l1, np.pi / 4))
-
-      l5 = np.asfarray((0, 1, 1, 0))
-      self.assertTrue(self.cv_util.AreLinesOrthogonal(l3, l5, 0))
-
-    def testFindLineIntersection(self):
-      l1 = np.asfarray((1, 1, 2, 1))
-      l2 = np.asfarray((1, 1, 1, 2))
-      ret, p = self.cv_util.FindLineIntersection(l1, l2)
-      self.assertTrue(ret)
-      self.assertTrue(np.array_equal(p, np.array([1, 1])))
-      l3 = np.asfarray((1.1, 1, 2, 1))
-      ret, p = self.cv_util.FindLineIntersection(l2, l3)
-      self.assertFalse(ret)
-      self.assertTrue(np.array_equal(p, np.array([1, 1])))
-      l4 = np.asfarray((2, 1, 1, 1))
-      l5 = np.asfarray((1, 2, 1, 1))
-      ret, p = self.cv_util.FindLineIntersection(l4, l5)
-      self.assertTrue(ret)
-      self.assertTrue(np.array_equal(p, np.array([1, 1])))
-      l6 = np.asfarray((1, 1, 0, 0))
-      l7 = np.asfarray((0, 1, 1, 0))
-      ret, p = self.cv_util.FindLineIntersection(l7, l6)
-      self.assertTrue(ret)
-      self.assertTrue(np.array_equal(p, np.array([0.5, 0.5])))
-      l8 = np.asfarray((0, 0, 0, 1))
-      l9 = np.asfarray((1, 0, 1, 1))
-      ret, p = self.cv_util.FindLineIntersection(l8, l9)
-      self.assertFalse(ret)
-      self.assertTrue(np.isnan(p[0]))
-
-    def testExtendLines(self):
-      l1 = (-1, 0, 1, 0)
-      l2 = (0, -1, 0, 1)
-      l3 = (4, 4, 6, 6)
-      l4 = (1, 1, 1, 1)
-      lines = self.cv_util.ExtendLines(np.asfarray([l1, l2, l3, l4],
-                                                   dtype=np.float64), 10)
-      lines = np.around(lines, 10)
-      expected0 = ((5.0, 0.0, -5.0, 0.0))
-      self.assertAlmostEqual(np.sum(np.abs(np.subtract(lines[0], expected0))),
-                             0.0, 7)
-      expected1 = ((0.0, 5.0, 0.0, -5.0))
-      self.assertAlmostEqual(np.sum(np.abs(np.subtract(lines[1], expected1))),
-                             0.0, 7)
-
-      off = np.divide(np.sqrt(50), 2, dtype=np.float64)
-      expected2 = ((5 + off, 5 + off, 5 - off, 5 - off))
-      self.assertAlmostEqual(np.sum(np.abs(np.subtract(lines[2], expected2))),
-                             0.0, 7)
-      expected3 = ((-4, 1, 6, 1))
-      self.assertAlmostEqual(np.sum(np.abs(np.subtract(lines[3], expected3))),
-                             0.0, 7)
-
-    def testIsPointApproxOnLine(self):
-      p1 = np.asfarray((-1, -1))
-      l1 = np.asfarray((0, 0, 100, 100))
-      p2 = np.asfarray((1, 2))
-      p3 = np.asfarray((2, 1))
-      p4 = np.asfarray((3, 1))
-      self.assertTrue(self.cv_util.IsPointApproxOnLine(p1, l1, 1 + 1e-7))
-      self.assertTrue(self.cv_util.IsPointApproxOnLine(p2, l1, 1 + 1e-7))
-      self.assertTrue(self.cv_util.IsPointApproxOnLine(p3, l1, 1 + 1e-7))
-      self.assertFalse(self.cv_util.IsPointApproxOnLine(p4, l1, 1 + 1e-7))
-
-    def testSqDistances(self):
-      p1 = np.array([[0, 2], [0, 3]])
-      p2 = np.array([2, 0])
-      dists = self.cv_util.SqDistance(p1, p2)
-      self.assertEqual(dists[0], 8)
-      self.assertEqual(dists[1], 13)
-
-    def testSqDistance(self):
-      p1 = np.array([0, 2])
-      p2 = np.array([2, 0])
-      self.assertEqual(self.cv_util.SqDistance(p1, p2), 8)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/fake_frame_generator.py b/catapult/telemetry/telemetry/internal/image_processing/fake_frame_generator.py
deleted file mode 100644
index cd77541..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/fake_frame_generator.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.image_processing import frame_generator
-from telemetry.internal.util import external_modules
-
-np = external_modules.ImportRequiredModule('numpy')
-
-
-class FakeFrameGenerator(frame_generator.FrameGenerator):
-  """ Fakes a Frame Generator, for testing.
-
-  Attributes:
-    _frame_index: A frame read counter.
-    _timestamps: A generator of timestamps to return, or None.
-    _timestamp: The current timestamp.
-    _dimensions: The dimensions to return.
-    _channels: The number of color channels to return in the generated frames.
-    _frames: The number of frames to return before fake EOF."""
-  def __init__(self, frames=1e16, dimensions=(320, 240), channels=3,
-               timestamps=(x for x in iter(int, 1))):
-    """ Initializes the FakeFrameGenerator object.
-
-    Args:
-      frames: int, The number of frames to return before fake EOF.
-      dimensions: (int, int), The dimensions to return.
-      timestamps: generator, A generator of timestamps to return. The default
-          value is an infinite 0 generator.
-      channels: int, The number of color channels to return in the generated
-          frames, 1 for greyscale, 3 for RGB."""
-    self._dimensions = dimensions
-    self._timestamps = timestamps
-    self._timestamp = 0
-    self._frame_index = -1
-    self._channels = channels
-    self._frames = frames
-
-    super(FakeFrameGenerator, self).__init__()
-
-  # OVERRIDE
-  def _CreateGenerator(self):
-    while self._frame_index < self._frames - 1:
-      self._frame_index += 1
-      self._timestamp = next(self._timestamps)
-      yield np.zeros((self._dimensions[0], self._dimensions[1],
-                      self._channels), np.uint8)
-
-  # OVERRIDE
-  @property
-  def CurrentTimestamp(self):
-    return self._timestamp
-
-  # OVERRIDE
-  @property
-  def CurrentFrameNumber(self):
-    return self._frame_index
-
-  # OVERRIDE
-  @property
-  def Dimensions(self):
-    return self._dimensions
diff --git a/catapult/telemetry/telemetry/internal/image_processing/frame_generator.py b/catapult/telemetry/telemetry/internal/image_processing/frame_generator.py
deleted file mode 100644
index b701418..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/frame_generator.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import abc
-
-
-class FrameReadError(Exception):
-  pass
-
-
-class FrameGenerator(object):
-  """ Defines an interface for reading input frames.
-
-  Attributes:
-    _generator: A reference to the created generator.
-  """
-  __metaclass__ = abc.ABCMeta
-
-  def __init__(self):
-    """ Initializes the FrameGenerator object. """
-    self._generator = self._CreateGenerator()
-
-  @abc.abstractmethod
-  def _CreateGenerator(self):
-    """ Creates a new generator.
-
-    Implemented in derived classes.
-
-    Raises:
-      FrameReadError: A error occurred in reading the frame.
-    """
-    raise NotImplementedError
-
-  @property
-  def Generator(self):
-    """ Returns:
-          A reference to the created generator.
-    """
-    return self._generator
-
-  @abc.abstractproperty
-  def CurrentTimestamp(self):
-    """ Returns:
-          float, The timestamp of the current frame in milliseconds.
-    """
-    raise NotImplementedError
-
-  @abc.abstractproperty
-  def CurrentFrameNumber(self):
-    """ Returns:
-          int, The frame index of the current frame.
-    """
-    raise NotImplementedError
-
-  @abc.abstractproperty
-  def Dimensions(self):
-    """ Returns:
-          The dimensions of the frame sequence as a tuple int (width, height).
-          This value should be constant across frames.
-    """
-    raise NotImplementedError
diff --git a/catapult/telemetry/telemetry/internal/image_processing/image_util_bitmap_impl.py b/catapult/telemetry/telemetry/internal/image_processing/image_util_bitmap_impl.py
deleted file mode 100644
index 18e4554..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/image_util_bitmap_impl.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from __future__ import division
-
-from telemetry.internal.image_processing import _bitmap
-
-
-def Channels(bitmap):
-  return bitmap.bpp
-
-def Width(bitmap):
-  return bitmap.width
-
-def Height(bitmap):
-  return bitmap.height
-
-def Pixels(bitmap):
-  return bitmap.pixels
-
-def GetPixelColor(bitmap, x, y):
-  return bitmap.GetPixelColor(x, y)
-
-def WritePngFile(bitmap, path):
-  bitmap.WritePngFile(path)
-
-def FromRGBPixels(width, height, pixels, bpp):
-  return _bitmap.Bitmap(bpp, width, height, pixels)
-
-def FromPng(png_data):
-  return _bitmap.Bitmap.FromPng(png_data)
-
-def FromPngFile(path):
-  return _bitmap.Bitmap.FromPngFile(path)
-
-def AreEqual(bitmap1, bitmap2, tolerance, _):
-  return bitmap1.IsEqual(bitmap2, tolerance)
-
-def Diff(bitmap1, bitmap2):
-  return bitmap1.Diff(bitmap2)
-
-def GetBoundingBox(bitmap, color, tolerance):
-  return bitmap.GetBoundingBox(color, tolerance)
-
-def Crop(bitmap, left, top, width, height):
-  return bitmap.Crop(left, top, width, height)
-
-def GetColorHistogram(bitmap, ignore_color, tolerance):
-  return bitmap.ColorHistogram(ignore_color, tolerance)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/image_util_numpy_impl.py b/catapult/telemetry/telemetry/internal/image_processing/image_util_numpy_impl.py
deleted file mode 100644
index 5b71429..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/image_util_numpy_impl.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from __future__ import division
-
-import warnings
-
-from telemetry.internal.util import external_modules
-from telemetry.util import color_histogram
-from telemetry.util import rgba_color
-import png
-
-cv2 = external_modules.ImportOptionalModule('cv2')
-np = external_modules.ImportRequiredModule('numpy')
-
-
-def Channels(image):
-  return image.shape[2]
-
-def Width(image):
-  return image.shape[1]
-
-def Height(image):
-  return image.shape[0]
-
-def Pixels(image):
-  return bytearray(np.uint8(image[:, :, ::-1]).flat)  # Convert from bgr to rgb.
-
-def GetPixelColor(image, x, y):
-  bgr = image[y][x]
-  return rgba_color.RgbaColor(bgr[2], bgr[1], bgr[0])
-
-def WritePngFile(image, path):
-  if cv2 is not None:
-    cv2.imwrite(path, image)
-  else:
-    with open(path, "wb") as f:
-      metadata = {}
-      metadata['size'] = (Width(image), Height(image))
-      metadata['alpha'] = False
-      metadata['bitdepth'] = 8
-      img = image[:, :, ::-1]
-      pixels = img.reshape(-1).tolist()
-      png.Writer(**metadata).write_array(f, pixels)
-
-def FromRGBPixels(width, height, pixels, bpp):
-  img = np.array(pixels, order='F', dtype=np.uint8)
-  img.resize((height, width, bpp))
-  if bpp == 4:
-    img = img[:, :, :3]  # Drop alpha.
-  return img[:, :, ::-1]  # Convert from rgb to bgr.
-
-def FromPngFile(path):
-  if cv2 is not None:
-    img = cv2.imread(path, cv2.CV_LOAD_IMAGE_COLOR)
-    if img is None:
-      raise ValueError('Image at path {0} could not be read'.format(path))
-    return img
-  else:
-    with open(path, "rb") as f:
-      return FromPng(f.read())
-
-def FromPng(png_data):
-  if cv2 is not None:
-    file_bytes = np.asarray(bytearray(png_data), dtype=np.uint8)
-    return cv2.imdecode(file_bytes, cv2.CV_LOAD_IMAGE_COLOR)
-  else:
-    warnings.warn(
-        'Using pure python png decoder, which could be very slow. To speed up, '
-        'consider installing numpy & cv2 (OpenCV).')
-    width, height, pixels, meta = png.Reader(bytes=png_data).read_flat()
-    return FromRGBPixels(width, height, pixels, 4 if meta['alpha'] else 3)
-
-def _SimpleDiff(image1, image2):
-  if cv2 is not None:
-    return cv2.absdiff(image1, image2)
-  else:
-    amax = np.maximum(image1, image2)
-    amin = np.minimum(image1, image2)
-    return amax - amin
-
-def AreEqual(image1, image2, tolerance, likely_equal):
-  if image1.shape != image2.shape:
-    return False
-  self_image = image1
-  other_image = image2
-  if tolerance:
-    if likely_equal:
-      return np.amax(_SimpleDiff(image1, image2)) <= tolerance
-    else:
-      for row in xrange(Height(image1)):
-        if np.amax(_SimpleDiff(image1[row], image2[row])) > tolerance:
-          return False
-      return True
-  else:
-    if likely_equal:
-      return (self_image == other_image).all()
-    else:
-      for row in xrange(Height(image1)):
-        if not (self_image[row] == other_image[row]).all():
-          return False
-      return True
-
-def Diff(image1, image2):
-  self_image = image1
-  other_image = image2
-  if image1.shape[2] != image2.shape[2]:
-    raise ValueError('Cannot diff images of differing bit depth')
-  if image1.shape[:2] != image2.shape[:2]:
-    width = max(Width(image1), Width(image2))
-    height = max(Height(image1), Height(image2))
-    self_image = np.zeros((width, height, image1.shape[2]), np.uint8)
-    other_image = np.zeros((width, height, image1.shape[2]), np.uint8)
-    self_image[0:Height(image1), 0:Width(image1)] = image1
-    other_image[0:Height(image2), 0:Width(image2)] = image2
-  return _SimpleDiff(self_image, other_image)
-
-def GetBoundingBox(image, color, tolerance):
-  if cv2 is not None:
-    color = np.array([color.b, color.g, color.r])
-    img = cv2.inRange(image, np.subtract(color[0:3], tolerance),
-                      np.add(color[0:3], tolerance))
-    count = cv2.countNonZero(img)
-    if count == 0:
-      return None, 0
-    contours, _ = cv2.findContours(img, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
-    contour = np.concatenate(contours)
-    return cv2.boundingRect(contour), count
-  else:
-    if tolerance:
-      color = np.array([color.b, color.g, color.r])
-      colorm = color - tolerance
-      colorp = color + tolerance
-      b = image[:, :, 0]
-      g = image[:, :, 1]
-      r = image[:, :, 2]
-      w = np.where(((b >= colorm[0]) & (b <= colorp[0]) &
-                    (g >= colorm[1]) & (g <= colorp[1]) &
-                    (r >= colorm[2]) & (r <= colorp[2])))
-    else:
-      w = np.where((image[:, :, 0] == color.b) &
-                   (image[:, :, 1] == color.g) &
-                   (image[:, :, 2] == color.r))
-    if len(w[0]) == 0:
-      return None, 0
-    return (w[1][0], w[0][0], w[1][-1] - w[1][0] + 1, w[0][-1] - w[0][0] + 1), \
-        len(w[0])
-
-def Crop(image, left, top, width, height):
-  img_height, img_width = image.shape[:2]
-  if (left < 0 or top < 0 or
-      (left + width) > img_width or
-      (top + height) > img_height):
-    raise ValueError('Invalid dimensions')
-  return image[top:top + height, left:left + width]
-
-def GetColorHistogram(image, ignore_color, tolerance):
-  if cv2 is not None:
-    mask = None
-    if ignore_color is not None:
-      color = np.array([ignore_color.b, ignore_color.g, ignore_color.r])
-      mask = ~cv2.inRange(image, np.subtract(color, tolerance),
-                          np.add(color, tolerance))
-
-    flatten = np.ndarray.flatten
-    hist_b = flatten(cv2.calcHist([image], [0], mask, [256], [0, 256]))
-    hist_g = flatten(cv2.calcHist([image], [1], mask, [256], [0, 256]))
-    hist_r = flatten(cv2.calcHist([image], [2], mask, [256], [0, 256]))
-  else:
-    filtered = image.reshape(-1, 3)
-    if ignore_color is not None:
-      color = np.array([ignore_color.b, ignore_color.g, ignore_color.r])
-      colorm = np.array(color) - tolerance
-      colorp = np.array(color) + tolerance
-      in_range = ((filtered[:, 0] < colorm[0]) | (filtered[:, 0] > colorp[0]) |
-                  (filtered[:, 1] < colorm[1]) | (filtered[:, 1] > colorp[1]) |
-                  (filtered[:, 2] < colorm[2]) | (filtered[:, 2] > colorp[2]))
-      filtered = np.compress(in_range, filtered, axis=0)
-    if len(filtered[:, 0]) == 0:
-      return color_histogram.ColorHistogram(np.zeros((256)), np.zeros((256)),
-                                      np.zeros((256)), ignore_color)
-    hist_b = np.bincount(filtered[:, 0], minlength=256)
-    hist_g = np.bincount(filtered[:, 1], minlength=256)
-    hist_r = np.bincount(filtered[:, 2], minlength=256)
-
-  return color_histogram.ColorHistogram(hist_r, hist_g, hist_b, ignore_color)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/screen_finder.py b/catapult/telemetry/telemetry/internal/image_processing/screen_finder.py
deleted file mode 100755
index 932d6df..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/screen_finder.py
+++ /dev/null
@@ -1,857 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This script attempts to detect the region of a camera's field of view that
-# contains the screen of the device we are testing.
-#
-# Usage: ./screen_finder.py path_to_video 0 0 --verbose
-
-from __future__ import division
-
-import copy
-import logging
-import os
-import sys
-
-if __name__ == '__main__':
-  sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..'))
-
-from telemetry.internal.image_processing import cv_util
-from telemetry.internal.image_processing import frame_generator as \
-    frame_generator_module
-from telemetry.internal.image_processing import video_file_frame_generator
-from telemetry.internal.util import external_modules
-
-np = external_modules.ImportRequiredModule('numpy')
-cv2 = external_modules.ImportRequiredModule('cv2')
-
-
-class ScreenFinder(object):
-  """Finds and extracts device screens from video.
-
-  Sample Usage:
-    sf = ScreenFinder(sys.argv[1])
-    while sf.HasNext():
-      ret, screen = sf.GetNext()
-
-  Attributes:
-    _lost_corners: Each index represents whether or not we lost track of that
-        corner on the previous frame. Ordered by [top-right, top-left,
-        bottom-left, bottom-right]
-    _frame: An unmodified copy of the frame we're currently processing.
-    _frame_debug: A copy of the frame we're currently processing, may be
-        modified at any time, used for debugging.
-    _frame_grey: A greyscale copy of the frame we're currently processing.
-    _frame_edges: A Canny Edge detected copy of the frame we're currently
-        processing.
-    _screen_size: The size of device screen in the video when first detected.
-    _avg_corners: Exponentially weighted average of the previous corner
-        locations.
-    _prev_corners: The location of the corners in the previous frame.
-    _lost_corner_frames: A counter of the number of successive frames in which
-        we've lost a corner location.
-    _border: See |border| above.
-    _min_line_length: The minimum length a line must be before we consider it
-        a possible screen edge.
-    _frame_generator: See |frame_generator| above.
-    _width, _height: The width and height of the frame.
-    _anglesp5, _anglesm5: The angles for each point we look at in the grid
-        when computing brightness, constant across frames."""
-
-  class ScreenNotFoundError(Exception):
-    pass
-
-  # Square of the distance a corner can travel in pixels between frames
-  MAX_INTERFRAME_MOTION = 25
-  # The minimum width line that may be considered a screen edge.
-  MIN_SCREEN_WIDTH = 40
-  # Number of frames with lost corners before we ignore MAX_INTERFRAME_MOTION
-  RESET_AFTER_N_BAD_FRAMES = 2
-  # The weight applied to the new screen location when exponentially averaging
-  # screen location.
-  # TODO(mthiesse): This should be framerate dependent, for lower framerates
-  # this value should approach 1. For higher framerates, this value should
-  # approach 0. The current 0.5 value works well in testing with 240 FPS.
-  CORNER_AVERAGE_WEIGHT = 0.5
-
-  # TODO(mthiesse): Investigate how to select the constants used here. In very
-  # bright videos, twice as bright may be too high, and the minimum of 60 may
-  # be too low.
-  # The factor by which a quadrant at an intersection must be brighter than
-  # the other quadrants to be considered a screen corner.
-  MIN_RELATIVE_BRIGHTNESS_FACTOR = 1.5
-  # The minimum average brightness required of an intersection quadrant to
-  # be considered a screen corner (on a scale of 0-255).
-  MIN_CORNER_ABSOLUTE_BRIGHTNESS = 60
-
-  # Low and high hysteresis parameters to be passed to the Canny edge
-  # detection algorithm.
-  CANNY_HYSTERESIS_THRESH_LOW = 300
-  CANNY_HYSTERESIS_THRESH_HIGH = 500
-
-  SMALL_ANGLE = 5 / 180 * np.pi  # 5 degrees in radians
-
-  DEBUG = False
-
-  def __init__(self, frame_generator, border=5):
-    """Initializes the ScreenFinder object.
-
-    Args:
-      frame_generator: FrameGenerator, An initialized Video Frame Generator.
-      border: int, number of pixels of border to be kept when cropping the
-          detected screen.
-
-    Raises:
-      FrameReadError: The frame generator may output a read error during
-          initialization."""
-    assert isinstance(frame_generator, frame_generator_module.FrameGenerator)
-    self._lost_corners = [False, False, False, False]
-    self._frame_debug = None
-    self._frame = None
-    self._frame_grey = None
-    self._frame_edges = None
-    self._screen_size = None
-    self._avg_corners = None
-    self._prev_corners = None
-    self._lost_corner_frames = 0
-    self._border = border
-    self._min_line_length = self.MIN_SCREEN_WIDTH
-    self._frame_generator = frame_generator
-    self._anglesp5 = None
-    self._anglesm5 = None
-
-    if not self._InitNextFrame():
-      logging.warn('Not enough frames in video feed!')
-      return
-
-    self._height, self._width = self._frame.shape[:2]
-
-  def _InitNextFrame(self):
-    """Called after processing each frame, reads in the next frame to ensure
-    HasNext() is accurate."""
-    self._frame_debug = None
-    self._frame = None
-    self._frame_grey = None
-    self._frame_edges = None
-    try:
-      frame = next(self._frame_generator.Generator)
-    except StopIteration:
-      return False
-    self._frame = frame
-    self._frame_debug = copy.copy(frame)
-    self._frame_grey = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
-    self._frame_edges = cv2.Canny(self._frame_grey,
-                                  self.CANNY_HYSTERESIS_THRESH_LOW,
-                                  self.CANNY_HYSTERESIS_THRESH_HIGH)
-    return True
-
-  def HasNext(self):
-    """True if there are more frames available to process. """
-    return self._frame is not None
-
-  def GetNext(self):
-    """Gets the next screen image.
-
-    Returns:
-      A numpy matrix containing the screen surrounded by the number of border
-      pixels specified in initialization, and the location of the detected
-      screen corners in the current frame, if a screen is found. The returned
-      screen is guaranteed to be the same size at each frame.
-      'None' and 'None' if no screen was found on the current frame.
-
-    Raises:
-      FrameReadError: An error occurred in the FrameGenerator.
-      RuntimeError: This method was called when no frames were available."""
-    if self._frame is None:
-      raise RuntimeError('No more frames available.')
-
-    logging.info('Processing frame: %d',
-                 self._frame_generator.CurrentFrameNumber)
-
-    # Finds straight lines in the image.
-    hlines = cv2.HoughLinesP(self._frame_edges, 1, np.pi / 180, 60,
-                             minLineLength=self._min_line_length,
-                             maxLineGap=100)
-
-    # Extends these straight lines to be long enough to ensure the screen edge
-    # lines intersect.
-    lines = cv_util.ExtendLines(np.float32(hlines[0]), 10000) \
-        if hlines is not None else []
-
-    # Find intersections in the lines; these are likely to be screen corners.
-    intersections = self._FindIntersections(lines)
-    if len(intersections[:, 0]) > 0:
-      points = np.vstack(intersections[:, 0].flat)
-      if (self._prev_corners is not None and len(points) >= 4 and
-          not self._HasMovedFast(points, self._prev_corners)):
-        corners = self._prev_corners
-        missing_corners = 0
-      else:
-        # Extract the corners from all intersections.
-        corners, missing_corners = self._FindCorners(
-            intersections, self._frame_grey)
-    else:
-      corners = np.empty((4, 2), np.float32)
-      corners[:] = np.nan
-      missing_corners = 4
-
-    screen = None
-    found_screen = True
-    final_corners = None
-    try:
-      # Handle the cases where we have missing corners.
-      screen_corners = self._NewScreenLocation(
-          corners, missing_corners, intersections)
-
-      final_corners = self._SmoothCorners(screen_corners)
-
-      # Create a perspective transform from our corners.
-      transform, w, h = self._GetTransform(final_corners, self._border)
-
-      # Apply the perspective transform to get our output.
-      screen = cv2.warpPerspective(
-          self._frame, transform, (int(w + 0.5), int(h + 0.5)))
-
-      self._prev_corners = final_corners
-
-    except self.ScreenNotFoundError as e:
-      found_screen = False
-      logging.info(e)
-
-    if self.DEBUG:
-      self._Debug(lines, corners, final_corners, screen)
-
-    self._InitNextFrame()
-    if found_screen:
-      return screen, self._prev_corners
-    return None, None
-
-  def _FindIntersections(self, lines):
-    """Finds intersections in a set of lines.
-
-    Filters pairs of lines that are less than 45 degrees apart. Filtering
-    these pairs helps dramatically reduce the number of points we have to
-    process, as these points could not represent screen corners anyways.
-
-    Returns:
-      The intersections, represented as a tuple of (point, line, line) of the
-      points and the lines that intersect there of all lines in the array that
-      are more than 45 degrees apart."""
-    intersections = np.empty((0, 3), np.float32)
-    for i in xrange(0, len(lines)):
-      for j in xrange(i + 1, len(lines)):
-        # Filter lines that are less than 45 (or greater than 135) degrees
-        # apart.
-        if not cv_util.AreLinesOrthogonal(lines[i], lines[j], (np.pi / 4.0)):
-          continue
-        ret, point = cv_util.FindLineIntersection(lines[i], lines[j])
-        point = np.float32(point)
-        if not ret:
-          continue
-        # If we know where the previous corners are, we can also filter
-        # intersections that are too far away from the previous corners to be
-        # where the screen has moved.
-        if self._prev_corners is not None and \
-           self._lost_corner_frames <= self.RESET_AFTER_N_BAD_FRAMES and \
-           not self._PointIsCloseToPreviousCorners(point):
-          continue
-        intersections = np.vstack((intersections,
-                                   np.array((point, lines[i], lines[j]))))
-    return intersections
-
-  def _PointIsCloseToPreviousCorners(self, point):
-    """True if the point is close to the previous corners."""
-    max_dist = self.MAX_INTERFRAME_MOTION
-    if cv_util.SqDistance(self._prev_corners[0], point) <= max_dist or \
-       cv_util.SqDistance(self._prev_corners[1], point) <= max_dist or \
-       cv_util.SqDistance(self._prev_corners[2], point) <= max_dist or \
-       cv_util.SqDistance(self._prev_corners[3], point) <= max_dist:
-      return True
-    return False
-
-  def _HasMovedFast(self, corners, prev_corners):
-    min_dist = np.zeros(4, np.float32)
-    for i in xrange(4):
-      dist = np.min(cv_util.SqDistances(corners, prev_corners[i]))
-      min_dist[i] = dist
-    # 3 corners can move up to one pixel before we consider the screen to have
-    # moved. TODO(mthiesse): Should this be relaxed? Resolution dependent?
-    if np.sum(min_dist) < 3:
-      return False
-    return True
-
-  class CornerData(object):
-
-    def __init__(self, corner_index, corner_location, brightness_score, line1,
-                 line2):
-      self.corner_index = corner_index
-      self.corner_location = corner_location
-      self.brightness_score = brightness_score
-      self.line1 = line1
-      self.line2 = line2
-
-    def __gt__(self, corner_data2):
-      return self.corner_index > corner_data2.corner_index
-
-    def __repr__(self):
-      return ('\nCorner index: ' + str(self.corner_index) +
-              ',\nCorner location: ' + str(self.corner_location) +
-              ',\nBrightness score: ' + str(self.brightness_score) +
-              ',\nline1: ' + str(self.line1) + ',\nline2: ' + str(self.line2))
-
-  def _FindCorners(self, intersections, grey_frame):
-    """Finds the screen corners in the image.
-
-    Given the set of intersections in the image, finds the intersections most
-    likely to be corners.
-
-    Args:
-      intersections: The array of intersections in the image.
-      grey_frame: The greyscale frame we're processing.
-
-    Returns:
-      An array of length 4 containing the positions of the corners, or nan for
-      each index where a corner could not be found, and a count of the number
-      of missing corners.
-      The corners are ordered as follows:
-        1 | 0
-        -----
-        2 | 3
-      Ex. 3 corners are found from a square of width 2 centered at the origin,
-      the output would look like:
-          '[[1, 1], [np.nan, np.nan], [-1, -1], [1, -1]], 1'"""
-    filtered = []
-    corners = np.empty((0, 2), np.float32)
-    for corner_pos, score, point, line1, line2 in \
-        self._LooksLikeCorner(intersections, grey_frame):
-      if self.DEBUG:
-        center = (int(point[0] + 0.5), int(point[1] + 0.5))
-        cv2.circle(self._frame_debug, center, 5, (0, 255, 0), 1)
-      point.resize(1, 2)
-      corners = np.append(corners, point, axis=0)
-      point.resize(2,)
-      corner_data = self.CornerData(corner_pos, point, score, line1, line2)
-      filtered.append(corner_data)
-
-    # De-duplicate corners because we may have found many false positives, or
-    # near-misses.
-    self._DeDupCorners(filtered, corners)
-
-    # Strip everything but the corner location.
-    filtered_corners = np.array(
-        [corner_data.corner_location for corner_data in filtered])
-    corner_indices = [corner_data.corner_index for corner_data in filtered]
-
-    # If we have found a corner to replace a lost corner, we want to check
-    # that the corner is not erroneous by ensuring it makes a rectangle with
-    # the 3 known good corners.
-    if len(filtered) == 4:
-      for i in xrange(4):
-        point_info = (filtered[i].corner_location,
-                      filtered[i].line1,
-                      filtered[i].line2)
-        if (self._lost_corners[i] and
-            not self._PointConnectsToCorners(filtered_corners, point_info)):
-          filtered_corners = np.delete(filtered_corners, i, 0)
-          corner_indices = np.delete(corner_indices, i, 0)
-          break
-
-    # Ensure corners are sorted properly, inserting nans for missing corners.
-    sorted_corners = np.empty((4, 2), np.float32)
-    sorted_corners[:] = np.nan
-    for i in xrange(len(filtered_corners)):
-      sorted_corners[corner_indices[i]] = filtered_corners[i]
-
-    # From this point on, our corners arrays are guaranteed to have 4
-    # elements, though some may be nan.
-
-    # Filter corners that have moved too far from the previous corner if we
-    # are not resetting known corner information.
-    reset_corners = (
-        (self._lost_corner_frames > self.RESET_AFTER_N_BAD_FRAMES)
-        and len(filtered_corners) == 4)
-    if self._prev_corners is not None and not reset_corners:
-      sqdists = cv_util.SqDistances(self._prev_corners, sorted_corners)
-      for i in xrange(4):
-        if np.isnan(sorted_corners[i][0]):
-          continue
-        if sqdists[i] > self.MAX_INTERFRAME_MOTION:
-          sorted_corners[i] = np.nan
-
-    real_corners = self._FindExactCorners(sorted_corners)
-    missing_corners = np.count_nonzero(np.isnan(real_corners)) / 2
-    return real_corners, missing_corners
-
-  def _LooksLikeCorner(self, intersections, grey_frame):
-    """Finds any intersections of lines that look like a screen corner.
-
-    Args:
-      intersections: The numpy array of points, and the lines that intersect
-          at the given point.
-      grey_frame: The greyscale frame we're processing.
-
-    Returns:
-      An array of: The corner location (0-3), the relative brightness score
-      (to be used to de-duplicate corners later), the point, and the lines
-      that make up the intersection, for all intersections that look like a
-      corner."""
-    points = np.vstack(intersections[:, 0].flat)
-    lines1 = np.vstack(intersections[:, 1].flat)
-    lines2 = np.vstack(intersections[:, 2].flat)
-    # Map the image to four quadrants defined as the regions between each of
-    # the lines that make up the intersection.
-    line1a1 = np.pi - np.arctan2(lines1[:, 1] - points[:, 1],
-                                 lines1[:, 0] - points[:, 0])
-    line1a2 = np.pi - np.arctan2(lines1[:, 3] - points[:, 1],
-                                 lines1[:, 2] - points[:, 0])
-    line2a1 = np.pi - np.arctan2(lines2[:, 1] - points[:, 1],
-                                 lines2[:, 0] - points[:, 0])
-    line2a2 = np.pi - np.arctan2(lines2[:, 3] - points[:, 1],
-                                 lines2[:, 2] - points[:, 0])
-    line1a1 = line1a1.reshape(-1, 1)
-    line1a2 = line1a2.reshape(-1, 1)
-    line2a1 = line2a1.reshape(-1, 1)
-    line2a2 = line2a2.reshape(-1, 1)
-
-    line_angles = np.concatenate((line1a1, line1a2, line2a1, line2a2), axis=1)
-    np.ndarray.sort(line_angles)
-
-    # TODO(mthiesse): Investigate whether these should scale with image or
-    # screen size. My intuition is that these don't scale with image size,
-    # though they may be affected by image quality and how blurry the corners
-    # are. See stackoverflow.com/q/7765810/ for inspiration.
-    avg_range = 8.0
-    num_points = 7
-
-    points_m_avg = points - avg_range
-    points_p_avg = points + avg_range
-    # Exclude points near frame boundaries.
-    include = np.where((points_m_avg[:, 0] > 0) & (points_m_avg[:, 1] > 0) &
-                       (points_p_avg[:, 0] < self._width) &
-                       (points_p_avg[:, 1] < self._height))
-    line_angles = line_angles[include]
-    points = points[include]
-    lines1 = lines1[include]
-    lines2 = lines2[include]
-    points_m_avg = points_m_avg[include]
-    points_p_avg = points_p_avg[include]
-    # Perform a 2-d linspace to generate the x, y ranges for each
-    # intersection.
-    arr1 = points_m_avg[:, 0].reshape(-1, 1)
-    arr2 = points_p_avg[:, 0].reshape(-1, 1)
-    lin = np.linspace(0, 1, num_points)
-    x_range = arr1 + (arr2 - arr1) * lin
-    arr1 = points_m_avg[:, 1].reshape(-1, 1)
-    arr2 = points_p_avg[:, 1].reshape(-1, 1)
-    y_range = arr1 + (arr2 - arr1) * lin
-
-    # The angles for each point we look at in the grid when computing
-    # brightness are constant across frames, so we can generate them once.
-    if self._anglesp5 is None:
-      ind = np.transpose([np.tile(x_range[0], num_points),
-                          np.repeat(y_range[0], num_points)])
-      vectors = ind - points[0]
-      angles = np.arctan2(vectors[:, 1], vectors[:, 0]) + np.pi
-      self._anglesp5 = angles + self.SMALL_ANGLE
-      self._anglesm5 = angles - self.SMALL_ANGLE
-    results = []
-    for i in xrange(len(y_range)):
-      # Generate our filters for which points belong to which quadrant.
-      one = np.where((self._anglesp5 <= line_angles[i, 1]) &
-                     (self._anglesm5 >= line_angles[i, 0]))
-      two = np.where((self._anglesp5 <= line_angles[i, 2]) &
-                     (self._anglesm5 >= line_angles[i, 1]))
-      thr = np.where((self._anglesp5 <= line_angles[i, 3]) &
-                     (self._anglesm5 >= line_angles[i, 2]))
-      fou = np.where((self._anglesp5 <= line_angles[i, 0]) |
-                     (self._anglesm5 >= line_angles[i, 3]))
-      # Take the cartesian product of our x and y ranges to get the full list
-      # of pixels to look at.
-      ind = np.transpose([np.tile(x_range[i], num_points),
-                          np.repeat(y_range[i], num_points)])
-
-      # Filter the full list by which indices belong to which quadrant, and
-      # convert to integers so we can index with them.
-      one_i = np.int32(np.rint(ind[one[0]]))
-      two_i = np.int32(np.rint(ind[two[0]]))
-      thr_i = np.int32(np.rint(ind[thr[0]]))
-      fou_i = np.int32(np.rint(ind[fou[0]]))
-
-      # Average the brightness of the pixels that belong to each quadrant.
-      q_1 = np.average(grey_frame[one_i[:, 1], one_i[:, 0]])
-      q_2 = np.average(grey_frame[two_i[:, 1], two_i[:, 0]])
-      q_3 = np.average(grey_frame[thr_i[:, 1], thr_i[:, 0]])
-      q_4 = np.average(grey_frame[fou_i[:, 1], fou_i[:, 0]])
-
-      avg_intensity = [(q_4, 0), (q_1, 1), (q_2, 2), (q_3, 3)]
-      # Sort by intensity.
-      avg_intensity.sort(reverse=True)
-
-      # Treat the point as a corner if one quadrant is at least twice as
-      # bright as the next brightest quadrant, with a minimum brightness
-      # requirement.
-      tau = (2.0 * np.pi)
-      min_factor = self.MIN_RELATIVE_BRIGHTNESS_FACTOR
-      min_brightness = self.MIN_RELATIVE_BRIGHTNESS_FACTOR
-      if avg_intensity[0][0] > avg_intensity[1][0] * min_factor and \
-         avg_intensity[0][0] > min_brightness:
-        bright_corner = avg_intensity[0][1]
-        if bright_corner == 0:
-          angle = np.pi - (line_angles[i, 0] + line_angles[i, 3]) / 2.0
-          if angle < 0:
-            angle = angle + tau
-        else:
-          angle = tau - (line_angles[i, bright_corner] +
-                         line_angles[i, bright_corner - 1]) / 2.0
-        score = avg_intensity[0][0] - avg_intensity[1][0]
-        # TODO(mthiesse): int(angle / (pi / 2.0)) will break if the screen is
-        # rotated through 45 degrees. Probably many other things will break as
-        # well, movement of corners from one quadrant to another hasn't been
-        # tested. We should support this eventually, but this is unlikely to
-        # cause issues for any test setups.
-        results.append((int(angle / (np.pi / 2.0)), score, points[i],
-                        lines1[i], lines2[i]))
-    return results
-
-  def _DeDupCorners(self, corner_data, corners):
-    """De-duplicate corners based on corner_index.
-
-    For each set of points representing a corner: If one point is part of the
-    rectangle and the other is not, filter the other one. If both or none are
-    part of the rectangle, filter based on score (highest relative brightness
-    of a quadrant). The reason we allow for neither to be part of the
-    rectangle is because we may not have found all four corners of the
-    rectangle, and in degenerate cases like this it's better to find 3 likely
-    corners than none.
-
-    Modifies corner_data directly.
-
-    Args:
-      corner_data: CornerData for each potential corner in the frame.
-      corners: List of all potential corners in the frame."""
-    # TODO(mthiesse): Ensure that the corners form a sensible rectangle. For
-    # example, it is currently possible (but unlikely) to detect a 'screen'
-    # where the bottom-left corner is above the top-left corner, while the
-    # bottom-right corner is below the top-right corner.
-
-    # Sort by corner_index to make de-duping easier.
-    corner_data.sort()
-
-    # De-dup corners.
-    c_old = None
-    for i in xrange(len(corner_data) - 1, 0, -1):
-      if corner_data[i].corner_index != corner_data[i - 1].corner_index:
-        c_old = None
-        continue
-      if c_old is None:
-        point_info = (corner_data[i].corner_location,
-                      corner_data[i].line1,
-                      corner_data[i].line2)
-        c_old = self._PointConnectsToCorners(corners, point_info, 2)
-      point_info_new = (corner_data[i - 1].corner_location,
-                        corner_data[i - 1].line1,
-                        corner_data[i - 1].line2)
-      c_new = self._PointConnectsToCorners(corners, point_info_new, 2)
-      if (not (c_old or c_new)) or (c_old and c_new):
-        if (corner_data[i].brightness_score <
-            corner_data[i - 1].brightness_score):
-          del corner_data[i]
-          c_old = c_new
-        else:
-          del corner_data[i - 1]
-      elif c_old:
-        del corner_data[i - 1]
-      else:
-        del corner_data[i]
-        c_old = c_new
-
-  def _PointConnectsToCorners(self, corners, point_info, tolerance=1):
-    """Checks if the lines of an intersection intersect with corners.
-
-    This is useful to check if the point is part of a rectangle specified by
-    |corners|.
-
-    Args:
-      point_info: A tuple of (point, line, line) representing an intersection
-          of two lines.
-      corners: corners that (hopefully) make up a rectangle.
-      tolerance: The tolerance (approximately in pixels) of the distance
-          between the corners and the lines for detecting if the point is on
-          the line.
-
-    Returns:
-      True if each of the two lines that make up the intersection where the
-      point is located connect the point to other corners."""
-    line1_connected = False
-    line2_connected = False
-    point, line1, line2 = point_info
-    for corner in corners:
-      if corner is None:
-        continue
-
-      # Filter out points that are too close to one another to be different
-      # corners.
-      sqdist = cv_util.SqDistance(corner, point)
-      if sqdist < self.MIN_SCREEN_WIDTH * self.MIN_SCREEN_WIDTH:
-        continue
-
-      line1_connected = line1_connected or \
-          cv_util.IsPointApproxOnLine(corner, line1, tolerance)
-      line2_connected = line2_connected or \
-          cv_util.IsPointApproxOnLine(corner, line2, tolerance)
-    if line1_connected and line2_connected:
-      return True
-    return False
-
-  def _FindExactCorners(self, sorted_corners):
-    """Attempts to find more accurate corner locations.
-
-    Args:
-      sorted_corners: The four screen corners, sorted by corner_index.
-
-    Returns:
-      A list of 4 probably more accurate corners, still sorted."""
-    real_corners = np.empty((4, 2), np.float32)
-    # Count missing corners, and search in a small area around our
-    # intersections representing corners to see if we can find a more exact
-    # corner, as the position of the intersections is noisy and not always
-    # perfectly accurate.
-    for i in xrange(4):
-      corner = sorted_corners[i]
-      if np.isnan(corner[0]):
-        real_corners[i] = np.nan
-        continue
-
-      # Almost unbelievably, in edge cases with floating point error, the
-      # width/height of the cropped corner image may be 2 or 4. This is fine
-      # though, as long as the width and height of the cropped corner are not
-      # hard-coded anywhere.
-      corner_image = self._frame_edges[corner[1] - 1:corner[1] + 2,
-                                       corner[0] - 1:corner[0] + 2]
-      ret, p = self._FindExactCorner(i <= 1, i == 1 or i == 2, corner_image)
-      if ret:
-        if self.DEBUG:
-          self._frame_edges[corner[1] - 1 + p[1]][corner[0] - 1 + p[0]] = 128
-        real_corners[i] = corner - 1 + p
-      else:
-        real_corners[i] = corner
-    return real_corners
-
-  def _FindExactCorner(self, top, left, img):
-    """Tries to finds the exact corner location for a given corner.
-
-    Searches for the top or bottom, left or right most lit
-    pixel in an edge-detected image, which should represent, with pixel
-    precision, as accurate a corner location as possible. (Though perhaps
-    up-sampling using cubic spline interpolation could get sub-pixel
-    precision)
-
-    TODO(mthiesse): This algorithm could be improved by including a larger
-    region to search in, but would have to be made smarter about which lit
-    pixels are on the detected screen edge and which are a not as it's
-    currently extremely easy to fool by things like notification icons in
-    screen corners.
-
-    Args:
-      top: boolean, whether or not we're looking for a top corner.
-      left: boolean, whether or not we're looking for a left corner.
-      img: A small cropping of the edge detected image in which to search.
-
-    Returns:
-      True and the location if a better corner location is found,
-      False otherwise."""
-    h, w = img.shape[:2]
-    cy = 0
-    starting_x = w - 1 if left else 0
-    cx = starting_x
-    if top:
-      y_range = xrange(h - 1, -1, -1)
-    else:
-      y_range = xrange(0, h, 1)
-    if left:
-      x_range = xrange(w - 1, -1, -1)
-    else:
-      x_range = xrange(0, w, 1)
-    for y in y_range:
-      for x in x_range:
-        if img[y][x] == 255:
-          cy = y
-          if (left and x <= cx) or (not left and x >= cx):
-            cx = x
-    if cx == starting_x and cy == 0 and img[0][starting_x] != 255:
-      return False, (0, 0)
-    return True, (cx, cy)
-
-  def _NewScreenLocation(self, new_corners, missing_corners, intersections):
-    """Computes the new screen location with best effort.
-
-    Creates the final list of corners that represents the best effort attempt
-    to find the new screen location. Handles degenerate cases where 3 or fewer
-    new corners are present, using previous corner and intersection data.
-
-    Args:
-      new_corners: The corners found by our search for corners.
-      missing_corners: The count of how many corners we're missing.
-      intersections: The intersections of straight lines found in the current
-          frame.
-
-    Returns:
-      An array of 4 new_corners hopefully representing the screen, or throws
-      an error if this is not possible.
-
-    Raises:
-      ValueError: Finding the screen location was not possible."""
-    screen_corners = copy.copy(new_corners)
-    if missing_corners == 0:
-      self._lost_corner_frames = 0
-      self._lost_corners = [False, False, False, False]
-      return screen_corners
-    if self._prev_corners is None:
-      raise self.ScreenNotFoundError(
-          'Could not locate screen on frame %d' %
-          self._frame_generator.CurrentFrameNumber)
-
-    self._lost_corner_frames += 1
-    if missing_corners > 1:
-      logging.info('Unable to properly detect screen corners, making '
-                   'potentially false assumptions on frame %d',
-                   self._frame_generator.CurrentFrameNumber)
-    # Replace missing new_corners with either nearest intersection to previous
-    # corner, or previous corner if no intersections are found.
-    for i in xrange(0, 4):
-      if not np.isnan(new_corners[i][0]):
-        self._lost_corners[i] = False
-        continue
-      self._lost_corners[i] = True
-      min_dist = self.MAX_INTERFRAME_MOTION
-      min_corner = None
-
-      for isection in intersections:
-        dist = cv_util.SqDistance(isection[0], self._prev_corners[i])
-        if dist >= min_dist:
-          continue
-        if missing_corners == 1:
-          # We know in this case that we have 3 corners present, meaning
-          # all 4 screen lines, and therefore intersections near screen
-          # corners present, so our new corner must connect to these
-          # other corners.
-          if not self._PointConnectsToCorners(new_corners, isection, 3):
-            continue
-        min_corner = isection[0]
-        min_dist = dist
-      screen_corners[i] = min_corner if min_corner is not None else \
-          self._prev_corners[i]
-
-    return screen_corners
-
-  def _SmoothCorners(self, corners):
-    """Smoothes the motion of corners, reduces noise.
-
-    Smoothes the motion of corners by computing an exponentially weighted
-    moving average of corner positions over time.
-
-    Args:
-      corners: The corners of the detected screen.
-
-    Returns:
-      The final corner positions."""
-    if self._avg_corners is None:
-      self._avg_corners = np.asfarray(corners, np.float32)
-    for i in xrange(0, 4):
-      # Keep an exponential moving average of the corner location to reduce
-      # noise.
-      new_contrib = np.multiply(self.CORNER_AVERAGE_WEIGHT, corners[i])
-      old_contrib = np.multiply(1 - self.CORNER_AVERAGE_WEIGHT,
-                                self._avg_corners[i])
-      self._avg_corners[i] = np.add(new_contrib, old_contrib)
-
-    return self._avg_corners
-
-  def _GetTransform(self, corners, border):
-    """Gets the perspective transform of the screen.
-
-    Args:
-      corners: The corners of the detected screen.
-      border: The number of pixels of border to crop along with the screen.
-
-    Returns:
-      A perspective transform and the width and height of the target
-      transform.
-
-    Raises:
-      ScreenNotFoundError: Something went wrong in detecting the screen."""
-    if self._screen_size is None:
-      w = np.sqrt(cv_util.SqDistance(corners[1], corners[0]))
-      h = np.sqrt(cv_util.SqDistance(corners[1], corners[2]))
-      if w < 1 or h < 1:
-        raise self.ScreenNotFoundError(
-            'Screen detected improperly (bad corners)')
-      if min(w, h) < self.MIN_SCREEN_WIDTH:
-        raise self.ScreenNotFoundError('Detected screen was too small.')
-
-      self._screen_size = (w, h)
-      # Extend min line length, if we can, to reduce the number of extraneous
-      # lines the line finder finds.
-      self._min_line_length = max(self._min_line_length, min(w, h) / 1.75)
-    w = self._screen_size[0]
-    h = self._screen_size[1]
-
-    target = np.zeros((4, 2), np.float32)
-    width = w + border
-    height = h + border
-    target[0] = np.asfarray((width, border))
-    target[1] = np.asfarray((border, border))
-    target[2] = np.asfarray((border, height))
-    target[3] = np.asfarray((width, height))
-    transform_w = width + border
-    transform_h = height + border
-    transform = cv2.getPerspectiveTransform(corners, target)
-    return transform, transform_w, transform_h
-
-  def _Debug(self, lines, corners, final_corners, screen):
-    for line in lines:
-      intline = ((int(line[0]), int(line[1])),
-                 (int(line[2]), int(line[3])))
-      cv2.line(self._frame_debug, intline[0], intline[1], (0, 0, 255), 1)
-    i = 0
-    for corner in corners:
-      if not np.isnan(corner[0]):
-        cv2.putText(
-            self._frame_debug, str(i), (int(corner[0]), int(corner[1])),
-            cv2.FONT_HERSHEY_COMPLEX_SMALL, 1, (255, 255, 0), 1, cv2.CV_AA)
-        i += 1
-    if final_corners is not None:
-      for corner in final_corners:
-        cv2.circle(self._frame_debug,
-                   (int(corner[0]), int(corner[1])), 5, (255, 0, 255), 1)
-    cv2.imshow('original', self._frame)
-    cv2.imshow('debug', self._frame_debug)
-    if screen is not None:
-      cv2.imshow('screen', screen)
-    cv2.waitKey()
-
-# For being run as a script.
-# TODO(mthiesse): To be replaced with a better standalone script.
-# Ex: ./screen_finder.py path_to_video 0 5 --verbose
-
-
-def main():
-  start_frame = int(sys.argv[2]) if len(sys.argv) >= 3 else 0
-  vf = video_file_frame_generator.VideoFileFrameGenerator(sys.argv[1],
-                                                          start_frame)
-  if len(sys.argv) >= 4:
-    sf = ScreenFinder(vf, int(sys.argv[3]))
-  else:
-    sf = ScreenFinder(vf)
-  # TODO(mthiesse): Use argument parser to improve command line parsing.
-  if len(sys.argv) > 4 and sys.argv[4] == '--verbose':
-    logging.basicConfig(format='%(message)s', level=logging.INFO)
-  else:
-    logging.basicConfig(format='%(message)s', level=logging.WARN)
-  while sf.HasNext():
-    sf.GetNext()
-
-if __name__ == '__main__':
-  main()
diff --git a/catapult/telemetry/telemetry/internal/image_processing/screen_finder_unittest.py b/catapult/telemetry/telemetry/internal/image_processing/screen_finder_unittest.py
deleted file mode 100644
index 313b496..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/screen_finder_unittest.py
+++ /dev/null
@@ -1,368 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import copy
-import math
-import os
-import unittest
-
-from telemetry.core import util
-from telemetry.internal.util import external_modules
-
-try:
-  np = external_modules.ImportRequiredModule('numpy')
-  cv2 = external_modules.ImportRequiredModule('cv2')
-except (ImportError, NotImplementedError) as err:
-  pass
-else:
-  # pylint: disable=protected-access
-  class ScreenFinderTest(unittest.TestCase):
-    def __init__(self, *args, **kwargs):
-      super(ScreenFinderTest, self).__init__(*args, **kwargs)
-      # Import modules with dependencies that may not be preset in test setup so
-      # that importing this unit test doesn't cause the test runner to raise an
-      # exception.
-      from telemetry.internal.image_processing import fake_frame_generator
-      from telemetry.internal.image_processing import screen_finder
-      from telemetry.internal.image_processing import video_file_frame_generator
-      self.FakeFrameGenerator = fake_frame_generator.FakeFrameGenerator
-      self.VideoFileFrameGenerator = \
-          video_file_frame_generator.VideoFileFrameGenerator
-      self.ScreenFinder = screen_finder.ScreenFinder
-
-    def _GetScreenFinder(self, video_filename):
-      if not video_filename:
-        fg = self.FakeFrameGenerator()
-      else:
-        vid = os.path.join(util.GetUnittestDataDir(), video_filename)
-        fg = self.VideoFileFrameGenerator(vid)
-      return self.ScreenFinder(fg)
-
-    def testBasicFunctionality(self):
-      def CheckCorners(corners, expected):
-        for i in xrange(len(corners)):
-          for j in xrange(len(corners[i])):
-            self.assertAlmostEqual(corners[i][j], expected[i][j], delta=1.1)
-      expected = [[314, 60], [168, 58], [162, 274], [311, 276]]
-      sf = self._GetScreenFinder('screen_3_frames.mov')
-      self.assertTrue(sf.HasNext())
-      screen, corners = sf.GetNext()
-      CheckCorners(corners, expected)
-      self.assertIsNotNone(screen)
-      height, width = screen.shape[:2]
-      self.assertAlmostEqual(height, 226, delta=2)
-      self.assertAlmostEqual(width, 156, delta=2)
-      self.assertTrue(sf.HasNext())
-      screen, corners = sf.GetNext()
-      CheckCorners(corners, expected)
-      self.assertIsNotNone(screen)
-      height1, width1 = screen.shape[:2]
-      self.assertEqual(width, width1)
-      self.assertEqual(height, height1)
-      self.assertTrue(sf.HasNext())
-      screen, corners = sf.GetNext()
-      CheckCorners(corners, expected)
-      self.assertIsNotNone(screen)
-      height2, width2 = screen.shape[:2]
-      self.assertEqual(width, width2)
-      self.assertEqual(height, height2)
-      self.assertFalse(sf.HasNext())
-      error = ''
-      try:
-        sf.GetNext()
-      except RuntimeError as e:
-        error = str(e)
-      self.assertEqual(error, 'No more frames available.')
-
-    def testHasMovedFast(self):
-      sf = self._GetScreenFinder(None)
-      prev_corners = np.asfarray(([1000, 1000], [0, 1000], [0, 0], [1000, 0]))
-      self.assertFalse(sf._HasMovedFast(prev_corners, prev_corners))
-      not_moved = copy.deepcopy(prev_corners)
-      not_moved[0][1] += 1
-      not_moved[1][1] += 1
-      not_moved[3][0] += 0.9
-      self.assertFalse(sf._HasMovedFast(not_moved, prev_corners))
-      moved = copy.deepcopy(prev_corners)
-      moved[0][1] += math.sqrt(0.5)
-      moved[0][0] += math.sqrt(0.5)
-      moved[1][1] += 2.1
-      self.assertTrue(sf._HasMovedFast(moved, prev_corners))
-
-    def testPointConnectsToCorners(self):
-      sf = self._GetScreenFinder(None)
-      line1 = np.asfarray(((0, 0, 1, 0)))
-      line2 = np.asfarray(((0, 0, 0, 1)))
-      point = np.asfarray((0, 0))
-      point_info = (point, line1, line2)
-      corners = np.asfarray(((1, 0), (0, 1)))
-      self.assertFalse(sf._PointConnectsToCorners(corners, point_info, 1))
-      corners = np.append(corners, (100, 1))
-      corners = np.append(corners, (1, 100))
-      corners = corners.reshape(-1, 2)
-      self.assertTrue(sf._PointConnectsToCorners(corners, point_info, 2))
-      self.assertFalse(sf._PointConnectsToCorners(corners, point_info, 0.5))
-      corners = np.append(corners, (100, 0))
-      corners = np.append(corners, (0, 100))
-      corners = corners.reshape(-1, 2)
-      self.assertTrue(sf._PointConnectsToCorners(corners, point_info, 0))
-
-    def testFindIntersections(self):
-      def _BuildResult(point, line1, line2):
-        return [point, np.asfarray(line1).tolist(), np.asfarray(line2).tolist()]
-
-      def _IntersectionResultsToList(results):
-        result_list = []
-        for result in results:
-          point, line1, line2 = result
-          p = np.round(point).tolist()
-          l1 = np.round(line1).tolist()
-          l2 = np.round(line2).tolist()
-          result_list.append([p, l1, l2])
-        return result_list
-
-      sf = self._GetScreenFinder(None)
-      expected = []
-      lines = []
-      # Box with corners at (0, 0), (1000, 0), (0, 1000), (1000, 1000)
-      lines.append(np.asfarray(((0, 1001, 0, -1))))
-      lines.append(np.asfarray(((-1, 0, 1001, 0))))
-      lines.append(np.asfarray(((1000, 1001, 1000, -1))))
-      lines.append(np.asfarray(((-1, 1000, 1001, 1000))))
-      expected.append(_BuildResult([0, 0], lines[0], lines[1]))
-      expected.append(_BuildResult([0, 1000], lines[0], lines[3]))
-      expected.append(_BuildResult([1000, 0], lines[1], lines[2]))
-      expected.append(_BuildResult([1000, 1000], lines[2], lines[3]))
-
-      # crosses 2 lines at 45 degrees.
-      lines.append(np.asfarray(((0, 500, 500, 0))))
-      expected.append(_BuildResult([0, 500], lines[0], lines[4]))
-      expected.append(_BuildResult([500, 0], lines[1], lines[4]))
-
-      # crosses 1 line at > 45 degrees, 1 line at < 45 degrees.
-      lines.append(np.asfarray(((0, 400, 600, 0))))
-      expected.append(_BuildResult([0, 400], lines[0], lines[5]))
-
-      # Test without previous corner data, all intersections should be found.
-      results = sf._FindIntersections(lines)
-      result_list = _IntersectionResultsToList(results)
-
-      for e in expected:
-        self.assertIn(e, result_list)
-      self.assertEqual(len(expected), len(result_list))
-
-      # Now introduce previous corners, but also reset conditions. No
-      # intersections should be lost.
-      corners = ((1000, 1000), (0, 1000), (0, 0), (1000, 0))
-      sf._prev_corners = np.asfarray(corners, np.float32)
-      sf._lost_corner_frames = sf.RESET_AFTER_N_BAD_FRAMES + 1
-      results = sf._FindIntersections(lines)
-      result_list = _IntersectionResultsToList(results)
-
-      for e in expected:
-        self.assertIn(e, result_list)
-      self.assertEqual(len(expected), len(result_list))
-
-      # Remove reset conditions, so intersections not near corners will be lost.
-      sf._lost_corner_frames = sf.RESET_AFTER_N_BAD_FRAMES
-      # First 4 intersections are the ones at the old corner locations.
-      expected = expected[0:4]
-      results = sf._FindIntersections(lines)
-      result_list = _IntersectionResultsToList(results)
-
-      for e in expected:
-        self.assertIn(e, result_list)
-      self.assertEqual(len(expected), len(result_list))
-
-    def testPointIsCloseToPreviousCorners(self):
-      sf = self._GetScreenFinder(None)
-      corners = ((1000, 1000), (0, 1000), (0, 0), (1000, 0))
-      sf._prev_corners = np.asfarray(corners, np.float32)
-      dist = math.sqrt(sf.MAX_INTERFRAME_MOTION)
-      sidedist1 = math.sqrt(sf.MAX_INTERFRAME_MOTION) / math.sqrt(2) - (1e-13)
-      sidedist2 = math.sqrt(sf.MAX_INTERFRAME_MOTION) / math.sqrt(2) + (1e-13)
-      point1 = (corners[3][0] + dist, corners[3][1])
-      self.assertTrue(sf._PointIsCloseToPreviousCorners(point1))
-      point2 = (corners[3][0] + sidedist1, corners[3][1] + sidedist1)
-      self.assertTrue(sf._PointIsCloseToPreviousCorners(point2))
-      point3 = (corners[1][0] + sidedist2, corners[1][1] + sidedist2)
-      self.assertFalse(sf._PointIsCloseToPreviousCorners(point3))
-
-    def testLooksLikeCorner(self):
-      # TODO: Probably easier to just do end to end tests.
-      pass
-
-    def testCornerData(self):
-      cd = self.ScreenFinder.CornerData('a', 'b', 'c', 'd', 'e')
-      self.assertEqual(cd.corner_index, 'a')
-      self.assertEqual(cd.corner_location, 'b')
-      self.assertEqual(cd.brightness_score, 'c')
-      self.assertEqual(cd.line1, 'd')
-      self.assertEqual(cd.line2, 'e')
-      cd_list = []
-      cd_list.append(self.ScreenFinder.CornerData(0, None, None, None, None))
-      cd_list.append(self.ScreenFinder.CornerData(3, None, None, None, None))
-      cd_list.append(self.ScreenFinder.CornerData(1, None, None, None, None))
-      cd_list.append(self.ScreenFinder.CornerData(2, None, None, None, None))
-      cd_list.sort()
-      for i in range(len(cd_list)):
-        self.assertEqual(i, cd_list[i].corner_index)
-
-    def testFindCorners(self):
-      # TODO: Probably easier to just do end to end tests.
-      pass
-
-    def testDeDupCorners(self):
-      sf = self._GetScreenFinder(None)
-      data = []
-      lines = []
-      lines.append(np.asfarray((0, 1001, 0, -1)))
-      lines.append(np.asfarray((-1, 0, 1001, 0)))
-      lines.append(np.asfarray((1000, 1001, 1000, -1)))
-      lines.append(np.asfarray((-1, 1000, 1001, 1000)))
-      lines.append(np.asfarray((0, 10, 10, 0)))
-      lines.append(np.asfarray((-1, 1001, 1001, 1001)))
-      corners = np.asfarray(((1000, 1000), (0, 1000), (0, 0),
-                             (1000, 0), (0, 10), (10, 0), (1000, 1001)))
-      data.append(self.ScreenFinder.CornerData(2, corners[2], 100,
-                                               lines[0], lines[1]))
-      data.append(self.ScreenFinder.CornerData(1, corners[1], 100,
-                                               lines[0], lines[3]))
-      data.append(self.ScreenFinder.CornerData(3, corners[3], 100,
-                                               lines[1], lines[2]))
-      data.append(self.ScreenFinder.CornerData(0, corners[0], 100,
-                                               lines[2], lines[3]))
-      data.append(self.ScreenFinder.CornerData(2, corners[4], 120,
-                                               lines[0], lines[4]))
-      data.append(self.ScreenFinder.CornerData(2, corners[5], 110,
-                                               lines[1], lines[4]))
-      data.append(self.ScreenFinder.CornerData(0, corners[6], 110,
-                                               lines[2], lines[5]))
-      dedup = copy.copy(data)
-      # Tests 2 non-duplicate corners, 1 corner with connected and unconnected
-      # corners, and 1 corner with two connected corners.
-      sf._DeDupCorners(dedup, corners)
-      self.assertEqual(len(dedup), 4)
-      self.assertIn(data[0], dedup)
-      self.assertIn(data[1], dedup)
-      self.assertIn(data[2], dedup)
-      self.assertIn(data[6], dedup)
-
-      # Same test, but this time the corner with connected and unconnected
-      # corners now only contains unconnected corners.
-      del data[0]
-      corners = np.delete(corners, 2, axis=0)
-      dedup2 = copy.copy(data)
-      sf._DeDupCorners(dedup2, corners)
-      self.assertEqual(len(dedup2), 4)
-      self.assertIn(data[3], dedup2)
-      self.assertIn(data[0], dedup2)
-      self.assertIn(data[1], dedup2)
-      self.assertIn(data[5], dedup2)
-
-    def testFindExactCorners(self):
-      sf = self._GetScreenFinder(None)
-      img = np.zeros((3, 3), np.uint8)
-      img[1][0] = 255
-      img[0][1] = 255
-      img[1][2] = 255
-      img[2][1] = 255
-      sf._frame_edges = img
-      corners = np.asfarray([(1, 1), (1, 1), (1, 1), (1, 1)])
-      expected = np.asfarray([(2, 0), (0, 0), (0, 2), (2, 2)])
-      ret = sf._FindExactCorners(corners)
-      np.testing.assert_equal(ret, expected)
-      img2 = np.zeros((3, 3), np.uint8)
-      img2[1][0] = 255
-      img2[1][1] = 255
-      img2[2][2] = 255
-      img2[2][1] = 255
-      sf._frame_edges = img2
-      expected2 = [(2, 1), (0, 1), (0, 2), (2, 2)]
-      ret2 = sf._FindExactCorners(corners)
-      np.testing.assert_equal(ret2, expected2)
-
-    def testSmoothCorners(self):
-      sf = self._GetScreenFinder(None)
-      corners = [[10, 10], [10, 10], [10, 10], [10, 10]]
-      ret = sf._SmoothCorners(corners).tolist()
-      self.assertListEqual(ret, corners)
-      corners = [[0, 0], [0, 0], [0, 0], [0, 0]]
-      expected = [[5, 5], [5, 5], [5, 5], [5, 5]]
-      ret = sf._SmoothCorners(corners).tolist()
-      self.assertListEqual(ret, expected)
-      expected = [[2.5, 2.5], [2.5, 2.5], [2.5, 2.5], [2.5, 2.5]]
-      ret = sf._SmoothCorners(corners).tolist()
-      self.assertListEqual(ret, expected)
-
-    def testGetTransform(self):
-      sf = self._GetScreenFinder(None)
-      corners = np.array([[100, 1000], [0, 1000], [0, 0], [100, 0]], np.float32)
-      transform, w, h = sf._GetTransform(corners, 1)
-      transform = np.round(transform, 2)
-      expected = [[1., 0., 1.], [-0., -1., 1001.], [0., -0., 1.]]
-      self.assertListEqual(transform.tolist(), expected)
-      self.assertEqual(w, 102)
-      self.assertEqual(h, 1002)
-
-      corners = np.array([(200, 2000), (0, 2000), (0, 0), (200, 0)], np.float32)
-      transform, w, h = sf._GetTransform(corners, 5)
-      transform = np.round(transform, 2)
-      expected = [[0.5, 0.0, 5.0], [-0.0, -0.5, 1005.0], [-0.0, 0.0, 1.0]]
-      self.assertListEqual(transform.tolist(), expected)
-      self.assertEqual(w, 110)
-      self.assertEqual(h, 1010)
-
-    def testNewScreenLocation(self):
-      sf = self._GetScreenFinder(None)
-      corners_2 = np.asfarray([[np.nan, np.nan], [0, 1000], [np.nan, np.nan],
-                               [1000, 0]])
-      corners_3 = np.asfarray([[1000, 1000], [0, 1000], [np.nan, np.nan],
-                               [1000, 0]])
-      corners_4 = np.asfarray([[1000, 1000], [0, 1000], [0, 0], [1000, 0]])
-      lines = []
-      # Box with corners at (0, 0), (1000, 0), (0, 1000), (1000, 1000)
-      lines.append(np.asfarray(((0, 1001, 0, -1))))
-      lines.append(np.asfarray(((-1, 0, 1001, 0))))
-      lines.append(np.asfarray(((1000, 1001, 1000, -1))))
-      lines.append(np.asfarray(((-1, 1000, 1001, 1000))))
-      # Additional intersections near a corner.
-      lines.append(np.asfarray(((0, 3, 7, 0))))
-      lines.append(np.asfarray(((0, 4, 6, 0))))
-      intersections = sf._FindIntersections(lines)
-      failed = False
-      try:
-        sf._NewScreenLocation(corners_3, 1, intersections)
-      except self.ScreenFinder.ScreenNotFoundError:
-        failed = True
-      self.assertTrue(failed)
-
-      sf._lost_corner_frames = 10
-      sf._lost_corners = [True, True, True, True]
-      ret = sf._NewScreenLocation(corners_4, 0, intersections)
-      np.testing.assert_equal(ret, corners_4)
-      self.assertListEqual(sf._lost_corners, [False, False, False, False])
-      self.assertEqual(sf._lost_corner_frames, 0)
-
-      sf._prev_corners = corners_4
-      ret = sf._NewScreenLocation(corners_3, 1, intersections)
-      ret = np.round(ret)
-      np.testing.assert_equal(ret, corners_4)
-      self.assertListEqual(sf._lost_corners, [False, False, True, False])
-      self.assertEqual(sf._lost_corner_frames, 1)
-
-      sf._prev_corners = np.asfarray([(1000, 1000), (0, 1000),
-                                      (0, 3), (1000, 0)])
-      ret = sf._NewScreenLocation(corners_3, 1, intersections)
-      ret = np.round(ret)
-      np.testing.assert_equal(ret, corners_4)
-      self.assertListEqual(sf._lost_corners, [False, False, True, False])
-      self.assertEqual(sf._lost_corner_frames, 2)
-
-      ret = sf._NewScreenLocation(corners_2, 2, intersections)
-      ret = np.round(ret)
-      expected = [[1000, 1000], [0, 1000], [0, 3], [1000, 0]]
-      np.testing.assert_equal(ret, expected)
-      self.assertListEqual(sf._lost_corners, [True, False, True, False])
-      self.assertEqual(sf._lost_corner_frames, 3)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/video.py b/catapult/telemetry/telemetry/internal/image_processing/video.py
deleted file mode 100644
index 06fc9ca..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/video.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import subprocess
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.core import platform
-from telemetry.util import image_util
-from telemetry.util import rgba_color
-
-HIGHLIGHT_ORANGE_FRAME = rgba_color.WEB_PAGE_TEST_ORANGE
-
-class BoundingBoxNotFoundException(Exception):
-  pass
-
-
-class Video(object):
-  """Utilities for storing and interacting with the video capture."""
-
-  def __init__(self, video_file_obj):
-    assert video_file_obj.delete
-    assert not video_file_obj.close_called
-    self._video_file_obj = video_file_obj
-    self._tab_contents_bounding_box = None
-
-  def UploadToCloudStorage(self, bucket, target_path):
-    """Uploads video file to cloud storage.
-
-    Args:
-      target_path: Path indicating where to store the file in cloud storage.
-    """
-    cloud_storage.Insert(bucket, target_path, self._video_file_obj.name)
-
-  def GetVideoFrameIter(self):
-    """Returns the iteration for processing the video capture.
-
-    This looks for the initial color flash in the first frame to establish the
-    tab content boundaries and then omits all frames displaying the flash.
-
-    Yields:
-      (time_ms, image) tuples representing each video keyframe. Only the first
-      frame is a run of sequential duplicate bitmaps is typically included.
-        time_ms is milliseconds since navigationStart.
-        image may be a telemetry.core.Bitmap, or a numpy array depending on
-        whether numpy is installed.
-    """
-    frame_generator = self._FramesFromMp4(self._video_file_obj.name)
-
-    # Flip through frames until we find the initial tab contents flash.
-    content_box = None
-    for _, bmp in frame_generator:
-      content_box = self._FindHighlightBoundingBox(
-          bmp, HIGHLIGHT_ORANGE_FRAME)
-      if content_box:
-        break
-
-    if not content_box:
-      raise BoundingBoxNotFoundException(
-          'Failed to identify tab contents in video capture.')
-
-    # Flip through frames until the flash goes away and emit that as frame 0.
-    timestamp = 0
-    for timestamp, bmp in frame_generator:
-      if not self._FindHighlightBoundingBox(bmp, HIGHLIGHT_ORANGE_FRAME):
-        yield 0, image_util.Crop(bmp, *content_box)
-        break
-
-    start_time = timestamp
-    for timestamp, bmp in frame_generator:
-      yield timestamp - start_time, image_util.Crop(bmp, *content_box)
-
-  def _FindHighlightBoundingBox(self, bmp, color, bounds_tolerance=8,
-                                color_tolerance=8):
-    """Returns the bounding box of the content highlight of the given color.
-
-    Raises:
-      BoundingBoxNotFoundException if the hightlight could not be found.
-    """
-    content_box, pixel_count = image_util.GetBoundingBox(bmp, color,
-        tolerance=color_tolerance)
-
-    if not content_box:
-      return None
-
-    # We assume arbitrarily that tabs are all larger than 200x200. If this
-    # fails it either means that assumption has changed or something is
-    # awry with our bounding box calculation.
-    if content_box[2] < 200 or content_box[3] < 200:
-      raise BoundingBoxNotFoundException('Unexpectedly small tab contents.')
-
-    # TODO(tonyg): Can this threshold be increased?
-    if pixel_count < 0.9 * content_box[2] * content_box[3]:
-      raise BoundingBoxNotFoundException(
-          'Low count of pixels in tab contents matching expected color.')
-
-    # Since we allow some fuzziness in bounding box finding, we want to make
-    # sure that the bounds are always stable across a run. So we cache the
-    # first box, whatever it may be.
-    #
-    # This relies on the assumption that since Telemetry doesn't know how to
-    # resize the window, we should always get the same content box for a tab.
-    # If this assumption changes, this caching needs to be reworked.
-    if not self._tab_contents_bounding_box:
-      self._tab_contents_bounding_box = content_box
-
-    # Verify that there is only minor variation in the bounding box. If it's
-    # just a few pixels, we can assume it's due to compression artifacts.
-    for x, y in zip(self._tab_contents_bounding_box, content_box):
-      if abs(x - y) > bounds_tolerance:
-        # If this fails, it means either that either the above assumption has
-        # changed or something is awry with our bounding box calculation.
-        raise BoundingBoxNotFoundException(
-            'Unexpected change in tab contents box.')
-
-    return self._tab_contents_bounding_box
-
-  def _FramesFromMp4(self, mp4_file):
-    host_platform = platform.GetHostPlatform()
-    if not host_platform.CanLaunchApplication('avconv'):
-      host_platform.InstallApplication('avconv')
-
-    def GetDimensions(video):
-      proc = subprocess.Popen(['avconv', '-i', video], stderr=subprocess.PIPE)
-      dimensions = None
-      output = ''
-      for line in proc.stderr.readlines():
-        output += line
-        if 'Video:' in line:
-          dimensions = line.split(',')[2]
-          dimensions = map(int, dimensions.split()[0].split('x'))
-          break
-      proc.communicate()
-      assert dimensions, ('Failed to determine video dimensions. output=%s' %
-                          output)
-      return dimensions
-
-    def GetFrameTimestampMs(stderr):
-      """Returns the frame timestamp in integer milliseconds from the dump log.
-
-      The expected line format is:
-      '  dts=1.715  pts=1.715\n'
-
-      We have to be careful to only read a single timestamp per call to avoid
-      deadlock because avconv interleaves its writes to stdout and stderr.
-      """
-      while True:
-        line = ''
-        next_char = ''
-        while next_char != '\n':
-          next_char = stderr.read(1)
-          line += next_char
-        if 'pts=' in line:
-          return int(1000 * float(line.split('=')[-1]))
-
-    dimensions = GetDimensions(mp4_file)
-    frame_length = dimensions[0] * dimensions[1] * 3
-    frame_data = bytearray(frame_length)
-
-    # Use rawvideo so that we don't need any external library to parse frames.
-    proc = subprocess.Popen(['avconv', '-i', mp4_file, '-vcodec',
-                             'rawvideo', '-pix_fmt', 'rgb24', '-dump',
-                             '-loglevel', 'debug', '-f', 'rawvideo', '-'],
-                            stderr=subprocess.PIPE, stdout=subprocess.PIPE)
-    while True:
-      num_read = proc.stdout.readinto(frame_data)
-      if not num_read:
-        raise StopIteration
-      assert num_read == len(frame_data), 'Unexpected frame size: %d' % num_read
-      yield (GetFrameTimestampMs(proc.stderr),
-             image_util.FromRGBPixels(dimensions[0], dimensions[1], frame_data))
diff --git a/catapult/telemetry/telemetry/internal/image_processing/video_file_frame_generator.py b/catapult/telemetry/telemetry/internal/image_processing/video_file_frame_generator.py
deleted file mode 100644
index dc209b4..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/video_file_frame_generator.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.image_processing import frame_generator
-from telemetry.internal.util import external_modules
-
-cv2 = external_modules.ImportRequiredModule('cv2')
-
-
-class VideoFileFrameGenerator(frame_generator.FrameGenerator):
-  """Provides a Frame Generator for a video file.
-
-  Sample Usage:
-    generator = VideoFileFrameGenerator(sys.argv[1]).GetGenerator()
-    for frame in generator:
-      # Do something
-
-  Attributes:
-    _capture: The openCV video capture.
-    _frame_count: The number of frames in the video capture.
-    _frame_index: The frame number of the current frame.
-    _timestamp: The timestamp of the current frame.
-    _dimensions: The dimensions of the video capture."""
-  def __init__(self, video_filename, start_frame_index=0):
-    """Initializes the VideoFileFrameGenerator object.
-
-    Args:
-      video_filename: str, The path to the video file.
-      start_frame_index: int, The number of frames to skip at the start of the
-          file.
-
-    Raises:
-      FrameReadError: A read error occurred during initialization."""
-    self._capture = cv2.VideoCapture(video_filename)
-    self._frame_count = int(self._capture.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT))
-    self._frame_index = -1
-    self._timestamp = 0
-    width = self._capture.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)
-    height = self._capture.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)
-    self._dimensions = (int(width), int(height))
-    if self._frame_count <= start_frame_index:
-      raise frame_generator.FrameReadError('Not enough frames in capture.')
-    while self._frame_index < start_frame_index - 1:
-      self._ReadFrame(True)
-
-    super(self.__class__, self).__init__()
-
-  def _ReadFrame(self, skip_decode=False):
-    """Reads the next frame, updates attributes.
-
-    Args:
-      skip_decode: Whether or not to skip decoding. Useful for seeking.
-
-    Returns:
-      The frame if not EOF, 'None' if EOF.
-
-    Raises:
-      FrameReadError: Unexpectedly failed to read a frame from the capture."""
-    if self._frame_index >= self._frame_count - 1:
-      return None
-    self._timestamp = self._capture.get(cv2.cv.CV_CAP_PROP_POS_MSEC)
-    if skip_decode:
-      ret = self._capture.grab()
-      frame = None
-    else:
-      ret, frame = self._capture.read()
-    if not ret:
-      raise frame_generator.FrameReadError(
-          'Failed to read frame from capture.')
-    self._frame_index += 1
-    return frame
-
-  # OVERRIDE
-  def _CreateGenerator(self):
-    while True:
-      frame = self._ReadFrame()
-      if frame is None:
-        break
-      yield frame
-
-  # OVERRIDE
-  @property
-  def CurrentTimestamp(self):
-    return self._timestamp
-
-  # OVERRIDE
-  @property
-  def CurrentFrameNumber(self):
-    return self._frame_index
-
-  # OVERRIDE
-  @property
-  def Dimensions(self):
-    return self._dimensions
diff --git a/catapult/telemetry/telemetry/internal/image_processing/video_file_frame_generator_unittest.py b/catapult/telemetry/telemetry/internal/image_processing/video_file_frame_generator_unittest.py
deleted file mode 100644
index 72632a2..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/video_file_frame_generator_unittest.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry.core import util
-from telemetry.internal.image_processing import frame_generator
-from telemetry.internal.util import external_modules
-
-try:
-  cv2 = external_modules.ImportRequiredModule('cv2')
-except (ImportError, NotImplementedError):
-  pass
-else:
-  class VideoFileFrameGeneratorTest(unittest.TestCase):
-    def __init__(self, *args, **kwargs):
-      super(VideoFileFrameGeneratorTest, self).__init__(*args, **kwargs)
-      # Import modules with dependencies that may not be preset in test setup so
-      # that importing this unit test doesn't cause the test runner to raise an
-      # exception.
-      from telemetry.internal.image_processing import video_file_frame_generator
-      self.VideoFileFrameGenerator = \
-          video_file_frame_generator.VideoFileFrameGenerator
-
-    def testVideoFileFrameGeneratorSuccess(self):
-      vid = os.path.join(util.GetUnittestDataDir(), 'screen_3_frames.mov')
-      fg = self.VideoFileFrameGenerator(vid)
-      timestamps = [0, 33.367, 66.733]
-      self.assertTrue(isinstance(fg, frame_generator.FrameGenerator))
-
-      self.assertEqual(fg.CurrentFrameNumber, -1)
-      self.assertAlmostEqual(fg.CurrentTimestamp, 0, 3)
-      self.assertEqual(fg.Dimensions, (432, 320))
-      generator = fg.Generator
-      i = 0
-      for frame in generator:
-        self.assertEqual(fg.CurrentFrameNumber, i)
-        self.assertAlmostEqual(fg.CurrentTimestamp, timestamps[i], 3)
-        self.assertEqual(fg.Dimensions, (432, 320))
-        self.assertEqual(frame.shape[:2], (320, 432))
-        i += 1
-      self.assertEqual(i, 3)
-      try:
-        next(generator)
-        stopped = False
-      except StopIteration:
-        stopped = True
-      self.assertTrue(stopped)
-      try:
-        next(fg.Generator)
-        stopped = False
-      except StopIteration:
-        stopped = True
-      self.assertTrue(stopped)
-
-    def testVideoFileFrameGeneratorSkipFrames(self):
-      vid = os.path.join(util.GetUnittestDataDir(), 'screen_3_frames.mov')
-      fg = self.VideoFileFrameGenerator(vid, 2)
-      self.assertEqual(fg.CurrentFrameNumber, 1)
-      self.assertAlmostEqual(fg.CurrentTimestamp, 33.367, 3)
-      self.assertEqual(fg.Dimensions, (432, 320))
-      next(fg.Generator)
-      try:
-        next(fg.Generator)
-        stopped = False
-      except StopIteration:
-        stopped = True
-      self.assertTrue(stopped)
-
-    def testVideoFileFrameGeneratorFailure(self):
-      vid = os.path.join(util.GetUnittestDataDir(), 'screen_3_frames.mov')
-      try:
-        self.VideoFileFrameGenerator(vid, 4)
-        fail = False
-      except frame_generator.FrameReadError:
-        fail = True
-      self.assertTrue(fail)
-
-      try:
-        self.VideoFileFrameGenerator('not_a_file', 0)
-        fail = False
-      except frame_generator.FrameReadError:
-        fail = True
-      self.assertTrue(fail)
diff --git a/catapult/telemetry/telemetry/internal/image_processing/video_unittest.py b/catapult/telemetry/telemetry/internal/image_processing/video_unittest.py
deleted file mode 100644
index 0f83ff5..0000000
--- a/catapult/telemetry/telemetry/internal/image_processing/video_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import unittest
-
-from telemetry.core import platform
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.image_processing import video
-from telemetry.util import image_util
-
-
-class VideoTest(unittest.TestCase):
-
-  @decorators.Disabled('all')
-  def testFramesFromMp4(self):
-    host_platform = platform.GetHostPlatform()
-
-    try:
-      host_platform.InstallApplication('avconv')
-    finally:
-      if not host_platform.CanLaunchApplication('avconv'):
-        logging.warning('Test not supported on this platform')
-        return  # pylint: disable=lost-exception
-
-    vid = os.path.join(util.GetUnittestDataDir(), 'vid.mp4')
-    expected_timestamps = [
-      0,
-      763,
-      783,
-      940,
-      1715,
-      1732,
-      1842,
-      1926,
-      ]
-
-    video_obj = video.Video(vid)
-
-    # Calling _FramesFromMp4 should return all frames.
-    # pylint: disable=protected-access
-    for i, timestamp_bitmap in enumerate(video_obj._FramesFromMp4(vid)):
-      timestamp, bmp = timestamp_bitmap
-      self.assertEquals(timestamp, expected_timestamps[i])
-      expected_bitmap = image_util.FromPngFile(os.path.join(
-          util.GetUnittestDataDir(), 'frame%d.png' % i))
-      self.assertTrue(image_util.AreEqual(expected_bitmap, bmp))
diff --git a/catapult/telemetry/telemetry/internal/platform/__init__.py b/catapult/telemetry/telemetry/internal/platform/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/platform/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/platform/android_device.py b/catapult/telemetry/telemetry/internal/platform/android_device.py
deleted file mode 100644
index 3afdbd2..0000000
--- a/catapult/telemetry/telemetry/internal/platform/android_device.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-
-from telemetry.internal.platform import cros_device
-from telemetry.internal.platform import device
-from telemetry.internal.platform.profiler import monsoon
-
-from devil.android import device_blacklist
-from devil.android import device_errors
-from devil.android import device_utils
-from devil.android.sdk import adb_wrapper
-
-import py_utils
-
-class AndroidDevice(device.Device):
-  """ Class represents information for connecting to an android device.
-
-  Attributes:
-    device_id: the device's serial string created by adb to uniquely
-      identify an emulator/device instance. This string can be found by running
-      'adb devices' command
-    enable_performance_mode: when this is set to True, android platform will be
-    set to high performance mode after browser is started.
-  """
-  def __init__(self, device_id, enable_performance_mode=True):
-    super(AndroidDevice, self).__init__(
-        name='Android device %s' % device_id, guid=device_id)
-    self._device_id = device_id
-    self._enable_performance_mode = enable_performance_mode
-
-  @classmethod
-  def GetAllConnectedDevices(cls, blacklist):
-    device_serials = GetDeviceSerials(blacklist)
-    return [cls(s) for s in device_serials]
-
-  @property
-  def device_id(self):
-    return self._device_id
-
-  @property
-  def enable_performance_mode(self):
-    return self._enable_performance_mode
-
-
-def _ListSerialsOfHealthyOnlineDevices(blacklist):
-  return [d.adb.GetDeviceSerial()
-          for d in device_utils.DeviceUtils.HealthyDevices(blacklist)]
-
-
-def GetDeviceSerials(blacklist):
-  """Return the list of device serials of healthy devices.
-
-  If a preferred device has been set with ANDROID_SERIAL, it will be first in
-  the returned list. The arguments specify what devices to include in the list.
-  """
-
-  device_serials = _ListSerialsOfHealthyOnlineDevices(blacklist)
-
-  # The monsoon provides power for the device, so for devices with no
-  # real battery, we need to turn them on after the monsoon enables voltage
-  # output to the device.
-  if not device_serials:
-    try:
-      m = monsoon.Monsoon(wait=False)
-      m.SetUsbPassthrough(1)
-      m.SetVoltage(3.8)
-      m.SetMaxCurrent(8)
-      logging.warn("""
-Monsoon power monitor detected, but no Android devices.
-
-The Monsoon's power output has been enabled. Please now ensure that:
-
-  1. The Monsoon's front and back USB are connected to the host.
-  2. The device is connected to the Monsoon's main and USB channels.
-  3. The device is turned on.
-
-Waiting for device...
-""")
-      py_utils.WaitFor(_ListSerialsOfHealthyOnlineDevices(blacklist), 600)
-      device_serials = _ListSerialsOfHealthyOnlineDevices(blacklist)
-    except IOError:
-      return []
-
-  preferred_device = os.environ.get('ANDROID_SERIAL')
-  if preferred_device in device_serials:
-    logging.warn(
-        'ANDROID_SERIAL is defined. Put %s in the first of the'
-        'discovered devices list.' % preferred_device)
-    device_serials.remove(preferred_device)
-    device_serials.insert(0, preferred_device)
-  return device_serials
-
-
-def GetDevice(finder_options):
-  """Return a Platform instance for the device specified by |finder_options|."""
-  android_platform_options = finder_options.remote_platform_options
-  if not CanDiscoverDevices():
-    logging.info(
-        'No adb command found. Will not try searching for Android browsers.')
-    return None
-
-  if android_platform_options.android_blacklist_file:
-    blacklist = device_blacklist.Blacklist(
-        android_platform_options.android_blacklist_file)
-  else:
-    blacklist = None
-
-  if (android_platform_options.device
-      and android_platform_options.device in GetDeviceSerials(blacklist)):
-    return AndroidDevice(
-        android_platform_options.device,
-        enable_performance_mode=not finder_options.no_performance_mode)
-
-  devices = AndroidDevice.GetAllConnectedDevices(blacklist)
-  if len(devices) == 0:
-    logging.warn('No android devices found.')
-    return None
-  if len(devices) > 1:
-    logging.warn(
-        'Multiple devices attached. Please specify one of the following:\n' +
-        '\n'.join(['  --device=%s' % d.device_id for d in devices]))
-    return None
-  return devices[0]
-
-
-def _HasValidAdb():
-  """Returns true if adb is present.
-
-  Note that this currently will return True even if the adb that's present
-  cannot run on this system.
-  """
-  if os.name != 'posix' or cros_device.IsRunningOnCrOS():
-    return False
-
-  try:
-    adb_path = adb_wrapper.AdbWrapper.GetAdbPath()
-  except device_errors.NoAdbError:
-    return False
-
-  if os.path.isabs(adb_path) and not os.path.exists(adb_path):
-    return False
-
-  return True
-
-
-def CanDiscoverDevices():
-  """Returns true if devices are discoverable via adb."""
-  if not _HasValidAdb():
-    return False
-
-  try:
-    device_utils.DeviceUtils.HealthyDevices(None)
-    return True
-  except (device_errors.CommandFailedError, device_errors.CommandTimeoutError,
-          device_errors.NoAdbError, OSError):
-    return False
-
-
-def FindAllAvailableDevices(options):
-  """Returns a list of available devices.
-  """
-  # Disable Android device discovery when remote testing a CrOS device
-  if options.cros_remote:
-    return []
-
-  android_platform_options = options.remote_platform_options
-  devices = []
-  try:
-    if CanDiscoverDevices():
-      blacklist = None
-      if android_platform_options.android_blacklist_file:
-        blacklist = device_blacklist.Blacklist(
-            android_platform_options.android_blacklist_file)
-      devices = AndroidDevice.GetAllConnectedDevices(blacklist)
-  finally:
-    if not devices and _HasValidAdb():
-      try:
-        adb_wrapper.AdbWrapper.KillServer()
-      except device_errors.NoAdbError as e:
-        logging.warning(
-            'adb reported as present, but NoAdbError thrown: %s', str(e))
-
-  return devices
diff --git a/catapult/telemetry/telemetry/internal/platform/android_device_unittest.py b/catapult/telemetry/telemetry/internal/platform/android_device_unittest.py
deleted file mode 100644
index ac09935..0000000
--- a/catapult/telemetry/telemetry/internal/platform/android_device_unittest.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.browser import browser_options
-from telemetry.internal.platform import android_device
-from telemetry.internal.platform import remote_platform_options
-from telemetry.testing import system_stub
-import mock
-
-from devil.android import device_utils
-from devil.android import device_blacklist
-
-
-class _BaseAndroidDeviceTest(unittest.TestCase):
-  def setUp(self):
-    def check_blacklist_arg(blacklist):
-      self.assertTrue(blacklist is None
-                      or isinstance(blacklist, device_blacklist.Blacklist))
-      return mock.DEFAULT
-
-    self._healthy_device_patcher = mock.patch(
-        'devil.android.device_utils.DeviceUtils.HealthyDevices')
-    self._healthy_device_mock = self._healthy_device_patcher.start()
-    self._healthy_device_mock.side_effect = check_blacklist_arg
-    self._android_device_stub = system_stub.Override(
-        android_device, ['subprocess', 'logging'])
-
-  def _GetMockDeviceUtils(self, device_serial):
-    device = device_utils.DeviceUtils(device_serial)
-    return device
-
-  def tearDown(self):
-    self._healthy_device_patcher.stop()
-    self._android_device_stub.Restore()
-
-
-class AndroidDeviceTest(_BaseAndroidDeviceTest):
-  @decorators.Enabled('android')
-  def testGetAllAttachedAndroidDevices(self):
-    self._healthy_device_mock.return_value = [
-        self._GetMockDeviceUtils('01'),
-        self._GetMockDeviceUtils('02')]
-    self.assertEquals(
-        set(['01', '02']),
-        set(device.device_id for device in
-            android_device.AndroidDevice.GetAllConnectedDevices(None)))
-
-  @decorators.Enabled('android')
-  def testNoAdbReturnsNone(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with (
-        mock.patch('os.path.isabs', return_value=True)), (
-        mock.patch('os.path.exists', return_value=False)):
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertIsNone(android_device.GetDevice(finder_options))
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testAdbNoDevicesReturnsNone(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = []
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertIsNone(android_device.GetDevice(finder_options))
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testAdbTwoDevicesReturnsNone(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = [
-          self._GetMockDeviceUtils('015d14fec128220c'),
-          self._GetMockDeviceUtils('015d14fec128220d')]
-      device = android_device.GetDevice(finder_options)
-      self.assertEquals([
-          'Multiple devices attached. Please specify one of the following:\n'
-          '  --device=015d14fec128220c\n'
-          '  --device=015d14fec128220d'],
-          self._android_device_stub.logging.warnings)
-      self.assertIsNone(device)
-
-  @decorators.Enabled('android')
-  def testAdbPickOneDeviceReturnsDeviceInstance(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    platform_options = remote_platform_options.AndroidPlatformOptions(
-        device='555d14fecddddddd')  # pick one
-    finder_options.remote_platform_options = platform_options
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = [
-          self._GetMockDeviceUtils('015d14fec128220c'),
-          self._GetMockDeviceUtils('555d14fecddddddd')]
-      device = android_device.GetDevice(finder_options)
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertEquals('555d14fecddddddd', device.device_id)
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testAdbOneDeviceReturnsDeviceInstance(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = [
-          self._GetMockDeviceUtils('015d14fec128220c')]
-      device = android_device.GetDevice(finder_options)
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertEquals('015d14fec128220c', device.device_id)
-
-
-class FindAllAvailableDevicesTest(_BaseAndroidDeviceTest):
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testAdbNoDeviceReturnsEmptyList(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = []
-      devices = android_device.FindAllAvailableDevices(finder_options)
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertIsNotNone(devices)
-      self.assertEquals(len(devices), 0)
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testAdbOneDeviceReturnsListWithOneDeviceInstance(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = [
-          self._GetMockDeviceUtils('015d14fec128220c')]
-      devices = android_device.FindAllAvailableDevices(finder_options)
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertIsNotNone(devices)
-      self.assertEquals(len(devices), 1)
-      self.assertEquals('015d14fec128220c', devices[0].device_id)
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testAdbMultipleDevicesReturnsListWithAllDeviceInstances(self):
-    finder_options = browser_options.BrowserFinderOptions()
-    with mock.patch('os.path.isabs', return_value=False):
-      self._healthy_device_mock.return_value = [
-          self._GetMockDeviceUtils('015d14fec128220c'),
-          self._GetMockDeviceUtils('015d14fec128220d'),
-          self._GetMockDeviceUtils('015d14fec128220e')]
-      devices = android_device.FindAllAvailableDevices(finder_options)
-      self.assertEquals([], self._android_device_stub.logging.warnings)
-      self.assertIsNotNone(devices)
-      self.assertEquals(len(devices), 3)
-      self.assertEquals(devices[0].guid, '015d14fec128220c')
-      self.assertEquals(devices[1].guid, '015d14fec128220d')
-      self.assertEquals(devices[2].guid, '015d14fec128220e')
diff --git a/catapult/telemetry/telemetry/internal/platform/android_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/android_platform_backend.py
deleted file mode 100644
index 37cded3..0000000
--- a/catapult/telemetry/telemetry/internal/platform/android_platform_backend.py
+++ /dev/null
@@ -1,834 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import posixpath
-import re
-import subprocess
-import tempfile
-
-from battor import battor_wrapper
-from telemetry.core import android_platform
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal import forwarders
-from telemetry.internal.forwarders import android_forwarder
-from telemetry.internal.image_processing import video
-from telemetry.internal.platform import android_device
-from telemetry.internal.platform import linux_based_platform_backend
-from telemetry.internal.platform.power_monitor import android_dumpsys_power_monitor
-from telemetry.internal.platform.power_monitor import android_fuelgauge_power_monitor
-from telemetry.internal.platform.power_monitor import android_temperature_monitor
-from telemetry.internal.platform.power_monitor import monsoon_power_monitor
-from telemetry.internal.platform.power_monitor import (
-  android_power_monitor_controller)
-from telemetry.internal.platform.power_monitor import sysfs_power_monitor
-from telemetry.internal.platform.profiler import android_prebuilt_profiler_helper
-from telemetry.internal.util import binary_manager
-from telemetry.internal.util import external_modules
-
-psutil = external_modules.ImportOptionalModule('psutil')
-import adb_install_cert
-
-from devil.android import app_ui
-from devil.android import battery_utils
-from devil.android import device_errors
-from devil.android import device_utils
-from devil.android.perf import cache_control
-from devil.android.perf import perf_control
-from devil.android.perf import thermal_throttle
-from devil.android.sdk import version_codes
-from devil.android.tools import video_recorder
-
-try:
-  # devil.android.forwarder uses fcntl, which doesn't exist on Windows.
-  from devil.android import forwarder
-except ImportError:
-  forwarder = None
-
-try:
-  from devil.android.perf import surface_stats_collector
-except Exception:
-  surface_stats_collector = None
-
-
-_ARCH_TO_STACK_TOOL_ARCH = {
-  'armeabi-v7a': 'arm',
-  'arm64-v8a': 'arm64',
-}
-_DEVICE_COPY_SCRIPT_FILE = os.path.abspath(os.path.join(
-    os.path.dirname(__file__), 'efficient_android_directory_copy.sh'))
-_DEVICE_COPY_SCRIPT_LOCATION = (
-    '/data/local/tmp/efficient_android_directory_copy.sh')
-
-# TODO(nednguyen): Remove this method and update the client config to point to
-# the correct binary instead.
-def _FindLocallyBuiltPath(binary_name):
-  """Finds the most recently built |binary_name|."""
-  command = None
-  command_mtime = 0
-  required_mode = os.X_OK
-  if binary_name.endswith('.apk'):
-    required_mode = os.R_OK
-  for build_path in util.GetBuildDirectories():
-    candidate = os.path.join(build_path, binary_name)
-    if os.path.isfile(candidate) and os.access(candidate, required_mode):
-      candidate_mtime = os.stat(candidate).st_mtime
-      if candidate_mtime > command_mtime:
-        command = candidate
-        command_mtime = candidate_mtime
-  return command
-
-
-class AndroidPlatformBackend(
-    linux_based_platform_backend.LinuxBasedPlatformBackend):
-  def __init__(self, device):
-    assert device, (
-        'AndroidPlatformBackend can only be initialized from remote device')
-    super(AndroidPlatformBackend, self).__init__(device)
-    self._device = device_utils.DeviceUtils(device.device_id)
-    # Trying to root the device, if possible.
-    if not self._device.HasRoot():
-      try:
-        self._device.EnableRoot()
-      except device_errors.CommandFailedError:
-        logging.warning('Unable to root %s', str(self._device))
-    self._battery = battery_utils.BatteryUtils(self._device)
-    self._enable_performance_mode = device.enable_performance_mode
-    self._surface_stats_collector = None
-    self._perf_tests_setup = perf_control.PerfControl(self._device)
-    self._thermal_throttle = thermal_throttle.ThermalThrottle(self._device)
-    self._raw_display_frame_rate_measurements = []
-    self._can_elevate_privilege = (
-        self._device.HasRoot() or self._device.NeedsSU())
-    self._device_copy_script = None
-    self._power_monitor = (
-      android_power_monitor_controller.AndroidPowerMonitorController([
-        android_temperature_monitor.AndroidTemperatureMonitor(self._device),
-        monsoon_power_monitor.MonsoonPowerMonitor(self._device, self),
-        android_dumpsys_power_monitor.DumpsysPowerMonitor(
-          self._battery, self),
-        sysfs_power_monitor.SysfsPowerMonitor(self, standalone=True),
-        android_fuelgauge_power_monitor.FuelGaugePowerMonitor(
-            self._battery),
-    ], self._battery))
-    self._video_recorder = None
-    self._installed_applications = None
-
-    self._device_cert_util = None
-    self._system_ui = None
-
-    _FixPossibleAdbInstability()
-
-  @property
-  def log_file_path(self):
-    return None
-
-  @classmethod
-  def SupportsDevice(cls, device):
-    return isinstance(device, android_device.AndroidDevice)
-
-  @classmethod
-  def CreatePlatformForDevice(cls, device, finder_options):
-    assert cls.SupportsDevice(device)
-    platform_backend = AndroidPlatformBackend(device)
-    return android_platform.AndroidPlatform(platform_backend)
-
-  @property
-  def forwarder_factory(self):
-    if not self._forwarder_factory:
-      self._forwarder_factory = android_forwarder.AndroidForwarderFactory(
-          self._device)
-
-    return self._forwarder_factory
-
-  @property
-  def device(self):
-    return self._device
-
-  def Initialize(self):
-    self.EnsureBackgroundApkInstalled()
-
-  def GetSystemUi(self):
-    if self._system_ui is None:
-      self._system_ui = app_ui.AppUi(self.device, 'com.android.systemui')
-    return self._system_ui
-
-  def IsSvelte(self):
-    description = self._device.GetProp('ro.build.description', cache=True)
-    if description is not None:
-      return 'svelte' in description
-    else:
-      return False
-
-  def GetRemotePort(self, port):
-    return forwarder.Forwarder.DevicePortForHostPort(port) or 0
-
-  def IsDisplayTracingSupported(self):
-    return bool(self.GetOSVersionName() >= 'J')
-
-  def StartDisplayTracing(self):
-    assert not self._surface_stats_collector
-    # Clear any leftover data from previous timed out tests
-    self._raw_display_frame_rate_measurements = []
-    self._surface_stats_collector = \
-        surface_stats_collector.SurfaceStatsCollector(self._device)
-    self._surface_stats_collector.Start()
-
-  def StopDisplayTracing(self):
-    if not self._surface_stats_collector:
-      return
-
-    try:
-      refresh_period, timestamps = self._surface_stats_collector.Stop()
-      pid = self._surface_stats_collector.GetSurfaceFlingerPid()
-    finally:
-      self._surface_stats_collector = None
-    # TODO(sullivan): should this code be inline, or live elsewhere?
-    events = []
-    for ts in timestamps:
-      events.append({
-        'cat': 'SurfaceFlinger',
-        'name': 'vsync_before',
-        'ts': ts,
-        'pid': pid,
-        'tid': pid,
-        'args': {'data': {
-          'frame_count': 1,
-          'refresh_period': refresh_period,
-        }}
-      })
-    return events
-
-  def CanTakeScreenshot(self):
-    return True
-
-  def TakeScreenshot(self, file_path):
-    return bool(self._device.TakeScreenshot(host_path=file_path))
-
-  def SetFullPerformanceModeEnabled(self, enabled):
-    if not self._enable_performance_mode:
-      logging.warning('CPU governor will not be set!')
-      return
-    if enabled:
-      self._perf_tests_setup.SetHighPerfMode()
-    else:
-      self._perf_tests_setup.SetDefaultPerfMode()
-
-  def CanMonitorThermalThrottling(self):
-    return True
-
-  def IsThermallyThrottled(self):
-    return self._thermal_throttle.IsThrottled()
-
-  def HasBeenThermallyThrottled(self):
-    return self._thermal_throttle.HasBeenThrottled()
-
-  def GetCpuStats(self, pid):
-    if not self._can_elevate_privilege:
-      logging.warning('CPU stats cannot be retrieved on non-rooted device.')
-      return {}
-    return super(AndroidPlatformBackend, self).GetCpuStats(pid)
-
-  def GetCpuTimestamp(self):
-    if not self._can_elevate_privilege:
-      logging.warning('CPU timestamp cannot be retrieved on non-rooted device.')
-      return {}
-    return super(AndroidPlatformBackend, self).GetCpuTimestamp()
-
-  def SetGraphicsMemoryTrackingEnabled(self, enabled):
-    if not enabled:
-      self.KillApplication('memtrack_helper')
-      return
-
-    if not android_prebuilt_profiler_helper.InstallOnDevice(
-        self._device, 'memtrack_helper'):
-      raise Exception('Error installing memtrack_helper.')
-    self._device.RunShellCommand([
-      android_prebuilt_profiler_helper.GetDevicePath('memtrack_helper'),
-      '-d'], as_root=True, check_return=True)
-
-  def EnsureBackgroundApkInstalled(self):
-    app = 'push_apps_to_background_apk'
-    arch_name = self._device.GetABI()
-    host_path = binary_manager.FetchPath(app, arch_name, 'android')
-    if not host_path:
-      raise Exception('Error installing PushAppsToBackground.apk.')
-    self.InstallApplication(host_path)
-
-  def PurgeUnpinnedMemory(self):
-    """Purges the unpinned ashmem memory for the whole system.
-
-    This can be used to make memory measurements more stable. Requires root.
-    """
-    if not self._can_elevate_privilege:
-      logging.warning('Cannot run purge_ashmem. Requires a rooted device.')
-      return
-
-    if not android_prebuilt_profiler_helper.InstallOnDevice(
-        self._device, 'purge_ashmem'):
-      raise Exception('Error installing purge_ashmem.')
-    output = self._device.RunShellCommand([
-      android_prebuilt_profiler_helper.GetDevicePath('purge_ashmem')],
-      check_return=True)
-    for l in output:
-      logging.info(l)
-
-  @decorators.Deprecated(
-      2017, 11, 4,
-      'Clients should use tracing and memory-infra in new Telemetry '
-      'benchmarks. See for context: https://crbug.com/632021')
-  def GetMemoryStats(self, pid):
-    memory_usage = self._device.GetMemoryUsageForPid(pid)
-    if not memory_usage:
-      return {}
-    return {'ProportionalSetSize': memory_usage['Pss'] * 1024,
-            'SharedDirty': memory_usage['Shared_Dirty'] * 1024,
-            'PrivateDirty': memory_usage['Private_Dirty'] * 1024,
-            'VMPeak': memory_usage['VmHWM'] * 1024}
-
-  def GetChildPids(self, pid):
-    child_pids = []
-    ps = self.GetPsOutput(['pid', 'name'])
-    for curr_pid, curr_name in ps:
-      if int(curr_pid) == pid:
-        name = curr_name
-        for curr_pid, curr_name in ps:
-          if curr_name.startswith(name) and curr_name != name:
-            child_pids.append(int(curr_pid))
-        break
-    return child_pids
-
-  @decorators.Cache
-  def GetCommandLine(self, pid):
-    ps = self.GetPsOutput(['pid', 'name'], pid)
-    if not ps:
-      raise exceptions.ProcessGoneException()
-    return ps[0][1]
-
-  @decorators.Cache
-  def GetArchName(self):
-    return self._device.GetABI()
-
-  def GetOSName(self):
-    return 'android'
-
-  def GetDeviceTypeName(self):
-    return self._device.product_model
-
-  @decorators.Cache
-  def GetOSVersionName(self):
-    return self._device.GetProp('ro.build.id')[0]
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    return False
-
-  def SupportFlushEntireSystemCache(self):
-    return self._can_elevate_privilege
-
-  def FlushEntireSystemCache(self):
-    cache = cache_control.CacheControl(self._device)
-    cache.DropRamCaches()
-
-  def FlushSystemCacheForDirectory(self, directory):
-    raise NotImplementedError()
-
-  def FlushDnsCache(self):
-    self._device.RunShellCommand(
-        ['ndc', 'resolver', 'flushdefaultif'], as_root=True, check_return=True)
-
-  def StopApplication(self, application):
-    """Stop the given |application|.
-
-    Args:
-       application: The full package name string of the application to stop.
-    """
-    self._device.ForceStop(application)
-
-  def KillApplication(self, application):
-    """Kill the given |application|.
-
-    Might be used instead of ForceStop for efficiency reasons.
-
-    Args:
-      application: The full package name string of the application to kill.
-    """
-    assert isinstance(application, basestring)
-    self._device.KillAll(application, blocking=True, quiet=True)
-
-  def LaunchApplication(
-      self, application, parameters=None, elevate_privilege=False):
-    """Launches the given |application| with a list of |parameters| on the OS.
-
-    Args:
-      application: The full package name string of the application to launch.
-      parameters: A list of parameters to be passed to the ActivityManager.
-      elevate_privilege: Currently unimplemented on Android.
-    """
-    if elevate_privilege:
-      raise NotImplementedError("elevate_privilege isn't supported on android.")
-    # TODO(catapult:#3215): Migrate to StartActivity.
-    cmd = ['am', 'start']
-    if parameters:
-      cmd.extend(parameters)
-    cmd.append(application)
-    result_lines = self._device.RunShellCommand(cmd, check_return=True)
-    for line in result_lines:
-      if line.startswith('Error: '):
-        raise ValueError('Failed to start "%s" with error\n  %s' %
-                         (application, line))
-
-  def IsApplicationRunning(self, application):
-    return len(self._device.GetPids(application)) > 0
-
-  def CanLaunchApplication(self, application):
-    if not self._installed_applications:
-      self._installed_applications = self._device.RunShellCommand(
-          ['pm', 'list', 'packages'], check_return=True)
-    return 'package:' + application in self._installed_applications
-
-  def InstallApplication(self, application):
-    self._installed_applications = None
-    self._device.Install(application)
-
-  @decorators.Cache
-  def CanCaptureVideo(self):
-    return self.GetOSVersionName() >= 'K'
-
-  def StartVideoCapture(self, min_bitrate_mbps):
-    """Starts the video capture at specified bitrate."""
-    min_bitrate_mbps = max(min_bitrate_mbps, 0.1)
-    if min_bitrate_mbps > 100:
-      raise ValueError('Android video capture cannot capture at %dmbps. '
-                       'Max capture rate is 100mbps.' % min_bitrate_mbps)
-    if self.is_video_capture_running:
-      self._video_recorder.Stop()
-    self._video_recorder = video_recorder.VideoRecorder(
-        self._device, megabits_per_second=min_bitrate_mbps)
-    self._video_recorder.Start(timeout=5)
-
-  @property
-  def is_video_capture_running(self):
-    return self._video_recorder is not None
-
-  def StopVideoCapture(self):
-    assert self.is_video_capture_running, 'Must start video capture first'
-    self._video_recorder.Stop()
-    video_file_obj = tempfile.NamedTemporaryFile()
-    self._video_recorder.Pull(video_file_obj.name)
-    self._video_recorder = None
-
-    return video.Video(video_file_obj)
-
-  def CanMonitorPower(self):
-    return self._power_monitor.CanMonitorPower()
-
-  def StartMonitoringPower(self, browser):
-    self._power_monitor.StartMonitoringPower(browser)
-
-  def StopMonitoringPower(self):
-    return self._power_monitor.StopMonitoringPower()
-
-  def CanMonitorNetworkData(self):
-    return self._device.build_version_sdk >= version_codes.LOLLIPOP
-
-  def GetNetworkData(self, browser):
-    return self._battery.GetNetworkData(browser._browser_backend.package)
-
-  def PathExists(self, device_path, timeout=None, retries=None):
-    """ Return whether the given path exists on the device.
-    This method is the same as
-    devil.android.device_utils.DeviceUtils.PathExists.
-    """
-    return self._device.PathExists(
-        device_path, timeout=timeout, retries=retries)
-
-  def GetFileContents(self, fname):
-    if not self._can_elevate_privilege:
-      logging.warning('%s cannot be retrieved on non-rooted device.', fname)
-      return ''
-    return self._device.ReadFile(fname, as_root=True)
-
-  def GetPsOutput(self, columns, pid=None):
-    assert columns == ['pid', 'name'] or columns == ['pid'], \
-        'Only know how to return pid and name. Requested: ' + columns
-    if pid is not None:
-      pid = str(pid)
-    procs_pids = self._device.GetPids()
-    output = []
-    for curr_name, pids_list in procs_pids.iteritems():
-      for curr_pid in pids_list:
-        if columns == ['pid', 'name']:
-          row = [curr_pid, curr_name]
-        else:
-          row = [curr_pid]
-        if pid is not None:
-          if curr_pid == pid:
-            return [row]
-        else:
-          output.append(row)
-    return output
-
-  def RunCommand(self, command):
-    return '\n'.join(self._device.RunShellCommand(command, check_return=True))
-
-  @staticmethod
-  def ParseCStateSample(sample):
-    sample_stats = {}
-    for cpu in sample:
-      values = sample[cpu].splitlines()
-      # Each state has three values after excluding the time value.
-      num_states = (len(values) - 1) / 3
-      names = values[:num_states]
-      times = values[num_states:2 * num_states]
-      cstates = {'C0': int(values[-1]) * 10 ** 6}
-      for i, state in enumerate(names):
-        if state == 'C0':
-          # The Exynos cpuidle driver for the Nexus 10 uses the name 'C0' for
-          # its WFI state.
-          # TODO(tmandel): We should verify that no other Android device
-          # actually reports time in C0 causing this to report active time as
-          # idle time.
-          state = 'WFI'
-        cstates[state] = int(times[i])
-        cstates['C0'] -= int(times[i])
-      sample_stats[cpu] = cstates
-    return sample_stats
-
-  def SetRelaxSslCheck(self, value):
-    old_flag = self._device.GetProp('socket.relaxsslcheck')
-    self._device.SetProp('socket.relaxsslcheck', value)
-    return old_flag
-
-  def ForwardHostToDevice(self, host_port, device_port):
-    self._device.adb.Forward('tcp:%d' % host_port, device_port)
-
-  def StopForwardingHost(self, host_port):
-    # This used to run `adb forward --list` to check that the requested
-    # port was actually being forwarded to self._device. Unfortunately,
-    # starting in adb 1.0.36, a bug (b/31811775) keeps this from working.
-    # For now, try to remove the port forwarding and ignore failures.
-    try:
-      self._device.adb.ForwardRemove('tcp:%d' % host_port)
-    except device_errors.AdbCommandFailedError:
-      logging.critical(
-          'Attempted to unforward port tcp:%d but failed.', host_port)
-
-  def DismissCrashDialogIfNeeded(self):
-    """Dismiss any error dialogs.
-
-    Limit the number in case we have an error loop or we are failing to dismiss.
-    """
-    for _ in xrange(10):
-      if not self._device.DismissCrashDialogIfNeeded():
-        break
-
-  def IsAppRunning(self, process_name):
-    """Determine if the given process is running.
-
-    Args:
-      process_name: The full package name string of the process.
-    """
-    return bool(self._device.GetPids(process_name))
-
-  @property
-  def supports_test_ca(self):
-    # TODO(nednguyen): figure out how to install certificate on Android M
-    # crbug.com/593152
-    return self._device.build_version_sdk <= version_codes.LOLLIPOP_MR1
-
-  def InstallTestCa(self, ca_cert_path):
-    """Install a randomly generated root CA on the android device.
-
-    This allows transparent HTTPS testing with WPR server without need
-    to tweak application network stack.
-
-    Note: If this method fails with any exception, then RemoveTestCa will be
-    automatically called by the network_controller_backend.
-    """
-    if self._device_cert_util is not None:
-      logging.warning('Test certificate authority is already installed.')
-      return
-    self._device_cert_util = adb_install_cert.AndroidCertInstaller(
-        self._device.adb.GetDeviceSerial(), None, ca_cert_path,
-        adb_path=self._device.adb.GetAdbPath())
-    self._device_cert_util.install_cert(overwrite_cert=True)
-
-  def RemoveTestCa(self):
-    """Remove root CA from device installed by InstallTestCa.
-
-    Note: Any exceptions raised by this method will be logged but dismissed by
-    the network_controller_backend.
-    """
-    if self._device_cert_util is not None:
-      try:
-        self._device_cert_util.remove_cert()
-      finally:
-        self._device_cert_util = None
-
-  def PushProfile(self, package, new_profile_dir):
-    """Replace application profile with files found on host machine.
-
-    Pushing the profile is slow, so we don't want to do it every time.
-    Avoid this by pushing to a safe location using PushChangedFiles, and
-    then copying into the correct location on each test run.
-
-    Args:
-      package: The full package name string of the application for which the
-        profile is to be updated.
-      new_profile_dir: Location where profile to be pushed is stored on the
-        host machine.
-    """
-    (profile_parent, profile_base) = os.path.split(new_profile_dir)
-    # If the path ends with a '/' python split will return an empty string for
-    # the base name; so we now need to get the base name from the directory.
-    if not profile_base:
-      profile_base = os.path.basename(profile_parent)
-
-    saved_profile_location = '/sdcard/profile/%s' % profile_base
-    self._device.PushChangedFiles([(new_profile_dir, saved_profile_location)])
-
-    profile_dir = self._GetProfileDir(package)
-    self._EfficientDeviceDirectoryCopy(
-        saved_profile_location, profile_dir)
-    dumpsys = self._device.RunShellCommand(
-        ['dumpsys', 'package', package], check_return=True)
-    id_line = next(line for line in dumpsys if 'userId=' in line)
-    uid = re.search(r'\d+', id_line).group()
-    files = self._device.ListDirectory(profile_dir, as_root=True)
-    paths = [posixpath.join(profile_dir, f) for f in files if f != 'lib']
-    for path in paths:
-      # TODO(crbug.com/628617): Implement without ignoring shell errors.
-      # Note: need to pass command as a string for the shell to expand the *'s.
-      extended_path = '%s %s/* %s/*/* %s/*/*/*' % (path, path, path, path)
-      self._device.RunShellCommand(
-          'chown %s.%s %s' % (uid, uid, extended_path),
-          check_return=False, shell=True)
-
-  def _EfficientDeviceDirectoryCopy(self, source, dest):
-    if not self._device_copy_script:
-      self._device.adb.Push(
-          _DEVICE_COPY_SCRIPT_FILE,
-          _DEVICE_COPY_SCRIPT_LOCATION)
-      self._device_copy_script = _DEVICE_COPY_SCRIPT_LOCATION
-    self._device.RunShellCommand(
-        ['sh', self._device_copy_script, source, dest], check_return=True)
-
-  def GetPortPairForForwarding(self, local_port):
-    return forwarders.PortPair(local_port=local_port, remote_port=0)
-
-  def RemoveProfile(self, package, ignore_list):
-    """Delete application profile on device.
-
-    Args:
-      package: The full package name string of the application for which the
-        profile is to be deleted.
-      ignore_list: List of files to keep.
-    """
-    profile_dir = self._GetProfileDir(package)
-    if not self._device.PathExists(profile_dir):
-      return
-    files = [
-      posixpath.join(profile_dir, f)
-      for f in self._device.ListDirectory(profile_dir, as_root=True)
-      if f not in ignore_list]
-    if not files:
-      return
-    self._device.RemovePath(files, recursive=True, as_root=True)
-
-  def PullProfile(self, package, output_profile_path):
-    """Copy application profile from device to host machine.
-
-    Args:
-      package: The full package name string of the application for which the
-        profile is to be copied.
-      output_profile_dir: Location where profile to be stored on host machine.
-    """
-    profile_dir = self._GetProfileDir(package)
-    logging.info("Pulling profile directory from device: '%s'->'%s'.",
-                 profile_dir, output_profile_path)
-    # To minimize bandwidth it might be good to look at whether all the data
-    # pulled down is really needed e.g. .pak files.
-    if not os.path.exists(output_profile_path):
-      os.makedirs(output_profile_path)
-    problem_files = []
-    for filename in self._device.ListDirectory(profile_dir, as_root=True):
-      # Don't pull lib, since it is created by the installer.
-      if filename == 'lib':
-        continue
-      source = posixpath.join(profile_dir, filename)
-      dest = os.path.join(output_profile_path, filename)
-      try:
-        self._device.PullFile(source, dest, timeout=240)
-      except device_errors.CommandFailedError:
-        problem_files.append(source)
-    if problem_files:
-      # Some paths (e.g. 'files', 'app_textures') consistently fail to be
-      # pulled from the device.
-      logging.warning(
-          'There were errors retrieving the following paths from the profile:')
-      for filepath in problem_files:
-        logging.warning('- %s', filepath)
-
-  def _GetProfileDir(self, package):
-    """Returns the on-device location where the application profile is stored
-    based on Android convention.
-
-    Args:
-      package: The full package name string of the application.
-    """
-    return '/data/data/%s/' % package
-
-  def SetDebugApp(self, package):
-    """Set application to debugging.
-
-    Args:
-      package: The full package name string of the application.
-    """
-    if self._device.IsUserBuild():
-      logging.debug('User build device, setting debug app')
-      self._device.RunShellCommand(
-          ['am', 'set-debug-app', '--persistent', package],
-          check_return=True)
-
-  def GetLogCat(self, number_of_lines=500):
-    """Returns most recent lines of logcat dump.
-
-    Args:
-      number_of_lines: Number of lines of log to return.
-    """
-    def decode_line(line):
-      try:
-        uline = unicode(line, encoding='utf-8')
-        return uline.encode('ascii', 'backslashreplace')
-      except Exception:
-        logging.error('Error encoding UTF-8 logcat line as ASCII.')
-        return '<MISSING LOGCAT LINE: FAILED TO ENCODE>'
-
-    logcat_output = self._device.RunShellCommand(
-        ['logcat', '-d', '-t', str(number_of_lines)],
-        check_return=True, large_output=True)
-    return '\n'.join(decode_line(l) for l in logcat_output)
-
-  def GetStandardOutput(self):
-    return 'Cannot get standard output on Android'
-
-  def GetStackTrace(self):
-    """Returns stack trace.
-
-    The stack trace consists of raw logcat dump, logcat dump with symbols,
-    and stack info from tomstone files.
-    """
-    def Decorate(title, content):
-      return "%s\n%s\n%s\n" % (title, content, '*' * 80)
-
-    # Get the UI nodes that can be found on the screen
-    ret = Decorate('UI dump', '\n'.join(self.GetSystemUi().ScreenDump()))
-
-    # Get the last lines of logcat (large enough to contain stacktrace)
-    logcat = self.GetLogCat()
-    ret += Decorate('Logcat', logcat)
-    stack = os.path.join(util.GetChromiumSrcDir(), 'third_party',
-                         'android_platform', 'development', 'scripts', 'stack')
-    # Try to symbolize logcat.
-    if os.path.exists(stack):
-      cmd = [stack]
-      arch = self.GetArchName()
-      arch = _ARCH_TO_STACK_TOOL_ARCH.get(arch, arch)
-      cmd.append('--arch=%s' % arch)
-      p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-      ret += Decorate('Stack from Logcat', p.communicate(input=logcat)[0])
-
-    # Try to get tombstones.
-    tombstones = os.path.join(util.GetChromiumSrcDir(), 'build', 'android',
-                              'tombstones.py')
-    if os.path.exists(tombstones):
-      tombstones_cmd = [
-          tombstones, '-w',
-          '--device', self._device.adb.GetDeviceSerial(),
-          '--adb-path', self._device.adb.GetAdbPath(),
-      ]
-      ret += Decorate('Tombstones',
-                      subprocess.Popen(tombstones_cmd,
-                                       stdout=subprocess.PIPE).communicate()[0])
-    return (True, ret)
-
-  def GetMinidumpPath(self):
-    return None
-
-  def IsScreenOn(self):
-    """Determines if device screen is on."""
-    return self._device.IsScreenOn()
-
-  @staticmethod
-  def _IsScreenLocked(input_methods):
-    """Parser method for IsScreenLocked()
-
-    Args:
-      input_methods: Output from dumpsys input_methods
-
-    Returns:
-      boolean: True if screen is locked, false if screen is not locked.
-
-    Raises:
-      ValueError: An unknown value is found for the screen lock state.
-      AndroidDeviceParsingError: Error in detecting screen state.
-
-    """
-    for line in input_methods:
-      if 'mHasBeenInactive' in line:
-        for pair in line.strip().split(' '):
-          key, value = pair.split('=', 1)
-          if key == 'mHasBeenInactive':
-            if value == 'true':
-              return True
-            elif value == 'false':
-              return False
-            else:
-              raise ValueError('Unknown value for %s: %s' % (key, value))
-    raise exceptions.AndroidDeviceParsingError(str(input_methods))
-
-  def IsScreenLocked(self):
-    """Determines if device screen is locked."""
-    input_methods = self._device.RunShellCommand(['dumpsys', 'input_method'],
-                                                 check_return=True)
-    return self._IsScreenLocked(input_methods)
-
-  def HasBattOrConnected(self):
-    # Use linux instead of Android because when determining what tests to run on
-    # a bot the individual device could be down, which would make BattOr tests
-    # not run on any device. BattOrs communicate with the host and not android
-    # devices.
-    return battor_wrapper.IsBattOrConnected('linux')
-
-  def Log(self, message):
-    """Prints line to logcat."""
-    TELEMETRY_LOGCAT_TAG = 'Telemetry'
-    self._device.RunShellCommand(
-        ['log', '-p', 'i', '-t', TELEMETRY_LOGCAT_TAG, message],
-        check_return=True)
-
-  def WaitForTemperature(self, temp):
-    # Temperature is in tenths of a degree C, so we convert to that scale.
-    self._battery.LetBatteryCoolToTemperature(temp * 10)
-
-def _FixPossibleAdbInstability():
-  """Host side workaround for crbug.com/268450 (adb instability).
-
-  The adb server has a race which is mitigated by binding to a single core.
-  """
-  if not psutil:
-    return
-  for process in psutil.process_iter():
-    try:
-      if psutil.version_info >= (2, 0):
-        if 'adb' in process.name():
-          process.cpu_affinity([0])
-      else:
-        if 'adb' in process.name:
-          process.set_cpu_affinity([0])
-    except (psutil.NoSuchProcess, psutil.AccessDenied):
-      logging.warn('Failed to set adb process CPU affinity')
diff --git a/catapult/telemetry/telemetry/internal/platform/android_platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/android_platform_backend_unittest.py
deleted file mode 100644
index 554df5c..0000000
--- a/catapult/telemetry/telemetry/internal/platform/android_platform_backend_unittest.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.platform import android_device
-from telemetry.internal.platform import android_platform_backend
-from telemetry.testing import system_stub
-import mock
-
-from devil.android import battery_utils
-from devil.android import device_utils
-
-class AndroidPlatformBackendTest(unittest.TestCase):
-  def setUp(self):
-    self._stubs = system_stub.Override(
-        android_platform_backend,
-        ['perf_control', 'thermal_throttle'])
-
-    # Skip _FixPossibleAdbInstability by setting psutil to None.
-    self._actual_ps_util = android_platform_backend.psutil
-    android_platform_backend.psutil = None
-    self.battery_patcher = mock.patch.object(battery_utils, 'BatteryUtils')
-    self.battery_patcher.start()
-
-    def get_prop(name, cache=None):
-      del cache  # unused
-      return {'ro.product.cpu.abi': 'armeabi-v7a'}.get(name)
-
-    self.device_patcher = mock.patch.multiple(
-        device_utils.DeviceUtils,
-        HasRoot=mock.MagicMock(return_value=True),
-        GetProp=mock.MagicMock(side_effect=get_prop))
-    self.device_patcher.start()
-
-  def tearDown(self):
-    self._stubs.Restore()
-    android_platform_backend.psutil = self._actual_ps_util
-    self.battery_patcher.stop()
-    self.device_patcher.stop()
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testIsSvelte(self):
-    with mock.patch('devil.android.device_utils.DeviceUtils.GetProp',
-                    return_value='svelte'):
-      backend = android_platform_backend.AndroidPlatformBackend(
-          android_device.AndroidDevice('12345'))
-      self.assertTrue(backend.IsSvelte())
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testIsNotSvelte(self):
-    with mock.patch('devil.android.device_utils.DeviceUtils.GetProp',
-                    return_value='foo'):
-      backend = android_platform_backend.AndroidPlatformBackend(
-          android_device.AndroidDevice('12345'))
-      self.assertFalse(backend.IsSvelte())
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testGetCpuStats(self):
-    proc_stat_content = (
-        '7702 (.android.chrome) S 167 167 0 0 -1 1077936448 '
-        '3247 0 0 0 4 1 0 0 20 0 9 0 5603962 337379328 5867 '
-        '4294967295 1074458624 1074463824 3197495984 3197494152 '
-        '1074767676 0 4612 0 38136 4294967295 0 0 17 0 0 0 0 0 0 '
-        '1074470376 1074470912 1102155776\n')
-    with mock.patch('devil.android.device_utils.DeviceUtils.ReadFile',
-                    return_value=proc_stat_content):
-      backend = android_platform_backend.AndroidPlatformBackend(
-          android_device.AndroidDevice('12345'))
-      cpu_stats = backend.GetCpuStats('7702')
-      self.assertEquals(cpu_stats, {'CpuProcessTime': 0.05})
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testGetCpuStatsInvalidPID(self):
-    # Mock an empty /proc/pid/stat.
-    with mock.patch('devil.android.device_utils.DeviceUtils.ReadFile',
-                    return_value=''):
-      backend = android_platform_backend.AndroidPlatformBackend(
-          android_device.AndroidDevice('1234'))
-      cpu_stats = backend.GetCpuStats('7702')
-      self.assertEquals(cpu_stats, {})
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testAndroidParseCpuStates(self):
-    cstate = {
-      'cpu0': 'C0\nC1\n103203424\n5342040\n300\n500\n1403232500',
-      'cpu1': 'C0\n124361858\n300\n1403232500'
-    }
-    expected_cstate = {
-      'cpu0': {
-        'WFI': 103203424,
-        'C0': 1403232391454536,
-        'C1': 5342040
-      },
-      'cpu1': {
-        'WFI': 124361858,
-        'C0': 1403232375638142
-      }
-    }
-    # Use mock start and end times to allow for the test to calculate C0.
-    result = android_platform_backend.AndroidPlatformBackend.ParseCStateSample(
-        cstate)
-    for cpu in result:
-      for state in result[cpu]:
-        self.assertAlmostEqual(result[cpu][state], expected_cstate[cpu][state])
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testInstallTestCaSuccess(self):
-    backend = android_platform_backend.AndroidPlatformBackend(
-        android_device.AndroidDevice('success'))
-    with mock.patch('adb_install_cert.AndroidCertInstaller'):
-      backend.InstallTestCa('testca.pem')
-      self.assertIsNotNone(backend._device_cert_util)
-
-      backend.RemoveTestCa()
-      self.assertIsNone(backend._device_cert_util)
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testIsScreenLockedTrue(self):
-    test_input = ['a=b', 'mHasBeenInactive=true']
-    backend = android_platform_backend.AndroidPlatformBackend(
-        android_device.AndroidDevice('success'))
-    self.assertTrue(backend._IsScreenLocked(test_input))
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testIsScreenLockedFalse(self):
-    test_input = ['a=b', 'mHasBeenInactive=false']
-    backend = android_platform_backend.AndroidPlatformBackend(
-        android_device.AndroidDevice('success'))
-    self.assertFalse(backend._IsScreenLocked(test_input))
-
-
-class AndroidPlatformBackendPsutilTest(unittest.TestCase):
-
-  class psutil_1_0(object):
-    version_info = (1, 0)
-    def __init__(self):
-      self.set_cpu_affinity_args = []
-    class Process(object):
-      def __init__(self, parent):
-        self._parent = parent
-        self.name = 'adb'
-      def set_cpu_affinity(self, cpus):
-        self._parent.set_cpu_affinity_args.append(cpus)
-    def process_iter(self):
-      return [self.Process(self)]
-
-  class psutil_2_0(object):
-    version_info = (2, 0)
-    def __init__(self):
-      self.set_cpu_affinity_args = []
-    class Process(object):
-      def __init__(self, parent):
-        self._parent = parent
-        self.set_cpu_affinity_args = []
-      def name(self):
-        return 'adb'
-      def cpu_affinity(self, cpus=None):
-        self._parent.set_cpu_affinity_args.append(cpus)
-    def process_iter(self):
-      return [self.Process(self)]
-
-  def setUp(self):
-    self._stubs = system_stub.Override(
-        android_platform_backend,
-        ['perf_control'])
-    self.battery_patcher = mock.patch.object(battery_utils, 'BatteryUtils')
-    self.battery_patcher.start()
-    self._actual_ps_util = android_platform_backend.psutil
-
-    def get_prop(name, cache=None):
-      del cache  # unused
-      return {'ro.product.cpu.abi': 'armeabi-v7a'}.get(name)
-
-    self.device_patcher = mock.patch.multiple(
-        device_utils.DeviceUtils,
-        FileExists=mock.MagicMock(return_value=False),
-        GetProp=mock.MagicMock(side_effect=get_prop),
-        HasRoot=mock.MagicMock(return_value=True))
-    self.device_patcher.start()
-
-  def tearDown(self):
-    self._stubs.Restore()
-    android_platform_backend.psutil = self._actual_ps_util
-    self.battery_patcher.stop()
-    self.device_patcher.stop()
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testPsutil1(self):
-    psutil = self.psutil_1_0()
-    android_platform_backend.psutil = psutil
-
-    # Mock an empty /proc/pid/stat.
-    with mock.patch('devil.android.device_utils.DeviceUtils.ReadFile',
-                    return_value=''):
-      backend = android_platform_backend.AndroidPlatformBackend(
-          android_device.AndroidDevice('1234'))
-      cpu_stats = backend.GetCpuStats('7702')
-      self.assertEquals({}, cpu_stats)
-      self.assertEquals([[0]], psutil.set_cpu_affinity_args)
-
-  @decorators.Disabled('chromeos', 'mac', 'win')
-  def testPsutil2(self):
-    psutil = self.psutil_2_0()
-    android_platform_backend.psutil = psutil
-
-    # Mock an empty /proc/pid/stat.
-    with mock.patch('devil.android.device_utils.DeviceUtils.ReadFile',
-                    return_value=''):
-      backend = android_platform_backend.AndroidPlatformBackend(
-          android_device.AndroidDevice('1234'))
-      cpu_stats = backend.GetCpuStats('7702')
-      self.assertEquals({}, cpu_stats)
-      self.assertEquals([[0]], psutil.set_cpu_affinity_args)
diff --git a/catapult/telemetry/telemetry/internal/platform/cros_device.py b/catapult/telemetry/telemetry/internal/platform/cros_device.py
deleted file mode 100644
index f27ebd1..0000000
--- a/catapult/telemetry/telemetry/internal/platform/cros_device.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-
-from telemetry.core import cros_interface
-from telemetry.core import platform
-from telemetry.internal.platform import device
-
-
-class CrOSDevice(device.Device):
-  def __init__(self, host_name, ssh_port, ssh_identity, is_local):
-    super(CrOSDevice, self).__init__(
-        name='ChromeOs with host %s' % host_name or 'localhost',
-        guid='cros:%s' % host_name or 'localhost')
-    self._host_name = host_name
-    self._ssh_port = ssh_port
-    self._ssh_identity = ssh_identity
-    self._is_local = is_local
-
-  @classmethod
-  def GetAllConnectedDevices(cls, blacklist):
-    return []
-
-  @property
-  def host_name(self):
-    return self._host_name
-
-  @property
-  def ssh_port(self):
-    return self._ssh_port
-
-  @property
-  def ssh_identity(self):
-    return self._ssh_identity
-
-  @property
-  def is_local(self):
-    return self._is_local
-
-
-def IsRunningOnCrOS():
-  return platform.GetHostPlatform().GetOSName() == 'chromeos'
-
-
-def FindAllAvailableDevices(options):
-  """Returns a list of available device types."""
-  use_ssh = options.cros_remote and cros_interface.HasSSH()
-  if not use_ssh and not IsRunningOnCrOS():
-    logging.debug('No --remote specified, and not running on ChromeOs.')
-    return []
-
-  return [CrOSDevice(options.cros_remote, options.cros_remote_ssh_port,
-                     options.cros_ssh_identity, not use_ssh)]
diff --git a/catapult/telemetry/telemetry/internal/platform/cros_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/cros_platform_backend.py
deleted file mode 100644
index 89466fd..0000000
--- a/catapult/telemetry/telemetry/internal/platform/cros_platform_backend.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry import decorators
-from telemetry.core import cros_interface
-from telemetry.core import platform
-from telemetry.core import util
-from telemetry.internal.forwarders import cros_forwarder
-from telemetry.internal.platform import cros_device
-from telemetry.internal.platform import linux_based_platform_backend
-from telemetry.internal.platform.power_monitor import cros_power_monitor
-from telemetry.internal.util import ps_util
-
-
-class CrosPlatformBackend(
-    linux_based_platform_backend.LinuxBasedPlatformBackend):
-  def __init__(self, device=None):
-    super(CrosPlatformBackend, self).__init__(device)
-    if device and not device.is_local:
-      self._cri = cros_interface.CrOSInterface(
-          device.host_name, device.ssh_port, device.ssh_identity)
-      self._cri.TryLogin()
-    else:
-      self._cri = cros_interface.CrOSInterface()
-    self._powermonitor = cros_power_monitor.CrosPowerMonitor(self)
-
-  @classmethod
-  def IsPlatformBackendForHost(cls):
-    return util.IsRunningOnCrosDevice()
-
-  @classmethod
-  def SupportsDevice(cls, device):
-    return isinstance(device, cros_device.CrOSDevice)
-
-  @classmethod
-  def CreatePlatformForDevice(cls, device, finder_options):
-    assert cls.SupportsDevice(device)
-    return platform.Platform(CrosPlatformBackend(device))
-
-  @property
-  def cri(self):
-    return self._cri
-
-  @property
-  def forwarder_factory(self):
-    if not self._forwarder_factory:
-      self._forwarder_factory = cros_forwarder.CrOsForwarderFactory(self._cri)
-    return self._forwarder_factory
-
-  def GetRemotePort(self, port):
-    if self._cri.local:
-      return port
-    return self._cri.GetRemotePort()
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def RunCommand(self, args):
-    if not isinstance(args, list):
-      args = [args]
-    stdout, stderr = self._cri.RunCmdOnDevice(args)
-    if stderr:
-      raise IOError('Failed to run: cmd = %s, stderr = %s' %
-                    (str(args), stderr))
-    return stdout
-
-  def GetFileContents(self, filename):
-    try:
-      return self.RunCommand(['cat', filename])
-    except AssertionError:
-      return ''
-
-  def GetPsOutput(self, columns, pid=None):
-    return ps_util.GetPsOutputWithPlatformBackend(self, columns, pid)
-
-  @staticmethod
-  def ParseCStateSample(sample):
-    sample_stats = {}
-    for cpu in sample:
-      values = sample[cpu].splitlines()
-      # There are three values per state after excluding the single time value.
-      num_states = (len(values) - 1) / 3
-      names = values[:num_states]
-      times = values[num_states:2 * num_states]
-      latencies = values[2 * num_states:]
-      # The last line in the sample contains the time.
-      cstates = {'C0': int(values[-1]) * 10 ** 6}
-      for i, state in enumerate(names):
-        if names[i] == 'POLL' and not int(latencies[i]):
-          # C0 state. Kernel stats aren't right, so calculate by
-          # subtracting all other states from total time (using epoch
-          # timer since we calculate differences in the end anyway).
-          # NOTE: Only x86 lists C0 under cpuidle, ARM does not.
-          continue
-        cstates['C0'] -= int(times[i])
-        if names[i] == '<null>':
-          # Kernel race condition that can happen while a new C-state gets
-          # added (e.g. AC->battery). Don't know the 'name' of the state
-          # yet, but its 'time' would be 0 anyway.
-          continue
-        cstates[state] = int(times[i])
-      sample_stats[cpu] = cstates
-    return sample_stats
-
-  def GetDeviceTypeName(self):
-    return self._cri.GetDeviceTypeName()
-
-  @decorators.Cache
-  def GetArchName(self):
-    return self._cri.GetArchName()
-
-  def GetOSName(self):
-    return 'chromeos'
-
-  def GetOSVersionName(self):
-    return ''  # TODO: Implement this.
-
-  def GetChildPids(self, pid):
-    """Returns a list of child pids of |pid|."""
-    all_process_info = self._cri.ListProcesses()
-    processes = [(curr_pid, curr_ppid, curr_state)
-                 for curr_pid, _, curr_ppid, curr_state in all_process_info]
-    return ps_util.GetChildPids(processes, pid)
-
-  def GetCommandLine(self, pid):
-    procs = self._cri.ListProcesses()
-    return next((proc[1] for proc in procs if proc[0] == pid), None)
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    return True
-
-  def FlushEntireSystemCache(self):
-    raise NotImplementedError()
-
-  def FlushSystemCacheForDirectory(self, directory):
-    flush_command = (
-        '/usr/local/telemetry/src/src/out/Release/clear_system_cache')
-    self.RunCommand(['chmod', '+x', flush_command])
-    self.RunCommand([flush_command, '--recurse', directory])
-
-  def CanMonitorPower(self):
-    return self._powermonitor.CanMonitorPower()
-
-  def StartMonitoringPower(self, browser):
-    self._powermonitor.StartMonitoringPower(browser)
-
-  def StopMonitoringPower(self):
-    return self._powermonitor.StopMonitoringPower()
-
-  def PathExists(self, path, timeout=None, retries=None):
-    if timeout or retries:
-      logging.warning(
-          'PathExists: params timeout and retries are not support on CrOS.')
-    return self._cri.FileExistsOnDevice(path)
-
-  def CanTakeScreenshot(self):
-    # crbug.com/609001: screenshots don't work on VMs.
-    return not self.cri.IsRunningOnVM()
-
-  def TakeScreenshot(self, file_path):
-    return self._cri.TakeScreenshot(file_path)
diff --git a/catapult/telemetry/telemetry/internal/platform/cros_platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/cros_platform_backend_unittest.py
deleted file mode 100644
index d6c8ac7..0000000
--- a/catapult/telemetry/telemetry/internal/platform/cros_platform_backend_unittest.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.platform import cros_platform_backend
-
-
-class CrosPlatformBackendTest(unittest.TestCase):
-  initial_cstate = {
-    'cpu0': 'POLL\nC1\nC2\nC3\n0\n138356189\n102416540\n'
-            '17158209182\n0\n1\n500\n1000\n1403211341',
-    'cpu1': 'POLL\nC1\nC2\nC3\n0\n107318149\n81786238\n'
-            '17348563431\n0\n1\n500\n1000\n1403211341'
-  }
-  expected_cstate = {
-    'cpu0': {
-      'C0': 1403193942018089,
-      'C1': 138356189,
-      'C2': 102416540,
-      'C3': 17158209182
-    },
-    'cpu1': {
-      'C0': 1403193803332182,
-      'C1': 107318149,
-      'C2': 81786238,
-      'C3': 17348563431
-    }
-  }
-  def testCrosParseCpuStates(self):
-    # Use mock start and end times to allow for the test to calculate C0.
-    results = cros_platform_backend.CrosPlatformBackend.ParseCStateSample(
-        self.initial_cstate)
-    for cpu in results:
-      for state in results[cpu]:
-        self.assertAlmostEqual(results[cpu][state],
-                               self.expected_cstate[cpu][state])
diff --git a/catapult/telemetry/telemetry/internal/platform/desktop_device.py b/catapult/telemetry/telemetry/internal/platform/desktop_device.py
deleted file mode 100644
index 0a9f0fa..0000000
--- a/catapult/telemetry/telemetry/internal/platform/desktop_device.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import platform
-from telemetry.internal.platform import device
-
-
-class DesktopDevice(device.Device):
-  def __init__(self):
-    super(DesktopDevice, self).__init__(name='desktop', guid='desktop')
-
-  @classmethod
-  def GetAllConnectedDevices(cls, blacklist):
-    return []
-
-
-def FindAllAvailableDevices(_):
-  """Returns a list of available devices.
-  """
-  # If the host platform is Chrome OS, the device is also considered as cros.
-  if platform.GetHostPlatform().GetOSName() == 'chromeos':
-    return []
-  return [DesktopDevice()]
diff --git a/catapult/telemetry/telemetry/internal/platform/desktop_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/desktop_platform_backend.py
deleted file mode 100644
index 510b534..0000000
--- a/catapult/telemetry/telemetry/internal/platform/desktop_platform_backend.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import subprocess
-
-from telemetry.internal.util import binary_manager
-from telemetry.internal.platform import platform_backend
-
-
-class DesktopPlatformBackend(platform_backend.PlatformBackend):
-
-  # This is an abstract class. It is OK to have abstract methods.
-  # pylint: disable=abstract-method
-
-  def FlushSystemCacheForDirectory(self, directory):
-    assert directory and os.path.exists(directory), \
-        'Target directory %s must exist' % directory
-    flush_command = binary_manager.FetchPath(
-        'clear_system_cache', self.GetArchName(), self.GetOSName())
-    assert flush_command, 'You must build clear_system_cache first'
-
-    subprocess.check_call([flush_command, '--recurse', directory])
-
-  def GetDeviceTypeName(self):
-    return 'Desktop'
diff --git a/catapult/telemetry/telemetry/internal/platform/device.py b/catapult/telemetry/telemetry/internal/platform/device.py
deleted file mode 100644
index 34ca721..0000000
--- a/catapult/telemetry/telemetry/internal/platform/device.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class Device(object):
-  """ A base class of devices.
-  A device instance contains all the necessary information for constructing
-  a platform backend object for remote platforms.
-
-  Attributes:
-    name: A device name string in human-understandable term.
-    guid: A unique id of the device. Subclass of device must specify this
-      id properly so that device objects to a same actual device must have same
-      guid.
-    """
-
-  def __init__(self, name, guid):
-    self._name = name
-    self._guid = guid
-
-  @property
-  def name(self):
-    return self._name
-
-  @property
-  def guid(self):
-    return self._guid
-
-  @classmethod
-  def GetAllConnectedDevices(cls, blacklist):
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/internal/platform/device_finder.py b/catapult/telemetry/telemetry/internal/platform/device_finder.py
deleted file mode 100644
index fdcd5ae..0000000
--- a/catapult/telemetry/telemetry/internal/platform/device_finder.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Finds devices that can be controlled by telemetry."""
-
-from telemetry.internal.platform import android_device
-from telemetry.internal.platform import cros_device
-from telemetry.internal.platform import desktop_device
-from telemetry.internal.platform import ios_device
-
-DEVICES = [
-  android_device,
-  cros_device,
-  desktop_device,
-  ios_device,
-]
-
-
-def _GetAllAvailableDevices(options):
-  """Returns a list of all available devices."""
-  devices = []
-  for device in DEVICES:
-    devices.extend(device.FindAllAvailableDevices(options))
-  return devices
-
-
-def GetDevicesMatchingOptions(options):
-  """Returns a list of devices matching the options."""
-  devices = []
-  remote_platform_options = options.remote_platform_options
-  if (not remote_platform_options.device or
-      remote_platform_options.device == 'list'):
-    devices = _GetAllAvailableDevices(options)
-  elif remote_platform_options.device == 'android':
-    devices = android_device.FindAllAvailableDevices(options)
-  else:
-    devices = _GetAllAvailableDevices(options)
-    devices = [d for d in devices if d.guid ==
-               options.remote_platform_options.device]
-
-  devices.sort(key=lambda device: device.name)
-  return devices
diff --git a/catapult/telemetry/telemetry/internal/platform/efficient_android_directory_copy.sh b/catapult/telemetry/telemetry/internal/platform/efficient_android_directory_copy.sh
deleted file mode 100755
index 7021109..0000000
--- a/catapult/telemetry/telemetry/internal/platform/efficient_android_directory_copy.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/system/bin/sh
-
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Android shell script to make the destination directory identical with the
-# source directory, without doing unnecessary copies. This assumes that the
-# the destination directory was originally a copy of the source directory, and
-# has since been modified.
-
-source=$1
-dest=$2
-echo copying $source to $dest
-
-delete_extra() {
-  # Don't delete symbolic links, since doing so deletes the vital lib link.
-  if [ ! -L "$1" ]
-  then
-    if [ ! -e "$source/$1" ]
-    then
-      echo rm -rf "$dest/$1"
-      rm -rf "$dest/$1"
-    elif [ -d "$1" ]
-    then
-      for f in "$1"/*
-      do
-       delete_extra "$f"
-      done
-    fi
-  fi
-}
-
-copy_if_older() {
-  if [ -d "$1" ] && [ -e "$dest/$1" ]
-  then
-    if [ ! -e "$dest/$1" ]
-    then
-      echo cp -a "$1" "$dest/$1"
-      cp -a "$1" "$dest/$1"
-    else
-      for f in "$1"/*
-      do
-        copy_if_older "$f"
-      done
-    fi
-  elif [ ! -e "$dest/$1" ] || [ "$1" -ot "$dest/$1" ] || [ "$1" -nt "$dest/$1" ]
-  then
-    # dates are different, so either the destination of the source has changed.
-    echo cp -a "$1" "$dest/$1"
-    cp -a "$1" "$dest/$1"
-  fi
-}
-
-if [ -e "$dest" ]
-then
-  echo cd "$dest"
-  cd "$dest"
-  for f in ./*
-  do
-    if [ -e "$f" ]
-    then
-      delete_extra "$f"
-    fi
-  done
-else
-  echo mkdir "$dest"
-  mkdir "$dest"
-fi
-echo cd "$source"
-cd "$source"
-for f in ./*
-do
-  if [ -e "$f" ]
-  then
-    copy_if_older "$f"
-  fi
-done
diff --git a/catapult/telemetry/telemetry/internal/platform/gpu_device.py b/catapult/telemetry/telemetry/internal/platform/gpu_device.py
deleted file mode 100644
index 926f927..0000000
--- a/catapult/telemetry/telemetry/internal/platform/gpu_device.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class GPUDevice(object):
-  """Provides information about an individual GPU device.
-
-     On platforms which support them, the vendor_id and device_id are
-     PCI IDs. On other platforms, the vendor_string and device_string
-     are platform-dependent strings.
-  """
-
-  _VENDOR_ID_MAP = {
-    0x1002: 'ATI',
-    0x8086: 'Intel',
-    0x10de: 'Nvidia',
-    }
-
-  def __init__(self, vendor_id, device_id, vendor_string, device_string):
-    self._vendor_id = vendor_id
-    self._device_id = device_id
-    self._vendor_string = vendor_string
-    self._device_string = device_string
-
-  def __str__(self):
-    vendor = 'VENDOR = 0x%x' % self._vendor_id
-    vendor_string = self._vendor_string
-    if not vendor_string and self._vendor_id in self._VENDOR_ID_MAP:
-      vendor_string = self._VENDOR_ID_MAP[self._vendor_id]
-    if vendor_string:
-      vendor += ' (%s)' % vendor_string
-    device = 'DEVICE = 0x%x' % self._device_id
-    if self._device_string:
-      device += ' (%s)' % self._device_string
-    return '%s, %s' % (vendor, device)
-
-  @classmethod
-  def FromDict(cls, attrs):
-    """Constructs a GPUDevice from a dictionary. Requires the
-       following attributes to be present in the dictionary:
-
-         vendor_id
-         device_id
-         vendor_string
-         device_string
-
-       Raises an exception if any attributes are missing.
-    """
-    return cls(attrs['vendor_id'], attrs['device_id'],
-               attrs['vendor_string'], attrs['device_string'])
-
-  @property
-  def vendor_id(self):
-    """The GPU vendor's PCI ID as a number, or 0 if not available.
-
-       Most desktop machines supply this information rather than the
-       vendor and device strings."""
-    return self._vendor_id
-
-  @property
-  def device_id(self):
-    """The GPU device's PCI ID as a number, or 0 if not available.
-
-       Most desktop machines supply this information rather than the
-       vendor and device strings."""
-    return self._device_id
-
-  @property
-  def vendor_string(self):
-    """The GPU vendor's name as a string, or the empty string if not
-       available.
-
-       Most mobile devices supply this information rather than the PCI
-       IDs."""
-    return self._vendor_string
-
-  @property
-  def device_string(self):
-    """The GPU device's name as a string, or the empty string if not
-       available.
-
-       Most mobile devices supply this information rather than the PCI
-       IDs."""
-    return self._device_string
diff --git a/catapult/telemetry/telemetry/internal/platform/gpu_device_unittest.py b/catapult/telemetry/telemetry/internal/platform/gpu_device_unittest.py
deleted file mode 100644
index d4ba384..0000000
--- a/catapult/telemetry/telemetry/internal/platform/gpu_device_unittest.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.internal.platform import gpu_device
-
-
-class TestGPUDevice(unittest.TestCase):
-
-  def testConstruction(self):
-    device = gpu_device.GPUDevice(1000, 2000, 'test_vendor', 'test_device')
-    self.assertEquals(device.vendor_id, 1000)
-    self.assertEquals(device.device_id, 2000)
-    self.assertEquals(device.vendor_string, 'test_vendor')
-    self.assertEquals(device.device_string, 'test_device')
-
-  def testFromDict(self):
-    dictionary = {'vendor_id': 3000,
-                  'device_id': 4000,
-                  'vendor_string': 'test_vendor_2',
-                  'device_string': 'test_device_2'}
-    device = gpu_device.GPUDevice.FromDict(dictionary)
-    self.assertEquals(device.vendor_id, 3000)
-    self.assertEquals(device.device_id, 4000)
-    self.assertEquals(device.vendor_string, 'test_vendor_2')
-    self.assertEquals(device.device_string, 'test_device_2')
-
-  def testMissingAttrsFromDict(self):
-    data = {
-        'vendor_id': 1,
-        'device_id': 2,
-        'vendor_string': 'a',
-        'device_string': 'b'
-    }
-
-    for k in data:
-      data_copy = data.copy()
-      del data_copy[k]
-      try:
-        gpu_device.GPUDevice.FromDict(data_copy)
-        self.fail('Should raise exception if attribute "%s" is missing' % k)
-      except AssertionError:
-        raise
-      except KeyError:
-        pass
diff --git a/catapult/telemetry/telemetry/internal/platform/gpu_info.py b/catapult/telemetry/telemetry/internal/platform/gpu_info.py
deleted file mode 100644
index b565bb1..0000000
--- a/catapult/telemetry/telemetry/internal/platform/gpu_info.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.platform import gpu_device
-
-
-class GPUInfo(object):
-  """Provides information about the GPUs on the system."""
-
-  def __init__(self, device_array, aux_attributes,
-               feature_status, driver_bug_workarounds):
-    if device_array == None:
-      raise Exception('Missing required "devices" property')
-    if len(device_array) == 0:
-      raise Exception('Missing at least one GPU in device_array')
-
-    self._devices = [gpu_device.GPUDevice.FromDict(d) for d in device_array]
-    self._aux_attributes = aux_attributes
-    self._feature_status = feature_status
-    self._driver_bug_workarounds = driver_bug_workarounds
-
-  @classmethod
-  def FromDict(cls, attrs):
-    """Constructs a GPUInfo from a dictionary of attributes.
-
-    Attributes currently required to be present in the dictionary:
-      devices (array of dictionaries, each of which contains
-          GPUDevice's required attributes)
-    """
-    return cls(attrs['devices'], attrs.get('aux_attributes'),
-               attrs.get('feature_status'),
-               attrs.get('driver_bug_workarounds'))
-
-  @property
-  def devices(self):
-    """An array of GPUDevices. Element 0 is the primary GPU on the system."""
-    return self._devices
-
-  @property
-  def aux_attributes(self):
-    """Returns a dictionary of auxiliary, optional, attributes.
-
-    On the Chrome browser, for example, this dictionary contains:
-      optimus (boolean)
-      amd_switchable (boolean)
-      driver_vendor (string)
-      driver_version (string)
-      driver_date (string)
-      gl_version_string (string)
-      gl_vendor (string)
-      gl_renderer (string)
-      gl_extensions (string)
-    """
-    return self._aux_attributes
-
-  @property
-  def feature_status(self):
-    """Returns an optional dictionary of graphics features and their status."""
-    return self._feature_status
-
-  @property
-  def driver_bug_workarounds(self):
-    """Returns an optional array of driver bug workarounds."""
-    return self._driver_bug_workarounds
diff --git a/catapult/telemetry/telemetry/internal/platform/gpu_info_unittest.py b/catapult/telemetry/telemetry/internal/platform/gpu_info_unittest.py
deleted file mode 100644
index a395ddd..0000000
--- a/catapult/telemetry/telemetry/internal/platform/gpu_info_unittest.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.internal.platform import gpu_device
-from telemetry.internal.platform import gpu_info
-
-
-class TestGPUInfo(unittest.TestCase):
-
-  def testConstruction(self):
-    data = {
-        'devices': [
-            {'vendor_id': 1000, 'device_id': 2000,
-             'vendor_string': 'a', 'device_string': 'b'},
-            {'vendor_id': 3000, 'device_id': 4000,
-             'vendor_string': 'k', 'device_string': 'l'}
-        ],
-        'aux_attributes': {
-            'optimus': False,
-            'amd_switchable': False,
-            'driver_vendor': 'c',
-            'driver_version': 'd',
-            'driver_date': 'e',
-            'gl_version_string': 'g',
-            'gl_vendor': 'h',
-            'gl_renderer': 'i',
-            'gl_extensions': 'j',
-        }
-    }
-    info = gpu_info.GPUInfo.FromDict(data)
-    self.assertTrue(len(info.devices) == 2)
-    self.assertTrue(isinstance(info.devices[0], gpu_device.GPUDevice))
-    self.assertEquals(info.devices[0].vendor_id, 1000)
-    self.assertEquals(info.devices[0].device_id, 2000)
-    self.assertEquals(info.devices[0].vendor_string, 'a')
-    self.assertEquals(info.devices[0].device_string, 'b')
-    self.assertTrue(isinstance(info.devices[1], gpu_device.GPUDevice))
-    self.assertEquals(info.devices[1].vendor_id, 3000)
-    self.assertEquals(info.devices[1].device_id, 4000)
-    self.assertEquals(info.devices[1].vendor_string, 'k')
-    self.assertEquals(info.devices[1].device_string, 'l')
-    self.assertEquals(info.aux_attributes['optimus'], False)
-    self.assertEquals(info.aux_attributes['amd_switchable'], False)
-    self.assertEquals(info.aux_attributes['driver_vendor'], 'c')
-    self.assertEquals(info.aux_attributes['driver_version'], 'd')
-    self.assertEquals(info.aux_attributes['driver_date'], 'e')
-    self.assertEquals(info.aux_attributes['gl_version_string'], 'g')
-    self.assertEquals(info.aux_attributes['gl_vendor'], 'h')
-    self.assertEquals(info.aux_attributes['gl_renderer'], 'i')
-    self.assertEquals(info.aux_attributes['gl_extensions'], 'j')
-
-  def testMissingAttrsFromDict(self):
-    data = {
-        'devices': [{'vendor_id': 1000, 'device_id': 2000,
-                     'vendor_string': 'a', 'device_string': 'b'}]
-    }
-
-    for k in data:
-      data_copy = data.copy()
-      del data_copy[k]
-      try:
-        gpu_info.GPUInfo.FromDict(data_copy)
-        self.fail('Should raise exception if attribute "%s" is missing' % k)
-      except AssertionError:
-        raise
-      except KeyError:
-        pass
-
-  def testMissingDevices(self):
-    data = {
-        'devices': []
-    }
-
-    try:
-      gpu_info.GPUInfo.FromDict(data)
-      self.fail('Should raise exception if devices array is empty')
-    except AssertionError:
-      raise
-    except Exception:
-      pass
diff --git a/catapult/telemetry/telemetry/internal/platform/ios_device.py b/catapult/telemetry/telemetry/internal/platform/ios_device.py
deleted file mode 100644
index fac0280..0000000
--- a/catapult/telemetry/telemetry/internal/platform/ios_device.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import logging
-import re
-import subprocess
-
-from telemetry.core import platform
-from telemetry.internal.platform import device
-
-
-IOSSIM_BUILD_DIRECTORIES = [
-    'Debug-iphonesimulator',
-    'Profile-iphonesimulator',
-    'Release-iphonesimulator'
-]
-
-class IOSDevice(device.Device):
-  def __init__(self):
-    super(IOSDevice, self).__init__(name='ios', guid='ios')
-
-  @classmethod
-  def GetAllConnectedDevices(cls, blacklist):
-    return []
-
-
-def _IsIosDeviceAttached():
-  devices = subprocess.check_output('system_profiler SPUSBDataType', shell=True)
-  for line in devices.split('\n'):
-    if line and re.match(r'\s*(iPod|iPhone|iPad):', line):
-      return True
-  return False
-
-def _IsIosSimulatorAvailable(chrome_root):
-  """Determines whether an iOS simulator is present in the local checkout.
-
-  Assumes the iOS simulator (iossim) and Chromium have already been built.
-
-  Returns:
-    True if at least one simulator is found, otherwise False.
-  """
-  for build_dir in IOSSIM_BUILD_DIRECTORIES:
-    iossim_path = os.path.join(
-        chrome_root, 'out', build_dir, 'iossim')
-    chromium_path = os.path.join(
-        chrome_root, 'out', build_dir, 'Chromium.app')
-
-    # If the iOS simulator and Chromium app are present, return True
-    if os.path.exists(iossim_path) and os.path.exists(chromium_path):
-      return True
-
-  return False
-
-def FindAllAvailableDevices(options):
-  """Returns a list of available devices.
-  """
-  # TODO(baxley): Add support for all platforms possible. Probably Linux,
-  # probably not Windows.
-  if platform.GetHostPlatform().GetOSName() != 'mac':
-    return []
-
-  if options.chrome_root is None:
-    logging.warning('--chrome-root is not specified, skip iOS simulator tests.')
-    return []
-
-  if (not _IsIosDeviceAttached() and not
-      _IsIosSimulatorAvailable(options.chrome_root)):
-    return []
-
-  return [IOSDevice()]
diff --git a/catapult/telemetry/telemetry/internal/platform/ios_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/ios_platform_backend.py
deleted file mode 100644
index 1221422..0000000
--- a/catapult/telemetry/telemetry/internal/platform/ios_platform_backend.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.internal.platform import posix_platform_backend
-
-#TODO(baxley): Put in real values.
-class IosPlatformBackend(posix_platform_backend.PosixPlatformBackend):
-  def __init__(self):
-    super(IosPlatformBackend, self).__init__()
-
-  def GetOSName(self):
-    # TODO(baxley): Get value from ideviceinfo.
-    logging.warn('Not implemented')
-    return 'ios'
-
-  def GetOSVersionName(self):
-    # TODO(baxley): Get value from ideviceinfo.
-    logging.warn('Not implemented')
-    return '7.1'
-
-  def SetFullPerformanceModeEnabled(self, enabled):
-    logging.warn('Not implemented')
-    return
-
-  def FlushDnsCache(self):
-    logging.warn('Not implemented')
-    return
-
-  def CanMonitorThermalThrottling(self):
-    logging.warn('Not implemented')
-    return False
-
-  def CanMonitorPower(self):
-    logging.warn('Not implemented')
-    return False
-
-  def StartMonitoringPower(self, browser):
-    raise NotImplementedError()
-
-  def StopMonitoringPower(self):
-    raise NotImplementedError()
-
-  def FlushEntireSystemCache(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def StopVideoCapture(self):
-    raise NotImplementedError()
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def GetSystemTotalPhysicalMemory(self):
-    raise NotImplementedError()
-
-  def InstallApplication(self, application):
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/internal/platform/linux_based_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/linux_based_platform_backend.py
deleted file mode 100644
index d06b85c..0000000
--- a/catapult/telemetry/telemetry/internal/platform/linux_based_platform_backend.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-try:
-  import resource  # pylint: disable=import-error
-except ImportError:
-  resource = None  # Not available on all platforms
-
-import re
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.platform import platform_backend
-
-
-class LinuxBasedPlatformBackend(platform_backend.PlatformBackend):
-
-  """Abstract platform containing functionality shared by all Linux based OSes.
-
-  This includes Android and ChromeOS.
-
-  Subclasses must implement RunCommand, GetFileContents, GetPsOutput, and
-  ParseCStateSample."""
-
-  # Get the commit charge in kB.
-  def GetSystemCommitCharge(self):
-    meminfo_contents = self.GetFileContents('/proc/meminfo')
-    meminfo = self._GetProcFileDict(meminfo_contents)
-    if not meminfo:
-      return None
-    return (self._ConvertToKb(meminfo['MemTotal'])
-            - self._ConvertToKb(meminfo['MemFree'])
-            - self._ConvertToKb(meminfo['Buffers'])
-            - self._ConvertToKb(meminfo['Cached']))
-
-  @decorators.Cache
-  def GetSystemTotalPhysicalMemory(self):
-    meminfo_contents = self.GetFileContents('/proc/meminfo')
-    meminfo = self._GetProcFileDict(meminfo_contents)
-    if not meminfo:
-      return None
-    return self._ConvertToBytes(meminfo['MemTotal'])
-
-  def GetCpuStats(self, pid):
-    results = {}
-    stats = self._GetProcFileForPid(pid, 'stat')
-    if not stats:
-      return results
-    stats = stats.split()
-    utime = float(stats[13])
-    stime = float(stats[14])
-    cpu_process_jiffies = utime + stime
-    clock_ticks = self.GetClockTicks()
-    results.update({'CpuProcessTime': cpu_process_jiffies / clock_ticks})
-    return results
-
-  def GetCpuTimestamp(self):
-    total_jiffies = self._GetProcJiffies()
-    clock_ticks = self.GetClockTicks()
-    return {'TotalTime': total_jiffies / clock_ticks}
-
-  @decorators.Deprecated(
-      2017, 11, 4,
-      'Clients should use tracing and memory-infra in new Telemetry '
-      'benchmarks. See for context: https://crbug.com/632021')
-  def GetMemoryStats(self, pid):
-    status_contents = self._GetProcFileForPid(pid, 'status')
-    stats = self._GetProcFileForPid(pid, 'stat').split()
-    status = self._GetProcFileDict(status_contents)
-    if not status or not stats or 'Z' in status['State']:
-      return {}
-    vm = int(stats[22])
-    vm_peak = (self._ConvertToBytes(status['VmPeak'])
-               if 'VmPeak' in status else vm)
-    wss = int(stats[23]) * resource.getpagesize()
-    wss_peak = (self._ConvertToBytes(status['VmHWM'])
-                if 'VmHWM' in status else wss)
-
-    private_dirty_bytes = 0
-    for line in self._GetProcFileForPid(pid, 'smaps').splitlines():
-      if line.startswith('Private_Dirty:'):
-        private_dirty_bytes += self._ConvertToBytes(line.split(':')[1].strip())
-
-    return {'VM': vm,
-            'VMPeak': vm_peak,
-            'PrivateDirty': private_dirty_bytes,
-            'WorkingSetSize': wss,
-            'WorkingSetSizePeak': wss_peak}
-
-  @decorators.Cache
-  def GetClockTicks(self):
-    """Returns the number of clock ticks per second.
-
-    The proper way is to call os.sysconf('SC_CLK_TCK') but that is not easy to
-    do on Android/CrOS. In practice, nearly all Linux machines have a USER_HZ
-    of 100, so just return that.
-    """
-    return 100
-
-  def GetFileContents(self, filename):
-    raise NotImplementedError()
-
-  def GetPsOutput(self, columns, pid=None):
-    raise NotImplementedError()
-
-  def RunCommand(self, cmd):
-    """Runs the specified command.
-
-    Args:
-        cmd: A list of program arguments or the path string of the program.
-    Returns:
-        A string whose content is the output of the command.
-    """
-    raise NotImplementedError()
-
-  @staticmethod
-  def ParseCStateSample(sample):
-    """Parse a single c-state residency sample.
-
-    Args:
-        sample: A sample of c-state residency times to be parsed. Organized as
-            a dictionary mapping CPU name to a string containing all c-state
-            names, the times in each state, the latency of each state, and the
-            time at which the sample was taken all separated by newlines.
-            Ex: {'cpu0': 'C0\nC1\n5000\n2000\n20\n30\n1406673171'}
-
-    Returns:
-        Dictionary associating a c-state with a time.
-    """
-    raise NotImplementedError()
-
-  def _IsPidAlive(self, pid):
-    assert pid, 'pid is required'
-    return bool(self.GetPsOutput(['pid'], pid) == str(pid))
-
-  def _GetProcFileForPid(self, pid, filename):
-    try:
-      return self.GetFileContents('/proc/%s/%s' % (pid, filename))
-    except IOError:
-      if not self._IsPidAlive(pid):
-        raise exceptions.ProcessGoneException()
-      raise
-
-  def _ConvertToKb(self, value):
-    return int(value.replace('kB', ''))
-
-  def _ConvertToBytes(self, value):
-    return self._ConvertToKb(value) * 1024
-
-  def _GetProcFileDict(self, contents):
-    retval = {}
-    for line in contents.splitlines():
-      key, value = line.split(':')
-      retval[key.strip()] = value.strip()
-    return retval
-
-  def _GetProcJiffies(self):
-    """Parse '/proc/timer_list' output and returns the first jiffies attribute.
-
-    Multi-CPU machines will have multiple 'jiffies:' lines, all of which will be
-    essentially the same.  Return the first one."""
-    jiffies_timer_lines = self.RunCommand(
-        ['grep', 'jiffies', '/proc/timer_list'])
-    if not jiffies_timer_lines:
-      raise Exception('Unable to find jiffies from /proc/timer_list')
-    jiffies_timer_list = jiffies_timer_lines.splitlines()
-    # Each line should look something like 'jiffies: 4315883489'.
-    for line in jiffies_timer_list:
-      match = re.match(r'\s*jiffies\s*:\s*(\d+)', line)
-      if match:
-        value = match.group(1)
-        return float(value)
-    raise Exception('Unable to parse jiffies attribute: %s' %
-                    repr(jiffies_timer_lines))
diff --git a/catapult/telemetry/telemetry/internal/platform/linux_based_platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/linux_based_platform_backend_unittest.py
deleted file mode 100644
index 69ddb48..0000000
--- a/catapult/telemetry/telemetry/internal/platform/linux_based_platform_backend_unittest.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import unittest
-
-from telemetry.core import util
-from telemetry.internal.platform import linux_based_platform_backend
-import mock
-
-
-class TestLinuxBackend(linux_based_platform_backend.LinuxBasedPlatformBackend):
-
-  # pylint: disable=abstract-method
-
-  def __init__(self):
-    super(TestLinuxBackend, self).__init__()
-    self._mock_files = {}
-
-  def SetMockFile(self, filename, output):
-    self._mock_files[filename] = output
-
-  def GetFileContents(self, filename):
-    return self._mock_files[filename]
-
-  def GetClockTicks(self):
-    return 41
-
-
-class LinuxBasedPlatformBackendTest(unittest.TestCase):
-
-  def SetMockFileInBackend(self, backend, real_file, mock_file):
-    with open(os.path.join(util.GetUnittestDataDir(), real_file)) as f:
-      backend.SetMockFile(mock_file, f.read())
-
-  def testGetSystemCommitCharge(self):
-    if not linux_based_platform_backend.resource:
-      logging.warning('Test not supported')
-      return
-
-    backend = TestLinuxBackend()
-    self.SetMockFileInBackend(backend, 'proc_meminfo', '/proc/meminfo')
-    result = backend.GetSystemCommitCharge()
-    # 25252140 == MemTotal - MemFree - Buffers - Cached (in kB)
-    self.assertEquals(result, 25252140)
-
-  def testGetSystemTotalPhysicalMemory(self):
-    if not linux_based_platform_backend.resource:
-      logging.warning('Test not supported')
-      return
-
-    backend = TestLinuxBackend()
-    self.SetMockFileInBackend(backend, 'proc_meminfo', '/proc/meminfo')
-    result = backend.GetSystemTotalPhysicalMemory()
-    # 67479191552 == MemTotal * 1024
-    self.assertEquals(result, 67479191552)
-
-  def testGetCpuStatsBasic(self):
-    if not linux_based_platform_backend.resource:
-      logging.warning('Test not supported')
-      return
-
-    backend = TestLinuxBackend()
-    self.SetMockFileInBackend(backend, 'stat', '/proc/1/stat')
-    result = backend.GetCpuStats(1)
-    self.assertEquals(result, {'CpuProcessTime': 22.0})
-
-  def testGetCpuTimestampBasic(self):
-    if not linux_based_platform_backend.resource:
-      logging.warning('Test not supported')
-      return
-    jiffies_grep_string = """
-    jiffies
-jiffies  a1111
-    .last_jiffies   : 4307239958
-    .next_jiffies   : 4307239968
-    jiffies: 10505463300
-    jiffies: 10505463333
-    """
-    with mock.patch.object(
-        linux_based_platform_backend.LinuxBasedPlatformBackend,
-        'RunCommand', return_value=jiffies_grep_string) as mock_method:
-      backend = linux_based_platform_backend.LinuxBasedPlatformBackend()
-      result = backend.GetCpuTimestamp()
-      self.assertEquals(result, {'TotalTime': 105054633.0})
-    mock_method.assert_call_once_with(
-        ['grep', '-m', '1', 'jiffies:', '/proc/timer_list'])
-
-  def testGetMemoryStatsBasic(self):
-    if not linux_based_platform_backend.resource:
-      logging.warning('Test not supported')
-      return
-
-    backend = TestLinuxBackend()
-    self.SetMockFileInBackend(backend, 'stat', '/proc/1/stat')
-    self.SetMockFileInBackend(backend, 'status', '/proc/1/status')
-    self.SetMockFileInBackend(backend, 'smaps', '/proc/1/smaps')
-    result = backend.GetMemoryStats(1)
-    self.assertEquals(result, {'PrivateDirty': 5324800,
-                               'VM': 1025978368,
-                               'VMPeak': 1050099712,
-                               'WorkingSetSize': 84000768,
-                               'WorkingSetSizePeak': 144547840})
-
-  def testGetMemoryStatsNoHWM(self):
-    if not linux_based_platform_backend.resource:
-      logging.warning('Test not supported')
-      return
-
-    backend = TestLinuxBackend()
-    self.SetMockFileInBackend(backend, 'stat', '/proc/1/stat')
-    self.SetMockFileInBackend(backend, 'status_nohwm', '/proc/1/status')
-    self.SetMockFileInBackend(backend, 'smaps', '/proc/1/smaps')
-    result = backend.GetMemoryStats(1)
-    self.assertEquals(result, {'PrivateDirty': 5324800,
-                               'VM': 1025978368,
-                               'VMPeak': 1025978368,
-                               'WorkingSetSize': 84000768,
-                               'WorkingSetSizePeak': 84000768})
diff --git a/catapult/telemetry/telemetry/internal/platform/linux_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/linux_platform_backend.py
deleted file mode 100644
index 5532d59..0000000
--- a/catapult/telemetry/telemetry/internal/platform/linux_platform_backend.py
+++ /dev/null
@@ -1,162 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import platform
-import subprocess
-import sys
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.internal.util import binary_manager
-from telemetry.core import os_version
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.platform import linux_based_platform_backend
-from telemetry.internal.platform import posix_platform_backend
-from telemetry.internal.platform.power_monitor import msr_power_monitor
-
-
-_POSSIBLE_PERFHOST_APPLICATIONS = [
-  'perfhost_precise',
-  'perfhost_trusty',
-]
-
-
-class LinuxPlatformBackend(
-    posix_platform_backend.PosixPlatformBackend,
-    linux_based_platform_backend.LinuxBasedPlatformBackend):
-  def __init__(self):
-    super(LinuxPlatformBackend, self).__init__()
-    self._power_monitor = msr_power_monitor.MsrPowerMonitorLinux(self)
-
-  @classmethod
-  def IsPlatformBackendForHost(cls):
-    return sys.platform.startswith('linux') and not util.IsRunningOnCrosDevice()
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  @decorators.Cache
-  def GetArchName(self):
-    return platform.machine()
-
-  def GetOSName(self):
-    return 'linux'
-
-  @decorators.Cache
-  def GetOSVersionName(self):
-    if not os.path.exists('/etc/lsb-release'):
-      raise NotImplementedError('Unknown Linux OS version')
-
-    codename = None
-    version = None
-    for line in self.GetFileContents('/etc/lsb-release').splitlines():
-      key, _, value = line.partition('=')
-      if key == 'DISTRIB_CODENAME':
-        codename = value.strip()
-      elif key == 'DISTRIB_RELEASE':
-        try:
-          version = float(value)
-        except ValueError:
-          version = 0
-      if codename and version:
-        break
-    return os_version.OSVersion(codename, version)
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    return True
-
-  def SupportFlushEntireSystemCache(self):
-    return self.HasRootAccess()
-
-  def FlushEntireSystemCache(self):
-    p = subprocess.Popen(['/sbin/sysctl', '-w', 'vm.drop_caches=3'])
-    p.wait()
-    assert p.returncode == 0, 'Failed to flush system cache'
-
-  def CanLaunchApplication(self, application):
-    if application == 'ipfw' and not self._IsIpfwKernelModuleInstalled():
-      return False
-    return super(LinuxPlatformBackend, self).CanLaunchApplication(application)
-
-  def InstallApplication(self, application):
-    if application == 'ipfw':
-      self._InstallIpfw()
-    elif application == 'avconv':
-      self._InstallBinary(application)
-    elif application in _POSSIBLE_PERFHOST_APPLICATIONS:
-      self._InstallBinary(application)
-    else:
-      raise NotImplementedError(
-          'Please teach Telemetry how to install ' + application)
-
-  def CanMonitorPower(self):
-    return self._power_monitor.CanMonitorPower()
-
-  def CanMeasurePerApplicationPower(self):
-    return self._power_monitor.CanMeasurePerApplicationPower()
-
-  def StartMonitoringPower(self, browser):
-    self._power_monitor.StartMonitoringPower(browser)
-
-  def StopMonitoringPower(self):
-    return self._power_monitor.StopMonitoringPower()
-
-  def ReadMsr(self, msr_number, start=0, length=64):
-    cmd = ['rdmsr', '-d', str(msr_number)]
-    (out, err) = subprocess.Popen(cmd,
-                                  stdout=subprocess.PIPE,
-                                  stderr=subprocess.PIPE).communicate()
-    if err:
-      raise OSError(err)
-    try:
-      result = int(out)
-    except ValueError:
-      raise OSError('Cannot interpret rdmsr output: %s' % out)
-    return result >> start & ((1 << length) - 1)
-
-  def _IsIpfwKernelModuleInstalled(self):
-    return 'ipfw_mod' in subprocess.Popen(
-        ['lsmod'], stdout=subprocess.PIPE).communicate()[0]
-
-  def _InstallIpfw(self):
-    ipfw_bin = binary_manager.FindPath(
-        'ipfw', self.GetArchName(), self.GetOSName())
-    ipfw_mod = binary_manager.FindPath(
-        'ipfw_mod.ko', self.GetArchName(), self.GetOSName())
-
-    try:
-      changed = cloud_storage.GetIfChanged(
-          ipfw_bin, cloud_storage.INTERNAL_BUCKET)
-      changed |= cloud_storage.GetIfChanged(
-          ipfw_mod, cloud_storage.INTERNAL_BUCKET)
-    except cloud_storage.CloudStorageError, e:
-      logging.error(str(e))
-      logging.error('You may proceed by manually building and installing'
-                    'dummynet for your kernel. See: '
-                    'http://info.iet.unipi.it/~luigi/dummynet/')
-      sys.exit(1)
-
-    if changed or not self.CanLaunchApplication('ipfw'):
-      if not self._IsIpfwKernelModuleInstalled():
-        subprocess.check_call(['/usr/bin/sudo', 'insmod', ipfw_mod])
-      os.chmod(ipfw_bin, 0755)
-      subprocess.check_call(
-          ['/usr/bin/sudo', 'cp', ipfw_bin, '/usr/local/sbin'])
-
-    assert self.CanLaunchApplication('ipfw'), 'Failed to install ipfw. ' \
-        'ipfw provided binaries are not supported for linux kernel < 3.13. ' \
-        'You may proceed by manually building and installing dummynet for ' \
-        'your kernel. See: http://info.iet.unipi.it/~luigi/dummynet/'
-
-  def _InstallBinary(self, bin_name):
-    bin_path = binary_manager.FetchPath(
-        bin_name, self.GetArchName(), self.GetOSName())
-    os.environ['PATH'] += os.pathsep + os.path.dirname(bin_path)
-    assert self.CanLaunchApplication(bin_name), 'Failed to install ' + bin_name
diff --git a/catapult/telemetry/telemetry/internal/platform/linux_platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/linux_platform_backend_unittest.py
deleted file mode 100644
index 052d59f..0000000
--- a/catapult/telemetry/telemetry/internal/platform/linux_platform_backend_unittest.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry import decorators
-from telemetry.core import util
-from telemetry.internal.platform import linux_platform_backend
-import mock
-
-
-class LinuxPlatformBackendTest(unittest.TestCase):
-  @decorators.Enabled('linux')
-  def testGetOSVersionNameSaucy(self):
-    path = os.path.join(util.GetUnittestDataDir(), 'ubuntu-saucy-lsb-release')
-    with open(path) as f:
-      unbuntu_saucy_lsb_release_content = f.read()
-
-    with mock.patch.object(
-        linux_platform_backend.LinuxPlatformBackend, 'GetFileContents',
-        return_value=unbuntu_saucy_lsb_release_content) as mock_method:
-      backend = linux_platform_backend.LinuxPlatformBackend()
-      self.assertEqual(backend.GetOSVersionName(), 'saucy')
-      mock_method.assert_called_once_with('/etc/lsb-release')
-
-  @decorators.Enabled('linux')
-  def testGetOSVersionNameArch(self):
-    path = os.path.join(util.GetUnittestDataDir(), 'arch-lsb-release')
-    with open(path) as f:
-      arch_lsb_release_content = f.read()
-
-    with mock.patch.object(
-        linux_platform_backend.LinuxPlatformBackend, 'GetFileContents',
-        return_value=arch_lsb_release_content) as mock_method:
-      backend = linux_platform_backend.LinuxPlatformBackend()
-      # a distribution may not have a codename or a release number. We just
-      # check that GetOSVersionName doesn't raise an exception
-      backend.GetOSVersionName()
-      mock_method.assert_called_once_with('/etc/lsb-release')
diff --git a/catapult/telemetry/telemetry/internal/platform/mac_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/mac_platform_backend.py
deleted file mode 100644
index 168986a..0000000
--- a/catapult/telemetry/telemetry/internal/platform/mac_platform_backend.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import ctypes
-import os
-import platform
-import subprocess
-import sys
-import time
-
-from telemetry.core import os_version as os_version_module
-from telemetry import decorators
-from telemetry.internal.platform import posix_platform_backend
-from telemetry.internal.platform.power_monitor import powermetrics_power_monitor
-from telemetry.util import process_statistic_timeline_data
-
-try:
-  import resource  # pylint: disable=import-error
-except ImportError:
-  resource = None  # Not available on all platforms
-
-
-
-class MacPlatformBackend(posix_platform_backend.PosixPlatformBackend):
-  def __init__(self):
-    super(MacPlatformBackend, self).__init__()
-    self.libproc = None
-    self._power_monitor = powermetrics_power_monitor.PowerMetricsPowerMonitor(
-        self)
-
-  def GetSystemLog(self):
-    # Since the log file can be very large, only show the last 200 lines.
-    return subprocess.check_output(
-        ['tail', '-n', '200', '/var/log/system.log'])
-
-  @classmethod
-  def IsPlatformBackendForHost(cls):
-    return sys.platform == 'darwin'
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def _GetIdleWakeupCount(self, pid):
-    top_output = self._GetTopOutput(pid, ['idlew'])
-
-    # Sometimes top won't return anything here, just ignore such cases -
-    # crbug.com/354812 .
-    if top_output[-2] != 'IDLEW':
-      return process_statistic_timeline_data.IdleWakeupTimelineData(pid, 0)
-    # Numbers reported by top may have a '+' appended.
-    wakeup_count = int(top_output[-1].strip('+ '))
-    return process_statistic_timeline_data.IdleWakeupTimelineData(pid,
-        wakeup_count)
-
-  def GetCpuStats(self, pid):
-    """Returns a dict of cpu statistics for the process represented by |pid|."""
-    class ProcTaskInfo(ctypes.Structure):
-      """Struct for proc_pidinfo() call."""
-      _fields_ = [("pti_virtual_size", ctypes.c_uint64),
-                  ("pti_resident_size", ctypes.c_uint64),
-                  ("pti_total_user", ctypes.c_uint64),
-                  ("pti_total_system", ctypes.c_uint64),
-                  ("pti_threads_user", ctypes.c_uint64),
-                  ("pti_threads_system", ctypes.c_uint64),
-                  ("pti_policy", ctypes.c_int32),
-                  ("pti_faults", ctypes.c_int32),
-                  ("pti_pageins", ctypes.c_int32),
-                  ("pti_cow_faults", ctypes.c_int32),
-                  ("pti_messages_sent", ctypes.c_int32),
-                  ("pti_messages_received", ctypes.c_int32),
-                  ("pti_syscalls_mach", ctypes.c_int32),
-                  ("pti_syscalls_unix", ctypes.c_int32),
-                  ("pti_csw", ctypes.c_int32),
-                  ("pti_threadnum", ctypes.c_int32),
-                  ("pti_numrunning", ctypes.c_int32),
-                  ("pti_priority", ctypes.c_int32)]
-      PROC_PIDTASKINFO = 4
-      def __init__(self):
-        self.size = ctypes.sizeof(self)
-        super(ProcTaskInfo, self).__init__()  # pylint: disable=bad-super-call
-
-    proc_info = ProcTaskInfo()
-    if not self.libproc:
-      self.libproc = ctypes.CDLL(ctypes.util.find_library('libproc'))
-    self.libproc.proc_pidinfo(pid, proc_info.PROC_PIDTASKINFO, 0,
-                              ctypes.byref(proc_info), proc_info.size)
-
-    # Convert nanoseconds to seconds.
-    cpu_time = (proc_info.pti_total_user / 1000000000.0 +
-                proc_info.pti_total_system / 1000000000.0)
-    results = {'CpuProcessTime': cpu_time,
-               'ContextSwitches': proc_info.pti_csw}
-
-    # top only reports idle wakeup count starting from OS X 10.9.
-    if self.GetOSVersionName() >= os_version_module.MAVERICKS:
-      results.update({'IdleWakeupCount': self._GetIdleWakeupCount(pid)})
-    return results
-
-  def GetCpuTimestamp(self):
-    """Return current timestamp in seconds."""
-    return {'TotalTime': time.time()}
-
-  def GetSystemCommitCharge(self):
-    vm_stat = self.RunCommand(['vm_stat'])
-    for stat in vm_stat.splitlines():
-      key, value = stat.split(':')
-      if key == 'Pages active':
-        pages_active = int(value.strip()[:-1])  # Strip trailing '.'
-        return pages_active * resource.getpagesize() / 1024
-    return 0
-
-  @decorators.Cache
-  def GetSystemTotalPhysicalMemory(self):
-    return int(self.RunCommand(['sysctl', '-n', 'hw.memsize']))
-
-  def PurgeUnpinnedMemory(self):
-    # TODO(pliard): Implement this.
-    pass
-
-  @decorators.Deprecated(
-      2017, 11, 4,
-      'Clients should use tracing and memory-infra in new Telemetry '
-      'benchmarks. See for context: https://crbug.com/632021')
-  def GetMemoryStats(self, pid):
-    rss_vsz = self.GetPsOutput(['rss', 'vsz'], pid)
-    if rss_vsz:
-      rss, vsz = rss_vsz[0].split()
-      return {'VM': 1024 * int(vsz),
-              'WorkingSetSize': 1024 * int(rss)}
-    return {}
-
-  @decorators.Cache
-  def GetArchName(self):
-    return platform.machine()
-
-  def GetOSName(self):
-    return 'mac'
-
-  @decorators.Cache
-  def GetOSVersionName(self):
-    os_version = os.uname()[2]
-
-    if os_version.startswith('9.'):
-      return os_version_module.LEOPARD
-    if os_version.startswith('10.'):
-      return os_version_module.SNOWLEOPARD
-    if os_version.startswith('11.'):
-      return os_version_module.LION
-    if os_version.startswith('12.'):
-      return os_version_module.MOUNTAINLION
-    if os_version.startswith('13.'):
-      return os_version_module.MAVERICKS
-    if os_version.startswith('14.'):
-      return os_version_module.YOSEMITE
-    if os_version.startswith('15.'):
-      return os_version_module.ELCAPITAN
-    if os_version.startswith('16.'):
-      return os_version_module.SIERRA
-
-    raise NotImplementedError('Unknown mac version %s.' % os_version)
-
-  def CanTakeScreenshot(self):
-    return True
-
-  def TakeScreenshot(self, file_path):
-    return subprocess.call(['screencapture', file_path])
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    return False
-
-  def SupportFlushEntireSystemCache(self):
-    return self.HasRootAccess()
-
-  def FlushEntireSystemCache(self):
-    mavericks_or_later = self.GetOSVersionName() >= os_version_module.MAVERICKS
-    p = self.LaunchApplication('purge', elevate_privilege=mavericks_or_later)
-    p.communicate()
-    assert p.returncode == 0, 'Failed to flush system cache'
-
-  def CanMonitorPower(self):
-    return self._power_monitor.CanMonitorPower()
-
-  def CanMeasurePerApplicationPower(self):
-    return self._power_monitor.CanMeasurePerApplicationPower()
-
-  def StartMonitoringPower(self, browser):
-    self._power_monitor.StartMonitoringPower(browser)
-
-  def StopMonitoringPower(self):
-    return self._power_monitor.StopMonitoringPower()
diff --git a/catapult/telemetry/telemetry/internal/platform/mac_platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/mac_platform_backend_unittest.py
deleted file mode 100644
index c3b67bc..0000000
--- a/catapult/telemetry/telemetry/internal/platform/mac_platform_backend_unittest.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry.core import platform as platform_module
-from telemetry.core import os_version
-from telemetry import decorators
-
-
-class MacPlatformBackendTest(unittest.TestCase):
-  def testVersionCamparison(self):
-    self.assertGreater(os_version.YOSEMITE, os_version.MAVERICKS)
-    self.assertGreater(os_version.MAVERICKS, os_version.SNOWLEOPARD)
-    self.assertGreater(os_version.LION, os_version.LEOPARD)
-    self.assertEqual(os_version.YOSEMITE, 'yosemite')
-    self.assertEqual(os_version.MAVERICKS, 'mavericks')
-    self.assertEqual('%s2' % os_version.MAVERICKS, 'mavericks2')
-    self.assertEqual(''.join([os_version.MAVERICKS, '2']),
-                     'mavericks2')
-    self.assertEqual(os_version.LION.upper(), 'LION')
-
-  @decorators.Enabled('mac')
-  def testGetCPUStats(self):
-    platform = platform_module.GetHostPlatform()
-
-    backend = platform._platform_backend # pylint: disable=protected-access
-
-    cpu_stats = backend.GetCpuStats(os.getpid())
-    self.assertGreater(cpu_stats['CpuProcessTime'], 0)
-    self.assertTrue(cpu_stats.has_key('ContextSwitches'))
-    if backend.GetOSVersionName() >= os_version.MAVERICKS:
-      self.assertTrue(cpu_stats.has_key('IdleWakeupCount'))
-
-  @decorators.Enabled('mac')
-  def testGetSystemLogSmoke(self):
-    platform = platform_module.GetHostPlatform()
-    self.assertTrue(platform.GetSystemLog())
diff --git a/catapult/telemetry/telemetry/internal/platform/msr_server_win.py b/catapult/telemetry/telemetry/internal/platform/msr_server_win.py
deleted file mode 100644
index 087407b..0000000
--- a/catapult/telemetry/telemetry/internal/platform/msr_server_win.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A server that serves MSR values over TCP. Takes a port as its sole parameter.
-
-The reference client for this server is msr_power_monitor.MsrPowerMonitor.
-
-Must be run as Administrator. We use TCP instead of named pipes or another IPC
-to avoid dealing with the pipe security mechanisms. We take the port as a
-parameter instead of choosing one, because it's hard to communicate the port
-number across integrity levels.
-
-Requires WinRing0 to be installed in the Python directory.
-msr_power_monitor.MsrPowerMonitor does this if needed.
-"""
-
-import argparse
-import ctypes
-import os
-import SocketServer
-import struct
-import sys
-try:
-  import win32api  # pylint: disable=import-error
-  import win32file  # pylint: disable=import-error
-except ImportError:
-  win32api = None
-  win32file = None
-
-
-WINRING0_STATUS_MESSAGES = (
-    'No error',
-    'Unsupported platform',
-    'Driver not loaded. You may need to run as Administrator',
-    'Driver not found',
-    'Driver unloaded by other process',
-    'Driver not loaded because of executing on Network Drive',
-    'Unknown error',
-)
-
-
-# The DLL initialization is global, so put it in a global variable.
-_winring0 = None
-
-
-class WinRing0Error(OSError):
-  pass
-
-
-def _WinRing0Path():
-  python_is_64_bit = sys.maxsize > 2 ** 32
-  dll_file_name = 'WinRing0x64.dll' if python_is_64_bit else 'WinRing0.dll'
-  return os.path.join(os.path.dirname(sys.executable), dll_file_name)
-
-
-def _Initialize():
-  global _winring0
-  if not _winring0:
-    winring0 = ctypes.WinDLL(_WinRing0Path())
-    if not winring0.InitializeOls():
-      winring0_status = winring0.GetDllStatus()
-      raise WinRing0Error(winring0_status,
-                          'Unable to initialize WinRing0: %s' %
-                          WINRING0_STATUS_MESSAGES[winring0_status])
-    _winring0 = winring0
-
-
-def _Deinitialize():
-  global _winring0
-  if _winring0:
-    _winring0.DeinitializeOls()
-    _winring0 = None
-
-
-def _ReadMsr(msr_number):
-  low = ctypes.c_uint()
-  high = ctypes.c_uint()
-  _winring0.Rdmsr(ctypes.c_uint(msr_number),
-                  ctypes.byref(low), ctypes.byref(high))
-  return high.value << 32 | low.value
-
-
-class MsrRequestHandler(SocketServer.StreamRequestHandler):
-  def handle(self):
-    msr_number = struct.unpack('I', self.rfile.read(4))[0]
-    self.wfile.write(struct.pack('Q', _ReadMsr(msr_number)))
-
-
-def main():
-  parser = argparse.ArgumentParser()
-  parser.add_argument('pipe_name', type=str)
-  args = parser.parse_args()
-
-  _Initialize()
-  try:
-    SocketServer.TCPServer.allow_reuse_address = True
-    server_address = ('127.0.0.1', 0)
-    server = SocketServer.TCPServer(server_address, MsrRequestHandler)
-    handle = win32file.CreateFile(args.pipe_name,
-                                  win32file.GENERIC_WRITE,
-                                  0, None,
-                                  win32file.OPEN_EXISTING,
-                                  0, None)
-    _, port = server.server_address
-    win32file.WriteFile(handle, str(port))
-    win32api.CloseHandle(handle)
-    server.serve_forever()
-  finally:
-    _Deinitialize()
-
-
-if __name__ == '__main__':
-  main()
diff --git a/catapult/telemetry/telemetry/internal/platform/network_controller_backend.py b/catapult/telemetry/telemetry/internal/platform/network_controller_backend.py
deleted file mode 100644
index 052be07..0000000
--- a/catapult/telemetry/telemetry/internal/platform/network_controller_backend.py
+++ /dev/null
@@ -1,280 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import shutil
-import tempfile
-
-from telemetry.internal.util import wpr_server
-from telemetry.internal.util import ts_proxy_server
-from telemetry.util import wpr_modes
-
-import certutils
-import platformsettings
-
-
-class ArchiveDoesNotExistError(Exception):
-  """Raised when the archive path does not exist for replay mode."""
-  pass
-
-
-class ReplayAndBrowserPortsError(Exception):
-  """Raised an existing browser would get different remote replay ports."""
-  pass
-
-
-class NetworkControllerBackend(object):
-  """Control network settings and servers to simulate the Web.
-
-  Network changes include forwarding device ports to host platform ports.
-  Web Page Replay is used to record and replay HTTP/HTTPS responses.
-  """
-
-  def __init__(self, platform_backend):
-    self._platform_backend = platform_backend
-    self._wpr_mode = None
-    self._extra_wpr_args = None
-    self._archive_path = None
-    self._make_javascript_deterministic = None
-    self._forwarder = None
-    self._wpr_ca_cert_path = None
-    self._wpr_server = None
-    self._ts_proxy_server = None
-    self._port_pair = None
-    self._use_live_traffic = None
-
-  def InitializeIfNeeded(self, use_live_traffic):
-    """
-    This may, e.g., install test certificates and perform any needed setup
-    on the target platform.
-
-    After network interactions are over, clients should call the Close method.
-    """
-    if self._use_live_traffic is None:
-      self._use_live_traffic = use_live_traffic
-    assert self._use_live_traffic == use_live_traffic, (
-        'inconsistent state of use_live_traffic')
-    assert bool(self._ts_proxy_server) == bool(self._forwarder)
-    if self._ts_proxy_server:
-      return
-    local_port = self._StartTsProxyServer(self._use_live_traffic)
-    self._forwarder = self._platform_backend.forwarder_factory.Create(
-        self._platform_backend.GetPortPairForForwarding(local_port))
-
-  @property
-  def is_open(self):
-    return self._wpr_mode is not None
-
-  @property
-  def is_initialized(self):
-    return self._forwarder is not None
-
-  @property
-  def host_ip(self):
-    return self._platform_backend.forwarder_factory.host_ip
-
-  @property
-  def wpr_device_ports(self):
-    try:
-      return self._forwarder.port_pairs.remote_ports
-    except AttributeError:
-      return None
-
-  @property
-  def is_test_ca_installed(self):
-    return self._wpr_ca_cert_path is not None
-
-  def Open(self, wpr_mode, extra_wpr_args):
-    """Configure and prepare target platform for network control.
-
-    This may, e.g., install test certificates and perform any needed setup
-    on the target platform.
-
-    After network interactions are over, clients should call the Close method.
-
-    Args:
-      wpr_mode: a mode for web page replay; available modes are
-          wpr_modes.WPR_OFF, wpr_modes.APPEND, wpr_modes.WPR_REPLAY, or
-          wpr_modes.WPR_RECORD.
-      extra_wpr_args: an list of extra arguments for web page replay.
-    """
-    assert not self.is_open, 'Network controller is already open'
-    self._wpr_mode = wpr_mode
-    self._extra_wpr_args = extra_wpr_args
-    self._InstallTestCa()
-
-  def Close(self):
-    """Undo changes in the target platform used for network control.
-
-    Implicitly stops replay if currently active.
-    """
-    self.StopReplay()
-    self._StopForwarder()
-    self._StopTsProxyServer()
-    self._RemoveTestCa()
-    self._make_javascript_deterministic = None
-    self._archive_path = None
-    self._extra_wpr_args = None
-    self._wpr_mode = None
-
-  def _InstallTestCa(self):
-    if not self._platform_backend.supports_test_ca:
-      return
-    assert not self.is_test_ca_installed, 'Test CA is already installed'
-    if certutils.openssl_import_error:
-      logging.warning(
-          'The OpenSSL module is unavailable. '
-          'Browsers may fall back to ignoring certificate errors.')
-      return
-    if not platformsettings.HasSniSupport():
-      logging.warning(
-          'Web Page Replay requires SNI support (pyOpenSSL 0.13 or greater) '
-          'to generate certificates from a test CA. '
-          'Browsers may fall back to ignoring certificate errors.')
-      return
-    self._wpr_ca_cert_path = os.path.join(tempfile.mkdtemp(), 'testca.pem')
-    try:
-      certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(),
-                                    cert_path=self._wpr_ca_cert_path)
-      self._platform_backend.InstallTestCa(self._wpr_ca_cert_path)
-      logging.info('Test certificate authority installed on target platform.')
-    except Exception:
-      logging.exception(
-          'Failed to install test certificate authority on target platform. '
-          'Browsers may fall back to ignoring certificate errors.')
-      self._RemoveTestCa()
-
-  def _RemoveTestCa(self):
-    if not self.is_test_ca_installed:
-      return
-    try:
-      self._platform_backend.RemoveTestCa()
-    except Exception:
-      # Best effort cleanup - show the error and continue.
-      logging.exception(
-          'Error trying to remove certificate authority from target platform.')
-    try:
-      shutil.rmtree(os.path.dirname(self._wpr_ca_cert_path), ignore_errors=True)
-    finally:
-      self._wpr_ca_cert_path = None
-
-  def StartReplay(self, archive_path, make_javascript_deterministic=False):
-    """Start web page replay from a given replay archive.
-
-    Starts as needed, and reuses if possible, the replay server on the host and
-    a forwarder from the host to the target platform.
-
-    Implementation details
-    ----------------------
-
-    The local host is where Telemetry is run. The remote is host where
-    the target application is run. The local and remote hosts may be
-    the same (e.g., testing a desktop browser) or different (e.g., testing
-    an android browser).
-
-    A replay server is started on the local host using the local ports, while
-    a forwarder ties the local to the remote ports.
-
-    Both local and remote ports may be zero. In that case they are determined
-    by the replay server and the forwarder respectively. Setting dns to None
-    disables DNS traffic.
-
-    Args:
-      archive_path: a path to a specific WPR archive.
-      make_javascript_deterministic: True if replay should inject a script
-          to make JavaScript behave deterministically (e.g., override Date()).
-    """
-    assert self.is_open, 'Network controller is not open'
-    if self._wpr_mode == wpr_modes.WPR_OFF:
-      return
-    if not archive_path:
-      # TODO(slamm, tonyg): Ideally, replay mode should be stopped when there is
-      # no archive path. However, if the replay server already started, and
-      # a file URL is tested with the
-      # telemetry.core.local_server.LocalServerController, then the
-      # replay server forwards requests to it. (Chrome is configured to use
-      # fixed ports fo all HTTP/HTTPS requests.)
-      return
-    if (self._wpr_mode == wpr_modes.WPR_REPLAY and
-        not os.path.exists(archive_path)):
-      raise ArchiveDoesNotExistError(
-          'Archive path does not exist: %s' % archive_path)
-    if (self._wpr_server is not None and
-        self._archive_path == archive_path and
-        self._make_javascript_deterministic == make_javascript_deterministic):
-      return  # We may reuse the existing replay server.
-
-    self._archive_path = archive_path
-    self._make_javascript_deterministic = make_javascript_deterministic
-    local_ports = self._StartReplayServer()
-    self._ts_proxy_server.UpdateOutboundPorts(
-        http_port=local_ports.http, https_port=local_ports.https)
-
-  def _StopForwarder(self):
-    if self._forwarder:
-      self._forwarder.Close()
-      self._forwarder = None
-
-  def StopReplay(self):
-    """Stop web page replay.
-
-    Stops both the replay server and the forwarder if currently active.
-    """
-    self._StopReplayServer()
-
-  def _StartReplayServer(self):
-    """Start the replay server and return the started local_ports."""
-    self._StopReplayServer()  # In case it was already running.
-    self._wpr_server = wpr_server.ReplayServer(
-        self._archive_path,
-        self.host_ip,
-        http_port=0,
-        https_port=0,
-        dns_port=None,
-        replay_options=self._ReplayCommandLineArgs())
-    return self._wpr_server.StartServer()
-
-  def _StopReplayServer(self):
-    """Stop the replay server only."""
-    if self._wpr_server:
-      self._wpr_server.StopServer()
-      self._wpr_server = None
-
-  def _StopTsProxyServer(self):
-    """Stop the replay server only."""
-    if self._ts_proxy_server:
-      self._ts_proxy_server.StopServer()
-      self._ts_proxy_server = None
-
-  def _ReplayCommandLineArgs(self):
-    wpr_args = list(self._extra_wpr_args)
-    if self._wpr_mode == wpr_modes.WPR_APPEND:
-      wpr_args.append('--append')
-    elif self._wpr_mode == wpr_modes.WPR_RECORD:
-      wpr_args.append('--record')
-    if not self._make_javascript_deterministic:
-      wpr_args.append('--inject_scripts=')
-    if self._wpr_ca_cert_path:
-      wpr_args.extend([
-          '--should_generate_certs',
-          '--https_root_ca_cert_path=%s' % self._wpr_ca_cert_path])
-    return wpr_args
-
-  def _StartTsProxyServer(self, use_live_traffic):
-    assert not self._ts_proxy_server, 'ts_proxy_server is already started'
-    host_ip = None
-    if not use_live_traffic:
-      host_ip = self.host_ip
-    self._ts_proxy_server = ts_proxy_server.TsProxyServer(host_ip=host_ip)
-    self._ts_proxy_server.StartServer()
-    return self._ts_proxy_server.port
-
-  @property
-  def forwarder(self):
-    return self._forwarder
-
-  @property
-  def ts_proxy_server(self):
-    return self._ts_proxy_server
diff --git a/catapult/telemetry/telemetry/internal/platform/platform_backend.py b/catapult/telemetry/telemetry/internal/platform/platform_backend.py
deleted file mode 100644
index 9ca19a4..0000000
--- a/catapult/telemetry/telemetry/internal/platform/platform_backend.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import weakref
-
-from battor import battor_wrapper
-from telemetry.internal import forwarders
-from telemetry.internal.forwarders import do_nothing_forwarder
-from telemetry.internal.platform import network_controller_backend
-from telemetry.internal.platform import tracing_controller_backend
-
-
-# pylint: disable=unused-argument
-
-class PlatformBackend(object):
-
-  def __init__(self, device=None):
-    """ Initalize an instance of PlatformBackend from a device optionally.
-      Call sites need to use SupportsDevice before intialization to check
-      whether this platform backend supports the device.
-      If device is None, this constructor returns the host platform backend
-      which telemetry is running on.
-
-      Args:
-        device: an instance of telemetry.core.platform.device.Device.
-    """
-    if device and not self.SupportsDevice(device):
-      raise ValueError('Unsupported device: %s' % device.name)
-    self._platform = None
-    self._running_browser_backends = weakref.WeakSet()
-    self._network_controller_backend = None
-    self._tracing_controller_backend = None
-    self._forwarder_factory = None
-
-  def InitPlatformBackend(self):
-    self._network_controller_backend = (
-        network_controller_backend.NetworkControllerBackend(self))
-    self._tracing_controller_backend = (
-        tracing_controller_backend.TracingControllerBackend(self))
-
-  @classmethod
-  def IsPlatformBackendForHost(cls):
-    """ Returns whether this platform backend is the platform backend to be used
-    for the host device which telemetry is running on. """
-    return False
-
-  @classmethod
-  def SupportsDevice(cls, device):
-    """ Returns whether this platform backend supports intialization from the
-    device. """
-    return False
-
-  @classmethod
-  def CreatePlatformForDevice(cls, device, finder_options):
-    raise NotImplementedError
-
-  def SetPlatform(self, platform):
-    assert self._platform == None
-    self._platform = platform
-
-  @property
-  def platform(self):
-    return self._platform
-
-  @property
-  def is_host_platform(self):
-    return self._platform.is_host_platform
-
-  @property
-  def running_browser_backends(self):
-    return list(self._running_browser_backends)
-
-  @property
-  def network_controller_backend(self):
-    return self._network_controller_backend
-
-  @property
-  def tracing_controller_backend(self):
-    return self._tracing_controller_backend
-
-  @property
-  def forwarder_factory(self):
-    if not self._forwarder_factory:
-      self._forwarder_factory = do_nothing_forwarder.DoNothingForwarderFactory()
-    return self._forwarder_factory
-
-  def GetPortPairForForwarding(self, local_port):
-    return forwarders.PortPair(local_port=local_port, remote_port=local_port)
-
-  def GetRemotePort(self, port):
-    return port
-
-  def GetSystemLog(self):
-    return None
-
-  def DidCreateBrowser(self, browser, browser_backend):
-    browser_options = browser_backend.browser_options
-    self.SetFullPerformanceModeEnabled(browser_options.full_performance_mode)
-
-  def DidStartBrowser(self, browser, browser_backend):
-    assert browser not in self._running_browser_backends
-    self._running_browser_backends.add(browser_backend)
-
-  def WillCloseBrowser(self, browser, browser_backend):
-    is_last_browser = len(self._running_browser_backends) <= 1
-    if is_last_browser:
-      self.SetFullPerformanceModeEnabled(False)
-
-    self._running_browser_backends.discard(browser_backend)
-
-  def IsDisplayTracingSupported(self):
-    return False
-
-  def StartDisplayTracing(self):
-    """Start gathering a trace with frame timestamps close to physical
-    display."""
-    raise NotImplementedError()
-
-  def StopDisplayTracing(self):
-    """Stop gathering a trace with frame timestamps close to physical display.
-
-    Returns a raw tracing events that contains the timestamps of physical
-    display.
-    """
-    raise NotImplementedError()
-
-  def SetFullPerformanceModeEnabled(self, enabled):
-    pass
-
-  def CanMonitorThermalThrottling(self):
-    return False
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def GetSystemCommitCharge(self):
-    raise NotImplementedError()
-
-  def GetSystemTotalPhysicalMemory(self):
-    raise NotImplementedError()
-
-  def GetCpuStats(self, pid):
-    return {}
-
-  def GetCpuTimestamp(self):
-    return {}
-
-  def PurgeUnpinnedMemory(self):
-    pass
-
-  def GetMemoryStats(self, pid):
-    return {}
-
-  def GetChildPids(self, pid):
-    raise NotImplementedError()
-
-  def GetCommandLine(self, pid):
-    raise NotImplementedError()
-
-  def GetDeviceTypeName(self):
-    raise NotImplementedError()
-
-  def GetArchName(self):
-    raise NotImplementedError()
-
-  def GetOSName(self):
-    raise NotImplementedError()
-
-  def GetOSVersionName(self):
-    raise NotImplementedError()
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    raise NotImplementedError()
-
-  def SupportFlushEntireSystemCache(self):
-    return False
-
-  def FlushEntireSystemCache(self):
-    raise NotImplementedError()
-
-  def FlushSystemCacheForDirectory(self, directory):
-    raise NotImplementedError()
-
-  def FlushDnsCache(self):
-    pass
-
-  def LaunchApplication(
-      self, application, parameters=None, elevate_privilege=False):
-    raise NotImplementedError()
-
-  def IsApplicationRunning(self, application):
-    raise NotImplementedError()
-
-  def CanLaunchApplication(self, application):
-    return False
-
-  def InstallApplication(self, application):
-    raise NotImplementedError()
-
-  def CanCaptureVideo(self):
-    return False
-
-  def StartVideoCapture(self, min_bitrate_mbps):
-    raise NotImplementedError()
-
-  @property
-  def is_video_capture_running(self):
-    return False
-
-  def StopVideoCapture(self):
-    raise NotImplementedError()
-
-  def CanMonitorPower(self):
-    return False
-
-  def CanMeasurePerApplicationPower(self):
-    return False
-
-  def StartMonitoringPower(self, browser):
-    raise NotImplementedError()
-
-  def StopMonitoringPower(self):
-    raise NotImplementedError()
-
-  def CanMonitorNetworkData(self):
-    return False
-
-  def GetNetworkData(self, browser):
-    raise NotImplementedError()
-
-  def ReadMsr(self, msr_number, start=0, length=64):
-    """Read a CPU model-specific register (MSR).
-
-    Which MSRs are available depends on the CPU model.
-    On systems with multiple CPUs, this function may run on any CPU.
-
-    Args:
-      msr_number: The number of the register to read.
-      start: The least significant bit to read, zero-indexed.
-          (Said another way, the number of bits to right-shift the MSR value.)
-      length: The number of bits to read. MSRs are 64 bits, even on 32-bit CPUs.
-    """
-    raise NotImplementedError()
-
-  @property
-  def supports_test_ca(self):
-    """Indicates whether the platform supports installing test CA."""
-    return False
-
-  def InstallTestCa(self, ca_cert_path):
-    """Install a test CA on the platform."""
-    raise NotImplementedError()
-
-  def RemoveTestCa(self):
-    """Remove a previously installed test CA from the platform."""
-    raise NotImplementedError()
-
-  def CanTakeScreenshot(self):
-    return False
-
-  def TakeScreenshot(self, file_path):
-    raise NotImplementedError
-
-  def IsCooperativeShutdownSupported(self):
-    """Indicates whether CooperativelyShutdown, below, is supported.
-    It is not necessary to implement it on all platforms."""
-    return False
-
-  def CooperativelyShutdown(self, proc, app_name):
-    """Cooperatively shut down the given process from subprocess.Popen.
-
-    Currently this is only implemented on Windows. See
-    crbug.com/424024 for background on why it was added.
-
-    Args:
-      proc: a process object returned from subprocess.Popen.
-      app_name: on Windows, is the prefix of the application's window
-          class name that should be searched for. This helps ensure
-          that only the application's windows are closed.
-
-    Returns True if it is believed the attempt succeeded.
-    """
-    raise NotImplementedError()
-
-  def PathExists(self, path, timeout=None, retries=None):
-    """Tests whether the given path exists on the target platform.
-    Args:
-      path: path in request.
-      timeout: timeout.
-      retries: num of retries.
-    Return:
-      Whether the path exists on the target platform.
-    """
-    raise NotImplementedError()
-
-  def HasBattOrConnected(self):
-    return battor_wrapper.IsBattOrConnected(self.GetOSName())
-
-  def WaitForTemperature(self, temp):
-    """Waits for device under test to cool down to temperature given.
-    Args:
-      temp: temperature target in degrees C.
-    """
-    pass
diff --git a/catapult/telemetry/telemetry/internal/platform/platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/platform_backend_unittest.py
deleted file mode 100644
index b2d3b83..0000000
--- a/catapult/telemetry/telemetry/internal/platform/platform_backend_unittest.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-import unittest
-
-from telemetry.core import platform as platform_module
-from telemetry import decorators
-
-
-class PlatformBackendTest(unittest.TestCase):
-  @decorators.Disabled('mac',       # crbug.com/440666
-                       'vista',     # crbug.com/479337
-                       'chromeos',  # crbug.com/483212
-                       'win')       # catapult/issues/2282
-  def testPowerMonitoringSync(self):
-    # Tests that the act of monitoring power doesn't blow up.
-    platform = platform_module.GetHostPlatform()
-    can_monitor_power = platform.CanMonitorPower()
-    self.assertIsInstance(can_monitor_power, bool)
-    if not can_monitor_power:
-      logging.warning('Test not supported on this platform.')
-      return
-
-    browser_mock = lambda: None
-    # Android needs to access the package of the monitored app.
-    if platform.GetOSName() == 'android':
-      # pylint: disable=protected-access
-      browser_mock._browser_backend = lambda: None
-      # Monitor the launcher, which is always present.
-      browser_mock._browser_backend.package = 'com.android.launcher'
-
-    platform.StartMonitoringPower(browser_mock)
-    time.sleep(0.001)
-    output = platform.StopMonitoringPower()
-    self.assertTrue(output.has_key('energy_consumption_mwh'))
-    self.assertTrue(output.has_key('identifier'))
diff --git a/catapult/telemetry/telemetry/internal/platform/posix_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/posix_platform_backend.py
deleted file mode 100644
index aeb4c19..0000000
--- a/catapult/telemetry/telemetry/internal/platform/posix_platform_backend.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import distutils.spawn
-import logging
-import os
-import re
-import stat
-import subprocess
-import sys
-
-from telemetry.internal.platform import desktop_platform_backend
-from telemetry.internal.util import ps_util
-
-
-def _BinaryExistsInSudoersFiles(path, sudoers_file_contents):
-  """Returns True if the binary in |path| features in the sudoers file.
-  """
-  for line in sudoers_file_contents.splitlines():
-    if re.match(r'\s*\(.+\) NOPASSWD: %s(\s\S+)*$' % re.escape(path), line):
-      return True
-  return False
-
-
-def _CanRunElevatedWithSudo(path):
-  """Returns True if the binary at |path| appears in the sudoers file.
-  If this function returns true then the binary at |path| can be run via sudo
-  without prompting for a password.
-  """
-  sudoers = subprocess.check_output(['/usr/bin/sudo', '-l'])
-  return _BinaryExistsInSudoersFiles(path, sudoers)
-
-
-class PosixPlatformBackend(desktop_platform_backend.DesktopPlatformBackend):
-
-  # This is an abstract class. It is OK to have abstract methods.
-  # pylint: disable=abstract-method
-
-  def HasRootAccess(self):
-    return os.getuid() == 0
-
-  def RunCommand(self, args):
-    return subprocess.Popen(args, stdout=subprocess.PIPE).communicate()[0]
-
-  def GetFileContents(self, path):
-    with open(path, 'r') as f:
-      return f.read()
-
-  def GetPsOutput(self, columns, pid=None):
-    """Returns output of the 'ps' command as a list of lines.
-    Subclass should override this function.
-
-    Args:
-      columns: A list of require columns, e.g., ['pid', 'pss'].
-      pid: If not None, returns only the information of the process
-         with the pid.
-    """
-    return ps_util.GetPsOutputWithPlatformBackend(self, columns, pid)
-
-  def _GetTopOutput(self, pid, columns):
-    """Returns output of the 'top' command as a list of lines.
-
-    Args:
-      pid: pid of process to examine.
-      columns: A list of require columns, e.g., ['idlew', 'vsize'].
-    """
-    args = ['top']
-    args.extend(['-pid', str(pid), '-l', '1', '-s', '0', '-stats',
-        ','.join(columns)])
-    return self.RunCommand(args).splitlines()
-
-  def GetChildPids(self, pid):
-    """Returns a list of child pids of |pid|."""
-    ps_output = self.GetPsOutput(['pid', 'ppid', 'state'])
-    ps_line_re = re.compile(
-        r'\s*(?P<pid>\d+)\s*(?P<ppid>\d+)\s*(?P<state>\S*)\s*')
-    processes = []
-    for pid_ppid_state in ps_output:
-      m = ps_line_re.match(pid_ppid_state)
-      assert m, 'Did not understand ps output: %s' % pid_ppid_state
-      processes.append((m.group('pid'), m.group('ppid'), m.group('state')))
-    return ps_util.GetChildPids(processes, pid)
-
-  def GetCommandLine(self, pid):
-    command = self.GetPsOutput(['command'], pid)
-    return command[0] if command else None
-
-  def CanLaunchApplication(self, application):
-    return bool(distutils.spawn.find_executable(application))
-
-  def IsApplicationRunning(self, application):
-    ps_output = self.GetPsOutput(['command'])
-    application_re = re.compile(
-        r'(.*%s|^)%s(\s|$)' % (os.path.sep, application))
-    return any(application_re.match(cmd) for cmd in ps_output)
-
-  def LaunchApplication(
-      self, application, parameters=None, elevate_privilege=False):
-    assert application, 'Must specify application to launch'
-
-    if os.path.sep not in application:
-      application = distutils.spawn.find_executable(application)
-      assert application, 'Failed to find application in path'
-
-    args = [application]
-
-    if parameters:
-      assert isinstance(parameters, list), 'parameters must be a list'
-      args += parameters
-
-    def IsElevated():
-      """ Returns True if the current process is elevated via sudo i.e. running
-      sudo will not prompt for a password. Returns False if not authenticated
-      via sudo or if telemetry is run on a non-interactive TTY."""
-      # `sudo -v` will always fail if run from a non-interactive TTY.
-      p = subprocess.Popen(
-          ['/usr/bin/sudo', '-nv'], stdin=subprocess.PIPE,
-          stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-      stdout = p.communicate()[0]
-      # Some versions of sudo set the returncode based on whether sudo requires
-      # a password currently. Other versions return output when password is
-      # required and no output when the user is already authenticated.
-      return not p.returncode and not stdout
-
-    def IsSetUID(path):
-      """Returns True if the binary at |path| has the setuid bit set."""
-      return (os.stat(path).st_mode & stat.S_ISUID) == stat.S_ISUID
-
-    if elevate_privilege and not IsSetUID(application):
-      args = ['/usr/bin/sudo'] + args
-      if not _CanRunElevatedWithSudo(application) and not IsElevated():
-        if not sys.stdout.isatty():
-          # Without an interactive terminal (or a configured 'askpass', but
-          # that is rarely relevant), there's no way to prompt the user for
-          # sudo. Fail with a helpful error message. For more information, see:
-          #   https://code.google.com/p/chromium/issues/detail?id=426720
-          text = ('Telemetry needs to run %s with elevated privileges, but the '
-                 'setuid bit is not set and there is no interactive terminal '
-                 'for a prompt. Please ask an administrator to set the setuid '
-                 'bit on this executable and ensure that it is owned by a user '
-                 'with the necessary privileges. Aborting.' % application)
-          print text
-          raise Exception(text)
-        # Else, there is a tty that can be used for a useful interactive prompt.
-        print ('Telemetry needs to run %s under sudo. Please authenticate.' %
-               application)
-        # Synchronously authenticate.
-        subprocess.check_call(['/usr/bin/sudo', '-v'])
-
-    stderror_destination = subprocess.PIPE
-    if logging.getLogger().isEnabledFor(logging.DEBUG):
-      stderror_destination = None
-
-    return subprocess.Popen(
-        args, stdout=subprocess.PIPE, stderr=stderror_destination)
diff --git a/catapult/telemetry/telemetry/internal/platform/posix_platform_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/posix_platform_backend_unittest.py
deleted file mode 100644
index e139980..0000000
--- a/catapult/telemetry/telemetry/internal/platform/posix_platform_backend_unittest.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import sys
-import unittest
-
-from telemetry.core import platform as platform_module
-from telemetry import decorators
-from telemetry.internal.platform import posix_platform_backend
-
-
-class TestBackend(posix_platform_backend.PosixPlatformBackend):
-
-  # pylint: disable=abstract-method
-
-  def __init__(self):
-    super(TestBackend, self).__init__()
-    self._mock_ps_output = None
-
-  def SetMockPsOutput(self, output):
-    self._mock_ps_output = output
-
-  def GetPsOutput(self, columns, pid=None):
-    return self._mock_ps_output
-
-
-class PosixPlatformBackendTest(unittest.TestCase):
-
-  def testGetChildPidsWithGrandChildren(self):
-    backend = TestBackend()
-    backend.SetMockPsOutput(['1 0 S', '2 1 R', '3 2 S', '4 1 R', '5 4 R'])
-    result = backend.GetChildPids(1)
-    self.assertEquals(set(result), set([2, 3, 4, 5]))
-
-  def testGetChildPidsWithNoSuchPid(self):
-    backend = TestBackend()
-    backend.SetMockPsOutput(['1 0 S', '2 1 R', '3 2 S', '4 1 R', '5 4 R'])
-    result = backend.GetChildPids(6)
-    self.assertEquals(set(result), set())
-
-  def testGetChildPidsWithZombieChildren(self):
-    backend = TestBackend()
-    backend.SetMockPsOutput(['1 0 S', '2 1 R', '3 2 S', '4 1 R', '5 4 Z'])
-    result = backend.GetChildPids(1)
-    self.assertEquals(set(result), set([2, 3, 4]))
-
-  def testGetChildPidsWithMissingState(self):
-    backend = TestBackend()
-    backend.SetMockPsOutput(['  1 0 S  ', '  2 1', '3 2 '])
-    result = backend.GetChildPids(1)
-    self.assertEquals(set(result), set([2, 3]))
-
-  def testSudoersFileParsing(self):
-    binary_path = '/usr/bin/pkill'
-    self.assertFalse(
-        posix_platform_backend._BinaryExistsInSudoersFiles(binary_path, ''))
-    self.assertFalse(
-        posix_platform_backend._BinaryExistsInSudoersFiles(
-            binary_path, '    (ALL) ALL'))
-    self.assertFalse(
-        posix_platform_backend._BinaryExistsInSudoersFiles(
-            binary_path, '     (root) NOPASSWD: /usr/bin/pkill_DUMMY'))
-    self.assertFalse(
-        posix_platform_backend._BinaryExistsInSudoersFiles(
-            binary_path, '     (root) NOPASSWD: pkill'))
-
-
-    self.assertTrue(
-        posix_platform_backend._BinaryExistsInSudoersFiles(
-            binary_path, '(root) NOPASSWD: /usr/bin/pkill'))
-    self.assertTrue(
-        posix_platform_backend._BinaryExistsInSudoersFiles(
-            binary_path, '     (root) NOPASSWD: /usr/bin/pkill'))
-    self.assertTrue(
-        posix_platform_backend._BinaryExistsInSudoersFiles(
-            binary_path, '     (root) NOPASSWD: /usr/bin/pkill arg1 arg2'))
-
-  @decorators.Enabled('linux', 'mac')
-  def testIsApplicationRunning(self):
-    platform = platform_module.GetHostPlatform()
-
-    self.assertFalse(platform.IsApplicationRunning('This_Is_A_Bad___App__Name'))
-    sys_exe = os.path.basename(sys.executable)
-    self.assertTrue(platform.IsApplicationRunning(sys_exe))
-    self.assertFalse(
-        platform.IsApplicationRunning('%s append_bad_after_space' % sys_exe))
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/__init__.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/__init__.py
deleted file mode 100644
index 4c3cf45..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/__init__.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.core import exceptions
-
-
-class PowerMonitor(object):
-  """A power profiler.
-
-  Provides an interface to register power consumption during a test.
-  """
-  def __init__(self):
-    self._monitoring = False
-
-  def CanMonitorPower(self):
-    """Returns True iff power can be monitored asynchronously via
-    StartMonitoringPower() and StopMonitoringPower().
-    """
-    return False
-
-  def CanMeasurePerApplicationPower(self):
-    """Returns True if the power monitor can measure power for the target
-    application in isolation. False if power measurement is for full system
-    energy consumption."""
-    return False
-
-  def _CheckStart(self):
-    assert not self._monitoring, "Already monitoring power."
-    self._monitoring = True
-
-  def _CheckStop(self):
-    assert self._monitoring, "Not monitoring power."
-    self._monitoring = False
-
-  def StartMonitoringPower(self, browser):
-    """Starts monitoring power utilization statistics.
-
-    See Platform#StartMonitoringPower for the arguments format.
-    """
-    raise NotImplementedError()
-
-  def StopMonitoringPower(self):
-    """Stops monitoring power utilization and returns collects stats
-
-    See Platform#StopMonitoringPower for the return format.
-    """
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor.py
deleted file mode 100644
index 2983777..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import csv
-import logging
-
-from telemetry.internal.platform.power_monitor import android_power_monitor_base
-
-class DumpsysPowerMonitor(android_power_monitor_base.AndroidPowerMonitorBase):
-  """PowerMonitor that relies on the dumpsys batterystats to monitor the power
-  consumption of a single android application. This measure uses a heuristic
-  and is the same information end-users see with the battery application.
-  Available on Android L and higher releases.
-  """
-  def __init__(self, battery, platform_backend):
-    """Constructor.
-
-    Args:
-        battery: A BatteryUtil instance.
-        platform_backend: A LinuxBasedPlatformBackend instance.
-    """
-    super(DumpsysPowerMonitor, self).__init__()
-    self._battery = battery
-    self._browser = None
-    self._platform = platform_backend
-
-  def CanMonitorPower(self):
-    result = self._platform.device.RunShellCommand(
-        ['dumpsys', 'batterystats', '-c'], check_return=True)
-    DUMP_VERSION_INDEX = 0
-    # Dumpsys power data is present in dumpsys versions 8 and 9
-    # which is found on L+ devices.
-    return (csv.reader(result).next()[DUMP_VERSION_INDEX] in ['8', '9'])
-
-  def StartMonitoringPower(self, browser):
-    self._CheckStart()
-    assert browser
-    self._browser = browser
-    # Disable the charging of the device over USB. This is necessary because the
-    # device only collects information about power usage when the device is not
-    # charging.
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    assert self._browser
-    package = self._browser._browser_backend.package
-    self._browser = None
-
-    voltage = self._ParseVoltage(self._battery.GetBatteryInfo().get('voltage'))
-    power_data = self._battery.GetPowerData()
-    power_results = self.ProcessPowerData(power_data, voltage, package)
-    self._LogPowerAnomalies(power_results, package)
-    return power_results
-
-  @staticmethod
-  def ProcessPowerData(power_data, voltage, package):
-    package_power_data = power_data['per_package'].get(package)
-    if not package_power_data:
-      logging.warning('No power data for %s in dumpsys output.' % package)
-      package_power = 0
-    else:
-      package_power = sum(package_power_data['data'])
-
-    return {'identifier': 'dumpsys',
-            'power_samples_mw': [],
-            'energy_consumption_mwh': power_data['system_total'] * voltage,
-            'application_energy_consumption_mwh': package_power * voltage}
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor_unittest.py
deleted file mode 100644
index e38ebc5..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_dumpsys_power_monitor_unittest.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.platform.power_monitor import android_dumpsys_power_monitor
-from telemetry.internal.platform.power_monitor import pm_mock
-
-
-_PACKAGE = 'com.google.android.apps.chrome'
-
-_TYPICAL_POWER_DATA = {
-      'system_total': 2000.0,
-      'per_package': {
-        _PACKAGE: {'data': [23.9], 'uid': '12345'}
-      }
-    }
-
-_TYPICAL_POWER_DATA_MULTISAMPLE = {
-      'system_total': 2000.0,
-      'per_package': {
-        _PACKAGE: {'data': [23.9, 26.1], 'uid': '12345'}
-      }
-    }
-
-
-class DumpsysPowerMonitorMonitorTest(unittest.TestCase):
-
-  def testApplicationEnergyConsumption(self):
-    results = (
-        android_dumpsys_power_monitor.DumpsysPowerMonitor.ProcessPowerData(
-            _TYPICAL_POWER_DATA, 4.0, _PACKAGE))
-    self.assertEqual(results['identifier'], 'dumpsys')
-    self.assertAlmostEqual(results['application_energy_consumption_mwh'], 95.6)
-
-  def testSystemEnergyConsumption(self):
-    power_data = {
-      'system_total': 2000.0,
-      'per_package': {}
-    }
-    results = (
-        android_dumpsys_power_monitor.DumpsysPowerMonitor.ProcessPowerData(
-            power_data, 4.0, 'some.package'))
-    self.assertEqual(results['identifier'], 'dumpsys')
-    self.assertEqual(results['application_energy_consumption_mwh'], 0)
-    self.assertEqual(results['energy_consumption_mwh'], 8000.0)
-
-  def testMonitorCycle(self):
-    browser = pm_mock.MockBrowser(_PACKAGE)
-    battery = pm_mock.MockBattery(_TYPICAL_POWER_DATA_MULTISAMPLE, voltage=5.0)
-    backend = pm_mock.MockPlatformBackend()
-    pm = android_dumpsys_power_monitor.DumpsysPowerMonitor(battery, backend)
-    pm.StartMonitoringPower(browser)
-    result = pm.StopMonitoringPower()
-    self.assertEqual(result['identifier'], 'dumpsys')
-    self.assertEqual(result['power_samples_mw'], [])
-    self.assertAlmostEqual(result['application_energy_consumption_mwh'], 250.0)
-    self.assertAlmostEqual(result['energy_consumption_mwh'], 10000.0)
-
-  def testDoubleStop(self):
-    browser = pm_mock.MockBrowser(_PACKAGE)
-    battery = pm_mock.MockBattery(_TYPICAL_POWER_DATA_MULTISAMPLE, voltage=5.0)
-    backend = pm_mock.MockPlatformBackend()
-    pm = android_dumpsys_power_monitor.DumpsysPowerMonitor(battery, backend)
-    pm.StartMonitoringPower(browser)
-    pm.StopMonitoringPower()
-    with self.assertRaises(AssertionError):
-      pm.StopMonitoringPower()
-
-  def testDoubleStart(self):
-    browser = pm_mock.MockBrowser(_PACKAGE)
-    battery = pm_mock.MockBattery(_TYPICAL_POWER_DATA_MULTISAMPLE, voltage=5.0)
-    backend = pm_mock.MockPlatformBackend()
-    pm = android_dumpsys_power_monitor.DumpsysPowerMonitor(battery, backend)
-    pm.StartMonitoringPower(browser)
-    with self.assertRaises(AssertionError):
-      pm.StartMonitoringPower(browser)
-
-  def testBatteryChargingState(self):
-    browser = pm_mock.MockBrowser(_PACKAGE)
-    battery = pm_mock.MockBattery(_TYPICAL_POWER_DATA_MULTISAMPLE, voltage=5.0)
-    backend = pm_mock.MockPlatformBackend()
-    pm = android_dumpsys_power_monitor.DumpsysPowerMonitor(battery, backend)
-    self.assertEqual(battery.GetCharging(), True)
-    pm.StartMonitoringPower(browser)
-    self.assertEqual(battery.GetCharging(), True)
-    pm.StopMonitoringPower()
-    self.assertEqual(battery.GetCharging(), True)
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor.py
deleted file mode 100644
index 7bd421b..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.platform.power_monitor import android_power_monitor_base
-
-
-class FuelGaugePowerMonitor(android_power_monitor_base.AndroidPowerMonitorBase):
-  """PowerMonitor that relies on the fuel gauge chips to monitor the power
-  consumption of a android device.
-  """
-  def __init__(self, battery):
-    """Constructor.
-
-    Args:
-        battery: A BatteryUtil instance.
-        platform_backend: A LinuxBasedPlatformBackend instance.
-    """
-    super(FuelGaugePowerMonitor, self).__init__()
-    self._battery = battery
-    self._starting_fuel_gauge = None
-
-  def CanMonitorPower(self):
-    return self._battery.SupportsFuelGauge()
-
-  def StartMonitoringPower(self, browser):
-    self._CheckStart()
-    self._starting_fuel_gauge = self._battery.GetFuelGaugeChargeCounter()
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    # Convert from nAh to mAh.
-    fuel_gauge_delta = (
-        float((self._starting_fuel_gauge) -
-        self._battery.GetFuelGaugeChargeCounter()) / 1000000)
-    voltage = self._ParseVoltage(self._battery.GetBatteryInfo().get('voltage'))
-    return self.ProcessPowerData(voltage, fuel_gauge_delta)
-
-  @staticmethod
-  def ProcessPowerData(voltage, fuel_gauge_delta):
-    return {'identifier': 'fuel_gauge',
-            'fuel_gauge_energy_consumption_mwh': fuel_gauge_delta * voltage}
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor_unittest.py
deleted file mode 100644
index 6bce9c3..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_fuelgauge_power_monitor_unittest.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.platform.power_monitor import (
-    android_fuelgauge_power_monitor)
-from telemetry.internal.platform.power_monitor import pm_mock
-
-
-class FuelGaugePowerMonitorMonitorTest(unittest.TestCase):
-
-  def testEnergyConsumption(self):
-    fuel_gauge_delta = 100
-    results = (
-        android_fuelgauge_power_monitor.FuelGaugePowerMonitor.ProcessPowerData(
-            4.0, fuel_gauge_delta))
-    self.assertEqual(results['identifier'], 'fuel_gauge')
-    self.assertEqual(
-        results.get('fuel_gauge_energy_consumption_mwh'), 400)
-
-  def testMonitorCycle(self):
-    battery = pm_mock.MockBattery(None, voltage=5.0, fuelgauge=[5.e6, 3.e6])
-    pm = android_fuelgauge_power_monitor.FuelGaugePowerMonitor(battery)
-    pm.StartMonitoringPower(None)
-    results = pm.StopMonitoringPower()
-    self.assertEqual(results['identifier'], 'fuel_gauge')
-    self.assertAlmostEqual(results['fuel_gauge_energy_consumption_mwh'], 10)
-
-  def testDoubleStop(self):
-    battery = pm_mock.MockBattery(None, voltage=5.0, fuelgauge=[5.e6, 3.e6])
-    pm = android_fuelgauge_power_monitor.FuelGaugePowerMonitor(battery)
-    pm.StartMonitoringPower(None)
-    pm.StopMonitoringPower()
-    with self.assertRaises(AssertionError):
-      pm.StopMonitoringPower()
-
-  def testDoubleStart(self):
-    battery = pm_mock.MockBattery(None, voltage=5.0, fuelgauge=[5.e6, 3.e6])
-    pm = android_fuelgauge_power_monitor.FuelGaugePowerMonitor(battery)
-    pm.StartMonitoringPower(None)
-    with self.assertRaises(AssertionError):
-      pm.StartMonitoringPower(None)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_base.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_base.py
deleted file mode 100644
index afcc87d..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_base.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.internal.platform import power_monitor
-
-
-class AndroidPowerMonitorBase(power_monitor.PowerMonitor):
-
-  # Abstract class.
-  # pylint: disable=abstract-method
-
-  def _ParseVoltage(self, millivolts):
-    # Parse voltage information.
-    # If voltage is None, use 4.0 as default.
-    # Otherwise, convert millivolts to volts.
-    if millivolts is None:
-      # Converting at a nominal voltage of 4.0V, as those values are obtained by
-      # a heuristic, and 4.0V is the voltage we set when using a monsoon device.
-      voltage = 4.0
-      logging.warning('Unable to get device voltage. Using %s.', voltage)
-    else:
-      voltage = float(millivolts) / 1000
-      logging.info('Device voltage at %s', voltage)
-      return voltage
-
-  def _LogPowerAnomalies(self, power_data, package):
-    # Log anomalies in power data.
-    if power_data['energy_consumption_mwh'] == 0:
-      logging.warning('Power data is returning 0 for system total usage. %s'
-                      % (power_data))
-      if power_data['application_energy_consumption_mwh'] == 0:
-        logging.warning('Power data is returning 0 usage for %s. %s'
-                        % (package, power_data))
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_controller.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_controller.py
deleted file mode 100644
index 5648163..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_controller.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.util import atexit_with_log
-import logging
-
-from telemetry.internal.platform.power_monitor import android_power_monitor_base
-
-def _ReenableChargingIfNeeded(battery):
-  if not battery.GetCharging():
-    battery.SetCharging(True)
-  logging.info('Charging status checked at exit.')
-
-class AndroidPowerMonitorController(
-    android_power_monitor_base.AndroidPowerMonitorBase):
-  """
-  PowerMonitor that acts as facade for a list of PowerMonitor objects and uses
-  the first available one.
-  """
-  def __init__(self, power_monitors, battery):
-    super(AndroidPowerMonitorController, self).__init__()
-    self._candidate_power_monitors = power_monitors
-    self._active_monitors = []
-    self._battery = battery
-    atexit_with_log.Register(_ReenableChargingIfNeeded, self._battery)
-
-  def CanMonitorPower(self):
-    return any(m.CanMonitorPower() for m in self._candidate_power_monitors)
-
-  def StartMonitoringPower(self, browser):
-    # TODO(rnephew): re-add assert when crbug.com/553601 is solved and
-    # StopMonitoringPower is called in the correct place.
-    if self._active_monitors:
-      logging.warning('StopMonitoringPower() not called when expected. Last '
-                      'results are likely not reported.')
-      self.StopMonitoringPower()
-    self._CheckStart()
-    self._ChargingOff(self._battery)
-    self._active_monitors = (
-        [m for m in self._candidate_power_monitors if m.CanMonitorPower()])
-    assert self._active_monitors, 'No available monitor.'
-    for monitor in self._active_monitors:
-      monitor.StartMonitoringPower(browser)
-
-  @staticmethod
-  def _MergePowerResults(combined_results, monitor_results):
-    """
-    Merges monitor_results into combined_results and leaves monitor_results
-    values if there are merge conflicts.
-    """
-    def _CheckDuplicateKeys(dict_one, dict_two, ignore_list=None):
-      for key in dict_one:
-        if key in dict_two and key not in ignore_list:
-          logging.warning('Found multiple instances of %s in power monitor '
-                          'entries. Using newest one.', key)
-    # Sub level power entries.
-    for part in ['platform_info', 'component_utilization']:
-      if part in monitor_results:
-        _CheckDuplicateKeys(combined_results[part], monitor_results[part])
-        combined_results[part].update(monitor_results[part])
-
-    # Top level power entries.
-    platform_info = combined_results['platform_info'].copy()
-    comp_utilization = combined_results['component_utilization'].copy()
-    _CheckDuplicateKeys(
-        combined_results, monitor_results,
-        ['identifier', 'platform_info', 'component_utilization'])
-    combined_results.update(monitor_results)
-    combined_results['platform_info'] = platform_info
-    combined_results['component_utilization'] = comp_utilization
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    self._ChargingOn(self._battery)
-    try:
-      results = {'platform_info': {}, 'component_utilization': {}}
-      for monitor in self._active_monitors:
-        self._MergePowerResults(results, monitor.StopMonitoringPower())
-      return results
-    finally:
-      self._active_monitors = []
-
-  def _ChargingOff(self, battery):
-    battery.SetCharging(False)
-
-  def _ChargingOn(self, battery):
-    if battery.GetCharging():
-      logging.warning('Charging re-enabled during test.'
-                      'Results may be inaccurate.')
-    battery.SetCharging(True)
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_controller_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_controller_unittest.py
deleted file mode 100644
index a77c3cc..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_power_monitor_controller_unittest.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.platform import power_monitor as power_monitor
-from telemetry.internal.platform.power_monitor import (
-  android_power_monitor_controller)
-import mock
-from devil.android import battery_utils
-
-# pylint: disable=import-error, unused-argument
-
-
-class AndroidPowerMonitorControllerTest(unittest.TestCase):
-  @mock.patch.object(battery_utils, 'BatteryUtils')
-  def testComposition(self, _):
-
-    class P1(power_monitor.PowerMonitor):
-      def StartMonitoringPower(self, browser):
-        raise NotImplementedError()
-      def StopMonitoringPower(self):
-        raise NotImplementedError()
-
-    class P2(power_monitor.PowerMonitor):
-      def __init__(self, value):
-        super(P2, self).__init__()
-        self._value = {'P2': value}
-      def CanMonitorPower(self):
-        return True
-      def StartMonitoringPower(self, browser):
-        pass
-      def StopMonitoringPower(self):
-        return self._value
-
-    class P3(power_monitor.PowerMonitor):
-      def __init__(self, value):
-        super(P3, self).__init__()
-        self._value = {'P3': value}
-      def CanMonitorPower(self):
-        return True
-      def StartMonitoringPower(self, browser):
-        pass
-      def StopMonitoringPower(self):
-        return self._value
-
-    battery = battery_utils.BatteryUtils(None)
-    controller = android_power_monitor_controller.AndroidPowerMonitorController(
-        [P1(), P2(1), P3(2)], battery)
-    self.assertEqual(controller.CanMonitorPower(), True)
-    controller.StartMonitoringPower(None)
-    controller_returns = controller.StopMonitoringPower()
-    self.assertEqual(controller_returns['P2'], 1)
-    self.assertEqual(controller_returns['P3'], 2)
-
-  @mock.patch.object(battery_utils, 'BatteryUtils')
-  def testReenableChargingIfNeeded(self, mock_battery):
-    battery = battery_utils.BatteryUtils(None)
-    battery.GetCharging.return_value = False
-    android_power_monitor_controller._ReenableChargingIfNeeded(battery)
-
-  def testMergePowerResultsOneEmpty(self):
-    dict_one = {'platform_info': {}, 'component_utilization': {}}
-    dict_two = {'test': 1, 'component_utilization': {'test': 2}}
-    results = {
-        'platform_info': {},
-        'component_utilization': {'test': 2},
-        'test': 1
-    }
-    (android_power_monitor_controller.AndroidPowerMonitorController.
-     _MergePowerResults(dict_one, dict_two))
-    self.assertDictEqual(dict_one, results)
-
-  def testMergePowerResultsSameEntry(self):
-    dict_one = {
-        'test': 1,
-        'component_utilization': {'test': 2},
-        'platform_info': {'test2': 'a'}
-    }
-    dict_two = {'test': 3, 'platform_info': {'test': 4}}
-    results = {
-        'test' : 3,
-        'component_utilization': {'test': 2},
-        'platform_info': {'test': 4, 'test2': 'a'}
-    }
-    (android_power_monitor_controller.AndroidPowerMonitorController.
-     _MergePowerResults(dict_one, dict_two))
-    self.assertDictEqual(dict_one, results)
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_temperature_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_temperature_monitor.py
deleted file mode 100644
index 87d7c37..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_temperature_monitor.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.internal.platform import power_monitor
-
-try:
-  from devil.android import device_errors  # pylint: disable=import-error
-except ImportError:
-  device_errors = None
-
-
-_TEMPERATURE_FILE = '/sys/class/thermal/thermal_zone0/temp'
-
-
-class AndroidTemperatureMonitor(power_monitor.PowerMonitor):
-  """
-  Returns temperature results in power monitor dictionary format.
-  """
-  def __init__(self, device):
-    super(AndroidTemperatureMonitor, self).__init__()
-    self._device = device
-
-  def CanMonitorPower(self):
-    return self._GetBoardTemperatureCelsius() is not None
-
-  def StartMonitoringPower(self, browser):
-    # don't call _CheckStart() because this is temperature, not power
-    # therefore, StartMonitoringPower and StopMonitoringPower
-    # do not need to be paired
-    pass
-
-  def StopMonitoringPower(self):
-    avg_temp = self._GetBoardTemperatureCelsius()
-    if avg_temp is None:
-      return {'identifier': 'android_temperature_monitor'}
-    else:
-      return {'identifier': 'android_temperature_monitor',
-              'platform_info': {'average_temperature_c': avg_temp}}
-
-  def _GetBoardTemperatureCelsius(self):
-    try:
-      contents = self._device.ReadFile(_TEMPERATURE_FILE)
-      return float(contents) if contents else None
-    except ValueError:
-      logging.warning('String returned from device.ReadFile(_TEMPERATURE_FILE) '
-                      'in invalid format.')
-      return None
-    except device_errors.CommandFailedError:
-      return None
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_temperature_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/android_temperature_monitor_unittest.py
deleted file mode 100644
index 830ba0f..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/android_temperature_monitor_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import mock
-from telemetry.internal.platform.power_monitor import android_temperature_monitor
-
-class AndroidTemperatureMonitorTest(unittest.TestCase):
-
-  def testPowerMonitoringResultsWereUpdated(self):
-    mock_device_utils = mock.Mock()
-    mock_device_utils.ReadFile.side_effect = ['0', '24']
-
-    monitor = android_temperature_monitor.AndroidTemperatureMonitor(
-        mock_device_utils)
-    self.assertTrue(monitor.CanMonitorPower())
-    monitor.StartMonitoringPower(None)
-    measurements = monitor.StopMonitoringPower()
-    mock_device_utils.ReadFile.assert_has_calls(
-        [mock.call(mock.ANY), mock.call(mock.ANY)])
-    expected_return = {
-        'identifier': 'android_temperature_monitor',
-        'platform_info': {'average_temperature_c': 24.0}
-    }
-    self.assertDictEqual(expected_return, measurements)
-
-  def testSysfsReadFailed(self):
-    mock_device_utils = mock.Mock()
-    mock_device_utils.ReadFile.side_effect = ['24', None]
-
-    monitor = android_temperature_monitor.AndroidTemperatureMonitor(
-        mock_device_utils)
-    self.assertTrue(monitor.CanMonitorPower())
-    monitor.StartMonitoringPower(None)
-    measurements = monitor.StopMonitoringPower()
-    mock_device_utils.ReadFile.assert_has_calls(
-        [mock.call(mock.ANY), mock.call(mock.ANY)])
-    self.assertTrue('identifier' in measurements)
-    self.assertTrue('platform_info' not in measurements)
-
-  def testSysfsReadFailedCanMonitor(self):
-    mock_device_utils = mock.Mock()
-    mock_device_utils.ReadFile.side_effect = [None]
-
-    monitor = android_temperature_monitor.AndroidTemperatureMonitor(
-        mock_device_utils)
-    self.assertFalse(monitor.CanMonitorPower())
-    mock_device_utils.ReadFile.assert_called_once_with(mock.ANY)
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/cros_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/cros_power_monitor.py
deleted file mode 100644
index 7f922bd..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/cros_power_monitor.py
+++ /dev/null
@@ -1,164 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import logging
-import re
-
-from telemetry import decorators
-from telemetry.internal.platform.power_monitor import sysfs_power_monitor
-
-
-class CrosPowerMonitor(sysfs_power_monitor.SysfsPowerMonitor):
-  """PowerMonitor that relies on 'dump_power_status' to monitor power
-  consumption of a single ChromeOS application.
-  """
-  def __init__(self, platform_backend):
-    """Constructor.
-
-    Args:
-        platform_backend: A LinuxBasedPlatformBackend object.
-
-    Attributes:
-        _initial_power: The result of 'dump_power_status' before the test.
-        _start_time: The epoch time at which the test starts executing.
-    """
-    super(CrosPowerMonitor, self).__init__(platform_backend)
-    self._initial_power = None
-    self._start_time = None
-
-  @decorators.Cache
-  def CanMonitorPower(self):
-    return super(CrosPowerMonitor, self).CanMonitorPower()
-
-  def StartMonitoringPower(self, browser):
-    super(CrosPowerMonitor, self).StartMonitoringPower(browser)
-    if self._IsOnBatteryPower():
-      sample = self._platform.RunCommand(['dump_power_status;', 'date', '+%s'])
-      self._initial_power, self._start_time = CrosPowerMonitor.SplitSample(
-          sample)
-    else:
-      logging.warning('Device not on battery power during power monitoring. '
-                      'Results may be incorrect.')
-
-  def StopMonitoringPower(self):
-    # Don't need to call self._CheckStop here; it's called by the superclass
-    cpu_stats = super(CrosPowerMonitor, self).StopMonitoringPower()
-    power_stats = {}
-    if self._IsOnBatteryPower():
-      sample = self._platform.RunCommand(['dump_power_status;', 'date', '+%s'])
-      final_power, end_time = CrosPowerMonitor.SplitSample(sample)
-      # The length of the test is used to measure energy consumption.
-      length_h = (end_time - self._start_time) / 3600.0
-      power_stats = CrosPowerMonitor.ParsePower(self._initial_power,
-                                                final_power, length_h)
-    else:
-      logging.warning('Device not on battery power during power monitoring. '
-                      'Results may be incorrect.')
-    return CrosPowerMonitor.CombineResults(cpu_stats, power_stats)
-
-  @staticmethod
-  def SplitSample(sample):
-    """Splits a power and time sample into the two separate values.
-
-    Args:
-        sample: The result of calling 'dump_power_status; date +%s' on the
-            device.
-
-    Returns:
-        A tuple of power sample and epoch time of the sample.
-    """
-    sample = sample.strip()
-    index = sample.rfind('\n')
-    power = sample[:index]
-    time = sample[index + 1:]
-    return power, int(time)
-
-  @staticmethod
-  def IsOnBatteryPower(status, board):
-    """Determines if the devices is being charged.
-
-    Args:
-        status: The parsed result of 'dump_power_status'
-        board: The name of the board running the test.
-
-    Returns:
-        True if the device is on battery power; False otherwise.
-    """
-    on_battery = status['line_power_connected'] == '0'
-    # Butterfly can incorrectly report AC online for some time after unplug.
-    # Check battery discharge state to confirm.
-    if board == 'butterfly':
-      on_battery |= status['battery_discharging'] == '1'
-    return on_battery
-
-  def _IsOnBatteryPower(self):
-    """Determines if the device is being charged.
-
-    Returns:
-        True if the device is on battery power; False otherwise.
-    """
-    status = CrosPowerMonitor.ParsePowerStatus(
-        self._platform.RunCommand(['dump_power_status']))
-    board_data = self._platform.RunCommand(['cat', '/etc/lsb-release'])
-    board = re.search('BOARD=(.*)', board_data).group(1)
-    return CrosPowerMonitor.IsOnBatteryPower(status, board)
-
-  @staticmethod
-  def ParsePowerStatus(sample):
-    """Parses 'dump_power_status' command output.
-
-    Args:
-        sample: The output of 'dump_power_status'
-
-    Returns:
-        Dictionary containing all fields from 'dump_power_status'
-    """
-    rv = collections.defaultdict(dict)
-    for ln in sample.splitlines():
-      words = ln.split()
-      assert len(words) == 2
-      rv[words[0]] = words[1]
-    return dict(rv)
-
-  @staticmethod
-  def ParsePower(initial_stats, final_stats, length_h):
-    """Parse output of 'dump_power_status'
-
-    Args:
-        initial_stats: The output of 'dump_power_status' before the test.
-        final_stats: The output of 'dump_power_status' after the test.
-        length_h: The length of the test in hours.
-
-    Returns:
-        Dictionary in the format returned by StopMonitoringPower().
-    """
-    initial = CrosPowerMonitor.ParsePowerStatus(initial_stats)
-    final = CrosPowerMonitor.ParsePowerStatus(final_stats)
-    # The charge value reported by 'dump_power_status' is not precise enough to
-    # give meaningful results across shorter tests, so average energy rate and
-    # the length of the test are used.
-    initial_power_mw = float(initial['battery_energy_rate']) * 10 ** 3
-    final_power_mw = float(final['battery_energy_rate']) * 10 ** 3
-    average_power_mw = (initial_power_mw + final_power_mw) / 2.0
-
-    # Duplicating CrOS battery fields where applicable.
-    def CopyFinalState(field, key):
-      """Copy fields from battery final state."""
-      if field in final:
-        battery[key] = float(final[field])
-
-    battery = {}
-    CopyFinalState('battery_charge_full', 'charge_full')
-    CopyFinalState('battery_charge_full_design', 'charge_full_design')
-    CopyFinalState('battery_charge', 'charge_now')
-    CopyFinalState('battery_current', 'current_now')
-    CopyFinalState('battery_energy', 'energy')
-    CopyFinalState('battery_energy_rate', 'energy_rate')
-    CopyFinalState('battery_voltage', 'voltage_now')
-
-    return {'identifier': 'dump_power_status',
-            'power_samples_mw': [initial_power_mw, final_power_mw],
-            'energy_consumption_mwh': average_power_mw * length_h,
-            'component_utilization': {'battery': battery}}
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/cros_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/cros_power_monitor_unittest.py
deleted file mode 100644
index 2d4945e..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/cros_power_monitor_unittest.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.platform.power_monitor import cros_power_monitor
-
-
-class CrosPowerMonitorMonitorTest(unittest.TestCase):
-  initial_power = ('''line_power_connected 0
-battery_present 1
-battery_percent 70.20
-battery_charge 2.83
-battery_charge_full 4.03
-battery_charge_full_design 4.03
-battery_current 1.08
-battery_energy 31.83
-battery_energy_rate 12.78
-battery_voltage 11.82
-battery_discharging 1''')
-  final_power = ('''line_power_connected 0
-battery_present 1
-battery_percent 70.20
-battery_charge 2.83
-battery_charge_full 4.03
-battery_charge_full_design 4.03
-battery_current 1.08
-battery_energy 31.83
-battery_energy_rate 12.80
-battery_voltage 12.24
-battery_discharging 1''')
-  incomplete_final_power = ('''line_power_connected 0
-battery_present 1
-battery_percent 70.20
-battery_charge 2.83
-battery_charge_full 4.03
-battery_charge_full_design 4.03
-battery_energy_rate 12.80
-battery_discharging 1''')
-  expected_power = {
-    'energy_consumption_mwh': 2558.0,
-    'power_samples_mw': [12780.0, 12800.0],
-    'component_utilization': {
-      'battery': {
-        'charge_full': 4.03,
-        'charge_full_design': 4.03,
-        'charge_now': 2.83,
-        'current_now': 1.08,
-        'energy': 31.83,
-        'energy_rate': 12.80,
-        'voltage_now': 12.24
-      }
-    }
-  }
-  expected_incomplete_power = {
-    'energy_consumption_mwh': 2558.0,
-    'power_samples_mw': [12780.0, 12800.0],
-    'component_utilization': {
-      'battery': {
-        'charge_full': 4.03,
-        'charge_full_design': 4.03,
-        'charge_now': 2.83,
-        'energy_rate': 12.80,
-      }
-    }
-  }
-  expected_cpu = {
-    'whole_package': {
-      'frequency_percent': {
-        1700000000: 3.29254111574526,
-        1600000000: 0.0,
-        1500000000: 0.0,
-        1400000000: 0.15926805099535601,
-        1300000000: 0.47124116307273645,
-        1200000000: 0.818756100807525,
-        1100000000: 1.099381692400982,
-        1000000000: 2.5942528544384302,
-        900000000: 5.68661122326737,
-        800000000: 3.850545467654628,
-        700000000: 2.409691872245393,
-        600000000: 1.4693702487650486,
-        500000000: 2.4623575553879373,
-        400000000: 2.672038150383057,
-        300000000: 3.415770495015825,
-        200000000: 69.59817400982045
-      },
-      'cstate_residency_percent': {
-        'C0': 83.67623835616438535,
-        'C1': 0.2698609589041096,
-        'C2': 0.2780191780821918,
-        'C3': 15.77588150684931505
-      }
-    },
-    'cpu0': {
-      'frequency_percent': {
-        1700000000: 4.113700564971752,
-        1600000000: 0.0,
-        1500000000: 0.0,
-        1400000000: 0.1765536723163842,
-        1300000000: 0.4943502824858757,
-        1200000000: 0.7944915254237288,
-        1100000000: 1.2226341807909604,
-        1000000000: 3.0632062146892656,
-        900000000: 5.680614406779661,
-        800000000: 3.6679025423728815,
-        700000000: 2.379060734463277,
-        600000000: 1.4124293785310735,
-        500000000: 2.599752824858757,
-        400000000: 3.0102401129943503,
-        300000000: 3.650247175141243,
-        200000000: 67.73481638418079
-      },
-      'cstate_residency_percent': {
-        'C0': 76.76226164383562,
-        'C1': 0.3189164383561644,
-        'C2': 0.4544301369863014,
-        'C3': 22.4643917808219178
-      }
-    },
-    'cpu1': {
-      'frequency_percent': {
-        1700000000: 2.4713816665187682,
-        1600000000: 0.0,
-        1500000000: 0.0,
-        1400000000: 0.1419824296743278,
-        1300000000: 0.44813204365959713,
-        1200000000: 0.8430206761913214,
-        1100000000: 0.9761292040110037,
-        1000000000: 2.1252994941875945,
-        900000000: 5.69260803975508,
-        800000000: 4.033188392936374,
-        700000000: 2.4403230100275093,
-        600000000: 1.526311118999024,
-        500000000: 2.3249622859171177,
-        400000000: 2.3338361877717633,
-        300000000: 3.1812938148904073,
-        200000000: 71.46153163546012
-      },
-      'cstate_residency_percent': {
-        'C0': 90.5902150684931507,
-        'C1': 0.2208054794520548,
-        'C2': 0.1016082191780822,
-        'C3': 9.0873712328767123
-      }
-    }
-  }
-
-  def _assertPowerEqual(self, results, expected):
-    battery = results['component_utilization']['battery']
-    expected_battery = expected['component_utilization']['battery']
-    self.assertItemsEqual(battery.keys(), expected_battery.keys())
-    for value in battery:
-      self.assertAlmostEqual(battery[value], expected_battery[value])
-
-    self.assertAlmostEqual(results['energy_consumption_mwh'],
-                           expected['energy_consumption_mwh'])
-    self.assertAlmostEqual(results['power_samples_mw'][0],
-                           expected['power_samples_mw'][0])
-    self.assertAlmostEqual(results['power_samples_mw'][1],
-                           expected['power_samples_mw'][1])
-
-  def testParsePower(self):
-    results = cros_power_monitor.CrosPowerMonitor.ParsePower(
-        self.initial_power, self.final_power, 0.2)
-    self._assertPowerEqual(results, self.expected_power)
-
-  def testParseIncompletePowerState(self):
-    """Test the case where dump_power_status only outputs partial fields.
-
-    CrosPowerMonitor hard-coded expected fields from dump_power_status,
-    this test ensures it parses successfully when expected fields does not
-    exist. It's mainly for backward compatibility.
-    """
-    results = cros_power_monitor.CrosPowerMonitor.ParsePower(
-        self.initial_power, self.incomplete_final_power, 0.2)
-    self._assertPowerEqual(results, self.expected_incomplete_power)
-
-
-  def testSplitSample(self):
-    sample = self.initial_power + '\n1408739546\n'
-    power, time = cros_power_monitor.CrosPowerMonitor.SplitSample(sample)
-    self.assertEqual(power, self.initial_power)
-    self.assertEqual(time, 1408739546)
-
-  def testCombineResults(self):
-    result = cros_power_monitor.CrosPowerMonitor.CombineResults(
-        self.expected_cpu, self.expected_power)
-    comp_util = result['component_utilization']
-    # Test power values.
-    self.assertEqual(result['energy_consumption_mwh'],
-                     self.expected_power['energy_consumption_mwh'])
-    self.assertEqual(result['power_samples_mw'],
-                     self.expected_power['power_samples_mw'])
-    self.assertEqual(comp_util['battery'],
-                     self.expected_power['component_utilization']['battery'])
-    # Test frequency values.
-    self.assertDictEqual(
-        comp_util['whole_package']['frequency_percent'],
-        self.expected_cpu['whole_package']['frequency_percent'])
-    self.assertDictEqual(
-        comp_util['cpu0']['frequency_percent'],
-        self.expected_cpu['cpu0']['frequency_percent'])
-    self.assertDictEqual(
-        comp_util['cpu1']['frequency_percent'],
-        self.expected_cpu['cpu1']['frequency_percent'])
-    # Test c-state residency values.
-    self.assertDictEqual(
-        comp_util['whole_package']['cstate_residency_percent'],
-        self.expected_cpu['whole_package']['cstate_residency_percent'])
-    self.assertDictEqual(
-        comp_util['cpu0']['cstate_residency_percent'],
-        self.expected_cpu['cpu0']['cstate_residency_percent'])
-    self.assertDictEqual(
-        comp_util['cpu1']['cstate_residency_percent'],
-        self.expected_cpu['cpu1']['cstate_residency_percent'])
-
-  def testCanMonitorPower(self):
-    # TODO(tmandel): Add a test here where the device cannot monitor power.
-    initial_status = cros_power_monitor.CrosPowerMonitor.ParsePowerStatus(
-        self.initial_power)
-    final_status = cros_power_monitor.CrosPowerMonitor.ParsePowerStatus(
-        self.final_power)
-    self.assertTrue(cros_power_monitor.CrosPowerMonitor.IsOnBatteryPower(
-        initial_status, 'peppy'))
-    self.assertTrue(cros_power_monitor.CrosPowerMonitor.IsOnBatteryPower(
-        final_status, 'butterfly'))
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/monsoon_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/monsoon_power_monitor.py
deleted file mode 100644
index abbd9f4..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/monsoon_power_monitor.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import multiprocessing
-import tempfile
-import time
-
-from telemetry.core import exceptions
-from telemetry.internal.platform.power_monitor import android_power_monitor_base
-from telemetry.internal.platform.profiler import monsoon
-
-
-def _MonitorPower(device, is_collecting, output):
-  """Monitoring process
-     Args:
-       device: A profiler.monsoon object to collect samples from.
-       is_collecting: the event to synchronize on.
-       output: opened file to write the samples.
-  """
-  with output:
-    samples = []
-    start_time = None
-    end_time = None
-    try:
-      device.StartDataCollection()
-      is_collecting.set()
-      # First sample also calibrate the computation.
-      device.CollectData()
-      start_time = time.time()
-      while is_collecting.is_set():
-        new_data = device.CollectData()
-        assert new_data, 'Unable to collect data from device'
-        samples += new_data
-      end_time = time.time()
-    finally:
-      device.StopDataCollection()
-    result = {
-      'duration_s': end_time - start_time,
-      'samples': samples
-    }
-    json.dump(result, output)
-
-
-class MonsoonPowerMonitor(android_power_monitor_base.AndroidPowerMonitorBase):
-  def __init__(self, _, platform_backend):
-    super(MonsoonPowerMonitor, self).__init__()
-    self._powermonitor_process = None
-    self._powermonitor_output_file = None
-    self._is_collecting = None
-    self._monsoon = None
-    self._platform = platform_backend
-    try:
-      self._monsoon = monsoon.Monsoon(wait=False)
-      # Nominal Li-ion voltage is 3.7V, but it puts out 4.2V at max capacity.
-      # Use 4.0V to simulate a "~80%" charged battery. Google "li-ion voltage
-      # curve". This is true only for a single cell. (Most smartphones, some
-      # tablets.)
-      self._monsoon.SetVoltage(4.0)
-    except EnvironmentError:
-      self._monsoon = None
-
-  def CanMonitorPower(self):
-    return self._monsoon is not None
-
-  def StartMonitoringPower(self, browser):
-    self._CheckStart()
-    self._powermonitor_output_file = tempfile.TemporaryFile()
-    self._is_collecting = multiprocessing.Event()
-    self._powermonitor_process = multiprocessing.Process(
-        target=_MonitorPower,
-        args=(self._monsoon,
-              self._is_collecting,
-              self._powermonitor_output_file))
-    # Ensure child is not left behind: parent kills daemonic children on exit.
-    self._powermonitor_process.daemon = True
-    self._powermonitor_process.start()
-    if not self._is_collecting.wait(timeout=0.5):
-      self._powermonitor_process.terminate()
-      raise exceptions.ProfilingException('Failed to start data collection.')
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    try:
-      # Tell powermonitor to take an immediate sample and join.
-      self._is_collecting.clear()
-      self._powermonitor_process.join()
-      with self._powermonitor_output_file:
-        self._powermonitor_output_file.seek(0)
-        powermonitor_output = self._powermonitor_output_file.read()
-      assert powermonitor_output, 'PowerMonitor produced no output'
-      return MonsoonPowerMonitor.ParseSamplingOutput(powermonitor_output)
-    finally:
-      self._powermonitor_output_file = None
-      self._powermonitor_process = None
-      self._is_collecting = None
-
-  @staticmethod
-  def ParseSamplingOutput(powermonitor_output):
-    """Parse the output of of the samples collector process.
-
-    Returns:
-        Dictionary in the format returned by StopMonitoringPower().
-    """
-    result = json.loads(powermonitor_output)
-    if result['samples']:
-      timedelta_h = (result['duration_s'] / len(result['samples'])) / 3600.0
-      power_samples = [current_a * voltage_v * 10**3
-                       for (current_a, voltage_v) in result['samples']]
-      total_energy_consumption_mwh = sum(power_samples) * timedelta_h
-    else:
-      logging.warning('Sample information not available.')
-      power_samples = []
-      total_energy_consumption_mwh = 0
-
-    return {'identifier':'monsoon',
-            'power_samples_mw':power_samples,
-            'monsoon_energy_consumption_mwh':total_energy_consumption_mwh}
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/monsoon_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/monsoon_power_monitor_unittest.py
deleted file mode 100644
index f2f35c3..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/monsoon_power_monitor_unittest.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import unittest
-
-from telemetry.internal.platform.power_monitor import monsoon_power_monitor
-
-
-class MonsoonPowerMonitorTest(unittest.TestCase):
-
-  def testEnergyComsumption(self):
-    data = {
-        'duration_s': 3600.0,
-        'samples': [(1.0, 1.0), (2.0, 2.0), (3.0, 3.0), (4.0, 4.0)]
-    }
-    results = monsoon_power_monitor.MonsoonPowerMonitor.ParseSamplingOutput(
-        json.dumps(data))
-    self.assertEqual(results['power_samples_mw'], [1000, 4000, 9000, 16000])
-    self.assertEqual(results['monsoon_energy_consumption_mwh'], 7500)
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/msr_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/msr_power_monitor.py
deleted file mode 100644
index 5cf3d16..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/msr_power_monitor.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import platform
-import re
-
-from telemetry import decorators
-from telemetry.internal.platform import power_monitor
-
-
-MSR_RAPL_POWER_UNIT = 0x606
-MSR_PKG_ENERGY_STATUS = 0x611  # Whole package
-MSR_PP0_ENERGY_STATUS = 0x639  # Core
-MSR_PP1_ENERGY_STATUS = 0x641  # Uncore
-MSR_DRAM_ENERGY_STATUS = 0x619
-IA32_PACKAGE_THERM_STATUS = 0x1b1
-IA32_TEMPERATURE_TARGET = 0x1a2
-
-
-def _JoulesToMilliwattHours(value_joules):
-  return value_joules * 1000 / 3600.
-
-
-def _IsSandyBridgeOrLater(vendor, family, model):
-  # Model numbers from:
-  # https://software.intel.com/en-us/articles/intel-architecture-and-processor-identification-with-cpuid-model-and-family-numbers
-  # http://www.speedtraq.com
-  return ('Intel' in vendor and family == 6 and
-          (model in (0x2A, 0x2D) or model >= 0x30))
-
-
-class MsrPowerMonitor(power_monitor.PowerMonitor):
-  def __init__(self, backend):
-    super(MsrPowerMonitor, self).__init__()
-    self._backend = backend
-    self._start_energy_j = None
-    self._start_temp_c = None
-
-  def CanMonitorPower(self):
-    raise NotImplementedError()
-
-  def StartMonitoringPower(self, browser):
-    self._CheckStart()
-    self._start_energy_j = self._PackageEnergyJoules()
-    self._start_temp_c = self._TemperatureCelsius()
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    energy_consumption_j = self._PackageEnergyJoules() - self._start_energy_j
-    average_temp_c = (self._TemperatureCelsius() + self._start_temp_c) / 2.
-    if energy_consumption_j < 0:  # Correct overflow.
-      # The energy portion of the MSR is 4 bytes.
-      energy_consumption_j += 2 ** 32 * self._EnergyMultiplier()
-
-    self._start_energy_j = None
-    self._start_temp_c = None
-
-    return {
-        'identifier': 'msr',
-        'energy_consumption_mwh': _JoulesToMilliwattHours(energy_consumption_j),
-        'platform_info': {
-            'average_temperature_c': average_temp_c,
-        },
-    }
-
-  @decorators.Cache
-  def _EnergyMultiplier(self):
-    return 0.5 ** self._backend.ReadMsr(MSR_RAPL_POWER_UNIT, 8, 5)
-
-  def _PackageEnergyJoules(self):
-    return (self._backend.ReadMsr(MSR_PKG_ENERGY_STATUS, 0, 32) *
-            self._EnergyMultiplier())
-
-  def _TemperatureCelsius(self):
-    tcc_activation_temp = self._backend.ReadMsr(IA32_TEMPERATURE_TARGET, 16, 7)
-    if tcc_activation_temp <= 0:
-      tcc_activation_temp = 105
-    package_temp_headroom = self._backend.ReadMsr(
-        IA32_PACKAGE_THERM_STATUS, 16, 7)
-    return tcc_activation_temp - package_temp_headroom
-
-  def _CheckMSRs(self):
-    try:
-      if self._PackageEnergyJoules() <= 0:
-        logging.info('Cannot monitor power: no energy readings.')
-        return False
-
-      if self._TemperatureCelsius() <= 0:
-        logging.info('Cannot monitor power: no temperature readings.')
-        return False
-    except OSError as e:
-      logging.info('Cannot monitor power: %s' % e)
-      return False
-    return True
-
-
-class MsrPowerMonitorLinux(MsrPowerMonitor):
-  def CanMonitorPower(self):
-    vendor = None
-    family = None
-    model = None
-    cpuinfo = open('/proc/cpuinfo').read().splitlines()
-    for line in cpuinfo:
-      if vendor and family and model:
-        break
-      if line.startswith('vendor_id'):
-        vendor = line.split('\t')[1]
-      elif line.startswith('cpu family'):
-        family = int(line.split(' ')[2])
-      elif line.startswith('model\t\t'):
-        model = int(line.split(' ')[1])
-    if not _IsSandyBridgeOrLater(vendor, family, model):
-      logging.info('Cannot monitor power: pre-Sandy Bridge CPU.')
-      return False
-
-    if not self._CheckMSRs():
-      logging.info('Try running tools/telemetry/build/linux_setup_msr.py.')
-      return False
-
-    return True
-
-
-class MsrPowerMonitorWin(MsrPowerMonitor):
-  def CanMonitorPower(self):
-    family, model = map(int, re.match('.+ Family ([0-9]+) Model ([0-9]+)',
-                        platform.processor()).groups())
-    if not _IsSandyBridgeOrLater(platform.processor(), family, model):
-      logging.info('Cannot monitor power: pre-Sandy Bridge CPU.')
-      return False
-
-    try:
-      return self._CheckMSRs()
-    finally:
-      # Since _CheckMSRs() starts the MSR server on win platform, we must close
-      # it after checking to avoid leaking msr server process.
-      self._backend.CloseMsrServer()
-
-  def StopMonitoringPower(self):
-    power_statistics = super(MsrPowerMonitorWin, self).StopMonitoringPower()
-    self._backend.CloseMsrServer()
-    return power_statistics
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/msr_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/msr_power_monitor_unittest.py
deleted file mode 100644
index 5734308..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/msr_power_monitor_unittest.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.platform.power_monitor import msr_power_monitor
-from telemetry.internal.platform import win_platform_backend
-
-
-class MsrPowerMonitorTest(unittest.TestCase):
-  @decorators.Enabled('xp', 'win7', 'win8')  # http://crbug.com/479337
-  def testMsrRuns(self):
-    platform_backend = win_platform_backend.WinPlatformBackend()
-    power_monitor = msr_power_monitor.MsrPowerMonitorWin(platform_backend)
-    if not power_monitor.CanMonitorPower():
-      logging.warning('Test not supported on this platform.')
-      return
-
-    power_monitor.StartMonitoringPower(None)
-    time.sleep(0.01)
-    statistics = power_monitor.StopMonitoringPower()
-
-    self.assertEqual(statistics['identifier'], 'msr')
-    self.assertIn('energy_consumption_mwh', statistics)
-    self.assertGreater(statistics['energy_consumption_mwh'], 0)
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/pm_mock.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/pm_mock.py
deleted file mode 100644
index d9bbab5..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/pm_mock.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class MockBrowserBackend(object):
-  def __init__(self, package):
-    self.package = package
-
-class MockBrowser(object):
-  def __init__(self, package):
-    self._browser_backend = MockBrowserBackend(package)
-
-class MockBattery(object):
-  def __init__(self,
-               power_results,
-               starts_charging=True,
-               voltage=4.0,
-               fuelgauge=None):
-    # voltage in millivolts
-    self._power_results = power_results
-    self._charging = starts_charging
-    self._voltage = voltage
-    self._fuelgauge = fuelgauge if fuelgauge else []
-    self._fuel_idx = 0
-
-  def SupportsFuelGauge(self):
-    return len(self._fuelgauge) >= 0
-
-  def GetFuelGaugeChargeCounter(self):
-    try:
-      x = self._fuelgauge[self._fuel_idx]
-      self._fuel_idx += 1
-      return x
-    except IndexError:
-      assert False, "Too many GetFuelGaugeChargeCounter() calls."
-
-  def GetCharging(self):
-    return self._charging
-
-  def SetCharging(self, charging):
-    if charging:
-      assert not self._charging, "Mock battery already charging."
-      self._charging = True
-    else:
-      assert self._charging, "Mock battery already not charging."
-      self._charging = False
-
-  def GetPowerData(self):
-    return self._power_results
-
-  def GetBatteryInfo(self):
-    # the voltage returned by GetBatteryInfo() is in millivolts
-    return {'voltage': int(self._voltage*1000)}
-
-class MockPlatformBackend(object):
-  def __init__(self, command_dict=None):
-    self._cdict = (command_dict if command_dict else {})
-
-  def RunCommand(self, command):
-    assert command in self._cdict, "Mock platform error: Unexpected command."
-    return self._cdict[command]
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py
deleted file mode 100644
index 89d141a..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import logging
-import os
-import plistlib
-import shutil
-import tempfile
-import xml.parsers.expat
-
-from telemetry.core import os_version
-from telemetry import decorators
-from telemetry.internal.platform import power_monitor
-
-import py_utils
-
-
-# TODO: rename this class (seems like this is used by mac)
-class PowerMetricsPowerMonitor(power_monitor.PowerMonitor):
-
-  def __init__(self, backend):
-    super(PowerMetricsPowerMonitor, self).__init__()
-    self._powermetrics_process = None
-    self._backend = backend
-    self._output_filename = None
-    self._output_directory = None
-
-  @property
-  def binary_path(self):
-    return '/usr/bin/powermetrics'
-
-  def StartMonitoringPower(self, browser):
-    self._CheckStart()
-    # Empirically powermetrics creates an empty output file immediately upon
-    # starting.  We detect file creation as a signal that measurement has
-    # started.  In order to avoid various race conditions in tempfile creation
-    # we create a temp directory and have powermetrics create it's output
-    # there rather than say, creating a tempfile, deleting it and reusing its
-    # name.
-    self._output_directory = tempfile.mkdtemp()
-    self._output_filename = os.path.join(self._output_directory,
-                                         'powermetrics.output')
-    args = ['-f', 'plist',
-            '-u', self._output_filename,
-            '-i0',
-            '--show-usage-summary']
-    self._powermetrics_process = self._backend.LaunchApplication(
-        self.binary_path, args, elevate_privilege=True)
-
-    # Block until output file is written to ensure this function call is
-    # synchronous in respect to powermetrics starting.
-    def _OutputFileExists():
-      return os.path.isfile(self._output_filename)
-    py_utils.WaitFor(_OutputFileExists, 1)
-
-  @decorators.Cache
-  def CanMonitorPower(self):
-    mavericks_or_later = (
-        self._backend.GetOSVersionName() >= os_version.MAVERICKS)
-    binary_path = self.binary_path
-    return mavericks_or_later and self._backend.CanLaunchApplication(
-        binary_path)
-
-  @staticmethod
-  def _ParsePlistString(plist_string):
-    """Wrapper to parse a plist from a string and catch any errors.
-
-    Sometimes powermetrics will exit in the middle of writing it's output,
-    empirically it seems that it always writes at least one sample in it's
-    entirety so we can safely ignore any errors in it's output.
-
-    Returns:
-        Parser output on successful parse, None on parse error.
-    """
-    try:
-      return plistlib.readPlistFromString(plist_string)
-    except xml.parsers.expat.ExpatError:
-      return None
-
-  @staticmethod
-  def ParsePowerMetricsOutput(powermetrics_output):
-    """Parse output of powermetrics command line utility.
-
-    Returns:
-        Dictionary in the format returned by StopMonitoringPower() or None
-        if |powermetrics_output| is empty - crbug.com/353250 .
-    """
-    if len(powermetrics_output) == 0:
-      logging.warning('powermetrics produced zero length output')
-      return {}
-
-    # Container to collect samples for running averages.
-    # out_path - list containing the key path in the output dictionary.
-    # src_path - list containing the key path to get the data from in
-    #    powermetrics' output.
-    def ConstructMetric(out_path, src_path):
-      RunningAverage = collections.namedtuple('RunningAverage', [
-          'out_path', 'src_path', 'samples'])
-      return RunningAverage(out_path, src_path, [])
-
-    # List of RunningAverage objects specifying metrics we want to aggregate.
-    metrics = [
-        ConstructMetric(
-            ['platform_info', 'average_frequency_hz'],
-            ['processor', 'freq_hz']),
-        ConstructMetric(
-            ['platform_info', 'idle_percent'],
-            ['processor', 'packages', 0, 'c_state_ratio'])]
-
-    def DataWithMetricKeyPath(metric, powermetrics_output):
-      """Retrieve the sample from powermetrics' output for a given metric.
-
-      Args:
-          metric: The RunningAverage object we want to collect a new sample for.
-          powermetrics_output: Dictionary containing powermetrics output.
-
-      Returns:
-          The sample corresponding to |metric|'s keypath."""
-      # Get actual data corresponding to key path.
-      out_data = powermetrics_output
-      for k in metric.src_path:
-        out_data = out_data[k]
-
-      assert type(out_data) in [int, float], (
-          'Was expecting a number: %s (%s)' % (type(out_data), out_data))
-      return float(out_data)
-
-    sample_durations = []
-    total_energy_consumption_mwh = 0
-    # powermetrics outputs multiple plists separated by null terminators.
-    raw_plists = powermetrics_output.split('\0')
-    raw_plists = [x for x in raw_plists if len(x) > 0]
-    assert len(raw_plists) == 1
-
-    # -------- Examine contents of first plist for systems specs. --------
-    plist = PowerMetricsPowerMonitor._ParsePlistString(raw_plists[0])
-    if not plist:
-      logging.warning('powermetrics produced invalid output, output length: '
-                      '%d', len(powermetrics_output))
-      return {}
-
-    # Powermetrics doesn't record power usage when running on a VM.
-    hw_model = plist.get('hw_model')
-    if hw_model and hw_model.startswith('VMware'):
-      return {}
-
-    if 'GPU' in plist:
-      metrics.extend([
-          ConstructMetric(
-              ['component_utilization', 'gpu', 'average_frequency_hz'],
-              ['GPU', 0, 'freq_hz']),
-          ConstructMetric(
-              ['component_utilization', 'gpu', 'idle_percent'],
-              ['GPU', 0, 'c_state_ratio'])])
-
-    # There's no way of knowing ahead of time how many cpus and packages the
-    # current system has. Iterate over cores and cpus - construct metrics for
-    # each one.
-    if 'processor' in plist:
-      core_dict = plist['processor']['packages'][0]['cores']
-      num_cores = len(core_dict)
-      cpu_num = 0
-      for core_idx in xrange(num_cores):
-        num_cpus = len(core_dict[core_idx]['cpus'])
-        base_src_path = ['processor', 'packages', 0, 'cores', core_idx]
-        for cpu_idx in xrange(num_cpus):
-          base_out_path = ['component_utilization', 'cpu%d' % cpu_num]
-          # C State ratio is per-package, component CPUs of that package may
-          # have different frequencies.
-          metrics.append(ConstructMetric(
-              base_out_path + ['average_frequency_hz'],
-              base_src_path + ['cpus', cpu_idx, 'freq_hz']))
-          metrics.append(ConstructMetric(
-              base_out_path + ['idle_percent'],
-              base_src_path + ['c_state_ratio']))
-          cpu_num += 1
-
-    # -------- Parse Data Out of Plists --------
-    plist = PowerMetricsPowerMonitor._ParsePlistString(raw_plists[0])
-    if not plist:
-      logging.error('Error parsing plist.')
-      return {}
-
-    # Duration of this sample.
-    sample_duration_ms = int(plist['elapsed_ns']) / 10 ** 6
-    sample_durations.append(sample_duration_ms)
-
-    if 'processor' not in plist:
-      logging.error("'processor' field not found in plist.")
-      return {}
-    processor = plist['processor']
-
-    total_energy_consumption_mwh = (
-        (float(processor.get('package_joules', 0)) / 3600.) * 10 ** 3)
-
-    for m in metrics:
-      try:
-        m.samples.append(DataWithMetricKeyPath(m, plist))
-      except KeyError:
-        # Old CPUs don't have c-states, so if data is missing, just ignore it.
-        logging.info('Field missing from powermetrics output: %s', m.src_path)
-        continue
-
-    # -------- Collect and Process Data --------
-    out_dict = {}
-    out_dict['identifier'] = 'powermetrics'
-    out_dict['energy_consumption_mwh'] = total_energy_consumption_mwh
-
-    def StoreMetricAverage(metric, sample_durations, out):
-      """Calculate average value of samples in a metric and store in output
-         path as specified by metric.
-
-      Args:
-          metric: A RunningAverage object containing samples to average.
-          sample_durations: A list which parallels the samples list containing
-              the time slice for each sample.
-          out: The output dicat, average is stored in the location specified by
-              metric.out_path.
-      """
-      if len(metric.samples) == 0:
-        return
-
-      assert len(metric.samples) == len(sample_durations)
-      avg = 0
-      for i in xrange(len(metric.samples)):
-        avg += metric.samples[i] * sample_durations[i]
-      avg /= sum(sample_durations)
-
-      # Store data in output, creating empty dictionaries as we go.
-      for k in metric.out_path[:-1]:
-        if not out.has_key(k):
-          out[k] = {}
-        out = out[k]
-      out[metric.out_path[-1]] = avg
-
-    for m in metrics:
-      StoreMetricAverage(m, sample_durations, out_dict)
-
-    if 'tasks' not in plist:
-      logging.error("'tasks' field not found in plist.")
-      return {}
-
-    # The following CPU metrics are already time-normalized, and segmented by
-    # process. Sum the metrics across all Chrome processes.
-    cputime = 0
-    energy_impact = 0
-    browser_process_count = 0
-    idle_wakeups = 0
-    for task in plist['tasks']:
-      if 'Chrome' in task['name'] or 'Chromium' in task['name']:
-        if 'Helper' not in task['name']:
-          browser_process_count += 1
-        cputime += float(task['cputime_ms_per_s'])
-        energy_impact += float(task.get('energy_impact', 0))
-        idle_wakeups += float(task['idle_wakeups_per_s'])
-    if browser_process_count == 0:
-      logging.warning('No Chrome or Chromium browser process found with '
-                      'powermetrics. Chrome CPU metrics will not be emitted.')
-      return {}
-    elif browser_process_count >= 2:
-      logging.warning('powermetrics found more than one Chrome or Chromium '
-                      'browser. Chrome CPU metrics will not be emitted.')
-      # During Telemetry unit tests, there may be multiple Chrome browsers
-      # present. Don't add cpu metrics, but don't return {} either.
-    else:  # browser_process_count == 1:
-      chrome_dict = {}
-      chrome_dict['cputime_ms_per_s'] = cputime
-      chrome_dict['energy_impact'] = energy_impact
-      chrome_dict['idle_wakeups_per_s'] = idle_wakeups
-      out_dict['component_utilization']['chrome'] = chrome_dict
-
-    return out_dict
-
-  def _KillPowerMetricsProcess(self):
-    """Kill a running powermetrics process."""
-    try:
-      if self._powermetrics_process.poll() is None:
-        self._powermetrics_process.terminate()
-    except OSError as e:
-      logging.warning(
-          'Error when trying to terminate powermetric process: %s', repr(e))
-      if self._powermetrics_process.poll() is None:
-        # terminate() can fail when Powermetrics does not have the SetUID set.
-        self._backend.LaunchApplication(
-          '/usr/bin/pkill',
-          ['-SIGTERM', os.path.basename(self.binary_path)],
-          elevate_privilege=True)
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    # Tell powermetrics to take an immediate sample.
-    try:
-      self._KillPowerMetricsProcess()
-      (power_stdout, power_stderr) = self._powermetrics_process.communicate()
-      returncode = self._powermetrics_process.returncode
-      assert returncode in [0, -15], (
-          """powermetrics error
-          return code=%d
-          stdout=(%s)
-          stderr=(%s)""" % (returncode, power_stdout, power_stderr))
-
-      with open(self._output_filename, 'rb') as output_file:
-        powermetrics_output = output_file.read()
-      return PowerMetricsPowerMonitor.ParsePowerMetricsOutput(
-          powermetrics_output)
-    except Exception as e:
-      logging.warning(
-          'Error when trying to collect power monitoring data: %s', repr(e))
-      return PowerMetricsPowerMonitor.ParsePowerMetricsOutput('')
-    finally:
-      shutil.rmtree(self._output_directory)
-      self._output_directory = None
-      self._output_filename = None
-      self._powermetrics_process = None
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py
deleted file mode 100644
index 1c5a65c..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/powermetrics_power_monitor_unittest.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import unittest
-
-from telemetry.core import os_version
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.platform import mac_platform_backend
-from telemetry.internal.platform.power_monitor import powermetrics_power_monitor
-
-
-def _parsePowerMetricsDataFromTestFile(output_file):
-  test_data_path = os.path.join(util.GetUnittestDataDir(), output_file)
-  with open(test_data_path, 'r') as f:
-    process_output = f.read()
-  return (powermetrics_power_monitor.PowerMetricsPowerMonitor.
-      ParsePowerMetricsOutput(process_output))
-
-
-class PowerMetricsPowerMonitorTest(unittest.TestCase):
-  @decorators.Enabled('mac')
-  def testCanMonitorPowerUsage(self):
-    backend = mac_platform_backend.MacPlatformBackend()
-    power_monitor = powermetrics_power_monitor.PowerMetricsPowerMonitor(backend)
-    mavericks_or_later = (
-        backend.GetOSVersionName() >= os_version.MAVERICKS)
-    # Should always be able to monitor power usage on OS Version >= 10.9 .
-    self.assertEqual(power_monitor.CanMonitorPower(), mavericks_or_later,
-        "Error checking powermetrics availability: '%s'" % '|'.join(os.uname()))
-
-  @decorators.Enabled('mac')
-  def testParseEmptyPowerMetricsOutput(self):
-    # Important to handle zero length powermetrics outout - crbug.com/353250 .
-    self.assertFalse(powermetrics_power_monitor.PowerMetricsPowerMonitor.
-        ParsePowerMetricsOutput(''))
-
-  @decorators.Enabled('mac')
-  def testParsePowerMetricsOutputFromVM(self):
-    # Don't fail when running on VM - crbug.com/423688.
-    self.assertEquals({},
-        _parsePowerMetricsDataFromTestFile('powermetrics_vmware.output'))
-
-  @decorators.Enabled('mac')
-  def testParsePowerMetricsOutput(self):
-    power_monitor = powermetrics_power_monitor.PowerMetricsPowerMonitor(
-        mac_platform_backend.MacPlatformBackend())
-    if not power_monitor.CanMonitorPower():
-      logging.warning('Test not supported on this platform.')
-      return
-
-    # Not supported on Mac at this time.
-    self.assertFalse(power_monitor.CanMeasurePerApplicationPower())
-
-    # Supported hardware reports power samples and energy consumption.
-    result = _parsePowerMetricsDataFromTestFile('powermetrics_output.output')
-
-    self.assertTrue(result['energy_consumption_mwh'] > 0)
-
-    # Verify platform info exists in output.
-    self.assertTrue(result['platform_info']['average_frequency_hz'] > 0)
-    self.assertTrue(result['platform_info']['idle_percent'] > 0)
-
-    # Verify that all component entries exist in output.
-    component_utilization = result['component_utilization']
-    for k in ['gpu'] + ['cpu%d' % x for x in range(8)]:
-      self.assertTrue(component_utilization[k]['average_frequency_hz'] > 0)
-      self.assertTrue(component_utilization[k]['idle_percent'] > 0)
-
-    # Unsupported hardware doesn't.
-    result = _parsePowerMetricsDataFromTestFile(
-        'powermetrics_output_unsupported_hardware.output')
-    self.assertNotIn('energy_consumption_mwh', result)
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/sysfs_power_monitor.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/sysfs_power_monitor.py
deleted file mode 100644
index 85e5d30..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/sysfs_power_monitor.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import logging
-import os
-import re
-
-from telemetry.internal.platform import power_monitor
-from telemetry import decorators
-
-
-CPU_PATH = '/sys/devices/system/cpu/'
-
-
-class SysfsPowerMonitor(power_monitor.PowerMonitor):
-  """PowerMonitor that relies on sysfs to monitor CPU statistics on several
-  different platforms.
-  """
-  # TODO(rnephew): crbug.com/513453
-  # Convert all platforms to use standalone power monitors.
-  def __init__(self, linux_based_platform_backend, standalone=False):
-    """Constructor.
-
-    Args:
-        linux_based_platform_backend: A LinuxBasedPlatformBackend object.
-        standalone: If it is not wrapping another monitor, set to True.
-
-    Attributes:
-        _cpus: A list of the CPUs on the target device.
-        _end_time: The time the test stopped monitoring power.
-        _final_cstate: The c-state residency times after the test.
-        _final_freq: The CPU frequency times after the test.
-        _initial_cstate: The c-state residency times before the test.
-        _initial_freq: The CPU frequency times before the test.
-        _platform: A LinuxBasedPlatformBackend object associated with the
-            target platform.
-        _start_time: The time the test started monitoring power.
-    """
-    super(SysfsPowerMonitor, self).__init__()
-    self._cpus = None
-    self._final_cstate = None
-    self._final_freq = None
-    self._initial_cstate = None
-    self._initial_freq = None
-    self._platform = linux_based_platform_backend
-    self._standalone = standalone
-
-  @decorators.Cache
-  def CanMonitorPower(self):
-    return bool(self._platform.RunCommand(
-        'if [ -e %s ]; then echo true; fi' % CPU_PATH))
-
-  def StartMonitoringPower(self, browser):
-    del browser  # unused
-    self._CheckStart()
-    if self.CanMonitorPower():
-      self._cpus = filter(  # pylint: disable=deprecated-lambda
-          lambda x: re.match(r'^cpu[0-9]+', x),
-          self._platform.RunCommand('ls %s' % CPU_PATH).split())
-      self._initial_freq = self.GetCpuFreq()
-      self._initial_cstate = self.GetCpuState()
-
-  def StopMonitoringPower(self):
-    self._CheckStop()
-    try:
-      out = {}
-      if SysfsPowerMonitor.CanMonitorPower(self):
-        self._final_freq = self.GetCpuFreq()
-        self._final_cstate = self.GetCpuState()
-        frequencies = SysfsPowerMonitor.ComputeCpuStats(
-            SysfsPowerMonitor.ParseFreqSample(self._initial_freq),
-            SysfsPowerMonitor.ParseFreqSample(self._final_freq))
-        cstates = SysfsPowerMonitor.ComputeCpuStats(
-            self._platform.ParseCStateSample(self._initial_cstate),
-            self._platform.ParseCStateSample(self._final_cstate))
-        for cpu in frequencies:
-          out[cpu] = {'frequency_percent': frequencies.get(cpu)}
-          out[cpu] = {'cstate_residency_percent': cstates.get(cpu)}
-      if self._standalone:
-        return self.CombineResults(out, {})
-      return out
-    finally:
-      self._initial_cstate = None
-      self._initial_freq = None
-
-  def GetCpuState(self):
-    """Retrieve CPU c-state residency times from the device.
-
-    Returns:
-        Dictionary containing c-state residency times for each CPU.
-    """
-    stats = {}
-    for cpu in self._cpus:
-      cpu_idle_path = os.path.join(CPU_PATH, cpu, 'cpuidle')
-      if not self._platform.PathExists(cpu_idle_path):
-        logging.warning(
-            'Cannot read cpu c-state residency times for %s due to %s not exist'
-            % (cpu, cpu_idle_path))
-        continue
-      cpu_state_path = os.path.join(cpu_idle_path, 'state*')
-      output = self._platform.RunCommand(
-          'cat %s %s %s; date +%%s' % (
-              os.path.join(cpu_state_path, 'name'),
-              os.path.join(cpu_state_path, 'time'),
-              os.path.join(cpu_state_path, 'latency')))
-      stats[cpu] = re.sub('\n\n+', '\n', output)
-    return stats
-
-  def GetCpuFreq(self):
-    """Retrieve CPU frequency times from the device.
-
-    Returns:
-        Dictionary containing frequency times for each CPU.
-    """
-    stats = {}
-    for cpu in self._cpus:
-      cpu_freq_path = os.path.join(
-          CPU_PATH, cpu, 'cpufreq/stats/time_in_state')
-      if not self._platform.PathExists(cpu_freq_path):
-        logging.warning(
-            'Cannot read cpu frequency times for %s due to %s not existing'
-            % (cpu, cpu_freq_path))
-        stats[cpu] = None
-        continue
-      try:
-        stats[cpu] = self._platform.GetFileContents(cpu_freq_path)
-      except Exception as e:
-        logging.warning(
-            'Cannot read cpu frequency times in %s due to error: %s' %
-            (cpu_freq_path, e.message))
-        stats[cpu] = None
-    return stats
-
-  @staticmethod
-  def ParseFreqSample(sample):
-    """Parse a single frequency sample.
-
-    Args:
-        sample: The single sample of frequency data to be parsed.
-
-    Returns:
-        A dictionary associating a frequency with a time.
-    """
-    sample_stats = {}
-    for cpu in sample:
-      frequencies = {}
-      if sample[cpu] is None:
-        sample_stats[cpu] = None
-        continue
-      for line in sample[cpu].splitlines():
-        pair = line.split()
-        freq = int(pair[0]) * 10 ** 3
-        timeunits = int(pair[1])
-        if freq in frequencies:
-          frequencies[freq] += timeunits
-        else:
-          frequencies[freq] = timeunits
-      sample_stats[cpu] = frequencies
-    return sample_stats
-
-  @staticmethod
-  def ComputeCpuStats(initial, final):
-    """Parse the CPU c-state and frequency values saved during monitoring.
-
-    Args:
-        initial: The parsed dictionary of initial statistics to be converted
-        into percentages.
-        final: The parsed dictionary of final statistics to be converted
-        into percentages.
-
-    Returns:
-        Dictionary containing percentages for each CPU as well as an average
-        across all CPUs.
-    """
-    cpu_stats = {}
-    # Each core might have different states or frequencies, so keep track of
-    # the total time in a state or frequency and how many cores report a time.
-    cumulative_times = collections.defaultdict(lambda: (0, 0))
-    for cpu in initial:
-      current_cpu = {}
-      total = 0
-      if not initial[cpu] or not final[cpu]:
-        cpu_stats[cpu] = collections.defaultdict(int)
-        continue
-      for state in initial[cpu]:
-        current_cpu[state] = final[cpu][state] - initial[cpu][state]
-        total += current_cpu[state]
-      if total == 0:
-        # Somehow it's possible for initial and final to have the same sum,
-        # but a different distribution, making total == 0. crbug.com/426430
-        cpu_stats[cpu] = collections.defaultdict(int)
-        continue
-      for state in current_cpu:
-        current_cpu[state] /= (float(total) / 100.0)
-        # Calculate the average c-state residency across all CPUs.
-        time, count = cumulative_times[state]
-        cumulative_times[state] = (time + current_cpu[state], count + 1)
-      cpu_stats[cpu] = current_cpu
-    average = {}
-    for state in cumulative_times:
-      time, count = cumulative_times[state]
-      average[state] = time / float(count)
-    cpu_stats['platform_info'] = average
-    return cpu_stats
-
-  @staticmethod
-  def CombineResults(cpu_stats, power_stats):
-    """Add frequency and c-state residency data to the power data.
-
-    Args:
-        cpu_stats: Dictionary containing CPU statistics.
-        power_stats: Dictionary containing power statistics.
-
-    Returns:
-        Dictionary in the format returned by StopMonitoringPower.
-    """
-    if not cpu_stats:
-      return power_stats
-    if 'component_utilization' not in power_stats:
-      power_stats['component_utilization'] = {}
-    if 'platform_info' in cpu_stats:
-      if 'platform_info' not in power_stats:
-        power_stats['platform_info'] = {}
-      power_stats['platform_info'].update(cpu_stats['platform_info'])
-      del cpu_stats['platform_info']
-    for cpu in cpu_stats:
-      power_stats['component_utilization'][cpu] = cpu_stats[cpu]
-    return power_stats
diff --git a/catapult/telemetry/telemetry/internal/platform/power_monitor/sysfs_power_monitor_unittest.py b/catapult/telemetry/telemetry/internal/platform/power_monitor/sysfs_power_monitor_unittest.py
deleted file mode 100644
index 4389590..0000000
--- a/catapult/telemetry/telemetry/internal/platform/power_monitor/sysfs_power_monitor_unittest.py
+++ /dev/null
@@ -1,285 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.platform import android_platform_backend
-from telemetry.internal.platform.power_monitor import sysfs_power_monitor
-
-
-class SysfsPowerMonitorMonitorTest(unittest.TestCase):
-  initial_freq = {
-    'cpu0': '1700000 6227\n1600000 0\n1500000 0\n1400000 28\n1300000 22\n'
-            '1200000 14\n1100000 19\n1000000 22\n900000 14\n800000 20\n'
-            '700000 15\n600000 23\n500000 23\n400000 9\n300000 28\n200000 179',
-    'cpu1': '1700000 11491\n1600000 0\n1500000 0\n1400000 248\n1300000 1166\n'
-            '1200000 2082\n1100000 2943\n1000000 6560\n900000 12517\n'
-            '800000 8690\n700000 5105\n600000 3800\n500000 5131\n400000 5479\n'
-            '300000 7571\n200000 133618',
-    'cpu2': '1700000 1131',
-    'cpu3': '1700000 1131'
-  }
-  final_freq = {
-    'cpu0': '1700000 7159\n1600000 0\n1500000 0\n1400000 68\n1300000 134\n'
-            '1200000 194\n1100000 296\n1000000 716\n900000 1301\n800000 851\n'
-            '700000 554\n600000 343\n500000 612\n400000 691\n300000 855\n'
-            '200000 15525',
-    'cpu1': '1700000 12048\n1600000 0\n1500000 0\n1400000 280\n1300000 1267\n'
-            '1200000 2272\n1100000 3163\n1000000 7039\n900000 13800\n'
-            '800000 9599\n700000 5655\n600000 4144\n500000 5655\n400000 6005\n'
-            '300000 8288\n200000 149724',
-    'cpu2': None,
-    'cpu3': ''
-  }
-  expected_initial_freq = {
-    'cpu0': {
-      1700000000: 6227,
-      1600000000: 0,
-      1500000000: 0,
-      1400000000: 28,
-      1300000000: 22,
-      1200000000: 14,
-      1100000000: 19,
-      1000000000: 22,
-      900000000: 14,
-      800000000: 20,
-      700000000: 15,
-      600000000: 23,
-      500000000: 23,
-      400000000: 9,
-      300000000: 28,
-      200000000: 179
-    },
-    'cpu1': {
-      1700000000: 11491,
-      1600000000: 0,
-      1500000000: 0,
-      1400000000: 248,
-      1300000000: 1166,
-      1200000000: 2082,
-      1100000000: 2943,
-      1000000000: 6560,
-      900000000: 12517,
-      800000000: 8690,
-      700000000: 5105,
-      600000000: 3800,
-      500000000: 5131,
-      400000000: 5479,
-      300000000: 7571,
-      200000000: 133618
-    },
-    'cpu2': {
-      1700000000: 1131
-    },
-    'cpu3': {
-      1700000000: 1131
-    }
-  }
-  expected_final_freq = {
-    'cpu0': {
-      1700000000: 7159,
-      1600000000: 0,
-      1500000000: 0,
-      1400000000: 68,
-      1300000000: 134,
-      1200000000: 194,
-      1100000000: 296,
-      1000000000: 716,
-      900000000: 1301,
-      800000000: 851,
-      700000000: 554,
-      600000000: 343,
-      500000000: 612,
-      400000000: 691,
-      300000000: 855,
-      200000000: 15525
-    },
-    'cpu1': {
-      1700000000: 12048,
-      1600000000: 0,
-      1500000000: 0,
-      1400000000: 280,
-      1300000000: 1267,
-      1200000000: 2272,
-      1100000000: 3163,
-      1000000000: 7039,
-      900000000: 13800,
-      800000000: 9599,
-      700000000: 5655,
-      600000000: 4144,
-      500000000: 5655,
-      400000000: 6005,
-      300000000: 8288,
-      200000000: 149724
-    },
-    'cpu2': None,
-    'cpu3': {}
-  }
-  expected_freq_percents = {
-    'platform_info': {
-      1700000000: 3.29254111574526,
-      1600000000: 0.0,
-      1500000000: 0.0,
-      1400000000: 0.15926805099535601,
-      1300000000: 0.47124116307273645,
-      1200000000: 0.818756100807525,
-      1100000000: 1.099381692400982,
-      1000000000: 2.5942528544384302,
-      900000000: 5.68661122326737,
-      800000000: 3.850545467654628,
-      700000000: 2.409691872245393,
-      600000000: 1.4693702487650486,
-      500000000: 2.4623575553879373,
-      400000000: 2.672038150383057,
-      300000000: 3.415770495015825,
-      200000000: 69.59817400982045
-    },
-    'cpu0': {
-      1700000000: 4.113700564971752,
-      1600000000: 0.0,
-      1500000000: 0.0,
-      1400000000: 0.1765536723163842,
-      1300000000: 0.4943502824858757,
-      1200000000: 0.7944915254237288,
-      1100000000: 1.2226341807909604,
-      1000000000: 3.0632062146892656,
-      900000000: 5.680614406779661,
-      800000000: 3.6679025423728815,
-      700000000: 2.379060734463277,
-      600000000: 1.4124293785310735,
-      500000000: 2.599752824858757,
-      400000000: 3.0102401129943503,
-      300000000: 3.650247175141243,
-      200000000: 67.73481638418079
-    },
-    'cpu1': {
-      1700000000: 2.4713816665187682,
-      1600000000: 0.0,
-      1500000000: 0.0,
-      1400000000: 0.1419824296743278,
-      1300000000: 0.44813204365959713,
-      1200000000: 0.8430206761913214,
-      1100000000: 0.9761292040110037,
-      1000000000: 2.1252994941875945,
-      900000000: 5.69260803975508,
-      800000000: 4.033188392936374,
-      700000000: 2.4403230100275093,
-      600000000: 1.526311118999024,
-      500000000: 2.3249622859171177,
-      400000000: 2.3338361877717633,
-      300000000: 3.1812938148904073,
-      200000000: 71.46153163546012
-    },
-    'cpu2': {
-      1700000000: 0.0,
-    },
-    'cpu3': {
-      1700000000: 0.0,
-   }
-  }
-
-  def testParseCpuFreq(self):
-    initial = sysfs_power_monitor.SysfsPowerMonitor.ParseFreqSample(
-        self.initial_freq)
-    final = sysfs_power_monitor.SysfsPowerMonitor.ParseFreqSample(
-        self.final_freq)
-    self.assertDictEqual(initial, self.expected_initial_freq)
-    self.assertDictEqual(final, self.expected_final_freq)
-
-  def testComputeCpuStats(self):
-    results = sysfs_power_monitor.SysfsPowerMonitor.ComputeCpuStats(
-        self.expected_initial_freq, self.expected_final_freq)
-    for cpu in self.expected_freq_percents:
-      for freq in results[cpu]:
-        self.assertAlmostEqual(results[cpu][freq],
-                               self.expected_freq_percents[cpu][freq])
-
-  def testComputeCpuStatsWithMissingData(self):
-    results = sysfs_power_monitor.SysfsPowerMonitor.ComputeCpuStats(
-        {'cpu1': {}}, {'cpu1': {}})
-    self.assertEqual(results['cpu1'][12345], 0)
-
-    results = sysfs_power_monitor.SysfsPowerMonitor.ComputeCpuStats(
-        {'cpu1': {123: 0}}, {'cpu1': {123: 0}})
-    self.assertEqual(results['cpu1'][123], 0)
-
-    results = sysfs_power_monitor.SysfsPowerMonitor.ComputeCpuStats(
-        {'cpu1': {123: 456}}, {'cpu1': {123: 456}})
-    self.assertEqual(results['cpu1'][123], 0)
-
-  def testComputeCpuStatsWithNumberChange(self):
-    results = sysfs_power_monitor.SysfsPowerMonitor.ComputeCpuStats(
-        {'cpu1': {'C0': 10, 'WFI': 20}},
-        {'cpu1': {'C0': 20, 'WFI': 10}})
-    self.assertEqual(results['cpu1']['C0'], 0)
-    self.assertEqual(results['cpu1']['WFI'], 0)
-
-  def testGetCpuStateForAndroidDevices(self):
-    class PlatformStub(object):
-      def __init__(self, run_command_return_value):
-        self._run_command_return_value = run_command_return_value
-      def RunCommand(self, cmd):
-        del cmd  # unused
-        return self._run_command_return_value
-      def PathExists(self, path):
-        return 'cpu0' in path or 'cpu1' in path
-
-    cpu_state_from_samsung_note3 = (
-        "C0\n\nC1\n\nC2\n\nC3\n\n"
-        "53658520886\n1809072\n7073\n1722554\n"
-        "1\n35\n300\n500\n"
-        "1412949256\n")
-    expected_cstate_dict = {
-      'C0': 1412895593940415,
-      'C1': 1809072,
-      'C2': 7073,
-      'C3': 1722554,
-      'WFI': 53658520886
-    }
-    cpus = ["cpu%d" % cpu for cpu in range(4)]
-    expected_result = dict(zip(cpus, [expected_cstate_dict]*2))
-
-    sysfsmon = sysfs_power_monitor.SysfsPowerMonitor(
-      PlatformStub(cpu_state_from_samsung_note3))
-    # pylint: disable=protected-access
-    sysfsmon._cpus = cpus
-    cstate = sysfsmon.GetCpuState()
-    result = android_platform_backend.AndroidPlatformBackend.ParseCStateSample(
-        cstate)
-    self.assertDictEqual(expected_result, result)
-
-  def testStandAlone(self):
-    class PlatformStub(object):
-      def __init__(self, run_command_return_value):
-        self._run_command_return_value = run_command_return_value
-      def RunCommand(self, cmd):
-        del cmd  # unused
-        return self._run_command_return_value
-      def PathExists(self, path):
-        del path  # unused
-        return True
-
-    cpu_state_from_samsung_note3 = (
-        "C0\n\nC1\n\nC2\n\nC3\n\n"
-        "53658520886\n1809072\n7073\n1722554\n"
-        "1\n35\n300\n500\n"
-        "1412949256\n")
-    expected_cstate_dict = {
-        'C0': 1412895593940415,
-        'C1': 1809072,
-        'C2': 7073,
-        'C3': 1722554,
-        'WFI': 53658520886
-    }
-    cpus = ["cpu%d" % cpu for cpu in range(2)]
-    expected_result = dict(zip(cpus, [expected_cstate_dict]*len(cpus)))
-
-    sysfsmon = sysfs_power_monitor.SysfsPowerMonitor(
-        PlatformStub(cpu_state_from_samsung_note3), standalone=True)
-    # pylint: disable=protected-access
-    sysfsmon._cpus = cpus
-    cstate = sysfsmon.GetCpuState()
-    result = android_platform_backend.AndroidPlatformBackend.ParseCStateSample(
-        cstate)
-    self.assertDictEqual(expected_result, result)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/__init__.py b/catapult/telemetry/telemetry/internal/platform/profiler/__init__.py
deleted file mode 100644
index 4f035a3..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/__init__.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-
-from telemetry.core import exceptions
-
-class Profiler(object):
-  """A sampling profiler provided by the platform.
-
-  A profiler is started on its constructor, and should
-  gather data until CollectProfile().
-  The life cycle is normally tied to a single page,
-  i.e., multiple profilers will be created for a page set.
-  WillCloseBrowser() is called right before the browser
-  is closed to allow any further cleanup.
-  """
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    self._browser_backend = browser_backend
-    self._platform_backend = platform_backend
-    self._output_path = output_path
-    self._state = state
-
-  @classmethod
-  def name(cls):
-    """User-friendly name of this profiler."""
-    raise NotImplementedError()
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    """True iff this profiler is currently supported by the platform."""
-    raise NotImplementedError()
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    """Override to customize the Browser's options before it is created."""
-    pass
-
-  @classmethod
-  def WillCloseBrowser(cls, browser_backend, platform_backend):
-    """Called before the browser is stopped."""
-    pass
-
-  def _GetProcessOutputFileMap(self):
-    """Returns a dict with pid: output_file."""
-    all_pids = ([self._browser_backend.pid] +
-                self._platform_backend.GetChildPids(self._browser_backend.pid))
-
-    process_name_counts = collections.defaultdict(int)
-    process_output_file_map = {}
-    for pid in all_pids:
-      try:
-        cmd_line = self._platform_backend.GetCommandLine(pid)
-        process_name = self._browser_backend.GetProcessName(cmd_line)
-        output_file = '%s.%s%s' % (self._output_path, process_name,
-                                   process_name_counts[process_name])
-        process_name_counts[process_name] += 1
-        process_output_file_map[pid] = output_file
-      except exceptions.ProcessGoneException:
-        # Ignore processes that disappeared since calling GetChildPids().
-        continue
-    return process_output_file_map
-
-  def CollectProfile(self):
-    """Collect the profile from the profiler."""
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_prebuilt_profiler_helper.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_prebuilt_profiler_helper.py
deleted file mode 100644
index 77e2314..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_prebuilt_profiler_helper.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Android-specific, installs pre-built profilers."""
-
-import logging
-import os
-
-from telemetry.internal.util import binary_manager
-from telemetry import decorators
-
-_DEVICE_PROFILER_DIR = '/data/local/tmp/profilers/'
-
-
-def GetDevicePath(profiler_binary):
-  return os.path.join(_DEVICE_PROFILER_DIR, os.path.basename(profiler_binary))
-
-
-@decorators.Cache
-def InstallOnDevice(device, profiler_binary):
-  arch_name = device.GetABI()
-  host_path = binary_manager.FetchPath(profiler_binary, arch_name, 'android')
-  if not host_path:
-    logging.error('Profiler binary "%s" not found. Could not be installed',
-                  host_path)
-    return False
-
-  device_binary_path = GetDevicePath(profiler_binary)
-  device.PushChangedFiles([(host_path, device_binary_path)])
-  device.RunShellCommand(
-      ['chmod', '777', device_binary_path], check_return=True)
-  return True
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_profiling_helper.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_profiling_helper.py
deleted file mode 100644
index e1dc786..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_profiling_helper.py
+++ /dev/null
@@ -1,325 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import glob
-import hashlib
-import logging
-import os
-import platform
-import re
-import shutil
-import subprocess
-
-from telemetry.internal.util import binary_manager
-from telemetry.core import platform as telemetry_platform
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.platform.profiler import android_prebuilt_profiler_helper
-
-from devil.android import md5sum  # pylint: disable=import-error
-
-
-try:
-  import sqlite3
-except ImportError:
-  sqlite3 = None
-
-
-
-_TEXT_SECTION = '.text'
-
-
-def _ElfMachineId(elf_file):
-  headers = subprocess.check_output(['readelf', '-h', elf_file])
-  return re.match(r'.*Machine:\s+(\w+)', headers, re.DOTALL).group(1)
-
-
-def _ElfSectionAsString(elf_file, section):
-  return subprocess.check_output(['readelf', '-p', section, elf_file])
-
-
-def _ElfSectionMd5Sum(elf_file, section):
-  result = subprocess.check_output(
-      'readelf -p%s "%s" | md5sum' % (section, elf_file), shell=True)
-  return result.split(' ', 1)[0]
-
-
-def _FindMatchingUnstrippedLibraryOnHost(device, lib):
-  lib_base = os.path.basename(lib)
-
-  device_md5sums = md5sum.CalculateDeviceMd5Sums([lib], device)
-  if lib not in device_md5sums:
-    return None
-
-  device_md5 = device_md5sums[lib]
-
-  def FindMatchingStrippedLibrary(out_path):
-    # First find a matching stripped library on the host. This avoids the need
-    # to pull the stripped library from the device, which can take tens of
-    # seconds.
-    # Check the GN stripped lib path first, and the GYP ones afterwards.
-    host_lib_path = os.path.join(out_path, lib_base)
-    host_lib_pattern = os.path.join(out_path, '*_apk', 'libs', '*', lib_base)
-    for stripped_host_lib in [host_lib_path] + glob.glob(host_lib_pattern):
-      if os.path.exists(stripped_host_lib):
-        with open(stripped_host_lib) as f:
-          host_md5 = hashlib.md5(f.read()).hexdigest()
-          if host_md5 == device_md5:
-            return stripped_host_lib
-    return None
-
-  out_path = None
-  stripped_host_lib = None
-  for out_path in util.GetBuildDirectories():
-    stripped_host_lib = FindMatchingStrippedLibrary(out_path)
-    if stripped_host_lib:
-      break
-
-  if not stripped_host_lib:
-    return None
-
-  # The corresponding unstripped library will be under lib.unstripped for GN, or
-  # lib for GYP.
-  unstripped_host_lib_paths = [
-      os.path.join(out_path, 'lib.unstripped', lib_base),
-      os.path.join(out_path, 'lib', lib_base)
-  ]
-  unstripped_host_lib = next(
-      (lib for lib in unstripped_host_lib_paths if os.path.exists(lib)), None)
-  if unstripped_host_lib is None:
-    return None
-
-  # Make sure the unstripped library matches the stripped one. We do this
-  # by comparing the hashes of text sections in both libraries. This isn't an
-  # exact guarantee, but should still give reasonable confidence that the
-  # libraries are compatible.
-  # TODO(skyostil): Check .note.gnu.build-id instead once we're using
-  # --build-id=sha1.
-  # pylint: disable=undefined-loop-variable
-  if (_ElfSectionMd5Sum(unstripped_host_lib, _TEXT_SECTION) !=
-      _ElfSectionMd5Sum(stripped_host_lib, _TEXT_SECTION)):
-    return None
-  return unstripped_host_lib
-
-
-@decorators.Cache
-def GetPerfhostName():
-  return 'perfhost_' + telemetry_platform.GetHostPlatform().GetOSVersionName()
-
-
-# Ignored directories for libraries that aren't useful for symbolization.
-_IGNORED_LIB_PATHS = [
-  '/data/dalvik-cache',
-  '/tmp'
-]
-
-
-def GetRequiredLibrariesForPerfProfile(profile_file):
-  """Returns the set of libraries necessary to symbolize a given perf profile.
-
-  Args:
-    profile_file: Path to perf profile to analyse.
-
-  Returns:
-    A set of required library file names.
-  """
-  with open(os.devnull, 'w') as dev_null:
-    perfhost_path = binary_manager.FetchPath(
-        GetPerfhostName(), 'x86_64', 'linux')
-    perf = subprocess.Popen([perfhost_path, 'script', '-i', profile_file],
-                             stdout=dev_null, stderr=subprocess.PIPE)
-    _, output = perf.communicate()
-  missing_lib_re = re.compile(
-      ('^Failed to open (.*), continuing without symbols|'
-       '^(.*[.]so).*not found, continuing without symbols'))
-  libs = set()
-  for line in output.split('\n'):
-    lib = missing_lib_re.match(line)
-    if lib:
-      lib = lib.group(1) or lib.group(2)
-      path = os.path.dirname(lib)
-      if (any(path.startswith(ignored_path)
-              for ignored_path in _IGNORED_LIB_PATHS)
-          or path == '/' or not path):
-        continue
-      libs.add(lib)
-  return libs
-
-
-def GetRequiredLibrariesForVTuneProfile(profile_file):
-  """Returns the set of libraries necessary to symbolize a given VTune profile.
-
-  Args:
-    profile_file: Path to VTune profile to analyse.
-
-  Returns:
-    A set of required library file names.
-  """
-  db_file = os.path.join(profile_file, 'sqlite-db', 'dicer.db')
-  conn = sqlite3.connect(db_file)
-
-  try:
-    # The 'dd_module_file' table lists all libraries on the device. Only the
-    # ones with 'bin_located_path' are needed for the profile.
-    query = 'SELECT bin_path, bin_located_path FROM dd_module_file'
-    return set(row[0] for row in conn.cursor().execute(query) if row[1])
-  finally:
-    conn.close()
-
-
-def _FileMetadataMatches(filea, fileb):
-  """Check if the metadata of two files matches."""
-  assert os.path.exists(filea)
-  if not os.path.exists(fileb):
-    return False
-
-  fields_to_compare = [
-      'st_ctime', 'st_gid', 'st_mode', 'st_mtime', 'st_size', 'st_uid']
-
-  filea_stat = os.stat(filea)
-  fileb_stat = os.stat(fileb)
-  for field in fields_to_compare:
-    # shutil.copy2 doesn't get ctime/mtime identical when the file system
-    # provides sub-second accuracy.
-    if int(getattr(filea_stat, field)) != int(getattr(fileb_stat, field)):
-      return False
-  return True
-
-
-def CreateSymFs(device, symfs_dir, libraries, use_symlinks=True):
-  """Creates a symfs directory to be used for symbolizing profiles.
-
-  Prepares a set of files ("symfs") to be used with profilers such as perf for
-  converting binary addresses into human readable function names.
-
-  Args:
-    device: DeviceUtils instance identifying the target device.
-    symfs_dir: Path where the symfs should be created.
-    libraries: Set of library file names that should be included in the symfs.
-    use_symlinks: If True, link instead of copy unstripped libraries into the
-      symfs. This will speed up the operation, but the resulting symfs will no
-      longer be valid if the linked files are modified, e.g., by rebuilding.
-
-  Returns:
-    The absolute path to the kernel symbols within the created symfs.
-  """
-  logging.info('Building symfs into %s.' % symfs_dir)
-
-  for lib in libraries:
-    device_dir = os.path.dirname(lib)
-    output_dir = os.path.join(symfs_dir, device_dir[1:])
-    if not os.path.exists(output_dir):
-      os.makedirs(output_dir)
-    output_lib = os.path.join(output_dir, os.path.basename(lib))
-
-    if lib.startswith('/data/app'):
-      # If this is our own library instead of a system one, look for a matching
-      # unstripped library under the out directory.
-      unstripped_host_lib = _FindMatchingUnstrippedLibraryOnHost(device, lib)
-      if not unstripped_host_lib:
-        logging.warning('Could not find symbols for %s.' % lib)
-        logging.warning('Is the correct output directory selected '
-                        '(CHROMIUM_OUTPUT_DIR)? Did you install the APK after '
-                        'building?')
-        continue
-      if use_symlinks:
-        if os.path.lexists(output_lib):
-          os.remove(output_lib)
-        os.symlink(os.path.abspath(unstripped_host_lib), output_lib)
-      # Copy the unstripped library only if it has been changed to avoid the
-      # delay.
-      elif not _FileMetadataMatches(unstripped_host_lib, output_lib):
-        logging.info('Copying %s to %s' % (unstripped_host_lib, output_lib))
-        shutil.copy2(unstripped_host_lib, output_lib)
-    else:
-      # Otherwise save a copy of the stripped system library under the symfs so
-      # the profiler can at least use the public symbols of that library. To
-      # speed things up, only pull files that don't match copies we already
-      # have in the symfs.
-      if not os.path.exists(output_lib):
-        pull = True
-      else:
-        host_md5sums = md5sum.CalculateHostMd5Sums([output_lib])
-        device_md5sums = md5sum.CalculateDeviceMd5Sums([lib], device)
-
-        pull = True
-        if host_md5sums and device_md5sums and output_lib in host_md5sums \
-          and lib in device_md5sums:
-          pull = host_md5sums[output_lib] != device_md5sums[lib]
-
-      if pull:
-        logging.info('Pulling %s to %s', lib, output_lib)
-        device.PullFile(lib, output_lib)
-
-  # Also pull a copy of the kernel symbols.
-  output_kallsyms = os.path.join(symfs_dir, 'kallsyms')
-  if not os.path.exists(output_kallsyms):
-    device.PullFile('/proc/kallsyms', output_kallsyms)
-  return output_kallsyms
-
-
-def PrepareDeviceForPerf(device):
-  """Set up a device for running perf.
-
-  Args:
-    device: DeviceUtils instance identifying the target device.
-
-  Returns:
-    The path to the installed perf binary on the device.
-  """
-  android_prebuilt_profiler_helper.InstallOnDevice(device, 'perf')
-  # Make sure kernel pointers are not hidden.
-  device.WriteFile('/proc/sys/kernel/kptr_restrict', '0', as_root=True)
-  return android_prebuilt_profiler_helper.GetDevicePath('perf')
-
-
-def GetToolchainBinaryPath(library_file, binary_name):
-  """Return the path to an Android toolchain binary on the host.
-
-  Args:
-    library_file: ELF library which is used to identify the used ABI,
-        architecture and toolchain.
-    binary_name: Binary to search for, e.g., 'objdump'
-  Returns:
-    Full path to binary or None if the binary was not found.
-  """
-  # Mapping from ELF machine identifiers to GNU toolchain names.
-  toolchain_configs = {
-    'x86': 'i686-linux-android',
-    'MIPS': 'mipsel-linux-android',
-    'ARM': 'arm-linux-androideabi',
-    'x86-64': 'x86_64-linux-android',
-    'AArch64': 'aarch64-linux-android',
-  }
-  toolchain_config = toolchain_configs[_ElfMachineId(library_file)]
-  host_os = platform.uname()[0].lower()
-  host_machine = platform.uname()[4]
-
-  elf_comment = _ElfSectionAsString(library_file, '.comment')
-  toolchain_version = re.match(r'.*GCC: \(GNU\) ([\w.]+)',
-                               elf_comment, re.DOTALL)
-  if not toolchain_version:
-    return None
-  toolchain_version = toolchain_version.group(1)
-  toolchain_version = toolchain_version.replace('.x', '')
-
-  toolchain_path = os.path.abspath(os.path.join(
-      util.GetChromiumSrcDir(), 'third_party', 'android_tools', 'ndk',
-      'toolchains', '%s-%s' % (toolchain_config, toolchain_version)))
-  if not os.path.exists(toolchain_path):
-    logging.warning(
-        'Unable to find toolchain binary %s: toolchain not found at %s',
-        binary_name, toolchain_path)
-    return None
-
-  path = os.path.join(
-      toolchain_path, 'prebuilt', '%s-%s' % (host_os, host_machine), 'bin',
-      '%s-%s' % (toolchain_config, binary_name))
-  if not os.path.exists(path):
-    logging.warning(
-        'Unable to find toolchain binary %s: binary not found at %s',
-        binary_name, path)
-    return None
-
-  return path
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_profiling_helper_unittest.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_profiling_helper_unittest.py
deleted file mode 100644
index 70aa2f6..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_profiling_helper_unittest.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import pickle
-import re
-import shutil
-import tempfile
-import time
-import unittest
-
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.platform.profiler import android_profiling_helper
-from telemetry.testing import simple_mock
-from telemetry.testing import tab_test_case
-
-
-def _GetLibrariesMappedIntoProcesses(device, pids):
-  libs = set()
-  for pid in pids:
-    maps_file = '/proc/%d/maps' % pid
-    maps = device.ReadFile(maps_file, as_root=True).splitlines()
-    for map_line in maps:
-      lib = re.match(r'.*\s(/.*[.]so)$', map_line)
-      if lib:
-        libs.add(lib.group(1))
-  return libs
-
-
-class TestFileMetadataMatches(unittest.TestCase):
-  def setUp(self):
-    self.tempdir = tempfile.mkdtemp()
-    self.filename_a = os.path.join(self.tempdir, 'filea')
-    self.filename_b = os.path.join(self.tempdir, 'fileb')
-
-    with open(self.filename_a, 'w') as f:
-      f.write('testing')
-
-  def tearDown(self):
-    shutil.rmtree(self.tempdir)
-
-  def testDoesntMatchNonExistant(self):
-    self.assertFalse(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-  def testDoesntMatchJustExistence(self):
-    with open(self.filename_b, 'w') as f:
-      f.write('blah')
-
-    self.assertFalse(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-  def testDoesntMatchCopy(self):
-    # This test can run so fast that the file system doesn't have enough
-    # accuracy to differentiate between the copy and initial file times.
-    # Hence we need to guarantee a delay here.
-    time.sleep(3)
-    shutil.copy(self.filename_a, self.filename_b)
-    self.assertFalse(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-  def testMatchesAfterCopy2(self):
-    shutil.copy2(self.filename_a, self.filename_b)
-    self.assertTrue(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-  def testDoesntMatchAfterCopy2ThenModify(self):
-    shutil.copy2(self.filename_a, self.filename_b)
-
-    filea = open(self.filename_a, 'w')
-    filea.write('moar testing!')
-    filea.close()
-
-    self.assertFalse(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-  def testDoesntMatchAfterCopy2ThenModifyStats(self):
-    shutil.copy2(self.filename_a, self.filename_b)
-    os.utime(self.filename_a, (20, 20))
-    self.assertFalse(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-  def testMatchesAfterCopyStatWithDifferentContent(self):
-    fileb = open(self.filename_b, 'w')
-    fileb.write('blahing')
-    fileb.close()
-
-    shutil.copystat(self.filename_a, self.filename_b)
-
-    self.assertTrue(
-        android_profiling_helper._FileMetadataMatches(
-            self.filename_a, self.filename_b))
-
-
-class TestAndroidProfilingHelper(unittest.TestCase):
-
-  @decorators.Enabled('linux')
-  def testGetRequiredLibrariesForPerfProfile(self):
-    perf_output = os.path.join(
-        util.GetUnittestDataDir(), 'sample_perf_report_output.txt')
-    with open(perf_output) as f:
-      perf_output = f.read()
-
-    mock_popen = simple_mock.MockObject()
-    mock_popen.ExpectCall('communicate').WillReturn([None, perf_output])
-
-    mock_subprocess = simple_mock.MockObject()
-    mock_subprocess.ExpectCall(
-        'Popen').WithArgs(simple_mock.DONT_CARE).WillReturn(mock_popen)
-    mock_subprocess.SetAttribute('PIPE', simple_mock.MockObject())
-
-    real_subprocess = android_profiling_helper.subprocess
-    android_profiling_helper.subprocess = mock_subprocess
-    try:
-      libs = android_profiling_helper.GetRequiredLibrariesForPerfProfile('foo')
-      self.assertEqual(libs, set([
-          '/data/app-lib/com.google.android.apps.chrome-2/libchrome.2016.0.so',
-          '/system/lib/libart.so',
-          '/system/lib/libc.so',
-          '/system/lib/libm.so']))
-    finally:
-      android_profiling_helper.subprocess = real_subprocess
-
-  @decorators.Enabled('android')
-  def testGetRequiredLibrariesForVTuneProfile(self):
-    vtune_db_output = os.path.join(
-        util.GetUnittestDataDir(), 'sample_vtune_db_output')
-    with open(vtune_db_output, 'rb') as f:
-      vtune_db_output = pickle.load(f)
-
-    mock_cursor = simple_mock.MockObject()
-    mock_cursor.ExpectCall(
-        'execute').WithArgs(simple_mock.DONT_CARE).WillReturn(vtune_db_output)
-
-    mock_conn = simple_mock.MockObject()
-    mock_conn.ExpectCall('cursor').WillReturn(mock_cursor)
-    mock_conn.ExpectCall('close')
-
-    mock_sqlite3 = simple_mock.MockObject()
-    mock_sqlite3.ExpectCall(
-        'connect').WithArgs(simple_mock.DONT_CARE).WillReturn(mock_conn)
-
-    real_sqlite3 = android_profiling_helper.sqlite3
-    android_profiling_helper.sqlite3 = mock_sqlite3
-    try:
-      libs = android_profiling_helper.GetRequiredLibrariesForVTuneProfile('foo')
-      self.assertEqual(libs, set([
-          '/data/app-lib/com.google.android.apps.chrome-1/libchrome.2019.0.so',
-          '/system/lib/libdvm.so',
-          '/system/lib/libc.so',
-          '/system/lib/libm.so']))
-    finally:
-      android_profiling_helper.sqlite3 = real_sqlite3
-
-
-class TestAndroidProfilingHelperTabTestCase(tab_test_case.TabTestCase):
-
-  def setUp(self):
-    super(TestAndroidProfilingHelperTabTestCase, self).setUp()
-    # pylint: disable=protected-access
-    browser_backend = self._browser._browser_backend
-    self._device = browser_backend.device()
-
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testCreateSymFs(self):
-    # pylint: disable=protected-access
-    browser_pid = self._browser._browser_backend.pid
-    pids = ([browser_pid] +
-        self._browser._platform_backend.GetChildPids(browser_pid))
-    libs = _GetLibrariesMappedIntoProcesses(self._device, pids)
-    assert libs
-
-    symfs_dir = tempfile.mkdtemp()
-    try:
-      kallsyms = android_profiling_helper.CreateSymFs(self._device, symfs_dir,
-                                                      libs)
-
-      # Check that we have kernel symbols.
-      assert os.path.exists(kallsyms)
-
-      is_unstripped = re.compile(r'^/data/app(-lib)?/.*\.so$')
-      has_unstripped = False
-
-      # Check that all requested libraries are present.
-      for lib in libs:
-        has_unstripped = has_unstripped or is_unstripped.match(lib)
-        assert os.path.exists(os.path.join(symfs_dir, lib[1:])), \
-            '%s not found in symfs' % lib
-
-      # Make sure we found at least one unstripped library.
-      assert has_unstripped
-    finally:
-      shutil.rmtree(symfs_dir)
-
-  # Test fails: crbug.com/437081
-  # @decorators.Enabled('android')
-  @decorators.Disabled('all')
-  def testGetToolchainBinaryPath(self):
-    with tempfile.NamedTemporaryFile() as libc:
-      self._device.PullFile('/system/lib/libc.so', libc.name)
-      path = android_profiling_helper.GetToolchainBinaryPath(libc.name,
-                                                             'objdump')
-      assert path and os.path.exists(path)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_screen_recorder_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_screen_recorder_profiler.py
deleted file mode 100644
index c1d4031..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_screen_recorder_profiler.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# devil may not be available if we're not in an Android checkout.
-try:
-  from devil.android.tools import video_recorder
-except ImportError:
-  video_recorder = None
-
-from telemetry.internal.platform import profiler
-from telemetry.internal.backends.chrome import android_browser_finder
-
-
-_VIDEO_MEGABITS_PER_SECOND = 4
-
-
-class AndroidScreenRecordingProfiler(profiler.Profiler):
-  """Captures a screen recording on Android."""
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(AndroidScreenRecordingProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    self._output_path = output_path + '.mp4'
-    self._recorder = video_recorder.VideoRecorder(
-        browser_backend.device,
-        megabits_per_second=_VIDEO_MEGABITS_PER_SECOND)
-    self._recorder.Start()
-
-  @classmethod
-  def name(cls):
-    return 'android-screen-recorder'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if browser_type == 'any':
-      return android_browser_finder.CanFindAvailableBrowsers()
-    return browser_type.startswith('android')
-
-  def CollectProfile(self):
-    self._recorder.Stop()
-    self._recorder.Pull(self._output_path)
-
-    print 'Screen recording saved as %s' % self._output_path
-    print 'To view, open in Chrome or a video player'
-    return [self._output_path]
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_screen_recorder_profiler_unittest.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_screen_recorder_profiler_unittest.py
deleted file mode 100644
index 8e6632b..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_screen_recorder_profiler_unittest.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import shutil
-import tempfile
-
-from telemetry import decorators
-from telemetry.internal.platform.profiler import (
-    android_screen_recorder_profiler)
-from telemetry.testing import tab_test_case
-
-
-class AndroidScreenRecorderProfilerTest(tab_test_case.TabTestCase):
-  @decorators.Enabled('android')
-  def testRecording(self):
-    out_dir = tempfile.mkdtemp()
-    try:
-      # pylint: disable=protected-access
-      profiler = (
-          android_screen_recorder_profiler.AndroidScreenRecordingProfiler(
-              self._browser._browser_backend,
-              self._browser._platform_backend,
-              os.path.join(out_dir, 'android_screen_recording'),
-              {}))
-      result = profiler.CollectProfile()[0]
-      self.assertTrue(os.path.exists(result))
-    finally:
-      shutil.rmtree(out_dir)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_systrace_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_systrace_profiler.py
deleted file mode 100644
index f117244..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_systrace_profiler.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import StringIO
-import subprocess
-import zipfile
-
-from telemetry.core import util
-from telemetry.internal.backends.chrome import android_browser_finder
-from telemetry.internal.platform import profiler
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data as trace_data_module
-
-_SYSTRACE_CATEGORIES = [
-    'gfx',
-    'input',
-    'view',
-    'sched',
-    'freq',
-]
-
-class AndroidSystraceProfiler(profiler.Profiler):
-  """Collects a Systrace on Android."""
-
-  def __init__(self, browser_backend, platform_backend, output_path, state,
-               device=None):
-    super(AndroidSystraceProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    assert self._browser_backend.supports_tracing
-    self._output_path = output_path + '-trace.zip'
-    self._systrace_output_path = output_path + '.systrace'
-
-    # Use telemetry's own tracing backend instead the combined mode in
-    # adb_profile_chrome because some benchmarks also do tracing of their own
-    # and the two methods conflict.
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    self._browser_backend.StartTracing(config, timeout=10)
-    command = ['python', os.path.join(util.GetCatapultDir(), 'systrace', 'bin',
-                                      'adb_profile_chrome'),
-               '--categories', '', '--continuous', '--output',
-               self._systrace_output_path, '--json', '--systrace',
-               ','.join(_SYSTRACE_CATEGORIES)]
-    if device:
-      command.extend(['--device', device])
-    self._profiler = subprocess.Popen(command, stdin=subprocess.PIPE,
-                                      stdout=subprocess.PIPE)
-
-  @classmethod
-  def name(cls):
-    return 'android-systrace'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if browser_type == 'any':
-      return android_browser_finder.CanFindAvailableBrowsers()
-    return browser_type.startswith('android')
-
-  def CollectProfile(self):
-    self._profiler.communicate(input='\n')
-    trace_result_builder = trace_data_module.TraceDataBuilder()
-    self._browser_backend.StopTracing(trace_result_builder)
-    trace_result = trace_result_builder.AsData()
-
-    trace_file = StringIO.StringIO()
-    trace_result.Serialize(trace_file)
-
-    # Merge the chrome and systraces into a zip file.
-    with zipfile.ZipFile(self._output_path, 'w', zipfile.ZIP_DEFLATED) as z:
-      z.writestr('trace.json', trace_file.getvalue())
-      z.write(self._systrace_output_path, 'systrace')
-      os.unlink(self._systrace_output_path)
-
-    print 'Systrace saved as %s' % self._output_path
-    print 'To view, open in chrome://tracing'
-    return [self._output_path]
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_systrace_profiler_unittest.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_systrace_profiler_unittest.py
deleted file mode 100644
index db4f9df..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_systrace_profiler_unittest.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import shutil
-import tempfile
-import zipfile
-
-from telemetry import decorators
-from telemetry.internal.platform.profiler import android_systrace_profiler
-from telemetry.testing import tab_test_case
-
-
-class TestAndroidSystraceProfiler(tab_test_case.TabTestCase):
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testSystraceProfiler(self):
-    try:
-      out_dir = tempfile.mkdtemp()
-      # pylint: disable=protected-access
-      profiler = android_systrace_profiler.AndroidSystraceProfiler(
-          self._browser._browser_backend,
-          self._browser._platform_backend,
-          os.path.join(out_dir, 'systrace'),
-          {},
-          self._device)
-      result = profiler.CollectProfile()[0]
-      self.assertTrue(zipfile.is_zipfile(result))
-      with zipfile.ZipFile(result) as z:
-        self.assertEquals(len(z.namelist()), 2)
-        self.assertIn('sched_wakeup', z.open('systrace').read())
-    finally:
-      shutil.rmtree(out_dir)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/android_traceview_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/android_traceview_profiler.py
deleted file mode 100644
index 5cb6b49..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/android_traceview_profiler.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.internal.backends.chrome import android_browser_finder
-from telemetry.internal.platform import profiler
-
-import py_utils
-
-try:
-  from devil.android import device_errors  # pylint: disable=import-error
-except ImportError:
-  device_errors = None
-
-
-class AndroidTraceviewProfiler(profiler.Profiler):
-  """Collects a Traceview on Android."""
-
-  _DEFAULT_DEVICE_DIR = '/data/local/tmp/traceview'
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(AndroidTraceviewProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-
-    if self._browser_backend.device.FileExists(self._DEFAULT_DEVICE_DIR):
-      # Note: command must be passed as a string to expand wildcards.
-      self._browser_backend.device.RunShellCommand(
-          'rm ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'),
-          check_return=True, shell=True)
-    else:
-      self._browser_backend.device.RunShellCommand(
-          ['mkdir', '-p', self._DEFAULT_DEVICE_DIR], check_return=True)
-      self._browser_backend.device.RunShellCommand(
-          ['chmod', '777', self._DEFAULT_DEVICE_DIR], check_return=True)
-
-    self._trace_files = []
-    for pid in self._GetProcessOutputFileMap().iterkeys():
-      device_dump_file = '%s/%s.trace' % (self._DEFAULT_DEVICE_DIR, pid)
-      self._trace_files.append((pid, device_dump_file))
-      self._browser_backend.device.RunShellCommand(
-          ['am', 'profile', str(pid), 'start', device_dump_file],
-          check_return=True)
-
-  @classmethod
-  def name(cls):
-    return 'android-traceview'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if browser_type == 'any':
-      return android_browser_finder.CanFindAvailableBrowsers()
-    return browser_type.startswith('android')
-
-  def CollectProfile(self):
-    output_files = []
-    for pid, trace_file in self._trace_files:
-      self._browser_backend.device.RunShellCommand(
-          ['am', 'profile', str(pid), 'stop'], check_return=True)
-      # pylint: disable=cell-var-from-loop
-      py_utils.WaitFor(lambda: self._FileSize(trace_file) > 0, timeout=10)
-      output_files.append(trace_file)
-    self._browser_backend.device.PullFile(
-        self._DEFAULT_DEVICE_DIR, self._output_path)
-    # Note: command must be passed as a string to expand wildcards.
-    self._browser_backend.device.RunShellCommand(
-        'rm ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'),
-        check_return=True, shell=True)
-    print 'Traceview profiles available in ', self._output_path
-    print 'Use third_party/android_tools/sdk/tools/monitor '
-    print 'then use "File->Open File" to visualize them.'
-    return output_files
-
-  def _FileSize(self, file_name):
-    try:
-      return self._browser_backend.device.FileSize(file_name)
-    except device_errors.CommandFailedError:
-      return 0
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/iprofiler_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/iprofiler_profiler.py
deleted file mode 100644
index bf57427..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/iprofiler_profiler.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import signal
-import sys
-
-from telemetry.core import exceptions
-from telemetry.internal.platform import profiler
-
-import py_utils
-
-try:
-  import pexpect  # pylint: disable=import-error
-except ImportError:
-  pass
-
-
-class _SingleProcessIprofilerProfiler(object):
-  """An internal class for using iprofiler for a given process."""
-  def __init__(self, pid, output_path):
-    self._output_path = output_path
-    output_dir = os.path.dirname(self._output_path)
-    output_file = os.path.basename(self._output_path)
-    self._proc = pexpect.spawn(
-        'iprofiler', ['-timeprofiler', '-T', '300', '-a', str(pid),
-                      '-d', output_dir, '-o', output_file],
-        timeout=300)
-    while True:
-      if self._proc.getecho():
-        output = self._proc.readline().strip()
-        if not output:
-          continue
-        if 'iprofiler: Profiling process' in output:
-          break
-        print output
-      self._proc.interact(escape_character='\x0d')
-      if 'Failed to authorize rights' in output:
-        raise exceptions.ProfilingException(
-            'Failed to authorize rights for iprofiler\n')
-      if 'iprofiler error' in output:
-        raise exceptions.ProfilingException(
-            'Failed to start iprofiler for process %s\n' %
-            self._output_path.split('.')[1])
-      self._proc.write('\x0d')
-      print
-      def Echo():
-        return self._proc.getecho()
-      py_utils.WaitFor(Echo, timeout=5)
-
-  def CollectProfile(self):
-    self._proc.kill(signal.SIGINT)
-    try:
-      self._proc.wait()
-    except pexpect.ExceptionPexpect:
-      pass
-    finally:
-      self._proc = None
-
-    print 'To view the profile, run:'
-    print '  open -a Instruments %s.dtps' % self._output_path
-    return self._output_path
-
-
-class IprofilerProfiler(profiler.Profiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(IprofilerProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    process_output_file_map = self._GetProcessOutputFileMap()
-    self._process_profilers = []
-    for pid, output_file in process_output_file_map.iteritems():
-      if '.utility' in output_file:
-        # The utility process may not have been started by Telemetry.
-        # So we won't have permissing to profile it
-        continue
-      self._process_profilers.append(
-          _SingleProcessIprofilerProfiler(pid, output_file))
-
-  @classmethod
-  def name(cls):
-    return 'iprofiler'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if sys.platform != 'darwin':
-      return False
-    if browser_type == 'any':
-      return True
-    return (not browser_type.startswith('android') and
-            not browser_type.startswith('cros'))
-
-  def CollectProfile(self):
-    output_files = []
-    for single_process in self._process_profilers:
-      output_files.append(single_process.CollectProfile())
-    return output_files
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/java_heap_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/java_heap_profiler.py
deleted file mode 100644
index c127a19..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/java_heap_profiler.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import subprocess
-import threading
-
-from telemetry.core import platform
-from telemetry.internal.backends.chrome import android_browser_finder
-from telemetry.internal.platform import profiler
-from telemetry.internal.util import binary_manager
-
-import py_utils
-
-try:
-  from devil.android import device_errors  # pylint: disable=import-error
-except ImportError:
-  device_errors = None
-
-
-class JavaHeapProfiler(profiler.Profiler):
-  """Android-specific, trigger and fetch java heap dumps."""
-
-  _DEFAULT_DEVICE_DIR = '/data/local/tmp/javaheap'
-  # TODO(bulach): expose this as a command line option somehow.
-  _DEFAULT_INTERVAL = 20
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(JavaHeapProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    self._run_count = 1
-
-    self._DumpJavaHeap(False)
-
-    self._timer = threading.Timer(self._DEFAULT_INTERVAL, self._OnTimer)
-    self._timer.start()
-
-  @classmethod
-  def name(cls):
-    return 'java-heap'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if browser_type == 'any':
-      return android_browser_finder.CanFindAvailableBrowsers()
-    return browser_type.startswith('android')
-
-  def CollectProfile(self):
-    self._timer.cancel()
-    self._DumpJavaHeap(True)
-    self._browser_backend.device.PullFile(
-        self._DEFAULT_DEVICE_DIR, self._output_path)
-    # Note: command must be passed as a string to expand wildcards.
-    self._browser_backend.device.RunShellCommand(
-        'rm -f ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'),
-        check_return=True, shell=True)
-    output_files = []
-    for f in os.listdir(self._output_path):
-      if os.path.splitext(f)[1] == '.aprof':
-        input_file = os.path.join(self._output_path, f)
-        output_file = input_file.replace('.aprof', '.hprof')
-        hprof_conv = binary_manager.FetchPath(
-            'hprof-conv',
-            platform.GetHostPlatform().GetArchName(),
-            platform.GetHostPlatform().GetOSName())
-        subprocess.call([hprof_conv, input_file, output_file])
-        output_files.append(output_file)
-    return output_files
-
-  def _OnTimer(self):
-    self._DumpJavaHeap(False)
-
-  def _DumpJavaHeap(self, wait_for_completion):
-    if not self._browser_backend.device.FileExists(
-        self._DEFAULT_DEVICE_DIR):
-      self._browser_backend.device.RunShellCommand(
-          ['mkdir', '-p', self._DEFAULT_DEVICE_DIR], check_return=True)
-      self._browser_backend.device.RunShellCommand(
-          ['chmod', '777', self._DEFAULT_DEVICE_DIR], check_return=True)
-
-    device_dump_file = None
-    for pid in self._GetProcessOutputFileMap().iterkeys():
-      device_dump_file = '%s/%s.%s.aprof' % (self._DEFAULT_DEVICE_DIR, pid,
-                                             self._run_count)
-      self._browser_backend.device.RunShellCommand(
-          ['am', 'dumpheap', str(pid), device_dump_file], check_return=True)
-    if device_dump_file and wait_for_completion:
-      py_utils.WaitFor(lambda: self._FileSize(device_dump_file) > 0, timeout=2)
-    self._run_count += 1
-
-  def _FileSize(self, file_name):
-    try:
-      return self._browser_backend.device.FileSize(file_name)
-    except device_errors.CommandFailedError:
-      return 0
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/monsoon.py b/catapult/telemetry/telemetry/internal/platform/profiler/monsoon.py
deleted file mode 100644
index 72425f7..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/monsoon.py
+++ /dev/null
@@ -1,292 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Interface for a USB-connected Monsoon power meter.
-
-http://msoon.com/LabEquipment/PowerMonitor/
-Currently Unix-only. Relies on fcntl, /dev, and /tmp.
-"""
-
-import collections
-import logging
-import os
-import select
-import struct
-import time
-
-import serial  # pylint: disable=import-error,no-name-in-module
-import serial.tools.list_ports  # pylint: disable=import-error,no-name-in-module
-
-
-Power = collections.namedtuple('Power', ['amps', 'volts'])
-
-
-class Monsoon(object):
-  """Provides a simple class to use the power meter.
-
-  mon = monsoon.Monsoon()
-  mon.SetVoltage(3.7)
-  mon.StartDataCollection()
-  mydata = []
-  while len(mydata) < 1000:
-    mydata.extend(mon.CollectData())
-  mon.StopDataCollection()
-  """
-
-  def __init__(self, device=None, serialno=None, wait=True):
-    """Establish a connection to a Monsoon.
-
-    By default, opens the first available port, waiting if none are ready.
-    A particular port can be specified with 'device', or a particular Monsoon
-    can be specified with 'serialno' (using the number printed on its back).
-    With wait=False, IOError is thrown if a device is not immediately available.
-    """
-    assert float(serial.VERSION) >= 2.7, \
-     'Monsoon requires pyserial v2.7 or later. You have %s' % serial.VERSION
-
-    self._coarse_ref = self._fine_ref = self._coarse_zero = self._fine_zero = 0
-    self._coarse_scale = self._fine_scale = 0
-    self._last_seq = 0
-    self._voltage_multiplier = None
-
-    if device:
-      self.ser = serial.Serial(device, timeout=1)
-      return
-
-    while 1:
-      for (port, desc, _) in serial.tools.list_ports.comports():
-        if not desc.lower().startswith('mobile device power monitor'):
-          continue
-        tmpname = '/tmp/monsoon.%s.%s' % (os.uname()[0], os.path.basename(port))
-        self._tempfile = open(tmpname, 'w')
-        try:  # Use a lockfile to ensure exclusive access.
-          # Put the import in here to avoid doing it on unsupported platforms.
-          import fcntl  # pylint: disable=import-error
-          fcntl.lockf(self._tempfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
-        except IOError:
-          logging.error('device %s is in use', port)
-          continue
-
-        try:  # Try to open the device.
-          self.ser = serial.Serial(port, timeout=1)
-          self.StopDataCollection()  # Just in case.
-          self._FlushInput()  # Discard stale input.
-          status = self.GetStatus()
-        except IOError, e:
-          logging.error('error opening device %s: %s', port, e)
-          continue
-
-        if not status:
-          logging.error('no response from device %s', port)
-        elif serialno and status['serialNumber'] != serialno:
-          logging.error('device %s is #%d', port, status['serialNumber'])
-        else:
-          if status['hardwareRevision'] == 1:
-            self._voltage_multiplier = 62.5 / 10**6
-          else:
-            self._voltage_multiplier = 125.0 / 10**6
-          return
-
-      self._tempfile = None
-      if not wait:
-        raise IOError('No device found')
-      logging.info('waiting for device...')
-      time.sleep(1)
-
-  def GetStatus(self):
-    """Requests and waits for status.  Returns status dictionary."""
-
-    # status packet format
-    STATUS_FORMAT = '>BBBhhhHhhhHBBBxBbHBHHHHBbbHHBBBbbbbbbbbbBH'
-    STATUS_FIELDS = [
-        'packetType', 'firmwareVersion', 'protocolVersion',
-        'mainFineCurrent', 'usbFineCurrent', 'auxFineCurrent', 'voltage1',
-        'mainCoarseCurrent', 'usbCoarseCurrent', 'auxCoarseCurrent', 'voltage2',
-        'outputVoltageSetting', 'temperature', 'status', 'leds',
-        'mainFineResistor', 'serialNumber', 'sampleRate',
-        'dacCalLow', 'dacCalHigh',
-        'powerUpCurrentLimit', 'runTimeCurrentLimit', 'powerUpTime',
-        'usbFineResistor', 'auxFineResistor',
-        'initialUsbVoltage', 'initialAuxVoltage',
-        'hardwareRevision', 'temperatureLimit', 'usbPassthroughMode',
-        'mainCoarseResistor', 'usbCoarseResistor', 'auxCoarseResistor',
-        'defMainFineResistor', 'defUsbFineResistor', 'defAuxFineResistor',
-        'defMainCoarseResistor', 'defUsbCoarseResistor', 'defAuxCoarseResistor',
-        'eventCode', 'eventData',
-    ]
-
-    self._SendStruct('BBB', 0x01, 0x00, 0x00)
-    while 1:  # Keep reading, discarding non-status packets.
-      data = self._ReadPacket()
-      if not data:
-        return None
-      if len(data) != struct.calcsize(STATUS_FORMAT) or data[0] != '\x10':
-        logging.debug('wanted status, dropped type=0x%02x, len=%d',
-                      ord(data[0]), len(data))
-        continue
-
-      status = dict(zip(STATUS_FIELDS, struct.unpack(STATUS_FORMAT, data)))
-      assert status['packetType'] == 0x10
-      for k in status.keys():
-        if k.endswith('VoltageSetting'):
-          status[k] = 2.0 + status[k] * 0.01
-        elif k.endswith('FineCurrent'):
-          pass  # Needs calibration data.
-        elif k.endswith('CoarseCurrent'):
-          pass  # Needs calibration data.
-        elif k.startswith('voltage') or k.endswith('Voltage'):
-          status[k] = status[k] * 0.000125
-        elif k.endswith('Resistor'):
-          status[k] = 0.05 + status[k] * 0.0001
-          if k.startswith('aux') or k.startswith('defAux'):
-            status[k] += 0.05
-        elif k.endswith('CurrentLimit'):
-          status[k] = 8 * (1023 - status[k]) / 1023.0
-      return status
-
-
-  def SetVoltage(self, v):
-    """Set the output voltage, 0 to disable."""
-    if v == 0:
-      self._SendStruct('BBB', 0x01, 0x01, 0x00)
-    else:
-      self._SendStruct('BBB', 0x01, 0x01, int((v - 2.0) * 100))
-
-  def SetStartupCurrent(self, a):
-    """Set the max startup output current. the unit of |a| : Amperes """
-    assert a >= 0 and a <= 8
-
-    val = 1023 - int((a/8.0)*1023)
-    self._SendStruct('BBB', 0x01, 0x08, val & 0xff)
-    self._SendStruct('BBB', 0x01, 0x09, val >> 8)
-
-  def SetMaxCurrent(self, a):
-    """Set the max output current. the unit of |a| : Amperes """
-    assert a >= 0 and a <= 8
-
-    val = 1023 - int((a/8.0)*1023)
-    self._SendStruct('BBB', 0x01, 0x0a, val & 0xff)
-    self._SendStruct('BBB', 0x01, 0x0b, val >> 8)
-
-  def SetUsbPassthrough(self, val):
-    """Set the USB passthrough mode: 0 = off, 1 = on,  2 = auto."""
-    self._SendStruct('BBB', 0x01, 0x10, val)
-
-
-  def StartDataCollection(self):
-    """Tell the device to start collecting and sending measurement data."""
-    self._SendStruct('BBB', 0x01, 0x1b, 0x01)  # Mystery command.
-    self._SendStruct('BBBBBBB', 0x02, 0xff, 0xff, 0xff, 0xff, 0x03, 0xe8)
-
-
-  def StopDataCollection(self):
-    """Tell the device to stop collecting measurement data."""
-    self._SendStruct('BB', 0x03, 0x00)  # Stop.
-
-
-  def CollectData(self):
-    """Return some current samples.  Call StartDataCollection() first."""
-    while 1:  # Loop until we get data or a timeout.
-      data = self._ReadPacket()
-      if not data:
-        return None
-      if len(data) < 4 + 8 + 1 or data[0] < '\x20' or data[0] > '\x2F':
-        logging.debug('wanted data, dropped type=0x%02x, len=%d',
-            ord(data[0]), len(data))
-        continue
-
-      seq, packet_type, x, _ = struct.unpack('BBBB', data[:4])
-      data = [struct.unpack(">hhhh", data[x:x+8])
-              for x in range(4, len(data) - 8, 8)]
-
-      if self._last_seq and seq & 0xF != (self._last_seq + 1) & 0xF:
-        logging.info('data sequence skipped, lost packet?')
-      self._last_seq = seq
-
-      if packet_type == 0:
-        if not self._coarse_scale or not self._fine_scale:
-          logging.info('waiting for calibration, dropped data packet')
-          continue
-
-        out = []
-        for main, usb, _, voltage in data:
-          main_voltage_v = self._voltage_multiplier * (voltage & ~3)
-          sample = 0.0
-          if main & 1:
-            sample += ((main & ~1) - self._coarse_zero) * self._coarse_scale
-          else:
-            sample += (main - self._fine_zero) * self._fine_scale
-          if usb & 1:
-            sample += ((usb & ~1) - self._coarse_zero) * self._coarse_scale
-          else:
-            sample += (usb - self._fine_zero) * self._fine_scale
-          out.append(Power(sample, main_voltage_v))
-        return out
-
-      elif packet_type == 1:
-        self._fine_zero = data[0][0]
-        self._coarse_zero = data[1][0]
-
-      elif packet_type == 2:
-        self._fine_ref = data[0][0]
-        self._coarse_ref = data[1][0]
-
-      else:
-        logging.debug('discarding data packet type=0x%02x', packet_type)
-        continue
-
-      if self._coarse_ref != self._coarse_zero:
-        self._coarse_scale = 2.88 / (self._coarse_ref - self._coarse_zero)
-      if self._fine_ref != self._fine_zero:
-        self._fine_scale = 0.0332 / (self._fine_ref - self._fine_zero)
-
-
-  def _SendStruct(self, fmt, *args):
-    """Pack a struct (without length or checksum) and send it."""
-    data = struct.pack(fmt, *args)
-    data_len = len(data) + 1
-    checksum = (data_len + sum(struct.unpack('B' * len(data), data))) % 256
-    out = struct.pack('B', data_len) + data + struct.pack('B', checksum)
-    self.ser.write(out)
-
-
-  def _ReadPacket(self):
-    """Read a single data record as a string (without length or checksum)."""
-    len_char = self.ser.read(1)
-    if not len_char:
-      logging.error('timeout reading from serial port')
-      return None
-
-    data_len = struct.unpack('B', len_char)
-    data_len = ord(len_char)
-    if not data_len:
-      return ''
-
-    result = self.ser.read(data_len)
-    if len(result) != data_len:
-      return None
-    body = result[:-1]
-    checksum = (data_len + sum(struct.unpack('B' * len(body), body))) % 256
-    if result[-1] != struct.pack('B', checksum):
-      logging.error('invalid checksum from serial port')
-      return None
-    return result[:-1]
-
-  def _FlushInput(self):
-    """Flush all read data until no more available."""
-    self.ser.flush()
-    flushed = 0
-    while True:
-      ready_r, _, ready_x = select.select([self.ser], [], [self.ser], 0)
-      if len(ready_x) > 0:
-        logging.error('exception from serial port')
-        return None
-      elif len(ready_r) > 0:
-        flushed += 1
-        self.ser.read(1)  # This may cause underlying buffering.
-        self.ser.flush()  # Flush the underlying buffer too.
-      else:
-        break
-    if flushed > 0:
-      logging.debug('dropped >%d bytes', flushed)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/monsoon_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/monsoon_profiler.py
deleted file mode 100644
index e8712e6..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/monsoon_profiler.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Profiler using data collected from a Monsoon power meter.
-
-http://msoon.com/LabEquipment/PowerMonitor/
-Data collected is a namedtuple of (amps, volts), at 5000 samples/second.
-Output graph plots power in watts over time in seconds.
-"""
-
-import csv
-import multiprocessing
-
-from telemetry.core import exceptions
-from telemetry.internal.platform import profiler
-from telemetry.internal.platform.profiler import monsoon
-from telemetry.util import statistics
-
-
-def _CollectData(output_path, is_collecting):
-  mon = monsoon.Monsoon(wait=False)
-  # Note: Telemetry requires the device to be connected by USB, but that
-  # puts it in charging mode. This increases the power consumption.
-  mon.SetUsbPassthrough(1)
-  # Nominal Li-ion voltage is 3.7V, but it puts out 4.2V at max capacity. Use
-  # 4.0V to simulate a "~80%" charged battery. Google "li-ion voltage curve".
-  # This is true only for a single cell. (Most smartphones, some tablets.)
-  mon.SetVoltage(4.0)
-
-  samples = []
-  try:
-    mon.StartDataCollection()
-    # Do one CollectData() to make the Monsoon set up, which takes about
-    # 0.3 seconds, and only signal that we've started after that.
-    mon.CollectData()
-    is_collecting.set()
-    while is_collecting.is_set():
-      samples += mon.CollectData()
-  finally:
-    mon.StopDataCollection()
-
-  # Add x-axis labels.
-  plot_data = [(i / 5000., sample.amps * sample.volts)
-               for i, sample in enumerate(samples)]
-
-  # Print data in csv.
-  with open(output_path, 'w') as output_file:
-    output_writer = csv.writer(output_file)
-    output_writer.writerows(plot_data)
-    output_file.flush()
-
-  power_samples = [s.amps * s.volts for s in samples]
-
-  print 'Monsoon profile power readings in watts:'
-  print '  Total    = %f' % statistics.TrapezoidalRule(power_samples, 1/5000.)
-  print ('  Average  = %f' % statistics.ArithmeticMean(power_samples) +
-         '+-%f' % statistics.StandardDeviation(power_samples))
-  print '  Peak     = %f' % max(power_samples)
-  print '  Duration = %f' % (len(power_samples) / 5000.)
-
-  print 'To view the Monsoon profile, run:'
-  print ('  echo "set datafile separator \',\'; plot \'%s\' with lines" | '
-      'gnuplot --persist' % output_path)
-
-
-class MonsoonProfiler(profiler.Profiler):
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(MonsoonProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    # We collect the data in a separate process, so we can continuously
-    # read the samples from the USB port while running the test.
-    self._is_collecting = multiprocessing.Event()
-    self._collector = multiprocessing.Process(
-        target=_CollectData, args=(output_path, self._is_collecting))
-    self._collector.start()
-    if not self._is_collecting.wait(timeout=0.5):
-      self._collector.terminate()
-      raise exceptions.ProfilingException('Failed to start data collection.')
-
-  @classmethod
-  def name(cls):
-    return 'monsoon'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    try:
-      monsoon.Monsoon(wait=False)
-    except EnvironmentError:
-      return False
-    else:
-      return True
-
-  def CollectProfile(self):
-    self._is_collecting.clear()
-    self._collector.join()
-    return [self._output_path]
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/netlog_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/netlog_profiler.py
deleted file mode 100644
index 4d3673d..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/netlog_profiler.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import tempfile
-
-from telemetry.internal.platform import profiler
-
-
-class NetLogProfiler(profiler.Profiler):
-
-  _NET_LOG_ARG = '--log-net-log='
-
-  @classmethod
-  def name(cls):
-    return 'netlog'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    return not browser_type.startswith('cros')
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    if browser_type.startswith('android'):
-      dump_file = '/sdcard/net-internals-profile.json'
-    else:
-      dump_file = tempfile.mkstemp()[1]
-    options.AppendExtraBrowserArgs([cls._NET_LOG_ARG + dump_file])
-
-  def CollectProfile(self):
-    # Find output filename from browser argument.
-    for i in self._browser_backend.browser_options.extra_browser_args:
-      if i.startswith(self._NET_LOG_ARG):
-        output_file = i[len(self._NET_LOG_ARG):]
-    assert output_file
-    # On Android pull the output file to the host.
-    if self._platform_backend.GetOSName() == 'android':
-      host_output_file = '%s.json' % self._output_path
-      self._browser_backend.device.PullFile(output_file, host_output_file)
-      # Clean the device
-      self._browser_backend.device.RemovePath(output_file)
-      output_file = host_output_file
-    print 'Net-internals log saved as %s' % output_file
-    print 'To view, open in chrome://net-internals'
-    return [output_file]
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/perf_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/perf_profiler.py
deleted file mode 100644
index aac177e..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/perf_profiler.py
+++ /dev/null
@@ -1,257 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import re
-import signal
-import subprocess
-import sys
-import tempfile
-
-from devil.android import device_errors  # pylint: disable=import-error
-
-from telemetry.internal.util import binary_manager
-from telemetry.core import platform
-from telemetry.internal.platform import profiler
-from telemetry.internal.platform.profiler import android_profiling_helper
-
-from devil.android.perf import perf_control  # pylint: disable=import-error
-
-
-_PERF_OPTIONS = [
-    # Sample across all processes and CPUs to so that the current CPU gets
-    # recorded to each sample.
-    '--all-cpus',
-    # In perf 3.13 --call-graph requires an argument, so use the -g short-hand
-    # which does not.
-    '-g',
-    # Record raw samples to get CPU information.
-    '--raw-samples',
-    # Increase sampling frequency for better coverage.
-    '--freq', '2000',
-]
-
-_PERF_OPTIONS_ANDROID = [
-    # Increase priority to avoid dropping samples. Requires root.
-    '--realtime', '80',
-]
-
-
-def _NicePath(path):
-  rel_path = os.path.relpath(path, os.curdir)
-  return rel_path if len(rel_path) < len(path) else path
-
-
-def _PrepareHostForPerf():
-  kptr_file = '/proc/sys/kernel/kptr_restrict'
-  with open(kptr_file) as f:
-    if f.read().strip() != '0':
-      logging.warning('Making kernel symbols unrestricted. You might have to '
-          'enter your password for "sudo".')
-      with tempfile.NamedTemporaryFile() as zero:
-        zero.write('0')
-        zero.flush()
-        subprocess.call(['/usr/bin/sudo', 'cp', zero.name, kptr_file])
-
-
-def _InstallPerfHost():
-  perfhost_name = android_profiling_helper.GetPerfhostName()
-  host = platform.GetHostPlatform()
-  if not host.CanLaunchApplication(perfhost_name):
-    host.InstallApplication(perfhost_name)
-  return binary_manager.FetchPath(perfhost_name, 'x86_64', 'linux')
-
-
-class _SingleProcessPerfProfiler(object):
-  """An internal class for using perf for a given process.
-
-  On android, this profiler uses pre-built binaries from AOSP.
-  See more details in prebuilt/android/README.txt.
-  """
-  def __init__(self, pid, output_file, browser_backend, platform_backend,
-               perf_binary, perfhost_binary):
-    self._pid = pid
-    self._browser_backend = browser_backend
-    self._platform_backend = platform_backend
-    self._output_file = output_file
-    self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
-    self._is_android = platform_backend.GetOSName() == 'android'
-    self._perf_binary = perf_binary
-    self._perfhost_binary = perfhost_binary
-    cmd_prefix = []
-    perf_args = ['record', '--pid', str(pid)]
-    if self._is_android:
-      cmd_prefix = [
-          browser_backend.device.adb.GetAdbPath(),
-          '-s', browser_backend.device.adb.GetDeviceSerial(),
-          'shell', perf_binary]
-      perf_args += _PERF_OPTIONS_ANDROID
-      output_file = os.path.join('/sdcard', 'perf_profiles',
-                                 os.path.basename(output_file))
-      self._device_output_file = output_file
-      browser_backend.device.RunShellCommand(
-          ['mkdir', '-p', os.path.dirname(self._device_output_file)],
-          check_return=True)
-      browser_backend.device.RemovePath(self._device_output_file, force=True)
-    else:
-      cmd_prefix = [perf_binary]
-    perf_args += ['--output', output_file] + _PERF_OPTIONS
-    self._proc = subprocess.Popen(cmd_prefix + perf_args,
-        stdout=self._tmp_output_file, stderr=subprocess.STDOUT)
-
-  def CollectProfile(self):
-    if ('renderer' in self._output_file and
-        not self._is_android and
-        not self._platform_backend.GetCommandLine(self._pid)):
-      logging.warning('Renderer was swapped out during profiling. '
-                      'To collect a full profile rerun with '
-                      '"--extra-browser-args=--single-process"')
-    if self._is_android:
-      device = self._browser_backend.device
-      try:
-        binary_name = os.path.basename(self._perf_binary)
-        device.KillAll(binary_name, signum=signal.SIGINT, blocking=True,
-                       quiet=True)
-      except device_errors.CommandFailedError:
-        logging.warning('The perf process could not be killed on the device.')
-    self._proc.send_signal(signal.SIGINT)
-    exit_code = self._proc.wait()
-    try:
-      if exit_code == 128:
-        raise Exception(
-            """perf failed with exit code 128.
-Try rerunning this script under sudo or setting
-/proc/sys/kernel/perf_event_paranoid to "-1".\nOutput:\n%s""" %
-            self._GetStdOut())
-      elif exit_code not in (0, -2):
-        raise Exception(
-            'perf failed with exit code %d. Output:\n%s' % (exit_code,
-                                                            self._GetStdOut()))
-    finally:
-      self._tmp_output_file.close()
-    cmd = '%s report -n -i %s' % (_NicePath(self._perfhost_binary),
-                                  self._output_file)
-    if self._is_android:
-      device = self._browser_backend.device
-      device.PullFile(self._device_output_file, self._output_file)
-      required_libs = \
-          android_profiling_helper.GetRequiredLibrariesForPerfProfile(
-              self._output_file)
-      symfs_root = os.path.join(os.path.dirname(self._output_file), 'symfs')
-      if not os.path.exists(symfs_root):
-        os.makedirs(symfs_root)
-      kallsyms = android_profiling_helper.CreateSymFs(device,
-                                                      symfs_root,
-                                                      required_libs,
-                                                      use_symlinks=True)
-      cmd += ' --symfs %s --kallsyms %s' % (symfs_root, kallsyms)
-      for lib in required_libs:
-        lib = os.path.join(symfs_root, lib[1:])
-        if not os.path.exists(lib):
-          continue
-        objdump_path = android_profiling_helper.GetToolchainBinaryPath(
-            lib, 'objdump')
-        if objdump_path:
-          cmd += ' --objdump %s' % _NicePath(objdump_path)
-          break
-
-    print 'To view the profile, run:'
-    print ' ', cmd
-    return self._output_file
-
-  def _GetStdOut(self):
-    self._tmp_output_file.flush()
-    try:
-      with open(self._tmp_output_file.name) as f:
-        return f.read()
-    except IOError:
-      return ''
-
-
-class PerfProfiler(profiler.Profiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(PerfProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    process_output_file_map = self._GetProcessOutputFileMap()
-    self._process_profilers = []
-    self._perf_control = None
-
-    perf_binary = perfhost_binary = _InstallPerfHost()
-    try:
-      if platform_backend.GetOSName() == 'android':
-        device = browser_backend.device
-        perf_binary = android_profiling_helper.PrepareDeviceForPerf(device)
-        self._perf_control = perf_control.PerfControl(device)
-        self._perf_control.SetPerfProfilingMode()
-      else:
-        _PrepareHostForPerf()
-
-      for pid, output_file in process_output_file_map.iteritems():
-        if 'zygote' in output_file:
-          continue
-        self._process_profilers.append(
-            _SingleProcessPerfProfiler(
-                pid, output_file, browser_backend, platform_backend,
-                perf_binary, perfhost_binary))
-    except:
-      if self._perf_control:
-        self._perf_control.SetDefaultPerfMode()
-      raise
-
-  @classmethod
-  def name(cls):
-    return 'perf'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if sys.platform != 'linux2':
-      return False
-    if platform.GetHostPlatform().GetOSName() == 'chromeos':
-      return False
-    return True
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    options.AppendExtraBrowserArgs([
-        '--no-sandbox',
-        '--allow-sandbox-debugging',
-    ])
-
-  def CollectProfile(self):
-    if self._perf_control:
-      self._perf_control.SetDefaultPerfMode()
-    output_files = []
-    for single_process in self._process_profilers:
-      output_files.append(single_process.CollectProfile())
-    return output_files
-
-  @classmethod
-  def GetTopSamples(cls, file_name, number):
-    """Parses the perf generated profile in |file_name| and returns a
-    {function: period} dict of the |number| hottests functions.
-    """
-    assert os.path.exists(file_name)
-    with open(os.devnull, 'w') as devnull:
-      _InstallPerfHost()
-      report = subprocess.Popen(
-          [android_profiling_helper.GetPerfhostName(),
-           'report', '--show-total-period', '-U', '-t', '^', '-i', file_name],
-          stdout=subprocess.PIPE, stderr=devnull).communicate()[0]
-    period_by_function = {}
-    for line in report.split('\n'):
-      if not line or line.startswith('#'):
-        continue
-      fields = line.split('^')
-      if len(fields) != 5:
-        continue
-      period = int(fields[1])
-      function = fields[4].partition(' ')[2]
-      function = re.sub('<.*>', '', function)  # Strip template params.
-      function = re.sub('[(].*[)]', '', function)  # Strip function params.
-      period_by_function[function] = period
-      if len(period_by_function) == number:
-        break
-    return period_by_function
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/perf_profiler_unittest.py b/catapult/telemetry/telemetry/internal/platform/profiler/perf_profiler_unittest.py
deleted file mode 100644
index 7026946..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/perf_profiler_unittest.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-import os
-import unittest
-
-from telemetry.core import util
-from telemetry.internal.platform.profiler import perf_profiler
-from telemetry.testing import options_for_unittests
-import mock
-
-class TestPerfProfiler(unittest.TestCase):
-  @mock.patch('telemetry.internal.platform.profiler.perf_profiler.subprocess')
-  def testPerfProfiler(self, mock_subprocess):
-    options = options_for_unittests.GetCopy()
-    if not perf_profiler.PerfProfiler.is_supported(options.browser_type):
-      logging.warning('PerfProfiler is not supported. Skipping test')
-      return
-
-    profile_file = os.path.join(
-        util.GetUnittestDataDir(), 'perf_report_output.txt')
-    with open(profile_file) as f:
-      perf_report_output = f.read()
-
-    mock_popen = mock.Mock()
-    mock_popen.communicate.side_effect = [[perf_report_output]]
-    mock_subprocess.Popen.side_effect = [mock_popen]
-    mock_subprocess.PIPE = mock.Mock()
-
-    perf_profiler.subprocess = mock_subprocess
-
-    self.assertEqual(
-        perf_profiler.PerfProfiler.GetTopSamples(profile_file, 10),
-        {'v8::internal::StaticMarkingVisitor::MarkMapContents': 63615201,
-         'v8::internal::RelocIterator::next': 38271931,
-         'v8::internal::LAllocator::MeetConstraintsBetween': 42913933,
-         'v8::internal::FlexibleBodyVisitor::Visit': 31909537,
-         'v8::internal::LiveRange::CreateAssignedOperand': 42913933,
-         'void v8::internal::RelocInfo::Visit': 96878864,
-         'WebCore::HTMLTokenizer::nextToken': 48240439,
-         'v8::internal::Scanner::ScanIdentifierOrKeyword': 46054550,
-         'sk_memset32_SSE2': 45121317,
-         'v8::internal::HeapObject::Size': 39786862
-         })
-    mock_popen.communicate.assert_called_once_with()
-    mock_subprocess.Popen.assert_called_once_with(
-        mock.ANY, stdout=mock.ANY, stderr=mock.ANY)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/profiler_finder.py b/catapult/telemetry/telemetry/internal/platform/profiler/profiler_finder.py
deleted file mode 100644
index 33c31e5..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/profiler_finder.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.core import discover
-from telemetry.internal.platform import profiler
-from telemetry.core import util
-
-
-def _DiscoverProfilers():
-  profiler_dir = os.path.dirname(__file__)
-  return discover.DiscoverClasses(profiler_dir, util.GetTelemetryDir(),
-                                  profiler.Profiler,
-                                  index_by_class_name=True).values()
-
-
-def FindProfiler(name):
-  for p in _DiscoverProfilers():
-    if p.name() == name:
-      return p
-  return None
-
-
-def GetAllAvailableProfilers():
-  return sorted([p.name() for p in _DiscoverProfilers()
-                 if p.is_supported(browser_type='any')])
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/sample_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/sample_profiler.py
deleted file mode 100644
index 1955901..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/sample_profiler.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import signal
-import subprocess
-import sys
-import tempfile
-
-from telemetry.core import exceptions
-from telemetry.internal.platform import profiler
-
-import py_utils
-
-
-class _SingleProcessSampleProfiler(object):
-  """An internal class for using iprofiler for a given process."""
-  def __init__(self, pid, output_path):
-    self._output_path = output_path
-    self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
-    self._proc = subprocess.Popen(
-        ['sample', str(pid), '-mayDie', '-file', self._output_path],
-        stdout=self._tmp_output_file, stderr=subprocess.STDOUT)
-    def IsStarted():
-      stdout = self._GetStdOut()
-      if 'sample cannot examine process' in stdout:
-        raise exceptions.ProfilingException(
-            'Failed to start sample for process %s\n' %
-            self._output_path.split('.')[1])
-      return 'Sampling process' in stdout
-    py_utils.WaitFor(IsStarted, 120)
-
-  def CollectProfile(self):
-    self._proc.send_signal(signal.SIGINT)
-    exit_code = self._proc.wait()
-    try:
-      if exit_code:
-        raise Exception(
-            'sample failed with exit code %d. Output:\n%s' % (
-            exit_code, self._GetStdOut()))
-    finally:
-      self._proc = None
-      self._tmp_output_file.close()
-
-    print 'To view the profile, run:'
-    print '  open -a TextEdit %s' % self._output_path
-
-    return self._output_path
-
-  def _GetStdOut(self):
-    self._tmp_output_file.flush()
-    try:
-      with open(self._tmp_output_file.name) as f:
-        return f.read()
-    except IOError:
-      return ''
-
-
-class SampleProfiler(profiler.Profiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(SampleProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    process_output_file_map = self._GetProcessOutputFileMap()
-    self._process_profilers = []
-    for pid, output_file in process_output_file_map.iteritems():
-      if '.utility' in output_file:
-        # The utility process may not have been started by Telemetry.
-        # So we won't have permissing to profile it
-        continue
-      self._process_profilers.append(
-          _SingleProcessSampleProfiler(pid, output_file))
-
-  @classmethod
-  def name(cls):
-    return 'sample'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if sys.platform != 'darwin':
-      return False
-    if browser_type == 'any':
-      return True
-    return (not browser_type.startswith('android') and
-            not browser_type.startswith('cros'))
-
-  def CollectProfile(self):
-    output_paths = []
-    for single_process in self._process_profilers:
-      output_paths.append(single_process.CollectProfile())
-    return output_paths
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/strace_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/strace_profiler.py
deleted file mode 100644
index 57f4c08..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/strace_profiler.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import re
-import signal
-import subprocess
-import sys
-import tempfile
-
-from telemetry.internal.platform import profiler
-from telemetry.timeline import model
-from tracing.trace_data import trace_data as trace_data_module
-
-
-# Parses one line of strace output, for example:
-# 6052  1311456063.159722 read(8, "\1\0\0\0\0\0\0\0", 8) = 8 <0.000022>
-_STRACE_LINE_RE = re.compile(
-    r'^(?P<tid>\d+)\s+'
-    r'(?P<ts>\d+)'
-    r'(?P<micro>.\d+)\s+'
-    r'(?P<func>.*?)'
-    r'[(](?P<args>.*?)[)]\s+=\s+'
-    r'(?P<ret>.*?)\s+'
-    r'<(?P<dur>[\d.]+)>$')
-
-_UNFINISHED_LINE_RE = re.compile(
-    r'^(?P<tid>\d+)\s+'
-    r'(?P<line>.*?)'
-    r'<unfinished ...>$')
-
-_RESUMED_LINE_RE = re.compile(
-    r'^(?P<tid>\d+)\s+'
-    r'(?P<ts>\d+)'
-    r'(?P<micro>.\d+)\s+'
-    r'<[.][.][.]\s(?P<func>.*?)\sresumed>'
-    r'(?P<line>.*?)$')
-
-_KILLED_LINE_RE = re.compile(
-    r'^(?P<tid>\d+)\s+'
-    r'(?P<ts>\d+)'
-    r'(?P<micro>.\d+)\s+'
-    r'[+][+][+] killed by SIGKILL [+][+][+]$')
-
-
-def _StraceToChromeTrace(pid, infile):
-  """Returns chrometrace json format for |infile| strace output."""
-  # Map of fd:file_name for open file descriptors. Useful for displaying
-  # file name instead of the descriptor number.
-  fd_map = {}
-
-  # Map of tid:interrupted_call for the interrupted call on each thread. It is
-  # possible to context switch during a system call. In this case we must
-  # match up the lines.
-  interrupted_call_map = {}
-
-  out = []
-  with open(infile, 'r') as f:
-    for line in f.readlines():
-      # Ignore kill lines for now.
-      m = _KILLED_LINE_RE.match(line)
-      if m:
-        continue
-
-      # If this line is interrupted, then remember it and continue.
-      m = _UNFINISHED_LINE_RE.match(line)
-      if m:
-        assert m.group('tid') not in interrupted_call_map
-        interrupted_call_map[m.group('tid')] = line
-        continue
-
-      # If this is a resume of a previous line, stitch it together.
-      interrupted = False
-      m = _RESUMED_LINE_RE.match(line)
-      if m:
-        interrupted = True
-        assert m.group('tid') in interrupted_call_map
-        line = interrupted_call_map[m.group('tid')].replace(
-            '<unfinished ...>', m.group('line'))
-        del interrupted_call_map[m.group('tid')]
-
-      # At this point we can do a normal match.
-      m = _STRACE_LINE_RE.match(line)
-      if not m:
-        if ('exit' not in line and
-            'Profiling timer expired' not in line and
-            '<unavailable>' not in line):
-          logging.warn('Failed to parse line: %s' % line)
-        continue
-
-      ts_begin = int(1000000 * (int(m.group('ts')) + float(m.group('micro'))))
-      ts_end = ts_begin + int(1000000 * float(m.group('dur')))
-      tid = int(m.group('tid'))
-      function_name = unicode(m.group('func'), errors='ignore')
-      function_args = unicode(m.group('args'), errors='ignore')
-      ret = unicode(m.group('ret'), errors='ignore')
-      cat = 'strace'
-
-      possible_fd_arg = None
-      first_arg = function_args.split(',')[0]
-      if first_arg and first_arg.strip().isdigit():
-        possible_fd_arg = first_arg.strip()
-
-      if function_name == 'open' and ret.isdigit():
-        # 1918  1311606151.649379 open("/foo/bar.so", O_RDONLY) = 7 <0.000088>
-        fd_map[ret] = first_arg
-
-      args = {
-          'args': function_args,
-          'ret': ret,
-          }
-      if interrupted:
-        args['interrupted'] = True
-      if possible_fd_arg and possible_fd_arg in fd_map:
-        args['fd%s' % first_arg] = fd_map[possible_fd_arg]
-
-      out.append({
-          'cat': cat,
-          'pid': pid,
-          'tid': tid,
-          'ts': ts_begin,
-          'ph': 'B',  # Begin
-          'name': function_name,
-          })
-      out.append({
-          'cat': cat,
-          'pid': pid,
-          'tid': tid,
-          'ts': ts_end,
-          'ph': 'E',  # End
-          'name': function_name,
-          'args': args,
-          })
-
-  return out
-
-
-def _GenerateTraceMetadata(timeline_model):
-  out = []
-  for process in timeline_model.processes:
-    out.append({
-        'name': 'process_name',
-        'ph': 'M',  # Metadata
-        'pid': process,
-        'args': {
-          'name': timeline_model.processes[process].name
-          }
-        })
-    for thread in timeline_model.processes[process].threads:
-      out.append({
-          'name': 'thread_name',
-          'ph': 'M',  # Metadata
-          'pid': process,
-          'tid': thread,
-          'args': {
-            'name': timeline_model.processes[process].threads[thread].name
-            }
-          })
-  return out
-
-
-class _SingleProcessStraceProfiler(object):
-  """An internal class for using perf for a given process."""
-  def __init__(self, pid, output_file, platform_backend):
-    self._pid = pid
-    self._platform_backend = platform_backend
-    self._output_file = output_file
-    self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
-    self._proc = subprocess.Popen(
-        ['strace', '-ttt', '-f', '-T', '-p', str(pid), '-o', output_file],
-        stdout=self._tmp_output_file, stderr=subprocess.STDOUT)
-
-  def CollectProfile(self):
-    if ('renderer' in self._output_file and
-        not self._platform_backend.GetCommandLine(self._pid)):
-      logging.warning('Renderer was swapped out during profiling. '
-                      'To collect a full profile rerun with '
-                      '"--extra-browser-args=--single-process"')
-    self._proc.send_signal(signal.SIGINT)
-    exit_code = self._proc.wait()
-    try:
-      if exit_code:
-        raise Exception('strace failed with exit code %d. Output:\n%s' % (
-                        exit_code, self._GetStdOut()))
-    finally:
-      self._tmp_output_file.close()
-
-    return _StraceToChromeTrace(self._pid, self._output_file)
-
-  def _GetStdOut(self):
-    self._tmp_output_file.flush()
-    try:
-      with open(self._tmp_output_file.name) as f:
-        return f.read()
-    except IOError:
-      return ''
-
-
-class StraceProfiler(profiler.Profiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(StraceProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    assert self._browser_backend.supports_tracing
-    self._browser_backend.browser.StartTracing(None, timeout=10)
-    process_output_file_map = self._GetProcessOutputFileMap()
-    self._process_profilers = []
-    self._output_file = output_path + '.json'
-    for pid, output_file in process_output_file_map.iteritems():
-      if 'zygote' in output_file:
-        continue
-      self._process_profilers.append(
-          _SingleProcessStraceProfiler(pid, output_file, platform_backend))
-
-  @classmethod
-  def name(cls):
-    return 'strace'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if sys.platform != 'linux2':
-      return False
-    # TODO(tonyg): This should be supported on android and cros.
-    if (browser_type.startswith('android') or
-       browser_type.startswith('cros')):
-      return False
-    return True
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    options.AppendExtraBrowserArgs([
-        '--no-sandbox',
-        '--allow-sandbox-debugging'
-    ])
-
-  def CollectProfile(self):
-    print 'Processing trace...'
-
-    out_json = []
-
-    for single_process in self._process_profilers:
-      out_json.extend(single_process.CollectProfile())
-
-    trace_data_builder = trace_data_module.TraceDataBuilder()
-    self._browser_backend.browser.StopTracing(trace_data_builder)
-    timeline_model = model.TimelineModel(trace_data_builder.AsData())
-    out_json.extend(_GenerateTraceMetadata(timeline_model))
-
-    with open(self._output_file, 'w') as f:
-      f.write(json.dumps(out_json, separators=(',', ':')))
-
-    print 'Trace saved as %s' % self._output_file
-    print 'To view, open in chrome://tracing'
-    return [self._output_file]
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/tcmalloc_heap_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/tcmalloc_heap_profiler.py
deleted file mode 100644
index 382bfb6..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/tcmalloc_heap_profiler.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import sys
-
-from telemetry.internal.backends.chrome import android_browser_finder
-from telemetry.internal.platform import profiler
-
-# Environment variables to (android properties, default value) mapping.
-_ENV_VARIABLES = {
-  'HEAP_PROFILE_TIME_INTERVAL': ('heapprof.time_interval', 20),
-  'HEAP_PROFILE_MMAP': ('heapprof.mmap', 1),
-  'DEEP_HEAP_PROFILE': ('heapprof.deep_heap_profile', 1),
-}
-
-
-class _TCMallocHeapProfilerAndroid(object):
-  """An internal class to set android properties and fetch dumps from device."""
-
-  _DEFAULT_DEVICE_DIR = '/data/local/tmp/heap'
-
-  def __init__(self, browser_backend, output_path):
-    self._browser_backend = browser_backend
-    self._output_path = output_path
-
-    _ENV_VARIABLES['HEAPPROFILE'] = ('heapprof',
-        os.path.join(self._DEFAULT_DEVICE_DIR, 'dmprof'))
-
-    self._SetDeviceProperties(_ENV_VARIABLES)
-
-  def _SetDeviceProperties(self, properties):
-    device_configured = False
-    # This profiler requires adb root to set properties.
-    self._browser_backend.device.EnableRoot()
-    for values in properties.itervalues():
-      device_property = self._browser_backend.device.GetProp(values[0])
-      if not device_property or not device_property.strip():
-        self._browser_backend.device.SetProp(values[0], values[1])
-        device_configured = True
-    if not self._browser_backend.device.FileExists(
-        self._DEFAULT_DEVICE_DIR):
-      self._browser_backend.device.RunShellCommand(
-          ['mkdir', '-p', self._DEFAULT_DEVICE_DIR], check_return=True)
-      self._browser_backend.device.RunShellCommand(
-          ['chmod', '777', self._DEFAULT_DEVICE_DIR], check_return=True)
-      device_configured = True
-    if device_configured:
-      raise Exception('Device required special config, run again.')
-
-  def CollectProfile(self):
-    try:
-      self._browser_backend.device.PullFile(
-          self._DEFAULT_DEVICE_DIR, self._output_path)
-    except:
-      logging.exception('New exception caused by DeviceUtils conversion')
-      raise
-    # Note: command must be passed as a string to expand wildcards.
-    self._browser_backend.device.RunShellCommand(
-        'rm -f ' + os.path.join(self._DEFAULT_DEVICE_DIR, '*'),
-        check_return=True, shell=True)
-    if os.path.exists(self._output_path):
-      logging.info('TCMalloc dumps pulled to %s', self._output_path)
-      with file(os.path.join(self._output_path,
-                             'browser.pid'), 'w') as pid_file:
-        pid_file.write(str(self._browser_backend.pid).rjust(5, '0'))
-    return [self._output_path]
-
-
-class _TCMallocHeapProfilerLinux(object):
-  """An internal class to set environment variables and fetch dumps."""
-
-  _DEFAULT_DIR = '/tmp/tcmalloc/'
-
-  def __init__(self, browser_backend):
-    self._browser_backend = browser_backend
-    _ENV_VARIABLES['HEAPPROFILE'] = ('heapprof', self._DEFAULT_DIR + 'dmprof')
-    self._CheckEnvironmentVariables(_ENV_VARIABLES)
-
-  def _CheckEnvironmentVariables(self, env_vars):
-    msg = ''
-    for key, values in env_vars.iteritems():
-      if key not in os.environ:
-        msg += '%s=%s ' % (key, str(values[1]))
-    if msg:
-      raise Exception('Need environment variables, try again with:\n %s' % msg)
-    if not os.path.exists(os.environ['HEAPPROFILE']):
-      os.makedirs(os.environ['HEAPPROFILE'])
-    assert os.path.isdir(os.environ['HEAPPROFILE']), 'HEAPPROFILE is not a dir'
-
-  def CollectProfile(self):
-    with file(os.path.join(os.path.dirname(os.environ['HEAPPROFILE']),
-                           'browser.pid'), 'w') as pid_file:
-      pid_file.write(str(self._browser_backend.pid))
-    print 'TCMalloc dumps available ', os.environ['HEAPPROFILE']
-    return [os.environ['HEAPPROFILE']]
-
-
-class TCMallocHeapProfiler(profiler.Profiler):
-  """A Factory to instantiate the platform-specific profiler."""
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(TCMallocHeapProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    if platform_backend.GetOSName() == 'android':
-      self._platform_profiler = _TCMallocHeapProfilerAndroid(
-          browser_backend, output_path)
-    else:
-      self._platform_profiler = _TCMallocHeapProfilerLinux(browser_backend)
-
-  @classmethod
-  def name(cls):
-    return 'tcmalloc-heap'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if browser_type.startswith('cros'):
-      return False
-    if sys.platform.startswith('linux'):
-      return True
-    if browser_type == 'any':
-      return android_browser_finder.CanFindAvailableBrowsers()
-    return browser_type.startswith('android')
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    options.AppendExtraBrowserArgs('--no-sandbox')
-    options.AppendExtraBrowserArgs('--enable-memory-benchmarking')
-
-  @classmethod
-  def WillCloseBrowser(cls, browser_backend, platform_backend):
-    # The tcmalloc_heap_profiler dumps files at regular
-    # intervals (~20 secs).
-    # This is a minor optimization to ensure it'll dump the last file when
-    # the test completes.
-    for i in xrange(len(browser_backend.browser.tabs)):
-      browser_backend.browser.tabs[i].ExecuteJavaScript("""
-        if (chrome && chrome.memoryBenchmarking) {
-          chrome.memoryBenchmarking.heapProfilerDump('renderer', 'final');
-          chrome.memoryBenchmarking.heapProfilerDump('browser', 'final');
-        }
-      """)
-
-  def CollectProfile(self):
-    return self._platform_profiler.CollectProfile()
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/tcpdump_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/tcpdump_profiler.py
deleted file mode 100644
index a8527cb..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/tcpdump_profiler.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import signal
-import subprocess
-import sys
-import tempfile
-
-from telemetry.internal.platform import profiler
-from telemetry.internal.platform.profiler import android_prebuilt_profiler_helper
-
-_TCP_DUMP_BASE_OPTS = ['-i', 'any', '-p', '-s', '0', '-w']
-
-
-class _TCPDumpProfilerAndroid(object):
-  """An internal class to collect TCP dumps on android.
-
-  This profiler uses pre-built binaries from AOSP.
-  See more details in prebuilt/android/README.txt.
-  """
-
-  _DEVICE_DUMP_FILE = '/sdcard/tcpdump_profiles/capture.pcap'
-
-  def __init__(self, device, output_path):
-    self._device = device
-    self._output_path = output_path
-    self._device.RunShellCommand(
-        ['mkdir', '-p', os.path.dirname(self._DEVICE_DUMP_FILE)],
-        check_return=True)
-    self._proc = subprocess.Popen(
-        [self._device.adb.GetAdbPath(),
-         '-s', self._device.adb.GetDeviceSerial(),
-         'shell', android_prebuilt_profiler_helper.GetDevicePath('tcpdump')] +
-         _TCP_DUMP_BASE_OPTS +
-         [self._DEVICE_DUMP_FILE])
-
-  def CollectProfile(self):
-    tcpdump_pid = self._device.GetPids('tcpdump')
-    if not tcpdump_pid or not 'tcpdump' in tcpdump_pid:
-      raise Exception('Unable to find TCPDump. Check your device is rooted '
-          'and tcpdump is installed at ' +
-          android_prebuilt_profiler_helper.GetDevicePath('tcpdump'))
-    if len(tcpdump_pid['tcpdump']) > 1:
-      raise Exception(
-          'At most one instance of process tcpdump expected but found pids: '
-          '%s' % tcpdump_pid)
-    tcpdump_pid = int(tcpdump_pid['tcpdump'][0])
-    self._device.RunShellCommand(
-        ['kill', '-term', str(tcpdump_pid)], check_return=True)
-    self._proc.terminate()
-    host_dump = os.path.join(self._output_path,
-                             os.path.basename(self._DEVICE_DUMP_FILE))
-    self._device.PullFile(self._DEVICE_DUMP_FILE, host_dump)
-    print 'TCP dump available at: %s ' % host_dump
-    print 'Use Wireshark to open it.'
-    return host_dump
-
-
-class _TCPDumpProfilerLinux(object):
-  """An internal class to collect TCP dumps on linux desktop."""
-
-  _DUMP_FILE = 'capture.pcap'
-
-  def __init__(self, output_path):
-    if not os.path.exists(output_path):
-      os.makedirs(output_path)
-    self._dump_file = os.path.join(output_path, self._DUMP_FILE)
-    self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
-    try:
-      self._proc = subprocess.Popen(
-          ['tcpdump'] + _TCP_DUMP_BASE_OPTS + [self._dump_file],
-          stdout=self._tmp_output_file, stderr=subprocess.STDOUT)
-    except OSError as e:
-      raise Exception('Unable to execute TCPDump, please check your '
-          'installation. ' + str(e))
-
-  def CollectProfile(self):
-    self._proc.send_signal(signal.SIGINT)
-    exit_code = self._proc.wait()
-    try:
-      if exit_code:
-        raise Exception(
-            'tcpdump failed with exit code %d. Output:\n%s' %
-            (exit_code, self._GetStdOut()))
-    finally:
-      self._tmp_output_file.close()
-    print 'TCP dump available at: ', self._dump_file
-    print 'Use Wireshark to open it.'
-    return self._dump_file
-
-  def _GetStdOut(self):
-    self._tmp_output_file.flush()
-    try:
-      with open(self._tmp_output_file.name) as f:
-        return f.read()
-    except IOError:
-      return ''
-
-
-class TCPDumpProfiler(profiler.Profiler):
-  """A Factory to instantiate the platform-specific profiler."""
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(TCPDumpProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    if platform_backend.GetOSName() == 'android':
-      android_prebuilt_profiler_helper.InstallOnDevice(
-          browser_backend.device, 'tcpdump')
-      self._platform_profiler = _TCPDumpProfilerAndroid(
-          browser_backend.device, output_path)
-    else:
-      self._platform_profiler = _TCPDumpProfilerLinux(output_path)
-
-  @classmethod
-  def name(cls):
-    return 'tcpdump'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if browser_type.startswith('cros'):
-      return False
-    if sys.platform.startswith('linux'):
-      return True
-    return browser_type.startswith('android')
-
-  def CollectProfile(self):
-    return self._platform_profiler.CollectProfile()
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/trace_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/trace_profiler.py
deleted file mode 100644
index a9a662a..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/trace_profiler.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.internal.platform import profiler
-from telemetry.timeline import chrome_trace_category_filter
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TraceProfiler(profiler.Profiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state,
-               categories=None):
-    super(TraceProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    assert self._browser_backend.supports_tracing
-    # We always want flow events when tracing via telemetry.
-    categories_with_flow = 'disabled-by-default-toplevel.flow'
-    if categories:
-      categories_with_flow += ',%s' % categories
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = True
-    config.chrome_trace_config.SetCategoryFilter(
-        chrome_trace_category_filter.ChromeTraceCategoryFilter(
-            categories_with_flow))
-    self._browser_backend.StartTracing(config, timeout=10)
-
-  @classmethod
-  def name(cls):
-    return 'trace'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    return True
-
-  def CollectProfile(self):
-    print 'Processing trace...'
-
-    trace_result_builder = trace_data_module.TraceDataBuilder()
-    self._browser_backend.StopTracing()
-    self._browser_backend.CollectTracingData(trace_result_builder)
-    trace_result = trace_result_builder.AsData()
-    try:
-      trace_file = '%s.html' % self._output_path
-      title = os.path.basename(self._output_path)
-      trace_result.Serialize(trace_file, trace_title=title)
-    finally:
-      trace_result.CleanUpAllTraces()
-
-    print 'Trace saved as file:///%s' % os.path.abspath(trace_file)
-
-    return [trace_file]
-
-
-class TraceDetailedProfiler(TraceProfiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(TraceDetailedProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state,
-        categories='disabled-by-default-cc.debug*')
-
-  @classmethod
-  def name(cls):
-    return 'trace-detailed'
-
-
-class TraceAllProfiler(TraceProfiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(TraceAllProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state,
-        categories='disabled-by-default-*')
-
-  @classmethod
-  def name(cls):
-    return 'trace-all'
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/trace_profiler_unittest.py b/catapult/telemetry/telemetry/internal/platform/profiler/trace_profiler_unittest.py
deleted file mode 100644
index 3e5f542..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/trace_profiler_unittest.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import shutil
-import tempfile
-
-from telemetry.internal.platform.profiler import trace_profiler
-from telemetry.testing import tab_test_case
-
-
-class TestTraceProfiler(tab_test_case.TabTestCase):
-
-  def testTraceProfiler(self):
-    try:
-      out_dir = tempfile.mkdtemp()
-      profiler = trace_profiler.TraceProfiler(
-          self._browser._browser_backend,
-          self._browser._platform_backend,
-          os.path.join(out_dir, 'trace'),
-          {})
-      result = profiler.CollectProfile()[0]
-      with open(result) as f:
-        self.assertTrue(f.read())
-    finally:
-      shutil.rmtree(out_dir)
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/v8_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/v8_profiler.py
deleted file mode 100644
index b2d930f..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/v8_profiler.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-import tempfile
-
-from telemetry.internal.platform import profiler
-
-
-class V8Profiler(profiler.Profiler):
-
-  _V8_ARG = '--js-flags=--logfile=%s --prof --log-timer-events'
-
-  @classmethod
-  def name(cls):
-    return 'v8'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    return not browser_type.startswith('cros')
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    if browser_type.startswith('android'):
-      dump_file = '/data/local/tmp/v8-profile.log'
-    else:
-      dump_file = tempfile.mkstemp()[1]
-    options.AppendExtraBrowserArgs([cls._V8_ARG % dump_file, '--no-sandbox'])
-
-  def CollectProfile(self):
-    # Find output filename from browser argument.
-    for i in self._browser_backend.browser_options.extra_browser_args:
-      match = re.match(self._V8_ARG % r'(\S+)', i)
-      if match:
-        output_file = match.groups(0)[0]
-    assert output_file
-    # On Android pull the output file to the host.
-    if self._platform_backend.GetOSName() == 'android':
-      host_output_file = '%s.log' % self._output_path
-      self._browser_backend.device.PullFile(output_file, host_output_file)
-      # Clean the device
-      self._browser_backend.device.RemovePath(output_file)
-      output_file = host_output_file
-    print 'V8 profile saved as %s' % output_file
-    print 'To view, open in ' \
-          'http://v8.googlecode.com/svn/trunk/tools/tick-processor.html'
-    return [output_file]
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/vtune_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/vtune_profiler.py
deleted file mode 100644
index edbf6ef..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/vtune_profiler.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import subprocess
-import sys
-import tempfile
-
-from telemetry.core import exceptions
-from telemetry.internal.platform import profiler
-from telemetry.internal.platform.profiler import android_profiling_helper
-
-from devil.android.sdk import adb_wrapper
-
-
-class _SingleProcessVTuneProfiler(object):
-  """An internal class for using vtune for a given process."""
-  def __init__(self, pid, output_file, browser_backend, platform_backend):
-    self._pid = pid
-    self._browser_backend = browser_backend
-    self._platform_backend = platform_backend
-    self._output_file = output_file
-    self._tmp_output_file = tempfile.NamedTemporaryFile('w', 0)
-    cmd = ['amplxe-cl', '-collect', 'hotspots',
-           '-target-pid', str(pid), '-r', self._output_file]
-    self._is_android = platform_backend.GetOSName() == 'android'
-    if self._is_android:
-      cmd += ['-target-system', 'android']
-
-    self._proc = subprocess.Popen(
-        cmd, stdout=self._tmp_output_file, stderr=subprocess.STDOUT)
-
-  def CollectProfile(self):
-    if 'renderer' in self._output_file:
-      try:
-        self._platform_backend.GetCommandLine(self._pid)
-      except exceptions.ProcessGoneException:
-        logging.warning('Renderer was swapped out during profiling. '
-                        'To collect a full profile rerun with '
-                        '"--extra-browser-args=--single-process"')
-    subprocess.call(['amplxe-cl', '-command', 'stop', '-r', self._output_file])
-
-    exit_code = self._proc.wait()
-    try:
-      # 1: amplxe: Error: Cannot find a running process with the specified ID.
-      #    Provide a valid PID.
-      if exit_code not in (0, 1):
-        raise Exception(
-            'amplxe-cl failed with exit code %d. Output:\n%s' % (exit_code,
-            self._GetStdOut()))
-    finally:
-      self._tmp_output_file.close()
-
-    if exit_code:
-      # The renderer process was swapped out. Now that we made sure VTune has
-      # stopped, return without further processing the invalid profile.
-      return self._output_file
-
-    if self._is_android:
-      required_libs = \
-          android_profiling_helper.GetRequiredLibrariesForVTuneProfile(
-              self._output_file)
-
-      device = self._browser_backend.device
-      symfs_root = os.path.join(os.path.dirname(self._output_file), 'symfs')
-      if not os.path.exists(symfs_root):
-        os.makedirs(symfs_root)
-      android_profiling_helper.CreateSymFs(device,
-                                           symfs_root,
-                                           required_libs,
-                                           use_symlinks=True)
-      logging.info('Resolving symbols in profile.')
-      subprocess.call(['amplxe-cl', '-finalize', '-r', self._output_file,
-                       '-search-dir', symfs_root])
-
-    print 'To view the profile, run:'
-    print '  amplxe-gui %s' % self._output_file
-
-    return self._output_file
-
-  def _GetStdOut(self):
-    self._tmp_output_file.flush()
-    try:
-      with open(self._tmp_output_file.name) as f:
-        return f.read()
-    except IOError:
-      return ''
-
-
-class VTuneProfiler(profiler.Profiler):
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(VTuneProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-    process_output_file_map = self._GetProcessOutputFileMap()
-    self._process_profilers = []
-
-    has_renderer = False
-    for pid, output_file in process_output_file_map.iteritems():
-      if 'renderer' in output_file:
-        has_renderer = True
-        break
-
-    for pid, output_file in process_output_file_map.iteritems():
-      if has_renderer:
-        if not 'renderer' in output_file:
-          continue
-      elif not 'browser0' in output_file:
-        continue
-
-      self._process_profilers.append(
-          _SingleProcessVTuneProfiler(pid, output_file, browser_backend,
-                                      platform_backend))
-
-  @classmethod
-  def name(cls):
-    return 'vtune'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    if sys.platform != 'linux2':
-      return False
-    if browser_type.startswith('cros'):
-      return False
-    try:
-      proc = subprocess.Popen(['amplxe-cl', '-version'],
-                              stderr=subprocess.STDOUT,
-                              stdout=subprocess.PIPE)
-      proc.communicate()
-      if proc.returncode != 0:
-        return False
-
-      if browser_type.startswith('android'):
-        # VTune checks if 'su' is available on the device.
-        proc = subprocess.Popen(
-            [adb_wrapper.AdbWrapper.GetAdbPath(),
-             'shell', 'su', '-c', 'id'],
-            stderr=subprocess.STDOUT,
-            stdout=subprocess.PIPE)
-        return 'not found' not in proc.communicate()[0]
-
-      return True
-    except OSError:
-      return False
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    options.AppendExtraBrowserArgs([
-        '--no-sandbox',
-        '--allow-sandbox-debugging',
-    ])
-
-  def CollectProfile(self):
-    print 'Processing profile, this will take a few minutes...'
-
-    output_files = []
-    for single_process in self._process_profilers:
-      output_files.append(single_process.CollectProfile())
-    return output_files
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/vtune_profiler_unittest.py b/catapult/telemetry/telemetry/internal/platform/profiler/vtune_profiler_unittest.py
deleted file mode 100644
index d763d77..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/vtune_profiler_unittest.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.platform.profiler import vtune_profiler
-from telemetry.testing import options_for_unittests
-from telemetry.testing import simple_mock
-from telemetry.testing import tab_test_case
-
-
-class MockPopen(object):
-  def __init__(self, returncode, stdout=None, stderr=None):
-    self.returncode = returncode
-    self.stdout = stdout
-    self.stderr = stderr
-
-  def communicate(self):
-    return (self.stdout, self.stderr)
-
-  def wait(self):
-    return self.returncode
-
-
-class MockSubprocess(object):
-  def __init__(self):
-    self.PIPE = simple_mock.MockObject()
-    self.STDOUT = simple_mock.MockObject()
-    self._num_collect_calls = 0
-    self._num_stop_calls = 0
-
-  @property
-  def num_collect_calls(self):
-    return self._num_collect_calls
-
-  @property
-  def num_stop_calls(self):
-    return self._num_stop_calls
-
-  def Popen(self, cmd, **_):
-    self._AnalyzeCommand(cmd)
-    return MockPopen(0)
-
-  def call(self, cmd):
-    self._AnalyzeCommand(cmd)
-
-  def _AnalyzeCommand(self, cmd):
-    if MockSubprocess._IsCollectCommand(cmd):
-      self._num_collect_calls += 1
-    elif MockSubprocess._IsStopCommand(cmd):
-      self._num_stop_calls += 1
-
-  @staticmethod
-  def _IsCollectCommand(cmd):
-    return '-collect' in cmd
-
-  @staticmethod
-  def _IsStopCommand(cmd):
-    try:
-      cmd_idx = cmd.index('-command') + 1
-      return cmd_idx < len(cmd) and cmd[cmd_idx] == 'stop'
-    except ValueError:
-      return False
-
-
-class TestVTuneProfiler(unittest.TestCase):
-
-  def testVTuneProfilerIsSupported(self):
-    options = options_for_unittests.GetCopy()
-
-    mock_subprocess = simple_mock.MockObject()
-    mock_subprocess.ExpectCall(
-        'Popen').WithArgs(simple_mock.DONT_CARE).WillReturn(MockPopen(0))
-    mock_subprocess.SetAttribute('PIPE', simple_mock.MockObject())
-    mock_subprocess.SetAttribute('STDOUT', simple_mock.MockObject())
-
-    real_subprocess = vtune_profiler.subprocess
-    vtune_profiler.subprocess = mock_subprocess
-
-    if options.browser_type.startswith('android'):
-      # On Android we're querying if 'su' is available.
-      mock_subprocess.ExpectCall('Popen').WithArgs(
-          simple_mock.DONT_CARE).WillReturn(MockPopen(0, 'su', None))
-
-    try:
-      self.assertTrue(
-          vtune_profiler.VTuneProfiler.is_supported(options.browser_type) or
-          sys.platform != 'linux2' or
-          options.browser_type.startswith('cros'))
-    finally:
-      vtune_profiler.subprocess = real_subprocess
-
-
-class TestVTuneProfilerTabTestCase(tab_test_case.TabTestCase):
-
-  # This test is only meant to be run if VTune is installed locally. Please
-  # run it locally if you are modifying related code, but it's disabled on the
-  # bots because they don't have VTune. See crbug.com/437085
-  @decorators.Disabled('all')
-  def testVTuneProfiler(self):
-    mock_subprocess = MockSubprocess()
-    real_subprocess = vtune_profiler.subprocess
-    vtune_profiler.subprocess = mock_subprocess
-
-    try:
-      # pylint: disable=protected-access
-      profiler = vtune_profiler.VTuneProfiler(self._browser._browser_backend,
-                                              self._browser._platform_backend,
-                                              'tmp',
-                                              {})
-      profiler.CollectProfile()
-      self.assertEqual(mock_subprocess.num_collect_calls,
-                       mock_subprocess.num_stop_calls)
-    finally:
-      vtune_profiler.subprocess = real_subprocess
diff --git a/catapult/telemetry/telemetry/internal/platform/profiler/win_pgo_profiler.py b/catapult/telemetry/telemetry/internal/platform/profiler/win_pgo_profiler.py
deleted file mode 100644
index d11e43b..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiler/win_pgo_profiler.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import glob
-import os
-import subprocess
-import sys
-
-from telemetry.internal.platform import profiler
-
-_PGOSWEEP_EXECUTABLE = 'pgosweep.exe'
-
-
-class WinPGOProfiler(profiler.Profiler):
-  """A profiler that run the Visual Studio PGO utility 'pgosweep.exe' before
-  terminating a browser or a renderer process.
-  """
-
-  def __init__(self, browser_backend, platform_backend, output_path, state):
-    super(WinPGOProfiler, self).__init__(
-        browser_backend, platform_backend, output_path, state)
-
-    self._pgosweep_path = None
-
-    if os.path.exists(os.path.join(browser_backend.browser_directory,
-                                   _PGOSWEEP_EXECUTABLE)):
-      self._pgosweep_path = os.path.join(browser_backend.browser_directory,
-                                         _PGOSWEEP_EXECUTABLE)
-
-    if not self._pgosweep_path:
-      for entry in os.environ['PATH'].split(os.pathsep):
-        if os.path.exists(os.path.join(entry, _PGOSWEEP_EXECUTABLE)):
-          self._pgosweep_path = os.path.join(entry, _PGOSWEEP_EXECUTABLE)
-          break
-    if not self._pgosweep_path:
-      raise IOError(2, 'Can\'t find %s, run vcvarsall.bat to fix this.' %
-                    _PGOSWEEP_EXECUTABLE)
-
-    self._browser_dir = browser_backend.browser_directory
-    self._chrome_child_pgc_counter = self._GetNextProfileIndex('chrome_child')
-
-  def _GetNextProfileIndex(self, dll_name):
-    """Scan the directory containing the DLL |dll_name| to find the next index
-    to use for the profile data files.
-
-    Args:
-      dll_name: The name of the DLL for which we want to get the next index to
-          to use.
-    """
-    max_index = 0
-    pgc_files = glob.glob(os.path.join(self._browser_dir,
-                                       '%s!*.pgc' % dll_name))
-    for pgc_file in pgc_files:
-      max_index = max(max_index,
-          int(os.path.splitext(os.path.split(pgc_file)[1])[0].split('!')[1]))
-    return max_index + 1
-
-  def _RunPGOSweep(self, pid, dll_name, index):
-    """Run the pgosweep utility to gather the profile data of a given process.
-
-    Args:
-      pid: The PID of the process we're interested in.
-      dll_name: The name of the DLL for which we want the profile data.
-      index: The index to use for the profile data file.
-
-    Returns the name of the profile data file.
-    """
-    pgc_filename = '%s\\%s!%d.pgc' % (self._browser_dir, dll_name, index)
-    subprocess.Popen([self._pgosweep_path,
-                      '/pid:%d' % pid,
-                      '%s.dll' % dll_name,
-                      pgc_filename]
-                    ).wait()
-    return pgc_filename
-
-  @classmethod
-  def name(cls):
-    return 'win_pgo_profiler'
-
-  @classmethod
-  def is_supported(cls, browser_type):
-    # This profiler only make sense when doing a Windows build with Visual
-    # Studio (minimal supported version is 2013 Update 2).
-    return sys.platform.startswith('win')
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, browser_type, options):
-    # The sandbox need to be disabled if we want to be able to gather the
-    # profile data.
-    options.AppendExtraBrowserArgs('--no-sandbox')
-
-  def CollectProfile(self):
-    """Collect the profile data for the current processes."""
-    output_files = []
-    for pid, output_file in self._GetProcessOutputFileMap().iteritems():
-      if 'renderer' in output_file:
-        output_files.append(self._RunPGOSweep(pid,
-                                              'chrome_child',
-                                              self._chrome_child_pgc_counter))
-        self._chrome_child_pgc_counter += 1
-    return output_files
diff --git a/catapult/telemetry/telemetry/internal/platform/profiling_controller_backend.py b/catapult/telemetry/telemetry/internal/platform/profiling_controller_backend.py
deleted file mode 100644
index 744bc28..0000000
--- a/catapult/telemetry/telemetry/internal/platform/profiling_controller_backend.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.internal.platform.profiler import profiler_finder
-
-
-class ProfilingControllerBackend(object):
-  def __init__(self, platform_backend, browser_backend):
-    self._platform_backend = platform_backend
-    self._browser_backend = browser_backend
-    self._active_profilers = []
-    self._profilers_states = {}
-
-  def Start(self, profiler_name, base_output_file):
-    """Starts profiling using |profiler_name|. Results are saved to
-    |base_output_file|.<process_name>."""
-    assert not self._active_profilers, 'Already profiling. Must stop first.'
-
-    profiler_class = profiler_finder.FindProfiler(profiler_name)
-
-    if not profiler_class.is_supported(self._browser_backend.browser_type):
-      raise Exception('The %s profiler is not '
-                      'supported on this platform.' % profiler_name)
-
-    if not profiler_class in self._profilers_states:
-      self._profilers_states[profiler_class] = {}
-
-    self._active_profilers.append(
-        profiler_class(self._browser_backend, self._platform_backend,
-            base_output_file, self._profilers_states[profiler_class]))
-
-  def Stop(self):
-    """Stops all active profilers and saves their results.
-
-    Returns:
-      A list of filenames produced by the profiler.
-    """
-    output_files = []
-    for profiler in self._active_profilers:
-      output_files.extend(profiler.CollectProfile())
-    self._active_profilers = []
-    return output_files
-
-  def WillCloseBrowser(self):
-    for profiler_class in self._profilers_states:
-      profiler_class.WillCloseBrowser(
-        self._browser_backend, self._platform_backend)
diff --git a/catapult/telemetry/telemetry/internal/platform/remote_platform_options.py b/catapult/telemetry/telemetry/internal/platform/remote_platform_options.py
deleted file mode 100644
index 05c9df5..0000000
--- a/catapult/telemetry/telemetry/internal/platform/remote_platform_options.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class RemotePlatformOptions(object):
-  """Options to be used for creating a remote platform instance."""
-
-
-class AndroidPlatformOptions(RemotePlatformOptions):
-  """Android-specific remote platform options."""
-
-  def __init__(self, device=None, android_blacklist_file=None):
-    super(AndroidPlatformOptions, self).__init__()
-
-    self.device = device
-    self.android_blacklist_file = android_blacklist_file
diff --git a/catapult/telemetry/telemetry/internal/platform/system_info.py b/catapult/telemetry/telemetry/internal/platform/system_info.py
deleted file mode 100644
index 8cf6d17..0000000
--- a/catapult/telemetry/telemetry/internal/platform/system_info.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.internal.platform import gpu_info
-
-
-class SystemInfo(object):
-  """Provides low-level system information."""
-
-  def __init__(self, model_name, gpu_dict):
-    if (model_name == None) or (gpu_dict == None):
-      raise Exception("Missing model_name or gpu_dict argument")
-    self._model_name = model_name
-    self._gpu = gpu_info.GPUInfo.FromDict(gpu_dict)
-
-  @classmethod
-  def FromDict(cls, attrs):
-    """Constructs a SystemInfo from a dictionary of attributes.
-       Attributes currently required to be present in the dictionary:
-
-         model_name (string): a platform-dependent string
-           describing the model of machine, or the empty string if not
-           supported.
-         gpu (object containing GPUInfo's required attributes)
-    """
-    return cls(attrs["model_name"], attrs["gpu"])
-
-  @property
-  def model_name(self):
-    """A string describing the machine model.
-
-       This is a highly platform-dependent value and not currently
-       specified for any machine type aside from Macs. On Mac OS, this
-       is the model identifier, reformatted slightly; for example,
-       'MacBookPro 10.1'."""
-    return self._model_name
-
-  @property
-  def gpu(self):
-    """A GPUInfo object describing the graphics processor(s) on the system."""
-    return self._gpu
diff --git a/catapult/telemetry/telemetry/internal/platform/system_info_unittest.py b/catapult/telemetry/telemetry/internal/platform/system_info_unittest.py
deleted file mode 100644
index d4c341e..0000000
--- a/catapult/telemetry/telemetry/internal/platform/system_info_unittest.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.internal.platform import gpu_device
-from telemetry.internal.platform import gpu_info
-from telemetry.internal.platform import system_info
-
-
-class TestSystemInfo(unittest.TestCase):
-
-  def testConstruction(self):
-    data = {
-        'model_name': 'MacBookPro 10.1',
-        'gpu': {
-            'devices': [
-                {'vendor_id': 1000, 'device_id': 2000,
-                 'vendor_string': 'a', 'device_string': 'b'},
-            ]
-        }
-    }
-    info = system_info.SystemInfo.FromDict(data)
-    self.assertTrue(isinstance(info, system_info.SystemInfo))
-    self.assertTrue(isinstance(info.gpu, gpu_info.GPUInfo))
-    self.assertEquals(info.model_name, 'MacBookPro 10.1')
-    self.assertTrue(len(info.gpu.devices) == 1)
-    self.assertTrue(isinstance(info.gpu.devices[0], gpu_device.GPUDevice))
-    self.assertEquals(info.gpu.devices[0].vendor_id, 1000)
-    self.assertEquals(info.gpu.devices[0].device_id, 2000)
-    self.assertEquals(info.gpu.devices[0].vendor_string, 'a')
-    self.assertEquals(info.gpu.devices[0].device_string, 'b')
-
-  def testEmptyModelName(self):
-    data = {
-        'model_name': '',
-        'gpu': {
-            'devices': [
-                {'vendor_id': 1000, 'device_id': 2000,
-                 'vendor_string': 'a', 'device_string': 'b'},
-            ]
-        }
-    }
-    try:
-      info = system_info.SystemInfo.FromDict(data)
-      self.assertEquals(info.model_name, '')
-    except AssertionError:
-      raise
-    except Exception:
-      self.fail('Should not raise exception for empty model_name string')
-
-  def testMissingAttrsFromDict(self):
-    data = {
-        'model_name': 'MacBookPro 10.1',
-        'devices': [{'vendor_id': 1000, 'device_id': 2000,
-                     'vendor_string': 'a', 'device_string': 'b'}]
-    }
-
-    for k in data:
-      data_copy = data.copy()
-      del data_copy[k]
-      try:
-        system_info.SystemInfo.FromDict(data_copy)
-        self.fail('Should raise exception if attribute "%s" is missing' % k)
-      except AssertionError:
-        raise
-      except KeyError:
-        pass
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/__init__.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/__init__.py
deleted file mode 100644
index f57b0ec..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/__init__.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class TracingAgent(object):
-  """A tracing agent provided by the platform.
-
-  A tracing agent can gather data with Start() until Stop().
-  Before constructing an TracingAgent, check whether it's supported on the
-  platform with IsSupported method first.
-
-  NOTE: All subclasses of TracingAgent must not change the constructor's
-  parameters so the agents can be dynamically constructed in
-  tracing_controller_backend.
-
-  """
-
-  def __init__(self, platform_backend):
-    self._platform_backend = platform_backend
-
-  @classmethod
-  def IsSupported(cls, platform_backend):
-    del platform_backend  # unused
-    return False
-
-  def StartAgentTracing(self, config, timeout):
-    """ Override to add tracing agent's custom logic to start tracing.
-
-    Depending on trace_options and category_filter, the tracing agent may choose
-    to start or not start tracing.
-
-    Args:
-      config: tracing_config instance that contains trace_option and
-        category_filter
-        trace_options: an instance of tracing_options.TracingOptions that
-          control which core tracing systems should be enabled.
-        category_filter: an instance of
-          chrome_trace_category_filter.ChromeTraceCategoryFilter
-      timeout: number of seconds that this tracing agent should try to start
-        tracing until time out.
-
-    Returns:
-      True if tracing agent started successfully.
-    """
-    raise NotImplementedError
-
-  def StopAgentTracing(self):
-    """ Override to add tracing agent's custom logic to stop tracing.
-
-    StopAgentTracing() should guarantee tracing is stopped, even if there may
-    be exception.
-    """
-    raise NotImplementedError
-
-  def SupportsFlushingAgentTracing(self):
-    """ Override to indicate support of flushing tracing. """
-    return False
-
-  def FlushAgentTracing(self, config, timeout, trace_data_builder):
-    """ Override to add tracing agent's custom logic to flush tracing. """
-    del config, timeout, trace_data_builder  # unused
-    raise NotImplementedError
-
-  def SupportsExplicitClockSync(self):
-    """ Override to indicate support of explicit clock syncing. """
-    return False
-
-  def RecordClockSyncMarker(self, sync_id,
-                            record_controller_clocksync_marker_callback):
-    """ Override to record clock sync marker.
-
-    Only override if supports explicit clock syncing.
-    Args:
-      sync_id: Unqiue id for sync event.
-      record_controller_clocksync_marker_callback: Function that accepts two
-        arguments: a sync ID and a timestamp taken immediately before the
-        controller requested that the agent write a clock sync marker into its
-        trace. Any tracing agent that implements this method must invoke this
-        callback immediately after receiving confirmation from the agent that
-        the clock sync marker was recorded.
-
-        We use a callback here rather than just calling this function after
-        RecordClockSyncMarker because it's important for clock sync accuracy
-        reasons that the "issued" timestamp and "received confirmation"
-        timestamp be as accurate as possible, and some agents are forced to do
-        additional time-consuming cleanup work in RecordClockSyncMarker after
-        receiving this confirmation.
-    """
-    del sync_id # unused
-    del record_controller_clocksync_marker_callback # unused
-    raise NotImplementedError
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    """ Override to add agent's custom logic to collect tracing data. """
-    del trace_data_builder
-    del timeout
-    raise NotImplementedError
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/atrace_tracing_agent.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/atrace_tracing_agent.py
deleted file mode 100644
index 02ca3c7..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/atrace_tracing_agent.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from systrace.tracing_agents import atrace_agent
-from telemetry.internal.platform import tracing_agent
-from tracing.trace_data import trace_data
-
-from devil.android.sdk import version_codes
-
-
-class AtraceTracingAgent(tracing_agent.TracingAgent):
-  def __init__(self, platform_backend):
-    super(AtraceTracingAgent, self).__init__(platform_backend)
-    self._device = platform_backend.device
-    self._categories = None
-    self._atrace_agent = atrace_agent.AtraceAgent(
-        platform_backend.device.build_version_sdk)
-    self._config = None
-
-  @classmethod
-  def IsSupported(cls, platform_backend):
-    return (platform_backend.GetOSName() == 'android' and
-        platform_backend.device.build_version_sdk >
-            version_codes.JELLY_BEAN_MR1)
-
-  def StartAgentTracing(self, config, timeout):
-    if not config.enable_atrace_trace:
-      return False
-
-    app_name = (','.join(config.atrace_config.app_name) if
-        isinstance(config.atrace_config.app_name, list) else
-        config.atrace_config.app_name)
-    self._config = atrace_agent.AtraceConfig(
-        config.atrace_config.categories,
-        trace_buf_size=None, kfuncs=None, app_name=app_name,
-        compress_trace_data=True, from_file=True,
-        device_serial_number=str(self._device), trace_time=None,
-        target='android')
-    return self._atrace_agent.StartAgentTracing(self._config, timeout)
-
-  def StopAgentTracing(self):
-    self._atrace_agent.StopAgentTracing()
-
-  def SupportsExplicitClockSync(self):
-    return self._atrace_agent.SupportsExplicitClockSync()
-
-  def RecordClockSyncMarker(self, sync_id,
-                            record_controller_clock_sync_marker_callback):
-    return self._atrace_agent.RecordClockSyncMarker(sync_id,
-        lambda t, sid: record_controller_clock_sync_marker_callback(sid, t))
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    raw_data = self._atrace_agent.GetResults(timeout).raw_data
-    trace_data_builder.AddTraceFor(trace_data.ATRACE_PART, raw_data)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/battor_tracing_agent.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/battor_tracing_agent.py
deleted file mode 100644
index 42dac1c..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/battor_tracing_agent.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from battor import battor_error
-from battor import battor_wrapper
-from py_utils import cloud_storage
-from devil.android import battery_utils
-from py_trace_event import trace_time
-from telemetry.internal.platform import tracing_agent
-from telemetry.internal.util import atexit_with_log
-from tracing.trace_data import trace_data
-
-
-def _ReenableChargingIfNeeded(battery):
-  if not battery.GetCharging():
-    battery.SetCharging(True)
-  logging.info('Charging status checked at exit.')
-
-
-class BattOrTracingAgent(tracing_agent.TracingAgent):
-  """A tracing agent for getting power data from a BattOr device.
-
-  BattOrTracingAgent allows Telemetry to issue high-level tracing commands
-  (StartTracing, StopTracing, RecordClockSyncMarker) to BattOrs, which are
-  high-frequency power monitors used for battery testing.
-  """
-
-  def __init__(self, platform_backend):
-    super(BattOrTracingAgent, self).__init__(platform_backend)
-    self._platform_backend = platform_backend
-    android_device = (
-        platform_backend.device if platform_backend.GetOSName() == 'android'
-        else None)
-    self._battery = (
-        battery_utils.BatteryUtils(platform_backend.device)
-        if platform_backend.GetOSName() == 'android' else None)
-    self._battor = battor_wrapper.BattOrWrapper(
-        platform_backend.GetOSName(), android_device=android_device,
-        serial_log_bucket=cloud_storage.TELEMETRY_OUTPUT)
-
-  @classmethod
-  def IsSupported(cls, platform_backend):
-    """Returns True if BattOr tracing is available."""
-    if platform_backend.GetOSName() == 'android':
-      # TODO(rnephew): When we pass BattOr device map into Telemetry, change
-      # this to reflect that.
-      return battor_wrapper.IsBattOrConnected(
-          'android', android_device=platform_backend.device)
-    return battor_wrapper.IsBattOrConnected(platform_backend.GetOSName())
-
-  def StartAgentTracing(self, config, timeout):
-    """Start tracing on the BattOr.
-
-    Args:
-      config: A TracingConfig instance.
-      timeout: number of seconds that this tracing agent should try to start
-        tracing until timing out.
-
-    Returns:
-      True if the tracing agent started successfully.
-    """
-    if not config.enable_battor_trace:
-      return False
-    try:
-      if self._battery:
-        self._battery.SetCharging(False)
-        atexit_with_log.Register(_ReenableChargingIfNeeded, self._battery)
-
-      self._battor.StartShell()
-      self._battor.StartTracing()
-      return True
-    except battor_error.BattOrError:
-      if self._battery:
-        self._battery.SetCharging(True)
-      raise
-
-  def StopAgentTracing(self):
-    """Stops tracing on the BattOr."""
-    try:
-      self._battor.StopTracing()
-    finally:
-      if self._battery:
-        self._battery.SetCharging(True)
-
-  def SupportsExplicitClockSync(self):
-    return self._battor.SupportsExplicitClockSync()
-
-  def RecordClockSyncMarker(self, sync_id,
-                            record_controller_clock_sync_marker_callback):
-    """Records a clock sync marker in the BattOr trace.
-
-    Args:
-      sync_id: Unique id for sync event.
-      record_controller_clock_sync_marker_callback: Function that takes a sync
-        ID and a timestamp as arguments. This function typically will record the
-        tracing controller clock sync marker.
-    """
-    timestamp = trace_time.Now()
-    try:
-      self._battor.RecordClockSyncMarker(sync_id)
-    except battor_error.BattOrError:
-      logging.critical(
-          'Error while clock syncing with BattOr. Killing BattOr shell.')
-      self._battor.KillBattOrShell()
-      raise
-    record_controller_clock_sync_marker_callback(sync_id, timestamp)
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    data = self._battor.CollectTraceData(timeout=timeout)
-    trace_data_builder.AddTraceFor(trace_data.BATTOR_TRACE_PART, data)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/battor_tracing_agent_unittest.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/battor_tracing_agent_unittest.py
deleted file mode 100644
index 1c6dc06..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/battor_tracing_agent_unittest.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from battor import battor_error
-from battor import battor_wrapper
-from devil.android import battery_utils
-from telemetry.internal.platform.tracing_agent import battor_tracing_agent
-from telemetry.timeline import trace_data
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data
-
-
-_BATTOR_RETURN = 'fake\nbattor\ndata'
-
-
-class FakeBatteryUtils(object):
-  def __init__(self, device):
-    self._device = device
-    self._charging_state = True
-
-  def SetCharging(self, state):
-    self._charging_state = state
-
-  def GetCharging(self):
-    return self._charging_state
-
-
-class FakePlatformBackend(object):
-  def GetOSName(self):
-    return ''
-
-
-class FakeAndroidPlatformBackend(FakePlatformBackend):
-  def __init__(self):
-    super(FakeAndroidPlatformBackend, self).__init__()
-    self.device = 'fake_device'
-
-  def GetOSName(self):
-    return 'android'
-
-
-class FakeDesktopPlatformBackend(FakePlatformBackend):
-  def __init__(self):
-    self.platform = 'win'
-
-  def GetOSName(self):
-    return self.platform
-
-
-class FakeBattOr(object):
-  def __init__(self, test_platform, android_device=None, battor_path=None,
-               battor_map=None, serial_log_bucket=None):
-    self._is_shell_running = False
-    self._android_device = android_device
-    self._battor_path = battor_path
-    self._battor_map = battor_map
-    self._test_platform = test_platform
-    self._serial_log_bucket = serial_log_bucket
-    self._stop_tracing_called = False
-    self._start_shell_called = False
-    self._start_tracing_called = False
-    self._collect_trace_data_called = False
-    self._record_clock_sync_marker_called = False
-
-  def IsShellRunning(self):
-    return self._is_shell_running
-
-  def StartShell(self):
-    self._is_shell_running = True
-    self._start_shell_called = True
-
-  def StartTracing(self):
-    self.StartShell()
-    self._start_tracing_called = True
-
-  def StopTracing(self):
-    self._is_shell_running = False
-    self._stop_tracing_called = True
-
-  def CollectTraceData(self, timeout=None):
-    del timeout # unused
-    self._collect_trace_data_called = True
-    return _BATTOR_RETURN
-
-  def RecordClockSyncMarker(self, _):
-    self._record_clock_sync_marker_called = True
-
-
-class BattOrTracingAgentTest(unittest.TestCase):
-  def setUp(self):
-    self._config = tracing_config.TracingConfig()
-    self._config.enable_battor_trace = True
-
-    # Monkey patch BattOrWrapper.
-    self._battor_wrapper = battor_wrapper.BattOrWrapper
-    battor_wrapper.BattOrWrapper = FakeBattOr
-    battor_wrapper.IsBattOrConnected = lambda x, android_device=None: True
-
-    self._battery_utils = battery_utils.BatteryUtils
-    battery_utils.BatteryUtils = FakeBatteryUtils
-
-    # Agents and backends.
-    self.android_backend = FakeAndroidPlatformBackend()
-    self.desktop_backend = FakeDesktopPlatformBackend()
-    self.android_agent = (
-        battor_tracing_agent.BattOrTracingAgent(self.android_backend))
-    self.desktop_agent = (
-        battor_tracing_agent.BattOrTracingAgent(self.desktop_backend))
-
-  def tearDown(self):
-    battor_wrapper.BattOrWrapper = self._battor_wrapper
-    battery_utils.BatteryUtils = self._battery_utils
-
-  def testInit(self):
-    self.assertTrue(isinstance(self.android_agent._platform_backend,
-                               FakeAndroidPlatformBackend))
-    self.assertTrue(isinstance(self.desktop_agent._platform_backend,
-                               FakeDesktopPlatformBackend))
-
-  def testIsSupportedAndroid(self):
-    self.assertTrue(battor_tracing_agent.BattOrTracingAgent.IsSupported(
-        self.android_backend))
-    battor_wrapper.IsBattOrConnected = lambda x, android_device=None: False
-    self.assertFalse(battor_tracing_agent.BattOrTracingAgent.IsSupported(
-        self.android_backend))
-
-  def testIsSupportedNonAndroid(self):
-    self.desktop_backend.platform = 'mac'
-    battor_wrapper.IsBattOrConnected = lambda *unused: True
-    self.assertTrue(battor_tracing_agent.BattOrTracingAgent.IsSupported(
-        self.desktop_backend))
-    battor_wrapper.IsBattOrConnected = lambda *unused: False
-    self.assertFalse(battor_tracing_agent.BattOrTracingAgent.IsSupported(
-        self.desktop_backend))
-
-  def testStartAgentTracingPass(self):
-    self.assertTrue(self.android_agent.StartAgentTracing(self._config, 0))
-    self.assertTrue(self.android_agent._battor._is_shell_running)
-    self.assertTrue(self.android_agent._battor._start_shell_called)
-    self.assertTrue(self.android_agent._battor._start_tracing_called)
-    self.assertFalse(self.android_agent._battor._stop_tracing_called)
-    self.assertFalse(
-        self.android_agent._battor._record_clock_sync_marker_called)
-
-  def testStartAgentTracingConfigSetToFalse(self):
-    self._config.enable_battor_trace = False
-    self.assertFalse(self.android_agent.StartAgentTracing(self._config, 0))
-    self.assertFalse(self.android_agent._battor._is_shell_running)
-    self.assertFalse(self.android_agent._battor._start_shell_called)
-    self.assertFalse(self.android_agent._battor._start_tracing_called)
-    self.assertFalse(self.android_agent._battor._stop_tracing_called)
-    self.assertFalse(
-        self.android_agent._battor._record_clock_sync_marker_called)
-
-  def testStartAgentTracingFail(self):
-    def throw_battor_error():
-      raise battor_error.BattOrError('Forced Exception')
-    self.android_agent._battor.StartTracing = throw_battor_error
-    with self.assertRaises(battor_error.BattOrError):
-      self.android_agent.StartAgentTracing(self._config, 0)
-
-  def testStopAgentTracing(self):
-    self.android_agent.StopAgentTracing()
-    self.assertTrue(self.android_agent._battor._stop_tracing_called)
-
-  def testCollectAgentTraceData(self):
-    builder = trace_data.TraceDataBuilder()
-    self.android_agent.CollectAgentTraceData(builder)
-    self.assertTrue(self.android_agent._battor._collect_trace_data_called)
-    builder = builder.AsData()
-    self.assertTrue(builder.HasTracesFor(trace_data.BATTOR_TRACE_PART))
-    data_from_builder = builder.GetTracesFor(trace_data.BATTOR_TRACE_PART)
-    self.assertEqual([_BATTOR_RETURN], data_from_builder)
-
-  def testAndroidCharging(self):
-    self.assertTrue(self.android_agent._battery.GetCharging())
-    self.assertTrue(self.android_agent.StartAgentTracing(self._config, 0))
-    self.assertFalse(self.android_agent._battery.GetCharging())
-    self.android_agent.StopAgentTracing()
-    self.assertTrue(self.android_agent._battery.GetCharging())
-
-  def testRecordClockSyncMarker(self):
-    def callback_with_exception(a, b):
-      del a # unused
-      del b # unused
-      raise Exception
-    def callback_without_exception(a, b):
-      del a # unused
-      del b # unused
-
-    self.android_agent.RecordClockSyncMarker('123', callback_without_exception)
-    with self.assertRaises(Exception):
-      self.android_agent.RecordClockSyncMarker('abc', callback_with_exception)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_agent.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_agent.py
deleted file mode 100644
index 0572989..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_agent.py
+++ /dev/null
@@ -1,331 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.util import atexit_with_log
-import json
-import logging
-import os
-import shutil
-import stat
-import sys
-import tempfile
-import traceback
-
-from py_trace_event import trace_time
-from telemetry.internal.platform import tracing_agent
-from telemetry.internal.platform.tracing_agent import (
-    chrome_tracing_devtools_manager)
-
-_DESKTOP_OS_NAMES = ['linux', 'mac', 'win']
-_STARTUP_TRACING_OS_NAMES = _DESKTOP_OS_NAMES + ['android', 'chromeos']
-
-# The trace config file path should be the same as specified in
-# src/components/tracing/trace_config_file.[h|cc]
-_CHROME_TRACE_CONFIG_DIR_ANDROID = '/data/local/'
-_CHROME_TRACE_CONFIG_DIR_CROS = '/tmp/'
-_CHROME_TRACE_CONFIG_FILE_NAME = 'chrome-trace-config.json'
-
-
-def ClearStarupTracingStateIfNeeded(platform_backend):
-  # Trace config file has fixed path on Android and temporary path on desktop.
-  if platform_backend.GetOSName() == 'android':
-    trace_config_file = os.path.join(_CHROME_TRACE_CONFIG_DIR_ANDROID,
-                                     _CHROME_TRACE_CONFIG_FILE_NAME)
-    platform_backend.device.RunShellCommand(
-        ['rm', '-f', trace_config_file], check_return=True, as_root=True)
-
-
-class ChromeTracingStartedError(Exception):
-  pass
-
-
-class ChromeTracingStoppedError(Exception):
-  pass
-
-
-class ChromeClockSyncError(Exception):
-  pass
-
-
-class ChromeTracingAgent(tracing_agent.TracingAgent):
-  def __init__(self, platform_backend):
-    super(ChromeTracingAgent, self).__init__(platform_backend)
-    self._trace_config = None
-    self._trace_config_file = None
-    self._previously_responsive_devtools = []
-
-  @property
-  def trace_config(self):
-    # Trace config is also used to check if Chrome tracing is running or not.
-    return self._trace_config
-
-  @property
-  def trace_config_file(self):
-    return self._trace_config_file
-
-  @classmethod
-  def IsStartupTracingSupported(cls, platform_backend):
-    if platform_backend.GetOSName() in _STARTUP_TRACING_OS_NAMES:
-      return True
-    else:
-      return False
-
-  @classmethod
-  def IsSupported(cls, platform_backend):
-    if cls.IsStartupTracingSupported(platform_backend):
-      return True
-    else:
-      return chrome_tracing_devtools_manager.IsSupported(platform_backend)
-
-  def _StartStartupTracing(self, config):
-    if not self.IsStartupTracingSupported(self._platform_backend):
-      return False
-    self._CreateTraceConfigFile(config)
-    return True
-
-  def _StartDevToolsTracing(self, config, timeout):
-    if not chrome_tracing_devtools_manager.IsSupported(self._platform_backend):
-      return False
-    devtools_clients = (chrome_tracing_devtools_manager
-        .GetActiveDevToolsClients(self._platform_backend))
-    if not devtools_clients:
-      return False
-    for client in devtools_clients:
-      if client.is_tracing_running:
-        raise ChromeTracingStartedError(
-            'Tracing is already running on devtools at port %s on platform'
-            'backend %s.' % (client.remote_port, self._platform_backend))
-      client.StartChromeTracing(config, timeout)
-    return True
-
-  def StartAgentTracing(self, config, timeout):
-    if not config.enable_chrome_trace:
-      return False
-
-    if self._trace_config:
-      raise ChromeTracingStartedError(
-          'Tracing is already running on platform backend %s.'
-          % self._platform_backend)
-
-    if (config.enable_android_graphics_memtrack and
-        self._platform_backend.GetOSName() == 'android'):
-      self._platform_backend.SetGraphicsMemoryTrackingEnabled(True)
-
-    # Chrome tracing Agent needs to start tracing for chrome browsers that are
-    # not yet started, and for the ones that already are. For the former, we
-    # first setup the trace_config_file, which allows browsers that starts after
-    # this point to use it for enabling tracing upon browser startup. For the
-    # latter, we invoke start tracing command through devtools for browsers that
-    # are already started and tracked by chrome_tracing_devtools_manager.
-    started_startup_tracing = self._StartStartupTracing(config)
-    started_devtools_tracing = self._StartDevToolsTracing(config, timeout)
-    if started_startup_tracing or started_devtools_tracing:
-      self._trace_config = config
-      return True
-    return False
-
-  def SupportsExplicitClockSync(self):
-    return True
-
-  def _RecordClockSyncMarkerDevTools(
-      self, sync_id, record_controller_clock_sync_marker_callback,
-      devtools_clients):
-    has_clock_synced = False
-    for client in devtools_clients:
-      try:
-        timestamp = trace_time.Now()
-        client.RecordChromeClockSyncMarker(sync_id)
-        # We only need one successful clock sync.
-        has_clock_synced = True
-        break
-      except Exception:
-        logging.exception('Failed to record clock sync marker with sync_id=%r '
-                          'via DevTools client %r:' % (sync_id, client))
-    if not has_clock_synced:
-      raise ChromeClockSyncError(
-          'Failed to issue clock sync to devtools client')
-    record_controller_clock_sync_marker_callback(sync_id, timestamp)
-
-  def _RecordClockSyncMarkerAsyncEvent(
-      self, sync_id, record_controller_clock_sync_marker_callback):
-    has_clock_synced = False
-    for backend in self._IterInspectorBackends():
-      try:
-        timestamp = trace_time.Now()
-        event = 'ClockSyncEvent.%s' % sync_id
-        backend.EvaluateJavaScript(
-            "console.time({{ event }});", event=event)
-        backend.EvaluateJavaScript(
-            "console.timeEnd({{ event }});", event=event)
-        has_clock_synced = True
-        break
-      except Exception:
-        logging.exception('Failed to record clock sync marker with sync_id=%r '
-                          'via inspector backend %r:' % (sync_id, backend))
-    if not has_clock_synced:
-      raise ChromeClockSyncError(
-          'Failed to issue clock sync to devtools client')
-    record_controller_clock_sync_marker_callback(sync_id, timestamp)
-
-  def RecordClockSyncMarker(self, sync_id,
-                            record_controller_clock_sync_marker_callback):
-    devtools_clients = (chrome_tracing_devtools_manager
-        .GetActiveDevToolsClients(self._platform_backend))
-    if not devtools_clients:
-      raise ChromeClockSyncError('Cannot issue clock sync. No devtools clients')
-    version = None
-    for client in devtools_clients:
-      version = client.GetChromeBranchNumber()
-      break
-    logging.info('Chrome version: %s', version)
-    # Note, we aren't sure whether 2744 is the correct cut-off point which
-    # Chrome will support clock sync marker, however we verified that 2743 does
-    # not support clock sync (catapult/issues/2804) hence we use it here.
-    # On the next update of Chrome ref build, if testTBM2ForSmoke still fails,
-    # the cut-off branch number will need to be bumped up again.
-    if version and int(version) > 2743:
-      self._RecordClockSyncMarkerDevTools(
-          sync_id, record_controller_clock_sync_marker_callback,
-          devtools_clients)
-    else:  # TODO(rnephew): Remove once chrome stable is past branch 2743.
-      self._RecordClockSyncMarkerAsyncEvent(
-          sync_id, record_controller_clock_sync_marker_callback)
-
-  def StopAgentTracing(self):
-    if not self._trace_config:
-      raise ChromeTracingStoppedError(
-          'Tracing is not running on platform backend %s.'
-          % self._platform_backend)
-
-    if self.IsStartupTracingSupported(self._platform_backend):
-      self._RemoveTraceConfigFile()
-
-    # We get all DevTools clients including the stale ones, so that we get an
-    # exception if there is a stale client. This is because we will potentially
-    # lose data if there is a stale client.
-    devtools_clients = (chrome_tracing_devtools_manager
-        .GetDevToolsClients(self._platform_backend))
-    raised_exception_messages = []
-    assert len(self._previously_responsive_devtools) == 0
-    for client in devtools_clients:
-      try:
-        client.StopChromeTracing()
-        self._previously_responsive_devtools.append(client)
-
-      except Exception:
-        raised_exception_messages.append(
-          'Error when trying to stop Chrome tracing on devtools at port %s:\n%s'
-          % (client.remote_port,
-             ''.join(traceback.format_exception(*sys.exc_info()))))
-
-    if (self._trace_config.enable_android_graphics_memtrack and
-        self._platform_backend.GetOSName() == 'android'):
-      self._platform_backend.SetGraphicsMemoryTrackingEnabled(False)
-
-    self._trace_config = None
-    if raised_exception_messages:
-      raise ChromeTracingStoppedError(
-          'Exceptions raised when trying to stop Chrome devtool tracing:\n' +
-          '\n'.join(raised_exception_messages))
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    raised_exception_messages = []
-    for client in self._previously_responsive_devtools:
-      try:
-        client.CollectChromeTracingData(trace_data_builder)
-      except Exception:
-        raised_exception_messages.append(
-          'Error when collecting Chrome tracing on devtools at port %s:\n%s'
-          % (client.remote_port,
-             ''.join(traceback.format_exception(*sys.exc_info()))))
-    self._previously_responsive_devtools = []
-
-    if raised_exception_messages:
-      raise ChromeTracingStoppedError(
-          'Exceptions raised when trying to collect Chrome devtool tracing:\n' +
-          '\n'.join(raised_exception_messages))
-
-  def _CreateTraceConfigFileString(self, config):
-    # See src/components/tracing/trace_config_file.h for the format
-    result = {
-      'trace_config':
-        config.chrome_trace_config.GetChromeTraceConfigForStartupTracing()
-    }
-    return json.dumps(result, sort_keys=True)
-
-  def _CreateTraceConfigFile(self, config):
-    assert not self._trace_config_file
-    if self._platform_backend.GetOSName() == 'android':
-      self._trace_config_file = os.path.join(_CHROME_TRACE_CONFIG_DIR_ANDROID,
-                                             _CHROME_TRACE_CONFIG_FILE_NAME)
-      self._platform_backend.device.WriteFile(self._trace_config_file,
-          self._CreateTraceConfigFileString(config), as_root=True)
-      # The config file has fixed path on Android. We need to ensure it is
-      # always cleaned up.
-      atexit_with_log.Register(self._RemoveTraceConfigFile)
-    elif self._platform_backend.GetOSName() == 'chromeos':
-      self._trace_config_file = os.path.join(_CHROME_TRACE_CONFIG_DIR_CROS,
-                                             _CHROME_TRACE_CONFIG_FILE_NAME)
-      cri = self._platform_backend.cri
-      cri.PushContents(self._CreateTraceConfigFileString(config),
-                       self._trace_config_file)
-      cri.Chown(self._trace_config_file)
-      # The config file has fixed path on CrOS. We need to ensure it is
-      # always cleaned up.
-      atexit_with_log.Register(self._RemoveTraceConfigFile)
-    elif self._platform_backend.GetOSName() in _DESKTOP_OS_NAMES:
-      self._trace_config_file = os.path.join(tempfile.mkdtemp(),
-                                             _CHROME_TRACE_CONFIG_FILE_NAME)
-      with open(self._trace_config_file, 'w') as f:
-        trace_config_string = self._CreateTraceConfigFileString(config)
-        logging.info('Trace config file string: %s', trace_config_string)
-        f.write(trace_config_string)
-      os.chmod(self._trace_config_file,
-               os.stat(self._trace_config_file).st_mode | stat.S_IROTH)
-    else:
-      raise NotImplementedError
-
-  def _RemoveTraceConfigFile(self):
-    if not self._trace_config_file:
-      return
-    if self._platform_backend.GetOSName() == 'android':
-      self._platform_backend.device.RunShellCommand(
-          ['rm', '-f', self._trace_config_file], check_return=True,
-          as_root=True)
-    elif self._platform_backend.GetOSName() == 'chromeos':
-      self._platform_backend.cri.RmRF(self._trace_config_file)
-    elif self._platform_backend.GetOSName() in _DESKTOP_OS_NAMES:
-      if os.path.exists(self._trace_config_file):
-        os.remove(self._trace_config_file)
-      shutil.rmtree(os.path.dirname(self._trace_config_file))
-    else:
-      raise NotImplementedError
-    self._trace_config_file = None
-
-  def SupportsFlushingAgentTracing(self):
-    return True
-
-  def FlushAgentTracing(self, config, timeout, trace_data_builder):
-    if not self._trace_config:
-      raise ChromeTracingStoppedError(
-          'Tracing is not running on platform backend %s.'
-          % self._platform_backend)
-
-    for backend in self._IterInspectorBackends():
-      backend.EvaluateJavaScript("console.time('flush-tracing');")
-
-    self.StopAgentTracing()
-    self.CollectAgentTraceData(trace_data_builder)
-    self.StartAgentTracing(config, timeout)
-
-    for backend in self._IterInspectorBackends():
-      backend.EvaluateJavaScript("console.timeEnd('flush-tracing');")
-
-  def _IterInspectorBackends(self):
-    for client in chrome_tracing_devtools_manager.GetDevToolsClients(
-        self._platform_backend):
-      context_map = client.GetUpdatedInspectableContexts()
-      for context in context_map.contexts:
-        if context['type'] in ['iframe', 'page', 'webview']:
-          yield context_map.GetInspectorBackend(context['id'])
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_agent_unittest.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_agent_unittest.py
deleted file mode 100644
index b4d3c51..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_agent_unittest.py
+++ /dev/null
@@ -1,387 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import platform
-import stat
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.platform.tracing_agent import chrome_tracing_agent
-from telemetry.internal.platform.tracing_agent import (
-    chrome_tracing_devtools_manager)
-from telemetry.timeline import tracing_config
-from telemetry.core import cros_interface
-from telemetry.testing import options_for_unittests
-
-
-from devil.android import device_utils
-
-
-class FakeTracingControllerBackend(object):
-  def __init__(self):
-    self.is_tracing_running = False
-
-
-class FakePlatformBackend(object):
-  def __init__(self):
-    self.tracing_controller_backend = FakeTracingControllerBackend()
-
-  def GetOSName(self):
-    return ''
-
-class FakeAndroidPlatformBackend(FakePlatformBackend):
-  def __init__(self):
-    super(FakeAndroidPlatformBackend, self).__init__()
-    devices = device_utils.DeviceUtils.HealthyDevices(None)
-    self.device = devices[0]
-
-  def GetOSName(self):
-    return 'android'
-
-class FakeCrOSPlatformBackend(FakePlatformBackend):
-  def __init__(self):
-    super(FakeCrOSPlatformBackend, self).__init__()
-    remote = options_for_unittests.GetCopy().cros_remote
-    remote_ssh_port = options_for_unittests.GetCopy().cros_remote_ssh_port
-    self.cri = cros_interface.CrOSInterface(
-        remote, remote_ssh_port,
-        options_for_unittests.GetCopy().cros_ssh_identity)
-
-  def GetOSName(self):
-    return 'chromeos'
-
-class FakeDesktopPlatformBackend(FakePlatformBackend):
-  def GetOSName(self):
-    system = platform.system()
-    if system == 'Linux':
-      return 'linux'
-    if system == 'Darwin':
-      return 'mac'
-    if system == 'Windows':
-      return 'win'
-
-
-class FakeContextMap(object):
-  def __init__(self, contexts):
-    self.contexts = contexts
-
-
-class FakeDevtoolsClient(object):
-  def __init__(self, remote_port):
-    self.is_alive = True
-    self.is_tracing_running = False
-    self.remote_port = remote_port
-    self.will_raise_exception_in_stop_tracing = False
-    self.collected = False
-
-  def IsAlive(self):
-    return self.is_alive
-
-  def StartChromeTracing(self, trace_options, timeout=10):
-    del trace_options, timeout  # unused
-    self.is_tracing_running = True
-
-  def StopChromeTracing(self):
-    self.is_tracing_running = False
-    if self.will_raise_exception_in_stop_tracing:
-      raise Exception
-
-  def CollectChromeTracingData(self, trace_data_builder, timeout=30):
-    del trace_data_builder  # unused
-    del timeout # unused
-    self.collected = True
-
-  def IsChromeTracingSupported(self):
-    return True
-
-  def GetUpdatedInspectableContexts(self):
-    return FakeContextMap([])
-
-
-class ChromeTracingAgentTest(unittest.TestCase):
-  def setUp(self):
-    self.platform1 = FakePlatformBackend()
-    self.platform2 = FakePlatformBackend()
-    self.platform3 = FakePlatformBackend()
-
-  def StartTracing(self, platform_backend, enable_chrome_trace=True):
-    assert chrome_tracing_agent.ChromeTracingAgent.IsSupported(platform_backend)
-    agent = chrome_tracing_agent.ChromeTracingAgent(platform_backend)
-    config = tracing_config.TracingConfig()
-    config.enable_chrome_trace = enable_chrome_trace
-    config.chrome_trace_config.category_filter.AddIncludedCategory('foo')
-    agent._platform_backend.tracing_controller_backend.is_tracing_running = True
-    agent._test_config = config
-    agent.StartAgentTracing(config, 10)
-    return agent
-
-  def FlushTracing(self, agent):
-    agent.FlushAgentTracing(agent._test_config, 10, None)
-
-  def StopTracing(self, agent):
-    agent._platform_backend.tracing_controller_backend.is_tracing_running = (
-        False)
-    agent.StopAgentTracing()
-    agent.CollectAgentTraceData(None)
-
-  def testRegisterDevtoolsClient(self):
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        FakeDevtoolsClient(1), self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        FakeDevtoolsClient(2), self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        FakeDevtoolsClient(3), self.platform1)
-
-    tracing_agent_of_platform1 = self.StartTracing(self.platform1)
-
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        FakeDevtoolsClient(4), self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        FakeDevtoolsClient(5), self.platform2)
-
-    self.StopTracing(tracing_agent_of_platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        FakeDevtoolsClient(6), self.platform1)
-
-  def testIsSupportWithoutStartupTracingSupport(self):
-    self.assertFalse(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(self.platform1))
-    self.assertFalse(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(self.platform2))
-    self.assertFalse(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(self.platform3))
-
-    devtool1 = FakeDevtoolsClient(1)
-    devtool2 = FakeDevtoolsClient(2)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool1, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool2, self.platform2)
-    devtool2.is_alive = False
-
-    # Chrome tracing is only supported on platform 1 since only platform 1 has
-    # an alive devtool.
-    self.assertTrue(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(self.platform1))
-    self.assertFalse(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(self.platform2))
-    self.assertFalse(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(self.platform3))
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testIsSupportOnDesktopPlatform(self):
-    # Chrome tracing is always supported on desktop platforms because of startup
-    # tracing.
-    desktop_platform = FakeDesktopPlatformBackend()
-    self.assertTrue(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(desktop_platform))
-
-    devtool = FakeDevtoolsClient(1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool, desktop_platform)
-    self.assertTrue(
-        chrome_tracing_agent.ChromeTracingAgent.IsSupported(desktop_platform))
-
-  def testStartAndStopTracing(self):
-    devtool1 = FakeDevtoolsClient(1)
-    devtool2 = FakeDevtoolsClient(2)
-    devtool3 = FakeDevtoolsClient(3)
-    devtool4 = FakeDevtoolsClient(2)
-    # Register devtools 1, 2, 3 on platform1 and devtool 4 on platform 2
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool1, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool2, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool3, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool4, self.platform2)
-    devtool2.is_alive = False
-
-    tracing_agent1 = self.StartTracing(self.platform1)
-    with self.assertRaises(chrome_tracing_agent.ChromeTracingStartedError):
-      self.StartTracing(self.platform1)
-
-    self.assertTrue(devtool1.is_tracing_running)
-    self.assertFalse(devtool2.is_tracing_running)
-    self.assertTrue(devtool3.is_tracing_running)
-    # Devtool 4 shouldn't have tracing started although it has the same remote
-    # port as devtool 2
-    self.assertFalse(devtool4.is_tracing_running)
-
-
-    self.assertFalse(devtool1.collected)
-    self.StopTracing(tracing_agent1)
-    self.assertTrue(devtool1.collected)
-    self.assertFalse(devtool1.is_tracing_running)
-    self.assertFalse(devtool2.is_tracing_running)
-    self.assertFalse(devtool3.is_tracing_running)
-    self.assertFalse(devtool4.is_tracing_running)
-
-    # Test that it should be ok to start & stop tracing on platform1 again.
-    tracing_agent1 = self.StartTracing(self.platform1)
-    self.StopTracing(tracing_agent1)
-
-    tracing_agent2 = self.StartTracing(self.platform2)
-    self.assertTrue(devtool4.is_tracing_running)
-    self.assertFalse(devtool4.collected)
-    self.StopTracing(tracing_agent2)
-    self.assertFalse(devtool4.is_tracing_running)
-    self.assertTrue(devtool4.collected)
-
-  def testFlushTracing(self):
-    devtool1 = FakeDevtoolsClient(1)
-    devtool2 = FakeDevtoolsClient(2)
-    devtool3 = FakeDevtoolsClient(3)
-    devtool4 = FakeDevtoolsClient(2)
-
-    # Register devtools 1, 2, 3 on platform1 and devtool 4 on platform 2.
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool1, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool2, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool3, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool4, self.platform2)
-    devtool2.is_alive = False
-
-    tracing_agent1 = self.StartTracing(self.platform1)
-
-    self.assertTrue(devtool1.is_tracing_running)
-    self.assertFalse(devtool2.is_tracing_running)
-    self.assertTrue(devtool3.is_tracing_running)
-    # Devtool 4 shouldn't have tracing started although it has the same remote
-    # port as devtool 2.
-    self.assertFalse(devtool4.is_tracing_running)
-
-    for _ in xrange(5):
-      self.FlushTracing(tracing_agent1)
-      self.assertTrue(devtool1.is_tracing_running)
-      self.assertFalse(devtool2.is_tracing_running)
-      self.assertTrue(devtool3.is_tracing_running)
-      self.assertFalse(devtool4.is_tracing_running)
-
-    self.StopTracing(tracing_agent1)
-    self.assertFalse(devtool1.is_tracing_running)
-    self.assertFalse(devtool2.is_tracing_running)
-    self.assertFalse(devtool3.is_tracing_running)
-    self.assertFalse(devtool4.is_tracing_running)
-
-    # Test that it is ok to start, flush & stop tracing on platform1 again.
-    tracing_agent1 = self.StartTracing(self.platform1)
-    self.FlushTracing(tracing_agent1)
-    self.StopTracing(tracing_agent1)
-
-    tracing_agent2 = self.StartTracing(self.platform2)
-    self.assertTrue(devtool4.is_tracing_running)
-    self.FlushTracing(tracing_agent2)
-    self.assertTrue(devtool4.is_tracing_running)
-    self.StopTracing(tracing_agent2)
-    self.assertFalse(devtool4.is_tracing_running)
-
-  def testExceptionRaisedInStopTracing(self):
-    devtool1 = FakeDevtoolsClient(1)
-    devtool2 = FakeDevtoolsClient(2)
-    # Register devtools 1, 2 on platform 1
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool1, self.platform1)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool2, self.platform1)
-    tracing_agent1 = self.StartTracing(self.platform1)
-
-    self.assertTrue(devtool1.is_tracing_running)
-    self.assertTrue(devtool2.is_tracing_running)
-
-    devtool1.will_raise_exception_in_stop_tracing = True
-    with self.assertRaises(chrome_tracing_agent.ChromeTracingStoppedError):
-      self.StopTracing(tracing_agent1)
-    # Tracing is stopped on both devtools clients even if there is exception.
-    self.assertIsNone(tracing_agent1.trace_config)
-    self.assertFalse(devtool1.is_tracing_running)
-    self.assertFalse(devtool2.is_tracing_running)
-
-    devtool1.is_alive = False
-    devtool2.is_alive = False
-    # Register devtools 3 on platform 1 should not raise any exception.
-    devtool3 = FakeDevtoolsClient(3)
-    chrome_tracing_devtools_manager.RegisterDevToolsClient(
-        devtool3, self.platform1)
-
-    # Start & Stop tracing on platform 1 should work just fine.
-    tracing_agent2 = self.StartTracing(self.platform1)
-    self.StopTracing(tracing_agent2)
-
-  @decorators.Enabled('android')
-  def testCreateAndRemoveTraceConfigFileOnAndroid(self):
-    platform_backend = FakeAndroidPlatformBackend()
-    agent = chrome_tracing_agent.ChromeTracingAgent(platform_backend)
-    self.assertIsNone(agent.trace_config_file)
-
-    config = tracing_config.TracingConfig()
-    agent._CreateTraceConfigFile(config)
-    self.assertIsNotNone(agent.trace_config_file)
-    self.assertTrue(platform_backend.device.PathExists(agent.trace_config_file))
-    config_file_str = platform_backend.device.ReadFile(agent.trace_config_file,
-                                                       as_root=True)
-    self.assertEqual(agent._CreateTraceConfigFileString(config),
-                     config_file_str.strip())
-
-    config_file_path = agent.trace_config_file
-    agent._RemoveTraceConfigFile()
-    self.assertFalse(platform_backend.device.PathExists(config_file_path))
-    self.assertIsNone(agent.trace_config_file)
-    # robust to multiple file removal
-    agent._RemoveTraceConfigFile()
-    self.assertFalse(platform_backend.device.PathExists(config_file_path))
-    self.assertIsNone(agent.trace_config_file)
-
-  @decorators.Enabled('chromeos')
-  def testCreateAndRemoveTraceConfigFileOnCrOS(self):
-    platform_backend = FakeCrOSPlatformBackend()
-    cri = platform_backend.cri
-    agent = chrome_tracing_agent.ChromeTracingAgent(platform_backend)
-    self.assertIsNone(agent.trace_config_file)
-
-    config = tracing_config.TracingConfig()
-    agent._CreateTraceConfigFile(config)
-    self.assertIsNotNone(agent.trace_config_file)
-    self.assertTrue(cri.FileExistsOnDevice(agent.trace_config_file))
-    config_file_str = cri.GetFileContents(agent.trace_config_file)
-    self.assertEqual(agent._CreateTraceConfigFileString(config),
-                     config_file_str.strip())
-
-    config_file_path = agent.trace_config_file
-    agent._RemoveTraceConfigFile()
-    self.assertFalse(cri.FileExistsOnDevice(config_file_path))
-    self.assertIsNone(agent.trace_config_file)
-    # robust to multiple file removal
-    agent._RemoveTraceConfigFile()
-    self.assertFalse(cri.FileExistsOnDevice(config_file_path))
-    self.assertIsNone(agent.trace_config_file)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testCreateAndRemoveTraceConfigFileOnDesktop(self):
-    platform_backend = FakeDesktopPlatformBackend()
-    agent = chrome_tracing_agent.ChromeTracingAgent(platform_backend)
-    self.assertIsNone(agent.trace_config_file)
-
-    config = tracing_config.TracingConfig()
-    agent._CreateTraceConfigFile(config)
-    self.assertIsNotNone(agent.trace_config_file)
-    self.assertTrue(os.path.exists(agent.trace_config_file))
-    self.assertTrue(os.stat(agent.trace_config_file).st_mode & stat.S_IROTH)
-    with open(agent.trace_config_file, 'r') as f:
-      config_file_str = f.read()
-      self.assertEqual(agent._CreateTraceConfigFileString(config),
-                       config_file_str.strip())
-
-    config_file_path = agent.trace_config_file
-    agent._RemoveTraceConfigFile()
-    self.assertFalse(os.path.exists(config_file_path))
-    self.assertIsNone(agent.trace_config_file)
-    # robust to multiple file removal
-    agent._RemoveTraceConfigFile()
-    self.assertFalse(os.path.exists(config_file_path))
-    self.assertIsNone(agent.trace_config_file)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_devtools_manager.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_devtools_manager.py
deleted file mode 100644
index ea2bde2..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/chrome_tracing_devtools_manager.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# A singleton map from platform backends to maps of uniquely-identifying
-# remote port (which may be the same as local port) to DevToolsClientBackend.
-# There is no guarantee that the devtools agent is still alive.
-_platform_backends_to_devtools_clients_maps = {}
-
-
-def _RemoveStaleDevToolsClient(platform_backend):
-  """Removes DevTools clients that are no longer connectable."""
-  devtools_clients_map = _platform_backends_to_devtools_clients_maps.get(
-      platform_backend, {})
-  devtools_clients_map = {
-      port: client
-      for port, client in devtools_clients_map.iteritems()
-      if client.IsAlive()
-      }
-  _platform_backends_to_devtools_clients_maps[platform_backend] = (
-      devtools_clients_map)
-
-
-def RegisterDevToolsClient(devtools_client_backend, platform_backend):
-  """Register DevTools client
-
-  This should only be called from DevToolsClientBackend when it is initialized.
-  """
-  remote_port = str(devtools_client_backend.remote_port)
-  if platform_backend not in _platform_backends_to_devtools_clients_maps:
-    _platform_backends_to_devtools_clients_maps[platform_backend] = {}
-  devtools_clients_map = (
-    _platform_backends_to_devtools_clients_maps[platform_backend])
-  devtools_clients_map[remote_port] = devtools_client_backend
-
-
-def IsSupported(platform_backend):
-  _RemoveStaleDevToolsClient(platform_backend)
-  devtools_clients_map = _platform_backends_to_devtools_clients_maps.get(
-      platform_backend, {})
-  for _, devtools_client in devtools_clients_map.iteritems():
-    if devtools_client.IsChromeTracingSupported():
-      return True
-  return False
-
-
-def GetDevToolsClients(platform_backend):
-  """Get DevTools clients including the ones that are no longer connectable."""
-  devtools_clients_map = _platform_backends_to_devtools_clients_maps.get(
-      platform_backend, {})
-  if not devtools_clients_map:
-    return []
-  return devtools_clients_map.values()
-
-def GetActiveDevToolsClients(platform_backend):
-  """Get DevTools clients that are still connectable."""
-  _RemoveStaleDevToolsClient(platform_backend)
-  return GetDevToolsClients(platform_backend)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/cpu_tracing_agent.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/cpu_tracing_agent.py
deleted file mode 100644
index 92427d5..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/cpu_tracing_agent.py
+++ /dev/null
@@ -1,326 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import os
-import re
-import subprocess
-from threading import Timer
-
-from py_trace_event import trace_time
-from telemetry.internal.platform import tracing_agent
-from tracing.trace_data import trace_data
-
-
-def _ParsePsProcessString(line):
-  """Parses a process line from the output of `ps`.
-
-  Example of `ps` command output:
-  '3.4 8.0 31887 31447 com.app.Webkit'
-  """
-  token_list = line.strip().split()
-  if len(token_list) < 5:
-    raise ValueError('Line has too few tokens: %s.' % token_list)
-
-  return {
-    'pCpu': float(token_list[0]),
-    'pMem': float(token_list[1]),
-    'pid': int(token_list[2]),
-    'ppid': int(token_list[3]),
-    'name': ' '.join(token_list[4:])
-  }
-
-
-class ProcessCollector(object):
-  def _GetProcessesAsStrings(self):
-    """Returns a list of strings, each of which contains info about a
-    process.
-    """
-    raise NotImplementedError
-
-  # pylint: disable=unused-argument
-  def _ParseProcessString(self, proc_string):
-    """Parses an individual process string returned by _GetProcessesAsStrings().
-
-    Returns:
-      A dictionary containing keys of 'pid' (an integer process ID), 'ppid' (an
-      integer parent process ID), 'name' (a string for the process name), 'pCpu'
-      (a float for the percent CPU load incurred by the process), and 'pMem' (a
-      float for the percent memory load caused by the process).
-    """
-    raise NotImplementedError
-
-  def Init(self):
-    """Performs any required initialization before starting tracing."""
-    pass
-
-  def GetProcesses(self):
-    """Fetches the top processes returned by top command.
-
-    Returns:
-      A list of dictionaries, each containing 'pid' (an integer process ID),
-      'ppid' (an integer parent process ID), 'name (a string for the process
-      name), pCpu' (a float for the percent CPU load incurred by the process),
-      and 'pMem' (a float for the percent memory load caused by the process).
-    """
-    proc_strings = self._GetProcessesAsStrings()
-    return [
-        self._ParseProcessString(proc_string) for proc_string in proc_strings
-    ]
-
-
-class WindowsProcessCollector(ProcessCollector):
-  """Class for collecting information about processes on Windows.
-
-  Example of Windows command output:
-  '3644      1724   chrome#1                 8           84497'
-  '3644      832    chrome#2                 4           34872'
-  """
-  _GET_PERF_DATA_SHELL_COMMAND = [
-    'wmic',
-    'path', # Retrieve a WMI object from the following path.
-    'Win32_PerfFormattedData_PerfProc_Process', # Contains process perf data.
-    'get',
-    'CreatingProcessID,IDProcess,Name,PercentProcessorTime,WorkingSet'
-  ]
-
-  _GET_COMMANDS_SHELL_COMMAND = [
-    'wmic',
-    'Process',
-    'get',
-    'CommandLine,ProcessID',
-    # Formatting the result as a CSV means that if no CommandLine is available,
-    # we can at least tell by the lack of data between commas.
-    '/format:csv'
-  ]
-
-  _GET_PHYSICAL_MEMORY_BYTES_SHELL_COMMAND = [
-    'wmic',
-    'ComputerSystem',
-    'get',
-    'TotalPhysicalMemory'
-  ]
-
-  def __init__(self):
-    self._physicalMemoryBytes = None
-
-  def Init(self):
-    if not self._physicalMemoryBytes:
-      self._physicalMemoryBytes = self._GetPhysicalMemoryBytes()
-
-    # The command to get the per-process perf data takes significantly longer
-    # the first time that it's run (~10s, compared to ~60ms for subsequent
-    # runs). In order to avoid having this affect tracing, we run it once ahead
-    # of time.
-    self._GetProcessesAsStrings()
-
-  def GetProcesses(self):
-    processes = super(WindowsProcessCollector, self).GetProcesses()
-
-    # On Windows, the absolute minimal name of the process is given
-    # (e.g. "python" for Telemetry). In order to make this more useful, we check
-    # if a more descriptive command is available for each PID and use that
-    # command if it is.
-    pid_to_command_dict = self._GetPidToCommandDict()
-    for process in processes:
-      if process['pid'] in pid_to_command_dict:
-        process['name'] = pid_to_command_dict[process['pid']]
-
-    return processes
-
-  def _GetPhysicalMemoryBytes(self):
-    """Returns the number of bytes of physical memory on the computer."""
-    raw_output = subprocess.check_output(
-        self._GET_PHYSICAL_MEMORY_BYTES_SHELL_COMMAND)
-    # The bytes of physical memory is on the second row (after the header row).
-    return int(raw_output.strip().split('\n')[1])
-
-  def _GetProcessesAsStrings(self):
-    # Skip the header and total rows and strip the trailing newline.
-    return subprocess.check_output(
-        self._GET_PERF_DATA_SHELL_COMMAND).strip().split('\n')[2:]
-
-  def _ParseProcessString(self, proc_string):
-    assert self._physicalMemoryBytes, 'Must call Init() before using collector'
-
-    token_list = proc_string.strip().split()
-    if len(token_list) < 5:
-      raise ValueError('Line has too few tokens: %s.' % token_list)
-
-    # Process names are given in the form:
-    #
-    #   windowsUpdate
-    #   Windows Explorer
-    #   chrome#1
-    #   chrome#2
-    #
-    # In order to match other platforms, where multiple processes can have the
-    # same name and can be easily grouped based on that name, we strip any
-    # pound sign and number.
-    name = ' '.join(token_list[2:-2])
-    name = re.sub(r'#[0-9]+$', '', name)
-    # The working set size (roughly equivalent to the resident set size on Unix)
-    # is given in bytes. In order to convert this to percent of physical memory
-    # occupied by the process, we divide by the amount of total physical memory
-    # on the machine.
-    percent_memory = float(token_list[-1]) / self._physicalMemoryBytes * 100
-
-    return {
-      'ppid': int(token_list[0]),
-      'pid': int(token_list[1]),
-      'name': name,
-      'pCpu': float(token_list[-2]),
-      'pMem': percent_memory
-    }
-
-  def _GetPidToCommandDict(self):
-    """Returns a dictionary from the PID of a process to the full command used
-    to launch that process. If no full command is available for a given process,
-    that process is omitted from the returned dictionary.
-    """
-    # Skip the header row and strip the trailing newline.
-    process_strings = subprocess.check_output(
-        self._GET_COMMANDS_SHELL_COMMAND).strip().split('\n')[1:]
-    command_by_pid = {}
-    for process_string in process_strings:
-      process_string = process_string.strip()
-      command = self._ParseCommandString(process_string)
-
-      # Only return additional information about the command if it's available.
-      if command['command']:
-        command_by_pid[command['pid']] = command['command']
-
-    return command_by_pid
-
-  def _ParseCommandString(self, command_string):
-    groups = re.match(r'^([^,]+),(.*),([0-9]+)$', command_string).groups()
-    return {
-      # Ignore groups[0]: it's the hostname.
-      'pid': int(groups[2]),
-      'command': groups[1]
-    }
-
-
-class LinuxProcessCollector(ProcessCollector):
-  """Class for collecting information about processes on Linux.
-
-  Example of Linux command output:
-  '3.4 8.0 31887 31447 com.app.Webkit'
-  """
-  _SHELL_COMMAND = [
-    'ps',
-    '-a', # Include processes that aren't session leaders.
-    '-x', # List all processes, even those not owned by the user.
-    '-o', # Show the output in the specified format.
-    'pcpu,pmem,pid,ppid,cmd'
-  ]
-
-  def _GetProcessesAsStrings(self):
-    # Skip the header row and strip the trailing newline.
-    return subprocess.check_output(self._SHELL_COMMAND).strip().split('\n')[1:]
-
-  def _ParseProcessString(self, proc_string):
-    return _ParsePsProcessString(proc_string)
-
-
-class MacProcessCollector(ProcessCollector):
-  """Class for collecting information about processes on Mac.
-
-  Example of Mac command output:
-  '3.4 8.0 31887 31447 com.app.Webkit'
-  """
-
-  _SHELL_COMMAND = [
-    'ps',
-    '-a', # Include all users' processes.
-    '-ww', # Don't limit the length of each line.
-    '-x', # Include processes that aren't associated with a terminal.
-    '-o', # Show the output in the specified format.
-    '%cpu %mem pid ppid command' # Put the command last to avoid truncation.
-  ]
-
-  def _GetProcessesAsStrings(self):
-    # Skip the header row and strip the trailing newline.
-    return subprocess.check_output(self._SHELL_COMMAND).strip().split('\n')[1:]
-
-  def _ParseProcessString(self, proc_string):
-    return _ParsePsProcessString(proc_string)
-
-
-class CpuTracingAgent(tracing_agent.TracingAgent):
-  _SNAPSHOT_INTERVAL_BY_OS = {
-    # Sampling via wmic on Windows is about twice as expensive as sampling via
-    # ps on Linux and Mac, so we halve the sampling frequency.
-    'win': 2.0,
-    'mac': 1.0,
-    'linux': 1.0
-  }
-
-  def __init__(self, platform_backend):
-    super(CpuTracingAgent, self).__init__(platform_backend)
-    self._snapshot_ongoing = False
-    self._snapshots = []
-    self._os_name = platform_backend.GetOSName()
-    if  self._os_name == 'win':
-      self._collector = WindowsProcessCollector()
-    elif self._os_name == 'mac':
-      self._collector = MacProcessCollector()
-    else:
-      self._collector = LinuxProcessCollector()
-
-  @classmethod
-  def IsSupported(cls, platform_backend):
-    os_name = platform_backend.GetOSName()
-    return (os_name in ['mac', 'linux', 'win'])
-
-  def StartAgentTracing(self, config, timeout):
-    assert not self._snapshot_ongoing, (
-           'Agent is already taking snapshots when tracing is started.')
-    if not config.enable_cpu_trace:
-      return False
-
-    self._collector.Init()
-    self._snapshot_ongoing = True
-    self._KeepTakingSnapshots()
-    return True
-
-  def _KeepTakingSnapshots(self):
-    """Take CPU snapshots every SNAPSHOT_FREQUENCY seconds."""
-    if not self._snapshot_ongoing:
-      return
-    # Assume CpuTracingAgent shares the same clock domain as telemetry
-    self._snapshots.append(
-        (self._collector.GetProcesses(), trace_time.Now()))
-    interval = self._SNAPSHOT_INTERVAL_BY_OS[self._os_name]
-    Timer(interval, self._KeepTakingSnapshots).start()
-
-  def StopAgentTracing(self):
-    assert self._snapshot_ongoing, (
-           'Agent is not taking snapshots when tracing is stopped.')
-    self._snapshot_ongoing = False
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    assert not self._snapshot_ongoing, (
-           'Agent is still taking snapshots when data is collected.')
-    self._snapshot_ongoing = False
-    data = json.dumps(self._FormatSnapshotsData())
-    trace_data_builder.AddTraceFor(trace_data.CPU_TRACE_DATA, data)
-
-  def _FormatSnapshotsData(self):
-    """Format raw data into Object Event specified in Trace Format document."""
-    pid = os.getpid()
-    return [{
-      'name': 'CPUSnapshots',
-      'ph': 'O',
-      'id': '0x1000',
-      'local': True,
-      'ts': timestamp,
-      'pid': pid,
-      'tid':None,
-      'args': {
-        'snapshot':{
-          'processes': snapshot
-        }
-      }
-    } for snapshot, timestamp in self._snapshots]
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/cpu_tracing_agent_unittest.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/cpu_tracing_agent_unittest.py
deleted file mode 100644
index f87f009..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/cpu_tracing_agent_unittest.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import json
-import sys
-import time
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.platform.tracing_agent import cpu_tracing_agent
-from telemetry.internal.platform import tracing_agent
-from telemetry.internal.platform import linux_platform_backend
-from telemetry.internal.platform import mac_platform_backend
-from telemetry.internal.platform import win_platform_backend
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data
-
-
-SNAPSHOT_KEYS = ['pid', 'ppid', 'name', 'pCpu', 'pMem']
-TRACE_EVENT_KEYS = ['name', 'tid', 'pid', 'ph', 'args', 'local', 'id', 'ts']
-
-
-class FakeAndroidPlatformBackend(object):
-  def __init__(self):
-    self.device = 'fake_device'
-
-  def GetOSName(self):
-    return 'android'
-
-
-class CpuTracingAgentTest(unittest.TestCase):
-
-  def setUp(self):
-    self._config = tracing_config.TracingConfig()
-    self._config.enable_cpu_trace = True
-    if sys.platform.startswith('win'):
-      self._desktop_backend = win_platform_backend.WinPlatformBackend()
-    elif sys.platform.startswith('darwin'):
-      self._desktop_backend = mac_platform_backend.MacPlatformBackend()
-    else:
-      self._desktop_backend = linux_platform_backend.LinuxPlatformBackend()
-    self._agent = cpu_tracing_agent.CpuTracingAgent(self._desktop_backend)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testInit(self):
-    self.assertTrue(isinstance(self._agent,
-                               tracing_agent.TracingAgent))
-    self.assertFalse(self._agent._snapshots)
-    self.assertFalse(self._agent._snapshot_ongoing)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testIsSupported(self):
-    self.assertTrue(cpu_tracing_agent.CpuTracingAgent.IsSupported(
-      self._desktop_backend))
-    self.assertFalse(cpu_tracing_agent.CpuTracingAgent.IsSupported(
-      FakeAndroidPlatformBackend()))
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testStartAgentTracing(self):
-    self.assertFalse(self._agent._snapshot_ongoing)
-    self.assertFalse(self._agent._snapshots)
-    self.assertTrue(self._agent.StartAgentTracing(self._config, 0))
-    self.assertTrue(self._agent._snapshot_ongoing)
-    time.sleep(2)
-    self.assertTrue(self._agent._snapshots)
-    self._agent.StopAgentTracing()
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testStartAgentTracingNotEnabled(self):
-    self._config.enable_cpu_trace = False
-    self.assertFalse(self._agent._snapshot_ongoing)
-    self.assertFalse(self._agent.StartAgentTracing(self._config, 0))
-    self.assertFalse(self._agent._snapshot_ongoing)
-    self.assertFalse(self._agent._snapshots)
-    time.sleep(2)
-    self.assertFalse(self._agent._snapshots)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testStopAgentTracingBeforeStart(self):
-    self.assertRaises(AssertionError, self._agent.StopAgentTracing)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testStopAgentTracing(self):
-    self._agent.StartAgentTracing(self._config, 0)
-    self._agent.StopAgentTracing()
-    self.assertFalse(self._agent._snapshot_ongoing)
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testCollectAgentTraceDataBeforeStop(self):
-    self._agent.StartAgentTracing(self._config, 0)
-    self.assertRaises(AssertionError, self._agent.CollectAgentTraceData,
-        trace_data.TraceDataBuilder())
-    self._agent.StopAgentTracing()
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testCollectAgentTraceData(self):
-    builder = trace_data.TraceDataBuilder()
-    self._agent.StartAgentTracing(self._config, 0)
-    self._agent.StopAgentTracing()
-    self._agent.CollectAgentTraceData(builder)
-    self.assertFalse(self._agent._snapshot_ongoing)
-    builder = builder.AsData()
-    self.assertTrue(builder.HasTracesFor(trace_data.CPU_TRACE_DATA))
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testCollectAgentTraceDataFormat(self):
-    builder = trace_data.TraceDataBuilder()
-    self._agent.StartAgentTracing(self._config, 0)
-    time.sleep(2)
-    self._agent.StopAgentTracing()
-    self._agent.CollectAgentTraceData(builder)
-    builder = builder.AsData()
-    data = json.loads(builder.GetTracesFor(trace_data.CPU_TRACE_DATA)[0])
-    self.assertTrue(data)
-    self.assertEquals(set(data[0].keys()), set(TRACE_EVENT_KEYS))
-    self.assertEquals(set(data[0]['args']['snapshot'].keys()),
-                      set(['processes']))
-    self.assertTrue(data[0]['args']['snapshot']['processes'])
-    self.assertEquals(set(data[0]['args']['snapshot']['processes'][0].keys()),
-                      set(SNAPSHOT_KEYS))
-
-  @decorators.Enabled('linux', 'mac', 'win')
-  def testContainsRealProcesses(self):
-    builder = trace_data.TraceDataBuilder()
-    self._agent.StartAgentTracing(self._config, 0)
-    time.sleep(2)
-    self._agent.StopAgentTracing()
-    self._agent.CollectAgentTraceData(builder)
-    builder = builder.AsData()
-    data = json.loads(builder.GetTracesFor(trace_data.CPU_TRACE_DATA)[0])
-    self.assertTrue(data)
-    for snapshot in data:
-      found_unittest_process = False
-      processes = snapshot['args']['snapshot']['processes']
-      for process in processes:
-        if 'run_tests' in process['name']:
-          found_unittest_process = True
-
-      self.assertTrue(found_unittest_process)
-
-  @decorators.Enabled('win')
-  def testWindowsCanHandleProcessesWithSpaces(self):
-    proc_collector = cpu_tracing_agent.WindowsProcessCollector()
-    proc_collector.Init()
-    proc = proc_collector._ParseProcessString(
-      '0 1 Multi Word Process 50 75')
-    self.assertEquals(proc['ppid'], 0)
-    self.assertEquals(proc['pid'], 1)
-    self.assertEquals(proc['name'], 'Multi Word Process')
-    self.assertEquals(proc['pCpu'], 50)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/display_tracing_agent.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/display_tracing_agent.py
deleted file mode 100644
index c7c67a3..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/display_tracing_agent.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.platform import tracing_agent
-from tracing.trace_data import trace_data
-
-
-class DisplayTracingAgent(tracing_agent.TracingAgent):
-  def __init__(self, platform_backend):
-    super(DisplayTracingAgent, self).__init__(platform_backend)
-
-  @classmethod
-  def IsSupported(cls, platform_backend):
-    return platform_backend.IsDisplayTracingSupported()
-
-  def StartAgentTracing(self, config, timeout):
-    del timeout  # unused
-    if config.enable_platform_display_trace:
-      self._platform_backend.StartDisplayTracing()
-      return True
-
-  def StopAgentTracing(self):
-    # TODO: Split collection and stopping.
-    pass
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    # TODO: Move stopping to StopAgentTracing.
-    del timeout
-    surface_flinger_trace_data = self._platform_backend.StopDisplayTracing()
-    trace_data_builder.AddTraceFor(
-          trace_data.SURFACE_FLINGER_PART, surface_flinger_trace_data)
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_agent/display_tracing_agent_unittest.py b/catapult/telemetry/telemetry/internal/platform/tracing_agent/display_tracing_agent_unittest.py
deleted file mode 100644
index 62b5b08..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_agent/display_tracing_agent_unittest.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import mock
-import unittest
-
-from telemetry.internal.platform import android_platform_backend
-from telemetry.internal.platform.tracing_agent import display_tracing_agent
-from telemetry.timeline import tracing_config
-
-# pylint: disable=super-init-not-called, abstract-method, unused-argument
-class FakeAndroidPlatformBackend(
-    android_platform_backend.AndroidPlatformBackend):
-  def __init__(self):
-    self._device = 0
-    self._raw_display_frame_rate_measurements = []
-    self._surface_stats_collector = None
-
-  @property
-  def surface_stats_collector(self):
-    return self._surface_stats_collector
-
-  def IsDisplayTracingSupported(self):
-    return True
-
-
-class DisplayTracingAgentTest(unittest.TestCase):
-  def setUp(self):
-    self._config = tracing_config.TracingConfig()
-    self._config.enable_platform_display_trace = True
-    self._platform_backend = FakeAndroidPlatformBackend()
-    self._agent = display_tracing_agent.DisplayTracingAgent(
-        self._platform_backend)
-
-  def stopAndCollect(self):
-    self._agent.StopAgentTracing()
-    self._agent.CollectAgentTraceData(mock.MagicMock())
-
-  @mock.patch(
-      'devil.android.perf.surface_stats_collector.SurfaceStatsCollector')
-  def testStartAndStopTracing(self, MockSurfaceStatsCollector):
-    self._agent.StartAgentTracing(self._config, 10)
-    # Second start tracing will raise error.
-    with self.assertRaises(AssertionError):
-      self._agent.StartAgentTracing(self._config, 10)
-    self._platform_backend.surface_stats_collector.Stop.return_value = (0, [])
-    self.stopAndCollect()
-
-    # Can start and stop tracing multiple times.
-    self._agent.StartAgentTracing(self._config, 10)
-    self._platform_backend.surface_stats_collector.Stop.return_value = (0, [])
-    self.stopAndCollect()
-
-  @mock.patch(
-      'devil.android.perf.surface_stats_collector.SurfaceStatsCollector')
-  def testExceptionRaisedInStopTracing(self, MockSurfaceStatsCollector):
-    self._agent.StartAgentTracing(self._config, 10)
-    self._platform_backend.surface_stats_collector.Stop.side_effect = Exception(
-        'Raise error when stopping tracing.')
-    with self.assertRaises(Exception):
-      self.stopAndCollect()
-    # Tracing is stopped even if there is exception. And the agent can start
-    # tracing again.
-    self._agent.StartAgentTracing(self._config, 10)
-    self._platform_backend.surface_stats_collector.Stop.side_effect = None
-    self._platform_backend.surface_stats_collector.Stop.return_value = (0, [])
-    self.stopAndCollect()
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_controller_backend.py b/catapult/telemetry/telemetry/internal/platform/tracing_controller_backend.py
deleted file mode 100644
index 31365b0..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_controller_backend.py
+++ /dev/null
@@ -1,293 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import ast
-from telemetry.internal.util import atexit_with_log
-import contextlib
-import gc
-import logging
-import os
-import sys
-import tempfile
-import traceback
-import uuid
-
-from py_trace_event import trace_event
-from telemetry.core import discover
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry.internal.platform import tracing_agent
-from telemetry.internal.platform.tracing_agent import chrome_tracing_agent
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data as trace_data_module
-
-
-def _IterAllTracingAgentClasses():
-  tracing_agent_dir = os.path.join(
-      os.path.dirname(os.path.realpath(__file__)), 'tracing_agent')
-  return discover.DiscoverClasses(
-      tracing_agent_dir, util.GetTelemetryDir(),
-      tracing_agent.TracingAgent).itervalues()
-
-
-class _TracingState(object):
-
-  def __init__(self, config, timeout):
-    self._builder = trace_data_module.TraceDataBuilder()
-    self._config = config
-    self._timeout = timeout
-
-  @property
-  def builder(self):
-    return self._builder
-
-  @property
-  def config(self):
-    return self._config
-
-  @property
-  def timeout(self):
-    return self._timeout
-
-
-class TracingControllerBackend(object):
-  def __init__(self, platform_backend):
-    self._platform_backend = platform_backend
-    self._current_state = None
-    self._supported_agents_classes = [
-        agent_classes for agent_classes in _IterAllTracingAgentClasses() if
-        agent_classes.IsSupported(platform_backend)]
-    self._active_agents_instances = []
-    self._trace_log = None
-    self._is_tracing_controllable = True
-    self._telemetry_info = None
-
-  def StartTracing(self, config, timeout):
-    if self.is_tracing_running:
-      return False
-
-    assert isinstance(config, tracing_config.TracingConfig)
-    assert len(self._active_agents_instances) == 0
-
-    self._current_state = _TracingState(config, timeout)
-    # Hack: chrome tracing agent may only depend on the number of alive chrome
-    # devtools processes, rather platform (when startup tracing is not
-    # supported), hence we add it to the list of supported agents here if it was
-    # not added.
-    if (chrome_tracing_agent.ChromeTracingAgent.IsSupported(
-        self._platform_backend) and
-        not chrome_tracing_agent.ChromeTracingAgent in
-        self._supported_agents_classes):
-      self._supported_agents_classes.append(
-          chrome_tracing_agent.ChromeTracingAgent)
-
-    self.StartAgentTracing(config, timeout)
-    for agent_class in self._supported_agents_classes:
-      agent = agent_class(self._platform_backend)
-      with trace_event.trace(
-          'StartAgentTracing',
-          agent=str(agent.__class__.__name__)):
-        started = agent.StartAgentTracing(config, timeout)
-      if started:
-        self._active_agents_instances.append(agent)
-    return True
-
-  def _GenerateClockSyncId(self):
-    return str(uuid.uuid4())
-
-  @contextlib.contextmanager
-  def _DisableGarbageCollection(self):
-    try:
-      gc.disable()
-      yield
-    finally:
-      gc.enable()
-
-  def StopTracing(self):
-    assert self.is_tracing_running, 'Can only stop tracing when tracing is on.'
-    self._IssueClockSyncMarker()
-    builder = self._current_state.builder
-
-    raised_exception_messages = []
-    for agent in self._active_agents_instances + [self]:
-      try:
-        with trace_event.trace(
-            'StopAgentTracing',
-            agent=str(agent.__class__.__name__)):
-          agent.StopAgentTracing()
-      except Exception: # pylint: disable=broad-except
-        raised_exception_messages.append(
-            ''.join(traceback.format_exception(*sys.exc_info())))
-
-    for agent in self._active_agents_instances + [self]:
-      try:
-        with trace_event.trace(
-            'CollectAgentTraceData',
-            agent=str(agent.__class__.__name__)):
-          agent.CollectAgentTraceData(builder)
-      except Exception: # pylint: disable=broad-except
-        raised_exception_messages.append(
-            ''.join(traceback.format_exception(*sys.exc_info())))
-
-    self._telemetry_info = None
-    self._active_agents_instances = []
-    self._current_state = None
-
-    if raised_exception_messages:
-      raise exceptions.Error(
-          'Exceptions raised when trying to stop tracing:\n' +
-          '\n'.join(raised_exception_messages))
-
-    return builder.AsData()
-
-  def FlushTracing(self):
-    assert self.is_tracing_running, 'Can only flush tracing when tracing is on.'
-    self._IssueClockSyncMarker()
-
-    raised_exception_messages = []
-    # Flushing the controller's pytrace is not supported.
-    for agent in self._active_agents_instances:
-      try:
-        if agent.SupportsFlushingAgentTracing():
-          with trace_event.trace(
-              'FlushAgentTracing',
-              agent=str(agent.__class__.__name__)):
-            agent.FlushAgentTracing(self._current_state.config,
-                                    self._current_state.timeout,
-                                    self._current_state.builder)
-      except Exception: # pylint: disable=broad-except
-        raised_exception_messages.append(
-            ''.join(traceback.format_exception(*sys.exc_info())))
-
-    if raised_exception_messages:
-      raise exceptions.Error(
-          'Exceptions raised when trying to flush tracing:\n' +
-          '\n'.join(raised_exception_messages))
-
-  def StartAgentTracing(self, config, timeout):
-    self._is_tracing_controllable = self._IsTracingControllable()
-    if not self._is_tracing_controllable:
-      return False
-
-    tf = tempfile.NamedTemporaryFile(delete=False)
-    self._trace_log = tf.name
-    tf.close()
-    del config # unused
-    del timeout # unused
-    assert not trace_event.trace_is_enabled(), 'Tracing already running.'
-    trace_event.trace_enable(self._trace_log)
-    assert trace_event.trace_is_enabled(), 'Tracing didn\'t enable properly.'
-    return True
-
-  def StopAgentTracing(self):
-    if not self._is_tracing_controllable:
-      return
-    assert trace_event.trace_is_enabled(), 'Tracing not running'
-    trace_event.trace_disable()
-    assert not trace_event.trace_is_enabled(), 'Tracing didnt disable properly.'
-
-  def SupportsExplicitClockSync(self):
-    return True
-
-  def _RecordIssuerClockSyncMarker(self, sync_id, issue_ts):
-    """ Record clock sync event.
-
-    Args:
-      sync_id: Unqiue id for sync event.
-      issue_ts: timestamp before issuing clocksync to agent.
-    """
-    if self._is_tracing_controllable:
-      trace_event.clock_sync(sync_id, issue_ts=issue_ts)
-
-  def _IssueClockSyncMarker(self):
-    with self._DisableGarbageCollection():
-      for agent in self._active_agents_instances:
-        if agent.SupportsExplicitClockSync():
-          sync_id = self._GenerateClockSyncId()
-          with trace_event.trace(
-              'RecordClockSyncMarker',
-              agent=str(agent.__class__.__name__),
-              sync_id=sync_id):
-            agent.RecordClockSyncMarker(sync_id,
-                                        self._RecordIssuerClockSyncMarker)
-
-  def IsChromeTracingSupported(self):
-    return chrome_tracing_agent.ChromeTracingAgent.IsSupported(
-        self._platform_backend)
-
-  @property
-  def is_tracing_running(self):
-    return self._current_state is not None
-
-  def _GetActiveChromeTracingAgent(self):
-    if not self.is_tracing_running:
-      return None
-    if not self._current_state.config.enable_chrome_trace:
-      return None
-    for agent in self._active_agents_instances:
-      if isinstance(agent, chrome_tracing_agent.ChromeTracingAgent):
-        return agent
-    return None
-
-  def GetChromeTraceConfig(self):
-    agent = self._GetActiveChromeTracingAgent()
-    if agent:
-      return agent.trace_config
-    return None
-
-  def GetChromeTraceConfigFile(self):
-    agent = self._GetActiveChromeTracingAgent()
-    if agent:
-      return agent.trace_config_file
-    return None
-
-  def _IsTracingControllable(self):
-    return trace_event.is_tracing_controllable()
-
-  def ClearStateIfNeeded(self):
-    chrome_tracing_agent.ClearStarupTracingStateIfNeeded(self._platform_backend)
-
-  @property
-  def telemetry_info(self):
-    return self._telemetry_info
-
-  @telemetry_info.setter
-  def telemetry_info(self, ii):
-    self._telemetry_info = ii
-
-  def CollectAgentTraceData(self, trace_data_builder):
-    if not self._is_tracing_controllable:
-      return
-    assert not trace_event.trace_is_enabled(), 'Stop tracing before collection.'
-    with open(self._trace_log, 'r') as fp:
-      data = ast.literal_eval(fp.read() + ']')
-    trace_data_builder.AddTraceFor(trace_data_module.TELEMETRY_PART, {
-        "traceEvents": data,
-        "metadata": {
-            # TODO(charliea): For right now, we use "TELEMETRY" as the clock
-            # domain to guarantee that Telemetry is given its own clock
-            # domain. Telemetry isn't really a clock domain, though: it's a
-            # system that USES a clock domain like LINUX_CLOCK_MONOTONIC or
-            # WIN_QPC. However, there's a chance that a Telemetry controller
-            # running on Linux (using LINUX_CLOCK_MONOTONIC) is interacting with
-            # an Android phone (also using LINUX_CLOCK_MONOTONIC, but on a
-            # different machine). The current logic collapses clock domains
-            # based solely on the clock domain string, but we really should to
-            # collapse based on some (device ID, clock domain ID) tuple. Giving
-            # Telemetry its own clock domain is a work-around for this.
-            "clock-domain": "TELEMETRY",
-            "telemetry": (self._telemetry_info.AsDict()
-                if self._telemetry_info else {}),
-        }
-    })
-    try:
-      os.remove(self._trace_log)
-      self._trace_log = None
-    except OSError:
-      logging.exception('Error when deleting %s, will try again at exit.',
-                        self._trace_log)
-      def DeleteAtExit(path):
-        os.remove(path)
-      atexit_with_log.Register(DeleteAtExit, self._trace_log)
-    self._trace_log = None
diff --git a/catapult/telemetry/telemetry/internal/platform/tracing_controller_backend_unittest.py b/catapult/telemetry/telemetry/internal/platform/tracing_controller_backend_unittest.py
deleted file mode 100644
index 4431985..0000000
--- a/catapult/telemetry/telemetry/internal/platform/tracing_controller_backend_unittest.py
+++ /dev/null
@@ -1,373 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import gc
-import platform as _platform
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.platform import linux_based_platform_backend
-from telemetry.internal.platform import tracing_agent
-from telemetry.internal.platform import tracing_controller_backend
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data
-
-
-class PlatformDevice(object):
-  def __init__(self):
-    self.build_version_sdk = 99
-
-class PlatformBackend(linux_based_platform_backend.LinuxBasedPlatformBackend):
-  # pylint: disable=abstract-method
-  def __init__(self):
-    super(PlatformBackend, self).__init__()
-    self._mock_files = {}
-
-  def GetOSName(self):
-    if 'Win' in _platform.system():
-      return 'win'
-    elif 'Linux' in _platform.system():
-      return 'android'
-    elif 'Darwin' in _platform.system():
-      return 'mac'
-
-  @property
-  def device(self):
-    return PlatformDevice()
-
-
-class FakeTracingAgentBase(tracing_agent.TracingAgent):
-  def __init__(
-      self, platform, start=True, clock_sync=True, split_collection=True):
-    super(FakeTracingAgentBase, self).__init__(platform)
-    self._start = start
-    self._clock_sync = clock_sync
-    self._sync_seen = False
-    self._split_collection = split_collection
-
-  def StartAgentTracing(self, config, timeout):
-    return self._start
-
-  def StopAgentTracing(self):
-    pass
-
-  def SupportsExplicitClockSync(self):
-    return self._clock_sync
-
-  def RecordClockSyncMarker(self, sync_id, callback):
-    if not self._clock_sync:
-      raise NotImplementedError
-    self._sync_seen = True
-    callback(sync_id, 1)
-
-  def CollectAgentTraceData(self, trace_data_builder, timeout=None):
-    pass
-
-
-class FakeTracingAgentStartAndClockSync(FakeTracingAgentBase):
-  def __init__(self, platform):
-    super(FakeTracingAgentStartAndClockSync, self).__init__(
-        platform, start=True, clock_sync=True, split_collection=False)
-
-
-class FakeTracingAgentStartAndNoClockSync(FakeTracingAgentBase):
-  def __init__(self, platform):
-    super(FakeTracingAgentStartAndNoClockSync, self).__init__(platform,
-                                                            start=True,
-                                                            clock_sync=False)
-
-
-class FakeTracingAgentNoStartAndNoClockSync(FakeTracingAgentBase):
-  def __init__(self, platform):
-    super(FakeTracingAgentNoStartAndNoClockSync, self).__init__(platform,
-                                                            start=False,
-                                                            clock_sync=False)
-
-
-class FakeTracingAgentNoStartAndClockSync(FakeTracingAgentBase):
-  def __init__(self, platform):
-    super(FakeTracingAgentNoStartAndClockSync, self).__init__(platform,
-                                                              start=False,
-                                                              clock_sync=True)
-
-
-class TracingControllerBackendTest(unittest.TestCase):
-  def _getControllerEventsAslist(self, data):
-    traces = data.GetTracesFor(trace_data.TELEMETRY_PART)
-    if not traces:
-      return []
-    assert len(traces) == 1
-    telemetry_trace = traces[0]
-    return telemetry_trace["traceEvents"]
-
-  def _getControllerClockDomain(self, data):
-    traces = data.GetTracesFor(trace_data.TELEMETRY_PART)
-    if not traces:
-      return []
-    assert len(traces) == 1
-    telemetry_trace = traces[0]
-    telemetry_trace = data.GetTracesFor(trace_data.TELEMETRY_PART)[0]
-    if not telemetry_trace or not telemetry_trace["metadata"]:
-      return ""
-    return telemetry_trace["metadata"]["clock-domain"]
-
-  def _getSyncCount(self, data):
-    return len([entry for entry in self._getControllerEventsAslist(data)
-                if entry.get('name') == 'clock_sync'])
-
-  def setUp(self):
-    self.platform = PlatformBackend()
-    self.controller = (
-        tracing_controller_backend.TracingControllerBackend(self.platform))
-    self.controller._supported_agents_classes = [FakeTracingAgentBase]
-    self.config = tracing_config.TracingConfig()
-    self.controller_log = self.controller._trace_log
-
-  def tearDown(self):
-    if self.controller.is_tracing_running:
-      self.controller.StopTracing()
-
-  @decorators.Isolated
-  def testStartTracing(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-
-  @decorators.Isolated
-  def testDoubleStartTracing(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.assertFalse(self.controller.StartTracing(self.config, 30))
-
-  @decorators.Isolated
-  def testStopTracingNotStarted(self):
-    with self.assertRaises(AssertionError):
-      self.controller.StopTracing()
-
-  @decorators.Isolated
-  def testStopTracing(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    data = self.controller.StopTracing()
-    self.assertEqual(self._getSyncCount(data), 1)
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEqual(self.controller._trace_log, None)
-
-  @decorators.Isolated
-  def testDoubleStopTracing(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    with self.assertRaises(AssertionError):
-      self.controller.StopTracing()
-
-  @decorators.Isolated
-  def testMultipleStartStop(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    data = self.controller.StopTracing()
-    self.assertEqual(self._getSyncCount(data), 1)
-    sync_event_one = [x for x in self._getControllerEventsAslist(data)
-                      if x.get('name') == 'clock_sync'][0]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEqual(self.controller._trace_log, None)
-    # Run 2
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    data = self.controller.StopTracing()
-    self.assertEqual(self._getSyncCount(data), 1)
-    sync_event_two = [x for x in self._getControllerEventsAslist(data)
-                      if x.get('name') == 'clock_sync'][0]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertFalse(self.controller._trace_log, None)
-    # Test difference between events
-    self.assertNotEqual(sync_event_one, sync_event_two)
-
-  @decorators.Isolated
-  def testCollectAgentDataBeforeStoppingTracing(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    with self.assertRaises(AssertionError):
-      self.controller.CollectAgentTraceData(None)
-
-  @decorators.Isolated
-  def testFlush(self):
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertIsNone(self.controller._current_state)
-
-    # Start tracing.
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.assertIs(self.controller._current_state.config, self.config)
-    self.assertEqual(self.controller._current_state.timeout, 30)
-    self.assertIsNotNone(self.controller._current_state.builder)
-
-    # Flush tracing several times.
-    for _ in xrange(5):
-      self.controller.FlushTracing()
-      self.assertTrue(self.controller.is_tracing_running)
-      self.assertIs(self.controller._current_state.config, self.config)
-      self.assertEqual(self.controller._current_state.timeout, 30)
-      self.assertIsNotNone(self.controller._current_state.builder)
-
-    # Stop tracing.
-    data = self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertIsNone(self.controller._current_state)
-
-    self.assertEqual(self._getSyncCount(data), 6)
-
-  @decorators.Isolated
-  def testNoWorkingAgents(self):
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentNoStartAndNoClockSync
-    ]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.assertEquals(self.controller._active_agents_instances, [])
-    data = self.controller.StopTracing()
-    self.assertEqual(self._getSyncCount(data), 0)
-    self.assertFalse(self.controller.is_tracing_running)
-
-  @decorators.Isolated
-  def testNoClockSyncSupport(self):
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentStartAndNoClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-    ]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    data = self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEquals(self._getSyncCount(data), 0)
-
-  @decorators.Isolated
-  def testClockSyncSupport(self):
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentStartAndNoClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndNoClockSync
-    ]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.assertEquals(len(self.controller._active_agents_instances), 3)
-    # No sync event before running StopTracing().
-    data = self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEquals(self._getSyncCount(data), 2)
-    self.assertEquals(self._getControllerClockDomain(data), "TELEMETRY")
-
-  @decorators.Isolated
-  def testMultipleAgents(self):
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync
-    ]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.assertEquals(len(self.controller._active_agents_instances), 4)
-    data = self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEquals(self._getSyncCount(data), 2)
-
-  @decorators.Isolated
-  def testGenerateRandomSyncId(self):
-    ids = []
-    for _ in xrange(1000):
-      i = self.controller._GenerateClockSyncId()
-      self.assertFalse(i in ids)
-      ids.append(i)
-
-  @decorators.Isolated
-  def testRecordIssuerClockSyncMarker(self):
-    sync_id = 'test_id'
-    ts = 1
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync
-    ]
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.controller._RecordIssuerClockSyncMarker(sync_id, ts)
-    data = self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEquals(self._getSyncCount(data), 1)
-    self.assertEquals(self._getControllerClockDomain(data), "TELEMETRY")
-    log = self._getControllerEventsAslist(data)
-    for entry in log:
-      if entry.get('name') == 'clock_sync':
-        self.assertEqual(entry['args']['sync_id'], sync_id)
-        self.assertEqual(entry['args']['issue_ts'], 1)
-
-  @decorators.Isolated
-  def testIssueClockSyncMarker_normalUse(self):
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync
-    ]
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertTrue(self.controller.StartTracing(self.config, 30))
-    self.assertTrue(self.controller.is_tracing_running)
-    self.assertEquals(len(self.controller._active_agents_instances), 4)
-    self.controller._IssueClockSyncMarker()
-    data = self.controller.StopTracing()
-    self.assertFalse(self.controller.is_tracing_running)
-    self.assertEquals(self._getSyncCount(data), 4)
-    self.assertEquals(self._getControllerClockDomain(data), "TELEMETRY")
-
-  @decorators.Isolated
-  def testIssueClockSyncMarker_tracingNotControllable(self):
-    self.controller._supported_agents_classes = [
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentStartAndClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentNoStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync,
-        FakeTracingAgentStartAndNoClockSync
-    ]
-    original_controllable = self.controller._IsTracingControllable
-    self.controller._IsTracingControllable = lambda: False
-    try:
-      self.assertFalse(self.controller.is_tracing_running)
-      self.assertTrue(self.controller.StartTracing(self.config, 30))
-      self.assertTrue(self.controller.is_tracing_running)
-      self.assertEquals(len(self.controller._active_agents_instances), 4)
-      self.controller._IssueClockSyncMarker()
-      data = self.controller.StopTracing()
-      self.assertFalse(self.controller.is_tracing_running)
-      self.assertEquals(self._getSyncCount(data), 0)
-    finally:
-      self.controller._IsTracingControllable = original_controllable
-
-  @decorators.Isolated
-  def testDisableGarbageCollection(self):
-    self.assertTrue(gc.isenabled())
-    with self.controller._DisableGarbageCollection():
-      self.assertFalse(gc.isenabled())
-    self.assertTrue(gc.isenabled())
diff --git a/catapult/telemetry/telemetry/internal/platform/win_platform_backend.py b/catapult/telemetry/telemetry/internal/platform/win_platform_backend.py
deleted file mode 100644
index f1fbf05..0000000
--- a/catapult/telemetry/telemetry/internal/platform/win_platform_backend.py
+++ /dev/null
@@ -1,443 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.util import atexit_with_log
-import collections
-import contextlib
-import ctypes
-import logging
-import os
-import platform
-import re
-import socket
-import struct
-import subprocess
-import sys
-import time
-import zipfile
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.core import exceptions
-from telemetry.core import os_version as os_version_module
-from telemetry import decorators
-from telemetry.internal.platform import desktop_platform_backend
-from telemetry.internal.platform.power_monitor import msr_power_monitor
-from telemetry.internal.util import path
-
-try:
-  import pywintypes  # pylint: disable=import-error
-  import win32api  # pylint: disable=import-error
-  from win32com.shell import shell  # pylint: disable=no-name-in-module
-  from win32com.shell import shellcon  # pylint: disable=no-name-in-module
-  import win32con  # pylint: disable=import-error
-  import win32file  # pylint: disable=import-error
-  import win32gui  # pylint: disable=import-error
-  import win32pipe  # pylint: disable=import-error
-  import win32process  # pylint: disable=import-error
-  try:
-    import winreg  # pylint: disable=import-error
-  except ImportError:
-    import _winreg as winreg  # pylint: disable=import-error
-  import win32security  # pylint: disable=import-error
-except ImportError:
-  pywintypes = None
-  shell = None
-  shellcon = None
-  win32api = None
-  win32con = None
-  win32file = None
-  win32gui = None
-  win32pipe = None
-  win32process = None
-  win32security = None
-  winreg = None
-
-
-def _InstallWinRing0():
-  """WinRing0 is used for reading MSRs."""
-  executable_dir = os.path.dirname(sys.executable)
-
-  python_is_64_bit = sys.maxsize > 2 ** 32
-  dll_file_name = 'WinRing0x64.dll' if python_is_64_bit else 'WinRing0.dll'
-  dll_path = os.path.join(executable_dir, dll_file_name)
-
-  os_is_64_bit = platform.machine().endswith('64')
-  driver_file_name = 'WinRing0x64.sys' if os_is_64_bit else 'WinRing0.sys'
-  driver_path = os.path.join(executable_dir, driver_file_name)
-
-  # Check for WinRing0 and download if needed.
-  if not (os.path.exists(dll_path) and os.path.exists(driver_path)):
-    win_binary_dir = os.path.join(
-        path.GetTelemetryDir(), 'bin', 'win', 'AMD64')
-    zip_path = os.path.join(win_binary_dir, 'winring0.zip')
-    cloud_storage.GetIfChanged(zip_path, bucket=cloud_storage.PUBLIC_BUCKET)
-    try:
-      with zipfile.ZipFile(zip_path, 'r') as zip_file:
-        error_message = (
-            'Failed to extract %s into %s. If python claims that '
-            'the zip file is locked, this may be a lie. The problem may be '
-            'that python does not have write permissions to the destination '
-            'directory.'
-        )
-        # Install DLL.
-        if not os.path.exists(dll_path):
-          try:
-            zip_file.extract(dll_file_name, executable_dir)
-          except:
-            logging.error(error_message % (dll_file_name, executable_dir))
-            raise
-
-        # Install kernel driver.
-        if not os.path.exists(driver_path):
-          try:
-            zip_file.extract(driver_file_name, executable_dir)
-          except:
-            logging.error(error_message % (driver_file_name, executable_dir))
-            raise
-    finally:
-      os.remove(zip_path)
-
-
-def TerminateProcess(process_handle):
-  if not process_handle:
-    return
-  if win32process.GetExitCodeProcess(process_handle) == win32con.STILL_ACTIVE:
-    win32process.TerminateProcess(process_handle, 0)
-  process_handle.close()
-
-
-class WinPlatformBackend(desktop_platform_backend.DesktopPlatformBackend):
-  def __init__(self):
-    super(WinPlatformBackend, self).__init__()
-    self._msr_server_handle = None
-    self._msr_server_port = None
-    self._power_monitor = msr_power_monitor.MsrPowerMonitorWin(self)
-
-  @classmethod
-  def IsPlatformBackendForHost(cls):
-    return sys.platform == 'win32'
-
-  def __del__(self):
-    self.close()
-
-  def close(self):
-    self.CloseMsrServer()
-
-  def CloseMsrServer(self):
-    if not self._msr_server_handle:
-      return
-
-    TerminateProcess(self._msr_server_handle)
-    self._msr_server_handle = None
-    self._msr_server_port = None
-
-  def IsThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def HasBeenThermallyThrottled(self):
-    raise NotImplementedError()
-
-  def GetSystemCommitCharge(self):
-    performance_info = self._GetPerformanceInfo()
-    return performance_info.CommitTotal * performance_info.PageSize / 1024
-
-  @decorators.Cache
-  def GetSystemTotalPhysicalMemory(self):
-    performance_info = self._GetPerformanceInfo()
-    return performance_info.PhysicalTotal * performance_info.PageSize / 1024
-
-  def GetCpuStats(self, pid):
-    cpu_info = self._GetWin32ProcessInfo(win32process.GetProcessTimes, pid)
-    # Convert 100 nanosecond units to seconds
-    cpu_time = (cpu_info['UserTime'] / 1e7 +
-                cpu_info['KernelTime'] / 1e7)
-    return {'CpuProcessTime': cpu_time}
-
-  def GetCpuTimestamp(self):
-    """Return current timestamp in seconds."""
-    return {'TotalTime': time.time()}
-
-  @decorators.Deprecated(
-      2017, 11, 4,
-      'Clients should use tracing and memory-infra in new Telemetry '
-      'benchmarks. See for context: https://crbug.com/632021')
-  def GetMemoryStats(self, pid):
-    memory_info = self._GetWin32ProcessInfo(
-        win32process.GetProcessMemoryInfo, pid)
-    return {'VM': memory_info['PagefileUsage'],
-            'VMPeak': memory_info['PeakPagefileUsage'],
-            'WorkingSetSize': memory_info['WorkingSetSize'],
-            'WorkingSetSizePeak': memory_info['PeakWorkingSetSize']}
-
-  def KillProcess(self, pid, kill_process_tree=False):
-    # os.kill for Windows is Python 2.7.
-    cmd = ['taskkill', '/F', '/PID', str(pid)]
-    if kill_process_tree:
-      cmd.append('/T')
-    subprocess.Popen(cmd, stdout=subprocess.PIPE,
-                     stderr=subprocess.STDOUT).communicate()
-
-  def GetSystemProcessInfo(self):
-    # [3:] To skip 2 blank lines and header.
-    lines = subprocess.Popen(
-        ['wmic', 'process', 'get',
-         'CommandLine,CreationDate,Name,ParentProcessId,ProcessId',
-         '/format:csv'],
-        stdout=subprocess.PIPE).communicate()[0].splitlines()[3:]
-    process_info = []
-    for line in lines:
-      if not line:
-        continue
-      parts = line.split(',')
-      pi = {}
-      pi['ProcessId'] = int(parts[-1])
-      pi['ParentProcessId'] = int(parts[-2])
-      pi['Name'] = parts[-3]
-      creation_date = None
-      if parts[-4]:
-        creation_date = float(re.split('[+-]', parts[-4])[0])
-      pi['CreationDate'] = creation_date
-      pi['CommandLine'] = ','.join(parts[1:-4])
-      process_info.append(pi)
-    return process_info
-
-  def GetChildPids(self, pid):
-    """Retunds a list of child pids of |pid|."""
-    ppid_map = collections.defaultdict(list)
-    creation_map = {}
-    for pi in self.GetSystemProcessInfo():
-      ppid_map[pi['ParentProcessId']].append(pi['ProcessId'])
-      if pi['CreationDate']:
-        creation_map[pi['ProcessId']] = pi['CreationDate']
-
-    def _InnerGetChildPids(pid):
-      if not pid or pid not in ppid_map:
-        return []
-      ret = [p for p in ppid_map[pid] if creation_map[p] >= creation_map[pid]]
-      for child in ret:
-        if child == pid:
-          continue
-        ret.extend(_InnerGetChildPids(child))
-      return ret
-
-    return _InnerGetChildPids(pid)
-
-  def GetCommandLine(self, pid):
-    for pi in self.GetSystemProcessInfo():
-      if pid == pi['ProcessId']:
-        return pi['CommandLine']
-    raise exceptions.ProcessGoneException()
-
-  @decorators.Cache
-  def GetArchName(self):
-    return platform.machine()
-
-  def GetOSName(self):
-    return 'win'
-
-  @decorators.Cache
-  def GetOSVersionName(self):
-    os_version = platform.uname()[3]
-
-    if os_version.startswith('5.1.'):
-      return os_version_module.XP
-    if os_version.startswith('6.0.'):
-      return os_version_module.VISTA
-    if os_version.startswith('6.1.'):
-      return os_version_module.WIN7
-    # The version of python.exe we commonly use (2.7) is only manifested as
-    # being compatible with Windows versions up to 8. Therefore Windows *lies*
-    # to python about the version number to keep it runnable on Windows 10.
-    key_name = r'Software\Microsoft\Windows NT\CurrentVersion'
-    key = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, key_name)
-    try:
-      value, _ = winreg.QueryValueEx(key, 'CurrentMajorVersionNumber')
-    except OSError:
-      value = None
-    finally:
-      key.Close()
-    if value == 10:
-      return os_version_module.WIN10
-    elif os_version.startswith('6.2.'):
-      return os_version_module.WIN8
-    elif os_version.startswith('6.3.'):
-      return os_version_module.WIN81
-    raise NotImplementedError(
-        'Unknown win version: %s, CurrentMajorVersionNumber: %s' %
-        (os_version, value))
-
-  def CanFlushIndividualFilesFromSystemCache(self):
-    return True
-
-  def _GetWin32ProcessInfo(self, func, pid):
-    mask = (win32con.PROCESS_QUERY_INFORMATION |
-            win32con.PROCESS_VM_READ)
-    handle = None
-    try:
-      handle = win32api.OpenProcess(mask, False, pid)
-      return func(handle)
-    except pywintypes.error, e:
-      errcode = e[0]
-      if errcode == 87:
-        raise exceptions.ProcessGoneException()
-      raise
-    finally:
-      if handle:
-        win32api.CloseHandle(handle)
-
-  def _GetPerformanceInfo(self):
-    class PerformanceInfo(ctypes.Structure):
-      """Struct for GetPerformanceInfo() call
-      http://msdn.microsoft.com/en-us/library/ms683210
-      """
-      _fields_ = [('size', ctypes.c_ulong),
-                  ('CommitTotal', ctypes.c_size_t),
-                  ('CommitLimit', ctypes.c_size_t),
-                  ('CommitPeak', ctypes.c_size_t),
-                  ('PhysicalTotal', ctypes.c_size_t),
-                  ('PhysicalAvailable', ctypes.c_size_t),
-                  ('SystemCache', ctypes.c_size_t),
-                  ('KernelTotal', ctypes.c_size_t),
-                  ('KernelPaged', ctypes.c_size_t),
-                  ('KernelNonpaged', ctypes.c_size_t),
-                  ('PageSize', ctypes.c_size_t),
-                  ('HandleCount', ctypes.c_ulong),
-                  ('ProcessCount', ctypes.c_ulong),
-                  ('ThreadCount', ctypes.c_ulong)]
-
-      def __init__(self):
-        self.size = ctypes.sizeof(self)
-        # pylint: disable=bad-super-call
-        super(PerformanceInfo, self).__init__()
-
-    performance_info = PerformanceInfo()
-    ctypes.windll.psapi.GetPerformanceInfo(
-        ctypes.byref(performance_info), performance_info.size)
-    return performance_info
-
-  def IsCurrentProcessElevated(self):
-    if self.GetOSVersionName() < os_version_module.VISTA:
-      # TOKEN_QUERY is not defined before Vista. All processes are elevated.
-      return True
-
-    handle = win32process.GetCurrentProcess()
-    with contextlib.closing(
-        win32security.OpenProcessToken(handle, win32con.TOKEN_QUERY)) as token:
-      return bool(win32security.GetTokenInformation(
-          token, win32security.TokenElevation))
-
-  def LaunchApplication(
-      self, application, parameters=None, elevate_privilege=False):
-    """Launch an application. Returns a PyHANDLE object."""
-
-    parameters = ' '.join(parameters) if parameters else ''
-    if elevate_privilege and not self.IsCurrentProcessElevated():
-      # Use ShellExecuteEx() instead of subprocess.Popen()/CreateProcess() to
-      # elevate privileges. A new console will be created if the new process has
-      # different permissions than this process.
-      proc_info = shell.ShellExecuteEx(
-          fMask=shellcon.SEE_MASK_NOCLOSEPROCESS | shellcon.SEE_MASK_NO_CONSOLE,
-          lpVerb='runas' if elevate_privilege else '',
-          lpFile=application,
-          lpParameters=parameters,
-          nShow=win32con.SW_HIDE)
-      if proc_info['hInstApp'] <= 32:
-        raise Exception('Unable to launch %s' % application)
-      return proc_info['hProcess']
-    else:
-      handle, _, _, _ = win32process.CreateProcess(
-          None, application + ' ' + parameters, None, None, False,
-          win32process.CREATE_NO_WINDOW, None, None, win32process.STARTUPINFO())
-      return handle
-
-  def CanMonitorPower(self):
-    return self._power_monitor.CanMonitorPower()
-
-  def CanMeasurePerApplicationPower(self):
-    return self._power_monitor.CanMeasurePerApplicationPower()
-
-  def StartMonitoringPower(self, browser):
-    self._power_monitor.StartMonitoringPower(browser)
-
-  def StopMonitoringPower(self):
-    return self._power_monitor.StopMonitoringPower()
-
-  def _StartMsrServerIfNeeded(self):
-    if self._msr_server_handle:
-      return
-
-    _InstallWinRing0()
-
-    pipe_name = r"\\.\pipe\msr_server_pipe_{}".format(os.getpid())
-    # Try to open a named pipe to receive a msr port number from server process.
-    pipe = win32pipe.CreateNamedPipe(
-        pipe_name,
-        win32pipe.PIPE_ACCESS_INBOUND,
-        win32pipe.PIPE_TYPE_MESSAGE | win32pipe.PIPE_WAIT,
-        1, 32, 32, 300, None)
-    parameters = (
-        os.path.join(os.path.dirname(__file__), 'msr_server_win.py'),
-        pipe_name,
-    )
-    self._msr_server_handle = self.LaunchApplication(
-        sys.executable, parameters, elevate_privilege=True)
-    if pipe != win32file.INVALID_HANDLE_VALUE:
-      if win32pipe.ConnectNamedPipe(pipe, None) == 0:
-        self._msr_server_port = int(win32file.ReadFile(pipe, 32)[1])
-      win32api.CloseHandle(pipe)
-    # Wait for server to start.
-    try:
-      socket.create_connection(('127.0.0.1', self._msr_server_port), 5).close()
-    except socket.error:
-      self.CloseMsrServer()
-    atexit_with_log.Register(TerminateProcess, self._msr_server_handle)
-
-  def ReadMsr(self, msr_number, start=0, length=64):
-    self._StartMsrServerIfNeeded()
-    if not self._msr_server_handle:
-      raise OSError('Unable to start MSR server.')
-
-    sock = socket.create_connection(('127.0.0.1', self._msr_server_port), 5)
-    try:
-      sock.sendall(struct.pack('I', msr_number))
-      response = sock.recv(8)
-    finally:
-      sock.close()
-    return struct.unpack('Q', response)[0] >> start & ((1 << length) - 1)
-
-  def IsCooperativeShutdownSupported(self):
-    return True
-
-  def CooperativelyShutdown(self, proc, app_name):
-    pid = proc.pid
-
-    # http://timgolden.me.uk/python/win32_how_do_i/
-    #   find-the-window-for-my-subprocess.html
-    #
-    # It seems that intermittently this code manages to find windows
-    # that don't belong to Chrome -- for example, the cmd.exe window
-    # running slave.bat on the tryservers. Try to be careful about
-    # finding only Chrome's windows. This works for both the browser
-    # and content_shell.
-    #
-    # It seems safest to send the WM_CLOSE messages after discovering
-    # all of the sub-process's windows.
-    def find_chrome_windows(hwnd, hwnds):
-      _, win_pid = win32process.GetWindowThreadProcessId(hwnd)
-      if (pid == win_pid and
-          win32gui.IsWindowVisible(hwnd) and
-          win32gui.IsWindowEnabled(hwnd) and
-          win32gui.GetClassName(hwnd).lower().startswith(app_name)):
-        hwnds.append(hwnd)
-      return True
-    hwnds = []
-    win32gui.EnumWindows(find_chrome_windows, hwnds)
-    if hwnds:
-      for hwnd in hwnds:
-        win32gui.SendMessage(hwnd, win32con.WM_CLOSE, 0, 0)
-      return True
-    else:
-      logging.info('Did not find any windows owned by target process')
-    return False
diff --git a/catapult/telemetry/telemetry/internal/results/__init__.py b/catapult/telemetry/telemetry/internal/results/__init__.py
deleted file mode 100644
index 172bd9e..0000000
--- a/catapult/telemetry/telemetry/internal/results/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-The PageTestResults hierarchy provides a way of representing the results of
-running the test or measurement on pages.
-"""
-
diff --git a/catapult/telemetry/telemetry/internal/results/base_test_results_unittest.py b/catapult/telemetry/telemetry/internal/results/base_test_results_unittest.py
deleted file mode 100644
index 84e0438..0000000
--- a/catapult/telemetry/telemetry/internal/results/base_test_results_unittest.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import sys
-import unittest
-
-from telemetry.core import exceptions
-
-
-class BaseTestResultsUnittest(unittest.TestCase):
-
-  def CreateException(self):
-    try:
-      raise exceptions.IntentionalException
-    except Exception:
-      return sys.exc_info()
-
-  def assertEquals(self, ex, res):
-    # This helps diagnose result mismatches.
-    if ex != res and isinstance(ex, list):
-      def CleanList(l):
-        res = []
-        for x in l:
-          x = x.split('\n')
-          res.extend(x)
-        return res
-      ex = CleanList(ex)
-      res = CleanList(res)
-      max_len = max(len(ex), len(res))
-      max_width = max([len(x) for x in ex + res])
-      max_width = max(10, max_width)
-      print 'Lists differ!'
-      print '%*s | %*s' % (max_width, 'expected', max_width, 'result')
-      for i in range(max_len):
-        if i < len(ex):
-          e = ex[i]
-        else:
-          e = ''
-        if i < len(res):
-          r = res[i]
-        else:
-          r = ''
-        if e != r:
-          sep = '*'
-        else:
-          sep = '|'
-        print '%*s %s %*s' % (max_width, e, sep, max_width, r)
-      print ''
-    if ex != res and isinstance(ex, str) and isinstance(res, str):
-      print 'Strings differ!'
-      print 'exepected:\n%s' % repr(ex)
-      print 'result:\n%s\n' % repr(res)
-    super(BaseTestResultsUnittest, self).assertEquals(ex, res)
diff --git a/catapult/telemetry/telemetry/internal/results/chart_json_output_formatter.py b/catapult/telemetry/telemetry/internal/results/chart_json_output_formatter.py
deleted file mode 100644
index 6a84be1..0000000
--- a/catapult/telemetry/telemetry/internal/results/chart_json_output_formatter.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import itertools
-import json
-
-from telemetry.internal.results import output_formatter
-from telemetry.value import trace
-
-def ResultsAsChartDict(benchmark_metadata, page_specific_values,
-                       summary_values):
-  """Produces a dict for serialization to Chart JSON format from raw values.
-
-  Chart JSON is a transformation of the basic Telemetry JSON format that
-  removes the page map, summarizes the raw values, and organizes the results
-  by chart and trace name. This function takes the key pieces of data needed to
-  perform this transformation (namely, lists of values and a benchmark metadata
-  object) and processes them into a dict which can be serialized using the json
-  module.
-
-  Design doc for schema: http://goo.gl/kOtf1Y
-
-  Args:
-    page_specific_values: list of page-specific values
-    summary_values: list of summary values
-    benchmark_metadata: a benchmark.BenchmarkMetadata object
-
-  Returns:
-    A Chart JSON dict corresponding to the given data.
-  """
-  values = itertools.chain(
-      output_formatter.SummarizePageSpecificValues(page_specific_values),
-      summary_values)
-  charts = collections.defaultdict(dict)
-
-  for value in values:
-    if value.page:
-      chart_name, trace_name = (value.GetChartAndTraceNameForPerPageResult())
-    else:
-      chart_name, trace_name = (
-          value.GetChartAndTraceNameForComputedSummaryResult(None))
-      if chart_name == trace_name:
-        trace_name = 'summary'
-
-    # Dashboard handles the chart_name of trace values specially: it
-    # strips out the field with chart_name 'trace'. Hence in case trace
-    # value has tir_label, we preserve the chart_name.
-    # For relevant section code of dashboard code that handles this, see:
-    # https://github.com/catapult-project/catapult/blob/25e660b/dashboard/dashboard/add_point.py#L199#L216
-    if value.tir_label and not isinstance(value, trace.TraceValue):
-      chart_name = value.tir_label + '@@' + chart_name
-
-    # This intentionally overwrites the trace if it already exists because this
-    # is expected of output from the buildbots currently.
-    # See: crbug.com/413393
-    charts[chart_name][trace_name] = value.AsDict()
-
-  result_dict = {
-    'format_version': '0.1',
-    'next_version': '0.2',
-    # TODO(sullivan): benchmark_name, benchmark_description, and
-    # trace_rerun_options should be removed when incrementing format_version
-    # to 0.1.
-    'benchmark_name': benchmark_metadata.name,
-    'benchmark_description': benchmark_metadata.description,
-    'trace_rerun_options': benchmark_metadata.rerun_options,
-    'benchmark_metadata': benchmark_metadata.AsDict(),
-    'charts': charts,
-    # Need to add this in for compatibility with disabled chartjson results.
-    'enabled': True
-  }
-
-  return result_dict
-
-
-def DisabledResultsDict(benchmark_name):
-  """Produces a dict for serialization to Chart JSON when a benchmark is
-    disabled.
-
-  Args:
-    benchmark_name: name of the disabled benchmark
-
-  Returns:
-    A Chart JSON dict corresponding to a disabled benchmark.
-  """
-  result_dict = {
-    'benchmark_name': benchmark_name,
-    'enabled': False
-  }
-
-  return result_dict
-
-
-# TODO(eakuefner): Transition this to translate Telemetry JSON.
-class ChartJsonOutputFormatter(output_formatter.OutputFormatter):
-  def __init__(self, output_stream, benchmark_metadata):
-    super(ChartJsonOutputFormatter, self).__init__(output_stream)
-    self._benchmark_metadata = benchmark_metadata
-
-  def FormatDisabled(self):
-    self._Dump(DisabledResultsDict(self._benchmark_metadata.name))
-
-  def Format(self, page_test_results):
-    self._Dump(ResultsAsChartDict(
-      self._benchmark_metadata,
-      page_test_results.all_page_specific_values,
-      page_test_results.all_summary_values))
-
-  def _Dump(self, results):
-    json.dump(results, self.output_stream, indent=2,
-      separators=(',', ': '))
-    self.output_stream.write('\n')
diff --git a/catapult/telemetry/telemetry/internal/results/chart_json_output_formatter_unittest.py b/catapult/telemetry/telemetry/internal/results/chart_json_output_formatter_unittest.py
deleted file mode 100644
index df56b0c..0000000
--- a/catapult/telemetry/telemetry/internal/results/chart_json_output_formatter_unittest.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import os
-import StringIO
-import unittest
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.internal.results import chart_json_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-from telemetry.value import trace
-from tracing.trace_data import trace_data
-
-
-def _MakeStorySet():
-  ps = story.StorySet(base_dir=os.path.dirname(__file__))
-  ps.AddStory(page_module.Page('http://www.foo.com/', ps, ps.base_dir))
-  ps.AddStory(page_module.Page('http://www.bar.com/', ps, ps.base_dir))
-  return ps
-
-class ChartJsonTest(unittest.TestCase):
-  def setUp(self):
-    self._output = StringIO.StringIO()
-    self._story_set = _MakeStorySet()
-    self._benchmark_metadata = benchmark.BenchmarkMetadata(
-        'benchmark_name', 'benchmark_description')
-    self._formatter = chart_json_output_formatter.ChartJsonOutputFormatter(
-        self._output, self._benchmark_metadata)
-
-  def testOutputAndParse(self):
-    results = page_test_results.PageTestResults()
-
-    self._output.truncate(0)
-
-    results.WillRunPage(self._story_set[0])
-    v0 = scalar.ScalarValue(results.current_page, 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    results.AddValue(v0)
-    results.DidRunPage(self._story_set[0])
-
-    self._formatter.Format(results)
-    d = json.loads(self._output.getvalue())
-    self.assertIn('foo', d['charts'])
-
-  def testOutputAndParseDisabled(self):
-    self._formatter.FormatDisabled()
-    d = json.loads(self._output.getvalue())
-    self.assertEquals(d['benchmark_name'], 'benchmark_name')
-    self.assertFalse(d['enabled'])
-
-  def testAsChartDictSerializable(self):
-    v0 = scalar.ScalarValue(self._story_set[0], 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    page_specific_values = [v0]
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-    json.dumps(d)
-
-  def testAsChartDictBaseKeys(self):
-    page_specific_values = []
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertEquals(d['format_version'], '0.1')
-    self.assertEquals(d['next_version'], '0.2')
-    self.assertEquals(d['benchmark_metadata']['name'], 'benchmark_name')
-    self.assertEquals(d['benchmark_metadata']['description'],
-                      'benchmark_description')
-    self.assertEquals(d['benchmark_metadata']['type'], 'telemetry_benchmark')
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictNoDescription(self):
-    page_specific_values = []
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        benchmark.BenchmarkMetadata('benchmark_name', ''),
-        page_specific_values,
-        summary_values)
-
-    self.assertEquals('', d['benchmark_metadata']['description'])
-
-  def testAsChartDictPageSpecificValuesSamePageWithInteractionRecord(self):
-    v0 = scalar.ScalarValue(self._story_set[0], 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN,
-                            tir_label='MyIR')
-    v1 = scalar.ScalarValue(self._story_set[0], 'foo', 'seconds', 4,
-                            improvement_direction=improvement_direction.DOWN,
-                            tir_label='MyIR')
-    page_specific_values = [v0, v1]
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertTrue('MyIR@@foo' in d['charts'])
-    self.assertTrue('http://www.foo.com/' in d['charts']['MyIR@@foo'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictPageSpecificValuesSamePageWithoutInteractionRecord(self):
-    v0 = scalar.ScalarValue(self._story_set[0], 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    v1 = scalar.ScalarValue(self._story_set[0], 'foo', 'seconds', 4,
-                            improvement_direction=improvement_direction.DOWN)
-    page_specific_values = [v0, v1]
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertTrue('foo' in d['charts'])
-    self.assertTrue('http://www.foo.com/' in d['charts']['foo'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictPageSpecificValuesAndComputedSummaryWithTraceName(self):
-    v0 = scalar.ScalarValue(self._story_set[0], 'foo.bar', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    v1 = scalar.ScalarValue(self._story_set[1], 'foo.bar', 'seconds', 4,
-                            improvement_direction=improvement_direction.DOWN)
-    page_specific_values = [v0, v1]
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertTrue('foo' in d['charts'])
-    self.assertTrue('http://www.foo.com/' in d['charts']['foo'])
-    self.assertTrue('http://www.bar.com/' in d['charts']['foo'])
-    self.assertTrue('bar' in d['charts']['foo'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictPageSpecificValuesAndComputedSummaryWithoutTraceName(self):
-    v0 = scalar.ScalarValue(self._story_set[0], 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    v1 = scalar.ScalarValue(self._story_set[1], 'foo', 'seconds', 4,
-                            improvement_direction=improvement_direction.DOWN)
-    page_specific_values = [v0, v1]
-    summary_values = []
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertTrue('foo' in d['charts'])
-    self.assertTrue('http://www.foo.com/' in d['charts']['foo'])
-    self.assertTrue('http://www.bar.com/' in d['charts']['foo'])
-    self.assertTrue('summary' in d['charts']['foo'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictSummaryValueWithTraceName(self):
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        None, 'foo.bar', 'seconds', [3, 4],
-        improvement_direction=improvement_direction.DOWN)
-    page_specific_values = []
-    summary_values = [v0]
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertTrue('bar' in d['charts']['foo'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictSummaryValueWithoutTraceName(self):
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        None, 'foo', 'seconds', [3, 4],
-        improvement_direction=improvement_direction.DOWN)
-    page_specific_values = []
-    summary_values = [v0]
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertTrue('summary' in d['charts']['foo'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictWithTraceValuesThatHasTirLabel(self):
-    v = trace.TraceValue(self._story_set[0],
-                         trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-    v.tir_label = 'background'
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values=[v],
-        summary_values=[v])
-
-    self.assertTrue('trace' in d['charts'])
-    self.assertTrue('http://www.foo.com/' in d['charts']['trace'],
-                    msg=d['charts']['trace'])
-    self.assertTrue(d['enabled'])
-
-  def testAsChartDictValueSmokeTest(self):
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        None, 'foo.bar', 'seconds', [3, 4],
-        improvement_direction=improvement_direction.DOWN)
-    page_specific_values = []
-    summary_values = [v0]
-
-    d = chart_json_output_formatter.ResultsAsChartDict(
-        self._benchmark_metadata,
-        page_specific_values,
-        summary_values)
-
-    self.assertEquals(d['charts']['foo']['bar']['values'], [3, 4])
diff --git a/catapult/telemetry/telemetry/internal/results/csv_pivot_table_output_formatter.py b/catapult/telemetry/telemetry/internal/results/csv_pivot_table_output_formatter.py
deleted file mode 100644
index 43fb973..0000000
--- a/catapult/telemetry/telemetry/internal/results/csv_pivot_table_output_formatter.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import csv
-
-from telemetry.internal.results import output_formatter
-from telemetry.value import scalar
-from telemetry.value import trace
-
-
-class CsvPivotTableOutputFormatter(output_formatter.OutputFormatter):
-  """Output the results as CSV suitable for reading into a spreadsheet.
-
-  This will write a header row, and one row for each value. Each value row
-  contains the value and unit, identifies the value (story_set, page, name), and
-  (optionally) data from --output-trace-tag. This format matches what
-  spreadsheet programs expect as input for a "pivot table".
-
-  A trace tag (--output-trace-tag) can be used to tag each value, to allow
-  easy combination of the resulting CSVs from several runs.
-  If the trace_tag contains a comma, it will be written as several
-  comma-separated values.
-
-  This class only processes scalar values.
-  """
-
-  FIELDS = ['story_set', 'page', 'name', 'value', 'units', 'run_index']
-
-  def __init__(self, output_stream, trace_tag=''):
-    super(CsvPivotTableOutputFormatter, self).__init__(output_stream)
-    self._trace_tag = trace_tag
-
-  def Format(self, page_test_results):
-    csv_writer = csv.writer(self.output_stream)
-
-    # Observe trace_tag. Use comma to split up the trace tag.
-    tag_values = self._trace_tag.split(',')
-    tag_values = [x for x in tag_values if x] # filter empty list entries
-    tag_headers = ['trace_tag_%d' % i for i in range(len(tag_values))]
-
-    # Write header.
-    csv_writer.writerow(self.FIELDS + tag_headers)
-
-    # Write all values. Each row contains a value + page-level metadata.
-    for run in page_test_results.all_page_runs:
-      run_index = page_test_results.all_page_runs.index(run)
-      page_dict = {
-          'page': run.story.display_name,
-          'story_set': run.story.page_set.Name(),
-          'run_index': run_index,
-      }
-      for value in run.values:
-        if (isinstance(value, scalar.ScalarValue) or
-            isinstance(value, trace.TraceValue)):
-          value_dict = {
-            'name': value.name,
-            'value': value.value,
-            'units': value.units,
-          }
-          value_dict.update(page_dict.items())
-          csv_writer.writerow(
-              [value_dict[field] for field in self.FIELDS] + tag_values)
diff --git a/catapult/telemetry/telemetry/internal/results/csv_pivot_table_output_formatter_unittest.py b/catapult/telemetry/telemetry/internal/results/csv_pivot_table_output_formatter_unittest.py
deleted file mode 100644
index 1ada569..0000000
--- a/catapult/telemetry/telemetry/internal/results/csv_pivot_table_output_formatter_unittest.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import StringIO
-import unittest
-
-import mock
-
-from telemetry import story
-from telemetry.internal.results import csv_pivot_table_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.value import trace
-from tracing.trace_data import trace_data
-
-
-def _MakeStorySet():
-  story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-  story_set.AddStory(
-      page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-  return story_set
-
-
-class CsvPivotTableOutputFormatterTest(unittest.TestCase):
-
-  # The line separator used by CSV formatter.
-  _LINE_SEPARATOR = '\r\n'
-
-  def setUp(self):
-    self._output = StringIO.StringIO()
-    self._story_set = _MakeStorySet()
-    self._results = page_test_results.PageTestResults()
-    self._formatter = None
-    self.MakeFormatter()
-
-  def MakeFormatter(self, trace_tag=''):
-    self._formatter = (
-        csv_pivot_table_output_formatter.CsvPivotTableOutputFormatter(
-            self._output, trace_tag))
-
-  def SimulateBenchmarkRun(self, list_of_page_and_values):
-    """Simulate one run of a benchmark, using the supplied values.
-
-    Args:
-      list_of_pages_and_values: a list of tuple (page, list of values)
-    """
-    for page, values in list_of_page_and_values:
-      self._results.WillRunPage(page)
-      for v in values:
-        v.page = page
-        self._results.AddValue(v)
-      self._results.DidRunPage(page)
-
-  def Format(self):
-    self._formatter.Format(self._results)
-    return self._output.getvalue()
-
-  def testSimple(self):
-    # Test a simple benchmark with only one value:
-    self.SimulateBenchmarkRun([
-        (self._story_set[0], [scalar.ScalarValue(
-            None, 'foo', 'seconds', 3,
-            improvement_direction=improvement_direction.DOWN)])])
-    expected = self._LINE_SEPARATOR.join([
-        'story_set,page,name,value,units,run_index',
-        'story_set,http://www.foo.com/,foo,3,seconds,0',
-        ''])
-
-    self.assertEqual(expected, self.Format())
-
-  @mock.patch('py_utils.cloud_storage.Insert')
-  def testMultiplePagesAndValues(self, cs_insert_mock):
-    cs_insert_mock.return_value = 'https://cloud_storage_url/foo'
-    trace_value = trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData('{"traceEvents": []}'))
-    trace_value.UploadToCloud(bucket='foo')
-    self.SimulateBenchmarkRun([
-        (self._story_set[0], [
-            scalar.ScalarValue(
-              None, 'foo', 'seconds', 4,
-              improvement_direction=improvement_direction.DOWN)]),
-        (self._story_set[1], [
-            scalar.ScalarValue(
-                None, 'foo', 'seconds', 3.4,
-                improvement_direction=improvement_direction.DOWN),
-            trace_value,
-            scalar.ScalarValue(
-                None, 'bar', 'km', 10,
-                improvement_direction=improvement_direction.DOWN),
-            scalar.ScalarValue(
-                None, 'baz', 'count', 5,
-                improvement_direction=improvement_direction.DOWN)])])
-
-    # Parse CSV output into list of lists.
-    csv_string = self.Format()
-    lines = csv_string.split(self._LINE_SEPARATOR)
-    values = [s.split(',') for s in lines[1:-1]]
-
-    self.assertEquals(len(values), 5)  # We expect 5 value in total.
-    self.assertEquals(len(set((v[1] for v in values))), 2)  # 2 pages.
-    self.assertEquals(len(set((v[2] for v in values))), 4)  # 4 value names.
-    self.assertEquals(values[2],
-        ['story_set', 'http://www.bar.com/', 'trace',
-         'https://cloud_storage_url/foo', '', '1'])
-
-  def testTraceTag(self):
-    self.MakeFormatter(trace_tag='date,option')
-    self.SimulateBenchmarkRun([
-        (self._story_set[0], [
-            scalar.ScalarValue(
-                None, 'foo', 'seconds', 3,
-                improvement_direction=improvement_direction.DOWN),
-            scalar.ScalarValue(
-                None, 'bar', 'tons', 5,
-                improvement_direction=improvement_direction.DOWN)])])
-    output = self.Format().split(self._LINE_SEPARATOR)
-
-    self.assertTrue(output[0].endswith(',trace_tag_0,trace_tag_1'))
-    for line in output[1:-1]:
-      self.assertTrue(line.endswith(',date,option'))
diff --git a/catapult/telemetry/telemetry/internal/results/gtest_progress_reporter.py b/catapult/telemetry/telemetry/internal/results/gtest_progress_reporter.py
deleted file mode 100644
index 75e6864..0000000
--- a/catapult/telemetry/telemetry/internal/results/gtest_progress_reporter.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import time
-
-from telemetry.internal.results import progress_reporter
-from telemetry.value import failure
-from telemetry.value import skip
-
-
-class GTestProgressReporter(progress_reporter.ProgressReporter):
-  """A progress reporter that outputs the progress report in gtest style.
-
-  Be careful each print should only handle one string. Otherwise, the output
-  might be interrupted by Chrome logging, and the output interpretation might
-  be incorrect. For example:
-      print >> self._output_stream, "[ OK ]", testname
-  should be written as
-      print >> self._output_stream, "[ OK ] %s" % testname
-  """
-
-  def __init__(self, output_stream, output_skipped_tests_summary=False):
-    super(GTestProgressReporter, self).__init__()
-    self._output_stream = output_stream
-    self._timestamp = None
-    self._output_skipped_tests_summary = output_skipped_tests_summary
-
-  def _GetMs(self):
-    assert self._timestamp is not None, 'Did not call WillRunPage.'
-    return (time.time() - self._timestamp) * 1000
-
-  def _GenerateGroupingKeyString(self, page):
-    return '' if not page.grouping_keys else '@%s' % str(page.grouping_keys)
-
-  def DidAddValue(self, value):
-    super(GTestProgressReporter, self).DidAddValue(value)
-    if isinstance(value, failure.FailureValue):
-      print >> self._output_stream, failure.GetStringFromExcInfo(
-          value.exc_info)
-      self._output_stream.flush()
-    elif isinstance(value, skip.SkipValue):
-      print >> self._output_stream, '===== SKIPPING TEST %s: %s =====' % (
-          value.page.display_name, value.reason)
-    # TODO(chrishenry): Consider outputting metric values as well. For
-    # e.g., it can replace BuildbotOutputFormatter in
-    # --output-format=html, which we used only so that users can grep
-    # the results without opening results.html.
-
-  def WillRunPage(self, page_test_results):
-    super(GTestProgressReporter, self).WillRunPage(page_test_results)
-    print >> self._output_stream, '[ RUN      ] %s%s' % (
-        page_test_results.current_page.display_name,
-        self._GenerateGroupingKeyString(page_test_results.current_page))
-
-    self._output_stream.flush()
-    self._timestamp = time.time()
-
-  def DidRunPage(self, page_test_results):
-    super(GTestProgressReporter, self).DidRunPage(page_test_results)
-    page = page_test_results.current_page
-    if page_test_results.current_page_run.failed:
-      print >> self._output_stream, '[  FAILED  ] %s%s (%0.f ms)' % (
-          page.display_name,
-          self._GenerateGroupingKeyString(page_test_results.current_page),
-          self._GetMs())
-    else:
-      print >> self._output_stream, '[       OK ] %s%s (%0.f ms)' % (
-          page.display_name,
-          self._GenerateGroupingKeyString(page_test_results.current_page),
-          self._GetMs())
-    self._output_stream.flush()
-
-  def DidFinishAllTests(self, page_test_results):
-    super(GTestProgressReporter, self).DidFinishAllTests(page_test_results)
-    successful_runs = []
-    failed_runs = []
-    for run in page_test_results.all_page_runs:
-      if run.failed:
-        failed_runs.append(run)
-      else:
-        successful_runs.append(run)
-
-    unit = 'test' if len(successful_runs) == 1 else 'tests'
-    print >> self._output_stream, '[  PASSED  ] %d %s.' % (
-        (len(successful_runs), unit))
-    if len(failed_runs) > 0:
-      unit = 'test' if len(failed_runs) == 1 else 'tests'
-      print >> self._output_stream, '[  FAILED  ] %d %s, listed below:' % (
-          (len(page_test_results.failures), unit))
-      for failed_run in failed_runs:
-        print >> self._output_stream, '[  FAILED  ]  %s%s' % (
-            failed_run.story.display_name,
-            self._GenerateGroupingKeyString(failed_run.story))
-      print >> self._output_stream
-      count = len(failed_runs)
-      unit = 'TEST' if count == 1 else 'TESTS'
-      print >> self._output_stream, '%d FAILED %s' % (count, unit)
-    print >> self._output_stream
-
-    if self._output_skipped_tests_summary:
-      if len(page_test_results.skipped_values) > 0:
-        print >> self._output_stream, 'Skipped pages:\n%s\n' % ('\n'.join(
-            v.page.display_name for v in page_test_results.skipped_values))
-
-    self._output_stream.flush()
diff --git a/catapult/telemetry/telemetry/internal/results/gtest_progress_reporter_unittest.py b/catapult/telemetry/telemetry/internal/results/gtest_progress_reporter_unittest.py
deleted file mode 100644
index a6d0d5d..0000000
--- a/catapult/telemetry/telemetry/internal/results/gtest_progress_reporter_unittest.py
+++ /dev/null
@@ -1,250 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import traceback
-
-from telemetry import story
-from telemetry.internal.results import base_test_results_unittest
-from telemetry.internal.results import gtest_progress_reporter
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.testing import fakes
-from telemetry.testing import stream
-from telemetry.value import failure
-from telemetry.value import skip
-
-
-_GROUPING_KEY_DEFAULT = {'1': '2'}
-
-
-def _MakeStorySet():
-  story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-  story_set.AddStory(
-      page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.roz.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.fus.com/', story_set, story_set.base_dir,
-                       grouping_keys=_GROUPING_KEY_DEFAULT))
-  story_set.AddStory(
-      page_module.Page('http://www.ro.com/', story_set, story_set.base_dir,
-                       grouping_keys=_GROUPING_KEY_DEFAULT))
-  return story_set
-
-
-class GTestProgressReporterTest(
-    base_test_results_unittest.BaseTestResultsUnittest):
-
-  def setUp(self):
-    super(GTestProgressReporterTest, self).setUp()
-    self._fake_timer = fakes.FakeTimer(gtest_progress_reporter)
-
-    self._output_stream = stream.TestOutputStream()
-    self._reporter = gtest_progress_reporter.GTestProgressReporter(
-        self._output_stream)
-
-  def tearDown(self):
-    self._fake_timer.Restore()
-
-  def testSingleSuccessPage(self):
-    test_story_set = _MakeStorySet()
-
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    results.WillRunPage(test_story_set.stories[0])
-    self._fake_timer.SetTime(0.007)
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.PrintSummary()
-    expected = ('[ RUN      ] http://www.foo.com/\n'
-                '[       OK ] http://www.foo.com/ (7 ms)\n'
-                '[  PASSED  ] 1 test.\n\n')
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-  def testSingleSuccessPageWithGroupingKeys(self):
-    test_story_set = _MakeStorySet()
-
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    results.WillRunPage(test_story_set.stories[4])
-    self._fake_timer.SetTime(0.007)
-    results.DidRunPage(test_story_set.stories[4])
-
-    results.PrintSummary()
-    expected = ("[ RUN      ] http://www.fus.com/@{'1': '2'}\n"
-                "[       OK ] http://www.fus.com/@{'1': '2'} (7 ms)\n"
-                "[  PASSED  ] 1 test.\n\n")
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-  def testSingleFailedPage(self):
-    test_story_set = _MakeStorySet()
-
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    results.WillRunPage(test_story_set.stories[0])
-    exc_info = self.CreateException()
-    results.AddValue(failure.FailureValue(test_story_set.stories[0], exc_info))
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.PrintSummary()
-    exception_trace = ''.join(traceback.format_exception(*exc_info))
-    expected = ('[ RUN      ] http://www.foo.com/\n'
-                '%s\n'
-                '[  FAILED  ] http://www.foo.com/ (0 ms)\n'
-                '[  PASSED  ] 0 tests.\n'
-                '[  FAILED  ] 1 test, listed below:\n'
-                '[  FAILED  ]  http://www.foo.com/\n\n'
-                '1 FAILED TEST\n\n' % exception_trace)
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-  def testSingleFailedPageWithGroupingKeys(self):
-    test_story_set = _MakeStorySet()
-
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    results.WillRunPage(test_story_set.stories[4])
-    exc_info = self.CreateException()
-    results.AddValue(failure.FailureValue(test_story_set.stories[4], exc_info))
-    results.DidRunPage(test_story_set.stories[4])
-
-    results.PrintSummary()
-    exception_trace = ''.join(traceback.format_exception(*exc_info))
-    expected = ("[ RUN      ] http://www.fus.com/@{'1': '2'}\n"
-                "%s\n"
-                "[  FAILED  ] http://www.fus.com/@{'1': '2'} (0 ms)\n"
-                "[  PASSED  ] 0 tests.\n"
-                "[  FAILED  ] 1 test, listed below:\n"
-                "[  FAILED  ]  http://www.fus.com/@{'1': '2'}\n\n"
-                "1 FAILED TEST\n\n" % exception_trace)
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-  def testSingleSkippedPage(self):
-    test_story_set = _MakeStorySet()
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    results.WillRunPage(test_story_set.stories[0])
-    self._fake_timer.SetTime(0.007)
-    results.AddValue(skip.SkipValue(test_story_set.stories[0],
-        'Page skipped for testing reason'))
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.PrintSummary()
-    expected = ('[ RUN      ] http://www.foo.com/\n'
-                '===== SKIPPING TEST http://www.foo.com/:'
-                ' Page skipped for testing reason =====\n'
-                '[       OK ] http://www.foo.com/ (7 ms)\n'
-                '[  PASSED  ] 1 test.\n\n')
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-  def testPassAndFailedPages(self):
-    test_story_set = _MakeStorySet()
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    exc_info = self.CreateException()
-
-    results.WillRunPage(test_story_set.stories[0])
-    self._fake_timer.SetTime(0.007)
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.WillRunPage(test_story_set.stories[1])
-    self._fake_timer.SetTime(0.009)
-    results.AddValue(failure.FailureValue(test_story_set.stories[1], exc_info))
-    results.DidRunPage(test_story_set.stories[1])
-
-    results.WillRunPage(test_story_set.stories[2])
-    self._fake_timer.SetTime(0.015)
-    results.AddValue(failure.FailureValue(test_story_set.stories[2], exc_info))
-    results.DidRunPage(test_story_set.stories[2])
-
-    results.WillRunPage(test_story_set.stories[3])
-    self._fake_timer.SetTime(0.020)
-    results.DidRunPage(test_story_set.stories[3])
-
-    results.WillRunPage(test_story_set.stories[4])
-    self._fake_timer.SetTime(0.025)
-    results.DidRunPage(test_story_set.stories[4])
-
-    results.WillRunPage(test_story_set.stories[5])
-    self._fake_timer.SetTime(0.030)
-    results.AddValue(failure.FailureValue(test_story_set.stories[5], exc_info))
-    results.DidRunPage(test_story_set.stories[5])
-
-    results.PrintSummary()
-    exception_trace = ''.join(traceback.format_exception(*exc_info))
-    expected = ("[ RUN      ] http://www.foo.com/\n"
-                "[       OK ] http://www.foo.com/ (7 ms)\n"
-                "[ RUN      ] http://www.bar.com/\n"
-                "%s\n"
-                "[  FAILED  ] http://www.bar.com/ (2 ms)\n"
-                "[ RUN      ] http://www.baz.com/\n"
-                "%s\n"
-                "[  FAILED  ] http://www.baz.com/ (6 ms)\n"
-                "[ RUN      ] http://www.roz.com/\n"
-                "[       OK ] http://www.roz.com/ (5 ms)\n"
-                "[ RUN      ] http://www.fus.com/@{'1': '2'}\n"
-                "[       OK ] http://www.fus.com/@{'1': '2'} (5 ms)\n"
-                "[ RUN      ] http://www.ro.com/@{'1': '2'}\n"
-                "%s\n"
-                "[  FAILED  ] http://www.ro.com/@{'1': '2'} (5 ms)\n"
-                "[  PASSED  ] 3 tests.\n"
-                "[  FAILED  ] 3 tests, listed below:\n"
-                "[  FAILED  ]  http://www.bar.com/\n"
-                "[  FAILED  ]  http://www.baz.com/\n"
-                "[  FAILED  ]  http://www.ro.com/@{'1': '2'}\n\n"
-                "3 FAILED TESTS\n\n"
-                % (exception_trace, exception_trace, exception_trace))
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-  def testStreamingResults(self):
-    test_story_set = _MakeStorySet()
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    exc_info = self.CreateException()
-
-    results.WillRunPage(test_story_set.stories[0])
-    self._fake_timer.SetTime(0.007)
-    results.DidRunPage(test_story_set.stories[0])
-    expected = ('[ RUN      ] http://www.foo.com/\n'
-                '[       OK ] http://www.foo.com/ (7 ms)\n')
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
-
-    results.WillRunPage(test_story_set.stories[1])
-    self._fake_timer.SetTime(0.009)
-    exception_trace = ''.join(traceback.format_exception(*exc_info))
-    results.AddValue(failure.FailureValue(test_story_set.stories[1], exc_info))
-    results.DidRunPage(test_story_set.stories[1])
-    expected = ('[ RUN      ] http://www.foo.com/\n'
-                '[       OK ] http://www.foo.com/ (7 ms)\n'
-                '[ RUN      ] http://www.bar.com/\n'
-                '%s\n'
-                '[  FAILED  ] http://www.bar.com/ (2 ms)\n' % exception_trace)
-
-  def testOutputSkipInformation(self):
-    test_story_set = _MakeStorySet()
-    self._reporter = gtest_progress_reporter.GTestProgressReporter(
-        self._output_stream, output_skipped_tests_summary=True)
-    results = page_test_results.PageTestResults(
-        progress_reporter=self._reporter)
-    results.WillRunPage(test_story_set.stories[0])
-    self._fake_timer.SetTime(0.007)
-    results.AddValue(skip.SkipValue(test_story_set.stories[0],
-        'Page skipped for testing reason'))
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.PrintSummary()
-    expected = ('[ RUN      ] http://www.foo.com/\n'
-                '===== SKIPPING TEST http://www.foo.com/:'
-                ' Page skipped for testing reason =====\n'
-                '[       OK ] http://www.foo.com/ (7 ms)\n'
-                '[  PASSED  ] 1 test.\n'
-                '\n'
-                'Skipped pages:\n'
-                'http://www.foo.com/\n'
-                '\n')
-    self.assertEquals(expected, ''.join(self._output_stream.output_data))
diff --git a/catapult/telemetry/telemetry/internal/results/histogram_set_json_output_formatter.py b/catapult/telemetry/telemetry/internal/results/histogram_set_json_output_formatter.py
deleted file mode 100644
index 6c6f397..0000000
--- a/catapult/telemetry/telemetry/internal/results/histogram_set_json_output_formatter.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-
-from telemetry.internal.results import output_formatter
-
-
-class HistogramSetJsonOutputFormatter(output_formatter.OutputFormatter):
-  def __init__(self, output_stream, metadata, reset_results):
-    super(HistogramSetJsonOutputFormatter, self).__init__(output_stream)
-    self._metadata = metadata
-    self._reset_results = reset_results
-
-  def Format(self, page_test_results):
-    histograms = page_test_results.AsHistogramDicts(self._metadata)
-    self._output_stream.seek(0)
-    if not self._reset_results:
-      existing = self._output_stream.read()
-      self._output_stream.seek(0)
-      if existing:
-        try:
-          histograms += json.loads(existing)
-        except ValueError:
-          logging.warn('Found existing histograms json but failed to parse it.')
-    json.dump(histograms, self._output_stream)
diff --git a/catapult/telemetry/telemetry/internal/results/html_output_formatter.py b/catapult/telemetry/telemetry/internal/results/html_output_formatter.py
deleted file mode 100644
index 1e12965..0000000
--- a/catapult/telemetry/telemetry/internal/results/html_output_formatter.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import datetime
-import json
-import logging
-import os
-import tempfile
-
-from py_utils import cloud_storage
-
-from telemetry.internal.results import chart_json_output_formatter
-from telemetry.internal.results import output_formatter
-
-from tracing import results_renderer
-from tracing.value import convert_chart_json
-
-
-class HtmlOutputFormatter(output_formatter.OutputFormatter):
-  def __init__(self, output_stream, metadata, reset_results,
-               upload_bucket=None):
-    super(HtmlOutputFormatter, self).__init__(output_stream)
-    self._metadata = metadata
-    self._upload_bucket = upload_bucket
-    self._reset_results = reset_results
-
-  def _ConvertChartJson(self, page_test_results):
-    chart_json = chart_json_output_formatter.ResultsAsChartDict(
-        self._metadata, page_test_results.all_page_specific_values,
-        page_test_results.all_summary_values)
-    info = page_test_results.telemetry_info
-    chart_json['label'] = info.label
-    chart_json['benchmarkStartMs'] = info.benchmark_start_ms
-
-    file_descriptor, chart_json_path = tempfile.mkstemp()
-    os.close(file_descriptor)
-    json.dump(chart_json, file(chart_json_path, 'w'))
-
-    vinn_result = convert_chart_json.ConvertChartJson(chart_json_path)
-
-    os.remove(chart_json_path)
-
-    if vinn_result.returncode != 0:
-      logging.error('Error converting chart json to Histograms:\n' +
-          vinn_result.stdout)
-      return []
-    return json.loads(vinn_result.stdout)
-
-  def Format(self, page_test_results):
-    histograms = page_test_results.value_set
-    if not histograms:
-      histograms = self._ConvertChartJson(page_test_results)
-
-    results_renderer.RenderHTMLView(histograms,
-        self._output_stream, self._reset_results)
-    file_path = os.path.abspath(self._output_stream.name)
-    if self._upload_bucket:
-      remote_path = ('html-results/results-%s' %
-                     datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'))
-      try:
-        url = cloud_storage.Insert(self._upload_bucket, remote_path, file_path)
-        print 'View HTML results online at %s' % url
-      except cloud_storage.PermissionError as e:
-        logging.error('Cannot upload profiling files to cloud storage due to '
-                      ' permission error: %s' % e.message)
diff --git a/catapult/telemetry/telemetry/internal/results/json_output_formatter.py b/catapult/telemetry/telemetry/internal/results/json_output_formatter.py
deleted file mode 100644
index 81dd35f..0000000
--- a/catapult/telemetry/telemetry/internal/results/json_output_formatter.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-
-from telemetry.internal.results import output_formatter
-
-
-def ResultsAsDict(page_test_results, benchmark_metadata):
-  """Takes PageTestResults to a dict serializable to JSON.
-
-  To serialize results as JSON we first convert them to a dict that can be
-  serialized by the json module. It also requires a benchmark_metadat object
-  for metadata to be integrated into the results (currently the benchmark
-  name). This function will also output trace files if they exist.
-
-  Args:
-    page_test_results: a PageTestResults object
-    benchmark_metadata: a benchmark.BenchmarkMetadata object
-  """
-  result_dict = {
-    'format_version': '0.2',
-    'next_version': '0.3',
-    # TODO(sullivan): benchmark_name should be removed when updating
-    # format_version to 0.3.
-    'benchmark_name': benchmark_metadata.name,
-    'benchmark_metadata': benchmark_metadata.AsDict(),
-    'summary_values': [v.AsDict() for v in
-                       page_test_results.all_summary_values],
-    'per_page_values': [v.AsDict() for v in
-                        page_test_results.all_page_specific_values],
-    'pages': {p.id: p.AsDict() for p in _GetAllPages(page_test_results)}
-  }
-  if page_test_results.serialized_trace_file_ids_to_paths:
-    result_dict['files'] = page_test_results.serialized_trace_file_ids_to_paths
-  return result_dict
-
-
-def _GetAllPages(page_test_results):
-  pages = set(page_run.story for page_run in
-              page_test_results.all_page_runs)
-  return pages
-
-
-class JsonOutputFormatter(output_formatter.OutputFormatter):
-  def __init__(self, output_stream, benchmark_metadata):
-    super(JsonOutputFormatter, self).__init__(output_stream)
-    self._benchmark_metadata = benchmark_metadata
-
-  @property
-  def benchmark_metadata(self):
-    return self._benchmark_metadata
-
-  def Format(self, page_test_results):
-    json.dump(
-        ResultsAsDict(page_test_results, self.benchmark_metadata),
-        self.output_stream, indent=2)
-    self.output_stream.write('\n')
diff --git a/catapult/telemetry/telemetry/internal/results/json_output_formatter_unittest.py b/catapult/telemetry/telemetry/internal/results/json_output_formatter_unittest.py
deleted file mode 100644
index d2cd40e..0000000
--- a/catapult/telemetry/telemetry/internal/results/json_output_formatter_unittest.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import json
-import os
-import shutil
-import StringIO
-import tempfile
-import unittest
-
-from telemetry import story
-from telemetry import benchmark
-from telemetry.internal.results import json_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.value import trace
-from tracing.trace_data import trace_data
-
-
-def _MakeStorySet():
-  story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-  story_set.AddStory(
-      page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-  return story_set
-
-def _HasPage(pages, page):
-  return pages.get(page.id, None) != None
-
-def _HasValueNamed(values, name):
-  return len([x for x in values if x['name'] == name]) == 1
-
-class JsonOutputFormatterTest(unittest.TestCase):
-  def setUp(self):
-    self._output = StringIO.StringIO()
-    self._story_set = _MakeStorySet()
-    self._formatter = json_output_formatter.JsonOutputFormatter(
-        self._output,
-        benchmark.BenchmarkMetadata('benchmark_name'))
-
-  def testOutputAndParse(self):
-    results = page_test_results.PageTestResults()
-
-    self._output.truncate(0)
-
-    results.WillRunPage(self._story_set[0])
-    v0 = scalar.ScalarValue(results.current_page, 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    results.AddValue(v0)
-    results.DidRunPage(self._story_set[0])
-
-    self._formatter.Format(results)
-    json.loads(self._output.getvalue())
-
-  def testAsDictBaseKeys(self):
-    results = page_test_results.PageTestResults()
-    d = json_output_formatter.ResultsAsDict(results,
-        self._formatter.benchmark_metadata)
-
-    self.assertEquals(d['format_version'], '0.2')
-    self.assertEquals(d['next_version'], '0.3')
-    self.assertEquals(d['benchmark_metadata']['name'], 'benchmark_name')
-
-  def testAsDictWithOnePage(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self._story_set[0])
-    v0 = scalar.ScalarValue(results.current_page, 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    results.AddValue(v0)
-    results.DidRunPage(self._story_set[0])
-
-    d = json_output_formatter.ResultsAsDict(results,
-        self._formatter.benchmark_metadata)
-
-    self.assertTrue(_HasPage(d['pages'], self._story_set[0]))
-    self.assertTrue(_HasValueNamed(d['per_page_values'], 'foo'))
-
-  def testAsDictWithTraceValue(self):
-    tempdir = tempfile.mkdtemp()
-    try:
-      results = page_test_results.PageTestResults()
-      results.WillRunPage(self._story_set[0])
-      v0 = trace.TraceValue(
-          results.current_page,
-          trace_data.CreateTraceDataFromRawData([{'event': 'test'}]))
-      results.AddValue(v0)
-      results.DidRunPage(self._story_set[0])
-      results._SerializeTracesToDirPath(tempdir)
-      d = json_output_formatter.ResultsAsDict(results,
-          self._formatter.benchmark_metadata)
-
-      self.assertTrue(_HasPage(d['pages'], self._story_set[0]))
-      self.assertTrue(_HasValueNamed(d['per_page_values'], 'trace'))
-      self.assertEquals(len(d['files']), 1)
-      output_trace_path = d['files'].values()[0]
-      self.assertTrue(output_trace_path.startswith(tempdir))
-      self.assertTrue(os.path.exists(output_trace_path))
-    finally:
-      shutil.rmtree(tempdir)
-
-  def testAsDictWithTwoPages(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self._story_set[0])
-    v0 = scalar.ScalarValue(results.current_page, 'foo', 'seconds', 3,
-                            improvement_direction=improvement_direction.DOWN)
-    results.AddValue(v0)
-    results.DidRunPage(self._story_set[0])
-
-    results.WillRunPage(self._story_set[1])
-    v1 = scalar.ScalarValue(results.current_page, 'bar', 'seconds', 4,
-                            improvement_direction=improvement_direction.DOWN)
-    results.AddValue(v1)
-    results.DidRunPage(self._story_set[1])
-
-    d = json_output_formatter.ResultsAsDict(results,
-        self._formatter.benchmark_metadata)
-
-    self.assertTrue(_HasPage(d['pages'], self._story_set[0]))
-    self.assertTrue(_HasPage(d['pages'], self._story_set[1]))
-    self.assertTrue(_HasValueNamed(d['per_page_values'], 'foo'))
-    self.assertTrue(_HasValueNamed(d['per_page_values'], 'bar'))
-
-  def testAsDictWithSummaryValueOnly(self):
-    results = page_test_results.PageTestResults()
-    v = scalar.ScalarValue(None, 'baz', 'seconds', 5,
-                           improvement_direction=improvement_direction.DOWN)
-    results.AddSummaryValue(v)
-
-    d = json_output_formatter.ResultsAsDict(results,
-        self._formatter.benchmark_metadata)
-
-    self.assertFalse(d['pages'])
-    self.assertTrue(_HasValueNamed(d['summary_values'], 'baz'))
diff --git a/catapult/telemetry/telemetry/internal/results/legacy_html_output_formatter.py b/catapult/telemetry/telemetry/internal/results/legacy_html_output_formatter.py
deleted file mode 100644
index a3782c0..0000000
--- a/catapult/telemetry/telemetry/internal/results/legacy_html_output_formatter.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import datetime
-import json
-import logging
-import os
-import re
-
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.results import chart_json_output_formatter
-from telemetry.internal.results import output_formatter
-from telemetry import value as value_module
-from telemetry.value import list_of_scalar_values
-
-
-_TEMPLATE_HTML_PATH = os.path.join(
-    util.GetTelemetryDir(), 'support', 'html_output', 'results-template.html')
-_JS_PLUGINS = [os.path.join('flot', 'jquery.flot.min.js'),
-               os.path.join('WebKit', 'PerformanceTests', 'resources',
-                            'jquery.tablesorter.min.js'),
-               os.path.join('WebKit', 'PerformanceTests', 'resources',
-                            'statistics.js')]
-_UNIT_JSON = os.path.join(
-    util.GetTelemetryDir(), 'telemetry', 'value', 'unit-info.json')
-
-
-def _DatetimeInEs5CompatibleFormat(dt):
-  return dt.strftime('%Y-%m-%dT%H:%M:%S.%f')
-
-
-def _ShortDatetimeInEs5CompatibleFormat(dt):
-  return dt.strftime('%Y-%m-%d %H:%M:%S')
-
-
-class LegacyHtmlOutputFormatter(output_formatter.OutputFormatter):
-  def __init__(self, output_stream, metadata, reset_results, browser_type,
-               results_label=None):
-    super(LegacyHtmlOutputFormatter, self).__init__(output_stream)
-    self._metadata = metadata
-    self._reset_results = reset_results
-    self._build_time = self._GetBuildTime()
-    self._combined_results = []
-    if results_label:
-      self._results_label = results_label
-    else:
-      self._results_label = '%s (%s)' % (
-          metadata.name, _ShortDatetimeInEs5CompatibleFormat(self._build_time))
-    self._result = {
-        'buildTime': _DatetimeInEs5CompatibleFormat(self._build_time),
-        'label': self._results_label,
-        'platform': browser_type,
-        'tests': {}
-        }
-
-  def _GetBuildTime(self):
-    return datetime.datetime.utcnow()
-
-  def _GetHtmlTemplate(self):
-    with open(_TEMPLATE_HTML_PATH) as f:
-      return f.read()
-
-  def _GetPlugins(self):
-    plugins = ''
-    for p in _JS_PLUGINS:
-      with open(os.path.join(util.GetTelemetryThirdPartyDir(), p)) as f:
-        plugins += f.read()
-    return plugins
-
-  def _GetUnitJson(self):
-    with open(_UNIT_JSON) as f:
-      return f.read()
-
-  def _ReadExistingResults(self, output_stream):
-    results_html = output_stream.read()
-    if self._reset_results or not results_html:
-      return []
-    m = re.search(
-        '^<script id="results-json" type="application/json">(.*?)</script>$',
-        results_html, re.MULTILINE | re.DOTALL)
-    if not m:
-      logging.warn('Failed to extract previous results from HTML output')
-      return []
-    return json.loads(m.group(1))[:512]
-
-  def _SaveResults(self, results):
-    self._output_stream.seek(0)
-    self._output_stream.write(unicode(results, 'utf-8'))
-    self._output_stream.truncate()
-
-  def _PrintPerfResult(self, measurement, trace, values, units,
-                       result_type='default', std=None):
-    metric_name = measurement
-    if trace != measurement:
-      metric_name += '.' + trace
-    self._result['tests'].setdefault(self._test_name, {})
-    self._result['tests'][self._test_name].setdefault('metrics', {})
-    metric_data = {
-        'current': values,
-        'units': units,
-        'important': result_type == 'default'
-        }
-    if std is not None:
-      metric_data['std'] = std
-    self._result['tests'][self._test_name]['metrics'][metric_name] = metric_data
-
-  def _TranslateChartJson(self, chart_json_dict):
-    dummy_dict = dict()
-
-    for chart_name, traces in chart_json_dict['charts'].iteritems():
-      for trace_name, value_dict in traces.iteritems():
-        # TODO(eakuefner): refactor summarization so we don't have to jump
-        # through hoops like this.
-        if 'page_id' in value_dict:
-          del value_dict['page_id']
-          result_type = 'nondefault'
-        else:
-          result_type = 'default'
-
-        # Note: we explicitly ignore TraceValues because Buildbot did.
-        if value_dict['type'] == 'trace':
-          continue
-        value = value_module.Value.FromDict(value_dict, dummy_dict)
-
-        perf_value = value.GetBuildbotValue()
-
-        if '@@' in chart_name:
-          chart_name_to_print = '%s-%s' % tuple(chart_name.split('@@'))
-        else:
-          chart_name_to_print = str(chart_name)
-
-        if trace_name == 'summary':
-          trace_name = chart_name_to_print
-
-        std = None
-        if isinstance(value, list_of_scalar_values.ListOfScalarValues):
-          std = value.std
-
-        self._PrintPerfResult(chart_name_to_print, trace_name, perf_value,
-                              value.units, result_type, std)
-
-  @property
-  def _test_name(self):
-    return self._metadata.name
-
-  def GetResults(self):
-    return self._result
-
-  def GetCombinedResults(self):
-    return self._combined_results
-
-  @decorators.Deprecated(
-      2017, 1, 7, 'Use HtmlOutputFormatter and file any issues on GitHub at '
-      'https://github.com/catapult-project/catapult/issues/new?labels=Results2&title=[Results2]')
-  def Format(self, page_test_results):
-    chart_json_dict = chart_json_output_formatter.ResultsAsChartDict(
-        self._metadata, page_test_results.all_page_specific_values,
-        page_test_results.all_summary_values)
-
-    self._TranslateChartJson(chart_json_dict)
-    self._PrintPerfResult('telemetry_page_measurement_results', 'num_failed',
-                          [len(page_test_results.failures)], 'count',
-                          'unimportant')
-
-    self._combined_results = self._ReadExistingResults(self._output_stream)
-    self._combined_results.append(self._result)
-
-    html = self._GetHtmlTemplate()
-    html = html.replace('%json_results%', json.dumps(self.GetCombinedResults()))
-    html = html.replace('%json_units%', self._GetUnitJson())
-    html = html.replace('%plugins%', self._GetPlugins())
-    self._SaveResults(html)
diff --git a/catapult/telemetry/telemetry/internal/results/legacy_html_output_formatter_unittest.py b/catapult/telemetry/telemetry/internal/results/legacy_html_output_formatter_unittest.py
deleted file mode 100644
index 84baebd..0000000
--- a/catapult/telemetry/telemetry/internal/results/legacy_html_output_formatter_unittest.py
+++ /dev/null
@@ -1,265 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import datetime
-import os
-import StringIO
-import unittest
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.internal.results import legacy_html_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-
-
-def _MakeStorySet():
-  story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-  story_set.AddStory(
-      page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-  story_set.AddStory(
-      page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-  return story_set
-
-
-class DeterministicHtmlOutputFormatter(
-    legacy_html_output_formatter.LegacyHtmlOutputFormatter):
-  def _GetBuildTime(self):
-    return datetime.datetime(1998, 9, 4, 13, 0, 0, 7777)
-
-  def _GetRevision(self):
-    return 'revision'
-
-class FakeMetadataForTest(benchmark.BenchmarkMetadata):
-  def __init__(self):
-    super(FakeMetadataForTest, self).__init__('test_name')
-
-# Wrap string IO with a .name property so that it behaves more like a file.
-class StringIOFile(StringIO.StringIO):
-  name = 'fake_output_file'
-
-
-class LegacyHtmlOutputFormatterTest(unittest.TestCase):
-
-  def setUp(self):
-    self.maxDiff = 100000
-
-  def test_basic_summary(self):
-    test_story_set = _MakeStorySet()
-    output_file = StringIOFile()
-
-    # Run the first time and verify the results are written to the HTML file.
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(test_story_set.stories[0])
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.DOWN))
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.WillRunPage(test_story_set.stories[1])
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[1], 'a', 'seconds', 7,
-        improvement_direction=improvement_direction.DOWN))
-    results.DidRunPage(test_story_set.stories[1])
-
-    formatter = DeterministicHtmlOutputFormatter(
-        output_file, FakeMetadataForTest(), False, 'browser_type')
-    formatter.Format(results)
-    expected = {
-      "platform": "browser_type",
-      "buildTime": "1998-09-04T13:00:00.007777",
-      "label": 'test_name (1998-09-04 13:00:00)',
-      "tests": {
-        "test_name": {
-          "metrics": {
-            "a": {
-              "current": [3, 7],
-              "std": 0.0,  # Only one sample per page.
-              "units": "seconds",
-              "important": True
-            },
-            "telemetry_page_measurement_results.num_failed": {
-              "current": [0],
-              "units": "count",
-              "important": False
-            },
-            "a.http://www.bar.com/": {
-              "current": [7],
-              "std": 0.0,
-              "units": "seconds",
-              "important": False
-            },
-            "a.http://www.foo.com/": {
-              "current": [3],
-              "std": 0.0,
-              "units": "seconds",
-              "important": False
-            }
-          }
-        }
-      },
-    }
-    self.assertEquals(expected, formatter.GetResults())
-
-    # Run the second time and verify the results are appended to the HTML file.
-    output_file.seek(0)
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(test_story_set.stories[0])
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[0], 'a', 'seconds', 4,
-        improvement_direction=improvement_direction.DOWN))
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.WillRunPage(test_story_set.stories[1])
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[1], 'a', 'seconds', 8,
-        improvement_direction=improvement_direction.DOWN))
-    results.DidRunPage(test_story_set.stories[1])
-
-    formatter = DeterministicHtmlOutputFormatter(
-        output_file, FakeMetadataForTest(), False, 'browser_type')
-    formatter.Format(results)
-    expected = [
-      {
-        "platform": "browser_type",
-        "buildTime": "1998-09-04T13:00:00.007777",
-        "label": 'test_name (1998-09-04 13:00:00)',
-        "tests": {
-          "test_name": {
-            "metrics": {
-              "a": {
-                "current": [3, 7],
-                "units": "seconds",
-                "std": 0.0,  # Only one sample per page.
-                "important": True
-              },
-              "telemetry_page_measurement_results.num_failed": {
-                "current": [0],
-                "units": "count",
-                "important": False
-              },
-              "a.http://www.bar.com/": {
-                "current": [7],
-                "std": 0.0,
-                "units": "seconds",
-                "important": False
-              },
-              "a.http://www.foo.com/": {
-                "current": [3],
-                "std": 0.0,
-                "units": "seconds",
-                "important": False
-              }
-            }
-          }
-        },
-      },
-      {
-        "platform": "browser_type",
-        "buildTime": "1998-09-04T13:00:00.007777",
-        "label": 'test_name (1998-09-04 13:00:00)',
-        "tests": {
-          "test_name": {
-            "metrics": {
-              "a": {
-                "current": [4, 8],
-                'std': 0.0,  # Only one sample per page.
-                "units": "seconds",
-                "important": True
-              },
-              "telemetry_page_measurement_results.num_failed": {
-                "current": [0],
-                "units": "count",
-                "important": False,
-              },
-              "a.http://www.bar.com/": {
-                "current": [8],
-                "std": 0.0,
-                "units": "seconds",
-                "important": False
-              },
-              "a.http://www.foo.com/": {
-                "current": [4],
-                "std": 0.0,
-                "units": "seconds",
-                "important": False
-              }
-            }
-          }
-        },
-      }]
-    self.assertEquals(expected, formatter.GetCombinedResults())
-    last_output_len = len(output_file.getvalue())
-
-    # Now reset the results and verify the old ones are gone.
-    output_file.seek(0)
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(test_story_set.stories[0])
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[0], 'a', 'seconds', 5,
-        improvement_direction=improvement_direction.DOWN))
-    results.DidRunPage(test_story_set.stories[0])
-
-    results.WillRunPage(test_story_set.stories[1])
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[1], 'a', 'seconds', 9,
-        improvement_direction=improvement_direction.DOWN))
-    results.AddValue(scalar.ScalarValue(
-        test_story_set.stories[1], 'b', 'seconds', 20, tir_label='foo'))
-    results.DidRunPage(test_story_set.stories[1])
-
-    formatter = DeterministicHtmlOutputFormatter(
-       output_file, FakeMetadataForTest(), True, 'browser_type')
-    formatter.Format(results)
-    expected = [{
-      "platform": "browser_type",
-      "buildTime": "1998-09-04T13:00:00.007777",
-      "label": 'test_name (1998-09-04 13:00:00)',
-      "tests": {
-        "test_name": {
-          "metrics": {
-            "a": {
-              "current": [5, 9],
-              'std': 0.0,  # Only one sample per page.
-              "units": "seconds",
-              "important": True
-            },
-            "telemetry_page_measurement_results.num_failed": {
-              "current": [0],
-              "units": "count",
-              "important": False
-            },
-            "a.http://www.bar.com/": {
-              "current": [9],
-              "std": 0.0,
-              "units": "seconds",
-              "important": False
-            },
-            "a.http://www.foo.com/": {
-              "current": [5],
-              "std": 0.0,
-              "units": "seconds",
-              "important": False
-            },
-            "foo-b.http://www.bar.com/": {
-              "current": [20],
-              "std": 0.0,
-              "units": "seconds",
-              "important": False
-            },
-            "foo-b": {
-              "current": [20],
-              "std": 0.0,
-              "units": "seconds",
-              "important": True
-            }
-          }
-        }
-      },
-    }]
-    self.assertEquals(expected, formatter.GetCombinedResults())
-    self.assertTrue(len(output_file.getvalue()) < last_output_len)
diff --git a/catapult/telemetry/telemetry/internal/results/output_formatter.py b/catapult/telemetry/telemetry/internal/results/output_formatter.py
deleted file mode 100644
index ccd49d2..0000000
--- a/catapult/telemetry/telemetry/internal/results/output_formatter.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from telemetry.value import summary as summary_module
-
-class OutputFormatter(object):
-  """A formatter for PageTestResults.
-
-  An OutputFormatter takes PageTestResults, formats the results
-  (telemetry.value.Value instances), and output the formatted results
-  in the given output stream.
-
-  Examples of output formatter: CsvOutputFormatter produces results in
-  CSV format."""
-
-  def __init__(self, output_stream):
-    """Constructs a new formatter that writes to the output_stream.
-
-    Args:
-      output_stream: The stream to write the formatted output to.
-    """
-    self._output_stream = output_stream
-
-  def Format(self, page_test_results):
-    """Formats the given PageTestResults into the output stream.
-
-    This will be called once at the end of a benchmark.
-
-    Args:
-      page_test_results: A PageTestResults object containing all results
-         from the current benchmark run.
-    """
-    raise NotImplementedError()
-
-  def PrintViewResults(self):
-    print 'View result at file://' + os.path.abspath(self.output_stream.name)
-
-  def FormatDisabled(self):
-    """Formats disabled results into the output stream.
-
-    This will be called once when a benchmark is run but disabled.
-    """
-    pass
-
-  @property
-  def output_stream(self):
-    return self._output_stream
-
-
-def SummarizePageSpecificValues(page_specific_values):
-  """Summarize results appropriately for TBM and legacy benchmarks.
-
-  For benchmarks that are timeline-based, we need to summarize not once, but
-  twice, once by name and tir_label (default) and again by name only. But for
-  benchmarks that are not timeline-based, since no tir_labels are set, we will
-  end up duplicating values.
-
-  Thus, we only want to summarize once if the benchmark is not timeline-based,
-  but twice, using the two different key functions, otherwise.
-  """
-  # Default summary uses merge_values.DefaultKeyFunc to summarize both by name
-  # and tir_label.
-  summary = summary_module.Summary(page_specific_values)
-  values = summary.interleaved_computed_per_page_values_and_summaries
-
-  if any(v.tir_label for v in page_specific_values):
-    summary_by_name_only = summary_module.Summary(
-        page_specific_values,
-        key_func=lambda v: v.name)
-    values.extend(
-        summary_by_name_only.interleaved_computed_per_page_values_and_summaries
-    )
-  return values
diff --git a/catapult/telemetry/telemetry/internal/results/page_test_results.py b/catapult/telemetry/telemetry/internal/results/page_test_results.py
deleted file mode 100644
index 05c27e6..0000000
--- a/catapult/telemetry/telemetry/internal/results/page_test_results.py
+++ /dev/null
@@ -1,416 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import copy
-import datetime
-import json
-import logging
-import os
-import random
-import sys
-import tempfile
-import traceback
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry import value as value_module
-from telemetry.internal.results import chart_json_output_formatter
-from telemetry.internal.results import json_output_formatter
-from telemetry.internal.results import progress_reporter as reporter_module
-from telemetry.internal.results import story_run
-from telemetry.value import failure
-from telemetry.value import skip
-from telemetry.value import trace
-
-from tracing.value import convert_chart_json
-
-class TelemetryInfo(object):
-  def __init__(self):
-    self._benchmark_name = None
-    self._benchmark_start_ms = None
-    self._label = None
-    self._story_display_name = ''
-    self._story_grouping_keys = {}
-    self._storyset_repeat_counter = 0
-
-  @property
-  def benchmark_name(self):
-    return self._benchmark_name
-
-  @benchmark_name.setter
-  def benchmark_name(self, benchmark_name):
-    assert self.benchmark_name is None, (
-      'benchmark_name must be set exactly once')
-    self._benchmark_name = benchmark_name
-
-  @property
-  def benchmark_start_ms(self):
-    return self._benchmark_start_ms
-
-  @benchmark_start_ms.setter
-  def benchmark_start_ms(self, benchmark_start_ms):
-    assert self.benchmark_start_ms is None, (
-      'benchmark_start_ms must be set exactly once')
-    self._benchmark_start_ms = benchmark_start_ms
-
-  @property
-  def label(self):
-    return self._label
-
-  @label.setter
-  def label(self, label):
-    assert self.label is None, 'label cannot be set more than once'
-    self._label = label
-
-  @property
-  def story_display_name(self):
-    return self._story_display_name
-
-  @property
-  def story_grouping_keys(self):
-    return self._story_grouping_keys
-
-  @property
-  def storyset_repeat_counter(self):
-    return self._storyset_repeat_counter
-
-  def WillRunStory(self, story, storyset_repeat_counter):
-    self._story_display_name = story.display_name
-    if story.grouping_keys:
-      self._story_grouping_keys = story.grouping_keys
-    self._storyset_repeat_counter = storyset_repeat_counter
-
-  def AsDict(self):
-    assert self.benchmark_name is not None, (
-        'benchmark_name must be set exactly once')
-    assert self.benchmark_start_ms is not None, (
-        'benchmark_start_ms must be set exactly once')
-    d = {}
-    d['benchmarkName'] = self.benchmark_name
-    d['benchmarkStartMs'] = self.benchmark_start_ms
-    if self.label:
-      d['label'] = self.label
-    d['storyDisplayName'] = self.story_display_name
-    d['storyGroupingKeys'] = self.story_grouping_keys
-    d['storysetRepeatCounter'] = self.storyset_repeat_counter
-    return d
-
-
-class PageTestResults(object):
-  def __init__(self, output_formatters=None,
-               progress_reporter=None, trace_tag='', output_dir=None,
-               value_can_be_added_predicate=lambda v, is_first: True,
-               benchmark_enabled=True):
-    """
-    Args:
-      output_formatters: A list of output formatters. The output
-          formatters are typically used to format the test results, such
-          as CsvPivotTableOutputFormatter, which output the test results as CSV.
-      progress_reporter: An instance of progress_reporter.ProgressReporter,
-          to be used to output test status/results progressively.
-      trace_tag: A string to append to the buildbot trace name. Currently only
-          used for buildbot.
-      output_dir: A string specified the directory where to store the test
-          artifacts, e.g: trace, videos,...
-      value_can_be_added_predicate: A function that takes two arguments:
-          a value.Value instance (except failure.FailureValue, skip.SkipValue
-          or trace.TraceValue) and a boolean (True when the value is part of
-          the first result for the story). It returns True if the value
-          can be added to the test results and False otherwise.
-    """
-    # TODO(chrishenry): Figure out if trace_tag is still necessary.
-
-    super(PageTestResults, self).__init__()
-    self._progress_reporter = (
-        progress_reporter if progress_reporter is not None
-        else reporter_module.ProgressReporter())
-    self._output_formatters = (
-        output_formatters if output_formatters is not None else [])
-    self._trace_tag = trace_tag
-    self._output_dir = output_dir
-    self._value_can_be_added_predicate = value_can_be_added_predicate
-
-    self._current_page_run = None
-    self._all_page_runs = []
-    self._all_stories = set()
-    self._representative_value_for_each_value_name = {}
-    self._all_summary_values = []
-    self._serialized_trace_file_ids_to_paths = {}
-    self._pages_to_profiling_files = collections.defaultdict(list)
-    self._pages_to_profiling_files_cloud_url = collections.defaultdict(list)
-
-    # You'd expect this to be a set(), but Values are dictionaries, which are
-    # unhashable. We could wrap Values with custom __eq/hash__, but we don't
-    # actually need set-ness in python.
-    self._value_set = []
-
-    self._telemetry_info = TelemetryInfo()
-
-    # State of the benchmark this set of results represents.
-    self._benchmark_enabled = benchmark_enabled
-
-  @property
-  def telemetry_info(self):
-    return self._telemetry_info
-
-  @property
-  def value_set(self):
-    return self._value_set
-
-  def AsHistogramDicts(self, benchmark_metadata):
-    if self.value_set:
-      return self.value_set
-    chart_json = chart_json_output_formatter.ResultsAsChartDict(
-        benchmark_metadata, self.all_page_specific_values,
-        self.all_summary_values)
-    info = self.telemetry_info
-    chart_json['label'] = info.label
-    chart_json['benchmarkStartMs'] = info.benchmark_start_ms
-
-    file_descriptor, chart_json_path = tempfile.mkstemp()
-    os.close(file_descriptor)
-    json.dump(chart_json, file(chart_json_path, 'w'))
-
-    vinn_result = convert_chart_json.ConvertChartJson(chart_json_path)
-
-    os.remove(chart_json_path)
-
-    if vinn_result.returncode != 0:
-      logging.error('Error converting chart json to Histograms:\n' +
-          vinn_result.stdout)
-      return []
-    return json.loads(vinn_result.stdout)
-
-  def __copy__(self):
-    cls = self.__class__
-    result = cls.__new__(cls)
-    for k, v in self.__dict__.items():
-      if isinstance(v, collections.Container):
-        v = copy.copy(v)
-      setattr(result, k, v)
-    return result
-
-  @property
-  def pages_to_profiling_files(self):
-    return self._pages_to_profiling_files
-
-  @property
-  def serialized_trace_file_ids_to_paths(self):
-    return self._serialized_trace_file_ids_to_paths
-
-  @property
-  def pages_to_profiling_files_cloud_url(self):
-    return self._pages_to_profiling_files_cloud_url
-
-  @property
-  def all_page_specific_values(self):
-    values = []
-    for run in self._all_page_runs:
-      values += run.values
-    if self._current_page_run:
-      values += self._current_page_run.values
-    return values
-
-  @property
-  def all_summary_values(self):
-    return self._all_summary_values
-
-  @property
-  def current_page(self):
-    assert self._current_page_run, 'Not currently running test.'
-    return self._current_page_run.story
-
-  @property
-  def current_page_run(self):
-    assert self._current_page_run, 'Not currently running test.'
-    return self._current_page_run
-
-  @property
-  def all_page_runs(self):
-    return self._all_page_runs
-
-  @property
-  def pages_that_succeeded(self):
-    """Returns the set of pages that succeeded."""
-    pages = set(run.story for run in self.all_page_runs)
-    pages.difference_update(self.pages_that_failed)
-    return pages
-
-  @property
-  def pages_that_failed(self):
-    """Returns the set of failed pages."""
-    failed_pages = set()
-    for run in self.all_page_runs:
-      if run.failed:
-        failed_pages.add(run.story)
-    return failed_pages
-
-  @property
-  def failures(self):
-    values = self.all_page_specific_values
-    return [v for v in values if isinstance(v, failure.FailureValue)]
-
-  @property
-  def skipped_values(self):
-    values = self.all_page_specific_values
-    return [v for v in values if isinstance(v, skip.SkipValue)]
-
-  def _GetStringFromExcInfo(self, err):
-    return ''.join(traceback.format_exception(*err))
-
-  def CleanUp(self):
-    """Clean up any TraceValues contained within this results object."""
-    for run in self._all_page_runs:
-      for v in run.values:
-        if isinstance(v, trace.TraceValue):
-          v.CleanUp()
-          run.values.remove(v)
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, _, __, ___):
-    self.CleanUp()
-
-  def WillRunPage(self, page, storyset_repeat_counter=0):
-    assert not self._current_page_run, 'Did not call DidRunPage.'
-    self._current_page_run = story_run.StoryRun(page)
-    self._progress_reporter.WillRunPage(self)
-    self.telemetry_info.WillRunStory(
-        page, storyset_repeat_counter)
-
-  def DidRunPage(self, page):  # pylint: disable=unused-argument
-    """
-    Args:
-      page: The current page under test.
-    """
-    assert self._current_page_run, 'Did not call WillRunPage.'
-    self._progress_reporter.DidRunPage(self)
-    self._all_page_runs.append(self._current_page_run)
-    self._all_stories.add(self._current_page_run.story)
-    self._current_page_run = None
-
-  def AddValue(self, value):
-    assert self._current_page_run, 'Not currently running test.'
-    assert self._benchmark_enabled, 'Cannot add value to disabled results'
-    self._ValidateValue(value)
-    is_first_result = (
-      self._current_page_run.story not in self._all_stories)
-
-    story_keys = self._current_page_run.story.grouping_keys
-
-    if story_keys:
-      for k, v in story_keys.iteritems():
-        assert k not in value.grouping_keys, (
-            'Tried to add story grouping key ' + k + ' already defined by ' +
-            'value')
-        value.grouping_keys[k] = v
-
-      # We sort by key name to make building the tir_label deterministic.
-      story_keys_label = '_'.join(v for _, v in sorted(story_keys.iteritems()))
-      if value.tir_label:
-        assert value.tir_label == story_keys_label, (
-            'Value has an explicit tir_label (%s) that does not match the '
-            'one computed from story_keys (%s)' % (value.tir_label, story_keys))
-      else:
-        value.tir_label = story_keys_label
-
-    if not (isinstance(value, skip.SkipValue) or
-            isinstance(value, failure.FailureValue) or
-            isinstance(value, trace.TraceValue) or
-            self._value_can_be_added_predicate(value, is_first_result)):
-      return
-    # TODO(eakuefner/chrishenry): Add only one skip per pagerun assert here
-    self._current_page_run.AddValue(value)
-    self._progress_reporter.DidAddValue(value)
-
-  def AddProfilingFile(self, page, file_handle):
-    self._pages_to_profiling_files[page].append(file_handle)
-
-  def AddSummaryValue(self, value):
-    assert value.page is None
-    self._ValidateValue(value)
-    self._all_summary_values.append(value)
-
-  def _ValidateValue(self, value):
-    assert isinstance(value, value_module.Value)
-    if value.name not in self._representative_value_for_each_value_name:
-      self._representative_value_for_each_value_name[value.name] = value
-    representative_value = self._representative_value_for_each_value_name[
-        value.name]
-    assert value.IsMergableWith(representative_value)
-
-  def PrintSummary(self):
-    if self._benchmark_enabled:
-      self._progress_reporter.DidFinishAllTests(self)
-
-      # Only serialize the trace if output_format is json.
-      if (self._output_dir and
-          any(isinstance(o, json_output_formatter.JsonOutputFormatter)
-              for o in self._output_formatters)):
-        self._SerializeTracesToDirPath(self._output_dir)
-      for output_formatter in self._output_formatters:
-        output_formatter.Format(self)
-        output_formatter.PrintViewResults()
-    else:
-      for output_formatter in self._output_formatters:
-        output_formatter.FormatDisabled()
-
-  def FindValues(self, predicate):
-    """Finds all values matching the specified predicate.
-
-    Args:
-      predicate: A function that takes a Value and returns a bool.
-    Returns:
-      A list of values matching |predicate|.
-    """
-    values = []
-    for value in self.all_page_specific_values:
-      if predicate(value):
-        values.append(value)
-    return values
-
-  def FindPageSpecificValuesForPage(self, page, value_name):
-    return self.FindValues(lambda v: v.page == page and v.name == value_name)
-
-  def FindAllPageSpecificValuesNamed(self, value_name):
-    return self.FindValues(lambda v: v.name == value_name)
-
-  def FindAllPageSpecificValuesFromIRNamed(self, tir_label, value_name):
-    return self.FindValues(lambda v: v.name == value_name
-                           and v.tir_label == tir_label)
-
-  def FindAllTraceValues(self):
-    return self.FindValues(lambda v: isinstance(v, trace.TraceValue))
-
-  def _SerializeTracesToDirPath(self, dir_path):
-    """ Serialize all trace values to files in dir_path and return a list of
-    file handles to those files. """
-    for value in self.FindAllTraceValues():
-      fh = value.Serialize(dir_path)
-      self._serialized_trace_file_ids_to_paths[fh.id] = fh.GetAbsPath()
-
-  def UploadTraceFilesToCloud(self, bucket):
-    for value in self.FindAllTraceValues():
-      value.UploadToCloud(bucket)
-
-  def UploadProfilingFilesToCloud(self, bucket):
-    for page, file_handle_list in self._pages_to_profiling_files.iteritems():
-      for file_handle in file_handle_list:
-        remote_path = ('profiler-file-id_%s-%s%-d%s' % (
-            file_handle.id,
-            datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'),
-            random.randint(1, 100000),
-            file_handle.extension))
-        try:
-          cloud_url = cloud_storage.Insert(
-              bucket, remote_path, file_handle.GetAbsPath())
-          sys.stderr.write(
-              'View generated profiler files online at %s for page %s\n' %
-              (cloud_url, page.display_name))
-          self._pages_to_profiling_files_cloud_url[page].append(cloud_url)
-        except cloud_storage.PermissionError as e:
-          logging.error('Cannot upload profiling files to cloud storage due to '
-                        ' permission error: %s' % e.message)
diff --git a/catapult/telemetry/telemetry/internal/results/page_test_results_unittest.py b/catapult/telemetry/telemetry/internal/results/page_test_results_unittest.py
deleted file mode 100644
index c4eb8ba..0000000
--- a/catapult/telemetry/telemetry/internal/results/page_test_results_unittest.py
+++ /dev/null
@@ -1,512 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.internal.results import base_test_results_unittest
-from telemetry.internal.results import chart_json_output_formatter
-from telemetry.internal.results import json_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.testing import stream
-from telemetry.value import failure
-from telemetry.value import histogram
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.value import skip
-from telemetry.value import trace
-from tracing.trace_data import trace_data
-
-
-class PageTestResultsTest(base_test_results_unittest.BaseTestResultsUnittest):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(page_module.Page("http://www.bar.com/", story_set, story_set.base_dir))
-    story_set.AddStory(page_module.Page("http://www.baz.com/", story_set, story_set.base_dir))
-    story_set.AddStory(page_module.Page("http://www.foo.com/", story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-  def testFailures(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(
-        failure.FailureValue(self.pages[0], self.CreateException()))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.DidRunPage(self.pages[1])
-
-    self.assertEqual(set([self.pages[0]]), results.pages_that_failed)
-    self.assertEqual(set([self.pages[1]]), results.pages_that_succeeded)
-
-    self.assertEqual(2, len(results.all_page_runs))
-    self.assertTrue(results.all_page_runs[0].failed)
-    self.assertTrue(results.all_page_runs[1].ok)
-
-  def testSkips(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(skip.SkipValue(self.pages[0], 'testing reason'))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.DidRunPage(self.pages[1])
-
-    self.assertTrue(results.all_page_runs[0].skipped)
-    self.assertEqual(self.pages[0], results.all_page_runs[0].story)
-    self.assertEqual(set([self.pages[0], self.pages[1]]),
-                     results.pages_that_succeeded)
-
-    self.assertEqual(2, len(results.all_page_runs))
-    self.assertTrue(results.all_page_runs[0].skipped)
-    self.assertTrue(results.all_page_runs[1].ok)
-
-  def testBasic(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[1])
-
-    results.PrintSummary()
-
-    values = results.FindPageSpecificValuesForPage(self.pages[0], 'a')
-    self.assertEquals(1, len(values))
-    v = values[0]
-    self.assertEquals(v.name, 'a')
-    self.assertEquals(v.page, self.pages[0])
-
-    values = results.FindAllPageSpecificValuesNamed('a')
-    assert len(values) == 2
-
-  def testAddValueWithStoryGroupingKeys(self):
-    results = page_test_results.PageTestResults()
-    self.pages[0].grouping_keys['foo'] = 'bar'
-    self.pages[0].grouping_keys['answer'] = '42'
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-
-    results.PrintSummary()
-
-    values = results.FindPageSpecificValuesForPage(self.pages[0], 'a')
-    v = values[0]
-    self.assertEquals(v.grouping_keys['foo'], 'bar')
-    self.assertEquals(v.grouping_keys['answer'], '42')
-    self.assertEquals(v.tir_label, '42_bar')
-
-  def testAddValueWithStoryGroupingKeysAndMatchingTirLabel(self):
-    results = page_test_results.PageTestResults()
-    self.pages[0].grouping_keys['foo'] = 'bar'
-    self.pages[0].grouping_keys['answer'] = '42'
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP,
-        tir_label='42_bar'))
-    results.DidRunPage(self.pages[0])
-
-    results.PrintSummary()
-
-    values = results.FindPageSpecificValuesForPage(self.pages[0], 'a')
-    v = values[0]
-    self.assertEquals(v.grouping_keys['foo'], 'bar')
-    self.assertEquals(v.grouping_keys['answer'], '42')
-    self.assertEquals(v.tir_label, '42_bar')
-
-  def testAddValueWithStoryGroupingKeysAndMismatchingTirLabel(self):
-    results = page_test_results.PageTestResults()
-    self.pages[0].grouping_keys['foo'] = 'bar'
-    self.pages[0].grouping_keys['answer'] = '42'
-    results.WillRunPage(self.pages[0])
-    with self.assertRaises(AssertionError):
-      results.AddValue(scalar.ScalarValue(
-          self.pages[0], 'a', 'seconds', 3,
-          improvement_direction=improvement_direction.UP,
-          tir_label='another_label'))
-
-  def testAddValueWithDuplicateStoryGroupingKeyFails(self):
-    results = page_test_results.PageTestResults()
-    self.pages[0].grouping_keys['foo'] = 'bar'
-    results.WillRunPage(self.pages[0])
-    with self.assertRaises(AssertionError):
-      results.AddValue(scalar.ScalarValue(
-          self.pages[0], 'a', 'seconds', 3,
-          improvement_direction=improvement_direction.UP,
-          grouping_keys={'foo': 'bar'}))
-
-  def testUrlIsInvalidValue(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    self.assertRaises(
-      AssertionError,
-      lambda: results.AddValue(scalar.ScalarValue(
-          self.pages[0], 'url', 'string', 'foo',
-          improvement_direction=improvement_direction.UP)))
-
-  def testAddSummaryValueWithPageSpecified(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    self.assertRaises(
-      AssertionError,
-      lambda: results.AddSummaryValue(scalar.ScalarValue(
-          self.pages[0], 'a', 'units', 3,
-          improvement_direction=improvement_direction.UP)))
-
-  def testUnitChange(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    self.assertRaises(
-      AssertionError,
-      lambda: results.AddValue(scalar.ScalarValue(
-          self.pages[1], 'a', 'foobgrobbers', 3,
-          improvement_direction=improvement_direction.UP)))
-
-  def testTypeChange(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    self.assertRaises(
-      AssertionError,
-      lambda: results.AddValue(histogram.HistogramValue(
-          self.pages[1], 'a', 'seconds',
-          raw_value_json='{"buckets": [{"low": 1, "high": 2, "count": 1}]}',
-          improvement_direction=improvement_direction.UP)))
-
-  def testGetPagesThatSucceededAllPagesFail(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(failure.FailureValue.FromMessage(self.pages[0], 'message'))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'a', 'seconds', 7,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(failure.FailureValue.FromMessage(self.pages[1], 'message'))
-    results.DidRunPage(self.pages[1])
-
-    results.PrintSummary()
-    self.assertEquals(0, len(results.pages_that_succeeded))
-
-  def testGetSuccessfulPageValuesMergedNoFailures(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    self.assertEquals(1, len(results.all_page_specific_values))
-    results.DidRunPage(self.pages[0])
-
-  def testGetAllValuesForSuccessfulPages(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    value1 = scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(value1)
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    value2 = scalar.ScalarValue(
-        self.pages[1], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(value2)
-    results.DidRunPage(self.pages[1])
-
-    results.WillRunPage(self.pages[2])
-    value3 = scalar.ScalarValue(
-        self.pages[2], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(value3)
-    results.DidRunPage(self.pages[2])
-
-    self.assertEquals(
-        [value1, value2, value3], results.all_page_specific_values)
-
-  def testGetAllValuesForSuccessfulPagesOnePageFails(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    value1 = scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(value1)
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    value2 = failure.FailureValue.FromMessage(self.pages[1], 'Failure')
-    results.AddValue(value2)
-    results.DidRunPage(self.pages[1])
-
-    results.WillRunPage(self.pages[2])
-    value3 = scalar.ScalarValue(
-        self.pages[2], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(value3)
-    results.DidRunPage(self.pages[2])
-
-    self.assertEquals(
-        [value1, value2, value3], results.all_page_specific_values)
-
-  def testFindValues(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    v0 = scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    v1 = scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 4,
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(self.pages[1])
-
-    values = results.FindValues(lambda v: v.value == 3)
-    self.assertEquals([v0], values)
-
-  def testValueWithTIRLabel(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    v0 = scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3, tir_label='foo',
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    v1 = scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3, tir_label='bar',
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(self.pages[0])
-
-    values = results.FindAllPageSpecificValuesFromIRNamed('foo', 'a')
-    self.assertEquals([v0], values)
-
-  def testTraceValue(self):
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.pages[0])
-    results.AddValue(trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData([[{'test': 1}]])))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.AddValue(trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData([[{'test': 2}]])))
-    results.DidRunPage(self.pages[1])
-
-    results.PrintSummary()
-
-    values = results.FindAllTraceValues()
-    self.assertEquals(2, len(values))
-
-  def testCleanUpCleansUpTraceValues(self):
-    results = page_test_results.PageTestResults()
-    v0 = trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-    v1 = trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData([{'test': 2}]))
-
-    results.WillRunPage(self.pages[0])
-    results.AddValue(v0)
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.AddValue(v1)
-    results.DidRunPage(self.pages[1])
-
-    results.CleanUp()
-    self.assertTrue(v0.cleaned_up)
-    self.assertTrue(v1.cleaned_up)
-
-  def testNoTracesLeftAfterCleanUp(self):
-    results = page_test_results.PageTestResults()
-    v0 = trace.TraceValue(None,
-                          trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-    v1 = trace.TraceValue(None,
-                          trace_data.CreateTraceDataFromRawData([{'test': 2}]))
-
-    results.WillRunPage(self.pages[0])
-    results.AddValue(v0)
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.AddValue(v1)
-    results.DidRunPage(self.pages[1])
-
-    results.CleanUp()
-    self.assertFalse(results.FindAllTraceValues())
-
-  def testPrintSummaryDisabledResults(self):
-    output_stream = stream.TestOutputStream()
-    output_formatters = []
-    benchmark_metadata = benchmark.BenchmarkMetadata(
-      'benchmark_name', 'benchmark_description')
-    output_formatters.append(
-        chart_json_output_formatter.ChartJsonOutputFormatter(
-            output_stream, benchmark_metadata))
-    output_formatters.append(json_output_formatter.JsonOutputFormatter(
-        output_stream, benchmark_metadata))
-    results = page_test_results.PageTestResults(
-        output_formatters=output_formatters, benchmark_enabled=False)
-    results.PrintSummary()
-    self.assertEquals(output_stream.output_data,
-      "{\n  \"enabled\": false,\n  \"benchmark_name\": \"benchmark_name\"\n}\n")
-
-
-class PageTestResultsFilterTest(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-  def testFilterValue(self):
-    def AcceptValueNamed_a(value, _):
-      return value.name == 'a'
-    results = page_test_results.PageTestResults(
-        value_can_be_added_predicate=AcceptValueNamed_a)
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'b', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-
-    results.WillRunPage(self.pages[1])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'd', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[1])
-    results.PrintSummary()
-    self.assertEquals(
-        [('a', 'http://www.foo.com/'), ('a', 'http://www.bar.com/')],
-        [(v.name, v.page.url) for v in results.all_page_specific_values])
-
-  def testFilterIsFirstResult(self):
-    def AcceptSecondValues(_, is_first_result):
-      return not is_first_result
-    results = page_test_results.PageTestResults(
-        value_can_be_added_predicate=AcceptSecondValues)
-
-    # First results (filtered out)
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 7,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'b', 'seconds', 8,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-    results.WillRunPage(self.pages[1])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'a', 'seconds', 5,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'd', 'seconds', 6,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[1])
-
-    # Second results
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'a', 'seconds', 3,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'b', 'seconds', 4,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[0])
-    results.WillRunPage(self.pages[1])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'a', 'seconds', 1,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(scalar.ScalarValue(
-        self.pages[1], 'd', 'seconds', 2,
-        improvement_direction=improvement_direction.UP))
-    results.DidRunPage(self.pages[1])
-    results.PrintSummary()
-    expected_values = [
-        ('a', 'http://www.foo.com/', 3),
-        ('b', 'http://www.foo.com/', 4),
-        ('a', 'http://www.bar.com/', 1),
-        ('d', 'http://www.bar.com/', 2)]
-    actual_values = [(v.name, v.page.url, v.value)
-                     for v in results.all_page_specific_values]
-    self.assertEquals(expected_values, actual_values)
-
-  def testFailureValueCannotBeFiltered(self):
-    def AcceptValueNamed_a(value, _):
-      return value.name == 'a'
-    results = page_test_results.PageTestResults(
-        value_can_be_added_predicate=AcceptValueNamed_a)
-    results.WillRunPage(self.pages[0])
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'b', 'seconds', 8,
-        improvement_direction=improvement_direction.UP))
-    failure_value = failure.FailureValue.FromMessage(self.pages[0], 'failure')
-    results.AddValue(failure_value)
-    results.DidRunPage(self.pages[0])
-    results.PrintSummary()
-
-    # Although predicate says only accept values named 'a', the failure value is
-    # added anyway.
-    self.assertEquals(len(results.all_page_specific_values), 1)
-    self.assertIn(failure_value, results.all_page_specific_values)
-
-  def testSkipValueCannotBeFiltered(self):
-    def AcceptValueNamed_a(value, _):
-      return value.name == 'a'
-    results = page_test_results.PageTestResults(
-        value_can_be_added_predicate=AcceptValueNamed_a)
-    results.WillRunPage(self.pages[0])
-    skip_value = skip.SkipValue(self.pages[0], 'skip for testing')
-    results.AddValue(scalar.ScalarValue(
-        self.pages[0], 'b', 'seconds', 8,
-        improvement_direction=improvement_direction.UP))
-    results.AddValue(skip_value)
-    results.DidRunPage(self.pages[0])
-    results.PrintSummary()
-
-    # Although predicate says only accept value with named 'a', skip value is
-    # added anyway.
-    self.assertEquals(len(results.all_page_specific_values), 1)
-    self.assertIn(skip_value, results.all_page_specific_values)
diff --git a/catapult/telemetry/telemetry/internal/results/progress_reporter.py b/catapult/telemetry/telemetry/internal/results/progress_reporter.py
deleted file mode 100644
index 3eea999..0000000
--- a/catapult/telemetry/telemetry/internal/results/progress_reporter.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class ProgressReporter(object):
-  """A class that reports progress of a benchmark.
-
-  The reporter produces output whenever a significant event happens
-  during the progress of a benchmark, including (but not limited to):
-  when a page run is started, when a page run finished, any failures
-  during a page run.
-
-  The default implementation outputs nothing.
-  """
-
-  def DidAddValue(self, value):
-    pass
-
-  def WillRunPage(self, page_test_results):
-    pass
-
-  def DidRunPage(self, page_test_results):
-    pass
-
-  def DidFinishAllTests(self, page_test_results):
-    pass
diff --git a/catapult/telemetry/telemetry/internal/results/results_options.py b/catapult/telemetry/telemetry/internal/results/results_options.py
deleted file mode 100644
index 357ec30..0000000
--- a/catapult/telemetry/telemetry/internal/results/results_options.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import codecs
-import optparse
-import os
-import sys
-import time
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.core import util
-from telemetry.internal.results import chart_json_output_formatter
-from telemetry.internal.results import csv_pivot_table_output_formatter
-from telemetry.internal.results import gtest_progress_reporter
-from telemetry.internal.results import histogram_set_json_output_formatter
-from telemetry.internal.results import html_output_formatter
-from telemetry.internal.results import json_output_formatter
-from telemetry.internal.results import legacy_html_output_formatter
-from telemetry.internal.results import page_test_results
-from telemetry.internal.results import progress_reporter
-
-# Allowed output formats. The default is the first item in the list.
-
-_OUTPUT_FORMAT_CHOICES = ('html', 'gtest', 'json', 'chartjson',
-    'csv-pivot-table', 'histograms', 'legacy-html', 'none')
-
-
-# Filenames to use for given output formats.
-_OUTPUT_FILENAME_LOOKUP = {
-    'html': 'results.html',
-    'json': 'results.json',
-    'chartjson': 'results-chart.json',
-    'csv-pivot-table': 'results-pivot-table.csv',
-    'histograms': 'histograms.json',
-    'legacy-html': 'legacy-results.html'
-}
-
-
-def AddResultsOptions(parser):
-  group = optparse.OptionGroup(parser, 'Results options')
-  group.add_option('--output-format', action='append', dest='output_formats',
-                    choices=_OUTPUT_FORMAT_CHOICES, default=[],
-                    help='Output format. Defaults to "%%default". '
-                    'Can be %s.' % ', '.join(_OUTPUT_FORMAT_CHOICES))
-  group.add_option('-o', '--output',
-                    dest='output_file',
-                    default=None,
-                    help='Redirects output to a file. Defaults to stdout.')
-  group.add_option('--output-dir', default=util.GetBaseDir(),
-                    help='Where to save output data after the run.')
-  group.add_option('--output-trace-tag',
-                    default='',
-                    help='Append a tag to the key of each result trace. Use '
-                    'with html, csv-pivot-table output formats.')
-  group.add_option('--reset-results', action='store_true',
-                    help='Delete all stored results.')
-  group.add_option('--upload-results', action='store_true',
-                    help='Upload the results to cloud storage.')
-  group.add_option('--upload-bucket', default='output',
-                    help='Storage bucket to use for the uploaded results. ' +
-                    'Defaults to output bucket. Supported values are: ' +
-                    ', '.join(cloud_storage.BUCKET_ALIAS_NAMES) +
-                    '; or a valid cloud storage bucket name.')
-  group.add_option('--results-label',
-                    default=None,
-                    help='Optional label to use for the results of a run .')
-  group.add_option('--suppress_gtest_report',
-                   default=False,
-                   help='Whether to suppress GTest progress report.')
-  parser.add_option_group(group)
-
-
-def ProcessCommandLineArgs(parser, args):
-  # TODO(ariblue): Delete this flag entirely at some future data, when the
-  # existence of such a flag has been long forgotten.
-  if args.output_file:
-    parser.error('This flag is deprecated. Please use --output-dir instead.')
-
-  try:
-    os.makedirs(args.output_dir)
-  except OSError:
-    # Do nothing if the output directory already exists. Existing files will
-    # get overwritten.
-    pass
-
-  args.output_dir = os.path.expanduser(args.output_dir)
-
-
-def _GetOutputStream(output_format, output_dir):
-  assert output_format in _OUTPUT_FORMAT_CHOICES, 'Must specify a valid format.'
-  assert output_format not in ('gtest', 'none'), (
-      'Cannot set stream for \'gtest\' or \'none\' output formats.')
-
-  assert output_format in _OUTPUT_FILENAME_LOOKUP, (
-      'No known filename for the \'%s\' output format' % output_format)
-  output_file = os.path.join(output_dir, _OUTPUT_FILENAME_LOOKUP[output_format])
-
-  # TODO(eakuefner): Factor this hack out after we rewrite HTMLOutputFormatter.
-  if output_format == 'html' or output_format == 'legacy-html':
-    open(output_file, 'a').close() # Create file if it doesn't exist.
-    return codecs.open(output_file, mode='r+', encoding='utf-8')
-  else:
-    return open(output_file, mode='w+')
-
-
-def _GetProgressReporter(output_skipped_tests_summary, suppress_gtest_report):
-  if suppress_gtest_report:
-    return progress_reporter.ProgressReporter()
-
-  return gtest_progress_reporter.GTestProgressReporter(
-      sys.stdout, output_skipped_tests_summary=output_skipped_tests_summary)
-
-
-def CreateResults(benchmark_metadata, options,
-                  value_can_be_added_predicate=lambda v, is_first: True,
-                  benchmark_enabled=True):
-  """
-  Args:
-    options: Contains the options specified in AddResultsOptions.
-  """
-  if not options.output_formats:
-    options.output_formats = [_OUTPUT_FORMAT_CHOICES[0]]
-
-  upload_bucket = None
-  if options.upload_results:
-    upload_bucket = options.upload_bucket
-    if upload_bucket in cloud_storage.BUCKET_ALIASES:
-      upload_bucket = cloud_storage.BUCKET_ALIASES[upload_bucket]
-
-  output_formatters = []
-  for output_format in options.output_formats:
-    if output_format == 'none' or output_format == "gtest":
-      continue
-
-    output_stream = _GetOutputStream(output_format, options.output_dir)
-    if output_format == 'csv-pivot-table':
-      output_formatters.append(
-          csv_pivot_table_output_formatter.CsvPivotTableOutputFormatter(
-              output_stream, trace_tag=options.output_trace_tag))
-    elif output_format == 'html':
-      output_formatters.append(html_output_formatter.HtmlOutputFormatter(
-          output_stream, benchmark_metadata, options.reset_results,
-          upload_bucket))
-    elif output_format == 'json':
-      output_formatters.append(json_output_formatter.JsonOutputFormatter(
-          output_stream, benchmark_metadata))
-    elif output_format == 'chartjson':
-      output_formatters.append(
-          chart_json_output_formatter.ChartJsonOutputFormatter(
-              output_stream, benchmark_metadata))
-    elif output_format == 'histograms':
-      output_formatters.append(
-          histogram_set_json_output_formatter.HistogramSetJsonOutputFormatter(
-              output_stream, benchmark_metadata, options.reset_results))
-    elif output_format == 'legacy-html':
-      output_formatters.append(
-          legacy_html_output_formatter.LegacyHtmlOutputFormatter(
-              output_stream, benchmark_metadata, options.reset_results,
-              options.browser_type, options.results_label))
-    else:
-      # Should never be reached. The parser enforces the choices.
-      raise Exception('Invalid --output-format "%s". Valid choices are: %s'
-                      % (output_format, ', '.join(_OUTPUT_FORMAT_CHOICES)))
-
-  # TODO(chrishenry): This is here to not change the output of
-  # gtest. Let's try enabling skipped tests summary for gtest test
-  # results too (in a separate patch), and see if we break anything.
-  output_skipped_tests_summary = 'gtest' in options.output_formats
-
-  reporter = _GetProgressReporter(output_skipped_tests_summary,
-                                  options.suppress_gtest_report)
-
-  results = page_test_results.PageTestResults(
-      output_formatters=output_formatters, progress_reporter=reporter,
-      output_dir=options.output_dir,
-      value_can_be_added_predicate=value_can_be_added_predicate,
-      benchmark_enabled=benchmark_enabled)
-
-  results.telemetry_info.benchmark_name = benchmark_metadata.name
-  results.telemetry_info.benchmark_start_ms = time.time() * 1000.0
-  if options.results_label:
-    results.telemetry_info.label = options.results_label
-
-  return results
diff --git a/catapult/telemetry/telemetry/internal/results/story_run.py b/catapult/telemetry/telemetry/internal/results/story_run.py
deleted file mode 100644
index 078d0fc..0000000
--- a/catapult/telemetry/telemetry/internal/results/story_run.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.value import failure
-from telemetry.value import skip
-
-
-class StoryRun(object):
-  def __init__(self, story):
-    self._story = story
-    self._values = []
-
-  def AddValue(self, value):
-    self._values.append(value)
-
-  @property
-  def story(self):
-    return self._story
-
-  @property
-  def values(self):
-    """The values that correspond to this story run."""
-    return self._values
-
-  @property
-  def ok(self):
-    """Whether the current run is still ok.
-
-    To be precise: returns true if there is neither FailureValue nor
-    SkipValue in self.values.
-    """
-    return not self.skipped and not self.failed
-
-  @property
-  def skipped(self):
-    """Whether the current run is being skipped.
-
-    To be precise: returns true if there is any SkipValue in self.values.
-    """
-    return any(isinstance(v, skip.SkipValue) for v in self.values)
-
-  @property
-  def failed(self):
-    """Whether the current run failed.
-
-    To be precise: returns true if there is a FailureValue but not
-    SkipValue in self.values.
-    """
-    return not self.skipped and any(
-        isinstance(v, failure.FailureValue) for v in self.values)
diff --git a/catapult/telemetry/telemetry/internal/results/story_run_unittest.py b/catapult/telemetry/telemetry/internal/results/story_run_unittest.py
deleted file mode 100644
index d084a75..0000000
--- a/catapult/telemetry/telemetry/internal/results/story_run_unittest.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.results import story_run
-from telemetry.story import shared_state
-from telemetry.story import story_set
-from telemetry import story as story_module
-from telemetry.value import failure
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.value import skip
-
-
-# pylint: disable=abstract-method
-class SharedStateBar(shared_state.SharedState):
-  pass
-
-class StoryFoo(story_module.Story):
-  def __init__(self, name='', tags=None):
-    super(StoryFoo, self).__init__(
-        SharedStateBar, name, tags)
-
-class StoryRunTest(unittest.TestCase):
-  def setUp(self):
-    self.story_set = story_set.StorySet()
-    self.story_set.AddStory(StoryFoo())
-
-  @property
-  def stories(self):
-    return self.story_set.stories
-
-  def testStoryRunFailed(self):
-    run = story_run.StoryRun(self.stories[0])
-    run.AddValue(failure.FailureValue.FromMessage(self.stories[0], 'test'))
-    self.assertFalse(run.ok)
-    self.assertTrue(run.failed)
-    self.assertFalse(run.skipped)
-
-    run = story_run.StoryRun(self.stories[0])
-    run.AddValue(scalar.ScalarValue(
-        self.stories[0], 'a', 's', 1,
-        improvement_direction=improvement_direction.UP))
-    run.AddValue(failure.FailureValue.FromMessage(self.stories[0], 'test'))
-    self.assertFalse(run.ok)
-    self.assertTrue(run.failed)
-    self.assertFalse(run.skipped)
-
-  def testStoryRunSkipped(self):
-    run = story_run.StoryRun(self.stories[0])
-    run.AddValue(failure.FailureValue.FromMessage(self.stories[0], 'test'))
-    run.AddValue(skip.SkipValue(self.stories[0], 'test'))
-    self.assertFalse(run.ok)
-    self.assertFalse(run.failed)
-    self.assertTrue(run.skipped)
-
-    run = story_run.StoryRun(self.stories[0])
-    run.AddValue(scalar.ScalarValue(
-        self.stories[0], 'a', 's', 1,
-        improvement_direction=improvement_direction.UP))
-    run.AddValue(skip.SkipValue(self.stories[0], 'test'))
-    self.assertFalse(run.ok)
-    self.assertFalse(run.failed)
-    self.assertTrue(run.skipped)
-
-  def testStoryRunSucceeded(self):
-    run = story_run.StoryRun(self.stories[0])
-    self.assertTrue(run.ok)
-    self.assertFalse(run.failed)
-    self.assertFalse(run.skipped)
-
-    run = story_run.StoryRun(self.stories[0])
-    run.AddValue(scalar.ScalarValue(
-        self.stories[0], 'a', 's', 1,
-        improvement_direction=improvement_direction.UP))
-    self.assertTrue(run.ok)
-    self.assertFalse(run.failed)
-    self.assertFalse(run.skipped)
diff --git a/catapult/telemetry/telemetry/internal/story_runner.py b/catapult/telemetry/telemetry/internal/story_runner.py
deleted file mode 100644
index 63e31b1..0000000
--- a/catapult/telemetry/telemetry/internal/story_runner.py
+++ /dev/null
@@ -1,470 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import optparse
-import os
-import subprocess
-import sys
-import time
-
-import py_utils
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.core import exceptions
-from telemetry import decorators
-from telemetry.internal.actions import page_action
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.results import results_options
-from telemetry.internal.util import exception_formatter
-from telemetry import page
-from telemetry.page import legacy_page_test
-from telemetry import story as story_module
-from telemetry.util import wpr_modes
-from telemetry.value import failure
-from telemetry.value import skip
-from telemetry.value import scalar
-from telemetry.web_perf import story_test
-
-
-class ArchiveError(Exception):
-  pass
-
-
-def AddCommandLineArgs(parser):
-  story_module.StoryFilter.AddCommandLineArgs(parser)
-  results_options.AddResultsOptions(parser)
-
-  # Page set options
-  group = optparse.OptionGroup(parser, 'Page set repeat options')
-  group.add_option('--pageset-repeat', default=1, type='int',
-                   help='Number of times to repeat the entire pageset.')
-  group.add_option('--max-failures', default=None, type='int',
-                   help='Maximum number of test failures before aborting '
-                   'the run. Defaults to the number specified by the '
-                   'PageTest.')
-  parser.add_option_group(group)
-
-  # WPR options
-  group = optparse.OptionGroup(parser, 'Web Page Replay options')
-  group.add_option('--use-live-sites',
-      dest='use_live_sites', action='store_true',
-      help='Run against live sites and ignore the Web Page Replay archives.')
-  parser.add_option_group(group)
-
-  parser.add_option('-d', '--also-run-disabled-tests',
-                    dest='run_disabled_tests',
-                    action='store_true', default=False,
-                    help='Ignore @Disabled and @Enabled restrictions.')
-
-
-def ProcessCommandLineArgs(parser, args):
-  story_module.StoryFilter.ProcessCommandLineArgs(parser, args)
-  results_options.ProcessCommandLineArgs(parser, args)
-
-  if args.pageset_repeat < 1:
-    parser.error('--pageset-repeat must be a positive integer.')
-
-
-def _RunStoryAndProcessErrorIfNeeded(story, results, state, test):
-  def ProcessError(description=None):
-    state.DumpStateUponFailure(story, results)
-    results.AddValue(failure.FailureValue(story, sys.exc_info(), description))
-  try:
-    # TODO(mikecase): Remove this logging once Android perf bots are swarmed.
-    # crbug.com/678282
-    if state.platform.GetOSName() == 'android':
-      state.platform._platform_backend.Log(
-          'START %s' % (story.name if story.name else str(story)))
-    if isinstance(test, story_test.StoryTest):
-      test.WillRunStory(state.platform)
-    state.WillRunStory(story)
-    if not state.CanRunStory(story):
-      results.AddValue(skip.SkipValue(
-          story,
-          'Skipped because story is not supported '
-          '(SharedState.CanRunStory() returns False).'))
-      return
-    state.RunStory(results)
-    if isinstance(test, story_test.StoryTest):
-      test.Measure(state.platform, results)
-  except (legacy_page_test.Failure, exceptions.TimeoutException,
-          exceptions.LoginException, exceptions.ProfilingException,
-          py_utils.TimeoutException):
-    ProcessError()
-  except exceptions.Error:
-    ProcessError()
-    raise
-  except page_action.PageActionNotSupported as e:
-    results.AddValue(
-        skip.SkipValue(story, 'Unsupported page action: %s' % e))
-  except Exception:
-    ProcessError(description='Unhandlable exception raised.')
-    raise
-  finally:
-    has_existing_exception = (sys.exc_info() != (None, None, None))
-    try:
-      state.DidRunStory(results)
-      # if state.DidRunStory raises exception, things are messed up badly and we
-      # do not need to run test.DidRunStory at that point.
-      if isinstance(test, story_test.StoryTest):
-        test.DidRunStory(state.platform)
-      else:
-        test.DidRunPage(state.platform)
-      # TODO(mikecase): Remove this logging once Android perf bots are swarmed.
-      # crbug.com/678282
-      if state.platform.GetOSName() == 'android':
-        state.platform._platform_backend.Log(
-            'END %s' % (story.name if story.name else str(story)))
-    except Exception:
-      if not has_existing_exception:
-        state.DumpStateUponFailure(story, results)
-        raise
-      # Print current exception and propagate existing exception.
-      exception_formatter.PrintFormattedException(
-          msg='Exception raised when cleaning story run: ')
-
-
-class StoryGroup(object):
-  def __init__(self, shared_state_class):
-    self._shared_state_class = shared_state_class
-    self._stories = []
-
-  @property
-  def shared_state_class(self):
-    return self._shared_state_class
-
-  @property
-  def stories(self):
-    return self._stories
-
-  def AddStory(self, story):
-    assert (story.shared_state_class is
-            self._shared_state_class)
-    self._stories.append(story)
-
-
-def StoriesGroupedByStateClass(story_set, allow_multiple_groups):
-  """ Returns a list of story groups which each contains stories with
-  the same shared_state_class.
-
-  Example:
-    Assume A1, A2, A3 are stories with same shared story class, and
-    similar for B1, B2.
-    If their orders in story set is A1 A2 B1 B2 A3, then the grouping will
-    be [A1 A2] [B1 B2] [A3].
-
-  It's purposefully done this way to make sure that order of
-  stories are the same of that defined in story_set. It's recommended that
-  stories with the same states should be arranged next to each others in
-  story sets to reduce the overhead of setting up & tearing down the
-  shared story state.
-  """
-  story_groups = []
-  story_groups.append(
-      StoryGroup(story_set[0].shared_state_class))
-  for story in story_set:
-    if (story.shared_state_class is not
-        story_groups[-1].shared_state_class):
-      if not allow_multiple_groups:
-        raise ValueError('This StorySet is only allowed to have one '
-                         'SharedState but contains the following '
-                         'SharedState classes: %s, %s.\n Either '
-                         'remove the extra SharedStates or override '
-                         'allow_mixed_story_states.' % (
-                         story_groups[-1].shared_state_class,
-                         story.shared_state_class))
-      story_groups.append(
-          StoryGroup(story.shared_state_class))
-    story_groups[-1].AddStory(story)
-  return story_groups
-
-
-def Run(test, story_set, finder_options, results, max_failures=None,
-        tear_down_after_story=False, tear_down_after_story_set=False):
-  """Runs a given test against a given page_set with the given options.
-
-  Stop execution for unexpected exceptions such as KeyboardInterrupt.
-  We "white list" certain exceptions for which the story runner
-  can continue running the remaining stories.
-  """
-  for s in story_set:
-    ValidateStory(s)
-
-  # Filter page set based on options.
-  stories = filter(story_module.StoryFilter.IsSelected, story_set)
-
-  if (not finder_options.use_live_sites and
-      finder_options.browser_options.wpr_mode != wpr_modes.WPR_RECORD):
-    serving_dirs = story_set.serving_dirs
-    if story_set.bucket:
-      for directory in serving_dirs:
-        cloud_storage.GetFilesInDirectoryIfChanged(directory,
-                                                   story_set.bucket)
-    if story_set.archive_data_file and not _UpdateAndCheckArchives(
-        story_set.archive_data_file, story_set.wpr_archive_info, stories):
-      return
-
-  if not stories:
-    return
-
-  # Effective max failures gives priority to command-line flag value.
-  effective_max_failures = finder_options.max_failures
-  if effective_max_failures is None:
-    effective_max_failures = max_failures
-
-  story_groups = StoriesGroupedByStateClass(
-      stories,
-      story_set.allow_mixed_story_states)
-
-  for group in story_groups:
-    state = None
-    try:
-      for storyset_repeat_counter in xrange(finder_options.pageset_repeat):
-        for story in group.stories:
-          if not state:
-            # Construct shared state by using a copy of finder_options. Shared
-            # state may update the finder_options. If we tear down the shared
-            # state after this story run, we want to construct the shared
-            # state for the next story from the original finder_options.
-            state = group.shared_state_class(
-                test, finder_options.Copy(), story_set)
-
-          results.WillRunPage(story, storyset_repeat_counter)
-          try:
-            # Log ps on n7s to determine if adb changed processes.
-            # crbug.com/667470
-            if 'Nexus 7' in state.platform.GetDeviceTypeName():
-              ps_output = subprocess.check_output(['ps', '-ef'])
-              logging.info('Ongoing processes:\n%s', ps_output)
-
-            state.platform.WaitForTemperature(35)
-            _WaitForThermalThrottlingIfNeeded(state.platform)
-            _RunStoryAndProcessErrorIfNeeded(story, results, state, test)
-          except exceptions.Error:
-            # Catch all Telemetry errors to give the story a chance to retry.
-            # The retry is enabled by tearing down the state and creating
-            # a new state instance in the next iteration.
-            try:
-              # If TearDownState raises, do not catch the exception.
-              # (The Error was saved as a failure value.)
-              state.TearDownState()
-            finally:
-              # Later finally-blocks use state, so ensure it is cleared.
-              state = None
-          finally:
-            has_existing_exception = sys.exc_info() != (None, None, None)
-            try:
-              if state:
-                _CheckThermalThrottling(state.platform)
-              results.DidRunPage(story)
-            except Exception:
-              if not has_existing_exception:
-                raise
-              # Print current exception and propagate existing exception.
-              exception_formatter.PrintFormattedException(
-                  msg='Exception from result processing:')
-            if state and tear_down_after_story:
-              state.TearDownState()
-              state = None
-          if (effective_max_failures is not None and
-              len(results.failures) > effective_max_failures):
-            logging.error('Too many failures. Aborting.')
-            return
-        if state and tear_down_after_story_set:
-          state.TearDownState()
-          state = None
-    finally:
-      if state:
-        has_existing_exception = sys.exc_info() != (None, None, None)
-        try:
-          state.TearDownState()
-        except Exception:
-          if not has_existing_exception:
-            raise
-          # Print current exception and propagate existing exception.
-          exception_formatter.PrintFormattedException(
-              msg='Exception from TearDownState:')
-
-
-def ValidateStory(story):
-  if len(story.display_name) > 180:
-    raise ValueError(
-        'User story has display name exceeding 180 characters: %s' %
-        story.display_name)
-
-
-def RunBenchmark(benchmark, finder_options):
-  """Run this test with the given options.
-
-  Returns:
-    The number of failure values (up to 254) or 255 if there is an uncaught
-    exception.
-  """
-  start = time.time()
-  benchmark.CustomizeBrowserOptions(finder_options.browser_options)
-
-  benchmark_metadata = benchmark.GetMetadata()
-  possible_browser = browser_finder.FindBrowser(finder_options)
-  if not possible_browser:
-    print ('Cannot find browser of type %s. To list out all '
-           'available browsers, rerun your command with '
-           '--browser=list' %  finder_options.browser_options.browser_type)
-    return 1
-  if (possible_browser and
-    not decorators.IsBenchmarkEnabled(benchmark, possible_browser)):
-    print '%s is disabled on the selected browser' % benchmark.Name()
-    if finder_options.run_disabled_tests:
-      print 'Running benchmark anyway due to: --also-run-disabled-tests'
-    else:
-      print 'Try --also-run-disabled-tests to force the benchmark to run.'
-      # If chartjson is specified, this will print a dict indicating the
-      # benchmark name and disabled state.
-      with results_options.CreateResults(
-          benchmark_metadata, finder_options,
-          benchmark.ValueCanBeAddedPredicate, benchmark_enabled=False
-          ) as results:
-        results.PrintSummary()
-      # When a disabled benchmark is run we now want to return success since
-      # we are no longer filtering these out in the buildbot recipes.
-      return 0
-
-  pt = benchmark.CreatePageTest(finder_options)
-  pt.__name__ = benchmark.__class__.__name__
-
-  disabled_attr_name = decorators.DisabledAttributeName(benchmark)
-  # pylint: disable=protected-access
-  pt._disabled_strings = getattr(benchmark, disabled_attr_name, set())
-  if hasattr(benchmark, '_enabled_strings'):
-    # pylint: disable=protected-access
-    pt._enabled_strings = benchmark._enabled_strings
-
-  stories = benchmark.CreateStorySet(finder_options)
-
-  if isinstance(pt, legacy_page_test.LegacyPageTest):
-    if any(not isinstance(p, page.Page) for p in stories.stories):
-      raise Exception(
-          'PageTest must be used with StorySet containing only '
-          'telemetry.page.Page stories.')
-
-  should_tear_down_state_after_each_story_run = (
-      benchmark.ShouldTearDownStateAfterEachStoryRun())
-  # HACK: restarting shared state has huge overhead on cros (crbug.com/645329),
-  # hence we default this to False when test is run against CrOS.
-  # TODO(cros-team): figure out ways to remove this hack.
-  if (possible_browser.platform.GetOSName() == 'chromeos' and
-      not benchmark.IsShouldTearDownStateAfterEachStoryRunOverriden()):
-    should_tear_down_state_after_each_story_run = False
-
-  with results_options.CreateResults(
-      benchmark_metadata, finder_options,
-      benchmark.ValueCanBeAddedPredicate, benchmark_enabled=True) as results:
-    try:
-      Run(pt, stories, finder_options, results, benchmark.max_failures,
-          should_tear_down_state_after_each_story_run,
-          benchmark.ShouldTearDownStateAfterEachStorySetRun())
-      return_code = min(254, len(results.failures))
-    except Exception:
-      exception_formatter.PrintFormattedException()
-      return_code = 255
-
-    try:
-      if finder_options.upload_results:
-        bucket = finder_options.upload_bucket
-        if bucket in cloud_storage.BUCKET_ALIASES:
-          bucket = cloud_storage.BUCKET_ALIASES[bucket]
-        results.UploadTraceFilesToCloud(bucket)
-        results.UploadProfilingFilesToCloud(bucket)
-    finally:
-      duration = time.time() - start
-      results.AddSummaryValue(scalar.ScalarValue(
-          None, 'BenchmarkDuration', 'minutes', duration / 60.0))
-      results.PrintSummary()
-  return return_code
-
-
-def _UpdateAndCheckArchives(archive_data_file, wpr_archive_info,
-                            filtered_stories):
-  """Verifies that all stories are local or have WPR archives.
-
-  Logs warnings and returns False if any are missing.
-  """
-  # Report any problems with the entire story set.
-  if any(not story.is_local for story in filtered_stories):
-    if not archive_data_file:
-      logging.error('The story set is missing an "archive_data_file" '
-                    'property.\nTo run from live sites pass the flag '
-                    '--use-live-sites.\nTo create an archive file add an '
-                    'archive_data_file property to the story set and then '
-                    'run record_wpr.')
-      raise ArchiveError('No archive data file.')
-    if not wpr_archive_info:
-      logging.error('The archive info file is missing.\n'
-                    'To fix this, either add svn-internal to your '
-                    '.gclient using http://goto/read-src-internal, '
-                    'or create a new archive using record_wpr.')
-      raise ArchiveError('No archive info file.')
-    wpr_archive_info.DownloadArchivesIfNeeded()
-
-  # Report any problems with individual story.
-  stories_missing_archive_path = []
-  stories_missing_archive_data = []
-  for story in filtered_stories:
-    if not story.is_local:
-      archive_path = wpr_archive_info.WprFilePathForStory(story)
-      if not archive_path:
-        stories_missing_archive_path.append(story)
-      elif not os.path.isfile(archive_path):
-        stories_missing_archive_data.append(story)
-  if stories_missing_archive_path:
-    logging.error(
-        'The story set archives for some stories do not exist.\n'
-        'To fix this, record those stories using record_wpr.\n'
-        'To ignore this warning and run against live sites, '
-        'pass the flag --use-live-sites.')
-    logging.error(
-        'stories without archives: %s',
-        ', '.join(story.display_name
-                  for story in stories_missing_archive_path))
-  if stories_missing_archive_data:
-    logging.error(
-        'The story set archives for some stories are missing.\n'
-        'Someone forgot to check them in, uploaded them to the '
-        'wrong cloud storage bucket, or they were deleted.\n'
-        'To fix this, record those stories using record_wpr.\n'
-        'To ignore this warning and run against live sites, '
-        'pass the flag --use-live-sites.')
-    logging.error(
-        'stories missing archives: %s',
-        ', '.join(story.display_name
-                  for story in stories_missing_archive_data))
-  if stories_missing_archive_path or stories_missing_archive_data:
-    raise ArchiveError('Archive file is missing stories.')
-  # Only run valid stories if no problems with the story set or
-  # individual stories.
-  return True
-
-
-def _WaitForThermalThrottlingIfNeeded(platform):
-  if not platform.CanMonitorThermalThrottling():
-    return
-  thermal_throttling_retry = 0
-  while (platform.IsThermallyThrottled() and
-         thermal_throttling_retry < 3):
-    logging.warning('Thermally throttled, waiting (%d)...',
-                    thermal_throttling_retry)
-    thermal_throttling_retry += 1
-    time.sleep(thermal_throttling_retry * 2)
-
-  if thermal_throttling_retry and platform.IsThermallyThrottled():
-    logging.warning('Device is thermally throttled before running '
-                    'performance tests, results will vary.')
-
-
-def _CheckThermalThrottling(platform):
-  if not platform.CanMonitorThermalThrottling():
-    return
-  if platform.HasBeenThermallyThrottled():
-    logging.warning('Device has been thermally throttled during '
-                    'performance tests, results will vary.')
diff --git a/catapult/telemetry/telemetry/internal/story_runner_unittest.py b/catapult/telemetry/telemetry/internal/story_runner_unittest.py
deleted file mode 100644
index 822092f..0000000
--- a/catapult/telemetry/telemetry/internal/story_runner_unittest.py
+++ /dev/null
@@ -1,1083 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import math
-import os
-import shutil
-import StringIO
-import sys
-import tempfile
-import unittest
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry import benchmark
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.actions import page_action
-from telemetry.internal.results import page_test_results
-from telemetry.internal.results import results_options
-from telemetry.internal import story_runner
-from telemetry.internal.util import exception_formatter as ex_formatter_module
-from telemetry.page import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry import story as story_module
-from telemetry.testing import fakes
-from telemetry.testing import options_for_unittests
-from telemetry.testing import system_stub
-import mock
-from telemetry.value import failure
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-from telemetry.value import skip
-from telemetry.value import summary as summary_module
-from telemetry.web_perf import story_test
-from telemetry.web_perf import timeline_based_measurement
-from telemetry.wpr import archive_info
-
-# This linter complains if we define classes nested inside functions.
-# pylint: disable=bad-super-call
-
-# pylint: disable=too-many-lines
-
-class FakePlatform(object):
-  def CanMonitorThermalThrottling(self):
-    return False
-
-  def GetOSName(self):
-    pass
-
-  def WaitForTemperature(self, _):
-    pass
-
-  def GetDeviceTypeName(self):
-    return "GetDeviceTypeName"
-
-class TestSharedState(story_module.SharedState):
-
-  _platform = FakePlatform()
-
-  @classmethod
-  def SetTestPlatform(cls, platform):
-    cls._platform = platform
-
-  def __init__(self, test, options, story_set):
-    super(TestSharedState, self).__init__(
-        test, options, story_set)
-    self._test = test
-    self._current_story = None
-
-  @property
-  def platform(self):
-    return self._platform
-
-  def WillRunStory(self, story):
-    self._current_story = story
-
-  def CanRunStory(self, story):
-    return True
-
-  def RunStory(self, results):
-    raise NotImplementedError
-
-  def DidRunStory(self, results):
-    pass
-
-  def TearDownState(self):
-    pass
-
-  def DumpStateUponFailure(self, story, results):
-    pass
-
-
-class TestSharedPageState(TestSharedState):
-  def RunStory(self, results):
-    self._test.RunPage(self._current_story, None, results)
-
-
-class FooStoryState(TestSharedPageState):
-  pass
-
-
-class BarStoryState(TestSharedPageState):
-  pass
-
-
-class DummyTest(legacy_page_test.LegacyPageTest):
-  def RunPage(self, *_):
-    pass
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    pass
-
-
-class EmptyMetadataForTest(benchmark.BenchmarkMetadata):
-  def __init__(self):
-    super(EmptyMetadataForTest, self).__init__('')
-
-
-class DummyLocalStory(story_module.Story):
-  def __init__(self, shared_state_class, name=''):
-    super(DummyLocalStory, self).__init__(
-        shared_state_class, name=name)
-
-  def Run(self, shared_state):
-    pass
-
-  @property
-  def is_local(self):
-    return True
-
-  @property
-  def url(self):
-    return 'data:,'
-
-
-class MixedStateStorySet(story_module.StorySet):
-  @property
-  def allow_mixed_story_states(self):
-    return True
-
-
-def SetupStorySet(allow_multiple_story_states, story_state_list):
-  if allow_multiple_story_states:
-    story_set = MixedStateStorySet()
-  else:
-    story_set = story_module.StorySet()
-  for i, story_state in enumerate(story_state_list):
-    story_set.AddStory(DummyLocalStory(story_state,
-                                       name='story%d' % i))
-  return story_set
-
-class FakeBenchmark(benchmark.Benchmark):
-  @classmethod
-  def Name(cls):
-    return 'fake'
-
-  test = DummyTest
-
-  def page_set(self):
-    return story_module.StorySet()
-
-
-def _GetOptionForUnittest():
-  options = options_for_unittests.GetCopy()
-  options.output_formats = ['none']
-  options.suppress_gtest_report = False
-  parser = options.CreateParser()
-  story_runner.AddCommandLineArgs(parser)
-  options.MergeDefaultValues(parser.get_default_values())
-  story_runner.ProcessCommandLineArgs(parser, options)
-  return options
-
-
-class FakeExceptionFormatterModule(object):
-  @staticmethod
-  def PrintFormattedException(
-      exception_class=None, exception=None, tb=None, msg=None):
-    pass
-
-
-def GetNumberOfSuccessfulPageRuns(results):
-  return len([run for run in results.all_page_runs if run.ok or run.skipped])
-
-
-class TestOnlyException(Exception):
-  pass
-
-
-class FailureValueMatcher(object):
-  def __init__(self, expected_exception_message):
-    self._expected_exception_message = expected_exception_message
-
-  def __eq__(self, other):
-    return (isinstance(other, failure.FailureValue) and
-            other.exc_info[1].message == self._expected_exception_message)
-
-
-class SkipValueMatcher(object):
-  def __eq__(self, other):
-    return isinstance(other, skip.SkipValue)
-
-
-class StoryRunnerTest(unittest.TestCase):
-  def setUp(self):
-    self.fake_stdout = StringIO.StringIO()
-    self.actual_stdout = sys.stdout
-    sys.stdout = self.fake_stdout
-    self.options = _GetOptionForUnittest()
-    self.results = results_options.CreateResults(
-        EmptyMetadataForTest(), self.options)
-    self._story_runner_logging_stub = None
-
-  def SuppressExceptionFormatting(self):
-    """Fake out exception formatter to avoid spamming the unittest stdout."""
-    story_runner.exception_formatter = FakeExceptionFormatterModule
-    self._story_runner_logging_stub = system_stub.Override(
-      story_runner, ['logging'])
-
-  def RestoreExceptionFormatter(self):
-    story_runner.exception_formatter = ex_formatter_module
-    if self._story_runner_logging_stub:
-      self._story_runner_logging_stub.Restore()
-      self._story_runner_logging_stub = None
-
-  def tearDown(self):
-    sys.stdout = self.actual_stdout
-    self.RestoreExceptionFormatter()
-
-  def testStoriesGroupedByStateClass(self):
-    foo_states = [FooStoryState, FooStoryState, FooStoryState,
-                  FooStoryState, FooStoryState]
-    mixed_states = [FooStoryState, FooStoryState, FooStoryState,
-                    BarStoryState, FooStoryState]
-    # StorySet's are only allowed to have one SharedState.
-    story_set = SetupStorySet(False, foo_states)
-    story_groups = (
-        story_runner.StoriesGroupedByStateClass(
-            story_set, False))
-    self.assertEqual(len(story_groups), 1)
-    story_set = SetupStorySet(False, mixed_states)
-    self.assertRaises(
-        ValueError,
-        story_runner.StoriesGroupedByStateClass,
-        story_set, False)
-    # BaseStorySets are allowed to have multiple SharedStates.
-    mixed_story_set = SetupStorySet(True, mixed_states)
-    story_groups = (
-        story_runner.StoriesGroupedByStateClass(
-            mixed_story_set, True))
-    self.assertEqual(len(story_groups), 3)
-    self.assertEqual(story_groups[0].shared_state_class,
-                     FooStoryState)
-    self.assertEqual(story_groups[1].shared_state_class,
-                     BarStoryState)
-    self.assertEqual(story_groups[2].shared_state_class,
-                     FooStoryState)
-
-  def RunStoryTest(self, s, expected_successes):
-    test = DummyTest()
-    story_runner.Run(
-        test, s, self.options, self.results)
-    self.assertEquals(0, len(self.results.failures))
-    self.assertEquals(expected_successes,
-                      GetNumberOfSuccessfulPageRuns(self.results))
-
-  def testRunStoryWithMissingArchiveFile(self):
-    story_set = story_module.StorySet(archive_data_file='data/hi.json')
-    story_set.AddStory(page_module.Page(
-        'http://www.testurl.com', story_set, story_set.base_dir))
-    test = DummyTest()
-    self.assertRaises(story_runner.ArchiveError, story_runner.Run, test,
-                      story_set, self.options, self.results)
-
-  def testStoryTest(self):
-    all_foo = [FooStoryState, FooStoryState, FooStoryState]
-    one_bar = [FooStoryState, FooStoryState, BarStoryState]
-    story_set = SetupStorySet(True, one_bar)
-    self.RunStoryTest(story_set, 3)
-    story_set = SetupStorySet(True, all_foo)
-    self.RunStoryTest(story_set, 6)
-    story_set = SetupStorySet(False, all_foo)
-    self.RunStoryTest(story_set, 9)
-    story_set = SetupStorySet(False, one_bar)
-    test = DummyTest()
-    self.assertRaises(ValueError, story_runner.Run, test, story_set,
-                      self.options, self.results)
-
-  def testRunStoryWithLongName(self):
-    story_set = story_module.StorySet()
-    story_set.AddStory(DummyLocalStory(FooStoryState, name='l' * 182))
-    test = DummyTest()
-    self.assertRaises(ValueError, story_runner.Run, test, story_set,
-                      self.options, self.results)
-
-  def testRunStoryWithLongURLPage(self):
-    story_set = story_module.StorySet()
-    story_set.AddStory(page_module.Page('file://long' + 'g' * 180, story_set))
-    test = DummyTest()
-    self.assertRaises(ValueError, story_runner.Run, test, story_set,
-                      self.options, self.results)
-
-  def testSuccessfulTimelineBasedMeasurementTest(self):
-    """Check that PageTest is not required for story_runner.Run.
-
-    Any PageTest related calls or attributes need to only be called
-    for PageTest tests.
-    """
-    class TestSharedTbmState(TestSharedState):
-      def RunStory(self, results):
-        pass
-
-    TEST_WILL_RUN_STORY = 'test.WillRunStory'
-    TEST_MEASURE = 'test.Measure'
-    TEST_DID_RUN_STORY = 'test.DidRunStory'
-
-    EXPECTED_CALLS_IN_ORDER = [TEST_WILL_RUN_STORY,
-                               TEST_MEASURE,
-                               TEST_DID_RUN_STORY]
-
-    test = timeline_based_measurement.TimelineBasedMeasurement(
-        timeline_based_measurement.Options())
-
-    manager = mock.MagicMock()
-    test.WillRunStory = mock.MagicMock()
-    test.Measure = mock.MagicMock()
-    test.DidRunStory = mock.MagicMock()
-    manager.attach_mock(test.WillRunStory, TEST_WILL_RUN_STORY)
-    manager.attach_mock(test.Measure, TEST_MEASURE)
-    manager.attach_mock(test.DidRunStory, TEST_DID_RUN_STORY)
-
-    story_set = story_module.StorySet()
-    story_set.AddStory(DummyLocalStory(TestSharedTbmState, name='foo'))
-    story_set.AddStory(DummyLocalStory(TestSharedTbmState, name='bar'))
-    story_set.AddStory(DummyLocalStory(TestSharedTbmState, name='baz'))
-    story_runner.Run(
-        test, story_set, self.options, self.results)
-    self.assertEquals(0, len(self.results.failures))
-    self.assertEquals(3, GetNumberOfSuccessfulPageRuns(self.results))
-
-    self.assertEquals(3*EXPECTED_CALLS_IN_ORDER,
-                      [call[0] for call in manager.mock_calls])
-
-  def testCallOrderBetweenStoryTestAndSharedState(self):
-    """Check that the call order between StoryTest and SharedState is correct.
-    """
-    TEST_WILL_RUN_STORY = 'test.WillRunStory'
-    TEST_MEASURE = 'test.Measure'
-    TEST_DID_RUN_STORY = 'test.DidRunStory'
-    STATE_WILL_RUN_STORY = 'state.WillRunStory'
-    STATE_RUN_STORY = 'state.RunStory'
-    STATE_DID_RUN_STORY = 'state.DidRunStory'
-
-    EXPECTED_CALLS_IN_ORDER = [TEST_WILL_RUN_STORY,
-                               STATE_WILL_RUN_STORY,
-                               STATE_RUN_STORY,
-                               TEST_MEASURE,
-                               STATE_DID_RUN_STORY,
-                               TEST_DID_RUN_STORY]
-
-    class TestStoryTest(story_test.StoryTest):
-      def WillRunStory(self, platform):
-        pass
-
-      def Measure(self, platform, results):
-        pass
-
-      def DidRunStory(self, platform):
-        pass
-
-    class TestSharedStateForStoryTest(TestSharedState):
-      def RunStory(self, results):
-        pass
-
-    @mock.patch.object(TestStoryTest, 'WillRunStory')
-    @mock.patch.object(TestStoryTest, 'Measure')
-    @mock.patch.object(TestStoryTest, 'DidRunStory')
-    @mock.patch.object(TestSharedStateForStoryTest, 'WillRunStory')
-    @mock.patch.object(TestSharedStateForStoryTest, 'RunStory')
-    @mock.patch.object(TestSharedStateForStoryTest, 'DidRunStory')
-    def GetCallsInOrder(state_DidRunStory, state_RunStory, state_WillRunStory,
-                        test_DidRunStory, test_Measure, test_WillRunStory):
-      manager = mock.MagicMock()
-      manager.attach_mock(test_WillRunStory, TEST_WILL_RUN_STORY)
-      manager.attach_mock(test_Measure, TEST_MEASURE)
-      manager.attach_mock(test_DidRunStory, TEST_DID_RUN_STORY)
-      manager.attach_mock(state_WillRunStory, STATE_WILL_RUN_STORY)
-      manager.attach_mock(state_RunStory, STATE_RUN_STORY)
-      manager.attach_mock(state_DidRunStory, STATE_DID_RUN_STORY)
-
-      test = TestStoryTest()
-      story_set = story_module.StorySet()
-      story_set.AddStory(DummyLocalStory(TestSharedStateForStoryTest))
-      story_runner.Run(test, story_set, self.options, self.results)
-      return [call[0] for call in manager.mock_calls]
-
-    calls_in_order = GetCallsInOrder() # pylint: disable=no-value-for-parameter
-    self.assertEquals(EXPECTED_CALLS_IN_ORDER, calls_in_order)
-
-  def testTearDownStateAfterEachStoryOrStorySetRun(self):
-    class TestSharedStateForTearDown(TestSharedState):
-      num_of_tear_downs = 0
-
-      def RunStory(self, results):
-        pass
-
-      def TearDownState(self):
-        TestSharedStateForTearDown.num_of_tear_downs += 1
-
-    story_set = story_module.StorySet()
-    story_set.AddStory(DummyLocalStory(TestSharedStateForTearDown, name='foo'))
-    story_set.AddStory(DummyLocalStory(TestSharedStateForTearDown, name='bar'))
-    story_set.AddStory(DummyLocalStory(TestSharedStateForTearDown, name='baz'))
-
-    TestSharedStateForTearDown.num_of_tear_downs = 0
-    story_runner.Run(mock.MagicMock(), story_set, self.options, self.results)
-    self.assertEquals(TestSharedStateForTearDown.num_of_tear_downs, 1)
-
-    TestSharedStateForTearDown.num_of_tear_downs = 0
-    story_runner.Run(mock.MagicMock(), story_set, self.options, self.results,
-                     tear_down_after_story=True)
-    self.assertEquals(TestSharedStateForTearDown.num_of_tear_downs, 3)
-
-    self.options.pageset_repeat = 5
-    TestSharedStateForTearDown.num_of_tear_downs = 0
-    story_runner.Run(mock.MagicMock(), story_set, self.options, self.results,
-                     tear_down_after_story_set=True)
-    self.assertEquals(TestSharedStateForTearDown.num_of_tear_downs, 5)
-
-  def testTearDownIsCalledOnceForEachStoryGroupWithPageSetRepeat(self):
-    self.options.pageset_repeat = 3
-    fooz_init_call_counter = [0]
-    fooz_tear_down_call_counter = [0]
-    barz_init_call_counter = [0]
-    barz_tear_down_call_counter = [0]
-    class FoozStoryState(FooStoryState):
-      def __init__(self, test, options, storyz):
-        super(FoozStoryState, self).__init__(
-          test, options, storyz)
-        fooz_init_call_counter[0] += 1
-      def TearDownState(self):
-        fooz_tear_down_call_counter[0] += 1
-
-    class BarzStoryState(BarStoryState):
-      def __init__(self, test, options, storyz):
-        super(BarzStoryState, self).__init__(
-          test, options, storyz)
-        barz_init_call_counter[0] += 1
-      def TearDownState(self):
-        barz_tear_down_call_counter[0] += 1
-    def AssertAndCleanUpFoo():
-      self.assertEquals(1, fooz_init_call_counter[0])
-      self.assertEquals(1, fooz_tear_down_call_counter[0])
-      fooz_init_call_counter[0] = 0
-      fooz_tear_down_call_counter[0] = 0
-
-    story_set1_list = [FoozStoryState, FoozStoryState, FoozStoryState,
-                       BarzStoryState, BarzStoryState]
-    story_set1 = SetupStorySet(True, story_set1_list)
-    self.RunStoryTest(story_set1, 15)
-    AssertAndCleanUpFoo()
-    self.assertEquals(1, barz_init_call_counter[0])
-    self.assertEquals(1, barz_tear_down_call_counter[0])
-    barz_init_call_counter[0] = 0
-    barz_tear_down_call_counter[0] = 0
-
-    story_set2_list = [FoozStoryState, FoozStoryState, FoozStoryState,
-                       FoozStoryState]
-    story_set2 = SetupStorySet(False, story_set2_list)
-    self.RunStoryTest(story_set2, 27)
-    AssertAndCleanUpFoo()
-    self.assertEquals(0, barz_init_call_counter[0])
-    self.assertEquals(0, barz_tear_down_call_counter[0])
-
-  def testAppCrashExceptionCausesFailureValue(self):
-    self.SuppressExceptionFormatting()
-    story_set = story_module.StorySet()
-    class SharedStoryThatCausesAppCrash(TestSharedPageState):
-      def WillRunStory(self, story):
-        raise exceptions.AppCrashException(msg='App Foo crashes')
-
-    story_set.AddStory(DummyLocalStory(
-          SharedStoryThatCausesAppCrash))
-    story_runner.Run(
-        DummyTest(), story_set, self.options, self.results)
-    self.assertEquals(1, len(self.results.failures))
-    self.assertEquals(0, GetNumberOfSuccessfulPageRuns(self.results))
-    self.assertIn('App Foo crashes', self.fake_stdout.getvalue())
-
-  def testExceptionRaisedInSharedStateTearDown(self):
-    self.SuppressExceptionFormatting()
-    story_set = story_module.StorySet()
-    class SharedStoryThatCausesAppCrash(TestSharedPageState):
-      def TearDownState(self):
-        raise TestOnlyException()
-
-    story_set.AddStory(DummyLocalStory(
-          SharedStoryThatCausesAppCrash))
-    with self.assertRaises(TestOnlyException):
-      story_runner.Run(
-          DummyTest(), story_set, self.options, self.results)
-
-  def testUnknownExceptionIsFatal(self):
-    self.SuppressExceptionFormatting()
-    story_set = story_module.StorySet()
-
-    class UnknownException(Exception):
-      pass
-
-    # This erroneous test is set up to raise exception for the 2nd story
-    # run.
-    class Test(legacy_page_test.LegacyPageTest):
-      def __init__(self, *args):
-        super(Test, self).__init__(*args)
-        self.run_count = 0
-
-      def RunPage(self, *_):
-        old_run_count = self.run_count
-        self.run_count += 1
-        if old_run_count == 1:
-          raise UnknownException('FooBarzException')
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    s1 = DummyLocalStory(TestSharedPageState, name='foo')
-    s2 = DummyLocalStory(TestSharedPageState, name='bar')
-    story_set.AddStory(s1)
-    story_set.AddStory(s2)
-    test = Test()
-    with self.assertRaises(UnknownException):
-      story_runner.Run(
-          test, story_set, self.options, self.results)
-    self.assertEqual(set([s2]), self.results.pages_that_failed)
-    self.assertEqual(set([s1]), self.results.pages_that_succeeded)
-    self.assertIn('FooBarzException', self.fake_stdout.getvalue())
-
-  def testRaiseBrowserGoneExceptionFromRunPage(self):
-    self.SuppressExceptionFormatting()
-    story_set = story_module.StorySet()
-
-    class Test(legacy_page_test.LegacyPageTest):
-      def __init__(self, *args):
-        super(Test, self).__init__(*args)
-        self.run_count = 0
-
-      def RunPage(self, *_):
-        old_run_count = self.run_count
-        self.run_count += 1
-        if old_run_count == 0:
-          raise exceptions.BrowserGoneException(
-              None, 'i am a browser crash message')
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    story_set.AddStory(DummyLocalStory(TestSharedPageState, name='foo'))
-    story_set.AddStory(DummyLocalStory(TestSharedPageState, name='bar'))
-    test = Test()
-    story_runner.Run(
-        test, story_set, self.options, self.results)
-    self.assertEquals(2, test.run_count)
-    self.assertEquals(1, len(self.results.failures))
-    self.assertEquals(1, GetNumberOfSuccessfulPageRuns(self.results))
-
-  def testAppCrashThenRaiseInTearDownFatal(self):
-    self.SuppressExceptionFormatting()
-    story_set = story_module.StorySet()
-
-    unit_test_events = []  # track what was called when
-    class DidRunTestError(Exception):
-      pass
-
-    class TestTearDownSharedState(TestSharedPageState):
-      def TearDownState(self):
-        unit_test_events.append('tear-down-state')
-        raise DidRunTestError
-
-      def DumpStateUponFailure(self, story, results):
-        unit_test_events.append('dump-state')
-
-
-    class Test(legacy_page_test.LegacyPageTest):
-      def __init__(self, *args):
-        super(Test, self).__init__(*args)
-        self.run_count = 0
-
-      def RunPage(self, *_):
-        old_run_count = self.run_count
-        self.run_count += 1
-        if old_run_count == 0:
-          unit_test_events.append('app-crash')
-          raise exceptions.AppCrashException
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    story_set.AddStory(DummyLocalStory(TestTearDownSharedState, name='foo'))
-    story_set.AddStory(DummyLocalStory(TestTearDownSharedState, name='bar'))
-    test = Test()
-
-    with self.assertRaises(DidRunTestError):
-      story_runner.Run(
-          test, story_set, self.options, self.results)
-    self.assertEqual(['app-crash', 'dump-state', 'tear-down-state'],
-                     unit_test_events)
-    # The AppCrashException gets added as a failure.
-    self.assertEquals(1, len(self.results.failures))
-
-  def testPagesetRepeat(self):
-    story_set = story_module.StorySet()
-
-    # TODO(eakuefner): Factor this out after flattening page ref in Value
-    blank_story = DummyLocalStory(TestSharedPageState, name='blank')
-    green_story = DummyLocalStory(TestSharedPageState, name='green')
-    story_set.AddStory(blank_story)
-    story_set.AddStory(green_story)
-
-    class Measurement(legacy_page_test.LegacyPageTest):
-      i = 0
-      def RunPage(self, page, _, results):
-        self.i += 1
-        results.AddValue(scalar.ScalarValue(
-            page, 'metric', 'unit', self.i,
-            improvement_direction=improvement_direction.UP))
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    self.options.pageset_repeat = 2
-    self.options.output_formats = []
-    results = results_options.CreateResults(
-      EmptyMetadataForTest(), self.options)
-    story_runner.Run(
-        Measurement(), story_set, self.options, results)
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    blank_value = list_of_scalar_values.ListOfScalarValues(
-        blank_story, 'metric', 'unit', [1, 3],
-        improvement_direction=improvement_direction.UP)
-    green_value = list_of_scalar_values.ListOfScalarValues(
-        green_story, 'metric', 'unit', [2, 4],
-        improvement_direction=improvement_direction.UP)
-    merged_value = list_of_scalar_values.ListOfScalarValues(
-        None, 'metric', 'unit',
-        [1, 3, 2, 4], std=math.sqrt(2),  # Pooled standard deviation.
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(4, GetNumberOfSuccessfulPageRuns(results))
-    self.assertEquals(0, len(results.failures))
-    self.assertEquals(3, len(values))
-    self.assertIn(blank_value, values)
-    self.assertIn(green_value, values)
-    self.assertIn(merged_value, values)
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUpdateAndCheckArchives(self):
-    usr_stub = system_stub.Override(story_runner, ['cloud_storage'])
-    wpr_stub = system_stub.Override(archive_info, ['cloud_storage'])
-    archive_data_dir = os.path.join(
-        util.GetTelemetryDir(),
-        'telemetry', 'internal', 'testing', 'archive_files')
-    try:
-      story_set = story_module.StorySet()
-      story_set.AddStory(page_module.Page(
-          'http://www.testurl.com', story_set, story_set.base_dir))
-      # Page set missing archive_data_file.
-      self.assertRaises(
-          story_runner.ArchiveError,
-          story_runner._UpdateAndCheckArchives,
-          story_set.archive_data_file,
-          story_set.wpr_archive_info,
-          story_set.stories)
-
-      story_set = story_module.StorySet(
-          archive_data_file='missing_archive_data_file.json')
-      story_set.AddStory(page_module.Page(
-          'http://www.testurl.com', story_set, story_set.base_dir))
-      # Page set missing json file specified in archive_data_file.
-      self.assertRaises(
-          story_runner.ArchiveError,
-          story_runner._UpdateAndCheckArchives,
-          story_set.archive_data_file,
-          story_set.wpr_archive_info,
-          story_set.stories)
-
-      story_set = story_module.StorySet(
-          archive_data_file=os.path.join(archive_data_dir, 'test.json'),
-          cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET)
-      story_set.AddStory(page_module.Page(
-          'http://www.testurl.com', story_set, story_set.base_dir))
-      # Page set with valid archive_data_file.
-      self.assertTrue(story_runner._UpdateAndCheckArchives(
-            story_set.archive_data_file, story_set.wpr_archive_info,
-            story_set.stories))
-      story_set.AddStory(page_module.Page(
-          'http://www.google.com', story_set, story_set.base_dir))
-      # Page set with an archive_data_file which exists but is missing a page.
-      self.assertRaises(
-          story_runner.ArchiveError,
-          story_runner._UpdateAndCheckArchives,
-          story_set.archive_data_file,
-          story_set.wpr_archive_info,
-          story_set.stories)
-
-      story_set = story_module.StorySet(
-          archive_data_file=
-              os.path.join(archive_data_dir, 'test_missing_wpr_file.json'),
-          cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET)
-      story_set.AddStory(page_module.Page(
-          'http://www.testurl.com', story_set, story_set.base_dir))
-      story_set.AddStory(page_module.Page(
-          'http://www.google.com', story_set, story_set.base_dir))
-      # Page set with an archive_data_file which exists and contains all pages
-      # but fails to find a wpr file.
-      self.assertRaises(
-          story_runner.ArchiveError,
-          story_runner._UpdateAndCheckArchives,
-          story_set.archive_data_file,
-          story_set.wpr_archive_info,
-          story_set.stories)
-    finally:
-      usr_stub.Restore()
-      wpr_stub.Restore()
-
-
-  def _testMaxFailuresOptionIsRespectedAndOverridable(
-      self, num_failing_stories, runner_max_failures, options_max_failures,
-      expected_num_failures):
-    class SimpleSharedState(story_module.SharedState):
-      _fake_platform = FakePlatform()
-      _current_story = None
-
-      @property
-      def platform(self):
-        return self._fake_platform
-
-      def WillRunStory(self, story):
-        self._current_story = story
-
-      def RunStory(self, results):
-        self._current_story.Run(self)
-
-      def DidRunStory(self, results):
-        pass
-
-      def CanRunStory(self, story):
-        return True
-
-      def TearDownState(self):
-        pass
-
-      def DumpStateUponFailure(self, story, results):
-        pass
-
-    class FailingStory(story_module.Story):
-      def __init__(self, name):
-        super(FailingStory, self).__init__(
-            shared_state_class=SimpleSharedState,
-            is_local=True, name=name)
-        self.was_run = False
-
-      def Run(self, shared_state):
-        self.was_run = True
-        raise legacy_page_test.Failure
-
-      @property
-      def url(self):
-        return 'data:,'
-
-    self.SuppressExceptionFormatting()
-
-    story_set = story_module.StorySet()
-    for i in range(num_failing_stories):
-      story_set.AddStory(FailingStory(name='failing%d' % i))
-
-    options = _GetOptionForUnittest()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    if options_max_failures:
-      options.max_failures = options_max_failures
-
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(
-        DummyTest(), story_set, options,
-        results, max_failures=runner_max_failures)
-    self.assertEquals(0, GetNumberOfSuccessfulPageRuns(results))
-    self.assertEquals(expected_num_failures, len(results.failures))
-    for ii, story in enumerate(story_set.stories):
-      self.assertEqual(story.was_run, ii < expected_num_failures)
-
-  def testMaxFailuresNotSpecified(self):
-    self._testMaxFailuresOptionIsRespectedAndOverridable(
-        num_failing_stories=5, runner_max_failures=None,
-        options_max_failures=None, expected_num_failures=5)
-
-  def testMaxFailuresSpecifiedToRun(self):
-    # Runs up to max_failures+1 failing tests before stopping, since
-    # every tests after max_failures failures have been encountered
-    # may all be passing.
-    self._testMaxFailuresOptionIsRespectedAndOverridable(
-        num_failing_stories=5, runner_max_failures=3,
-        options_max_failures=None, expected_num_failures=4)
-
-  def testMaxFailuresOption(self):
-    # Runs up to max_failures+1 failing tests before stopping, since
-    # every tests after max_failures failures have been encountered
-    # may all be passing.
-    self._testMaxFailuresOptionIsRespectedAndOverridable(
-        num_failing_stories=5, runner_max_failures=3,
-        options_max_failures=1, expected_num_failures=2)
-
-  def _CreateErrorProcessingMock(self, method_exceptions=None,
-                                 legacy_test=False):
-    if legacy_test:
-      test_class = legacy_page_test.LegacyPageTest
-    else:
-      test_class = story_test.StoryTest
-
-    root_mock = mock.NonCallableMock(
-        story=mock.NonCallableMagicMock(story_module.Story),
-        results=mock.NonCallableMagicMock(page_test_results.PageTestResults),
-        test=mock.NonCallableMagicMock(test_class),
-        state=mock.NonCallableMagicMock(
-            story_module.SharedState,
-            CanRunStory=mock.Mock(return_value=True)))
-
-    if method_exceptions:
-      root_mock.configure_mock(**{
-          path + '.side_effect': exception
-          for path, exception in method_exceptions.iteritems()})
-
-    return root_mock
-
-  def testRunStoryAndProcessErrorIfNeeded_success(self):
-    root_mock = self._CreateErrorProcessingMock()
-
-    story_runner._RunStoryAndProcessErrorIfNeeded(
-        root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.RunStory(root_mock.results),
-      mock.call.test.Measure(root_mock.state.platform, root_mock.results),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform),
-      mock.call.state.platform.GetOSName(),
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_successLegacy(self):
-    root_mock = self._CreateErrorProcessingMock(legacy_test=True)
-
-    story_runner._RunStoryAndProcessErrorIfNeeded(
-        root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.RunStory(root_mock.results),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunPage(root_mock.state.platform),
-      mock.call.state.platform.GetOSName(),
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryTimeout(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'state.WillRunStory': exceptions.TimeoutException('foo')
-    })
-
-    story_runner._RunStoryAndProcessErrorIfNeeded(
-        root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results),
-      mock.call.results.AddValue(FailureValueMatcher('foo')),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform),
-      mock.call.state.platform.GetOSName(),
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryError(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'state.CanRunStory': exceptions.Error('foo')
-    })
-
-    with self.assertRaisesRegexp(exceptions.Error, 'foo'):
-      story_runner._RunStoryAndProcessErrorIfNeeded(
-          root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results),
-      mock.call.results.AddValue(FailureValueMatcher('foo')),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform),
-      mock.call.state.platform.GetOSName(),
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryUnsupportedAction(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'state.RunStory': page_action.PageActionNotSupported('foo')
-    })
-
-    story_runner._RunStoryAndProcessErrorIfNeeded(
-        root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.RunStory(root_mock.results),
-      mock.call.results.AddValue(SkipValueMatcher()),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform),
-      mock.call.state.platform.GetOSName(),
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryUnhandlable(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'test.WillRunStory': Exception('foo')
-    })
-
-    with self.assertRaisesRegexp(Exception, 'foo'):
-      story_runner._RunStoryAndProcessErrorIfNeeded(
-          root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results),
-      mock.call.results.AddValue(FailureValueMatcher('foo')),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform),
-      mock.call.state.platform.GetOSName(),
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_finallyException(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'state.DidRunStory': Exception('bar')
-    })
-
-    with self.assertRaisesRegexp(Exception, 'bar'):
-      story_runner._RunStoryAndProcessErrorIfNeeded(
-          root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.RunStory(root_mock.results),
-      mock.call.test.Measure(root_mock.state.platform, root_mock.results),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results)
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryTimeout_finallyException(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'state.RunStory': exceptions.TimeoutException('foo'),
-      'state.DidRunStory': Exception('bar')
-    })
-
-    story_runner._RunStoryAndProcessErrorIfNeeded(
-        root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.RunStory(root_mock.results),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results),
-      mock.call.results.AddValue(FailureValueMatcher('foo')),
-      mock.call.state.DidRunStory(root_mock.results)
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryError_finallyException(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'state.WillRunStory': exceptions.Error('foo'),
-      'test.DidRunStory': Exception('bar')
-    })
-
-    with self.assertRaisesRegexp(exceptions.Error, 'foo'):
-      story_runner._RunStoryAndProcessErrorIfNeeded(
-          root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results),
-      mock.call.results.AddValue(FailureValueMatcher('foo')),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform)
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryUnsupportedAction_finallyException(
-      self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'test.WillRunStory': page_action.PageActionNotSupported('foo'),
-      'state.DidRunStory': Exception('bar')
-    })
-
-    story_runner._RunStoryAndProcessErrorIfNeeded(
-        root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.results.AddValue(SkipValueMatcher()),
-      mock.call.state.DidRunStory(root_mock.results)
-    ])
-
-  def testRunStoryAndProcessErrorIfNeeded_tryUnhandlable_finallyException(self):
-    root_mock = self._CreateErrorProcessingMock(method_exceptions={
-      'test.Measure': Exception('foo'),
-      'test.DidRunStory': Exception('bar')
-    })
-
-    with self.assertRaisesRegexp(Exception, 'foo'):
-      story_runner._RunStoryAndProcessErrorIfNeeded(
-          root_mock.story, root_mock.results, root_mock.state, root_mock.test)
-
-    self.assertEquals(root_mock.method_calls, [
-      mock.call.state.platform.GetOSName(),
-      mock.call.test.WillRunStory(root_mock.state.platform),
-      mock.call.state.WillRunStory(root_mock.story),
-      mock.call.state.CanRunStory(root_mock.story),
-      mock.call.state.RunStory(root_mock.results),
-      mock.call.test.Measure(root_mock.state.platform, root_mock.results),
-      mock.call.state.DumpStateUponFailure(root_mock.story, root_mock.results),
-      mock.call.results.AddValue(FailureValueMatcher('foo')),
-      mock.call.state.DidRunStory(root_mock.results),
-      mock.call.test.DidRunStory(root_mock.state.platform)
-    ])
-
-  def testRunBenchmarkTimeDuration(self):
-    fake_benchmark = FakeBenchmark()
-    options = fakes.CreateBrowserFinderOptions()
-    options.upload_results = None
-    options.suppress_gtest_report = False
-    options.results_label = None
-    options.use_live_sites = False
-    options.max_failures = 100
-    options.pageset_repeat = 1
-    options.output_formats = ['chartjson']
-
-    with mock.patch('telemetry.internal.story_runner.time.time') as time_patch:
-      # 3, because telemetry code asks for the time at some point
-      time_patch.side_effect = [1, 0, 61]
-      tmp_path = tempfile.mkdtemp()
-
-      try:
-        options.output_dir = tmp_path
-        story_runner.RunBenchmark(fake_benchmark, options)
-        with open(os.path.join(tmp_path, 'results-chart.json')) as f:
-          data = json.load(f)
-
-        self.assertEqual(len(data['charts']), 1)
-        charts = data['charts']
-        self.assertIn('BenchmarkDuration', charts)
-        duration = charts['BenchmarkDuration']
-        self.assertIn("summary", duration)
-        summary = duration['summary']
-        duration = summary['value']
-        self.assertAlmostEqual(duration, 1)
-      finally:
-        shutil.rmtree(tmp_path)
diff --git a/catapult/telemetry/telemetry/internal/testing/.gitignore b/catapult/telemetry/telemetry/internal/testing/.gitignore
deleted file mode 100644
index 4842ffe..0000000
--- a/catapult/telemetry/telemetry/internal/testing/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-internal
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/__init__.py b/catapult/telemetry/telemetry/internal/testing/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/telemetry/internal/testing/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/telemetry/internal/testing/animated_page.html b/catapult/telemetry/telemetry/internal/testing/animated_page.html
deleted file mode 100644
index 3eb9502..0000000
--- a/catapult/telemetry/telemetry/internal/testing/animated_page.html
+++ /dev/null
@@ -1,21 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <style type="text/css">
-    @-webkit-keyframes rotating {
-      from{
-        -webkit-transform: rotate(0deg);
-      }
-      to{
-        -webkit-transform: rotate(360deg);
-      }
-    }
-    .rotating {
-      -webkit-animation: rotating 2s linear infinite;
-    }
-    </style>
-  </head>
-  <body>
-    <img src="image.png" class="rotating">
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/arch-lsb-release b/catapult/telemetry/telemetry/internal/testing/arch-lsb-release
deleted file mode 100644
index 1e02092..0000000
--- a/catapult/telemetry/telemetry/internal/testing/arch-lsb-release
+++ /dev/null
@@ -1,4 +0,0 @@
-LSB_VERSION=1.4
-DISTRIB_ID=Arch
-DISTRIB_RELEASE=rolling
-DISTRIB_DESCRIPTION="Arch Linux"
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test.json b/catapult/telemetry/telemetry/internal/testing/archive_files/test.json
deleted file mode 100644
index 1b7e6b8..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-    "archives": {
-        "http://www.testurl.com": {
-            "DEFAULT": "test_000.wpr"
-        }
-    },
-    "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
-    "platform_specific": true
-}
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test_000.wpr b/catapult/telemetry/telemetry/internal/testing/archive_files/test_000.wpr
deleted file mode 100644
index 32d459f..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test_000.wpr
+++ /dev/null
@@ -1 +0,0 @@
-File needed for story_runner_unittest testCheckArchives.
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test_000.wpr.sha1 b/catapult/telemetry/telemetry/internal/testing/archive_files/test_000.wpr.sha1
deleted file mode 100644
index e27e86d..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test_000.wpr.sha1
+++ /dev/null
@@ -1 +0,0 @@
-6bd6f4b08b44abc206f68471c0444df156d0fd1a
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test_missing_wpr_file.json b/catapult/telemetry/telemetry/internal/testing/archive_files/test_missing_wpr_file.json
deleted file mode 100644
index 3a64401..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test_missing_wpr_file.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "archives": {
-        "http://www.google.com": {
-            "DEFAULT": "test_missing_wpr_file.wpr"
-        },
-        "http://www.testurl.com": {
-            "DEFAULT": "test_000.wpr"
-        }
-    },
-    "description": "Describes the Web Page Replay archives for a story set. Don't edit by hand! Use record_wpr for updating.",
-    "platform_specific": true
-}
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test_page_set.py b/catapult/telemetry/telemetry/internal/testing/archive_files/test_page_set.py
deleted file mode 100644
index ec53709..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test_page_set.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import story
-from telemetry.page import page
-from telemetry.internal.testing.pages.external_page import ExternalPage
-
-
-class InternalPage(page.Page):
-  def __init__(self, story_set):
-    super(InternalPage, self).__init__('file://bar.html', story=story_set)
-
-class TestPageSet(story.StorySet):
-  """A pageset for testing purpose"""
-
-  def __init__(self):
-    super(TestPageSet, self).__init__(
-      archive_data_file='data/archive_files/test.json',
-      credentials_path='data/credential',
-      user_agent_type='desktop',
-      bucket=story.PUBLIC_BUCKET)
-
-    #top google property; a google tab is often open
-    class Google(page.Page):
-      def __init__(self, story_set):
-        # pylint: disable=bad-super-call
-        super(Google, self).__init__('https://www.google.com',
-                                     page_set=story_set)
-
-      def RunGetActionRunner(self, action_runner):
-        return action_runner
-
-    self.AddStory(Google(self))
-    self.AddStory(InternalPage(self))
-    self.AddStory(ExternalPage(self))
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test_simple_one_page_set.py b/catapult/telemetry/telemetry/internal/testing/archive_files/test_simple_one_page_set.py
deleted file mode 100644
index 4fb1198..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test_simple_one_page_set.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import story
-
-
-class TestSimpleOnePageSet(story.StorySet):
-  def __init__(self):
-    super(TestSimpleOnePageSet, self).__init__(
-      archive_data_file='data/archive_files/test.json',
-      credentials_path='data/credential')
diff --git a/catapult/telemetry/telemetry/internal/testing/archive_files/test_simple_two_page_set.py b/catapult/telemetry/telemetry/internal/testing/archive_files/test_simple_two_page_set.py
deleted file mode 100644
index c17c5f3..0000000
--- a/catapult/telemetry/telemetry/internal/testing/archive_files/test_simple_two_page_set.py
+++ /dev/null
@@ -1,12 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import story
-
-
-class TestSimpleTwoPageSet(story.StorySet):
-  def __init__(self):
-    super(TestSimpleTwoPageSet, self).__init__(
-      archive_data_file='data/archive_files/test.json',
-      credentials_path='data/credential')
diff --git a/catapult/telemetry/telemetry/internal/testing/autotest_ext/background.js b/catapult/telemetry/telemetry/internal/testing/autotest_ext/background.js
deleted file mode 100644
index 1513ac0..0000000
--- a/catapult/telemetry/telemetry/internal/testing/autotest_ext/background.js
+++ /dev/null
@@ -1,4 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
diff --git a/catapult/telemetry/telemetry/internal/testing/autotest_ext/manifest.json b/catapult/telemetry/telemetry/internal/testing/autotest_ext/manifest.json
deleted file mode 100644
index 1eb454e..0000000
--- a/catapult/telemetry/telemetry/internal/testing/autotest_ext/manifest.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDuUZGKCDbff6IRaxa4Pue7PPkxwPaNhGT3JEqppEsNWFjM80imEdqMbf3lrWqEfaHgaNku7nlpwPO1mu3/4Hr+XdNa5MhfnOnuPee4hyTLwOs3Vzz81wpbdzUxZSi2OmqMyI5oTaBYICfNHLwcuc65N5dbt6WKGeKgTpp4v7j7zwIDAQAB",
-  "description": "Telemetry ChromeOS Autotest component extension",
-  "name": "Telemetry ChromeOS AutoTest Component Extension",
-  "background": {
-    "scripts": ["background.js"]
-  },
-  "manifest_version": 2,
-  "version": "0.1",
-  "permissions" : [
-    "autotestPrivate"
-  ]
-}
diff --git a/catapult/telemetry/telemetry/internal/testing/bear.webm b/catapult/telemetry/telemetry/internal/testing/bear.webm
deleted file mode 100644
index a1b4150..0000000
--- a/catapult/telemetry/telemetry/internal/testing/bear.webm
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/blank.html b/catapult/telemetry/telemetry/internal/testing/blank.html
deleted file mode 100644
index 8d0ce09..0000000
--- a/catapult/telemetry/telemetry/internal/testing/blank.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-Hello world
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/blink_style.html b/catapult/telemetry/telemetry/internal/testing/blink_style.html
deleted file mode 100644
index 213020c..0000000
--- a/catapult/telemetry/telemetry/internal/testing/blink_style.html
+++ /dev/null
@@ -1,15 +0,0 @@
-<!DOCTYPE html>
-<body>
-Test Page for Blink Style measurement.
-<script>
-var css = '';
-for (var i = 0; i < 1000; i++) {
-  css += 'div { background: green }\n';
-}
-var style = document.createElement('style');
-style.textContent = css;
-document.head.appendChild(style);
-for (var i = 0; i < 1000; i++) {
-  document.body.appendChild(document.createElement('div'));
-}
-</script>
diff --git a/catapult/telemetry/telemetry/internal/testing/cast.html b/catapult/telemetry/telemetry/internal/testing/cast.html
deleted file mode 100644
index 80314a3..0000000
--- a/catapult/telemetry/telemetry/internal/testing/cast.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<!DOCTYPE HTML>
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <title>Media Router Dialog Test</title>
-    <script type="text/javascript">
-      'use strict';
-      var startSessionPromise = null;
-      var presentationUrl = 'http://www.google.com/#__testprovider__=true';
-      var startSessionRequest = new PresentationRequest(presentationUrl);
-      window.navigator.presentation.defaultRequest = startSessionRequest;
-
-      function startSession() {
-        startSessionPromise = startSessionRequest.start();
-        console.log('start session');
-      }
-    </script>
-  </head>
-  <body>
-    <button id="start_session_button" onclick="startSession()">
-      Start session
-    </button>
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/create_many_objects.html b/catapult/telemetry/telemetry/internal/testing/create_many_objects.html
deleted file mode 100644
index 4893563..0000000
--- a/catapult/telemetry/telemetry/internal/testing/create_many_objects.html
+++ /dev/null
@@ -1,20 +0,0 @@
-<!DOCTYPE html>
-<script>
-var maxObjects = 100000;
-
-var TestRunner = function() {
-  this.isDone = false;
-};
-
-var testRunner = null;
-window.onload = function () {
-  testRunner = new TestRunner();
-
-  // Create a lot of objects can trigger a Blink GC.
-  for (var i = 0; i < maxObjects; i++) {
-    new TextDecoder();
-  }
-
-  testRunner.isDone = true;
-}
-</script>
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/dog/dog/__init__.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/dog/dog/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/dog/dog/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/dog/dog/dog_object.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/dog/dog/dog_object.py
deleted file mode 100644
index dfba650..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/dog/dog/dog_object.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-sys.path.append(os.path.join(
-  os.path.dirname(__file__), '..', '..', 'other_animals', 'cat'))
-
-from cat import cat_object  # pylint: disable=import-error
-
-class Dog(object):
-  def CreateEnemy(self):
-    return cat_object.Cat()
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/cat/cat/__init__.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/cat/cat/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/cat/cat/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/cat/cat/cat_object.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/cat/cat/cat_object.py
deleted file mode 100644
index 41be7ba..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/cat/cat/cat_object.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class Cat(object):
-  def Run(self):
-    print 'Meow'
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/__init__.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/horn/__init__.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/horn/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/horn/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/horn/horn_object.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/horn/horn_object.py
deleted file mode 100644
index 1a883ef..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/horn/horn_object.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class Horn(object):
-  def IsBig(self):
-    return True
diff --git a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/moose_object.py b/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/moose_object.py
deleted file mode 100644
index 1e87ea4..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dependency_test_dir/other_animals/moose/moose/moose_object.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from horn import horn_object  # pylint: disable=relative-import
-
-class Moose(object):
-  def __init__(self):
-    self._horn = horn_object.Horn()
-
-  def Run(self):
-    if self._horn.IsBig():
-      print 'I need to drop my horn! It is big!'
diff --git a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/__init__.py b/catapult/telemetry/telemetry/internal/testing/discoverable_classes/__init__.py
deleted file mode 100644
index 9228df8..0000000
--- a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/another_discover_dummyclass.py b/catapult/telemetry/telemetry/internal/testing/discoverable_classes/another_discover_dummyclass.py
deleted file mode 100644
index 88581be..0000000
--- a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/another_discover_dummyclass.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""More dummy exception subclasses used by core/discover.py's unit tests."""
-
-# Import class instead of module explicitly so that inspect.getmembers() returns
-# two Exception subclasses in this current file.
-# Suppress complaints about unable to import class.  The directory path is
-# added at runtime by telemetry test runner.
-#pylint: disable=import-error
-from telemetry.internal.testing.discoverable_classes import discover_dummyclass
-
-
-class _PrivateDummyException(discover_dummyclass.DummyException):
-  def __init__(self):
-    super(_PrivateDummyException, self).__init__()
-
-
-class DummyExceptionImpl1(_PrivateDummyException):
-  def __init__(self):
-    super(DummyExceptionImpl1, self).__init__()
-
-
-class DummyExceptionImpl2(_PrivateDummyException):
-  def __init__(self):
-    super(DummyExceptionImpl2, self).__init__()
-
-
-class DummyExceptionWithParameterImpl1(_PrivateDummyException):
-  def __init__(self, parameter):
-    super(DummyExceptionWithParameterImpl1, self).__init__()
-    del parameter
diff --git a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/discover_dummyclass.py b/catapult/telemetry/telemetry/internal/testing/discoverable_classes/discover_dummyclass.py
deleted file mode 100644
index 15dcb35..0000000
--- a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/discover_dummyclass.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A dummy exception subclass used by core/discover.py's unit tests."""
-
-class DummyException(Exception):
-  def __init__(self):
-    super(DummyException, self).__init__()
diff --git a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/parameter_discover_dummyclass.py b/catapult/telemetry/telemetry/internal/testing/discoverable_classes/parameter_discover_dummyclass.py
deleted file mode 100644
index 3360fbd..0000000
--- a/catapult/telemetry/telemetry/internal/testing/discoverable_classes/parameter_discover_dummyclass.py
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A dummy exception subclass used by core/discover.py's unit tests."""
-from telemetry.internal.testing.discoverable_classes import discover_dummyclass
-
-class DummyExceptionWithParameterImpl2(discover_dummyclass.DummyException):
-  def __init__(self, parameter1, parameter2):
-    super(DummyExceptionWithParameterImpl2, self).__init__()
-    del parameter1, parameter2
diff --git a/catapult/telemetry/telemetry/internal/testing/dom_counter_sample.html b/catapult/telemetry/telemetry/internal/testing/dom_counter_sample.html
deleted file mode 100644
index 483d1e0..0000000
--- a/catapult/telemetry/telemetry/internal/testing/dom_counter_sample.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<html>
-  <title>DOM counter unit test page</title>
-  <body>
-    <h1 onclick="">Webpage to be used for DOM counter unit testing.</h1>
-    <p onclick="">
-      This webpage is meant to be used by a unit test that checks DOM element
-      counters.  The test expects there to be exactly 1 document, 14 nodes,
-      and 2 event listeners.  Beware, modifying the HTML of this page may
-      change the element count, causing the unit test to fail!
-    </p>
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/draggable.html b/catapult/telemetry/telemetry/internal/testing/draggable.html
deleted file mode 100644
index 8af37ba..0000000
--- a/catapult/telemetry/telemetry/internal/testing/draggable.html
+++ /dev/null
@@ -1,52 +0,0 @@
-<html>
-  <head>
-    <style>
-      body { margin: 0; }
-      #drag_div {
-        width: 100%;
-        height: 100%;
-        background: blue;
-        position: relative;
-      }
-    </style>
-    <script>
-    offsetX = 0;
-    offsetY = 0;
-
-    function drag(event) {
-      d = document.getElementById('drag_div');
-      offsetX = event.clientX - d.offsetLeft;
-      offsetY = event.clientY - d.offsetTop;
-    }
-
-    function drop(event) {
-      d = document.getElementById('drag_div');
-      d.style.left = event.clientX - offsetX;
-      d.style.top = event.clientY - offsetY;
-    }
-
-    function touchStart(event) {
-      d = document.getElementById('drag_div');
-      offsetX = event.touches[0].clientX - d.offsetLeft;
-      offsetY = event.touches[0].clientY - d.offsetTop;
-    }
-
-    function touchEnd(event) {
-      d = document.getElementById('drag_div');
-      d.style.left = event.changedTouches[0].clientX - offsetX;
-      d.style.top = event.changedTouches[0].clientY - offsetY;
-    }
-
-    </script>
-  </head>
-
-  <body id ="body">
-    <div id="drag_div"> </div>
-  </body>
-  <script>
-  document.getElementById('body').addEventListener('mouseup', drop);
-  document.getElementById('body').addEventListener('touchend', touchEnd);
-  document.getElementById('drag_div').addEventListener('mousedown', drag);
-  document.getElementById('drag_div').addEventListener('touchstart', touchStart);
-  </script>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/favicon.ico b/catapult/telemetry/telemetry/internal/testing/favicon.ico
deleted file mode 100644
index 0069d5d..0000000
--- a/catapult/telemetry/telemetry/internal/testing/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame0.png b/catapult/telemetry/telemetry/internal/testing/frame0.png
deleted file mode 100644
index 956b62c..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame0.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame1.png b/catapult/telemetry/telemetry/internal/testing/frame1.png
deleted file mode 100644
index 8f59394..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame1.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame2.png b/catapult/telemetry/telemetry/internal/testing/frame2.png
deleted file mode 100644
index f0bf178..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame2.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame3.png b/catapult/telemetry/telemetry/internal/testing/frame3.png
deleted file mode 100644
index f36b453..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame3.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame4.png b/catapult/telemetry/telemetry/internal/testing/frame4.png
deleted file mode 100644
index ef9d38a..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame4.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame5.png b/catapult/telemetry/telemetry/internal/testing/frame5.png
deleted file mode 100644
index ef1926d..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame5.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame6.png b/catapult/telemetry/telemetry/internal/testing/frame6.png
deleted file mode 100644
index 0a3028f..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame6.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/frame7.png b/catapult/telemetry/telemetry/internal/testing/frame7.png
deleted file mode 100644
index 9b6b6e5..0000000
--- a/catapult/telemetry/telemetry/internal/testing/frame7.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/green_rect.html b/catapult/telemetry/telemetry/internal/testing/green_rect.html
deleted file mode 100644
index 478c755..0000000
--- a/catapult/telemetry/telemetry/internal/testing/green_rect.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <style>
-  html, body {
-    margin: 0;
-    padding: 0;
-  }
-  #green {
-    width: 32px;
-    height: 32px;
-    background-color: rgb(0, 255, 0);
-  }
-  </style>
-</head>
-<body>
-  <div id="green"></div>
-</body>
-</html>
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/host.html b/catapult/telemetry/telemetry/internal/testing/host.html
deleted file mode 100644
index 46cfb06..0000000
--- a/catapult/telemetry/telemetry/internal/testing/host.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<script type="text/javascript">var testVar = "host";</script>
-</head>
-<body>
-This is the host page.
-<br>
-<iframe src="iframe1.html"></iframe>
-<iframe src="iframe3.html"></iframe>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/iframe1.html b/catapult/telemetry/telemetry/internal/testing/iframe1.html
deleted file mode 100644
index 972b8fb..0000000
--- a/catapult/telemetry/telemetry/internal/testing/iframe1.html
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<script type="text/javascript">var testVar="iframe1";</script>
-</head>
-<body>
-This is IFrame 1.
-<br>
-<iframe src="iframe2.html"></iframe>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/iframe2.html b/catapult/telemetry/telemetry/internal/testing/iframe2.html
deleted file mode 100644
index 778f8a0..0000000
--- a/catapult/telemetry/telemetry/internal/testing/iframe2.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<script type="text/javascript">var testVar="iframe2";</script>
-</head>
-<body>
-This is IFrame 2.
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/iframe3.html b/catapult/telemetry/telemetry/internal/testing/iframe3.html
deleted file mode 100644
index f992152..0000000
--- a/catapult/telemetry/telemetry/internal/testing/iframe3.html
+++ /dev/null
@@ -1,9 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<script type="text/javascript">var testVar="iframe3";</script>
-</head>
-<body>
-This is IFrame 3.
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/image.png b/catapult/telemetry/telemetry/internal/testing/image.png
deleted file mode 100644
index 82c2870..0000000
--- a/catapult/telemetry/telemetry/internal/testing/image.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/image_decoding.html b/catapult/telemetry/telemetry/internal/testing/image_decoding.html
deleted file mode 100644
index 59c1f0d..0000000
--- a/catapult/telemetry/telemetry/internal/testing/image_decoding.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-  <img src="image.png">
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/interaction_enabled_page.html b/catapult/telemetry/telemetry/internal/testing/interaction_enabled_page.html
deleted file mode 100644
index 761f912..0000000
--- a/catapult/telemetry/telemetry/internal/testing/interaction_enabled_page.html
+++ /dev/null
@@ -1,96 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <meta name="viewport" content="user-scalable:no">
-    <style type="text/css">
-      body { height: 1500px; }
-      #center {
-         position: fixed;
-         left: 40%;;
-         width: 50%;
-         height: 250px;
-         top: 25%;
-         background-color: grey;
-         -webkit-transform: scale(0.25, 0.25);
-         -webkit-transition: -webkit-transform 1s;
-      }
-
-      #drawer {
-         position: fixed;
-         top: 0;
-         left: 0;
-         height: 100%;
-         width: 120px;
-         background-color: red;
-         -webkit-transform: translate3d(-1000px, 0, 0);
-         -webkit-transition: -webkit-transform 1s;
-      }
-
-    </style>
-    <script>
-    'use strict';
-    window.animationDone = false;
-    function makeAnimation() {
-      var centerEl = document.querySelector('#center');
-      centerEl.style.webkitTransform = 'scale(1.0, 1.0)';
-      console.time('Interaction.CenterAnimation');
-      centerEl.addEventListener('transitionend', function() {
-        console.timeEnd('Interaction.CenterAnimation');
-        var drawerEl = document.querySelector('#drawer');
-        drawerEl.style.webkitTransform = 'translate3D(0, 0, 0)';
-        console.time('Interaction.DrawerAnimation');
-        drawerEl.addEventListener('transitionend', function() {
-          console.timeEnd('Interaction.DrawerAnimation');
-          window.animationDone = true;
-        });
-      });
-    }
-    </script>
-
-    <script>
-    'use strict';
-    var jankMs = 100;
-    var slowMs = 200;
-    window.jankScriptDone = false;
-    window.slowScriptDone = false;
-    function waitMs(ms) {
-      var startTime = window.performance.now();
-      var currTime = startTime;
-      while (currTime - startTime < ms) {
-        var currTime = window.performance.now();
-      }
-    }
-    function makeJank() {
-      console.time('Interaction.JankThreadJSRun');
-      waitMs(jankMs);
-      console.timeEnd('Interaction.JankThreadJSRun');
-      window.jankScriptDone = true;
-    }
-    function makeSlow() {
-      console.time('Interaction.SlowThreadJsRun');
-      waitMs(slowMs);
-      console.timeEnd('Interaction.SlowThreadJsRun');
-      window.slowScriptDone = true;
-    }
-    </script>
-
-  </head>
-  <body>
-    <div id="center">
-      This is something in the middle.
-    </div>
-    <div id="drawer">
-      This is a drawer.
-    </div>
-    <button type="button" id="animating-button" onclick="makeAnimation()">
-      Click or tap this to trigger an animation.
-    </div>
-    <button type="button" id="jank-button" onclick="makeJank()">
-      Click or tap this to make jank of 100ms (approximately).
-    </div>
-    <button type="button" id="slow-button" onclick="makeSlow()">
-      Click or tap this to make wait 200ms (approximately).
-    </div>
-
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/jebgalgnebhfojomionfpkfelancnnkf.crx b/catapult/telemetry/telemetry/internal/testing/jebgalgnebhfojomionfpkfelancnnkf.crx
deleted file mode 100644
index 4fb2a3b..0000000
--- a/catapult/telemetry/telemetry/internal/testing/jebgalgnebhfojomionfpkfelancnnkf.crx
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/manifest_with_key.json b/catapult/telemetry/telemetry/internal/testing/manifest_with_key.json
deleted file mode 100644
index 4b41dd4..0000000
--- a/catapult/telemetry/telemetry/internal/testing/manifest_with_key.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "name": "unpacked extension",
-  "description": "this is an unpacked extension with a key in it",
-  "version": "1",
-  "manifest_version": 2,
-  "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCoq+cJMuoIaoL2hx//QoIeHnNkXLAEu3IJGcLpM95qbmw9VnAplFI0tpSv4IpuJ1DPPsdsEMhONu1mPhK9xd3BHCtzqXRfRsnx/uOap4NTcUimxiUH3uuX9xkCNWO8EihdV0atnrKROhhnyIxmhgKmKfAYLheOrSGSXP0A4SqaBQIDAQAB"
-}
diff --git a/catapult/telemetry/telemetry/internal/testing/non_scrollable_page.html b/catapult/telemetry/telemetry/internal/testing/non_scrollable_page.html
deleted file mode 100644
index 5770408..0000000
--- a/catapult/telemetry/telemetry/internal/testing/non_scrollable_page.html
+++ /dev/null
@@ -1,10 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <style type="text/css">
-    </style>
-  </head>
-  <body>
-    Hello, world.
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/page_that_logs_to_console.html b/catapult/telemetry/telemetry/internal/testing/page_that_logs_to_console.html
deleted file mode 100644
index 373eebc..0000000
--- a/catapult/telemetry/telemetry/internal/testing/page_that_logs_to_console.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-<script>
-  window.__logCount = 0;
-  setInterval(function() {
-    console.log("Hello, world")
-    window.__logCount += 1
-  }, 100);
-</script>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/page_with_clickables.html b/catapult/telemetry/telemetry/internal/testing/page_with_clickables.html
deleted file mode 100644
index a1bfc07..0000000
--- a/catapult/telemetry/telemetry/internal/testing/page_with_clickables.html
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-<div id="test">Click/tap me</div>
-<script>
-var el = document.getElementById('test');
-var valueSettableByTest = 0;
-var valueToTest = 0;
-el.addEventListener('click', function() {
-  valueToTest = valueSettableByTest;
-});
-</script>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/page_with_link.html b/catapult/telemetry/telemetry/internal/testing/page_with_link.html
deleted file mode 100644
index dc3c008..0000000
--- a/catapult/telemetry/telemetry/internal/testing/page_with_link.html
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-</head>
-<body>
-<a id="clickme" href="blank.html">Click me</a>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/page_with_swipeables.html b/catapult/telemetry/telemetry/internal/testing/page_with_swipeables.html
deleted file mode 100644
index 8844bb9..0000000
--- a/catapult/telemetry/telemetry/internal/testing/page_with_swipeables.html
+++ /dev/null
@@ -1,53 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-<style>
-.swipeable {
-  overflow: scroll;
-  height: 200px;
-  width: 200px;
-}
-.left-right-item,
-.top-bottom-item {
-  height: 100px;
-  width: 100px;
-}
-.left-right-item {
-  display: inline-block;
-}
-.red-bg {
-  background-color: red;
-}
-.blue-bg {
-  background-color: blue;
-}
-.tall-and-wide {
-  background-color: grey;
-  height: 5000px;
-  width: 5000px;
-}
-</style>
-</head>
-<body>
-
-<div id="left-right" class="swipeable">
-  <div style="width: 1000px;">
-    <div class="left-right-item red-bg">Test</div>
-    <div class="left-right-item blue-bg">Test</div>
-    <div class="left-right-item red-bg">Test</div>
-    <div class="left-right-item blue-bg">Test</div>
-  </div>
-</div>
-
-<div id="top-bottom" class="swipeable">
-  <div class="top-bottom-item red-bg">Test</div>
-  <div class="top-bottom-item blue-bg">Test</div>
-  <div class="top-bottom-item red-bg">Test</div>
-  <div class="top-bottom-item blue-bg">Test</div>
-</div>
-
-<div class="tall-and-wide"></div>
-
-<div id="off-screen"></div>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/pages/__init__.py b/catapult/telemetry/telemetry/internal/testing/pages/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/telemetry/internal/testing/pages/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/telemetry/internal/testing/pages/external_page.py b/catapult/telemetry/telemetry/internal/testing/pages/external_page.py
deleted file mode 100755
index c0a1cf3..0000000
--- a/catapult/telemetry/telemetry/internal/testing/pages/external_page.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.page.page import Page
-
-
-class ExternalPage(Page):
-  def __init__(self, ps):
-    super(ExternalPage, self).__init__('file://foo.html', page_set=ps)
diff --git a/catapult/telemetry/telemetry/internal/testing/perf_report_output.txt b/catapult/telemetry/telemetry/internal/testing/perf_report_output.txt
deleted file mode 100644
index d9e9c44..0000000
--- a/catapult/telemetry/telemetry/internal/testing/perf_report_output.txt
+++ /dev/null
@@ -1,2497 +0,0 @@
-# ========
-# captured on: Thu Aug 15 09:40:36 2013
-# hostname : tonyg-linux.mtv.corp.google.com
-# os release : 3.2.5-gg1236
-# perf version : 3.2.5
-# arch : x86_64
-# nrcpus online : 32
-# nrcpus avail : 32
-# cpudesc : Intel(R) Xeon(R) CPU E5-2690 0 @ 2.90GHz
-# cpuid : GenuineIntel,6,45,7
-# total memory : 65904780 kB
-# cmdline : /usr/bin/perf_3.2.5-gg1236 record --call-graph --pid 20916 --output /tmp/tmprt1Qz7/http___www_techcrunch_com__001.renderer0 
-# event : name = cycles, type = 0, config = 0x0, config1 = 0x0, config2 = 0x0, excl_usr = 0, excl_kern = 0, id = { 40116, 40117, 40118, 40119, 40120, 40121, 40122, 40123, 40124 }
-# HEADER_CPU_TOPOLOGY info available, use -I to display
-# HEADER_NUMA_TOPOLOGY info available, use -I to display
-# ========
-#
-# Events: 825  cycles
-#
-# Overhead^Period^Command^Shared Object^Symbol
-3.22^96878864^HTMLParserThrea^chrome               ^[.] void v8::internal::RelocInfo::Visit<v8::internal::MarkCompactMarkingVisitor>(v8::internal::Heap*)
-            |
-            --- void v8::internal::RelocInfo::Visit<v8::internal::MarkCompactMarkingVisitor>(v8::internal::Heap*)
-
-2.11^63615201^HTMLParserThrea^chrome               ^[.] v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::MarkMapContents(v8::internal::Heap*, v8::internal::Map*)
-            |
-            --- v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::MarkMapContents(v8::internal::Heap*, v8::internal::Map*)
-
-1.60^48240439^HTMLParserThrea^chrome               ^[.] WebCore::HTMLTokenizer::nextToken(WebCore::SegmentedString&, WebCore::HTMLToken&)
-            |
-            --- WebCore::HTMLTokenizer::nextToken(WebCore::SegmentedString&, WebCore::HTMLToken&)
-               |          
-                --100.00%-- 0x3b2abdf74074
-
-1.53^46054550^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::ScanIdentifierOrKeyword()
-            |
-            --- v8::internal::Scanner::ScanIdentifierOrKeyword()
-               |          
-               |--33.87%-- 0x3b2abe3e3700
-               |          
-               |--33.85%-- 0x3b2abdf52240
-               |          
-                --32.28%-- 0x3b2abd766000
-
-1.50^45121317^HTMLParserThrea^chrome               ^[.] sk_memset32_SSE2(unsigned int*, unsigned int, int)
-            |
-            --- sk_memset32_SSE2(unsigned int*, unsigned int, int)
-
-1.43^42913933^HTMLParserThrea^chrome               ^[.] v8::internal::LiveRange::CreateAssignedOperand(v8::internal::Zone*)
-            |
-            --- v8::internal::LiveRange::CreateAssignedOperand(v8::internal::Zone*)
-
-1.43^42913933^HTMLParserThrea^chrome               ^[.] v8::internal::LAllocator::MeetConstraintsBetween(v8::internal::LInstruction*, v8::internal::LInstruction*, int)
-            |
-            --- v8::internal::LAllocator::MeetConstraintsBetween(v8::internal::LInstruction*, v8::internal::LInstruction*, int)
-
-1.32^39786862^HTMLParserThrea^chrome               ^[.] v8::internal::HeapObject::Size()
-            |
-            --- v8::internal::HeapObject::Size()
-               |          
-                --100.00%-- 0x1d00000015
-
-1.27^38271931^HTMLParserThrea^chrome               ^[.] v8::internal::RelocIterator::next()
-            |
-            --- v8::internal::RelocIterator::next()
-               |          
-               |--85.80%-- 0x228100000001
-               |          
-                --14.20%-- 0x7fff30e90200
-
-1.06^31909537^HTMLParserThrea^chrome               ^[.] v8::internal::FlexibleBodyVisitor<v8::internal::MarkCompactMarkingVisitor, v8::internal::FixedArray::BodyDescriptor, void>::Visit(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- v8::internal::FlexibleBodyVisitor<v8::internal::MarkCompactMarkingVisitor, v8::internal::FixedArray::BodyDescriptor, void>::Visit(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.98^29461075^HTMLParserThrea^chrome               ^[.] operator new(unsigned long)
-            |
-            --- operator new(unsigned long)
-
-0.88^26612604^HTMLParserThrea^chrome               ^[.] v8::internal::InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(unsigned char*)
-            |
-            --- v8::internal::InnerPointerToCodeCache::GcSafeFindCodeForInnerPointer(unsigned char*)
-
-0.83^25019326^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::Scan()
-            |
-            --- v8::internal::Scanner::Scan()
-               |          
-               |--31.35%-- 0x7fff30e9065000
-               |          
-               |--25.38%-- 0x7fff30e915a000
-               |          
-               |--22.29%-- 0x7fff30e9081000
-               |          
-                --20.99%-- 0x7fff30e91900
-                          0x900000001
-
-0.80^24225440^HTMLParserThrea^chrome               ^[.] WebCore::TokenPreloadScanner::scan(WebCore::CompactHTMLToken const&, WebCore::SegmentedString const&, WTF::Vector<WTF::OwnPtr<WebCore::PreloadRequest>, 0ul>&)
-            |
-            --- WebCore::TokenPreloadScanner::scan(WebCore::CompactHTMLToken const&, WebCore::SegmentedString const&, WTF::Vector<WTF::OwnPtr<WebCore::PreloadRequest>, 0ul>&)
-
-0.73^22115352^HTMLParserThrea^chrome               ^[.] v8::internal::DescriptorArray::Append(v8::internal::Descriptor*)
-            |
-            --- v8::internal::DescriptorArray::Append(v8::internal::Descriptor*)
-
-0.73^21947849^HTMLParserThrea^chrome               ^[.] v8::internal::HRepresentationChangesPhase::InsertRepresentationChangesForValue(v8::internal::HValue*)
-            |
-            --- v8::internal::HRepresentationChangesPhase::InsertRepresentationChangesForValue(v8::internal::HValue*)
-
-0.72^21805774^HTMLParserThrea^chrome               ^[.] SkBlitLCD16OpaqueRow_SSE2(unsigned int*, unsigned short const*, unsigned int, int, unsigned int)
-            |
-            --- SkBlitLCD16OpaqueRow_SSE2(unsigned int*, unsigned short const*, unsigned int, int, unsigned int)
-
-0.71^21252690^HTMLParserThrea^chrome               ^[.] int v8::internal::Search<(v8::internal::SearchMode)1, v8::internal::DescriptorArray>(v8::internal::DescriptorArray*, v8::internal::Name*, int)
-            |
-            --- int v8::internal::Search<(v8::internal::SearchMode)1, v8::internal::DescriptorArray>(v8::internal::DescriptorArray*, v8::internal::Name*, int)
-
-0.63^18864914^HTMLParserThrea^chrome               ^[.] v8::internal::HashTable<v8::internal::StringTableShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::Isolate*, v8::internal::HashTableKey*)
-            |
-            --- v8::internal::HashTable<v8::internal::StringTableShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::Isolate*, v8::internal::HashTableKey*)
-               |          
-                --100.00%-- 0x3b2abdff2b80
-
-0.56^16917055^HTMLParserThrea^chrome               ^[.] WebCore::LayoutUnit::LayoutUnit(int)
-            |
-            --- WebCore::LayoutUnit::LayoutUnit(int)
-               |          
-                --100.00%-- (nil)
-
-0.54^16308133^HTMLParserThrea^chrome               ^[.] event_base_loop
-            |
-            --- event_base_loop
-                0x7f7a0b959fc0
-                epoll_init
-                0x7265727265666572
-
-0.51^15412114^HTMLParserThrea^chrome               ^[.] tc_malloc
-            |
-            --- tc_malloc
-
-0.51^15239999^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::Next()
-            |
-            --- v8::internal::Scanner::Next()
-               |          
-               |--23.51%-- 0x7fff30e9054a
-               |          
-               |--23.51%-- 0x7fff30e906ca
-               |          
-               |--23.38%-- (nil)
-               |          
-               |--15.20%-- 0x7fff30e9081000
-               |          
-                --14.39%-- 0x7fff30e9048c
-
-0.47^14231099^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::DoScavenge(v8::internal::ObjectVisitor*, unsigned char*)
-            |
-            --- v8::internal::Heap::DoScavenge(v8::internal::ObjectVisitor*, unsigned char*)
-
-0.47^14229607^HTMLParserThrea^chrome               ^[.] bool WebCore::SelectorChecker::checkOne<WebCore::DOMSiblingTraversalStrategy>(WebCore::SelectorChecker::SelectorCheckingContext const&, WebCore::DOMSiblingTraversalStrategy const&) const
-            |
-            --- bool WebCore::SelectorChecker::checkOne<WebCore::DOMSiblingTraversalStrategy>(WebCore::SelectorChecker::SelectorCheckingContext const&, WebCore::DOMSiblingTraversalStrategy const&) const
-               |          
-               |--25.11%-- 0x1e83176cd048
-               |          
-               |--25.08%-- 0x7f7a0b9980e000
-               |          
-               |--24.93%-- 0x7f7a00000000
-               |          
-                --24.88%-- 0x7f7a0b997c9000
-
-0.46^13955450^HTMLParserThrea^chrome               ^[.] tc_realloc
-            |
-            --- tc_realloc
-
-0.46^13941187^HTMLParserThrea^chrome               ^[.] WebCore::minimumValueForLength(WebCore::Length const&, WebCore::LayoutUnit, WebCore::RenderView*, bool)
-            |
-            --- WebCore::minimumValueForLength(WebCore::Length const&, WebCore::LayoutUnit, WebCore::RenderView*, bool)
-
-0.46^13834654^HTMLParserThrea^chrome               ^[.] v8::internal::JSReceiver::LocalLookup(v8::internal::Name*, v8::internal::LookupResult*, bool)
-            |
-            --- v8::internal::JSReceiver::LocalLookup(v8::internal::Name*, v8::internal::LookupResult*, bool)
-               |          
-               |--33.05%-- 0x7fff30e91860
-               |          
-               |--26.80%-- (nil)
-               |          
-               |--20.72%-- 0x7fff30e91a10
-               |          
-                --19.43%-- 0x7fff30e90860
-
-0.44^13202625^HTMLParserThrea^chrome               ^[.] v8::internal::Expression::Expression(v8::internal::Isolate*)
-            |
-            --- v8::internal::Expression::Expression(v8::internal::Isolate*)
-               |          
-               |--35.68%-- 0x7fff30e9198000
-               |          
-               |--32.51%-- 0x7f7a00000000
-               |          
-                --31.81%-- (nil)
-
-0.44^13149418^HTMLParserThrea^chrome               ^[.] v8::internal::String::IsOneByteEqualTo(v8::internal::Vector<unsigned char const>)
-            |
-            --- v8::internal::String::IsOneByteEqualTo(v8::internal::Vector<unsigned char const>)
-
-0.43^13061272^HTMLParserThrea^chrome               ^[.] event_active
-            |
-            --- event_active
-                0x40
-
-0.43^12899765^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::Name*, v8::internal::LookupResult*)
-            |
-            --- v8::internal::JSObject::LocalLookupRealNamedProperty(v8::internal::Name*, v8::internal::LookupResult*)
-               |          
-               |--79.39%-- (nil)
-               |          
-                --20.61%-- 0x7fff30e90ab0
-
-0.42^12696531^HTMLParserThrea^chrome               ^[.] v8::internal::IsIdentifier(v8::internal::UnicodeCache*, v8::internal::Name*)
-            |
-            --- v8::internal::IsIdentifier(v8::internal::UnicodeCache*, v8::internal::Name*)
-
-0.41^12442842^HTMLParserThrea^chrome               ^[.] v8::internal::PointersUpdatingVisitor::VisitPointers(v8::internal::Object**, v8::internal::Object**)
-            |
-            --- v8::internal::PointersUpdatingVisitor::VisitPointers(v8::internal::Object**, v8::internal::Object**)
-
-0.41^12212739^HTMLParserThrea^chrome               ^[.] v8::internal::StubCompiler::CheckPrototypes(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Register, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Register, v8::internal::Register, v8::internal::Register, v8::internal::Handle<v8::internal::Name>, int, v8::internal::Label*, v8::internal::PrototypeCheckType)
-            |
-            --- v8::internal::StubCompiler::CheckPrototypes(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Register, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Register, v8::internal::Register, v8::internal::Register, v8::internal::Handle<v8::internal::Name>, int, v8::internal::Label*, v8::internal::PrototypeCheckType)
-               |          
-                --100.00%-- 0x29f988404121
-
-0.40^11929902^HTMLParserThrea^chrome               ^[.] _ZN2v88internal12BinarySearchILNS0_10SearchModeE1ENS0_15DescriptorArrayEEEiPT0_PNS0_4NameEiii.constprop.530
-            |
-            --- _ZN2v88internal12BinarySearchILNS0_10SearchModeE1ENS0_15DescriptorArrayEEEiPT0_PNS0_4NameEiii.constprop.530
-
-0.36^10844486^HTMLParserThrea^chrome               ^[.] content::VideoCaptureMessageFilter::OnMessageReceived(IPC::Message const&)
-            |
-            --- content::VideoCaptureMessageFilter::OnMessageReceived(IPC::Message const&)
-                0xfffffffc0000000e
-                IPC::ChannelProxy::Context::OnChannelConnected(int)
-                0x6c894cfb8948d824
-
-0.36^10745270^HTMLParserThrea^chrome               ^[.] v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitJSFunctionStrongCode(v8::internal::Heap*, v8::internal::HeapObject*)
-            |
-            --- v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitJSFunctionStrongCode(v8::internal::Heap*, v8::internal::HeapObject*)
-
-0.36^10717680^HTMLParserThrea^chrome               ^[.] v8::internal::TemplateHashMapImpl<v8::internal::ZoneAllocationPolicy>::Lookup(void*, unsigned int, bool, v8::internal::ZoneAllocationPolicy)
-            |
-            --- v8::internal::TemplateHashMapImpl<v8::internal::ZoneAllocationPolicy>::Lookup(void*, unsigned int, bool, v8::internal::ZoneAllocationPolicy)
-
-0.36^10710349^HTMLParserThrea^chrome               ^[.] v8::internal::Code::CopyFrom(v8::internal::CodeDesc const&)
-            |
-            --- v8::internal::Code::CopyFrom(v8::internal::CodeDesc const&)
-
-0.35^10674297^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseBinaryExpression(int, bool, bool*)
-            |
-            --- v8::internal::Parser::ParseBinaryExpression(int, bool, bool*)
-               |          
-               |--66.59%-- (nil)
-               |          
-                --33.41%-- 0x7f7a0b98e010
-
-0.35^10650066^HTMLParserThrea^chrome               ^[.] WebCore::SelectorFilter::pushParentStackFrame(WebCore::Element*)
-            |
-            --- WebCore::SelectorFilter::pushParentStackFrame(WebCore::Element*)
-
-0.35^10614251^HTMLParserThrea^libc-2.15.so         ^[.] __memcpy_ssse3_back
-            |
-            --- __memcpy_ssse3_back
-
-0.35^10611142^HTMLParserThrea^chrome               ^[.] v8::internal::GlobalHandles::ComputeObjectGroupsAndImplicitReferences()
-            |
-            --- v8::internal::GlobalHandles::ComputeObjectGroupsAndImplicitReferences()
-
-0.35^10527946^HTMLParserThrea^chrome               ^[.] tcmalloc::FL_PopRange(void**, int, void**, void**)
-            |
-            --- tcmalloc::FL_PopRange(void**, int, void**, void**)
-
-0.35^10514181^HTMLParserThrea^libpthread-2.15.so   ^[.] pthread_getspecific
-            |
-            --- pthread_getspecific
-
-0.35^10497704^HTMLParserThrea^chrome               ^[.] v8::internal::IC::PostPatching(unsigned char*, v8::internal::Code*, v8::internal::Code*)
-            |
-            --- v8::internal::IC::PostPatching(unsigned char*, v8::internal::Code*, v8::internal::Code*)
-
-0.35^10452932^HTMLParserThrea^chrome               ^[.] _ZN2v88internal12StringHasher13AddCharactersIhEEvPKT_i.constprop.518
-            |
-            --- _ZN2v88internal12StringHasher13AddCharactersIhEEvPKT_i.constprop.518
-
-0.35^10426463^HTMLParserThrea^chrome               ^[.] _ZN2v88internalL13LookupForReadENS0_6HandleINS0_6ObjectEEENS1_INS0_6StringEEEPNS0_12LookupResultE.constprop.171
-            |
-            --- _ZN2v88internalL13LookupForReadENS0_6HandleINS0_6ObjectEEENS1_INS0_6StringEEEPNS0_12LookupResultE.constprop.171
-               |          
-               |--65.70%-- (nil)
-               |          
-                --34.30%-- 0x7fff30e91e38
-
-0.34^10228287^HTMLParserThrea^chrome               ^[.] WTF::Unicode::convertLatin1ToUTF8(unsigned char const**, unsigned char const*, char**, char*)
-            |
-            --- WTF::Unicode::convertLatin1ToUTF8(unsigned char const**, unsigned char const*, char**, char*)
-               |          
-               |--34.63%-- 0x3b2abdeedb48
-               |          
-               |--32.97%-- webkit_glue::(anonymous namespace)::HeaderFlattener::visitHeader(WebKit::WebString const&, WebKit::WebString const&)
-               |          0x3b2abdfe9230
-               |          
-                --32.40%-- void WTF::StringBuilder::reallocateBuffer<unsigned char>(unsigned int)
-
-0.34^10139628^HTMLParserThrea^chrome               ^[.] base::subtle::RefCountedThreadSafeBase::Release() const
-            |
-            --- base::subtle::RefCountedThreadSafeBase::Release() const
-               |          
-               |--63.45%-- base::internal::Invoker<1, base::internal::BindState<base::internal::RunnableAdapter<void (base::BaseTimerTaskInternal::*)()>, void ()(base::BaseTimerTaskInternal*), void ()(base::internal::OwnedWrapper<base::BaseTimerTaskInternal>)>, void ()(base::BaseTimerTaskInternal*)>::Run(base::internal::BindStateBase*)
-               |          
-                --36.55%-- 0x7f7a0b8ff200
-
-0.33^9932889^HTMLParserThrea^chrome               ^[.] void WebCore::StyleResolver::applyProperties<(WebCore::StyleResolver::StyleApplicationPass)1>(WebCore::StyleResolverState&, WebCore::StylePropertySet const*, WebCore::StyleRule*, bool, bool, WebCore::PropertyWhitelistType)
-            |
-            --- void WebCore::StyleResolver::applyProperties<(WebCore::StyleResolver::StyleApplicationPass)1>(WebCore::StyleResolverState&, WebCore::StylePropertySet const*, WebCore::StyleRule*, bool, bool, WebCore::PropertyWhitelistType)
-
-0.33^9928749^HTMLParserThrea^chrome               ^[.] v8::internal::CodeStub::GetCode(v8::internal::Isolate*)
-            |
-            --- v8::internal::CodeStub::GetCode(v8::internal::Isolate*)
-
-0.33^9868335^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateSharedFunctionInfo(v8::internal::Object*)
-            |
-            --- v8::internal::Heap::AllocateSharedFunctionInfo(v8::internal::Object*)
-
-0.33^9807337^HTMLParserThrea^chrome               ^[.] v8::internal::Zone::New(int)
-            |
-            --- v8::internal::Zone::New(int)
-               |          
-                --100.00%-- 0x7fff30e91d48
-
-0.32^9579492^HTMLParserThrea^chrome               ^[.] v8::internal::Object::GetProperty(v8::internal::Object*, v8::internal::LookupResult*, v8::internal::Name*, PropertyAttributes*)
-            |
-            --- v8::internal::Object::GetProperty(v8::internal::Object*, v8::internal::LookupResult*, v8::internal::Name*, PropertyAttributes*)
-               |          
-               |--58.83%-- 0x2281c1418f41
-               |          
-                --41.17%-- (nil)
-
-0.32^9578890^HTMLParserThrea^chrome               ^[.] _ZN2v88internal15DescriptorArray3SetEiPNS0_10DescriptorERKNS1_16WhitenessWitnessE.isra.252
-            |
-            --- _ZN2v88internal15DescriptorArray3SetEiPNS0_10DescriptorERKNS1_16WhitenessWitnessE.isra.252
-
-0.31^9412432^HTMLParserThrea^chrome               ^[.] WebCore::ScrollView::unscaledVisibleContentSize(WebCore::ScrollableArea::VisibleContentRectIncludesScrollbars) const
-            |
-            --- WebCore::ScrollView::unscaledVisibleContentSize(WebCore::ScrollableArea::VisibleContentRectIncludesScrollbars) const
-
-0.31^9384389^HTMLParserThrea^chrome               ^[.] v8::internal::CallICBase::ReceiverToObjectIfRequired(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>)
-            |
-            --- v8::internal::CallICBase::ReceiverToObjectIfRequired(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>)
-               |          
-               |--37.40%-- 0x2281c141ab41
-               |          
-               |--35.85%-- 0x2281c1419541
-               |          
-                --26.75%-- 0x2281c141a941
-
-0.31^9309826^HTMLParserThrea^chrome               ^[.] v8::internal::Factory::NewFunctionFromSharedFunctionInfo(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::Context>, v8::internal::PretenureFlag)
-            |
-            --- v8::internal::Factory::NewFunctionFromSharedFunctionInfo(v8::internal::Handle<v8::internal::SharedFunctionInfo>, v8::internal::Handle<v8::internal::Context>, v8::internal::PretenureFlag)
-
-0.31^9238181^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseAssignmentExpression(bool, bool*)
-            |
-            --- v8::internal::Parser::ParseAssignmentExpression(bool, bool*)
-               |          
-               |--73.43%-- (nil)
-               |          
-                --26.57%-- 0x7fff30e9136000
-
-0.30^9076438^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject* WebCore::bidiNextShared<WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun> >(WebCore::RenderObject*, WebCore::RenderObject*, WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>*, WebCore::EmptyInlineBehavior, bool*)
-            |
-            --- WebCore::RenderObject* WebCore::bidiNextShared<WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun> >(WebCore::RenderObject*, WebCore::RenderObject*, WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>*, WebCore::EmptyInlineBehavior, bool*)
-               |          
-                --100.00%-- 0x3b2abd841928
-
-0.30^8941888^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateStruct(v8::internal::InstanceType)
-            |
-            --- v8::internal::Heap::AllocateStruct(v8::internal::InstanceType)
-
-0.29^8602723^HTMLParserThrea^chrome               ^[.] v8::internal::LoadIC::ComputeLoadHandler(v8::internal::LookupResult*, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::String>)
-            |
-            --- v8::internal::LoadIC::ComputeLoadHandler(v8::internal::LookupResult*, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::String>)
-               |          
-                --100.00%-- 0x7fff30e90648
-
-0.28^8470525^HTMLParserThrea^chrome               ^[.] void v8::internal::String::WriteToFlat<unsigned char>(v8::internal::String*, unsigned char*, int, int)
-            |
-            --- void v8::internal::String::WriteToFlat<unsigned char>(v8::internal::String*, unsigned char*, int, int)
-
-0.28^8366209^HTMLParserThrea^chrome               ^[.] WTF::StringImpl::hashSlowCase() const
-            |
-            --- WTF::StringImpl::hashSlowCase() const
-               |          
-               |--36.45%-- 0x7f7a11ebab98
-               |          0x7f7a0b9bd000
-               |          
-               |--33.90%-- 0xfffe02a2
-               |          0x1e83176903e8
-               |          
-                --29.65%-- 0x3b2abd1fa100
-
-0.27^8156738^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_ParallelRecompile(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_ParallelRecompile(int, v8::internal::Object**, v8::internal::Isolate*)
-                0x2281c142b871
-                0x2281c1f35545
-                0x2281c1f31dba
-                0x2281c140e854
-                0x2281c142b65e
-                0x2281c1417d97
-                v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.27^8131676^HTMLParserThrea^chrome               ^[.] v8::internal::FixedArray::set(int, v8::internal::Object*)
-            |
-            --- v8::internal::FixedArray::set(int, v8::internal::Object*)
-
-0.27^8075110^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateRaw(int, v8::internal::AllocationSpace, v8::internal::AllocationSpace)
-            |
-            --- v8::internal::Heap::AllocateRaw(int, v8::internal::AllocationSpace, v8::internal::AllocationSpace)
-
-0.26^7972021^HTMLParserThrea^chrome               ^[.] WebCore::MarkupAccumulator::appendCharactersReplacingEntities(WTF::StringBuilder&, WTF::String const&, unsigned int, unsigned int, WebCore::EntityMask)
-            |
-            --- WebCore::MarkupAccumulator::appendCharactersReplacingEntities(WTF::StringBuilder&, WTF::String const&, unsigned int, unsigned int, WebCore::EntityMask)
-
-0.25^7610316^HTMLParserThrea^chrome               ^[.] _ZN12_GLOBAL__N_121do_free_with_callbackEPvPFvS0_E.constprop.42
-            |
-            --- _ZN12_GLOBAL__N_121do_free_with_callbackEPvPFvS0_E.constprop.42
-
-0.25^7488722^HTMLParserThrea^chrome               ^[.] WebCore::NodeListV8Internal::indexedPropertyGetterCallback(unsigned int, v8::PropertyCallbackInfo<v8::Value> const&)
-            |
-            --- WebCore::NodeListV8Internal::indexedPropertyGetterCallback(unsigned int, v8::PropertyCallbackInfo<v8::Value> const&)
-                0x7f7a0b900000
-               |          
-                --100.00%-- 0x7f7a0b900000
-
-0.25^7420533^HTMLParserThrea^chrome               ^[.] webkit_glue::WebThreadBase::TaskObserverAdapter::DidProcessTask(base::PendingTask const&)
-            |
-            --- webkit_glue::WebThreadBase::TaskObserverAdapter::DidProcessTask(base::PendingTask const&)
-                0x7f7a0b8ff200
-
-0.24^7201464^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::computeRectForRepaint(WebCore::RenderLayerModelObject const*, WebCore::LayoutRect&, bool) const
-            |
-            --- WebCore::RenderBox::computeRectForRepaint(WebCore::RenderLayerModelObject const*, WebCore::LayoutRect&, bool) const
-               |          
-               |--50.28%-- 0x124000002bc0
-               |          
-                --49.72%-- 0x194000003e80
-
-0.24^7186236^HTMLParserThrea^chrome               ^[.] v8::internal::StoreBuffer::IteratePointersInStoreBuffer(void (*)(v8::internal::HeapObject**, v8::internal::HeapObject*), bool)
-            |
-            --- v8::internal::StoreBuffer::IteratePointersInStoreBuffer(void (*)(v8::internal::HeapObject**, v8::internal::HeapObject*), bool)
-
-0.24^7180913^HTMLParserThrea^chrome               ^[.] v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitJSFunction(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitJSFunction(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.24^7180572^HTMLParserThrea^chrome               ^[.] v8::internal::MarkCompactCollector::ClearNonLivePrototypeTransitions(v8::internal::Map*)
-            |
-            --- v8::internal::MarkCompactCollector::ClearNonLivePrototypeTransitions(v8::internal::Map*)
-
-0.24^7178618^HTMLParserThrea^chrome               ^[.] v8::internal::MarkCompactCollector::SweepSpace(v8::internal::PagedSpace*, v8::internal::MarkCompactCollector::SweeperType)
-            |
-            --- v8::internal::MarkCompactCollector::SweepSpace(v8::internal::PagedSpace*, v8::internal::MarkCompactCollector::SweeperType)
-
-0.24^7154254^HTMLParserThrea^chrome               ^[.] WTF::HashTableConstIterator<WebCore::RenderObject const*, WebCore::RenderObject const*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*> > WTF::HashTable<WebCore::RenderObject const*, WebCore::RenderObject const*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*>, WTF::HashTraits
-            |
-            --- WTF::HashTableConstIterator<WebCore::RenderObject const*, WebCore::RenderObject const*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*> > WTF::HashTable<WebCore::RenderObject const*, WebCore::RenderObject const*, WTF::IdentityExtractor, WTF::PtrHash<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*>, WTF::HashTraits<WebCore::RenderObject const*> >::find<WTF::IdentityHashTranslator<WTF::PtrHash<WebCore::RenderObject const*> >, WebCore::RenderObject const*>(WebCore::RenderObject const* const&) const
-
-0.24^7150261^HTMLParserThrea^chrome               ^[.] void url_parse::(anonymous namespace)::DoParseAuthority<char>(char const*, url_parse::Component const&, url_parse::Component*, url_parse::Component*, url_parse::Component*, url_parse::Component*)
-            |
-            --- void url_parse::(anonymous namespace)::DoParseAuthority<char>(char const*, url_parse::Component const&, url_parse::Component*, url_parse::Component*, url_parse::Component*, url_parse::Component*)
-               |          
-                --100.00%-- 0xffffffff00000000
-
-0.24^7147589^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateFixedArray(int)
-            |
-            --- v8::internal::Heap::AllocateFixedArray(int)
-
-0.24^7145279^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::MustAllocate(v8::internal::Variable*)
-            |
-            --- v8::internal::Scope::MustAllocate(v8::internal::Variable*)
-
-0.24^7140300^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::fillAvailableMeasure(WebCore::LayoutUnit, WebCore::LayoutUnit&, WebCore::LayoutUnit&) const
-            |
-            --- WebCore::RenderBox::fillAvailableMeasure(WebCore::LayoutUnit, WebCore::LayoutUnit&, WebCore::LayoutUnit&) const
-
-0.24^7139300^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::computeInlinePreferredLogicalWidths(WebCore::LayoutUnit&, WebCore::LayoutUnit&)
-            |
-            --- WebCore::RenderBlock::computeInlinePreferredLogicalWidths(WebCore::LayoutUnit&, WebCore::LayoutUnit&)
-
-0.24^7134579^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::ScanString()
-            |
-            --- v8::internal::Scanner::ScanString()
-
-0.24^7132161^HTMLParserThrea^chrome               ^[.] WebCore::ElementRuleCollector::collectRuleIfMatches(WebCore::RuleData const&, WebCore::MatchRequest const&, WebCore::RuleRange&)
-            |
-            --- WebCore::ElementRuleCollector::collectRuleIfMatches(WebCore::RuleData const&, WebCore::MatchRequest const&, WebCore::RuleRange&)
-
-0.24^7127556^HTMLParserThrea^chrome               ^[.] v8::internal::TemplateHashMapImpl<v8::internal::FreeStoreAllocationPolicy>::Lookup(void*, unsigned int, bool, v8::internal::FreeStoreAllocationPolicy)
-            |
-            --- v8::internal::TemplateHashMapImpl<v8::internal::FreeStoreAllocationPolicy>::Lookup(void*, unsigned int, bool, v8::internal::FreeStoreAllocationPolicy)
-
-0.24^7124874^HTMLParserThrea^chrome               ^[.] url_canon::RemoveURLWhitespace(char const*, int, url_canon::CanonOutputT<char>*, int*)
-            |
-            --- url_canon::RemoveURLWhitespace(char const*, int, url_canon::CanonOutputT<char>*, int*)
-
-0.24^7120126^HTMLParserThrea^chrome               ^[.] v8::internal::RelocInfoWriter::Write(v8::internal::RelocInfo const*)
-            |
-            --- v8::internal::RelocInfoWriter::Write(v8::internal::RelocInfo const*)
-
-0.24^7115866^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseMemberWithNewPrefixesExpression(v8::internal::PositionStack*, bool*)
-            |
-            --- v8::internal::Parser::ParseMemberWithNewPrefixesExpression(v8::internal::PositionStack*, bool*)
-               |          
-               |--50.15%-- 0x7fff30e9065000
-               |          
-                --49.85%-- 0x7fff30e914d000
-
-0.24^7113138^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::AddFastPropertyUsingMap(v8::internal::Map*, v8::internal::Name*, v8::internal::Object*, int, v8::internal::Representation)
-            |
-            --- v8::internal::JSObject::AddFastPropertyUsingMap(v8::internal::Map*, v8::internal::Name*, v8::internal::Object*, int, v8::internal::Representation)
-
-0.24^7106943^HTMLParserThrea^chrome               ^[.] v8::internal::StoreBuffer::Compact()
-            |
-            --- v8::internal::StoreBuffer::Compact()
-
-0.24^7104154^HTMLParserThrea^chrome               ^[.] WebCore::VisitedLinkState::determineLinkStateSlowCase(WebCore::Element*)
-            |
-            --- WebCore::VisitedLinkState::determineLinkStateSlowCase(WebCore::Element*)
-
-0.24^7089266^HTMLParserThrea^chrome               ^[.] WebCore::selectorIdentifierHash(WebCore::CSSSelector const*)
-            |
-            --- WebCore::selectorIdentifierHash(WebCore::CSSSelector const*)
-
-0.24^7086923^HTMLParserThrea^chrome               ^[.] v8::internal::InnerPointerToCodeCache::GetCacheEntry(unsigned char*)
-            |
-            --- v8::internal::InnerPointerToCodeCache::GetCacheEntry(unsigned char*)
-               |          
-                --100.00%-- 0x7fff30e912c0
-                          0xc6a3430a8a9
-
-0.24^7081815^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseUnaryExpression(bool*)
-            |
-            --- v8::internal::Parser::ParseUnaryExpression(bool*)
-                (nil)
-
-0.24^7079188^HTMLParserThrea^chrome               ^[.] WebCore::SelectorFilter::fastRejectSelector(WebCore::CSSSelector const*) const
-            |
-            --- WebCore::SelectorFilter::fastRejectSelector(WebCore::CSSSelector const*) const
-
-0.24^7077714^HTMLParserThrea^chrome               ^[.] v8::internal::CallICBase::LoadFunction(v8::internal::InlineCacheState, int, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::String>)
-            |
-            --- v8::internal::CallICBase::LoadFunction(v8::internal::InlineCacheState, int, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::String>)
-               |          
-               |--50.54%-- 0x7fff30e90d30
-               |          
-                --49.46%-- 0x7fff30e90270
-
-0.23^7065769^HTMLParserThrea^chrome               ^[.] WebCore::RenderBoxModelObject::computedCSSPadding(WebCore::Length) const
-            |
-            --- WebCore::RenderBoxModelObject::computedCSSPadding(WebCore::Length) const
-
-0.23^7059576^HTMLParserThrea^chrome               ^[.] v8::internal::Deserializer::ReadChunk(v8::internal::Object**, v8::internal::Object**, int, unsigned char*)
-            |
-            --- v8::internal::Deserializer::ReadChunk(v8::internal::Object**, v8::internal::Object**, int, unsigned char*)
-                0x7f7a0b900000
-
-0.23^7058229^HTMLParserThrea^chrome               ^[.] visitedlink::VisitedLinkCommon::IsVisited(unsigned long) const
-            |
-            --- visitedlink::VisitedLinkCommon::IsVisited(unsigned long) const
-
-0.23^7051436^HTMLParserThrea^chrome               ^[.] v8::internal::AllocateFixedArrayWithFiller(v8::internal::Heap*, int, v8::internal::PretenureFlag, v8::internal::Object*)
-            |
-            --- v8::internal::AllocateFixedArrayWithFiller(v8::internal::Heap*, int, v8::internal::PretenureFlag, v8::internal::Object*)
-
-0.23^7043481^HTMLParserThrea^chrome               ^[.] v8::internal::FuncNameInferrer::PushLiteralName(v8::internal::Handle<v8::internal::String>)
-            |
-            --- v8::internal::FuncNameInferrer::PushLiteralName(v8::internal::Handle<v8::internal::String>)
-
-0.23^7023232^HTMLParserThrea^chrome               ^[.] v8::internal::VariableProxy::VariableProxy(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>, bool, v8::internal::Interface*, int)
-            |
-            --- v8::internal::VariableProxy::VariableProxy(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>, bool, v8::internal::Interface*, int)
-               |          
-                --100.00%-- 0x7fff30e90ed8
-
-0.23^7022335^HTMLParserThrea^chrome               ^[.] WebCore::V8CSSStyleDeclaration::createWrapper(WTF::PassRefPtr<WebCore::CSSStyleDeclaration>, v8::Handle<v8::Object>, v8::Isolate*)
-            |
-            --- WebCore::V8CSSStyleDeclaration::createWrapper(WTF::PassRefPtr<WebCore::CSSStyleDeclaration>, v8::Handle<v8::Object>, v8::Isolate*)
-                0x7f7a0b93a3c0
-
-0.23^7015773^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::LineBreaker::nextSegmentBreak(WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>&, WebCore::LineInfo&, WebCore::RenderBlock::RenderTextInfo&, WebCore::RenderBlock::FloatingObject*, unsigned int, WTF::Vector<WebCore::WordMeasurement, 64ul>&)
-            |
-            --- WebCore::RenderBlock::LineBreaker::nextSegmentBreak(WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>&, WebCore::LineInfo&, WebCore::RenderBlock::RenderTextInfo&, WebCore::RenderBlock::FloatingObject*, unsigned int, WTF::Vector<WebCore::WordMeasurement, 64ul>&)
-
-0.23^7009841^HTMLParserThrea^chrome               ^[.] v8::internal::CodeCache::LookupDefaultCache(v8::internal::Name*, unsigned int)
-            |
-            --- v8::internal::CodeCache::LookupDefaultCache(v8::internal::Name*, unsigned int)
-
-0.23^6940000^HTMLParserThrea^chrome               ^[.] v8::internal::PositionsRecorder::RecordPosition(int)
-            |
-            --- v8::internal::PositionsRecorder::RecordPosition(int)
-
-0.23^6866416^HTMLParserThrea^chrome               ^[.] _ZN2v88internal6Parser25ParseVariableDeclarationsENS1_26VariableDeclarationContextEPNS1_29VariableDeclarationPropertiesEPNS0_8ZoneListINS0_6HandleINS0_6StringEEEEEPS8_Pb.constprop.454
-            |
-            --- _ZN2v88internal6Parser25ParseVariableDeclarationsENS1_26VariableDeclarationContextEPNS1_29VariableDeclarationPropertiesEPNS0_8ZoneListINS0_6HandleINS0_6StringEEEEEPS8_Pb.constprop.454
-
-0.23^6858851^HTMLParserThrea^chrome               ^[.] S32A_Opaque_BlitRow32_SSE2(unsigned int*, unsigned int const*, int, unsigned int)
-            |
-            --- S32A_Opaque_BlitRow32_SSE2(unsigned int*, unsigned int const*, int, unsigned int)
-
-0.23^6846415^HTMLParserThrea^chrome               ^[.] v8::internal::String::SlowEquals(v8::internal::String*)
-            |
-            --- v8::internal::String::SlowEquals(v8::internal::String*)
-
-0.22^6771375^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::Expect(v8::internal::Token::Value, bool*)
-            |
-            --- v8::internal::Parser::Expect(v8::internal::Token::Value, bool*)
-               |          
-               |--52.15%-- 0x7fff30e905d002
-               |          
-                --47.85%-- (nil)
-
-0.22^6645010^HTMLParserThrea^chrome               ^[.] v8::internal::DeoptimizerData::FindDeoptimizingCode(unsigned char*)
-            |
-            --- v8::internal::DeoptimizerData::FindDeoptimizingCode(unsigned char*)
-
-0.22^6627879^HTMLParserThrea^chrome               ^[.] v8::internal::StoreIC::Store(v8::internal::InlineCacheState, v8::internal::StrictModeFlag, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::Object>, v8::internal::JSReceiver::StoreFromKeyed)
-            |
-            --- v8::internal::StoreIC::Store(v8::internal::InlineCacheState, v8::internal::StrictModeFlag, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::Object>, v8::internal::JSReceiver::StoreFromKeyed)
-               |          
-               |--53.63%-- 0xc6a34268609
-               |          
-                --46.37%-- 0xc6a34ea2a81
-
-0.22^6600293^HTMLParserThrea^chrome               ^[.] WTF::HashTableAddResult<WTF::HashTableIterator<WTF::AtomicString, WTF::AtomicString, WTF::IdentityExtractor, WTF::AtomicStringHash, WTF::HashTraits<WTF::AtomicString>, WTF::HashTraits<WTF::AtomicString> > > WTF::HashTable<WTF::AtomicString, WTF::AtomicString, WTF::IdentityExtractor, WTF::AtomicStringHash, WTF::HashTraits<WTF::AtomicString>, WTF::HashTraits<WTF::AtomicString> >::add<WTF::IdentityHashTranslator<WTF::AtomicStringHash>, WTF::AtomicString, 
-            |
-            --- WTF::HashTableAddResult<WTF::HashTableIterator<WTF::AtomicString, WTF::AtomicString, WTF::IdentityExtractor, WTF::AtomicStringHash, WTF::HashTraits<WTF::AtomicString>, WTF::HashTraits<WTF::AtomicString> > > WTF::HashTable<WTF::AtomicString, WTF::AtomicString, WTF::IdentityExtractor, WTF::AtomicStringHash, WTF::HashTraits<WTF::AtomicString>, WTF::HashTraits<WTF::AtomicString> >::add<WTF::IdentityHashTranslator<WTF::AtomicStringHash>, WTF::AtomicString, WTF::AtomicString>(WTF::AtomicString const&, WTF::AtomicString const&)
-
-0.22^6596875^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::bind(v8::internal::Label*)
-            |
-            --- v8::internal::Assembler::bind(v8::internal::Label*)
-
-0.22^6594480^HTMLParserThrea^chrome               ^[.] WebCore::InspectorInstrumentation::instrumentingAgentsForPage(WebCore::Page*)
-            |
-            --- WebCore::InspectorInstrumentation::instrumentingAgentsForPage(WebCore::Page*)
-
-0.22^6579973^HTMLParserThrea^chrome               ^[.] v8::internal::IC::PatchCache(v8::internal::InlineCacheState, v8::internal::StrictModeFlag, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::Code>)
-            |
-            --- v8::internal::IC::PatchCache(v8::internal::InlineCacheState, v8::internal::StrictModeFlag, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::Code>)
-               |          
-               |--54.27%-- 0x29f988404121
-               |          
-                --45.73%-- 0xc6a3487f2f1
-
-0.22^6576754^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::movq(v8::internal::Register, v8::internal::Handle<v8::internal::Object>, v8::internal::RelocInfo::Mode)
-            |
-            --- v8::internal::Assembler::movq(v8::internal::Register, v8::internal::Handle<v8::internal::Object>, v8::internal::RelocInfo::Mode)
-
-0.22^6564875^HTMLParserThrea^libpthread-2.15.so   ^[.] pthread_mutex_lock
-            |
-            --- pthread_mutex_lock
-
-0.22^6559671^HTMLParserThrea^chrome               ^[.] v8::internal::VariableProxy::node_type() const
-            |
-            --- v8::internal::VariableProxy::node_type() const
-
-0.22^6543901^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_NewClosure(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_NewClosure(int, v8::internal::Object**, v8::internal::Isolate*)
-               |          
-                --100.00%-- 0x2281c1ab1279
-                          0x2281c142b664
-                          0x2281c1417d97
-                          v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.22^6487316^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateConsString(v8::internal::String*, v8::internal::String*)
-            |
-            --- v8::internal::Heap::AllocateConsString(v8::internal::String*, v8::internal::String*)
-
-0.21^6470256^HTMLParserThrea^chrome               ^[.] v8::internal::StringTable::LookupOneByteString(v8::internal::Vector<unsigned char const>, v8::internal::Object**)
-            |
-            --- v8::internal::StringTable::LookupOneByteString(v8::internal::Vector<unsigned char const>, v8::internal::Object**)
-
-0.21^6461476^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::SetLocalPropertyIgnoreAttributes(v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::Object::ValueType)
-            |
-            --- v8::internal::JSObject::SetLocalPropertyIgnoreAttributes(v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::Object::ValueType)
-
-0.21^6410633^HTMLParserThrea^chrome               ^[.] v8::internal::BaseLoadStoreStubCompiler::CompilePolymorphicIC(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::List<v8::internal::Handle<v8::internal::Code>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::Handle<v8::internal::Name>, v8::internal::Code::StubType, v8::internal::IcCheckType)
-            |
-            --- v8::internal::BaseLoadStoreStubCompiler::CompilePolymorphicIC(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::List<v8::internal::Handle<v8::internal::Code>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::Handle<v8::internal::Name>, v8::internal::Code::StubType, v8::internal::IcCheckType)
-                0x7f7a0b900000
-
-0.21^6354296^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseExpressionOrLabelledStatement(v8::internal::ZoneList<v8::internal::Handle<v8::internal::String> >*, bool*)
-            |
-            --- v8::internal::Parser::ParseExpressionOrLabelledStatement(v8::internal::ZoneList<v8::internal::Handle<v8::internal::String> >*, bool*)
-               |          
-               |--55.30%-- 0x7fff30e9145000
-               |          
-                --44.70%-- 0x7fff30e906e000
-
-0.21^6319435^HTMLParserThrea^chrome               ^[.] _ZN2v88internal14NameDictionary9FindEntryEPNS0_4NameE.part.385
-            |
-            --- _ZN2v88internal14NameDictionary9FindEntryEPNS0_4NameE.part.385
-               |          
-                --100.00%-- (nil)
-
-0.21^6243685^HTMLParserThrea^chrome               ^[.] WebCore::Font::glyphDataAndPageForCharacter(int, bool, WebCore::FontDataVariant) const
-            |
-            --- WebCore::Font::glyphDataAndPageForCharacter(int, bool, WebCore::FontDataVariant) const
-                0x7fff30e8f0e0
-
-0.20^6145083^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::AccumulatorValueContext::Plug(v8::internal::Register) const
-            |
-            --- v8::internal::FullCodeGenerator::AccumulatorValueContext::Plug(v8::internal::Register) const
-
-0.20^6137312^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::SetPropertyForResult(v8::internal::LookupResult*, v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::StrictModeFlag, v8::internal::JSReceiver::StoreFromKeyed)
-            |
-            --- v8::internal::JSObject::SetPropertyForResult(v8::internal::LookupResult*, v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::StrictModeFlag, v8::internal::JSReceiver::StoreFromKeyed)
-
-0.20^6135468^HTMLParserThrea^chrome               ^[.] v8::internal::Factory::NewNumber(double, v8::internal::PretenureFlag)
-            |
-            --- v8::internal::Factory::NewNumber(double, v8::internal::PretenureFlag)
-               |          
-                --100.00%-- 0x7fff30e9160000
-
-0.20^6051127^HTMLParserThrea^chrome               ^[.] WebCore::WidthIterator::glyphDataForCharacter(int, bool, int, unsigned int&)
-            |
-            --- WebCore::WidthIterator::glyphDataForCharacter(int, bool, int, unsigned int&)
-               |          
-               |--58.44%-- 0x7fff30e8cfa0
-               |          
-                --41.56%-- 0x7fff30e8f550
-
-0.20^6000454^HTMLParserThrea^chrome               ^[.] v8::internal::CodeCache::UpdateDefaultCache(v8::internal::Name*, v8::internal::Code*)
-            |
-            --- v8::internal::CodeCache::UpdateDefaultCache(v8::internal::Name*, v8::internal::Code*)
-               |          
-                --100.00%-- 0xc6a355788f1
-
-0.20^5976974^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject::containingBlock() const
-            |
-            --- WebCore::RenderObject::containingBlock() const
-
-0.20^5926952^HTMLParserThrea^chrome               ^[.] v8::internal::GlobalHandles::Create(v8::internal::Object*)
-            |
-            --- v8::internal::GlobalHandles::Create(v8::internal::Object*)
-
-0.20^5880116^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseLeftHandSideExpression(bool*)
-            |
-            --- v8::internal::Parser::ParseLeftHandSideExpression(bool*)
-               |          
-                --100.00%-- 0x7fff30e9151000
-
-0.19^5834557^HTMLParserThrea^chrome               ^[.] WebCore::CachedRawResource::willSendRequest(WebCore::ResourceRequest&, WebCore::ResourceResponse const&)
-            |
-            --- WebCore::CachedRawResource::willSendRequest(WebCore::ResourceRequest&, WebCore::ResourceResponse const&)
-
-0.18^5527800^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&)
-            |
-            --- WebCore::RenderBlock::paint(WebCore::PaintInfo&, WebCore::LayoutPoint const&)
-
-0.18^5461500^HTMLParserThrea^chrome               ^[.] WebCore::Document::updateStyleIfNeeded()
-            |
-            --- WebCore::Document::updateStyleIfNeeded()
-
-0.18^5428693^HTMLParserThrea^libc-2.15.so         ^[.] __memset_sse2
-            |
-            --- __memset_sse2
-
-0.18^5423805^HTMLParserThrea^chrome               ^[.] WebCore::FrameView::paintContents(WebCore::GraphicsContext*, WebCore::IntRect const&)
-            |
-            --- WebCore::FrameView::paintContents(WebCore::GraphicsContext*, WebCore::IntRect const&)
-               |          
-               |--61.15%-- 0x5a000002d8
-               |          
-                --38.85%-- 0x2e00000092
-
-0.18^5363793^HTMLParserThrea^chrome               ^[.] WebCore::HTTPHeaderMap::get(WTF::AtomicString const&) const
-            |
-            --- WebCore::HTTPHeaderMap::get(WTF::AtomicString const&) const
-
-0.18^5306454^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::Scope(v8::internal::Scope*, v8::internal::ScopeType, v8::internal::Zone*)
-            |
-            --- v8::internal::Scope::Scope(v8::internal::Scope*, v8::internal::ScopeType, v8::internal::Zone*)
-
-0.18^5274362^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::bind_to(v8::internal::Label*, int)
-            |
-            --- v8::internal::Assembler::bind_to(v8::internal::Label*, int)
-               |          
-                --100.00%-- 0x3b2abd7c3000
-
-0.18^5270432^HTMLParserThrea^chrome               ^[.] SkDraw::drawPosText(char const*, unsigned long, float const*, float, int, SkPaint const&) const
-            |
-            --- SkDraw::drawPosText(char const*, unsigned long, float const*, float, int, SkPaint const&) const
-                (nil)
-               |          
-               |--55.20%-- 0x4f005200260003
-               |          
-                --44.80%-- 0x52004a00440003
-
-0.17^5196475^HTMLParserThrea^chrome               ^[.] WTF::equalNonNull(WTF::StringImpl const*, WTF::StringImpl const*)
-            |
-            --- WTF::equalNonNull(WTF::StringImpl const*, WTF::StringImpl const*)
-                0x7f7a0b975100
-
-0.17^5103842^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::convertToLayerCoords(WebCore::RenderLayer const*, WebCore::LayoutPoint&) const
-            |
-            --- WebCore::RenderLayer::convertToLayerCoords(WebCore::RenderLayer const*, WebCore::LayoutPoint&) const
-
-0.17^4967343^HTMLParserThrea^chrome               ^[.] _ZN2v88internal4ListINS0_16FuncNameInferrer4NameENS0_20ZoneAllocationPolicyEE3AddERKS3_S4_.constprop.51
-            |
-            --- _ZN2v88internal4ListINS0_16FuncNameInferrer4NameENS0_20ZoneAllocationPolicyEE3AddERKS3_S4_.constprop.51
-
-0.16^4900762^HTMLParserThrea^libc-2.15.so         ^[.] __memcmp_sse4_1
-            |
-            --- __memcmp_sse4_1
-               |          
-                --100.00%-- 0x7f7a0b975100
-
-0.15^4610114^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::GetPropertyWithCallback(v8::internal::Object*, v8::internal::Object*, v8::internal::Name*)
-            |
-            --- v8::internal::JSObject::GetPropertyWithCallback(v8::internal::Object*, v8::internal::Object*, v8::internal::Name*)
-
-0.15^4535632^HTMLParserThrea^chrome               ^[.] v8::HandleScope::HandleScope()
-            |
-            --- v8::HandleScope::HandleScope()
-
-0.15^4419717^HTMLParserThrea^chrome               ^[.] WebCore::MarkupAccumulator::appendStartTag(WebCore::Node*, WTF::HashMap<WTF::AtomicStringImpl*, WTF::AtomicStringImpl*, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*> >*)
-            |
-            --- WebCore::MarkupAccumulator::appendStartTag(WebCore::Node*, WTF::HashMap<WTF::AtomicStringImpl*, WTF::AtomicStringImpl*, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*> >*)
-
-0.14^4269939^HTMLParserThrea^chrome               ^[.] cssyyparse(WebCore::CSSParser*)
-            |
-            --- cssyyparse(WebCore::CSSParser*)
-               |          
-               |--56.10%-- content::PepperGraphics2DHost::Paint(SkCanvas*, gfx::Rect const&, gfx::Rect const&)
-               |          
-                --43.90%-- 0x1b800000b600
-
-0.14^4189741^HTMLParserThrea^chrome               ^[.] v8::internal::HandleScope::Extend(v8::internal::Isolate*)
-            |
-            --- v8::internal::HandleScope::Extend(v8::internal::Isolate*)
-
-0.13^3989323^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::overflowRectForPaintRejection() const
-            |
-            --- WebCore::RenderBox::overflowRectForPaintRejection() const
-
-0.12^3691476^HTMLParserThrea^libstdc++.so.6.0.16  ^[.] std::_Rb_tree_increment(std::_Rb_tree_node_base*)
-            |
-            --- std::_Rb_tree_increment(std::_Rb_tree_node_base*)
-
-0.12^3619871^HTMLParserThrea^chrome               ^[.] WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(WebCore::ContainerNode*)
-            |
-            --- WebCore::ChildNodeInsertionNotifier::notifyDescendantInsertedIntoTree(WebCore::ContainerNode*)
-                (nil)
-
-0.12^3610233^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::addLayoutOverflow(WebCore::LayoutRect const&)
-            |
-            --- WebCore::RenderBox::addLayoutOverflow(WebCore::LayoutRect const&)
-
-0.12^3602214^HTMLParserThrea^chrome               ^[.] v8::internal::RelocIterator::RelocIterator(v8::internal::Code*, int)
-            |
-            --- v8::internal::RelocIterator::RelocIterator(v8::internal::Code*, int)
-
-0.12^3592533^HTMLParserThrea^chrome               ^[.] v8::internal::MarkCompactCollector::MigrateObject(unsigned char*, unsigned char*, int, v8::internal::AllocationSpace)
-            |
-            --- v8::internal::MarkCompactCollector::MigrateObject(unsigned char*, unsigned char*, int, v8::internal::AllocationSpace)
-
-0.12^3591487^HTMLParserThrea^chrome               ^[.] v8::internal::StringTableCleaner::VisitPointers(v8::internal::Object**, v8::internal::Object**)
-            |
-            --- v8::internal::StringTableCleaner::VisitPointers(v8::internal::Object**, v8::internal::Object**)
-
-0.12^3590966^HTMLParserThrea^chrome               ^[.] v8::internal::MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage(v8::internal::NewSpace*, v8::internal::NewSpacePage*)
-            |
-            --- v8::internal::MarkCompactCollector::DiscoverAndPromoteBlackObjectsOnPage(v8::internal::NewSpace*, v8::internal::NewSpacePage*)
-
-0.12^3590884^HTMLParserThrea^chrome               ^[.] v8::internal::MarkCompactCollector::ClearNonLiveReferences()
-            |
-            --- v8::internal::MarkCompactCollector::ClearNonLiveReferences()
-
-0.12^3590478^HTMLParserThrea^chrome               ^[.] void std::__introsort_loop<v8::internal::ObjectGroupConnection*, long>(v8::internal::ObjectGroupConnection*, v8::internal::ObjectGroupConnection*, long)
-            |
-            --- void std::__introsort_loop<v8::internal::ObjectGroupConnection*, long>(v8::internal::ObjectGroupConnection*, v8::internal::ObjectGroupConnection*, long)
-
-0.12^3590200^HTMLParserThrea^chrome               ^[.] v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitPropertyCell(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitPropertyCell(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.12^3589094^HTMLParserThrea^chrome               ^[.] long v8::internal::MarkCompactCollector::SweepConservatively<(v8::internal::MarkCompactCollector::SweepingParallelism)0>(v8::internal::PagedSpace*, v8::internal::FreeList*, v8::internal::Page*)
-            |
-            --- long v8::internal::MarkCompactCollector::SweepConservatively<(v8::internal::MarkCompactCollector::SweepingParallelism)0>(v8::internal::PagedSpace*, v8::internal::FreeList*, v8::internal::Page*)
-
-0.12^3589023^HTMLParserThrea^chrome               ^[.] WebCore::RenderStyle::~RenderStyle()
-            |
-            --- WebCore::RenderStyle::~RenderStyle()
-
-0.12^3588259^HTMLParserThrea^chrome               ^[.] v8::internal::FlexibleBodyVisitor<v8::internal::MarkCompactMarkingVisitor, v8::internal::JSObject::BodyDescriptor, void>::Visit(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- v8::internal::FlexibleBodyVisitor<v8::internal::MarkCompactMarkingVisitor, v8::internal::JSObject::BodyDescriptor, void>::Visit(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.12^3588121^HTMLParserThrea^chrome               ^[.] v8::internal::GlobalHandles::IterateWeakRoots(v8::internal::ObjectVisitor*)
-            |
-            --- v8::internal::GlobalHandles::IterateWeakRoots(v8::internal::ObjectVisitor*)
-
-0.12^3587651^HTMLParserThrea^chrome               ^[.] v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::MarkTransitionArray(v8::internal::Heap*, v8::internal::TransitionArray*)
-            |
-            --- v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::MarkTransitionArray(v8::internal::Heap*, v8::internal::TransitionArray*)
-
-0.12^3585248^HTMLParserThrea^chrome               ^[.] v8::internal::SequentialStringKey<unsigned char>::Hash()
-            |
-            --- v8::internal::SequentialStringKey<unsigned char>::Hash()
-
-0.12^3584278^HTMLParserThrea^chrome               ^[.] v8::internal::ChoiceNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)
-            |
-            --- v8::internal::ChoiceNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)
-                0x3b2abd5271d8
-
-0.12^3583348^HTMLParserThrea^chrome               ^[.] v8::internal::LoadIC::UpdateMonomorphicIC(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Code>, v8::internal::Handle<v8::internal::String>, v8::internal::StrictModeFlag)
-            |
-            --- v8::internal::LoadIC::UpdateMonomorphicIC(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Code>, v8::internal::Handle<v8::internal::String>, v8::internal::StrictModeFlag)
-                0xc6a34dd2791
-
-0.12^3582808^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseIfStatement(v8::internal::ZoneList<v8::internal::Handle<v8::internal::String> >*, bool*)
-            |
-            --- v8::internal::Parser::ParseIfStatement(v8::internal::ZoneList<v8::internal::Handle<v8::internal::String> >*, bool*)
-                0x3b2abdf3f010
-
-0.12^3582142^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::addOverflowFromInlineChildren()
-            |
-            --- WebCore::RenderBlock::addOverflowFromInlineChildren()
-
-0.12^3581759^HTMLParserThrea^chrome               ^[.] _ZN7WebCore10RenderText29computePreferredLogicalWidthsEfRN3WTF7HashSetIPKNS_14SimpleFontDataENS1_7PtrHashIS5_EENS1_10HashTraitsIS5_EEEERNS_13GlyphOverflowE.part.184
-            |
-            --- _ZN7WebCore10RenderText29computePreferredLogicalWidthsEfRN3WTF7HashSetIPKNS_14SimpleFontDataENS1_7PtrHashIS5_EENS1_10HashTraitsIS5_EEEERNS_13GlyphOverflowE.part.184
-
-0.12^3581038^HTMLParserThrea^chrome               ^[.] WTF::String WebCore::v8StringToWebCoreString<WTF::String>(v8::Handle<v8::String>, WebCore::ExternalMode)
-            |
-            --- WTF::String WebCore::v8StringToWebCoreString<WTF::String>(v8::Handle<v8::String>, WebCore::ExternalMode)
-                0xc6a34d43fe9
-
-0.12^3581023^HTMLParserThrea^chrome               ^[.] WebCore::RenderInline::marginLeft() const
-            |
-            --- WebCore::RenderInline::marginLeft() const
-
-0.12^3580522^HTMLParserThrea^chrome               ^[.] WTF::Vector<WebCore::GraphicsContext::DeferredSaveState, 0ul>::expandCapacity(unsigned long)
-            |
-            --- WTF::Vector<WebCore::GraphicsContext::DeferredSaveState, 0ul>::expandCapacity(unsigned long)
-                0x100017718028
-
-0.12^3580338^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_MaterializeRegExpLiteral(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_MaterializeRegExpLiteral(int, v8::internal::Object**, v8::internal::Isolate*)
-
-0.12^3579940^HTMLParserThrea^chrome               ^[.] v8::internal::FunctionLiteral::AllowsLazyCompilation()
-            |
-            --- v8::internal::FunctionLiteral::AllowsLazyCompilation()
-
-0.12^3579555^HTMLParserThrea^chrome               ^[.] WebCore::XMLHttpRequest::isAllowedHTTPMethod(WTF::String const&)
-            |
-            --- WebCore::XMLHttpRequest::isAllowedHTTPMethod(WTF::String const&)
-                0x7f7a0b900000
-
-0.12^3579477^HTMLParserThrea^chrome               ^[.] ppapi::PpapiGlobals::Get()
-            |
-            --- ppapi::PpapiGlobals::Get()
-
-0.12^3579477^HTMLParserThrea^chrome               ^[.] v8::internal::StaticVisitorBase::GetVisitorId(int, int)
-            |
-            --- v8::internal::StaticVisitorBase::GetVisitorId(int, int)
-
-0.12^3578703^HTMLParserThrea^chrome               ^[.] v8::internal::LoadIC::ComputePolymorphicIC(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::List<v8::internal::Handle<v8::internal::Code>, v8::internal::FreeStoreAllocationPolicy>*, int, v8::internal::Handle<v8::internal::Name>, v8::internal::StrictModeFlag)
-            |
-            --- v8::internal::LoadIC::ComputePolymorphicIC(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::List<v8::internal::Handle<v8::internal::Code>, v8::internal::FreeStoreAllocationPolicy>*, int, v8::internal::Handle<v8::internal::Name>, v8::internal::StrictModeFlag)
-                0xc6a354cfa21
-
-0.12^3578592^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::BuildObjectLiteralConstantProperties(v8::internal::ZoneList<v8::internal::ObjectLiteralProperty*>*, v8::internal::Handle<v8::internal::FixedArray>, bool*, bool*, int*, bool*)
-            |
-            --- v8::internal::Parser::BuildObjectLiteralConstantProperties(v8::internal::ZoneList<v8::internal::ObjectLiteralProperty*>*, v8::internal::Handle<v8::internal::FixedArray>, bool*, bool*, int*, bool*)
-
-0.12^3578004^HTMLParserThrea^chrome               ^[.] v8::internal::StubCache::ComputePolymorphicLoadIC(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::List<v8::internal::Handle<v8::internal::Code>, v8::internal::FreeStoreAllocationPolicy>*, int, v8::internal::Handle<v8::internal::Name>)
-            |
-            --- v8::internal::StubCache::ComputePolymorphicLoadIC(v8::internal::List<v8::internal::Handle<v8::internal::Map>, v8::internal::FreeStoreAllocationPolicy>*, v8::internal::List<v8::internal::Handle<v8::internal::Code>, v8::internal::FreeStoreAllocationPolicy>*, int, v8::internal::Handle<v8::internal::Name>)
-                0xc6a3444c2a9
-
-0.12^3577719^HTMLParserThrea^chrome               ^[.] v8::internal::BoyerMooreLookahead::FindBestInterval(int, int, int*, int*)
-            |
-            --- v8::internal::BoyerMooreLookahead::FindBestInterval(int, int, int*, int*)
-
-0.12^3577405^HTMLParserThrea^chrome               ^[.] WebCore::RenderBoxModelObject::continuation() const
-            |
-            --- WebCore::RenderBoxModelObject::continuation() const
-
-0.12^3576942^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::hasPercentHeightDescendant(WebCore::RenderBox*)
-            |
-            --- WebCore::RenderBlock::hasPercentHeightDescendant(WebCore::RenderBox*)
-
-0.12^3575468^HTMLParserThrea^chrome               ^[.] v8::internal::VariableProxy* v8::internal::Scope::NewUnresolved<v8::internal::AstConstructionVisitor>(v8::internal::AstNodeFactory<v8::internal::AstConstructionVisitor>*, v8::internal::Handle<v8::internal::String>, v8::internal::Interface*, int)
-            |
-            --- v8::internal::VariableProxy* v8::internal::Scope::NewUnresolved<v8::internal::AstConstructionVisitor>(v8::internal::AstNodeFactory<v8::internal::AstConstructionVisitor>*, v8::internal::Handle<v8::internal::String>, v8::internal::Interface*, int)
-                0x7fff30e91928
-
-0.12^3575428^HTMLParserThrea^chrome               ^[.] WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>::createBidiRunsForLine(WebCore::InlineIterator const&, WebCore::VisualDirectionOverride, bool)
-            |
-            --- WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>::createBidiRunsForLine(WebCore::InlineIterator const&, WebCore::VisualDirectionOverride, bool)
-                0x3b2abd843120
-
-0.12^3574896^HTMLParserThrea^chrome               ^[.] v8::internal::FixedArray::set(int, v8::internal::Object*, v8::internal::WriteBarrierMode)
-            |
-            --- v8::internal::FixedArray::set(int, v8::internal::Object*, v8::internal::WriteBarrierMode)
-
-0.12^3574498^HTMLParserThrea^chrome               ^[.] v8::internal::String::Equals(v8::internal::String*)
-            |
-            --- v8::internal::String::Equals(v8::internal::String*)
-
-0.12^3574405^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::ExpressionContext::IsTest() const
-            |
-            --- v8::internal::FullCodeGenerator::ExpressionContext::IsTest() const
-
-0.12^3574327^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::ResolveVariable(v8::internal::CompilationInfo*, v8::internal::VariableProxy*, v8::internal::AstNodeFactory<v8::internal::AstNullVisitor>*)
-            |
-            --- v8::internal::Scope::ResolveVariable(v8::internal::CompilationInfo*, v8::internal::VariableProxy*, v8::internal::AstNodeFactory<v8::internal::AstNullVisitor>*)
-
-0.12^3573789^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateMap(v8::internal::InstanceType, int, v8::internal::ElementsKind)
-            |
-            --- v8::internal::Heap::AllocateMap(v8::internal::InstanceType, int, v8::internal::ElementsKind)
-
-0.12^3573631^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime::CreateArrayLiteralBoilerplate(v8::internal::Isolate*, v8::internal::Handle<v8::internal::FixedArray>, v8::internal::Handle<v8::internal::FixedArray>)
-            |
-            --- v8::internal::Runtime::CreateArrayLiteralBoilerplate(v8::internal::Isolate*, v8::internal::Handle<v8::internal::FixedArray>, v8::internal::Handle<v8::internal::FixedArray>)
-
-0.12^3573214^HTMLParserThrea^chrome               ^[.] WTF::HashTableIterator<WebCore::CachedResource*, WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*>, WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::HashTraits<WebCore::Cache
-            |
-            --- WTF::HashTableIterator<WebCore::CachedResource*, WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*>, WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::HashTraits<WebCore::CachedResource*> > WTF::HashTable<WebCore::CachedResource*, WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*>, WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::HashTraits<WebCore::CachedResource*> >::find<WTF::IdentityHashTranslator<WTF::PtrHash<WebCore::CachedResource*> >, WebCore::CachedResource*>(WebCore::CachedResource* const&)
-
-0.12^3573010^HTMLParserThrea^chrome               ^[.] Pickle::Resize(unsigned long)
-            |
-            --- Pickle::Resize(unsigned long)
-
-0.12^3572646^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::floatingObjects() const
-            |
-            --- WebCore::RenderBlock::floatingObjects() const
-
-0.12^3572547^HTMLParserThrea^chrome               ^[.] WebCore::LiveNodeListBase::item(unsigned int) const
-            |
-            --- WebCore::LiveNodeListBase::item(unsigned int) const
-
-0.12^3572456^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::computeLogicalHeight(WebCore::LayoutUnit, WebCore::LayoutUnit, WebCore::RenderBox::LogicalExtentComputedValues&) const
-            |
-            --- WebCore::RenderBox::computeLogicalHeight(WebCore::LayoutUnit, WebCore::LayoutUnit, WebCore::RenderBox::LogicalExtentComputedValues&) const
-                (nil)
-
-0.12^3572406^HTMLParserThrea^chrome               ^[.] WebCore::ScriptController::callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int, v8::Handle<v8::Value>*)
-            |
-            --- WebCore::ScriptController::callFunction(v8::Handle<v8::Function>, v8::Handle<v8::Object>, int, v8::Handle<v8::Value>*)
-
-0.12^3571839^HTMLParserThrea^chrome               ^[.] WTF::HashTableAddResult<WTF::HashTableIterator<WTF::AtomicStringImpl*, WTF::KeyValuePair<WTF::AtomicStringImpl*, WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::AtomicStringImpl*, WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > > >, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashMapValueTraits<WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleDa
-            |
-            --- WTF::HashTableAddResult<WTF::HashTableIterator<WTF::AtomicStringImpl*, WTF::KeyValuePair<WTF::AtomicStringImpl*, WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::AtomicStringImpl*, WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > > >, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashMapValueTraits<WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > > >, WTF::HashTraits<WTF::AtomicStringImpl*> > > WTF::HashTable<WTF::AtomicStringImpl*, WTF::KeyValuePair<WTF::AtomicStringImpl*, WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::AtomicStringImpl*, WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > > >, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashMapValueTraits<WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > > >, WTF::HashTraits<WTF::AtomicStringImpl*> >::add<WTF::HashMapTranslator<WTF::HashMapValueTraits<WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::OwnPtr<WTF::LinkedStack<WebCore::RuleData> > > >, WTF::PtrHash<WTF::AtomicStringImpl*> >, WTF::AtomicStringImpl*, WTF::PassOwnPtr<WTF::LinkedStack<WebCore::RuleData> > >(WTF::AtomicStringImpl* const&, WTF::PassOwnPtr<WTF::LinkedStack<WebCore::RuleData> > const&)
-
-0.12^3571626^HTMLParserThrea^chrome               ^[.] v8::internal::Factory::ObjectLiteralMapFromCache(v8::internal::Handle<v8::internal::Context>, v8::internal::Handle<v8::internal::FixedArray>)
-            |
-            --- v8::internal::Factory::ObjectLiteralMapFromCache(v8::internal::Handle<v8::internal::Context>, v8::internal::Handle<v8::internal::FixedArray>)
-
-0.12^3571455^HTMLParserThrea^chrome               ^[.] WebCore::RenderView::intervalArena()
-            |
-            --- WebCore::RenderView::intervalArena()
-
-0.12^3571267^HTMLParserThrea^chrome               ^[.] v8::internal::VarAndOrder::Compare(v8::internal::VarAndOrder const*, v8::internal::VarAndOrder const*)
-            |
-            --- v8::internal::VarAndOrder::Compare(v8::internal::VarAndOrder const*, v8::internal::VarAndOrder const*)
-
-0.12^3570914^HTMLParserThrea^chrome               ^[.] bool WebCore::shouldInvalidateNodeListCachesForAttr<2u>(unsigned int const*, WebCore::QualifiedName const&)
-            |
-            --- bool WebCore::shouldInvalidateNodeListCachesForAttr<2u>(unsigned int const*, WebCore::QualifiedName const&)
-
-0.12^3570523^HTMLParserThrea^chrome               ^[.] v8::internal::CodeCacheHashTableKey::IsMatch(v8::internal::Object*)
-            |
-            --- v8::internal::CodeCacheHashTableKey::IsMatch(v8::internal::Object*)
-
-0.12^3570308^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::hasRelativeDimensions() const
-            |
-            --- WebCore::RenderBox::hasRelativeDimensions() const
-
-0.12^3570109^HTMLParserThrea^chrome               ^[.] WTF::HashMap<WTF::AtomicStringImpl*, WTF::OwnPtr<WebCore::RuleData>, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::OwnPtr<WebCore::RuleData> > >::get(WTF::AtomicStringImpl* const&) const
-            |
-            --- WTF::HashMap<WTF::AtomicStringImpl*, WTF::OwnPtr<WebCore::RuleData>, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::OwnPtr<WebCore::RuleData> > >::get(WTF::AtomicStringImpl* const&) const
-                void WTF::Vector<WebCore::StyleRule*, 64ul>::appendSlowCase<WebCore::StyleRule*>(WebCore::StyleRule* const&)
-
-0.12^3569976^HTMLParserThrea^chrome               ^[.] v8::internal::IC::address() const
-            |
-            --- v8::internal::IC::address() const
-
-0.12^3569735^HTMLParserThrea^chrome               ^[.] v8::internal::StringTable::LookupUtf8String(v8::internal::Vector<char const>, v8::internal::Object**)
-            |
-            --- v8::internal::StringTable::LookupUtf8String(v8::internal::Vector<char const>, v8::internal::Object**)
-
-0.12^3569690^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::updateLogicalWidthForAlignment(WebCore::ETextAlign const&, WebCore::BidiRun*, float&, float&, float&, int)
-            |
-            --- WebCore::RenderBlock::updateLogicalWidthForAlignment(WebCore::ETextAlign const&, WebCore::BidiRun*, float&, float&, float&, int)
-
-0.12^3569632^HTMLParserThrea^chrome               ^[.] content::GetContentClient()
-            |
-            --- content::GetContentClient()
-                WebCore::Node::invalidateNodeListCachesInAncestors(WebCore::QualifiedName const*, WebCore::Element*)
-
-0.12^3569389^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::SkipSingleLineComment()
-            |
-            --- v8::internal::Scanner::SkipSingleLineComment()
-
-0.12^3568302^HTMLParserThrea^chrome               ^[.] v8::internal::PagedSpace::AllocateRaw(int)
-            |
-            --- v8::internal::PagedSpace::AllocateRaw(int)
-                0x5d00001000
-
-0.12^3567675^HTMLParserThrea^chrome               ^[.] v8::internal::HashTable<v8::internal::NameDictionaryShape, v8::internal::Name*>::FindEntry(v8::internal::Isolate*, v8::internal::Name*)
-            |
-            --- v8::internal::HashTable<v8::internal::NameDictionaryShape, v8::internal::Name*>::FindEntry(v8::internal::Isolate*, v8::internal::Name*)
-
-0.12^3567487^HTMLParserThrea^chrome               ^[.] WebCore::ImageLoader::updateFromElement()
-            |
-            --- WebCore::ImageLoader::updateFromElement()
-
-0.12^3567473^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject::localToContainerQuad(WebCore::FloatQuad const&, WebCore::RenderLayerModelObject const*, unsigned int, bool*) const
-            |
-            --- WebCore::RenderObject::localToContainerQuad(WebCore::FloatQuad const&, WebCore::RenderLayerModelObject const*, unsigned int, bool*) const
-
-0.12^3567274^HTMLParserThrea^chrome               ^[.] webCoreInitializeScriptWrappableForInterface(WebCore::DocumentFragment*)
-            |
-            --- webCoreInitializeScriptWrappableForInterface(WebCore::DocumentFragment*)
-
-0.12^3567005^HTMLParserThrea^chrome               ^[.] WebCore::Frame::settings() const
-            |
-            --- WebCore::Frame::settings() const
-
-0.12^3566636^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseIdentifier(bool*)
-            |
-            --- v8::internal::Parser::ParseIdentifier(bool*)
-                0x7fff30e90bf000
-
-0.12^3566359^HTMLParserThrea^chrome               ^[.] WebCore::CachedImage::didAddClient(WebCore::CachedResourceClient*)
-            |
-            --- WebCore::CachedImage::didAddClient(WebCore::CachedResourceClient*)
-
-0.12^3566119^HTMLParserThrea^chrome               ^[.] WebCore::RenderStyle::diff(WebCore::RenderStyle const*, unsigned int&) const
-            |
-            --- WebCore::RenderStyle::diff(WebCore::RenderStyle const*, unsigned int&) const
-
-0.12^3565713^HTMLParserThrea^chrome               ^[.] WebCore::LiveNodeListBase::invalidateCache() const
-            |
-            --- WebCore::LiveNodeListBase::invalidateCache() const
-
-0.12^3565698^HTMLParserThrea^chrome               ^[.] WebCore::SelectorChecker::SelectorChecker(WebCore::Document*, WebCore::SelectorChecker::Mode)
-            |
-            --- WebCore::SelectorChecker::SelectorChecker(WebCore::Document*, WebCore::SelectorChecker::Mode)
-
-0.12^3565455^HTMLParserThrea^chrome               ^[.] WebCore::HTMLTreeBuilder::processEndTag(WebCore::AtomicHTMLToken*)
-            |
-            --- WebCore::HTMLTreeBuilder::processEndTag(WebCore::AtomicHTMLToken*)
-                0x7f7a11e52eb0
-
-0.12^3565182^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::arithmetic_op_32(unsigned char, v8::internal::Register, v8::internal::Register)
-            |
-            --- v8::internal::Assembler::arithmetic_op_32(unsigned char, v8::internal::Register, v8::internal::Register)
-
-0.12^3565074^HTMLParserThrea^chrome               ^[.] v8::internal::TranslationBuffer::Add(int, v8::internal::Zone*)
-            |
-            --- v8::internal::TranslationBuffer::Add(int, v8::internal::Zone*)
-
-0.12^3565037^HTMLParserThrea^chrome               ^[.] WebCore::Node::parentOrShadowHostElement() const
-            |
-            --- WebCore::Node::parentOrShadowHostElement() const
-
-0.12^3564789^HTMLParserThrea^chrome               ^[.] void v8::internal::FlexibleBodyVisitor<v8::internal::MarkCompactMarkingVisitor, v8::internal::StructBodyDescriptor, void>::VisitSpecialized<56>(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- void v8::internal::FlexibleBodyVisitor<v8::internal::MarkCompactMarkingVisitor, v8::internal::StructBodyDescriptor, void>::VisitSpecialized<56>(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.12^3564677^HTMLParserThrea^chrome               ^[.] v8::internal::Map::RawCopy(int)
-            |
-            --- v8::internal::Map::RawCopy(int)
-
-0.12^3563819^HTMLParserThrea^chrome               ^[.] _ZN2v88internal8LCodeGen16WriteTranslationEPNS0_12LEnvironmentEPNS0_11TranslationE.constprop.384
-            |
-            --- _ZN2v88internal8LCodeGen16WriteTranslationEPNS0_12LEnvironmentEPNS0_11TranslationE.constprop.384
-
-0.12^3563122^HTMLParserThrea^chrome               ^[.] WebCore::MatchedProperties::~MatchedProperties()
-            |
-            --- WebCore::MatchedProperties::~MatchedProperties()
-                0x3b2abdb056b8
-                0x1e83176feba8
-
-0.12^3562575^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::MakeCode(v8::internal::CompilationInfo*)
-            |
-            --- v8::internal::FullCodeGenerator::MakeCode(v8::internal::CompilationInfo*)
-
-0.12^3561995^HTMLParserThrea^chrome               ^[.] v8::internal::BaseLoadStoreStubCompiler::GetICCode(v8::internal::Code::Kind, v8::internal::Code::StubType, v8::internal::Handle<v8::internal::Name>, v8::internal::InlineCacheState)
-            |
-            --- v8::internal::BaseLoadStoreStubCompiler::GetICCode(v8::internal::Code::Kind, v8::internal::Code::StubType, v8::internal::Handle<v8::internal::Name>, v8::internal::InlineCacheState)
-                0x9d2ae798179
-
-0.12^3561893^HTMLParserThrea^chrome               ^[.] int v8::internal::FlexibleBodyVisitor<v8::internal::NewSpaceScavenger, v8::internal::JSObject::BodyDescriptor, int>::VisitSpecialized<24>(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- int v8::internal::FlexibleBodyVisitor<v8::internal::NewSpaceScavenger, v8::internal::JSObject::BodyDescriptor, int>::VisitSpecialized<24>(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.12^3561621^HTMLParserThrea^chrome               ^[.] WTF::AtomicString::addSlowCase(WTF::StringImpl*)
-            |
-            --- WTF::AtomicString::addSlowCase(WTF::StringImpl*)
-
-0.12^3561375^HTMLParserThrea^chrome               ^[.] WebCore::StyleResolver::styleForElement(WebCore::Element*, WebCore::RenderStyle*, WebCore::StyleSharingBehavior, WebCore::RuleMatchingBehavior, WebCore::RenderRegion*)
-            |
-            --- WebCore::StyleResolver::styleForElement(WebCore::Element*, WebCore::RenderStyle*, WebCore::StyleSharingBehavior, WebCore::RuleMatchingBehavior, WebCore::RenderRegion*)
-
-0.12^3561200^HTMLParserThrea^chrome               ^[.] v8::internal::Builtins::LoadIC_PreMonomorphic()
-            |
-            --- v8::internal::Builtins::LoadIC_PreMonomorphic()
-                0x29f9884600a9
-
-0.12^3561181^HTMLParserThrea^chrome               ^[.] WebCore::FloatPoint::FloatPoint(WebCore::LayoutPoint const&)
-            |
-            --- WebCore::FloatPoint::FloatPoint(WebCore::LayoutPoint const&)
-                WebCore::RenderBox::clippedOverflowRectForRepaint(WebCore::RenderLayerModelObject const*) const
-                WebCore::RenderBox::contentWidth() const
-
-0.12^3561117^HTMLParserThrea^chrome               ^[.] v8::internal::LoadStubCompiler::registers()
-            |
-            --- v8::internal::LoadStubCompiler::registers()
-                0xc6a34d0ef91
-
-0.12^3561066^HTMLParserThrea^chrome               ^[.] WebCore::BorderData::BorderData()
-            |
-            --- WebCore::BorderData::BorderData()
-
-0.12^3560598^HTMLParserThrea^chrome               ^[.] WebCore::HTMLElement::parseAttribute(WebCore::QualifiedName const&, WTF::AtomicString const&)
-            |
-            --- WebCore::HTMLElement::parseAttribute(WebCore::QualifiedName const&, WTF::AtomicString const&)
-
-0.12^3560313^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::createLineBoxesFromBidiRuns(WebCore::BidiRunList<WebCore::BidiRun>&, WebCore::InlineIterator const&, WebCore::LineInfo&, WebCore::VerticalPositionCache&, WebCore::BidiRun*, WTF::Vector<WebCore::WordMeasurement, 64ul>&)
-            |
-            --- WebCore::RenderBlock::createLineBoxesFromBidiRuns(WebCore::BidiRunList<WebCore::BidiRun>&, WebCore::InlineIterator const&, WebCore::LineInfo&, WebCore::VerticalPositionCache&, WebCore::BidiRun*, WTF::Vector<WebCore::WordMeasurement, 64ul>&)
-                0x3b2abd54deb0
-
-0.12^3560066^HTMLParserThrea^chrome               ^[.] void WebCore::StringCache::setReturnValueFromString<v8::PropertyCallbackInfo<v8::Value> >(v8::PropertyCallbackInfo<v8::Value> const&, WTF::StringImpl*, v8::Isolate*)
-            |
-            --- void WebCore::StringCache::setReturnValueFromString<v8::PropertyCallbackInfo<v8::Value> >(v8::PropertyCallbackInfo<v8::Value> const&, WTF::StringImpl*, v8::Isolate*)
-                0xc6a35a2a0c9
-                v8::internal::JSReceiver::LocalLookup(v8::internal::Name*, v8::internal::LookupResult*, bool)
-
-0.12^3560037^HTMLParserThrea^chrome               ^[.] v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitSharedFunctionInfo(v8::internal::Map*, v8::internal::HeapObject*)
-            |
-            --- v8::internal::StaticMarkingVisitor<v8::internal::MarkCompactMarkingVisitor>::VisitSharedFunctionInfo(v8::internal::Map*, v8::internal::HeapObject*)
-
-0.12^3559792^HTMLParserThrea^chrome               ^[.] WebCore::ComposedShadowTreeWalker::traverseParent(WebCore::Node const*, WebCore::NodeRenderingTraversal::ParentDetails*) const
-            |
-            --- WebCore::ComposedShadowTreeWalker::traverseParent(WebCore::Node const*, WebCore::NodeRenderingTraversal::ParentDetails*) const
-
-0.12^3559628^HTMLParserThrea^chrome               ^[.] WebCore::Element::rebuildPresentationAttributeStyle()
-            |
-            --- WebCore::Element::rebuildPresentationAttributeStyle()
-                0x1e83176beb48
-
-0.12^3558753^HTMLParserThrea^chrome               ^[.] v8::internal::LoadStubCompiler::JitEvent(v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Code>)
-            |
-            --- v8::internal::LoadStubCompiler::JitEvent(v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::Code>)
-                0xc6a354902f1
-
-0.12^3557965^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::lea(v8::internal::Register, v8::internal::Operand const&)
-            |
-            --- v8::internal::Assembler::lea(v8::internal::Register, v8::internal::Operand const&)
-
-0.12^3557486^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::updateShapeInsideInfoAfterStyleChange(WebCore::ShapeValue const*, WebCore::ShapeValue const*)
-            |
-            --- WebCore::RenderBlock::updateShapeInsideInfoAfterStyleChange(WebCore::ShapeValue const*, WebCore::ShapeValue const*)
-
-0.12^3556781^HTMLParserThrea^libc-2.15.so         ^[.] __strlen_sse2_pminub
-            |
-            --- __strlen_sse2_pminub
-
-0.12^3556662^HTMLParserThrea^chrome               ^[.] WebCore::ElementRuleCollector::collectMatchingRulesForList(WebCore::RuleData const*, WebCore::MatchRequest const&, WebCore::RuleRange&)
-            |
-            --- WebCore::ElementRuleCollector::collectMatchingRulesForList(WebCore::RuleData const*, WebCore::MatchRequest const&, WebCore::RuleRange&)
-
-0.12^3556305^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::Scavenge()
-            |
-            --- v8::internal::Heap::Scavenge()
-
-0.12^3556183^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::linkToEndLineIfNeeded(WebCore::LineLayoutState&)
-            |
-            --- WebCore::RenderBlock::linkToEndLineIfNeeded(WebCore::LineLayoutState&)
-
-0.12^3555975^HTMLParserThrea^chrome               ^[.] WebCore::SharedStyleFinder::locateCousinList(WebCore::Element*, unsigned int&) const
-            |
-            --- WebCore::SharedStyleFinder::locateCousinList(WebCore::Element*, unsigned int&) const
-                0x176da48800000000
-
-0.12^3555563^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::PrepareForBailoutForId(v8::internal::BailoutId, v8::internal::FullCodeGenerator::State)
-            |
-            --- v8::internal::FullCodeGenerator::PrepareForBailoutForId(v8::internal::BailoutId, v8::internal::FullCodeGenerator::State)
-
-0.12^3555363^HTMLParserThrea^chrome               ^[.] v8::internal::PropertyCallbackArguments::Call(v8::Handle<v8::Value> (*)(v8::Local<v8::String>, v8::AccessorInfo const&), v8::Local<v8::String>)
-            |
-            --- v8::internal::PropertyCallbackArguments::Call(v8::Handle<v8::Value> (*)(v8::Local<v8::String>, v8::AccessorInfo const&), v8::Local<v8::String>)
-                0x7f7a0b900000
-
-0.12^3554978^HTMLParserThrea^chrome               ^[.] v8::internal::Object::Lookup(v8::internal::Name*, v8::internal::LookupResult*)
-            |
-            --- v8::internal::Object::Lookup(v8::internal::Name*, v8::internal::LookupResult*)
-
-0.12^3554874^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateRawOneByteString(int, v8::internal::PretenureFlag)
-            |
-            --- v8::internal::Heap::AllocateRawOneByteString(int, v8::internal::PretenureFlag)
-
-0.12^3554475^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::styleWillChange(WebCore::StyleDifference, WebCore::RenderStyle const*)
-            |
-            --- WebCore::RenderBlock::styleWillChange(WebCore::StyleDifference, WebCore::RenderStyle const*)
-
-0.12^3553383^HTMLParserThrea^chrome               ^[.] base::Time::Now()
-            |
-            --- base::Time::Now()
-
-0.12^3553107^HTMLParserThrea^chrome               ^[.] WebCore::ElementRuleCollector::~ElementRuleCollector()
-            |
-            --- WebCore::ElementRuleCollector::~ElementRuleCollector()
-
-0.12^3550744^HTMLParserThrea^chrome               ^[.] net::HttpResponseHeaders::FindHeader(unsigned long, base::BasicStringPiece<std::string> const&) const
-            |
-            --- net::HttpResponseHeaders::FindHeader(unsigned long, base::BasicStringPiece<std::string> const&) const
-
-0.12^3550703^HTMLParserThrea^chrome               ^[.] WebCore::NodeRenderingContext::createRendererForElementIfNeeded()
-            |
-            --- WebCore::NodeRenderingContext::createRendererForElementIfNeeded()
-
-0.12^3550144^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::ScavengeObject(v8::internal::HeapObject**, v8::internal::HeapObject*)
-            |
-            --- v8::internal::Heap::ScavengeObject(v8::internal::HeapObject**, v8::internal::HeapObject*)
-
-0.12^3550090^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayerModelObject::styleDidChange(WebCore::StyleDifference, WebCore::RenderStyle const*)
-            |
-            --- WebCore::RenderLayerModelObject::styleDidChange(WebCore::StyleDifference, WebCore::RenderStyle const*)
-
-0.12^3549513^HTMLParserThrea^chrome               ^[.] std::_Rb_tree<extensions::ChromeV8Context*, extensions::ChromeV8Context*, std::_Identity<extensions::ChromeV8Context*>, std::less<extensions::ChromeV8Context*>, std::allocator<extensions::ChromeV8Context*> >::_M_insert_unique(extensions::ChromeV8Context* const&)
-            |
-            --- std::_Rb_tree<extensions::ChromeV8Context*, extensions::ChromeV8Context*, std::_Identity<extensions::ChromeV8Context*>, std::less<extensions::ChromeV8Context*>, std::allocator<extensions::ChromeV8Context*> >::_M_insert_unique(extensions::ChromeV8Context* const&)
-
-0.12^3549422^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::clearFloats()
-            |
-            --- WebCore::RenderBlock::clearFloats()
-
-0.12^3548487^HTMLParserThrea^chrome               ^[.] WebCore::RenderReplaced::computeAspectRatioInformationForRenderBox(WebCore::RenderBox*, WebCore::FloatSize&, double&, bool&) const
-            |
-            --- WebCore::RenderReplaced::computeAspectRatioInformationForRenderBox(WebCore::RenderBox*, WebCore::FloatSize&, double&, bool&) const
-                0x3b2abdce1ed8
-
-0.12^3545724^HTMLParserThrea^chrome               ^[.] WebCore::SVGRenderSupport::styleChanged(WebCore::RenderObject*)
-            |
-            --- WebCore::SVGRenderSupport::styleChanged(WebCore::RenderObject*)
-
-0.12^3545370^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::AllocateNonParameterLocals()
-            |
-            --- v8::internal::Scope::AllocateNonParameterLocals()
-                0x700000007
-
-0.12^3545160^HTMLParserThrea^chrome               ^[.] WebCore::Element::hasFlagsSetDuringStylingOfChildren() const
-            |
-            --- WebCore::Element::hasFlagsSetDuringStylingOfChildren() const
-
-0.12^3543621^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::visualOverflowRectForPropagation(WebCore::RenderStyle*) const
-            |
-            --- WebCore::RenderBox::visualOverflowRectForPropagation(WebCore::RenderStyle*) const
-
-0.12^3542672^HTMLParserThrea^libm-2.15.so         ^[.] __ceilf_sse41
-            |
-            --- __ceilf_sse41
-
-0.12^3542332^HTMLParserThrea^chrome               ^[.] v8::internal::CallStubCompiler::CompileHandlerFrontend(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Name>, v8::internal::CheckType, v8::internal::Label*)
-            |
-            --- v8::internal::CallStubCompiler::CompileHandlerFrontend(v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::Name>, v8::internal::CheckType, v8::internal::Label*)
-                0x7f7a11d17f90
-
-0.12^3542050^HTMLParserThrea^chrome               ^[.] v8::internal::MarkCompactCollector::RecordRelocSlot(v8::internal::RelocInfo*, v8::internal::Object*)
-            |
-            --- v8::internal::MarkCompactCollector::RecordRelocSlot(v8::internal::RelocInfo*, v8::internal::Object*)
-
-0.12^3540984^HTMLParserThrea^chrome               ^[.] v8::internal::RegExpMacroAssemblerX64::CheckSpecialCharacterClass(unsigned short, v8::internal::Label*)
-            |
-            --- v8::internal::RegExpMacroAssemblerX64::CheckSpecialCharacterClass(unsigned short, v8::internal::Label*)
-
-0.12^3537796^HTMLParserThrea^chrome               ^[.] SkBitmapProcState::chooseProcs(SkMatrix const&, SkPaint const&)
-            |
-            --- SkBitmapProcState::chooseProcs(SkMatrix const&, SkPaint const&)
-                0x3f80000041400000
-
-0.12^3537246^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::CreateCode(v8::internal::CodeDesc const&, unsigned int, v8::internal::Handle<v8::internal::Object>, bool, bool)
-            |
-            --- v8::internal::Heap::CreateCode(v8::internal::CodeDesc const&, unsigned int, v8::internal::Handle<v8::internal::Object>, bool, bool)
-                0x8f00001000
-
-0.12^3535475^HTMLParserThrea^chrome               ^[.] WebCore::Element::getAttribute(WebCore::QualifiedName const&) const
-            |
-            --- WebCore::Element::getAttribute(WebCore::QualifiedName const&) const
-
-0.12^3534788^HTMLParserThrea^chrome               ^[.] v8::internal::ToBooleanIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::ToBooleanIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
-
-0.12^3534268^HTMLParserThrea^chrome               ^[.] WebCore::FormElementKey::deref() const
-            |
-            --- WebCore::FormElementKey::deref() const
-
-0.12^3533584^HTMLParserThrea^chrome               ^[.] std::basic_string<unsigned short, base::string16_char_traits, std::allocator<unsigned short> >::assign(std::basic_string<unsigned short, base::string16_char_traits, std::allocator<unsigned short> > const&)
-            |
-            --- std::basic_string<unsigned short, base::string16_char_traits, std::allocator<unsigned short> >::assign(std::basic_string<unsigned short, base::string16_char_traits, std::allocator<unsigned short> > const&)
-                0x33d2a411c441
-
-0.12^3533503^HTMLParserThrea^chrome               ^[.] void v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::EvacuateObject<(v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::ObjectContents)1, (v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::SizeRestriction)0, 8>(v8::internal::Map*, v8::internal::HeapObject**, v8::internal::HeapObject*, int)
-            |
-            --- void v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::EvacuateObject<(v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::ObjectContents)1, (v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::SizeRestriction)0, 8>(v8::internal::Map*, v8::internal::HeapObject**, v8::internal::HeapObject*, int)
-
-0.12^3532801^HTMLParserThrea^chrome               ^[.] WebCore::HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned int&) const
-            |
-            --- WebCore::HTMLConstructionSite::indexOfFirstUnopenFormattingElement(unsigned int&) const
-
-0.12^3531175^HTMLParserThrea^chrome               ^[.] v8::internal::StubCache::ComputeLoadNonexistent(v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::JSObject>)
-            |
-            --- v8::internal::StubCache::ComputeLoadNonexistent(v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::JSObject>)
-
-0.12^3529077^HTMLParserThrea^chrome               ^[.] WTF::currentTime()
-            |
-            --- WTF::currentTime()
-
-0.12^3527952^HTMLParserThrea^chrome               ^[.] void WebCore::SelectorDataList::execute<false>(WebCore::Node*, WTF::Vector<WTF::RefPtr<WebCore::Node>, 0ul>&) const
-            |
-            --- void WebCore::SelectorDataList::execute<false>(WebCore::Node*, WTF::Vector<WTF::RefPtr<WebCore::Node>, 0ul>&) const
-
-0.12^3527820^HTMLParserThrea^chrome               ^[.] v8::preparser::PreParser::ParseStatement(bool*)
-            |
-            --- v8::preparser::PreParser::ParseStatement(bool*)
-                0x3b2abd78300000
-
-0.12^3526909^HTMLParserThrea^chrome               ^[.] v8::internal::MacroAssembler::LoadSmiConstant(v8::internal::Register, v8::internal::Smi*)
-            |
-            --- v8::internal::MacroAssembler::LoadSmiConstant(v8::internal::Register, v8::internal::Smi*)
-
-0.12^3526173^HTMLParserThrea^chrome               ^[.] v8::internal::MacroAssembler::CheckMap(v8::internal::Register, v8::internal::Handle<v8::internal::Map>, v8::internal::Label*, v8::internal::SmiCheckType)
-            |
-            --- v8::internal::MacroAssembler::CheckMap(v8::internal::Register, v8::internal::Handle<v8::internal::Map>, v8::internal::Label*, v8::internal::SmiCheckType)
-
-0.12^3525548^HTMLParserThrea^chrome               ^[.] v8::internal::String::SlowTryFlatten(v8::internal::PretenureFlag)
-            |
-            --- v8::internal::String::SlowTryFlatten(v8::internal::PretenureFlag)
-
-0.12^3525251^HTMLParserThrea^chrome               ^[.] WebCore::RuleSet::addChildRules(WTF::Vector<WTF::RefPtr<WebCore::StyleRuleBase>, 0ul> const&, WebCore::MediaQueryEvaluator const&, WebCore::StyleResolver*, WebCore::ContainerNode const*, bool, WebCore::AddRuleFlags)
-            |
-            --- WebCore::RuleSet::addChildRules(WTF::Vector<WTF::RefPtr<WebCore::StyleRuleBase>, 0ul> const&, WebCore::MediaQueryEvaluator const&, WebCore::StyleResolver*, WebCore::ContainerNode const*, bool, WebCore::AddRuleFlags)
-
-0.12^3524914^HTMLParserThrea^chrome               ^[.] v8::internal::PositionsRecorder::WriteRecordedPositions()
-            |
-            --- v8::internal::PositionsRecorder::WriteRecordedPositions()
-
-0.12^3524273^HTMLParserThrea^chrome               ^[.] WebCore::FrameLoader::checkLoadComplete()
-            |
-            --- WebCore::FrameLoader::checkLoadComplete()
-
-0.12^3523358^HTMLParserThrea^chrome               ^[.] v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::EvacuateFixedArray(v8::internal::Map*, v8::internal::HeapObject**, v8::internal::HeapObject*)
-            |
-            --- v8::internal::ScavengingVisitor<(v8::internal::MarksHandling)1, (v8::internal::LoggingAndProfiling)1>::EvacuateFixedArray(v8::internal::Map*, v8::internal::HeapObject**, v8::internal::HeapObject*)
-
-0.12^3522817^HTMLParserThrea^chrome               ^[.] WebCore::HTMLFrameElementBase::attach(WebCore::Node::AttachContext const&)
-            |
-            --- WebCore::HTMLFrameElementBase::attach(WebCore::Node::AttachContext const&)
-
-0.12^3522399^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime::SetObjectProperty(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, PropertyAttributes, v8::internal::StrictModeFlag)
-            |
-            --- v8::internal::Runtime::SetObjectProperty(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, PropertyAttributes, v8::internal::StrictModeFlag)
-                0x2281c143442a
-                0x2281c143180c
-                0x2281c14310e9
-                0x2281c140e854
-                0x2281c14317b0
-                0x2281c14310e9
-                0x2281c140e854
-                0x2281c14317b0
-                0x2281c14310e9
-                0x2281c140e854
-                0x2281c142b65e
-                0x2281c1417d97
-                v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.12^3521835^HTMLParserThrea^chrome               ^[.] v8::Object::SetAlignedPointerInInternalField(int, void*)
-            |
-            --- v8::Object::SetAlignedPointerInInternalField(int, void*)
-
-0.12^3519670^HTMLParserThrea^chrome               ^[.] v8::internal::HDeadCodeEliminationPhase::RemoveDeadInstructions()
-            |
-            --- v8::internal::HDeadCodeEliminationPhase::RemoveDeadInstructions()
-                0x7fff30e8edb0
-
-0.12^3518719^HTMLParserThrea^chrome               ^[.] v8::internal::LCodeGen::Comment(char const*, ...)
-            |
-            --- v8::internal::LCodeGen::Comment(char const*, ...)
-
-0.12^3518131^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::HasRealNamedProperty(v8::internal::Isolate*, v8::internal::Name*)
-            |
-            --- v8::internal::JSObject::HasRealNamedProperty(v8::internal::Isolate*, v8::internal::Name*)
-
-0.12^3516705^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_GetTemplateField(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_GetTemplateField(int, v8::internal::Object**, v8::internal::Isolate*)
-                0x2281c1431084
-                0x2281c140e854
-                0x2281c142b65e
-                0x2281c1417d97
-                v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.12^3515242^HTMLParserThrea^chrome               ^[.] void WebCore::StyleResolver::applyProperties<(WebCore::StyleResolver::StyleApplicationPass)0>(WebCore::StyleResolverState&, WebCore::StylePropertySet const*, WebCore::StyleRule*, bool, bool, WebCore::PropertyWhitelistType)
-            |
-            --- void WebCore::StyleResolver::applyProperties<(WebCore::StyleResolver::StyleApplicationPass)0>(WebCore::StyleResolverState&, WebCore::StylePropertySet const*, WebCore::StyleRule*, bool, bool, WebCore::PropertyWhitelistType)
-
-0.12^3514809^HTMLParserThrea^chrome               ^[.] url_util::LowerCaseEqualsASCII(char const*, char const*, char const*)
-            |
-            --- url_util::LowerCaseEqualsASCII(char const*, char const*, char const*)
-
-0.12^3514002^HTMLParserThrea^chrome               ^[.] v8::internal::ScavengeVisitor::VisitPointer(v8::internal::Object**)
-            |
-            --- v8::internal::ScavengeVisitor::VisitPointer(v8::internal::Object**)
-
-0.12^3513688^HTMLParserThrea^chrome               ^[.] _ZN2v88internal15DescriptorArray6AppendEPNS0_10DescriptorERKNS1_16WhitenessWitnessE.constprop.537
-            |
-            --- _ZN2v88internal15DescriptorArray6AppendEPNS0_10DescriptorERKNS1_16WhitenessWitnessE.constprop.537
-
-0.12^3512883^HTMLParserThrea^chrome               ^[.] v8::internal::LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::LoadIC_Miss(int, v8::internal::Object**, v8::internal::Isolate*)
-                0x7fff30e92040
-
-0.12^3511238^HTMLParserThrea^chrome               ^[.] WebCore::V8ScriptRunner::precompileScript(v8::Handle<v8::String>, WebCore::CachedScript*)
-            |
-            --- WebCore::V8ScriptRunner::precompileScript(v8::Handle<v8::String>, WebCore::CachedScript*)
-
-0.12^3506824^HTMLParserThrea^chrome               ^[.] v8::internal::Factory::NewAllocationSite()
-            |
-            --- v8::internal::Factory::NewAllocationSite()
-
-0.12^3504680^HTMLParserThrea^chrome               ^[.] WebCore::InputTypeNames::text()
-            |
-            --- WebCore::InputTypeNames::text()
-
-0.12^3503829^HTMLParserThrea^chrome               ^[.] v8::internal::FastElementsAccessor<v8::internal::FastPackedObjectElementsAccessor, v8::internal::ElementsKindTraits<(v8::internal::ElementsKind)2>, 8>::SetLengthWithoutNormalize(v8::internal::FixedArrayBase*, v8::internal::JSArray*, v8::internal::Object*, unsigned int)
-            |
-            --- v8::internal::FastElementsAccessor<v8::internal::FastPackedObjectElementsAccessor, v8::internal::ElementsKindTraits<(v8::internal::ElementsKind)2>, 8>::SetLengthWithoutNormalize(v8::internal::FixedArrayBase*, v8::internal::JSArray*, v8::internal::Object*, unsigned int)
-
-0.12^3500368^HTMLParserThrea^chrome               ^[.] WTF::Vector<WTF::String, 0ul>::expandCapacity(unsigned long)
-            |
-            --- WTF::Vector<WTF::String, 0ul>::expandCapacity(unsigned long)
-                0x1000
-
-0.12^3497657^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject::adjustStyleDifference(WebCore::StyleDifference, unsigned int) const
-            |
-            --- WebCore::RenderObject::adjustStyleDifference(WebCore::StyleDifference, unsigned int) const
-
-0.12^3494287^HTMLParserThrea^chrome               ^[.] v8::internal::IC::Clear(unsigned char*)
-            |
-            --- v8::internal::IC::Clear(unsigned char*)
-
-0.12^3492300^HTMLParserThrea^chrome               ^[.] ppapi::proxy::InterfaceProxy::Send(IPC::Message*)
-            |
-            --- ppapi::proxy::InterfaceProxy::Send(IPC::Message*)
-
-0.12^3492214^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::Assembler(v8::internal::Isolate*, void*, int)
-            |
-            --- v8::internal::Assembler::Assembler(v8::internal::Isolate*, void*, int)
-                0xc6a346f4711
-
-0.12^3489812^HTMLParserThrea^chrome               ^[.] WebCore::SelectorCheckerFastPath::matchesRightmostSelector(WebCore::SelectorChecker::VisitedMatchType) const
-            |
-            --- WebCore::SelectorCheckerFastPath::matchesRightmostSelector(WebCore::SelectorChecker::VisitedMatchType) const
-
-0.12^3488486^HTMLParserThrea^chrome               ^[.] tc_free
-            |
-            --- tc_free
-                0x100000000
-                0x29f988404121
-
-0.12^3488229^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject::updateFillImages(WebCore::FillLayer const*, WebCore::FillLayer const*)
-            |
-            --- WebCore::RenderObject::updateFillImages(WebCore::FillLayer const*, WebCore::FillLayer const*)
-
-0.12^3486534^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParsePostfixExpression(bool*)
-            |
-            --- v8::internal::Parser::ParsePostfixExpression(bool*)
-                0x7fff30e905d002
-
-0.12^3484804^HTMLParserThrea^chrome               ^[.] v8::internal::SharedStoreIC_ExtendStorage(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::SharedStoreIC_ExtendStorage(int, v8::internal::Object**, v8::internal::Isolate*)
-
-0.12^3484146^HTMLParserThrea^chrome               ^[.] WebCore::RenderCounter::rendererSubtreeAttached(WebCore::RenderObject*)
-            |
-            --- WebCore::RenderCounter::rendererSubtreeAttached(WebCore::RenderObject*)
-
-0.12^3483547^HTMLParserThrea^chrome               ^[.] WebCore::LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned int, WebCore::ContainerNode*) const
-            |
-            --- WebCore::LiveNodeListBase::itemBeforeOrAfterCachedItem(unsigned int, WebCore::ContainerNode*) const
-
-0.12^3482072^HTMLParserThrea^chrome               ^[.] v8::internal::CPU::FlushICache(void*, unsigned long)
-            |
-            --- v8::internal::CPU::FlushICache(void*, unsigned long)
-
-0.12^3481935^HTMLParserThrea^chrome               ^[.] WebCore::StyleResolver::matchAuthorRules(WebCore::Element*, WebCore::ElementRuleCollector&, bool)
-            |
-            --- WebCore::StyleResolver::matchAuthorRules(WebCore::Element*, WebCore::ElementRuleCollector&, bool)
-                0x1e83176abb08
-
-0.12^3481470^HTMLParserThrea^chrome               ^[.] v8::internal::StackFrame::GetCallerState(v8::internal::StackFrame::State*) const
-            |
-            --- v8::internal::StackFrame::GetCallerState(v8::internal::StackFrame::State*) const
-                0x7fff30e8f698
-                0x9d2ae7aa1e1
-
-0.12^3479937^HTMLParserThrea^chrome               ^[.] WTF::AtomicString::add(unsigned char const*)
-            |
-            --- WTF::AtomicString::add(unsigned char const*)
-
-0.12^3476115^HTMLParserThrea^chrome               ^[.] WebCore::StyleAdjuster::adjustRenderStyle(WebCore::RenderStyle*, WebCore::RenderStyle*, WebCore::Element*)
-            |
-            --- WebCore::StyleAdjuster::adjustRenderStyle(WebCore::RenderStyle*, WebCore::RenderStyle*, WebCore::Element*)
-
-0.12^3474363^HTMLParserThrea^chrome               ^[.] WebCore::CSSValue::deref()
-            |
-            --- WebCore::CSSValue::deref()
-
-0.12^3473710^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::movq(v8::internal::Register, long, v8::internal::RelocInfo::Mode)
-            |
-            --- v8::internal::Assembler::movq(v8::internal::Register, long, v8::internal::RelocInfo::Mode)
-
-0.12^3471996^HTMLParserThrea^chrome               ^[.] v8::internal::RegExpEngine::Compile(v8::internal::RegExpCompileData*, bool, bool, bool, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::String>, bool, v8::internal::Zone*)
-            |
-            --- v8::internal::RegExpEngine::Compile(v8::internal::RegExpCompileData*, bool, bool, bool, v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::String>, bool, v8::internal::Zone*)
-                0xc6a3439fca1
-
-0.12^3468177^HTMLParserThrea^chrome               ^[.] v8::internal::Context::global_proxy()
-            |
-            --- v8::internal::Context::global_proxy()
-
-0.12^3467384^HTMLParserThrea^chrome               ^[.] WTF::Vector<std::pair<void (*)(WebCore::Node*), WTF::RefPtr<WebCore::Node> >, 0ul>::shrinkCapacity(unsigned long)
-            |
-            --- WTF::Vector<std::pair<void (*)(WebCore::Node*), WTF::RefPtr<WebCore::Node> >, 0ul>::shrinkCapacity(unsigned long)
-
-0.12^3466196^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::GetSymbol()
-            |
-            --- v8::internal::Parser::GetSymbol()
-                0x7fff30e9182000
-
-0.12^3462208^HTMLParserThrea^chrome               ^[.] v8::internal::JSReceiver::SetProperty(v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::StrictModeFlag, v8::internal::JSReceiver::StoreFromKeyed)
-            |
-            --- v8::internal::JSReceiver::SetProperty(v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::StrictModeFlag, v8::internal::JSReceiver::StoreFromKeyed)
-                0x7fff30e91950
-
-0.12^3461655^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::shouldBeNormalFlowOnlyIgnoringCompositedScrolling() const
-            |
-            --- WebCore::RenderLayer::shouldBeNormalFlowOnlyIgnoringCompositedScrolling() const
-
-0.11^3453572^HTMLParserThrea^chrome               ^[.] v8::internal::HBasicBlock::HBasicBlock(v8::internal::HGraph*)
-            |
-            --- v8::internal::HBasicBlock::HBasicBlock(v8::internal::HGraph*)
-
-0.11^3450775^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject::invalidateContainerPreferredLogicalWidths()
-            |
-            --- WebCore::RenderObject::invalidateContainerPreferredLogicalWidths()
-
-0.11^3446446^HTMLParserThrea^chrome               ^[.] WebCore::LayoutUnit::round() const
-            |
-            --- WebCore::LayoutUnit::round() const
-
-0.11^3445539^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_RegExpExec(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_RegExpExec(int, v8::internal::Object**, v8::internal::Isolate*)
-                0xc6a3540bd09
-
-0.11^3445347^HTMLParserThrea^chrome               ^[.] v8::internal::BaseLoadStubCompiler::GenerateLoadCallback(v8::internal::Register, v8::internal::Handle<v8::internal::ExecutableAccessorInfo>)
-            |
-            --- v8::internal::BaseLoadStubCompiler::GenerateLoadCallback(v8::internal::Register, v8::internal::Handle<v8::internal::ExecutableAccessorInfo>)
-
-0.11^3444801^HTMLParserThrea^chrome               ^[.] v8::internal::BufferedUtf16CharacterStream::ReadBlock()
-            |
-            --- v8::internal::BufferedUtf16CharacterStream::ReadBlock()
-                0x7fff30e91798
-
-0.11^3436515^HTMLParserThrea^chrome               ^[.] WTF::Vector<unsigned short, 256ul>::shrinkCapacity(unsigned long)
-            |
-            --- WTF::Vector<unsigned short, 256ul>::shrinkCapacity(unsigned long)
-
-0.11^3435352^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseFunctionLiteral(v8::internal::Handle<v8::internal::String>, bool, bool, int, v8::internal::FunctionLiteral::FunctionType, bool*)
-            |
-            --- v8::internal::Parser::ParseFunctionLiteral(v8::internal::Handle<v8::internal::String>, bool, bool, int, v8::internal::FunctionLiteral::FunctionType, bool*)
-                0x7fff30e903a000
-
-0.11^3434720^HTMLParserThrea^chrome               ^[.] WebCore::ImageSource::setData(WebCore::SharedBuffer*, bool)
-            |
-            --- WebCore::ImageSource::setData(WebCore::SharedBuffer*, bool)
-
-0.11^3432682^HTMLParserThrea^chrome               ^[.] v8::internal::StandardFrame::ComputeCallerState(v8::internal::StackFrame::State*) const
-            |
-            --- v8::internal::StandardFrame::ComputeCallerState(v8::internal::StackFrame::State*) const
-                0x7fff30e90df8
-                0xc6a346b4fe9
-
-0.11^3432008^HTMLParserThrea^chrome               ^[.] v8::internal::VariableProxy::Accept(v8::internal::AstVisitor*)
-            |
-            --- v8::internal::VariableProxy::Accept(v8::internal::AstVisitor*)
-
-0.11^3420656^HTMLParserThrea^chrome               ^[.] SkBlitter::Choose(SkBitmap const&, SkMatrix const&, SkPaint const&, void*, unsigned long)
-            |
-            --- SkBlitter::Choose(SkBitmap const&, SkMatrix const&, SkPaint const&, void*, unsigned long)
-
-0.11^3420637^HTMLParserThrea^chrome               ^[.] v8::internal::Map::UpdateCodeCache(v8::internal::Name*, v8::internal::Code*)
-            |
-            --- v8::internal::Map::UpdateCodeCache(v8::internal::Name*, v8::internal::Code*)
-
-0.11^3419913^HTMLParserThrea^chrome               ^[.] WebCore::Element::childrenChanged(bool, WebCore::Node*, WebCore::Node*, int)
-            |
-            --- WebCore::Element::childrenChanged(bool, WebCore::Node*, WebCore::Node*, int)
-
-0.11^3413310^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::ResolveVariablesRecursively(v8::internal::CompilationInfo*, v8::internal::AstNodeFactory<v8::internal::AstNullVisitor>*)
-            |
-            --- v8::internal::Scope::ResolveVariablesRecursively(v8::internal::CompilationInfo*, v8::internal::AstNodeFactory<v8::internal::AstNullVisitor>*)
-
-0.11^3413062^HTMLParserThrea^chrome               ^[.] void WTF::Vector<WebCore::MatchedProperties, 0ul>::append<WebCore::MatchedProperties>(WebCore::MatchedProperties const*, unsigned long)
-            |
-            --- void WTF::Vector<WebCore::MatchedProperties, 0ul>::append<WebCore::MatchedProperties>(WebCore::MatchedProperties const*, unsigned long)
-
-0.11^3409803^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::movq(v8::internal::Register, v8::internal::Operand const&)
-            |
-            --- v8::internal::Assembler::movq(v8::internal::Register, v8::internal::Operand const&)
-
-0.11^3406785^HTMLParserThrea^chrome               ^[.] v8::internal::HashTable<v8::internal::MapCacheShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::Isolate*, v8::internal::HashTableKey*)
-            |
-            --- v8::internal::HashTable<v8::internal::MapCacheShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::Isolate*, v8::internal::HashTableKey*)
-
-0.11^3404799^HTMLParserThrea^chrome               ^[.] WebCore::RenderLineBoxList::removeLineBox(WebCore::InlineFlowBox*)
-            |
-            --- WebCore::RenderLineBoxList::removeLineBox(WebCore::InlineFlowBox*)
-
-0.11^3398149^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::clippingRootForPainting() const
-            |
-            --- WebCore::RenderLayer::clippingRootForPainting() const
-                0x2bc00000a000
-
-0.11^3390095^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::VarOperand(v8::internal::Variable*, v8::internal::Register)
-            |
-            --- v8::internal::FullCodeGenerator::VarOperand(v8::internal::Variable*, v8::internal::Register)
-                0x7fff30e91980
-
-0.11^3388424^HTMLParserThrea^chrome               ^[.] WebCore::DOMTimer::fired()
-            |
-            --- WebCore::DOMTimer::fired()
-
-0.11^3378612^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::SetFastElementsCapacityAndLength(int, int, v8::internal::JSObject::SetFastElementsCapacitySmiMode)
-            |
-            --- v8::internal::JSObject::SetFastElementsCapacityAndLength(int, int, v8::internal::JSObject::SetFastElementsCapacitySmiMode)
-
-0.11^3374619^HTMLParserThrea^chrome               ^[.] v8::internal::Code::MakeCodeAgeSequenceYoung(unsigned char*)
-            |
-            --- v8::internal::Code::MakeCodeAgeSequenceYoung(unsigned char*)
-                0x2281c140e854
-                0x2281c1e636e1
-                0x2281c1e52c8f
-                0x2281c142b664
-                0x2281c1417d97
-                v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.11^3373628^HTMLParserThrea^chrome               ^[.] ucase_fold_46
-            |
-            --- ucase_fold_46
-
-0.11^3372159^HTMLParserThrea^chrome               ^[.] WebCore::LayoutState::LayoutState(WebCore::LayoutState*, WebCore::RenderBox*, WebCore::LayoutSize const&, WebCore::LayoutUnit, bool, WebCore::ColumnInfo*)
-            |
-            --- WebCore::LayoutState::LayoutState(WebCore::LayoutState*, WebCore::RenderBox*, WebCore::LayoutSize const&, WebCore::LayoutUnit, bool, WebCore::ColumnInfo*)
-
-0.11^3365891^HTMLParserThrea^chrome               ^[.] v8::internal::HOptimizedGraphBuilder::BuildGraph()
-            |
-            --- v8::internal::HOptimizedGraphBuilder::BuildGraph()
-
-0.11^3359190^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::Initialize()
-            |
-            --- v8::internal::Scope::Initialize()
-
-0.11^3356725^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::updateScrollbarsAfterLayout()
-            |
-            --- WebCore::RenderLayer::updateScrollbarsAfterLayout()
-
-0.11^3356459^HTMLParserThrea^chrome               ^[.] _ZN7WebCoreplEiRKNS_10LayoutUnitE.constprop.860
-            |
-            --- _ZN7WebCoreplEiRKNS_10LayoutUnitE.constprop.860
-
-0.11^3355399^HTMLParserThrea^chrome               ^[.] v8::internal::ExitFrame::GetCallerStackPointer() const
-            |
-            --- v8::internal::ExitFrame::GetCallerStackPointer() const
-                (nil)
-
-0.11^3351779^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::layoutRunsAndFloatsInRange(WebCore::LineLayoutState&, WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>&, WebCore::InlineIterator const&, WebCore::BidiStatus const&, unsigned int)
-            |
-            --- WebCore::RenderBlock::layoutRunsAndFloatsInRange(WebCore::LineLayoutState&, WebCore::BidiResolver<WebCore::InlineIterator, WebCore::BidiRun>&, WebCore::InlineIterator const&, WebCore::BidiStatus const&, unsigned int)
-                0x3b2abd866648
-
-0.11^3344999^HTMLParserThrea^chrome               ^[.] v8::internal::CompilationCacheRegExp::Lookup(v8::internal::Handle<v8::internal::String>, v8::internal::JSRegExp::Flags)
-            |
-            --- v8::internal::CompilationCacheRegExp::Lookup(v8::internal::Handle<v8::internal::String>, v8::internal::JSRegExp::Flags)
-
-0.11^3344476^HTMLParserThrea^chrome               ^[.] tracked_objects::DeathData::RecordDeath(int, int, int)
-            |
-            --- tracked_objects::DeathData::RecordDeath(int, int, int)
-
-0.11^3343357^HTMLParserThrea^chrome               ^[.] void WTF::Vector<WebCore::SelectorFilter::ParentStackFrame, 0ul>::appendSlowCase<WebCore::SelectorFilter::ParentStackFrame>(WebCore::SelectorFilter::ParentStackFrame const&)
-            |
-            --- void WTF::Vector<WebCore::SelectorFilter::ParentStackFrame, 0ul>::appendSlowCase<WebCore::SelectorFilter::ParentStackFrame>(WebCore::SelectorFilter::ParentStackFrame const&)
-
-0.11^3341336^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::VisitObjectLiteral(v8::internal::ObjectLiteral*)
-            |
-            --- v8::internal::FullCodeGenerator::VisitObjectLiteral(v8::internal::ObjectLiteral*)
-
-0.11^3340676^HTMLParserThrea^chrome               ^[.] v8::internal::Assignment::Accept(v8::internal::AstVisitor*)
-            |
-            --- v8::internal::Assignment::Accept(v8::internal::AstVisitor*)
-
-0.11^3336841^HTMLParserThrea^chrome               ^[.] v8::internal::MacroAssembler::Set(v8::internal::Register, long)
-            |
-            --- v8::internal::MacroAssembler::Set(v8::internal::Register, long)
-                0x3b2abd624000
-
-0.11^3335871^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::ScanRegExpPattern(bool)
-            |
-            --- v8::internal::Scanner::ScanRegExpPattern(bool)
-                0x10e8a1901
-
-0.11^3313926^HTMLParserThrea^chrome               ^[.] v8::internal::ToBooleanStub::Types::UpdateStatus(v8::internal::Handle<v8::internal::Object>)
-            |
-            --- v8::internal::ToBooleanStub::Types::UpdateStatus(v8::internal::Handle<v8::internal::Object>)
-                0x2281c14140c1
-
-0.11^3300775^HTMLParserThrea^chrome               ^[.] WebCore::SVGRenderSupport::setRendererHasSVGShadow(WebCore::RenderObject*, bool)
-            |
-            --- WebCore::SVGRenderSupport::setRendererHasSVGShadow(WebCore::RenderObject*, bool)
-
-0.11^3292871^HTMLParserThrea^chrome               ^[.] base::debug::TraceLog::GetInstance()
-            |
-            --- base::debug::TraceLog::GetInstance()
-
-0.11^3289620^HTMLParserThrea^chrome               ^[.] WebCore::FrameView::pagination() const
-            |
-            --- WebCore::FrameView::pagination() const
-                (nil)
-                0x3b2abdc16c30
-
-0.11^3274771^HTMLParserThrea^chrome               ^[.] v8::internal::Factory::NewMap(v8::internal::InstanceType, int, v8::internal::ElementsKind)
-            |
-            --- v8::internal::Factory::NewMap(v8::internal::InstanceType, int, v8::internal::ElementsKind)
-
-0.11^3268228^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool, WebCore::RenderBox*)
-            |
-            --- WebCore::RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool, WebCore::RenderBox*)
-
-0.11^3264333^HTMLParserThrea^chrome               ^[.] v8::internal::CreateObjectLiteralBoilerplate(v8::internal::Isolate*, v8::internal::Handle<v8::internal::FixedArray>, v8::internal::Handle<v8::internal::FixedArray>, bool, bool)
-            |
-            --- v8::internal::CreateObjectLiteralBoilerplate(v8::internal::Isolate*, v8::internal::Handle<v8::internal::FixedArray>, v8::internal::Handle<v8::internal::FixedArray>, bool, bool)
-
-0.11^3263293^HTMLParserThrea^chrome               ^[.] content::RenderViewObserver::DidClearWindowObject(WebKit::WebFrame*)
-            |
-            --- content::RenderViewObserver::DidClearWindowObject(WebKit::WebFrame*)
-
-0.11^3263262^HTMLParserThrea^chrome               ^[.] WebCore::V8HiddenPropertyName::sleepFunction()
-            |
-            --- WebCore::V8HiddenPropertyName::sleepFunction()
-                0x5bf5d67bd1
-
-0.11^3253742^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::boundingBox(WebCore::RenderLayer const*, unsigned int, WebCore::LayoutPoint const*) const
-            |
-            --- WebCore::RenderLayer::boundingBox(WebCore::RenderLayer const*, unsigned int, WebCore::LayoutPoint const*) const
-                (nil)
-
-0.11^3250656^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_StringCharCodeAt(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_StringCharCodeAt(int, v8::internal::Object**, v8::internal::Isolate*)
-                0x2281c1449ea3
-                0x2281c14497a7
-                0x2281c1425b83
-                0x2281c141b848
-                0x2281c1443ab6
-                0x2281c14480ae
-                0x2281c144938f
-                0x2281c142b664
-                0x2281c1417d97
-                v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.11^3240988^HTMLParserThrea^chrome               ^[.] WTF::equalIgnoringCaseNonNull(WTF::StringImpl const*, WTF::StringImpl const*)
-            |
-            --- WTF::equalIgnoringCaseNonNull(WTF::StringImpl const*, WTF::StringImpl const*)
-
-0.11^3237736^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::call(v8::internal::Handle<v8::internal::Code>, v8::internal::RelocInfo::Mode, v8::internal::TypeFeedbackId)
-            |
-            --- v8::internal::Assembler::call(v8::internal::Handle<v8::internal::Code>, v8::internal::RelocInfo::Mode, v8::internal::TypeFeedbackId)
-
-0.11^3228754^HTMLParserThrea^libpthread-2.15.so   ^[.] pthread_mutex_unlock
-            |
-            --- pthread_mutex_unlock
-
-0.11^3225835^HTMLParserThrea^chrome               ^[.] WebCore::RenderObject::repaintUsingContainer(WebCore::RenderLayerModelObject const*, WebCore::IntRect const&) const
-            |
-            --- WebCore::RenderObject::repaintUsingContainer(WebCore::RenderLayerModelObject const*, WebCore::IntRect const&) const
-
-0.11^3219559^HTMLParserThrea^chrome               ^[.] icu_46::RuleBasedBreakIterator::handleNext(icu_46::RBBIStateTable const*)
-            |
-            --- icu_46::RuleBasedBreakIterator::handleNext(icu_46::RBBIStateTable const*)
-
-0.11^3215902^HTMLParserThrea^chrome               ^[.] v8::internal::Scanner::Scanner(v8::internal::UnicodeCache*)
-            |
-            --- v8::internal::Scanner::Scanner(v8::internal::UnicodeCache*)
-                0x7f7a0b900000
-
-0.11^3202188^HTMLParserThrea^chrome               ^[.] v8::Object::FindInstanceInPrototypeChain(v8::Handle<v8::FunctionTemplate>)
-            |
-            --- v8::Object::FindInstanceInPrototypeChain(v8::Handle<v8::FunctionTemplate>)
-
-0.11^3202083^HTMLParserThrea^chrome               ^[.] WebCore::Element::attach(WebCore::Node::AttachContext const&)
-            |
-            --- WebCore::Element::attach(WebCore::Node::AttachContext const&)
-
-0.11^3200673^HTMLParserThrea^chrome               ^[.] v8::internal::CompareIC::NewInputState(v8::internal::CompareIC::State, v8::internal::Handle<v8::internal::Object>)
-            |
-            --- v8::internal::CompareIC::NewInputState(v8::internal::CompareIC::State, v8::internal::Handle<v8::internal::Object>)
-
-0.11^3176018^HTMLParserThrea^chrome               ^[.] WebCore::Element::recalcStyle(WebCore::Node::StyleChange)
-            |
-            --- WebCore::Element::recalcStyle(WebCore::Node::StyleChange)
-
-0.11^3170916^HTMLParserThrea^chrome               ^[.] WebCore::MajorGCWrapperVisitor::VisitPersistentHandle(v8::Persistent<v8::Value>*, unsigned short)
-            |
-            --- WebCore::MajorGCWrapperVisitor::VisitPersistentHandle(v8::Persistent<v8::Value>*, unsigned short)
-                0x80e894c5308
-
-0.10^3137671^HTMLParserThrea^chrome               ^[.] v8::internal::DependentCode::DeoptimizeDependentCodeGroup(v8::internal::Isolate*, v8::internal::DependentCode::DependencyGroup)
-            |
-            --- v8::internal::DependentCode::DeoptimizeDependentCodeGroup(v8::internal::Isolate*, v8::internal::DependentCode::DependencyGroup)
-
-0.10^3136480^HTMLParserThrea^chrome               ^[.] WebCore::DOMWindow::document() const
-            |
-            --- WebCore::DOMWindow::document() const
-
-0.10^3136403^HTMLParserThrea^chrome               ^[.] _ZNK3WTF7HashMapIPN7WebCore12RenderObjectENS_6RefPtrINS1_18CompositeAnimationEEENS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS9_IS6_EEE3getERKS3_.isra.185
-            |
-            --- _ZNK3WTF7HashMapIPN7WebCore12RenderObjectENS_6RefPtrINS1_18CompositeAnimationEEENS_7PtrHashIS3_EENS_10HashTraitsIS3_EENS9_IS6_EEE3getERKS3_.isra.185
-
-0.10^3126165^HTMLParserThrea^chrome               ^[.] v8::internal::VariableProxy::BindTo(v8::internal::Variable*)
-            |
-            --- v8::internal::VariableProxy::BindTo(v8::internal::Variable*)
-                0x3b2abdf3f010
-
-0.10^3124159^HTMLParserThrea^chrome               ^[.] WebCore::InlineTextBox::logicalOverflowRect() const
-            |
-            --- WebCore::InlineTextBox::logicalOverflowRect() const
-                0xaf00000000
-                0x3b2abdda8680
-
-0.10^3121836^HTMLParserThrea^chrome               ^[.] v8::internal::JSObject::SetPropertyViaPrototypes(v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::StrictModeFlag, bool*)
-            |
-            --- v8::internal::JSObject::SetPropertyViaPrototypes(v8::internal::Name*, v8::internal::Object*, PropertyAttributes, v8::internal::StrictModeFlag, bool*)
-
-0.10^3107295^HTMLParserThrea^chrome               ^[.] WebCore::ElementStyleResources::ElementStyleResources()
-            |
-            --- WebCore::ElementStyleResources::ElementStyleResources()
-
-0.10^3103474^HTMLParserThrea^chrome               ^[.] void WTF::deleteAllValues<true, WebCore::RenderBlock::FloatingObject*, WTF::HashTable<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*, WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*, WTF::IdentityExtractor, WTF::ListHashSetNodeHashFunctions<WebCore::RenderBlock::FloatingObjectHashFunctions>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*>, WTF::HashTraits<WTF::ListHashSetNode<WebCo
-            |
-            --- void WTF::deleteAllValues<true, WebCore::RenderBlock::FloatingObject*, WTF::HashTable<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*, WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*, WTF::IdentityExtractor, WTF::ListHashSetNodeHashFunctions<WebCore::RenderBlock::FloatingObjectHashFunctions>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*> > const>(WTF::HashTable<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*, WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*, WTF::IdentityExtractor, WTF::ListHashSetNodeHashFunctions<WebCore::RenderBlock::FloatingObjectHashFunctions>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::RenderBlock::FloatingObject*, 4ul>*> > const&)
-
-0.10^3103474^HTMLParserThrea^chrome               ^[.] base::subtle::RefCountedBase::Release() const
-            |
-            --- base::subtle::RefCountedBase::Release() const
-
-0.10^3092884^HTMLParserThrea^chrome               ^[.] WebCore::RenderView::usesCompositing() const
-            |
-            --- WebCore::RenderView::usesCompositing() const
-
-0.10^3090079^HTMLParserThrea^chrome               ^[.] webCoreInitializeScriptWrappableForInterface(WebCore::Element*)
-            |
-            --- webCoreInitializeScriptWrappableForInterface(WebCore::Element*)
-
-0.10^3084985^HTMLParserThrea^chrome               ^[.] WebCore::ScopedStyleTree::pushStyleCache(WebCore::ContainerNode const*, WebCore::ContainerNode const*)
-            |
-            --- WebCore::ScopedStyleTree::pushStyleCache(WebCore::ContainerNode const*, WebCore::ContainerNode const*)
-
-0.10^3075629^HTMLParserThrea^chrome               ^[.] v8::internal::HydrogenCodeStub::MinorKey()
-            |
-            --- v8::internal::HydrogenCodeStub::MinorKey()
-
-0.10^3075535^HTMLParserThrea^librt-2.15.so        ^[.] clock_gettime
-            |
-            --- clock_gettime
-
-0.10^3066941^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::jmp(v8::internal::Handle<v8::internal::Code>, v8::internal::RelocInfo::Mode)
-            |
-            --- v8::internal::Assembler::jmp(v8::internal::Handle<v8::internal::Code>, v8::internal::RelocInfo::Mode)
-
-0.10^3064555^HTMLParserThrea^chrome               ^[.] WebCore::RenderStyle::getRoundedBorderFor(WebCore::LayoutRect const&, WebCore::RenderView*, bool, bool) const
-            |
-            --- WebCore::RenderStyle::getRoundedBorderFor(WebCore::LayoutRect const&, WebCore::RenderView*, bool, bool) const
-
-0.10^3056872^HTMLParserThrea^chrome               ^[.] WebCore::LayoutRect::intersect(WebCore::LayoutRect const&)
-            |
-            --- WebCore::LayoutRect::intersect(WebCore::LayoutRect const&)
-                (nil)
-
-0.10^3056623^HTMLParserThrea^chrome               ^[.] v8::internal::CodeCacheHashTable::Put(v8::internal::Name*, v8::internal::Code*)
-            |
-            --- v8::internal::CodeCacheHashTable::Put(v8::internal::Name*, v8::internal::Code*)
-
-0.10^3054623^HTMLParserThrea^chrome               ^[.] v8::internal::ActionNode::GetQuickCheckDetails(v8::internal::QuickCheckDetails*, v8::internal::RegExpCompiler*, int, bool)
-            |
-            --- v8::internal::ActionNode::GetQuickCheckDetails(v8::internal::QuickCheckDetails*, v8::internal::RegExpCompiler*, int, bool)
-                0x3b2a00000002
-
-0.10^3051571^HTMLParserThrea^chrome               ^[.] _ZN2v88internal12PropertyCell17SetValueInferTypeEPNS0_6ObjectENS0_16WriteBarrierModeE.part.326
-            |
-            --- _ZN2v88internal12PropertyCell17SetValueInferTypeEPNS0_6ObjectENS0_16WriteBarrierModeE.part.326
-
-0.10^3047011^HTMLParserThrea^chrome               ^[.] WebCore::RenderBoxModelObject::paintFillLayerExtended(WebCore::PaintInfo const&, WebCore::Color const&, WebCore::FillLayer const*, WebCore::LayoutRect const&, WebCore::BackgroundBleedAvoidance, WebCore::InlineFlowBox*, WebCore::LayoutSize const&, WebCore::CompositeOperator, WebCore::RenderObject*)
-            |
-            --- WebCore::RenderBoxModelObject::paintFillLayerExtended(WebCore::PaintInfo const&, WebCore::Color const&, WebCore::FillLayer const*, WebCore::LayoutRect const&, WebCore::BackgroundBleedAvoidance, WebCore::InlineFlowBox*, WebCore::LayoutSize const&, WebCore::CompositeOperator, WebCore::RenderObject*)
-
-0.10^3047011^HTMLParserThrea^chrome               ^[.] WebCore::Timer<WebCore::EventSender<WebCore::ImageLoader> >::fired()
-            |
-            --- WebCore::Timer<WebCore::EventSender<WebCore::ImageLoader> >::fired()
-
-0.10^3042405^HTMLParserThrea^chrome               ^[.] SkGlyphCache::getGlyphIDMetrics(unsigned short)
-            |
-            --- SkGlyphCache::getGlyphIDMetrics(unsigned short)
-
-0.10^3034275^HTMLParserThrea^chrome               ^[.] WebCore::StyleBuilder::applyProperty(WebCore::CSSPropertyID, WebCore::StyleResolver*, WebCore::StyleResolverState&, WebCore::CSSValue*, bool, bool)
-            |
-            --- WebCore::StyleBuilder::applyProperty(WebCore::CSSPropertyID, WebCore::StyleResolver*, WebCore::StyleResolverState&, WebCore::CSSValue*, bool, bool)
-                0x1e83176a8568
-
-0.10^3027837^HTMLParserThrea^chrome               ^[.] v8::preparser::PreParser::ParseBinaryExpression(int, bool, bool*)
-            |
-            --- v8::preparser::PreParser::ParseBinaryExpression(int, bool, bool*)
-                0x7f7a0b96214000
-
-0.10^3027190^HTMLParserThrea^chrome               ^[.] v8::internal::CallOptimization::GetPrototypeDepthOfExpectedType(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::JSObject>) const
-            |
-            --- v8::internal::CallOptimization::GetPrototypeDepthOfExpectedType(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::JSObject>) const
-
-0.10^3025376^HTMLParserThrea^chrome               ^[.] v8::Function::Call(v8::Handle<v8::Object>, int, v8::Handle<v8::Value>*)
-            |
-            --- v8::Function::Call(v8::Handle<v8::Object>, int, v8::Handle<v8::Value>*)
-
-0.10^3019937^HTMLParserThrea^chrome               ^[.] net::HttpResponseHeaders::EnumerateHeader(void**, base::BasicStringPiece<std::string> const&, std::string*) const
-            |
-            --- net::HttpResponseHeaders::EnumerateHeader(void**, base::BasicStringPiece<std::string> const&, std::string*) const
-                0x7fff30e91800
-
-0.10^3017488^HTMLParserThrea^chrome               ^[.] v8::internal::Parser::ParseLazy()
-            |
-            --- v8::internal::Parser::ParseLazy()
-
-0.10^3014944^HTMLParserThrea^chrome               ^[.] WebCore::MarkupAccumulator::appendAttribute(WTF::StringBuilder&, WebCore::Element*, WebCore::Attribute const&, WTF::HashMap<WTF::AtomicStringImpl*, WTF::AtomicStringImpl*, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*> >*)
-            |
-            --- WebCore::MarkupAccumulator::appendAttribute(WTF::StringBuilder&, WebCore::Element*, WebCore::Attribute const&, WTF::HashMap<WTF::AtomicStringImpl*, WTF::AtomicStringImpl*, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*> >*)
-
-0.10^3005563^HTMLParserThrea^chrome               ^[.] tcmalloc::PageHeap::Carve(tcmalloc::Span*, unsigned long)
-            |
-            --- tcmalloc::PageHeap::Carve(tcmalloc::Span*, unsigned long)
-
-0.10^3002471^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::paintOutlineForFragments(WTF::Vector<WebCore::LayerFragment, 1ul> const&, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*)
-            |
-            --- WebCore::RenderLayer::paintOutlineForFragments(WTF::Vector<WebCore::LayerFragment, 1ul> const&, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*)
-
-0.10^2988466^HTMLParserThrea^chrome               ^[.] v8::internal::CompareIC::TargetState(v8::internal::CompareIC::State, v8::internal::CompareIC::State, v8::internal::CompareIC::State, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>)
-            |
-            --- v8::internal::CompareIC::TargetState(v8::internal::CompareIC::State, v8::internal::CompareIC::State, v8::internal::CompareIC::State, bool, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>)
-
-0.10^2985776^HTMLParserThrea^chrome               ^[.] v8::internal::CodeStub::UseSpecialCache()
-            |
-            --- v8::internal::CodeStub::UseSpecialCache()
-
-0.10^2983793^HTMLParserThrea^chrome               ^[.] v8::internal::Genesis::TransferNamedProperties(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::JSObject>)
-            |
-            --- v8::internal::Genesis::TransferNamedProperties(v8::internal::Handle<v8::internal::JSObject>, v8::internal::Handle<v8::internal::JSObject>)
-
-0.10^2978233^HTMLParserThrea^chrome               ^[.] v8::internal::ReturnStatement::Accept(v8::internal::AstVisitor*)
-            |
-            --- v8::internal::ReturnStatement::Accept(v8::internal::AstVisitor*)
-
-0.10^2961361^HTMLParserThrea^chrome               ^[.] WebCore::HTMLInputElement::parseAttribute(WebCore::QualifiedName const&, WTF::AtomicString const&)
-            |
-            --- WebCore::HTMLInputElement::parseAttribute(WebCore::QualifiedName const&, WTF::AtomicString const&)
-                WebCore::V8PerIsolateData::hasInstance(WebCore::WrapperTypeInfo*, v8::Handle<v8::Value>, WebCore::WrapperWorldType)
-
-0.10^2950771^HTMLParserThrea^chrome               ^[.] webkit::ppapi::PluginInstance::Paint(SkCanvas*, gfx::Rect const&, gfx::Rect const&)
-            |
-            --- webkit::ppapi::PluginInstance::Paint(SkCanvas*, gfx::Rect const&, gfx::Rect const&)
-
-0.10^2941407^HTMLParserThrea^chrome               ^[.] WebCore::DocumentStyleSheetCollection::combineCSSFeatureFlags(WebCore::RuleFeatureSet const&)
-            |
-            --- WebCore::DocumentStyleSheetCollection::combineCSSFeatureFlags(WebCore::RuleFeatureSet const&)
-
-0.10^2927492^HTMLParserThrea^chrome               ^[.] SkCanvas::~SkCanvas()
-            |
-            --- SkCanvas::~SkCanvas()
-
-0.10^2924222^HTMLParserThrea^chrome               ^[.] WTF::HashTableAddResult<WTF::HashTableIterator<unsigned long, WTF::KeyValuePair<unsigned long, WTF::OwnPtr<WebCore::ProgressItem> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<unsigned long, WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::IntHash<unsigned long>, WTF::HashMapValueTraits<WTF::HashTraits<unsigned long>, WTF::HashTraits<WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::HashTraits<unsigned long> > > WTF::HashTable<unsigned long, WTF::KeyValueP
-            |
-            --- WTF::HashTableAddResult<WTF::HashTableIterator<unsigned long, WTF::KeyValuePair<unsigned long, WTF::OwnPtr<WebCore::ProgressItem> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<unsigned long, WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::IntHash<unsigned long>, WTF::HashMapValueTraits<WTF::HashTraits<unsigned long>, WTF::HashTraits<WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::HashTraits<unsigned long> > > WTF::HashTable<unsigned long, WTF::KeyValuePair<unsigned long, WTF::OwnPtr<WebCore::ProgressItem> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<unsigned long, WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::IntHash<unsigned long>, WTF::HashMapValueTraits<WTF::HashTraits<unsigned long>, WTF::HashTraits<WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::HashTraits<unsigned long> >::add<WTF::HashMapTranslator<WTF::HashMapValueTraits<WTF::HashTraits<unsigned long>, WTF::HashTraits<WTF::OwnPtr<WebCore::ProgressItem> > >, WTF::IntHash<unsigned long> >, unsigned long, WTF::PassOwnPtr<WebCore::ProgressItem> >(unsigned long const&, WTF::PassOwnPtr<WebCore::ProgressItem> const&)
-
-0.10^2912173^HTMLParserThrea^chrome               ^[.] v8::internal::Genesis::CreateNewGlobals(v8::Handle<v8::ObjectTemplate>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::GlobalObject>*)
-            |
-            --- v8::internal::Genesis::CreateNewGlobals(v8::Handle<v8::ObjectTemplate>, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::GlobalObject>*)
-
-0.10^2898436^HTMLParserThrea^chrome               ^[.] v8::internal::Runtime_FunctionSetName(int, v8::internal::Object**, v8::internal::Isolate*)
-            |
-            --- v8::internal::Runtime_FunctionSetName(int, v8::internal::Object**, v8::internal::Isolate*)
-                0x2281c14315f1
-                0x2281c14310e9
-                0x2281c1434402
-                0x2281c142b664
-                0x2281c1417d97
-                v8::internal::Invoke(bool, v8::internal::Handle<v8::internal::JSFunction>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*, bool*)
-
-0.10^2892794^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::AllocateUninitializedFixedArray(int)
-            |
-            --- v8::internal::Heap::AllocateUninitializedFixedArray(int)
-
-0.10^2891663^HTMLParserThrea^chrome               ^[.] content::RenderViewImpl::didCommitProvisionalLoad(WebKit::WebFrame*, bool)
-            |
-            --- content::RenderViewImpl::didCommitProvisionalLoad(WebKit::WebFrame*, bool)
-
-0.10^2867709^HTMLParserThrea^chrome               ^[.] v8::internal::Object::GetPropertyWithReceiver(v8::internal::Object*, v8::internal::Name*, PropertyAttributes*)
-            |
-            --- v8::internal::Object::GetPropertyWithReceiver(v8::internal::Object*, v8::internal::Name*, PropertyAttributes*)
-
-0.09^2852873^HTMLParserThrea^chrome               ^[.] WebCore::RenderLineBoxList::deleteLineBoxes(WebCore::RenderArena*)
-            |
-            --- WebCore::RenderLineBoxList::deleteLineBoxes(WebCore::RenderArena*)
-
-0.09^2848135^HTMLParserThrea^chrome               ^[.] base::internal::IncomingTaskQueue::PostPendingTask(base::PendingTask*)
-            |
-            --- base::internal::IncomingTaskQueue::PostPendingTask(base::PendingTask*)
-
-0.09^2845960^HTMLParserThrea^chrome               ^[.] WebCore::V8HTMLEmbedElement::namedPropertyGetterCustom(v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const&)
-            |
-            --- WebCore::V8HTMLEmbedElement::namedPropertyGetterCustom(v8::Local<v8::String>, v8::PropertyCallbackInfo<v8::Value> const&)
-                0x7f7a0b900000
-
-0.09^2831855^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int)
-            |
-            --- WebCore::RenderLayer::paintLayerContents(WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int)
-                (nil)
-
-0.09^2830116^HTMLParserThrea^chrome               ^[.] v8::internal::RegExpParser::Advance()
-            |
-            --- v8::internal::RegExpParser::Advance()
-                0x3b2abdce1010
-
-0.09^2802116^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::logicalLeftFloatOffsetForLine(WebCore::LayoutUnit, WebCore::LayoutUnit, WebCore::LayoutUnit*, WebCore::LayoutUnit, WebCore::RenderBlock::ShapeOutsideFloatOffsetMode) const
-            |
-            --- WebCore::RenderBlock::logicalLeftFloatOffsetForLine(WebCore::LayoutUnit, WebCore::LayoutUnit, WebCore::LayoutUnit*, WebCore::LayoutUnit, WebCore::RenderBlock::ShapeOutsideFloatOffsetMode) const
-
-0.09^2792893^HTMLParserThrea^chrome               ^[.] v8::internal::HashTable<v8::internal::UnseededNumberDictionaryShape, unsigned int>::FindEntry(v8::internal::Isolate*, unsigned int)
-            |
-            --- v8::internal::HashTable<v8::internal::UnseededNumberDictionaryShape, unsigned int>::FindEntry(v8::internal::Isolate*, unsigned int)
-
-0.09^2758347^HTMLParserThrea^chrome               ^[.] v8::internal::ElementsAccessorBase<v8::internal::DictionaryElementsAccessor, v8::internal::ElementsKindTraits<(v8::internal::ElementsKind)6> >::Get(v8::internal::Object*, v8::internal::JSObject*, unsigned int, v8::internal::FixedArrayBase*)
-            |
-            --- v8::internal::ElementsAccessorBase<v8::internal::DictionaryElementsAccessor, v8::internal::ElementsKindTraits<(v8::internal::ElementsKind)6> >::Get(v8::internal::Object*, v8::internal::JSObject*, unsigned int, v8::internal::FixedArrayBase*)
-
-0.09^2738185^HTMLParserThrea^chrome               ^[.] v8::internal::LoadFieldStub::MajorKey()
-            |
-            --- v8::internal::LoadFieldStub::MajorKey()
-
-0.09^2719813^HTMLParserThrea^chrome               ^[.] _ZN2v88internal9Execution4CallENS0_6HandleINS0_6ObjectEEES4_iPS4_Pbb.constprop.84
-            |
-            --- _ZN2v88internal9Execution4CallENS0_6HandleINS0_6ObjectEEES4_iPS4_Pbb.constprop.84
-
-0.09^2709340^HTMLParserThrea^chrome               ^[.] operator delete(void*)
-            |
-            --- operator delete(void*)
-
-0.09^2697911^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::AllocateVariablesRecursively()
-            |
-            --- v8::internal::Scope::AllocateVariablesRecursively()
-
-0.09^2685980^HTMLParserThrea^chrome               ^[.] IPC::SyncChannel::SendWithTimeout(IPC::Message*, int)
-            |
-            --- IPC::SyncChannel::SendWithTimeout(IPC::Message*, int)
-
-0.09^2673092^HTMLParserThrea^chrome               ^[.] v8::internal::StubCache::ComputeCallPreMonomorphic(int, v8::internal::Code::Kind, int)
-            |
-            --- v8::internal::StubCache::ComputeCallPreMonomorphic(int, v8::internal::Code::Kind, int)
-
-0.09^2660139^HTMLParserThrea^chrome               ^[.] v8::internal::HashTable<v8::internal::CodeCacheHashTableShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::HashTableKey*)
-            |
-            --- v8::internal::HashTable<v8::internal::CodeCacheHashTableShape, v8::internal::HashTableKey*>::FindEntry(v8::internal::HashTableKey*)
-
-0.09^2639411^HTMLParserThrea^chrome               ^[.] base::subtle::RefCountedThreadSafeBase::HasOneRef() const
-            |
-            --- base::subtle::RefCountedThreadSafeBase::HasOneRef() const
-                0x3b2abd1f8b20
-
-0.09^2639411^HTMLParserThrea^chrome               ^[.] PickleIterator::ReadLong(long*)
-            |
-            --- PickleIterator::ReadLong(long*)
-                0x2e40c81e951be0
-
-0.09^2632999^HTMLParserThrea^chrome               ^[.] IPC::SyncChannel::SyncContext::DispatchMessages()
-            |
-            --- IPC::SyncChannel::SyncContext::DispatchMessages()
-
-0.09^2600329^HTMLParserThrea^chrome               ^[.] v8::internal::Operand::Operand(v8::internal::Register, int)
-            |
-            --- v8::internal::Operand::Operand(v8::internal::Register, int)
-                0x3b2abd628000
-
-0.09^2577224^HTMLParserThrea^chrome               ^[.] v8::internal::CompareIC::ComputeCondition(v8::internal::Token::Value)
-            |
-            --- v8::internal::CompareIC::ComputeCondition(v8::internal::Token::Value)
-
-0.09^2566312^HTMLParserThrea^chrome               ^[.] v8::internal::Rewriter::Rewrite(v8::internal::CompilationInfo*)
-            |
-            --- v8::internal::Rewriter::Rewrite(v8::internal::CompilationInfo*)
-                0x7f7a0b900000
-
-0.08^2546113^HTMLParserThrea^chrome               ^[.] WebCore::RenderBoxModelObject::borderLeft() const
-            |
-            --- WebCore::RenderBoxModelObject::borderLeft() const
-
-0.08^2538991^HTMLParserThrea^chrome               ^[.] v8::internal::Handle<v8::internal::String> v8::internal::URIEscape::Escape<unsigned char>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>)
-            |
-            --- v8::internal::Handle<v8::internal::String> v8::internal::URIEscape::Escape<unsigned char>(v8::internal::Isolate*, v8::internal::Handle<v8::internal::String>)
-
-0.08^2527291^HTMLParserThrea^chrome               ^[.] WTF::HashTableAddResult<WTF::HashTableIterator<WTF::StringImpl*, WTF::StringImpl*, WTF::IdentityExtractor, WTF::StringHash, WTF::HashTraits<WTF::StringImpl*>, WTF::HashTraits<WTF::StringImpl*> > > WTF::HashTable<WTF::StringImpl*, WTF::StringImpl*, WTF::IdentityExtractor, WTF::StringHash, WTF::HashTraits<WTF::StringImpl*>, WTF::HashTraits<WTF::StringImpl*> >::add<WTF::IdentityHashTranslator<WTF::StringHash>, WTF::StringImpl*, WTF::StringImpl*>(WTF::Stri
-            |
-            --- WTF::HashTableAddResult<WTF::HashTableIterator<WTF::StringImpl*, WTF::StringImpl*, WTF::IdentityExtractor, WTF::StringHash, WTF::HashTraits<WTF::StringImpl*>, WTF::HashTraits<WTF::StringImpl*> > > WTF::HashTable<WTF::StringImpl*, WTF::StringImpl*, WTF::IdentityExtractor, WTF::StringHash, WTF::HashTraits<WTF::StringImpl*>, WTF::HashTraits<WTF::StringImpl*> >::add<WTF::IdentityHashTranslator<WTF::StringHash>, WTF::StringImpl*, WTF::StringImpl*>(WTF::StringImpl* const&, WTF::StringImpl* const&)
-                0x7fff30e91098
-
-0.08^2505118^HTMLParserThrea^chrome               ^[.] v8::internal::AssertionNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)
-            |
-            --- v8::internal::AssertionNode::Emit(v8::internal::RegExpCompiler*, v8::internal::Trace*)
-                0xa
-
-0.08^2499686^HTMLParserThrea^chrome               ^[.] base::SampleVector::GetBucketIndex(int) const
-            |
-            --- base::SampleVector::GetBucketIndex(int) const
-
-0.08^2493442^HTMLParserThrea^chrome               ^[.] v8::internal::RegExpImpl::SetLastMatchInfo(v8::internal::Handle<v8::internal::JSArray>, v8::internal::Handle<v8::internal::String>, int, int*)
-            |
-            --- v8::internal::RegExpImpl::SetLastMatchInfo(v8::internal::Handle<v8::internal::JSArray>, v8::internal::Handle<v8::internal::String>, int, int*)
-
-0.08^2449547^HTMLParserThrea^chrome               ^[.] content::(anonymous namespace)::RendererMessageLoopObserver::DidProcessTask(base::PendingTask const&)
-            |
-            --- content::(anonymous namespace)::RendererMessageLoopObserver::DidProcessTask(base::PendingTask const&)
-                0x7f7a0b8ff200
-
-0.08^2382741^HTMLParserThrea^chrome               ^[.] WTF::HashTableAddResult<WTF::HashTableIterator<WebCore::CachedResource*, WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*>, WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::H
-            |
-            --- WTF::HashTableAddResult<WTF::HashTableIterator<WebCore::CachedResource*, WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*>, WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::HashTraits<WebCore::CachedResource*> > > WTF::HashTable<WebCore::CachedResource*, WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> >, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WebCore::CachedResource*, WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*>, WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::HashTraits<WebCore::CachedResource*> >::add<WTF::HashMapTranslator<WTF::HashMapValueTraits<WTF::HashTraits<WebCore::CachedResource*>, WTF::HashTraits<WTF::RefPtr<WebCore::ResourceTimingInfo> > >, WTF::PtrHash<WebCore::CachedResource*> >, WebCore::CachedResource*, WTF::PassRefPtr<WebCore::ResourceTimingInfo> >(WebCore::CachedResource* const&, WTF::PassRefPtr<WebCore::ResourceTimingInfo> const&)
-
-0.08^2347799^HTMLParserThrea^chrome               ^[.] v8::internal::Isolate::MayNamedAccess(v8::internal::JSObject*, v8::internal::Object*, v8::AccessType)
-            |
-            --- v8::internal::Isolate::MayNamedAccess(v8::internal::JSObject*, v8::internal::Object*, v8::AccessType)
-
-0.08^2337746^HTMLParserThrea^chrome               ^[.] v8::internal::Heap::NumberFromDouble(double, v8::internal::PretenureFlag)
-            |
-            --- v8::internal::Heap::NumberFromDouble(double, v8::internal::PretenureFlag)
-
-0.08^2334937^HTMLParserThrea^chrome               ^[.] WebCore::LayoutRect::intersects(WebCore::LayoutRect const&) const
-            |
-            --- WebCore::LayoutRect::intersects(WebCore::LayoutRect const&) const
-
-0.08^2315633^HTMLParserThrea^chrome               ^[.] _ZN7content14RenderViewImpl15willSendRequestEPN6WebKit8WebFrameEjRNS1_13WebURLRequestERKNS1_14WebURLResponseE.part.953
-            |
-            --- _ZN7content14RenderViewImpl15willSendRequestEPN6WebKit8WebFrameEjRNS1_13WebURLRequestERKNS1_14WebURLResponseE.part.953
-                0x7f7a11c1f320
-                0x7fff30e90fd0
-
-0.08^2309876^HTMLParserThrea^libstdc++.so.6.0.16  ^[.] std::string::find_first_not_of(char const*, unsigned long, unsigned long) const
-            |
-            --- std::string::find_first_not_of(char const*, unsigned long, unsigned long) const
-                (nil)
-
-0.08^2271635^HTMLParserThrea^chrome               ^[.] base::TaskQueue::Swap(base::TaskQueue*)
-            |
-            --- base::TaskQueue::Swap(base::TaskQueue*)
-
-0.08^2270859^HTMLParserThrea^chrome               ^[.] v8::internal::Map::ShareDescriptor(v8::internal::DescriptorArray*, v8::internal::Descriptor*)
-            |
-            --- v8::internal::Map::ShareDescriptor(v8::internal::DescriptorArray*, v8::internal::Descriptor*)
-
-0.08^2267153^HTMLParserThrea^chrome               ^[.] v8::internal::Map::EnsureDescriptorSlack(v8::internal::Handle<v8::internal::Map>, int)
-            |
-            --- v8::internal::Map::EnsureDescriptorSlack(v8::internal::Handle<v8::internal::Map>, int)
-
-0.07^2254719^HTMLParserThrea^chrome               ^[.] v8::internal::Map::IndexInCodeCache(v8::internal::Object*, v8::internal::Code*)
-            |
-            --- v8::internal::Map::IndexInCodeCache(v8::internal::Object*, v8::internal::Code*)
-
-0.07^2218397^HTMLParserThrea^chrome               ^[.] WebCore::RenderBlock::paintContents(WebCore::PaintInfo&, WebCore::LayoutPoint const&)
-            |
-            --- WebCore::RenderBlock::paintContents(WebCore::PaintInfo&, WebCore::LayoutPoint const&)
-
-0.07^2215989^HTMLParserThrea^chrome               ^[.] SkRegion::freeRuns()
-            |
-            --- SkRegion::freeRuns()
-
-0.07^2213591^HTMLParserThrea^libpthread-2.15.so   ^[.] pthread_cond_destroy@@GLIBC_2.3.2
-            |
-            --- pthread_cond_destroy@@GLIBC_2.3.2
-
-0.07^2185498^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::paintForegroundForFragmentsWithPhase(WebCore::PaintPhase, WTF::Vector<WebCore::LayerFragment, 1ul> const&, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*)
-            |
-            --- WebCore::RenderLayer::paintForegroundForFragmentsWithPhase(WebCore::PaintPhase, WTF::Vector<WebCore::LayerFragment, 1ul> const&, WebCore::GraphicsContext*, WebCore::RenderLayer::LayerPaintingInfo const&, unsigned int, WebCore::RenderObject*)
-                (nil)
-
-0.07^2181719^HTMLParserThrea^chrome               ^[.] v8::internal::JSFunction::CompileLazy(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ClearExceptionFlag)
-            |
-            --- v8::internal::JSFunction::CompileLazy(v8::internal::Handle<v8::internal::JSFunction>, v8::internal::ClearExceptionFlag)
-
-0.07^2181709^HTMLParserThrea^chrome               ^[.] base::subtle::RefCountedThreadSafeBase::AddRef() const
-            |
-            --- base::subtle::RefCountedThreadSafeBase::AddRef() const
-
-0.07^2162161^HTMLParserThrea^chrome               ^[.] v8::internal::LChunk::MarkEmptyBlocks()
-            |
-            --- v8::internal::LChunk::MarkEmptyBlocks()
-
-0.07^2154798^HTMLParserThrea^chrome               ^[.] v8::preparser::PreParser::ParsePostfixExpression(bool*)
-            |
-            --- v8::preparser::PreParser::ParsePostfixExpression(bool*)
-
-0.07^2153747^HTMLParserThrea^chrome               ^[.] WebCore::deviceScaleFactor(WebCore::Frame*)
-            |
-            --- WebCore::deviceScaleFactor(WebCore::Frame*)
-                (nil)
-
-0.07^2111797^HTMLParserThrea^chrome               ^[.] v8::preparser::PreParser::ParseConditionalExpression(bool, bool*)
-            |
-            --- v8::preparser::PreParser::ParseConditionalExpression(bool, bool*)
-                0x3b2abe08368000
-
-0.07^2107366^HTMLParserThrea^chrome               ^[.] ppapi::thunk::subtle::EnterBase::EnterBase(int)
-            |
-            --- ppapi::thunk::subtle::EnterBase::EnterBase(int)
-
-0.07^2061079^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::EmitBackEdgeTable()
-            |
-            --- v8::internal::FullCodeGenerator::EmitBackEdgeTable()
-
-0.07^2055678^HTMLParserThrea^chrome               ^[.] WebCore::MarkupAccumulator::appendStartMarkup(WTF::StringBuilder&, WebCore::Node const*, WTF::HashMap<WTF::AtomicStringImpl*, WTF::AtomicStringImpl*, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*> >*)
-            |
-            --- WebCore::MarkupAccumulator::appendStartMarkup(WTF::StringBuilder&, WebCore::Node const*, WTF::HashMap<WTF::AtomicStringImpl*, WTF::AtomicStringImpl*, WTF::PtrHash<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*>, WTF::HashTraits<WTF::AtomicStringImpl*> >*)
-                (nil)
-
-0.07^2053845^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::flipForWritingMode(WebCore::LayoutRect&) const
-            |
-            --- WebCore::RenderBox::flipForWritingMode(WebCore::LayoutRect&) const
-
-0.07^2043240^HTMLParserThrea^chrome               ^[.] net::HttpUtil::HeadersIterator::GetNext()
-            |
-            --- net::HttpUtil::HeadersIterator::GetNext()
-                0x7f7a0689c4d8
-
-0.07^2038325^HTMLParserThrea^chrome               ^[.] WTF::HashTable<WTF::AtomicString, WTF::KeyValuePair<WTF::AtomicString, WTF::AtomicString>, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::AtomicString, WTF::AtomicString> >, WTF::CaseFoldingHash, WTF::HashMapValueTraits<WTF::HashTraits<WTF::AtomicString>, WTF::HashTraits<WTF::AtomicString> >, WTF::HashTraits<WTF::AtomicString> >::rehash(int)
-            |
-            --- WTF::HashTable<WTF::AtomicString, WTF::KeyValuePair<WTF::AtomicString, WTF::AtomicString>, WTF::KeyValuePairKeyExtractor<WTF::KeyValuePair<WTF::AtomicString, WTF::AtomicString> >, WTF::CaseFoldingHash, WTF::HashMapValueTraits<WTF::HashTraits<WTF::AtomicString>, WTF::HashTraits<WTF::AtomicString> >, WTF::HashTraits<WTF::AtomicString> >::rehash(int)
-
-0.07^2038325^HTMLParserThrea^chrome               ^[.] WebCore::KURL::isValid() const
-            |
-            --- WebCore::KURL::isValid() const
-
-0.07^2030555^HTMLParserThrea^chrome               ^[.] v8::internal::Scope::LocalLookup(v8::internal::Handle<v8::internal::String>)
-            |
-            --- v8::internal::Scope::LocalLookup(v8::internal::Handle<v8::internal::String>)
-
-0.07^2017287^HTMLParserThrea^chrome               ^[.] WebKit::WebFrameImpl::document() const
-            |
-            --- WebKit::WebFrameImpl::document() const
-
-0.07^1991309^HTMLParserThrea^chrome               ^[.] v8::internal::Assembler::int3()
-            |
-            --- v8::internal::Assembler::int3()
-
-0.07^1989976^HTMLParserThrea^chrome               ^[.] __gnu_cxx::hashtable<std::pair<int const, std::pair<ppapi::Resource*, int> >, int, __gnu_cxx::hash<int>, std::_Select1st<std::pair<int const, std::pair<ppapi::Resource*, int> > >, std::equal_to<int>, std::allocator<std::pair<ppapi::Resource*, int> > >::find_or_insert(std::pair<int const, std::pair<ppapi::Resource*, int> > const&)
-            |
-            --- __gnu_cxx::hashtable<std::pair<int const, std::pair<ppapi::Resource*, int> >, int, __gnu_cxx::hash<int>, std::_Select1st<std::pair<int const, std::pair<ppapi::Resource*, int> > >, std::equal_to<int>, std::allocator<std::pair<ppapi::Resource*, int> > >::find_or_insert(std::pair<int const, std::pair<ppapi::Resource*, int> > const&)
-                (nil)
-
-0.07^1989976^HTMLParserThrea^chrome               ^[.] content::PaintAggregator::InvalidateRect(gfx::Rect const&)
-            |
-            --- content::PaintAggregator::InvalidateRect(gfx::Rect const&)
-
-0.07^1983969^HTMLParserThrea^chrome               ^[.] tracked_objects::ThreadData::TallyADeath(tracked_objects::Births const&, int, int)
-            |
-            --- tracked_objects::ThreadData::TallyADeath(tracked_objects::Births const&, int, int)
-
-0.07^1983969^HTMLParserThrea^chrome               ^[.] WebCore::HTMLDocumentParser::pumpTokenizer(WebCore::HTMLDocumentParser::SynchronousMode)
-            |
-            --- WebCore::HTMLDocumentParser::pumpTokenizer(WebCore::HTMLDocumentParser::SynchronousMode)
-
-0.07^1964943^HTMLParserThrea^chrome               ^[.] v8::internal::NormalizedMapCache::Get(v8::internal::JSObject*, v8::internal::PropertyNormalizationMode)
-            |
-            --- v8::internal::NormalizedMapCache::Get(v8::internal::JSObject*, v8::internal::PropertyNormalizationMode)
-
-0.07^1960139^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::visualOverflowRect() const
-            |
-            --- WebCore::RenderBox::visualOverflowRect() const
-
-0.06^1953892^HTMLParserThrea^chrome               ^[.] base::MessagePumpDefault::ScheduleWork()
-            |
-            --- base::MessagePumpDefault::ScheduleWork()
-
-0.06^1922033^HTMLParserThrea^chrome               ^[.] v8::preparser::PreParser::ParseIdentifier(bool*)
-            |
-            --- v8::preparser::PreParser::ParseIdentifier(bool*)
-                0x3b2abe08368000
-
-0.06^1902957^HTMLParserThrea^chrome               ^[.] base::MessageLoop::ScheduleWork(bool)
-            |
-            --- base::MessageLoop::ScheduleWork(bool)
-
-0.06^1857157^HTMLParserThrea^chrome               ^[.] v8::internal::FullCodeGenerator::DoTest(v8::internal::Expression*, v8::internal::Label*, v8::internal::Label*, v8::internal::Label*)
-            |
-            --- v8::internal::FullCodeGenerator::DoTest(v8::internal::Expression*, v8::internal::Label*, v8::internal::Label*, v8::internal::Label*)
-                0x7fff30e91bc0
-
-0.06^1758928^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::ancestorStackingContainer() const
-            |
-            --- WebCore::RenderLayer::ancestorStackingContainer() const
-
-0.06^1708834^HTMLParserThrea^libcairo.so.2.11000.2^[.] _cairo_matrix_is_identity
-            |
-            --- _cairo_matrix_is_identity
-
-0.06^1707254^HTMLParserThrea^chrome               ^[.] WebCore::RenderLineBoxList::anyLineIntersectsRect(WebCore::RenderBoxModelObject*, WebCore::LayoutRect const&, WebCore::LayoutPoint const&, WebCore::LayoutUnit) const
-            |
-            --- WebCore::RenderLineBoxList::anyLineIntersectsRect(WebCore::RenderBoxModelObject*, WebCore::LayoutRect const&, WebCore::LayoutPoint const&, WebCore::LayoutUnit) const
-
-0.06^1695178^HTMLParserThrea^chrome               ^[.] base::internal::CallbackBase::CallbackBase(base::internal::BindStateBase*)
-            |
-            --- base::internal::CallbackBase::CallbackBase(base::internal::BindStateBase*)
-
-0.06^1682330^HTMLParserThrea^chrome               ^[.] WebCore::RenderBox::clippedOverflowRectForRepaint(WebCore::RenderLayerModelObject const*) const
-            |
-            --- WebCore::RenderBox::clippedOverflowRectForRepaint(WebCore::RenderLayerModelObject const*) const
-
-0.06^1665533^HTMLParserThrea^chrome               ^[.] v8::internal::Zone::DeleteAll()
-            |
-            --- v8::internal::Zone::DeleteAll()
-
-0.05^1641632^HTMLParserThrea^chrome               ^[.] WebCore::Color::blend(WebCore::Color const&) const
-            |
-            --- WebCore::Color::blend(WebCore::Color const&) const
-
-0.05^1611521^HTMLParserThrea^chrome               ^[.] WebKit::currentTimeFunction()
-            |
-            --- WebKit::currentTimeFunction()
-
-0.05^1539536^HTMLParserThrea^chrome               ^[.] WebCore::RenderLayer::collectFragments(WTF::Vector<WebCore::LayerFragment, 1ul>&, WebCore::RenderLayer const*, WebCore::RenderRegion*, WebCore::LayoutRect const&, WebCore::ClipRectsType, WebCore::OverlayScrollbarSizeRelevancy, WebCore::ShouldRespectOverflowClip, WebCore::LayoutPoint const*, WebCore::LayoutRect const*)
-            |
-            --- WebCore::RenderLayer::collectFragments(WTF::Vector<WebCore::LayerFragment, 1ul>&, WebCore::RenderLayer const*, WebCore::RenderRegion*, WebCore::LayoutRect const&, WebCore::ClipRectsType, WebCore::OverlayScrollbarSizeRelevancy, WebCore::ShouldRespectOverflowClip, WebCore::LayoutPoint const*, WebCore::LayoutRect const*)
-
-0.05^1523423^HTMLParserThrea^chrome               ^[.] v8::internal::StubCache::ComputeLoadNormal(v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::JSObject>)
-            |
-            --- v8::internal::StubCache::ComputeLoadNormal(v8::internal::Handle<v8::internal::Name>, v8::internal::Handle<v8::internal::JSObject>)
-                (nil)
-
-0.05^1521966^HTMLParserThrea^chrome               ^[.] void url_canon::(anonymous namespace)::DoHost<char, unsigned char>(char const*, url_parse::Component const&, url_canon::CanonOutputT<char>*, url_canon::CanonHostInfo*)
-            |
-            --- void url_canon::(anonymous namespace)::DoHost<char, unsigned char>(char const*, url_parse::Component const&, url_canon::CanonOutputT<char>*, url_canon::CanonHostInfo*)
-                0xffffffff00000000
-
-0.05^1443413^HTMLParserThrea^chrome               ^[.] WTF::HashTableAddResult<WTF::HashTableIterator<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*, WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*, WTF::IdentityExtractor, WTF::ListHashSetNodeHashFunctions<WTF::PtrHash<WebCore::CachedResource*> >, WTF::HashTraits<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*> > > WTF::HashTable<WTF::ListHashSetNode<WebCore::Cac
-            |
-            --- WTF::HashTableAddResult<WTF::HashTableIterator<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*, WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*, WTF::IdentityExtractor, WTF::ListHashSetNodeHashFunctions<WTF::PtrHash<WebCore::CachedResource*> >, WTF::HashTraits<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*> > > WTF::HashTable<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*, WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*, WTF::IdentityExtractor, WTF::ListHashSetNodeHashFunctions<WTF::PtrHash<WebCore::CachedResource*> >, WTF::HashTraits<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*>, WTF::HashTraits<WTF::ListHashSetNode<WebCore::CachedResource*, 256ul>*> >::add<WTF::ListHashSetTranslator<WTF::PtrHash<WebCore::CachedResource*> >, WebCore::CachedResource*, WTF::ListHashSetNodeAllocator<WebCore::CachedResource*, 256ul>*>(WebCore::CachedResource* const&, WTF::ListHashSetNodeAllocator<WebCore::CachedResource*, 256ul>* const&)
-                (nil)
-
-0.05^1380694^HTMLParserThrea^chrome               ^[.] v8::internal::HBasicBlock::Finish(v8::internal::HControlInstruction*)
-            |
-            --- v8::internal::HBasicBlock::Finish(v8::internal::HControlInstruction*)
-
-0.04^1244009^HTMLParserThrea^chrome               ^[.] WebCore::Node::isWebVTTElement() const
-            |
-            --- WebCore::Node::isWebVTTElement() const
-                0x7fff30e91700
-
-
-
-#
-# (For a higher level overview, try: perf report --sort comm,dso)
-#
diff --git a/catapult/telemetry/telemetry/internal/testing/powermetrics_output.output b/catapult/telemetry/telemetry/internal/testing/powermetrics_output.output
deleted file mode 100644
index d952096..0000000
--- a/catapult/telemetry/telemetry/internal/testing/powermetrics_output.output
+++ /dev/null
@@ -1,3375 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-	<key>GPU</key>
-	<array>
-		<dict>
-			<key>freq_hz</key>
-			<real>1</real>
-			<key>c_state_ns</key>
-			<integer>4295987562</integer>
-			<key>c_state_ratio</key>
-			<real>1</real>
-			<key>GPU number</key>
-			<integer>0</integer>
-			<key>misc counters</key>
-			<array>
-				<dict>
-					<key>GPU Busy</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>FB Test Case</key>
-					<real>0</real>
-				</dict>
-			</array>
-			<key>c_states</key>
-			<array>
-				<dict>
-					<key>used_ns</key>
-					<integer>8737642</integer>
-					<key>used_ratio</key>
-					<real>0.00203391</real>
-				</dict>
-				<dict>
-					<key>used_ns</key>
-					<integer>4287249920</integer>
-					<key>used_ratio</key>
-					<real>0.997969</real>
-				</dict>
-			</array>
-			<key>p_states</key>
-			<array>
-				<dict>
-					<key>frequency</key>
-					<string>1300000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>1250000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>1200000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>1150000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>1100000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>1050000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>1000000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>950000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>900000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>850000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>800000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>750000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>700000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>650000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>600000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>550000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>500000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>450000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>400000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>350000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>300000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>250000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-				<dict>
-					<key>frequency</key>
-					<string>200000000</string>
-					<key>used_ns</key>
-					<integer>0</integer>
-					<key>used_ratio</key>
-					<real>0</real>
-				</dict>
-			</array>
-			<key>freq_ratio</key>
-			<real>0</real>
-			<key>name</key>
-			<string>IntelIG</string>
-		</dict>
-	</array>
-	<key>timestamp</key>
-	<date>2014-06-13T17:07:20Z</date>
-	<key>tasks</key>
-	<array>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>592</integer>
-			<key>cputime_ms_per_s</key>
-			<real>23.4812</real>
-			<key>cputime_userland_ratio</key>
-			<real>0</real>
-			<key>intr_wakeups</key>
-			<integer>687</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>137.889</real>
-			<key>started_ns</key>
-			<integer>0</integer>
-			<key>cputime_ns</key>
-			<integer>100812002</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>3.72673</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>16</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>160.016</real>
-			<key>pid</key>
-			<integer>0</integer>
-			<key>name</key>
-			<string>kernel_task</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>141</integer>
-			<key>cputime_ms_per_s</key>
-			<real>24.2995</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.6389860000000001</real>
-			<key>intr_wakeups</key>
-			<integer>145</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>32.8418</real>
-			<key>started_ns</key>
-			<integer>1610501000</integer>
-			<key>cputime_ns</key>
-			<integer>104325487</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>17.469</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>75</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>12.1119</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>52</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>33.7735</real>
-			<key>pid</key>
-			<integer>113</integer>
-			<key>name</key>
-			<string>WindowServer</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>40</integer>
-			<key>cputime_ms_per_s</key>
-			<real>21.3695</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.970651</real>
-			<key>intr_wakeups</key>
-			<integer>44</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>9.31682</real>
-			<key>started_ns</key>
-			<integer>7367983585000</integer>
-			<key>cputime_ns</key>
-			<integer>91746051</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>10.2485</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>44</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>10.2485</real>
-			<key>pid</key>
-			<integer>12745</integer>
-			<key>name</key>
-			<string>Python</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>20</integer>
-			<key>cputime_ms_per_s</key>
-			<real>18.167</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.914095</real>
-			<key>intr_wakeups</key>
-			<integer>22</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>4.65841</real>
-			<key>started_ns</key>
-			<integer>43264491000</integer>
-			<key>cputime_ns</key>
-			<integer>77996425</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0.23292</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>1</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>5.12425</real>
-			<key>pid</key>
-			<integer>1318</integer>
-			<key>name</key>
-			<string>Google Chrome He</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>117</integer>
-			<key>cputime_ms_per_s</key>
-			<real>10.6337</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.8333199999999999</real>
-			<key>intr_wakeups</key>
-			<integer>125</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>27.2517</real>
-			<key>started_ns</key>
-			<integer>10444809000</integer>
-			<key>cputime_ns</key>
-			<integer>45653817</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>29.1151</real>
-			<key>pid</key>
-			<integer>583</integer>
-			<key>name</key>
-			<string>Terminal</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>65</integer>
-			<key>cputime_ms_per_s</key>
-			<real>11.7345</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.88018</real>
-			<key>intr_wakeups</key>
-			<integer>75</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>15.1398</real>
-			<key>started_ns</key>
-			<integer>7911274078000</integer>
-			<key>cputime_ns</key>
-			<integer>50379825</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>17.469</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>75</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>17.469</real>
-			<key>pid</key>
-			<integer>13560</integer>
-			<key>name</key>
-			<string>Python</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>47</integer>
-			<key>cputime_ms_per_s</key>
-			<real>8.64067</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.584309</real>
-			<key>intr_wakeups</key>
-			<integer>50</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>10.9473</real>
-			<key>started_ns</key>
-			<integer>10437471000</integer>
-			<key>cputime_ns</key>
-			<integer>37097106</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0.931682</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>4</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>11.646</real>
-			<key>pid</key>
-			<integer>582</integer>
-			<key>name</key>
-			<string>Google Chrome</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>14</integer>
-			<key>cputime_ms_per_s</key>
-			<real>7.9918</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.919737</real>
-			<key>intr_wakeups</key>
-			<integer>17</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>3.26089</real>
-			<key>started_ns</key>
-			<integer>10465929000</integer>
-			<key>cputime_ns</key>
-			<integer>34311297</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>3.95965</real>
-			<key>pid</key>
-			<integer>587</integer>
-			<key>name</key>
-			<string>SystemUIServer</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>6</integer>
-			<key>cputime_ms_per_s</key>
-			<real>6.42884</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.582192</real>
-			<key>intr_wakeups</key>
-			<integer>7</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>1.39752</real>
-			<key>started_ns</key>
-			<integer>639336000</integer>
-			<key>cputime_ns</key>
-			<integer>27601023</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>1.63044</real>
-			<key>pid</key>
-			<integer>25</integer>
-			<key>name</key>
-			<string>syslogd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>45</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.681478</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.365057</real>
-			<key>intr_wakeups</key>
-			<integer>49</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>10.4814</real>
-			<key>started_ns</key>
-			<integer>49189572000</integer>
-			<key>cputime_ns</key>
-			<integer>2925797</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>11.4131</real>
-			<key>pid</key>
-			<integer>1551</integer>
-			<key>name</key>
-			<string>GoogleTalkPlugin</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>12</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.399903</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.489519</real>
-			<key>intr_wakeups</key>
-			<integer>15</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>2.79504</real>
-			<key>started_ns</key>
-			<integer>1881153000</integer>
-			<key>cputime_ns</key>
-			<integer>1716908</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>3.49381</real>
-			<key>pid</key>
-			<integer>145</integer>
-			<key>name</key>
-			<string>gagent</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>5</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.475033</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.725976</real>
-			<key>intr_wakeups</key>
-			<integer>6</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>1.1646</real>
-			<key>started_ns</key>
-			<integer>8483361342000</integer>
-			<key>cputime_ns</key>
-			<integer>2039463</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>1.39752</real>
-			<key>pid</key>
-			<integer>14091</integer>
-			<key>name</key>
-			<string>Google Chrome He</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.679799</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.256151</real>
-			<key>intr_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0</real>
-			<key>started_ns</key>
-			<integer>8917493171000</integer>
-			<key>cputime_ns</key>
-			<integer>2918588</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0</real>
-			<key>pid</key>
-			<integer>14209</integer>
-			<key>name</key>
-			<string>powermetrics</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.211558</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.6101799999999999</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>started_ns</key>
-			<integer>1493715000</integer>
-			<key>cputime_ns</key>
-			<integer>908286</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>95</integer>
-			<key>name</key>
-			<string>Python</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.181734</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.677046</real>
-			<key>intr_wakeups</key>
-			<integer>3</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>started_ns</key>
-			<integer>12546437000</integer>
-			<key>cputime_ns</key>
-			<integer>780239</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.698761</real>
-			<key>pid</key>
-			<integer>695</integer>
-			<key>name</key>
-			<string>Google Chrome He</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>3</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.117981</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.252391</real>
-			<key>intr_wakeups</key>
-			<integer>4</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.698761</real>
-			<key>started_ns</key>
-			<integer>1676947000</integer>
-			<key>cputime_ns</key>
-			<integer>506528</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.931682</real>
-			<key>pid</key>
-			<integer>132</integer>
-			<key>name</key>
-			<string>pacemaker</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.125953</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.55472</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>started_ns</key>
-			<integer>11624896000</integer>
-			<key>cputime_ns</key>
-			<integer>540756</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>654</integer>
-			<key>name</key>
-			<string>Google Chrome He</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.108103</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.648833</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>started_ns</key>
-			<integer>6838183543000</integer>
-			<key>cputime_ns</key>
-			<integer>464121</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>12260</integer>
-			<key>name</key>
-			<string>Google Chrome He</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.120981</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.682463</real>
-			<key>intr_wakeups</key>
-			<integer>3</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>started_ns</key>
-			<integer>1491205000</integer>
-			<key>cputime_ns</key>
-			<integer>519408</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.698761</real>
-			<key>pid</key>
-			<integer>79</integer>
-			<key>name</key>
-			<string>fseventsd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.0486729</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.254202</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>started_ns</key>
-			<integer>1622879000</integer>
-			<key>cputime_ns</key>
-			<integer>208968</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>114</integer>
-			<key>name</key>
-			<string>ocspd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.08862200000000001</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.635134</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>started_ns</key>
-			<integer>12714103000</integer>
-			<key>cputime_ns</key>
-			<integer>380482</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>698</integer>
-			<key>name</key>
-			<string>Google Chrome He</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.0410855</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.189299</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>started_ns</key>
-			<integer>1492092000</integer>
-			<key>cputime_ns</key>
-			<integer>176393</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>85</integer>
-			<key>name</key>
-			<string>launchservicesd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.110853</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.279103</real>
-			<key>intr_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0</real>
-			<key>started_ns</key>
-			<integer>624120000</integer>
-			<key>cputime_ns</key>
-			<integer>475925</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0</real>
-			<key>pid</key>
-			<integer>20</integer>
-			<key>name</key>
-			<string>notifyd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.0619692</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.401646</real>
-			<key>intr_wakeups</key>
-			<integer>2</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>started_ns</key>
-			<integer>1489680000</integer>
-			<key>cputime_ns</key>
-			<integer>266053</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.465841</real>
-			<key>pid</key>
-			<integer>69</integer>
-			<key>name</key>
-			<string>mds</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.0550766</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.362267</real>
-			<key>intr_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>started_ns</key>
-			<integer>2992466000</integer>
-			<key>cputime_ns</key>
-			<integer>236461</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>pid</key>
-			<integer>202</integer>
-			<key>name</key>
-			<string>CVMServer</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.0873813</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.842692</real>
-			<key>intr_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0</real>
-			<key>started_ns</key>
-			<integer>7393764015000</integer>
-			<key>cputime_ns</key>
-			<integer>375155</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0</real>
-			<key>pid</key>
-			<integer>13253</integer>
-			<key>name</key>
-			<string>syslog</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.010856</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.187307</real>
-			<key>intr_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>started_ns</key>
-			<integer>10349417000</integer>
-			<key>cputime_ns</key>
-			<integer>46608</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>pid</key>
-			<integer>573</integer>
-			<key>name</key>
-			<string>cfprefsd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.00967575</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.216677</real>
-			<key>intr_wakeups</key>
-			<integer>1</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>started_ns</key>
-			<integer>865104000</integer>
-			<key>cputime_ns</key>
-			<integer>41541</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0.23292</real>
-			<key>pid</key>
-			<integer>30</integer>
-			<key>name</key>
-			<string>cfprefsd</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.039699</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.240431</real>
-			<key>intr_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0</real>
-			<key>started_ns</key>
-			<integer>603081000</integer>
-			<key>cputime_ns</key>
-			<integer>170440</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0</real>
-			<key>pid</key>
-			<integer>17</integer>
-			<key>name</key>
-			<string>UserEventAgent</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-		<dict>
-			<key>idle_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s</key>
-			<real>0.0260172</real>
-			<key>cputime_userland_ratio</key>
-			<real>0.260627</real>
-			<key>intr_wakeups</key>
-			<integer>0</integer>
-			<key>cputime_ms_per_s_reliable</key>
-			<true/>
-			<key>idle_wakeups_per_s</key>
-			<real>0</real>
-			<key>started_ns</key>
-			<integer>10467715000</integer>
-			<key>cputime_ns</key>
-			<integer>111700</integer>
-			<key>timer_wakeups</key>
-			<array>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>2000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-				<dict>
-					<key>wakeups_per_s</key>
-					<real>0</real>
-					<key>interval_ns</key>
-					<integer>5000000</integer>
-					<key>wakeups</key>
-					<integer>0</integer>
-				</dict>
-			</array>
-			<key>intr_wakeups_per_s</key>
-			<real>0</real>
-			<key>pid</key>
-			<integer>588</integer>
-			<key>name</key>
-			<string>Finder</string>
-			<key>started_ns_reliable</key>
-			<false/>
-		</dict>
-	</array>
-	<key>hw_model</key>
-	<string>MacBookPro11,3</string>
-	<key>interrupts</key>
-	<array>
-		<dict>
-			<key>cpu</key>
-			<integer>0</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>116</integer>
-					<key>events</key>
-					<integer>167</integer>
-					<key>events_per_s</key>
-					<real>38.8753</real>
-					<key>name</key>
-					<string>XHC1</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>119</integer>
-					<key>events</key>
-					<integer>463</integer>
-					<key>events_per_s</key>
-					<real>107.78</real>
-					<key>name</key>
-					<string>GFX0</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>122</integer>
-					<key>events</key>
-					<integer>65</integer>
-					<key>events_per_s</key>
-					<real>15.1311</real>
-					<key>name</key>
-					<string>ARPT</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>221</integer>
-					<key>events</key>
-					<integer>635</integer>
-					<key>events_per_s</key>
-					<real>147.819</real>
-					<key>name</key>
-					<string>TMR</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>12</integer>
-					<key>events_per_s</key>
-					<real>2.79343</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>1</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>221</integer>
-					<key>events</key>
-					<integer>3</integer>
-					<key>events_per_s</key>
-					<real>0.698358</real>
-					<key>name</key>
-					<string>TMR</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>3</integer>
-					<key>events_per_s</key>
-					<real>0.698358</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>2</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>221</integer>
-					<key>events</key>
-					<integer>92</integer>
-					<key>events_per_s</key>
-					<real>21.4163</real>
-					<key>name</key>
-					<string>TMR</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>16</integer>
-					<key>events_per_s</key>
-					<real>3.72458</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>3</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>3</integer>
-					<key>events_per_s</key>
-					<real>0.698358</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>4</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>221</integer>
-					<key>events</key>
-					<integer>131</integer>
-					<key>events_per_s</key>
-					<real>30.495</real>
-					<key>name</key>
-					<string>TMR</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>20</integer>
-					<key>events_per_s</key>
-					<real>4.65572</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>5</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>221</integer>
-					<key>events</key>
-					<integer>2</integer>
-					<key>events_per_s</key>
-					<real>0.465572</real>
-					<key>name</key>
-					<string>TMR</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>3</integer>
-					<key>events_per_s</key>
-					<real>0.698358</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>6</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>221</integer>
-					<key>events</key>
-					<integer>111</integer>
-					<key>events_per_s</key>
-					<real>25.8393</real>
-					<key>name</key>
-					<string>TMR</string>
-				</dict>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>15</integer>
-					<key>events_per_s</key>
-					<real>3.49179</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-		<dict>
-			<key>cpu</key>
-			<integer>7</integer>
-			<key>vectors</key>
-			<array>
-				<dict>
-					<key>vector</key>
-					<integer>222</integer>
-					<key>events</key>
-					<integer>2</integer>
-					<key>events_per_s</key>
-					<real>0.465572</real>
-					<key>name</key>
-					<string>IPI</string>
-				</dict>
-			</array>
-		</dict>
-	</array>
-	<key>backlight</key>
-	<dict>
-		<key>min</key>
-		<integer>0</integer>
-		<key>value</key>
-		<integer>687</integer>
-		<key>max</key>
-		<integer>1024</integer>
-	</dict>
-	<key>kern_osversion</key>
-	<string>13D65</string>
-	<key>all_tasks</key>
-	<dict>
-		<key>idle_wakeups</key>
-		<integer>1125</integer>
-		<key>cputime_ms_per_s</key>
-		<real>136.35</real>
-		<key>cputime_userland_ratio</key>
-		<real>0.65911</real>
-		<key>intr_wakeups</key>
-		<integer>1269</integer>
-		<key>cputime_ms_per_s_reliable</key>
-		<true/>
-		<key>idle_wakeups_per_s</key>
-		<real>261.884</real>
-		<key>started_ns</key>
-		<integer>0</integer>
-		<key>cputime_ns</key>
-		<integer>585732853</integer>
-		<key>timer_wakeups</key>
-		<array>
-			<dict>
-				<key>wakeups_per_s</key>
-				<real>39.5736</real>
-				<key>interval_ns</key>
-				<integer>2000000</integer>
-				<key>wakeups</key>
-				<integer>170</integer>
-			</dict>
-			<dict>
-				<key>wakeups_per_s</key>
-				<real>22.5803</real>
-				<key>interval_ns</key>
-				<integer>5000000</integer>
-				<key>wakeups</key>
-				<integer>97</integer>
-			</dict>
-		</array>
-		<key>intr_wakeups_per_s</key>
-		<real>295.406</real>
-		<key>pid</key>
-		<integer>-2</integer>
-		<key>name</key>
-		<string>ALL_TASKS</string>
-		<key>started_ns_reliable</key>
-		<false/>
-	</dict>
-	<key>disk</key>
-	<dict>
-		<key>rbytes_diff</key>
-		<integer>0</integer>
-		<key>rops_per_s</key>
-		<real>0</real>
-		<key>rops_diff</key>
-		<integer>0</integer>
-		<key>wops_diff</key>
-		<integer>0</integer>
-		<key>wops_per_s</key>
-		<real>0</real>
-		<key>wbytes_per_s</key>
-		<real>0</real>
-		<key>rbytes_per_s</key>
-		<real>0</real>
-		<key>wbytes_diff</key>
-		<integer>0</integer>
-	</dict>
-	<key>processor</key>
-	<dict>
-		<key>freq_hz</key>
-		<real>1668120000</real>
-		<key>package_joules</key>
-		<real>13.0469</real>
-		<key>packages</key>
-		<array>
-			<dict>
-				<key>c_state_ns</key>
-				<integer>3723350796</integer>
-				<key>c_state_ratio</key>
-				<real>0.866745</real>
-				<key>package</key>
-				<integer>0</integer>
-				<key>c_states</key>
-				<array>
-					<dict>
-						<key>used_ns</key>
-						<integer>191313723</integer>
-						<key>used_ratio</key>
-						<real>0.0445352</real>
-						<key>name</key>
-						<string>C2</string>
-					</dict>
-					<dict>
-						<key>used_ns</key>
-						<integer>743617321</integer>
-						<key>used_ratio</key>
-						<real>0.173104</real>
-						<key>name</key>
-						<string>C3</string>
-					</dict>
-					<dict>
-						<key>used_ns</key>
-						<integer>2788419751</integer>
-						<key>used_ratio</key>
-						<real>0.649106</real>
-						<key>name</key>
-						<string>C6</string>
-					</dict>
-					<dict>
-						<key>used_ns</key>
-						<integer>0</integer>
-						<key>used_ratio</key>
-						<real>0</real>
-						<key>name</key>
-						<string>C7</string>
-					</dict>
-				</array>
-				<key>cores</key>
-				<array>
-					<dict>
-						<key>c_state_ns</key>
-						<integer>3942072317</integer>
-						<key>c_state_ratio</key>
-						<real>0.91766</real>
-						<key>core</key>
-						<integer>0</integer>
-						<key>c_states</key>
-						<array>
-							<dict>
-								<key>used_ns</key>
-								<integer>9035527</integer>
-								<key>used_ratio</key>
-								<real>0.00210335</real>
-								<key>name</key>
-								<string>C3</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>0</integer>
-								<key>used_ratio</key>
-								<real>0</real>
-								<key>name</key>
-								<string>C6</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>3933036790</integer>
-								<key>used_ratio</key>
-								<real>0.915557</real>
-								<key>name</key>
-								<string>C7</string>
-							</dict>
-						</array>
-						<key>cpus</key>
-						<array>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>139</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>32.3573</real>
-										<key>idle_count</key>
-										<integer>25</integer>
-										<key>idle_per_s</key>
-										<real>32.3573</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>16</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>3.72458</real>
-										<key>idle_count</key>
-										<integer>47</integer>
-										<key>idle_per_s</key>
-										<real>3.72458</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>59</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>13.7344</real>
-										<key>idle_count</key>
-										<integer>75</integer>
-										<key>idle_per_s</key>
-										<real>13.7344</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>263</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>61.2228</real>
-										<key>idle_count</key>
-										<integer>171</integer>
-										<key>idle_per_s</key>
-										<real>61.2228</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>356</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>82.8719</real>
-										<key>idle_count</key>
-										<integer>63</integer>
-										<key>idle_per_s</key>
-										<real>82.8719</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>266</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>61.9211</real>
-										<key>idle_count</key>
-										<integer>89</integer>
-										<key>idle_per_s</key>
-										<real>61.9211</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>78</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>18.1573</real>
-										<key>idle_count</key>
-										<integer>154</integer>
-										<key>idle_per_s</key>
-										<real>18.1573</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>10</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>2.32786</real>
-										<key>idle_count</key>
-										<integer>130</integer>
-										<key>idle_per_s</key>
-										<real>2.32786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>4</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>0.931145</real>
-										<key>idle_count</key>
-										<integer>140</integer>
-										<key>idle_per_s</key>
-										<real>0.931145</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>7</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>1.6295</real>
-										<key>idle_count</key>
-										<integer>134</integer>
-										<key>idle_per_s</key>
-										<real>1.6295</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>119</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>50</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>0</integer>
-								<key>freq_hz</key>
-								<real>1478510000</real>
-								<key>freq_ratio</key>
-								<real>0.569975</real>
-							</dict>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>11</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>2.56065</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>2.56065</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>5</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>1.16393</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>1.16393</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>4</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>0.931145</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0.931145</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>4</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>0.931145</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.931145</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>1</integer>
-								<key>freq_hz</key>
-								<real>1604120000</real>
-								<key>freq_ratio</key>
-								<real>0.6183959999999999</real>
-							</dict>
-						</array>
-					</dict>
-					<dict>
-						<key>c_state_ns</key>
-						<integer>4165689565</integer>
-						<key>c_state_ratio</key>
-						<real>0.969715</real>
-						<key>core</key>
-						<integer>1</integer>
-						<key>c_states</key>
-						<array>
-							<dict>
-								<key>used_ns</key>
-								<integer>3710669</integer>
-								<key>used_ratio</key>
-								<real>0.000863793</real>
-								<key>name</key>
-								<string>C3</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>0</integer>
-								<key>used_ratio</key>
-								<real>0</real>
-								<key>name</key>
-								<string>C6</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>4161978895</integer>
-								<key>used_ratio</key>
-								<real>0.968851</real>
-								<key>name</key>
-								<string>C7</string>
-							</dict>
-						</array>
-						<key>cpus</key>
-						<array>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>325</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>75.6555</real>
-										<key>idle_count</key>
-										<integer>28</integer>
-										<key>idle_per_s</key>
-										<real>75.6555</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>19</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>4.42294</real>
-										<key>idle_count</key>
-										<integer>61</integer>
-										<key>idle_per_s</key>
-										<real>4.42294</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>58</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>13.5016</real>
-										<key>idle_count</key>
-										<integer>104</integer>
-										<key>idle_per_s</key>
-										<real>13.5016</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>84</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>19.554</real>
-										<key>idle_count</key>
-										<integer>87</integer>
-										<key>idle_per_s</key>
-										<real>19.554</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>29</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>6.7508</real>
-										<key>idle_count</key>
-										<integer>36</integer>
-										<key>idle_per_s</key>
-										<real>6.7508</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>18</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>4.19015</real>
-										<key>idle_count</key>
-										<integer>24</integer>
-										<key>idle_per_s</key>
-										<real>4.19015</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>39</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>9.078659999999999</real>
-										<key>idle_count</key>
-										<integer>19</integer>
-										<key>idle_per_s</key>
-										<real>9.078659999999999</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>20</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>9</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>2.09508</real>
-										<key>idle_count</key>
-										<integer>31</integer>
-										<key>idle_per_s</key>
-										<real>2.09508</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>37</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>44</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>62</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>2</integer>
-								<key>freq_hz</key>
-								<real>2073780000</real>
-								<key>freq_ratio</key>
-								<real>0.799453</real>
-							</dict>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>9</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>2.09508</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>2.09508</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>3</integer>
-								<key>freq_hz</key>
-								<real>1989580000</real>
-								<key>freq_ratio</key>
-								<real>0.766994</real>
-							</dict>
-						</array>
-					</dict>
-					<dict>
-						<key>c_state_ns</key>
-						<integer>4141777109</integer>
-						<key>c_state_ratio</key>
-						<real>0.964148</real>
-						<key>core</key>
-						<integer>2</integer>
-						<key>c_states</key>
-						<array>
-							<dict>
-								<key>used_ns</key>
-								<integer>884933</integer>
-								<key>used_ratio</key>
-								<real>0.000206</real>
-								<key>name</key>
-								<string>C3</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>0</integer>
-								<key>used_ratio</key>
-								<real>0</real>
-								<key>name</key>
-								<string>C6</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>4140892176</integer>
-								<key>used_ratio</key>
-								<real>0.963942</real>
-								<key>name</key>
-								<string>C7</string>
-							</dict>
-						</array>
-						<key>cpus</key>
-						<array>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>396</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>92.1833</real>
-										<key>idle_count</key>
-										<integer>26</integer>
-										<key>idle_per_s</key>
-										<real>92.1833</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>28</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>6.51801</real>
-										<key>idle_count</key>
-										<integer>58</integer>
-										<key>idle_per_s</key>
-										<real>6.51801</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>69</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>16.0622</real>
-										<key>idle_count</key>
-										<integer>124</integer>
-										<key>idle_per_s</key>
-										<real>16.0622</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>97</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>22.5803</real>
-										<key>idle_count</key>
-										<integer>115</integer>
-										<key>idle_per_s</key>
-										<real>22.5803</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>37</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>8.61309</real>
-										<key>idle_count</key>
-										<integer>36</integer>
-										<key>idle_per_s</key>
-										<real>8.61309</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>34</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>7.91473</real>
-										<key>idle_count</key>
-										<integer>34</integer>
-										<key>idle_per_s</key>
-										<real>7.91473</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>32</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>7.44916</real>
-										<key>idle_count</key>
-										<integer>18</integer>
-										<key>idle_per_s</key>
-										<real>7.44916</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>7</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>1.6295</real>
-										<key>idle_count</key>
-										<integer>40</integer>
-										<key>idle_per_s</key>
-										<real>1.6295</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>17</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>3.95736</real>
-										<key>idle_count</key>
-										<integer>40</integer>
-										<key>idle_per_s</key>
-										<real>3.95736</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>64</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>72</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>75</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>4</integer>
-								<key>freq_hz</key>
-								<real>1768190000</real>
-								<key>freq_ratio</key>
-								<real>0.6816449999999999</real>
-							</dict>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>16</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>3.72458</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>3.72458</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>5</integer>
-								<key>freq_hz</key>
-								<real>2250530000</real>
-								<key>freq_ratio</key>
-								<real>0.867594</real>
-							</dict>
-						</array>
-					</dict>
-					<dict>
-						<key>c_state_ns</key>
-						<integer>4177380735</integer>
-						<key>c_state_ratio</key>
-						<real>0.972436</real>
-						<key>core</key>
-						<integer>3</integer>
-						<key>c_states</key>
-						<array>
-							<dict>
-								<key>used_ns</key>
-								<integer>9674041</integer>
-								<key>used_ratio</key>
-								<real>0.00225198</real>
-								<key>name</key>
-								<string>C3</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>0</integer>
-								<key>used_ratio</key>
-								<real>0</real>
-								<key>name</key>
-								<string>C6</string>
-							</dict>
-							<dict>
-								<key>used_ns</key>
-								<integer>4167706693</integer>
-								<key>used_ratio</key>
-								<real>0.970184</real>
-								<key>name</key>
-								<string>C7</string>
-							</dict>
-						</array>
-						<key>cpus</key>
-						<array>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>378</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>87.9932</real>
-										<key>idle_count</key>
-										<integer>29</integer>
-										<key>idle_per_s</key>
-										<real>87.9932</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>28</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>6.51801</real>
-										<key>idle_count</key>
-										<integer>51</integer>
-										<key>idle_per_s</key>
-										<real>6.51801</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>62</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>14.4327</real>
-										<key>idle_count</key>
-										<integer>119</integer>
-										<key>idle_per_s</key>
-										<real>14.4327</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>84</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>19.554</real>
-										<key>idle_count</key>
-										<integer>103</integer>
-										<key>idle_per_s</key>
-										<real>19.554</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>32</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>7.44916</real>
-										<key>idle_count</key>
-										<integer>41</integer>
-										<key>idle_per_s</key>
-										<real>7.44916</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>27</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>6.28523</real>
-										<key>idle_count</key>
-										<integer>23</integer>
-										<key>idle_per_s</key>
-										<real>6.28523</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>29</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>6.7508</real>
-										<key>idle_count</key>
-										<integer>17</integer>
-										<key>idle_per_s</key>
-										<real>6.7508</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>10</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>2.32786</real>
-										<key>idle_count</key>
-										<integer>30</integer>
-										<key>idle_per_s</key>
-										<real>2.32786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>12</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>2.79343</real>
-										<key>idle_count</key>
-										<integer>32</integer>
-										<key>idle_per_s</key>
-										<real>2.79343</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>73</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>51</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>72</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>6</integer>
-								<key>freq_hz</key>
-								<real>1635700000</real>
-								<key>freq_ratio</key>
-								<real>0.6305730000000001</real>
-							</dict>
-							<dict>
-								<key>duty_cycles</key>
-								<array>
-									<dict>
-										<key>active_count</key>
-										<integer>15</integer>
-										<key>interval_ns</key>
-										<integer>16000</integer>
-										<key>active_per_s</key>
-										<real>3.49179</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>3.49179</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>3</integer>
-										<key>interval_ns</key>
-										<integer>32000</integer>
-										<key>active_per_s</key>
-										<real>0.698358</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.698358</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>2</integer>
-										<key>interval_ns</key>
-										<integer>64000</integer>
-										<key>active_per_s</key>
-										<real>0.465572</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0.465572</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>128000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>1</integer>
-										<key>interval_ns</key>
-										<integer>256000</integer>
-										<key>active_per_s</key>
-										<real>0.232786</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0.232786</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>512000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>1024000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>2048000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>4096000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>2</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>8192000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>1</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>16384000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-									<dict>
-										<key>active_count</key>
-										<integer>0</integer>
-										<key>interval_ns</key>
-										<integer>32768000</integer>
-										<key>active_per_s</key>
-										<real>0</real>
-										<key>idle_count</key>
-										<integer>0</integer>
-										<key>idle_per_s</key>
-										<real>0</real>
-									</dict>
-								</array>
-								<key>cpu</key>
-								<integer>7</integer>
-								<key>freq_hz</key>
-								<real>1818650000</real>
-								<key>freq_ratio</key>
-								<real>0.701099</real>
-							</dict>
-						</array>
-					</dict>
-				</array>
-			</dict>
-		</array>
-		<key>package_watts</key>
-		<real>3.03713</real>
-		<key>llc_flushed_ratio</key>
-		<real>0.850534</real>
-		<key>freq_ratio</key>
-		<real>0.643069</real>
-	</dict>
-	<key>network</key>
-	<dict>
-		<key>obytes</key>
-		<integer>258</integer>
-		<key>obyte_rate</key>
-		<real>60.0588</real>
-		<key>opacket_rate</key>
-		<real>0.698358</real>
-		<key>ipackets</key>
-		<integer>8</integer>
-		<key>ibytes</key>
-		<integer>2449</integer>
-		<key>ibyte_rate</key>
-		<real>570.093</real>
-		<key>ipacket_rate</key>
-		<real>1.86229</real>
-		<key>opackets</key>
-		<integer>3</integer>
-	</dict>
-	<key>elapsed_ns</key>
-	<integer>4295788088</integer>
-	<key>is_delta</key>
-	<false/>
-</dict>
-</plist>
diff --git a/catapult/telemetry/telemetry/internal/testing/powermetrics_output_unsupported_hardware.output b/catapult/telemetry/telemetry/internal/testing/powermetrics_output_unsupported_hardware.output
deleted file mode 100644
index ce03f93..0000000
--- a/catapult/telemetry/telemetry/internal/testing/powermetrics_output_unsupported_hardware.output
+++ /dev/null
@@ -1,505 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-<key>is_delta</key><true/>
-<key>elapsed_ns</key><integer>57758028</integer>
-<key>hw_model</key><string>MacBookPro5,4</string>
-<key>kern_osversion</key><string>13B42</string>
-<key>timestamp</key><date>2014-01-26T03:58:59Z</date>
-<key>tasks</key>
-<array>
-<dict>
-<key>pid</key><integer>6555</integer>
-<key>name</key><string>Google Chrome He</string>
-<key>started_ns</key><integer>284136698238000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>35244306</integer>
-<key>cputime_ms_per_s</key><real>610.206</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.889658</real>
-<key>intr_wakeups</key><integer>3</integer>
-<key>intr_wakeups_per_s</key><real>51.9408</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>6546</integer>
-<key>name</key><string>Google Chrome He</string>
-<key>started_ns</key><integer>284134682369000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>32548397</integer>
-<key>cputime_ms_per_s</key><real>563.53</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.966536</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>6544</integer>
-<key>name</key><string>Google Chrome Ca</string>
-<key>started_ns</key><integer>284134369378000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>8773988</integer>
-<key>cputime_ms_per_s</key><real>151.909</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.78863</real>
-<key>intr_wakeups</key><integer>3</integer>
-<key>intr_wakeups_per_s</key><real>51.9408</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>6543</integer>
-<key>name</key><string>Python</string>
-<key>started_ns</key><integer>284133951261000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>5664752</integer>
-<key>cputime_ms_per_s</key><real>98.0773</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.813448</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>6556</integer>
-<key>name</key><string>powermetrics</string>
-<key>started_ns</key><integer>284137559665000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>5653312</integer>
-<key>cputime_ms_per_s</key><real>97.8792</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.275642</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>17.3136</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>4658</integer>
-<key>name</key><string>powermetrics</string>
-<key>started_ns</key><integer>283169551318000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>4295690</integer>
-<key>cputime_ms_per_s</key><real>74.3739</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.255386</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>17.3136</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>923</integer>
-<key>name</key><string>Google Chrome</string>
-<key>started_ns</key><integer>159793249000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>3993669</integer>
-<key>cputime_ms_per_s</key><real>69.1448</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.885849</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>34.6272</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>939</integer>
-<key>name</key><string>coreaudiod</string>
-<key>started_ns</key><integer>160547555000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>3831594</integer>
-<key>cputime_ms_per_s</key><real>66.3387</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.111444</real>
-<key>intr_wakeups</key><integer>20</integer>
-<key>intr_wakeups_per_s</key><real>346.272</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>20</integer>
-  <key>wakeups_per_s</key><real>346.272</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>171</integer>
-<key>name</key><string>WindowServer</string>
-<key>started_ns</key><integer>80236634000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>2596609</integer>
-<key>cputime_ms_per_s</key><real>44.9567</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.7211</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>17.3136</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>92729</integer>
-<key>name</key><string>Google Chrome He</string>
-<key>started_ns</key><integer>280934551284000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>2189391</integer>
-<key>cputime_ms_per_s</key><real>37.9063</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.859925</real>
-<key>intr_wakeups</key><integer>9</integer>
-<key>intr_wakeups_per_s</key><real>155.822</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>0</integer>
-<key>name</key><string>kernel_task</string>
-<key>started_ns</key><integer>5162903000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>1223535</integer>
-<key>cputime_ms_per_s</key><real>21.1838</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0</real>
-<key>intr_wakeups</key><integer>19</integer>
-<key>intr_wakeups_per_s</key><real>328.959</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>60</integer>
-<key>name</key><string>mds</string>
-<key>started_ns</key><integer>71568427000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>33490</integer>
-<key>cputime_ms_per_s</key><real>0.579833</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.718901</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>14230</integer>
-<key>name</key><string>CIJScannerRegist</string>
-<key>started_ns</key><integer>17913578888000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>28198</integer>
-<key>cputime_ms_per_s</key><real>0.488209</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.271189</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>34.6272</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>92766</integer>
-<key>name</key><string>GoogleTalkPlugin</string>
-<key>started_ns</key><integer>281459670930000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>22858</integer>
-<key>cputime_ms_per_s</key><real>0.395755</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.442558</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>17.3136</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-<key>all_tasks</key>
-<dict>
-<key>pid</key><integer>-2</integer>
-<key>name</key><string>ALL_TASKS</string>
-<key>started_ns</key><integer>0</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>106099789</integer>
-<key>cputime_ms_per_s</key><real>1836.97</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.798862</real>
-<key>intr_wakeups</key><integer>62</integer>
-<key>intr_wakeups_per_s</key><real>1073.44</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>20</integer>
-  <key>wakeups_per_s</key><real>346.272</real>
-</dict>
-</array>
-</dict>
-<key>backlight</key>
-<dict>
-<key>value</key><integer>412</integer>
-<key>min</key><integer>0</integer>
-<key>max</key><integer>1024</integer>
-</dict>
-<key>network</key>
-<dict>
-<key>opackets</key><integer>24</integer>
-<key>opacket_rate</key><real>415.527</real>
-<key>ipackets</key><integer>24</integer>
-<key>ipacket_rate</key><real>415.527</real>
-<key>obytes</key><integer>7244</integer>
-<key>obyte_rate</key><real>125420</real>
-<key>ibytes</key><integer>7244</integer>
-<key>ibyte_rate</key><real>125420</real>
-</dict>
-<key>disk</key>
-<dict>
-<key>rops_diff</key><integer>0</integer>
-<key>rops_per_s</key><real>0</real>
-<key>wops_diff</key><integer>0</integer>
-<key>wops_per_s</key><real>0</real>
-<key>rbytes_diff</key><integer>0</integer>
-<key>rbytes_per_s</key><real>0</real>
-<key>wbytes_diff</key><integer>0</integer>
-<key>wbytes_per_s</key><real>0</real>
-</dict>
-<key>interrupts</key>
-<array>
-<dict>
-<key>cpu</key><integer>0</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>HPET</string>
-<key>vector</key><integer>66</integer>
-<key>events</key><integer>2</integer>
-<key>events_per_s</key><real>34.6272</real>
-</dict>
-<dict>
-<key>name</key><string>IGPU</string>
-<key>vector</key><integer>146</integer>
-<key>events</key><integer>2</integer>
-<key>events_per_s</key><real>34.6272</real>
-</dict>
-<dict>
-<key>name</key><string>ARPT</string>
-<key>vector</key><integer>148</integer>
-<key>events</key><integer>2</integer>
-<key>events_per_s</key><real>34.6272</real>
-</dict>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>43</integer>
-<key>events_per_s</key><real>744.485</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>47</integer>
-<key>events_per_s</key><real>813.74</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>1</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>15</integer>
-<key>events_per_s</key><real>259.704</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>56</integer>
-<key>events_per_s</key><real>969.562</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-</plist>
diff --git a/catapult/telemetry/telemetry/internal/testing/powermetrics_vmware.output b/catapult/telemetry/telemetry/internal/testing/powermetrics_vmware.output
deleted file mode 100644
index 8cf3b8d..0000000
--- a/catapult/telemetry/telemetry/internal/testing/powermetrics_vmware.output
+++ /dev/null
@@ -1,2889 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
-<plist version="1.0">
-<dict>
-<key>is_delta</key><false/>
-<key>elapsed_ns</key><integer>2791294949</integer>
-<key>hw_model</key><string>VMware7,1</string>
-<key>kern_osversion</key><string>13F34</string>
-<key>timestamp</key><date>2014-12-09T13:48:10Z</date>
-<key>tasks</key>
-<array>
-<dict>
-<key>pid</key><integer>8283</integer>
-<key>name</key><string>Python</string>
-<key>started_ns</key><integer>258047690000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>2785827455</integer>
-<key>cputime_ms_per_s</key><real>998.698</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.907007</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>0</integer>
-<key>name</key><string>kernel_task</string>
-<key>started_ns</key><integer>252926000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>22377453</integer>
-<key>cputime_ms_per_s</key><real>8.02215</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0</real>
-<key>intr_wakeups</key><integer>393</integer>
-<key>intr_wakeups_per_s</key><real>140.888</real>
-<key>idle_wakeups</key><integer>142</integer>
-<key>idle_wakeups_per_s</key><real>50.9059</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>124</integer>
-<key>name</key><string>grr</string>
-<key>started_ns</key><integer>8507377000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>2568839</integer>
-<key>cputime_ms_per_s</key><real>0.92091</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.718355</real>
-<key>intr_wakeups</key><integer>67</integer>
-<key>intr_wakeups_per_s</key><real>24.019</real>
-<key>idle_wakeups</key><integer>52</integer>
-<key>idle_wakeups_per_s</key><real>18.6416</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>2</integer>
-  <key>wakeups_per_s</key><real>0.716985</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>1</integer>
-  <key>wakeups_per_s</key><real>0.358493</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>116</integer>
-<key>name</key><string>vmware-tools-dae</string>
-<key>started_ns</key><integer>8411762000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>3273185</integer>
-<key>cputime_ms_per_s</key><real>1.17341</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.449496</real>
-<key>intr_wakeups</key><integer>31</integer>
-<key>intr_wakeups_per_s</key><real>11.1133</real>
-<key>idle_wakeups</key><integer>22</integer>
-<key>idle_wakeups_per_s</key><real>7.88684</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>267</integer>
-<key>name</key><string>vmware-tools-dae</string>
-<key>started_ns</key><integer>73620941000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>3680193</integer>
-<key>cputime_ms_per_s</key><real>1.31932</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.437701</real>
-<key>intr_wakeups</key><integer>32</integer>
-<key>intr_wakeups_per_s</key><real>11.4718</real>
-<key>idle_wakeups</key><integer>9</integer>
-<key>idle_wakeups_per_s</key><real>3.22643</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>90</integer>
-<key>name</key><string>mds</string>
-<key>started_ns</key><integer>8404018000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>4231481</integer>
-<key>cputime_ms_per_s</key><real>1.51695</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.422196</real>
-<key>intr_wakeups</key><integer>12</integer>
-<key>intr_wakeups_per_s</key><real>4.30191</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>47</integer>
-<key>name</key><string>fseventsd</string>
-<key>started_ns</key><integer>5848136000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>3609311</integer>
-<key>cputime_ms_per_s</key><real>1.29391</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.425773</real>
-<key>intr_wakeups</key><integer>16</integer>
-<key>intr_wakeups_per_s</key><real>5.73588</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>69</integer>
-<key>name</key><string>netbiosd</string>
-<key>started_ns</key><integer>8370786000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>2217146</integer>
-<key>cputime_ms_per_s</key><real>0.79483</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.319186</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>8289</integer>
-<key>name</key><string>powermetrics</string>
-<key>started_ns</key><integer>266634178000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>1857249</integer>
-<key>cputime_ms_per_s</key><real>0.66581</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.244225</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>230</integer>
-<key>name</key><string>Finder</string>
-<key>started_ns</key><integer>72342540000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>1460335</integer>
-<key>cputime_ms_per_s</key><real>0.523519</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.403851</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>50</integer>
-<key>name</key><string>mDNSResponder</string>
-<key>started_ns</key><integer>5850938000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>1156791</integer>
-<key>cputime_ms_per_s</key><real>0.414701</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.499696</real>
-<key>intr_wakeups</key><integer>8</integer>
-<key>intr_wakeups_per_s</key><real>2.86794</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>128</integer>
-<key>name</key><string>nrpe</string>
-<key>started_ns</key><integer>8596070000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>158225</integer>
-<key>cputime_ms_per_s</key><real>0.0567225</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.148194</real>
-<key>intr_wakeups</key><integer>5</integer>
-<key>intr_wakeups_per_s</key><real>1.79246</real>
-<key>idle_wakeups</key><integer>4</integer>
-<key>idle_wakeups_per_s</key><real>1.43397</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>26</integer>
-<key>name</key><string>cfprefsd</string>
-<key>started_ns</key><integer>5283770000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>357267</integer>
-<key>cputime_ms_per_s</key><real>0.128078</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.16081</real>
-<key>intr_wakeups</key><integer>3</integer>
-<key>intr_wakeups_per_s</key><real>1.07548</real>
-<key>idle_wakeups</key><integer>3</integer>
-<key>idle_wakeups_per_s</key><real>1.07548</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>72</integer>
-<key>name</key><string>snmpd</string>
-<key>started_ns</key><integer>8399046000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>254431</integer>
-<key>cputime_ms_per_s</key><real>0.0912116</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.289497</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>0.716985</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>87</integer>
-<key>name</key><string>pacemaker</string>
-<key>started_ns</key><integer>8403252000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>234206</integer>
-<key>cputime_ms_per_s</key><real>0.0839611</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.310556</real>
-<key>intr_wakeups</key><integer>3</integer>
-<key>intr_wakeups_per_s</key><real>1.07548</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>95</integer>
-<key>name</key><string>locationd</string>
-<key>started_ns</key><integer>8405499000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>161023</integer>
-<key>cputime_ms_per_s</key><real>0.0577255</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.196748</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>0.716985</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>73</integer>
-<key>name</key><string>httpd</string>
-<key>started_ns</key><integer>8399290000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>65001</integer>
-<key>cputime_ms_per_s</key><real>0.0233024</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.298288</real>
-<key>intr_wakeups</key><integer>3</integer>
-<key>intr_wakeups_per_s</key><real>1.07548</real>
-<key>idle_wakeups</key><integer>1</integer>
-<key>idle_wakeups_per_s</key><real>0.358493</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>117</integer>
-<key>name</key><string>ruby</string>
-<key>started_ns</key><integer>8412025000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>250926</integer>
-<key>cputime_ms_per_s</key><real>0.0899551</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.789161</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>14</integer>
-<key>name</key><string>kextd</string>
-<key>started_ns</key><integer>3391443000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>239039</integer>
-<key>cputime_ms_per_s</key><real>0.0856937</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.502717</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>20</integer>
-<key>name</key><string>configd</string>
-<key>started_ns</key><integer>3427308000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>209575</integer>
-<key>cputime_ms_per_s</key><real>0.0751311</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.266702</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>93</integer>
-<key>name</key><string>loginwindow</string>
-<key>started_ns</key><integer>8404920000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>209443</integer>
-<key>cputime_ms_per_s</key><real>0.0750838</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.213891</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>272</integer>
-<key>name</key><string>com.apple.ShareK</string>
-<key>started_ns</key><integer>73682045000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>190765</integer>
-<key>cputime_ms_per_s</key><real>0.0683878</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.183666</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>8248</integer>
-<key>name</key><string>sshd</string>
-<key>started_ns</key><integer>203501449000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>186285</integer>
-<key>cputime_ms_per_s</key><real>0.0667818</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.258147</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>205</integer>
-<key>name</key><string>UserEventAgent</string>
-<key>started_ns</key><integer>12002515000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>166112</integer>
-<key>cputime_ms_per_s</key><real>0.0595499</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.258067</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>260</integer>
-<key>name</key><string>identityservices</string>
-<key>started_ns</key><integer>73617898000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>162945</integer>
-<key>cputime_ms_per_s</key><real>0.0584146</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.153935</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>17</integer>
-<key>name</key><string>notifyd</string>
-<key>started_ns</key><integer>3409006000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>155892</integer>
-<key>cputime_ms_per_s</key><real>0.0558861</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.244599</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>0.716985</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>245</integer>
-<key>name</key><string>AirPlayUIAgent</string>
-<key>started_ns</key><integer>72643963000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>143964</integer>
-<key>cputime_ms_per_s</key><real>0.05161</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.296227</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>249</integer>
-<key>name</key><string>NotificationCent</string>
-<key>started_ns</key><integer>73038119000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>138477</integer>
-<key>cputime_ms_per_s</key><real>0.049643</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.175401</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>0.716985</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>19</integer>
-<key>name</key><string>diskarbitrationd</string>
-<key>started_ns</key><integer>3425697000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>133407</integer>
-<key>cputime_ms_per_s</key><real>0.0478254</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.293141</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>112</integer>
-<key>name</key><string>apsd</string>
-<key>started_ns</key><integer>8410568000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>133265</integer>
-<key>cputime_ms_per_s</key><real>0.0477745</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.188587</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>0.716985</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>254</integer>
-<key>name</key><string>ReportPanic</string>
-<key>started_ns</key><integer>73615217000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>128367</integer>
-<key>cputime_ms_per_s</key><real>0.0460186</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.208917</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>227</integer>
-<key>name</key><string>Dock</string>
-<key>started_ns</key><integer>72337119000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>126905</integer>
-<key>cputime_ms_per_s</key><real>0.0454945</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.271258</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>18</integer>
-<key>name</key><string>powerd</string>
-<key>started_ns</key><integer>3420877000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>125879</integer>
-<key>cputime_ms_per_s</key><real>0.0451267</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.211783</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>250</integer>
-<key>name</key><string>com.apple.dock.e</string>
-<key>started_ns</key><integer>73506698000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>122322</integer>
-<key>cputime_ms_per_s</key><real>0.0438515</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.187816</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>22</integer>
-<key>name</key><string>syslogd</string>
-<key>started_ns</key><integer>3438979000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>121278</integer>
-<key>cputime_ms_per_s</key><real>0.0434773</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.240629</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>111</integer>
-<key>name</key><string>autofsd</string>
-<key>started_ns</key><integer>8410315000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>117402</integer>
-<key>cputime_ms_per_s</key><real>0.0420877</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.186803</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>99</integer>
-<key>name</key><string>hidd</string>
-<key>started_ns</key><integer>8406630000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>116557</integer>
-<key>cputime_ms_per_s</key><real>0.0417848</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.206037</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>248</integer>
-<key>name</key><string>ARDAgent</string>
-<key>started_ns</key><integer>72729660000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>116430</integer>
-<key>cputime_ms_per_s</key><real>0.0417393</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.216465</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>80</integer>
-<key>name</key><string>stackshot</string>
-<key>started_ns</key><integer>8401291000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>115387</integer>
-<key>cputime_ms_per_s</key><real>0.0413654</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.276002</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>139</integer>
-<key>name</key><string>rpcsvchost</string>
-<key>started_ns</key><integer>8709470000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>112551</integer>
-<key>cputime_ms_per_s</key><real>0.0403487</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.273076</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>130</integer>
-<key>name</key><string>WindowServer</string>
-<key>started_ns</key><integer>8647186000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>110836</integer>
-<key>cputime_ms_per_s</key><real>0.0397339</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.239417</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>522</integer>
-<key>name</key><string>suhelperd</string>
-<key>started_ns</key><integer>83826131000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>106108</integer>
-<key>cputime_ms_per_s</key><real>0.0380389</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.180627</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>114</integer>
-<key>name</key><string>airportd</string>
-<key>started_ns</key><integer>8411228000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>105857</integer>
-<key>cputime_ms_per_s</key><real>0.0379489</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.192524</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>261</integer>
-<key>name</key><string>helpd</string>
-<key>started_ns</key><integer>73618414000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>105836</integer>
-<key>cputime_ms_per_s</key><real>0.0379414</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.278535</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>520</integer>
-<key>name</key><string>softwareupdated</string>
-<key>started_ns</key><integer>83764815000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>105122</integer>
-<key>cputime_ms_per_s</key><real>0.0376855</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.205019</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>259</integer>
-<key>name</key><string>imagent</string>
-<key>started_ns</key><integer>73617455000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>103551</integer>
-<key>cputime_ms_per_s</key><real>0.0371223</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.18247</real>
-<key>intr_wakeups</key><integer>2</integer>
-<key>intr_wakeups_per_s</key><real>0.716985</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>211</integer>
-<key>name</key><string>fontd</string>
-<key>started_ns</key><integer>12043121000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>101409</integer>
-<key>cputime_ms_per_s</key><real>0.0363544</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.240639</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>77</integer>
-<key>name</key><string>usbmuxd</string>
-<key>started_ns</key><integer>8400477000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>99736</integer>
-<key>cputime_ms_per_s</key><real>0.0357546</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.236936</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>115</integer>
-<key>name</key><string>daemondo</string>
-<key>started_ns</key><integer>8411524000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>92755</integer>
-<key>cputime_ms_per_s</key><real>0.033252</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.290475</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>231</integer>
-<key>name</key><string>coreaudiod</string>
-<key>started_ns</key><integer>72346216000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>89762</integer>
-<key>cputime_ms_per_s</key><real>0.032179</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.28248</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>49</integer>
-<key>name</key><string>networkd</string>
-<key>started_ns</key><integer>5850133000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>89467</integer>
-<key>cputime_ms_per_s</key><real>0.0320733</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.232935</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>160</integer>
-<key>name</key><string>ocspd</string>
-<key>started_ns</key><integer>10495124000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>87848</integer>
-<key>cputime_ms_per_s</key><real>0.0314929</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.239163</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>23</integer>
-<key>name</key><string>opendirectoryd</string>
-<key>started_ns</key><integer>3453740000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>87217</integer>
-<key>cputime_ms_per_s</key><real>0.0312666</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.202231</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>113</integer>
-<key>name</key><string>aosnotifyd</string>
-<key>started_ns</key><integer>8410931000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>86484</integer>
-<key>cputime_ms_per_s</key><real>0.0310039</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.280919</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>273</integer>
-<key>name</key><string>secd</string>
-<key>started_ns</key><integer>73714612000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>86365</integer>
-<key>cputime_ms_per_s</key><real>0.0309612</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.303746</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>218</integer>
-<key>name</key><string>CalendarAgent</string>
-<key>started_ns</key><integer>12364928000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>86062</integer>
-<key>cputime_ms_per_s</key><real>0.0308526</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.260138</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>251</integer>
-<key>name</key><string>WiFiKeychainProx</string>
-<key>started_ns</key><integer>73614011000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>82732</integer>
-<key>cputime_ms_per_s</key><real>0.0296588</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.207731</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>8288</integer>
-<key>name</key><string>sudo</string>
-<key>started_ns</key><integer>266624234000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>78962</integer>
-<key>cputime_ms_per_s</key><real>0.0283073</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.223145</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>237</integer>
-<key>name</key><string>ubd</string>
-<key>started_ns</key><integer>72509873000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>76577</integer>
-<key>cputime_ms_per_s</key><real>0.0274523</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.324732</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>97</integer>
-<key>name</key><string>kdc</string>
-<key>started_ns</key><integer>8406021000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>70459</integer>
-<key>cputime_ms_per_s</key><real>0.025259</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.264281</real>
-<key>intr_wakeups</key><integer>1</integer>
-<key>intr_wakeups_per_s</key><real>0.358493</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>pid</key><integer>638</integer>
-<key>name</key><string>Python</string>
-<key>started_ns</key><integer>104013927000</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>67435</integer>
-<key>cputime_ms_per_s</key><real>0.0241749</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.235634</real>
-<key>intr_wakeups</key><integer>0</integer>
-<key>intr_wakeups_per_s</key><real>0</real>
-<key>idle_wakeups</key><integer>0</integer>
-<key>idle_wakeups_per_s</key><real>0</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>0</integer>
-  <key>wakeups_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-<key>all_tasks</key>
-warning: time went backwards by 1418132621000000000 ns
-<dict>
-<key>pid</key><integer>-2</integer>
-<key>name</key><string>ALL_TASKS</string>
-<key>started_ns</key><integer>0</integer>
-<key>started_ns_reliable</key><false/>
-<key>cputime_ns</key><integer>2838933344</integer>
-<key>cputime_ms_per_s</key><real>1017.07</real>
-<key>cputime_ms_per_s_reliable</key><true/>
-<key>cputime_userland_ratio</key><real>0.894385</real>
-<key>intr_wakeups</key><integer>623</integer>
-<key>intr_wakeups_per_s</key><real>223.194</real>
-<key>idle_wakeups</key><integer>239</integer>
-<key>idle_wakeups_per_s</key><real>85.6233</real>
-<key>timer_wakeups</key>
-<array>
-<dict>
-  <key>interval_ns</key><integer>2000000</integer>
-  <key>wakeups</key><integer>2</integer>
-  <key>wakeups_per_s</key><real>0.716513</real>
-</dict>
-<dict>
-  <key>interval_ns</key><integer>5000000</integer>
-  <key>wakeups</key><integer>1</integer>
-  <key>wakeups_per_s</key><real>0.358257</real>
-</dict>
-</array>
-</dict>
-<key>network</key>
-<dict>
-<key>opackets</key><integer>2</integer>
-<key>opacket_rate</key><real>0.716513</real>
-<key>ipackets</key><integer>41</integer>
-<key>ipacket_rate</key><real>14.6885</real>
-<key>obytes</key><integer>168</integer>
-<key>obyte_rate</key><real>60.1871</real>
-<key>ibytes</key><integer>6304</integer>
-<key>ibyte_rate</key><real>2258.45</real>
-</dict>
-<key>disk</key>
-<dict>
-<key>rops_diff</key><integer>1</integer>
-<key>rops_per_s</key><real>0.358257</real>
-<key>wops_diff</key><integer>251</integer>
-<key>wops_per_s</key><real>89.9224</real>
-<key>rbytes_diff</key><integer>4096</integer>
-<key>rbytes_per_s</key><real>1467.42</real>
-<key>wbytes_diff</key><integer>65906688</integer>
-<key>wbytes_per_s</key><real>2.36115e+07</real>
-</dict>
-<key>interrupts</key>
-<array>
-<dict>
-<key>cpu</key><integer>0</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>CHN1</string>
-<key>vector</key><integer>79</integer>
-<key>events</key><integer>9</integer>
-<key>events_per_s</key><real>3.22431</real>
-</dict>
-<dict>
-<key>name</key><string>scsi</string>
-<key>vector</key><integer>81</integer>
-<key>events</key><integer>239</integer>
-<key>events_per_s</key><real>85.6233</real>
-</dict>
-<dict>
-<key>name</key><string>S2F0</string>
-<key>vector</key><integer>83</integer>
-<key>events</key><integer>34</integer>
-<key>events_per_s</key><real>12.1807</real>
-</dict>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>108</integer>
-<key>events_per_s</key><real>38.6917</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>92</integer>
-<key>events_per_s</key><real>32.9596</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>1</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>126</integer>
-<key>events_per_s</key><real>45.1403</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>183</integer>
-<key>events_per_s</key><real>65.561</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>2</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>41</integer>
-<key>events_per_s</key><real>14.6885</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>152</integer>
-<key>events_per_s</key><real>54.455</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>3</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>97</integer>
-<key>events_per_s</key><real>34.7509</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>72</integer>
-<key>events_per_s</key><real>25.7945</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>4</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>10</integer>
-<key>events_per_s</key><real>3.58257</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>104</integer>
-<key>events_per_s</key><real>37.2587</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>5</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>94</integer>
-<key>events_per_s</key><real>33.6761</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>140</integer>
-<key>events_per_s</key><real>50.1559</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>6</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>53</integer>
-<key>events_per_s</key><real>18.9876</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>150</integer>
-<key>events_per_s</key><real>53.7385</real>
-</dict>
-</array>
-</dict>
-<dict>
-<key>cpu</key><integer>7</integer>
-<key>vectors</key>
-<array>
-<dict>
-<key>name</key><string>TMR</string>
-<key>vector</key><integer>221</integer>
-<key>events</key><integer>1</integer>
-<key>events_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>name</key><string>IPI</string>
-<key>vector</key><integer>222</integer>
-<key>events</key><integer>28</integer>
-<key>events_per_s</key><real>10.0312</real>
-</dict>
-</array>
-</dict>
-</array>
-<key>processor</key>
-<dict>
-<key>llc_flushed_ratio</key><real>0</real>
-<key>packages</key>
-<array>
-<dict>
-<key>package</key><integer>0</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C2</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cores</key>
-<array>
-<dict>
-<key>core</key><integer>0</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>0</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>162</integer>
-<key>active_per_s</key><real>58.0376</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>58.0376</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>6</integer>
-<key>active_per_s</key><real>2.14954</real>
-<key>idle_count</key><integer>15</integer>
-<key>idle_per_s</key><real>2.14954</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>28</integer>
-<key>active_per_s</key><real>10.0312</real>
-<key>idle_count</key><integer>104</integer>
-<key>idle_per_s</key><real>10.0312</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>62</integer>
-<key>active_per_s</key><real>22.2119</real>
-<key>idle_count</key><integer>8</integer>
-<key>idle_per_s</key><real>22.2119</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>23</integer>
-<key>active_per_s</key><real>8.2399</real>
-<key>idle_count</key><integer>5</integer>
-<key>idle_per_s</key><real>8.2399</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>2</integer>
-<key>active_per_s</key><real>0.716513</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>0.716513</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>3</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>19</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>20</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>31</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>29</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>26</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>core</key><integer>1</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>1</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>98</integer>
-<key>active_per_s</key><real>35.1092</real>
-<key>idle_count</key><integer>3</integer>
-<key>idle_per_s</key><real>35.1092</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>24</integer>
-<key>active_per_s</key><real>8.59816</real>
-<key>idle_count</key><integer>21</integer>
-<key>idle_per_s</key><real>8.59816</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>51</integer>
-<key>active_per_s</key><real>18.2711</real>
-<key>idle_count</key><integer>43</integer>
-<key>idle_per_s</key><real>18.2711</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>34</integer>
-<key>active_per_s</key><real>12.1807</real>
-<key>idle_count</key><integer>12</integer>
-<key>idle_per_s</key><real>12.1807</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>13</integer>
-<key>active_per_s</key><real>4.65734</real>
-<key>idle_count</key><integer>6</integer>
-<key>idle_per_s</key><real>4.65734</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>3</integer>
-<key>active_per_s</key><real>1.07477</real>
-<key>idle_count</key><integer>5</integer>
-<key>idle_per_s</key><real>1.07477</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>2</integer>
-<key>active_per_s</key><real>0.716513</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>0.716513</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>19</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>21</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>25</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>25</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>29</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>core</key><integer>2</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>2</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>79</integer>
-<key>active_per_s</key><real>28.3023</real>
-<key>idle_count</key><integer>5</integer>
-<key>idle_per_s</key><real>28.3023</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>25</integer>
-<key>active_per_s</key><real>8.95642</real>
-<key>idle_count</key><integer>29</integer>
-<key>idle_per_s</key><real>8.95642</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>39</integer>
-<key>active_per_s</key><real>13.972</real>
-<key>idle_count</key><integer>17</integer>
-<key>idle_per_s</key><real>13.972</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>26</integer>
-<key>active_per_s</key><real>9.31467</real>
-<key>idle_count</key><integer>6</integer>
-<key>idle_per_s</key><real>9.31467</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>11</integer>
-<key>active_per_s</key><real>3.94082</real>
-<key>idle_count</key><integer>7</integer>
-<key>idle_per_s</key><real>3.94082</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>9</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>12</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>14</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>26</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>26</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>core</key><integer>3</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>3</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>37</integer>
-<key>active_per_s</key><real>13.2555</real>
-<key>idle_count</key><integer>3</integer>
-<key>idle_per_s</key><real>13.2555</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>9</integer>
-<key>active_per_s</key><real>3.22431</real>
-<key>idle_count</key><integer>12</integer>
-<key>idle_per_s</key><real>3.22431</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>15</integer>
-<key>active_per_s</key><real>5.37385</real>
-<key>idle_count</key><integer>14</integer>
-<key>idle_per_s</key><real>5.37385</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>11</integer>
-<key>active_per_s</key><real>3.94082</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>3.94082</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>5</integer>
-<key>active_per_s</key><real>1.79128</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>1.79128</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>10</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>11</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>package</key><integer>1</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C2</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C8</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C9</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C10</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cores</key>
-<array>
-<dict>
-<key>core</key><integer>4</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>4</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>23</integer>
-<key>active_per_s</key><real>8.2399</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>8.2399</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>10</integer>
-<key>active_per_s</key><real>3.58257</real>
-<key>idle_count</key><integer>21</integer>
-<key>idle_per_s</key><real>3.58257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>30</integer>
-<key>active_per_s</key><real>10.7477</real>
-<key>idle_count</key><integer>13</integer>
-<key>idle_per_s</key><real>10.7477</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>22</integer>
-<key>active_per_s</key><real>7.88165</real>
-<key>idle_count</key><integer>5</integer>
-<key>idle_per_s</key><real>7.88165</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>9</integer>
-<key>active_per_s</key><real>3.22431</real>
-<key>idle_count</key><integer>3</integer>
-<key>idle_per_s</key><real>3.22431</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>8</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>6</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>11</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>3</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>5</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>core</key><integer>5</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>5</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>97</integer>
-<key>active_per_s</key><real>34.7509</real>
-<key>idle_count</key><integer>3</integer>
-<key>idle_per_s</key><real>34.7509</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>20</integer>
-<key>active_per_s</key><real>7.16513</real>
-<key>idle_count</key><integer>60</integer>
-<key>idle_per_s</key><real>7.16513</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>18</integer>
-<key>active_per_s</key><real>6.44862</real>
-<key>idle_count</key><integer>38</integer>
-<key>idle_per_s</key><real>6.44862</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>9</integer>
-<key>active_per_s</key><real>3.22431</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>3.22431</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>2</integer>
-<key>active_per_s</key><real>0.716513</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0.716513</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>6</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>4</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>core</key><integer>6</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>6</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>78</integer>
-<key>active_per_s</key><real>27.944</real>
-<key>idle_count</key><integer>6</integer>
-<key>idle_per_s</key><real>27.944</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>40</integer>
-<key>active_per_s</key><real>14.3303</real>
-<key>idle_count</key><integer>29</integer>
-<key>idle_per_s</key><real>14.3303</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>31</integer>
-<key>active_per_s</key><real>11.106</real>
-<key>idle_count</key><integer>36</integer>
-<key>idle_per_s</key><real>11.106</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>31</integer>
-<key>active_per_s</key><real>11.106</real>
-<key>idle_count</key><integer>7</integer>
-<key>idle_per_s</key><real>11.106</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>2</integer>
-<key>active_per_s</key><real>0.716513</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>0.716513</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>6</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>10</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>9</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>21</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>18</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-<dict>
-<key>core</key><integer>7</integer>
-<key>c_state_ns</key><integer>0</integer>
-<key>c_state_ratio</key><real>0</real>
-<key>c_states</key>
-<array>
-<dict>
-<key>name</key><string>C3</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C6</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-<dict>
-<key>name</key><string>C7</string>
-<key>used_ns</key><integer>0</integer>
-<key>used_ratio</key><real>0</real>
-</dict>
-</array>
-<key>cpus</key>
-<array>
-<dict>
-<key>cpu</key><integer>7</integer>
-<key>duty_cycles</key>
-<array>
-<dict>
-<key>interval_ns</key><integer>16000</integer>
-<key>active_count</key><integer>11</integer>
-<key>active_per_s</key><real>3.94082</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>3.94082</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>64000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>2</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>128000</integer>
-<key>active_count</key><integer>2</integer>
-<key>active_per_s</key><real>0.716513</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0.716513</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>256000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>512000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>1024000</integer>
-<key>active_count</key><integer>1</integer>
-<key>active_per_s</key><real>0.358257</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0.358257</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>2048000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>4096000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>8192000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>16384000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>0</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-<dict>
-<key>interval_ns</key><integer>32768000</integer>
-<key>active_count</key><integer>0</integer>
-<key>active_per_s</key><real>0</real>
-<key>idle_count</key><integer>1</integer>
-<key>idle_per_s</key><real>0</real>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-</array>
-</dict>
-</dict>
-</plist>
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/proc_meminfo b/catapult/telemetry/telemetry/internal/testing/proc_meminfo
deleted file mode 100644
index 600101a..0000000
--- a/catapult/telemetry/telemetry/internal/testing/proc_meminfo
+++ /dev/null
@@ -1,43 +0,0 @@
-MemTotal:       65897648 kB
-MemFree:         1084568 kB
-Buffers:         1221540 kB
-Cached:         38339400 kB
-SwapCached:       119564 kB
-Active:         38582600 kB
-Inactive:       20341624 kB
-Active(anon):   17113656 kB
-Inactive(anon):  2566996 kB
-Active(file):   21468944 kB
-Inactive(file): 17774628 kB
-Unevictable:       27280 kB
-Mlocked:           27280 kB
-SwapTotal:       1048572 kB
-SwapFree:              8 kB
-Dirty:               452 kB
-Writeback:             0 kB
-AnonPages:      19271176 kB
-Mapped:           724456 kB
-Shmem:            290412 kB
-Slab:            5047568 kB
-SReclaimable:    4773516 kB
-SUnreclaim:       274052 kB
-KernelStack:       21824 kB
-PageTables:       133852 kB
-NFS_Unstable:          0 kB
-Bounce:                0 kB
-WritebackTmp:          0 kB
-CommitLimit:    33997396 kB
-Committed_AS:   36218868 kB
-VmallocTotal:   34359738367 kB
-VmallocUsed:      338372 kB
-VmallocChunk:   34325659540 kB
-HardwareCorrupted:     0 kB
-AnonHugePages:   9410560 kB
-HugePages_Total:       0
-HugePages_Free:        0
-HugePages_Rsvd:        0
-HugePages_Surp:        0
-Hugepagesize:       2048 kB
-DirectMap4k:     6369212 kB
-DirectMap2M:    58564608 kB
-DirectMap1G:     2097152 kB
diff --git a/catapult/telemetry/telemetry/internal/testing/sample_perf_report_output.txt b/catapult/telemetry/telemetry/internal/testing/sample_perf_report_output.txt
deleted file mode 100644
index 2f7dd93..0000000
--- a/catapult/telemetry/telemetry/internal/testing/sample_perf_report_output.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-Failed to open /data/app-lib/com.google.android.apps.chrome-2/libchrome.2016.0.so, continuing without symbols
-Failed to open /data/dalvik-cache/arm/data@app@com.google.android.apps.chrome-2.apk@classes.dex, continuing without symbols
-No kallsyms or vmlinux with build-id 3b63ca692cbb756f837744e061d02a790bf637d5 was found
-[kernel.kallsyms] with build id 3b63ca692cbb756f837744e061d02a790bf637d5 not found, continuing without symbols
-Failed to open /system/lib/libc.so, continuing without symbols
-Failed to open /system/lib/libm.so, continuing without symbols
-Failed to open /tmp/perf-18246.map, continuing without symbols
-Failed to open /system/lib/libart.so, continuing without symbols
-Failed to open /init, continuing without symbols
-Failed to open [vectors], continuing without symbols
diff --git a/catapult/telemetry/telemetry/internal/testing/sample_vtune_db_output b/catapult/telemetry/telemetry/internal/testing/sample_vtune_db_output
deleted file mode 100644
index 71c6eaa..0000000
--- a/catapult/telemetry/telemetry/internal/testing/sample_vtune_db_output
+++ /dev/null
@@ -1,316 +0,0 @@
-(lp0
-(V/data/app-lib/com.google.android.apps.chrome-1/libchrome.2019.0.so
-p1
-V/tmp/amplxe-tmp-dominikg/modules.android/libchrome.2019.0.so/00a9b3533743e080ab94e760bc891ab8/libchrome.2019.0.so
-p2
-tp3
-a(V/system/bin/app_process
-p4
-Ntp5
-a(V/system/bin/linker
-p6
-Ntp7
-a(V/system/lib/libcutils.so
-p8
-Ntp9
-a(V/system/lib/liblog.so
-p10
-Ntp11
-a(V/system/lib/libc.so
-p12
-V/tmp/amplxe-tmp-dominikg/modules.android/libc.so/abc82d050be774f342adeb7e91fe5a0a/libc.so
-p13
-tp14
-a(V/system/lib/libstdc++.so
-p15
-Ntp16
-a(V/system/lib/libm.so
-p17
-V/tmp/amplxe-tmp-dominikg/modules.android/libm.so/55c87bc955f6c7bf84cce8522fb1e88b/libm.so
-p18
-tp19
-a(V/system/lib/libutils.so
-p20
-Ntp21
-a(V/system/lib/libcorkscrew.so
-p22
-Ntp23
-a(V/system/lib/libgccdemangle.so
-p24
-Ntp25
-a(V/system/lib/libz.so
-p26
-Ntp27
-a(V/system/lib/libbinder.so
-p28
-Ntp29
-a(V/system/lib/libandroid_runtime.so
-p30
-Ntp31
-a(V/system/lib/libandroidfw.so
-p32
-Ntp33
-a(V/system/lib/libskia.so
-p34
-Ntp35
-a(V/system/lib/libemoji.so
-p36
-Ntp37
-a(V/system/lib/libjpeg.so
-p38
-Ntp39
-a(V/system/lib/libexpat.so
-p40
-Ntp41
-a(V/system/lib/libEGL.so
-p42
-Ntp43
-a(V/system/lib/libGLES_trace.so
-p44
-Ntp45
-a(V/system/lib/libstlport.so
-p46
-Ntp47
-a(V/system/lib/libGLESv2.so
-p48
-Ntp49
-a(V/system/lib/libnativehelper.so
-p50
-Ntp51
-a(V/system/lib/libnetutils.so
-p52
-Ntp53
-a(V/system/lib/libui.so
-p54
-Ntp55
-a(V/system/lib/libhardware.so
-p56
-Ntp57
-a(V/system/lib/libsync.so
-p58
-Ntp59
-a(V/system/lib/libgui.so
-p60
-Ntp61
-a(V/system/lib/libcamera_client.so
-p62
-Ntp63
-a(V/system/lib/libcamera_metadata.so
-p64
-Ntp65
-a(V/system/lib/libsqlite.so
-p66
-Ntp67
-a(V/system/lib/libicuuc.so
-p68
-Ntp69
-a(V/system/lib/libgabi++.so
-p70
-Ntp71
-a(V/system/lib/libicui18n.so
-p72
-Ntp73
-a(V/system/lib/libdvm.so
-p74
-V/tmp/amplxe-tmp-dominikg/modules.android/libdvm.so/8f6c9167e20b377dc90646a1bac0e201/libdvm.so
-p75
-tp76
-a(V/system/lib/libselinux.so
-p77
-Ntp78
-a(V/system/lib/libGLESv1_CM.so
-p79
-Ntp80
-a(V/system/lib/libETC1.so
-p81
-Ntp82
-a(V/system/lib/libhardware_legacy.so
-p83
-Ntp84
-a(V/system/lib/libwpa_client.so
-p85
-Ntp86
-a(V/system/lib/libsonivox.so
-p87
-Ntp88
-a(V/system/lib/libcrypto.so
-p89
-Ntp90
-a(V/system/lib/libssl.so
-p91
-Ntp92
-a(V/system/lib/libmedia.so
-p93
-Ntp94
-a(V/system/lib/libstagefright_foundation.so
-p95
-Ntp96
-a(V/system/lib/libaudioutils.so
-p97
-Ntp98
-a(V/system/lib/libspeexresampler.so
-p99
-Ntp100
-a(V/system/lib/libaudioresample.so
-p101
-Ntp102
-a(V/system/lib/libusbhost.so
-p103
-Ntp104
-a(V/system/lib/libharfbuzz_ng.so
-p105
-Ntp106
-a(V/system/lib/libhwui.so
-p107
-Ntp108
-a(V/system/lib/libRS.so
-p109
-Ntp110
-a(V/system/lib/libbcc.so
-p111
-Ntp112
-a(V/system/lib/libbcinfo.so
-p113
-Ntp114
-a(V/system/lib/libLLVM.so
-p115
-Ntp116
-a(V/system/lib/libRScpp.so
-p117
-Ntp118
-a(V/system/lib/libjavacore.so
-p119
-Ntp120
-a(V/system/lib/libdrmframework_jni.so
-p121
-Ntp122
-a(V/system/lib/libdrmframework.so
-p123
-Ntp124
-a(V/system/lib/libstagefright_yuv.so
-p125
-Ntp126
-a(V/system/lib/libdrm.so
-p127
-Ntp128
-a(V/system/lib/libmedia_jni.so
-p129
-Ntp130
-a(V/system/lib/libstagefright_omx.so
-p131
-Ntp132
-a(V/system/lib/libvorbisidec.so
-p133
-Ntp134
-a(V/system/lib/libva.so
-p135
-Ntp136
-a(V/system/lib/libva-android.so
-p137
-Ntp138
-a(V/system/lib/libva-tpi.so
-p139
-Ntp140
-a(V/system/lib/libva_videodecoder.so
-p141
-Ntp142
-a(V/system/lib/libmixvbp.so
-p143
-Ntp144
-a(V/system/lib/libasfparser.so
-p145
-Ntp146
-a(V/system/lib/libstagefright_enc_common.so
-p147
-Ntp148
-a(V/system/lib/libstagefright_avc_common.so
-p149
-Ntp150
-a(V/system/lib/libmultidisplay.so
-p151
-Ntp152
-a(V/system/lib/libsepdrm.so
-p153
-Ntp154
-a(V/system/lib/libmtp.so
-p155
-Ntp156
-a(V/system/lib/libexif.so
-p157
-Ntp158
-a(V/system/lib/libstagefright_amrnb_common.so
-p159
-Ntp160
-a(V/system/lib/libexif_jni.so
-p161
-Ntp162
-a(V/system/lib/libsoundpool.so
-p163
-Ntp164
-a(V/system/lib/libvideoeditor_jni.so
-p165
-Ntp166
-a(V/system/lib/libaudioflinger.so
-p167
-Ntp168
-a(V/system/lib/libcommon_time_client.so
-p169
-Ntp170
-a(V/system/lib/libnbaio.so
-p171
-Ntp172
-a(V/system/lib/libeffects.so
-p173
-Ntp174
-a(V/system/lib/libpowermanager.so
-p175
-Ntp176
-a(V/system/lib/libvideoeditor_core.so
-p177
-Ntp178
-a(V/system/lib/libvideoeditor_osal.so
-p179
-Ntp180
-a(V/system/lib/libvideoeditor_videofilters.so
-p181
-Ntp182
-a(V/system/lib/libvideoeditorplayer.so
-p183
-Ntp184
-a(V/system/lib/libsharedbuffer.so
-p185
-Ntp186
-a(V/system/lib/libva_videoencoder.so
-p187
-Ntp188
-a(V/system/lib/libintelmetadatabuffer.so
-p189
-Ntp190
-a(V/system/lib/librs_jni.so
-p191
-Ntp192
-a(V/system/lib/libandroid.so
-p193
-Ntp194
-a(V/system/lib/libharfbuzz.so
-p195
-Ntp196
-a(V/system/lib/libstagefright.so
-p197
-Ntp198
-a(V/system/lib/libwebcore.so
-p199
-Ntp200
-a(V/system/lib/libchromium_net.so
-p201
-Ntp202
-a(V/data/app-lib/com.google.android.apps.chrome-1/libchromium_android_linker.so
-p203
-Ntp204
-a(V/system/lib/libjnigraphics.so
-p205
-Ntp206
-a(V/dev/ashmem/dalvik-jit-code-cache (deleted)
-p207
-Ntp208
-a.
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/screen_3_frames.mov b/catapult/telemetry/telemetry/internal/testing/screen_3_frames.mov
deleted file mode 100644
index 7a90f07..0000000
--- a/catapult/telemetry/telemetry/internal/testing/screen_3_frames.mov
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/screenshot_test.html b/catapult/telemetry/telemetry/internal/testing/screenshot_test.html
deleted file mode 100644
index 239e9a7..0000000
--- a/catapult/telemetry/telemetry/internal/testing/screenshot_test.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <style>
-  html, body {
-    margin: 0;
-    padding: 0;
-  }
-  #colorful {
-    width: 32px;
-    height: 32px;
-    background-color: rgb(217, 115, 43);
-  }
-  </style>
-</head>
-<body>
-  <div id="colorful"></div>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/scrollable_page.html b/catapult/telemetry/telemetry/internal/testing/scrollable_page.html
deleted file mode 100644
index c50175b..0000000
--- a/catapult/telemetry/telemetry/internal/testing/scrollable_page.html
+++ /dev/null
@@ -1,33 +0,0 @@
-<!doctype html>
-<html>
-  <head>
-    <style type="text/css">
-      body { height: 200vh; }
-    </style>
-  </head>
-  <body>
-    <!--
-    Below info are used in smoothness unittest only. use URL below to get the 
-    diagnostic info which is used when this page failed in test due to the 
-    scroll bar didn't show up.
-    scrollable_page.html?show_scroll_diagnosis_info
-    -->
-    <div id="info"></div>
-    <script>
-      var txt = "<h3>Screen info (Used for diagnosis):</h3>"
-                + "<p>Total width/height: " + screen.width + "*" + screen.height
-                + "</p><p>Available width/height: " + screen.availWidth + "*" 
-                + screen.availHeight + "</p><p>Color depth: "
-                + screen.colorDepth + "</p><p>Color resolution: "
-                + screen.pixelDepth + "</p><p>Body scrollable height: "
-                + document.body.scrollHeight + "</p><p>Body offset height: "
-                + document.body.offsetHeight + "</p><p>Body client height: "
-                + document.body.clientHeight + "</p><p>Window inner height: "
-                + window.innerHeight + "</p><p>Window device Pixel Ratio: "
-                + window.devicePixelRatio + "</p>";
-      if (window.location.search.substr(1) == "show_scroll_diagnosis_info") {
-          document.getElementById("info").innerHTML = txt;
-      }
-    </script>
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/simple_app/background.js b/catapult/telemetry/telemetry/internal/testing/simple_app/background.js
deleted file mode 100644
index 01412a3..0000000
--- a/catapult/telemetry/telemetry/internal/testing/simple_app/background.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-chrome.app.window.create('main.html');
-chrome.app.window.create('second.html');
diff --git a/catapult/telemetry/telemetry/internal/testing/simple_app/main.html b/catapult/telemetry/telemetry/internal/testing/simple_app/main.html
deleted file mode 100644
index bb67633..0000000
--- a/catapult/telemetry/telemetry/internal/testing/simple_app/main.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
-This is the simple telemetry webapp main page.
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/simple_app/manifest.json b/catapult/telemetry/telemetry/internal/testing/simple_app/manifest.json
deleted file mode 100644
index 5275205..0000000
--- a/catapult/telemetry/telemetry/internal/testing/simple_app/manifest.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
-  "description": "Simple Telemetry Test WebApp",
-  "name": "Simple Telemetry Test WebApp",
-  "app": {
-    "background": {
-      "scripts": ["background.js"]
-    }
-  },
-  "manifest_version": 2,
-  "version": "1.0"
-}
diff --git a/catapult/telemetry/telemetry/internal/testing/simple_app/second.html b/catapult/telemetry/telemetry/internal/testing/simple_app/second.html
deleted file mode 100644
index debc8fc..0000000
--- a/catapult/telemetry/telemetry/internal/testing/simple_app/second.html
+++ /dev/null
@@ -1,5 +0,0 @@
-<html>
-<body>
-This is the simple telemetry webapp secondary page.
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/simple_extension/background.js b/catapult/telemetry/telemetry/internal/testing/simple_extension/background.js
deleted file mode 100644
index 303ef9f..0000000
--- a/catapult/telemetry/telemetry/internal/testing/simple_extension/background.js
+++ /dev/null
@@ -1,8 +0,0 @@
-// Copyright 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-var _testVar;
-function setTestVar(x) {
-  _testVar = x;
-}
diff --git a/catapult/telemetry/telemetry/internal/testing/simple_extension/manifest.json b/catapult/telemetry/telemetry/internal/testing/simple_extension/manifest.json
deleted file mode 100644
index d4bb6a3..0000000
--- a/catapult/telemetry/telemetry/internal/testing/simple_extension/manifest.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "description": "Simple test extension which has just a background script",
-  "name": "Simple Telemetry Test Extension",
-  "background": {
-    "scripts": ["background.js"]
-  },
-  "manifest_version": 2,
-  "version": "0.1"
-}
diff --git a/catapult/telemetry/telemetry/internal/testing/smaps b/catapult/telemetry/telemetry/internal/testing/smaps
deleted file mode 100644
index 7902e52..0000000
--- a/catapult/telemetry/telemetry/internal/testing/smaps
+++ /dev/null
@@ -1,1065 +0,0 @@
-00400000-004a2000 r-xp 00000000 08:01 2883606                            /bin/zsh4
-Size:                648 kB
-Rss:                 584 kB
-Pss:                  30 kB
-Shared_Clean:        584 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:          584 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-006a1000-006a2000 r--p 000a1000 08:01 2883606                            /bin/zsh4
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-006a2000-006a8000 rw-p 000a2000 08:01 2883606                            /bin/zsh4
-Size:                 24 kB
-Rss:                  24 kB
-Pss:                  24 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        24 kB
-Referenced:           24 kB
-Anonymous:            24 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-006a8000-006bc000 rw-p 00000000 00:00 0 
-Size:                 80 kB
-Rss:                  44 kB
-Pss:                  44 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        44 kB
-Referenced:           44 kB
-Anonymous:            44 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-0137c000-0168d000 rw-p 00000000 00:00 0                                  [heap]
-Size:               3140 kB
-Rss:                3116 kB
-Pss:                3116 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:      3116 kB
-Referenced:         3116 kB
-Anonymous:          3116 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff557c58000-7ff557c68000 r-xp 00000000 08:01 7082269                    /usr/lib/zsh/4.3.17/zsh/computil.so
-Size:                 64 kB
-Rss:                  52 kB
-Pss:                   4 kB
-Shared_Clean:         52 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           52 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff557c68000-7ff557e67000 ---p 00010000 08:01 7082269                    /usr/lib/zsh/4.3.17/zsh/computil.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff557e67000-7ff557e68000 r--p 0000f000 08:01 7082269                    /usr/lib/zsh/4.3.17/zsh/computil.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff557e68000-7ff557e69000 rw-p 00010000 08:01 7082269                    /usr/lib/zsh/4.3.17/zsh/computil.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff557e69000-7ff557e72000 r-xp 00000000 08:01 7082280                    /usr/lib/zsh/4.3.17/zsh/parameter.so
-Size:                 36 kB
-Rss:                  28 kB
-Pss:                   2 kB
-Shared_Clean:         28 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           28 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff557e72000-7ff558071000 ---p 00009000 08:01 7082280                    /usr/lib/zsh/4.3.17/zsh/parameter.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558071000-7ff558072000 r--p 00008000 08:01 7082280                    /usr/lib/zsh/4.3.17/zsh/parameter.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558072000-7ff558073000 rw-p 00009000 08:01 7082280                    /usr/lib/zsh/4.3.17/zsh/parameter.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558073000-7ff55807a000 r-xp 00000000 08:01 7082272                    /usr/lib/zsh/4.3.17/zsh/zutil.so
-Size:                 28 kB
-Rss:                  24 kB
-Pss:                   1 kB
-Shared_Clean:         24 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           24 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55807a000-7ff558279000 ---p 00007000 08:01 7082272                    /usr/lib/zsh/4.3.17/zsh/zutil.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558279000-7ff55827a000 r--p 00006000 08:01 7082272                    /usr/lib/zsh/4.3.17/zsh/zutil.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55827a000-7ff55827b000 rw-p 00007000 08:01 7082272                    /usr/lib/zsh/4.3.17/zsh/zutil.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55827b000-7ff55829d000 r-xp 00000000 08:01 7082291                    /usr/lib/zsh/4.3.17/zsh/complete.so
-Size:                136 kB
-Rss:                 128 kB
-Pss:                   8 kB
-Shared_Clean:        128 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:          128 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55829d000-7ff55849c000 ---p 00022000 08:01 7082291                    /usr/lib/zsh/4.3.17/zsh/complete.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55849c000-7ff55849d000 r--p 00021000 08:01 7082291                    /usr/lib/zsh/4.3.17/zsh/complete.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55849d000-7ff55849e000 rw-p 00022000 08:01 7082291                    /usr/lib/zsh/4.3.17/zsh/complete.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55849e000-7ff5584dd000 r-xp 00000000 08:01 7082277                    /usr/lib/zsh/4.3.17/zsh/zle.so
-Size:                252 kB
-Rss:                 224 kB
-Pss:                  13 kB
-Shared_Clean:        224 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:          224 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5584dd000-7ff5586dd000 ---p 0003f000 08:01 7082277                    /usr/lib/zsh/4.3.17/zsh/zle.so
-Size:               2048 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5586dd000-7ff5586de000 r--p 0003f000 08:01 7082277                    /usr/lib/zsh/4.3.17/zsh/zle.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5586de000-7ff5586e5000 rw-p 00040000 08:01 7082277                    /usr/lib/zsh/4.3.17/zsh/zle.so
-Size:                 28 kB
-Rss:                  28 kB
-Pss:                  28 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        28 kB
-Referenced:           28 kB
-Anonymous:            28 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5586e5000-7ff5586e7000 r-xp 00000000 08:01 7082293                    /usr/lib/zsh/4.3.17/zsh/terminfo.so
-Size:                  8 kB
-Rss:                   8 kB
-Pss:                   0 kB
-Shared_Clean:          8 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            8 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5586e7000-7ff5588e6000 ---p 00002000 08:01 7082293                    /usr/lib/zsh/4.3.17/zsh/terminfo.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5588e6000-7ff5588e7000 r--p 00001000 08:01 7082293                    /usr/lib/zsh/4.3.17/zsh/terminfo.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5588e7000-7ff5588e8000 rw-p 00002000 08:01 7082293                    /usr/lib/zsh/4.3.17/zsh/terminfo.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5588e8000-7ff5588ec000 r-xp 00000000 08:01 6688948                    /usr/lib/libnss_cache.so.2.0 (deleted)
-Size:                 16 kB
-Rss:                  12 kB
-Pss:                   0 kB
-Shared_Clean:         12 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           12 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff5588ec000-7ff558aeb000 ---p 00004000 08:01 6688948                    /usr/lib/libnss_cache.so.2.0 (deleted)
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558aeb000-7ff558aec000 r--p 00003000 08:01 6688948                    /usr/lib/libnss_cache.so.2.0 (deleted)
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558aec000-7ff558aed000 rw-p 00004000 08:01 6688948                    /usr/lib/libnss_cache.so.2.0 (deleted)
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558aed000-7ff558af9000 r-xp 00000000 08:01 41681577                   /lib/x86_64-linux-gnu/libnss_files-2.15.so
-Size:                 48 kB
-Rss:                  16 kB
-Pss:                   0 kB
-Shared_Clean:         16 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           16 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558af9000-7ff558cf8000 ---p 0000c000 08:01 41681577                   /lib/x86_64-linux-gnu/libnss_files-2.15.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558cf8000-7ff558cf9000 r--p 0000b000 08:01 41681577                   /lib/x86_64-linux-gnu/libnss_files-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558cf9000-7ff558cfa000 rw-p 0000c000 08:01 41681577                   /lib/x86_64-linux-gnu/libnss_files-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff558d1e000-7ff559be1000 r--p 00000000 08:01 7209368                    /usr/lib/locale/locale-archive
-Size:              15116 kB
-Rss:                  76 kB
-Pss:                  10 kB
-Shared_Clean:         68 kB
-Shared_Dirty:          0 kB
-Private_Clean:         8 kB
-Private_Dirty:         0 kB
-Referenced:           76 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff559be1000-7ff559d96000 r-xp 00000000 08:01 41681428                   /lib/x86_64-linux-gnu/libc-2.15.so
-Size:               1748 kB
-Rss:                 696 kB
-Pss:                   7 kB
-Shared_Clean:        696 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:          696 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff559d96000-7ff559f96000 ---p 001b5000 08:01 41681428                   /lib/x86_64-linux-gnu/libc-2.15.so
-Size:               2048 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff559f96000-7ff559f9a000 r--p 001b5000 08:01 41681428                   /lib/x86_64-linux-gnu/libc-2.15.so
-Size:                 16 kB
-Rss:                  16 kB
-Pss:                  16 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        16 kB
-Referenced:           16 kB
-Anonymous:            16 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff559f9a000-7ff559f9c000 rw-p 001b9000 08:01 41681428                   /lib/x86_64-linux-gnu/libc-2.15.so
-Size:                  8 kB
-Rss:                   8 kB
-Pss:                   8 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         8 kB
-Referenced:            8 kB
-Anonymous:             8 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff559f9c000-7ff559fa1000 rw-p 00000000 00:00 0 
-Size:                 20 kB
-Rss:                  20 kB
-Pss:                  20 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        20 kB
-Referenced:           20 kB
-Anonymous:            20 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff559fa1000-7ff55a09c000 r-xp 00000000 08:01 41681674                   /lib/x86_64-linux-gnu/libm-2.15.so
-Size:               1004 kB
-Rss:                  64 kB
-Pss:                   1 kB
-Shared_Clean:         64 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           64 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a09c000-7ff55a29b000 ---p 000fb000 08:01 41681674                   /lib/x86_64-linux-gnu/libm-2.15.so
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a29b000-7ff55a29c000 r--p 000fa000 08:01 41681674                   /lib/x86_64-linux-gnu/libm-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a29c000-7ff55a29d000 rw-p 000fb000 08:01 41681674                   /lib/x86_64-linux-gnu/libm-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a29d000-7ff55a2bf000 r-xp 00000000 08:01 41681144                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
-Size:                136 kB
-Rss:                 124 kB
-Pss:                   3 kB
-Shared_Clean:        124 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:          124 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a2bf000-7ff55a4bf000 ---p 00022000 08:01 41681144                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
-Size:               2048 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a4bf000-7ff55a4c3000 r--p 00022000 08:01 41681144                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
-Size:                 16 kB
-Rss:                  16 kB
-Pss:                  16 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        16 kB
-Referenced:           16 kB
-Anonymous:            16 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a4c3000-7ff55a4c4000 rw-p 00026000 08:01 41681144                   /lib/x86_64-linux-gnu/libtinfo.so.5.9
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a4c4000-7ff55a4c6000 r-xp 00000000 08:01 41681743                   /lib/x86_64-linux-gnu/libdl-2.15.so
-Size:                  8 kB
-Rss:                   8 kB
-Pss:                   0 kB
-Shared_Clean:          8 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            8 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a4c6000-7ff55a6c6000 ---p 00002000 08:01 41681743                   /lib/x86_64-linux-gnu/libdl-2.15.so
-Size:               2048 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a6c6000-7ff55a6c7000 r--p 00002000 08:01 41681743                   /lib/x86_64-linux-gnu/libdl-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a6c7000-7ff55a6c8000 rw-p 00003000 08:01 41681743                   /lib/x86_64-linux-gnu/libdl-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a6c8000-7ff55a6cc000 r-xp 00000000 08:01 41681169                   /lib/x86_64-linux-gnu/libcap.so.2.22
-Size:                 16 kB
-Rss:                  12 kB
-Pss:                   0 kB
-Shared_Clean:         12 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           12 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a6cc000-7ff55a8cb000 ---p 00004000 08:01 41681169                   /lib/x86_64-linux-gnu/libcap.so.2.22
-Size:               2044 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a8cb000-7ff55a8cc000 r--p 00003000 08:01 41681169                   /lib/x86_64-linux-gnu/libcap.so.2.22
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a8cc000-7ff55a8cd000 rw-p 00004000 08:01 41681169                   /lib/x86_64-linux-gnu/libcap.so.2.22
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a8cd000-7ff55a8ef000 r-xp 00000000 08:01 41681675                   /lib/x86_64-linux-gnu/ld-2.15.so
-Size:                136 kB
-Rss:                 120 kB
-Pss:                   1 kB
-Shared_Clean:        120 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:          120 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55a930000-7ff55aac9000 rw-p 00000000 00:00 0 
-Size:               1636 kB
-Rss:                1636 kB
-Pss:                1636 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:      1636 kB
-Referenced:         1636 kB
-Anonymous:          1636 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aacc000-7ff55aad8000 rw-p 00000000 00:00 0 
-Size:                 48 kB
-Rss:                  48 kB
-Pss:                  48 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        48 kB
-Referenced:           48 kB
-Anonymous:            48 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aad9000-7ff55aae1000 rw-p 00000000 00:00 0 
-Size:                 32 kB
-Rss:                  32 kB
-Pss:                  32 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        32 kB
-Referenced:           32 kB
-Anonymous:            32 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aae2000-7ff55aae6000 rw-p 00000000 00:00 0 
-Size:                 16 kB
-Rss:                  16 kB
-Pss:                  16 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        16 kB
-Referenced:           16 kB
-Anonymous:            16 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aae6000-7ff55aaed000 r--s 00000000 08:01 6826621                    /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache
-Size:                 28 kB
-Rss:                  24 kB
-Pss:                   0 kB
-Shared_Clean:         24 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:           24 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aaed000-7ff55aaef000 rw-p 00000000 00:00 0 
-Size:                  8 kB
-Rss:                   8 kB
-Pss:                   8 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         8 kB
-Referenced:            8 kB
-Anonymous:             8 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aaef000-7ff55aaf0000 r--p 00022000 08:01 41681675                   /lib/x86_64-linux-gnu/ld-2.15.so
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   4 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         4 kB
-Referenced:            4 kB
-Anonymous:             4 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7ff55aaf0000-7ff55aaf2000 rw-p 00023000 08:01 41681675                   /lib/x86_64-linux-gnu/ld-2.15.so
-Size:                  8 kB
-Rss:                   8 kB
-Pss:                   8 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         8 kB
-Referenced:            8 kB
-Anonymous:             8 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7fff76a3d000-7fff76a5e000 rw-p 00000000 00:00 0                          [stack]
-Size:                136 kB
-Rss:                  84 kB
-Pss:                  84 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:        84 kB
-Referenced:           84 kB
-Anonymous:            84 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-7fff76bbb000-7fff76bbc000 r-xp 00000000 00:00 0                          [vdso]
-Size:                  4 kB
-Rss:                   4 kB
-Pss:                   0 kB
-Shared_Clean:          4 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            4 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
-ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
-Size:                  4 kB
-Rss:                   0 kB
-Pss:                   0 kB
-Shared_Clean:          0 kB
-Shared_Dirty:          0 kB
-Private_Clean:         0 kB
-Private_Dirty:         0 kB
-Referenced:            0 kB
-Anonymous:             0 kB
-AnonHugePages:         0 kB
-Swap:                  0 kB
-KernelPageSize:        4 kB
-MMUPageSize:           4 kB
-Locked:                0 kB
diff --git a/catapult/telemetry/telemetry/internal/testing/stat b/catapult/telemetry/telemetry/internal/testing/stat
deleted file mode 100644
index a2c20d1..0000000
--- a/catapult/telemetry/telemetry/internal/testing/stat
+++ /dev/null
@@ -1 +0,0 @@
-12911 (chrome) S 16468 4631 4631 0 -1 4202560 145133 0 0 0 831 71 0 0 20 0 4 0 62513410 1025978368 20508 18446744073709551615 1 1 0 0 0 0 0 67112962 1073808616 18446744073709551615 0 0 17 23 0 0 0 0 0
diff --git a/catapult/telemetry/telemetry/internal/testing/status b/catapult/telemetry/telemetry/internal/testing/status
deleted file mode 100644
index cb3d4f6..0000000
--- a/catapult/telemetry/telemetry/internal/testing/status
+++ /dev/null
@@ -1,39 +0,0 @@
-Name:	chrome
-State:	S (sleeping)
-Tgid:	12911
-Pid:	12911
-PPid:	16468
-TracerPid:	0
-Uid:	20989	20989	20989	20989
-Gid:	5000	5000	5000	5000
-FDSize:	64
-Groups:	4 20 24 25 44 46 104 128 499 5000 5001 5762 5825 66187 66609 66975 68604 74787 74990 75209 75279 76551 76613 76701 76830 77056 77281 78255 79910 79982 80665 80824 
-VmPeak:	 1025488 kB
-VmSize:	 1001932 kB
-VmLck:	       0 kB
-VmPin:	       0 kB
-VmHWM:	  141160 kB
-VmRSS:	   82032 kB
-VmData:	  660664 kB
-VmStk:	     136 kB
-VmExe:	   91844 kB
-VmLib:	   52088 kB
-VmPTE:	     852 kB
-VmSwap:	       0 kB
-Threads:	4
-SigQ:	0/514714
-SigPnd:	0000000000000000
-ShdPnd:	0000000000000000
-SigBlk:	0000000000000000
-SigIgn:	0000000004001002
-SigCgt:	00000001c00104e8
-CapInh:	0000000000000000
-CapPrm:	0000000000000000
-CapEff:	0000000000000000
-CapBnd:	ffffffffffffffff
-Cpus_allowed:	ffffffff
-Cpus_allowed_list:	0-31
-Mems_allowed:	00000000,00000003
-Mems_allowed_list:	0-1
-voluntary_ctxt_switches:	3061
-nonvoluntary_ctxt_switches:	730
diff --git a/catapult/telemetry/telemetry/internal/testing/status_nohwm b/catapult/telemetry/telemetry/internal/testing/status_nohwm
deleted file mode 100644
index 5d94aa4..0000000
--- a/catapult/telemetry/telemetry/internal/testing/status_nohwm
+++ /dev/null
@@ -1,37 +0,0 @@
-Name:	chrome
-State:	S (sleeping)
-Tgid:	12911
-Pid:	12911
-PPid:	16468
-TracerPid:	0
-Uid:	20989	20989	20989	20989
-Gid:	5000	5000	5000	5000
-FDSize:	64
-Groups:	4 20 24 25 44 46 104 128 499 5000 5001 5762 5825 66187 66609 66975 68604 74787 74990 75209 75279 76551 76613 76701 76830 77056 77281 78255 79910 79982 80665 80824 
-VmSize:	 1001932 kB
-VmLck:	       0 kB
-VmPin:	       0 kB
-VmRSS:	   82032 kB
-VmData:	  660664 kB
-VmStk:	     136 kB
-VmExe:	   91844 kB
-VmLib:	   52088 kB
-VmPTE:	     852 kB
-VmSwap:	       0 kB
-Threads:	4
-SigQ:	0/514714
-SigPnd:	0000000000000000
-ShdPnd:	0000000000000000
-SigBlk:	0000000000000000
-SigIgn:	0000000004001002
-SigCgt:	00000001c00104e8
-CapInh:	0000000000000000
-CapPrm:	0000000000000000
-CapEff:	0000000000000000
-CapBnd:	ffffffffffffffff
-Cpus_allowed:	ffffffff
-Cpus_allowed_list:	0-31
-Mems_allowed:	00000000,00000003
-Mems_allowed_list:	0-1
-voluntary_ctxt_switches:	3063
-nonvoluntary_ctxt_switches:	730
diff --git a/catapult/telemetry/telemetry/internal/testing/system_stub_test_module.py b/catapult/telemetry/telemetry/internal/testing/system_stub_test_module.py
deleted file mode 100644
index 97e3ef3..0000000
--- a/catapult/telemetry/telemetry/internal/testing/system_stub_test_module.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-class SystemStubTest(object):
-  @staticmethod
-  def TestOpen(file_path):
-    return open(file_path)
diff --git a/catapult/telemetry/telemetry/internal/testing/test_page_sets/__init__.py b/catapult/telemetry/telemetry/internal/testing/test_page_sets/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_page_sets/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/.gitignore b/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/.gitignore
deleted file mode 100644
index 2f9e5f9..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.wpr
diff --git a/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/example_domain.json b/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/example_domain.json
deleted file mode 100644
index 9628451..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/example_domain.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-    "description": "Describes the Web Page Replay archives for a user story set. Don't edit by hand! Use record_wpr for updating.", 
-    "platform_specific": true,
-    "archives": {
-        "http://www.example.com": {
-          "DEFAULT": "example_domain_001.wpr"
-        },
-        "https://www.example.com":{
-          "DEFAULT": "example_domain_001.wpr"
-        }
-    }
-}
diff --git a/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/example_domain_001.wpr.sha1 b/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/example_domain_001.wpr.sha1
deleted file mode 100644
index fdfac39..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_page_sets/data/example_domain_001.wpr.sha1
+++ /dev/null
@@ -1 +0,0 @@
-5e49b8152e40b5df427a8e73062045ddde2edcb8
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/internal/testing/test_page_sets/example_domain.py b/catapult/telemetry/telemetry/internal/testing/test_page_sets/example_domain.py
deleted file mode 100644
index c56e0ae..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_page_sets/example_domain.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import story
-from telemetry.page import page
-
-
-class ExampleDomainPageSet(story.StorySet):
-  def __init__(self):
-    super(ExampleDomainPageSet, self).__init__(
-      archive_data_file='data/example_domain.json',
-      cloud_storage_bucket=story.PUBLIC_BUCKET)
-
-    self.AddStory(page.Page('http://www.example.com', self))
-    self.AddStory(page.Page('https://www.example.com', self))
diff --git a/catapult/telemetry/telemetry/internal/testing/test_png.png b/catapult/telemetry/telemetry/internal/testing/test_png.png
deleted file mode 100644
index 3aaf03b..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_png.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/test_png_2.png b/catapult/telemetry/telemetry/internal/testing/test_png_2.png
deleted file mode 100644
index f44a4a6..0000000
--- a/catapult/telemetry/telemetry/internal/testing/test_png_2.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/ubuntu-saucy-lsb-release b/catapult/telemetry/telemetry/internal/testing/ubuntu-saucy-lsb-release
deleted file mode 100644
index 382258e..0000000
--- a/catapult/telemetry/telemetry/internal/testing/ubuntu-saucy-lsb-release
+++ /dev/null
@@ -1,4 +0,0 @@
-DISTRIB_ID=Ubuntu
-DISTRIB_RELEASE=13.10
-DISTRIB_CODENAME=saucy
-DISTRIB_DESCRIPTION="Ubuntu 13.10"
diff --git a/catapult/telemetry/telemetry/internal/testing/vid.mp4 b/catapult/telemetry/telemetry/internal/testing/vid.mp4
deleted file mode 100644
index 117ff0c..0000000
--- a/catapult/telemetry/telemetry/internal/testing/vid.mp4
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/telemetry/internal/testing/video_test.html b/catapult/telemetry/telemetry/internal/testing/video_test.html
deleted file mode 100644
index ce8529c..0000000
--- a/catapult/telemetry/telemetry/internal/testing/video_test.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<!DOCTYPE html>
-<html>
-  <body>
-    <video id="video_1" src="bear.webm" controls></video>
-    <audio id="audio_1" src="bear.webm" controls></audio>
-  </body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/webview_app/background.js b/catapult/telemetry/telemetry/internal/testing/webview_app/background.js
deleted file mode 100644
index 5f284a8..0000000
--- a/catapult/telemetry/telemetry/internal/testing/webview_app/background.js
+++ /dev/null
@@ -1,5 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-chrome.app.window.create('main.html');
diff --git a/catapult/telemetry/telemetry/internal/testing/webview_app/main.html b/catapult/telemetry/telemetry/internal/testing/webview_app/main.html
deleted file mode 100644
index 0294246..0000000
--- a/catapult/telemetry/telemetry/internal/testing/webview_app/main.html
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
-<body>
-This is the simple telemetry webapp main page with a &lt;webview&gt; element.
-<webview id="foo" src="data:text/html;charset=utf-8,<html><body><input id='test_input_id' type='text'></body></html>" style="width:640px; height:480px" autosize="on" minwidth="576" minheight="432">
-</webview>
-</body>
-</html>
diff --git a/catapult/telemetry/telemetry/internal/testing/webview_app/manifest.json b/catapult/telemetry/telemetry/internal/testing/webview_app/manifest.json
deleted file mode 100644
index b24438e..0000000
--- a/catapult/telemetry/telemetry/internal/testing/webview_app/manifest.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "description": "Simple Telemetry Test WebApp Containing <webview> Element",
-  "name": "Simple <webview> Telemetry Test WebApp",
-  "app": {
-    "background": {
-      "scripts": ["background.js"]
-    }
-  },
-  "permissions": [
-    "webview"
-  ],
-  "manifest_version": 2,
-  "version": "1.0"
-}
diff --git a/catapult/telemetry/telemetry/internal/util/__init__.py b/catapult/telemetry/telemetry/internal/util/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/internal/util/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/internal/util/atexit_with_log.py b/catapult/telemetry/telemetry/internal/util/atexit_with_log.py
deleted file mode 100644
index 6dd7967..0000000
--- a/catapult/telemetry/telemetry/internal/util/atexit_with_log.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import atexit
-import logging
-
-def _WrapFunction(function):
-  def _wrapped_function(*args, **kwargs):
-    logging.debug('Try running %s', repr(function))
-    function(*args, **kwargs)
-    logging.debug('Did run %s', repr(function))
-  return _wrapped_function
-
-def Register(function, *args, **kwargs):
-  atexit.register(_WrapFunction(function), *args, **kwargs)
diff --git a/catapult/telemetry/telemetry/internal/util/binary_manager.py b/catapult/telemetry/telemetry/internal/util/binary_manager.py
deleted file mode 100644
index 27f1b1d..0000000
--- a/catapult/telemetry/telemetry/internal/util/binary_manager.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-
-from py_utils import binary_manager
-from py_utils import dependency_util
-import dependency_manager
-from devil import devil_env
-
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry.core import platform as platform_module
-
-
-TELEMETRY_PROJECT_CONFIG = os.path.join(
-    util.GetTelemetryDir(), 'telemetry', 'internal', 'binary_dependencies.json')
-
-
-CHROME_BINARY_CONFIG = os.path.join(util.GetCatapultDir(), 'common', 'py_utils',
-                                    'py_utils', 'chrome_binaries.json')
-
-
-BATTOR_BINARY_CONFIG = os.path.join(util.GetCatapultDir(), 'common', 'battor',
-                                    'battor', 'battor_binary_dependencies.json')
-
-
-NoPathFoundError = dependency_manager.NoPathFoundError
-CloudStorageError = dependency_manager.CloudStorageError
-
-
-_binary_manager = None
-
-
-def NeedsInit():
-  return not _binary_manager
-
-
-def InitDependencyManager(client_configs):
-  global _binary_manager
-  if _binary_manager:
-    raise exceptions.InitializationError(
-        'Trying to re-initialize the binary manager with config %s'
-        % client_configs)
-  configs = []
-  if client_configs:
-    configs += client_configs
-  configs += [TELEMETRY_PROJECT_CONFIG, CHROME_BINARY_CONFIG]
-  _binary_manager = binary_manager.BinaryManager(configs)
-
-  devil_env.config.Initialize()
-
-
-def FetchPath(binary_name, arch, os_name, os_version=None):
-  """ Return a path to the appropriate executable for <binary_name>, downloading
-      from cloud storage if needed, or None if it cannot be found.
-  """
-  if _binary_manager is None:
-    raise exceptions.InitializationError(
-        'Called FetchPath with uninitialized binary manager.')
-  return _binary_manager.FetchPath(binary_name, os_name, arch, os_version)
-
-
-def LocalPath(binary_name, arch, os_name, os_version=None):
-  """ Return a local path to the given binary name, or None if an executable
-      cannot be found. Will not download the executable.
-      """
-  if _binary_manager is None:
-    raise exceptions.InitializationError(
-        'Called LocalPath with uninitialized binary manager.')
-  return _binary_manager.LocalPath(binary_name, os_name, arch, os_version)
-
-
-def FetchBinaryDependencies(platform, client_configs,
-                          fetch_reference_chrome_binary):
-  """ Fetch all binary dependenencies for the given |platform|.
-
-  Note: we don't fetch browser binaries by default because the size of the
-  binary is about 2Gb, and it requires cloud storage permission to
-  chrome-telemetry bucket.
-
-  Args:
-    platform: an instance of telemetry.core.platform
-    client_configs: A list of paths (string) to dependencies json files.
-    fetch_reference_chrome_binary: whether to fetch reference chrome binary for
-      the given platform.
-  """
-  configs = [
-      dependency_manager.BaseConfig(TELEMETRY_PROJECT_CONFIG),
-      dependency_manager.BaseConfig(BATTOR_BINARY_CONFIG)
-  ]
-  dep_manager = dependency_manager.DependencyManager(configs)
-  target_platform = '%s_%s' % (platform.GetOSName(), platform.GetArchName())
-  dep_manager.PrefetchPaths(target_platform)
-
-  host_platform = None
-  fetch_devil_deps = False
-  if platform.GetOSName() == 'android':
-    host_platform = '%s_%s' % (
-        platform_module.GetHostPlatform().GetOSName(),
-        platform_module.GetHostPlatform().GetArchName())
-    dep_manager.PrefetchPaths(host_platform)
-    # TODO(aiolos): this is a hack to prefetch the devil deps.
-    if host_platform == 'linux_x86_64':
-      fetch_devil_deps = True
-    else:
-      logging.error('Devil only supports 64 bit linux as a host platform. '
-                    'Android tests may fail.')
-
-  if fetch_reference_chrome_binary:
-    _FetchReferenceBrowserBinary(platform)
-
-  # For now, handle client config separately because the BUILD.gn & .isolate of
-  # telemetry tests in chromium src failed to include the files specified in its
-  # client config.
-  # (https://github.com/catapult-project/catapult/issues/2192)
-  # For now this is ok because the client configs usually don't include cloud
-  # storage infos.
-  # TODO(nednguyen): remove the logic of swallowing exception once the issue is
-  # fixed on Chromium side.
-  if client_configs:
-    manager = dependency_manager.DependencyManager(
-        list(dependency_manager.BaseConfig(c) for c in client_configs))
-    try:
-      manager.PrefetchPaths(target_platform)
-      if host_platform is not None:
-        manager.PrefetchPaths(host_platform)
-
-    except dependency_manager.NoPathFoundError as e:
-      logging.error('Error when trying to prefetch paths for %s: %s',
-                    target_platform, e.message)
-
-  if fetch_devil_deps:
-    devil_env.config.Initialize()
-    devil_env.config.PrefetchPaths(arch=platform.GetArchName())
-    devil_env.config.PrefetchPaths()
-
-
-def _FetchReferenceBrowserBinary(platform):
-  os_name = platform.GetOSName()
-  arch_name = platform.GetArchName()
-  manager = binary_manager.BinaryManager(
-             [CHROME_BINARY_CONFIG])
-  if os_name == 'android':
-    os_version = dependency_util.GetChromeApkOsVersion(
-        platform.GetOSVersionName())
-    manager.FetchPath(
-        'chrome_stable', os_name, arch_name, os_version)
-  else:
-    manager.FetchPath(
-        'chrome_stable', os_name, arch_name)
diff --git a/catapult/telemetry/telemetry/internal/util/binary_manager_unittest.py b/catapult/telemetry/telemetry/internal/util/binary_manager_unittest.py
deleted file mode 100644
index acf63b4..0000000
--- a/catapult/telemetry/telemetry/internal/util/binary_manager_unittest.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.core import exceptions
-from telemetry.internal.util import binary_manager
-import mock
-
-
-class BinaryManagerTest(unittest.TestCase):
-  def setUp(self):
-    # We need to preserve the real initialized dependecny_manager.
-    self.actual_binary_manager = binary_manager._binary_manager
-    binary_manager._binary_manager = None
-
-  def tearDown(self):
-    binary_manager._binary_manager = self.actual_binary_manager
-
-  def testReinitialization(self):
-    binary_manager.InitDependencyManager(None)
-    self.assertRaises(exceptions.InitializationError,
-                      binary_manager.InitDependencyManager, None)
-
-  @mock.patch('py_utils.binary_manager.BinaryManager')
-  def testFetchPathInitialized(self, binary_manager_mock):
-    expected = [mock.call.binary_manager.BinaryManager(
-                   ['base_config_object']),
-                mock.call.binary_manager.BinaryManager().FetchPath(
-                    'dep', 'plat_arch')]
-    binary_manager.InitDependencyManager(None)
-    binary_manager.FetchPath('dep', 'plat', 'arch')
-    binary_manager_mock.assert_call_args(expected)
-
-  def testFetchPathUninitialized(self):
-    self.assertRaises(exceptions.InitializationError,
-                      binary_manager.FetchPath, 'dep', 'plat', 'arch')
-
-  @mock.patch('py_utils.binary_manager.BinaryManager')
-  def testLocalPathInitialized(self, binary_manager_mock):
-    expected = [mock.call.binary_manager.BinaryManager(
-                   ['base_config_object']),
-                mock.call.binary_manager.BinaryManager().LocalPath(
-                    'dep', 'plat_arch')]
-    binary_manager.InitDependencyManager(None)
-    binary_manager.LocalPath('dep', 'plat', 'arch')
-    binary_manager_mock.assert_call_args(expected)
-
-  def testLocalPathUninitialized(self):
-    self.assertRaises(exceptions.InitializationError,
-                      binary_manager.LocalPath, 'dep', 'plat', 'arch')
diff --git a/catapult/telemetry/telemetry/internal/util/camel_case.py b/catapult/telemetry/telemetry/internal/util/camel_case.py
deleted file mode 100644
index 9a76890..0000000
--- a/catapult/telemetry/telemetry/internal/util/camel_case.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-
-def ToUnderscore(obj):
-  """Converts a string, list, or dict from camelCase to lower_with_underscores.
-
-  Descends recursively into lists and dicts, converting all dict keys.
-  Returns a newly allocated object of the same structure as the input.
-  """
-  if isinstance(obj, basestring):
-    return re.sub('(?!^)([A-Z]+)', r'_\1', obj).lower()
-
-  elif isinstance(obj, list):
-    return [ToUnderscore(item) for item in obj]
-
-  elif isinstance(obj, dict):
-    output = {}
-    for k, v in obj.iteritems():
-      if isinstance(v, list) or isinstance(v, dict):
-        output[ToUnderscore(k)] = ToUnderscore(v)
-      else:
-        output[ToUnderscore(k)] = v
-    return output
-
-  else:
-    return obj
diff --git a/catapult/telemetry/telemetry/internal/util/camel_case_unittest.py b/catapult/telemetry/telemetry/internal/util/camel_case_unittest.py
deleted file mode 100644
index 9ba4d3a..0000000
--- a/catapult/telemetry/telemetry/internal/util/camel_case_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.util import camel_case
-
-
-class CamelCaseTest(unittest.TestCase):
-
-  def testString(self):
-    self.assertEqual(camel_case.ToUnderscore('camelCase'), 'camel_case')
-    self.assertEqual(camel_case.ToUnderscore('CamelCase'), 'camel_case')
-    self.assertEqual(camel_case.ToUnderscore('Camel2Case'), 'camel2_case')
-    self.assertEqual(camel_case.ToUnderscore('Camel2Case2'), 'camel2_case2')
-    self.assertEqual(camel_case.ToUnderscore('2012Q3'), '2012_q3')
-
-  def testList(self):
-    camel_case_list = ['CamelCase', ['NestedList']]
-    underscore_list = ['camel_case', ['nested_list']]
-    self.assertEqual(camel_case.ToUnderscore(camel_case_list), underscore_list)
-
-  def testDict(self):
-    camel_case_dict = {
-        'gpu': {
-            'vendorId': 1000,
-            'deviceId': 2000,
-            'vendorString': 'aString',
-            'deviceString': 'bString'},
-        'secondaryGpus': [
-            {'vendorId': 3000, 'deviceId': 4000,
-             'vendorString': 'k', 'deviceString': 'l'}
-        ]
-    }
-    underscore_dict = {
-        'gpu': {
-            'vendor_id': 1000,
-            'device_id': 2000,
-            'vendor_string': 'aString',
-            'device_string': 'bString'},
-        'secondary_gpus': [
-            {'vendor_id': 3000, 'device_id': 4000,
-             'vendor_string': 'k', 'device_string': 'l'}
-        ]
-    }
-    self.assertEqual(camel_case.ToUnderscore(camel_case_dict), underscore_dict)
-
-  def testOther(self):
-    self.assertEqual(camel_case.ToUnderscore(self), self)
diff --git a/catapult/telemetry/telemetry/internal/util/classes.py b/catapult/telemetry/telemetry/internal/util/classes.py
deleted file mode 100644
index 0f90a06..0000000
--- a/catapult/telemetry/telemetry/internal/util/classes.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import inspect
-
-
-def IsDirectlyConstructable(cls):
-  """Returns True if instance of |cls| can be construct without arguments."""
-  assert inspect.isclass(cls)
-  if not hasattr(cls, '__init__'):
-    # Case |class A: pass|.
-    return True
-  if cls.__init__ is object.__init__:
-    # Case |class A(object): pass|.
-    return True
-  # Case |class (object):| with |__init__| other than |object.__init__|.
-  args, _, _, defaults = inspect.getargspec(cls.__init__)
-  if defaults is None:
-    defaults = ()
-  # Return true if |self| is only arg without a default.
-  return len(args) == len(defaults) + 1
diff --git a/catapult/telemetry/telemetry/internal/util/classes_unittest.py b/catapult/telemetry/telemetry/internal/util/classes_unittest.py
deleted file mode 100644
index dc7ac51..0000000
--- a/catapult/telemetry/telemetry/internal/util/classes_unittest.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.util import classes
-
-
-class ClassWithoutInitDefOne: # pylint: disable=old-style-class, no-init
-  pass
-
-
-class ClassWithoutInitDefTwo(object):
-  pass
-
-
-class ClassWhoseInitOnlyHasSelf(object):
-  def __init__(self):
-    pass
-
-
-class ClassWhoseInitWithDefaultArguments(object):
-  def __init__(self, dog=1, cat=None, cow=None, fud='a'):
-    pass
-
-
-class ClassWhoseInitWithDefaultArgumentsAndNonDefaultArguments(object):
-  def __init__(self, x, dog=1, cat=None, fish=None, fud='a'):
-    pass
-
-
-class ClassesUnitTest(unittest.TestCase):
-
-  def testIsDirectlyConstructableReturnsTrue(self):
-    self.assertTrue(classes.IsDirectlyConstructable(ClassWithoutInitDefOne))
-    self.assertTrue(classes.IsDirectlyConstructable(ClassWithoutInitDefTwo))
-    self.assertTrue(classes.IsDirectlyConstructable(ClassWhoseInitOnlyHasSelf))
-    self.assertTrue(
-        classes.IsDirectlyConstructable(ClassWhoseInitWithDefaultArguments))
-
-  def testIsDirectlyConstructableReturnsFalse(self):
-    self.assertFalse(
-        classes.IsDirectlyConstructable(
-            ClassWhoseInitWithDefaultArgumentsAndNonDefaultArguments))
diff --git a/catapult/telemetry/telemetry/internal/util/command_line.py b/catapult/telemetry/telemetry/internal/util/command_line.py
deleted file mode 100644
index 2a0d603..0000000
--- a/catapult/telemetry/telemetry/internal/util/command_line.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import optparse
-
-from telemetry.internal.util import camel_case
-
-
-class ArgumentHandlerMixIn(object):
-  """A structured way to handle command-line arguments.
-
-  In AddCommandLineArgs, add command-line arguments.
-  In ProcessCommandLineArgs, validate them and store them in a private class
-  variable. This way, each class encapsulates its own arguments, without needing
-  to pass an arguments object around everywhere.
-  """
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    """Override to accept custom command-line arguments."""
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    """Override to process command-line arguments.
-
-    We pass in parser so we can call parser.error()."""
-
-
-class Command(ArgumentHandlerMixIn):
-  """An abstraction for things that run from the command-line."""
-
-  @classmethod
-  def Name(cls):
-    return camel_case.ToUnderscore(cls.__name__)
-
-  @classmethod
-  def Description(cls):
-    if cls.__doc__:
-      return cls.__doc__.splitlines()[0]
-    else:
-      return ''
-
-  def Run(self, args):
-    raise NotImplementedError()
-
-  @classmethod
-  def main(cls, args=None):
-    """Main method to run this command as a standalone script."""
-    parser = argparse.ArgumentParser()
-    cls.AddCommandLineArgs(parser)
-    args = parser.parse_args(args=args)
-    cls.ProcessCommandLineArgs(parser, args)
-    return min(cls().Run(args), 255)
-
-
-# TODO: Convert everything to argparse.
-class OptparseCommand(Command):
-  usage = ''
-
-  @classmethod
-  def CreateParser(cls):
-    return optparse.OptionParser('%%prog %s %s' % (cls.Name(), cls.usage),
-                                 description=cls.Description())
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser, environment):
-    # pylint: disable=arguments-differ
-    pass
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args, environment):
-    # pylint: disable=arguments-differ
-    pass
-
-  def Run(self, args):
-    raise NotImplementedError()
-
-  @classmethod
-  def main(cls, args=None):
-    """Main method to run this command as a standalone script."""
-    parser = cls.CreateParser()
-    cls.AddCommandLineArgs(parser, None)
-    options, args = parser.parse_args(args=args)
-    options.positional_args = args
-    cls.ProcessCommandLineArgs(parser, options, None)
-    return min(cls().Run(options), 255)
-
-
-class SubcommandCommand(Command):
-  """Combines Commands into one big command with sub-commands.
-
-  E.g. "svn checkout", "svn update", and "svn commit" are separate sub-commands.
-
-  Example usage:
-    class MyCommand(command_line.SubcommandCommand):
-      commands = (Help, List, Run)
-
-    if __name__ == '__main__':
-      sys.exit(MyCommand.main())
-  """
-
-  commands = ()
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    subparsers = parser.add_subparsers()
-
-    for command in cls.commands:
-      subparser = subparsers.add_parser(
-          command.Name(), help=command.Description())
-      subparser.set_defaults(command=command)
-      command.AddCommandLineArgs(subparser)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    args.command.ProcessCommandLineArgs(parser, args)
-
-  def Run(self, args):
-    return args.command().Run(args)
diff --git a/catapult/telemetry/telemetry/internal/util/exception_formatter.py b/catapult/telemetry/telemetry/internal/util/exception_formatter.py
deleted file mode 100644
index fe036c8..0000000
--- a/catapult/telemetry/telemetry/internal/util/exception_formatter.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Print prettier and more detailed exceptions."""
-
-import logging
-import math
-import os
-import sys
-import traceback
-
-from telemetry.core import exceptions
-
-
-def PrintFormattedException(exception_class=None, exception=None, tb=None,
-                            msg=None):
-  logging.info('Try printing formatted exception: %s %s %s' %
-               (exception_class, exception, tb))
-  assert bool(exception_class) == bool(exception) == bool(tb), (
-      'Must specify all or none of exception_class, exception, and tb')
-
-  if not exception_class:
-    exception_class, exception, tb = sys.exc_info()
-
-  if exception_class == exceptions.IntentionalException:
-    return
-
-  def _GetFinalFrame(tb_level):
-    while tb_level.tb_next:
-      tb_level = tb_level.tb_next
-    return tb_level.tb_frame
-
-  processed_tb = traceback.extract_tb(tb)
-  frame = _GetFinalFrame(tb)
-  exception_list = traceback.format_exception_only(exception_class, exception)
-  exception_string = '\n'.join(l.strip() for l in exception_list)
-
-  if msg:
-    print >> sys.stderr
-    print >> sys.stderr, msg
-
-  _PrintFormattedTrace(processed_tb, frame, exception_string)
-
-
-def PrintFormattedFrame(frame, exception_string=None):
-  _PrintFormattedTrace(traceback.extract_stack(frame), frame, exception_string)
-
-
-def _PrintFormattedTrace(processed_tb, frame, exception_string=None):
-  """Prints an Exception in a more useful format than the default.
-
-  TODO(tonyg): Consider further enhancements. For instance:
-    - Report stacks to maintainers like depot_tools does.
-    - Add a debug flag to automatically start pdb upon exception.
-  """
-  print >> sys.stderr
-
-  # Format the traceback.
-  print >> sys.stderr, 'Traceback (most recent call last):'
-  for filename, line, function, text in processed_tb:
-    filename = os.path.abspath(filename)
-    print >> sys.stderr, '  %s at %s:%d' % (function, filename, line)
-    print >> sys.stderr, '    %s' % text
-
-  # Format the exception.
-  if exception_string:
-    print >> sys.stderr, exception_string
-
-  # Format the locals.
-  local_variables = [(variable, value) for variable, value in
-                     frame.f_locals.iteritems() if variable != 'self']
-  print >> sys.stderr
-  print >> sys.stderr, 'Locals:'
-  if local_variables:
-    longest_variable = max(len(v) for v, _ in local_variables)
-    for variable, value in sorted(local_variables):
-      value = repr(value)
-      possibly_truncated_value = _AbbreviateMiddleOfString(value, ' ... ', 1024)
-      truncation_indication = ''
-      if len(possibly_truncated_value) != len(value):
-        truncation_indication = ' (truncated)'
-      print >> sys.stderr, '  %s: %s%s' % (variable.ljust(longest_variable + 1),
-                                           possibly_truncated_value,
-                                           truncation_indication)
-  else:
-    print >> sys.stderr, '  No locals!'
-
-  print >> sys.stderr
-  sys.stderr.flush()
-
-
-def _AbbreviateMiddleOfString(target, middle, max_length):
-  if max_length < 0:
-    raise ValueError('Must provide positive max_length')
-  if len(middle) > max_length:
-    raise ValueError('middle must not be greater than max_length')
-
-  if len(target) <= max_length:
-    return target
-  half_length = (max_length - len(middle)) / 2.
-  return (target[:int(math.floor(half_length))] + middle +
-          target[-int(math.ceil(half_length)):])
diff --git a/catapult/telemetry/telemetry/internal/util/external_modules.py b/catapult/telemetry/telemetry/internal/util/external_modules.py
deleted file mode 100644
index 92faf59..0000000
--- a/catapult/telemetry/telemetry/internal/util/external_modules.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import importlib
-
-from distutils import version
-
-MODULES = {
-  'cv2': (version.StrictVersion('2.4.8'), version.StrictVersion('3.0.0')),
-  'numpy': (version.StrictVersion('1.6.1'), None),
-  'psutil': (version.StrictVersion('0.5.0'), None),
-}
-
-def ImportRequiredModule(module):
-  """Tries to import the desired module.
-
-  Returns:
-    The module on success, raises error on failure.
-  Raises:
-    ImportError: The import failed."""
-  versions = MODULES.get(module)
-  if versions is None:
-    raise NotImplementedError('Please teach telemetry about module %s.' %
-                              module)
-  min_version, max_version = versions
-
-  module = importlib.import_module(module)
-  try:
-    if ((min_version is not None and
-            version.StrictVersion(module.__version__) < min_version) or
-        (max_version is not None and
-            version.StrictVersion(module.__version__) >= max_version)):
-      raise ImportError(('Incorrect {0} version found, expected {1} <= version '
-                         '< {2}, found version {3}').format(
-          module, min_version, max_version, module.__version__))
-  except ValueError as e:
-    # This error is raised when a module returns and incorrectly formatted
-    # version string. ex. '$build 1456a'
-    if 'invalid version number' in str(e):
-      raise ImportError(('Incorrectly formatted {0} version found, expected '
-                         '{1} <= version < {2}, found version {3}').format(
-          module, min_version, max_version, module.__version__))
-    else:
-      raise
-  return module
-
-def ImportOptionalModule(module):
-  """Tries to import the desired module.
-
-  Returns:
-    The module if successful, None if not."""
-  try:
-    return ImportRequiredModule(module)
-  except ImportError:
-    return None
diff --git a/catapult/telemetry/telemetry/internal/util/file_handle.py b/catapult/telemetry/telemetry/internal/util/file_handle.py
deleted file mode 100644
index 8133b0d..0000000
--- a/catapult/telemetry/telemetry/internal/util/file_handle.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-
-_next_file_id = 0
-
-
-class FileHandle(object):
-  def __init__(self, temp_file=None, absolute_path=None):
-    """Constructs a FileHandle object.
-
-    This constructor should not be used by the user; rather it is preferred to
-    use the module-level GetAbsPath and FromTempFile functions.
-
-    Args:
-      temp_file: An instance of a temporary file object.
-      absolute_path: A path; should not be passed if tempfile is and vice-versa.
-      extension: A string that specifies the file extension. It must starts with
-        ".".
-    """
-    # Exactly one of absolute_path or temp_file must be specified.
-    assert (absolute_path is None) != (temp_file is None)
-    self._temp_file = temp_file
-    self._absolute_path = absolute_path
-
-    global _next_file_id
-    self._id = _next_file_id
-    _next_file_id += 1
-
-  @property
-  def id(self):
-    return self._id
-
-  @property
-  def extension(self):
-    return os.path.splitext(self.GetAbsPath())[1]
-
-  def GetAbsPath(self):
-    """Returns the path to the pointed-to file relative to the given start path.
-
-    Args:
-      start: A string representing a starting path.
-    Returns:
-      A string giving the relative path from path to this file.
-    """
-    if self._temp_file:
-      self._temp_file.close()
-      return self._temp_file.name
-    else:
-      return self._absolute_path
-
-
-def FromTempFile(temp_file):
-  """Constructs a FileHandle pointing to a temporary file.
-
-  Returns:
-    A FileHandle referring to a named temporary file.
-  """
-  return FileHandle(temp_file)
-
-
-def FromFilePath(path):
-  """Constructs a FileHandle from an absolute file path.
-
-  Args:
-    path: A string giving the absolute path to a file.
-  Returns:
-    A FileHandle referring to the file at the specified path.
-  """
-  return FileHandle(None, os.path.abspath(path))
diff --git a/catapult/telemetry/telemetry/internal/util/file_handle_unittest.py b/catapult/telemetry/telemetry/internal/util/file_handle_unittest.py
deleted file mode 100644
index 28c4265..0000000
--- a/catapult/telemetry/telemetry/internal/util/file_handle_unittest.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import tempfile
-import unittest
-
-from telemetry.internal.util import file_handle
-
-
-class FileHandleUnittest(unittest.TestCase):
-
-  def setUp(self):
-    self.temp_file_txt = tempfile.NamedTemporaryFile(
-        suffix='.txt', delete=False)
-    self.abs_path_html = tempfile.NamedTemporaryFile(
-        suffix='.html', delete=False).name
-
-  def tearDown(self):
-    os.remove(self.abs_path_html)
-
-  def testCreatingFileHandle(self):
-    fh1 = file_handle.FromTempFile(self.temp_file_txt)
-    self.assertEquals(fh1.extension, '.txt')
-
-    fh2 = file_handle.FromFilePath(self.abs_path_html)
-    self.assertEquals(fh2.extension, '.html')
-    self.assertNotEquals(fh1.id, fh2.id)
diff --git a/catapult/telemetry/telemetry/internal/util/global_hooks.py b/catapult/telemetry/telemetry/internal/util/global_hooks.py
deleted file mode 100644
index d343575..0000000
--- a/catapult/telemetry/telemetry/internal/util/global_hooks.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Hooks that apply globally to all scripts that import or use Telemetry."""
-import signal
-import sys
-
-from telemetry.internal.util import exception_formatter
-
-
-def InstallHooks():
-  InstallUnhandledExceptionFormatter()
-  InstallStackDumpOnSigusr1()
-  InstallTerminationHook()
-
-def InstallUnhandledExceptionFormatter():
-  """Print prettier exceptions that also contain the stack frame's locals."""
-  sys.excepthook = exception_formatter.PrintFormattedException
-
-
-def InstallStackDumpOnSigusr1():
-  """Catch SIGUSR1 and print a stack trace."""
-  # Windows doesn't define SIGUSR1.
-  if not hasattr(signal, 'SIGUSR1'):
-    return
-
-  def PrintDiagnostics(_, stack_frame):
-    exception_string = 'SIGUSR1 received, printed stack trace'
-    exception_formatter.PrintFormattedFrame(stack_frame, exception_string)
-  signal.signal(signal.SIGUSR1, PrintDiagnostics)
-
-
-def InstallTerminationHook():
-  """Catch SIGTERM, print a stack trace, and exit."""
-  def PrintStackAndExit(sig, stack_frame):
-    exception_string = 'Received signal %s, exiting' % sig
-    exception_formatter.PrintFormattedFrame(stack_frame, exception_string)
-    sys.exit(-1)
-  signal.signal(signal.SIGTERM, PrintStackAndExit)
diff --git a/catapult/telemetry/telemetry/internal/util/path.py b/catapult/telemetry/telemetry/internal/util/path.py
deleted file mode 100644
index 80379df..0000000
--- a/catapult/telemetry/telemetry/internal/util/path.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import glob
-import os
-
-from telemetry.core import util
-import py_utils as catapult_util
-
-# TODO(aiolos): Move these functions to catapult_util or here.
-GetBaseDir = util.GetBaseDir
-GetTelemetryDir = util.GetTelemetryDir
-GetUnittestDataDir = util.GetUnittestDataDir
-GetChromiumSrcDir = util.GetChromiumSrcDir
-GetBuildDirectories = util.GetBuildDirectories
-
-IsExecutable = catapult_util.IsExecutable
-
-
-def _HasWildcardCharacters(input_string):
-  # Could make this more precise.
-  return '*' in input_string or '+' in input_string
-
-
-def FindInstalledWindowsApplication(application_path):
-  """Search common Windows installation directories for an application.
-
-  Args:
-    application_path: Path to application relative from installation location.
-  Returns:
-    A string representing the full path, or None if not found.
-  """
-  search_paths = [os.getenv('PROGRAMFILES(X86)'),
-                  os.getenv('PROGRAMFILES'),
-                  os.getenv('LOCALAPPDATA')]
-  search_paths += os.getenv('PATH', '').split(os.pathsep)
-  for search_path in search_paths:
-    if not search_path:
-      continue
-    path = os.path.join(search_path, application_path)
-    if _HasWildcardCharacters(path):
-      paths = glob.glob(path)
-    else:
-      paths = [path]
-    for p in paths:
-      if IsExecutable(p):
-        return p
-  return None
-
-
-def IsSubpath(subpath, superpath):
-  """Returns True iff subpath is or is in superpath."""
-  subpath = os.path.realpath(subpath)
-  superpath = os.path.realpath(superpath)
-
-  while len(subpath) >= len(superpath):
-    if subpath == superpath:
-      return True
-    subpath = os.path.split(subpath)[0]
-  return False
-
-
-def ListFiles(base_directory, should_include_dir=lambda _: True,
-              should_include_file=lambda _: True):
-  matching_files = []
-  for root, dirs, files in os.walk(base_directory):
-    dirs[:] = [dir_name for dir_name in dirs if should_include_dir(dir_name)]
-    matching_files += [os.path.join(root, file_name)
-                       for file_name in files if should_include_file(file_name)]
-  return sorted(matching_files)
diff --git a/catapult/telemetry/telemetry/internal/util/path_set.py b/catapult/telemetry/telemetry/internal/util/path_set.py
deleted file mode 100644
index 0b46783..0000000
--- a/catapult/telemetry/telemetry/internal/util/path_set.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import os
-
-
-class PathSet(collections.MutableSet):
-  """A set of paths.
-
-  All mutation methods can take both directories or individual files, but the
-  iterator yields the individual files. All paths are automatically normalized.
-  """
-  def __init__(self, iterable=None):
-    self._paths = set()
-    if iterable:
-      self |= iterable
-
-  def __contains__(self, path):
-    return os.path.realpath(path) in self._paths
-
-  def __iter__(self):
-    return iter(self._paths)
-
-  def __len__(self):
-    return len(self._paths)
-
-  def add(self, path):
-    path = os.path.realpath(path)
-    if os.path.isfile(path):
-      self._paths.add(path)
-    for root, _, files in os.walk(path):
-      for basename in files:
-        file_path = os.path.join(root, basename)
-        if os.path.isfile(file_path):
-          self._paths.add(file_path)
-
-  def discard(self, path):
-    path = os.path.realpath(path)
-    self._paths.discard(path)
-    for root, _, files in os.walk(path):
-      for basename in files:
-        self._paths.discard(os.path.join(root, basename))
diff --git a/catapult/telemetry/telemetry/internal/util/path_set_unittest.py b/catapult/telemetry/telemetry/internal/util/path_set_unittest.py
deleted file mode 100755
index 6cc0ec1..0000000
--- a/catapult/telemetry/telemetry/internal/util/path_set_unittest.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry.internal.util import path_set
-
-
-class PathSetTest(unittest.TestCase):
-  def testCreate(self):
-    ps = path_set.PathSet()
-    self.assertEqual(len(ps), 0)  # Check __len__.
-    self.assertFalse(__file__ in ps)
-    for _ in ps:  # Check __iter__.
-      self.fail('New set is not empty.')
-
-    ps = path_set.PathSet([__file__])
-    self.assertEqual(len(ps), 1)
-    self.assertTrue(__file__ in ps)
-    self.assertEqual(ps.pop(), os.path.realpath(__file__))
-
-  def testAdd(self):
-    ps = path_set.PathSet()
-    ps.add(__file__)
-    self.assertEqual(len(ps), 1)
-    self.assertTrue(__file__ in ps)
-    self.assertEqual(ps.pop(), os.path.realpath(__file__))
-
-  def testDiscard(self):
-    ps = path_set.PathSet([__file__])
-    ps.discard(__file__)
-    self.assertEqual(len(ps), 0)
-    self.assertFalse(__file__ in ps)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/telemetry/internal/util/path_unittest.py b/catapult/telemetry/telemetry/internal/util/path_unittest.py
deleted file mode 100644
index e9a0ee0..0000000
--- a/catapult/telemetry/telemetry/internal/util/path_unittest.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-import unittest
-
-from telemetry import decorators
-from telemetry.internal.util import path
-
-
-class PathTest(unittest.TestCase):
-  def testIsExecutable(self):
-    self.assertFalse(path.IsExecutable('nonexistent_file'))
-    self.assertTrue(path.IsExecutable(sys.executable))
-
-  @decorators.Enabled('win')
-  def testFindInstalledWindowsApplication(self):
-    self.assertTrue(path.FindInstalledWindowsApplication(os.path.join(
-        'Internet Explorer', 'iexplore.exe')))
-
-  @decorators.Enabled('win')
-  def testFindInstalledWindowsApplicationWithWildcards(self):
-    self.assertTrue(path.FindInstalledWindowsApplication(os.path.join(
-        '*', 'iexplore.exe')))
diff --git a/catapult/telemetry/telemetry/internal/util/ps_util.py b/catapult/telemetry/telemetry/internal/util/ps_util.py
deleted file mode 100644
index 6cae814..0000000
--- a/catapult/telemetry/telemetry/internal/util/ps_util.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.util import atexit_with_log
-import inspect
-import logging
-import os
-
-from collections import defaultdict
-
-
-def GetChildPids(processes, pid):
-  """Returns all child processes of |pid| from the given |processes| list.
-
-  Args:
-    processes: A tuple of (pid, ppid, state) as generated by ps.
-    pid: The pid for which to get children.
-
-  Returns:
-    A list of child pids.
-  """
-  child_dict = defaultdict(list)
-  for curr_pid, curr_ppid, state in processes:
-    if 'Z' in state:
-      continue  # Ignore zombie processes
-    child_dict[int(curr_ppid)].append(int(curr_pid))
-  queue = [pid]
-  child_ids = []
-  while queue:
-    parent = queue.pop()
-    if parent in child_dict:
-      children = child_dict[parent]
-      queue.extend(children)
-      child_ids.extend(children)
-  return child_ids
-
-
-def GetPsOutputWithPlatformBackend(platform_backend, columns, pid):
-  """Returns output of the 'ps' command as a list of lines.
-
-  Args:
-    platform_backend: The platform backend (LinuxBasedPlatformBackend or
-        PosixPlatformBackend).
-    columns: A list of require columns, e.g., ['pid', 'pss'].
-    pid: If not None, returns only the information of the process with the pid.
-  """
-  args = ['ps']
-  args.extend(['-p', str(pid)] if pid != None else ['-e'])
-  for c in columns:
-    args.extend(['-o', c + '='])
-  return platform_backend.RunCommand(args).splitlines()
-
-
-def EnableListingStrayProcessesUponExitHook():
-  def _ListAllSubprocesses():
-    try:
-      import psutil
-    except ImportError:
-      logging.warning(
-          'psutil is not installed on the system. Not listing possible '
-          'leaked processes. To install psutil, see: '
-          'https://pypi.python.org/pypi/psutil')
-      return
-    telemetry_pid = os.getpid()
-    parent = psutil.Process(telemetry_pid)
-    if hasattr(parent, 'children'):
-      children = parent.children(recursive=True)
-    else:  # Some old version of psutil use get_children instead children.
-      children = parent.get_children()
-    if children:
-      leak_processes_info = []
-      for p in children:
-        if inspect.ismethod(p.name):
-          name = p.name()
-        else:  # Process.name is a property in old versions of psutil.
-          name = p.name
-        process_info = '%s (%s)' % (name, p.pid)
-        try:
-          if inspect.ismethod(p.cmdline):
-            cmdline = p.cmdline()
-          else:
-            cmdline = p.cmdline
-          process_info += ' - %s' % cmdline
-        except Exception as e:
-          logging.warning(str(e))
-        leak_processes_info.append(process_info)
-      logging.warning('Telemetry leaks these processes: %s',
-                      ', '.join(leak_processes_info))
-
-  atexit_with_log.Register(_ListAllSubprocesses)
diff --git a/catapult/telemetry/telemetry/internal/util/ts_proxy_server.py b/catapult/telemetry/telemetry/internal/util/ts_proxy_server.py
deleted file mode 100644
index c4c5cd3..0000000
--- a/catapult/telemetry/telemetry/internal/util/ts_proxy_server.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Start and stop tsproxy."""
-
-import logging
-import os
-import re
-import subprocess
-import sys
-
-from telemetry.core import util
-from telemetry.internal.util import atexit_with_log
-
-import py_utils
-
-
-_TSPROXY_PATH = os.path.join(
-    util.GetTelemetryThirdPartyDir(), 'tsproxy', 'tsproxy.py')
-
-
-def ParseTsProxyPortFromOutput(output_line):
-  port_re = re.compile(
-      r'Started Socks5 proxy server on '
-      r'(?P<host>[^:]*):'
-      r'(?P<port>\d+)')
-  m = port_re.match(output_line.strip())
-  if m:
-    return int(m.group('port'))
-
-
-class TsProxyServer(object):
-  """Start and Stop Tsproxy.
-
-  TsProxy provides basic latency, download and upload traffic shaping. This
-  class provides a programming API to the tsproxy script in
-  telemetry/third_party/tsproxy/tsproxy.py
-  """
-
-  def __init__(self, host_ip=None, http_port=None, https_port=None):
-    """Initialize TsProxyServer.
-    """
-    self._proc = None
-    self._port = None
-    self._is_running = False
-    self._host_ip = host_ip
-    assert bool(http_port) == bool(https_port)
-    self._http_port = http_port
-    self._https_port = https_port
-
-  @property
-  def port(self):
-    return self._port
-
-  def StartServer(self, timeout=10):
-    """Start TsProxy server and verify that it started.
-    """
-    cmd_line = [sys.executable, _TSPROXY_PATH]
-    cmd_line.extend([
-        '--port=0'])  # Use port 0 so tsproxy picks a random available port.
-    if self._host_ip:
-      cmd_line.append('--desthost=%s' % self._host_ip)
-    if self._http_port:
-      cmd_line.append(
-        '--mapports=443:%s,*:%s' % (self._https_port, self._http_port))
-    logging.info('Tsproxy commandline: %r' % cmd_line)
-    self._proc = subprocess.Popen(
-        cmd_line, stdout=subprocess.PIPE, stdin=subprocess.PIPE,
-        stderr=subprocess.PIPE, bufsize=1)
-    atexit_with_log.Register(self.StopServer)
-    try:
-      py_utils.WaitFor(self._IsStarted, timeout)
-      logging.info('TsProxy port: %s', self._port)
-      self._is_running = True
-    except py_utils.TimeoutException:
-      err = self.StopServer()
-      raise RuntimeError(
-          'Error starting tsproxy: %s' % err)
-
-  def _IsStarted(self):
-    assert not self._is_running
-    assert self._proc
-    if self._proc.poll() is not None:
-      return False
-    self._proc.stdout.flush()
-    self._port = ParseTsProxyPortFromOutput(
-          output_line=self._proc.stdout.readline())
-    return self._port != None
-
-
-  def _IssueCommand(self, command_string, timeout):
-    logging.info('Issuing command to ts_proxy_server: %s', command_string)
-    command_output = []
-    self._proc.stdin.write('%s\n' % command_string)
-    self._proc.stdin.flush()
-    self._proc.stdout.flush()
-    def CommandStatusIsRead():
-      command_output.append(self._proc.stdout.readline().strip())
-      return (
-          command_output[-1] == 'OK' or command_output[-1] == 'ERROR')
-    py_utils.WaitFor(CommandStatusIsRead, timeout)
-    if not 'OK' in command_output:
-      raise RuntimeError('Failed to execute command %s:\n%s' %
-                         (repr(command_string), '\n'.join(command_output)))
-
-
-  def UpdateOutboundPorts(self, http_port, https_port, timeout=5):
-    assert http_port and https_port
-    assert http_port != https_port
-    assert isinstance(http_port, int) and isinstance(https_port, int)
-    assert 1 <= http_port <= 65535
-    assert 1 <= https_port <= 65535
-    self._IssueCommand('set mapports 443:%i,*:%i' % (https_port, http_port),
-                       timeout)
-
-  def UpdateTrafficSettings(self, round_trip_latency_ms=0,
-      download_bandwidth_kbps=0, upload_bandwidth_kbps=0, timeout=5):
-    self._IssueCommand('set rtt %s' % round_trip_latency_ms, timeout)
-    self._IssueCommand('set inkbps %s' % download_bandwidth_kbps, timeout)
-    self._IssueCommand('set outkbps %s' % upload_bandwidth_kbps, timeout)
-
-  def StopServer(self):
-    """Stop TsProxy Server."""
-    if not self._is_running:
-      logging.debug('Attempting to stop TsProxy server that is not running.')
-      return
-    if self._proc:
-      self._proc.terminate()
-      self._proc.wait()
-    err = self._proc.stderr.read()
-    self._proc = None
-    self._port = None
-    self._is_running = False
-    return err
-
-  def __enter__(self):
-    """Add support for with-statement."""
-    self.StartServer()
-    return self
-
-  def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
-    """Add support for with-statement."""
-    self.StopServer()
diff --git a/catapult/telemetry/telemetry/internal/util/ts_proxy_server_unittest.py b/catapult/telemetry/telemetry/internal/util/ts_proxy_server_unittest.py
deleted file mode 100644
index feb1824..0000000
--- a/catapult/telemetry/telemetry/internal/util/ts_proxy_server_unittest.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.util import ts_proxy_server
-
-class TsProxyServerTest(unittest.TestCase):
-  def testParseTsProxyPort(self):
-    self.assertEquals(
-      ts_proxy_server.ParseTsProxyPortFromOutput(
-          'Started Socks5 proxy server on 127.0.0.1:54430 \n'),
-      54430)
-    self.assertEquals(
-      ts_proxy_server.ParseTsProxyPortFromOutput(
-          'Started Socks5 proxy server on foo.bar.com:430 \n'),
-      430)
-    self.assertEquals(
-      ts_proxy_server.ParseTsProxyPortFromOutput(
-          'Failed to start sock5 proxy.'),
-      None)
-
-  def testSmokeStartingTsProxyServer(self):
-    with ts_proxy_server.TsProxyServer() as server:
-      self.assertIsNotNone(server.port)
-    with ts_proxy_server.TsProxyServer(None, 37124, 37125) as server:
-      self.assertIsNotNone(server.port)
-
-  def testSmokeUpdatingOutboundPorts(self):
-    with ts_proxy_server.TsProxyServer() as server:
-      self.assertIsNotNone(server.port)
-      server.UpdateOutboundPorts(31242, 14220)
-
-  def testSmokeUpdateOutboundPortsInvalid(self):
-    with ts_proxy_server.TsProxyServer() as server:
-      self.assertIsNotNone(server.port)
-      with self.assertRaises(AssertionError):
-        server.UpdateOutboundPorts(31242, 'abcde')
-
-  def testSmokeUpdateTrafficSettings(self):
-    with ts_proxy_server.TsProxyServer() as server:
-      server.UpdateTrafficSettings(round_trip_latency_ms=100)
-      server.UpdateTrafficSettings(download_bandwidth_kbps=5000)
-      server.UpdateTrafficSettings(upload_bandwidth_kbps=2000)
-      server.UpdateTrafficSettings(
-          round_trip_latency_ms=200, download_bandwidth_kbps=500,
-          upload_bandwidth_kbps=2000)
diff --git a/catapult/telemetry/telemetry/internal/util/wp_server_unittest.py b/catapult/telemetry/telemetry/internal/util/wp_server_unittest.py
deleted file mode 100644
index 054760d..0000000
--- a/catapult/telemetry/telemetry/internal/util/wp_server_unittest.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import sys
-import unittest
-
-from telemetry.internal.util import wpr_server
-
-
-# pylint: disable=protected-access
-class CreateCommandTest(unittest.TestCase):
-  def testHasDnsGivesDnsPort(self):
-    expected_cmd_line = [
-        sys.executable, 'replay.py', '--host=127.0.0.1',
-        '--port=2', '--ssl_port=1', '--dns_port=0',
-        '--use_closest_match', '--log_level=warning', '--extra_arg', 'foo.wpr']
-    cmd_line = wpr_server.ReplayServer._GetCommandLine(
-        'replay.py', '127.0.0.1', 2, 1, 0, ['--extra_arg'], 'foo.wpr',
-        log_level=logging.WARNING)
-    self.assertEqual(expected_cmd_line, cmd_line)
-
-  def testNoDnsGivesNoDnsForwarding(self):
-    expected_cmd_line = [
-        sys.executable, 'replay.py', '--host=127.0.0.1',
-        '--port=8080', '--ssl_port=8443', '--no-dns_forwarding',
-        '--use_closest_match', '--log_level=warning', 'bar.wpr']
-    cmd_line = wpr_server.ReplayServer._GetCommandLine(
-        'replay.py', '127.0.0.1', 8080, 8443, None, [], 'bar.wpr',
-        log_level=logging.WARNING)
-    self.assertEqual(expected_cmd_line, cmd_line)
-
-
-# pylint: disable=protected-access
-class ParseLogFilePortsTest(unittest.TestCase):
-  def testEmptyLinesGivesEmptyDict(self):
-    log_lines = iter([])
-    self.assertEqual(
-      {},
-      wpr_server.ReplayServer._ParseLogFilePorts(log_lines))
-
-  def testSingleMatchGivesSingleElementDict(self):
-    log_lines = iter([
-        'extra stuff',
-        '2014-09-27 17:04:27,11 WARNING HTTP server started on 127.0.0.1:5167',
-        'extra stuff',
-        ])
-    self.assertEqual(
-        {'http': 5167},
-        wpr_server.ReplayServer._ParseLogFilePorts(log_lines))
-
-  def testUnknownProtocolSkipped(self):
-    log_lines = iter([
-        '2014-09-27 17:04:27,11 WARNING FOO server started on 127.0.0.1:1111',
-        '2014-09-27 17:04:27,12 WARNING HTTP server started on 127.0.0.1:5167',
-        ])
-    self.assertEqual(
-        {'http': 5167},
-        wpr_server.ReplayServer._ParseLogFilePorts(log_lines))
-
-  def testTypicalLogLinesGiveFullDict(self):
-    log_lines = iter([
-        'extra',
-        '2014-09-27 17:04:27,11 WARNING DNS server started on 127.0.0.1:2345',
-        '2014-09-27 17:04:27,12 WARNING HTTP server started on 127.0.0.1:3456',
-        '2014-09-27 17:04:27,13 WARNING HTTPS server started on 127.0.0.1:4567',
-        ])
-    self.assertEqual(
-        {'dns': 2345, 'http': 3456, 'https': 4567},
-        wpr_server.ReplayServer._ParseLogFilePorts(log_lines))
diff --git a/catapult/telemetry/telemetry/internal/util/wpr_server.py b/catapult/telemetry/telemetry/internal/util/wpr_server.py
deleted file mode 100644
index d7f78db..0000000
--- a/catapult/telemetry/telemetry/internal/util/wpr_server.py
+++ /dev/null
@@ -1,339 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Start and stop Web Page Replay."""
-
-from telemetry.internal.util import atexit_with_log
-import logging
-import os
-import re
-import signal
-import subprocess
-import sys
-import tempfile
-import urllib
-
-from telemetry.core import util
-from telemetry.internal import forwarders
-
-import py_utils
-
-_REPLAY_DIR = os.path.join(
-    util.GetTelemetryThirdPartyDir(), 'web-page-replay')
-
-
-class ReplayError(Exception):
-  """Catch-all exception for the module."""
-  pass
-
-
-class ReplayNotFoundError(ReplayError):
-  def __init__(self, label, path):
-    super(ReplayNotFoundError, self).__init__()
-    self.args = (label, path)
-
-  def __str__(self):
-    label, path = self.args
-    return 'Path does not exist for %s: %s' % (label, path)
-
-
-class ReplayNotStartedError(ReplayError):
-  pass
-
-
-class ReplayServer(object):
-  """Start and Stop Web Page Replay.
-
-  Web Page Replay is a proxy that can record and "replay" web pages with
-  simulated network characteristics -- without having to edit the pages
-  by hand. With WPR, tests can use "real" web content, and catch
-  performance issues that may result from introducing network delays and
-  bandwidth throttling.
-
-  Example:
-     with ReplayServer(archive_path):
-       self.NavigateToURL(start_url)
-       self.WaitUntil(...)
-  """
-
-  def __init__(self, archive_path, replay_host, http_port, https_port, dns_port,
-               replay_options):
-    """Initialize ReplayServer.
-
-    Args:
-      archive_path: a path to a specific WPR archive (required).
-      replay_host: the hostname to serve traffic.
-      http_port: an integer port on which to serve HTTP traffic. May be zero
-          to let the OS choose an available port.
-      https_port: an integer port on which to serve HTTPS traffic. May be zero
-          to let the OS choose an available port.
-      dns_port: an integer port on which to serve DNS traffic. May be zero
-          to let the OS choose an available port. If None DNS forwarding is
-          disabled.
-      replay_options: an iterable of options strings to forward to replay.py.
-    """
-    self.archive_path = archive_path
-    self._replay_host = replay_host
-    self._use_dns_server = dns_port is not None
-    self._started_ports = {}  # a dict such as {'http': 80, 'https': 443}
-
-    # A temporary path for storing stdout & stderr of the webpagereplay
-    # subprocess.
-    self._temp_log_file_path = None
-
-    replay_py = os.path.join(_REPLAY_DIR, 'replay.py')
-    self._cmd_line = self._GetCommandLine(
-        replay_py, self._replay_host, http_port, https_port, dns_port,
-        replay_options, archive_path)
-
-    if '--record' in replay_options:
-      self._CheckPath('archive directory', os.path.dirname(self.archive_path))
-    elif not os.path.exists(self.archive_path):
-      self._CheckPath('archive file', self.archive_path)
-    self._CheckPath('replay script', replay_py)
-
-    self.replay_process = None
-
-  @staticmethod
-  def _GetLoggingLevel(log_level=None):
-    return {
-      logging.DEBUG: 'debug',
-      logging.INFO: 'info',
-      logging.WARNING: 'warning',
-      logging.ERROR: 'error',
-      logging.CRITICAL: 'critical',
-    }[log_level or logging.getLogger().level]
-
-  @staticmethod
-  def _GetCommandLine(replay_py, host_ip, http_port, https_port, dns_port,
-                      replay_options, archive_path, log_level=None):
-    """Set WPR command-line options. Can be overridden if needed."""
-    cmd_line = [sys.executable, replay_py]
-    cmd_line.extend([
-        '--host=%s' % host_ip,
-        '--port=%s' % http_port,
-        '--ssl_port=%s' % https_port
-        ])
-    if dns_port is not None:
-      # Note that if --host is not '127.0.0.1', Replay will override the local
-      # DNS nameserver settings to point to the replay-started DNS server.
-      cmd_line.append('--dns_port=%s' % dns_port)
-    else:
-      cmd_line.append('--no-dns_forwarding')
-    cmd_line.extend([
-        '--use_closest_match',
-        '--log_level=%s' % ReplayServer._GetLoggingLevel(log_level)
-        ])
-    cmd_line.extend(replay_options)
-    cmd_line.append(archive_path)
-    return cmd_line
-
-  def _CheckPath(self, label, path):
-    if not os.path.exists(path):
-      raise ReplayNotFoundError(label, path)
-
-  def _OpenLogFile(self):
-    """Opens the log file for writing."""
-    log_dir = os.path.dirname(self._temp_log_file_path)
-    if not os.path.exists(log_dir):
-      os.makedirs(log_dir)
-    return open(self._temp_log_file_path, 'w')
-
-  def _LogLines(self):
-    """Yields the log lines."""
-    if not os.path.isfile(self._temp_log_file_path):
-      return
-    with open(self._temp_log_file_path) as f:
-      for line in f:
-        yield line
-
-  def _IsStarted(self):
-    """Returns true if the server is up and running."""
-    if self.replay_process.poll() is not None:
-      # The process terminated.
-      return False
-
-    def HasIncompleteStartedPorts():
-      return ('http' not in self._started_ports or
-              'https' not in self._started_ports or
-              (self._use_dns_server and 'dns' not in self._started_ports))
-
-    if HasIncompleteStartedPorts():
-      self._started_ports = self._ParseLogFilePorts(self._LogLines())
-    if HasIncompleteStartedPorts():
-      return False
-    try:
-      # HTTPS may require SNI (which urllib does not speak), so only check
-      # that HTTP responds.
-      return 200 == self._UrlOpen('web-page-replay-generate-200').getcode()
-    except IOError:
-      return False
-
-  @staticmethod
-  def _ParseLogFilePorts(log_lines):
-    """Returns the ports on which replay listens as reported in its log file.
-
-    Only matches HTTP, HTTPS, and DNS. One call may return only some
-    of the ports depending on what has been written to the log file.
-
-    Example log lines:
-        2014-09-03 17:04:27,978 WARNING HTTP server started on 127.0.0.1:51673
-        2014-09-03 17:04:27,978 WARNING HTTPS server started on 127.0.0.1:35270
-
-    Returns:
-      a dict with ports available in log_lines. For example,
-         {}  # no ports found
-         {'http': 1234, 'https': 2345, 'dns': 3456}
-    """
-    ports = {}
-    port_re = re.compile(
-        r'.*?(?P<protocol>HTTP|HTTPS|DNS)'
-        r' server started on '
-        r'(?P<host>[^:]*):'
-        r'(?P<port>\d+)')
-    for line in log_lines:
-      m = port_re.match(line.strip())
-      if m:
-        protocol = m.group('protocol').lower()
-        ports[protocol] = int(m.group('port'))
-    return ports
-
-  def StartServer(self):
-    """Start Web Page Replay and verify that it started.
-
-    Returns:
-      A forwarders.PortSet(http, https, dns) tuple; with dns None if unused.
-    Raises:
-      ReplayNotStartedError: if Replay start-up fails.
-    """
-    is_posix = sys.platform.startswith('linux') or sys.platform == 'darwin'
-    logging.info('Starting Web-Page-Replay: %s', self._cmd_line)
-    self._CreateTempLogFilePath()
-    with open(self._temp_log_file_path, 'w') as log_fh:
-      self.replay_process = subprocess.Popen(
-          self._cmd_line, stdout=log_fh, stderr=subprocess.STDOUT,
-          preexec_fn=(_ResetInterruptHandler if is_posix else None))
-    try:
-      py_utils.WaitFor(self._IsStarted, 30)
-      logging.info('WPR ports: %s' % self._started_ports)
-      atexit_with_log.Register(self.StopServer)
-      return forwarders.PortSet(
-          self._started_ports['http'],
-          self._started_ports['https'],
-          self._started_ports.get('dns'),  # None if unused
-          )
-    except py_utils.TimeoutException:
-      raise ReplayNotStartedError(
-          'Web Page Replay failed to start. Log output:\n%s' %
-          ''.join(self._LogLines()))
-
-  def StopServer(self):
-    """Stop Web Page Replay."""
-    if self._IsStarted():
-      try:
-        self._StopReplayProcess()
-      finally:
-        # TODO(rnephew): Upload logs to google storage. crbug.com/525787
-        self._CleanUpTempLogFilePath()
-
-  def _StopReplayProcess(self):
-    if not self.replay_process:
-      return
-
-    logging.debug('Trying to stop Web-Page-Replay gracefully')
-    try:
-      if self._started_ports:
-        self._UrlOpen('web-page-replay-command-exit').close()
-    except IOError:
-      # IOError is possible because the server might exit without response.
-      pass
-
-    try:
-      py_utils.WaitFor(lambda: self.replay_process.poll() is not None, 10)
-    except py_utils.TimeoutException:
-      try:
-        # Use a SIGINT so that it can do graceful cleanup.
-        self.replay_process.send_signal(signal.SIGINT)
-      except:  # pylint: disable=bare-except
-        # On Windows, we are left with no other option than terminate().
-        is_primary_nameserver_changed_by_replay = (
-            self._use_dns_server and self._replay_host == '127.0.0.1')
-        if is_primary_nameserver_changed_by_replay:
-          # Replay changes the DNS nameserver configuration so that DNS
-          # requests are resolved by replay's own DNS server. It resolves
-          # all DNS requests to it own IP address to it can server the
-          # HTTP and HTTPS requests.
-          # If the replay host is not '127.0.0.1', then replay skips the
-          # nameserver change because it assumes a different mechanism
-          # will be used to route DNS requests to replay's DNS server.
-          logging.warning(
-              'Unable to stop Web-Page-Replay gracefully.\n'
-              'Replay changed the DNS nameserver configuration to make replay '
-              'the primary nameserver. That might not be restored!')
-        try:
-          self.replay_process.terminate()
-        except:  # pylint: disable=bare-except
-          pass
-      self.replay_process.wait()
-
-  def _CreateTempLogFilePath(self):
-    assert self._temp_log_file_path is None
-    handle, self._temp_log_file_path = tempfile.mkstemp()
-    os.close(handle)
-
-  def _CleanUpTempLogFilePath(self):
-    assert self._temp_log_file_path
-    if logging.getLogger('').isEnabledFor(logging.DEBUG):
-      with open(self._temp_log_file_path, 'r') as f:
-        wpr_log_content = '\n'.join([
-            '************************** WPR LOG *****************************',
-            f.read(),
-            '************************** END OF WPR LOG **********************'])
-      logging.debug(wpr_log_content)
-    os.remove(self._temp_log_file_path)
-    self._temp_log_file_path = None
-
-  def __enter__(self):
-    """Add support for with-statement."""
-    self.StartServer()
-    return self
-
-  def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
-    """Add support for with-statement."""
-    self.StopServer()
-
-  def _UrlOpen(self, url_path, protocol='http'):
-    """Open a Replay URL.
-
-    For matching requests in the archive, Replay relies on the "Host:" header.
-    For Replay command URLs, the "Host:" header is not needed.
-
-    Args:
-      url_path: WPR server request path.
-      protocol: 'http' or 'https'
-    Returns:
-      a file-like object from urllib.urlopen
-    """
-    url = '%s://%s:%s/%s' % (
-        protocol, self._replay_host, self._started_ports[protocol], url_path)
-    return urllib.urlopen(url, proxies={})
-
-def _ResetInterruptHandler():
-  """Reset the interrupt handler back to the default.
-
-  The replay process is stopped gracefully by making an HTTP request
-  ('web-page-replay-command-exit'). The graceful exit is important for
-  restoring the DNS configuration. If the HTTP request fails, the fallback
-  is to send SIGINT to the process.
-
-  On posix system, running this function before starting replay fixes a
-  bug that shows up when Telemetry is run as a background command from a
-  script. https://crbug.com/254572.
-
-  Background: Signal masks on Linux are inherited from parent
-  processes. If anything invoking us accidentally masks SIGINT
-  (e.g. by putting a process in the background from a shell script),
-  sending a SIGINT to the child will fail to terminate it.
-  """
-  signal.signal(signal.SIGINT, signal.SIG_DFL)
diff --git a/catapult/telemetry/telemetry/page/__init__.py b/catapult/telemetry/telemetry/page/__init__.py
deleted file mode 100644
index f11e2e1..0000000
--- a/catapult/telemetry/telemetry/page/__init__.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import inspect
-import logging
-import os
-import urlparse
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry import story
-from telemetry.page import cache_temperature as cache_temperature_module
-from telemetry.page import shared_page_state
-from telemetry.page import traffic_setting as traffic_setting_module
-from telemetry.internal.actions import action_runner as action_runner_module
-
-
-class Page(story.Story):
-
-  def __init__(self, url, page_set=None, base_dir=None, name='',
-               credentials_path=None,
-               credentials_bucket=cloud_storage.PUBLIC_BUCKET, tags=None,
-               startup_url='', make_javascript_deterministic=True,
-               shared_page_state_class=shared_page_state.SharedPageState,
-               grouping_keys=None,
-               cache_temperature=cache_temperature_module.ANY,
-               traffic_setting=traffic_setting_module.NONE,
-               platform_specific=False):
-    self._url = url
-
-    super(Page, self).__init__(
-        shared_page_state_class, name=name, tags=tags,
-        is_local=self._scheme in ['file', 'chrome', 'about'],
-        make_javascript_deterministic=make_javascript_deterministic,
-        grouping_keys=grouping_keys, platform_specific=platform_specific)
-
-    self._page_set = page_set
-    # Default value of base_dir is the directory of the file that defines the
-    # class of this page instance.
-    if base_dir is None:
-      base_dir = os.path.dirname(inspect.getfile(self.__class__))
-    self._base_dir = base_dir
-    self._name = name
-    if credentials_path:
-      credentials_path = os.path.join(self._base_dir, credentials_path)
-      cloud_storage.GetIfChanged(credentials_path, credentials_bucket)
-      if not os.path.exists(credentials_path):
-        logging.error('Invalid credentials path: %s' % credentials_path)
-        credentials_path = None
-    self._credentials_path = credentials_path
-    self._cache_temperature = cache_temperature
-    if cache_temperature != cache_temperature_module.ANY:
-      self.grouping_keys['cache_temperature'] = cache_temperature
-    if traffic_setting != traffic_setting_module.NONE:
-      self.grouping_keys['traffic_setting'] = traffic_setting
-
-    assert traffic_setting in traffic_setting_module.NETWORK_CONFIGS, (
-        'Invalid traffic setting: %s' % traffic_setting)
-    self._traffic_setting = traffic_setting
-
-    # Whether to collect garbage on the page before navigating & performing
-    # page actions.
-    self._collect_garbage_before_run = True
-
-    # These attributes can be set dynamically by the page.
-    self.synthetic_delays = dict()
-    self._startup_url = startup_url
-    self.credentials = None
-    self.skip_waits = False
-    self.script_to_evaluate_on_commit = None
-    self._SchemeErrorCheck()
-
-  @property
-  def credentials_path(self):
-    return self._credentials_path
-
-  @property
-  def cache_temperature(self):
-    return self._cache_temperature
-
-  @property
-  def traffic_setting(self):
-    return self._traffic_setting
-
-  @property
-  def startup_url(self):
-    return self._startup_url
-
-  def _SchemeErrorCheck(self):
-    if not self._scheme:
-      raise ValueError('Must prepend the URL with scheme (e.g. file://)')
-
-    if self.startup_url:
-      startup_url_scheme = urlparse.urlparse(self.startup_url).scheme
-      if not startup_url_scheme:
-        raise ValueError('Must prepend the URL with scheme (e.g. http://)')
-      if startup_url_scheme == 'file':
-        raise ValueError('startup_url with local file scheme is not supported')
-
-  def Run(self, shared_state):
-    current_tab = shared_state.current_tab
-    # Collect garbage from previous run several times to make the results more
-    # stable if needed.
-    if self._collect_garbage_before_run:
-      for _ in xrange(0, 5):
-        current_tab.CollectGarbage()
-    shared_state.page_test.WillNavigateToPage(self, current_tab)
-    shared_state.page_test.RunNavigateSteps(self, current_tab)
-    shared_state.page_test.DidNavigateToPage(self, current_tab)
-    action_runner = action_runner_module.ActionRunner(
-        current_tab, skip_waits=self.skip_waits)
-    self.RunPageInteractions(action_runner)
-
-  def RunNavigateSteps(self, action_runner):
-    url = self.file_path_url_with_scheme if self.is_file else self.url
-    action_runner.Navigate(
-        url, script_to_evaluate_on_commit=self.script_to_evaluate_on_commit)
-
-  def RunPageInteractions(self, action_runner):
-    """Override this to define custom interactions with the page.
-    e.g:
-      def RunPageInteractions(self, action_runner):
-        action_runner.ScrollPage()
-        action_runner.TapElement(text='Next')
-    """
-    pass
-
-  def AsDict(self):
-    """Converts a page object to a dict suitable for JSON output."""
-    d = {
-        'id': self._id,
-        'url': self._url,
-    }
-    if self._name:
-      d['name'] = self._name
-    return d
-
-  @property
-  def story_set(self):
-    return self._page_set
-
-  # TODO(nednguyen, aiolos): deprecate this property.
-  @property
-  def page_set(self):
-    return self._page_set
-
-  @property
-  def url(self):
-    return self._url
-
-  def GetSyntheticDelayCategories(self):
-    result = []
-    for delay, options in self.synthetic_delays.items():
-      options = '%f;%s' % (options.get('target_duration', 0),
-                           options.get('mode', 'static'))
-      result.append('DELAY(%s;%s)' % (delay, options))
-    return result
-
-  def __lt__(self, other):
-    return self.url < other.url
-
-  def __cmp__(self, other):
-    x = cmp(self.name, other.name)
-    if x != 0:
-      return x
-    return cmp(self.url, other.url)
-
-  def __str__(self):
-    return self.url
-
-  @property
-  def _scheme(self):
-    return urlparse.urlparse(self.url).scheme
-
-  @property
-  def is_file(self):
-    """Returns True iff this URL points to a file."""
-    return self._scheme == 'file'
-
-  @property
-  def file_path(self):
-    """Returns the path of the file, stripping the scheme and query string."""
-    assert self.is_file
-    # Because ? is a valid character in a filename,
-    # we have to treat the URL as a non-file by removing the scheme.
-    parsed_url = urlparse.urlparse(self.url[7:])
-    return os.path.normpath(os.path.join(
-        self._base_dir, parsed_url.netloc + parsed_url.path))
-
-  @property
-  def base_dir(self):
-    return self._base_dir
-
-  @property
-  def file_path_url(self):
-    """Returns the file path, including the params, query, and fragment."""
-    assert self.is_file
-    file_path_url = os.path.normpath(
-        os.path.join(self._base_dir, self.url[7:]))
-    # Preserve trailing slash or backslash.
-    # It doesn't matter in a file path, but it does matter in a URL.
-    if self.url.endswith('/'):
-      file_path_url += os.sep
-    return file_path_url
-
-  @property
-  def file_path_url_with_scheme(self):
-    return 'file://' + self.file_path_url
-
-  @property
-  def serving_dir(self):
-    if not self.is_file:
-      return None
-    file_path = os.path.realpath(self.file_path)
-    if os.path.isdir(file_path):
-      return file_path
-    else:
-      return os.path.dirname(file_path)
-
-  @property
-  def display_name(self):
-    if self.name:
-      return self.name
-    if self.page_set is None or not self.is_file:
-      return self.url
-    all_urls = [p.url.rstrip('/') for p in self.page_set if p.is_file]
-    common_prefix = os.path.dirname(os.path.commonprefix(all_urls))
-    return self.url[len(common_prefix):].strip('/')
diff --git a/catapult/telemetry/telemetry/page/action_runner.py b/catapult/telemetry/telemetry/page/action_runner.py
deleted file mode 100644
index d250a57..0000000
--- a/catapult/telemetry/telemetry/page/action_runner.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.actions import action_runner
-
-ActionRunner = action_runner.ActionRunner
diff --git a/catapult/telemetry/telemetry/page/cache_temperature.py b/catapult/telemetry/telemetry/page/cache_temperature.py
deleted file mode 100644
index 868bba5..0000000
--- a/catapult/telemetry/telemetry/page/cache_temperature.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Cache temperature specifies how the browser cache should be configured before
-the page run.
-
-See design doc for details:
-https://docs.google.com/document/u/1/d/12D7tkhZi887g9d0U2askU9JypU_wYiEI7Lw0bfwxUgA
-"""
-
-import logging
-
-import py_utils
-
-# Default Cache Temperature. The page doesn't care which browser cache state
-# it is run on.
-ANY = 'any'
-# Emulates PageCycler V1 cold runs. Clears system DNS cache, browser DiskCache,
-# net/ predictor cache, and net/ host resolver cache.
-PCV1_COLD = 'pcv1-cold'
-# Emulates PageCycler V1 warm runs. Ensures that the page was visited at least
-# once just before the run.
-PCV1_WARM = 'pcv1-warm'
-
-class MarkTelemetryInternal(object):
-
-  def __init__(self, browser, identifier):
-    self.browser = browser
-    self.identifier = identifier
-
-  def __enter__(self):
-    marker = 'telemetry.internal.%s.start' % self.identifier
-    self.browser.tabs[0].ExecuteJavaScript(
-        "console.time({{ marker }});", marker=marker)
-    self.browser.tabs[0].ExecuteJavaScript(
-        "console.timeEnd({{ marker }});", marker=marker)
-    return self
-
-  def __exit__(self, exception_type, exception_value, traceback):
-    if exception_type:
-      return True
-
-    marker = 'telemetry.internal.%s.end' % self.identifier
-    self.browser.tabs[0].ExecuteJavaScript(
-        "console.time({{ marker }});", marker=marker)
-    self.browser.tabs[0].ExecuteJavaScript(
-        "console.timeEnd({{ marker }});", marker=marker)
-    return True
-
-def EnsurePageCacheTemperature(page, browser, previous_page=None):
-  temperature = page.cache_temperature
-  logging.info('PageCacheTemperature: %s', temperature)
-
-  if temperature == ANY:
-    return
-
-  if temperature == PCV1_COLD:
-    if previous_page is None:
-      with MarkTelemetryInternal(browser, 'ensure_diskcache'):
-        tab = browser.tabs[0]
-        tab.Navigate("http://does.not.exist")
-        tab.WaitForDocumentReadyStateToBeComplete()
-
-    any_tab = browser.tabs[0]
-    any_tab.ClearCache(force=True)
-  elif temperature == PCV1_WARM:
-    if (previous_page is not None and
-        previous_page.url == page.url and
-        (previous_page.cache_temperature == PCV1_COLD or
-            previous_page.cache_temperature == PCV1_WARM)):
-      if '#' in page.url:
-        # Navigate to inexistent URL to avoid in-page hash navigation.
-        # Note: Unlike PCv1, PCv2 iterates the same URL for different cache
-        #       configurations. This may issue blink in-page hash navigations,
-        #       which isn't intended here.
-        with MarkTelemetryInternal(browser, 'avoid_double_hash_navigation'):
-          tab = browser.tabs[0]
-          tab.Navigate("http://does.not.exist")
-          tab.WaitForDocumentReadyStateToBeComplete()
-      return
-
-    with MarkTelemetryInternal(browser, 'warmCache'):
-      tab = browser.tabs[0]
-      tab.Navigate(page.url)
-      py_utils.WaitFor(tab.HasReachedQuiescence, 60)
-      tab.WaitForDocumentReadyStateToBeComplete()
-      tab.Navigate("about:blank")
-      tab.WaitForDocumentReadyStateToBeComplete()
diff --git a/catapult/telemetry/telemetry/page/cache_temperature_unittest.py b/catapult/telemetry/telemetry/page/cache_temperature_unittest.py
deleted file mode 100644
index 37cd02e..0000000
--- a/catapult/telemetry/telemetry/page/cache_temperature_unittest.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import contextlib
-
-from telemetry import decorators
-from telemetry import page as page_module
-from telemetry import story
-from telemetry.page import cache_temperature
-from telemetry.testing import browser_test_case
-from telemetry.timeline import tracing_config
-from tracing.trace_data import trace_data
-
-
-class CacheTempeartureTests(browser_test_case.BrowserTestCase):
-  def __init__(self, *args, **kwargs):
-    super(CacheTempeartureTests, self).__init__(*args, **kwargs)
-    self._full_trace = None
-
-  @contextlib.contextmanager
-  def captureTrace(self):
-    tracing_controller = self._browser.platform.tracing_controller
-    options = tracing_config.TracingConfig()
-    options.enable_chrome_trace = True
-    tracing_controller.StartTracing(options)
-    try:
-      yield
-    finally:
-      self._full_trace = tracing_controller.StopTracing()
-
-  def traceMarkers(self):
-    if not self._full_trace:
-      return set()
-
-    chrome_trace = self._full_trace.GetTraceFor(trace_data.CHROME_TRACE_PART)
-    return set(
-        event['name']
-        for event in chrome_trace['traceEvents']
-        if event['cat'] == 'blink.console')
-
-  @decorators.Enabled('has tabs')
-  def testEnsureAny(self):
-    with self.captureTrace():
-      story_set = story.StorySet()
-      page = page_module.Page('http://google.com', page_set=story_set,
-          cache_temperature=cache_temperature.ANY)
-      cache_temperature.EnsurePageCacheTemperature(page, self._browser)
-
-    markers = self.traceMarkers()
-    self.assertNotIn('telemetry.internal.ensure_diskcache.start', markers)
-    self.assertNotIn('telemetry.internal.warmCache.start', markers)
-
-  @decorators.Enabled('has tabs')
-  @decorators.Disabled('chromeos')
-  def testEnsurePCv1Cold(self):
-    with self.captureTrace():
-      story_set = story.StorySet()
-      page = page_module.Page('http://google.com', page_set=story_set,
-          cache_temperature=cache_temperature.PCV1_COLD)
-      cache_temperature.EnsurePageCacheTemperature(page, self._browser)
-
-    markers = self.traceMarkers()
-    self.assertIn('telemetry.internal.ensure_diskcache.start', markers)
-    self.assertIn('telemetry.internal.ensure_diskcache.end', markers)
-
-  @decorators.Enabled('has tabs')
-  def testEnsurePCv1WarmAfterPCv1ColdRun(self):
-    with self.captureTrace():
-      story_set = story.StorySet()
-      page = page_module.Page('http://google.com', page_set=story_set,
-          cache_temperature=cache_temperature.PCV1_COLD)
-      cache_temperature.EnsurePageCacheTemperature(page, self._browser)
-
-      previous_page = page
-      page = page_module.Page('http://google.com', page_set=story_set,
-          cache_temperature=cache_temperature.PCV1_WARM)
-      cache_temperature.EnsurePageCacheTemperature(page, self._browser,
-          previous_page)
-
-    markers = self.traceMarkers()
-    self.assertNotIn('telemetry.internal.warmCache.start', markers)
-
-  @decorators.Enabled('has tabs')
-  @decorators.Disabled('chromeos')
-  def testEnsurePCv1WarmFromScratch(self):
-    with self.captureTrace():
-      story_set = story.StorySet()
-      page = page_module.Page('http://google.com', page_set=story_set,
-          cache_temperature=cache_temperature.PCV1_WARM)
-      cache_temperature.EnsurePageCacheTemperature(page, self._browser)
-
-    markers = self.traceMarkers()
-    self.assertIn('telemetry.internal.warmCache.start', markers)
-    self.assertIn('telemetry.internal.warmCache.end', markers)
diff --git a/catapult/telemetry/telemetry/page/legacy_page_test.py b/catapult/telemetry/telemetry/page/legacy_page_test.py
deleted file mode 100644
index 47b6f80..0000000
--- a/catapult/telemetry/telemetry/page/legacy_page_test.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from py_trace_event import trace_event
-
-from telemetry.core import exceptions
-from telemetry.internal.actions import action_runner as action_runner_module
-
-# Export story_test.Failure to this page_test module
-from telemetry.web_perf.story_test import Failure
-
-
-class TestNotSupportedOnPlatformError(Exception):
-  """LegacyPageTest Exception raised when a required feature is unavailable.
-
-  The feature required to run the test could be part of the platform,
-  hardware configuration, or browser.
-  """
-
-
-class MultiTabTestAppCrashError(Exception):
-  """Exception raised after browser or tab crash for multi-tab tests.
-
-  Used to abort the test rather than try to recover from an unknown state.
-  """
-
-
-class MeasurementFailure(Failure):
-  """Exception raised when an undesired but designed-for problem."""
-
-
-class LegacyPageTest(object):
-  """A class styled on unittest.TestCase for creating page-specific tests.
-
-  Note that this method of measuring browser's performance is obsolete and only
-  here for "historical" reason. For your performance measurement need, please
-  use TimelineBasedMeasurement instead: https://goo.gl/eMvikK
-
-  For correctness testing, please use
-  serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase
-  instead. See examples in:
-  https://github.com/catapult-project/catapult/tree/master/telemetry/examples/browser_tests
-
-  Test should override ValidateAndMeasurePage to perform test
-  validation and page measurement as necessary.
-
-     class BodyChildElementMeasurement(LegacyPageTest):
-       def ValidateAndMeasurePage(self, page, tab, results):
-         body_child_count = tab.EvaluateJavaScript(
-             'document.body.children.length')
-         results.AddValue(scalar.ScalarValue(
-             page, 'body_children', 'count', body_child_count))
-  """
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def __init__(self,
-               needs_browser_restart_after_each_page=False,
-               clear_cache_before_each_run=False):
-    super(LegacyPageTest, self).__init__()
-
-    self.options = None
-    self._needs_browser_restart_after_each_page = (
-        needs_browser_restart_after_each_page)
-    self._clear_cache_before_each_run = clear_cache_before_each_run
-    self._close_tabs_before_run = True
-
-  @property
-  def is_multi_tab_test(self):
-    """Returns True if the test opens multiple tabs.
-
-    If the test overrides TabForPage, it is deemed a multi-tab test.
-    Multi-tab tests do not retry after tab or browser crashes, whereas,
-    single-tab tests too. That is because the state of multi-tab tests
-    (e.g., how many tabs are open, etc.) is unknown after crashes.
-    """
-    return self.TabForPage.__func__ is not LegacyPageTest.TabForPage.__func__
-
-  @property
-  def clear_cache_before_each_run(self):
-    """When set to True, the browser's disk and memory cache will be cleared
-    before each run."""
-    return self._clear_cache_before_each_run
-
-  @property
-  def close_tabs_before_run(self):
-    """When set to True, all tabs are closed before running the test for the
-    first time."""
-    return self._close_tabs_before_run
-
-  @close_tabs_before_run.setter
-  def close_tabs_before_run(self, close_tabs):
-    self._close_tabs_before_run = close_tabs
-
-  def RestartBrowserBeforeEachPage(self):
-    """ Should the browser be restarted for the page?
-
-    This returns true if the test needs to unconditionally restart the
-    browser for each page. It may be called before the browser is started.
-    """
-    return self._needs_browser_restart_after_each_page
-
-  def StopBrowserAfterPage(self, browser, page):
-    """Should the browser be stopped after the page is run?
-
-    This is called after a page is run to decide whether the browser needs to
-    be stopped to clean up its state. If it is stopped, then it will be
-    restarted to run the next page.
-
-    A test that overrides this can look at both the page and the browser to
-    decide whether it needs to stop the browser.
-    """
-    del browser, page  # unused
-    return False
-
-  def CustomizeBrowserOptions(self, options):
-    """Override to add test-specific options to the BrowserOptions object"""
-
-  def WillStartBrowser(self, platform):
-    """Override to manipulate the browser environment before it launches."""
-
-  def DidStartBrowser(self, browser):
-    """Override to customize the browser right after it has launched."""
-
-  def SetOptions(self, options):
-    """Sets the BrowserFinderOptions instance to use."""
-    self.options = options
-
-  def WillNavigateToPage(self, page, tab):
-    """Override to do operations before the page is navigated, notably Telemetry
-    will already have performed the following operations on the browser before
-    calling this function:
-    * Ensure only one tab is open.
-    * Call WaitForDocumentReadyStateToComplete on the tab."""
-
-  def DidNavigateToPage(self, page, tab):
-    """Override to do operations right after the page is navigated and after
-    all waiting for completion has occurred."""
-
-  def DidRunPage(self, platform):
-    """Called after the test run method was run, even if it failed."""
-
-  def TabForPage(self, page, browser):   # pylint: disable=unused-argument
-    """Override to select a different tab for the page.  For instance, to
-    create a new tab for every page, return browser.tabs.New()."""
-    try:
-      return browser.tabs[0]
-    # The tab may have gone away in some case, so we create a new tab and retry
-    # (See crbug.com/496280)
-    except exceptions.DevtoolsTargetCrashException as e:
-      logging.error('Tab may have crashed: %s' % str(e))
-      browser.tabs.New()
-      # See comment in shared_page_state.WillRunStory for why this waiting
-      # is needed.
-      browser.tabs[0].WaitForDocumentReadyStateToBeComplete()
-      return browser.tabs[0]
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    """Override to check test assertions and perform measurement.
-
-    When adding measurement results, call results.AddValue(...) for
-    each result. Raise an exception or add a failure.FailureValue on
-    failure. legacy_page_test.py also provides several base exception classes
-    to use.
-
-    Prefer metric value names that are in accordance with python
-    variable style. e.g., metric_name. The name 'url' must not be used.
-
-    Put together:
-      def ValidateAndMeasurePage(self, page, tab, results):
-        res = tab.EvaluateJavaScript('2+2')
-        if res != 4:
-          raise Exception('Oh, wow.')
-        results.AddValue(scalar.ScalarValue(
-            page, 'two_plus_two', 'count', res))
-
-    Args:
-      page: A telemetry.page.Page instance.
-      tab: A telemetry.core.Tab instance.
-      results: A telemetry.results.PageTestResults instance.
-    """
-    raise NotImplementedError
-
-  # Deprecated: do not use this hook. (crbug.com/470147)
-  def RunNavigateSteps(self, page, tab):
-    """Navigates the tab to the page URL attribute.
-
-    Runs the 'navigate_steps' page attribute as a compound action.
-    """
-    action_runner = action_runner_module.ActionRunner(
-        tab, skip_waits=page.skip_waits)
-    page.RunNavigateSteps(action_runner)
diff --git a/catapult/telemetry/telemetry/page/page.py b/catapult/telemetry/telemetry/page/page.py
deleted file mode 100644
index b838894..0000000
--- a/catapult/telemetry/telemetry/page/page.py
+++ /dev/null
@@ -1,8 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO(eakuefner): Refactor references to Page and kill this hack.
-from telemetry import page
-
-Page = page.Page
diff --git a/catapult/telemetry/telemetry/page/page_run_end_to_end_unittest.py b/catapult/telemetry/telemetry/page/page_run_end_to_end_unittest.py
deleted file mode 100644
index b18eb31..0000000
--- a/catapult/telemetry/telemetry/page/page_run_end_to_end_unittest.py
+++ /dev/null
@@ -1,788 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import re
-import shutil
-import sys
-import StringIO
-import tempfile
-import time
-import unittest
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import user_agent
-from telemetry.internal.results import results_options
-from telemetry.internal import story_runner
-from telemetry.internal.testing.test_page_sets import example_domain
-from telemetry.internal.util import exception_formatter
-from telemetry.page import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry.page import shared_page_state
-from telemetry.page import traffic_setting as traffic_setting_module
-from telemetry.util import image_util
-from telemetry.testing import fakes
-from telemetry.testing import options_for_unittests
-from telemetry.testing import system_stub
-
-
-SIMPLE_CREDENTIALS_STRING = """
-{
-  "test": {
-    "username": "example",
-    "password": "asdf"
-  }
-}
-"""
-
-
-class DummyTest(legacy_page_test.LegacyPageTest):
-
-  def ValidateAndMeasurePage(self, *_):
-    pass
-
-
-def SetUpStoryRunnerArguments(options):
-  parser = options.CreateParser()
-  story_runner.AddCommandLineArgs(parser)
-  options.MergeDefaultValues(parser.get_default_values())
-  story_runner.ProcessCommandLineArgs(parser, options)
-
-
-class EmptyMetadataForTest(benchmark.BenchmarkMetadata):
-
-  def __init__(self):
-    super(EmptyMetadataForTest, self).__init__('')
-
-
-class StubCredentialsBackend(object):
-
-  def __init__(self, login_return_value):
-    self.did_get_login = False
-    self.did_get_login_no_longer_needed = False
-    self.login_return_value = login_return_value
-
-  @property
-  def credentials_type(self):
-    return 'test'
-
-  def LoginNeeded(self, *_):
-    self.did_get_login = True
-    return self.login_return_value
-
-  def LoginNoLongerNeeded(self, _):
-    self.did_get_login_no_longer_needed = True
-
-
-def GetSuccessfulPageRuns(results):
-  return [run for run in results.all_page_runs if run.ok or run.skipped]
-
-
-def CaptureStderr(func, output_buffer):
-  def wrapper(*args, **kwargs):
-    original_stderr, sys.stderr = sys.stderr, output_buffer
-    try:
-      return func(*args, **kwargs)
-    finally:
-      sys.stderr = original_stderr
-  return wrapper
-
-
-# TODO: remove test cases that use real browsers and replace with a
-# story_runner or shared_page_state unittest that tests the same logic.
-class ActualPageRunEndToEndTests(unittest.TestCase):
-  # TODO(nduca): Move the basic "test failed, test succeeded" tests from
-  # page_test_unittest to here.
-
-  def setUp(self):
-    self._story_runner_logging_stub = None
-    self._formatted_exception_buffer = StringIO.StringIO()
-    self._original_formatter = exception_formatter.PrintFormattedException
-
-  def tearDown(self):
-    self.RestoreExceptionFormatter()
-
-  def CaptureFormattedException(self):
-    exception_formatter.PrintFormattedException = CaptureStderr(
-        exception_formatter.PrintFormattedException,
-        self._formatted_exception_buffer)
-    self._story_runner_logging_stub = system_stub.Override(
-        story_runner, ['logging'])
-
-  @property
-  def formatted_exception(self):
-    return self._formatted_exception_buffer.getvalue()
-
-  def RestoreExceptionFormatter(self):
-    exception_formatter.PrintFormattedException = self._original_formatter
-    if self._story_runner_logging_stub:
-      self._story_runner_logging_stub.Restore()
-      self._story_runner_logging_stub = None
-
-  def assertFormattedExceptionIsEmpty(self):
-    self.longMessage = False
-    self.assertEquals(
-        '', self.formatted_exception,
-        msg='Expected empty formatted exception: actual=%s' % '\n   > '.join(
-            self.formatted_exception.split('\n')))
-
-  def assertFormattedExceptionOnlyHas(self, expected_exception_name):
-    self.longMessage = True
-    actual_exception_names = re.findall(r'^Traceback.*?^(\w+)',
-                                        self.formatted_exception,
-                                        re.DOTALL | re.MULTILINE)
-    self.assertEquals([expected_exception_name], actual_exception_names,
-                      msg='Full formatted exception: %s' % '\n   > '.join(
-                          self.formatted_exception.split('\n')))
-
-  def testRaiseBrowserGoneExceptionFromRestartBrowserBeforeEachPage(self):
-    self.CaptureFormattedException()
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='foo'))
-    story_set.AddStory(page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='bar'))
-    story_set.AddStory(page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='baz'))
-
-    class Test(legacy_page_test.LegacyPageTest):
-
-      def __init__(self, *args):
-        super(Test, self).__init__(
-            *args, needs_browser_restart_after_each_page=True)
-        self.run_count = 0
-
-      def RestartBrowserBeforeEachPage(self):
-        # This will only be called twice with 3 pages.
-        old_run_count = self.run_count
-        self.run_count += 1
-        if old_run_count == 1:
-          raise exceptions.BrowserGoneException(None)
-        return self._needs_browser_restart_after_each_page
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    test = Test()
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-    self.assertEquals(2, test.run_count)
-    self.assertEquals(2, len(GetSuccessfulPageRuns(results)))
-    self.assertEquals(1, len(results.failures))
-    self.assertFormattedExceptionIsEmpty()
-
-  def testNeedsBrowserRestartAfterEachPage(self):
-    self.CaptureFormattedException()
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='foo'))
-    story_set.AddStory(page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='bar'))
-
-    class Test(legacy_page_test.LegacyPageTest):
-
-      def __init__(self, *args, **kwargs):
-        super(Test, self).__init__(*args, **kwargs)
-        self.browser_starts = 0
-
-      def DidStartBrowser(self, *args):
-        super(Test, self).DidStartBrowser(*args)
-        self.browser_starts += 1
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    test = Test(needs_browser_restart_after_each_page=True)
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-    self.assertEquals(2, len(GetSuccessfulPageRuns(results)))
-    self.assertEquals(2, test.browser_starts)
-    self.assertFormattedExceptionIsEmpty()
-
-  def testCredentialsWhenLoginFails(self):
-    self.CaptureFormattedException()
-    credentials_backend = StubCredentialsBackend(login_return_value=False)
-    did_run = self.runCredentialsTest(credentials_backend)
-    assert credentials_backend.did_get_login
-    assert not credentials_backend.did_get_login_no_longer_needed
-    assert not did_run
-    self.assertFormattedExceptionIsEmpty()
-
-  def testCredentialsWhenLoginSucceeds(self):
-    credentials_backend = StubCredentialsBackend(login_return_value=True)
-    did_run = self.runCredentialsTest(credentials_backend)
-    assert credentials_backend.did_get_login
-    assert credentials_backend.did_get_login_no_longer_needed
-    assert did_run
-
-  def runCredentialsTest(self, credentials_backend):
-    story_set = story.StorySet()
-    did_run = [False]
-
-    try:
-      with tempfile.NamedTemporaryFile(delete=False) as f:
-        page = page_module.Page(
-            'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-            credentials_path=f.name)
-        page.credentials = "test"
-        story_set.AddStory(page)
-
-        f.write(SIMPLE_CREDENTIALS_STRING)
-
-      class TestThatInstallsCredentialsBackend(legacy_page_test.LegacyPageTest):
-
-        def __init__(self, credentials_backend):
-          super(TestThatInstallsCredentialsBackend, self).__init__()
-          self._credentials_backend = credentials_backend
-
-        def DidStartBrowser(self, browser):
-          browser.credentials.AddBackend(self._credentials_backend)
-
-        def ValidateAndMeasurePage(self, *_):
-          did_run[0] = True
-
-      test = TestThatInstallsCredentialsBackend(credentials_backend)
-      options = options_for_unittests.GetCopy()
-      options.output_formats = ['none']
-      options.suppress_gtest_report = True
-      SetUpStoryRunnerArguments(options)
-      results = results_options.CreateResults(EmptyMetadataForTest(), options)
-      story_runner.Run(test, story_set, options, results)
-    finally:
-      os.remove(f.name)
-
-    return did_run[0]
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  def testUserAgent(self):
-    story_set = story.StorySet()
-    page = page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        shared_page_state_class=shared_page_state.SharedTabletPageState)
-    story_set.AddStory(page)
-
-    class TestUserAgent(legacy_page_test.LegacyPageTest):
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del page, results  # unused
-        actual_user_agent = tab.EvaluateJavaScript(
-            'window.navigator.userAgent')
-        expected_user_agent = user_agent.UA_TYPE_MAPPING['tablet']
-        assert actual_user_agent.strip() == expected_user_agent
-
-        # This is so we can check later that the test actually made it into this
-        # function. Previously it was timing out before even getting here, which
-        # should fail, but since it skipped all the asserts, it slipped by.
-        self.hasRun = True  # pylint: disable=attribute-defined-outside-init
-
-    test = TestUserAgent()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-
-    self.assertTrue(hasattr(test, 'hasRun') and test.hasRun)
-
-  # Ensure that story_runner forces exactly 1 tab before running a page.
-  @decorators.Enabled('has tabs')
-  def testOneTab(self):
-    story_set = story.StorySet()
-    page = page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir())
-    story_set.AddStory(page)
-
-    class TestOneTab(legacy_page_test.LegacyPageTest):
-
-      def DidStartBrowser(self, browser):
-        browser.tabs.New()
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del page, results  # unused
-        assert len(tab.browser.tabs) == 1
-
-    test = TestOneTab()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-
-  @decorators.Disabled('chromeos')  # crbug.com/652385
-  def testTrafficSettings(self):
-    story_set = story.StorySet()
-    slow_page = page_module.Page(
-        'file://green_rect.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='slow',
-        traffic_setting=traffic_setting_module.REGULAR_2G)
-    fast_page = page_module.Page(
-        'file://green_rect.html', story_set, base_dir=util.GetUnittestDataDir(),
-        name='fast',
-        traffic_setting=traffic_setting_module.WIFI)
-    story_set.AddStory(slow_page)
-    story_set.AddStory(fast_page)
-
-    latencies_by_page_in_ms = {}
-
-    class MeasureLatency(legacy_page_test.LegacyPageTest):
-      def __init__(self):
-        super(MeasureLatency, self).__init__()
-        self._will_navigate_time = None
-
-      def WillNavigateToPage(self, page, tab):
-        del page, tab # unused
-        self._will_navigate_time = time.time() * 1000
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del results  # unused
-        latencies_by_page_in_ms[page.name] = (
-            time.time() * 1000 - self._will_navigate_time)
-
-    test = MeasureLatency()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-    # Slow page should be slower than fast page by at least 300 ms (roundtrip
-    # time of 2G) - 2 ms (roundtrip time of Wifi)
-    self.assertGreater(latencies_by_page_in_ms['slow'],
-                       latencies_by_page_in_ms['fast'] + 300 - 2)
-
-  # Ensure that story_runner allows >1 tab for multi-tab test.
-  @decorators.Enabled('has tabs')
-  def testMultipleTabsOkayForMultiTabTest(self):
-    story_set = story.StorySet()
-    page = page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir())
-    story_set.AddStory(page)
-
-    class TestMultiTabs(legacy_page_test.LegacyPageTest):
-      def TabForPage(self, page, browser):
-        del page  # unused
-        return browser.tabs.New()
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del page, results  # unused
-        assert len(tab.browser.tabs) == 2
-
-    test = TestMultiTabs()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-
-  # Ensure that story_runner allows the test to customize the browser
-  # before it launches.
-  def testBrowserBeforeLaunch(self):
-    story_set = story.StorySet()
-    page = page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir())
-    story_set.AddStory(page)
-
-    class TestBeforeLaunch(legacy_page_test.LegacyPageTest):
-
-      def __init__(self):
-        super(TestBeforeLaunch, self).__init__()
-        self._did_call_will_start = False
-        self._did_call_did_start = False
-
-      def WillStartBrowser(self, platform):
-        self._did_call_will_start = True
-        # TODO(simonjam): Test that the profile is available.
-
-      def DidStartBrowser(self, browser):
-        assert self._did_call_will_start
-        self._did_call_did_start = True
-
-      def ValidateAndMeasurePage(self, *_):
-        assert self._did_call_did_start
-
-    test = TestBeforeLaunch()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-
-  def testRunPageWithStartupUrl(self):
-    num_times_browser_closed = [0]
-
-    class TestSharedState(shared_page_state.SharedPageState):
-
-      def _StopBrowser(self):
-        super(TestSharedState, self)._StopBrowser()
-        num_times_browser_closed[0] += 1
-
-    story_set = story.StorySet()
-    page = page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir(),
-        startup_url='about:blank', shared_page_state_class=TestSharedState)
-    story_set.AddStory(page)
-
-    class Measurement(legacy_page_test.LegacyPageTest):
-
-      def __init__(self):
-        super(Measurement, self).__init__()
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del page, tab, results  # not used
-
-    options = options_for_unittests.GetCopy()
-    options.pageset_repeat = 2
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    if not browser_finder.FindBrowser(options):
-      return
-    test = Measurement()
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-    self.assertEquals('about:blank', options.browser_options.startup_url)
-    # _StopBrowser should be called 2 times:
-    # 1. browser restarts after page 1 run
-    # 2. in the TearDownState after all the pages have run.
-    self.assertEquals(num_times_browser_closed[0], 2)
-
-  # Ensure that story_runner calls cleanUp when a page run fails.
-  def testCleanUpPage(self):
-    story_set = story.StorySet()
-    page = page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir())
-    story_set.AddStory(page)
-
-    class Test(legacy_page_test.LegacyPageTest):
-
-      def __init__(self):
-        super(Test, self).__init__()
-        self.did_call_clean_up = False
-
-      def ValidateAndMeasurePage(self, *_):
-        raise legacy_page_test.Failure
-
-      def DidRunPage(self, platform):
-        del platform  # unused
-        self.did_call_clean_up = True
-
-    test = Test()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-    assert test.did_call_clean_up
-
-  # Ensure skipping the test if shared state cannot be run on the browser.
-  def testSharedPageStateCannotRunOnBrowser(self):
-    story_set = story.StorySet()
-
-    class UnrunnableSharedState(shared_page_state.SharedPageState):
-      def CanRunOnBrowser(self, browser_info, page):
-        del browser_info, page  # unused
-        return False
-
-      def ValidateAndMeasurePage(self, _):
-        pass
-
-    story_set.AddStory(page_module.Page(
-        url='file://blank.html', page_set=story_set,
-        base_dir=util.GetUnittestDataDir(),
-        shared_page_state_class=UnrunnableSharedState))
-
-    class Test(legacy_page_test.LegacyPageTest):
-
-      def __init__(self, *args, **kwargs):
-        super(Test, self).__init__(*args, **kwargs)
-        self.will_navigate_to_page_called = False
-
-      def ValidateAndMeasurePage(self, *args):
-        del args  # unused
-        raise Exception('Exception should not be thrown')
-
-      def WillNavigateToPage(self, page, tab):
-        del page, tab  # unused
-        self.will_navigate_to_page_called = True
-
-    test = Test()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results)
-    self.assertFalse(test.will_navigate_to_page_called)
-    self.assertEquals(1, len(GetSuccessfulPageRuns(results)))
-    self.assertEquals(1, len(results.skipped_values))
-    self.assertEquals(0, len(results.failures))
-
-  def testRunPageWithProfilingFlag(self):
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page(
-        'file://blank.html', story_set, base_dir=util.GetUnittestDataDir()))
-
-    class Measurement(legacy_page_test.LegacyPageTest):
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        pass
-
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    options.reset_results = None
-    options.upload_results = None
-    options.results_label = None
-    options.output_dir = tempfile.mkdtemp()
-    options.profiler = 'trace'
-    try:
-      SetUpStoryRunnerArguments(options)
-      results = results_options.CreateResults(EmptyMetadataForTest(), options)
-      story_runner.Run(Measurement(), story_set, options, results)
-      self.assertEquals(1, len(GetSuccessfulPageRuns(results)))
-      self.assertEquals(0, len(results.failures))
-      self.assertEquals(0, len(results.all_page_specific_values))
-      self.assertTrue(os.path.isfile(
-          os.path.join(options.output_dir, 'blank_html.html')))
-    finally:
-      shutil.rmtree(options.output_dir)
-
-  def _RunPageTestThatRaisesAppCrashException(self, test, max_failures):
-    class TestPage(page_module.Page):
-
-      def RunNavigateSteps(self, _):
-        raise exceptions.AppCrashException
-
-    story_set = story.StorySet()
-    for i in range(5):
-      story_set.AddStory(
-          TestPage('file://blank.html', story_set,
-                   base_dir=util.GetUnittestDataDir(), name='foo%d' % i))
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(test, story_set, options, results,
-                     max_failures=max_failures)
-    return results
-
-  def testSingleTabMeansCrashWillCauseFailureValue(self):
-    self.CaptureFormattedException()
-
-    class SingleTabTest(legacy_page_test.LegacyPageTest):
-      # Test is not multi-tab because it does not override TabForPage.
-
-      def ValidateAndMeasurePage(self, *_):
-        pass
-
-    test = SingleTabTest()
-    results = self._RunPageTestThatRaisesAppCrashException(
-        test, max_failures=1)
-    self.assertEquals([], GetSuccessfulPageRuns(results))
-    self.assertEquals(2, len(results.failures))  # max_failures + 1
-    self.assertFormattedExceptionIsEmpty()
-
-  @decorators.Enabled('has tabs')
-  def testMultipleTabsMeansCrashRaises(self):
-    self.CaptureFormattedException()
-
-    class MultipleTabsTest(legacy_page_test.LegacyPageTest):
-      # Test *is* multi-tab because it overrides TabForPage.
-
-      def TabForPage(self, page, browser):
-        return browser.tabs.New()
-
-      def ValidateAndMeasurePage(self, *_):
-        pass
-
-    test = MultipleTabsTest()
-    with self.assertRaises(legacy_page_test.MultiTabTestAppCrashError):
-      self._RunPageTestThatRaisesAppCrashException(test, max_failures=1)
-    self.assertFormattedExceptionOnlyHas('AppCrashException')
-
-  def testWebPageReplay(self):
-    story_set = example_domain.ExampleDomainPageSet()
-    body = []
-
-    class TestWpr(legacy_page_test.LegacyPageTest):
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del page, results  # unused
-        body.append(tab.EvaluateJavaScript('document.body.innerText'))
-
-      def DidRunPage(self, platform):
-        # Force the replay server to restart between pages; this verifies that
-        # the restart mechanism works.
-        platform.network_controller.StopReplay()
-
-    test = TestWpr()
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-
-    story_runner.Run(test, story_set, options, results)
-
-    self.longMessage = True
-    self.assertIn('Example Domain', body[0],
-                  msg='URL: %s' % story_set.stories[0].url)
-    self.assertIn('Example Domain', body[1],
-                  msg='URL: %s' % story_set.stories[1].url)
-
-    self.assertEquals(2, len(GetSuccessfulPageRuns(results)))
-    self.assertEquals(0, len(results.failures))
-
-  def testScreenShotTakenForFailedPage(self):
-    self.CaptureFormattedException()
-    platform_screenshot_supported = [False]
-    tab_screenshot_supported = [False]
-    chrome_version_screen_shot = [None]
-
-    class FailingTestPage(page_module.Page):
-
-      def RunNavigateSteps(self, action_runner):
-        action_runner.Navigate(self._url)
-        platform_screenshot_supported[0] = (
-            action_runner.tab.browser.platform.CanTakeScreenshot)
-        tab_screenshot_supported[0] = action_runner.tab.screenshot_supported
-        if not platform_screenshot_supported[0] and tab_screenshot_supported[0]:
-          chrome_version_screen_shot[0] = action_runner.tab.Screenshot()
-        raise exceptions.AppCrashException
-
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page('file://blank.html', story_set))
-    failing_page = FailingTestPage('chrome://version', story_set)
-    story_set.AddStory(failing_page)
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.browser_options.take_screenshot_for_failed_page = True
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(DummyTest(), story_set, options, results,
-                     max_failures=2)
-    self.assertEquals(1, len(results.failures))
-    if not platform_screenshot_supported[0] and tab_screenshot_supported[0]:
-      self.assertEquals(1, len(results.pages_to_profiling_files))
-      self.assertIn(failing_page,
-                    results.pages_to_profiling_files)
-      screenshot_file_path = (
-          results.pages_to_profiling_files[failing_page][0].GetAbsPath())
-      try:
-        actual_screenshot = image_util.FromPngFile(screenshot_file_path)
-        self.assertEquals(image_util.Pixels(chrome_version_screen_shot[0]),
-                          image_util.Pixels(actual_screenshot))
-      finally:  # Must clean up screenshot file if exists.
-        os.remove(screenshot_file_path)
-
-  def testNoProfilingFilesCreatedForPageByDefault(self):
-    self.CaptureFormattedException()
-
-    class FailingTestPage(page_module.Page):
-
-      def RunNavigateSteps(self, action_runner):
-        action_runner.Navigate(self._url)
-        raise exceptions.AppCrashException
-
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page('file://blank.html', story_set))
-    failing_page = FailingTestPage('chrome://version', story_set)
-    story_set.AddStory(failing_page)
-    options = options_for_unittests.GetCopy()
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(DummyTest(), story_set, options, results,
-                     max_failures=2)
-    self.assertEquals(1, len(results.failures))
-    self.assertEquals(0, len(results.pages_to_profiling_files))
-
-
-class FakePageRunEndToEndTests(unittest.TestCase):
-
-  def setUp(self):
-    self.options = fakes.CreateBrowserFinderOptions()
-    self.options.output_formats = ['none']
-    self.options.suppress_gtest_report = True
-    SetUpStoryRunnerArguments(self.options)
-
-  def testNoScreenShotTakenForFailedPageDueToNoSupport(self):
-    self.options.browser_options.take_screenshot_for_failed_page = True
-
-    class FailingTestPage(page_module.Page):
-
-      def RunNavigateSteps(self, action_runner):
-        raise exceptions.AppCrashException
-
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page('file://blank.html', story_set))
-    failing_page = FailingTestPage('chrome://version', story_set)
-    story_set.AddStory(failing_page)
-    results = results_options.CreateResults(
-        EmptyMetadataForTest(), self.options)
-    story_runner.Run(DummyTest(), story_set, self.options, results,
-                     max_failures=2)
-    self.assertEquals(1, len(results.failures))
-    self.assertEquals(0, len(results.pages_to_profiling_files))
-
-  def testScreenShotTakenForFailedPageOnSupportedPlatform(self):
-    fake_platform = self.options.fake_possible_browser.returned_browser.platform
-    expected_png_base64 = """
- iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91
- JpzAAAAFklEQVR4Xg3EAQ0AAABAMP1LY3YI7l8l6A
- T8tgwbJAAAAABJRU5ErkJggg==
-"""
-    fake_platform.screenshot_png_data = expected_png_base64
-    self.options.browser_options.take_screenshot_for_failed_page = True
-
-    class FailingTestPage(page_module.Page):
-
-      def RunNavigateSteps(self, action_runner):
-        raise exceptions.AppCrashException
-    story_set = story.StorySet()
-    story_set.AddStory(page_module.Page('file://blank.html', story_set))
-    failing_page = FailingTestPage('chrome://version', story_set)
-    story_set.AddStory(failing_page)
-
-    results = results_options.CreateResults(
-        EmptyMetadataForTest(), self.options)
-    story_runner.Run(DummyTest(), story_set, self.options, results,
-                     max_failures=2)
-    self.assertEquals(1, len(results.failures))
-    self.assertEquals(1, len(results.pages_to_profiling_files))
-    self.assertIn(failing_page,
-                  results.pages_to_profiling_files)
-    screenshot_file_path = (
-        results.pages_to_profiling_files[failing_page][0].GetAbsPath())
-    try:
-      actual_screenshot_img = image_util.FromPngFile(screenshot_file_path)
-      self.assertTrue(image_util.AreEqual(
-                      image_util.FromBase64Png(expected_png_base64),
-                      actual_screenshot_img))
-    finally:  # Must clean up screenshot file if exists.
-      os.remove(screenshot_file_path)
diff --git a/catapult/telemetry/telemetry/page/page_test_unittest.py b/catapult/telemetry/telemetry/page/page_test_unittest.py
deleted file mode 100644
index f4cc3bf..0000000
--- a/catapult/telemetry/telemetry/page/page_test_unittest.py
+++ /dev/null
@@ -1,196 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import os
-import unittest
-
-from telemetry import decorators
-from telemetry import story
-from telemetry.page import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry.testing import options_for_unittests
-from telemetry.testing import page_test_test_case
-from telemetry.util import wpr_modes
-from telemetry.wpr import archive_info
-
-
-class PageTestThatFails(legacy_page_test.LegacyPageTest):
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    raise legacy_page_test.Failure
-
-
-class PageTestForBlank(legacy_page_test.LegacyPageTest):
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    contents = tab.EvaluateJavaScript('document.body.textContent')
-    if contents.strip() != 'Hello world':
-      raise legacy_page_test.MeasurementFailure(
-          'Page contents were: ' + contents)
-
-
-class PageTestForReplay(legacy_page_test.LegacyPageTest):
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    # Web Page Replay returns '404 Not found' if a page is not in the archive.
-    contents = tab.EvaluateJavaScript('document.body.textContent')
-    if '404 Not Found' in contents.strip():
-      raise legacy_page_test.MeasurementFailure('Page not in archive.')
-
-
-class PageTestQueryParams(legacy_page_test.LegacyPageTest):
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    query = tab.EvaluateJavaScript('window.location.search')
-    expected = '?foo=1'
-    if query.strip() != expected:
-      raise legacy_page_test.MeasurementFailure(
-          'query was %s, not %s.' % (query, expected))
-
-
-class PageTestWithAction(legacy_page_test.LegacyPageTest):
-
-  def __init__(self):
-    super(PageTestWithAction, self).__init__()
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    pass
-
-
-class PageWithAction(page_module.Page):
-
-  def __init__(self, url, story_set):
-    super(PageWithAction, self).__init__(url, story_set, story_set.base_dir)
-    self.run_test_action_called = False
-
-  def RunPageInteractions(self, _):
-    self.run_test_action_called = True
-
-
-class PageTestUnitTest(page_test_test_case.PageTestTestCase):
-
-  def setUp(self):
-    self._options = options_for_unittests.GetCopy()
-    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
-
-  def testGotToBlank(self):
-    story_set = self.CreateStorySetFromFileInUnittestDataDir('blank.html')
-    measurement = PageTestForBlank()
-    all_results = self.RunMeasurement(
-        measurement, story_set, options=self._options)
-    self.assertEquals(0, len(all_results.failures))
-
-  def testGotQueryParams(self):
-    story_set = self.CreateStorySetFromFileInUnittestDataDir(
-        'blank.html?foo=1')
-    measurement = PageTestQueryParams()
-    all_results = self.RunMeasurement(
-        measurement, story_set, options=self._options)
-    self.assertEquals(0, len(all_results.failures))
-
-  def testFailure(self):
-    story_set = self.CreateStorySetFromFileInUnittestDataDir('blank.html')
-    measurement = PageTestThatFails()
-    all_results = self.RunMeasurement(
-        measurement, story_set, options=self._options)
-    self.assertEquals(1, len(all_results.failures))
-
-  # This test is disabled because it runs against live sites, and needs to be
-  # fixed. crbug.com/179038
-  @decorators.Disabled('all')
-  def testRecordAndReplay(self):
-    test_archive = '/tmp/google.wpr'
-    google_url = 'http://www.google.com/'
-    foo_url = 'http://www.foo.com/'
-    archive_info_template = ("""
-{
-"archives": {
-  "%s": ["%s"]
-}
-}
-""")
-    try:
-      story_set = story.StorySet.PageSet()
-      measurement = PageTestForReplay()
-
-      # First record an archive with only www.google.com.
-      self._options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
-
-      story_set._wpr_archive_info = archive_info.WprArchiveInfo(
-          '', json.loads(archive_info_template % (test_archive, google_url)),
-          story_set.bucket)
-      story_set.pages = [page_module.Page(google_url, story_set)]
-      all_results = self.RunMeasurement(
-          measurement, story_set, options=self._options)
-      self.assertEquals(0, len(all_results.failures))
-
-      # Now replay it and verify that google.com is found but foo.com is not.
-      self._options.browser_options.wpr_mode = wpr_modes.WPR_REPLAY
-
-      story_set._wpr_archive_info = archive_info.WprArchiveInfo(
-          '', json.loads(archive_info_template % (test_archive, foo_url)),
-          story_set.bucket)
-      story_set.pages = [page_module.Page(foo_url, story_set)]
-      all_results = self.RunMeasurement(
-          measurement, story_set, options=self._options)
-      self.assertEquals(1, len(all_results.failures))
-
-      story_set._wpr_archive_info = archive_info.WprArchiveInfo(
-          '', json.loads(archive_info_template % (test_archive, google_url)),
-          story_set.bucket)
-      story_set.pages = [page_module.Page(google_url, story_set)]
-      all_results = self.RunMeasurement(
-          measurement, story_set, options=self._options)
-      self.assertEquals(0, len(all_results.failures))
-
-      self.assertTrue(os.path.isfile(test_archive))
-
-    finally:
-      if os.path.isfile(test_archive):
-        os.remove(test_archive)
-
-  def testRunActions(self):
-    story_set = self.CreateEmptyPageSet()
-    page = PageWithAction('file://blank.html', story_set)
-    story_set.AddStory(page)
-    measurement = PageTestWithAction()
-    self.RunMeasurement(measurement, story_set, options=self._options)
-    self.assertTrue(page.run_test_action_called)
-
-
-class MultiTabPageTestUnitTest(unittest.TestCase):
-
-  def testNoTabForPageReturnsFalse(self):
-    class PageTestWithoutTabForPage(legacy_page_test.LegacyPageTest):
-
-      def ValidateAndMeasurePage(self, *_):
-        pass
-    test = PageTestWithoutTabForPage()
-    self.assertFalse(test.is_multi_tab_test)
-
-  def testHasTabForPageReturnsTrue(self):
-    class PageTestWithTabForPage(legacy_page_test.LegacyPageTest):
-
-      def ValidateAndMeasurePage(self, *_):
-        pass
-
-      def TabForPage(self, *_):
-        pass
-    test = PageTestWithTabForPage()
-    self.assertTrue(test.is_multi_tab_test)
-
-  def testHasTabForPageInAncestor(self):
-    class PageTestWithTabForPage(legacy_page_test.LegacyPageTest):
-
-      def ValidateAndMeasurePage(self, *_):
-        pass
-
-      def TabForPage(self, *_):
-        pass
-
-    class PageTestWithTabForPageInParent(PageTestWithTabForPage):
-      pass
-    test = PageTestWithTabForPageInParent()
-    self.assertTrue(test.is_multi_tab_test)
diff --git a/catapult/telemetry/telemetry/page/page_unittest.py b/catapult/telemetry/telemetry/page/page_unittest.py
deleted file mode 100644
index 7620465..0000000
--- a/catapult/telemetry/telemetry/page/page_unittest.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry import story
-from telemetry.page import page
-
-import mock
-
-
-class TestPage(unittest.TestCase):
-
-  def assertPathEqual(self, path1, path2):
-    self.assertEqual(os.path.normpath(path1), os.path.normpath(path2))
-
-  def testFilePathRelative(self):
-    apage = page.Page('file://somedir/otherdir/file.html',
-                      None, base_dir='basedir')
-    self.assertPathEqual(apage.file_path, 'basedir/somedir/otherdir/file.html')
-
-  def testFilePathAbsolute(self):
-    apage = page.Page('file:///somedir/otherdir/file.html',
-                      None, base_dir='basedir')
-    self.assertPathEqual(apage.file_path, '/somedir/otherdir/file.html')
-
-  def testFilePathQueryString(self):
-    apage = page.Page('file://somedir/otherdir/file.html?key=val',
-                      None, base_dir='basedir')
-    self.assertPathEqual(apage.file_path, 'basedir/somedir/otherdir/file.html')
-
-  def testFilePathUrlQueryString(self):
-    apage = page.Page('file://somedir/file.html?key=val',
-                      None, base_dir='basedir')
-    self.assertPathEqual(apage.file_path_url,
-                         'basedir/somedir/file.html?key=val')
-
-  def testFilePathUrlTrailingSeparator(self):
-    apage = page.Page('file://somedir/otherdir/',
-                      None, base_dir='basedir')
-    self.assertPathEqual(apage.file_path_url, 'basedir/somedir/otherdir/')
-    self.assertTrue(apage.file_path_url.endswith(os.sep) or
-                    (os.altsep and apage.file_path_url.endswith(os.altsep)))
-
-  def testSort(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page.Page('http://www.bar.com/', story_set, story_set.base_dir))
-
-    pages = sorted([story_set.stories[0], story_set.stories[1]])
-    self.assertEquals([story_set.stories[1], story_set.stories[0]],
-                      pages)
-
-  def testGetUrlBaseDirAndFileForUrlBaseDir(self):
-    base_dir = os.path.dirname(__file__)
-    file_path = os.path.join(
-        os.path.dirname(base_dir), 'otherdir', 'file.html')
-    story_set = story.StorySet(base_dir=base_dir,
-                               serving_dirs=[os.path.join('..', 'somedir', '')])
-    story_set.AddStory(
-        page.Page('file://../otherdir/file.html', story_set,
-                  story_set.base_dir))
-    self.assertPathEqual(story_set[0].file_path, file_path)
-
-  def testDisplayUrlForHttp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page.Page('http://www.bar.com/', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'http://www.foo.com/')
-    self.assertEquals(story_set[1].display_name, 'http://www.bar.com/')
-
-  def testDisplayUrlForHttps(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page.Page('https://www.bar.com/', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'http://www.foo.com/')
-    self.assertEquals(story_set[1].display_name, 'https://www.bar.com/')
-
-  def testDisplayUrlForFile(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(page.Page(
-        'file://../../otherdir/foo.html', story_set, story_set.base_dir))
-    story_set.AddStory(page.Page(
-        'file://../../otherdir/bar.html', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'foo.html')
-    self.assertEquals(story_set[1].display_name, 'bar.html')
-
-  def testDisplayUrlForFilesDifferingBySuffix(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(page.Page(
-        'file://../../otherdir/foo.html', story_set, story_set.base_dir))
-    story_set.AddStory(page.Page(
-        'file://../../otherdir/foo1.html', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'foo.html')
-    self.assertEquals(story_set[1].display_name, 'foo1.html')
-
-  def testDisplayUrlForFileOfDifferentPaths(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page.Page(
-            'file://../../somedir/foo.html', story_set, story_set.base_dir))
-    story_set.AddStory(page.Page(
-        'file://../../otherdir/bar.html', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'somedir/foo.html')
-    self.assertEquals(story_set[1].display_name, 'otherdir/bar.html')
-
-  def testDisplayUrlForFileDirectories(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page.Page('file://../../otherdir/foo', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page.Page('file://../../otherdir/bar', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'foo')
-    self.assertEquals(story_set[1].display_name, 'bar')
-
-  def testDisplayUrlForSingleFile(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(page.Page(
-        'file://../../otherdir/foo.html', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'foo.html')
-
-  def testDisplayUrlForSingleDirectory(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page.Page('file://../../otherdir/foo', story_set, story_set.base_dir))
-
-    self.assertEquals(story_set[0].display_name, 'foo')
-
-  def testPagesHaveDifferentIds(self):
-    p0 = page.Page("http://example.com")
-    p1 = page.Page("http://example.com")
-    self.assertNotEqual(p0.id, p1.id)
-
-  def testNamelessPageAsDict(self):
-    nameless_dict = page.Page('http://example.com/').AsDict()
-    self.assertIn('id', nameless_dict)
-    del nameless_dict['id']
-    self.assertEquals({
-                      'url': 'http://example.com/',
-                      }, nameless_dict)
-
-  def testNamedPageAsDict(self):
-    named_dict = page.Page('http://example.com/', name='Example').AsDict()
-    self.assertIn('id', named_dict)
-    del named_dict['id']
-    self.assertEquals({
-                      'url': 'http://example.com/',
-                      'name': 'Example'
-                      }, named_dict)
-
-  def testIsLocal(self):
-    p = page.Page('file://foo.html')
-    self.assertTrue(p.is_local)
-
-    p = page.Page('chrome://extensions')
-    self.assertTrue(p.is_local)
-
-    p = page.Page('about:blank')
-    self.assertTrue(p.is_local)
-
-    p = page.Page('http://foo.com')
-    self.assertFalse(p.is_local)
-
-
-class TestPageRun(unittest.TestCase):
-
-  def testFiveGarbageCollectionCallsByDefault(self):
-    mock_shared_state = mock.Mock()
-    p = page.Page('file://foo.html')
-    p.Run(mock_shared_state)
-    expected = [mock.call.current_tab.CollectGarbage(),
-                mock.call.current_tab.CollectGarbage(),
-                mock.call.current_tab.CollectGarbage(),
-                mock.call.current_tab.CollectGarbage(),
-                mock.call.current_tab.CollectGarbage(),
-                mock.call.page_test.WillNavigateToPage(
-                p, mock_shared_state.current_tab),
-                mock.call.page_test.RunNavigateSteps(
-                p, mock_shared_state.current_tab),
-                mock.call.page_test.DidNavigateToPage(
-                p, mock_shared_state.current_tab)]
-    self.assertEquals(mock_shared_state.mock_calls, expected)
-
-  def testNoGarbageCollectionCalls(self):
-    mock_shared_state = mock.Mock()
-
-    class NonGarbageCollectPage(page.Page):
-
-      def __init__(self, url):
-        super(NonGarbageCollectPage, self).__init__(url)
-        self._collect_garbage_before_run = False
-
-    p = NonGarbageCollectPage('file://foo.html')
-    p.Run(mock_shared_state)
-    expected = [mock.call.page_test.WillNavigateToPage(
-                p, mock_shared_state.current_tab),
-                mock.call.page_test.RunNavigateSteps(
-                p, mock_shared_state.current_tab),
-                mock.call.page_test.DidNavigateToPage(
-                p, mock_shared_state.current_tab)]
-    self.assertEquals(mock_shared_state.mock_calls, expected)
diff --git a/catapult/telemetry/telemetry/page/shared_page_state.py b/catapult/telemetry/telemetry/page/shared_page_state.py
deleted file mode 100644
index a42d7e2..0000000
--- a/catapult/telemetry/telemetry/page/shared_page_state.py
+++ /dev/null
@@ -1,350 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import sys
-
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import browser_finder_exceptions
-from telemetry.internal.browser import browser_info as browser_info_module
-from telemetry.internal.platform.profiler import profiler_finder
-from telemetry.internal.util import exception_formatter
-from telemetry.internal.util import file_handle
-from telemetry.page import cache_temperature
-from telemetry.page import traffic_setting
-from telemetry.page import legacy_page_test
-from telemetry import story
-from telemetry.util import screenshot
-from telemetry.util import wpr_modes
-from telemetry.web_perf import timeline_based_measurement
-
-
-def _PrepareFinderOptions(finder_options, test, device_type):
-  browser_options = finder_options.browser_options
-  # Set up user agent.
-  browser_options.browser_user_agent_type = device_type
-
-  test.CustomizeBrowserOptions(finder_options.browser_options)
-  if finder_options.profiler:
-    profiler_class = profiler_finder.FindProfiler(finder_options.profiler)
-    profiler_class.CustomizeBrowserOptions(browser_options.browser_type,
-                                           finder_options)
-
-
-class SharedPageState(story.SharedState):
-  """
-  This class contains all specific logic necessary to run a Chrome browser
-  benchmark.
-  """
-
-  _device_type = None
-
-  def __init__(self, test, finder_options, story_set):
-    super(SharedPageState, self).__init__(test, finder_options, story_set)
-    if isinstance(test, timeline_based_measurement.TimelineBasedMeasurement):
-      if finder_options.profiler:
-        assert not 'trace' in finder_options.profiler, (
-            'This is a Timeline Based Measurement benchmark. You cannot run it '
-            'with trace profiler enabled. If you need trace data, tracing is '
-            'always enabled in Timeline Based Measurement benchmarks and you '
-            'can get the trace data by adding --output-format=json.')
-      # This is to avoid the cyclic-import caused by timeline_based_page_test.
-      from telemetry.web_perf import timeline_based_page_test
-      self._test = timeline_based_page_test.TimelineBasedPageTest(test)
-    else:
-      self._test = test
-    _PrepareFinderOptions(finder_options, self._test, self._device_type)
-    self._browser = None
-    self._finder_options = finder_options
-    self._possible_browser = self._GetPossibleBrowser(
-        self._test, finder_options)
-
-    self._first_browser = True
-    self._did_login_for_current_page = False
-    self._previous_page = None
-    self._current_page = None
-    self._current_tab = None
-
-    self._test.SetOptions(self._finder_options)
-
-    # TODO(crbug/404771): Move network controller options out of
-    # browser_options and into finder_options.
-    browser_options = self._finder_options.browser_options
-    if self._finder_options.use_live_sites:
-      wpr_mode = wpr_modes.WPR_OFF
-    elif browser_options.wpr_mode == wpr_modes.WPR_RECORD:
-      wpr_mode = wpr_modes.WPR_RECORD
-    else:
-      wpr_mode = wpr_modes.WPR_REPLAY
-
-    use_live_traffic = wpr_mode == wpr_modes.WPR_OFF
-
-    if self.platform.network_controller.is_open:
-      self.platform.network_controller.Close()
-    self.platform.network_controller.InitializeIfNeeded(
-        use_live_traffic=use_live_traffic)
-    self.platform.network_controller.Open(wpr_mode,
-                                          browser_options.extra_wpr_args)
-    self.platform.Initialize()
-
-  @property
-  def possible_browser(self):
-    return self._possible_browser
-
-  @property
-  def browser(self):
-    return self._browser
-
-  def _FindBrowser(self, finder_options):
-    possible_browser = browser_finder.FindBrowser(finder_options)
-    if not possible_browser:
-      raise browser_finder_exceptions.BrowserFinderException(
-          'No browser found.\n\nAvailable browsers:\n%s\n' %
-          '\n'.join(browser_finder.GetAllAvailableBrowserTypes(finder_options)))
-    return possible_browser
-
-  def _GetPossibleBrowser(self, test, finder_options):
-    """Return a possible_browser with the given options for |test|. """
-    possible_browser = self._FindBrowser(finder_options)
-    finder_options.browser_options.browser_type = (
-        possible_browser.browser_type)
-
-    enabled, msg = decorators.IsEnabled(test, possible_browser)
-    if not enabled and not finder_options.run_disabled_tests:
-      logging.warning(msg)
-      logging.warning('You are trying to run a disabled test.')
-
-    if possible_browser.IsRemote():
-      possible_browser.RunRemote()
-      sys.exit(0)
-    return possible_browser
-
-  def DumpStateUponFailure(self, page, results):
-    # Dump browser standard output and log.
-    if self._browser:
-      self._browser.DumpStateUponFailure()
-    else:
-      logging.warning('Cannot dump browser state: No browser.')
-
-    # Capture a screenshot
-    if self._finder_options.browser_options.take_screenshot_for_failed_page:
-      fh = screenshot.TryCaptureScreenShot(self.platform, self._current_tab)
-      if fh is not None:
-        results.AddProfilingFile(page, fh)
-    else:
-      logging.warning('Taking screenshots upon failures disabled.')
-
-  def DidRunStory(self, results):
-    if self._finder_options.profiler:
-      self._StopProfiling(results)
-    # We might hang while trying to close the connection, and need to guarantee
-    # the page will get cleaned up to avoid future tests failing in weird ways.
-    try:
-      if self._current_tab and self._current_tab.IsAlive():
-        self._current_tab.CloseConnections()
-      self._previous_page = self._current_page
-    except Exception:
-      if self._current_tab:
-        self._current_tab.Close()
-    finally:
-      if self._current_page.credentials and self._did_login_for_current_page:
-        self.browser.credentials.LoginNoLongerNeeded(
-            self._current_tab, self._current_page.credentials)
-      if self._test.StopBrowserAfterPage(self.browser, self._current_page):
-        self._StopBrowser()
-      self._current_page = None
-      self._current_tab = None
-
-  @property
-  def platform(self):
-    return self._possible_browser.platform
-
-  def _StartBrowser(self, page):
-    assert self._browser is None
-    self._possible_browser.SetCredentialsPath(page.credentials_path)
-
-    self._test.WillStartBrowser(self.platform)
-    if page.startup_url:
-      self._finder_options.browser_options.startup_url = page.startup_url
-    self._browser = self._possible_browser.Create(self._finder_options)
-    self._test.DidStartBrowser(self.browser)
-
-    if self._first_browser:
-      self._first_browser = False
-      self.browser.credentials.WarnIfMissingCredentials(page)
-
-  def WillRunStory(self, page):
-    if not self.platform.tracing_controller.is_tracing_running:
-      # For TimelineBasedMeasurement benchmarks, tracing has already started.
-      # For PageTest benchmarks, tracing has not yet started. We need to make
-      # sure no tracing state is left before starting the browser for PageTest
-      # benchmarks.
-      self.platform.tracing_controller.ClearStateIfNeeded()
-
-    page_set = page.page_set
-    self._current_page = page
-    if self._browser and (self._test.RestartBrowserBeforeEachPage()
-                          or page.startup_url):
-      assert not self.platform.tracing_controller.is_tracing_running, (
-          'Should not restart browser when tracing is already running. For '
-          'TimelineBasedMeasurement (TBM) benchmarks, you should not use '
-          'startup_url. Use benchmark.ShouldTearDownStateAfterEachStoryRun '
-          'instead.')
-      self._StopBrowser()
-    started_browser = not self.browser
-
-    archive_path = page_set.WprFilePathForStory(page, self.platform.GetOSName())
-    # TODO(nednguyen, perezju): Ideally we should just let the network
-    # controller raise an exception when the archive_path is not found.
-    if archive_path is not None and not os.path.isfile(archive_path):
-      logging.warning('WPR archive missing: %s', archive_path)
-      archive_path = None
-    self.platform.network_controller.StartReplay(
-        archive_path, page.make_javascript_deterministic)
-
-    if self.browser:
-      # Set new credential path for browser.
-      self.browser.credentials.credentials_path = page.credentials_path
-    else:
-      self._StartBrowser(page)
-    if self.browser.supports_tab_control and self._test.close_tabs_before_run:
-      # Create a tab if there's none.
-      if len(self.browser.tabs) == 0:
-        self.browser.tabs.New()
-
-      # Ensure only one tab is open, unless the test is a multi-tab test.
-      if not self._test.is_multi_tab_test:
-        while len(self.browser.tabs) > 1:
-          self.browser.tabs[-1].Close()
-
-      # Must wait for tab to commit otherwise it can commit after the next
-      # navigation has begun and RenderFrameHostManager::DidNavigateMainFrame()
-      # will cancel the next navigation because it's pending. This manifests as
-      # the first navigation in a PageSet freezing indefinitely because the
-      # navigation was silently canceled when |self.browser.tabs[0]| was
-      # committed. Only do this when we just started the browser, otherwise
-      # there are cases where previous pages in a PageSet never complete
-      # loading so we'll wait forever.
-      if started_browser:
-        self.browser.tabs[0].WaitForDocumentReadyStateToBeComplete()
-
-    # Reset traffic shaping to speed up cache temperature setup.
-    self.platform.network_controller.UpdateTrafficSettings(0, 0, 0)
-    cache_temperature.EnsurePageCacheTemperature(
-        self._current_page, self.browser, self._previous_page)
-    if self._current_page.traffic_setting != traffic_setting.NONE:
-      s = traffic_setting.NETWORK_CONFIGS[self._current_page.traffic_setting]
-      self.platform.network_controller.UpdateTrafficSettings(
-          round_trip_latency_ms=s.round_trip_latency_ms,
-          download_bandwidth_kbps=s.download_bandwidth_kbps,
-          upload_bandwidth_kbps=s.upload_bandwidth_kbps)
-
-    # Start profiling if needed.
-    if self._finder_options.profiler:
-      self._StartProfiling(self._current_page)
-
-  def CanRunStory(self, page):
-    return self.CanRunOnBrowser(browser_info_module.BrowserInfo(self.browser),
-                                page)
-
-  def CanRunOnBrowser(self, browser_info,
-                      page):  # pylint: disable=unused-argument
-    """Override this to return whether the browser brought up by this state
-    instance is suitable for running the given page.
-
-    Args:
-      browser_info: an instance of telemetry.core.browser_info.BrowserInfo
-      page: an instance of telemetry.page.Page
-    """
-    del browser_info, page  # unused
-    return True
-
-  def _PreparePage(self):
-    self._current_tab = self._test.TabForPage(self._current_page, self.browser)
-    if self._current_page.is_file:
-      self.platform.SetHTTPServerDirectories(
-          self._current_page.page_set.serving_dirs |
-          set([self._current_page.serving_dir]))
-
-    if self._current_page.credentials:
-      if not self.browser.credentials.LoginNeeded(
-          self._current_tab, self._current_page.credentials):
-        raise legacy_page_test.Failure(
-            'Login as ' + self._current_page.credentials + ' failed')
-      self._did_login_for_current_page = True
-
-    if self._test.clear_cache_before_each_run:
-      self._current_tab.ClearCache(force=True)
-
-  @property
-  def current_page(self):
-    return self._current_page
-
-  @property
-  def current_tab(self):
-    return self._current_tab
-
-  @property
-  def page_test(self):
-    return self._test
-
-  def RunStory(self, results):
-    try:
-      self._PreparePage()
-      self._current_page.Run(self)
-      self._test.ValidateAndMeasurePage(
-          self._current_page, self._current_tab, results)
-    except exceptions.Error:
-      if self._test.is_multi_tab_test:
-        # Avoid trying to recover from an unknown multi-tab state.
-        exception_formatter.PrintFormattedException(
-            msg='Telemetry Error during multi tab test:')
-        raise legacy_page_test.MultiTabTestAppCrashError
-      raise
-
-  def TearDownState(self):
-    self._StopBrowser()
-    self.platform.StopAllLocalServers()
-    self.platform.network_controller.Close()
-
-  def _StopBrowser(self):
-    if self._browser:
-      self._browser.Close()
-      self._browser = None
-
-  def _StartProfiling(self, page):
-    output_file = os.path.join(self._finder_options.output_dir,
-                               page.file_safe_name)
-    if self._finder_options.pageset_repeat != 1:
-      output_file = util.GetSequentialFileName(output_file)
-    self.browser.profiling_controller.Start(
-        self._finder_options.profiler, output_file)
-
-  def _StopProfiling(self, results):
-    if self.browser:
-      profiler_files = self.browser.profiling_controller.Stop()
-      for f in profiler_files:
-        if os.path.isfile(f):
-          results.AddProfilingFile(self._current_page,
-                                   file_handle.FromFilePath(f))
-
-
-class SharedMobilePageState(SharedPageState):
-  _device_type = 'mobile'
-
-
-class SharedDesktopPageState(SharedPageState):
-  _device_type = 'desktop'
-
-
-class SharedTabletPageState(SharedPageState):
-  _device_type = 'tablet'
-
-
-class Shared10InchTabletPageState(SharedPageState):
-  _device_type = 'tablet_10_inch'
diff --git a/catapult/telemetry/telemetry/page/shared_page_state_unittest.py b/catapult/telemetry/telemetry/page/shared_page_state_unittest.py
deleted file mode 100644
index 7909f8f..0000000
--- a/catapult/telemetry/telemetry/page/shared_page_state_unittest.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal import story_runner
-from telemetry.page import page
-from telemetry.page import legacy_page_test
-from telemetry.page import shared_page_state
-from telemetry import story as story_module
-from telemetry.testing import fakes
-from telemetry.util import wpr_modes
-
-
-def SetUpPageRunnerArguments(options):
-  parser = options.CreateParser()
-  story_runner.AddCommandLineArgs(parser)
-  options.MergeDefaultValues(parser.get_default_values())
-  story_runner.ProcessCommandLineArgs(parser, options)
-
-
-class DummyTest(legacy_page_test.LegacyPageTest):
-
-  def ValidateAndMeasurePage(self, *_):
-    pass
-
-
-class SharedPageStateTests(unittest.TestCase):
-
-  def setUp(self):
-    self.options = fakes.CreateBrowserFinderOptions()
-    self.options.use_live_sites = False
-    self.options.output_formats = ['none']
-    self.options.suppress_gtest_report = True
-
-  def testUseLiveSitesFlagSet(self):
-    self.options.use_live_sites = True
-    run_state = shared_page_state.SharedPageState(
-        DummyTest(), self.options, story_module.StorySet())
-    self.assertTrue(run_state.platform.network_controller.is_open)
-    self.assertEquals(run_state.platform.network_controller.wpr_mode,
-                      wpr_modes.WPR_OFF)
-    self.assertTrue(run_state.platform.network_controller.use_live_traffic)
-
-  def testUseLiveSitesFlagUnset(self):
-    run_state = shared_page_state.SharedPageState(
-        DummyTest(), self.options, story_module.StorySet())
-    self.assertTrue(run_state.platform.network_controller.is_open)
-    self.assertEquals(run_state.platform.network_controller.wpr_mode,
-                      wpr_modes.WPR_REPLAY)
-    self.assertFalse(run_state.platform.network_controller.use_live_traffic)
-
-  def testWPRRecordEnable(self):
-    self.options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
-    run_state = shared_page_state.SharedPageState(
-        DummyTest(), self.options, story_module.StorySet())
-    self.assertTrue(run_state.platform.network_controller.is_open)
-    self.assertEquals(run_state.platform.network_controller.wpr_mode,
-                      wpr_modes.WPR_RECORD)
-    self.assertFalse(run_state.platform.network_controller.use_live_traffic)
-
-  def testConstructorCallsSetOptions(self):
-    test = DummyTest()
-    shared_page_state.SharedPageState(
-        test, self.options, story_module.StorySet())
-    self.assertEqual(test.options, self.options)
-
-  def assertUserAgentSetCorrectly(
-      self, shared_page_state_class, expected_user_agent):
-    story = page.Page(
-        'http://www.google.com',
-        shared_page_state_class=shared_page_state_class)
-    test = DummyTest()
-    story_set = story_module.StorySet()
-    story_set.AddStory(story)
-    story.shared_state_class(test, self.options, story_set)
-    browser_options = self.options.browser_options
-    actual_user_agent = browser_options.browser_user_agent_type
-    self.assertEqual(expected_user_agent, actual_user_agent)
-
-  def testPageStatesUserAgentType(self):
-    self.assertUserAgentSetCorrectly(
-        shared_page_state.SharedMobilePageState, 'mobile')
-    self.assertUserAgentSetCorrectly(
-        shared_page_state.SharedDesktopPageState, 'desktop')
-    self.assertUserAgentSetCorrectly(
-        shared_page_state.SharedTabletPageState, 'tablet')
-    self.assertUserAgentSetCorrectly(
-        shared_page_state.Shared10InchTabletPageState, 'tablet_10_inch')
-    self.assertUserAgentSetCorrectly(
-        shared_page_state.SharedPageState, None)
-
-  def testBrowserStartupURLSetCorrectly(self):
-    story_set = story_module.StorySet()
-    google_page = page.Page(
-        'http://www.google.com',
-        startup_url='http://www.google.com', page_set=story_set)
-    example_page = page.Page(
-        'https://www.example.com',
-        startup_url='https://www.example.com', page_set=story_set)
-    gmail_page = page.Page(
-        'https://www.gmail.com',
-        startup_url='https://www.gmail.com', page_set=story_set)
-
-    for p in (google_page, example_page, gmail_page):
-      story_set.AddStory(p)
-
-    shared_state = shared_page_state.SharedPageState(
-        DummyTest(), self.options, story_set)
-
-    for p in (google_page, example_page, gmail_page):
-      shared_state.WillRunStory(p)
-      self.assertEquals(
-          p.startup_url, self.options.browser_options.startup_url)
diff --git a/catapult/telemetry/telemetry/page/traffic_setting.py b/catapult/telemetry/telemetry/page/traffic_setting.py
deleted file mode 100644
index caffa09..0000000
--- a/catapult/telemetry/telemetry/page/traffic_setting.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-
-_Configs = collections.namedtuple(
-  '_Configs', ('download_bandwidth_kbps,'
-               'upload_bandwidth_kbps,'
-               'round_trip_latency_ms'))
-
-# These presets are copied from devtool's:
-# https://cs.chromium.org/chromium/src/third_party/WebKit/Source/devtools/front_end/components/NetworkConditionsSelector.js?l=43
-NONE = 'none'
-GPRS = 'GPRS'
-REGULAR_2G = 'Regular-2G'
-GOOD_2G = 'Good-2G'
-REGULAR_3G = 'Regular-3G'
-GOOD_3G = 'Good-3G'
-REGULAR_4G = 'Regular-4G'
-DSL = 'DSL'
-WIFI = 'WiFi'
-
-NETWORK_CONFIGS = {
-  NONE: _Configs(0, 0, 0),
-  GPRS: _Configs(50 * 1024 / 8, 20 * 1024 / 8, 500),
-  REGULAR_2G: _Configs(250 * 1024 / 8, 50 * 1024 / 8, 300),
-  GOOD_2G: _Configs(450 * 1024 / 8, 150 * 1024 / 8, 150),
-  REGULAR_3G: _Configs(750 * 1024 / 8, 250 * 1024 / 8, 100),
-  GOOD_3G: _Configs(1.5 * 1024 * 1024 / 8, 750 * 1024 / 8, 40),
-  REGULAR_4G: _Configs(4 * 1024 * 1024 / 8, 3 * 1024 * 1024 / 8, 20),
-  DSL: _Configs(2 * 1024 * 1024 / 8, 1 * 1024 * 1024 / 8, 5),
-  WIFI: _Configs(30 * 1024 * 1024 / 8, 15 * 1024 * 1024 / 8, 2),
-}
diff --git a/catapult/telemetry/telemetry/project_config.py b/catapult/telemetry/telemetry/project_config.py
deleted file mode 100644
index 5763dce..0000000
--- a/catapult/telemetry/telemetry/project_config.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class ProjectConfig(object):
-  """Contains information about the benchmark runtime environment.
-
-  Attributes:
-    top_level_dir: A dir that contains benchmark, page test, and/or story
-        set dirs and associated artifacts.
-    benchmark_dirs: A list of dirs containing benchmarks.
-    benchmark_aliases: A dict of name:alias string pairs to be matched against
-        exactly during benchmark selection.
-    client_configs: A list of paths to a ProjectDependencies json files.
-    default_chrome_root: A path to chromium source directory. Many telemetry
-      features depend on chromium source tree's presence and those won't work
-      in case this is not specified.
-  """
-  def __init__(self, top_level_dir, benchmark_dirs=None,
-               benchmark_aliases=None, client_configs=None,
-               default_chrome_root=None):
-    self._top_level_dir = top_level_dir
-    self._benchmark_dirs = benchmark_dirs or []
-    self._benchmark_aliases = benchmark_aliases or dict()
-    self._client_configs = client_configs or []
-    self._default_chrome_root = default_chrome_root
-
-  @property
-  def top_level_dir(self):
-    return self._top_level_dir
-
-  @property
-  def start_dirs(self):
-    return self._benchmark_dirs
-
-  @property
-  def benchmark_dirs(self):
-    return self._benchmark_dirs
-
-  @property
-  def benchmark_aliases(self):
-    return self._benchmark_aliases
-
-  @property
-  def client_configs(self):
-    return self._client_configs
-
-  @property
-  def default_chrome_root(self):
-    return self._default_chrome_root
diff --git a/catapult/telemetry/telemetry/record_wpr.py b/catapult/telemetry/telemetry/record_wpr.py
deleted file mode 100644
index 0cab637..0000000
--- a/catapult/telemetry/telemetry/record_wpr.py
+++ /dev/null
@@ -1,295 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import logging
-import sys
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.core import discover
-from telemetry.internal.browser import browser_options
-from telemetry.internal.results import results_options
-from telemetry.internal import story_runner
-from telemetry.internal.util import binary_manager
-from telemetry.page import legacy_page_test
-from telemetry.util import matching
-from telemetry.util import wpr_modes
-from telemetry.web_perf import timeline_based_measurement
-from telemetry.web_perf import timeline_based_page_test
-
-import py_utils
-
-DEFAULT_LOG_FORMAT = (
-  '(%(levelname)s) %(asctime)s %(module)s.%(funcName)s:%(lineno)d  '
-  '%(message)s')
-
-
-class RecorderPageTest(legacy_page_test.LegacyPageTest):
-  def __init__(self):
-    super(RecorderPageTest, self).__init__()
-    self.page_test = None
-    self.platform = None
-
-  def CustomizeBrowserOptions(self, options):
-    if self.page_test:
-      self.page_test.CustomizeBrowserOptions(options)
-
-  def WillStartBrowser(self, browser):
-    if self.platform is not None:
-      assert browser.GetOSName() == self.platform
-    self.platform = browser.GetOSName()
-    if self.page_test:
-      self.page_test.WillStartBrowser(browser)
-
-  def DidStartBrowser(self, browser):
-    if self.page_test:
-      self.page_test.DidStartBrowser(browser)
-
-  def WillNavigateToPage(self, page, tab):
-    """Override to ensure all resources are fetched from network."""
-    tab.ClearCache(force=False)
-    if self.page_test:
-      self.page_test.WillNavigateToPage(page, tab)
-
-  def DidNavigateToPage(self, page, tab):
-    if self.page_test:
-      self.page_test.DidNavigateToPage(page, tab)
-    tab.WaitForDocumentReadyStateToBeComplete()
-    py_utils.WaitFor(tab.HasReachedQuiescence, 30)
-
-  def CleanUpAfterPage(self, page, tab):
-    if self.page_test:
-      self.page_test.CleanUpAfterPage(page, tab)
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    if self.page_test:
-      self.page_test.ValidateAndMeasurePage(page, tab, results)
-
-  def RunNavigateSteps(self, page, tab):
-    if self.page_test:
-      self.page_test.RunNavigateSteps(page, tab)
-    else:
-      super(RecorderPageTest, self).RunNavigateSteps(page, tab)
-
-
-def _GetSubclasses(base_dir, cls):
-  """Returns all subclasses of |cls| in |base_dir|.
-
-  Args:
-    cls: a class
-
-  Returns:
-    dict of {underscored_class_name: benchmark class}
-  """
-  return discover.DiscoverClasses(base_dir, base_dir, cls,
-                                  index_by_class_name=True)
-
-
-def _MaybeGetInstanceOfClass(target, base_dir, cls):
-  if isinstance(target, cls):
-    return target
-  classes = _GetSubclasses(base_dir, cls)
-  return classes[target]() if target in classes else None
-
-
-def _PrintAllImpl(all_items, item_name, output_stream):
-  output_stream.write('Available %s\' names with descriptions:\n' % item_name)
-  keys = sorted(all_items.keys())
-  key_description = [(k, all_items[k].Description()) for k in keys]
-  _PrintPairs(key_description, output_stream)
-  output_stream.write('\n')
-
-
-def _PrintAllBenchmarks(base_dir, output_stream):
-  # TODO: reuse the logic of finding supported benchmarks in benchmark_runner.py
-  # so this only prints out benchmarks that are supported by the recording
-  # platform.
-  _PrintAllImpl(_GetSubclasses(base_dir, benchmark.Benchmark), 'benchmarks',
-                output_stream)
-
-
-def _PrintAllStories(base_dir, output_stream):
-  # TODO: actually print all stories once record_wpr support general
-  # stories recording.
-  _PrintAllImpl(_GetSubclasses(base_dir, story.StorySet), 'story sets',
-                output_stream)
-
-
-def _PrintPairs(pairs, output_stream, prefix=''):
-  """Prints a list of string pairs with alignment."""
-  first_column_length = max(len(a) for a, _ in pairs)
-  format_string = '%s%%-%ds  %%s\n' % (prefix, first_column_length)
-  for a, b in pairs:
-    output_stream.write(format_string % (a, b.strip()))
-
-
-class WprRecorder(object):
-
-  def __init__(self, base_dir, target, args=None):
-    self._base_dir = base_dir
-    self._record_page_test = RecorderPageTest()
-    self._options = self._CreateOptions()
-
-    self._benchmark = _MaybeGetInstanceOfClass(target, base_dir,
-                                               benchmark.Benchmark)
-    self._parser = self._options.CreateParser(usage='See %prog --help')
-    self._AddCommandLineArgs()
-    self._ParseArgs(args)
-    self._ProcessCommandLineArgs()
-    if self._benchmark is not None:
-      test = self._benchmark.CreatePageTest(self.options)
-      if isinstance(test, timeline_based_measurement.TimelineBasedMeasurement):
-        test = timeline_based_page_test.TimelineBasedPageTest(test)
-      # This must be called after the command line args are added.
-      self._record_page_test.page_test = test
-
-    self._page_set_base_dir = (
-        self._options.page_set_base_dir if self._options.page_set_base_dir
-        else self._base_dir)
-    self._story_set = self._GetStorySet(target)
-
-  @property
-  def options(self):
-    return self._options
-
-  def _CreateOptions(self):
-    options = browser_options.BrowserFinderOptions()
-    options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
-    return options
-
-  def CreateResults(self):
-    if self._benchmark is not None:
-      benchmark_metadata = self._benchmark.GetMetadata()
-    else:
-      benchmark_metadata = benchmark.BenchmarkMetadata('record_wpr')
-
-    return results_options.CreateResults(benchmark_metadata, self._options)
-
-  def _AddCommandLineArgs(self):
-    self._parser.add_option('--page-set-base-dir', action='store',
-                            type='string')
-    story_runner.AddCommandLineArgs(self._parser)
-    if self._benchmark is not None:
-      self._benchmark.AddCommandLineArgs(self._parser)
-      self._benchmark.SetArgumentDefaults(self._parser)
-    self._parser.add_option('--upload', action='store_true')
-    self._SetArgumentDefaults()
-
-  def _SetArgumentDefaults(self):
-    self._parser.set_defaults(**{'output_formats': ['none']})
-
-  def _ParseArgs(self, args=None):
-    args_to_parse = sys.argv[1:] if args is None else args
-    self._parser.parse_args(args_to_parse)
-
-  def _ProcessCommandLineArgs(self):
-    story_runner.ProcessCommandLineArgs(self._parser, self._options)
-
-    if self._options.use_live_sites:
-      self._parser.error("Can't --use-live-sites while recording")
-
-    if self._benchmark is not None:
-      self._benchmark.ProcessCommandLineArgs(self._parser, self._options)
-
-  def _GetStorySet(self, target):
-    if self._benchmark is not None:
-      return self._benchmark.CreateStorySet(self._options)
-    story_set = _MaybeGetInstanceOfClass(target, self._page_set_base_dir,
-                                         story.StorySet)
-    if story_set is None:
-      sys.stderr.write('Target %s is neither benchmark nor story set.\n'
-                       % target)
-      if not self._HintMostLikelyBenchmarksStories(target):
-        sys.stderr.write(
-            'Found no similar benchmark or story. Please use '
-            '--list-benchmarks or --list-stories to list candidates.\n')
-        self._parser.print_usage()
-      sys.exit(1)
-    return story_set
-
-  def _HintMostLikelyBenchmarksStories(self, target):
-    def _Impl(all_items, category_name):
-      candidates = matching.GetMostLikelyMatchedObject(
-          all_items.iteritems(), target, name_func=lambda kv: kv[1].Name())
-      if candidates:
-        sys.stderr.write('\nDo you mean any of those %s below?\n' %
-                         category_name)
-        _PrintPairs([(k, v.Description()) for k, v in candidates], sys.stderr)
-        return True
-      return False
-
-    has_benchmark_hint = _Impl(
-        _GetSubclasses(self._base_dir, benchmark.Benchmark), 'benchmarks')
-    has_story_hint = _Impl(
-        _GetSubclasses(self._base_dir, story.StorySet), 'stories')
-    return has_benchmark_hint or has_story_hint
-
-  def Record(self, results):
-    assert self._story_set.wpr_archive_info, (
-      'Pageset archive_data_file path must be specified.')
-    self._story_set.wpr_archive_info.AddNewTemporaryRecording()
-    self._record_page_test.CustomizeBrowserOptions(self._options)
-    story_runner.Run(self._record_page_test, self._story_set,
-        self._options, results)
-
-  def HandleResults(self, results, upload_to_cloud_storage):
-    if results.failures or results.skipped_values:
-      logging.warning('Some pages failed and/or were skipped. The recording '
-                      'has not been updated for these pages.')
-    results.PrintSummary()
-    self._story_set.wpr_archive_info.AddRecordedStories(
-        results.pages_that_succeeded,
-        upload_to_cloud_storage,
-        target_platform=self._record_page_test.platform)
-
-
-def Main(environment, **log_config_kwargs):
-  # the log level is set in browser_options
-  log_config_kwargs.pop('level', None)
-  log_config_kwargs.setdefault('format', DEFAULT_LOG_FORMAT)
-  logging.basicConfig(**log_config_kwargs)
-
-  parser = argparse.ArgumentParser(
-      usage='Record a benchmark or a story (page set).')
-  parser.add_argument(
-      'benchmark',
-      help=('benchmark name. This argument is optional. If both benchmark name '
-            'and story name are specified, this takes precedence as the '
-            'target of the recording.'),
-      nargs='?')
-  parser.add_argument('--story', help='story (page set) name')
-  parser.add_argument('--list-stories', dest='list_stories',
-                      action='store_true', help='list all story names.')
-  parser.add_argument('--list-benchmarks', dest='list_benchmarks',
-                      action='store_true', help='list all benchmark names.')
-  parser.add_argument('--upload', action='store_true',
-                      help='upload to cloud storage.')
-  args, extra_args = parser.parse_known_args()
-
-  if args.list_benchmarks or args.list_stories:
-    if args.list_benchmarks:
-      _PrintAllBenchmarks(environment.top_level_dir, sys.stderr)
-    if args.list_stories:
-      _PrintAllStories(environment.top_level_dir, sys.stderr)
-    return 0
-
-  target = args.benchmark or args.story
-
-  if not target:
-    sys.stderr.write('Please specify target (benchmark or story). Please refer '
-                     'usage below\n\n')
-    parser.print_help()
-    return 0
-
-  binary_manager.InitDependencyManager(environment.client_configs)
-
-  # TODO(nednguyen): update WprRecorder so that it handles the difference
-  # between recording a benchmark vs recording a story better based on
-  # the distinction between args.benchmark & args.story
-  wpr_recorder = WprRecorder(environment.top_level_dir, target, extra_args)
-  results = wpr_recorder.CreateResults()
-  wpr_recorder.Record(results)
-  wpr_recorder.HandleResults(results, args.upload)
-  return min(255, len(results.failures))
diff --git a/catapult/telemetry/telemetry/record_wpr_unittest.py b/catapult/telemetry/telemetry/record_wpr_unittest.py
deleted file mode 100644
index 926dc8f..0000000
--- a/catapult/telemetry/telemetry/record_wpr_unittest.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.core import util
-from telemetry import decorators
-from telemetry.page import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry import record_wpr
-from telemetry.testing import options_for_unittests
-from telemetry.testing import tab_test_case
-from telemetry.util import wpr_modes
-
-
-class MockPage(page_module.Page):
-  def __init__(self, story_set, url):
-    super(MockPage, self).__init__(url=url,
-                                   page_set=story_set,
-                                   base_dir=util.GetUnittestDataDir())
-    self.func_calls = []
-
-  def RunNavigateSteps(self, action_runner):
-    self.func_calls.append('RunNavigateSteps')
-    super(MockPage, self).RunNavigateSteps(action_runner)
-
-  def RunPageInteractions(self, _):
-    self.func_calls.append('RunPageInteractions')
-
-  def RunSmoothness(self, _):
-    self.func_calls.append('RunSmoothness')
-
-class MockStorySet(story.StorySet):
-  def __init__(self, url=''):
-    super(MockStorySet, self).__init__(
-        archive_data_file='data/archive_files/test.json')
-    self.AddStory(MockPage(self, url))
-
-
-class MockPageTest(legacy_page_test.LegacyPageTest):
-  def __init__(self):
-    super(MockPageTest, self).__init__()
-    self._action_name_to_run = "RunPageInteractions"
-    self.func_calls = []
-
-  def CustomizeBrowserOptions(self, options):
-    self.func_calls.append('CustomizeBrowserOptions')
-
-  def WillNavigateToPage(self, page, tab):
-    self.func_calls.append('WillNavigateToPage')
-
-  def DidNavigateToPage(self, page, tab):
-    self.func_calls.append('DidNavigateToPage')
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    self.func_calls.append('ValidateAndMeasurePage')
-
-  def WillStartBrowser(self, platform):
-    self.func_calls.append('WillStartBrowser')
-
-  def DidStartBrowser(self, browser):
-    self.func_calls.append('DidStartBrowser')
-
-class MockBenchmark(benchmark.Benchmark):
-  test = MockPageTest
-
-  def __init__(self):
-    super(MockBenchmark, self).__init__()
-    self.mock_story_set = None
-
-  @classmethod
-  def AddBenchmarkCommandLineArgs(cls, group):
-    group.add_option('', '--mock-benchmark-url', action='store', type='string')
-
-  def CreateStorySet(self, options):
-    kwargs = {}
-    if options.mock_benchmark_url:
-      kwargs['url'] = options.mock_benchmark_url
-    self.mock_story_set = MockStorySet(**kwargs)
-    return self.mock_story_set
-
-
-class MockTimelineBasedMeasurementBenchmark(benchmark.Benchmark):
-
-  def __init__(self):
-    super(MockTimelineBasedMeasurementBenchmark, self).__init__()
-    self.mock_story_set = None
-
-  @classmethod
-  def AddBenchmarkCommandLineArgs(cls, group):
-    group.add_option('', '--mock-benchmark-url', action='store', type='string')
-
-  def CreateStorySet(self, options):
-    kwargs = {}
-    if options.mock_benchmark_url:
-      kwargs['url'] = options.mock_benchmark_url
-    self.mock_story_set = MockStorySet(**kwargs)
-    return self.mock_story_set
-
-
-class RecordWprUnitTests(tab_test_case.TabTestCase):
-
-  _base_dir = util.GetUnittestDataDir()
-  _test_data_dir = os.path.join(util.GetUnittestDataDir(), 'page_tests')
-
-  @classmethod
-  def setUpClass(cls):
-    sys.path.extend([cls._base_dir, cls._test_data_dir])
-    super(RecordWprUnitTests, cls).setUpClass()
-    cls._url = cls.UrlOfUnittestFile('blank.html')
-    cls._test_options = options_for_unittests.GetCopy()
-
-  # When the RecorderPageTest is created from a PageSet, we do not have a
-  # PageTest to use. In this case, we will record every available action.
-  def testRunPage_AllActions(self):
-    record_page_test = record_wpr.RecorderPageTest()
-    page = MockPage(story_set=MockStorySet(url=self._url), url=self._url)
-
-    record_page_test.RunNavigateSteps(page, self._tab)
-    self.assertTrue('RunNavigateSteps' in page.func_calls)
-
-  # When the RecorderPageTest is created from a Benchmark, the benchmark will
-  # have a PageTest, specified by its test attribute.
-  def testRunPage_OnlyRunBenchmarkAction(self):
-    record_page_test = record_wpr.RecorderPageTest()
-    record_page_test.page_test = MockBenchmark().test()
-    page = MockPage(story_set=MockStorySet(url=self._url), url=self._url)
-    record_page_test.ValidateAndMeasurePage(page, self._tab, results=None)
-
-  def testRunPage_CallBenchmarksPageTestsFunctions(self):
-    record_page_test = record_wpr.RecorderPageTest()
-    record_page_test.page_test = MockBenchmark().test()
-    page = MockPage(story_set=MockStorySet(url=self._url), url=self._url)
-    record_page_test.ValidateAndMeasurePage(page, self._tab, results=None)
-    self.assertEqual(1, len(record_page_test.page_test.func_calls))
-    self.assertEqual('ValidateAndMeasurePage',
-                     record_page_test.page_test.func_calls[0])
-
-  def GetBrowserDeviceFlags(self):
-    flags = ['--browser', self._browser.browser_type,
-             '--remote', self._test_options.cros_remote,
-             '--device', self._device]
-    if self._test_options.chrome_root:
-      flags += ['--chrome-root', self._test_options.chrome_root]
-    return flags
-
-  @decorators.Disabled('chromeos') # crbug.com/404868.
-  def testWprRecorderWithPageSet(self):
-    flags = self.GetBrowserDeviceFlags()
-    mock_story_set = MockStorySet(url=self._url)
-    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir,
-                                          mock_story_set, flags)
-    results = wpr_recorder.CreateResults()
-    wpr_recorder.Record(results)
-    self.assertEqual(set(mock_story_set.stories), results.pages_that_succeeded)
-
-  def testWprRecorderWithBenchmark(self):
-    flags = self.GetBrowserDeviceFlags()
-    flags.extend(['--mock-benchmark-url', self._url])
-    mock_benchmark = MockBenchmark()
-    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, mock_benchmark,
-                                          flags)
-    results = wpr_recorder.CreateResults()
-    wpr_recorder.Record(results)
-    self.assertEqual(set(mock_benchmark.mock_story_set.stories),
-                     results.pages_that_succeeded)
-
-  def testWprRecorderWithTimelineBasedMeasurementBenchmark(self):
-    flags = self.GetBrowserDeviceFlags()
-    flags.extend(['--mock-benchmark-url', self._url])
-    mock_benchmark = MockTimelineBasedMeasurementBenchmark()
-    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, mock_benchmark,
-                                          flags)
-    results = wpr_recorder.CreateResults()
-    wpr_recorder.Record(results)
-    self.assertEqual(set(mock_benchmark.mock_story_set.stories),
-                     results.pages_that_succeeded)
-
-  def testPageSetBaseDirFlag(self):
-    flags = self.GetBrowserDeviceFlags()
-    flags.extend(['--page-set-base-dir', self._test_data_dir,
-                  '--mock-benchmark-url', self._url])
-    mock_benchmark = MockBenchmark()
-    wpr_recorder = record_wpr.WprRecorder(
-        'non-existent-dummy-dir', mock_benchmark, flags)
-    results = wpr_recorder.CreateResults()
-    wpr_recorder.Record(results)
-    self.assertEqual(set(mock_benchmark.mock_story_set.stories),
-                     results.pages_that_succeeded)
-
-  def testCommandLineFlags(self):
-    flags = [
-        '--pageset-repeat', '2',
-        '--mock-benchmark-url', self._url,
-        '--upload',
-    ]
-    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, MockBenchmark(),
-                                          flags)
-    # page_runner command-line args
-    self.assertEquals(2, wpr_recorder.options.pageset_repeat)
-    # benchmark command-line args
-    self.assertEquals(self._url, wpr_recorder.options.mock_benchmark_url)
-    # record_wpr command-line arg to upload to cloud-storage.
-    self.assertTrue(wpr_recorder.options.upload)
-    # invalid command-line args
-    self.assertFalse(hasattr(wpr_recorder.options, 'not_a_real_option'))
-
-  def testRecordingEnabled(self):
-    flags = ['--mock-benchmark-url', self._url]
-    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, MockBenchmark(),
-                                          flags)
-    self.assertEqual(wpr_modes.WPR_RECORD,
-                     wpr_recorder.options.browser_options.wpr_mode)
-
-  # When the RecorderPageTest CustomizeBrowserOptions/WillStartBrowser/
-  # DidStartBrowser function is called, it forwards the call to the PageTest
-  def testRecorderPageTest_BrowserMethods(self):
-    flags = ['--mock-benchmark-url', self._url]
-    record_page_test = record_wpr.RecorderPageTest()
-    record_page_test.page_test = MockBenchmark().test()
-    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, MockBenchmark(),
-                                          flags)
-    record_page_test.CustomizeBrowserOptions(wpr_recorder.options)
-    record_page_test.WillStartBrowser(self._tab.browser.platform)
-    record_page_test.DidStartBrowser(self._tab.browser)
-    self.assertTrue(
-        'CustomizeBrowserOptions' in record_page_test.page_test.func_calls)
-    self.assertTrue('WillStartBrowser' in record_page_test.page_test.func_calls)
-    self.assertTrue('DidStartBrowser' in record_page_test.page_test.func_calls)
-
-  def testUseLiveSitesUnsupported(self):
-    flags = ['--use-live-sites']
-    with self.assertRaises(SystemExit):
-      record_wpr.WprRecorder(self._test_data_dir, MockBenchmark(), flags)
diff --git a/catapult/telemetry/telemetry/story/__init__.py b/catapult/telemetry/telemetry/story/__init__.py
deleted file mode 100644
index a17b72d..0000000
--- a/catapult/telemetry/telemetry/story/__init__.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.story.shared_state import SharedState
-from telemetry.story.story import Story
-from telemetry.story.story_filter import StoryFilter
-from telemetry.story.story_set import StorySet
-
-
-PUBLIC_BUCKET = cloud_storage.PUBLIC_BUCKET
-PARTNER_BUCKET = cloud_storage.PARTNER_BUCKET
-INTERNAL_BUCKET = cloud_storage.INTERNAL_BUCKET
diff --git a/catapult/telemetry/telemetry/story/shared_state.py b/catapult/telemetry/telemetry/story/shared_state.py
deleted file mode 100644
index 9de4945..0000000
--- a/catapult/telemetry/telemetry/story/shared_state.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from py_trace_event import trace_event
-
-
-class SharedState(object):
-  """A class that manages the test state across multiple stories.
-  It's styled on unittest.TestCase for handling test setup & teardown logic.
-
-  """
-
-  __metaclass__ = trace_event.TracedMetaClass
-
-  def __init__(self, test, options, story_set):
-    """ This method is styled on unittest.TestCase.setUpClass.
-    Override to do any action before running stories that
-    share this same state.
-    Args:
-      test: a legacy_page_test.LegacyPageTest or story_test.StoryTest instance.
-      options: a BrowserFinderOptions instance that contains command line
-        options.
-      story_set: a story.StorySet instance.
-    """
-    pass
-
-  @property
-  def platform(self):
-    """ Override to return the platform which stories that share this same
-    state will be run on.
-    """
-    raise NotImplementedError()
-
-  def WillRunStory(self, story):
-    """ Override to do any action before running each one of all stories
-    that share this same state.
-    This method is styled on unittest.TestCase.setUp.
-    """
-    raise NotImplementedError()
-
-  def DidRunStory(self, results):
-    """ Override to do any action after running each of all stories that
-    share this same state.
-    This method is styled on unittest.TestCase.tearDown.
-    """
-    raise NotImplementedError()
-
-  def CanRunStory(self, story):
-    """Indicate whether the story can be run in the current configuration.
-    This is called after WillRunStory and before RunStory. Return True
-    if the story should be run, and False if it should be skipped.
-    Most subclasses will probably want to override this to always
-    return True.
-    Args:
-      story: a story.Story instance.
-    """
-    raise NotImplementedError()
-
-  def RunStory(self, results):
-    """ Override to do any action before running each one of all stories
-    that share this same state.
-    This method is styled on unittest.TestCase.run.
-    """
-    raise NotImplementedError()
-
-  def TearDownState(self):
-    """ Override to do any action after running multiple stories that
-    share this same state.
-    This method is styled on unittest.TestCase.tearDownClass.
-    """
-    raise NotImplementedError()
-
-  def DumpStateUponFailure(self, story, results):
-    """ Dump the state upon failure.
-    This method tries to dump as much information about the application under
-    test as possible (output, log, screenshot, etc.) to simplify triaging the
-    failure.
-    """
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/story/story.py b/catapult/telemetry/telemetry/story/story.py
deleted file mode 100644
index 99a2ed9..0000000
--- a/catapult/telemetry/telemetry/story/story.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-from telemetry.story import shared_state as shared_state_module
-
-_next_story_id = 0
-
-
-class Story(object):
-  """A class styled on unittest.TestCase for creating story tests.
-
-  Tests should override Run to maybe start the application and perform actions
-  on it. To share state between different tests, one can define a
-  shared_state which contains hooks that will be called before and
-  after mutiple stories run and in between runs.
-
-  Args:
-    shared_state_class: subclass of telemetry.story.shared_state.SharedState.
-    name: string name of this story that can be used for identifying this story
-        in results output.
-    tags: A list or set of string labels that are used for filtering. See
-        story.story_filter for more information.
-    is_local: If True, the story does not require network.
-    grouping_keys: A dict of grouping keys that will be added to values computed
-        on this story.
-  """
-
-  def __init__(self, shared_state_class, name='', tags=None,
-               is_local=False, make_javascript_deterministic=True,
-               grouping_keys=None, platform_specific=False):
-    """
-    Args:
-      make_javascript_deterministic: Whether JavaScript performed on
-          the page is made deterministic across multiple runs. This
-          requires that the web content is served via Web Page Replay
-          to take effect. This setting does not affect stories containing no web
-          content or where the HTTP MIME type is not text/html.See also:
-          _InjectScripts method in third_party/web-page-replay/httpclient.py.
-      platform_specific: Boolean indicating if a separate web page replay
-          recording is required on each platform.
-    """
-    assert issubclass(shared_state_class,
-                      shared_state_module.SharedState)
-    self._shared_state_class = shared_state_class
-    self._name = name
-    self._platform_specific = platform_specific
-    global _next_story_id
-    self._id = _next_story_id
-    _next_story_id += 1
-    if tags is None:
-      tags = set()
-    elif isinstance(tags, list):
-      tags = set(tags)
-    else:
-      assert isinstance(tags, set)
-    self._tags = tags
-    self._is_local = is_local
-    self._make_javascript_deterministic = make_javascript_deterministic
-    if grouping_keys is None:
-      grouping_keys = {}
-    else:
-      assert isinstance(grouping_keys, dict)
-    self._grouping_keys = grouping_keys
-
-  def Run(self, shared_state):
-    """Execute the interactions with the applications and/or platforms."""
-    raise NotImplementedError
-
-  @property
-  def tags(self):
-    return self._tags
-
-  @property
-  def shared_state_class(self):
-    return self._shared_state_class
-
-  @property
-  def id(self):
-    return self._id
-
-  @property
-  def name(self):
-    return self._name
-
-  @property
-  def grouping_keys(self):
-    return self._grouping_keys
-
-  @property
-  def display_name_and_grouping_key_tuple(self):
-    return self.display_name, tuple(self.grouping_keys.iteritems())
-
-  def AsDict(self):
-    """Converts a story object to a dict suitable for JSON output."""
-    d = {
-      'id': self._id,
-    }
-    if self._name:
-      d['name'] = self._name
-    return d
-
-  @property
-  def file_safe_name(self):
-    """A version of display_name that's safe to use as a filename.
-
-    The default implementation sanitizes special characters with underscores,
-    but it's okay to override it with a more specific implementation in
-    subclasses.
-    """
-    # This fail-safe implementation is safe for subclasses to override.
-    return re.sub('[^a-zA-Z0-9]', '_', self.display_name)
-
-  @property
-  def display_name(self):
-    if self.name:
-      return self.name
-    else:
-      return self.__class__.__name__
-
-  @property
-  def is_local(self):
-    """Returns True iff this story does not require network."""
-    return self._is_local
-
-  @property
-  def serving_dir(self):
-    """Returns the absolute path to a directory with hash files to data that
-       should be updated from cloud storage, or None if no files need to be
-       updated.
-    """
-    return None
-
-  @property
-  def make_javascript_deterministic(self):
-    return self._make_javascript_deterministic
-
-  @property
-  def platform_specific(self):
-    return self._platform_specific
diff --git a/catapult/telemetry/telemetry/story/story_filter.py b/catapult/telemetry/telemetry/story/story_filter.py
deleted file mode 100644
index 1bbb528..0000000
--- a/catapult/telemetry/telemetry/story/story_filter.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-import re
-
-from telemetry.internal.util import command_line
-
-
-class _StoryMatcher(object):
-  def __init__(self, pattern):
-    self._regex = None
-    self.has_compile_error = False
-    if pattern:
-      try:
-        self._regex = re.compile(pattern)
-      except re.error:
-        self.has_compile_error = True
-
-  def __nonzero__(self):
-    return self._regex is not None
-
-  def HasMatch(self, story):
-    return self and bool(
-        self._regex.search(story.display_name) or
-        (story.name and self._regex.search(story.name)))
-
-
-class _StoryTagMatcher(object):
-  def __init__(self, tags_str):
-    self._tags = tags_str.split(',') if tags_str else None
-
-  def __nonzero__(self):
-    return self._tags is not None
-
-  def HasLabelIn(self, story):
-    return self and bool(story.tags.intersection(self._tags))
-
-
-class StoryFilter(command_line.ArgumentHandlerMixIn):
-  """Filters stories in the story set based on command-line flags."""
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser):
-    group = optparse.OptionGroup(parser, 'User story filtering options')
-    group.add_option('--story-filter',
-        help='Use only stories whose names match the given filter regexp.')
-    group.add_option('--story-filter-exclude',
-        help='Exclude stories whose names match the given filter regexp.')
-    group.add_option('--story-tag-filter',
-        help='Use only stories that have any of these tags')
-    group.add_option('--story-tag-filter-exclude',
-        help='Exclude stories that have any of these tags')
-    parser.add_option_group(group)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args):
-    cls._include_regex = _StoryMatcher(args.story_filter)
-    cls._exclude_regex = _StoryMatcher(args.story_filter_exclude)
-
-    cls._include_tags = _StoryTagMatcher(args.story_tag_filter)
-    cls._exclude_tags = _StoryTagMatcher(args.story_tag_filter_exclude)
-
-    if cls._include_regex.has_compile_error:
-      raise parser.error('--story-filter: Invalid regex.')
-    if cls._exclude_regex.has_compile_error:
-      raise parser.error('--story-filter-exclude: Invalid regex.')
-
-  @classmethod
-  def IsSelected(cls, story):
-    # Exclude filters take priority.
-    if cls._exclude_tags.HasLabelIn(story):
-      return False
-    if cls._exclude_regex.HasMatch(story):
-      return False
-
-    if cls._include_tags and not cls._include_tags.HasLabelIn(story):
-      return False
-    if cls._include_regex and not cls._include_regex.HasMatch(story):
-      return False
-    return True
diff --git a/catapult/telemetry/telemetry/story/story_filter_unittest.py b/catapult/telemetry/telemetry/story/story_filter_unittest.py
deleted file mode 100644
index 2df8bc3..0000000
--- a/catapult/telemetry/telemetry/story/story_filter_unittest.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import story
-from telemetry.page import page
-from telemetry.story import story_filter as story_filter_module
-
-
-class FilterTest(unittest.TestCase):
-
-  def setUp(self):
-    story_set = story.StorySet()
-    self.p1 = page.Page(
-      url='file://your/smile/widen.html', page_set=story_set,
-      name='MayYour.smile_widen', tags=['tag1', 'tag2'])
-    self.p2 = page.Page(
-      url='file://share_a/smile/too.html', page_set=story_set,
-      name='ShareA.smiles_too', tags=['tag1'])
-    self.p3 = page.Page(
-      url='file://share_a/smile/too.html', page_set=story_set,
-      tags=['tag2'])
-    self.pages = [self.p1, self.p2, self.p3]
-
-  @staticmethod
-  def ProcessCommandLineArgs(parser=None, **kwargs):
-    class Options(object):
-      def __init__(
-          self, story_filter=None, story_filter_exclude=None,
-          story_tag_filter=None, story_tag_filter_exclude=None):
-        self.story_filter = story_filter
-        self.story_filter_exclude = story_filter_exclude
-        self.story_tag_filter = story_tag_filter
-        self.story_tag_filter_exclude = story_tag_filter_exclude
-    story_filter_module.StoryFilter.ProcessCommandLineArgs(
-        parser, Options(**kwargs))
-
-  def PageSelections(self):
-    return [story_filter_module.StoryFilter.IsSelected(p) for p in self.pages]
-
-  def testNoFilterMatchesAll(self):
-    self.ProcessCommandLineArgs()
-    self.assertEquals([True, True, True], self.PageSelections())
-
-  def testBadRegexCallsParserError(self):
-    class MockParserException(Exception):
-      pass
-    class MockParser(object):
-      def error(self, _):
-        raise MockParserException
-    with self.assertRaises(MockParserException):
-      self.ProcessCommandLineArgs(parser=MockParser(), story_filter='+')
-
-  def testUniqueSubstring(self):
-    self.ProcessCommandLineArgs(story_filter='smile_widen')
-    self.assertEquals([True, False, False], self.PageSelections())
-
-  def testSharedSubstring(self):
-    self.ProcessCommandLineArgs(story_filter='smile')
-    self.assertEquals([True, True, True], self.PageSelections())
-
-  def testNoMatch(self):
-    self.ProcessCommandLineArgs(story_filter='frown')
-    self.assertEquals([False, False, False], self.PageSelections())
-
-  def testExclude(self):
-    self.ProcessCommandLineArgs(story_filter_exclude='ShareA')
-    self.assertEquals([True, False, True], self.PageSelections())
-
-  def testExcludeTakesPriority(self):
-    self.ProcessCommandLineArgs(
-        story_filter='smile',
-        story_filter_exclude='wide')
-    self.assertEquals([False, True, True], self.PageSelections())
-
-  def testNoNameMatchesDisplayName(self):
-    self.ProcessCommandLineArgs(story_filter='share_a/smile')
-    self.assertEquals([False, False, True], self.PageSelections())
-
-  def testNotagMatch(self):
-    self.ProcessCommandLineArgs(story_tag_filter='tagX')
-    self.assertEquals([False, False, False], self.PageSelections())
-
-  def testtagsAllMatch(self):
-    self.ProcessCommandLineArgs(story_tag_filter='tag1,tag2')
-    self.assertEquals([True, True, True], self.PageSelections())
-
-  def testExcludetagTakesPriority(self):
-    self.ProcessCommandLineArgs(
-        story_tag_filter='tag1',
-        story_tag_filter_exclude='tag2')
-    self.assertEquals([False, True, False], self.PageSelections())
diff --git a/catapult/telemetry/telemetry/story/story_set.py b/catapult/telemetry/telemetry/story/story_set.py
deleted file mode 100644
index bae72ab..0000000
--- a/catapult/telemetry/telemetry/story/story_set.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import inspect
-import os
-
-from telemetry.story import story as story_module
-from telemetry.wpr import archive_info
-
-
-class StorySet(object):
-  """A collection of stories.
-
-  A typical usage of StorySet would be to subclass it and then call
-  AddStory for each Story.
-  """
-
-  def __init__(self, archive_data_file='', cloud_storage_bucket=None,
-               base_dir=None, serving_dirs=None):
-    """Creates a new StorySet.
-
-    Args:
-      archive_data_file: The path to Web Page Replay's archive data, relative
-          to self.base_dir.
-      cloud_storage_bucket: The cloud storage bucket used to download
-          Web Page Replay's archive data. Valid values are: None,
-          story.PUBLIC_BUCKET, story.PARTNER_BUCKET, or story.INTERNAL_BUCKET
-          (defined in telemetry.util.cloud_storage).
-      serving_dirs: A set of paths, relative to self.base_dir, to directories
-          containing hash files for non-wpr archive data stored in cloud
-          storage.
-    """
-    self._stories = []
-    self._story_names_and_grouping_keys = set()
-    self._archive_data_file = archive_data_file
-    self._wpr_archive_info = None
-    archive_info.AssertValidCloudStorageBucket(cloud_storage_bucket)
-    self._cloud_storage_bucket = cloud_storage_bucket
-    if base_dir:
-      if not os.path.isdir(base_dir):
-        raise ValueError('Invalid directory path of base_dir: %s' % base_dir)
-      self._base_dir = base_dir
-    else:
-      self._base_dir = os.path.dirname(inspect.getfile(self.__class__))
-    # Convert any relative serving_dirs to absolute paths.
-    self._serving_dirs = set(os.path.realpath(os.path.join(self.base_dir, d))
-                             for d in serving_dirs or [])
-
-  @property
-  def allow_mixed_story_states(self):
-    """True iff Stories are allowed to have different StoryState classes.
-
-    There are no checks in place for determining if SharedStates are
-    being assigned correctly to all Stories in a given StorySet. The
-    majority of test cases should not need the ability to have multiple
-    SharedStates, which usually implies you should be writing multiple
-    benchmarks instead. We provide errors to avoid accidentally assigning
-    or defaulting to the wrong SharedState.
-    Override at your own risk. Here be dragons.
-    """
-    return False
-
-  @property
-  def file_path(self):
-    return inspect.getfile(self.__class__).replace('.pyc', '.py')
-
-  @property
-  def base_dir(self):
-    """The base directory to resolve archive_data_file.
-
-    This defaults to the directory containing the StorySet instance's class.
-    """
-    return self._base_dir
-
-  @property
-  def serving_dirs(self):
-    all_serving_dirs = self._serving_dirs.copy()
-    for story in self.stories:
-      if story.serving_dir:
-        all_serving_dirs.add(story.serving_dir)
-    return all_serving_dirs
-
-  @property
-  def archive_data_file(self):
-    return self._archive_data_file
-
-  @property
-  def bucket(self):
-    return self._cloud_storage_bucket
-
-  @property
-  def wpr_archive_info(self):
-    """Lazily constructs wpr_archive_info if it's not set and returns it."""
-    if self.archive_data_file and not self._wpr_archive_info:
-      self._wpr_archive_info = archive_info.WprArchiveInfo.FromFile(
-          os.path.join(self.base_dir, self.archive_data_file), self.bucket)
-    return self._wpr_archive_info
-
-  @property
-  def stories(self):
-    return self._stories
-
-  def AddStory(self, story):
-    assert isinstance(story, story_module.Story)
-    assert self._IsUnique(story), ('Tried to add story with duplicate display '
-                                   'name %s. Story display names should be '
-                                   'unique.' % story.display_name)
-    self._stories.append(story)
-    self._story_names_and_grouping_keys.add(
-        story.display_name_and_grouping_key_tuple)
-
-  def _IsUnique(self, story):
-    return (story.display_name_and_grouping_key_tuple not in
-            self._story_names_and_grouping_keys)
-
-  def RemoveStory(self, story):
-    """Removes a Story.
-
-    Allows the stories to be filtered.
-    """
-    self._stories.remove(story)
-    self._story_names_and_grouping_keys.remove(
-        story.display_name_and_grouping_key_tuple)
-
-  @classmethod
-  def Name(cls):
-    """Returns the string name of this StorySet.
-    Note that this should be a classmethod so the benchmark_runner script can
-    match the story class with its name specified in the run command:
-    'Run <User story test name> <User story class name>'
-    """
-    return cls.__module__.split('.')[-1]
-
-  @classmethod
-  def Description(cls):
-    """Return a string explaining in human-understandable terms what this
-    story represents.
-    Note that this should be a classmethod so the benchmark_runner script can
-    display stories' names along with their descriptions in the list command.
-    """
-    if cls.__doc__:
-      return cls.__doc__.splitlines()[0]
-    else:
-      return ''
-
-  def WprFilePathForStory(self, story, target_platform=None):
-    """Convenient function to retrieve WPR archive file path.
-
-    Args:
-      story: The Story to look up.
-
-    Returns:
-      The WPR archive file path for the given Story, if found.
-      Otherwise, None.
-    """
-    if not self.wpr_archive_info:
-      return None
-    return self.wpr_archive_info.WprFilePathForStory(
-        story, target_platform=target_platform)
-
-  def __iter__(self):
-    return self.stories.__iter__()
-
-  def __len__(self):
-    return len(self.stories)
-
-  def __getitem__(self, key):
-    return self.stories[key]
-
-  def __setitem__(self, key, value):
-    self._stories[key] = value
diff --git a/catapult/telemetry/telemetry/story/story_set_unittest.py b/catapult/telemetry/telemetry/story/story_set_unittest.py
deleted file mode 100644
index b6710c6..0000000
--- a/catapult/telemetry/telemetry/story/story_set_unittest.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry import story
-
-
-# pylint: disable=abstract-method
-class SharedStateBar(story.SharedState):
-  pass
-
-
-class StoryFoo(story.Story):
-  def __init__(self, name='', labels=None, grouping_keys=None):
-    super(StoryFoo, self).__init__(
-        SharedStateBar, name, labels, grouping_keys=grouping_keys)
-
-
-class StorySetFoo(story.StorySet):
-  """ StorySetFoo is a story set created for testing purpose. """
-  pass
-
-
-class StorySetTest(unittest.TestCase):
-
-  def testStorySetTestName(self):
-    self.assertEquals('story_set_unittest', StorySetFoo.Name())
-
-  def testStorySetTestDescription(self):
-    self.assertEquals(
-        ' StorySetFoo is a story set created for testing purpose. ',
-        StorySetFoo.Description())
-
-  def testBaseDir(self):
-    story_set = StorySetFoo()
-    base_dir = story_set.base_dir
-    self.assertTrue(os.path.isdir(base_dir))
-    self.assertEqual(base_dir, os.path.dirname(__file__))
-
-  def testFilePath(self):
-    story_set = StorySetFoo()
-    self.assertEqual(os.path.abspath(__file__).replace('.pyc', '.py'),
-                     story_set.file_path)
-
-  def testCloudBucket(self):
-    blank_story_set = story.StorySet()
-    self.assertEqual(blank_story_set.bucket, None)
-
-    public_story_set = story.StorySet(
-        cloud_storage_bucket=story.PUBLIC_BUCKET)
-    self.assertEqual(public_story_set.bucket, story.PUBLIC_BUCKET)
-
-    partner_story_set = story.StorySet(
-        cloud_storage_bucket=story.PARTNER_BUCKET)
-    self.assertEqual(partner_story_set.bucket, story.PARTNER_BUCKET)
-
-    internal_story_set = story.StorySet(
-        cloud_storage_bucket=story.INTERNAL_BUCKET)
-    self.assertEqual(internal_story_set.bucket, story.INTERNAL_BUCKET)
-
-    with self.assertRaises(ValueError):
-      story.StorySet(cloud_storage_bucket='garbage_bucket')
-
-  def testRemoveWithEmptySetRaises(self):
-    story_set = story.StorySet()
-    foo_story = StoryFoo()
-    with self.assertRaises(ValueError):
-      story_set.RemoveStory(foo_story)
-
-  def testBasicAddRemove(self):
-    story_set = story.StorySet()
-    foo_story = StoryFoo()
-    story_set.AddStory(foo_story)
-    self.assertEqual([foo_story], story_set.stories)
-
-    story_set.RemoveStory(foo_story)
-    self.assertEqual([], story_set.stories)
-
-  def testAddDuplicateDisplayNameWithoutGroupingKeysRaises(self):
-    story_set = story.StorySet()
-    foo_story = StoryFoo(name='foo')
-
-    story_set.AddStory(foo_story)
-
-    with self.assertRaises(AssertionError):
-      story_set.AddStory(foo_story)
-
-  def testAddDuplicateDisplayNameWithDifferentGroupingKeys(self):
-    story_set = story.StorySet()
-    foo_story0 = StoryFoo(name='foo', grouping_keys={
-        'bar': 3, 'baz': 4})
-    foo_story1 = StoryFoo(name='foo', grouping_keys={
-        'bar': 7, 'baz': 8})
-
-    story_set.AddStory(foo_story0)
-    story_set.AddStory(foo_story1)
-
-  def testAddDuplicateDisplayNameWithSameGroupingKeysRaises(self):
-    story_set = story.StorySet()
-    foo_story0 = StoryFoo(name='foo', grouping_keys={
-        'bar': 3, 'baz': 4})
-    foo_story1 = StoryFoo(name='foo', grouping_keys={
-        'bar': 3, 'baz': 4})
-
-    story_set.AddStory(foo_story0)
-
-    with self.assertRaises(AssertionError):
-      story_set.AddStory(foo_story1)
-
-  def testAddRemoveAddStoryIsStillUnique(self):
-    story_set = story.StorySet()
-    foo_story = StoryFoo(name='foo', grouping_keys={
-        'bar': 3, 'baz': 4})
-
-    story_set.AddStory(foo_story)
-    story_set.RemoveStory(foo_story)
-    story_set.AddStory(foo_story)
diff --git a/catapult/telemetry/telemetry/story/story_unittest.py b/catapult/telemetry/telemetry/story/story_unittest.py
deleted file mode 100644
index 9bc18b5..0000000
--- a/catapult/telemetry/telemetry/story/story_unittest.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import story
-from telemetry.story import shared_state
-
-
-# pylint: disable=abstract-method
-class SharedStateBar(shared_state.SharedState):
-  pass
-
-
-class StoryFoo(story.Story):
-  def __init__(self, name='', tags=None):
-    super(StoryFoo, self).__init__(
-        SharedStateBar, name, tags)
-
-
-class StoryTest(unittest.TestCase):
-  def testStoriesHaveDifferentIds(self):
-    s0 = story.Story(SharedStateBar, 'foo')
-    s1 = story.Story(SharedStateBar, 'bar')
-    self.assertNotEqual(s0.id, s1.id)
-
-  def testNamelessStoryDisplayName(self):
-    s = StoryFoo()
-    self.assertEquals('StoryFoo', s.display_name)
-
-  def testNamedStoryDisplayName(self):
-    s = StoryFoo('Bar')
-    self.assertEquals('Bar', s.display_name)
-
-  def testStoryFileSafeName(self):
-    s = StoryFoo('Foo Bar:Baz~0')
-    self.assertEquals('Foo_Bar_Baz_0', s.file_safe_name)
-
-  def testNamelessStoryAsDict(self):
-    s = story.Story(SharedStateBar)
-    s_dict = s.AsDict()
-    self.assertEquals(s_dict['id'], s.id)
-    self.assertNotIn('name', s_dict)
-
-  def testNamedStoryAsDict(self):
-    s = story.Story(SharedStateBar, 'Foo')
-    s_dict = s.AsDict()
-    self.assertEquals(s_dict['id'], s.id)
-    self.assertEquals('Foo', s_dict['name'])
-
-  def testMakeJavaScriptDeterministic(self):
-    s = story.Story(SharedStateBar)
-    self.assertTrue(s.make_javascript_deterministic)
-
-    s = story.Story(SharedStateBar, make_javascript_deterministic=False)
-    self.assertFalse(s.make_javascript_deterministic)
-
-    s = story.Story(SharedStateBar, make_javascript_deterministic=True)
-    self.assertTrue(s.make_javascript_deterministic)
diff --git a/catapult/telemetry/telemetry/telemetry_unittest_deps.json b/catapult/telemetry/telemetry/telemetry_unittest_deps.json
deleted file mode 100644
index 429493b..0000000
--- a/catapult/telemetry/telemetry/telemetry_unittest_deps.json
+++ /dev/null
@@ -1,27 +0,0 @@
-{
-  "config_type": "BaseConfig",
-  "dependencies": {
-    "example_domain_archive": {
-      "cloud_storage_base_folder": "wpr-archives",
-      "cloud_storage_bucket": "chromium-telemetry",
-      "file_info": {
-        "linux_x86_64": {
-          "cloud_storage_hash": "5e49b8152e40b5df427a8e73062045ddde2edcb8",
-          "download_path": "internal/testing/test_page_sets/data/example_domain_001.wpr"
-        },
-        "mac_x86_64": {
-          "cloud_storage_hash": "5e49b8152e40b5df427a8e73062045ddde2edcb8",
-          "download_path": "internal/testing/test_page_sets/data/example_domain_001.wpr"
-        },
-        "win_AMD64": {
-          "cloud_storage_hash": "5e49b8152e40b5df427a8e73062045ddde2edcb8",
-          "download_path": "internal/testing/test_page_sets/data/example_domain_001.wpr"
-        },
-        "win_x86": {
-          "cloud_storage_hash": "5e49b8152e40b5df427a8e73062045ddde2edcb8",
-          "download_path": "internal/testing/test_page_sets/data/example_domain_001.wpr"
-        }
-      }
-    }
-  }
-}
\ No newline at end of file
diff --git a/catapult/telemetry/telemetry/testing/__init__.py b/catapult/telemetry/telemetry/testing/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/catapult/telemetry/telemetry/testing/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/testing/browser_test_case.py b/catapult/telemetry/telemetry/testing/browser_test_case.py
deleted file mode 100644
index 956e5d8..0000000
--- a/catapult/telemetry/telemetry/testing/browser_test_case.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from functools import wraps
-import logging
-import os
-import sys
-import types
-import unittest
-
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.util import path
-from telemetry.testing import options_for_unittests
-
-current_browser_options = None
-current_browser = None
-
-
-class _MetaBrowserTestCase(type):
-  """Metaclass for BrowserTestCase.
-
-  The metaclass wraps all test* methods of all subclasses of BrowserTestCase to
-  print browser standard output and log upon failure.
-  """
-
-  def __new__(mcs, name, bases, dct):
-    new_dct = {}
-    for attributeName, attribute in dct.iteritems():
-      if (isinstance(attribute, types.FunctionType) and
-          attributeName.startswith('test')):
-        attribute = mcs._PrintBrowserStandardOutputAndLogOnFailure(attribute)
-      new_dct[attributeName] = attribute
-    return type.__new__(mcs, name, bases, new_dct)
-
-  @staticmethod
-  def _PrintBrowserStandardOutputAndLogOnFailure(method):
-    @wraps(method)
-    def WrappedMethod(self):
-      try:  # pylint: disable=broad-except
-        method(self)
-      except Exception:
-        exc_info = sys.exc_info()
-
-        if self._browser:
-          self._browser.DumpStateUponFailure()
-        else:
-          logging.warning('Cannot dump browser state: No browser.')
-
-        # Re-raise the original exception. Note that we can't just use 'raise'
-        # without any arguments because an exception might have been thrown when
-        # dumping the state of the browser.
-        raise exc_info[0], exc_info[1], exc_info[2]
-    return WrappedMethod
-
-
-def teardown_browser():
-  global current_browser
-  global current_browser_options
-
-  if current_browser:
-    current_browser.Close()
-    current_browser.platform.network_controller.Close()
-  current_browser = None
-  current_browser_options = None
-
-
-class BrowserTestCase(unittest.TestCase):
-  __metaclass__ = _MetaBrowserTestCase
-
-  @classmethod
-  def setUpClass(cls):
-    cls._platform = None
-    global current_browser
-    global current_browser_options
-
-    options = options_for_unittests.GetCopy()
-
-    cls.CustomizeBrowserOptions(options.browser_options)
-    if not current_browser or (current_browser_options !=
-                               options.browser_options):
-      if current_browser:
-        teardown_browser()
-
-      browser_to_create = browser_finder.FindBrowser(options)
-      if not browser_to_create:
-        raise Exception('No browser found, cannot continue test.')
-      cls._platform = browser_to_create.platform
-      cls._platform.network_controller.InitializeIfNeeded()
-
-      try:
-        current_browser = browser_to_create.Create(options)
-        current_browser_options = options.browser_options
-      except:
-        cls.tearDownClass()
-        raise
-    cls._browser = current_browser
-    cls._device = options.remote_platform_options.device
-
-  @classmethod
-  def tearDownClass(cls):
-    if cls._platform:
-      cls._platform.StopAllLocalServers()
-      cls._platform.network_controller.Close()
-
-  @classmethod
-  def CustomizeBrowserOptions(cls, options):
-    """Override to add test-specific options to the BrowserOptions object"""
-    pass
-
-  @classmethod
-  def UrlOfUnittestFile(cls, filename):
-    cls._platform.SetHTTPServerDirectories(path.GetUnittestDataDir())
-    file_path = os.path.join(path.GetUnittestDataDir(), filename)
-    return cls._platform.http_server.UrlOf(file_path)
diff --git a/catapult/telemetry/telemetry/testing/browser_test_context.py b/catapult/telemetry/telemetry/testing/browser_test_context.py
deleted file mode 100644
index f119372..0000000
--- a/catapult/telemetry/telemetry/testing/browser_test_context.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import copy
-import sets
-
-
-_global_test_context = None
-
-
-def GetCopy():
-  return copy.deepcopy(_global_test_context)
-
-
-class TypTestContext(object):
-  """ The TestContext that is used for passing data from the main test process
-  to typ's subprocesses. Those includes:
-     _ client_configs: list of client configs that contain infos about binaries
-        to use.
-     _ finder_options: the commandline options object. This is an instance of
-        telemetry.internal.browser.browser_options.BrowserFinderOptions.
-     _ test_class: the name of the test class to be run.
-     _ test_case_ids_to_run: the ids of the test cases to be run. e.g:
-        foo.bar.Test1, foo.bar.Test2,..
-
-
-  This object is designed to be pickle-able so that it can be easily pass from
-  the main process to test subprocesses. It also supports immutable mode to
-  ensure its data won't be changed by the subprocesses.
-  """
-  def __init__(self):
-    self._client_configs = []
-    self._finder_options = None
-    self._test_class = None
-    self._test_cases_ids_to_run = set()
-    self._frozen = False
-
-  def Freeze(self):
-    """ Makes the |self| object immutable.
-
-    Calling setter on |self|'s property will throw exception.
-    """
-    assert self._finder_options
-    assert self._test_class
-    self._frozen = True
-    self._test_cases_ids_to_run = sets.ImmutableSet(self._test_cases_ids_to_run)
-    self._client_configs = tuple(self._client_configs)
-
-  @property
-  def finder_options(self):
-    return self._finder_options
-
-  @property
-  def client_configs(self):
-    return self._client_configs
-
-  @property
-  def test_class(self):
-    return self._test_class
-
-  @property
-  def test_case_ids_to_run(self):
-    return self._test_cases_ids_to_run
-
-  @finder_options.setter
-  def finder_options(self, value):
-    assert not self._frozen
-    self._finder_options = value
-
-  @test_class.setter
-  def test_class(self, value):
-    assert not self._test_class
-    self._test_class = value
diff --git a/catapult/telemetry/telemetry/testing/browser_test_runner.py b/catapult/telemetry/telemetry/testing/browser_test_runner.py
deleted file mode 100644
index 5d883c8..0000000
--- a/catapult/telemetry/telemetry/testing/browser_test_runner.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import subprocess
-import sys
-
-from telemetry.core import util
-
-
-def Run(project_config, args):
-  assert '--top-level-dir' not in args, (
-      'Top level directory for running tests should be specified through '
-      'the instance of telemetry.project_config.ProjectConfig.')
-  assert '--client-config' not in args, (
-      'Client config file to be used for telemetry should be specified through '
-      'the instance of telemetry.project_config.ProjectConfig.')
-  assert project_config.top_level_dir, 'Must specify top level dir for project'
-  args.extend(['--top-level-dir', project_config.top_level_dir])
-  for c in project_config.client_configs:
-    args.extend(['--client-config', c])
-  for s in project_config.start_dirs:
-    args.extend(['--start-dir', s])
-
-  if project_config.default_chrome_root and not '--chrome-root' in args:
-    args.extend(['--chrome-root', project_config.default_chrome_root])
-
-  env = os.environ.copy()
-  telemetry_dir = util.GetTelemetryDir()
-  if 'PYTHONPATH' in env:
-    env['PYTHONPATH'] = os.pathsep.join([env['PYTHONPATH'], telemetry_dir])
-  else:
-    env['PYTHONPATH'] = telemetry_dir
-
-  path_to_run_tests = os.path.join(os.path.abspath(os.path.dirname(__file__)),
-                                   'run_browser_tests.py')
-  return subprocess.call([sys.executable, path_to_run_tests] + args, env=env)
diff --git a/catapult/telemetry/telemetry/testing/browser_test_runner_unittest.py b/catapult/telemetry/telemetry/testing/browser_test_runner_unittest.py
deleted file mode 100644
index d3439bb..0000000
--- a/catapult/telemetry/telemetry/testing/browser_test_runner_unittest.py
+++ /dev/null
@@ -1,399 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import string
-import sys
-import tempfile
-import unittest
-import json
-
-from telemetry import decorators
-from telemetry import project_config
-from telemetry.core import util
-from telemetry.testing import browser_test_context
-from telemetry.testing import browser_test_runner
-from telemetry.testing import options_for_unittests
-from telemetry.testing import run_browser_tests
-from telemetry.testing import serially_executed_browser_test_case
-
-
-class BrowserTestRunnerTest(unittest.TestCase):
-
-  def _ExtractTestResults(self, test_result):
-    delimiter = test_result['path_delimiter']
-    failures = []
-    successes = []
-    def _IsLeafNode(node):
-      test_dict = node[1]
-      return ('expected' in test_dict and
-              isinstance(test_dict['expected'], basestring))
-    node_queues = []
-    for t in test_result['tests']:
-      node_queues.append((t, test_result['tests'][t]))
-    while node_queues:
-      node = node_queues.pop()
-      full_test_name, test_dict = node
-      if _IsLeafNode(node):
-        if all(res not in test_dict['expected'].split() for res in
-               test_dict['actual'].split()):
-          failures.append(full_test_name)
-        else:
-          successes.append(full_test_name)
-      else:
-        for k in test_dict:
-          node_queues.append(
-            ('%s%s%s' % (full_test_name, delimiter, k),
-             test_dict[k]))
-    return successes, failures
-
-  def baseTest(self, test_filter,
-               failures, successes, test_name='SimpleTest'):
-    config = project_config.ProjectConfig(
-        top_level_dir=os.path.join(util.GetTelemetryDir(), 'examples'),
-        client_configs=[],
-        benchmark_dirs=[
-            os.path.join(util.GetTelemetryDir(), 'examples', 'browser_tests')]
-    )
-    temp_file = tempfile.NamedTemporaryFile(delete=False)
-    temp_file.close()
-    temp_file_name = temp_file.name
-    try:
-      browser_test_runner.Run(
-          config,
-          [test_name,
-           '--write-full-results-to=%s' % temp_file_name,
-           '--test-filter=%s' % test_filter])
-      with open(temp_file_name) as f:
-        test_result = json.load(f)
-
-      actual_successes, actual_failures = self._ExtractTestResults(test_result)
-      self.assertEquals(set(actual_failures), set(failures))
-      self.assertEquals(set(actual_successes), set(successes))
-    finally:
-      os.remove(temp_file_name)
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testJsonOutputFormatNegativeFilter(self):
-    self.baseTest(
-      '^(add|multiplier).*',
-      ['browser_tests.simple_numeric_test.SimpleTest.add_1_and_2',
-       'browser_tests.simple_numeric_test.SimpleTest.add_7_and_3',
-       'browser_tests.simple_numeric_test.SimpleTest.multiplier_simple_2'],
-      ['browser_tests.simple_numeric_test.SimpleTest.add_2_and_3',
-       'browser_tests.simple_numeric_test.SimpleTest.multiplier_simple',
-       'browser_tests.simple_numeric_test.SimpleTest.multiplier_simple_3'])
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testJsonOutputWhenSetupClassFailed(self):
-    self.baseTest(
-      '.*',
-      ['browser_tests.failed_tests.SetUpClassFailedTest.dummy_test_0',
-       'browser_tests.failed_tests.SetUpClassFailedTest.dummy_test_1',
-       'browser_tests.failed_tests.SetUpClassFailedTest.dummy_test_2'],
-      [], test_name='SetUpClassFailedTest')
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testJsonOutputWhenTearDownClassFailed(self):
-    self.baseTest(
-      '.*',
-      ['browser_tests.failed_tests.TearDownClassFailedTest.dummy_test_0',
-       'browser_tests.failed_tests.TearDownClassFailedTest.dummy_test_1',
-       'browser_tests.failed_tests.TearDownClassFailedTest.dummy_test_2'],
-      [], test_name='TearDownClassFailedTest')
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testSetUpProcessCalledOnce(self):
-    self.baseTest(
-      '.*',
-      [],
-      ['browser_tests.process_tests.FailIfSetUpProcessCalledTwice.Dummy_0',
-       'browser_tests.process_tests.FailIfSetUpProcessCalledTwice.Dummy_1',
-       'browser_tests.process_tests.FailIfSetUpProcessCalledTwice.Dummy_2'],
-      test_name='FailIfSetUpProcessCalledTwice')
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testTearDownProcessCalledOnce(self):
-    self.baseTest(
-      '.*',
-      [],
-      ['browser_tests.process_tests.FailIfTearDownProcessCalledTwice.Dummy_0',
-       'browser_tests.process_tests.FailIfTearDownProcessCalledTwice.Dummy_1',
-       'browser_tests.process_tests.FailIfTearDownProcessCalledTwice.Dummy_2'],
-      test_name='FailIfTearDownProcessCalledTwice')
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testJsonOutputFormatPositiveFilter(self):
-    self.baseTest(
-      '(TestSimple|TestException).*',
-      ['browser_tests.simple_numeric_test.SimpleTest.TestException',
-       'browser_tests.simple_numeric_test.SimpleTest.TestSimple'], [])
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testExecutingTestsInSortedOrder(self):
-    alphabetical_tests = []
-    prefix = 'browser_tests.simple_numeric_test.SimpleTest.Alphabetical_'
-    for i in xrange(20):
-      alphabetical_tests.append(prefix + str(i))
-    for c in string.uppercase[:26]:
-      alphabetical_tests.append(prefix + c)
-    for c in string.lowercase[:26]:
-      alphabetical_tests.append(prefix + c)
-    alphabetical_tests.sort()
-    self.baseTest(
-        'Alphabetical', [], alphabetical_tests)
-
-  def shardingRangeTestHelper(self, total_shards, num_tests):
-    shard_ranges = []
-    for shard_index in xrange(0, total_shards):
-      shard_ranges.append(run_browser_tests._TestRangeForShard(
-        total_shards, shard_index, num_tests))
-    # Make assertions about ranges
-    num_tests_run = 0
-    for i in xrange(0, len(shard_ranges)):
-      cur_range = shard_ranges[i]
-      if i < num_tests:
-        self.assertGreater(cur_range[1], cur_range[0])
-        num_tests_run += (cur_range[1] - cur_range[0])
-      else:
-        # Not enough tests to go around all of the shards.
-        self.assertEquals(cur_range[0], cur_range[1])
-    # Make assertions about non-overlapping ranges
-    for i in xrange(1, len(shard_ranges)):
-      prev_range = shard_ranges[i - 1]
-      cur_range = shard_ranges[i]
-      self.assertEquals(prev_range[1], cur_range[0])
-    # Assert that we run all of the tests (very important)
-    self.assertEquals(num_tests_run, num_tests)
-
-  def testShardsWithPrimeNumTests(self):
-    for total_shards in xrange(1, 20):
-      # Nice non-prime number
-      self.shardingRangeTestHelper(total_shards, 101)
-
-  def testShardsWithDivisibleNumTests(self):
-    for total_shards in xrange(1, 6):
-      self.shardingRangeTestHelper(total_shards, 8)
-
-  def testShardBoundaryConditions(self):
-    self.shardingRangeTestHelper(1, 0)
-    self.shardingRangeTestHelper(1, 1)
-    self.shardingRangeTestHelper(2, 1)
-
-  def baseShardingTest(self, total_shards, shard_index, failures, successes,
-                       opt_abbr_input_json_file=None,
-                       opt_test_filter='',
-                       opt_filter_tests_after_sharding=False):
-    config = project_config.ProjectConfig(
-        top_level_dir=os.path.join(util.GetTelemetryDir(), 'examples'),
-        client_configs=[],
-        benchmark_dirs=[
-            os.path.join(util.GetTelemetryDir(), 'examples', 'browser_tests')]
-    )
-    temp_file = tempfile.NamedTemporaryFile(delete=False)
-    temp_file.close()
-    temp_file_name = temp_file.name
-    opt_args = []
-    if opt_abbr_input_json_file:
-      opt_args += [
-        '--read-abbreviated-json-results-from=%s' % opt_abbr_input_json_file]
-    if opt_test_filter:
-      opt_args += [
-        '--test-filter=%s' % opt_test_filter]
-    if opt_filter_tests_after_sharding:
-      opt_args += ['--filter-tests-after-sharding']
-    try:
-      browser_test_runner.Run(
-          config,
-          ['SimpleShardingTest',
-           '--write-full-results-to=%s' % temp_file_name,
-           '--total-shards=%d' % total_shards,
-           '--shard-index=%d' % shard_index] + opt_args)
-      with open(temp_file_name) as f:
-        test_result = json.load(f)
-      actual_successes, actual_failures = self._ExtractTestResults(test_result)
-      self.assertEquals(set(actual_failures), set(failures))
-      self.assertEquals(set(actual_successes), set(successes))
-    finally:
-      os.remove(temp_file_name)
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testShardedTestRun(self):
-    self.baseShardingTest(3, 0, [], [
-      'browser_tests.simple_sharding_test.SimpleShardingTest.Test1',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.Test2',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.Test3',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_0',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_1',
-    ])
-    self.baseShardingTest(3, 1, [], [
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_2',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_3',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_4',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_5',
-    ])
-    self.baseShardingTest(3, 2, [], [
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_6',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_7',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_8',
-      'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_9',
-    ])
-
-  def writeMockTestResultsFile(self):
-    mock_test_results = {
-      'passes': [
-        'Test1',
-        'Test2',
-        'Test3',
-        'passing_test_0',
-        'passing_test_1',
-        'passing_test_2',
-        'passing_test_3',
-        'passing_test_4',
-        'passing_test_5',
-        'passing_test_6',
-        'passing_test_7',
-        'passing_test_8',
-        'passing_test_9',
-      ],
-      'failures': [],
-      'valid': True,
-      'times': {
-        'Test1': 3.0,
-        'Test2': 3.0,
-        'Test3': 3.0,
-        'passing_test_0': 3.0,
-        'passing_test_1': 2.0,
-        'passing_test_2': 2.0,
-        'passing_test_3': 2.0,
-        'passing_test_4': 2.0,
-        'passing_test_5': 1.0,
-        'passing_test_6': 1.0,
-        'passing_test_7': 1.0,
-        'passing_test_8': 1.0,
-        'passing_test_9': 0.5,
-      }
-    }
-    temp_file = tempfile.NamedTemporaryFile(delete=False)
-    temp_file.close()
-    temp_file_name = temp_file.name
-    with open(temp_file_name, 'w') as f:
-      json.dump(mock_test_results, f)
-    return temp_file_name
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testSplittingShardsByTimes(self):
-    temp_file_name = self.writeMockTestResultsFile()
-    # It seems that the sorting order of the first four tests above is:
-    #   passing_test_0, Test1, Test2, Test3
-    # This is probably because the relative order of the "fixed" tests
-    # (starting with "Test") and the generated ones ("passing_") is
-    # not well defined, and the sorting is stable afterward.  The
-    # expectations have been adjusted for this fact.
-    try:
-      self.baseShardingTest(
-        4, 0, [],
-        ['browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_0',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_1',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_5',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_9'
-        ], temp_file_name)
-      self.baseShardingTest(
-        4, 1, [],
-        ['browser_tests.simple_sharding_test.SimpleShardingTest.Test1',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_2',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_6'
-        ], temp_file_name)
-      self.baseShardingTest(
-        4, 2, [],
-        ['browser_tests.simple_sharding_test.SimpleShardingTest.Test2',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_3',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_7'
-        ], temp_file_name)
-      self.baseShardingTest(
-        4, 3, [],
-        ['browser_tests.simple_sharding_test.SimpleShardingTest.Test3',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_4',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_8'
-        ], temp_file_name)
-    finally:
-      os.remove(temp_file_name)
-
-  @decorators.Disabled('chromeos')  # crbug.com/696553
-  def testFilteringAfterSharding(self):
-    temp_file_name = self.writeMockTestResultsFile()
-    try:
-      self.baseShardingTest(
-        4, 1, [],
-        ['browser_tests.simple_sharding_test.SimpleShardingTest.Test1',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_2',
-         'browser_tests.simple_sharding_test.SimpleShardingTest.passing_test_6'
-        ], temp_file_name,
-        opt_test_filter='(Test1|passing_test_2|passing_test_6)',
-        opt_filter_tests_after_sharding=True)
-    finally:
-      os.remove(temp_file_name)
-
-  def testMedianComputation(self):
-    self.assertEquals(2.0, run_browser_tests._MedianTestTime(
-      {'test1': 2.0, 'test2': 7.0, 'test3': 1.0}))
-    self.assertEquals(2.0, run_browser_tests._MedianTestTime(
-      {'test1': 2.0}))
-    self.assertEquals(0.0, run_browser_tests._MedianTestTime({}))
-    self.assertEqual(4.0, run_browser_tests._MedianTestTime(
-      {'test1': 2.0, 'test2': 6.0, 'test3': 1.0, 'test4': 8.0}))
-
-
-class Algebra(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  @classmethod
-  def GenerateTestCases_Simple(cls, options):
-    del options  # Unused.
-    yield 'testOne', (1, 2)
-    yield 'testTwo', (3, 3)
-
-  def Simple(self, x, y):
-    self.assertEquals(x, y)
-
-  def TestNumber(self):
-    self.assertEquals(0, 1)
-
-
-class ErrorneousGeometric(
-    serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-
-  @classmethod
-  def GenerateTestCases_Compare(cls, options):
-    del options  # Unused.
-    assert False, 'I am a problematic generator'
-    yield 'testBasic', ('square', 'circle')
-
-  def Compare(self, x, y):
-    self.assertEquals(x, y)
-
-  def TestAngle(self):
-    self.assertEquals(90, 450)
-
-class TestLoadAllTestModules(unittest.TestCase):
-  def testLoadAllTestsInModule(self):
-    context = browser_test_context.TypTestContext()
-    context.finder_options = options_for_unittests.GetCopy()
-    context.test_class = Algebra
-    context.test_case_ids_to_run.add(
-      'telemetry.testing.browser_test_runner_unittest.Algebra.TestNumber')
-    context.test_case_ids_to_run.add(
-      'telemetry.testing.browser_test_runner_unittest.Algebra.testOne')
-    context.Freeze()
-    browser_test_context._global_test_context = context
-    try:
-      # This should not invoke GenerateTestCases of ErrorneousGeometric class,
-      # otherwise that would throw Exception.
-      tests = serially_executed_browser_test_case.LoadAllTestsInModule(
-          sys.modules[__name__])
-      self.assertEquals(sorted([t.id() for t in tests]),
-          ['telemetry.testing.browser_test_runner_unittest.Algebra.TestNumber',
-           'telemetry.testing.browser_test_runner_unittest.Algebra.testOne'])
-    finally:
-      browser_test_context._global_test_context = None
diff --git a/catapult/telemetry/telemetry/testing/decorators_unittest.py b/catapult/telemetry/telemetry/testing/decorators_unittest.py
deleted file mode 100644
index f27d36c..0000000
--- a/catapult/telemetry/telemetry/testing/decorators_unittest.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import decorators
-
-_counter = 0
-
-
-class Foo(object):
-  @decorators.Cache
-  def GetCountCached(self, _):
-    global _counter
-    _counter = _counter + 1
-    return _counter
-
-
-def CreateFooUncached(_):
-  return Foo()
-
-
-@decorators.Cache
-def CreateFooCached(_):
-  return Foo()
-
-
-class DecoratorsUnitTest(unittest.TestCase):
-  # pylint: disable=blacklisted-name
-
-  def testCacheDecorator(self):
-    self.assertNotEquals(CreateFooUncached(1), CreateFooUncached(2))
-    self.assertNotEquals(CreateFooCached(1), CreateFooCached(2))
-
-    self.assertNotEquals(CreateFooUncached(1), CreateFooUncached(1))
-    self.assertEquals(CreateFooCached(1), CreateFooCached(1))
-
-  def testCacheableMemberCachesOnlyForSameArgs(self):
-    foo = Foo()
-    value_of_one = foo.GetCountCached(1)
-
-    self.assertEquals(value_of_one, foo.GetCountCached(1))
-    self.assertNotEquals(value_of_one, foo.GetCountCached(2))
-
-  def testCacheableMemberHasSeparateCachesForSiblingInstances(self):
-    foo = Foo()
-    sibling_foo = Foo()
-
-    self.assertNotEquals(foo.GetCountCached(1), sibling_foo.GetCountCached(1))
-
-  def testCacheableMemberHasSeparateCachesForNextGenerationInstances(self):
-    foo = Foo()
-    last_generation_count = foo.GetCountCached(1)
-    foo = None
-    foo = Foo()
-
-    self.assertNotEquals(last_generation_count, foo.GetCountCached(1))
diff --git a/catapult/telemetry/telemetry/testing/disabled_cases.py b/catapult/telemetry/telemetry/testing/disabled_cases.py
deleted file mode 100644
index bb4641a..0000000
--- a/catapult/telemetry/telemetry/testing/disabled_cases.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry import decorators
-
-
-# These are not real unittests.
-# They are merely to test our Enable/Disable annotations.
-class DisabledCases(unittest.TestCase):
-
-  def testAllEnabled(self):
-    pass
-
-  @decorators.Disabled('all')
-  def testAllDisabled(self):
-    pass
-
-  @decorators.Enabled('mavericks')
-  def testMavericksOnly(self):
-    pass
-
-  @decorators.Disabled('mavericks')
-  def testNoMavericks(self):
-    pass
-
-  @decorators.Enabled('mac')
-  def testMacOnly(self):
-    pass
-
-  @decorators.Disabled('mac')
-  def testNoMac(self):
-    pass
-
-  @decorators.Enabled('chromeos')
-  def testChromeOSOnly(self):
-    pass
-
-  @decorators.Disabled('chromeos')
-  def testNoChromeOS(self):
-    pass
-
-  @decorators.Enabled('win', 'linux')
-  def testWinOrLinuxOnly(self):
-    pass
-
-  @decorators.Disabled('win', 'linux')
-  def testNoWinLinux(self):
-    pass
-
-  @decorators.Enabled('system')
-  def testSystemOnly(self):
-    pass
-
-  @decorators.Disabled('system')
-  def testNoSystem(self):
-    pass
-
-  @decorators.Enabled('has tabs')
-  def testHasTabs(self):
-    pass
diff --git a/catapult/telemetry/telemetry/testing/fakes/__init__.py b/catapult/telemetry/telemetry/testing/fakes/__init__.py
deleted file mode 100644
index 97c6360..0000000
--- a/catapult/telemetry/telemetry/testing/fakes/__init__.py
+++ /dev/null
@@ -1,539 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides fakes for several of Telemetry's internal objects.
-
-These allow code like story_runner and Benchmark to be run and tested
-without compiling or starting a browser. Class names prepended with an
-underscore are intended to be implementation details, and should not
-be subclassed; however, some, like _FakeBrowser, have public APIs that
-may need to be called in tests.
-"""
-from telemetry.internal.backends.chrome_inspector import websocket
-from telemetry.internal.browser import browser_options
-from telemetry.internal.platform import system_info
-from telemetry.page import shared_page_state
-from telemetry.util import image_util
-from telemetry.testing.internal import fake_gpu_info
-from types import ModuleType
-
-
-# Classes and functions which are intended to be part of the public
-# fakes API.
-
-class FakePlatform(object):
-  def __init__(self):
-    self._network_controller = None
-    self._tracing_controller = None
-
-  @property
-  def is_host_platform(self):
-    raise NotImplementedError
-
-  @property
-  def network_controller(self):
-    if self._network_controller is None:
-      self._network_controller = _FakeNetworkController()
-    return  self._network_controller
-
-  @property
-  def tracing_controller(self):
-    if self._tracing_controller is None:
-      self._tracing_controller = _FakeTracingController()
-    return  self._tracing_controller
-
-  def Initialize(self):
-    pass
-
-  def CanMonitorThermalThrottling(self):
-    return False
-
-  def IsThermallyThrottled(self):
-    return False
-
-  def HasBeenThermallyThrottled(self):
-    return False
-
-  def GetDeviceTypeName(self):
-    return 'FakeDevice'
-
-  def GetArchName(self):
-    raise NotImplementedError
-
-  def GetOSName(self):
-    return 'FakeOS'
-
-  def GetOSVersionName(self):
-    raise NotImplementedError
-
-  def StopAllLocalServers(self):
-    pass
-
-  def WaitForTemperature(self, _):
-    pass
-
-
-class FakeLinuxPlatform(FakePlatform):
-  def __init__(self):
-    super(FakeLinuxPlatform, self).__init__()
-    self.screenshot_png_data = None
-    self.http_server_directories = []
-    self.http_server = FakeHTTPServer()
-
-  @property
-  def is_host_platform(self):
-    return True
-
-  def GetDeviceTypeName(self):
-    return 'Desktop'
-
-  def GetArchName(self):
-    return 'x86_64'
-
-  def GetOSName(self):
-    return 'linux'
-
-  def GetOSVersionName(self):
-    return 'trusty'
-
-  def CanTakeScreenshot(self):
-    return bool(self.screenshot_png_data)
-
-  def TakeScreenshot(self, file_path):
-    if not self.CanTakeScreenshot():
-      raise NotImplementedError
-    img = image_util.FromBase64Png(self.screenshot_png_data)
-    image_util.WritePngFile(img, file_path)
-    return True
-
-  def SetHTTPServerDirectories(self, paths):
-    self.http_server_directories.append(paths)
-
-
-class FakeHTTPServer(object):
-  def UrlOf(self, url):
-    del url  # unused
-    return 'file:///foo'
-
-
-class FakePossibleBrowser(object):
-  def __init__(self, execute_on_startup=None,
-               execute_after_browser_creation=None):
-    self._returned_browser = _FakeBrowser(FakeLinuxPlatform())
-    self.browser_type = 'linux'
-    self.supports_tab_control = False
-    self.is_remote = False
-    self.execute_on_startup = execute_on_startup
-    self.execute_after_browser_creation = execute_after_browser_creation
-
-  @property
-  def returned_browser(self):
-    """The browser object that will be returned through later API calls."""
-    return self._returned_browser
-
-  def Create(self, finder_options):
-    if self.execute_on_startup is not None:
-      self.execute_on_startup()
-    del finder_options  # unused
-    if self.execute_after_browser_creation is not None:
-      self.execute_after_browser_creation(self._returned_browser)
-    return self.returned_browser
-
-  @property
-  def platform(self):
-    """The platform object from the returned browser.
-
-    To change this or set it up, change the returned browser's
-    platform.
-    """
-    return self.returned_browser.platform
-
-  def IsRemote(self):
-    return self.is_remote
-
-  def SetCredentialsPath(self, _):
-    pass
-
-
-class FakeSharedPageState(shared_page_state.SharedPageState):
-  def __init__(self, test, finder_options, story_set):
-    super(FakeSharedPageState, self).__init__(test, finder_options, story_set)
-
-  def _GetPossibleBrowser(self, test, finder_options):
-    p = FakePossibleBrowser()
-    self.ConfigurePossibleBrowser(p)
-    return p
-
-  def ConfigurePossibleBrowser(self, possible_browser):
-    """Override this to configure the PossibleBrowser.
-
-    Can make changes to the browser's configuration here via e.g.:
-       possible_browser.returned_browser.returned_system_info = ...
-    """
-    pass
-
-
-  def DidRunStory(self, results):
-    # TODO(kbr): add a test which throws an exception from DidRunStory
-    # to verify the fix from https://crrev.com/86984d5fc56ce00e7b37ebe .
-    super(FakeSharedPageState, self).DidRunStory(results)
-
-
-class FakeSystemInfo(system_info.SystemInfo):
-  def __init__(self, model_name='', gpu_dict=None):
-    if gpu_dict == None:
-      gpu_dict = fake_gpu_info.FAKE_GPU_INFO
-    super(FakeSystemInfo, self).__init__(model_name, gpu_dict)
-
-
-class _FakeBrowserFinderOptions(browser_options.BrowserFinderOptions):
-  def __init__(self, execute_on_startup=None,
-               execute_after_browser_creation=None, *args, **kwargs):
-    browser_options.BrowserFinderOptions.__init__(self, *args, **kwargs)
-    self.fake_possible_browser = \
-      FakePossibleBrowser(
-        execute_on_startup=execute_on_startup,
-        execute_after_browser_creation=execute_after_browser_creation)
-
-def CreateBrowserFinderOptions(browser_type=None, execute_on_startup=None,
-                               execute_after_browser_creation=None):
-  """Creates fake browser finder options for discovering a browser."""
-  return _FakeBrowserFinderOptions(
-    browser_type=browser_type,
-    execute_on_startup=execute_on_startup,
-    execute_after_browser_creation=execute_after_browser_creation)
-
-
-# Internal classes. Note that end users may still need to both call
-# and mock out methods of these classes, but they should not be
-# subclassed.
-
-class _FakeBrowser(object):
-  def __init__(self, platform):
-    self._tabs = _FakeTabList(self)
-    # Fake the creation of the first tab.
-    self._tabs.New()
-    self._returned_system_info = FakeSystemInfo()
-    self._platform = platform
-    self._browser_type = 'release'
-    self._is_crashed = False
-
-  @property
-  def platform(self):
-    return self._platform
-
-  @platform.setter
-  def platform(self, incoming):
-    """Allows overriding of the fake browser's platform object."""
-    assert isinstance(incoming, FakePlatform)
-    self._platform = incoming
-
-  @property
-  def returned_system_info(self):
-    """The object which will be returned from calls to GetSystemInfo."""
-    return self._returned_system_info
-
-  @returned_system_info.setter
-  def returned_system_info(self, incoming):
-    """Allows overriding of the returned SystemInfo object.
-
-    Incoming argument must be an instance of FakeSystemInfo."""
-    assert isinstance(incoming, FakeSystemInfo)
-    self._returned_system_info = incoming
-
-  @property
-  def browser_type(self):
-    """The browser_type this browser claims to be ('debug', 'release', etc.)"""
-    return self._browser_type
-
-  @browser_type.setter
-  def browser_type(self, incoming):
-    """Allows setting of the browser_type."""
-    self._browser_type = incoming
-
-  @property
-  def credentials(self):
-    return _FakeCredentials()
-
-  def Close(self):
-    self._is_crashed = False
-
-  @property
-  def supports_system_info(self):
-    return True
-
-  def GetSystemInfo(self):
-    return self.returned_system_info
-
-  @property
-  def supports_tab_control(self):
-    return True
-
-  @property
-  def tabs(self):
-    return self._tabs
-
-  def DumpStateUponFailure(self):
-    pass
-
-
-class _FakeCredentials(object):
-  def WarnIfMissingCredentials(self, _):
-    pass
-
-
-class _FakeTracingController(object):
-  def __init__(self):
-    self._is_tracing = False
-
-  def StartTracing(self, tracing_config, timeout=10):
-    self._is_tracing = True
-    del tracing_config
-    del timeout
-
-  def StopTracing(self):
-    self._is_tracing = False
-
-  @property
-  def is_tracing_running(self):
-    return self._is_tracing
-
-  def ClearStateIfNeeded(self):
-    pass
-
-  def IsChromeTracingSupported(self):
-    return True
-
-
-class _FakeNetworkController(object):
-  def __init__(self):
-    self.wpr_mode = None
-    self.extra_wpr_args = None
-    self.is_initialized = False
-    self.is_open = False
-    self.use_live_traffic = None
-
-  def InitializeIfNeeded(self, use_live_traffic=False):
-    self.use_live_traffic = use_live_traffic
-
-  def UpdateTrafficSettings(self, round_trip_latency_ms=None,
-      download_bandwidth_kbps=None, upload_bandwidth_kbps=None):
-    pass
-
-  def Open(self, wpr_mode, extra_wpr_args):
-    self.wpr_mode = wpr_mode
-    self.extra_wpr_args = extra_wpr_args
-    self.is_open = True
-
-  def Close(self):
-    self.wpr_mode = None
-    self.extra_wpr_args = None
-    self.is_initialized = False
-    self.is_open = False
-
-  def StartReplay(self, archive_path, make_javascript_deterministic=False):
-    del make_javascript_deterministic  # Unused.
-    assert self.is_open
-    self.is_initialized = archive_path is not None
-
-  def StopReplay(self):
-    self.is_initialized = False
-
-
-class _FakeTab(object):
-  def __init__(self, browser, tab_id):
-    self._browser = browser
-    self._tab_id = str(tab_id)
-    self._collect_garbage_count = 0
-    self.test_png = None
-
-  @property
-  def collect_garbage_count(self):
-    return self._collect_garbage_count
-
-  @property
-  def id(self):
-    return self._tab_id
-
-  @property
-  def browser(self):
-    return self._browser
-
-  def WaitForDocumentReadyStateToBeComplete(self, timeout=0):
-    pass
-
-  def Navigate(self, url, script_to_evaluate_on_commit=None,
-               timeout=0):
-    del script_to_evaluate_on_commit, timeout # unused
-    if url == 'chrome://crash':
-      self.browser._is_crashed = True
-      raise Exception
-
-  def WaitForDocumentReadyStateToBeInteractiveOrBetter(self, timeout=0):
-    pass
-
-  def WaitForFrameToBeDisplayed(self, timeout=0):
-    pass
-
-  def IsAlive(self):
-    return True
-
-  def CloseConnections(self):
-    pass
-
-  def CollectGarbage(self):
-    self._collect_garbage_count += 1
-
-  def Close(self):
-    pass
-
-  @property
-  def screenshot_supported(self):
-    return self.test_png is not None
-
-  def Screenshot(self):
-    assert self.screenshot_supported, 'Screenshot is not supported'
-    return image_util.FromBase64Png(self.test_png)
-
-
-class _FakeTabList(object):
-  _current_tab_id = 0
-
-  def __init__(self, browser):
-    self._tabs = []
-    self._browser = browser
-
-  def New(self, timeout=300):
-    del timeout  # unused
-    type(self)._current_tab_id += 1
-    t = _FakeTab(self._browser, type(self)._current_tab_id)
-    self._tabs.append(t)
-    return t
-
-  def __iter__(self):
-    return self._tabs.__iter__()
-
-  def __len__(self):
-    return len(self._tabs)
-
-  def __getitem__(self, index):
-    if self._tabs[index].browser._is_crashed:
-      raise Exception
-    else:
-      return self._tabs[index]
-
-  def GetTabById(self, identifier):
-    """The identifier of a tab can be accessed with tab.id."""
-    for tab in self._tabs:
-      if tab.id == identifier:
-        return tab
-    return None
-
-
-class FakeInspectorWebsocket(object):
-  _NOTIFICATION_EVENT = 1
-  _NOTIFICATION_CALLBACK = 2
-
-  """A fake InspectorWebsocket.
-
-  A fake that allows tests to send pregenerated data. Normal
-  InspectorWebsockets allow for any number of domain handlers. This fake only
-  allows up to 1 domain handler, and assumes that the domain of the response
-  always matches that of the handler.
-  """
-  def __init__(self, mock_timer):
-    self._mock_timer = mock_timer
-    self._notifications = []
-    self._response_handlers = {}
-    self._pending_callbacks = {}
-    self._handler = None
-
-  def RegisterDomain(self, _, handler):
-    self._handler = handler
-
-  def AddEvent(self, method, params, time):
-    if self._notifications:
-      assert self._notifications[-1][1] < time, (
-          'Current response is scheduled earlier than previous response.')
-    response = {'method': method, 'params': params}
-    self._notifications.append((response, time, self._NOTIFICATION_EVENT))
-
-  def AddAsyncResponse(self, method, result, time):
-    if self._notifications:
-      assert self._notifications[-1][1] < time, (
-          'Current response is scheduled earlier than previous response.')
-    response = {'method': method, 'result': result}
-    self._notifications.append((response, time, self._NOTIFICATION_CALLBACK))
-
-  def AddResponseHandler(self, method, handler):
-    self._response_handlers[method] = handler
-
-  def SyncRequest(self, request, *args, **kwargs):
-    del args, kwargs  # unused
-    handler = self._response_handlers[request['method']]
-    return handler(request) if handler else None
-
-  def AsyncRequest(self, request, callback):
-    self._pending_callbacks.setdefault(request['method'], []).append(callback)
-
-  def SendAndIgnoreResponse(self, request):
-    pass
-
-  def Connect(self, _):
-    pass
-
-  def DispatchNotifications(self, timeout):
-    current_time = self._mock_timer.time()
-    if not self._notifications:
-      self._mock_timer.SetTime(current_time + timeout + 1)
-      raise websocket.WebSocketTimeoutException()
-
-    response, time, kind = self._notifications[0]
-    if time - current_time > timeout:
-      self._mock_timer.SetTime(current_time + timeout + 1)
-      raise websocket.WebSocketTimeoutException()
-
-    self._notifications.pop(0)
-    self._mock_timer.SetTime(time + 1)
-    if kind == self._NOTIFICATION_EVENT:
-      self._handler(response)
-    elif kind == self._NOTIFICATION_CALLBACK:
-      callback = self._pending_callbacks.get(response['method']).pop(0)
-      callback(response)
-    else:
-      raise Exception('Unexpected response type')
-
-
-class FakeTimer(object):
-  """ A fake timer to fake out the timing for a module.
-    Args:
-      module: module to fake out the time
-  """
-  def __init__(self, module=None):
-    self._elapsed_time = 0
-    self._module = module
-    self._actual_time = None
-    if module:
-      assert isinstance(module, ModuleType)
-      self._actual_time = module.time
-      self._module.time = self
-
-  def sleep(self, time):
-    self._elapsed_time += time
-
-  def time(self):
-    return self._elapsed_time
-
-  def SetTime(self, time):
-    self._elapsed_time = time
-
-  def __del__(self):
-    self.Restore()
-
-  def Restore(self):
-    if self._module:
-      self._module.time = self._actual_time
-      self._module = None
-      self._actual_time = None
-
diff --git a/catapult/telemetry/telemetry/testing/internal/__init__.py b/catapult/telemetry/telemetry/testing/internal/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/catapult/telemetry/telemetry/testing/internal/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/testing/internal/fake_gpu_info.py b/catapult/telemetry/telemetry/testing/internal/fake_gpu_info.py
deleted file mode 100644
index fe74b07..0000000
--- a/catapult/telemetry/telemetry/testing/internal/fake_gpu_info.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This dictionary of GPU information was captured from a run of
-# Telemetry on a Linux workstation with NVIDIA GPU. It helps test
-# telemetry.internal.platform's GPUInfo class, and specifically the
-# attributes it expects to find in the dictionary; if the code changes
-# in an incompatible way, tests using this fake GPU info will begin
-# failing, indicating this fake data must be updated.
-#
-# To regenerate it, import pdb in
-# telemetry/internal/platform/gpu_info.py and add a call to
-# pdb.set_trace() in GPUInfo.FromDict before the return statement.
-# Print the attrs dictionary in the debugger and copy/paste the result
-# on the right-hand side of this assignment. Then run:
-#
-#   pyformat [this file name] | sed -e "s/'/'/g"
-#
-# and put the output into this file.
-
-FAKE_GPU_INFO = {
-    'feature_status':
-        {
-            'flash_stage3d': 'enabled',
-            'gpu_compositing': 'enabled',
-            'video_decode': 'unavailable_software',
-            'flash_3d': 'enabled',
-            'webgl': 'enabled',
-            'video_encode': 'enabled',
-            'multiple_raster_threads': 'enabled_on',
-            '2d_canvas': 'unavailable_software',
-            'rasterization': 'disabled_software',
-            'flash_stage3d_baseline': 'enabled'
-        },
-    'aux_attributes':
-        {
-            'optimus': False,
-            'sandboxed': True,
-            'basic_info_state': 1,
-            'adapter_luid': 0.0,
-            'driver_version': '331.79',
-            'direct_rendering': True,
-            'amd_switchable': False,
-            'context_info_state': 1,
-            'process_crash_count': 0,
-            'pixel_shader_version': '4.40',
-            'gl_ws_version': '1.4',
-            'can_lose_context': False,
-            'driver_vendor': 'NVIDIA',
-            'max_msaa_samples': '64',
-            'software_rendering': False,
-            'gl_version': '4.4.0 NVIDIA 331.79',
-            'gl_ws_vendor': 'NVIDIA Corporation',
-            'vertex_shader_version': '4.40',
-            'initialization_time': 1.284043,
-            'gl_reset_notification_strategy': 33362,
-            'gl_ws_extensions':
-                'GLX_EXT_visual_info GLX_EXT_visual_rating GLX_SGIX_fbconfig '
-                'GLX_SGIX_pbuffer GLX_SGI_video_sync GLX_SGI_swap_control '
-                'GLX_EXT_swap_control GLX_EXT_swap_control_tear '
-                'GLX_EXT_texture_from_pixmap GLX_EXT_buffer_age '
-                'GLX_ARB_create_context GLX_ARB_create_context_profile '
-                'GLX_EXT_create_context_es_profile '
-                'GLX_EXT_create_context_es2_profile '
-                'GLX_ARB_create_context_robustness GLX_ARB_multisample '
-                'GLX_NV_float_buffer GLX_ARB_fbconfig_float GLX_NV_swap_group'
-                ' GLX_EXT_framebuffer_sRGB GLX_NV_multisample_coverage '
-                'GLX_NV_copy_image GLX_NV_video_capture ',
-            'gl_renderer': 'Quadro 600/PCIe/SSE2',
-            'driver_date': '',
-            'gl_vendor': 'NVIDIA Corporation',
-            'gl_extensions':
-                'GL_AMD_multi_draw_indirect GL_ARB_arrays_of_arrays '
-                'GL_ARB_base_instance GL_ARB_blend_func_extended '
-                'GL_ARB_buffer_storage GL_ARB_clear_buffer_object '
-                'GL_ARB_clear_texture GL_ARB_color_buffer_float '
-                'GL_ARB_compatibility GL_ARB_compressed_texture_pixel_storage'
-                ' GL_ARB_conservative_depth GL_ARB_compute_shader '
-                'GL_ARB_compute_variable_group_size GL_ARB_copy_buffer '
-                'GL_ARB_copy_image GL_ARB_debug_output '
-                'GL_ARB_depth_buffer_float GL_ARB_depth_clamp '
-                'GL_ARB_depth_texture GL_ARB_draw_buffers '
-                'GL_ARB_draw_buffers_blend GL_ARB_draw_indirect '
-                'GL_ARB_draw_elements_base_vertex GL_ARB_draw_instanced '
-                'GL_ARB_enhanced_layouts GL_ARB_ES2_compatibility '
-                'GL_ARB_ES3_compatibility GL_ARB_explicit_attrib_location '
-                'GL_ARB_explicit_uniform_location '
-                'GL_ARB_fragment_coord_conventions '
-                'GL_ARB_fragment_layer_viewport GL_ARB_fragment_program '
-                'GL_ARB_fragment_program_shadow GL_ARB_fragment_shader '
-                'GL_ARB_framebuffer_no_attachments GL_ARB_framebuffer_object '
-                'GL_ARB_framebuffer_sRGB GL_ARB_geometry_shader4 '
-                'GL_ARB_get_program_binary GL_ARB_gpu_shader5 '
-                'GL_ARB_gpu_shader_fp64 GL_ARB_half_float_pixel '
-                'GL_ARB_half_float_vertex GL_ARB_imaging '
-                'GL_ARB_indirect_parameters GL_ARB_instanced_arrays '
-                'GL_ARB_internalformat_query GL_ARB_internalformat_query2 '
-                'GL_ARB_invalidate_subdata GL_ARB_map_buffer_alignment '
-                'GL_ARB_map_buffer_range GL_ARB_multi_bind '
-                'GL_ARB_multi_draw_indirect GL_ARB_multisample '
-                'GL_ARB_multitexture GL_ARB_occlusion_query '
-                'GL_ARB_occlusion_query2 GL_ARB_pixel_buffer_object '
-                'GL_ARB_point_parameters GL_ARB_point_sprite '
-                'GL_ARB_program_interface_query GL_ARB_provoking_vertex '
-                'GL_ARB_robust_buffer_access_behavior GL_ARB_robustness '
-                'GL_ARB_sample_shading GL_ARB_sampler_objects '
-                'GL_ARB_seamless_cube_map GL_ARB_separate_shader_objects '
-                'GL_ARB_shader_atomic_counters GL_ARB_shader_bit_encoding '
-                'GL_ARB_shader_draw_parameters GL_ARB_shader_group_vote '
-                'GL_ARB_shader_image_load_store GL_ARB_shader_image_size '
-                'GL_ARB_shader_objects GL_ARB_shader_precision '
-                'GL_ARB_query_buffer_object '
-                'GL_ARB_shader_storage_buffer_object GL_ARB_shader_subroutine'
-                ' GL_ARB_shader_texture_lod GL_ARB_shading_language_100 '
-                'GL_ARB_shading_language_420pack '
-                'GL_ARB_shading_language_include '
-                'GL_ARB_shading_language_packing GL_ARB_shadow '
-                'GL_ARB_stencil_texturing GL_ARB_sync '
-                'GL_ARB_tessellation_shader GL_ARB_texture_border_clamp '
-                'GL_ARB_texture_buffer_object '
-                'GL_ARB_texture_buffer_object_rgb32 '
-                'GL_ARB_texture_buffer_range GL_ARB_texture_compression '
-                'GL_ARB_texture_compression_bptc '
-                'GL_ARB_texture_compression_rgtc GL_ARB_texture_cube_map '
-                'GL_ARB_texture_cube_map_array GL_ARB_texture_env_add '
-                'GL_ARB_texture_env_combine GL_ARB_texture_env_crossbar '
-                'GL_ARB_texture_env_dot3 GL_ARB_texture_float '
-                'GL_ARB_texture_gather GL_ARB_texture_mirror_clamp_to_edge '
-                'GL_ARB_texture_mirrored_repeat GL_ARB_texture_multisample '
-                'GL_ARB_texture_non_power_of_two GL_ARB_texture_query_levels '
-                'GL_ARB_texture_query_lod GL_ARB_texture_rectangle '
-                'GL_ARB_texture_rg GL_ARB_texture_rgb10_a2ui '
-                'GL_ARB_texture_stencil8 GL_ARB_texture_storage '
-                'GL_ARB_texture_storage_multisample GL_ARB_texture_swizzle '
-                'GL_ARB_texture_view GL_ARB_timer_query '
-                'GL_ARB_transform_feedback2 GL_ARB_transform_feedback3 '
-                'GL_ARB_transform_feedback_instanced GL_ARB_transpose_matrix '
-                'GL_ARB_uniform_buffer_object GL_ARB_vertex_array_bgra '
-                'GL_ARB_vertex_array_object GL_ARB_vertex_attrib_64bit '
-                'GL_ARB_vertex_attrib_binding GL_ARB_vertex_buffer_object '
-                'GL_ARB_vertex_program GL_ARB_vertex_shader '
-                'GL_ARB_vertex_type_10f_11f_11f_rev '
-                'GL_ARB_vertex_type_2_10_10_10_rev GL_ARB_viewport_array '
-                'GL_ARB_window_pos GL_ATI_draw_buffers GL_ATI_texture_float '
-                'GL_ATI_texture_mirror_once GL_S3_s3tc GL_EXT_texture_env_add'
-                ' GL_EXT_abgr GL_EXT_bgra GL_EXT_bindable_uniform '
-                'GL_EXT_blend_color GL_EXT_blend_equation_separate '
-                'GL_EXT_blend_func_separate GL_EXT_blend_minmax '
-                'GL_EXT_blend_subtract GL_EXT_compiled_vertex_array '
-                'GL_EXT_Cg_shader GL_EXT_depth_bounds_test '
-                'GL_EXT_direct_state_access GL_EXT_draw_buffers2 '
-                'GL_EXT_draw_instanced GL_EXT_draw_range_elements '
-                'GL_EXT_fog_coord GL_EXT_framebuffer_blit '
-                'GL_EXT_framebuffer_multisample '
-                'GL_EXTX_framebuffer_mixed_formats '
-                'GL_EXT_framebuffer_multisample_blit_scaled '
-                'GL_EXT_framebuffer_object GL_EXT_framebuffer_sRGB '
-                'GL_EXT_geometry_shader4 GL_EXT_gpu_program_parameters '
-                'GL_EXT_gpu_shader4 GL_EXT_multi_draw_arrays '
-                'GL_EXT_packed_depth_stencil GL_EXT_packed_float '
-                'GL_EXT_packed_pixels GL_EXT_pixel_buffer_object '
-                'GL_EXT_point_parameters GL_EXT_provoking_vertex '
-                'GL_EXT_rescale_normal GL_EXT_secondary_color '
-                'GL_EXT_separate_shader_objects '
-                'GL_EXT_separate_specular_color '
-                'GL_EXT_shader_image_load_store GL_EXT_shadow_funcs '
-                'GL_EXT_stencil_two_side GL_EXT_stencil_wrap GL_EXT_texture3D'
-                ' GL_EXT_texture_array GL_EXT_texture_buffer_object '
-                'GL_EXT_texture_compression_dxt1 '
-                'GL_EXT_texture_compression_latc '
-                'GL_EXT_texture_compression_rgtc '
-                'GL_EXT_texture_compression_s3tc GL_EXT_texture_cube_map '
-                'GL_EXT_texture_edge_clamp GL_EXT_texture_env_combine '
-                'GL_EXT_texture_env_dot3 GL_EXT_texture_filter_anisotropic '
-                'GL_EXT_texture_integer GL_EXT_texture_lod '
-                'GL_EXT_texture_lod_bias GL_EXT_texture_mirror_clamp '
-                'GL_EXT_texture_object GL_EXT_texture_shared_exponent '
-                'GL_EXT_texture_sRGB GL_EXT_texture_sRGB_decode '
-                'GL_EXT_texture_storage GL_EXT_texture_swizzle '
-                'GL_EXT_timer_query GL_EXT_transform_feedback2 '
-                'GL_EXT_vertex_array GL_EXT_vertex_array_bgra '
-                'GL_EXT_vertex_attrib_64bit GL_EXT_x11_sync_object '
-                'GL_EXT_import_sync_object GL_IBM_rasterpos_clip '
-                'GL_IBM_texture_mirrored_repeat GL_KHR_debug '
-                'GL_KTX_buffer_region GL_NV_bindless_multi_draw_indirect '
-                'GL_NV_blend_equation_advanced GL_NV_blend_square '
-                'GL_NV_compute_program5 GL_NV_conditional_render '
-                'GL_NV_copy_depth_to_color GL_NV_copy_image '
-                'GL_NV_depth_buffer_float GL_NV_depth_clamp '
-                'GL_NV_draw_texture GL_NV_ES1_1_compatibility '
-                'GL_NV_explicit_multisample GL_NV_fence GL_NV_float_buffer '
-                'GL_NV_fog_distance GL_NV_fragment_program '
-                'GL_NV_fragment_program_option GL_NV_fragment_program2 '
-                'GL_NV_framebuffer_multisample_coverage '
-                'GL_NV_geometry_shader4 GL_NV_gpu_program4 '
-                'GL_NV_gpu_program4_1 GL_NV_gpu_program5 '
-                'GL_NV_gpu_program5_mem_extended GL_NV_gpu_program_fp64 '
-                'GL_NV_gpu_shader5 GL_NV_half_float GL_NV_light_max_exponent '
-                'GL_NV_multisample_coverage GL_NV_multisample_filter_hint '
-                'GL_NV_occlusion_query GL_NV_packed_depth_stencil '
-                'GL_NV_parameter_buffer_object GL_NV_parameter_buffer_object2'
-                ' GL_NV_path_rendering GL_NV_pixel_data_range '
-                'GL_NV_point_sprite GL_NV_primitive_restart '
-                'GL_NV_register_combiners GL_NV_register_combiners2 '
-                'GL_NV_shader_atomic_counters GL_NV_shader_atomic_float '
-                'GL_NV_shader_buffer_load GL_NV_shader_storage_buffer_object '
-                'GL_ARB_sparse_texture GL_NV_texgen_reflection '
-                'GL_NV_texture_barrier GL_NV_texture_compression_vtc '
-                'GL_NV_texture_env_combine4 GL_NV_texture_expand_normal '
-                'GL_NV_texture_multisample GL_NV_texture_rectangle '
-                'GL_NV_texture_shader GL_NV_texture_shader2 '
-                'GL_NV_texture_shader3 GL_NV_transform_feedback '
-                'GL_NV_transform_feedback2 GL_NV_vdpau_interop '
-                'GL_NV_vertex_array_range GL_NV_vertex_array_range2 '
-                'GL_NV_vertex_attrib_integer_64bit '
-                'GL_NV_vertex_buffer_unified_memory GL_NV_vertex_program '
-                'GL_NV_vertex_program1_1 GL_NV_vertex_program2 '
-                'GL_NV_vertex_program2_option GL_NV_vertex_program3 '
-                'GL_NVX_conditional_render GL_NVX_gpu_memory_info '
-                'GL_SGIS_generate_mipmap GL_SGIS_texture_lod '
-                'GL_SGIX_depth_texture GL_SGIX_shadow GL_SUN_slice_accum '
-        },
-    'devices':
-        [
-            {
-                'device_string': '',
-                'vendor_id': 4318.0,
-                'device_id': 3576.0,
-                'vendor_string': ''
-            }],
-    'driver_bug_workarounds':
-        ['clear_uniforms_before_first_program_use',
-         'disable_gl_path_rendering',
-         'init_gl_position_in_vertex_shader',
-         'init_vertex_attributes',
-         'remove_pow_with_constant_exponent',
-         'scalarize_vec_and_mat_constructor_args',
-         'use_current_program_after_successful_link',
-         'use_virtualized_gl_contexts']
-}
diff --git a/catapult/telemetry/telemetry/testing/options_for_unittests.py b/catapult/telemetry/telemetry/testing/options_for_unittests.py
deleted file mode 100644
index 1c47fbf..0000000
--- a/catapult/telemetry/telemetry/testing/options_for_unittests.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This module provides the global variable options_for_unittests.
-
-This is set to a BrowserOptions object by the test harness, or None
-if unit tests are not running.
-
-This allows multiple unit tests to use a specific
-browser, in face of multiple options."""
-
-
-_options = []
-
-
-def Push(options):
-  _options.append(options)
-
-
-def Pop():
-  return _options.pop()
-
-
-def GetCopy():
-  if not AreSet():
-    return None
-  return _options[-1].Copy()
-
-
-def AreSet():
-  return bool(_options)
diff --git a/catapult/telemetry/telemetry/testing/page_test_test_case.py b/catapult/telemetry/telemetry/testing/page_test_test_case.py
deleted file mode 100644
index d7e7296..0000000
--- a/catapult/telemetry/telemetry/testing/page_test_test_case.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provide a TestCase base class for PageTest subclasses' unittests."""
-
-import unittest
-
-from telemetry import benchmark
-from telemetry import story
-from telemetry.core import exceptions
-from telemetry.core import util
-from telemetry.internal.results import results_options
-from telemetry.internal import story_runner
-from telemetry.page import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry.testing import options_for_unittests
-
-
-class BasicTestPage(page_module.Page):
-  def __init__(self, url, story_set, base_dir):
-    super(BasicTestPage, self).__init__(url, story_set, base_dir)
-
-  def RunPageInteractions(self, action_runner):
-    with action_runner.CreateGestureInteraction('ScrollAction'):
-      action_runner.ScrollPage()
-
-
-class EmptyMetadataForTest(benchmark.BenchmarkMetadata):
-  def __init__(self):
-    super(EmptyMetadataForTest, self).__init__('')
-
-
-class PageTestTestCase(unittest.TestCase):
-  """A base class to simplify writing unit tests for PageTest subclasses."""
-
-  def CreateStorySetFromFileInUnittestDataDir(self, test_filename):
-    ps = self.CreateEmptyPageSet()
-    page = BasicTestPage('file://' + test_filename, ps, base_dir=ps.base_dir)
-    ps.AddStory(page)
-    return ps
-
-  def CreateEmptyPageSet(self):
-    base_dir = util.GetUnittestDataDir()
-    ps = story.StorySet(base_dir=base_dir)
-    return ps
-
-  def RunMeasurement(self, measurement, ps,
-      options=None):
-    """Runs a measurement against a pageset, returning the rows its outputs."""
-    if options is None:
-      options = options_for_unittests.GetCopy()
-    assert options
-    temp_parser = options.CreateParser()
-    story_runner.AddCommandLineArgs(temp_parser)
-    defaults = temp_parser.get_default_values()
-    for k, v in defaults.__dict__.items():
-      if hasattr(options, k):
-        continue
-      setattr(options, k, v)
-
-    if isinstance(measurement, legacy_page_test.LegacyPageTest):
-      measurement.CustomizeBrowserOptions(options.browser_options)
-    options.output_file = None
-    options.output_formats = ['none']
-    options.suppress_gtest_report = True
-    options.output_trace_tag = None
-    story_runner.ProcessCommandLineArgs(temp_parser, options)
-    results = results_options.CreateResults(EmptyMetadataForTest(), options)
-    story_runner.Run(measurement, ps, options, results)
-    return results
-
-  def TestTracingCleanedUp(self, measurement_class, options=None):
-    ps = self.CreateStorySetFromFileInUnittestDataDir('blank.html')
-    start_tracing_called = [False]
-    stop_tracing_called = [False]
-
-    class BuggyMeasurement(measurement_class):
-      def __init__(self, *args, **kwargs):
-        measurement_class.__init__(self, *args, **kwargs)
-
-      # Inject fake tracing methods to tracing_controller
-      def TabForPage(self, page, browser):
-        ActualStartTracing = browser.platform.tracing_controller.StartTracing
-        def FakeStartTracing(*args, **kwargs):
-          ActualStartTracing(*args, **kwargs)
-          start_tracing_called[0] = True
-          raise exceptions.IntentionalException
-        browser.StartTracing = FakeStartTracing
-
-        ActualStopTracing = browser.platform.tracing_controller.StopTracing
-        def FakeStopTracing(*args, **kwargs):
-          result = ActualStopTracing(*args, **kwargs)
-          stop_tracing_called[0] = True
-          return result
-        browser.platform.tracing_controller.StopTracing = FakeStopTracing
-
-        return measurement_class.TabForPage(self, page, browser)
-
-    measurement = BuggyMeasurement()
-    try:
-      self.RunMeasurement(measurement, ps, options=options)
-    except legacy_page_test.TestNotSupportedOnPlatformError:
-      pass
-    if start_tracing_called[0]:
-      self.assertTrue(stop_tracing_called[0])
diff --git a/catapult/telemetry/telemetry/testing/progress_reporter.py b/catapult/telemetry/telemetry/testing/progress_reporter.py
deleted file mode 100644
index 036192b..0000000
--- a/catapult/telemetry/telemetry/testing/progress_reporter.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-import sys
-
-from telemetry.internal.util import path
-from telemetry.testing import options_for_unittests
-
-
-class ProgressReporter(object):
-  def __init__(self, output_stream):
-    self._output_stream = output_stream
-
-  def StartTest(self, test):
-    pass
-
-  def StartTestSuite(self, suite):
-    pass
-
-  def StartTestRun(self):
-    pass
-
-  def StopTest(self, test):
-    pass
-
-  def StopTestSuite(self, suite):
-    pass
-
-  def StopTestRun(self, result):
-    pass
-
-  def Error(self, test, err):
-    pass
-
-  def Failure(self, test, err):
-    pass
-
-  def Success(self, test):
-    pass
-
-  def Skip(self, test, reason):
-    pass
-
-
-class TestSuite(unittest.TestSuite):
-  """TestSuite that can delegate start and stop calls to a TestResult object."""
-  def run(self, result):  # pylint: disable=arguments-differ
-    if hasattr(result, 'startTestSuite'):
-      result.startTestSuite(self)
-    result = super(TestSuite, self).run(result)
-    if hasattr(result, 'stopTestSuite'):
-      result.stopTestSuite(self)
-    return result
-
-
-class TestRunner(object):
-  def run(self, test, progress_reporters, repeat_count, args):
-    sys.path.append(path.GetUnittestDataDir())
-    result = TestResult(progress_reporters)
-    result.startTestRun()
-    try:
-      options_for_unittests.Push(args)
-      for _ in xrange(repeat_count):
-        test(result)
-    finally:
-      options_for_unittests.Pop()
-      result.stopTestRun()
-
-    return result
-
-
-class TestResult(unittest.TestResult):
-  def __init__(self, progress_reporters):
-    super(TestResult, self).__init__()
-    self.successes = []
-    self._progress_reporters = progress_reporters
-
-  @property
-  def failures_and_errors(self):
-    return self.failures + self.errors
-
-  def startTest(self, test):
-    super(TestResult, self).startTest(test)
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.StartTest(test)
-
-  def startTestSuite(self, suite):
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.StartTestSuite(suite)
-
-  def startTestRun(self):
-    super(TestResult, self).startTestRun()
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.StartTestRun()
-
-  def stopTest(self, test):
-    super(TestResult, self).stopTest(test)
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.StopTest(test)
-
-  def stopTestSuite(self, suite):
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.StopTestSuite(suite)
-
-  def stopTestRun(self):
-    super(TestResult, self).stopTestRun()
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.StopTestRun(self)
-
-  def addError(self, test, err):
-    super(TestResult, self).addError(test, err)
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.Error(test, err)
-
-  def addFailure(self, test, err):
-    super(TestResult, self).addFailure(test, err)
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.Failure(test, err)
-
-  def addSuccess(self, test):
-    super(TestResult, self).addSuccess(test)
-    self.successes.append(test)
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.Success(test)
-
-  def addSkip(self, test, reason):
-    super(TestResult, self).addSkip(test, reason)
-    for progress_reporter in self._progress_reporters:
-      progress_reporter.Skip(test, reason)
diff --git a/catapult/telemetry/telemetry/testing/progress_reporter_unittest.py b/catapult/telemetry/telemetry/testing/progress_reporter_unittest.py
deleted file mode 100644
index 2a60882..0000000
--- a/catapult/telemetry/telemetry/testing/progress_reporter_unittest.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.testing import progress_reporter
-
-
-class TestFoo(unittest.TestCase):
-  # Test method doesn't have test- prefix intentionally. This is so that
-  # run_test script won't run this test.
-  def RunPassingTest(self):
-    pass
-
-  def RunFailingTest(self):
-    self.fail('expected failure')
-
-
-class LoggingProgressReporter(object):
-  def __init__(self):
-    self._call_log = []
-
-  @property
-  def call_log(self):
-    return tuple(self._call_log)
-
-  def __getattr__(self, name):
-    def wrapper(*_):
-      self._call_log.append(name)
-    return wrapper
-
-
-class ProgressReporterTest(unittest.TestCase):
-  def testTestRunner(self):
-    suite = progress_reporter.TestSuite()
-    suite.addTest(TestFoo(methodName='RunPassingTest'))
-    suite.addTest(TestFoo(methodName='RunFailingTest'))
-
-    reporter = LoggingProgressReporter()
-    runner = progress_reporter.TestRunner()
-    progress_reporters = (reporter,)
-    result = runner.run(suite, progress_reporters, 1, None)
-
-    self.assertEqual(len(result.successes), 1)
-    self.assertEqual(len(result.failures), 1)
-    self.assertEqual(len(result.failures_and_errors), 1)
-    expected = (
-        'StartTestRun', 'StartTestSuite',
-        'StartTest', 'Success', 'StopTest',
-        'StartTest', 'Failure', 'StopTest',
-        'StopTestSuite', 'StopTestRun',
-    )
-    self.assertEqual(reporter.call_log, expected)
diff --git a/catapult/telemetry/telemetry/testing/run_browser_tests.py b/catapult/telemetry/telemetry/testing/run_browser_tests.py
deleted file mode 100644
index d637116..0000000
--- a/catapult/telemetry/telemetry/testing/run_browser_tests.py
+++ /dev/null
@@ -1,355 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import fnmatch
-import re
-import sys
-import json
-
-from telemetry.core import discover
-from telemetry.internal.browser import browser_options
-from telemetry.internal.platform import android_device
-from telemetry.internal.util import binary_manager
-from telemetry.testing import browser_test_context
-from telemetry.testing import serially_executed_browser_test_case
-
-import typ
-from typ import arg_parser
-
-TEST_SUFFIXES = ['*_test.py', '*_tests.py', '*_unittest.py', '*_unittests.py']
-
-
-def ProcessCommandLineOptions(test_class, typ_options, args):
-  options = browser_options.BrowserFinderOptions()
-  options.browser_type = 'any'
-  parser = options.CreateParser(test_class.__doc__)
-  test_class.AddCommandlineArgs(parser)
-  # Set the default chrome root variable. This is required for the
-  # Android browser finder to function properly.
-  if typ_options.default_chrome_root:
-    parser.set_defaults(chrome_root=typ_options.default_chrome_root)
-  finder_options, positional_args = parser.parse_args(args)
-  finder_options.positional_args = positional_args
-  # Typ parses the "verbose", or "-v", command line arguments which
-  # are supposed to control logging verbosity. Carry them over.
-  finder_options.verbosity = typ_options.verbose
-  return finder_options
-
-
-def _ValidateDistinctNames(browser_test_classes):
-  names_to_test_classes = {}
-  for cl in browser_test_classes:
-    name = cl.Name()
-    if name in names_to_test_classes:
-      raise Exception('Test name %s is duplicated between %s and %s' % (
-          name, repr(cl), repr(names_to_test_classes[name])))
-    names_to_test_classes[name] = cl
-
-
-def _TestRangeForShard(total_shards, shard_index, num_tests):
-  """Returns a 2-tuple containing the start (inclusive) and ending
-  (exclusive) indices of the tests that should be run, given that
-  |num_tests| tests are split across |total_shards| shards, and that
-  |shard_index| is currently being run.
-  """
-  assert num_tests >= 0
-  assert total_shards >= 1
-  assert shard_index >= 0 and shard_index < total_shards, (
-    'shard_index (%d) must be >= 0 and < total_shards (%d)' %
-    (shard_index, total_shards))
-  if num_tests == 0:
-    return (0, 0)
-  floored_tests_per_shard = num_tests // total_shards
-  remaining_tests = num_tests % total_shards
-  if remaining_tests == 0:
-    return (floored_tests_per_shard * shard_index,
-            floored_tests_per_shard * (1 + shard_index))
-  # More complicated. Some shards will run floored_tests_per_shard
-  # tests, and some will run 1 + floored_tests_per_shard.
-  num_earlier_shards_with_one_extra_test = min(remaining_tests, shard_index)
-  num_earlier_shards_with_no_extra_tests = max(
-    0, shard_index - num_earlier_shards_with_one_extra_test)
-  num_earlier_tests = (
-    num_earlier_shards_with_one_extra_test * (floored_tests_per_shard + 1) +
-    num_earlier_shards_with_no_extra_tests * floored_tests_per_shard)
-  tests_for_this_shard = floored_tests_per_shard
-  if shard_index < remaining_tests:
-    tests_for_this_shard += 1
-  return (num_earlier_tests, num_earlier_tests + tests_for_this_shard)
-
-
-def _MedianTestTime(test_times):
-  times = test_times.values()
-  times.sort()
-  if len(times) == 0:
-    return 0
-  halfLen = len(times) / 2
-  if len(times) % 2:
-    return times[halfLen]
-  else:
-    return 0.5 * (times[halfLen - 1] + times[halfLen])
-
-
-def _TestTime(test, test_times, default_test_time):
-  return test_times.get(test.shortName()) or default_test_time
-
-
-def _DebugShardDistributions(shards, test_times):
-  for i, s in enumerate(shards):
-    num_tests = len(s)
-    if test_times:
-      median = _MedianTestTime(test_times)
-      shard_time = 0.0
-      for t in s:
-        shard_time += _TestTime(t, test_times, median)
-      print 'shard %d: %d seconds (%d tests)' % (i, shard_time, num_tests)
-    else:
-      print 'shard %d: %d tests (unknown duration)' % (i, num_tests)
-
-
-def _SplitShardsByTime(test_cases, total_shards, test_times,
-                       debug_shard_distributions):
-  median = _MedianTestTime(test_times)
-  shards = []
-  for i in xrange(total_shards):
-    shards.append({'total_time': 0.0, 'tests': []})
-  test_cases.sort(key=lambda t: _TestTime(t, test_times, median),
-                  reverse=True)
-
-  # The greedy algorithm has been empirically tested on the WebGL 2.0
-  # conformance tests' times, and results in an essentially perfect
-  # shard distribution of 530 seconds per shard. In the same scenario,
-  # round-robin scheduling resulted in shard times spread between 502
-  # and 592 seconds, and the current alphabetical sharding resulted in
-  # shard times spread between 44 and 1591 seconds.
-
-  # Greedy scheduling. O(m*n), where m is the number of shards and n
-  # is the number of test cases.
-  for t in test_cases:
-    min_shard_index = 0
-    min_shard_time = None
-    for i in xrange(total_shards):
-      if min_shard_time is None or shards[i]['total_time'] < min_shard_time:
-        min_shard_index = i
-        min_shard_time = shards[i]['total_time']
-    shards[min_shard_index]['tests'].append(t)
-    shards[min_shard_index]['total_time'] += _TestTime(t, test_times, median)
-
-  res = [s['tests'] for s in shards]
-  if debug_shard_distributions:
-    _DebugShardDistributions(res, test_times)
-
-  return res
-
-
-def LoadTestCasesToBeRun(
-    test_class, finder_options, filter_regex_str, filter_tests_after_sharding,
-    total_shards, shard_index, test_times, debug_shard_distributions):
-  test_cases = []
-  real_regex = re.compile(filter_regex_str)
-  noop_regex = re.compile('')
-  if filter_tests_after_sharding:
-    filter_regex = noop_regex
-    post_filter_regex = real_regex
-  else:
-    filter_regex = real_regex
-    post_filter_regex = noop_regex
-
-  for t in serially_executed_browser_test_case.GenerateTestCases(
-      test_class, finder_options):
-    if filter_regex.search(t.shortName()):
-      test_cases.append(t)
-
-  if test_times:
-    # Assign tests to shards.
-    shards = _SplitShardsByTime(test_cases, total_shards, test_times,
-                                debug_shard_distributions)
-    return [t for t in shards[shard_index]
-            if post_filter_regex.search(t.shortName())]
-  else:
-    test_cases.sort(key=lambda t: t.shortName())
-    test_range = _TestRangeForShard(total_shards, shard_index, len(test_cases))
-    if debug_shard_distributions:
-      tmp_shards = []
-      for i in xrange(total_shards):
-        tmp_range = _TestRangeForShard(total_shards, i, len(test_cases))
-        tmp_shards.append(test_cases[tmp_range[0]:tmp_range[1]])
-      # Can edit the code to get 'test_times' passed in here for
-      # debugging and comparison purposes.
-      _DebugShardDistributions(tmp_shards, None)
-    return [t for t in test_cases[test_range[0]:test_range[1]]
-            if post_filter_regex.search(t.shortName())]
-
-
-def _CreateTestArgParsers():
-  parser = typ.ArgumentParser(discovery=False, reporting=True, running=True)
-  parser.add_argument('test', type=str, help='Name of the test suite to run')
-  parser.add_argument('--test-filter', type=str, default='', action='store',
-      help='Run only tests whose names match the given filter regexp.')
-  parser.add_argument(
-    '--filter-tests-after-sharding', default=False, action='store_true',
-    help=('Apply the test filter after tests are split for sharding. Useful '
-          'for reproducing bugs related to the order in which tests run.'))
-  parser.add_argument(
-      '--read-abbreviated-json-results-from', metavar='FILENAME',
-      action='store', help=(
-        'If specified, reads abbreviated results from that path in json form. '
-        'This information is used to more evenly distribute tests among '
-        'shards.'))
-  parser.add_argument('--debug-shard-distributions',
-      action='store_true', default=False,
-      help='Print debugging information about the shards\' test distributions')
-
-  parser.add_argument('--default-chrome-root', type=str, default=None)
-  parser.add_argument('--client-config', dest='client_configs',
-                      action='append', default=[])
-  parser.add_argument('--start-dir', dest='start_dirs',
-                      action='append', default=[])
-  parser.add_argument('--skip', metavar='glob', default=[],
-      action='append',
-      help=('Globs of test names to skip (defaults to %(default)s).'))
-  return parser
-
-
-def _SkipMatch(name, skipGlobs):
-  return any(fnmatch.fnmatch(name, glob) for glob in skipGlobs)
-
-
-def _GetClassifier(args):
-  def _SeriallyExecutedBrowserTestCaseClassifer(test_set, test):
-    # Do not pick up tests that do not inherit from
-    # serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase
-    # class.
-    if not isinstance(test,
-        serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-      return
-    name = test.id()
-    if _SkipMatch(name, args.skip):
-      test_set.tests_to_skip.append(
-          typ.TestInput(name, 'skipped because matched --skip'))
-      return
-    # For now, only support running these tests serially.
-    test_set.isolated_tests.append(typ.TestInput(name))
-  return _SeriallyExecutedBrowserTestCaseClassifer
-
-
-def RunTests(args):
-  parser = _CreateTestArgParsers()
-  try:
-    options, extra_args = parser.parse_known_args(args)
-  except arg_parser._Bailout:
-    return parser.exit_status
-  binary_manager.InitDependencyManager(options.client_configs)
-
-  for start_dir in options.start_dirs:
-    modules_to_classes = discover.DiscoverClasses(
-        start_dir, options.top_level_dir,
-        base_class=serially_executed_browser_test_case.
-            SeriallyExecutedBrowserTestCase)
-    browser_test_classes = modules_to_classes.values()
-
-  _ValidateDistinctNames(browser_test_classes)
-
-  test_class = None
-  for cl in browser_test_classes:
-    if cl.Name() == options.test:
-      test_class = cl
-      break
-
-  if not test_class:
-    print 'Cannot find test class with name matching %s' % options.test
-    print 'Available tests: %s' % '\n'.join(
-        cl.Name() for cl in browser_test_classes)
-    return 1
-
-  # Create test context.
-  context = browser_test_context.TypTestContext()
-  for c in options.client_configs:
-    context.client_configs.append(c)
-  context.finder_options = ProcessCommandLineOptions(
-      test_class, options, extra_args)
-  context.test_class = test_class
-  test_times = None
-  if options.read_abbreviated_json_results_from:
-    with open(options.read_abbreviated_json_results_from, 'r') as f:
-      abbr_results = json.load(f)
-      test_times = abbr_results.get('times')
-  tests_to_run = LoadTestCasesToBeRun(
-      test_class=test_class, finder_options=context.finder_options,
-      filter_regex_str=options.test_filter,
-      filter_tests_after_sharding=options.filter_tests_after_sharding,
-      total_shards=options.total_shards, shard_index=options.shard_index,
-      test_times=test_times,
-      debug_shard_distributions=options.debug_shard_distributions)
-  for t in tests_to_run:
-    context.test_case_ids_to_run.add(t.id())
-  context.Freeze()
-  browser_test_context._global_test_context = context
-
-  # Setup typ runner.
-  runner = typ.Runner()
-
-  runner.context = context
-  runner.setup_fn = _SetUpProcess
-  runner.teardown_fn = _TearDownProcess
-
-  runner.args.jobs = options.jobs
-  runner.args.metadata = options.metadata
-  runner.args.passthrough = options.passthrough
-  runner.args.path = options.path
-  runner.args.retry_limit = options.retry_limit
-  runner.args.test_results_server = options.test_results_server
-  runner.args.test_type = options.test_type
-  runner.args.top_level_dir = options.top_level_dir
-  runner.args.write_full_results_to = options.write_full_results_to
-  runner.args.write_trace_to = options.write_trace_to
-  runner.args.list_only = options.list_only
-  runner.classifier = _GetClassifier(options)
-
-  runner.args.suffixes = TEST_SUFFIXES
-
-  # Since sharding logic is handled by browser_test_runner harness by passing
-  # browser_test_context.test_case_ids_to_run to subprocess to indicate test
-  # cases to be run, we explicitly disable sharding logic in typ.
-  runner.args.total_shards = 1
-  runner.args.shard_index = 0
-
-  runner.args.timing = True
-  runner.args.verbose = options.verbose
-  runner.win_multiprocessing = typ.WinMultiprocessing.importable
-  try:
-    ret, _, _ = runner.run()
-  except KeyboardInterrupt:
-    print >> sys.stderr, "interrupted, exiting"
-    ret = 130
-  return ret
-
-
-def _SetUpProcess(child, context):
-  del child  # Unused.
-  args = context.finder_options
-  if binary_manager.NeedsInit():
-    # On windows, typ doesn't keep the DependencyManager initialization in the
-    # child processes.
-    binary_manager.InitDependencyManager(context.client_configs)
-  if args.remote_platform_options.device == 'android':
-    android_devices = android_device.FindAllAvailableDevices(args)
-    if not android_devices:
-      raise RuntimeError("No Android device found")
-    android_devices.sort(key=lambda device: device.name)
-    args.remote_platform_options.device = (
-        android_devices[child.worker_num-1].guid)
-  browser_test_context._global_test_context = context
-  context.test_class.SetUpProcess()
-
-
-def _TearDownProcess(child, context):
-  del child, context  # Unused.
-  browser_test_context._global_test_context.test_class.TearDownProcess()
-  browser_test_context._global_test_context = None
-
-
-if __name__ == '__main__':
-  ret_code = RunTests(sys.argv[1:])
-  sys.exit(ret_code)
diff --git a/catapult/telemetry/telemetry/testing/run_chromeos_tests.py b/catapult/telemetry/telemetry/testing/run_chromeos_tests.py
deleted file mode 100644
index 2313321..0000000
--- a/catapult/telemetry/telemetry/testing/run_chromeos_tests.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import logging
-
-from telemetry.testing import run_tests
-
-
-def RunChromeOSTests(browser_type, tests_to_run):
-  """ Run ChromeOS tests.
-  Args:
-    |browser_type|: string specifies which browser type to use.
-    |tests_to_run|: a list of tuples (top_level_dir, unit_tests), whereas
-      |top_level_dir| specifies the top level directory for running tests, and
-      |unit_tests| is a list of string test names to run.
-  """
-  stream = _LoggingOutputStream()
-  error_string = ''
-
-  for (top_level_dir, unit_tests) in tests_to_run:
-    logging.info('Running unit tests in %s with browser_type "%s".' %
-                 (top_level_dir, browser_type))
-
-    ret = _RunOneSetOfTests(browser_type, top_level_dir, unit_tests, stream)
-    if ret:
-      error_string += 'The unit tests of %s failed.\n' % top_level_dir
-  return error_string
-
-
-def _RunOneSetOfTests(browser_type, top_level_dir, tests, stream):
-  args = ['--browser', browser_type,
-          '--top-level-dir', top_level_dir,
-          '--jobs', '1',
-          '--disable-logging-config'] + tests
-  return run_tests.RunTestsCommand.main(args, stream=stream)
-
-
-class _LoggingOutputStream(object):
-
-  def __init__(self):
-    self._buffer = []
-
-  def write(self, s):
-    """Buffer a string write. Log it when we encounter a newline."""
-    if '\n' in s:
-      segments = s.split('\n')
-      segments[0] = ''.join(self._buffer + [segments[0]])
-      log_level = logging.getLogger().getEffectiveLevel()
-      try:  # TODO(dtu): We need this because of crbug.com/394571
-        logging.getLogger().setLevel(logging.INFO)
-        for line in segments[:-1]:
-          logging.info(line)
-      finally:
-        logging.getLogger().setLevel(log_level)
-      self._buffer = [segments[-1]]
-    else:
-      self._buffer.append(s)
-
-  def flush(self):
-    pass
diff --git a/catapult/telemetry/telemetry/testing/run_tests.py b/catapult/telemetry/telemetry/testing/run_tests.py
deleted file mode 100644
index 17c9ff5..0000000
--- a/catapult/telemetry/telemetry/testing/run_tests.py
+++ /dev/null
@@ -1,303 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import fnmatch
-import logging
-import os
-import sys
-
-from telemetry.core import util
-from telemetry.core import platform as platform_module
-from telemetry import decorators
-from telemetry.internal.browser import browser_finder
-from telemetry.internal.browser import browser_finder_exceptions
-from telemetry.internal.browser import browser_options
-from telemetry.internal.platform import android_device
-from telemetry.internal.util import binary_manager
-from telemetry.internal.util import command_line
-from telemetry.internal.util import ps_util
-from telemetry.testing import browser_test_case
-from telemetry.testing import options_for_unittests
-
-from py_utils import cloud_storage
-from py_utils import xvfb
-
-import typ
-
-
-class RunTestsCommand(command_line.OptparseCommand):
-  """Run unit tests"""
-
-  usage = '[test_name ...] [<options>]'
-  xvfb_process = None
-
-  def __init__(self):
-    super(RunTestsCommand, self).__init__()
-    self.stream = sys.stdout
-
-  @classmethod
-  def CreateParser(cls):
-    options = browser_options.BrowserFinderOptions()
-    options.browser_type = 'any'
-    parser = options.CreateParser('%%prog %s' % cls.usage)
-    return parser
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser, _):
-    parser.add_option('--start-xvfb', action='store_true',
-                      default=False, help='Start Xvfb display if needed.')
-    parser.add_option('--disable-cloud-storage-io', action='store_true',
-                      default=False, help=('Disable cloud storage IO when '
-                                           'tests are run in parallel.'))
-    parser.add_option('--repeat-count', type='int', default=1,
-                      help='Repeats each a provided number of times.')
-    parser.add_option('--no-browser', action='store_true', default=False,
-                      help='Don\'t require an actual browser to run the tests.')
-    parser.add_option('-d', '--also-run-disabled-tests',
-                      dest='run_disabled_tests',
-                      action='store_true', default=False,
-                      help='Ignore @Disabled and @Enabled restrictions.')
-    parser.add_option('--exact-test-filter', action='store_true', default=False,
-                      help='Treat test filter as exact matches (default is '
-                           'substring matches).')
-    parser.add_option('--client-config', dest='client_configs',
-                      action='append', default=[])
-    parser.add_option('--disable-logging-config', action='store_true',
-                      default=False, help='Configure logging (default on)')
-    parser.add_option('--skip', metavar='glob', default=[],
-                      action='append', help=(
-                          'Globs of test names to skip (defaults to '
-                          '%(default)s).'))
-    typ.ArgumentParser.add_option_group(parser,
-                                        "Options for running the tests",
-                                        running=True,
-                                        skip=['-d', '-v', '--verbose'])
-    typ.ArgumentParser.add_option_group(parser,
-                                        "Options for reporting the results",
-                                        reporting=True)
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, args, _):
-    # We retry failures by default unless we're running a list of tests
-    # explicitly.
-    if not args.retry_limit and not args.positional_args:
-      args.retry_limit = 3
-
-    if args.no_browser:
-      return
-
-    if args.start_xvfb and xvfb.ShouldStartXvfb():
-      cls.xvfb_process = xvfb.StartXvfb()
-      # Work around Mesa issues on Linux. See
-      # https://github.com/catapult-project/catapult/issues/3074
-      args.browser_options.AppendExtraBrowserArgs('--disable-gpu')
-
-    try:
-      possible_browser = browser_finder.FindBrowser(args)
-    except browser_finder_exceptions.BrowserFinderException, ex:
-      parser.error(ex)
-
-    if not possible_browser:
-      parser.error('No browser found of type %s. Cannot run tests.\n'
-                   'Re-run with --browser=list to see '
-                   'available browser types.' % args.browser_type)
-
-  @classmethod
-  def main(cls, args=None, stream=None):  # pylint: disable=arguments-differ
-    # We override the superclass so that we can hook in the 'stream' arg.
-    parser = cls.CreateParser()
-    cls.AddCommandLineArgs(parser, None)
-    options, positional_args = parser.parse_args(args)
-    options.positional_args = positional_args
-
-    try:
-      # Must initialize the DependencyManager before calling
-      # browser_finder.FindBrowser(args)
-      binary_manager.InitDependencyManager(options.client_configs)
-      cls.ProcessCommandLineArgs(parser, options, None)
-
-      obj = cls()
-      if stream is not None:
-        obj.stream = stream
-      return obj.Run(options)
-    finally:
-      if cls.xvfb_process:
-        cls.xvfb_process.kill()
-
-  def Run(self, args):
-    runner = typ.Runner()
-    if self.stream:
-      runner.host.stdout = self.stream
-
-    if args.no_browser:
-      possible_browser = None
-      platform = platform_module.GetHostPlatform()
-    else:
-      possible_browser = browser_finder.FindBrowser(args)
-      platform = possible_browser.platform
-
-    fetch_reference_chrome_binary = False
-    # Fetch all binaries needed by telemetry before we run the benchmark.
-    if possible_browser and possible_browser.browser_type == 'reference':
-      fetch_reference_chrome_binary = True
-    binary_manager.FetchBinaryDependencies(
-        platform, args.client_configs, fetch_reference_chrome_binary)
-
-    # Telemetry seems to overload the system if we run one test per core,
-    # so we scale things back a fair amount. Many of the telemetry tests
-    # are long-running, so there's a limit to how much parallelism we
-    # can effectively use for now anyway.
-    #
-    # It should be possible to handle multiple devices if we adjust the
-    # browser_finder code properly, but for now we only handle one on ChromeOS.
-    if platform.GetOSName() == 'chromeos':
-      runner.args.jobs = 1
-    elif platform.GetOSName() == 'android':
-      android_devs = android_device.FindAllAvailableDevices(args)
-      runner.args.jobs = len(android_devs)
-      if runner.args.jobs == 0:
-        raise RuntimeError("No Android device found")
-      print 'Running tests with %d Android device(s).' % runner.args.jobs
-    elif platform.GetOSVersionName() == 'xp':
-      # For an undiagnosed reason, XP falls over with more parallelism.
-      # See crbug.com/388256
-      runner.args.jobs = max(int(args.jobs) // 4, 1)
-    else:
-      runner.args.jobs = max(int(args.jobs) // 2, 1)
-
-    runner.args.skip = args.skip
-    runner.args.metadata = args.metadata
-    runner.args.passthrough = args.passthrough
-    runner.args.path = args.path
-    runner.args.retry_limit = args.retry_limit
-    runner.args.test_results_server = args.test_results_server
-    runner.args.test_type = args.test_type
-    runner.args.top_level_dir = args.top_level_dir
-    runner.args.write_full_results_to = args.write_full_results_to
-    runner.args.write_trace_to = args.write_trace_to
-    runner.args.list_only = args.list_only
-    runner.args.shard_index = args.shard_index
-    runner.args.total_shards = args.total_shards
-
-    runner.args.path.append(util.GetUnittestDataDir())
-
-    # Always print out these info for the ease of debugging.
-    runner.args.timing = True
-    runner.args.verbose = 3
-
-    runner.classifier = GetClassifier(args, possible_browser)
-    runner.context = args
-    runner.setup_fn = _SetUpProcess
-    runner.teardown_fn = _TearDownProcess
-    runner.win_multiprocessing = typ.WinMultiprocessing.importable
-    try:
-      ret, _, _ = runner.run()
-    except KeyboardInterrupt:
-      print >> sys.stderr, "interrupted, exiting"
-      ret = 130
-    return ret
-
-
-def _SkipMatch(name, skipGlobs):
-  return any(fnmatch.fnmatch(name, glob) for glob in skipGlobs)
-
-
-def GetClassifier(args, possible_browser):
-
-  def ClassifyTestWithoutBrowser(test_set, test):
-    name = test.id()
-    if _SkipMatch(name, args.skip):
-      test_set.tests_to_skip.append(
-          typ.TestInput(name, 'skipped because matched --skip'))
-      return
-    if (not args.positional_args
-        or _MatchesSelectedTest(name, args.positional_args,
-                                  args.exact_test_filter)):
-      # TODO(telemetry-team): Make sure that all telemetry unittest that invokes
-      # actual browser are subclasses of browser_test_case.BrowserTestCase
-      # (crbug.com/537428)
-      if issubclass(test.__class__, browser_test_case.BrowserTestCase):
-        test_set.tests_to_skip.append(typ.TestInput(
-            name, msg='Skip the test because it requires a browser.'))
-      else:
-        test_set.parallel_tests.append(typ.TestInput(name))
-
-  def ClassifyTestWithBrowser(test_set, test):
-    name = test.id()
-    if _SkipMatch(name, args.skip):
-      test_set.tests_to_skip.append(
-          typ.TestInput(name, 'skipped because matched --skip'))
-      return
-    if (not args.positional_args
-        or _MatchesSelectedTest(name, args.positional_args,
-                                args.exact_test_filter)):
-      assert hasattr(test, '_testMethodName')
-      method = getattr(
-          test, test._testMethodName)  # pylint: disable=protected-access
-      should_skip, reason = decorators.ShouldSkip(method, possible_browser)
-      if should_skip and not args.run_disabled_tests:
-        test_set.tests_to_skip.append(typ.TestInput(name, msg=reason))
-      elif decorators.ShouldBeIsolated(method, possible_browser):
-        test_set.isolated_tests.append(typ.TestInput(name))
-      else:
-        test_set.parallel_tests.append(typ.TestInput(name))
-
-  if possible_browser:
-    return ClassifyTestWithBrowser
-  else:
-    return ClassifyTestWithoutBrowser
-
-
-def _MatchesSelectedTest(name, selected_tests, selected_tests_are_exact):
-  if not selected_tests:
-    return False
-  if selected_tests_are_exact:
-    return any(name in selected_tests)
-  else:
-    return any(test in name for test in selected_tests)
-
-
-def _SetUpProcess(child, context): # pylint: disable=unused-argument
-  ps_util.EnableListingStrayProcessesUponExitHook()
-  # Make sure that we don't invokes cloud storage I/Os when we run the tests in
-  # parallel.
-  # TODO(nednguyen): always do this once telemetry tests in Chromium is updated
-  # to prefetch files.
-  # (https://github.com/catapult-project/catapult/issues/2192)
-  args = context
-  if args.disable_cloud_storage_io:
-    os.environ[cloud_storage.DISABLE_CLOUD_STORAGE_IO] = '1'
-  if binary_manager.NeedsInit():
-    # Typ doesn't keep the DependencyManager initialization in the child
-    # processes.
-    binary_manager.InitDependencyManager(context.client_configs)
-  # We need to reset the handlers in case some other parts of telemetry already
-  # set it to make this work.
-  if not args.disable_logging_config:
-    logging.getLogger().handlers = []
-    logging.basicConfig(
-        level=logging.INFO,
-        format='(%(levelname)s) %(asctime)s pid=%(process)d'
-               '  %(module)s.%(funcName)s:%(lineno)d'
-               '  %(message)s')
-  if args.remote_platform_options.device == 'android':
-    android_devices = android_device.FindAllAvailableDevices(args)
-    if not android_devices:
-      raise RuntimeError("No Android device found")
-    android_devices.sort(key=lambda device: device.name)
-    args.remote_platform_options.device = (
-        android_devices[child.worker_num-1].guid)
-  options_for_unittests.Push(args)
-
-
-def _TearDownProcess(child, context): # pylint: disable=unused-argument
-  # It's safe to call teardown_browser even if we did not start any browser
-  # in any of the tests.
-  browser_test_case.teardown_browser()
-  options_for_unittests.Pop()
-
-
-if __name__ == '__main__':
-  ret_code = RunTestsCommand.main()
-  sys.exit(ret_code)
diff --git a/catapult/telemetry/telemetry/testing/run_tests_unittest.py b/catapult/telemetry/telemetry/testing/run_tests_unittest.py
deleted file mode 100644
index 8728813..0000000
--- a/catapult/telemetry/telemetry/testing/run_tests_unittest.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.core import util
-from telemetry.testing import run_tests
-
-
-class MockArgs(object):
-  def __init__(self):
-    self.positional_args = []
-    self.exact_test_filter = True
-    self.run_disabled_tests = False
-    self.skip = []
-
-
-class MockPossibleBrowser(object):
-  def __init__(self, browser_type, os_name, os_version_name,
-               supports_tab_control):
-    self.browser_type = browser_type
-    self.platform = MockPlatform(os_name, os_version_name)
-    self.supports_tab_control = supports_tab_control
-
-
-class MockPlatform(object):
-  def __init__(self, os_name, os_version_name):
-    self.os_name = os_name
-    self.os_version_name = os_version_name
-
-  def GetOSName(self):
-    return self.os_name
-
-  def GetOSVersionName(self):
-    return self.os_version_name
-
-
-class RunTestsUnitTest(unittest.TestCase):
-
-  def _GetEnabledTests(self, browser_type, os_name, os_version_name,
-                       supports_tab_control, args=None):
-    if not args:
-      args = MockArgs()
-    runner = run_tests.typ.Runner()
-    host = runner.host
-    runner.top_level_dir = util.GetTelemetryDir()
-    runner.args.tests = [host.join(util.GetTelemetryDir(),
-        'telemetry', 'testing', 'disabled_cases.py')]
-    possible_browser = MockPossibleBrowser(
-        browser_type, os_name, os_version_name, supports_tab_control)
-    runner.classifier = run_tests.GetClassifier(args, possible_browser)
-    _, test_set = runner.find_tests(runner.args)
-    return set(test.name.split('.')[-1] for test in test_set.parallel_tests)
-
-  def testSystemMacMavericks(self):
-    self.assertEquals(
-        set(['testAllEnabled',
-             'testMacOnly',
-             'testMavericksOnly',
-             'testNoChromeOS',
-             'testNoWinLinux',
-             'testSystemOnly',
-             'testHasTabs']),
-        self._GetEnabledTests('system', 'mac', 'mavericks', True))
-
-  def testSystemMacLion(self):
-    self.assertEquals(
-        set(['testAllEnabled',
-             'testMacOnly',
-             'testNoChromeOS',
-             'testNoMavericks',
-             'testNoWinLinux',
-             'testSystemOnly',
-             'testHasTabs']),
-        self._GetEnabledTests('system', 'mac', 'lion', True))
-
-  def testCrosGuestChromeOS(self):
-    self.assertEquals(
-        set(['testAllEnabled',
-             'testChromeOSOnly',
-             'testNoMac',
-             'testNoMavericks',
-             'testNoSystem',
-             'testNoWinLinux',
-             'testHasTabs']),
-        self._GetEnabledTests('cros-guest', 'chromeos', '', True))
-
-  def testCanaryWindowsWin7(self):
-    self.assertEquals(
-        set(['testAllEnabled',
-             'testNoChromeOS',
-             'testNoMac',
-             'testNoMavericks',
-             'testNoSystem',
-             'testWinOrLinuxOnly',
-             'testHasTabs']),
-        self._GetEnabledTests('canary', 'win', 'win7', True))
-
-  def testDoesntHaveTabs(self):
-    self.assertEquals(
-        set(['testAllEnabled',
-             'testNoChromeOS',
-             'testNoMac',
-             'testNoMavericks',
-             'testNoSystem',
-             'testWinOrLinuxOnly']),
-        self._GetEnabledTests('canary', 'win', 'win7', False))
-
-  def testSkip(self):
-    args = MockArgs()
-    args.skip = ['telemetry.*testNoMac', '*NoMavericks',
-                 'telemetry.testing.disabled_cases.DisabledCases.testNoSystem']
-    self.assertEquals(
-        set(['testAllEnabled',
-             'testNoChromeOS',
-             'testWinOrLinuxOnly',
-             'testHasTabs']),
-        self._GetEnabledTests('canary', 'win', 'win7', True, args))
diff --git a/catapult/telemetry/telemetry/testing/serially_executed_browser_test_case.py b/catapult/telemetry/telemetry/testing/serially_executed_browser_test_case.py
deleted file mode 100644
index d0a4049..0000000
--- a/catapult/telemetry/telemetry/testing/serially_executed_browser_test_case.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import inspect
-import logging
-import re
-import unittest
-
-from py_utils import cloud_storage
-from telemetry.internal.browser import browser_finder
-from telemetry.testing import browser_test_context
-from telemetry.util import wpr_modes
-
-
-DEFAULT_LOG_FORMAT = (
-  '(%(levelname)s) %(asctime)s %(module)s.%(funcName)s:%(lineno)d  '
-  '%(message)s')
-
-
-class SeriallyExecutedBrowserTestCase(unittest.TestCase):
-  def __init__(self, methodName):
-    super(SeriallyExecutedBrowserTestCase, self).__init__(methodName)
-    self._private_methodname = methodName
-
-  def shortName(self):
-    """Returns the method name this test runs, without the package prefix."""
-    return self._private_methodname
-
-  @classmethod
-  def Name(cls):
-    return cls.__name__
-
-  @classmethod
-  def AddCommandlineArgs(cls, parser):
-    pass
-
-  @classmethod
-  def SetUpProcess(cls):
-    """ Set up testing logic before running the test case.
-    This is guaranteed to be called only once for all the tests before the test
-    suite runs.
-    """
-    finder_options = browser_test_context.GetCopy().finder_options
-    cls._finder_options = finder_options
-
-    # Set up logging based on the verbosity passed from the parent to
-    # the child process.
-    if finder_options.verbosity >= 2:
-      logging.getLogger().setLevel(logging.DEBUG)
-    elif finder_options.verbosity:
-      logging.getLogger().setLevel(logging.INFO)
-    else:
-      logging.getLogger().setLevel(logging.WARNING)
-    logging.basicConfig(format=DEFAULT_LOG_FORMAT)
-
-    cls.platform = None
-    cls.browser = None
-    cls._browser_to_create = None
-    cls._browser_options = None
-
-  @classmethod
-  def SetBrowserOptions(cls, browser_options):
-    """Sets the browser option for the browser to create.
-
-    Args:
-      browser_options: Browser options object for the browser we want to test.
-    """
-    cls._browser_options = browser_options
-    cls._browser_to_create = browser_finder.FindBrowser(browser_options)
-    if not cls.platform:
-      cls.platform = cls._browser_to_create.platform
-      cls.platform.network_controller.InitializeIfNeeded()
-    else:
-      assert cls.platform == cls._browser_to_create.platform, (
-          'All browser launches within same test suite must use browsers on '
-          'the same platform')
-
-  @classmethod
-  def StartWPRServer(cls, archive_path=None, archive_bucket=None):
-    """Start a webpage replay server.
-
-    Args:
-      archive_path: Path to the WPR file. If there is a corresponding sha1 file,
-          this archive will be automatically downloaded from Google Storage.
-      archive_bucket: The bucket to look for the WPR archive.
-    """
-    assert cls._browser_options, (
-        'Browser options must be set with |SetBrowserOptions| prior to '
-        'starting WPR')
-    assert not cls.browser, 'WPR must be started prior to browser being started'
-
-    cloud_storage.GetIfChanged(archive_path, archive_bucket)
-    cls.platform.network_controller.Open(wpr_modes.WPR_REPLAY, [])
-    cls.platform.network_controller.StartReplay(archive_path=archive_path)
-
-  @classmethod
-  def StopWPRServer(cls):
-    cls.platform.network_controller.StopReplay()
-
-  @classmethod
-  def StartBrowser(cls):
-    assert cls._browser_options, (
-        'Browser options must be set with |SetBrowserOptions| prior to '
-        'starting WPR')
-    assert not cls.browser, 'Browser is started. Must close it first'
-
-    cls.browser = cls._browser_to_create.Create(cls._browser_options)
-
-  @classmethod
-  def StopBrowser(cls):
-    assert cls.browser, 'Browser is not started'
-    cls.browser.Close()
-    cls.browser = None
-
-  @classmethod
-  def TearDownProcess(cls):
-    """ Tear down the testing logic after running the test cases.
-    This is guaranteed to be called only once for all the tests after the test
-    suite finishes running.
-    """
-
-    if cls.platform:
-      cls.platform.StopAllLocalServers()
-      cls.platform.network_controller.Close()
-    if cls.browser:
-      cls.StopBrowser()
-
-  @classmethod
-  def SetStaticServerDirs(cls, dirs_path):
-    assert cls.platform
-    assert isinstance(dirs_path, list)
-    cls.platform.SetHTTPServerDirectories(dirs_path)
-
-  @classmethod
-  def UrlOfStaticFilePath(cls, file_path):
-    return cls.platform.http_server.UrlOf(file_path)
-
-
-def LoadAllTestsInModule(module):
-  """ Load all tests & generated browser tests in a given module.
-
-  This is supposed to be invoke in load_tests() method of your test modules that
-  use browser_test_runner framework to discover & generate the tests to be
-  picked up by the test runner. Here is the example of how your test module
-  should looks like:
-
-  ################## my_awesome_browser_tests.py  ################
-  import sys
-
-  from telemetry.testing import serially_executed_browser_test_case
-  ...
-
-  class TestSimpleBrowser(
-      serially_executed_browser_test_case.SeriallyExecutedBrowserTestCase):
-  ...
-  ...
-
-  def load_tests(loader, tests, pattern):
-    return serially_executed_browser_test_case.LoadAllTestsInModule(
-        sys.modules[__name__])
-  #################################################################
-
-  Args:
-    module: the module which contains test cases classes.
-
-  Returns:
-    an instance of unittest.TestSuite, which contains all the tests & generated
-    test cases to be run.
-  """
-  suite = unittest.TestSuite()
-  test_context = browser_test_context.GetCopy()
-  if not test_context:
-    return suite
-  for _, obj in inspect.getmembers(module):
-    if (inspect.isclass(obj) and
-        issubclass(obj, SeriallyExecutedBrowserTestCase)):
-      # We bail out early if this class doesn't match the targeted
-      # test_class in test_context to avoid calling GenerateTestCases
-      # for tests that we don't intend to run. This is to avoid possible errors
-      # in GenerateTestCases as the test class may define custom options in
-      # the finder_options object, and hence would raise error if they can't
-      # find their custom options in finder_options object.
-      if test_context.test_class != obj:
-        continue
-      for test in GenerateTestCases(
-          test_class=obj, finder_options=test_context.finder_options):
-        if test.id() in test_context.test_case_ids_to_run:
-          suite.addTest(test)
-  return suite
-
-
-def _GenerateTestMethod(based_method, args):
-  return lambda self: based_method(self, *args)
-
-
-_TEST_GENERATOR_PREFIX = 'GenerateTestCases_'
-_INVALID_TEST_NAME_RE = re.compile(r'[^a-zA-Z0-9_]')
-
-def _ValidateTestMethodname(test_name):
-  assert not bool(_INVALID_TEST_NAME_RE.search(test_name))
-
-
-def GenerateTestCases(test_class, finder_options):
-  test_cases = []
-  for name, method in inspect.getmembers(
-      test_class, predicate=inspect.ismethod):
-    if name.startswith('test'):
-      # Do not allow method names starting with "test" in these
-      # subclasses, to avoid collisions with Python's unit test runner.
-      raise Exception('Name collision with Python\'s unittest runner: %s' %
-                      name)
-    elif name.startswith('Test'):
-      # Pass these through for the time being. We may want to rethink
-      # how they are handled in the future.
-      test_cases.append(test_class(name))
-    elif name.startswith(_TEST_GENERATOR_PREFIX):
-      based_method_name = name[len(_TEST_GENERATOR_PREFIX):]
-      assert hasattr(test_class, based_method_name), (
-          '%s is specified but based method %s does not exist' %
-          (name, based_method_name))
-      based_method = getattr(test_class, based_method_name)
-      for generated_test_name, args in method(finder_options):
-        _ValidateTestMethodname(generated_test_name)
-        setattr(test_class, generated_test_name, _GenerateTestMethod(
-            based_method, args))
-        test_cases.append(test_class(generated_test_name))
-  return test_cases
diff --git a/catapult/telemetry/telemetry/testing/simple_mock.py b/catapult/telemetry/telemetry/testing/simple_mock.py
deleted file mode 100644
index dbd02b6..0000000
--- a/catapult/telemetry/telemetry/testing/simple_mock.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""A very very simple mock object harness."""
-
-DONT_CARE = ''
-
-class MockFunctionCall(object):
-  def __init__(self, name):
-    self.name = name
-    self.args = tuple()
-    self.return_value = None
-    self.when_called_handlers = []
-
-  def WithArgs(self, *args):
-    self.args = args
-    return self
-
-  def WillReturn(self, value):
-    self.return_value = value
-    return self
-
-  def WhenCalled(self, handler):
-    self.when_called_handlers.append(handler)
-
-  def VerifyEquals(self, got):
-    if self.name != got.name:
-      raise Exception('Self %s, got %s' % (repr(self), repr(got)))
-    if len(self.args) != len(got.args):
-      raise Exception('Self %s, got %s' % (repr(self), repr(got)))
-    for i in range(len(self.args)):
-      self_a = self.args[i]
-      got_a = got.args[i]
-      if self_a == DONT_CARE:
-        continue
-      if self_a != got_a:
-        raise Exception('Self %s, got %s' % (repr(self), repr(got)))
-
-  def __repr__(self):
-    def arg_to_text(a):
-      if a == DONT_CARE:
-        return '_'
-      return repr(a)
-    args_text = ', '.join([arg_to_text(a) for a in self.args])
-    if self.return_value in (None, DONT_CARE):
-      return '%s(%s)' % (self.name, args_text)
-    return '%s(%s)->%s' % (self.name, args_text, repr(self.return_value))
-
-class MockTrace(object):
-  def __init__(self):
-    self.expected_calls = []
-    self.next_call_index = 0
-
-class MockObject(object):
-  def __init__(self, parent_mock=None):
-    if parent_mock:
-      self._trace = parent_mock._trace # pylint: disable=protected-access
-    else:
-      self._trace = MockTrace()
-
-  def __setattr__(self, name, value):
-    if (not hasattr(self, '_trace') or
-        hasattr(value, 'is_hook')):
-      object.__setattr__(self, name, value)
-      return
-    assert isinstance(value, MockObject)
-    object.__setattr__(self, name, value)
-
-  def SetAttribute(self, name, value):
-    setattr(self, name, value)
-
-  def ExpectCall(self, func_name, *args):
-    assert self._trace.next_call_index == 0
-    if not hasattr(self, func_name):
-      self._install_hook(func_name)
-
-    call = MockFunctionCall(func_name)
-    self._trace.expected_calls.append(call)
-    call.WithArgs(*args)
-    return call
-
-  def _install_hook(self, func_name):
-    def handler(*args, **_):
-      got_call = MockFunctionCall(
-        func_name).WithArgs(*args).WillReturn(DONT_CARE)
-      if self._trace.next_call_index >= len(self._trace.expected_calls):
-        raise Exception(
-          'Call to %s was not expected, at end of programmed trace.' %
-          repr(got_call))
-      expected_call = self._trace.expected_calls[
-        self._trace.next_call_index]
-      expected_call.VerifyEquals(got_call)
-      self._trace.next_call_index += 1
-      for h in expected_call.when_called_handlers:
-        h(*args)
-      return expected_call.return_value
-    handler.is_hook = True
-    setattr(self, func_name, handler)
diff --git a/catapult/telemetry/telemetry/testing/simple_mock_unittest.py b/catapult/telemetry/telemetry/testing/simple_mock_unittest.py
deleted file mode 100644
index 67cee58..0000000
--- a/catapult/telemetry/telemetry/testing/simple_mock_unittest.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.testing import simple_mock
-
-_ = simple_mock.DONT_CARE
-
-# pylint: disable=no-member
-class SimpleMockUnitTest(unittest.TestCase):
-  def testBasic(self):
-    mock = simple_mock.MockObject()
-    mock.ExpectCall('foo')
-
-    mock.foo()
-
-  def testReturn(self):
-    mock = simple_mock.MockObject()
-    mock.ExpectCall('foo').WillReturn(7)
-
-    ret = mock.foo()
-    self.assertEquals(ret, 7)
-
-  def testArgs(self):
-    mock = simple_mock.MockObject()
-    mock.ExpectCall('foo').WithArgs(3, 4)
-
-    mock.foo(3, 4)
-
-  def testArgs2(self):
-    mock = simple_mock.MockObject()
-    mock.ExpectCall('foo', 3, 4)
-
-    mock.foo(3, 4)
-
-  def testArgsMismatch(self):
-    mock = simple_mock.MockObject()
-    mock.ExpectCall('foo').WithArgs(3, 4)
-
-    self.assertRaises(Exception,
-                      lambda: mock.foo(4, 4))
-
-
-  def testArgsDontCare(self):
-    mock = simple_mock.MockObject()
-    mock.ExpectCall('foo').WithArgs(_, 4)
-
-    mock.foo(4, 4)
-
-  def testOnCall(self):
-    mock = simple_mock.MockObject()
-
-    handler_called = []
-    def Handler(arg0):
-      assert arg0 == 7
-      handler_called.append(True)
-    mock.ExpectCall('baz', 7).WhenCalled(Handler)
-
-    mock.baz(7)
-    self.assertTrue(len(handler_called) > 0)
-
-
-  def testSubObject(self):
-    mock = simple_mock.MockObject()
-    mock.bar = simple_mock.MockObject(mock)
-
-    mock.ExpectCall('foo').WithArgs(_, 4)
-    mock.bar.ExpectCall('baz')
-
-    mock.foo(0, 4)
-    mock.bar.baz()
-
-  def testSubObjectMismatch(self):
-    mock = simple_mock.MockObject()
-    mock.bar = simple_mock.MockObject(mock)
-
-    mock.ExpectCall('foo').WithArgs(_, 4)
-    mock.bar.ExpectCall('baz')
-
-    self.assertRaises(
-      Exception,
-      lambda: mock.bar.baz()) # pylint: disable=unnecessary-lambda
diff --git a/catapult/telemetry/telemetry/testing/story_set_smoke_test.py b/catapult/telemetry/telemetry/testing/story_set_smoke_test.py
deleted file mode 100644
index 8697741..0000000
--- a/catapult/telemetry/telemetry/testing/story_set_smoke_test.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import unittest
-
-from telemetry.core import discover
-from telemetry.internal.browser import browser_credentials
-from telemetry.internal import story_runner
-from telemetry import page
-from telemetry import story as story_module
-from telemetry.wpr import archive_info
-
-
-class StorySetSmokeTest(unittest.TestCase):
-
-  def setUp(self):
-    # Make sure the added failure message is appended to the default failure
-    # message.
-    self.longMessage = True
-
-  def GetAllStorySetClasses(self, story_sets_dir, top_level_dir):
-    # We can't test page sets that aren't directly constructible since we
-    # don't know what arguments to put for the constructor.
-    return discover.DiscoverClasses(story_sets_dir, top_level_dir,
-                                    story_module.StorySet,
-                                    directly_constructable=True).values()
-
-  def CheckArchive(self, story_set):
-    """Verify that all URLs of pages in story_set have an associated archive."""
-    # TODO: Eventually these should be fatal.
-    if not story_set.archive_data_file:
-      logging.warning('Skipping %s: no archive data file', story_set.file_path)
-      return
-
-    logging.info('Testing %s', story_set.file_path)
-
-    archive_data_file_path = os.path.join(story_set.base_dir,
-                                          story_set.archive_data_file)
-    self.assertTrue(os.path.exists(archive_data_file_path),
-                    msg='Archive data file not found for %s' %
-                    story_set.file_path)
-
-    wpr_archive_info = archive_info.WprArchiveInfo.FromFile(
-        archive_data_file_path, story_set.bucket)
-    for story in story_set.stories:
-      if isinstance(story, page.Page) and story.url.startswith('http'):
-        self.assertTrue(wpr_archive_info.WprFilePathForStory(story),
-                        msg='No archive found for %s in %s' % (
-                            story.url, story_set.archive_data_file))
-
-  def CheckCredentials(self, story_set):
-    """Verify that all pages in story_set use proper credentials"""
-    for story in story_set.stories:
-      if not isinstance(story, page.Page):
-        continue
-      credentials = browser_credentials.BrowserCredentials()
-      if story.credentials_path:
-        credentials.credentials_path = (
-            os.path.join(story.base_dir, story.credentials_path))
-      fail_message = ('page %s of %s has invalid credentials %s' %
-                      (story.url, story_set.file_path, story.credentials))
-      if story.credentials:
-        try:
-          self.assertTrue(credentials.CanLogin(story.credentials), fail_message)
-        except browser_credentials.CredentialsError:
-          self.fail(fail_message)
-
-  def CheckAttributes(self, story_set):
-    """Verify that story_set and its stories base attributes have the right
-       types.
-    """
-    self.CheckAttributesOfStorySetBasicAttributes(story_set)
-    for story in story_set.stories:
-      self.CheckAttributesOfStoryBasicAttributes(story)
-
-  def CheckAttributesOfStorySetBasicAttributes(self, story_set):
-    if story_set.base_dir is not None:
-      self.assertTrue(
-          isinstance(story_set.base_dir, str),
-          msg='story_set %\'s base_dir must have type string')
-
-    self.assertTrue(
-        isinstance(story_set.archive_data_file, str),
-        msg='story_set\'s archive_data_file path must have type string')
-
-  def CheckAttributesOfStoryBasicAttributes(self, story):
-    self.assertTrue(not hasattr(story, 'disabled'))
-    self.assertTrue(
-       isinstance(story.name, str),
-       msg='story %s \'s name field must have type string' % story.display_name)
-    self.assertTrue(
-       isinstance(story.tags, set),
-       msg='story %s \'s tags field must have type set' % story.display_name)
-    for t in story.tags:
-      self.assertTrue(
-         isinstance(t, str),
-         msg='tag %s in story %s \'s tags must have type string'
-         % (str(t), story.display_name))
-    if not isinstance(story, page.Page):
-      return
-    self.assertTrue(
-       # We use basestring instead of str because story's URL can be string of
-       # unicode.
-       isinstance(story.url, basestring),
-       msg='page %s \'s url must have type string' % story.display_name)
-    self.assertTrue(
-        isinstance(story.startup_url, str),
-        msg=('page %s \'s startup_url field must have type string'
-            % story.display_name))
-    self.assertIsInstance(
-        story.make_javascript_deterministic, bool,
-        msg='page %s \'s make_javascript_deterministic must have type bool'
-            % story.display_name)
-
-  def CheckSharedStates(self, story_set):
-    if not story_set.allow_mixed_story_states:
-      shared_state_class = (
-          story_set.stories[0].shared_state_class)
-      for story in story_set:
-        self.assertIs(
-            shared_state_class,
-            story.shared_state_class,
-            msg='story %s\'s shared_state_class field is different '
-            'from other story\'s shared_state_class whereas '
-            'story set %s disallows having mixed states' %
-            (story, story_set))
-
-  def CheckPassingStoryRunnerValidation(self, story_set):
-    errors = []
-    for s in story_set:
-      try:
-        story_runner.ValidateStory(s)
-      except ValueError as e:
-        errors.append(e)
-    self.assertFalse(
-        errors, 'Errors validating user stories in %s:\n %s' % (
-            story_set, '\n'.join(e.message for e in errors)))
-
-  def RunSmokeTest(self, story_sets_dir, top_level_dir):
-    """Run smoke test on all story sets in story_sets_dir.
-
-    Subclass of StorySetSmokeTest is supposed to call this in some test
-    method to run smoke test.
-    """
-    story_sets = self.GetAllStorySetClasses(story_sets_dir, top_level_dir)
-    for story_set_class in story_sets:
-      story_set = story_set_class()
-      self.CheckArchive(story_set)
-      self.CheckCredentials(story_set)
-      self.CheckAttributes(story_set)
-      self.CheckSharedStates(story_set)
-      self.CheckPassingStoryRunnerValidation(story_set)
diff --git a/catapult/telemetry/telemetry/testing/stream.py b/catapult/telemetry/telemetry/testing/stream.py
deleted file mode 100644
index 4d97ab4..0000000
--- a/catapult/telemetry/telemetry/testing/stream.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class TestOutputStream(object):
-  def __init__(self):
-    self._output_data = []
-
-  @property
-  def output_data(self):
-    return ''.join(self._output_data)
-
-  def write(self, data):
-    self._output_data.append(data)
-
-  def flush(self):
-    pass
diff --git a/catapult/telemetry/telemetry/testing/system_stub.py b/catapult/telemetry/telemetry/testing/system_stub.py
deleted file mode 100644
index 78e152f..0000000
--- a/catapult/telemetry/telemetry/testing/system_stub.py
+++ /dev/null
@@ -1,491 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides stubs for os, sys and subprocess for testing
-
-This test allows one to test code that itself uses os, sys, and subprocess.
-"""
-
-import ntpath
-import os
-import posixpath
-import re
-import shlex
-import sys
-
-
-class Override(object):
-
-  _overidden_modules = set()
-
-  def __init__(self, base_module, module_list):
-    self.cloud_storage = None
-    self.open = None
-    self.os = None
-    self.perf_control = None
-    self.raw_input = None
-    self.subprocess = None
-    self.sys = None
-    self.thermal_throttle = None
-    self.logging = None
-    stubs = {'cloud_storage': CloudStorageModuleStub,
-             'open': OpenFunctionStub,
-             'os': OsModuleStub,
-             'perf_control': PerfControlModuleStub,
-             'raw_input': RawInputFunctionStub,
-             'subprocess': SubprocessModuleStub,
-             'sys': SysModuleStub,
-             'thermal_throttle': ThermalThrottleModuleStub,
-             'logging': LoggingStub,
-    }
-    self.adb_commands = None
-    self.os = None
-    self.subprocess = None
-    self.sys = None
-
-    assert base_module not in self._overidden_modules, (
-        '%s is already overridden' % base_module.__name__)
-    self._overidden_modules.add(base_module)
-    self._base_module = base_module
-    self._overrides = {}
-
-    for module_name in module_list:
-      self._overrides[module_name] = getattr(base_module, module_name, None)
-      setattr(self, module_name, stubs[module_name]())
-      setattr(base_module, module_name, getattr(self, module_name))
-
-    if self.os and self.sys:
-      self.os.path.sys = self.sys
-
-  def __del__(self):
-    assert not len(self._overrides)
-
-  def Restore(self):
-    for module_name, original_module in self._overrides.iteritems():
-      if original_module is None:
-        # This will happen when we override built-in functions, like open.
-        # If we don't delete the attribute, we will shadow the built-in
-        # function with an attribute set to None.
-        delattr(self._base_module, module_name)
-      else:
-        setattr(self._base_module, module_name, original_module)
-    self._overrides = {}
-    self._overidden_modules.remove(self._base_module)
-    self._base_module = None
-
-
-class AdbDevice(object):
-
-  def __init__(self):
-    self.has_root = False
-    self.needs_su = False
-    self.shell_command_handlers = {}
-    self.mock_content = []
-    self.system_properties = {}
-    if self.system_properties.get('ro.product.cpu.abi') == None:
-      self.system_properties['ro.product.cpu.abi'] = 'armeabi-v7a'
-
-  def HasRoot(self):
-    return self.has_root
-
-  def NeedsSU(self):
-    return self.needs_su
-
-  def RunShellCommand(self, args, **kwargs):
-    del kwargs  # unused
-    if isinstance(args, basestring):
-      args = shlex.split(args)
-    handler = self.shell_command_handlers[args[0]]
-    return handler(args)
-
-  def FileExists(self, _):
-    return False
-
-  def ReadFile(self, device_path, as_root=False):
-    del device_path, as_root  # unused
-    return self.mock_content
-
-  def GetProp(self, property_name):
-    return self.system_properties[property_name]
-
-  def SetProp(self, property_name, property_value):
-    self.system_properties[property_name] = property_value
-
-
-class CloudStorageModuleStub(object):
-  PUBLIC_BUCKET = 'chromium-telemetry'
-  PARTNER_BUCKET = 'chrome-partner-telemetry'
-  INTERNAL_BUCKET = 'chrome-telemetry'
-  BUCKET_ALIASES = {
-    'public': PUBLIC_BUCKET,
-    'partner': PARTNER_BUCKET,
-    'internal': INTERNAL_BUCKET,
-  }
-
-  # These are used to test for CloudStorage errors.
-  INTERNAL_PERMISSION = 2
-  PARTNER_PERMISSION = 1
-  PUBLIC_PERMISSION = 0
-  # Not logged in.
-  CREDENTIALS_ERROR_PERMISSION = -1
-
-  class NotFoundError(Exception):
-    pass
-
-  class CloudStorageError(Exception):
-    pass
-
-  class PermissionError(CloudStorageError):
-    pass
-
-  class CredentialsError(CloudStorageError):
-    pass
-
-  def __init__(self):
-    self.default_remote_paths = {CloudStorageModuleStub.INTERNAL_BUCKET:{},
-                                 CloudStorageModuleStub.PARTNER_BUCKET:{},
-                                 CloudStorageModuleStub.PUBLIC_BUCKET:{}}
-    self.remote_paths = self.default_remote_paths
-    self.local_file_hashes = {}
-    self.local_hash_files = {}
-    self.permission_level = CloudStorageModuleStub.INTERNAL_PERMISSION
-    self.downloaded_files = []
-
-  def SetPermissionLevelForTesting(self, permission_level):
-    self.permission_level = permission_level
-
-  def CheckPermissionLevelForBucket(self, bucket):
-    if bucket == CloudStorageModuleStub.PUBLIC_BUCKET:
-      return
-    elif (self.permission_level ==
-          CloudStorageModuleStub.CREDENTIALS_ERROR_PERMISSION):
-      raise CloudStorageModuleStub.CredentialsError()
-    elif bucket == CloudStorageModuleStub.PARTNER_BUCKET:
-      if self.permission_level < CloudStorageModuleStub.PARTNER_PERMISSION:
-        raise CloudStorageModuleStub.PermissionError()
-    elif bucket == CloudStorageModuleStub.INTERNAL_BUCKET:
-      if self.permission_level < CloudStorageModuleStub.INTERNAL_PERMISSION:
-        raise CloudStorageModuleStub.PermissionError()
-    elif bucket not in self.remote_paths:
-      raise CloudStorageModuleStub.NotFoundError()
-
-  def SetRemotePathsForTesting(self, remote_path_dict=None):
-    if not remote_path_dict:
-      self.remote_paths = self.default_remote_paths
-      return
-    self.remote_paths = remote_path_dict
-
-  def GetRemotePathsForTesting(self):
-    if not self.remote_paths:
-      self.remote_paths = self.default_remote_paths
-    return self.remote_paths
-
-  # Set a dictionary of data files and their "calculated" hashes.
-  def SetCalculatedHashesForTesting(self, calculated_hash_dictionary):
-    self.local_file_hashes = calculated_hash_dictionary
-
-  def GetLocalDataFiles(self):
-    return self.local_file_hashes.keys()
-
-  # Set a dictionary of hash files and the hashes they should contain.
-  def SetHashFileContentsForTesting(self, hash_file_dictionary):
-    self.local_hash_files = hash_file_dictionary
-
-  def GetLocalHashFiles(self):
-    return self.local_hash_files.keys()
-
-  def ChangeRemoteHashForTesting(self, bucket, remote_path, new_hash):
-    self.remote_paths[bucket][remote_path] = new_hash
-
-  def List(self, bucket):
-    if not bucket or not bucket in self.remote_paths:
-      bucket_error = ('Incorrect bucket specified, correct buckets:' +
-                      str(self.remote_paths))
-      raise CloudStorageModuleStub.CloudStorageError(bucket_error)
-    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
-    return list(self.remote_paths[bucket].keys())
-
-  def Exists(self, bucket, remote_path):
-    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
-    return remote_path in self.remote_paths[bucket]
-
-  def Insert(self, bucket, remote_path, local_path):
-    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
-    if not local_path in self.GetLocalDataFiles():
-      file_path_error = 'Local file path does not exist'
-      raise CloudStorageModuleStub.CloudStorageError(file_path_error)
-    self.remote_paths[bucket][remote_path] = (
-      CloudStorageModuleStub.CalculateHash(self, local_path))
-    return remote_path
-
-  def GetHelper(self, bucket, remote_path, local_path, only_if_changed):
-    CloudStorageModuleStub.CheckPermissionLevelForBucket(self, bucket)
-    if not remote_path in self.remote_paths[bucket]:
-      if only_if_changed:
-        return False
-      raise CloudStorageModuleStub.NotFoundError('Remote file does not exist.')
-    remote_hash = self.remote_paths[bucket][remote_path]
-    local_hash = self.local_file_hashes[local_path]
-    if only_if_changed and remote_hash == local_hash:
-      return False
-    self.downloaded_files.append(remote_path)
-    self.local_file_hashes[local_path] = remote_hash
-    self.local_hash_files[local_path + '.sha1'] = remote_hash
-    return remote_hash
-
-  def Get(self, bucket, remote_path, local_path):
-    return CloudStorageModuleStub.GetHelper(self, bucket, remote_path,
-                                            local_path, False)
-
-  def GetIfChanged(self, local_path, bucket=None):
-    remote_path = os.path.basename(local_path)
-    if bucket:
-      return CloudStorageModuleStub.GetHelper(self, bucket, remote_path,
-                                              local_path, True)
-    result = CloudStorageModuleStub.GetHelper(
-        self, self.PUBLIC_BUCKET, remote_path, local_path, True)
-    if not result:
-      result = CloudStorageModuleStub.GetHelper(
-          self, self.PARTNER_BUCKET, remote_path, local_path, True)
-    if not result:
-      result = CloudStorageModuleStub.GetHelper(
-          self, self.INTERNAL_BUCKET, remote_path, local_path, True)
-    return result
-
-  def GetFilesInDirectoryIfChanged(self, directory, bucket):
-    if os.path.dirname(directory) == directory: # If in the root dir.
-      raise ValueError('Trying to serve root directory from HTTP server.')
-    for dirpath, _, filenames in os.walk(directory):
-      for filename in filenames:
-        path, extension = os.path.splitext(
-            os.path.join(dirpath, filename))
-        if extension != '.sha1':
-          continue
-        self.GetIfChanged(path, bucket)
-
-  def CalculateHash(self, file_path):
-    return self.local_file_hashes[file_path]
-
-  def ReadHash(self, hash_path):
-    return self.local_hash_files[hash_path]
-
-
-class LoggingStub(object):
-  def __init__(self):
-    self.warnings = []
-    self.errors = []
-
-  def info(self, msg, *args):
-    pass
-
-  def error(self, msg, *args):
-    self.errors.append(msg % args)
-
-  def warning(self, msg, *args):
-    self.warnings.append(msg % args)
-
-  def warn(self, msg, *args):
-    self.warning(msg, *args)
-
-
-class OpenFunctionStub(object):
-  class FileStub(object):
-    def __init__(self, data):
-      self._data = data
-
-    def __enter__(self):
-      return self
-
-    def __exit__(self, *args):
-      pass
-
-    def read(self, size=None):
-      if size:
-        return self._data[:size]
-      else:
-        return self._data
-
-    def write(self, data):
-      self._data.write(data)
-
-    def close(self):
-      pass
-
-  def __init__(self):
-    self.files = {}
-
-  def __call__(self, name, *args, **kwargs):
-    return OpenFunctionStub.FileStub(self.files[name])
-
-
-class OsModuleStub(object):
-  class OsEnvironModuleStub(object):
-    def get(self, _):
-      return None
-
-  class OsPathModuleStub(object):
-    def __init__(self, sys_module):
-      self.sys = sys_module
-      self.files = []
-      self.dirs = []
-
-    def exists(self, path):
-      return path in self.files
-
-    def isfile(self, path):
-      return path in self.files
-
-    def isdir(self, path):
-      return path in self.dirs
-
-    def join(self, *paths):
-      def IsAbsolutePath(path):
-        if self.sys.platform.startswith('win'):
-          return re.match('[a-zA-Z]:\\\\', path)
-        else:
-          return path.startswith('/')
-
-      # Per Python specification, if any component is an absolute path,
-      # discard previous components.
-      for index, path in reversed(list(enumerate(paths))):
-        if IsAbsolutePath(path):
-          paths = paths[index:]
-          break
-
-      if self.sys.platform.startswith('win'):
-        tmp = os.path.join(*paths)
-        return tmp.replace('/', '\\')
-      else:
-        tmp = os.path.join(*paths)
-        return tmp.replace('\\', '/')
-
-    def basename(self, path):
-      if self.sys.platform.startswith('win'):
-        return ntpath.basename(path)
-      else:
-        return posixpath.basename(path)
-
-    @staticmethod
-    def abspath(path):
-      return os.path.abspath(path)
-
-    @staticmethod
-    def expanduser(path):
-      return os.path.expanduser(path)
-
-    @staticmethod
-    def dirname(path):
-      return os.path.dirname(path)
-
-    @staticmethod
-    def realpath(path):
-      return os.path.realpath(path)
-
-    @staticmethod
-    def split(path):
-      return os.path.split(path)
-
-    @staticmethod
-    def splitext(path):
-      return os.path.splitext(path)
-
-    @staticmethod
-    def splitdrive(path):
-      return os.path.splitdrive(path)
-
-  X_OK = os.X_OK
-
-  sep = os.sep
-  pathsep = os.pathsep
-
-  def __init__(self, sys_module=sys):
-    self.path = OsModuleStub.OsPathModuleStub(sys_module)
-    self.environ = OsModuleStub.OsEnvironModuleStub()
-    self.display = ':0'
-    self.local_app_data = None
-    self.sys_path = None
-    self.program_files = None
-    self.program_files_x86 = None
-    self.devnull = os.devnull
-    self._directory = {}
-
-  def access(self, path, _):
-    return path in self.path.files
-
-  def getenv(self, name, value=None):
-    if name == 'DISPLAY':
-      env = self.display
-    elif name == 'LOCALAPPDATA':
-      env = self.local_app_data
-    elif name == 'PATH':
-      env = self.sys_path
-    elif name == 'PROGRAMFILES':
-      env = self.program_files
-    elif name == 'PROGRAMFILES(X86)':
-      env = self.program_files_x86
-    else:
-      raise NotImplementedError('Unsupported getenv')
-    return env if env else value
-
-  def chdir(self, path):
-    pass
-
-  def walk(self, top):
-    for dir_name in self._directory:
-      yield top, dir_name, self._directory[dir_name]
-
-
-class PerfControlModuleStub(object):
-  class PerfControlStub(object):
-    def __init__(self, adb):
-      pass
-
-  def __init__(self):
-    self.PerfControl = PerfControlModuleStub.PerfControlStub
-
-
-class RawInputFunctionStub(object):
-  def __init__(self):
-    self.input = ''
-
-  def __call__(self, name, *args, **kwargs):
-    return self.input
-
-
-class SubprocessModuleStub(object):
-  class PopenStub(object):
-    def __init__(self):
-      self.communicate_result = ('', '')
-      self.returncode_result = 0
-
-    def __call__(self, args, **kwargs):
-      return self
-
-    def communicate(self):
-      return self.communicate_result
-
-    @property
-    def returncode(self):
-      return self.returncode_result
-
-  def __init__(self):
-    self.Popen = SubprocessModuleStub.PopenStub()
-    self.PIPE = None
-
-  def call(self, *args, **kwargs):
-    pass
-
-
-class SysModuleStub(object):
-  def __init__(self):
-    self.platform = ''
-
-
-class ThermalThrottleModuleStub(object):
-  class ThermalThrottleStub(object):
-    def __init__(self, adb):
-      pass
-
-  def __init__(self):
-    self.ThermalThrottle = ThermalThrottleModuleStub.ThermalThrottleStub
diff --git a/catapult/telemetry/telemetry/testing/system_stub_unittest.py b/catapult/telemetry/telemetry/testing/system_stub_unittest.py
deleted file mode 100644
index 5a23ed4..0000000
--- a/catapult/telemetry/telemetry/testing/system_stub_unittest.py
+++ /dev/null
@@ -1,251 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-PERF_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-from telemetry.testing import system_stub
-from telemetry.internal.testing import system_stub_test_module
-
-class CloudStorageTest(unittest.TestCase):
-  SUCCESS_FILE_HASH = 'success'.zfill(40)
-  PUBLIC_FILE_HASH = 'public'.zfill(40)
-  PARTNER_FILE_HASH = 'partner'.zfill(40)
-  INTERNAL_FILE_HASH = 'internal'.zfill(40)
-  UPDATED_HASH = 'updated'.zfill(40)
-
-  def setUp(self):
-    self.cloud_storage = system_stub.CloudStorageModuleStub()
-
-    # Files in Cloud Storage.
-    self.remote_files = ['preset_public_file.wpr',
-                         'preset_partner_file.wpr',
-                         'preset_internal_file.wpr']
-    self.remote_paths = {
-      self.cloud_storage.PUBLIC_BUCKET:
-        {'preset_public_file.wpr':CloudStorageTest.PUBLIC_FILE_HASH},
-      self.cloud_storage.PARTNER_BUCKET:
-        {'preset_partner_file.wpr':CloudStorageTest.PARTNER_FILE_HASH},
-      self.cloud_storage.INTERNAL_BUCKET:
-        {'preset_internal_file.wpr':CloudStorageTest.INTERNAL_FILE_HASH}}
-
-    # Local data files and hashes.
-    self.data_files = [
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'),
-        os.path.join(os.path.sep, 'path', 'to', 'wrong_hash.wpr'),
-        os.path.join(os.path.sep, 'path', 'to', 'preset_public_file.wpr'),
-        os.path.join(os.path.sep, 'path', 'to', 'preset_partner_file.wpr'),
-        os.path.join(os.path.sep, 'path', 'to', 'preset_internal_file.wpr')]
-    self.local_file_hashes = {
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'):
-            CloudStorageTest.SUCCESS_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to', 'wrong_hash.wpr'):
-            CloudStorageTest.SUCCESS_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to', 'preset_public_file.wpr'):
-            CloudStorageTest.PUBLIC_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to', 'preset_partner_file.wpr'):
-            CloudStorageTest.PARTNER_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to', 'preset_internal_file.wpr'):
-            CloudStorageTest.INTERNAL_FILE_HASH,
-    }
-    self.cloud_storage.SetCalculatedHashesForTesting(self.local_file_hashes)
-    # Local hash files and their contents.
-    local_hash_files = {
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr.sha1'):
-            CloudStorageTest.SUCCESS_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to', 'wrong_hash.wpr.sha1'):
-            'wronghash'.zfill(40),
-        os.path.join(os.path.sep, 'path', 'to', 'preset_public_file.wpr.sha1'):
-            CloudStorageTest.PUBLIC_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to', 'preset_partner_file.wpr.sha1'):
-            CloudStorageTest.PARTNER_FILE_HASH,
-        os.path.join(os.path.sep, 'path', 'to',
-                     'preset_internal_file.wpr.sha1'):
-            CloudStorageTest.INTERNAL_FILE_HASH,
-    }
-    self.cloud_storage.SetHashFileContentsForTesting(local_hash_files)
-
-  def testSetup(self):
-    self.assertEqual(self.local_file_hashes,
-                     self.cloud_storage.local_file_hashes)
-    self.assertEqual(set(self.data_files),
-                     set(self.cloud_storage.GetLocalDataFiles()))
-    self.assertEqual(self.cloud_storage.default_remote_paths,
-                     self.cloud_storage.GetRemotePathsForTesting())
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.assertEqual(self.remote_paths,
-                     self.cloud_storage.GetRemotePathsForTesting())
-
-  def testExistsEmptyCloudStorage(self):
-    # Test empty remote files dictionary.
-    self.assertFalse(self.cloud_storage.Exists(self.cloud_storage.PUBLIC_BUCKET,
-                                               'preset_public_file.wpr'))
-    self.assertFalse(self.cloud_storage.Exists(
-        self.cloud_storage.PARTNER_BUCKET, 'preset_partner_file.wpr'))
-    self.assertFalse(self.cloud_storage.Exists(
-        self.cloud_storage.INTERNAL_BUCKET, 'preset_internal_file.wpr'))
-
-  def testExistsNonEmptyCloudStorage(self):
-    # Test non-empty remote files dictionary.
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.assertTrue(self.cloud_storage.Exists(
-        self.cloud_storage.PUBLIC_BUCKET, 'preset_public_file.wpr'))
-    self.assertTrue(self.cloud_storage.Exists(
-        self.cloud_storage.PARTNER_BUCKET, 'preset_partner_file.wpr'))
-    self.assertTrue(self.cloud_storage.Exists(
-        self.cloud_storage.INTERNAL_BUCKET, 'preset_internal_file.wpr'))
-    self.assertFalse(self.cloud_storage.Exists(
-        self.cloud_storage.PUBLIC_BUCKET, 'fake_file'))
-    self.assertFalse(self.cloud_storage.Exists(
-        self.cloud_storage.PARTNER_BUCKET, 'fake_file'))
-    self.assertFalse(self.cloud_storage.Exists(
-        self.cloud_storage.INTERNAL_BUCKET, 'fake_file'))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testNonEmptyInsertAndExistsPublic(self):
-    # Test non-empty remote files dictionary.
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.assertFalse(self.cloud_storage.Exists(self.cloud_storage.PUBLIC_BUCKET,
-                                               'success.wpr'))
-    self.cloud_storage.Insert(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    self.assertTrue(self.cloud_storage.Exists(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr'))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testEmptyInsertAndExistsPublic(self):
-    # Test empty remote files dictionary.
-    self.assertFalse(self.cloud_storage.Exists(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr'))
-    self.cloud_storage.Insert(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    self.assertTrue(self.cloud_storage.Exists(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr'))
-
-  def testEmptyInsertAndGet(self):
-    self.assertRaises(self.cloud_storage.NotFoundError, self.cloud_storage.Get,
-                      self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-                      os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    self.cloud_storage.Insert(self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-                              os.path.join(os.path.sep, 'path', 'to',
-                                           'success.wpr'))
-    self.assertTrue(self.cloud_storage.Exists(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr'))
-    self.assertEqual(CloudStorageTest.SUCCESS_FILE_HASH, self.cloud_storage.Get(
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr')))
-
-  def testNonEmptyInsertAndGet(self):
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.assertRaises(self.cloud_storage.NotFoundError, self.cloud_storage.Get,
-                      self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-                      os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    self.cloud_storage.Insert(self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-                              os.path.join(os.path.sep, 'path', 'to',
-                                           'success.wpr'))
-    self.assertTrue(self.cloud_storage.Exists(self.cloud_storage.PUBLIC_BUCKET,
-                                              'success.wpr'))
-    self.assertEqual(
-        CloudStorageTest.SUCCESS_FILE_HASH, self.cloud_storage.Get(
-            self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-            os.path.join(os.path.sep, 'path', 'to', 'success.wpr')))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testGetIfChanged(self):
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.assertRaises(
-        self.cloud_storage.NotFoundError, self.cloud_storage.Get,
-        self.cloud_storage.PUBLIC_BUCKET, 'success.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    self.assertFalse(self.cloud_storage.GetIfChanged(
-        os.path.join(os.path.sep, 'path', 'to', 'preset_public_file.wpr'),
-        self.cloud_storage.PUBLIC_BUCKET))
-    self.cloud_storage.ChangeRemoteHashForTesting(
-        self.cloud_storage.PUBLIC_BUCKET, 'preset_public_file.wpr',
-        CloudStorageTest.UPDATED_HASH)
-    self.assertTrue(self.cloud_storage.GetIfChanged(
-        os.path.join(os.path.sep, 'path', 'to', 'preset_public_file.wpr'),
-        self.cloud_storage.PUBLIC_BUCKET))
-    self.assertFalse(self.cloud_storage.GetIfChanged(
-        os.path.join(os.path.sep, 'path', 'to', 'preset_public_file.wpr'),
-        self.cloud_storage.PUBLIC_BUCKET))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testList(self):
-    self.assertEqual([],
-                     self.cloud_storage.List(self.cloud_storage.PUBLIC_BUCKET))
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.assertEqual(['preset_public_file.wpr'],
-                     self.cloud_storage.List(self.cloud_storage.PUBLIC_BUCKET))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testPermissionError(self):
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.cloud_storage.SetPermissionLevelForTesting(
-        self.cloud_storage.PUBLIC_PERMISSION)
-    self.assertRaises(
-        self.cloud_storage.PermissionError, self.cloud_storage.Get,
-        self.cloud_storage.INTERNAL_BUCKET, 'preset_internal_file.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'preset_internal_file.wpr'))
-    self.assertRaises(
-        self.cloud_storage.PermissionError, self.cloud_storage.GetIfChanged,
-        os.path.join(os.path.sep, 'path', 'to', 'preset_internal_file.wpr'),
-        self.cloud_storage.INTERNAL_BUCKET)
-    self.assertRaises(
-        self.cloud_storage.PermissionError, self.cloud_storage.List,
-        self.cloud_storage.INTERNAL_BUCKET)
-    self.assertRaises(
-        self.cloud_storage.PermissionError, self.cloud_storage.Exists,
-        self.cloud_storage.INTERNAL_BUCKET, 'preset_internal_file.wpr')
-    self.assertRaises(
-        self.cloud_storage.PermissionError, self.cloud_storage.Insert,
-        self.cloud_storage.INTERNAL_BUCKET, 'success.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testCredentialsError(self):
-    self.cloud_storage.SetRemotePathsForTesting(self.remote_paths)
-    self.cloud_storage.SetPermissionLevelForTesting(
-        self.cloud_storage.CREDENTIALS_ERROR_PERMISSION)
-    self.assertRaises(
-        self.cloud_storage.CredentialsError, self.cloud_storage.Get,
-        self.cloud_storage.INTERNAL_BUCKET, 'preset_internal_file.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'preset_internal_file.wpr'))
-    self.assertRaises(
-        self.cloud_storage.CredentialsError, self.cloud_storage.GetIfChanged,
-        self.cloud_storage.INTERNAL_BUCKET,
-        os.path.join(os.path.sep, 'path', 'to', 'preset_internal_file.wpr'))
-    self.assertRaises(
-        self.cloud_storage.CredentialsError, self.cloud_storage.List,
-        self.cloud_storage.INTERNAL_BUCKET)
-    self.assertRaises(
-        self.cloud_storage.CredentialsError, self.cloud_storage.Exists,
-        self.cloud_storage.INTERNAL_BUCKET, 'preset_internal_file.wpr')
-    self.assertRaises(
-        self.cloud_storage.CredentialsError, self.cloud_storage.Insert,
-        self.cloud_storage.INTERNAL_BUCKET, 'success.wpr',
-        os.path.join(os.path.sep, 'path', 'to', 'success.wpr'))
-    # Reset state.
-    self.cloud_storage.SetRemotePathsForTesting()
-
-  def testOpenRestoresCorrectly(self):
-    file_path = os.path.realpath(__file__)
-    stubs = system_stub.Override(system_stub_test_module, ['open'])
-    stubs.open.files = {file_path:'contents'}
-    f = system_stub_test_module.SystemStubTest.TestOpen(file_path)
-    self.assertEqual(type(f), system_stub.OpenFunctionStub.FileStub)
-    stubs.open.files = {}
-    stubs.Restore()
-    # This will throw an error if the open stub wasn't restored correctly.
-    f = system_stub_test_module.SystemStubTest.TestOpen(file_path)
-    self.assertEqual(type(f), file)
diff --git a/catapult/telemetry/telemetry/testing/tab_test_case.py b/catapult/telemetry/telemetry/testing/tab_test_case.py
deleted file mode 100644
index 2fff0ca..0000000
--- a/catapult/telemetry/telemetry/testing/tab_test_case.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import exceptions
-from telemetry.testing import browser_test_case
-
-
-class TabTestCase(browser_test_case.BrowserTestCase):
-  def __init__(self, *args):
-    super(TabTestCase, self).__init__(*args)
-    self._tab = None
-
-  def setUp(self):
-    super(TabTestCase, self).setUp()
-
-    if self._browser.supports_tab_control:
-      try:
-        while len(self._browser.tabs) < 1:
-          self._browser.tabs.New()
-        while len(self._browser.tabs) > 1:
-          self._browser.tabs[0].Close()
-        self._tab = self._browser.tabs[0]
-      except exceptions.TimeoutException:
-        self._RestartBrowser()
-    else:
-      self._RestartBrowser()
-    self._tab.Navigate('about:blank')
-    self._tab.WaitForDocumentReadyStateToBeInteractiveOrBetter()
-
-  def Navigate(self, filename, script_to_evaluate_on_commit=None):
-    """Navigates |tab| to |filename| in the unittest data directory.
-
-    Also sets up http server to point to the unittest data directory.
-    """
-    url = self.UrlOfUnittestFile(filename)
-    self._tab.Navigate(url, script_to_evaluate_on_commit)
-    self._tab.WaitForDocumentReadyStateToBeComplete()
-    self._tab.WaitForFrameToBeDisplayed()
-
-  def _RestartBrowser(self):
-    if not self._browser.tabs:
-      self.tearDownClass()
-      self.setUpClass()
-    self._tab = self._browser.tabs[0]
-
-  @property
-  def tabs(self):
-    return self._browser.tabs
diff --git a/catapult/telemetry/telemetry/testing/test_page_test_results.py b/catapult/telemetry/telemetry/testing/test_page_test_results.py
deleted file mode 100644
index 3770c72..0000000
--- a/catapult/telemetry/telemetry/testing/test_page_test_results.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.results import page_test_results
-from telemetry.page import page as page_module
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-
-
-class TestPageTestResults(
-    page_test_results.PageTestResults):
-  def __init__(self, test):
-    super(TestPageTestResults, self).__init__()
-    self.test = test
-    page = page_module.Page("http://www.google.com", {})
-    self.WillRunPage(page)
-
-  def GetPageSpecificValueNamed(self, name):
-    values = [value for value in self.all_page_specific_values
-         if value.name == name]
-    assert len(values) == 1, 'Could not find value named %s' % name
-    return values[0]
-
-  def AssertHasPageSpecificScalarValue(self, name, units, expected_value):
-    value = self.GetPageSpecificValueNamed(name)
-    self.test.assertEquals(units, value.units)
-    self.test.assertTrue(isinstance(value, scalar.ScalarValue))
-    self.test.assertEquals(expected_value, value.value)
-
-  def AssertHasPageSpecificListOfScalarValues(self, name, units,
-                                              expected_values):
-    value = self.GetPageSpecificValueNamed(name)
-    self.test.assertEquals(units, value.units)
-    self.test.assertTrue(
-        isinstance(value, list_of_scalar_values.ListOfScalarValues))
-    self.test.assertItemsEqual(expected_values, value.values)
-
-  def __str__(self):
-    return '\n'.join([repr(x) for x in self.all_page_specific_values])
diff --git a/catapult/telemetry/telemetry/testing/unittest_runner.py b/catapult/telemetry/telemetry/testing/unittest_runner.py
deleted file mode 100644
index 1a4c21b..0000000
--- a/catapult/telemetry/telemetry/testing/unittest_runner.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import subprocess
-import sys
-
-from telemetry.core import util
-
-
-def Run(project_config, no_browser=False,
-        disable_cloud_storage_io_during_test=False):
-  args = sys.argv[1:]
-  assert '--top-level-dir' not in args, (
-      'Top level directory for running tests should be specified through '
-      'the instance of telemetry.project_config.ProjectConfig.')
-  assert '--client-config' not in args, (
-      'Client config file to be used for telemetry should be specified through '
-      'the instance of telemetry.project_config.ProjectConfig.')
-  assert project_config.top_level_dir, 'Must specify top level dir for project'
-  args.extend(['--top-level-dir', project_config.top_level_dir])
-  for c in project_config.client_configs:
-    args.extend(['--client-config', c])
-  if no_browser and not '--no-browser' in args:
-    args.extend(['--no-browser'])
-
-  if project_config.default_chrome_root and not '--chrome-root' in args:
-    args.extend(['--chrome-root', project_config.default_chrome_root])
-
-  if disable_cloud_storage_io_during_test:
-    args.extend(['--disable-cloud-storage-io'])
-
-  env = os.environ.copy()
-  telemetry_dir = util.GetTelemetryDir()
-  if 'PYTHONPATH' in env:
-    env['PYTHONPATH'] = os.pathsep.join([env['PYTHONPATH'], telemetry_dir])
-  else:
-    env['PYTHONPATH'] = telemetry_dir
-
-  path_to_run_tests = os.path.join(os.path.abspath(os.path.dirname(__file__)),
-                                   'run_tests.py')
-  return subprocess.call([sys.executable, path_to_run_tests] + args, env=env)
diff --git a/catapult/telemetry/telemetry/timeline/__init__.py b/catapult/telemetry/telemetry/timeline/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/telemetry/timeline/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/telemetry/timeline/async_slice.py b/catapult/telemetry/telemetry/timeline/async_slice.py
deleted file mode 100644
index 2a5068f..0000000
--- a/catapult/telemetry/telemetry/timeline/async_slice.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import telemetry.timeline.event as event
-
-
-class AsyncSlice(event.TimelineEvent):
-  """An AsyncSlice represents an interval of time during which an
-  asynchronous operation is in progress. An AsyncSlice consumes no CPU time
-  itself and so is only associated with Threads at its start and end point.
-  """
-  def __init__(self, category, name, timestamp, args=None,
-               duration=0, start_thread=None, end_thread=None,
-               thread_start=None, thread_duration=None):
-    super(AsyncSlice, self).__init__(
-        category, name, timestamp, duration, thread_start, thread_duration,
-        args)
-    self.parent_slice = None
-    self.start_thread = start_thread
-    self.end_thread = end_thread
-    self.sub_slices = []
-    self.id = None
-
-  def AddSubSlice(self, sub_slice):
-    assert sub_slice.parent_slice == self
-    self.sub_slices.append(sub_slice)
-
-  def IterEventsInThisContainerRecrusively(self):
-    for sub_slice in self.sub_slices:
-      yield sub_slice
diff --git a/catapult/telemetry/telemetry/timeline/atrace_config.py b/catapult/telemetry/telemetry/timeline/atrace_config.py
deleted file mode 100644
index 4956009..0000000
--- a/catapult/telemetry/telemetry/timeline/atrace_config.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from systrace.tracing_agents import atrace_agent
-
-class AtraceConfig(object):
-  """Stores configuration options specific to Atrace.
-
-    categories: List that specifies the Atrace categories to trace.
-        Example: ['sched', 'webview']
-    app_name: String or list that specifies the application name (or names)
-        on which to run application level tracing.
-        Example: 'org.chromium.webview_shell'
-  """
-  def __init__(self):
-    self.categories = atrace_agent.DEFAULT_CATEGORIES
-    self.app_name = None
diff --git a/catapult/telemetry/telemetry/timeline/bounds.py b/catapult/telemetry/telemetry/timeline/bounds.py
deleted file mode 100644
index dd7a4ef..0000000
--- a/catapult/telemetry/telemetry/timeline/bounds.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class Bounds(object):
-  """Represents a min-max bounds."""
-  def __init__(self):
-    self.is_empty_ = True
-    self.min_ = None
-    self.max_ = None
-
-  @staticmethod
-  def CreateFromEvent(event):
-    bounds = Bounds()
-    bounds.AddEvent(event)
-    return bounds
-
-  def __repr__(self):
-    if self.is_empty_:
-      return "Bounds()"
-    else:
-      return "Bounds(min=%s,max=%s)" % (self.min_, self.max_)
-
-  @property
-  def is_empty(self):
-    return self.is_empty_
-
-  @property
-  def min(self):
-    if self.is_empty_:
-      return None
-    return self.min_
-
-  @property
-  def max(self):
-    if self.is_empty_:
-      return None
-    return self.max_
-
-  @property
-  def bounds(self):
-    if self.is_empty_:
-      return None
-    return self.max_ - self.min_
-
-  @property
-  def center(self):
-    return (self.min_ + self.max_) * 0.5
-
-  def Contains(self, other):
-    if self.is_empty or other.is_empty:
-      return False
-    return self.min <= other.min and self.max >= other.max
-
-  def ContainsInterval(self, start, end):
-    return self.min <= start and self.max >= end
-
-  def Intersects(self, other):
-    if self.is_empty or other.is_empty:
-      return False
-    return not (other.max < self.min or other.min > self.max)
-
-  def Reset(self):
-    self.is_empty_ = True
-    self.min_ = None
-    self.max_ = None
-
-  def AddBounds(self, bounds):
-    if bounds.is_empty:
-      return
-    self.AddValue(bounds.min_)
-    self.AddValue(bounds.max_)
-
-  def AddValue(self, value):
-    if self.is_empty_:
-      self.max_ = value
-      self.min_ = value
-      self.is_empty_ = False
-      return
-
-    self.max_ = max(self.max_, value)
-    self.min_ = min(self.min_, value)
-
-  def AddEvent(self, event):
-    self.AddValue(event.start)
-    self.AddValue(event.start + event.duration)
-
-  @staticmethod
-  def CompareByMinTimes(a, b):
-    if not a.is_empty and not b.is_empty:
-      return a.min_ - b.min_
-
-    if a.is_empty and not b.is_empty:
-      return -1
-
-    if not a.is_empty and b.is_empty:
-      return 1
-
-    return 0
-
-  @staticmethod
-  def GetOverlapBetweenBounds(first_bounds, second_bounds):
-    """Compute the overlap duration between first_bounds and second_bounds."""
-    return Bounds.GetOverlap(first_bounds.min_, first_bounds.max_,
-                             second_bounds.min_, second_bounds.max_)
-
-  @staticmethod
-  def GetOverlap(first_bounds_min, first_bounds_max,
-                 second_bounds_min, second_bounds_max):
-    assert first_bounds_min <= first_bounds_max
-    assert second_bounds_min <= second_bounds_max
-    overlapped_range_start = max(first_bounds_min, second_bounds_min)
-    overlapped_range_end = min(first_bounds_max, second_bounds_max)
-    return max(overlapped_range_end - overlapped_range_start, 0)
diff --git a/catapult/telemetry/telemetry/timeline/bounds_unittest.py b/catapult/telemetry/telemetry/timeline/bounds_unittest.py
deleted file mode 100644
index 0b06124..0000000
--- a/catapult/telemetry/telemetry/timeline/bounds_unittest.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.timeline import bounds
-
-
-class BoundsTests(unittest.TestCase):
-
-  def testGetOverlap(self):
-    # Non overlap cases.
-    self.assertEquals(0, bounds.Bounds.GetOverlap(10, 20, 30, 40))
-    self.assertEquals(0, bounds.Bounds.GetOverlap(30, 40, 10, 20))
-    # Overlap cases.
-    self.assertEquals(10, bounds.Bounds.GetOverlap(10, 30, 20, 40))
-    self.assertEquals(10, bounds.Bounds.GetOverlap(20, 40, 10, 30))
-    # Inclusive cases.
-    self.assertEquals(10, bounds.Bounds.GetOverlap(10, 40, 20, 30))
-    self.assertEquals(10, bounds.Bounds.GetOverlap(20, 30, 10, 40))
diff --git a/catapult/telemetry/telemetry/timeline/chrome_trace_category_filter.py b/catapult/telemetry/telemetry/timeline/chrome_trace_category_filter.py
deleted file mode 100644
index 203c5e9..0000000
--- a/catapult/telemetry/telemetry/timeline/chrome_trace_category_filter.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-
-def CreateLowOverheadFilter():
-  """Returns a filter with the least overhead possible.
-
-  This contains no sub-traces of thread tasks, so it's only useful for
-  capturing the cpu-time spent on threads (as well as needed benchmark
-  traces).
-
-  FIXME: Remove webkit.console when blink.console lands in chromium and
-  the ref builds are updated. crbug.com/386847
-  """
-  categories = [
-    "toplevel",
-    "benchmark",
-    "webkit.console",
-    "blink.console",
-    "trace_event_overhead"
-  ]
-  return ChromeTraceCategoryFilter(filter_string=','.join(categories))
-
-
-def CreateDefaultOverheadFilter():
-  """Returns a filter with the best-effort amount of overhead.
-
-  This matches Chrome tracing's default category filter setting, i.e., enable
-  all categories except the disabled-by-default-* ones.
-
-  We should use '*' instead of '' (empty string) here. On the Chrome side, both
-  '*' and '' mean default category filter setting. However, if someone adds
-  additional category filters, the behavior becomes different.
-
-  For example:
-  '*': enable all categories except the disabled-by-default-* ones.
-  '':  enable all categories except the disabled-by-default-* ones.
-
-  Now add an additional category filter 'abc' to '*' and '':
-  '*,abc': enable all categories (including 'abc') except the
-           disabled-by-default-* ones.
-  'abc':   enable only 'abc', and disable all other ones.
-  """
-  return ChromeTraceCategoryFilter(filter_string='*')
-
-
-def CreateDebugOverheadFilter():
-  """Returns a filter with as many traces enabled as is useful."""
-  return ChromeTraceCategoryFilter(
-      filter_string='*,disabled-by-default-cc.debug')
-
-
-_delay_re = re.compile(r'DELAY[(][A-Za-z0-9._;]+[)]')
-
-
-class ChromeTraceCategoryFilter(object):
-  """A set of included and excluded categories that should be traced.
-
-  The ChromeTraceCategoryFilter allows fine tuning of what data is traced for
-  Chrome. Basic choice of which tracers to use is done by TracingConfig.
-
-  Providing filter_string=None gives the default category filter, which leaves
-  what to trace up to the individual trace systems.
-  """
-  def __init__(self, filter_string=None):
-    self._included_categories = set()
-    self._excluded_categories = set()
-    self._disabled_by_default_categories = set()
-    self._synthetic_delays = set()
-    self.contains_wildcards = False
-    self.AddFilterString(filter_string)
-
-  def AddFilterString(self, filter_string):
-    if filter_string == None:
-      return
-
-    if '*' in filter_string or '?' in filter_string:
-      self.contains_wildcards = True
-
-    filter_set = set([cf.strip() for cf in filter_string.split(',')])
-    for category in filter_set:
-      if category == '':
-        continue
-
-      if _delay_re.match(category):
-        self._synthetic_delays.add(category)
-        continue
-
-      if category[0] == '-':
-        assert not category[1:] in self._included_categories
-        self._excluded_categories.add(category[1:])
-        continue
-
-      if category.startswith('disabled-by-default-'):
-        self._disabled_by_default_categories.add(category)
-        continue
-
-      assert not category in self._excluded_categories
-      self._included_categories.add(category)
-
-  @property
-  def included_categories(self):
-    return self._included_categories
-
-  @property
-  def excluded_categories(self):
-    return self._excluded_categories
-
-  @property
-  def disabled_by_default_categories(self):
-    return self._disabled_by_default_categories
-
-  @property
-  def synthetic_delays(self):
-    return self._synthetic_delays
-
-  @property
-  def filter_string(self):
-    return self._GetFilterString(stable_output=False)
-
-  @property
-  def stable_filter_string(self):
-    return self._GetFilterString(stable_output=True)
-
-  def _GetFilterString(self, stable_output):
-    # Note: This outputs fields in an order that intentionally matches
-    # trace_event_impl's CategoryFilter string order.
-    lists = []
-    lists.append(self._included_categories)
-    lists.append(self._disabled_by_default_categories)
-    lists.append(['-%s' % x for x in self._excluded_categories])
-    lists.append(self._synthetic_delays)
-    categories = []
-    for l in lists:
-      if stable_output:
-        l = list(l)
-        l.sort()
-      categories.extend(l)
-    return ','.join(categories)
-
-  def GetDictForChromeTracing(self):
-    INCLUDED_CATEGORIES_PARAM = 'included_categories'
-    EXCLUDED_CATEGORIES_PARAM = 'excluded_categories'
-    SYNTHETIC_DELAYS_PARAM = 'synthetic_delays'
-
-    result = {}
-    if self._included_categories or self._disabled_by_default_categories:
-      result[INCLUDED_CATEGORIES_PARAM] = list(
-        self._included_categories | self._disabled_by_default_categories)
-    if self._excluded_categories:
-      result[EXCLUDED_CATEGORIES_PARAM] = list(self._excluded_categories)
-    if self._synthetic_delays:
-      result[SYNTHETIC_DELAYS_PARAM] = list(self._synthetic_delays)
-    return result
-
-  def AddDisabledByDefault(self, category):
-    assert category.startswith('disabled-by-default-')
-    self._disabled_by_default_categories.add(category)
-
-  def AddIncludedCategory(self, category_glob):
-    """Explicitly enables anything matching category_glob."""
-    assert not category_glob.startswith('disabled-by-default-')
-    assert not category_glob in self._excluded_categories
-    self._included_categories.add(category_glob)
-
-  def AddExcludedCategory(self, category_glob):
-    """Explicitly disables anything matching category_glob."""
-    assert not category_glob.startswith('disabled-by-default-')
-    assert not category_glob in self._included_categories
-    self._excluded_categories.add(category_glob)
-
-  def AddSyntheticDelay(self, delay):
-    assert _delay_re.match(delay)
-    self._synthetic_delays.add(delay)
-
-  def IsSubset(self, other):
-    """ Determine if filter A (self) is a subset of filter B (other).
-        Returns True if A is a subset of B, False if A is not a subset of B,
-        and None if we can't tell for sure.
-    """
-    # We don't handle filters with wildcards in this test.
-    if self.contains_wildcards or other.contains_wildcards:
-      return None
-
-    # Disabled categories get into a trace if and only if they are contained in
-    # the 'disabled' set. Return False if A's disabled set is not a subset of
-    # B's disabled set.
-    if not self.disabled_by_default_categories <= \
-       other.disabled_by_default_categories:
-      return False
-
-    # If A defines more or different synthetic delays than B, then A is not a
-    # subset.
-    if not self.synthetic_delays <= other.synthetic_delays:
-      return False
-
-    if self.included_categories and other.included_categories:
-      # A and B have explicit include lists. If A includes something that B
-      # doesn't, return False.
-      if not self.included_categories <= other.included_categories:
-        return False
-    elif self.included_categories:
-      # Only A has an explicit include list. If A includes something that B
-      # excludes, return False.
-      if self.included_categories.intersection(other.excluded_categories):
-        return False
-    elif other.included_categories:
-      # Only B has an explicit include list. We don't know which categories are
-      # contained in the default list, so return None.
-      return None
-    else:
-      # None of the filter have explicit include list. If B excludes categories
-      # that A doesn't exclude, return False.
-      if not other.excluded_categories <= self.excluded_categories:
-        return False
-
-    return True
diff --git a/catapult/telemetry/telemetry/timeline/chrome_trace_category_filter_unittest.py b/catapult/telemetry/telemetry/timeline/chrome_trace_category_filter_unittest.py
deleted file mode 100644
index 9bcb377..0000000
--- a/catapult/telemetry/telemetry/timeline/chrome_trace_category_filter_unittest.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import chrome_trace_category_filter
-
-
-class ChromeTraceCategoryFilterTest(unittest.TestCase):
-  def CheckBasicCategoryFilters(self, cf):
-    self.assertEquals(set(['x']), set(cf.included_categories))
-    self.assertEquals(set(['y']), set(cf.excluded_categories))
-    self.assertEquals(set(['disabled-by-default-z']),
-        set(cf.disabled_by_default_categories))
-    self.assertEquals(set(['DELAY(7;foo)']), set(cf.synthetic_delays))
-
-    self.assertTrue('x' in cf.filter_string)
-    self.assertEquals(
-        'x,disabled-by-default-z,-y,DELAY(7;foo)',
-        cf.stable_filter_string)
-
-  def testBasic(self):
-    cf = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        'x,-y,disabled-by-default-z,DELAY(7;foo)')
-    self.CheckBasicCategoryFilters(cf)
-
-  def testBasicWithSpace(self):
-    cf = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        ' x ,\n-y\t,disabled-by-default-z ,DELAY(7;foo)')
-    self.CheckBasicCategoryFilters(cf)
-
-  def testNoneAndEmptyCategory(self):
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    self.assertEquals(a.stable_filter_string, '')
-    self.assertEquals(a.filter_string, '')
-    self.assertEquals(str(a.GetDictForChromeTracing()), '{}')
-
-    # Initializing chrome trace category filter with empty string is the same
-    # as initialization with None.
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(filter_string='')
-    self.assertEquals(b.stable_filter_string, '')
-    self.assertEquals(b.filter_string, '')
-    self.assertEquals(str(b.GetDictForChromeTracing()), '{}')
-
-  def testAddIncludedCategory(self):
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a.AddIncludedCategory('foo')
-    a.AddIncludedCategory('bar')
-    a.AddIncludedCategory('foo')
-    self.assertEquals(a.stable_filter_string, 'bar,foo')
-
-  def testAddExcludedCategory(self):
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a.AddExcludedCategory('foo')
-    a.AddExcludedCategory('bar')
-    a.AddExcludedCategory('foo')
-    self.assertEquals(a.stable_filter_string, '-bar,-foo')
-
-  def testIncludeAndExcludeCategoryRaisesAssertion(self):
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a.AddIncludedCategory('foo')
-    self.assertRaises(AssertionError, a.AddExcludedCategory, 'foo')
-
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a.AddExcludedCategory('foo')
-    self.assertRaises(AssertionError, a.AddIncludedCategory, 'foo')
-
-    self.assertRaises(AssertionError,
-                      chrome_trace_category_filter.ChromeTraceCategoryFilter,
-                      'foo,-foo')
-
-    self.assertRaises(AssertionError,
-                      chrome_trace_category_filter.ChromeTraceCategoryFilter,
-                      '-foo,foo')
-
-
-  def testIsSubset(self):
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("test1,test2")
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("-test1,-test2")
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter("test1,test2")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    self.assertEquals(a.IsSubset(b), None)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("test*")
-    self.assertEquals(a.IsSubset(b), None)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter("test?")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    self.assertEquals(a.IsSubset(b), None)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter("test1")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("test1,test2")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter("-test1")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("test1")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter("test1,test2")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("test2,test1")
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter("-test1,-test2")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter("-test2")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "disabled-by-default-test1")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "disabled-by-default-test1,disabled-by-default-test2")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "disabled-by-default-test1")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "disabled-by-default-test2")
-    self.assertEquals(a.IsSubset(b), False)
-
-  def testIsSubsetWithSyntheticDelays(self):
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016)")
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter()
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016)")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.032)")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016;static)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016;oneshot)")
-    self.assertEquals(a.IsSubset(b), False)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016),DELAY(bar;0.1)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(bar;0.1),DELAY(foo;0.016)")
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016),DELAY(bar;0.1)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(bar;0.1)")
-    self.assertEquals(a.IsSubset(b), True)
-
-    b = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.016),DELAY(bar;0.1)")
-    a = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        "DELAY(foo;0.032),DELAY(bar;0.1)")
-    self.assertEquals(a.IsSubset(b), False)
diff --git a/catapult/telemetry/telemetry/timeline/chrome_trace_config.py b/catapult/telemetry/telemetry/timeline/chrome_trace_config.py
deleted file mode 100644
index 850b84e..0000000
--- a/catapult/telemetry/telemetry/timeline/chrome_trace_config.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-from telemetry.timeline import chrome_trace_category_filter
-
-
-RECORD_MODE_PARAM = 'record_mode'
-
-ECHO_TO_CONSOLE = 'trace-to-console'
-RECORD_AS_MUCH_AS_POSSIBLE = 'record-as-much-as-possible'
-RECORD_CONTINUOUSLY = 'record-continuously'
-RECORD_UNTIL_FULL = 'record-until-full'
-
-# Map telemetry's tracing record_mode to the DevTools API string.
-# (The keys happen to be the same as the values.)
-RECORD_MODE_MAP = {
-  RECORD_UNTIL_FULL: 'record-until-full',
-  RECORD_CONTINUOUSLY: 'record-continuously',
-  RECORD_AS_MUCH_AS_POSSIBLE: 'record-as-much-as-possible',
-  ECHO_TO_CONSOLE: 'trace-to-console'
-}
-
-
-def ConvertStringToCamelCase(string):
-  """Convert an underscore/hyphen-case string to its camel-case counterpart.
-
-  This function is the inverse of Chromium's ConvertFromCamelCase function
-  in src/content/browser/devtools/protocol/tracing_handler.cc.
-  """
-  parts = re.split(r'[-_]', string)
-  return parts[0] + ''.join([p.title() for p in parts[1:]])
-
-
-def ConvertDictKeysToCamelCaseRecursively(data):
-  """Recursively convert dictionary keys from underscore/hyphen- to camel-case.
-
-  This function is the inverse of Chromium's ConvertDictKeyStyle function
-  in src/content/browser/devtools/protocol/tracing_handler.cc.
-  """
-  if isinstance(data, dict):
-    return {ConvertStringToCamelCase(k):
-            ConvertDictKeysToCamelCaseRecursively(v)
-            for k, v in data.iteritems()}
-  elif isinstance(data, list):
-    return map(ConvertDictKeysToCamelCaseRecursively, data)
-  else:
-    return data
-
-
-class ChromeTraceConfig(object):
-  """Stores configuration options specific to the Chrome tracing agent.
-
-    This produces the trace config JSON string for tracing in Chrome.
-
-    record_mode: can be any mode in RECORD_MODE_MAP. This corresponds to
-        record modes in chrome.
-    category_filter: Object that specifies which tracing categories to trace.
-    memory_dump_config: Stores the triggers for memory dumps.
-  """
-
-  def __init__(self):
-    self._record_mode = RECORD_AS_MUCH_AS_POSSIBLE
-    self._category_filter = (
-        chrome_trace_category_filter.ChromeTraceCategoryFilter())
-    self._memory_dump_config = None
-
-  def SetLowOverheadFilter(self):
-    self._category_filter = (
-        chrome_trace_category_filter.CreateLowOverheadFilter())
-
-  def SetDefaultOverheadFilter(self):
-    self._category_filter = (
-        chrome_trace_category_filter.CreateDefaultOverheadFilter())
-
-  def SetDebugOverheadFilter(self):
-    self._category_filter = (
-        chrome_trace_category_filter.CreateDebugOverheadFilter())
-
-  @property
-  def category_filter(self):
-    return self._category_filter
-
-  def SetCategoryFilter(self, cf):
-    if isinstance(cf, chrome_trace_category_filter.ChromeTraceCategoryFilter):
-      self._category_filter = cf
-    else:
-      raise TypeError(
-          'Must pass SetCategoryFilter a ChromeTraceCategoryFilter instance')
-
-  def SetMemoryDumpConfig(self, dump_config):
-    if isinstance(dump_config, MemoryDumpConfig):
-      self._memory_dump_config = dump_config
-    else:
-      raise TypeError(
-          'Must pass SetMemoryDumpConfig a MemoryDumpConfig instance')
-
-  @property
-  def record_mode(self):
-    return self._record_mode
-
-  @record_mode.setter
-  def record_mode(self, value):
-    assert value in RECORD_MODE_MAP
-    self._record_mode = value
-
-  def GetChromeTraceConfigForStartupTracing(self):
-    """Map the config to a JSON string for startup tracing.
-
-    All keys in the returned dictionary use underscore-case (e.g.
-    'record_mode'). In addition, the 'record_mode' value uses hyphen-case
-    (e.g. 'record-until-full').
-    """
-    result = {
-        RECORD_MODE_PARAM: RECORD_MODE_MAP[self._record_mode]
-    }
-    result.update(self._category_filter.GetDictForChromeTracing())
-    if self._memory_dump_config:
-      result.update(self._memory_dump_config.GetDictForChromeTracing())
-    return result
-
-  @property
-  def requires_modern_devtools_tracing_start_api(self):
-    """Returns True iff the config CANNOT be passed via the legacy DevTools API.
-
-    Legacy DevTools Tracing.start API:
-      Available since:    the introduction of the Tracing.start request.
-      Parameters:         categories (string), options (string),
-                          bufferUsageReportingInterval (number),
-                          transferMode (enum).
-      TraceConfig method: GetChromeTraceCategoriesAndOptionsStringsForDevTools()
-
-    Modern DevTools Tracing.start API:
-      Available since:    Chrome 51.0.2683.0.
-      Parameters:         traceConfig (dict),
-                          bufferUsageReportingInterval (number),
-                          transferMode (enum).
-      TraceConfig method: GetChromeTraceConfigDictForDevTools()
-    """
-    # Memory dump config cannot be passed via the 'options' string (legacy API)
-    # in the DevTools Tracing.start request.
-    return bool(self._memory_dump_config)
-
-  def GetChromeTraceConfigForDevTools(self):
-    """Map the config to a DevTools API config dictionary.
-
-    All keys in the returned dictionary use camel-case (e.g. 'recordMode').
-    In addition, the 'recordMode' value also uses camel-case (e.g.
-    'recordUntilFull'). This is to invert the camel-case ->
-    underscore/hyphen-delimited mapping performed in Chromium devtools.
-    """
-    result = self.GetChromeTraceConfigForStartupTracing()
-    if result[RECORD_MODE_PARAM]:
-      result[RECORD_MODE_PARAM] = ConvertStringToCamelCase(
-          result[RECORD_MODE_PARAM])
-    return ConvertDictKeysToCamelCaseRecursively(result)
-
-  def GetChromeTraceCategoriesAndOptionsForDevTools(self):
-    """Map the categories and options to their DevTools API counterparts."""
-    assert not self.requires_modern_devtools_tracing_start_api
-    options_parts = [RECORD_MODE_MAP[self._record_mode]]
-    return (self._category_filter.stable_filter_string,
-            ','.join(options_parts))
-
-
-class MemoryDumpConfig(object):
-  """Stores the triggers for memory dumps in ChromeTraceConfig."""
-  def __init__(self):
-    self._triggers = []
-
-  def AddTrigger(self, mode, periodic_interval_ms):
-    """Adds a new trigger to config.
-
-    Args:
-      periodic_interval_ms: Dump time period in milliseconds.
-      level_of_detail: Memory dump level of detail string.
-          Valid arguments are "background", "light" and "detailed".
-    """
-    assert mode in ['background', 'light', 'detailed']
-    assert periodic_interval_ms > 0
-    self._triggers.append({'mode': mode,
-                           'periodic_interval_ms': periodic_interval_ms})
-
-  def GetDictForChromeTracing(self):
-    """Returns the dump config as dictionary for chrome tracing."""
-    # An empty trigger list would mean no periodic memory dumps.
-    return {'memory_dump_config': {'triggers': self._triggers}}
diff --git a/catapult/telemetry/telemetry/timeline/chrome_trace_config_unittest.py b/catapult/telemetry/telemetry/timeline/chrome_trace_config_unittest.py
deleted file mode 100644
index e65e354..0000000
--- a/catapult/telemetry/telemetry/timeline/chrome_trace_config_unittest.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import chrome_trace_category_filter
-from telemetry.timeline import chrome_trace_config
-
-
-class ChromeTraceConfigTests(unittest.TestCase):
-  def testDefault(self):
-    config = chrome_trace_config.ChromeTraceConfig()
-
-    # Trace config for startup tracing.
-    self.assertEquals({
-        'record_mode': 'record-as-much-as-possible'
-    }, config.GetChromeTraceConfigForStartupTracing())
-
-    # Trace config for DevTools (modern API).
-    self.assertEquals({
-        'recordMode': 'recordAsMuchAsPossible'
-    }, config.GetChromeTraceConfigForDevTools())
-
-    # Trace categories and options for DevTools (legacy API).
-    self.assertFalse(config.requires_modern_devtools_tracing_start_api)
-    self.assertEquals(
-        ('', 'record-as-much-as-possible'),
-        config.GetChromeTraceCategoriesAndOptionsForDevTools())
-
-  def testBasic(self):
-    category_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        'x,-y,disabled-by-default-z,DELAY(7;foo)')
-    config = chrome_trace_config.ChromeTraceConfig()
-    config.SetCategoryFilter(category_filter)
-    config.record_mode = chrome_trace_config.RECORD_UNTIL_FULL
-
-    # Trace config for startup tracing.
-    self.assertEquals({
-        'excluded_categories': ['y'],
-        'included_categories': ['x', 'disabled-by-default-z'],
-        'record_mode': 'record-until-full',
-        'synthetic_delays': ['DELAY(7;foo)']
-    }, config.GetChromeTraceConfigForStartupTracing())
-
-    # Trace config for DevTools (modern API).
-    self.assertEquals({
-        'excludedCategories': ['y'],
-        'includedCategories': ['x', 'disabled-by-default-z'],
-        'recordMode': 'recordUntilFull',
-        'syntheticDelays': ['DELAY(7;foo)']
-    }, config.GetChromeTraceConfigForDevTools())
-
-    # Trace categories and options for DevTools (legacy API).
-    self.assertFalse(config.requires_modern_devtools_tracing_start_api)
-    self.assertEquals(
-        ('x,disabled-by-default-z,-y,DELAY(7;foo)',
-         'record-until-full'),
-        config.GetChromeTraceCategoriesAndOptionsForDevTools())
-
-  def testMemoryDumpConfigFormat(self):
-    config = chrome_trace_config.ChromeTraceConfig()
-    config.record_mode = chrome_trace_config.ECHO_TO_CONSOLE
-    dump_config = chrome_trace_config.MemoryDumpConfig()
-    config.SetMemoryDumpConfig(dump_config)
-
-    # Trace config for startup tracing.
-    self.assertEquals({
-        'memory_dump_config': {'triggers': []},
-        'record_mode': 'trace-to-console'
-    }, config.GetChromeTraceConfigForStartupTracing())
-
-    # Trace config for DevTools (modern API).
-    self.assertEquals({
-        'memoryDumpConfig': {'triggers': []},
-        'recordMode': 'traceToConsole'
-    }, config.GetChromeTraceConfigForDevTools())
-
-    # Trace categories and options for DevTools (legacy API).
-    self.assertTrue(config.requires_modern_devtools_tracing_start_api)
-    with self.assertRaises(AssertionError):
-      config.GetChromeTraceCategoriesAndOptionsForDevTools()
-
-    dump_config.AddTrigger('light', 250)
-    dump_config.AddTrigger('detailed', 2000)
-
-    # Trace config for startup tracing.
-    self.assertEquals({
-        'memory_dump_config': {
-            'triggers': [
-                {'mode': 'light', 'periodic_interval_ms': 250},
-                {'mode': 'detailed', 'periodic_interval_ms': 2000}
-            ]
-        },
-        'record_mode': 'trace-to-console'
-    }, config.GetChromeTraceConfigForStartupTracing())
-
-    # Trace config for DevTools (modern API).
-    self.assertEquals({
-        'memoryDumpConfig': {
-            'triggers': [
-                {'mode': 'light', 'periodicIntervalMs': 250},
-                {'mode': 'detailed', 'periodicIntervalMs': 2000}
-            ]
-        },
-        'recordMode': 'traceToConsole'
-    }, config.GetChromeTraceConfigForDevTools())
-
-    # Trace categories and options for DevTools (legacy API).
-    self.assertTrue(config.requires_modern_devtools_tracing_start_api)
-    with self.assertRaises(AssertionError):
-      config.GetChromeTraceCategoriesAndOptionsForDevTools()
diff --git a/catapult/telemetry/telemetry/timeline/counter.py b/catapult/telemetry/telemetry/timeline/counter.py
deleted file mode 100644
index 63aacc6..0000000
--- a/catapult/telemetry/telemetry/timeline/counter.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import telemetry.timeline.event_container as event_container
-
-
-# Doesn't inherit from TimelineEvent because its only a temporary wrapper of a
-# counter sample into an event. During stable operation, the samples are stored
-# a dense array of values rather than in the long-form done by an Event.
-class CounterSample(object):
-  def __init__(self, counter, sample_index):
-    self._counter = counter
-    self._sample_index = sample_index
-
-  @property
-  def category(self):
-    return self._counter.category
-
-  @property
-  def name(self):
-    return self._counter.full_name
-
-  @property
-  def value(self):
-    return self._counter.samples[self._sample_index]
-
-  @property
-  def start(self):
-    return self._counter.timestamps[self._sample_index]
-
-  @start.setter
-  def start(self, start):
-    self._counter.timestamps[self._sample_index] = start
-
-  @property
-  def duration(self):
-    return 0
-
-  @property
-  def end(self):
-    return self.start
-
-  @property
-  def thread_start(self):
-    return None
-
-  @property
-  def thread_duration(self):
-    return None
-
-  @property
-  def thread_end(self):
-    return None
-
-
-class Counter(event_container.TimelineEventContainer):
-  """ Stores all the samples for a given counter.
-  """
-  def __init__(self, parent, category, name):
-    super(Counter, self).__init__(name, parent)
-    self.category = category
-    self.full_name = category + '.' + name
-    self.samples = []
-    self.timestamps = []
-    self.series_names = []
-    self.totals = []
-    self.max_total = 0
-
-  def IterChildContainers(self):
-    return
-    yield # pylint: disable=unreachable
-
-  def IterEventsInThisContainer(self, event_type_predicate, event_predicate):
-    if not event_type_predicate(CounterSample) or not self.timestamps:
-      return
-
-    # Pass event_predicate a reused CounterSample instance to avoid
-    # creating a ton of garbage for rejected samples.
-    test_sample = CounterSample(self, 0)
-    for i in xrange(len(self.timestamps)):
-      test_sample._sample_index = i  # pylint: disable=protected-access
-      if event_predicate(test_sample):
-        yield CounterSample(self, i)
-
-  @property
-  def num_series(self):
-    return len(self.series_names)
-
-  @property
-  def num_samples(self):
-    return len(self.timestamps)
-
-  def FinalizeImport(self):
-    if self.num_series * self.num_samples != len(self.samples):
-      raise ValueError(
-          'Length of samples must be a multiple of length of timestamps.')
-
-    self.totals = []
-    self.max_total = 0
-    if not len(self.samples):
-      return
-
-    max_total = None
-    for i in xrange(self.num_samples):
-      total = 0
-      for j in xrange(self.num_series):
-        total += self.samples[i * self.num_series + j]
-        self.totals.append(total)
-      if max_total is None or total > max_total:
-        max_total = total
-    self.max_total = max_total
diff --git a/catapult/telemetry/telemetry/timeline/counter_unittest.py b/catapult/telemetry/telemetry/timeline/counter_unittest.py
deleted file mode 100644
index a97d4ac..0000000
--- a/catapult/telemetry/telemetry/timeline/counter_unittest.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import types
-import unittest
-
-from telemetry.timeline import counter as counter_module
-
-
-class FakeProcess(object):
-  pass
-
-
-class CounterIterEventsInThisContainerTest(unittest.TestCase):
-
-  def setUp(self):
-    parent = FakeProcess()
-    self.counter = counter_module.Counter(parent, 'cat', 'name')
-
-  def assertIsEmptyIterator(self, itr):
-    self.assertIsInstance(itr, types.GeneratorType)
-    self.assertRaises(StopIteration, itr.next)
-
-  def testEmptyTimestamps(self):
-    self.assertIsEmptyIterator(self.counter.IterEventsInThisContainer(
-        event_type_predicate=lambda x: True,
-        event_predicate=lambda x: True))
-
-  def testEventTypeMismatch(self):
-    self.counter.timestamps = [111, 222]
-    self.assertIsEmptyIterator(self.counter.IterEventsInThisContainer(
-        event_type_predicate=lambda x: False,
-        event_predicate=lambda x: True))
-
-  def testNoEventMatch(self):
-    self.counter.timestamps = [111, 222]
-    self.assertIsEmptyIterator(self.counter.IterEventsInThisContainer(
-        event_type_predicate=lambda x: True,
-        event_predicate=lambda x: False))
-
-  def testAllMatch(self):
-    self.counter.timestamps = [111, 222]
-    self.counter.samples = [100, 200]
-    events = self.counter.IterEventsInThisContainer(
-        event_type_predicate=lambda x: True,
-        event_predicate=lambda x: True)
-    self.assertIsInstance(events, types.GeneratorType)
-    eventlist = list(events)
-    self.assertEqual([111, 222], [s.start for s in eventlist])
-    self.assertEqual(['cat.name', 'cat.name'], [s.name for s in eventlist])
-    self.assertEqual([100, 200], [s.value for s in eventlist])
-
-  def testPartialMatch(self):
-    self.counter.timestamps = [111, 222]
-    self.counter.samples = [100, 200]
-    events = self.counter.IterEventsInThisContainer(
-        event_type_predicate=lambda x: True,
-        event_predicate=lambda x: x.start > 200)
-    self.assertIsInstance(events, types.GeneratorType)
-    eventlist = list(events)
-    self.assertEqual([222], [s.start for s in eventlist])
-    self.assertEqual(['cat.name'], [s.name for s in eventlist])
-    self.assertEqual([200], [s.value for s in eventlist])
diff --git a/catapult/telemetry/telemetry/timeline/event.py b/catapult/telemetry/telemetry/timeline/event.py
deleted file mode 100644
index 996cba9..0000000
--- a/catapult/telemetry/telemetry/timeline/event.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class TimelineEvent(object):
-  """Represents a timeline event.
-
-  thread_start, thread_duration and thread_end are the start time, duration
-  and end time of this event as measured by the thread-specific CPU clock
-  (ticking when the thread is actually scheduled). Thread time is optional
-  on trace events and the corresponding attributes in TimelineEvent will be
-  set to None (not 0) if not present. Users of this class need to properly
-  handle this case.
-  """
-  def __init__(self, category, name, start, duration, thread_start=None,
-               thread_duration=None, args=None):
-    self.category = category
-    self.name = name
-    self.start = start
-    self.duration = duration
-    self.thread_start = thread_start
-    self.thread_duration = thread_duration
-    self.args = args
-
-  @property
-  def end(self):
-    return self.start + self.duration
-
-  @property
-  def has_thread_timestamps(self):
-    return self.thread_start is not None and self.thread_duration is not None
-
-  @property
-  def thread_end(self):
-    """Thread-specific CPU time when this event ended.
-
-    May be None if the trace event didn't have thread time data.
-    """
-    if self.thread_start == None or self.thread_duration == None:
-      return None
-    return self.thread_start + self.thread_duration
-
-  def __repr__(self):
-    if self.args:
-      args_str = ', ' + repr(self.args)
-    else:
-      args_str = ''
-
-    return ("TimelineEvent(name='%s', start=%f, duration=%s, " +
-            "thread_start=%s, thread_duration=%s%s)") % (
-                self.name,
-                self.start,
-                self.duration,
-                self.thread_start,
-                self.thread_duration,
-                args_str)
diff --git a/catapult/telemetry/telemetry/timeline/event_container.py b/catapult/telemetry/telemetry/timeline/event_container.py
deleted file mode 100644
index 4d41e68..0000000
--- a/catapult/telemetry/telemetry/timeline/event_container.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.timeline import async_slice as async_slice_module
-from telemetry.timeline import flow_event as flow_event_module
-from telemetry.timeline import slice as slice_module
-
-
-class TimelineEventContainer(object):
-  """Represents a container for events.
-
-  """
-  def __init__(self, name, parent):
-    self.parent = parent
-    self.name = name
-
-  @staticmethod
-  def IsAsyncSlice(t):
-    return t == async_slice_module.AsyncSlice
-
-  # Basic functions that subclasses of TimelineEventContainer should implement
-  # in order to expose their events. New methods should be added to this part of
-  # the code only when absolutely certain they're needed.
-
-  def IterChildContainers(self):
-    raise NotImplementedError()
-
-  def IterEventsInThisContainer(self, event_type_predicate, event_predicate):
-    """Iterates all the TimelineEvents in this container.
-
-    Only events with a type matching event_type_predicate AND matching event
-    event_predicate will be yielded.
-
-    event_type_predicate is given an actual type object, e.g.:
-        event_type_predicate(slice_module.Slice)
-
-    event_predicate is given actual events:
-        event_predicate(thread.slices[7])
-
-    DO NOT ASSUME that the event_type_predicate will be called for every event
-    found. The relative calling order of the two is left up to the implementer
-    of the method.
-
-    """
-    del event_type_predicate, event_predicate  # unused
-    return
-    yield # pylint: disable=unreachable
-
-
-  def IterAllEvents(self,
-                    recursive=True,
-                    event_type_predicate=lambda t: True,
-                    event_predicate=lambda e: True):
-    """Iterates all events in this container, pre-filtered by two predicates.
-
-    Only events with a type matching event_type_predicate AND matching event
-    event_predicate will be yielded.
-
-    event_type_predicate is given an actual type object, e.g.:
-        event_type_predicate(slice_module.Slice)
-
-    event_predicate is given actual events:
-        event_predicate(thread.slices[7])
-    """
-    if not recursive:
-      for e in self.IterEventsInThisContainer(
-          event_type_predicate, event_predicate):
-        yield e
-      return
-
-    # TODO(nduca): Write this as a proper iterator instead of one that creates a
-    # list and then iterates it.
-    containers = []
-    def GetContainersRecursive(container):
-      containers.append(container)
-      for container in container.IterChildContainers():
-        GetContainersRecursive(container)
-    GetContainersRecursive(self)
-
-    # Actually create the iterator.
-    for c in containers:
-      for e in c.IterEventsInThisContainer(event_type_predicate,
-                                           event_predicate):
-        yield e
-
-  # Helper functions for finding common kinds of events. Must always take an
-  # optinal recurisve parameter and be implemented in terms fo IterAllEvents.
-  def IterAllEventsOfName(self, name, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=lambda t: True,
-      event_predicate=lambda e: e.name == name)
-
-  def IterAllSlices(self, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=lambda t: t == slice_module.Slice)
-
-  def IterAllSlicesInRange(self, start, end, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=lambda t: t == slice_module.Slice,
-      event_predicate=lambda s: s.start >= start and s.end <= end)
-
-  def IterAllSlicesOfName(self, name, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=lambda t: t == slice_module.Slice,
-      event_predicate=lambda e: e.name == name)
-
-  def IterAllToplevelSlicesOfName(self, name, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=lambda t: t == slice_module.Slice,
-      event_predicate=lambda e: e.name == name and e.parent_slice == None)
-
-  def IterAllAsyncSlicesOfName(self, name, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=self.IsAsyncSlice,
-      event_predicate=lambda e: e.name == name)
-
-  def IterAllAsyncSlicesStartsWithName(self, name, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=self.IsAsyncSlice,
-      event_predicate=lambda e: e.name.startswith(name))
-
-  def IterAllFlowEvents(self, recursive=True):
-    return self.IterAllEvents(
-      recursive=recursive,
-      event_type_predicate=lambda t: t == flow_event_module.FlowEvent)
-
-  # List versions. These should always be simple expressions that list() on
-  # an underlying iter method.
-  def GetAllEvents(self, recursive=True):
-    return list(self.IterAllEvents(recursive=recursive))
-
-  def GetAllEventsOfName(self, name, recursive=True):
-    return list(self.IterAllEventsOfName(name, recursive))
-
-  def GetAllToplevelSlicesOfName(self, name, recursive=True):
-    return list(self.IterAllToplevelSlicesOfName(name, recursive))
diff --git a/catapult/telemetry/telemetry/timeline/event_unittest.py b/catapult/telemetry/telemetry/timeline/event_unittest.py
deleted file mode 100644
index 380fea4..0000000
--- a/catapult/telemetry/telemetry/timeline/event_unittest.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import event
-
-
-class TimelineEventTest(unittest.TestCase):
-  def testHasThreadTimestamps(self):
-    # No thread_start and no thread_duration
-    event_1 = event.TimelineEvent('test', 'foo', 0, 10)
-    # Has thread_start but no thread_duration
-    event_2 = event.TimelineEvent('test', 'foo', 0, 10, 2)
-    # Has thread_duration but no thread_start
-    event_3 = event.TimelineEvent('test', 'foo', 0, 10, None, 4)
-    # Has thread_start and thread_duration
-    event_4 = event.TimelineEvent('test', 'foo', 0, 10, 2, 4)
-
-    self.assertFalse(event_1.has_thread_timestamps)
-    self.assertFalse(event_2.has_thread_timestamps)
-    self.assertFalse(event_3.has_thread_timestamps)
-    self.assertTrue(event_4.has_thread_timestamps)
diff --git a/catapult/telemetry/telemetry/timeline/flow_event.py b/catapult/telemetry/telemetry/timeline/flow_event.py
deleted file mode 100644
index 8a39215..0000000
--- a/catapult/telemetry/telemetry/timeline/flow_event.py
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import telemetry.timeline.event as event
-
-
-class FlowEvent(event.TimelineEvent):
-  """A FlowEvent represents an interval of time plus parameters associated
-  with that interval.
-  """
-  def __init__(self, category, event_id, name, start, args=None):
-    super(FlowEvent, self).__init__(
-        category, name, start, duration=0, args=args)
-    self.event_id = event_id
diff --git a/catapult/telemetry/telemetry/timeline/importer.py b/catapult/telemetry/telemetry/timeline/importer.py
deleted file mode 100644
index 5c355a9..0000000
--- a/catapult/telemetry/telemetry/timeline/importer.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class TimelineImporter(object):
-  """Reads TraceData and populates timeline model with what it finds."""
-  def __init__(self, model, trace_data, import_order):
-    self._model = model
-    self._trace_data = trace_data
-    self.import_order = import_order
-
-  @staticmethod
-  def GetSupportedPart():
-    raise NotImplementedError
-
-  def ImportEvents(self):
-    """Processes the event data in the wrapper and creates and adds
-    new timeline events to the model"""
-    raise NotImplementedError
-
-  def FinalizeImport(self):
-    """Called after all other importers for the model are run."""
-    raise NotImplementedError
diff --git a/catapult/telemetry/telemetry/timeline/inspector_importer.py b/catapult/telemetry/telemetry/timeline/inspector_importer.py
deleted file mode 100644
index 21aa4ed..0000000
--- a/catapult/telemetry/telemetry/timeline/inspector_importer.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Imports event data obtained from the inspector's timeline."""
-
-from telemetry.timeline import importer
-import telemetry.timeline.slice as tracing_slice
-import telemetry.timeline.thread as timeline_thread
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class InspectorTimelineImporter(importer.TimelineImporter):
-  def __init__(self, model, trace_data):
-    super(InspectorTimelineImporter, self).__init__(model,
-                                                    trace_data,
-                                                    import_order=1)
-    traces = trace_data.GetTracesFor(
-      trace_data_module.INSPECTOR_TRACE_PART)
-    assert len(traces) == 1
-    self._events = traces[0]
-
-  @staticmethod
-  def GetSupportedPart():
-    return trace_data_module.INSPECTOR_TRACE_PART
-
-  def ImportEvents(self):
-    render_process = self._model.GetOrCreateProcess(0)
-    for raw_event in self._events:
-      thread = render_process.GetOrCreateThread(raw_event.get('thread', 0))
-      InspectorTimelineImporter.AddRawEventToThreadRecursive(thread, raw_event)
-
-  def FinalizeImport(self):
-    pass
-
-  @staticmethod
-  def AddRawEventToThreadRecursive(thread, raw_inspector_event):
-    pending_slice = None
-    if ('startTime' in raw_inspector_event and
-        'type' in raw_inspector_event):
-      args = {}
-      for x in raw_inspector_event:
-        if x in ('startTime', 'endTime', 'children'):
-          continue
-        args[x] = raw_inspector_event[x]
-      if len(args) == 0:
-        args = None
-      start_time = raw_inspector_event['startTime']
-      end_time = raw_inspector_event.get('endTime', start_time)
-
-      pending_slice = tracing_slice.Slice(
-        thread, 'inspector',
-        raw_inspector_event['type'],
-        start_time,
-        thread_timestamp=None,
-        args=args)
-
-    for child in raw_inspector_event.get('children', []):
-      InspectorTimelineImporter.AddRawEventToThreadRecursive(
-          thread, child)
-
-    if pending_slice:
-      pending_slice.duration = end_time - pending_slice.start
-      thread.PushSlice(pending_slice)
-
-  @staticmethod
-  def RawEventToTimelineEvent(raw_inspector_event):
-    """Converts raw_inspector_event to TimelineEvent."""
-    thread = timeline_thread.Thread(None, 0)
-    InspectorTimelineImporter.AddRawEventToThreadRecursive(
-        thread, raw_inspector_event)
-    thread.FinalizeImport()
-    assert len(thread.toplevel_slices) <= 1
-    if len(thread.toplevel_slices) == 0:
-      return None
-    return thread.toplevel_slices[0]
diff --git a/catapult/telemetry/telemetry/timeline/inspector_importer_unittest.py b/catapult/telemetry/telemetry/timeline/inspector_importer_unittest.py
deleted file mode 100644
index d38e4e0..0000000
--- a/catapult/telemetry/telemetry/timeline/inspector_importer_unittest.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.timeline import inspector_importer
-from telemetry.timeline import model
-from tracing.trace_data import trace_data
-
-
-_BACKGROUND_MESSAGE = {
-  'data': {},
-  'type': 'BeginFrame',
-  'thread': '2',
-  'startTime': 1352783525921.824}
-
-_SAMPLE_MESSAGE = {
-  'children': [
-    {'data': {},
-     'startTime': 1352783525921.823,
-     'type': 'BeginFrame',
-     'usedHeapSize': 1870736},
-    {'children': [],
-     'data': {'height': 723,
-              'width': 1272,
-              'x': 0,
-              'y': 0},
-     'endTime': 1352783525921.8992,
-     'frameId': '10.2',
-     'startTime': 1352783525921.8281,
-     'type': 'Layout',
-     'usedHeapSize': 1870736},
-    {'children': [
-        {'children': [],
-         'data': {'imageType': 'PNG'},
-         'endTime': 1352783525927.7939,
-         'startTime': 1352783525922.4241,
-         'type': 'DecodeImage',
-         'usedHeapSize': 1870736}
-        ],
-     'data': {'height': 432,
-              'width': 1272,
-              'x': 0,
-              'y': 8},
-     'endTime': 1352783525927.9822,
-     'frameId': '10.2',
-     'startTime': 1352783525921.9292,
-     'type': 'Paint',
-     'usedHeapSize': 1870736}
-    ],
-  'data': {},
-  'endTime': 1352783525928.041,
-  'startTime': 1352783525921.8049,
-  'type': 'Program'}
-
-class InspectorEventParsingTest(unittest.TestCase):
-  def testParsingWithSampleData(self):
-    root_event = (inspector_importer.InspectorTimelineImporter
-        .RawEventToTimelineEvent(_SAMPLE_MESSAGE))
-    self.assertTrue(root_event)
-    decode_image_event = [
-      child for child in root_event.IterEventsInThisContainerRecrusively()
-      if child.name == 'DecodeImage'][0]
-    self.assertEquals(decode_image_event.args['data']['imageType'], 'PNG')
-    self.assertTrue(decode_image_event.duration > 0)
-
-  def testParsingWithSimpleData(self):
-    raw_event = {'type': 'Foo',
-                 'startTime': 1,
-                 'endTime': 3,
-                 'children': []}
-    event = (inspector_importer.InspectorTimelineImporter
-        .RawEventToTimelineEvent(raw_event))
-    self.assertEquals('Foo', event.name)
-    self.assertEquals(1, event.start)
-    self.assertEquals(3, event.end)
-    self.assertEquals(2, event.duration)
-    self.assertEquals([], event.sub_slices)
-
-  def testParsingWithArgs(self):
-    raw_event = {'type': 'Foo',
-                 'startTime': 1,
-                 'endTime': 3,
-                 'foo': 7,
-                 'bar': {'x': 1}}
-    event = (inspector_importer.InspectorTimelineImporter
-        .RawEventToTimelineEvent(raw_event))
-    self.assertEquals('Foo', event.name)
-    self.assertEquals(1, event.start)
-    self.assertEquals(3, event.end)
-    self.assertEquals(2, event.duration)
-    self.assertEquals([], event.sub_slices)
-    self.assertEquals(7, event.args['foo'])
-    self.assertEquals(1, event.args['bar']['x'])
-
-  def testEventsWithNoStartTimeAreDropped(self):
-    raw_event = {'type': 'Foo',
-                 'endTime': 1,
-                 'children': []}
-    event = (inspector_importer.InspectorTimelineImporter.
-        RawEventToTimelineEvent(raw_event))
-    self.assertEquals(None, event)
-
-  def testEventsWithNoEndTimeAreOk(self):
-    raw_event = {'type': 'Foo',
-                 'startTime': 1,
-                 'children': []}
-    event = (inspector_importer.InspectorTimelineImporter.
-        RawEventToTimelineEvent(raw_event))
-    self.assertEquals(1, event.start)
-    self.assertEquals(1, event.end)
-
-  def testOutOfOrderData(self):
-    builder = trace_data.TraceDataBuilder()
-    builder.AddTraceFor(
-      trace_data.INSPECTOR_TRACE_PART, [{
-      'startTime': 5295.004, 'endTime': 5305.004,
-      'data': {}, 'type': 'Program',
-      'children': [
-        {'startTime': 5295.004, 'data': {'id': 0}, 'type': 'BeginFrame', },
-        {'startTime': 4492.973, 'endTime': 4493.086, 'data': {'rootNode': -3},
-         'type': 'PaintSetup'},
-        {'startTime': 5298.004, 'endTime': 5301.004, 'type': 'Paint',
-         'frameId': '53228.1',
-         'data': {'rootNode': -3, 'clip': [0, 0, 1018, 0, 1018, 764, 0, 764],
-                  'layerId': 10}, 'children': []},
-        {'startTime': 5301.004, 'endTime': 5305.004, 'data': {},
-         'type': 'CompositeLayers', 'children': []},
-        {'startTime': 5305.004, 'data': {}, 'type': 'MarkFirstPaint'}
-    ]}])
-    model.TimelineModel(builder.AsData(), shift_world_to_zero=False)
-
-class InspectorImporterTest(unittest.TestCase):
-  def testImport(self):
-    builder = trace_data.TraceDataBuilder()
-    builder.AddTraceFor(trace_data.INSPECTOR_TRACE_PART,
-                        [_BACKGROUND_MESSAGE, _SAMPLE_MESSAGE])
-    m = model.TimelineModel(builder.AsData(), shift_world_to_zero=False)
-    self.assertEquals(1, len(m.processes))
-    process = m.processes.values()[0]
-    threads = process.threads
-    self.assertEquals(2, len(threads))
-    renderer_thread = threads[0]
-    self.assertEquals(1, len(renderer_thread.toplevel_slices))
-    self.assertEquals('Program',
-                      renderer_thread.toplevel_slices[0].name)
-    second_thread = threads['2']
-    self.assertEquals(1, len(second_thread.toplevel_slices))
-    self.assertEquals('BeginFrame',
-                      second_thread.toplevel_slices[0].name)
diff --git a/catapult/telemetry/telemetry/timeline/memory_dump_event.py b/catapult/telemetry/telemetry/timeline/memory_dump_event.py
deleted file mode 100644
index e8c0af2..0000000
--- a/catapult/telemetry/telemetry/timeline/memory_dump_event.py
+++ /dev/null
@@ -1,343 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import posixpath
-import re
-
-from telemetry.timeline import event as timeline_event
-
-
-class MmapCategory(object):
-  _DEFAULT_CATEGORY = None
-
-  def __init__(self, name, file_pattern, children=None):
-    """A (sub)category for classifying memory maps.
-
-    Args:
-      name: A string to identify the category.
-      file_pattern: A regex pattern, the category will aggregate memory usage
-          for all mapped files matching this pattern.
-      children: A list of MmapCategory objects, used to sub-categorize memory
-          usage.
-    """
-    self.name = name
-    self._file_pattern = re.compile(file_pattern) if file_pattern else None
-    self._children = list(children) if children else None
-
-  @classmethod
-  def DefaultCategory(cls):
-    """An implicit 'Others' match-all category with no children."""
-    if cls._DEFAULT_CATEGORY is None:
-      cls._DEFAULT_CATEGORY = cls('Others', None)
-    return cls._DEFAULT_CATEGORY
-
-  def Match(self, mapped_file):
-    """Test whether a mapped file matches this category."""
-    return (self._file_pattern is None
-            or bool(self._file_pattern.search(mapped_file)))
-
-  def GetMatchingChild(self, mapped_file):
-    """Get the first matching sub-category for a given mapped file.
-
-    Returns None if the category has no children, or the DefaultCategory if
-    it does have children but none of them match.
-    """
-    if not self._children:
-      return None
-    for child in self._children:
-      if child.Match(mapped_file):
-        return child
-    return type(self).DefaultCategory()
-
-
-ROOT_CATEGORY = MmapCategory('/', None, [
-  MmapCategory('Android', r'^\/dev\/ashmem(?!\/libc malloc)', [
-    MmapCategory('Java runtime', r'^\/dev\/ashmem\/dalvik-', [
-      MmapCategory('Spaces', r'\/dalvik-(alloc|main|large'
-                             r' object|non moving|zygote) space', [
-        MmapCategory('Normal', r'\/dalvik-(alloc|main)'),
-        MmapCategory('Large', r'\/dalvik-large object'),
-        MmapCategory('Zygote', r'\/dalvik-zygote'),
-        MmapCategory('Non-moving', r'\/dalvik-non moving')
-      ]),
-      MmapCategory('Linear Alloc', r'\/dalvik-LinearAlloc'),
-      MmapCategory('Indirect Reference Table', r'\/dalvik-indirect.ref'),
-      MmapCategory('Cache', r'\/dalvik-jit-code-cache'),
-      MmapCategory('Accounting', None)
-    ]),
-    MmapCategory('Cursor', r'\/CursorWindow'),
-    MmapCategory('Ashmem', None)
-  ]),
-  MmapCategory('Native heap',
-               r'^((\[heap\])|(\[anon:)|(\/dev\/ashmem\/libc malloc)|$)'),
-  MmapCategory('Stack', r'^\[stack'),
-  MmapCategory('Files',
-               r'\.((((so)|(jar)|(apk)|(ttf)|(odex)|(oat)|(art))$)|(dex))', [
-    MmapCategory('so', r'\.so$'),
-    MmapCategory('jar', r'\.jar$'),
-    MmapCategory('apk', r'\.apk$'),
-    MmapCategory('ttf', r'\.ttf$'),
-    MmapCategory('dex', r'\.((dex)|(odex$))'),
-    MmapCategory('oat', r'\.oat$'),
-    MmapCategory('art', r'\.art$'),
-  ]),
-  MmapCategory('Devices', r'(^\/dev\/)|(anon_inode:dmabuf)', [
-    MmapCategory('GPU', r'\/((nv)|(mali)|(kgsl))'),
-    MmapCategory('DMA', r'anon_inode:dmabuf'),
-  ]),
-  MmapCategory('Discounted tracing overhead',
-               r'\[discounted tracing overhead\]')
-])
-
-
-# Map long descriptive attribute names, as understood by MemoryBucket.GetValue,
-# to the short keys used by events in raw json traces.
-BUCKET_ATTRS = {
-  'proportional_resident': 'pss',
-  'private_dirty_resident': 'pd',
-  'private_clean_resident': 'pc',
-  'shared_dirty_resident': 'sd',
-  'shared_clean_resident': 'sc',
-  'swapped': 'sw'}
-
-
-# Map of {memory_key: (category_path, discount_tracing), ...}.
-# When discount_tracing is True, we have to discount the resident_size of the
-# tracing allocator to get the correct value for that key.
-MMAPS_METRICS = {
-  'mmaps_overall_pss': ('/.proportional_resident', True),
-  'mmaps_private_dirty' : ('/.private_dirty_resident', True),
-  'mmaps_java_heap': ('/Android/Java runtime/Spaces.proportional_resident',
-                      False),
-  'mmaps_ashmem': ('/Android/Ashmem.proportional_resident', False),
-  'mmaps_native_heap': ('/Native heap.proportional_resident', True)}
-
-
-class MemoryBucket(object):
-  """Simple object to hold and aggregate memory values."""
-  def __init__(self):
-    self._bucket = dict.fromkeys(BUCKET_ATTRS.iterkeys(), 0)
-
-  def __repr__(self):
-    values = ', '.join('%s=%d' % (src_key, self._bucket[dst_key])
-                       for dst_key, src_key
-                       in sorted(BUCKET_ATTRS.iteritems()))
-    return '%s[%s]' % (type(self).__name__, values)
-
-  def AddRegion(self, byte_stats):
-    for dst_key, src_key in BUCKET_ATTRS.iteritems():
-      self._bucket[dst_key] += int(byte_stats.get(src_key, '0'), 16)
-
-  def GetValue(self, name):
-    return self._bucket[name]
-
-
-class ProcessMemoryDumpEvent(timeline_event.TimelineEvent):
-  """A memory dump event belonging to a single timeline.Process object.
-
-  It's a subclass of telemetry's TimelineEvent so it can be included in
-  the stream of events contained in timeline.model objects, and have its
-  timing correlated with that of other events in the model.
-
-  Args:
-    process: The Process object associated with the memory dump.
-    dump_events: A list of dump events of the process with the same dump id.
-
-  Properties:
-    dump_id: A string to identify events belonging to the same global dump.
-    process: The timeline.Process object that owns this memory dump event.
-    has_mmaps: True if the memory dump has mmaps information. If False then
-        GetMemoryUsage will report all zeros.
-  """
-  def __init__(self, process, dump_events):
-    assert dump_events
-
-    start_time = min(event['ts'] for event in dump_events) / 1000.0
-    duration = max(event['ts'] for event in dump_events) / 1000.0 - start_time
-    super(ProcessMemoryDumpEvent, self).__init__('memory', 'memory_dump',
-                                                 start_time, duration)
-
-    self.process = process
-    self.dump_id = dump_events[0]['id']
-
-    allocator_dumps = {}
-    vm_regions = []
-    for event in dump_events:
-      assert (event['ph'] == 'v' and self.process.pid == event['pid'] and
-              self.dump_id == event['id'])
-      try:
-        allocator_dumps.update(event['args']['dumps']['allocators'])
-      except KeyError:
-        pass  # It's ok if any of those keys are not present.
-      try:
-        value = event['args']['dumps']['process_mmaps']['vm_regions']
-        assert not vm_regions
-        vm_regions = value
-      except KeyError:
-        pass  # It's ok if any of those keys are not present.
-
-    self._allocators = {}
-    parent_path = ''
-    parent_has_size = False
-    for allocator_name, size_values in sorted(allocator_dumps.iteritems()):
-      if ((allocator_name.startswith(parent_path) and parent_has_size) or
-          allocator_name.startswith('global/')):
-        continue
-      parent_path = allocator_name + '/'
-      parent_has_size = 'size' in size_values['attrs']
-      name_parts = allocator_name.split('/')
-      allocator_name = name_parts[0]
-      # For 'gpu/android_memtrack/*' we want to keep track of individual
-      # components. E.g. 'gpu/android_memtrack/gl' will be stored as
-      # 'android_memtrack_gl' in the allocators dict.
-      if (len(name_parts) == 3 and allocator_name == 'gpu' and
-          name_parts[1] == 'android_memtrack'):
-        allocator_name = '_'.join(name_parts[1:3])
-      allocator = self._allocators.setdefault(allocator_name, {})
-      for size_key, size_value in size_values['attrs'].iteritems():
-        if size_value['units'] == 'bytes':
-          allocator[size_key] = (allocator.get(size_key, 0)
-                                 + int(size_value['value'], 16))
-    # we need to discount tracing from malloc size.
-    try:
-      self._allocators['malloc']['size'] -= self._allocators['tracing']['size']
-    except KeyError:
-      pass  # It's ok if any of those keys are not present.
-
-    self.has_mmaps = bool(vm_regions)
-    self._buckets = {}
-    for vm_region in vm_regions:
-      self._AddRegion(vm_region)
-
-  @property
-  def process_name(self):
-    return self.process.name
-
-  def _AddRegion(self, vm_region):
-    path = ''
-    category = ROOT_CATEGORY
-    while category:
-      path = posixpath.join(path, category.name)
-      self.GetMemoryBucket(path).AddRegion(vm_region['bs'])
-      mapped_file = vm_region['mf']
-      category = category.GetMatchingChild(mapped_file)
-
-  def __repr__(self):
-    values = ['pid=%d' % self.process.pid]
-    for key, value in sorted(self.GetMemoryUsage().iteritems()):
-      values.append('%s=%d' % (key, value))
-    values = ', '.join(values)
-    return '%s[%s]' % (type(self).__name__, values)
-
-  def GetMemoryBucket(self, path):
-    """Return the MemoryBucket associated with a category path.
-
-    An empty bucket will be created if the path does not already exist.
-
-    path: A string with path in the classification tree, e.g.
-        '/Android/Java runtime/Cache'. Note: no trailing slash, except for
-        the root path '/'.
-    """
-    if not path in self._buckets:
-      self._buckets[path] = MemoryBucket()
-    return self._buckets[path]
-
-  def GetMemoryValue(self, category_path, discount_tracing=False):
-    """Return a specific value from within a MemoryBucket.
-
-    category_path: A string composed of a path in the classification tree,
-        followed by a '.', followed by a specific bucket value, e.g.
-        '/Android/Java runtime/Cache.private_dirty_resident'.
-    discount_tracing: A boolean indicating whether the returned value should
-        be discounted by the resident size of the tracing allocator.
-    """
-    path, name = category_path.rsplit('.', 1)
-    value = self.GetMemoryBucket(path).GetValue(name)
-    if discount_tracing and 'tracing' in self._allocators:
-      value -= self._allocators['tracing'].get('resident_size', 0)
-    return value
-
-  def GetMemoryUsage(self):
-    """Get a dictionary with the memory usage of this process."""
-    usage = {}
-    for name, values in self._allocators.iteritems():
-      # If you wish to track more attributes here, make sure they are correctly
-      # calculated by the ProcessMemoryDumpEvent method. All dumps whose parent
-      # has "size" attribute are ignored to avoid double counting. So, the
-      # other attributes are totals of only top level dumps.
-      if 'size' in values:
-        usage['allocator_%s' % name] = values['size']
-      if 'allocated_objects_size' in values:
-        usage['allocated_objects_%s' % name] = values['allocated_objects_size']
-      if 'memtrack_pss' in values:
-        usage[name] = values['memtrack_pss']
-    if self.has_mmaps:
-      usage.update((key, self.GetMemoryValue(*value))
-                   for key, value in MMAPS_METRICS.iteritems())
-    return usage
-
-
-class GlobalMemoryDump(object):
-  """Object to aggregate individual process dumps with the same dump id.
-
-  Args:
-    process_dumps: A sequence of ProcessMemoryDumpEvent objects, all sharing
-        the same global dump id.
-
-  Attributes:
-    dump_id: A string identifying this dump.
-    has_mmaps: True if the memory dump has mmaps information. If False then
-        GetMemoryUsage will report all zeros.
-  """
-  def __init__(self, process_dumps):
-    assert process_dumps
-    # Keep dumps sorted in chronological order.
-    self._process_dumps = sorted(process_dumps, key=lambda dump: dump.start)
-
-    # All process dump events should have the same dump id.
-    dump_ids = set(dump.dump_id for dump in self._process_dumps)
-    assert len(dump_ids) == 1
-    self.dump_id = dump_ids.pop()
-
-    # Either all processes have mmaps or none of them do.
-    have_mmaps = set(dump.has_mmaps for dump in self._process_dumps)
-    assert len(have_mmaps) == 1
-    self.has_mmaps = have_mmaps.pop()
-
-  @property
-  def start(self):
-    return self._process_dumps[0].start
-
-  @property
-  def end(self):
-    return max(dump.end for dump in self._process_dumps)
-
-  @property
-  def duration(self):
-    return self.end - self.start
-
-  @property
-  def pids(self):
-    return set(d.process.pid for d in self._process_dumps)
-
-  def IterProcessMemoryDumps(self):
-    return iter(self._process_dumps)
-
-  def CountProcessMemoryDumps(self):
-    return len(self._process_dumps)
-
-  def __repr__(self):
-    values = ['id=%s' % self.dump_id]
-    for key, value in sorted(self.GetMemoryUsage().iteritems()):
-      values.append('%s=%d' % (key, value))
-    values = ', '.join(values)
-    return '%s[%s]' % (type(self).__name__, values)
-
-  def GetMemoryUsage(self):
-    """Get the aggregated memory usage over all processes in this dump."""
-    result = {}
-    for dump in self._process_dumps:
-      for key, value in dump.GetMemoryUsage().iteritems():
-        result[key] = result.get(key, 0) + value
-    return result
diff --git a/catapult/telemetry/telemetry/timeline/memory_dump_event_unittest.py b/catapult/telemetry/telemetry/timeline/memory_dump_event_unittest.py
deleted file mode 100644
index 966f9ad..0000000
--- a/catapult/telemetry/telemetry/timeline/memory_dump_event_unittest.py
+++ /dev/null
@@ -1,278 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import memory_dump_event
-import mock
-
-
-def MakeRawMemoryDumpEvent(dump_id='123456ABCDEF', pid=1234, start=0,
-                           mmaps=None, allocators=None):
-
-  def vm_region(mapped_file, byte_stats):
-    return {
-      'mf': mapped_file,
-      'bs': {k: hex(v) for k, v in byte_stats.iteritems()}}
-
-  def attrs(sizes):
-    return {'attrs': {k: {'value': hex(v), 'units': 'bytes'}
-                      for k, v in sizes.iteritems()}}
-
-  if allocators is None:
-    allocators = {}
-
-  event = {'ph': 'v', 'id': dump_id, 'pid': pid, 'ts': start * 1000,
-           'args': {'dumps': {'allocators': {
-               name: attrs(sizes) for name, sizes in allocators.iteritems()}}}}
-  if mmaps:
-    event['args']['dumps']['process_mmaps'] = {
-      'vm_regions': [vm_region(mapped_file, byte_stats)
-                     for mapped_file, byte_stats in mmaps.iteritems()]}
-
-  return event
-
-
-def TestProcessDumpEvent(dump_id='123456ABCDEF', pid=1234, start=0, mmaps=None,
-                         allocators=None):
-  event = MakeRawMemoryDumpEvent(dump_id, pid, start, mmaps=mmaps,
-                                allocators=allocators)
-  process = mock.Mock()
-  process.pid = event['pid']
-  return memory_dump_event.ProcessMemoryDumpEvent(process, [event])
-
-
-class ProcessMemoryDumpEventUnitTest(unittest.TestCase):
-
-  def testProcessMemoryDump_allocators(self):
-    process = mock.Mock()
-    process.pid = 1234
-    events = [
-      MakeRawMemoryDumpEvent(
-        pid=process.pid, allocators={
-          'v8': {'size': 10, 'allocated_objects_size': 5},
-          'v8/allocated_objects': {'size': 4},
-          'skia': {'not_size': 10,
-          'allocated_objects_size': 5},
-          'skia/cache1': {'size': 24}
-        }
-      ),
-      MakeRawMemoryDumpEvent(
-        pid=process.pid, allocators={
-          'skia/cache2': {'not_size': 20},
-          'skia/cache2/obj1': {'size': 8},
-          'skia/cache2/obj2': {'size': 9},
-          'skia_different/obj': {'size': 30},
-          'skia_different/obj/not_counted': {'size': 26},
-          'global/0xdead': {'size': 26}
-        }
-      )
-    ]
-    memory_dump = memory_dump_event.ProcessMemoryDumpEvent(process, events)
-
-    EXPECTED_ALLOCATORS = {
-      'skia': {
-        'allocated_objects_size': 5,
-        'not_size': 30,
-        'size': 41
-      },
-      'v8': {
-        'allocated_objects_size': 5,
-        'size': 10
-      },
-      'skia_different': {'size': 30}
-    }
-
-    self.assertEquals(memory_dump._allocators, EXPECTED_ALLOCATORS)
-
-  def testProcessMemoryDump_mmaps(self):
-    ALL = [2 ** x for x in range(8)]
-    (JAVA_SPACES, JAVA_CACHE, ASHMEM, NATIVE_1, NATIVE_2, STACK, FILES_APK,
-     DEVICE_GPU) = ALL
-
-    memory_dump = TestProcessDumpEvent(mmaps={
-      '/dev/ashmem/dalvik-space-foo': {'pss': JAVA_SPACES},
-      '/dev/ashmem/dalvik-jit-code-cache': {'pss': JAVA_CACHE},
-      '/dev/ashmem/other-random-stuff': {'pss': ASHMEM},
-      '[heap] bar': {'pss': NATIVE_1},
-      '': {'pss': NATIVE_2},
-      '[stack thingy]': {'pss': STACK},
-      'my_little_app.apk': {'pss': FILES_APK},
-      '/dev/mali': {'pss': DEVICE_GPU}
-    })
-
-    EXPECTED = {
-      '/': sum(ALL),
-      '/Android/Java runtime': JAVA_SPACES + JAVA_CACHE,
-      '/Android/Ashmem': ASHMEM,
-      '/Android': JAVA_SPACES + JAVA_CACHE + ASHMEM,
-      '/Native heap': NATIVE_1 + NATIVE_2,
-      '/Stack': STACK,
-      '/Files/apk': FILES_APK,
-      '/Devices': DEVICE_GPU}
-
-    self.assertTrue(memory_dump.has_mmaps)
-    for path, value in EXPECTED.iteritems():
-      self.assertEquals(
-          value,
-          memory_dump.GetMemoryBucket(path).GetValue('proportional_resident'))
-
-  def testProcessMemoryDump_composability(self):
-    java_spaces = 100
-    process = mock.Mock()
-    process.pid = 1234
-    allocators = {'v8': {'size': 10}}
-    mmaps = {'/dev/ashmem/dalvik-space-foo': {'pss': java_spaces}}
-
-    events = [MakeRawMemoryDumpEvent(pid=process.pid, allocators=allocators),
-              MakeRawMemoryDumpEvent(pid=process.pid, mmaps=mmaps)]
-    memory_dump = memory_dump_event.ProcessMemoryDumpEvent(process, events)
-
-    self.assertEquals(memory_dump._allocators, allocators)
-
-    EXPECTED_MMAPS = {
-      '/': java_spaces,
-      '/Android/Java runtime': java_spaces,
-      '/Android': java_spaces,
-    }
-
-    self.assertTrue(memory_dump.has_mmaps)
-    for path, value in EXPECTED_MMAPS.iteritems():
-      self.assertEquals(value,
-          memory_dump.GetMemoryBucket(path).GetValue('proportional_resident'))
-
-
-class MemoryDumpEventUnitTest(unittest.TestCase):
-  def testRepr(self):
-    process_dump1 = TestProcessDumpEvent(
-        mmaps={'/dev/ashmem/other-ashmem': {'pss': 5}},
-        allocators={'v8': {'size': 10, 'allocated_objects_size' : 5}})
-    process_dump2 = TestProcessDumpEvent(
-        mmaps={'/dev/ashmem/libc malloc': {'pss': 42, 'pd': 27}},
-        allocators={'v8': {'size': 20, 'allocated_objects_size' : 10},
-                    'oilpan': {'size': 40}})
-    global_dump = memory_dump_event.GlobalMemoryDump(
-        [process_dump1, process_dump2])
-
-    self.assertEquals(
-        repr(process_dump1),
-        'ProcessMemoryDumpEvent[pid=1234, allocated_objects_v8=5,'
-        ' allocator_v8=10, mmaps_ashmem=5, mmaps_java_heap=0,'
-        ' mmaps_native_heap=0, mmaps_overall_pss=5, mmaps_private_dirty=0]')
-    self.assertEquals(
-        repr(process_dump2),
-        'ProcessMemoryDumpEvent[pid=1234, allocated_objects_v8=10,'
-        ' allocator_oilpan=40, allocator_v8=20, mmaps_ashmem=0,'
-        ' mmaps_java_heap=0, mmaps_native_heap=42, mmaps_overall_pss=42,'
-        ' mmaps_private_dirty=27]')
-    self.assertEquals(
-        repr(global_dump),
-        'GlobalMemoryDump[id=123456ABCDEF, allocated_objects_v8=15,'
-        ' allocator_oilpan=40, allocator_v8=30, mmaps_ashmem=5,'
-        ' mmaps_java_heap=0, mmaps_native_heap=42, mmaps_overall_pss=47,'
-        ' mmaps_private_dirty=27]')
-
-  def testDumpEventsTiming(self):
-    process = mock.Mock()
-    process.pid = 1
-    composable_dump = memory_dump_event.ProcessMemoryDumpEvent(
-        process,
-        [
-          MakeRawMemoryDumpEvent(pid=process.pid, start=8),
-          MakeRawMemoryDumpEvent(pid=process.pid, start=16),
-          MakeRawMemoryDumpEvent(pid=process.pid, start=10)
-        ])
-    self.assertAlmostEquals(8.0, composable_dump.start)
-    self.assertAlmostEquals(16.0, composable_dump.end)
-
-    memory_dump = memory_dump_event.GlobalMemoryDump([
-        composable_dump,
-        TestProcessDumpEvent(pid=3, start=8),
-        TestProcessDumpEvent(pid=2, start=13),
-        TestProcessDumpEvent(pid=4, start=7)])
-
-    self.assertFalse(memory_dump.has_mmaps)
-    self.assertEquals(4, len(list(memory_dump.IterProcessMemoryDumps())))
-    self.assertItemsEqual([1, 2, 3, 4], memory_dump.pids)
-    self.assertAlmostEquals(7.0, memory_dump.start)
-    self.assertAlmostEquals(16.0, memory_dump.end)
-    self.assertAlmostEquals(9.0, memory_dump.duration)
-
-  def testGetMemoryUsage(self):
-    ALL = [2 ** x for x in range(7)]
-    (JAVA_HEAP_1, JAVA_HEAP_2, ASHMEM_1, ASHMEM_2, NATIVE,
-     DIRTY_1, DIRTY_2) = ALL
-
-    memory_dump = memory_dump_event.GlobalMemoryDump([
-        TestProcessDumpEvent(pid=1, mmaps={
-            '/dev/ashmem/dalvik-alloc space': {'pss': JAVA_HEAP_1}}),
-        TestProcessDumpEvent(pid=2, mmaps={
-            '/dev/ashmem/other-ashmem': {'pss': ASHMEM_1, 'pd': DIRTY_1}}),
-        TestProcessDumpEvent(pid=3, mmaps={
-            '[heap] native': {'pss': NATIVE, 'pd': DIRTY_2},
-            '/dev/ashmem/dalvik-zygote space': {'pss': JAVA_HEAP_2}}),
-        TestProcessDumpEvent(pid=4, mmaps={
-            '/dev/ashmem/other-ashmem': {'pss': ASHMEM_2}})])
-
-    self.assertTrue(memory_dump.has_mmaps)
-    self.assertItemsEqual([1, 2, 3, 4], memory_dump.pids)
-    self.assertEquals({'mmaps_overall_pss': sum(ALL[:5]),
-                       'mmaps_private_dirty': DIRTY_1 + DIRTY_2,
-                       'mmaps_java_heap': JAVA_HEAP_1 + JAVA_HEAP_2,
-                       'mmaps_ashmem': ASHMEM_1 + ASHMEM_2,
-                       'mmaps_native_heap': NATIVE},
-                      memory_dump.GetMemoryUsage())
-
-  def testGetMemoryUsageWithAllocators(self):
-    process_dump1 = TestProcessDumpEvent(
-        mmaps={'/dev/ashmem/other-ashmem': {'pss': 5}},
-        allocators={'v8': {'size': 10, 'allocated_objects_size' : 5}})
-    process_dump2 = TestProcessDumpEvent(
-        mmaps={'/dev/ashmem/other-ashmem': {'pss': 5}},
-        allocators={'v8': {'size': 20, 'allocated_objects_size' : 10}})
-    memory_dump = memory_dump_event.GlobalMemoryDump(
-        [process_dump1, process_dump2])
-    self.assertEquals({'mmaps_overall_pss': 10,
-                       'mmaps_private_dirty': 0,
-                       'mmaps_java_heap': 0,
-                       'mmaps_ashmem': 10,
-                       'mmaps_native_heap': 0,
-                       'allocator_v8': 30,
-                       'allocated_objects_v8': 15},
-                      memory_dump.GetMemoryUsage())
-
-  def testGetMemoryUsageWithAndroidMemtrack(self):
-    GL1, EGL1, GL2, EGL2 = [2 ** x for x in range(4)]
-    process_dump1 = TestProcessDumpEvent(
-        allocators={'gpu/android_memtrack/gl': {'memtrack_pss' : GL1},
-                    'gpu/android_memtrack/graphics': {'memtrack_pss': EGL1}})
-    process_dump2 = TestProcessDumpEvent(
-        allocators={'gpu/android_memtrack/gl': {'memtrack_pss' : GL2},
-                    'gpu/android_memtrack/graphics': {'memtrack_pss': EGL2}})
-    memory_dump = memory_dump_event.GlobalMemoryDump(
-        [process_dump1, process_dump2])
-    self.assertEquals({'android_memtrack_gl': GL1 + GL2,
-                       'android_memtrack_graphics': EGL1 + EGL2},
-                      memory_dump.GetMemoryUsage())
-
-  def testGetMemoryUsageDiscountsTracing(self):
-    ALL = [2 ** x for x in range(5)]
-    (HEAP, DIRTY, MALLOC, TRACING_1, TRACING_2) = ALL
-
-    memory_dump = memory_dump_event.GlobalMemoryDump([
-        TestProcessDumpEvent(
-            mmaps={'/dev/ashmem/libc malloc': {'pss': HEAP + TRACING_2,
-                                               'pd': DIRTY + TRACING_2}},
-            allocators={
-                'tracing': {'size': TRACING_1, 'resident_size': TRACING_2},
-                'malloc': {'size': MALLOC + TRACING_1}})])
-
-    self.assertEquals({'mmaps_overall_pss': HEAP,
-                       'mmaps_private_dirty': DIRTY,
-                       'mmaps_java_heap': 0,
-                       'mmaps_ashmem': 0,
-                       'mmaps_native_heap': HEAP,
-                       'allocator_tracing': TRACING_1,
-                       'allocator_malloc': MALLOC},
-                      memory_dump.GetMemoryUsage())
diff --git a/catapult/telemetry/telemetry/timeline/model.py b/catapult/telemetry/telemetry/timeline/model.py
deleted file mode 100644
index 278b70c..0000000
--- a/catapult/telemetry/telemetry/timeline/model.py
+++ /dev/null
@@ -1,279 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""A container for timeline-based events and traces and can handle importing
-raw event data from different sources. This model closely resembles that in the
-trace_viewer project:
-https://code.google.com/p/trace-viewer/
-"""
-
-import logging
-from operator import attrgetter
-
-from telemetry.timeline import async_slice as async_slice_module
-from telemetry.timeline import bounds
-from telemetry.timeline import event_container
-from telemetry.timeline import inspector_importer
-from telemetry.timeline import process as process_module
-from telemetry.timeline import slice as slice_module
-from telemetry.timeline import surface_flinger_importer
-from telemetry.timeline import tab_id_importer
-from telemetry.timeline import trace_event_importer
-from tracing.trace_data import trace_data as trace_data_module
-
-
-# Register importers for data
-
-_IMPORTERS = [
-    inspector_importer.InspectorTimelineImporter,
-    tab_id_importer.TabIdImporter,
-    trace_event_importer.TraceEventTimelineImporter,
-    surface_flinger_importer.SurfaceFlingerTimelineImporter
-]
-
-
-class MarkerMismatchError(Exception):
-  def __init__(self):
-    super(MarkerMismatchError, self).__init__(
-        'Number or order of timeline markers does not match provided labels')
-
-
-class MarkerOverlapError(Exception):
-  def __init__(self):
-    super(MarkerOverlapError, self).__init__(
-        'Overlapping timeline markers found')
-
-
-def IsSliceOrAsyncSlice(t):
-  if t == async_slice_module.AsyncSlice:
-    return True
-  return t == slice_module.Slice
-
-
-class TimelineModel(event_container.TimelineEventContainer):
-  def __init__(self, trace_data=None, shift_world_to_zero=True):
-    """ Initializes a TimelineModel.
-
-    Args:
-        trace_data: trace_data.TraceData containing events to import
-        shift_world_to_zero: If true, the events will be shifted such that the
-            first event starts at time 0.
-    """
-    super(TimelineModel, self).__init__(name='TimelineModel', parent=None)
-    self._bounds = bounds.Bounds()
-    self._thread_time_bounds = {}
-    self._processes = {}
-    self._browser_process = None
-    self._gpu_process = None
-    self._surface_flinger_process = None
-    self._frozen = False
-    self._tab_ids_to_renderer_threads_map = {}
-    self.import_errors = []
-    self.metadata = []
-    self.flow_events = []
-    self._global_memory_dumps = None
-    if trace_data is not None:
-      self.ImportTraces(trace_data, shift_world_to_zero=shift_world_to_zero)
-
-  def SetGlobalMemoryDumps(self, global_memory_dumps):
-    """Populates the model with a sequence of GlobalMemoryDump objects."""
-    assert not self._frozen and self._global_memory_dumps is None
-    # Keep dumps sorted in chronological order.
-    self._global_memory_dumps = tuple(sorted(global_memory_dumps,
-                                             key=lambda dump: dump.start))
-
-  def IterGlobalMemoryDumps(self):
-    """Iterate over the memory dump events of this model."""
-    return iter(self._global_memory_dumps or [])
-
-  def IterChildContainers(self):
-    for process in self._processes.itervalues():
-      yield process
-
-  def GetAllProcesses(self):
-    return self._processes.values()
-
-  def GetAllThreads(self):
-    threads = []
-    for process in self._processes.values():
-      threads.extend(process.threads.values())
-    return threads
-
-  @property
-  def bounds(self):
-    return self._bounds
-
-  @property
-  def processes(self):
-    return self._processes
-
-  @property
-  def browser_process(self):
-    return self._browser_process
-
-  @browser_process.setter
-  def browser_process(self, browser_process):
-    self._browser_process = browser_process
-
-  @property
-  def gpu_process(self):
-    return self._gpu_process
-
-  @gpu_process.setter
-  def gpu_process(self, gpu_process):
-    self._gpu_process = gpu_process
-
-  @property
-  def surface_flinger_process(self):
-    return self._surface_flinger_process
-
-  @surface_flinger_process.setter
-  def surface_flinger_process(self, surface_flinger_process):
-    self._surface_flinger_process = surface_flinger_process
-
-  def AddMappingFromTabIdToRendererThread(self, tab_id, renderer_thread):
-    if self._frozen:
-      raise Exception('Cannot add mapping from tab id to renderer thread once '
-                      'trace is imported')
-    self._tab_ids_to_renderer_threads_map[tab_id] = renderer_thread
-
-  def ImportTraces(self, trace_data, shift_world_to_zero=True):
-    """Populates the model with the provided trace data.
-
-    trace_data must be an instance of TraceData.
-
-    Passing shift_world_to_zero=True causes the events to be shifted such that
-    the first event starts at time 0.
-    """
-    if self._frozen:
-      raise Exception("Cannot add events once trace is imported")
-    assert isinstance(trace_data, trace_data_module.TraceData)
-
-    importers = self._CreateImporters(trace_data)
-
-    for importer in importers:
-      # TODO: catch exceptions here and add it to error list
-      importer.ImportEvents()
-    self.FinalizeImport(shift_world_to_zero, importers)
-
-  def FinalizeImport(self, shift_world_to_zero=False, importers=None):
-    if importers == None:
-      importers = []
-    self.UpdateBounds()
-    if not self.bounds.is_empty:
-      for process in self._processes.itervalues():
-        process.AutoCloseOpenSlices(self.bounds.max,
-                                    self._thread_time_bounds)
-
-    for importer in importers:
-      importer.FinalizeImport()
-
-    for process in self.processes.itervalues():
-      process.FinalizeImport()
-
-    if shift_world_to_zero:
-      self.ShiftWorldToZero()
-    self.UpdateBounds()
-
-    # Because of FinalizeImport, it would probably be a good idea
-    # to prevent the timeline from from being modified.
-    self._frozen = True
-
-  def ShiftWorldToZero(self):
-    self.UpdateBounds()
-    if self._bounds.is_empty:
-      return
-    shift_amount = self._bounds.min
-    for event in self.IterAllEvents():
-      event.start -= shift_amount
-
-  def UpdateBounds(self):
-    self._bounds.Reset()
-    for event in self.IterAllEvents():
-      self._bounds.AddValue(event.start)
-      self._bounds.AddValue(event.end)
-
-    self._thread_time_bounds = {}
-    for thread in self.GetAllThreads():
-      self._thread_time_bounds[thread] = bounds.Bounds()
-      for event in thread.IterEventsInThisContainer(
-          event_type_predicate=lambda t: True,
-          event_predicate=lambda e: True):
-        if event.thread_start != None:
-          self._thread_time_bounds[thread].AddValue(event.thread_start)
-        if event.thread_end != None:
-          self._thread_time_bounds[thread].AddValue(event.thread_end)
-
-  def GetOrCreateProcess(self, pid):
-    if pid not in self._processes:
-      assert not self._frozen
-      self._processes[pid] = process_module.Process(self, pid)
-    return self._processes[pid]
-
-  def FindTimelineMarkers(self, timeline_marker_names):
-    """Find the timeline events with the given names.
-
-    If the number and order of events found does not match the names,
-    raise an error.
-    """
-    # Make sure names are in a list and remove all None names
-    if not isinstance(timeline_marker_names, list):
-      timeline_marker_names = [timeline_marker_names]
-    names = [x for x in timeline_marker_names if x is not None]
-
-    # Gather all events that match the names and sort them.
-    events = []
-    name_set = set()
-    for name in names:
-      name_set.add(name)
-
-    def IsEventNeeded(event):
-      if event.parent_slice != None:
-        return
-      return event.name in name_set
-
-    events = list(self.IterAllEvents(
-      recursive=True,
-      event_type_predicate=IsSliceOrAsyncSlice,
-      event_predicate=IsEventNeeded))
-    events.sort(key=attrgetter('start'))
-
-    # Check if the number and order of events matches the provided names,
-    # and that the events don't overlap.
-    if len(events) != len(names):
-      raise MarkerMismatchError()
-    for (i, event) in enumerate(events):
-      if event.name != names[i]:
-        raise MarkerMismatchError()
-    for i in xrange(0, len(events)):
-      for j in xrange(i+1, len(events)):
-        if events[j].start < events[i].start + events[i].duration:
-          raise MarkerOverlapError()
-
-    return events
-
-  def GetRendererProcessFromTabId(self, tab_id):
-    renderer_thread = self.GetRendererThreadFromTabId(tab_id)
-    if renderer_thread:
-      return renderer_thread.parent
-    return None
-
-  def GetRendererThreadFromTabId(self, tab_id):
-    return self._tab_ids_to_renderer_threads_map.get(tab_id, None)
-
-  def _CreateImporters(self, trace_data):
-    def FindImporterClassForPart(part):
-      for importer_class in _IMPORTERS:
-        if importer_class.GetSupportedPart() == part:
-          return importer_class
-
-    importers = []
-    for part in trace_data.active_parts:
-      importer_class = FindImporterClassForPart(part)
-      if not importer_class:
-        logging.warning('No importer found for %s' % repr(part))
-      else:
-        importers.append(importer_class(self, trace_data))
-        importers.sort(key=lambda k: k.import_order)
-
-    return importers
diff --git a/catapult/telemetry/telemetry/timeline/model_unittest.py b/catapult/telemetry/telemetry/timeline/model_unittest.py
deleted file mode 100644
index bb1af1b..0000000
--- a/catapult/telemetry/telemetry/timeline/model_unittest.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import model as model_module
-from tracing.trace_data import trace_data
-
-
-class TimelineModelUnittest(unittest.TestCase):
-  def testEmptyImport(self):
-    model_module.TimelineModel(trace_data.CreateTraceDataFromRawData({}))
-
-  def testBrowserProcess(self):
-    builder = trace_data.TraceDataBuilder()
-    builder.AddTraceFor(trace_data.CHROME_TRACE_PART, {
-      "traceEvents": [
-        {"name": "process_name", "args": {"name": "Browser"},
-         "pid": 5, "ph": "M"},
-        {"name": "thread_name", "args": {"name": "CrBrowserMain"},
-         "pid": 5, "tid": 32578, "ph": "M"}]})
-    model = model_module.TimelineModel(builder.AsData())
-    self.assertEquals(5, model.browser_process.pid)
diff --git a/catapult/telemetry/telemetry/timeline/process.py b/catapult/telemetry/telemetry/timeline/process.py
deleted file mode 100644
index 516f03f..0000000
--- a/catapult/telemetry/telemetry/timeline/process.py
+++ /dev/null
@@ -1,101 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import telemetry.timeline.counter as tracing_counter
-import telemetry.timeline.event as event_module
-import telemetry.timeline.event_container as event_container
-import telemetry.timeline.thread as tracing_thread
-from telemetry.timeline import memory_dump_event
-
-
-class Process(event_container.TimelineEventContainer):
-  """The Process represents a single userland process in the trace.
-  """
-  def __init__(self, parent, pid):
-    super(Process, self).__init__('process %s' % pid, parent)
-    self.pid = pid
-    self.labels = None
-    self.uptime_seconds = None
-    self._threads = {}
-    self._counters = {}
-    self._trace_buffer_overflow_event = None
-    self._memory_dump_events = {}
-
-  @property
-  def trace_buffer_did_overflow(self):
-    return self._trace_buffer_overflow_event is not None
-
-  @property
-  def trace_buffer_overflow_event(self):
-    return self._trace_buffer_overflow_event
-
-  @property
-  def threads(self):
-    return self._threads
-
-  @property
-  def counters(self):
-    return self._counters
-
-  def IterChildContainers(self):
-    for thread in self._threads.itervalues():
-      yield thread
-    for counter in self._counters.itervalues():
-      yield counter
-
-  def IterEventsInThisContainer(self, event_type_predicate, event_predicate):
-    if (self.trace_buffer_did_overflow and
-        event_type_predicate(event_module.TimelineEvent) and
-        event_predicate(self._trace_buffer_overflow_event)):
-      yield self._trace_buffer_overflow_event
-    if (self._memory_dump_events and
-        event_type_predicate(memory_dump_event.ProcessMemoryDumpEvent)):
-      for memory_dump in self._memory_dump_events.itervalues():
-        if event_predicate(memory_dump):
-          yield memory_dump
-
-  def GetOrCreateThread(self, tid):
-    thread = self.threads.get(tid, None)
-    if thread:
-      return thread
-    thread = tracing_thread.Thread(self, tid)
-    self._threads[tid] = thread
-    return thread
-
-  def GetCounter(self, category, name):
-    counter_id = category + '.' + name
-    if counter_id in self.counters:
-      return self.counters[counter_id]
-    raise ValueError(
-        'Counter %s not found in process with id %s.' % (counter_id,
-                                                         self.pid))
-  def GetOrCreateCounter(self, category, name):
-    try:
-      return self.GetCounter(category, name)
-    except ValueError:
-      ctr = tracing_counter.Counter(self, category, name)
-      self._counters[ctr.full_name] = ctr
-      return ctr
-
-  def AutoCloseOpenSlices(self, max_timestamp, thread_time_bounds):
-    for thread in self._threads.itervalues():
-      thread.AutoCloseOpenSlices(max_timestamp, thread_time_bounds[thread].max)
-
-  def SetTraceBufferOverflowTimestamp(self, timestamp):
-    # TODO: use instant event for trace_buffer_overflow_event
-    self._trace_buffer_overflow_event = event_module.TimelineEvent(
-        "TraceBufferInfo", "trace_buffer_overflowed", timestamp, 0)
-
-  def AddMemoryDumpEvent(self, memory_dump):
-    """Add a ProcessMemoryDumpEvent to this process."""
-    if memory_dump.dump_id in self._memory_dump_events:
-      raise ValueError('Duplicate memory dump id %s in process with id %s.' % (
-          memory_dump.dump_id, self.pid))
-    self._memory_dump_events[memory_dump.dump_id] = memory_dump
-
-  def FinalizeImport(self):
-    for thread in self._threads.itervalues():
-      thread.FinalizeImport()
-    for counter in self._counters.itervalues():
-      counter.FinalizeImport()
diff --git a/catapult/telemetry/telemetry/timeline/sample.py b/catapult/telemetry/telemetry/timeline/sample.py
deleted file mode 100644
index 806f60f..0000000
--- a/catapult/telemetry/telemetry/timeline/sample.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import telemetry.timeline.event as timeline_event
-
-
-class Sample(timeline_event.TimelineEvent):
-  """A Sample represents a sample taken at an instant in time
-  plus parameters associated with that sample.
-
-  NOTE: The Sample class implements the same interface as
-  Slice. These must be kept in sync.
-
-  All time units are stored in milliseconds.
-  """
-  def __init__(self, parent_thread, category, name, timestamp, args=None):
-    super(Sample, self).__init__(
-        category, name, timestamp, 0, args=args)
-    self.parent_thread = parent_thread
diff --git a/catapult/telemetry/telemetry/timeline/slice.py b/catapult/telemetry/telemetry/timeline/slice.py
deleted file mode 100644
index 3a39a80..0000000
--- a/catapult/telemetry/telemetry/timeline/slice.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import telemetry.timeline.event as timeline_event
-
-
-class Slice(timeline_event.TimelineEvent):
-  """A Slice represents an interval of time plus parameters associated
-  with that interval.
-
-  NOTE: The Sample class implements the same interface as
-  Slice. These must be kept in sync.
-
-  All time units are stored in milliseconds.
-  """
-  def __init__(self, parent_thread, category, name, timestamp, duration=0,
-               thread_timestamp=None, thread_duration=None, args=None):
-    super(Slice, self).__init__(
-        category, name, timestamp, duration, thread_timestamp, thread_duration,
-        args)
-    self.parent_thread = parent_thread
-    self.parent_slice = None
-    self.sub_slices = []
-    self.did_not_finish = False
-
-  def AddSubSlice(self, sub_slice):
-    assert sub_slice.parent_slice == self
-    self.sub_slices.append(sub_slice)
-
-  def IterEventsInThisContainerRecrusively(self, stack=None):
-    # This looks awkward, but it lets us create only a single iterator instead
-    # of having to create one iterator for every subslice found.
-    if stack == None:
-      stack = []
-    else:
-      assert len(stack) == 0
-    stack.extend(reversed(self.sub_slices))
-    while len(stack):
-      s = stack.pop()
-      yield s
-      stack.extend(reversed(s.sub_slices))
-
-  @property
-  def self_time(self):
-    """Time spent in this function less any time spent in child events."""
-    child_total = sum(
-      [e.duration for e in self.sub_slices])
-    return self.duration - child_total
-
-  @property
-  def self_thread_time(self):
-    """Thread (scheduled) time spent in this function less any thread time spent
-    in child events. Returns None if the slice or any of its children does not
-    have a thread_duration value.
-    """
-    if not self.thread_duration:
-      return None
-
-    child_total = 0
-    for e in self.sub_slices:
-      if e.thread_duration == None:
-        return None
-      child_total += e.thread_duration
-
-    return self.thread_duration - child_total
-
-  def _GetSubSlicesRecursive(self):
-    for sub_slice in self.sub_slices:
-      for s in sub_slice.GetAllSubSlices():
-        yield s
-      yield sub_slice
-
-  def GetAllSubSlices(self):
-    return list(self._GetSubSlicesRecursive())
-
-  def GetAllSubSlicesOfName(self, name):
-    return [e for e in self.GetAllSubSlices() if e.name == name]
diff --git a/catapult/telemetry/telemetry/timeline/slice_unittest.py b/catapult/telemetry/telemetry/timeline/slice_unittest.py
deleted file mode 100644
index 67106c3..0000000
--- a/catapult/telemetry/telemetry/timeline/slice_unittest.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline.slice import Slice
-
-
-class SliceTest(unittest.TestCase):
-  def testChildrenLogic(self):
-    # [      top          ]
-    #   [ a  ]    [  b  ]
-    #    [x]
-    top = Slice(None, 'cat', 'top', 0, duration=10, thread_timestamp=0,
-                thread_duration=5)
-    a = Slice(None, 'cat', 'a', 1, duration=2, thread_timestamp=0.5,
-              thread_duration=1)
-    x = Slice(None, 'cat', 'x', 1.5, duration=0.25, thread_timestamp=0.75,
-              thread_duration=0.125)
-    b = Slice(None, 'cat', 'b', 5, duration=2, thread_timestamp=None,
-              thread_duration=None)
-    top.sub_slices.extend([a, b])
-    a.sub_slices.append(x)
-
-    all_children = list(top.IterEventsInThisContainerRecrusively())
-    self.assertEquals([a, x, b], all_children)
-
-    self.assertEquals(x.self_time, 0.25)
-    self.assertEquals(a.self_time, 1.75) # 2 - 0.25
-    self.assertEquals(top.self_time, 6) # 10 - 2 - 2
-
-    self.assertEquals(x.self_thread_time, 0.125)
-    self.assertEquals(a.self_thread_time, 0.875) # 1 - 0.125
-    self.assertEquals(top.self_thread_time, None) # b has no thread time
diff --git a/catapult/telemetry/telemetry/timeline/surface_flinger_importer.py b/catapult/telemetry/telemetry/timeline/surface_flinger_importer.py
deleted file mode 100644
index a02637f..0000000
--- a/catapult/telemetry/telemetry/timeline/surface_flinger_importer.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.timeline import importer
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class SurfaceFlingerTimelineImporter(importer.TimelineImporter):
-  def __init__(self, model, trace_data):
-    super(SurfaceFlingerTimelineImporter, self).__init__(
-        model, trace_data, import_order=2)
-    traces = trace_data.GetTracesFor(trace_data_module.SURFACE_FLINGER_PART)
-    assert len(traces) == 1
-    self._events = traces[0]
-    self._surface_flinger_process = None
-
-  @staticmethod
-  def GetSupportedPart():
-    return trace_data_module.SURFACE_FLINGER_PART
-
-  def ImportEvents(self):
-    for event in self._events:
-      self._surface_flinger_process = self._model.GetOrCreateProcess(
-          event['pid'])
-      self._surface_flinger_process.name = 'SurfaceFlinger'
-      thread = self._surface_flinger_process.GetOrCreateThread(event['tid'])
-      thread.BeginSlice(event['cat'],
-                        event['name'],
-                        event['ts'],
-                        args=event.get('args'))
-      thread.EndSlice(event['ts'])
-
-  def FinalizeImport(self):
-    """Called by the Model after all other importers have imported their
-    events."""
-    self._model.UpdateBounds()
-    self._model.surface_flinger_process = self._surface_flinger_process
diff --git a/catapult/telemetry/telemetry/timeline/tab_id_importer.py b/catapult/telemetry/telemetry/timeline/tab_id_importer.py
deleted file mode 100644
index 025d80b..0000000
--- a/catapult/telemetry/telemetry/timeline/tab_id_importer.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.timeline import importer
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TraceBufferOverflowException(Exception):
-  pass
-
-
-class TabIdImporter(importer.TimelineImporter):
-  def __init__(self, model, trace_data):
-    # Needs to run after all other importers so overflow events have been
-    # created on the model.
-    super(TabIdImporter, self).__init__(
-        model,
-        trace_data,
-        import_order=999)
-    self._trace_data = trace_data
-
-  @staticmethod
-  def GetSupportedPart():
-    return trace_data_module.TAB_ID_PART
-
-  def ImportEvents(self):
-    pass
-
-  def FinalizeImport(self):
-    self._CheckTraceBufferOverflow()
-    self._CreateTabIdsToThreadsMap()
-
-  def _CheckTraceBufferOverflow(self):
-    # Since _CreateTabIdsToThreadsMap() relies on markers output on timeline
-    # tracing data, it may not work in case we have trace events dropped due to
-    # trace buffer overflow.
-    for process in self._model.GetAllProcesses():
-      if process.trace_buffer_did_overflow:
-        raise TraceBufferOverflowException(
-            'Trace buffer of process with pid=%d overflowed at timestamp %d. '
-            'Raw trace data:\n%s' %
-            (process.pid, process.trace_buffer_overflow_event.start,
-             repr(self._trace_data)))
-
-  def _CreateTabIdsToThreadsMap(self):
-    tab_id_events = []
-    for tab_ids in self._trace_data.GetTracesFor(trace_data_module.TAB_ID_PART):
-      tab_id_events.extend(tab_ids)
-
-    for tab_id in tab_id_events:
-      try:
-        timeline_markers = self._model.FindTimelineMarkers(tab_id)
-      # If timeline_markers with name equals |tab_id| can't be found, it's
-      # non-fatal.
-      except Exception:
-        logging.warning('Cannot find timeline marker for tab with id=%s' %
-                        tab_id)
-        continue
-      assert len(timeline_markers) == 1
-      assert timeline_markers[0].start_thread == timeline_markers[0].end_thread
-      self._model.AddMappingFromTabIdToRendererThread(
-          tab_id, timeline_markers[0].start_thread)
diff --git a/catapult/telemetry/telemetry/timeline/tab_id_importer_unittest.py b/catapult/telemetry/telemetry/timeline/tab_id_importer_unittest.py
deleted file mode 100644
index 6b706ba..0000000
--- a/catapult/telemetry/telemetry/timeline/tab_id_importer_unittest.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import model as timeline_model
-from telemetry.timeline import tab_id_importer
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TabIdImporterUnitTest(unittest.TestCase):
-  def testImportOverflowedTrace(self):
-    builder = trace_data_module.TraceDataBuilder()
-    builder.AddTraceFor(trace_data_module.CHROME_TRACE_PART, {'traceEvents': [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 7, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 8, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'b', 'args': {}, 'pid': 2, 'ts': 9, 'cat': 'foo',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 2, 'ts': 10, 'cat': 'foo',
-       'tid': 2, 'ph': 'E'},
-      {'name': 'trace_buffer_overflowed',
-       'args': {'overflowed_at_ts': 12},
-        'pid': 2, 'ts': 0, 'tid': 2, 'ph': 'M'}
-    ]})
-    builder.AddTraceFor(
-        trace_data_module.TAB_ID_PART, ['tab-id-1', 'tab-id-2'])
-
-    with self.assertRaises(tab_id_importer.TraceBufferOverflowException) \
-        as context:
-      timeline_model.TimelineModel(builder.AsData())
-    self.assertTrue(
-        'Trace buffer of process with pid=2 overflowed at timestamp 12' in
-        context.exception.message)
-
-  def testTraceEventsWithTabIdsMarkers(self):
-    builder = trace_data_module.TraceDataBuilder()
-    builder.AddTraceFor(trace_data_module.CHROME_TRACE_PART, {'traceEvents': [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 20, 'tts': 10, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      # tab-id-1
-      {'name': 'tab-id-1', 'args': {}, 'pid': 1, 'ts': 25, 'cat': 'foo',
-       'tid': 1,
-         'ph': 'S', 'id': 72},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 30, 'tts': 20, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'tab-id-1', 'args': {}, 'pid': 1, 'ts': 35, 'cat': 'foo',
-       'tid': 1,
-         'ph': 'F', 'id': 72},
-      # tab-id-2
-      {'name': 'tab-id-2', 'args': {}, 'pid': 1, 'ts': 25, 'cat': 'foo',
-       'tid': 2,
-         'ph': 'S', 'id': 72},
-      {'name': 'tab-id-2', 'args': {}, 'pid': 1, 'ts': 26, 'cat': 'foo',
-       'tid': 2,
-         'ph': 'F', 'id': 72},
-     ]})
-    builder.AddTraceFor(
-        trace_data_module.TAB_ID_PART, ['tab-id-1', 'tab-id-2'])
-
-    m = timeline_model.TimelineModel(builder.AsData())
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    self.assertIs(processes[0], m.GetRendererProcessFromTabId('tab-id-1'))
-    self.assertIs(processes[0], m.GetRendererProcessFromTabId('tab-id-2'))
-
-    p = processes[0]
-    self.assertEqual(2, len(p.threads))
-    self.assertIs(p.threads[1], m.GetRendererThreadFromTabId('tab-id-1'))
-    self.assertIs(p.threads[2], m.GetRendererThreadFromTabId('tab-id-2'))
diff --git a/catapult/telemetry/telemetry/timeline/thread.py b/catapult/telemetry/telemetry/timeline/thread.py
deleted file mode 100644
index 5810ae3..0000000
--- a/catapult/telemetry/telemetry/timeline/thread.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import telemetry.timeline.async_slice as async_slice_module
-import telemetry.timeline.event_container as event_container
-import telemetry.timeline.flow_event as flow_event_module
-import telemetry.timeline.sample as sample_module
-import telemetry.timeline.slice as slice_module
-
-
-class Thread(event_container.TimelineEventContainer):
-  """A Thread stores all the trace events collected for a particular
-  thread. We organize the synchronous slices on a thread by "subrows," where
-  subrow 0 has all the root slices, subrow 1 those nested 1 deep, and so on.
-  The asynchronous slices are stored in an AsyncSliceGroup object.
-  """
-  def __init__(self, process, tid):
-    super(Thread, self).__init__('thread %s' % tid, parent=process)
-    self.tid = tid
-    self._async_slices = []
-    self._flow_events = []
-    self._samples = []
-    self._toplevel_slices = []
-    self._all_slices = []
-
-    # State only valid during import.
-    self._open_slices = []
-    self._newly_added_slices = []
-
-  @property
-  def toplevel_slices(self):
-    return self._toplevel_slices
-
-  @property
-  def all_slices(self):
-    return self._all_slices
-
-  @property
-  def samples(self):
-    return self._samples
-
-  @property
-  def async_slices(self):
-    return self._async_slices
-
-  @property
-  def open_slice_count(self):
-    return len(self._open_slices)
-
-  def IterChildContainers(self):
-    return
-    yield # pylint: disable=unreachable
-
-  def IterEventsInThisContainer(self, event_type_predicate, event_predicate):
-    if event_type_predicate(slice_module.Slice):
-      for s in self._newly_added_slices:
-        if event_predicate(s):
-          yield s
-      for s in self._all_slices:
-        if event_predicate(s):
-          yield s
-
-    if event_type_predicate(async_slice_module.AsyncSlice):
-      for async_slice in self._async_slices:
-        if event_predicate(async_slice):
-          yield async_slice
-        for sub_slice in async_slice.IterEventsInThisContainerRecrusively():
-          if event_predicate(sub_slice):
-            yield sub_slice
-
-    if event_type_predicate(flow_event_module.FlowEvent):
-      for flow_event in self._flow_events:
-        if event_predicate(flow_event):
-          yield flow_event
-
-    if event_type_predicate(sample_module.Sample):
-      for sample in self._samples:
-        if event_predicate(sample):
-          yield sample
-
-  def AddSample(self, category, name, timestamp, args=None):
-    if len(self._samples) and timestamp < self._samples[-1].start:
-      raise ValueError(
-          'Samples must be added in increasing timestamp order')
-    sample = sample_module.Sample(self,
-        category, name, timestamp, args=args)
-    self._samples.append(sample)
-
-  def AddAsyncSlice(self, async_slice):
-    self._async_slices.append(async_slice)
-
-  def AddFlowEvent(self, flow_event):
-    self._flow_events.append(flow_event)
-
-  def BeginSlice(self, category, name, timestamp, thread_timestamp=None,
-                 args=None):
-    """Opens a new slice for the thread.
-    Calls to beginSlice and endSlice must be made with
-    non-monotonically-decreasing timestamps.
-
-    * category: Category to which the slice belongs.
-    * name: Name of the slice to add.
-    * timestamp: The timetsamp of the slice, in milliseconds.
-    * thread_timestamp: Thread specific clock (scheduled) timestamp of the
-                        slice, in milliseconds.
-    * args: Arguments associated with
-
-    Returns newly opened slice
-    """
-    if len(self._open_slices) > 0 and timestamp < self._open_slices[-1].start:
-      raise ValueError(
-          'Slices must be added in increasing timestamp order')
-    new_slice = slice_module.Slice(self, category, name, timestamp,
-                                    thread_timestamp=thread_timestamp,
-                                    args=args)
-    self._open_slices.append(new_slice)
-    new_slice.did_not_finish = True
-    self.PushSlice(new_slice)
-    return new_slice
-
-  def EndSlice(self, end_timestamp, end_thread_timestamp=None):
-    """ Ends the last begun slice in this group and pushes it onto the slice
-    array.
-
-    * end_timestamp: Timestamp when the slice ended in milliseconds
-    * end_thread_timestamp: Timestamp when the scheduled time of the slice ended
-                            in milliseconds
-
-    returns completed slice.
-    """
-    if not len(self._open_slices):
-      raise ValueError(
-          'EndSlice called without an open slice')
-    curr_slice = self._open_slices.pop()
-    if end_timestamp < curr_slice.start:
-      raise ValueError(
-          'Slice %s end time is before its start.' % curr_slice.name)
-    curr_slice.duration = end_timestamp - curr_slice.start
-    # On Windows, it is possible to have a value for |end_thread_timestamp|
-    # but not for |curr_slice.thread_start|, because it takes some time to
-    # initialize the thread time timer.
-    if curr_slice.thread_start != None and end_thread_timestamp != None:
-      curr_slice.thread_duration = (end_thread_timestamp -
-                                    curr_slice.thread_start)
-    curr_slice.did_not_finish = False
-    return curr_slice
-
-  def PushCompleteSlice(self, category, name, timestamp, duration,
-                        thread_timestamp, thread_duration, args=None):
-    new_slice = slice_module.Slice(self, category, name, timestamp,
-                                   thread_timestamp=thread_timestamp,
-                                   args=args)
-    if duration == None:
-      new_slice.did_not_finish = True
-    else:
-      new_slice.duration = duration
-      new_slice.thread_duration = thread_duration
-    self.PushSlice(new_slice)
-    return new_slice
-
-  def PushMarkSlice(self, category, name, timestamp, thread_timestamp,
-        args=None):
-    new_slice = slice_module.Slice(self, category, name, timestamp,
-                                   thread_timestamp=thread_timestamp,
-                                   args=args)
-    self.PushSlice(new_slice)
-    return new_slice
-
-  def PushSlice(self, new_slice):
-    self._newly_added_slices.append(new_slice)
-    return new_slice
-
-  def AutoCloseOpenSlices(self, max_timestamp, max_thread_timestamp):
-    for s in self._newly_added_slices:
-      if s.did_not_finish:
-        s.duration = max_timestamp - s.start
-        assert s.duration >= 0
-        if s.thread_start != None:
-          s.thread_duration = max_thread_timestamp - s.thread_start
-          assert s.thread_duration >= 0
-    self._open_slices = []
-
-  def IsTimestampValidForBeginOrEnd(self, timestamp):
-    if not len(self._open_slices):
-      return True
-    return timestamp >= self._open_slices[-1].start
-
-  def FinalizeImport(self):
-    self._BuildSliceSubRows()
-
-  def _BuildSliceSubRows(self):
-    """This function works by walking through slices by start time.
-
-     The basic idea here is to insert each slice as deep into the subrow
-     list as it can go such that every subslice is fully contained by its
-     parent slice.
-
-     Visually, if we start with this:
-      0:  [    a       ]
-      1:    [  b  ]
-      2:    [c][d]
-
-     To place this slice:
-                   [e]
-     We first check row 2's last item, [d]. [e] wont fit into [d] (they dont
-     even intersect). So we go to row 1. That gives us [b], and [d] wont fit
-     into that either. So, we go to row 0 and its last slice, [a]. That can
-     completely contain [e], so that means we should add [e] as a subslice
-     of [a]. That puts it on row 1, yielding:
-      0:  [    a       ]
-      1:    [  b  ][e]
-      2:    [c][d]
-
-     If we then get this slice:
-                          [f]
-     We do the same deepest-to-shallowest walk of the subrows trying to fit
-     it. This time, it doesn't fit in any open slice. So, we simply append
-     it to row 0 (a root slice):
-      0:  [    a       ]  [f]
-      1:    [  b  ][e]
-    """
-    def CompareSlices(s1, s2):
-      if s1.start == s2.start:
-        # Break ties by having the slice with the greatest
-        # end timestamp come first.
-        return cmp(s2.end, s1.end)
-      return cmp(s1.start, s2.start)
-
-    assert len(self._toplevel_slices) == 0
-    assert len(self._all_slices) == 0
-    if not len(self._newly_added_slices):
-      return
-
-    self._all_slices.extend(self._newly_added_slices)
-
-    sorted_slices = sorted(self._newly_added_slices, cmp=CompareSlices)
-    root_slice = sorted_slices[0]
-    self._toplevel_slices.append(root_slice)
-    for s in sorted_slices[1:]:
-      if not self._AddSliceIfBounds(root_slice, s):
-        root_slice = s
-        self._toplevel_slices.append(root_slice)
-    self._newly_added_slices = []
-
-
-  def _AddSliceIfBounds(self, root, child):
-    """Adds a child slice to a root slice its proper row.
-    Return False if the child slice is not in the bounds
-    of the root slice.
-
-    Because we know that the start time of child is >= the start time
-    of all other slices seen so far, we can just check the last slice
-    of each row for bounding.
-    """
-    # The source trace data is in microseconds but we store it as milliseconds
-    # in floating-point. Since we can't represent micros as millis perfectly,
-    # two end=start+duration combos that should be the same will be slightly
-    # different. Round back to micros to ensure equality below.
-    child_end_micros = round(child.end * 1000)
-    root_end_micros = round(root.end * 1000)
-    if child.start >= root.start and child_end_micros <= root_end_micros:
-      if len(root.sub_slices) > 0:
-        if self._AddSliceIfBounds(root.sub_slices[-1], child):
-          return True
-      child.parent_slice = root
-      root.AddSubSlice(child)
-      return True
-    return False
diff --git a/catapult/telemetry/telemetry/timeline/thread_unittest.py b/catapult/telemetry/telemetry/timeline/thread_unittest.py
deleted file mode 100644
index 081a100..0000000
--- a/catapult/telemetry/telemetry/timeline/thread_unittest.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.timeline import model as model_module
-
-
-class ThreadUnittest(unittest.TestCase):
-
-  def testIterAllSlicesInRange(self):
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    #    [       X     ] [   Y    ] [   U   ]
-    #        [   Z   ]     [ T ]
-    #      |                           |
-    #    start                        end
-    renderer_main.BeginSlice('cat1', 'X', 10)
-    renderer_main.BeginSlice('cat1', 'Z', 20)
-    renderer_main.EndSlice(30)
-    renderer_main.EndSlice(40)
-    renderer_main.BeginSlice('cat1', 'Y', 50)
-    renderer_main.BeginSlice('cat1', 'T', 52)
-    renderer_main.EndSlice(55)
-    renderer_main.EndSlice(60)
-    renderer_main.BeginSlice('cat1', 'U', 60)
-    renderer_main.EndSlice(70)
-
-    model.FinalizeImport(shift_world_to_zero=False)
-    slice_names = set(s.name for s in
-                      renderer_main.IterAllSlicesInRange(start=12, end=65))
-    self.assertEqual(slice_names, {'Z', 'Y', 'T'})
diff --git a/catapult/telemetry/telemetry/timeline/trace_data.py b/catapult/telemetry/telemetry/timeline/trace_data.py
deleted file mode 100644
index e6dcf5e..0000000
--- a/catapult/telemetry/telemetry/timeline/trace_data.py
+++ /dev/null
@@ -1,335 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import copy
-import json
-import logging
-import os
-import shutil
-import subprocess
-import tempfile
-
-from telemetry.core import util
-
-
-_TRACE2HTML_PATH = os.path.join(
-    util.GetCatapultDir(), 'tracing', 'bin', 'trace2html')
-
-
-class NonSerializableTraceData(Exception):
-  """Raised when raw trace data cannot be serialized to TraceData."""
-  pass
-
-
-class TraceDataPart(object):
-  """TraceData can have a variety of events.
-
-  These are called "parts" and are accessed by the following fixed field names.
-  """
-  def __init__(self, raw_field_name):
-    self._raw_field_name = raw_field_name
-
-  def __repr__(self):
-    return 'TraceDataPart("%s")' % self._raw_field_name
-
-  @property
-  def raw_field_name(self):
-    return self._raw_field_name
-
-  def __eq__(self, other):
-    return self.raw_field_name == other.raw_field_name
-
-  def __hash__(self):
-    return hash(self.raw_field_name)
-
-
-ATRACE_PART = TraceDataPart('systemTraceEvents')
-BATTOR_TRACE_PART = TraceDataPart('powerTraceAsString')
-CHROME_TRACE_PART = TraceDataPart('traceEvents')
-CPU_TRACE_DATA = TraceDataPart('cpuSnapshots')
-INSPECTOR_TRACE_PART = TraceDataPart('inspectorTimelineEvents')
-SURFACE_FLINGER_PART = TraceDataPart('surfaceFlinger')
-TAB_ID_PART = TraceDataPart('tabIds')
-TELEMETRY_PART = TraceDataPart('telemetry')
-
-ALL_TRACE_PARTS = {ATRACE_PART,
-                   BATTOR_TRACE_PART,
-                   CHROME_TRACE_PART,
-                   CPU_TRACE_DATA,
-                   INSPECTOR_TRACE_PART,
-                   SURFACE_FLINGER_PART,
-                   TAB_ID_PART,
-                   TELEMETRY_PART}
-
-ALL_TRACE_PARTS_RAW_NAMES = set(k.raw_field_name for k in ALL_TRACE_PARTS)
-
-def _HasTraceFor(part, raw):
-  assert isinstance(part, TraceDataPart)
-  if part.raw_field_name not in raw:
-    return False
-  return len(raw[part.raw_field_name]) > 0
-
-
-def _GetFilePathForTrace(trace, dir_path):
-  """ Return path to a file that contains |trace|.
-
-  Note: if |trace| is an instance of TraceFileHandle, this reuses the trace path
-  that the trace file handle holds. Otherwise, it creates a new trace file
-  in |dir_path| directory.
-  """
-  if isinstance(trace, TraceFileHandle):
-    return trace.file_path
-  with tempfile.NamedTemporaryFile(mode='w', dir=dir_path, delete=False) as fp:
-    if isinstance(trace, basestring):
-      fp.write(trace)
-    elif isinstance(trace, dict) or isinstance(trace, list):
-      json.dump(trace, fp)
-    else:
-      raise TypeError('Trace is of unknown type.')
-    return fp.name
-
-
-class TraceData(object):
-  """ TraceData holds a collection of traces from multiple sources.
-
-  A TraceData can have multiple active parts. Each part represents traces
-  collected from a different trace agent.
-  """
-  def __init__(self):
-    """Creates TraceData from the given data."""
-    self._raw_data = {}
-    self._events_are_safely_mutable = False
-
-  def _SetFromBuilder(self, d):
-    self._raw_data = d
-    self._events_are_safely_mutable = True
-
-  @property
-  def events_are_safely_mutable(self):
-    """Returns true if the events in this value are completely sealed.
-
-    Some importers want to take complex fields out of the TraceData and add
-    them to the model, changing them subtly as they do so. If the TraceData
-    was constructed with data that is shared with something outside the trace
-    data, for instance a test harness, then this mutation is unexpected. But,
-    if the values are sealed, then mutating the events is a lot faster.
-
-    We know if events are sealed if the value came from a string, or if the
-    value came from a TraceDataBuilder.
-    """
-    return self._events_are_safely_mutable
-
-  @property
-  def active_parts(self):
-    return {p for p in ALL_TRACE_PARTS if p.raw_field_name in self._raw_data}
-
-  def HasTracesFor(self, part):
-    return _HasTraceFor(part, self._raw_data)
-
-  def GetTracesFor(self, part):
-    """ Return the list of traces for |part| in string or dictionary forms.
-
-    Note: since this API return the traces that can be directly accessed in
-    memory, it may require lots of memory usage as some of the trace can be
-    very big.
-    For references, we have cases where Telemetry is OOM'ed because the memory
-    required for processing the trace in Python is too big (crbug.com/672097).
-    """
-    assert isinstance(part, TraceDataPart)
-    if not self.HasTracesFor(part):
-      return []
-    traces_list = self._raw_data[part.raw_field_name]
-    # Since this API return the traces in memory form, and since the memory
-    # bottleneck of Telemetry is for keeping trace in memory, there is no uses
-    # in keeping the on-disk form of tracing beyond this point. Hence we convert
-    # all traces for part of form TraceFileHandle to the JSON form.
-    for i, data in enumerate(traces_list):
-      if isinstance(data, TraceFileHandle):
-        traces_list[i] = data.AsTraceData()
-    return traces_list
-
-  def GetTraceFor(self, part):
-    assert isinstance(part, TraceDataPart)
-    traces = self.GetTracesFor(part)
-    assert len(traces) == 1
-    return traces[0]
-
-  def CleanUpAllTraces(self):
-    """ Remove all the traces that this has handles to.
-
-    Those include traces stored in memory & on disk. After invoking this,
-    one can no longer uses this object for collecting the traces.
-    """
-    for traces_list in self._raw_data.itervalues():
-      for trace in traces_list:
-        if isinstance(trace, TraceFileHandle):
-          trace.Clean()
-    self._raw_data = {}
-
-  def Serialize(self, file_path, trace_title=''):
-    """Serializes the trace result to |file_path|.
-
-    """
-    if not self._raw_data:
-      logging.warning('No traces to convert to html.')
-      return
-    temp_dir = tempfile.mkdtemp()
-    trace_files = []
-    try:
-      trace_size_data = {}
-      for part, traces_list in self._raw_data.iteritems():
-        for trace in traces_list:
-          path = _GetFilePathForTrace(trace, temp_dir)
-          trace_size_data.setdefault(part, 0)
-          trace_size_data[part] += os.path.getsize(path)
-          trace_files.append(path)
-      logging.info('Trace sizes in bytes: %s', trace_size_data)
-
-      cmd = (['python', _TRACE2HTML_PATH] + trace_files +
-          ['--output', file_path] + ['--title', trace_title])
-      subprocess.check_output(cmd)
-    finally:
-      shutil.rmtree(temp_dir)
-
-
-class TraceFileHandle(object):
-  """A trace file handle object allows storing trace data on disk.
-
-  TraceFileHandle API allows one to collect traces from Chrome into disk instead
-  of keeping them in memory. This is important for keeping memory usage of
-  Telemetry low to avoid OOM (see:
-  https://github.com/catapult-project/catapult/issues/3119).
-
-  The fact that this uses a file underneath to store tracing data means the
-  callsite is repsonsible for discarding the file when they no longer need the
-  tracing data. Call TraceFileHandle.Clean when you done using this object.
-  """
-  def __init__(self):
-    self._backing_file = None
-    self._file_path = None
-    self._trace_data = None
-
-  def Open(self):
-    assert not self._backing_file and not self._file_path
-    self._backing_file = tempfile.NamedTemporaryFile(delete=False, mode='a')
-
-  def AppendTraceData(self, partial_trace_data):
-    assert isinstance(partial_trace_data, basestring)
-    self._backing_file.write(partial_trace_data)
-
-  @property
-  def file_path(self):
-    assert self._file_path, (
-        'Either the handle need to be closed first or this handle is cleaned')
-    return self._file_path
-
-  def Close(self):
-    assert self._backing_file
-    self._backing_file.close()
-    self._file_path = self._backing_file.name
-    self._backing_file = None
-
-  def AsTraceData(self):
-    """Get the object form of trace data that this handle manages.
-
-    *Warning: this can have large memory footprint if the trace data is big.
-
-    Since this requires the in-memory form of the trace, it is no longer useful
-    to still keep the backing file underneath, invoking this will also discard
-    the file to avoid the risk of leaking the backing trace file.
-    """
-    if self._trace_data:
-      return self._trace_data
-    assert self._file_path
-    with open(self._file_path) as f:
-      self._trace_data = json.load(f)
-    self.Clean()
-    return self._trace_data
-
-  def Clean(self):
-    """Remove the backing file used for storing trace on disk.
-
-    This should be called when and only when you no longer need to use
-    TraceFileHandle.
-    """
-    assert self._file_path
-    os.remove(self._file_path)
-    self._file_path = None
-
-
-class TraceDataBuilder(object):
-  """TraceDataBuilder helps build up a trace from multiple trace agents.
-
-  TraceData is supposed to be immutable, but it is useful during recording to
-  have a mutable version. That is TraceDataBuilder.
-  """
-  def __init__(self):
-    self._raw_data = {}
-
-  def AsData(self):
-    if self._raw_data == None:
-      raise Exception('Can only AsData once')
-    data = TraceData()
-    data._SetFromBuilder(self._raw_data)
-    self._raw_data = None
-    return data
-
-  def AddTraceFor(self, part, trace):
-    assert isinstance(part, TraceDataPart)
-    if part == CHROME_TRACE_PART:
-      assert (isinstance(trace, dict) or
-              isinstance(trace, TraceFileHandle))
-    else:
-      assert (isinstance(trace, basestring) or
-              isinstance(trace, dict) or
-              isinstance(trace, list))
-
-    if self._raw_data == None:
-      raise Exception('Already called AsData() on this builder.')
-
-    self._raw_data.setdefault(part.raw_field_name, [])
-    self._raw_data[part.raw_field_name].append(trace)
-
-  def HasTracesFor(self, part):
-    return _HasTraceFor(part, self._raw_data)
-
-
-def CreateTraceDataFromRawData(raw_data):
-  """Convenient method for creating a TraceData object from |raw_data|.
-     This is mostly used for testing.
-
-     Args:
-        raw_data can be:
-            + A dictionary that repsents multiple trace parts. Keys of the
-            dictionary must always contain 'traceEvents', as chrome trace
-            must always present.
-            + A list that represents Chrome trace events.
-            + JSON string of either above.
-
-  """
-  raw_data = copy.deepcopy(raw_data)
-  if isinstance(raw_data, basestring):
-    json_data = json.loads(raw_data)
-  else:
-    json_data = raw_data
-
-  b = TraceDataBuilder()
-  if not json_data:
-    return b.AsData()
-  if isinstance(json_data, dict):
-    assert 'traceEvents' in json_data, 'Only raw chrome trace is supported'
-    trace_parts_keys = []
-    for k in json_data:
-      if k != 'traceEvents' and k in ALL_TRACE_PARTS_RAW_NAMES:
-        trace_parts_keys.append(k)
-        b.AddTraceFor(TraceDataPart(k), json_data[k])
-    # Delete the data for extra keys to form trace data for Chrome part only.
-    for k in trace_parts_keys:
-      del json_data[k]
-    b.AddTraceFor(CHROME_TRACE_PART, json_data)
-  elif isinstance(json_data, list):
-    b.AddTraceFor(CHROME_TRACE_PART, {'traceEvents': json_data})
-  else:
-    raise NonSerializableTraceData('Unrecognized data format.')
-  return b.AsData()
diff --git a/catapult/telemetry/telemetry/timeline/trace_data_unittest.py b/catapult/telemetry/telemetry/timeline/trace_data_unittest.py
deleted file mode 100644
index 9ecf668..0000000
--- a/catapult/telemetry/telemetry/timeline/trace_data_unittest.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import datetime
-import exceptions
-import os
-import shutil
-import tempfile
-import unittest
-
-from tracing_build import html2trace
-from telemetry.timeline import trace_data
-
-
-class TraceDataTest(unittest.TestCase):
-  def testSerialize(self):
-    test_dir = tempfile.mkdtemp()
-    trace_path = os.path.join(test_dir, 'test_trace.json')
-    try:
-      ri = trace_data.CreateTraceDataFromRawData({'traceEvents': [1, 2, 3]})
-      ri.Serialize(trace_path)
-      with open(trace_path) as f:
-        json_traces = html2trace.ReadTracesFromHTMLFilePath(f)
-      self.assertEqual(json_traces, [{'traceEvents': [1, 2, 3]}])
-    finally:
-      shutil.rmtree(test_dir)
-
-  def testEmptyArrayValue(self):
-    # We can import empty lists and empty string.
-    d = trace_data.CreateTraceDataFromRawData([])
-    self.assertFalse(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
-
-  def testInvalidTrace(self):
-    with self.assertRaises(AssertionError):
-      trace_data.CreateTraceDataFromRawData({'hello': 1})
-
-  def testListForm(self):
-    d = trace_data.CreateTraceDataFromRawData([{'ph': 'B'}])
-    self.assertTrue(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
-    events = d.GetTracesFor(trace_data.CHROME_TRACE_PART)[0].get(
-        'traceEvents', [])
-    self.assertEquals(1, len(events))
-
-  def testStringForm(self):
-    d = trace_data.CreateTraceDataFromRawData('[{"ph": "B"}]')
-    self.assertTrue(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
-    events = d.GetTracesFor(trace_data.CHROME_TRACE_PART)[0].get(
-        'traceEvents', [])
-    self.assertEquals(1, len(events))
-
-
-class TraceDataBuilderTest(unittest.TestCase):
-  def testBasicChrome(self):
-    builder = trace_data.TraceDataBuilder()
-    builder.AddTraceFor(trace_data.CHROME_TRACE_PART,
-                        {'traceEvents': [1, 2, 3]})
-    builder.AddTraceFor(trace_data.TAB_ID_PART, ['tab-7'])
-    builder.AddTraceFor(trace_data.BATTOR_TRACE_PART, 'battor data here')
-
-    d = builder.AsData()
-    self.assertTrue(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
-    self.assertTrue(d.HasTracesFor(trace_data.TAB_ID_PART))
-    self.assertTrue(d.HasTracesFor(trace_data.BATTOR_TRACE_PART))
-
-    self.assertRaises(Exception, builder.AsData)
-
-  def testSetTraceFor(self):
-    telemetry_trace = {
-        'traceEvents': [1, 2, 3],
-        'metadata': {
-          'field1': 'value1'
-        }
-    }
-
-    builder = trace_data.TraceDataBuilder()
-    builder.AddTraceFor(trace_data.TELEMETRY_PART, telemetry_trace)
-    d = builder.AsData()
-
-    self.assertEqual(d.GetTracesFor(trace_data.TELEMETRY_PART),
-                     [telemetry_trace])
-
-  def testSetTraceForRaisesWithInvalidPart(self):
-    builder = trace_data.TraceDataBuilder()
-
-    self.assertRaises(exceptions.AssertionError,
-                      lambda: builder.AddTraceFor('not_a_trace_part', {}))
-
-  def testSetTraceForRaisesWithInvalidTrace(self):
-    builder = trace_data.TraceDataBuilder()
-
-    self.assertRaises(exceptions.AssertionError, lambda:
-        builder.AddTraceFor(trace_data.TELEMETRY_PART, datetime.time.min))
-
-  def testSetTraceForRaisesAfterAsData(self):
-    builder = trace_data.TraceDataBuilder()
-    builder.AsData()
-
-    self.assertRaises(exceptions.Exception,
-        lambda: builder.AddTraceFor(trace_data.TELEMETRY_PART, {}))
diff --git a/catapult/telemetry/telemetry/timeline/trace_event_importer.py b/catapult/telemetry/telemetry/timeline/trace_event_importer.py
deleted file mode 100644
index b1f48ad..0000000
--- a/catapult/telemetry/telemetry/timeline/trace_event_importer.py
+++ /dev/null
@@ -1,466 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""TraceEventImporter imports TraceEvent-formatted data
-into the provided model.
-This is a port of the trace event importer from
-https://code.google.com/p/trace-viewer/
-"""
-
-import collections
-import copy
-
-import telemetry.timeline.async_slice as tracing_async_slice
-import telemetry.timeline.flow_event as tracing_flow_event
-from telemetry.timeline import importer
-from telemetry.timeline import memory_dump_event
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TraceEventTimelineImporter(importer.TimelineImporter):
-  def __init__(self, model, trace_data):
-    super(TraceEventTimelineImporter, self).__init__(
-        model, trace_data, import_order=1)
-    assert isinstance(trace_data, trace_data_module.TraceData)
-    self._trace_data = trace_data
-
-    self._all_async_events = []
-    self._all_object_events = []
-    self._all_flow_events = []
-    self._all_memory_dumps_by_dump_id = collections.defaultdict(list)
-
-    self._events = []
-    self._metadata = []
-    for trace in trace_data.GetTracesFor(trace_data_module.CHROME_TRACE_PART):
-      self._events.extend(trace['traceEvents'])
-      self.CollectMetadataRecords(trace)
-
-  def CollectMetadataRecords(self, trace):
-    part_field_names = {p.raw_field_name for p in
-                        trace_data_module.ALL_TRACE_PARTS}
-    for k, v in trace.iteritems():
-      if k in part_field_names:
-        continue
-      self._metadata.append({'name': k, 'value': v})
-
-
-  @staticmethod
-  def GetSupportedPart():
-    return trace_data_module.CHROME_TRACE_PART
-
-  def _GetOrCreateProcess(self, pid):
-    return self._model.GetOrCreateProcess(pid)
-
-  def _DeepCopyIfNeeded(self, obj):
-    if self._trace_data.events_are_safely_mutable:
-      return obj
-    return copy.deepcopy(obj)
-
-  def _ProcessAsyncEvent(self, event):
-    """Helper to process an 'async finish' event, which will close an
-    open slice.
-    """
-    thread = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateThread(event['tid']))
-    self._all_async_events.append({
-        'event': event,
-        'thread': thread})
-
-  def _ProcessCounterEvent(self, event):
-    """Helper that creates and adds samples to a Counter object based on
-    'C' phase events.
-    """
-    if 'id' in event:
-      ctr_name = event['name'] + '[' + str(event['id']) + ']'
-    else:
-      ctr_name = event['name']
-
-    ctr = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateCounter(event['cat'], ctr_name))
-    # Initialize the counter's series fields if needed.
-    if len(ctr.series_names) == 0:
-      #TODO: implement counter object
-      for series_name in event['args']:
-        ctr.series_names.append(series_name)
-      if len(ctr.series_names) == 0:
-        self._model.import_errors.append('Expected counter ' + event['name'] +
-            ' to have at least one argument to use as a value.')
-        # Drop the counter.
-        del ctr.parent.counters[ctr.full_name]
-        return
-
-    # Add the sample values.
-    ctr.timestamps.append(event['ts'] / 1000.0)
-    for series_name in ctr.series_names:
-      if series_name not in event['args']:
-        ctr.samples.append(0)
-        continue
-      ctr.samples.append(event['args'][series_name])
-
-  def _ProcessObjectEvent(self, event):
-    thread = (self._GetOrCreateProcess(event['pid'])
-      .GetOrCreateThread(event['tid']))
-    self._all_object_events.append({
-        'event': event,
-        'thread': thread})
-
-  def _ProcessDurationEvent(self, event):
-    thread = (self._GetOrCreateProcess(event['pid'])
-      .GetOrCreateThread(event['tid']))
-    if not thread.IsTimestampValidForBeginOrEnd(event['ts'] / 1000.0):
-      self._model.import_errors.append(
-          'Timestamps are moving backward.')
-      return
-
-    if event['ph'] == 'B':
-      thread.BeginSlice(event['cat'],
-                        event['name'],
-                        event['ts'] / 1000.0,
-                        event['tts'] / 1000.0 if 'tts' in event else None,
-                        event['args'])
-    elif event['ph'] == 'E':
-      thread = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateThread(event['tid']))
-      if not thread.IsTimestampValidForBeginOrEnd(event['ts'] / 1000.0):
-        self._model.import_errors.append(
-            'Timestamps are moving backward.')
-        return
-      if not thread.open_slice_count:
-        self._model.import_errors.append(
-            'E phase event without a matching B phase event.')
-        return
-
-      new_slice = thread.EndSlice(
-          event['ts'] / 1000.0,
-          event['tts'] / 1000.0 if 'tts' in event else None)
-      for arg_name, arg_value in event.get('args', {}).iteritems():
-        if arg_name in new_slice.args:
-          self._model.import_errors.append(
-              'Both the B and E phases of ' + new_slice.name +
-              ' provided values for argument ' + arg_name + '. ' +
-              'The value of the E phase event will be used.')
-        new_slice.args[arg_name] = arg_value
-
-  def _ProcessCompleteEvent(self, event):
-    thread = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateThread(event['tid']))
-    thread.PushCompleteSlice(
-        event['cat'],
-        event['name'],
-        event['ts'] / 1000.0,
-        event['dur'] / 1000.0 if 'dur' in event else None,
-        event['tts'] / 1000.0 if 'tts' in event else None,
-        event['tdur'] / 1000.0 if 'tdur' in event else None,
-        event['args'])
-
-  def _ProcessMarkEvent(self, event):
-    thread = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateThread(event['tid']))
-    thread.PushMarkSlice(
-        event['cat'],
-        event['name'],
-        event['ts'] / 1000.0,
-        event['tts'] / 1000.0 if 'tts' in event else None,
-        event['args'] if 'args' in event else None)
-
-  def _ProcessMetadataEvent(self, event):
-    if event['name'] == 'thread_name':
-      thread = (self._GetOrCreateProcess(event['pid'])
-          .GetOrCreateThread(event['tid']))
-      thread.name = event['args']['name']
-    elif event['name'] == 'process_name':
-      process = self._GetOrCreateProcess(event['pid'])
-      process.name = event['args']['name']
-    elif event['name'] == 'process_labels':
-      process = self._GetOrCreateProcess(event['pid'])
-      process.labels = event['args']['labels']
-    elif event['name'] == 'process_uptime_seconds':
-      process = self._GetOrCreateProcess(event['pid'])
-      process.uptime_seconds = event['args']['uptime']
-    elif event['name'] == 'trace_buffer_overflowed':
-      process = self._GetOrCreateProcess(event['pid'])
-      process.SetTraceBufferOverflowTimestamp(event['args']['overflowed_at_ts'])
-    else:
-      self._model.import_errors.append(
-          'Unrecognized metadata name: ' + event['name'])
-
-  def _ProcessInstantEvent(self, event):
-    # Treat an Instant event as a duration 0 slice.
-    # SliceTrack's redraw() knows how to handle this.
-    thread = (self._GetOrCreateProcess(event['pid'])
-      .GetOrCreateThread(event['tid']))
-    thread.BeginSlice(event['cat'],
-                      event['name'],
-                      event['ts'] / 1000.0,
-                      args=event.get('args'))
-    thread.EndSlice(event['ts'] / 1000.0)
-
-  def _ProcessSampleEvent(self, event):
-    thread = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateThread(event['tid']))
-    thread.AddSample(event['cat'],
-                     event['name'],
-                     event['ts'] / 1000.0,
-                     event.get('args'))
-
-  def _ProcessFlowEvent(self, event):
-    thread = (self._GetOrCreateProcess(event['pid'])
-        .GetOrCreateThread(event['tid']))
-    self._all_flow_events.append({
-        'event': event,
-        'thread': thread})
-
-  def _ProcessMemoryDumpEvents(self, events):
-    # Dictionary to order dumps by id and process.
-    global_dumps = {}
-    for event in events:
-      global_dump = global_dumps.setdefault(event['id'], {})
-      dump_events = global_dump.setdefault(event['pid'], [])
-      dump_events.append(event)
-    for dump_id, global_dump in global_dumps.iteritems():
-      for pid, dump_events in global_dump.iteritems():
-        process = self._GetOrCreateProcess(pid)
-        memory_dump = memory_dump_event.ProcessMemoryDumpEvent(process,
-                                                               dump_events)
-        process.AddMemoryDumpEvent(memory_dump)
-        self._all_memory_dumps_by_dump_id[dump_id].append(memory_dump)
-
-  def ImportEvents(self):
-    """Walks through the events_ list and outputs the structures discovered to
-    model_.
-    """
-    for r in self._metadata:
-      self._model.metadata.append(r)
-    memory_dump_events = []
-    for event in self._events:
-      phase = event.get('ph', None)
-      if phase == 'B' or phase == 'E':
-        self._ProcessDurationEvent(event)
-      elif phase == 'X':
-        self._ProcessCompleteEvent(event)
-      # Note, S, F, T are deprecated and replaced by 'b' and 'e'. For
-      # backwards compatibility continue to support them here.
-      elif phase == 'S' or phase == 'F' or phase == 'T':
-        self._ProcessAsyncEvent(event)
-      elif phase == 'b' or phase == 'e':
-        self._ProcessAsyncEvent(event)
-      # Note, I is historic. The instant event marker got changed, but we
-      # want to support loading old trace files so we have both I and i.
-      elif phase == 'I' or phase == 'i':
-        self._ProcessInstantEvent(event)
-      elif phase == 'P':
-        self._ProcessSampleEvent(event)
-      elif phase == 'C':
-        self._ProcessCounterEvent(event)
-      elif phase == 'M':
-        self._ProcessMetadataEvent(event)
-      elif phase == 'N' or phase == 'D' or phase == 'O':
-        self._ProcessObjectEvent(event)
-      elif phase == 's' or phase == 't' or phase == 'f':
-        self._ProcessFlowEvent(event)
-      elif phase == 'v':
-        memory_dump_events.append(event)
-      elif phase == 'R':
-        self._ProcessMarkEvent(event)
-      else:
-        self._model.import_errors.append('Unrecognized event phase: ' +
-            phase + '(' + event['name'] + ')')
-
-    # Memory dumps of a process with the same dump id need to be merged before
-    # processing. So, memory dump events are processed all at once.
-    self._ProcessMemoryDumpEvents(memory_dump_events)
-    return self._model
-
-  def FinalizeImport(self):
-    """Called by the Model after all other importers have imported their
-    events."""
-    self._model.UpdateBounds()
-
-    # We need to reupdate the bounds in case the minimum start time changes
-    self._model.UpdateBounds()
-    self._CreateAsyncSlices()
-    self._CreateFlowSlices()
-    self._SetBrowserProcess()
-    self._SetGpuProcess()
-    self._CreateExplicitObjects()
-    self._CreateImplicitObjects()
-    self._CreateMemoryDumps()
-
-  def _CreateAsyncSlices(self):
-    if len(self._all_async_events) == 0:
-      return
-
-    self._all_async_events.sort(key=lambda x: x['event']['ts'])
-
-    async_event_states_by_name_then_id = {}
-
-    all_async_events = self._all_async_events
-    for async_event_state in all_async_events:
-      event = async_event_state['event']
-      name = event.get('name', None)
-      if name is None:
-        self._model.import_errors.append(
-            'Async events (ph: b, e, S, T or F) require an name parameter.')
-        continue
-
-      event_id = event.get('id')
-      if event_id is None:
-        self._model.import_errors.append(
-            'Async events (ph: b, e, S, T or F) require an id parameter.')
-        continue
-
-      # TODO(simonjam): Add a synchronous tick on the appropriate thread.
-
-      if event['ph'] == 'S' or event['ph'] == 'b':
-        if not name in async_event_states_by_name_then_id:
-          async_event_states_by_name_then_id[name] = {}
-        if event_id in async_event_states_by_name_then_id[name]:
-          self._model.import_errors.append(
-              'At %d, a slice of the same id %s was already open.' % (
-                  event['ts'], event_id))
-          continue
-
-        async_event_states_by_name_then_id[name][event_id] = []
-        async_event_states_by_name_then_id[name][event_id].append(
-            async_event_state)
-      else:
-        if name not in async_event_states_by_name_then_id:
-          self._model.import_errors.append(
-              'At %d, no slice named %s was open.' % (event['ts'], name,))
-          continue
-        if event_id not in async_event_states_by_name_then_id[name]:
-          self._model.import_errors.append(
-              'At %d, no slice named %s with id=%s was open.' % (
-                  event['ts'], name, event_id))
-          continue
-        events = async_event_states_by_name_then_id[name][event_id]
-        events.append(async_event_state)
-
-        if event['ph'] == 'F' or event['ph'] == 'e':
-          # Create a slice from start to end.
-          async_slice = tracing_async_slice.AsyncSlice(
-              events[0]['event']['cat'],
-              name,
-              events[0]['event']['ts'] / 1000.0)
-
-          async_slice.duration = ((event['ts'] / 1000.0)
-              - (events[0]['event']['ts'] / 1000.0))
-
-          async_slice.start_thread = events[0]['thread']
-          async_slice.end_thread = async_event_state['thread']
-          if async_slice.start_thread == async_slice.end_thread:
-            if 'tts' in event and 'tts' in events[0]['event']:
-              async_slice.thread_start = events[0]['event']['tts'] / 1000.0
-              async_slice.thread_duration = ((event['tts'] / 1000.0)
-                  - (events[0]['event']['tts'] / 1000.0))
-          async_slice.id = event_id
-          async_slice.args = events[0]['event']['args']
-
-          # Create sub_slices for each step.
-          for j in xrange(1, len(events)):
-            sub_name = name
-            if events[j - 1]['event']['ph'] == 'T':
-              sub_name = name + ':' + events[j - 1]['event']['args']['step']
-            sub_slice = tracing_async_slice.AsyncSlice(
-                events[0]['event']['cat'],
-                sub_name,
-                events[j - 1]['event']['ts'] / 1000.0)
-            sub_slice.parent_slice = async_slice
-
-            sub_slice.duration = ((events[j]['event']['ts'] / 1000.0)
-                - (events[j - 1]['event']['ts'] / 1000.0))
-
-            sub_slice.start_thread = events[j - 1]['thread']
-            sub_slice.end_thread = events[j]['thread']
-            if sub_slice.start_thread == sub_slice.end_thread:
-              if 'tts' in events[j]['event'] and \
-                  'tts' in events[j - 1]['event']:
-                sub_slice.thread_duration = \
-                    ((events[j]['event']['tts'] / 1000.0)
-                        - (events[j - 1]['event']['tts'] / 1000.0))
-
-            sub_slice.id = event_id
-            sub_slice.args = events[j - 1]['event']['args']
-
-            async_slice.AddSubSlice(sub_slice)
-
-          # The args for the finish event go in the last sub_slice.
-          last_slice = async_slice.sub_slices[-1]
-          for arg_name, arg_value in event['args'].iteritems():
-            last_slice.args[arg_name] = arg_value
-
-          # Add |async_slice| to the start-thread's async_slices.
-          async_slice.start_thread.AddAsyncSlice(async_slice)
-          del async_event_states_by_name_then_id[name][event_id]
-
-  def _CreateExplicitObjects(self):
-    # TODO(tengs): Implement object instance parsing
-    pass
-
-  def _CreateImplicitObjects(self):
-    # TODO(tengs): Implement object instance parsing
-    pass
-
-  def _CreateFlowSlices(self):
-    if len(self._all_flow_events) == 0:
-      return
-
-    self._all_flow_events.sort(key=lambda x: x['event']['ts'])
-
-    flow_id_to_event = {}
-    for data in self._all_flow_events:
-      event = data['event']
-      thread = data['thread']
-      if 'name' not in event:
-        self._model.import_errors.append(
-          'Flow events (ph: s, t or f) require a name parameter.')
-        continue
-      if 'id' not in event:
-        self._model.import_errors.append(
-          'Flow events (ph: s, t or f) require an id parameter.')
-        continue
-
-      flow_event = tracing_flow_event.FlowEvent(
-          event['cat'],
-          event['id'],
-          event['name'],
-          event['ts'] / 1000.0,
-          event['args'])
-      thread.AddFlowEvent(flow_event)
-
-      if event['ph'] == 's':
-        if event['id'] in flow_id_to_event:
-          self._model.import_errors.append(
-              'event id %s already seen when encountering start of'
-              'flow event.' % event['id'])
-          continue
-        flow_id_to_event[event['id']] = flow_event
-      elif event['ph'] == 't' or event['ph'] == 'f':
-        if not event['id'] in flow_id_to_event:
-          self._model.import_errors.append(
-            'Found flow phase %s for id: %s but no flow start found.' % (
-                event['ph'], event['id']))
-          continue
-        flow_position = flow_id_to_event[event['id']]
-        self._model.flow_events.append([flow_position, flow_event])
-
-        if event['ph'] == 'f':
-          del flow_id_to_event[event['id']]
-        else:
-          # Make this event the next start event in this flow.
-          flow_id_to_event[event['id']] = flow_event
-
-  def _CreateMemoryDumps(self):
-    self._model.SetGlobalMemoryDumps(
-        memory_dump_event.GlobalMemoryDump(events)
-        for events in self._all_memory_dumps_by_dump_id.itervalues())
-
-  def _SetBrowserProcess(self):
-    for thread in self._model.GetAllThreads():
-      if thread.name == 'CrBrowserMain':
-        self._model.browser_process = thread.parent
-
-  def _SetGpuProcess(self):
-    for thread in self._model.GetAllThreads():
-      if thread.name == 'CrGpuMain':
-        self._model.gpu_process = thread.parent
diff --git a/catapult/telemetry/telemetry/timeline/trace_event_importer_unittest.py b/catapult/telemetry/telemetry/timeline/trace_event_importer_unittest.py
deleted file mode 100644
index e49d336..0000000
--- a/catapult/telemetry/telemetry/timeline/trace_event_importer_unittest.py
+++ /dev/null
@@ -1,1134 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=too-many-lines
-
-import unittest
-
-import telemetry.timeline.counter as tracing_counter
-import telemetry.timeline.model as timeline_model
-from tracing.trace_data import trace_data as trace_data_module
-
-
-def FindEventNamed(events, name):
-  for event in events:
-    if event.name == name:
-      return event
-  raise ValueError('No event found with name %s' % name)
-
-class TraceEventTimelineImporterTest(unittest.TestCase):
-
-  def testBasicSingleThreadNonnestedParsing(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 520, 'tts': 280, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 560, 'tts': 310, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'},
-      {'name': 'b', 'args': {}, 'pid': 52, 'ts': 629, 'tts': 356, 'cat': 'bar',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 52, 'ts': 631, 'tts': 357, 'cat': 'bar',
-       'tid': 53, 'ph': 'E'},
-      {'name': 'c', 'args': {}, 'pid': 52, 'ts': 633, 'cat': 'baz',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'c', 'args': {}, 'pid': 52, 'ts': 637, 'cat': 'baz',
-       'tid': 53, 'ph': 'E'}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    p = processes[0]
-    self.assertEqual(52, p.pid)
-
-    self.assertEqual(1, len(p.threads))
-    t = p.threads[53]
-    self.assertEqual(3, len(t.all_slices))
-    self.assertEqual(53, t.tid)
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertAlmostEqual(0, slice_event.start)
-    self.assertAlmostEqual((560 - 520) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual((560 - 520) / 1000.0, slice_event.end)
-    self.assertAlmostEqual(280 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((310 - 280) / 1000.0, slice_event.thread_duration)
-    self.assertAlmostEqual(310 / 1000.0, slice_event.thread_end)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-    slice_event = t.all_slices[1]
-    self.assertEqual('b', slice_event.name)
-    self.assertEqual('bar', slice_event.category)
-    self.assertAlmostEqual((629 - 520) / 1000.0, slice_event.start)
-    self.assertAlmostEqual((631 - 629) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual((631 - 520) / 1000.0, slice_event.end)
-    self.assertAlmostEqual(356 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((357 - 356) / 1000.0, slice_event.thread_duration)
-    self.assertAlmostEqual(357 / 1000.0, slice_event.thread_end)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-    slice_event = t.all_slices[2]
-    self.assertEqual('c', slice_event.name)
-    self.assertEqual('baz', slice_event.category)
-    self.assertAlmostEqual((633 - 520) / 1000.0, slice_event.start)
-    self.assertAlmostEqual((637 - 633) / 1000.0, slice_event.duration)
-    self.assertEqual(None, slice_event.thread_start)
-    self.assertEqual(None, slice_event.thread_duration)
-    self.assertEqual(None, slice_event.thread_end)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-
-  def testArgumentDupeCreatesNonFailingImportError(self):
-    events = [
-      {'name': 'a', 'args': {'x': 1}, 'pid': 1, 'ts': 520, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a', 'args': {'x': 2}, 'pid': 1, 'ts': 560, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    t = processes[0].threads[1]
-    slice_a = FindEventNamed(t.all_slices, 'a')
-
-    self.assertEqual(2, slice_a.args['x'])
-    self.assertEqual(1, len(m.import_errors))
-
-  def testCategoryBeginEndMismatchPreferslice_begin(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 520, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 560, 'cat': 'bar',
-       'tid': 53, 'ph': 'E'}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    p = processes[0]
-    self.assertEqual(52, p.pid)
-
-    self.assertEqual(1, len(p.threads))
-    t = p.threads[53]
-    self.assertEqual(1, len(t.all_slices))
-    self.assertEqual(53, t.tid)
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-
-  def testNestedParsing(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 1, 'tts': 2, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 3, 'tts': 3, 'cat': 'bar',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 5, 'tts': 4, 'cat': 'bar',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 7, 'tts': 5, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    t = m.GetAllProcesses()[0].threads[1]
-
-    slice_a = FindEventNamed(t.all_slices, 'a')
-    slice_b = FindEventNamed(t.all_slices, 'b')
-
-    self.assertEqual('a', slice_a.name)
-    self.assertEqual('foo', slice_a.category)
-    self.assertAlmostEqual(0.001, slice_a.start)
-    self.assertAlmostEqual(0.006, slice_a.duration)
-    self.assertAlmostEqual(0.002, slice_a.thread_start)
-    self.assertAlmostEqual(0.003, slice_a.thread_duration)
-
-    self.assertEqual('b', slice_b.name)
-    self.assertEqual('bar', slice_b.category)
-    self.assertAlmostEqual(0.003, slice_b.start)
-    self.assertAlmostEqual(0.002, slice_b.duration)
-    self.assertAlmostEqual(0.003, slice_b.thread_start)
-    self.assertAlmostEqual(0.001, slice_b.thread_duration)
-
-  def testAutoclosing(self):
-    events = [
-      # Slices that don't finish.
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 1, 'tts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 2, 'cat': 'foo',
-       'tid': 2, 'ph': 'B'},
-
-      # Slices on thread 1 and 2 that do finish to give an 'end time' to make
-      # autoclosing work.
-      {'name': 'c', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 1.5, 'cat': 'bar',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'c', 'args': {}, 'pid': 1, 'ts': 4, 'tts': 3, 'cat': 'bar',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'd', 'args': {}, 'pid': 1, 'ts': 3, 'tts': 2.5, 'cat': 'bar',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'd', 'args': {}, 'pid': 1, 'ts': 7, 'tts': 5, 'cat': 'bar',
-       'tid': 2, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t1 = p.threads[1]
-    slice_event = FindEventNamed(t1.all_slices, 'a')
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertTrue(slice_event.did_not_finish)
-    self.assertAlmostEqual(0, slice_event.start)
-    self.assertAlmostEqual((7 - 1) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(1 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((3 - 1) / 1000.0, slice_event.thread_duration)
-
-    t2 = p.threads[2]
-    slice_event = FindEventNamed(t2.all_slices, 'b')
-    self.assertEqual('b', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertTrue(slice_event.did_not_finish)
-    self.assertAlmostEqual((2 - 1) / 1000.0, slice_event.start)
-    self.assertAlmostEqual((7 - 2) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(2 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((5 - 2) / 1000.0, slice_event.thread_duration)
-
-  def testAutoclosingLoneBegin(self):
-    events = [
-      # Slice that doesn't finish.
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 1, 'tts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[1]
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertTrue(slice_event.did_not_finish)
-    self.assertAlmostEqual(0, slice_event.start)
-    self.assertAlmostEqual(0, slice_event.duration)
-    self.assertAlmostEqual(1 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual(0, slice_event.thread_duration)
-
-  def testAutoclosingWithSubTasks(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'b1', 'args': {}, 'pid': 1, 'ts': 2, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'b1', 'args': {}, 'pid': 1, 'ts': 3, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'b2', 'args': {}, 'pid': 1, 'ts': 3, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    t = m.GetAllProcesses()[0].threads[1]
-
-    slice_a = FindEventNamed(t.all_slices, 'a')
-    slice_b1 = FindEventNamed(t.all_slices, 'b1')
-    slice_b2 = FindEventNamed(t.all_slices, 'b2')
-
-    self.assertAlmostEqual(0.003, slice_a.end)
-    self.assertAlmostEqual(0.003, slice_b1.end)
-    self.assertAlmostEqual(0.003, slice_b2.end)
-
-  def testAutoclosingWithEventsOutsideBounds(self):
-    events = [
-      # Slice that begins before min and ends after max of the other threads.
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 0, 'tts': 0, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 6, 'tts': 3, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-
-      # Slice that does finish to give an 'end time' to establish a basis
-      {'name': 'c', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 1, 'cat': 'bar',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'c', 'args': {}, 'pid': 1, 'ts': 4, 'tts': 2, 'cat': 'bar',
-       'tid': 2, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    p = m.GetAllProcesses()[0]
-    t1 = p.threads[1]
-    t1_thread_time_bounds = (
-        m._thread_time_bounds[t1]) # pylint: disable=protected-access
-    self.assertAlmostEqual(0.000, t1_thread_time_bounds.min)
-    self.assertAlmostEqual(0.003, t1_thread_time_bounds.max)
-    self.assertEqual(2, len(t1.all_slices))
-
-    slice_event = FindEventNamed(t1.all_slices, 'a')
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertAlmostEqual(0, slice_event.start)
-    self.assertAlmostEqual(0.006, slice_event.duration)
-    self.assertAlmostEqual(0, slice_event.thread_start)
-    self.assertAlmostEqual(0.003, slice_event.thread_duration)
-
-    t2 = p.threads[2]
-    t2_thread_time_bounds = (
-        m._thread_time_bounds[t2]) # pylint: disable=protected-access
-    self.assertAlmostEqual(0.001, t2_thread_time_bounds.min)
-    self.assertAlmostEqual(0.002, t2_thread_time_bounds.max)
-    slice2 = FindEventNamed(t2.all_slices, 'c')
-    self.assertEqual('c', slice2.name)
-    self.assertEqual('bar', slice2.category)
-    self.assertAlmostEqual(0.002, slice2.start)
-    self.assertAlmostEqual(0.002, slice2.duration)
-    self.assertAlmostEqual(0.001, slice2.thread_start)
-    self.assertAlmostEqual(0.001, slice2.thread_duration)
-
-    self.assertAlmostEqual(0.000, m.bounds.min)
-    self.assertAlmostEqual(0.006, m.bounds.max)
-
-  def testNestedAutoclosing(self):
-    events = [
-      # Tasks that don't finish.
-      {'name': 'a1', 'args': {}, 'pid': 1, 'ts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a2', 'args': {}, 'pid': 1, 'ts': 1.5, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-
-      # Slice that does finish to give an 'end time' to make autoclosing work.
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 1, 'cat': 'foo',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 2, 'cat': 'foo',
-       'tid': 2, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    t1 = m.GetAllProcesses()[0].threads[1]
-    t2 = m.GetAllProcesses()[0].threads[2]
-
-    slice_a1 = FindEventNamed(t1.all_slices, 'a1')
-    slice_a2 = FindEventNamed(t1.all_slices, 'a2')
-    FindEventNamed(t2.all_slices, 'b')
-
-    self.assertAlmostEqual(0.002, slice_a1.end)
-    self.assertAlmostEqual(0.002, slice_a2.end)
-
-  def testMultipleThreadParsing(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 4, 'tts': 2, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 6, 'tts': 3, 'cat': 'bar',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 1, 'ts': 8, 'tts': 4, 'cat': 'bar',
-       'tid': 2, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    p = processes[0]
-
-    self.assertEqual(2, len(p.threads))
-
-    # Check thread 1.
-    t = p.threads[1]
-    self.assertAlmostEqual(1, len(t.all_slices))
-    self.assertAlmostEqual(1, t.tid)
-
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertAlmostEqual(0, slice_event.start)
-    self.assertAlmostEqual((4 - 2) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(1 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((2 - 1) / 1000.0, slice_event.thread_duration)
-
-    # Check thread 2.
-    t = p.threads[2]
-    self.assertAlmostEqual(1, len(t.all_slices))
-    self.assertAlmostEqual(2, t.tid)
-
-    slice_event = t.all_slices[0]
-    self.assertEqual('b', slice_event.name)
-    self.assertEqual('bar', slice_event.category)
-    self.assertAlmostEqual((6 - 2) / 1000.0, slice_event.start)
-    self.assertAlmostEqual((8 - 6) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(3 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((4 - 3) / 1000.0, slice_event.thread_duration)
-
-  def testMultiplePidParsing(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 4, 'tts': 2, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'b', 'args': {}, 'pid': 2, 'ts': 6, 'tts': 3, 'cat': 'bar',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 2, 'ts': 8, 'tts': 4, 'cat': 'bar',
-       'tid': 2, 'ph': 'E'}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual(2, len(processes))
-
-    p = processes[0]
-    self.assertEqual(1, p.pid)
-    self.assertEqual(1, len(p.threads))
-
-    # Check process 1 thread 1.
-    t = p.threads[1]
-    self.assertEqual(1, len(t.all_slices))
-    self.assertEqual(1, t.tid)
-
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertAlmostEqual(0, slice_event.start)
-    self.assertAlmostEqual((4 - 2) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(1 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((2 - 1) / 1000.0, slice_event.thread_duration)
-
-    # Check process 2 thread 2.
-    # TODO: will this be in deterministic order?
-    p = processes[1]
-    self.assertEqual(2, p.pid)
-    self.assertEqual(1, len(p.threads))
-    t = p.threads[2]
-    self.assertEqual(1, len(t.all_slices))
-    self.assertEqual(2, t.tid)
-
-    slice_event = t.all_slices[0]
-    self.assertEqual('b', slice_event.name)
-    self.assertEqual('bar', slice_event.category)
-    self.assertAlmostEqual((6 - 2) / 1000.0, slice_event.start)
-    self.assertAlmostEqual((8 - 6) / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(3 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual((4 - 3) / 1000.0, slice_event.thread_duration)
-
-    # Check getAllThreads.
-    self.assertEqual([processes[0].threads[1],
-                      processes[1].threads[2]],
-                      m.GetAllThreads())
-
-  def testThreadNames(self):
-    events = [
-      {'name': 'thread_name', 'args': {'name': 'Thread 1'},
-        'pid': 1, 'ts': 0, 'tid': 1, 'ph': 'M'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 2, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'b', 'args': {}, 'pid': 2, 'ts': 3, 'cat': 'foo',
-       'tid': 2, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 2, 'ts': 4, 'cat': 'foo',
-       'tid': 2, 'ph': 'E'},
-      {'name': 'thread_name', 'args': {'name': 'Thread 2'},
-        'pid': 2, 'ts': 0, 'tid': 2, 'ph': 'M'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual('Thread 1', processes[0].threads[1].name)
-    self.assertEqual('Thread 2', processes[1].threads[2].name)
-
-  def testParsingWhenEndComesFirst(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 1, 'tts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 4, 'tts': 4, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 5, 'tts': 5, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[1]
-    self.assertEqual(1, len(t.all_slices))
-    self.assertEqual('a', t.all_slices[0].name)
-    self.assertEqual('foo', t.all_slices[0].category)
-    self.assertEqual(0.004, t.all_slices[0].start)
-    self.assertEqual(0.001, t.all_slices[0].duration)
-    self.assertEqual(0.004, t.all_slices[0].thread_start)
-    self.assertEqual(0.001, t.all_slices[0].thread_duration)
-    self.assertEqual(1, len(m.import_errors))
-
-  def testImmediateParsing(self):
-    events = [
-      # Need to include immediates inside a task so the timeline
-      # recentering/zeroing doesn't clobber their timestamp.
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 2, 'tts': 1, 'cat': 'foo',
-       'tid': 1, 'ph': 'B'},
-      {'name': 'immediate', 'args': {}, 'pid': 1, 'ts': 4, 'cat': 'bar',
-       'tid': 1, 'ph': 'I'},
-      {'name': 'slower', 'args': {}, 'pid': 1, 'ts': 8, 'cat': 'baz',
-       'tid': 1, 'ph': 'i'},
-      {'name': 'a', 'args': {}, 'pid': 1, 'ts': 8, 'tts': 4, 'cat': 'foo',
-       'tid': 1, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[1]
-    self.assertEqual(3, len(t.all_slices))
-
-    i = m.GetAllEventsOfName('immediate')[0]
-    self.assertEqual('immediate', i.name)
-    self.assertEqual('bar', i.category)
-    self.assertAlmostEqual(0.004, i.start)
-    self.assertAlmostEqual(0, i.duration)
-
-    slower = m.GetAllEventsOfName('slower')[0]
-    self.assertEqual('slower', slower.name)
-    self.assertEqual('baz', slower.category)
-    self.assertAlmostEqual(0.008, slower.start)
-    self.assertAlmostEqual(0, slower.duration)
-
-    a = m.GetAllEventsOfName('a')[0]
-    self.assertEqual('a', a.name)
-    self.assertEqual('foo', a.category)
-    self.assertAlmostEqual(0.002, a.start)
-    self.assertAlmostEqual(0.006, a.duration)
-    self.assertAlmostEqual(0.001, a.thread_start)
-    self.assertAlmostEqual(0.003, a.thread_duration)
-
-
-  def testSimpleCounter(self):
-    events = [
-      {'name': 'ctr', 'args': {'value': 0}, 'pid': 1, 'ts': 0, 'cat': 'foo',
-       'tid': 1, 'ph': 'C'},
-      {'name': 'ctr', 'args': {'value': 10}, 'pid': 1, 'ts': 10, 'cat': 'foo',
-       'tid': 1, 'ph': 'C'},
-      {'name': 'ctr', 'args': {'value': 0}, 'pid': 1, 'ts': 20, 'cat': 'foo',
-       'tid': 1, 'ph': 'C'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    ctr = p.counters['foo.ctr']
-
-    self.assertEqual('ctr', ctr.name)
-    self.assertEqual('foo', ctr.category)
-    self.assertEqual(3, ctr.num_samples)
-    self.assertEqual(1, ctr.num_series)
-
-    self.assertEqual(['value'], ctr.series_names)
-    self.assertEqual([0, 0.01, 0.02], ctr.timestamps)
-    self.assertEqual([0, 10, 0], ctr.samples)
-    self.assertEqual([0, 10, 0], ctr.totals)
-    self.assertEqual(10, ctr.max_total)
-
-  def testInstanceCounter(self):
-    events = [
-      {'name': 'ctr', 'args': {'value': 0}, 'pid': 1, 'ts': 0, 'cat': 'foo',
-       'tid': 1,
-       'ph': 'C', 'id': 0},
-      {'name': 'ctr', 'args': {'value': 10}, 'pid': 1, 'ts': 10, 'cat': 'foo',
-       'tid': 1,
-       'ph': 'C', 'id': 0},
-      {'name': 'ctr', 'args': {'value': 10}, 'pid': 1, 'ts': 10, 'cat': 'foo',
-       'tid': 1,
-       'ph': 'C', 'id': 1},
-      {'name': 'ctr', 'args': {'value': 20}, 'pid': 1, 'ts': 15, 'cat': 'foo',
-       'tid': 1,
-       'ph': 'C', 'id': 1},
-      {'name': 'ctr', 'args': {'value': 30}, 'pid': 1, 'ts': 18, 'cat': 'foo',
-       'tid': 1,
-       'ph': 'C', 'id': 1},
-      {'name': 'ctr', 'args': {'value': 40}, 'pid': 1, 'ts': 20, 'cat': 'bar',
-       'tid': 1,
-       'ph': 'C', 'id': 2}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    ctr = p.counters['foo.ctr[0]']
-    self.assertEqual('ctr[0]', ctr.name)
-    self.assertEqual('foo', ctr.category)
-    self.assertEqual(2, ctr.num_samples)
-    self.assertEqual(1, ctr.num_series)
-    self.assertEqual([0, 0.01], ctr.timestamps)
-    self.assertEqual([0, 10], ctr.samples)
-
-    ctr = m.GetAllProcesses()[0].counters['foo.ctr[1]']
-    self.assertEqual('ctr[1]', ctr.name)
-    self.assertEqual('foo', ctr.category)
-    self.assertEqual(3, ctr.num_samples)
-    self.assertEqual(1, ctr.num_series)
-    self.assertEqual([0.01, 0.015, 0.018], ctr.timestamps)
-    self.assertEqual([10, 20, 30], ctr.samples)
-
-    ctr = m.GetAllProcesses()[0].counters['bar.ctr[2]']
-    self.assertEqual('ctr[2]', ctr.name)
-    self.assertEqual('bar', ctr.category)
-    self.assertEqual(1, ctr.num_samples)
-    self.assertEqual(1, ctr.num_series)
-    self.assertEqual([0.02], ctr.timestamps)
-    self.assertEqual([40], ctr.samples)
-
-  def testMultiCounterUpdateBounds(self):
-    ctr = tracing_counter.Counter(None, 'testBasicCounter',
-        'testBasicCounter')
-    ctr.series_names = ['value1', 'value2']
-    ctr.timestamps = [0, 1, 2, 3, 4, 5, 6, 7]
-    ctr.samples = [0, 0,
-                   1, 0,
-                   1, 1,
-                   2, 1.1,
-                   3, 0,
-                   1, 7,
-                   3, 0,
-                   3.1, 0.5]
-    ctr.FinalizeImport()
-    self.assertEqual(8, ctr.max_total)
-    self.assertEqual([0, 0,
-                       1, 1,
-                       1, 2,
-                       2, 3.1,
-                       3, 3,
-                       1, 8,
-                       3, 3,
-                       3.1, 3.6], ctr.totals)
-
-  def testMultiCounter(self):
-    events = [
-      {'name': 'ctr', 'args': {'value1': 0, 'value2': 7}, 'pid': 1, 'ts': 0,
-       'cat': 'foo', 'tid': 1, 'ph': 'C'},
-      {'name': 'ctr', 'args': {'value1': 10, 'value2': 4}, 'pid': 1, 'ts': 10,
-       'cat': 'foo', 'tid': 1, 'ph': 'C'},
-      {'name': 'ctr', 'args': {'value1': 0, 'value2': 1}, 'pid': 1, 'ts': 20,
-       'cat': 'foo', 'tid': 1, 'ph': 'C'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    ctr = p.counters['foo.ctr']
-    self.assertEqual('ctr', ctr.name)
-
-    self.assertEqual('ctr', ctr.name)
-    self.assertEqual('foo', ctr.category)
-    self.assertEqual(3, ctr.num_samples)
-    self.assertEqual(2, ctr.num_series)
-
-    self.assertEqual(sorted(['value1', 'value2']), sorted(ctr.series_names))
-    self.assertEqual(sorted([0, 0.01, 0.02]), sorted(ctr.timestamps))
-    self.assertEqual(sorted([0, 7, 10, 4, 0, 1]), sorted(ctr.samples))
-    # We can't check ctr.totals here because it can change depending on
-    # the order in which the series names are added.
-    self.assertEqual(14, ctr.max_total)
-
-  def testStartFinishOneSliceOneThread(self):
-    events = [
-      # Time is intentionally out of order.
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 560, 'cat': 'cat',
-       'tid': 53,
-         'ph': 'F', 'id': 72},
-      {'name': 'a', 'pid': 52, 'ts': 524, 'cat': 'cat',
-       'tid': 53,
-         'ph': 'S', 'id': 72, 'args': {'foo': 'bar'}}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-
-    events = list(m.IterAllEvents())
-    self.assertEqual(2, len(events))
-
-    processes = m.GetAllProcesses()
-    t = processes[0].threads[53]
-    slices = t.async_slices
-    self.assertEqual(1, len(slices))
-    self.assertEqual('a', slices[0].name)
-    self.assertEqual('cat', slices[0].category)
-    self.assertEqual(72, slices[0].id)
-    self.assertEqual('bar', slices[0].args['foo'])
-    self.assertEqual(0, slices[0].start)
-    self.assertAlmostEqual((60 - 24) / 1000.0, slices[0].duration)
-    self.assertEqual(t, slices[0].start_thread)
-    self.assertEqual(t, slices[0].end_thread)
-
-  def testEndArgsAddedToSlice(self):
-    events = [
-      {'name': 'a', 'args': {'x': 1}, 'pid': 52, 'ts': 520, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'a', 'args': {'y': 2}, 'pid': 52, 'ts': 560, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    p = processes[0]
-
-    self.assertEqual(1, len(p.threads))
-    t = p.threads[53]
-    self.assertEqual(1, len(t.all_slices))
-    self.assertEqual(53, t.tid)
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertEqual(0, slice_event.start)
-    self.assertEqual(1, slice_event.args['x'])
-    self.assertEqual(2, slice_event.args['y'])
-
-  def testEndArgOverrwritesOriginalArgValueIfDuplicated(self):
-    events = [
-      {'name': 'b', 'args': {'z': 3}, 'pid': 52, 'ts': 629, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'b', 'args': {'z': 4}, 'pid': 52, 'ts': 631, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    p = processes[0]
-
-    self.assertEqual(1, len(p.threads))
-    t = p.threads[53]
-    slice_event = t.all_slices[0]
-    self.assertEqual('b', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertEqual(0, slice_event.start)
-    self.assertEqual(4, slice_event.args['z'])
-
-  def testSliceHierarchy(self):
-    """The slice hierarchy should look something like this:
-           [            a            ]
-              [      b      ]  [ d ]
-              [ c ]     [ e ]
-    """
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 100, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 200, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'},
-      {'name': 'b', 'args': {}, 'pid': 52, 'ts': 125, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'b', 'args': {}, 'pid': 52, 'ts': 165, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'},
-      {'name': 'c', 'args': {}, 'pid': 52, 'ts': 125, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'c', 'args': {}, 'pid': 52, 'ts': 135, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'},
-      {'name': 'd', 'args': {}, 'pid': 52, 'ts': 175, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'd', 'args': {}, 'pid': 52, 'ts': 190, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'},
-      {'name': 'e', 'args': {}, 'pid': 52, 'ts': 155, 'cat': 'foo',
-       'tid': 53, 'ph': 'B'},
-      {'name': 'e', 'args': {}, 'pid': 52, 'ts': 165, 'cat': 'foo',
-       'tid': 53, 'ph': 'E'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data, shift_world_to_zero=False)
-    processes = m.GetAllProcesses()
-    self.assertEqual(1, len(processes))
-    p = processes[0]
-
-    self.assertEqual(1, len(p.threads))
-    t = p.threads[53]
-
-    slice_a = t.all_slices[0]
-    self.assertEqual(4, len(slice_a.GetAllSubSlices()))
-    self.assertEqual('a', slice_a.name)
-    self.assertEqual(100 / 1000.0, slice_a.start)
-    self.assertEqual(200 / 1000.0, slice_a.end)
-    self.assertEqual(2, len(slice_a.sub_slices))
-
-    slice_b = slice_a.sub_slices[0]
-    self.assertEqual('b', slice_b.name)
-    self.assertEqual(2, len(slice_b.sub_slices))
-    self.assertEqual('c', slice_b.sub_slices[0].name)
-    self.assertEqual('e', slice_b.sub_slices[1].name)
-
-    slice_d = slice_a.sub_slices[1]
-    self.assertEqual('d', slice_d.name)
-    self.assertEqual(0, len(slice_d.sub_slices))
-
-  def testAsyncEndArgAddedToSlice(self):
-    events = [
-      # Time is intentionally out of order.
-      {'name': 'c', 'args': {'y': 2}, 'pid': 52, 'ts': 560, 'cat': 'foo',
-       'tid': 53,
-         'ph': 'F', 'id': 72},
-      {'name': 'c', 'args': {'x': 1}, 'pid': 52, 'ts': 524, 'cat': 'foo',
-       'tid': 53,
-         'ph': 'S', 'id': 72}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    t = m.GetAllProcesses()[0].threads[53]
-    self.assertEqual(1, len(t.async_slices))
-    parent_slice = t.async_slices[0]
-    self.assertEqual('c', parent_slice.name)
-    self.assertEqual('foo', parent_slice.category)
-
-    self.assertEqual(1, len(parent_slice.sub_slices))
-    sub_slice = parent_slice.sub_slices[0]
-    self.assertEqual(1, sub_slice.args['x'])
-    self.assertEqual(2, sub_slice.args['y'])
-
-  def testAsyncEndArgOverrwritesOriginalArgValueIfDuplicated(self):
-    events = [
-      # Time is intentionally out of order.
-      {'name': 'd', 'args': {'z': 4}, 'pid': 52, 'ts': 560, 'cat': 'foo',
-       'tid': 53,
-         'ph': 'F', 'id': 72},
-      {'name': 'd', 'args': {'z': 3}, 'pid': 52, 'ts': 524, 'cat': 'foo',
-       'tid': 53,
-         'ph': 'S', 'id': 72}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    t = m.GetAllProcesses()[0].threads[53]
-    self.assertEqual(1, len(t.async_slices))
-    parent_slice = t.async_slices[0]
-    self.assertEqual('d', parent_slice.name)
-    self.assertEqual('foo', parent_slice.category)
-
-    self.assertEqual(1, len(parent_slice.sub_slices))
-    sub_slice = parent_slice.sub_slices[0]
-    self.assertEqual(4, sub_slice.args['z'])
-
-  def testAsyncStepsInOneThread(self):
-    events = [
-      # Time is intentionally out of order.
-      {'name': 'a', 'args': {'z': 3}, 'pid': 52, 'ts': 560, 'cat': 'foo',
-       'tid': 53, 'ph': 'F', 'id': 72, 'tts': 25},
-      {'name': 'a', 'args': {'step': 's1', 'y': 2}, 'pid': 52, 'ts': 548,
-       'cat': 'foo', 'tid': 53, 'ph': 'T', 'id': 72, 'tts': 20},
-      {'name': 'a', 'args': {'x': 1}, 'pid': 52, 'ts': 524, 'cat': 'foo',
-       'tid': 53, 'ph': 'S', 'id': 72, 'tts': 17}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    t = m.GetAllProcesses()[0].threads[53]
-    self.assertEqual(1, len(t.async_slices))
-    parent_slice = t.async_slices[0]
-    self.assertEqual('a', parent_slice.name)
-    self.assertEqual('foo', parent_slice.category)
-    self.assertEqual(0, parent_slice.start)
-    self.assertAlmostEqual(17/1000.0, parent_slice.thread_start)
-    self.assertAlmostEqual(25/1000.0, parent_slice.thread_end)
-
-    self.assertEqual(2, len(parent_slice.sub_slices))
-    sub_slice = parent_slice.sub_slices[0]
-    self.assertEqual('a', sub_slice.name)
-    self.assertEqual('foo', sub_slice.category)
-    self.assertAlmostEqual(0, sub_slice.start)
-    self.assertAlmostEqual((548 - 524) / 1000.0, sub_slice.duration)
-    self.assertAlmostEqual((20 - 17) / 1000.0, sub_slice.thread_duration)
-    self.assertEqual(1, sub_slice.args['x'])
-
-    sub_slice = parent_slice.sub_slices[1]
-    self.assertEqual('a:s1', sub_slice.name)
-    self.assertEqual('foo', sub_slice.category)
-    self.assertAlmostEqual((548 - 524) / 1000.0, sub_slice.start)
-    self.assertAlmostEqual((560 - 548) / 1000.0, sub_slice.duration)
-    self.assertAlmostEqual((25 - 20) / 1000.0, sub_slice.thread_duration)
-    self.assertEqual(2, sub_slice.args['y'])
-    self.assertEqual(3, sub_slice.args['z'])
-
-  def testAsyncStepsMissingStart(self):
-    events = [
-      # Time is intentionally out of order.
-      {'name': 'a', 'args': {'z': 3}, 'pid': 52, 'ts': 560, 'cat': 'foo',
-       'tid': 53, 'ph': 'F', 'id': 72},
-      {'name': 'a', 'args': {'step': 's1', 'y': 2}, 'pid': 52, 'ts': 548,
-       'cat': 'foo', 'tid': 53, 'ph': 'T', 'id': 72}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    t = m.GetAllProcesses()[0].threads[53]
-    self.assertTrue(t is not None)
-
-  def testAsyncStepsMissingFinish(self):
-    events = [
-      # Time is intentionally out of order.
-      {'name': 'a', 'args': {'step': 's1', 'y': 2}, 'pid': 52, 'ts': 548,
-       'cat': 'foo', 'tid': 53, 'ph': 'T', 'id': 72},
-      {'name': 'a', 'args': {'z': 3}, 'pid': 52, 'ts': 560, 'cat': 'foo',
-       'tid': 53, 'ph': 'S', 'id': 72}
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    t = m.GetAllProcesses()[0].threads[53]
-    self.assertTrue(t is not None)
-
-  def testImportSamples(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 548, 'cat': 'test',
-       'tid': 53, 'ph': 'P'},
-      {'name': 'b', 'args': {}, 'pid': 52, 'ts': 548, 'cat': 'test',
-       'tid': 53, 'ph': 'P'},
-      {'name': 'c', 'args': {}, 'pid': 52, 'ts': 558, 'cat': 'test',
-       'tid': 53, 'ph': 'P'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[53]
-    self.assertEqual(3, len(t.samples))
-    self.assertEqual(0.0, t.samples[0].start)
-    self.assertEqual(0.0, t.samples[1].start)
-    self.assertAlmostEqual(0.01, t.samples[2].start)
-    self.assertEqual('a', t.samples[0].name)
-    self.assertEqual('b', t.samples[1].name)
-    self.assertEqual('c', t.samples[2].name)
-    self.assertEqual(0, len(m.import_errors))
-
-  def testImportSamplesMissingArgs(self):
-    events = [
-      {'name': 'a', 'pid': 52, 'ts': 548, 'cat': 'test',
-       'tid': 53, 'ph': 'P'},
-      {'name': 'b', 'pid': 52, 'ts': 548, 'cat': 'test',
-       'tid': 53, 'ph': 'P'},
-      {'name': 'c', 'pid': 52, 'ts': 549, 'cat': 'test',
-       'tid': 53, 'ph': 'P'}
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[53]
-    self.assertEqual(3, len(t.samples))
-    self.assertEqual(0, len(m.import_errors))
-
-  def testImportCompleteEvent(self):
-    events = [
-      {'name': 'a', 'args': {}, 'pid': 52, 'ts': 629, 'tts': 538, 'dur': 1,
-       'tdur': 1, 'cat': 'baz', 'tid': 53, 'ph': 'X'},
-      {'name': 'b', 'args': {}, 'pid': 52, 'ts': 730, 'tts': 620, 'dur': 20,
-       'tdur': 14, 'cat': 'foo', 'tid': 53, 'ph': 'X'},
-      {'name': 'c', 'args': {}, 'pid': 52, 'ts': 740, 'tts': 625, 'cat': 'baz',
-       'tid': 53, 'ph': 'X'},
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[53]
-    self.assertEqual(3, len(t.all_slices))
-
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertAlmostEqual(0.0, slice_event.start)
-    self.assertAlmostEqual(1 / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(538 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual(1 / 1000.0, slice_event.thread_duration)
-    self.assertFalse(slice_event.did_not_finish)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-    slice_event = t.all_slices[1]
-    self.assertEqual('b', slice_event.name)
-    self.assertAlmostEqual((730 - 629) / 1000.0, slice_event.start)
-    self.assertAlmostEqual(20 / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(620 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual(14 / 1000.0, slice_event.thread_duration)
-    self.assertFalse(slice_event.did_not_finish)
-    self.assertEqual(1, len(slice_event.sub_slices))
-    self.assertEqual(t.all_slices[2], slice_event.sub_slices[0])
-
-    slice_event = t.all_slices[2]
-    self.assertEqual('c', slice_event.name)
-    self.assertAlmostEqual((740 - 629) / 1000.0, slice_event.start)
-    self.assertAlmostEqual(10 / 1000.0, slice_event.duration)
-    self.assertAlmostEqual(625 / 1000.0, slice_event.thread_start)
-    self.assertAlmostEqual(9 / 1000.0, slice_event.thread_duration)
-    self.assertTrue(slice_event.did_not_finish)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-  def testImportMarkEvent(self):
-    events = [
-      {'name': 'a', 'pid': 52, 'ts': 629, 'cat': 'baz', 'tid': 53, 'ph': 'R'},
-      {'name': 'b', 'pid': 52, 'ts': 730, 'cat': 'foo', 'tid': 53, 'ph': 'R'},
-      {'name': 'c', 'pid': 52, 'ts': 740, 'cat': 'baz', 'tid': 53, 'ph': 'R'},
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[53]
-    self.assertEqual(3, len(t.all_slices))
-
-    slice_event = t.all_slices[0]
-    self.assertEqual('a', slice_event.name)
-    self.assertEqual('baz', slice_event.category)
-    self.assertAlmostEqual(0.0, slice_event.start)
-    self.assertFalse(slice_event.did_not_finish)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-    slice_event = t.all_slices[1]
-    self.assertEqual('b', slice_event.name)
-    self.assertEqual('foo', slice_event.category)
-    self.assertAlmostEqual((730 - 629) / 1000.0, slice_event.start)
-    self.assertFalse(slice_event.did_not_finish)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-    slice_event = t.all_slices[2]
-    self.assertEqual('c', slice_event.name)
-    self.assertEqual('baz', slice_event.category)
-    self.assertAlmostEqual((740 - 629) / 1000.0, slice_event.start)
-    self.assertFalse(slice_event.did_not_finish)
-    self.assertEqual(0, len(slice_event.sub_slices))
-
-  def testImportFlowEvent(self):
-    events = [
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 548,
-       'ph': 's', 'args': {}},
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 560,
-       'ph': 't', 'args': {}},
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 580,
-       'ph': 'f', 'args': {}},
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    p = m.GetAllProcesses()[0]
-    t = p.threads[53]
-    self.assertTrue(t is not None)
-    self.assertEqual(2, len(m.flow_events))
-
-    start = m.flow_events[0][0]
-    step = m.flow_events[0][1]
-    finish = m.flow_events[1][1]
-
-    self.assertEqual('a', start.name)
-    self.assertEqual('foo', start.category)
-    self.assertEqual(72, start.event_id)
-    self.assertEqual(0, start.start)
-    self.assertEqual(0, start.duration)
-
-    self.assertEqual(start.name, step.name)
-    self.assertEqual(start.category, step.category)
-    self.assertEqual(start.event_id, step.event_id)
-    self.assertAlmostEqual(12 / 1000.0, step.start)
-    self.assertEquals(0, step.duration)
-
-    self.assertEqual(start.name, finish.name)
-    self.assertEqual(start.category, finish.category)
-    self.assertEqual(start.event_id, finish.event_id)
-    self.assertAlmostEqual((20 + 12) / 1000.0, finish.start)
-    self.assertEqual(0, finish.duration)
-
-  def testImportOutOfOrderFlowEvent(self):
-    events = [
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 548,
-       'ph': 's', 'args': {}},
-      {'name': 'b', 'cat': 'foo', 'id': 73, 'pid': 52, 'tid': 53, 'ts': 148,
-       'ph': 's', 'args': {}},
-      {'name': 'b', 'cat': 'foo', 'id': 73, 'pid': 52, 'tid': 53, 'ts': 570,
-       'ph': 'f', 'args': {}},
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 560,
-       'ph': 't', 'args': {}},
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 580,
-       'ph': 'f', 'args': {}},
-    ]
-
-    expected = [[0.4, 0.412], [0.0, 0.422], [0.412, 0.432]]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    self.assertEqual(3, len(m.flow_events))
-
-    for i in range(len(expected)):
-      self.assertAlmostEqual(expected[i][0], m.flow_events[i][0].start)
-      self.assertAlmostEqual(expected[i][1], m.flow_events[i][1].start)
-
-  def testImportErrornousFlowEvent(self):
-    events = [
-      {'name': 'a', 'cat': 'foo', 'id': 70, 'pid': 52, 'tid': 53, 'ts': 548,
-       'ph': 's', 'args': {}},
-      {'name': 'a2', 'cat': 'foo', 'id': 70, 'pid': 52, 'tid': 53, 'ts': 550,
-       'ph': 's', 'args': {}},
-      {'name': 'b', 'cat': 'foo', 'id': 73, 'pid': 52, 'tid': 53, 'ts': 570,
-       'ph': 'f', 'args': {}},
-      {'name': 'a', 'cat': 'foo', 'id': 72, 'pid': 52, 'tid': 53, 'ts': 560,
-       'ph': 't', 'args': {}},
-    ]
-
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    self.assertEqual(0, len(m.flow_events))
-
-  def testImportMemoryDumpEvents(self):
-    events = [
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 52, 'ts': 123,
-       'id': '1234ABCD'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 54, 'ts': 134,
-       'id': '1234ABCD'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 52, 'ts': 144,
-       'id': '1234ABCD'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 52, 'ts': 245,
-       'id': '1234ABDF'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 54, 'ts': 256,
-       'id': '1234ABDF'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 52, 'ts': 233,
-       'id': '1234ABDF'},
-    ]
-
-    expected_processes = set([52, 54])
-    expected_results = [['1234ABCD', 0, 21], ['1234ABDF', 110, 23]]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    assert set(p.pid for p in m.GetAllProcesses()) == expected_processes
-
-    memory_dumps = list(m.IterGlobalMemoryDumps())
-    self.assertEqual(len(expected_results), len(memory_dumps))
-    for memory_dump, test_values in zip(memory_dumps, expected_results):
-      assert len(list(memory_dump.IterProcessMemoryDumps())) == len(
-          expected_processes)
-      dump_id, start, duration = test_values
-      self.assertEquals(dump_id, memory_dump.dump_id)
-      self.assertAlmostEqual(start / 1000.0, memory_dump.start)
-      self.assertAlmostEqual(duration / 1000.0, memory_dump.duration)
-
-  def testImportOutOfOrderMemoryDumpEvents(self):
-    events = [
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 52, 'ts': 245,
-       'id': '1234ABDF'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 54, 'ts': 134,
-       'id': '1234ABCD'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 54, 'ts': 256,
-       'id': '1234ABDF'},
-      {'name': 'a', 'cat': 'b', 'ph': 'v', 'pid': 52, 'ts': 123,
-       'id': '1234ABCD'},
-    ]
-
-    expected = [['1234ABCD', 0, 11], ['1234ABDF', 122, 11]]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    memory_dumps = list(m.IterGlobalMemoryDumps())
-    self.assertEqual(len(expected), len(memory_dumps))
-    for memory_dump, test_values in zip(memory_dumps, expected):
-      dump_id, start, duration = test_values
-      self.assertEquals(dump_id, memory_dump.dump_id)
-      self.assertAlmostEqual(start / 1000.0, memory_dump.start)
-      self.assertAlmostEqual(duration / 1000.0, memory_dump.duration)
-
-  def testMetadataImport(self):
-    events = [
-      {'cat': '__metadata', 'pid': 14689, 'tid': 14740, 'ts': 245,
-       'ph': 'M', 'name': 'process_name', 'args': {'name': 'Browser'}},
-      {'cat': '__metadata', 'pid': 23828, 'tid': 23828, 'ts': 0,
-       'ph': 'M', 'name': 'process_labels',
-       'args': {'labels': 'huge image - Google Search'}}
-    ]
-
-    expected = [
-      [None, 'Browser'],
-      ['huge image - Google Search', 'process 23828']
-    ]
-    trace_data = trace_data_module.CreateTraceDataFromRawData(events)
-    m = timeline_model.TimelineModel(trace_data)
-    processes = m.GetAllProcesses()
-
-    self.assertEqual(len(processes), len(expected))
-    for process, test_values in zip(processes, expected):
-      process_labels, process_name = test_values
-      self.assertEquals(process_labels, process.labels)
-      self.assertEquals(process_name, process.name)
diff --git a/catapult/telemetry/telemetry/timeline/tracing_config.py b/catapult/telemetry/telemetry/timeline/tracing_config.py
deleted file mode 100644
index 049f545..0000000
--- a/catapult/telemetry/telemetry/timeline/tracing_config.py
+++ /dev/null
@@ -1,103 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.timeline import atrace_config
-from telemetry.timeline import chrome_trace_config
-
-
-class TracingConfig(object):
-  """Tracing config is the configuration for tracing in Telemetry.
-
-  TracingConfig configures tracing in Telemetry. It contains tracing options
-  that control which core tracing system should be enabled. If a tracing
-  system requires additional configuration, e.g., what to trace, then it is
-  typically configured in its own config class. TracingConfig provides
-  interfaces to access the configuration for those tracing systems.
-
-  Options:
-      enable_atrace_trace: a boolean that specifies whether to enable
-          atrace tracing.
-      enable_cpu_trace: a boolean that specifies whether to enable cpu tracing.
-      enable_chrome_trace: a boolean that specifies whether to enable
-          chrome tracing.
-      enable_platform_display_trace: a boolean that specifies whether to
-          platform display tracing.
-      enable_android_graphics_memtrack: a boolean that specifies whether
-          to enable the memtrack_helper daemon to track graphics memory on
-          Android (see goo.gl/4Y30p9). Doesn't have any effects on other OSs.
-      enable_battor_trace: a boolean that specifies whether to enable BattOr
-          tracing.
-
-  Detailed configurations:
-      atrace_config: Stores configuration options specific to Atrace.
-      chrome_trace_config: Stores configuration options specific to
-          Chrome trace.
-  """
-
-  def __init__(self):
-    self._enable_atrace_trace = False
-    self._enable_platform_display_trace = False
-    self._enable_android_graphics_memtrack = False
-    self._enable_battor_trace = False
-    self._enable_cpu_trace = False
-    self._enable_chrome_trace = False
-
-    self._atrace_config = atrace_config.AtraceConfig()
-    self._chrome_trace_config = chrome_trace_config.ChromeTraceConfig()
-
-  @property
-  def enable_atrace_trace(self):
-    return self._enable_atrace_trace
-
-  @enable_atrace_trace.setter
-  def enable_atrace_trace(self, value):
-    self._enable_atrace_trace = value
-
-  @property
-  def enable_cpu_trace(self):
-    return self._enable_cpu_trace
-
-  @enable_cpu_trace.setter
-  def enable_cpu_trace(self, value):
-    self._enable_cpu_trace = value
-
-  @property
-  def enable_platform_display_trace(self):
-    return self._enable_platform_display_trace
-
-  @enable_platform_display_trace.setter
-  def enable_platform_display_trace(self, value):
-    self._enable_platform_display_trace = value
-
-  @property
-  def enable_android_graphics_memtrack(self):
-    return self._enable_android_graphics_memtrack
-
-  @enable_android_graphics_memtrack.setter
-  def enable_android_graphics_memtrack(self, value):
-    self._enable_android_graphics_memtrack = value
-
-  @property
-  def enable_battor_trace(self):
-    return self._enable_battor_trace
-
-  @enable_battor_trace.setter
-  def enable_battor_trace(self, value):
-    self._enable_battor_trace = value
-
-  @property
-  def enable_chrome_trace(self):
-    return self._enable_chrome_trace
-
-  @enable_chrome_trace.setter
-  def enable_chrome_trace(self, value):
-    self._enable_chrome_trace = value
-
-  @property
-  def atrace_config(self):
-    return self._atrace_config
-
-  @property
-  def chrome_trace_config(self):
-    return self._chrome_trace_config
diff --git a/catapult/telemetry/telemetry/util/__init__.py b/catapult/telemetry/telemetry/util/__init__.py
deleted file mode 100644
index 08483cc..0000000
--- a/catapult/telemetry/telemetry/util/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""A library for bootstrapping Telemetry performance testing."""
diff --git a/catapult/telemetry/telemetry/util/bot_utils.py b/catapult/telemetry/telemetry/util/bot_utils.py
deleted file mode 100644
index 70955f5..0000000
--- a/catapult/telemetry/telemetry/util/bot_utils.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Utility functions used to generate info used by the bots.
-
-TODO(eyaich): Remove once we no longer generate the list of benchmarks to
-run on the perf waterfall in telemetry.
-"""
-
-import hashlib
-
-def GetDeviceAffinity(num_shards, base_name):
-  # Based on the current timings, we shift the result of the hash function to
-  # achieve better load balancing. Those shift values are to be revised when
-  # necessary. The shift value is calculated such that the total cycle time
-  # is minimized.
-  hash_shift = {
-    2 : 47,  # for old desktop configurations with 2 slaves
-    5 : 56,  # for new desktop configurations with 5 slaves
-    21 : 43  # for Android 3 slaves 7 devices configurations
-  }
-  shift = hash_shift.get(num_shards, 0)
-  base_name_hash = hashlib.sha1(base_name).hexdigest()
-  device_affinity = (int(base_name_hash, 16) >> shift) % num_shards
-  return device_affinity
diff --git a/catapult/telemetry/telemetry/util/color_histogram.py b/catapult/telemetry/telemetry/util/color_histogram.py
deleted file mode 100644
index 76bb4b9..0000000
--- a/catapult/telemetry/telemetry/util/color_histogram.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Color Histograms and implementations of functions operating on them."""
-
-from __future__ import division
-
-import collections
-
-from telemetry.internal.util import external_modules
-
-np = external_modules.ImportOptionalModule('numpy')
-
-
-def HistogramDistance(hist1, hist2, default_color=None):
-  """Earth mover's distance.
-  http://en.wikipedia.org/wiki/Earth_mover's_distance"""
-  if len(hist1) != len(hist2):
-    raise ValueError('Trying to compare histograms '
-                     'of different sizes, %s != %s' % (len(hist1), len(hist2)))
-  if len(hist1) == 0:
-    return 0
-
-  sum_func = np.sum if np is not None else sum
-
-  n1 = sum_func(hist1)
-  n2 = sum_func(hist2)
-  if (n1 == 0 or n2 == 0) and default_color is None:
-    raise ValueError('Histogram has no data and no default color.')
-  if n1 == 0:
-    hist1[default_color] = 1
-    n1 = 1
-  if n2 == 0:
-    hist2[default_color] = 1
-    n2 = 1
-
-  if np is not None:
-    remainder = np.multiply(hist1, n2) - np.multiply(hist2, n1)
-    cumsum = np.cumsum(remainder)
-    total = np.sum(np.abs(cumsum))
-  else:
-    total = 0
-    remainder = 0
-    for value1, value2 in zip(hist1, hist2):
-      remainder += value1 * n2 - value2 * n1
-      total += abs(remainder)
-    assert remainder == 0, (
-        '%s pixel(s) left over after computing histogram distance.'
-        % abs(remainder))
-  return abs(float(total) / n1 / n2)
-
-
-class ColorHistogram(
-    collections.namedtuple('ColorHistogram', ['r', 'g', 'b', 'default_color'])):
-  # pylint: disable=no-init
-  # pylint: disable=super-on-old-class
-
-  def __new__(cls, r, g, b, default_color=None):
-    return super(ColorHistogram, cls).__new__(cls, r, g, b, default_color)
-
-  def Distance(self, other):
-    total = 0
-    for i in xrange(3):
-      default_color = self[3][i] if self[3] is not None else None
-      total += HistogramDistance(self[i], other[i], default_color)
-    return total
diff --git a/catapult/telemetry/telemetry/util/color_histogram_unittest.py b/catapult/telemetry/telemetry/util/color_histogram_unittest.py
deleted file mode 100644
index a853d53..0000000
--- a/catapult/telemetry/telemetry/util/color_histogram_unittest.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.util import color_histogram
-from telemetry.util import image_util
-from telemetry.util import rgba_color
-
-class HistogramDistanceTest(unittest.TestCase):
-  def testNoData(self):
-    hist1 = []
-    hist2 = []
-    self.assertEqual(color_histogram.HistogramDistance(hist1, hist2), 0)
-
-    hist1 = [0, 0, 0]
-    hist2 = [0, 0, 0]
-    self.assertRaises(
-        ValueError, lambda: color_histogram.HistogramDistance(hist1, hist2))
-
-  def testWrongSizes(self):
-    hist1 = [1]
-    hist2 = [1, 0]
-    self.assertRaises(
-        ValueError, lambda: color_histogram.HistogramDistance(hist1, hist2))
-
-  def testNoDistance(self):
-    hist1 = [2, 4, 1, 8, 0, 0]
-    hist2 = [2, 4, 1, 8, 0, 0]
-    self.assertEqual(color_histogram.HistogramDistance(hist1, hist2), 0)
-
-  def testNormalizeCounts(self):
-    hist1 = [0, 0, 1, 0, 0]
-    hist2 = [0, 0, 0, 0, 7]
-    self.assertEqual(color_histogram.HistogramDistance(hist1, hist2), 2)
-    self.assertEqual(color_histogram.HistogramDistance(hist2, hist1), 2)
-
-  def testDistance(self):
-    hist1 = [2, 0, 1, 3, 4]
-    hist2 = [3, 1, 2, 4, 0]
-    self.assertEqual(color_histogram.HistogramDistance(hist1, hist2), 1)
-    self.assertEqual(color_histogram.HistogramDistance(hist2, hist1), 1)
-
-    hist1 = [0, 1, 3, 1]
-    hist2 = [2, 2, 1, 0]
-    self.assertEqual(color_histogram.HistogramDistance(hist1, hist2), 1.2)
-    self.assertEqual(color_histogram.HistogramDistance(hist2, hist1), 1.2)
-
-
-class HistogramTest(unittest.TestCase):
-  def testHistogram(self):
-    pixels = [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3,
-              1, 2, 3, 8, 7, 6, 5, 4, 6, 1, 2, 3,
-              1, 2, 3, 8, 7, 6, 5, 4, 6, 1, 2, 3]
-    bmp = image_util.FromRGBPixels(4, 3, pixels)
-    bmp = image_util.Crop(bmp, 1, 1, 2, 2)
-
-    hist = image_util.GetColorHistogram(bmp)
-    for i in xrange(3):
-      self.assertEquals(sum(hist[i]),
-                        image_util.Width(bmp) * image_util.Height(bmp))
-    self.assertEquals(hist.r[1], 0)
-    self.assertEquals(hist.r[5], 2)
-    self.assertEquals(hist.r[8], 2)
-    self.assertEquals(hist.g[2], 0)
-    self.assertEquals(hist.g[4], 2)
-    self.assertEquals(hist.g[7], 2)
-    self.assertEquals(hist.b[3], 0)
-    self.assertEquals(hist.b[6], 4)
-
-  def testHistogramIgnoreColor(self):
-    pixels = [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3,
-              1, 2, 3, 8, 7, 6, 5, 4, 6, 1, 2, 3,
-              1, 2, 3, 8, 7, 6, 5, 4, 6, 1, 2, 3]
-    bmp = image_util.FromRGBPixels(4, 3, pixels)
-
-    hist = image_util.GetColorHistogram(
-        bmp, ignore_color=rgba_color.RgbaColor(1, 2, 3))
-    self.assertEquals(hist.r[1], 0)
-    self.assertEquals(hist.r[5], 2)
-    self.assertEquals(hist.r[8], 2)
-    self.assertEquals(hist.g[2], 0)
-    self.assertEquals(hist.g[4], 2)
-    self.assertEquals(hist.g[7], 2)
-    self.assertEquals(hist.b[3], 0)
-    self.assertEquals(hist.b[6], 4)
-
-  def testHistogramIgnoreColorTolerance(self):
-    pixels = [1, 2, 3, 4, 5, 6,
-              7, 8, 9, 8, 7, 6]
-    bmp = image_util.FromRGBPixels(2, 2, pixels)
-
-    hist = image_util.GetColorHistogram(
-        bmp, ignore_color=rgba_color.RgbaColor(0, 1, 2), tolerance=1)
-    self.assertEquals(hist.r[1], 0)
-    self.assertEquals(hist.r[4], 1)
-    self.assertEquals(hist.r[7], 1)
-    self.assertEquals(hist.r[8], 1)
-    self.assertEquals(hist.g[2], 0)
-    self.assertEquals(hist.g[5], 1)
-    self.assertEquals(hist.g[7], 1)
-    self.assertEquals(hist.g[8], 1)
-    self.assertEquals(hist.b[3], 0)
-    self.assertEquals(hist.b[6], 2)
-    self.assertEquals(hist.b[9], 1)
-
-  def testHistogramDistanceIgnoreColor(self):
-    pixels = [1, 2, 3, 1, 2, 3,
-              1, 2, 3, 1, 2, 3]
-    bmp = image_util.FromRGBPixels(2, 2, pixels)
-
-    hist1 = image_util.GetColorHistogram(
-        bmp, ignore_color=rgba_color.RgbaColor(1, 2, 3))
-    hist2 = image_util.GetColorHistogram(bmp)
-
-    self.assertEquals(hist1.Distance(hist2), 0)
diff --git a/catapult/telemetry/telemetry/util/command_line.py b/catapult/telemetry/telemetry/util/command_line.py
deleted file mode 100644
index faf870f..0000000
--- a/catapult/telemetry/telemetry/util/command_line.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-
-from telemetry.internal.util import command_line
-
-
-class ArgParseCommand(command_line.Command):
-  usage = ''
-
-  @classmethod
-  def CreateParser(cls):
-    return argparse.ArgumentParser('%%prog %s %s' % (cls.Name(), cls.usage),
-                                   description=cls.Description())
-
-  @classmethod
-  def AddCommandLineArgs(cls, parser, environment):
-    # pylint: disable=arguments-differ
-    pass
-
-  @classmethod
-  def ProcessCommandLineArgs(cls, parser, options, extra_args, environment):
-    # pylint: disable=arguments-differ
-    pass
-
-  def Run(self, options, extra_args=None):
-    # pylint: disable=arguments-differ
-    raise NotImplementedError()
-
-  @classmethod
-  def main(cls, args=None):
-    """Main method to run this command as a standalone script."""
-    parser = cls.CreateParser()
-    cls.AddCommandLineArgs(parser, None)
-    options, extra_args = parser.parse_known_args(args=args)
-    cls.ProcessCommandLineArgs(parser, options, extra_args, None)
-    return min(cls().Run(options, extra_args), 255)
diff --git a/catapult/telemetry/telemetry/util/dependency.py b/catapult/telemetry/telemetry/util/dependency.py
deleted file mode 100644
index 9ff2ee6..0000000
--- a/catapult/telemetry/telemetry/util/dependency.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.core import platform as platform_module
-from telemetry.internal.util import binary_manager
-
-def FetchTelemetryDependencies(
-  platform=None, client_configs=None, chrome_reference_browser=False):
-  if not platform:
-    platform = platform_module.GetHostPlatform()
-  if binary_manager.NeedsInit():
-    binary_manager.InitDependencyManager(client_configs)
-  else:
-    raise Exception('Binary manager already initialized with other configs.')
-  binary_manager.FetchBinaryDependencies(
-    platform, client_configs, chrome_reference_browser)
diff --git a/catapult/telemetry/telemetry/util/image_util.py b/catapult/telemetry/telemetry/util/image_util.py
deleted file mode 100644
index 809dc57..0000000
--- a/catapult/telemetry/telemetry/util/image_util.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides implementations of basic image processing functions.
-
-Implements basic image processing functions, such as reading/writing images,
-cropping, finding the bounding box of a color and diffing images.
-
-When numpy is present, image_util_numpy_impl is used for the implementation of
-this interface. The old bitmap implementation (image_util_bitmap_impl) is used
-as a fallback when numpy is not present."""
-
-import base64
-
-from telemetry.internal.util import external_modules
-
-np = external_modules.ImportOptionalModule('numpy')
-
-if np is None:
-  from telemetry.internal.image_processing import image_util_bitmap_impl
-  impl = image_util_bitmap_impl
-else:
-  from telemetry.internal.image_processing import image_util_numpy_impl
-  impl = image_util_numpy_impl
-
-
-def Channels(image):
-  """Number of color channels in the image."""
-  return impl.Channels(image)
-
-def Width(image):
-  """Width of the image."""
-  return impl.Width(image)
-
-def Height(image):
-  """Height of the image."""
-  return impl.Height(image)
-
-def Pixels(image):
-  """Flat RGB pixel array of the image."""
-  return impl.Pixels(image)
-
-def GetPixelColor(image, x, y):
-  """Returns a RgbaColor for the pixel at (x, y)."""
-  return impl.GetPixelColor(image, x, y)
-
-def WritePngFile(image, path):
-  """Write an image to a PNG file.
-
-  Args:
-    image: an image object.
-    path: The path to the PNG file. Must end in 'png' or an
-          AssertionError will be raised."""
-  assert path.endswith('png')
-  return impl.WritePngFile(image, path)
-
-def FromRGBPixels(width, height, pixels, bpp=3):
-  """Create an image from an array of rgb pixels.
-
-  Ignores alpha channel if present.
-
-  Args:
-    width, height: int, the width and height of the image.
-    pixels: The flat array of pixels in the form of [r,g,b[,a],r,g,b[,a],...]
-    bpp: 3 for RGB, 4 for RGBA."""
-  return impl.FromRGBPixels(width, height, pixels, bpp)
-
-def FromPng(png_data):
-  """Create an image from raw PNG data."""
-  return impl.FromPng(png_data)
-
-def FromPngFile(path):
-  """Create an image from a PNG file.
-
-  Args:
-    path: The path to the PNG file."""
-  return impl.FromPngFile(path)
-
-def FromBase64Png(base64_png):
-  """Create an image from raw PNG data encoded in base64."""
-  return FromPng(base64.b64decode(base64_png))
-
-def AreEqual(image1, image2, tolerance=0, likely_equal=True):
-  """Determines whether two images are identical within a given tolerance.
-  Setting likely_equal to False enables short-circuit equality testing, which
-  is about 2-3x slower for equal images, but can be image height times faster
-  if the images are not equal."""
-  return impl.AreEqual(image1, image2, tolerance, likely_equal)
-
-def Diff(image1, image2):
-  """Returns a new image that represents the difference between this image
-  and another image."""
-  return impl.Diff(image1, image2)
-
-def GetBoundingBox(image, color, tolerance=0):
-  """Finds the minimum box surrounding all occurrences of bgr |color|.
-
-  Ignores the alpha channel.
-
-  Args:
-    color: RbgaColor, bounding box color.
-    tolerance: int, per-channel tolerance for the bounding box color.
-
-  Returns:
-    (top, left, width, height), match_count"""
-  return impl.GetBoundingBox(image, color, tolerance)
-
-def Crop(image, left, top, width, height):
-  """Crops the current image down to the specified box."""
-  return impl.Crop(image, left, top, width, height)
-
-def GetColorHistogram(image, ignore_color=None, tolerance=0):
-  """Computes a histogram of the pixel colors in this image.
-  Args:
-    ignore_color: An RgbaColor to exclude from the bucket counts.
-    tolerance: A tolerance for the ignore_color.
-
-  Returns:
-    A ColorHistogram namedtuple with 256 integers in each field: r, g, and b."""
-  return impl.GetColorHistogram(image, ignore_color, tolerance)
diff --git a/catapult/telemetry/telemetry/util/image_util_unittest.py b/catapult/telemetry/telemetry/util/image_util_unittest.py
deleted file mode 100644
index 4cb10e6..0000000
--- a/catapult/telemetry/telemetry/util/image_util_unittest.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import tempfile
-import unittest
-
-from telemetry.core import util
-from telemetry.util import image_util
-from telemetry.util import rgba_color
-
-# This is a simple base64 encoded 2x2 PNG which contains, in order, a single
-# Red, Yellow, Blue, and Green pixel.
-test_png = """
- iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91
- JpzAAAAFklEQVR4Xg3EAQ0AAABAMP1LY3YI7l8l6A
- T8tgwbJAAAAABJRU5ErkJggg==
-"""
-test_png_path = os.path.join(util.GetUnittestDataDir(), 'test_png.png')
-test_png_2_path = os.path.join(util.GetUnittestDataDir(), 'test_png_2.png')
-
-class ImageUtilTest(unittest.TestCase):
-  def testReadFromBase64Png(self):
-    bmp = image_util.FromBase64Png(test_png)
-
-    self.assertEquals(2, image_util.Width(bmp))
-    self.assertEquals(2, image_util.Height(bmp))
-
-    image_util.GetPixelColor(bmp, 0, 0).AssertIsRGB(255, 0, 0)
-    image_util.GetPixelColor(bmp, 1, 1).AssertIsRGB(0, 255, 0)
-    image_util.GetPixelColor(bmp, 0, 1).AssertIsRGB(0, 0, 255)
-    image_util.GetPixelColor(bmp, 1, 0).AssertIsRGB(255, 255, 0)
-
-  def testReadFromPngFile(self):
-    file_bmp = image_util.FromPngFile(test_png_path)
-
-    self.assertEquals(2, image_util.Width(file_bmp))
-    self.assertEquals(2, image_util.Height(file_bmp))
-
-    image_util.GetPixelColor(file_bmp, 0, 0).AssertIsRGB(255, 0, 0)
-    image_util.GetPixelColor(file_bmp, 1, 1).AssertIsRGB(0, 255, 0)
-    image_util.GetPixelColor(file_bmp, 0, 1).AssertIsRGB(0, 0, 255)
-    image_util.GetPixelColor(file_bmp, 1, 0).AssertIsRGB(255, 255, 0)
-
-  def testWritePngToPngFile(self):
-    orig = image_util.FromPngFile(test_png_path)
-    temp_file = tempfile.NamedTemporaryFile(suffix='.png').name
-    image_util.WritePngFile(orig, temp_file)
-    new_file = image_util.FromPngFile(temp_file)
-    self.assertTrue(image_util.AreEqual(orig, new_file, likely_equal=True))
-
-  def testWritePngWithoutPngSuffixThrows(self):
-    orig = image_util.FromPngFile(test_png_path)
-    temp_file = tempfile.NamedTemporaryFile().name
-    self.assertRaises(AssertionError, image_util.WritePngFile,
-                      orig, temp_file)
-
-  def testWriteCroppedBmpToPngFile(self):
-    pixels = [255, 0, 0, 255, 255, 0, 0, 0, 0,
-              255, 255, 0, 0, 255, 0, 0, 0, 0]
-    orig = image_util.FromRGBPixels(3, 2, pixels)
-    orig = image_util.Crop(orig, 0, 0, 2, 2)
-    temp_file = tempfile.NamedTemporaryFile(suffix='.png').name
-    image_util.WritePngFile(orig, temp_file)
-    new_file = image_util.FromPngFile(temp_file)
-    self.assertTrue(image_util.AreEqual(orig, new_file, likely_equal=True))
-
-  def testIsEqual(self):
-    bmp = image_util.FromBase64Png(test_png)
-    file_bmp = image_util.FromPngFile(test_png_path)
-    self.assertTrue(image_util.AreEqual(bmp, file_bmp, likely_equal=True))
-
-  def testDiff(self):
-    file_bmp = image_util.FromPngFile(test_png_path)
-    file_bmp_2 = image_util.FromPngFile(test_png_2_path)
-
-    diff_bmp = image_util.Diff(file_bmp, file_bmp)
-
-    self.assertEquals(2, image_util.Width(diff_bmp))
-    self.assertEquals(2, image_util.Height(diff_bmp))
-
-    image_util.GetPixelColor(diff_bmp, 0, 0).AssertIsRGB(0, 0, 0)
-    image_util.GetPixelColor(diff_bmp, 1, 1).AssertIsRGB(0, 0, 0)
-    image_util.GetPixelColor(diff_bmp, 0, 1).AssertIsRGB(0, 0, 0)
-    image_util.GetPixelColor(diff_bmp, 1, 0).AssertIsRGB(0, 0, 0)
-
-    diff_bmp = image_util.Diff(file_bmp, file_bmp_2)
-
-    self.assertEquals(3, image_util.Width(diff_bmp))
-    self.assertEquals(3, image_util.Height(diff_bmp))
-
-    image_util.GetPixelColor(diff_bmp, 0, 0).AssertIsRGB(0, 255, 255)
-    image_util.GetPixelColor(diff_bmp, 1, 1).AssertIsRGB(255, 0, 255)
-    image_util.GetPixelColor(diff_bmp, 0, 1).AssertIsRGB(255, 255, 0)
-    image_util.GetPixelColor(diff_bmp, 1, 0).AssertIsRGB(0, 0, 255)
-
-    image_util.GetPixelColor(diff_bmp, 0, 2).AssertIsRGB(255, 255, 255)
-    image_util.GetPixelColor(diff_bmp, 1, 2).AssertIsRGB(255, 255, 255)
-    image_util.GetPixelColor(diff_bmp, 2, 0).AssertIsRGB(255, 255, 255)
-    image_util.GetPixelColor(diff_bmp, 2, 1).AssertIsRGB(255, 255, 255)
-    image_util.GetPixelColor(diff_bmp, 2, 2).AssertIsRGB(255, 255, 255)
-
-  def testGetBoundingBox(self):
-    pixels = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
-              0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0,
-              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-    bmp = image_util.FromRGBPixels(4, 3, pixels)
-    box, count = image_util.GetBoundingBox(bmp, rgba_color.RgbaColor(1, 0, 0))
-    self.assertEquals(box, (1, 1, 2, 1))
-    self.assertEquals(count, 2)
-
-    box, count = image_util.GetBoundingBox(bmp, rgba_color.RgbaColor(0, 1, 0))
-    self.assertEquals(box, None)
-    self.assertEquals(count, 0)
-
-  def testCrop(self):
-    pixels = [0, 0, 0, 1, 0, 0, 2, 0, 0, 3, 0, 0,
-              0, 1, 0, 1, 1, 0, 2, 1, 0, 3, 1, 0,
-              0, 2, 0, 1, 2, 0, 2, 2, 0, 3, 2, 0]
-    bmp = image_util.FromRGBPixels(4, 3, pixels)
-    bmp = image_util.Crop(bmp, 1, 2, 2, 1)
-
-    self.assertEquals(2, image_util.Width(bmp))
-    self.assertEquals(1, image_util.Height(bmp))
-    image_util.GetPixelColor(bmp, 0, 0).AssertIsRGB(1, 2, 0)
-    image_util.GetPixelColor(bmp, 1, 0).AssertIsRGB(2, 2, 0)
-    self.assertEquals(image_util.Pixels(bmp), bytearray([1, 2, 0, 2, 2, 0]))
diff --git a/catapult/telemetry/telemetry/util/js_template.py b/catapult/telemetry/telemetry/util/js_template.py
deleted file mode 100644
index 8e23f5c..0000000
--- a/catapult/telemetry/telemetry/util/js_template.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import re
-
-
-RE_REPLACEMENT_FIELD = re.compile(r'{{(?P<field_spec>[^}]*)}}')
-RE_FIELD_IDENTIFIER = re.compile(r'(?P<modifier>[@*])?(?P<name>\w+)$')
-
-
-def RenderValue(value):
-  """Convert a Python value to a string with its JavaScript representation."""
-  return json.dumps(value, sort_keys=True)
-
-
-def Render(template, **kwargs):
-  """Helper method to interpolate Python values into JavaScript snippets.
-
-  Placeholders in the template, field names enclosed in double curly braces,
-  are replaced with the value of the corresponding named argument.
-
-  Prefixing a field name with '*' causes the value, expected to be a
-  sequence of individual values, to be all interpolated and separated by
-  commas.
-
-  Prefixing a field name with '@' causes the value to be inserted literally.
-
-
-  For example:
-
-    js_template.Render(
-      'var {{ @var_name }} = f({{ x }}, {{ *args }});',
-      var_name='foo', x=42, args=('hello', 'there'))
-
-  Returns:
-
-    'var foo = f(42, "hello", "there");'
-
-  Args:
-    template: A string with a JavaScript template, tagged with {{ fields }}
-      to interpolate with values.
-    **kwargs: Values to be interpolated in the template.
-  """
-  unused = set(kwargs)
-
-  def interpolate(m):
-    field_spec = m.group('field_spec').strip()
-    field = RE_FIELD_IDENTIFIER.match(field_spec)
-    if not field:
-      raise KeyError(field_spec)
-    key = field.group('name')
-    value = kwargs[key]
-    unused.discard(key)
-    if field.group('modifier') == '@':
-      if not isinstance(value, str):
-        raise ValueError('Literal value for %s must be a string' % field_spec)
-      return value
-    elif field.group('modifier') == '*':
-      return ', '.join(RenderValue(v) for v in value)
-    else:
-      return RenderValue(value)
-
-  result = RE_REPLACEMENT_FIELD.sub(interpolate, template)
-  if unused:
-    raise TypeError('Unexpected arguments not used in template: %s.' % (
-      ', '.join(repr(str(k)) for k in sorted(unused))))
-  return result
diff --git a/catapult/telemetry/telemetry/util/js_template_unittest.py b/catapult/telemetry/telemetry/util/js_template_unittest.py
deleted file mode 100644
index b233a8a..0000000
--- a/catapult/telemetry/telemetry/util/js_template_unittest.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.util import js_template
-
-
-class JavaScriptTemplateTest(unittest.TestCase):
-  def testRenderSimple(self):
-    self.assertEquals(
-        js_template.Render(
-            'foo({{ a }}, {{ b }}, {{ c }})',
-            a=42, b='hello', c=['x', 'y']),
-        'foo(42, "hello", ["x", "y"])')
-
-  def testRenderWithSpecialCharts(self):
-    self.assertEquals(
-        js_template.Render(
-            'function(elem) { return elem.find({{ selector }}); }',
-            selector='.r > a[href*="wikipedia"]'),
-        r'function(elem) { return elem.find(".r > a[href*=\"wikipedia\"]"); }')
-
-  def testRenderWithLiteralValues(self):
-    self.assertEquals(
-        js_template.Render(
-            'var {{ @var_name }} = {{ x }} + {{ y }};',
-            var_name='foo', x='bar', y=None),
-        'var foo = "bar" + null;')
-
-  def testRenderWithArgumentExpansion(self):
-    self.assertEquals(
-        js_template.Render(
-            '{{ @f }}({{ *args }})', f='foo', args=(1, 'hi!', None)),
-        'foo(1, "hi!", null)')
-
-  def testRenderRaisesWithUnknownIdentifier(self):
-    with self.assertRaises(KeyError):
-      js_template.Render('foo({{ some_name }})', another_name='bar')
-
-  def testRenderRaisesWithBadIdentifier(self):
-    with self.assertRaises(KeyError):
-      js_template.Render('foo({{ bad identifier name }})', name='bar')
-
-  def testRenderRaisesWithBadLiteralValue(self):
-    with self.assertRaises(ValueError):
-      js_template.Render('function() { {{ @code }} }', code=['foo', 'bar'])
-
-  def testRenderRaisesWithUnusedKeywordArgs(self):
-    with self.assertRaises(TypeError):
-      js_template.Render('foo = {{ x }};', x=4, y=5, timemout=6)
diff --git a/catapult/telemetry/telemetry/util/mac/README b/catapult/telemetry/telemetry/util/mac/README
deleted file mode 100644
index 0c5538b..0000000
--- a/catapult/telemetry/telemetry/util/mac/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This directory contains files needed to run Chrome browser Telemetry tests on
-OSX.
diff --git a/catapult/telemetry/telemetry/util/mac/__init__.py b/catapult/telemetry/telemetry/util/mac/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/catapult/telemetry/telemetry/util/mac/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/util/mac/determine_if_keychain_entry_is_decryptable.c b/catapult/telemetry/telemetry/util/mac/determine_if_keychain_entry_is_decryptable.c
deleted file mode 100644
index 5facb61..0000000
--- a/catapult/telemetry/telemetry/util/mac/determine_if_keychain_entry_is_decryptable.c
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This program determines whether a specific entry in the default OSX Keychain
-// is decryptable by all applications without a user prompt.
-//
-// This program uses APIs only available on OSX 10.7+.
-//
-// Input format:
-//  determine_if_keychain_entry_is_decryptable [service name] [account name]
-//
-// Return values:
-//   0 - The entry doesn't exist, or the ACLs are correct.
-//   1 - The ACLs are incorrect.
-//   >=2 - Unexpected error.
-//
-// To compile, run: "clang -framework Security -framework CoreFoundation
-//                   -o determine_if_keychain_entry_is_decryptable
-//                   determine_if_keychain_entry_is_decryptable.c"
-
-#include <CoreFoundation/CoreFoundation.h>
-#include <Security/Security.h>
-#include <string.h>
-
-int main(int argc, char* argv[]) {
-  // There must be exactly 2 arguments to the program.
-  if (argc != 3)
-    return 2;
-
-  const char* service_name = argv[1];
-  const char* account_name = argv[2];
-  SecKeychainItemRef item;
-  OSStatus status = SecKeychainFindGenericPassword(NULL, strlen(service_name),
-      service_name, strlen(account_name), account_name, NULL, NULL, &item);
-
-  // There is no keychain item.
-  if (status == errSecItemNotFound)
-    return 0;
-
-  // Unexpected error.
-  if (status != errSecSuccess)
-    return 3;
-
-  SecAccessRef access;
-  status = SecKeychainItemCopyAccess(item, &access);
-
-  // Unexpected error.
-  if (status != errSecSuccess) {
-    CFRelease(access);
-    CFRelease(item);
-    return 4;
-  }
-
-  CFArrayRef acl_list =
-      SecAccessCopyMatchingACLList(access, kSecACLAuthorizationDecrypt);
-
-  for (CFIndex i = 0; i < CFArrayGetCount(acl_list); ++i) {
-    SecACLRef acl = (SecACLRef)CFArrayGetValueAtIndex(acl_list, i);
-
-    CFArrayRef application_list;
-    CFStringRef description;
-    SecKeychainPromptSelector prompt_selector;
-    status = SecACLCopyContents(acl, &application_list, &description,
-                                &prompt_selector);
-
-    // Unexpected error.
-    if (status != errSecSuccess) {
-      CFRelease(acl_list);
-      CFRelease(access);
-      CFRelease(item);
-      return 5;
-    }
-
-    // Check whether this acl gives decryption access to all applications.
-    bool found_correct_acl = (application_list == NULL);
-    CFRelease(description);
-    if (application_list)
-      CFRelease(application_list);
-
-    if (found_correct_acl) {
-      CFRelease(acl_list);
-      CFRelease(access);
-      CFRelease(item);
-      return 0;
-    }
-  }
-
-  // No acl was found that gave decryption access to all applications.
-  CFRelease(acl_list);
-  CFRelease(access);
-  CFRelease(item);
-  return 1;
-}
diff --git a/catapult/telemetry/telemetry/util/mac/determine_if_keychain_is_locked.c b/catapult/telemetry/telemetry/util/mac/determine_if_keychain_is_locked.c
deleted file mode 100644
index ddf0aff..0000000
--- a/catapult/telemetry/telemetry/util/mac/determine_if_keychain_is_locked.c
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-// This program determines whether the default OSX Keychain is unlocked without
-// causing a user interaction prompt.
-// Return values:
-//   0 - The default keychain is unlocked.
-//   1 - The default keychain is locked.
-//   2 - Unexpected error.
-//
-// To compile, run: "clang -framework Security
-//                   -o determine_if_keychain_is_locked
-//                   determine_if_keychain_is_locked.c"
-
-#include <Security/Security.h>
-
-int main() {
-  SecKeychainStatus keychain_status;
-  OSStatus os_status = SecKeychainGetStatus(NULL, &keychain_status);
-  if (os_status != errSecSuccess)
-    return 2;
-
-  return (keychain_status & kSecUnlockStateStatus) ? 0 : 1;
-}
diff --git a/catapult/telemetry/telemetry/util/mac/keychain_helper.py b/catapult/telemetry/telemetry/util/mac/keychain_helper.py
deleted file mode 100644
index 40219ea..0000000
--- a/catapult/telemetry/telemetry/util/mac/keychain_helper.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import subprocess
-
-from telemetry.internal.util import binary_manager
-from telemetry.core import platform
-from telemetry.core import os_version
-
-def _PathForExecutable(executable_name):
-  """Fetches the executable from cloud storage, and returns its path."""
-  arch_name = platform.GetHostPlatform().GetArchName()
-  return binary_manager.FetchPath(executable_name, arch_name, 'mac')
-
-def IsKeychainLocked():
-  """
-  Returns True if the keychain is locked, or if there is an error determining
-  the keychain state.
-  """
-  path = _PathForExecutable('determine_if_keychain_is_locked')
-
-  child = subprocess.Popen(path, stdout=subprocess.PIPE)
-  child.communicate()
-  return child.returncode != 0
-
-def DoesKeychainHaveTimeout():
-  """
-  Returns True if the keychain will lock itself have a period of time.
-
-  This method will trigger a blocking, modal dialog if the keychain is
-  locked.
-  """
-  command = ("/usr/bin/security", "show-keychain-info")
-  child = subprocess.Popen(command, stderr=subprocess.PIPE)
-  stderr = child.communicate()[1]
-  return "no-timeout" not in stderr
-
-def _IsKeychainConfiguredForBots(service_name, account_name):
-  """
-  Returns True if the keychain entry associated with |service_name| and
-  |account_name| is correctly configured for running telemetry tests on bots.
-
-  This method will trigger a blocking, modal dialog if the keychain is
-  locked.
-  """
-  # The executable requires OSX 10.7+ APIs.
-  if (platform.GetHostPlatform().GetOSVersionName() <
-      os_version.LION):
-    return False
-
-  path = _PathForExecutable('determine_if_keychain_entry_is_decryptable')
-
-  command = (path, service_name, account_name)
-  child = subprocess.Popen(command)
-  child.communicate()
-  return child.returncode == 0
-
-def IsKeychainConfiguredForBotsWithChrome():
-  return _IsKeychainConfiguredForBots("Chrome Safe Storage",
-      "Chrome")
-
-def IsKeychainConfiguredForBotsWithChromium():
-  return _IsKeychainConfiguredForBots("Chromium Safe Storage",
-      "Chromium")
diff --git a/catapult/telemetry/telemetry/util/matching.py b/catapult/telemetry/telemetry/util/matching.py
deleted file mode 100644
index 1ecd182..0000000
--- a/catapult/telemetry/telemetry/util/matching.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import difflib
-
-
-def GetMostLikelyMatchedObject(objects, target_name,
-                               name_func=lambda x: x,
-                               matched_score_threshold=0.4):
-  """Matches objects whose names are most likely matched with target.
-
-  Args:
-    objects: list of objects to match.
-    target_name: name to match.
-    name_func: function to get object name to match. Default bypass.
-    matched_score_threshold: threshold of likelihood to match.
-
-  Returns:
-    A list of objects whose names are likely target_name.
-  """
-  def MatchScore(obj):
-    return difflib.SequenceMatcher(
-        isjunk=None, a=name_func(obj), b=target_name).ratio()
-  object_score = [(o, MatchScore(o)) for o in objects]
-  result = [x for x in object_score if x[1] > matched_score_threshold]
-  return [x[0] for x in sorted(result, key=lambda r: r[1], reverse=True)]
diff --git a/catapult/telemetry/telemetry/util/matching_unittest.py b/catapult/telemetry/telemetry/util/matching_unittest.py
deleted file mode 100644
index a43c044..0000000
--- a/catapult/telemetry/telemetry/util/matching_unittest.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.util import matching
-
-
-class BenchmarkFoo(object):
-  """ Benchmark Foo for testing."""
-  @classmethod
-  def Name(cls):
-    return 'FooBenchmark'
-
-
-class BenchmarkBar(object):
-  """ Benchmark Bar for testing long description line."""
-  @classmethod
-  def Name(cls):
-    return 'BarBenchmarkkkkk'
-
-
-class UnusualBenchmark(object):
-  @classmethod
-  def Name(cls):
-    return 'I have a very unusual name'
-
-
-class CommandLineUnittest(unittest.TestCase):
-  def testGetMostLikelyMatchedObject(self):
-    # Test moved from telemetry/benchmark_runner_unittest.py
-    all_benchmarks = [BenchmarkFoo, BenchmarkBar, UnusualBenchmark]
-    self.assertEquals(
-        [BenchmarkFoo, BenchmarkBar],
-        matching.GetMostLikelyMatchedObject(
-            all_benchmarks, 'BenchmarkFooz', name_func=lambda x: x.Name()))
-
-    self.assertEquals(
-        [BenchmarkBar, BenchmarkFoo],
-        matching.GetMostLikelyMatchedObject(
-            all_benchmarks, 'BarBenchmark', name_func=lambda x: x.Name()))
-
-    self.assertEquals(
-        [UnusualBenchmark],
-        matching.GetMostLikelyMatchedObject(
-            all_benchmarks, 'unusual', name_func=lambda x: x.Name()))
diff --git a/catapult/telemetry/telemetry/util/perf_result_data_type.py b/catapult/telemetry/telemetry/util/perf_result_data_type.py
deleted file mode 100644
index dbaf794..0000000
--- a/catapult/telemetry/telemetry/util/perf_result_data_type.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-DEFAULT = 'default'
-UNIMPORTANT = 'unimportant'
-HISTOGRAM = 'histogram'
-UNIMPORTANT_HISTOGRAM = 'unimportant-histogram'
-INFORMATIONAL = 'informational'
-
-ALL_TYPES = [DEFAULT, UNIMPORTANT, HISTOGRAM, UNIMPORTANT_HISTOGRAM,
-             INFORMATIONAL]
-
-
-def IsValidType(datatype):
-  return datatype in ALL_TYPES
-
-
-def IsHistogram(datatype):
-  return datatype == HISTOGRAM or datatype == UNIMPORTANT_HISTOGRAM
diff --git a/catapult/telemetry/telemetry/util/perf_tests_helper.py b/catapult/telemetry/telemetry/util/perf_tests_helper.py
deleted file mode 100644
index aaf51be..0000000
--- a/catapult/telemetry/telemetry/util/perf_tests_helper.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from telemetry.util import perf_tests_results_helper
-
-
-FlattenList = \
-    perf_tests_results_helper.FlattenList
-GeomMeanAndStdDevFromHistogram = \
-    perf_tests_results_helper.GeomMeanAndStdDevFromHistogram
-PrintPerfResult = \
-    perf_tests_results_helper.PrintPerfResult
-PrintPages = \
-    perf_tests_results_helper.PrintPages
diff --git a/catapult/telemetry/telemetry/util/perf_tests_results_helper.py b/catapult/telemetry/telemetry/util/perf_tests_results_helper.py
deleted file mode 100644
index 72ccfb0..0000000
--- a/catapult/telemetry/telemetry/util/perf_tests_results_helper.py
+++ /dev/null
@@ -1,165 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-import sys
-
-import json
-import math
-
-from telemetry.util import perf_result_data_type
-
-
-# Mapping from result type to test output
-RESULT_TYPES = {perf_result_data_type.UNIMPORTANT: 'RESULT ',
-                perf_result_data_type.DEFAULT: '*RESULT ',
-                perf_result_data_type.INFORMATIONAL: '',
-                perf_result_data_type.UNIMPORTANT_HISTOGRAM: 'HISTOGRAM ',
-                perf_result_data_type.HISTOGRAM: '*HISTOGRAM '}
-
-
-def _EscapePerfResult(s):
-  """Escapes |s| for use in a perf result."""
-  return re.sub(r'[\:|=/#&,]', '_', s)
-
-
-def FlattenList(values):
-  """Returns a simple list without sub-lists."""
-  ret = []
-  for entry in values:
-    if isinstance(entry, list):
-      ret.extend(FlattenList(entry))
-    else:
-      ret.append(entry)
-  return ret
-
-
-def GeomMeanAndStdDevFromHistogram(histogram_json):
-  histogram = json.loads(histogram_json)
-  # Handle empty histograms gracefully.
-  if not 'buckets' in histogram:
-    return 0.0, 0.0
-  count = 0
-  sum_of_logs = 0
-  for bucket in histogram['buckets']:
-    if 'high' in bucket:
-      bucket['mean'] = (bucket['low'] + bucket['high']) / 2.0
-    else:
-      bucket['mean'] = bucket['low']
-    if bucket['mean'] > 0:
-      sum_of_logs += math.log(bucket['mean']) * bucket['count']
-      count += bucket['count']
-
-  if count == 0:
-    return 0.0, 0.0
-
-  sum_of_squares = 0
-  geom_mean = math.exp(sum_of_logs / count)
-  for bucket in histogram['buckets']:
-    if bucket['mean'] > 0:
-      sum_of_squares += (bucket['mean'] - geom_mean) ** 2 * bucket['count']
-  return geom_mean, math.sqrt(sum_of_squares / count)
-
-
-def _ValueToString(v):
-  # Special case for floats so we don't print using scientific notation.
-  if isinstance(v, float):
-    return '%f' % v
-  else:
-    return str(v)
-
-
-def _MeanAndStdDevFromList(values):
-  avg = None
-  sd = None
-  if len(values) > 1:
-    try:
-      value = '[%s]' % ','.join([_ValueToString(v) for v in values])
-      avg = sum([float(v) for v in values]) / len(values)
-      sqdiffs = [(float(v) - avg) ** 2 for v in values]
-      variance = sum(sqdiffs) / (len(values) - 1)
-      sd = math.sqrt(variance)
-    except ValueError:
-      value = ', '.join(values)
-  else:
-    value = values[0]
-  return value, avg, sd
-
-
-def PrintPages(page_list):
-  """Prints list of pages to stdout in the format required by perf tests."""
-  print 'Pages: [%s]' % ','.join([_EscapePerfResult(p) for p in page_list])
-
-
-def PrintPerfResult(measurement, trace, values, units,
-                    result_type=perf_result_data_type.DEFAULT,
-                    print_to_stdout=True):
-  """Prints numerical data to stdout in the format required by perf tests.
-
-  The string args may be empty but they must not contain any colons (:) or
-  equals signs (=).
-  This is parsed by the buildbot using:
-  http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/slave/process_log_utils.py
-
-  Args:
-    measurement: A description of the quantity being measured, e.g. "vm_peak".
-        On the dashboard, this maps to a particular graph. Mandatory.
-    trace: A description of the particular data point, e.g. "reference".
-        On the dashboard, this maps to a particular "line" in the graph.
-        Mandatory.
-    values: A list of numeric measured values. An N-dimensional list will be
-        flattened and treated as a simple list.
-    units: A description of the units of measure, e.g. "bytes".
-    result_type: Accepts values of perf_result_data_type.ALL_TYPES.
-    print_to_stdout: If True, prints the output in stdout instead of returning
-        the output to caller.
-
-    Returns:
-      String of the formated perf result.
-  """
-  assert perf_result_data_type.IsValidType(result_type), \
-         'result type: %s is invalid' % result_type
-
-  trace_name = _EscapePerfResult(trace)
-
-  if (result_type == perf_result_data_type.UNIMPORTANT or
-      result_type == perf_result_data_type.DEFAULT or
-      result_type == perf_result_data_type.INFORMATIONAL):
-    assert isinstance(values, list)
-    assert '/' not in measurement
-    flattened_values = FlattenList(values)
-    assert len(flattened_values)
-    value, avg, sd = _MeanAndStdDevFromList(flattened_values)
-    output = '%s%s: %s%s%s %s' % (
-        RESULT_TYPES[result_type],
-        _EscapePerfResult(measurement),
-        trace_name,
-        # Do not show equal sign if the trace is empty. Usually it happens when
-        # measurement is enough clear to describe the result.
-        '= ' if trace_name else '',
-        value,
-        units)
-  else:
-    assert perf_result_data_type.IsHistogram(result_type)
-    assert isinstance(values, list)
-    # The histograms can only be printed individually, there's no computation
-    # across different histograms.
-    assert len(values) == 1
-    value = values[0]
-    output = '%s%s: %s= %s %s' % (
-        RESULT_TYPES[result_type],
-        _EscapePerfResult(measurement),
-        trace_name,
-        value,
-        units)
-    avg, sd = GeomMeanAndStdDevFromHistogram(value)
-
-  if avg:
-    output += '\nAvg %s: %f%s' % (measurement, avg, units)
-  if sd:
-    output += '\nSd  %s: %f%s' % (measurement, sd, units)
-  if print_to_stdout:
-    print output
-    sys.stdout.flush()
-  return output
diff --git a/catapult/telemetry/telemetry/util/process_statistic_timeline_data.py b/catapult/telemetry/telemetry/util/process_statistic_timeline_data.py
deleted file mode 100644
index 589e8d3..0000000
--- a/catapult/telemetry/telemetry/util/process_statistic_timeline_data.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class ProcessStatisticTimelineData(object):
-  """Holds value of a stat for one or more processes.
-
-  This object can hold a value for more than one pid by adding another
-  object."""
-
-  def __init__(self, pid, value):
-    super(ProcessStatisticTimelineData, self).__init__()
-    assert value >= 0
-    self._value_by_pid = {pid: value}
-
-  def __sub__(self, other):
-    """The results of subtraction is an object holding only the pids contained
-    in |self|.
-
-    The motivation is that some processes may have died between two consecutive
-    measurements. The desired behavior is to only make calculations based on
-    the processes that are alive at the end of the second measurement."""
-    # pylint: disable=protected-access
-    ret = self.__class__(0, 0)
-    my_dict = self._value_by_pid
-
-    ret._value_by_pid = (
-        {k: my_dict[k] - other._value_by_pid.get(k, 0) for
-            k in my_dict.keys()})
-    return ret
-
-  def __add__(self, other):
-    """The result contains pids from both |self| and |other|, if duplicate
-    pids are found between objects, an error will occur. """
-    # pylint: disable=protected-access
-    intersecting_pids = (set(self._value_by_pid.keys()) &
-        set(other._value_by_pid.keys()))
-    assert len(intersecting_pids) == 0
-
-    ret = self.__class__(0, 0)
-    ret._value_by_pid = {}
-    ret._value_by_pid.update(self._value_by_pid)
-    ret._value_by_pid.update(other._value_by_pid)
-    return ret
-
-  @property
-  def value_by_pid(self):
-    return self._value_by_pid
-
-  def total_sum(self):
-    """Returns the sum of all values contained by this object. """
-    return sum(self._value_by_pid.values())
-
-
-class IdleWakeupTimelineData(ProcessStatisticTimelineData):
-  """A ProcessStatisticTimelineData to hold idle wakeups."""
-  pass
diff --git a/catapult/telemetry/telemetry/util/process_statistic_timeline_data_unittest.py b/catapult/telemetry/telemetry/util/process_statistic_timeline_data_unittest.py
deleted file mode 100644
index 98f0346..0000000
--- a/catapult/telemetry/telemetry/util/process_statistic_timeline_data_unittest.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.util import process_statistic_timeline_data
-
-
-class ProcessStatisticTimelineDataTest(unittest.TestCase):
-
-  def testProcessStatisticValueMath(self):
-    pid1 = 1
-    pid2 = 2
-
-    a = process_statistic_timeline_data.ProcessStatisticTimelineData(pid1, 5)
-    b = process_statistic_timeline_data.ProcessStatisticTimelineData(pid2, 1)
-    c = process_statistic_timeline_data.ProcessStatisticTimelineData(pid1, 1)
-
-    # Test addition.
-    addition_result = (a + b).value_by_pid
-    self.assertEquals(5, addition_result[pid1])
-    self.assertEquals(1, addition_result[pid2])
-    self.assertEquals(2, len(addition_result.keys()))
-
-    # Test subtraction.
-    subtraction_result = ((a + b) - c).value_by_pid
-    self.assertEquals(4, subtraction_result[pid1])
-    self.assertEquals(1, subtraction_result[pid2])
-    self.assertEquals(2, len(subtraction_result.keys()))
-
-    # Test subtraction with a pid that exists only in rhs.
-    subtraction_results1 = (a - (b + c)).value_by_pid
-    self.assertEquals(4, subtraction_results1[pid1])
-    self.assertEquals(1, len(subtraction_results1.keys()))
-
-    # Test calculation of total sum.
-    self.assertEquals(6, (a + b).total_sum())
-
-  def testProcessStatisticValueSummary(self):
-    pid1 = 1
-    pid2 = 2
-
-    a = process_statistic_timeline_data.ProcessStatisticTimelineData(pid1, 1)
-    b = process_statistic_timeline_data.ProcessStatisticTimelineData(pid2, 99)
-    c = a + b
-    self.assertEquals(100, c.total_sum())
diff --git a/catapult/telemetry/telemetry/util/rgba_color.py b/catapult/telemetry/telemetry/util/rgba_color.py
deleted file mode 100644
index 84e0235..0000000
--- a/catapult/telemetry/telemetry/util/rgba_color.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-
-class RgbaColor(collections.namedtuple('RgbaColor', ['r', 'g', 'b', 'a'])):
-  """Encapsulates an RGBA color retrieved from an image."""
-  def __new__(cls, r, g, b, a=255):
-    return super(RgbaColor, cls).__new__(cls, r, g, b, a)
-
-  def __int__(self):
-    return (self.r << 16) | (self.g << 8) | self.b
-
-  def IsEqual(self, expected_color, tolerance=0):
-    """Verifies that the color is within a given tolerance of
-    the expected color."""
-    r_diff = abs(self.r - expected_color.r)
-    g_diff = abs(self.g - expected_color.g)
-    b_diff = abs(self.b - expected_color.b)
-    a_diff = abs(self.a - expected_color.a)
-    return (r_diff <= tolerance and g_diff <= tolerance
-        and b_diff <= tolerance and a_diff <= tolerance)
-
-  def AssertIsRGB(self, r, g, b, tolerance=0):
-    assert self.IsEqual(RgbaColor(r, g, b), tolerance)
-
-  def AssertIsRGBA(self, r, g, b, a, tolerance=0):
-    assert self.IsEqual(RgbaColor(r, g, b, a), tolerance)
-
-
-WEB_PAGE_TEST_ORANGE = RgbaColor(222, 100, 13)
-WHITE = RgbaColor(255, 255, 255)
diff --git a/catapult/telemetry/telemetry/util/screenshot.py b/catapult/telemetry/telemetry/util/screenshot.py
deleted file mode 100644
index bdd3014..0000000
--- a/catapult/telemetry/telemetry/util/screenshot.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import datetime
-import logging
-import os
-import random
-import tempfile
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-from telemetry.util import image_util
-from telemetry.internal.util import file_handle
-
-
-def TryCaptureScreenShot(platform, tab=None):
-  """ If the platform or tab supports screenshot, attempt to take a screenshot
-  of the current browser.
-
-  Args:
-    platform: current platform
-    tab: browser tab if available
-
-  Returns:
-    file handle of the tempoerary file path for the screenshot if
-    present, None otherwise.
-  """
-  try:
-    # TODO(nednguyen): once all platforms support taking screenshot,
-    # remove the tab checking logic and consider moving this to story_runner.
-    # (crbug.com/369490)
-    if platform.CanTakeScreenshot():
-      tf = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
-      tf.close()
-      platform.TakeScreenshot(tf.name)
-      return file_handle.FromTempFile(tf)
-    elif tab and tab.IsAlive() and tab.screenshot_supported:
-      tf = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
-      tf.close()
-      image = tab.Screenshot()
-      image_util.WritePngFile(image, tf.name)
-      return file_handle.FromTempFile(tf)
-    else:
-      logging.warning(
-          'Either tab has crashed or browser does not support taking tab '
-          'screenshot. Skip taking screenshot on failure.')
-      return None
-  except Exception as e:
-    logging.warning('Exception when trying to capture screenshot: %s', repr(e))
-    return None
-
-
-def TryCaptureScreenShotAndUploadToCloudStorage(platform, tab=None):
-  """ If the platform or tab supports screenshot, attempt to take a screenshot
-  of the current browser.  If present it uploads this local path to cloud
-  storage and returns the URL of the cloud storage path.
-
-  Args:
-    platform: current platform
-    tab: browser tab if available
-
-  Returns:
-    url of the cloud storage path if screenshot is present, None otherwise
-  """
-  fh = TryCaptureScreenShot(platform, tab)
-  if fh is not None:
-    return _UploadScreenShotToCloudStorage(fh)
-
-  return None
-
-def _GenerateRemotePath(fh):
-  return ('browser-screenshot_%s-%s%-d%s' % (
-          fh.id,
-          datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'),
-          random.randint(1, 100000),
-          fh.extension))
-
-def _UploadScreenShotToCloudStorage(fh):
-  """ Upload the given screenshot image to cloud storage and return the
-    cloud storage url if successful.
-  """
-  try:
-    return cloud_storage.Insert(cloud_storage.TELEMETRY_OUTPUT,
-                                _GenerateRemotePath(fh), fh.GetAbsPath())
-  except cloud_storage.CloudStorageError as err:
-    logging.error('Cloud storage error while trying to upload screenshot: %s'
-                  % repr(err))
-    return '<Missing link>'
-  finally:  # Must clean up screenshot file if exists.
-    os.remove(fh.GetAbsPath())
diff --git a/catapult/telemetry/telemetry/util/screenshot_unittest.py b/catapult/telemetry/telemetry/util/screenshot_unittest.py
deleted file mode 100644
index 1bc17e8..0000000
--- a/catapult/telemetry/telemetry/util/screenshot_unittest.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import mock
-import tempfile
-import unittest
-import os
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-from telemetry.testing import fakes
-from telemetry.internal.util import file_handle
-from telemetry.util import image_util
-from telemetry.util import screenshot
-
-class ScreenshotUtilTests(unittest.TestCase):
-
-  def setUp(self):
-    self.options = fakes.CreateBrowserFinderOptions()
-
-  def testScreenShotTakenSupportedPlatform(self):
-    fake_platform = self.options.fake_possible_browser.returned_browser.platform
-    expected_png_base64 = """
-      iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91
-      JpzAAAAFklEQVR4Xg3EAQ0AAABAMP1LY3YI7l8l6A
-      T8tgwbJAAAAABJRU5ErkJggg==
-      """
-    fake_platform.screenshot_png_data = expected_png_base64
-
-    fh = screenshot.TryCaptureScreenShot(fake_platform, None)
-    screenshot_file_path = fh.GetAbsPath()
-    try:
-      actual_screenshot_img = image_util.FromPngFile(screenshot_file_path)
-      self.assertTrue(image_util.AreEqual(
-                      image_util.FromBase64Png(expected_png_base64),
-                      actual_screenshot_img))
-    finally:  # Must clean up screenshot file if exists.
-      os.remove(screenshot_file_path)
-
-  def testUploadScreenshotToCloudStorage(self):
-    tf = tempfile.NamedTemporaryFile(
-        suffix='.png', delete=False)
-    fh1 = file_handle.FromTempFile(tf)
-
-    local_path = '123456abcdefg.png'
-
-    with mock.patch('py_utils.cloud_storage.Insert') as mock_insert:
-      with mock.patch('telemetry.util.screenshot._GenerateRemotePath',
-        return_value=local_path):
-
-        url = screenshot._UploadScreenShotToCloudStorage(fh1)
-        mock_insert.assert_called_with(
-            cloud_storage.TELEMETRY_OUTPUT,
-            local_path,
-            fh1.GetAbsPath())
-        self.assertTrue(url is not None)
diff --git a/catapult/telemetry/telemetry/util/statistics.py b/catapult/telemetry/telemetry/util/statistics.py
deleted file mode 100644
index 381c6b4..0000000
--- a/catapult/telemetry/telemetry/util/statistics.py
+++ /dev/null
@@ -1,346 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A collection of statistical utility functions to be used by metrics."""
-
-import math
-
-
-def Clamp(value, low=0.0, high=1.0):
-  """Clamp a value between some low and high value."""
-  return min(max(value, low), high)
-
-
-def NormalizeSamples(samples):
-  """Sorts the samples, and map them linearly to the range [0,1].
-
-  They're mapped such that for the N samples, the first sample is 0.5/N and the
-  last sample is (N-0.5)/N.
-
-  Background: The discrepancy of the sample set i/(N-1); i=0, ..., N-1 is 2/N,
-  twice the discrepancy of the sample set (i+1/2)/N; i=0, ..., N-1. In our case
-  we don't want to distinguish between these two cases, as our original domain
-  is not bounded (it is for Monte Carlo integration, where discrepancy was
-  first used).
-  """
-  if not samples:
-    return samples, 1.0
-  samples = sorted(samples)
-  low = min(samples)
-  high = max(samples)
-  new_low = 0.5 / len(samples)
-  new_high = (len(samples)-0.5) / len(samples)
-  if high-low == 0.0:
-    return [0.5] * len(samples), 1.0
-  scale = (new_high - new_low) / (high - low)
-  for i in xrange(0, len(samples)):
-    samples[i] = float(samples[i] - low) * scale + new_low
-  return samples, scale
-
-
-def Discrepancy(samples, location_count=None):
-  """Computes the discrepancy of a set of 1D samples from the interval [0,1].
-
-  The samples must be sorted. We define the discrepancy of an empty set
-  of samples to be zero.
-
-  http://en.wikipedia.org/wiki/Low-discrepancy_sequence
-  http://mathworld.wolfram.com/Discrepancy.html
-  """
-  if not samples:
-    return 0.0
-
-  max_local_discrepancy = 0
-  inv_sample_count = 1.0 / len(samples)
-  locations = []
-  # For each location, stores the number of samples less than that location.
-  count_less = []
-  # For each location, stores the number of samples less than or equal to that
-  # location.
-  count_less_equal = []
-
-  if location_count:
-    # Generate list of equally spaced locations.
-    sample_index = 0
-    for i in xrange(0, int(location_count)):
-      location = float(i) / (location_count-1)
-      locations.append(location)
-      while sample_index < len(samples) and samples[sample_index] < location:
-        sample_index += 1
-      count_less.append(sample_index)
-      while  sample_index < len(samples) and samples[sample_index] <= location:
-        sample_index += 1
-      count_less_equal.append(sample_index)
-  else:
-    # Populate locations with sample positions. Append 0 and 1 if necessary.
-    if samples[0] > 0.0:
-      locations.append(0.0)
-      count_less.append(0)
-      count_less_equal.append(0)
-    for i in xrange(0, len(samples)):
-      locations.append(samples[i])
-      count_less.append(i)
-      count_less_equal.append(i+1)
-    if samples[-1] < 1.0:
-      locations.append(1.0)
-      count_less.append(len(samples))
-      count_less_equal.append(len(samples))
-
-  # Compute discrepancy as max(overshoot, -undershoot), where
-  # overshoot = max(count_closed(i, j)/N - length(i, j)) for all i < j,
-  # undershoot = min(count_open(i, j)/N - length(i, j)) for all i < j,
-  # N = len(samples),
-  # count_closed(i, j) is the number of points between i and j including ends,
-  # count_open(i, j) is the number of points between i and j excluding ends,
-  # length(i, j) is locations[i] - locations[j].
-
-  # The following algorithm is modification of Kadane's algorithm,
-  # see https://en.wikipedia.org/wiki/Maximum_subarray_problem.
-
-  # The maximum of (count_closed(k, i-1)/N - length(k, i-1)) for any k < i-1.
-  max_diff = 0
-  # The minimum of (count_open(k, i-1)/N - length(k, i-1)) for any k < i-1.
-  min_diff = 0
-  for i in xrange(1, len(locations)):
-    length = locations[i] - locations[i - 1]
-    count_closed = count_less_equal[i] - count_less[i - 1]
-    count_open = count_less[i] - count_less_equal[i - 1]
-    # Number of points that are added if we extend a closed range that
-    # ends at location (i-1).
-    count_closed_increment = count_less_equal[i] - count_less_equal[i - 1]
-    # Number of points that are added if we extend an open range that
-    # ends at location (i-1).
-    count_open_increment = count_less[i] - count_less[i - 1]
-
-    # Either extend the previous optimal range or start a new one.
-    max_diff = max(
-        float(count_closed_increment) * inv_sample_count - length + max_diff,
-        float(count_closed) * inv_sample_count - length)
-    min_diff = min(
-        float(count_open_increment) * inv_sample_count - length + min_diff,
-        float(count_open) * inv_sample_count - length)
-
-    max_local_discrepancy = max(max_diff, -min_diff, max_local_discrepancy)
-  return max_local_discrepancy
-
-
-def TimestampsDiscrepancy(timestamps, absolute=True,
-                          location_count=None):
-  """A discrepancy based metric for measuring timestamp jank.
-
-  TimestampsDiscrepancy quantifies the largest area of jank observed in a series
-  of timestamps.  Note that this is different from metrics based on the
-  max_time_interval. For example, the time stamp series A = [0,1,2,3,5,6] and
-  B = [0,1,2,3,5,7] have the same max_time_interval = 2, but
-  Discrepancy(B) > Discrepancy(A).
-
-  Two variants of discrepancy can be computed:
-
-  Relative discrepancy is following the original definition of
-  discrepancy. It characterized the largest area of jank, relative to the
-  duration of the entire time stamp series.  We normalize the raw results,
-  because the best case discrepancy for a set of N samples is 1/N (for
-  equally spaced samples), and we want our metric to report 0.0 in that
-  case.
-
-  Absolute discrepancy also characterizes the largest area of jank, but its
-  value wouldn't change (except for imprecisions due to a low
-  |interval_multiplier|) if additional 'good' intervals were added to an
-  exisiting list of time stamps.  Its range is [0,inf] and the unit is
-  milliseconds.
-
-  The time stamp series C = [0,2,3,4] and D = [0,2,3,4,5] have the same
-  absolute discrepancy, but D has lower relative discrepancy than C.
-
-  |timestamps| may be a list of lists S = [S_1, S_2, ..., S_N], where each
-  S_i is a time stamp series. In that case, the discrepancy D(S) is:
-  D(S) = max(D(S_1), D(S_2), ..., D(S_N))
-  """
-  if not timestamps:
-    return 0.0
-
-  if isinstance(timestamps[0], list):
-    range_discrepancies = [TimestampsDiscrepancy(r) for r in timestamps]
-    return max(range_discrepancies)
-
-  samples, sample_scale = NormalizeSamples(timestamps)
-  discrepancy = Discrepancy(samples, location_count)
-  inv_sample_count = 1.0 / len(samples)
-  if absolute:
-    # Compute absolute discrepancy
-    discrepancy /= sample_scale
-  else:
-    # Compute relative discrepancy
-    discrepancy = Clamp((discrepancy-inv_sample_count) / (1.0-inv_sample_count))
-  return discrepancy
-
-
-def DurationsDiscrepancy(durations, absolute=True,
-                         location_count=None):
-  """A discrepancy based metric for measuring duration jank.
-
-  DurationsDiscrepancy computes a jank metric which measures how irregular a
-  given sequence of intervals is. In order to minimize jank, each duration
-  should be equally long. This is similar to how timestamp jank works,
-  and we therefore reuse the timestamp discrepancy function above to compute a
-  similar duration discrepancy number.
-
-  Because timestamp discrepancy is defined in terms of timestamps, we first
-  convert the list of durations to monotonically increasing timestamps.
-
-  Args:
-    durations: List of interval lengths in milliseconds.
-    absolute: See TimestampsDiscrepancy.
-    interval_multiplier: See TimestampsDiscrepancy.
-  """
-  if not durations:
-    return 0.0
-
-  timestamps = reduce(lambda x, y: x + [x[-1] + y], durations, [0])
-  return TimestampsDiscrepancy(timestamps, absolute, location_count)
-
-
-def ArithmeticMean(data):
-  """Calculates arithmetic mean.
-
-  Args:
-    data: A list of samples.
-
-  Returns:
-    The arithmetic mean value, or 0 if the list is empty.
-  """
-  numerator_total = Total(data)
-  denominator_total = Total(len(data))
-  return DivideIfPossibleOrZero(numerator_total, denominator_total)
-
-
-def StandardDeviation(data):
-  """Calculates the standard deviation.
-
-  Args:
-    data: A list of samples.
-
-  Returns:
-    The standard deviation of the samples provided.
-  """
-  if len(data) == 1:
-    return 0.0
-
-  mean = ArithmeticMean(data)
-  variances = [float(x) - mean for x in data]
-  variances = [x * x for x in variances]
-  std_dev = math.sqrt(ArithmeticMean(variances))
-
-  return std_dev
-
-
-def TrapezoidalRule(data, dx):
-  """ Calculate the integral according to the trapezoidal rule
-
-  TrapezoidalRule approximates the definite integral of f from a to b by
-  the composite trapezoidal rule, using n subintervals.
-  http://en.wikipedia.org/wiki/Trapezoidal_rule#Uniform_grid
-
-  Args:
-    data: A list of samples
-    dx: The uniform distance along the x axis between any two samples
-
-  Returns:
-    The area under the curve defined by the samples and the uniform distance
-    according to the trapezoidal rule.
-  """
-
-  n = len(data) - 1
-  s = data[0] + data[n]
-
-  if n == 0:
-    return 0.0
-
-  for i in range(1, n):
-    s += 2 * data[i]
-
-  return s * dx / 2.0
-
-def Total(data):
-  """Returns the float value of a number or the sum of a list."""
-  if type(data) == float:
-    total = data
-  elif type(data) == int:
-    total = float(data)
-  elif type(data) == list:
-    total = float(sum(data))
-  else:
-    raise TypeError
-  return total
-
-
-def DivideIfPossibleOrZero(numerator, denominator):
-  """Returns the quotient, or zero if the denominator is zero."""
-  return (float(numerator) / float(denominator)) if denominator else 0
-
-
-def GeneralizedMean(values, exponent):
-  """See http://en.wikipedia.org/wiki/Generalized_mean"""
-  if not values:
-    return 0.0
-  sum_of_powers = 0.0
-  for v in values:
-    sum_of_powers += v ** exponent
-  return (sum_of_powers / len(values)) ** (1.0/exponent)
-
-
-def Median(values):
-  """Gets the median of a list of values."""
-  return Percentile(values, 50)
-
-
-def Percentile(values, percentile):
-  """Calculates the value below which a given percentage of values fall.
-
-  For example, if 17% of the values are less than 5.0, then 5.0 is the 17th
-  percentile for this set of values. When the percentage doesn't exactly
-  match a rank in the list of values, the percentile is computed using linear
-  interpolation between closest ranks.
-
-  Args:
-    values: A list of numerical values.
-    percentile: A number between 0 and 100.
-
-  Returns:
-    The Nth percentile for the list of values, where N is the given percentage.
-  """
-  if not values:
-    return 0.0
-  sorted_values = sorted(values)
-  n = len(values)
-  percentile /= 100.0
-  if percentile <= 0.5 / n:
-    return sorted_values[0]
-  elif percentile >= (n - 0.5) / n:
-    return sorted_values[-1]
-  else:
-    floor_index = int(math.floor(n * percentile -  0.5))
-    floor_value = sorted_values[floor_index]
-    ceil_value = sorted_values[floor_index+1]
-    alpha = n * percentile - 0.5 - floor_index
-    return floor_value + alpha * (ceil_value - floor_value)
-
-
-def GeometricMean(values):
-  """Compute a rounded geometric mean from an array of values."""
-  if not values:
-    return None
-  # To avoid infinite value errors, make sure no value is less than 0.001.
-  new_values = []
-  for value in values:
-    if value > 0.001:
-      new_values.append(value)
-    else:
-      new_values.append(0.001)
-  # Compute the sum of the log of the values.
-  log_sum = sum(map(math.log, new_values))
-  # Raise e to that sum over the number of values.
-  mean = math.pow(math.e, (log_sum / len(new_values)))
-  # Return the rounded mean.
-  return int(round(mean))
diff --git a/catapult/telemetry/telemetry/util/statistics_unittest.py b/catapult/telemetry/telemetry/util/statistics_unittest.py
deleted file mode 100644
index 8468a16..0000000
--- a/catapult/telemetry/telemetry/util/statistics_unittest.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import math
-import random
-import unittest
-
-from telemetry.util import statistics
-
-
-def Relax(samples, iterations=10):
-  """Lloyd relaxation in 1D.
-
-  Keeps the position of the first and last sample.
-  """
-  for _ in xrange(0, iterations):
-    voronoi_boundaries = []
-    for i in xrange(1, len(samples)):
-      voronoi_boundaries.append((samples[i] + samples[i-1]) * 0.5)
-
-    relaxed_samples = []
-    relaxed_samples.append(samples[0])
-    for i in xrange(1, len(samples)-1):
-      relaxed_samples.append(
-          (voronoi_boundaries[i-1] + voronoi_boundaries[i]) * 0.5)
-    relaxed_samples.append(samples[-1])
-    samples = relaxed_samples
-  return samples
-
-def CreateRandomSamples(num_samples):
-  samples = []
-  position = 0.0
-  samples.append(position)
-  for _ in xrange(1, num_samples):
-    position += random.random()
-    samples.append(position)
-  return samples
-
-class StatisticsUnitTest(unittest.TestCase):
-
-  def testNormalizeSamples(self):
-    samples = []
-    normalized_samples, scale = statistics.NormalizeSamples(samples)
-    self.assertEquals(normalized_samples, [])
-    self.assertEquals(scale, 1.0)
-
-    samples = [0.0, 0.0]
-    normalized_samples, scale = statistics.NormalizeSamples(samples)
-    self.assertEquals(normalized_samples, [0.5, 0.5])
-    self.assertEquals(scale, 1.0)
-
-    samples = [0.0, 1.0/3.0, 2.0/3.0, 1.0]
-    normalized_samples, scale = statistics.NormalizeSamples(samples)
-    self.assertEquals(normalized_samples, [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0])
-    self.assertEquals(scale, 0.75)
-
-    samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0]
-    normalized_samples, scale = statistics.NormalizeSamples(samples)
-    self.assertEquals(normalized_samples, samples)
-    self.assertEquals(scale, 1.0)
-
-  def testDiscrepancyRandom(self):
-    """Tests NormalizeSamples and Discrepancy with random samples.
-
-    Generates 10 sets of 10 random samples, computes the discrepancy,
-    relaxes the samples using Llloyd's algorithm in 1D, and computes the
-    discrepancy of the relaxed samples. Discrepancy of the relaxed samples
-    must be less than or equal to the discrepancy of the original samples.
-    """
-    random.seed(1234567)
-    for _ in xrange(0, 10):
-      samples = CreateRandomSamples(10)
-      samples = statistics.NormalizeSamples(samples)[0]
-      d = statistics.Discrepancy(samples)
-      relaxed_samples = Relax(samples)
-      d_relaxed = statistics.Discrepancy(relaxed_samples)
-      self.assertTrue(d_relaxed <= d)
-
-  def testDiscrepancyAnalytic(self):
-    """Computes discrepancy for sample sets with known statistics."""
-    samples = []
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.0)
-
-    samples = [0.5]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.5)
-
-    samples = [0.0, 1.0]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 1.0)
-
-    samples = [0.5, 0.5, 0.5]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 1.0)
-
-    samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 7.0/8.0]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.25)
-
-    samples = [1.0/8.0, 5.0/8.0, 5.0/8.0, 7.0/8.0]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.5)
-
-    samples = [1.0/8.0, 3.0/8.0, 5.0/8.0, 5.0/8.0, 7.0/8.0]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.4)
-
-    samples = [0.0, 1.0/3.0, 2.0/3.0, 1.0]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.5)
-
-    samples = statistics.NormalizeSamples(samples)[0]
-    d = statistics.Discrepancy(samples)
-    self.assertEquals(d, 0.25)
-
-  def testTimestampsDiscrepancy(self):
-    time_stamps = []
-    d_abs = statistics.TimestampsDiscrepancy(time_stamps, True)
-    self.assertEquals(d_abs, 0.0)
-
-    time_stamps = [4]
-    d_abs = statistics.TimestampsDiscrepancy(time_stamps, True)
-    self.assertEquals(d_abs, 0.5)
-
-    time_stamps_a = [0, 1, 2, 3, 5, 6]
-    time_stamps_b = [0, 1, 2, 3, 5, 7]
-    time_stamps_c = [0, 2, 3, 4]
-    time_stamps_d = [0, 2, 3, 4, 5]
-
-    d_abs_a = statistics.TimestampsDiscrepancy(time_stamps_a, True)
-    d_abs_b = statistics.TimestampsDiscrepancy(time_stamps_b, True)
-    d_abs_c = statistics.TimestampsDiscrepancy(time_stamps_c, True)
-    d_abs_d = statistics.TimestampsDiscrepancy(time_stamps_d, True)
-    d_rel_a = statistics.TimestampsDiscrepancy(time_stamps_a, False)
-    d_rel_b = statistics.TimestampsDiscrepancy(time_stamps_b, False)
-    d_rel_c = statistics.TimestampsDiscrepancy(time_stamps_c, False)
-    d_rel_d = statistics.TimestampsDiscrepancy(time_stamps_d, False)
-
-    self.assertTrue(d_abs_a < d_abs_b)
-    self.assertTrue(d_rel_a < d_rel_b)
-    self.assertTrue(d_rel_d < d_rel_c)
-    self.assertAlmostEquals(d_abs_d, d_abs_c)
-
-  def testDiscrepancyMultipleRanges(self):
-    samples = [[0.0, 1.2, 2.3, 3.3], [6.3, 7.5, 8.4], [4.2, 5.4, 5.9]]
-    d_0 = statistics.TimestampsDiscrepancy(samples[0])
-    d_1 = statistics.TimestampsDiscrepancy(samples[1])
-    d_2 = statistics.TimestampsDiscrepancy(samples[2])
-    d = statistics.TimestampsDiscrepancy(samples)
-    self.assertEquals(d, max(d_0, d_1, d_2))
-
-  def testApproximateDiscrepancy(self):
-    """Tests approimate discrepancy implementation by comparing to exact
-    solution.
-    """
-    random.seed(1234567)
-    for _ in xrange(0, 5):
-      samples = CreateRandomSamples(10)
-      samples = statistics.NormalizeSamples(samples)[0]
-      d = statistics.Discrepancy(samples)
-      d_approx = statistics.Discrepancy(samples, 500)
-      self.assertEquals(round(d, 2), round(d_approx, 2))
-
-  def testPercentile(self):
-    # The 50th percentile is the median value.
-    self.assertEquals(3, statistics.Percentile([4, 5, 1, 3, 2], 50))
-    self.assertEquals(2.5, statistics.Percentile([5, 1, 3, 2], 50))
-    # When the list of values is empty, 0 is returned.
-    self.assertEquals(0, statistics.Percentile([], 50))
-    # When the given percentage is very low, the lowest value is given.
-    self.assertEquals(1, statistics.Percentile([2, 1, 5, 4, 3], 5))
-    # When the given percentage is very high, the highest value is given.
-    self.assertEquals(5, statistics.Percentile([5, 2, 4, 1, 3], 95))
-    # Linear interpolation between closest ranks is used. Using the example
-    # from <http://en.wikipedia.org/wiki/Percentile>:
-    self.assertEquals(27.5, statistics.Percentile([15, 20, 35, 40, 50], 40))
-
-  def testArithmeticMean(self):
-    # The ArithmeticMean function computes the simple average.
-    self.assertAlmostEquals(40/3.0, statistics.ArithmeticMean([10, 10, 20]))
-    self.assertAlmostEquals(15.0, statistics.ArithmeticMean([10, 20]))
-    # If the 'count' is zero, then zero is returned.
-    self.assertEquals(0, statistics.ArithmeticMean([]))
-
-  def testDurationsDiscrepancy(self):
-    durations = []
-    d = statistics.DurationsDiscrepancy(durations)
-    self.assertEquals(d, 0.0)
-
-    durations = [4]
-    d = statistics.DurationsDiscrepancy(durations)
-    self.assertEquals(d, 4.0)
-
-    durations_a = [1, 1, 1, 1, 1]
-    durations_b = [1, 1, 2, 1, 1]
-    durations_c = [1, 2, 1, 2, 1]
-
-    d_a = statistics.DurationsDiscrepancy(durations_a)
-    d_b = statistics.DurationsDiscrepancy(durations_b)
-    d_c = statistics.DurationsDiscrepancy(durations_c)
-
-    self.assertTrue(d_a < d_b < d_c)
-
-  def testStandardDeviation(self):
-    self.assertAlmostEquals(math.sqrt(2/3.0),
-                            statistics.StandardDeviation([1, 2, 3]))
-    self.assertEquals(0, statistics.StandardDeviation([1]))
-    self.assertEquals(0, statistics.StandardDeviation([]))
-
-  def testTrapezoidalRule(self):
-    self.assertEquals(4, statistics.TrapezoidalRule([1, 2, 3], 1))
-    self.assertEquals(2, statistics.TrapezoidalRule([1, 2, 3], .5))
-    self.assertEquals(0, statistics.TrapezoidalRule([1, 2, 3], 0))
-    self.assertEquals(-4, statistics.TrapezoidalRule([1, 2, 3], -1))
-    self.assertEquals(3, statistics.TrapezoidalRule([-1, 2, 3], 1))
-    self.assertEquals(0, statistics.TrapezoidalRule([1], 1))
-    self.assertEquals(0, statistics.TrapezoidalRule([0], 1))
diff --git a/catapult/telemetry/telemetry/util/wpr_modes.py b/catapult/telemetry/telemetry/util/wpr_modes.py
deleted file mode 100644
index 262a4fb..0000000
--- a/catapult/telemetry/telemetry/util/wpr_modes.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-WPR_APPEND = 'wpr-append'
-WPR_OFF = 'wpr-off'
-WPR_RECORD = 'wpr-record'
-WPR_REPLAY = 'wpr-replay'
diff --git a/catapult/telemetry/telemetry/value/__init__.py b/catapult/telemetry/telemetry/value/__init__.py
deleted file mode 100644
index 5b4ad1d..0000000
--- a/catapult/telemetry/telemetry/value/__init__.py
+++ /dev/null
@@ -1,373 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-The Value hierarchy provides a way of representing the values measurements
-produce such that they can be merged across runs, grouped by page, and output
-to different targets.
-
-The core Value concept provides the basic functionality:
-- association with a page, may be none
-- naming and units
-- importance tracking [whether a value will show up on a waterfall or output
-  file by default]
-- other metadata, such as a description of what was measured
-- default conversion to scalar and string
-- merging properties
-
-A page may actually run a few times during a single telemetry session.
-Downstream consumers of test results typically want to group these runs
-together, then compute summary statistics across runs. Value provides the
-Merge* family of methods for this kind of aggregation.
-"""
-import os
-
-from telemetry.core import discover
-from telemetry.core import util
-
-# When converting a Value to its buildbot equivalent, the context in which the
-# value is being interpreted actually affects the conversion. This is insane,
-# but there you have it. There are three contexts in which Values are converted
-# for use by buildbot, represented by these output-intent values.
-PER_PAGE_RESULT_OUTPUT_CONTEXT = 'per-page-result-output-context'
-COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT = 'merged-pages-result-output-context'
-SUMMARY_RESULT_OUTPUT_CONTEXT = 'summary-result-output-context'
-
-class Value(object):
-  """An abstract value produced by a telemetry page test.
-  """
-  def __init__(self, page, name, units, important, description,
-               tir_label, grouping_keys):
-    """A generic Value object.
-
-    Args:
-      page: A Page object, may be given as None to indicate that the value
-          represents results for multiple pages.
-      name: A value name string, may contain a dot. Values from the same test
-          with the same prefix before the dot may be considered to belong to
-          the same chart.
-      units: A units string.
-      important: Whether the value is "important". Causes the value to appear
-          by default in downstream UIs.
-      description: A string explaining in human-understandable terms what this
-          value represents.
-      tir_label: The string label of the TimelineInteractionRecord with
-          which this value is associated.
-      grouping_keys: A dict that maps grouping key names to grouping keys.
-    """
-    # TODO(eakuefner): Check story here after migration (crbug.com/442036)
-    if not isinstance(name, basestring):
-      raise ValueError('name field of Value must be string.')
-    if not isinstance(units, basestring):
-      raise ValueError('units field of Value must be string.')
-    if not isinstance(important, bool):
-      raise ValueError('important field of Value must be bool.')
-    if not ((description is None) or isinstance(description, basestring)):
-      raise ValueError('description field of Value must absent or string.')
-    if not ((tir_label is None) or
-            isinstance(tir_label, basestring)):
-      raise ValueError('tir_label field of Value must absent or '
-                       'string.')
-    if not ((grouping_keys is None) or isinstance(grouping_keys, dict)):
-      raise ValueError('grouping_keys field of Value must be absent or dict')
-
-    if grouping_keys is None:
-      grouping_keys = {}
-
-    self.page = page
-    self.name = name
-    self.units = units
-    self.important = important
-    self.description = description
-    self.tir_label = tir_label
-    self.grouping_keys = grouping_keys
-
-  def __eq__(self, other):
-    return hash(self) == hash(other)
-
-  def __hash__(self):
-    return hash(str(self))
-
-  def IsMergableWith(self, that):
-    return (self.units == that.units and
-            type(self) == type(that) and
-            self.important == that.important)
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    """Combines the provided list of values into a single compound value.
-
-    When a page runs multiple times, it may produce multiple values. This
-    function is given the same-named values across the multiple runs, and has
-    the responsibility of producing a single result.
-
-    It must return a single Value. If merging does not make sense, the
-    implementation must pick a representative value from one of the runs.
-
-    For instance, it may be given
-        [ScalarValue(page, 'a', 1), ScalarValue(page, 'a', 2)]
-    and it might produce
-        ListOfScalarValues(page, 'a', [1, 2])
-    """
-    raise NotImplementedError()
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    """Combines the provided values into a single compound value.
-
-    When a full pageset runs, a single value_name will usually end up getting
-    collected for multiple pages. For instance, we may end up with
-       [ScalarValue(page1, 'a',  1),
-        ScalarValue(page2, 'a',  2)]
-
-    This function takes in the values of the same name, but across multiple
-    pages, and produces a single summary result value. In this instance, it
-    could produce a ScalarValue(None, 'a', 1.5) to indicate averaging, or even
-    ListOfScalarValues(None, 'a', [1, 2]) if concatenated output was desired.
-
-    Some results are so specific to a page that they make no sense when
-    aggregated across pages. If merging values of this type across pages is
-    non-sensical, this method may return None.
-    """
-    raise NotImplementedError()
-
-  def _IsImportantGivenOutputIntent(self, output_context):
-    if output_context == PER_PAGE_RESULT_OUTPUT_CONTEXT:
-      return False
-    elif output_context == COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT:
-      return self.important
-    elif output_context == SUMMARY_RESULT_OUTPUT_CONTEXT:
-      return self.important
-
-  def GetBuildbotDataType(self, output_context):
-    """Returns the buildbot's equivalent data_type.
-
-    This should be one of the values accepted by perf_tests_results_helper.py.
-    """
-    raise NotImplementedError()
-
-  def GetBuildbotValue(self):
-    """Returns the buildbot's equivalent value."""
-    raise NotImplementedError()
-
-  def GetChartAndTraceNameForPerPageResult(self):
-    chart_name, _ = _ConvertValueNameToChartAndTraceName(self.name)
-    trace_name = self.page.display_name
-    return chart_name, trace_name
-
-  @property
-  def name_suffix(self):
-    """Returns the string after a . in the name, or the full name otherwise."""
-    if '.' in self.name:
-      return self.name.split('.', 1)[1]
-    else:
-      return self.name
-
-  def GetChartAndTraceNameForComputedSummaryResult(
-      self, trace_tag):
-    chart_name, trace_name = (
-        _ConvertValueNameToChartAndTraceName(self.name))
-    if trace_tag:
-      return chart_name, trace_name + trace_tag
-    else:
-      return chart_name, trace_name
-
-  def GetRepresentativeNumber(self):
-    """Gets a single scalar value that best-represents this value.
-
-    Returns None if not possible.
-    """
-    raise NotImplementedError()
-
-  def GetRepresentativeString(self):
-    """Gets a string value that best-represents this value.
-
-    Returns None if not possible.
-    """
-    raise NotImplementedError()
-
-  @staticmethod
-  def GetJSONTypeName():
-    """Gets the typename for serialization to JSON using AsDict."""
-    raise NotImplementedError()
-
-  def AsDict(self):
-    """Pre-serializes a value to a dict for output as JSON."""
-    return self._AsDictImpl()
-
-  def _AsDictImpl(self):
-    d = {
-      'name': self.name,
-      'type': self.GetJSONTypeName(),
-      'units': self.units,
-      'important': self.important
-    }
-
-    if self.description:
-      d['description'] = self.description
-
-    if self.tir_label:
-      d['tir_label'] = self.tir_label
-
-    if self.page:
-      d['page_id'] = self.page.id
-
-    if self.grouping_keys:
-      d['grouping_keys'] = self.grouping_keys
-
-    return d
-
-  def AsDictWithoutBaseClassEntries(self):
-    full_dict = self.AsDict()
-    base_dict_keys = set(self._AsDictImpl().keys())
-
-    # Extracts only entries added by the subclass.
-    return dict([(k, v) for (k, v) in full_dict.iteritems()
-                  if k not in base_dict_keys])
-
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    """Produces a value from a value dict and a page dict.
-
-    Value dicts are produced by serialization to JSON, and must be accompanied
-    by a dict mapping page IDs to pages, also produced by serialization, in
-    order to be completely deserialized. If deserializing multiple values, use
-    ListOfValuesFromListOfDicts instead.
-
-    value_dict: a dictionary produced by AsDict() on a value subclass.
-    page_dict: a dictionary mapping IDs to page objects.
-    """
-    return Value.ListOfValuesFromListOfDicts([value_dict], page_dict)[0]
-
-  @staticmethod
-  def ListOfValuesFromListOfDicts(value_dicts, page_dict):
-    """Takes a list of value dicts to values.
-
-    Given a list of value dicts produced by AsDict, this method
-    deserializes the dicts given a dict mapping page IDs to pages.
-    This method performs memoization for deserializing a list of values
-    efficiently, where FromDict is meant to handle one-offs.
-
-    values: a list of value dicts produced by AsDict() on a value subclass.
-    page_dict: a dictionary mapping IDs to page objects.
-    """
-    value_dir = os.path.dirname(__file__)
-    value_classes = discover.DiscoverClasses(
-        value_dir, util.GetTelemetryDir(),
-        Value, index_by_class_name=True)
-
-    value_json_types = dict((value_classes[x].GetJSONTypeName(), x) for x in
-        value_classes)
-
-    values = []
-    for value_dict in value_dicts:
-      value_class = value_classes[value_json_types[value_dict['type']]]
-      assert 'FromDict' in value_class.__dict__, \
-             'Subclass doesn\'t override FromDict'
-      values.append(value_class.FromDict(value_dict, page_dict))
-
-    return values
-
-  @staticmethod
-  def GetConstructorKwArgs(value_dict, page_dict):
-    """Produces constructor arguments from a value dict and a page dict.
-
-    Takes a dict parsed from JSON and an index of pages and recovers the
-    keyword arguments to be passed to the constructor for deserializing the
-    dict.
-
-    value_dict: a dictionary produced by AsDict() on a value subclass.
-    page_dict: a dictionary mapping IDs to page objects.
-    """
-    d = {
-      'name': value_dict['name'],
-      'units': value_dict['units']
-    }
-
-    description = value_dict.get('description', None)
-    if description:
-      d['description'] = description
-    else:
-      d['description'] = None
-
-    page_id = value_dict.get('page_id', None)
-    if page_id is not None:
-      d['page'] = page_dict[int(page_id)]
-    else:
-      d['page'] = None
-
-    d['important'] = False
-
-    tir_label = value_dict.get('tir_label', None)
-    if tir_label:
-      d['tir_label'] = tir_label
-    else:
-      d['tir_label'] = None
-
-    grouping_keys = value_dict.get('grouping_keys', None)
-    if grouping_keys:
-      d['grouping_keys'] = grouping_keys
-    else:
-      d['grouping_keys'] = None
-
-    return d
-
-
-def MergedTirLabel(values):
-  """Returns the tir_label that should be applied to a merge of values.
-
-  As of TBMv2, we encounter situations where we need to merge values with
-  different tir_labels because Telemetry's tir_label field is being used to
-  store story keys for system health stories. As such, when merging, we want to
-  take the common tir_label if all values share the same label (legacy
-  behavior), or have no tir_label if not.
-
-  Args:
-    values: a list of Value instances
-
-  Returns:
-    The tir_label that would be set on the merge of |values|.
-  """
-  assert len(values) > 0
-  v0 = values[0]
-
-  first_tir_label = v0.tir_label
-  if all(v.tir_label == first_tir_label for v in values):
-    return first_tir_label
-  else:
-    return None
-
-
-def ValueNameFromTraceAndChartName(trace_name, chart_name=None):
-  """Mangles a trace name plus optional chart name into a standard string.
-
-  A value might just be a bareword name, e.g. numPixels. In that case, its
-  chart may be None.
-
-  But, a value might also be intended for display with other values, in which
-  case the chart name indicates that grouping. So, you might have
-  screen.numPixels, screen.resolution, where chartName='screen'.
-  """
-  assert trace_name != 'url', 'The name url cannot be used'
-  if chart_name:
-    return '%s.%s' % (chart_name, trace_name)
-  else:
-    assert '.' not in trace_name, ('Trace names cannot contain "." with an '
-        'empty chart_name since this is used to delimit chart_name.trace_name.')
-    return trace_name
-
-
-def _ConvertValueNameToChartAndTraceName(value_name):
-  """Converts a value_name into the equivalent chart-trace name pair.
-
-  Buildbot represents values by the measurement name and an optional trace name,
-  whereas telemetry represents values with a chart_name.trace_name convention,
-  where chart_name is optional. This convention is also used by chart_json.
-
-  This converts from the telemetry convention to the buildbot convention,
-  returning a 2-tuple (measurement_name, trace_name).
-  """
-  if '.' in value_name:
-    return value_name.split('.', 1)
-  else:
-    return value_name, value_name
diff --git a/catapult/telemetry/telemetry/value/common_value_helpers.py b/catapult/telemetry/telemetry/value/common_value_helpers.py
deleted file mode 100644
index a1d366c..0000000
--- a/catapult/telemetry/telemetry/value/common_value_helpers.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import copy
-from telemetry.value import failure
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-
-
-def TranslateMreFailure(mre_failure, page):
-  return failure.FailureValue.FromMessage(page, mre_failure.stack)
-
-
-def TranslateScalarValue(scalar_value, page):
-  # This function should not modify scalar_value because it is also held by
-  # PageTestResults.value_set.
-  scalar_value = copy.deepcopy(scalar_value)
-
-  value = scalar_value['numeric']['value']
-  scalar_value['value'] = value
-  if value is None:
-    scalar_value['none_value_reason'] = 'Common scalar contained None'
-
-  name = scalar_value['name']
-
-  unit_parts = scalar_value['numeric']['unit'].split('_')
-  if len(unit_parts) != 2:
-    raise ValueError('Must specify improvement direction for value ' + name)
-
-  scalar_value['units'] = unit_parts[0]
-
-  if unit_parts[1] == 'biggerIsBetter':
-    scalar_value['improvement_direction'] = improvement_direction.UP
-  else:
-    assert unit_parts[1] == 'smallerIsBetter'
-    scalar_value['improvement_direction'] = improvement_direction.DOWN
-
-  scalar_value['page_id'] = page.id
-  scalar_value['name'] = name
-  return scalar.ScalarValue.FromDict(scalar_value, {page.id: page})
diff --git a/catapult/telemetry/telemetry/value/common_value_helpers_unittest.py b/catapult/telemetry/telemetry/value/common_value_helpers_unittest.py
deleted file mode 100644
index 100aca0..0000000
--- a/catapult/telemetry/telemetry/value/common_value_helpers_unittest.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-import os
-
-from tracing.mre import function_handle
-from tracing.mre import failure
-from tracing.mre import job as job_module
-
-from telemetry import page
-from telemetry import story
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.value import common_value_helpers
-
-
-def _SingleFileFunctionHandle(filename, function_name, guid):
-  return function_handle.FunctionHandle(
-      modules_to_load=[function_handle.ModuleToLoad(filename=filename)],
-      function_name=function_name, guid=guid)
-
-
-class TranslateCommonValuesTest(unittest.TestCase):
-  def testTranslateMreFailure(self):
-    map_function_handle = _SingleFileFunctionHandle('foo.html', 'Foo', '2')
-    job = job_module.Job(map_function_handle, '1')
-
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    p = page.Page('http://www.foo.com/', story_set, story_set.base_dir)
-
-    f = failure.Failure(job, 'foo', '/a.json', 'MyFailure', 'failure', 'stack')
-    fv = common_value_helpers.TranslateMreFailure(f, p)
-
-    self.assertIn('stack', str(fv))
-
-  def testTranslateScalarValue(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    p = page.Page('http://www.foo.com/', story_set, story_set.base_dir)
-
-    scalar_value = {
-        'type': 'numeric',
-        'numeric': {
-            'type': 'scalar',
-            'unit': 'timeInMs_smallerIsBetter',
-            'value': 42
-        },
-        'name': 'foo',
-        'description': 'desc'
-    }
-
-    v = common_value_helpers.TranslateScalarValue(scalar_value, p)
-
-    self.assertIsInstance(v, scalar.ScalarValue)
-    self.assertEquals('foo', v.name)
-    self.assertEquals(p, v.page)
-    self.assertEquals('timeInMs', v.units)
-    self.assertEquals(42, v.value)
-    self.assertEquals(improvement_direction.DOWN, v.improvement_direction)
-    self.assertEquals('desc', v.description)
-
-  def testTranslateScalarNoneValue(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    p = page.Page('http://www.foo.com/', story_set, story_set.base_dir)
-
-    scalar_value = {
-        'type': 'numeric',
-        'numeric': {
-            'type': 'scalar',
-            'unit': 'timeInMs_smallerIsBetter',
-            'value': None
-        },
-        'name': 'foo'
-    }
-
-    v = common_value_helpers.TranslateScalarValue(scalar_value, p)
-
-    self.assertIsNone(v.value)
-    self.assertEquals('Common scalar contained None', v.none_value_reason)
diff --git a/catapult/telemetry/telemetry/value/failure.py b/catapult/telemetry/telemetry/value/failure.py
deleted file mode 100644
index 27086f4..0000000
--- a/catapult/telemetry/telemetry/value/failure.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-import traceback
-
-from telemetry import value as value_module
-
-
-class FailureValue(value_module.Value):
-
-  def __init__(self, page, exc_info, description=None, tir_label=None,
-               grouping_keys=None):
-    """A value representing a failure when running the page.
-
-    Args:
-      page: The page where this failure occurs.
-      exc_info: The exception info (sys.exc_info()) corresponding to
-          this failure.
-    """
-    exc_type = exc_info[0].__name__
-    super(FailureValue, self).__init__(page, exc_type, '', True, description,
-                                       tir_label, grouping_keys)
-    self._exc_info = exc_info
-
-  @classmethod
-  def FromMessage(cls, page, message):
-    """Creates a failure value for a given string message.
-
-    Args:
-      page: The page where this failure occurs.
-      message: A string message describing the failure.
-    """
-    exc_info = cls._GetExcInfoFromMessage(message)
-    return FailureValue(page, exc_info)
-
-  @staticmethod
-  def _GetExcInfoFromMessage(message):
-    try:
-      raise Exception(message)
-    except Exception:
-      return sys.exc_info()
-
-  def __repr__(self):
-    if self.page:
-      page_name = self.page.display_name
-    else:
-      page_name = 'None'
-    return 'FailureValue(%s, %s)' % (
-        page_name, GetStringFromExcInfo(self._exc_info))
-
-  @property
-  def exc_info(self):
-    return self._exc_info
-
-  def GetBuildbotDataType(self, output_context):
-    return None
-
-  def GetBuildbotValue(self):
-    return None
-
-  def GetChartAndTraceNameForPerPageResult(self):
-    return None
-
-  def GetRepresentativeNumber(self):
-    return None
-
-  def GetRepresentativeString(self):
-    return None
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'failure'
-
-  def AsDict(self):
-    d = super(FailureValue, self).AsDict()
-    d['value'] = GetStringFromExcInfo(self.exc_info)
-    return d
-
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
-    del kwargs['name']
-    del kwargs['units']
-    if 'important' in kwargs:
-      del kwargs['important']
-    kwargs['exc_info'] = FailureValue._GetExcInfoFromMessage(
-        value_dict['value'])
-
-    return FailureValue(**kwargs)
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    assert False, 'Should not be called.'
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    assert False, 'Should not be called.'
-
-def GetStringFromExcInfo(exc_info):
-  return ''.join(traceback.format_exception(*exc_info))
diff --git a/catapult/telemetry/telemetry/value/failure_unittest.py b/catapult/telemetry/telemetry/value/failure_unittest.py
deleted file mode 100644
index 9a60d65..0000000
--- a/catapult/telemetry/telemetry/value/failure_unittest.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-import traceback
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry import value
-from telemetry.value import failure
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    self.story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    self.story_set.AddStory(page_module.Page(
-        'http://www.bar.com/', self.story_set, self.story_set.base_dir))
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class ValueTest(TestBase):
-  def testRepr(self):
-    v = failure.FailureValue.FromMessage(self.pages[0], 'Failure')
-
-    exc_info_str = failure.GetStringFromExcInfo(v.exc_info)
-    expected = 'FailureValue(http://www.bar.com/, %s)' % exc_info_str
-
-    self.assertEquals(expected, str(v))
-
-  def testName(self):
-    v0 = failure.FailureValue.FromMessage(self.pages[0], 'Failure')
-    self.assertEquals('Exception', v0.name)
-    try:
-      raise NotImplementedError()
-    except Exception:
-      v1 = failure.FailureValue(self.pages[0], sys.exc_info())
-    self.assertEquals('NotImplementedError', v1.name)
-
-  def testBuildbotAndRepresentativeValue(self):
-    v = failure.FailureValue.FromMessage(self.pages[0], 'Failure')
-    self.assertIsNone(v.GetBuildbotValue())
-    self.assertIsNone(v.GetBuildbotDataType(
-        value.COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT))
-    self.assertIsNone(v.GetChartAndTraceNameForPerPageResult())
-    self.assertIsNone(v.GetRepresentativeNumber())
-    self.assertIsNone(v.GetRepresentativeString())
-
-  def testAsDict(self):
-    v = failure.FailureValue.FromMessage(self.pages[0], 'Failure')
-    d = v.AsDictWithoutBaseClassEntries()
-    self.assertTrue(d['value'].find('Exception: Failure') > -1)
-
-  def testFromDict(self):
-    try:
-      raise Exception('test')
-    except Exception:
-      exc_info = sys.exc_info()
-    d = {
-      'type': 'failure',
-      'name': exc_info[0].__name__,
-      'units': '',
-      'value': ''.join(traceback.format_exception(*exc_info))
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, failure.FailureValue))
-    self.assertEquals(v.name, 'Exception')
diff --git a/catapult/telemetry/telemetry/value/histogram.py b/catapult/telemetry/telemetry/value/histogram.py
deleted file mode 100644
index 55f8928..0000000
--- a/catapult/telemetry/telemetry/value/histogram.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import json
-
-from telemetry.util import perf_tests_helper
-from telemetry import value as value_module
-from telemetry.value import histogram_util
-from telemetry.value import summarizable
-
-
-class HistogramValueBucket(object):
-  def __init__(self, low, high, count=0):
-    self.low = low
-    self.high = high
-    self.count = count
-
-  def AsDict(self):
-    return {
-      'low': self.low,
-      'high': self.high,
-      'count': self.count
-    }
-
-  def ToJSONString(self):
-    return '{%s}' % ', '.join([
-      '"low": %i' % self.low,
-      '"high": %i' % self.high,
-      '"count": %i' % self.count])
-
-class HistogramValue(summarizable.SummarizableValue):
-  def __init__(self, page, name, units,
-               raw_value=None, raw_value_json=None, important=True,
-               description=None, tir_label=None, improvement_direction=None,
-               grouping_keys=None):
-    super(HistogramValue, self).__init__(page, name, units, important,
-                                         description, tir_label,
-                                         improvement_direction, grouping_keys)
-    if raw_value_json:
-      assert raw_value == None, \
-             'Don\'t specify both raw_value and raw_value_json'
-      raw_value = json.loads(raw_value_json)
-    if raw_value:
-      self.buckets = []
-      for bucket in histogram_util.GetHistogramBucketsFromRawValue(raw_value):
-        self.buckets.append(HistogramValueBucket(
-          low=bucket['low'],
-          high=bucket['high'],
-          count=bucket['count']))
-    else:
-      self.buckets = []
-
-  def __repr__(self):
-    if self.page:
-      page_name = self.page.display_name
-    else:
-      page_name = 'None'
-    return ('HistogramValue(%s, %s, %s, raw_json_string=%s, '
-            'important=%s, description=%s, tir_label=%s, '
-            'improvement_direction=%s, grouping_keys=%s)') % (
-                page_name,
-                self.name, self.units,
-                self.ToJSONString(),
-                self.important,
-                self.description,
-                self.tir_label,
-                self.improvement_direction,
-                self.grouping_keys)
-
-  def GetBuildbotDataType(self, output_context):
-    if self._IsImportantGivenOutputIntent(output_context):
-      return 'histogram'
-    return 'unimportant-histogram'
-
-  def GetBuildbotValue(self):
-    # More buildbot insanity: perf_tests_results_helper requires the histogram
-    # to be an array of size one.
-    return [self.ToJSONString()]
-
-  def ToJSONString(self):
-    # This has to hand-JSONify the histogram to ensure the order of keys
-    # produced is stable across different systems.
-    #
-    # This is done because the buildbot unittests are string equality
-    # assertions. Thus, tests that contain histograms require stable
-    # stringification of the histogram.
-    #
-    # Sigh, buildbot, Y U gotta be that way.
-    return '{"buckets": [%s]}' % (
-      ', '.join([b.ToJSONString() for b in self.buckets]))
-
-  def GetRepresentativeNumber(self):
-    (mean, _) = perf_tests_helper.GeomMeanAndStdDevFromHistogram(
-        self.ToJSONString())
-    return mean
-
-  def GetRepresentativeString(self):
-    return self.GetBuildbotValue()
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'histogram'
-
-  def AsDict(self):
-    d = super(HistogramValue, self).AsDict()
-    d['buckets'] = [b.AsDict() for b in self.buckets]
-    return d
-
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
-    kwargs['raw_value'] = value_dict
-
-    if 'improvement_direction' in value_dict:
-      kwargs['improvement_direction'] = value_dict['improvement_direction']
-
-    return HistogramValue(**kwargs)
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    assert len(values) > 0
-    v0 = values[0]
-    return HistogramValue(
-        v0.page, v0.name, v0.units,
-        raw_value_json=histogram_util.AddHistograms(
-            [v.ToJSONString() for v in values]),
-        description=v0.description,
-        important=v0.important, tir_label=value_module.MergedTirLabel(values),
-        improvement_direction=v0.improvement_direction,
-        grouping_keys=v0.grouping_keys)
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    # Histograms cannot be merged across pages, at least for now. It should be
-    # theoretically possible, just requires more work. Instead, return None.
-    # This signals to the merging code that the data is unmergable and it will
-    # cope accordingly.
-    return None
diff --git a/catapult/telemetry/telemetry/value/histogram_unittest.py b/catapult/telemetry/telemetry/value/histogram_unittest.py
deleted file mode 100644
index 3e8e662..0000000
--- a/catapult/telemetry/telemetry/value/histogram_unittest.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry import value
-from telemetry.value import histogram as histogram_module
-from telemetry.value import improvement_direction
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page("http://www.bar.com/", story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page("http://www.baz.com/", story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page("http://www.foo.com/", story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class ValueTest(TestBase):
-  def testRepr(self):
-    page = self.pages[0]
-    v = histogram_module.HistogramValue(
-            page, 'x', 'counts',
-           raw_value_json='{"buckets": [{"low": 1, "high": 2, "count": 1}]}',
-           important=True, description='desc', tir_label='my_ir',
-           improvement_direction=improvement_direction.UP)
-    expected = ('HistogramValue(http://www.bar.com/, x, counts, '
-                'raw_json_string={"buckets": [{"low": 1, "high": 2, "count": '
-                '1}]}, important=True, description=desc, tir_label=my_ir, '
-                'improvement_direction=up, grouping_keys={})')
-
-    self.assertEquals(expected, str(v))
-
-  def testHistogramBasic(self):
-    page0 = self.pages[0]
-    histogram = histogram_module.HistogramValue(
-        page0, 'x', 'counts',
-        raw_value_json='{"buckets": [{"low": 1, "high": 2, "count": 1}]}',
-        important=False, improvement_direction=improvement_direction.UP)
-    self.assertEquals(
-      ['{"buckets": [{"low": 1, "high": 2, "count": 1}]}'],
-      histogram.GetBuildbotValue())
-    self.assertEquals(1.5,
-                      histogram.GetRepresentativeNumber())
-    self.assertEquals(
-      ['{"buckets": [{"low": 1, "high": 2, "count": 1}]}'],
-      histogram.GetBuildbotValue())
-
-    self.assertEquals(
-        'unimportant-histogram',
-        histogram.GetBuildbotDataType(value.SUMMARY_RESULT_OUTPUT_CONTEXT))
-    histogram.important = True
-    self.assertEquals(
-        'histogram',
-        histogram.GetBuildbotDataType(value.SUMMARY_RESULT_OUTPUT_CONTEXT))
-
-  def testBucketAsDict(self):
-    bucket = histogram_module.HistogramValueBucket(33, 45, 78)
-    d = bucket.AsDict()
-
-    self.assertEquals(d, {
-          'low': 33,
-          'high': 45,
-          'count': 78
-        })
-
-  def testAsDict(self):
-    histogram = histogram_module.HistogramValue(
-        None, 'x', 'counts',
-        raw_value_json='{"buckets": [{"low": 1, "high": 2, "count": 1}]}',
-        important=False, improvement_direction=improvement_direction.DOWN)
-    d = histogram.AsDictWithoutBaseClassEntries()
-
-    self.assertEquals(['buckets'], d.keys())
-    self.assertTrue(isinstance(d['buckets'], list))
-    self.assertEquals(len(d['buckets']), 1)
-
-  def testFromDict(self):
-    d = {
-      'type': 'histogram',
-      'name': 'x',
-      'units': 'counts',
-      'buckets': [{'low': 1, 'high': 2, 'count': 1}],
-      'improvement_direction': 'down',
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, histogram_module.HistogramValue))
-    self.assertEquals(
-      ['{"buckets": [{"low": 1, "high": 2, "count": 1}]}'],
-      v.GetBuildbotValue())
-    self.assertEquals(improvement_direction.DOWN, v.improvement_direction)
-
-  def testFromDictWithoutImprovementDirection(self):
-    d = {
-      'type': 'histogram',
-      'name': 'x',
-      'units': 'counts',
-      'buckets': [{'low': 1, 'high': 2, 'count': 1}],
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, histogram_module.HistogramValue))
-    self.assertIsNone(v.improvement_direction)
-
-  def testMergeLikeValuesFromSamePage(self):
-    d1 = {
-      'type': 'histogram',
-      'name': 'x',
-      'units': 'counts',
-      'description': 'histogram-based metric',
-      'buckets': [{'low': 1, 'high': 3, 'count': 1}],
-    }
-
-    d2 = {
-      'type': 'histogram',
-      'name': 'x',
-      'units': 'counts',
-      'description': 'histogram-based metric',
-      'buckets': [{'low': 2, 'high': 4, 'count': 1}],
-    }
-
-    v0, v1 = value.Value.FromDict(d1, {}), value.Value.FromDict(d2, {})
-
-    vM = histogram_module.HistogramValue.MergeLikeValuesFromSamePage([v0, v1])
-    self.assertTrue(isinstance(vM, histogram_module.HistogramValue))
-    self.assertEquals('histogram-based metric', vM.description)
diff --git a/catapult/telemetry/telemetry/value/histogram_util.py b/catapult/telemetry/telemetry/value/histogram_util.py
deleted file mode 100644
index e12bb41..0000000
--- a/catapult/telemetry/telemetry/value/histogram_util.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This is a helper module to get and manipulate histogram data.
-
-The histogram data is the same data as is visible from "chrome://histograms".
-More information can be found at: chromium/src/base/metrics/histogram.h
-"""
-
-import collections
-import json
-import logging
-
-from telemetry.core import exceptions
-
-BROWSER_HISTOGRAM = 'browser_histogram'
-RENDERER_HISTOGRAM = 'renderer_histogram'
-
-
-def GetHistogramBucketsFromJson(histogram_json):
-  return GetHistogramBucketsFromRawValue(json.loads(histogram_json))
-
-
-def GetHistogramBucketsFromRawValue(raw_value):
-  buckets = raw_value.get('buckets', [])
-  if buckets:
-    # If there are values greater than the maximum allowable for the histogram,
-    # the highest bucket will have a 'low': maxvalue entry in the dict but no
-    # 'high' entry. Code often assumes the 'high' value will always be present,
-    # and uses it to get bucket mean. So default it to the same value as low.
-    buckets[-1].setdefault('high', buckets[-1]['low'])
-  return buckets
-
-
-def CustomizeBrowserOptions(options):
-  """Allows histogram collection."""
-  options.AppendExtraBrowserArgs(['--enable-stats-collection-bindings'])
-
-
-def SubtractHistogram(histogram_json, start_histogram_json):
-  """Subtracts a previous histogram from a histogram.
-
-  Both parameters and the returned result are json serializations.
-  """
-  start_histogram = json.loads(start_histogram_json)
-  start_histogram_buckets = GetHistogramBucketsFromRawValue(start_histogram)
-  # It's ok if the start histogram is empty (we had no data, maybe even no
-  # histogram at all, at the start of the test).
-  if not start_histogram_buckets:
-    return histogram_json
-
-  histogram = json.loads(histogram_json)
-  if ('pid' in start_histogram and 'pid' in histogram
-      and start_histogram['pid'] != histogram['pid']):
-    raise Exception(
-        'Trying to compare histograms from different processes (%d and %d)'
-        % (start_histogram['pid'], histogram['pid']))
-
-  start_histogram_bucket_counts = dict()
-  for b in start_histogram_buckets:
-    start_histogram_bucket_counts[b['low']] = b['count']
-
-  new_buckets = []
-  for b in GetHistogramBucketsFromRawValue(histogram):
-    new_bucket = b
-    low = b['low']
-    if low in start_histogram_bucket_counts:
-      new_bucket['count'] = b['count'] - start_histogram_bucket_counts[low]
-      if new_bucket['count'] < 0:
-        logging.error('Histogram subtraction error, starting histogram most '
-                      'probably invalid.')
-    if new_bucket['count']:
-      new_buckets.append(new_bucket)
-  histogram['buckets'] = new_buckets
-  histogram['count'] -= start_histogram['count']
-
-  return json.dumps(histogram)
-
-
-def AddHistograms(histogram_jsons):
-  """Adds histograms together. Used for aggregating data.
-
-  The parameter is a list of json serializations and the returned result is a
-  json serialization too.
-
-  Note that the histograms to be added together are typically from different
-  processes.
-  """
-
-  buckets = collections.defaultdict(int)
-  for histogram_json in histogram_jsons:
-    for b in GetHistogramBucketsFromJson(histogram_json):
-      key = (b['low'], b['high'])
-      buckets[key] += b['count']
-
-  buckets = [{'low': key[0], 'high': key[1], 'count': value}
-      for key, value in buckets.iteritems()]
-  buckets.sort(key=lambda h: h['low'])
-
-  result_histogram = {}
-  result_histogram['buckets'] = buckets
-  return json.dumps(result_histogram)
-
-
-def GetHistogram(histogram_type, histogram_name, tab):
-  """Get a json serialization of a histogram."""
-  assert histogram_type in [BROWSER_HISTOGRAM, RENDERER_HISTOGRAM]
-  function = 'getHistogram'
-  if histogram_type == BROWSER_HISTOGRAM:
-    function = 'getBrowserHistogram'
-  try:
-    histogram_json = tab.EvaluateJavaScript(
-        'statsCollectionController.{{ @f }}({{ name }})',
-        f=function, name=histogram_name)
-  except exceptions.EvaluateException:
-    # Sometimes JavaScript flakily fails to execute: http://crbug.com/508431
-    histogram_json = None
-  if histogram_json:
-    return histogram_json
-  return None
-
-
-def GetHistogramCount(histogram_type, histogram_name, tab):
-  """Get the count of events for the given histograms."""
-  histogram_json = GetHistogram(histogram_type, histogram_name, tab)
-  histogram = json.loads(histogram_json)
-  if 'count' in histogram:
-    return histogram['count']
-  else:
-    return 0
-
-def GetHistogramSum(histogram_type, histogram_name, tab):
-  """Get the sum of events for the given histograms."""
-  histogram_json = GetHistogram(histogram_type, histogram_name, tab)
-  histogram = json.loads(histogram_json)
-  if 'sum' in histogram:
-    return histogram['sum']
-  else:
-    return 0
diff --git a/catapult/telemetry/telemetry/value/histogram_util_unittest.py b/catapult/telemetry/telemetry/value/histogram_util_unittest.py
deleted file mode 100644
index d20caca..0000000
--- a/catapult/telemetry/telemetry/value/histogram_util_unittest.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import unittest
-
-from telemetry.value import histogram_util
-
-class TestHistogram(unittest.TestCase):
-  def testSubtractHistogram(self):
-    baseline_histogram = """{"count": 3, "buckets": [
-        {"low": 1, "high": 2, "count": 1},
-        {"low": 2, "high": 3, "count": 2}]}"""
-
-    later_histogram = """{"count": 14, "buckets": [
-        {"low": 1, "high": 2, "count": 1},
-        {"low": 2, "high": 3, "count": 3},
-        {"low": 3, "high": 4, "count": 10}]}"""
-
-    new_histogram = json.loads(
-        histogram_util.SubtractHistogram(later_histogram, baseline_histogram))
-    new_buckets = dict()
-    for b in new_histogram['buckets']:
-      new_buckets[b['low']] = b['count']
-    self.assertFalse(1 in new_buckets)
-    self.assertEquals(1, new_buckets[2])
-    self.assertEquals(10, new_buckets[3])
-
-
-  def testAddHistograms(self):
-    histograms = []
-    histograms.append("""{"count": 3, "buckets": [
-        {"low": 1, "high": 2, "count": 1},
-        {"low": 2, "high": 3, "count": 2}]}""")
-
-    histograms.append("""{"count": 20, "buckets": [
-        {"low": 2, "high": 3, "count": 10},
-        {"low": 3, "high": 4, "count": 10}]}""")
-
-    histograms.append("""{"count": 15, "buckets": [
-        {"low": 1, "high": 2, "count": 4},
-        {"low": 3, "high": 4, "count": 11}]}""")
-
-    new_histogram = json.loads(
-        histogram_util.AddHistograms(histograms))
-    new_buckets = dict()
-    for b in new_histogram['buckets']:
-      new_buckets[b['low']] = b['count']
-    self.assertEquals(5, new_buckets[1])
-    self.assertEquals(12, new_buckets[2])
-    self.assertEquals(21, new_buckets[3])
-
-
-  def testGetHistogramBucketsFromRawValue_Max(self):
-    raw_value = {'buckets': [
-      {'count': 4, 'low': 10, 'high': 15,},
-      {'count': 6, 'low': 16, 'high': 18,},
-      {'count': 8, 'low': 19},
-    ]}
-    buckets = histogram_util.GetHistogramBucketsFromRawValue(raw_value)
-    self.assertEquals([
-      {'count': 4, 'low': 10, 'high': 15,},
-      {'count': 6, 'low': 16, 'high': 18,},
-      {'count': 8, 'low': 19, 'high': 19},],
-      buckets)
-
-
-  def testGetHistogramBucketsFromJson(self):
-    json_value = json.dumps({'buckets': [
-      {'count': 4, 'low': 10, 'high': 15,},
-      {'count': 6, 'low': 16, 'high': 18,},
-      {'count': 8, 'low': 19, 'high': 25},
-    ]})
-    buckets = histogram_util.GetHistogramBucketsFromJson(json_value)
-    self.assertEquals([
-      {'count': 4, 'low': 10, 'high': 15,},
-      {'count': 6, 'low': 16, 'high': 18,},
-      {'count': 8, 'low': 19, 'high': 25},],
-      buckets)
diff --git a/catapult/telemetry/telemetry/value/improvement_direction.py b/catapult/telemetry/telemetry/value/improvement_direction.py
deleted file mode 100644
index aca75ca..0000000
--- a/catapult/telemetry/telemetry/value/improvement_direction.py
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-UP = 'up'
-DOWN = 'down'
-
-def IsValid(improvement_direction):
-  return improvement_direction in [UP, DOWN]
diff --git a/catapult/telemetry/telemetry/value/list_of_scalar_values.py b/catapult/telemetry/telemetry/value/list_of_scalar_values.py
deleted file mode 100644
index b7ceff5..0000000
--- a/catapult/telemetry/telemetry/value/list_of_scalar_values.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import numbers
-import math
-
-from telemetry import value as value_module
-from telemetry.value import none_values
-from telemetry.value import summarizable
-
-
-def Variance(sample):
-  """ Compute the population variance.
-
-    Args:
-      sample: a list of numbers.
-  """
-  k = len(sample) - 1  # Bessel correction
-  if k <= 0:
-    return 0.0
-  m = _Mean(sample)
-  return sum((x - m)**2 for x in sample)/k
-
-
-def StandardDeviation(sample):
-  """ Compute standard deviation for a list of numbers.
-
-    Args:
-      sample: a list of numbers.
-  """
-  return math.sqrt(Variance(sample))
-
-
-def PooledStandardDeviation(list_of_samples, list_of_variances=None):
-  """ Compute standard deviation for a list of samples.
-
-  See: https://en.wikipedia.org/wiki/Pooled_variance for the formula.
-
-  Args:
-    list_of_samples: a list of lists, each is a list of numbers.
-    list_of_variances: a list of numbers, the i-th element is the variance of
-      the i-th sample in list_of_samples. If this is None, we use
-      Variance(sample) to get the variance of the i-th sample.
-  """
-  pooled_variance = 0.0
-  total_degrees_of_freedom = 0
-  for i in xrange(len(list_of_samples)):
-    l = list_of_samples[i]
-    k = len(l) - 1  # Bessel correction
-    if k <= 0:
-      continue
-    variance = list_of_variances[i] if list_of_variances else Variance(l)
-    pooled_variance += k * variance
-    total_degrees_of_freedom += k
-  if total_degrees_of_freedom:
-    return (pooled_variance / total_degrees_of_freedom) ** 0.5
-  else:
-    return 0.0
-
-
-def _Mean(values):
-  return float(sum(values)) / len(values) if len(values) > 0 else 0.0
-
-
-class ListOfScalarValues(summarizable.SummarizableValue):
-  """ ListOfScalarValues represents a list of numbers.
-
-  By default, std is the standard deviation of all numbers in the list. Std can
-  also be specified in the constructor if the numbers are not from the same
-  population.
-  """
-  def __init__(self, page, name, units, values,
-               important=True, description=None,
-               tir_label=None, none_value_reason=None,
-               std=None, improvement_direction=None, grouping_keys=None):
-    super(ListOfScalarValues, self).__init__(page, name, units, important,
-                                             description, tir_label,
-                                             improvement_direction,
-                                             grouping_keys)
-    if values is not None:
-      assert isinstance(values, list)
-      assert len(values) > 0
-      assert all(isinstance(v, numbers.Number) for v in values)
-      assert std is None or isinstance(std, numbers.Number)
-    else:
-      assert std is None
-    none_values.ValidateNoneValueReason(values, none_value_reason)
-    self.values = values
-    self.none_value_reason = none_value_reason
-    if values is not None and std is None:
-      std = StandardDeviation(values)
-    assert std is None or std >= 0, (
-        'standard deviation cannot be negative: %s' % std)
-    self._std = std
-
-  @property
-  def std(self):
-    return self._std
-
-  @property
-  def variance(self):
-    return self._std ** 2
-
-  def __repr__(self):
-    if self.page:
-      page_name = self.page.display_name
-    else:
-      page_name = 'None'
-    return ('ListOfScalarValues(%s, %s, %s, %s, '
-            'important=%s, description=%s, tir_label=%s, std=%s, '
-            'improvement_direction=%s, grouping_keys=%s)') % (
-                page_name,
-                self.name,
-                self.units,
-                repr(self.values),
-                self.important,
-                self.description,
-                self.tir_label,
-                self.std,
-                self.improvement_direction,
-                self.grouping_keys)
-
-  def GetBuildbotDataType(self, output_context):
-    if self._IsImportantGivenOutputIntent(output_context):
-      return 'default'
-    return 'unimportant'
-
-  def GetBuildbotValue(self):
-    return self.values
-
-  def GetRepresentativeNumber(self):
-    return _Mean(self.values)
-
-  def GetRepresentativeString(self):
-    return repr(self.values)
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'list_of_scalar_values'
-
-  def AsDict(self):
-    d = super(ListOfScalarValues, self).AsDict()
-    d['values'] = self.values
-    d['std'] = self.std
-
-    if self.none_value_reason is not None:
-      d['none_value_reason'] = self.none_value_reason
-
-    return d
-
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
-    kwargs['values'] = value_dict['values']
-    kwargs['std'] = value_dict['std']
-
-    if 'improvement_direction' in value_dict:
-      kwargs['improvement_direction'] = value_dict['improvement_direction']
-    if 'none_value_reason' in value_dict:
-      kwargs['none_value_reason'] = value_dict['none_value_reason']
-
-    return ListOfScalarValues(**kwargs)
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    assert len(values) > 0
-    v0 = values[0]
-
-    return cls._MergeLikeValues(values, v0.page, v0.name, v0.grouping_keys)
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    assert len(values) > 0
-    v0 = values[0]
-    return cls._MergeLikeValues(values, None, v0.name, v0.grouping_keys)
-
-  @classmethod
-  def _MergeLikeValues(cls, values, page, name, grouping_keys):
-    v0 = values[0]
-    merged_values = []
-    list_of_samples = []
-    none_value_reason = None
-    pooled_std = None
-    for v in values:
-      if v.values is None:
-        merged_values = None
-        merged_none_values = [v for v in values if v.values is None]
-        none_value_reason = (none_values.MERGE_FAILURE_REASON +
-            ' None values: %s' % repr(merged_none_values))
-        break
-      merged_values.extend(v.values)
-      list_of_samples.append(v.values)
-    if merged_values and page is None:
-      # Pooled standard deviation is only used when merging values comming from
-      # different pages. Otherwise, fall back to the default computation done
-      # in the cosntructor of ListOfScalarValues.
-      pooled_std = PooledStandardDeviation(
-          list_of_samples, list_of_variances=[v.variance for v in values])
-    return ListOfScalarValues(
-        page, name, v0.units,
-        merged_values,
-        important=v0.important,
-        description=v0.description,
-        tir_label=value_module.MergedTirLabel(values),
-        std=pooled_std,
-        none_value_reason=none_value_reason,
-        improvement_direction=v0.improvement_direction,
-        grouping_keys=grouping_keys)
diff --git a/catapult/telemetry/telemetry/value/list_of_scalar_values_unittest.py b/catapult/telemetry/telemetry/value/list_of_scalar_values_unittest.py
deleted file mode 100644
index d2c1e38..0000000
--- a/catapult/telemetry/telemetry/value/list_of_scalar_values_unittest.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry import value
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import none_values
-
-
-class StatisticComputationTest(unittest.TestCase):
-  def testVariance(self):
-    self.assertAlmostEqual(
-        list_of_scalar_values.Variance([]), 0)
-    self.assertAlmostEqual(
-        list_of_scalar_values.Variance([3]), 0)
-    self.assertAlmostEqual(
-        list_of_scalar_values.Variance([600, 470, 170, 430, 300]), 27130)
-
-  def testStandardDeviation(self):
-    self.assertAlmostEqual(
-        list_of_scalar_values.StandardDeviation([]), 0)
-    self.assertAlmostEqual(
-        list_of_scalar_values.StandardDeviation([1]), 0)
-    self.assertAlmostEqual(
-        list_of_scalar_values.StandardDeviation([600, 470, 170, 430, 300]),
-        164.71186, places=4)
-
-  def testPooledVariance(self):
-    self.assertAlmostEqual(
-        list_of_scalar_values.PooledStandardDeviation([[], [], []]), 0)
-    self.assertAlmostEqual(
-        list_of_scalar_values.PooledStandardDeviation([[1], [], [3], []]), 0)
-    self.assertAlmostEqual(
-        list_of_scalar_values.PooledStandardDeviation([[1], [2], [3], [4]]), 0)
-    self.assertAlmostEqual(list_of_scalar_values.PooledStandardDeviation(
-        [[600, 470, 170, 430, 300],           # variance = 27130, std = 164.7
-        [4000, 4020, 4230],                   # variance = 16233, std = 127.41
-        [260, 700, 800, 900, 0, 120, 150]]),  # variance = 136348, std = 369.2
-        282.7060,  # SQRT((27130 4 + 16233*2 + 136348*6)/12)
-        places=4)
-    self.assertAlmostEqual(list_of_scalar_values.PooledStandardDeviation(
-        [[600, 470, 170, 430, 300],
-         [4000, 4020, 4230],
-         [260, 700, 800, 900, 0, 120, 150]],
-        list_of_variances=[100000, 200000, 300000]),
-        465.47466,  # SQRT((100000*4 + 200000* 2 + 300000*6)/12)
-        places=4)
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class ValueTest(TestBase):
-  def testRepr(self):
-    page = self.pages[0]
-    v = list_of_scalar_values.ListOfScalarValues(
-        page, 'x', 'unit', [10, 9, 9, 7], important=True, description='desc',
-        tir_label='my_ir', std=42,
-        improvement_direction=improvement_direction.DOWN)
-
-    expected = ('ListOfScalarValues(http://www.bar.com/, x, unit, '
-                '[10, 9, 9, 7], important=True, description=desc, '
-                'tir_label=my_ir, std=42, '
-                'improvement_direction=down, grouping_keys={})')
-
-    self.assertEquals(expected, str(v))
-
-  def testListSamePageMerging(self):
-    page0 = self.pages[0]
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        [10, 9, 9, 7], description='list-based metric',
-        improvement_direction=improvement_direction.DOWN)
-    v1 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        [300, 302, 303, 304], description='list-based metric',
-        improvement_direction=improvement_direction.DOWN)
-    self.assertTrue(v1.IsMergableWith(v0))
-
-    vM = (list_of_scalar_values.ListOfScalarValues.
-          MergeLikeValuesFromSamePage([v0, v1]))
-    self.assertEquals(page0, vM.page)
-    self.assertEquals('x', vM.name)
-    self.assertEquals('unit', vM.units)
-    self.assertEquals(True, vM.important)
-    self.assertEquals([10, 9, 9, 7, 300, 302, 303, 304], vM.values)
-    # Values from the same page use regular standard deviation.
-    self.assertAlmostEqual(156.88849, vM.std, places=4)
-    self.assertEquals('list-based metric', vM.description)
-    self.assertEquals(improvement_direction.DOWN, vM.improvement_direction)
-
-  def testListDifferentPageMerging(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        [10, 9, 9, 7], improvement_direction=improvement_direction.DOWN)
-    v1 = list_of_scalar_values.ListOfScalarValues(
-        page1, 'x', 'unit',
-        [300, 302, 303, 304], improvement_direction=improvement_direction.DOWN)
-    self.assertTrue(v1.IsMergableWith(v0))
-
-    vM = (list_of_scalar_values.ListOfScalarValues.
-          MergeLikeValuesFromDifferentPages([v0, v1]))
-    self.assertEquals(None, vM.page)
-    self.assertEquals('x', vM.name)
-    self.assertEquals('unit', vM.units)
-    self.assertEquals(True, vM.important)
-    self.assertEquals([10, 9, 9, 7, 300, 302, 303, 304], vM.values)
-    # Values from different pages use pooled standard deviation.
-    # SQRT((19/12 * 3 + 35/12 * 3)/6) = 1.5
-    self.assertAlmostEqual(1.5, vM.std)
-    self.assertEquals(improvement_direction.DOWN, vM.improvement_direction)
-
-  def testListWithNoneValueMerging(self):
-    page0 = self.pages[0]
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        [1, 2], improvement_direction=improvement_direction.UP)
-    v1 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        None, none_value_reason='n',
-        improvement_direction=improvement_direction.UP)
-    self.assertTrue(v1.IsMergableWith(v0))
-
-    vM = (list_of_scalar_values.ListOfScalarValues.
-          MergeLikeValuesFromSamePage([v0, v1]))
-    self.assertEquals(None, vM.values)
-    expected_none_value_reason = (
-        'Merging values containing a None value results in a None value. '
-        'None values: [ListOfScalarValues(http://www.bar.com/, x, unit, None, '
-        'important=True, description=None, tir_label=None, std=None,'
-        ' improvement_direction=up, grouping_keys={})]')
-    self.assertEquals(expected_none_value_reason, vM.none_value_reason)
-    self.assertEquals(improvement_direction.UP, vM.improvement_direction)
-
-  def testListWithNoneValueMustHaveNoneReason(self):
-    page0 = self.pages[0]
-    self.assertRaises(none_values.NoneValueMissingReason,
-                      lambda: list_of_scalar_values.ListOfScalarValues(
-                          page0, 'x', 'unit', None,
-                          improvement_direction=improvement_direction.DOWN))
-
-  def testListWithNoneReasonMustHaveNoneValue(self):
-    page0 = self.pages[0]
-    self.assertRaises(none_values.ValueMustHaveNoneValue,
-                      lambda: list_of_scalar_values.ListOfScalarValues(
-                          page0, 'x', 'unit', [1, 2],
-                          none_value_reason='n',
-                          improvement_direction=improvement_direction.UP))
-
-  def testAsDict(self):
-    v = list_of_scalar_values.ListOfScalarValues(
-        None, 'x', 'unit', [1, 2],
-        important=False, improvement_direction=improvement_direction.DOWN)
-    d = v.AsDictWithoutBaseClassEntries()
-
-    self.assertEquals(d['values'], [1, 2])
-    self.assertAlmostEqual(d['std'], 0.7071, places=4)
-
-  def testMergedValueAsDict(self):
-    page0 = self.pages[0]
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        [10, 9, 9, 7], improvement_direction=improvement_direction.DOWN)
-    v1 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'x', 'unit',
-        [300, 302, 303, 304], improvement_direction=improvement_direction.DOWN)
-    self.assertTrue(v1.IsMergableWith(v0))
-
-    vM = (list_of_scalar_values.ListOfScalarValues.
-          MergeLikeValuesFromSamePage([v0, v1]))
-    d = vM.AsDict()
-    self.assertEquals(d['values'], [10, 9, 9, 7, 300, 302, 303, 304])
-    # Values from the same page use regular standard deviation.
-    self.assertAlmostEqual(d['std'], 156.88849, places=4)
-
-
-  def testNoneValueAsDict(self):
-    v = list_of_scalar_values.ListOfScalarValues(
-        None, 'x', 'unit', None,
-        important=False, none_value_reason='n',
-        improvement_direction=improvement_direction.UP)
-    d = v.AsDictWithoutBaseClassEntries()
-
-    self.assertEquals(d, {
-          'values': None,
-          'none_value_reason': 'n',
-          'std': None
-        })
-
-  def testFromDictInts(self):
-    d = {
-      'type': 'list_of_scalar_values',
-      'name': 'x',
-      'units': 'unit',
-      'values': [1, 2],
-      'std': 0.7071,
-      'improvement_direction': improvement_direction.DOWN
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
-    self.assertEquals(v.values, [1, 2])
-    self.assertEquals(v.std, 0.7071)
-    self.assertEquals(improvement_direction.DOWN, v.improvement_direction)
-
-  def testFromDictFloats(self):
-    d = {
-      'type': 'list_of_scalar_values',
-      'name': 'x',
-      'units': 'unit',
-      'values': [1.3, 2.7, 4.5, 2.1, 3.4],
-      'std': 0.901,
-      'improvement_direction': improvement_direction.UP
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
-    self.assertEquals(v.values, [1.3, 2.7, 4.5, 2.1, 3.4])
-    self.assertEquals(v.std, 0.901)
-
-  def testFromDictWithoutImprovementDirection(self):
-    d = {
-      'type': 'list_of_scalar_values',
-      'name': 'x',
-      'units': 'unit',
-      'values': [1, 2],
-      'std': 0.7071,
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
-    self.assertIsNone(v.improvement_direction)
-
-  def testFromDictNoneValue(self):
-    d = {
-      'type': 'list_of_scalar_values',
-      'name': 'x',
-      'units': 'unit',
-      'values': None,
-      'std': None,
-      'none_value_reason': 'n',
-      'improvement_direction': improvement_direction.DOWN
-    }
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, list_of_scalar_values.ListOfScalarValues))
-    self.assertEquals(v.values, None)
-    self.assertEquals(v.none_value_reason, 'n')
diff --git a/catapult/telemetry/telemetry/value/merge_values.py b/catapult/telemetry/telemetry/value/merge_values.py
deleted file mode 100644
index 7ac808d..0000000
--- a/catapult/telemetry/telemetry/value/merge_values.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.value import failure
-from telemetry.value import skip
-
-
-# TODO(eakuefner): Get rid of this as part of crbug.com/525688
-def DefaultKeyFunc(value):
-  """Keys values in a standard way for grouping in merging and summary.
-
-  Merging and summarization can be parameterized by a function that groups
-  values into equivalence classes. Any function that returns a comparable
-  object can be used as a key_func, but merge_values and summary both use this
-  function by default, to allow the default grouping to change as Telemtry does.
-
-  Args:
-    value: A Telemetry Value instance
-
-  Returns:
-    A comparable object used to group values.
-  """
-  # We use the name and tir_label because even in the TBMv2 case, right now
-  # metrics are responsible for mangling grouping keys into the name, and
-  # PageTestResults is responsible for mangling story grouping keys into the
-  # tir_label.
-  return value.name, value.tir_label
-
-
-def MergeLikeValuesFromSamePage(all_values, key_func=DefaultKeyFunc):
-  """Merges values that measure the same thing on the same page.
-
-  A page may end up being measured multiple times, meaning that we may end up
-  with something like this:
-       ScalarValue(page1, 'x', 1, 'foo')
-       ScalarValue(page2, 'x', 4, 'bar')
-       ScalarValue(page1, 'x', 2, 'foo')
-       ScalarValue(page2, 'x', 5, 'baz')
-
-  This function will produce:
-       ListOfScalarValues(page1, 'x', [1, 2], 'foo')
-       ListOfScalarValues(page2, 'x', [4], 'bar')
-       ListOfScalarValues(page2, 'x', [5], 'baz')
-
-  The workhorse of this code is Value.MergeLikeValuesFromSamePage.
-
-  This requires (but assumes) that the values passed in with the same grouping
-  key pass the Value.IsMergableWith test. If this is not obeyed, the
-  results will be undefined.
-  """
-  return _MergeLikeValuesCommon(
-      all_values,
-      lambda x: (x.page, key_func(x)),
-      lambda v0, merge_group: v0.MergeLikeValuesFromSamePage(merge_group))
-
-
-def MergeLikeValuesFromDifferentPages(all_values, key_func=DefaultKeyFunc):
-  """Merges values that measure the same thing on different pages.
-
-  After using MergeLikeValuesFromSamePage, one still ends up with values from
-  different pages:
-       ScalarValue(page1, 'x', 1, 'foo')
-       ScalarValue(page1, 'y', 30, 'bar')
-       ScalarValue(page2, 'x', 2, 'foo')
-       ScalarValue(page2, 'y', 40, 'baz')
-
-  This function will group values with the same name and tir_label together:
-       ListOfScalarValues(None, 'x', [1, 2], 'foo')
-       ListOfScalarValues(None, 'y', [30], 'bar')
-       ListOfScalarValues(None, 'y', [40], 'baz')
-
-  The workhorse of this code is Value.MergeLikeValuesFromDifferentPages.
-
-  Not all values that go into this function will come out: not every value can
-  be merged across pages. Values whose MergeLikeValuesFromDifferentPages returns
-  None will be omitted from the results.
-
-  This requires (but assumes) that the values passed in with the same name pass
-  the Value.IsMergableWith test. If this is not obeyed, the results
-  will be undefined.
-  """
-  return _MergeLikeValuesCommon(
-      all_values,
-      key_func,
-      lambda v0, merge_group: v0.MergeLikeValuesFromDifferentPages(merge_group))
-
-
-def _MergeLikeValuesCommon(all_values, key_func, merge_func):
-  """Groups all_values by key_func then applies merge_func to the groups.
-
-  This takes the all_values list and groups each item in that using the key
-  provided by key_func. This produces groups of values with like keys. Thes are
-  then handed to the merge_func to produce a new key. If merge_func produces a
-  non-None return, it is added to the list of returned values.
-  """
-  # When merging, we want to merge values in a consistent order, e.g. so that
-  # Scalar(1), Scalar(2) predictably produces ListOfScalarValues([1,2]) rather
-  # than 2,1.
-  #
-  # To do this, the values are sorted by key up front. Then, grouping is
-  # performed using a dictionary, but as new groups are found, the order in
-  # which they were found is also noted.
-  #
-  # Merging is then performed on groups in group-creation-order. This ensures
-  # that the returned array is in a stable order, group by group.
-  #
-  # Within a group, the order is stable because of the original sort.
-  all_values = list(all_values)
-  merge_groups = GroupStably(all_values, key_func)
-
-  res = []
-  for merge_group in merge_groups:
-    v0 = merge_group[0]
-    vM = merge_func(v0, merge_group)
-    if vM:
-      res.append(vM)
-  return res
-
-def GroupStably(all_values, key_func):
-  """Groups an array by key_func, with the groups returned in a stable order.
-
-  Returns a list of groups.
-  """
-  all_values = list(all_values)
-
-  merge_groups = {}
-  merge_groups_in_creation_order = []
-  for value in all_values:
-    # TODO(chrishenry): This is temporary. When we figure out the
-    # right summarization strategy for page runs with failures/skips, we
-    # should use that instead.
-    should_skip_value = (isinstance(value, failure.FailureValue) or
-                         isinstance(value, skip.SkipValue))
-
-    if should_skip_value:
-      continue
-
-    key = key_func(value)
-    if key not in merge_groups:
-      merge_groups[key] = []
-      merge_groups_in_creation_order.append(merge_groups[key])
-    merge_groups[key].append(value)
-  return merge_groups_in_creation_order
diff --git a/catapult/telemetry/telemetry/value/merge_values_unittest.py b/catapult/telemetry/telemetry/value/merge_values_unittest.py
deleted file mode 100644
index 0725bdd..0000000
--- a/catapult/telemetry/telemetry/value/merge_values_unittest.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import merge_values
-from telemetry.value import scalar
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class MergeValueTest(TestBase):
-  def testDefaultKeyFuncWithTirLabel(self):
-    page0 = self.pages[0]
-
-    value = scalar.ScalarValue(
-        page0, 'x', 'units', 1,
-        improvement_direction=improvement_direction.UP,
-        tir_label='foo')
-
-    self.assertEquals(('x', 'foo'), merge_values.DefaultKeyFunc(value))
-
-  def testSamePageMergeBasic(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'x', 'units', 1,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'x', 'units', 4,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page0, 'x', 'units', 2,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'x', 'units', 5,
-                      improvement_direction=improvement_direction.UP)]
-
-    merged_values = merge_values.MergeLikeValuesFromSamePage(all_values)
-    # Sort the results so that their order is predictable for the subsequent
-    # assertions.
-    merged_values.sort(key=lambda x: x.page.url)
-
-    self.assertEquals(2, len(merged_values))
-
-    self.assertEquals((page0, 'x'),
-                      (merged_values[0].page, merged_values[0].name))
-    self.assertEquals([1, 2], merged_values[0].values)
-
-    self.assertEquals((page1, 'x'),
-                      (merged_values[1].page, merged_values[1].name))
-    self.assertEquals([4, 5], merged_values[1].values)
-
-  def testSamePageMergeNonstandardKeyFunc(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'x', 'units', 1,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'x', 'units', 4,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page0, 'y', 'units', 2,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'y', 'units', 5,
-                      improvement_direction=improvement_direction.UP)]
-
-    merged_values = merge_values.MergeLikeValuesFromSamePage(
-      all_values, key_func=lambda v: v.page.display_name)
-    # Sort the results so that their order is predictable for the subsequent
-    # assertions.
-    merged_values.sort(key=lambda x: x.page.url)
-
-    self.assertEquals(2, len(merged_values))
-    self.assertEquals([1, 2], merged_values[0].values)
-    self.assertEquals([4, 5], merged_values[1].values)
-
-  def testSamePageMergeOneValue(self):
-    page0 = self.pages[0]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'x', 'units', 1,
-                      improvement_direction=improvement_direction.DOWN)]
-
-    # Sort the results so that their order is predictable for the subsequent
-    # assertions.
-    merged_values = merge_values.MergeLikeValuesFromSamePage(all_values)
-    self.assertEquals(1, len(merged_values))
-    self.assertEquals(all_values[0].name, merged_values[0].name)
-    self.assertEquals(all_values[0].units, merged_values[0].units)
-
-  def testSamePageMergeWithInteractionRecord(self):
-    page0 = self.pages[0]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'foo-x', 'units', 1, tir_label='foo',
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page0, 'foo-x', 'units', 4, tir_label='foo',
-                      improvement_direction=improvement_direction.UP)]
-
-    merged_values = merge_values.MergeLikeValuesFromSamePage(all_values)
-    self.assertEquals(1, len(merged_values))
-    self.assertEquals('foo', merged_values[0].tir_label)
-
-  def testSamePageMergeWithTwoInteractionRecords(self):
-    page0 = self.pages[0]
-
-    all_values = [scalar.ScalarValue(page0, 'x', 'units', 1, tir_label='foo'),
-                  scalar.ScalarValue(page0, 'x', 'units', 4, tir_label='bar')]
-
-    merged_values = merge_values.MergeLikeValuesFromSamePage(all_values)
-    self.assertEquals(2, len(merged_values))
-    self.assertEquals('foo', merged_values[0].tir_label)
-    self.assertEquals('bar', merged_values[1].tir_label)
-
-  def testDifferentPageMergeBasic(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'x', 'units', 1,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'x', 'units', 2,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page0, 'y', 'units', 10,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'y', 'units', 20,
-                      improvement_direction=improvement_direction.UP)]
-
-    merged_values = merge_values.MergeLikeValuesFromDifferentPages(all_values)
-    merged_values.sort(key=lambda x: x.name)
-    self.assertEquals(2, len(merged_values))
-
-    self.assertEquals((None, 'x'),
-                      (merged_values[0].page, merged_values[0].name))
-    self.assertEquals([1, 2], merged_values[0].values)
-
-    self.assertEquals((None, 'y'),
-                      (merged_values[1].page, merged_values[1].name))
-    self.assertEquals([10, 20], merged_values[1].values)
-
-  def testDifferentPageMergeNonstandardKeyFunc(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'x', 'units', 1,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'x', 'units', 2,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page0, 'y', 'units', 10,
-                      improvement_direction=improvement_direction.UP),
-                  scalar.ScalarValue(
-                      page1, 'y', 'units', 20,
-                      improvement_direction=improvement_direction.UP)]
-
-    merged_values = merge_values.MergeLikeValuesFromDifferentPages(
-      all_values, key_func=lambda v: True)
-
-    self.assertEquals(1, len(merged_values))
-    self.assertEquals([1, 2, 10, 20], merged_values[0].values)
-
-  def testDifferentPageMergeSingleValueStillMerges(self):
-    page0 = self.pages[0]
-
-    all_values = [scalar.ScalarValue(
-                      page0, 'x', 'units', 1,
-                      improvement_direction=improvement_direction.DOWN)]
-
-    # Sort the results so that their order is predictable for the subsequent
-    # assertions.
-    merged_values = merge_values.MergeLikeValuesFromDifferentPages(all_values)
-    self.assertEquals(1, len(merged_values))
-
-    self.assertEquals((None, 'x'),
-                      (merged_values[0].page, merged_values[0].name))
-    self.assertTrue(
-        isinstance(merged_values[0], list_of_scalar_values.ListOfScalarValues))
-    self.assertEquals([1], merged_values[0].values)
-
-  def testDifferentPageMergeWithInteractionRecord(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    v0 = scalar.ScalarValue(page0, 'x', 'units', 1, tir_label='foo')
-    v1 = scalar.ScalarValue(page0, 'y', 'units', 30, tir_label='bar')
-    v2 = scalar.ScalarValue(page1, 'x', 'units', 2, tir_label='foo')
-    v3 = scalar.ScalarValue(page1, 'y', 'units', 40, tir_label='baz')
-
-    all_values = [v0, v1, v2, v3]
-
-    merged_x = list_of_scalar_values.ListOfScalarValues(
-      None, 'x', 'units', [1, 2], tir_label='foo')
-    merged_y_bar = list_of_scalar_values.ListOfScalarValues(
-      None, 'y', 'units', [30], tir_label='bar')
-    merged_y_baz = list_of_scalar_values.ListOfScalarValues(
-      None, 'y', 'units', [40], tir_label='baz')
-
-    merged_values = merge_values.MergeLikeValuesFromDifferentPages(all_values)
-    merged_values.sort(key=lambda x: x.tir_label)
-
-    self.assertEquals([merged_y_bar, merged_y_baz, merged_x], merged_values)
diff --git a/catapult/telemetry/telemetry/value/none_values.py b/catapult/telemetry/telemetry/value/none_values.py
deleted file mode 100644
index 7e2759a..0000000
--- a/catapult/telemetry/telemetry/value/none_values.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-MERGE_FAILURE_REASON = (
-    'Merging values containing a None value results in a None value.')
-
-class NoneValueMissingReason(Exception):
-  pass
-
-class ValueMustHaveNoneValue(Exception):
-  pass
-
-def ValidateNoneValueReason(value, none_value_reason):
-  """Ensures that the none_value_reason is appropriate for the given value.
-
-  There is a logical equality between having a value of None and having a
-  reason for being None. That is to say, value is None if and only if
-  none_value_reason is a string.
-  """
-  if value is None and not isinstance(none_value_reason, basestring):
-    raise NoneValueMissingReason()
-  if value is not None and none_value_reason is not None:
-    raise ValueMustHaveNoneValue()
diff --git a/catapult/telemetry/telemetry/value/scalar.py b/catapult/telemetry/telemetry/value/scalar.py
deleted file mode 100644
index 2a0a17a..0000000
--- a/catapult/telemetry/telemetry/value/scalar.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import numbers
-
-from telemetry import value as value_module
-from telemetry.value import list_of_scalar_values
-from telemetry.value import none_values
-from telemetry.value import summarizable
-
-
-class ScalarValue(summarizable.SummarizableValue):
-  def __init__(self, page, name, units, value, important=True,
-               description=None, tir_label=None,
-               none_value_reason=None, improvement_direction=None,
-               grouping_keys=None):
-    """A single value (float or integer) result from a test.
-
-    A test that counts the number of DOM elements in a page might produce a
-    scalar value:
-       ScalarValue(page, 'num_dom_elements', 'count', num_elements)
-    """
-    super(ScalarValue, self).__init__(page, name, units, important, description,
-                                      tir_label, improvement_direction,
-                                      grouping_keys)
-    assert value is None or isinstance(value, numbers.Number)
-    none_values.ValidateNoneValueReason(value, none_value_reason)
-    self.value = value
-    self.none_value_reason = none_value_reason
-
-  def __repr__(self):
-    if self.page:
-      page_name = self.page.display_name
-    else:
-      page_name = 'None'
-    return ('ScalarValue(%s, %s, %s, %s, important=%s, description=%s, '
-            'tir_label=%s, improvement_direction=%s, grouping_keys=%s') % (
-                page_name,
-                self.name,
-                self.units,
-                self.value,
-                self.important,
-                self.description,
-                self.tir_label,
-                self.improvement_direction,
-                self.grouping_keys)
-
-  def GetBuildbotDataType(self, output_context):
-    if self._IsImportantGivenOutputIntent(output_context):
-      return 'default'
-    return 'unimportant'
-
-  def GetBuildbotValue(self):
-    # Buildbot's print_perf_results method likes to get lists for all values,
-    # even when they are scalar, so list-ize the return value.
-    return [self.value]
-
-  def GetRepresentativeNumber(self):
-    return self.value
-
-  def GetRepresentativeString(self):
-    return str(self.value)
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'scalar'
-
-  def AsDict(self):
-    d = super(ScalarValue, self).AsDict()
-    d['value'] = self.value
-
-    if self.none_value_reason is not None:
-      d['none_value_reason'] = self.none_value_reason
-
-    return d
-
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
-
-    # Infinity and NaN are left out of JSON for security reasons that do not
-    # apply to our use cases, so TBMv2 serializes them as strings,
-    # but TBMv1 doesn't support them.
-    if value_dict['value'] in ['Infinity', '-Infinity', 'NaN']:
-      kwargs['value'] = None
-      kwargs['none_value_reason'] = 'value was ' + value_dict['value']
-    else:
-      kwargs['value'] = value_dict['value']
-
-    if 'improvement_direction' in value_dict:
-      kwargs['improvement_direction'] = value_dict['improvement_direction']
-    if 'none_value_reason' in value_dict:
-      kwargs['none_value_reason'] = value_dict['none_value_reason']
-
-    return ScalarValue(**kwargs)
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    assert len(values) > 0
-    v0 = values[0]
-    return cls._MergeLikeValues(values, v0.page, v0.name, v0.grouping_keys)
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    assert len(values) > 0
-    v0 = values[0]
-    return cls._MergeLikeValues(values, None, v0.name, v0.grouping_keys)
-
-  @classmethod
-  def _MergeLikeValues(cls, values, page, name, grouping_keys):
-    v0 = values[0]
-
-    merged_value = [v.value for v in values]
-    none_value_reason = None
-    if None in merged_value:
-      merged_value = None
-      merged_none_values = [v for v in values if v.value is None]
-      none_value_reason = (
-          none_values.MERGE_FAILURE_REASON +
-          ' None values: %s' % repr(merged_none_values))
-    return list_of_scalar_values.ListOfScalarValues(
-        page, name, v0.units, merged_value, important=v0.important,
-        description=v0.description,
-        tir_label=value_module.MergedTirLabel(values),
-        none_value_reason=none_value_reason,
-        improvement_direction=v0.improvement_direction,
-        grouping_keys=grouping_keys)
diff --git a/catapult/telemetry/telemetry/value/scalar_unittest.py b/catapult/telemetry/telemetry/value/scalar_unittest.py
deleted file mode 100644
index a37d5d4..0000000
--- a/catapult/telemetry/telemetry/value/scalar_unittest.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry import value
-from telemetry.value import improvement_direction
-from telemetry.value import none_values
-from telemetry.value import scalar
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class ValueTest(TestBase):
-  def testRepr(self):
-    page0 = self.pages[0]
-    v = scalar.ScalarValue(page0, 'x', 'unit', 3, important=True,
-                           description='desc', tir_label='my_ir',
-                           improvement_direction=improvement_direction.DOWN)
-
-    expected = ('ScalarValue(http://www.bar.com/, x, unit, 3, important=True, '
-                'description=desc, tir_label=my_ir, '
-                'improvement_direction=down, grouping_keys={}')
-
-    self.assertEquals(expected, str(v))
-
-  def testBuildbotValueType(self):
-    page0 = self.pages[0]
-    v = scalar.ScalarValue(page0, 'x', 'unit', 3, important=True,
-                           improvement_direction=improvement_direction.DOWN)
-    self.assertEquals('default', v.GetBuildbotDataType(
-        value.COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT))
-    self.assertEquals([3], v.GetBuildbotValue())
-    self.assertEquals(('x', page0.display_name),
-                      v.GetChartAndTraceNameForPerPageResult())
-
-    v = scalar.ScalarValue(page0, 'x', 'unit', 3, important=False,
-                           improvement_direction=improvement_direction.DOWN)
-    self.assertEquals(
-        'unimportant',
-        v.GetBuildbotDataType(value.COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT))
-
-  def testScalarSamePageMerging(self):
-    page0 = self.pages[0]
-    v0 = scalar.ScalarValue(page0, 'x', 'unit', 1,
-                            description='important metric',
-                            improvement_direction=improvement_direction.UP)
-    v1 = scalar.ScalarValue(page0, 'x', 'unit', 2,
-                            description='important metric',
-                            improvement_direction=improvement_direction.UP)
-    self.assertTrue(v1.IsMergableWith(v0))
-
-    vM = scalar.ScalarValue.MergeLikeValuesFromSamePage([v0, v1])
-    self.assertEquals(page0, vM.page)
-    self.assertEquals('x', vM.name)
-    self.assertEquals('unit', vM.units)
-    self.assertEquals('important metric', vM.description)
-    self.assertEquals(True, vM.important)
-    self.assertEquals([1, 2], vM.values)
-    self.assertEquals(improvement_direction.UP, vM.improvement_direction)
-
-  def testScalarDifferentPageMerging(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-    v0 = scalar.ScalarValue(page0, 'x', 'unit', 1,
-                            description='important metric',
-                            improvement_direction=improvement_direction.UP)
-    v1 = scalar.ScalarValue(page1, 'x', 'unit', 2,
-                            description='important metric',
-                            improvement_direction=improvement_direction.UP)
-
-    vM = scalar.ScalarValue.MergeLikeValuesFromDifferentPages([v0, v1])
-    self.assertEquals(None, vM.page)
-    self.assertEquals('x', vM.name)
-    self.assertEquals('unit', vM.units)
-    self.assertEquals('important metric', vM.description)
-    self.assertEquals(True, vM.important)
-    self.assertEquals([1, 2], vM.values)
-    self.assertEquals(improvement_direction.UP, vM.improvement_direction)
-
-  def testScalarWithNoneValueMerging(self):
-    page0 = self.pages[0]
-    v0 = scalar.ScalarValue(
-        page0, 'x', 'unit', 1, improvement_direction=improvement_direction.DOWN)
-    v1 = scalar.ScalarValue(page0, 'x', 'unit', None, none_value_reason='n',
-                            improvement_direction=improvement_direction.DOWN)
-    self.assertTrue(v1.IsMergableWith(v0))
-
-    vM = scalar.ScalarValue.MergeLikeValuesFromSamePage([v0, v1])
-    self.assertEquals(None, vM.values)
-    expected_none_value_reason = (
-        'Merging values containing a None value results in a None value. '
-        'None values: [ScalarValue(http://www.bar.com/, x, unit, None, '
-        'important=True, description=None, tir_label=None, '
-        'improvement_direction=down, grouping_keys={}]')
-    self.assertEquals(expected_none_value_reason, vM.none_value_reason)
-
-  def testScalarWithNoneValueMustHaveNoneReason(self):
-    page0 = self.pages[0]
-    self.assertRaises(none_values.NoneValueMissingReason,
-                      lambda: scalar.ScalarValue(
-                          page0, 'x', 'unit', None,
-                          improvement_direction=improvement_direction.UP))
-
-  def testScalarWithNoneReasonMustHaveNoneValue(self):
-    page0 = self.pages[0]
-    self.assertRaises(none_values.ValueMustHaveNoneValue,
-                      lambda: scalar.ScalarValue(
-                          page0, 'x', 'unit', 1, none_value_reason='n',
-                          improvement_direction=improvement_direction.UP))
-
-  def testAsDict(self):
-    v = scalar.ScalarValue(None, 'x', 'unit', 42, important=False,
-                           improvement_direction=improvement_direction.DOWN)
-    d = v.AsDictWithoutBaseClassEntries()
-
-    self.assertEquals(d, {
-          'value': 42
-        })
-
-  def testNoneValueAsDict(self):
-    v = scalar.ScalarValue(None, 'x', 'unit', None, important=False,
-                           none_value_reason='n',
-                           improvement_direction=improvement_direction.DOWN)
-    d = v.AsDictWithoutBaseClassEntries()
-
-    self.assertEquals(d, {
-          'value': None,
-          'none_value_reason': 'n'
-        })
-
-  def testFromDictInt(self):
-    d = {
-      'type': 'scalar',
-      'name': 'x',
-      'units': 'unit',
-      'value': 42,
-      'improvement_direction': improvement_direction.DOWN,
-    }
-
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, scalar.ScalarValue))
-    self.assertEquals(v.value, 42)
-    self.assertEquals(v.improvement_direction, improvement_direction.DOWN)
-
-  def testFromDictFloat(self):
-    d = {
-      'type': 'scalar',
-      'name': 'x',
-      'units': 'unit',
-      'value': 42.4,
-      'improvement_direction': improvement_direction.UP,
-    }
-
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, scalar.ScalarValue))
-    self.assertEquals(v.value, 42.4)
-
-  def testFromDictWithoutImprovementDirection(self):
-    d = {
-      'type': 'scalar',
-      'name': 'x',
-      'units': 'unit',
-      'value': 42,
-    }
-
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, scalar.ScalarValue))
-    self.assertIsNone(v.improvement_direction)
-
-  def testFromDictNoneValue(self):
-    d = {
-      'type': 'scalar',
-      'name': 'x',
-      'units': 'unit',
-      'value': None,
-      'none_value_reason': 'n',
-      'improvement_direction': improvement_direction.UP,
-    }
-
-    v = value.Value.FromDict(d, {})
-
-    self.assertTrue(isinstance(v, scalar.ScalarValue))
-    self.assertEquals(v.value, None)
-    self.assertEquals(v.none_value_reason, 'n')
diff --git a/catapult/telemetry/telemetry/value/skip.py b/catapult/telemetry/telemetry/value/skip.py
deleted file mode 100644
index 1dd0108..0000000
--- a/catapult/telemetry/telemetry/value/skip.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import value as value_module
-
-
-class SkipValue(value_module.Value):
-
-  def __init__(self, page, reason, description=None):
-    """A value representing a skipped page.
-
-    Args:
-      page: The skipped page object.
-      reason: The string reason the page was skipped.
-    """
-    super(SkipValue, self).__init__(page, 'skip', '', True, description, None,
-                                    None)
-    self._reason = reason
-
-  def __repr__(self):
-    page_name = self.page.display_name
-    return 'SkipValue(%s, %s, description=%s)' % (page_name, self._reason,
-                                                  self.description)
-
-  @property
-  def reason(self):
-    return self._reason
-
-  def GetBuildbotDataType(self, output_context):
-    return None
-
-  def GetBuildbotValue(self):
-    return None
-
-  def GetChartAndTraceNameForPerPageResult(self):
-    return None
-
-  def GetRepresentativeNumber(self):
-    return None
-
-  def GetRepresentativeString(self):
-    return None
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'skip'
-
-  def AsDict(self):
-    d = super(SkipValue, self).AsDict()
-    d['reason'] = self._reason
-    return d
-
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    kwargs = value_module.Value.GetConstructorKwArgs(value_dict, page_dict)
-    del kwargs['name']
-    del kwargs['units']
-    if 'important' in kwargs:
-      del kwargs['important']
-    kwargs['reason'] = value_dict['reason']
-    if 'tir_label' in kwargs:
-      del kwargs['tir_label']
-    if 'grouping_keys' in kwargs:
-      del kwargs['grouping_keys']
-
-    return SkipValue(**kwargs)
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    assert False, 'Should not be called.'
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    assert False, 'Should not be called.'
diff --git a/catapult/telemetry/telemetry/value/skip_unittest.py b/catapult/telemetry/telemetry/value/skip_unittest.py
deleted file mode 100644
index 9b11579..0000000
--- a/catapult/telemetry/telemetry/value/skip_unittest.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry import value
-from telemetry.value import skip
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class ValueTest(TestBase):
-  def testRepr(self):
-    v = skip.SkipValue(self.pages[0], 'page skipped for testing reason',
-                       description='desc')
-
-    expected = ('SkipValue(http://www.bar.com/, '
-                'page skipped for testing reason, '
-                'description=desc)')
-
-    self.assertEquals(expected, str(v))
-
-  def testBuildbotAndRepresentativeValue(self):
-    v = skip.SkipValue(self.pages[0], 'page skipped for testing reason')
-    self.assertIsNone(v.GetBuildbotValue())
-    self.assertIsNone(v.GetBuildbotDataType(
-        value.COMPUTED_PER_PAGE_SUMMARY_OUTPUT_CONTEXT))
-    self.assertIsNone(v.GetChartAndTraceNameForPerPageResult())
-    self.assertIsNone(v.GetRepresentativeNumber())
-    self.assertIsNone(v.GetRepresentativeString())
-
-  def testAsDict(self):
-    v = skip.SkipValue(self.pages[0], 'page skipped for testing reason')
-    d = v.AsDictWithoutBaseClassEntries()
-    self.assertEquals(d['reason'], 'page skipped for testing reason')
-
-  def testFromDict(self):
-    d = {
-      'type': 'skip',
-      'name': 'skip',
-      'units': '',
-      'reason': 'page skipped for testing reason'
-    }
-    v = value.Value.FromDict(d, {})
-    self.assertTrue(isinstance(v, skip.SkipValue))
-    self.assertEquals(v.reason, 'page skipped for testing reason')
diff --git a/catapult/telemetry/telemetry/value/summarizable.py b/catapult/telemetry/telemetry/value/summarizable.py
deleted file mode 100644
index 9cfcf46..0000000
--- a/catapult/telemetry/telemetry/value/summarizable.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import value as value_module
-from telemetry.value import (improvement_direction
-                             as improvement_direction_module)
-
-
-class SummarizableValue(value_module.Value):
-  def __init__(self, page, name, units, important, description, tir_label,
-               improvement_direction, grouping_keys):
-    """A summarizable value result from a test."""
-    super(SummarizableValue, self).__init__(
-        page, name, units, important, description, tir_label, grouping_keys)
-# TODO(eakuefner): uncomment this assert after Telemetry clients are fixed.
-# Note: Telemetry unittests satisfy this assert.
-#    assert improvement_direction_module.IsValid(improvement_direction)
-    self._improvement_direction = improvement_direction
-
-  @property
-  def improvement_direction(self):
-    return self._improvement_direction
-
-  def AsDict(self):
-    d = super(SummarizableValue, self).AsDict()
-    if improvement_direction_module.IsValid(self.improvement_direction):
-      d['improvement_direction'] = self.improvement_direction
-    return d
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'summarizable'
-
-  def AsDictWithoutBaseClassEntries(self):
-    d = super(SummarizableValue, self).AsDictWithoutBaseClassEntries()
-    if 'improvement_direction' in d:
-      del d['improvement_direction']
-    return d
-
-  def GetBuildbotDataType(self, output_context):
-    """Returns the buildbot's equivalent data_type.
-
-    This should be one of the values accepted by perf_tests_results_helper.py.
-    """
-    raise NotImplementedError()
-
-  def GetBuildbotValue(self):
-    """Returns the buildbot's equivalent value."""
-    raise NotImplementedError()
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    raise NotImplementedError()
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    raise NotImplementedError()
-
-  def GetRepresentativeNumber(self):
-    """Gets a single scalar value that best-represents this value.
-
-    Returns None if not possible.
-    """
-    raise NotImplementedError()
-
-  def GetRepresentativeString(self):
-    """Gets a string value that best-represents this value.
-
-    Returns None if not possible.
-    """
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/value/summarizable_unittest.py b/catapult/telemetry/telemetry/value/summarizable_unittest.py
deleted file mode 100644
index 54a94b2..0000000
--- a/catapult/telemetry/telemetry/value/summarizable_unittest.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.value import summarizable
-
-class SummarizableTest(unittest.TestCase):
-
-  def testAsDictWithoutImprovementDirection(self):
-    value = summarizable.SummarizableValue(
-        None, 'foo', 'bars', important=False, description='desc',
-        tir_label=None, improvement_direction=None, grouping_keys=None)
-
-    self.assertNotIn('improvement_direction', value.AsDict())
-
-  def testAsDictWithoutBaseClassEntries(self):
-    value = summarizable.SummarizableValue(
-        None, 'foo', 'bars', important=False, description='desc',
-        tir_label=None, improvement_direction=None, grouping_keys=None)
-
-    self.assertFalse(value.AsDictWithoutBaseClassEntries())
-
-  def testAsDictWithInvalidImprovementDirection(self):
-    # TODO(eakuefner): Remove this test when we check I.D. in constructor
-    value = summarizable.SummarizableValue(
-        None, 'foo', 'bars', important=False, description='desc',
-        tir_label=None, improvement_direction='baz', grouping_keys=None)
-
-    self.assertNotIn('improvement_direction', value.AsDict())
diff --git a/catapult/telemetry/telemetry/value/summary.py b/catapult/telemetry/telemetry/value/summary.py
deleted file mode 100644
index 3043f6d..0000000
--- a/catapult/telemetry/telemetry/value/summary.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from collections import defaultdict
-
-from telemetry.value import failure
-from telemetry.value import merge_values
-from telemetry.value import skip
-
-
-class Summary(object):
-  """Computes summary values from the per-page-run values produced by a test.
-
-  Some telemetry benchmark repeat a number of times in order to get a reliable
-  measurement. The test does not have to handle merging of these runs:
-  summarizer does it for you.
-
-  For instance, if two pages run, 3 and 1 time respectively:
-      ScalarValue(page1, 'foo', units='ms', 1)
-      ScalarValue(page1, 'foo', units='ms', 1)
-      ScalarValue(page1, 'foo', units='ms', 1)
-      ScalarValue(page2, 'foo', units='ms', 2)
-
-  Then summarizer will produce two sets of values. First,
-  computed_per_page_values:
-      [
-         ListOfScalarValues(page1, 'foo', units='ms', [1,1,1])],
-         ListOfScalarValues(page2, 'foo', units='ms', [2])]
-      ]
-
-  In addition, it will produce a summary value:
-      [
-         ListOfScalarValues(page=None, 'foo', units='ms', [1,1,1,2])]
-      ]
-
-  """
-  def __init__(self, all_page_specific_values,
-               key_func=merge_values.DefaultKeyFunc):
-    had_failures = any(isinstance(v, failure.FailureValue) for v in
-        all_page_specific_values)
-    self.had_failures = had_failures
-    self._computed_per_page_values = []
-    self._computed_summary_values = []
-    self._interleaved_computed_per_page_values_and_summaries = []
-    self._key_func = key_func
-    self._ComputePerPageValues(all_page_specific_values)
-
-  @property
-  def computed_per_page_values(self):
-    return self._computed_per_page_values
-
-  @property
-  def computed_summary_values(self):
-    return self._computed_summary_values
-
-  @property
-  def interleaved_computed_per_page_values_and_summaries(self):
-    """Returns the computed per page values and summary values interleaved.
-
-    All the results for a given name are printed together. First per page
-    values, then summary values.
-
-    """
-    return self._interleaved_computed_per_page_values_and_summaries
-
-  def _ComputePerPageValues(self, all_page_specific_values):
-    all_successful_page_values = [
-        v for v in all_page_specific_values if not (isinstance(
-            v, failure.FailureValue) or isinstance(v, skip.SkipValue))]
-
-    # We will later need to determine how many values were originally created
-    # for each value name, to apply a workaround meant to clean up the printf
-    # output.
-    num_successful_pages_for_key = defaultdict(int)
-    for v in all_successful_page_values:
-      num_successful_pages_for_key[self._key_func(v)] += 1
-
-    # By here, due to page repeat options, all_values_from_successful_pages
-    # contains values of the same name not only from mulitple pages, but also
-    # from the same name. So even if, for instance, only one page ran, it may
-    # have run twice, producing two 'x' values.
-    #
-    # So, get rid of the repeated pages by merging.
-    merged_page_values = merge_values.MergeLikeValuesFromSamePage(
-        all_successful_page_values, self._key_func)
-
-    # Now we have a bunch of values, but there is only one value_name per page.
-    # Suppose page1 and page2 ran, producing values x and y. We want to print
-    #    x for page1
-    #    x for page2
-    #    x for page1, page2 combined
-    #
-    #    y for page1
-    #    y for page2
-    #    y for page1, page2 combined
-    #
-    # We already have the x values in the values array. But, we will need
-    # them indexable by summary key.
-    #
-    # The following dict maps summary_key -> list of pages that have values of
-    # that name.
-    per_page_values_by_key = defaultdict(list)
-    for value in merged_page_values:
-      per_page_values_by_key[self._key_func(value)].append(value)
-
-    # We already have the x values in the values array. But, we also need
-    # the values merged across the pages. And, we will need them indexed by
-    # summary key so that we can find them when printing out value names in
-    # alphabetical order.
-    merged_pages_value_by_key = {}
-    if not self.had_failures:
-      for value in merge_values.MergeLikeValuesFromDifferentPages(
-          merged_page_values, self._key_func):
-        value_key = self._key_func(value)
-        assert value_key not in merged_pages_value_by_key
-        merged_pages_value_by_key[value_key] = value
-
-    keys = sorted(set([self._key_func(v) for v in merged_page_values]))
-
-    # Time to walk through the values by key, printing first the page-specific
-    # values and then the merged_site value.
-    for key in keys:
-      per_page_values = per_page_values_by_key.get(key, [])
-
-      # Sort the values by their URL.
-      sorted_per_page_values = list(per_page_values)
-      sorted_per_page_values.sort(
-          key=lambda per_page_values: per_page_values.page.display_name)
-
-      # Output the page-specific results.
-      num_successful_pages_for_this_key = (
-          num_successful_pages_for_key[key])
-      for per_page_value in sorted_per_page_values:
-        self._ComputePerPageValue(per_page_value,
-                                  num_successful_pages_for_this_key)
-
-      # Output the combined values.
-      merged_pages_value = merged_pages_value_by_key.get(key, None)
-      if merged_pages_value:
-        self._computed_summary_values.append(merged_pages_value)
-        self._interleaved_computed_per_page_values_and_summaries.append(
-            merged_pages_value)
-
-  def _ComputePerPageValue(
-      self, value, num_successful_pages_for_this_value_name):
-    if num_successful_pages_for_this_value_name >= 1:
-      # Save the result.
-      self._computed_per_page_values.append(value)
-      self._interleaved_computed_per_page_values_and_summaries.append(value)
diff --git a/catapult/telemetry/telemetry/value/summary_unittest.py b/catapult/telemetry/telemetry/value/summary_unittest.py
deleted file mode 100644
index f0a29fb..0000000
--- a/catapult/telemetry/telemetry/value/summary_unittest.py
+++ /dev/null
@@ -1,429 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import math
-import os
-import unittest
-
-from telemetry import story
-from telemetry.internal.results import page_test_results
-from telemetry import page as page_module
-from telemetry.value import failure
-from telemetry.value import histogram
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-from telemetry.value import summary as summary_module
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-
-class SummaryTest(TestBase):
-  def testBasicSummary(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v1 = scalar.ScalarValue(page1, 'a', 'seconds', 7,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    v0_list = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [3],
-        improvement_direction=improvement_direction.UP)
-    v1_list = list_of_scalar_values.ListOfScalarValues(
-        page1, 'a', 'seconds', [7],
-        improvement_direction=improvement_direction.UP)
-    # Std is 0 because we only have one measurement per page.
-    merged_value = list_of_scalar_values.ListOfScalarValues(
-        None, 'a', 'seconds', [3, 7], std=0.0,
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(3, len(values))
-    self.assertIn(v0_list, values)
-    self.assertIn(v1_list, values)
-    self.assertIn(merged_value, values)
-
-  def testBasicSummaryWithOnlyOnePage(self):
-    page0 = self.pages[0]
-
-    results = page_test_results.PageTestResults()
-
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    v0_list = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [3],
-        improvement_direction=improvement_direction.UP)
-    merged_list = list_of_scalar_values.ListOfScalarValues(
-        None, 'a', 'seconds', [3],
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(2, len(values))
-    self.assertIn(v0_list, values)
-    self.assertIn(merged_list, values)
-
-  def testBasicSummaryNonuniformResults(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-    page2 = self.pages[2]
-
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    v1 = scalar.ScalarValue(page0, 'b', 'seconds', 10,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v2 = scalar.ScalarValue(page1, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v2)
-    v3 = scalar.ScalarValue(page1, 'b', 'seconds', 10,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v3)
-    results.DidRunPage(page1)
-
-    results.WillRunPage(page2)
-    v4 = scalar.ScalarValue(page2, 'a', 'seconds', 7,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v4)
-    # Note, page[2] does not report a 'b' metric.
-    results.DidRunPage(page2)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    v0_list = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [3],
-        improvement_direction=improvement_direction.UP)
-    v1_list = list_of_scalar_values.ListOfScalarValues(
-        page0, 'b', 'seconds', [10],
-        improvement_direction=improvement_direction.UP)
-    v2_list = list_of_scalar_values.ListOfScalarValues(
-        page1, 'a', 'seconds', [3],
-        improvement_direction=improvement_direction.UP)
-    v3_list = list_of_scalar_values.ListOfScalarValues(
-        page1, 'b', 'seconds', [10],
-        improvement_direction=improvement_direction.UP)
-    v4_list = list_of_scalar_values.ListOfScalarValues(
-        page2, 'a', 'seconds', [7],
-        improvement_direction=improvement_direction.UP)
-    # Std is 0 because we only have one measurement per page.
-    a_summary = list_of_scalar_values.ListOfScalarValues(
-        None, 'a', 'seconds', [3, 3, 7], std=0.0,
-        improvement_direction=improvement_direction.UP)
-    b_summary = list_of_scalar_values.ListOfScalarValues(
-        None, 'b', 'seconds', [10, 10], std=0.0,
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(7, len(values))
-    self.assertIn(v0_list, values)
-    self.assertIn(v1_list, values)
-    self.assertIn(v2_list, values)
-    self.assertIn(v3_list, values)
-    self.assertIn(v4_list, values)
-    self.assertIn(a_summary, values)
-    self.assertIn(b_summary, values)
-
-  def testBasicSummaryPassAndFailPage(self):
-    """If a page failed, only print summary for individual pages."""
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    v1 = failure.FailureValue.FromMessage(page0, 'message')
-    results.AddValue(v1)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v2 = scalar.ScalarValue(page1, 'a', 'seconds', 7,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v2)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    v0_list = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [3],
-        improvement_direction=improvement_direction.UP)
-    v2_list = list_of_scalar_values.ListOfScalarValues(
-        page1, 'a', 'seconds', [7],
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(2, len(values))
-    self.assertIn(v0_list, values)
-    self.assertIn(v2_list, values)
-
-  def testRepeatedPagesetOneIterationOnePageFails(self):
-    """Page fails on one iteration, no averaged results should print."""
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v1 = scalar.ScalarValue(page1, 'a', 'seconds', 7,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    v2 = failure.FailureValue.FromMessage(page1, 'message')
-    results.AddValue(v2)
-    results.DidRunPage(page1)
-
-    results.WillRunPage(page0)
-    v3 = scalar.ScalarValue(page0, 'a', 'seconds', 4,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v3)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v4 = scalar.ScalarValue(page1, 'a', 'seconds', 8,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v4)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    page0_aggregated = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [3, 4],
-        improvement_direction=improvement_direction.UP)
-    page1_aggregated = list_of_scalar_values.ListOfScalarValues(
-        page1, 'a', 'seconds', [7, 8],
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(2, len(values))
-    self.assertIn(page0_aggregated, values)
-    self.assertIn(page1_aggregated, values)
-
-  def testRepeatedPages(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page0)
-    v2 = scalar.ScalarValue(page0, 'a', 'seconds', 4,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v2)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v1 = scalar.ScalarValue(page1, 'a', 'seconds', 7,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page1)
-
-    results.WillRunPage(page1)
-    v3 = scalar.ScalarValue(page1, 'a', 'seconds', 8,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v3)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    page0_aggregated = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [3, 4],
-        improvement_direction=improvement_direction.UP)
-    page1_aggregated = list_of_scalar_values.ListOfScalarValues(
-        page1, 'a', 'seconds', [7, 8],
-        improvement_direction=improvement_direction.UP)
-    # Std is computed using pooled standard deviation.
-    a_summary = list_of_scalar_values.ListOfScalarValues(
-        None, 'a', 'seconds', [3, 4, 7, 8], std=math.sqrt(0.5),
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(3, len(values))
-    self.assertIn(page0_aggregated, values)
-    self.assertIn(page1_aggregated, values)
-    self.assertIn(a_summary, values)
-
-  def testPageRunsTwice(self):
-    page0 = self.pages[0]
-
-    results = page_test_results.PageTestResults()
-
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'b', 'seconds', 2,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page0)
-    v1 = scalar.ScalarValue(page0, 'b', 'seconds', 3,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page0)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    page0_aggregated = list_of_scalar_values.ListOfScalarValues(
-        page0, 'b', 'seconds', [2, 3],
-        improvement_direction=improvement_direction.UP)
-    b_summary = list_of_scalar_values.ListOfScalarValues(
-        None, 'b', 'seconds', [2, 3],
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(2, len(values))
-    self.assertIn(page0_aggregated, values)
-    self.assertIn(b_summary, values)
-
-  def testListValue(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-
-    results.WillRunPage(page0)
-    v0 = list_of_scalar_values.ListOfScalarValues(
-        page0, 'b', 'seconds', [2, 2],
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v1 = list_of_scalar_values.ListOfScalarValues(
-        page1, 'b', 'seconds', [3, 3],
-        improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    b_summary = list_of_scalar_values.ListOfScalarValues(
-        None, 'b', 'seconds', [2, 2, 3, 3], std=0.0,
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(3, len(values))
-    self.assertIn(v0, values)
-    self.assertIn(v1, values)
-    self.assertIn(b_summary, values)
-
-  def testHistogram(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(page0)
-    v0 = histogram.HistogramValue(
-        page0, 'a', 'units',
-        raw_value_json='{"buckets": [{"low": 1, "high": 2, "count": 1}]}',
-        important=False, improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v1 = histogram.HistogramValue(
-        page1, 'a', 'units',
-        raw_value_json='{"buckets": [{"low": 2, "high": 3, "count": 1}]}',
-        important=False, improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(results.all_page_specific_values)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    self.assertEquals(2, len(values))
-    self.assertIn(v0, values)
-    self.assertIn(v1, values)
-
-  def testSummaryUsesKeyFunc(self):
-    page0 = self.pages[0]
-    page1 = self.pages[1]
-
-    results = page_test_results.PageTestResults()
-
-    results.WillRunPage(page0)
-    v0 = scalar.ScalarValue(page0, 'a', 'seconds', 20,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v0)
-
-    v1 = scalar.ScalarValue(page0, 'b', 'seconds', 42,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v1)
-    results.DidRunPage(page0)
-
-    results.WillRunPage(page1)
-    v2 = scalar.ScalarValue(page1, 'a', 'seconds', 20,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v2)
-
-    v3 = scalar.ScalarValue(page1, 'b', 'seconds', 42,
-                            improvement_direction=improvement_direction.UP)
-    results.AddValue(v3)
-    results.DidRunPage(page1)
-
-    summary = summary_module.Summary(
-        results.all_page_specific_values,
-        key_func=lambda v: True)
-    values = summary.interleaved_computed_per_page_values_and_summaries
-
-    v0_list = list_of_scalar_values.ListOfScalarValues(
-        page0, 'a', 'seconds', [20, 42],
-        improvement_direction=improvement_direction.UP)
-    v2_list = list_of_scalar_values.ListOfScalarValues(
-        page1, 'a', 'seconds', [20, 42],
-        improvement_direction=improvement_direction.UP)
-    # Std is computed using pooled standard deviation.
-    merged_value = list_of_scalar_values.ListOfScalarValues(
-        None, 'a', 'seconds', [20, 42, 20, 42], std=math.sqrt(242.0),
-        improvement_direction=improvement_direction.UP)
-
-    self.assertEquals(3, len(values))
-    self.assertIn(v0_list, values)
-    self.assertIn(v2_list, values)
-    self.assertIn(merged_value, values)
diff --git a/catapult/telemetry/telemetry/value/trace.py b/catapult/telemetry/telemetry/value/trace.py
deleted file mode 100644
index b6b756d..0000000
--- a/catapult/telemetry/telemetry/value/trace.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import datetime
-import logging
-import os
-import random
-import shutil
-import sys
-import tempfile
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.internal.util import file_handle
-from telemetry.timeline import trace_data as trace_data_module
-from telemetry import value as value_module
-from tracing.trace_data import trace_data as trace_data_module
-
-
-class TraceValue(value_module.Value):
-  def __init__(self, page, trace_data, important=False, description=None):
-    """A value that contains a TraceData object and knows how to
-    output it.
-
-    Adding TraceValues and outputting as JSON will produce a directory full of
-    HTML files called trace_files. Outputting as chart JSON will also produce
-    an index, files.html, linking to each of these files.
-    """
-    super(TraceValue, self).__init__(
-        page, name='trace', units='', important=important,
-        description=description, tir_label=None, grouping_keys=None)
-    self._temp_file = self._GetTempFileHandle(trace_data)
-    self._cloud_url = None
-    self._serialized_file_handle = None
-
-  @property
-  def value(self):
-    if self._cloud_url:
-      return self._cloud_url
-    elif self._serialized_file_handle:
-      return self._serialized_file_handle.GetAbsPath()
-
-  def _GetTraceParts(self, trace_data):
-    return [(trace_data.GetTracesFor(p), p)
-            for p in trace_data_module.ALL_TRACE_PARTS
-            if trace_data.HasTracesFor(p)]
-
-  def _GetTempFileHandle(self, trace_data):
-    tf = tempfile.NamedTemporaryFile(delete=False, suffix='.html')
-    tf.close()
-    title = ''
-    if self.page:
-      title = self.page.display_name
-    trace_data.Serialize(tf.name, trace_title=title)
-    return file_handle.FromFilePath(tf.name)
-
-  def __repr__(self):
-    if self.page:
-      page_name = self.page.display_name
-    else:
-      page_name = 'None'
-    return 'TraceValue(%s, %s)' % (page_name, self.name)
-
-  def CleanUp(self):
-    """Cleans up tempfile after it is no longer needed.
-
-    A cleaned up TraceValue cannot be used for further operations. CleanUp()
-    may be called more than once without error.
-    """
-    if self._temp_file is None:
-      return
-    os.remove(self._temp_file.GetAbsPath())
-    self._temp_file = None
-
-  def __enter__(self):
-    return self
-
-  def __exit__(self, _, __, ___):
-    self.CleanUp()
-
-  @property
-  def cleaned_up(self):
-    return self._temp_file is None
-
-  @property
-  def filename(self):
-    return self._temp_file.GetAbsPath()
-
-  def GetBuildbotDataType(self, output_context):
-    return None
-
-  def GetBuildbotValue(self):
-    return None
-
-  def GetRepresentativeNumber(self):
-    return None
-
-  def GetRepresentativeString(self):
-    return None
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'trace'
-
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    assert len(values) > 0
-    return values[0]
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    return None
-
-  def AsDict(self):
-    if self._temp_file is None:
-      raise ValueError('Tried to serialize TraceValue without tempfile.')
-    d = super(TraceValue, self).AsDict()
-    if self._serialized_file_handle:
-      d['file_id'] = self._serialized_file_handle.id
-    if self._cloud_url:
-      d['cloud_url'] = self._cloud_url
-    return d
-
-  def Serialize(self, dir_path):
-    if self._temp_file is None:
-      raise ValueError('Tried to serialize nonexistent trace.')
-    if self.page:
-      file_name = self.page.file_safe_name
-    else:
-      file_name = ''
-    file_name += str(self._temp_file.id)
-    file_name += datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S')
-    file_name += self._temp_file.extension
-    file_path = os.path.abspath(os.path.join(dir_path, file_name))
-    shutil.copy(self._temp_file.GetAbsPath(), file_path)
-    self._serialized_file_handle = file_handle.FromFilePath(file_path)
-    return self._serialized_file_handle
-
-  def UploadToCloud(self, bucket):
-    if self._temp_file is None:
-      raise ValueError('Tried to upload nonexistent trace to Cloud Storage.')
-    try:
-      if self._serialized_file_handle:
-        fh = self._serialized_file_handle
-      else:
-        fh = self._temp_file
-      remote_path = ('trace-file-id_%s-%s-%d%s' % (
-          fh.id,
-          datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'),
-          random.randint(1, 100000),
-          fh.extension))
-      self._cloud_url = cloud_storage.Insert(
-          bucket, remote_path, fh.GetAbsPath())
-      sys.stderr.write(
-          'View generated trace files online at %s for page %s\n' %
-          (self._cloud_url, self.page.url if self.page else 'unknown'))
-      return self._cloud_url
-    except cloud_storage.PermissionError as e:
-      logging.error('Cannot upload trace files to cloud storage due to '
-                    ' permission error: %s' % e.message)
diff --git a/catapult/telemetry/telemetry/value/trace_unittest.py b/catapult/telemetry/telemetry/value/trace_unittest.py
deleted file mode 100644
index a95d000..0000000
--- a/catapult/telemetry/telemetry/value/trace_unittest.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import codecs
-import json
-import os
-import shutil
-import tempfile
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry.testing import system_stub
-from telemetry.value import trace
-from tracing_build import html2trace
-from tracing.trace_data import trace_data
-
-
-class TestBase(unittest.TestCase):
-
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page('http://www.bar.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.baz.com/', story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page('http://www.foo.com/', story_set, story_set.base_dir))
-    self.story_set = story_set
-
-    self._cloud_storage_stub = system_stub.Override(trace, ['cloud_storage'])
-
-  def tearDown(self):
-    if self._cloud_storage_stub:
-      self._cloud_storage_stub.Restore()
-      self._cloud_storage_stub = None
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-
-class TestSet(object):
-  """ A test set that represents a set that contains any key. """
-
-  def __contains__(self, key):
-    return True
-
-
-class TestDefaultDict(object):
-  """ A test default dict that represents a dictionary that contains any key
-  with value |default_value|. """
-
-  def __init__(self, default_value):
-    self._default_value = default_value
-    self._test_set = TestSet()
-
-  def __contains__(self, key):
-    return key in self._test_set
-
-  def __getitem__(self, key):
-    return self._default_value
-
-  def keys(self):
-    return self._test_set
-
-
-class ValueTest(TestBase):
-  def testRepr(self):
-    v = trace.TraceValue(
-        self.pages[0], trace_data.CreateTraceDataFromRawData([{'test': 1}]),
-                         important=True, description='desc')
-
-    self.assertEquals('TraceValue(http://www.bar.com/, trace)', str(v))
-
-  def testTraceSerializationContainStoryName(self):
-    tempdir = tempfile.mkdtemp()
-    try:
-      v = trace.TraceValue(self.pages[0],
-                           trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-      fh = v.Serialize(tempdir)
-      self.assertTrue(os.path.basename(fh.GetAbsPath()).startswith(
-          'http___www_bar_com'))
-    finally:
-      shutil.rmtree(tempdir)
-
-  def testAsDictWhenTraceSerializedAndUploaded(self):
-    tempdir = tempfile.mkdtemp()
-    try:
-      v = trace.TraceValue(None,
-                           trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-      fh = v.Serialize(tempdir)
-      # pylint: disable=no-member
-      trace.cloud_storage.SetCalculatedHashesForTesting(
-          {fh.GetAbsPath(): 123})
-      # pylint: enable=no-member
-      bucket = trace.cloud_storage.PUBLIC_BUCKET
-      cloud_url = v.UploadToCloud(bucket)
-      d = v.AsDict()
-      self.assertEqual(d['file_id'], fh.id)
-      self.assertEqual(d['cloud_url'], cloud_url)
-    finally:
-      shutil.rmtree(tempdir)
-
-  def testAsDictWhenTraceIsNotSerializedAndUploaded(self):
-    test_temp_file = tempfile.NamedTemporaryFile(delete=False)
-    try:
-      v = trace.TraceValue(None,
-                           trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-      # pylint: disable=no-member
-      trace.cloud_storage.SetCalculatedHashesForTesting(
-          TestDefaultDict(123))
-      # pylint: enable=no-member
-      bucket = trace.cloud_storage.PUBLIC_BUCKET
-      cloud_url = v.UploadToCloud(bucket)
-      d = v.AsDict()
-      self.assertEqual(d['cloud_url'], cloud_url)
-    finally:
-      if os.path.exists(test_temp_file.name):
-        test_temp_file.close()
-        os.remove(test_temp_file.name)
-
-  def testFindTraceParts(self):
-    raw_data = {
-      'powerTraceAsString': 'BattOr Data',
-      'traceEvents': [{'trace': 1}],
-      'tabIds': 'Tab Data',
-    }
-    data = trace_data.CreateTraceDataFromRawData(raw_data)
-    v = trace.TraceValue(None, data)
-    tempdir = tempfile.mkdtemp()
-    temp_path = os.path.join(tempdir, 'test.json')
-    battor_seen = False
-    chrome_seen = False
-    tabs_seen = False
-    try:
-      with codecs.open(v.filename, mode='r', encoding='utf-8') as f:
-        trace_files = html2trace.CopyTraceDataFromHTMLFilePath(f, temp_path)
-      for f in trace_files:
-        with open(f, 'r') as trace_file:
-          d = trace_file.read()
-          if d == raw_data['powerTraceAsString']:
-            self.assertFalse(battor_seen)
-            battor_seen = True
-          elif d == json.dumps({'traceEvents': raw_data['traceEvents']}):
-            self.assertFalse(chrome_seen)
-            chrome_seen = True
-          elif d == raw_data['tabIds']:
-            self.assertFalse(tabs_seen)
-            tabs_seen = True
-      self.assertTrue(battor_seen)
-      self.assertTrue(chrome_seen)
-      self.assertTrue(tabs_seen)
-    finally:
-      shutil.rmtree(tempdir)
-      os.remove(v.filename)
-
-
-def _IsEmptyDir(path):
-  return os.path.exists(path) and not os.listdir(path)
-
-
-class NoLeakedTempfilesTests(TestBase):
-
-  def setUp(self):
-    super(NoLeakedTempfilesTests, self).setUp()
-    self.temp_test_dir = tempfile.mkdtemp()
-    self.actual_tempdir = trace.tempfile.tempdir
-    trace.tempfile.tempdir = self.temp_test_dir
-
-  def testNoLeakedTempFileOnImplicitCleanUp(self):
-    with trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData([{'test': 1}])):
-      pass
-    self.assertTrue(_IsEmptyDir(self.temp_test_dir))
-
-  def testNoLeakedTempFileWhenUploadingTrace(self):
-    v = trace.TraceValue(
-        None, trace_data.CreateTraceDataFromRawData([{'test': 1}]))
-    v.CleanUp()
-    self.assertTrue(_IsEmptyDir(self.temp_test_dir))
-
-  def tearDown(self):
-    super(NoLeakedTempfilesTests, self).tearDown()
-    shutil.rmtree(self.temp_test_dir)
-    trace.tempfile.tempdir = self.actual_tempdir
diff --git a/catapult/telemetry/telemetry/value/unit-info.json b/catapult/telemetry/telemetry/value/unit-info.json
deleted file mode 100644
index 6a6c931..0000000
--- a/catapult/telemetry/telemetry/value/unit-info.json
+++ /dev/null
@@ -1,221 +0,0 @@
-{
-  "_description" : "This file contains info about our performance test units, used by the perf dashboard (http://chromeperf.appspot.com).",
-
-  "%": {
-    "improvement_direction": "down",
-    "why": "Percent CPU usage. Used by cpu metric."
-  },
-  "bit/s": {
-    "improvement_direction": "down",
-    "why": "Bitrate."
-  },
-  "bytes/s": {
-    "improvement_direction": "down",
-    "why": "Bitrate."
-  },
-  "bytes": {
-    "improvement_direction": "down"
-  },
-  "chars/s": {
-    "improvement_direction": "up"
-  },
-  "Celsius": {
-    "improvement_direction": "down",
-    "why": "Colder machines are faster."
-  },
-  "commit_count": {
-    "improvement_direction": "up",
-    "why": "layer_tree_host_perftest"
-  },
-  "count": {
-    "improvement_direction": "down",
-    "why": "Processes"
-  },
-  "coverage%": {
-    "improvement_direction": "up",
-    "why": "Used in alloy-perf-test/cts%/passed."
-  },
-  "dB": {
-    "improvement_direction": "up",
-    "why": "Decibels peak signal-to-noise ratio. Used by WebRTC quality tests."
-  },
-  "files": {
-    "improvement_direction": "down",
-    "why": "Static initializers"
-  },
-  "fps": {
-    "improvement_direction": "up",
-    "why": "The faster the better. Used by scirra benchmark."
-  },
-  "frames": {
-    "improvement_direction": "down",
-    "why": "Dropped frames."
-  },
-  "frames-per-second": {
-    "improvement_direction": "up",
-    "why": "Synonym for fps."
-  },
-  "frame_count": {
-    "improvement_direction": "up",
-    "why": "layer_tree_host_perftest"
-  },
-  "frame_time": {
-    "improvement_direction": "down"
-  },
-  "garbage_collections": {
-    "improvement_direction": "down",
-    "why": "Number of GCs needed to collect an object. Less is better."
-  },
-  "Hz": {
-    "improvement_direction": "up",
-    "why": "Higher frequencies are faster."
-  },
-  "janks": {
-    "improvement_direction": "down",
-    "why": "Fewer janks is better."
-  },
-  "kb": {
-    "improvement_direction": "down",
-    "why": "Synonym for KB, used in memory and io metrics."
-  },
-  "available_kB": {
-    "improvement_direction": "up",
-    "why": "kB of memory available. More memory available is better."
-  },
-  "KB": {
-    "improvement_direction": "down",
-    "why": "KB of memory usage. Less memory usage is better. Used in endure."
-  },
-  "lines": {
-    "improvement_direction": "up",
-    "why": "Coverage. More test coverage is better."
-  },
-  "load": {
-    "improvement_direction": "down"
-  },
-  "MB": {
-    "improvement_direction": "down"
-  },
-  "mips": {
-    "improvement_direction": "up",
-    "why": "More instructions processed per time unit."
-  },
-  "mpixels_sec": {
-    "improvement_direction": "up",
-    "why": "More pixels processed per time unit."
-  },
-  "mtexel_sec": {
-    "improvement_direction": "up",
-    "why": "More texels processed per time unit."
-  },
-  "mtri_sec": {
-    "improvement_direction": "up",
-    "why": "More triangles processed per time unit."
-  },
-  "mvtx_sec": {
-    "improvement_direction": "up",
-    "why": "More vertices processed per time unit."
-  },
-  "ms": {
-    "improvement_direction": "down",
-    "why": "Used in many Telemetry measurements. Fewer ms of time means faster."
-  },
-  "ms/1000 elements": {
-    "improvement_direction": "down"
-  },
-  "milliseconds": {
-    "improvement_direction": "down",
-    "why": "Synonym for ms."
-  },
-  "milliseconds-per-frame": {
-    "improvement_direction": "down"
-  },
-  "minutes": {
-    "improvement_direction": "down",
-    "why": "Used for NaCl build time."
-  },
-  "mWh": {
-    "improvement_direction": "down",
-    "why": "Fewer milliwatt-hours means less energy consumed."
-  },
-  "objects (bigger is better)": {
-    "improvement_direction": "up",
-    "why": "Used in spaceport benchmark."
-  },
-  "ObjectsAt30FPS": {
-    "improvement_direction": "up"
-  },
-  "packets": {
-    "improvement_direction": "down",
-    "why": "Monitors how many packets we use to accomplish something."
-  },
-  "percent": {
-    "improvement_direction": "down",
-    "why": "Synonym for %, used in memory metric for percent fragmentation."
-  },
-  "points": {
-    "improvement_direction": "up",
-    "why": "Synonym for score, used in ChromeOS touchpad tests."
-  },
-  "ports": {
-    "improvement_direction": "down"
-  },
-  "reduction%": {
-    "improvement_direction": "up",
-    "why": "Used in draw_property measurement to indicate relative improvement."
-  },
-  "relocs": {
-    "improvement_direction": "down"
-  },
-  "runs/ms": {
-    "improvement_direction": "up",
-    "why": "Higher runs/ms implies faster execution."
-  },
-  "runs/s": {
-    "improvement_direction": "up",
-    "why": "Used in dromaeo. Higher runs/s implies faster execution."
-  },
-  "runs_per_s": {
-    "improvement_direction": "up",
-    "why": "Synonym for runs/s, used in dromaeo data sent by cros bots."
-  },
-  "runs_per_second": {
-    "improvement_direction": "up",
-    "why": "Synonym for runs/s."
-  },
-  "score": {
-    "improvement_direction": "up",
-    "why": "Used in a variety of benchmarks where a higher score is better."
-  },
-  "score_(bigger_is_better)": {
-    "improvement_direction": "up",
-    "why": "Synonym for score."
-  },
-  "score (bigger is better)": {
-    "improvement_direction": "up",
-    "why": "Synonym for score, used in jsgamebench and dom_perf."
-  },
-  "sec": {
-    "improvement_direction": "down"
-  },
-  "seconds": {
-    "improvement_direction": "down"
-  },
-  "tasks": {
-    "improvement_direction": "down"
-  },
-  "tokens/s": {
-    "improvement_direction": "up"
-  },
-  "us": {
-    "improvement_direction": "down"
-  },
-  "vsyncs": {
-    "improvement_direction": "down",
-    "why": "Used in smoothness benchmarks. Number of vsyncs to generate a frame, never < 1.0"
-  },
-  "idle%": {
-    "improvement_direction": "up",
-    "why": "Percentage of work done in idle time."
-  }
-}
diff --git a/catapult/telemetry/telemetry/value/value_unittest.py b/catapult/telemetry/telemetry/value/value_unittest.py
deleted file mode 100644
index a06300e..0000000
--- a/catapult/telemetry/telemetry/value/value_unittest.py
+++ /dev/null
@@ -1,337 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import unittest
-
-from telemetry import story
-from telemetry import page as page_module
-from telemetry import value
-
-
-class TestBase(unittest.TestCase):
-  def setUp(self):
-    story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    story_set.AddStory(
-        page_module.Page("http://www.bar.com/", story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page("http://www.baz.com/", story_set, story_set.base_dir))
-    story_set.AddStory(
-        page_module.Page("http://www.foo.com/", story_set, story_set.base_dir))
-    self.story_set = story_set
-
-  @property
-  def pages(self):
-    return self.story_set.stories
-
-class ValueForTest(value.Value):
-  @classmethod
-  def MergeLikeValuesFromSamePage(cls, values):
-    pass
-
-  @classmethod
-  def MergeLikeValuesFromDifferentPages(cls, values):
-    pass
-
-  def GetBuildbotDataType(self, output_context):
-    pass
-
-  def GetBuildbotValue(self):
-    pass
-
-  def GetChartAndTraceNameForComputedSummaryResult(
-      self, trace_tag):
-    pass
-
-  def GetRepresentativeNumber(self):
-    pass
-
-  def GetRepresentativeString(self):
-    pass
-
-  @staticmethod
-  def GetJSONTypeName():
-    pass
-
-class ValueForAsDictTest(ValueForTest):
-  @staticmethod
-  def GetJSONTypeName():
-    return 'baz'
-
-class ValueForFromDictTest(ValueForTest):
-  @staticmethod
-  def FromDict(value_dict, page_dict):
-    kwargs = value.Value.GetConstructorKwArgs(value_dict, page_dict)
-    return ValueForFromDictTest(**kwargs)
-
-  @staticmethod
-  def GetJSONTypeName():
-    return 'value_for_from_dict_test'
-
-class ValueTest(TestBase):
-  def testCompat(self):
-    page0 = self.pages[0]
-    page1 = self.pages[0]
-
-    a = value.Value(page0, 'x', 'unit', important=False, description=None,
-                    tir_label='foo', grouping_keys=None)
-    b = value.Value(page1, 'x', 'unit', important=False, description=None,
-                    tir_label='foo', grouping_keys=None)
-    self.assertTrue(b.IsMergableWith(a))
-
-    a = value.Value(page0, 'x', 'unit', important=False, description=None,
-                    tir_label='foo', grouping_keys=None)
-    b = value.Value(page0, 'x', 'unit', important=False, description=None,
-                     tir_label='bar', grouping_keys=None)
-    self.assertTrue(b.IsMergableWith(a))
-
-  def testIncompat(self):
-    page0 = self.pages[0]
-
-    a = value.Value(page0, 'x', 'unit', important=False, description=None,
-                    tir_label=None, grouping_keys=None)
-    b = value.Value(page0, 'x', 'incompatUnit', important=False,
-                    tir_label=None, description=None, grouping_keys=None)
-    self.assertFalse(b.IsMergableWith(a))
-
-    a = value.Value(page0, 'x', 'unit', important=False, description=None,
-                    tir_label=None, grouping_keys=None)
-    b = value.Value(page0, 'x', 'unit', important=True, description=None,
-                    tir_label=None, grouping_keys=None)
-    self.assertFalse(b.IsMergableWith(a))
-
-    a = value.Value(page0, 'x', 'unit', important=False, description=None,
-                    tir_label=None, grouping_keys=None)
-    b = ValueForTest(page0, 'x', 'unit', important=True, description=None,
-                     tir_label=None, grouping_keys=None)
-    self.assertFalse(b.IsMergableWith(a))
-
-  def testNameMustBeString(self):
-    with self.assertRaises(ValueError):
-      value.Value(None, 42, 'unit', important=False, description=None,
-                  tir_label=None, grouping_keys=None)
-
-  def testUnitsMustBeString(self):
-    with self.assertRaises(ValueError):
-      value.Value(None, 'x', 42, important=False, description=None,
-                  tir_label=None, grouping_keys=None)
-
-  def testImportantMustBeBool(self):
-    with self.assertRaises(ValueError):
-      value.Value(None, 'x', 'unit', important='foo', description=None,
-                  tir_label=None, grouping_keys=None)
-
-  def testDescriptionMustBeStringOrNone(self):
-    with self.assertRaises(ValueError):
-      value.Value(None, 'x', 'unit', important=False, description=42,
-                  tir_label=None, grouping_keys=None)
-
-  def testInteractionRecordMustBeStringOrNone(self):
-    with self.assertRaises(ValueError):
-      value.Value(None, 'x', 'unit', important=False, description=None,
-                  tir_label=42, grouping_keys=None)
-
-  def testGroupingKeysMustBeDictOrNone(self):
-    with self.assertRaises(ValueError):
-      value.Value(None, 'x', 'unit', important=False, description=None,
-                  tir_label=42, grouping_keys='foo')
-
-  def testAsDictBaseKeys(self):
-    v = ValueForAsDictTest(None, 'x', 'unit', important=True, description=None,
-                           tir_label='bar', grouping_keys={'foo': 'baz'})
-    d = v.AsDict()
-
-    self.assertEquals(d, {
-          'name': 'x',
-          'type': 'baz',
-          'units': 'unit',
-          'important': True,
-          'tir_label': 'bar',
-          'grouping_keys': {'foo': 'baz'}
-        })
-
-  def testAsDictWithPage(self):
-    page0 = self.pages[0]
-
-    v = ValueForAsDictTest(page0, 'x', 'unit', important=False,
-                           description=None, tir_label=None, grouping_keys=None)
-    d = v.AsDict()
-
-    self.assertIn('page_id', d)
-
-  def testAsDictWithoutPage(self):
-    v = ValueForAsDictTest(None, 'x', 'unit', important=False, description=None,
-                           tir_label=None, grouping_keys=None)
-    d = v.AsDict()
-
-    self.assertNotIn('page_id', d)
-
-  def testAsDictWithDescription(self):
-    v = ValueForAsDictTest(None, 'x', 'unit', important=False,
-                           description='Some description.',
-                           tir_label=None, grouping_keys=None)
-    d = v.AsDict()
-    self.assertEqual('Some description.', d['description'])
-
-  def testAsDictWithoutDescription(self):
-    v = ValueForAsDictTest(None, 'x', 'unit', important=False, description=None,
-                           tir_label=None, grouping_keys=None)
-    self.assertNotIn('description', v.AsDict())
-
-  def testAsDictWithInteractionRecord(self):
-    v = ValueForAsDictTest(None, 'x', 'unit', important=False,
-                           description='Some description.',
-                           tir_label='foo', grouping_keys=None)
-    d = v.AsDict()
-    self.assertEqual('foo', d['tir_label'])
-
-  def testAsDictWithoutInteractionRecord(self):
-    v = ValueForAsDictTest(None, 'x', 'unit', important=False, description=None,
-                           tir_label=None, grouping_keys=None)
-    self.assertNotIn('tir_label', v.AsDict())
-
-  def testFromDictBaseKeys(self):
-    d = {
-      'type': 'value_for_from_dict_test',
-      'name': 'x',
-      'units': 'unit'
-    }
-
-    v = value.Value.FromDict(d, None)
-    self.assertEquals(v.name, 'x')
-    self.assertTrue(isinstance(v, ValueForFromDictTest))
-    self.assertEquals(v.units, 'unit')
-
-  def testFromDictWithPage(self):
-    page0 = self.pages[0]
-    page_dict = {page0.id: page0}
-
-    d = {
-      'type': 'value_for_from_dict_test',
-      'name': 'x',
-      'units': 'unit',
-      'page_id': page0.id
-    }
-
-    v = value.Value.FromDict(d, page_dict)
-
-    self.assertEquals(v.page.id, page0.id)
-
-  def testFromDictWithPageId0(self):
-    page_dict = {0: 'foo'}
-
-    d = {
-      'type': 'value_for_from_dict_test',
-      'name': 'x',
-      'units': 'unit',
-      'page_id': 0
-    }
-
-    v = value.Value.FromDict(d, page_dict)
-
-    self.assertEquals(v.page, 'foo')
-
-  def testFromDictWithoutPage(self):
-    d = {
-      'type': 'value_for_from_dict_test',
-      'name': 'x',
-      'units': 'unit'
-    }
-
-    v = value.Value.FromDict(d, {})
-
-    self.assertEquals(v.page, None)
-
-  def testFromDictWithDescription(self):
-    d = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit',
-          'description': 'foo'
-        }
-
-    v = value.Value.FromDict(d, {})
-    self.assertEquals(v.description, 'foo')
-
-  def testFromDictWithoutDescription(self):
-    d = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit'
-        }
-
-    v = value.Value.FromDict(d, {})
-    self.assertEquals(v.description, None)
-
-  def testFromDictWithInteractionRecord(self):
-    d = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit',
-          'description': 'foo',
-          'tir_label': 'bar'
-        }
-
-    v = value.Value.FromDict(d, {})
-    self.assertEquals(v.tir_label, 'bar')
-
-  def testFromDictWithoutInteractionRecord(self):
-    d = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit'
-        }
-
-    v = value.Value.FromDict(d, {})
-    self.assertEquals(v.tir_label, None)
-
-  def testFromDictWithGroupingKeys(self):
-    d = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit',
-          'description': 'foo',
-          'tir_label': 'bar',
-          'grouping_keys': {'foo': 'bar'}
-        }
-
-    v = value.Value.FromDict(d, {})
-    self.assertEquals(v.grouping_keys, {'foo': 'bar'})
-
-  def testFromDictWithoutGroupingKeys(self):
-    d = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit'
-        }
-
-    v = value.Value.FromDict(d, {})
-    self.assertEquals(v.grouping_keys, {})
-
-  def testListOfValuesFromListOfDicts(self):
-    d0 = {
-          'type': 'value_for_from_dict_test',
-          'name': 'x',
-          'units': 'unit'
-        }
-    d1 = {
-          'type': 'value_for_from_dict_test',
-          'name': 'y',
-          'units': 'unit'
-        }
-    vs = value.Value.ListOfValuesFromListOfDicts([d0, d1], {})
-    self.assertEquals(vs[0].name, 'x')
-    self.assertEquals(vs[1].name, 'y')
-
-  def testMergedTirLabelForSameLabel(self):
-    v = ValueForTest(None, 'foo', 'ms', False, 'd', 'bar', {})
-
-    tir_label = value.MergedTirLabel([v, v])
-    self.assertEquals(tir_label, 'bar')
-
-  def testMergedTirLabelForDifferentLabels(self):
-    v0 = ValueForTest(None, 'foo', 'ms', False, 'd', 'bar', {})
-    v1 = ValueForTest(None, 'foo', 'ms', False, 'd', 'baz', {})
-
-    tir_label = value.MergedTirLabel([v0, v1])
-    self.assertIsNone(tir_label)
diff --git a/catapult/telemetry/telemetry/web_perf/__init__.py b/catapult/telemetry/telemetry/web_perf/__init__.py
deleted file mode 100644
index 648af8e..0000000
--- a/catapult/telemetry/telemetry/web_perf/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-The web_perf module provides utilities and measurements for benchmarking web
-app's performance.
-"""
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/__init__.py b/catapult/telemetry/telemetry/web_perf/metrics/__init__.py
deleted file mode 100644
index 89406a1..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/__init__.py
+++ /dev/null
@@ -1,6 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""
-The web_perf.metrics module provides metrics for analyzing web performance.
-"""
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/blob_timeline.py b/catapult/telemetry/telemetry/web_perf/metrics/blob_timeline.py
deleted file mode 100644
index db81f69..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/blob_timeline.py
+++ /dev/null
@@ -1,117 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.web_perf.metrics import timeline_based_metric
-
-
-WRITE_EVENT_NAME = 'Registry::RegisterBlob'
-READ_EVENT_NAME = 'BlobRequest'
-
-
-class BlobTimelineMetric(timeline_based_metric.TimelineBasedMetric):
-  """BlobTimelineMetric reports timing information about blob storage.
-
-  The following metrics are added to the results:
-    * blob write times (blob_writes)
-    * blob read times (blob_reads)
-  """
-
-  def __init__(self):
-    super(BlobTimelineMetric, self).__init__()
-
-  @staticmethod
-  def IsWriteEvent(event):
-    return event.name == WRITE_EVENT_NAME
-
-  @staticmethod
-  def IsReadEvent(event):
-    return event.name == READ_EVENT_NAME
-
-  @staticmethod
-  def IsEventInInteraction(event, interaction):
-    return interaction.start <= event.start <= interaction.end
-
-  @staticmethod
-  def ThreadDurationIfPresent(event):
-    if event.thread_duration:
-      return event.thread_duration
-    else:
-      return event.duration
-
-  def AddResults(self, model, renderer_thread, interactions, results):
-    assert interactions
-
-    write_events = []
-    read_events = []
-    for event in model.IterAllEvents(
-        event_predicate=lambda e: self.IsWriteEvent(e) or self.IsReadEvent(e)):
-      if self.IsReadEvent(event):
-        read_events.append(event)
-      else:
-        write_events.append(event)
-
-    # Only these private methods are tested for mocking simplicity.
-    self._AddWriteResultsInternal(write_events, interactions, results)
-    self._AddReadResultsInternal(read_events, interactions, results)
-
-  def _AddWriteResultsInternal(self, events, interactions, results):
-    writes = []
-    for event in events:
-      if (self.IsWriteEvent(event) and
-          any(self.IsEventInInteraction(event, interaction)
-              for interaction in interactions)):
-        writes.append(self.ThreadDurationIfPresent(event))
-    if writes:
-      results.AddValue(list_of_scalar_values.ListOfScalarValues(
-          page=results.current_page,
-          tir_label=interactions[0].label,
-          name='blob-writes',
-          units='ms',
-          values=writes,
-          description='List of durations of blob writes.',
-          improvement_direction=improvement_direction.DOWN))
-    else:
-      results.AddValue(list_of_scalar_values.ListOfScalarValues(
-          page=results.current_page,
-          tir_label=interactions[0].label,
-          name='blob-writes',
-          units='ms',
-          values=None,
-          none_value_reason='No blob write events found for this interaction.',
-          improvement_direction=improvement_direction.DOWN))
-
-  def _AddReadResultsInternal(self, events, interactions, results):
-    reads = dict()
-    for event in events:
-      if (not self.IsReadEvent(event) or
-          not any(self.IsEventInInteraction(event, interaction)
-                 for interaction in interactions)):
-        continue
-      # Every blob has unique UUID.  To get the total time for reading
-      # a blob, we add up the time of all events with the same blob UUID.
-      uuid = event.args['uuid']
-      if uuid not in reads:
-        reads[uuid] = 0
-      reads[uuid] += self.ThreadDurationIfPresent(event)
-
-    if reads:
-      results.AddValue(list_of_scalar_values.ListOfScalarValues(
-          page=results.current_page,
-          tir_label=interactions[0].label,
-          name='blob-reads',
-          units='ms',
-          values=reads.values(),
-          description='List of read times for blobs.',
-          improvement_direction=improvement_direction.DOWN))
-    else:
-      results.AddValue(list_of_scalar_values.ListOfScalarValues(
-          page=results.current_page,
-          tir_label=interactions[0].label,
-          name='blob-reads',
-          units='ms',
-          values=None,
-          none_value_reason='No blob read events found for this interaction.',
-          improvement_direction=improvement_direction.DOWN))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/blob_timeline_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/blob_timeline_unittest.py
deleted file mode 100644
index 7f2efb7..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/blob_timeline_unittest.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from collections import namedtuple
-from telemetry.internal.results import page_test_results
-from telemetry.page import page
-from telemetry.web_perf.metrics import blob_timeline
-from telemetry.web_perf import timeline_interaction_record
-
-
-FakeEvent = namedtuple('Event', 'name, start, end, thread_duration, args')
-Interaction = timeline_interaction_record.TimelineInteractionRecord
-TEST_INTERACTION_LABEL = 'Action_TestInteraction'
-WRITE_EVENT_NAME = 'Registry::RegisterBlob'
-READ_EVENT_NAME = 'BlobRequest'
-
-
-def GetBlobMetrics(events, interactions):
-  results = page_test_results.PageTestResults()
-  test_page = page.Page('file://blank.html')
-  results.WillRunPage(test_page)
-  blob_timeline.BlobTimelineMetric()._AddWriteResultsInternal(
-      events, interactions, results)  # pylint:disable=protected-access
-  blob_timeline.BlobTimelineMetric()._AddReadResultsInternal(
-      events, interactions, results)  # pylint:disable=protected-access
-  return_dict = dict((value.name, value.values) for value in
-                     results.current_page_run.values)
-  results.DidRunPage(test_page)
-  return return_dict
-
-def FakeWriteEvent(start, end, thread_duration=None):
-  if not thread_duration:
-    thread_duration = end - start
-  return FakeEvent(blob_timeline.WRITE_EVENT_NAME,
-                   start, end, thread_duration, {'uuid':'fakeuuid'})
-
-def FakeReadEvent(start, end, uuid, thread_duration=None):
-  if not thread_duration:
-    thread_duration = end - start
-  return FakeEvent(blob_timeline.READ_EVENT_NAME,
-                   start, end, thread_duration, {'uuid': uuid})
-
-def TestInteraction(start, end):
-  return Interaction(TEST_INTERACTION_LABEL, start, end)
-
-
-class BlobTimelineMetricUnitTest(unittest.TestCase):
-  def testWriteMetric(self):
-    events = [FakeWriteEvent(0, 1),
-              FakeWriteEvent(9, 11),
-              FakeWriteEvent(10, 13),
-              FakeWriteEvent(20, 24),
-              FakeWriteEvent(21, 26),
-              FakeWriteEvent(29, 35),
-              FakeWriteEvent(30, 37),
-              FakeWriteEvent(40, 48),
-              FakeWriteEvent(41, 50),
-              FakeEvent('something', 10, 13, 3, {}),
-              FakeEvent('FrameView::something', 20, 24, 4, {}),
-              FakeEvent('SomeThing::performLayout', 30, 37, 7, {}),
-              FakeEvent('something else', 40, 48, 8, {})]
-    interactions = [TestInteraction(10, 20),
-                    TestInteraction(30, 40)]
-
-    # The first event starts before the first interaction, so it is ignored.
-    # The second event starts before the first interaction, so it is ignored.
-    # The third event starts during the first interaction, and its duration is
-    # 13 - 10 = 3.
-    # The fourth event starts during the first interaction, and its duration is
-    # 24 - 20 = 4.
-    # The fifth event starts between the two interactions, so it is ignored.
-    # The sixth event starts between the two interactions, so it is ignored.
-    # The seventh event starts during the second interaction, and its duration
-    # is 37 - 30 = 7.
-    # The eighth event starts during the second interaction and its duration is
-    # 48 - 40 = 8.
-    # The ninth event starts after the last interaction, so it is ignored.
-    # The rest of the events are not layout events, so they are ignored.
-    self.assertEqual({'blob-reads': None, 'blob-writes': [3, 4, 7, 8]},
-        GetBlobMetrics(events, interactions))
-
-  def testReadMetric(self):
-    events = [FakeReadEvent(0, 1, 'a'),
-              FakeReadEvent(9, 11, 'a'),
-              FakeReadEvent(10, 13, 'b', 1), # counts
-              FakeReadEvent(15, 18, 'b'),    # counts
-              FakeReadEvent(21, 26, 'b'),
-              FakeReadEvent(29, 35, 'c'),
-              FakeReadEvent(31, 32, 'e'),    # counts
-              FakeReadEvent(34, 36, 'e', 1), # counts
-              FakeReadEvent(32, 37, 'd'),    # counts
-              FakeEvent('something', 10, 13, 3, {}),
-              FakeEvent('something else', 40, 48, 8, {})]
-    interactions = [TestInteraction(10, 20),
-                    TestInteraction(30, 40)]
-
-    # We ignore events outside of the interaction intervals, and we use the
-    # beginning of the first event of the interval and the end of the last
-    # event.
-    # 18 - 10 = 8
-    # 37 - 32 = 5
-    self.assertEqual({'blob-reads': [4, 2, 5], 'blob-writes': None},
-        GetBlobMetrics(events, interactions))
-
-  def testReadAndWriteMetrics(self):
-    events = [FakeReadEvent(0, 1, 'a'),
-              FakeReadEvent(9, 11, 'a'),
-              FakeReadEvent(10, 13, 'b'),     # counts
-              FakeWriteEvent(15, 18),         # counts
-              FakeReadEvent(21, 26, 'c'),
-              FakeReadEvent(29, 35, 'd'),
-              FakeWriteEvent(31, 34, 1), # counts
-              FakeReadEvent(32, 33, 'e'),     # counts
-              FakeReadEvent(34, 35, 'e'),     # counts
-              FakeEvent('something', 31, 33, 2, {})]
-    interactions = [TestInteraction(10, 20),
-                    TestInteraction(30, 35)]
-
-    # We use the read events in the interactions, so the same as the test above.
-    self.assertEqual({'blob-reads': [3, 2], 'blob-writes': [3, 1]},
-      GetBlobMetrics(events, interactions))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/gpu_timeline.py b/catapult/telemetry/telemetry/web_perf/metrics/gpu_timeline.py
deleted file mode 100644
index ff362be..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/gpu_timeline.py
+++ /dev/null
@@ -1,240 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import collections
-import math
-import sys
-
-from telemetry.timeline import model as model_module
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-from telemetry.web_perf.metrics import timeline_based_metric
-
-TOPLEVEL_GL_CATEGORY = 'gpu_toplevel'
-TOPLEVEL_SERVICE_CATEGORY = 'disabled-by-default-gpu.service'
-TOPLEVEL_DEVICE_CATEGORY = 'disabled-by-default-gpu.device'
-
-SERVICE_FRAME_END_MARKER = (TOPLEVEL_SERVICE_CATEGORY, 'SwapBuffer')
-DEVICE_FRAME_END_MARKER = (TOPLEVEL_DEVICE_CATEGORY, 'SwapBuffer')
-
-TRACKED_GL_CONTEXT_NAME = {'RenderCompositor': 'render_compositor',
-                           'BrowserCompositor': 'browser_compositor',
-                           'Compositor': 'browser_compositor'}
-
-
-def _CalculateFrameTimes(events_per_frame, event_data_func):
-  """Given a list of events per frame and a function to extract event time data,
-     returns a list of frame times."""
-  times_per_frame = []
-  for event_list in events_per_frame:
-    event_times = [event_data_func(event) for event in event_list]
-    times_per_frame.append(sum(event_times))
-  return times_per_frame
-
-
-def _CPUFrameTimes(events_per_frame):
-  """Given a list of events per frame, returns a list of CPU frame times."""
-  # CPU event frames are calculated using the event thread duration.
-  # Some platforms do not support thread_duration, convert those to 0.
-  return _CalculateFrameTimes(events_per_frame,
-                              lambda event: event.thread_duration or 0)
-
-
-def _GPUFrameTimes(events_per_frame):
-  """Given a list of events per frame, returns a list of GPU frame times."""
-  # GPU event frames are asynchronous slices which use the event duration.
-  return _CalculateFrameTimes(events_per_frame,
-                              lambda event: event.duration)
-
-
-def TimelineName(name, source_type, value_type):
-  """Constructs the standard name given in the timeline.
-
-  Args:
-    name: The name of the timeline, for example "total", or "render_compositor".
-    source_type: One of "cpu", "gpu" or None. None is only used for total times.
-    value_type: the type of value. For example "mean", "stddev"...etc.
-  """
-  if source_type:
-    return '%s_%s_%s_time' % (name, value_type, source_type)
-  else:
-    return '%s_%s_time' % (name, value_type)
-
-
-class GPUTimelineMetric(timeline_based_metric.TimelineBasedMetric):
-  """Computes GPU based metrics."""
-
-  def __init__(self):
-    super(GPUTimelineMetric, self).__init__()
-
-  def AddResults(self, model, _, interaction_records, results):
-    self.VerifyNonOverlappedRecords(interaction_records)
-    service_times = self._CalculateGPUTimelineData(model)
-    for value_item, durations in service_times.iteritems():
-      count = len(durations)
-      avg = 0.0
-      stddev = 0.0
-      maximum = 0.0
-      if count:
-        avg = sum(durations) / count
-        stddev = math.sqrt(sum((d - avg) ** 2 for d in durations) / count)
-        maximum = max(durations)
-
-      name, src = value_item
-
-      if src:
-        frame_times_name = '%s_%s_frame_times' % (name, src)
-      else:
-        frame_times_name = '%s_frame_times' % (name)
-
-      if durations:
-        results.AddValue(list_of_scalar_values.ListOfScalarValues(
-            results.current_page, frame_times_name, 'ms', durations,
-            tir_label=interaction_records[0].label,
-            improvement_direction=improvement_direction.DOWN))
-
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, TimelineName(name, src, 'max'), 'ms', maximum,
-          tir_label=interaction_records[0].label,
-          improvement_direction=improvement_direction.DOWN))
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, TimelineName(name, src, 'mean'), 'ms', avg,
-          tir_label=interaction_records[0].label,
-          improvement_direction=improvement_direction.DOWN))
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, TimelineName(name, src, 'stddev'), 'ms', stddev,
-          tir_label=interaction_records[0].label,
-          improvement_direction=improvement_direction.DOWN))
-
-  def _CalculateGPUTimelineData(self, model):
-    """Uses the model and calculates the times for various values for each
-       frame. The return value will be a dictionary of the following format:
-         {
-           (EVENT_NAME1, SRC1_TYPE): [FRAME0_TIME, FRAME1_TIME...etc.],
-           (EVENT_NAME2, SRC2_TYPE): [FRAME0_TIME, FRAME1_TIME...etc.],
-         }
-
-       Events:
-         swap - The time in milliseconds between each swap marker.
-         total - The amount of time spent in the renderer thread.
-         TRACKED_NAMES: Using the TRACKED_GL_CONTEXT_NAME dict, we
-                        include the traces per frame for the
-                        tracked name.
-       Source Types:
-         None - This will only be valid for the "swap" event.
-         cpu - For an event, the "cpu" source type signifies time spent on the
-               gpu thread using the CPU. This uses the "gpu.service" markers.
-         gpu - For an event, the "gpu" source type signifies time spent on the
-               gpu thread using the GPU. This uses the "gpu.device" markers.
-    """
-    all_service_events = []
-    current_service_frame_end = sys.maxint
-    current_service_events = []
-
-    all_device_events = []
-    current_device_frame_end = sys.maxint
-    current_device_events = []
-
-    tracked_events = {}
-    tracked_events.update(
-        dict([((value, 'cpu'), [])
-              for value in TRACKED_GL_CONTEXT_NAME.itervalues()]))
-    tracked_events.update(
-        dict([((value, 'gpu'), [])
-              for value in TRACKED_GL_CONTEXT_NAME.itervalues()]))
-
-    # These will track traces within the current frame.
-    current_tracked_service_events = collections.defaultdict(list)
-    current_tracked_device_events = collections.defaultdict(list)
-
-    event_iter = model.IterAllEvents(
-        event_type_predicate=model_module.IsSliceOrAsyncSlice)
-    for event in event_iter:
-      # Look for frame end markers
-      if (event.category, event.name) == SERVICE_FRAME_END_MARKER:
-        current_service_frame_end = event.end
-      elif (event.category, event.name) == DEVICE_FRAME_END_MARKER:
-        current_device_frame_end = event.end
-
-      # Track all other toplevel gl category markers
-      elif event.args.get('gl_category', None) == TOPLEVEL_GL_CATEGORY:
-        base_name = event.name
-        dash_index = base_name.rfind('-')
-        if dash_index != -1:
-          base_name = base_name[:dash_index]
-        tracked_name = TRACKED_GL_CONTEXT_NAME.get(base_name, None)
-
-        if event.category == TOPLEVEL_SERVICE_CATEGORY:
-          # Check if frame has ended.
-          if event.start >= current_service_frame_end:
-            if current_service_events:
-              all_service_events.append(current_service_events)
-              for value in TRACKED_GL_CONTEXT_NAME.itervalues():
-                tracked_events[(value, 'cpu')].append(
-                    current_tracked_service_events[value])
-            current_service_events = []
-            current_service_frame_end = sys.maxint
-            current_tracked_service_events.clear()
-
-          current_service_events.append(event)
-          if tracked_name:
-            current_tracked_service_events[tracked_name].append(event)
-
-        elif event.category == TOPLEVEL_DEVICE_CATEGORY:
-          # Check if frame has ended.
-          if event.start >= current_device_frame_end:
-            if current_device_events:
-              all_device_events.append(current_device_events)
-              for value in TRACKED_GL_CONTEXT_NAME.itervalues():
-                tracked_events[(value, 'gpu')].append(
-                    current_tracked_device_events[value])
-            current_device_events = []
-            current_device_frame_end = sys.maxint
-            current_tracked_device_events.clear()
-
-          current_device_events.append(event)
-          if tracked_name:
-            current_tracked_device_events[tracked_name].append(event)
-
-    # Append Data for Last Frame.
-    if current_service_events:
-      all_service_events.append(current_service_events)
-      for value in TRACKED_GL_CONTEXT_NAME.itervalues():
-        tracked_events[(value, 'cpu')].append(
-            current_tracked_service_events[value])
-    if current_device_events:
-      all_device_events.append(current_device_events)
-      for value in TRACKED_GL_CONTEXT_NAME.itervalues():
-        tracked_events[(value, 'gpu')].append(
-            current_tracked_device_events[value])
-
-    # Calculate Mean Frame Time for the CPU side.
-    frame_times = []
-    if all_service_events:
-      prev_frame_end = all_service_events[0][0].start
-      for event_list in all_service_events:
-        last_service_event_in_frame = event_list[-1]
-        frame_times.append(last_service_event_in_frame.end - prev_frame_end)
-        prev_frame_end = last_service_event_in_frame.end
-
-    # Create the timeline data dictionary for service side traces.
-    total_frame_value = ('swap', None)
-    cpu_frame_value = ('total', 'cpu')
-    gpu_frame_value = ('total', 'gpu')
-    timeline_data = {}
-    timeline_data[total_frame_value] = frame_times
-    timeline_data[cpu_frame_value] = _CPUFrameTimes(all_service_events)
-    for value in TRACKED_GL_CONTEXT_NAME.itervalues():
-      cpu_value = (value, 'cpu')
-      timeline_data[cpu_value] = _CPUFrameTimes(tracked_events[cpu_value])
-
-    # Add in GPU side traces if it was supported (IE. device traces exist).
-    if all_device_events:
-      timeline_data[gpu_frame_value] = _GPUFrameTimes(all_device_events)
-      for value in TRACKED_GL_CONTEXT_NAME.itervalues():
-        gpu_value = (value, 'gpu')
-        tracked_gpu_event = tracked_events[gpu_value]
-        timeline_data[gpu_value] = _GPUFrameTimes(tracked_gpu_event)
-
-    return timeline_data
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/gpu_timeline_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/gpu_timeline_unittest.py
deleted file mode 100644
index 2af5b10..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/gpu_timeline_unittest.py
+++ /dev/null
@@ -1,313 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.testing import test_page_test_results
-from telemetry.timeline import async_slice as async_slice_module
-from telemetry.timeline import model as model_module
-from telemetry.timeline import slice as slice_module
-from telemetry.web_perf.metrics import gpu_timeline
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-SERVICE_FRAME_END_CATEGORY, SERVICE_FRAME_END_NAME = \
-    gpu_timeline.SERVICE_FRAME_END_MARKER
-
-DEVICE_FRAME_END_CATEGORY, DEVICE_FRAME_END_NAME = \
-    gpu_timeline.DEVICE_FRAME_END_MARKER
-
-INTERACTION_RECORDS = [tir_module.TimelineInteractionRecord("test-record",
-                                                            0,
-                                                            float('inf'))]
-
-
-def _CreateGPUSlices(parent_thread, name, start_time, duration, offset=0):
-  args = {'gl_category': gpu_timeline.TOPLEVEL_GL_CATEGORY}
-  return (slice_module.Slice(parent_thread,
-                             gpu_timeline.TOPLEVEL_SERVICE_CATEGORY,
-                             name, start_time,
-                             args=args,
-                             duration=duration,
-                             thread_duration=duration),
-          async_slice_module.AsyncSlice(gpu_timeline.TOPLEVEL_DEVICE_CATEGORY,
-                             name, start_time + offset,
-                             args=args,
-                             duration=duration))
-
-def _CreateFrameEndSlices(parent_thread, start_time, duration, offset=0):
-  args = {'gl_category': gpu_timeline.TOPLEVEL_GL_CATEGORY}
-  return (slice_module.Slice(parent_thread,
-                             SERVICE_FRAME_END_CATEGORY,
-                             SERVICE_FRAME_END_NAME,
-                             start_time,
-                             args=args,
-                             duration=duration,
-                             thread_duration=duration),
-          async_slice_module.AsyncSlice(DEVICE_FRAME_END_CATEGORY,
-                             DEVICE_FRAME_END_NAME,
-                             start_time + offset,
-                             args=args,
-                             duration=duration))
-
-
-def _AddSliceToThread(parent_thread, slice_item):
-  if isinstance(slice_item, slice_module.Slice):
-    parent_thread.PushSlice(slice_item)
-  elif isinstance(slice_item, async_slice_module.AsyncSlice):
-    parent_thread.AddAsyncSlice(slice_item)
-  else:
-    assert False, "Invalid Slice Item Type: %s" % type(slice_item)
-
-
-class GPUTimelineTest(unittest.TestCase):
-  def GetResults(self, metric, model, renderer_thread, interaction_records):
-    results = test_page_test_results.TestPageTestResults(self)
-    metric.AddResults(model, renderer_thread, interaction_records, results)
-    return results
-
-  def testExpectedResults(self):
-    """Test a simply trace will output all expected results."""
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    for slice_item in _CreateGPUSlices(test_thread, 'test_item', 100, 10):
-      _AddSliceToThread(test_thread, slice_item)
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for name, src_type in (('swap', None), ('total', 'cpu'), ('total', 'gpu')):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, src_type, 'max'), 'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, src_type, 'mean'), 'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, src_type, 'stddev'), 'ms', 0)
-
-    for tracked_name in gpu_timeline.TRACKED_GL_CONTEXT_NAME.values():
-      for source_type in ('cpu', 'gpu'):
-        results.AssertHasPageSpecificScalarValue(
-            gpu_timeline.TimelineName(tracked_name, source_type, 'max'),
-                                      'ms', 0)
-        results.AssertHasPageSpecificScalarValue(
-            gpu_timeline.TimelineName(tracked_name, source_type, 'mean'),
-                                      'ms', 0)
-        results.AssertHasPageSpecificScalarValue(
-            gpu_timeline.TimelineName(tracked_name, source_type, 'stddev'),
-                                      'ms', 0)
-
-  def testNoDeviceTraceResults(self):
-    """Test expected results when missing device traces."""
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    service_slice, _ = _CreateGPUSlices(test_thread, 'test_item', 100, 10)
-    _AddSliceToThread(test_thread, service_slice)
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for name, source_type in (('swap', None), ('total', 'cpu')):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, source_type, 'max'), 'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, source_type, 'mean'), 'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, source_type, 'stddev'), 'ms', 0)
-
-    self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
-                      gpu_timeline.TimelineName('total', 'gpu', 'max'))
-    self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
-                      gpu_timeline.TimelineName('total', 'gpu', 'mean'))
-    self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
-                      gpu_timeline.TimelineName('total', 'gpu', 'stddev'))
-
-    for name in gpu_timeline.TRACKED_GL_CONTEXT_NAME.values():
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, 'cpu', 'max'), 'ms', 0)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, 'cpu', 'mean'), 'ms', 0)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, 'cpu', 'stddev'), 'ms', 0)
-
-      self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
-                        gpu_timeline.TimelineName(name, 'gpu', 'max'))
-      self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
-                        gpu_timeline.TimelineName(name, 'gpu', 'mean'))
-      self.assertRaises(AssertionError, results.GetPageSpecificValueNamed,
-                        gpu_timeline.TimelineName(name, 'gpu', 'stddev'))
-
-  def testFrameSeparation(self):
-    """Test frames are correctly calculated using the frame end marker."""
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-
-    # First frame is 10 seconds.
-    for slice_item in _CreateGPUSlices(test_thread, 'test_item', 100, 10):
-      _AddSliceToThread(test_thread, slice_item)
-
-    # Mark frame end.
-    for slice_item in _CreateFrameEndSlices(test_thread, 105, 5):
-      _AddSliceToThread(test_thread, slice_item)
-
-    # Second frame is 20 seconds.
-    for slice_item in _CreateGPUSlices(test_thread, 'test_item', 110, 20):
-      _AddSliceToThread(test_thread, slice_item)
-
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for name, source_type in (('swap', None),
-                              ('total', 'cpu'),
-                              ('total', 'gpu')):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, source_type, 'max'), 'ms', 20)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, source_type, 'mean'), 'ms', 15)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, source_type, 'stddev'), 'ms', 5)
-
-  def testFrameSeparationBeforeMarker(self):
-    """Test frames are correctly calculated using the frame end marker."""
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-
-    # Mark frame end.
-    for slice_item in _CreateFrameEndSlices(test_thread, 105, 5):
-      _AddSliceToThread(test_thread, slice_item)
-
-    # First frame is 10 seconds.
-    for slice_item in _CreateGPUSlices(test_thread, 'test_item', 100, 10):
-      _AddSliceToThread(test_thread, slice_item)
-
-    # Second frame is 20 seconds.
-    for slice_item in _CreateGPUSlices(test_thread, 'test_item', 110, 20):
-      _AddSliceToThread(test_thread, slice_item)
-
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for name, src_type in (('swap', None), ('total', 'cpu'), ('total', 'gpu')):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, src_type, 'max'), 'ms', 20)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, src_type, 'mean'), 'ms', 15)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(name, src_type, 'stddev'), 'ms', 5)
-
-  def testTrackedNameTraces(self):
-    """Be sure tracked names are being recorded correctly."""
-    self.assertGreater(len(gpu_timeline.TRACKED_GL_CONTEXT_NAME), 0)
-
-    marker, result = gpu_timeline.TRACKED_GL_CONTEXT_NAME.iteritems().next()
-
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    for slice_item in _CreateGPUSlices(test_thread, marker, 100, 10):
-      _AddSliceToThread(test_thread, slice_item)
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for source_type in ('cpu', 'gpu'):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result, source_type, 'max'),
-          'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result, source_type, 'mean'),
-          'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result, source_type, 'stddev'),
-          'ms', 0)
-
-  def testTrackedNameWithContextIDTraces(self):
-    """Be sure tracked names with context IDs are recorded correctly."""
-    self.assertGreater(len(gpu_timeline.TRACKED_GL_CONTEXT_NAME), 0)
-
-    marker, result = gpu_timeline.TRACKED_GL_CONTEXT_NAME.iteritems().next()
-    context_id = '-0x1234'
-
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    for slice_item in _CreateGPUSlices(test_thread, marker + context_id,
-                                       100, 10):
-      _AddSliceToThread(test_thread, slice_item)
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for source_type in ('cpu', 'gpu'):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result, source_type, 'max'),
-          'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result, source_type, 'mean'),
-          'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result, source_type, 'stddev'),
-          'ms', 0)
-
-  def testOutOfOrderDeviceTraces(self):
-    """Out of order device traces are still matched up to correct services."""
-    self.assertGreaterEqual(len(gpu_timeline.TRACKED_GL_CONTEXT_NAME), 2)
-
-    tracked_names_iter = gpu_timeline.TRACKED_GL_CONTEXT_NAME.iteritems()
-    marker1_name, result1_name = tracked_names_iter.next()
-    result2_name = result1_name
-    while result2_name == result1_name:
-      marker2_name, result2_name = tracked_names_iter.next()
-
-    model = model_module.TimelineModel()
-    test_thread = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-
-    # marker1 lasts for 10 seconds.
-    service_item1, device_item1 = _CreateGPUSlices(test_thread, marker1_name,
-                                                   100, 10)
-    # marker2 lasts for 20 seconds.
-    service_item2, device_item2 = _CreateGPUSlices(test_thread, marker2_name,
-                                                   200, 20)
-
-    # Append out of order
-    _AddSliceToThread(test_thread, service_item1)
-    _AddSliceToThread(test_thread, service_item2)
-    _AddSliceToThread(test_thread, device_item2)
-    _AddSliceToThread(test_thread, device_item1)
-
-    model.FinalizeImport()
-
-    metric = gpu_timeline.GPUTimelineMetric()
-    results = self.GetResults(metric, model=model, renderer_thread=test_thread,
-                              interaction_records=INTERACTION_RECORDS)
-
-    for source_type in ('cpu', 'gpu'):
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result1_name, source_type, 'max'),
-          'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result1_name, source_type, 'mean'),
-          'ms', 10)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result1_name, source_type, 'stddev'),
-          'ms', 0)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result2_name, source_type, 'max'),
-          'ms', 20)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result2_name, source_type, 'mean'),
-          'ms', 20)
-      results.AssertHasPageSpecificScalarValue(
-          gpu_timeline.TimelineName(result2_name, source_type, 'stddev'),
-          'ms', 0)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/indexeddb_timeline.py b/catapult/telemetry/telemetry/web_perf/metrics/indexeddb_timeline.py
deleted file mode 100644
index 1dc8382..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/indexeddb_timeline.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-from telemetry.web_perf.metrics import timeline_based_metric
-from telemetry.web_perf.metrics.trace_event_stats import TraceEventStats
-from telemetry.web_perf.metrics.trace_event_stats import TraceEventStatsInput
-
-
-class IndexedDBTimelineMetric(timeline_based_metric.TimelineBasedMetric):
-  """Metrics for IndexedDB operations.
-  """
-
-  def __init__(self):
-    super(IndexedDBTimelineMetric, self).__init__()
-    self._stats = TraceEventStats()
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBDatabase::GetOperation',
-      metric_name='idb-gets',
-      metric_description='The duration of all "get" ops in IndexedDB',
-      units='ms',
-      process_name='Browser'))
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBDatabase::PutOperation',
-      metric_name='idb-puts',
-      metric_description='The duration of all "put" ops in IndexedDB',
-      units='ms',
-      process_name='Browser'))
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBFactoryImpl::Open',
-      metric_name='idb-opens',
-      metric_description='The duration of all "open" ops in IndexedDB',
-      units='ms',
-      process_name='Browser'))
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBTransaction::Commit',
-      metric_name='idb-transaction-commits',
-      metric_description=('The duration of all "commit" ops of ' +
-                               'transactions in IndexedDB.'),
-      units='ms',
-      process_name='Browser'))
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBFactoryImpl::DeleteDatabase',
-      metric_name='idb-database-deletes',
-      metric_description=('The duration of all "delete" ops of ' +
-                               'IndexedDB databases.'),
-      units='ms',
-      process_name='Browser'))
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBDatabase::OpenCursorOperation',
-      metric_name='idb-cursor-opens',
-      metric_description=('The duration of all "open" ops of ' +
-                               'IndexedDB cursors.'),
-      units='ms',
-      process_name='Browser'))
-
-    self._stats.AddInput(TraceEventStatsInput(
-      event_category='IndexedDB',
-      event_name='IndexedDBCursor::CursorIterationOperation',
-      metric_name='idb-cursor-iterations',
-      metric_description=('The duration of all "iteration" ops of ' +
-                               'IndexedDB cursors.'),
-      units='ms',
-      process_name='Browser'))
-
-  def AddResults(self, model, renderer_process, interactions, results):
-    self._stats.AddResults(model, renderer_process, interactions, results)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/jitter_timeline.py b/catapult/telemetry/telemetry/web_perf/metrics/jitter_timeline.py
deleted file mode 100644
index cc1879d..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/jitter_timeline.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.web_perf.metrics import timeline_based_metric
-
-
-JITTER_EVENT_NAME = 'jitter'
-
-
-class JitterTimelineMetric(timeline_based_metric.TimelineBasedMetric):
-  """JitterTimelineMetric reports jitter in composited layers.
-
-  This jitter is due to the main thread attempting to fix the position of a
-  scrolling composited layer. 'jitter-amount' is the metric added to the
-  results.
-  """
-
-  def __init__(self):
-    super(JitterTimelineMetric, self).__init__()
-
-  @staticmethod
-  def IsJitterEvent(event):
-    return event.name == JITTER_EVENT_NAME
-
-  def AddResults(self, model, renderer_thread, interactions, results):
-    assert interactions
-
-    jitter_events = []
-    for event in model.IterAllEvents(
-        event_predicate=self.IsJitterEvent):
-      jitter_events.append(event)
-
-    self._AddJitterResultsInternal(jitter_events, interactions, results)
-
-  def _AddJitterResultsInternal(self, events, interactions, results):
-    jitters = []
-    for event in events:
-      if timeline_based_metric.IsEventInInteractions(event, interactions):
-        jitters.append(event.args['value'])
-    if jitters:
-      results.AddValue(list_of_scalar_values.ListOfScalarValues(
-          page=results.current_page,
-          tir_label=interactions[0].label,
-          name='jitter-amount',
-          units='score',
-          values=jitters,
-          description='Jitter each frame',
-          improvement_direction=improvement_direction.DOWN))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/jitter_timeline_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/jitter_timeline_unittest.py
deleted file mode 100644
index d2a93dc..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/jitter_timeline_unittest.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from collections import namedtuple
-from telemetry.internal.results import page_test_results
-from telemetry.page import page
-from telemetry.web_perf.metrics import jitter_timeline
-from telemetry.web_perf import timeline_interaction_record
-
-
-FakeEvent = namedtuple('Event', 'name, start, end, thread_duration, args')
-Interaction = timeline_interaction_record.TimelineInteractionRecord
-TEST_INTERACTION_LABEL = 'Action_TestInteraction'
-JITTER_EVENT_NAME = 'jitter'
-
-def GetJitterMetrics(events, interactions):
-  results = page_test_results.PageTestResults()
-  test_page = page.Page('file://blank.html')
-  results.WillRunPage(test_page)
-  jitter_timeline.JitterTimelineMetric()._AddJitterResultsInternal(
-      events, interactions, results)
-  return_dict = dict((value.name, value.values) for value in
-                     results.current_page_run.values)
-  results.DidRunPage(test_page)
-  return return_dict
-
-def FakeJitterEvent(start, end, value, thread_duration=None):
-  if not thread_duration:
-    thread_duration = end - start
-  return FakeEvent(jitter_timeline.JITTER_EVENT_NAME,
-          start, end, thread_duration, {'value':value})
-
-def TestInteraction(start, end):
-  return Interaction(TEST_INTERACTION_LABEL, start, end)
-
-
-class JitterTimelineMetricUnitTest(unittest.TestCase):
-  def testJitterMetric(self):
-    events = [FakeJitterEvent(0, 1, 10),
-              FakeJitterEvent(5, 10, 5),
-              FakeJitterEvent(15, 34, 45)]
-    interactions = [TestInteraction(4, 14)]
-    # The first and the last event do not start during the interaction, so
-    # they are ignored. The second event starts during the interaction, and its
-    # value is 5.
-    self.assertEqual({'jitter-amount': [5]},
-        GetJitterMetrics(events, interactions))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/layout.py b/catapult/telemetry/telemetry/web_perf/metrics/layout.py
deleted file mode 100644
index fb1c5f2..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/layout.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.web_perf.metrics import single_event
-
-EVENT_NAME = 'FrameView::performLayout'
-METRIC_NAME = 'layout'
-
-class LayoutMetric(single_event._SingleEventMetric):
-  """Reports directly durations of FrameView::performLayout events.
-
-    layout: Durations of FrameView::performLayout events that were caused by and
-            start during user interaction.
-
-  Layout happens no more than once per frame, so per-frame-ness is implied.
-  """
-
-  def __init__(self):
-    super(LayoutMetric, self).__init__(EVENT_NAME, METRIC_NAME,
-        metric_description=('List of durations of layouts that were caused by '
-                            'and start during interactions'))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/mainthread_jank_stats.py b/catapult/telemetry/telemetry/web_perf/metrics/mainthread_jank_stats.py
deleted file mode 100644
index 66a86a7..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/mainthread_jank_stats.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-# A top level slice of a main thread can cause the webapp to behave
-# unresponsively if its thread duration is greater than or equals to
-# USER_PERCEIVABLE_DELAY_THRESHOLD_MS. Human eyes can perceive delay at low as
-# 100ms, but since we use thread time instead of wall-time, we reduce the
-# threshold further to 50ms to make room for other OS's activities.
-USER_PERCEIVABLE_DELAY_THRESHOLD_MS = 50
-
-
-class _MainthreadJankStat(object):
-  """A small wrapper class for storing mainthread jank stats computed for
-  single record.
-  """
-
-  def __init__(self):
-    self.sum_big_top_slices_thread_time = 0
-    self.biggest_top_slice_thread_time = 0
-
-
-def _ComputeMainthreadJankStatsForRecord(renderer_thread, record):
-  """Computes the mainthread jank stat on a record range.
-
-  Returns:
-      An instance of _MainthreadJankStat, which has:
-
-      sum_big_top_slices_thread_time is the total thread duration of all top
-      slices whose thread time ranges overlapped with (thread_start, thread_end)
-      and the overlapped thread duration is greater than or equal
-      USER_PERCEIVABLE_DELAY_THRESHOLD_MS.
-
-      biggest_top_slice_thread_time is the biggest thread duration of all
-      top slices whose thread time ranges overlapped with
-      (thread_start, thread_end).
-
-      Note: thread duration of each slices is computed using overlapped range
-      with (thread_start, thread_end).
-  """
-  stat = _MainthreadJankStat()
-  for s in renderer_thread.toplevel_slices:
-    jank_thread_duration = record.GetOverlappedThreadTimeForSlice(s)
-    stat.biggest_top_slice_thread_time = max(
-        stat.biggest_top_slice_thread_time, jank_thread_duration)
-    if jank_thread_duration >= USER_PERCEIVABLE_DELAY_THRESHOLD_MS:
-      stat.sum_big_top_slices_thread_time += jank_thread_duration
-  return stat
-
-
-class MainthreadJankStats(object):
-  """
-    Utility class for extracting main thread jank statistics from the timeline
-    (or other loggin facilities), and providing them in a common format to
-    classes that compute benchmark metrics from this data.
-
-      total_big_jank_thread_time is the total thread duration of all top
-      slices whose thread time ranges overlapped with any thread time ranges of
-      the records and the overlapped thread duration is greater than or equal
-      USER_PERCEIVABLE_DELAY_THRESHOLD_MS.
-
-      biggest_jank_thread_time is the biggest thread duration of all
-      top slices whose thread time ranges overlapped with any of records' thread
-      time ranges.
-  """
-
-  def __init__(self, renderer_thread, interaction_records):
-    self._renderer_thread = renderer_thread
-    self._interaction_records = interaction_records
-    self._total_big_jank_thread_time = 0
-    self._biggest_jank_thread_time = 0
-    self._ComputeMainthreadJankStats()
-
-  @property
-  def total_big_jank_thread_time(self):
-    return self._total_big_jank_thread_time
-
-  @property
-  def biggest_jank_thread_time(self):
-    return self._biggest_jank_thread_time
-
-  def _ComputeMainthreadJankStats(self):
-    for record in self._interaction_records:
-      record_jank_stat = _ComputeMainthreadJankStatsForRecord(
-          self._renderer_thread, record)
-      self._total_big_jank_thread_time += (
-          record_jank_stat.sum_big_top_slices_thread_time)
-      self._biggest_jank_thread_time = (
-          max(self._biggest_jank_thread_time,
-              record_jank_stat.biggest_top_slice_thread_time))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/mainthread_jank_stats_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/mainthread_jank_stats_unittest.py
deleted file mode 100644
index 093d686..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/mainthread_jank_stats_unittest.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import async_slice
-from telemetry.timeline import model as model_module
-from telemetry.web_perf.metrics import mainthread_jank_stats
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-
-class MainthreadJankTests(unittest.TestCase):
-
-  def CreateTestRecord(self, name, start, end, thread_start, thread_end,
-                       parent_thread):
-    s = async_slice.AsyncSlice(
-        'cat', 'Interaction.%s' % name,
-        timestamp=start, duration=end - start, start_thread=parent_thread,
-        end_thread=parent_thread, thread_start=thread_start,
-        thread_duration=thread_end - thread_start)
-    return tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
-
-  def testComputeMainthreadJankStatsForRecord(self):
-    # The slice hierarchy should look something like this:
-    # [  MessageLoop::RunTask   ] [MessageLoop::RunTask][  MessagLoop::RunTask ]
-    #                                 [ foo ]                  [ bar ]
-    #            |                                                |
-    #          200ms                                            800ms
-    #       (thread_start)                                   (thread_end)
-    #
-    # Note: all timings mentioned here and in comments below are thread time.
-
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    renderer_main.name = 'CrRendererMain'
-
-    #   [     MessageLoop::RunTask             ]
-    # 100ms                                   300ms
-    renderer_main.BeginSlice('toplevel', 'MessageLoop::RunTask', 112, 100)
-    renderer_main.EndSlice(240, 300)
-
-    #   [     MessageLoop::RunTask             ]
-    # 450ms     [   foo  ]                    475 ms
-    #         460ms    470ms
-    renderer_main.BeginSlice('toplevel', 'MessageLoop::RunTask', 462, 450)
-    renderer_main.BeginSlice('otherlevel', 'foo', 468, 460)
-    renderer_main.EndSlice(475, 470)
-    renderer_main.EndSlice(620, 475)
-
-    #   [     MessageLoop::RunTask             ]
-    #  620ms     [   bar  ]                   900ms
-    #         750ms    850ms
-    renderer_main.BeginSlice('toplevel', 'MessageLoop::RunTask', 652, 620)
-    renderer_main.BeginSlice('otherlevel', 'bar', 785, 750)
-    renderer_main.EndSlice(875, 850)
-    renderer_main.EndSlice(1040, 900)
-
-    model.FinalizeImport(shift_world_to_zero=False)
-
-    # Make a record that starts at 200ms and ends at 800ms in thread time
-    record = self.CreateTestRecord('test', 100, 700, 200, 800, renderer_main)
-    # pylint: disable=protected-access
-    stat = mainthread_jank_stats._ComputeMainthreadJankStatsForRecord(
-        renderer_main, record)
-
-    # The overlapped between thread time range(200ms -> 800ms)
-    # with the first top slice (100ms -> 300ms) is 300 - 200 = 100ms,
-    # with the second slice (450ms -> 475ms) is 475 - 450 = 25 ms,
-    # with the third slice (620ms -> 900ms) is 800 - 620 = 180 ms.
-    #
-    # Hence we have 2 big top slices which overlapped duration > 50ms,
-    # the biggest top slice is 180ms, and the total big top slice's thread time
-    # is 100 + 180 = 280ms.
-    self.assertEquals(180, stat.biggest_top_slice_thread_time)
-    self.assertEquals(280, stat.sum_big_top_slices_thread_time)
-
-  def testMainthreadJankStats(self):
-    # [ MessageLoop::RunTask]  [MessageLoop::RunTask]  [MessagLoop::RunTask]
-    # 10                   100 120                 400 450                750
-    #     [  record_1  ]       [  record_2  ]   [            record_3        ]
-    #     40          70      120          200  220                         900
-
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    renderer_main.name = 'CrRendererMain'
-
-    #   [     MessageLoop::RunTask  ]
-    #   10ms                       100ms
-    renderer_main.BeginSlice('toplevel', 'MessageLoop::RunTask', 12, 10)
-    renderer_main.EndSlice(120, 100)
-
-    #   [     MessageLoop::RunTask  ]
-    #   120ms                      200ms
-    renderer_main.BeginSlice('toplevel', 'MessageLoop::RunTask', 115, 120)
-    renderer_main.EndSlice(410, 400)
-
-    #   [     MessageLoop::RunTask  ]
-    #  220ms                       900ms
-    renderer_main.BeginSlice('toplevel', 'MessageLoop::RunTask', 477, 450)
-    renderer_main.EndSlice(772, 750)
-
-    model.FinalizeImport(shift_world_to_zero=False)
-
-    test_records = [
-        self.CreateTestRecord('record_1', 10, 80, 40, 70, renderer_main),
-        self.CreateTestRecord('record_2', 100, 210, 120, 200, renderer_main),
-        self.CreateTestRecord('record_3', 215, 920, 220, 900, renderer_main)
-    ]
-
-    stats = mainthread_jank_stats.MainthreadJankStats(
-        renderer_main, test_records)
-    # Main thread janks covered by records' ranges are:
-    # Record 1: (40ms -> 70ms)
-    # Record 2: (120ms -> 200ms)
-    # Record 3: (220ms -> 400ms), (450ms -> 750ms)
-    self.assertEquals(560, stats.total_big_jank_thread_time)
-    self.assertEquals(300, stats.biggest_jank_thread_time)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame.py b/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame.py
deleted file mode 100644
index 48f8546..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from collections import defaultdict
-
-from telemetry.timeline import bounds
-from telemetry.timeline import slice as slice_module
-
-
-class MissingData(Exception):
-  pass
-
-
-class NoBeginFrameIdException(Exception):
-  pass
-
-
-class RenderingFrame(object):
-  """Object with information about the triggering of a BeginMainFrame event."""
-  send_begin_frame_event = 'ThreadProxy::ScheduledActionSendBeginMainFrame'
-  begin_main_frame_event = 'ThreadProxy::BeginMainFrame'
-
-  def __init__(self, events):
-    all_send_begin_frame_events = [e for e in events
-                                   if e.name == self.send_begin_frame_event]
-    if len(all_send_begin_frame_events) != 1:
-      raise MissingData('There must be at exactly one %s event.' %
-                        self.send_begin_frame_event)
-
-    all_begin_main_frame_events = [e for e in events
-                                   if e.name == self.begin_main_frame_event]
-    if not all_begin_main_frame_events:
-      raise MissingData('There must be at least one %s event.' %
-                        self.begin_main_frame_event)
-    all_begin_main_frame_events.sort(key=lambda e: e.start)
-
-    self._send_begin_frame = all_send_begin_frame_events[0]
-    self._begin_main_frame = all_begin_main_frame_events[-1]
-
-    self._bounds = bounds.Bounds()
-    self._bounds.AddEvent(self._begin_main_frame)
-    self._bounds.AddEvent(self._send_begin_frame)
-
-  @staticmethod
-  def IsEventUseful(event):
-    return event.name in [RenderingFrame.send_begin_frame_event,
-                          RenderingFrame.begin_main_frame_event]
-
-  @property
-  def bounds(self):
-    return self._bounds
-
-  @property
-  def queueing_duration(self):
-    return self._begin_main_frame.start - self._send_begin_frame.start
-
-
-def GetFrameEventsInsideRange(renderer_process, timeline_range):
-  """Returns RenderingFrames for all relevant events in the timeline_range."""
-  # First filter all events from the renderer_process and turn them into a
-  # dictonary of the form:
-  #   {0: [send_begin_frame, begin_main_frame, begin_main_frame],
-  #    1: [begin_main_frame, send_begin_frame],
-  #    2: [send_begin_frame, begin_main_frame]}
-  begin_frame_events_by_id = defaultdict(list)
-  for event in renderer_process.IterAllEvents(
-      event_type_predicate=lambda t: t == slice_module.Slice,
-      event_predicate=RenderingFrame.IsEventUseful):
-    begin_frame_id = event.args.get('begin_frame_id', None)
-    if begin_frame_id is None:
-      raise NoBeginFrameIdException('Event is missing a begin_frame_id.')
-    begin_frame_events_by_id[begin_frame_id].append(event)
-
-  # Now, create RenderingFrames for events wherever possible.
-  frames = []
-  for events in begin_frame_events_by_id.values():
-    try:
-      frame = RenderingFrame(events)
-      if frame.bounds.Intersects(timeline_range):
-        frames.append(frame)
-    except MissingData:
-      continue
-  frames.sort(key=lambda frame: frame.bounds.min)
-
-  return frames
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py
deleted file mode 100644
index 95f6d93..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import telemetry.timeline.bounds as timeline_bounds
-from telemetry.timeline import model
-import telemetry.timeline.slice as tracing_slice
-from telemetry.web_perf.metrics. \
-    rendering_frame import GetFrameEventsInsideRange
-from telemetry.web_perf.metrics.rendering_frame import MissingData
-from telemetry.web_perf.metrics.rendering_frame import RenderingFrame
-
-
-class RenderingFrameTestData(object):
-
-  def __init__(self):
-    self._begin_frame_id = 0
-    self._events = []
-    self._renderer_process = model.TimelineModel().GetOrCreateProcess(pid=1)
-    self._main_thread = self._renderer_process.GetOrCreateThread(tid=11)
-    self._compositor_thread = self._renderer_process.GetOrCreateThread(tid=12)
-
-  @property
-  def events(self):
-    return self._events
-
-  @property
-  def renderer_process(self):
-    return self._renderer_process
-
-  def AddSendEvent(self, ts=0, duration=1):
-    self._begin_frame_id += 1
-    event = self._CreateEvent(
-        RenderingFrame.send_begin_frame_event, ts, duration)
-    self._compositor_thread.PushSlice(event)
-
-  def AddBeginMainFrameEvent(self, ts=0, duration=1):
-    event = self._CreateEvent(
-        RenderingFrame.begin_main_frame_event, ts, duration)
-    self._main_thread.PushSlice(event)
-
-  def FinalizeImport(self):
-    self._renderer_process.FinalizeImport()
-
-  def _CreateEvent(self, event_name, ts, duration):
-    event = tracing_slice.Slice(None, 'cc,benchmark', event_name, ts,
-        duration=duration, args={'begin_frame_id': self._begin_frame_id})
-    self._events.append(event)
-    return event
-
-
-def GenerateTimelineRange(start=0, end=100):
-  timeline_range = timeline_bounds.Bounds()
-  timeline_range.AddValue(start)
-  timeline_range.AddValue(end)
-  return timeline_range
-
-
-class RenderingFrameUnitTest(unittest.TestCase):
-
-  def testRenderingFrame(self):
-    d = RenderingFrameTestData()
-    d.AddSendEvent(ts=10)
-    d.AddBeginMainFrameEvent(ts=20)
-    d.FinalizeImport()
-
-    frame = RenderingFrame(d.events)
-    self.assertEquals(10, frame.queueing_duration)
-
-  def testRenderingFrameMissingSendBeginFrameEvents(self):
-    d = RenderingFrameTestData()
-    d.AddBeginMainFrameEvent(ts=10)
-    d.FinalizeImport()
-
-    self.assertRaises(MissingData, RenderingFrame, d.events)
-
-  def testRenderingFrameDuplicateSendBeginFrameEvents(self):
-    d = RenderingFrameTestData()
-    d.AddSendEvent(ts=10)
-    d.AddBeginMainFrameEvent(ts=20)
-    d.AddSendEvent(ts=30)
-    d.FinalizeImport()
-
-    self.assertRaises(MissingData, RenderingFrame, d.events)
-
-  def testRenderingFrameMissingBeginMainFrameEvents(self):
-    d = RenderingFrameTestData()
-    d.AddSendEvent(ts=10)
-    d.FinalizeImport()
-
-    self.assertRaises(MissingData, RenderingFrame, d.events)
-
-  def testRenderingFrameDuplicateBeginMainFrameEvents(self):
-    d = RenderingFrameTestData()
-    d.AddSendEvent(ts=10)
-    d.AddBeginMainFrameEvent(ts=20)
-    d.AddBeginMainFrameEvent(ts=30)
-    d.AddBeginMainFrameEvent(ts=40)
-    d.FinalizeImport()
-
-    frame = RenderingFrame(d.events)
-    self.assertEquals(30, frame.queueing_duration)
-
-  def testFrameEventMissingBeginFrameId(self):
-    timeline = model.TimelineModel()
-    process = timeline.GetOrCreateProcess(pid=1)
-    main_thread = process.GetOrCreateThread(tid=11)
-    timeline_range = timeline_bounds.Bounds()
-
-    # Create an event without the begin_frame_id argument
-    event = tracing_slice.Slice(
-        None, 'cc,benchmark', RenderingFrame.begin_main_frame_event, 0)
-    main_thread.PushSlice(event)
-    process.FinalizeImport()
-    self.assertRaises(Exception, GetFrameEventsInsideRange, process,
-                      timeline_range)
-
-  def testGetFrameEventsInsideRange(self):
-    """Test a basic sequenece, with expected frame queueing delays A and B.
-
-                 |----A----|    |--B--|
-         Main:        [1]  [1]        [2]
-
-    Compositor:  [1]            [2]
-    """
-    d = RenderingFrameTestData()
-    d.AddSendEvent(ts=10)
-    d.AddBeginMainFrameEvent(ts=20)
-    d.AddBeginMainFrameEvent(ts=30)
-    d.AddSendEvent(ts=40)
-    d.AddBeginMainFrameEvent(ts=50)
-    d.FinalizeImport()
-
-    timeline_range = GenerateTimelineRange()
-    frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
-
-    self.assertEquals(2, len(frame_events))
-    self.assertEquals(20, frame_events[0].queueing_duration)
-    self.assertEquals(10, frame_events[1].queueing_duration)
-
-  def testFrameEventsMissingDataNotIncluded(self):
-    """Test a sequenece missing an initial SendBeginFrame.
-
-    Only one frame should be returned, with expected frame queueing delay A.
-                           |--A--|
-          Main:  [0]  [0]        [2]
-
-    Compositor:            [2]
-    """
-    d = RenderingFrameTestData()
-    d.AddBeginMainFrameEvent(ts=20)
-    d.AddBeginMainFrameEvent(ts=30)
-    d.AddSendEvent(ts=40)
-    d.AddBeginMainFrameEvent(ts=50)
-    d.FinalizeImport()
-
-    timeline_range = GenerateTimelineRange()
-    frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
-
-    self.assertEquals(1, len(frame_events))
-    self.assertEquals(10, frame_events[0].queueing_duration)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/rendering_stats.py b/catapult/telemetry/telemetry/web_perf/metrics/rendering_stats.py
deleted file mode 100644
index 9f9b104..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/rendering_stats.py
+++ /dev/null
@@ -1,316 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import itertools
-
-from operator import attrgetter
-
-from telemetry.web_perf.metrics import rendering_frame
-
-# These are LatencyInfo component names indicating the various components
-# that the input event has travelled through.
-# This is when the input event first reaches chrome.
-UI_COMP_NAME = 'INPUT_EVENT_LATENCY_UI_COMPONENT'
-# This is when the input event was originally created by OS.
-ORIGINAL_COMP_NAME = 'INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT'
-# This is when the input event was sent from browser to renderer.
-BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT'
-# This is when an input event is turned into a scroll update.
-BEGIN_SCROLL_UPDATE_COMP_NAME = (
-    'LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT')
-# This is when a scroll update is forwarded to the main thread.
-FORWARD_SCROLL_UPDATE_COMP_NAME = (
-    'INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT')
-# This is when the input event has reached swap buffer.
-END_COMP_NAME = 'INPUT_EVENT_GPU_SWAP_BUFFER_COMPONENT'
-
-# Name for a main thread scroll update latency event.
-MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME = 'Latency::ScrollUpdate'
-# Name for a gesture scroll update latency event.
-GESTURE_SCROLL_UPDATE_EVENT_NAME = 'InputLatency::GestureScrollUpdate'
-
-# These are keys used in the 'data' field dictionary located in
-# BenchmarkInstrumentation::ImplThreadRenderingStats.
-VISIBLE_CONTENT_DATA = 'visible_content_area'
-APPROXIMATED_VISIBLE_CONTENT_DATA = 'approximated_visible_content_area'
-CHECKERBOARDED_VISIBLE_CONTENT_DATA = 'checkerboarded_visible_content_area'
-# These are keys used in the 'errors' field  dictionary located in
-# RenderingStats in this file.
-APPROXIMATED_PIXEL_ERROR = 'approximated_pixel_percentages'
-CHECKERBOARDED_PIXEL_ERROR = 'checkerboarded_pixel_percentages'
-
-
-def GetLatencyEvents(process, timeline_range):
-  """Get LatencyInfo trace events from the process's trace buffer that are
-     within the timeline_range.
-
-  Input events dump their LatencyInfo into trace buffer as async trace event
-  of name starting with "InputLatency". Non-input events with name starting
-  with "Latency". The trace event has a member 'data' containing its latency
-  history.
-
-  """
-  latency_events = []
-  if not process:
-    return latency_events
-  for event in itertools.chain(
-      process.IterAllAsyncSlicesStartsWithName('InputLatency'),
-      process.IterAllAsyncSlicesStartsWithName('Latency')):
-    if event.start >= timeline_range.min and event.end <= timeline_range.max:
-      for ss in event.sub_slices:
-        if 'data' in ss.args:
-          latency_events.append(ss)
-  return latency_events
-
-
-def ComputeEventLatencies(input_events):
-  """ Compute input event latencies.
-
-  Input event latency is the time from when the input event is created to
-  when its resulted page is swap buffered.
-  Input event on different platforms uses different LatencyInfo component to
-  record its creation timestamp. We go through the following component list
-  to find the creation timestamp:
-  1. INPUT_EVENT_LATENCY_ORIGINAL_COMPONENT -- when event is created in OS
-  2. INPUT_EVENT_LATENCY_UI_COMPONENT -- when event reaches Chrome
-  3. INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT -- when event reaches RenderWidget
-
-  If the latency starts with a
-  LATENCY_BEGIN_SCROLL_UPDATE_MAIN_COMPONENT component, then it is
-  classified as a scroll update instead of a normal input latency measure.
-
-  Returns:
-    A list sorted by increasing start time of latencies which are tuples of
-    (input_event_name, latency_in_ms).
-  """
-  input_event_latencies = []
-  for event in input_events:
-    data = event.args['data']
-    if END_COMP_NAME in data:
-      end_time = data[END_COMP_NAME]['time']
-      if ORIGINAL_COMP_NAME in data:
-        start_time = data[ORIGINAL_COMP_NAME]['time']
-      elif UI_COMP_NAME in data:
-        start_time = data[UI_COMP_NAME]['time']
-      elif BEGIN_COMP_NAME in data:
-        start_time = data[BEGIN_COMP_NAME]['time']
-      elif BEGIN_SCROLL_UPDATE_COMP_NAME in data:
-        start_time = data[BEGIN_SCROLL_UPDATE_COMP_NAME]['time']
-      else:
-        raise ValueError('LatencyInfo has no begin component')
-      latency = (end_time - start_time) / 1000.0
-      input_event_latencies.append((start_time, event.name, latency))
-
-  input_event_latencies.sort()
-  return [(name, latency) for _, name, latency in input_event_latencies]
-
-
-def HasDrmStats(process):
-  """ Return True if the process contains DrmEventFlipComplete event.
-  """
-  if not process:
-    return False
-  for event in process.IterAllSlicesOfName('DrmEventFlipComplete'):
-    if 'data' in event.args and event.args['data']['frame_count'] == 1:
-      return True
-  return False
-
-def HasRenderingStats(process):
-  """ Returns True if the process contains at least one
-      BenchmarkInstrumentation::*RenderingStats event with a frame.
-  """
-  if not process:
-    return False
-  for event in process.IterAllSlicesOfName(
-      'BenchmarkInstrumentation::DisplayRenderingStats'):
-    if 'data' in event.args and event.args['data']['frame_count'] == 1:
-      return True
-  for event in process.IterAllSlicesOfName(
-      'BenchmarkInstrumentation::ImplThreadRenderingStats'):
-    if 'data' in event.args and event.args['data']['frame_count'] == 1:
-      return True
-  return False
-
-def GetTimestampEventName(process):
-  """ Returns the name of the events used to count frame timestamps. """
-  if process.name == 'SurfaceFlinger':
-    return 'vsync_before'
-
-  if process.name == 'GPU Process':
-    return 'DrmEventFlipComplete'
-
-  event_name = 'BenchmarkInstrumentation::DisplayRenderingStats'
-  for event in process.IterAllSlicesOfName(event_name):
-    if 'data' in event.args and event.args['data']['frame_count'] == 1:
-      return event_name
-
-  return 'BenchmarkInstrumentation::ImplThreadRenderingStats'
-
-class RenderingStats(object):
-  def __init__(self, renderer_process, browser_process, surface_flinger_process,
-               gpu_process, timeline_ranges):
-    """
-    Utility class for extracting rendering statistics from the timeline (or
-    other loggin facilities), and providing them in a common format to classes
-    that compute benchmark metrics from this data.
-
-    Stats are lists of lists of numbers. The outer list stores one list per
-    timeline range.
-
-    All *_time values are measured in milliseconds.
-    """
-    assert len(timeline_ranges) > 0
-    self.refresh_period = None
-
-    # Find the top level process with rendering stats (browser or renderer).
-    if surface_flinger_process:
-      timestamp_process = surface_flinger_process
-      self._GetRefreshPeriodFromSurfaceFlingerProcess(surface_flinger_process)
-    elif HasDrmStats(gpu_process):
-      timestamp_process = gpu_process
-    elif HasRenderingStats(browser_process):
-      timestamp_process = browser_process
-    else:
-      timestamp_process = renderer_process
-
-    timestamp_event_name = GetTimestampEventName(timestamp_process)
-
-    # A lookup from list names below to any errors or exceptions encountered
-    # in attempting to generate that list.
-    self.errors = {}
-
-    self.frame_timestamps = []
-    self.frame_times = []
-    self.approximated_pixel_percentages = []
-    self.checkerboarded_pixel_percentages = []
-    # End-to-end latency for input event - from when input event is
-    # generated to when the its resulted page is swap buffered.
-    self.input_event_latency = []
-    self.frame_queueing_durations = []
-    # Latency from when a scroll update is sent to the main thread until the
-    # resulting frame is swapped.
-    self.main_thread_scroll_latency = []
-    # Latency for a GestureScrollUpdate input event.
-    self.gesture_scroll_update_latency = []
-
-    for timeline_range in timeline_ranges:
-      self.frame_timestamps.append([])
-      self.frame_times.append([])
-      self.approximated_pixel_percentages.append([])
-      self.checkerboarded_pixel_percentages.append([])
-      self.input_event_latency.append([])
-      self.main_thread_scroll_latency.append([])
-      self.gesture_scroll_update_latency.append([])
-
-      if timeline_range.is_empty:
-        continue
-      self._InitFrameTimestampsFromTimeline(
-          timestamp_process, timestamp_event_name, timeline_range)
-      self._InitImplThreadRenderingStatsFromTimeline(
-          renderer_process, timeline_range)
-      self._InitInputLatencyStatsFromTimeline(
-          browser_process, renderer_process, timeline_range)
-      self._InitFrameQueueingDurationsFromTimeline(
-          renderer_process, timeline_range)
-
-  def _GetRefreshPeriodFromSurfaceFlingerProcess(self, surface_flinger_process):
-    for event in surface_flinger_process.IterAllEventsOfName('vsync_before'):
-      self.refresh_period = event.args['data']['refresh_period']
-      return
-
-  def _InitInputLatencyStatsFromTimeline(
-      self, browser_process, renderer_process, timeline_range):
-    latency_events = GetLatencyEvents(browser_process, timeline_range)
-    # Plugin input event's latency slice is generated in renderer process.
-    latency_events.extend(GetLatencyEvents(renderer_process, timeline_range))
-    event_latencies = ComputeEventLatencies(latency_events)
-    # Don't include scroll updates in the overall input latency measurement,
-    # because scroll updates can take much more time to process than other
-    # input events and would therefore add noise to overall latency numbers.
-    self.input_event_latency[-1] = [
-        latency for name, latency in event_latencies
-        if name != MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME]
-    self.main_thread_scroll_latency[-1] = [
-        latency for name, latency in event_latencies
-        if name == MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME]
-    self.gesture_scroll_update_latency[-1] = [
-        latency for name, latency in event_latencies
-        if name == GESTURE_SCROLL_UPDATE_EVENT_NAME]
-
-  def _GatherEvents(self, event_name, process, timeline_range):
-    events = []
-    for event in process.IterAllSlicesOfName(event_name):
-      if event.start >= timeline_range.min and event.end <= timeline_range.max:
-        if 'data' not in event.args:
-          continue
-        events.append(event)
-    events.sort(key=attrgetter('start'))
-    return events
-
-  def _AddFrameTimestamp(self, event):
-    frame_count = event.args['data']['frame_count']
-    if frame_count > 1:
-      raise ValueError('trace contains multi-frame render stats')
-    if frame_count == 1:
-      if event.name == 'DrmEventFlipComplete':
-        self.frame_timestamps[-1].append(
-            event.args['data']['vblank.tv_sec'] * 1000.0 +
-            event.args['data']['vblank.tv_usec'] / 1000.0)
-      else:
-        self.frame_timestamps[-1].append(
-            event.start)
-      if len(self.frame_timestamps[-1]) >= 2:
-        self.frame_times[-1].append(
-            self.frame_timestamps[-1][-1] - self.frame_timestamps[-1][-2])
-
-  def _InitFrameTimestampsFromTimeline(
-      self, process, timestamp_event_name, timeline_range):
-    for event in self._GatherEvents(
-        timestamp_event_name, process, timeline_range):
-      self._AddFrameTimestamp(event)
-
-  def _InitImplThreadRenderingStatsFromTimeline(self, process, timeline_range):
-    event_name = 'BenchmarkInstrumentation::ImplThreadRenderingStats'
-    for event in self._GatherEvents(event_name, process, timeline_range):
-      data = event.args['data']
-      if VISIBLE_CONTENT_DATA not in data:
-        self.errors[APPROXIMATED_PIXEL_ERROR] = (
-          'Calculating approximated_pixel_percentages not possible because '
-          'visible_content_area was missing.')
-        self.errors[CHECKERBOARDED_PIXEL_ERROR] = (
-          'Calculating checkerboarded_pixel_percentages not possible because '
-          'visible_content_area was missing.')
-        return
-      visible_content_area = data[VISIBLE_CONTENT_DATA]
-      if visible_content_area == 0:
-        self.errors[APPROXIMATED_PIXEL_ERROR] = (
-          'Calculating approximated_pixel_percentages would have caused '
-          'a divide-by-zero')
-        self.errors[CHECKERBOARDED_PIXEL_ERROR] = (
-          'Calculating checkerboarded_pixel_percentages would have caused '
-          'a divide-by-zero')
-        return
-      if APPROXIMATED_VISIBLE_CONTENT_DATA in data:
-        self.approximated_pixel_percentages[-1].append(
-          round(float(data[APPROXIMATED_VISIBLE_CONTENT_DATA]) /
-                float(data[VISIBLE_CONTENT_DATA]) * 100.0, 3))
-      else:
-        self.errors[APPROXIMATED_PIXEL_ERROR] = (
-          'approximated_pixel_percentages was not recorded')
-      if CHECKERBOARDED_VISIBLE_CONTENT_DATA in data:
-        self.checkerboarded_pixel_percentages[-1].append(
-          round(float(data[CHECKERBOARDED_VISIBLE_CONTENT_DATA]) /
-                float(data[VISIBLE_CONTENT_DATA]) * 100.0, 3))
-      else:
-        self.errors[CHECKERBOARDED_PIXEL_ERROR] = (
-          'checkerboarded_pixel_percentages was not recorded')
-
-  def _InitFrameQueueingDurationsFromTimeline(self, process, timeline_range):
-    try:
-      events = rendering_frame.GetFrameEventsInsideRange(process,
-                                                         timeline_range)
-      new_frame_queueing_durations = [e.queueing_duration for e in events]
-      self.frame_queueing_durations.append(new_frame_queueing_durations)
-    except rendering_frame.NoBeginFrameIdException:
-      self.errors['frame_queueing_durations'] = (
-          'Current chrome version does not support the queueing delay metric.')
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
deleted file mode 100644
index 972d2f0..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/rendering_stats_unittest.py
+++ /dev/null
@@ -1,666 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import random
-import unittest
-
-from telemetry.timeline import async_slice
-from telemetry.timeline import bounds
-from telemetry.timeline import model
-from telemetry.util import perf_tests_helper
-from telemetry.util import statistics
-from telemetry.web_perf.metrics import rendering_stats
-
-
-class MockTimer(object):
-  """A mock timer class which can generate random durations.
-
-  An instance of this class is used as a global timer to generate random
-  durations for stats and consistent timestamps for all mock trace events.
-  The unit of time is milliseconds.
-  """
-
-  def __init__(self):
-    self.milliseconds = 0
-
-  def Advance(self, low=0.1, high=1):
-    delta = random.uniform(low, high)
-    self.milliseconds += delta
-    return delta
-
-  def AdvanceAndGet(self, low=0.1, high=1):
-    self.Advance(low, high)
-    return self.milliseconds
-
-
-class MockVblankTimer(object):
-  """A mock vblank timer class which can generate random durations.
-
-  An instance of this class is used as a vblank timer to generate random
-  durations for drm stats and consistent timeval for mock trace drm events.
-  The unit of time is microseconds.
-  """
-
-  def __init__(self):
-    self.microseconds = 200000000
-
-  def TvAdvance(self, low=100, high=1000):
-    delta = random.randint(low, high)
-    self.microseconds += delta
-    return delta
-
-  def TvAdvanceAndGet(self, low=100, high=1000):
-    self.TvAdvance(low, high)
-    return self.microseconds
-
-
-class ReferenceRenderingStats(object):
-  """ Stores expected data for comparison with actual RenderingStats """
-
-  def __init__(self):
-    self.frame_timestamps = []
-    self.frame_times = []
-    self.approximated_pixel_percentages = []
-    self.checkerboarded_pixel_percentages = []
-
-  def AppendNewRange(self):
-    self.frame_timestamps.append([])
-    self.frame_times.append([])
-    self.approximated_pixel_percentages.append([])
-    self.checkerboarded_pixel_percentages.append([])
-
-
-class ReferenceInputLatencyStats(object):
-  """ Stores expected data for comparison with actual input latency stats """
-
-  def __init__(self):
-    self.input_event_latency = []
-    self.input_event = []
-
-
-def AddSurfaceFlingerStats(mock_timer, thread, first_frame,
-                           ref_stats=None):
-  """ Adds a random surface flinger stats event.
-
-  thread: The timeline model thread to which the event will be added.
-  first_frame: Is this the first frame within the bounds of an action?
-  ref_stats: A ReferenceRenderingStats object to record expected values.
-  """
-  # Create random data and timestamp for impl thread rendering stats.
-  data = {'frame_count': 1,
-          'refresh_period': 16.6666}
-  timestamp = mock_timer.AdvanceAndGet()
-
-  # Add a slice with the event data to the given thread.
-  thread.PushCompleteSlice(
-      'SurfaceFlinger', 'vsync_before',
-      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
-      args={'data': data})
-
-  if not ref_stats:
-    return
-
-  # Add timestamp only if a frame was output
-  if data['frame_count'] == 1:
-    if not first_frame:
-      # Add frame_time if this is not the first frame in within the bounds of an
-      # action.
-      prev_timestamp = ref_stats.frame_timestamps[-1][-1]
-      ref_stats.frame_times[-1].append(timestamp - prev_timestamp)
-    ref_stats.frame_timestamps[-1].append(timestamp)
-
-
-def AddDrmEventFlipStats(mock_timer, vblank_timer, thread,
-                         first_frame, ref_stats=None):
-  """ Adds a random drm flip complete event.
-
-  thread: The timeline model thread to which the event will be added.
-  first_frame: Is this the first frame within the bounds of an action?
-  ref_stats: A ReferenceRenderingStats object to record expected values.
-  """
-  # Create random data and timestamp for drm thread flip complete stats.
-  vblank_timeval = vblank_timer.TvAdvanceAndGet()
-  vblank_tv_sec = vblank_timeval / 1000000
-  vblank_tv_usec = vblank_timeval % 1000000
-  data = {'frame_count': 1,
-          'vblank.tv_usec': vblank_tv_usec,
-          'vblank.tv_sec': vblank_tv_sec}
-  timestamp = mock_timer.AdvanceAndGet()
-
-  # Add a slice with the event data to the given thread.
-  thread.PushCompleteSlice(
-      'benchmark,drm', 'DrmEventFlipComplete',
-      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
-      args={'data': data})
-
-  if not ref_stats:
-    return
-
-  # Add vblank timeval only if a frame was output.
-  cur_timestamp = vblank_tv_sec * 1000.0 + vblank_tv_usec / 1000.0
-  if not first_frame:
-    # Add frame_time if this is not the first frame in within the bounds of an
-    # action.
-    prev_timestamp = ref_stats.frame_timestamps[-1][-1]
-    ref_stats.frame_times[-1].append(cur_timestamp - prev_timestamp)
-  ref_stats.frame_timestamps[-1].append(cur_timestamp)
-
-
-def AddDisplayRenderingStats(mock_timer, thread, first_frame,
-                             ref_stats=None):
-  """ Adds a random display rendering stats event.
-
-  thread: The timeline model thread to which the event will be added.
-  first_frame: Is this the first frame within the bounds of an action?
-  ref_stats: A ReferenceRenderingStats object to record expected values.
-  """
-  # Create random data and timestamp for main thread rendering stats.
-  data = {'frame_count': 1}
-  timestamp = mock_timer.AdvanceAndGet()
-
-  # Add a slice with the event data to the given thread.
-  thread.PushCompleteSlice(
-      'benchmark', 'BenchmarkInstrumentation::DisplayRenderingStats',
-      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
-      args={'data': data})
-
-  if not ref_stats:
-    return
-
-  # Add timestamp only if a frame was output
-  if not first_frame:
-    # Add frame_time if this is not the first frame in within the bounds of an
-    # action.
-    prev_timestamp = ref_stats.frame_timestamps[-1][-1]
-    ref_stats.frame_times[-1].append(timestamp - prev_timestamp)
-  ref_stats.frame_timestamps[-1].append(timestamp)
-
-
-def AddImplThreadRenderingStats(mock_timer, thread, first_frame,
-                                ref_stats=None):
-  """ Adds a random impl thread rendering stats event.
-
-  thread: The timeline model thread to which the event will be added.
-  first_frame: Is this the first frame within the bounds of an action?
-  ref_stats: A ReferenceRenderingStats object to record expected values.
-  """
-  # Create random data and timestamp for impl thread rendering stats.
-  data = {'frame_count': 1,
-          'visible_content_area': random.uniform(0, 100),
-          'approximated_visible_content_area': random.uniform(0, 5),
-          'checkerboarded_visible_content_area': random.uniform(0, 5)}
-  timestamp = mock_timer.AdvanceAndGet()
-
-  # Add a slice with the event data to the given thread.
-  thread.PushCompleteSlice(
-      'benchmark', 'BenchmarkInstrumentation::ImplThreadRenderingStats',
-      timestamp, duration=0.0, thread_timestamp=None, thread_duration=None,
-      args={'data': data})
-
-  if not ref_stats:
-    return
-
-  # Add timestamp only if a frame was output
-  if data['frame_count'] == 1:
-    if not first_frame:
-      # Add frame_time if this is not the first frame in within the bounds of an
-      # action.
-      prev_timestamp = ref_stats.frame_timestamps[-1][-1]
-      ref_stats.frame_times[-1].append(timestamp - prev_timestamp)
-    ref_stats.frame_timestamps[-1].append(timestamp)
-
-  ref_stats.approximated_pixel_percentages[-1].append(
-      round(statistics.DivideIfPossibleOrZero(
-          data['approximated_visible_content_area'],
-          data['visible_content_area']) * 100.0, 3))
-
-  ref_stats.checkerboarded_pixel_percentages[-1].append(
-      round(statistics.DivideIfPossibleOrZero(
-          data['checkerboarded_visible_content_area'],
-          data['visible_content_area']) * 100.0, 3))
-
-def AddInputLatencyStats(mock_timer, start_thread, end_thread,
-                         ref_latency_stats=None):
-  """ Adds a random input latency stats event.
-
-  start_thread: The start thread on which the async slice is added.
-  end_thread: The end thread on which the async slice is ended.
-  ref_latency_stats: A ReferenceInputLatencyStats object for expected values.
-  """
-
-  original_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
-  ui_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
-  begin_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
-  forward_comp_time = mock_timer.AdvanceAndGet(2, 4) * 1000.0
-  end_comp_time = mock_timer.AdvanceAndGet(10, 20) * 1000.0
-
-  data = {rendering_stats.ORIGINAL_COMP_NAME: {'time': original_comp_time},
-          rendering_stats.UI_COMP_NAME: {'time': ui_comp_time},
-          rendering_stats.BEGIN_COMP_NAME: {'time': begin_comp_time},
-          rendering_stats.END_COMP_NAME: {'time': end_comp_time}}
-
-  timestamp = mock_timer.AdvanceAndGet(2, 4)
-
-  tracing_async_slice = async_slice.AsyncSlice(
-      'benchmark', 'InputLatency', timestamp)
-
-  async_sub_slice = async_slice.AsyncSlice(
-      'benchmark', rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME, timestamp)
-  async_sub_slice.args = {'data': data}
-  async_sub_slice.parent_slice = tracing_async_slice
-  async_sub_slice.start_thread = start_thread
-  async_sub_slice.end_thread = end_thread
-
-  tracing_async_slice.sub_slices.append(async_sub_slice)
-  tracing_async_slice.start_thread = start_thread
-  tracing_async_slice.end_thread = end_thread
-  start_thread.AddAsyncSlice(tracing_async_slice)
-
-  # Add scroll update latency info.
-  scroll_update_data = {
-      rendering_stats.BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time},
-      rendering_stats.FORWARD_SCROLL_UPDATE_COMP_NAME:
-          {'time': forward_comp_time},
-      rendering_stats.END_COMP_NAME: {'time': end_comp_time}
-  }
-
-  scroll_async_slice = async_slice.AsyncSlice(
-      'benchmark', 'InputLatency', timestamp)
-
-  scroll_async_sub_slice = async_slice.AsyncSlice(
-      'benchmark', rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME,
-      timestamp)
-  scroll_async_sub_slice.args = {'data': scroll_update_data}
-  scroll_async_sub_slice.parent_slice = scroll_async_slice
-  scroll_async_sub_slice.start_thread = start_thread
-  scroll_async_sub_slice.end_thread = end_thread
-
-  scroll_async_slice.sub_slices.append(scroll_async_sub_slice)
-  scroll_async_slice.start_thread = start_thread
-  scroll_async_slice.end_thread = end_thread
-  start_thread.AddAsyncSlice(scroll_async_slice)
-
-  # Also add some dummy frame statistics so we can feed the resulting timeline
-  # to RenderingStats.
-  AddImplThreadRenderingStats(mock_timer, end_thread, False)
-
-  if not ref_latency_stats:
-    return
-
-  ref_latency_stats.input_event.append(async_sub_slice)
-  ref_latency_stats.input_event.append(scroll_async_sub_slice)
-  ref_latency_stats.input_event_latency.append((
-      rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME,
-      (data[rendering_stats.END_COMP_NAME]['time'] -
-       data[rendering_stats.ORIGINAL_COMP_NAME]['time']) / 1000.0))
-  scroll_update_time = (
-      scroll_update_data[rendering_stats.END_COMP_NAME]['time'] -
-      scroll_update_data[rendering_stats.BEGIN_SCROLL_UPDATE_COMP_NAME]['time'])
-  ref_latency_stats.input_event_latency.append((
-      rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME,
-      scroll_update_time / 1000.0))
-
-
-class RenderingStatsUnitTest(unittest.TestCase):
-
-  def testHasRenderingStats(self):
-    timeline = model.TimelineModel()
-    timer = MockTimer()
-
-    # A process without rendering stats
-    process_without_stats = timeline.GetOrCreateProcess(pid=1)
-    thread_without_stats = process_without_stats.GetOrCreateThread(tid=11)
-    process_without_stats.FinalizeImport()
-    self.assertFalse(rendering_stats.HasRenderingStats(thread_without_stats))
-
-    # A process with rendering stats, but no frames in them
-    process_without_frames = timeline.GetOrCreateProcess(pid=2)
-    thread_without_frames = process_without_frames.GetOrCreateThread(tid=21)
-    process_without_frames.FinalizeImport()
-    self.assertFalse(rendering_stats.HasRenderingStats(thread_without_frames))
-
-    # A process with rendering stats and frames in them
-    process_with_frames = timeline.GetOrCreateProcess(pid=3)
-    thread_with_frames = process_with_frames.GetOrCreateThread(tid=31)
-    AddImplThreadRenderingStats(timer, thread_with_frames, True, None)
-    process_with_frames.FinalizeImport()
-    self.assertTrue(rendering_stats.HasRenderingStats(thread_with_frames))
-
-  def testHasDrmStats(self):
-    timeline = model.TimelineModel()
-    timer = MockTimer()
-    vblank_timer = MockVblankTimer()
-
-    # A process without drm stats
-    process_without_stats = timeline.GetOrCreateProcess(pid=5)
-    thread_without_stats = process_without_stats.GetOrCreateThread(tid=51)
-    process_without_stats.FinalizeImport()
-    self.assertFalse(rendering_stats.HasDrmStats(thread_without_stats))
-
-    # A process with drm stats and frames in them
-    process_with_frames = timeline.GetOrCreateProcess(pid=6)
-    thread_with_frames = process_with_frames.GetOrCreateThread(tid=61)
-    AddDrmEventFlipStats(timer, vblank_timer, thread_with_frames, True, None)
-    process_with_frames.FinalizeImport()
-    self.assertTrue(rendering_stats.HasDrmStats(thread_with_frames))
-
-  def testBothSurfaceFlingerAndDisplayStats(self):
-    timeline = model.TimelineModel()
-    timer = MockTimer()
-
-    ref_stats = ReferenceRenderingStats()
-    ref_stats.AppendNewRange()
-    surface_flinger = timeline.GetOrCreateProcess(pid=4)
-    surface_flinger.name = 'SurfaceFlinger'
-    surface_flinger_thread = surface_flinger.GetOrCreateThread(tid=41)
-    renderer = timeline.GetOrCreateProcess(pid=2)
-    browser = timeline.GetOrCreateProcess(pid=3)
-    browser_main = browser.GetOrCreateThread(tid=31)
-    browser_main.BeginSlice('webkit.console', 'ActionA',
-                            timer.AdvanceAndGet(2, 4), '')
-
-    # Create SurfaceFlinger stats and display rendering stats.
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddSurfaceFlingerStats(timer, surface_flinger_thread, first, ref_stats)
-      timer.Advance(2, 4)
-
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddDisplayRenderingStats(timer, browser_main, first, None)
-      timer.Advance(5, 10)
-
-    browser_main.EndSlice(timer.AdvanceAndGet())
-    timer.Advance(2, 4)
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-    timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
-    timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
-                       for marker in timeline_markers]
-    stats = rendering_stats.RenderingStats(
-        renderer, browser, surface_flinger, None, timeline_ranges)
-
-    # Compare rendering stats to reference - Only SurfaceFlinger stats should
-    # count
-    self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
-    self.assertEquals(stats.frame_times, ref_stats.frame_times)
-
-  def testBothDrmAndDisplayStats(self):
-    timeline = model.TimelineModel()
-    timer = MockTimer()
-    vblank_timer = MockVblankTimer()
-
-    ref_stats = ReferenceRenderingStats()
-    ref_stats.AppendNewRange()
-    gpu = timeline.GetOrCreateProcess(pid=6)
-    gpu.name = 'GPU Process'
-    gpu_drm_thread = gpu.GetOrCreateThread(tid=61)
-    renderer = timeline.GetOrCreateProcess(pid=2)
-    browser = timeline.GetOrCreateProcess(pid=3)
-    browser_main = browser.GetOrCreateThread(tid=31)
-    browser_main.BeginSlice('webkit.console', 'ActionA',
-                            timer.AdvanceAndGet(2, 4), '')
-    vblank_timer.TvAdvance(2000, 4000)
-
-    # Create drm flip stats and display rendering stats.
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddDrmEventFlipStats(timer, vblank_timer, gpu_drm_thread,
-                           first, ref_stats)
-      timer.Advance(2, 4)
-      vblank_timer.TvAdvance(2000, 4000)
-
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddDisplayRenderingStats(timer, browser_main, first, None)
-      timer.Advance(5, 10)
-      vblank_timer.TvAdvance(5000, 10000)
-
-    browser_main.EndSlice(timer.AdvanceAndGet())
-    timer.Advance(2, 4)
-    vblank_timer.TvAdvance(2000, 4000)
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-    timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
-    timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
-                       for marker in timeline_markers]
-    stats = rendering_stats.RenderingStats(
-        renderer, browser, None, gpu, timeline_ranges)
-
-    # Compare rendering stats to reference - Only drm flip stats should
-    # count
-    self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
-    self.assertEquals(stats.frame_times, ref_stats.frame_times)
-
-  def testBothDisplayAndImplStats(self):
-    timeline = model.TimelineModel()
-    timer = MockTimer()
-
-    ref_stats = ReferenceRenderingStats()
-    ref_stats.AppendNewRange()
-    renderer = timeline.GetOrCreateProcess(pid=2)
-    browser = timeline.GetOrCreateProcess(pid=3)
-    browser_main = browser.GetOrCreateThread(tid=31)
-    browser_main.BeginSlice('webkit.console', 'ActionA',
-                            timer.AdvanceAndGet(2, 4), '')
-
-    # Create main, impl, and display rendering stats.
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddImplThreadRenderingStats(timer, browser_main, first, None)
-      timer.Advance(2, 4)
-
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddDisplayRenderingStats(timer, browser_main, first, ref_stats)
-      timer.Advance(5, 10)
-
-    browser_main.EndSlice(timer.AdvanceAndGet())
-    timer.Advance(2, 4)
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-    timeline_markers = timeline.FindTimelineMarkers(['ActionA'])
-    timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
-                       for marker in timeline_markers]
-    stats = rendering_stats.RenderingStats(
-        renderer, browser, None, None, timeline_ranges)
-
-    # Compare rendering stats to reference - Only display stats should count
-    self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps)
-    self.assertEquals(stats.frame_times, ref_stats.frame_times)
-
-  def testRangeWithoutFrames(self):
-    timer = MockTimer()
-    timeline = model.TimelineModel()
-
-    # Create a renderer process, with a main thread and impl thread.
-    renderer = timeline.GetOrCreateProcess(pid=2)
-    renderer_main = renderer.GetOrCreateThread(tid=21)
-    renderer_compositor = renderer.GetOrCreateThread(tid=22)
-
-    # Create 10 main and impl rendering stats events for Action A.
-    renderer_main.BeginSlice('webkit.console', 'ActionA',
-                             timer.AdvanceAndGet(2, 4), '')
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-    timer.Advance(2, 4)
-
-    # Create 5 main and impl rendering stats events not within any action.
-    for i in xrange(0, 5):
-      first = (i == 0)
-      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-
-    # Create Action B without any frames. This should trigger
-    # NotEnoughFramesError when the RenderingStats object is created.
-    renderer_main.BeginSlice('webkit.console', 'ActionB',
-                             timer.AdvanceAndGet(2, 4), '')
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
-    renderer.FinalizeImport()
-
-    timeline_markers = timeline.FindTimelineMarkers(['ActionA', 'ActionB'])
-    timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
-                       for marker in timeline_markers]
-
-    stats = rendering_stats.RenderingStats(
-        renderer, None, None, None, timeline_ranges)
-    self.assertEquals(0, len(stats.frame_timestamps[1]))
-
-  def testFromTimeline(self):
-    timeline = model.TimelineModel()
-
-    # Create a browser process and a renderer process, and a main thread and
-    # impl thread for each.
-    browser = timeline.GetOrCreateProcess(pid=1)
-    browser_compositor = browser.GetOrCreateThread(tid=12)
-    renderer = timeline.GetOrCreateProcess(pid=2)
-    renderer_main = renderer.GetOrCreateThread(tid=21)
-    renderer_compositor = renderer.GetOrCreateThread(tid=22)
-
-    timer = MockTimer()
-    renderer_ref_stats = ReferenceRenderingStats()
-    browser_ref_stats = ReferenceRenderingStats()
-
-    # Create 10 main and impl rendering stats events for Action A.
-    renderer_main.BeginSlice('webkit.console', 'ActionA',
-                             timer.AdvanceAndGet(2, 4), '')
-    renderer_ref_stats.AppendNewRange()
-    browser_ref_stats.AppendNewRange()
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddImplThreadRenderingStats(
-          timer, renderer_compositor, first, renderer_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, browser_compositor, first, browser_ref_stats)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
-    # Create 5 main and impl rendering stats events not within any action.
-    for i in xrange(0, 5):
-      first = (i == 0)
-      AddImplThreadRenderingStats(timer, renderer_compositor, first, None)
-      AddImplThreadRenderingStats(timer, browser_compositor, first, None)
-
-    # Create 10 main and impl rendering stats events for Action B.
-    renderer_main.BeginSlice('webkit.console', 'ActionB',
-                             timer.AdvanceAndGet(2, 4), '')
-    renderer_ref_stats.AppendNewRange()
-    browser_ref_stats.AppendNewRange()
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddImplThreadRenderingStats(
-          timer, renderer_compositor, first, renderer_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, browser_compositor, first, browser_ref_stats)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
-    # Create 10 main and impl rendering stats events for Action A.
-    renderer_main.BeginSlice('webkit.console', 'ActionA',
-                             timer.AdvanceAndGet(2, 4), '')
-    renderer_ref_stats.AppendNewRange()
-    browser_ref_stats.AppendNewRange()
-    for i in xrange(0, 10):
-      first = (i == 0)
-      AddImplThreadRenderingStats(
-          timer, renderer_compositor, first, renderer_ref_stats)
-      AddImplThreadRenderingStats(
-          timer, browser_compositor, first, browser_ref_stats)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-    timer.Advance(2, 4)
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-
-    timeline_markers = timeline.FindTimelineMarkers(
-        ['ActionA', 'ActionB', 'ActionA'])
-    timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
-                       for marker in timeline_markers]
-    stats = rendering_stats.RenderingStats(
-        renderer, browser, None, None, timeline_ranges)
-
-    # Compare rendering stats to reference.
-    self.assertEquals(stats.frame_timestamps,
-                      browser_ref_stats.frame_timestamps)
-    self.assertEquals(stats.frame_times, browser_ref_stats.frame_times)
-    self.assertEquals(stats.approximated_pixel_percentages,
-                      renderer_ref_stats.approximated_pixel_percentages)
-    self.assertEquals(stats.checkerboarded_pixel_percentages,
-                      renderer_ref_stats.checkerboarded_pixel_percentages)
-
-  def testInputLatencyFromTimeline(self):
-    timeline = model.TimelineModel()
-
-    # Create a browser process and a renderer process.
-    browser = timeline.GetOrCreateProcess(pid=1)
-    browser_main = browser.GetOrCreateThread(tid=11)
-    renderer = timeline.GetOrCreateProcess(pid=2)
-    renderer_main = renderer.GetOrCreateThread(tid=21)
-
-    timer = MockTimer()
-    ref_latency = ReferenceInputLatencyStats()
-
-    # Create 10 input latency stats events for Action A.
-    renderer_main.BeginSlice('webkit.console', 'ActionA',
-                             timer.AdvanceAndGet(2, 4), '')
-    for _ in xrange(0, 10):
-      AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
-    # Create 5 input latency stats events not within any action.
-    timer.Advance(2, 4)
-    for _ in xrange(0, 5):
-      AddInputLatencyStats(timer, browser_main, renderer_main, None)
-
-    # Create 10 input latency stats events for Action B.
-    renderer_main.BeginSlice('webkit.console', 'ActionB',
-                             timer.AdvanceAndGet(2, 4), '')
-    for _ in xrange(0, 10):
-      AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
-    # Create 10 input latency stats events for Action A.
-    renderer_main.BeginSlice('webkit.console', 'ActionA',
-                             timer.AdvanceAndGet(2, 4), '')
-    for _ in xrange(0, 10):
-      AddInputLatencyStats(timer, browser_main, renderer_main, ref_latency)
-    renderer_main.EndSlice(timer.AdvanceAndGet(2, 4))
-
-    browser.FinalizeImport()
-    renderer.FinalizeImport()
-
-    latency_events = []
-
-    timeline_markers = timeline.FindTimelineMarkers(
-        ['ActionA', 'ActionB', 'ActionA'])
-    timeline_ranges = [bounds.Bounds.CreateFromEvent(marker)
-                       for marker in timeline_markers]
-    for timeline_range in timeline_ranges:
-      if timeline_range.is_empty:
-        continue
-      latency_events.extend(rendering_stats.GetLatencyEvents(
-          browser, timeline_range))
-
-    self.assertEquals(latency_events, ref_latency.input_event)
-    event_latency_result = rendering_stats.ComputeEventLatencies(latency_events)
-    self.assertEquals(event_latency_result,
-                      ref_latency.input_event_latency)
-
-    stats = rendering_stats.RenderingStats(
-        renderer, browser, None, None, timeline_ranges)
-    self.assertEquals(
-        perf_tests_helper.FlattenList(stats.input_event_latency),
-        [latency for name, latency in ref_latency.input_event_latency
-         if name != rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME])
-    self.assertEquals(
-        perf_tests_helper.FlattenList(stats.main_thread_scroll_latency),
-        [latency for name, latency in ref_latency.input_event_latency
-         if name == rendering_stats.MAIN_THREAD_SCROLL_UPDATE_EVENT_NAME])
-    self.assertEquals(
-        perf_tests_helper.FlattenList(stats.gesture_scroll_update_latency),
-        [latency for name, latency in ref_latency.input_event_latency
-         if name == rendering_stats.GESTURE_SCROLL_UPDATE_EVENT_NAME])
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/single_event.py b/catapult/telemetry/telemetry/web_perf/metrics/single_event.py
deleted file mode 100644
index 5d510c3..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/single_event.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.web_perf.metrics import timeline_based_metric
-
-
-class _SingleEventMetric(timeline_based_metric.TimelineBasedMetric):
-  """Reports directly durations of specific trace events that start during the
-  user interaction.
-  """
-
-  def __init__(self, trace_event_name, metric_name, metric_description=None):
-    super(_SingleEventMetric, self).__init__()
-    self._TRACE_EVENT_NAME = trace_event_name
-    self._metric_name = metric_name
-    self._metric_description = metric_description
-
-  def AddResults(self, model, renderer_thread, interactions, results):
-    del model  # unused
-    assert interactions
-    self._AddResultsInternal(renderer_thread.parent.IterAllSlices(),
-                             interactions, results)
-
-  def _AddResultsInternal(self, events, interactions, results):
-    events_found = []
-    for event in events:
-      if (event.name == self._TRACE_EVENT_NAME) and any(
-              interaction.start <= event.start <= interaction.end
-              for interaction in interactions):
-        if event.has_thread_timestamps:
-          events_found.append(event.thread_duration)
-        else:
-          events_found.append(event.duration)
-    if not events_found:
-      return
-    results.AddValue(list_of_scalar_values.ListOfScalarValues(
-      page=results.current_page,
-      tir_label=interactions[0].label,
-      name=self._metric_name,
-      units='ms',
-      values=events_found,
-      description=self._metric_description,
-      improvement_direction=improvement_direction.DOWN))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/single_event_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/single_event_unittest.py
deleted file mode 100644
index f96ef9f..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/single_event_unittest.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from collections import namedtuple
-from telemetry.internal.results import page_test_results
-from telemetry.page import page
-from telemetry.web_perf.metrics import single_event
-from telemetry.web_perf import timeline_interaction_record
-
-TRACE_EVENT_NAME = 'FrameView::performLayout'
-METRIC_NAME = 'layout'
-FakeEventTuple = namedtuple(
-    'Event',
-    'start, end, name, duration, thread_duration, has_thread_timestamps')
-Interaction = timeline_interaction_record.TimelineInteractionRecord
-
-class SingleEventTestMetric(single_event._SingleEventMetric):
-  def __init__(self):
-    super(SingleEventTestMetric, self).__init__(TRACE_EVENT_NAME, METRIC_NAME)
-
-def GetSingleEventMetrics(events, interactions):
-  results = page_test_results.PageTestResults()
-  results.WillRunPage(page.Page('file://blank.html'))
-  SingleEventTestMetric()._AddResultsInternal(events, interactions, results)
-  return dict((value.name, value.values) for value in
-              results.current_page_run.values)
-
-def FakeEvent(start, end, name=TRACE_EVENT_NAME):
-  dur = end - start
-  return FakeEventTuple(start, end, name, dur, dur, True)
-
-
-class SingleEventMetricUnitTest(unittest.TestCase):
-  def testSingleEventMetric(self):
-    events = [FakeEvent(0, 1),
-              FakeEvent(9, 11),
-              FakeEventTuple(10, 13, TRACE_EVENT_NAME, 3, 0, False),
-              FakeEvent(20, 24),
-              FakeEvent(21, 26),
-              FakeEvent(29, 35),
-              FakeEvent(30, 37),
-              FakeEvent(40, 48),
-              FakeEvent(41, 50),
-              FakeEvent(10, 13, name='something'),
-              FakeEvent(20, 24, name='FrameView::something'),
-              FakeEvent(30, 37, name='SomeThing::performLayout'),
-              FakeEvent(40, 48, name='something else')]
-    interactions = [Interaction('interaction', 10, 20),
-                    Interaction('interaction', 30, 40)]
-
-    self.assertFalse(GetSingleEventMetrics(events, []))
-    self.assertFalse(GetSingleEventMetrics([], interactions))
-
-    # The first event starts before the first interaction, so it is ignored.
-    # The second event starts before the first interaction, so it is ignored.
-    # The third event starts during the first interaction, and its duration is
-    # 13 - 10 = 3.
-    # The fourth event starts during the first interaction, and its duration is
-    # 24 - 20 = 4.
-    # The fifth event starts between the two interactions, so it is ignored.
-    # The sixth event starts between the two interactions, so it is ignored.
-    # The seventh event starts during the second interaction, and its duration
-    # is 37 - 30 = 7.
-    # The eighth event starts during the second interaction, and its duration is
-    # 48 - 40 = 8.
-    # The ninth event starts after the last interaction, so it is ignored.
-    # The rest of the events have the wrong name, so they are ignored.
-    self.assertEqual({METRIC_NAME: [3, 4, 7, 8]}, GetSingleEventMetrics(
-        events, interactions))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/smoothness.py b/catapult/telemetry/telemetry/web_perf/metrics/smoothness.py
deleted file mode 100644
index 5caa568..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/smoothness.py
+++ /dev/null
@@ -1,349 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.util import perf_tests_helper
-from telemetry.util import statistics
-from telemetry.value import improvement_direction
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-from telemetry.web_perf.metrics import rendering_stats
-from telemetry.web_perf.metrics import timeline_based_metric
-
-
-NOT_ENOUGH_FRAMES_MESSAGE = (
-  'Not enough frames for smoothness metrics (at least two are required).\n'
-  'Issues that have caused this in the past:\n'
-  '- Browser bugs that prevents the page from redrawing\n'
-  '- Bugs in the synthetic gesture code\n'
-  '- Page and benchmark out of sync (e.g. clicked element was renamed)\n'
-  '- Pages that render extremely slow\n'
-  '- Pages that can\'t be scrolled')
-
-
-class SmoothnessMetric(timeline_based_metric.TimelineBasedMetric):
-  """Computes metrics that measure smoothness of animations over given ranges.
-
-  Animations are typically considered smooth if the frame rates are close to
-  60 frames per second (fps) and uniformly distributed over the sequence. To
-  determine if a timeline range contains a smooth animation, we update the
-  results object with several representative metrics:
-
-    frame_times: A list of raw frame times
-    mean_frame_time: The arithmetic mean of frame times
-    percentage_smooth: Percentage of frames that were hitting 60 FPS.
-    frame_time_discrepancy: The absolute discrepancy of frame timestamps
-    mean_pixels_approximated: The mean percentage of pixels approximated
-    queueing_durations: The queueing delay between compositor & main threads
-
-  Note that if any of the interaction records provided to AddResults have less
-  than 2 frames, we will return telemetry values with None values for each of
-  the smoothness metrics. Similarly, older browsers without support for
-  tracking the BeginMainFrame events will report a ListOfScalarValues with a
-  None value for the queueing duration metric.
-  """
-
-  def __init__(self):
-    super(SmoothnessMetric, self).__init__()
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    self.VerifyNonOverlappedRecords(interaction_records)
-    renderer_process = renderer_thread.parent
-    stats = rendering_stats.RenderingStats(
-      renderer_process, model.browser_process, model.surface_flinger_process,
-      model.gpu_process, [r.GetBounds() for r in interaction_records])
-    has_surface_flinger_stats = model.surface_flinger_process is not None
-    self._PopulateResultsFromStats(results, stats, has_surface_flinger_stats)
-
-  def _PopulateResultsFromStats(self, results, stats,
-                                has_surface_flinger_stats):
-    page = results.current_page
-    values = [
-        self._ComputeQueueingDuration(page, stats),
-        self._ComputeFrameTimeDiscrepancy(page, stats),
-        self._ComputeMeanPixelsApproximated(page, stats),
-        self._ComputeMeanPixelsCheckerboarded(page, stats)
-    ]
-    values += self._ComputeLatencyMetric(page, stats, 'input_event_latency',
-                                         stats.input_event_latency)
-    values += self._ComputeLatencyMetric(page, stats,
-                                         'main_thread_scroll_latency',
-                                         stats.main_thread_scroll_latency)
-    values.append(self._ComputeFirstGestureScrollUpdateLatencies(page, stats))
-    values += self._ComputeFrameTimeMetric(page, stats)
-    if has_surface_flinger_stats:
-      values += self._ComputeSurfaceFlingerMetric(page, stats)
-
-    for v in values:
-      results.AddValue(v)
-
-  def _HasEnoughFrames(self, list_of_frame_timestamp_lists):
-    """Whether we have collected at least two frames in every timestamp list."""
-    return all(len(s) >= 2 for s in list_of_frame_timestamp_lists)
-
-  @staticmethod
-  def _GetNormalizedDeltas(data, refresh_period, min_normalized_delta=None):
-    deltas = [t2 - t1 for t1, t2 in zip(data, data[1:])]
-    if min_normalized_delta != None:
-      deltas = [d for d in deltas
-                if d / refresh_period >= min_normalized_delta]
-    return (deltas, [delta / refresh_period for delta in deltas])
-
-  @staticmethod
-  def _JoinTimestampRanges(frame_timestamps):
-    """Joins ranges of timestamps, adjusting timestamps to remove deltas
-    between the start of a range and the end of the prior range.
-    """
-    timestamps = []
-    for timestamp_range in frame_timestamps:
-      if len(timestamps) == 0:
-        timestamps.extend(timestamp_range)
-      else:
-        for i in range(1, len(timestamp_range)):
-          timestamps.append(timestamps[-1] +
-              timestamp_range[i] - timestamp_range[i-1])
-    return timestamps
-
-  def _ComputeSurfaceFlingerMetric(self, page, stats):
-    jank_count = None
-    avg_surface_fps = None
-    max_frame_delay = None
-    frame_lengths = None
-    none_value_reason = None
-    if self._HasEnoughFrames(stats.frame_timestamps):
-      timestamps = self._JoinTimestampRanges(stats.frame_timestamps)
-      frame_count = len(timestamps)
-      milliseconds = timestamps[-1] - timestamps[0]
-      min_normalized_frame_length = 0.5
-
-      frame_lengths, normalized_frame_lengths = \
-          self._GetNormalizedDeltas(timestamps, stats.refresh_period,
-                                    min_normalized_frame_length)
-      if len(frame_lengths) < frame_count - 1:
-        logging.warning('Skipping frame lengths that are too short.')
-        frame_count = len(frame_lengths) + 1
-      if len(frame_lengths) == 0:
-        raise Exception('No valid frames lengths found.')
-      _, normalized_changes = \
-          self._GetNormalizedDeltas(frame_lengths, stats.refresh_period)
-      jankiness = [max(0, round(change)) for change in normalized_changes]
-      pause_threshold = 20
-      jank_count = sum(1 for change in jankiness
-                       if change > 0 and change < pause_threshold)
-      avg_surface_fps = int(round((frame_count - 1) * 1000.0 / milliseconds))
-      max_frame_delay = round(max(normalized_frame_lengths))
-      frame_lengths = normalized_frame_lengths
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-
-    return (
-        scalar.ScalarValue(
-            page, 'avg_surface_fps', 'fps', avg_surface_fps,
-            description='Average frames per second as measured by the '
-                        'platform\'s SurfaceFlinger.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.UP),
-        scalar.ScalarValue(
-            page, 'jank_count', 'janks', jank_count,
-            description='Number of changes in frame rate as measured by the '
-                        'platform\'s SurfaceFlinger.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.DOWN),
-        scalar.ScalarValue(
-            page, 'max_frame_delay', 'vsyncs', max_frame_delay,
-            description='Largest frame time as measured by the platform\'s '
-                        'SurfaceFlinger.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.DOWN),
-        list_of_scalar_values.ListOfScalarValues(
-            page, 'frame_lengths', 'vsyncs', frame_lengths,
-            description='Frame time in vsyncs as measured by the platform\'s '
-                        'SurfaceFlinger.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.DOWN)
-    )
-
-  def _ComputeLatencyMetric(self, page, stats, name, list_of_latency_lists):
-    """Returns Values for the mean and discrepancy for given latency stats."""
-    mean_latency = None
-    latency_discrepancy = None
-    none_value_reason = None
-    if self._HasEnoughFrames(stats.frame_timestamps):
-      latency_list = perf_tests_helper.FlattenList(list_of_latency_lists)
-      if len(latency_list) == 0:
-        return ()
-      mean_latency = round(statistics.ArithmeticMean(latency_list), 3)
-      latency_discrepancy = (
-          round(statistics.DurationsDiscrepancy(latency_list), 4))
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return (
-      scalar.ScalarValue(
-          page, 'mean_%s' % name, 'ms', mean_latency,
-          description='Arithmetic mean of the raw %s values' % name,
-          none_value_reason=none_value_reason,
-          improvement_direction=improvement_direction.DOWN),
-      scalar.ScalarValue(
-          page, '%s_discrepancy' % name, 'ms', latency_discrepancy,
-          description='Discrepancy of the raw %s values' % name,
-          none_value_reason=none_value_reason,
-          improvement_direction=improvement_direction.DOWN)
-    )
-
-  def _ComputeFirstGestureScrollUpdateLatencies(self, page, stats):
-    """Returns a ListOfScalarValuesValues of gesture scroll update latencies.
-
-    Returns a Value for the first gesture scroll update latency for each
-    interaction record in |stats|.
-    """
-    none_value_reason = None
-    first_gesture_scroll_update_latencies = [round(latencies[0], 4)
-        for latencies in stats.gesture_scroll_update_latency
-        if len(latencies)]
-    if (not self._HasEnoughFrames(stats.frame_timestamps) or
-        not first_gesture_scroll_update_latencies):
-      first_gesture_scroll_update_latencies = None
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return list_of_scalar_values.ListOfScalarValues(
-        page, 'first_gesture_scroll_update_latency', 'ms',
-        first_gesture_scroll_update_latencies,
-        description='First gesture scroll update latency measures the time it '
-                    'takes to process the very first gesture scroll update '
-                    'input event. The first scroll gesture can often get '
-                    'delayed by work related to page loading.',
-        none_value_reason=none_value_reason,
-        improvement_direction=improvement_direction.DOWN)
-
-  def _ComputeQueueingDuration(self, page, stats):
-    """Returns a Value for the frame queueing durations."""
-    queueing_durations = None
-    none_value_reason = None
-    if 'frame_queueing_durations' in stats.errors:
-      none_value_reason = stats.errors['frame_queueing_durations']
-    elif self._HasEnoughFrames(stats.frame_timestamps):
-      queueing_durations = perf_tests_helper.FlattenList(
-          stats.frame_queueing_durations)
-      if len(queueing_durations) == 0:
-        queueing_durations = None
-        none_value_reason = 'No frame queueing durations recorded.'
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return list_of_scalar_values.ListOfScalarValues(
-        page, 'queueing_durations', 'ms', queueing_durations,
-        description='The frame queueing duration quantifies how out of sync '
-                    'the compositor and renderer threads are. It is the amount '
-                    'of wall time that elapses between a '
-                    'ScheduledActionSendBeginMainFrame event in the compositor '
-                    'thread and the corresponding BeginMainFrame event in the '
-                    'main thread.',
-        none_value_reason=none_value_reason,
-        improvement_direction=improvement_direction.DOWN)
-
-  def _ComputeFrameTimeMetric(self, page, stats):
-    """Returns Values for the frame time metrics.
-
-    This includes the raw and mean frame times, as well as the percentage of
-    frames that were hitting 60 fps.
-    """
-    frame_times = None
-    mean_frame_time = None
-    percentage_smooth = None
-    none_value_reason = None
-    if self._HasEnoughFrames(stats.frame_timestamps):
-      frame_times = perf_tests_helper.FlattenList(stats.frame_times)
-      mean_frame_time = round(statistics.ArithmeticMean(frame_times), 3)
-      # We use 17ms as a somewhat looser threshold, instead of 1000.0/60.0.
-      smooth_threshold = 17.0
-      smooth_count = sum(1 for t in frame_times if t < smooth_threshold)
-      percentage_smooth = float(smooth_count) / len(frame_times) * 100.0
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return (
-        list_of_scalar_values.ListOfScalarValues(
-            page, 'frame_times', 'ms', frame_times,
-            description='List of raw frame times, helpful to understand the '
-                        'other metrics.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.DOWN),
-        scalar.ScalarValue(
-            page, 'mean_frame_time', 'ms', mean_frame_time,
-            description='Arithmetic mean of frame times.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.DOWN),
-        scalar.ScalarValue(
-            page, 'percentage_smooth', 'score', percentage_smooth,
-            description='Percentage of frames that were hitting 60 fps.',
-            none_value_reason=none_value_reason,
-            improvement_direction=improvement_direction.UP)
-    )
-
-  def _ComputeFrameTimeDiscrepancy(self, page, stats):
-    """Returns a Value for the absolute discrepancy of frame time stamps."""
-
-    frame_discrepancy = None
-    none_value_reason = None
-    if self._HasEnoughFrames(stats.frame_timestamps):
-      frame_discrepancy = round(statistics.TimestampsDiscrepancy(
-          stats.frame_timestamps), 4)
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return scalar.ScalarValue(
-        page, 'frame_time_discrepancy', 'ms', frame_discrepancy,
-        description='Absolute discrepancy of frame time stamps, where '
-                    'discrepancy is a measure of irregularity. It quantifies '
-                    'the worst jank. For a single pause, discrepancy '
-                    'corresponds to the length of this pause in milliseconds. '
-                    'Consecutive pauses increase the discrepancy. This metric '
-                    'is important because even if the mean and 95th '
-                    'percentile are good, one long pause in the middle of an '
-                    'interaction is still bad.',
-        none_value_reason=none_value_reason,
-        improvement_direction=improvement_direction.DOWN)
-
-  def _ComputeMeanPixelsApproximated(self, page, stats):
-    """Add the mean percentage of pixels approximated.
-
-    This looks at tiles which are missing or of low or non-ideal resolution.
-    """
-    mean_pixels_approximated = None
-    none_value_reason = None
-    if self._HasEnoughFrames(stats.frame_timestamps):
-      mean_pixels_approximated = round(statistics.ArithmeticMean(
-          perf_tests_helper.FlattenList(
-              stats.approximated_pixel_percentages)), 3)
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return scalar.ScalarValue(
-        page, 'mean_pixels_approximated', 'percent', mean_pixels_approximated,
-        description='Percentage of pixels that were approximated '
-                    '(checkerboarding, low-resolution tiles, etc.).',
-        none_value_reason=none_value_reason,
-        improvement_direction=improvement_direction.DOWN)
-
-  def _ComputeMeanPixelsCheckerboarded(self, page, stats):
-    """Add the mean percentage of pixels checkerboarded.
-
-    This looks at tiles which are only missing.
-    It does not take into consideration tiles which are of low or
-    non-ideal resolution.
-    """
-    mean_pixels_checkerboarded = None
-    none_value_reason = None
-    if self._HasEnoughFrames(stats.frame_timestamps):
-      if rendering_stats.CHECKERBOARDED_PIXEL_ERROR in stats.errors:
-        none_value_reason = stats.errors[
-            rendering_stats.CHECKERBOARDED_PIXEL_ERROR]
-      else:
-        mean_pixels_checkerboarded = round(statistics.ArithmeticMean(
-            perf_tests_helper.FlattenList(
-                stats.checkerboarded_pixel_percentages)), 3)
-    else:
-      none_value_reason = NOT_ENOUGH_FRAMES_MESSAGE
-    return scalar.ScalarValue(
-        page, 'mean_pixels_checkerboarded', 'percent',
-        mean_pixels_checkerboarded,
-        description='Percentage of pixels that were checkerboarded.',
-        none_value_reason=none_value_reason,
-        improvement_direction=improvement_direction.DOWN)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/smoothness_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/smoothness_unittest.py
deleted file mode 100644
index efa5716..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/smoothness_unittest.py
+++ /dev/null
@@ -1,286 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.internal.results import page_test_results
-from telemetry.page import page as page_module
-from telemetry.web_perf.metrics import rendering_stats
-from telemetry.web_perf.metrics import smoothness
-
-
-class _MockRenderingStats(object):
-
-  stats = ['refresh_period', 'frame_timestamps', 'frame_times', 'paint_times',
-           'painted_pixel_counts', 'record_times',
-           'recorded_pixel_counts', 'approximated_pixel_percentages',
-           'checkerboarded_pixel_percentages', 'input_event_latency',
-           'frame_queueing_durations', 'main_thread_scroll_latency',
-           'gesture_scroll_update_latency']
-
-  def __init__(self, **kwargs):
-    self.input_event_latency = None  # to avoid pylint no-member error
-    self.errors = {}
-    for stat in self.stats:
-      value = kwargs[stat] if stat in kwargs else None
-      setattr(self, stat, value)
-
-
-#pylint: disable=protected-access
-class SmoothnessMetricUnitTest(unittest.TestCase):
-
-  def setUp(self):
-    self.metric = smoothness.SmoothnessMetric()
-    self.page = page_module.Page('file://blank.html')
-    self.good_timestamps = [[10, 20], [30, 40, 50]]
-    self.not_enough_frames_timestamps = [[10], [20, 30, 40]]
-
-  def testPopulateResultsFromStats(self):
-    stats = _MockRenderingStats()
-    for stat in _MockRenderingStats.stats:
-      # Just set fake data for all of the relevant arrays of stats typically
-      # found in a RenderingStats object.
-      setattr(stats, stat, [[10, 20], [30, 40, 50]])
-    results = page_test_results.PageTestResults()
-    results.WillRunPage(self.page)
-    self.metric._PopulateResultsFromStats(results, stats, False)
-    current_page_run = results.current_page_run
-    self.assertTrue(current_page_run.ok)
-    expected_values_count = 12
-    self.assertEquals(expected_values_count, len(current_page_run.values))
-
-  def testHasEnoughFrames(self):
-    # This list will pass since every sub-array has at least 2 frames.
-    has_enough_frames = self.metric._HasEnoughFrames(self.good_timestamps)
-    self.assertTrue(has_enough_frames)
-
-  def testHasEnoughFramesWithNotEnoughFrames(self):
-    # This list will fail since the first sub-array only has a single frame.
-    has_enough_frames = self.metric._HasEnoughFrames(
-        self.not_enough_frames_timestamps)
-    self.assertFalse(has_enough_frames)
-
-  def testComputeSurfaceFlingerMetricNoJank(self):
-    stats = _MockRenderingStats(refresh_period=10,
-                                frame_timestamps=[[10, 20], [130, 140, 150]],
-                                frame_times=[[10], [10, 10]])
-    avg_surface_fps, jank_count, max_frame_delay, frame_lengths = (
-        self.metric._ComputeSurfaceFlingerMetric(self.page, stats))
-    self.assertEquals([1, 1, 1], frame_lengths.values)
-    self.assertEquals(1, max_frame_delay.value)
-    self.assertEquals(0, jank_count.value)
-    self.assertEquals(100, avg_surface_fps.value)
-
-  def testComputeSurfaceFlingerMetricJank(self):
-    stats = _MockRenderingStats(
-        refresh_period=10,
-        frame_timestamps=[[10, 20, 50], [130, 140, 150, 170, 180]],
-        frame_times=[[10, 30], [10, 10, 20, 10]])
-    avg_surface_fps, jank_count, max_frame_delay, frame_lengths = (
-        self.metric._ComputeSurfaceFlingerMetric(self.page, stats))
-    self.assertEquals([1, 3, 1, 1, 2, 1], frame_lengths.values)
-    self.assertEquals(3, max_frame_delay.value)
-    self.assertEquals(2, jank_count.value)
-    self.assertEquals(67, avg_surface_fps.value)
-
-  def testComputeFrameTimeMetricWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        refresh_period=10,
-        frame_timestamps=self.not_enough_frames_timestamps,
-        frame_times=[[10, 20], [30, 40, 50]])
-    avg_surface_fps, jank_count, max_frame_delay, frame_lengths = (
-        self.metric._ComputeSurfaceFlingerMetric(self.page, stats))
-    self.assertEquals(None, avg_surface_fps.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      avg_surface_fps.none_value_reason)
-    self.assertEquals(None, jank_count.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      jank_count.none_value_reason)
-    self.assertEquals(None, max_frame_delay.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      max_frame_delay.none_value_reason)
-    self.assertEquals(None, frame_lengths.values)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      frame_lengths.none_value_reason)
-
-  def testComputeLatencyMetric(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
-                               input_event_latency=[[10, 20], [30, 40, 50]])
-    # pylint: disable=unbalanced-tuple-unpacking
-    mean_value, discrepancy_value = self.metric._ComputeLatencyMetric(
-        self.page, stats, 'input_event_latency', stats.input_event_latency)
-    self.assertEquals(30, mean_value.value)
-    self.assertEquals(60, discrepancy_value.value)
-
-  def testComputeLatencyMetricWithMissingData(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
-                               input_event_latency=[[], []])
-    value = self.metric._ComputeLatencyMetric(
-        self.page, stats, 'input_event_latency', stats.input_event_latency)
-    self.assertEquals((), value)
-
-  def testComputeLatencyMetricWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps,
-        input_event_latency=[[], []])
-    # pylint: disable=unbalanced-tuple-unpacking
-    mean_value, discrepancy_value = self.metric._ComputeLatencyMetric(
-        self.page, stats, 'input_event_latency', stats.input_event_latency)
-    self.assertEquals(None, mean_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      mean_value.none_value_reason)
-    self.assertEquals(None, discrepancy_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      discrepancy_value.none_value_reason)
-
-  def testComputeGestureScrollUpdateLatencies(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.good_timestamps,
-        gesture_scroll_update_latency=[[10, 20], [30, 40, 50]])
-    gesture_value = self.metric._ComputeFirstGestureScrollUpdateLatencies(
-        self.page, stats)
-    self.assertEquals([10, 30], gesture_value.values)
-
-  def testComputeGestureScrollUpdateLatenciesWithMissingData(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.good_timestamps,
-        gesture_scroll_update_latency=[[], []])
-    value = self.metric._ComputeFirstGestureScrollUpdateLatencies(
-        self.page, stats)
-    self.assertEquals(None, value.values)
-
-  def testComputeGestureScrollUpdateLatenciesWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps,
-        gesture_scroll_update_latency=[[10, 20], [30, 40, 50]])
-    gesture_value = self.metric._ComputeFirstGestureScrollUpdateLatencies(
-        self.page, stats)
-    self.assertEquals(None, gesture_value.values)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      gesture_value.none_value_reason)
-
-  def testComputeQueueingDuration(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
-                               frame_queueing_durations=[[10, 20], [30, 40]])
-    list_of_scalar_values = self.metric._ComputeQueueingDuration(self.page,
-                                                                stats)
-    self.assertEquals([10, 20, 30, 40], list_of_scalar_values.values)
-
-  def testComputeQueueingDurationWithMissingData(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
-                               frame_queueing_durations=[[], []])
-    list_of_scalar_values = self.metric._ComputeQueueingDuration(
-        self.page, stats)
-    self.assertEquals(None, list_of_scalar_values.values)
-    self.assertEquals('No frame queueing durations recorded.',
-                      list_of_scalar_values.none_value_reason)
-
-  def testComputeQueueingDurationWithMissingDataAndErrorValue(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
-                               frame_queueing_durations=[[], []])
-    stats.errors['frame_queueing_durations'] = (
-        'Current chrome version does not support the queueing delay metric.')
-    list_of_scalar_values = self.metric._ComputeQueueingDuration(
-        self.page, stats)
-    self.assertEquals(None, list_of_scalar_values.values)
-    self.assertEquals(
-        'Current chrome version does not support the queueing delay metric.',
-        list_of_scalar_values.none_value_reason)
-
-  def testComputeQueueingDurationWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps,
-        frame_queueing_durations=[[10, 20], [30, 40, 50]])
-    list_of_scalar_values = self.metric._ComputeQueueingDuration(self.page,
-                                                                stats)
-    self.assertEquals(None, list_of_scalar_values.values)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      list_of_scalar_values.none_value_reason)
-
-  def testComputeFrameTimeMetric(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps,
-                               frame_times=[[10, 20], [30, 40, 50]])
-    frame_times_value, mean_frame_time_value, percentage_smooth_value = (
-        self.metric._ComputeFrameTimeMetric(self.page, stats))
-    self.assertEquals([10, 20, 30, 40, 50], frame_times_value.values)
-    self.assertEquals(30, mean_frame_time_value.value)
-    self.assertEquals(20, percentage_smooth_value.value)
-
-  def testComputeFrameTimeMetricWithNotEnoughFrames2(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps,
-        frame_times=[[10, 20], [30, 40, 50]])
-    frame_times_value, mean_frame_time_value, percentage_smooth_value = (
-        self.metric._ComputeFrameTimeMetric(self.page, stats))
-    self.assertEquals(None, frame_times_value.values)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      frame_times_value.none_value_reason)
-    self.assertEquals(None, mean_frame_time_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      mean_frame_time_value.none_value_reason)
-    self.assertEquals(None, percentage_smooth_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      percentage_smooth_value.none_value_reason)
-
-  def testComputeFrameTimeDiscrepancy(self):
-    stats = _MockRenderingStats(frame_timestamps=self.good_timestamps)
-    frame_time_discrepancy_value = self.metric._ComputeFrameTimeDiscrepancy(
-        self.page, stats)
-    self.assertEquals(10, frame_time_discrepancy_value.value)
-
-  def testComputeFrameTimeDiscrepancyWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps)
-    frame_time_discrepancy_value = self.metric._ComputeFrameTimeDiscrepancy(
-        self.page, stats)
-    self.assertEquals(None, frame_time_discrepancy_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      frame_time_discrepancy_value.none_value_reason)
-
-  def testComputeMeanPixelsApproximated(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.good_timestamps,
-        approximated_pixel_percentages=[[10, 20], [30, 40, 50]])
-    mean_pixels_value = self.metric._ComputeMeanPixelsApproximated(
-        self.page, stats)
-    self.assertEquals(30, mean_pixels_value.value)
-
-  def testComputeMeanPixelsApproximatedWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps,
-        approximated_pixel_percentages=[[10, 20], [30, 40, 50]])
-    mean_pixels_value = self.metric._ComputeMeanPixelsApproximated(
-        self.page, stats)
-    self.assertEquals(None, mean_pixels_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      mean_pixels_value.none_value_reason)
-
-  def testComputeMeanPixelsCheckerboarded(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.good_timestamps,
-        checkerboarded_pixel_percentages=[[10, 20], [30, 40, 50]])
-    mean_pixels_value = self.metric._ComputeMeanPixelsCheckerboarded(
-        self.page, stats)
-    self.assertEquals(30, mean_pixels_value.value)
-
-  def testComputeMeanPixelsCheckerboardedWithNotEnoughFrames(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.not_enough_frames_timestamps,
-        checkerboarded_pixel_percentages=[[10, 20], [30, 40, 50]])
-    mean_pixels_value = self.metric._ComputeMeanPixelsCheckerboarded(
-        self.page, stats)
-    self.assertEquals(None, mean_pixels_value.value)
-    self.assertEquals(smoothness.NOT_ENOUGH_FRAMES_MESSAGE,
-                      mean_pixels_value.none_value_reason)
-
-  def testComputeMeanPixelsCheckerboardedWithNoData(self):
-    stats = _MockRenderingStats(
-        frame_timestamps=self.good_timestamps,
-        checkerboarded_pixel_percentages=None)
-    stats.errors[rendering_stats.CHECKERBOARDED_PIXEL_ERROR] = 'test error'
-    mean_pixels_value = self.metric._ComputeMeanPixelsCheckerboarded(
-        self.page, stats)
-    self.assertEquals(None, mean_pixels_value.value)
-    self.assertEquals('test error',
-                      mean_pixels_value.none_value_reason)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/startup.py b/catapult/telemetry/telemetry/web_perf/metrics/startup.py
deleted file mode 100644
index bac6b58..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/startup.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import value
-from telemetry.web_perf.metrics import timeline_based_metric
-
-_PROCESS_CREATION = 'Startup.BrowserProcessCreation'
-_MAIN_ENTRY_POINT = 'Startup.BrowserMainEntryPoint'
-
-# A dictionary that maps metric names to a value, which can be either of
-# the two:
-#  1. A tuple of one event name if the event itself contains reported duration
-#  2. A tuple of two event names if the value to report is the time difference
-#     between starting these events
-_METRICS = {
-  'messageloop_start_time':
-      ('Startup.BrowserMessageLoopStartTimeFromMainEntry2',),
-
-  'window_display_time':
-      ('Startup.BrowserWindowDisplay',),
-
-  'open_tabs_time':
-      ('Startup.BrowserOpenTabs',),
-
-  'first_non_empty_paint_time':
-      ('Startup.FirstWebContents.NonEmptyPaint2',),
-
-  'first_main_frame_load_time':
-      ('Startup.FirstWebContents.MainFrameLoad2',),
-
-  'foreground_tab_load_complete':
-      (_MAIN_ENTRY_POINT, 'loadEventEnd'),
-
-  'foreground_tab_request_start':
-      (_MAIN_ENTRY_POINT, 'requestStart'),
-}
-
-_TRACKED_EVENT_NAMES = set()
-for i in _METRICS.values():
-  _TRACKED_EVENT_NAMES.add(i[0])
-  if len(i) == 2:
-    _TRACKED_EVENT_NAMES.add(i[1])
-
-
-class StartupTimelineMetric(timeline_based_metric.TimelineBasedMetric):
-  """Reports summary stats from important startup events."""
-
-  def __init__(self):
-    super(StartupTimelineMetric, self).__init__()
-
-  def AddResults(self, model, _renderer_thread, interactions, results):
-    pass
-
-  def AddWholeTraceResults(self, model, results):
-    browser = model.browser_process
-
-    if not browser:
-      return
-
-    # Produce a map of events to track.
-    tracked_events = {}
-    for event in browser.parent.IterAllEvents(
-      event_predicate=lambda event: event.name in _TRACKED_EVENT_NAMES):
-      # In case of a begin/end trace event, only track the begin that contain
-      # the duration.
-      if event.name in tracked_events:
-        continue
-
-      tracked_events[event.name] = event
-
-    # Generate the metric values according to the tracked events.
-    for display_name, event_names in _METRICS.iteritems():
-      if event_names[0] not in tracked_events:
-        continue
-
-      duration = None
-      if len(event_names) == 1:
-        # The single event contains the duration to report.
-        duration = tracked_events[event_names[0]].duration
-
-      elif len(event_names) == 2:
-        # The duration is defined as the difference between two event starts.
-        if event_names[1] not in tracked_events:
-          continue
-
-        duration = (tracked_events[event_names[1]].start -
-            tracked_events[event_names[0]].start)
-
-      results.AddValue(value.scalar.ScalarValue(
-        page=results.current_page,
-        name=display_name,
-        units='ms',
-        value=duration,
-        improvement_direction=value.improvement_direction.DOWN))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/startup_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/startup_unittest.py
deleted file mode 100644
index a2aa113..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/startup_unittest.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import telemetry.timeline.event as timeline_event
-from telemetry.testing import test_page_test_results
-from telemetry.web_perf.metrics import startup
-
-
-class StartupTimelineMetricTest(unittest.TestCase):
-
-  def setUp(self):
-    self.events = []
-
-  def AddEvent(self, event_name, start, duration=None):
-    event = timeline_event.TimelineEvent('my_category', event_name,
-                                         start, duration)
-    self.events.append(event)
-
-  # Attributes defined outside __init__
-  # pylint: disable=attribute-defined-outside-init
-  def ComputeStartupMetrics(self):
-    results = test_page_test_results.TestPageTestResults(self)
-
-    # Create a mock model usable by
-    # StartupTimelineMetric.AddWholeTraceResults().
-    def IterateEvents(event_predicate):
-      for event in self.events:
-        if event_predicate(event):
-          yield event
-    class MockClass(object):
-      pass
-    model = MockClass()
-    model.browser_process = MockClass()
-    model.browser_process.parent = MockClass()
-    model.browser_process.parent.IterAllEvents = IterateEvents
-
-    startup.StartupTimelineMetric().AddWholeTraceResults(model, results)
-    return results
-
-  def testUntrackedvents(self):
-    # Code coverage for untracked events
-    self.AddEvent('uknown_event_0', 0)
-    self.AddEvent('uknown_event_1', 1)
-    self.ComputeStartupMetrics()
-
-  def testInstantEventsBasedValue(self):
-    # Test case with instant events to measure the duration between the first
-    # occurrences of two distinct events.
-    START0 = 7
-    START1 = 8
-    DURATION0 = 17
-    DURATION1 = 18
-
-    # Generate duplicated events to make sure we consider only the first one.
-    self.AddEvent(startup._MAIN_ENTRY_POINT, START0)
-    self.AddEvent(startup._MAIN_ENTRY_POINT, START1)
-    self.AddEvent('loadEventEnd', START0 + DURATION0)
-    self.AddEvent('loadEventEnd', START1 + DURATION1)
-    self.AddEvent('requestStart', START0 + DURATION0 * 2)
-    self.AddEvent('requestStart', START1 + DURATION1 * 2)
-
-    results = self.ComputeStartupMetrics()
-    results.AssertHasPageSpecificScalarValue('foreground_tab_load_complete',
-        'ms', DURATION0)
-    results.AssertHasPageSpecificScalarValue('foreground_tab_request_start',
-        'ms', DURATION0 * 2)
-
-  def testDurationEventsBasedValues(self):
-    DURATION_EVENTS = set([
-        'messageloop_start_time',
-        'window_display_time',
-        'open_tabs_time',
-        'first_non_empty_paint_time',
-        'first_main_frame_load_time'])
-
-    # Test case to get the duration of the first occurrence of a duration event.
-    i = 1
-    for display_name in DURATION_EVENTS:
-      self.assertTrue(len(startup._METRICS[display_name]) == 1)
-      event_name = startup._METRICS[display_name][0]
-
-      duration = 13 * i
-      i += 1
-
-      # Generate duplicated events to make sure only the first event is
-      # considered.
-      self.AddEvent(event_name, 5, duration)
-      self.AddEvent(event_name, 6, duration + 2)
-
-    results = self.ComputeStartupMetrics()
-
-    i = 1
-    for display_name in DURATION_EVENTS:
-      duration = 13 * i
-      i += 1
-
-      results.AssertHasPageSpecificScalarValue(display_name, 'ms', duration)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/text_selection.py b/catapult/telemetry/telemetry/web_perf/metrics/text_selection.py
deleted file mode 100644
index 6918579..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/text_selection.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.web_perf.metrics import single_event
-
-EVENT_NAME = 'WebLocalFrameImpl::moveRangeSelectionExtent'
-METRIC_NAME = 'text-selection'
-
-class TextSelectionMetric(single_event._SingleEventMetric):
-  """Reports directly durations of WebLocalFrameImpl::moveRangeSelectionExtent
-  events associated with moving a selection extent.
-  """
-
-  def __init__(self):
-    super(TextSelectionMetric, self).__init__(EVENT_NAME, METRIC_NAME,
-        metric_description=('List of durations of selection extent movements '
-                            'that were caused by and start during '
-                            'interactions'))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric.py b/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric.py
deleted file mode 100644
index d1307e9..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class TimelineBasedMetricException(Exception):
-  """Exception that can be thrown from metrics that implements
-     TimelineBasedMetric to indicate a problem arose when computing the metric.
-     """
-
-
-def _TimeRangesHasOverlap(iterable_time_ranges):
-  """ Returns True if there is are overlapped ranges in time ranges.
-  iterable_time_ranges: an iterable of time ranges. Each time range is a
-  tuple (start time, end time).
-  """
-  # Sort the ranges by the start time
-  sorted_time_ranges = sorted(iterable_time_ranges)
-  last_range = sorted_time_ranges[0]
-  for current_range in sorted_time_ranges[1:]:
-    start_current_range = current_range[0]
-    end_last_range = last_range[1]
-    if start_current_range < end_last_range:
-      return True
-    last_range = current_range
-  return False
-
-
-def IsEventInInteractions(event, interaction_records):
-  """ Return True if event is in any of the interaction records' time range.
-
-  Args:
-    event: an instance of telemetry.timeline.event.TimelineEvent.
-    interaction_records: a list of interaction records, whereas each record is
-      an instance of
-      telemetry.web_perf.timeline_interaction_record.TimelineInteractionRecord.
-
-  Returns:
-    True if |event|'s start & end time is in any of the |interaction_records|'s
-    time range.
-  """
-  return any(ir.start <= event.start and ir.end >= event.end for ir
-             in interaction_records)
-
-
-class TimelineBasedMetric(object):
-
-  def __init__(self):
-    """Computes metrics from a telemetry.timeline Model and a range
-
-    """
-    super(TimelineBasedMetric, self).__init__()
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    """Computes and adds metrics for the interaction_records' time ranges.
-
-    The override of this method should compute results on the data **only**
-    within the interaction_records' start and end time ranges.
-
-    Args:
-      model: An instance of telemetry.timeline.model.TimelineModel.
-      interaction_records: A list of instances of TimelineInteractionRecord. If
-        the override of this method doesn't support overlapped ranges, use
-        VerifyNonOverlappedRecords to check that no records are overlapped.
-      results: An instance of page.PageTestResults.
-
-    """
-    raise NotImplementedError()
-
-  def AddWholeTraceResults(self, model, results):
-    """Computes and adds metrics corresponding to the entire trace.
-
-    Override this method to compute results that correspond to the whole trace.
-
-    Args:
-      model: An instance of telemetry.timeline.model.TimelineModel.
-      results: An instance of page.PageTestResults.
-    """
-    pass
-
-  def VerifyNonOverlappedRecords(self, interaction_records):
-    """This raises exceptions if interaction_records contain overlapped ranges.
-    """
-    if _TimeRangesHasOverlap(((r.start, r.end) for r in interaction_records)):
-      raise TimelineBasedMetricException(
-          'This metric does not support interaction records with overlapped '
-          'time range.')
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric_unittest.py
deleted file mode 100644
index 31f0725..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/timeline_based_metric_unittest.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-import telemetry.web_perf.metrics.timeline_based_metric as tbm_module
-
-
-class FakeEvent(object):
-  def __init__(self, start, end):
-    self.start = start
-    self.end = end
-
-
-class FakeRecord(object):
-  def __init__(self, start, end):
-    self.start = start
-    self.end = end
-
-
-class TimelineBasedMetricTest(unittest.TestCase):
-
-  # pylint: disable=protected-access
-  def testTimeRangesHasOverlap(self):
-    # Test cases with overlap on one side
-    self.assertTrue(tbm_module._TimeRangesHasOverlap([(10, 20), (5, 15)]))
-    self.assertTrue(tbm_module._TimeRangesHasOverlap([(5, 15), (10, 20)]))
-    self.assertTrue(tbm_module._TimeRangesHasOverlap(
-        [(5, 15), (25, 30), (10, 20)]))
-
-    # Test cases with one range fall in the middle of other
-    self.assertTrue(tbm_module._TimeRangesHasOverlap([(10, 20), (15, 18)]))
-    self.assertTrue(tbm_module._TimeRangesHasOverlap([(15, 18), (10, 20)]))
-    self.assertTrue(tbm_module._TimeRangesHasOverlap(
-        [(15, 18), (40, 50), (10, 20)]))
-
-    self.assertFalse(tbm_module._TimeRangesHasOverlap([(15, 18), (20, 25)]))
-    self.assertFalse(tbm_module._TimeRangesHasOverlap(
-        [(1, 2), (2, 3), (0, 1)]))
-
-  def testIsEventInInteractions(self):
-    self.assertFalse(
-        tbm_module.IsEventInInteractions(
-        FakeEvent(0, 100),
-        [FakeRecord(5, 105), FakeRecord(50, 200), FakeRecord(300, 400)]))
-    self.assertFalse(
-        tbm_module.IsEventInInteractions(
-        FakeEvent(50, 100),
-        [FakeRecord(105, 205), FakeRecord(0, 45), FakeRecord(0, 90)]))
-    self.assertTrue(
-        tbm_module.IsEventInInteractions(
-        FakeEvent(50, 100),
-        [FakeRecord(5, 105), FakeRecord(0, 45), FakeRecord(0, 90)]))
-    self.assertTrue(
-        tbm_module.IsEventInInteractions(
-        FakeEvent(50, 100),
-        [FakeRecord(5, 45), FakeRecord(0, 45), FakeRecord(0, 100)]))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/trace_event_stats.py b/catapult/telemetry/telemetry/web_perf/metrics/trace_event_stats.py
deleted file mode 100644
index 097d866..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/trace_event_stats.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-
-
-class TraceEventStatsInput(object):
-  """Input for the TraceEventStats.
-  Using this object with TraceEventStats will include two metrics, one with a
-  list of times of the given event, and one for the count of the events, named
-  `metric_name + '-count'`.
-  Args:
-    event_category: The category of the event to track.
-    event_name: The name of the event to track.
-    metric_name: The name of the metric name, which accumulates all of the
-                 times of the events.
-    metric_description: Description of the metric.
-    units: Units for the metric.
-    process_name: (optional) The name of the process to inspect for the trace
-                  events. Defaults to 'Renderer'.
-  """
-  def __init__(self, event_category, event_name, metric_name,
-               metric_description, units, process_name='Renderer'):
-    self.event_category = event_category
-    self.event_name = event_name
-    self.metric_name = metric_name
-    self.metric_description = metric_description
-    self.units = units
-    self.process_name = process_name
-    self.event_id = TraceEventStatsInput.GetEventId(event_category, event_name)
-    assert process_name is not None
-
-  @staticmethod
-  def GetEventId(event_category, event_name):
-    return event_category + '^SERIALIZE-DELIM^' + event_name
-
-class TraceEventStats(object):
-  """Reports durations and counts of given trace events.
-  """
-
-  def __init__(self, trace_event_aggregator_inputs=None):
-    self._inputs_by_process_name = collections.defaultdict(list)
-    self._metrics = set()
-    self._IndexNewInputs(trace_event_aggregator_inputs)
-
-  def AddInput(self, trace_event_aggregator_input):
-    self._IndexNewInputs([trace_event_aggregator_input])
-
-  def _IndexNewInputs(self, input_list):
-    if not input_list:
-      return
-    for input_obj in input_list:
-      name = input_obj.metric_name
-      # We check here to make sure we don't have a duplicate metric
-      assert name not in self._metrics
-      assert (name + '-count') not in self._metrics
-      self._metrics.add(name)
-      self._metrics.add(name + '-count')
-
-      self._inputs_by_process_name[input_obj.process_name].append(input_obj)
-
-  @staticmethod
-  def ThreadDurationIfPresent(event):
-    if event.thread_duration:
-      return event.thread_duration
-    else:
-      return event.duration
-
-  def AddResults(self, model, renderer_process, interactions, results):
-    del renderer_process  # unused
-    assert interactions
-    for p in model.GetAllProcesses():
-      if p.name not in self._inputs_by_process_name:
-        continue
-
-      inputs = self._inputs_by_process_name[p.name]
-      input_ids = {i.event_id for i in inputs}
-
-      def InputIdPredicate(e, ids):
-        return TraceEventStatsInput.GetEventId(e.category, e.name) in ids
-
-      self._AddResultsInternal(
-          p.IterAllEvents(
-              recursive=True,
-              event_type_predicate=lambda t: True,
-              event_predicate=
-                  lambda e, ids=input_ids: InputIdPredicate(e, ids)),
-          interactions,
-          results,
-          inputs)
-
-  # We assume events have been filtered already. 'events' is an iterator.
-  def _AddResultsInternal(self, events, interactions, results, inputs):
-    times_by_event_id = collections.defaultdict(list)
-
-    for event in events:
-      if not any(interaction.start <= event.start <= interaction.end
-                 for interaction in interactions):
-        continue
-      event_id = TraceEventStatsInput.GetEventId(event.category, event.name)
-      times_by_event_id[event_id].append(self.ThreadDurationIfPresent(event))
-
-    if not times_by_event_id:
-      return
-
-    inputs_by_event_id = dict([[input_obj.event_id, input_obj]
-                                for input_obj in inputs])
-
-    for (event_name, times) in times_by_event_id.iteritems():
-      input_for_event = inputs_by_event_id[event_name]
-      name = input_for_event.metric_name
-      results.AddValue(scalar.ScalarValue(
-        page=results.current_page,
-        tir_label=interactions[0].label,
-        name=name + '-count',
-        units='count',
-        value=len(times),
-        description='The number of times ' + name + ' was recorded.'))
-      if len(times) == 0:
-        continue
-      results.AddValue(list_of_scalar_values.ListOfScalarValues(
-        page=results.current_page,
-        tir_label=interactions[0].label,
-        name=name,
-        units=input_for_event.units,
-        values=times,
-        description=input_for_event.metric_description))
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/trace_event_stats_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/trace_event_stats_unittest.py
deleted file mode 100644
index 242ae59..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/trace_event_stats_unittest.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from collections import namedtuple
-from telemetry.testing import test_page_test_results
-from telemetry.timeline import model as model_module
-from telemetry.timeline import slice as slice_module
-from telemetry.web_perf import timeline_interaction_record
-from telemetry.web_perf.metrics.trace_event_stats import TraceEventStats
-from telemetry.web_perf.metrics.trace_event_stats import TraceEventStatsInput
-
-
-FakeEvent = namedtuple('Event', 'name, start, end, thread_duration, args')
-Interaction = timeline_interaction_record.TimelineInteractionRecord
-TEST_INTERACTION_LABEL = 'Action_TestInteraction'
-
-RENDERER_PROCESS = 'Renderer'
-OTHER_PROCESS = 'Other'
-
-EVENT_CATEGORY1 = 'Category1'
-EVENT_CATEGORY2 = 'Category2'
-
-EVENT_NAME1 = 'Name1'
-EVENT_NAME2 = 'Name2'
-
-
-def TestInteraction(start, end):
-  return Interaction(TEST_INTERACTION_LABEL, start, end)
-
-class TraceEventStatsUnittest(unittest.TestCase):
-
-  def setUp(self):
-    self.model = model_module.TimelineModel()
-    self.renderer_process = self.model.GetOrCreateProcess(1)
-    self.renderer_process.name = RENDERER_PROCESS
-    self.main_thread = self.renderer_process.GetOrCreateThread(tid=11)
-    self.other_process = self.model.GetOrCreateProcess(2)
-    self.other_process.name = OTHER_PROCESS
-    self.other_thread = self.other_process.GetOrCreateThread(tid=12)
-
-  def GetThreadForProcessName(self, process_name):
-    if process_name is RENDERER_PROCESS:
-      return self.main_thread
-    elif process_name is OTHER_PROCESS:
-      return self.other_thread
-    else:
-      raise
-
-  def AddEvent(self, process_name, event_category, event_name,
-               start, duration, thread_start, thread_duration):
-    thread = self.GetThreadForProcessName(process_name)
-    record = slice_module.Slice(thread,
-                             event_category,
-                             event_name,
-                             start, duration, thread_start, thread_duration)
-    thread.PushSlice(record)
-
-  def RunAggregator(self, aggregator, interactions):
-    results = test_page_test_results.TestPageTestResults(self)
-    aggregator.AddResults(self.model, self.renderer_process,
-                          interactions, results)
-    return results
-
-  def testBasicUsage(self):
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 10, 8, 10, 5)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 14, 2, 14, 2)
-    interactions = [TestInteraction(9, 14)]
-
-    aggregator = TraceEventStats()
-    aggregator.AddInput(TraceEventStatsInput(
-      EVENT_CATEGORY1,
-      EVENT_NAME1,
-      'metric-name',
-      'metric-description',
-      'units',
-      'Renderer'))
-
-    results = self.RunAggregator(aggregator, interactions)
-    results.AssertHasPageSpecificScalarValue('metric-name-count', 'count', 2)
-    results.AssertHasPageSpecificListOfScalarValues(
-      'metric-name', 'units', [5, 2])
-
-  def testFiltering(self):
-    # These should be recorded.
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 10, 8, 10, 5)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 14, 2, 14, 2)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 20, 6, 20, 1)
-
-    # These should be filtered.
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 15, 1, 15, 1)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY2, EVENT_NAME1, 11, 4, 11, 4)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME2, 11, 3, 11, 3)
-    self.AddEvent(OTHER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 11, 2, 11, 2)
-
-    interactions = [TestInteraction(9, 14), TestInteraction(20, 21)]
-
-    aggregator = TraceEventStats()
-    # Test that we default to 'Renderer'
-    aggregator.AddInput(TraceEventStatsInput(
-      EVENT_CATEGORY1,
-      EVENT_NAME1,
-      'metric-name',
-      'metric-description',
-      'units'))
-
-    results = self.RunAggregator(aggregator, interactions)
-    results.AssertHasPageSpecificScalarValue('metric-name-count', 'count', 3)
-    results.AssertHasPageSpecificListOfScalarValues(
-      'metric-name', 'units', [5, 2, 1])
-
-  def testNoInputs(self):
-    # These should be recorded.
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 10, 8, 10, 5)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 14, 2, 14, 2)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 20, 6, 20, 1)
-
-    # These should be filtered.
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 15, 1, 15, 1)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY2, EVENT_NAME1, 11, 4, 11, 4)
-    self.AddEvent(RENDERER_PROCESS, EVENT_CATEGORY1, EVENT_NAME2, 11, 3, 11, 3)
-    self.AddEvent(OTHER_PROCESS, EVENT_CATEGORY1, EVENT_NAME1, 11, 2, 11, 2)
-
-    interactions = [TestInteraction(9, 14), TestInteraction(20, 21)]
-
-    aggregator = TraceEventStats()
-
-    results = self.RunAggregator(aggregator, interactions)
-    self.assertEquals([], results.all_page_specific_values)
-
-
-  def testNoEvents(self):
-    interactions = [TestInteraction(9, 14)]
-
-    aggregator = TraceEventStats()
-    aggregator.AddInput(TraceEventStatsInput(
-      EVENT_CATEGORY1,
-      EVENT_NAME1,
-      'metric-name',
-      'metric-description',
-      'units'))
-
-    results = self.RunAggregator(aggregator, interactions)
-    self.assertEquals([], results.all_page_specific_values)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/v8_gc_latency.py b/catapult/telemetry/telemetry/web_perf/metrics/v8_gc_latency.py
deleted file mode 100644
index 9d385f6..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/v8_gc_latency.py
+++ /dev/null
@@ -1,199 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.util import statistics
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.web_perf.metrics import timeline_based_metric
-
-import logging
-
-class V8EventStat(object):
-
-  def __init__(self, src_event_name, result_name, result_description):
-    self.src_event_name = src_event_name
-    self.result_name = result_name
-    self.result_description = result_description
-    self.thread_duration = 0.0
-    self.thread_duration_inside_idle = 0.0
-    self.idle_task_overrun_duration = 0.0
-    self.max_thread_duration = 0.0
-    self.count = 0
-
-  @property
-  def thread_duration_outside_idle(self):
-    return self.thread_duration - self.thread_duration_inside_idle
-
-  @property
-  def percentage_thread_duration_during_idle(self):
-    return statistics.DivideIfPossibleOrZero(
-        100 * self.thread_duration_inside_idle, self.thread_duration)
-
-class V8GCLatency(timeline_based_metric.TimelineBasedMetric):
-  _RENDERER_MAIN_THREAD = 'CrRendererMain'
-  _IDLE_TASK_PARENT = 'SingleThreadIdleTaskRunner::RunTask'
-
-  def __init__(self):
-    super(V8GCLatency, self).__init__()
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    self.VerifyNonOverlappedRecords(interaction_records)
-    self._AddV8MetricsToResults(model, interaction_records, results)
-
-  def _AddV8MetricsToResults(self, model,
-                             interaction_records, results):
-    self._AddV8EventStatsToResults(model, interaction_records, results)
-
-  def _AddV8EventStatsToResults(self, model, interactions, results):
-    v8_event_stats = [
-        V8EventStat('V8.GCIncrementalMarking',
-                    'v8_gc_incremental_marking',
-                    'incremental marking steps'),
-        V8EventStat('V8.GCScavenger',
-                    'v8_gc_scavenger',
-                    'scavenges'),
-        V8EventStat('V8.GCCompactor',
-                    'v8_gc_mark_compactor',
-                    'mark-sweep-compactor'),
-        V8EventStat('V8.GCFinalizeMC',
-                    'v8_gc_finalize_incremental',
-                    'finalization of incremental marking'),
-        V8EventStat('V8.GCFinalizeMCReduceMemory',
-                    'v8_gc_finalize_incremental_reduce_memory',
-                    'finalization of incremental marking with memory reducer')]
-    label = interactions[0].label
-    name_to_v8_stat = {x.src_event_name : x for x in v8_event_stats}
-    thread_time_not_available = False
-    for event in model.IterAllSlices():
-      if (not timeline_based_metric.IsEventInInteractions(event, interactions)
-          or not event.name in name_to_v8_stat):
-        continue
-      event_stat = name_to_v8_stat[event.name]
-      if event.thread_duration is None:
-        thread_time_not_available = True
-        event_duration = event.duration
-      else:
-        event_duration = event.thread_duration
-      event_stat.thread_duration += event_duration
-      event_stat.max_thread_duration = max(event_stat.max_thread_duration,
-                                           event_duration)
-      event_stat.count += 1
-
-      parent_idle_task = self._ParentIdleTask(event)
-      if parent_idle_task:
-        allotted_idle_time = parent_idle_task.args['allotted_time_ms']
-        idle_task_wall_overrun = 0
-        if event.duration > allotted_idle_time:
-          idle_task_wall_overrun = event.duration - allotted_idle_time
-        # Don't count time over the deadline as being inside idle time.
-        # Since the deadline should be relative to wall clock we compare
-        # allotted_time_ms with wall duration instead of thread duration, and
-        # then assume the thread duration was inside idle for the same
-        # percentage of time.
-        inside_idle = event_duration * statistics.DivideIfPossibleOrZero(
-            event.duration - idle_task_wall_overrun, event.duration)
-        event_stat.thread_duration_inside_idle += inside_idle
-        event_stat.idle_task_overrun_duration += idle_task_wall_overrun
-
-    if thread_time_not_available:
-      logging.warning(
-          'thread time is not available in trace data, switch to walltime')
-
-    for v8_event_stat in v8_event_stats:
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, v8_event_stat.result_name, 'ms',
-          v8_event_stat.thread_duration,
-          description=('Total thread duration spent in %s' %
-                       v8_event_stat.result_description),
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, '%s_max' % v8_event_stat.result_name, 'ms',
-          v8_event_stat.max_thread_duration,
-          description=('Max thread duration spent in %s' %
-                       v8_event_stat.result_description),
-          tir_label=label))
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, '%s_count' % v8_event_stat.result_name, 'count',
-          v8_event_stat.count,
-          description=('Number of %s' %
-                       v8_event_stat.result_description),
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-      average_thread_duration = statistics.DivideIfPossibleOrZero(
-          v8_event_stat.thread_duration, v8_event_stat.count)
-      results.AddValue(scalar.ScalarValue(
-          results.current_page, '%s_average' % v8_event_stat.result_name, 'ms',
-          average_thread_duration,
-          description=('Average thread duration spent in %s' %
-                       v8_event_stat.result_description),
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-      results.AddValue(scalar.ScalarValue(results.current_page,
-          '%s_outside_idle' % v8_event_stat.result_name, 'ms',
-          v8_event_stat.thread_duration_outside_idle,
-          description=(
-              'Total thread duration spent in %s outside of idle tasks' %
-              v8_event_stat.result_description),
-          tir_label=label))
-      results.AddValue(scalar.ScalarValue(results.current_page,
-          '%s_idle_deadline_overrun' % v8_event_stat.result_name, 'ms',
-          v8_event_stat.idle_task_overrun_duration,
-          description=('Total idle task deadline overrun for %s idle tasks'
-                       % v8_event_stat.result_description),
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-      results.AddValue(scalar.ScalarValue(results.current_page,
-          '%s_percentage_idle' % v8_event_stat.result_name, 'idle%',
-          v8_event_stat.percentage_thread_duration_during_idle,
-          description=('Percentage of %s spent in idle time' %
-                       v8_event_stat.result_description),
-          tir_label=label,
-          improvement_direction=improvement_direction.UP))
-
-    # Add total metrics.
-    gc_total = sum(x.thread_duration for x in v8_event_stats)
-    gc_total_outside_idle = sum(
-        x.thread_duration_outside_idle for x in v8_event_stats)
-    gc_total_idle_deadline_overrun = sum(
-        x.idle_task_overrun_duration for x in v8_event_stats)
-    gc_total_percentage_idle = statistics.DivideIfPossibleOrZero(
-        100 * (gc_total - gc_total_outside_idle), gc_total)
-
-    results.AddValue(scalar.ScalarValue(results.current_page,
-        'v8_gc_total', 'ms', gc_total,
-        description='Total thread duration of all garbage collection events',
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-    results.AddValue(scalar.ScalarValue(results.current_page,
-        'v8_gc_total_outside_idle', 'ms', gc_total_outside_idle,
-        description=(
-            'Total thread duration of all garbage collection events outside of '
-            'idle tasks'),
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-    results.AddValue(scalar.ScalarValue(results.current_page,
-        'v8_gc_total_idle_deadline_overrun', 'ms',
-        gc_total_idle_deadline_overrun,
-        description=(
-            'Total idle task deadline overrun for all idle tasks garbage '
-            'collection events'),
-          tir_label=label,
-          improvement_direction=improvement_direction.DOWN))
-    results.AddValue(scalar.ScalarValue(results.current_page,
-        'v8_gc_total_percentage_idle', 'idle%', gc_total_percentage_idle,
-        description=(
-            'Percentage of the thread duration of all garbage collection '
-            'events spent inside of idle tasks'),
-          tir_label=label,
-          improvement_direction=improvement_direction.UP))
-
-  def _ParentIdleTask(self, event):
-    parent = event.parent_slice
-    while parent:
-      if parent.name == self._IDLE_TASK_PARENT:
-        return parent
-      parent = parent.parent_slice
-    return None
-
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/v8_gc_latency_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/v8_gc_latency_unittest.py
deleted file mode 100644
index 03c850a..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/v8_gc_latency_unittest.py
+++ /dev/null
@@ -1,445 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.internal.results import page_test_results
-from telemetry.page import page as page_module
-from telemetry.testing import options_for_unittests
-from telemetry.testing import page_test_test_case
-from telemetry.timeline import model as model_module
-from telemetry.util import wpr_modes
-
-from telemetry.web_perf.metrics import v8_gc_latency
-from telemetry.web_perf import timeline_interaction_record
-
-class V8EventStat(object):
-
-  def __init__(self, src_event_name, result_name, result_description):
-    self.src_event_name = src_event_name
-    self.result_name = result_name
-    self.result_description = result_description
-    self.thread_duration = 0.0
-    self.thread_duration_inside_idle = 0.0
-    self.idle_task_overrun_duration = 0.0
-    self.max_thread_duration = 0.0
-    self.count = 0
-
-class V8GCLatencyTestPageHelper(object):
-
-  def __init__(self, page_set):
-    self._page_set = page_set
-    self._model = model_module.TimelineModel()
-    self._renderer_process = self._model.GetOrCreateProcess(1)
-    self._renderer_thread = self._renderer_process.GetOrCreateThread(2)
-    self._renderer_thread.name = 'CrRendererMain'
-    self._interaction_records = []
-
-  def AddEvent(self, category, name, thread_start, thread_duration,
-               args=None, wall_start=None, wall_duration=None):
-    wall_start = wall_start or thread_start
-    wall_duration = wall_duration or thread_duration
-    self._renderer_thread.BeginSlice(category, name, wall_start, thread_start,
-                                     args=args)
-    self._renderer_thread.EndSlice(wall_start + wall_duration,
-                                   thread_start + thread_duration)
-
-  def AddEventWithoutThreadDuration(self, category, name,
-                                    wall_start, wall_duration):
-    self._renderer_thread.BeginSlice(category, name, wall_start)
-    self._renderer_thread.EndSlice(wall_start + wall_duration)
-
-  def AddInteractionRecord(self, label, start, end):
-    self._interaction_records.append(
-      timeline_interaction_record.TimelineInteractionRecord(label, start, end))
-
-  class MockV8GCLatencyPage(page_module.Page):
-
-    def __init__(self, page_set):
-      super(V8GCLatencyTestPageHelper.MockV8GCLatencyPage, self).__init__(
-          'file://blank.html', page_set, page_set.base_dir)
-
-  def MeasureFakePage(self):
-    # Create a fake page and add it to the page set.
-    results = page_test_results.PageTestResults()
-    page = V8GCLatencyTestPageHelper.MockV8GCLatencyPage(self._page_set)
-    self._page_set.AddStory(page)
-
-    # Pretend we're about to run the tests to silence lower level asserts.
-    results.WillRunPage(page)
-
-    metric = v8_gc_latency.V8GCLatency()
-
-    # Finalize the timeline import.
-    self._model.FinalizeImport()
-
-    for interaction in self._interaction_records:
-      # Measure the V8GCLatency metric and return the results
-      # pylint: disable=protected-access
-      metric._AddV8MetricsToResults(self._model, [interaction], results)
-    results.DidRunPage(page)
-    return results
-
-
-class V8GCLatencyTests(page_test_test_case.PageTestTestCase):
-
-  def setUp(self):
-    self._options = options_for_unittests.GetCopy()
-    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
-
-  def testWithNoTraceEvents(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-    test_page_helper.AddInteractionRecord('Action', 0, 32)
-
-    results = test_page_helper.MeasureFakePage()
-    self._AssertResultsEqual(_GetEmptyResults(), _ActualValues(results))
-
-  def testWithNoGarbageCollectionEvents(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-
-    test_page_helper.AddInteractionRecord('Action', 0, 32)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=14, wall_start=5, wall_duration=35)
-
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-
-    self._AssertResultsEqual(expected, _ActualValues(results))
-
-  def testWithGarbageCollectionEvents(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-
-    test_page_helper.AddInteractionRecord('Action', 0, 88)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=77, wall_start=5, wall_duration=88)
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4)
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3)
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4)
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2)
-    test_page_helper.AddEvent('v8', 'V8.GCFinalizeMC', 38, 2)
-    test_page_helper.AddEvent('v8', 'V8.GCFinalizeMC', 42, 3)
-    test_page_helper.AddEvent('v8', 'V8.GCFinalizeMCReduceMemory', 46, 4)
-    test_page_helper.AddEvent('v8', 'V8.GCFinalizeMCReduceMemory', 51, 5)
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 62, 4)
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 72, 5)
-
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-    expected['v8_gc_incremental_marking'] = ('ms', 6.0)
-    expected['v8_gc_incremental_marking_average'] = ('ms', 3.0)
-    expected['v8_gc_incremental_marking_count'] = ('count', 2)
-    expected['v8_gc_incremental_marking_max'] = ('ms', 4.0)
-    expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 6.0)
-    expected['v8_gc_finalize_incremental'] = ('ms', 5.0)
-    expected['v8_gc_finalize_incremental_average'] = ('ms', 2.5)
-    expected['v8_gc_finalize_incremental_count'] = ('count', 2)
-    expected['v8_gc_finalize_incremental_max'] = ('ms', 3.0)
-    expected['v8_gc_finalize_incremental_outside_idle'] = ('ms', 5.0)
-    expected['v8_gc_finalize_incremental_reduce_memory'] = ('ms', 9.0)
-    expected['v8_gc_finalize_incremental_reduce_memory_average'] = ('ms', 4.5)
-    expected['v8_gc_finalize_incremental_reduce_memory_count'] = ('count', 2)
-    expected['v8_gc_finalize_incremental_reduce_memory_max'] = ('ms', 5.0)
-    expected['v8_gc_finalize_incremental_reduce_memory_outside_idle'] = (
-        'ms', 9.0)
-    expected['v8_gc_scavenger'] = ('ms', 7.0)
-    expected['v8_gc_scavenger_average'] = ('ms', 3.5)
-    expected['v8_gc_scavenger_count'] = ('count', 2)
-    expected['v8_gc_scavenger_max'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_outside_idle'] = ('ms', 7.0)
-    expected['v8_gc_mark_compactor'] = ('ms', 9.0)
-    expected['v8_gc_mark_compactor_average'] = ('ms', 4.5)
-    expected['v8_gc_mark_compactor_count'] = ('count', 2)
-    expected['v8_gc_mark_compactor_max'] = ('ms', 5.0)
-    expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 9.0)
-    expected['v8_gc_total'] = ('ms', 36.0)
-    expected['v8_gc_total_outside_idle'] = ('ms', 36.0)
-
-    self._AssertResultsEqual(expected, _ActualValues(results))
-
-  def testWithIdleTaskGarbageCollectionEvents(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-
-    test_page_helper.AddInteractionRecord('Action', 0, 68)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=57, wall_start=5, wall_duration=68)
-
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4)
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 15, 4, {'allotted_time_ms': 12})
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3)
-
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4)
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 34, 3, {'allotted_time_ms': 12})
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2)
-
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 42, 4)
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 52, 6, {'allotted_time_ms': 12})
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 5)
-
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-    expected['v8_gc_incremental_marking'] = ('ms', 6.0)
-    expected['v8_gc_incremental_marking_average'] = ('ms', 3.0)
-    expected['v8_gc_incremental_marking_count'] = ('count', 2)
-    expected['v8_gc_incremental_marking_max'] = ('ms', 4.0)
-    expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_incremental_marking_percentage_idle'] = \
-        ('idle%', 100 * 2 / 6.0)
-    expected['v8_gc_scavenger'] = ('ms', 7.0)
-    expected['v8_gc_scavenger_average'] = ('ms', 3.5)
-    expected['v8_gc_scavenger_count'] = ('count', 2)
-    expected['v8_gc_scavenger_max'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_percentage_idle'] = ('idle%', 100 * 3 / 7.0)
-    expected['v8_gc_mark_compactor'] = ('ms', 9.0)
-    expected['v8_gc_mark_compactor_average'] = ('ms', 4.5)
-    expected['v8_gc_mark_compactor_count'] = ('count', 2)
-    expected['v8_gc_mark_compactor_max'] = ('ms', 5.0)
-    expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_mark_compactor_percentage_idle'] = ('idle%', 100 * 5 / 9.0)
-    expected['v8_gc_total'] = ('ms', 22.0)
-    expected['v8_gc_total_outside_idle'] = ('ms', 12.0)
-    expected['v8_gc_total_percentage_idle'] = ('idle%', 100 * 10 / 22.0)
-
-    self._AssertResultsEqual(expected, _ActualValues(results))
-
-  def testWithIdleTaskOverruns(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-
-    test_page_helper.AddInteractionRecord('Action', 0, 92)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=80, wall_start=5, wall_duration=92)
-
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 15, 15, {'allotted_time_ms': 8})
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 14)
-
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 34, 15, {'allotted_time_ms': 6})
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 14)
-
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 52, 23, {'allotted_time_ms': 9})
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 22)
-
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-    expected['v8_gc_incremental_marking'] = ('ms', 14.0)
-    expected['v8_gc_incremental_marking_average'] = ('ms', 14.0)
-    expected['v8_gc_incremental_marking_count'] = ('count', 1)
-    expected['v8_gc_incremental_marking_max'] = ('ms', 14.0)
-    expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 8.0)
-    expected['v8_gc_incremental_marking_idle_deadline_overrun'] = ('ms', 8.0)
-    expected['v8_gc_incremental_marking_percentage_idle'] = \
-        ('idle%', 100 * 6 / 14.0)
-    expected['v8_gc_scavenger'] = ('ms', 14.0)
-    expected['v8_gc_scavenger_average'] = ('ms', 14.0)
-    expected['v8_gc_scavenger_count'] = ('count', 1)
-    expected['v8_gc_scavenger_max'] = ('ms', 14.0)
-    expected['v8_gc_scavenger_outside_idle'] = ('ms', 6.0)
-    expected['v8_gc_scavenger_idle_deadline_overrun'] = ('ms', 6.0)
-    expected['v8_gc_scavenger_percentage_idle'] = ('idle%', 100 * 8 / 14.0)
-    expected['v8_gc_mark_compactor'] = ('ms', 22.0)
-    expected['v8_gc_mark_compactor_average'] = ('ms', 22.0)
-    expected['v8_gc_mark_compactor_count'] = ('count', 1)
-    expected['v8_gc_mark_compactor_max'] = ('ms', 22.0)
-    expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 13.0)
-    expected['v8_gc_mark_compactor_idle_deadline_overrun'] = ('ms', 13.0)
-    expected['v8_gc_mark_compactor_percentage_idle'] = ('idle%', 100 * 9 / 22.0)
-    expected['v8_gc_total'] = ('ms', 50.0)
-    expected['v8_gc_total_outside_idle'] = ('ms', 27.0)
-    expected['v8_gc_total_idle_deadline_overrun'] = ('ms', 27.0)
-    expected['v8_gc_total_percentage_idle'] = ('idle%', 100 * 23 / 50.0)
-
-    self._AssertResultsEqual(expected, _ActualValues(results))
-
-  def testWithIdleTaskWallDurationOverruns(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-
-    test_page_helper.AddInteractionRecord('Action', 0, 92)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=80, wall_start=5, wall_duration=92)
-
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 15, 15, {'allotted_time_ms': 8})
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger',
-        thread_start=15, thread_duration=4, wall_start=15, wall_duration=14)
-
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-    expected['v8_gc_scavenger'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_average'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_count'] = ('count', 1)
-    expected['v8_gc_scavenger_max'] = ('ms', 4.0)
-    expected_outside_idle = 4.0 - (4.0 * 8 / 14)
-    expected['v8_gc_scavenger_outside_idle'] = ('ms', expected_outside_idle)
-    expected['v8_gc_scavenger_idle_deadline_overrun'] = ('ms', 6.0)
-    expected['v8_gc_scavenger_percentage_idle'] = \
-        ('idle%', 100 * (4.0 - expected_outside_idle) / 4.0)
-    expected['v8_gc_total'] = expected['v8_gc_scavenger']
-    expected['v8_gc_total_outside_idle'] = \
-        expected['v8_gc_scavenger_outside_idle']
-    expected['v8_gc_total_idle_deadline_overrun'] = \
-        expected['v8_gc_scavenger_idle_deadline_overrun']
-    expected['v8_gc_total_percentage_idle'] = \
-        expected['v8_gc_scavenger_percentage_idle']
-
-    self._AssertResultsEqual(expected, _ActualValues(results))
-
-  def testWithMultipleInteractionRecords(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-
-    test_page_helper.AddInteractionRecord('Action1', 5, 18)
-    test_page_helper.AddInteractionRecord('Action2', 19, 57)
-    test_page_helper.AddInteractionRecord('Action3', 60, 68)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=57, wall_start=5, wall_duration=68)
-
-    # This event is not in any interaction record.
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 0, 1)
-
-    # These events are in Action1.
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4)
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 15, 4, {'allotted_time_ms': 12})
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3)
-
-    # These events are in Action2.
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4)
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 34, 3, {'allotted_time_ms': 12})
-    test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2)
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 42, 4)
-    test_page_helper.AddEvent('renderer.scheduler',
-        'SingleThreadIdleTaskRunner::RunTask', 52, 6, {'allotted_time_ms': 12})
-    test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 5)
-
-    # This event is not in any interaction record.
-    test_page_helper.AddEvent('v8', 'V8.GCScavenger', 58, 1)
-
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-    expected['v8_gc_scavenger'] = ('ms', 7.0)
-    expected['v8_gc_scavenger_average'] = ('ms', 3.5)
-    expected['v8_gc_scavenger_count'] = ('count', 2)
-    expected['v8_gc_scavenger_max'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_percentage_idle'] = ('idle%', 100 * 3 / 7.0)
-    expected['v8_gc_total'] = ('ms', 7.0)
-    expected['v8_gc_total_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_total_percentage_idle'] = ('idle%', 100 * 3.0 / 7.0)
-
-    self._AssertResultsEqual(expected, _ActualValues(results, 'Action1'))
-
-    expected = _GetEmptyResults()
-    expected['v8_gc_incremental_marking'] = ('ms', 6.0)
-    expected['v8_gc_incremental_marking_average'] = ('ms', 3.0)
-    expected['v8_gc_incremental_marking_count'] = ('count', 2)
-    expected['v8_gc_incremental_marking_max'] = ('ms', 4.0)
-    expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_incremental_marking_percentage_idle'] = \
-        ('idle%', 100 * 2 / 6.0)
-    expected['v8_gc_mark_compactor'] = ('ms', 9.0)
-    expected['v8_gc_mark_compactor_average'] = ('ms', 4.5)
-    expected['v8_gc_mark_compactor_count'] = ('count', 2)
-    expected['v8_gc_mark_compactor_max'] = ('ms', 5.0)
-    expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_mark_compactor_percentage_idle'] = ('idle%', 100 * 5 / 9.0)
-    expected['v8_gc_total'] = ('ms', 15.0)
-    expected['v8_gc_total_outside_idle'] = ('ms', 8.0)
-    expected['v8_gc_total_percentage_idle'] = ('idle%', 100 * 7.0 / 15.0)
-
-    self._AssertResultsEqual(expected, _ActualValues(results, 'Action2'))
-
-    expected = _GetEmptyResults()
-    self._AssertResultsEqual(expected, _ActualValues(results, 'Action3'))
-
-
-  def testRegress549150(self):
-    test_page_helper = V8GCLatencyTestPageHelper(
-        self.CreateEmptyPageSet())
-    test_page_helper.AddInteractionRecord('Action', 0, 10)
-    test_page_helper.AddEvent('toplevel', 'PostMessage',
-        thread_start=0, thread_duration=10, wall_start=0, wall_duration=10)
-    test_page_helper.AddEventWithoutThreadDuration(
-        'v8', 'V8.GCScavenger', 0, 4)
-    results = test_page_helper.MeasureFakePage()
-    expected = _GetEmptyResults()
-    expected['v8_gc_scavenger'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_average'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_count'] = ('count', 1)
-    expected['v8_gc_scavenger_max'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_scavenger_percentage_idle'] = ('idle%', 0.0)
-    expected['v8_gc_total'] = ('ms', 4.0)
-    expected['v8_gc_total_outside_idle'] = ('ms', 4.0)
-    expected['v8_gc_total_percentage_idle'] = ('idle%', 0.0)
-
-    self._AssertResultsEqual(expected, _ActualValues(results, 'Action'))
-
-
-  def _AssertResultsEqual(self, expected, actual):
-    for key in expected.iterkeys():
-      self.assertIn(key, actual.keys())
-      self.assertEqual(expected[key], actual[key],
-          'Result for [' + key + '] - expected ' + str(expected[key]) +
-          ' but got ' + str(actual[key]))
-
-
-def _ActualValues(results, interaction_record=''):
-  return dict(list(
-      (v.name, (v.units, v.value))
-      for v in results.all_page_specific_values
-      if (interaction_record == '' or v.tir_label == interaction_record)
-      ))
-
-
-def _GetEmptyResults():
-  return {'v8_gc_incremental_marking': ('ms', 0.0),
-          'v8_gc_incremental_marking_average': ('ms', 0.0),
-          'v8_gc_incremental_marking_count': ('count', 0),
-          'v8_gc_incremental_marking_max': ('ms', 0.0),
-          'v8_gc_incremental_marking_idle_deadline_overrun': ('ms', 0.0),
-          'v8_gc_incremental_marking_outside_idle': ('ms', 0.0),
-          'v8_gc_incremental_marking_percentage_idle': ('idle%', 0.0),
-          'v8_gc_finalize_incremental': ('ms', 0.0),
-          'v8_gc_finalize_incremental_average': ('ms', 0.0),
-          'v8_gc_finalize_incremental_count': ('count', 0),
-          'v8_gc_finalize_incremental_max': ('ms', 0.0),
-          'v8_gc_finalize_incremental_idle_deadline_overrun': ('ms', 0.0),
-          'v8_gc_finalize_incremental_outside_idle': ('ms', 0.0),
-          'v8_gc_finalize_incremental_percentage_idle': ('idle%', 0.0),
-          'v8_gc_finalize_incremental_reduce_memory': ('ms', 0.0),
-          'v8_gc_finalize_incremental_reduce_memory_average': ('ms', 0.0),
-          'v8_gc_finalize_incremental_reduce_memory_count': ('count', 0),
-          'v8_gc_finalize_incremental_reduce_memory_max': ('ms', 0.0),
-          'v8_gc_finalize_incremental_reduce_memory_idle_deadline_overrun':
-              ('ms', 0.0),
-          'v8_gc_finalize_incremental_reduce_memory_outside_idle': ('ms', 0.0),
-          'v8_gc_finalize_incremental_reduce_memory_percentage_idle':
-              ('idle%', 0.0),
-          'v8_gc_mark_compactor': ('ms', 0.0),
-          'v8_gc_mark_compactor_average': ('ms', 0.0),
-          'v8_gc_mark_compactor_count': ('count', 0),
-          'v8_gc_mark_compactor_max': ('ms', 0.0),
-          'v8_gc_mark_compactor_idle_deadline_overrun': ('ms', 0.0),
-          'v8_gc_mark_compactor_outside_idle': ('ms', 0.0),
-          'v8_gc_mark_compactor_percentage_idle': ('idle%', 0.0),
-          'v8_gc_scavenger': ('ms', 0.0),
-          'v8_gc_scavenger_average': ('ms', 0.0),
-          'v8_gc_scavenger_count': ('count', 0),
-          'v8_gc_scavenger_max': ('ms', 0.0),
-          'v8_gc_scavenger_idle_deadline_overrun': ('ms', 0.0),
-          'v8_gc_scavenger_outside_idle': ('ms', 0.0),
-          'v8_gc_scavenger_percentage_idle': ('idle%', 0.0),
-          'v8_gc_total': ('ms', 0.0),
-          'v8_gc_total_idle_deadline_overrun': ('ms', 0.0),
-          'v8_gc_total_outside_idle': ('ms', 0.0)}
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_stats.py b/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_stats.py
deleted file mode 100644
index 43276b6..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_stats.py
+++ /dev/null
@@ -1,366 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from telemetry.util import statistics
-
-DISPLAY_HERTZ = 60.0
-VSYNC_DURATION = 1e6 / DISPLAY_HERTZ
-# When to consider a frame frozen (in VSYNC units): meaning 1 initial
-# frame + 5 repeats of that frame.
-FROZEN_THRESHOLD = 6
-# Severity factor.
-SEVERITY = 3
-
-IDEAL_RENDER_INSTANT = 'Ideal Render Instant'
-ACTUAL_RENDER_BEGIN = 'Actual Render Begin'
-ACTUAL_RENDER_END = 'Actual Render End'
-SERIAL = 'Serial'
-
-
-class TimeStats(object):
-  """Stats container for webrtc rendering metrics."""
-
-  def __init__(self, drift_time=None, mean_drift_time=None,
-    std_dev_drift_time=None, percent_badly_out_of_sync=None,
-    percent_out_of_sync=None, smoothness_score=None, freezing_score=None,
-    rendering_length_error=None, fps=None, frame_distribution=None):
-    self.drift_time = drift_time
-    self.mean_drift_time = mean_drift_time
-    self.std_dev_drift_time = std_dev_drift_time
-    self.percent_badly_out_of_sync = percent_badly_out_of_sync
-    self.percent_out_of_sync = percent_out_of_sync
-    self.smoothness_score = smoothness_score
-    self.freezing_score = freezing_score
-    self.rendering_length_error = rendering_length_error
-    self.fps = fps
-    self.frame_distribution = frame_distribution
-    self.invalid_data = False
-
-
-
-class WebMediaPlayerMsRenderingStats(object):
-  """Analyzes events of WebMediaPlayerMs type."""
-
-  def __init__(self, events):
-    """Save relevant events according to their stream."""
-    self.stream_to_events = self._MapEventsToStream(events)
-
-  def _IsEventValid(self, event):
-    """Check that the needed arguments are present in event.
-
-    Args:
-      event: event to check.
-
-    Returns:
-      True is event is valid, false otherwise."""
-    if not event.args:
-      return False
-    mandatory = [ACTUAL_RENDER_BEGIN, ACTUAL_RENDER_END,
-        IDEAL_RENDER_INSTANT, SERIAL]
-    for parameter in mandatory:
-      if not parameter in event.args:
-        return False
-    return True
-
-  def _MapEventsToStream(self, events):
-    """Build a dictionary of events indexed by stream.
-
-    The events of interest have a 'Serial' argument which represents the
-    stream ID. The 'Serial' argument identifies the local or remote nature of
-    the stream with a least significant bit  of 0 or 1 as well as the hash
-    value of the video track's URL. So stream::=hash(0|1} . The method will
-    then list the events of the same stream in a frame_distribution on stream
-    id. Practically speaking remote streams have an odd stream id and local
-    streams have a even stream id.
-    Args:
-      events: Telemetry WebMediaPlayerMs events.
-
-    Returns:
-      A dict of stream IDs mapped to events on that stream.
-    """
-    stream_to_events = {}
-    for event in events:
-      if not self._IsEventValid(event):
-        # This is not a render event, skip it.
-        continue
-      stream = event.args[SERIAL]
-      events_for_stream = stream_to_events.setdefault(stream, [])
-      events_for_stream.append(event)
-
-    return stream_to_events
-
-  def _GetCadence(self, relevant_events):
-    """Calculate the apparent cadence of the rendering.
-
-    In this paragraph I will be using regex notation. What is intended by the
-    word cadence is a sort of extended instantaneous 'Cadence' (thus not
-    necessarily periodic). Just as an example, a normal 'Cadence' could be
-    something like [2 3] which means possibly an observed frame persistence
-    progression of [{2 3}+] for an ideal 20FPS video source. So what we are
-    calculating here is the list of frame persistence, kind of a
-    'Proto-Cadence', but cadence is shorter so we abuse the word.
-
-    Args:
-      relevant_events: list of Telemetry events.
-
-    Returns:
-      a list of frame persistence values.
-    """
-    cadence = []
-    frame_persistence = 0
-    old_ideal_render = 0
-    for event in relevant_events:
-      if not self._IsEventValid(event):
-        # This event is not a render event so skip it.
-        continue
-      if event.args[IDEAL_RENDER_INSTANT] == old_ideal_render:
-        frame_persistence += 1
-      else:
-        cadence.append(frame_persistence)
-        frame_persistence = 1
-        old_ideal_render = event.args[IDEAL_RENDER_INSTANT]
-    cadence.append(frame_persistence)
-    cadence.pop(0)
-    return cadence
-
-  def _GetSourceToOutputDistribution(self, cadence):
-    """Create distribution for the cadence frame display values.
-
-    If the overall display distribution is A1:A2:..:An, this will tell us how
-    many times a frame stays displayed during Ak*VSYNC_DURATION, also known as
-    'source to output' distribution. Or in other terms:
-    a distribution B::= let C be the cadence, B[k]=p with k in Unique(C)
-    and p=Card(k in C).
-
-    Args:
-      cadence: list of frame persistence values.
-
-    Returns:
-      a dictionary containing the distribution
-    """
-    frame_distribution = {}
-    for ticks in cadence:
-      ticks_so_far = frame_distribution.setdefault(ticks, 0)
-      frame_distribution[ticks] = ticks_so_far + 1
-    return frame_distribution
-
-  def _GetFpsFromCadence(self, frame_distribution):
-    """Calculate the apparent FPS from frame distribution.
-
-    Knowing the display frequency and the frame distribution, it is possible to
-    calculate the video apparent frame rate as played by WebMediaPlayerMs
-    module.
-
-    Args:
-      frame_distribution: the source to output distribution.
-
-    Returns:
-      the video apparent frame rate.
-    """
-    number_frames = sum(frame_distribution.values())
-    number_vsyncs = sum([ticks * frame_distribution[ticks]
-       for ticks in frame_distribution])
-    mean_ratio = float(number_vsyncs) / number_frames
-    return DISPLAY_HERTZ / mean_ratio
-
-  def _GetFrozenFramesReports(self, frame_distribution):
-    """Find evidence of frozen frames in distribution.
-
-    For simplicity we count as freezing the frames that appear at least five
-    times in a row counted from 'Ideal Render Instant' perspective. So let's
-    say for 1 source frame, we rendered 6 frames, then we consider 5 of these
-    rendered frames as frozen. But we mitigate this by saying anything under
-    5 frozen frames will not be counted as frozen.
-
-    Args:
-      frame_distribution: the source to output distribution.
-
-    Returns:
-      a list of dicts whose keys are ('frozen_frames', 'occurrences').
-    """
-    frozen_frames = []
-    frozen_frame_vsyncs = [ticks for ticks in frame_distribution if ticks >=
-        FROZEN_THRESHOLD]
-    for frozen_frames_vsync in frozen_frame_vsyncs:
-      logging.debug('%s frames not updated after %s vsyncs',
-          frame_distribution[frozen_frames_vsync], frozen_frames_vsync)
-      frozen_frames.append(
-          {'frozen_frames': frozen_frames_vsync - 1,
-           'occurrences': frame_distribution[frozen_frames_vsync]})
-    return frozen_frames
-
-  def _FrozenPenaltyWeight(self, number_frozen_frames):
-    """Returns the weighted penalty for a number of frozen frames.
-
-    As mentioned earlier, we count for frozen anything above 6 vsync display
-    duration for the same 'Initial Render Instant', which is five frozen
-    frames.
-
-    Args:
-      number_frozen_frames: number of frozen frames.
-
-    Returns:
-      the penalty weight (int) for that number of frozen frames.
-    """
-
-    penalty = {
-      0: 0,
-      1: 0,
-      2: 0,
-      3: 0,
-      4: 0,
-      5: 1,
-      6: 5,
-      7: 15,
-      8: 25
-    }
-    weight = penalty.get(number_frozen_frames, 8 * (number_frozen_frames - 4))
-    return weight
-
-  def _IsRemoteStream(self, stream):
-    """Check if stream is remote."""
-    return stream % 2
-
-  def _GetDrifTimeStats(self, relevant_events, cadence):
-    """Get the drift time statistics.
-
-    This method will calculate drift_time stats, that is to say :
-    drift_time::= list(actual render begin - ideal render).
-    rendering_length error::= the rendering length error.
-
-    Args:
-      relevant_events: events to get drift times stats from.
-      cadence: list of frame persistence values.
-
-    Returns:
-      a tuple of (drift_time, rendering_length_error).
-    """
-    drift_time = []
-    old_ideal_render = 0
-    discrepancy = []
-    index = 0
-    for event in relevant_events:
-      current_ideal_render = event.args[IDEAL_RENDER_INSTANT]
-      if current_ideal_render == old_ideal_render:
-        # Skip to next event because we're looking for a source frame.
-        continue
-      actual_render_begin = event.args[ACTUAL_RENDER_BEGIN]
-      drift_time.append(actual_render_begin - current_ideal_render)
-      discrepancy.append(abs(current_ideal_render - old_ideal_render
-          - VSYNC_DURATION * cadence[index]))
-      old_ideal_render = current_ideal_render
-      index += 1
-    discrepancy.pop(0)
-    last_ideal_render = relevant_events[-1].args[IDEAL_RENDER_INSTANT]
-    first_ideal_render = relevant_events[0].args[IDEAL_RENDER_INSTANT]
-    rendering_length_error = 100.0 * (sum([x for x in discrepancy]) /
-        (last_ideal_render - first_ideal_render))
-
-    return drift_time, rendering_length_error
-
-  def _GetSmoothnessStats(self, norm_drift_time):
-    """Get the smoothness stats from the normalized drift time.
-
-    This method will calculate the smoothness score, along with the percentage
-    of frames badly out of sync and the percentage of frames out of sync. To be
-    considered badly out of sync, a frame has to have missed rendering by at
-    least 2*VSYNC_DURATION. To be considered out of sync, a frame has to have
-    missed rendering by at least one VSYNC_DURATION.
-    The smoothness score is a measure of how out of sync the frames are.
-
-    Args:
-      norm_drift_time: normalized drift time.
-
-    Returns:
-      a tuple of (percent_badly_oos, percent_out_of_sync, smoothness_score)
-    """
-    # How many times is a frame later/earlier than T=2*VSYNC_DURATION. Time is
-    # in microseconds.
-    frames_severely_out_of_sync = len(
-        [x for x in norm_drift_time if abs(x) > 2 * VSYNC_DURATION])
-    percent_badly_oos = (
-        100.0 * frames_severely_out_of_sync / len(norm_drift_time))
-
-    # How many times is a frame later/earlier than VSYNC_DURATION.
-    frames_out_of_sync = len(
-        [x for x in norm_drift_time if abs(x) > VSYNC_DURATION])
-    percent_out_of_sync = (
-        100.0 * frames_out_of_sync / len(norm_drift_time))
-
-    frames_oos_only_once = frames_out_of_sync - frames_severely_out_of_sync
-
-    # Calculate smoothness metric. From the formula, we can see that smoothness
-    # score can be negative.
-    smoothness_score = 100.0 - 100.0 * (frames_oos_only_once +
-        SEVERITY * frames_severely_out_of_sync) / len(norm_drift_time)
-
-    # Minimum smoothness_score value allowed is zero.
-    if smoothness_score < 0:
-      smoothness_score = 0
-
-    return (percent_badly_oos, percent_out_of_sync, smoothness_score)
-
-  def _GetFreezingScore(self, frame_distribution):
-    """Get the freezing score."""
-
-    # The freezing score is based on the source to output distribution.
-    number_vsyncs = sum([n * frame_distribution[n]
-        for n in frame_distribution])
-    frozen_frames = self._GetFrozenFramesReports(frame_distribution)
-
-    # Calculate freezing metric.
-    # Freezing metric can be negative if things are really bad. In that case we
-    # change it to zero as minimum valud.
-    freezing_score = 100.0
-    for frozen_report in frozen_frames:
-      weight = self._FrozenPenaltyWeight(frozen_report['frozen_frames'])
-      freezing_score -= (
-          100.0 * frozen_report['occurrences'] / number_vsyncs * weight)
-    if freezing_score < 0:
-      freezing_score = 0
-
-    return freezing_score
-
-  def GetTimeStats(self):
-    """Calculate time stamp stats for all remote stream events."""
-    stats = {}
-    for stream, relevant_events in self.stream_to_events.iteritems():
-      if len(relevant_events) == 1:
-        logging.debug('Found a stream=%s with just one event', stream)
-        continue
-      if not self._IsRemoteStream(stream):
-        logging.info('Skipping processing of local stream: %s', stream)
-        continue
-
-      cadence = self._GetCadence(relevant_events)
-      if not cadence:
-        stats = TimeStats()
-        stats.invalid_data = True
-        return stats
-
-      frame_distribution = self._GetSourceToOutputDistribution(cadence)
-      fps = self._GetFpsFromCadence(frame_distribution)
-
-      drift_time_stats = self._GetDrifTimeStats(relevant_events, cadence)
-      (drift_time, rendering_length_error) = drift_time_stats
-
-      # Drift time normalization.
-      mean_drift_time = statistics.ArithmeticMean(drift_time)
-      norm_drift_time = [abs(x - mean_drift_time) for x in drift_time]
-
-      smoothness_stats = self._GetSmoothnessStats(norm_drift_time)
-      (percent_badly_oos, percent_out_of_sync,
-          smoothness_score) = smoothness_stats
-
-      freezing_score = self._GetFreezingScore(frame_distribution)
-
-      stats = TimeStats(drift_time=drift_time,
-          percent_badly_out_of_sync=percent_badly_oos,
-          percent_out_of_sync=percent_out_of_sync,
-          smoothness_score=smoothness_score, freezing_score=freezing_score,
-          rendering_length_error=rendering_length_error, fps=fps,
-          frame_distribution=frame_distribution)
-    return stats
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_stats_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_stats_unittest.py
deleted file mode 100644
index 15e1035..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_stats_unittest.py
+++ /dev/null
@@ -1,271 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-
-from telemetry.web_perf.metrics import webrtc_rendering_stats as stats_helper
-
-
-class FakeEvent(object):
-  """Fake event class to mock rendering events."""
-
-  def __init__(self, **kwargs):
-    """Initializer for the fake WebMediaPlayerMS::UpdateCurrentFrame events.
-
-    The WebMediaPlayerMsRenderingStats only cares about actual render begin,
-    actual render end, ideal render instant and serial fields of the events.
-    So we only define these four fields here in this fake event class.
-    This method is written so as to take whatever valid parameters from the
-    event definition. It can also be used to craft incomplete events.
-
-    Args:
-      kwargs::= dict('actual_begin', 'actual_end', 'ideal_instant', 'serial').
-    """
-    self.args = {}
-    name_map = {
-        'Actual Render Begin': 'actual_begin',
-        'Actual Render End': 'actual_end',
-        'Ideal Render Instant': 'ideal_instant',
-        'Serial': 'serial'}
-    for internal_name, external_name in name_map.iteritems():
-      if external_name in kwargs:
-        self.args[internal_name] = kwargs[external_name]
-
-
-class WebMediaPlayerMsRenderingStatsTest(unittest.TestCase):
-
-  def setUp(self):
-    # A local stream id always has an even number.
-    # A remote stream id always has an odd number.
-    self.local_stream = 136390988
-    self.remote_stream = 118626165
-
-  def testInitialization(self):
-    event_local_stream = FakeEvent(actual_begin=1655987203306,
-        actual_end=1655987219972, ideal_instant=1655987154324,
-        serial=self.local_stream)
-
-    event_remote_stream = FakeEvent(actual_begin=1655987203306,
-        actual_end=1655987219972, ideal_instant=1655987167999,
-        serial=self.remote_stream)
-
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats(
-        [event_local_stream, event_remote_stream])
-
-    self.assertEqual(2, len(stats_parser.stream_to_events))
-
-    self.assertEqual(event_local_stream.args,
-        stats_parser.stream_to_events[self.local_stream][0].args)
-
-    self.assertEqual(event_remote_stream.args,
-        stats_parser.stream_to_events[self.remote_stream][0].args)
-
-  def testInvalidEvents(self):
-    event_missing_serial = FakeEvent(actual_begin=1655987244074,
-        actual_end=1655987260740, ideal_instant=1655987204839)
-
-    event_missing_actual_begin = FakeEvent(actual_end=1655987260740,
-        ideal_instant=1655987217999, serial=self.local_stream)
-
-    event_missing_actual_end = FakeEvent(actual_end=1655987260740,
-        ideal_instant=1655987217999, serial=self.remote_stream)
-
-    event_missing_ideal_instant = FakeEvent(actual_begin=1655987260740,
-        actual_end=1655987277406, serial=self.remote_stream)
-
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats(
-        [event_missing_serial, event_missing_actual_begin,
-         event_missing_actual_end, event_missing_ideal_instant])
-
-    self.assertEqual(0, len(stats_parser.stream_to_events))
-
-  def _GetFakeEvents(self):
-    fake_events = [
-        FakeEvent(actual_begin=1663780195583, actual_end=1663780212249,
-            ideal_instant=1663780179998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780212249, actual_end=1663780228915,
-            ideal_instant=1663780179998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780228915, actual_end=1663780245581,
-            ideal_instant=1663780197998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780245581, actual_end=1663780262247,
-            ideal_instant=1663780215998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780262247, actual_end=1663780278913,
-            ideal_instant=1663780215998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780278913, actual_end=1663780295579,
-            ideal_instant=1663780254998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780295579, actual_end=1663780312245,
-            ideal_instant=1663780254998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780312245, actual_end=1663780328911,
-           ideal_instant=1663780254998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780328911, actual_end=1663780345577,
-           ideal_instant=1663780310998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780345577, actual_end=1663780362243,
-            ideal_instant=1663780310998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780362243, actual_end=1663780378909,
-            ideal_instant=1663780310998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780378909, actual_end=1663780395575,
-            ideal_instant=1663780361998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780395575, actual_end=1663780412241,
-            ideal_instant=1663780361998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780412241, actual_end=1663780428907,
-            ideal_instant=1663780361998, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780428907, actual_end=1663780445573,
-            ideal_instant=1663780412998, serial=self.remote_stream)]
-
-    return fake_events
-
-  def _GetCorruptEvents(self):
-    # The events below are corrupt data because the |ideal_instant|
-    # parameter is zero, which makes all computation meaningless.
-    # Indeed, the ideal_instant (aka Ideal Render Instant) indicates
-    # when the frame should be rendered ideally.
-    corrupt_events = [
-        FakeEvent(actual_begin=1663780195583, actual_end=1663780212249,
-            ideal_instant=0, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780212249, actual_end=1663780228915,
-            ideal_instant=0, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780228915, actual_end=1663780245581,
-            ideal_instant=0, serial=self.remote_stream),
-        FakeEvent(actual_begin=1663780245581, actual_end=1663780262247,
-            ideal_instant=0, serial=self.remote_stream)]
-    return corrupt_events
-
-  def testGetCadence(self):
-    fake_events = self._GetFakeEvents()
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats(fake_events)
-    # The events defined in _GetFakeEvents above show that the first source
-    # framee of ideal_instant=1663780179998 is rendered twice, then
-    # the second source frame of ideal_instant=1663780197998 is rendered once
-    # the third source frame of  ideal_instant=1663780215998 is rendered twice
-    # and so on. The expected cadence will therefore be [2 1 2 etc..]
-    expected_cadence = [2, 1, 2, 3, 3, 3, 1]
-    self.assertEqual(expected_cadence, stats_parser._GetCadence(fake_events))
-
-  def testGetSourceToOutputDistribution(self):
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    cadence = [2, 1, 2, 3, 3, 3, 1]
-    expected_frame_distribution = {1: 2, 2: 2, 3: 3}
-    self.assertEqual(expected_frame_distribution,
-        stats_parser._GetSourceToOutputDistribution(cadence))
-
-  def testGetFpsFromCadence(self):
-    frame_distribution = {1: 2, 2: 2, 3: 3}
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    expected_frame_rate = 28.0
-    self.assertEqual(expected_frame_rate,
-        stats_parser._GetFpsFromCadence(frame_distribution))
-
-  def testGetFrozenFramesReports(self):
-    frame_distribution = {1: 2, 2: 2, 3: 569, 6: 1}
-    expected_frozen_reports = [{'frozen_frames': 5, 'occurrences': 1}]
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    self.assertEqual(expected_frozen_reports,
-        stats_parser._GetFrozenFramesReports(frame_distribution))
-
-  def testIsRemoteStream(self):
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    self.assertTrue(stats_parser._IsRemoteStream(self.remote_stream))
-
-  def testGetDrifTimeStats(self):
-    fake_events = self._GetFakeEvents()
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    cadence = stats_parser._GetCadence(fake_events)
-    expected_drift_time = [15585, 30917, 29583, 23915, 17913, 16911, 15909]
-    expected_rendering_length_error = 29.613733905579398
-
-    self.assertEqual((expected_drift_time, expected_rendering_length_error),
-        stats_parser._GetDrifTimeStats(fake_events, cadence))
-
-  def testGetSmoothnessStats(self):
-    norm_drift_time = [5948.2857142857138, 9383.7142857142862,
-        8049.7142857142862, 2381.7142857142862, 3620.2857142857138,
-        4622.2857142857138, 5624.2857142857138]
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    expected_percent_badly_oos = 0.0
-    expected_percent_out_of_sync = 0.0
-    expected_smoothness_score = 100.0
-    expected_smoothness_stats = (expected_percent_badly_oos,
-        expected_percent_out_of_sync, expected_smoothness_score)
-
-    self.assertEqual(expected_smoothness_stats,
-        stats_parser._GetSmoothnessStats(norm_drift_time))
-
-  def testNegativeSmoothnessScoreChangedToZero(self):
-    norm_drift_time = [15948.285714285714, 9383.714285714286,
-        28049.714285714286, 72381.71428571429, 3620.2857142857138,
-        4622.285714285714, 35624.28571428572]
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    expected_percent_badly_oos = 28.571428571428573
-    expected_percent_out_of_sync = 42.857142857142854
-    expected_smoothness_score = 0.0
-    expected_smoothness_stats = (expected_percent_badly_oos,
-        expected_percent_out_of_sync, expected_smoothness_score)
-
-    self.assertEqual(expected_smoothness_stats,
-        stats_parser._GetSmoothnessStats(norm_drift_time))
-
-  def testGetFreezingScore(self):
-    frame_distribution = {1: 2, 2: 2, 3: 569, 6: 1}
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    expected_freezing_score = 99.94182664339732
-    self.assertEqual(expected_freezing_score,
-        stats_parser._GetFreezingScore(frame_distribution))
-
-  def testNegativeFrezingScoreChangedToZero(self):
-    frame_distribution = {1: 2, 2: 2, 3: 2, 8:100}
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats([])
-    self.assertEqual(0.0, stats_parser._GetFreezingScore(frame_distribution))
-
-  def testGetTimeStats(self):
-    fake_events = self._GetFakeEvents()
-    expected_frame_dist = {1: 2, 2: 2, 3: 3}
-    expected_frame_rate = 28.0
-    expected_drift_time = [15585, 30917, 29583, 23915, 17913, 16911, 15909]
-    expected_rendering_length_error = 29.613733905579398
-    expected_percent_badly_oos = 0.0
-    expected_percent_out_of_sync = 0.0
-    expected_smoothness_score = 100.0
-    expected_freezing_score = 100.0
-
-    stats_cls = stats_helper.WebMediaPlayerMsRenderingStats
-
-    stats_parser = stats_cls(fake_events)
-
-    expected_stats = stats_helper.TimeStats(
-        drift_time=expected_drift_time,
-        percent_badly_out_of_sync=expected_percent_badly_oos,
-        percent_out_of_sync=expected_percent_out_of_sync,
-        smoothness_score=expected_smoothness_score,
-        freezing_score=expected_freezing_score,
-        rendering_length_error=expected_rendering_length_error,
-        fps=expected_frame_rate,
-        frame_distribution=expected_frame_dist)
-
-    stats = stats_parser.GetTimeStats()
-
-    self.assertEqual(expected_stats.drift_time, stats.drift_time)
-    self.assertEqual(expected_stats.percent_badly_out_of_sync,
-        stats.percent_badly_out_of_sync)
-    self.assertEqual(expected_stats.percent_out_of_sync,
-        stats.percent_out_of_sync)
-    self.assertEqual(expected_stats.smoothness_score, stats.smoothness_score)
-    self.assertEqual(expected_stats.freezing_score, stats.freezing_score)
-    self.assertEqual(expected_stats.rendering_length_error,
-        stats.rendering_length_error)
-    self.assertEqual(expected_stats.fps, stats.fps)
-    self.assertEqual(expected_stats.frame_distribution,
-        stats.frame_distribution)
-
-  def testCorruptData(self):
-    corrupt_events = self._GetCorruptEvents()
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats(corrupt_events)
-    stats = stats_parser.GetTimeStats()
-    self.assertTrue(stats.invalid_data)
-    self.assertIsNone(stats.drift_time)
-    self.assertIsNone(stats.percent_badly_out_of_sync)
-    self.assertIsNone(stats.percent_out_of_sync)
-    self.assertIsNone(stats.smoothness_score)
-    self.assertIsNone(stats.freezing_score)
-    self.assertIsNone(stats.rendering_length_error)
-    self.assertIsNone(stats.fps)
-    self.assertIsNone(stats.frame_distribution)
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_timeline.py b/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_timeline.py
deleted file mode 100644
index 062ef09..0000000
--- a/catapult/telemetry/telemetry/web_perf/metrics/webrtc_rendering_timeline.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.value import list_of_scalar_values
-from telemetry.value import scalar
-from telemetry.value import improvement_direction
-from telemetry.web_perf.metrics import timeline_based_metric
-from telemetry.web_perf.metrics import webrtc_rendering_stats as stats_helper
-
-WEB_MEDIA_PLAYER_MS_EVENT = 'WebMediaPlayerMS::UpdateCurrentFrame'
-
-
-class WebRtcRenderingTimelineMetric(timeline_based_metric.TimelineBasedMetric):
-  """WebrtcRenderingTimelineMetric calculates metric for WebMediaPlayerMS.
-
-  The following metrics are added to the results:
-    WebRTCRendering_drift_time us
-    WebRTCRendering_percent_badly_out_of_sync %
-    WebRTCRendering_percent_out_of_sync %
-    WebRTCRendering_fps FPS
-    WebRTCRendering_smoothness_score %
-    WebRTCRendering_freezing_score %
-    WebRTCRendering_rendering_length_error %
-  """
-
-  def __init__(self):
-    super(WebRtcRenderingTimelineMetric, self).__init__()
-
-  @staticmethod
-  def IsMediaPlayerMSEvent(event):
-    """Verify that the event is a webmediaplayerMS event."""
-    return event.name == WEB_MEDIA_PLAYER_MS_EVENT
-
-  def AddResults(self, model, renderer_thread, interactions, results):
-    """Adding metrics to the results."""
-    assert interactions
-    found_events = []
-    for event in renderer_thread.parent.IterAllEvents(
-        event_predicate=self.IsMediaPlayerMSEvent):
-      if timeline_based_metric.IsEventInInteractions(event, interactions):
-        found_events.append(event)
-    stats_parser = stats_helper.WebMediaPlayerMsRenderingStats(found_events)
-    rendering_stats = stats_parser.GetTimeStats()
-    none_reason = None
-    if not rendering_stats:
-      # Create a TimeStats object whose members have None values.
-      rendering_stats = stats_helper.TimeStats()
-      none_reason = 'No WebMediaPlayerMS::UpdateCurrentFrame event found'
-    elif rendering_stats.invalid_data:
-      # Throw away the data.
-      rendering_stats = stats_helper.TimeStats()
-      none_reason = 'WebMediaPlayerMS data is corrupted.'
-    results.AddValue(list_of_scalar_values.ListOfScalarValues(
-        results.current_page,
-        'WebRTCRendering_drift_time',
-        'us',
-        rendering_stats.drift_time,
-        important=True,
-        description='Drift time for a rendered frame',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.DOWN,
-        none_value_reason=none_reason))
-
-    results.AddValue(scalar.ScalarValue(
-        results.current_page,
-        'WebRTCRendering_percent_badly_out_of_sync',
-        '%',
-        rendering_stats.percent_badly_out_of_sync,
-        important=True,
-        description='Percentage of frame which drifted more than 2 VSYNC',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.DOWN,
-        none_value_reason=none_reason))
-
-    results.AddValue(scalar.ScalarValue(
-        results.current_page,
-        'WebRTCRendering_percent_out_of_sync',
-        '%',
-        rendering_stats.percent_out_of_sync,
-        important=True,
-        description='Percentage of frame which drifted more than 1 VSYNC',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.DOWN,
-        none_value_reason=none_reason))
-
-    # I removed the frame distribution list from stats as it is not a metric,
-    # rather it is the underlying data. Also there is no sense of improvement
-    # direction for frame distribution.
-
-    results.AddValue(scalar.ScalarValue(
-        results.current_page,
-        'WebRTCRendering_fps',
-        'fps',
-        rendering_stats.fps,
-        important=True,
-        description='Calculated Frame Rate of video rendering',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.UP,
-        none_value_reason=none_reason))
-
-    results.AddValue(scalar.ScalarValue(
-        results.current_page,
-        'WebRTCRendering_smoothness_score',
-        '%',
-        rendering_stats.smoothness_score,
-        important=True,
-        description='Smoothness score of rendering',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.UP,
-        none_value_reason=none_reason))
-
-    results.AddValue(scalar.ScalarValue(
-        results.current_page,
-        'WebRTCRendering_freezing_score',
-        '%',
-        rendering_stats.freezing_score,
-        important=True,
-        description='Freezing score of rendering',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.UP,
-        none_value_reason=none_reason))
-
-    results.AddValue(scalar.ScalarValue(
-        results.current_page,
-        'WebRTCRendering_rendering_length_error',
-        '%',
-        rendering_stats.rendering_length_error,
-        important=True,
-        description='Rendering length error rate',
-        tir_label=interactions[0].label,
-        improvement_direction=improvement_direction.DOWN,
-        none_value_reason=none_reason))
diff --git a/catapult/telemetry/telemetry/web_perf/smooth_gesture_util.py b/catapult/telemetry/telemetry/web_perf/smooth_gesture_util.py
deleted file mode 100644
index 0d0d453..0000000
--- a/catapult/telemetry/telemetry/web_perf/smooth_gesture_util.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import copy
-
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-
-def GetAdjustedInteractionIfContainGesture(timeline, interaction_record):
-  """ Returns a new interaction record if interaction_record contains geture
-  whose time range that overlaps with interaction_record's range. If not,
-  returns a clone of original interaction_record.
-  The synthetic gesture controller inserts a trace marker to precisely
-  demarcate when the gesture was running. We check for overlap, not inclusion,
-  because gesture_actions can start/end slightly outside the telemetry markers
-  on Windows. This problem is probably caused by a race condition between
-  the browser and renderer process submitting the trace events for the
-  markers.
-  """
-  # Only adjust the range for gestures.
-  if not interaction_record.label.startswith('Gesture_'):
-    return copy.copy(interaction_record)
-  gesture_events = [
-    ev for ev
-    in timeline.IterAllAsyncSlicesOfName('SyntheticGestureController::running')
-    if ev.parent_slice is None and
-    ev.start <= interaction_record.end and
-    ev.end >= interaction_record.start]
-  if len(gesture_events) == 0:
-    return copy.copy(interaction_record)
-  if len(gesture_events) > 1:
-    raise Exception('More than one possible synthetic gesture marker found in '
-                    'interaction_record %s.' % interaction_record.label)
-  return tir_module.TimelineInteractionRecord(
-    interaction_record.label, gesture_events[0].start,
-    gesture_events[0].end, gesture_events[0],
-    interaction_record._flags)  # pylint: disable=protected-access
diff --git a/catapult/telemetry/telemetry/web_perf/smooth_gesture_util_unittest.py b/catapult/telemetry/telemetry/web_perf/smooth_gesture_util_unittest.py
deleted file mode 100644
index 07bf4fd..0000000
--- a/catapult/telemetry/telemetry/web_perf/smooth_gesture_util_unittest.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import time
-import unittest
-
-from telemetry import decorators
-from telemetry.page import page as page_module
-from telemetry.page import legacy_page_test
-from telemetry.testing import page_test_test_case
-from telemetry.timeline import async_slice
-from telemetry.timeline import model as model_module
-from telemetry.timeline import tracing_config
-from telemetry.web_perf import smooth_gesture_util as sg_util
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-
-class SmoothGestureUtilTest(unittest.TestCase):
-  def testGetAdjustedInteractionIfContainGesture(self):
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    renderer_main.name = 'CrRendererMain'
-
-    #      [          X          ]                   [   Y  ]
-    #      [  sub_async_slice_X  ]
-    #          [   record_1]
-    #          [   record_6]
-    #  [  record_2 ]          [ record_3 ]
-    #  [           record_4              ]
-    #                                [ record_5 ]
-    #
-    # Note: X and Y are async slice with name
-    # SyntheticGestureController::running
-
-    async_slice_X = async_slice.AsyncSlice(
-      'X', 'SyntheticGestureController::running', 10, duration=20,
-      start_thread=renderer_main, end_thread=renderer_main)
-
-    sub_async_slice_X = async_slice.AsyncSlice(
-      'X', 'SyntheticGestureController::running', 10, duration=20,
-      start_thread=renderer_main, end_thread=renderer_main)
-    sub_async_slice_X.parent_slice = async_slice_X
-    async_slice_X.AddSubSlice(sub_async_slice_X)
-
-    async_slice_Y = async_slice.AsyncSlice(
-      'X', 'SyntheticGestureController::running', 60, duration=20,
-      start_thread=renderer_main, end_thread=renderer_main)
-
-    renderer_main.AddAsyncSlice(async_slice_X)
-    renderer_main.AddAsyncSlice(async_slice_Y)
-
-    model.FinalizeImport(shift_world_to_zero=False)
-
-    record_1 = tir_module.TimelineInteractionRecord('Gesture_included', 15, 25)
-    record_2 = tir_module.TimelineInteractionRecord(
-      'Gesture_overlapped_left', 5, 25)
-    record_3 = tir_module.TimelineInteractionRecord(
-      'Gesture_overlapped_right', 25, 35)
-    record_4 = tir_module.TimelineInteractionRecord(
-      'Gesture_containing', 5, 35)
-    record_5 = tir_module.TimelineInteractionRecord(
-      'Gesture_non_overlapped', 35, 45)
-    record_6 = tir_module.TimelineInteractionRecord('Action_included', 15, 25)
-
-    adjusted_record_1 = sg_util.GetAdjustedInteractionIfContainGesture(
-      model, record_1)
-    self.assertEquals(adjusted_record_1.start, 10)
-    self.assertEquals(adjusted_record_1.end, 30)
-    self.assertTrue(adjusted_record_1 is not record_1)
-
-    adjusted_record_2 = sg_util.GetAdjustedInteractionIfContainGesture(
-      model, record_2)
-    self.assertEquals(adjusted_record_2.start, 10)
-    self.assertEquals(adjusted_record_2.end, 30)
-
-    adjusted_record_3 = sg_util.GetAdjustedInteractionIfContainGesture(
-      model, record_3)
-    self.assertEquals(adjusted_record_3.start, 10)
-    self.assertEquals(adjusted_record_3.end, 30)
-
-    adjusted_record_4 = sg_util.GetAdjustedInteractionIfContainGesture(
-      model, record_4)
-    self.assertEquals(adjusted_record_4.start, 10)
-    self.assertEquals(adjusted_record_4.end, 30)
-
-    adjusted_record_5 = sg_util.GetAdjustedInteractionIfContainGesture(
-      model, record_5)
-    self.assertEquals(adjusted_record_5.start, 35)
-    self.assertEquals(adjusted_record_5.end, 45)
-    self.assertTrue(adjusted_record_5 is not record_5)
-
-    adjusted_record_6 = sg_util.GetAdjustedInteractionIfContainGesture(
-      model, record_6)
-    self.assertEquals(adjusted_record_6.start, 15)
-    self.assertEquals(adjusted_record_6.end, 25)
-    self.assertTrue(adjusted_record_6 is not record_6)
-
-
-class ScrollingPage(page_module.Page):
-  def __init__(self, url, page_set, base_dir):
-    super(ScrollingPage, self).__init__(url, page_set, base_dir)
-
-  def RunPageInteractions(self, action_runner):
-    with action_runner.CreateGestureInteraction('ScrollAction'):
-      # Add 0.5s gap between when Gesture records are issued to when we actually
-      # scroll the page.
-      time.sleep(0.5)
-      action_runner.ScrollPage()
-      time.sleep(0.5)
-
-
-class SmoothGestureTest(page_test_test_case.PageTestTestCase):
-
-  @decorators.Disabled('chromeos')  # crbug.com/483212
-  @decorators.Isolated  # Needed because of py_trace_event
-  def testSmoothGestureAdjusted(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddStory(ScrollingPage(
-      'file://scrollable_page.html', ps, base_dir=ps.base_dir))
-    models = []
-    tab_ids = []
-    class ScrollingGestureTestMeasurement(legacy_page_test.LegacyPageTest):
-      def __init__(self):
-        # pylint: disable=bad-super-call
-        super(ScrollingGestureTestMeasurement, self).__init__()
-
-      def WillNavigateToPage(self, page, tab):
-        del page  # unused
-        config = tracing_config.TracingConfig()
-        config.enable_chrome_trace = True
-        tab.browser.platform.tracing_controller.StartTracing(config)
-
-      def ValidateAndMeasurePage(self, page, tab, results):
-        del page, results  # unused
-        models.append(model_module.TimelineModel(
-          tab.browser.platform.tracing_controller.StopTracing()))
-        tab_ids.append(tab.id)
-
-    self.RunMeasurement(ScrollingGestureTestMeasurement(), ps)
-    timeline_model = models[0]
-    renderer_thread = timeline_model.GetRendererThreadFromTabId(
-        tab_ids[0])
-    smooth_record = None
-    for e in renderer_thread.async_slices:
-      if tir_module.IsTimelineInteractionRecord(e.name):
-        smooth_record = tir_module.TimelineInteractionRecord.FromAsyncEvent(e)
-    self.assertIsNotNone(smooth_record)
-    adjusted_smooth_gesture = (
-      sg_util.GetAdjustedInteractionIfContainGesture(
-        timeline_model, smooth_record))
-    # Test that the scroll gesture starts at at least 500ms after the start of
-    # the interaction record and ends at at least 500ms before the end of
-    # interaction record.
-    self.assertLessEqual(
-      500, adjusted_smooth_gesture.start - smooth_record.start)
-    self.assertLessEqual(
-      500, smooth_record.end - adjusted_smooth_gesture.end)
diff --git a/catapult/telemetry/telemetry/web_perf/story_test.py b/catapult/telemetry/telemetry/web_perf/story_test.py
deleted file mode 100644
index 2ed65a4..0000000
--- a/catapult/telemetry/telemetry/web_perf/story_test.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class Failure(Exception):
-  """StoryTest Exception raised when an undesired but designed-for problem."""
-
-
-class StoryTest(object):
-  """A class for creating story tests.
-
-  The overall test run control flow follows this order:
-    test.WillRunStory
-    state.WillRunStory
-    state.RunStory
-    test.Measure
-    state.DidRunStory
-    test.DidRunStory
-  """
-
-  def WillRunStory(self, platform):
-    """Override to do any action before running the story.
-
-    This is run before state.WillRunStory.
-    Args:
-      platform: The platform that the story will run on.
-    """
-    raise NotImplementedError()
-
-  def Measure(self, platform, results):
-    """Override to take the measurement.
-
-    This is run only if state.RunStory is successful.
-    Args:
-      platform: The platform that the story will run on.
-      results: The results of running the story.
-    """
-    raise NotImplementedError()
-
-  def DidRunStory(self, platform):
-    """Override to do any action after running the story, e.g., clean up.
-
-    This is run after state.DidRunStory. And this is always called even if the
-    test run failed.
-    Args:
-      platform: The platform that the story will run on.
-    """
-    raise NotImplementedError()
diff --git a/catapult/telemetry/telemetry/web_perf/timeline_based_measurement.py b/catapult/telemetry/telemetry/web_perf/timeline_based_measurement.py
deleted file mode 100644
index 961ed91..0000000
--- a/catapult/telemetry/telemetry/web_perf/timeline_based_measurement.py
+++ /dev/null
@@ -1,358 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import collections
-import logging
-from collections import defaultdict
-
-from tracing.metrics import metric_runner
-
-from telemetry.timeline import chrome_trace_category_filter
-from telemetry.timeline import model as model_module
-from telemetry.timeline import tracing_config
-from telemetry.value import trace
-from telemetry.value import common_value_helpers
-from telemetry.web_perf.metrics import timeline_based_metric
-from telemetry.web_perf.metrics import blob_timeline
-from telemetry.web_perf.metrics import jitter_timeline
-from telemetry.web_perf.metrics import webrtc_rendering_timeline
-from telemetry.web_perf.metrics import gpu_timeline
-from telemetry.web_perf.metrics import indexeddb_timeline
-from telemetry.web_perf.metrics import layout
-from telemetry.web_perf.metrics import smoothness
-from telemetry.web_perf.metrics import text_selection
-from telemetry.web_perf import smooth_gesture_util
-from telemetry.web_perf import story_test
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-# TimelineBasedMeasurement considers all instrumentation as producing a single
-# timeline. But, depending on the amount of instrumentation that is enabled,
-# overhead increases. The user of the measurement must therefore chose between
-# a few levels of instrumentation.
-LOW_OVERHEAD_LEVEL = 'low-overhead'
-DEFAULT_OVERHEAD_LEVEL = 'default-overhead'
-DEBUG_OVERHEAD_LEVEL = 'debug-overhead'
-
-ALL_OVERHEAD_LEVELS = [
-  LOW_OVERHEAD_LEVEL,
-  DEFAULT_OVERHEAD_LEVEL,
-  DEBUG_OVERHEAD_LEVEL,
-]
-
-
-def _GetAllLegacyTimelineBasedMetrics():
-  # TODO(nednguyen): use discovery pattern to return all the instances of
-  # all TimelineBasedMetrics class in web_perf/metrics/ folder.
-  # This cannot be done until crbug.com/460208 is fixed.
-  return (smoothness.SmoothnessMetric(),
-          layout.LayoutMetric(),
-          gpu_timeline.GPUTimelineMetric(),
-          blob_timeline.BlobTimelineMetric(),
-          jitter_timeline.JitterTimelineMetric(),
-          text_selection.TextSelectionMetric(),
-          indexeddb_timeline.IndexedDBTimelineMetric(),
-          webrtc_rendering_timeline.WebRtcRenderingTimelineMetric())
-
-
-class InvalidInteractions(Exception):
-  pass
-
-
-# TODO(nednguyen): Get rid of this results wrapper hack after we add interaction
-# record to telemetry value system (crbug.com/453109)
-class ResultsWrapperInterface(object):
-  def __init__(self):
-    self._tir_label = None
-    self._results = None
-
-  def SetResults(self, results):
-    self._results = results
-
-  def SetTirLabel(self, tir_label):
-    self._tir_label = tir_label
-
-  @property
-  def current_page(self):
-    return self._results.current_page
-
-  def AddValue(self, value):
-    raise NotImplementedError
-
-
-class _TBMResultWrapper(ResultsWrapperInterface):
-  def AddValue(self, value):
-    assert self._tir_label
-    if value.tir_label:
-      assert value.tir_label == self._tir_label
-    else:
-      value.tir_label = self._tir_label
-    self._results.AddValue(value)
-
-
-def _GetRendererThreadsToInteractionRecordsMap(model):
-  threads_to_records_map = defaultdict(list)
-  interaction_labels_of_previous_threads = set()
-  for curr_thread in model.GetAllThreads():
-    for event in curr_thread.async_slices:
-      # TODO(nduca): Add support for page-load interaction record.
-      if tir_module.IsTimelineInteractionRecord(event.name):
-        interaction = tir_module.TimelineInteractionRecord.FromAsyncEvent(event)
-        # Adjust the interaction record to match the synthetic gesture
-        # controller if needed.
-        interaction = (
-            smooth_gesture_util.GetAdjustedInteractionIfContainGesture(
-                model, interaction))
-        threads_to_records_map[curr_thread].append(interaction)
-        if interaction.label in interaction_labels_of_previous_threads:
-          raise InvalidInteractions(
-            'Interaction record label %s is duplicated on different '
-            'threads' % interaction.label)
-    if curr_thread in threads_to_records_map:
-      interaction_labels_of_previous_threads.update(
-        r.label for r in threads_to_records_map[curr_thread])
-
-  return threads_to_records_map
-
-
-class _TimelineBasedMetrics(object):
-  def __init__(self, model, renderer_thread, interaction_records,
-               results_wrapper, metrics):
-    self._model = model
-    self._renderer_thread = renderer_thread
-    self._interaction_records = interaction_records
-    self._results_wrapper = results_wrapper
-    self._all_metrics = metrics
-
-  def AddResults(self, results):
-    interactions_by_label = defaultdict(list)
-    for i in self._interaction_records:
-      interactions_by_label[i.label].append(i)
-
-    for label, interactions in interactions_by_label.iteritems():
-      are_repeatable = [i.repeatable for i in interactions]
-      if not all(are_repeatable) and len(interactions) > 1:
-        raise InvalidInteractions('Duplicate unrepeatable interaction records '
-                                  'on the page')
-      self._results_wrapper.SetResults(results)
-      self._results_wrapper.SetTirLabel(label)
-      self.UpdateResultsByMetric(interactions, self._results_wrapper)
-
-  def UpdateResultsByMetric(self, interactions, wrapped_results):
-    if not interactions:
-      return
-
-    for metric in self._all_metrics:
-      metric.AddResults(self._model, self._renderer_thread,
-                        interactions, wrapped_results)
-
-
-class Options(object):
-  """A class to be used to configure TimelineBasedMeasurement.
-
-  This is created and returned by
-  Benchmark.CreateTimelineBasedMeasurementOptions.
-
-  By default, all the timeline based metrics in telemetry/web_perf/metrics are
-  used (see _GetAllLegacyTimelineBasedMetrics above).
-  To customize your metric needs, use SetTimelineBasedMetrics().
-  """
-
-  def __init__(self, overhead_level=LOW_OVERHEAD_LEVEL):
-    """As the amount of instrumentation increases, so does the overhead.
-    The user of the measurement chooses the overhead level that is appropriate,
-    and the tracing is filtered accordingly.
-
-    overhead_level: Can either be a custom ChromeTraceCategoryFilter object or
-        one of LOW_OVERHEAD_LEVEL, DEFAULT_OVERHEAD_LEVEL or
-        DEBUG_OVERHEAD_LEVEL.
-    """
-    self._config = tracing_config.TracingConfig()
-    self._config.enable_chrome_trace = True
-    self._config.enable_platform_display_trace = False
-
-    if isinstance(overhead_level,
-                  chrome_trace_category_filter.ChromeTraceCategoryFilter):
-      self._config.chrome_trace_config.SetCategoryFilter(overhead_level)
-    elif overhead_level in ALL_OVERHEAD_LEVELS:
-      if overhead_level == LOW_OVERHEAD_LEVEL:
-        self._config.chrome_trace_config.SetLowOverheadFilter()
-      elif overhead_level == DEFAULT_OVERHEAD_LEVEL:
-        self._config.chrome_trace_config.SetDefaultOverheadFilter()
-      else:
-        self._config.chrome_trace_config.SetDebugOverheadFilter()
-    else:
-      raise Exception("Overhead level must be a ChromeTraceCategoryFilter "
-                      "object or valid overhead level string. Given overhead "
-                      "level: %s" % overhead_level)
-
-    self._timeline_based_metrics = None
-    self._legacy_timeline_based_metrics = []
-
-
-  def ExtendTraceCategoryFilter(self, filters):
-    category_filter = self._config.chrome_trace_config.category_filter
-    for new_category_filter in filters:
-      category_filter.AddIncludedCategory(new_category_filter)
-
-  @property
-  def category_filter(self):
-    return self._config.chrome_trace_config.category_filter
-
-  @property
-  def config(self):
-    return self._config
-
-  def AddTimelineBasedMetric(self, metric):
-    assert isinstance(metric, basestring)
-    if self._timeline_based_metrics is None:
-      self._timeline_based_metrics = []
-    self._timeline_based_metrics.append(metric)
-
-  def SetTimelineBasedMetrics(self, metrics):
-    """Sets the new-style (TBMv2) metrics to run.
-
-    Metrics are assumed to live in //tracing/tracing/metrics, so the path you
-    pass in should be relative to that. For example, to specify
-    sample_metric.html, you should pass in ['sample_metric.html'].
-
-    Args:
-      metrics: A list of strings giving metric paths under
-          //tracing/tracing/metrics.
-    """
-    assert isinstance(metrics, list)
-    for metric in metrics:
-      assert isinstance(metric, basestring)
-    self._timeline_based_metrics = metrics
-
-  def GetTimelineBasedMetrics(self):
-    return self._timeline_based_metrics
-
-  def SetLegacyTimelineBasedMetrics(self, metrics):
-    assert isinstance(metrics, collections.Iterable)
-    for m in metrics:
-      assert isinstance(m, timeline_based_metric.TimelineBasedMetric)
-    self._legacy_timeline_based_metrics = metrics
-
-  def GetLegacyTimelineBasedMetrics(self):
-    return self._legacy_timeline_based_metrics
-
-
-class TimelineBasedMeasurement(story_test.StoryTest):
-  """Collects multiple metrics based on their interaction records.
-
-  A timeline based measurement shifts the burden of what metrics to collect onto
-  the story under test. Instead of the measurement
-  having a fixed set of values it collects, the story being tested
-  issues (via javascript) an Interaction record into the user timing API that
-  describing what is happening at that time, as well as a standardized set
-  of flags describing the semantics of the work being done. The
-  TimelineBasedMeasurement object collects a trace that includes both these
-  interaction records, and a user-chosen amount of performance data using
-  Telemetry's various timeline-producing APIs, tracing especially.
-
-  It then passes the recorded timeline to different TimelineBasedMetrics based
-  on those flags. As an example, this allows a single story run to produce
-  load timing data, smoothness data, critical jank information and overall cpu
-  usage information.
-
-  For information on how to mark up a page to work with
-  TimelineBasedMeasurement, refer to the
-  perf.metrics.timeline_interaction_record module.
-
-  Args:
-      options: an instance of timeline_based_measurement.Options.
-      results_wrapper: A class that has the __init__ method takes in
-        the page_test_results object and the interaction record label. This
-        class follows the ResultsWrapperInterface. Note: this class is not
-        supported long term and to be removed when crbug.com/453109 is resolved.
-  """
-  def __init__(self, options, results_wrapper=None):
-    self._tbm_options = options
-    self._results_wrapper = results_wrapper or _TBMResultWrapper()
-
-  def WillRunStory(self, platform):
-    """Configure and start tracing."""
-    if not platform.tracing_controller.IsChromeTracingSupported():
-      raise Exception('Not supported')
-    if self._tbm_options.config.enable_chrome_trace:
-      # Always enable 'blink.console' category for:
-      # 1) Backward compat of chrome clock sync (crbug.com/646925)
-      # 2) Allows users to add trace event through javascript.
-      # Note that blink.console is extremely low-overhead, so this doesn't
-      # affect the tracing overhead budget much.
-      chrome_config = self._tbm_options.config.chrome_trace_config
-      chrome_config.category_filter.AddIncludedCategory('blink.console')
-    platform.tracing_controller.StartTracing(self._tbm_options.config)
-
-  def Measure(self, platform, results):
-    """Collect all possible metrics and added them to results."""
-    platform.tracing_controller.telemetry_info = results.telemetry_info
-    trace_result = platform.tracing_controller.StopTracing()
-    trace_value = trace.TraceValue(results.current_page, trace_result)
-    results.AddValue(trace_value)
-
-    try:
-      if self._tbm_options.GetTimelineBasedMetrics():
-        assert not self._tbm_options.GetLegacyTimelineBasedMetrics(), (
-            'Specifying both TBMv1 and TBMv2 metrics is not allowed.')
-        self._ComputeTimelineBasedMetrics(results, trace_value)
-      else:
-        # Run all TBMv1 metrics if no other metric is specified
-        # (legacy behavior)
-        if not self._tbm_options.GetLegacyTimelineBasedMetrics():
-          logging.warn('Please specify the TBMv1 metrics you are interested in '
-                       'explicitly. This implicit functionality will be removed'
-                       ' on July 17, 2016.')
-          self._tbm_options.SetLegacyTimelineBasedMetrics(
-              _GetAllLegacyTimelineBasedMetrics())
-        self._ComputeLegacyTimelineBasedMetrics(results, trace_result)
-    finally:
-      trace_result.CleanUpAllTraces()
-
-  def DidRunStory(self, platform):
-    """Clean up after running the story."""
-    if platform.tracing_controller.is_tracing_running:
-      platform.tracing_controller.StopTracing()
-
-  def _ComputeTimelineBasedMetrics(self, results, trace_value):
-    metrics = self._tbm_options.GetTimelineBasedMetrics()
-    extra_import_options = {
-      'trackDetailedModelStats': True
-    }
-
-    mre_result = metric_runner.RunMetric(
-        trace_value.filename, metrics, extra_import_options)
-    page = results.current_page
-
-    failure_dicts = mre_result.failures
-    for d in failure_dicts:
-      results.AddValue(
-          common_value_helpers.TranslateMreFailure(d, page))
-
-    results.value_set.extend(mre_result.pairs.get('histograms', []))
-
-    for d in mre_result.pairs.get('scalars', []):
-      results.AddValue(common_value_helpers.TranslateScalarValue(d, page))
-
-  def _ComputeLegacyTimelineBasedMetrics(self, results, trace_result):
-    model = model_module.TimelineModel(trace_result)
-    threads_to_records_map = _GetRendererThreadsToInteractionRecordsMap(model)
-    if (len(threads_to_records_map.values()) == 0 and
-        self._tbm_options.config.enable_chrome_trace):
-      logging.warning(
-          'No timeline interaction records were recorded in the trace. '
-          'This could be caused by console.time() & console.timeEnd() execution'
-          ' failure or the tracing category specified doesn\'t include '
-          'blink.console categories.')
-
-    all_metrics = self._tbm_options.GetLegacyTimelineBasedMetrics()
-
-    for renderer_thread, interaction_records in (
-        threads_to_records_map.iteritems()):
-      meta_metrics = _TimelineBasedMetrics(
-          model, renderer_thread, interaction_records, self._results_wrapper,
-          all_metrics)
-      meta_metrics.AddResults(results)
-
-    for metric in all_metrics:
-      metric.AddWholeTraceResults(model, results)
diff --git a/catapult/telemetry/telemetry/web_perf/timeline_based_measurement_unittest.py b/catapult/telemetry/telemetry/web_perf/timeline_based_measurement_unittest.py
deleted file mode 100644
index 1523bfb..0000000
--- a/catapult/telemetry/telemetry/web_perf/timeline_based_measurement_unittest.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import unittest
-
-from telemetry import story
-from telemetry.internal.results import page_test_results
-from telemetry.page import page as page_module
-from telemetry.timeline import async_slice
-from telemetry.timeline import model as model_module
-from telemetry.value import improvement_direction
-from telemetry.value import scalar
-from telemetry.web_perf.metrics import timeline_based_metric
-from telemetry.web_perf import timeline_based_measurement as tbm_module
-
-
-class FakeSmoothMetric(timeline_based_metric.TimelineBasedMetric):
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    results.AddValue(scalar.ScalarValue(
-        results.current_page, 'FakeSmoothMetric', 'ms', 1,
-        improvement_direction=improvement_direction.DOWN))
-    results.AddValue(scalar.ScalarValue(
-        results.current_page, 'SmoothMetricRecords', 'count',
-        len(interaction_records),
-        improvement_direction=improvement_direction.DOWN))
-
-
-class FakeLoadingMetric(timeline_based_metric.TimelineBasedMetric):
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    results.AddValue(scalar.ScalarValue(
-        results.current_page, 'FakeLoadingMetric', 'ms', 2,
-        improvement_direction=improvement_direction.DOWN))
-    results.AddValue(scalar.ScalarValue(
-        results.current_page, 'LoadingMetricRecords', 'count',
-        len(interaction_records),
-        improvement_direction=improvement_direction.DOWN))
-
-
-class FakeStartupMetric(timeline_based_metric.TimelineBasedMetric):
-
-  def AddResults(self, model, renderer_thread, interaction_records, results):
-    pass
-
-  def AddWholeTraceResults(self, model, results):
-    results.AddValue(scalar.ScalarValue(
-        results.current_page, 'FakeStartupMetric', 'ms', 3,
-        improvement_direction=improvement_direction.DOWN))
-
-
-class TimelineBasedMetricTestData(object):
-
-  def __init__(self, options):
-    self._model = model_module.TimelineModel()
-    renderer_process = self._model.GetOrCreateProcess(1)
-    self._renderer_thread = renderer_process.GetOrCreateThread(2)
-    self._renderer_thread.name = 'CrRendererMain'
-    self._foo_thread = renderer_process.GetOrCreateThread(3)
-    self._foo_thread.name = 'CrFoo'
-
-    self._results_wrapper = tbm_module._TBMResultWrapper()
-    self._results = page_test_results.PageTestResults()
-    self._story_set = None
-    self._threads_to_records_map = None
-    self._tbm_options = options
-
-  @property
-  def model(self):
-    return self._model
-
-  @property
-  def renderer_thread(self):
-    return self._renderer_thread
-
-  @property
-  def foo_thread(self):
-    return self._foo_thread
-
-  @property
-  def threads_to_records_map(self):
-    return self._threads_to_records_map
-
-  @property
-  def results(self):
-    return self._results
-
-  def AddInteraction(self, thread, marker='', ts=0, duration=5):
-    assert thread in (self._renderer_thread, self._foo_thread)
-    thread.async_slices.append(async_slice.AsyncSlice(
-        'category', marker, timestamp=ts, duration=duration,
-        start_thread=self._renderer_thread, end_thread=self._renderer_thread,
-        thread_start=ts, thread_duration=duration))
-
-  def FinalizeImport(self):
-    self._model.FinalizeImport()
-    self._threads_to_records_map = (
-      tbm_module._GetRendererThreadsToInteractionRecordsMap(self._model))
-    self._story_set = story.StorySet(base_dir=os.path.dirname(__file__))
-    self._story_set.AddStory(page_module.Page(
-        'http://www.bar.com/', self._story_set, self._story_set.base_dir))
-    self._results.WillRunPage(self._story_set.stories[0])
-
-  def AddResults(self):
-    all_metrics = self._tbm_options.GetLegacyTimelineBasedMetrics()
-
-    for thread, records in self._threads_to_records_map.iteritems():
-      # pylint: disable=protected-access
-      metric = tbm_module._TimelineBasedMetrics(
-          self._model, thread, records, self._results_wrapper, all_metrics)
-      metric.AddResults(self._results)
-
-    for metric in all_metrics:
-      metric.AddWholeTraceResults(self._model, self._results)
-
-    self._results.DidRunPage(self._story_set.stories[0])
-
-
-class TimelineBasedMetricsTests(unittest.TestCase):
-
-  def setUp(self):
-    self.actual_get_all_tbm_metrics = (
-        tbm_module._GetAllLegacyTimelineBasedMetrics)
-    self._options = tbm_module.Options()
-    self._options.SetLegacyTimelineBasedMetrics(
-        (FakeSmoothMetric(), FakeLoadingMetric(), FakeStartupMetric()))
-
-  def tearDown(self):
-    tbm_module._GetAllLegacyTimelineBasedMetrics = (
-        self.actual_get_all_tbm_metrics)
-
-  def testGetRendererThreadsToInteractionRecordsMap(self):
-    d = TimelineBasedMetricTestData(self._options)
-    # Insert 2 interaction records to renderer_thread and 1 to foo_thread
-    d.AddInteraction(d.renderer_thread, ts=0, duration=20,
-                     marker='Interaction.LogicalName1')
-    d.AddInteraction(d.renderer_thread, ts=25, duration=5,
-                     marker='Interaction.LogicalName2')
-    d.AddInteraction(d.foo_thread, ts=50, duration=15,
-                     marker='Interaction.LogicalName3')
-    d.FinalizeImport()
-
-    self.assertEquals(2, len(d.threads_to_records_map))
-
-    # Assert the 2 interaction records of renderer_thread are in the map.
-    self.assertIn(d.renderer_thread, d.threads_to_records_map)
-    interactions = d.threads_to_records_map[d.renderer_thread]
-    self.assertEquals(2, len(interactions))
-    self.assertEquals(0, interactions[0].start)
-    self.assertEquals(20, interactions[0].end)
-
-    self.assertEquals(25, interactions[1].start)
-    self.assertEquals(30, interactions[1].end)
-
-    # Assert the 1 interaction records of foo_thread is in the map.
-    self.assertIn(d.foo_thread, d.threads_to_records_map)
-    interactions = d.threads_to_records_map[d.foo_thread]
-    self.assertEquals(1, len(interactions))
-    self.assertEquals(50, interactions[0].start)
-    self.assertEquals(65, interactions[0].end)
-
-  def testAddResults(self):
-    d = TimelineBasedMetricTestData(self._options)
-    d.AddInteraction(d.renderer_thread, ts=0, duration=20,
-                     marker='Interaction.LogicalName1')
-    d.AddInteraction(d.foo_thread, ts=25, duration=5,
-                     marker='Interaction.LogicalName2')
-    d.FinalizeImport()
-    d.AddResults()
-    self.assertEquals(1, len(d.results.FindAllPageSpecificValuesFromIRNamed(
-        'LogicalName1', 'FakeSmoothMetric')))
-    self.assertEquals(1, len(d.results.FindAllPageSpecificValuesFromIRNamed(
-        'LogicalName2', 'FakeLoadingMetric')))
-    self.assertEquals(1, len(d.results.FindAllPageSpecificValuesNamed(
-        'FakeStartupMetric')))
-
-  def testDuplicateInteractionsInDifferentThreads(self):
-    d = TimelineBasedMetricTestData(self._options)
-    d.AddInteraction(d.renderer_thread, ts=10, duration=5,
-                     marker='Interaction.LogicalName/repeatable')
-    d.AddInteraction(d.foo_thread, ts=20, duration=5,
-                     marker='Interaction.LogicalName')
-    self.assertRaises(tbm_module.InvalidInteractions, d.FinalizeImport)
-
-  def testDuplicateRepeatableInteractionsInDifferentThreads(self):
-    d = TimelineBasedMetricTestData(self._options)
-    d.AddInteraction(d.renderer_thread, ts=10, duration=5,
-                     marker='Interaction.LogicalName/repeatable')
-    d.AddInteraction(d.foo_thread, ts=20, duration=5,
-                     marker='Interaction.LogicalName/repeatable')
-    self.assertRaises(tbm_module.InvalidInteractions, d.FinalizeImport)
-
-  def testDuplicateUnrepeatableInteractionsInSameThread(self):
-    d = TimelineBasedMetricTestData(self._options)
-    d.AddInteraction(d.renderer_thread, ts=10, duration=5,
-                     marker='Interaction.LogicalName')
-    d.AddInteraction(d.renderer_thread, ts=20, duration=5,
-                     marker='Interaction.LogicalName')
-    d.FinalizeImport()
-    self.assertRaises(tbm_module.InvalidInteractions, d.AddResults)
-
-  def testDuplicateRepeatableInteractions(self):
-    d = TimelineBasedMetricTestData(self._options)
-    d.AddInteraction(d.renderer_thread, ts=10, duration=5,
-                     marker='Interaction.LogicalName/repeatable')
-    d.AddInteraction(d.renderer_thread, ts=20, duration=5,
-                     marker='Interaction.LogicalName/repeatable')
-    d.FinalizeImport()
-    d.AddResults()
-    self.assertEquals(1, len(d.results.pages_that_succeeded))
diff --git a/catapult/telemetry/telemetry/web_perf/timeline_based_page_test.py b/catapult/telemetry/telemetry/web_perf/timeline_based_page_test.py
deleted file mode 100644
index 5413bb7..0000000
--- a/catapult/telemetry/telemetry/web_perf/timeline_based_page_test.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry.page import legacy_page_test
-
-class TimelineBasedPageTest(legacy_page_test.LegacyPageTest):
-  """Page test that collects metrics with TimelineBasedMeasurement.
-
-  WillRunStory(), Measure() and DidRunStory() are all done in story_runner
-  explicitly. We still need this wrapper around PageTest because it executes
-  some browser related functions in the parent class, which is needed by
-  Timeline Based Measurement benchmarks. This class will be removed after
-  page_test's hooks are fully removed.
-  """
-  def __init__(self, tbm):
-    super(TimelineBasedPageTest, self).__init__()
-    self._measurement = tbm
-
-  @property
-  def measurement(self):
-    return self._measurement
-
-  def ValidateAndMeasurePage(self, page, tab, results):
-    """Collect all possible metrics and added them to results."""
-    # Measurement is done explicitly in story_runner for timeline based page
-    # test.
-    pass
diff --git a/catapult/telemetry/telemetry/web_perf/timeline_based_page_test_unittest.py b/catapult/telemetry/telemetry/web_perf/timeline_based_page_test_unittest.py
deleted file mode 100644
index 0757250..0000000
--- a/catapult/telemetry/telemetry/web_perf/timeline_based_page_test_unittest.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from telemetry import decorators
-from telemetry.page import page as page_module
-from telemetry.testing import browser_test_case
-from telemetry.testing import options_for_unittests
-from telemetry.testing import page_test_test_case
-from telemetry.timeline import chrome_trace_category_filter
-from telemetry.util import wpr_modes
-from telemetry.web_perf import timeline_based_measurement as tbm_module
-from telemetry.web_perf.metrics import gpu_timeline
-from telemetry.web_perf.metrics import smoothness
-
-class TestTimelinebasedMeasurementPage(page_module.Page):
-
-  def __init__(self, ps, base_dir, trigger_animation=False,
-               trigger_jank=False, trigger_slow=False,
-               trigger_scroll_gesture=False):
-    super(TestTimelinebasedMeasurementPage, self).__init__(
-        'file://interaction_enabled_page.html', ps, base_dir)
-    self._trigger_animation = trigger_animation
-    self._trigger_jank = trigger_jank
-    self._trigger_slow = trigger_slow
-    self._trigger_scroll_gesture = trigger_scroll_gesture
-
-  def RunPageInteractions(self, action_runner):
-    if self._trigger_animation:
-      action_runner.TapElement('#animating-button')
-      action_runner.WaitForJavaScriptCondition('window.animationDone')
-    if self._trigger_jank:
-      action_runner.TapElement('#jank-button')
-      action_runner.WaitForJavaScriptCondition('window.jankScriptDone')
-    if self._trigger_slow:
-      action_runner.TapElement('#slow-button')
-      action_runner.WaitForJavaScriptCondition('window.slowScriptDone')
-    if self._trigger_scroll_gesture:
-      with action_runner.CreateGestureInteraction('Scroll'):
-        action_runner.ScrollPage()
-
-
-class TimelineBasedPageTestTest(page_test_test_case.PageTestTestCase):
-
-  def setUp(self):
-    browser_test_case.teardown_browser()
-    self._options = options_for_unittests.GetCopy()
-    self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF
-
-  # This test is flaky when run in parallel on the mac: crbug.com/426676
-  # Also, fails on android: crbug.com/437057, and chromeos: crbug.com/483212
-  @decorators.Disabled('android', 'mac', 'chromeos')
-  @decorators.Disabled('win')  # catapult/issues/2282
-  @decorators.Isolated  # Needed because of py_trace_event
-  def testSmoothnessTimelineBasedMeasurementForSmoke(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddStory(TestTimelinebasedMeasurementPage(
-        ps, ps.base_dir, trigger_animation=True))
-
-    options = tbm_module.Options()
-    options.SetLegacyTimelineBasedMetrics([smoothness.SmoothnessMetric()])
-    tbm = tbm_module.TimelineBasedMeasurement(options)
-    results = self.RunMeasurement(tbm, ps, options=self._options)
-
-    self.assertEquals(0, len(results.failures))
-    v = results.FindAllPageSpecificValuesFromIRNamed(
-        'CenterAnimation', 'frame_time_discrepancy')
-    self.assertEquals(len(v), 1)
-    v = results.FindAllPageSpecificValuesFromIRNamed(
-        'DrawerAnimation', 'frame_time_discrepancy')
-    self.assertEquals(len(v), 1)
-
-  # This test should eventually work on all platforms, but currently this
-  # this metric is flaky on desktop: crbug.com/453131
-  # https://github.com/catapult-project/catapult/issues/3099 (Android)
-  @decorators.Disabled('all')
-  def testGPUTimesTimelineBasedMeasurementForSmoke(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddStory(TestTimelinebasedMeasurementPage(
-        ps, ps.base_dir, trigger_animation=True))
-
-    cat_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        'disabled-by-default-gpu.service')
-    tbm_option = tbm_module.Options(overhead_level=cat_filter)
-    tbm_option.SetLegacyTimelineBasedMetrics([gpu_timeline.GPUTimelineMetric()])
-    tbm = tbm_module.TimelineBasedMeasurement(tbm_option)
-    results = self.RunMeasurement(tbm, ps, options=self._options)
-
-    self.assertEquals(0, len(results.failures))
-    v = results.FindAllPageSpecificValuesFromIRNamed(
-        'CenterAnimation', 'browser_compositor_max_cpu_time')
-    self.assertEquals(len(v), 1)
-    self.assertGreater(v[0].value, 0)
-    v = results.FindAllPageSpecificValuesFromIRNamed(
-        'DrawerAnimation', 'browser_compositor_max_cpu_time')
-    self.assertEquals(len(v), 1)
-    self.assertGreater(v[0].value, 0)
-
-  # win: crbug.com/520781, chromeos: crbug.com/483212.
-  @decorators.Disabled('win', 'chromeos')
-  @decorators.Isolated  # Needed because of py_trace_event
-  def testTimelineBasedMeasurementGestureAdjustmentSmoke(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddStory(TestTimelinebasedMeasurementPage(
-        ps, ps.base_dir, trigger_scroll_gesture=True))
-
-    options = tbm_module.Options()
-    options.SetLegacyTimelineBasedMetrics([smoothness.SmoothnessMetric()])
-    tbm = tbm_module.TimelineBasedMeasurement(options)
-    results = self.RunMeasurement(tbm, ps, options=self._options)
-
-    self.assertEquals(0, len(results.failures))
-    v = results.FindAllPageSpecificValuesFromIRNamed(
-        'Gesture_Scroll', 'frame_time_discrepancy')
-    self.assertEquals(len(v), 1)
-
-  # Fails on chromeos: crbug.com/483212
-  @decorators.Disabled('chromeos')
-  @decorators.Isolated
-  def testTBM2ForSmoke(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddStory(TestTimelinebasedMeasurementPage(ps, ps.base_dir))
-
-    options = tbm_module.Options()
-    options.config.enable_chrome_trace = True
-    options.SetTimelineBasedMetrics(['sampleMetric'])
-
-    tbm = tbm_module.TimelineBasedMeasurement(options)
-    results = self.RunMeasurement(tbm, ps, self._options)
-
-    self.assertEquals(0, len(results.failures))
-    self.assertEquals(2, len(results.value_set))
-    diagnostics = results.value_set[1]['diagnostics']
-    self.assertEquals(1, len(diagnostics))
-    telemetry_info = results.value_set[0]
-    self.assertEquals(telemetry_info['guid'], diagnostics['telemetry'])
-    self.assertEqual('TelemetryInfo', telemetry_info['type'])
-    self.assertEqual('', telemetry_info['benchmarkName'])
-    self.assertEqual('interaction_enabled_page.html',
-                     telemetry_info['storyDisplayName'])
-    self.assertNotIn('storyGroupingKeys', telemetry_info)
-    self.assertEqual(0, telemetry_info['storysetRepeatCounter'])
-    v_foo = results.FindAllPageSpecificValuesNamed('foo_avg')
-    self.assertEquals(len(v_foo), 1)
-    self.assertEquals(v_foo[0].value, 50)
-    self.assertIsNotNone(v_foo[0].page)
-
-  @decorators.Disabled('chromeos')
-  def testFirstPaintMetricSmoke(self):
-    ps = self.CreateEmptyPageSet()
-    ps.AddStory(TestTimelinebasedMeasurementPage(ps, ps.base_dir))
-
-    cat_filter = chrome_trace_category_filter.ChromeTraceCategoryFilter(
-        filter_string='*,blink.console,navigation,blink.user_timing,loading,' +
-        'devtools.timeline,disabled-by-default-blink.debug.layout')
-
-    options = tbm_module.Options(overhead_level=cat_filter)
-    options.SetTimelineBasedMetrics(['loadingMetric'])
-
-    tbm = tbm_module.TimelineBasedMeasurement(options)
-    results = self.RunMeasurement(tbm, ps, self._options)
-
-    self.assertEquals(0, len(results.failures), results.failures)
-    v_ttfcp_max = results.FindAllPageSpecificValuesNamed(
-        'timeToFirstContentfulPaint_max')
-    self.assertEquals(len(v_ttfcp_max), 1)
-    self.assertIsNotNone(v_ttfcp_max[0].page)
-    # TODO(kouhei): enable this once the reference build of telemetry is
-    # updated.
-    #  self.assertGreater(v_ttfcp_max[0].value, 0)
-
-    v_ttfmp_max = results.FindAllPageSpecificValuesNamed(
-       'timeToFirstMeaningfulPaint_max')
-    self.assertEquals(len(v_ttfmp_max), 1)
-    # TODO(ksakamoto): enable this once the reference build of telemetry is
-    # updated.
-    # self.assertIsNotNone(v_ttfmp_max[0].page)
diff --git a/catapult/telemetry/telemetry/web_perf/timeline_interaction_record.py b/catapult/telemetry/telemetry/web_perf/timeline_interaction_record.py
deleted file mode 100644
index 7d6ce26..0000000
--- a/catapult/telemetry/telemetry/web_perf/timeline_interaction_record.py
+++ /dev/null
@@ -1,235 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-
-from telemetry import decorators
-import telemetry.timeline.bounds as timeline_bounds
-
-# Allows multiple duplicate interactions of the same type
-REPEATABLE = 'repeatable'
-
-FLAGS = [REPEATABLE]
-
-
-class ThreadTimeRangeOverlappedException(Exception):
-  """Exception that can be thrown when computing overlapped thread time range
-  with other events.
-  """
-
-class NoThreadTimeDataException(ThreadTimeRangeOverlappedException):
-  """Exception that can be thrown if there is not sufficient thread time data
-  to compute the overlapped thread time range."""
-
-def IsTimelineInteractionRecord(event_name):
-  return event_name.startswith('Interaction.')
-
-def _AssertFlagsAreValid(flags):
-  assert isinstance(flags, list)
-  for f in flags:
-    if f not in FLAGS:
-      raise AssertionError(
-          'Unrecognized flag for a timeline interaction record: %s' % f)
-
-def GetJavaScriptMarker(label, flags):
-  """Computes the marker string of an interaction record.
-
-  This marker string can be used with JavaScript API console.time()
-  and console.timeEnd() to mark the beginning and end of the
-  interaction record..
-
-  Args:
-    label: The label used to identify the interaction record.
-    flags: the flags for the interaction record see FLAGS above.
-
-  Returns:
-    The interaction record marker string (e.g., Interaction.Label/flag1,flag2).
-
-  Raises:
-    AssertionError: If one or more of the flags is unrecognized.
-  """
-  _AssertFlagsAreValid(flags)
-  marker = 'Interaction.%s' % label
-  if flags:
-    marker += '/%s' % (','.join(flags))
-  return marker
-
-class TimelineInteractionRecord(object):
-  """Represents an interaction that took place during a timeline recording.
-
-  As a page runs, typically a number of different (simulated) user interactions
-  take place. For instance, a user might click a button in a mail app causing a
-  popup to animate in. Then they might press another button that sends data to a
-  server and simultaneously closes the popup without an animation. These are two
-  interactions.
-
-  From the point of view of the page, each interaction might have a different
-  label: ClickComposeButton and SendEmail, for instance. From the point
-  of view of the benchmarking harness, the labels aren't so interesting as what
-  the performance expectations are for that interaction: was it loading
-  resources from the network? was there an animation?
-
-  Determining these things is hard to do, simply by observing the state given to
-  a page from javascript. There are hints, for instance if network requests are
-  sent, or if a CSS animation is pending. But this is by no means a complete
-  story.
-
-  Instead, we expect pages to mark up the timeline what they are doing, with
-  label and flags indicating the semantics of that interaction. This
-  is currently done by pushing markers into the console.time/timeEnd API: this
-  for instance can be issued in JS:
-
-     var str = 'Interaction.SendEmail';
-     console.time(str);
-     setTimeout(function() {
-       console.timeEnd(str);
-     }, 1000);
-
-  When run with perf.measurements.timeline_based_measurement running, this will
-  then cause a TimelineInteractionRecord to be created for this range with
-  all metrics reported for the marked up 1000ms time-range.
-
-  The valid interaction flags are:
-     * repeatable: Allows other interactions to use the same label
-  """
-
-  def __init__(self, label, start, end, async_event=None, flags=None):
-    assert label
-    self._label = label
-    self._start = start
-    self._end = end
-    self._async_event = async_event
-    self._flags = flags if flags is not None else []
-    _AssertFlagsAreValid(self._flags)
-
-  @property
-  def label(self):
-    return self._label
-
-  @property
-  def start(self):
-    return self._start
-
-  @property
-  def end(self):
-    return self._end
-
-  @property
-  def repeatable(self):
-    return REPEATABLE in self._flags
-
-  # TODO(nednguyen): After crbug.com/367175 is marked fixed, we should be able
-  # to get rid of perf.measurements.smooth_gesture_util and make this the only
-  # constructor method for TimelineInteractionRecord.
-  @classmethod
-  def FromAsyncEvent(cls, async_event):
-    """Construct an timeline_interaction_record from an async event.
-    Args:
-      async_event: An instance of
-        telemetry.timeline.async_slices.AsyncSlice
-    """
-    assert async_event.start_thread == async_event.end_thread, (
-        'Start thread of this record\'s async event is not the same as its '
-        'end thread')
-    m = re.match(r'Interaction\.(?P<label>.+?)(/(?P<flags>[^/]+))?$',
-                 async_event.name)
-    assert m, "Async event is not an interaction record."
-    label = m.group('label')
-    flags = m.group('flags').split(',') if m.group('flags') is not None else []
-    return cls(label, async_event.start, async_event.end, async_event, flags)
-
-  @decorators.Cache
-  def GetBounds(self):
-    bounds = timeline_bounds.Bounds()
-    bounds.AddValue(self.start)
-    bounds.AddValue(self.end)
-    return bounds
-
-  def GetOverlappedThreadTimeForSlice(self, timeline_slice):
-    """Get the thread duration of timeline_slice that overlaps with this record.
-
-    There are two cases :
-
-    Case 1: timeline_slice runs in the same thread as the record.
-
-                  |    [       timeline_slice         ]
-      THREAD 1    |                  |                              |
-                  |            record starts                    record ends
-
-                      (relative order in thread time)
-
-      As the thread timestamps in timeline_slice and record are consistent, we
-      simply use them to compute the overlap.
-
-    Case 2: timeline_slice runs in a different thread from the record's.
-
-                  |
-      THREAD 2    |    [       timeline_slice         ]
-                  |
-
-                  |
-      THREAD 1    |               |                               |
-                  |          record starts                      record ends
-
-                      (relative order in wall-time)
-
-      Unlike case 1, thread timestamps of a thread are measured by its
-      thread-specific clock, which is inconsistent with that of the other
-      thread, and thus can't be used to compute the overlapped thread duration.
-      Hence, we use a heuristic to compute the overlap (see
-      _GetOverlappedThreadTimeForSliceInDifferentThread for more details)
-
-    Args:
-      timeline_slice: An instance of telemetry.timeline.slice.Slice
-    """
-    if not self._async_event:
-      raise ThreadTimeRangeOverlappedException(
-          'This record was not constructed from async event')
-    if not self._async_event.has_thread_timestamps:
-      raise NoThreadTimeDataException(
-          'This record\'s async_event does not contain thread time data. '
-          'Event data: %s' % repr(self._async_event))
-    if not timeline_slice.has_thread_timestamps:
-      raise NoThreadTimeDataException(
-          'slice does not contain thread time data')
-
-    if timeline_slice.parent_thread == self._async_event.start_thread:
-      return self._GetOverlappedThreadTimeForSliceInSameThread(
-          timeline_slice)
-    else:
-      return self._GetOverlappedThreadTimeForSliceInDifferentThread(
-          timeline_slice)
-
-  def _GetOverlappedThreadTimeForSliceInSameThread(self, timeline_slice):
-    return timeline_bounds.Bounds.GetOverlap(
-        timeline_slice.thread_start, timeline_slice.thread_end,
-        self._async_event.thread_start, self._async_event.thread_end)
-
-  def _GetOverlappedThreadTimeForSliceInDifferentThread(self, timeline_slice):
-    # In case timeline_slice's parent thread is not the parent thread of the
-    # async slice that issues this record, we assume that events are descheduled
-    # uniformly. The overlap duration in thread time is then computed by
-    # multiplying the overlap wall-time duration of timeline_slice and the
-    # record's async slice with their thread_duration/duration ratios.
-    overlapped_walltime_duration = timeline_bounds.Bounds.GetOverlap(
-        timeline_slice.start, timeline_slice.end,
-        self.start, self.end)
-    if timeline_slice.duration == 0 or self._async_event.duration == 0:
-      return 0
-    timeline_slice_scheduled_ratio = (
-        timeline_slice.thread_duration / float(timeline_slice.duration))
-    record_scheduled_ratio = (
-        self._async_event.thread_duration / float(self._async_event.duration))
-    return (overlapped_walltime_duration * timeline_slice_scheduled_ratio *
-            record_scheduled_ratio)
-
-  def __repr__(self):
-    flags_str = ','.join(self._flags)
-    return ('TimelineInteractionRecord(label=\'%s\', start=%f, end=%f,' +
-            ' flags=%s, async_event=%s)') % (
-                self.label,
-                self.start,
-                self.end,
-                flags_str,
-                repr(self._async_event))
diff --git a/catapult/telemetry/telemetry/web_perf/timeline_interaction_record_unittest.py b/catapult/telemetry/telemetry/web_perf/timeline_interaction_record_unittest.py
deleted file mode 100644
index 870b66b..0000000
--- a/catapult/telemetry/telemetry/web_perf/timeline_interaction_record_unittest.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from telemetry.timeline import async_slice
-from telemetry.timeline import model as model_module
-from telemetry.timeline import slice as slice_module
-from telemetry.web_perf import timeline_interaction_record as tir_module
-
-
-class ParseTests(unittest.TestCase):
-
-  def testParse(self):
-    self.assertTrue(tir_module.IsTimelineInteractionRecord(
-        'Interaction.Foo'))
-    self.assertTrue(tir_module.IsTimelineInteractionRecord(
-        'Interaction.Foo/Bar'))
-    self.assertFalse(tir_module.IsTimelineInteractionRecord(
-        'SomethingRandom'))
-
-
-class TimelineInteractionRecordTests(unittest.TestCase):
-
-  def CreateSimpleRecordWithName(self, event_name):
-    s = async_slice.AsyncSlice(
-        'cat', event_name,
-        timestamp=0, duration=200, thread_start=20, thread_duration=100)
-    return tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
-
-  def CreateTestSliceFromTimeRanges(
-      self, parent_thread, time_start, time_end, thread_start, thread_end):
-    duration = time_end - time_start
-    thread_duration = thread_end - thread_start
-    return slice_module.Slice(parent_thread, 'Test', 'foo', time_start,
-                              duration, thread_start, thread_duration)
-
-  def testCreate(self):
-    r = self.CreateSimpleRecordWithName('Interaction.LogicalName')
-    self.assertEquals('LogicalName', r.label)
-    self.assertEquals(False, r.repeatable)
-
-    r = self.CreateSimpleRecordWithName('Interaction.LogicalName/repeatable')
-    self.assertEquals('LogicalName', r.label)
-    self.assertEquals(True, r.repeatable)
-
-    r = self.CreateSimpleRecordWithName(
-        'Interaction.LogicalNameWith/Slash/repeatable')
-    self.assertEquals('LogicalNameWith/Slash', r.label)
-    self.assertEquals(True, r.repeatable)
-
-  def testGetJavaScriptMarker(self):
-    repeatable_marker = tir_module.GetJavaScriptMarker(
-        'MyLabel', [tir_module.REPEATABLE])
-    self.assertEquals('Interaction.MyLabel/repeatable', repeatable_marker)
-
-  def testGetOverlappedThreadTimeForSliceInSameThread(self):
-    # Create a renderer thread.
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    model.FinalizeImport()
-
-   # Make a record that starts at 30ms and ends at 60ms in thread time.
-    s = async_slice.AsyncSlice(
-        'cat', 'Interaction.Test',
-        timestamp=0, duration=200, start_thread=renderer_main,
-        end_thread=renderer_main, thread_start=30, thread_duration=30)
-    record = tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
-
-    # Non overlapped range on the left of event.
-    s1 = self.CreateTestSliceFromTimeRanges(renderer_main, 0, 100, 10, 20)
-    self.assertEquals(0, record.GetOverlappedThreadTimeForSlice(s1))
-
-    # Non overlapped range on the right of event.
-    s2 = self.CreateTestSliceFromTimeRanges(renderer_main, 0, 100, 70, 90)
-    self.assertEquals(0, record.GetOverlappedThreadTimeForSlice(s2))
-
-    # Overlapped range on the left of event.
-    s3 = self.CreateTestSliceFromTimeRanges(renderer_main, 0, 100, 20, 50)
-    self.assertEquals(20, record.GetOverlappedThreadTimeForSlice(s3))
-
-    # Overlapped range in the middle of event.
-    s4 = self.CreateTestSliceFromTimeRanges(renderer_main, 0, 100, 40, 50)
-    self.assertEquals(10, record.GetOverlappedThreadTimeForSlice(s4))
-
-    # Overlapped range on the left of event.
-    s5 = self.CreateTestSliceFromTimeRanges(renderer_main, 0, 100, 50, 90)
-    self.assertEquals(10, record.GetOverlappedThreadTimeForSlice(s5))
-
-  def testRepr(self):
-    # Create a renderer thread.
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    model.FinalizeImport()
-
-    s = async_slice.AsyncSlice(
-        'cat', 'Interaction.Test/repeatable',
-        timestamp=0, duration=200, start_thread=renderer_main,
-        end_thread=renderer_main, thread_start=30, thread_duration=30)
-    record = tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
-    expected_repr = (
-        'TimelineInteractionRecord(label=\'Test\', '
-        'start=0.000000, end=200.000000, flags=repeatable, '
-        'async_event=TimelineEvent(name=\'Interaction.Test/repeatable\','
-        ' start=0.000000, duration=200, thread_start=30, thread_duration=30))')
-    self.assertEquals(expected_repr, repr(record))
-
-
-  def testGetOverlappedThreadTimeForSliceInDifferentThread(self):
-    # Create a renderer thread and another thread.
-    model = model_module.TimelineModel()
-    renderer_main = model.GetOrCreateProcess(1).GetOrCreateThread(2)
-    another_thread = model.GetOrCreateProcess(1).GetOrCreateThread(3)
-    model.FinalizeImport()
-
-   # Make a record that starts at 50ms and ends at 150ms in wall time, and is
-   # scheduled 75% of the time (hence thread_duration = 100ms*75% = 75ms).
-    s = async_slice.AsyncSlice(
-        'cat', 'Interaction.Test',
-        timestamp=50, duration=100, start_thread=renderer_main,
-        end_thread=renderer_main, thread_start=55, thread_duration=75)
-    record = tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
-
-    # Non overlapped range on the left of event.
-    s1 = self.CreateTestSliceFromTimeRanges(another_thread, 25, 40, 28, 30)
-    self.assertEquals(0, record.GetOverlappedThreadTimeForSlice(s1))
-
-    # Non overlapped range on the right of event.
-    s2 = self.CreateTestSliceFromTimeRanges(another_thread, 200, 300, 270, 290)
-    self.assertEquals(0, record.GetOverlappedThreadTimeForSlice(s2))
-
-    # Overlapped range on the left of event, and slice is scheduled 50% of the
-    # time.
-    # The overlapped wall-time duration is 50ms.
-    # The overlapped thread-time duration is 50ms * 75% * 50% = 18.75
-    s3 = self.CreateTestSliceFromTimeRanges(another_thread, 0, 100, 20, 70)
-    self.assertEquals(18.75, record.GetOverlappedThreadTimeForSlice(s3))
-
-    # Overlapped range in the middle of event, and slice is scheduled 20% of the
-    # time.
-    # The overlapped wall-time duration is 40ms.
-    # The overlapped thread-time duration is 40ms * 75% * 20% = 6
-    s4 = self.CreateTestSliceFromTimeRanges(another_thread, 100, 140, 120, 128)
-    self.assertEquals(6, record.GetOverlappedThreadTimeForSlice(s4))
-
-    # Overlapped range on the left of event, and slice is scheduled 100% of the
-    # time.
-    # The overlapped wall-time duration is 32ms.
-    # The overlapped thread-time duration is 32ms * 75% * 100% = 24
-    s5 = self.CreateTestSliceFromTimeRanges(another_thread, 118, 170, 118, 170)
-    self.assertEquals(24, record.GetOverlappedThreadTimeForSlice(s5))
diff --git a/catapult/telemetry/telemetry/wpr/__init__.py b/catapult/telemetry/telemetry/wpr/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/catapult/telemetry/telemetry/wpr/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/catapult/telemetry/telemetry/wpr/archive_info.py b/catapult/telemetry/telemetry/wpr/archive_info.py
deleted file mode 100644
index 9ec4cda..0000000
--- a/catapult/telemetry/telemetry/wpr/archive_info.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-import os
-import re
-import shutil
-import tempfile
-import time
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-
-_DEFAULT_PLATFORM = 'DEFAULT'
-_ALL_PLATFORMS = ['mac', 'linux', 'android', 'win', _DEFAULT_PLATFORM]
-
-
-def AssertValidCloudStorageBucket(bucket):
-  is_valid = bucket in (None,
-                        cloud_storage.PUBLIC_BUCKET,
-                        cloud_storage.PARTNER_BUCKET,
-                        cloud_storage.INTERNAL_BUCKET)
-  if not is_valid:
-    raise ValueError("Cloud storage privacy bucket %s is invalid" % bucket)
-
-
-class WprArchiveInfo(object):
-  def __init__(self, file_path, data, bucket):
-    AssertValidCloudStorageBucket(bucket)
-    self._file_path = file_path
-    self._base_dir = os.path.dirname(file_path)
-    self._data = data
-    self._bucket = bucket
-    self.temp_target_wpr_file_path = None
-    # Ensure directory exists.
-    if not os.path.exists(self._base_dir):
-      os.makedirs(self._base_dir)
-
-    assert data.get('platform_specific', False), (
-        'Detected old version of archive info json file. Please update to new '
-        'version.')
-
-    self._story_name_to_wpr_file = data['archives']
-
-  @classmethod
-  def FromFile(cls, file_path, bucket):
-    """ Generates an archive_info instance with the given json file. """
-    if os.path.exists(file_path):
-      with open(file_path, 'r') as f:
-        data = json.load(f)
-        return cls(file_path, data, bucket)
-    return cls(file_path, {'archives': {}, 'platform_specific': True}, bucket)
-
-  def DownloadArchivesIfNeeded(self, target_platforms=None):
-    """Downloads archives iff the Archive has a bucket parameter and the user
-    has permission to access the bucket.
-
-    Raises cloud storage Permissions or Credentials error when there is no
-    local copy of the archive and the user doesn't have permission to access
-    the archive's bucket.
-
-    Warns when a bucket is not specified or when the user doesn't have
-    permission to access the archive's bucket but a local copy of the archive
-    exists.
-    """
-    logging.info('Downloading WPR archives. This can take a long time.')
-    start_time = time.time()
-    # If no target platform is set, download all platforms.
-    if target_platforms is None:
-      target_platforms = _ALL_PLATFORMS
-    else:
-      assert isinstance(target_platforms, list), 'Must pass platforms as a list'
-      target_platforms = target_platforms + [_DEFAULT_PLATFORM]
-    # Download all .wpr files.
-    if not self._bucket:
-      logging.warning('Story set in %s has no bucket specified, and '
-                      'cannot be downloaded from cloud_storage.', )
-      return
-    assert 'archives' in self._data, ("Invalid data format in %s. 'archives' "
-                                      "field is needed" % self._file_path)
-
-    def download_if_needed(path):
-      try:
-        cloud_storage.GetIfChanged(path, self._bucket)
-      except (cloud_storage.CredentialsError, cloud_storage.PermissionError):
-        if os.path.exists(path):
-          # If the archive exists, assume the user recorded their own and warn
-          # them that they do not have the proper credentials to download.
-          logging.warning('Need credentials to update WPR archive: %s', path)
-        else:
-          logging.error("You either aren't authenticated or don't have "
-                        "permission to use the archives for this page set."
-                        "\nYou may need to run gsutil config."
-                        "\nYou can find instructions for gsutil config at: "
-                        "http://www.chromium.org/developers/telemetry/"
-                        "upload_to_cloud_storage")
-          raise
-    try:
-      story_archives = self._data['archives']
-      for story in story_archives:
-        for target_platform in target_platforms:
-          if story_archives[story].get(target_platform):
-            archive_path = self._WprFileNameToPath(
-                story_archives[story][target_platform])
-            download_if_needed(archive_path)
-    finally:
-      logging.info('All WPR archives are downloaded, took %s seconds.',
-                   time.time() - start_time)
-
-  def WprFilePathForStory(self, story, target_platform=_DEFAULT_PLATFORM):
-    if self.temp_target_wpr_file_path:
-      return self.temp_target_wpr_file_path
-
-    wpr_file = self._story_name_to_wpr_file.get(story.display_name, None)
-    if wpr_file is None and hasattr(story, 'url'):
-      # Some old pages always use the URL to identify a page rather than the
-      # display_name, so try to look for that.
-      wpr_file = self._story_name_to_wpr_file.get(story.url, None)
-    if wpr_file:
-      if target_platform in wpr_file:
-        return self._WprFileNameToPath(wpr_file[target_platform])
-      return self._WprFileNameToPath(wpr_file[_DEFAULT_PLATFORM])
-    return None
-
-  def AddNewTemporaryRecording(self, temp_wpr_file_path=None):
-    if temp_wpr_file_path is None:
-      temp_wpr_file_handle, temp_wpr_file_path = tempfile.mkstemp()
-      os.close(temp_wpr_file_handle)
-    self.temp_target_wpr_file_path = temp_wpr_file_path
-
-  def AddRecordedStories(self, stories, upload_to_cloud_storage=False,
-                         target_platform=_DEFAULT_PLATFORM):
-    if not stories:
-      os.remove(self.temp_target_wpr_file_path)
-      return
-
-    (target_wpr_file, target_wpr_file_path) = self._NextWprFileName()
-    for story in stories:
-      # Check to see if the platform has been manually overrided.
-      if not story.platform_specific:
-        current_target_platform = _DEFAULT_PLATFORM
-      else:
-        current_target_platform = target_platform
-      self._SetWprFileForStory(
-          story.display_name, target_wpr_file, current_target_platform)
-    shutil.move(self.temp_target_wpr_file_path, target_wpr_file_path)
-
-    # Update the hash file.
-    target_wpr_file_hash = cloud_storage.CalculateHash(target_wpr_file_path)
-    with open(target_wpr_file_path + '.sha1', 'wb') as f:
-      f.write(target_wpr_file_hash)
-      f.flush()
-
-    self._WriteToFile()
-
-    # Upload to cloud storage
-    if upload_to_cloud_storage:
-      if not self._bucket:
-        logging.warning('StorySet must have bucket specified to upload '
-                        'stories to cloud storage.')
-        return
-      try:
-        cloud_storage.Insert(self._bucket, target_wpr_file_hash,
-                             target_wpr_file_path)
-      except cloud_storage.CloudStorageError, e:
-        logging.warning('Failed to upload wpr file %s to cloud storage. '
-                        'Error:%s' % target_wpr_file_path, e)
-
-  def _WriteToFile(self):
-    """Writes the metadata into the file passed as constructor parameter."""
-    metadata = dict()
-    metadata['description'] = (
-        'Describes the Web Page Replay archives for a story set. '
-        'Don\'t edit by hand! Use record_wpr for updating.')
-    metadata['archives'] = self._story_name_to_wpr_file.copy()
-    metadata['platform_specific'] = True
-
-    with open(self._file_path, 'w') as f:
-      json.dump(metadata, f, indent=4, sort_keys=True, separators=(',', ': '))
-      f.flush()
-
-  def _WprFileNameToPath(self, wpr_file):
-    return os.path.abspath(os.path.join(self._base_dir, wpr_file))
-
-  def _NextWprFileName(self):
-    """Creates a new file name for a wpr archive file."""
-    # The names are of the format "some_thing_number.wpr". Read the numbers.
-    highest_number = -1
-    base = None
-    wpr_files = []
-    for story in self._data['archives']:
-      for p in self._data['archives'][story]:
-        wpr_files.append(self._data['archives'][story][p])
-
-    for wpr_file in wpr_files:
-      match = re.match(r'(?P<BASE>.*)_(?P<NUMBER>[0-9]+)\.wpr', wpr_file)
-      if not match:
-        raise Exception('Illegal wpr file name ' + wpr_file)
-      highest_number = max(int(match.groupdict()['NUMBER']), highest_number)
-      if base and match.groupdict()['BASE'] != base:
-        raise Exception('Illegal wpr file name ' + wpr_file +
-                        ', doesn\'t begin with ' + base)
-      base = match.groupdict()['BASE']
-    if not base:
-      # If we're creating a completely new info file, use the base name of the
-      # story set file.
-      base = os.path.splitext(os.path.basename(self._file_path))[0]
-    new_filename = '%s_%03d.wpr' % (base, highest_number + 1)
-    return new_filename, self._WprFileNameToPath(new_filename)
-
-  def _SetWprFileForStory(self, story_name, wpr_file, target_platform):
-    """For modifying the metadata when we're going to record a new archive."""
-    if story_name not in self._data['archives']:
-      # If there is no other recording we want the first to be the default
-      # until a new default is recorded.
-      self._data['archives'][story_name] = {_DEFAULT_PLATFORM: wpr_file}
-    self._data['archives'][story_name][target_platform] = wpr_file
diff --git a/catapult/telemetry/telemetry/wpr/archive_info_unittest.py b/catapult/telemetry/telemetry/wpr/archive_info_unittest.py
deleted file mode 100644
index 1711eda..0000000
--- a/catapult/telemetry/telemetry/wpr/archive_info_unittest.py
+++ /dev/null
@@ -1,407 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import json
-import os
-import shutil
-import tempfile
-import unittest
-
-from py_utils import cloud_storage  # pylint: disable=import-error
-
-from telemetry.page import page
-from telemetry.testing import system_stub
-from telemetry.wpr import archive_info
-
-
-class MockPage(page.Page):
-  def __init__(self, url, name=None, platform_specific=False):
-    super(MockPage, self).__init__(url, None, name=name)
-    self._platform_specific = platform_specific
-
-page1 = MockPage('http://www.foo.com/', 'Foo')
-page2 = MockPage('http://www.bar.com/', 'Bar', True)
-page3 = MockPage('http://www.baz.com/', platform_specific=True)
-pageNew1 = MockPage('http://www.new.com/', 'New')
-pageNew2 = MockPage('http://www.newer.com/', 'Newer', True)
-recording1 = 'data_001.wpr'
-recording2 = 'data_002.wpr'
-recording3 = 'data_003.wpr'
-recording4 = 'data_004.wpr'
-recording5 = 'data_005.wpr'
-_DEFAULT_PLATFORM = archive_info._DEFAULT_PLATFORM
-
-default_archives_info_contents_dict = {
-    "platform_specific": True,
-    "archives": {
-        "Foo": {
-            _DEFAULT_PLATFORM: recording1
-        },
-        "Bar": {
-            _DEFAULT_PLATFORM: recording2
-        },
-        "http://www.baz.com/": {
-            _DEFAULT_PLATFORM: recording1,
-            "win": recording2,
-            "mac": recording3,
-            "linux": recording4,
-            "android": recording5
-        }
-    }
-}
-
-default_archive_info_contents = json.dumps(default_archives_info_contents_dict)
-default_wpr_files = [
-    'data_001.wpr', 'data_002.wpr', 'data_003.wpr', 'data_004.wpr',
-    'data_005.wpr']
-_BASE_ARCHIVE = {
-        u'platform_specific': True,
-        u'description': (u'Describes the Web Page Replay archives for a'
-                         u' story set. Don\'t edit by hand! Use record_wpr for'
-                         u' updating.'),
-        u'archives': {},
-}
-
-
-class WprArchiveInfoTest(unittest.TestCase):
-  def setUp(self):
-    self.tmp_dir = tempfile.mkdtemp()
-    # Set file for the metadata.
-    self.story_set_archive_info_file = os.path.join(
-        self.tmp_dir, 'info.json')
-    self.overrides = system_stub.Override(archive_info, ['cloud_storage'])
-
-  def tearDown(self):
-    shutil.rmtree(self.tmp_dir)
-    self.overrides.Restore()
-
-  def createArchiveInfo(
-      self, archive_data=default_archive_info_contents,
-      cloud_storage_bucket=cloud_storage.PUBLIC_BUCKET, wpr_files=None):
-
-    # Cannot set lists as a default parameter, so doing it this way.
-    if wpr_files is None:
-      wpr_files = default_wpr_files
-
-    with open(self.story_set_archive_info_file, 'w') as f:
-      f.write(archive_data)
-
-    assert isinstance(wpr_files, list)
-    for wpr_file in wpr_files:
-      assert isinstance(wpr_file, basestring)
-      with open(os.path.join(self.tmp_dir, wpr_file), 'w') as f:
-        f.write(archive_data)
-    return archive_info.WprArchiveInfo.FromFile(
-        self.story_set_archive_info_file, cloud_storage_bucket)
-
-  def testInitNotPlatformSpecific(self):
-    with open(self.story_set_archive_info_file, 'w') as f:
-      f.write('{}')
-    with self.assertRaises(AssertionError):
-      self.createArchiveInfo(archive_data='{}')
-
-
-  def testDownloadArchivesIfNeededAllNeeded(self):
-    test_archive_info = self.createArchiveInfo()
-    cloud_storage_stub = self.overrides.cloud_storage
-    # Second hash doesn't match, need to fetch it.
-    cloud_storage_stub.SetRemotePathsForTesting(
-        {cloud_storage.PUBLIC_BUCKET: {recording1: "dummyhash1_old",
-                                       recording2: "dummyhash2_old",
-                                       recording3: "dummyhash3_old",
-                                       recording4: "dummyhash4_old"}})
-    cloud_storage_stub.SetCalculatedHashesForTesting(
-        {os.path.join(self.tmp_dir, recording1): "dummyhash1",
-         os.path.join(self.tmp_dir, recording2): "dummyhash2",
-         os.path.join(self.tmp_dir, recording3): "dummyhash3",
-         os.path.join(self.tmp_dir, recording4): "dummyhash4",})
-
-    test_archive_info.DownloadArchivesIfNeeded()
-    self.assertItemsEqual(cloud_storage_stub.downloaded_files,
-                          [recording1, recording2, recording3, recording4])
-
-
-  def testDownloadArchivesIfNeededOneNeeded(self):
-    test_archive_info = self.createArchiveInfo()
-    cloud_storage_stub = self.overrides.cloud_storage
-    # Second hash doesn't match, need to fetch it.
-    cloud_storage_stub.SetRemotePathsForTesting(
-        {cloud_storage.PUBLIC_BUCKET: {recording1: "dummyhash1_old",
-                                       recording2: "dummyhash2",
-                                       recording3: "dummyhash3",
-                                       recording4: "dummyhash4"}})
-    cloud_storage_stub.SetCalculatedHashesForTesting(
-        {os.path.join(self.tmp_dir, recording1): "dummyhash1",
-         os.path.join(self.tmp_dir, recording2): "dummyhash2",
-         os.path.join(self.tmp_dir, recording3): "dummyhash3",
-         os.path.join(self.tmp_dir, recording4): "dummyhash4",})
-    test_archive_info.DownloadArchivesIfNeeded()
-    self.assertItemsEqual(cloud_storage_stub.downloaded_files, [recording1])
-
-  def testDownloadArchivesIfNeededNonDefault(self):
-    data = {
-        'platform_specific': True,
-        'archives': {
-            'http://www.baz.com/': {
-                _DEFAULT_PLATFORM: 'data_001.wpr',
-                'win': 'data_002.wpr',
-                'linux': 'data_004.wpr',
-                'mac': 'data_003.wpr',
-                'android': 'data_005.wpr'},
-            'Foo': {_DEFAULT_PLATFORM: 'data_003.wpr'},
-            'Bar': {_DEFAULT_PLATFORM: 'data_002.wpr'}
-        }
-    }
-    test_archive_info = self.createArchiveInfo(
-        archive_data=json.dumps(data, separators=(',', ': ')))
-    cloud_storage_stub = self.overrides.cloud_storage
-    # Second hash doesn't match, need to fetch it.
-    cloud_storage_stub.SetRemotePathsForTesting(
-        {cloud_storage.PUBLIC_BUCKET: {recording1: "dummyhash1_old",
-                                       recording2: "dummyhash2",
-                                       recording3: "dummyhash3",
-                                       recording4: "dummyhash4_old"}})
-    cloud_storage_stub.SetCalculatedHashesForTesting(
-        {os.path.join(self.tmp_dir, recording1): "dummyhash1",
-         os.path.join(self.tmp_dir, recording2): "dummyhash2",
-         os.path.join(self.tmp_dir, recording3): "dummyhash3",
-         os.path.join(self.tmp_dir, recording4): "dummyhash4",})
-    test_archive_info.DownloadArchivesIfNeeded(target_platforms=['linux'])
-    self.assertItemsEqual(cloud_storage_stub.downloaded_files,
-                          [recording1, recording4])
-
-  def testDownloadArchivesIfNeededNoBucket(self):
-    test_archive_info = self.createArchiveInfo(cloud_storage_bucket=None)
-    cloud_storage_stub = self.overrides.cloud_storage
-    # Second hash doesn't match, need to fetch it.
-    cloud_storage_stub.SetRemotePathsForTesting(
-        {cloud_storage.PUBLIC_BUCKET: {recording1: "dummyhash1",
-                                       recording2: "dummyhash2",
-                                       recording3: "dummyhash3",
-                                       recording4: "dummyhash4_old"}})
-    cloud_storage_stub.SetCalculatedHashesForTesting(
-        {os.path.join(self.tmp_dir, recording1): "dummyhash1",
-         os.path.join(self.tmp_dir, recording2): "dummyhash2",
-         os.path.join(self.tmp_dir, recording3): "dummyhash3",
-         os.path.join(self.tmp_dir, recording4): "dummyhash4",})
-    test_archive_info.DownloadArchivesIfNeeded()
-    self.assertItemsEqual(cloud_storage_stub.downloaded_files, [])
-
-  def testWprFilePathForStoryDefault(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertEqual(
-        test_archive_info.WprFilePathForStory(page1),
-        os.path.join(self.tmp_dir, recording1))
-    self.assertEqual(
-        test_archive_info.WprFilePathForStory(page2),
-        os.path.join(self.tmp_dir, recording2))
-    self.assertEqual(
-        test_archive_info.WprFilePathForStory(page3),
-        os.path.join(self.tmp_dir, recording1))
-
-  def testWprFilePathForStoryMac(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertEqual(test_archive_info.WprFilePathForStory(page1, 'mac'),
-                     os.path.join(self.tmp_dir, recording1))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page2, 'mac'),
-                     os.path.join(self.tmp_dir, recording2))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page3, 'mac'),
-                     os.path.join(self.tmp_dir, recording3))
-
-  def testWprFilePathForStoryWin(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertEqual(test_archive_info.WprFilePathForStory(page1, 'win'),
-                     os.path.join(self.tmp_dir, recording1))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page2, 'win'),
-                     os.path.join(self.tmp_dir, recording2))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page3, 'win'),
-                     os.path.join(self.tmp_dir, recording2))
-
-  def testWprFilePathForStoryAndroid(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertEqual(test_archive_info.WprFilePathForStory(page1, 'android'),
-                     os.path.join(self.tmp_dir, recording1))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page2, 'android'),
-                     os.path.join(self.tmp_dir, recording2))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page3, 'android'),
-                     os.path.join(self.tmp_dir, recording5))
-
-  def testWprFilePathForStoryLinux(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertEqual(test_archive_info.WprFilePathForStory(page1, 'linux'),
-                     os.path.join(self.tmp_dir, recording1))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page2, 'linux'),
-                     os.path.join(self.tmp_dir, recording2))
-    self.assertEqual(test_archive_info.WprFilePathForStory(page3, 'linux'),
-                     os.path.join(self.tmp_dir, recording4))
-
-  def testWprFilePathForStoryBadStory(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertIsNone(test_archive_info.WprFilePathForStory(pageNew1))
-
-
-  def testAddRecordedStoriesNoStories(self):
-    test_archive_info = self.createArchiveInfo()
-    old_data = test_archive_info._data.copy()
-    test_archive_info.AddNewTemporaryRecording()
-    test_archive_info.AddRecordedStories(None)
-    self.assertDictEqual(old_data, test_archive_info._data)
-
-  def assertWprFileDoesNotExist(self, file_name):
-    sha_file = file_name + '.sha1'
-    self.assertFalse(os.path.isfile(os.path.join(self.tmp_dir, sha_file)))
-    self.assertFalse(os.path.isfile(os.path.join(self.tmp_dir, file_name)))
-
-  def assertWprFileDoesExist(self, file_name):
-    sha_file = file_name + '.sha1'
-    self.assertTrue(os.path.isfile(os.path.join(self.tmp_dir, sha_file)))
-    self.assertTrue(os.path.isfile(os.path.join(self.tmp_dir, file_name)))
-
-  def testAddRecordedStoriesDefault(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertWprFileDoesNotExist('data_006.wpr')
-
-    new_temp_recording = os.path.join(self.tmp_dir, 'recording.wpr')
-    expected_archive_file_path = os.path.join(self.tmp_dir, 'data_006.wpr')
-    hash_dictionary = {expected_archive_file_path: 'filehash'}
-    cloud_storage_stub = self.overrides.cloud_storage
-    cloud_storage_stub.SetCalculatedHashesForTesting(hash_dictionary)
-
-    with open(new_temp_recording, 'w') as f:
-      f.write('wpr data')
-
-    test_archive_info.AddNewTemporaryRecording(new_temp_recording)
-    test_archive_info.AddRecordedStories([page2, page3])
-
-    with open(self.story_set_archive_info_file, 'r') as f:
-      archive_file_contents = json.load(f)
-
-    expected_archive_contents = _BASE_ARCHIVE.copy()
-    expected_archive_contents['archives'] = {
-        page1.display_name: {
-            _DEFAULT_PLATFORM: recording1
-        },
-        page2.display_name: {
-            _DEFAULT_PLATFORM: 'data_006.wpr'
-        },
-        page3.display_name: {
-           _DEFAULT_PLATFORM: u'data_006.wpr',
-           'linux': recording4,
-           'mac': recording3,
-           'win': recording2,
-           'android': recording5
-        }
-    }
-
-    self.assertDictEqual(expected_archive_contents, archive_file_contents)
-    # Ensure the saved JSON does not contain trailing spaces.
-    with open(self.story_set_archive_info_file, 'rU') as f:
-      for line in f:
-        self.assertFalse(line.rstrip('\n').endswith(' '))
-    self.assertWprFileDoesExist('data_006.wpr')
-
-  def testAddRecordedStoriesNotDefault(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertWprFileDoesNotExist('data_006.wpr')
-    new_temp_recording = os.path.join(self.tmp_dir, 'recording.wpr')
-    expected_archive_file_path = os.path.join(self.tmp_dir, 'data_006.wpr')
-    hash_dictionary = {expected_archive_file_path: 'filehash'}
-    cloud_storage_stub = self.overrides.cloud_storage
-    cloud_storage_stub.SetCalculatedHashesForTesting(hash_dictionary)
-
-    with open(new_temp_recording, 'w') as f:
-      f.write('wpr data')
-    test_archive_info.AddNewTemporaryRecording(new_temp_recording)
-    test_archive_info.AddRecordedStories([page2, page3],
-                                         target_platform='android')
-
-    with open(self.story_set_archive_info_file, 'r') as f:
-      archive_file_contents = json.load(f)
-
-    expected_archive_contents = _BASE_ARCHIVE.copy()
-    expected_archive_contents['archives'] = {
-        page1.display_name: {
-            _DEFAULT_PLATFORM: recording1
-        },
-        page2.display_name: {
-            _DEFAULT_PLATFORM: recording2,
-            'android': 'data_006.wpr'
-        },
-        page3.display_name: {
-           _DEFAULT_PLATFORM: recording1,
-           'linux': recording4,
-           'mac': recording3,
-           'win': recording2,
-           'android': 'data_006.wpr'
-        },
-    }
-
-    self.assertDictEqual(expected_archive_contents, archive_file_contents)
-    # Ensure the saved JSON does not contain trailing spaces.
-    with open(self.story_set_archive_info_file, 'rU') as f:
-      for line in f:
-        self.assertFalse(line.rstrip('\n').endswith(' '))
-    self.assertWprFileDoesExist('data_006.wpr')
-
-
-
-  def testAddRecordedStoriesNewPage(self):
-    test_archive_info = self.createArchiveInfo()
-    self.assertWprFileDoesNotExist('data_006.wpr')
-    self.assertWprFileDoesNotExist('data_007.wpr')
-    new_temp_recording = os.path.join(self.tmp_dir, 'recording.wpr')
-    expected_archive_file_path1 = os.path.join(self.tmp_dir, 'data_006.wpr')
-    expected_archive_file_path2 = os.path.join(self.tmp_dir, 'data_007.wpr')
-    hash_dictionary = {
-        expected_archive_file_path1: 'filehash',
-        expected_archive_file_path2: 'filehash2'
-    }
-    cloud_storage_stub = self.overrides.cloud_storage
-    cloud_storage_stub.SetCalculatedHashesForTesting(hash_dictionary)
-
-    with open(new_temp_recording, 'w') as f:
-      f.write('wpr data')
-    test_archive_info.AddNewTemporaryRecording(new_temp_recording)
-    test_archive_info.AddRecordedStories([pageNew1])
-
-    with open(new_temp_recording, 'w') as f:
-      f.write('wpr data2')
-
-    test_archive_info.AddNewTemporaryRecording(new_temp_recording)
-    test_archive_info.AddRecordedStories([pageNew2], target_platform='android')
-
-    with open(self.story_set_archive_info_file, 'r') as f:
-      archive_file_contents = json.load(f)
-
-
-    expected_archive_contents = _BASE_ARCHIVE.copy()
-    expected_archive_contents['archives'] = {
-        page1.display_name: {
-            _DEFAULT_PLATFORM: recording1
-        },
-        page2.display_name: {
-            _DEFAULT_PLATFORM: recording2,
-        },
-        page3.display_name: {
-           _DEFAULT_PLATFORM: recording1,
-           'linux': recording4,
-           'mac': recording3,
-           'win': recording2,
-           'android': recording5
-        },
-        pageNew1.display_name: {
-          _DEFAULT_PLATFORM: 'data_006.wpr'
-        },
-        pageNew2.display_name: {
-          _DEFAULT_PLATFORM: 'data_007.wpr',
-          'android': 'data_007.wpr'
-        }
-    }
-
-    self.assertDictEqual(expected_archive_contents, archive_file_contents)
-    # Ensure the saved JSON does not contain trailing spaces.
-    with open(self.story_set_archive_info_file, 'rU') as f:
-      for line in f:
-        self.assertFalse(line.rstrip('\n').endswith(' '))
-    self.assertWprFileDoesExist('data_006.wpr')
-    self.assertWprFileDoesExist('data_007.wpr')
diff --git a/catapult/telemetry/third_party/.gitignore b/catapult/telemetry/third_party/.gitignore
deleted file mode 100644
index 4127a2d..0000000
--- a/catapult/telemetry/third_party/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-gsutil
diff --git a/catapult/telemetry/third_party/WebKit/LICENSE b/catapult/telemetry/third_party/WebKit/LICENSE
deleted file mode 100644
index 70bcb8a..0000000
--- a/catapult/telemetry/third_party/WebKit/LICENSE
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-//
-// The Chromium Authors can be found at
-// http://src.chromium.org/svn/trunk/src/AUTHORS
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/catapult/telemetry/third_party/WebKit/PerformanceTests/resources/jquery.tablesorter.min.js b/catapult/telemetry/third_party/WebKit/PerformanceTests/resources/jquery.tablesorter.min.js
deleted file mode 100644
index 19d7359..0000000
--- a/catapult/telemetry/third_party/WebKit/PerformanceTests/resources/jquery.tablesorter.min.js
+++ /dev/null
@@ -1,4 +0,0 @@
-
-(function($){$.extend({tablesorter:new
-function(){var parsers=[],widgets=[];this.defaults={cssHeader:"header",cssAsc:"headerSortUp",cssDesc:"headerSortDown",cssChildRow:"expand-child",sortInitialOrder:"asc",sortMultiSortKey:"shiftKey",sortForce:null,sortAppend:null,sortLocaleCompare:true,textExtraction:"simple",parsers:{},widgets:[],widgetZebra:{css:["even","odd"]},headers:{},widthFixed:false,cancelSelection:true,sortList:[],headerList:[],dateFormat:"us",decimal:'/\.|\,/g',onRenderHeader:null,selectorHeaders:'thead th',debug:false};function benchmark(s,d){log(s+","+(new Date().getTime()-d.getTime())+"ms");}this.benchmark=benchmark;function log(s){if(typeof console!="undefined"&&typeof console.debug!="undefined"){console.log(s);}else{alert(s);}}function buildParserCache(table,$headers){if(table.config.debug){var parsersDebug="";}if(table.tBodies.length==0)return;var rows=table.tBodies[0].rows;if(rows[0]){var list=[],cells=rows[0].cells,l=cells.length;for(var i=0;i<l;i++){var p=false;if($.metadata&&($($headers[i]).metadata()&&$($headers[i]).metadata().sorter)){p=getParserById($($headers[i]).metadata().sorter);}else if((table.config.headers[i]&&table.config.headers[i].sorter)){p=getParserById(table.config.headers[i].sorter);}if(!p){p=detectParserForColumn(table,rows,-1,i);}if(table.config.debug){parsersDebug+="column:"+i+" parser:"+p.id+"\n";}list.push(p);}}if(table.config.debug){log(parsersDebug);}return list;};function detectParserForColumn(table,rows,rowIndex,cellIndex){var l=parsers.length,node=false,nodeValue=false,keepLooking=true;while(nodeValue==''&&keepLooking){rowIndex++;if(rows[rowIndex]){node=getNodeFromRowAndCellIndex(rows,rowIndex,cellIndex);nodeValue=trimAndGetNodeText(table.config,node);if(table.config.debug){log('Checking if value was empty on row:'+rowIndex);}}else{keepLooking=false;}}for(var i=1;i<l;i++){if(parsers[i].is(nodeValue,table,node)){return parsers[i];}}return parsers[0];}function getNodeFromRowAndCellIndex(rows,rowIndex,cellIndex){return rows[rowIndex].cells[cellIndex];}function trimAndGetNodeText(config,node){return $.trim(getElementText(config,node));}function getParserById(name){var l=parsers.length;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==name.toLowerCase()){return parsers[i];}}return false;}function buildCache(table){if(table.config.debug){var cacheTime=new Date();}var totalRows=(table.tBodies[0]&&table.tBodies[0].rows.length)||0,totalCells=(table.tBodies[0].rows[0]&&table.tBodies[0].rows[0].cells.length)||0,parsers=table.config.parsers,cache={row:[],normalized:[]};for(var i=0;i<totalRows;++i){var c=$(table.tBodies[0].rows[i]),cols=[];if(c.hasClass(table.config.cssChildRow)){cache.row[cache.row.length-1]=cache.row[cache.row.length-1].add(c);continue;}cache.row.push(c);for(var j=0;j<totalCells;++j){cols.push(parsers[j].format(getElementText(table.config,c[0].cells[j]),table,c[0].cells[j]));}cols.push(cache.normalized.length);cache.normalized.push(cols);cols=null;};if(table.config.debug){benchmark("Building cache for "+totalRows+" rows:",cacheTime);}return cache;};function getElementText(config,node){var text="";if(!node)return"";if(!config.supportsTextContent)config.supportsTextContent=node.textContent||false;if(config.textExtraction=="simple"){if(config.supportsTextContent){text=node.textContent;}else{if(node.childNodes[0]&&node.childNodes[0].hasChildNodes()){text=node.childNodes[0].innerHTML;}else{text=node.innerHTML;}}}else{if(typeof(config.textExtraction)=="function"){text=config.textExtraction(node);}else{text=$(node).text();}}return text;}function appendToTable(table,cache){if(table.config.debug){var appendTime=new Date()}var c=cache,r=c.row,n=c.normalized,totalRows=n.length,checkCell=(n[0].length-1),tableBody=$(table.tBodies[0]),rows=[];for(var i=0;i<totalRows;i++){var pos=n[i][checkCell];rows.push(r[pos]);if(!table.config.appender){var l=r[pos].length;for(var j=0;j<l;j++){tableBody[0].appendChild(r[pos][j]);}}}if(table.config.appender){table.config.appender(table,rows);}rows=null;if(table.config.debug){benchmark("Rebuilt table:",appendTime);}applyWidget(table);setTimeout(function(){$(table).trigger("sortEnd");},0);};function buildHeaders(table){if(table.config.debug){var time=new Date();}var meta=($.metadata)?true:false;var header_index=computeTableHeaderCellIndexes(table);$tableHeaders=$(table.config.selectorHeaders,table).each(function(index){this.column=header_index[this.parentNode.rowIndex+"-"+this.cellIndex];this.order=formatSortingOrder(table.config.sortInitialOrder);this.count=this.order;if(checkHeaderMetadata(this)||checkHeaderOptions(table,index))this.sortDisabled=true;if(checkHeaderOptionsSortingLocked(table,index))this.order=this.lockedOrder=checkHeaderOptionsSortingLocked(table,index);if(!this.sortDisabled){var $th=$(this).addClass(table.config.cssHeader);if(table.config.onRenderHeader)table.config.onRenderHeader.apply($th);}table.config.headerList[index]=this;});if(table.config.debug){benchmark("Built headers:",time);log($tableHeaders);}return $tableHeaders;};function computeTableHeaderCellIndexes(t){var matrix=[];var lookup={};var thead=t.getElementsByTagName('THEAD')[0];var trs=thead.getElementsByTagName('TR');for(var i=0;i<trs.length;i++){var cells=trs[i].cells;for(var j=0;j<cells.length;j++){var c=cells[j];var rowIndex=c.parentNode.rowIndex;var cellId=rowIndex+"-"+c.cellIndex;var rowSpan=c.rowSpan||1;var colSpan=c.colSpan||1
-var firstAvailCol;if(typeof(matrix[rowIndex])=="undefined"){matrix[rowIndex]=[];}for(var k=0;k<matrix[rowIndex].length+1;k++){if(typeof(matrix[rowIndex][k])=="undefined"){firstAvailCol=k;break;}}lookup[cellId]=firstAvailCol;for(var k=rowIndex;k<rowIndex+rowSpan;k++){if(typeof(matrix[k])=="undefined"){matrix[k]=[];}var matrixrow=matrix[k];for(var l=firstAvailCol;l<firstAvailCol+colSpan;l++){matrixrow[l]="x";}}}}return lookup;}function checkCellColSpan(table,rows,row){var arr=[],r=table.tHead.rows,c=r[row].cells;for(var i=0;i<c.length;i++){var cell=c[i];if(cell.colSpan>1){arr=arr.concat(checkCellColSpan(table,headerArr,row++));}else{if(table.tHead.length==1||(cell.rowSpan>1||!r[row+1])){arr.push(cell);}}}return arr;};function checkHeaderMetadata(cell){if(($.metadata)&&($(cell).metadata().sorter===false)){return true;};return false;}function checkHeaderOptions(table,i){if((table.config.headers[i])&&(table.config.headers[i].sorter===false)){return true;};return false;}function checkHeaderOptionsSortingLocked(table,i){if((table.config.headers[i])&&(table.config.headers[i].lockedOrder))return table.config.headers[i].lockedOrder;return false;}function applyWidget(table){var c=table.config.widgets;var l=c.length;for(var i=0;i<l;i++){getWidgetById(c[i]).format(table);}}function getWidgetById(name){var l=widgets.length;for(var i=0;i<l;i++){if(widgets[i].id.toLowerCase()==name.toLowerCase()){return widgets[i];}}};function formatSortingOrder(v){if(typeof(v)!="Number"){return(v.toLowerCase()=="desc")?1:0;}else{return(v==1)?1:0;}}function isValueInArray(v,a){var l=a.length;for(var i=0;i<l;i++){if(a[i][0]==v){return true;}}return false;}function setHeadersCss(table,$headers,list,css){$headers.removeClass(css[0]).removeClass(css[1]);var h=[];$headers.each(function(offset){if(!this.sortDisabled){h[this.column]=$(this);}});var l=list.length;for(var i=0;i<l;i++){h[list[i][0]].addClass(css[list[i][1]]);}}function fixColumnWidth(table,$headers){var c=table.config;if(c.widthFixed){var colgroup=$('<colgroup>');$("tr:first td",table.tBodies[0]).each(function(){colgroup.append($('<col>').css('width',$(this).width()));});$(table).prepend(colgroup);};}function updateHeaderSortCount(table,sortList){var c=table.config,l=sortList.length;for(var i=0;i<l;i++){var s=sortList[i],o=c.headerList[s[0]];o.count=s[1];o.count++;}}function multisort(table,sortList,cache){if(table.config.debug){var sortTime=new Date();}var dynamicExp="var sortWrapper = function(a,b) {",l=sortList.length;for(var i=0;i<l;i++){var c=sortList[i][0];var order=sortList[i][1];var s=(table.config.parsers[c].type=="text")?((order==0)?makeSortFunction("text","asc",c):makeSortFunction("text","desc",c)):((order==0)?makeSortFunction("numeric","asc",c):makeSortFunction("numeric","desc",c));var e="e"+i;dynamicExp+="var "+e+" = "+s;dynamicExp+="if("+e+") { return "+e+"; } ";dynamicExp+="else { ";}var orgOrderCol=cache.normalized[0].length-1;dynamicExp+="return a["+orgOrderCol+"]-b["+orgOrderCol+"];";for(var i=0;i<l;i++){dynamicExp+="}; ";}dynamicExp+="return 0; ";dynamicExp+="}; ";if(table.config.debug){benchmark("Evaling expression:"+dynamicExp,new Date());}eval(dynamicExp);cache.normalized.sort(sortWrapper);if(table.config.debug){benchmark("Sorting on "+sortList.toString()+" and dir "+order+" time:",sortTime);}return cache;};function makeSortFunction(type,direction,index){var a="a["+index+"]",b="b["+index+"]";if(type=='text'&&direction=='asc'){return"("+a+" == "+b+" ? 0 : ("+a+" === null ? Number.POSITIVE_INFINITY : ("+b+" === null ? Number.NEGATIVE_INFINITY : ("+a+" < "+b+") ? -1 : 1 )));";}else if(type=='text'&&direction=='desc'){return"("+a+" == "+b+" ? 0 : ("+a+" === null ? Number.POSITIVE_INFINITY : ("+b+" === null ? Number.NEGATIVE_INFINITY : ("+b+" < "+a+") ? -1 : 1 )));";}else if(type=='numeric'&&direction=='asc'){return"("+a+" === null && "+b+" === null) ? 0 :("+a+" === null ? Number.POSITIVE_INFINITY : ("+b+" === null ? Number.NEGATIVE_INFINITY : "+a+" - "+b+"));";}else if(type=='numeric'&&direction=='desc'){return"("+a+" === null && "+b+" === null) ? 0 :("+a+" === null ? Number.POSITIVE_INFINITY : ("+b+" === null ? Number.NEGATIVE_INFINITY : "+b+" - "+a+"));";}};function makeSortText(i){return"((a["+i+"] < b["+i+"]) ? -1 : ((a["+i+"] > b["+i+"]) ? 1 : 0));";};function makeSortTextDesc(i){return"((b["+i+"] < a["+i+"]) ? -1 : ((b["+i+"] > a["+i+"]) ? 1 : 0));";};function makeSortNumeric(i){return"a["+i+"]-b["+i+"];";};function makeSortNumericDesc(i){return"b["+i+"]-a["+i+"];";};function sortText(a,b){if(table.config.sortLocaleCompare)return a.localeCompare(b);return((a<b)?-1:((a>b)?1:0));};function sortTextDesc(a,b){if(table.config.sortLocaleCompare)return b.localeCompare(a);return((b<a)?-1:((b>a)?1:0));};function sortNumeric(a,b){return a-b;};function sortNumericDesc(a,b){return b-a;};function getCachedSortType(parsers,i){return parsers[i].type;};this.construct=function(settings){return this.each(function(){if(!this.tHead||!this.tBodies)return;var $this,$document,$headers,cache,config,shiftDown=0,sortOrder;this.config={};config=$.extend(this.config,$.tablesorter.defaults,settings);$this=$(this);$.data(this,"tablesorter",config);$headers=buildHeaders(this);this.config.parsers=buildParserCache(this,$headers);cache=buildCache(this);var sortCSS=[config.cssDesc,config.cssAsc];fixColumnWidth(this);$headers.click(function(e){var totalRows=($this[0].tBodies[0]&&$this[0].tBodies[0].rows.length)||0;if(!this.sortDisabled&&totalRows>0){$this.trigger("sortStart");var $cell=$(this);var i=this.column;this.order=this.count++%2;if(this.lockedOrder)this.order=this.lockedOrder;if(!e[config.sortMultiSortKey]){config.sortList=[];if(config.sortForce!=null){var a=config.sortForce;for(var j=0;j<a.length;j++){if(a[j][0]!=i){config.sortList.push(a[j]);}}}config.sortList.push([i,this.order]);}else{if(isValueInArray(i,config.sortList)){for(var j=0;j<config.sortList.length;j++){var s=config.sortList[j],o=config.headerList[s[0]];if(s[0]==i){o.count=s[1];o.count++;s[1]=o.count%2;}}}else{config.sortList.push([i,this.order]);}};setTimeout(function(){setHeadersCss($this[0],$headers,config.sortList,sortCSS);appendToTable($this[0],multisort($this[0],config.sortList,cache));},1);return false;}}).mousedown(function(){if(config.cancelSelection){this.onselectstart=function(){return false};return false;}});$this.bind("update",function(){var me=this;setTimeout(function(){me.config.parsers=buildParserCache(me,$headers);cache=buildCache(me);},1);}).bind("updateCell",function(e,cell){var config=this.config;var pos=[(cell.parentNode.rowIndex-1),cell.cellIndex];cache.normalized[pos[0]][pos[1]]=config.parsers[pos[1]].format(getElementText(config,cell),cell);}).bind("sorton",function(e,list){$(this).trigger("sortStart");config.sortList=list;var sortList=config.sortList;updateHeaderSortCount(this,sortList);setHeadersCss(this,$headers,sortList,sortCSS);appendToTable(this,multisort(this,sortList,cache));}).bind("appendCache",function(){appendToTable(this,cache);}).bind("applyWidgetId",function(e,id){getWidgetById(id).format(this);}).bind("applyWidgets",function(){applyWidget(this);});if($.metadata&&($(this).metadata()&&$(this).metadata().sortlist)){config.sortList=$(this).metadata().sortlist;}if(config.sortList.length>0){$this.trigger("sorton",[config.sortList]);}applyWidget(this);});};this.addParser=function(parser){var l=parsers.length,a=true;for(var i=0;i<l;i++){if(parsers[i].id.toLowerCase()==parser.id.toLowerCase()){a=false;}}if(a){parsers.push(parser);};};this.addWidget=function(widget){widgets.push(widget);};this.formatFloat=function(s){var i=parseFloat(s);return(isNaN(i))?0:i;};this.formatInt=function(s){var i=parseInt(s);return(isNaN(i))?0:i;};this.isDigit=function(s,config){return/^[-+]?\d*$/.test($.trim(s.replace(/[,.']/g,'')));};this.clearTableBody=function(table){if($.browser.msie){function empty(){while(this.firstChild)this.removeChild(this.firstChild);}empty.apply(table.tBodies[0]);}else{table.tBodies[0].innerHTML="";}};}});$.fn.extend({tablesorter:$.tablesorter.construct});var ts=$.tablesorter;ts.addParser({id:"text",is:function(s){return true;},format:function(s){return $.trim(s.toLocaleLowerCase());},type:"text"});ts.addParser({id:"digit",is:function(s,table){var c=table.config;return $.tablesorter.isDigit(s,c);},format:function(s){return $.tablesorter.formatFloat(s);},type:"numeric"});ts.addParser({id:"currency",is:function(s){return/^[£$€?.]/.test(s);},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/[£$€]/g),""));},type:"numeric"});ts.addParser({id:"ipAddress",is:function(s){return/^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);},format:function(s){var a=s.split("."),r="",l=a.length;for(var i=0;i<l;i++){var item=a[i];if(item.length==2){r+="0"+item;}else{r+=item;}}return $.tablesorter.formatFloat(r);},type:"numeric"});ts.addParser({id:"url",is:function(s){return/^(https?|ftp|file):\/\/$/.test(s);},format:function(s){return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),''));},type:"text"});ts.addParser({id:"isoDate",is:function(s){return/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);},format:function(s){return $.tablesorter.formatFloat((s!="")?new Date(s.replace(new RegExp(/-/g),"/")).getTime():"0");},type:"numeric"});ts.addParser({id:"percent",is:function(s){return/\%$/.test($.trim(s));},format:function(s){return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),""));},type:"numeric"});ts.addParser({id:"usLongDate",is:function(s){return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));},format:function(s){return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"shortDate",is:function(s){return/\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);},format:function(s,table){var c=table.config;s=s.replace(/\-/g,"/");if(c.dateFormat=="us"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$1/$2");}else if(c.dateFormat=="uk"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/,"$3/$2/$1");}else if(c.dateFormat=="dd/mm/yy"||c.dateFormat=="dd-mm-yy"){s=s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/,"$1/$2/$3");}return $.tablesorter.formatFloat(new Date(s).getTime());},type:"numeric"});ts.addParser({id:"time",is:function(s){return/^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);},format:function(s){return $.tablesorter.formatFloat(new Date("2000/01/01 "+s).getTime());},type:"numeric"});ts.addParser({id:"metadata",is:function(s){return false;},format:function(s,table,cell){var c=table.config,p=(!c.parserMetadataName)?'sortValue':c.parserMetadataName;return $(cell).metadata()[p];},type:"numeric"});ts.addWidget({id:"zebra",format:function(table){if(table.config.debug){var time=new Date();}var $tr,row=-1,odd;$("tr:visible",table.tBodies[0]).each(function(i){$tr=$(this);if(!$tr.hasClass(table.config.cssChildRow))row++;odd=(row%2==0);$tr.removeClass(table.config.widgetZebra.css[odd?0:1]).addClass(table.config.widgetZebra.css[odd?1:0])});if(table.config.debug){$.tablesorter.benchmark("Applying Zebra widget",time);}}});})(jQuery);
diff --git a/catapult/telemetry/third_party/WebKit/PerformanceTests/resources/statistics.js b/catapult/telemetry/third_party/WebKit/PerformanceTests/resources/statistics.js
deleted file mode 100644
index 5a14b9c..0000000
--- a/catapult/telemetry/third_party/WebKit/PerformanceTests/resources/statistics.js
+++ /dev/null
@@ -1,201 +0,0 @@
-/*
- * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-var Statistics = new (function () {
-
-    this.max = function (values) {
-        var maxVal = values[0];
-        for (var i = 1; i < values.length; i++) {
-            maxVal = Math.max(maxVal, values[i]);
-        }
-        return maxVal;
-    }
-
-    this.min = function (values) {
-        var minVal = values[0];
-        for (var i = 1; i < values.length; i++) {
-            minVal = Math.min(minVal, values[i]);
-        }
-        return minVal;
-    }
-
-    this.sum = function (values) {
-        return values.reduce(function (a, b) { return a + b; }, 0);
-    }
-
-    this.squareSum = function (values) {
-        return values.reduce(function (sum, value) { return sum + value * value;}, 0);
-    }
-
-    // With sum and sum of squares, we can compute the sample standard deviation in O(1).
-    // See https://rniwa.com/2012-11-10/sample-standard-deviation-in-terms-of-sum-and-square-sum-of-samples/
-    this.sampleStandardDeviation = function (numberOfSamples, sum, squareSum) {
-        if (numberOfSamples < 2)
-            return 0;
-        return Math.sqrt(squareSum / (numberOfSamples - 1)
-            - sum * sum / (numberOfSamples - 1) / numberOfSamples);
-    }
-
-    this.supportedConfidenceLevels = function () {
-        var supportedLevels = [];
-        for (var quantile in tDistributionInverseCDF)
-            supportedLevels.push((1 - (1 - quantile) * 2).toFixed(2));
-        return supportedLevels;
-    }
-
-    this.quantile = function (confidenceLevel, numberOfSamples, opt_degreesOfFreedom) {
-        var probability = (1 - (1 - confidenceLevel) / 2);
-        if (!(probability in tDistributionInverseCDF)) {
-            console.warn('We only support ' + this.supportedConfidenceLevels().map(
-                function (level) { return level * 100 + '%'; } ).join(', ') + ' confidence intervals.');
-            return NaN;
-        }
-        if (numberOfSamples < 2)
-            return Number.POSITIVE_INFINITY;
-
-        var cdfForProbability = tDistributionInverseCDF[probability];
-        var degreesOfFreedom = opt_degreesOfFreedom;
-        if (degreesOfFreedom === undefined)
-          degreesOfFreedom = numberOfSamples - 1;
-
-        // tDistributionQuantile(degreesOfFreedom, confidenceLevel) * sampleStandardDeviation / sqrt(numberOfSamples) * S/sqrt(numberOfSamples)
-        if (degreesOfFreedom <= 100)
-          return cdfForProbability[degreesOfFreedom - 1]; // The first entry is for the one degree of freedom.
-        else if (degreesOfFreedom <= 300)
-          return cdfForProbability[Math.round(degreesOfFreedom / 10) + 100 - 10 - 1];
-        else if (degreesOfFreedom <= 1300)
-          return cdfForProbability[Math.round(degreesOfFreedom / 100) + 120 - 3 - 1];
-        else
-          return cdfForProbability[cdfForProbability.length - 1];
-    }
-
-    // Computes the delta d s.t. (mean - d, mean + d) is the confidence interval with the specified confidence level in O(1).
-    this.confidenceIntervalDelta = function (confidenceLevel, numberOfSamples, sum, squareSum) {
-        var sampleStandardDeviation = this.sampleStandardDeviation(numberOfSamples, sum, squareSum);
-        return this.confidenceIntervalDeltaFromStd(confidenceLevel, numberOfSamples, sampleStandardDeviation);
-    }
-
-    this.confidenceIntervalDeltaFromStd = function (confidenceLevel, numberOfSamples, sampleStandardDeviation, opt_degreesOfFreedom) {
-        var quantile = this.quantile(confidenceLevel, numberOfSamples, opt_degreesOfFreedom);
-        return quantile * sampleStandardDeviation / Math.sqrt(numberOfSamples);
-    }
-
-
-    this.confidenceInterval = function (values, probability) {
-        var sum = this.sum(values);
-        var mean = sum / values.length;
-        var delta = this.confidenceIntervalDelta(probability || 0.95, values.length, sum, this.squareSum(values));
-        return [mean - delta, mean + delta];
-    }
-
-    // See http://en.wikipedia.org/wiki/Student's_t-distribution#Table_of_selected_values
-    // This table contains one sided (a.k.a. tail) values.
-    // Use TINV((1 - probability) * 2, df) in your favorite spreadsheet software to compute these.
-    // The spacing of the values with df greater than 100 maintains error less than 0.8%.
-    var tDistributionInverseCDF = {
-        0.9: [
-            // 1 - 100 step 1
-            3.077684, 1.885618, 1.637744, 1.533206, 1.475884, 1.439756, 1.414924, 1.396815, 1.383029, 1.372184,
-            1.363430, 1.356217, 1.350171, 1.345030, 1.340606, 1.336757, 1.333379, 1.330391, 1.327728, 1.325341,
-            1.323188, 1.321237, 1.319460, 1.317836, 1.316345, 1.314972, 1.313703, 1.312527, 1.311434, 1.310415,
-            1.309464, 1.308573, 1.307737, 1.306952, 1.306212, 1.305514, 1.304854, 1.304230, 1.303639, 1.303077,
-            1.302543, 1.302035, 1.301552, 1.301090, 1.300649, 1.300228, 1.299825, 1.299439, 1.299069, 1.298714,
-            1.298373, 1.298045, 1.297730, 1.297426, 1.297134, 1.296853, 1.296581, 1.296319, 1.296066, 1.295821,
-            1.295585, 1.295356, 1.295134, 1.294920, 1.294712, 1.294511, 1.294315, 1.294126, 1.293942, 1.293763,
-            1.293589, 1.293421, 1.293256, 1.293097, 1.292941, 1.292790, 1.292643, 1.292500, 1.292360, 1.292224,
-            1.292091, 1.291961, 1.291835, 1.291711, 1.291591, 1.291473, 1.291358, 1.291246, 1.291136, 1.291029,
-            1.290924, 1.290821, 1.290721, 1.290623, 1.290527, 1.290432, 1.290340, 1.290250, 1.290161, 1.290075,
-            // 110 - 300 step 10
-            1.289295, 1.288646, 1.288098, 1.287628, 1.287221, 1.286865, 1.286551, 1.286272, 1.286023, 1.285799,
-            1.285596, 1.285411, 1.285243, 1.285089, 1.284947, 1.284816, 1.284695, 1.284582, 1.284478, 1.284380,
-            // 400 - 1300 step 100
-            1.283672, 1.283247, 1.282964, 1.282762, 1.282611, 1.282493, 1.282399, 1.282322, 1.282257, 1.282203,
-            // Infinity
-            1.281548],
-        0.95: [
-            // 1 - 100 step 1
-            6.313752, 2.919986, 2.353363, 2.131847, 2.015048, 1.943180, 1.894579, 1.859548, 1.833113, 1.812461,
-            1.795885, 1.782288, 1.770933, 1.761310, 1.753050, 1.745884, 1.739607, 1.734064, 1.729133, 1.724718,
-            1.720743, 1.717144, 1.713872, 1.710882, 1.708141, 1.705618, 1.703288, 1.701131, 1.699127, 1.697261,
-            1.695519, 1.693889, 1.692360, 1.690924, 1.689572, 1.688298, 1.687094, 1.685954, 1.684875, 1.683851,
-            1.682878, 1.681952, 1.681071, 1.680230, 1.679427, 1.678660, 1.677927, 1.677224, 1.676551, 1.675905,
-            1.675285, 1.674689, 1.674116, 1.673565, 1.673034, 1.672522, 1.672029, 1.671553, 1.671093, 1.670649,
-            1.670219, 1.669804, 1.669402, 1.669013, 1.668636, 1.668271, 1.667916, 1.667572, 1.667239, 1.666914,
-            1.666600, 1.666294, 1.665996, 1.665707, 1.665425, 1.665151, 1.664885, 1.664625, 1.664371, 1.664125,
-            1.663884, 1.663649, 1.663420, 1.663197, 1.662978, 1.662765, 1.662557, 1.662354, 1.662155, 1.661961,
-            1.661771, 1.661585, 1.661404, 1.661226, 1.661052, 1.660881, 1.660715, 1.660551, 1.660391, 1.660234,
-            // 110 - 300 step 10
-            1.658824, 1.657651, 1.656659, 1.655811, 1.655076, 1.654433, 1.653866, 1.653363, 1.652913, 1.652508,
-            1.652142, 1.651809, 1.651506, 1.651227, 1.650971, 1.650735, 1.650517, 1.650314, 1.650125, 1.649949,
-            // 400 - 1300 step 100
-            1.648672, 1.647907, 1.647397, 1.647033, 1.646761, 1.646548, 1.646379, 1.646240, 1.646124, 1.646027,
-            // Infinity
-            1.644847],
-        0.975: [
-            // 1 - 100 step 1
-            12.706205, 4.302653, 3.182446, 2.776445, 2.570582, 2.446912, 2.364624, 2.306004, 2.262157, 2.228139,
-            2.200985, 2.178813, 2.160369, 2.144787, 2.131450, 2.119905, 2.109816, 2.100922, 2.093024, 2.085963,
-            2.079614, 2.073873, 2.068658, 2.063899, 2.059539, 2.055529, 2.051831, 2.048407, 2.045230, 2.042272,
-            2.039513, 2.036933, 2.034515, 2.032245, 2.030108, 2.028094, 2.026192, 2.024394, 2.022691, 2.021075,
-            2.019541, 2.018082, 2.016692, 2.015368, 2.014103, 2.012896, 2.011741, 2.010635, 2.009575, 2.008559,
-            2.007584, 2.006647, 2.005746, 2.004879, 2.004045, 2.003241, 2.002465, 2.001717, 2.000995, 2.000298,
-            1.999624, 1.998972, 1.998341, 1.997730, 1.997138, 1.996564, 1.996008, 1.995469, 1.994945, 1.994437,
-            1.993943, 1.993464, 1.992997, 1.992543, 1.992102, 1.991673, 1.991254, 1.990847, 1.990450, 1.990063,
-            1.989686, 1.989319, 1.988960, 1.988610, 1.988268, 1.987934, 1.987608, 1.987290, 1.986979, 1.986675,
-            1.986377, 1.986086, 1.985802, 1.985523, 1.985251, 1.984984, 1.984723, 1.984467, 1.984217, 1.983972,
-            // 110 - 300 step 10
-            1.981765, 1.979930, 1.978380, 1.977054, 1.975905, 1.974902, 1.974017, 1.973231, 1.972528, 1.971896,
-            1.971325, 1.970806, 1.970332, 1.969898, 1.969498, 1.969130, 1.968789, 1.968472, 1.968178, 1.967903,
-            // 400 - 1300 step 100
-            1.965912, 1.964720, 1.963926, 1.963359, 1.962934, 1.962603, 1.962339, 1.962123, 1.961943, 1.961790,
-            // Infinity
-            1.959964],
-        0.99: [
-            // 1 - 100 step 1
-            31.820516, 6.964557, 4.540703, 3.746947, 3.364930, 3.142668, 2.997952, 2.896459, 2.821438, 2.763769,
-            2.718079, 2.680998, 2.650309, 2.624494, 2.602480, 2.583487, 2.566934, 2.552380, 2.539483, 2.527977,
-            2.517648, 2.508325, 2.499867, 2.492159, 2.485107, 2.478630, 2.472660, 2.467140, 2.462021, 2.457262,
-            2.452824, 2.448678, 2.444794, 2.441150, 2.437723, 2.434494, 2.431447, 2.428568, 2.425841, 2.423257,
-            2.420803, 2.418470, 2.416250, 2.414134, 2.412116, 2.410188, 2.408345, 2.406581, 2.404892, 2.403272,
-            2.401718, 2.400225, 2.398790, 2.397410, 2.396081, 2.394801, 2.393568, 2.392377, 2.391229, 2.390119,
-            2.389047, 2.388011, 2.387008, 2.386037, 2.385097, 2.384186, 2.383302, 2.382446, 2.381615, 2.380807,
-            2.380024, 2.379262, 2.378522, 2.377802, 2.377102, 2.376420, 2.375757, 2.375111, 2.374482, 2.373868,
-            2.373270, 2.372687, 2.372119, 2.371564, 2.371022, 2.370493, 2.369977, 2.369472, 2.368979, 2.368497,
-            2.368026, 2.367566, 2.367115, 2.366674, 2.366243, 2.365821, 2.365407, 2.365002, 2.364606, 2.364217,
-            // 110 - 300 step 10
-            2.360726, 2.357825, 2.355375, 2.353278, 2.351465, 2.349880, 2.348483, 2.347243, 2.346134, 2.345137,
-            2.344236, 2.343417, 2.342670, 2.341985, 2.341356, 2.340775, 2.340238, 2.339739, 2.339275, 2.338842,
-            // 400 - 1300 step 100
-            2.335706, 2.333829, 2.332579, 2.331687, 2.331018, 2.330498, 2.330083, 2.329743, 2.329459, 2.329220,
-            // Infinity
-            2.326348],
-    };
-
-})();
-
-if (typeof module != 'undefined') {
-    for (var key in Statistics)
-        module.exports[key] = Statistics[key];
-}
diff --git a/catapult/telemetry/third_party/WebKit/README.chromium b/catapult/telemetry/third_party/WebKit/README.chromium
deleted file mode 100644
index 798990b..0000000
--- a/catapult/telemetry/third_party/WebKit/README.chromium
+++ /dev/null
@@ -1,14 +0,0 @@
-Name: Blink javascript libraries.
-Short Name: Blink
-URL: http://www.chromium.org/blink
-Version: N/A
-License: BSD license
-License File: NOT_SHIPPED
-Security Critical: no
-Description: Blink javascripts libraries are used for visualize performance
-metrics.
-Local Modifications: All the files not needed by telemetry are removed. Only
-keep jquery.tablesorter.min.js and statistics.js.
-statistics.js is modified to support computing confidenceIntervalDelta with
-custom standard deviation & degrees of freedom (see
-https://codereview.chromium.org/1309143006).
diff --git a/catapult/telemetry/third_party/__init__.py b/catapult/telemetry/third_party/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/altgraph/MANIFEST.in b/catapult/telemetry/third_party/altgraph/MANIFEST.in
deleted file mode 100644
index 9a9b960..0000000
--- a/catapult/telemetry/third_party/altgraph/MANIFEST.in
+++ /dev/null
@@ -1,9 +0,0 @@
-include ReadMe.txt
-include *.txt MANIFEST.in *.py
-graft doc
-graft doc/_static
-graft doc/_templates
-graft altgraph_tests
-global-exclude .DS_Store
-global-exclude *.pyc
-global-exclude *.so
diff --git a/catapult/telemetry/third_party/altgraph/PKG-INFO b/catapult/telemetry/third_party/altgraph/PKG-INFO
deleted file mode 100644
index 87b602f..0000000
--- a/catapult/telemetry/third_party/altgraph/PKG-INFO
+++ /dev/null
@@ -1,216 +0,0 @@
-Metadata-Version: 1.1
-Name: altgraph
-Version: 0.12
-Summary: Python graph (network) package
-Home-page: http://packages.python.org/altgraph
-Author: Ronald Oussoren
-Author-email: ronaldoussoren@mac.com
-License: MIT
-Download-URL: http://pypi.python.org/pypi/altgraph
-Description: altgraph is a fork of graphlib: a graph (network) package for constructing
-        graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
-        graphviz output.
-        
-        altgraph includes some additional usage of Python 2.6+ features and
-        enhancements related to modulegraph and macholib.
-        
-        
-        Release history
-        ===============
-        
-        0.12
-        ----
-        
-        - Added ``ObjectGraph.edgeData`` to retrieve the edge data
-          from a specific edge.
-        
-        - Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
-          to update the data associated with a graph edge.
-        
-        0.11
-        ----
-        
-        - Stabilize the order of elements in dot file exports,
-          patch from bitbucket user 'pombredanne'.
-        
-        - Tweak setup.py file to remove dependency on distribute (but
-          keep the dependency on setuptools)
-        
-        
-        0.10.2
-        ------
-        
-        - There where no classifiers in the package metadata due to a bug
-          in setup.py
-        
-        0.10.1
-        ------
-        
-        This is a bugfix release
-        
-        Bug fixes:
-        
-        - Issue #3: The source archive contains a README.txt
-          while the setup file refers to ReadMe.txt.
-        
-          This is caused by a misfeature in distutils, as a
-          workaround I've renamed ReadMe.txt to README.txt
-          in the source tree and setup file.
-        
-        
-        0.10
-        -----
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - Do not use "2to3" to support Python 3.
-        
-          As a side effect of this altgraph now supports
-          Python 2.6 and later, and no longer supports
-          earlier releases of Python.
-        
-        - The order of attributes in the Dot output
-          is now always alphabetical.
-        
-          With this change the output will be consistent
-          between runs and Python versions.
-        
-        0.9
-        ---
-        
-        This is a minor bugfix release
-        
-        Features:
-        
-        - Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
-          yielding all nodes in an object graph.
-        
-        Bugfixes:
-        
-        - The 0.8 release didn't work with py2app when using
-          python 3.x.
-        
-        
-        0.8
-        -----
-        
-        This is a minor feature release. The major new feature
-        is a extensive set of unittests, which explains almost
-        all other changes in this release.
-        
-        Bugfixes:
-        
-        - Installing failed with Python 2.5 due to using a distutils
-          class that isn't available in that version of Python
-          (issue #1 on the issue tracker)
-        
-        - ``altgraph.GraphStat.degree_dist`` now actually works
-        
-        - ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
-          no longer create the edge when one of the nodes doesn't
-          exist.
-        
-        - ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
-        
-        - ``altgraph.Graph.back_topo_sort`` was completely broken in
-          previous releases.
-        
-        - ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
-        
-        - ``altgraph.Graph.back_bfs_subgraph`` now actually works.
-        
-        - ``altgraph.Graph.iterdfs`` now returns the correct result
-          when the ``forward`` argument is ``False``.
-        
-        - ``altgraph.Graph.iterdata`` now returns the correct result
-          when the ``forward`` argument is ``False``.
-        
-        
-        Features:
-        
-        - The ``altgraph.Graph`` constructor now accepts an argument
-          that contains 2- and 3-tuples instead of requireing that
-          all items have the same size. The (optional) argument can now
-          also be any iterator.
-        
-        - ``altgraph.Graph.Graph.add_node`` has no effect when you
-          add a hidden node.
-        
-        - The private method ``altgraph.Graph._bfs`` is no longer
-          present.
-        
-        - The private method ``altgraph.Graph._dfs`` is no longer
-          present.
-        
-        - ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
-          which means you can use the ``in`` operator to check if a
-          node is part of a graph.
-        
-        - ``altgraph.GraphUtil.generate_random_graph`` will raise
-          ``GraphError`` instead of looping forever when it is
-          impossible to create the requested graph.
-        
-        - ``altgraph.Dot.edge_style`` raises ``GraphError`` when
-          one of the nodes is not present in the graph. The method
-          silently added the tail in the past, but without ensuring
-          a consistent graph state.
-        
-        - ``altgraph.Dot.save_img`` now works when the mode is
-          ``"neato"``.
-        
-        0.7.2
-        -----
-        
-        This is a minor bugfix release
-        
-        Bugfixes:
-        
-        - distutils didn't include the documentation subtree
-        
-        0.7.1
-        -----
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
-          and can be viewed at <http://packages.python.org/altgraph>.
-        
-        - The repository has moved to bitbucket
-        
-        - ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
-          implementation and no specified behaviour.
-        
-        - the module ``altgraph.compat`` is gone, which means altgraph will no
-          longer work with Python 2.3.
-        
-        
-        0.7.0
-        -----
-        
-        This is a minor feature release.
-        
-        Features:
-        
-        - Support for Python 3
-        
-        - It is now possible to run tests using 'python setup.py test'
-        
-          (The actual testsuite is still very minimal though)
-        
-Keywords: graph
-Platform: any
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Scientific/Engineering :: Mathematics
-Classifier: Topic :: Scientific/Engineering :: Visualization
diff --git a/catapult/telemetry/third_party/altgraph/README.chromium b/catapult/telemetry/third_party/altgraph/README.chromium
deleted file mode 100644
index f9f0cae..0000000
--- a/catapult/telemetry/third_party/altgraph/README.chromium
+++ /dev/null
@@ -1,12 +0,0 @@
-Name: altgraph
-Short Name: altgraph
-URL: https://pypi.python.org/pypi/altgraph/
-Version: 0.12
-License: MIT
-License File: NOT_SHIPPED
-Security Critical: no
-Description: altgraph is a fork of graphlib: a graph (network) package for
-constructing graphs, BFS and DFS traversals, topological sort, shortest paths,
-etc. with graphviz output. altgraph is used by
-telemetry/third_party/modulegraph.
-Local modification: remove doc/_build directory.
diff --git a/catapult/telemetry/third_party/altgraph/README.txt b/catapult/telemetry/third_party/altgraph/README.txt
deleted file mode 100644
index 904a14b..0000000
--- a/catapult/telemetry/third_party/altgraph/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-altgraph is a fork of graphlib: a graph (network) package for constructing
-graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
-graphviz output.
-
-altgraph includes some additional usage of Python 2.6+ features and
-enhancements related to modulegraph and macholib.
diff --git a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/PKG-INFO b/catapult/telemetry/third_party/altgraph/altgraph.egg-info/PKG-INFO
deleted file mode 100644
index 87b602f..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/PKG-INFO
+++ /dev/null
@@ -1,216 +0,0 @@
-Metadata-Version: 1.1
-Name: altgraph
-Version: 0.12
-Summary: Python graph (network) package
-Home-page: http://packages.python.org/altgraph
-Author: Ronald Oussoren
-Author-email: ronaldoussoren@mac.com
-License: MIT
-Download-URL: http://pypi.python.org/pypi/altgraph
-Description: altgraph is a fork of graphlib: a graph (network) package for constructing
-        graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
-        graphviz output.
-        
-        altgraph includes some additional usage of Python 2.6+ features and
-        enhancements related to modulegraph and macholib.
-        
-        
-        Release history
-        ===============
-        
-        0.12
-        ----
-        
-        - Added ``ObjectGraph.edgeData`` to retrieve the edge data
-          from a specific edge.
-        
-        - Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
-          to update the data associated with a graph edge.
-        
-        0.11
-        ----
-        
-        - Stabilize the order of elements in dot file exports,
-          patch from bitbucket user 'pombredanne'.
-        
-        - Tweak setup.py file to remove dependency on distribute (but
-          keep the dependency on setuptools)
-        
-        
-        0.10.2
-        ------
-        
-        - There where no classifiers in the package metadata due to a bug
-          in setup.py
-        
-        0.10.1
-        ------
-        
-        This is a bugfix release
-        
-        Bug fixes:
-        
-        - Issue #3: The source archive contains a README.txt
-          while the setup file refers to ReadMe.txt.
-        
-          This is caused by a misfeature in distutils, as a
-          workaround I've renamed ReadMe.txt to README.txt
-          in the source tree and setup file.
-        
-        
-        0.10
-        -----
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - Do not use "2to3" to support Python 3.
-        
-          As a side effect of this altgraph now supports
-          Python 2.6 and later, and no longer supports
-          earlier releases of Python.
-        
-        - The order of attributes in the Dot output
-          is now always alphabetical.
-        
-          With this change the output will be consistent
-          between runs and Python versions.
-        
-        0.9
-        ---
-        
-        This is a minor bugfix release
-        
-        Features:
-        
-        - Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
-          yielding all nodes in an object graph.
-        
-        Bugfixes:
-        
-        - The 0.8 release didn't work with py2app when using
-          python 3.x.
-        
-        
-        0.8
-        -----
-        
-        This is a minor feature release. The major new feature
-        is a extensive set of unittests, which explains almost
-        all other changes in this release.
-        
-        Bugfixes:
-        
-        - Installing failed with Python 2.5 due to using a distutils
-          class that isn't available in that version of Python
-          (issue #1 on the issue tracker)
-        
-        - ``altgraph.GraphStat.degree_dist`` now actually works
-        
-        - ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
-          no longer create the edge when one of the nodes doesn't
-          exist.
-        
-        - ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
-        
-        - ``altgraph.Graph.back_topo_sort`` was completely broken in
-          previous releases.
-        
-        - ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
-        
-        - ``altgraph.Graph.back_bfs_subgraph`` now actually works.
-        
-        - ``altgraph.Graph.iterdfs`` now returns the correct result
-          when the ``forward`` argument is ``False``.
-        
-        - ``altgraph.Graph.iterdata`` now returns the correct result
-          when the ``forward`` argument is ``False``.
-        
-        
-        Features:
-        
-        - The ``altgraph.Graph`` constructor now accepts an argument
-          that contains 2- and 3-tuples instead of requireing that
-          all items have the same size. The (optional) argument can now
-          also be any iterator.
-        
-        - ``altgraph.Graph.Graph.add_node`` has no effect when you
-          add a hidden node.
-        
-        - The private method ``altgraph.Graph._bfs`` is no longer
-          present.
-        
-        - The private method ``altgraph.Graph._dfs`` is no longer
-          present.
-        
-        - ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
-          which means you can use the ``in`` operator to check if a
-          node is part of a graph.
-        
-        - ``altgraph.GraphUtil.generate_random_graph`` will raise
-          ``GraphError`` instead of looping forever when it is
-          impossible to create the requested graph.
-        
-        - ``altgraph.Dot.edge_style`` raises ``GraphError`` when
-          one of the nodes is not present in the graph. The method
-          silently added the tail in the past, but without ensuring
-          a consistent graph state.
-        
-        - ``altgraph.Dot.save_img`` now works when the mode is
-          ``"neato"``.
-        
-        0.7.2
-        -----
-        
-        This is a minor bugfix release
-        
-        Bugfixes:
-        
-        - distutils didn't include the documentation subtree
-        
-        0.7.1
-        -----
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
-          and can be viewed at <http://packages.python.org/altgraph>.
-        
-        - The repository has moved to bitbucket
-        
-        - ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
-          implementation and no specified behaviour.
-        
-        - the module ``altgraph.compat`` is gone, which means altgraph will no
-          longer work with Python 2.3.
-        
-        
-        0.7.0
-        -----
-        
-        This is a minor feature release.
-        
-        Features:
-        
-        - Support for Python 3
-        
-        - It is now possible to run tests using 'python setup.py test'
-        
-          (The actual testsuite is still very minimal though)
-        
-Keywords: graph
-Platform: any
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Scientific/Engineering :: Mathematics
-Classifier: Topic :: Scientific/Engineering :: Visualization
diff --git a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/SOURCES.txt b/catapult/telemetry/third_party/altgraph/altgraph.egg-info/SOURCES.txt
deleted file mode 100644
index c345b03..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-MANIFEST.in
-README.txt
-ReadMe.txt
-setup.cfg
-setup.py
-altgraph/Dot.py
-altgraph/Graph.py
-altgraph/GraphAlgo.py
-altgraph/GraphStat.py
-altgraph/GraphUtil.py
-altgraph/ObjectGraph.py
-altgraph/__init__.py
-altgraph.egg-info/PKG-INFO
-altgraph.egg-info/SOURCES.txt
-altgraph.egg-info/dependency_links.txt
-altgraph.egg-info/top_level.txt
-altgraph.egg-info/zip-safe
-altgraph_tests/__init__.py
-altgraph_tests/test_altgraph.py
-altgraph_tests/test_dot.py
-altgraph_tests/test_graph.py
-altgraph_tests/test_graphstat.py
-altgraph_tests/test_graphutil.py
-altgraph_tests/test_object_graph.py
-doc/Makefile
-doc/changelog.rst
-doc/conf.py
-doc/core.rst
-doc/dot.rst
-doc/graph.rst
-doc/graphalgo.rst
-doc/graphstat.rst
-doc/graphutil.rst
-doc/index.rst
-doc/license.rst
-doc/objectgraph.rst
-doc/_build/doctrees/changelog.doctree
-doc/_build/doctrees/core.doctree
-doc/_build/doctrees/dot.doctree
-doc/_build/doctrees/environment.pickle
-doc/_build/doctrees/graph.doctree
-doc/_build/doctrees/graphalgo.doctree
-doc/_build/doctrees/graphstat.doctree
-doc/_build/doctrees/graphutil.doctree
-doc/_build/doctrees/index.doctree
-doc/_build/doctrees/license.doctree
-doc/_build/doctrees/objectgraph.doctree
-doc/_build/html/.buildinfo
-doc/_build/html/changelog.html
-doc/_build/html/core.html
-doc/_build/html/dot.html
-doc/_build/html/genindex.html
-doc/_build/html/graph.html
-doc/_build/html/graphalgo.html
-doc/_build/html/graphstat.html
-doc/_build/html/graphutil.html
-doc/_build/html/index.html
-doc/_build/html/license.html
-doc/_build/html/objectgraph.html
-doc/_build/html/objects.inv
-doc/_build/html/py-modindex.html
-doc/_build/html/search.html
-doc/_build/html/searchindex.js
-doc/_build/html/_sources/changelog.txt
-doc/_build/html/_sources/core.txt
-doc/_build/html/_sources/dot.txt
-doc/_build/html/_sources/graph.txt
-doc/_build/html/_sources/graphalgo.txt
-doc/_build/html/_sources/graphstat.txt
-doc/_build/html/_sources/graphutil.txt
-doc/_build/html/_sources/index.txt
-doc/_build/html/_sources/license.txt
-doc/_build/html/_sources/objectgraph.txt
-doc/_build/html/_static/ajax-loader.gif
-doc/_build/html/_static/basic.css
-doc/_build/html/_static/comment-bright.png
-doc/_build/html/_static/comment-close.png
-doc/_build/html/_static/comment.png
-doc/_build/html/_static/doctools.js
-doc/_build/html/_static/down-pressed.png
-doc/_build/html/_static/down.png
-doc/_build/html/_static/file.png
-doc/_build/html/_static/jquery.js
-doc/_build/html/_static/minus.png
-doc/_build/html/_static/nature.css
-doc/_build/html/_static/plus.png
-doc/_build/html/_static/pygments.css
-doc/_build/html/_static/searchtools.js
-doc/_build/html/_static/underscore.js
-doc/_build/html/_static/up-pressed.png
-doc/_build/html/_static/up.png
-doc/_build/html/_static/websupport.js
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/dependency_links.txt b/catapult/telemetry/third_party/altgraph/altgraph.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/top_level.txt b/catapult/telemetry/third_party/altgraph/altgraph.egg-info/top_level.txt
deleted file mode 100644
index 5ad6b8a..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-altgraph
diff --git a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/zip-safe b/catapult/telemetry/third_party/altgraph/altgraph.egg-info/zip-safe
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph.egg-info/zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/Dot.py b/catapult/telemetry/third_party/altgraph/altgraph/Dot.py
deleted file mode 100644
index 49a471e..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/Dot.py
+++ /dev/null
@@ -1,299 +0,0 @@
-'''
-altgraph.Dot - Interface to the dot language
-============================================
-
-The :py:mod:`~altgraph.Dot` module provides a simple interface to the
-file format used in the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
-program. The module is intended to offload the most tedious part of the process
-(the **dot** file generation) while transparently exposing most of its features.
-
-To display the graphs or to generate image files the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
-package needs to be installed on the system, moreover the :command:`dot` and :command:`dotty` programs must
-be accesible in the program path so that they can be ran from processes spawned
-within the module.
-
-Example usage
--------------
-
-Here is a typical usage::
-
-    from altgraph import Graph, Dot
-
-    # create a graph
-    edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
-    graph = Graph.Graph(edges)
-
-    # create a dot representation of the graph
-    dot = Dot.Dot(graph)
-
-    # display the graph
-    dot.display()
-
-    # save the dot representation into the mydot.dot file
-    dot.save_dot(file_name='mydot.dot')
-
-    # save dot file as gif image into the graph.gif file
-    dot.save_img(file_name='graph', file_type='gif')
-
-Directed graph and non-directed graph
--------------------------------------
-
-Dot class can use for both directed graph and non-directed graph
-by passing ``graphtype`` parameter.
-
-Example::
-
-    # create directed graph(default)
-    dot = Dot.Dot(graph, graphtype="digraph")
-
-    # create non-directed graph
-    dot = Dot.Dot(graph, graphtype="graph")
-
-Customizing the output
-----------------------
-
-The graph drawing process may be customized by passing
-valid :command:`dot` parameters for the nodes and edges. For a list of all
-parameters see the `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
-documentation.
-
-Example::
-
-    # customizing the way the overall graph is drawn
-    dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
-
-    # customizing node drawing
-    dot.node_style(1, label='BASE_NODE',shape='box', color='blue' )
-    dot.node_style(2, style='filled', fillcolor='red')
-
-    # customizing edge drawing
-    dot.edge_style(1, 2, style='dotted')
-    dot.edge_style(3, 5, arrowhead='dot', label='binds', labelangle='90')
-    dot.edge_style(4, 5, arrowsize=2, style='bold')
-
-
-.. note::
-
-   dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
-   display all graphics styles. To verify the output save it to an image file
-   and look at it that way.
-
-Valid attributes
-----------------
-
-    - dot styles, passed via the :py:meth:`Dot.style` method::
-
-        rankdir = 'LR'   (draws the graph horizontally, left to right)
-        ranksep = number (rank separation in inches)
-
-    - node attributes, passed via the :py:meth:`Dot.node_style` method::
-
-        style = 'filled' | 'invisible' | 'diagonals' | 'rounded'
-        shape = 'box' | 'ellipse' | 'circle' | 'point' | 'triangle'
-
-    - edge attributes, passed via the :py:meth:`Dot.edge_style` method::
-
-        style     = 'dashed' | 'dotted' | 'solid' | 'invis' | 'bold'
-        arrowhead = 'box' | 'crow' | 'diamond' | 'dot' | 'inv' | 'none' | 'tee' | 'vee'
-        weight    = number (the larger the number the closer the nodes will be)
-
-    - valid `graphviz colors <http://www.research.att.com/~erg/graphviz/info/colors.html>`_
-
-    - for more details on how to control the graph drawing process see the
-      `graphviz reference <http://www.research.att.com/sw/tools/graphviz/refs.html>`_.
-'''
-import os
-import warnings
-
-from altgraph import GraphError
-
-
-class Dot(object):
-    '''
-    A  class providing a **graphviz** (dot language) representation
-    allowing a fine grained control over how the graph is being
-    displayed.
-
-    If the :command:`dot` and :command:`dotty` programs are not in the current system path
-    their location needs to be specified in the contructor.
-    '''
-
-    def __init__(self, graph=None, nodes=None, edgefn=None, nodevisitor=None, edgevisitor=None, name="G", dot='dot', dotty='dotty', neato='neato', graphtype="digraph"):
-        '''
-        Initialization.
-        '''
-        self.name, self.attr = name, {}
-
-        assert graphtype in ['graph', 'digraph']
-        self.type = graphtype
-
-        self.temp_dot = "tmp_dot.dot"
-        self.temp_neo = "tmp_neo.dot"
-
-        self.dot, self.dotty, self.neato = dot, dotty, neato
-
-        # self.nodes: node styles
-        # self.edges: edge styles
-        self.nodes, self.edges = {}, {}
-
-        if graph is not None and nodes is None:
-            nodes = graph
-        if graph is not None and edgefn is None:
-            def edgefn(node, graph=graph):
-                return graph.out_nbrs(node)
-        if nodes is None:
-            nodes = ()
-
-        seen = set()
-        for node in nodes:
-            if nodevisitor is None:
-                style = {}
-            else:
-                style = nodevisitor(node)
-            if style is not None:
-                self.nodes[node] = {}
-                self.node_style(node, **style)
-                seen.add(node)
-        if edgefn is not None:
-            for head in seen:
-                for tail in (n for n in edgefn(head) if n in seen):
-                    if edgevisitor is None:
-                        edgestyle = {}
-                    else:
-                        edgestyle = edgevisitor(head, tail)
-                    if edgestyle is not None:
-                        if head not in self.edges:
-                            self.edges[head] = {}
-                        self.edges[head][tail] = {}
-                        self.edge_style(head, tail, **edgestyle)
-
-    def style(self, **attr):
-        '''
-        Changes the overall style
-        '''
-        self.attr = attr
-
-    def display(self, mode='dot'):
-        '''
-        Displays the current graph via dotty
-        '''
-
-        if  mode == 'neato':
-            self.save_dot(self.temp_neo)
-            neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo)
-            os.system(neato_cmd)
-        else:
-            self.save_dot(self.temp_dot)
-
-        plot_cmd = "%s %s" % (self.dotty, self.temp_dot)
-        os.system(plot_cmd)
-
-    def node_style(self, node, **kwargs):
-        '''
-        Modifies a node style to the dot representation.
-        '''
-        if node not in self.edges:
-            self.edges[node] = {}
-        self.nodes[node] = kwargs
-
-    def all_node_style(self, **kwargs):
-        '''
-        Modifies all node styles
-        '''
-        for node in self.nodes:
-            self.node_style(node, **kwargs)
-
-    def edge_style(self, head, tail, **kwargs):
-        '''
-        Modifies an edge style to the dot representation.
-        '''
-        if tail not in self.nodes:
-            raise GraphError("invalid node %s" % (tail,))
-
-        try:
-            if tail not in self.edges[head]:
-                self.edges[head][tail]= {}
-            self.edges[head][tail] = kwargs
-        except KeyError:
-            raise GraphError("invalid edge  %s -> %s " % (head, tail) )
-
-    def iterdot(self):
-        # write graph title
-        if self.type == 'digraph':
-            yield 'digraph %s {\n' % (self.name,)
-        elif self.type == 'graph':
-            yield 'graph %s {\n' % (self.name,)
-
-        else:
-            raise GraphError("unsupported graphtype %s" % (self.type,))
-
-        # write overall graph attributes
-        for attr_name, attr_value in sorted(self.attr.items()):
-            yield '%s="%s";' % (attr_name, attr_value)
-        yield '\n'
-
-        # some reusable patterns
-        cpatt  = '%s="%s",'      # to separate attributes
-        epatt  = '];\n'          # to end attributes
-
-        # write node attributes
-        for node_name, node_attr in sorted(self.nodes.items()):
-            yield '\t"%s" [' % (node_name,)
-            for attr_name, attr_value in sorted(node_attr.items()):
-                yield cpatt % (attr_name, attr_value)
-            yield epatt
-
-        # write edge attributes
-        for head in sorted(self.edges):
-            for tail in sorted(self.edges[head]):
-                if self.type == 'digraph':
-                    yield '\t"%s" -> "%s" [' % (head, tail)
-                else:
-                    yield '\t"%s" -- "%s" [' % (head, tail)
-                for attr_name, attr_value in sorted(self.edges[head][tail].items()):
-                    yield cpatt % (attr_name, attr_value)
-                yield epatt
-
-        # finish file
-        yield '}\n'
-
-    def __iter__(self):
-        return self.iterdot()
-
-    def save_dot(self, file_name=None):
-        '''
-        Saves the current graph representation into a file
-        '''
-
-        if not file_name:
-            warnings.warn(DeprecationWarning, "always pass a file_name")
-            file_name = self.temp_dot
-
-        fp   = open(file_name, "w")
-        try:
-            for chunk in self.iterdot():
-                fp.write(chunk)
-        finally:
-            fp.close()
-
-    def save_img(self, file_name=None, file_type="gif", mode='dot'):
-        '''
-        Saves the dot file as an image file
-        '''
-
-        if not file_name:
-            warnings.warn(DeprecationWarning, "always pass a file_name")
-            file_name = "out"
-
-        if  mode == 'neato':
-            self.save_dot(self.temp_neo)
-            neato_cmd = "%s -o %s %s" % (self.neato, self.temp_dot, self.temp_neo)
-            os.system(neato_cmd)
-            plot_cmd = self.dot
-        else:
-            self.save_dot(self.temp_dot)
-            plot_cmd = self.dot
-
-        file_name  = "%s.%s" % (file_name, file_type)
-        create_cmd = "%s -T%s %s -o %s" % (plot_cmd, file_type, self.temp_dot, file_name)
-        os.system(create_cmd)
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/Graph.py b/catapult/telemetry/third_party/altgraph/altgraph/Graph.py
deleted file mode 100644
index 491e5c2..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/Graph.py
+++ /dev/null
@@ -1,677 +0,0 @@
-"""
-altgraph.Graph - Base Graph class
-=================================
-
-..
-  #--Version 2.1
-  #--Bob Ippolito October, 2004
-
-  #--Version 2.0
-  #--Istvan Albert June, 2004
-
-  #--Version 1.0
-  #--Nathan Denny, May 27, 1999
-"""
-
-from altgraph import GraphError
-from collections import deque
-
-class Graph(object):
-    """
-    The Graph class represents a directed graph with *N* nodes and *E* edges.
-
-    Naming conventions:
-
-    - the prefixes such as *out*, *inc* and *all* will refer to methods
-      that operate on the outgoing, incoming or all edges of that node.
-
-      For example: :py:meth:`inc_degree` will refer to the degree of the node
-      computed over the incoming edges (the number of neighbours linking to
-      the node).
-
-    - the prefixes such as *forw* and *back* will refer to the
-      orientation of the edges used in the method with respect to the node.
-
-      For example: :py:meth:`forw_bfs` will start at the node then use the outgoing
-      edges to traverse the graph (goes forward).
-    """
-
-    def __init__(self, edges=None):
-        """
-        Initialization
-        """
-
-        self.next_edge = 0
-        self.nodes, self.edges = {}, {}
-        self.hidden_edges, self.hidden_nodes = {}, {}
-
-        if edges is not None:
-            for item in edges:
-                if len(item) == 2:
-                    head, tail = item
-                    self.add_edge(head, tail)
-                elif len(item) == 3:
-                    head, tail, data = item
-                    self.add_edge(head, tail, data)
-                else:
-                    raise GraphError("Cannot create edge from %s"%(item,))
-
-
-    def __repr__(self):
-        return '<Graph: %d nodes, %d edges>' % (
-            self.number_of_nodes(), self.number_of_edges())
-
-    def add_node(self, node, node_data=None):
-        """
-        Adds a new node to the graph.  Arbitrary data can be attached to the
-        node via the node_data parameter.  Adding the same node twice will be
-        silently ignored.
-
-        The node must be a hashable value.
-        """
-        #
-        # the nodes will contain tuples that will store incoming edges,
-        # outgoing edges and data
-        #
-        # index 0 -> incoming edges
-        # index 1 -> outgoing edges
-
-        if node in self.hidden_nodes:
-            # Node is present, but hidden
-            return
-
-        if node not in self.nodes:
-            self.nodes[node] = ([], [], node_data)
-
-    def add_edge(self, head_id, tail_id, edge_data=1, create_nodes=True):
-        """
-        Adds a directed edge going from head_id to tail_id.
-        Arbitrary data can be attached to the edge via edge_data.
-        It may create the nodes if adding edges between nonexisting ones.
-
-        :param head_id: head node
-        :param tail_id: tail node
-        :param edge_data: (optional) data attached to the edge
-        :param create_nodes: (optional) creates the head_id or tail_id node in case they did not exist
-        """
-        # shorcut
-        edge = self.next_edge
-
-        # add nodes if on automatic node creation
-        if create_nodes:
-            self.add_node(head_id)
-            self.add_node(tail_id)
-
-        # update the corresponding incoming and outgoing lists in the nodes
-        # index 0 -> incoming edges
-        # index 1 -> outgoing edges
-
-        try:
-            self.nodes[tail_id][0].append(edge)
-            self.nodes[head_id][1].append(edge)
-        except KeyError:
-            raise GraphError('Invalid nodes %s -> %s' % (head_id, tail_id))
-
-        # store edge information
-        self.edges[edge] = (head_id, tail_id, edge_data)
-
-
-        self.next_edge += 1
-
-    def hide_edge(self, edge):
-        """
-        Hides an edge from the graph. The edge may be unhidden at some later
-        time.
-        """
-        try:
-            head_id, tail_id, edge_data = self.hidden_edges[edge] = self.edges[edge]
-            self.nodes[tail_id][0].remove(edge)
-            self.nodes[head_id][1].remove(edge)
-            del self.edges[edge]
-        except KeyError:
-            raise GraphError('Invalid edge %s' % edge)
-
-    def hide_node(self, node):
-        """
-        Hides a node from the graph.  The incoming and outgoing edges of the
-        node will also be hidden.  The node may be unhidden at some later time.
-        """
-        try:
-            all_edges = self.all_edges(node)
-            self.hidden_nodes[node] = (self.nodes[node], all_edges)
-            for edge in all_edges:
-                self.hide_edge(edge)
-            del self.nodes[node]
-        except KeyError:
-            raise GraphError('Invalid node %s' % node)
-
-    def restore_node(self, node):
-        """
-        Restores a previously hidden node back into the graph and restores
-        all of its incoming and outgoing edges.
-        """
-        try:
-            self.nodes[node], all_edges = self.hidden_nodes[node]
-            for edge in all_edges:
-                self.restore_edge(edge)
-            del self.hidden_nodes[node]
-        except KeyError:
-            raise GraphError('Invalid node %s' % node)
-
-    def restore_edge(self, edge):
-        """
-        Restores a previously hidden edge back into the graph.
-        """
-        try:
-            head_id, tail_id, data = self.hidden_edges[edge]
-            self.nodes[tail_id][0].append(edge)
-            self.nodes[head_id][1].append(edge)
-            self.edges[edge] = head_id, tail_id, data
-            del self.hidden_edges[edge]
-        except KeyError:
-            raise GraphError('Invalid edge %s' % edge)
-
-    def restore_all_edges(self):
-        """
-        Restores all hidden edges.
-        """
-        for edge in list(self.hidden_edges.keys()):
-            try:
-                self.restore_edge(edge)
-            except GraphError:
-                pass
-
-    def restore_all_nodes(self):
-        """
-        Restores all hidden nodes.
-        """
-        for node in list(self.hidden_nodes.keys()):
-            self.restore_node(node)
-
-    def __contains__(self, node):
-        """
-        Test whether a node is in the graph
-        """
-        return node in self.nodes
-
-    def edge_by_id(self, edge):
-        """
-        Returns the edge that connects the head_id and tail_id nodes
-        """
-        try:
-            head, tail, data =  self.edges[edge]
-        except KeyError:
-            head, tail = None, None
-            raise GraphError('Invalid edge %s' % edge)
-
-        return (head, tail)
-
-    def edge_by_node(self, head, tail):
-        """
-        Returns the edge that connects the head_id and tail_id nodes
-        """
-        for edge in self.out_edges(head):
-            if self.tail(edge) == tail:
-                return edge
-        return None
-
-    def number_of_nodes(self):
-        """
-        Returns the number of nodes
-        """
-        return len(self.nodes)
-
-    def number_of_edges(self):
-        """
-        Returns the number of edges
-        """
-        return len(self.edges)
-
-    def __iter__(self):
-        """
-        Iterates over all nodes in the graph
-        """
-        return iter(self.nodes)
-
-    def node_list(self):
-        """
-        Return a list of the node ids for all visible nodes in the graph.
-        """
-        return list(self.nodes.keys())
-
-    def edge_list(self):
-        """
-        Returns an iterator for all visible nodes in the graph.
-        """
-        return list(self.edges.keys())
-
-    def number_of_hidden_edges(self):
-        """
-        Returns the number of hidden edges
-        """
-        return len(self.hidden_edges)
-
-    def number_of_hidden_nodes(self):
-        """
-        Returns the number of hidden nodes
-        """
-        return len(self.hidden_nodes)
-
-    def hidden_node_list(self):
-        """
-        Returns the list with the hidden nodes
-        """
-        return list(self.hidden_nodes.keys())
-
-    def hidden_edge_list(self):
-        """
-        Returns a list with the hidden edges
-        """
-        return list(self.hidden_edges.keys())
-
-    def describe_node(self, node):
-        """
-        return node, node data, outgoing edges, incoming edges for node
-        """
-        incoming, outgoing, data = self.nodes[node]
-        return node, data, outgoing, incoming
-
-    def describe_edge(self, edge):
-        """
-        return edge, edge data, head, tail for edge
-        """
-        head, tail, data = self.edges[edge]
-        return edge, data, head, tail
-
-    def node_data(self, node):
-        """
-        Returns the data associated with a node
-        """
-        return self.nodes[node][2]
-
-    def edge_data(self, edge):
-        """
-        Returns the data associated with an edge
-        """
-        return self.edges[edge][2]
-
-    def update_edge_data(self, edge, edge_data):
-        """
-        Replace the edge data for a specific edge
-        """
-        self.edges[edge] = self.edges[edge][0:2] + (edge_data,)
-
-    def head(self, edge):
-        """
-        Returns the node of the head of the edge.
-        """
-        return self.edges[edge][0]
-
-    def tail(self, edge):
-        """
-        Returns node of the tail of the edge.
-        """
-        return self.edges[edge][1]
-
-    def out_nbrs(self, node):
-        """
-        List of nodes connected by outgoing edges
-        """
-        l = [self.tail(n) for n in self.out_edges(node)]
-        return l
-
-    def inc_nbrs(self, node):
-        """
-        List of nodes connected by incoming edges
-        """
-        l = [self.head(n) for n in self.inc_edges(node)]
-        return l
-
-    def all_nbrs(self, node):
-        """
-        List of nodes connected by incoming and outgoing edges
-        """
-        l = dict.fromkeys( self.inc_nbrs(node) + self.out_nbrs(node) )
-        return list(l)
-
-    def out_edges(self, node):
-        """
-        Returns a list of the outgoing edges
-        """
-        try:
-            return list(self.nodes[node][1])
-        except KeyError:
-            raise GraphError('Invalid node %s' % node)
-
-        return None
-
-    def inc_edges(self, node):
-        """
-        Returns a list of the incoming edges
-        """
-        try:
-            return list(self.nodes[node][0])
-        except KeyError:
-            raise GraphError('Invalid node %s' % node)
-
-        return None
-
-    def all_edges(self, node):
-        """
-        Returns a list of incoming and outging edges.
-        """
-        return set(self.inc_edges(node) + self.out_edges(node))
-
-    def out_degree(self, node):
-        """
-        Returns the number of outgoing edges
-        """
-        return len(self.out_edges(node))
-
-    def inc_degree(self, node):
-        """
-        Returns the number of incoming edges
-        """
-        return len(self.inc_edges(node))
-
-    def all_degree(self, node):
-        """
-        The total degree of a node
-        """
-        return self.inc_degree(node) + self.out_degree(node)
-
-    def _topo_sort(self, forward=True):
-        """
-        Topological sort.
-
-        Returns a list of nodes where the successors (based on outgoing and
-        incoming edges selected by the forward parameter) of any given node
-        appear in the sequence after that node.
-        """
-        topo_list = []
-        queue = deque()
-        indeg = {}
-
-        # select the operation that will be performed
-        if forward:
-            get_edges = self.out_edges
-            get_degree = self.inc_degree
-            get_next = self.tail
-        else:
-            get_edges = self.inc_edges
-            get_degree = self.out_degree
-            get_next = self.head
-
-        for node in self.node_list():
-            degree = get_degree(node)
-            if degree:
-                indeg[node] = degree
-            else:
-                queue.append(node)
-
-        while queue:
-            curr_node = queue.popleft()
-            topo_list.append(curr_node)
-            for edge in get_edges(curr_node):
-                tail_id = get_next(edge)
-                if tail_id in indeg:
-                    indeg[tail_id] -= 1
-                    if indeg[tail_id] == 0:
-                        queue.append(tail_id)
-
-        if len(topo_list) == len(self.node_list()):
-            valid = True
-        else:
-            # the graph has cycles, invalid topological sort
-            valid = False
-
-        return (valid, topo_list)
-
-    def forw_topo_sort(self):
-        """
-        Topological sort.
-
-        Returns a list of nodes where the successors (based on outgoing edges)
-        of any given node appear in the sequence after that node.
-        """
-        return self._topo_sort(forward=True)
-
-    def back_topo_sort(self):
-        """
-        Reverse topological sort.
-
-        Returns a list of nodes where the successors (based on incoming edges)
-        of any given node appear in the sequence after that node.
-        """
-        return self._topo_sort(forward=False)
-
-    def _bfs_subgraph(self, start_id, forward=True):
-        """
-        Private method creates a subgraph in a bfs order.
-
-        The forward parameter specifies whether it is a forward or backward
-        traversal.
-        """
-        if forward:
-            get_bfs  = self.forw_bfs
-            get_nbrs = self.out_nbrs
-        else:
-            get_bfs  = self.back_bfs
-            get_nbrs = self.inc_nbrs
-
-        g = Graph()
-        bfs_list = get_bfs(start_id)
-        for node in bfs_list:
-            g.add_node(node)
-
-        for node in bfs_list:
-            for nbr_id in get_nbrs(node):
-                g.add_edge(node, nbr_id)
-
-        return g
-
-    def forw_bfs_subgraph(self, start_id):
-        """
-        Creates and returns a subgraph consisting of the breadth first
-        reachable nodes based on their outgoing edges.
-        """
-        return self._bfs_subgraph(start_id, forward=True)
-
-    def back_bfs_subgraph(self, start_id):
-        """
-        Creates and returns a subgraph consisting of the breadth first
-        reachable nodes based on the incoming edges.
-        """
-        return self._bfs_subgraph(start_id, forward=False)
-
-    def iterdfs(self, start, end=None, forward=True):
-        """
-        Collecting nodes in some depth first traversal.
-
-        The forward parameter specifies whether it is a forward or backward
-        traversal.
-        """
-        visited, stack = set([start]), deque([start])
-
-        if forward:
-            get_edges = self.out_edges
-            get_next = self.tail
-        else:
-            get_edges = self.inc_edges
-            get_next = self.head
-
-        while stack:
-            curr_node = stack.pop()
-            yield curr_node
-            if curr_node == end:
-                break
-            for edge in sorted(get_edges(curr_node)):
-                tail = get_next(edge)
-                if tail not in visited:
-                    visited.add(tail)
-                    stack.append(tail)
-
-    def iterdata(self, start, end=None, forward=True, condition=None):
-        """
-        Perform a depth-first walk of the graph (as ``iterdfs``)
-        and yield the item data of every node where condition matches. The
-        condition callback is only called when node_data is not None.
-        """
-
-        visited, stack = set([start]), deque([start])
-
-        if forward:
-            get_edges = self.out_edges
-            get_next = self.tail
-        else:
-            get_edges = self.inc_edges
-            get_next = self.head
-
-        get_data = self.node_data
-
-        while stack:
-            curr_node = stack.pop()
-            curr_data = get_data(curr_node)
-            if curr_data is not None:
-                if condition is not None and not condition(curr_data):
-                    continue
-                yield curr_data
-            if curr_node == end:
-                break
-            for edge in get_edges(curr_node):
-                tail = get_next(edge)
-                if tail not in visited:
-                    visited.add(tail)
-                    stack.append(tail)
-
-    def _iterbfs(self, start, end=None, forward=True):
-        """
-        The forward parameter specifies whether it is a forward or backward
-        traversal.  Returns a list of tuples where the first value is the hop
-        value the second value is the node id.
-        """
-        queue, visited = deque([(start, 0)]), set([start])
-
-        # the direction of the bfs depends on the edges that are sampled
-        if forward:
-            get_edges = self.out_edges
-            get_next = self.tail
-        else:
-            get_edges = self.inc_edges
-            get_next = self.head
-
-        while queue:
-            curr_node, curr_step = queue.popleft()
-            yield (curr_node, curr_step)
-            if curr_node == end:
-                break
-            for edge in get_edges(curr_node):
-                tail = get_next(edge)
-                if tail not in visited:
-                    visited.add(tail)
-                    queue.append((tail, curr_step + 1))
-
-
-    def forw_bfs(self, start, end=None):
-        """
-        Returns a list of nodes in some forward BFS order.
-
-        Starting from the start node the breadth first search proceeds along
-        outgoing edges.
-        """
-        return [node for node, step in self._iterbfs(start, end, forward=True)]
-
-    def back_bfs(self, start, end=None):
-        """
-        Returns a list of nodes in some backward BFS order.
-
-        Starting from the start node the breadth first search proceeds along
-        incoming edges.
-        """
-        return [node for node, step in self._iterbfs(start, end, forward=False)]
-
-    def forw_dfs(self, start, end=None):
-        """
-        Returns a list of nodes in some forward DFS order.
-
-        Starting with the start node the depth first search proceeds along
-        outgoing edges.
-        """
-        return list(self.iterdfs(start, end, forward=True))
-
-    def back_dfs(self, start, end=None):
-        """
-        Returns a list of nodes in some backward DFS order.
-
-        Starting from the start node the depth first search proceeds along
-        incoming edges.
-        """
-        return list(self.iterdfs(start, end, forward=False))
-
-    def connected(self):
-        """
-        Returns :py:data:`True` if the graph's every node can be reached from every
-        other node.
-        """
-        node_list = self.node_list()
-        for node in node_list:
-            bfs_list = self.forw_bfs(node)
-            if len(bfs_list) != len(node_list):
-                return False
-        return True
-
-    def clust_coef(self, node):
-        """
-        Computes and returns the local clustering coefficient of node.  The
-        local cluster coefficient is proportion of the actual number of edges between
-        neighbours of node and the maximum number of edges between those neighbours.
-
-        See <http://en.wikipedia.org/wiki/Clustering_coefficient#Local_clustering_coefficient>
-        for a formal definition.
-        """
-        num = 0
-        nbr_set = set(self.out_nbrs(node))
-
-        if node in nbr_set:
-            nbr_set.remove(node) # loop defense
-
-        for nbr in nbr_set:
-            sec_set = set(self.out_nbrs(nbr))
-            if nbr in sec_set:
-                sec_set.remove(nbr) # loop defense
-            num += len(nbr_set & sec_set)
-
-        nbr_num = len(nbr_set)
-        if nbr_num:
-            clust_coef = float(num) / (nbr_num * (nbr_num - 1))
-        else:
-            clust_coef = 0.0
-        return clust_coef
-
-    def get_hops(self, start, end=None, forward=True):
-        """
-        Computes the hop distance to all nodes centered around a specified node.
-
-        First order neighbours are at hop 1, their neigbours are at hop 2 etc.
-        Uses :py:meth:`forw_bfs` or :py:meth:`back_bfs` depending on the value of the forward
-        parameter.  If the distance between all neighbouring nodes is 1 the hop
-        number corresponds to the shortest distance between the nodes.
-
-        :param start: the starting node
-        :param end: ending node (optional). When not specified will search the whole graph.
-        :param forward: directionality parameter (optional). If C{True} (default) it uses L{forw_bfs} otherwise L{back_bfs}.
-        :return: returns a list of tuples where each tuple contains the node and the hop.
-
-        Typical usage::
-
-            >>> print (graph.get_hops(1, 8))
-            >>> [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
-            # node 1 is at 0 hops
-            # node 2 is at 1 hop
-            # ...
-            # node 8 is at 5 hops
-        """
-        if forward:
-            return list(self._iterbfs(start=start, end=end, forward=True))
-        else:
-            return list(self._iterbfs(start=start, end=end, forward=False))
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/GraphAlgo.py b/catapult/telemetry/third_party/altgraph/altgraph/GraphAlgo.py
deleted file mode 100644
index 9e6fff2..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/GraphAlgo.py
+++ /dev/null
@@ -1,147 +0,0 @@
-'''
-altgraph.GraphAlgo - Graph algorithms
-=====================================
-'''
-from altgraph import GraphError
-
-def dijkstra(graph, start, end=None):
-    """
-    Dijkstra's algorithm for shortest paths
-
-    `David Eppstein, UC Irvine, 4 April 2002 <http://www.ics.uci.edu/~eppstein/161/python/>`_
-
-    `Python Cookbook Recipe <http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/119466>`_
-
-    Find shortest paths from the  start node to all nodes nearer than or equal to the end node.
-
-    Dijkstra's algorithm is only guaranteed to work correctly when all edge lengths are positive.
-    This code does not verify this property for all edges (only the edges examined until the end
-    vertex is reached), but will correctly compute shortest paths even for some graphs with negative
-    edges, and will raise an exception if it discovers that a negative edge has caused it to make a mistake.
-
-    *Adapted to altgraph by Istvan Albert, Pennsylvania State University - June, 9 2004*
-
-    """
-    D = {}    # dictionary of final distances
-    P = {}    # dictionary of predecessors
-    Q = _priorityDictionary()    # estimated distances of non-final vertices
-    Q[start] = 0
-
-    for v in Q:
-        D[v] = Q[v]
-        if v == end: break
-
-        for w in graph.out_nbrs(v):
-            edge_id  = graph.edge_by_node(v,w)
-            vwLength = D[v] + graph.edge_data(edge_id)
-            if w in D:
-                if vwLength < D[w]:
-                    raise GraphError("Dijkstra: found better path to already-final vertex")
-            elif w not in Q or vwLength < Q[w]:
-                Q[w] = vwLength
-                P[w] = v
-
-    return (D,P)
-
-def shortest_path(graph, start, end):
-    """
-    Find a single shortest path from the given start node to the given end node.
-    The input has the same conventions as dijkstra(). The output is a list of the nodes
-    in order along the shortest path.
-
-    **Note that the distances must be stored in the edge data as numeric data**
-    """
-
-    D,P = dijkstra(graph, start, end)
-    Path = []
-    while 1:
-        Path.append(end)
-        if end == start: break
-        end = P[end]
-    Path.reverse()
-    return Path
-
-#
-# Utility classes and functions
-#
-class _priorityDictionary(dict):
-    '''
-    Priority dictionary using binary heaps (internal use only)
-
-    David Eppstein, UC Irvine, 8 Mar 2002
-
-    Implements a data structure that acts almost like a dictionary, with two modifications:
-        1. D.smallest() returns the value x minimizing D[x].  For this to work correctly,
-            all values D[x] stored in the dictionary must be comparable.
-        2. iterating "for x in D" finds and removes the items from D in sorted order.
-            Each item is not removed until the next item is requested, so D[x] will still
-            return a useful value until the next iteration of the for-loop.
-            Each operation takes logarithmic amortized time.
-    '''
-    def __init__(self):
-        '''
-        Initialize priorityDictionary by creating binary heap of pairs (value,key).
-        Note that changing or removing a dict entry will not remove the old pair from the heap
-        until it is found by smallest() or until the heap is rebuilt.
-        '''
-        self.__heap = []
-        dict.__init__(self)
-
-    def smallest(self):
-        '''
-        Find smallest item after removing deleted items from front of heap.
-        '''
-        if len(self) == 0:
-            raise IndexError("smallest of empty priorityDictionary")
-        heap = self.__heap
-        while heap[0][1] not in self or self[heap[0][1]] != heap[0][0]:
-            lastItem = heap.pop()
-            insertionPoint = 0
-            while 1:
-                smallChild = 2*insertionPoint+1
-                if smallChild+1 < len(heap) and heap[smallChild] > heap[smallChild+1] :
-                    smallChild += 1
-                if smallChild >= len(heap) or lastItem <= heap[smallChild]:
-                    heap[insertionPoint] = lastItem
-                    break
-                heap[insertionPoint] = heap[smallChild]
-                insertionPoint = smallChild
-        return heap[0][1]
-
-    def __iter__(self):
-        '''
-        Create destructive sorted iterator of priorityDictionary.
-        '''
-        def iterfn():
-            while len(self) > 0:
-                x = self.smallest()
-                yield x
-                del self[x]
-        return iterfn()
-
-    def __setitem__(self,key,val):
-        '''
-        Change value stored in dictionary and add corresponding pair to heap.
-        Rebuilds the heap if the number of deleted items gets large, to avoid memory leakage.
-        '''
-        dict.__setitem__(self,key,val)
-        heap = self.__heap
-        if len(heap) > 2 * len(self):
-            self.__heap = [(v,k) for k,v in self.iteritems()]
-            self.__heap.sort()  # builtin sort probably faster than O(n)-time heapify
-        else:
-            newPair = (val,key)
-            insertionPoint = len(heap)
-            heap.append(None)
-            while insertionPoint > 0 and newPair < heap[(insertionPoint-1)//2]:
-                heap[insertionPoint] = heap[(insertionPoint-1)//2]
-                insertionPoint = (insertionPoint-1)//2
-            heap[insertionPoint] = newPair
-
-    def setdefault(self,key,val):
-        '''
-        Reimplement setdefault to pass through our customized __setitem__.
-        '''
-        if key not in self:
-            self[key] = val
-        return self[key]
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/GraphStat.py b/catapult/telemetry/third_party/altgraph/altgraph/GraphStat.py
deleted file mode 100644
index 25fc46c..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/GraphStat.py
+++ /dev/null
@@ -1,73 +0,0 @@
-'''
-altgraph.GraphStat - Functions providing various graph statistics
-=================================================================
-'''
-import sys
-
-def degree_dist(graph, limits=(0,0), bin_num=10, mode='out'):
-    '''
-    Computes the degree distribution for a graph.
-
-    Returns a list of tuples where the first element of the tuple is the center of the bin
-    representing a range of degrees and the second element of the tuple are the number of nodes
-    with the degree falling in the range.
-
-    Example::
-
-        ....
-    '''
-
-    deg = []
-    if mode == 'inc':
-        get_deg = graph.inc_degree
-    else:
-        get_deg = graph.out_degree
-
-    for node in graph:
-        deg.append( get_deg(node) )
-
-    if not deg:
-        return []
-
-    results = _binning(values=deg, limits=limits, bin_num=bin_num)
-
-    return results
-
-_EPS = 1.0/(2.0**32)
-def _binning(values, limits=(0,0), bin_num=10):
-    '''
-    Bins data that falls between certain limits, if the limits are (0, 0) the
-    minimum and maximum values are used.
-
-    Returns a list of tuples where the first element of the tuple is the center of the bin
-    and the second element of the tuple are the counts.
-    '''
-    if limits == (0, 0):
-        min_val, max_val = min(values) - _EPS, max(values) + _EPS
-    else:
-        min_val, max_val = limits
-
-    # get bin size
-    bin_size = (max_val - min_val)/float(bin_num)
-    bins = [0] * (bin_num)
-
-    # will ignore these outliers for now
-    out_points = 0
-    for value in values:
-        try:
-            if (value - min_val) < 0:
-                out_points += 1
-            else:
-                index = int((value - min_val)/float(bin_size))
-                bins[index] += 1
-        except IndexError:
-            out_points += 1
-
-    # make it ready for an x,y plot
-    result = []
-    center = (bin_size/2) + min_val
-    for i, y in enumerate(bins):
-        x = center + bin_size * i
-        result.append( (x,y) )
-
-    return result
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/GraphUtil.py b/catapult/telemetry/third_party/altgraph/altgraph/GraphUtil.py
deleted file mode 100644
index d3b6acd..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/GraphUtil.py
+++ /dev/null
@@ -1,137 +0,0 @@
-'''
-altgraph.GraphUtil - Utility classes and functions
-==================================================
-'''
-
-import random
-from collections import deque
-from altgraph import Graph
-from altgraph import GraphError
-
-def generate_random_graph(node_num, edge_num, self_loops=False, multi_edges=False):
-    '''
-    Generates and returns a :py:class:`~altgraph.Graph.Graph` instance with *node_num* nodes
-    randomly connected by *edge_num* edges.
-    '''
-    g = Graph.Graph()
-
-    if not multi_edges:
-        if self_loops:
-            max_edges = node_num * node_num
-        else:
-            max_edges = node_num * (node_num-1)
-
-        if edge_num > max_edges:
-            raise GraphError("inconsistent arguments to 'generate_random_graph'")
-
-    nodes = range(node_num)
-
-    for node in nodes:
-        g.add_node(node)
-
-    while 1:
-        head = random.choice(nodes)
-        tail = random.choice(nodes)
-
-        # loop defense
-        if head == tail and not self_loops:
-            continue
-
-        # multiple edge defense
-        if g.edge_by_node(head,tail) is not None and not multi_edges:
-            continue
-
-        # add the edge
-        g.add_edge(head, tail)
-        if g.number_of_edges() >= edge_num:
-            break
-
-    return g
-
-def generate_scale_free_graph(steps, growth_num, self_loops=False, multi_edges=False):
-    '''
-    Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that will have *steps* \* *growth_num* nodes
-    and a scale free (powerlaw) connectivity. Starting with a fully connected graph with *growth_num* nodes
-    at every step *growth_num* nodes are added to the graph and are connected to existing nodes with
-    a probability proportional to the degree of these existing nodes.
-    '''
-    # FIXME: The code doesn't seem to do what the documentation claims.
-    graph = Graph.Graph()
-
-    # initialize the graph
-    store = []
-    for i in range(growth_num):
-        #store   += [ i ] * (growth_num - 1)
-        for j in range(i + 1, growth_num):
-            store.append(i)
-            store.append(j)
-            graph.add_edge(i,j)
-
-    # generate
-    for node in range(growth_num, steps * growth_num):
-        graph.add_node(node)
-        while ( graph.out_degree(node) < growth_num ):
-            nbr = random.choice(store)
-
-            # loop defense
-            if node == nbr and not self_loops:
-                continue
-
-            # multi edge defense
-            if graph.edge_by_node(node, nbr) and not multi_edges:
-                continue
-
-            graph.add_edge(node, nbr)
-
-
-        for nbr in graph.out_nbrs(node):
-            store.append(node)
-            store.append(nbr)
-
-    return graph
-
-def filter_stack(graph, head, filters):
-    """
-    Perform a walk in a depth-first order starting
-    at *head*.
-
-    Returns (visited, removes, orphans).
-
-    * visited: the set of visited nodes
-    * removes: the list of nodes where the node
-      data does not all *filters*
-    * orphans: tuples of (last_good, node),
-      where node is not in removes, is directly
-      reachable from a node in *removes* and
-      *last_good* is the closest upstream node that is not
-      in *removes*.
-    """
-
-    visited, removes, orphans = set([head]), set(), set()
-    stack = deque([(head, head)])
-    get_data = graph.node_data
-    get_edges = graph.out_edges
-    get_tail = graph.tail
-
-    while stack:
-        last_good, node = stack.pop()
-        data = get_data(node)
-        if data is not None:
-            for filtfunc in filters:
-                if not filtfunc(data):
-                    removes.add(node)
-                    break
-            else:
-                last_good = node
-        for edge in get_edges(node):
-            tail = get_tail(edge)
-            if last_good is not node:
-                orphans.add((last_good, tail))
-            if tail not in visited:
-                visited.add(tail)
-                stack.append((last_good, tail))
-
-    orphans = [(last_good, tail) for (last_good, tail) in orphans if tail not in removes]
-    #orphans.sort()
-
-    return visited, removes, orphans
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/ObjectGraph.py b/catapult/telemetry/third_party/altgraph/altgraph/ObjectGraph.py
deleted file mode 100644
index d07f51b..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/ObjectGraph.py
+++ /dev/null
@@ -1,202 +0,0 @@
-"""
-altgraph.ObjectGraph - Graph of objects with an identifier
-==========================================================
-
-A graph of objects that have a "graphident" attribute.
-graphident is the key for the object in the graph
-"""
-
-from altgraph import GraphError
-from altgraph.Graph import Graph
-from altgraph.GraphUtil import filter_stack
-
-class ObjectGraph(object):
-    """
-    A graph of objects that have a "graphident" attribute.
-    graphident is the key for the object in the graph
-    """
-    def __init__(self, graph=None, debug=0):
-        if graph is None:
-            graph = Graph()
-        self.graphident = self
-        self.graph = graph
-        self.debug = debug
-        self.indent = 0
-        graph.add_node(self, None)
-
-    def __repr__(self):
-        return '<%s>' % (type(self).__name__,)
-
-    def flatten(self, condition=None, start=None):
-        """
-        Iterate over the subgraph that is entirely reachable by condition
-        starting from the given start node or the ObjectGraph root
-        """
-        if start is None:
-            start = self
-        start = self.getRawIdent(start)
-        return self.graph.iterdata(start=start, condition=condition)
-
-    def nodes(self):
-        for ident in self.graph:
-            node = self.graph.node_data(ident)
-            if node is not None:
-                yield self.graph.node_data(ident)
-
-
-    def get_edges(self, node):
-        start = self.getRawIdent(node)
-        _, _, outraw, incraw = self.graph.describe_node(start)
-        def iter_edges(lst, n):
-            seen = set()
-            for tpl in (self.graph.describe_edge(e) for e in lst):
-                ident = tpl[n]
-                if ident not in seen:
-                    yield self.findNode(ident)
-                    seen.add(ident)
-        return iter_edges(outraw, 3), iter_edges(incraw, 2)
-
-    def edgeData(self, fromNode, toNode):
-        start = self.getRawIdent(fromNode)
-        stop = self.getRawIdent(toNode)
-        edge = self.graph.edge_by_node(start, stop)
-        return self.graph.edge_data(edge)
-
-    def updateEdgeData(self, fromNode, toNode, edgeData):
-        start = self.getRawIdent(fromNode)
-        stop = self.getRawIdent(toNode)
-        edge = self.graph.edge_by_node(start, stop)
-        self.graph.update_edge_data(edge, edgeData)
-
-    def filterStack(self, filters):
-        """
-        Filter the ObjectGraph in-place by removing all edges to nodes that
-        do not match every filter in the given filter list
-
-        Returns a tuple containing the number of: (nodes_visited, nodes_removed, nodes_orphaned)
-        """
-        visited, removes, orphans = filter_stack(self.graph, self, filters)
-
-        for last_good, tail in orphans:
-            self.graph.add_edge(last_good, tail, edge_data='orphan')
-
-        for node in removes:
-            self.graph.hide_node(node)
-
-        return len(visited)-1, len(removes), len(orphans)
-
-    def removeNode(self, node):
-        """
-        Remove the given node from the graph if it exists
-        """
-        ident = self.getIdent(node)
-        if ident is not None:
-            self.graph.hide_node(ident)
-
-    def removeReference(self, fromnode, tonode):
-        """
-        Remove all edges from fromnode to tonode
-        """
-        if fromnode is None:
-            fromnode = self
-        fromident = self.getIdent(fromnode)
-        toident = self.getIdent(tonode)
-        if fromident is not None and toident is not None:
-            while True:
-                edge = self.graph.edge_by_node(fromident, toident)
-                if edge is None:
-                    break
-                self.graph.hide_edge(edge)
-
-    def getIdent(self, node):
-        """
-        Get the graph identifier for a node
-        """
-        ident = self.getRawIdent(node)
-        if ident is not None:
-            return ident
-        node = self.findNode(node)
-        if node is None:
-            return None
-        return node.graphident
-
-    def getRawIdent(self, node):
-        """
-        Get the identifier for a node object
-        """
-        if node is self:
-            return node
-        ident = getattr(node, 'graphident', None)
-        return ident
-
-    def __contains__(self, node):
-        return self.findNode(node) is not None
-
-    def findNode(self, node):
-        """
-        Find the node on the graph
-        """
-        ident = self.getRawIdent(node)
-        if ident is None:
-            ident = node
-        try:
-            return self.graph.node_data(ident)
-        except KeyError:
-            return None
-
-    def addNode(self, node):
-        """
-        Add a node to the graph referenced by the root
-        """
-        self.msg(4, "addNode", node)
-
-        try:
-            self.graph.restore_node(node.graphident)
-        except GraphError:
-            self.graph.add_node(node.graphident, node)
-
-    def createReference(self, fromnode, tonode, edge_data=None):
-        """
-        Create a reference from fromnode to tonode
-        """
-        if fromnode is None:
-            fromnode = self
-        fromident, toident = self.getIdent(fromnode), self.getIdent(tonode)
-        if fromident is None or toident is None:
-            return
-        self.msg(4, "createReference", fromnode, tonode, edge_data)
-        self.graph.add_edge(fromident, toident, edge_data=edge_data)
-
-    def createNode(self, cls, name, *args, **kw):
-        """
-        Add a node of type cls to the graph if it does not already exist
-        by the given name
-        """
-        m = self.findNode(name)
-        if m is None:
-            m = cls(name, *args, **kw)
-            self.addNode(m)
-        return m
-
-    def msg(self, level, s, *args):
-        """
-        Print a debug message with the given level
-        """
-        if s and level <= self.debug:
-            print ("%s%s %s" % ("  " * self.indent, s, ' '.join(map(repr, args))))
-
-    def msgin(self, level, s, *args):
-        """
-        Print a debug message and indent
-        """
-        if level <= self.debug:
-            self.msg(level, s, *args)
-            self.indent = self.indent + 1
-
-    def msgout(self, level, s, *args):
-        """
-        Dedent and print a debug message
-        """
-        if level <= self.debug:
-            self.indent = self.indent - 1
-            self.msg(level, s, *args)
diff --git a/catapult/telemetry/third_party/altgraph/altgraph/__init__.py b/catapult/telemetry/third_party/altgraph/altgraph/__init__.py
deleted file mode 100644
index 9f72c18..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph/__init__.py
+++ /dev/null
@@ -1,135 +0,0 @@
-'''
-altgraph - a python graph library
-=================================
-
-altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
-to use newer Python 2.3+ features, including additional support used by the
-py2app suite (modulegraph and macholib, specifically).
-
-altgraph is a python based graph (network) representation and manipulation package.
-It has started out as an extension to the `graph_lib module <http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html>`_
-written by Nathan Denny it has been significantly optimized and expanded.
-
-The :class:`altgraph.Graph.Graph` class is loosely modeled after the `LEDA <http://www.algorithmic-solutions.com/enleda.htm>`_
-(Library of Efficient Datatypes)  representation. The library
-includes methods for constructing graphs, BFS and DFS traversals,
-topological sort, finding connected components, shortest paths as well as a number
-graph statistics functions. The library can also visualize graphs
-via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_.
-
-The package contains the following modules:
-
-    -  the :py:mod:`altgraph.Graph` module contains the :class:`~altgraph.Graph.Graph` class that stores the graph data
-
-    -  the :py:mod:`altgraph.GraphAlgo` module implements graph algorithms operating on graphs (:py:class:`~altgraph.Graph.Graph`} instances)
-
-    -  the :py:mod:`altgraph.GraphStat` module contains functions for computing statistical measures on graphs
-
-    -  the :py:mod:`altgraph.GraphUtil` module contains functions for generating, reading and saving graphs
-
-    -  the :py:mod:`altgraph.Dot` module  contains functions for displaying graphs via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_
-
-    -  the :py:mod:`altgraph.ObjectGraph` module implements a graph of objects with a unique identifier
-
-Installation
-------------
-
-Download and unpack the archive then type::
-
-    python setup.py install
-
-This will install the library in the default location. For instructions on
-how to customize the install procedure read the output of::
-
-    python setup.py --help install
-
-To verify that the code works run the test suite::
-
-    python setup.py test
-
-Example usage
--------------
-
-Lets assume that we want to analyze the graph below (links to the full picture) GRAPH_IMG.
-Our script then might look the following way::
-
-    from altgraph import Graph, GraphAlgo, Dot
-
-    # these are the edges
-    edges = [ (1,2), (2,4), (1,3), (2,4), (3,4), (4,5), (6,5),
-        (6,14), (14,15), (6, 15),  (5,7), (7, 8), (7,13), (12,8),
-        (8,13), (11,12), (11,9), (13,11), (9,13), (13,10) ]
-
-    # creates the graph
-    graph = Graph.Graph()
-    for head, tail in edges:
-        graph.add_edge(head, tail)
-
-    # do a forward bfs from 1 at most to 20
-    print(graph.forw_bfs(1))
-
-This will print the nodes in some breadth first order::
-
-    [1, 2, 3, 4, 5, 7, 8, 13, 11, 10, 12, 9]
-
-If we wanted to get the hop-distance from node 1 to node 8
-we coud write::
-
-    print(graph.get_hops(1, 8))
-
-This will print the following::
-
-    [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
-
-Node 1 is at 0 hops since it is the starting node, nodes 2,3 are 1 hop away ...
-node 8 is 5 hops away. To find the shortest distance between two nodes you
-can use::
-
-    print(GraphAlgo.shortest_path(graph, 1, 12))
-
-It will print the nodes on one (if there are more) the shortest paths::
-
-    [1, 2, 4, 5, 7, 13, 11, 12]
-
-To display the graph we can use the GraphViz backend::
-
-    dot = Dot.Dot(graph)
-
-    # display the graph on the monitor
-    dot.display()
-
-    # save it in an image file
-    dot.save_img(file_name='graph', file_type='gif')
-
-
-
-..
-  @author: U{Istvan Albert<http://www.personal.psu.edu/staff/i/u/iua1/>}
-
-  @license:  MIT License
-
-  Copyright (c) 2004 Istvan Albert unless otherwise noted.
-
-  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-  and associated documentation files (the "Software"), to deal in the Software without restriction,
-  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
-  so.
-
-  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-  INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-  PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-  FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-  ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-  THE SOFTWARE.
-  @requires: Python 2.3 or higher
-
-  @newfield contributor: Contributors:
-  @contributor: U{Reka Albert <http://www.phys.psu.edu/~ralbert/>}
-
-'''
-import pkg_resources
-__version__ = pkg_resources.require('altgraph')[0].version
-
-class GraphError(ValueError):
-    pass
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/__init__.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/__init__.py
deleted file mode 100644
index 6890389..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" altgraph tests """
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_altgraph.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/test_altgraph.py
deleted file mode 100644
index 2ca6b25..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_altgraph.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env py.test
-import os
-import sys
-
-from altgraph import Graph, GraphAlgo
-import unittest
-
-class BasicTests (unittest.TestCase):
-    def setUp(self):
-        self.edges = [
-            (1,2), (2,4), (1,3), (2,4), (3,4), (4,5), (6,5), (6,14), (14,15),
-            (6, 15), (5,7), (7, 8), (7,13), (12,8), (8,13), (11,12), (11,9),
-            (13,11), (9,13), (13,10)
-        ]
-
-        # these are the edges
-        self.store = {}
-        self.g = Graph.Graph()
-        for head, tail in self.edges:
-            self.store[head] = self.store[tail] = None
-            self.g.add_edge(head, tail)
-
-    def test_num_edges(self):
-        # check the parameters
-        self.assertEqual(self.g.number_of_nodes(), len(self.store))
-        self.assertEqual(self.g.number_of_edges(), len(self.edges))
-
-    def test_forw_bfs(self):
-        # do a forward bfs
-        self.assertEqual( self.g.forw_bfs(1),
-                [1, 2, 3, 4, 5, 7, 8, 13, 11, 10, 12, 9])
-
-
-    def test_get_hops(self):
-        # diplay the hops and hop numbers between nodes
-        self.assertEqual(self.g.get_hops(1, 8),
-                [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
-
-    def test_shortest_path(self):
-        self.assertEqual(GraphAlgo.shortest_path(self.g, 1, 12),
-                [1, 2, 4, 5, 7, 13, 11, 12])
-
-
-if __name__ == "__main__":  # pragma: no cover
-    unittest.main()
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_dot.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/test_dot.py
deleted file mode 100644
index 83993da..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_dot.py
+++ /dev/null
@@ -1,370 +0,0 @@
-import unittest
-import os
-
-from altgraph import Dot
-from altgraph import Graph
-from altgraph import GraphError
-
-
-class TestDot (unittest.TestCase):
-
-    def test_constructor(self):
-        g = Graph.Graph([
-                (1,2),
-                (1,3),
-                (1,4),
-                (2,4),
-                (2,6),
-                (2,7),
-                (7,4),
-                (6,1),
-            ]
-        )
-
-        dot = Dot.Dot(g)
-
-        self.assertEqual(dot.name, 'G')
-        self.assertEqual(dot.attr, {})
-        self.assertEqual(dot.temp_dot, 'tmp_dot.dot')
-        self.assertEqual(dot.temp_neo, 'tmp_neo.dot')
-        self.assertEqual(dot.dot, 'dot')
-        self.assertEqual(dot.dotty, 'dotty')
-        self.assertEqual(dot.neato, 'neato')
-        self.assertEqual(dot.type, 'digraph')
-
-        self.assertEqual(dot.nodes, dict([(x, {}) for x in g]))
-
-        edges = {}
-        for head in g:
-            edges[head] = {}
-            for tail in g.out_nbrs(head):
-                edges[head][tail] = {}
-
-        self.assertEqual(dot.edges[1], edges[1])
-        self.assertEqual(dot.edges, edges)
-
-
-        dot = Dot.Dot(g, nodes=[1,2],
-                edgefn=lambda node: list(sorted(g.out_nbrs(node)))[:-1],
-                nodevisitor=lambda node: {'label': node},
-                edgevisitor=lambda head, tail: {'label': (head, tail) },
-                name="testgraph",
-                dot='/usr/local/bin/dot',
-                dotty='/usr/local/bin/dotty',
-                neato='/usr/local/bin/neato',
-                graphtype="graph")
-
-        self.assertEqual(dot.name, 'testgraph')
-        self.assertEqual(dot.attr, {})
-        self.assertEqual(dot.temp_dot, 'tmp_dot.dot')
-        self.assertEqual(dot.temp_neo, 'tmp_neo.dot')
-        self.assertEqual(dot.dot, '/usr/local/bin/dot')
-        self.assertEqual(dot.dotty, '/usr/local/bin/dotty')
-        self.assertEqual(dot.neato, '/usr/local/bin/neato')
-        self.assertEqual(dot.type, 'graph')
-
-        self.assertEqual(dot.nodes, dict([(x, {'label': x}) for x in [1,2]]))
-
-        edges = {}
-        for head in [1,2]:
-            edges[head] = {}
-            for tail in list(sorted(g.out_nbrs(head)))[:-1]:
-                if tail not in [1,2]: continue
-                edges[head][tail] = {'label': (head, tail) }
-
-        self.assertEqual(dot.edges[1], edges[1])
-        self.assertEqual(dot.edges, edges)
-
-        self.assertRaises(GraphError, Dot.Dot, g, nodes=[1,2, 9])
-
-    def test_style(self):
-        g = Graph.Graph([])
-
-        dot = Dot.Dot(g)
-
-        self.assertEqual(dot.attr, {})
-
-        dot.style(key='value')
-        self.assertEqual(dot.attr, {'key': 'value'})
-
-        dot.style(key2='value2')
-        self.assertEqual(dot.attr, {'key2': 'value2'})
-
-    def test_node_style(self):
-        g = Graph.Graph([
-                (1,2),
-                (1,3),
-                (1,4),
-                (2,4),
-                (2,6),
-                (2,7),
-                (7,4),
-                (6,1),
-            ]
-        )
-
-        dot = Dot.Dot(g)
-
-        self.assertEqual(dot.nodes[1], {})
-
-        dot.node_style(1, key='value')
-        self.assertEqual(dot.nodes[1], {'key': 'value'})
-
-        dot.node_style(1, key2='value2')
-        self.assertEqual(dot.nodes[1], {'key2': 'value2'})
-        self.assertEqual(dot.nodes[2], {})
-
-        dot.all_node_style(key3='value3')
-        for n in g:
-            self.assertEqual(dot.nodes[n], {'key3': 'value3'})
-
-        self.assertTrue(9 not in dot.nodes)
-        dot.node_style(9, key='value')
-        self.assertEqual(dot.nodes[9], {'key': 'value'})
-
-    def test_edge_style(self):
-        g = Graph.Graph([
-                (1,2),
-                (1,3),
-                (1,4),
-                (2,4),
-                (2,6),
-                (2,7),
-                (7,4),
-                (6,1),
-            ]
-        )
-
-        dot = Dot.Dot(g)
-
-        self.assertEqual(dot.edges[1][2], {})
-        dot.edge_style(1,2, foo='bar')
-        self.assertEqual(dot.edges[1][2], {'foo': 'bar'})
-
-        dot.edge_style(1,2, foo2='2bar')
-        self.assertEqual(dot.edges[1][2], {'foo2': '2bar'})
-
-        self.assertEqual(dot.edges[1][3], {})
-
-        self.assertFalse(6 in dot.edges[1])
-        dot.edge_style(1,6, foo2='2bar')
-        self.assertEqual(dot.edges[1][6], {'foo2': '2bar'})
-
-        self.assertRaises(GraphError, dot.edge_style, 1, 9, a=1)
-        self.assertRaises(GraphError, dot.edge_style, 9, 1, a=1)
-
-
-    def test_iter(self):
-        g = Graph.Graph([
-                (1,2),
-                (1,3),
-                (1,4),
-                (2,4),
-                (2,6),
-                (2,7),
-                (7,4),
-                (6,1),
-            ]
-        )
-
-        dot = Dot.Dot(g)
-        dot.style(graph="foobar")
-        dot.node_style(1, key='value')
-        dot.node_style(2, key='another', key2='world')
-        dot.edge_style(1,4, key1='value1', key2='value2')
-        dot.edge_style(2,4, key1='valueA')
-
-        self.assertEqual(list(iter(dot)), list(dot.iterdot()))
-
-        for item in dot.iterdot():
-            self.assertTrue(isinstance(item, str))
-
-        first = list(dot.iterdot())[0]
-        self.assertEqual(first, "digraph %s {\n"%(dot.name,))
-
-        dot.type = 'graph'
-        first = list(dot.iterdot())[0]
-        self.assertEqual(first, "graph %s {\n"%(dot.name,))
-
-        dot.type = 'foo'
-        self.assertRaises(GraphError, list, dot.iterdot())
-        dot.type = 'digraph'
-
-        self.assertEqual(list(dot), [
-            'digraph G {\n',
-              'graph="foobar";',
-              '\n',
-
-            '\t"1" [',
-              'key="value",',
-            '];\n',
-
-            '\t"2" [',
-              'key="another",',
-              'key2="world",',
-            '];\n',
-
-            '\t"3" [',
-            '];\n',
-
-            '\t"4" [',
-            '];\n',
-
-            '\t"6" [',
-            '];\n',
-
-            '\t"7" [',
-            '];\n',
-
-            '\t"1" -> "2" [',
-            '];\n',
-
-            '\t"1" -> "3" [',
-            '];\n',
-
-            '\t"1" -> "4" [',
-              'key1="value1",',
-              'key2="value2",',
-            '];\n',
-
-             '\t"2" -> "4" [',
-               'key1="valueA",',
-             '];\n',
-
-             '\t"2" -> "6" [',
-             '];\n',
-
-             '\t"2" -> "7" [',
-             '];\n',
-
-             '\t"6" -> "1" [',
-             '];\n',
-
-             '\t"7" -> "4" [',
-             '];\n',
-           '}\n'])
-
-
-    def test_save(self):
-        g = Graph.Graph([
-                (1,2),
-                (1,3),
-                (1,4),
-                (2,4),
-                (2,6),
-                (2,7),
-                (7,4),
-                (6,1),
-            ]
-        )
-
-        dot = Dot.Dot(g)
-        dot.style(graph="foobar")
-        dot.node_style(1, key='value')
-        dot.node_style(2, key='another', key2='world')
-        dot.edge_style(1,4, key1='value1', key2='value2')
-        dot.edge_style(2,4, key1='valueA')
-
-        fn = 'test_dot.dot'
-        self.assertTrue(not os.path.exists(fn))
-
-        try:
-            dot.save_dot(fn)
-
-            fp = open(fn, 'r')
-            data = fp.read()
-            fp.close()
-            self.assertEqual(data, ''.join(dot))
-
-        finally:
-            if os.path.exists(fn):
-                os.unlink(fn)
-
-
-    def test_img(self):
-        g = Graph.Graph([
-                (1,2),
-                (1,3),
-                (1,4),
-                (2,4),
-                (2,6),
-                (2,7),
-                (7,4),
-                (6,1),
-            ]
-        )
-
-        dot = Dot.Dot(g, dot='/usr/local/bin/!!dot', dotty='/usr/local/bin/!!dotty', neato='/usr/local/bin/!!neato')
-        dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
-        dot.node_style(1, label='BASE_NODE',shape='box', color='blue')
-        dot.node_style(2, style='filled', fillcolor='red')
-        dot.edge_style(1,4, style='dotted')
-        dot.edge_style(2,4, arrowhead='dot', label='binds', labelangle='90')
-
-        system_cmds = []
-        def fake_system(cmd):
-            system_cmds.append(cmd)
-            return None
-
-        try:
-            real_system = os.system
-            os.system = fake_system
-
-            system_cmds = []
-            dot.save_img('foo')
-            self.assertEqual(system_cmds, ['/usr/local/bin/!!dot -Tgif tmp_dot.dot -o foo.gif'])
-
-            system_cmds = []
-            dot.save_img('foo', file_type='jpg')
-            self.assertEqual(system_cmds, ['/usr/local/bin/!!dot -Tjpg tmp_dot.dot -o foo.jpg'])
-
-            system_cmds = []
-            dot.save_img('bar', file_type='jpg', mode='neato')
-            self.assertEqual(system_cmds, [
-                '/usr/local/bin/!!neato -o tmp_dot.dot tmp_neo.dot',
-                '/usr/local/bin/!!dot -Tjpg tmp_dot.dot -o bar.jpg',
-            ])
-
-            system_cmds = []
-            dot.display()
-            self.assertEqual(system_cmds, [
-                '/usr/local/bin/!!dotty tmp_dot.dot'
-            ])
-
-            system_cmds = []
-            dot.display(mode='neato')
-            self.assertEqual(system_cmds, [
-                '/usr/local/bin/!!neato -o tmp_dot.dot tmp_neo.dot',
-                '/usr/local/bin/!!dotty tmp_dot.dot'
-            ])
-
-        finally:
-            if os.path.exists(dot.temp_dot):
-                os.unlink(dot.temp_dot)
-            if os.path.exists(dot.temp_neo):
-                os.unlink(dot.temp_neo)
-            os.system = real_system
-
-        if os.path.exists('/usr/local/bin/dot') and os.path.exists('/usr/local/bin/neato'):
-            try:
-                dot.dot='/usr/local/bin/dot'
-                dot.neato='/usr/local/bin/neato'
-                self.assertFalse(os.path.exists('foo.gif'))
-                dot.save_img('foo')
-                self.assertTrue(os.path.exists('foo.gif'))
-                os.unlink('foo.gif')
-
-                self.assertFalse(os.path.exists('foo.gif'))
-                dot.save_img('foo', mode='neato')
-                self.assertTrue(os.path.exists('foo.gif'))
-                os.unlink('foo.gif')
-
-            finally:
-                if os.path.exists(dot.temp_dot):
-                    os.unlink(dot.temp_dot)
-                if os.path.exists(dot.temp_neo):
-                    os.unlink(dot.temp_neo)
-
-
-if __name__ == "__main__": # pragma: no cover
-    unittest.main()
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graph.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graph.py
deleted file mode 100644
index 553549f..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graph.py
+++ /dev/null
@@ -1,644 +0,0 @@
-import unittest
-
-from altgraph import GraphError
-from altgraph.Graph import Graph
-
-class TestGraph (unittest.TestCase):
-
-    def test_nodes(self):
-        graph = Graph()
-
-        self.assertEqual(graph.node_list(), [])
-
-        o1 = object()
-        o1b = object()
-        o2 = object()
-        graph.add_node(1, o1)
-        graph.add_node(1, o1b)
-        graph.add_node(2, o2)
-        graph.add_node(3)
-
-        self.assertRaises(TypeError, graph.add_node, [])
-
-        self.assertTrue(graph.node_data(1) is o1)
-        self.assertTrue(graph.node_data(2) is o2)
-        self.assertTrue(graph.node_data(3) is None)
-
-        self.assertTrue(1 in graph)
-        self.assertTrue(2 in graph)
-        self.assertTrue(3 in graph)
-
-        self.assertEqual(graph.number_of_nodes(), 3)
-        self.assertEqual(graph.number_of_hidden_nodes(), 0)
-        self.assertEqual(graph.hidden_node_list(), [])
-        self.assertEqual(list(sorted(graph)), [1, 2, 3])
-
-        graph.hide_node(1)
-        graph.hide_node(2)
-        graph.hide_node(3)
-
-
-        self.assertEqual(graph.number_of_nodes(), 0)
-        self.assertEqual(graph.number_of_hidden_nodes(), 3)
-        self.assertEqual(list(sorted(graph.hidden_node_list())), [1, 2, 3])
-
-        self.assertFalse(1 in graph)
-        self.assertFalse(2 in graph)
-        self.assertFalse(3 in graph)
-
-        graph.add_node(1)
-        self.assertFalse(1 in graph)
-
-        graph.restore_node(1)
-        self.assertTrue(1 in graph)
-        self.assertFalse(2 in graph)
-        self.assertFalse(3 in graph)
-
-        graph.restore_all_nodes()
-        self.assertTrue(1 in graph)
-        self.assertTrue(2 in graph)
-        self.assertTrue(3 in graph)
-
-        self.assertEqual(list(sorted(graph.node_list())), [1, 2, 3])
-
-        v = graph.describe_node(1)
-        self.assertEqual(v, (1, o1, [], []))
-
-    def test_edges(self):
-        graph = Graph()
-        graph.add_node(1)
-        graph.add_node(2)
-        graph.add_node(3)
-        graph.add_node(4)
-        graph.add_node(5)
-
-        self.assertTrue(isinstance(graph.edge_list(), list))
-
-        graph.add_edge(1, 2)
-        graph.add_edge(4, 5, 'a')
-
-        self.assertRaises(GraphError, graph.add_edge, 'a', 'b', create_nodes=False)
-
-        self.assertEqual(graph.number_of_hidden_edges(), 0)
-        self.assertEqual(graph.number_of_edges(), 2)
-        e = graph.edge_by_node(1, 2)
-        self.assertTrue(isinstance(e, int))
-        graph.hide_edge(e)
-        self.assertEqual(graph.number_of_hidden_edges(), 1)
-        self.assertEqual(graph.number_of_edges(), 1)
-        e2 = graph.edge_by_node(1, 2)
-        self.assertTrue(e2 is None)
-
-        graph.restore_edge(e)
-        e2 = graph.edge_by_node(1, 2)
-        self.assertEqual(e, e2)
-        self.assertEqual(graph.number_of_hidden_edges(), 0)
-
-        self.assertEqual(graph.number_of_edges(), 2)
-
-        e1 = graph.edge_by_node(1, 2)
-        e2 = graph.edge_by_node(4, 5)
-        graph.hide_edge(e1)
-        graph.hide_edge(e2)
-
-        self.assertEqual(graph.number_of_edges(), 0)
-        graph.restore_all_edges()
-        self.assertEqual(graph.number_of_edges(), 2)
-
-        self.assertEqual(graph.edge_by_id(e1), (1,2))
-        self.assertRaises(GraphError, graph.edge_by_id, (e1+1)*(e2+1)+1)
-
-        self.assertEqual(list(sorted(graph.edge_list())), [e1, e2])
-
-        self.assertEqual(graph.describe_edge(e1), (e1, 1, 1, 2))
-        self.assertEqual(graph.describe_edge(e2), (e2, 'a', 4, 5))
-
-        self.assertEqual(graph.edge_data(e1), 1)
-        self.assertEqual(graph.edge_data(e2), 'a')
-
-        self.assertEqual(graph.head(e2), 4)
-        self.assertEqual(graph.tail(e2), 5)
-
-        graph.add_edge(1, 3)
-        graph.add_edge(1, 5)
-        graph.add_edge(4, 1)
-
-        self.assertEqual(list(sorted(graph.out_nbrs(1))), [2, 3, 5])
-        self.assertEqual(list(sorted(graph.inc_nbrs(1))), [4])
-        self.assertEqual(list(sorted(graph.inc_nbrs(5))), [1, 4])
-        self.assertEqual(list(sorted(graph.all_nbrs(1))), [2, 3, 4, 5])
-
-        graph.add_edge(5, 1)
-        self.assertEqual(list(sorted(graph.all_nbrs(5))), [1, 4])
-
-        self.assertEqual(graph.out_degree(1), 3)
-        self.assertEqual(graph.inc_degree(2), 1)
-        self.assertEqual(graph.inc_degree(5), 2)
-        self.assertEqual(graph.all_degree(5), 3)
-
-        v = graph.out_edges(4)
-        self.assertTrue(isinstance(v, list))
-        self.assertEqual(graph.edge_by_id(v[0]), (4, 5))
-
-        v = graph.out_edges(1)
-        for e in v:
-            self.assertEqual(graph.edge_by_id(e)[0], 1)
-
-        v = graph.inc_edges(1)
-        self.assertTrue(isinstance(v, list))
-        self.assertEqual(graph.edge_by_id(v[0]), (4, 1))
-
-        v = graph.inc_edges(5)
-        for e in v:
-            self.assertEqual(graph.edge_by_id(e)[1], 5)
-
-        v = graph.all_edges(5)
-        for e in v:
-            self.assertTrue(graph.edge_by_id(e)[1] == 5 or graph.edge_by_id(e)[0] == 5)
-
-        e1 = graph.edge_by_node(1, 2)
-        self.assertTrue(isinstance(e1, int))
-        graph.hide_node(1)
-        self.assertRaises(GraphError, graph.edge_by_node, 1, 2)
-        graph.restore_node(1)
-        e2 = graph.edge_by_node(1, 2)
-        self.assertEqual(e1, e2)
-
-
-
-    def test_toposort(self):
-        graph = Graph()
-        graph.add_node(1)
-        graph.add_node(2)
-        graph.add_node(3)
-        graph.add_node(4)
-        graph.add_node(5)
-
-        graph.add_edge(1, 2)
-        graph.add_edge(1, 3)
-        graph.add_edge(2, 4)
-        graph.add_edge(3, 5)
-
-        ok, result = graph.forw_topo_sort()
-        self.assertTrue(ok)
-        for idx in range(1, 6):
-            self.assertTrue(idx in result)
-
-        self.assertTrue(result.index(1) < result.index(2))
-        self.assertTrue(result.index(1) < result.index(3))
-        self.assertTrue(result.index(2) < result.index(4))
-        self.assertTrue(result.index(3) < result.index(5))
-
-        ok, result = graph.back_topo_sort()
-        self.assertTrue(ok)
-        for idx in range(1, 6):
-            self.assertTrue(idx in result)
-        self.assertTrue(result.index(2) < result.index(1))
-        self.assertTrue(result.index(3) < result.index(1))
-        self.assertTrue(result.index(4) < result.index(2))
-        self.assertTrue(result.index(5) < result.index(3))
-
-
-        # Same graph as before, but with edges
-        # reversed, which means we should get
-        # the same results as before if using
-        # back_topo_sort rather than forw_topo_sort
-        # (and v.v.)
-
-        graph = Graph()
-        graph.add_node(1)
-        graph.add_node(2)
-        graph.add_node(3)
-        graph.add_node(4)
-        graph.add_node(5)
-
-        graph.add_edge(2, 1)
-        graph.add_edge(3, 1)
-        graph.add_edge(4, 2)
-        graph.add_edge(5, 3)
-
-        ok, result = graph.back_topo_sort()
-        self.assertTrue(ok)
-        for idx in range(1, 6):
-            self.assertTrue(idx in result)
-
-        self.assertTrue(result.index(1) < result.index(2))
-        self.assertTrue(result.index(1) < result.index(3))
-        self.assertTrue(result.index(2) < result.index(4))
-        self.assertTrue(result.index(3) < result.index(5))
-
-        ok, result = graph.forw_topo_sort()
-        self.assertTrue(ok)
-        for idx in range(1, 6):
-            self.assertTrue(idx in result)
-        self.assertTrue(result.index(2) < result.index(1))
-        self.assertTrue(result.index(3) < result.index(1))
-        self.assertTrue(result.index(4) < result.index(2))
-        self.assertTrue(result.index(5) < result.index(3))
-
-
-        # Create a cycle
-        graph.add_edge(1, 5)
-        ok, result = graph.forw_topo_sort()
-        self.assertFalse(ok)
-        ok, result = graph.back_topo_sort()
-        self.assertFalse(ok)
-
-    def test_bfs_subgraph(self):
-        graph = Graph()
-        graph.add_edge(1, 2)
-        graph.add_edge(1, 4)
-        graph.add_edge(2, 4)
-        graph.add_edge(4, 8)
-        graph.add_edge(4, 9)
-        graph.add_edge(4, 10)
-        graph.add_edge(8, 10)
-
-        subgraph = graph.forw_bfs_subgraph(10)
-        self.assertTrue(isinstance(subgraph, Graph))
-        self.assertEqual(subgraph.number_of_nodes(), 1)
-        self.assertTrue(10 in subgraph)
-        self.assertEqual(subgraph.number_of_edges(), 0)
-
-        subgraph = graph.forw_bfs_subgraph(4)
-        self.assertTrue(isinstance(subgraph, Graph))
-        self.assertEqual(subgraph.number_of_nodes(), 4)
-        self.assertTrue(4 in subgraph)
-        self.assertTrue(8 in subgraph)
-        self.assertTrue(9 in subgraph)
-        self.assertTrue(10 in subgraph)
-        self.assertEqual(subgraph.number_of_edges(), 4)
-        e = subgraph.edge_by_node(4, 8)
-        e = subgraph.edge_by_node(4, 9)
-        e = subgraph.edge_by_node(4, 10)
-        e = subgraph.edge_by_node(8, 10)
-
-        # same graph as before, but switch around
-        # edges. This results in the same test results
-        # but now for back_bfs_subgraph rather than
-        # forw_bfs_subgraph
-
-        graph = Graph()
-        graph.add_edge(2, 1)
-        graph.add_edge(4, 1)
-        graph.add_edge(4, 2)
-        graph.add_edge(8, 4)
-        graph.add_edge(9, 4)
-        graph.add_edge(10, 4)
-        graph.add_edge(10, 8)
-
-        subgraph = graph.back_bfs_subgraph(10)
-        self.assertTrue(isinstance(subgraph, Graph))
-        self.assertEqual(subgraph.number_of_nodes(), 1)
-        self.assertTrue(10 in subgraph)
-        self.assertEqual(subgraph.number_of_edges(), 0)
-
-        subgraph = graph.back_bfs_subgraph(4)
-        self.assertTrue(isinstance(subgraph, Graph))
-        self.assertEqual(subgraph.number_of_nodes(), 4)
-        self.assertTrue(4 in subgraph)
-        self.assertTrue(8 in subgraph)
-        self.assertTrue(9 in subgraph)
-        self.assertTrue(10 in subgraph)
-        self.assertEqual(subgraph.number_of_edges(), 4)
-        e = subgraph.edge_by_node(4, 8)
-        e = subgraph.edge_by_node(4, 9)
-        e = subgraph.edge_by_node(4, 10)
-        e = subgraph.edge_by_node(8, 10)
-
-    def test_iterdfs(self):
-        graph = Graph()
-        graph.add_edge("1", "1.1")
-        graph.add_edge("1", "1.2")
-        graph.add_edge("1", "1.3")
-        graph.add_edge("1.1", "1.1.1")
-        graph.add_edge("1.1", "1.1.2")
-        graph.add_edge("1.2", "1.2.1")
-        graph.add_edge("1.2", "1.2.2")
-        graph.add_edge("1.2.2", "1.2.2.1")
-        graph.add_edge("1.2.2", "1.2.2.2")
-        graph.add_edge("1.2.2", "1.2.2.3")
-
-        result = list(graph.iterdfs("1"))
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
-        ])
-        result = list(graph.iterdfs("1", "1.2.1"))
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1'
-        ])
-
-        result = graph.forw_dfs("1")
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
-        ])
-        result = graph.forw_dfs("1", "1.2.1")
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1'
-        ])
-
-        graph = Graph()
-        graph.add_edge("1.1", "1")
-        graph.add_edge("1.2", "1")
-        graph.add_edge("1.3", "1")
-        graph.add_edge("1.1.1", "1.1")
-        graph.add_edge("1.1.2", "1.1")
-        graph.add_edge("1.2.1", "1.2")
-        graph.add_edge("1.2.2", "1.2")
-        graph.add_edge("1.2.2.1", "1.2.2")
-        graph.add_edge("1.2.2.2", "1.2.2")
-        graph.add_edge("1.2.2.3", "1.2.2")
-
-        result = list(graph.iterdfs("1", forward=False))
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
-        ])
-        result = list(graph.iterdfs("1", "1.2.1", forward=False))
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1'
-        ])
-        result = graph.back_dfs("1")
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
-        ])
-        result = graph.back_dfs("1", "1.2.1")
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1'
-        ])
-
-
-        # Introduce cyle:
-        graph.add_edge("1", "1.2")
-        result = list(graph.iterdfs("1", forward=False))
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
-        ])
-
-        result = graph.back_dfs("1")
-        self.assertEqual(result, [
-            '1', '1.3', '1.2', '1.2.2', '1.2.2.3', '1.2.2.2',
-            '1.2.2.1', '1.2.1', '1.1', '1.1.2', '1.1.1'
-        ])
-
-
-    def test_iterdata(self):
-        graph = Graph()
-        graph.add_node("1", "I")
-        graph.add_node("1.1", "I.I")
-        graph.add_node("1.2", "I.II")
-        graph.add_node("1.3", "I.III")
-        graph.add_node("1.1.1", "I.I.I")
-        graph.add_node("1.1.2", "I.I.II")
-        graph.add_node("1.2.1", "I.II.I")
-        graph.add_node("1.2.2", "I.II.II")
-        graph.add_node("1.2.2.1", "I.II.II.I")
-        graph.add_node("1.2.2.2", "I.II.II.II")
-        graph.add_node("1.2.2.3", "I.II.II.III")
-
-        graph.add_edge("1", "1.1")
-        graph.add_edge("1", "1.2")
-        graph.add_edge("1", "1.3")
-        graph.add_edge("1.1", "1.1.1")
-        graph.add_edge("1.1", "1.1.2")
-        graph.add_edge("1.2", "1.2.1")
-        graph.add_edge("1.2", "1.2.2")
-        graph.add_edge("1.2.2", "1.2.2.1")
-        graph.add_edge("1.2.2", "1.2.2.2")
-        graph.add_edge("1.2.2", "1.2.2.3")
-
-        result = list(graph.iterdata("1", forward=True))
-        self.assertEqual(result, [
-            'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
-            'I.II.II.I', 'I.II.I', 'I.I', 'I.I.II', 'I.I.I'
-        ])
-
-        result = list(graph.iterdata("1", end="1.2.1", forward=True))
-        self.assertEqual(result, [
-            'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
-            'I.II.II.I', 'I.II.I'
-        ])
-
-        result = list(graph.iterdata("1", condition=lambda n: len(n) < 6, forward=True))
-        self.assertEqual(result, [
-            'I', 'I.III', 'I.II',
-            'I.I', 'I.I.I'
-        ])
-
-
-        # And the revese option:
-        graph = Graph()
-        graph.add_node("1", "I")
-        graph.add_node("1.1", "I.I")
-        graph.add_node("1.2", "I.II")
-        graph.add_node("1.3", "I.III")
-        graph.add_node("1.1.1", "I.I.I")
-        graph.add_node("1.1.2", "I.I.II")
-        graph.add_node("1.2.1", "I.II.I")
-        graph.add_node("1.2.2", "I.II.II")
-        graph.add_node("1.2.2.1", "I.II.II.I")
-        graph.add_node("1.2.2.2", "I.II.II.II")
-        graph.add_node("1.2.2.3", "I.II.II.III")
-
-        graph.add_edge("1.1", "1")
-        graph.add_edge("1.2", "1")
-        graph.add_edge("1.3", "1")
-        graph.add_edge("1.1.1", "1.1")
-        graph.add_edge("1.1.2", "1.1")
-        graph.add_edge("1.2.1", "1.2")
-        graph.add_edge("1.2.2", "1.2")
-        graph.add_edge("1.2.2.1", "1.2.2")
-        graph.add_edge("1.2.2.2", "1.2.2")
-        graph.add_edge("1.2.2.3", "1.2.2")
-
-        result = list(graph.iterdata("1", forward=False))
-        self.assertEqual(result, [
-            'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
-            'I.II.II.I', 'I.II.I', 'I.I', 'I.I.II', 'I.I.I'
-        ])
-
-        result = list(graph.iterdata("1", end="1.2.1", forward=False))
-        self.assertEqual(result, [
-            'I', 'I.III', 'I.II', 'I.II.II', 'I.II.II.III', 'I.II.II.II',
-            'I.II.II.I', 'I.II.I'
-        ])
-
-        result = list(graph.iterdata("1", condition=lambda n: len(n) < 6, forward=False))
-        self.assertEqual(result, [
-            'I', 'I.III', 'I.II',
-            'I.I', 'I.I.I'
-        ])
-
-    def test_bfs(self):
-        graph = Graph()
-        graph.add_edge("1", "1.1")
-        graph.add_edge("1.1", "1.1.1")
-        graph.add_edge("1.1", "1.1.2")
-        graph.add_edge("1.1.2", "1.1.2.1")
-        graph.add_edge("1.1.2", "1.1.2.2")
-        graph.add_edge("1", "1.2")
-        graph.add_edge("1", "1.3")
-        graph.add_edge("1.2", "1.2.1")
-
-        self.assertEqual(graph.forw_bfs("1"),
-                ['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
-        self.assertEqual(graph.forw_bfs("1", "1.1.1"),
-                ['1', '1.1', '1.2', '1.3', '1.1.1'])
-
-
-        # And the "reverse" graph
-        graph = Graph()
-        graph.add_edge("1.1", "1")
-        graph.add_edge("1.1.1", "1.1")
-        graph.add_edge("1.1.2", "1.1")
-        graph.add_edge("1.1.2.1", "1.1.2")
-        graph.add_edge("1.1.2.2", "1.1.2")
-        graph.add_edge("1.2", "1")
-        graph.add_edge("1.3", "1")
-        graph.add_edge("1.2.1", "1.2")
-
-        self.assertEqual(graph.back_bfs("1"),
-                ['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
-        self.assertEqual(graph.back_bfs("1", "1.1.1"),
-                ['1', '1.1', '1.2', '1.3', '1.1.1'])
-
-
-
-        # check cycle handling
-        graph.add_edge("1", "1.2.1")
-        self.assertEqual(graph.back_bfs("1"),
-                ['1', '1.1', '1.2', '1.3', '1.1.1', '1.1.2', '1.2.1', '1.1.2.1', '1.1.2.2'])
-
-
-    def test_connected(self):
-        graph = Graph()
-        graph.add_node(1)
-        graph.add_node(2)
-        graph.add_node(3)
-        graph.add_node(4)
-
-        self.assertFalse(graph.connected())
-
-        graph.add_edge(1, 2)
-        graph.add_edge(3, 4)
-        self.assertFalse(graph.connected())
-
-        graph.add_edge(2, 3)
-        graph.add_edge(4, 1)
-        self.assertTrue(graph.connected())
-
-    def test_edges_complex(self):
-        g = Graph()
-        g.add_edge(1, 2)
-        e = g.edge_by_node(1,2)
-        g.hide_edge(e)
-        g.hide_node(2)
-        self.assertRaises(GraphError, g.restore_edge, e)
-
-        g.restore_all_edges()
-        self.assertRaises(GraphError, g.edge_by_id, e)
-
-    def test_clust_coef(self):
-        g = Graph()
-        g.add_edge(1, 2)
-        g.add_edge(1, 3)
-        g.add_edge(1, 4)
-        self.assertEqual(g.clust_coef(1), 0)
-
-        g.add_edge(2, 5)
-        g.add_edge(3, 5)
-        g.add_edge(4, 5)
-        self.assertEqual(g.clust_coef(1), 0)
-
-        g.add_edge(2, 3)
-        self.assertEqual(g.clust_coef(1), 1./6)
-        g.add_edge(2, 4)
-        self.assertEqual(g.clust_coef(1), 2./6)
-        g.add_edge(4, 2)
-        self.assertEqual(g.clust_coef(1), 3./6)
-
-        g.add_edge(2, 3)
-        g.add_edge(2, 4)
-        g.add_edge(3, 4)
-        g.add_edge(3, 2)
-        g.add_edge(4, 2)
-        g.add_edge(4, 3)
-        self.assertEqual(g.clust_coef(1), 1)
-
-
-    def test_get_hops(self):
-        graph = Graph()
-        graph.add_edge(1, 2)
-        graph.add_edge(1, 3)
-        graph.add_edge(2, 4)
-        graph.add_edge(4, 5)
-        graph.add_edge(5, 7)
-        graph.add_edge(7, 8)
-
-        self.assertEqual(graph.get_hops(1),
-            [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
-
-        self.assertEqual(graph.get_hops(1, 5),
-            [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3)])
-
-        graph.add_edge(5, 1)
-        graph.add_edge(7, 1)
-        graph.add_edge(7, 4)
-
-        self.assertEqual(graph.get_hops(1),
-            [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
-
-        # And the reverse graph
-        graph = Graph()
-        graph.add_edge(2, 1)
-        graph.add_edge(3, 1)
-        graph.add_edge(4, 2)
-        graph.add_edge(5, 4)
-        graph.add_edge(7, 5)
-        graph.add_edge(8, 7)
-
-        self.assertEqual(graph.get_hops(1, forward=False),
-            [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
-
-        self.assertEqual(graph.get_hops(1, 5, forward=False),
-            [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3)])
-
-        graph.add_edge(1, 5)
-        graph.add_edge(1, 7)
-        graph.add_edge(4, 7)
-
-        self.assertEqual(graph.get_hops(1, forward=False),
-            [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)])
-
-
-    def test_constructor(self):
-        graph = Graph(iter([
-                (1, 2),
-                (2, 3, 'a'),
-                (1, 3),
-                (3, 4),
-            ]))
-        self.assertEqual(graph.number_of_nodes(), 4)
-        self.assertEqual(graph.number_of_edges(), 4)
-        try:
-            graph.edge_by_node(1,2)
-            graph.edge_by_node(2,3)
-            graph.edge_by_node(1,3)
-            graph.edge_by_node(3,4)
-        except GraphError:
-            self.fail("Incorrect graph")
-
-        self.assertEqual(graph.edge_data(graph.edge_by_node(2, 3)), 'a')
-
-        self.assertRaises(GraphError, Graph, [(1,2,3,4)])
-
-if __name__ == "__main__": # pragma: no cover
-    unittest.main()
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graphstat.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graphstat.py
deleted file mode 100644
index b628b6f..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graphstat.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import unittest
-
-from altgraph import GraphStat
-from altgraph import Graph
-import sys
-
-class TestDegreesDist (unittest.TestCase):
-
-    def test_simple(self):
-        a = Graph.Graph()
-        self.assertEqual(GraphStat.degree_dist(a), [])
-
-        a.add_node(1)
-        a.add_node(2)
-        a.add_node(3)
-
-        self.assertEqual(GraphStat.degree_dist(a), GraphStat._binning([0, 0, 0]))
-
-        for x in range(100):
-            a.add_node(x)
-
-        for x in range(1, 100):
-            for y in range(1, 50):
-                if x % y == 0:
-                    a.add_edge(x, y)
-
-        counts_inc = []
-        counts_out = []
-        for n in a:
-            counts_inc.append(a.inc_degree(n))
-            counts_out.append(a.out_degree(n))
-
-        self.assertEqual(GraphStat.degree_dist(a), GraphStat._binning(counts_out))
-        self.assertEqual(GraphStat.degree_dist(a, mode='inc'), GraphStat._binning(counts_inc))
-
-class TestBinning (unittest.TestCase):
-    def test_simple(self):
-
-        # Binning [0, 100) into 10 bins
-        a = list(range(100))
-        out = GraphStat._binning(a, limits=(0, 100), bin_num=10)
-
-        self.assertEqual(out,
-                [ (x*1.0, 10) for x in range(5, 100, 10) ])
-
-
-        # Check that outliers are ignored.
-        a = list(range(100))
-        out = GraphStat._binning(a, limits=(0, 90), bin_num=9)
-
-        self.assertEqual(out,
-                [ (x*1.0, 10) for x in range(5, 90, 10) ])
-
-
-        out = GraphStat._binning(a, limits=(0, 100), bin_num=15)
-        binSize = 100 / 15.0
-        result = [0]*15
-        for i in range(100):
-            bin = int(i/binSize)
-            try:
-                result[bin] += 1
-            except IndexError:
-                pass
-
-        result = [ (i * binSize + binSize/2, result[i]) for i in range(len(result))]
-
-        self.assertEqual(result, out)
-
-if __name__ == "__main__": # pragma: no cover
-    unittest.main()
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graphutil.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graphutil.py
deleted file mode 100644
index c116623..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_graphutil.py
+++ /dev/null
@@ -1,140 +0,0 @@
-import unittest
-from altgraph import GraphUtil
-from altgraph import Graph, GraphError
-
-class TestGraphUtil (unittest.TestCase):
-
-    def test_generate_random(self):
-        g =  GraphUtil.generate_random_graph(10, 50)
-        self.assertEqual(g.number_of_nodes(), 10)
-        self.assertEqual(g.number_of_edges(), 50)
-
-        seen = set()
-
-        for e in g.edge_list():
-            h, t = g.edge_by_id(e)
-            self.assertFalse(h == t)
-            self.assertTrue((h, t) not in seen)
-            seen.add((h, t))
-
-        g =  GraphUtil.generate_random_graph(5, 30, multi_edges=True)
-        self.assertEqual(g.number_of_nodes(), 5)
-        self.assertEqual(g.number_of_edges(), 30)
-
-        seen = set()
-
-        for e in g.edge_list():
-            h, t = g.edge_by_id(e)
-            self.assertFalse(h == t)
-            if (h, t) in seen:
-                break
-            seen.add((h, t))
-
-        else:
-            self.fail("no duplicates?")
-
-        g =  GraphUtil.generate_random_graph(5, 21, self_loops=True)
-        self.assertEqual(g.number_of_nodes(), 5)
-        self.assertEqual(g.number_of_edges(), 21)
-
-        seen = set()
-
-        for e in g.edge_list():
-            h, t = g.edge_by_id(e)
-            self.assertFalse((h, t) in seen)
-            if h == t:
-                break
-            seen.add((h, t))
-
-        else:
-            self.fail("no self loops?")
-
-        self.assertRaises(GraphError, GraphUtil.generate_random_graph, 5, 21)
-        g = GraphUtil.generate_random_graph(5, 21, True)
-        self.assertRaises(GraphError, GraphUtil.generate_random_graph, 5, 26, True)
-
-    def test_generate_scale_free(self):
-        graph = GraphUtil.generate_scale_free_graph(50, 10)
-        self.assertEqual(graph.number_of_nodes(), 500)
-
-        counts = {}
-        for node in graph:
-            degree = graph.inc_degree(node)
-            try:
-                counts[degree] += 1
-            except KeyError:
-                counts[degree] = 1
-
-        total_counts = sum(counts.values())
-        P = {}
-        for degree, count in counts.items():
-            P[degree] = count * 1.0 / total_counts
-
-        # XXX: use algoritm <http://stackoverflow.com/questions/3433486/how-to-do-exponential-and-logarithmic-curve-fitting-in-python-i-found-only-polyn>
-        # to check if P[degree] ~ degree ** G (for some G)
-
-        #print sorted(P.items())
-
-        #print sorted([(count, degree) for degree, count in counts.items()])
-
-        #self.fail("missing tests for GraphUtil.generate_scale_free_graph")
-
-    def test_filter_stack(self):
-        g = Graph.Graph()
-        g.add_node("1", "N.1")
-        g.add_node("1.1", "N.1.1")
-        g.add_node("1.1.1", "N.1.1.1")
-        g.add_node("1.1.2", "N.1.1.2")
-        g.add_node("1.1.3", "N.1.1.3")
-        g.add_node("1.1.1.1", "N.1.1.1.1")
-        g.add_node("1.1.1.2", "N.1.1.1.2")
-        g.add_node("1.1.2.1", "N.1.1.2.1")
-        g.add_node("1.1.2.2", "N.1.1.2.2")
-        g.add_node("1.1.2.3", "N.1.1.2.3")
-        g.add_node("2", "N.2")
-
-        g.add_edge("1", "1.1")
-        g.add_edge("1.1", "1.1.1")
-        g.add_edge("1.1", "1.1.2")
-        g.add_edge("1.1", "1.1.3")
-        g.add_edge("1.1.1", "1.1.1.1")
-        g.add_edge("1.1.1", "1.1.1.2")
-        g.add_edge("1.1.2", "1.1.2.1")
-        g.add_edge("1.1.2", "1.1.2.2")
-        g.add_edge("1.1.2", "1.1.2.3")
-
-        v, r, o =  GraphUtil.filter_stack(g, "1", [
-            lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.2.3" ])
-
-        self.assertEqual(v,
-            set(["1", "1.1", "1.1.1", "1.1.2", "1.1.3",
-                "1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2",
-                "1.1.2.3"]))
-        self.assertEqual(r, set([
-                "1.1.1", "1.1.2.3"]))
-
-        o.sort()
-        self.assertEqual(o,
-            [
-                ("1.1", "1.1.1.1"),
-                ("1.1", "1.1.1.2")
-            ])
-
-        v, r, o =  GraphUtil.filter_stack(g, "1", [
-            lambda n: n != "N.1.1.1", lambda n: n != "N.1.1.1.2" ])
-
-        self.assertEqual(v,
-            set(["1", "1.1", "1.1.1", "1.1.2", "1.1.3",
-                "1.1.1.1", "1.1.1.2", "1.1.2.1", "1.1.2.2",
-                "1.1.2.3"]))
-        self.assertEqual(r, set([
-                "1.1.1", "1.1.1.2"]))
-
-        self.assertEqual(o,
-            [
-                ("1.1", "1.1.1.1"),
-            ])
-
-
-if __name__ == "__main__": # pragma: no cover
-    unittest.main()
diff --git a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_object_graph.py b/catapult/telemetry/third_party/altgraph/altgraph_tests/test_object_graph.py
deleted file mode 100644
index 9035607..0000000
--- a/catapult/telemetry/third_party/altgraph/altgraph_tests/test_object_graph.py
+++ /dev/null
@@ -1,349 +0,0 @@
-import unittest
-import sys
-from altgraph.ObjectGraph import ObjectGraph
-from altgraph.Graph import Graph
-
-try:
-    from StringIO import StringIO
-except ImportError:
-    from io import StringIO
-
-
-class Node (object):
-    def __init__(self, graphident):
-        self.graphident = graphident
-
-class SubNode (Node):
-    pass
-
-class ArgNode (object):
-    def __init__(self, graphident, *args, **kwds):
-        self.graphident = graphident
-        self.args = args
-        self.kwds = kwds
-
-    def __repr__(self):
-        return '<ArgNode %s>'%(self.graphident,)
-
-class TestObjectGraph (unittest.TestCase):
-
-    def test_constructor(self):
-        graph = ObjectGraph()
-        self.assertTrue(isinstance(graph, ObjectGraph))
-
-        g = Graph()
-        graph = ObjectGraph(g)
-        self.assertTrue(graph.graph is g)
-        self.assertEqual(graph.debug, 0)
-        self.assertEqual(graph.indent, 0)
-
-        graph = ObjectGraph(debug=5)
-        self.assertEqual(graph.debug, 5)
-
-    def test_repr(self):
-        graph = ObjectGraph()
-        self.assertEqual(repr(graph), '<ObjectGraph>')
-
-
-    def testNodes(self):
-        graph = ObjectGraph()
-        n1 = Node("n1")
-        n2 = Node("n2")
-        n3 = Node("n3")
-        n4 = Node("n4")
-
-        n1b = Node("n1")
-
-        self.assertTrue(graph.getIdent(graph)  is graph)
-        self.assertTrue(graph.getRawIdent(graph)  is graph)
-
-        graph.addNode(n1)
-        graph.addNode(n2)
-        graph.addNode(n3)
-
-        self.assertTrue(n1 in graph)
-        self.assertFalse(n4 in graph)
-        self.assertTrue("n1" in graph)
-        self.assertFalse("n4" in graph)
-
-        self.assertTrue(graph.findNode(n1) is n1)
-        self.assertTrue(graph.findNode(n1b) is n1)
-        self.assertTrue(graph.findNode(n2) is n2)
-        self.assertTrue(graph.findNode(n4) is None)
-        self.assertTrue(graph.findNode("n1") is n1)
-        self.assertTrue(graph.findNode("n2") is n2)
-        self.assertTrue(graph.findNode("n4") is None)
-
-        self.assertEqual(graph.getRawIdent(n1), "n1")
-        self.assertEqual(graph.getRawIdent(n1b), "n1")
-        self.assertEqual(graph.getRawIdent(n4), "n4")
-        self.assertEqual(graph.getRawIdent("n1"), None)
-
-        self.assertEqual(graph.getIdent(n1), "n1")
-        self.assertEqual(graph.getIdent(n1b), "n1")
-        self.assertEqual(graph.getIdent(n4), "n4")
-        self.assertEqual(graph.getIdent("n1"), "n1")
-
-        self.assertTrue(n3 in graph)
-        graph.removeNode(n3)
-        self.assertTrue(n3 not in graph)
-        graph.addNode(n3)
-        self.assertTrue(n3 in graph)
-
-        n = graph.createNode(SubNode, "n1")
-        self.assertTrue(n is n1)
-
-        n = graph.createNode(SubNode, "n8")
-        self.assertTrue(isinstance(n, SubNode))
-        self.assertTrue(n in graph)
-        self.assertTrue(graph.findNode("n8") is n)
-
-        n = graph.createNode(ArgNode, "args", 1, 2, 3, a='a', b='b')
-        self.assertTrue(isinstance(n, ArgNode))
-        self.assertTrue(n in graph)
-        self.assertTrue(graph.findNode("args") is n)
-        self.assertEqual(n.args, (1, 2, 3))
-        self.assertEqual(n.kwds, {'a':'a', 'b':'b'})
-
-    def testEdges(self):
-        graph = ObjectGraph()
-        n1 = graph.createNode(ArgNode, "n1", 1)
-        n2 = graph.createNode(ArgNode, "n2", 1)
-        n3 = graph.createNode(ArgNode, "n3", 1)
-        n4 = graph.createNode(ArgNode, "n4", 1)
-
-        graph.createReference(n1, n2, "n1-n2")
-        graph.createReference("n1", "n3", "n1-n3")
-        graph.createReference("n2", n3)
-
-        g = graph.graph
-        e = g.edge_by_node("n1", "n2")
-        self.assertTrue(e is not None)
-        self.assertEqual(g.edge_data(e), "n1-n2")
-
-        e = g.edge_by_node("n1", "n3")
-        self.assertTrue(e is not None)
-        self.assertEqual(g.edge_data(e), "n1-n3")
-
-        e = g.edge_by_node("n2", "n3")
-        self.assertTrue(e is not None)
-        self.assertEqual(g.edge_data(e), None)
-
-        e = g.edge_by_node("n1", "n4")
-        self.assertTrue(e is None)
-
-        graph.removeReference(n1, n2)
-        e = g.edge_by_node("n1", "n2")
-        self.assertTrue(e is None)
-
-        graph.removeReference("n1", "n3")
-        e = g.edge_by_node("n1", "n3")
-        self.assertTrue(e is None)
-
-        graph.createReference(n1, n2, "foo")
-        e = g.edge_by_node("n1", "n2")
-        self.assertTrue(e is not None)
-        self.assertEqual(g.edge_data(e), "foo")
-
-
-    def test_flatten(self):
-        graph = ObjectGraph()
-        n1 = graph.createNode(ArgNode, "n1", 1)
-        n2 = graph.createNode(ArgNode, "n2", 2)
-        n3 = graph.createNode(ArgNode, "n3", 3)
-        n4 = graph.createNode(ArgNode, "n4", 4)
-        n5 = graph.createNode(ArgNode, "n5", 5)
-        n6 = graph.createNode(ArgNode, "n6", 6)
-        n7 = graph.createNode(ArgNode, "n7", 7)
-        n8 = graph.createNode(ArgNode, "n8", 8)
-
-        graph.createReference(graph, n1)
-        graph.createReference(graph, n7)
-        graph.createReference(n1, n2)
-        graph.createReference(n1, n4)
-        graph.createReference(n2, n3)
-        graph.createReference(n2, n5)
-        graph.createReference(n5, n6)
-        graph.createReference(n4, n6)
-        graph.createReference(n4, n2)
-
-        self.assertFalse(isinstance(graph.flatten(), list))
-
-        fl = list(graph.flatten())
-        self.assertTrue(n1 in fl)
-        self.assertTrue(n2 in fl)
-        self.assertTrue(n3 in fl)
-        self.assertTrue(n4 in fl)
-        self.assertTrue(n5 in fl)
-        self.assertTrue(n6 in fl)
-        self.assertTrue(n7 in fl)
-        self.assertFalse(n8 in fl)
-
-        fl = list(graph.flatten(start=n2))
-        self.assertFalse(n1 in fl)
-        self.assertTrue(n2 in fl)
-        self.assertTrue(n3 in fl)
-        self.assertFalse(n4 in fl)
-        self.assertTrue(n5 in fl)
-        self.assertTrue(n6 in fl)
-        self.assertFalse(n7 in fl)
-        self.assertFalse(n8 in fl)
-
-        graph.createReference(n1, n5)
-        fl = list(graph.flatten(lambda n: n.args[0] % 2 != 0))
-        self.assertTrue(n1 in fl)
-        self.assertFalse(n2 in fl)
-        self.assertFalse(n3 in fl)
-        self.assertFalse(n4 in fl)
-        self.assertTrue(n5 in fl)
-        self.assertFalse(n6 in fl)
-        self.assertTrue(n7 in fl)
-        self.assertFalse(n8 in fl)
-
-    def test_iter_nodes(self):
-        graph = ObjectGraph()
-        n1 = graph.createNode(ArgNode, "n1", 1)
-        n2 = graph.createNode(ArgNode, "n2", 2)
-        n3 = graph.createNode(ArgNode, "n3", 3)
-        n4 = graph.createNode(ArgNode, "n4", 4)
-        n5 = graph.createNode(ArgNode, "n5", 5)
-        n6 = graph.createNode(ArgNode, "n6", 5)
-
-        nodes = graph.nodes()
-        if sys.version[0] == '2':
-            self.assertTrue(hasattr(nodes, 'next'))
-        else:
-            self.assertTrue(hasattr(nodes, '__next__'))
-        self.assertTrue(hasattr(nodes, '__iter__'))
-
-        nodes = list(nodes)
-        self.assertEqual(len(nodes), 6)
-        self.assertTrue(n1 in nodes)
-        self.assertTrue(n2 in nodes)
-        self.assertTrue(n3 in nodes)
-        self.assertTrue(n4 in nodes)
-        self.assertTrue(n5 in nodes)
-        self.assertTrue(n6 in nodes)
-
-    def test_get_edges(self):
-        graph = ObjectGraph()
-        n1 = graph.createNode(ArgNode, "n1", 1)
-        n2 = graph.createNode(ArgNode, "n2", 2)
-        n3 = graph.createNode(ArgNode, "n3", 3)
-        n4 = graph.createNode(ArgNode, "n4", 4)
-        n5 = graph.createNode(ArgNode, "n5", 5)
-        n6 = graph.createNode(ArgNode, "n6", 5)
-
-        graph.createReference(n1, n2)
-        graph.createReference(n1, n3)
-        graph.createReference(n3, n1)
-        graph.createReference(n5, n1)
-        graph.createReference(n2, n4)
-        graph.createReference(n2, n5)
-        graph.createReference(n6, n2)
-
-        outs, ins = graph.get_edges(n1)
-
-        self.assertFalse(isinstance(outs, list))
-        self.assertFalse(isinstance(ins, list))
-
-        ins = list(ins)
-        outs = list(outs)
-
-
-        self.assertTrue(n1 not in outs)
-        self.assertTrue(n2 in outs)
-        self.assertTrue(n3 in outs)
-        self.assertTrue(n4 not in outs)
-        self.assertTrue(n5 not in outs)
-        self.assertTrue(n6 not in outs)
-
-        self.assertTrue(n1 not in ins)
-        self.assertTrue(n2 not in ins)
-        self.assertTrue(n3 in ins)
-        self.assertTrue(n4 not in ins)
-        self.assertTrue(n5 in ins)
-        self.assertTrue(n6 not in ins)
-
-    def test_filterStack(self):
-        graph = ObjectGraph()
-        n1 = graph.createNode(ArgNode, "n1", 0)
-        n11 = graph.createNode(ArgNode, "n1.1", 1)
-        n12 = graph.createNode(ArgNode, "n1.2", 0)
-        n111 = graph.createNode(ArgNode, "n1.1.1", 0)
-        n112 = graph.createNode(ArgNode, "n1.1.2",2)
-        n2 = graph.createNode(ArgNode, "n2", 0)
-        n3 = graph.createNode(ArgNode, "n2", 0)
-
-        graph.createReference(None, n1)
-        graph.createReference(None, n2)
-        graph.createReference(n1, n11)
-        graph.createReference(n1, n12)
-        graph.createReference(n11, n111)
-        graph.createReference(n11, n112)
-
-        self.assertTrue(n1 in graph)
-        self.assertTrue(n2 in graph)
-        self.assertTrue(n11 in graph)
-        self.assertTrue(n12 in graph)
-        self.assertTrue(n111 in graph)
-        self.assertTrue(n112 in graph)
-        self.assertTrue(n2 in graph)
-        self.assertTrue(n3 in graph)
-
-        visited, removes, orphans = graph.filterStack(
-                [lambda n: n.args[0] != 1, lambda n: n.args[0] != 2])
-
-        self.assertEqual(visited, 6)
-        self.assertEqual(removes, 2)
-        self.assertEqual(orphans, 1)
-
-        e = graph.graph.edge_by_node(n1.graphident, n111.graphident)
-        self.assertEqual(graph.graph.edge_data(e), "orphan")
-
-        self.assertTrue(n1 in graph)
-        self.assertTrue(n2 in graph)
-        self.assertTrue(n11 not in graph)
-        self.assertTrue(n12 in graph)
-        self.assertTrue(n111 in graph)
-        self.assertTrue(n112 not in graph)
-        self.assertTrue(n2 in graph)
-        self.assertTrue(n3 in graph)
-
-
-class TestObjectGraphIO (unittest.TestCase):
-    def setUp(self):
-        self._stdout = sys.stdout
-
-    def tearDown(self):
-        sys.stdout = self._stdout
-
-    def test_msg(self):
-        graph = ObjectGraph()
-
-        sys.stdout = fp = StringIO()
-        graph.msg(0, "foo")
-        self.assertEqual(fp.getvalue(), "foo \n")
-
-        sys.stdout = fp = StringIO()
-        graph.msg(5, "foo")
-        self.assertEqual(fp.getvalue(), "")
-
-        sys.stdout = fp = StringIO()
-        graph.debug = 10
-        graph.msg(5, "foo")
-        self.assertEqual(fp.getvalue(), "foo \n")
-
-        sys.stdout = fp = StringIO()
-        graph.msg(0, "foo", 1, "a")
-        self.assertEqual(fp.getvalue(), "foo 1 'a'\n")
-
-        sys.stdout = fp = StringIO()
-        graph.msgin(0, "hello", "world")
-        graph.msg(0, "test me")
-        graph.msgout(0, "bye bye")
-        self.assertEqual(fp.getvalue(), "hello 'world'\n  test me \nbye bye \n")
-
-
-if __name__ == "__main__": # pragma: no cover
-    unittest.main()
diff --git a/catapult/telemetry/third_party/altgraph/doc/Makefile b/catapult/telemetry/third_party/altgraph/doc/Makefile
deleted file mode 100644
index b91ac81..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    =
-SPHINXBUILD   = sphinx-build
-PAPER         =
-BUILDDIR      = _build
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
-
-help:
-	@echo "Please use \`make <target>' where <target> is one of"
-	@echo "  html      to make standalone HTML files"
-	@echo "  dirhtml   to make HTML files named index.html in directories"
-	@echo "  pickle    to make pickle files"
-	@echo "  json      to make JSON files"
-	@echo "  htmlhelp  to make HTML files and a HTML help project"
-	@echo "  qthelp    to make HTML files and a qthelp project"
-	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-	@echo "  changes   to make an overview of all changed/added/deprecated items"
-	@echo "  linkcheck to check all external links for integrity"
-	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
-
-clean:
-	-rm -rf $(BUILDDIR)/*
-
-html:
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
-	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-pickle:
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-	@echo
-	@echo "Build finished; now you can process the pickle files."
-
-json:
-	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-	@echo
-	@echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-	@echo
-	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
-	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-	@echo
-	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
-	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/altgraph.qhcp"
-	@echo "To view the help file:"
-	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/altgraph.qhc"
-
-latex:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo
-	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
-	      "run these through (pdf)latex."
-
-changes:
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-	@echo
-	@echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-	@echo
-	@echo "Link check complete; look for any errors in the above output " \
-	      "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
-	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-	@echo "Testing of doctests in the sources finished, look at the " \
-	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/catapult/telemetry/third_party/altgraph/doc/changelog.rst b/catapult/telemetry/third_party/altgraph/doc/changelog.rst
deleted file mode 100644
index 02fd412..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/changelog.rst
+++ /dev/null
@@ -1,185 +0,0 @@
-Release history
-===============
-
-0.12
-----
-
-- Added ``ObjectGraph.edgeData`` to retrieve the edge data
-  from a specific edge.
-
-- Added ``AltGraph.update_edge_data`` and ``ObjectGraph.updateEdgeData``
-  to update the data associated with a graph edge.
-
-0.11
-----
-
-- Stabilize the order of elements in dot file exports,
-  patch from bitbucket user 'pombredanne'.
-
-- Tweak setup.py file to remove dependency on distribute (but
-  keep the dependency on setuptools)
-
-
-0.10.2
-------
-
-- There where no classifiers in the package metadata due to a bug
-  in setup.py
-
-0.10.1
-------
-
-This is a bugfix release
-
-Bug fixes:
-
-- Issue #3: The source archive contains a README.txt
-  while the setup file refers to ReadMe.txt.
-
-  This is caused by a misfeature in distutils, as a
-  workaround I've renamed ReadMe.txt to README.txt
-  in the source tree and setup file.
-
-
-0.10
------
-
-This is a minor feature release
-
-Features:
-
-- Do not use "2to3" to support Python 3.
-
-  As a side effect of this altgraph now supports
-  Python 2.6 and later, and no longer supports
-  earlier releases of Python.
-
-- The order of attributes in the Dot output
-  is now always alphabetical.
-
-  With this change the output will be consistent
-  between runs and Python versions.
-
-0.9
----
-
-This is a minor bugfix release
-
-Features:
-
-- Added ``altgraph.ObjectGraph.ObjectGraph.nodes``, a method
-  yielding all nodes in an object graph.
-
-Bugfixes:
-
-- The 0.8 release didn't work with py2app when using
-  python 3.x.
-
-
-0.8
------
-
-This is a minor feature release. The major new feature
-is a extensive set of unittests, which explains almost
-all other changes in this release.
-
-Bugfixes:
-
-- Installing failed with Python 2.5 due to using a distutils
-  class that isn't available in that version of Python
-  (issue #1 on the issue tracker)
-
-- ``altgraph.GraphStat.degree_dist`` now actually works
-
-- ``altgraph.Graph.add_edge(a, b, create_nodes=False)`` will
-  no longer create the edge when one of the nodes doesn't
-  exist.
-
-- ``altgraph.Graph.forw_topo_sort`` failed for some sparse graphs.
-
-- ``altgraph.Graph.back_topo_sort`` was completely broken in
-  previous releases.
-
-- ``altgraph.Graph.forw_bfs_subgraph`` now actually works.
-
-- ``altgraph.Graph.back_bfs_subgraph`` now actually works.
-
-- ``altgraph.Graph.iterdfs`` now returns the correct result
-  when the ``forward`` argument is ``False``.
-
-- ``altgraph.Graph.iterdata`` now returns the correct result
-  when the ``forward`` argument is ``False``.
-
-
-Features:
-
-- The ``altgraph.Graph`` constructor now accepts an argument
-  that contains 2- and 3-tuples instead of requireing that
-  all items have the same size. The (optional) argument can now
-  also be any iterator.
-
-- ``altgraph.Graph.Graph.add_node`` has no effect when you
-  add a hidden node.
-
-- The private method ``altgraph.Graph._bfs`` is no longer
-  present.
-
-- The private method ``altgraph.Graph._dfs`` is no longer
-  present.
-
-- ``altgraph.ObjectGraph`` now has a ``__contains__`` methods,
-  which means you can use the ``in`` operator to check if a
-  node is part of a graph.
-
-- ``altgraph.GraphUtil.generate_random_graph`` will raise
-  ``GraphError`` instead of looping forever when it is
-  impossible to create the requested graph.
-
-- ``altgraph.Dot.edge_style`` raises ``GraphError`` when
-  one of the nodes is not present in the graph. The method
-  silently added the tail in the past, but without ensuring
-  a consistent graph state.
-
-- ``altgraph.Dot.save_img`` now works when the mode is
-  ``"neato"``.
-
-0.7.2
------
-
-This is a minor bugfix release
-
-Bugfixes:
-
-- distutils didn't include the documentation subtree
-
-0.7.1
------
-
-This is a minor feature release
-
-Features:
-
-- Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
-  and can be viewed at <http://packages.python.org/altgraph>.
-
-- The repository has moved to bitbucket
-
-- ``altgraph.GraphStat.avg_hops`` is no longer present, the function had no
-  implementation and no specified behaviour.
-
-- the module ``altgraph.compat`` is gone, which means altgraph will no
-  longer work with Python 2.3.
-
-
-0.7.0
------
-
-This is a minor feature release.
-
-Features:
-
-- Support for Python 3
-
-- It is now possible to run tests using 'python setup.py test'
-
-  (The actual testsuite is still very minimal though)
diff --git a/catapult/telemetry/third_party/altgraph/doc/conf.py b/catapult/telemetry/third_party/altgraph/doc/conf.py
deleted file mode 100644
index cd3fd99..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/conf.py
+++ /dev/null
@@ -1,209 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# altgraph documentation build configuration file, created by
-# sphinx-quickstart on Tue Aug 31 11:04:49 2010.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-def get_version():
-    fn = os.path.join(
-            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
-            'setup.cfg')
-    for ln in open(fn):
-        if ln.startswith('version'):
-            version = ln.split('=')[-1].strip()
-            return version
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.append(os.path.abspath('.'))
-sys.path.insert(0,
-        os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-# -- General configuration -----------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.autodoc' ]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'altgraph'
-copyright = u'2010-2011, Ronald Oussoren, Bob Ippolito, 2004 Istvan Albert'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = get_version()
-# The full version, including alpha/beta/rc tags.
-release = version
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directory, that shouldn't be searched
-# for source files.
-exclude_trees = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  Major themes that come with
-# Sphinx are currently 'default' and 'sphinxdoc'.
-html_theme = 'nature'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-#html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_use_modindex = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-html_show_sourcelink = False
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'altgraphdoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'altgraph.tex', u'altgraph Documentation',
-   u'Ronald Oussoren', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_use_modindex = True
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {'python': ('http://docs.python.org/', None) }
diff --git a/catapult/telemetry/third_party/altgraph/doc/core.rst b/catapult/telemetry/third_party/altgraph/doc/core.rst
deleted file mode 100644
index 8288f6a..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/core.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-:mod:`altgraph` --- A Python Graph Library
-==================================================
-
-.. module:: altgraph
-   :synopsis: A directional graph for python
-
-altgraph is a fork of `graphlib <http://pygraphlib.sourceforge.net>`_ tailored
-to use newer Python 2.3+ features, including additional support used by the
-py2app suite (modulegraph and macholib, specifically).
-
-altgraph is a python based graph (network) representation and manipulation package.
-It has started out as an extension to the `graph_lib module <http://www.ece.arizona.edu/~denny/python_nest/graph_lib_1.0.1.html>`_
-written by Nathan Denny it has been significantly optimized and expanded.
-
-The :class:`altgraph.Graph.Graph` class is loosely modeled after the `LEDA <http://www.algorithmic-solutions.com/enleda.htm>`_ 
-(Library of Efficient Datatypes)  representation. The library
-includes methods for constructing graphs, BFS and DFS traversals,
-topological sort, finding connected components, shortest paths as well as a number
-graph statistics functions. The library can also visualize graphs
-via `graphviz <http://www.research.att.com/sw/tools/graphviz/>`_.
-
-
-.. exception:: GraphError
-
-   Exception raised when methods are called with bad values of
-   an inconsistent state.
diff --git a/catapult/telemetry/third_party/altgraph/doc/dot.rst b/catapult/telemetry/third_party/altgraph/doc/dot.rst
deleted file mode 100644
index 3848c48..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/dot.rst
+++ /dev/null
@@ -1,224 +0,0 @@
-:mod:`altgraph.Dot` --- Interface to the dot language
-=====================================================
-
-.. module:: altgraph.Dot
-   :synopsis: Interface to the dot language as used by Graphviz..
-
-The :py:mod:`~altgraph.Dot` module provides a simple interface to the
-file format used in the `graphviz`_ program. The module is intended to 
-offload the most tedious part of the process (the **dot** file generation) 
-while transparently exposing most of its features.
-
-.. _`graphviz`: <http://www.research.att.com/sw/tools/graphviz/>`_
-
-To display the graphs or to generate image files the `graphviz`_
-package needs to be installed on the system, moreover the :command:`dot` and :command:`dotty` programs must
-be accesible in the program path so that they can be ran from processes spawned
-within the module. 
-
-Example usage
--------------
-
-Here is a typical usage::
-
-    from altgraph import Graph, Dot
-
-    # create a graph
-    edges = [ (1,2), (1,3), (3,4), (3,5), (4,5), (5,4) ]
-    graph = Graph.Graph(edges)
-    
-    # create a dot representation of the graph
-    dot = Dot.Dot(graph)
-
-    # display the graph
-    dot.display()
-
-    # save the dot representation into the mydot.dot file
-    dot.save_dot(file_name='mydot.dot')
-
-    # save dot file as gif image into the graph.gif file
-    dot.save_img(file_name='graph', file_type='gif')
-
-
-Directed graph and non-directed graph
--------------------------------------
-
-Dot class can use for both directed graph and non-directed graph
-by passing *graphtype* parameter.
-
-Example::
-
-    # create directed graph(default)
-    dot = Dot.Dot(graph, graphtype="digraph")
-
-    # create non-directed graph
-    dot = Dot.Dot(graph, graphtype="graph")
-
-
-Customizing the output
-----------------------
-
-The graph drawing process may be customized by passing
-valid :command:`dot` parameters for the nodes and edges. For a list of all
-parameters see the `graphviz`_ documentation.
-
-Example::
-
-    # customizing the way the overall graph is drawn
-    dot.style(size='10,10', rankdir='RL', page='5, 5' , ranksep=0.75)
-
-    # customizing node drawing
-    dot.node_style(1, label='BASE_NODE',shape='box', color='blue' )
-    dot.node_style(2, style='filled', fillcolor='red')
-
-    # customizing edge drawing
-    dot.edge_style(1, 2, style='dotted')
-    dot.edge_style(3, 5, arrowhead='dot', label='binds', labelangle='90')
-    dot.edge_style(4, 5, arrowsize=2, style='bold')
-
-
-    .. note:: 
-       
-       dotty (invoked via :py:func:`~altgraph.Dot.display`) may not be able to
-       display all graphics styles. To verify the output save it to an image 
-       file and look at it that way.
-
-Valid attributes
-----------------
-
-- dot styles, passed via the :py:meth:`Dot.style` method::
-
-    rankdir = 'LR'   (draws the graph horizontally, left to right)
-    ranksep = number (rank separation in inches)
-
-- node attributes, passed via the :py:meth:`Dot.node_style` method::
-
-     style = 'filled' | 'invisible' | 'diagonals' | 'rounded'
-     shape = 'box' | 'ellipse' | 'circle' | 'point' | 'triangle'
-
-- edge attributes, passed via the :py:meth:`Dot.edge_style` method::
-
-     style     = 'dashed' | 'dotted' | 'solid' | 'invis' | 'bold'
-     arrowhead = 'box' | 'crow' | 'diamond' | 'dot' | 'inv' | 'none' | 'tee' | 'vee'
-     weight    = number (the larger the number the closer the nodes will be)
-
-- valid `graphviz colors <http://www.research.att.com/~erg/graphviz/info/colors.html>`_
-
-- for more details on how to control the graph drawing process see the 
-  `graphviz reference <http://www.research.att.com/sw/tools/graphviz/refs.html>`_.
-
-
-Class interface
----------------
-
-.. class:: Dot(graph[, nodes[, edgefn[, nodevisitor[, edgevisitor[, name[, dot[, dotty[, neato[, graphtype]]]]]]]]])
-
-  Creates a new Dot generator based on the specified 
-  :class:`Graph <altgraph.Graph.Graph>`.  The Dot generator won't reference
-  the *graph* once it is constructed.
-
-  If the *nodes* argument is present it is the list of nodes to include
-  in the graph, otherwise all nodes in *graph* are included.
-  
-  If the *edgefn* argument is present it is a function that yields the
-  nodes connected to another node, this defaults to 
-  :meth:`graph.out_nbr <altgraph.Graph.Graph.out_nbr>`. The constructor won't
-  add edges to the dot file unless both the head and tail of the edge
-  are in *nodes*.
-
-  If the *name* is present it specifies the name of the graph in the resulting
-  dot file. The default is ``"G"``.
-
-  The functions *nodevisitor* and *edgevisitor* return the default style
-  for a given edge or node (both default to functions that return an empty
-  style).
-
-  The arguments *dot*, *dotty* and *neato* are used to pass the path to 
-  the corresponding `graphviz`_ command.
-
-
-Updating graph attributes
-.........................
-
-.. method:: Dot.style(\**attr)
-
-   Sets the overall style (graph attributes) to the given attributes.
-
-   See `Valid Attributes`_ for more information about the attributes.
-
-.. method:: Dot.node_style(node, \**attr)
-
-   Sets the style for *node* to the given attributes.
-
-   This method will add *node* to the graph when it isn't already 
-   present.
-
-   See `Valid Attributes`_ for more information about the attributes.
-
-.. method:: Dot.all_node_style(\**attr)
-
-   Replaces the current style for all nodes
-
-
-.. method:: edge_style(head, tail, \**attr)
-
-   Sets the style of an edge to the given attributes. The edge will
-   be added to the graph when it isn't already present, but *head*
-   and *tail* must both be valid nodes.
-
-   See `Valid Attributes`_ for more information about the attributes.
-
-
-
-Emitting output
-...............
-
-.. method:: Dot.display([mode])
-
-   Displays the current graph via dotty.
-
-   If the *mode* is ``"neato"`` the dot file is processed with
-   the neato command before displaying.
-
-   This method won't return until the dotty command exits.
-
-.. method:: save_dot(filename)
-
-   Saves the current graph representation into the given file.
-
-   .. note::
-
-       For backward compatibility reasons this method can also
-       be called without an argument, it will then write the graph
-       into a fixed filename (present in the attribute :data:`Graph.temp_dot`).
-
-       This feature is deprecated and should not be used.
-
-
-.. method:: save_image(file_name[, file_type[, mode]])
-
-   Saves the current graph representation as an image file. The output
-   is written into a file whose basename is *file_name* and whose suffix
-   is *file_type*.
-
-   The *file_type* specifies the type of file to write, the default
-   is ``"gif"``.
-
-   If the *mode* is ``"neato"`` the dot file is processed with
-   the neato command before displaying.
-
-   .. note::
-
-       For backward compatibility reasons this method can also
-       be called without an argument, it will then write the graph
-       with a fixed basename (``"out"``).
-
-       This feature is deprecated and should not be used.
-
-.. method:: iterdot()
-
-   Yields all lines of a `graphviz`_ input file (including line endings).
-
-.. method:: __iter__()
-
-   Alias for the :meth:`iterdot` method.
diff --git a/catapult/telemetry/third_party/altgraph/doc/graph.rst b/catapult/telemetry/third_party/altgraph/doc/graph.rst
deleted file mode 100644
index 502a218..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/graph.rst
+++ /dev/null
@@ -1,305 +0,0 @@
-:mod:`altgraph.Graph` --- Basic directional graphs
-==================================================
-
-.. module:: altgraph.Graph
-   :synopsis: Basic directional graphs.
-
-The module :mod:`altgraph.Graph` provides a class :class:`Graph` that
-represents a directed graph with *N* nodes and *E* edges.
-
-.. class:: Graph([edges])
-
-  Constructs a new empty :class:`Graph` object. If the optional
-  *edges* parameter is supplied, updates the graph by adding the
-  specified edges.
-
-  All of the elements in *edges* should be tuples with two or three
-  elements. The first two elements of the tuple are the source and
-  destination node of the edge, the optional third element is the
-  edge data.  The source and destination nodes are added to the graph
-  when the aren't already present.
-
-
-Node related methods
---------------------
-
-.. method:: Graph.add_node(node[, node_data])
-
-   Adds a new node to the graph if it is not already present. The new
-   node must be a hashable object.
-
-   Arbitrary data can be attached to the node via the optional *node_data*
-   argument.
-
-   .. note:: the node also won't be added to the graph when it is
-      present but currently hidden.
-
-
-.. method:: Graph.hide_node(node)
-
-   Hides a *node* from the graph. The incoming and outgoing edges of
-   the node will also be hidden.
-
-   Raises :class:`altgraph.GraphError` when the node is not (visible)
-   node of the graph.
-
-
-.. method:: Graph.restore_node(node)
-
-   Restores a previously hidden *node*. The incoming and outgoing
-   edges of the node are also restored.
-
-   Raises :class:`altgraph.GraphError` when the node is not a hidden
-   node of the graph.
-
-.. method:: Graph.restore_all_nodes()
-
-   Restores all hidden nodes.
-
-.. method:: Graph.number_of_nodes()
-
-   Return the number of visible nodes in the graph.
-
-.. method:: Graph.number_of_hidden_nodes()
-
-   Return the number of hidden nodes in the graph.
-
-.. method:: Graph.node_list()
-
-   Return a list with all visible nodes in the graph.
-
-.. method:: Graph.hidden_node_list()
-
-   Return a list with all hidden nodes in the graph.
-
-.. method:: node_data(node)
-
-   Return the data associated with the *node* when it was
-   added.
-
-.. method:: Graph.describe_node(node)
-
-   Returns *node*, the node's data and the lists of outgoing
-   and incoming edges for the node.
-
-   .. note::
-
-      the edge lists should not be modified, doing so
-      can result in unpredicatable behavior.
-
-.. method:: Graph.__contains__(node)
-
-   Returns True iff *node* is a node in the graph. This
-   method is accessed through the *in* operator.
-
-.. method:: Graph.__iter__()
-
-   Yield all nodes in the graph.
-
-.. method:: Graph.out_edges(node)
-
-   Return the list of outgoing edges for *node*
-
-.. method:: Graph.inc_edges(node)
-
-   Return the list of incoming edges for *node*
-
-.. method:: Graph.all_edges(node)
-
-   Return the list of incoming and outgoing edges for *node*
-
-.. method:: Graph.out_degree(node)
-
-   Return the number of outgoing edges for *node*.
-
-.. method:: Graph.inc_degree(node)
-
-   Return the number of incoming edges for *node*.
-
-.. method:: Graph.all_degree(node)
-
-   Return the number of edges (incoming or outgoing) for *node*.
-
-Edge related methods
---------------------
-
-.. method:: Graph.add_edge(head_id, tail_id [, edge data [, create_nodes]])
-
-   Adds a directed edge from *head_id* to *tail_id*. Arbitrary data can
-   be added via *edge_data*.  When *create_nodes* is *True* (the default),
-   *head_id* and *tail_id* will be added to the graph when the aren't
-   already present.
-
-.. method:: Graph.hide_edge(edge)
-
-   Hides an edge from the graph. The edge may be unhidden at some later
-   time.
-
-.. method:: Graph.restore_edge(edge)
-
-   Restores a previously hidden *edge*.
-
-.. method:: Graph.restore_all_edges()
-
-   Restore all edges that were hidden before, except for edges
-   referring to hidden nodes.
-
-.. method:: Graph.edge_by_node(head, tail)
-
-   Return the edge ID for an edge from *head* to *tail*,
-   or :data:`None` when no such edge exists.
-
-.. method:: Graph.edge_by_id(edge)
-
-   Return the head and tail of the *edge*
-
-.. method:: Graph.edge_data(edge)
-
-   Return the data associated with the *edge*.
-
-.. method:: Graph.update_edge_data(edge, data)
-
-   Replace the edge data for *edge* by *data*. Raises
-   :exc:`KeyError` when the edge does not exist.
-
-   .. versionadded:: 0.12
-
-.. method:: Graph.head(edge)
-
-   Return the head of an *edge*
-
-.. method:: Graph.tail(edge)
-
-   Return the tail of an *edge*
-
-.. method:: Graph.describe_edge(edge)
-
-   Return the *edge*, the associated data, its head and tail.
-
-.. method:: Graph.number_of_edges()
-
-   Return the number of visible edges.
-
-.. method:: Graph.number_of_hidden_edges()
-
-   Return the number of hidden edges.
-
-.. method:: Graph.edge_list()
-
-   Returns a list with all visible edges in the graph.
-
-.. method:: Graph.hidden_edge_list()
-
-   Returns a list with all hidden edges in the graph.
-
-Graph traversal
----------------
-
-.. method:: Graph.out_nbrs(node)
-
-   Return a list of all nodes connected by outgoing edges.
-
-.. method:: Graph.inc_nbrs(node)
-
-   Return a list of all nodes connected by incoming edges.
-
-.. method:: Graph.all_nbrs(node)
-
-   Returns a list of nodes connected by an incoming or outgoing edge.
-
-.. method:: Graph.forw_topo_sort()
-
-   Return a list of nodes where the successors (based on outgoing
-   edges) of any given node apear in the sequence after that node.
-
-.. method:: Graph.back_topo_sort()
-
-   Return a list of nodes where the successors (based on incoming
-   edges) of any given node apear in the sequence after that node.
-
-.. method:: Graph.forw_bfs_subgraph(start_id)
-
-   Return a subgraph consisting of the breadth first
-   reachable nodes from *start_id* based on their outgoing edges.
-
-
-.. method:: Graph.back_bfs_subgraph(start_id)
-
-   Return a subgraph consisting of the breadth first
-   reachable nodes from *start_id* based on their incoming edges.
-
-.. method:: Graph.iterdfs(start[, end[, forward]])
-
-   Yield nodes in a depth first traversal starting at the *start*
-   node.
-
-   If *end* is specified traversal stops when reaching that node.
-
-   If forward is True (the default) edges are traversed in forward
-   direction, otherwise they are traversed in reverse direction.
-
-.. method:: Graph.iterdata(start[, end[, forward[, condition]]])
-
-   Yield the associated data for nodes in a depth first traversal
-   starting at the *start* node. This method will not yield values for nodes
-   without associated data.
-
-   If *end* is specified traversal stops when reaching that node.
-
-   If *condition* is specified and the condition callable returns
-   False for the associated data this method will not yield the
-   associated data and will not follow the edges for the node.
-
-   If forward is True (the default) edges are traversed in forward
-   direction, otherwise they are traversed in reverse direction.
-
-.. method:: Graph.forw_bfs(start[, end])
-
-   Returns a list of nodes starting at *start* in some bread first
-   search order (following outgoing edges).
-
-   When *end* is specified iteration stops at that node.
-
-.. method:: Graph.back_bfs(start[, end])
-
-   Returns a list of nodes starting at *start* in some bread first
-   search order (following incoming edges).
-
-   When *end* is specified iteration stops at that node.
-
-.. method:: Graph.get_hops(start[, end[, forward]])
-
-   Computes the hop distance to all nodes centered around a specified node.
-
-   First order neighbours are at hop 1, their neigbours are at hop 2 etc.
-   Uses :py:meth:`forw_bfs` or :py:meth:`back_bfs` depending on the value of
-   the forward parameter.
-
-   If the distance between all neighbouring nodes is 1 the hop number
-   corresponds to the shortest distance between the nodes.
-
-   Typical usage::
-
-        >>> print graph.get_hops(1, 8)
-        >>> [(1, 0), (2, 1), (3, 1), (4, 2), (5, 3), (7, 4), (8, 5)]
-        # node 1 is at 0 hops
-        # node 2 is at 1 hop
-        # ...
-        # node 8 is at 5 hops
-
-
-Graph statistics
-----------------
-
-.. method:: Graph.connected()
-
-   Returns True iff every node in the graph can be reached from
-   every other node.
-
-.. method:: Graph.clust_coef(node)
-
-   Returns the local clustering coefficient of node.
-
-   The local cluster coefficient is the proportion of the actual number
-   of edges between neighbours of node and the maximum number of
-   edges between those nodes.
diff --git a/catapult/telemetry/third_party/altgraph/doc/graphalgo.rst b/catapult/telemetry/third_party/altgraph/doc/graphalgo.rst
deleted file mode 100644
index 84d492f..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/graphalgo.rst
+++ /dev/null
@@ -1,26 +0,0 @@
-:mod:`altgraph.GraphAlgo` --- Graph algorithms
-==================================================
-
-.. module:: altgraph.GraphAlgo
-   :synopsis: Basic graphs algoritms
-
-.. function:: dijkstra(graph, start[, end])
-
-   Dijkstra's algorithm for shortest paths.
-
-   Find shortest paths from the  start node to all nodes nearer 
-   than or equal to the *end* node. The edge data is assumed to be the edge length.
-
-   .. note::
-
-       Dijkstra's algorithm is only guaranteed to work correctly when all edge lengths are positive.
-       This code does not verify this property for all edges (only the edges examined until the end
-       vertex is reached), but will correctly compute shortest paths even for some graphs with negative
-       edges, and will raise an exception if it discovers that a negative edge has caused it to make a mistake.
-
-
-.. function:: shortest_path(graph, start, end)
-
-   Find a single shortest path from the given start node to the given end node.
-   The input has the same conventions as :func:`dijkstra`. The output is a list 
-   of the nodes in order along the shortest path.
diff --git a/catapult/telemetry/third_party/altgraph/doc/graphstat.rst b/catapult/telemetry/third_party/altgraph/doc/graphstat.rst
deleted file mode 100644
index 0931a12..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/graphstat.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-:mod:`altgraph.GraphStat` --- Functions providing various graph statistics
-==========================================================================
-
-.. module:: altgraph.GraphStat
-   :synopsis: Functions providing various graph statistics
-
-The module :mod:`altgraph.GraphStat` provides function that calculate
-graph statistics. Currently there is only one such function, more may
-be added later.
-
-.. function:: degree_dist(graph[, limits[, bin_num[, mode]]])
-
-   Groups the number of edges per node into *bin_num* bins
-   and returns the list of those bins. Every item in the result
-   is a tuple with the center of the bin and the number of items
-   in that bin.
-
-   When the *limits* argument is present it must be a tuple with
-   the mininum and maximum number of edges that get binned (that
-   is, when *limits* is ``(4, 10)`` only nodes with between 4
-   and 10 edges get counted.
-
-   The *mode* argument is used to count incoming (``'inc'``) or
-   outgoing (``'out'``) edges. The default is to count the outgoing
-   edges.
diff --git a/catapult/telemetry/third_party/altgraph/doc/graphutil.rst b/catapult/telemetry/third_party/altgraph/doc/graphutil.rst
deleted file mode 100644
index c07836d..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/graphutil.rst
+++ /dev/null
@@ -1,55 +0,0 @@
-:mod:`altgraph.GraphUtil` --- Utility functions
-================================================
-
-.. module:: altgraph.GraphUtil
-   :synopsis: Utility functions
-
-The module :mod:`altgraph.GraphUtil` performs a number of more
-or less useful utility functions.
-
-.. function:: generate_random_graph(node_num, edge_num[, self_loops[, multi_edges])
-
-   Generates and returns a :class:`Graph <altgraph.Graph.Graph>` instance
-   with *node_num* nodes randomly connected by *edge_num* edges.
-
-   When *self_loops* is present and True there can be edges that point from
-   a node to itself.
-
-   When *multi_edge* is present and True there can be duplicate edges.
-
-   This method raises :class:`GraphError <altgraph.GraphError` when
-   a graph with the requested configuration cannot be created.
-
-.. function:: generate_scale_free_graph(steps, growth_num[, self_loops[, multi_edges]])
-
-    Generates and returns a :py:class:`~altgraph.Graph.Graph` instance that 
-    will have *steps*growth_n um* nodes and a scale free (powerlaw) 
-    connectivity. 
-    
-    Starting with a fully connected graph with *growth_num* nodes
-    at every step *growth_num* nodes are added to the graph and are connected 
-    to existing nodes with a probability proportional to the degree of these 
-    existing nodes.
-
-    .. warning:: The current implementation is basically untested, although
-       code inspection seems to indicate an implementation that is consistent
-       with the description at 
-       `Wolfram MathWorld <http://mathworld.wolfram.com/Scale-FreeNetwork.html>`_
-
-.. function:: filter_stack(graph, head, filters)
-
-   Perform a depth-first oder walk of the graph starting at *head* and
-   apply all filter functions in *filters* on the node data of the nodes
-   found.
-
-   Returns (*visited*, *removes*, *orphans*), where
-
-   * *visited*: the set of visited nodes
-
-   * *removes*: the list of nodes where the node data doesn't match
-     all *filters*.
-
-   * *orphans*: list of tuples (*last_good*, *node*), where 
-     node is not in *removes* and one of the nodes that is connected
-     by an incoming edge is in *removes*. *Last_good* is the
-     closest upstream node that is not in *removes*.
diff --git a/catapult/telemetry/third_party/altgraph/doc/index.rst b/catapult/telemetry/third_party/altgraph/doc/index.rst
deleted file mode 100644
index 1e8d504..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/index.rst
+++ /dev/null
@@ -1,41 +0,0 @@
-.. altgraph documentation master file, created by
-   sphinx-quickstart on Tue Aug 31 11:04:49 2010.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Altgraph - A basic graph library
-================================
-
-altgraph is a fork of graphlib: a graph (network) package for constructing
-graphs, BFS and DFS traversals, topological sort, shortest paths, etc. with
-graphviz output.
-
-The primary users of this package are `macholib <http://pypi.python.org/pypi/macholib>`_ and `modulegraph <http://pypi.python.org/pypi/modulegraph>`_.
-
-.. toctree::
-   :maxdepth: 1
-
-   changelog
-   license
-   core
-   graph
-   objectgraph
-   graphalgo
-   graphstat
-   graphutil
-   dot
-
-Online Resources
-----------------
-
-* `Sourcecode repository on bitbucket <http://bitbucket.org/ronaldoussoren/altgraph/>`_
-
-* `The issue tracker <http://bitbucket.org/ronaldoussoren/altgraph/issues>`_
-
-Indices and tables
-------------------
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/catapult/telemetry/third_party/altgraph/doc/license.rst b/catapult/telemetry/third_party/altgraph/doc/license.rst
deleted file mode 100644
index 498e60b..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/license.rst
+++ /dev/null
@@ -1,25 +0,0 @@
-License
-=======
-
-Copyright (c) 2004 Istvan Albert unless otherwise noted.
-
-Parts are copyright (c) Bob Ippolito
-
-Parts are copyright (c) 2010-2014 Ronald Oussoren
-
-MIT License
-...........
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
-so.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/catapult/telemetry/third_party/altgraph/doc/objectgraph.rst b/catapult/telemetry/third_party/altgraph/doc/objectgraph.rst
deleted file mode 100644
index e3df396..0000000
--- a/catapult/telemetry/third_party/altgraph/doc/objectgraph.rst
+++ /dev/null
@@ -1,146 +0,0 @@
-:mod:`altgraph.ObjectGraph` --- Graphs of objecs with an identifier
-===================================================================
-
-.. module:: altgraph.ObjectGraph
-   :synopsis: A graph of objects that have a "graphident" attribute.
-
-.. class:: ObjectGraph([graph[, debug]])
-
-   A graph of objects that have a "graphident" attribute. The
-   value of this attribute is the key for the object in the
-   graph.
-
-   The optional *graph* is a previously constructed
-   :class:`Graph <altgraph.Graph.Graph>`.
-
-   The optional *debug* level controls the amount of debug output
-   (see :meth:`msg`, :meth:`msgin` and :meth:`msgout`).
-
-   .. note:: the altgraph library does not generate output, the
-      debug attribute and message methods are present for use
-      by subclasses.
-
-.. data:: ObjectGraph.graph
-
-   An :class:`Graph <altgraph.Graph.Graph>` object that contains
-   the graph data.
-
-
-.. method:: ObjectGraph.addNode(node)
-
-   Adds a *node* to the graph.
-
-   .. note:: re-adding a node that was previously removed
-      using :meth:`removeNode` will reinstate the previously
-      removed node.
-
-.. method:: ObjectGraph.createNode(self, cls, name, \*args, \**kwds)
-
-   Creates a new node using ``cls(*args, **kwds)`` and adds that
-   node using :meth:`addNode`.
-
-   Returns the newly created node.
-
-.. method:: ObjectGraph.removeNode(node)
-
-   Removes a *node* from the graph when it exists. The *node* argument
-   is either a node object, or the graphident of a node.
-
-.. method:: ObjectGraph.createReferences(fromnode, tonode[, edge_data])
-
-   Creates a reference from *fromnode* to *tonode*. The optional
-   *edge_data* is associated with the edge.
-
-   *Fromnode* and *tonode* can either be node objects or the graphident
-   values for nodes.
-
-.. method:: removeReference(fromnode, tonode)
-
-   Removes the reference from *fromnode* to *tonode* if it exists.
-
-.. method:: ObjectGraph.getRawIdent(node)
-
-   Returns the *graphident* attribute of *node*, or the graph itself
-   when *node* is :data:`None`.
-
-.. method:: getIdent(node)
-
-   Same as :meth:`getRawIdent`, but only if the node is part
-   of the graph.
-
-   *Node* can either be an actual node object or the graphident of
-   a node.
-
-.. method:: ObjectGraph.findNode(node)
-
-   Returns a given node in the graph, or :data:`Node` when it cannot
-   be found.
-
-   *Node* is either an object with a *graphident* attribute or
-   the *graphident* attribute itself.
-
-.. method:: ObjectGraph.__contains__(node)
-
-   Returns True if *node* is a member of the graph. *Node* is either an
-   object with a *graphident* attribute or the *graphident* attribute itself.
-
-.. method:: ObjectGraph.flatten([condition[, start]])
-
-   Yield all nodes that are entirely reachable by *condition*
-   starting fromt he given *start* node or the graph root.
-
-   .. note:: objects are only reachable from the graph root
-      when there is a reference from the root to the node
-      (either directly or through another node)
-
-.. method:: ObjectGraph.nodes()
-
-   Yield all nodes in the graph.
-
-.. method:: ObjectGraph.get_edges(node)
-
-   Returns two iterators that yield the nodes reaching by
-   outgoing and incoming edges.
-
-.. method:: ObjectGraph.filterStack(filters)
-
-   Filter the ObjectGraph in-place by removing all edges to nodes that
-   do not match every filter in the given filter list
-
-   Returns a tuple containing the number of:
-   (*nodes_visited*, *nodes_removed*, *nodes_orphaned*)
-
-.. method:: ObjectGraph.edgeData(fromNode, toNode):
-   Return the edge data associated with the edge from *fromNode*
-   to *toNode*.  Raises :exc:`KeyError` when no such edge exists.
-
-   .. versionadded: 0.12
-
-.. method:: ObjectGraph.updateEdgeData(fromNode, toNode, edgeData)
-
-   Replace the data associated with the edge from *fromNode* to
-   *toNode* by *edgeData*.
-
-   Raises :exc:`KeyError` when the edge does not exist.
-
-Debug output
-------------
-
-.. data:: ObjectGraph.debug
-
-   The current debug level.
-
-.. method:: ObjectGraph.msg(level, text, \*args)
-
-   Print a debug message at the current indentation level when the current
-   debug level is *level* or less.
-
-.. method:: ObjectGraph.msgin(level, text, \*args)
-
-   Print a debug message when the current debug level is *level* or less,
-   and increase the indentation level.
-
-.. method:: ObjectGraph.msgout(level, text, \*args)
-
-   Decrease the indentation level and print a debug message when the
-   current debug level is *level* or less.
diff --git a/catapult/telemetry/third_party/altgraph/setup.cfg b/catapult/telemetry/third_party/altgraph/setup.cfg
deleted file mode 100644
index 9c6880e..0000000
--- a/catapult/telemetry/third_party/altgraph/setup.cfg
+++ /dev/null
@@ -1,36 +0,0 @@
-[metadata]
-name = altgraph
-version = 0.12
-description = Python graph (network) package
-long_description_file = 
-	README.txt
-	doc/changelog.rst
-author = Ronald Oussoren
-author_email = ronaldoussoren@mac.com
-maintainer = Ronald Oussoren
-maintainer_email = ronaldoussoren@mac.com
-url = http://packages.python.org/altgraph
-download_url = http://pypi.python.org/pypi/altgraph
-license = MIT
-classifiers = 
-	Intended Audience :: Developers
-	License :: OSI Approved :: MIT License
-	Programming Language :: Python
-	Programming Language :: Python :: 2
-	Programming Language :: Python :: 2.7
-	Programming Language :: Python :: 3
-	Programming Language :: Python :: 3.3
-	Programming Language :: Python :: 3.4
-	Topic :: Software Development :: Libraries :: Python Modules
-	Topic :: Scientific/Engineering :: Mathematics
-	Topic :: Scientific/Engineering :: Visualization
-keywords = graph
-platforms = any
-packages = altgraph
-zip-safe = 1
-
-[egg_info]
-tag_build = 
-tag_date = 0
-tag_svn_revision = 0
-
diff --git a/catapult/telemetry/third_party/altgraph/setup.py b/catapult/telemetry/third_party/altgraph/setup.py
deleted file mode 100644
index a1a4cb6..0000000
--- a/catapult/telemetry/third_party/altgraph/setup.py
+++ /dev/null
@@ -1,867 +0,0 @@
-"""
-Shared setup file for simple python packages. Uses a setup.cfg that
-is the same as the distutils2 project, unless noted otherwise.
-
-It exists for two reasons:
-1) This makes it easier to reuse setup.py code between my own
-   projects
-
-2) Easier migration to distutils2 when that catches on.
-
-Additional functionality:
-
-* Section metadata:
-    requires-test:  Same as 'tests_require' option for setuptools.
-
-"""
-
-import sys
-import os
-import re
-import platform
-from fnmatch import fnmatch
-import os
-import sys
-import time
-import tempfile
-import tarfile
-try:
-    import urllib.request as urllib
-except ImportError:
-    import urllib
-from distutils import log
-try:
-    from hashlib import md5
-
-except ImportError:
-    from md5 import md5
-
-if sys.version_info[0] == 2:
-    from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
-else:
-    from configparser import RawConfigParser, NoOptionError, NoSectionError
-
-ROOTDIR = os.path.dirname(os.path.abspath(__file__))
-
-
-#
-#
-#
-# Parsing the setup.cfg and converting it to something that can be
-# used by setuptools.setup()
-#
-#
-#
-
-def eval_marker(value):
-    """
-    Evaluate an distutils2 environment marker.
-
-    This code is unsafe when used with hostile setup.cfg files,
-    but that's not a problem for our own files.
-    """
-    value = value.strip()
-
-    class M:
-        def __init__(self, **kwds):
-            for k, v in kwds.items():
-                setattr(self, k, v)
-
-    variables = {
-        'python_version': '%d.%d'%(sys.version_info[0], sys.version_info[1]),
-        'python_full_version': sys.version.split()[0],
-        'os': M(
-            name=os.name,
-        ),
-        'sys': M(
-            platform=sys.platform,
-        ),
-        'platform': M(
-            version=platform.version(),
-            machine=platform.machine(),
-        ),
-    }
-
-    return bool(eval(value, variables, variables))
-
-
-    return True
-
-def _opt_value(cfg, into, section, key, transform = None):
-    try:
-        v = cfg.get(section, key)
-        if transform != _as_lines and ';' in v:
-            v, marker = v.rsplit(';', 1)
-            if not eval_marker(marker):
-                return
-
-            v = v.strip()
-
-        if v:
-            if transform:
-                into[key] = transform(v.strip())
-            else:
-                into[key] = v.strip()
-
-    except (NoOptionError, NoSectionError):
-        pass
-
-def _as_bool(value):
-    if value.lower() in ('y', 'yes', 'on'):
-        return True
-    elif value.lower() in ('n', 'no', 'off'):
-        return False
-    elif value.isdigit():
-        return bool(int(value))
-    else:
-        raise ValueError(value)
-
-def _as_list(value):
-    return value.split()
-
-def _as_lines(value):
-    result = []
-    for v in value.splitlines():
-        if ';' in v:
-            v, marker = v.rsplit(';', 1)
-            if not eval_marker(marker):
-                continue
-
-            v = v.strip()
-            if v:
-                result.append(v)
-        else:
-            result.append(v)
-    return result
-
-def _map_requirement(value):
-    m = re.search(r'(\S+)\s*(?:\((.*)\))?', value)
-    name = m.group(1)
-    version = m.group(2)
-
-    if version is None:
-        return name
-
-    else:
-        mapped = []
-        for v in version.split(','):
-            v = v.strip()
-            if v[0].isdigit():
-                # Checks for a specific version prefix
-                m = v.rsplit('.', 1)
-                mapped.append('>=%s,<%s.%s'%(
-                    v, m[0], int(m[1])+1))
-
-            else:
-                mapped.append(v)
-        return '%s %s'%(name, ','.join(mapped),)
-
-def _as_requires(value):
-    requires = []
-    for req in value.splitlines():
-        if ';' in req:
-            req, marker = v.rsplit(';', 1)
-            if not eval_marker(marker):
-                continue
-            req = req.strip()
-
-        if not req:
-            continue
-        requires.append(_map_requirement(req))
-    return requires
-
-def parse_setup_cfg():
-    cfg = RawConfigParser()
-    r = cfg.read([os.path.join(ROOTDIR, 'setup.cfg')])
-    if len(r) != 1:
-        print("Cannot read 'setup.cfg'")
-        sys.exit(1)
-
-    metadata = dict(
-            name        = cfg.get('metadata', 'name'),
-            version     = cfg.get('metadata', 'version'),
-            description = cfg.get('metadata', 'description'),
-    )
-
-    _opt_value(cfg, metadata, 'metadata', 'license')
-    _opt_value(cfg, metadata, 'metadata', 'maintainer')
-    _opt_value(cfg, metadata, 'metadata', 'maintainer_email')
-    _opt_value(cfg, metadata, 'metadata', 'author')
-    _opt_value(cfg, metadata, 'metadata', 'author_email')
-    _opt_value(cfg, metadata, 'metadata', 'url')
-    _opt_value(cfg, metadata, 'metadata', 'download_url')
-    _opt_value(cfg, metadata, 'metadata', 'classifiers', _as_lines)
-    _opt_value(cfg, metadata, 'metadata', 'platforms', _as_list)
-    _opt_value(cfg, metadata, 'metadata', 'packages', _as_list)
-    _opt_value(cfg, metadata, 'metadata', 'keywords', _as_list)
-
-    try:
-        v = cfg.get('metadata', 'requires-dist')
-
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        requires = _as_requires(v)
-        if requires:
-            metadata['install_requires'] = requires
-
-    try:
-        v = cfg.get('metadata', 'requires-test')
-
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        requires = _as_requires(v)
-        if requires:
-            metadata['tests_require'] = requires
-
-
-    try:
-        v = cfg.get('metadata', 'long_description_file')
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        parts = []
-        for nm in v.split():
-            fp = open(nm, 'rU')
-            parts.append(fp.read())
-            fp.close()
-
-        metadata['long_description'] = '\n\n'.join(parts)
-
-
-    try:
-        v = cfg.get('metadata', 'zip-safe')
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        metadata['zip_safe'] = _as_bool(v)
-
-    try:
-        v = cfg.get('metadata', 'console_scripts')
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        if 'entry_points' not in metadata:
-            metadata['entry_points'] = {}
-
-        metadata['entry_points']['console_scripts'] = v.splitlines()
-
-    if sys.version_info[:2] <= (2,6):
-        try:
-            metadata['tests_require'] += ", unittest2"
-        except KeyError:
-            metadata['tests_require'] = "unittest2"
-
-    return metadata
-
-
-#
-#
-#
-# Bootstrapping setuptools/distribute, based on
-# a heavily modified version of distribute_setup.py
-#
-#
-#
-
-
-SETUPTOOLS_PACKAGE='setuptools'
-
-
-try:
-    import subprocess
-
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        return subprocess.call(args) == 0
-
-except ImportError:
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        new_args = []
-        for a in args:
-            new_args.append(a.replace("'", "'\"'\"'"))
-        os.system(' '.join(new_args)) == 0
-
-
-try:
-    import json
-
-    def get_pypi_src_download(package):
-        url = 'https://pypi.python.org/pypi/%s/json'%(package,)
-        fp = urllib.urlopen(url)
-        try:
-            try:
-                data = fp.read()
-
-            finally:
-                fp.close()
-        except urllib.error:
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        pkgdata = json.loads(data.decode('utf-8'))
-        if 'urls' not in pkgdata:
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        for info in pkgdata['urls']:
-            if info['packagetype'] == 'sdist' and info['url'].endswith('tar.gz'):
-                return (info.get('md5_digest'), info['url'])
-
-        raise RuntimeError("Cannot determine downlink link for %s"%(package,))
-
-except ImportError:
-    # Python 2.5 compatibility, no JSON in stdlib but luckily JSON syntax is
-    # simular enough to Python's syntax to be able to abuse the Python compiler
-
-    import _ast as ast
-
-    def get_pypi_src_download(package):
-        url = 'https://pypi.python.org/pypi/%s/json'%(package,)
-        fp = urllib.urlopen(url)
-        try:
-            try:
-                data = fp.read()
-
-            finally:
-                fp.close()
-        except urllib.error:
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-
-        a = compile(data, '-', 'eval', ast.PyCF_ONLY_AST)
-        if not isinstance(a, ast.Expression):
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        a = a.body
-        if not isinstance(a, ast.Dict):
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        for k, v in zip(a.keys, a.values):
-            if not isinstance(k, ast.Str):
-                raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-            k = k.s
-            if k == 'urls':
-                a = v
-                break
-        else:
-            raise RuntimeError("PyPI JSON for %s doesn't contain URLs section"%(package,))
-
-        if not isinstance(a, ast.List):
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        for info in v.elts:
-            if not isinstance(info, ast.Dict):
-                raise RuntimeError("Cannot determine download link for %s"%(package,))
-            url = None
-            packagetype = None
-            chksum = None
-
-            for k, v in zip(info.keys, info.values):
-                if not isinstance(k, ast.Str):
-                    raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-                if k.s == 'url':
-                    if not isinstance(v, ast.Str):
-                        raise RuntimeError("Cannot determine download link for %s"%(package,))
-                    url = v.s
-
-                elif k.s == 'packagetype':
-                    if not isinstance(v, ast.Str):
-                        raise RuntimeError("Cannot determine download link for %s"%(package,))
-                    packagetype = v.s
-
-                elif k.s == 'md5_digest':
-                    if not isinstance(v, ast.Str):
-                        raise RuntimeError("Cannot determine download link for %s"%(package,))
-                    chksum = v.s
-
-            if url is not None and packagetype == 'sdist' and url.endswith('.tar.gz'):
-                return (chksum, url)
-
-        raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-def _build_egg(egg, tarball, to_dir):
-    # extracting the tarball
-    tmpdir = tempfile.mkdtemp()
-    log.warn('Extracting in %s', tmpdir)
-    old_wd = os.getcwd()
-    try:
-        os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        _extractall(tar)
-        tar.close()
-
-        # going in the directory
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
-        os.chdir(subdir)
-        log.warn('Now working in %s', subdir)
-
-        # building an egg
-        log.warn('Building a %s egg in %s', egg, to_dir)
-        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
-
-    finally:
-        os.chdir(old_wd)
-    # returning the result
-    log.warn(egg)
-    if not os.path.exists(egg):
-        raise IOError('Could not build the egg.')
-
-
-def _do_download(to_dir, packagename=SETUPTOOLS_PACKAGE):
-    tarball = download_setuptools(packagename, to_dir)
-    version = tarball.split('-')[-1][:-7]
-    egg = os.path.join(to_dir, '%s-%s-py%d.%d.egg'
-                       % (packagename, version, sys.version_info[0], sys.version_info[1]))
-    if not os.path.exists(egg):
-        _build_egg(egg, tarball, to_dir)
-    sys.path.insert(0, egg)
-    import setuptools
-    setuptools.bootstrap_install_from = egg
-
-
-def use_setuptools():
-    # making sure we use the absolute path
-    return _do_download(os.path.abspath(os.curdir))
-
-def download_setuptools(packagename, to_dir):
-    # making sure we use the absolute path
-    to_dir = os.path.abspath(to_dir)
-    try:
-        from urllib.request import urlopen
-    except ImportError:
-        from urllib2 import urlopen
-
-    chksum, url = get_pypi_src_download(packagename)
-    tgz_name = os.path.basename(url)
-    saveto = os.path.join(to_dir, tgz_name)
-
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            log.warn("Downloading %s", url)
-            src = urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = src.read()
-
-            if chksum is not None:
-                data_sum = md5(data).hexdigest()
-                if data_sum != chksum:
-                    raise RuntimeError("Downloading %s failed: corrupt checksum"%(url,))
-
-
-            dst = open(saveto, "wb")
-            dst.write(data)
-        finally:
-            if src:
-                src.close()
-            if dst:
-                dst.close()
-    return os.path.realpath(saveto)
-
-
-
-def _extractall(self, path=".", members=None):
-    """Extract all members from the archive to the current working
-       directory and set owner, modification time and permissions on
-       directories afterwards. `path' specifies a different directory
-       to extract to. `members' is optional and must be a subset of the
-       list returned by getmembers().
-    """
-    import copy
-    import operator
-    from tarfile import ExtractError
-    directories = []
-
-    if members is None:
-        members = self
-
-    for tarinfo in members:
-        if tarinfo.isdir():
-            # Extract directories with a safe mode.
-            directories.append(tarinfo)
-            tarinfo = copy.copy(tarinfo)
-            tarinfo.mode = 448 # decimal for oct 0700
-        self.extract(tarinfo, path)
-
-    # Reverse sort directories.
-    if sys.version_info < (2, 4):
-        def sorter(dir1, dir2):
-            return cmp(dir1.name, dir2.name)
-        directories.sort(sorter)
-        directories.reverse()
-    else:
-        directories.sort(key=operator.attrgetter('name'), reverse=True)
-
-    # Set correct owner, mtime and filemode on directories.
-    for tarinfo in directories:
-        dirpath = os.path.join(path, tarinfo.name)
-        try:
-            self.chown(tarinfo, dirpath)
-            self.utime(tarinfo, dirpath)
-            self.chmod(tarinfo, dirpath)
-        except ExtractError:
-            e = sys.exc_info()[1]
-            if self.errorlevel > 1:
-                raise
-            else:
-                self._dbg(1, "tarfile: %s" % e)
-
-
-#
-#
-#
-# Definitions of custom commands
-#
-#
-#
-
-try:
-    import setuptools
-
-except ImportError:
-    use_setuptools()
-
-from setuptools import setup
-
-try:
-    from distutils.core import PyPIRCCommand
-except ImportError:
-    PyPIRCCommand = None # Ancient python version
-
-from distutils.core import Command
-from distutils.errors  import DistutilsError
-from distutils import log
-
-if PyPIRCCommand is None:
-    class upload_docs (Command):
-        description = "upload sphinx documentation"
-        user_options = []
-
-        def initialize_options(self):
-            pass
-
-        def finalize_options(self):
-            pass
-
-        def run(self):
-            raise DistutilsError("not supported on this version of python")
-
-else:
-    class upload_docs (PyPIRCCommand):
-        description = "upload sphinx documentation"
-        user_options = PyPIRCCommand.user_options
-
-        def initialize_options(self):
-            PyPIRCCommand.initialize_options(self)
-            self.username = ''
-            self.password = ''
-
-
-        def finalize_options(self):
-            PyPIRCCommand.finalize_options(self)
-            config = self._read_pypirc()
-            if config != {}:
-                self.username = config['username']
-                self.password = config['password']
-
-
-        def run(self):
-            import subprocess
-            import shutil
-            import zipfile
-            import os
-            import urllib
-            import StringIO
-            from base64 import standard_b64encode
-            import httplib
-            import urlparse
-
-            # Extract the package name from distutils metadata
-            meta = self.distribution.metadata
-            name = meta.get_name()
-
-            # Run sphinx
-            if os.path.exists('doc/_build'):
-                shutil.rmtree('doc/_build')
-            os.mkdir('doc/_build')
-
-            p = subprocess.Popen(['make', 'html'],
-                cwd='doc')
-            exit = p.wait()
-            if exit != 0:
-                raise DistutilsError("sphinx-build failed")
-
-            # Collect sphinx output
-            if not os.path.exists('dist'):
-                os.mkdir('dist')
-            zf = zipfile.ZipFile('dist/%s-docs.zip'%(name,), 'w',
-                    compression=zipfile.ZIP_DEFLATED)
-
-            for toplevel, dirs, files in os.walk('doc/_build/html'):
-                for fn in files:
-                    fullname = os.path.join(toplevel, fn)
-                    relname = os.path.relpath(fullname, 'doc/_build/html')
-
-                    print ("%s -> %s"%(fullname, relname))
-
-                    zf.write(fullname, relname)
-
-            zf.close()
-
-            # Upload the results, this code is based on the distutils
-            # 'upload' command.
-            content = open('dist/%s-docs.zip'%(name,), 'rb').read()
-
-            data = {
-                ':action': 'doc_upload',
-                'name': name,
-                'content': ('%s-docs.zip'%(name,), content),
-            }
-            auth = "Basic " + standard_b64encode(self.username + ":" +
-                 self.password)
-
-
-            boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
-            sep_boundary = '\n--' + boundary
-            end_boundary = sep_boundary + '--'
-            body = StringIO.StringIO()
-            for key, value in data.items():
-                if not isinstance(value, list):
-                    value = [value]
-
-                for value in value:
-                    if isinstance(value, tuple):
-                        fn = ';filename="%s"'%(value[0])
-                        value = value[1]
-                    else:
-                        fn = ''
-
-                    body.write(sep_boundary)
-                    body.write('\nContent-Disposition: form-data; name="%s"'%key)
-                    body.write(fn)
-                    body.write("\n\n")
-                    body.write(value)
-
-            body.write(end_boundary)
-            body.write('\n')
-            body = body.getvalue()
-
-            self.announce("Uploading documentation to %s"%(self.repository,), log.INFO)
-
-            schema, netloc, url, params, query, fragments = \
-                    urlparse.urlparse(self.repository)
-
-
-            if schema == 'http':
-                http = httplib.HTTPConnection(netloc)
-            elif schema == 'https':
-                http = httplib.HTTPSConnection(netloc)
-            else:
-                raise AssertionError("unsupported schema "+schema)
-
-            data = ''
-            loglevel = log.INFO
-            try:
-                http.connect()
-                http.putrequest("POST", url)
-                http.putheader('Content-type',
-                    'multipart/form-data; boundary=%s'%boundary)
-                http.putheader('Content-length', str(len(body)))
-                http.putheader('Authorization', auth)
-                http.endheaders()
-                http.send(body)
-            except socket.error:
-                e = socket.exc_info()[1]
-                self.announce(str(e), log.ERROR)
-                return
-
-            r = http.getresponse()
-            if r.status in (200, 301):
-                self.announce('Upload succeeded (%s): %s' % (r.status, r.reason),
-                    log.INFO)
-            else:
-                self.announce('Upload failed (%s): %s' % (r.status, r.reason),
-                    log.ERROR)
-
-                print ('-'*75)
-                print (r.read())
-                print ('-'*75)
-
-
-def recursiveGlob(root, pathPattern):
-    """
-    Recursively look for files matching 'pathPattern'. Return a list
-    of matching files/directories.
-    """
-    result = []
-
-    for rootpath, dirnames, filenames in os.walk(root):
-        for fn in filenames:
-            if fnmatch(fn, pathPattern):
-                result.append(os.path.join(rootpath, fn))
-    return result
-
-
-def importExternalTestCases(unittest,
-        pathPattern="test_*.py", root=".", package=None):
-    """
-    Import all unittests in the PyObjC tree starting at 'root'
-    """
-
-    testFiles = recursiveGlob(root, pathPattern)
-    testModules = map(lambda x:x[len(root)+1:-3].replace('/', '.'), testFiles)
-    if package is not None:
-        testModules = [(package + '.' + m) for m in testModules]
-
-    suites = []
-
-    for modName in testModules:
-        try:
-            module = __import__(modName)
-        except ImportError:
-            print("SKIP %s: %s"%(modName, sys.exc_info()[1]))
-            continue
-
-        if '.' in modName:
-            for elem in modName.split('.')[1:]:
-                module = getattr(module, elem)
-
-        s = unittest.defaultTestLoader.loadTestsFromModule(module)
-        suites.append(s)
-
-    return unittest.TestSuite(suites)
-
-
-
-class test (Command):
-    description = "run test suite"
-    user_options = [
-        ('verbosity=', None, "print what tests are run"),
-    ]
-
-    def initialize_options(self):
-        self.verbosity='1'
-
-    def finalize_options(self):
-        if isinstance(self.verbosity, str):
-            self.verbosity = int(self.verbosity)
-
-
-    def cleanup_environment(self):
-        ei_cmd = self.get_finalized_command('egg_info')
-        egg_name = ei_cmd.egg_name.replace('-', '_')
-
-        to_remove =  []
-        for dirname in sys.path:
-            bn = os.path.basename(dirname)
-            if bn.startswith(egg_name + "-"):
-                to_remove.append(dirname)
-
-        for dirname in to_remove:
-            log.info("removing installed %r from sys.path before testing"%(
-                dirname,))
-            sys.path.remove(dirname)
-
-    def add_project_to_sys_path(self):
-        from pkg_resources import normalize_path, add_activation_listener
-        from pkg_resources import working_set, require
-
-        self.reinitialize_command('egg_info')
-        self.run_command('egg_info')
-        self.reinitialize_command('build_ext', inplace=1)
-        self.run_command('build_ext')
-
-
-        # Check if this distribution is already on sys.path
-        # and remove that version, this ensures that the right
-        # copy of the package gets tested.
-
-        self.__old_path = sys.path[:]
-        self.__old_modules = sys.modules.copy()
-
-
-        ei_cmd = self.get_finalized_command('egg_info')
-        sys.path.insert(0, normalize_path(ei_cmd.egg_base))
-        sys.path.insert(1, os.path.dirname(__file__))
-
-        # Strip the namespace packages defined in this distribution
-        # from sys.modules, needed to reset the search path for
-        # those modules.
-
-        nspkgs = getattr(self.distribution, 'namespace_packages')
-        if nspkgs is not None:
-            for nm in nspkgs:
-                del sys.modules[nm]
-
-        # Reset pkg_resources state:
-        add_activation_listener(lambda dist: dist.activate())
-        working_set.__init__()
-        require('%s==%s'%(ei_cmd.egg_name, ei_cmd.egg_version))
-
-    def remove_from_sys_path(self):
-        from pkg_resources import working_set
-        sys.path[:] = self.__old_path
-        sys.modules.clear()
-        sys.modules.update(self.__old_modules)
-        working_set.__init__()
-
-
-    def run(self):
-        import unittest
-
-        # Ensure that build directory is on sys.path (py3k)
-
-        self.cleanup_environment()
-        self.add_project_to_sys_path()
-
-        try:
-            meta = self.distribution.metadata
-            name = meta.get_name()
-            test_pkg = name + "_tests"
-            suite = importExternalTestCases(unittest,
-                    "test_*.py", test_pkg, test_pkg)
-
-            runner = unittest.TextTestRunner(verbosity=self.verbosity)
-            result = runner.run(suite)
-
-            # Print out summary. This is a structured format that
-            # should make it easy to use this information in scripts.
-            summary = dict(
-                count=result.testsRun,
-                fails=len(result.failures),
-                errors=len(result.errors),
-                xfails=len(getattr(result, 'expectedFailures', [])),
-                xpass=len(getattr(result, 'expectedSuccesses', [])),
-                skip=len(getattr(result, 'skipped', [])),
-            )
-            print("SUMMARY: %s"%(summary,))
-
-        finally:
-            self.remove_from_sys_path()
-
-#
-#
-#
-#  And finally run the setuptools main entry point.
-#
-#
-#
-
-metadata = parse_setup_cfg()
-
-setup(
-    cmdclass=dict(
-        upload_docs=upload_docs,
-        test=test,
-    ),
-    **metadata
-)
diff --git a/catapult/telemetry/third_party/chromite/LICENSE b/catapult/telemetry/third_party/chromite/LICENSE
deleted file mode 100644
index 0aa7fc9..0000000
--- a/catapult/telemetry/third_party/chromite/LICENSE
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2006-2009 The Chromium OS Authors. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//    * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//    * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//    * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/catapult/telemetry/third_party/chromite/README.chromium b/catapult/telemetry/third_party/chromite/README.chromium
deleted file mode 100644
index b51feb8..0000000
--- a/catapult/telemetry/third_party/chromite/README.chromium
+++ /dev/null
@@ -1,15 +0,0 @@
-Name: chromite
-Short Name: chromite
-URL: https://chromium.googlesource.com/chromiumos/chromite
-Version: 0.0.2
-License: BSD
-License File: NOT_SHIPPED
-Security Critical: no
-
-Local modification: remove all the files except chromite/ssh_keys/ which contain
-keys used by telemetry.
-
-Description:
-This contains scripts used to build Chromium for Chromium OS
-('cros chrome-sdk'), as well as interact with the Chromium OS
-build system.
diff --git a/catapult/telemetry/third_party/chromite/ssh_keys/testing_rsa b/catapult/telemetry/third_party/chromite/ssh_keys/testing_rsa
deleted file mode 100644
index d50a630..0000000
--- a/catapult/telemetry/third_party/chromite/ssh_keys/testing_rsa
+++ /dev/null
@@ -1,27 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEoAIBAAKCAQEAvsNpFdK5lb0GfKx+FgsrsM/2+aZVFYXHMPdvGtTz63ciRhq0
-Jnw7nln1SOcHraSz3/imECBg8NHIKV6rA+B9zbf7pZXEv20x5Ul0vrcPqYWC44PT
-tgsgvi8s0KZUZN93YlcjZ+Q7BjQ/tuwGSaLWLqJ7hnHALMJ3dbEM9fKBHQBCrG5H
-OaWD2gtXj7jp04M/WUnDDdemq/KMg6E9jcrJOiQ39IuTpas4hLQzVkKAKSrpl6MY
-2etHyoNarlWhcOwitArEDwf3WgnctwKstI/MTKB5BTpO2WXUNUv4kXzA+g8/l1al
-jIG13vtd9A/IV3KFVx/sLkkjuZ7z2rQXyNKuJwIBIwKCAQA79EWZJPh/hI0CnJyn
-16AEXp4T8nKDG2p9GpCiCGnq6u2Dvz/u1pZk97N9T+x4Zva0GvJc1vnlST7objW/
-Y8/ET8QeGSCT7x5PYDqiVspoemr3DCyYTKPkADKn+cLAngDzBXGHDTcfNP4U6xfr
-Qc5JK8BsFR8kApqSs/zCU4eqBtp2FVvPbgUOv3uUrFnjEuGs9rb1QZ0K6o08L4Cq
-N+e2nTysjp78blakZfqlurqTY6iJb0ImU2W3T8sV6w5GP1NT7eicXLO3WdIRB15a
-evogPeqtMo8GcO62wU/D4UCvq4GNEjvYOvFmPzXHvhTxsiWv5KEACtleBIEYmWHA
-POwrAoGBAOKgNRgxHL7r4bOmpLQcYK7xgA49OpikmrebXCQnZ/kZ3QsLVv1QdNMH
-Rx/ex7721g8R0oWslM14otZSMITCDCMWTYVBNM1bqYnUeEu5HagFwxjQ2tLuSs8E
-SBzEr96JLfhwuBhDH10sQqn+OQG1yj5acs4Pt3L4wlYwMx0vs1BxAoGBANd9Owro
-5ONiJXfKNaNY/cJYuLR+bzGeyp8oxToxgmM4UuA4hhDU7peg4sdoKJ4XjB9cKMCz
-ZGU5KHKKxNf95/Z7aywiIJEUE/xPRGNP6tngRunevp2QyvZf4pgvACvk1tl9B3HH
-7J5tY/GRkT4sQuZYpx3YnbdP5Y6Kx33BF7QXAoGAVCzghVQR/cVT1QNhvz29gs66
-iPIrtQnwUtNOHA6i9h+MnbPBOYRIpidGTaqEtKTTKisw79JjJ78X6TR4a9ML0oSg
-c1K71z9NmZgPbJU25qMN80ZCph3+h2f9hwc6AjLz0U5wQ4alP909VRVIX7iM8paf
-q59wBiHhyD3J16QAxhsCgYBu0rCmhmcV2rQu+kd4lCq7uJmBZZhFZ5tny9MlPgiK
-zIJkr1rkFbyIfqCDzyrU9irOTKc+iCUA25Ek9ujkHC4m/aTU3lnkNjYp/OFXpXF3
-XWZMY+0Ak5uUpldG85mwLIvATu3ivpbyZCTFYM5afSm4StmaUiU5tA+oZKEcGily
-jwKBgBdFLg+kTm877lcybQ04G1kIRMf5vAXcConzBt8ry9J+2iX1ddlu2K2vMroD
-1cP/U/EmvoCXSOGuetaI4UNQwE/rGCtkpvNj5y4twVLh5QufSOl49V0Ut0mwjPXw
-HfN/2MoO07vQrjgsFylvrw9A79xItABaqKndlmqlwMZWc9Ne
------END RSA PRIVATE KEY-----
diff --git a/catapult/telemetry/third_party/chromite/ssh_keys/testing_rsa.pub b/catapult/telemetry/third_party/chromite/ssh_keys/testing_rsa.pub
deleted file mode 100644
index 7a4d033..0000000
--- a/catapult/telemetry/third_party/chromite/ssh_keys/testing_rsa.pub
+++ /dev/null
@@ -1 +0,0 @@
-ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvsNpFdK5lb0GfKx+FgsrsM/2+aZVFYXHMPdvGtTz63ciRhq0Jnw7nln1SOcHraSz3/imECBg8NHIKV6rA+B9zbf7pZXEv20x5Ul0vrcPqYWC44PTtgsgvi8s0KZUZN93YlcjZ+Q7BjQ/tuwGSaLWLqJ7hnHALMJ3dbEM9fKBHQBCrG5HOaWD2gtXj7jp04M/WUnDDdemq/KMg6E9jcrJOiQ39IuTpas4hLQzVkKAKSrpl6MY2etHyoNarlWhcOwitArEDwf3WgnctwKstI/MTKB5BTpO2WXUNUv4kXzA+g8/l1aljIG13vtd9A/IV3KFVx/sLkkjuZ7z2rQXyNKuJw== ChromeOS test key
diff --git a/catapult/telemetry/third_party/flot/LICENSE.txt b/catapult/telemetry/third_party/flot/LICENSE.txt
deleted file mode 100644
index 67f4625..0000000
--- a/catapult/telemetry/third_party/flot/LICENSE.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-Copyright (c) 2007-2013 IOLA and Ole Laursen
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
diff --git a/catapult/telemetry/third_party/flot/README.chromium b/catapult/telemetry/third_party/flot/README.chromium
deleted file mode 100644
index 6bbf71a..0000000
--- a/catapult/telemetry/third_party/flot/README.chromium
+++ /dev/null
@@ -1,10 +0,0 @@
-Name: Flot Javascript/JQuery library for creating graphs
-Short Name: Flot
-URL: http://www.flotcharts.org
-Version: 0.8.1
-License: MIT
-License File: NOT_SHIPPED
-Security Critical: yes
-Description: Flot is used in the webui for performance monitor and the visualizer for Deep Memory Profiler to draw charts of performance metrics.
-Local Modifications: All the files not needed by telemetry are removed. Only keep
-jquery.flot.min.js.
diff --git a/catapult/telemetry/third_party/flot/jquery.flot.min.js b/catapult/telemetry/third_party/flot/jquery.flot.min.js
deleted file mode 100644
index 3706512..0000000
--- a/catapult/telemetry/third_party/flot/jquery.flot.min.js
+++ /dev/null
@@ -1,29 +0,0 @@
-/* Javascript plotting library for jQuery, version 0.8.1.
-
-Copyright (c) 2007-2013 IOLA and Ole Laursen.
-Licensed under the MIT license.
-
-*/// first an inline dependency, jquery.colorhelpers.js, we inline it here
-// for convenience
-/* Plugin for jQuery for working with colors.
- *
- * Version 1.1.
- *
- * Inspiration from jQuery color animation plugin by John Resig.
- *
- * Released under the MIT license by Ole Laursen, October 2009.
- *
- * Examples:
- *
- *   $.color.parse("#fff").scale('rgb', 0.25).add('a', -0.5).toString()
- *   var c = $.color.extract($("#mydiv"), 'background-color');
- *   console.log(c.r, c.g, c.b, c.a);
- *   $.color.make(100, 50, 25, 0.4).toString() // returns "rgba(100,50,25,0.4)"
- *
- * Note that .scale() and .add() return the same modified object
- * instead of making a new one.
- *
- * V. 1.1: Fix error handling so e.g. parsing an empty string does
- * produce a color rather than just crashing.
- */(function(e){e.color={},e.color.make=function(t,n,r,i){var s={};return s.r=t||0,s.g=n||0,s.b=r||0,s.a=i!=null?i:1,s.add=function(e,t){for(var n=0;n<e.length;++n)s[e.charAt(n)]+=t;return s.normalize()},s.scale=function(e,t){for(var n=0;n<e.length;++n)s[e.charAt(n)]*=t;return s.normalize()},s.toString=function(){return s.a>=1?"rgb("+[s.r,s.g,s.b].join(",")+")":"rgba("+[s.r,s.g,s.b,s.a].join(",")+")"},s.normalize=function(){function e(e,t,n){return t<e?e:t>n?n:t}return s.r=e(0,parseInt(s.r),255),s.g=e(0,parseInt(s.g),255),s.b=e(0,parseInt(s.b),255),s.a=e(0,s.a,1),s},s.clone=function(){return e.color.make(s.r,s.b,s.g,s.a)},s.normalize()},e.color.extract=function(t,n){var r;do{r=t.css(n).toLowerCase();if(r!=""&&r!="transparent")break;t=t.parent()}while(!e.nodeName(t.get(0),"body"));return r=="rgba(0, 0, 0, 0)"&&(r="transparent"),e.color.parse(r)},e.color.parse=function(n){var r,i=e.color.make;if(r=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(n))return i(parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10));if(r=/rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(n))return i(parseInt(r[1],10),parseInt(r[2],10),parseInt(r[3],10),parseFloat(r[4]));if(r=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(n))return i(parseFloat(r[1])*2.55,parseFloat(r[2])*2.55,parseFloat(r[3])*2.55);if(r=/rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(n))return i(parseFloat(r[1])*2.55,parseFloat(r[2])*2.55,parseFloat(r[3])*2.55,parseFloat(r[4]));if(r=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(n))return i(parseInt(r[1],16),parseInt(r[2],16),parseInt(r[3],16));if(r=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(n))return i(parseInt(r[1]+r[1],16),parseInt(r[2]+r[2],16),parseInt(r[3]+r[3],16));var s=e.trim(n).toLowerCase();return s=="transparent"?i(255,255,255,0):(r=t[s]||[0,0,0],i(r[0],r[1],r[2]))};var t={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery),function(e){function n(t,n){var r=n.children("."+t)[0];if(r==null){r=document.createElement("canvas"),r.className=t,e(r).css({direction:"ltr",position:"absolute",left:0,top:0}).appendTo(n);if(!r.getContext){if(!window.G_vmlCanvasManager)throw new Error("Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.");r=window.G_vmlCanvasManager.initElement(r)}}this.element=r;var i=this.context=r.getContext("2d"),s=window.devicePixelRatio||1,o=i.webkitBackingStorePixelRatio||i.mozBackingStorePixelRatio||i.msBackingStorePixelRatio||i.oBackingStorePixelRatio||i.backingStorePixelRatio||1;this.pixelRatio=s/o,this.resize(n.width(),n.height()),this.textContainer=null,this.text={},this._textCache={}}function r(t,r,s,o){function E(e,t){t=[w].concat(t);for(var n=0;n<e.length;++n)e[n].apply(this,t)}function S(){var t={Canvas:n};for(var r=0;r<o.length;++r){var i=o[r];i.init(w,t),i.options&&e.extend(!0,a,i.options)}}function x(n){e.extend(!0,a,n),n&&n.colors&&(a.colors=n.colors),a.xaxis.color==null&&(a.xaxis.color=e.color.parse(a.grid.color).scale("a",.22).toString()),a.yaxis.color==null&&(a.yaxis.color=e.color.parse(a.grid.color).scale("a",.22).toString()),a.xaxis.tickColor==null&&(a.xaxis.tickColor=a.grid.tickColor||a.xaxis.color),a.yaxis.tickColor==null&&(a.yaxis.tickColor=a.grid.tickColor||a.yaxis.color),a.grid.borderColor==null&&(a.grid.borderColor=a.grid.color),a.grid.tickColor==null&&(a.grid.tickColor=e.color.parse(a.grid.color).scale("a",.22).toString());var r,i,s,o={style:t.css("font-style"),size:Math.round(.8*(+t.css("font-size").replace("px","")||13)),variant:t.css("font-variant"),weight:t.css("font-weight"),family:t.css("font-family")};o.lineHeight=o.size*1.15,s=a.xaxes.length||1;for(r=0;r<s;++r)i=a.xaxes[r],i&&!i.tickColor&&(i.tickColor=i.color),i=e.extend(!0,{},a.xaxis,i),a.xaxes[r]=i,i.font&&(i.font=e.extend({},o,i.font),i.font.color||(i.font.color=i.color));s=a.yaxes.length||1;for(r=0;r<s;++r)i=a.yaxes[r],i&&!i.tickColor&&(i.tickColor=i.color),i=e.extend(!0,{},a.yaxis,i),a.yaxes[r]=i,i.font&&(i.font=e.extend({},o,i.font),i.font.color||(i.font.color=i.color));a.xaxis.noTicks&&a.xaxis.ticks==null&&(a.xaxis.ticks=a.xaxis.noTicks),a.yaxis.noTicks&&a.yaxis.ticks==null&&(a.yaxis.ticks=a.yaxis.noTicks),a.x2axis&&(a.xaxes[1]=e.extend(!0,{},a.xaxis,a.x2axis),a.xaxes[1].position="top"),a.y2axis&&(a.yaxes[1]=e.extend(!0,{},a.yaxis,a.y2axis),a.yaxes[1].position="right"),a.grid.coloredAreas&&(a.grid.markings=a.grid.coloredAreas),a.grid.coloredAreasColor&&(a.grid.markingsColor=a.grid.coloredAreasColor),a.lines&&e.extend(!0,a.series.lines,a.lines),a.points&&e.extend(!0,a.series.points,a.points),a.bars&&e.extend(!0,a.series.bars,a.bars),a.shadowSize!=null&&(a.series.shadowSize=a.shadowSize),a.highlightColor!=null&&(a.series.highlightColor=a.highlightColor);for(r=0;r<a.xaxes.length;++r)O(d,r+1).options=a.xaxes[r];for(r=0;r<a.yaxes.length;++r)O(v,r+1).options=a.yaxes[r];for(var u in b)a.hooks[u]&&a.hooks[u].length&&(b[u]=b[u].concat(a.hooks[u]));E(b.processOptions,[a])}function T(e){u=N(e),M(),_()}function N(t){var n=[];for(var r=0;r<t.length;++r){var i=e.extend(!0,{},a.series);t[r].data!=null?(i.data=t[r].data,delete t[r].data,e.extend(!0,i,t[r]),t[r].data=i.data):i.data=t[r],n.push(i)}return n}function C(e,t){var n=e[t+"axis"];return typeof n=="object"&&(n=n.n),typeof n!="number"&&(n=1),n}function k(){return e.grep(d.concat(v),function(e){return e})}function L(e){var t={},n,r;for(n=0;n<d.length;++n)r=d[n],r&&r.used&&(t["x"+r.n]=r.c2p(e.left));for(n=0;n<v.length;++n)r=v[n],r&&r.used&&(t["y"+r.n]=r.c2p(e.top));return t.x1!==undefined&&(t.x=t.x1),t.y1!==undefined&&(t.y=t.y1),t}function A(e){var t={},n,r,i;for(n=0;n<d.length;++n){r=d[n];if(r&&r.used){i="x"+r.n,e[i]==null&&r.n==1&&(i="x");if(e[i]!=null){t.left=r.p2c(e[i]);break}}}for(n=0;n<v.length;++n){r=v[n];if(r&&r.used){i="y"+r.n,e[i]==null&&r.n==1&&(i="y");if(e[i]!=null){t.top=r.p2c(e[i]);break}}}return t}function O(t,n){return t[n-1]||(t[n-1]={n:n,direction:t==d?"x":"y",options:e.extend(!0,{},t==d?a.xaxis:a.yaxis)}),t[n-1]}function M(){var t=u.length,n=-1,r;for(r=0;r<u.length;++r){var i=u[r].color;i!=null&&(t--,typeof i=="number"&&i>n&&(n=i))}t<=n&&(t=n+1);var s,o=[],f=a.colors,l=f.length,c=0;for(r=0;r<t;r++)s=e.color.parse(f[r%l]||"#666"),r%l==0&&r&&(c>=0?c<.5?c=-c-.2:c=0:c=-c),o[r]=s.scale("rgb",1+c);var h=0,p;for(r=0;r<u.length;++r){p=u[r],p.color==null?(p.color=o[h].toString(),++h):typeof p.color=="number"&&(p.color=o[p.color].toString());if(p.lines.show==null){var m,g=!0;for(m in p)if(p[m]&&p[m].show){g=!1;break}g&&(p.lines.show=!0)}p.lines.zero==null&&(p.lines.zero=!!p.lines.fill),p.xaxis=O(d,C(p,"x")),p.yaxis=O(v,C(p,"y"))}}function _(){function x(e,t,n){t<e.datamin&&t!=-r&&(e.datamin=t),n>e.datamax&&n!=r&&(e.datamax=n)}var t=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,r=Number.MAX_VALUE,i,s,o,a,f,l,c,h,p,d,v,m,g,y,w,S;e.each(k(),function(e,r){r.datamin=t,r.datamax=n,r.used=!1});for(i=0;i<u.length;++i)l=u[i],l.datapoints={points:[]},E(b.processRawData,[l,l.data,l.datapoints]);for(i=0;i<u.length;++i){l=u[i],w=l.data,S=l.datapoints.format;if(!S){S=[],S.push({x:!0,number:!0,required:!0}),S.push({y:!0,number:!0,required:!0});if(l.bars.show||l.lines.show&&l.lines.fill){var T=!!(l.bars.show&&l.bars.zero||l.lines.show&&l.lines.zero);S.push({y:!0,number:!0,required:!1,defaultValue:0,autoscale:T}),l.bars.horizontal&&(delete S[S.length-1].y,S[S.length-1].x=!0)}l.datapoints.format=S}if(l.datapoints.pointsize!=null)continue;l.datapoints.pointsize=S.length,h=l.datapoints.pointsize,c=l.datapoints.points;var N=l.lines.show&&l.lines.steps;l.xaxis.used=l.yaxis.used=!0;for(s=o=0;s<w.length;++s,o+=h){y=w[s];var C=y==null;if(!C)for(a=0;a<h;++a)m=y[a],g=S[a],g&&(g.number&&m!=null&&(m=+m,isNaN(m)?m=null:m==Infinity?m=r:m==-Infinity&&(m=-r)),m==null&&(g.required&&(C=!0),g.defaultValue!=null&&(m=g.defaultValue))),c[o+a]=m;if(C)for(a=0;a<h;++a)m=c[o+a],m!=null&&(g=S[a],g.autoscale&&(g.x&&x(l.xaxis,m,m),g.y&&x(l.yaxis,m,m))),c[o+a]=null;else if(N&&o>0&&c[o-h]!=null&&c[o-h]!=c[o]&&c[o-h+1]!=c[o+1]){for(a=0;a<h;++a)c[o+h+a]=c[o+a];c[o+1]=c[o-h+1],o+=h}}}for(i=0;i<u.length;++i)l=u[i],E(b.processDatapoints,[l,l.datapoints]);for(i=0;i<u.length;++i){l=u[i],c=l.datapoints.points,h=l.datapoints.pointsize,S=l.datapoints.format;var L=t,A=t,O=n,M=n;for(s=0;s<c.length;s+=h){if(c[s]==null)continue;for(a=0;a<h;++a){m=c[s+a],g=S[a];if(!g||g.autoscale===!1||m==r||m==-r)continue;g.x&&(m<L&&(L=m),m>O&&(O=m)),g.y&&(m<A&&(A=m),m>M&&(M=m))}}if(l.bars.show){var _;switch(l.bars.align){case"left":_=0;break;case"right":_=-l.bars.barWidth;break;case"center":_=-l.bars.barWidth/2;break;default:throw new Error("Invalid bar alignment: "+l.bars.align)}l.bars.horizontal?(A+=_,M+=_+l.bars.barWidth):(L+=_,O+=_+l.bars.barWidth)}x(l.xaxis,L,O),x(l.yaxis,A,M)}e.each(k(),function(e,r){r.datamin==t&&(r.datamin=null),r.datamax==n&&(r.datamax=null)})}function D(){t.css("padding",0).children(":not(.flot-base,.flot-overlay)").remove(),t.css("position")=="static"&&t.css("position","relative"),f=new n("flot-base",t),l=new n("flot-overlay",t),h=f.context,p=l.context,c=e(l.element).unbind();var r=t.data("plot");r&&(r.shutdown(),l.clear()),t.data("plot",w)}function P(){a.grid.hoverable&&(c.mousemove(at),c.bind("mouseleave",ft)),a.grid.clickable&&c.click(lt),E(b.bindEvents,[c])}function H(){ot&&clearTimeout(ot),c.unbind("mousemove",at),c.unbind("mouseleave",ft),c.unbind("click",lt),E(b.shutdown,[c])}function B(e){function t(e){return e}var n,r,i=e.options.transform||t,s=e.options.inverseTransform;e.direction=="x"?(n=e.scale=g/Math.abs(i(e.max)-i(e.min)),r=Math.min(i(e.max),i(e.min))):(n=e.scale=y/Math.abs(i(e.max)-i(e.min)),n=-n,r=Math.max(i(e.max),i(e.min))),i==t?e.p2c=function(e){return(e-r)*n}:e.p2c=function(e){return(i(e)-r)*n},s?e.c2p=function(e){return s(r+e/n)}:e.c2p=function(e){return r+e/n}}function j(e){var t=e.options,n=e.ticks||[],r=t.labelWidth||0,i=t.labelHeight||0,s=r||e.direction=="x"?Math.floor(f.width/(n.length||1)):null;legacyStyles=e.direction+"Axis "+e.direction+e.n+"Axis",layer="flot-"+e.direction+"-axis flot-"+e.direction+e.n+"-axis "+legacyStyles,font=t.font||"flot-tick-label tickLabel";for(var o=0;o<n.length;++o){var u=n[o];if(!u.label)continue;var a=f.getTextInfo(layer,u.label,font,null,s);r=Math.max(r,a.width),i=Math.max(i,a.height)}e.labelWidth=t.labelWidth||r,e.labelHeight=t.labelHeight||i}function F(t){var n=t.labelWidth,r=t.labelHeight,i=t.options.position,s=t.options.tickLength,o=a.grid.axisMargin,u=a.grid.labelMargin,l=t.direction=="x"?d:v,c,h,p=e.grep(l,function(e){return e&&e.options.position==i&&e.reserveSpace});e.inArray(t,p)==p.length-1&&(o=0);if(s==null){var g=e.grep(l,function(e){return e&&e.reserveSpace});h=e.inArray(t,g)==0,h?s="full":s=5}isNaN(+s)||(u+=+s),t.direction=="x"?(r+=u,i=="bottom"?(m.bottom+=r+o,t.box={top:f.height-m.bottom,height:r}):(t.box={top:m.top+o,height:r},m.top+=r+o)):(n+=u,i=="left"?(t.box={left:m.left+o,width:n},m.left+=n+o):(m.right+=n+o,t.box={left:f.width-m.right,width:n})),t.position=i,t.tickLength=s,t.box.padding=u,t.innermost=h}function I(e){e.direction=="x"?(e.box.left=m.left-e.labelWidth/2,e.box.width=f.width-m.left-m.right+e.labelWidth):(e.box.top=m.top-e.labelHeight/2,e.box.height=f.height-m.bottom-m.top+e.labelHeight)}function q(){var t=a.grid.minBorderMargin,n={x:0,y:0},r,i;if(t==null){t=0;for(r=0;r<u.length;++r)t=Math.max(t,2*(u[r].points.radius+u[r].points.lineWidth/2))}n.x=n.y=Math.ceil(t),e.each(k(),function(e,t){var r=t.direction;t.reserveSpace&&(n[r]=Math.ceil(Math.max(n[r],(r=="x"?t.labelWidth:t.labelHeight)/2)))}),m.left=Math.max(n.x,m.left),m.right=Math.max(n.x,m.right),m.top=Math.max(n.y,m.top),m.bottom=Math.max(n.y,m.bottom)}function R(){var t,n=k(),r=a.grid.show;for(var i in m){var s=a.grid.margin||0;m[i]=typeof s=="number"?s:s[i]||0}E(b.processOffset,[m]);for(var i in m)typeof a.grid.borderWidth=="object"?m[i]+=r?a.grid.borderWidth[i]:0:m[i]+=r?a.grid.borderWidth:0;e.each(n,function(e,t){t.show=t.options.show,t.show==null&&(t.show=t.used),t.reserveSpace=t.show||t.options.reserveSpace,U(t)});if(r){var o=e.grep(n,function(e){return e.reserveSpace});e.each(o,function(e,t){z(t),W(t),X(t,t.ticks),j(t)});for(t=o.length-1;t>=0;--t)F(o[t]);q(),e.each(o,function(e,t){I(t)})}g=f.width-m.left-m.right,y=f.height-m.bottom-m.top,e.each(n,function(e,t){B(t)}),r&&G(),it()}function U(e){var t=e.options,n=+(t.min!=null?t.min:e.datamin),r=+(t.max!=null?t.max:e.datamax),i=r-n;if(i==0){var s=r==0?1:.01;t.min==null&&(n-=s);if(t.max==null||t.min!=null)r+=s}else{var o=t.autoscaleMargin;o!=null&&(t.min==null&&(n-=i*o,n<0&&e.datamin!=null&&e.datamin>=0&&(n=0)),t.max==null&&(r+=i*o,r>0&&e.datamax!=null&&e.datamax<=0&&(r=0)))}e.min=n,e.max=r}function z(t){var n=t.options,r;typeof n.ticks=="number"&&n.ticks>0?r=n.ticks:r=.3*Math.sqrt(t.direction=="x"?f.width:f.height);var s=(t.max-t.min)/r,o=-Math.floor(Math.log(s)/Math.LN10),u=n.tickDecimals;u!=null&&o>u&&(o=u);var a=Math.pow(10,-o),l=s/a,c;l<1.5?c=1:l<3?(c=2,l>2.25&&(u==null||o+1<=u)&&(c=2.5,++o)):l<7.5?c=5:c=10,c*=a,n.minTickSize!=null&&c<n.minTickSize&&(c=n.minTickSize),t.delta=s,t.tickDecimals=Math.max(0,u!=null?u:o),t.tickSize=n.tickSize||c;if(n.mode=="time"&&!t.tickGenerator)throw new Error("Time mode requires the flot.time plugin.");t.tickGenerator||(t.tickGenerator=function(e){var t=[],n=i(e.min,e.tickSize),r=0,s=Number.NaN,o;do o=s,s=n+r*e.tickSize,t.push(s),++r;while(s<e.max&&s!=o);return t},t.tickFormatter=function(e,t){var n=t.tickDecimals?Math.pow(10,t.tickDecimals):1,r=""+Math.round(e*n)/n;if(t.tickDecimals!=null){var i=r.indexOf("."),s=i==-1?0:r.length-i-1;if(s<t.tickDecimals)return(s?r:r+".")+(""+n).substr(1,t.tickDecimals-s)}return r}),e.isFunction(n.tickFormatter)&&(t.tickFormatter=function(e,t){return""+n.tickFormatter(e,t)});if(n.alignTicksWithAxis!=null){var h=(t.direction=="x"?d:v)[n.alignTicksWithAxis-1];if(h&&h.used&&h!=t){var p=t.tickGenerator(t);p.length>0&&(n.min==null&&(t.min=Math.min(t.min,p[0])),n.max==null&&p.length>1&&(t.max=Math.max(t.max,p[p.length-1]))),t.tickGenerator=function(e){var t=[],n,r;for(r=0;r<h.ticks.length;++r)n=(h.ticks[r].v-h.min)/(h.max-h.min),n=e.min+n*(e.max-e.min),t.push(n);return t};if(!t.mode&&n.tickDecimals==null){var m=Math.max(0,-Math.floor(Math.log(t.delta)/Math.LN10)+1),g=t.tickGenerator(t);g.length>1&&/\..*0$/.test((g[1]-g[0]).toFixed(m))||(t.tickDecimals=m)}}}}function W(t){var n=t.options.ticks,r=[];n==null||typeof n=="number"&&n>0?r=t.tickGenerator(t):n&&(e.isFunction(n)?r=n(t):r=n);var i,s;t.ticks=[];for(i=0;i<r.length;++i){var o=null,u=r[i];typeof u=="object"?(s=+u[0],u.length>1&&(o=u[1])):s=+u,o==null&&(o=t.tickFormatter(s,t)),isNaN(s)||t.ticks.push({v:s,label:o})}}function X(e,t){e.options.autoscaleMargin&&t.length>0&&(e.options.min==null&&(e.min=Math.min(e.min,t[0].v)),e.options.max==null&&t.length>1&&(e.max=Math.max(e.max,t[t.length-1].v)))}function V(){f.clear(),E(b.drawBackground,[h]);var e=a.grid;e.show&&e.backgroundColor&&K(),e.show&&!e.aboveData&&Q();for(var t=0;t<u.length;++t)E(b.drawSeries,[h,u[t]]),Y(u[t]);E(b.draw,[h]),e.show&&e.aboveData&&Q(),f.render(),ht()}function J(e,t){var n,r,i,s,o=k();for(var u=0;u<o.length;++u){n=o[u];if(n.direction==t){s=t+n.n+"axis",!e[s]&&n.n==1&&(s=t+"axis");if(e[s]){r=e[s].from,i=e[s].to;break}}}e[s]||(n=t=="x"?d[0]:v[0],r=e[t+"1"],i=e[t+"2"]);if(r!=null&&i!=null&&r>i){var a=r;r=i,i=a}return{from:r,to:i,axis:n}}function K(){h.save(),h.translate(m.left,m.top),h.fillStyle=bt(a.grid.backgroundColor,y,0,"rgba(255, 255, 255, 0)"),h.fillRect(0,0,g,y),h.restore()}function Q(){var t,n,r,i;h.save(),h.translate(m.left,m.top);var s=a.grid.markings;if(s){e.isFunction(s)&&(n=w.getAxes(),n.xmin=n.xaxis.min,n.xmax=n.xaxis.max,n.ymin=n.yaxis.min,n.ymax=n.yaxis.max,s=s(n));for(t=0;t<s.length;++t){var o=s[t],u=J(o,"x"),f=J(o,"y");u.from==null&&(u.from=u.axis.min),u.to==null&&(u.to=u.axis.max),f.from==null&&(f.from=f.axis.min),f.to==null&&(f.to=f.axis.max);if(u.to<u.axis.min||u.from>u.axis.max||f.to<f.axis.min||f.from>f.axis.max)continue;u.from=Math.max(u.from,u.axis.min),u.to=Math.min(u.to,u.axis.max),f.from=Math.max(f.from,f.axis.min),f.to=Math.min(f.to,f.axis.max);if(u.from==u.to&&f.from==f.to)continue;u.from=u.axis.p2c(u.from),u.to=u.axis.p2c(u.to),f.from=f.axis.p2c(f.from),f.to=f.axis.p2c(f.to),u.from==u.to||f.from==f.to?(h.beginPath(),h.strokeStyle=o.color||a.grid.markingsColor,h.lineWidth=o.lineWidth||a.grid.markingsLineWidth,h.moveTo(u.from,f.from),h.lineTo(u.to,f.to),h.stroke()):(h.fillStyle=o.color||a.grid.markingsColor,h.fillRect(u.from,f.to,u.to-u.from,f.from-f.to))}}n=k(),r=a.grid.borderWidth;for(var l=0;l<n.length;++l){var c=n[l],p=c.box,d=c.tickLength,v,b,E,S;if(!c.show||c.ticks.length==0)continue;h.lineWidth=1,c.direction=="x"?(v=0,d=="full"?b=c.position=="top"?0:y:b=p.top-m.top+(c.position=="top"?p.height:0)):(b=0,d=="full"?v=c.position=="left"?0:g:v=p.left-m.left+(c.position=="left"?p.width:0)),c.innermost||(h.strokeStyle=c.options.color,h.beginPath(),E=S=0,c.direction=="x"?E=g+1:S=y+1,h.lineWidth==1&&(c.direction=="x"?b=Math.floor(b)+.5:v=Math.floor(v)+.5),h.moveTo(v,b),h.lineTo(v+E,b+S),h.stroke()),h.strokeStyle=c.options.tickColor,h.beginPath();for(t=0;t<c.ticks.length;++t){var x=c.ticks[t].v;E=S=0;if(isNaN(x)||x<c.min||x>c.max||d=="full"&&(typeof r=="object"&&r[c.position]>0||r>0)&&(x==c.min||x==c.max))continue;c.direction=="x"?(v=c.p2c(x),S=d=="full"?-y:d,c.position=="top"&&(S=-S)):(b=c.p2c(x),E=d=="full"?-g:d,c.position=="left"&&(E=-E)),h.lineWidth==1&&(c.direction=="x"?v=Math.floor(v)+.5:b=Math.floor(b)+.5),h.moveTo(v,b),h.lineTo(v+E,b+S)}h.stroke()}r&&(i=a.grid.borderColor,typeof r=="object"||typeof i=="object"?(typeof r!="object"&&(r={top:r,right:r,bottom:r,left:r}),typeof i!="object"&&(i={top:i,right:i,bottom:i,left:i}),r.top>0&&(h.strokeStyle=i.top,h.lineWidth=r.top,h.beginPath(),h.moveTo(0-r.left,0-r.top/2),h.lineTo(g,0-r.top/2),h.stroke()),r.right>0&&(h.strokeStyle=i.right,h.lineWidth=r.right,h.beginPath(),h.moveTo(g+r.right/2,0-r.top),h.lineTo(g+r.right/2,y),h.stroke()),r.bottom>0&&(h.strokeStyle=i.bottom,h.lineWidth=r.bottom,h.beginPath(),h.moveTo(g+r.right,y+r.bottom/2),h.lineTo(0,y+r.bottom/2),h.stroke()),r.left>0&&(h.strokeStyle=i.left,h.lineWidth=r.left,h.beginPath(),h.moveTo(0-r.left/2,y+r.bottom),h.lineTo(0-r.left/2,0),h.stroke())):(h.lineWidth=r,h.strokeStyle=a.grid.borderColor,h.strokeRect(-r/2,-r/2,g+r,y+r))),h.restore()}function G(){e.each(k(),function(e,t){if(!t.show||t.ticks.length==0)return;var n=t.box,r=t.direction+"Axis "+t.direction+t.n+"Axis",i="flot-"+t.direction+"-axis flot-"+t.direction+t.n+"-axis "+r,s=t.options.font||"flot-tick-label tickLabel",o,u,a,l,c;f.removeText(i);for(var h=0;h<t.ticks.length;++h){o=t.ticks[h];if(!o.label||o.v<t.min||o.v>t.max)continue;t.direction=="x"?(l="center",u=m.left+t.p2c(o.v),t.position=="bottom"?a=n.top+n.padding:(a=n.top+n.height-n.padding,c="bottom")):(c="middle",a=m.top+t.p2c(o.v),t.position=="left"?(u=n.left+n.width-n.padding,l="right"):u=n.left+n.padding),f.addText(i,u,a,o.label,s,null,null,l,c)}})}function Y(e){e.lines.show&&Z(e),e.bars.show&&nt(e),e.points.show&&et(e)}function Z(e){function t(e,t,n,r,i){var s=e.points,o=e.pointsize,u=null,a=null;h.beginPath();for(var f=o;f<s.length;f+=o){var l=s[f-o],c=s[f-o+1],p=s[f],d=s[f+1];if(l==null||p==null)continue;if(c<=d&&c<i.min){if(d<i.min)continue;l=(i.min-c)/(d-c)*(p-l)+l,c=i.min}else if(d<=c&&d<i.min){if(c<i.min)continue;p=(i.min-c)/(d-c)*(p-l)+l,d=i.min}if(c>=d&&c>i.max){if(d>i.max)continue;l=(i.max-c)/(d-c)*(p-l)+l,c=i.max}else if(d>=c&&d>i.max){if(c>i.max)continue;p=(i.max-c)/(d-c)*(p-l)+l,d=i.max}if(l<=p&&l<r.min){if(p<r.min)continue;c=(r.min-l)/(p-l)*(d-c)+c,l=r.min}else if(p<=l&&p<r.min){if(l<r.min)continue;d=(r.min-l)/(p-l)*(d-c)+c,p=r.min}if(l>=p&&l>r.max){if(p>r.max)continue;c=(r.max-l)/(p-l)*(d-c)+c,l=r.max}else if(p>=l&&p>r.max){if(l>r.max)continue;d=(r.max-l)/(p-l)*(d-c)+c,p=r.max}(l!=u||c!=a)&&h.moveTo(r.p2c(l)+t,i.p2c(c)+n),u=p,a=d,h.lineTo(r.p2c(p)+t,i.p2c(d)+n)}h.stroke()}function n(e,t,n){var r=e.points,i=e.pointsize,s=Math.min(Math.max(0,n.min),n.max),o=0,u,a=!1,f=1,l=0,c=0;for(;;){if(i>0&&o>r.length+i)break;o+=i;var p=r[o-i],d=r[o-i+f],v=r[o],m=r[o+f];if(a){if(i>0&&p!=null&&v==null){c=o,i=-i,f=2;continue}if(i<0&&o==l+i){h.fill(),a=!1,i=-i,f=1,o=l=c+i;continue}}if(p==null||v==null)continue;if(p<=v&&p<t.min){if(v<t.min)continue;d=(t.min-p)/(v-p)*(m-d)+d,p=t.min}else if(v<=p&&v<t.min){if(p<t.min)continue;m=(t.min-p)/(v-p)*(m-d)+d,v=t.min}if(p>=v&&p>t.max){if(v>t.max)continue;d=(t.max-p)/(v-p)*(m-d)+d,p=t.max}else if(v>=p&&v>t.max){if(p>t.max)continue;m=(t.max-p)/(v-p)*(m-d)+d,v=t.max}a||(h.beginPath(),h.moveTo(t.p2c(p),n.p2c(s)),a=!0);if(d>=n.max&&m>=n.max){h.lineTo(t.p2c(p),n.p2c(n.max)),h.lineTo(t.p2c(v),n.p2c(n.max));continue}if(d<=n.min&&m<=n.min){h.lineTo(t.p2c(p),n.p2c(n.min)),h.lineTo(t.p2c(v),n.p2c(n.min));continue}var g=p,y=v;d<=m&&d<n.min&&m>=n.min?(p=(n.min-d)/(m-d)*(v-p)+p,d=n.min):m<=d&&m<n.min&&d>=n.min&&(v=(n.min-d)/(m-d)*(v-p)+p,m=n.min),d>=m&&d>n.max&&m<=n.max?(p=(n.max-d)/(m-d)*(v-p)+p,d=n.max):m>=d&&m>n.max&&d<=n.max&&(v=(n.max-d)/(m-d)*(v-p)+p,m=n.max),p!=g&&h.lineTo(t.p2c(g),n.p2c(d)),h.lineTo(t.p2c(p),n.p2c(d)),h.lineTo(t.p2c(v),n.p2c(m)),v!=y&&(h.lineTo(t.p2c(v),n.p2c(m)),h.lineTo(t.p2c(y),n.p2c(m)))}}h.save(),h.translate(m.left,m.top),h.lineJoin="round";var r=e.lines.lineWidth,i=e.shadowSize;if(r>0&&i>0){h.lineWidth=i,h.strokeStyle="rgba(0,0,0,0.1)";var s=Math.PI/18;t(e.datapoints,Math.sin(s)*(r/2+i/2),Math.cos(s)*(r/2+i/2),e.xaxis,e.yaxis),h.lineWidth=i/2,t(e.datapoints,Math.sin(s)*(r/2+i/4),Math.cos(s)*(r/2+i/4),e.xaxis,e.yaxis)}h.lineWidth=r,h.strokeStyle=e.color;var o=rt(e.lines,e.color,0,y);o&&(h.fillStyle=o,n(e.datapoints,e.xaxis,e.yaxis)),r>0&&t(e.datapoints,0,0,e.xaxis,e.yaxis),h.restore()}function et(e){function t(e,t,n,r,i,s,o,u){var a=e.points,f=e.pointsize;for(var l=0;l<a.length;l+=f){var c=a[l],p=a[l+1];if(c==null||c<s.min||c>s.max||p<o.min||p>o.max)continue;h.beginPath(),c=s.p2c(c),p=o.p2c(p)+r,u=="circle"?h.arc(c,p,t,0,i?Math.PI:Math.PI*2,!1):u(h,c,p,t,i),h.closePath(),n&&(h.fillStyle=n,h.fill()),h.stroke()}}h.save(),h.translate(m.left,m.top);var n=e.points.lineWidth,r=e.shadowSize,i=e.points.radius,s=e.points.symbol;n==0&&(n=1e-4);if(n>0&&r>0){var o=r/2;h.lineWidth=o,h.strokeStyle="rgba(0,0,0,0.1)",t(e.datapoints,i,null,o+o/2,!0,e.xaxis,e.yaxis,s),h.strokeStyle="rgba(0,0,0,0.2)",t(e.datapoints,i,null,o/2,!0,e.xaxis,e.yaxis,s)}h.lineWidth=n,h.strokeStyle=e.color,t(e.datapoints,i,rt(e.points,e.color),0,!1,e.xaxis,e.yaxis,s),h.restore()}function tt(e,t,n,r,i,s,o,u,a,f,l,c){var h,p,d,v,m,g,y,b,w;l?(b=g=y=!0,m=!1,h=n,p=e,v=t+r,d=t+i,p<h&&(w=p,p=h,h=w,m=!0,g=!1)):(m=g=y=!0,b=!1,h=e+r,p=e+i,d=n,v=t,v<d&&(w=v,v=d,d=w,b=!0,y=!1));if(p<u.min||h>u.max||v<a.min||d>a.max)return;h<u.min&&(h=u.min,m=!1),p>u.max&&(p=u.max,g=!1),d<a.min&&(d=a.min,b=!1),v>a.max&&(v=a.max,y=!1),h=u.p2c(h),d=a.p2c(d),p=u.p2c(p),v=a.p2c(v),o&&(f.beginPath(),f.moveTo(h,d),f.lineTo(h,v),f.lineTo(p,v),f.lineTo(p,d),f.fillStyle=o(d,v),f.fill()),c>0&&(m||g||y||b)&&(f.beginPath(),f.moveTo(h,d+s),m?f.lineTo(h,v+s):f.moveTo(h,v+s),y?f.lineTo(p,v+s):f.moveTo(p,v+s),g?f.lineTo(p,d+s):f.moveTo(p,d+s),b?f.lineTo(h,d+s):f.moveTo(h,d+s),f.stroke())}function nt(e){function t(t,n,r,i,s,o,u){var a=t.points,f=t.pointsize;for(var l=0;l<a.length;l+=f){if(a[l]==null)continue;tt(a[l],a[l+1],a[l+2],n,r,i,s,o,u,h,e.bars.horizontal,e.bars.lineWidth)}}h.save(),h.translate(m.left,m.top),h.lineWidth=e.bars.lineWidth,h.strokeStyle=e.color;var n;switch(e.bars.align){case"left":n=0;break;case"right":n=-e.bars.barWidth;break;case"center":n=-e.bars.barWidth/2;break;default:throw new Error("Invalid bar alignment: "+e.bars.align)}var r=e.bars.fill?function(t,n){return rt(e.bars,e.color,t,n)}:null;t(e.datapoints,n,n+e.bars.barWidth,0,r,e.xaxis,e.yaxis),h.restore()}function rt(t,n,r,i){var s=t.fill;if(!s)return null;if(t.fillColor)return bt(t.fillColor,r,i,n);var o=e.color.parse(n);return o.a=typeof s=="number"?s:.4,o.normalize(),o.toString()}function it(){t.find(".legend").remove();if(!a.legend.show)return;var n=[],r=[],i=!1,s=a.legend.labelFormatter,o,f;for(var l=0;l<u.length;++l)o=u[l],o.label&&(f=s?s(o.label,o):o.label,f&&r.push({label:f,color:o.color}));if(a.legend.sorted)if(e.isFunction(a.legend.sorted))r.sort(a.legend.sorted);else if(a.legend.sorted=="reverse")r.reverse();else{var c=a.legend.sorted!="descending";r.sort(function(e,t){return e.label==t.label?0:e.label<t.label!=c?1:-1})}for(var l=0;l<r.length;++l){var h=r[l];l%a.legend.noColumns==0&&(i&&n.push("</tr>"),n.push("<tr>"),i=!0),n.push('<td class="legendColorBox"><div style="border:1px solid '+a.legend.labelBoxBorderColor+';padding:1px"><div style="width:4px;height:0;border:5px solid '+h.color+';overflow:hidden"></div></div></td>'+'<td class="legendLabel">'+h.label+"</td>")}i&&n.push("</tr>");if(n.length==0)return;var p='<table style="font-size:smaller;color:'+a.grid.color+'">'+n.join("")+"</table>";if(a.legend.container!=null)e(a.legend.container).html(p);else{var d="",v=a.legend.position,g=a.legend.margin;g[0]==null&&(g=[g,g]),v.charAt(0)=="n"?d+="top:"+(g[1]+m.top)+"px;":v.charAt(0)=="s"&&(d+="bottom:"+(g[1]+m.bottom)+"px;"),v.charAt(1)=="e"?d+="right:"+(g[0]+m.right)+"px;":v.charAt(1)=="w"&&(d+="left:"+(g[0]+m.left)+"px;");var y=e('<div class="legend">'+p.replace('style="','style="position:absolute;'+d+";")+"</div>").appendTo(t);if(a.legend.backgroundOpacity!=0){var b=a.legend.backgroundColor;b==null&&(b=a.grid.backgroundColor,b&&typeof b=="string"?b=e.color.parse(b):b=e.color.extract(y,"background-color"),b.a=1,b=b.toString());var w=y.children();e('<div style="position:absolute;width:'+w.width()+"px;height:"+w.height()+"px;"+d+"background-color:"+b+';"> </div>').prependTo(y).css("opacity",a.legend.backgroundOpacity)}}}function ut(e,t,n){var r=a.grid.mouseActiveRadius,i=r*r+1,s=null,o=!1,f,l,c;for(f=u.length-1;f>=0;--f){if(!n(u[f]))continue;var h=u[f],p=h.xaxis,d=h.yaxis,v=h.datapoints.points,m=p.c2p(e),g=d.c2p(t),y=r/p.scale,b=r/d.scale;c=h.datapoints.pointsize,p.options.inverseTransform&&(y=Number.MAX_VALUE),d.options.inverseTransform&&(b=Number.MAX_VALUE);if(h.lines.show||h.points.show)for(l=0;l<v.length;l+=c){var w=v[l],E=v[l+1];if(w==null)continue;if(w-m>y||w-m<-y||E-g>b||E-g<-b)continue;var S=Math.abs(p.p2c(w)-e),x=Math.abs(d.p2c(E)-t),T=S*S+x*x;T<i&&(i=T,s=[f,l/c])}if(h.bars.show&&!s){var N=h.bars.align=="left"?0:-h.bars.barWidth/2,C=N+h.bars.barWidth;for(l=0;l<v.length;l+=c){var w=v[l],E=v[l+1],k=v[l+2];if(w==null)continue;if(u[f].bars.horizontal?m<=Math.max(k,w)&&m>=Math.min(k,w)&&g>=E+N&&g<=E+C:m>=w+N&&m<=w+C&&g>=Math.min(k,E)&&g<=Math.max(k,E))s=[f,l/c]}}}return s?(f=s[0],l=s[1],c=u[f].datapoints.pointsize,{datapoint:u[f].datapoints.points.slice(l*c,(l+1)*c),dataIndex:l,series:u[f],seriesIndex:f}):null}function at(e){a.grid.hoverable&&ct("plothover",e,function(e){return e["hoverable"]!=0})}function ft(e){a.grid.hoverable&&ct("plothover",e,function(e){return!1})}function lt(e){ct("plotclick",e,function(e){return e["clickable"]!=0})}function ct(e,n,r){var i=c.offset(),s=n.pageX-i.left-m.left,o=n.pageY-i.top-m.top,u=L({left:s,top:o});u.pageX=n.pageX,u.pageY=n.pageY;var f=ut(s,o,r);f&&(f.pageX=parseInt(f.series.xaxis.p2c(f.datapoint[0])+i.left+m.left,10),f.pageY=parseInt(f.series.yaxis.p2c(f.datapoint[1])+i.top+m.top,10));if(a.grid.autoHighlight){for(var l=0;l<st.length;++l){var h=st[l];h.auto==e&&(!f||h.series!=f.series||h.point[0]!=f.datapoint[0]||h.point[1]!=f.datapoint[1])&&vt(h.series,h.point)}f&&dt(f.series,f.datapoint,e)}t.trigger(e,[u,f])}function ht(){var e=a.interaction.redrawOverlayInterval;if(e==-1){pt();return}ot||(ot=setTimeout(pt,e))}function pt(){ot=null,p.save(),l.clear(),p.translate(m.left,m.top);var e,t;for(e=0;e<st.length;++e)t=st[e],t.series.bars.show?yt(t.series,t.point):gt(t.series,t.point);p.restore(),E(b.drawOverlay,[p])}function dt(e,t,n){typeof e=="number"&&(e=u[e]);if(typeof t=="number"){var r=e.datapoints.pointsize;t=e.datapoints.points.slice(r*t,r*(t+1))}var i=mt(e,t);i==-1?(st.push({series:e,point:t,auto:n}),ht()):n||(st[i].auto=!1)}function vt(e,t){if(e==null&&t==null){st=[],ht();return}typeof e=="number"&&(e=u[e]);if(typeof t=="number"){var n=e.datapoints.pointsize;t=e.datapoints.points.slice(n*t,n*(t+1))}var r=mt(e,t);r!=-1&&(st.splice(r,1),ht())}function mt(e,t){for(var n=0;n<st.length;++n){var r=st[n];if(r.series==e&&r.point[0]==t[0]&&r.point[1]==t[1])return n}return-1}function gt(t,n){var r=n[0],i=n[1],s=t.xaxis,o=t.yaxis,u=typeof t.highlightColor=="string"?t.highlightColor:e.color.parse(t.color).scale("a",.5).toString();if(r<s.min||r>s.max||i<o.min||i>o.max)return;var a=t.points.radius+t.points.lineWidth/2;p.lineWidth=a,p.strokeStyle=u;var f=1.5*a;r=s.p2c(r),i=o.p2c(i),p.beginPath(),t.points.symbol=="circle"?p.arc(r,i,f,0,2*Math.PI,!1):t.points.symbol(p,r,i,f,!1),p.closePath(),p.stroke()}function yt(t,n){var r=typeof t.highlightColor=="string"?t.highlightColor:e.color.parse(t.color).scale("a",.5).toString(),i=r,s=t.bars.align=="left"?0:-t.bars.barWidth/2;p.lineWidth=t.bars.lineWidth,p.strokeStyle=r,tt(n[0],n[1],n[2]||0,s,s+t.bars.barWidth,0,function(){return i},t.xaxis,t.yaxis,p,t.bars.horizontal,t.bars.lineWidth)}function bt(t,n,r,i){if(typeof t=="string")return t;var s=h.createLinearGradient(0,r,0,n);for(var o=0,u=t.colors.length;o<u;++o){var a=t.colors[o];if(typeof a!="string"){var f=e.color.parse(i);a.brightness!=null&&(f=f.scale("rgb",a.brightness)),a.opacity!=null&&(f.a*=a.opacity),a=f.toString()}s.addColorStop(o/(u-1),a)}return s}var u=[],a={colors:["#edc240","#afd8f8","#cb4b4b","#4da74d","#9440ed"],legend:{show:!0,noColumns:1,labelFormatter:null,labelBoxBorderColor:"#ccc",container:null,position:"ne",margin:5,backgroundColor:null,backgroundOpacity:.85,sorted:null},xaxis:{show:null,position:"bottom",mode:null,font:null,color:null,tickColor:null,transform:null,inverseTransform:null,min:null,max:null,autoscaleMargin:null,ticks:null,tickFormatter:null,labelWidth:null,labelHeight:null,reserveSpace:null,tickLength:null,alignTicksWithAxis:null,tickDecimals:null,tickSize:null,minTickSize:null},yaxis:{autoscaleMargin:.02,position:"left"},xaxes:[],yaxes:[],series:{points:{show:!1,radius:3,lineWidth:2,fill:!0,fillColor:"#ffffff",symbol:"circle"},lines:{lineWidth:2,fill:!1,fillColor:null,steps:!1},bars:{show:!1,lineWidth:2,barWidth:1,fill:!0,fillColor:null,align:"left",horizontal:!1,zero:!0},shadowSize:3,highlightColor:null},grid:{show:!0,aboveData:!1,color:"#545454",backgroundColor:null,borderColor:null,tickColor:null,margin:0,labelMargin:5,axisMargin:8,borderWidth:2,minBorderMargin:null,markings:null,markingsColor:"#f4f4f4",markingsLineWidth:2,clickable:!1,hoverable:!1,autoHighlight:!0,mouseActiveRadius:10},interaction:{redrawOverlayInterval:1e3/60},hooks:{}},f=null,l=null,c=null,h=null,p=null,d=[],v=[],m={left:0,right:0,top:0,bottom
-:0},g=0,y=0,b={processOptions:[],processRawData:[],processDatapoints:[],processOffset:[],drawBackground:[],drawSeries:[],draw:[],bindEvents:[],drawOverlay:[],shutdown:[]},w=this;w.setData=T,w.setupGrid=R,w.draw=V,w.getPlaceholder=function(){return t},w.getCanvas=function(){return f.element},w.getPlotOffset=function(){return m},w.width=function(){return g},w.height=function(){return y},w.offset=function(){var e=c.offset();return e.left+=m.left,e.top+=m.top,e},w.getData=function(){return u},w.getAxes=function(){var t={},n;return e.each(d.concat(v),function(e,n){n&&(t[n.direction+(n.n!=1?n.n:"")+"axis"]=n)}),t},w.getXAxes=function(){return d},w.getYAxes=function(){return v},w.c2p=L,w.p2c=A,w.getOptions=function(){return a},w.highlight=dt,w.unhighlight=vt,w.triggerRedrawOverlay=ht,w.pointOffset=function(e){return{left:parseInt(d[C(e,"x")-1].p2c(+e.x)+m.left,10),top:parseInt(v[C(e,"y")-1].p2c(+e.y)+m.top,10)}},w.shutdown=H,w.resize=function(){var e=t.width(),n=t.height();f.resize(e,n),l.resize(e,n)},w.hooks=b,S(w),x(s),D(),T(r),R(),V(),P();var st=[],ot=null}function i(e,t){return t*Math.floor(e/t)}var t=Object.prototype.hasOwnProperty;n.prototype.resize=function(e,t){if(e<=0||t<=0)throw new Error("Invalid dimensions for plot, width = "+e+", height = "+t);var n=this.element,r=this.context,i=this.pixelRatio;this.width!=e&&(n.width=e*i,n.style.width=e+"px",this.width=e),this.height!=t&&(n.height=t*i,n.style.height=t+"px",this.height=t),r.restore(),r.save(),r.scale(i,i)},n.prototype.clear=function(){this.context.clearRect(0,0,this.width,this.height)},n.prototype.render=function(){var e=this._textCache;for(var n in e)if(t.call(e,n)){var r=this.getTextLayer(n),i=e[n];r.hide();for(var s in i)if(t.call(i,s)){var o=i[s];for(var u in o)if(t.call(o,u)){var a=o[u].positions;for(var f=0,l;l=a[f];f++)l.active?l.rendered||(r.append(l.element),l.rendered=!0):(a.splice(f--,1),l.rendered&&l.element.detach());a.length==0&&delete o[u]}}r.show()}},n.prototype.getTextLayer=function(t){var n=this.text[t];return n==null&&(this.textContainer==null&&(this.textContainer=e("<div class='flot-text'></div>").css({position:"absolute",top:0,left:0,bottom:0,right:0,"font-size":"smaller",color:"#545454"}).insertAfter(this.element)),n=this.text[t]=e("<div></div>").addClass(t).css({position:"absolute",top:0,left:0,bottom:0,right:0}).appendTo(this.textContainer)),n},n.prototype.getTextInfo=function(t,n,r,i,s){var o,u,a,f;n=""+n,typeof r=="object"?o=r.style+" "+r.variant+" "+r.weight+" "+r.size+"px/"+r.lineHeight+"px "+r.family:o=r,u=this._textCache[t],u==null&&(u=this._textCache[t]={}),a=u[o],a==null&&(a=u[o]={}),f=a[n];if(f==null){var l=e("<div></div>").html(n).css({position:"absolute","max-width":s,top:-9999}).appendTo(this.getTextLayer(t));typeof r=="object"?l.css({font:o,color:r.color}):typeof r=="string"&&l.addClass(r),f=a[n]={width:l.outerWidth(!0),height:l.outerHeight(!0),element:l,positions:[]},l.detach()}return f},n.prototype.addText=function(e,t,n,r,i,s,o,u,a){var f=this.getTextInfo(e,r,i,s,o),l=f.positions;u=="center"?t-=f.width/2:u=="right"&&(t-=f.width),a=="middle"?n-=f.height/2:a=="bottom"&&(n-=f.height);for(var c=0,h;h=l[c];c++)if(h.x==t&&h.y==n){h.active=!0;return}h={active:!0,rendered:!1,element:l.length?f.element.clone():f.element,x:t,y:n},l.push(h),h.element.css({top:Math.round(n),left:Math.round(t),"text-align":u})},n.prototype.removeText=function(e,n,r,i,s,o){if(i==null){var u=this._textCache[e];if(u!=null)for(var a in u)if(t.call(u,a)){var f=u[a];for(var l in f)if(t.call(f,l)){var c=f[l].positions;for(var h=0,p;p=c[h];h++)p.active=!1}}}else{var c=this.getTextInfo(e,i,s,o).positions;for(var h=0,p;p=c[h];h++)p.x==n&&p.y==r&&(p.active=!1)}},e.plot=function(t,n,i){var s=new r(e(t),n,i,e.plot.plugins);return s},e.plot.version="0.8.1",e.plot.plugins=[],e.fn.plot=function(t,n){return this.each(function(){e.plot(this,t,n)})}}(jQuery);
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/mock/LICENSE.txt b/catapult/telemetry/third_party/mock/LICENSE.txt
deleted file mode 100644
index 7891703..0000000
--- a/catapult/telemetry/third_party/mock/LICENSE.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-Copyright (c) 2003-2012, Michael Foord
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials provided
-      with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/catapult/telemetry/third_party/mock/README.chromium b/catapult/telemetry/third_party/mock/README.chromium
deleted file mode 100644
index 2dc689b..0000000
--- a/catapult/telemetry/third_party/mock/README.chromium
+++ /dev/null
@@ -1,16 +0,0 @@
-Name: mock
-Short Name: mock
-URL: http://www.voidspace.org.uk/python/mock/
-Version: 1.0.1
-License: BSD
-License File: NOT_SHIPPED
-Security Critical: no
-
-Description:
-Library for mocks in Python tests.
-
-Local Modifications:
-Includes only mock.py and LICENSE.txt.
-Packaging and setup files have not been copied downstream.
-All other files and folders (docs/, html/, tests/)
-have not been copied downstream.
diff --git a/catapult/telemetry/third_party/mock/mock.py b/catapult/telemetry/third_party/mock/mock.py
deleted file mode 100644
index c8fc5d1..0000000
--- a/catapult/telemetry/third_party/mock/mock.py
+++ /dev/null
@@ -1,2367 +0,0 @@
-# mock.py
-# Test tools for mocking and patching.
-# Copyright (C) 2007-2012 Michael Foord & the mock team
-# E-mail: fuzzyman AT voidspace DOT org DOT uk
-
-# mock 1.0
-# http://www.voidspace.org.uk/python/mock/
-
-# Released subject to the BSD License
-# Please see http://www.voidspace.org.uk/python/license.shtml
-
-# Scripts maintained at http://www.voidspace.org.uk/python/index.shtml
-# Comments, suggestions and bug reports welcome.
-
-
-__all__ = (
-    'Mock',
-    'MagicMock',
-    'patch',
-    'sentinel',
-    'DEFAULT',
-    'ANY',
-    'call',
-    'create_autospec',
-    'FILTER_DIR',
-    'NonCallableMock',
-    'NonCallableMagicMock',
-    'mock_open',
-    'PropertyMock',
-)
-
-
-__version__ = '1.0.1'
-
-
-import pprint
-import sys
-
-try:
-    import inspect
-except ImportError:
-    # for alternative platforms that
-    # may not have inspect
-    inspect = None
-
-try:
-    from functools import wraps as original_wraps
-except ImportError:
-    # Python 2.4 compatibility
-    def wraps(original):
-        def inner(f):
-            f.__name__ = original.__name__
-            f.__doc__ = original.__doc__
-            f.__module__ = original.__module__
-            f.__wrapped__ = original
-            return f
-        return inner
-else:
-    if sys.version_info[:2] >= (3, 3):
-        wraps = original_wraps
-    else:
-        def wraps(func):
-            def inner(f):
-                f = original_wraps(func)(f)
-                f.__wrapped__ = func
-                return f
-            return inner
-
-try:
-    unicode
-except NameError:
-    # Python 3
-    basestring = unicode = str
-
-try:
-    long
-except NameError:
-    # Python 3
-    long = int
-
-try:
-    BaseException
-except NameError:
-    # Python 2.4 compatibility
-    BaseException = Exception
-
-try:
-    next
-except NameError:
-    def next(obj):
-        return obj.next()
-
-
-BaseExceptions = (BaseException,)
-if 'java' in sys.platform:
-    # jython
-    import java
-    BaseExceptions = (BaseException, java.lang.Throwable)
-
-try:
-    _isidentifier = str.isidentifier
-except AttributeError:
-    # Python 2.X
-    import keyword
-    import re
-    regex = re.compile(r'^[a-z_][a-z0-9_]*$', re.I)
-    def _isidentifier(string):
-        if string in keyword.kwlist:
-            return False
-        return regex.match(string)
-
-
-inPy3k = sys.version_info[0] == 3
-
-# Needed to work around Python 3 bug where use of "super" interferes with
-# defining __class__ as a descriptor
-_super = super
-
-self = 'im_self'
-builtin = '__builtin__'
-if inPy3k:
-    self = '__self__'
-    builtin = 'builtins'
-
-FILTER_DIR = True
-
-
-def _is_instance_mock(obj):
-    # can't use isinstance on Mock objects because they override __class__
-    # The base class for all mocks is NonCallableMock
-    return issubclass(type(obj), NonCallableMock)
-
-
-def _is_exception(obj):
-    return (
-        isinstance(obj, BaseExceptions) or
-        isinstance(obj, ClassTypes) and issubclass(obj, BaseExceptions)
-    )
-
-
-class _slotted(object):
-    __slots__ = ['a']
-
-
-DescriptorTypes = (
-    type(_slotted.a),
-    property,
-)
-
-
-def _getsignature(func, skipfirst, instance=False):
-    if inspect is None:
-        raise ImportError('inspect module not available')
-
-    if isinstance(func, ClassTypes) and not instance:
-        try:
-            func = func.__init__
-        except AttributeError:
-            return
-        skipfirst = True
-    elif not isinstance(func, FunctionTypes):
-        # for classes where instance is True we end up here too
-        try:
-            func = func.__call__
-        except AttributeError:
-            return
-
-    if inPy3k:
-        try:
-            argspec = inspect.getfullargspec(func)
-        except TypeError:
-            # C function / method, possibly inherited object().__init__
-            return
-        regargs, varargs, varkw, defaults, kwonly, kwonlydef, ann = argspec
-    else:
-        try:
-            regargs, varargs, varkwargs, defaults = inspect.getargspec(func)
-        except TypeError:
-            # C function / method, possibly inherited object().__init__
-            return
-
-    # instance methods and classmethods need to lose the self argument
-    if getattr(func, self, None) is not None:
-        regargs = regargs[1:]
-    if skipfirst:
-        # this condition and the above one are never both True - why?
-        regargs = regargs[1:]
-
-    if inPy3k:
-        signature = inspect.formatargspec(
-            regargs, varargs, varkw, defaults,
-            kwonly, kwonlydef, ann, formatvalue=lambda value: "")
-    else:
-        signature = inspect.formatargspec(
-            regargs, varargs, varkwargs, defaults,
-            formatvalue=lambda value: "")
-    return signature[1:-1], func
-
-
-def _check_signature(func, mock, skipfirst, instance=False):
-    if not _callable(func):
-        return
-
-    result = _getsignature(func, skipfirst, instance)
-    if result is None:
-        return
-    signature, func = result
-
-    # can't use self because "self" is common as an argument name
-    # unfortunately even not in the first place
-    src = "lambda _mock_self, %s: None" % signature
-    checksig = eval(src, {})
-    _copy_func_details(func, checksig)
-    type(mock)._mock_check_sig = checksig
-
-
-def _copy_func_details(func, funcopy):
-    funcopy.__name__ = func.__name__
-    funcopy.__doc__ = func.__doc__
-    #funcopy.__dict__.update(func.__dict__)
-    funcopy.__module__ = func.__module__
-    if not inPy3k:
-        funcopy.func_defaults = func.func_defaults
-        return
-    funcopy.__defaults__ = func.__defaults__
-    funcopy.__kwdefaults__ = func.__kwdefaults__
-
-
-def _callable(obj):
-    if isinstance(obj, ClassTypes):
-        return True
-    if getattr(obj, '__call__', None) is not None:
-        return True
-    return False
-
-
-def _is_list(obj):
-    # checks for list or tuples
-    # XXXX badly named!
-    return type(obj) in (list, tuple)
-
-
-def _instance_callable(obj):
-    """Given an object, return True if the object is callable.
-    For classes, return True if instances would be callable."""
-    if not isinstance(obj, ClassTypes):
-        # already an instance
-        return getattr(obj, '__call__', None) is not None
-
-    klass = obj
-    # uses __bases__ instead of __mro__ so that we work with old style classes
-    if klass.__dict__.get('__call__') is not None:
-        return True
-
-    for base in klass.__bases__:
-        if _instance_callable(base):
-            return True
-    return False
-
-
-def _set_signature(mock, original, instance=False):
-    # creates a function with signature (*args, **kwargs) that delegates to a
-    # mock. It still does signature checking by calling a lambda with the same
-    # signature as the original.
-    if not _callable(original):
-        return
-
-    skipfirst = isinstance(original, ClassTypes)
-    result = _getsignature(original, skipfirst, instance)
-    if result is None:
-        # was a C function (e.g. object().__init__ ) that can't be mocked
-        return
-
-    signature, func = result
-
-    src = "lambda %s: None" % signature
-    checksig = eval(src, {})
-    _copy_func_details(func, checksig)
-
-    name = original.__name__
-    if not _isidentifier(name):
-        name = 'funcopy'
-    context = {'_checksig_': checksig, 'mock': mock}
-    src = """def %s(*args, **kwargs):
-    _checksig_(*args, **kwargs)
-    return mock(*args, **kwargs)""" % name
-    exec (src, context)
-    funcopy = context[name]
-    _setup_func(funcopy, mock)
-    return funcopy
-
-
-def _setup_func(funcopy, mock):
-    funcopy.mock = mock
-
-    # can't use isinstance with mocks
-    if not _is_instance_mock(mock):
-        return
-
-    def assert_called_with(*args, **kwargs):
-        return mock.assert_called_with(*args, **kwargs)
-    def assert_called_once_with(*args, **kwargs):
-        return mock.assert_called_once_with(*args, **kwargs)
-    def assert_has_calls(*args, **kwargs):
-        return mock.assert_has_calls(*args, **kwargs)
-    def assert_any_call(*args, **kwargs):
-        return mock.assert_any_call(*args, **kwargs)
-    def reset_mock():
-        funcopy.method_calls = _CallList()
-        funcopy.mock_calls = _CallList()
-        mock.reset_mock()
-        ret = funcopy.return_value
-        if _is_instance_mock(ret) and not ret is mock:
-            ret.reset_mock()
-
-    funcopy.called = False
-    funcopy.call_count = 0
-    funcopy.call_args = None
-    funcopy.call_args_list = _CallList()
-    funcopy.method_calls = _CallList()
-    funcopy.mock_calls = _CallList()
-
-    funcopy.return_value = mock.return_value
-    funcopy.side_effect = mock.side_effect
-    funcopy._mock_children = mock._mock_children
-
-    funcopy.assert_called_with = assert_called_with
-    funcopy.assert_called_once_with = assert_called_once_with
-    funcopy.assert_has_calls = assert_has_calls
-    funcopy.assert_any_call = assert_any_call
-    funcopy.reset_mock = reset_mock
-
-    mock._mock_delegate = funcopy
-
-
-def _is_magic(name):
-    return '__%s__' % name[2:-2] == name
-
-
-class _SentinelObject(object):
-    "A unique, named, sentinel object."
-    def __init__(self, name):
-        self.name = name
-
-    def __repr__(self):
-        return 'sentinel.%s' % self.name
-
-
-class _Sentinel(object):
-    """Access attributes to return a named object, usable as a sentinel."""
-    def __init__(self):
-        self._sentinels = {}
-
-    def __getattr__(self, name):
-        if name == '__bases__':
-            # Without this help(mock) raises an exception
-            raise AttributeError
-        return self._sentinels.setdefault(name, _SentinelObject(name))
-
-
-sentinel = _Sentinel()
-
-DEFAULT = sentinel.DEFAULT
-_missing = sentinel.MISSING
-_deleted = sentinel.DELETED
-
-
-class OldStyleClass:
-    pass
-ClassType = type(OldStyleClass)
-
-
-def _copy(value):
-    if type(value) in (dict, list, tuple, set):
-        return type(value)(value)
-    return value
-
-
-ClassTypes = (type,)
-if not inPy3k:
-    ClassTypes = (type, ClassType)
-
-_allowed_names = set(
-    [
-        'return_value', '_mock_return_value', 'side_effect',
-        '_mock_side_effect', '_mock_parent', '_mock_new_parent',
-        '_mock_name', '_mock_new_name'
-    ]
-)
-
-
-def _delegating_property(name):
-    _allowed_names.add(name)
-    _the_name = '_mock_' + name
-    def _get(self, name=name, _the_name=_the_name):
-        sig = self._mock_delegate
-        if sig is None:
-            return getattr(self, _the_name)
-        return getattr(sig, name)
-    def _set(self, value, name=name, _the_name=_the_name):
-        sig = self._mock_delegate
-        if sig is None:
-            self.__dict__[_the_name] = value
-        else:
-            setattr(sig, name, value)
-
-    return property(_get, _set)
-
-
-
-class _CallList(list):
-
-    def __contains__(self, value):
-        if not isinstance(value, list):
-            return list.__contains__(self, value)
-        len_value = len(value)
-        len_self = len(self)
-        if len_value > len_self:
-            return False
-
-        for i in range(0, len_self - len_value + 1):
-            sub_list = self[i:i+len_value]
-            if sub_list == value:
-                return True
-        return False
-
-    def __repr__(self):
-        return pprint.pformat(list(self))
-
-
-def _check_and_set_parent(parent, value, name, new_name):
-    if not _is_instance_mock(value):
-        return False
-    if ((value._mock_name or value._mock_new_name) or
-        (value._mock_parent is not None) or
-        (value._mock_new_parent is not None)):
-        return False
-
-    _parent = parent
-    while _parent is not None:
-        # setting a mock (value) as a child or return value of itself
-        # should not modify the mock
-        if _parent is value:
-            return False
-        _parent = _parent._mock_new_parent
-
-    if new_name:
-        value._mock_new_parent = parent
-        value._mock_new_name = new_name
-    if name:
-        value._mock_parent = parent
-        value._mock_name = name
-    return True
-
-
-
-class Base(object):
-    _mock_return_value = DEFAULT
-    _mock_side_effect = None
-    def __init__(self, *args, **kwargs):
-        pass
-
-
-
-class NonCallableMock(Base):
-    """A non-callable version of `Mock`"""
-
-    def __new__(cls, *args, **kw):
-        # every instance has its own class
-        # so we can create magic methods on the
-        # class without stomping on other mocks
-        new = type(cls.__name__, (cls,), {'__doc__': cls.__doc__})
-        instance = object.__new__(new)
-        return instance
-
-
-    def __init__(
-            self, spec=None, wraps=None, name=None, spec_set=None,
-            parent=None, _spec_state=None, _new_name='', _new_parent=None,
-            **kwargs
-        ):
-        if _new_parent is None:
-            _new_parent = parent
-
-        __dict__ = self.__dict__
-        __dict__['_mock_parent'] = parent
-        __dict__['_mock_name'] = name
-        __dict__['_mock_new_name'] = _new_name
-        __dict__['_mock_new_parent'] = _new_parent
-
-        if spec_set is not None:
-            spec = spec_set
-            spec_set = True
-
-        self._mock_add_spec(spec, spec_set)
-
-        __dict__['_mock_children'] = {}
-        __dict__['_mock_wraps'] = wraps
-        __dict__['_mock_delegate'] = None
-
-        __dict__['_mock_called'] = False
-        __dict__['_mock_call_args'] = None
-        __dict__['_mock_call_count'] = 0
-        __dict__['_mock_call_args_list'] = _CallList()
-        __dict__['_mock_mock_calls'] = _CallList()
-
-        __dict__['method_calls'] = _CallList()
-
-        if kwargs:
-            self.configure_mock(**kwargs)
-
-        _super(NonCallableMock, self).__init__(
-            spec, wraps, name, spec_set, parent,
-            _spec_state
-        )
-
-
-    def attach_mock(self, mock, attribute):
-        """
-        Attach a mock as an attribute of this one, replacing its name and
-        parent. Calls to the attached mock will be recorded in the
-        `method_calls` and `mock_calls` attributes of this one."""
-        mock._mock_parent = None
-        mock._mock_new_parent = None
-        mock._mock_name = ''
-        mock._mock_new_name = None
-
-        setattr(self, attribute, mock)
-
-
-    def mock_add_spec(self, spec, spec_set=False):
-        """Add a spec to a mock. `spec` can either be an object or a
-        list of strings. Only attributes on the `spec` can be fetched as
-        attributes from the mock.
-
-        If `spec_set` is True then only attributes on the spec can be set."""
-        self._mock_add_spec(spec, spec_set)
-
-
-    def _mock_add_spec(self, spec, spec_set):
-        _spec_class = None
-
-        if spec is not None and not _is_list(spec):
-            if isinstance(spec, ClassTypes):
-                _spec_class = spec
-            else:
-                _spec_class = _get_class(spec)
-
-            spec = dir(spec)
-
-        __dict__ = self.__dict__
-        __dict__['_spec_class'] = _spec_class
-        __dict__['_spec_set'] = spec_set
-        __dict__['_mock_methods'] = spec
-
-
-    def __get_return_value(self):
-        ret = self._mock_return_value
-        if self._mock_delegate is not None:
-            ret = self._mock_delegate.return_value
-
-        if ret is DEFAULT:
-            ret = self._get_child_mock(
-                _new_parent=self, _new_name='()'
-            )
-            self.return_value = ret
-        return ret
-
-
-    def __set_return_value(self, value):
-        if self._mock_delegate is not None:
-            self._mock_delegate.return_value = value
-        else:
-            self._mock_return_value = value
-            _check_and_set_parent(self, value, None, '()')
-
-    __return_value_doc = "The value to be returned when the mock is called."
-    return_value = property(__get_return_value, __set_return_value,
-                            __return_value_doc)
-
-
-    @property
-    def __class__(self):
-        if self._spec_class is None:
-            return type(self)
-        return self._spec_class
-
-    called = _delegating_property('called')
-    call_count = _delegating_property('call_count')
-    call_args = _delegating_property('call_args')
-    call_args_list = _delegating_property('call_args_list')
-    mock_calls = _delegating_property('mock_calls')
-
-
-    def __get_side_effect(self):
-        sig = self._mock_delegate
-        if sig is None:
-            return self._mock_side_effect
-        return sig.side_effect
-
-    def __set_side_effect(self, value):
-        value = _try_iter(value)
-        sig = self._mock_delegate
-        if sig is None:
-            self._mock_side_effect = value
-        else:
-            sig.side_effect = value
-
-    side_effect = property(__get_side_effect, __set_side_effect)
-
-
-    def reset_mock(self):
-        "Restore the mock object to its initial state."
-        self.called = False
-        self.call_args = None
-        self.call_count = 0
-        self.mock_calls = _CallList()
-        self.call_args_list = _CallList()
-        self.method_calls = _CallList()
-
-        for child in self._mock_children.values():
-            if isinstance(child, _SpecState):
-                continue
-            child.reset_mock()
-
-        ret = self._mock_return_value
-        if _is_instance_mock(ret) and ret is not self:
-            ret.reset_mock()
-
-
-    def configure_mock(self, **kwargs):
-        """Set attributes on the mock through keyword arguments.
-
-        Attributes plus return values and side effects can be set on child
-        mocks using standard dot notation and unpacking a dictionary in the
-        method call:
-
-        >>> attrs = {'method.return_value': 3, 'other.side_effect': KeyError}
-        >>> mock.configure_mock(**attrs)"""
-        for arg, val in sorted(kwargs.items(),
-                               # we sort on the number of dots so that
-                               # attributes are set before we set attributes on
-                               # attributes
-                               key=lambda entry: entry[0].count('.')):
-            args = arg.split('.')
-            final = args.pop()
-            obj = self
-            for entry in args:
-                obj = getattr(obj, entry)
-            setattr(obj, final, val)
-
-
-    def __getattr__(self, name):
-        if name == '_mock_methods':
-            raise AttributeError(name)
-        elif self._mock_methods is not None:
-            if name not in self._mock_methods or name in _all_magics:
-                raise AttributeError("Mock object has no attribute %r" % name)
-        elif _is_magic(name):
-            raise AttributeError(name)
-
-        result = self._mock_children.get(name)
-        if result is _deleted:
-            raise AttributeError(name)
-        elif result is None:
-            wraps = None
-            if self._mock_wraps is not None:
-                # XXXX should we get the attribute without triggering code
-                # execution?
-                wraps = getattr(self._mock_wraps, name)
-
-            result = self._get_child_mock(
-                parent=self, name=name, wraps=wraps, _new_name=name,
-                _new_parent=self
-            )
-            self._mock_children[name]  = result
-
-        elif isinstance(result, _SpecState):
-            result = create_autospec(
-                result.spec, result.spec_set, result.instance,
-                result.parent, result.name
-            )
-            self._mock_children[name]  = result
-
-        return result
-
-
-    def __repr__(self):
-        _name_list = [self._mock_new_name]
-        _parent = self._mock_new_parent
-        last = self
-
-        dot = '.'
-        if _name_list == ['()']:
-            dot = ''
-        seen = set()
-        while _parent is not None:
-            last = _parent
-
-            _name_list.append(_parent._mock_new_name + dot)
-            dot = '.'
-            if _parent._mock_new_name == '()':
-                dot = ''
-
-            _parent = _parent._mock_new_parent
-
-            # use ids here so as not to call __hash__ on the mocks
-            if id(_parent) in seen:
-                break
-            seen.add(id(_parent))
-
-        _name_list = list(reversed(_name_list))
-        _first = last._mock_name or 'mock'
-        if len(_name_list) > 1:
-            if _name_list[1] not in ('()', '().'):
-                _first += '.'
-        _name_list[0] = _first
-        name = ''.join(_name_list)
-
-        name_string = ''
-        if name not in ('mock', 'mock.'):
-            name_string = ' name=%r' % name
-
-        spec_string = ''
-        if self._spec_class is not None:
-            spec_string = ' spec=%r'
-            if self._spec_set:
-                spec_string = ' spec_set=%r'
-            spec_string = spec_string % self._spec_class.__name__
-        return "<%s%s%s id='%s'>" % (
-            type(self).__name__,
-            name_string,
-            spec_string,
-            id(self)
-        )
-
-
-    def __dir__(self):
-        """Filter the output of `dir(mock)` to only useful members.
-        XXXX
-        """
-        extras = self._mock_methods or []
-        from_type = dir(type(self))
-        from_dict = list(self.__dict__)
-
-        if FILTER_DIR:
-            from_type = [e for e in from_type if not e.startswith('_')]
-            from_dict = [e for e in from_dict if not e.startswith('_') or
-                         _is_magic(e)]
-        return sorted(set(extras + from_type + from_dict +
-                          list(self._mock_children)))
-
-
-    def __setattr__(self, name, value):
-        if name in _allowed_names:
-            # property setters go through here
-            return object.__setattr__(self, name, value)
-        elif (self._spec_set and self._mock_methods is not None and
-            name not in self._mock_methods and
-            name not in self.__dict__):
-            raise AttributeError("Mock object has no attribute '%s'" % name)
-        elif name in _unsupported_magics:
-            msg = 'Attempting to set unsupported magic method %r.' % name
-            raise AttributeError(msg)
-        elif name in _all_magics:
-            if self._mock_methods is not None and name not in self._mock_methods:
-                raise AttributeError("Mock object has no attribute '%s'" % name)
-
-            if not _is_instance_mock(value):
-                setattr(type(self), name, _get_method(name, value))
-                original = value
-                value = lambda *args, **kw: original(self, *args, **kw)
-            else:
-                # only set _new_name and not name so that mock_calls is tracked
-                # but not method calls
-                _check_and_set_parent(self, value, None, name)
-                setattr(type(self), name, value)
-                self._mock_children[name] = value
-        elif name == '__class__':
-            self._spec_class = value
-            return
-        else:
-            if _check_and_set_parent(self, value, name, name):
-                self._mock_children[name] = value
-        return object.__setattr__(self, name, value)
-
-
-    def __delattr__(self, name):
-        if name in _all_magics and name in type(self).__dict__:
-            delattr(type(self), name)
-            if name not in self.__dict__:
-                # for magic methods that are still MagicProxy objects and
-                # not set on the instance itself
-                return
-
-        if name in self.__dict__:
-            object.__delattr__(self, name)
-
-        obj = self._mock_children.get(name, _missing)
-        if obj is _deleted:
-            raise AttributeError(name)
-        if obj is not _missing:
-            del self._mock_children[name]
-        self._mock_children[name] = _deleted
-
-
-
-    def _format_mock_call_signature(self, args, kwargs):
-        name = self._mock_name or 'mock'
-        return _format_call_signature(name, args, kwargs)
-
-
-    def _format_mock_failure_message(self, args, kwargs):
-        message = 'Expected call: %s\nActual call: %s'
-        expected_string = self._format_mock_call_signature(args, kwargs)
-        call_args = self.call_args
-        if len(call_args) == 3:
-            call_args = call_args[1:]
-        actual_string = self._format_mock_call_signature(*call_args)
-        return message % (expected_string, actual_string)
-
-
-    def assert_called_with(_mock_self, *args, **kwargs):
-        """assert that the mock was called with the specified arguments.
-
-        Raises an AssertionError if the args and keyword args passed in are
-        different to the last call to the mock."""
-        self = _mock_self
-        if self.call_args is None:
-            expected = self._format_mock_call_signature(args, kwargs)
-            raise AssertionError('Expected call: %s\nNot called' % (expected,))
-
-        if self.call_args != (args, kwargs):
-            msg = self._format_mock_failure_message(args, kwargs)
-            raise AssertionError(msg)
-
-
-    def assert_called_once_with(_mock_self, *args, **kwargs):
-        """assert that the mock was called exactly once and with the specified
-        arguments."""
-        self = _mock_self
-        if not self.call_count == 1:
-            msg = ("Expected to be called once. Called %s times." %
-                   self.call_count)
-            raise AssertionError(msg)
-        return self.assert_called_with(*args, **kwargs)
-
-
-    def assert_has_calls(self, calls, any_order=False):
-        """assert the mock has been called with the specified calls.
-        The `mock_calls` list is checked for the calls.
-
-        If `any_order` is False (the default) then the calls must be
-        sequential. There can be extra calls before or after the
-        specified calls.
-
-        If `any_order` is True then the calls can be in any order, but
-        they must all appear in `mock_calls`."""
-        if not any_order:
-            if calls not in self.mock_calls:
-                raise AssertionError(
-                    'Calls not found.\nExpected: %r\n'
-                    'Actual: %r' % (calls, self.mock_calls)
-                )
-            return
-
-        all_calls = list(self.mock_calls)
-
-        not_found = []
-        for kall in calls:
-            try:
-                all_calls.remove(kall)
-            except ValueError:
-                not_found.append(kall)
-        if not_found:
-            raise AssertionError(
-                '%r not all found in call list' % (tuple(not_found),)
-            )
-
-
-    def assert_any_call(self, *args, **kwargs):
-        """assert the mock has been called with the specified arguments.
-
-        The assert passes if the mock has *ever* been called, unlike
-        `assert_called_with` and `assert_called_once_with` that only pass if
-        the call is the most recent one."""
-        kall = call(*args, **kwargs)
-        if kall not in self.call_args_list:
-            expected_string = self._format_mock_call_signature(args, kwargs)
-            raise AssertionError(
-                '%s call not found' % expected_string
-            )
-
-
-    def _get_child_mock(self, **kw):
-        """Create the child mocks for attributes and return value.
-        By default child mocks will be the same type as the parent.
-        Subclasses of Mock may want to override this to customize the way
-        child mocks are made.
-
-        For non-callable mocks the callable variant will be used (rather than
-        any custom subclass)."""
-        _type = type(self)
-        if not issubclass(_type, CallableMixin):
-            if issubclass(_type, NonCallableMagicMock):
-                klass = MagicMock
-            elif issubclass(_type, NonCallableMock) :
-                klass = Mock
-        else:
-            klass = _type.__mro__[1]
-        return klass(**kw)
-
-
-
-def _try_iter(obj):
-    if obj is None:
-        return obj
-    if _is_exception(obj):
-        return obj
-    if _callable(obj):
-        return obj
-    try:
-        return iter(obj)
-    except TypeError:
-        # XXXX backwards compatibility
-        # but this will blow up on first call - so maybe we should fail early?
-        return obj
-
-
-
-class CallableMixin(Base):
-
-    def __init__(self, spec=None, side_effect=None, return_value=DEFAULT,
-                 wraps=None, name=None, spec_set=None, parent=None,
-                 _spec_state=None, _new_name='', _new_parent=None, **kwargs):
-        self.__dict__['_mock_return_value'] = return_value
-
-        _super(CallableMixin, self).__init__(
-            spec, wraps, name, spec_set, parent,
-            _spec_state, _new_name, _new_parent, **kwargs
-        )
-
-        self.side_effect = side_effect
-
-
-    def _mock_check_sig(self, *args, **kwargs):
-        # stub method that can be replaced with one with a specific signature
-        pass
-
-
-    def __call__(_mock_self, *args, **kwargs):
-        # can't use self in-case a function / method we are mocking uses self
-        # in the signature
-        _mock_self._mock_check_sig(*args, **kwargs)
-        return _mock_self._mock_call(*args, **kwargs)
-
-
-    def _mock_call(_mock_self, *args, **kwargs):
-        self = _mock_self
-        self.called = True
-        self.call_count += 1
-        self.call_args = _Call((args, kwargs), two=True)
-        self.call_args_list.append(_Call((args, kwargs), two=True))
-
-        _new_name = self._mock_new_name
-        _new_parent = self._mock_new_parent
-        self.mock_calls.append(_Call(('', args, kwargs)))
-
-        seen = set()
-        skip_next_dot = _new_name == '()'
-        do_method_calls = self._mock_parent is not None
-        name = self._mock_name
-        while _new_parent is not None:
-            this_mock_call = _Call((_new_name, args, kwargs))
-            if _new_parent._mock_new_name:
-                dot = '.'
-                if skip_next_dot:
-                    dot = ''
-
-                skip_next_dot = False
-                if _new_parent._mock_new_name == '()':
-                    skip_next_dot = True
-
-                _new_name = _new_parent._mock_new_name + dot + _new_name
-
-            if do_method_calls:
-                if _new_name == name:
-                    this_method_call = this_mock_call
-                else:
-                    this_method_call = _Call((name, args, kwargs))
-                _new_parent.method_calls.append(this_method_call)
-
-                do_method_calls = _new_parent._mock_parent is not None
-                if do_method_calls:
-                    name = _new_parent._mock_name + '.' + name
-
-            _new_parent.mock_calls.append(this_mock_call)
-            _new_parent = _new_parent._mock_new_parent
-
-            # use ids here so as not to call __hash__ on the mocks
-            _new_parent_id = id(_new_parent)
-            if _new_parent_id in seen:
-                break
-            seen.add(_new_parent_id)
-
-        ret_val = DEFAULT
-        effect = self.side_effect
-        if effect is not None:
-            if _is_exception(effect):
-                raise effect
-
-            if not _callable(effect):
-                result = next(effect)
-                if _is_exception(result):
-                    raise result
-                return result
-
-            ret_val = effect(*args, **kwargs)
-            if ret_val is DEFAULT:
-                ret_val = self.return_value
-
-        if (self._mock_wraps is not None and
-             self._mock_return_value is DEFAULT):
-            return self._mock_wraps(*args, **kwargs)
-        if ret_val is DEFAULT:
-            ret_val = self.return_value
-        return ret_val
-
-
-
-class Mock(CallableMixin, NonCallableMock):
-    """
-    Create a new `Mock` object. `Mock` takes several optional arguments
-    that specify the behaviour of the Mock object:
-
-    * `spec`: This can be either a list of strings or an existing object (a
-      class or instance) that acts as the specification for the mock object. If
-      you pass in an object then a list of strings is formed by calling dir on
-      the object (excluding unsupported magic attributes and methods). Accessing
-      any attribute not in this list will raise an `AttributeError`.
-
-      If `spec` is an object (rather than a list of strings) then
-      `mock.__class__` returns the class of the spec object. This allows mocks
-      to pass `isinstance` tests.
-
-    * `spec_set`: A stricter variant of `spec`. If used, attempting to *set*
-      or get an attribute on the mock that isn't on the object passed as
-      `spec_set` will raise an `AttributeError`.
-
-    * `side_effect`: A function to be called whenever the Mock is called. See
-      the `side_effect` attribute. Useful for raising exceptions or
-      dynamically changing return values. The function is called with the same
-      arguments as the mock, and unless it returns `DEFAULT`, the return
-      value of this function is used as the return value.
-
-      Alternatively `side_effect` can be an exception class or instance. In
-      this case the exception will be raised when the mock is called.
-
-      If `side_effect` is an iterable then each call to the mock will return
-      the next value from the iterable. If any of the members of the iterable
-      are exceptions they will be raised instead of returned.
-
-    * `return_value`: The value returned when the mock is called. By default
-      this is a new Mock (created on first access). See the
-      `return_value` attribute.
-
-    * `wraps`: Item for the mock object to wrap. If `wraps` is not None then
-      calling the Mock will pass the call through to the wrapped object
-      (returning the real result). Attribute access on the mock will return a
-      Mock object that wraps the corresponding attribute of the wrapped object
-      (so attempting to access an attribute that doesn't exist will raise an
-      `AttributeError`).
-
-      If the mock has an explicit `return_value` set then calls are not passed
-      to the wrapped object and the `return_value` is returned instead.
-
-    * `name`: If the mock has a name then it will be used in the repr of the
-      mock. This can be useful for debugging. The name is propagated to child
-      mocks.
-
-    Mocks can also be called with arbitrary keyword arguments. These will be
-    used to set attributes on the mock after it is created.
-    """
-
-
-
-def _dot_lookup(thing, comp, import_path):
-    try:
-        return getattr(thing, comp)
-    except AttributeError:
-        __import__(import_path)
-        return getattr(thing, comp)
-
-
-def _importer(target):
-    components = target.split('.')
-    import_path = components.pop(0)
-    thing = __import__(import_path)
-
-    for comp in components:
-        import_path += ".%s" % comp
-        thing = _dot_lookup(thing, comp, import_path)
-    return thing
-
-
-def _is_started(patcher):
-    # XXXX horrible
-    return hasattr(patcher, 'is_local')
-
-
-class _patch(object):
-
-    attribute_name = None
-    _active_patches = set()
-
-    def __init__(
-            self, getter, attribute, new, spec, create,
-            spec_set, autospec, new_callable, kwargs
-        ):
-        if new_callable is not None:
-            if new is not DEFAULT:
-                raise ValueError(
-                    "Cannot use 'new' and 'new_callable' together"
-                )
-            if autospec is not None:
-                raise ValueError(
-                    "Cannot use 'autospec' and 'new_callable' together"
-                )
-
-        self.getter = getter
-        self.attribute = attribute
-        self.new = new
-        self.new_callable = new_callable
-        self.spec = spec
-        self.create = create
-        self.has_local = False
-        self.spec_set = spec_set
-        self.autospec = autospec
-        self.kwargs = kwargs
-        self.additional_patchers = []
-
-
-    def copy(self):
-        patcher = _patch(
-            self.getter, self.attribute, self.new, self.spec,
-            self.create, self.spec_set,
-            self.autospec, self.new_callable, self.kwargs
-        )
-        patcher.attribute_name = self.attribute_name
-        patcher.additional_patchers = [
-            p.copy() for p in self.additional_patchers
-        ]
-        return patcher
-
-
-    def __call__(self, func):
-        if isinstance(func, ClassTypes):
-            return self.decorate_class(func)
-        return self.decorate_callable(func)
-
-
-    def decorate_class(self, klass):
-        for attr in dir(klass):
-            if not attr.startswith(patch.TEST_PREFIX):
-                continue
-
-            attr_value = getattr(klass, attr)
-            if not hasattr(attr_value, "__call__"):
-                continue
-
-            patcher = self.copy()
-            setattr(klass, attr, patcher(attr_value))
-        return klass
-
-
-    def decorate_callable(self, func):
-        if hasattr(func, 'patchings'):
-            func.patchings.append(self)
-            return func
-
-        @wraps(func)
-        def patched(*args, **keywargs):
-            # don't use a with here (backwards compatability with Python 2.4)
-            extra_args = []
-            entered_patchers = []
-
-            # can't use try...except...finally because of Python 2.4
-            # compatibility
-            exc_info = tuple()
-            try:
-                try:
-                    for patching in patched.patchings:
-                        arg = patching.__enter__()
-                        entered_patchers.append(patching)
-                        if patching.attribute_name is not None:
-                            keywargs.update(arg)
-                        elif patching.new is DEFAULT:
-                            extra_args.append(arg)
-
-                    args += tuple(extra_args)
-                    return func(*args, **keywargs)
-                except:
-                    if (patching not in entered_patchers and
-                        _is_started(patching)):
-                        # the patcher may have been started, but an exception
-                        # raised whilst entering one of its additional_patchers
-                        entered_patchers.append(patching)
-                    # Pass the exception to __exit__
-                    exc_info = sys.exc_info()
-                    # re-raise the exception
-                    raise
-            finally:
-                for patching in reversed(entered_patchers):
-                    patching.__exit__(*exc_info)
-
-        patched.patchings = [self]
-        if hasattr(func, 'func_code'):
-            # not in Python 3
-            patched.compat_co_firstlineno = getattr(
-                func, "compat_co_firstlineno",
-                func.func_code.co_firstlineno
-            )
-        return patched
-
-
-    def get_original(self):
-        target = self.getter()
-        name = self.attribute
-
-        original = DEFAULT
-        local = False
-
-        try:
-            original = target.__dict__[name]
-        except (AttributeError, KeyError):
-            original = getattr(target, name, DEFAULT)
-        else:
-            local = True
-
-        if not self.create and original is DEFAULT:
-            raise AttributeError(
-                "%s does not have the attribute %r" % (target, name)
-            )
-        return original, local
-
-
-    def __enter__(self):
-        """Perform the patch."""
-        new, spec, spec_set = self.new, self.spec, self.spec_set
-        autospec, kwargs = self.autospec, self.kwargs
-        new_callable = self.new_callable
-        self.target = self.getter()
-
-        # normalise False to None
-        if spec is False:
-            spec = None
-        if spec_set is False:
-            spec_set = None
-        if autospec is False:
-            autospec = None
-
-        if spec is not None and autospec is not None:
-            raise TypeError("Can't specify spec and autospec")
-        if ((spec is not None or autospec is not None) and
-            spec_set not in (True, None)):
-            raise TypeError("Can't provide explicit spec_set *and* spec or autospec")
-
-        original, local = self.get_original()
-
-        if new is DEFAULT and autospec is None:
-            inherit = False
-            if spec is True:
-                # set spec to the object we are replacing
-                spec = original
-                if spec_set is True:
-                    spec_set = original
-                    spec = None
-            elif spec is not None:
-                if spec_set is True:
-                    spec_set = spec
-                    spec = None
-            elif spec_set is True:
-                spec_set = original
-
-            if spec is not None or spec_set is not None:
-                if original is DEFAULT:
-                    raise TypeError("Can't use 'spec' with create=True")
-                if isinstance(original, ClassTypes):
-                    # If we're patching out a class and there is a spec
-                    inherit = True
-
-            Klass = MagicMock
-            _kwargs = {}
-            if new_callable is not None:
-                Klass = new_callable
-            elif spec is not None or spec_set is not None:
-                this_spec = spec
-                if spec_set is not None:
-                    this_spec = spec_set
-                if _is_list(this_spec):
-                    not_callable = '__call__' not in this_spec
-                else:
-                    not_callable = not _callable(this_spec)
-                if not_callable:
-                    Klass = NonCallableMagicMock
-
-            if spec is not None:
-                _kwargs['spec'] = spec
-            if spec_set is not None:
-                _kwargs['spec_set'] = spec_set
-
-            # add a name to mocks
-            if (isinstance(Klass, type) and
-                issubclass(Klass, NonCallableMock) and self.attribute):
-                _kwargs['name'] = self.attribute
-
-            _kwargs.update(kwargs)
-            new = Klass(**_kwargs)
-
-            if inherit and _is_instance_mock(new):
-                # we can only tell if the instance should be callable if the
-                # spec is not a list
-                this_spec = spec
-                if spec_set is not None:
-                    this_spec = spec_set
-                if (not _is_list(this_spec) and not
-                    _instance_callable(this_spec)):
-                    Klass = NonCallableMagicMock
-
-                _kwargs.pop('name')
-                new.return_value = Klass(_new_parent=new, _new_name='()',
-                                         **_kwargs)
-        elif autospec is not None:
-            # spec is ignored, new *must* be default, spec_set is treated
-            # as a boolean. Should we check spec is not None and that spec_set
-            # is a bool?
-            if new is not DEFAULT:
-                raise TypeError(
-                    "autospec creates the mock for you. Can't specify "
-                    "autospec and new."
-                )
-            if original is DEFAULT:
-                raise TypeError("Can't use 'autospec' with create=True")
-            spec_set = bool(spec_set)
-            if autospec is True:
-                autospec = original
-
-            new = create_autospec(autospec, spec_set=spec_set,
-                                  _name=self.attribute, **kwargs)
-        elif kwargs:
-            # can't set keyword args when we aren't creating the mock
-            # XXXX If new is a Mock we could call new.configure_mock(**kwargs)
-            raise TypeError("Can't pass kwargs to a mock we aren't creating")
-
-        new_attr = new
-
-        self.temp_original = original
-        self.is_local = local
-        setattr(self.target, self.attribute, new_attr)
-        if self.attribute_name is not None:
-            extra_args = {}
-            if self.new is DEFAULT:
-                extra_args[self.attribute_name] =  new
-            for patching in self.additional_patchers:
-                arg = patching.__enter__()
-                if patching.new is DEFAULT:
-                    extra_args.update(arg)
-            return extra_args
-
-        return new
-
-
-    def __exit__(self, *exc_info):
-        """Undo the patch."""
-        if not _is_started(self):
-            raise RuntimeError('stop called on unstarted patcher')
-
-        if self.is_local and self.temp_original is not DEFAULT:
-            setattr(self.target, self.attribute, self.temp_original)
-        else:
-            delattr(self.target, self.attribute)
-            if not self.create and not hasattr(self.target, self.attribute):
-                # needed for proxy objects like django settings
-                setattr(self.target, self.attribute, self.temp_original)
-
-        del self.temp_original
-        del self.is_local
-        del self.target
-        for patcher in reversed(self.additional_patchers):
-            if _is_started(patcher):
-                patcher.__exit__(*exc_info)
-
-
-    def start(self):
-        """Activate a patch, returning any created mock."""
-        result = self.__enter__()
-        self._active_patches.add(self)
-        return result
-
-
-    def stop(self):
-        """Stop an active patch."""
-        self._active_patches.discard(self)
-        return self.__exit__()
-
-
-
-def _get_target(target):
-    try:
-        target, attribute = target.rsplit('.', 1)
-    except (TypeError, ValueError):
-        raise TypeError("Need a valid target to patch. You supplied: %r" %
-                        (target,))
-    getter = lambda: _importer(target)
-    return getter, attribute
-
-
-def _patch_object(
-        target, attribute, new=DEFAULT, spec=None,
-        create=False, spec_set=None, autospec=None,
-        new_callable=None, **kwargs
-    ):
-    """
-    patch.object(target, attribute, new=DEFAULT, spec=None, create=False,
-                 spec_set=None, autospec=None, new_callable=None, **kwargs)
-
-    patch the named member (`attribute`) on an object (`target`) with a mock
-    object.
-
-    `patch.object` can be used as a decorator, class decorator or a context
-    manager. Arguments `new`, `spec`, `create`, `spec_set`,
-    `autospec` and `new_callable` have the same meaning as for `patch`. Like
-    `patch`, `patch.object` takes arbitrary keyword arguments for configuring
-    the mock object it creates.
-
-    When used as a class decorator `patch.object` honours `patch.TEST_PREFIX`
-    for choosing which methods to wrap.
-    """
-    getter = lambda: target
-    return _patch(
-        getter, attribute, new, spec, create,
-        spec_set, autospec, new_callable, kwargs
-    )
-
-
-def _patch_multiple(target, spec=None, create=False, spec_set=None,
-                    autospec=None, new_callable=None, **kwargs):
-    """Perform multiple patches in a single call. It takes the object to be
-    patched (either as an object or a string to fetch the object by importing)
-    and keyword arguments for the patches::
-
-        with patch.multiple(settings, FIRST_PATCH='one', SECOND_PATCH='two'):
-            ...
-
-    Use `DEFAULT` as the value if you want `patch.multiple` to create
-    mocks for you. In this case the created mocks are passed into a decorated
-    function by keyword, and a dictionary is returned when `patch.multiple` is
-    used as a context manager.
-
-    `patch.multiple` can be used as a decorator, class decorator or a context
-    manager. The arguments `spec`, `spec_set`, `create`,
-    `autospec` and `new_callable` have the same meaning as for `patch`. These
-    arguments will be applied to *all* patches done by `patch.multiple`.
-
-    When used as a class decorator `patch.multiple` honours `patch.TEST_PREFIX`
-    for choosing which methods to wrap.
-    """
-    if type(target) in (unicode, str):
-        getter = lambda: _importer(target)
-    else:
-        getter = lambda: target
-
-    if not kwargs:
-        raise ValueError(
-            'Must supply at least one keyword argument with patch.multiple'
-        )
-    # need to wrap in a list for python 3, where items is a view
-    items = list(kwargs.items())
-    attribute, new = items[0]
-    patcher = _patch(
-        getter, attribute, new, spec, create, spec_set,
-        autospec, new_callable, {}
-    )
-    patcher.attribute_name = attribute
-    for attribute, new in items[1:]:
-        this_patcher = _patch(
-            getter, attribute, new, spec, create, spec_set,
-            autospec, new_callable, {}
-        )
-        this_patcher.attribute_name = attribute
-        patcher.additional_patchers.append(this_patcher)
-    return patcher
-
-
-def patch(
-        target, new=DEFAULT, spec=None, create=False,
-        spec_set=None, autospec=None, new_callable=None, **kwargs
-    ):
-    """
-    `patch` acts as a function decorator, class decorator or a context
-    manager. Inside the body of the function or with statement, the `target`
-    is patched with a `new` object. When the function/with statement exits
-    the patch is undone.
-
-    If `new` is omitted, then the target is replaced with a
-    `MagicMock`. If `patch` is used as a decorator and `new` is
-    omitted, the created mock is passed in as an extra argument to the
-    decorated function. If `patch` is used as a context manager the created
-    mock is returned by the context manager.
-
-    `target` should be a string in the form `'package.module.ClassName'`. The
-    `target` is imported and the specified object replaced with the `new`
-    object, so the `target` must be importable from the environment you are
-    calling `patch` from. The target is imported when the decorated function
-    is executed, not at decoration time.
-
-    The `spec` and `spec_set` keyword arguments are passed to the `MagicMock`
-    if patch is creating one for you.
-
-    In addition you can pass `spec=True` or `spec_set=True`, which causes
-    patch to pass in the object being mocked as the spec/spec_set object.
-
-    `new_callable` allows you to specify a different class, or callable object,
-    that will be called to create the `new` object. By default `MagicMock` is
-    used.
-
-    A more powerful form of `spec` is `autospec`. If you set `autospec=True`
-    then the mock with be created with a spec from the object being replaced.
-    All attributes of the mock will also have the spec of the corresponding
-    attribute of the object being replaced. Methods and functions being
-    mocked will have their arguments checked and will raise a `TypeError` if
-    they are called with the wrong signature. For mocks replacing a class,
-    their return value (the 'instance') will have the same spec as the class.
-
-    Instead of `autospec=True` you can pass `autospec=some_object` to use an
-    arbitrary object as the spec instead of the one being replaced.
-
-    By default `patch` will fail to replace attributes that don't exist. If
-    you pass in `create=True`, and the attribute doesn't exist, patch will
-    create the attribute for you when the patched function is called, and
-    delete it again afterwards. This is useful for writing tests against
-    attributes that your production code creates at runtime. It is off by by
-    default because it can be dangerous. With it switched on you can write
-    passing tests against APIs that don't actually exist!
-
-    Patch can be used as a `TestCase` class decorator. It works by
-    decorating each test method in the class. This reduces the boilerplate
-    code when your test methods share a common patchings set. `patch` finds
-    tests by looking for method names that start with `patch.TEST_PREFIX`.
-    By default this is `test`, which matches the way `unittest` finds tests.
-    You can specify an alternative prefix by setting `patch.TEST_PREFIX`.
-
-    Patch can be used as a context manager, with the with statement. Here the
-    patching applies to the indented block after the with statement. If you
-    use "as" then the patched object will be bound to the name after the
-    "as"; very useful if `patch` is creating a mock object for you.
-
-    `patch` takes arbitrary keyword arguments. These will be passed to
-    the `Mock` (or `new_callable`) on construction.
-
-    `patch.dict(...)`, `patch.multiple(...)` and `patch.object(...)` are
-    available for alternate use-cases.
-    """
-    getter, attribute = _get_target(target)
-    return _patch(
-        getter, attribute, new, spec, create,
-        spec_set, autospec, new_callable, kwargs
-    )
-
-
-class _patch_dict(object):
-    """
-    Patch a dictionary, or dictionary like object, and restore the dictionary
-    to its original state after the test.
-
-    `in_dict` can be a dictionary or a mapping like container. If it is a
-    mapping then it must at least support getting, setting and deleting items
-    plus iterating over keys.
-
-    `in_dict` can also be a string specifying the name of the dictionary, which
-    will then be fetched by importing it.
-
-    `values` can be a dictionary of values to set in the dictionary. `values`
-    can also be an iterable of `(key, value)` pairs.
-
-    If `clear` is True then the dictionary will be cleared before the new
-    values are set.
-
-    `patch.dict` can also be called with arbitrary keyword arguments to set
-    values in the dictionary::
-
-        with patch.dict('sys.modules', mymodule=Mock(), other_module=Mock()):
-            ...
-
-    `patch.dict` can be used as a context manager, decorator or class
-    decorator. When used as a class decorator `patch.dict` honours
-    `patch.TEST_PREFIX` for choosing which methods to wrap.
-    """
-
-    def __init__(self, in_dict, values=(), clear=False, **kwargs):
-        if isinstance(in_dict, basestring):
-            in_dict = _importer(in_dict)
-        self.in_dict = in_dict
-        # support any argument supported by dict(...) constructor
-        self.values = dict(values)
-        self.values.update(kwargs)
-        self.clear = clear
-        self._original = None
-
-
-    def __call__(self, f):
-        if isinstance(f, ClassTypes):
-            return self.decorate_class(f)
-        @wraps(f)
-        def _inner(*args, **kw):
-            self._patch_dict()
-            try:
-                return f(*args, **kw)
-            finally:
-                self._unpatch_dict()
-
-        return _inner
-
-
-    def decorate_class(self, klass):
-        for attr in dir(klass):
-            attr_value = getattr(klass, attr)
-            if (attr.startswith(patch.TEST_PREFIX) and
-                 hasattr(attr_value, "__call__")):
-                decorator = _patch_dict(self.in_dict, self.values, self.clear)
-                decorated = decorator(attr_value)
-                setattr(klass, attr, decorated)
-        return klass
-
-
-    def __enter__(self):
-        """Patch the dict."""
-        self._patch_dict()
-
-
-    def _patch_dict(self):
-        values = self.values
-        in_dict = self.in_dict
-        clear = self.clear
-
-        try:
-            original = in_dict.copy()
-        except AttributeError:
-            # dict like object with no copy method
-            # must support iteration over keys
-            original = {}
-            for key in in_dict:
-                original[key] = in_dict[key]
-        self._original = original
-
-        if clear:
-            _clear_dict(in_dict)
-
-        try:
-            in_dict.update(values)
-        except AttributeError:
-            # dict like object with no update method
-            for key in values:
-                in_dict[key] = values[key]
-
-
-    def _unpatch_dict(self):
-        in_dict = self.in_dict
-        original = self._original
-
-        _clear_dict(in_dict)
-
-        try:
-            in_dict.update(original)
-        except AttributeError:
-            for key in original:
-                in_dict[key] = original[key]
-
-
-    def __exit__(self, *args):
-        """Unpatch the dict."""
-        self._unpatch_dict()
-        return False
-
-    start = __enter__
-    stop = __exit__
-
-
-def _clear_dict(in_dict):
-    try:
-        in_dict.clear()
-    except AttributeError:
-        keys = list(in_dict)
-        for key in keys:
-            del in_dict[key]
-
-
-def _patch_stopall():
-    """Stop all active patches."""
-    for patch in list(_patch._active_patches):
-        patch.stop()
-
-
-patch.object = _patch_object
-patch.dict = _patch_dict
-patch.multiple = _patch_multiple
-patch.stopall = _patch_stopall
-patch.TEST_PREFIX = 'test'
-
-magic_methods = (
-    "lt le gt ge eq ne "
-    "getitem setitem delitem "
-    "len contains iter "
-    "hash str sizeof "
-    "enter exit "
-    "divmod neg pos abs invert "
-    "complex int float index "
-    "trunc floor ceil "
-)
-
-numerics = "add sub mul div floordiv mod lshift rshift and xor or pow "
-inplace = ' '.join('i%s' % n for n in numerics.split())
-right = ' '.join('r%s' % n for n in numerics.split())
-extra = ''
-if inPy3k:
-    extra = 'bool next '
-else:
-    extra = 'unicode long nonzero oct hex truediv rtruediv '
-
-# not including __prepare__, __instancecheck__, __subclasscheck__
-# (as they are metaclass methods)
-# __del__ is not supported at all as it causes problems if it exists
-
-_non_defaults = set('__%s__' % method for method in [
-    'cmp', 'getslice', 'setslice', 'coerce', 'subclasses',
-    'format', 'get', 'set', 'delete', 'reversed',
-    'missing', 'reduce', 'reduce_ex', 'getinitargs',
-    'getnewargs', 'getstate', 'setstate', 'getformat',
-    'setformat', 'repr', 'dir'
-])
-
-
-def _get_method(name, func):
-    "Turns a callable object (like a mock) into a real function"
-    def method(self, *args, **kw):
-        return func(self, *args, **kw)
-    method.__name__ = name
-    return method
-
-
-_magics = set(
-    '__%s__' % method for method in
-    ' '.join([magic_methods, numerics, inplace, right, extra]).split()
-)
-
-_all_magics = _magics | _non_defaults
-
-_unsupported_magics = set([
-    '__getattr__', '__setattr__',
-    '__init__', '__new__', '__prepare__'
-    '__instancecheck__', '__subclasscheck__',
-    '__del__'
-])
-
-_calculate_return_value = {
-    '__hash__': lambda self: object.__hash__(self),
-    '__str__': lambda self: object.__str__(self),
-    '__sizeof__': lambda self: object.__sizeof__(self),
-    '__unicode__': lambda self: unicode(object.__str__(self)),
-}
-
-_return_values = {
-    '__lt__': NotImplemented,
-    '__gt__': NotImplemented,
-    '__le__': NotImplemented,
-    '__ge__': NotImplemented,
-    '__int__': 1,
-    '__contains__': False,
-    '__len__': 0,
-    '__exit__': False,
-    '__complex__': 1j,
-    '__float__': 1.0,
-    '__bool__': True,
-    '__nonzero__': True,
-    '__oct__': '1',
-    '__hex__': '0x1',
-    '__long__': long(1),
-    '__index__': 1,
-}
-
-
-def _get_eq(self):
-    def __eq__(other):
-        ret_val = self.__eq__._mock_return_value
-        if ret_val is not DEFAULT:
-            return ret_val
-        return self is other
-    return __eq__
-
-def _get_ne(self):
-    def __ne__(other):
-        if self.__ne__._mock_return_value is not DEFAULT:
-            return DEFAULT
-        return self is not other
-    return __ne__
-
-def _get_iter(self):
-    def __iter__():
-        ret_val = self.__iter__._mock_return_value
-        if ret_val is DEFAULT:
-            return iter([])
-        # if ret_val was already an iterator, then calling iter on it should
-        # return the iterator unchanged
-        return iter(ret_val)
-    return __iter__
-
-_side_effect_methods = {
-    '__eq__': _get_eq,
-    '__ne__': _get_ne,
-    '__iter__': _get_iter,
-}
-
-
-
-def _set_return_value(mock, method, name):
-    fixed = _return_values.get(name, DEFAULT)
-    if fixed is not DEFAULT:
-        method.return_value = fixed
-        return
-
-    return_calulator = _calculate_return_value.get(name)
-    if return_calulator is not None:
-        try:
-            return_value = return_calulator(mock)
-        except AttributeError:
-            # XXXX why do we return AttributeError here?
-            #      set it as a side_effect instead?
-            return_value = AttributeError(name)
-        method.return_value = return_value
-        return
-
-    side_effector = _side_effect_methods.get(name)
-    if side_effector is not None:
-        method.side_effect = side_effector(mock)
-
-
-
-class MagicMixin(object):
-    def __init__(self, *args, **kw):
-        _super(MagicMixin, self).__init__(*args, **kw)
-        self._mock_set_magics()
-
-
-    def _mock_set_magics(self):
-        these_magics = _magics
-
-        if self._mock_methods is not None:
-            these_magics = _magics.intersection(self._mock_methods)
-
-            remove_magics = set()
-            remove_magics = _magics - these_magics
-
-            for entry in remove_magics:
-                if entry in type(self).__dict__:
-                    # remove unneeded magic methods
-                    delattr(self, entry)
-
-        # don't overwrite existing attributes if called a second time
-        these_magics = these_magics - set(type(self).__dict__)
-
-        _type = type(self)
-        for entry in these_magics:
-            setattr(_type, entry, MagicProxy(entry, self))
-
-
-
-class NonCallableMagicMock(MagicMixin, NonCallableMock):
-    """A version of `MagicMock` that isn't callable."""
-    def mock_add_spec(self, spec, spec_set=False):
-        """Add a spec to a mock. `spec` can either be an object or a
-        list of strings. Only attributes on the `spec` can be fetched as
-        attributes from the mock.
-
-        If `spec_set` is True then only attributes on the spec can be set."""
-        self._mock_add_spec(spec, spec_set)
-        self._mock_set_magics()
-
-
-
-class MagicMock(MagicMixin, Mock):
-    """
-    MagicMock is a subclass of Mock with default implementations
-    of most of the magic methods. You can use MagicMock without having to
-    configure the magic methods yourself.
-
-    If you use the `spec` or `spec_set` arguments then *only* magic
-    methods that exist in the spec will be created.
-
-    Attributes and the return value of a `MagicMock` will also be `MagicMocks`.
-    """
-    def mock_add_spec(self, spec, spec_set=False):
-        """Add a spec to a mock. `spec` can either be an object or a
-        list of strings. Only attributes on the `spec` can be fetched as
-        attributes from the mock.
-
-        If `spec_set` is True then only attributes on the spec can be set."""
-        self._mock_add_spec(spec, spec_set)
-        self._mock_set_magics()
-
-
-
-class MagicProxy(object):
-    def __init__(self, name, parent):
-        self.name = name
-        self.parent = parent
-
-    def __call__(self, *args, **kwargs):
-        m = self.create_mock()
-        return m(*args, **kwargs)
-
-    def create_mock(self):
-        entry = self.name
-        parent = self.parent
-        m = parent._get_child_mock(name=entry, _new_name=entry,
-                                   _new_parent=parent)
-        setattr(parent, entry, m)
-        _set_return_value(parent, m, entry)
-        return m
-
-    def __get__(self, obj, _type=None):
-        return self.create_mock()
-
-
-
-class _ANY(object):
-    "A helper object that compares equal to everything."
-
-    def __eq__(self, other):
-        return True
-
-    def __ne__(self, other):
-        return False
-
-    def __repr__(self):
-        return '<ANY>'
-
-ANY = _ANY()
-
-
-
-def _format_call_signature(name, args, kwargs):
-    message = '%s(%%s)' % name
-    formatted_args = ''
-    args_string = ', '.join([repr(arg) for arg in args])
-    kwargs_string = ', '.join([
-        '%s=%r' % (key, value) for key, value in kwargs.items()
-    ])
-    if args_string:
-        formatted_args = args_string
-    if kwargs_string:
-        if formatted_args:
-            formatted_args += ', '
-        formatted_args += kwargs_string
-
-    return message % formatted_args
-
-
-
-class _Call(tuple):
-    """
-    A tuple for holding the results of a call to a mock, either in the form
-    `(args, kwargs)` or `(name, args, kwargs)`.
-
-    If args or kwargs are empty then a call tuple will compare equal to
-    a tuple without those values. This makes comparisons less verbose::
-
-        _Call(('name', (), {})) == ('name',)
-        _Call(('name', (1,), {})) == ('name', (1,))
-        _Call(((), {'a': 'b'})) == ({'a': 'b'},)
-
-    The `_Call` object provides a useful shortcut for comparing with call::
-
-        _Call(((1, 2), {'a': 3})) == call(1, 2, a=3)
-        _Call(('foo', (1, 2), {'a': 3})) == call.foo(1, 2, a=3)
-
-    If the _Call has no name then it will match any name.
-    """
-    def __new__(cls, value=(), name=None, parent=None, two=False,
-                from_kall=True):
-        name = ''
-        args = ()
-        kwargs = {}
-        _len = len(value)
-        if _len == 3:
-            name, args, kwargs = value
-        elif _len == 2:
-            first, second = value
-            if isinstance(first, basestring):
-                name = first
-                if isinstance(second, tuple):
-                    args = second
-                else:
-                    kwargs = second
-            else:
-                args, kwargs = first, second
-        elif _len == 1:
-            value, = value
-            if isinstance(value, basestring):
-                name = value
-            elif isinstance(value, tuple):
-                args = value
-            else:
-                kwargs = value
-
-        if two:
-            return tuple.__new__(cls, (args, kwargs))
-
-        return tuple.__new__(cls, (name, args, kwargs))
-
-
-    def __init__(self, value=(), name=None, parent=None, two=False,
-                 from_kall=True):
-        self.name = name
-        self.parent = parent
-        self.from_kall = from_kall
-
-
-    def __eq__(self, other):
-        if other is ANY:
-            return True
-        try:
-            len_other = len(other)
-        except TypeError:
-            return False
-
-        self_name = ''
-        if len(self) == 2:
-            self_args, self_kwargs = self
-        else:
-            self_name, self_args, self_kwargs = self
-
-        other_name = ''
-        if len_other == 0:
-            other_args, other_kwargs = (), {}
-        elif len_other == 3:
-            other_name, other_args, other_kwargs = other
-        elif len_other == 1:
-            value, = other
-            if isinstance(value, tuple):
-                other_args = value
-                other_kwargs = {}
-            elif isinstance(value, basestring):
-                other_name = value
-                other_args, other_kwargs = (), {}
-            else:
-                other_args = ()
-                other_kwargs = value
-        else:
-            # len 2
-            # could be (name, args) or (name, kwargs) or (args, kwargs)
-            first, second = other
-            if isinstance(first, basestring):
-                other_name = first
-                if isinstance(second, tuple):
-                    other_args, other_kwargs = second, {}
-                else:
-                    other_args, other_kwargs = (), second
-            else:
-                other_args, other_kwargs = first, second
-
-        if self_name and other_name != self_name:
-            return False
-
-        # this order is important for ANY to work!
-        return (other_args, other_kwargs) == (self_args, self_kwargs)
-
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-
-    def __call__(self, *args, **kwargs):
-        if self.name is None:
-            return _Call(('', args, kwargs), name='()')
-
-        name = self.name + '()'
-        return _Call((self.name, args, kwargs), name=name, parent=self)
-
-
-    def __getattr__(self, attr):
-        if self.name is None:
-            return _Call(name=attr, from_kall=False)
-        name = '%s.%s' % (self.name, attr)
-        return _Call(name=name, parent=self, from_kall=False)
-
-
-    def __repr__(self):
-        if not self.from_kall:
-            name = self.name or 'call'
-            if name.startswith('()'):
-                name = 'call%s' % name
-            return name
-
-        if len(self) == 2:
-            name = 'call'
-            args, kwargs = self
-        else:
-            name, args, kwargs = self
-            if not name:
-                name = 'call'
-            elif not name.startswith('()'):
-                name = 'call.%s' % name
-            else:
-                name = 'call%s' % name
-        return _format_call_signature(name, args, kwargs)
-
-
-    def call_list(self):
-        """For a call object that represents multiple calls, `call_list`
-        returns a list of all the intermediate calls as well as the
-        final call."""
-        vals = []
-        thing = self
-        while thing is not None:
-            if thing.from_kall:
-                vals.append(thing)
-            thing = thing.parent
-        return _CallList(reversed(vals))
-
-
-call = _Call(from_kall=False)
-
-
-
-def create_autospec(spec, spec_set=False, instance=False, _parent=None,
-                    _name=None, **kwargs):
-    """Create a mock object using another object as a spec. Attributes on the
-    mock will use the corresponding attribute on the `spec` object as their
-    spec.
-
-    Functions or methods being mocked will have their arguments checked
-    to check that they are called with the correct signature.
-
-    If `spec_set` is True then attempting to set attributes that don't exist
-    on the spec object will raise an `AttributeError`.
-
-    If a class is used as a spec then the return value of the mock (the
-    instance of the class) will have the same spec. You can use a class as the
-    spec for an instance object by passing `instance=True`. The returned mock
-    will only be callable if instances of the mock are callable.
-
-    `create_autospec` also takes arbitrary keyword arguments that are passed to
-    the constructor of the created mock."""
-    if _is_list(spec):
-        # can't pass a list instance to the mock constructor as it will be
-        # interpreted as a list of strings
-        spec = type(spec)
-
-    is_type = isinstance(spec, ClassTypes)
-
-    _kwargs = {'spec': spec}
-    if spec_set:
-        _kwargs = {'spec_set': spec}
-    elif spec is None:
-        # None we mock with a normal mock without a spec
-        _kwargs = {}
-
-    _kwargs.update(kwargs)
-
-    Klass = MagicMock
-    if type(spec) in DescriptorTypes:
-        # descriptors don't have a spec
-        # because we don't know what type they return
-        _kwargs = {}
-    elif not _callable(spec):
-        Klass = NonCallableMagicMock
-    elif is_type and instance and not _instance_callable(spec):
-        Klass = NonCallableMagicMock
-
-    _new_name = _name
-    if _parent is None:
-        # for a top level object no _new_name should be set
-        _new_name = ''
-
-    mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name,
-                 name=_name, **_kwargs)
-
-    if isinstance(spec, FunctionTypes):
-        # should only happen at the top level because we don't
-        # recurse for functions
-        mock = _set_signature(mock, spec)
-    else:
-        _check_signature(spec, mock, is_type, instance)
-
-    if _parent is not None and not instance:
-        _parent._mock_children[_name] = mock
-
-    if is_type and not instance and 'return_value' not in kwargs:
-        mock.return_value = create_autospec(spec, spec_set, instance=True,
-                                            _name='()', _parent=mock)
-
-    for entry in dir(spec):
-        if _is_magic(entry):
-            # MagicMock already does the useful magic methods for us
-            continue
-
-        if isinstance(spec, FunctionTypes) and entry in FunctionAttributes:
-            # allow a mock to actually be a function
-            continue
-
-        # XXXX do we need a better way of getting attributes without
-        # triggering code execution (?) Probably not - we need the actual
-        # object to mock it so we would rather trigger a property than mock
-        # the property descriptor. Likewise we want to mock out dynamically
-        # provided attributes.
-        # XXXX what about attributes that raise exceptions other than
-        # AttributeError on being fetched?
-        # we could be resilient against it, or catch and propagate the
-        # exception when the attribute is fetched from the mock
-        try:
-            original = getattr(spec, entry)
-        except AttributeError:
-            continue
-
-        kwargs = {'spec': original}
-        if spec_set:
-            kwargs = {'spec_set': original}
-
-        if not isinstance(original, FunctionTypes):
-            new = _SpecState(original, spec_set, mock, entry, instance)
-            mock._mock_children[entry] = new
-        else:
-            parent = mock
-            if isinstance(spec, FunctionTypes):
-                parent = mock.mock
-
-            new = MagicMock(parent=parent, name=entry, _new_name=entry,
-                            _new_parent=parent, **kwargs)
-            mock._mock_children[entry] = new
-            skipfirst = _must_skip(spec, entry, is_type)
-            _check_signature(original, new, skipfirst=skipfirst)
-
-        # so functions created with _set_signature become instance attributes,
-        # *plus* their underlying mock exists in _mock_children of the parent
-        # mock. Adding to _mock_children may be unnecessary where we are also
-        # setting as an instance attribute?
-        if isinstance(new, FunctionTypes):
-            setattr(mock, entry, new)
-
-    return mock
-
-
-def _must_skip(spec, entry, is_type):
-    if not isinstance(spec, ClassTypes):
-        if entry in getattr(spec, '__dict__', {}):
-            # instance attribute - shouldn't skip
-            return False
-        spec = spec.__class__
-    if not hasattr(spec, '__mro__'):
-        # old style class: can't have descriptors anyway
-        return is_type
-
-    for klass in spec.__mro__:
-        result = klass.__dict__.get(entry, DEFAULT)
-        if result is DEFAULT:
-            continue
-        if isinstance(result, (staticmethod, classmethod)):
-            return False
-        return is_type
-
-    # shouldn't get here unless function is a dynamically provided attribute
-    # XXXX untested behaviour
-    return is_type
-
-
-def _get_class(obj):
-    try:
-        return obj.__class__
-    except AttributeError:
-        # in Python 2, _sre.SRE_Pattern objects have no __class__
-        return type(obj)
-
-
-class _SpecState(object):
-
-    def __init__(self, spec, spec_set=False, parent=None,
-                 name=None, ids=None, instance=False):
-        self.spec = spec
-        self.ids = ids
-        self.spec_set = spec_set
-        self.parent = parent
-        self.instance = instance
-        self.name = name
-
-
-FunctionTypes = (
-    # python function
-    type(create_autospec),
-    # instance method
-    type(ANY.__eq__),
-    # unbound method
-    type(_ANY.__eq__),
-)
-
-FunctionAttributes = set([
-    'func_closure',
-    'func_code',
-    'func_defaults',
-    'func_dict',
-    'func_doc',
-    'func_globals',
-    'func_name',
-])
-
-
-file_spec = None
-
-
-def mock_open(mock=None, read_data=''):
-    """
-    A helper function to create a mock to replace the use of `open`. It works
-    for `open` called directly or used as a context manager.
-
-    The `mock` argument is the mock object to configure. If `None` (the
-    default) then a `MagicMock` will be created for you, with the API limited
-    to methods or attributes available on standard file handles.
-
-    `read_data` is a string for the `read` method of the file handle to return.
-    This is an empty string by default.
-    """
-    global file_spec
-    if file_spec is None:
-        # set on first use
-        if inPy3k:
-            import _io
-            file_spec = list(set(dir(_io.TextIOWrapper)).union(set(dir(_io.BytesIO))))
-        else:
-            file_spec = file
-
-    if mock is None:
-        mock = MagicMock(name='open', spec=open)
-
-    handle = MagicMock(spec=file_spec)
-    handle.write.return_value = None
-    handle.__enter__.return_value = handle
-    handle.read.return_value = read_data
-
-    mock.return_value = handle
-    return mock
-
-
-class PropertyMock(Mock):
-    """
-    A mock intended to be used as a property, or other descriptor, on a class.
-    `PropertyMock` provides `__get__` and `__set__` methods so you can specify
-    a return value when it is fetched.
-
-    Fetching a `PropertyMock` instance from an object calls the mock, with
-    no args. Setting it calls the mock with the value being set.
-    """
-    def _get_child_mock(self, **kwargs):
-        return MagicMock(**kwargs)
-
-    def __get__(self, obj, obj_type):
-        return self()
-    def __set__(self, obj, val):
-        self(val)
diff --git a/catapult/telemetry/third_party/modulegraph/MANIFEST.in b/catapult/telemetry/third_party/modulegraph/MANIFEST.in
deleted file mode 100644
index 7d2580d..0000000
--- a/catapult/telemetry/third_party/modulegraph/MANIFEST.in
+++ /dev/null
@@ -1,9 +0,0 @@
-include *.txt MANIFEST.in *.py
-recursive-include scripts *.py
-graft doc
-graft doc/_static
-graft doc/_templates
-graft modulegraph_tests
-global-exclude .DS_Store
-global-exclude *.pyc
-global-exclude *.so
diff --git a/catapult/telemetry/third_party/modulegraph/PKG-INFO b/catapult/telemetry/third_party/modulegraph/PKG-INFO
deleted file mode 100644
index bfd4006..0000000
--- a/catapult/telemetry/third_party/modulegraph/PKG-INFO
+++ /dev/null
@@ -1,337 +0,0 @@
-Metadata-Version: 1.1
-Name: modulegraph
-Version: 0.12.1
-Summary: Python module dependency analysis tool
-Home-page: http://bitbucket.org/ronaldoussoren/modulegraph
-Author: Ronald Oussoren
-Author-email: ronaldoussoren@mac.com
-License: MIT
-Download-URL: http://pypi.python.org/pypi/modulegraph
-Description: modulegraph determines a dependency graph between Python modules primarily
-        by bytecode analysis for import statements.
-        
-        modulegraph uses similar methods to modulefinder from the standard library,
-        but uses a more flexible internal representation, has more extensive 
-        knowledge of special cases, and is extensible.
-        
-        
-        Release history
-        ===============
-        
-        0.12.1
-        ------
-        
-        * Issue #25: Complex python files could cause an "maximum recursion depth exceeded"
-          exception due to using stack-based recursion to walk the module AST.
-        
-        
-        0.12
-        ----
-        
-        * Added 'modulegraph.modulegraph.InvalidSourceModule'. This graph node is
-          used for Python source modules that cannot be compiled (for example because
-          they contain syntax errors).
-        
-          This is primarily useful for being able to create a graph for packages
-          that have python 2.x or python 3.x compatibility in separate modules that
-          contain code that isn't valid in the "other" python version.
-        
-        * Added 'modulegraph.modulegraph.InvalidCompiledModule'. This graph node
-          is used for Python bytecode modules that cannot be loaded.
-        
-        * Added 'modulegraph.modulegraph.NamespacePackage'.
-        
-          Patch by bitbucket user htgoebel.
-        
-        * No longer add a MissingModule node to the graph for 'collections.defaultdict'
-          when using 'from collections import defaultdict' ('collections.defaultdict'
-          is an attribute of 'collections', not a submodule).
-        
-        * Fixed typo in ModuleGraph.getReferences()
-        
-        * Added ModuleGraph.getReferers(tonode). This methods yields the
-          nodes that are referencing *tonode* (the reverse of getReferences)
-        
-        * The graph will no longer contain MissingModule nodes when using 'from ... import name' to
-          import a global variable in a python module.
-        
-          There will still be MissingModule nodes for global variables in C extentions, and
-          for 'from missing import name' when 'missing' is itself a MissingModule.
-        
-        * Issue #18: Don't assume that a PEP 302 loader object has a ``path`` attribute. That
-          attribute is not documented and is not always present.
-        
-        0.11.2
-        ------
-        
-        *
-        
-        0.11.1
-        ------
-        
-        * Issue #145: Don't exclude the platform specific 'path' modules (like ntpath)
-        
-        0.11
-        ----
-        
-        This is a feature release
-        
-        Features
-        ........
-        
-        * Hardcode knowlegde about the compatibility aliases in the email
-          module (for python 2.5 upto 3.0).
-        
-          This makes it possible to remove a heavy-handed recipe from py2app.
-        
-        * Added ``modegraph.zipio.getmode`` to fetch the Unix file mode
-          for a file.
-        
-        * Added some handy methods to ``modulegraph.modulegraph.ModuleGraph``.
-        
-        0.10.5
-        ------
-        
-        This is a bugfix release
-        
-        * Don't look at the file extension to determine the file type
-          in modulegraph.find_modules.parse_mf_results, but use the
-          class of the item.
-        
-        * Issue #13: Improved handing of bad relative imports
-          ("from .foo import bar"), these tended to raise confusing errors and
-          are now handled like any other failed import.
-        
-        0.10.4
-        ------
-        
-        This is a bugfix release
-        
-        * There were no 'classifiers' in the package metadata due to a bug
-          in setup.py.
-        
-        0.10.3
-        ------
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * ``modulegraph.find.modules.parse_mf_results`` failed when the main script of
-          a py2app module didn't have a file name ending in '.py'.
-        
-        0.10.2
-        ------
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * Issue #12: modulegraph would sometimes find the wrong package *__init__*
-          module due to using the wrong search method. One easy way to reproduce the
-          problem was to have a toplevel module named *__init__*.
-        
-          Reported by Kentzo.
-        
-        0.10.1
-        ------
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * Issue #11: creating xrefs and dotty graphs from modulegraphs (the --xref
-          and --graph options of py2app) didn't work with python 3 due to use of
-          APIs that aren't available in that version of python.
-        
-          Reported by Andrew Barnert.
-        
-        
-        0.10
-        ----
-        
-        This is a minor feature release
-        
-        Features
-        ........
-        
-        * ``modulegraph.find_modules.find_needed_modules`` claimed to automaticly
-          include subpackages for the "packages" argument as well, but that code
-          didn't work at all.
-        
-        * Issue #9: The modulegraph script is deprecated, use
-          "python -mmodulegraph" instead.
-        
-        * Issue #10: Ensure that the result of "zipio.open" can be used
-          in a with statement (that is, ``with zipio.open(...) as fp``.
-        
-        * No longer use "2to3" to support Python 3.
-        
-          Because of this modulegraph now supports Python 2.6
-          and later.
-        
-        * Slightly improved HTML output, which makes it easier
-          to manipulate the generated HTML using JavaScript.
-        
-          Patch by anatoly techtonik.
-        
-        * Ensure modulegraph works with changes introduced after
-          Python 3.3b1.
-        
-        * Implement support for PEP 420 ("Implicit namespace packages")
-          in Python 3.3.
-        
-        * ``modulegraph.util.imp_walk`` is deprecated and will be
-          removed in the next release of this package.
-        
-        Bugfixes
-        ........
-        
-        * The module graph was incomplete, and generated incorrect warnings
-          along the way, when a subpackage contained import statements for
-          submodules.
-        
-          An example of this is ``sqlalchemy.util``, the ``__init__.py`` file
-          for this package contains imports of modules in that modules using
-          the classic relative import syntax (that is ``import compat`` to
-          import ``sqlalchemy.util.compat``). Until this release modulegraph
-          searched the wrong path to locate these modules (and hence failed
-          to find them).
-        
-        
-        0.9.2
-        -----
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * The 'packages' option to modulegraph.find_modules.find_modules ignored
-          the search path argument but always used the default search path.
-        
-        * The 'imp_find_modules' function in modulegraph.util has an argument 'path',
-          this was a string in previous release and can now also be a sequence.
-        
-        * Don't crash when a module on the 'includes' list doesn't exist, but warn
-          just like for missing 'packages' (modulegraph.find_modules.find_modules)
-        
-        0.9.1
-        -----
-        
-        This is a bugfix release
-        
-        Bug fixes
-        .........
-        
-        - Fixed the name of nodes imports in packages where the first element of
-          a dotted name can be found but the rest cannot. This used to create
-          a MissingModule node for the dotted name in the global namespace instead
-          of relative to the package.
-        
-          That is, given a package "pkg" with submodule "sub" if the "__init__.py"
-          of "pkg" contains "import sub.nomod" we now create a MissingModule node
-          for "pkg.sub.nomod" instead of "sub.nomod".
-        
-          This fixes an issue with including the crcmod package in application
-          bundles, first reported on the pythonmac-sig mailinglist by
-          Brendan Simon.
-        
-        0.9
-        ---
-        
-        This is a minor feature release
-        
-        
-        Features:
-        
-        - Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
-          and can be viewed at <http://packages.python.org/modulegraph>.
-        
-          The documention is very rough at this moment and in need of reorganisation and
-          language cleanup. I've basiclly writting the current version by reading the code
-          and documenting what it does, the order in which classes and methods are document
-          is therefore not necessarily the most useful.
-        
-        - The repository has moved to bitbucket
-        
-        - Renamed ``modulegraph.modulegraph.AddPackagePath`` to ``addPackagePath``,
-          likewise ``ReplacePackage`` is now ``replacePackage``. The old name is still
-          available, but is deprecated and will be removed before the 1.0 release.
-        
-        - ``modulegraph.modulegraph`` contains two node types that are unused and
-          have unclear semantics: ``FlatPackage`` and ``ArchiveModule``. These node
-          types are deprecated and will be removed before 1.0 is released.
-        
-        - Added a simple commandline tool (``modulegraph``) that will print information
-          about the dependency graph of a script.
-        
-        - Added a module (``zipio``) for dealing with paths that may refer to entries
-          inside zipfiles (such as source paths referring to modules in zipped eggfiles).
-        
-          With this addition ``modulegraph.modulegraph.os_listdir`` is deprecated and
-          it will be removed before the 1.0 release.
-        
-        Bug fixes:
-        
-        - The ``__cmp__`` method of a Node no longer causes an exception
-          when the compared-to object is not a Node. Patch by Ivan Kozik.
-        
-        - Issue #1: The initialiser for ``modulegraph.ModuleGraph`` caused an exception
-          when an entry on the path (``sys.path``) doesn't actually exist.
-        
-          Fix by "skurylo", testcase by Ronald.
-        
-        - The code no longer worked with python 2.5, this release fixes that.
-        
-        - Due to the switch to mercurial setuptools will no longer include
-          all required files. Fixed by adding a MANIFEST.in file
-        
-        - The method for printing a ``.dot`` representation of a ``ModuleGraph``
-          works again.
-        
-        
-        0.8.1
-        -----
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - ``from __future__ import absolute_import`` is now supported
-        
-        - Relative imports (``from . import module``) are now supported
-        
-        - Add support for namespace packages when those are installed
-          using option ``--single-version-externally-managed`` (part
-          of setuptools/distribute)
-        
-        0.8
-        ---
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - Initial support for Python 3.x
-        
-        - It is now possible to run the test suite
-          using ``python setup.py test``.
-        
-          (The actual test suite is still fairly minimal though)
-        
-Keywords: import,,dependencies
-Platform: any
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Software Development :: Build Tools
diff --git a/catapult/telemetry/third_party/modulegraph/README.chromium b/catapult/telemetry/third_party/modulegraph/README.chromium
deleted file mode 100644
index 937e677..0000000
--- a/catapult/telemetry/third_party/modulegraph/README.chromium
+++ /dev/null
@@ -1,11 +0,0 @@
-Name: modulegraph
-Short Name: modulegraph
-URL: https://pypi.python.org/pypi/modulegraph/
-Version: 0.12.1
-License: MIT
-License File: NOT_SHIPPED
-Security Critical: no
-Description: modulegraph determines a dependency graph between Python modules
-primarily by bytecode analysis for import statements. It's used by telemetry's
-find_dependencies script.
-Local modification: remove doc/_build directory.
diff --git a/catapult/telemetry/third_party/modulegraph/README.txt b/catapult/telemetry/third_party/modulegraph/README.txt
deleted file mode 100644
index 55ebf46..0000000
--- a/catapult/telemetry/third_party/modulegraph/README.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-modulegraph determines a dependency graph between Python modules primarily
-by bytecode analysis for import statements.
-
-modulegraph uses similar methods to modulefinder from the standard library,
-but uses a more flexible internal representation, has more extensive 
-knowledge of special cases, and is extensible.
diff --git a/catapult/telemetry/third_party/modulegraph/doc/Makefile b/catapult/telemetry/third_party/modulegraph/doc/Makefile
deleted file mode 100644
index b91ac81..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS    =
-SPHINXBUILD   = sphinx-build
-PAPER         =
-BUILDDIR      = _build
-
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest
-
-help:
-	@echo "Please use \`make <target>' where <target> is one of"
-	@echo "  html      to make standalone HTML files"
-	@echo "  dirhtml   to make HTML files named index.html in directories"
-	@echo "  pickle    to make pickle files"
-	@echo "  json      to make JSON files"
-	@echo "  htmlhelp  to make HTML files and a HTML help project"
-	@echo "  qthelp    to make HTML files and a qthelp project"
-	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-	@echo "  changes   to make an overview of all changed/added/deprecated items"
-	@echo "  linkcheck to check all external links for integrity"
-	@echo "  doctest   to run all doctests embedded in the documentation (if enabled)"
-
-clean:
-	-rm -rf $(BUILDDIR)/*
-
-html:
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
-	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
-	@echo
-	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-pickle:
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
-	@echo
-	@echo "Build finished; now you can process the pickle files."
-
-json:
-	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
-	@echo
-	@echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
-	@echo
-	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
-	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
-	@echo
-	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
-	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
-	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/altgraph.qhcp"
-	@echo "To view the help file:"
-	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/altgraph.qhc"
-
-latex:
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
-	@echo
-	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
-	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
-	      "run these through (pdf)latex."
-
-changes:
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
-	@echo
-	@echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
-	@echo
-	@echo "Link check complete; look for any errors in the above output " \
-	      "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
-	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
-	@echo "Testing of doctests in the sources finished, look at the " \
-	      "results in $(BUILDDIR)/doctest/output.txt."
diff --git a/catapult/telemetry/third_party/modulegraph/doc/changelog.rst b/catapult/telemetry/third_party/modulegraph/doc/changelog.rst
deleted file mode 100644
index f6725ac..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/changelog.rst
+++ /dev/null
@@ -1,307 +0,0 @@
-Release history
-===============
-
-0.12.1
-------
-
-* Issue #25: Complex python files could cause an "maximum recursion depth exceeded"
-  exception due to using stack-based recursion to walk the module AST.
-
-
-0.12
-----
-
-* Added 'modulegraph.modulegraph.InvalidSourceModule'. This graph node is
-  used for Python source modules that cannot be compiled (for example because
-  they contain syntax errors).
-
-  This is primarily useful for being able to create a graph for packages
-  that have python 2.x or python 3.x compatibility in separate modules that
-  contain code that isn't valid in the "other" python version.
-
-* Added 'modulegraph.modulegraph.InvalidCompiledModule'. This graph node
-  is used for Python bytecode modules that cannot be loaded.
-
-* Added 'modulegraph.modulegraph.NamespacePackage'.
-
-  Patch by bitbucket user htgoebel.
-
-* No longer add a MissingModule node to the graph for 'collections.defaultdict'
-  when using 'from collections import defaultdict' ('collections.defaultdict'
-  is an attribute of 'collections', not a submodule).
-
-* Fixed typo in ModuleGraph.getReferences()
-
-* Added ModuleGraph.getReferers(tonode). This methods yields the
-  nodes that are referencing *tonode* (the reverse of getReferences)
-
-* The graph will no longer contain MissingModule nodes when using 'from ... import name' to
-  import a global variable in a python module.
-
-  There will still be MissingModule nodes for global variables in C extentions, and
-  for 'from missing import name' when 'missing' is itself a MissingModule.
-
-* Issue #18: Don't assume that a PEP 302 loader object has a ``path`` attribute. That
-  attribute is not documented and is not always present.
-
-0.11.2
-------
-
-*
-
-0.11.1
-------
-
-* Issue #145: Don't exclude the platform specific 'path' modules (like ntpath)
-
-0.11
-----
-
-This is a feature release
-
-Features
-........
-
-* Hardcode knowlegde about the compatibility aliases in the email
-  module (for python 2.5 upto 3.0).
-
-  This makes it possible to remove a heavy-handed recipe from py2app.
-
-* Added ``modegraph.zipio.getmode`` to fetch the Unix file mode
-  for a file.
-
-* Added some handy methods to ``modulegraph.modulegraph.ModuleGraph``.
-
-0.10.5
-------
-
-This is a bugfix release
-
-* Don't look at the file extension to determine the file type
-  in modulegraph.find_modules.parse_mf_results, but use the
-  class of the item.
-
-* Issue #13: Improved handing of bad relative imports
-  ("from .foo import bar"), these tended to raise confusing errors and
-  are now handled like any other failed import.
-
-0.10.4
-------
-
-This is a bugfix release
-
-* There were no 'classifiers' in the package metadata due to a bug
-  in setup.py.
-
-0.10.3
-------
-
-This is a bugfix release
-
-Bugfixes
-........
-
-* ``modulegraph.find.modules.parse_mf_results`` failed when the main script of
-  a py2app module didn't have a file name ending in '.py'.
-
-0.10.2
-------
-
-This is a bugfix release
-
-Bugfixes
-........
-
-* Issue #12: modulegraph would sometimes find the wrong package *__init__*
-  module due to using the wrong search method. One easy way to reproduce the
-  problem was to have a toplevel module named *__init__*.
-
-  Reported by Kentzo.
-
-0.10.1
-------
-
-This is a bugfix release
-
-Bugfixes
-........
-
-* Issue #11: creating xrefs and dotty graphs from modulegraphs (the --xref
-  and --graph options of py2app) didn't work with python 3 due to use of
-  APIs that aren't available in that version of python.
-
-  Reported by Andrew Barnert.
-
-
-0.10
-----
-
-This is a minor feature release
-
-Features
-........
-
-* ``modulegraph.find_modules.find_needed_modules`` claimed to automaticly
-  include subpackages for the "packages" argument as well, but that code
-  didn't work at all.
-
-* Issue #9: The modulegraph script is deprecated, use
-  "python -mmodulegraph" instead.
-
-* Issue #10: Ensure that the result of "zipio.open" can be used
-  in a with statement (that is, ``with zipio.open(...) as fp``.
-
-* No longer use "2to3" to support Python 3.
-
-  Because of this modulegraph now supports Python 2.6
-  and later.
-
-* Slightly improved HTML output, which makes it easier
-  to manipulate the generated HTML using JavaScript.
-
-  Patch by anatoly techtonik.
-
-* Ensure modulegraph works with changes introduced after
-  Python 3.3b1.
-
-* Implement support for PEP 420 ("Implicit namespace packages")
-  in Python 3.3.
-
-* ``modulegraph.util.imp_walk`` is deprecated and will be
-  removed in the next release of this package.
-
-Bugfixes
-........
-
-* The module graph was incomplete, and generated incorrect warnings
-  along the way, when a subpackage contained import statements for
-  submodules.
-
-  An example of this is ``sqlalchemy.util``, the ``__init__.py`` file
-  for this package contains imports of modules in that modules using
-  the classic relative import syntax (that is ``import compat`` to
-  import ``sqlalchemy.util.compat``). Until this release modulegraph
-  searched the wrong path to locate these modules (and hence failed
-  to find them).
-
-
-0.9.2
------
-
-This is a bugfix release
-
-Bugfixes
-........
-
-* The 'packages' option to modulegraph.find_modules.find_modules ignored
-  the search path argument but always used the default search path.
-
-* The 'imp_find_modules' function in modulegraph.util has an argument 'path',
-  this was a string in previous release and can now also be a sequence.
-
-* Don't crash when a module on the 'includes' list doesn't exist, but warn
-  just like for missing 'packages' (modulegraph.find_modules.find_modules)
-
-0.9.1
------
-
-This is a bugfix release
-
-Bug fixes
-.........
-
-- Fixed the name of nodes imports in packages where the first element of
-  a dotted name can be found but the rest cannot. This used to create
-  a MissingModule node for the dotted name in the global namespace instead
-  of relative to the package.
-
-  That is, given a package "pkg" with submodule "sub" if the "__init__.py"
-  of "pkg" contains "import sub.nomod" we now create a MissingModule node
-  for "pkg.sub.nomod" instead of "sub.nomod".
-
-  This fixes an issue with including the crcmod package in application
-  bundles, first reported on the pythonmac-sig mailinglist by
-  Brendan Simon.
-
-0.9
----
-
-This is a minor feature release
-
-
-Features:
-
-- Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
-  and can be viewed at <http://packages.python.org/modulegraph>.
-
-  The documention is very rough at this moment and in need of reorganisation and
-  language cleanup. I've basiclly writting the current version by reading the code
-  and documenting what it does, the order in which classes and methods are document
-  is therefore not necessarily the most useful.
-
-- The repository has moved to bitbucket
-
-- Renamed ``modulegraph.modulegraph.AddPackagePath`` to ``addPackagePath``,
-  likewise ``ReplacePackage`` is now ``replacePackage``. The old name is still
-  available, but is deprecated and will be removed before the 1.0 release.
-
-- ``modulegraph.modulegraph`` contains two node types that are unused and
-  have unclear semantics: ``FlatPackage`` and ``ArchiveModule``. These node
-  types are deprecated and will be removed before 1.0 is released.
-
-- Added a simple commandline tool (``modulegraph``) that will print information
-  about the dependency graph of a script.
-
-- Added a module (``zipio``) for dealing with paths that may refer to entries
-  inside zipfiles (such as source paths referring to modules in zipped eggfiles).
-
-  With this addition ``modulegraph.modulegraph.os_listdir`` is deprecated and
-  it will be removed before the 1.0 release.
-
-Bug fixes:
-
-- The ``__cmp__`` method of a Node no longer causes an exception
-  when the compared-to object is not a Node. Patch by Ivan Kozik.
-
-- Issue #1: The initialiser for ``modulegraph.ModuleGraph`` caused an exception
-  when an entry on the path (``sys.path``) doesn't actually exist.
-
-  Fix by "skurylo", testcase by Ronald.
-
-- The code no longer worked with python 2.5, this release fixes that.
-
-- Due to the switch to mercurial setuptools will no longer include
-  all required files. Fixed by adding a MANIFEST.in file
-
-- The method for printing a ``.dot`` representation of a ``ModuleGraph``
-  works again.
-
-
-0.8.1
------
-
-This is a minor feature release
-
-Features:
-
-- ``from __future__ import absolute_import`` is now supported
-
-- Relative imports (``from . import module``) are now supported
-
-- Add support for namespace packages when those are installed
-  using option ``--single-version-externally-managed`` (part
-  of setuptools/distribute)
-
-0.8
----
-
-This is a minor feature release
-
-Features:
-
-- Initial support for Python 3.x
-
-- It is now possible to run the test suite
-  using ``python setup.py test``.
-
-  (The actual test suite is still fairly minimal though)
diff --git a/catapult/telemetry/third_party/modulegraph/doc/commandline.rst b/catapult/telemetry/third_party/modulegraph/doc/commandline.rst
deleted file mode 100644
index b5a8df5..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/commandline.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-Commandline tools
-=================
-
-The package can be used as a script using "python -mmodulegraph".
-
-This script calculates the module graph for the scripts passed
-on the commandline and by default prints a list of modules
-in the objectgraph, and their type and location.
-
-The script has a number of options to change the output:
-
-* ``-d``: Increase the debug level
-
-* ``-q``: Clear the debug level (emit minimal output)
-
-* ``-m``: The arguments are module names instead of script files
-
-* ``-x name``: Add ``name`` to the list of excludes
-
-* ``-p path``: Add ``path`` to the module search path
-
-* ``-g``: Emit a ``.dot`` file instead of a list of modules
-
-* ``-h``: Emit a ``.html`` file instead of a list of modules
-
-Deprecation warning
--------------------
-
-The package also installs a command-line tool named "modulegraph",
-this command-line tool is deprecated and will be removed in a
-future version.
diff --git a/catapult/telemetry/third_party/modulegraph/doc/conf.py b/catapult/telemetry/third_party/modulegraph/doc/conf.py
deleted file mode 100644
index 76d7b80..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/conf.py
+++ /dev/null
@@ -1,219 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-# modulegraph documentation build configuration file, created by
-# sphinx-quickstart on Tue Sep 28 21:04:40 2010.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
-
-import sys, os
-
-def get_version():
-    fn = os.path.join(
-        os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
-        'setup.cfg')
-    for ln in open(fn):
-        if ln.startswith('version'):
-            version = ln.split('=')[-1].strip()
-            return version
-
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.append(os.path.abspath('.'))
-sys.path.insert(0,
-    os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
-
-
-# -- General configuration -----------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', 'sphinx.ext.ifconfig']
-
-
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# The suffix of source filenames.
-source_suffix = '.rst'
-
-# The encoding of source files.
-#source_encoding = 'utf-8'
-
-# The master toctree document.
-master_doc = 'index'
-
-# General information about the project.
-project = u'modulegraph'
-copyright = u'2010, Ronald Oussoren'
-
-# The version info for the project you're documenting, acts as replacement for
-# |version| and |release|, also used in various other places throughout the
-# built documents.
-#
-# The short X.Y version.
-version = get_version()
-# The full version, including alpha/beta/rc tags.
-release = version
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-#today = ''
-# Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
-
-# List of documents that shouldn't be included in the build.
-#unused_docs = []
-
-# List of directories, relative to source directory, that shouldn't be searched
-# for source files.
-exclude_trees = ['_build']
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-#default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-#add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-#show_authors = False
-
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
-
-
-# -- Options for HTML output ---------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages.  Major themes that come with
-# Sphinx are currently 'default' and 'sphinxdoc'.
-#html_theme = 'default'
-html_theme = 'nature'
-
-# Theme options are theme-specific and customize the look and feel of a theme
-# further.  For a list of options available for each theme, see the
-# documentation.
-#html_theme_options = {}
-
-# Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-#html_title = None
-
-# A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
-
-# The name of an image file (relative to this directory) to place at the top
-# of the sidebar.
-#html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-#html_favicon = None
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
-
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-#html_additional_pages = {}
-
-# If false, no module index is generated.
-#html_use_modindex = True
-
-# If false, no index is generated.
-#html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-#html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-#html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = ''
-
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'modulegraphdoc'
-
-
-# -- Options for LaTeX output --------------------------------------------------
-
-# The paper size ('letter' or 'a4').
-#latex_paper_size = 'letter'
-
-# The font size ('10pt', '11pt' or '12pt').
-#latex_font_size = '10pt'
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, documentclass [howto/manual]).
-latex_documents = [
-  ('index', 'modulegraph.tex', u'modulegraph Documentation',
-   u'Ronald Oussoren', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-#latex_logo = None
-
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-#latex_use_parts = False
-
-# Additional stuff for the LaTeX preamble.
-#latex_preamble = ''
-
-# Documents to append as an appendix to all manuals.
-#latex_appendices = []
-
-# If false, no module index is generated.
-#latex_use_modindex = True
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-intersphinx_mapping = {
-        'python': ('http://docs.python.org/', None),
-        'altgraph': ('http://packages.python.org/altgraph', None),
-}
-
-todo_include_todos = True
diff --git a/catapult/telemetry/third_party/modulegraph/doc/find_modules.rst b/catapult/telemetry/third_party/modulegraph/doc/find_modules.rst
deleted file mode 100644
index 48f0f97..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/find_modules.rst
+++ /dev/null
@@ -1,58 +0,0 @@
-:mod:`modulegraph.find_modules` --- High-level module dependency finding interface
-==================================================================================
-
-.. module:: modulegraph.find_modules
-   :synopsis: High-level module dependency finding interface
-
-This module provides a high-level interface to the functionality of 
-the modulegraph package.
-
-
-.. function:: find_modules([scripts[, includes[, packages[, excludes[, path[, debug]]]]]])
-
-   High-level interface, takes iterables for: scripts, includes, packages, excludes
-
-   And returns a :class:`modulegraph.modulegraph.ModuleGraph` instance, 
-   python_files, and extensions
-
-   python_files is a list of pure python dependencies as modulegraph.Module objects,
-
-   extensions is a list of platform-specific C extension dependencies as modulegraph.Module objects
-
-
-.. function:: parse_mf_results(mf)
-
-   Return two lists: the first one contains the python files in the graph,
-   the second the C extensions.
-        
-   :param mf: a :class:`modulegraph.modulegraph.ModuleGraph` instance
-
-
-Lower-level functionality
--------------------------
-
-The functionality in this section is much lower level and should probably
-not be used. It's mostly documented as a convenience for maintainers.
-
-
-.. function:: get_implies()
-
-   Return a mapping of implied dependencies. The key is a, possibly dotted,
-   module name and the value a list of dependencies.
-
-   This contains hardcoded list of hard dependencies, for example for C
-   extensions in the standard libary that perform imports in C code, which
-   the generic dependency finder cannot locate.
-
-.. function:: plat_prepare(includes, packages, excludes)
-
-   Updates the lists of includes, packages and excludes for the current
-   platform. This will add items to these lists based on hardcoded platform
-   information.
-
-.. function:: find_needed_modules([mf[, scripts[, includes[, packages[, warn]]]]])
-
-   Feeds the given :class:`ModuleGraph <modulegraph.ModuleGraph>`  with
-   the *scripts*, *includes* and *packages* and returns the resulting
-   graph. This function will create a new graph when *mf* is not specified
-   or ``None``.
diff --git a/catapult/telemetry/third_party/modulegraph/doc/index.rst b/catapult/telemetry/third_party/modulegraph/doc/index.rst
deleted file mode 100644
index 534b4d3..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/index.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-.. modulegraph documentation master file, created by
-   sphinx-quickstart on Tue Sep 28 21:04:40 2010.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Modulegraph - Python module dependency graph
-============================================
-
-modulegraph determines a dependency graph between Python modules primarily
-by bytecode analysis for import statements.
-
-modulegraph uses similar methods to :mod:`modulefinder` from the standard library,
-but uses a more flexible internal representation, has more extensive 
-knowledge of special cases, and is extensible.
-
-Contents:
-
-.. toctree::
-   :maxdepth: 1
-
-   changelog
-   license
-   commandline
-   modulegraph
-   find_modules
-   util
-   zipio
-
-Online Resources
-----------------
-
-* `Sourcecode repository on bitbucket <http://bitbucket.org/ronaldoussoren/modulegraph/>`_
-
-* `The issue tracker <http://bitbucket.org/ronaldoussoren/modulegraph/issues>`_
-
-Indices and tables
-------------------
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/catapult/telemetry/third_party/modulegraph/doc/license.rst b/catapult/telemetry/third_party/modulegraph/doc/license.rst
deleted file mode 100644
index f9c8cc5..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/license.rst
+++ /dev/null
@@ -1,23 +0,0 @@
-License
-=======
-
-Copyright (c) Bob Ippolito
-
-Parts are copyright (c) 2010-2014 Ronald Oussoren
-
-MIT License
-...........
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software
-and associated documentation files (the "Software"), to deal in the Software without restriction,
-including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do
-so.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
-INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
-PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
-FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
diff --git a/catapult/telemetry/third_party/modulegraph/doc/modulegraph.rst b/catapult/telemetry/third_party/modulegraph/doc/modulegraph.rst
deleted file mode 100644
index 60566e7..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/modulegraph.rst
+++ /dev/null
@@ -1,531 +0,0 @@
-:mod:`modulegraph.modulegraph` --- Find modules used by a script
-================================================================
-
-.. module:: modulegraph.modulegraph
-   :synopsis: Find modules used by a script
-
-This module defines :class:`ModuleGraph`, which is used to find
-the dependencies of scripts using bytecode analysis.
-
-A number of APIs in this module refer to filesystem path. Those paths can refer to
-files inside zipfiles (for example when there are zipped egg files on :data:`sys.path`).
-Filenames referring to entries in a zipfile are not marked any way, if ``"somepath.zip"``
-refers to a zipfile, that is ``"somepath.zip/embedded/file"`` will be used to refer to
-``embedded/file`` inside the zipfile.
-
-The actual graph
-----------------
-
-.. class:: ModuleGraph([path[, excludes[, replace_paths[, implies[, graph[, debug]]]]]])
-
-   Create a new ModuleGraph object. Use the :meth:`run_script` method to add scripts,
-   and their dependencies to the graph.
-
-   :param path: Python search path to use, defaults to :data:`sys.path`
-   :param excludes: Iterable with module names that should not be included as a dependency
-   :param replace_paths: List of pathname rewrites ``(old, new)``. When this argument is
-     supplied the ``co_filename`` attributes of code objects get rewritten before scanning
-     them for dependencies.
-   :param implies: Implied module dependencies, a mapping from a module name to the list
-     of modules it depends on. Use this to tell modulegraph about dependencies that cannot
-     be found by code inspection (such as imports from C code or using the :func:`__import__`
-     function).
-   :param graph: A precreated :class:`Graph <altgraph.Graph.Graph>` object to use, the
-     default is to create a new one.
-   :param debug: The :class:`ObjectGraph <altgraph.ObjectGraph.ObjectGraph>` debug level.
-
-
-.. method:: run_script(pathname[, caller])
-
-   Create, and return,  a node by path (not module name). The *pathname* should
-   refer to a Python source file and will be scanned for dependencies.
-
-   The optional argument *caller* is the the node that calls this script,
-   and is used to add a reference in the graph.
-
-.. method:: import_hook(name[[, caller[, fromlist[, level, [, attr]]]])
-
-   Import a module and analyse its dependencies
-
-   :arg name:     The module name
-   :arg caller:   The node that caused the import to happen
-   :arg fromlist: The list of names to import, this is an empty list for
-      ``import name`` and a list of names for ``from name import a, b, c``.
-   :arg level:    The import level. The value should be ``-1`` for classical Python 2
-     imports, ``0`` for absolute imports and a positive number for relative imports (
-     where the value is the number of leading dots in the imported name).
-   :arg attr:     Attributes for the graph edge.
-
-
-.. method:: implyNodeReference(node, other, edgeData=None)
-
-   Explictly mark that *node* depends on *other*. Other is either
-   a :class:`node <Node>` or the name of a module that will be
-   searched for as if it were an absolute import.
-
-
-.. method:: createReference(fromnode, tonode[, edge_data])
-
-   Create a reference from *fromnode* to *tonode*, with optional edge data.
-
-   The default for *edge_data* is ``"direct"``.
-
-.. method:: getReferences(fromnode)
-
-   Yield all nodes that *fromnode* refers to. That is, all modules imported
-   by *fromnode*.
-
-   Node :data:`None` is the root of the graph, and refers to all notes that were
-   explicitly imported by :meth:`run_script` or :meth:`import_hook`, unless you use
-   an explicit parent with those methods.
-
-   .. versionadded:: 0.11
-
-.. method:: getReferers(tonode, collapse_missing_modules=True)
-
-   Yield all nodes that refer to *tonode*. That is, all modules that import
-   *tonode*.
-
-   If *collapse_missing_modules* is false this includes refererences from
-   :class:`MissingModule` nodes, otherwise :class:`MissingModule` nodes
-   are replaced by the "real" nodes that reference this missing node.
-
-   .. versionadded:: 0.12
-
-.. method:: foldReferences(pkgnode)
-
-   Hide all submodule nodes for package *pkgnode* and add ingoing and outgoing
-   edges to *pkgnode* based on the edges from the submodule nodes.
-
-   This can be used to simplify a module graph: after folding 'email' all
-   references to modules in the 'email' package are references to the package.
-
-   .. versionadded: 0.11
-
-.. method:: findNode(name)
-
-   Find a node by identifier.  If a node by that identifier exists, it will be returned.
-
-   If a lazy node exists by that identifier with no dependencies (excluded), it will be
-   instantiated and returned.
-
-   If a lazy node exists by that identifier with dependencies, it and its
-   dependencies will be instantiated and scanned for additional depende
-
-
-
-.. method:: create_xref([out])
-
-   Write an HTML file to the *out* stream (defaulting to :data:`sys.stdout`).
-
-   The HTML file contains a textual description of the dependency graph.
-
-
-
-.. method:: graphreport([fileobj[, flatpackages]])
-
-   .. todo:: To be documented
-
-
-
-.. method:: report()
-
-   Print a report to stdout, listing the found modules with their
-   paths, as well as modules that are missing, or seem to be missing.
-
-
-Mostly internal methods
-.......................
-
-The methods in this section should be considered as methods for subclassing at best,
-please let us know if you need these methods in your code as they are on track to be
-made private methods before the 1.0 release.
-
-.. warning:: The methods in this section will be refactored in a future release,
-   the current architecture makes it unnecessarily hard to write proper tests.
-
-.. method:: determine_parent(caller)
-
-   Returns the node of the package root voor *caller*. If *caller* is a package
-   this is the node itself, if the node is a module in a package this is the
-   node of for the package and otherwise the *caller* is not a package and
-   the result is :data:`None`.
-
-.. method:: find_head_package(parent, name[, level])
-
-   .. todo:: To be documented
-
-
-.. method:: load_tail(mod, tail)
-
-   This method is called to load the rest of a dotted name after loading the root
-   of a package. This will import all intermediate modules as well (using
-   :meth:`import_module`), and returns the module :class:`node <Node>` for the
-   requested node.
-
-   .. note:: When *tail* is empty this will just return *mod*.
-
-   :arg mod:   A start module (instance of :class:`Node`)
-   :arg tail:  The rest of a dotted name, can be empty
-   :raise ImportError: When the requested (or one of its parents) module cannot be found
-   :returns: the requested module
-
-
-
-.. method:: ensure_fromlist(m, fromlist)
-
-   Yield all submodules that would be imported when importing *fromlist*
-   from *m* (using ``from m import fromlist...``).
-
-   *m* must be a package and not a regular module.
-
-.. method:: find_all_submodules(m)
-
-   Yield the filenames for submodules of in the same package as *m*.
-
-
-
-.. method:: import_module(partname, fqname, parent)
-
-   Perform import of the module with basename *partname* (``path``) and
-   full name *fqname* (``os.path``). Import is performed by *parent*.
-
-   This will create a reference from the parent node to the
-   module node and will load the module node when it is not already
-   loaded.
-
-
-
-.. method:: load_module(fqname, fp, pathname, (suffix, mode, type))
-
-   Load the module named *fqname* from the given *pathame*. The
-   argument *fp* is either :data:`None`, or a stream where the
-   code for the Python module can be loaded (either byte-code or
-   the source code). The *(suffix, mode, type)* tuple are the
-   suffix of the source file, the open mode for the file and the
-   type of module.
-
-   Creates a node of the right class and processes the dependencies
-   of the :class:`node <Node>` by scanning the byte-code for the node.
-
-   Returns the resulting :class:`node <Node>`.
-
-
-
-.. method:: scan_code(code, m)
-
-   Scan the *code* object for module *m* and update the dependencies of
-   *m* using the import statemets found in the code.
-
-   This will automaticly scan the code for nested functions, generator
-   expressions and list comprehensions as well.
-
-
-
-.. method:: load_package(fqname, pathname)
-
-   Load a package directory.
-
-
-
-.. method:: find_module(name, path[, parent])
-
-   Locates a module named *name* that is not yet part of the
-   graph. This method will raise :exc:`ImportError` when
-   the module cannot be found or when it is already part
-   of the graph. The *name* can not be a dotted name.
-
-   The *path* is the search path used, or :data:`None` to
-   use the default path.
-
-   When the *parent* is specified *name* refers to a
-   subpackage of *parent*, and *path* should be the
-   search path of the parent.
-
-   Returns the result of the global function
-   :func:`find_module <modulegraph.modulegraph.find_module>`.
-
-
-.. method:: itergraphreport([name[, flatpackages]])
-
-   .. todo:: To be documented
-
-
-
-.. method:: replace_paths_in_code(co)
-
-   Replace the filenames in code object *co* using the *replace_paths* value that
-   was passed to the contructor. Returns the rewritten code object.
-
-
-
-.. method:: calc_setuptools_nspackages()
-
-   Returns a mapping from package name to a list of paths where that package
-   can be found in ``--single-version-externally-managed`` form.
-
-   This method is used to be able to find those packages: these use
-   a magic ``.pth`` file to ensure that the package is added to :data:`sys.path`,
-   as they do not contain an ``___init__.py`` file.
-
-   Packages in this form are used by system packages and the "pip"
-   installer.
-
-
-Graph nodes
------------
-
-The :class:`ModuleGraph` contains nodes that represent the various types of modules.
-
-.. class:: Alias(value)
-
-   This is a subclass of string that is used to mark module aliases.
-
-
-
-.. class:: Node(identifier)
-
-   Base class for nodes, which provides the common functionality.
-
-   Nodes can by used as mappings for storing arbitrary data in the node.
-
-   Nodes are compared by comparing their *identifier*.
-
-.. data:: debug
-
-   Debug level (integer)
-
-.. data:: graphident
-
-   The node identifier, this is the value of the *identifier* argument
-   to the constructor.
-
-.. data:: identifier
-
-   The node identifier, this is the value of the *identifier* argument
-   to the constructor.
-
-.. data:: filename
-
-   The filename associated with this node.
-
-.. data:: packagepath
-
-   The value of ``__path__`` for this node.
-
-.. data:: code
-
-   The :class:`code object <types.CodeObject>` associated with this node
-
-.. data:: globalnames
-
-   The set of global names that are assigned to in this module. This
-   includes those names imported through startimports of Python modules.
-
-.. data:: startimports
-
-   The set of startimports this module did that could not be resolved,
-   ie. a startimport from a non-Python module.
-
-
-.. method:: __contains__(name)
-
-   Return if there is a value associated with *name*.
-
-   This method is usually accessed as ``name in aNode``.
-
-.. method:: __setitem__(name, value)
-
-   Set the value of *name* to *value*.
-
-   This method is usually accessed as ``aNode[name] = value``.
-
-.. method:: __getitem__(name)
-
-   Returns the value of *name*, raises :exc:`KeyError` when
-   it cannot be found.
-
-   This method is usually accessed as ``value = aNode[name]``.
-
-.. method:: get(name[, default])
-
-   Returns the value of *name*, or the default value when it
-   cannot be found. The *default* is :data:`None` when not specified.
-
-.. method:: infoTuple()
-
-   Returns a tuple with information used in the :func:`repr`
-   output for the node. Subclasses can add additional informations
-   to the result.
-
-
-.. class:: AliasNode (name, node)
-
-   A node that represents an alias from a name to another node.
-
-   The value of attribute *graphident* for this node will be the
-   value of *name*, the other :class:`Node` attributed are
-   references to those attributed in *node*.
-
-.. class:: BadModule(identifier)
-
-   Base class for nodes that should be ignored for some reason
-
-.. class:: ExcludedModule(identifier)
-
-   A module that is explicitly excluded.
-
-.. class:: MissingModule(identifier)
-
-   A module that is imported but cannot be located.
-
-
-
-.. class:: Script(filename)
-
-   A python script.
-
-   .. data:: filename
-
-      The filename for the script
-
-.. class:: BaseModule(name[, filename[, path]])
-
-    The base class for actual modules. The *name* is
-    the possibly dotted module name, *filename* is the
-    filesystem path to the module and *path* is the
-    value of ``__path__`` for the module.
-
-.. data:: graphident
-
-   The name of the module
-
-.. data:: filename
-
-   The filesystem path to the module.
-
-.. data:: path
-
-   The value of ``__path__`` for this module.
-
-.. class:: BuiltinModule(name)
-
-   A built-in module (on in :data:`sys.builtin_module_names`).
-
-.. class:: SourceModule(name)
-
-   A module for which the python source code is available.
-
-.. class:: InvalidSourceModule(name)
-
-   A module for which the python source code is available, but where
-   that source code cannot be compiled (due to syntax errors).
-
-   This is a subclass of :class:`SourceModule`.
-
-   .. versionadded:: 0.12
-
-.. class:: CompiledModule(name)
-
-   A module for which only byte-code is available.
-
-.. class:: Package(name)
-
-   Represents a python package
-
-.. class:: NamespacePackage(name)
-
-   Represents a python namespace package.
-
-   This is a subclass of :class:`Package`.
-
-.. class:: Extension(name)
-
-   A native extension
-
-
-.. warning:: A number of other node types are defined in the module. Those modules aren't
-   used by modulegraph and will be removed in a future version.
-
-
-Edge data
----------
-
-The edges in a module graph by default contain information about the edge, represented
-by an instance of :class:`DependencyInfo`.
-
-.. class:: DependencyInfo(conditional, function, tryexcept, fromlist)
-
-   This class is a :func:`namedtuple <collections.namedtuple>` for representing
-   the information on a dependency between two modules.
-
-   All attributes can be used to deduce if a dependency is essential or not, and
-   are particularly useful when reporting on missing modules (dependencies on
-   :class:`MissingModule`).
-
-   .. data:: fromlist
-
-      A boolean that is true iff the target of the edge is named in the "import"
-      list of a "from" import ("from package import module").
-
-      When the target module is imported multiple times this attribute is false
-      unless all imports are in "import" list of a "from" import.
-
-   .. data:: function
-
-      A boolean that is true iff the import is done inside a function definition,
-      and is false for imports in module scope (or class scope for classes that
-      aren't definined in a function).
-
-   .. data:: tryexcept
-
-      A boolean that is true iff the import that is done in the "try" or "except"
-      block of a try statement (but not in the "else" block).
-
-   .. data:: conditional
-
-      A boolean that is true iff the import is done in either block of an "if"
-      statement.
-
-   When the target of the edge is imported multiple times the :data:`function`,
-   :data:`tryexcept` and :data:`conditional` attributes of all imports are
-   merged: when there is an import where all these attributes are false the
-   attributes are false, otherwise each attribute is set to true if it is
-   true for at least one of the imports.
-
-   For example, when a module is imported both in a try-except statement and
-   furthermore is imported in a function (in two separate statements),
-   both :data:`tryexcept` and :data:`function` will be true.  But if there
-   is a third unconditional toplevel import for that module as well all
-   three attributes are false.
-
-   .. warning::
-
-      All attributes but :data:`fromlist` will be false when the source of
-      a dependency is scanned from a byte-compiled module instead of a python
-      source file. The :data:`fromlist` attribute will stil be set correctly.
-
-Utility functions
------------------
-
-.. function:: find_module(name[, path])
-
-   A version of :func:`imp.find_module` that works with zipped packages (and other
-   :pep:`302` importers).
-
-.. function:: moduleInfoForPath(path)
-
-   Return the module name, readmode and type for the file at *path*, or
-   None if it doesn't seem to be a valid module (based on its name).
-
-.. function:: addPackagePath(packagename, path)
-
-   Add *path* to the value of ``__path__`` for the package named *packagename*.
-
-.. function:: replacePackage(oldname, newname)
-
-   Rename *oldname* to *newname* when it is found by the module finder. This
-   is used as a workaround for the hack that the ``_xmlplus`` package uses
-   to inject itself in the ``xml`` namespace.
-
-
diff --git a/catapult/telemetry/third_party/modulegraph/doc/util.rst b/catapult/telemetry/third_party/modulegraph/doc/util.rst
deleted file mode 100644
index 86427aa..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/util.rst
+++ /dev/null
@@ -1,31 +0,0 @@
-:mod:`modulegraph.util` --- Utilies functions
-=============================================
-
-.. module:: modulegraph.util
-   :synopsis: Utilitie functions
-
-
-.. function:: imp_find_module(name, path=None)
-
-   This function has the same interface as
-   :func:`imp.find_module`, but also works with
-   dotted names.
-
-.. function:: imp_walk(name)
-
-   yields the namepart and importer information
-   for every part of a dotted module name, and
-   raises :exc:`ImportError` when the *name*
-   cannot be found.
-
-   The result elements are tuples with two
-   elements, the first is a module name,
-   the second is the result for :func:`imp.find_module`
-   for that module (taking into account :pep:`302`
-   importers)
-
-   .. deprecated:: 0.10
-
-.. function:: guess_encoding(fp)
-
-   Returns the encoding of a python source file.
diff --git a/catapult/telemetry/third_party/modulegraph/doc/zipio.rst b/catapult/telemetry/third_party/modulegraph/doc/zipio.rst
deleted file mode 100644
index dd227b8..0000000
--- a/catapult/telemetry/third_party/modulegraph/doc/zipio.rst
+++ /dev/null
@@ -1,68 +0,0 @@
-:mod:`modulegraph.zipio` --- Read-only filesystem access
-========================================================
-
-.. module:: modulegraph.zipio
-   :synopsis: Read-only filesystem access with ZIP support
-
-This module contains a number of functions that mirror functions found
-in :mod:`os` and :mod:`os.path`, but have support for data inside
-zipfiles as well as regular filesystem objects.
-
-The *path* argument of all functions below can refer to an object
-on the filesystem, but can also refer to an entry inside a zipfile. In
-the latter case, a prefix of *path* will be the name of zipfile while
-the rest refers to an object in that zipfile. As an example, when
-``somepath/mydata.zip`` is a zipfile the path ``somepath/mydata.zip/somefile.txt``
-will refer to ``somefile.txt`` inside the zipfile.
-
-.. function:: open(path[, mode])
-
-   Open a file, like :func:`the built-in open function <__builtin__.open>`.
-
-   The *mode* defaults to ``"r"`` and must be either ``"r"`` or ``"rb"``.
-
-.. function:: listdir(path)
-
-   List the contents of a directory, like :func:`os.listdir`.
-
-
-.. function:: isfile(path)
-
-   Returns true if *path* exists and refers to a file.
-
-   Raises IOError when *path* doesn't exist at all.
-
-   Based on :func:`os.path.isfile`
-
-
-.. function:: isdir(path)
-
-   Returns true if *path* exists and refers to a directory.
-
-   Raises IOError when *path* doesn't exist at all.
-
-   Based on :func:`os.path.isdir`
-
-
-.. function:: islink(path)
-
-   Returns true if *path* exists and refers to a symbolic link.
-
-   Raises IOError when *path* doesn't exist at all.
-
-   Based on :func:`os.path.islink`
-
-
-.. function:: readlink(path)
-
-   Returns the contents of a symbolic link, like :func:`os.readlink`.
-
-.. function:: getmtime(path)
-
-   Returns the last modifiction time of a file or directory, like
-   :func:`os.path.getmtime`.
-
-.. function:: getmode(path)
-
-   Returns the UNIX file mode for a file or directory, like the
-   *st_mode* attribute in the result of :func:`os.stat`.
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/PKG-INFO
deleted file mode 100644
index bfd4006..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/PKG-INFO
+++ /dev/null
@@ -1,337 +0,0 @@
-Metadata-Version: 1.1
-Name: modulegraph
-Version: 0.12.1
-Summary: Python module dependency analysis tool
-Home-page: http://bitbucket.org/ronaldoussoren/modulegraph
-Author: Ronald Oussoren
-Author-email: ronaldoussoren@mac.com
-License: MIT
-Download-URL: http://pypi.python.org/pypi/modulegraph
-Description: modulegraph determines a dependency graph between Python modules primarily
-        by bytecode analysis for import statements.
-        
-        modulegraph uses similar methods to modulefinder from the standard library,
-        but uses a more flexible internal representation, has more extensive 
-        knowledge of special cases, and is extensible.
-        
-        
-        Release history
-        ===============
-        
-        0.12.1
-        ------
-        
-        * Issue #25: Complex python files could cause an "maximum recursion depth exceeded"
-          exception due to using stack-based recursion to walk the module AST.
-        
-        
-        0.12
-        ----
-        
-        * Added 'modulegraph.modulegraph.InvalidSourceModule'. This graph node is
-          used for Python source modules that cannot be compiled (for example because
-          they contain syntax errors).
-        
-          This is primarily useful for being able to create a graph for packages
-          that have python 2.x or python 3.x compatibility in separate modules that
-          contain code that isn't valid in the "other" python version.
-        
-        * Added 'modulegraph.modulegraph.InvalidCompiledModule'. This graph node
-          is used for Python bytecode modules that cannot be loaded.
-        
-        * Added 'modulegraph.modulegraph.NamespacePackage'.
-        
-          Patch by bitbucket user htgoebel.
-        
-        * No longer add a MissingModule node to the graph for 'collections.defaultdict'
-          when using 'from collections import defaultdict' ('collections.defaultdict'
-          is an attribute of 'collections', not a submodule).
-        
-        * Fixed typo in ModuleGraph.getReferences()
-        
-        * Added ModuleGraph.getReferers(tonode). This methods yields the
-          nodes that are referencing *tonode* (the reverse of getReferences)
-        
-        * The graph will no longer contain MissingModule nodes when using 'from ... import name' to
-          import a global variable in a python module.
-        
-          There will still be MissingModule nodes for global variables in C extentions, and
-          for 'from missing import name' when 'missing' is itself a MissingModule.
-        
-        * Issue #18: Don't assume that a PEP 302 loader object has a ``path`` attribute. That
-          attribute is not documented and is not always present.
-        
-        0.11.2
-        ------
-        
-        *
-        
-        0.11.1
-        ------
-        
-        * Issue #145: Don't exclude the platform specific 'path' modules (like ntpath)
-        
-        0.11
-        ----
-        
-        This is a feature release
-        
-        Features
-        ........
-        
-        * Hardcode knowlegde about the compatibility aliases in the email
-          module (for python 2.5 upto 3.0).
-        
-          This makes it possible to remove a heavy-handed recipe from py2app.
-        
-        * Added ``modegraph.zipio.getmode`` to fetch the Unix file mode
-          for a file.
-        
-        * Added some handy methods to ``modulegraph.modulegraph.ModuleGraph``.
-        
-        0.10.5
-        ------
-        
-        This is a bugfix release
-        
-        * Don't look at the file extension to determine the file type
-          in modulegraph.find_modules.parse_mf_results, but use the
-          class of the item.
-        
-        * Issue #13: Improved handing of bad relative imports
-          ("from .foo import bar"), these tended to raise confusing errors and
-          are now handled like any other failed import.
-        
-        0.10.4
-        ------
-        
-        This is a bugfix release
-        
-        * There were no 'classifiers' in the package metadata due to a bug
-          in setup.py.
-        
-        0.10.3
-        ------
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * ``modulegraph.find.modules.parse_mf_results`` failed when the main script of
-          a py2app module didn't have a file name ending in '.py'.
-        
-        0.10.2
-        ------
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * Issue #12: modulegraph would sometimes find the wrong package *__init__*
-          module due to using the wrong search method. One easy way to reproduce the
-          problem was to have a toplevel module named *__init__*.
-        
-          Reported by Kentzo.
-        
-        0.10.1
-        ------
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * Issue #11: creating xrefs and dotty graphs from modulegraphs (the --xref
-          and --graph options of py2app) didn't work with python 3 due to use of
-          APIs that aren't available in that version of python.
-        
-          Reported by Andrew Barnert.
-        
-        
-        0.10
-        ----
-        
-        This is a minor feature release
-        
-        Features
-        ........
-        
-        * ``modulegraph.find_modules.find_needed_modules`` claimed to automaticly
-          include subpackages for the "packages" argument as well, but that code
-          didn't work at all.
-        
-        * Issue #9: The modulegraph script is deprecated, use
-          "python -mmodulegraph" instead.
-        
-        * Issue #10: Ensure that the result of "zipio.open" can be used
-          in a with statement (that is, ``with zipio.open(...) as fp``.
-        
-        * No longer use "2to3" to support Python 3.
-        
-          Because of this modulegraph now supports Python 2.6
-          and later.
-        
-        * Slightly improved HTML output, which makes it easier
-          to manipulate the generated HTML using JavaScript.
-        
-          Patch by anatoly techtonik.
-        
-        * Ensure modulegraph works with changes introduced after
-          Python 3.3b1.
-        
-        * Implement support for PEP 420 ("Implicit namespace packages")
-          in Python 3.3.
-        
-        * ``modulegraph.util.imp_walk`` is deprecated and will be
-          removed in the next release of this package.
-        
-        Bugfixes
-        ........
-        
-        * The module graph was incomplete, and generated incorrect warnings
-          along the way, when a subpackage contained import statements for
-          submodules.
-        
-          An example of this is ``sqlalchemy.util``, the ``__init__.py`` file
-          for this package contains imports of modules in that modules using
-          the classic relative import syntax (that is ``import compat`` to
-          import ``sqlalchemy.util.compat``). Until this release modulegraph
-          searched the wrong path to locate these modules (and hence failed
-          to find them).
-        
-        
-        0.9.2
-        -----
-        
-        This is a bugfix release
-        
-        Bugfixes
-        ........
-        
-        * The 'packages' option to modulegraph.find_modules.find_modules ignored
-          the search path argument but always used the default search path.
-        
-        * The 'imp_find_modules' function in modulegraph.util has an argument 'path',
-          this was a string in previous release and can now also be a sequence.
-        
-        * Don't crash when a module on the 'includes' list doesn't exist, but warn
-          just like for missing 'packages' (modulegraph.find_modules.find_modules)
-        
-        0.9.1
-        -----
-        
-        This is a bugfix release
-        
-        Bug fixes
-        .........
-        
-        - Fixed the name of nodes imports in packages where the first element of
-          a dotted name can be found but the rest cannot. This used to create
-          a MissingModule node for the dotted name in the global namespace instead
-          of relative to the package.
-        
-          That is, given a package "pkg" with submodule "sub" if the "__init__.py"
-          of "pkg" contains "import sub.nomod" we now create a MissingModule node
-          for "pkg.sub.nomod" instead of "sub.nomod".
-        
-          This fixes an issue with including the crcmod package in application
-          bundles, first reported on the pythonmac-sig mailinglist by
-          Brendan Simon.
-        
-        0.9
-        ---
-        
-        This is a minor feature release
-        
-        
-        Features:
-        
-        - Documentation is now generated using `sphinx <http://pypi.python.org/pypi/sphinx>`_
-          and can be viewed at <http://packages.python.org/modulegraph>.
-        
-          The documention is very rough at this moment and in need of reorganisation and
-          language cleanup. I've basiclly writting the current version by reading the code
-          and documenting what it does, the order in which classes and methods are document
-          is therefore not necessarily the most useful.
-        
-        - The repository has moved to bitbucket
-        
-        - Renamed ``modulegraph.modulegraph.AddPackagePath`` to ``addPackagePath``,
-          likewise ``ReplacePackage`` is now ``replacePackage``. The old name is still
-          available, but is deprecated and will be removed before the 1.0 release.
-        
-        - ``modulegraph.modulegraph`` contains two node types that are unused and
-          have unclear semantics: ``FlatPackage`` and ``ArchiveModule``. These node
-          types are deprecated and will be removed before 1.0 is released.
-        
-        - Added a simple commandline tool (``modulegraph``) that will print information
-          about the dependency graph of a script.
-        
-        - Added a module (``zipio``) for dealing with paths that may refer to entries
-          inside zipfiles (such as source paths referring to modules in zipped eggfiles).
-        
-          With this addition ``modulegraph.modulegraph.os_listdir`` is deprecated and
-          it will be removed before the 1.0 release.
-        
-        Bug fixes:
-        
-        - The ``__cmp__`` method of a Node no longer causes an exception
-          when the compared-to object is not a Node. Patch by Ivan Kozik.
-        
-        - Issue #1: The initialiser for ``modulegraph.ModuleGraph`` caused an exception
-          when an entry on the path (``sys.path``) doesn't actually exist.
-        
-          Fix by "skurylo", testcase by Ronald.
-        
-        - The code no longer worked with python 2.5, this release fixes that.
-        
-        - Due to the switch to mercurial setuptools will no longer include
-          all required files. Fixed by adding a MANIFEST.in file
-        
-        - The method for printing a ``.dot`` representation of a ``ModuleGraph``
-          works again.
-        
-        
-        0.8.1
-        -----
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - ``from __future__ import absolute_import`` is now supported
-        
-        - Relative imports (``from . import module``) are now supported
-        
-        - Add support for namespace packages when those are installed
-          using option ``--single-version-externally-managed`` (part
-          of setuptools/distribute)
-        
-        0.8
-        ---
-        
-        This is a minor feature release
-        
-        Features:
-        
-        - Initial support for Python 3.x
-        
-        - It is now possible to run the test suite
-          using ``python setup.py test``.
-        
-          (The actual test suite is still fairly minimal though)
-        
-Keywords: import,,dependencies
-Platform: any
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Programming Language :: Python
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Programming Language :: Python :: 3.4
-Classifier: Topic :: Software Development :: Libraries :: Python Modules
-Classifier: Topic :: Software Development :: Build Tools
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/SOURCES.txt
deleted file mode 100644
index 3409094..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,280 +0,0 @@
-MANIFEST.in
-README.txt
-setup.cfg
-setup.py
-doc/Makefile
-doc/changelog.rst
-doc/commandline.rst
-doc/conf.py
-doc/find_modules.rst
-doc/index.rst
-doc/license.rst
-doc/modulegraph.rst
-doc/util.rst
-doc/zipio.rst
-doc/_build/doctrees/changelog.doctree
-doc/_build/doctrees/commandline.doctree
-doc/_build/doctrees/environment.pickle
-doc/_build/doctrees/find_modules.doctree
-doc/_build/doctrees/index.doctree
-doc/_build/doctrees/license.doctree
-doc/_build/doctrees/modulegraph.doctree
-doc/_build/doctrees/util.doctree
-doc/_build/doctrees/zipio.doctree
-doc/_build/html/.buildinfo
-doc/_build/html/changelog.html
-doc/_build/html/commandline.html
-doc/_build/html/find_modules.html
-doc/_build/html/genindex.html
-doc/_build/html/index.html
-doc/_build/html/license.html
-doc/_build/html/modulegraph.html
-doc/_build/html/objects.inv
-doc/_build/html/py-modindex.html
-doc/_build/html/search.html
-doc/_build/html/searchindex.js
-doc/_build/html/util.html
-doc/_build/html/zipio.html
-doc/_build/html/_sources/changelog.txt
-doc/_build/html/_sources/commandline.txt
-doc/_build/html/_sources/find_modules.txt
-doc/_build/html/_sources/index.txt
-doc/_build/html/_sources/license.txt
-doc/_build/html/_sources/modulegraph.txt
-doc/_build/html/_sources/util.txt
-doc/_build/html/_sources/zipio.txt
-doc/_build/html/_static/ajax-loader.gif
-doc/_build/html/_static/basic.css
-doc/_build/html/_static/comment-bright.png
-doc/_build/html/_static/comment-close.png
-doc/_build/html/_static/comment.png
-doc/_build/html/_static/doctools.js
-doc/_build/html/_static/down-pressed.png
-doc/_build/html/_static/down.png
-doc/_build/html/_static/file.png
-doc/_build/html/_static/jquery-1.11.1.js
-doc/_build/html/_static/jquery.js
-doc/_build/html/_static/minus.png
-doc/_build/html/_static/nature.css
-doc/_build/html/_static/plus.png
-doc/_build/html/_static/pygments.css
-doc/_build/html/_static/searchtools.js
-doc/_build/html/_static/underscore-1.3.1.js
-doc/_build/html/_static/underscore.js
-doc/_build/html/_static/up-pressed.png
-doc/_build/html/_static/up.png
-doc/_build/html/_static/websupport.js
-modulegraph/__init__.py
-modulegraph/__main__.py
-modulegraph/_compat.py
-modulegraph/find_modules.py
-modulegraph/modulegraph.py
-modulegraph/util.py
-modulegraph/zipio.py
-modulegraph.egg-info/PKG-INFO
-modulegraph.egg-info/SOURCES.txt
-modulegraph.egg-info/dependency_links.txt
-modulegraph.egg-info/entry_points.txt
-modulegraph.egg-info/requires.txt
-modulegraph.egg-info/top_level.txt
-modulegraph.egg-info/zip-safe
-modulegraph_tests/__init__.py
-modulegraph_tests/test_basic.py
-modulegraph_tests/test_edge_data.py
-modulegraph_tests/test_explicit_packages.py
-modulegraph_tests/test_implies.py
-modulegraph_tests/test_import_from_init.py
-modulegraph_tests/test_imports.py
-modulegraph_tests/test_modulegraph.py
-modulegraph_tests/test_pep420_nspkg.py
-modulegraph_tests/test_pycompat_pkg.py
-modulegraph_tests/test_relimport2.py
-modulegraph_tests/test_setuptools_nspkg.py
-modulegraph_tests/test_util.py
-modulegraph_tests/test_zipio.py
-modulegraph_tests/testdata/script
-modulegraph_tests/testdata/syspath.egg
-modulegraph_tests/testdata/syspath.zip
-modulegraph_tests/testdata/test.egg
-modulegraph_tests/testdata/test.txt
-modulegraph_tests/testdata/zipped.egg
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6-nspkg.pth
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/namedpkg/slave.py
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6-nspkg.pth
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg/parent.py
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5-nspkg.pth
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/namedpkg/slave.py
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5-nspkg.pth
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg/parent.py
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5-nspkg.pth
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/namedpkg/slave.py
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5-nspkg.pth
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg/parent.py
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/src/install.py
-modulegraph_tests/testdata/nspkg/src/child/setup.py
-modulegraph_tests/testdata/nspkg/src/child/namedpkg/__init__.py
-modulegraph_tests/testdata/nspkg/src/child/namedpkg/slave.py
-modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/top_level.txt
-modulegraph_tests/testdata/nspkg/src/parent/setup.py
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg/__init__.py
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg/parent.py
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/PKG-INFO
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/SOURCES.txt
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/dependency_links.txt
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/namespace_packages.txt
-modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/top_level.txt
-modulegraph_tests/testdata/subdir/file1.txt
-modulegraph_tests/testdata/subdir/file2.txt
-modulegraph_tests/testdata/syspath/myext.pyd
-modulegraph_tests/testdata/syspath/mymodule.py
-modulegraph_tests/testdata/syspath/mymodule3.py
-modulegraph_tests/testdata/syspath/mypkg/__init__.py
-modulegraph_tests/testpkg-compatmodule/pkg/__init__.py
-modulegraph_tests/testpkg-compatmodule/pkg/api.py
-modulegraph_tests/testpkg-compatmodule/pkg/api2.py
-modulegraph_tests/testpkg-compatmodule/pkg/api3.py
-modulegraph_tests/testpkg-edgedata/function_class_existing.py
-modulegraph_tests/testpkg-edgedata/function_conditional_existing.py
-modulegraph_tests/testpkg-edgedata/function_conditional_import2_existing.py
-modulegraph_tests/testpkg-edgedata/function_conditional_import_existing.py
-modulegraph_tests/testpkg-edgedata/function_existing.py
-modulegraph_tests/testpkg-edgedata/function_import2_existing.py
-modulegraph_tests/testpkg-edgedata/function_import_existing.py
-modulegraph_tests/testpkg-edgedata/script.py
-modulegraph_tests/testpkg-edgedata/script_from_import.py
-modulegraph_tests/testpkg-edgedata/script_multi_import.py
-modulegraph_tests/testpkg-edgedata/toplevel_class_existing.py
-modulegraph_tests/testpkg-edgedata/toplevel_conditional_existing.py
-modulegraph_tests/testpkg-edgedata/toplevel_conditional_import2_existing.py
-modulegraph_tests/testpkg-edgedata/toplevel_conditional_import_existing.py
-modulegraph_tests/testpkg-edgedata/toplevel_existing.py
-modulegraph_tests/testpkg-edgedata/toplevel_import2_existing.py
-modulegraph_tests/testpkg-edgedata/toplevel_import_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/__init__.py
-modulegraph_tests/testpkg-edgedata/pkg/function_class_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/function_conditional_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import2_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/function_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/function_import2_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/function_import_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_class_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import2_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_import2_existing.py
-modulegraph_tests/testpkg-edgedata/pkg/toplevel_import_existing.py
-modulegraph_tests/testpkg-import-from-init/script.py
-modulegraph_tests/testpkg-import-from-init/pkg/__init__.py
-modulegraph_tests/testpkg-import-from-init/pkg/subpkg/__init__.py
-modulegraph_tests/testpkg-import-from-init/pkg/subpkg/_collections.py
-modulegraph_tests/testpkg-import-from-init/pkg/subpkg/compat.py
-modulegraph_tests/testpkg-import-from-init/pkg2/__init__.py
-modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/__init__.py
-modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/_collections.py
-modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/compat.py
-modulegraph_tests/testpkg-packages/main_script.py
-modulegraph_tests/testpkg-packages/pkg/__init__.py
-modulegraph_tests/testpkg-packages/pkg/sub3.py
-modulegraph_tests/testpkg-packages/pkg/sub1/__init__.py
-modulegraph_tests/testpkg-packages/pkg/sub1/modA.py
-modulegraph_tests/testpkg-packages/pkg/sub2/__init__.py
-modulegraph_tests/testpkg-packages/pkg/sub2/mod.py
-modulegraph_tests/testpkg-pep420-namespace/path1/package/sub2.py
-modulegraph_tests/testpkg-pep420-namespace/path2/package/sub1.py
-modulegraph_tests/testpkg-pep420-namespace/path2/package/nspkg/mod.py
-modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/__init__.py
-modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/sub.py
-modulegraph_tests/testpkg-regr1/main_script.py
-modulegraph_tests/testpkg-regr1/pkg/__init__.py
-modulegraph_tests/testpkg-regr1/pkg/a.py
-modulegraph_tests/testpkg-regr1/pkg/b.py
-modulegraph_tests/testpkg-regr2/main_script.py
-modulegraph_tests/testpkg-regr2/pkg/__init__.py
-modulegraph_tests/testpkg-regr2/pkg/base.py
-modulegraph_tests/testpkg-regr2/pkg/pkg.py
-modulegraph_tests/testpkg-regr3/script.py
-modulegraph_tests/testpkg-regr3/mypkg/__init__.py
-modulegraph_tests/testpkg-regr3/mypkg/distutils/__init__.py
-modulegraph_tests/testpkg-regr3/mypkg/distutils/ccompiler.py
-modulegraph_tests/testpkg-regr4/script.py
-modulegraph_tests/testpkg-regr4/pkg/__init__.py
-modulegraph_tests/testpkg-regr4/pkg/core/__init__.py
-modulegraph_tests/testpkg-regr4/pkg/core/callables.py
-modulegraph_tests/testpkg-regr4/pkg/core/listener.py
-modulegraph_tests/testpkg-regr4/pkg/core/listenerimpl.py
-modulegraph_tests/testpkg-regr5/__init__.py
-modulegraph_tests/testpkg-regr5/script.py
-modulegraph_tests/testpkg-regr6/module.py
-modulegraph_tests/testpkg-regr6/script.py
-modulegraph_tests/testpkg-relimport/mod.py
-modulegraph_tests/testpkg-relimport/script.py
-modulegraph_tests/testpkg-relimport/pkg/__init__.py
-modulegraph_tests/testpkg-relimport/pkg/mod.py
-modulegraph_tests/testpkg-relimport/pkg/oldstyle.py
-modulegraph_tests/testpkg-relimport/pkg/relative.py
-modulegraph_tests/testpkg-relimport/pkg/relimport.py
-modulegraph_tests/testpkg-relimport/pkg/toplevel.py
-modulegraph_tests/testpkg-relimport/pkg/sub2/__init__.py
-modulegraph_tests/testpkg-relimport/pkg/sub2/mod.py
-modulegraph_tests/testpkg-relimport/pkg/subpkg/__init__.py
-modulegraph_tests/testpkg-relimport/pkg/subpkg/mod2.py
-modulegraph_tests/testpkg-relimport/pkg/subpkg/relative.py
-modulegraph_tests/testpkg-relimport/pkg/subpkg/relative2.py
-modulegraph_tests/testpkg-relimport2/toplevel.py
-modulegraph_tests/testpkg-relimport2/pkg/__init__.py
-modulegraph_tests/testpkg-relimport2/pkg/mod1.py
-modulegraph_tests/testpkg-relimport2/pkg/mod2.py
-modulegraph_tests/testpkg-relimport2/pkg/mod3.py
-modulegraph_tests/testpkg-relimport2/pkg/sub/__init__.py
-modulegraph_tests/testpkg-setuptools-namespace/setup.py
-modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/__init__.py
-modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/module.py
-modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/__init__.py
-modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/sub.py
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/__init__.py
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/module.py
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/PKG-INFO
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/SOURCES.txt
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/dependency_links.txt
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/namespace_packages.txt
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/not-zip-safe
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/top_level.txt
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/__init__.py
-modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/sub.py
-scripts/extract_implies.py
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/entry_points.txt b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/entry_points.txt
deleted file mode 100644
index 9fc3791..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/entry_points.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-[console_scripts]
-modulegraph = modulegraph.__main__:main
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/requires.txt b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/requires.txt
deleted file mode 100644
index dde6882..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/requires.txt
+++ /dev/null
@@ -1 +0,0 @@
-altgraph >= 0.12
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/top_level.txt
deleted file mode 100644
index e0e1b8f..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-modulegraph
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/zip-safe b/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/zip-safe
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph.egg-info/zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph/__init__.py
deleted file mode 100644
index 7c85619..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-import pkg_resources
-__version__ = pkg_resources.require('modulegraph')[0].version
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/__main__.py b/catapult/telemetry/third_party/modulegraph/modulegraph/__main__.py
deleted file mode 100644
index 2a84cda..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/__main__.py
+++ /dev/null
@@ -1,76 +0,0 @@
-from __future__ import print_function
-import sys
-import os
-import optparse
-import textwrap
-from .modulegraph import ModuleGraph
-
-def main():
-    # Parse command line
-    usage = textwrap.dedent('''\
-        Usage:
-            modulegraph [options] scriptfile ...
-
-        Valid options:
-        * -d: Increase debug level
-        * -q: Clear debug level
-
-        * -m: arguments are module names, not script files
-        * -x name: Add 'name' to the excludes list
-        * -p name: Add 'name' to the module search path
-
-        * -g: Output a .dot graph
-        * -h: Output a html file
-    ''')
-    parser = optparse.OptionParser(usage=usage, add_help_option=False)
-    parser.add_option('-d', action='count', dest='debug', default=1)
-    parser.add_option('-q', action='store_const', dest='debug', const=0)
-
-    parser.add_option('-m', action='store_true', dest='domods', default=False)
-    parser.add_option('-x', action='append', dest='excludes', default=[])
-    parser.add_option('-p', action='append', dest='addpath', default=[])
-
-    parser.add_option('-g', action='store_const', dest='output', const='dot')
-    parser.add_option('-h', action='store_const', dest='output', const='html')
-    opts, args = parser.parse_args()
-
-    if not args:
-        print("No script specified", file=sys.stderr)
-        print(usage, file=sys.stderr)
-        sys.exit(1)
-
-    script = args[0]
-
-    # Set the path based on sys.path and the script directory
-    path = sys.path[:]
-    path[0] = os.path.dirname(script)
-    path = opts.addpath + path
-    if opts.debug > 1:
-        print("path:", file=sys.stderr)
-        for item in path:
-            print("   ", repr(item), file=sys.stderr)
-
-    # Create the module finder and turn its crank
-    mf = ModuleGraph(path, excludes=opts.excludes, debug=opts.debug)
-    for arg in args:
-        if opts.domods:
-            if arg[-2:] == '.*':
-                mf.import_hook(arg[:-2], None, ["*"])
-            else:
-                mf.import_hook(arg)
-        else:
-            mf.run_script(arg)
-    if opts.output == 'dot':
-        mf.graphreport()
-    elif opts.output == 'html':
-        mf.create_xref()
-    else:
-        mf.report()
-    sys.exit(0)
-
-
-if __name__ == '__main__':
-    try:
-        main()
-    except KeyboardInterrupt:
-        print("\n[interrupt]")
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/_compat.py b/catapult/telemetry/third_party/modulegraph/modulegraph/_compat.py
deleted file mode 100644
index aa0fc02..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/_compat.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import sys
-
-if sys.version_info[0] == 2:
-    def Bchr(value):
-        return chr(value)
-
-else:
-    def Bchr(value):
-        return value
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/find_modules.py b/catapult/telemetry/third_party/modulegraph/modulegraph/find_modules.py
deleted file mode 100644
index fee8c17..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/find_modules.py
+++ /dev/null
@@ -1,366 +0,0 @@
-"""
-modulegraph.find_modules - High-level module dependency finding interface
-=========================================================================
-
-History
-........
-
-Originally (loosely) based on code in py2exe's build_exe.py by Thomas Heller.
-"""
-from __future__ import absolute_import
-
-import sys
-import os
-import imp
-import warnings
-
-import modulegraph.modulegraph as modulegraph
-from modulegraph.modulegraph import Alias, Script, Extension
-from modulegraph.util import imp_find_module
-
-__all__ = [
-    'find_modules', 'parse_mf_results'
-]
-
-def get_implies():
-    result = {
-        # imports done from builtin modules in C code (untrackable by modulegraph)
-        "_curses":      ["curses"],
-        "posix":        ["resource"],
-        "gc":           ["time"],
-        "time":         ["_strptime"],
-        "datetime":     ["time"],
-        "MacOS":        ["macresource"],
-        "cPickle":      ["copy_reg", "cStringIO"],
-        "parser":       ["copy_reg"],
-        "codecs":       ["encodings"],
-        "cStringIO":    ["copy_reg"],
-        "_sre":         ["copy", "string", "sre"],
-        "zipimport":    ["zlib"],
-
-        # Python 3.2:
-        "_datetime":    ["time", "_strptime"],
-        "_json":        ["json.decoder"],
-        "_pickle":      ["codecs", "copyreg", "_compat_pickle"],
-        "_posixsubprocess": ["gc"],
-        "_ssl":         ["socket"],
-
-        # Python 3.3:
-        "_elementtree": ["copy", "xml.etree.ElementPath" ],
-
-        # mactoolboxglue can do a bunch more of these
-        # that are far harder to predict, these should be tracked
-        # manually for now.
-
-        # this isn't C, but it uses __import__
-        "anydbm":       ["dbhash", "gdbm", "dbm", "dumbdbm", "whichdb"],
-        # package aliases
-        "wxPython.wx":  Alias('wx'),
-
-    }
-
-    if sys.version_info[0] == 3:
-        result["_sre"] = ["copy", "re"]
-        result["parser"] = ["copyreg"]
-
-        # _frozen_importlib is part of the interpreter itself
-        result["_frozen_importlib"] = None
-
-    if sys.version_info[0] == 2 and sys.version_info[1] >= 5:
-        result.update({
-            "email.base64MIME":         Alias("email.base64mime"),
-            "email.Charset":            Alias("email.charset"),
-            "email.Encoders":           Alias("email.encoders"),
-            "email.Errors":             Alias("email.errors"),
-            "email.Feedparser":         Alias("email.feedParser"),
-            "email.Generator":          Alias("email.generator"),
-            "email.Header":             Alias("email.header"),
-            "email.Iterators":          Alias("email.iterators"),
-            "email.Message":            Alias("email.message"),
-            "email.Parser":             Alias("email.parser"),
-            "email.quopriMIME":         Alias("email.quoprimime"),
-            "email.Utils":              Alias("email.utils"),
-            "email.MIMEAudio":          Alias("email.mime.audio"),
-            "email.MIMEBase":           Alias("email.mime.base"),
-            "email.MIMEImage":          Alias("email.mime.image"),
-            "email.MIMEMessage":        Alias("email.mime.message"),
-            "email.MIMEMultipart":      Alias("email.mime.multipart"),
-            "email.MIMENonMultipart":   Alias("email.mime.nonmultipart"),
-            "email.MIMEText":           Alias("email.mime.text"),
-        })
-
-    if sys.version_info[:2] >= (2, 5):
-        result["_elementtree"] = ["pyexpat"]
-
-        import xml.etree
-        files = os.listdir(xml.etree.__path__[0])
-        for fn in files:
-            if fn.endswith('.py') and fn != "__init__.py":
-                result["_elementtree"].append("xml.etree.%s"%(fn[:-3],))
-
-    if sys.version_info[:2] >= (2, 6):
-        result['future_builtins'] = ['itertools']
-
-    # os.path is an alias for a platform specific submodule,
-    # ensure that the graph shows this.
-    result['os.path'] = Alias(os.path.__name__)
-
-
-    return result
-
-def parse_mf_results(mf):
-    """
-    Return two lists: the first one contains the python files in the graph,
-    the second the C extensions.
-
-    :param mf: a :class:`modulegraph.modulegraph.ModuleGraph` instance
-    """
-    #for name, imports in get_hidden_imports().items():
-    #    if name in mf.modules.keys():
-    #        for mod in imports:
-    #            mf.import_hook(mod)
-
-    # Retrieve modules from modulegraph
-    py_files = []
-    extensions = []
-
-    for item in mf.flatten():
-        # There may be __main__ modules (from mf.run_script), but
-        # we don't need it in the zipfile we build.
-        if item.identifier == "__main__":
-            continue
-        src = item.filename
-        if src and src != '-':
-            if isinstance(item, Script):
-                # Scripts are python files
-                py_files.append(item)
-
-            elif isinstance(item, Extension):
-                extensions.append(item)
-
-            else:
-                py_files.append(item)
-
-    # sort on the file names, the output is nicer to read
-    py_files.sort(key=lambda v: v.filename)
-    extensions.sort(key=lambda v: v.filename)
-    return py_files, extensions
-
-
-def plat_prepare(includes, packages, excludes):
-    # used by Python itself
-    includes.update(["warnings", "unicodedata", "weakref"])
-
-    #if os.uname()[0] != 'java':
-        # Jython specific imports in the stdlib:
-        #excludes.update([
-        #    'java.lang',
-        #    'org.python.core',
-        #])
-
-    if not sys.platform.startswith('irix'):
-        excludes.update([
-            'AL',
-            'sgi',
-            'vms_lib',
-        ])
-
-    if not sys.platform in ('mac', 'darwin'):
-        # XXX - this doesn't look nearly complete
-        excludes.update([
-            'Audio_mac',
-            'Carbon.File',
-            'Carbon.Folder',
-            'Carbon.Folders',
-            'EasyDialogs',
-            'MacOS',
-            'macfs',
-            'macostools',
-            #'macpath',
-            '_scproxy',
-        ])
-
-    if not sys.platform == 'win32':
-        # only win32
-        excludes.update([
-            #'ntpath',
-            'nturl2path',
-            'win32api',
-            'win32con',
-            'win32event',
-            'win32evtlogutil',
-            'win32evtlog',
-            'win32file',
-            'win32gui',
-            'win32pipe',
-            'win32process',
-            'win32security',
-            'pywintypes',
-            'winsound',
-            'win32',
-            '_winreg',
-            '_winapi',
-            'msvcrt',
-            'winreg',
-            '_subprocess',
-         ])
-
-    if not sys.platform == 'riscos':
-        excludes.update([
-             'riscosenviron',
-             #'riscospath',
-             'rourl2path',
-          ])
-
-    if not sys.platform == 'dos' or sys.platform.startswith('ms-dos'):
-        excludes.update([
-            'dos',
-        ])
-
-    if not sys.platform == 'os2emx':
-        excludes.update([
-            #'os2emxpath',
-            '_emx_link',
-        ])
-
-    excludes.update(set(['posix', 'nt', 'os2', 'mac', 'ce', 'riscos']) - set(sys.builtin_module_names))
-
-    # Carbon.Res depends on this, but the module hasn't been present
-    # for a while...
-    excludes.add('OverrideFrom23')
-    excludes.add('OverrideFrom23._Res')
-
-    # import trickery in the dummy_threading module (stdlib)
-    excludes.add('_dummy_threading')
-
-    try:
-        imp_find_module('poll')
-    except ImportError:
-        excludes.update([
-            'poll',
-        ])
-
-def find_needed_modules(mf=None, scripts=(), includes=(), packages=(), warn=warnings.warn):
-    if mf is None:
-        mf = modulegraph.ModuleGraph()
-    # feed Modulefinder with everything, and return it.
-
-    for path in scripts:
-        mf.run_script(path)
-
-    for mod in includes:
-        try:
-            if mod[-2:] == '.*':
-                mf.import_hook(mod[:-2], None, ['*'])
-            else:
-                mf.import_hook(mod)
-        except ImportError:
-            warn("No module named %s"%(mod,))
-
-    for f in packages:
-        # If modulegraph has seen a reference to the package, then
-        # we prefer to believe that (imp_find_module doesn't seem to locate
-        # sub-packages)
-        m = mf.findNode(f)
-        if m is not None:
-            path = m.packagepath[0]
-        else:
-            # Find path of package
-            # TODO: use imp_find_module_or_importer
-            try:
-                path = imp_find_module(f, mf.path)[1]
-            except ImportError:
-                warn("No package named %s" % f)
-                continue
-
-        # walk the path to find subdirs containing __init__.py files
-        # scan the results (directory of __init__.py files)
-        # first trim the path (of the head package),
-        # then convert directory name in package name,
-        # finally push into modulegraph.
-        # FIXME:
-        # 1) Needs to be adjusted for namespace packages in python 3.3
-        # 2) Code is fairly dodgy and needs better tests
-        for (dirpath, dirnames, filenames) in os.walk(path):
-            if '__init__.py' in filenames and dirpath.startswith(path):
-                package = f + '.' + dirpath[len(path)+1:].replace(os.sep, '.')
-                if package.endswith('.'):
-                    package = package[:-1]
-                m = mf.import_hook(package, None, ["*"])
-            else:
-                # Exclude subtrees that aren't packages
-                dirnames[:] = []
-
-
-    return mf
-
-#
-# resource constants
-#
-PY_SUFFIXES = ['.py', '.pyw', '.pyo', '.pyc']
-C_SUFFIXES = [
-    _triple[0] for _triple in imp.get_suffixes()
-    if _triple[2] == imp.C_EXTENSION
-]
-
-#
-# side-effects
-#
-
-def _replacePackages():
-    REPLACEPACKAGES = {
-        '_xmlplus':     'xml',
-    }
-    for k,v in REPLACEPACKAGES.items():
-        modulegraph.replacePackage(k, v)
-
-_replacePackages()
-
-def find_modules(scripts=(), includes=(), packages=(), excludes=(), path=None, debug=0):
-    """
-    High-level interface, takes iterables for:
-        scripts, includes, packages, excludes
-
-    And returns a :class:`modulegraph.modulegraph.ModuleGraph` instance,
-    python_files, and extensions
-
-    python_files is a list of pure python dependencies as modulegraph.Module objects,
-    extensions is a list of platform-specific C extension dependencies as modulegraph.Module objects
-    """
-    scripts = set(scripts)
-    includes = set(includes)
-    packages = set(packages)
-    excludes = set(excludes)
-    plat_prepare(includes, packages, excludes)
-    mf = modulegraph.ModuleGraph(
-        path=path,
-        excludes=(excludes - includes),
-        implies=get_implies(),
-        debug=debug,
-    )
-    find_needed_modules(mf, scripts, includes, packages)
-    return mf
-
-def test():
-    if '-g' in sys.argv[1:]:
-        sys.argv.remove('-g')
-        dograph = True
-    else:
-        dograph = False
-    if '-x' in sys.argv[1:]:
-        sys.argv.remove('-x')
-        doxref = True
-    else:
-        doxref= False
-
-    scripts = sys.argv[1:] or [__file__]
-    mf = find_modules(scripts=scripts)
-    if doxref:
-        mf.create_xref()
-    elif dograph:
-        mf.graphreport()
-    else:
-        mf.report()
-
-if __name__ == '__main__':
-    test()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/modulegraph.py b/catapult/telemetry/third_party/modulegraph/modulegraph/modulegraph.py
deleted file mode 100644
index 2795cc4..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/modulegraph.py
+++ /dev/null
@@ -1,1686 +0,0 @@
-"""
-Find modules used by a script, using bytecode analysis.
-
-Based on the stdlib modulefinder by Thomas Heller and Just van Rossum,
-but uses a graph data structure and 2.3 features
-
-XXX: Verify all calls to import_hook (and variants) to ensure that
-imports are done in the right way.
-"""
-from __future__ import absolute_import, print_function
-
-import pkg_resources
-
-import dis
-import imp
-import marshal
-import os
-import sys
-import struct
-import zipimport
-import re
-from collections import deque, namedtuple
-import ast
-
-from altgraph.ObjectGraph import ObjectGraph
-from altgraph import GraphError
-
-from itertools import count
-
-from modulegraph import util
-from modulegraph import zipio
-
-if sys.version_info[0] == 2:
-    from StringIO import StringIO as BytesIO
-    from StringIO import StringIO
-    from  urllib import pathname2url
-    def _Bchr(value):
-        return chr(value)
-
-else:
-    from urllib.request  import pathname2url
-    from io import BytesIO, StringIO
-
-    def _Bchr(value):
-        return value
-
-
-# File open mode for reading (univeral newlines)
-if sys.version_info[0] == 2:
-    _READ_MODE = "rU"
-else:
-    _READ_MODE = "r"
-
-
-
-
-# Modulegraph does a good job at simulating Python's, but it can not
-# handle packagepath modifications packages make at runtime.  Therefore there
-# is a mechanism whereby you can register extra paths in this map for a
-# package, and it will be honored.
-#
-# Note this is a mapping is lists of paths.
-_packagePathMap = {}
-
-# Prefix used in magic .pth files used by setuptools to create namespace
-# packages without an __init__.py file.
-#
-# The value is a list of such prefixes as the prefix varies with versions of
-# setuptools.
-_SETUPTOOLS_NAMESPACEPKG_PTHs=(
-    "import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('",
-    "import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('",
-    "import sys, types, os;p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('",
-)
-
-
-def _namespace_package_path(fqname, pathnames, path=None):
-    """
-    Return the __path__ for the python package in *fqname*.
-
-    This function uses setuptools metadata to extract information
-    about namespace packages from installed eggs.
-    """
-    working_set = pkg_resources.WorkingSet(path)
-
-    path = list(pathnames)
-
-    for dist in working_set:
-        if dist.has_metadata('namespace_packages.txt'):
-            namespaces = dist.get_metadata(
-                    'namespace_packages.txt').splitlines()
-            if fqname in namespaces:
-                nspath = os.path.join(dist.location, *fqname.split('.'))
-                if nspath not in path:
-                    path.append(nspath)
-
-    return path
-
-_strs = re.compile(r'''^\s*["']([A-Za-z0-9_]+)["'],?\s*''') # "<- emacs happy
-
-def _eval_str_tuple(value):
-    """
-    Input is the repr of a tuple of strings, output
-    is that tuple.
-
-    This only works with a tuple where the members are
-    python identifiers.
-    """
-    if not (value.startswith('(') and value.endswith(')')):
-        raise ValueError(value)
-
-    orig_value = value
-    value = value[1:-1]
-
-    result = []
-    while value:
-        m = _strs.match(value)
-        if m is None:
-            raise ValueError(orig_value)
-
-        result.append(m.group(1))
-        value = value[len(m.group(0)):]
-
-    return tuple(result)
-
-def _path_from_importerror(exc, default):
-    # This is a hack, but sadly enough the necessary information
-    # isn't available otherwise.
-    m = re.match('^No module named (\S+)$', str(exc))
-    if m is not None:
-        return m.group(1)
-
-    return default
-
-def os_listdir(path):
-    """
-    Deprecated name
-    """
-    warnings.warn("Use zipio.listdir instead of os_listdir",
-            DeprecationWarning)
-    return zipio.listdir(path)
-
-
-def _code_to_file(co):
-    """ Convert code object to a .pyc pseudo-file """
-    return BytesIO(
-            imp.get_magic() + b'\0\0\0\0' + marshal.dumps(co))
-
-
-def find_module(name, path=None):
-    """
-    A version of imp.find_module that works with zipped packages.
-    """
-    if path is None:
-        path = sys.path
-
-    # Support for the PEP302 importer for normal imports:
-    # - Python 2.5 has pkgutil.ImpImporter
-    # - In setuptools 0.7 and later there's _pkgutil.ImpImporter
-    # - In earlier setuptools versions you pkg_resources.ImpWrapper
-    #
-    # XXX: This is a bit of a hack, should check if we can just rely on
-    # PEP302's get_code() method with all recent versions of pkgutil and/or
-    # setuptools (setuptools 0.6.latest, setuptools trunk and python2.[45])
-    #
-    # For python 3.3 this code should be replaced by code using importlib,
-    # for python 3.2 and 2.7 this should be cleaned up a lot.
-    try:
-        from pkgutil import ImpImporter
-    except ImportError:
-        try:
-            from _pkgutil import ImpImporter
-        except ImportError:
-            ImpImporter = pkg_resources.ImpWrapper
-
-    namespace_path =[]
-    fp = None
-    for entry in path:
-        importer = pkg_resources.get_importer(entry)
-        if importer is None:
-            continue
-
-        if sys.version_info[:2] >= (3,3) and hasattr(importer, 'find_loader'):
-            loader, portions = importer.find_loader(name)
-
-        else:
-            loader = importer.find_module(name)
-            portions = []
-
-        namespace_path.extend(portions)
-
-        if loader is None: continue
-
-        if isinstance(importer, ImpImporter):
-            filename = loader.filename
-            if filename.endswith('.pyc') or filename.endswith('.pyo'):
-                fp = open(filename, 'rb')
-                description = ('.pyc', 'rb', imp.PY_COMPILED)
-                return (fp, filename, description)
-
-            elif filename.endswith('.py'):
-                if sys.version_info[0] == 2:
-                    fp = open(filename, _READ_MODE)
-                else:
-                    with open(filename, 'rb') as fp:
-                        encoding = util.guess_encoding(fp)
-
-                    fp = open(filename, _READ_MODE, encoding=encoding)
-                description = ('.py', _READ_MODE, imp.PY_SOURCE)
-                return (fp, filename, description)
-
-            else:
-                for _sfx, _mode, _type in imp.get_suffixes():
-                    if _type == imp.C_EXTENSION and filename.endswith(_sfx):
-                        description = (_sfx, 'rb', imp.C_EXTENSION)
-                        break
-                else:
-                    description = ('', '', imp.PKG_DIRECTORY)
-
-                return (None, filename, description)
-
-        if hasattr(loader, 'path'):
-            if loader.path.endswith('.pyc') or loader.path.endswith('.pyo'):
-                fp = open(loader.path, 'rb')
-                description = ('.pyc', 'rb', imp.PY_COMPILED)
-                return (fp, loader.path, description)
-
-
-        if hasattr(loader, 'get_source'):
-            source = loader.get_source(name)
-            fp = StringIO(source)
-            co = None
-
-        else:
-            source = None
-
-        if source is None:
-            if hasattr(loader, 'get_code'):
-                co = loader.get_code(name)
-                fp = _code_to_file(co)
-
-            else:
-                fp = None
-                co = None
-
-        pathname = os.path.join(entry, *name.split('.'))
-
-        if isinstance(loader, zipimport.zipimporter):
-            # Check if this happens to be a wrapper module introduced by
-            # setuptools, if it is we return the actual extension.
-            zn = '/'.join(name.split('.'))
-            for _sfx, _mode, _type in imp.get_suffixes():
-                if _type == imp.C_EXTENSION:
-                    p = loader.prefix + zn + _sfx
-                    if loader._files is None:
-                        loader_files = zipimport._zip_directory_cache[loader.archive]
-                    else:
-                        loader_files = loader._files
-
-                    if p in loader_files:
-                        description = (_sfx, 'rb', imp.C_EXTENSION)
-                        return (None, pathname + _sfx, description)
-
-        if hasattr(loader, 'is_package') and loader.is_package(name):
-            return (None, pathname, ('', '', imp.PKG_DIRECTORY))
-
-        if co is None:
-            if hasattr(loader, 'path'):
-                filename = loader.path
-            elif hasattr(loader, 'get_filename'):
-                filename = loader.get_filename(name)
-                if source is not None:
-                    if filename.endswith(".pyc") or filename.endswith(".pyo"):
-                        filename = filename[:-1]
-            else:
-                filename = None
-
-            if filename is not None and (filename.endswith('.py') or filename.endswith('.pyw')):
-                return (fp, filename, ('.py', 'rU', imp.PY_SOURCE))
-            else:
-                if fp is not None:
-                    fp.close()
-                return (None, filename, (os.path.splitext(filename)[-1], 'rb', imp.C_EXTENSION))
-
-        else:
-            if hasattr(loader, 'path'):
-                return (fp, loader.path, ('.pyc', 'rb', imp.PY_COMPILED))
-            else:
-                return (fp, pathname + '.pyc', ('.pyc', 'rb', imp.PY_COMPILED))
-
-    if namespace_path:
-        if fp is not None:
-            fp.close()
-        return (None, namespace_path[0], ('', namespace_path, imp.PKG_DIRECTORY))
-
-    raise ImportError(name)
-
-def moduleInfoForPath(path):
-    for (ext, readmode, typ) in imp.get_suffixes():
-        if path.endswith(ext):
-            return os.path.basename(path)[:-len(ext)], readmode, typ
-    return None
-
-# A Public interface
-import warnings
-def AddPackagePath(packagename, path):
-    warnings.warn("Use addPackagePath instead of AddPackagePath",
-            DeprecationWarning)
-
-    addPackagePath(packagename, path)
-
-def addPackagePath(packagename, path):
-    paths = _packagePathMap.get(packagename, [])
-    paths.append(path)
-    _packagePathMap[packagename] = paths
-
-_replacePackageMap = {}
-
-# This ReplacePackage mechanism allows modulefinder to work around the
-# way the _xmlplus package injects itself under the name "xml" into
-# sys.modules at runtime by calling ReplacePackage("_xmlplus", "xml")
-# before running ModuleGraph.
-def ReplacePackage(oldname, newname):
-    warnings.warn("use replacePackage instead of ReplacePackage",
-            DeprecationWarning)
-    replacePackage(oldname, newname)
-
-def replacePackage(oldname, newname):
-    _replacePackageMap[oldname] = newname
-
-
-class DependencyInfo (namedtuple("DependencyInfo", ["conditional", "function", "tryexcept", "fromlist"])):
-    __slots__ = ()
-
-    def _merged(self, other):
-        if (not self.conditional and not self.function and not self.tryexcept) \
-            or (not other.conditional and not other.function and not other.tryexcept):
-                return DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=self.fromlist and other.fromlist)
-
-        else:
-            return DependencyInfo(
-                    conditional=self.conditional or other.conditional,
-                    function=self.function or other.function,
-                    tryexcept=self.tryexcept or other.tryexcept,
-                    fromlist=self.fromlist and other.fromlist)
-
-
-class Node(object):
-    def __init__(self, identifier):
-        self.debug = 0
-        self.graphident = identifier
-        self.identifier = identifier
-        self._namespace = {}
-        self.filename = None
-        self.packagepath = None
-        self.code = None
-        # The set of global names that are assigned to in the module.
-        # This includes those names imported through starimports of
-        # Python modules.
-        self.globalnames = set()
-        # The set of starimports this module did that could not be
-        # resolved, ie. a starimport from a non-Python module.
-        self.starimports = set()
-
-    def __contains__(self, name):
-        return name in self._namespace
-
-    def __getitem__(self, name):
-        return self._namespace[name]
-
-    def __setitem__(self, name, value):
-        self._namespace[name] = value
-
-    def get(self, *args):
-        return self._namespace.get(*args)
-
-    def __cmp__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return NotImplemented
-
-        return cmp(self.graphident, otherIdent)
-
-    def __eq__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return False
-
-        return self.graphident == otherIdent
-
-    def __ne__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return True
-
-        return self.graphident != otherIdent
-
-    def __lt__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return NotImplemented
-
-        return self.graphident < otherIdent
-
-    def __le__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return NotImplemented
-
-        return self.graphident <= otherIdent
-
-    def __gt__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return NotImplemented
-
-        return self.graphident > otherIdent
-
-    def __ge__(self, other):
-        try:
-            otherIdent = getattr(other, 'graphident')
-        except AttributeError:
-            return NotImplemented
-
-        return self.graphident >= otherIdent
-
-
-    def __hash__(self):
-        return hash(self.graphident)
-
-    def infoTuple(self):
-        return (self.identifier,)
-
-    def __repr__(self):
-        return '%s%r' % (type(self).__name__, self.infoTuple())
-
-class Alias(str):
-    pass
-
-class AliasNode(Node):
-    def __init__(self, name, node):
-        super(AliasNode, self).__init__(name)
-        for k in 'identifier', 'packagepath', '_namespace', 'globalnames', 'starimports':
-            setattr(self, k, getattr(node, k, None))
-
-    def infoTuple(self):
-        return (self.graphident, self.identifier)
-
-class BadModule(Node):
-    pass
-
-class ExcludedModule(BadModule):
-    pass
-
-class MissingModule(BadModule):
-    pass
-
-class Script(Node):
-    def __init__(self, filename):
-        super(Script, self).__init__(filename)
-        self.filename = filename
-
-    def infoTuple(self):
-        return (self.filename,)
-
-class BaseModule(Node):
-    def __init__(self, name, filename=None, path=None):
-        super(BaseModule, self).__init__(name)
-        self.filename = filename
-        self.packagepath = path
-
-    def infoTuple(self):
-        return tuple(filter(None, (self.identifier, self.filename, self.packagepath)))
-
-class BuiltinModule(BaseModule):
-    pass
-
-class SourceModule(BaseModule):
-    pass
-
-class InvalidSourceModule(SourceModule):
-    pass
-
-class CompiledModule(BaseModule):
-    pass
-
-class InvalidCompiledModule(BaseModule):
-    pass
-
-class Package(BaseModule):
-    pass
-
-class NamespacePackage(Package):
-    pass
-
-class Extension(BaseModule):
-    pass
-
-class FlatPackage(BaseModule): # nocoverage
-    def __init__(self, *args, **kwds):
-        warnings.warn("This class will be removed in a future version of modulegraph",
-            DeprecationWarning)
-        super(FlatPackage, *args, **kwds)
-
-class ArchiveModule(BaseModule): # nocoverage
-    def __init__(self, *args, **kwds):
-        warnings.warn("This class will be removed in a future version of modulegraph",
-            DeprecationWarning)
-        super(FlatPackage, *args, **kwds)
-
-# HTML templates for ModuleGraph generator
-header = """\
-<html>
-  <head>
-    <title>%(TITLE)s</title>
-    <style>
-      .node { margin:1em 0; }
-    </style>
-  </head>
-  <body>
-    <h1>%(TITLE)s</h1>"""
-entry = """
-<div class="node">
-  <a name="%(NAME)s" />
-  %(CONTENT)s
-</div>"""
-contpl = """<tt>%(NAME)s</tt> %(TYPE)s"""
-contpl_linked = """\
-<a target="code" href="%(URL)s" type="text/plain"><tt>%(NAME)s</tt></a>"""
-imports = """\
-  <div class="import">
-%(HEAD)s:
-  %(LINKS)s
-  </div>
-"""
-footer = """
-  </body>
-</html>"""
-
-def _ast_names(names):
-    result = []
-    for nm in names:
-        if isinstance(nm, ast.alias):
-            result.append(nm.name)
-        else:
-            result.append(nm)
-    return result
-
-
-if sys.version_info[0] == 2:
-    DEFAULT_IMPORT_LEVEL= -1
-else:
-    DEFAULT_IMPORT_LEVEL= 0
-
-class _Visitor (ast.NodeVisitor):
-    def __init__(self, graph, module):
-        self._graph = graph
-        self._module = module
-        self._level = DEFAULT_IMPORT_LEVEL
-        self._in_if = [False]
-        self._in_def = [False]
-        self._in_tryexcept = [False]
-
-    @property
-    def in_if(self):
-        return self._in_if[-1]
-
-    @property
-    def in_def(self):
-        return self._in_def[-1]
-
-    @property
-    def in_tryexcept(self):
-        return self._in_tryexcept[-1]
-
-    def _process_import(self, name, fromlist, level):
-
-        if sys.version_info[0] == 2:
-            if name == '__future__' and 'absolute_import' in (fromlist or ()):
-                self._level = 0
-
-        have_star = False
-        if fromlist is not None:
-            fromlist = set(fromlist)
-            if '*' in fromlist:
-                fromlist.remove('*')
-                have_star = True
-
-        imported_module = self._graph._safe_import_hook(name,
-            self._module, fromlist, level, attr=DependencyInfo(
-                conditional=self.in_if,
-                tryexcept=self.in_tryexcept,
-                function=self.in_def,
-                fromlist=False,
-            ))[0]
-        if have_star:
-            self._module.globalnames.update(imported_module.globalnames)
-            self._module.starimports.update(imported_module.starimports)
-            if imported_module.code is None:
-                self._module.starimports.add(name)
-
-
-    def visit_Import(self, node):
-        for nm in _ast_names(node.names):
-            self._process_import(nm, None, self._level)
-
-    def visit_ImportFrom(self, node):
-        level = node.level if node.level != 0 else self._level
-        self._process_import(node.module or '', _ast_names(node.names), level)
-
-    def visit_If(self, node):
-        self._in_if.append(True)
-        self.generic_visit(node)
-        self._in_if.pop()
-
-    def visit_FunctionDef(self, node):
-        self._in_def.append(True)
-        self.generic_visit(node)
-        self._in_def.pop()
-
-    def visit_Try(self, node):
-        self._in_tryexcept.append(True)
-        self.generic_visit(node)
-        self._in_tryexcept.pop()
-
-    def visit_ExceptHandler(self, node):
-        self._in_tryexcept.append(True)
-        self.generic_visit(node)
-        self._in_tryexcept.pop()
-
-    def visit_TryExcept(self, node):
-        self._in_tryexcept.append(True)
-        self.generic_visit(node)
-        self._in_tryexcept.pop()
-
-    def visit_ExceptHandler(self, node):
-        self._in_tryexcept.append(True)
-        self.generic_visit(node)
-        self._in_tryexcept.pop()
-
-    def visit_Expression(self, node):
-        # Expression node's cannot contain import statements or
-        # other nodes that are relevant for us.
-        pass
-
-    # Expression isn't actually used as such in AST trees,
-    # therefore define visitors for all kinds of expression nodes.
-    visit_BoolOp = visit_Expression
-    visit_BinOp = visit_Expression
-    visit_UnaryOp = visit_Expression
-    visit_Lambda = visit_Expression
-    visit_IfExp = visit_Expression
-    visit_Dict = visit_Expression
-    visit_Set = visit_Expression
-    visit_ListComp = visit_Expression
-    visit_SetComp = visit_Expression
-    visit_ListComp = visit_Expression
-    visit_GeneratorExp = visit_Expression
-    visit_Compare = visit_Expression
-    visit_Yield = visit_Expression
-    visit_YieldFrom = visit_Expression
-    visit_Await = visit_Expression
-    visit_Call = visit_Expression
-
-
-
-class ModuleGraph(ObjectGraph):
-    def __init__(self, path=None, excludes=(), replace_paths=(), implies=(), graph=None, debug=0):
-        super(ModuleGraph, self).__init__(graph=graph, debug=debug)
-        if path is None:
-            path = sys.path
-        self.path = path
-        self.lazynodes = {}
-        # excludes is stronger than implies
-        self.lazynodes.update(dict(implies))
-        for m in excludes:
-            self.lazynodes[m] = None
-        self.replace_paths = replace_paths
-
-        self.nspackages = self._calc_setuptools_nspackages()
-
-    def _calc_setuptools_nspackages(self):
-        # Setuptools has some magic handling for namespace
-        # packages when using 'install --single-version-externally-managed'
-        # (used by system packagers and also by pip)
-        #
-        # When this option is used namespace packages are writting to
-        # disk *without* an __init__.py file, which means the regular
-        # import machinery will not find them.
-        #
-        # We therefore explicitly look for the hack used by
-        # setuptools to get this kind of namespace packages to work.
-
-        pkgmap = {}
-
-        try:
-            from pkgutil import ImpImporter
-        except ImportError:
-            try:
-                from _pkgutil import ImpImporter
-            except ImportError:
-                ImpImporter = pkg_resources.ImpWrapper
-
-        if sys.version_info[:2] >= (3,3):
-            import importlib.machinery
-            ImpImporter = importlib.machinery.FileFinder
-
-        for entry in self.path:
-            importer = pkg_resources.get_importer(entry)
-
-            if isinstance(importer, ImpImporter):
-                try:
-                    ldir = os.listdir(entry)
-                except os.error:
-                    continue
-
-                for fn in ldir:
-                    if fn.endswith('-nspkg.pth'):
-                        fp = open(os.path.join(entry, fn), 'rU')
-                        try:
-                            for ln in fp:
-                                for pfx in _SETUPTOOLS_NAMESPACEPKG_PTHs:
-                                    if ln.startswith(pfx):
-                                        try:
-                                            start = len(pfx)-2
-                                            stop = ln.index(')', start)+1
-                                        except ValueError:
-                                            continue
-
-                                        pkg = _eval_str_tuple(ln[start:stop])
-                                        identifier = ".".join(pkg)
-                                        subdir = os.path.join(entry, *pkg)
-                                        if os.path.exists(os.path.join(subdir, '__init__.py')):
-                                            # There is a real __init__.py, ignore the setuptools hack
-                                            continue
-
-                                        if identifier in pkgmap:
-                                            pkgmap[identifier].append(subdir)
-                                        else:
-                                            pkgmap[identifier] = [subdir]
-                                        break
-                        finally:
-                            fp.close()
-
-        return pkgmap
-
-    def implyNodeReference(self, node, other, edge_data=None):
-        """
-        Imply that one node depends on another.
-        other may be a module name or another node.
-
-        For use by extension modules and tricky import code
-        """
-        if isinstance(other, Node):
-            self._updateReference(node, other, edge_data)
-
-        else:
-            if isinstance(other, tuple):
-                raise ValueError(other)
-
-            others = self._safe_import_hook(other, node, None)
-            for other in others:
-                self._updateReference(node, other, edge_data)
-
-
-    def getReferences(self, fromnode):
-        """
-        Yield all nodes that 'fromnode' dependes on (that is,
-        all modules that 'fromnode' imports.
-        """
-        node = self.findNode(fromnode)
-        out_edges, _ = self.get_edges(node)
-        return out_edges
-
-    def getReferers(self, tonode, collapse_missing_modules=True):
-        node = self.findNode(tonode)
-        _, in_edges = self.get_edges(node)
-
-        if collapse_missing_modules:
-            for n in in_edges:
-                if isinstance(n, MissingModule):
-                    for n in self.getReferers(n, False):
-                        yield n
-
-                else:
-                    yield n
-
-        else:
-            for n in in_edges:
-                yield n
-
-    def hasEdge(self, fromnode, tonode):
-        """ Return True iff there is an edge from 'fromnode' to 'tonode' """
-        fromnode = self.findNode(fromnode)
-        tonode = self.findNode(tonode)
-
-        return self.graph.edge_by_node(fromnode, tonode) is not None
-
-
-    def foldReferences(self, packagenode):
-        """
-        Create edges to/from 'packagenode' based on the
-        edges to/from modules in package. The module nodes
-        are then hidden.
-        """
-        pkg = self.findNode(packagenode)
-
-        for n in self.nodes():
-            if not n.identifier.startswith(pkg.identifier + '.'):
-                continue
-
-            iter_out, iter_inc = n.get_edges()
-            for other in iter_out:
-                if other.identifier.startswith(pkg.identifier + '.'):
-                    continue
-
-                if not self.hasEdge(pkg, other):
-                    # Ignore circular dependencies
-                    self._updateReference(pkg, other, 'pkg-internal-import')
-
-            for other in iter_in:
-                if other.identifier.startswith(pkg.identifier + '.'):
-                    # Ignore circular dependencies
-                    continue
-
-                if not self.hasEdge(other, pkg):
-                    self._updateReference(other, pkg, 'pkg-import')
-
-            self.graph.hide_node(n)
-
-    # TODO: unfoldReferences(pkg) that restore the submodule nodes and
-    #       removes 'pkg-import' and 'pkg-internal-import' edges. Care should
-    #       be taken to ensure that references are correct if multiple packages
-    #       are folded and then one of them in unfolded
-
-
-    def _updateReference(self, fromnode, tonode, edge_data):
-        try:
-            ed = self.edgeData(fromnode, tonode)
-        except (KeyError, GraphError): # XXX: Why 'GraphError'
-            return self.createReference(fromnode, tonode, edge_data)
-
-        if not (isinstance(ed, DependencyInfo) and isinstance(edge_data, DependencyInfo)):
-            self.updateEdgeData(fromnode, tonode, edge_data)
-        else:
-            self.updateEdgeData(fromnode, tonode, ed._merged(edge_data))
-
-
-    def createReference(self, fromnode, tonode, edge_data='direct'):
-        """
-        Create a reference from fromnode to tonode
-        """
-        return super(ModuleGraph, self).createReference(fromnode, tonode, edge_data=edge_data)
-
-    def findNode(self, name):
-        """
-        Find a node by identifier.  If a node by that identifier exists,
-        it will be returned.
-
-        If a lazy node exists by that identifier with no dependencies (excluded),
-        it will be instantiated and returned.
-
-        If a lazy node exists by that identifier with dependencies, it and its
-        dependencies will be instantiated and scanned for additional dependencies.
-        """
-        data = super(ModuleGraph, self).findNode(name)
-        if data is not None:
-            return data
-        if name in self.lazynodes:
-            deps = self.lazynodes.pop(name)
-            if deps is None:
-                # excluded module
-                m = self.createNode(ExcludedModule, name)
-            elif isinstance(deps, Alias):
-                other = self._safe_import_hook(deps, None, None).pop()
-                m = self.createNode(AliasNode, name, other)
-                self.implyNodeReference(m, other)
-
-            else:
-                m = self._safe_import_hook(name, None, None).pop()
-                for dep in deps:
-                    self.implyNodeReference(m, dep)
-            return m
-
-        if name in self.nspackages:
-            # name is a --single-version-externally-managed
-            # namespace package (setuptools/distribute)
-            pathnames = self.nspackages.pop(name)
-            m = self.createNode(NamespacePackage, name)
-
-            # FIXME: The filename must be set to a string to ensure that py2app
-            # works, it is not clear yet why that is. Setting to None would be
-            # cleaner.
-            m.filename = '-'
-            m.packagepath = _namespace_package_path(name, pathnames, self.path)
-
-            # As per comment at top of file, simulate runtime packagepath additions.
-            m.packagepath = m.packagepath + _packagePathMap.get(name, [])
-            return m
-
-        return None
-
-    def run_script(self, pathname, caller=None):
-        """
-        Create a node by path (not module name).  It is expected to be a Python
-        source file, and will be scanned for dependencies.
-        """
-        self.msg(2, "run_script", pathname)
-        pathname = os.path.realpath(pathname)
-        m = self.findNode(pathname)
-        if m is not None:
-            return m
-
-        if sys.version_info[0] != 2:
-            with open(pathname, 'rb') as fp:
-                encoding = util.guess_encoding(fp)
-
-            with open(pathname, _READ_MODE, encoding=encoding) as fp:
-                contents = fp.read() + '\n'
-
-        else:
-            with open(pathname, _READ_MODE) as fp:
-                contents = fp.read() + '\n'
-
-        co = compile(contents, pathname, 'exec', ast.PyCF_ONLY_AST, True)
-        m = self.createNode(Script, pathname)
-        self._updateReference(caller, m, None)
-        self._scan_code(co, m)
-        m.code = compile(co, pathname, 'exec', 0, True)
-        if self.replace_paths:
-            m.code = self._replace_paths_in_code(m.code)
-        return m
-
-    def import_hook(self, name, caller=None, fromlist=None, level=DEFAULT_IMPORT_LEVEL, attr=None):
-        """
-        Import a module
-
-        Return the set of modules that are imported
-        """
-        self.msg(3, "import_hook", name, caller, fromlist, level)
-        parent = self._determine_parent(caller)
-        q, tail = self._find_head_package(parent, name, level)
-        m = self._load_tail(q, tail)
-        modules = [m]
-        if fromlist and m.packagepath:
-            for s in self._ensure_fromlist(m, fromlist):
-                if s not in modules:
-                    modules.append(s)
-        for m in modules:
-            self._updateReference(caller, m, edge_data=attr)
-        return modules
-
-    def _determine_parent(self, caller):
-        """
-        Determine the package containing a node
-        """
-        self.msgin(4, "determine_parent", caller)
-        parent = None
-        if caller:
-            pname = caller.identifier
-
-            if isinstance(caller, Package):
-                parent = caller
-
-            elif '.' in pname:
-                pname = pname[:pname.rfind('.')]
-                parent = self.findNode(pname)
-
-            elif caller.packagepath:
-                # XXX: I have no idea why this line
-                # is necessary.
-                parent = self.findNode(pname)
-
-
-        self.msgout(4, "determine_parent ->", parent)
-        return parent
-
-    def _find_head_package(self, parent, name, level=DEFAULT_IMPORT_LEVEL):
-        """
-        Given a calling parent package and an import name determine the containing
-        package for the name
-        """
-        self.msgin(4, "find_head_package", parent, name, level)
-        if '.' in name:
-            head, tail = name.split('.', 1)
-        else:
-            head, tail = name, ''
-
-        if level == -1:
-            if parent:
-                qname = parent.identifier + '.' + head
-            else:
-                qname = head
-
-        elif level == 0:
-            qname = head
-
-            # Absolute import, ignore the parent
-            parent = None
-
-        else:
-            if parent is None:
-                self.msg(2, "Relative import outside of package")
-                raise ImportError("Relative import outside of package (name=%r, parent=%r, level=%r)"%(name, parent, level))
-
-            for i in range(level-1):
-                if '.' not in parent.identifier:
-                    self.msg(2, "Relative import outside of package")
-                    raise ImportError("Relative import outside of package (name=%r, parent=%r, level=%r)"%(name, parent, level))
-
-                p_fqdn = parent.identifier.rsplit('.', 1)[0]
-                new_parent = self.findNode(p_fqdn)
-                if new_parent is None:
-                    self.msg(2, "Relative import outside of package")
-                    raise ImportError("Relative import outside of package (name=%r, parent=%r, level=%r)"%(name, parent, level))
-
-                assert new_parent is not parent, (new_parent, parent)
-                parent = new_parent
-
-            if head:
-                qname = parent.identifier + '.' + head
-            else:
-                qname = parent.identifier
-
-
-        q = self._import_module(head, qname, parent)
-        if q:
-            self.msgout(4, "find_head_package ->", (q, tail))
-            return q, tail
-        if parent:
-            qname = head
-            parent = None
-            q = self._import_module(head, qname, parent)
-            if q:
-                self.msgout(4, "find_head_package ->", (q, tail))
-                return q, tail
-        self.msgout(4, "raise ImportError: No module named", qname)
-        raise ImportError("No module named " + qname)
-
-    def _load_tail(self, mod, tail):
-        self.msgin(4, "load_tail", mod, tail)
-        result = mod
-        while tail:
-            i = tail.find('.')
-            if i < 0: i = len(tail)
-            head, tail = tail[:i], tail[i+1:]
-            mname = "%s.%s" % (result.identifier, head)
-            result = self._import_module(head, mname, result)
-            if result is None:
-                result = self.createNode(MissingModule, mname)
-                #self.msgout(4, "raise ImportError: No module named", mname)
-                #raise ImportError("No module named " + mname)
-        self.msgout(4, "load_tail ->", result)
-        return result
-
-    def _ensure_fromlist(self, m, fromlist):
-        fromlist = set(fromlist)
-        self.msg(4, "ensure_fromlist", m, fromlist)
-        if '*' in fromlist:
-            fromlist.update(self._find_all_submodules(m))
-            fromlist.remove('*')
-        for sub in fromlist:
-            submod = m.get(sub)
-            if submod is None:
-                if sub in m.globalnames:
-                    # Name is a global in the module
-                    continue
-                # XXX: ^^^ need something simular for names imported
-                #      by 'm'.
-
-                fullname = m.identifier + '.' + sub
-                submod = self._import_module(sub, fullname, m)
-                if submod is None:
-                    raise ImportError("No module named " + fullname)
-            yield submod
-
-    def _find_all_submodules(self, m):
-        if not m.packagepath:
-            return
-        # 'suffixes' used to be a list hardcoded to [".py", ".pyc", ".pyo"].
-        # But we must also collect Python extension modules - although
-        # we cannot separate normal dlls from Python extensions.
-        suffixes = [triple[0] for triple in imp.get_suffixes()]
-        for path in m.packagepath:
-            try:
-                names = zipio.listdir(path)
-            except (os.error, IOError):
-                self.msg(2, "can't list directory", path)
-                continue
-            for info in (moduleInfoForPath(p) for p in names):
-                if info is None: continue
-                if info[0] != '__init__':
-                    yield info[0]
-
-    def _import_module(self, partname, fqname, parent):
-        # XXX: Review me for use with absolute imports.
-        self.msgin(3, "import_module", partname, fqname, parent)
-        m = self.findNode(fqname)
-        if m is not None:
-            self.msgout(3, "import_module ->", m)
-            if parent:
-                self._updateReference(m, parent, edge_data=DependencyInfo(
-                    conditional=False, fromlist=False, function=False, tryexcept=False
-                ))
-            return m
-
-        if parent and parent.packagepath is None:
-            self.msgout(3, "import_module -> None")
-            return None
-
-        try:
-            searchpath = None
-            if parent is not None and parent.packagepath:
-                searchpath = parent.packagepath
-
-            fp, pathname, stuff = self._find_module(partname,
-                searchpath, parent)
-
-        except ImportError:
-            self.msgout(3, "import_module ->", None)
-            return None
-
-        try:
-            m = self._load_module(fqname, fp, pathname, stuff)
-
-        finally:
-            if fp is not None:
-                fp.close()
-
-        if parent:
-            self.msgout(4, "create reference", m, "->", parent)
-            self._updateReference(m, parent, edge_data=DependencyInfo(
-                conditional=False, fromlist=False, function=False, tryexcept=False
-            ))
-            parent[partname] = m
-
-        self.msgout(3, "import_module ->", m)
-        return m
-
-    def _load_module(self, fqname, fp, pathname, info):
-        suffix, mode, typ = info
-        self.msgin(2, "load_module", fqname, fp and "fp", pathname)
-
-        if typ == imp.PKG_DIRECTORY:
-            if isinstance(mode, (list, tuple)):
-                packagepath = mode
-            else:
-                packagepath = []
-
-            m = self._load_package(fqname, pathname, packagepath)
-            self.msgout(2, "load_module ->", m)
-            return m
-
-        if typ == imp.PY_SOURCE:
-            contents = fp.read()
-            if isinstance(contents, bytes):
-                contents += b'\n'
-            else:
-                contents += '\n'
-
-            try:
-                co = compile(contents, pathname, 'exec', ast.PyCF_ONLY_AST, True)
-                #co = compile(contents, pathname, 'exec', 0, True)
-            except SyntaxError:
-                co = None
-                cls = InvalidSourceModule
-
-            else:
-                cls = SourceModule
-
-        elif typ == imp.PY_COMPILED:
-            if fp.read(4) != imp.get_magic():
-                self.msgout(2, "raise ImportError: Bad magic number", pathname)
-                co = None
-                cls = InvalidCompiledModule
-
-            else:
-                fp.read(4)
-                try:
-                    co = marshal.loads(fp.read())
-                    cls = CompiledModule
-                except Exception:
-                    co = None
-                    cls = InvalidCompiledModule
-
-        elif typ == imp.C_BUILTIN:
-            cls = BuiltinModule
-            co = None
-
-        else:
-            cls = Extension
-            co = None
-
-        m = self.createNode(cls, fqname)
-        m.filename = pathname
-        if co is not None:
-            self._scan_code(co, m)
-
-            if isinstance(co, ast.AST):
-                co = compile(co, pathname, 'exec', 0, True)
-            if self.replace_paths:
-                co = self._replace_paths_in_code(co)
-            m.code = co
-
-
-        self.msgout(2, "load_module ->", m)
-        return m
-
-    def _safe_import_hook(self, name, caller, fromlist, level=DEFAULT_IMPORT_LEVEL, attr=None):
-        # wrapper for self.import_hook() that won't raise ImportError
-        try:
-            mods = self.import_hook(name, caller, level=level, attr=attr)
-        except ImportError as msg:
-            self.msg(2, "ImportError:", str(msg))
-            m = self.createNode(MissingModule, _path_from_importerror(msg, name))
-            self._updateReference(caller, m, edge_data=attr)
-
-        else:
-            assert len(mods) == 1
-            m = list(mods)[0]
-
-        subs = [m]
-        if isinstance(attr, DependencyInfo):
-            attr = attr._replace(fromlist=True)
-        for sub in (fromlist or ()):
-            # If this name is in the module namespace already,
-            # then add the entry to the list of substitutions
-            if sub in m:
-                sm = m[sub]
-                if sm is not None:
-                    if sm not in subs:
-                        self._updateReference(caller, sm, edge_data=attr)
-                        subs.append(sm)
-                    continue
-
-            elif sub in m.globalnames:
-                # Global variable in the module, ignore
-                continue
-
-
-            # See if we can load it
-            #    fullname = name + '.' + sub
-            fullname = m.identifier + '.' + sub
-            #else:
-            #    print("XXX", repr(name), repr(sub), repr(caller), repr(m))
-            sm = self.findNode(fullname)
-            if sm is None:
-                try:
-                    sm = self.import_hook(name, caller, fromlist=[sub], level=level, attr=attr)
-                except ImportError as msg:
-                    self.msg(2, "ImportError:", str(msg))
-                    #sm = self.createNode(MissingModule, _path_from_importerror(msg, fullname))
-                    sm = self.createNode(MissingModule, fullname)
-                else:
-                    sm = self.findNode(fullname)
-                    if sm is None:
-                        sm = self.createNode(MissingModule, fullname)
-
-            m[sub] = sm
-            if sm is not None:
-                self._updateReference(m, sm, edge_data=attr)
-                self._updateReference(caller, sm, edge_data=attr)
-                if sm not in subs:
-                    subs.append(sm)
-        return subs
-
-    def _scan_code(self, co, m):
-        if isinstance(co, ast.AST):
-            #return self._scan_bytecode(compile(co, '-', 'exec', 0, True), m)
-            self._scan_ast(co, m)
-            self._scan_bytecode_stores(
-                    compile(co, '-', 'exec', 0, True), m)
-
-        else:
-            self._scan_bytecode(co, m)
-
-    def _scan_ast(self, co, m):
-        visitor = _Visitor(self, m)
-        visitor.visit(co)
-
-    def _scan_bytecode_stores(self, co, m,
-            STORE_NAME=_Bchr(dis.opname.index('STORE_NAME')),
-            STORE_GLOBAL=_Bchr(dis.opname.index('STORE_GLOBAL')),
-            HAVE_ARGUMENT=_Bchr(dis.HAVE_ARGUMENT),
-            unpack=struct.unpack):
-
-        extended_import = bool(sys.version_info[:2] >= (2,5))
-
-        code = co.co_code
-        constants = co.co_consts
-        n = len(code)
-        i = 0
-
-        while i < n:
-            c = code[i]
-            i += 1
-            if c >= HAVE_ARGUMENT:
-                i = i+2
-
-            if c == STORE_NAME or c == STORE_GLOBAL:
-                # keep track of all global names that are assigned to
-                oparg = unpack('<H', code[i - 2:i])[0]
-                name = co.co_names[oparg]
-                m.globalnames.add(name)
-
-        cotype = type(co)
-        for c in constants:
-            if isinstance(c, cotype):
-                self._scan_bytecode_stores(c, m)
-
-    def _scan_bytecode(self, co, m,
-            HAVE_ARGUMENT=_Bchr(dis.HAVE_ARGUMENT),
-            LOAD_CONST=_Bchr(dis.opname.index('LOAD_CONST')),
-            IMPORT_NAME=_Bchr(dis.opname.index('IMPORT_NAME')),
-            IMPORT_FROM=_Bchr(dis.opname.index('IMPORT_FROM')),
-            STORE_NAME=_Bchr(dis.opname.index('STORE_NAME')),
-            STORE_GLOBAL=_Bchr(dis.opname.index('STORE_GLOBAL')),
-            unpack=struct.unpack):
-
-        # Python >=2.5: LOAD_CONST flags, LOAD_CONST names, IMPORT_NAME name
-        # Python < 2.5: LOAD_CONST names, IMPORT_NAME name
-        extended_import = bool(sys.version_info[:2] >= (2,5))
-
-        code = co.co_code
-        constants = co.co_consts
-        n = len(code)
-        i = 0
-
-        level = None
-        fromlist = None
-
-        while i < n:
-            c = code[i]
-            i += 1
-            if c >= HAVE_ARGUMENT:
-                i = i+2
-
-            if c == IMPORT_NAME:
-                if extended_import:
-                    assert code[i-9] == LOAD_CONST
-                    assert code[i-6] == LOAD_CONST
-                    arg1, arg2 = unpack('<xHxH', code[i-9:i-3])
-                    level = co.co_consts[arg1]
-                    fromlist = co.co_consts[arg2]
-                else:
-                    assert code[-6] == LOAD_CONST
-                    arg1, = unpack('<xH', code[i-6:i-3])
-                    level = -1
-                    fromlist = co.co_consts[arg1]
-
-                assert fromlist is None or type(fromlist) is tuple
-                oparg, = unpack('<H', code[i - 2:i])
-                name = co.co_names[oparg]
-                have_star = False
-                if fromlist is not None:
-                    fromlist = set(fromlist)
-                    if '*' in fromlist:
-                        fromlist.remove('*')
-                        have_star = True
-
-                #self.msgin(2, "Before import hook", repr(name), repr(m), repr(fromlist), repr(level))
-
-                imported_module = self._safe_import_hook(name, m, fromlist, level)[0]
-
-                if have_star:
-                    m.globalnames.update(imported_module.globalnames)
-                    m.starimports.update(imported_module.starimports)
-                    if imported_module.code is None:
-                        m.starimports.add(name)
-
-            elif c == STORE_NAME or c == STORE_GLOBAL:
-                # keep track of all global names that are assigned to
-                oparg = unpack('<H', code[i - 2:i])[0]
-                name = co.co_names[oparg]
-                m.globalnames.add(name)
-
-        cotype = type(co)
-        for c in constants:
-            if isinstance(c, cotype):
-                self._scan_bytecode(c, m)
-
-    def _load_package(self, fqname, pathname, pkgpath):
-        """
-        Called only when an imp.PACKAGE_DIRECTORY is found
-        """
-        self.msgin(2, "load_package", fqname, pathname, pkgpath)
-        newname = _replacePackageMap.get(fqname)
-        if newname:
-            fqname = newname
-
-        ns_pkgpath = _namespace_package_path(fqname, pkgpath or [], self.path)
-        if ns_pkgpath or pkgpath:
-            # this is a namespace package
-            m = self.createNode(NamespacePackage, fqname)
-            m.filename = '-'
-            m.packagepath = ns_pkgpath
-        else:
-            m = self.createNode(Package, fqname)
-            m.filename = pathname
-            m.packagepath = [pathname] + ns_pkgpath
-
-        # As per comment at top of file, simulate runtime packagepath additions.
-        m.packagepath = m.packagepath + _packagePathMap.get(fqname, [])
-
-
-
-        try:
-            self.msg(2, "find __init__ for %s"%(m.packagepath,))
-            fp, buf, stuff = self._find_module("__init__", m.packagepath, parent=m)
-        except ImportError:
-            pass
-
-        else:
-            try:
-                self.msg(2, "load __init__ for %s"%(m.packagepath,))
-                self._load_module(fqname, fp, buf, stuff)
-            finally:
-                if fp is not None:
-                    fp.close()
-        self.msgout(2, "load_package ->", m)
-        return m
-
-    def _find_module(self, name, path, parent=None):
-        if parent is not None:
-            # assert path is not None
-            fullname = parent.identifier + '.' + name
-        else:
-            fullname = name
-
-        node = self.findNode(fullname)
-        if node is not None:
-            self.msgout(3, "find_module -> already included?", node)
-            raise ImportError(name)
-
-        if path is None:
-            if name in sys.builtin_module_names:
-                return (None, None, ("", "", imp.C_BUILTIN))
-
-            path = self.path
-
-        fp, buf, stuff = find_module(name, path)
-        try:
-            if buf:
-                buf = os.path.realpath(buf)
-
-            return (fp, buf, stuff)
-        except:
-            fp.close()
-            raise
-
-    def create_xref(self, out=None):
-        global header, footer, entry, contpl, contpl_linked, imports
-        if out is None:
-            out = sys.stdout
-        scripts = []
-        mods = []
-        for mod in self.flatten():
-            name = os.path.basename(mod.identifier)
-            if isinstance(mod, Script):
-                scripts.append((name, mod))
-            else:
-                mods.append((name, mod))
-        scripts.sort()
-        mods.sort()
-        scriptnames = [name for name, m in scripts]
-        scripts.extend(mods)
-        mods = scripts
-
-        title = "modulegraph cross reference for "  + ', '.join(scriptnames)
-        print(header % {"TITLE": title}, file=out)
-
-        def sorted_namelist(mods):
-            lst = [os.path.basename(mod.identifier) for mod in mods if mod]
-            lst.sort()
-            return lst
-        for name, m in mods:
-            content = ""
-            if isinstance(m, BuiltinModule):
-                content = contpl % {"NAME": name,
-                                    "TYPE": "<i>(builtin module)</i>"}
-            elif isinstance(m, Extension):
-                content = contpl % {"NAME": name,\
-                                    "TYPE": "<tt>%s</tt>" % m.filename}
-            else:
-                url = pathname2url(m.filename or "")
-                content = contpl_linked % {"NAME": name, "URL": url}
-            oute, ince = map(sorted_namelist, self.get_edges(m))
-            if oute:
-                links = ""
-                for n in oute:
-                    links += """  <a href="#%s">%s</a>\n""" % (n, n)
-                content += imports % {"HEAD": "imports", "LINKS": links}
-            if ince:
-                links = ""
-                for n in ince:
-                    links += """  <a href="#%s">%s</a>\n""" % (n, n)
-                content += imports % {"HEAD": "imported by", "LINKS": links}
-            print(entry % {"NAME": name,"CONTENT": content}, file=out)
-        print(footer, file=out)
-
-
-    def itergraphreport(self, name='G', flatpackages=()):
-        # XXX: Can this be implemented using Dot()?
-        nodes = map(self.graph.describe_node, self.graph.iterdfs(self))
-        describe_edge = self.graph.describe_edge
-        edges = deque()
-        packagenodes = set()
-        packageidents = {}
-        nodetoident = {}
-        inpackages = {}
-        mainedges = set()
-
-        # XXX - implement
-        flatpackages = dict(flatpackages)
-
-        def nodevisitor(node, data, outgoing, incoming):
-            if not isinstance(data, Node):
-                return {'label': str(node)}
-            #if isinstance(d, (ExcludedModule, MissingModule, BadModule)):
-            #    return None
-            s = '<f0> ' + type(data).__name__
-            for i,v in enumerate(data.infoTuple()[:1], 1):
-                s += '| <f%d> %s' % (i,v)
-            return {'label':s, 'shape':'record'}
-
-
-        def edgevisitor(edge, data, head, tail):
-            # XXX: This method nonsense, the edge
-            # data is never initialized.
-            if data == 'orphan':
-                return {'style':'dashed'}
-            elif data == 'pkgref':
-                return {'style':'dotted'}
-            return {}
-
-        yield 'digraph %s {\n' % (name,)
-        attr = dict(rankdir='LR', concentrate='true')
-        cpatt  = '%s="%s"'
-        for item in attr.items():
-            yield '\t%s;\n' % (cpatt % item,)
-
-        # find all packages (subgraphs)
-        for (node, data, outgoing, incoming) in nodes:
-            nodetoident[node] = getattr(data, 'identifier', None)
-            if isinstance(data, Package):
-                packageidents[data.identifier] = node
-                inpackages[node] = set([node])
-                packagenodes.add(node)
-
-
-        # create sets for subgraph, write out descriptions
-        for (node, data, outgoing, incoming) in nodes:
-            # update edges
-            for edge in (describe_edge(e) for e in outgoing):
-                edges.append(edge)
-
-            # describe node
-            yield '\t"%s" [%s];\n' % (
-                node,
-                ','.join([
-                    (cpatt % item) for item in
-                    nodevisitor(node, data, outgoing, incoming).items()
-                ]),
-            )
-
-            inside = inpackages.get(node)
-            if inside is None:
-                inside = inpackages[node] = set()
-            ident = nodetoident[node]
-            if ident is None:
-                continue
-            pkgnode = packageidents.get(ident[:ident.rfind('.')])
-            if pkgnode is not None:
-                inside.add(pkgnode)
-
-
-        graph = []
-        subgraphs = {}
-        for key in packagenodes:
-            subgraphs[key] = []
-
-        while edges:
-            edge, data, head, tail = edges.popleft()
-            if ((head, tail)) in mainedges:
-                continue
-            mainedges.add((head, tail))
-            tailpkgs = inpackages[tail]
-            common = inpackages[head] & tailpkgs
-            if not common and tailpkgs:
-                usepkgs = sorted(tailpkgs)
-                if len(usepkgs) != 1 or usepkgs[0] != tail:
-                    edges.append((edge, data, head, usepkgs[0]))
-                    edges.append((edge, 'pkgref', usepkgs[-1], tail))
-                    continue
-            if common:
-                common = common.pop()
-                if tail == common:
-                    edges.append((edge, data, tail, head))
-                elif head == common:
-                    subgraphs[common].append((edge, 'pkgref', head, tail))
-                else:
-                    edges.append((edge, data, common, head))
-                    edges.append((edge, data, common, tail))
-
-            else:
-                graph.append((edge, data, head, tail))
-
-        def do_graph(edges, tabs):
-            edgestr = tabs + '"%s" -> "%s" [%s];\n'
-            # describe edge
-            for (edge, data, head, tail) in edges:
-                attribs = edgevisitor(edge, data, head, tail)
-                yield edgestr % (
-                    head,
-                    tail,
-                    ','.join([(cpatt % item) for item in attribs.items()]),
-                )
-
-        for g, edges in subgraphs.items():
-            yield '\tsubgraph "cluster_%s" {\n' % (g,)
-            yield '\t\tlabel="%s";\n' % (nodetoident[g],)
-            for s in do_graph(edges, '\t\t'):
-                yield s
-            yield '\t}\n'
-
-        for s in do_graph(graph, '\t'):
-            yield s
-
-        yield '}\n'
-
-
-    def graphreport(self, fileobj=None, flatpackages=()):
-        if fileobj is None:
-            fileobj = sys.stdout
-        fileobj.writelines(self.itergraphreport(flatpackages=flatpackages))
-
-    def report(self):
-        """Print a report to stdout, listing the found modules with their
-        paths, as well as modules that are missing, or seem to be missing.
-        """
-        print()
-        print("%-15s %-25s %s" % ("Class", "Name", "File"))
-        print("%-15s %-25s %s" % ("-----", "----", "----"))
-        # Print modules found
-        sorted = [(os.path.basename(mod.identifier), mod) for mod in self.flatten()]
-        sorted.sort()
-        for (name, m) in sorted:
-            print("%-15s %-25s %s" % (type(m).__name__, name, m.filename or ""))
-
-    def _replace_paths_in_code(self, co):
-        new_filename = original_filename = os.path.normpath(co.co_filename)
-        for f, r in self.replace_paths:
-            f = os.path.join(f, '')
-            r = os.path.join(r, '')
-            if original_filename.startswith(f):
-                new_filename = r + original_filename[len(f):]
-                break
-
-        else:
-            return co
-
-        consts = list(co.co_consts)
-        for i in range(len(consts)):
-            if isinstance(consts[i], type(co)):
-                consts[i] = self._replace_paths_in_code(consts[i])
-
-        code_func = type(co)
-
-        if hasattr(co, 'co_kwonlyargcount'):
-            return code_func(co.co_argcount, co.co_kwonlyargcount, co.co_nlocals, co.co_stacksize,
-                         co.co_flags, co.co_code, tuple(consts), co.co_names,
-                         co.co_varnames, new_filename, co.co_name,
-                         co.co_firstlineno, co.co_lnotab,
-                         co.co_freevars, co.co_cellvars)
-        else:
-            return code_func(co.co_argcount, co.co_nlocals, co.co_stacksize,
-                         co.co_flags, co.co_code, tuple(consts), co.co_names,
-                         co.co_varnames, new_filename, co.co_name,
-                         co.co_firstlineno, co.co_lnotab,
-                         co.co_freevars, co.co_cellvars)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/util.py b/catapult/telemetry/third_party/modulegraph/modulegraph/util.py
deleted file mode 100644
index acf6bc1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/util.py
+++ /dev/null
@@ -1,119 +0,0 @@
-from __future__ import absolute_import
-
-import os
-import imp
-import sys
-import re
-import marshal
-import warnings
-
-try:
-    unicode
-except NameError:
-    unicode = str
-
-
-if sys.version_info[0] == 2:
-    from StringIO import StringIO as BytesIO
-    from StringIO import StringIO
-
-else:
-    from io import BytesIO, StringIO
-
-
-
-def imp_find_module(name, path=None):
-    """
-    same as imp.find_module, but handles dotted names
-    """
-    names = name.split('.')
-    if path is not None:
-        if isinstance(path, (str, unicode)):
-            path = [os.path.realpath(path)]
-    for name in names:
-        result = imp.find_module(name, path)
-        if result[0] is not None:
-            result[0].close()
-        path = [result[1]]
-    return result
-
-def _check_importer_for_path(name, path_item):
-    try:
-        importer = sys.path_importer_cache[path_item]
-    except KeyError:
-        for path_hook in sys.path_hooks:
-            try:
-                importer = path_hook(path_item)
-                break
-            except ImportError:
-                pass
-        else:
-            importer = None
-        sys.path_importer_cache.setdefault(path_item, importer)
-
-
-    if importer is None:
-        try:
-            return imp.find_module(name, [path_item])
-        except ImportError:
-            return None
-    return importer.find_module(name)
-
-def imp_walk(name):
-    """
-    yields namepart, tuple_or_importer for each path item
-
-    raise ImportError if a name can not be found.
-    """
-    warnings.warn("imp_walk will be removed in a future version", DeprecationWarning)
-
-    if name in sys.builtin_module_names:
-        yield name, (None, None, ("", "", imp.C_BUILTIN))
-        return
-    paths = sys.path
-    res = None
-    for namepart in name.split('.'):
-        for path_item in paths:
-            res = _check_importer_for_path(namepart, path_item)
-            if hasattr(res, 'load_module'):
-                if res.path.endswith('.py') or res.path.endswith('.pyw'):
-                    fp = StringIO(res.get_source(namepart))
-                    res = (fp, res.path, ('.py', 'rU', imp.PY_SOURCE))
-                elif res.path.endswith('.pyc') or res.path.endswith('.pyo'):
-                    co  = res.get_code(namepart)
-                    fp = BytesIO(imp.get_magic() + b'\0\0\0\0' + marshal.dumps(co))
-                    res = (fp, res.path, ('.pyc', 'rb', imp.PY_COMPILED))
-
-                else:
-                    res = (None, loader.path, (os.path.splitext(loader.path)[-1], 'rb', imp.C_EXTENSION))
-
-                break
-            elif isinstance(res, tuple):
-                break
-        else:
-            break
-
-        yield namepart, res
-        paths = [os.path.join(path_item, namepart)]
-    else:
-        return
-
-    raise ImportError('No module named %s' % (name,))
-
-
-cookie_re = re.compile(b"coding[:=]\s*([-\w.]+)")
-if sys.version_info[0] == 2:
-    default_encoding = 'ascii'
-else:
-    default_encoding = 'utf-8'
-
-def guess_encoding(fp):
-
-    for i in range(2):
-        ln = fp.readline()
-
-        m = cookie_re.search(ln)
-        if m is not None:
-            return m.group(1).decode('ascii')
-
-    return default_encoding
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph/zipio.py b/catapult/telemetry/third_party/modulegraph/modulegraph/zipio.py
deleted file mode 100644
index 34d580e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph/zipio.py
+++ /dev/null
@@ -1,426 +0,0 @@
-"""
-A helper module that can work with paths
-that can refer to data inside a zipfile
-
-XXX: Need to determine if isdir("zipfile.zip")
-should return True or False. Currently returns
-True, but that might do the wrong thing with
-data-files that are zipfiles.
-"""
-import os as _os
-import zipfile as _zipfile
-import errno as _errno
-import time as _time
-import sys as _sys
-import stat as _stat
-
-_DFLT_DIR_MODE = (
-      _stat.S_IFDIR
-    | _stat.S_IXOTH
-    | _stat.S_IXGRP
-    | _stat.S_IXUSR
-    | _stat.S_IROTH
-    | _stat.S_IRGRP
-    | _stat.S_IRUSR)
-
-_DFLT_FILE_MODE = (
-      _stat.S_IFREG
-    | _stat.S_IROTH
-    | _stat.S_IRGRP
-    | _stat.S_IRUSR)
-
-
-if _sys.version_info[0] == 2:
-    from  StringIO import StringIO as _BaseStringIO
-    from  StringIO import StringIO as _BaseBytesIO
-
-    class _StringIO (_BaseStringIO):
-        def __enter__(self):
-            return self
-
-        def __exit__(self, exc_type, exc_value, traceback):
-            self.close()
-            return False
-
-    class _BytesIO (_BaseBytesIO):
-        def __enter__(self):
-            return self
-
-        def __exit__(self, exc_type, exc_value, traceback):
-            self.close()
-            return False
-
-else:
-    from io import StringIO as _StringIO
-    from io import BytesIO as _BytesIO
-
-
-
-
-def _locate(path):
-    full_path = path
-    if _os.path.exists(path):
-        return path, None
-
-    else:
-        rest = []
-        root = _os.path.splitdrive(path)
-        while path and path != root:
-            path, bn = _os.path.split(path)
-            rest.append(bn)
-            if _os.path.exists(path):
-                break
-
-        if path == root:
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        if not _os.path.isfile(path):
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        rest.reverse()
-        return path, '/'.join(rest).strip('/')
-
-_open = open
-def open(path, mode='r'):
-    if 'w' in mode or 'a' in mode:
-        raise IOError(
-            _errno.EINVAL, path, "Write access not supported")
-    elif 'r+' in mode:
-        raise IOError(
-            _errno.EINVAL, path, "Write access not supported")
-
-    full_path = path
-    path, rest = _locate(path)
-    if not rest:
-        return _open(path, mode)
-
-    else:
-        try:
-            zf = _zipfile.ZipFile(path, 'r')
-
-        except _zipfile.error:
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        try:
-            data = zf.read(rest)
-        except (_zipfile.error, KeyError):
-            zf.close()
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-        zf.close()
-
-        if mode == 'rb':
-            return _BytesIO(data)
-
-        else:
-            if _sys.version_info[0] == 3:
-                data = data.decode('ascii')
-
-            return _StringIO(data)
-
-def listdir(path):
-    full_path = path
-    path, rest = _locate(path)
-    if not rest and not _os.path.isfile(path):
-        return _os.listdir(path)
-
-    else:
-        try:
-            zf = _zipfile.ZipFile(path, 'r')
-
-        except _zipfile.error:
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        result = set()
-        seen = False
-        try:
-            for nm in zf.namelist():
-                if rest is None:
-                    seen = True
-                    value = nm.split('/')[0]
-                    if value:
-                        result.add(value)
-
-                elif nm.startswith(rest):
-                    if nm == rest:
-                        seen = True
-                        value = ''
-                        pass
-                    elif nm[len(rest)] == '/':
-                        seen = True
-                        value = nm[len(rest)+1:].split('/')[0]
-                    else:
-                        value = None
-
-                    if value:
-                        result.add(value)
-        except _zipfile.error:
-            zf.close()
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        zf.close()
-
-        if not seen:
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        return list(result)
-
-def isfile(path):
-    full_path = path
-    path, rest = _locate(path)
-    if not rest:
-        ok =  _os.path.isfile(path)
-        if ok:
-            try:
-                zf = _zipfile.ZipFile(path, 'r')
-                return False
-            except (_zipfile.error, IOError):
-                return True
-        return False
-
-    zf = None
-    try:
-        zf = _zipfile.ZipFile(path, 'r')
-        info = zf.getinfo(rest)
-        zf.close()
-        return True
-    except (KeyError, _zipfile.error):
-        if zf is not None:
-            zf.close()
-
-        # Check if this is a directory
-        try:
-            info = zf.getinfo(rest + '/')
-        except KeyError:
-            pass
-        else:
-            return False
-
-        rest = rest + '/'
-        for nm in zf.namelist():
-            if nm.startswith(rest):
-                # Directory
-                return False
-
-        # No trace in zipfile
-        raise IOError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
-
-
-
-
-def isdir(path):
-    full_path = path
-    path, rest = _locate(path)
-    if not rest:
-        ok =  _os.path.isdir(path)
-        if not ok:
-            try:
-                zf = _zipfile.ZipFile(path, 'r')
-            except (_zipfile.error, IOError):
-                return False
-            return True
-        return True
-
-    zf = None
-    try:
-        try:
-            zf = _zipfile.ZipFile(path)
-        except _zipfile.error:
-            raise IOError(
-                _errno.ENOENT, full_path,
-                "No such file or directory")
-
-        try:
-            info = zf.getinfo(rest)
-        except KeyError:
-            pass
-        else:
-            # File found
-            return False
-
-        rest = rest + '/'
-        try:
-            info = zf.getinfo(rest)
-        except KeyError:
-            pass
-        else:
-            # Directory entry found
-            return True
-
-        for nm in zf.namelist():
-            if nm.startswith(rest):
-                return True
-
-        raise IOError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
-    finally:
-        if zf is not None:
-            zf.close()
-
-
-def islink(path):
-    full_path = path
-    path, rest = _locate(path)
-    if not rest:
-        return _os.path.islink(path)
-
-    try:
-        zf = _zipfile.ZipFile(path)
-    except _zipfile.error:
-        raise IOError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
-    try:
-
-
-        try:
-            info = zf.getinfo(rest)
-        except KeyError:
-            pass
-        else:
-            # File
-            return False
-
-        rest += '/'
-        try:
-            info = zf.getinfo(rest)
-        except KeyError:
-            pass
-        else:
-            # Directory
-            return False
-
-        for nm in zf.namelist():
-            if nm.startswith(rest):
-                # Directory without listing
-                return False
-
-        raise IOError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
-
-    finally:
-        zf.close()
-
-
-def readlink(path):
-    full_path = path
-    path, rest = _locate(path)
-    if rest:
-        # No symlinks inside zipfiles
-        raise OSError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
-
-    return _os.readlink(path)
-
-def getmode(path):
-    full_path = path
-    path, rest = _locate(path)
-    if not rest:
-        return _os.stat(path).st_mode
-
-    zf = None
-    try:
-        zf = _zipfile.ZipFile(path)
-        info = None
-
-        try:
-            info = zf.getinfo(rest)
-        except KeyError:
-            pass
-
-        if info is None:
-            try:
-                info = zf.getinfo(rest + '/')
-            except KeyError:
-                pass
-
-        if info is None:
-            rest = rest + '/'
-            for nm in zf.namelist():
-                if nm.startswith(rest):
-                    break
-            else:
-                raise IOError(
-                    _errno.ENOENT, full_path,
-                    "No such file or directory")
-
-            # Directory exists, but has no entry of its own.
-            return _DFLT_DIR_MODE
-
-        # The mode is stored without file-type in external_attr.
-        if (info.external_attr >> 16) != 0:
-            return _stat.S_IFREG | (info.external_attr >> 16)
-        else:
-            return _DFLT_FILE_MODE
-
-
-    except KeyError:
-        if zf is not None:
-            zf.close()
-        raise IOError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
-
-def getmtime(path):
-    full_path = path
-    path, rest = _locate(path)
-    if not rest:
-        return _os.path.getmtime(path)
-
-    zf = None
-    try:
-        zf = _zipfile.ZipFile(path)
-        info = None
-
-        try:
-            info = zf.getinfo(rest)
-        except KeyError:
-            pass
-
-        if info is None:
-            try:
-                info = zf.getinfo(rest + '/')
-            except KeyError:
-                pass
-
-        if info is None:
-            rest = rest + '/'
-            for nm in zf.namelist():
-                if nm.startswith(rest):
-                    break
-            else:
-                raise IOError(
-                    _errno.ENOENT, full_path,
-                    "No such file or directory")
-
-            # Directory exists, but has no entry of its
-            # own, fake mtime by using the timestamp of
-            # the zipfile itself.
-            return _os.path.getmtime(path)
-
-        return _time.mktime(info.date_time + (0, 0, -1))
-
-    except KeyError:
-        if zf is not None:
-            zf.close()
-        raise IOError(
-            _errno.ENOENT, full_path,
-            "No such file or directory")
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/__init__.py
deleted file mode 100644
index 3e9f9ed..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" modulegraph tests """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_basic.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_basic.py
deleted file mode 100644
index 387fde9..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_basic.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import unittest
-
-import os, shutil
-
-from modulegraph import modulegraph
-
-class DummyModule(object):
-    packagepath = None
-    def __init__(self, ppath):
-        self.packagepath = ppath
-
-class FindAllSubmodulesTestCase(unittest.TestCase):
-    def testNone(self):
-        mg = modulegraph.ModuleGraph()
-        # empty packagepath
-        m = DummyModule(None)
-        sub_ms = []
-        for sm in mg._find_all_submodules(m):
-            sub_ms.append(sm)
-        self.assertEqual(sub_ms, [])
-
-    def testSimple(self):
-        mg = modulegraph.ModuleGraph()
-        # a string does not break anything although it is split into its characters
-        # BUG: "/hi/there" will read "/"
-        m = DummyModule("xyz")
-        sub_ms = []
-        for sm in mg._find_all_submodules(m):
-            sub_ms.append(sm)
-        self.assertEqual(sub_ms, [])
-
-    def testSlashes(self):
-        # a string does not break anything although it is split into its characters
-        # BUG: "/xyz" will read "/" so this one already triggers missing itertools
-        mg = modulegraph.ModuleGraph()
-        m = DummyModule("/xyz")
-        sub_ms = []
-        for sm in mg._find_all_submodules(m):
-            sub_ms.append(sm)
-        self.assertEqual(sub_ms, [])
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_edge_data.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_edge_data.py
deleted file mode 100644
index 0760894..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_edge_data.py
+++ /dev/null
@@ -1,417 +0,0 @@
-import os
-import sys
-if sys.version_info[:2] <= (2,6):
-    import unittest2 as unittest
-else:
-    import unittest
-
-from modulegraph import modulegraph
-
-
-# XXX: Todo: simular tests with bytecompiled modules
-
-
-class TestEdgeData (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def test_regular_import(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-edgedata')
-        mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        script_name = os.path.join(root, 'script.py')
-        mf.run_script(script_name)
-
-        script_node = mf.findNode(script_name)
-        self.assertIsInstance(script_node, modulegraph.Script)
-
-
-        node = mf.findNode('toplevel_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('toplevel_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('toplevel_class_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('toplevel_class_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('toplevel_conditional_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('toplevel_conditional_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('toplevel_conditional_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_conditional_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_conditional_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_conditional_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('toplevel_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('function_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('function_class_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('function_class_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('function_conditional_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('function_conditional_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('function_conditional_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_conditional_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_conditional_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_conditional_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('function_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=False))
-
-
-    def test_multi_import(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-edgedata')
-        mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        script_name = os.path.join(root, 'script_multi_import.py')
-        mf.run_script(script_name)
-
-        script_node = mf.findNode(script_name)
-        self.assertIsInstance(script_node, modulegraph.Script)
-
-
-        node = mf.findNode('os.path')
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=False))
-
-        node = mf.findNode('os')
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('sys')
-        ed = mf.edgeData(script_node, node)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('platform')
-        ed = mf.edgeData(script_node, node)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=False))
-
-        node = mf.findNode('email')
-        ed = mf.edgeData(script_node, node)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=False))
-
-    def test_from_imports(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-edgedata')
-        mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        script_name = os.path.join(root, 'script_from_import.py')
-        mf.run_script(script_name)
-
-        script_node = mf.findNode(script_name)
-        self.assertIsInstance(script_node, modulegraph.Script)
-
-
-        node = mf.findNode('pkg.toplevel_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_class_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_class_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_conditional_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_conditional_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_conditional_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_conditional_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_conditional_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_conditional_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.toplevel_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=False, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.function_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.function_class_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.function_class_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.function_conditional_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.function_conditional_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=False, fromlist=True))
-
-        node = mf.findNode('pkg.function_conditional_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_conditional_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_conditional_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_conditional_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=True, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_import_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_import_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_import2_existing')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=True))
-
-        node = mf.findNode('pkg.function_import2_nonexisting')
-        self.assertIsInstance(node, modulegraph.MissingModule)
-        ed = mf.edgeData(script_node, node)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(conditional=False, function=True, tryexcept=True, fromlist=True))
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_explicit_packages.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_explicit_packages.py
deleted file mode 100644
index a964e4f..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_explicit_packages.py
+++ /dev/null
@@ -1,51 +0,0 @@
-from __future__ import absolute_import
-import unittest
-
-import os, shutil, sys
-
-from modulegraph import find_modules
-from modulegraph import modulegraph
-
-
-class PackagesTestCase (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, object, types, message=None):
-            self.assertTrue(isinstance(object, types),
-                    message or '%r is not an instance of %r'%(object, types))
-
-    def testIncludePackage(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-packages')
-
-        mf = find_modules.find_modules(
-                path=[root]+sys.path,
-                scripts=[os.path.join(root, "main_script.py")],
-                packages=['pkg'],
-                debug=1)
-
-        node = mf.findNode('pkg')
-        self.assertIsInstance(node, modulegraph.Package)
-
-        node = mf.findNode('pkg.sub3')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-    def testIncludePackageWithExclude(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-packages')
-
-        mf = find_modules.find_modules(
-                path=[root]+sys.path,
-                scripts=[os.path.join(root, "main_script.py")],
-                packages=['pkg'],
-                excludes=['pkg.sub3'])
-
-        node = mf.findNode('pkg')
-        self.assertIsInstance(node, modulegraph.Package)
-
-        node = mf.findNode('pkg.sub3')
-        self.assertIsInstance(node, modulegraph.ExcludedModule)
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_implies.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_implies.py
deleted file mode 100644
index 71be6a9..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_implies.py
+++ /dev/null
@@ -1,78 +0,0 @@
-import unittest
-
-import os, shutil, sys
-
-from modulegraph import modulegraph
-
-class ImpliesTestCase(unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, object, types, message=None):
-            self.assertTrue(isinstance(object, types),
-                    message or '%r is not an instance of %r'%(object, types))
-
-    def testBasicImplies(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-relimport')
-
-        # First check that 'syslog' isn't accidently in the graph:
-        mg = modulegraph.ModuleGraph(path=[root]+sys.path)
-        mg.run_script(os.path.join(root, 'script.py'))
-        node = mg.findNode('mod')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        node = mg.findNode('syslog')
-        self.assertEqual(node, None)
-
-        # Now check that adding an implied dependency actually adds
-        # 'syslog' to the graph:
-        mg = modulegraph.ModuleGraph(path=[root]+sys.path, implies={
-            'mod': ['syslog']})
-        self.assertEqual(node, None)
-        mg.run_script(os.path.join(root, 'script.py'))
-        node = mg.findNode('mod')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        node = mg.findNode('syslog')
-        self.assertIsInstance(node, modulegraph.Extension)
-
-        # Check that the edges are correct:
-        self.assertTrue(mg.findNode('mod') in mg.get_edges(node)[1])
-        self.assertTrue(node in mg.get_edges(mg.findNode('mod'))[0])
-
-    def testPackagedImplies(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-relimport')
-
-        # First check that 'syslog' isn't accidently in the graph:
-        mg = modulegraph.ModuleGraph(path=[root]+sys.path)
-        mg.run_script(os.path.join(root, 'script.py'))
-        node = mg.findNode('mod')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        node = mg.findNode('syslog')
-        self.assertEqual(node, None)
-
-
-        # Now check that adding an implied dependency actually adds
-        # 'syslog' to the graph:
-        mg = modulegraph.ModuleGraph(path=[root]+sys.path, implies={
-            'pkg.relative': ['syslog']})
-        node = mg.findNode('syslog')
-        self.assertEqual(node, None)
-
-        mg.run_script(os.path.join(root, 'script.py'))
-        node = mg.findNode('pkg.relative')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        node = mg.findNode('syslog')
-        self.assertIsInstance(node, modulegraph.Extension)
-
-        # Check that the edges are correct:
-        self.assertTrue(mg.findNode('pkg.relative') in mg.get_edges(node)[1])
-        self.assertTrue(node in mg.get_edges(mg.findNode('pkg.relative'))[0])
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_import_from_init.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_import_from_init.py
deleted file mode 100644
index f1333a1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_import_from_init.py
+++ /dev/null
@@ -1,128 +0,0 @@
-import sys
-if sys.version_info[:2] <= (2,6):
-    import unittest2 as unittest
-else:
-    import unittest
-import textwrap
-import subprocess
-import os
-from modulegraph import modulegraph
-
-class TestNativeImport (unittest.TestCase):
-    # The tests check that Python's import statement
-    # works as these tests expect.
-
-    def importModule(self, name):
-        if '.' in name:
-            script = textwrap.dedent("""\
-                try:
-                    import %s
-                except ImportError:
-                    import %s
-                print (%s.__name__)
-            """) %(name, name.rsplit('.', 1)[0], name)
-        else:
-            script = textwrap.dedent("""\
-                import %s
-                print (%s.__name__)
-            """) %(name, name)
-
-        p = subprocess.Popen([sys.executable, '-c', script],
-                stdout=subprocess.PIPE,
-                stderr=subprocess.STDOUT,
-                cwd=os.path.join(
-                    os.path.dirname(os.path.abspath(__file__)),
-                    'testpkg-import-from-init'),
-        )
-        data = p.communicate()[0]
-        if sys.version_info[0] != 2:
-            data = data.decode('UTF-8')
-        data = data.strip()
-
-        if data.endswith(' refs]'):
-            # with --with-pydebug builds
-            data = data.rsplit('\n', 1)[0].strip()
-
-        sts = p.wait()
-
-        if sts != 0:
-            print (data)
-        self.assertEqual(sts, 0)
-        return data
-
-
-    @unittest.skipUnless(sys.version_info[0] == 2, "Python 2.x test")
-    def testRootPkg(self):
-        m = self.importModule('pkg')
-        self.assertEqual(m, 'pkg')
-
-    @unittest.skipUnless(sys.version_info[0] == 2, "Python 2.x test")
-    def testSubPackage(self):
-        m = self.importModule('pkg.subpkg')
-        self.assertEqual(m, 'pkg.subpkg')
-
-    def testRootPkgRelImport(self):
-        m = self.importModule('pkg2')
-        self.assertEqual(m, 'pkg2')
-
-    def testSubPackageRelImport(self):
-        m = self.importModule('pkg2.subpkg')
-        self.assertEqual(m, 'pkg2.subpkg')
-
-
-class TestModuleGraphImport (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-import-from-init')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        #self.mf.debug = 999
-        self.mf.run_script(os.path.join(root, 'script.py'))
-
-
-    @unittest.skipUnless(sys.version_info[0] == 2, "Python 2.x test")
-    def testRootPkg(self):
-        node = self.mf.findNode('pkg')
-        self.assertIsInstance(node, modulegraph.Package)
-        self.assertEqual(node.identifier, 'pkg')
-
-    @unittest.skipUnless(sys.version_info[0] == 2, "Python 2.x test")
-    def testSubPackage(self):
-        node = self.mf.findNode('pkg.subpkg')
-        self.assertIsInstance(node, modulegraph.Package)
-        self.assertEqual(node.identifier, 'pkg.subpkg')
-
-        node = self.mf.findNode('pkg.subpkg.compat')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.subpkg.compat')
-
-        node = self.mf.findNode('pkg.subpkg._collections')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.subpkg._collections')
-
-    def testRootPkgRelImport(self):
-        node = self.mf.findNode('pkg2')
-        self.assertIsInstance(node, modulegraph.Package)
-        self.assertEqual(node.identifier, 'pkg2')
-
-    def testSubPackageRelImport(self):
-        node = self.mf.findNode('pkg2.subpkg')
-        self.assertIsInstance(node, modulegraph.Package)
-        self.assertEqual(node.identifier, 'pkg2.subpkg')
-
-        node = self.mf.findNode('pkg2.subpkg.compat')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg2.subpkg.compat')
-
-        node = self.mf.findNode('pkg2.subpkg._collections')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg2.subpkg._collections')
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_imports.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_imports.py
deleted file mode 100644
index 8cdcfa7..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_imports.py
+++ /dev/null
@@ -1,473 +0,0 @@
-"""
-Test for import machinery
-"""
-import unittest
-import sys
-import textwrap
-import subprocess
-import os
-from modulegraph import modulegraph
-
-class TestNativeImport (unittest.TestCase):
-    # The tests check that Python's import statement
-    # works as these tests expect.
-
-    def importModule(self, name):
-        if '.' in name:
-            script = textwrap.dedent("""\
-                try:
-                    import %s
-                except ImportError:
-                    import %s
-                print (%s.__name__)
-            """) %(name, name.rsplit('.', 1)[0], name)
-        else:
-            script = textwrap.dedent("""\
-                import %s
-                print (%s.__name__)
-            """) %(name, name)
-
-        p = subprocess.Popen([sys.executable, '-c', script],
-                stdout=subprocess.PIPE,
-                stderr=subprocess.STDOUT,
-                cwd=os.path.join(
-                    os.path.dirname(os.path.abspath(__file__)),
-                    'testpkg-relimport'),
-        )
-        data = p.communicate()[0]
-        if sys.version_info[0] != 2:
-            data = data.decode('UTF-8')
-        data = data.strip()
-
-        if data.endswith(' refs]'):
-            # with --with-pydebug builds
-            data = data.rsplit('\n', 1)[0].strip()
-
-        sts = p.wait()
-
-        if sts != 0:
-            print (data)
-        self.assertEqual(sts, 0)
-        return data
-
-
-    def testRootModule(self):
-        m = self.importModule('mod')
-        self.assertEqual(m, 'mod')
-
-    def testRootPkg(self):
-        m = self.importModule('pkg')
-        self.assertEqual(m, 'pkg')
-
-    def testSubModule(self):
-        m = self.importModule('pkg.mod')
-        self.assertEqual(m, 'pkg.mod')
-
-    if sys.version_info[0] == 2:
-        def testOldStyle(self):
-            m = self.importModule('pkg.oldstyle.mod')
-            self.assertEqual(m, 'pkg.mod')
-    else:
-        # python3 always has __future__.absolute_import
-        def testOldStyle(self):
-            m = self.importModule('pkg.oldstyle.mod')
-            self.assertEqual(m, 'mod')
-
-    def testNewStyle(self):
-        m = self.importModule('pkg.toplevel.mod')
-        self.assertEqual(m, 'mod')
-
-    def testRelativeImport(self):
-        m = self.importModule('pkg.relative.mod')
-        self.assertEqual(m, 'pkg.mod')
-
-        m = self.importModule('pkg.subpkg.relative.mod')
-        self.assertEqual(m, 'pkg.mod')
-
-        m = self.importModule('pkg.subpkg.mod2.mod')
-        self.assertEqual(m, 'pkg.sub2.mod')
-
-        m = self.importModule('pkg.subpkg.relative2')
-        self.assertEqual(m, 'pkg.subpkg.relative2')
-
-class TestModuleGraphImport (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-relimport')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        #self.mf.debug = 999
-        self.script_name = os.path.join(root, 'script.py')
-        self.mf.run_script(self.script_name)
-
-    def testGraphStructure(self):
-
-        # 1. Script to imported modules
-        n = self.mf.findNode(self.script_name)
-        self.assertIsInstance(n, modulegraph.Script)
-
-        imported = ('mod', 'pkg', 'pkg.mod', 'pkg.oldstyle',
-            'pkg.relative', 'pkg.toplevel', 'pkg.subpkg.relative',
-            'pkg.subpkg.relative2', 'pkg.subpkg.mod2')
-
-        for nm in imported:
-            n2 = self.mf.findNode(nm)
-            ed = self.mf.edgeData(n, n2)
-            self.assertIsInstance(ed, modulegraph.DependencyInfo)
-            self.assertEqual(ed, modulegraph.DependencyInfo(
-                fromlist=False, conditional=False, function=False, tryexcept=False))
-
-        refs = self.mf.getReferences(n)
-        self.assertEqual(set(refs), set(self.mf.findNode(nm) for nm in imported))
-
-        refs = list(self.mf.getReferers(n))
-        # The script is a toplevel item and is therefore referred to from the graph root (aka 'None')
-        self.assertEqual(refs, [None])
-
-
-        # 2. 'mod'
-        n = self.mf.findNode('mod')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = list(self.mf.getReferences(n))
-        self.assertEqual(refs, [])
-
-        #refs = list(self.mf.getReferers(n))
-        #self.assertEquals(refs, [])
-
-        # 3. 'pkg'
-        n = self.mf.findNode('pkg')
-        self.assertIsInstance(n, modulegraph.Package)
-        refs = list(self.mf.getReferences(n))
-        self.maxDiff = None
-        self.assertEqual(refs, [n])
-
-        #refs = list(self.mf.getReferers(n))
-        #self.assertEquals(refs, [])
-
-        # 4. pkg.mod
-        n = self.mf.findNode('pkg.mod')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([self.mf.findNode('pkg')]))
-        ed = self.mf.edgeData(n, self.mf.findNode('pkg'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-
-        # 5. pkg.oldstyle
-        n = self.mf.findNode('pkg.oldstyle')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        if sys.version_info[0] == 2:
-            n2 = self.mf.findNode('pkg.mod')
-        else:
-            n2 = self.mf.findNode('mod')
-        self.assertEqual(refs, set([self.mf.findNode('pkg'), n2]))
-        ed = self.mf.edgeData(n, n2)
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-
-        # 6. pkg.relative
-        n = self.mf.findNode('pkg.relative')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([self.mf.findNode('__future__'), self.mf.findNode('pkg'), self.mf.findNode('pkg.mod')]))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('pkg.mod'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=True, conditional=False, function=False, tryexcept=False))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('__future__'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-        #ed = self.mf.edgeData(n, self.mf.findNode('__future__.absolute_import'))
-        #self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        #self.assertEqual(ed, modulegraph.DependencyInfo(
-            #fromlist=True, conditional=False, function=False, tryexcept=False))
-
-        # 7. pkg.toplevel
-        n = self.mf.findNode('pkg.toplevel')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([self.mf.findNode('__future__'), self.mf.findNode('pkg'), self.mf.findNode('mod')]))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('mod'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('__future__'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-        #ed = self.mf.edgeData(n, self.mf.findNode('__future__.absolute_import'))
-        #self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        #self.assertEqual(ed, modulegraph.DependencyInfo(
-            #fromlist=True, conditional=False, function=False, tryexcept=False))
-
-        # 8. pkg.subpkg
-        n = self.mf.findNode('pkg.subpkg')
-        self.assertIsInstance(n, modulegraph.Package)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([self.mf.findNode('pkg')]))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('pkg'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-        # 9. pkg.subpkg.relative
-        n = self.mf.findNode('pkg.subpkg.relative')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([self.mf.findNode('__future__'), self.mf.findNode('pkg'), self.mf.findNode('pkg.subpkg'), self.mf.findNode('pkg.mod')]))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('pkg.subpkg'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=False, conditional=False, function=False, tryexcept=False))
-
-        ed = self.mf.edgeData(n, self.mf.findNode('pkg.mod'))
-        self.assertIsInstance(ed, modulegraph.DependencyInfo)
-        self.assertEqual(ed, modulegraph.DependencyInfo(
-            fromlist=True, conditional=False, function=False, tryexcept=False))
-
-        # 10. pkg.subpkg.relative2
-        n = self.mf.findNode('pkg.subpkg.relative2')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([self.mf.findNode('pkg.subpkg'), self.mf.findNode('pkg.relimport'), self.mf.findNode('__future__')]))
-
-        # 10. pkg.subpkg.mod2
-        n = self.mf.findNode('pkg.subpkg.mod2')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-        refs = set(self.mf.getReferences(n))
-        self.assertEqual(refs, set([
-            self.mf.findNode('__future__'),
-            self.mf.findNode('pkg.subpkg'),
-            self.mf.findNode('pkg.sub2.mod'),
-            self.mf.findNode('pkg.sub2'),
-        ]))
-
-
-    def testRootModule(self):
-        node = self.mf.findNode('mod')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'mod')
-
-    def testRootPkg(self):
-        node = self.mf.findNode('pkg')
-        self.assertIsInstance(node, modulegraph.Package)
-        self.assertEqual(node.identifier, 'pkg')
-
-    def testSubModule(self):
-        node = self.mf.findNode('pkg.mod')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.mod')
-
-    if sys.version_info[0] == 2:
-        def testOldStyle(self):
-            node = self.mf.findNode('pkg.oldstyle')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-            self.assertEqual(node.identifier, 'pkg.oldstyle')
-            sub = [ n for n in self.mf.get_edges(node)[0] if n.identifier != '__future__' ][0]
-            self.assertEqual(sub.identifier, 'pkg.mod')
-    else:
-        # python3 always has __future__.absolute_import
-        def testOldStyle(self):
-            node = self.mf.findNode('pkg.oldstyle')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-            self.assertEqual(node.identifier, 'pkg.oldstyle')
-            sub = [ n for n in self.mf.get_edges(node)[0] if n.identifier != '__future__' ][0]
-            self.assertEqual(sub.identifier, 'mod')
-
-    def testNewStyle(self):
-        node = self.mf.findNode('pkg.toplevel')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.toplevel')
-        sub = [ n for n in self.mf.get_edges(node)[0] if not n.identifier.startswith('__future__')][0]
-        self.assertEqual(sub.identifier, 'mod')
-
-    def testRelativeImport(self):
-        node = self.mf.findNode('pkg.relative')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.relative')
-        sub = [ n for n in self.mf.get_edges(node)[0] if not n.identifier.startswith('__future__') ][0]
-        self.assertIsInstance(sub, modulegraph.Package)
-        self.assertEqual(sub.identifier, 'pkg')
-
-        node = self.mf.findNode('pkg.subpkg.relative')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.subpkg.relative')
-        sub = [ n for n in self.mf.get_edges(node)[0] if not n.identifier.startswith('__future__') ][0]
-        self.assertIsInstance(sub, modulegraph.Package)
-        self.assertEqual(sub.identifier, 'pkg')
-
-        node = self.mf.findNode('pkg.subpkg.mod2')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.subpkg.mod2')
-        sub = [ n for n in self.mf.get_edges(node)[0] if not n.identifier.startswith('__future__') ][0]
-        self.assertIsInstance(sub, modulegraph.SourceModule)
-        self.assertEqual(sub.identifier, 'pkg.sub2.mod')
-
-        node = self.mf.findNode('pkg.subpkg.relative2')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'pkg.subpkg.relative2')
-
-        node = self.mf.findNode('pkg.relimport')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-class TestRegressions1 (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r", value, types)
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-regr1')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        self.mf.run_script(os.path.join(root, 'main_script.py'))
-
-    def testRegr1(self):
-        node = self.mf.findNode('pkg.a')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        node = self.mf.findNode('pkg.b')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-
-    def testMissingPathEntry(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'nosuchdirectory')
-        try:
-            mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        except os.error:
-            self.fail('modulegraph initialiser raises os.error')
-
-class TestRegressions2 (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-regr2')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        self.mf.run_script(os.path.join(root, 'main_script.py'))
-
-    def testRegr1(self):
-        node = self.mf.findNode('pkg.base')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        node = self.mf.findNode('pkg.pkg')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-class TestRegressions3 (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def assertStartswith(self, value, test):
-        if not value.startswith(test):
-            self.fail("%r does not start with %r"%(value, test))
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-regr3')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        self.mf.run_script(os.path.join(root, 'script.py'))
-
-    def testRegr1(self):
-        node = self.mf.findNode('mypkg.distutils')
-        self.assertIsInstance(node, modulegraph.Package)
-        node = self.mf.findNode('mypkg.distutils.ccompiler')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertStartswith(node.filename, os.path.dirname(__file__))
-
-        import distutils.sysconfig, distutils.ccompiler
-        node = self.mf.findNode('distutils.ccompiler')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(os.path.dirname(node.filename),
-                os.path.dirname(distutils.ccompiler.__file__))
-
-        node = self.mf.findNode('distutils.sysconfig')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(os.path.dirname(node.filename),
-                os.path.dirname(distutils.sysconfig.__file__))
-
-class TestRegression4 (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-regr4')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        self.mf.run_script(os.path.join(root, 'script.py'))
-
-    def testRegr1(self):
-        node = self.mf.findNode('pkg.core')
-        self.assertIsInstance(node, modulegraph.Package)
-
-        node = self.mf.findNode('pkg.core.callables')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        node = self.mf.findNode('pkg.core.listener')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        node = self.mf.findNode('pkg.core.listenerimpl')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-class TestRegression5 (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-regr5')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        self.mf.run_script(os.path.join(root, 'script.py'))
-
-    def testRegr1(self):
-        node = self.mf.findNode('distutils')
-        self.assertIsInstance(node, modulegraph.Package)
-        self.assertIn('distutils/__init__', node.filename)
-
-class TestDeeplyNested (unittest.TestCase):
-    def setUp(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-regr6')
-        self.mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        self.mf.run_script(os.path.join(root, 'script.py'))
-
-    def testRegr(self):
-        node = self.mf.findNode('os')
-        self.assertTrue(node is not None)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_modulegraph.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_modulegraph.py
deleted file mode 100644
index 0ee724b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_modulegraph.py
+++ /dev/null
@@ -1,1060 +0,0 @@
-import unittest
-from modulegraph import modulegraph
-import pkg_resources
-import os
-import imp
-import sys
-import shutil
-import warnings
-from altgraph import Graph
-import textwrap
-import xml.etree.ElementTree as ET
-import pickle
-
-try:
-    bytes
-except NameError:
-    bytes = str
-
-try:
-    from StringIO import StringIO
-except ImportError:
-    from io import StringIO
-
-TESTDATA = os.path.join(
-        os.path.dirname(os.path.abspath(__file__)),
-        "testdata", "nspkg")
-
-try:
-    expectedFailure = unittest.expectedFailure
-except AttributeError:
-    import functools
-    def expectedFailure(function):
-        @functools.wraps(function)
-        def wrapper(*args, **kwds):
-            try:
-                function(*args, **kwds)
-            except AssertionError:
-                pass
-
-            else:
-                self.fail("unexpected pass")
-
-class TestDependencyInfo (unittest.TestCase):
-    def test_pickling(self):
-        info = modulegraph.DependencyInfo(function=True, conditional=False, tryexcept=True, fromlist=False)
-        for proto in range(pickle.HIGHEST_PROTOCOL + 1):
-            b = pickle.dumps(info, proto)
-            self.assertTrue(isinstance(b, bytes))
-
-            o = pickle.loads(b)
-            self.assertEqual(o, info)
-
-    def test_merging(self):
-        info1 = modulegraph.DependencyInfo(function=True, conditional=False, tryexcept=True, fromlist=False)
-        info2 = modulegraph.DependencyInfo(function=False, conditional=True, tryexcept=True, fromlist=False)
-        self.assertEqual(
-            info1._merged(info2), modulegraph.DependencyInfo(function=True, conditional=True, tryexcept=True, fromlist=False))
-
-        info2 = modulegraph.DependencyInfo(function=False, conditional=True, tryexcept=False, fromlist=False)
-        self.assertEqual(
-            info1._merged(info2), modulegraph.DependencyInfo(function=True, conditional=True, tryexcept=True, fromlist=False))
-
-        info2 = modulegraph.DependencyInfo(function=False, conditional=False, tryexcept=False, fromlist=False)
-        self.assertEqual(
-            info1._merged(info2), modulegraph.DependencyInfo(function=False, conditional=False, tryexcept=False, fromlist=False))
-
-        info1 = modulegraph.DependencyInfo(function=True, conditional=False, tryexcept=True, fromlist=True)
-        self.assertEqual(
-            info1._merged(info2), modulegraph.DependencyInfo(function=False, conditional=False, tryexcept=False, fromlist=False))
-
-        info2 = modulegraph.DependencyInfo(function=False, conditional=False, tryexcept=False, fromlist=True)
-        self.assertEqual(
-            info1._merged(info2), modulegraph.DependencyInfo(function=False, conditional=False, tryexcept=False, fromlist=True))
-
-
-class TestFunctions (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, obj, types):
-            self.assertTrue(isinstance(obj, types), '%r is not instance of %r'%(obj, types))
-
-    def test_eval_str_tuple(self):
-        for v in [
-            '()',
-            '("hello",)',
-            '("hello", "world")',
-            "('hello',)",
-            "('hello', 'world')",
-            "('hello', \"world\")",
-            ]:
-
-            self.assertEqual(modulegraph._eval_str_tuple(v), eval(v))
-
-        self.assertRaises(ValueError, modulegraph._eval_str_tuple, "")
-        self.assertRaises(ValueError, modulegraph._eval_str_tuple, "'a'")
-        self.assertRaises(ValueError, modulegraph._eval_str_tuple, "'a', 'b'")
-        self.assertRaises(ValueError, modulegraph._eval_str_tuple, "('a', ('b', 'c'))")
-        self.assertRaises(ValueError, modulegraph._eval_str_tuple, "('a', ('b\", 'c'))")
-
-    def test_namespace_package_path(self):
-        class DS (object):
-            def __init__(self, path, namespace_packages=None):
-                self.location = path
-                self._namespace_packages = namespace_packages
-
-            def has_metadata(self, key):
-                if key == 'namespace_packages.txt':
-                    return self._namespace_packages is not None
-
-                raise ValueError("invalid lookup key")
-
-            def get_metadata(self, key):
-                if key == 'namespace_packages.txt':
-                    if self._namespace_packages is None:
-                        raise ValueError("no file")
-
-                    return self._namespace_packages
-
-                raise ValueError("invalid lookup key")
-
-        class WS (object):
-            def __init__(self, path=None):
-                pass
-
-            def __iter__(self):
-                yield DS("/pkg/pkg1")
-                yield DS("/pkg/pkg2", "foo\n")
-                yield DS("/pkg/pkg3", "bar.baz\n")
-                yield DS("/pkg/pkg4", "foobar\nfoo\n")
-
-        saved_ws = pkg_resources.WorkingSet
-        try:
-            pkg_resources.WorkingSet = WS
-
-            self.assertEqual(modulegraph._namespace_package_path("sys", ["appdir/pkg"]), ["appdir/pkg"])
-            self.assertEqual(modulegraph._namespace_package_path("foo", ["appdir/pkg"]), ["appdir/pkg", "/pkg/pkg2/foo", "/pkg/pkg4/foo"])
-            self.assertEqual(modulegraph._namespace_package_path("bar.baz", ["appdir/pkg"]), ["appdir/pkg", "/pkg/pkg3/bar/baz"])
-
-        finally:
-            pkg_resources.WorkingSet = saved_ws
-
-    def test_os_listdir(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)), 'testdata')
-
-        self.assertEqual(modulegraph.os_listdir('/etc/'), os.listdir('/etc'))
-        self.assertRaises(IOError, modulegraph.os_listdir, '/etc/hosts/foobar')
-        self.assertRaises(IOError, modulegraph.os_listdir, os.path.join(root, 'test.egg', 'bar'))
-
-        self.assertEqual(list(sorted(modulegraph.os_listdir(os.path.join(root, 'test.egg', 'foo')))),
-            [ 'bar', 'bar.txt', 'baz.txt' ])
-
-    def test_code_to_file(self):
-        try:
-            code = modulegraph._code_to_file.__code__
-        except AttributeError:
-            code = modulegraph._code_to_file.func_code
-
-        data = modulegraph._code_to_file(code)
-        self.assertTrue(hasattr(data, 'read'))
-
-        content = data.read()
-        self.assertIsInstance(content, bytes)
-        data.close()
-
-    def test_find_module(self):
-        for path in ('syspath', 'syspath.zip', 'syspath.egg'):
-            path = os.path.join(os.path.dirname(TESTDATA), path)
-            if os.path.exists(os.path.join(path, 'mymodule.pyc')):
-                os.unlink(os.path.join(path, 'mymodule.pyc'))
-
-            # Plain module
-            info = modulegraph.find_module('mymodule', path=[path] + sys.path)
-
-            fp = info[0]
-            filename = info[1]
-            description = info[2]
-
-            self.assertTrue(hasattr(fp, 'read'))
-
-            if path.endswith('.zip') or path.endswith('.egg'):
-                # Zip importers may precompile
-                if filename.endswith('.py'):
-                    self.assertEqual(filename, os.path.join(path, 'mymodule.py'))
-                    self.assertEqual(description, ('.py', 'rU', imp.PY_SOURCE))
-
-                else:
-                    self.assertEqual(filename, os.path.join(path, 'mymodule.pyc'))
-                    self.assertEqual(description, ('.pyc', 'rb', imp.PY_COMPILED))
-
-            else:
-                self.assertEqual(filename, os.path.join(path, 'mymodule.py'))
-                self.assertEqual(description, ('.py', 'rU', imp.PY_SOURCE))
-
-            # Compiled plain module, no source
-            if path.endswith('.zip') or path.endswith('.egg'):
-                self.assertRaises(ImportError, modulegraph.find_module, 'mymodule2', path=[path] + sys.path)
-
-            else:
-                info = modulegraph.find_module('mymodule2', path=[path] + sys.path)
-
-                fp = info[0]
-                filename = info[1]
-                description = info[2]
-
-                self.assertTrue(hasattr(fp, 'read'))
-                self.assertEqual(filename, os.path.join(path, 'mymodule2.pyc'))
-                self.assertEqual(description, ('.pyc', 'rb', imp.PY_COMPILED))
-
-                fp.close()
-
-            # Compiled plain module, with source
-#            info = modulegraph.find_module('mymodule3', path=[path] + sys.path)
-#
-#            fp = info[0]
-#            filename = info[1]
-#            description = info[2]
-#
-#            self.assertTrue(hasattr(fp, 'read'))
-#
-#            if sys.version_info[:2] >= (3,2):
-#                self.assertEqual(filename, os.path.join(path, '__pycache__', 'mymodule3.cpython-32.pyc'))
-#            else:
-#                self.assertEqual(filename, os.path.join(path, 'mymodule3.pyc'))
-#            self.assertEqual(description, ('.pyc', 'rb', imp.PY_COMPILED))
-
-
-            # Package
-            info = modulegraph.find_module('mypkg', path=[path] + sys.path)
-            fp = info[0]
-            filename = info[1]
-            description = info[2]
-
-            self.assertEqual(fp, None)
-            self.assertEqual(filename, os.path.join(path, 'mypkg'))
-            self.assertEqual(description, ('', '', imp.PKG_DIRECTORY))
-
-            # Extension
-            if path.endswith('.zip'):
-                self.assertRaises(ImportError, modulegraph.find_module, 'myext', path=[path] + sys.path)
-
-            else:
-                info = modulegraph.find_module('myext', path=[path] + sys.path)
-                fp = info[0]
-                filename = info[1]
-                description = info[2]
-
-                if sys.platform == 'win32':
-                    ext = '.pyd'
-                else:
-                    # This is a ly, but is good enough for now
-                    ext = '.so'
-
-                self.assertEqual(filename, os.path.join(path, 'myext' + ext))
-                self.assertEqual(description, (ext, 'rb', imp.C_EXTENSION))
-                self.assertEqual(fp, None)
-
-    def test_moduleInfoForPath(self):
-        self.assertEqual(modulegraph.moduleInfoForPath("/somewhere/else/file.txt"), None)
-
-        info = modulegraph.moduleInfoForPath("/somewhere/else/file.py")
-        self.assertEqual(info[0], "file")
-        if sys.version_info[:2] >= (3,4):
-            self.assertEqual(info[1], "r")
-        else:
-            self.assertEqual(info[1], "U")
-        self.assertEqual(info[2], imp.PY_SOURCE)
-
-        info = modulegraph.moduleInfoForPath("/somewhere/else/file.pyc")
-        self.assertEqual(info[0], "file")
-        self.assertEqual(info[1], "rb")
-        self.assertEqual(info[2], imp.PY_COMPILED)
-
-        if sys.platform in ('darwin', 'linux2'):
-            info = modulegraph.moduleInfoForPath("/somewhere/else/file.so")
-            self.assertEqual(info[0], "file")
-            self.assertEqual(info[1], "rb")
-            self.assertEqual(info[2], imp.C_EXTENSION)
-
-        elif sys.platform in ('win32',):
-            info = modulegraph.moduleInfoForPath("/somewhere/else/file.pyd")
-            self.assertEqual(info[0], "file")
-            self.assertEqual(info[1], "rb")
-            self.assertEqual(info[2], imp.C_EXTENSION)
-
-    if sys.version_info[:2] > (2,5):
-        exec(textwrap.dedent('''\
-            def test_deprecated(self):
-                saved_add = modulegraph.addPackagePath
-                saved_replace = modulegraph.replacePackage
-                try:
-                    called = []
-
-                    def log_add(*args, **kwds):
-                        called.append(('add', args, kwds))
-                    def log_replace(*args, **kwds):
-                        called.append(('replace', args, kwds))
-
-                    modulegraph.addPackagePath = log_add
-                    modulegraph.replacePackage = log_replace
-
-                    with warnings.catch_warnings(record=True) as w:
-                        warnings.simplefilter("always")
-                        modulegraph.ReplacePackage('a', 'b')
-                        modulegraph.AddPackagePath('c', 'd')
-
-                    self.assertEqual(len(w), 2)
-                    self.assertTrue(w[-1].category is DeprecationWarning)
-                    self.assertTrue(w[-2].category is DeprecationWarning)
-
-                    self.assertEqual(called, [
-                        ('replace', ('a', 'b'), {}),
-                        ('add', ('c', 'd'), {}),
-                    ])
-
-                finally:
-                    modulegraph.addPackagePath = saved_add
-                    modulegraph.replacePackage = saved_replace
-            '''), locals(), globals())
-
-    def test_addPackage(self):
-        saved = modulegraph._packagePathMap
-        self.assertIsInstance(saved, dict)
-        try:
-            modulegraph._packagePathMap = {}
-
-            modulegraph.addPackagePath('foo', 'a')
-            self.assertEqual(modulegraph._packagePathMap, { 'foo': ['a'] })
-
-            modulegraph.addPackagePath('foo', 'b')
-            self.assertEqual(modulegraph._packagePathMap, { 'foo': ['a', 'b'] })
-
-            modulegraph.addPackagePath('bar', 'b')
-            self.assertEqual(modulegraph._packagePathMap, { 'foo': ['a', 'b'], 'bar': ['b'] })
-
-        finally:
-            modulegraph._packagePathMap = saved
-
-
-    def test_replacePackage(self):
-        saved = modulegraph._replacePackageMap
-        self.assertIsInstance(saved, dict)
-        try:
-            modulegraph._replacePackageMap = {}
-
-            modulegraph.replacePackage("a", "b")
-            self.assertEqual(modulegraph._replacePackageMap, {"a": "b"})
-            modulegraph.replacePackage("a", "c")
-            self.assertEqual(modulegraph._replacePackageMap, {"a": "c"})
-            modulegraph.replacePackage("b", "c")
-            self.assertEqual(modulegraph._replacePackageMap, {"a": "c", 'b': 'c'})
-
-        finally:
-            modulegraph._replacePackageMap = saved
-
-class TestNode (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, obj, types):
-            self.assertTrue(isinstance(obj, types), '%r is not instance of %r'%(obj, types))
-    def testBasicAttributes(self):
-        n = modulegraph.Node("foobar.xyz")
-        self.assertIsInstance(n.debug, int)
-        self.assertEqual(n.identifier, n.graphident)
-        self.assertEqual(n.identifier, 'foobar.xyz')
-        self.assertEqual(n.filename, None)
-        self.assertEqual(n.packagepath, None)
-        self.assertEqual(n.code, None)
-        self.assertEqual(n.globalnames, set())
-        self.assertEqual(n.starimports, set())
-
-    def testMapping(self):
-        n = modulegraph.Node("foobar.xyz")
-        self.assertEqual(n._namespace, {})
-
-        self.assertFalse('foo' in n)
-        self.assertRaises(KeyError, n.__getitem__, 'foo')
-        self.assertEqual(n.get('foo'), None)
-        self.assertEqual(n.get('foo', 'a'), 'a')
-        n['foo'] = 42
-        self.assertEqual(n['foo'], 42)
-        self.assertTrue('foo' in n)
-        self.assertEqual(n._namespace, {'foo':42})
-
-    def testOrder(self):
-        n1 = modulegraph.Node("n1")
-        n2 = modulegraph.Node("n2")
-
-        self.assertTrue(n1 < n2)
-        self.assertFalse(n2 < n1)
-        self.assertTrue(n1 <= n1)
-        self.assertFalse(n1 == n2)
-        self.assertTrue(n1 == n1)
-        self.assertTrue(n1 != n2)
-        self.assertFalse(n1 != n1)
-        self.assertTrue(n2 > n1)
-        self.assertFalse(n1 > n2)
-        self.assertTrue(n1 >= n1)
-        self.assertTrue(n2 >= n1)
-
-    def testHashing(self):
-        n1a = modulegraph.Node('n1')
-        n1b = modulegraph.Node('n1')
-        n2 = modulegraph.Node('n2')
-
-        d = {}
-        d[n1a] = 'n1'
-        d[n2] = 'n2'
-        self.assertEqual(d[n1b], 'n1')
-        self.assertEqual(d[n2], 'n2')
-
-    def test_infoTuple(self):
-        n = modulegraph.Node('n1')
-        self.assertEqual(n.infoTuple(), ('n1',))
-
-    def assertNoMethods(self, klass):
-        d = dict(klass.__dict__)
-        del d['__doc__']
-        del d['__module__']
-        if '__qualname__' in d:
-            # New in Python 3.3
-            del d['__qualname__']
-        if '__dict__' in d:
-            # New in Python 3.4
-            del d['__dict__']
-        self.assertEqual(d, {})
-
-    def assertHasExactMethods(self, klass, *methods):
-        d = dict(klass.__dict__)
-        del d['__doc__']
-        del d['__module__']
-        if '__qualname__' in d:
-            # New in Python 3.3
-            del d['__qualname__']
-        if '__dict__' in d:
-            # New in Python 3.4
-            del d['__dict__']
-
-        for nm in methods:
-            self.assertTrue(nm in d, "%s doesn't have attribute %r"%(klass, nm))
-            del d[nm]
-
-        self.assertEqual(d, {})
-
-
-    if not hasattr(unittest.TestCase, 'assertIsSubclass'):
-        def assertIsSubclass(self, cls1, cls2, message=None):
-            self.assertTrue(issubclass(cls1, cls2),
-                    message or "%r is not a subclass of %r"%(cls1, cls2))
-
-    def test_subclasses(self):
-        self.assertIsSubclass(modulegraph.AliasNode, modulegraph.Node)
-        self.assertIsSubclass(modulegraph.Script, modulegraph.Node)
-        self.assertIsSubclass(modulegraph.BadModule, modulegraph.Node)
-        self.assertIsSubclass(modulegraph.ExcludedModule, modulegraph.BadModule)
-        self.assertIsSubclass(modulegraph.MissingModule, modulegraph.BadModule)
-        self.assertIsSubclass(modulegraph.BaseModule, modulegraph.Node)
-        self.assertIsSubclass(modulegraph.BuiltinModule, modulegraph.BaseModule)
-        self.assertIsSubclass(modulegraph.SourceModule, modulegraph.BaseModule)
-        self.assertIsSubclass(modulegraph.CompiledModule, modulegraph.BaseModule)
-        self.assertIsSubclass(modulegraph.Package, modulegraph.BaseModule)
-        self.assertIsSubclass(modulegraph.Extension, modulegraph.BaseModule)
-
-        # These classes have no new functionality, check that no code
-        # got added:
-        self.assertNoMethods(modulegraph.BadModule)
-        self.assertNoMethods(modulegraph.ExcludedModule)
-        self.assertNoMethods(modulegraph.MissingModule)
-        self.assertNoMethods(modulegraph.BuiltinModule)
-        self.assertNoMethods(modulegraph.SourceModule)
-        self.assertNoMethods(modulegraph.CompiledModule)
-        self.assertNoMethods(modulegraph.Package)
-        self.assertNoMethods(modulegraph.Extension)
-
-        # AliasNode is basicly a clone of an existing node
-        self.assertHasExactMethods(modulegraph.Script, '__init__', 'infoTuple')
-        n1 = modulegraph.Node('n1')
-        n1.packagepath = ['a', 'b']
-
-        a1 = modulegraph.AliasNode('a1', n1)
-        self.assertEqual(a1.graphident, 'a1')
-        self.assertEqual(a1.identifier, 'n1')
-        self.assertTrue(a1.packagepath is n1.packagepath)
-        self.assertTrue(a1._namespace is n1._namespace)
-        self.assertTrue(a1.globalnames is n1.globalnames)
-        self.assertTrue(a1.starimports is n1.starimports)
-
-        v = a1.infoTuple()
-        self.assertEqual(v, ('a1', 'n1'))
-
-        # Scripts have a filename
-        self.assertHasExactMethods(modulegraph.Script, '__init__', 'infoTuple')
-        s1 = modulegraph.Script('do_import')
-        self.assertEqual(s1.graphident, 'do_import')
-        self.assertEqual(s1.identifier, 'do_import')
-        self.assertEqual(s1.filename, 'do_import')
-
-        v = s1.infoTuple()
-        self.assertEqual(v, ('do_import',))
-
-        # BaseModule adds some attributes and a custom infotuple
-        self.assertHasExactMethods(modulegraph.BaseModule, '__init__', 'infoTuple')
-        m1 = modulegraph.BaseModule('foo')
-        self.assertEqual(m1.graphident, 'foo')
-        self.assertEqual(m1.identifier, 'foo')
-        self.assertEqual(m1.filename, None)
-        self.assertEqual(m1.packagepath, None)
-
-        m1 = modulegraph.BaseModule('foo', 'bar',  ['a'])
-        self.assertEqual(m1.graphident, 'foo')
-        self.assertEqual(m1.identifier, 'foo')
-        self.assertEqual(m1.filename, 'bar')
-        self.assertEqual(m1.packagepath, ['a'])
-
-class TestModuleGraph (unittest.TestCase):
-    # Test for class modulegraph.modulegraph.ModuleGraph
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, obj, types):
-            self.assertTrue(isinstance(obj, types), '%r is not instance of %r'%(obj, types))
-
-    def test_constructor(self):
-        o = modulegraph.ModuleGraph()
-        self.assertTrue(o.path is sys.path)
-        self.assertEqual(o.lazynodes, {})
-        self.assertEqual(o.replace_paths, ())
-        self.assertEqual(o.debug, 0)
-
-        # Stricter tests would be nice, but that requires
-        # better control over what's on sys.path
-        self.assertIsInstance(o.nspackages, dict)
-
-        g = Graph.Graph()
-        o = modulegraph.ModuleGraph(['a', 'b', 'c'], ['modA'], [
-                ('fromA', 'toB'), ('fromC', 'toD')],
-                {
-                    'modA': ['modB', 'modC'],
-                    'modC': ['modE', 'modF'],
-                }, g, 1)
-        self.assertEqual(o.path, ['a', 'b', 'c'])
-        self.assertEqual(o.lazynodes, {
-            'modA': None,
-            'modC': ['modE', 'modF'],
-        })
-        self.assertEqual(o.replace_paths, [('fromA', 'toB'), ('fromC', 'toD')])
-        self.assertEqual(o.nspackages, {})
-        self.assertTrue(o.graph is g)
-        self.assertEqual(o.debug, 1)
-
-    def test_calc_setuptools_nspackages(self):
-        stdlib = [ fn for fn in sys.path if fn.startswith(sys.prefix) and 'site-packages' not in fn ]
-        for subdir in [ nm for nm in os.listdir(TESTDATA) if nm != 'src' ]:
-            graph = modulegraph.ModuleGraph(path=[
-                    os.path.join(TESTDATA, subdir, "parent"),
-                    os.path.join(TESTDATA, subdir, "child"),
-                ] + stdlib)
-
-            pkgs = graph.nspackages
-            self.assertTrue('namedpkg' in pkgs)
-            self.assertEqual(set(pkgs['namedpkg']),
-                    set([
-                        os.path.join(TESTDATA, subdir, "parent", "namedpkg"),
-                        os.path.join(TESTDATA, subdir, "child", "namedpkg"),
-                    ]))
-            self.assertFalse(os.path.exists(os.path.join(TESTDATA, subdir, "parent", "namedpkg", "__init__.py")))
-            self.assertFalse(os.path.exists(os.path.join(TESTDATA, subdir, "child", "namedpkg", "__init__.py")))
-
-    def testImpliedReference(self):
-        graph = modulegraph.ModuleGraph()
-
-        record = []
-        def import_hook(*args):
-            record.append(('import_hook',) + args)
-            return [graph.createNode(modulegraph.Node, args[0])]
-
-        def _safe_import_hook(*args):
-            record.append(('_safe_import_hook',) + args)
-            return [graph.createNode(modulegraph.Node, args[0])]
-
-        graph.import_hook = import_hook
-        graph._safe_import_hook = _safe_import_hook
-
-        n1 = graph.createNode(modulegraph.Node, 'n1')
-        n2 = graph.createNode(modulegraph.Node, 'n2')
-
-        graph.implyNodeReference(n1, n2)
-        outs, ins = map(list, graph.get_edges(n1))
-        self.assertEqual(outs, [n2])
-        self.assertEqual(ins, [])
-
-        self.assertEqual(record, [])
-
-        graph.implyNodeReference(n2, "n3")
-        n3 = graph.findNode('n3')
-        outs, ins = map(list, graph.get_edges(n2))
-        self.assertEqual(outs, [n3])
-        self.assertEqual(ins, [n1])
-        self.assertEqual(record, [
-            ('_safe_import_hook', 'n3', n2, None)
-        ])
-
-
-
-    @expectedFailure
-    def test_findNode(self):
-        self.fail("findNode")
-
-    def test_run_script(self):
-        script = os.path.join(os.path.dirname(TESTDATA), 'script')
-
-        graph = modulegraph.ModuleGraph()
-        master = graph.createNode(modulegraph.Node, 'root')
-        m = graph.run_script(script, master)
-        self.assertEqual(list(graph.get_edges(master)[0])[0], m)
-        self.assertEqual(set(graph.get_edges(m)[0]), set([
-            graph.findNode('sys'),
-            graph.findNode('os'),
-        ]))
-
-    @expectedFailure
-    def test_import_hook(self):
-        self.fail("import_hook")
-
-    def test_determine_parent(self):
-        graph = modulegraph.ModuleGraph()
-        graph.import_hook('os.path', None)
-        graph.import_hook('idlelib', None)
-        graph.import_hook('xml.dom', None)
-
-        for node in graph.nodes():
-            if isinstance(node, modulegraph.Package):
-                break
-        else:
-            self.fail("No package located, should have at least 'os'")
-
-        self.assertIsInstance(node, modulegraph.Package)
-        parent = graph._determine_parent(node)
-        self.assertEqual(parent.identifier, node.identifier)
-        self.assertEqual(parent, graph.findNode(node.identifier))
-        self.assertTrue(isinstance(parent, modulegraph.Package))
-
-        # XXX: Might be a usecase for some odd code in determine_parent...
-        #node = modulegraph.Package('encodings')
-        #node.packagepath = parent.packagepath
-        #m = graph._determine_parent(node)
-        #self.assertTrue(m is parent)
-
-        m = graph.findNode('xml')
-        self.assertEqual(graph._determine_parent(m), m)
-
-        m = graph.findNode('xml.dom')
-        self.assertEqual(graph._determine_parent(m), graph.findNode('xml.dom'))
-
-
-    @expectedFailure
-    def test_find_head_package(self):
-        self.fail("find_head_package")
-
-    def test_load_tail(self):
-        # XXX: This test is dodgy!
-        graph = modulegraph.ModuleGraph()
-
-        record = []
-        def _import_module(partname, fqname, parent):
-            record.append((partname, fqname, parent))
-            if partname == 'raises' or '.raises.' in fqname:
-                return None
-            return modulegraph.Node(fqname)
-
-        graph._import_module = _import_module
-
-        record = []
-        root = modulegraph.Node('root')
-        m = graph._load_tail(root, '')
-        self.assertTrue(m is root)
-        self.assertEqual(record, [
-            ])
-
-        record = []
-        root = modulegraph.Node('root')
-        m = graph._load_tail(root, 'sub')
-        self.assertFalse(m is root)
-        self.assertEqual(record, [
-                ('sub', 'root.sub', root),
-            ])
-
-        record = []
-        root = modulegraph.Node('root')
-        m = graph._load_tail(root, 'sub.sub1')
-        self.assertFalse(m is root)
-        node = modulegraph.Node('root.sub')
-        self.assertEqual(record, [
-                ('sub', 'root.sub', root),
-                ('sub1', 'root.sub.sub1', node),
-            ])
-
-        record = []
-        root = modulegraph.Node('root')
-        m = graph._load_tail(root, 'sub.sub1.sub2')
-        self.assertFalse(m is root)
-        node = modulegraph.Node('root.sub')
-        node2 = modulegraph.Node('root.sub.sub1')
-        self.assertEqual(record, [
-                ('sub', 'root.sub', root),
-                ('sub1', 'root.sub.sub1', node),
-                ('sub2', 'root.sub.sub1.sub2', node2),
-            ])
-
-        n = graph._load_tail(root, 'raises')
-        self.assertIsInstance(n, modulegraph.MissingModule)
-        self.assertEqual(n.identifier, 'root.raises')
-
-        n = graph._load_tail(root, 'sub.raises')
-        self.assertIsInstance(n, modulegraph.MissingModule)
-        self.assertEqual(n.identifier, 'root.sub.raises')
-
-        n = graph._load_tail(root, 'sub.raises.sub')
-        self.assertIsInstance(n, modulegraph.MissingModule)
-        self.assertEqual(n.identifier, 'root.sub.raises.sub')
-
-
-
-    @expectedFailure
-    def test_ensure_fromlist(self):
-        # 1. basic 'from module import name, name'
-        # 2. 'from module import *'
-        # 3. from module import os
-        #    (where 'os' is not a name in 'module',
-        #     should create MissingModule node, and
-        #     should *not* refer to the global os)
-        self.fail("ensure_fromlist")
-
-    @expectedFailure
-    def test_find_all_submodules(self):
-        # 1. basic
-        # 2. no packagepath (basic module)
-        # 3. extensions, python modules
-        # 4. with/without zipfile
-        # 5. files that aren't python modules/extensions
-        self.fail("find_all_submodules")
-
-    @expectedFailure
-    def test_import_module(self):
-        self.fail("import_module")
-
-    @expectedFailure
-    def test_load_module(self):
-        self.fail("load_module")
-
-    @expectedFailure
-    def test_safe_import_hook(self):
-        self.fail("safe_import_hook")
-
-    @expectedFailure
-    def test_scan_code(self):
-        mod = modulegraph.Node('root')
-
-        graph = modulegraph.ModuleGraph()
-        code = compile('', '<test>', 'exec', 0, False)
-        graph.scan_code(code, mod)
-        self.assertEqual(list(graph.nodes()), [])
-
-        node_map = {}
-        def _safe_import(name, mod, fromlist, level):
-            if name in node_map:
-                node = node_map[name]
-            else:
-                node = modulegraph.Node(name)
-            node_map[name] = node
-            return [node]
-
-        graph = modulegraph.ModuleGraph()
-        graph._safe_import_hook = _safe_import
-
-        code = compile(textwrap.dedent('''\
-            import sys
-            import os.path
-
-            def testfunc():
-                import shutil
-            '''), '<test>', 'exec', 0, False)
-        graph.scan_code(code, mod)
-        modules = [node.identifier for node in graph.nodes()]
-        self.assertEqual(set(node_map), set(['sys', 'os.path', 'shutil']))
-
-
-        # from module import a, b, c
-        # from module import *
-        #  both:
-        #   -> with/without globals
-        #   -> with/without modules in globals (e.g,
-        #       from os import * adds dependency to os.path)
-        # from .module import a
-        # from ..module import a
-        #   -> check levels
-        # import name
-        # import a.b
-        #   -> should add dependency to a
-        # try to build case where commented out
-        # code would behave different than current code
-        # (Carbon.SomeMod contains 'import Sibling' seems
-        # to cause difference in real code)
-
-        self.fail("actual test needed")
-
-
-
-    @expectedFailure
-    def test_load_package(self):
-        self.fail("load_package")
-
-    def test_find_module(self):
-        record = []
-        def mock_finder(name, path):
-            record.append((name, path))
-            return saved_finder(name, path)
-
-        saved_finder = modulegraph.find_module
-        try:
-            modulegraph.find_module = mock_finder
-
-            graph = modulegraph.ModuleGraph()
-            m = graph._find_module('sys', None)
-            self.assertEqual(record, [])
-            self.assertEqual(m, (None, None, ("", "", imp.C_BUILTIN)))
-
-            modulegraph.find_module = saved_finder
-            xml = graph.import_hook("xml")[0]
-            self.assertEqual(xml.identifier, 'xml')
-            modulegraph.find_module = mock_finder
-
-            self.assertRaises(ImportError, graph._find_module, 'xml', None)
-
-            self.assertEqual(record, [])
-            m = graph._find_module('shutil', None)
-            self.assertEqual(record, [
-                ('shutil', graph.path),
-            ])
-            self.assertTrue(isinstance(m, tuple))
-            self.assertEqual(len(m), 3)
-            self.assertTrue(hasattr(m[0], 'read'))
-            self.assertIsInstance(m[0].read(), str)
-            srcfn = shutil.__file__
-            if srcfn.endswith('.pyc'):
-                srcfn = srcfn[:-1]
-            self.assertEqual(m[1], srcfn)
-            self.assertEqual(m[2], ('.py', 'rU', imp.PY_SOURCE))
-            m[0].close()
-
-            m2 = graph._find_module('shutil', None)
-            self.assertEqual(m[1:], m2[1:])
-            m2[0].close()
-
-
-            record[:] = []
-            m = graph._find_module('sax', xml.packagepath, xml)
-            self.assertEqual(m,
-                    (None, os.path.join(os.path.dirname(xml.filename), 'sax'),
-                    ('', '', imp.PKG_DIRECTORY)))
-            self.assertEqual(record, [
-                ('sax', xml.packagepath),
-            ])
-            if m[0] is not None: m[0].close()
-
-        finally:
-            modulegraph.find_module = saved_finder
-
-    @expectedFailure
-    def test_create_xref(self):
-        self.fail("create_xref")
-
-    @expectedFailure
-    def test_itergraphreport(self):
-        self.fail("itergraphreport")
-
-    def test_report(self):
-        graph = modulegraph.ModuleGraph()
-
-        saved_stdout = sys.stdout
-        try:
-            fp = sys.stdout = StringIO()
-            graph.report()
-            lines = fp.getvalue().splitlines()
-            fp.close()
-
-            self.assertEqual(len(lines), 3)
-            self.assertEqual(lines[0], '')
-            self.assertEqual(lines[1], 'Class           Name                      File')
-            self.assertEqual(lines[2], '-----           ----                      ----')
-
-            fp = sys.stdout = StringIO()
-            graph._safe_import_hook('os', None, ())
-            graph._safe_import_hook('sys', None, ())
-            graph._safe_import_hook('nomod', None, ())
-            graph.report()
-            lines = fp.getvalue().splitlines()
-            fp.close()
-
-            self.assertEqual(lines[0], '')
-            self.assertEqual(lines[1], 'Class           Name                      File')
-            self.assertEqual(lines[2], '-----           ----                      ----')
-            expected = []
-            for n in graph.flatten():
-                if n.filename:
-                    expected.append([type(n).__name__, n.identifier, n.filename])
-                else:
-                    expected.append([type(n).__name__, n.identifier])
-
-            expected.sort()
-            actual = [item.split() for item in lines[3:]]
-            actual.sort()
-            self.assertEqual(expected, actual)
-
-
-        finally:
-            sys.stdout = saved_stdout
-
-    def test_graphreport(self):
-
-        def my_iter(flatpackages="packages"):
-            yield "line1\n"
-            yield str(flatpackages) + "\n"
-            yield "line2\n"
-
-        graph = modulegraph.ModuleGraph()
-        graph.itergraphreport = my_iter
-
-        fp = StringIO()
-        graph.graphreport(fp)
-        self.assertEqual(fp.getvalue(), "line1\n()\nline2\n")
-
-        fp = StringIO()
-        graph.graphreport(fp, "deps")
-        self.assertEqual(fp.getvalue(), "line1\ndeps\nline2\n")
-
-        saved_stdout = sys.stdout
-        try:
-            sys.stdout = fp = StringIO()
-            graph.graphreport()
-            self.assertEqual(fp.getvalue(), "line1\n()\nline2\n")
-
-        finally:
-            sys.stdout = saved_stdout
-
-
-    def test_replace_paths_in_code(self):
-        graph = modulegraph.ModuleGraph(replace_paths=[
-                ('path1', 'path2'),
-                ('path3/path5', 'path4'),
-            ])
-
-        co = compile(textwrap.dedent("""
-        [x for x in range(4)]
-        """), "path4/index.py", 'exec', 0, 1)
-        co = graph._replace_paths_in_code(co)
-        self.assertEqual(co.co_filename, 'path4/index.py')
-
-        co = compile(textwrap.dedent("""
-        [x for x in range(4)]
-        (x for x in range(4))
-        """), "path1/index.py", 'exec', 0, 1)
-        self.assertEqual(co.co_filename, 'path1/index.py')
-        co = graph._replace_paths_in_code(co)
-        self.assertEqual(co.co_filename, 'path2/index.py')
-        for c in co.co_consts:
-            if isinstance(c, type(co)):
-                self.assertEqual(c.co_filename, 'path2/index.py')
-
-        co = compile(textwrap.dedent("""
-        [x for x in range(4)]
-        """), "path3/path4/index.py", 'exec', 0, 1)
-        co = graph._replace_paths_in_code(co)
-        self.assertEqual(co.co_filename, 'path3/path4/index.py')
-
-        co = compile(textwrap.dedent("""
-        [x for x in range(4)]
-        """), "path3/path5.py", 'exec', 0, 1)
-        co = graph._replace_paths_in_code(co)
-        self.assertEqual(co.co_filename, 'path3/path5.py')
-
-        co = compile(textwrap.dedent("""
-        [x for x in range(4)]
-        """), "path3/path5/index.py", 'exec', 0, 1)
-        co = graph._replace_paths_in_code(co)
-        self.assertEqual(co.co_filename, 'path4/index.py')
-
-    def test_createReference(self):
-        graph = modulegraph.ModuleGraph()
-        n1 = modulegraph.Node('n1')
-        n2 = modulegraph.Node('n2')
-        graph.addNode(n1)
-        graph.addNode(n2)
-
-        graph.createReference(n1, n2)
-        outs, ins = map(list, graph.get_edges(n1))
-        self.assertEqual(outs, [n2])
-        self.assertEqual(ins, [])
-        outs, ins = map(list, graph.get_edges(n2))
-        self.assertEqual(outs, [])
-        self.assertEqual(ins, [n1])
-
-        e = graph.graph.edge_by_node('n1', 'n2')
-        self.assertIsInstance(e, int)
-        self.assertEqual(graph.graph.edge_data(e), 'direct')
-
-    def test_create_xref(self):
-        # XXX: This test is far from optimal, it just ensures
-        # that all code is exercised to catch small bugs and
-        # py3k issues without verifying that the code actually
-        # works....
-        graph = modulegraph.ModuleGraph()
-        if __file__.endswith('.py'):
-            graph.run_script(__file__)
-        else:
-            graph.run_script(__file__[:-1])
-
-        graph.import_hook('os')
-        graph.import_hook('xml.etree')
-        graph.import_hook('unittest')
-
-        fp = StringIO()
-        graph.create_xref(out=fp)
-
-        data = fp.getvalue()
-        r = ET.fromstring(data)
-
-    def test_itergraphreport(self):
-        # XXX: This test is far from optimal, it just ensures
-        # that all code is exercised to catch small bugs and
-        # py3k issues without verifying that the code actually
-        # works....
-        graph = modulegraph.ModuleGraph()
-        if __file__.endswith('.py'):
-            graph.run_script(__file__)
-        else:
-            graph.run_script(__file__[:-1])
-        graph.import_hook('os')
-        graph.import_hook('xml.etree')
-        graph.import_hook('unittest')
-        graph.import_hook('distutils.command.build')
-
-        fp = StringIO()
-        list(graph.itergraphreport())
-
-        # XXX: platpackages isn't implemented, and is undocumented hence
-        # it is unclear what this is inteded to be...
-        #list(graph.itergraphreport(flatpackages=...))
-
-
-
-
-class CompatTests (unittest.TestCase):
-    def test_Bchr(self):
-        v = modulegraph._Bchr(ord('A'))
-        if sys.version_info[0] == 2:
-            self.assertTrue(isinstance(v, bytes))
-            self.assertEqual(v, b'A')
-        else:
-            self.assertTrue(isinstance(v, int))
-            self.assertEqual(v, ord('A'))
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_pep420_nspkg.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_pep420_nspkg.py
deleted file mode 100644
index a20c981..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_pep420_nspkg.py
+++ /dev/null
@@ -1,220 +0,0 @@
-"""
-Tests that deal with pep420 namespace packages.
-
-PEP 420 is new in Python 3.3
-"""
-import os
-import shutil
-import sys
-import subprocess
-import textwrap
-
-if sys.version_info[:2] <= (2,6):
-    import unittest2 as unittest
-else:
-    import unittest
-
-from modulegraph import modulegraph
-
-gRootDir = os.path.dirname(os.path.abspath(__file__))
-gSrcDir = os.path.join(gRootDir, 'testpkg-pep420-namespace')
-
-if sys.version_info[:2] >= (3,3):
-
-    class TestPythonBehaviour (unittest.TestCase):
-        def importModule(self, name):
-            test_dir1 = os.path.join(gSrcDir, 'path1')
-            test_dir2 = os.path.join(gSrcDir, 'path2')
-            if '.' in name:
-                script = textwrap.dedent("""\
-                    import site
-                    site.addsitedir(%r)
-                    site.addsitedir(%r)
-                    try:
-                        import %s
-                    except ImportError:
-                        import %s
-                    print (%s.__name__)
-                """) %(test_dir1, test_dir2, name, name.rsplit('.', 1)[0], name)
-            else:
-                script = textwrap.dedent("""\
-                    import site
-                    site.addsitedir(%r)
-                    site.addsitedir(%r)
-                    import %s
-                    print (%s.__name__)
-                """) %(test_dir1, test_dir2, name, name)
-
-            p = subprocess.Popen([sys.executable, '-c', script],
-                    stdout=subprocess.PIPE,
-                    stderr=subprocess.STDOUT,
-                    cwd=os.path.join(
-                        os.path.dirname(os.path.abspath(__file__)),
-                        'testpkg-relimport'),
-            )
-            data = p.communicate()[0]
-            if sys.version_info[0] != 2:
-                data = data.decode('UTF-8')
-            data = data.strip()
-            if data.endswith(' refs]'):
-                data = data.rsplit('\n', 1)[0].strip()
-
-            sts = p.wait()
-
-            if sts != 0:
-                print (data)
-                self.fail("import of %r failed"%(name,))
-
-            return data
-
-        def testToplevel(self):
-            m = self.importModule('package.sub1')
-            self.assertEqual(m, 'package.sub1')
-
-            m = self.importModule('package.sub2')
-            self.assertEqual(m, 'package.sub2')
-
-        def testSub(self):
-            m = self.importModule('package.subpackage.sub')
-            self.assertEqual(m, 'package.subpackage.sub')
-
-            m = self.importModule('package.nspkg.mod')
-            self.assertEqual(m, 'package.nspkg.mod')
-
-    class TestModuleGraphImport (unittest.TestCase):
-        if not hasattr(unittest.TestCase, 'assertIsInstance'):
-            def assertIsInstance(self, value, types):
-                if not isinstance(value, types):
-                    self.fail("%r is not an instance of %r", value, types)
-
-        def setUp(self):
-            self.mf = modulegraph.ModuleGraph(path=[
-                    os.path.join(gSrcDir, 'path1'),
-                    os.path.join(gSrcDir, 'path2'),
-                ] + sys.path)
-
-
-        def testRootPkg(self):
-            self.mf.import_hook('package')
-
-            node = self.mf.findNode('package')
-            self.assertIsInstance(node, modulegraph.NamespacePackage)
-            self.assertEqual(node.identifier, 'package')
-            self.assertEqual(node.filename, '-')
-
-        def testRootPkgModule(self):
-            self.mf.import_hook('package.sub1')
-
-            node = self.mf.findNode('package.sub1')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-            self.assertEqual(node.identifier, 'package.sub1')
-
-            self.mf.import_hook('package.sub2')
-            node = self.mf.findNode('package.sub2')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-            self.assertEqual(node.identifier, 'package.sub2')
-
-        def testSubRootPkgModule(self):
-            self.mf.import_hook('package.subpackage.sub')
-
-            node = self.mf.findNode('package.subpackage.sub')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-            self.assertEqual(node.identifier, 'package.subpackage.sub')
-
-            node = self.mf.findNode('package')
-            self.assertIsInstance(node, modulegraph.NamespacePackage)
-
-            self.mf.import_hook('package.nspkg.mod')
-            node = self.mf.findNode('package.nspkg.mod')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-            self.assertEqual(node.identifier, 'package.nspkg.mod')
-
-else:
-    # Check that PEP 420 is not implemented in python 3.2 and earlier
-    # (and that modulegraph also doesn't do this)
-
-    class TestPythonBehaviour (unittest.TestCase):
-        def importModule(self, name):
-            test_dir1 = os.path.join(gSrcDir, 'path1')
-            test_dir2 = os.path.join(gSrcDir, 'path2')
-            if '.' in name:
-                script = textwrap.dedent("""\
-                    import site
-                    site.addsitedir(%r)
-                    site.addsitedir(%r)
-                    try:
-                        import %s
-                    except ImportError:
-                        import %s
-                    print (%s.__name__)
-                """) %(test_dir1, test_dir2, name, name.rsplit('.', 1)[0], name)
-            else:
-                script = textwrap.dedent("""\
-                    import site
-                    site.addsitedir(%r)
-                    site.addsitedir(%r)
-                    import %s
-                    print (%s.__name__)
-                """) %(test_dir1, test_dir2, name, name)
-
-            p = subprocess.Popen([sys.executable, '-c', script],
-                    stdout=subprocess.PIPE,
-                    stderr=subprocess.STDOUT,
-                    cwd=os.path.join(
-                        os.path.dirname(os.path.abspath(__file__)),
-                        'testpkg-relimport'),
-            )
-            data = p.communicate()[0]
-            if sys.version_info[0] != 2:
-                data = data.decode('UTF-8')
-            data = data.strip()
-            if data.endswith(' refs]'):
-                data = data.rsplit('\n', 1)[0].strip()
-
-            sts = p.wait()
-
-            if sts != 0:
-                raise ImportError(name)
-
-            return data
-
-        def testToplevel(self):
-            m = self.importModule('sys')
-            self.assertEqual(m, 'sys')
-
-            self.assertRaises(ImportError, self.importModule, 'package.sub1')
-            self.assertRaises(ImportError, self.importModule, 'package.sub2')
-
-        def testSub(self):
-            self.assertRaises(ImportError, self.importModule, 'package.subpackage.sub')
-
-    class TestModuleGraphImport (unittest.TestCase):
-        if not hasattr(unittest.TestCase, 'assertIsInstance'):
-            def assertIsInstance(self, value, types):
-                if not isinstance(value, types):
-                    self.fail("%r is not an instance of %r", value, types)
-
-        def setUp(self):
-            self.mf = modulegraph.ModuleGraph(path=[
-                    os.path.join(gSrcDir, 'path1'),
-                    os.path.join(gSrcDir, 'path2'),
-                ] + sys.path)
-
-
-        def testRootPkg(self):
-            self.assertRaises(ImportError, self.mf.import_hook, 'package')
-
-            node = self.mf.findNode('package')
-            self.assertIs(node, None)
-
-        def testRootPkgModule(self):
-            self.assertRaises(ImportError, self.mf.import_hook, 'package.sub1')
-
-            node = self.mf.findNode('package.sub1')
-            self.assertIs(node, None)
-
-            node = self.mf.findNode('package.sub2')
-            self.assertIs(node, None)
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_pycompat_pkg.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_pycompat_pkg.py
deleted file mode 100644
index b5dcdb7..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_pycompat_pkg.py
+++ /dev/null
@@ -1,60 +0,0 @@
-"""
-Test for import machinery
-"""
-import unittest
-import sys
-import textwrap
-import subprocess
-import os
-from modulegraph import modulegraph
-
-class TestModuleGraphImport (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def test_compat(self):
-        root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-compatmodule')
-        mf = modulegraph.ModuleGraph(path=[ root ] + sys.path)
-        mf.import_hook('pkg.api')
-
-        node = mf.findNode('pkg')
-        self.assertIsInstance(node, modulegraph.Package)
-
-        node = mf.findNode('pkg.api')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-
-        if sys.version_info[0] == 2:
-            node = mf.findNode('pkg.api2')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-
-            node = mf.findNode('pkg.api3')
-            self.assertIsInstance(node, modulegraph.InvalidSourceModule)
-
-            node = mf.findNode('http.client')
-            self.assertIs(node, None)
-
-            node = mf.findNode('urllib2')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-
-        else:
-            node = mf.findNode('pkg.api2')
-            self.assertIsInstance(node, modulegraph.InvalidSourceModule)
-
-            node = mf.findNode('pkg.api3')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-
-            node = mf.findNode('http.client')
-            self.assertIsInstance(node, modulegraph.SourceModule)
-
-            node = mf.findNode('urllib2')
-            self.assertIs(node, None)
-
-
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_relimport2.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_relimport2.py
deleted file mode 100644
index 0a465a2..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_relimport2.py
+++ /dev/null
@@ -1,45 +0,0 @@
-"""
-Test for import machinery
-"""
-import unittest
-import sys
-import textwrap
-import subprocess
-import os
-from modulegraph import modulegraph
-
-class TestModuleGraphImport (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r"%(value, types))
-
-    def setUp(self):
-        self.root = os.path.join(
-                os.path.dirname(os.path.abspath(__file__)),
-                'testpkg-relimport2')
-        self.mf = modulegraph.ModuleGraph(path=[ self.root ] + sys.path)
-
-
-    def test_init_as_script(self):
-        self.mf.run_script(os.path.join(self.root, 'pkg/__init__.py'))
-        n = self.mf.findNode('mod1')
-        self.assertIs(n, None)
-
-        n = self.mf.findNode('mod2')
-        self.assertIsInstance(n, modulegraph.MissingModule)
-
-    def test_subpkg_bad_import(self):
-        self.mf.import_hook('pkg.sub')
-
-        n = self.mf.findNode('toplevel')
-        self.assertIs(n, None)
-
-        n = self.mf.findNode('pkg.mod1')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-
-        n = self.mf.findNode('pkg.mod3')
-        self.assertIsInstance(n, modulegraph.SourceModule)
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_setuptools_nspkg.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_setuptools_nspkg.py
deleted file mode 100644
index 87f845c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_setuptools_nspkg.py
+++ /dev/null
@@ -1,147 +0,0 @@
-"""
-Tests that deal with setuptools namespace
-packages, and in particular the installation
-flavour used by pip
-"""
-import os
-import shutil
-import sys
-import subprocess
-import unittest
-import textwrap
-
-from modulegraph import modulegraph
-
-gRootDir = os.path.dirname(os.path.abspath(__file__))
-gSrcDir = os.path.join(gRootDir, 'testpkg-setuptools-namespace')
-
-def install_testpkg(test_dir):
-    p = subprocess.Popen([
-        sys.executable, 'setup.py', 'install',
-            '--install-lib', test_dir,
-            '--single-version-externally-managed',
-            '--record', os.path.join(test_dir, 'record.lst'),
-        ], cwd=gSrcDir, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-    data = p.communicate()[0]
-
-    exit = p.wait()
-    return exit
-
-
-class TestPythonBehaviour (unittest.TestCase):
-    def setUp(self):
-        test_dir = os.path.join(gRootDir, 'test.dir')
-        if os.path.exists(test_dir):
-            shutil.rmtree(test_dir)
-
-        os.mkdir(test_dir)
-        exit = install_testpkg(test_dir)
-        self.assertEqual(exit, 0)
-
-    def tearDown(self):
-        test_dir = os.path.join(gRootDir, 'test.dir')
-        if os.path.exists(test_dir):
-            shutil.rmtree(test_dir)
-
-    def importModule(self, name):
-        test_dir = os.path.join(gRootDir, 'test.dir')
-        if '.' in name:
-            script = textwrap.dedent("""\
-                import site
-                site.addsitedir(%r)
-                try:
-                    import %s
-                except ImportError:
-                    import %s
-                print (%s.__name__)
-            """) %(test_dir, name, name.rsplit('.', 1)[0], name)
-        else:
-            script = textwrap.dedent("""\
-                import site
-                site.addsitedir(%r)
-                import %s
-                print (%s.__name__)
-            """) %(test_dir, name, name)
-
-        p = subprocess.Popen([sys.executable, '-c', script],
-                stdout=subprocess.PIPE,
-                stderr=subprocess.STDOUT,
-                cwd=os.path.join(
-                    os.path.dirname(os.path.abspath(__file__)),
-                    'testpkg-relimport'),
-        )
-        data = p.communicate()[0]
-        if sys.version_info[0] != 2:
-            data = data.decode('UTF-8')
-        data = data.strip()
-        if data.endswith(' refs]'):
-            data = data.rsplit('\n', 1)[0].strip()
-
-        sts = p.wait()
-
-        if sts != 0:
-            print (data)
-            self.fail("import of %r failed"%(name,))
-
-        return data
-
-    def testToplevel(self):
-        m = self.importModule('nspkg.module')
-        self.assertEqual(m, 'nspkg.module')
-
-    def testSub(self):
-        m = self.importModule('nspkg.nssubpkg.sub')
-        self.assertEqual(m, 'nspkg.nssubpkg.sub')
-
-class TestModuleGraphImport (unittest.TestCase):
-    if not hasattr(unittest.TestCase, 'assertIsInstance'):
-        def assertIsInstance(self, value, types):
-            if not isinstance(value, types):
-                self.fail("%r is not an instance of %r", value, types)
-
-    def setUp(self):
-        test_dir = os.path.join(gRootDir, 'test.dir')
-        if os.path.exists(test_dir):
-            shutil.rmtree(test_dir)
-
-        os.mkdir(test_dir)
-        exit = install_testpkg(test_dir)
-        self.assertEqual(exit, 0)
-
-        self.mf = modulegraph.ModuleGraph(path=[ test_dir ] + sys.path)
-
-    def tearDown(self):
-        test_dir = os.path.join(gRootDir, 'test.dir')
-        if os.path.exists(test_dir):
-            shutil.rmtree(test_dir)
-
-    def testRootPkg(self):
-        self.mf.import_hook('nspkg')
-
-        node = self.mf.findNode('nspkg')
-        self.assertIsInstance(node, modulegraph.NamespacePackage)
-        self.assertEqual(node.identifier, 'nspkg')
-        self.assertEqual(node.filename, '-')
-
-    def testRootPkgModule(self):
-        self.mf.import_hook('nspkg.module')
-
-        node = self.mf.findNode('nspkg.module')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'nspkg.module')
-
-    def testSubRootPkgModule(self):
-        self.mf.import_hook('nspkg.nssubpkg.sub')
-
-        node = self.mf.findNode('nspkg.nssubpkg.sub')
-        self.assertIsInstance(node, modulegraph.SourceModule)
-        self.assertEqual(node.identifier, 'nspkg.nssubpkg.sub')
-
-
-        node = self.mf.findNode('nspkg')
-        self.assertIsInstance(node, modulegraph.NamespacePackage)
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_util.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_util.py
deleted file mode 100644
index eafe43e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_util.py
+++ /dev/null
@@ -1,59 +0,0 @@
-import unittest
-import encodings
-import encodings.aliases
-from modulegraph import util
-import sys
-
-try:
-    from io import BytesIO
-except ImportError:
-    from cStringIO import StringIO as BytesIO
-
-class TestUtil (unittest.TestCase):
-    def test_imp_find_module(self):
-        fn = util.imp_find_module('encodings.aliases')[1]
-        self.assertTrue(encodings.aliases.__file__.startswith(fn))
-
-    def test_imp_walk(self):
-        imps = list(util.imp_walk('encodings.aliases'))
-        self.assertEqual(len(imps), 2)
-
-        self.assertEqual(imps[0][0], 'encodings')
-        self.assertTrue(encodings.__file__.startswith(imps[0][1][1]))
-
-        self.assertEqual(imps[1][0], 'aliases')
-        self.assertTrue(encodings.aliases.__file__.startswith(imps[1][1][1]))
-
-        # Close all files, avoid warning by unittest
-        for i in imps:
-            if i[1][0] is not None:
-                i[1][0].close()
-
-
-    def test_guess_encoding(self):
-        fp = BytesIO(b"# coding: utf-8")
-        self.assertEqual(util.guess_encoding(fp), "utf-8")
-
-        fp = BytesIO(b"\n# coding: utf-8")
-        self.assertEqual(util.guess_encoding(fp), "utf-8")
-
-        fp = BytesIO(b"# coding: latin-1")
-        self.assertEqual(util.guess_encoding(fp), "latin-1")
-
-        fp = BytesIO(b"\n# coding: latin-1")
-        self.assertEqual(util.guess_encoding(fp), "latin-1")
-
-        fp = BytesIO(b"#!/usr/bin/env/python\n# vim: set fileencoding=latin-1 :")
-        self.assertEqual(util.guess_encoding(fp), "latin-1")
-
-        fp = BytesIO(b"\n\n\n# coding: latin-1")
-        if sys.version_info[0] == 2:
-            self.assertEqual(util.guess_encoding(fp), "ascii")
-        else:
-            self.assertEqual(util.guess_encoding(fp), "utf-8")
-
-        del fp
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_zipio.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_zipio.py
deleted file mode 100644
index 81000bd..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/test_zipio.py
+++ /dev/null
@@ -1,218 +0,0 @@
-from modulegraph import zipio
-import os
-import time
-import sys
-
-if sys.version_info[:2] <= (2,6):
-    import unittest2 as unittest
-
-else:
-    import unittest
-
-TESTDATA=os.path.join(
-        os.path.dirname(os.path.abspath(__file__)),
-        'testdata')
-
-class TestModuleGraph (unittest.TestCase):
-    def test_locating(self):
-        # Private function
-        self.assertEqual(zipio._locate('/usr/bin/ditto'), ('/usr/bin/ditto', None))
-        self.assertEqual(zipio._locate('/usr/bin/ditto/bar'), ('/usr/bin/ditto', 'bar'))
-        self.assertEqual(zipio._locate('/usr/bin/ditto/foo/bar///bar/'), ('/usr/bin/ditto', 'foo/bar/bar'))
-        self.assertEqual(zipio._locate('/usr/bin/ditto///foo/bar///bar/'), ('/usr/bin/ditto', 'foo/bar/bar'))
-        self.assertRaises(IOError, zipio._locate, '/usr/bin/ditto.bar')
-        self.assertRaises(IOError, zipio._locate, '/foo/bar/baz.txt')
-
-    def test_open(self):
-        # 1. Regular file
-        fp = zipio.open(os.path.join(TESTDATA, 'test.txt'), 'r')
-        data = fp.read()
-        fp.close()
-        self.assertEqual(data, 'This is test.txt\n')
-
-        if sys.version_info[0] == 3:
-            fp = zipio.open(os.path.join(TESTDATA, 'test.txt'), 'rb')
-            data = fp.read()
-            fp.close()
-            self.assertEqual(data, b'This is test.txt\n')
-
-        # 2. File inside zipfile
-        fp = zipio.open(os.path.join(TESTDATA, 'zipped.egg', 'test.txt'), 'r')
-        data = fp.read()
-        fp.close()
-        self.assertEqual(data, 'Zipped up test.txt\n')
-
-        if sys.version_info[0] == 3:
-            fp = zipio.open(os.path.join(TESTDATA, 'zipped.egg', 'test.txt'), 'rb')
-            data = fp.read()
-            fp.close()
-            self.assertEqual(data, b'Zipped up test.txt\n')
-
-        # 3. EXC: Directory inside zipfile
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'subdir'))
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'subdir2'))
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'subdir2/subdir'))
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'subdir3'))
-        # TODO: Add subdir4/file.txt, without directory entry
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'subdir4'))
-
-        # 4. EXC: No such file in zipfile
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'no-such-file'))
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'zipped.egg', 'subdir/no-such-file'))
-
-        # 5. EXC: No such regular file
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'no-such-file.txt'))
-
-        # 6. EXC: Open r/w
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'test.txt'), 'w')
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'test.txt'), 'a')
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'test.txt'), 'r+')
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'test.txt'), 'w+')
-        self.assertRaises(IOError, zipio.open, os.path.join(TESTDATA, 'test.txt'), 'a+')
-
-    def test_listdir(self):
-        # 1. Regular directory
-        self.assertEqual(set(os.listdir(os.path.join(TESTDATA, 'subdir'))), set(['file1.txt', 'file2.txt']))
-
-        # 2. Zipfile with files in directory
-        self.assertEqual(set(zipio.listdir(os.path.join(TESTDATA, 'zipped.egg'))), set([
-            'test.txt', 'subdir', 'subdir2', 'subdir3', 'subdir4']))
-
-        # 3. Zipfile with files in subdirectory
-        self.assertEqual(set(zipio.listdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir'))), set(['file1.txt', 'file2.txt']))
-        self.assertEqual(set(zipio.listdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir2'))), set(['subdir']))
-        self.assertEqual(set(zipio.listdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir4', 'subdir6'))), set(['mydir']))
-
-        # 4. Zipfile with entry for directory, no files
-        self.assertEqual(set(zipio.listdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir3'))), set([]))
-
-        # 5. EXC: Zipfile without directory
-        self.assertRaises(IOError, zipio.listdir, os.path.join(TESTDATA, 'zipped.egg', 'subdir10'))
-
-        # 6. EXC: Regular directory doesn't exist
-        self.assertRaises(IOError, zipio.listdir, os.path.join(TESTDATA, 'subdir10'))
-
-    def test_isfile(self):
-        self.assertTrue(zipio.isfile(os.path.join(TESTDATA, 'test.txt')))
-        self.assertFalse(zipio.isfile(os.path.join(TESTDATA, 'subdir')))
-        self.assertRaises(IOError, zipio.isfile, os.path.join(TESTDATA, 'no-such-file'))
-        self.assertFalse(zipio.isfile(os.path.join(TESTDATA, 'zipped.egg')))
-        self.assertFalse(zipio.isfile(os.path.join(TESTDATA, 'zipped.egg', 'subdir4')))
-        self.assertTrue(zipio.isfile(os.path.join(TESTDATA, 'zipped.egg', 'test.txt')))
-        self.assertFalse(zipio.isfile(os.path.join(TESTDATA, 'zipped.egg', 'subdir')))
-        self.assertRaises(IOError, zipio.isfile, os.path.join(TESTDATA, 'zipped.egg', 'no-such-file'))
-        self.assertTrue(zipio.isfile(os.path.join(TESTDATA, 'zipped.egg', 'subdir2', 'subdir', 'file1.txt')))
-
-    def test_isdir(self):
-        self.assertTrue(zipio.isdir(TESTDATA))
-        self.assertFalse(zipio.isdir(os.path.join(TESTDATA, 'test.txt')))
-        self.assertTrue(zipio.isdir(os.path.join(TESTDATA, 'zipped.egg')))
-        self.assertTrue(zipio.isdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir')))
-        self.assertTrue(zipio.isdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir2/subdir')))
-        self.assertTrue(zipio.isdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir4')))
-        self.assertFalse(zipio.isdir(os.path.join(TESTDATA, 'zipped.egg', 'subdir4', 'file.txt')))
-        self.assertRaises(IOError, zipio.isdir, os.path.join(TESTDATA, 'no-such-file'))
-        self.assertRaises(IOError, zipio.isdir, os.path.join(TESTDATA, 'zipped.egg', 'no-such-file'))
-        self.assertRaises(IOError, zipio.isdir, os.path.join(TESTDATA, 'zipped.egg', 'subdir', 'no-such-file'))
-
-    def test_islink(self):
-        fn = os.path.join(TESTDATA, 'symlink')
-        os.symlink('test.txt', fn)
-        try:
-            self.assertTrue(zipio.islink(fn))
-
-        finally:
-            os.unlink(fn)
-
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'test.txt')))
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'subdir')))
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'zipped.egg')))
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'zipped.egg/subdir')))
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'zipped.egg/subdir4')))
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'zipped.egg/test.txt')))
-        self.assertFalse(zipio.islink(os.path.join(TESTDATA, 'zipped.egg/subdir/file1.txt')))
-
-        self.assertRaises(IOError, zipio.islink, os.path.join(TESTDATA, 'no-such-file'))
-        self.assertRaises(IOError, zipio.islink, os.path.join(TESTDATA, 'zipped.egg', 'no-such-file'))
-
-
-    def test_readlink(self):
-        fn = os.path.join(TESTDATA, 'symlink')
-        os.symlink('test.txt', fn)
-        try:
-            self.assertEqual(zipio.readlink(fn), 'test.txt')
-
-        finally:
-            os.unlink(fn)
-
-        self.assertRaises(OSError, zipio.readlink, os.path.join(TESTDATA, 'test.txt'))
-        self.assertRaises(OSError, zipio.readlink, os.path.join(TESTDATA, 'subdir'))
-        self.assertRaises(OSError, zipio.readlink, os.path.join(TESTDATA, 'zipped.egg'))
-        self.assertRaises(OSError, zipio.readlink, os.path.join(TESTDATA, 'zipped.egg', 'subdir4'))
-        self.assertRaises(OSError, zipio.readlink, os.path.join(TESTDATA, 'zipped.egg', 'no-such-file'))
-        self.assertRaises(OSError, zipio.readlink, os.path.join(TESTDATA, 'zipped.egg', 'subdir/no-such-file'))
-
-    def test_getmtime(self):
-        fn = os.path.join(TESTDATA, 'test.txt')
-        self.assertEqual(os.path.getmtime(fn), zipio.getmtime(fn))
-
-        fn = os.path.join(TESTDATA, 'zipped.egg')
-        self.assertEqual(os.path.getmtime(fn), zipio.getmtime(fn))
-
-        fn = os.path.join(TESTDATA, 'zipped.egg/test.txt')
-        self.assertIn(zipio.getmtime(fn), (1300193680.0, 1300222480.0))
-
-        fn = os.path.join(TESTDATA, 'zipped.egg/subdir')
-        self.assertIn(zipio.getmtime(fn), (1300193890.0, 1300222690.0))
-
-        fn = os.path.join(TESTDATA, 'zipped.egg/subdir4')
-        self.assertEqual(zipio.getmtime(fn), os.path.getmtime(os.path.join(TESTDATA, 'zipped.egg')))
-
-        self.assertRaises(IOError, zipio.getmtime, os.path.join(TESTDATA, 'no-file'))
-        self.assertRaises(IOError, zipio.getmtime, os.path.join(TESTDATA, 'zipped.egg/no-file'))
-
-    def test_contextlib(self):
-        # 1. Regular file
-        with zipio.open(os.path.join(TESTDATA, 'test.txt'), 'r') as fp:
-            data = fp.read()
-        try:
-            fp.read()
-            self.fail("file not closed")
-        except (ValueError, IOError):
-            pass
-
-        self.assertEqual(data, 'This is test.txt\n')
-
-        if sys.version_info[0] == 3:
-            with zipio.open(os.path.join(TESTDATA, 'test.txt'), 'rb') as fp:
-                data = fp.read()
-            try:
-                fp.read()
-                self.fail("file not closed")
-            except (ValueError, IOError):
-                pass
-
-            self.assertEqual(data, b'This is test.txt\n')
-
-        # 2. File inside zipfile
-        with zipio.open(os.path.join(TESTDATA, 'zipped.egg', 'test.txt'), 'r') as fp:
-            data = fp.read()
-        try:
-            fp.read()
-            self.fail("file not closed")
-        except (ValueError, IOError):
-            pass
-        self.assertEqual(data, 'Zipped up test.txt\n')
-
-        if sys.version_info[0] == 3:
-            with zipio.open(os.path.join(TESTDATA, 'zipped.egg', 'test.txt'), 'rb') as fp:
-                data = fp.read()
-            try:
-                fp.read()
-                self.fail("file not closed")
-            except (IOError, ValueError):
-                pass
-            self.assertEqual(data, b'Zipped up test.txt\n')
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/namedpkg/slave.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/namedpkg/slave.py
deleted file mode 100644
index 16a3d3c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/namedpkg/slave.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" slave packages """
-import os
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6-nspkg.pth b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6-nspkg.pth
deleted file mode 100644
index b020a3c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6-nspkg.pth
+++ /dev/null
@@ -1 +0,0 @@
-import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('namedpkg',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('namedpkg',types.ModuleType('namedpkg')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/PKG-INFO
deleted file mode 100644
index cff065a..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: nameduser
-Version: 1.5
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/SOURCES.txt
deleted file mode 100644
index 15c6126..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/slave.py
-nameduser.egg-info/PKG-INFO
-nameduser.egg-info/SOURCES.txt
-nameduser.egg-info/dependency_links.txt
-nameduser.egg-info/namespace_packages.txt
-nameduser.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6-nspkg.pth b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6-nspkg.pth
deleted file mode 100644
index b020a3c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6-nspkg.pth
+++ /dev/null
@@ -1 +0,0 @@
-import sys,types,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('namedpkg',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('namedpkg',types.ModuleType('namedpkg')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/PKG-INFO
deleted file mode 100644
index 138c5fd..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: namedpkg
-Version: 1.0
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/SOURCES.txt
deleted file mode 100644
index 29dfc47..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/parent.py
-namedpkg.egg-info/PKG-INFO
-namedpkg.egg-info/SOURCES.txt
-namedpkg.egg-info/dependency_links.txt
-namedpkg.egg-info/namespace_packages.txt
-namedpkg.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg/parent.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg/parent.py
deleted file mode 100644
index db7354b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg/parent.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" parent packages """
-import sys
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/namedpkg/slave.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/namedpkg/slave.py
deleted file mode 100644
index 16a3d3c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/namedpkg/slave.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" slave packages """
-import os
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5-nspkg.pth b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5-nspkg.pth
deleted file mode 100644
index 9423238..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5-nspkg.pth
+++ /dev/null
@@ -1 +0,0 @@
-import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('namedpkg',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('namedpkg',new.module('namedpkg')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/PKG-INFO
deleted file mode 100644
index cff065a..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: nameduser
-Version: 1.5
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt
deleted file mode 100644
index 15c6126..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/slave.py
-nameduser.egg-info/PKG-INFO
-nameduser.egg-info/SOURCES.txt
-nameduser.egg-info/dependency_links.txt
-nameduser.egg-info/namespace_packages.txt
-nameduser.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5-nspkg.pth b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5-nspkg.pth
deleted file mode 100644
index 9423238..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5-nspkg.pth
+++ /dev/null
@@ -1 +0,0 @@
-import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('namedpkg',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('namedpkg',new.module('namedpkg')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO
deleted file mode 100644
index 138c5fd..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: namedpkg
-Version: 1.0
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt
deleted file mode 100644
index 29dfc47..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/parent.py
-namedpkg.egg-info/PKG-INFO
-namedpkg.egg-info/SOURCES.txt
-namedpkg.egg-info/dependency_links.txt
-namedpkg.egg-info/namespace_packages.txt
-namedpkg.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg/parent.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg/parent.py
deleted file mode 100644
index db7354b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg/parent.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" parent packages """
-import sys
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/namedpkg/slave.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/namedpkg/slave.py
deleted file mode 100644
index 16a3d3c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/namedpkg/slave.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" slave packages """
-import os
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5-nspkg.pth b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5-nspkg.pth
deleted file mode 100644
index 9423238..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5-nspkg.pth
+++ /dev/null
@@ -1 +0,0 @@
-import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('namedpkg',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('namedpkg',new.module('namedpkg')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/PKG-INFO
deleted file mode 100644
index cff065a..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: nameduser
-Version: 1.5
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt
deleted file mode 100644
index 15c6126..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/slave.py
-nameduser.egg-info/PKG-INFO
-nameduser.egg-info/SOURCES.txt
-nameduser.egg-info/dependency_links.txt
-nameduser.egg-info/namespace_packages.txt
-nameduser.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5-nspkg.pth b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5-nspkg.pth
deleted file mode 100644
index 9423238..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5-nspkg.pth
+++ /dev/null
@@ -1 +0,0 @@
-import sys,new,os; p = os.path.join(sys._getframe(1).f_locals['sitedir'], *('namedpkg',)); ie = os.path.exists(os.path.join(p,'__init__.py')); m = not ie and sys.modules.setdefault('namedpkg',new.module('namedpkg')); mp = (m or []) and m.__dict__.setdefault('__path__',[]); (p not in mp) and mp.append(p)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO
deleted file mode 100644
index 138c5fd..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: namedpkg
-Version: 1.0
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt
deleted file mode 100644
index 29dfc47..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/parent.py
-namedpkg.egg-info/PKG-INFO
-namedpkg.egg-info/SOURCES.txt
-namedpkg.egg-info/dependency_links.txt
-namedpkg.egg-info/namespace_packages.txt
-namedpkg.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg/parent.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg/parent.py
deleted file mode 100644
index db7354b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg/parent.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" parent packages """
-import sys
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/namedpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/namedpkg/__init__.py
deleted file mode 100644
index de40ea7..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/namedpkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__import__('pkg_resources').declare_namespace(__name__)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/namedpkg/slave.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/namedpkg/slave.py
deleted file mode 100644
index 16a3d3c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/namedpkg/slave.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" slave packages """
-import os
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/PKG-INFO
deleted file mode 100644
index cff065a..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: nameduser
-Version: 1.5
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/SOURCES.txt
deleted file mode 100644
index 15c6126..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/slave.py
-nameduser.egg-info/PKG-INFO
-nameduser.egg-info/SOURCES.txt
-nameduser.egg-info/dependency_links.txt
-nameduser.egg-info/namespace_packages.txt
-nameduser.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/setup.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/setup.py
deleted file mode 100644
index e1000c5..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/child/setup.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from setuptools import setup
-
-setup(
-        name="nameduser",
-        version="1.5",
-        packages=["namedpkg"],
-        namespace_packages=["namedpkg"],
-)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/install.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/install.py
deleted file mode 100644
index 3f14e73..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/install.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-"""
-Script that will create a subdirectory one level up with two subdirs
-with --single-version-externally-managed namespace packages.
-
-Use this script with new versions of distribute and setuptools to ensure
-that changes in the handling of this option don't break us.
-"""
-import pkg_resources
-import subprocess
-import os
-import sys
-import shutil
-
-def main():
-    r = pkg_resources.require('setuptools')[0]
-    install_dir = os.path.join(
-            os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
-            "%s-%s"%(r.project_name, r.version))
-    if os.path.exists(install_dir):
-        print("Skip %s %s: already installed"%(r.project_name, r.version))
-
-    else:
-        os.mkdir(install_dir)
-        os.mkdir(os.path.join(install_dir, "parent"))
-        os.mkdir(os.path.join(install_dir, "child"))
-
-        if os.path.exists('parent/build'):
-            shutil.rmtree('parent/build')
-        if os.path.exists('child/build'):
-            shutil.rmtree('child/build')
-
-        for subdir in ('parent', 'child'):
-            p = subprocess.Popen([
-                sys.executable,
-                "setup.py",
-                "install",
-                 "--install-lib=%s/%s"%(install_dir, subdir),
-                 "--single-version-externally-managed",
-                 "--record", "files.txt"
-            ],
-            cwd=subdir)
-            xit = p.wait()
-            if xit != 0:
-                print("ERROR: install failed")
-                sys.exit(1)
-
-
-            if os.path.exists('%s/files.txt'%(subdir,)):
-                os.unlink('%s/files.txt'%(subdir,))
-
-
-if __name__ == "__main__":
-    main()
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/PKG-INFO
deleted file mode 100644
index 138c5fd..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: namedpkg
-Version: 1.0
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/SOURCES.txt
deleted file mode 100644
index 29dfc47..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-setup.py
-namedpkg/__init__.py
-namedpkg/parent.py
-namedpkg.egg-info/PKG-INFO
-namedpkg.egg-info/SOURCES.txt
-namedpkg.egg-info/dependency_links.txt
-namedpkg.egg-info/namespace_packages.txt
-namedpkg.egg-info/top_level.txt
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/namespace_packages.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/top_level.txt
deleted file mode 100644
index d332ce1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-namedpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg/__init__.py
deleted file mode 100644
index de40ea7..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-__import__('pkg_resources').declare_namespace(__name__)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg/parent.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg/parent.py
deleted file mode 100644
index db7354b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/namedpkg/parent.py
+++ /dev/null
@@ -1,2 +0,0 @@
-""" parent packages """
-import sys
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/setup.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/setup.py
deleted file mode 100644
index 1a5be60..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/nspkg/src/parent/setup.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from setuptools import setup
-
-setup(
-        name="namedpkg",
-        version="1.0",
-        packages=["namedpkg"],
-        namespace_packages=["namedpkg"],
-)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/script b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/script
deleted file mode 100755
index 2716038..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/script
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/usr/bin/python
-import sys, os
-
-print (sys.version)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/subdir/file1.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/subdir/file1.txt
deleted file mode 100644
index 7898192..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/subdir/file1.txt
+++ /dev/null
@@ -1 +0,0 @@
-a
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/subdir/file2.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/subdir/file2.txt
deleted file mode 100644
index 6178079..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/subdir/file2.txt
+++ /dev/null
@@ -1 +0,0 @@
-b
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath.egg b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath.egg
deleted file mode 100644
index 64db323..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath.egg
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath.zip b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath.zip
deleted file mode 100644
index d3c1f42..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath.zip
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/myext.pyd b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/myext.pyd
deleted file mode 100644
index 01e7507..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/myext.pyd
+++ /dev/null
@@ -1 +0,0 @@
-""" fake extension """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mymodule.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mymodule.py
deleted file mode 100644
index de6c648..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mymodule.py
+++ /dev/null
@@ -1,3 +0,0 @@
-"""
-some module
-"""
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mymodule3.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mymodule3.py
deleted file mode 100644
index 422b686..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mymodule3.py
+++ /dev/null
@@ -1 +0,0 @@
-"""  fake module """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mypkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mypkg/__init__.py
deleted file mode 100644
index 25597fb..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/syspath/mypkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" fake package """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/test.egg b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/test.egg
deleted file mode 100644
index 219c116..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/test.egg
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/test.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/test.txt
deleted file mode 100644
index 3b86232..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/test.txt
+++ /dev/null
@@ -1 +0,0 @@
-This is test.txt
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/zipped.egg b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/zipped.egg
deleted file mode 100644
index bf8bd09..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testdata/zipped.egg
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/__init__.py
deleted file mode 100644
index 78b491e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api.py
deleted file mode 100644
index 53fe9ba..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api.py
+++ /dev/null
@@ -1,9 +0,0 @@
-""" pkg.api """
-
-import sys
-
-if sys.version_info[0] == 2:
-    from .api2 import *
-
-else:
-    from .api3 import *
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api2.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api2.py
deleted file mode 100644
index 4f5be0b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api2.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import urllib2
-
-def div(a, b):
-    try:
-        return a/b
-
-    except ZeroDivisionError, exc:
-        return None
-
-class MyClass (object):
-    pass
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api3.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api3.py
deleted file mode 100644
index dc4aefa..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-compatmodule/pkg/api3.py
+++ /dev/null
@@ -1,11 +0,0 @@
-import http.client
-
-def div(a, b):
-    try:
-        return a/b
-
-    except ZeroDivisionError as exc:
-        return None
-
-class MyClass (object, metaclass=type):
-    pass
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_class_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_class_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_class_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_conditional_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/function_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/__init__.py
deleted file mode 100644
index 82e4875..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.__init__ """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_class_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_class_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_class_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_conditional_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/function_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_class_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_class_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_class_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_conditional_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/pkg/toplevel_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script.py
deleted file mode 100644
index 901c332..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script.py
+++ /dev/null
@@ -1,51 +0,0 @@
-
-import toplevel_existing
-import toplevel_nonexisting
-
-class MyClass:
-    import toplevel_class_existing
-    import toplevel_class_nonexisting
-
-if a == b:
-    import toplevel_conditional_existing
-    import toplevel_conditional_nonexisting
-
-    try:
-        import toplevel_conditional_import_existing
-        import toplevel_conditional_import_nonexisting
-    except:
-        import toplevel_conditional_import2_existing
-        import toplevel_conditional_import2_nonexisting
-
-try:
-    import toplevel_import_existing
-    import toplevel_import_nonexisting
-except:
-    import toplevel_import2_existing
-    import toplevel_import2_nonexisting
-
-def function():
-    import function_existing
-    import function_nonexisting
-
-    class MyClass:
-        import function_class_existing
-        import function_class_nonexisting
-
-    if a == b:
-        import function_conditional_existing
-        import function_conditional_nonexisting
-
-        try:
-            import function_conditional_import_existing
-            import function_conditional_import_nonexisting
-        except:
-            import function_conditional_import2_existing
-            import function_conditional_import2_nonexisting
-
-    try:
-        import function_import_existing
-        import function_import_nonexisting
-    except:
-        import function_import2_existing
-        import function_import2_nonexisting
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script_from_import.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script_from_import.py
deleted file mode 100644
index 1dd6783..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script_from_import.py
+++ /dev/null
@@ -1,46 +0,0 @@
-from pkg import toplevel_existing
-from pkg import toplevel_nonexisting
-
-class MyClass:
-    from pkg import toplevel_class_existing
-    from pkg import toplevel_class_nonexisting
-
-if a == b:
-    from pkg import toplevel_conditional_existing
-    from pkg import toplevel_conditional_nonexisting
-
-    try:
-        from pkg import toplevel_conditional_import_existing, toplevel_conditional_import_nonexisting
-    except:
-        from pkg import toplevel_conditional_import2_existing
-        from pkg import toplevel_conditional_import2_nonexisting
-
-try:
-    from pkg import toplevel_import_existing, toplevel_import_nonexisting
-except:
-    from pkg import toplevel_import2_existing
-    from pkg import toplevel_import2_nonexisting
-
-def function():
-    from pkg import function_existing, function_nonexisting
-
-    class MyClass:
-        from pkg import function_class_existing, function_class_nonexisting
-
-    if a == b:
-        from pkg import function_conditional_existing
-        from pkg import function_conditional_nonexisting
-
-        try:
-            from pkg import function_conditional_import_existing
-            from pkg import function_conditional_import_nonexisting
-        except:
-            from pkg import function_conditional_import2_existing
-            from pkg import function_conditional_import2_nonexisting
-
-    try:
-        from pkg import function_import_existing
-        from pkg import function_import_nonexisting
-    except:
-        from pkg import function_import2_existing
-        from pkg import function_import2_nonexisting
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script_multi_import.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script_multi_import.py
deleted file mode 100644
index cb6ce54..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/script_multi_import.py
+++ /dev/null
@@ -1,26 +0,0 @@
-
-
-try:
-    import os.path
-except ImportError:
-    pass
-
-import os
-
-def function(self):
-    import sys
-
-
-if a == b:
-    import sys
-
-def function2(self):
-    if a == b:
-        import platform
-
-def function3(self):
-    import platform
-    import email
-
-
-import email
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_class_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_class_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_class_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_conditional_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_import2_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_import2_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_import2_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_import_existing.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_import_existing.py
deleted file mode 100644
index ef467ea..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-edgedata/toplevel_import_existing.py
+++ /dev/null
@@ -1 +0,0 @@
-""" $fname """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/__init__.py
deleted file mode 100644
index 78b491e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/__init__.py
deleted file mode 100644
index ecd411e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-""" pkg.subpkg """
-
-from compat import X, Y
-
-from _collections import A, B
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/_collections.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/_collections.py
deleted file mode 100644
index 4e9a588..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/_collections.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg.subpkg._collections """
-
-A, B = "A", "B"
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/compat.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/compat.py
deleted file mode 100644
index 92850f2..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg/subpkg/compat.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg.subpkg.compat """
-
-X, Y = 1, 2
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/__init__.py
deleted file mode 100644
index f6e15f3..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg2.__init__ """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/__init__.py
deleted file mode 100644
index 97fddf1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/__init__.py
+++ /dev/null
@@ -1,5 +0,0 @@
-""" pkg2.subpkg """
-
-from .compat import X, Y
-
-from ._collections import A, B
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/_collections.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/_collections.py
deleted file mode 100644
index 1b37f9d..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/_collections.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg2.subpkg._collections """
-
-A, B = "A", "B"
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/compat.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/compat.py
deleted file mode 100644
index d544848..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/pkg2/subpkg/compat.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg2.subpkg.compat """
-
-X, Y = 1, 2
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/script.py
deleted file mode 100644
index 5867662..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-import-from-init/script.py
+++ /dev/null
@@ -1,2 +0,0 @@
-import pkg.subpkg
-import pkg2.subpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/main_script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/main_script.py
deleted file mode 100644
index de10111..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/main_script.py
+++ /dev/null
@@ -1 +0,0 @@
-import sys
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/__init__.py
deleted file mode 100644
index 84c8df8..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.init """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub1/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub1/__init__.py
deleted file mode 100644
index 7d52f7f..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub1/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub1.init """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub1/modA.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub1/modA.py
deleted file mode 100644
index b827020..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub1/modA.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub1.modA """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub2/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub2/__init__.py
deleted file mode 100644
index ca5ca11..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub2/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub2.init """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub2/mod.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub2/mod.py
deleted file mode 100644
index 1b172c8..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub2/mod.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub2.mod """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub3.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub3.py
deleted file mode 100644
index 211217d..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-packages/pkg/sub3.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub3 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path1/package/sub2.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path1/package/sub2.py
deleted file mode 100644
index 894a1ec..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path1/package/sub2.py
+++ /dev/null
@@ -1 +0,0 @@
-""" package.sub2 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/nspkg/mod.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/nspkg/mod.py
deleted file mode 100644
index 9e846e4..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/nspkg/mod.py
+++ /dev/null
@@ -1 +0,0 @@
-""" package.nspkg.mod """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/sub1.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/sub1.py
deleted file mode 100644
index bb1f933..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/sub1.py
+++ /dev/null
@@ -1 +0,0 @@
-""" package.sub1 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/__init__.py
deleted file mode 100644
index d1c6849..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" package.subpackage """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/sub.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/sub.py
deleted file mode 100644
index f0ed11d..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-pep420-namespace/path2/package/subpackage/sub.py
+++ /dev/null
@@ -1 +0,0 @@
-""" package.subpackage.sub """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/main_script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/main_script.py
deleted file mode 100644
index 35e2a36..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/main_script.py
+++ /dev/null
@@ -1 +0,0 @@
-from pkg import a
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/a.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/a.py
deleted file mode 100644
index b02981c..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/a.py
+++ /dev/null
@@ -1 +0,0 @@
-from . import b
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/b.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/b.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr1/pkg/b.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/main_script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/main_script.py
deleted file mode 100644
index 288701b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/main_script.py
+++ /dev/null
@@ -1 +0,0 @@
-import pkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/__init__.py
deleted file mode 100644
index 1374eb3..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/__init__.py
+++ /dev/null
@@ -1,9 +0,0 @@
-"""
-Package structure simular to crcmod
-"""
-try:
-    from pkg.pkg import *
-    import pkg.base
-except ImportError:
-    from pkg import *
-    import base
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/base.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/base.py
deleted file mode 100644
index 93e66ee..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/base.py
+++ /dev/null
@@ -1 +0,0 @@
-""" package base """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/pkg.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/pkg.py
deleted file mode 100644
index d5fcda2..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr2/pkg/pkg.py
+++ /dev/null
@@ -1 +0,0 @@
-""" nested """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/distutils/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/distutils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/distutils/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/distutils/ccompiler.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/distutils/ccompiler.py
deleted file mode 100644
index c1b0f9b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/mypkg/distutils/ccompiler.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from distutils.ccompiler import *
-from distutils.sysconfig import customize_compiler
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/script.py
deleted file mode 100644
index 9e38ced..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr3/script.py
+++ /dev/null
@@ -1 +0,0 @@
-from mypkg.distutils import ccompiler
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/__init__.py
deleted file mode 100644
index 82e4875..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.__init__ """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/__init__.py
deleted file mode 100644
index b393ff5..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.core.__init__ """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/callables.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/callables.py
deleted file mode 100644
index 9ce619b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/callables.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg.callables """
-
-getID, getArgs, getRawFunction, ListenerInadequate, CallArgsInfo = [None]*5
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/listener.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/listener.py
deleted file mode 100644
index 28ae017..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/listener.py
+++ /dev/null
@@ -1,6 +0,0 @@
-from .callables import \
-    getID, getArgs, getRawFunction,\
-    ListenerInadequate, \
-    CallArgsInfo
-
-from .listenerimpl import Listener, ListenerValidator
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/listenerimpl.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/listenerimpl.py
deleted file mode 100644
index 775bd34..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/pkg/core/listenerimpl.py
+++ /dev/null
@@ -1,6 +0,0 @@
-""" pkg.listenerimp """
-class Listener:
-    pass
-
-class ListenerValidator:
-    pass
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/script.py
deleted file mode 100644
index a3b2bfd..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr4/script.py
+++ /dev/null
@@ -1 +0,0 @@
-from pkg.core.listener import Listener as listen
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr5/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr5/__init__.py
deleted file mode 100644
index 606f71e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr5/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" A dummy __init__ file """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr5/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr5/script.py
deleted file mode 100644
index 2a5de40..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr5/script.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import __init__
-
-from modulegraph.find_modules import find_needed_modules
-import distutils
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr6/module.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr6/module.py
deleted file mode 100644
index f6b6f89..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr6/module.py
+++ /dev/null
@@ -1,1009 +0,0 @@
-
-ds = {
-    'name': [
-        list(1)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-        + list(2)
-    ]
-}
-
-import os
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr6/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr6/script.py
deleted file mode 100644
index 92211e1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-regr6/script.py
+++ /dev/null
@@ -1 +0,0 @@
-import module
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/mod.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/mod.py
deleted file mode 100644
index 7828fc9..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/mod.py
+++ /dev/null
@@ -1 +0,0 @@
-""" Toplevel module """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/__init__.py
deleted file mode 100644
index 7fa65f6..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" A Package """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/mod.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/mod.py
deleted file mode 100644
index de7fba1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/mod.py
+++ /dev/null
@@ -1 +0,0 @@
-""" A package module """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/oldstyle.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/oldstyle.py
deleted file mode 100644
index 4985e70..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/oldstyle.py
+++ /dev/null
@@ -1 +0,0 @@
-import mod
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/relative.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/relative.py
deleted file mode 100644
index 8ffd65a..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/relative.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from __future__ import absolute_import
-from . import mod
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/relimport.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/relimport.py
deleted file mode 100644
index e23cb2e..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/relimport.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.relimport """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/sub2/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/sub2/__init__.py
deleted file mode 100644
index 75c8c11..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/sub2/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub2 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/sub2/mod.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/sub2/mod.py
deleted file mode 100644
index 1b172c8..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/sub2/mod.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.sub2.mod """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/__init__.py
deleted file mode 100644
index ced6ba0..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-""" pkg.subpkg """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/mod2.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/mod2.py
deleted file mode 100644
index 791e4d4..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/mod2.py
+++ /dev/null
@@ -1,4 +0,0 @@
-""" pkg.subpkg.mod2 """
-from __future__ import absolute_import
-from ..sub2.mod import __doc__
-from ..sub2 import mod
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/relative.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/relative.py
deleted file mode 100644
index 775f435..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/relative.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg.subpkg.relative """
-from __future__ import absolute_import
-from .. import mod
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/relative2.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/relative2.py
deleted file mode 100644
index 9e11e20..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/subpkg/relative2.py
+++ /dev/null
@@ -1,3 +0,0 @@
-""" pkg.subpkg.relative """
-from __future__ import absolute_import
-from ..relimport import __doc__ as doc
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/toplevel.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/toplevel.py
deleted file mode 100644
index 67f0bb7..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/pkg/toplevel.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from __future__ import absolute_import
-import mod
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/script.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/script.py
deleted file mode 100644
index d2199dc..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport/script.py
+++ /dev/null
@@ -1,9 +0,0 @@
-import mod
-import pkg
-import pkg.mod
-import pkg.oldstyle
-import pkg.relative
-import pkg.toplevel
-import pkg.subpkg.relative
-import pkg.subpkg.relative2
-import pkg.subpkg.mod2
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/__init__.py
deleted file mode 100644
index 085139d..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/__init__.py
+++ /dev/null
@@ -1,2 +0,0 @@
-from . import mod1
-from .mod2 import *
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod1.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod1.py
deleted file mode 100644
index b7ef456..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod1.py
+++ /dev/null
@@ -1 +0,0 @@
-""" mod1 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod2.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod2.py
deleted file mode 100644
index 7161f08..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod2.py
+++ /dev/null
@@ -1 +0,0 @@
-""" mod2 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod3.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod3.py
deleted file mode 100644
index 7999d2d..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/mod3.py
+++ /dev/null
@@ -1 +0,0 @@
-""" mod3 """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/sub/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/sub/__init__.py
deleted file mode 100644
index 30440c3..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/pkg/sub/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from .. import mod1
-from .. import mod3
-from ... import toplevel
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/toplevel.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/toplevel.py
deleted file mode 100644
index 29059b9..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-relimport2/toplevel.py
+++ /dev/null
@@ -1 +0,0 @@
-""" toplevel """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/__init__.py
deleted file mode 100644
index 2e2033b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# this is a namespace package
-try:
-    import pkg_resources
-    pkg_resources.declare_namespace(__name__)
-except ImportError:
-    import pkgutil
-    __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/module.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/module.py
deleted file mode 100644
index 0c1d857..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/module.py
+++ /dev/null
@@ -1 +0,0 @@
-""" nspkg.module """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/__init__.py
deleted file mode 100644
index 2e2033b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# this is a namespace package
-try:
-    import pkg_resources
-    pkg_resources.declare_namespace(__name__)
-except ImportError:
-    import pkgutil
-    __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/sub.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/sub.py
deleted file mode 100644
index bce954b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/build/lib/nspkg/nssubpkg/sub.py
+++ /dev/null
@@ -1 +0,0 @@
-""" nspkg.nsubpkg.sub """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/setup.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/setup.py
deleted file mode 100644
index c3d21a1..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/setup.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from setuptools import setup
-
-setup(
-    name="nspkg",
-    version="1.0",
-    namespace_packages=['nspkg', 'nspkg.nssubpkg'],
-    packages=['nspkg', 'nspkg.nssubpkg'],
-    package_dir = {'': 'src'},
-    zip_safe=False,
-)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/PKG-INFO b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/PKG-INFO
deleted file mode 100644
index a2d9629..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/PKG-INFO
+++ /dev/null
@@ -1,10 +0,0 @@
-Metadata-Version: 1.0
-Name: nspkg
-Version: 1.0
-Summary: UNKNOWN
-Home-page: UNKNOWN
-Author: UNKNOWN
-Author-email: UNKNOWN
-License: UNKNOWN
-Description: UNKNOWN
-Platform: UNKNOWN
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/SOURCES.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/SOURCES.txt
deleted file mode 100644
index 6288716..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/SOURCES.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-setup.py
-src/nspkg/__init__.py
-src/nspkg/module.py
-src/nspkg.egg-info/PKG-INFO
-src/nspkg.egg-info/SOURCES.txt
-src/nspkg.egg-info/dependency_links.txt
-src/nspkg.egg-info/namespace_packages.txt
-src/nspkg.egg-info/not-zip-safe
-src/nspkg.egg-info/top_level.txt
-src/nspkg/nssubpkg/__init__.py
-src/nspkg/nssubpkg/sub.py
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/dependency_links.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/dependency_links.txt
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/dependency_links.txt
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/namespace_packages.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/namespace_packages.txt
deleted file mode 100644
index 2321d6b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/namespace_packages.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-nspkg
-nspkg.nssubpkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/not-zip-safe b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/not-zip-safe
deleted file mode 100644
index 8b13789..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/not-zip-safe
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/top_level.txt b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/top_level.txt
deleted file mode 100644
index 61d82f4..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info/top_level.txt
+++ /dev/null
@@ -1 +0,0 @@
-nspkg
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/__init__.py
deleted file mode 100644
index 2e2033b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# this is a namespace package
-try:
-    import pkg_resources
-    pkg_resources.declare_namespace(__name__)
-except ImportError:
-    import pkgutil
-    __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/module.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/module.py
deleted file mode 100644
index 0c1d857..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/module.py
+++ /dev/null
@@ -1 +0,0 @@
-""" nspkg.module """
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/__init__.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/__init__.py
deleted file mode 100644
index 2e2033b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/__init__.py
+++ /dev/null
@@ -1,7 +0,0 @@
-# this is a namespace package
-try:
-    import pkg_resources
-    pkg_resources.declare_namespace(__name__)
-except ImportError:
-    import pkgutil
-    __path__ = pkgutil.extend_path(__path__, __name__)
diff --git a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/sub.py b/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/sub.py
deleted file mode 100644
index bce954b..0000000
--- a/catapult/telemetry/third_party/modulegraph/modulegraph_tests/testpkg-setuptools-namespace/src/nspkg/nssubpkg/sub.py
+++ /dev/null
@@ -1 +0,0 @@
-""" nspkg.nsubpkg.sub """
diff --git a/catapult/telemetry/third_party/modulegraph/scripts/extract_implies.py b/catapult/telemetry/third_party/modulegraph/scripts/extract_implies.py
deleted file mode 100644
index d6ab353..0000000
--- a/catapult/telemetry/third_party/modulegraph/scripts/extract_implies.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python
-"""
-This script looks for ImportModules calls in C extensions
-of the stdlib.
-
-The current version has harcoded the location of the source
-tries on Ronald's machine, a future version will be able
-to rebuild the modulegraph source file that contains
-this information.
-"""
-
-import re
-import sys
-import os
-import pprint
-
-import_re = re.compile('PyImport_ImportModule\w+\("(\w+)"\);')
-
-def extract_implies(root):
-    modules_dir = os.path.join(root, "Modules")
-    for fn in os.listdir(modules_dir):
-        if not fn.endswith('.c'):
-            continue
-
-        module_name = fn[:-2]
-        if module_name.endswith('module'):
-            module_name = module_name[:-6]
-
-        with open(os.path.join(modules_dir, fn)) as fp:
-            data = fp.read()
-
-        imports = list(sorted(set(import_re.findall(data))))
-        if imports:
-            yield module_name, imports
-
-
-
-def main():
-    for version in ('2.6', '2.7', '3.1'):
-        print "====", version
-        pprint.pprint(list(extract_implies('/Users/ronald/Projects/python/release%s-maint'%(version.replace('.', '')))))
-
-if __name__ == "__main__":
-    main()
diff --git a/catapult/telemetry/third_party/modulegraph/setup.cfg b/catapult/telemetry/third_party/modulegraph/setup.cfg
deleted file mode 100644
index f1d0167..0000000
--- a/catapult/telemetry/third_party/modulegraph/setup.cfg
+++ /dev/null
@@ -1,54 +0,0 @@
-[metadata]
-name = modulegraph
-version = 0.12.1
-description = Python module dependency analysis tool
-long_description_file = 
-	README.txt
-	doc/changelog.rst
-classifiers = 
-	Intended Audience :: Developers
-	License :: OSI Approved :: MIT License
-	Programming Language :: Python
-	Programming Language :: Python :: 2
-	Programming Language :: Python :: 2.7
-	Programming Language :: Python :: 3
-	Programming Language :: Python :: 3.3
-	Programming Language :: Python :: 3.4
-	Topic :: Software Development :: Libraries :: Python Modules
-	Topic :: Software Development :: Build Tools
-author = Ronald Oussoren
-author_email = ronaldoussoren@mac.com
-maintainer = Ronald Oussoren
-maintainer_email = ronaldoussoren@mac.com
-url = http://bitbucket.org/ronaldoussoren/modulegraph
-download_url = http://pypi.python.org/pypi/modulegraph
-license = MIT
-packages = modulegraph
-platforms = any
-requires-dist = 
-	altgraph (>= 0.12)
-console_scripts = 
-	modulegraph = modulegraph.__main__:main
-zip-safe = 1
-keywords = import, dependencies
-
-[check-manifest]
-ignore = 
-	modulegraph_tests/testdata/nspkg/distribute-0.6.10/child/nameduser-1.5-py2.6.egg-info
-	modulegraph_tests/testdata/nspkg/distribute-0.6.10/parent/namedpkg-1.0-py2.6.egg-info
-	modulegraph_tests/testdata/nspkg/distribute-0.6.12/child/nameduser-1.5-py2.5.egg-info
-	modulegraph_tests/testdata/nspkg/distribute-0.6.12/parent/namedpkg-1.0-py2.5.egg-info
-	modulegraph_tests/testdata/nspkg/setuptools-0.6c9/child/nameduser-1.5-py2.5.egg-info
-	modulegraph_tests/testdata/nspkg/setuptools-0.6c9/parent/namedpkg-1.0-py2.5.egg-info
-	modulegraph_tests/testdata/nspkg/src/child/nameduser.egg-info
-	modulegraph_tests/testdata/nspkg/src/parent/namedpkg.egg-info
-	modulegraph_tests/testdata/syspath/myext.pyd
-	modulegraph_tests/testdata/syspath/myext.so
-	modulegraph_tests/testdata/syspath/mymodule2.pyc
-	modulegraph_tests/testpkg-setuptools-namespace/src/nspkg.egg-info
-
-[egg_info]
-tag_build = 
-tag_date = 0
-tag_svn_revision = 0
-
diff --git a/catapult/telemetry/third_party/modulegraph/setup.py b/catapult/telemetry/third_party/modulegraph/setup.py
deleted file mode 100644
index a1a4cb6..0000000
--- a/catapult/telemetry/third_party/modulegraph/setup.py
+++ /dev/null
@@ -1,867 +0,0 @@
-"""
-Shared setup file for simple python packages. Uses a setup.cfg that
-is the same as the distutils2 project, unless noted otherwise.
-
-It exists for two reasons:
-1) This makes it easier to reuse setup.py code between my own
-   projects
-
-2) Easier migration to distutils2 when that catches on.
-
-Additional functionality:
-
-* Section metadata:
-    requires-test:  Same as 'tests_require' option for setuptools.
-
-"""
-
-import sys
-import os
-import re
-import platform
-from fnmatch import fnmatch
-import os
-import sys
-import time
-import tempfile
-import tarfile
-try:
-    import urllib.request as urllib
-except ImportError:
-    import urllib
-from distutils import log
-try:
-    from hashlib import md5
-
-except ImportError:
-    from md5 import md5
-
-if sys.version_info[0] == 2:
-    from ConfigParser import RawConfigParser, NoOptionError, NoSectionError
-else:
-    from configparser import RawConfigParser, NoOptionError, NoSectionError
-
-ROOTDIR = os.path.dirname(os.path.abspath(__file__))
-
-
-#
-#
-#
-# Parsing the setup.cfg and converting it to something that can be
-# used by setuptools.setup()
-#
-#
-#
-
-def eval_marker(value):
-    """
-    Evaluate an distutils2 environment marker.
-
-    This code is unsafe when used with hostile setup.cfg files,
-    but that's not a problem for our own files.
-    """
-    value = value.strip()
-
-    class M:
-        def __init__(self, **kwds):
-            for k, v in kwds.items():
-                setattr(self, k, v)
-
-    variables = {
-        'python_version': '%d.%d'%(sys.version_info[0], sys.version_info[1]),
-        'python_full_version': sys.version.split()[0],
-        'os': M(
-            name=os.name,
-        ),
-        'sys': M(
-            platform=sys.platform,
-        ),
-        'platform': M(
-            version=platform.version(),
-            machine=platform.machine(),
-        ),
-    }
-
-    return bool(eval(value, variables, variables))
-
-
-    return True
-
-def _opt_value(cfg, into, section, key, transform = None):
-    try:
-        v = cfg.get(section, key)
-        if transform != _as_lines and ';' in v:
-            v, marker = v.rsplit(';', 1)
-            if not eval_marker(marker):
-                return
-
-            v = v.strip()
-
-        if v:
-            if transform:
-                into[key] = transform(v.strip())
-            else:
-                into[key] = v.strip()
-
-    except (NoOptionError, NoSectionError):
-        pass
-
-def _as_bool(value):
-    if value.lower() in ('y', 'yes', 'on'):
-        return True
-    elif value.lower() in ('n', 'no', 'off'):
-        return False
-    elif value.isdigit():
-        return bool(int(value))
-    else:
-        raise ValueError(value)
-
-def _as_list(value):
-    return value.split()
-
-def _as_lines(value):
-    result = []
-    for v in value.splitlines():
-        if ';' in v:
-            v, marker = v.rsplit(';', 1)
-            if not eval_marker(marker):
-                continue
-
-            v = v.strip()
-            if v:
-                result.append(v)
-        else:
-            result.append(v)
-    return result
-
-def _map_requirement(value):
-    m = re.search(r'(\S+)\s*(?:\((.*)\))?', value)
-    name = m.group(1)
-    version = m.group(2)
-
-    if version is None:
-        return name
-
-    else:
-        mapped = []
-        for v in version.split(','):
-            v = v.strip()
-            if v[0].isdigit():
-                # Checks for a specific version prefix
-                m = v.rsplit('.', 1)
-                mapped.append('>=%s,<%s.%s'%(
-                    v, m[0], int(m[1])+1))
-
-            else:
-                mapped.append(v)
-        return '%s %s'%(name, ','.join(mapped),)
-
-def _as_requires(value):
-    requires = []
-    for req in value.splitlines():
-        if ';' in req:
-            req, marker = v.rsplit(';', 1)
-            if not eval_marker(marker):
-                continue
-            req = req.strip()
-
-        if not req:
-            continue
-        requires.append(_map_requirement(req))
-    return requires
-
-def parse_setup_cfg():
-    cfg = RawConfigParser()
-    r = cfg.read([os.path.join(ROOTDIR, 'setup.cfg')])
-    if len(r) != 1:
-        print("Cannot read 'setup.cfg'")
-        sys.exit(1)
-
-    metadata = dict(
-            name        = cfg.get('metadata', 'name'),
-            version     = cfg.get('metadata', 'version'),
-            description = cfg.get('metadata', 'description'),
-    )
-
-    _opt_value(cfg, metadata, 'metadata', 'license')
-    _opt_value(cfg, metadata, 'metadata', 'maintainer')
-    _opt_value(cfg, metadata, 'metadata', 'maintainer_email')
-    _opt_value(cfg, metadata, 'metadata', 'author')
-    _opt_value(cfg, metadata, 'metadata', 'author_email')
-    _opt_value(cfg, metadata, 'metadata', 'url')
-    _opt_value(cfg, metadata, 'metadata', 'download_url')
-    _opt_value(cfg, metadata, 'metadata', 'classifiers', _as_lines)
-    _opt_value(cfg, metadata, 'metadata', 'platforms', _as_list)
-    _opt_value(cfg, metadata, 'metadata', 'packages', _as_list)
-    _opt_value(cfg, metadata, 'metadata', 'keywords', _as_list)
-
-    try:
-        v = cfg.get('metadata', 'requires-dist')
-
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        requires = _as_requires(v)
-        if requires:
-            metadata['install_requires'] = requires
-
-    try:
-        v = cfg.get('metadata', 'requires-test')
-
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        requires = _as_requires(v)
-        if requires:
-            metadata['tests_require'] = requires
-
-
-    try:
-        v = cfg.get('metadata', 'long_description_file')
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        parts = []
-        for nm in v.split():
-            fp = open(nm, 'rU')
-            parts.append(fp.read())
-            fp.close()
-
-        metadata['long_description'] = '\n\n'.join(parts)
-
-
-    try:
-        v = cfg.get('metadata', 'zip-safe')
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        metadata['zip_safe'] = _as_bool(v)
-
-    try:
-        v = cfg.get('metadata', 'console_scripts')
-    except (NoOptionError, NoSectionError):
-        pass
-
-    else:
-        if 'entry_points' not in metadata:
-            metadata['entry_points'] = {}
-
-        metadata['entry_points']['console_scripts'] = v.splitlines()
-
-    if sys.version_info[:2] <= (2,6):
-        try:
-            metadata['tests_require'] += ", unittest2"
-        except KeyError:
-            metadata['tests_require'] = "unittest2"
-
-    return metadata
-
-
-#
-#
-#
-# Bootstrapping setuptools/distribute, based on
-# a heavily modified version of distribute_setup.py
-#
-#
-#
-
-
-SETUPTOOLS_PACKAGE='setuptools'
-
-
-try:
-    import subprocess
-
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        return subprocess.call(args) == 0
-
-except ImportError:
-    def _python_cmd(*args):
-        args = (sys.executable,) + args
-        new_args = []
-        for a in args:
-            new_args.append(a.replace("'", "'\"'\"'"))
-        os.system(' '.join(new_args)) == 0
-
-
-try:
-    import json
-
-    def get_pypi_src_download(package):
-        url = 'https://pypi.python.org/pypi/%s/json'%(package,)
-        fp = urllib.urlopen(url)
-        try:
-            try:
-                data = fp.read()
-
-            finally:
-                fp.close()
-        except urllib.error:
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        pkgdata = json.loads(data.decode('utf-8'))
-        if 'urls' not in pkgdata:
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        for info in pkgdata['urls']:
-            if info['packagetype'] == 'sdist' and info['url'].endswith('tar.gz'):
-                return (info.get('md5_digest'), info['url'])
-
-        raise RuntimeError("Cannot determine downlink link for %s"%(package,))
-
-except ImportError:
-    # Python 2.5 compatibility, no JSON in stdlib but luckily JSON syntax is
-    # simular enough to Python's syntax to be able to abuse the Python compiler
-
-    import _ast as ast
-
-    def get_pypi_src_download(package):
-        url = 'https://pypi.python.org/pypi/%s/json'%(package,)
-        fp = urllib.urlopen(url)
-        try:
-            try:
-                data = fp.read()
-
-            finally:
-                fp.close()
-        except urllib.error:
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-
-        a = compile(data, '-', 'eval', ast.PyCF_ONLY_AST)
-        if not isinstance(a, ast.Expression):
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        a = a.body
-        if not isinstance(a, ast.Dict):
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        for k, v in zip(a.keys, a.values):
-            if not isinstance(k, ast.Str):
-                raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-            k = k.s
-            if k == 'urls':
-                a = v
-                break
-        else:
-            raise RuntimeError("PyPI JSON for %s doesn't contain URLs section"%(package,))
-
-        if not isinstance(a, ast.List):
-            raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-        for info in v.elts:
-            if not isinstance(info, ast.Dict):
-                raise RuntimeError("Cannot determine download link for %s"%(package,))
-            url = None
-            packagetype = None
-            chksum = None
-
-            for k, v in zip(info.keys, info.values):
-                if not isinstance(k, ast.Str):
-                    raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-                if k.s == 'url':
-                    if not isinstance(v, ast.Str):
-                        raise RuntimeError("Cannot determine download link for %s"%(package,))
-                    url = v.s
-
-                elif k.s == 'packagetype':
-                    if not isinstance(v, ast.Str):
-                        raise RuntimeError("Cannot determine download link for %s"%(package,))
-                    packagetype = v.s
-
-                elif k.s == 'md5_digest':
-                    if not isinstance(v, ast.Str):
-                        raise RuntimeError("Cannot determine download link for %s"%(package,))
-                    chksum = v.s
-
-            if url is not None and packagetype == 'sdist' and url.endswith('.tar.gz'):
-                return (chksum, url)
-
-        raise RuntimeError("Cannot determine download link for %s"%(package,))
-
-def _build_egg(egg, tarball, to_dir):
-    # extracting the tarball
-    tmpdir = tempfile.mkdtemp()
-    log.warn('Extracting in %s', tmpdir)
-    old_wd = os.getcwd()
-    try:
-        os.chdir(tmpdir)
-        tar = tarfile.open(tarball)
-        _extractall(tar)
-        tar.close()
-
-        # going in the directory
-        subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
-        os.chdir(subdir)
-        log.warn('Now working in %s', subdir)
-
-        # building an egg
-        log.warn('Building a %s egg in %s', egg, to_dir)
-        _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir)
-
-    finally:
-        os.chdir(old_wd)
-    # returning the result
-    log.warn(egg)
-    if not os.path.exists(egg):
-        raise IOError('Could not build the egg.')
-
-
-def _do_download(to_dir, packagename=SETUPTOOLS_PACKAGE):
-    tarball = download_setuptools(packagename, to_dir)
-    version = tarball.split('-')[-1][:-7]
-    egg = os.path.join(to_dir, '%s-%s-py%d.%d.egg'
-                       % (packagename, version, sys.version_info[0], sys.version_info[1]))
-    if not os.path.exists(egg):
-        _build_egg(egg, tarball, to_dir)
-    sys.path.insert(0, egg)
-    import setuptools
-    setuptools.bootstrap_install_from = egg
-
-
-def use_setuptools():
-    # making sure we use the absolute path
-    return _do_download(os.path.abspath(os.curdir))
-
-def download_setuptools(packagename, to_dir):
-    # making sure we use the absolute path
-    to_dir = os.path.abspath(to_dir)
-    try:
-        from urllib.request import urlopen
-    except ImportError:
-        from urllib2 import urlopen
-
-    chksum, url = get_pypi_src_download(packagename)
-    tgz_name = os.path.basename(url)
-    saveto = os.path.join(to_dir, tgz_name)
-
-    src = dst = None
-    if not os.path.exists(saveto):  # Avoid repeated downloads
-        try:
-            log.warn("Downloading %s", url)
-            src = urlopen(url)
-            # Read/write all in one block, so we don't create a corrupt file
-            # if the download is interrupted.
-            data = src.read()
-
-            if chksum is not None:
-                data_sum = md5(data).hexdigest()
-                if data_sum != chksum:
-                    raise RuntimeError("Downloading %s failed: corrupt checksum"%(url,))
-
-
-            dst = open(saveto, "wb")
-            dst.write(data)
-        finally:
-            if src:
-                src.close()
-            if dst:
-                dst.close()
-    return os.path.realpath(saveto)
-
-
-
-def _extractall(self, path=".", members=None):
-    """Extract all members from the archive to the current working
-       directory and set owner, modification time and permissions on
-       directories afterwards. `path' specifies a different directory
-       to extract to. `members' is optional and must be a subset of the
-       list returned by getmembers().
-    """
-    import copy
-    import operator
-    from tarfile import ExtractError
-    directories = []
-
-    if members is None:
-        members = self
-
-    for tarinfo in members:
-        if tarinfo.isdir():
-            # Extract directories with a safe mode.
-            directories.append(tarinfo)
-            tarinfo = copy.copy(tarinfo)
-            tarinfo.mode = 448 # decimal for oct 0700
-        self.extract(tarinfo, path)
-
-    # Reverse sort directories.
-    if sys.version_info < (2, 4):
-        def sorter(dir1, dir2):
-            return cmp(dir1.name, dir2.name)
-        directories.sort(sorter)
-        directories.reverse()
-    else:
-        directories.sort(key=operator.attrgetter('name'), reverse=True)
-
-    # Set correct owner, mtime and filemode on directories.
-    for tarinfo in directories:
-        dirpath = os.path.join(path, tarinfo.name)
-        try:
-            self.chown(tarinfo, dirpath)
-            self.utime(tarinfo, dirpath)
-            self.chmod(tarinfo, dirpath)
-        except ExtractError:
-            e = sys.exc_info()[1]
-            if self.errorlevel > 1:
-                raise
-            else:
-                self._dbg(1, "tarfile: %s" % e)
-
-
-#
-#
-#
-# Definitions of custom commands
-#
-#
-#
-
-try:
-    import setuptools
-
-except ImportError:
-    use_setuptools()
-
-from setuptools import setup
-
-try:
-    from distutils.core import PyPIRCCommand
-except ImportError:
-    PyPIRCCommand = None # Ancient python version
-
-from distutils.core import Command
-from distutils.errors  import DistutilsError
-from distutils import log
-
-if PyPIRCCommand is None:
-    class upload_docs (Command):
-        description = "upload sphinx documentation"
-        user_options = []
-
-        def initialize_options(self):
-            pass
-
-        def finalize_options(self):
-            pass
-
-        def run(self):
-            raise DistutilsError("not supported on this version of python")
-
-else:
-    class upload_docs (PyPIRCCommand):
-        description = "upload sphinx documentation"
-        user_options = PyPIRCCommand.user_options
-
-        def initialize_options(self):
-            PyPIRCCommand.initialize_options(self)
-            self.username = ''
-            self.password = ''
-
-
-        def finalize_options(self):
-            PyPIRCCommand.finalize_options(self)
-            config = self._read_pypirc()
-            if config != {}:
-                self.username = config['username']
-                self.password = config['password']
-
-
-        def run(self):
-            import subprocess
-            import shutil
-            import zipfile
-            import os
-            import urllib
-            import StringIO
-            from base64 import standard_b64encode
-            import httplib
-            import urlparse
-
-            # Extract the package name from distutils metadata
-            meta = self.distribution.metadata
-            name = meta.get_name()
-
-            # Run sphinx
-            if os.path.exists('doc/_build'):
-                shutil.rmtree('doc/_build')
-            os.mkdir('doc/_build')
-
-            p = subprocess.Popen(['make', 'html'],
-                cwd='doc')
-            exit = p.wait()
-            if exit != 0:
-                raise DistutilsError("sphinx-build failed")
-
-            # Collect sphinx output
-            if not os.path.exists('dist'):
-                os.mkdir('dist')
-            zf = zipfile.ZipFile('dist/%s-docs.zip'%(name,), 'w',
-                    compression=zipfile.ZIP_DEFLATED)
-
-            for toplevel, dirs, files in os.walk('doc/_build/html'):
-                for fn in files:
-                    fullname = os.path.join(toplevel, fn)
-                    relname = os.path.relpath(fullname, 'doc/_build/html')
-
-                    print ("%s -> %s"%(fullname, relname))
-
-                    zf.write(fullname, relname)
-
-            zf.close()
-
-            # Upload the results, this code is based on the distutils
-            # 'upload' command.
-            content = open('dist/%s-docs.zip'%(name,), 'rb').read()
-
-            data = {
-                ':action': 'doc_upload',
-                'name': name,
-                'content': ('%s-docs.zip'%(name,), content),
-            }
-            auth = "Basic " + standard_b64encode(self.username + ":" +
-                 self.password)
-
-
-            boundary = '--------------GHSKFJDLGDS7543FJKLFHRE75642756743254'
-            sep_boundary = '\n--' + boundary
-            end_boundary = sep_boundary + '--'
-            body = StringIO.StringIO()
-            for key, value in data.items():
-                if not isinstance(value, list):
-                    value = [value]
-
-                for value in value:
-                    if isinstance(value, tuple):
-                        fn = ';filename="%s"'%(value[0])
-                        value = value[1]
-                    else:
-                        fn = ''
-
-                    body.write(sep_boundary)
-                    body.write('\nContent-Disposition: form-data; name="%s"'%key)
-                    body.write(fn)
-                    body.write("\n\n")
-                    body.write(value)
-
-            body.write(end_boundary)
-            body.write('\n')
-            body = body.getvalue()
-
-            self.announce("Uploading documentation to %s"%(self.repository,), log.INFO)
-
-            schema, netloc, url, params, query, fragments = \
-                    urlparse.urlparse(self.repository)
-
-
-            if schema == 'http':
-                http = httplib.HTTPConnection(netloc)
-            elif schema == 'https':
-                http = httplib.HTTPSConnection(netloc)
-            else:
-                raise AssertionError("unsupported schema "+schema)
-
-            data = ''
-            loglevel = log.INFO
-            try:
-                http.connect()
-                http.putrequest("POST", url)
-                http.putheader('Content-type',
-                    'multipart/form-data; boundary=%s'%boundary)
-                http.putheader('Content-length', str(len(body)))
-                http.putheader('Authorization', auth)
-                http.endheaders()
-                http.send(body)
-            except socket.error:
-                e = socket.exc_info()[1]
-                self.announce(str(e), log.ERROR)
-                return
-
-            r = http.getresponse()
-            if r.status in (200, 301):
-                self.announce('Upload succeeded (%s): %s' % (r.status, r.reason),
-                    log.INFO)
-            else:
-                self.announce('Upload failed (%s): %s' % (r.status, r.reason),
-                    log.ERROR)
-
-                print ('-'*75)
-                print (r.read())
-                print ('-'*75)
-
-
-def recursiveGlob(root, pathPattern):
-    """
-    Recursively look for files matching 'pathPattern'. Return a list
-    of matching files/directories.
-    """
-    result = []
-
-    for rootpath, dirnames, filenames in os.walk(root):
-        for fn in filenames:
-            if fnmatch(fn, pathPattern):
-                result.append(os.path.join(rootpath, fn))
-    return result
-
-
-def importExternalTestCases(unittest,
-        pathPattern="test_*.py", root=".", package=None):
-    """
-    Import all unittests in the PyObjC tree starting at 'root'
-    """
-
-    testFiles = recursiveGlob(root, pathPattern)
-    testModules = map(lambda x:x[len(root)+1:-3].replace('/', '.'), testFiles)
-    if package is not None:
-        testModules = [(package + '.' + m) for m in testModules]
-
-    suites = []
-
-    for modName in testModules:
-        try:
-            module = __import__(modName)
-        except ImportError:
-            print("SKIP %s: %s"%(modName, sys.exc_info()[1]))
-            continue
-
-        if '.' in modName:
-            for elem in modName.split('.')[1:]:
-                module = getattr(module, elem)
-
-        s = unittest.defaultTestLoader.loadTestsFromModule(module)
-        suites.append(s)
-
-    return unittest.TestSuite(suites)
-
-
-
-class test (Command):
-    description = "run test suite"
-    user_options = [
-        ('verbosity=', None, "print what tests are run"),
-    ]
-
-    def initialize_options(self):
-        self.verbosity='1'
-
-    def finalize_options(self):
-        if isinstance(self.verbosity, str):
-            self.verbosity = int(self.verbosity)
-
-
-    def cleanup_environment(self):
-        ei_cmd = self.get_finalized_command('egg_info')
-        egg_name = ei_cmd.egg_name.replace('-', '_')
-
-        to_remove =  []
-        for dirname in sys.path:
-            bn = os.path.basename(dirname)
-            if bn.startswith(egg_name + "-"):
-                to_remove.append(dirname)
-
-        for dirname in to_remove:
-            log.info("removing installed %r from sys.path before testing"%(
-                dirname,))
-            sys.path.remove(dirname)
-
-    def add_project_to_sys_path(self):
-        from pkg_resources import normalize_path, add_activation_listener
-        from pkg_resources import working_set, require
-
-        self.reinitialize_command('egg_info')
-        self.run_command('egg_info')
-        self.reinitialize_command('build_ext', inplace=1)
-        self.run_command('build_ext')
-
-
-        # Check if this distribution is already on sys.path
-        # and remove that version, this ensures that the right
-        # copy of the package gets tested.
-
-        self.__old_path = sys.path[:]
-        self.__old_modules = sys.modules.copy()
-
-
-        ei_cmd = self.get_finalized_command('egg_info')
-        sys.path.insert(0, normalize_path(ei_cmd.egg_base))
-        sys.path.insert(1, os.path.dirname(__file__))
-
-        # Strip the namespace packages defined in this distribution
-        # from sys.modules, needed to reset the search path for
-        # those modules.
-
-        nspkgs = getattr(self.distribution, 'namespace_packages')
-        if nspkgs is not None:
-            for nm in nspkgs:
-                del sys.modules[nm]
-
-        # Reset pkg_resources state:
-        add_activation_listener(lambda dist: dist.activate())
-        working_set.__init__()
-        require('%s==%s'%(ei_cmd.egg_name, ei_cmd.egg_version))
-
-    def remove_from_sys_path(self):
-        from pkg_resources import working_set
-        sys.path[:] = self.__old_path
-        sys.modules.clear()
-        sys.modules.update(self.__old_modules)
-        working_set.__init__()
-
-
-    def run(self):
-        import unittest
-
-        # Ensure that build directory is on sys.path (py3k)
-
-        self.cleanup_environment()
-        self.add_project_to_sys_path()
-
-        try:
-            meta = self.distribution.metadata
-            name = meta.get_name()
-            test_pkg = name + "_tests"
-            suite = importExternalTestCases(unittest,
-                    "test_*.py", test_pkg, test_pkg)
-
-            runner = unittest.TextTestRunner(verbosity=self.verbosity)
-            result = runner.run(suite)
-
-            # Print out summary. This is a structured format that
-            # should make it easy to use this information in scripts.
-            summary = dict(
-                count=result.testsRun,
-                fails=len(result.failures),
-                errors=len(result.errors),
-                xfails=len(getattr(result, 'expectedFailures', [])),
-                xpass=len(getattr(result, 'expectedSuccesses', [])),
-                skip=len(getattr(result, 'skipped', [])),
-            )
-            print("SUMMARY: %s"%(summary,))
-
-        finally:
-            self.remove_from_sys_path()
-
-#
-#
-#
-#  And finally run the setuptools main entry point.
-#
-#
-#
-
-metadata = parse_setup_cfg()
-
-setup(
-    cmdclass=dict(
-        upload_docs=upload_docs,
-        test=test,
-    ),
-    **metadata
-)
diff --git a/catapult/telemetry/third_party/mox3/.gitignore b/catapult/telemetry/third_party/mox3/.gitignore
deleted file mode 100644
index f8f74ec..0000000
--- a/catapult/telemetry/third_party/mox3/.gitignore
+++ /dev/null
@@ -1,71 +0,0 @@
-*.py[co]
-
-# Packages
-*.egg
-*.egg-info
-dist
-build
-eggs
-parts
-bin
-var
-sdist
-develop-eggs
-.installed.cfg
-
-# Installer logs
-pip-log.txt
-
-# Unit test / coverage reports
-.coverage
-.tox
-.testrepository
-
-#Translations
-*.mo
-
-# virtualenv
-.venv
-
-#Mr Developer
-.mr.developer.cfg
-
-# https://github.com/h5bp/html5-boilerplate/blob/master/.gitignore
-# Numerous always-ignore extensions
-*.diff
-*.err
-*.orig
-*.log
-*.rej
-*.swo
-*.swp
-*.vi
-*~
-
-# OS or Editor folders
-.DS_Store
-Thumbs.db
-.cache
-.project
-.settings
-.tmproj
-nbproject
-*.sublime-project
-*.sublime-workspace
-*.komodoproject
-.komodotools
-
-# Folders to ignore
-.hg
-.svn
-.CVS
-intermediate
-publish
-.idea
-
-# PyDev
-.pydevproject
-
-# pbr
-AUTHORS
-ChangeLog
diff --git a/catapult/telemetry/third_party/mox3/.gitreview b/catapult/telemetry/third_party/mox3/.gitreview
deleted file mode 100644
index 3653540..0000000
--- a/catapult/telemetry/third_party/mox3/.gitreview
+++ /dev/null
@@ -1,4 +0,0 @@
-[gerrit]
-host=review.openstack.org
-port=29418
-project=openstack/mox3.git
diff --git a/catapult/telemetry/third_party/mox3/.mailmap b/catapult/telemetry/third_party/mox3/.mailmap
deleted file mode 100644
index 6a6d090..0000000
--- a/catapult/telemetry/third_party/mox3/.mailmap
+++ /dev/null
@@ -1 +0,0 @@
-Przemysław Gajda <quermit@gmail.com> <quermit@gmail.com>
diff --git a/catapult/telemetry/third_party/mox3/.testr.conf b/catapult/telemetry/third_party/mox3/.testr.conf
deleted file mode 100644
index 6c1541e..0000000
--- a/catapult/telemetry/third_party/mox3/.testr.conf
+++ /dev/null
@@ -1,4 +0,0 @@
-[DEFAULT]
-test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_TEST_TIMEOUT=60 ${PYTHON:-python} -m subunit.run discover -t ./ ./ $LISTOPT $IDOPTION
-test_id_option=--load-list $IDFILE
-test_list_option=--list
diff --git a/catapult/telemetry/third_party/mox3/CONTRIBUTING.rst b/catapult/telemetry/third_party/mox3/CONTRIBUTING.rst
deleted file mode 100644
index 8121da2..0000000
--- a/catapult/telemetry/third_party/mox3/CONTRIBUTING.rst
+++ /dev/null
@@ -1,17 +0,0 @@
-If you would like to contribute to the development of OpenStack,
-you must follow the steps in the "If you're a developer, start here"
-section of this page:
-
-   http://wiki.openstack.org/HowToContribute
-
-Once those steps have been completed, changes to OpenStack
-should be submitted for review via the Gerrit tool, following
-the workflow documented at:
-
-   http://wiki.openstack.org/GerritWorkflow
-
-Pull requests submitted through GitHub will be ignored.
-
-Bugs should be filed on Launchpad, not GitHub:
-
-   https://bugs.launchpad.net/mox3
diff --git a/catapult/telemetry/third_party/mox3/COPYING.txt b/catapult/telemetry/third_party/mox3/COPYING.txt
deleted file mode 100644
index d645695..0000000
--- a/catapult/telemetry/third_party/mox3/COPYING.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/catapult/telemetry/third_party/mox3/MANIFEST.in b/catapult/telemetry/third_party/mox3/MANIFEST.in
deleted file mode 100644
index c978a52..0000000
--- a/catapult/telemetry/third_party/mox3/MANIFEST.in
+++ /dev/null
@@ -1,6 +0,0 @@
-include AUTHORS
-include ChangeLog
-exclude .gitignore
-exclude .gitreview
-
-global-exclude *.pyc
diff --git a/catapult/telemetry/third_party/mox3/README.chromium b/catapult/telemetry/third_party/mox3/README.chromium
deleted file mode 100644
index cecbc0a..0000000
--- a/catapult/telemetry/third_party/mox3/README.chromium
+++ /dev/null
@@ -1,19 +0,0 @@
-Name: mox3
-Short Name: mox3
-URL: https://github.com/openstack/mox3
-Version: 60dd893a8095f9d7957bf6635dc1620a7908d86b (commit hash)
-License: Apache License 2.0
-License File: NOT_SHIPPED
-Security Critical: no
-
-Local modification:
-Remove doc/source/conf.py because it's not needed and cause the checklicense.py
-to fail.
-
-Description:
-Mox3 is an unofficial port of the Google mox framework
-(http://code.google.com/p/pymox/) to Python 3. It was meant to be as compatible
-with mox as possible, but small enhancements have been made. The library was
-tested on Python version 3.2, 2.7 and 2.6.
-
-This library is added since pyfakefs depends on it.
diff --git a/catapult/telemetry/third_party/mox3/README.rst b/catapult/telemetry/third_party/mox3/README.rst
deleted file mode 100644
index 7f9e9db..0000000
--- a/catapult/telemetry/third_party/mox3/README.rst
+++ /dev/null
@@ -1,60 +0,0 @@
-Mox3 - Mock object framework for Python 3
-=========================================
-
-Mox3 is an unofficial port of the Google mox framework
-(http://code.google.com/p/pymox/) to Python 3. It was meant to be as compatible
-with mox as possible, but small enhancements have been made. The library was
-tested on Python version 3.2, 2.7 and 2.6.
-
-Use at your own risk ;) 
-
-To install:
-
-  $ python setup.py install
-
-Running Tests
--------------
-The testing system is based on a combination of tox and testr. The canonical
-approach to running tests is to simply run the command `tox`. This will
-create virtual environments, populate them with depenedencies and run all of
-the tests that OpenStack CI systems run. Behind the scenes, tox is running
-`testr run --parallel`, but is set up such that you can supply any additional
-testr arguments that are needed to tox. For example, you can run:
-`tox -- --analyze-isolation` to cause tox to tell testr to add
---analyze-isolation to its argument list.
-
-It is also possible to run the tests inside of a virtual environment
-you have created, or it is possible that you have all of the dependencies
-installed locally already. In this case, you can interact with the testr
-command directly. Running `testr run` will run the entire test suite. `testr
-run --parallel` will run it in parallel (this is the default incantation tox
-uses.) More information about testr can be found at:
-http://wiki.openstack.org/testr
-
-Basic Usage
------------
-  
-The basic usage of mox3 is the same as with mox, but the initial import should
-be made from the mox3 module:
-
-  from mox3 import mox
-
-To learn how to use mox3 you may check the documentation of the original mox
-framework:
-
-  http://code.google.com/p/pymox/wiki/MoxDocumentation
-
-Original Copyright
-------------------
-
-Mox is Copyright 2008 Google Inc, and licensed under the Apache
-License, Version 2.0; see the file COPYING.txt for details.  If you would
-like to help us improve Mox, join the group.
-
-OpenStack Fork
---------------
-
-* Free software: Apache license
-* Documentation: http://docs.openstack.org/developer/mox3
-* Source: http://git.openstack.org/cgit/openstack/mox3
-* Bugs: http://bugs.launchpad.net/python-mox3
diff --git a/catapult/telemetry/third_party/mox3/doc/source/contributing.rst b/catapult/telemetry/third_party/mox3/doc/source/contributing.rst
deleted file mode 100644
index 2ca75d1..0000000
--- a/catapult/telemetry/third_party/mox3/doc/source/contributing.rst
+++ /dev/null
@@ -1,5 +0,0 @@
-==============
- Contributing
-==============
-
-.. include:: ../../CONTRIBUTING.rst
diff --git a/catapult/telemetry/third_party/mox3/doc/source/index.rst b/catapult/telemetry/third_party/mox3/doc/source/index.rst
deleted file mode 100644
index 2df4863..0000000
--- a/catapult/telemetry/third_party/mox3/doc/source/index.rst
+++ /dev/null
@@ -1,21 +0,0 @@
-mox3
-====
-
-A fork of mox with Python 3 support.
-
-Contents
-========
-
-.. toctree::
-   :maxdepth: 2
-
-   readme
-   contributing
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
diff --git a/catapult/telemetry/third_party/mox3/doc/source/readme.rst b/catapult/telemetry/third_party/mox3/doc/source/readme.rst
deleted file mode 100644
index a6210d3..0000000
--- a/catapult/telemetry/third_party/mox3/doc/source/readme.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. include:: ../../README.rst
diff --git a/catapult/telemetry/third_party/mox3/mox3/__init__.py b/catapult/telemetry/third_party/mox3/mox3/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/mox3/mox3/fixture.py b/catapult/telemetry/third_party/mox3/mox3/fixture.py
deleted file mode 100644
index f6e39d8..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/fixture.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# vim: tabstop=4 shiftwidth=4 softtabstop=4
-
-# Copyright 2013 Hewlett-Packard Development Company, L.P.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-import fixtures
-from mox3 import mox
-from mox3 import stubout
-
-
-class MoxStubout(fixtures.Fixture):
-    """Deal with code around mox and stubout as a fixture."""
-
-    def setUp(self):
-        super(MoxStubout, self).setUp()
-        self.mox = mox.Mox()
-        self.stubs = stubout.StubOutForTesting()
-        self.addCleanup(self.mox.UnsetStubs)
-        self.addCleanup(self.stubs.UnsetAll)
-        self.addCleanup(self.stubs.SmartUnsetAll)
-        self.addCleanup(self.mox.VerifyAll)
diff --git a/catapult/telemetry/third_party/mox3/mox3/mox.py b/catapult/telemetry/third_party/mox3/mox3/mox.py
deleted file mode 100644
index 3c10cc8..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/mox.py
+++ /dev/null
@@ -1,2168 +0,0 @@
-# Copyright 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This is a fork of the pymox library intended to work with Python 3.
-# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
-
-"""Mox, an object-mocking framework for Python.
-
-Mox works in the record-replay-verify paradigm.  When you first create
-a mock object, it is in record mode.  You then programmatically set
-the expected behavior of the mock object (what methods are to be
-called on it, with what parameters, what they should return, and in
-what order).
-
-Once you have set up the expected mock behavior, you put it in replay
-mode.  Now the mock responds to method calls just as you told it to.
-If an unexpected method (or an expected method with unexpected
-parameters) is called, then an exception will be raised.
-
-Once you are done interacting with the mock, you need to verify that
-all the expected interactions occured.  (Maybe your code exited
-prematurely without calling some cleanup method!)  The verify phase
-ensures that every expected method was called; otherwise, an exception
-will be raised.
-
-WARNING! Mock objects created by Mox are not thread-safe.  If you are
-call a mock in multiple threads, it should be guarded by a mutex.
-
-TODO(stevepm): Add the option to make mocks thread-safe!
-
-Suggested usage / workflow:
-
-    # Create Mox factory
-    my_mox = Mox()
-
-    # Create a mock data access object
-    mock_dao = my_mox.CreateMock(DAOClass)
-
-    # Set up expected behavior
-    mock_dao.RetrievePersonWithIdentifier('1').AndReturn(person)
-    mock_dao.DeletePerson(person)
-
-    # Put mocks in replay mode
-    my_mox.ReplayAll()
-
-    # Inject mock object and run test
-    controller.SetDao(mock_dao)
-    controller.DeletePersonById('1')
-
-    # Verify all methods were called as expected
-    my_mox.VerifyAll()
-"""
-
-import collections
-import difflib
-import inspect
-import re
-import types
-import unittest
-
-from mox3 import stubout
-
-
-class Error(AssertionError):
-    """Base exception for this module."""
-
-    pass
-
-
-class ExpectedMethodCallsError(Error):
-    """Raised when an expected method wasn't called.
-
-    This can occur if Verify() is called before all expected methods have been
-    called.
-    """
-
-    def __init__(self, expected_methods):
-        """Init exception.
-
-        Args:
-            # expected_methods: A sequence of MockMethod objects that should
-            #                   have been called.
-            expected_methods: [MockMethod]
-
-        Raises:
-            ValueError: if expected_methods contains no methods.
-        """
-
-        if not expected_methods:
-            raise ValueError("There must be at least one expected method")
-        Error.__init__(self)
-        self._expected_methods = expected_methods
-
-    def __str__(self):
-        calls = "\n".join(["%3d.  %s" % (i, m)
-                          for i, m in enumerate(self._expected_methods)])
-        return "Verify: Expected methods never called:\n%s" % (calls,)
-
-
-class UnexpectedMethodCallError(Error):
-    """Raised when an unexpected method is called.
-
-    This can occur if a method is called with incorrect parameters, or out of
-    the specified order.
-    """
-
-    def __init__(self, unexpected_method, expected):
-        """Init exception.
-
-        Args:
-            # unexpected_method: MockMethod that was called but was not at the
-            #     head of the expected_method queue.
-            # expected: MockMethod or UnorderedGroup the method should have
-            #     been in.
-            unexpected_method: MockMethod
-            expected: MockMethod or UnorderedGroup
-        """
-
-        Error.__init__(self)
-        if expected is None:
-            self._str = "Unexpected method call %s" % (unexpected_method,)
-        else:
-            differ = difflib.Differ()
-            diff = differ.compare(str(unexpected_method).splitlines(True),
-                                  str(expected).splitlines(True))
-            self._str = ("Unexpected method call."
-                         "  unexpected:-  expected:+\n%s"
-                         % ("\n".join(line.rstrip() for line in diff),))
-
-    def __str__(self):
-        return self._str
-
-
-class UnknownMethodCallError(Error):
-    """Raised if an unknown method is requested of the mock object."""
-
-    def __init__(self, unknown_method_name):
-        """Init exception.
-
-        Args:
-            # unknown_method_name: Method call that is not part of the mocked
-            #     class's public interface.
-            unknown_method_name: str
-        """
-
-        Error.__init__(self)
-        self._unknown_method_name = unknown_method_name
-
-    def __str__(self):
-        return ("Method called is not a member of the object: %s" %
-                self._unknown_method_name)
-
-
-class PrivateAttributeError(Error):
-    """Raised if a MockObject is passed a private additional attribute name."""
-
-    def __init__(self, attr):
-        Error.__init__(self)
-        self._attr = attr
-
-    def __str__(self):
-        return ("Attribute '%s' is private and should not be available"
-                "in a mock object." % self._attr)
-
-
-class ExpectedMockCreationError(Error):
-    """Raised if mocks should have been created by StubOutClassWithMocks."""
-
-    def __init__(self, expected_mocks):
-        """Init exception.
-
-        Args:
-            # expected_mocks: A sequence of MockObjects that should have been
-            #     created
-
-        Raises:
-            ValueError: if expected_mocks contains no methods.
-        """
-
-        if not expected_mocks:
-            raise ValueError("There must be at least one expected method")
-        Error.__init__(self)
-        self._expected_mocks = expected_mocks
-
-    def __str__(self):
-        mocks = "\n".join(["%3d.  %s" % (i, m)
-                          for i, m in enumerate(self._expected_mocks)])
-        return "Verify: Expected mocks never created:\n%s" % (mocks,)
-
-
-class UnexpectedMockCreationError(Error):
-    """Raised if too many mocks were created by StubOutClassWithMocks."""
-
-    def __init__(self, instance, *params, **named_params):
-        """Init exception.
-
-        Args:
-            # instance: the type of obejct that was created
-            # params: parameters given during instantiation
-            # named_params: named parameters given during instantiation
-        """
-
-        Error.__init__(self)
-        self._instance = instance
-        self._params = params
-        self._named_params = named_params
-
-    def __str__(self):
-        args = ", ".join(["%s" % v for i, v in enumerate(self._params)])
-        error = "Unexpected mock creation: %s(%s" % (self._instance, args)
-
-        if self._named_params:
-            error += ", " + ", ".join(["%s=%s" % (k, v) for k, v in
-                                      self._named_params.items()])
-
-        error += ")"
-        return error
-
-
-class Mox(object):
-    """Mox: a factory for creating mock objects."""
-
-    # A list of types that should be stubbed out with MockObjects (as
-    # opposed to MockAnythings).
-    _USE_MOCK_OBJECT = [types.FunctionType, types.ModuleType, types.MethodType]
-
-    def __init__(self):
-        """Initialize a new Mox."""
-
-        self._mock_objects = []
-        self.stubs = stubout.StubOutForTesting()
-
-    def CreateMock(self, class_to_mock, attrs=None, bounded_to=None):
-        """Create a new mock object.
-
-        Args:
-            # class_to_mock: the class to be mocked
-            class_to_mock: class
-            attrs: dict of attribute names to values that will be
-                   set on the mock object. Only public attributes may be set.
-            bounded_to: optionally, when class_to_mock is not a class,
-                        it points to a real class object, to which
-                        attribute is bound
-
-        Returns:
-            MockObject that can be used as the class_to_mock would be.
-        """
-        if attrs is None:
-            attrs = {}
-        new_mock = MockObject(class_to_mock, attrs=attrs,
-                              class_to_bind=bounded_to)
-        self._mock_objects.append(new_mock)
-        return new_mock
-
-    def CreateMockAnything(self, description=None):
-        """Create a mock that will accept any method calls.
-
-        This does not enforce an interface.
-
-        Args:
-        description: str. Optionally, a descriptive name for the mock object
-        being created, for debugging output purposes.
-        """
-        new_mock = MockAnything(description=description)
-        self._mock_objects.append(new_mock)
-        return new_mock
-
-    def ReplayAll(self):
-        """Set all mock objects to replay mode."""
-
-        for mock_obj in self._mock_objects:
-            mock_obj._Replay()
-
-    def VerifyAll(self):
-        """Call verify on all mock objects created."""
-
-        for mock_obj in self._mock_objects:
-            mock_obj._Verify()
-
-    def ResetAll(self):
-        """Call reset on all mock objects.    This does not unset stubs."""
-
-        for mock_obj in self._mock_objects:
-            mock_obj._Reset()
-
-    def StubOutWithMock(self, obj, attr_name, use_mock_anything=False):
-        """Replace a method, attribute, etc. with a Mock.
-
-        This will replace a class or module with a MockObject, and everything
-        else (method, function, etc) with a MockAnything. This can be
-        overridden to always use a MockAnything by setting use_mock_anything
-        to True.
-
-        Args:
-            obj: A Python object (class, module, instance, callable).
-            attr_name: str. The name of the attribute to replace with a mock.
-            use_mock_anything: bool. True if a MockAnything should be used
-                               regardless of the type of attribute.
-        """
-
-        if inspect.isclass(obj):
-            class_to_bind = obj
-        else:
-            class_to_bind = None
-
-        attr_to_replace = getattr(obj, attr_name)
-        attr_type = type(attr_to_replace)
-
-        if attr_type == MockAnything or attr_type == MockObject:
-            raise TypeError('Cannot mock a MockAnything! Did you remember to '
-                            'call UnsetStubs in your previous test?')
-
-        type_check = (
-            attr_type in self._USE_MOCK_OBJECT or
-            inspect.isclass(attr_to_replace) or
-            isinstance(attr_to_replace, object))
-        if type_check and not use_mock_anything:
-            stub = self.CreateMock(attr_to_replace, bounded_to=class_to_bind)
-        else:
-            stub = self.CreateMockAnything(
-                description='Stub for %s' % attr_to_replace)
-            stub.__name__ = attr_name
-
-        self.stubs.Set(obj, attr_name, stub)
-
-    def StubOutClassWithMocks(self, obj, attr_name):
-        """Replace a class with a "mock factory" that will create mock objects.
-
-        This is useful if the code-under-test directly instantiates
-        dependencies.    Previously some boilder plate was necessary to
-        create a mock that would act as a factory.    Using
-        StubOutClassWithMocks, once you've stubbed out the class you may
-        use the stubbed class as you would any other mock created by mox:
-        during the record phase, new mock instances will be created, and
-        during replay, the recorded mocks will be returned.
-
-        In replay mode
-
-        # Example using StubOutWithMock (the old, clunky way):
-
-        mock1 = mox.CreateMock(my_import.FooClass)
-        mock2 = mox.CreateMock(my_import.FooClass)
-        foo_factory = mox.StubOutWithMock(my_import, 'FooClass',
-                                          use_mock_anything=True)
-        foo_factory(1, 2).AndReturn(mock1)
-        foo_factory(9, 10).AndReturn(mock2)
-        mox.ReplayAll()
-
-        my_import.FooClass(1, 2)     # Returns mock1 again.
-        my_import.FooClass(9, 10)    # Returns mock2 again.
-        mox.VerifyAll()
-
-        # Example using StubOutClassWithMocks:
-
-        mox.StubOutClassWithMocks(my_import, 'FooClass')
-        mock1 = my_import.FooClass(1, 2)     # Returns a new mock of FooClass
-        mock2 = my_import.FooClass(9, 10)    # Returns another mock instance
-        mox.ReplayAll()
-
-        my_import.FooClass(1, 2)     # Returns mock1 again.
-        my_import.FooClass(9, 10)    # Returns mock2 again.
-        mox.VerifyAll()
-        """
-        attr_to_replace = getattr(obj, attr_name)
-        attr_type = type(attr_to_replace)
-
-        if attr_type == MockAnything or attr_type == MockObject:
-            raise TypeError('Cannot mock a MockAnything! Did you remember to '
-                            'call UnsetStubs in your previous test?')
-
-        if not inspect.isclass(attr_to_replace):
-            raise TypeError('Given attr is not a Class. Use StubOutWithMock.')
-
-        factory = _MockObjectFactory(attr_to_replace, self)
-        self._mock_objects.append(factory)
-        self.stubs.Set(obj, attr_name, factory)
-
-    def UnsetStubs(self):
-        """Restore stubs to their original state."""
-
-        self.stubs.UnsetAll()
-
-
-def Replay(*args):
-    """Put mocks into Replay mode.
-
-    Args:
-        # args is any number of mocks to put into replay mode.
-    """
-
-    for mock in args:
-        mock._Replay()
-
-
-def Verify(*args):
-    """Verify mocks.
-
-    Args:
-        # args is any number of mocks to be verified.
-    """
-
-    for mock in args:
-        mock._Verify()
-
-
-def Reset(*args):
-    """Reset mocks.
-
-    Args:
-        # args is any number of mocks to be reset.
-    """
-
-    for mock in args:
-        mock._Reset()
-
-
-class MockAnything(object):
-    """A mock that can be used to mock anything.
-
-    This is helpful for mocking classes that do not provide a public interface.
-    """
-
-    def __init__(self, description=None):
-        """Initialize a new MockAnything.
-
-        Args:
-            description: str. Optionally, a descriptive name for the mock
-                         object being created, for debugging output purposes.
-        """
-        self._description = description
-        self._Reset()
-
-    def __repr__(self):
-        if self._description:
-            return '<MockAnything instance of %s>' % self._description
-        else:
-            return '<MockAnything instance>'
-
-    def __getattr__(self, method_name):
-        """Intercept method calls on this object.
-
-         A new MockMethod is returned that is aware of the MockAnything's
-         state (record or replay).    The call will be recorded or replayed
-         by the MockMethod's __call__.
-
-        Args:
-            # method name: the name of the method being called.
-            method_name: str
-
-        Returns:
-            A new MockMethod aware of MockAnything's state (record or replay).
-        """
-        if method_name == '__dir__':
-                return self.__class__.__dir__.__get__(self, self.__class__)
-
-        return self._CreateMockMethod(method_name)
-
-    def __str__(self):
-        return self._CreateMockMethod('__str__')()
-
-    def __call__(self, *args, **kwargs):
-        return self._CreateMockMethod('__call__')(*args, **kwargs)
-
-    def __getitem__(self, i):
-        return self._CreateMockMethod('__getitem__')(i)
-
-    def _CreateMockMethod(self, method_name, method_to_mock=None,
-                          class_to_bind=object):
-        """Create a new mock method call and return it.
-
-        Args:
-            # method_name: the name of the method being called.
-            # method_to_mock: The actual method being mocked, used for
-            #                 introspection.
-            # class_to_bind: Class to which method is bounded
-            #                (object by default)
-            method_name: str
-            method_to_mock: a method object
-
-        Returns:
-            A new MockMethod aware of MockAnything's state (record or replay).
-        """
-
-        return MockMethod(method_name, self._expected_calls_queue,
-                          self._replay_mode, method_to_mock=method_to_mock,
-                          description=self._description,
-                          class_to_bind=class_to_bind)
-
-    def __nonzero__(self):
-        """Return 1 for nonzero so the mock can be used as a conditional."""
-
-        return 1
-
-    def __bool__(self):
-        """Return True for nonzero so the mock can be used as a conditional."""
-        return True
-
-    def __eq__(self, rhs):
-        """Provide custom logic to compare objects."""
-
-        return (isinstance(rhs, MockAnything) and
-                self._replay_mode == rhs._replay_mode and
-                self._expected_calls_queue == rhs._expected_calls_queue)
-
-    def __ne__(self, rhs):
-        """Provide custom logic to compare objects."""
-
-        return not self == rhs
-
-    def _Replay(self):
-        """Start replaying expected method calls."""
-
-        self._replay_mode = True
-
-    def _Verify(self):
-        """Verify that all of the expected calls have been made.
-
-        Raises:
-            ExpectedMethodCallsError: if there are still more method calls in
-                                      the expected queue.
-        """
-
-        # If the list of expected calls is not empty, raise an exception
-        if self._expected_calls_queue:
-            # The last MultipleTimesGroup is not popped from the queue.
-            if (len(self._expected_calls_queue) == 1 and
-                    isinstance(self._expected_calls_queue[0],
-                               MultipleTimesGroup) and
-                    self._expected_calls_queue[0].IsSatisfied()):
-                pass
-            else:
-                raise ExpectedMethodCallsError(self._expected_calls_queue)
-
-    def _Reset(self):
-        """Reset the state of this mock to record mode with an empty queue."""
-
-        # Maintain a list of method calls we are expecting
-        self._expected_calls_queue = collections.deque()
-
-        # Make sure we are in setup mode, not replay mode
-        self._replay_mode = False
-
-
-class MockObject(MockAnything):
-    """Mock object that simulates the public/protected interface of a class."""
-
-    def __init__(self, class_to_mock, attrs=None, class_to_bind=None):
-        """Initialize a mock object.
-
-        Determines the methods and properties of the class and stores them.
-
-        Args:
-            # class_to_mock: class to be mocked
-            class_to_mock: class
-            attrs: dict of attribute names to values that will be set on the
-                   mock object. Only public attributes may be set.
-            class_to_bind: optionally, when class_to_mock is not a class at
-                           all, it points to a real class
-
-        Raises:
-            PrivateAttributeError: if a supplied attribute is not public.
-            ValueError: if an attribute would mask an existing method.
-        """
-        if attrs is None:
-            attrs = {}
-
-        # Used to hack around the mixin/inheritance of MockAnything, which
-        # is not a proper object (it can be anything. :-)
-        MockAnything.__dict__['__init__'](self)
-
-        # Get a list of all the public and special methods we should mock.
-        self._known_methods = set()
-        self._known_vars = set()
-        self._class_to_mock = class_to_mock
-
-        if inspect.isclass(class_to_mock):
-            self._class_to_bind = self._class_to_mock
-        else:
-            self._class_to_bind = class_to_bind
-
-        try:
-            if inspect.isclass(self._class_to_mock):
-                self._description = class_to_mock.__name__
-            else:
-                self._description = type(class_to_mock).__name__
-        except Exception:
-            pass
-
-        for method in dir(class_to_mock):
-            attr = getattr(class_to_mock, method)
-            if callable(attr):
-                self._known_methods.add(method)
-            elif not (type(attr) is property):
-                # treating properties as class vars makes little sense.
-                self._known_vars.add(method)
-
-        # Set additional attributes at instantiation time; this is quicker
-        # than manually setting attributes that are normally created in
-        # __init__.
-        for attr, value in attrs.items():
-            if attr.startswith("_"):
-                raise PrivateAttributeError(attr)
-            elif attr in self._known_methods:
-                raise ValueError("'%s' is a method of '%s' objects." % (attr,
-                                 class_to_mock))
-            else:
-                setattr(self, attr, value)
-
-    def _CreateMockMethod(self, *args, **kwargs):
-        """Overridden to provide self._class_to_mock to class_to_bind."""
-        kwargs.setdefault("class_to_bind", self._class_to_bind)
-        return super(MockObject, self)._CreateMockMethod(*args, **kwargs)
-
-    def __getattr__(self, name):
-        """Intercept attribute request on this object.
-
-        If the attribute is a public class variable, it will be returned and
-        not recorded as a call.
-
-        If the attribute is not a variable, it is handled like a method
-        call. The method name is checked against the set of mockable
-        methods, and a new MockMethod is returned that is aware of the
-        MockObject's state (record or replay).    The call will be recorded
-        or replayed by the MockMethod's __call__.
-
-        Args:
-            # name: the name of the attribute being requested.
-            name: str
-
-        Returns:
-            Either a class variable or a new MockMethod that is aware of the
-            state of the mock (record or replay).
-
-        Raises:
-            UnknownMethodCallError if the MockObject does not mock the
-            requested method.
-        """
-
-        if name in self._known_vars:
-            return getattr(self._class_to_mock, name)
-
-        if name in self._known_methods:
-            return self._CreateMockMethod(
-                name,
-                method_to_mock=getattr(self._class_to_mock, name))
-
-        raise UnknownMethodCallError(name)
-
-    def __eq__(self, rhs):
-        """Provide custom logic to compare objects."""
-
-        return (isinstance(rhs, MockObject) and
-                self._class_to_mock == rhs._class_to_mock and
-                self._replay_mode == rhs._replay_mode and
-                self._expected_calls_queue == rhs._expected_calls_queue)
-
-    def __setitem__(self, key, value):
-        """Custom logic for mocking classes that support item assignment.
-
-        Args:
-            key: Key to set the value for.
-            value: Value to set.
-
-        Returns:
-            Expected return value in replay mode. A MockMethod object for the
-            __setitem__ method that has already been called if not in replay
-            mode.
-
-        Raises:
-            TypeError if the underlying class does not support item assignment.
-            UnexpectedMethodCallError if the object does not expect the call to
-                __setitem__.
-
-        """
-        # Verify the class supports item assignment.
-        if '__setitem__' not in dir(self._class_to_mock):
-            raise TypeError('object does not support item assignment')
-
-        # If we are in replay mode then simply call the mock __setitem__ method
-        if self._replay_mode:
-            return MockMethod('__setitem__', self._expected_calls_queue,
-                              self._replay_mode)(key, value)
-
-        # Otherwise, create a mock method __setitem__.
-        return self._CreateMockMethod('__setitem__')(key, value)
-
-    def __getitem__(self, key):
-        """Provide custom logic for mocking classes that are subscriptable.
-
-        Args:
-            key: Key to return the value for.
-
-        Returns:
-            Expected return value in replay mode. A MockMethod object for the
-            __getitem__ method that has already been called if not in replay
-            mode.
-
-        Raises:
-            TypeError if the underlying class is not subscriptable.
-            UnexpectedMethodCallError if the object does not expect the call to
-                __getitem__.
-
-        """
-        # Verify the class supports item assignment.
-        if '__getitem__' not in dir(self._class_to_mock):
-            raise TypeError('unsubscriptable object')
-
-        # If we are in replay mode then simply call the mock __getitem__ method
-        if self._replay_mode:
-            return MockMethod('__getitem__', self._expected_calls_queue,
-                              self._replay_mode)(key)
-
-        # Otherwise, create a mock method __getitem__.
-        return self._CreateMockMethod('__getitem__')(key)
-
-    def __iter__(self):
-        """Provide custom logic for mocking classes that are iterable.
-
-        Returns:
-            Expected return value in replay mode. A MockMethod object for the
-            __iter__ method that has already been called if not in replay mode.
-
-        Raises:
-            TypeError if the underlying class is not iterable.
-            UnexpectedMethodCallError if the object does not expect the call to
-                __iter__.
-
-        """
-        methods = dir(self._class_to_mock)
-
-        # Verify the class supports iteration.
-        if '__iter__' not in methods:
-            # If it doesn't have iter method and we are in replay method,
-            # then try to iterate using subscripts.
-            if '__getitem__' not in methods or not self._replay_mode:
-                raise TypeError('not iterable object')
-            else:
-                results = []
-                index = 0
-                try:
-                    while True:
-                        results.append(self[index])
-                        index += 1
-                except IndexError:
-                    return iter(results)
-
-        # If we are in replay mode then simply call the mock __iter__ method.
-        if self._replay_mode:
-            return MockMethod('__iter__', self._expected_calls_queue,
-                              self._replay_mode)()
-
-        # Otherwise, create a mock method __iter__.
-        return self._CreateMockMethod('__iter__')()
-
-    def __contains__(self, key):
-        """Provide custom logic for mocking classes that contain items.
-
-        Args:
-            key: Key to look in container for.
-
-        Returns:
-            Expected return value in replay mode. A MockMethod object for the
-            __contains__ method that has already been called if not in replay
-            mode.
-
-        Raises:
-            TypeError if the underlying class does not implement __contains__
-            UnexpectedMethodCaller if the object does not expect the call to
-            __contains__.
-
-        """
-        contains = self._class_to_mock.__dict__.get('__contains__', None)
-
-        if contains is None:
-            raise TypeError('unsubscriptable object')
-
-        if self._replay_mode:
-            return MockMethod('__contains__', self._expected_calls_queue,
-                              self._replay_mode)(key)
-
-        return self._CreateMockMethod('__contains__')(key)
-
-    def __call__(self, *params, **named_params):
-        """Provide custom logic for mocking classes that are callable."""
-
-        # Verify the class we are mocking is callable.
-        is_callable = hasattr(self._class_to_mock, '__call__')
-        if not is_callable:
-            raise TypeError('Not callable')
-
-        # Because the call is happening directly on this object instead of
-        # a method, the call on the mock method is made right here
-
-        # If we are mocking a Function, then use the function, and not the
-        # __call__ method
-        method = None
-        if type(self._class_to_mock) in (types.FunctionType, types.MethodType):
-            method = self._class_to_mock
-        else:
-            method = getattr(self._class_to_mock, '__call__')
-        mock_method = self._CreateMockMethod('__call__', method_to_mock=method)
-
-        return mock_method(*params, **named_params)
-
-    @property
-    def __name__(self):
-        """Return the name that is being mocked."""
-        return self._description
-
-    # TODO(dejw): this property stopped to work after I introduced changes with
-    #     binding classes. Fortunately I found a solution in the form of
-    #     __getattribute__ method below, but this issue should be investigated
-    @property
-    def __class__(self):
-        return self._class_to_mock
-
-    def __dir__(self):
-        """Return only attributes of a class to mock."""
-        return dir(self._class_to_mock)
-
-    def __getattribute__(self, name):
-        """Return _class_to_mock on __class__ attribute."""
-        if name == "__class__":
-            return super(MockObject, self).__getattribute__("_class_to_mock")
-
-        return super(MockObject, self).__getattribute__(name)
-
-
-class _MockObjectFactory(MockObject):
-    """A MockObjectFactory creates mocks and verifies __init__ params.
-
-    A MockObjectFactory removes the boiler plate code that was previously
-    necessary to stub out direction instantiation of a class.
-
-    The MockObjectFactory creates new MockObjects when called and verifies the
-    __init__ params are correct when in record mode.    When replaying,
-    existing mocks are returned, and the __init__ params are verified.
-
-    See StubOutWithMock vs StubOutClassWithMocks for more detail.
-    """
-
-    def __init__(self, class_to_mock, mox_instance):
-        MockObject.__init__(self, class_to_mock)
-        self._mox = mox_instance
-        self._instance_queue = collections.deque()
-
-    def __call__(self, *params, **named_params):
-        """Instantiate and record that a new mock has been created."""
-
-        method = getattr(self._class_to_mock, '__init__')
-        mock_method = self._CreateMockMethod('__init__', method_to_mock=method)
-        # Note: calling mock_method() is deferred in order to catch the
-        # empty instance_queue first.
-
-        if self._replay_mode:
-            if not self._instance_queue:
-                raise UnexpectedMockCreationError(self._class_to_mock, *params,
-                                                  **named_params)
-
-            mock_method(*params, **named_params)
-
-            return self._instance_queue.pop()
-        else:
-            mock_method(*params, **named_params)
-
-            instance = self._mox.CreateMock(self._class_to_mock)
-            self._instance_queue.appendleft(instance)
-            return instance
-
-    def _Verify(self):
-        """Verify that all mocks have been created."""
-        if self._instance_queue:
-            raise ExpectedMockCreationError(self._instance_queue)
-        super(_MockObjectFactory, self)._Verify()
-
-
-class MethodSignatureChecker(object):
-    """Ensures that methods are called correctly."""
-
-    _NEEDED, _DEFAULT, _GIVEN = range(3)
-
-    def __init__(self, method, class_to_bind=None):
-        """Creates a checker.
-
-        Args:
-            # method: A method to check.
-            # class_to_bind: optionally, a class used to type check first
-            #                method parameter, only used with unbound methods
-            method: function
-            class_to_bind: type or None
-
-        Raises:
-            ValueError: method could not be inspected, so checks aren't
-                        possible. Some methods and functions like built-ins
-                        can't be inspected.
-        """
-        try:
-            self._args, varargs, varkw, defaults = inspect.getargspec(method)
-        except TypeError:
-            raise ValueError('Could not get argument specification for %r'
-                             % (method,))
-        if inspect.ismethod(method) or class_to_bind:
-            self._args = self._args[1:]    # Skip 'self'.
-        self._method = method
-        self._instance = None    # May contain the instance this is bound to.
-        self._instance = getattr(method, "__self__", None)
-
-        # _bounded_to determines whether the method is bound or not
-        if self._instance:
-            self._bounded_to = self._instance.__class__
-        else:
-            self._bounded_to = class_to_bind or getattr(method, "im_class",
-                                                        None)
-
-        self._has_varargs = varargs is not None
-        self._has_varkw = varkw is not None
-        if defaults is None:
-            self._required_args = self._args
-            self._default_args = []
-        else:
-            self._required_args = self._args[:-len(defaults)]
-            self._default_args = self._args[-len(defaults):]
-
-    def _RecordArgumentGiven(self, arg_name, arg_status):
-        """Mark an argument as being given.
-
-        Args:
-            # arg_name: The name of the argument to mark in arg_status.
-            # arg_status: Maps argument names to one of
-            #             _NEEDED, _DEFAULT, _GIVEN.
-            arg_name: string
-            arg_status: dict
-
-        Raises:
-            AttributeError: arg_name is already marked as _GIVEN.
-        """
-        if arg_status.get(arg_name, None) == MethodSignatureChecker._GIVEN:
-            raise AttributeError('%s provided more than once' % (arg_name,))
-        arg_status[arg_name] = MethodSignatureChecker._GIVEN
-
-    def Check(self, params, named_params):
-        """Ensures that the parameters used while recording a call are valid.
-
-        Args:
-            # params: A list of positional parameters.
-            # named_params: A dict of named parameters.
-            params: list
-            named_params: dict
-
-        Raises:
-            AttributeError: the given parameters don't work with the given
-                            method.
-        """
-        arg_status = dict((a, MethodSignatureChecker._NEEDED)
-                          for a in self._required_args)
-        for arg in self._default_args:
-            arg_status[arg] = MethodSignatureChecker._DEFAULT
-
-        # WARNING: Suspect hack ahead.
-        #
-        # Check to see if this is an unbound method, where the instance
-        # should be bound as the first argument.    We try to determine if
-        # the first argument (param[0]) is an instance of the class, or it
-        # is equivalent to the class (used to account for Comparators).
-        #
-        # NOTE: If a Func() comparator is used, and the signature is not
-        # correct, this will cause extra executions of the function.
-        if inspect.ismethod(self._method) or self._bounded_to:
-            # The extra param accounts for the bound instance.
-            if len(params) > len(self._required_args):
-                expected = self._bounded_to
-
-                # Check if the param is an instance of the expected class,
-                # or check equality (useful for checking Comparators).
-
-                # This is a hack to work around the fact that the first
-                # parameter can be a Comparator, and the comparison may raise
-                # an exception during this comparison, which is OK.
-                try:
-                    param_equality = (params[0] == expected)
-                except Exception:
-                    param_equality = False
-
-                if isinstance(params[0], expected) or param_equality:
-                    params = params[1:]
-                # If the IsA() comparator is being used, we need to check the
-                # inverse of the usual case - that the given instance is a
-                # subclass of the expected class. For example, the code under
-                # test does late binding to a subclass.
-                elif (isinstance(params[0], IsA) and
-                      params[0]._IsSubClass(expected)):
-                    params = params[1:]
-
-        # Check that each positional param is valid.
-        for i in range(len(params)):
-            try:
-                arg_name = self._args[i]
-            except IndexError:
-                if not self._has_varargs:
-                    raise AttributeError(
-                        '%s does not take %d or more positional '
-                        'arguments' % (self._method.__name__, i))
-            else:
-                self._RecordArgumentGiven(arg_name, arg_status)
-
-        # Check each keyword argument.
-        for arg_name in named_params:
-            if arg_name not in arg_status and not self._has_varkw:
-                raise AttributeError('%s is not expecting keyword argument %s'
-                                     % (self._method.__name__, arg_name))
-            self._RecordArgumentGiven(arg_name, arg_status)
-
-        # Ensure all the required arguments have been given.
-        still_needed = [k for k, v in arg_status.items()
-                        if v == MethodSignatureChecker._NEEDED]
-        if still_needed:
-            raise AttributeError('No values given for arguments: %s'
-                                 % (' '.join(sorted(still_needed))))
-
-
-class MockMethod(object):
-    """Callable mock method.
-
-    A MockMethod should act exactly like the method it mocks, accepting
-    parameters and returning a value, or throwing an exception (as specified).
-    When this method is called, it can optionally verify whether the called
-    method (name and signature) matches the expected method.
-    """
-
-    def __init__(self, method_name, call_queue, replay_mode,
-                 method_to_mock=None, description=None, class_to_bind=None):
-        """Construct a new mock method.
-
-        Args:
-            # method_name: the name of the method
-            # call_queue: deque of calls, verify this call against the head,
-            #             or add this call to the queue.
-            # replay_mode: False if we are recording, True if we are verifying
-            #              calls against the call queue.
-            # method_to_mock: The actual method being mocked, used for
-            #                 introspection.
-            # description: optionally, a descriptive name for this method.
-            #              Typically this is equal to the descriptive name of
-            #              the method's class.
-            # class_to_bind: optionally, a class that is used for unbound
-            #                methods (or functions in Python3) to which method
-            #                is bound, in order not to loose binding
-            #                information. If given, it will be used for
-            #                checking the type of first method parameter
-            method_name: str
-            call_queue: list or deque
-            replay_mode: bool
-            method_to_mock: a method object
-            description: str or None
-            class_to_bind: type or None
-        """
-
-        self._name = method_name
-        self.__name__ = method_name
-        self._call_queue = call_queue
-        if not isinstance(call_queue, collections.deque):
-            self._call_queue = collections.deque(self._call_queue)
-        self._replay_mode = replay_mode
-        self._description = description
-
-        self._params = None
-        self._named_params = None
-        self._return_value = None
-        self._exception = None
-        self._side_effects = None
-
-        try:
-            self._checker = MethodSignatureChecker(method_to_mock,
-                                                   class_to_bind=class_to_bind)
-        except ValueError:
-            self._checker = None
-
-    def __call__(self, *params, **named_params):
-        """Log parameters and return the specified return value.
-
-        If the Mock(Anything/Object) associated with this call is in record
-        mode, this MockMethod will be pushed onto the expected call queue.
-        If the mock is in replay mode, this will pop a MockMethod off the
-        top of the queue and verify this call is equal to the expected call.
-
-        Raises:
-            UnexpectedMethodCall if this call is supposed to match an expected
-                method call and it does not.
-        """
-
-        self._params = params
-        self._named_params = named_params
-
-        if not self._replay_mode:
-            if self._checker is not None:
-                self._checker.Check(params, named_params)
-            self._call_queue.append(self)
-            return self
-
-        expected_method = self._VerifyMethodCall()
-
-        if expected_method._side_effects:
-            result = expected_method._side_effects(*params, **named_params)
-            if expected_method._return_value is None:
-                expected_method._return_value = result
-
-        if expected_method._exception:
-            raise expected_method._exception
-
-        return expected_method._return_value
-
-    def __getattr__(self, name):
-        """Raise an AttributeError with a helpful message."""
-
-        raise AttributeError(
-            'MockMethod has no attribute "%s". '
-            'Did you remember to put your mocks in replay mode?' % name)
-
-    def __iter__(self):
-        """Raise a TypeError with a helpful message."""
-        raise TypeError(
-            'MockMethod cannot be iterated. '
-            'Did you remember to put your mocks in replay mode?')
-
-    def next(self):
-        """Raise a TypeError with a helpful message."""
-        raise TypeError(
-            'MockMethod cannot be iterated. '
-            'Did you remember to put your mocks in replay mode?')
-
-    def __next__(self):
-        """Raise a TypeError with a helpful message."""
-        raise TypeError(
-            'MockMethod cannot be iterated. '
-            'Did you remember to put your mocks in replay mode?')
-
-    def _PopNextMethod(self):
-        """Pop the next method from our call queue."""
-        try:
-            return self._call_queue.popleft()
-        except IndexError:
-            raise UnexpectedMethodCallError(self, None)
-
-    def _VerifyMethodCall(self):
-        """Verify the called method is expected.
-
-        This can be an ordered method, or part of an unordered set.
-
-        Returns:
-            The expected mock method.
-
-        Raises:
-            UnexpectedMethodCall if the method called was not expected.
-        """
-
-        expected = self._PopNextMethod()
-
-        # Loop here, because we might have a MethodGroup followed by another
-        # group.
-        while isinstance(expected, MethodGroup):
-            expected, method = expected.MethodCalled(self)
-            if method is not None:
-                return method
-
-        # This is a mock method, so just check equality.
-        if expected != self:
-            raise UnexpectedMethodCallError(self, expected)
-
-        return expected
-
-    def __str__(self):
-        params = ', '.join(
-            [repr(p) for p in self._params or []] +
-            ['%s=%r' % x for x in sorted((self._named_params or {}).items())])
-        full_desc = "%s(%s) -> %r" % (self._name, params, self._return_value)
-        if self._description:
-            full_desc = "%s.%s" % (self._description, full_desc)
-        return full_desc
-
-    def __hash__(self):
-        return id(self)
-
-    def __eq__(self, rhs):
-        """Test whether this MockMethod is equivalent to another MockMethod.
-
-        Args:
-            # rhs: the right hand side of the test
-            rhs: MockMethod
-        """
-
-        return (isinstance(rhs, MockMethod) and
-                self._name == rhs._name and
-                self._params == rhs._params and
-                self._named_params == rhs._named_params)
-
-    def __ne__(self, rhs):
-        """Test if this MockMethod is not equivalent to another MockMethod.
-
-        Args:
-            # rhs: the right hand side of the test
-            rhs: MockMethod
-        """
-
-        return not self == rhs
-
-    def GetPossibleGroup(self):
-        """Returns a possible group from the end of the call queue.
-
-        Return None if no other methods are on the stack.
-        """
-
-        # Remove this method from the tail of the queue so we can add it
-        # to a group.
-        this_method = self._call_queue.pop()
-        assert this_method == self
-
-        # Determine if the tail of the queue is a group, or just a regular
-        # ordered mock method.
-        group = None
-        try:
-            group = self._call_queue[-1]
-        except IndexError:
-            pass
-
-        return group
-
-    def _CheckAndCreateNewGroup(self, group_name, group_class):
-        """Checks if the last method (a possible group) is an instance of our
-        group_class. Adds the current method to this group or creates a
-        new one.
-
-        Args:
-
-            group_name: the name of the group.
-            group_class: the class used to create instance of this new group
-        """
-        group = self.GetPossibleGroup()
-
-        # If this is a group, and it is the correct group, add the method.
-        if isinstance(group, group_class) and group.group_name() == group_name:
-            group.AddMethod(self)
-            return self
-
-        # Create a new group and add the method.
-        new_group = group_class(group_name)
-        new_group.AddMethod(self)
-        self._call_queue.append(new_group)
-        return self
-
-    def InAnyOrder(self, group_name="default"):
-        """Move this method into a group of unordered calls.
-
-        A group of unordered calls must be defined together, and must be
-        executed in full before the next expected method can be called.
-        There can be multiple groups that are expected serially, if they are
-        given different group names. The same group name can be reused if there
-        is a standard method call, or a group with a different name, spliced
-        between usages.
-
-        Args:
-            group_name: the name of the unordered group.
-
-        Returns:
-            self
-        """
-        return self._CheckAndCreateNewGroup(group_name, UnorderedGroup)
-
-    def MultipleTimes(self, group_name="default"):
-        """Move method into group of calls which may be called multiple times.
-
-        A group of repeating calls must be defined together, and must be
-        executed in full before the next expected method can be called.
-
-        Args:
-            group_name: the name of the unordered group.
-
-        Returns:
-            self
-        """
-        return self._CheckAndCreateNewGroup(group_name, MultipleTimesGroup)
-
-    def AndReturn(self, return_value):
-        """Set the value to return when this method is called.
-
-        Args:
-            # return_value can be anything.
-        """
-
-        self._return_value = return_value
-        return return_value
-
-    def AndRaise(self, exception):
-        """Set the exception to raise when this method is called.
-
-        Args:
-            # exception: the exception to raise when this method is called.
-            exception: Exception
-        """
-
-        self._exception = exception
-
-    def WithSideEffects(self, side_effects):
-        """Set the side effects that are simulated when this method is called.
-
-        Args:
-            side_effects: A callable which modifies the parameters or other
-                          relevant state which a given test case depends on.
-
-        Returns:
-            Self for chaining with AndReturn and AndRaise.
-        """
-        self._side_effects = side_effects
-        return self
-
-
-class Comparator:
-    """Base class for all Mox comparators.
-
-    A Comparator can be used as a parameter to a mocked method when the exact
-    value is not known.    For example, the code you are testing might build up
-    a long SQL string that is passed to your mock DAO. You're only interested
-    that the IN clause contains the proper primary keys, so you can set your
-    mock up as follows:
-
-    mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result)
-
-    Now whatever query is passed in must contain the string 'IN (1, 2, 4, 5)'.
-
-    A Comparator may replace one or more parameters, for example:
-    # return at most 10 rows
-    mock_dao.RunQuery(StrContains('SELECT'), 10)
-
-    or
-
-    # Return some non-deterministic number of rows
-    mock_dao.RunQuery(StrContains('SELECT'), IsA(int))
-    """
-
-    def equals(self, rhs):
-        """Special equals method that all comparators must implement.
-
-        Args:
-            rhs: any python object
-        """
-
-        raise NotImplementedError('method must be implemented by a subclass.')
-
-    def __eq__(self, rhs):
-        return self.equals(rhs)
-
-    def __ne__(self, rhs):
-        return not self.equals(rhs)
-
-
-class Is(Comparator):
-    """Comparison class used to check identity, instead of equality."""
-
-    def __init__(self, obj):
-        self._obj = obj
-
-    def equals(self, rhs):
-        return rhs is self._obj
-
-    def __repr__(self):
-        return "<is %r (%s)>" % (self._obj, id(self._obj))
-
-
-class IsA(Comparator):
-    """This class wraps a basic Python type or class.    It is used to verify
-    that a parameter is of the given type or class.
-
-    Example:
-    mock_dao.Connect(IsA(DbConnectInfo))
-    """
-
-    def __init__(self, class_name):
-        """Initialize IsA
-
-        Args:
-            class_name: basic python type or a class
-        """
-
-        self._class_name = class_name
-
-    def equals(self, rhs):
-        """Check to see if the RHS is an instance of class_name.
-
-        Args:
-            # rhs: the right hand side of the test
-            rhs: object
-
-        Returns:
-            bool
-        """
-
-        try:
-            return isinstance(rhs, self._class_name)
-        except TypeError:
-            # Check raw types if there was a type error.    This is helpful for
-            # things like cStringIO.StringIO.
-            return type(rhs) == type(self._class_name)
-
-    def _IsSubClass(self, clazz):
-        """Check to see if the IsA comparators class is a subclass of clazz.
-
-        Args:
-            # clazz: a class object
-
-        Returns:
-            bool
-        """
-
-        try:
-            return issubclass(self._class_name, clazz)
-        except TypeError:
-            # Check raw types if there was a type error.    This is helpful for
-            # things like cStringIO.StringIO.
-            return type(clazz) == type(self._class_name)
-
-    def __repr__(self):
-        return 'mox.IsA(%s) ' % str(self._class_name)
-
-
-class IsAlmost(Comparator):
-    """Comparison class used to check whether a parameter is nearly equal
-    to a given value.    Generally useful for floating point numbers.
-
-    Example mock_dao.SetTimeout((IsAlmost(3.9)))
-    """
-
-    def __init__(self, float_value, places=7):
-        """Initialize IsAlmost.
-
-        Args:
-            float_value: The value for making the comparison.
-            places: The number of decimal places to round to.
-        """
-
-        self._float_value = float_value
-        self._places = places
-
-    def equals(self, rhs):
-        """Check to see if RHS is almost equal to float_value
-
-        Args:
-            rhs: the value to compare to float_value
-
-        Returns:
-            bool
-        """
-
-        try:
-            return round(rhs - self._float_value, self._places) == 0
-        except Exception:
-            # Probably because either float_value or rhs is not a number.
-            return False
-
-    def __repr__(self):
-        return str(self._float_value)
-
-
-class StrContains(Comparator):
-    """Comparison class used to check whether a substring exists in a
-    string parameter.    This can be useful in mocking a database with SQL
-    passed in as a string parameter, for example.
-
-    Example:
-    mock_dao.RunQuery(StrContains('IN (1, 2, 4, 5)')).AndReturn(mock_result)
-    """
-
-    def __init__(self, search_string):
-        """Initialize.
-
-        Args:
-            # search_string: the string you are searching for
-            search_string: str
-        """
-
-        self._search_string = search_string
-
-    def equals(self, rhs):
-        """Check to see if the search_string is contained in the rhs string.
-
-        Args:
-            # rhs: the right hand side of the test
-            rhs: object
-
-        Returns:
-            bool
-        """
-
-        try:
-            return rhs.find(self._search_string) > -1
-        except Exception:
-            return False
-
-    def __repr__(self):
-        return '<str containing \'%s\'>' % self._search_string
-
-
-class Regex(Comparator):
-    """Checks if a string matches a regular expression.
-
-    This uses a given regular expression to determine equality.
-    """
-
-    def __init__(self, pattern, flags=0):
-        """Initialize.
-
-        Args:
-            # pattern is the regular expression to search for
-            pattern: str
-            # flags passed to re.compile function as the second argument
-            flags: int
-        """
-        self.flags = flags
-        self.regex = re.compile(pattern, flags=flags)
-
-    def equals(self, rhs):
-        """Check to see if rhs matches regular expression pattern.
-
-        Returns:
-            bool
-        """
-
-        try:
-            return self.regex.search(rhs) is not None
-        except Exception:
-            return False
-
-    def __repr__(self):
-        s = '<regular expression \'%s\'' % self.regex.pattern
-        if self.flags:
-            s += ', flags=%d' % self.flags
-        s += '>'
-        return s
-
-
-class In(Comparator):
-    """Checks whether an item (or key) is in a list (or dict) parameter.
-
-    Example:
-    mock_dao.GetUsersInfo(In('expectedUserName')).AndReturn(mock_result)
-    """
-
-    def __init__(self, key):
-        """Initialize.
-
-        Args:
-            # key is any thing that could be in a list or a key in a dict
-        """
-
-        self._key = key
-
-    def equals(self, rhs):
-        """Check to see whether key is in rhs.
-
-        Args:
-            rhs: dict
-
-        Returns:
-            bool
-        """
-
-        try:
-            return self._key in rhs
-        except Exception:
-            return False
-
-    def __repr__(self):
-        return '<sequence or map containing \'%s\'>' % str(self._key)
-
-
-class Not(Comparator):
-    """Checks whether a predicates is False.
-
-    Example:
-        mock_dao.UpdateUsers(Not(ContainsKeyValue('stevepm',
-                                                  stevepm_user_info)))
-    """
-
-    def __init__(self, predicate):
-        """Initialize.
-
-        Args:
-            # predicate: a Comparator instance.
-        """
-
-        assert isinstance(predicate, Comparator), ("predicate %r must be a"
-                                                   " Comparator." % predicate)
-        self._predicate = predicate
-
-    def equals(self, rhs):
-        """Check to see whether the predicate is False.
-
-        Args:
-            rhs: A value that will be given in argument of the predicate.
-
-        Returns:
-            bool
-        """
-
-        try:
-            return not self._predicate.equals(rhs)
-        except Exception:
-            return False
-
-    def __repr__(self):
-        return '<not \'%s\'>' % self._predicate
-
-
-class ContainsKeyValue(Comparator):
-    """Checks whether a key/value pair is in a dict parameter.
-
-    Example:
-    mock_dao.UpdateUsers(ContainsKeyValue('stevepm', stevepm_user_info))
-    """
-
-    def __init__(self, key, value):
-        """Initialize.
-
-        Args:
-            # key: a key in a dict
-            # value: the corresponding value
-        """
-
-        self._key = key
-        self._value = value
-
-    def equals(self, rhs):
-        """Check whether the given key/value pair is in the rhs dict.
-
-        Returns:
-            bool
-        """
-
-        try:
-            return rhs[self._key] == self._value
-        except Exception:
-            return False
-
-    def __repr__(self):
-        return '<map containing the entry \'%s: %s\'>' % (str(self._key),
-                                                          str(self._value))
-
-
-class ContainsAttributeValue(Comparator):
-    """Checks whether passed parameter contains attributes with a given value.
-
-    Example:
-    mock_dao.UpdateSomething(ContainsAttribute('stevepm', stevepm_user_info))
-    """
-
-    def __init__(self, key, value):
-        """Initialize.
-
-        Args:
-            # key: an attribute name of an object
-            # value: the corresponding value
-        """
-
-        self._key = key
-        self._value = value
-
-    def equals(self, rhs):
-        """Check if the given attribute has a matching value in the rhs object.
-
-        Returns:
-            bool
-        """
-
-        try:
-            return getattr(rhs, self._key) == self._value
-        except Exception:
-            return False
-
-
-class SameElementsAs(Comparator):
-    """Checks whether sequences contain the same elements (ignoring order).
-
-    Example:
-    mock_dao.ProcessUsers(SameElementsAs('stevepm', 'salomaki'))
-    """
-
-    def __init__(self, expected_seq):
-        """Initialize.
-
-        Args:
-            expected_seq: a sequence
-        """
-        # Store in case expected_seq is an iterator.
-        self._expected_list = list(expected_seq)
-
-    def equals(self, actual_seq):
-        """Check to see whether actual_seq has same elements as expected_seq.
-
-        Args:
-            actual_seq: sequence
-
-        Returns:
-            bool
-        """
-        try:
-            # Store in case actual_seq is an iterator. We potentially iterate
-            # twice: once to make the dict, once in the list fallback.
-            actual_list = list(actual_seq)
-        except TypeError:
-            # actual_seq cannot be read as a sequence.
-            #
-            # This happens because Mox uses __eq__ both to check object
-            # equality (in MethodSignatureChecker) and to invoke Comparators.
-            return False
-
-        try:
-            return set(self._expected_list) == set(actual_list)
-        except TypeError:
-            # Fall back to slower list-compare if any of the objects
-            # are unhashable.
-            if len(self._expected_list) != len(actual_list):
-                return False
-            for el in actual_list:
-                if el not in self._expected_list:
-                    return False
-        return True
-
-    def __repr__(self):
-        return '<sequence with same elements as \'%s\'>' % self._expected_list
-
-
-class And(Comparator):
-    """Evaluates one or more Comparators on RHS, returns an AND of the results.
-    """
-
-    def __init__(self, *args):
-        """Initialize.
-
-        Args:
-            *args: One or more Comparator
-        """
-
-        self._comparators = args
-
-    def equals(self, rhs):
-        """Checks whether all Comparators are equal to rhs.
-
-        Args:
-            # rhs: can be anything
-
-        Returns:
-            bool
-        """
-
-        for comparator in self._comparators:
-            if not comparator.equals(rhs):
-                return False
-
-        return True
-
-    def __repr__(self):
-        return '<AND %s>' % str(self._comparators)
-
-
-class Or(Comparator):
-    """Evaluates one or more Comparators on RHS; returns OR of the results."""
-
-    def __init__(self, *args):
-        """Initialize.
-
-        Args:
-            *args: One or more Mox comparators
-        """
-
-        self._comparators = args
-
-    def equals(self, rhs):
-        """Checks whether any Comparator is equal to rhs.
-
-        Args:
-            # rhs: can be anything
-
-        Returns:
-            bool
-        """
-
-        for comparator in self._comparators:
-            if comparator.equals(rhs):
-                return True
-
-        return False
-
-    def __repr__(self):
-        return '<OR %s>' % str(self._comparators)
-
-
-class Func(Comparator):
-    """Call a function that should verify the parameter passed in is correct.
-
-    You may need the ability to perform more advanced operations on the
-    parameter in order to validate it. You can use this to have a callable
-    validate any parameter. The callable should return either True or False.
-
-
-    Example:
-
-    def myParamValidator(param):
-        # Advanced logic here
-        return True
-
-    mock_dao.DoSomething(Func(myParamValidator), true)
-    """
-
-    def __init__(self, func):
-        """Initialize.
-
-        Args:
-            func: callable that takes one parameter and returns a bool
-        """
-
-        self._func = func
-
-    def equals(self, rhs):
-        """Test whether rhs passes the function test.
-
-        rhs is passed into func.
-
-        Args:
-            rhs: any python object
-
-        Returns:
-            the result of func(rhs)
-        """
-
-        return self._func(rhs)
-
-    def __repr__(self):
-        return str(self._func)
-
-
-class IgnoreArg(Comparator):
-    """Ignore an argument.
-
-    This can be used when we don't care about an argument of a method call.
-
-    Example:
-    # Check if CastMagic is called with 3 as first arg and
-    # 'disappear' as third.
-    mymock.CastMagic(3, IgnoreArg(), 'disappear')
-    """
-
-    def equals(self, unused_rhs):
-        """Ignores arguments and returns True.
-
-        Args:
-            unused_rhs: any python object
-
-        Returns:
-            always returns True
-        """
-
-        return True
-
-    def __repr__(self):
-        return '<IgnoreArg>'
-
-
-class Value(Comparator):
-    """Compares argument against a remembered value.
-
-    To be used in conjunction with Remember comparator.    See Remember()
-    for example.
-    """
-
-    def __init__(self):
-        self._value = None
-        self._has_value = False
-
-    def store_value(self, rhs):
-        self._value = rhs
-        self._has_value = True
-
-    def equals(self, rhs):
-        if not self._has_value:
-            return False
-        else:
-            return rhs == self._value
-
-    def __repr__(self):
-        if self._has_value:
-            return "<Value %r>" % self._value
-        else:
-            return "<Value>"
-
-
-class Remember(Comparator):
-    """Remembers the argument to a value store.
-
-    To be used in conjunction with Value comparator.
-
-    Example:
-    # Remember the argument for one method call.
-    users_list = Value()
-    mock_dao.ProcessUsers(Remember(users_list))
-
-    # Check argument against remembered value.
-    mock_dao.ReportUsers(users_list)
-    """
-
-    def __init__(self, value_store):
-        if not isinstance(value_store, Value):
-            raise TypeError(
-                "value_store is not an instance of the Value class")
-        self._value_store = value_store
-
-    def equals(self, rhs):
-        self._value_store.store_value(rhs)
-        return True
-
-    def __repr__(self):
-        return "<Remember %d>" % id(self._value_store)
-
-
-class MethodGroup(object):
-    """Base class containing common behaviour for MethodGroups."""
-
-    def __init__(self, group_name):
-        self._group_name = group_name
-
-    def group_name(self):
-        return self._group_name
-
-    def __str__(self):
-        return '<%s "%s">' % (self.__class__.__name__, self._group_name)
-
-    def AddMethod(self, mock_method):
-        raise NotImplementedError
-
-    def MethodCalled(self, mock_method):
-        raise NotImplementedError
-
-    def IsSatisfied(self):
-        raise NotImplementedError
-
-
-class UnorderedGroup(MethodGroup):
-    """UnorderedGroup holds a set of method calls that may occur in any order.
-
-    This construct is helpful for non-deterministic events, such as iterating
-    over the keys of a dict.
-    """
-
-    def __init__(self, group_name):
-        super(UnorderedGroup, self).__init__(group_name)
-        self._methods = []
-
-    def __str__(self):
-        return '%s "%s" pending calls:\n%s' % (
-            self.__class__.__name__,
-            self._group_name,
-            "\n".join(str(method) for method in self._methods))
-
-    def AddMethod(self, mock_method):
-        """Add a method to this group.
-
-        Args:
-            mock_method: A mock method to be added to this group.
-        """
-
-        self._methods.append(mock_method)
-
-    def MethodCalled(self, mock_method):
-        """Remove a method call from the group.
-
-        If the method is not in the set, an UnexpectedMethodCallError will be
-        raised.
-
-        Args:
-            mock_method: a mock method that should be equal to a method in the
-                         group.
-
-        Returns:
-            The mock method from the group
-
-        Raises:
-            UnexpectedMethodCallError if the mock_method was not in the group.
-        """
-
-        # Check to see if this method exists, and if so, remove it from the set
-        # and return it.
-        for method in self._methods:
-            if method == mock_method:
-                # Remove the called mock_method instead of the method in the
-                # group. The called method will match any comparators when
-                # equality is checked during removal. The method in the group
-                # could pass a comparator to another comparator during the
-                # equality check.
-                self._methods.remove(mock_method)
-
-                # If group is not empty, put it back at the head of the queue.
-                if not self.IsSatisfied():
-                    mock_method._call_queue.appendleft(self)
-
-                return self, method
-
-        raise UnexpectedMethodCallError(mock_method, self)
-
-    def IsSatisfied(self):
-        """Return True if there are not any methods in this group."""
-
-        return len(self._methods) == 0
-
-
-class MultipleTimesGroup(MethodGroup):
-    """MultipleTimesGroup holds methods that may be called any number of times.
-
-    Note: Each method must be called at least once.
-
-    This is helpful, if you don't know or care how many times a method is
-    called.
-    """
-
-    def __init__(self, group_name):
-        super(MultipleTimesGroup, self).__init__(group_name)
-        self._methods = set()
-        self._methods_left = set()
-
-    def AddMethod(self, mock_method):
-        """Add a method to this group.
-
-        Args:
-            mock_method: A mock method to be added to this group.
-        """
-
-        self._methods.add(mock_method)
-        self._methods_left.add(mock_method)
-
-    def MethodCalled(self, mock_method):
-        """Remove a method call from the group.
-
-        If the method is not in the set, an UnexpectedMethodCallError will be
-        raised.
-
-        Args:
-            mock_method: a mock method that should be equal to a method in the
-                         group.
-
-        Returns:
-            The mock method from the group
-
-        Raises:
-            UnexpectedMethodCallError if the mock_method was not in the group.
-        """
-
-        # Check to see if this method exists, and if so add it to the set of
-        # called methods.
-        for method in self._methods:
-            if method == mock_method:
-                self._methods_left.discard(method)
-                # Always put this group back on top of the queue,
-                # because we don't know when we are done.
-                mock_method._call_queue.appendleft(self)
-                return self, method
-
-        if self.IsSatisfied():
-            next_method = mock_method._PopNextMethod()
-            return next_method, None
-        else:
-            raise UnexpectedMethodCallError(mock_method, self)
-
-    def IsSatisfied(self):
-        """Return True if all methods in group are called at least once."""
-        return len(self._methods_left) == 0
-
-
-class MoxMetaTestBase(type):
-    """Metaclass to add mox cleanup and verification to every test.
-
-    As the mox unit testing class is being constructed (MoxTestBase or a
-    subclass), this metaclass will modify all test functions to call the
-    CleanUpMox method of the test class after they finish. This means that
-    unstubbing and verifying will happen for every test with no additional
-    code, and any failures will result in test failures as opposed to errors.
-    """
-
-    def __init__(cls, name, bases, d):
-        type.__init__(cls, name, bases, d)
-
-        # also get all the attributes from the base classes to account
-        # for a case when test class is not the immediate child of MoxTestBase
-        for base in bases:
-            for attr_name in dir(base):
-                if attr_name not in d:
-                    d[attr_name] = getattr(base, attr_name)
-
-        for func_name, func in d.items():
-            if func_name.startswith('test') and callable(func):
-
-                setattr(cls, func_name, MoxMetaTestBase.CleanUpTest(cls, func))
-
-    @staticmethod
-    def CleanUpTest(cls, func):
-        """Adds Mox cleanup code to any MoxTestBase method.
-
-        Always unsets stubs after a test. Will verify all mocks for tests that
-        otherwise pass.
-
-        Args:
-            cls: MoxTestBase or subclass; the class whose method we are
-                                          altering.
-            func: method; the method of the MoxTestBase test class we wish to
-                          alter.
-
-        Returns:
-            The modified method.
-        """
-        def new_method(self, *args, **kwargs):
-            mox_obj = getattr(self, 'mox', None)
-            stubout_obj = getattr(self, 'stubs', None)
-            cleanup_mox = False
-            cleanup_stubout = False
-            if mox_obj and isinstance(mox_obj, Mox):
-                cleanup_mox = True
-            if stubout_obj and isinstance(stubout_obj,
-                                          stubout.StubOutForTesting):
-                cleanup_stubout = True
-            try:
-                func(self, *args, **kwargs)
-            finally:
-                if cleanup_mox:
-                    mox_obj.UnsetStubs()
-                if cleanup_stubout:
-                    stubout_obj.UnsetAll()
-                    stubout_obj.SmartUnsetAll()
-            if cleanup_mox:
-                mox_obj.VerifyAll()
-        new_method.__name__ = func.__name__
-        new_method.__doc__ = func.__doc__
-        new_method.__module__ = func.__module__
-        return new_method
-
-
-_MoxTestBase = MoxMetaTestBase('_MoxTestBase', (unittest.TestCase, ), {})
-
-
-class MoxTestBase(_MoxTestBase):
-    """Convenience test class to make stubbing easier.
-
-    Sets up a "mox" attribute which is an instance of Mox (any mox tests will
-    want this), and a "stubs" attribute that is an instance of
-    StubOutForTesting (needed at times). Also automatically unsets any stubs
-    and verifies that all mock methods have been called at the end of each
-    test, eliminating boilerplate code.
-    """
-
-    def setUp(self):
-        super(MoxTestBase, self).setUp()
-        self.mox = Mox()
-        self.stubs = stubout.StubOutForTesting()
diff --git a/catapult/telemetry/third_party/mox3/mox3/stubout.py b/catapult/telemetry/third_party/mox3/mox3/stubout.py
deleted file mode 100644
index a02ed40..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/stubout.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# Copyright 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This is a fork of the pymox library intended to work with Python 3.
-# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
-
-import inspect
-
-
-class StubOutForTesting(object):
-    """Sample Usage:
-
-       You want os.path.exists() to always return true during testing.
-
-       stubs = StubOutForTesting()
-       stubs.Set(os.path, 'exists', lambda x: 1)
-           ...
-       stubs.UnsetAll()
-
-       The above changes os.path.exists into a lambda that returns 1.    Once
-       the ... part of the code finishes, the UnsetAll() looks up the old value
-       of os.path.exists and restores it.
-
-    """
-    def __init__(self):
-        self.cache = []
-        self.stubs = []
-
-    def __del__(self):
-        self.SmartUnsetAll()
-        self.UnsetAll()
-
-    def SmartSet(self, obj, attr_name, new_attr):
-        """Replace obj.attr_name with new_attr.
-
-        This method is smart and works at the module, class, and instance level
-        while preserving proper inheritance. It will not stub out C types
-        however unless that has been explicitly allowed by the type.
-
-        This method supports the case where attr_name is a staticmethod or a
-        classmethod of obj.
-
-        Notes:
-          - If obj is an instance, then it is its class that will actually be
-            stubbed. Note that the method Set() does not do that: if obj is
-            an instance, it (and not its class) will be stubbed.
-          - The stubbing is using the builtin getattr and setattr. So, the
-            __get__ and __set__ will be called when stubbing (TODO: A better
-            idea would probably be to manipulate obj.__dict__ instead of
-            getattr() and setattr()).
-
-        Raises AttributeError if the attribute cannot be found.
-        """
-        if (inspect.ismodule(obj) or
-                (not inspect.isclass(obj) and attr_name in obj.__dict__)):
-            orig_obj = obj
-            orig_attr = getattr(obj, attr_name)
-
-        else:
-            if not inspect.isclass(obj):
-                mro = list(inspect.getmro(obj.__class__))
-            else:
-                mro = list(inspect.getmro(obj))
-
-            mro.reverse()
-
-            orig_attr = None
-
-            for cls in mro:
-                try:
-                    orig_obj = cls
-                    orig_attr = getattr(obj, attr_name)
-                except AttributeError:
-                    continue
-
-        if orig_attr is None:
-            raise AttributeError("Attribute not found.")
-
-        # Calling getattr() on a staticmethod transforms it to a 'normal'
-        # function. We need to ensure that we put it back as a staticmethod.
-        old_attribute = obj.__dict__.get(attr_name)
-        if (old_attribute is not None
-                and isinstance(old_attribute, staticmethod)):
-            orig_attr = staticmethod(orig_attr)
-
-        self.stubs.append((orig_obj, attr_name, orig_attr))
-        setattr(orig_obj, attr_name, new_attr)
-
-    def SmartUnsetAll(self):
-        """Reverses all the SmartSet() calls.
-
-        Restores things to their original definition. Its okay to call
-        SmartUnsetAll() repeatedly, as later calls have no effect if no
-        SmartSet() calls have been made.
-        """
-        self.stubs.reverse()
-
-        for args in self.stubs:
-            setattr(*args)
-
-        self.stubs = []
-
-    def Set(self, parent, child_name, new_child):
-        """Replace child_name's old definition with new_child.
-
-        Replace definiion in the context of the given parent. The parent could
-        be a module when the child is a function at module scope. Or the parent
-        could be a class when a class' method is being replaced. The named
-        child is set to new_child, while the prior definition is saved away
-        for later, when UnsetAll() is called.
-
-        This method supports the case where child_name is a staticmethod or a
-        classmethod of parent.
-        """
-        old_child = getattr(parent, child_name)
-
-        old_attribute = parent.__dict__.get(child_name)
-        if old_attribute is not None:
-            if isinstance(old_attribute, staticmethod):
-                old_child = staticmethod(old_child)
-            elif isinstance(old_attribute, classmethod):
-                old_child = classmethod(old_child.__func__)
-
-        self.cache.append((parent, old_child, child_name))
-        setattr(parent, child_name, new_child)
-
-    def UnsetAll(self):
-        """Reverses all the Set() calls.
-
-        Restores things to their original definition. Its okay to call
-        UnsetAll() repeatedly, as later calls have no effect if no Set()
-        calls have been made.
-        """
-        # Undo calls to Set() in reverse order, in case Set() was called on the
-        # same arguments repeatedly (want the original call to be last one
-        # undone)
-        self.cache.reverse()
-
-        for (parent, old_child, child_name) in self.cache:
-            setattr(parent, child_name, old_child)
-        self.cache = []
diff --git a/catapult/telemetry/third_party/mox3/mox3/tests/__init__.py b/catapult/telemetry/third_party/mox3/mox3/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/tests/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/mox3/mox3/tests/mox_helper.py b/catapult/telemetry/third_party/mox3/mox3/tests/mox_helper.py
deleted file mode 100644
index 67843a9..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/tests/mox_helper.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# Copyright 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#
-# This is a fork of the pymox library intended to work with Python 3.
-# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
-
-"""A very basic test class derived from mox.MoxTestBase, used by test_mox.py.
-
-The class defined in this module is used to test the features of
-MoxTestBase and is not intended to be a standalone test.  It needs to
-be in a separate module, because otherwise the tests in this class
-(which should not all pass) would be executed as part of the
-test_mox.py test suite.
-
-See test_mox.MoxTestBaseTest for how this class is actually used.
-"""
-
-import os
-
-from mox3 import mox
-
-
-class ExampleMoxTestMixin(object):
-    """Mix-in class for mox test case class.
-
-    It stubs out the same function as one of the test methods in
-    the example test case.    Both tests must pass as meta class wraps
-    test methods in all base classes.
-    """
-
-    def testStat(self):
-        self.mox.StubOutWithMock(os, 'stat')
-        os.stat(self.DIR_PATH)
-        self.mox.ReplayAll()
-        os.stat(self.DIR_PATH)
-
-
-class ExampleMoxTest(mox.MoxTestBase, ExampleMoxTestMixin):
-
-    DIR_PATH = '/path/to/some/directory'
-
-    def testSuccess(self):
-        self.mox.StubOutWithMock(os, 'listdir')
-        os.listdir(self.DIR_PATH)
-        self.mox.ReplayAll()
-        os.listdir(self.DIR_PATH)
-
-    def testExpectedNotCalled(self):
-        self.mox.StubOutWithMock(os, 'listdir')
-        os.listdir(self.DIR_PATH)
-        self.mox.ReplayAll()
-
-    def testUnexpectedCall(self):
-        self.mox.StubOutWithMock(os, 'listdir')
-        os.listdir(self.DIR_PATH)
-        self.mox.ReplayAll()
-        os.listdir('/path/to/some/other/directory')
-        os.listdir(self.DIR_PATH)
-
-    def testFailure(self):
-        self.assertTrue(False)
-
-    def testStatOther(self):
-        self.mox.StubOutWithMock(os, 'stat')
-        os.stat(self.DIR_PATH)
-        self.mox.ReplayAll()
-        os.stat(self.DIR_PATH)
-
-    def testHasStubs(self):
-        listdir_list = []
-
-        def MockListdir(directory):
-            listdir_list.append(directory)
-
-        self.stubs.Set(os, 'listdir', MockListdir)
-        os.listdir(self.DIR_PATH)
-        self.assertEqual([self.DIR_PATH], listdir_list)
-
-
-class TestClassFromAnotherModule(object):
-
-    def __init__(self):
-        return None
-
-    def Value(self):
-        return 'Not mock'
-
-
-class ChildClassFromAnotherModule(TestClassFromAnotherModule):
-    """A child class of TestClassFromAnotherModule.
-
-    Used to test stubbing out unbound methods, where child classes
-    are eventually bound.
-    """
-
-    def __init__(self):
-        TestClassFromAnotherModule.__init__(self)
-
-
-class CallableClass(object):
-
-    def __init__(self, one, two, nine=None):
-        pass
-
-    def __call__(self, one):
-        return 'Not mock'
-
-    def Value(self):
-        return 'Not mock'
-
-
-def MyTestFunction(one, two, nine=None):
-    pass
-
-
-class ExampleClass(object):
-    def __init__(self, foo='bar'):
-        pass
-
-    def TestMethod(self, one, two, nine=None):
-        pass
-
-    def NamedParams(self, ignore, foo='bar', baz='qux'):
-        pass
-
-    def SpecialArgs(self, *args, **kwargs):
-        pass
-
-
-# This class is used to test stubbing out __init__ of a parent class.
-class ChildExampleClass(ExampleClass):
-    def __init__(self):
-        ExampleClass.__init__(self)
diff --git a/catapult/telemetry/third_party/mox3/mox3/tests/stubout_helper.py b/catapult/telemetry/third_party/mox3/mox3/tests/stubout_helper.py
deleted file mode 100644
index 7a6b266..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/tests/stubout_helper.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This is a fork of the pymox library intended to work with Python 3.
-# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
-
-
-def SampleFunction():
-    raise Exception('I should never be called!')
diff --git a/catapult/telemetry/third_party/mox3/mox3/tests/test_mox.py b/catapult/telemetry/third_party/mox3/mox3/tests/test_mox.py
deleted file mode 100644
index 48d1ecf..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/tests/test_mox.py
+++ /dev/null
@@ -1,2408 +0,0 @@
-# Unit tests for Mox.
-#
-# Copyright 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This is a fork of the pymox library intended to work with Python 3.
-# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
-
-import io
-import re
-import sys
-
-from mox3 import mox
-from mox3.tests import mox_helper
-
-import six
-import testtools
-
-
-OS_LISTDIR = mox_helper.os.listdir
-
-
-class ExpectedMethodCallsErrorTest(testtools.TestCase):
-    """Test creation and string conversion of ExpectedMethodCallsError."""
-
-    def testAtLeastOneMethod(self):
-        self.assertRaises(ValueError, mox.ExpectedMethodCallsError, [])
-
-    def testOneError(self):
-        method = mox.MockMethod("testMethod", [], False)
-        method(1, 2).AndReturn('output')
-        e = mox.ExpectedMethodCallsError([method])
-        self.assertEqual(
-            "Verify: Expected methods never called:\n"
-            "  0.  testMethod(1, 2) -> 'output'",
-            str(e))
-
-    def testManyErrors(self):
-        method1 = mox.MockMethod("testMethod", [], False)
-        method1(1, 2).AndReturn('output')
-        method2 = mox.MockMethod("testMethod", [], False)
-        method2(a=1, b=2, c="only named")
-        method3 = mox.MockMethod("testMethod2", [], False)
-        method3().AndReturn(44)
-        method4 = mox.MockMethod("testMethod", [], False)
-        method4(1, 2).AndReturn('output')
-        e = mox.ExpectedMethodCallsError([method1, method2, method3, method4])
-        self.assertEqual(
-            "Verify: Expected methods never called:\n"
-            "  0.  testMethod(1, 2) -> 'output'\n"
-            "  1.  testMethod(a=1, b=2, c='only named') -> None\n"
-            "  2.  testMethod2() -> 44\n"
-            "  3.  testMethod(1, 2) -> 'output'",
-            str(e))
-
-
-class OrTest(testtools.TestCase):
-    """Test Or correctly chains Comparators."""
-
-    def testValidOr(self):
-        """Or should be True if either Comparator returns True."""
-        self.assertTrue(mox.Or(mox.IsA(dict), mox.IsA(str)) == {})
-        self.assertTrue(mox.Or(mox.IsA(dict), mox.IsA(str)) == 'test')
-        self.assertTrue(mox.Or(mox.IsA(str), mox.IsA(str)) == 'test')
-
-    def testInvalidOr(self):
-        """Or should be False if both Comparators return False."""
-        self.assertFalse(mox.Or(mox.IsA(dict), mox.IsA(str)) == 0)
-
-
-class AndTest(testtools.TestCase):
-    """Test And correctly chains Comparators."""
-
-    def testValidAnd(self):
-        """And should be True if both Comparators return True."""
-        self.assertTrue(mox.And(mox.IsA(str), mox.IsA(str)) == '1')
-
-    def testClauseOneFails(self):
-        """And should be False if the first Comparator returns False."""
-
-        self.assertFalse(mox.And(mox.IsA(dict), mox.IsA(str)) == '1')
-
-    def testAdvancedUsage(self):
-        """And should work with other Comparators.
-
-        Note: this test is reliant on In and ContainsKeyValue.
-        """
-        test_dict = {"mock": "obj", "testing": "isCOOL"}
-        self.assertTrue(mox.And(mox.In("testing"),
-                        mox.ContainsKeyValue("mock", "obj")) == test_dict)
-
-    def testAdvancedUsageFails(self):
-        """Note: this test is reliant on In and ContainsKeyValue."""
-        test_dict = {"mock": "obj", "testing": "isCOOL"}
-        self.assertFalse(mox.And(mox.In("NOTFOUND"),
-                         mox.ContainsKeyValue("mock", "obj")) == test_dict)
-
-
-class FuncTest(testtools.TestCase):
-    """Test Func correctly evaluates based upon true-false return."""
-
-    def testFuncTrueFalseEvaluation(self):
-        """Should return True if the validating function returns True."""
-        equals_one = lambda x: x == 1
-        always_none = lambda x: None
-
-        self.assertTrue(mox.Func(equals_one) == 1)
-        self.assertFalse(mox.Func(equals_one) == 0)
-
-        self.assertFalse(mox.Func(always_none) == 1)
-        self.assertFalse(mox.Func(always_none) == 0)
-        self.assertFalse(mox.Func(always_none) is None)
-
-    def testFuncExceptionPropagation(self):
-        """Exceptions within the validating function should propagate."""
-        class TestException(Exception):
-            pass
-
-        def raiseExceptionOnNotOne(value):
-            if value != 1:
-                raise TestException
-            else:
-                return True
-
-        self.assertTrue(mox.Func(raiseExceptionOnNotOne) == 1)
-        self.assertRaises(
-            TestException, mox.Func(raiseExceptionOnNotOne).__eq__, 2)
-
-
-class SameElementsAsTest(testtools.TestCase):
-    """SameElementsAs correctly identifies sequences with same elements."""
-
-    def testSortedLists(self):
-        """Should return True if two lists are exactly equal."""
-        self.assertTrue(mox.SameElementsAs([1, 2.0, 'c']) == [1, 2.0, 'c'])
-
-    def testUnsortedLists(self):
-        """Should return True if lists are unequal but have same elements."""
-        self.assertTrue(mox.SameElementsAs([1, 2.0, 'c']) == [2.0, 'c', 1])
-
-    def testUnhashableLists(self):
-        """Should return True if lists have the same unhashable elements."""
-        self.assertTrue(mox.SameElementsAs([{'a': 1}, {2: 'b'}]) ==
-                        [{2: 'b'}, {'a': 1}])
-
-    def testEmptyLists(self):
-        """Should return True for two empty lists."""
-        self.assertTrue(mox.SameElementsAs([]) == [])
-
-    def testUnequalLists(self):
-        """Should return False if the lists are not equal."""
-        self.assertFalse(mox.SameElementsAs([1, 2.0, 'c']) == [2.0, 'c'])
-
-    def testUnequalUnhashableLists(self):
-        """Should return False if lists with unhashable items are unequal."""
-        self.assertFalse(mox.SameElementsAs(
-            [{'a': 1}, {2: 'b'}]) == [{2: 'b'}])
-
-    def testActualIsNotASequence(self):
-        """Should return False if the actual object is not a sequence."""
-        self.assertFalse(mox.SameElementsAs([1]) == object())
-
-    def testOneUnhashableObjectInActual(self):
-        """Store the entire iterator for a correct comparison.
-
-        In a previous version of SameElementsAs, iteration stopped when an
-        unhashable object was encountered and then was restarted, so the actual
-        list appeared smaller than it was.
-        """
-        self.assertFalse(mox.SameElementsAs([1, 2]) == iter([{}, 1, 2]))
-
-
-class ContainsKeyValueTest(testtools.TestCase):
-    """Test ContainsKeyValue correctly identifies key/value pairs in a dict.
-    """
-
-    def testValidPair(self):
-        """Should return True if the key value is in the dict."""
-        self.assertTrue(mox.ContainsKeyValue("key", 1) == {"key": 1})
-
-    def testInvalidValue(self):
-        """Should return False if the value is not correct."""
-        self.assertFalse(mox.ContainsKeyValue("key", 1) == {"key": 2})
-
-    def testInvalidKey(self):
-        """Should return False if they key is not in the dict."""
-        self.assertFalse(mox.ContainsKeyValue("qux", 1) == {"key": 2})
-
-
-class ContainsAttributeValueTest(testtools.TestCase):
-    """Test ContainsAttributeValue identifies properties in an object."""
-
-    def setUp(self):
-        """Create an object to test with."""
-
-        class TestObject(object):
-            key = 1
-
-        super(ContainsAttributeValueTest, self).setUp()
-        self.test_object = TestObject()
-
-    def testValidPair(self):
-        """Return True if the object has the key attribute that matches."""
-        self.assertTrue(mox.ContainsAttributeValue("key", 1)
-                        == self.test_object)
-
-    def testInvalidValue(self):
-        """Should return False if the value is not correct."""
-        self.assertFalse(mox.ContainsKeyValue("key", 2) == self.test_object)
-
-    def testInvalidKey(self):
-        """Should return False if they the object doesn't have the property."""
-        self.assertFalse(mox.ContainsKeyValue("qux", 1) == self.test_object)
-
-
-class InTest(testtools.TestCase):
-    """Test In correctly identifies a key in a list/dict."""
-
-    def testItemInList(self):
-        """Should return True if the item is in the list."""
-        self.assertTrue(mox.In(1) == [1, 2, 3])
-
-    def testKeyInDict(self):
-        """Should return True if the item is a key in a dict."""
-        self.assertTrue(mox.In("test") == {"test": "module"})
-
-    def testItemInTuple(self):
-        """Should return True if the item is in the list."""
-        self.assertTrue(mox.In(1) == (1, 2, 3))
-
-    def testTupleInTupleOfTuples(self):
-        self.assertTrue(mox.In((1, 2, 3)) == ((1, 2, 3), (1, 2)))
-
-    def testItemNotInList(self):
-        self.assertFalse(mox.In(1) == [2, 3])
-
-    def testTupleNotInTupleOfTuples(self):
-        self.assertFalse(mox.In((1, 2)) == ((1, 2, 3), (4, 5)))
-
-
-class NotTest(testtools.TestCase):
-    """Test Not correctly identifies False predicates."""
-
-    def testItemInList(self):
-        """Should return True if the item is NOT in the list."""
-        self.assertTrue(mox.Not(mox.In(42)) == [1, 2, 3])
-
-    def testKeyInDict(self):
-        """Should return True if the item is NOT a key in a dict."""
-        self.assertTrue(mox.Not(mox.In("foo")) == {"key": 42})
-
-    def testInvalidKeyWithNot(self):
-        """Should return False if they key is NOT in the dict."""
-        self.assertTrue(mox.Not(mox.ContainsKeyValue("qux", 1)) == {"key": 2})
-
-
-class StrContainsTest(testtools.TestCase):
-    """Test StrContains checks for substring occurrence of a parameter."""
-
-    def testValidSubstringAtStart(self):
-        """Should return True if substring is at the start of the string."""
-        self.assertTrue(mox.StrContains("hello") == "hello world")
-
-    def testValidSubstringInMiddle(self):
-        """Should return True if substring is in the middle of the string."""
-        self.assertTrue(mox.StrContains("lo wo") == "hello world")
-
-    def testValidSubstringAtEnd(self):
-        """Should return True if the substring is at the end of the string."""
-        self.assertTrue(mox.StrContains("ld") == "hello world")
-
-    def testInvaildSubstring(self):
-        """Should return False if the substring is not in the string."""
-        self.assertFalse(mox.StrContains("AAA") == "hello world")
-
-    def testMultipleMatches(self):
-        """Should return True if there are multiple occurances of substring."""
-        self.assertTrue(mox.StrContains("abc") == "ababcabcabcababc")
-
-
-class RegexTest(testtools.TestCase):
-    """Test Regex correctly matches regular expressions."""
-
-    def testIdentifyBadSyntaxDuringInit(self):
-        """The user should know immediately if a regex has bad syntax."""
-        self.assertRaises(re.error, mox.Regex, '(a|b')
-
-    def testPatternInMiddle(self):
-        """Return True if the pattern matches at the middle of the string.
-
-        This ensures that re.search is used (instead of re.find).
-        """
-        self.assertTrue(mox.Regex(r"a\s+b") == "x y z a b c")
-
-    def testNonMatchPattern(self):
-        """Should return False if the pattern does not match the string."""
-        self.assertFalse(mox.Regex(r"a\s+b") == "x y z")
-
-    def testFlagsPassedCorrectly(self):
-        """Should return True as we pass IGNORECASE flag."""
-        self.assertTrue(mox.Regex(r"A", re.IGNORECASE) == "a")
-
-    def testReprWithoutFlags(self):
-        """repr should return the regular expression pattern."""
-        self.assertTrue(
-            repr(mox.Regex(r"a\s+b")) == "<regular expression 'a\s+b'>")
-
-    def testReprWithFlags(self):
-        """repr should return the regular expression pattern and flags."""
-        self.assertTrue(repr(mox.Regex(r"a\s+b", flags=4)) ==
-                        "<regular expression 'a\s+b', flags=4>")
-
-
-class IsTest(testtools.TestCase):
-    """Verify Is correctly checks equality based upon identity, not value."""
-
-    class AlwaysComparesTrue(object):
-        def __eq__(self, other):
-            return True
-
-        def __cmp__(self, other):
-            return 0
-
-        def __ne__(self, other):
-            return False
-
-    def testEqualityValid(self):
-        o1 = self.AlwaysComparesTrue()
-        self.assertTrue(mox.Is(o1), o1)
-
-    def testEqualityInvalid(self):
-        o1 = self.AlwaysComparesTrue()
-        o2 = self.AlwaysComparesTrue()
-        self.assertTrue(o1 == o2)
-        # but...
-        self.assertFalse(mox.Is(o1) == o2)
-
-    def testInequalityValid(self):
-        o1 = self.AlwaysComparesTrue()
-        o2 = self.AlwaysComparesTrue()
-        self.assertTrue(mox.Is(o1) != o2)
-
-    def testInequalityInvalid(self):
-        o1 = self.AlwaysComparesTrue()
-        self.assertFalse(mox.Is(o1) != o1)
-
-    def testEqualityInListValid(self):
-        o1 = self.AlwaysComparesTrue()
-        o2 = self.AlwaysComparesTrue()
-        isa_list = [mox.Is(o1), mox.Is(o2)]
-        str_list = [o1, o2]
-        self.assertTrue(isa_list == str_list)
-
-    def testEquailtyInListInvalid(self):
-        o1 = self.AlwaysComparesTrue()
-        o2 = self.AlwaysComparesTrue()
-        isa_list = [mox.Is(o1), mox.Is(o2)]
-        mixed_list = [o2, o1]
-        self.assertFalse(isa_list == mixed_list)
-
-
-class IsATest(testtools.TestCase):
-    """Verify IsA correctly checks equality based upon class type not value."""
-
-    def testEqualityValid(self):
-        """Verify that == correctly identifies objects of the same type."""
-        self.assertTrue(mox.IsA(str) == 'test')
-
-    def testEqualityInvalid(self):
-        """Verify that == correctly identifies objects of different types."""
-        self.assertFalse(mox.IsA(str) == 10)
-
-    def testInequalityValid(self):
-        """Verify that != identifies objects of different type."""
-        self.assertTrue(mox.IsA(str) != 10)
-
-    def testInequalityInvalid(self):
-        """Verify that != correctly identifies objects of the same type."""
-        self.assertFalse(mox.IsA(str) != "test")
-
-    def testEqualityInListValid(self):
-        """Verify list contents are properly compared."""
-        isa_list = [mox.IsA(str), mox.IsA(str)]
-        str_list = ["abc", "def"]
-        self.assertTrue(isa_list == str_list)
-
-    def testEquailtyInListInvalid(self):
-        """Verify list contents are properly compared."""
-        isa_list = [mox.IsA(str), mox.IsA(str)]
-        mixed_list = ["abc", 123]
-        self.assertFalse(isa_list == mixed_list)
-
-    def testSpecialTypes(self):
-        """Verify that IsA can handle objects like io.StringIO."""
-        isA = mox.IsA(io.StringIO())
-        stringIO = io.StringIO()
-        self.assertTrue(isA == stringIO)
-
-
-class IsAlmostTest(testtools.TestCase):
-    """Verify IsAlmost correctly checks equality of floating point numbers."""
-
-    def testEqualityValid(self):
-        """Verify that == correctly identifies nearly equivalent floats."""
-        self.assertEqual(mox.IsAlmost(1.8999999999), 1.9)
-
-    def testEqualityInvalid(self):
-        """Verify that == correctly identifies non-equivalent floats."""
-        self.assertNotEqual(mox.IsAlmost(1.899), 1.9)
-
-    def testEqualityWithPlaces(self):
-        """Verify that specifying places has the desired effect."""
-        self.assertNotEqual(mox.IsAlmost(1.899), 1.9)
-        self.assertEqual(mox.IsAlmost(1.899, places=2), 1.9)
-
-    def testNonNumericTypes(self):
-        """Verify that IsAlmost handles non-numeric types properly."""
-
-        self.assertNotEqual(mox.IsAlmost(1.8999999999), '1.9')
-        self.assertNotEqual(mox.IsAlmost('1.8999999999'), 1.9)
-        self.assertNotEqual(mox.IsAlmost('1.8999999999'), '1.9')
-
-
-class ValueRememberTest(testtools.TestCase):
-    """Verify comparing argument against remembered value."""
-
-    def testValueEquals(self):
-        """Verify that value will compare to stored value."""
-        value = mox.Value()
-        value.store_value('hello world')
-        self.assertEqual(value, 'hello world')
-
-    def testNoValue(self):
-        """Verify that uninitialized value does not compare to empty values."""
-        value = mox.Value()
-        self.assertNotEqual(value, None)
-        self.assertNotEqual(value, False)
-        self.assertNotEqual(value, 0)
-        self.assertNotEqual(value, '')
-        self.assertNotEqual(value, ())
-        self.assertNotEqual(value, [])
-        self.assertNotEqual(value, {})
-        self.assertNotEqual(value, object())
-        self.assertNotEqual(value, set())
-
-    def testRememberValue(self):
-        """Verify that comparing against remember will store argument."""
-        value = mox.Value()
-        remember = mox.Remember(value)
-        self.assertNotEqual(value, 'hello world')  # value not yet stored.
-        self.assertEqual(remember, 'hello world')  # store value here.
-        self.assertEqual(value, 'hello world')  # compare against stored value.
-
-
-class MockMethodTest(testtools.TestCase):
-    """Test class to verify that the MockMethod class is working correctly."""
-
-    def setUp(self):
-        super(MockMethodTest, self).setUp()
-        self.expected_method = mox.MockMethod(
-            "testMethod", [], False)(['original'])
-        self.mock_method = mox.MockMethod(
-            "testMethod", [self.expected_method], True)
-
-    def testNameAttribute(self):
-        """Should provide a __name__ attribute."""
-        self.assertEqual('testMethod', self.mock_method.__name__)
-
-    def testAndReturnNoneByDefault(self):
-        """Should return None by default."""
-        return_value = self.mock_method(['original'])
-        self.assertTrue(return_value is None)
-
-    def testAndReturnValue(self):
-        """Should return a specificed return value."""
-        expected_return_value = "test"
-        self.expected_method.AndReturn(expected_return_value)
-        return_value = self.mock_method(['original'])
-        self.assertTrue(return_value == expected_return_value)
-
-    def testAndRaiseException(self):
-        """Should raise a specified exception."""
-        class TestException(Exception):
-            pass
-
-        expected_exception = TestException('test exception')
-        self.expected_method.AndRaise(expected_exception)
-        self.assertRaises(TestException, self.mock_method, ['original'])
-
-    def testWithSideEffects(self):
-        """Should call state modifier."""
-        local_list = ['original']
-
-        def modifier(mutable_list):
-            self.assertTrue(local_list is mutable_list)
-            mutable_list[0] = 'mutation'
-
-        self.expected_method.WithSideEffects(modifier).AndReturn(1)
-        self.mock_method(local_list)
-        self.assertEqual('mutation', local_list[0])
-
-    def testWithReturningSideEffects(self):
-        """Should call state modifier and propagate its return value."""
-        local_list = ['original']
-        expected_return = 'expected_return'
-
-        def modifier_with_return(mutable_list):
-            self.assertTrue(local_list is mutable_list)
-            mutable_list[0] = 'mutation'
-            return expected_return
-
-        self.expected_method.WithSideEffects(modifier_with_return)
-        actual_return = self.mock_method(local_list)
-        self.assertEqual('mutation', local_list[0])
-        self.assertEqual(expected_return, actual_return)
-
-    def testWithReturningSideEffectsWithAndReturn(self):
-        """Should call state modifier and ignore its return value."""
-        local_list = ['original']
-        expected_return = 'expected_return'
-        unexpected_return = 'unexpected_return'
-
-        def modifier_with_return(mutable_list):
-            self.assertTrue(local_list is mutable_list)
-            mutable_list[0] = 'mutation'
-            return unexpected_return
-
-        self.expected_method.WithSideEffects(modifier_with_return).AndReturn(
-            expected_return)
-        actual_return = self.mock_method(local_list)
-        self.assertEqual('mutation', local_list[0])
-        self.assertEqual(expected_return, actual_return)
-
-    def testEqualityNoParamsEqual(self):
-        """Methods with the same name and without params should be equal."""
-        expected_method = mox.MockMethod("testMethod", [], False)
-        self.assertEqual(self.mock_method, expected_method)
-
-    def testEqualityNoParamsNotEqual(self):
-        """Methods with different names without params should not be equal."""
-        expected_method = mox.MockMethod("otherMethod", [], False)
-        self.assertNotEqual(self.mock_method, expected_method)
-
-    def testEqualityParamsEqual(self):
-        """Methods with the same name and parameters should be equal."""
-        params = [1, 2, 3]
-        expected_method = mox.MockMethod("testMethod", [], False)
-        expected_method._params = params
-
-        self.mock_method._params = params
-        self.assertEqual(self.mock_method, expected_method)
-
-    def testEqualityParamsNotEqual(self):
-        """Methods with same name and different params should not be equal."""
-        expected_method = mox.MockMethod("testMethod", [], False)
-        expected_method._params = [1, 2, 3]
-
-        self.mock_method._params = ['a', 'b', 'c']
-        self.assertNotEqual(self.mock_method, expected_method)
-
-    def testEqualityNamedParamsEqual(self):
-        """Methods with the same name and same named params should be equal."""
-        named_params = {"input1": "test", "input2": "params"}
-        expected_method = mox.MockMethod("testMethod", [], False)
-        expected_method._named_params = named_params
-
-        self.mock_method._named_params = named_params
-        self.assertEqual(self.mock_method, expected_method)
-
-    def testEqualityNamedParamsNotEqual(self):
-        """Methods with same name and diffnamed params should not be equal."""
-        expected_method = mox.MockMethod("testMethod", [], False)
-        expected_method._named_params = {"input1": "test", "input2": "params"}
-
-        self.mock_method._named_params = {
-            "input1": "test2", "input2": "params2"}
-        self.assertNotEqual(self.mock_method, expected_method)
-
-    def testEqualityWrongType(self):
-        """Method should not be equal to an object of a different type."""
-        self.assertNotEqual(self.mock_method, "string?")
-
-    def testObjectEquality(self):
-        """Equality of objects should work without a Comparator"""
-        instA = TestClass()
-        instB = TestClass()
-
-        params = [instA, ]
-        expected_method = mox.MockMethod("testMethod", [], False)
-        expected_method._params = params
-
-        self.mock_method._params = [instB, ]
-        self.assertEqual(self.mock_method, expected_method)
-
-    def testStrConversion(self):
-        method = mox.MockMethod("f", [], False)
-        method(1, 2, "st", n1=8, n2="st2")
-        self.assertEqual(str(method),
-                         ("f(1, 2, 'st', n1=8, n2='st2') -> None"))
-
-        method = mox.MockMethod("testMethod", [], False)
-        method(1, 2, "only positional")
-        self.assertEqual(str(method),
-                         "testMethod(1, 2, 'only positional') -> None")
-
-        method = mox.MockMethod("testMethod", [], False)
-        method(a=1, b=2, c="only named")
-        self.assertEqual(str(method),
-                         "testMethod(a=1, b=2, c='only named') -> None")
-
-        method = mox.MockMethod("testMethod", [], False)
-        method()
-        self.assertEqual(str(method), "testMethod() -> None")
-
-        method = mox.MockMethod("testMethod", [], False)
-        method(x="only 1 parameter")
-        self.assertEqual(str(method),
-                         "testMethod(x='only 1 parameter') -> None")
-
-        method = mox.MockMethod("testMethod", [], False)
-        method().AndReturn('return_value')
-        self.assertEqual(str(method), "testMethod() -> 'return_value'")
-
-        method = mox.MockMethod("testMethod", [], False)
-        method().AndReturn(('a', {1: 2}))
-        self.assertEqual(str(method), "testMethod() -> ('a', {1: 2})")
-
-
-class MockAnythingTest(testtools.TestCase):
-    """Verify that the MockAnything class works as expected."""
-
-    def setUp(self):
-        super(MockAnythingTest, self).setUp()
-        self.mock_object = mox.MockAnything()
-
-    def testRepr(self):
-        """Calling repr on a MockAnything instance must work."""
-        self.assertEqual('<MockAnything instance>', repr(self.mock_object))
-
-    def testCanMockStr(self):
-        self.mock_object.__str__().AndReturn("foo")
-        self.mock_object._Replay()
-        actual = str(self.mock_object)
-        self.mock_object._Verify()
-        self.assertEqual("foo", actual)
-
-    def testSetupMode(self):
-        """Verify the mock will accept any call."""
-        self.mock_object.NonsenseCall()
-        self.assertTrue(len(self.mock_object._expected_calls_queue) == 1)
-
-    def testReplayWithExpectedCall(self):
-        """Verify the mock replays method calls as expected."""
-        self.mock_object.ValidCall()                    # setup method call
-        self.mock_object._Replay()                        # start replay mode
-        self.mock_object.ValidCall()                    # make method call
-
-    def testReplayWithUnexpectedCall(self):
-        """Unexpected method calls should raise UnexpectedMethodCallError."""
-        self.mock_object.ValidCall()                    # setup method call
-        self.mock_object._Replay()                         # start replay mode
-        self.assertRaises(mox.UnexpectedMethodCallError,
-                          self.mock_object.OtherValidCall)
-
-    def testVerifyWithCompleteReplay(self):
-        """Verify should not raise an exception for a valid replay."""
-        self.mock_object.ValidCall()                    # setup method call
-        self.mock_object._Replay()                         # start replay mode
-        self.mock_object.ValidCall()                    # make method call
-        self.mock_object._Verify()
-
-    def testVerifyWithIncompleteReplay(self):
-        """Verify should raise an exception if the replay was not complete."""
-        self.mock_object.ValidCall()                    # setup method call
-        self.mock_object._Replay()                         # start replay mode
-        # ValidCall() is never made
-        self.assertRaises(
-            mox.ExpectedMethodCallsError, self.mock_object._Verify)
-
-    def testSpecialClassMethod(self):
-        """Verify should not raise exception when special methods are used."""
-        self.mock_object[1].AndReturn(True)
-        self.mock_object._Replay()
-        returned_val = self.mock_object[1]
-        self.assertTrue(returned_val)
-        self.mock_object._Verify()
-
-    def testNonzero(self):
-        """You should be able to use the mock object in an if."""
-        self.mock_object._Replay()
-        if self.mock_object:
-            pass
-
-    def testNotNone(self):
-        """Mock should be comparable to None."""
-        self.mock_object._Replay()
-        if self.mock_object is not None:
-            pass
-
-        if self.mock_object is None:
-            pass
-
-    def testEquals(self):
-        """A mock should be able to compare itself to another object."""
-        self.mock_object._Replay()
-        self.assertEqual(self.mock_object, self.mock_object)
-
-    def testEqualsMockFailure(self):
-        """Verify equals identifies unequal objects."""
-        self.mock_object.SillyCall()
-        self.mock_object._Replay()
-        self.assertNotEqual(self.mock_object, mox.MockAnything())
-
-    def testEqualsInstanceFailure(self):
-        """Verify equals identifies that objects are different instances."""
-        self.mock_object._Replay()
-        self.assertNotEqual(self.mock_object, TestClass())
-
-    def testNotEquals(self):
-        """Verify not equals works."""
-        self.mock_object._Replay()
-        self.assertFalse(self.mock_object != self.mock_object)
-
-    def testNestedMockCallsRecordedSerially(self):
-        """Test that nested calls work when recorded serially."""
-        self.mock_object.CallInner().AndReturn(1)
-        self.mock_object.CallOuter(1)
-        self.mock_object._Replay()
-
-        self.mock_object.CallOuter(self.mock_object.CallInner())
-
-        self.mock_object._Verify()
-
-    def testNestedMockCallsRecordedNested(self):
-        """Test that nested cals work when recorded in a nested fashion."""
-        self.mock_object.CallOuter(self.mock_object.CallInner().AndReturn(1))
-        self.mock_object._Replay()
-
-        self.mock_object.CallOuter(self.mock_object.CallInner())
-
-        self.mock_object._Verify()
-
-    def testIsCallable(self):
-        """Test that MockAnything can even mock a simple callable.
-
-        This is handy for "stubbing out" a method in a module with a mock, and
-        verifying that it was called.
-        """
-        self.mock_object().AndReturn('mox0rd')
-        self.mock_object._Replay()
-
-        self.assertEqual('mox0rd', self.mock_object())
-
-        self.mock_object._Verify()
-
-    def testIsReprable(self):
-        """Test that MockAnythings can be repr'd without causing a failure."""
-        self.assertTrue('MockAnything' in repr(self.mock_object))
-
-
-class MethodCheckerTest(testtools.TestCase):
-    """Tests MockMethod's use of MethodChecker method."""
-
-    def testUnboundMethodsRequiresInstance(self):
-        # SKIP TEST IN PYTHON 2.x (Ugly hack for python 2.6)
-        # REASON: semantics for unbound methods has changed only in Python 3
-        #     so this test in earlier versions is invald
-        if sys.version_info < (3, 0):
-            return
-
-        instance = CheckCallTestClass()
-        method = mox.MockMethod('NoParameters', [], False,
-                                CheckCallTestClass.NoParameters)
-
-        self.assertRaises(AttributeError, method)
-        method(instance)
-        self.assertRaises(AttributeError, method, instance, 1)
-
-    def testNoParameters(self):
-        method = mox.MockMethod('NoParameters', [], False,
-                                CheckCallTestClass.NoParameters,
-                                class_to_bind=CheckCallTestClass)
-        method()
-        self.assertRaises(AttributeError, method, 1)
-        self.assertRaises(AttributeError, method, 1, 2)
-        self.assertRaises(AttributeError, method, a=1)
-        self.assertRaises(AttributeError, method, 1, b=2)
-
-    def testOneParameter(self):
-        method = mox.MockMethod('OneParameter', [], False,
-                                CheckCallTestClass.OneParameter,
-                                class_to_bind=CheckCallTestClass)
-        self.assertRaises(AttributeError, method)
-        method(1)
-        method(a=1)
-        self.assertRaises(AttributeError, method, b=1)
-        self.assertRaises(AttributeError, method, 1, 2)
-        self.assertRaises(AttributeError, method, 1, a=2)
-        self.assertRaises(AttributeError, method, 1, b=2)
-
-    def testTwoParameters(self):
-        method = mox.MockMethod('TwoParameters', [], False,
-                                CheckCallTestClass.TwoParameters,
-                                class_to_bind=CheckCallTestClass)
-        self.assertRaises(AttributeError, method)
-        self.assertRaises(AttributeError, method, 1)
-        self.assertRaises(AttributeError, method, a=1)
-        self.assertRaises(AttributeError, method, b=1)
-        method(1, 2)
-        method(1, b=2)
-        method(a=1, b=2)
-        method(b=2, a=1)
-        self.assertRaises(AttributeError, method, b=2, c=3)
-        self.assertRaises(AttributeError, method, a=1, b=2, c=3)
-        self.assertRaises(AttributeError, method, 1, 2, 3)
-        self.assertRaises(AttributeError, method, 1, 2, 3, 4)
-        self.assertRaises(AttributeError, method, 3, a=1, b=2)
-
-    def testOneDefaultValue(self):
-        method = mox.MockMethod('OneDefaultValue', [], False,
-                                CheckCallTestClass.OneDefaultValue,
-                                class_to_bind=CheckCallTestClass)
-        method()
-        method(1)
-        method(a=1)
-        self.assertRaises(AttributeError, method, b=1)
-        self.assertRaises(AttributeError, method, 1, 2)
-        self.assertRaises(AttributeError, method, 1, a=2)
-        self.assertRaises(AttributeError, method, 1, b=2)
-
-    def testTwoDefaultValues(self):
-        method = mox.MockMethod('TwoDefaultValues', [], False,
-                                CheckCallTestClass.TwoDefaultValues,
-                                class_to_bind=CheckCallTestClass)
-        self.assertRaises(AttributeError, method)
-        self.assertRaises(AttributeError, method, c=3)
-        self.assertRaises(AttributeError, method, 1)
-        self.assertRaises(AttributeError, method, 1, d=4)
-        self.assertRaises(AttributeError, method, 1, d=4, c=3)
-        method(1, 2)
-        method(a=1, b=2)
-        method(1, 2, 3)
-        method(1, 2, 3, 4)
-        method(1, 2, c=3)
-        method(1, 2, c=3, d=4)
-        method(1, 2, d=4, c=3)
-        method(d=4, c=3, a=1, b=2)
-        self.assertRaises(AttributeError, method, 1, 2, 3, 4, 5)
-        self.assertRaises(AttributeError, method, 1, 2, e=9)
-        self.assertRaises(AttributeError, method, a=1, b=2, e=9)
-
-    def testArgs(self):
-        method = mox.MockMethod('Args', [], False, CheckCallTestClass.Args,
-                                class_to_bind=CheckCallTestClass)
-        self.assertRaises(AttributeError, method)
-        self.assertRaises(AttributeError, method, 1)
-        method(1, 2)
-        method(a=1, b=2)
-        method(1, 2, 3)
-        method(1, 2, 3, 4)
-        self.assertRaises(AttributeError, method, 1, 2, a=3)
-        self.assertRaises(AttributeError, method, 1, 2, c=3)
-
-    def testKwargs(self):
-        method = mox.MockMethod('Kwargs', [], False, CheckCallTestClass.Kwargs,
-                                class_to_bind=CheckCallTestClass)
-        self.assertRaises(AttributeError, method)
-        method(1)
-        method(1, 2)
-        method(a=1, b=2)
-        method(b=2, a=1)
-        self.assertRaises(AttributeError, method, 1, 2, 3)
-        self.assertRaises(AttributeError, method, 1, 2, a=3)
-        method(1, 2, c=3)
-        method(a=1, b=2, c=3)
-        method(c=3, a=1, b=2)
-        method(a=1, b=2, c=3, d=4)
-        self.assertRaises(AttributeError, method, 1, 2, 3, 4)
-
-    def testArgsAndKwargs(self):
-        method = mox.MockMethod('ArgsAndKwargs', [], False,
-                                CheckCallTestClass.ArgsAndKwargs,
-                                class_to_bind=CheckCallTestClass)
-        self.assertRaises(AttributeError, method)
-        method(1)
-        method(1, 2)
-        method(1, 2, 3)
-        method(a=1)
-        method(1, b=2)
-        self.assertRaises(AttributeError, method, 1, a=2)
-        method(b=2, a=1)
-        method(c=3, b=2, a=1)
-        method(1, 2, c=3)
-
-
-class CheckCallTestClass(object):
-    def NoParameters(self):
-        pass
-
-    def OneParameter(self, a):
-        pass
-
-    def TwoParameters(self, a, b):
-        pass
-
-    def OneDefaultValue(self, a=1):
-        pass
-
-    def TwoDefaultValues(self, a, b, c=1, d=2):
-        pass
-
-    def Args(self, a, b, *args):
-        pass
-
-    def Kwargs(self, a, b=2, **kwargs):
-        pass
-
-    def ArgsAndKwargs(self, a, *args, **kwargs):
-        pass
-
-
-class MockObjectTest(testtools.TestCase):
-    """Verify that the MockObject class works as exepcted."""
-
-    def setUp(self):
-        super(MockObjectTest, self).setUp()
-        self.mock_object = mox.MockObject(TestClass)
-
-    def testSetupModeWithValidCall(self):
-        """Verify the mock object properly mocks a basic method call."""
-        self.mock_object.ValidCall()
-        self.assertTrue(len(self.mock_object._expected_calls_queue) == 1)
-
-    def testSetupModeWithInvalidCall(self):
-        """Rase UnknownMethodCallError for a non-member method call.
-        """
-        # Note: assertRaises does not catch exceptions thrown by MockObject's
-        # __getattr__
-        try:
-            self.mock_object.InvalidCall()
-            self.fail("No exception thrown, expected UnknownMethodCallError")
-        except mox.UnknownMethodCallError:
-            pass
-        except Exception:
-            self.fail("Wrong exception type thrown,"
-                      " expected UnknownMethodCallError")
-
-    def testReplayWithInvalidCall(self):
-        """Rase UnknownMethodCallError for a non-member method call.
-        """
-        self.mock_object.ValidCall()  # setup method call
-        self.mock_object._Replay()  # start replay mode
-        # Note: assertRaises does not catch exceptions thrown by MockObject's
-        # __getattr__
-        try:
-            self.mock_object.InvalidCall()
-            self.fail("No exception thrown, expected UnknownMethodCallError")
-        except mox.UnknownMethodCallError:
-            pass
-        except Exception:
-            self.fail("Wrong exception type thrown,"
-                      " expected UnknownMethodCallError")
-
-    def testIsInstance(self):
-        """Mock should be able to pass as an instance of the mocked class."""
-        self.assertTrue(isinstance(self.mock_object, TestClass))
-
-    def testFindValidMethods(self):
-        """Mock should be able to mock all public methods."""
-        self.assertTrue('ValidCall' in self.mock_object._known_methods)
-        self.assertTrue('OtherValidCall' in self.mock_object._known_methods)
-        self.assertTrue('MyClassMethod' in self.mock_object._known_methods)
-        self.assertTrue('MyStaticMethod' in self.mock_object._known_methods)
-        self.assertTrue('_ProtectedCall' in self.mock_object._known_methods)
-        self.assertTrue('__PrivateCall' not in self.mock_object._known_methods)
-        self.assertTrue(
-            '_TestClass__PrivateCall' in self.mock_object._known_methods)
-
-    def testFindsSuperclassMethods(self):
-        """Mock should be able to mock superclasses methods."""
-        self.mock_object = mox.MockObject(ChildClass)
-        self.assertTrue('ValidCall' in self.mock_object._known_methods)
-        self.assertTrue('OtherValidCall' in self.mock_object._known_methods)
-        self.assertTrue('MyClassMethod' in self.mock_object._known_methods)
-        self.assertTrue('ChildValidCall' in self.mock_object._known_methods)
-
-    def testAccessClassVariables(self):
-        """Class variables should be accessible through the mock."""
-        self.assertTrue('SOME_CLASS_VAR' in self.mock_object._known_vars)
-        self.assertTrue('_PROTECTED_CLASS_VAR' in self.mock_object._known_vars)
-        self.assertEqual('test_value', self.mock_object.SOME_CLASS_VAR)
-
-    def testEquals(self):
-        """A mock should be able to compare itself to another object."""
-        self.mock_object._Replay()
-        self.assertEqual(self.mock_object, self.mock_object)
-
-    def testEqualsMockFailure(self):
-        """Verify equals identifies unequal objects."""
-        self.mock_object.ValidCall()
-        self.mock_object._Replay()
-        self.assertNotEqual(self.mock_object, mox.MockObject(TestClass))
-
-    def testEqualsInstanceFailure(self):
-        """Verify equals identifies that objects are different instances."""
-        self.mock_object._Replay()
-        self.assertNotEqual(self.mock_object, TestClass())
-
-    def testNotEquals(self):
-        """Verify not equals works."""
-        self.mock_object._Replay()
-        self.assertFalse(self.mock_object != self.mock_object)
-
-    def testMockSetItem_ExpectedSetItem_Success(self):
-        """Test that __setitem__() gets mocked in Dummy.
-
-        In this test, _Verify() succeeds.
-        """
-        dummy = mox.MockObject(TestClass)
-        dummy['X'] = 'Y'
-
-        dummy._Replay()
-
-        dummy['X'] = 'Y'
-
-        dummy._Verify()
-
-    def testMockSetItem_ExpectedSetItem_NoSuccess(self):
-        """Test that __setitem__() gets mocked in Dummy.
-
-        In this test, _Verify() fails.
-        """
-        dummy = mox.MockObject(TestClass)
-        dummy['X'] = 'Y'
-
-        dummy._Replay()
-
-        # NOT doing dummy['X'] = 'Y'
-
-        self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify)
-
-    def testMockSetItem_ExpectedNoSetItem_Success(self):
-        """Test that __setitem__() gets mocked in Dummy."""
-        dummy = mox.MockObject(TestClass)
-        # NOT doing dummy['X'] = 'Y'
-
-        dummy._Replay()
-
-        def call():
-            dummy['X'] = 'Y'
-
-        self.assertRaises(mox.UnexpectedMethodCallError, call)
-
-    def testMockSetItem_ExpectedNoSetItem_NoSuccess(self):
-        """Test that __setitem__() gets mocked in Dummy.
-
-        In this test, _Verify() fails.
-        """
-        dummy = mox.MockObject(TestClass)
-        # NOT doing dummy['X'] = 'Y'
-
-        dummy._Replay()
-
-        # NOT doing dummy['X'] = 'Y'
-
-        dummy._Verify()
-
-    def testMockSetItem_ExpectedSetItem_NonmatchingParameters(self):
-        """Test that __setitem__() fails if other parameters are expected."""
-        dummy = mox.MockObject(TestClass)
-        dummy['X'] = 'Y'
-
-        dummy._Replay()
-
-        def call():
-            dummy['wrong'] = 'Y'
-
-        self.assertRaises(mox.UnexpectedMethodCallError, call)
-
-        dummy._Verify()
-
-    def testMockSetItem_WithSubClassOfNewStyleClass(self):
-        class NewStyleTestClass(object):
-            def __init__(self):
-                self.my_dict = {}
-
-            def __setitem__(self, key, value):
-                self.my_dict[key], value
-
-        class TestSubClass(NewStyleTestClass):
-            pass
-
-        dummy = mox.MockObject(TestSubClass)
-        dummy[1] = 2
-        dummy._Replay()
-        dummy[1] = 2
-        dummy._Verify()
-
-    def testMockGetItem_ExpectedGetItem_Success(self):
-        """Test that __getitem__() gets mocked in Dummy.
-
-        In this test, _Verify() succeeds.
-        """
-        dummy = mox.MockObject(TestClass)
-        dummy['X'].AndReturn('value')
-
-        dummy._Replay()
-
-        self.assertEqual(dummy['X'], 'value')
-
-        dummy._Verify()
-
-    def testMockGetItem_ExpectedGetItem_NoSuccess(self):
-        """Test that __getitem__() gets mocked in Dummy.
-
-        In this test, _Verify() fails.
-        """
-        dummy = mox.MockObject(TestClass)
-        dummy['X'].AndReturn('value')
-
-        dummy._Replay()
-
-        # NOT doing dummy['X']
-
-        self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify)
-
-    def testMockGetItem_ExpectedNoGetItem_NoSuccess(self):
-        """Test that __getitem__() gets mocked in Dummy."""
-        dummy = mox.MockObject(TestClass)
-        # NOT doing dummy['X']
-
-        dummy._Replay()
-
-        def call():
-            return dummy['X']
-
-        self.assertRaises(mox.UnexpectedMethodCallError, call)
-
-    def testMockGetItem_ExpectedGetItem_NonmatchingParameters(self):
-        """Test that __getitem__() fails if other parameters are expected."""
-        dummy = mox.MockObject(TestClass)
-        dummy['X'].AndReturn('value')
-
-        dummy._Replay()
-
-        def call():
-            return dummy['wrong']
-
-        self.assertRaises(mox.UnexpectedMethodCallError, call)
-
-        dummy._Verify()
-
-    def testMockGetItem_WithSubClassOfNewStyleClass(self):
-        class NewStyleTestClass(object):
-            def __getitem__(self, key):
-                return {1: '1', 2: '2'}[key]
-
-        class TestSubClass(NewStyleTestClass):
-            pass
-
-        dummy = mox.MockObject(TestSubClass)
-        dummy[1].AndReturn('3')
-
-        dummy._Replay()
-        self.assertEqual('3', dummy.__getitem__(1))
-        dummy._Verify()
-
-    def testMockIter_ExpectedIter_Success(self):
-        """Test that __iter__() gets mocked in Dummy.
-
-        In this test, _Verify() succeeds.
-        """
-        dummy = mox.MockObject(TestClass)
-        iter(dummy).AndReturn(iter(['X', 'Y']))
-
-        dummy._Replay()
-
-        self.assertEqual([x for x in dummy], ['X', 'Y'])
-
-        dummy._Verify()
-
-    def testMockContains_ExpectedContains_Success(self):
-        """Test that __contains__ gets mocked in Dummy.
-
-        In this test, _Verify() succeeds.
-        """
-        dummy = mox.MockObject(TestClass)
-        dummy.__contains__('X').AndReturn(True)
-
-        dummy._Replay()
-
-        self.assertTrue('X' in dummy)
-
-        dummy._Verify()
-
-    def testMockContains_ExpectedContains_NoSuccess(self):
-        """Test that __contains__() gets mocked in Dummy.
-
-        In this test, _Verify() fails.
-        """
-        dummy = mox.MockObject(TestClass)
-        dummy.__contains__('X').AndReturn('True')
-
-        dummy._Replay()
-
-        # NOT doing 'X' in dummy
-
-        self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify)
-
-    def testMockContains_ExpectedContains_NonmatchingParameter(self):
-        """Test that __contains__ fails if other parameters are expected."""
-        dummy = mox.MockObject(TestClass)
-        dummy.__contains__('X').AndReturn(True)
-
-        dummy._Replay()
-
-        def call():
-            return 'Y' in dummy
-
-        self.assertRaises(mox.UnexpectedMethodCallError, call)
-
-        dummy._Verify()
-
-    def testMockIter_ExpectedIter_NoSuccess(self):
-        """Test that __iter__() gets mocked in Dummy.
-
-        In this test, _Verify() fails.
-        """
-        dummy = mox.MockObject(TestClass)
-        iter(dummy).AndReturn(iter(['X', 'Y']))
-
-        dummy._Replay()
-
-        # NOT doing self.assertEqual([x for x in dummy], ['X', 'Y'])
-
-        self.assertRaises(mox.ExpectedMethodCallsError, dummy._Verify)
-
-    def testMockIter_ExpectedNoIter_NoSuccess(self):
-        """Test that __iter__() gets mocked in Dummy."""
-        dummy = mox.MockObject(TestClass)
-        # NOT doing iter(dummy)
-
-        dummy._Replay()
-
-        def call():
-            return [x for x in dummy]
-        self.assertRaises(mox.UnexpectedMethodCallError, call)
-
-    def testMockIter_ExpectedGetItem_Success(self):
-        """Test that __iter__() gets mocked in Dummy using getitem."""
-        dummy = mox.MockObject(SubscribtableNonIterableClass)
-        dummy[0].AndReturn('a')
-        dummy[1].AndReturn('b')
-        dummy[2].AndRaise(IndexError)
-
-        dummy._Replay()
-        self.assertEqual(['a', 'b'], [x for x in dummy])
-        dummy._Verify()
-
-    def testMockIter_ExpectedNoGetItem_NoSuccess(self):
-        """Test that __iter__() gets mocked in Dummy using getitem."""
-        dummy = mox.MockObject(SubscribtableNonIterableClass)
-        # NOT doing dummy[index]
-
-        dummy._Replay()
-        function = lambda: [x for x in dummy]
-        self.assertRaises(mox.UnexpectedMethodCallError, function)
-
-    def testMockGetIter_WithSubClassOfNewStyleClass(self):
-        class NewStyleTestClass(object):
-            def __iter__(self):
-                return iter([1, 2, 3])
-
-        class TestSubClass(NewStyleTestClass):
-            pass
-
-        dummy = mox.MockObject(TestSubClass)
-        iter(dummy).AndReturn(iter(['a', 'b']))
-        dummy._Replay()
-        self.assertEqual(['a', 'b'], [x for x in dummy])
-        dummy._Verify()
-
-    def testInstantiationWithAdditionalAttributes(self):
-        mock_object = mox.MockObject(TestClass, attrs={"attr1": "value"})
-        self.assertEqual(mock_object.attr1, "value")
-
-    def testCantOverrideMethodsWithAttributes(self):
-        self.assertRaises(ValueError, mox.MockObject, TestClass,
-                          attrs={"ValidCall": "value"})
-
-    def testCantMockNonPublicAttributes(self):
-        self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass,
-                          attrs={"_protected": "value"})
-        self.assertRaises(mox.PrivateAttributeError, mox.MockObject, TestClass,
-                          attrs={"__private": "value"})
-
-
-class MoxTest(testtools.TestCase):
-    """Verify Mox works correctly."""
-
-    def setUp(self):
-        super(MoxTest, self).setUp()
-        self.mox = mox.Mox()
-
-    def testCreateObject(self):
-        """Mox should create a mock object."""
-        self.mox.CreateMock(TestClass)
-
-    def testVerifyObjectWithCompleteReplay(self):
-        """Mox should replay and verify all objects it created."""
-        mock_obj = self.mox.CreateMock(TestClass)
-        mock_obj.ValidCall()
-        mock_obj.ValidCallWithArgs(mox.IsA(TestClass))
-        self.mox.ReplayAll()
-        mock_obj.ValidCall()
-        mock_obj.ValidCallWithArgs(TestClass("some_value"))
-        self.mox.VerifyAll()
-
-    def testVerifyObjectWithIncompleteReplay(self):
-        """Mox should raise an exception if a mock didn't replay completely."""
-        mock_obj = self.mox.CreateMock(TestClass)
-        mock_obj.ValidCall()
-        self.mox.ReplayAll()
-        # ValidCall() is never made
-        self.assertRaises(mox.ExpectedMethodCallsError, self.mox.VerifyAll)
-
-    def testEntireWorkflow(self):
-        """Test the whole work flow."""
-        mock_obj = self.mox.CreateMock(TestClass)
-        mock_obj.ValidCall().AndReturn("yes")
-        self.mox.ReplayAll()
-
-        ret_val = mock_obj.ValidCall()
-        self.assertEqual("yes", ret_val)
-        self.mox.VerifyAll()
-
-    def testSignatureMatchingWithComparatorAsFirstArg(self):
-        """Test that the first argument can be a comparator."""
-
-        def VerifyLen(val):
-            """This will raise an exception when not given a list.
-
-            This exception will be raised when trying to infer/validate the
-            method signature.
-            """
-            return len(val) != 1
-
-        mock_obj = self.mox.CreateMock(TestClass)
-        # This intentionally does not name the 'nine' param so it triggers
-        # deeper inspection.
-        mock_obj.MethodWithArgs(mox.Func(VerifyLen), mox.IgnoreArg(), None)
-        self.mox.ReplayAll()
-
-        mock_obj.MethodWithArgs([1, 2], "foo", None)
-
-        self.mox.VerifyAll()
-
-    def testCallableObject(self):
-        """Test recording calls to a callable object works."""
-        mock_obj = self.mox.CreateMock(CallableClass)
-        mock_obj("foo").AndReturn("qux")
-        self.mox.ReplayAll()
-
-        ret_val = mock_obj("foo")
-        self.assertEqual("qux", ret_val)
-        self.mox.VerifyAll()
-
-    def testInheritedCallableObject(self):
-        """Recording calls to an object inheriting from a callable object."""
-        mock_obj = self.mox.CreateMock(InheritsFromCallable)
-        mock_obj("foo").AndReturn("qux")
-        self.mox.ReplayAll()
-
-        ret_val = mock_obj("foo")
-        self.assertEqual("qux", ret_val)
-        self.mox.VerifyAll()
-
-    def testCallOnNonCallableObject(self):
-        """Test that you cannot call a non-callable object."""
-        mock_obj = self.mox.CreateMock("string is not callable")
-        self.assertRaises(TypeError, mock_obj)
-
-    def testCallableObjectWithBadCall(self):
-        """Test verifying calls to a callable object works."""
-        mock_obj = self.mox.CreateMock(CallableClass)
-        mock_obj("foo").AndReturn("qux")
-        self.mox.ReplayAll()
-
-        self.assertRaises(mox.UnexpectedMethodCallError, mock_obj, "ZOOBAZ")
-
-    def testCallableObjectVerifiesSignature(self):
-        mock_obj = self.mox.CreateMock(CallableClass)
-        # Too many arguments
-        self.assertRaises(AttributeError, mock_obj, "foo", "bar")
-
-    def testUnorderedGroup(self):
-        """Test that using one unordered group works."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Method(1).InAnyOrder()
-        mock_obj.Method(2).InAnyOrder()
-        self.mox.ReplayAll()
-
-        mock_obj.Method(2)
-        mock_obj.Method(1)
-
-        self.mox.VerifyAll()
-
-    def testUnorderedGroupsInline(self):
-        """Unordered groups should work in the context of ordered calls."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(1).InAnyOrder()
-        mock_obj.Method(2).InAnyOrder()
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        mock_obj.Method(2)
-        mock_obj.Method(1)
-        mock_obj.Close()
-
-        self.mox.VerifyAll()
-
-    def testMultipleUnorderdGroups(self):
-        """Multiple unoreded groups should work."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Method(1).InAnyOrder()
-        mock_obj.Method(2).InAnyOrder()
-        mock_obj.Foo().InAnyOrder('group2')
-        mock_obj.Bar().InAnyOrder('group2')
-        self.mox.ReplayAll()
-
-        mock_obj.Method(2)
-        mock_obj.Method(1)
-        mock_obj.Bar()
-        mock_obj.Foo()
-
-        self.mox.VerifyAll()
-
-    def testMultipleUnorderdGroupsOutOfOrder(self):
-        """Multiple unordered groups should maintain external order"""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Method(1).InAnyOrder()
-        mock_obj.Method(2).InAnyOrder()
-        mock_obj.Foo().InAnyOrder('group2')
-        mock_obj.Bar().InAnyOrder('group2')
-        self.mox.ReplayAll()
-
-        mock_obj.Method(2)
-        self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Bar)
-
-    def testUnorderedGroupWithReturnValue(self):
-        """Unordered groups should work with return values."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(1).InAnyOrder().AndReturn(9)
-        mock_obj.Method(2).InAnyOrder().AndReturn(10)
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        actual_two = mock_obj.Method(2)
-        actual_one = mock_obj.Method(1)
-        mock_obj.Close()
-
-        self.assertEqual(9, actual_one)
-        self.assertEqual(10, actual_two)
-
-        self.mox.VerifyAll()
-
-    def testUnorderedGroupWithComparator(self):
-        """Unordered groups should work with comparators."""
-
-        def VerifyOne(cmd):
-            if not isinstance(cmd, str):
-                self.fail('Unexpected type passed to comparator: ' + str(cmd))
-            return cmd == 'test'
-
-        def VerifyTwo(cmd):
-            return True
-
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Foo(['test'], mox.Func(VerifyOne), bar=1).InAnyOrder().\
-            AndReturn('yes test')
-        mock_obj.Foo(['test'], mox.Func(VerifyTwo), bar=1).InAnyOrder().\
-            AndReturn('anything')
-
-        self.mox.ReplayAll()
-
-        mock_obj.Foo(['test'], 'anything', bar=1)
-        mock_obj.Foo(['test'], 'test', bar=1)
-
-        self.mox.VerifyAll()
-
-    def testMultipleTimes(self):
-        """Test if MultipleTimesGroup works."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Method(1).MultipleTimes().AndReturn(9)
-        mock_obj.Method(2).AndReturn(10)
-        mock_obj.Method(3).MultipleTimes().AndReturn(42)
-        self.mox.ReplayAll()
-
-        actual_one = mock_obj.Method(1)
-        second_one = mock_obj.Method(1)    # This tests MultipleTimes.
-        actual_two = mock_obj.Method(2)
-        actual_three = mock_obj.Method(3)
-        mock_obj.Method(3)
-        mock_obj.Method(3)
-
-        self.mox.VerifyAll()
-
-        self.assertEqual(9, actual_one)
-        # Repeated calls should return same number.
-        self.assertEqual(9, second_one)
-        self.assertEqual(10, actual_two)
-        self.assertEqual(42, actual_three)
-
-    def testMultipleTimesUsingIsAParameter(self):
-        """Test if MultipleTimesGroup works with a IsA parameter."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(mox.IsA(str)).MultipleTimes("IsA").AndReturn(9)
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        actual_one = mock_obj.Method("1")
-        second_one = mock_obj.Method("2")    # This tests MultipleTimes.
-        mock_obj.Close()
-
-        self.mox.VerifyAll()
-
-        self.assertEqual(9, actual_one)
-        # Repeated calls should return same number.
-        self.assertEqual(9, second_one)
-
-    def testMutlipleTimesUsingFunc(self):
-        """Test that the Func is not evaluated more times than necessary.
-
-        If a Func() has side effects, it can cause a passing test to fail.
-        """
-
-        self.counter = 0
-
-        def MyFunc(actual_str):
-            """Increment the counter if actual_str == 'foo'."""
-            if actual_str == 'foo':
-                self.counter += 1
-            return True
-
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(mox.Func(MyFunc)).MultipleTimes()
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        mock_obj.Method('foo')
-        mock_obj.Method('foo')
-        mock_obj.Method('not-foo')
-        mock_obj.Close()
-
-        self.mox.VerifyAll()
-
-        self.assertEqual(2, self.counter)
-
-    def testMultipleTimesThreeMethods(self):
-        """Test if MultipleTimesGroup works with three or more methods."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(1).MultipleTimes().AndReturn(9)
-        mock_obj.Method(2).MultipleTimes().AndReturn(8)
-        mock_obj.Method(3).MultipleTimes().AndReturn(7)
-        mock_obj.Method(4).AndReturn(10)
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        actual_three = mock_obj.Method(3)
-        mock_obj.Method(1)
-        actual_two = mock_obj.Method(2)
-        mock_obj.Method(3)
-        actual_one = mock_obj.Method(1)
-        actual_four = mock_obj.Method(4)
-        mock_obj.Close()
-
-        self.assertEqual(9, actual_one)
-        self.assertEqual(8, actual_two)
-        self.assertEqual(7, actual_three)
-        self.assertEqual(10, actual_four)
-
-        self.mox.VerifyAll()
-
-    def testMultipleTimesMissingOne(self):
-        """Test if MultipleTimesGroup fails if one method is missing."""
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(1).MultipleTimes().AndReturn(9)
-        mock_obj.Method(2).MultipleTimes().AndReturn(8)
-        mock_obj.Method(3).MultipleTimes().AndReturn(7)
-        mock_obj.Method(4).AndReturn(10)
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        mock_obj.Method(3)
-        mock_obj.Method(2)
-        mock_obj.Method(3)
-        mock_obj.Method(3)
-        mock_obj.Method(2)
-
-        self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 4)
-
-    def testMultipleTimesTwoGroups(self):
-        """Test if MultipleTimesGroup works with a group after a
-        MultipleTimesGroup.
-        """
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(1).MultipleTimes().AndReturn(9)
-        mock_obj.Method(3).MultipleTimes("nr2").AndReturn(42)
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        actual_one = mock_obj.Method(1)
-        mock_obj.Method(1)
-        actual_three = mock_obj.Method(3)
-        mock_obj.Method(3)
-        mock_obj.Close()
-
-        self.assertEqual(9, actual_one)
-        self.assertEqual(42, actual_three)
-
-        self.mox.VerifyAll()
-
-    def testMultipleTimesTwoGroupsFailure(self):
-        """Test if MultipleTimesGroup fails with a group after a
-        MultipleTimesGroup.
-        """
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.Open()
-        mock_obj.Method(1).MultipleTimes().AndReturn(9)
-        mock_obj.Method(3).MultipleTimes("nr2").AndReturn(42)
-        mock_obj.Close()
-        self.mox.ReplayAll()
-
-        mock_obj.Open()
-        mock_obj.Method(1)
-        mock_obj.Method(1)
-        mock_obj.Method(3)
-
-        self.assertRaises(mox.UnexpectedMethodCallError, mock_obj.Method, 1)
-
-    def testWithSideEffects(self):
-        """Test side effect operations actually modify their target objects."""
-        def modifier(mutable_list):
-            mutable_list[0] = 'mutated'
-        mock_obj = self.mox.CreateMockAnything()
-        mock_obj.ConfigureInOutParameter(
-            ['original']).WithSideEffects(modifier)
-        mock_obj.WorkWithParameter(['mutated'])
-        self.mox.ReplayAll()
-
-        local_list = ['original']
-        mock_obj.ConfigureInOutParameter(local_list)
-        mock_obj.WorkWithParameter(local_list)
-
-        self.mox.VerifyAll()
-
-    def testWithSideEffectsException(self):
-        """Test side effect operations actually modify their target objects."""
-        class TestException(Exception):
-            pass
-
-        def modifier(mutable_list):
-            mutable_list[0] = 'mutated'
-        mock_obj = self.mox.CreateMockAnything()
-        method = mock_obj.ConfigureInOutParameter(['original'])
-        method.WithSideEffects(modifier).AndRaise(TestException('exception'))
-        mock_obj.WorkWithParameter(['mutated'])
-        self.mox.ReplayAll()
-
-        local_list = ['original']
-        self.assertRaises(TestException,
-                          mock_obj.ConfigureInOutParameter,
-                          local_list)
-        mock_obj.WorkWithParameter(local_list)
-
-        self.mox.VerifyAll()
-
-    def testStubOutMethod(self):
-        """Test that a method is replaced with a MockObject."""
-        test_obj = TestClass()
-        method_type = type(test_obj.OtherValidCall)
-        # Replace OtherValidCall with a mock.
-        self.mox.StubOutWithMock(test_obj, 'OtherValidCall')
-        self.assertTrue(isinstance(test_obj.OtherValidCall, mox.MockObject))
-        self.assertFalse(type(test_obj.OtherValidCall) is method_type)
-
-        test_obj.OtherValidCall().AndReturn('foo')
-        self.mox.ReplayAll()
-
-        actual = test_obj.OtherValidCall()
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertEqual('foo', actual)
-        self.assertTrue(type(test_obj.OtherValidCall) is method_type)
-
-    def testStubOutMethod_Unbound_Comparator(self):
-        instance = TestClass()
-        self.mox.StubOutWithMock(TestClass, 'OtherValidCall')
-
-        TestClass.OtherValidCall(mox.IgnoreArg()).AndReturn('foo')
-        self.mox.ReplayAll()
-
-        actual = TestClass.OtherValidCall(instance)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertEqual('foo', actual)
-
-    def testStubOutMethod_Unbound_Subclass_Comparator(self):
-        self.mox.StubOutWithMock(
-            mox_helper.TestClassFromAnotherModule, 'Value')
-        mox_helper.TestClassFromAnotherModule.Value(
-            mox.IsA(mox_helper.ChildClassFromAnotherModule)).AndReturn('foo')
-        self.mox.ReplayAll()
-
-        instance = mox_helper.ChildClassFromAnotherModule()
-        actual = mox_helper.TestClassFromAnotherModule.Value(instance)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertEqual('foo', actual)
-
-    def testStubOuMethod_Unbound_WithOptionalParams(self):
-        self.mox = mox.Mox()
-        self.mox.StubOutWithMock(TestClass, 'OptionalArgs')
-        TestClass.OptionalArgs(mox.IgnoreArg(), foo=2)
-        self.mox.ReplayAll()
-
-        t = TestClass()
-        TestClass.OptionalArgs(t, foo=2)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Unbound_ActualInstance(self):
-        instance = TestClass()
-        self.mox.StubOutWithMock(TestClass, 'OtherValidCall')
-
-        TestClass.OtherValidCall(instance).AndReturn('foo')
-        self.mox.ReplayAll()
-
-        actual = TestClass.OtherValidCall(instance)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertEqual('foo', actual)
-
-    def testStubOutMethod_Unbound_DifferentInstance(self):
-        instance = TestClass()
-        self.mox.StubOutWithMock(TestClass, 'OtherValidCall')
-
-        TestClass.OtherValidCall(instance).AndReturn('foo')
-        self.mox.ReplayAll()
-
-        # This should fail, since the instances are different
-        self.assertRaises(mox.UnexpectedMethodCallError,
-                          TestClass.OtherValidCall, "wrong self")
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Unbound_NamedUsingPositional(self):
-        """Check positional parameters can be matched to keyword arguments."""
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, 'NamedParams')
-        instance = mox_helper.ExampleClass()
-        mox_helper.ExampleClass.NamedParams(instance, 'foo', baz=None)
-        self.mox.ReplayAll()
-
-        mox_helper.ExampleClass.NamedParams(instance, 'foo', baz=None)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Unbound_NamedUsingPositional_SomePositional(self):
-        """Check positional parameters can be matched to keyword arguments."""
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, 'TestMethod')
-        instance = mox_helper.ExampleClass()
-        mox_helper.ExampleClass.TestMethod(instance, 'one', 'two', 'nine')
-        self.mox.ReplayAll()
-
-        mox_helper.ExampleClass.TestMethod(instance, 'one', 'two', 'nine')
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Unbound_SpecialArgs(self):
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, 'SpecialArgs')
-        instance = mox_helper.ExampleClass()
-        mox_helper.ExampleClass.SpecialArgs(instance, 'foo', None, bar='bar')
-        self.mox.ReplayAll()
-
-        mox_helper.ExampleClass.SpecialArgs(instance, 'foo', None, bar='bar')
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Bound_SimpleTest(self):
-        t = self.mox.CreateMock(TestClass)
-
-        t.MethodWithArgs(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn('foo')
-        self.mox.ReplayAll()
-
-        actual = t.MethodWithArgs(None, None)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertEqual('foo', actual)
-
-    def testStubOutMethod_Bound_NamedUsingPositional(self):
-        """Check positional parameters can be matched to keyword arguments."""
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, 'NamedParams')
-        instance = mox_helper.ExampleClass()
-        instance.NamedParams('foo', baz=None)
-        self.mox.ReplayAll()
-
-        instance.NamedParams('foo', baz=None)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Bound_NamedUsingPositional_SomePositional(self):
-        """Check positional parameters can be matched to keyword arguments."""
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, 'TestMethod')
-        instance = mox_helper.ExampleClass()
-        instance.TestMethod(instance, 'one', 'two', 'nine')
-        self.mox.ReplayAll()
-
-        instance.TestMethod(instance, 'one', 'two', 'nine')
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Bound_SpecialArgs(self):
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, 'SpecialArgs')
-        instance = mox_helper.ExampleClass()
-        instance.SpecialArgs(instance, 'foo', None, bar='bar')
-        self.mox.ReplayAll()
-
-        instance.SpecialArgs(instance, 'foo', None, bar='bar')
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOutMethod_Func_PropgatesExceptions(self):
-        """Errors in Func comparator should propagate to the calling method."""
-        class TestException(Exception):
-            pass
-
-        def raiseExceptionOnNotOne(value):
-            if value == 1:
-                return True
-            else:
-                raise TestException
-
-        test_obj = TestClass()
-        self.mox.StubOutWithMock(test_obj, 'MethodWithArgs')
-        test_obj.MethodWithArgs(
-            mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1)
-        test_obj.MethodWithArgs(
-            mox.IgnoreArg(), mox.Func(raiseExceptionOnNotOne)).AndReturn(1)
-        self.mox.ReplayAll()
-
-        self.assertEqual(test_obj.MethodWithArgs('ignored', 1), 1)
-        self.assertRaises(TestException,
-                          test_obj.MethodWithArgs, 'ignored', 2)
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    def testStubOut_SignatureMatching_init_(self):
-        self.mox.StubOutWithMock(mox_helper.ExampleClass, '__init__')
-        mox_helper.ExampleClass.__init__(mox.IgnoreArg())
-        self.mox.ReplayAll()
-
-        # Create an instance of a child class, which calls the parent
-        # __init__
-        mox_helper.ChildExampleClass()
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-    # FIXME(dhellmann): Skip this test until someone can debug why it
-    # fails on python 3.4.
-
-    @testtools.skipIf(six.PY3, "This test needs to be fixed for python 3")
-    def testStubOutClass_OldStyle(self):
-        """Test a mocked class whose __init__ returns a Mock."""
-        self.mox.StubOutWithMock(mox_helper, 'TestClassFromAnotherModule')
-        self.assertTrue(isinstance(mox_helper.TestClassFromAnotherModule,
-                                   mox.MockObject))
-
-        mock_instance = self.mox.CreateMock(
-            mox_helper.TestClassFromAnotherModule)
-        mox_helper.TestClassFromAnotherModule().AndReturn(mock_instance)
-        mock_instance.Value().AndReturn('mock instance')
-
-        self.mox.ReplayAll()
-
-        a_mock = mox_helper.TestClassFromAnotherModule()
-        actual = a_mock.Value()
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertEqual('mock instance', actual)
-
-    def testStubOutClass(self):
-        self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass')
-
-        # Instance one
-        mock_one = mox_helper.CallableClass(1, 2)
-        mock_one.Value().AndReturn('mock')
-
-        # Instance two
-        mock_two = mox_helper.CallableClass(8, 9)
-        mock_two('one').AndReturn('called mock')
-
-        self.mox.ReplayAll()
-
-        one = mox_helper.CallableClass(1, 2)
-        actual_one = one.Value()
-
-        two = mox_helper.CallableClass(8, 9)
-        actual_two = two('one')
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-
-        # Verify the correct mocks were returned
-        self.assertEqual(mock_one, one)
-        self.assertEqual(mock_two, two)
-
-        # Verify
-        self.assertEqual('mock', actual_one)
-        self.assertEqual('called mock', actual_two)
-
-    def testStubOutClass_NotAClass(self):
-        self.assertRaises(TypeError, self.mox.StubOutClassWithMocks,
-                          mox_helper, 'MyTestFunction')
-
-    def testStubOutClassNotEnoughCreated(self):
-        self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass')
-
-        mox_helper.CallableClass(1, 2)
-        mox_helper.CallableClass(8, 9)
-
-        self.mox.ReplayAll()
-        mox_helper.CallableClass(1, 2)
-
-        self.assertRaises(mox.ExpectedMockCreationError, self.mox.VerifyAll)
-        self.mox.UnsetStubs()
-
-    def testStubOutClassWrongSignature(self):
-        self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass')
-
-        self.assertRaises(AttributeError, mox_helper.CallableClass)
-
-        self.mox.UnsetStubs()
-
-    def testStubOutClassWrongParameters(self):
-        self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass')
-
-        mox_helper.CallableClass(1, 2)
-
-        self.mox.ReplayAll()
-
-        self.assertRaises(mox.UnexpectedMethodCallError,
-                          mox_helper.CallableClass, 8, 9)
-        self.mox.UnsetStubs()
-
-    def testStubOutClassTooManyCreated(self):
-        self.mox.StubOutClassWithMocks(mox_helper, 'CallableClass')
-
-        mox_helper.CallableClass(1, 2)
-
-        self.mox.ReplayAll()
-        mox_helper.CallableClass(1, 2)
-        self.assertRaises(mox.UnexpectedMockCreationError,
-                          mox_helper.CallableClass, 8, 9)
-
-        self.mox.UnsetStubs()
-
-    def testWarnsUserIfMockingMock(self):
-        """Test that user is warned if they try to stub out a MockAnything."""
-        self.mox.StubOutWithMock(TestClass, 'MyStaticMethod')
-        self.assertRaises(TypeError, self.mox.StubOutWithMock, TestClass,
-                          'MyStaticMethod')
-
-    def testStubOutFirstClassMethodVerifiesSignature(self):
-        self.mox.StubOutWithMock(mox_helper, 'MyTestFunction')
-
-        # Wrong number of arguments
-        self.assertRaises(AttributeError, mox_helper.MyTestFunction, 1)
-        self.mox.UnsetStubs()
-
-    def _testMethodSignatureVerification(self, stubClass):
-        # If stubClass is true, the test is run against an a stubbed out class,
-        # else the test is run against a stubbed out instance.
-        if stubClass:
-            self.mox.StubOutWithMock(mox_helper.ExampleClass, "TestMethod")
-            obj = mox_helper.ExampleClass()
-        else:
-            obj = mox_helper.ExampleClass()
-            self.mox.StubOutWithMock(mox_helper.ExampleClass, "TestMethod")
-        self.assertRaises(AttributeError, obj.TestMethod)
-        self.assertRaises(AttributeError, obj.TestMethod, 1)
-        self.assertRaises(AttributeError, obj.TestMethod, nine=2)
-        obj.TestMethod(1, 2)
-        obj.TestMethod(1, 2, 3)
-        obj.TestMethod(1, 2, nine=3)
-        self.assertRaises(AttributeError, obj.TestMethod, 1, 2, 3, 4)
-        self.mox.UnsetStubs()
-
-    def testStubOutClassMethodVerifiesSignature(self):
-        self._testMethodSignatureVerification(stubClass=True)
-
-    def testStubOutObjectMethodVerifiesSignature(self):
-        self._testMethodSignatureVerification(stubClass=False)
-
-    def testStubOutObject(self):
-        """Test than object is replaced with a Mock."""
-
-        class Foo(object):
-            def __init__(self):
-                self.obj = TestClass()
-
-        foo = Foo()
-        self.mox.StubOutWithMock(foo, "obj")
-        self.assertTrue(isinstance(foo.obj, mox.MockObject))
-        foo.obj.ValidCall()
-        self.mox.ReplayAll()
-
-        foo.obj.ValidCall()
-
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()
-        self.assertFalse(isinstance(foo.obj, mox.MockObject))
-
-    def testForgotReplayHelpfulMessage(self):
-        """If there is an AttributeError on a MockMethod, give helpful msg."""
-        foo = self.mox.CreateMockAnything()
-        bar = self.mox.CreateMockAnything()
-        foo.GetBar().AndReturn(bar)
-        bar.ShowMeTheMoney()
-        # Forgot to replay!
-        try:
-            foo.GetBar().ShowMeTheMoney()
-        except AttributeError as e:
-            self.assertEqual(
-                'MockMethod has no attribute "ShowMeTheMoney". '
-                'Did you remember to put your mocks in replay mode?', str(e))
-
-
-class ReplayTest(testtools.TestCase):
-    """Verify Replay works properly."""
-
-    def testReplay(self):
-        """Replay should put objects into replay mode."""
-        mock_obj = mox.MockObject(TestClass)
-        self.assertFalse(mock_obj._replay_mode)
-        mox.Replay(mock_obj)
-        self.assertTrue(mock_obj._replay_mode)
-
-
-class MoxTestBaseTest(testtools.TestCase):
-    """Verify that all tests in class derived from MoxTestBase are wrapped."""
-
-    def setUp(self):
-        super(MoxTestBaseTest, self).setUp()
-        self.mox = mox.Mox()
-        self.addCleanup(self.mox.UnsetStubs)
-        self.test_mox = mox.Mox()
-        self.addCleanup(self.test_mox.UnsetStubs)
-        self.test_stubs = mox.stubout.StubOutForTesting()
-        self.addCleanup(self.test_stubs.UnsetAll)
-        self.addCleanup(self.test_stubs.SmartUnsetAll)
-        self.result = testtools.TestResult()
-
-    def _setUpTestClass(self):
-        """Replacement for setUp in the test class instance.
-
-        Assigns a mox.Mox instance as the mox attribute of the test instance.
-        Replacement Mox instance is under our control before setUp is called
-        in the test class instance.
-        """
-        self.test.mox = self.test_mox
-        self.test.stubs = self.test_stubs
-
-    def _CreateTest(self, test_name):
-        """Create a test from our example mox class.
-
-        The created test instance is assigned to this instances test attribute.
-        """
-        self.test = mox_helper.ExampleMoxTest(test_name)
-        self.mox.stubs.Set(self.test, 'setUp', self._setUpTestClass)
-
-    def _VerifySuccess(self):
-        """Run the checks to confirm test method completed successfully."""
-        self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs')
-        self.mox.StubOutWithMock(self.test_mox, 'VerifyAll')
-        self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll')
-        self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll')
-        self.test_mox.UnsetStubs()
-        self.test_mox.VerifyAll()
-        self.test_stubs.UnsetAll()
-        self.test_stubs.SmartUnsetAll()
-        self.mox.ReplayAll()
-        self.test.run(result=self.result)
-        self.assertTrue(self.result.wasSuccessful())
-        self.mox.VerifyAll()
-        self.mox.UnsetStubs()    # Needed to call the real VerifyAll() below.
-        self.test_mox.VerifyAll()
-
-    def testSuccess(self):
-        """Successful test method execution test."""
-        self._CreateTest('testSuccess')
-        self._VerifySuccess()
-
-    def testSuccessNoMocks(self):
-        """testSuccess() unsets all the mocks. Vverify they've been unset."""
-        self._CreateTest('testSuccess')
-        self.test.run(result=self.result)
-        self.assertTrue(self.result.wasSuccessful())
-        self.assertEqual(OS_LISTDIR, mox_helper.os.listdir)
-
-    def testStubs(self):
-        """Test that "self.stubs" is provided as is useful."""
-        self._CreateTest('testHasStubs')
-        self._VerifySuccess()
-
-    def testStubsNoMocks(self):
-        """Let testHasStubs() unset the stubs by itself."""
-        self._CreateTest('testHasStubs')
-        self.test.run(result=self.result)
-        self.assertTrue(self.result.wasSuccessful())
-        self.assertEqual(OS_LISTDIR, mox_helper.os.listdir)
-
-    def testExpectedNotCalled(self):
-        """Stubbed out method is not called."""
-        self._CreateTest('testExpectedNotCalled')
-        self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs')
-        self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll')
-        self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll')
-        # Don't stub out VerifyAll - that's what causes the test to fail
-        self.test_mox.UnsetStubs()
-        self.test_stubs.UnsetAll()
-        self.test_stubs.SmartUnsetAll()
-        self.mox.ReplayAll()
-        self.test.run(result=self.result)
-        self.assertFalse(self.result.wasSuccessful())
-        self.mox.VerifyAll()
-
-    def testExpectedNotCalledNoMocks(self):
-        """Let testExpectedNotCalled() unset all the mocks by itself."""
-        self._CreateTest('testExpectedNotCalled')
-        self.test.run(result=self.result)
-        self.assertFalse(self.result.wasSuccessful())
-        self.assertEqual(OS_LISTDIR, mox_helper.os.listdir)
-
-    def testUnexpectedCall(self):
-        """Stubbed out method is called with unexpected arguments."""
-        self._CreateTest('testUnexpectedCall')
-        self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs')
-        self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll')
-        self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll')
-        # Ensure no calls are made to VerifyAll()
-        self.mox.StubOutWithMock(self.test_mox, 'VerifyAll')
-        self.test_mox.UnsetStubs()
-        self.test_stubs.UnsetAll()
-        self.test_stubs.SmartUnsetAll()
-        self.mox.ReplayAll()
-        self.test.run(result=self.result)
-        self.assertFalse(self.result.wasSuccessful())
-        self.mox.VerifyAll()
-
-    def testFailure(self):
-        """Failing assertion in test method."""
-        self._CreateTest('testFailure')
-        self.mox.StubOutWithMock(self.test_mox, 'UnsetStubs')
-        self.mox.StubOutWithMock(self.test_stubs, 'UnsetAll')
-        self.mox.StubOutWithMock(self.test_stubs, 'SmartUnsetAll')
-        # Ensure no calls are made to VerifyAll()
-        self.mox.StubOutWithMock(self.test_mox, 'VerifyAll')
-        self.test_mox.UnsetStubs()
-        self.test_stubs.UnsetAll()
-        self.test_stubs.SmartUnsetAll()
-        self.mox.ReplayAll()
-        self.test.run(result=self.result)
-        self.assertFalse(self.result.wasSuccessful())
-        self.mox.VerifyAll()
-
-    def testMixin(self):
-        """Run test from mix-in test class, ensure it passes."""
-        self._CreateTest('testStat')
-        self._VerifySuccess()
-
-    def testMixinAgain(self):
-        """Run same test as above but from the current test class.
-
-        Ensures metaclass properly wrapped test methods from all base classes.
-        If unsetting of stubs doesn't happen, this will fail.
-        """
-        self._CreateTest('testStatOther')
-        self._VerifySuccess()
-
-
-class VerifyTest(testtools.TestCase):
-    """Verify Verify works properly."""
-
-    def testVerify(self):
-        """Verify should be called for all objects.
-
-        Should throw an exception because the expected behavior did not occur.
-        """
-        mock_obj = mox.MockObject(TestClass)
-        mock_obj.ValidCall()
-        mock_obj._Replay()
-        self.assertRaises(mox.ExpectedMethodCallsError, mox.Verify, mock_obj)
-
-
-class ResetTest(testtools.TestCase):
-    """Verify Reset works properly."""
-
-    def testReset(self):
-        """Should empty all queues and put mocks in record mode."""
-        mock_obj = mox.MockObject(TestClass)
-        mock_obj.ValidCall()
-        self.assertFalse(mock_obj._replay_mode)
-        mock_obj._Replay()
-        self.assertTrue(mock_obj._replay_mode)
-        self.assertEqual(1, len(mock_obj._expected_calls_queue))
-
-        mox.Reset(mock_obj)
-        self.assertFalse(mock_obj._replay_mode)
-        self.assertEqual(0, len(mock_obj._expected_calls_queue))
-
-
-class MyTestCase(testtools.TestCase):
-    """Simulate the use of a fake wrapper around Python's unittest library."""
-
-    def setUp(self):
-        super(MyTestCase, self).setUp()
-        self.critical_variable = 42
-        self.another_critical_variable = 42
-
-    def testMethodOverride(self):
-        """Should be properly overriden in a derived class."""
-        self.assertEqual(42, self.another_critical_variable)
-        self.another_critical_variable += 1
-
-
-class MoxTestBaseMultipleInheritanceTest(mox.MoxTestBase, MyTestCase):
-    """Test that multiple inheritance can be used with MoxTestBase."""
-
-    def setUp(self):
-        super(MoxTestBaseMultipleInheritanceTest, self).setUp()
-        self.another_critical_variable = 99
-
-    def testMultipleInheritance(self):
-        """Should be able to access members created by all parent setUp()."""
-        self.assertTrue(isinstance(self.mox, mox.Mox))
-        self.assertEqual(42, self.critical_variable)
-
-    def testMethodOverride(self):
-        """Should run before MyTestCase.testMethodOverride."""
-        self.assertEqual(99, self.another_critical_variable)
-        self.another_critical_variable = 42
-        super(MoxTestBaseMultipleInheritanceTest, self).testMethodOverride()
-        self.assertEqual(43, self.another_critical_variable)
-
-
-class MoxTestDontMockProperties(MoxTestBaseTest):
-        def testPropertiesArentMocked(self):
-                mock_class = self.mox.CreateMock(ClassWithProperties)
-                self.assertRaises(mox.UnknownMethodCallError,
-                                  lambda: mock_class.prop_attr)
-
-
-class TestClass(object):
-    """This class is used only for testing the mock framework."""
-
-    SOME_CLASS_VAR = "test_value"
-    _PROTECTED_CLASS_VAR = "protected value"
-
-    def __init__(self, ivar=None):
-        self.__ivar = ivar
-
-    def __eq__(self, rhs):
-        return self.__ivar == rhs
-
-    def __ne__(self, rhs):
-        return not self.__eq__(rhs)
-
-    def ValidCall(self):
-        pass
-
-    def MethodWithArgs(self, one, two, nine=None):
-        pass
-
-    def OtherValidCall(self):
-        pass
-
-    def OptionalArgs(self, foo='boom'):
-        pass
-
-    def ValidCallWithArgs(self, *args, **kwargs):
-        pass
-
-    @classmethod
-    def MyClassMethod(cls):
-        pass
-
-    @staticmethod
-    def MyStaticMethod():
-        pass
-
-    def _ProtectedCall(self):
-        pass
-
-    def __PrivateCall(self):
-        pass
-
-    def __DoNotMock(self):
-        pass
-
-    def __getitem__(self, key):
-        """Return the value for key."""
-        return self.d[key]
-
-    def __setitem__(self, key, value):
-        """Set the value for key to value."""
-        self.d[key] = value
-
-    def __contains__(self, key):
-        """Returns True if d contains the key."""
-        return key in self.d
-
-    def __iter__(self):
-        pass
-
-
-class ChildClass(TestClass):
-    """This inherits from TestClass."""
-    def __init__(self):
-        TestClass.__init__(self)
-
-    def ChildValidCall(self):
-        pass
-
-
-class CallableClass(object):
-    """This class is callable, and that should be mockable!"""
-
-    def __init__(self):
-        pass
-
-    def __call__(self, param):
-        return param
-
-
-class ClassWithProperties(object):
-        def setter_attr(self, value):
-                pass
-
-        def getter_attr(self):
-                pass
-
-        prop_attr = property(getter_attr, setter_attr)
-
-
-class SubscribtableNonIterableClass(object):
-    def __getitem__(self, index):
-        raise IndexError
-
-
-class InheritsFromCallable(CallableClass):
-    """This class should be mockable; it inherits from a callable class."""
-
-    pass
-
-
-if __name__ == '__main__':
-    testtools.main()
diff --git a/catapult/telemetry/third_party/mox3/mox3/tests/test_stubout.py b/catapult/telemetry/third_party/mox3/mox3/tests/test_stubout.py
deleted file mode 100644
index 4a04170..0000000
--- a/catapult/telemetry/third_party/mox3/mox3/tests/test_stubout.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# Unit tests for stubout.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# This is a fork of the pymox library intended to work with Python 3.
-# The file was modified by quermit@gmail.com and dawid.fatyga@gmail.com
-
-import fixtures
-import testtools
-
-from mox3 import mox
-from mox3 import stubout
-from mox3.tests import stubout_helper
-
-
-class StubOutForTestingTest(testtools.TestCase):
-    def setUp(self):
-        super(StubOutForTestingTest, self).setUp()
-        self.mox = mox.Mox()
-        self.useFixture(fixtures.MonkeyPatch(
-            'mox3.tests.stubout_helper.SampleFunction',
-            stubout_helper.SampleFunction))
-
-    def testSmartSetOnModule(self):
-        mock_function = self.mox.CreateMockAnything()
-        mock_function()
-
-        stubber = stubout.StubOutForTesting()
-        stubber.SmartSet(stubout_helper, 'SampleFunction', mock_function)
-
-        self.mox.ReplayAll()
-
-        stubout_helper.SampleFunction()
-
-        self.mox.VerifyAll()
-
-
-if __name__ == '__main__':
-    testtools.main()
diff --git a/catapult/telemetry/third_party/mox3/requirements.txt b/catapult/telemetry/third_party/mox3/requirements.txt
deleted file mode 100644
index d52427f..0000000
--- a/catapult/telemetry/third_party/mox3/requirements.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-# The order of packages is significant, because pip processes them in the order
-# of appearance. Changing the order has an impact on the overall integration
-# process, which may cause wedges in the gate later.
-pbr<2.0,>=1.6
-
-fixtures>=1.3.1
diff --git a/catapult/telemetry/third_party/mox3/setup.cfg b/catapult/telemetry/third_party/mox3/setup.cfg
deleted file mode 100644
index 4a3de06..0000000
--- a/catapult/telemetry/third_party/mox3/setup.cfg
+++ /dev/null
@@ -1,27 +0,0 @@
-[metadata]
-name = mox3
-summary = Mock object framework for Python
-description-file =
-    README.rst
-author = OpenStack
-author-email = openstack-dev@lists.openstack.org
-home-page = http://www.openstack.org/
-classifiers =
-    Environment :: OpenStack
-    Programming Language :: Python
-    License :: OSI Approved :: Apache Software License
-    Programming Language :: Python :: 2.6
-    Programming Language :: Python :: 2.7
-    Programming Language :: Python :: 3
-    Operating System :: OS Independent
-    Development Status :: 4 - Beta
-    Intended Audience :: Developers
-    Topic :: Software Development :: Testing
-
-[files]
-packages =
-    mox3
-
-[global]
-setup-hooks =
-    pbr.hooks.setup_hook
diff --git a/catapult/telemetry/third_party/mox3/setup.py b/catapult/telemetry/third_party/mox3/setup.py
deleted file mode 100644
index d8080d0..0000000
--- a/catapult/telemetry/third_party/mox3/setup.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
-import setuptools
-
-# In python < 2.7.4, a lazy loading of package `pbr` will break
-# setuptools if some other modules registered functions in `atexit`.
-# solution from: http://bugs.python.org/issue15881#msg170215
-try:
-    import multiprocessing  # noqa
-except ImportError:
-    pass
-
-setuptools.setup(
-    setup_requires=['pbr>=1.3'],
-    pbr=True)
diff --git a/catapult/telemetry/third_party/mox3/test-requirements.txt b/catapult/telemetry/third_party/mox3/test-requirements.txt
deleted file mode 100644
index 22f6480..0000000
--- a/catapult/telemetry/third_party/mox3/test-requirements.txt
+++ /dev/null
@@ -1,22 +0,0 @@
-# The order of packages is significant, because pip processes them in the order
-# of appearance. Changing the order has an impact on the overall integration
-# process, which may cause wedges in the gate later.
-# this file lists dependencies required for the testing of heat
-
-# Install bounded pep8/pyflakes first, then let flake8 install
-pep8==1.5.7
-pyflakes==0.8.1
-flake8<=2.4.1,>=2.2.4
-
-coverage>=3.6
-discover
-python-subunit>=0.0.18
-testrepository>=0.0.18
-testtools>=1.4.0
-
-six>=1.9.0
-
-# this is required for the docs build jobs
-sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
-oslosphinx>=2.5.0 # Apache-2.0
-
diff --git a/catapult/telemetry/third_party/mox3/tox.ini b/catapult/telemetry/third_party/mox3/tox.ini
deleted file mode 100644
index eea97fc..0000000
--- a/catapult/telemetry/third_party/mox3/tox.ini
+++ /dev/null
@@ -1,28 +0,0 @@
-[tox]
-envlist = py34,py27,pep8
-
-[testenv]
-setenv = VIRTUAL_ENV={envdir}
-deps = -r{toxinidir}/requirements.txt
-       -r{toxinidir}/test-requirements.txt
-commands =
-  python setup.py testr --slowest --testr-args='{posargs}'
-
-[testenv:docs]
-commands = python setup.py build_sphinx
-
-[testenv:pep8]
-commands = flake8
-
-[testenv:venv]
-commands = {posargs}
-
-[testenv:cover]
-setenv = VIRTUAL_ENV={envdir}
-commands =
-  python setup.py testr --coverage
-
-[flake8]
-show-source = true
-builtins = _
-exclude=.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg
diff --git a/catapult/telemetry/third_party/png/README.chromium b/catapult/telemetry/third_party/png/README.chromium
deleted file mode 100644
index d838ece..0000000
--- a/catapult/telemetry/third_party/png/README.chromium
+++ /dev/null
@@ -1,17 +0,0 @@
-Name: Pure Python PNG Reader/Writer
-Short Name: pypng
-URL: https://github.com/drj11/pypng/
-Version: 0
-Date: 2009-03-11
-Revision: dd1797c361eafa443878b0915f767b75bd518d3b
-License: MIT
-License File: NOT_SHIPPED
-Security Critical: no
-
-Description:
-A png encoder and decoder for python. Used by telemetry to decode screenshots
-captured via the gpuBenchmark.windowSnapshot API, which are returned as
-Base64-encoded PNG files.
-
-Local Modifications:
-None.
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/png/png.py b/catapult/telemetry/third_party/png/png.py
deleted file mode 100755
index b55dd3a..0000000
--- a/catapult/telemetry/third_party/png/png.py
+++ /dev/null
@@ -1,3857 +0,0 @@
-#!/usr/bin/env python
-
-# $URL$
-# $Rev$
-
-# png.py - PNG encoder/decoder in pure Python
-#
-# Copyright (C) 2006 Johann C. Rocholl <johann@browsershots.org>
-# Portions Copyright (C) 2009 David Jones <drj@pobox.com>
-# And probably portions Copyright (C) 2006 Nicko van Someren <nicko@nicko.org>
-#
-# Original concept by Johann C. Rocholl.
-#
-# LICENSE (The MIT License)
-#
-# Permission is hereby granted, free of charge, to any person
-# obtaining a copy of this software and associated documentation files
-# (the "Software"), to deal in the Software without restriction,
-# including without limitation the rights to use, copy, modify, merge,
-# publish, distribute, sublicense, and/or sell copies of the Software,
-# and to permit persons to whom the Software is furnished to do so,
-# subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
-# BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
-# ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-# SOFTWARE.
-#
-# Changelog (recent first):
-# 2009-03-11 David: interlaced bit depth < 8 (writing).
-# 2009-03-10 David: interlaced bit depth < 8 (reading).
-# 2009-03-04 David: Flat and Boxed pixel formats.
-# 2009-02-26 David: Palette support (writing).
-# 2009-02-23 David: Bit-depths < 8; better PNM support.
-# 2006-06-17 Nicko: Reworked into a class, faster interlacing.
-# 2006-06-17 Johann: Very simple prototype PNG decoder.
-# 2006-06-17 Nicko: Test suite with various image generators.
-# 2006-06-17 Nicko: Alpha-channel, grey-scale, 16-bit/plane support.
-# 2006-06-15 Johann: Scanline iterator interface for large input files.
-# 2006-06-09 Johann: Very simple prototype PNG encoder.
-
-# Incorporated into Bangai-O Development Tools by drj on 2009-02-11 from
-# http://trac.browsershots.org/browser/trunk/pypng/lib/png.py?rev=2885
-
-# Incorporated into pypng by drj on 2009-03-12 from
-# //depot/prj/bangaio/master/code/png.py#67
-
-
-"""
-Pure Python PNG Reader/Writer
-
-This Python module implements support for PNG images (see PNG
-specification at http://www.w3.org/TR/2003/REC-PNG-20031110/ ). It reads
-and writes PNG files with all allowable bit depths (1/2/4/8/16/24/32/48/64
-bits per pixel) and colour combinations: greyscale (1/2/4/8/16 bit); RGB,
-RGBA, LA (greyscale with alpha) with 8/16 bits per channel; colour mapped
-images (1/2/4/8 bit).  Adam7 interlacing is supported for reading and
-writing.  A number of optional chunks can be specified (when writing)
-and understood (when reading): ``tRNS``, ``bKGD``, ``gAMA``.
-
-For help, type ``import png; help(png)`` in your python interpreter.
-
-A good place to start is the :class:`Reader` and :class:`Writer` classes.
-
-Requires Python 2.3.  Limited support is available for Python 2.2, but
-not everything works.  Best with Python 2.4 and higher.  Installation is
-trivial, but see the ``README.txt`` file (with the source distribution)
-for details.
-
-This file can also be used as a command-line utility to convert
-`Netpbm <http://netpbm.sourceforge.net/>`_ PNM files to PNG, and the reverse conversion from PNG to
-PNM. The interface is similar to that of the ``pnmtopng`` program from
-Netpbm.  Type ``python png.py --help`` at the shell prompt
-for usage and a list of options.
-
-A note on spelling and terminology
-----------------------------------
-
-Generally British English spelling is used in the documentation.  So
-that's "greyscale" and "colour".  This not only matches the author's
-native language, it's also used by the PNG specification.
-
-The major colour models supported by PNG (and hence by PyPNG) are:
-greyscale, RGB, greyscale--alpha, RGB--alpha.  These are sometimes
-referred to using the abbreviations: L, RGB, LA, RGBA.  In this case
-each letter abbreviates a single channel: *L* is for Luminance or Luma or
-Lightness which is the channel used in greyscale images; *R*, *G*, *B* stand
-for Red, Green, Blue, the components of a colour image; *A* stands for
-Alpha, the opacity channel (used for transparency effects, but higher
-values are more opaque, so it makes sense to call it opacity).
-
-A note on formats
------------------
-
-When getting pixel data out of this module (reading) and presenting
-data to this module (writing) there are a number of ways the data could
-be represented as a Python value.  Generally this module uses one of
-three formats called "flat row flat pixel", "boxed row flat pixel", and
-"boxed row boxed pixel".  Basically the concern is whether each pixel
-and each row comes in its own little tuple (box), or not.
-
-Consider an image that is 3 pixels wide by 2 pixels high, and each pixel
-has RGB components:
-
-Boxed row flat pixel::
-
-  list([R,G,B, R,G,B, R,G,B],
-       [R,G,B, R,G,B, R,G,B])
-
-Each row appears as its own list, but the pixels are flattened so that
-three values for one pixel simply follow the three values for the previous
-pixel.  This is the most common format used, because it provides a good
-compromise between space and convenience.  PyPNG regards itself as
-at liberty to replace any sequence type with any sufficiently compatible
-other sequence type; in practice each row is an array (from the array
-module), and the outer list is sometimes an iterator rather than an
-explicit list (so that streaming is possible).
-
-Flat row flat pixel::
-
-  [R,G,B, R,G,B, R,G,B,
-   R,G,B, R,G,B, R,G,B]
-
-The entire image is one single giant sequence of colour values.
-Generally an array will be used (to save space), not a list.
-
-Boxed row boxed pixel::
-
-  list([ (R,G,B), (R,G,B), (R,G,B) ],
-       [ (R,G,B), (R,G,B), (R,G,B) ])
-
-Each row appears in its own list, but each pixel also appears in its own
-tuple.  A serious memory burn in Python.
-
-In all cases the top row comes first, and for each row the pixels are
-ordered from left-to-right.  Within a pixel the values appear in the
-order, R-G-B-A (or L-A for greyscale--alpha).
-
-There is a fourth format, mentioned because it is used internally,
-is close to what lies inside a PNG file itself, and has some support
-from the public API.  This format is called packed.  When packed,
-each row is a sequence of bytes (integers from 0 to 255), just as
-it is before PNG scanline filtering is applied.  When the bit depth
-is 8 this is essentially the same as boxed row flat pixel; when the
-bit depth is less than 8, several pixels are packed into each byte;
-when the bit depth is 16 (the only value more than 8 that is supported
-by the PNG image format) each pixel value is decomposed into 2 bytes
-(and `packed` is a misnomer).  This format is used by the
-:meth:`Writer.write_packed` method.  It isn't usually a convenient
-format, but may be just right if the source data for the PNG image
-comes from something that uses a similar format (for example, 1-bit
-BMPs, or another PNG file).
-
-And now, my famous members
---------------------------
-"""
-
-# http://www.python.org/doc/2.2.3/whatsnew/node5.html
-from __future__ import generators
-
-__version__ = "$URL$ $Rev$"
-
-from array import array
-try: # See :pyver:old
-    import itertools
-except:
-    pass
-import math
-# http://www.python.org/doc/2.4.4/lib/module-operator.html
-import operator
-import struct
-import sys
-import zlib
-# http://www.python.org/doc/2.4.4/lib/module-warnings.html
-import warnings
-try:
-    import pyximport
-    pyximport.install()
-    import cpngfilters as pngfilters
-except ImportError:
-    pass
-
-
-__all__ = ['Image', 'Reader', 'Writer', 'write_chunks', 'from_array']
-
-
-# The PNG signature.
-# http://www.w3.org/TR/PNG/#5PNG-file-signature
-_signature = struct.pack('8B', 137, 80, 78, 71, 13, 10, 26, 10)
-
-_adam7 = ((0, 0, 8, 8),
-          (4, 0, 8, 8),
-          (0, 4, 4, 8),
-          (2, 0, 4, 4),
-          (0, 2, 2, 4),
-          (1, 0, 2, 2),
-          (0, 1, 1, 2))
-
-def group(s, n):
-    # See
-    # http://www.python.org/doc/2.6/library/functions.html#zip
-    return zip(*[iter(s)]*n)
-
-def isarray(x):
-    """Same as ``isinstance(x, array)`` except on Python 2.2, where it
-    always returns ``False``.  This helps PyPNG work on Python 2.2.
-    """
-
-    try:
-        return isinstance(x, array)
-    except:
-        return False
-
-try:  # see :pyver:old
-    array.tostring
-except:
-    def tostring(row):
-        l = len(row)
-        return struct.pack('%dB' % l, *row)
-else:
-    def tostring(row):
-        """Convert row of bytes to string.  Expects `row` to be an
-        ``array``.
-        """
-        return row.tostring()
-
-# Conditionally convert to bytes.  Works on Python 2 and Python 3.
-try:
-    bytes('', 'ascii')
-    def strtobytes(x): return bytes(x, 'iso8859-1')
-    def bytestostr(x): return str(x, 'iso8859-1')
-except:
-    strtobytes = str
-    bytestostr = str
-
-def interleave_planes(ipixels, apixels, ipsize, apsize):
-    """
-    Interleave (colour) planes, e.g. RGB + A = RGBA.
-
-    Return an array of pixels consisting of the `ipsize` elements of data
-    from each pixel in `ipixels` followed by the `apsize` elements of data
-    from each pixel in `apixels`.  Conventionally `ipixels` and
-    `apixels` are byte arrays so the sizes are bytes, but it actually
-    works with any arrays of the same type.  The returned array is the
-    same type as the input arrays which should be the same type as each other.
-    """
-
-    itotal = len(ipixels)
-    atotal = len(apixels)
-    newtotal = itotal + atotal
-    newpsize = ipsize + apsize
-    # Set up the output buffer
-    # See http://www.python.org/doc/2.4.4/lib/module-array.html#l2h-1356
-    out = array(ipixels.typecode)
-    # It's annoying that there is no cheap way to set the array size :-(
-    out.extend(ipixels)
-    out.extend(apixels)
-    # Interleave in the pixel data
-    for i in range(ipsize):
-        out[i:newtotal:newpsize] = ipixels[i:itotal:ipsize]
-    for i in range(apsize):
-        out[i+ipsize:newtotal:newpsize] = apixels[i:atotal:apsize]
-    return out
-
-def check_palette(palette):
-    """Check a palette argument (to the :class:`Writer` class) for validity.
-    Returns the palette as a list if okay; raises an exception otherwise.
-    """
-
-    # None is the default and is allowed.
-    if palette is None:
-        return None
-
-    p = list(palette)
-    if not (0 < len(p) <= 256):
-        raise ValueError("a palette must have between 1 and 256 entries")
-    seen_triple = False
-    for i,t in enumerate(p):
-        if len(t) not in (3,4):
-            raise ValueError(
-              "palette entry %d: entries must be 3- or 4-tuples." % i)
-        if len(t) == 3:
-            seen_triple = True
-        if seen_triple and len(t) == 4:
-            raise ValueError(
-              "palette entry %d: all 4-tuples must precede all 3-tuples" % i)
-        for x in t:
-            if int(x) != x or not(0 <= x <= 255):
-                raise ValueError(
-                  "palette entry %d: values must be integer: 0 <= x <= 255" % i)
-    return p
-
-class Error(Exception):
-    prefix = 'Error'
-    def __str__(self):
-        return self.prefix + ': ' + ' '.join(self.args)
-
-class FormatError(Error):
-    """Problem with input file format.  In other words, PNG file does
-    not conform to the specification in some way and is invalid.
-    """
-
-    prefix = 'FormatError'
-
-class ChunkError(FormatError):
-    prefix = 'ChunkError'
-
-
-class Writer:
-    """
-    PNG encoder in pure Python.
-    """
-
-    def __init__(self, width=None, height=None,
-                 size=None,
-                 greyscale=False,
-                 alpha=False,
-                 bitdepth=8,
-                 palette=None,
-                 transparent=None,
-                 background=None,
-                 gamma=None,
-                 compression=None,
-                 interlace=False,
-                 bytes_per_sample=None, # deprecated
-                 planes=None,
-                 colormap=None,
-                 maxval=None,
-                 chunk_limit=2**20):
-        """
-        Create a PNG encoder object.
-
-        Arguments:
-
-        width, height
-          Image size in pixels, as two separate arguments.
-        size
-          Image size (w,h) in pixels, as single argument.
-        greyscale
-          Input data is greyscale, not RGB.
-        alpha
-          Input data has alpha channel (RGBA or LA).
-        bitdepth
-          Bit depth: from 1 to 16.
-        palette
-          Create a palette for a colour mapped image (colour type 3).
-        transparent
-          Specify a transparent colour (create a ``tRNS`` chunk).
-        background
-          Specify a default background colour (create a ``bKGD`` chunk).
-        gamma
-          Specify a gamma value (create a ``gAMA`` chunk).
-        compression
-          zlib compression level: 0 (none) to 9 (more compressed); default: -1 or None.
-        interlace
-          Create an interlaced image.
-        chunk_limit
-          Write multiple ``IDAT`` chunks to save memory.
-
-        The image size (in pixels) can be specified either by using the
-        `width` and `height` arguments, or with the single `size`
-        argument.  If `size` is used it should be a pair (*width*,
-        *height*).
-
-        `greyscale` and `alpha` are booleans that specify whether
-        an image is greyscale (or colour), and whether it has an
-        alpha channel (or not).
-
-        `bitdepth` specifies the bit depth of the source pixel values.
-        Each source pixel value must be an integer between 0 and
-        ``2**bitdepth-1``.  For example, 8-bit images have values
-        between 0 and 255.  PNG only stores images with bit depths of
-        1,2,4,8, or 16.  When `bitdepth` is not one of these values,
-        the next highest valid bit depth is selected, and an ``sBIT``
-        (significant bits) chunk is generated that specifies the original
-        precision of the source image.  In this case the supplied pixel
-        values will be rescaled to fit the range of the selected bit depth.
-
-        The details of which bit depth / colour model combinations the
-        PNG file format supports directly, are somewhat arcane
-        (refer to the PNG specification for full details).  Briefly:
-        "small" bit depths (1,2,4) are only allowed with greyscale and
-        colour mapped images; colour mapped images cannot have bit depth
-        16.
-
-        For colour mapped images (in other words, when the `palette`
-        argument is specified) the `bitdepth` argument must match one of
-        the valid PNG bit depths: 1, 2, 4, or 8.  (It is valid to have a
-        PNG image with a palette and an ``sBIT`` chunk, but the meaning
-        is slightly different; it would be awkward to press the
-        `bitdepth` argument into service for this.)
-
-        The `palette` option, when specified, causes a colour mapped image
-        to be created: the PNG colour type is set to 3; greyscale
-        must not be set; alpha must not be set; transparent must
-        not be set; the bit depth must be 1,2,4, or 8.  When a colour
-        mapped image is created, the pixel values are palette indexes
-        and the `bitdepth` argument specifies the size of these indexes
-        (not the size of the colour values in the palette).
-
-        The palette argument value should be a sequence of 3- or
-        4-tuples.  3-tuples specify RGB palette entries; 4-tuples
-        specify RGBA palette entries.  If both 4-tuples and 3-tuples
-        appear in the sequence then all the 4-tuples must come
-        before all the 3-tuples.  A ``PLTE`` chunk is created; if there
-        are 4-tuples then a ``tRNS`` chunk is created as well.  The
-        ``PLTE`` chunk will contain all the RGB triples in the same
-        sequence; the ``tRNS`` chunk will contain the alpha channel for
-        all the 4-tuples, in the same sequence.  Palette entries
-        are always 8-bit.
-
-        If specified, the `transparent` and `background` parameters must
-        be a tuple with three integer values for red, green, blue, or
-        a simple integer (or singleton tuple) for a greyscale image.
-
-        If specified, the `gamma` parameter must be a positive number
-        (generally, a float).  A ``gAMA`` chunk will be created.  Note that
-        this will not change the values of the pixels as they appear in
-        the PNG file, they are assumed to have already been converted
-        appropriately for the gamma specified.
-
-        The `compression` argument specifies the compression level to
-        be used by the ``zlib`` module.  Values from 1 to 9 specify
-        compression, with 9 being "more compressed" (usually smaller
-        and slower, but it doesn't always work out that way).  0 means
-        no compression.  -1 and ``None`` both mean that the default
-        level of compession will be picked by the ``zlib`` module
-        (which is generally acceptable).
-
-        If `interlace` is true then an interlaced image is created
-        (using PNG's so far only interace method, *Adam7*).  This does not
-        affect how the pixels should be presented to the encoder, rather
-        it changes how they are arranged into the PNG file.  On slow
-        connexions interlaced images can be partially decoded by the
-        browser to give a rough view of the image that is successively
-        refined as more image data appears.
-        
-        .. note ::
-        
-          Enabling the `interlace` option requires the entire image
-          to be processed in working memory.
-
-        `chunk_limit` is used to limit the amount of memory used whilst
-        compressing the image.  In order to avoid using large amounts of
-        memory, multiple ``IDAT`` chunks may be created.
-        """
-
-        # At the moment the `planes` argument is ignored;
-        # its purpose is to act as a dummy so that
-        # ``Writer(x, y, **info)`` works, where `info` is a dictionary
-        # returned by Reader.read and friends.
-        # Ditto for `colormap`.
-
-        # A couple of helper functions come first.  Best skipped if you
-        # are reading through.
-
-        def isinteger(x):
-            try:
-                return int(x) == x
-            except:
-                return False
-
-        def check_color(c, which):
-            """Checks that a colour argument for transparent or
-            background options is the right form.  Also "corrects" bare
-            integers to 1-tuples.
-            """
-
-            if c is None:
-                return c
-            if greyscale:
-                try:
-                    l = len(c)
-                except TypeError:
-                    c = (c,)
-                if len(c) != 1:
-                    raise ValueError("%s for greyscale must be 1-tuple" %
-                        which)
-                if not isinteger(c[0]):
-                    raise ValueError(
-                        "%s colour for greyscale must be integer" %
-                        which)
-            else:
-                if not (len(c) == 3 and
-                        isinteger(c[0]) and
-                        isinteger(c[1]) and
-                        isinteger(c[2])):
-                    raise ValueError(
-                        "%s colour must be a triple of integers" %
-                        which)
-            return c
-
-        if size:
-            if len(size) != 2:
-                raise ValueError(
-                  "size argument should be a pair (width, height)")
-            if width is not None and width != size[0]:
-                raise ValueError(
-                  "size[0] (%r) and width (%r) should match when both are used."
-                    % (size[0], width))
-            if height is not None and height != size[1]:
-                raise ValueError(
-                  "size[1] (%r) and height (%r) should match when both are used."
-                    % (size[1], height))
-            width,height = size
-        del size
-
-        if width <= 0 or height <= 0:
-            raise ValueError("width and height must be greater than zero")
-        if not isinteger(width) or not isinteger(height):
-            raise ValueError("width and height must be integers")
-        # http://www.w3.org/TR/PNG/#7Integers-and-byte-order
-        if width > 2**32-1 or height > 2**32-1:
-            raise ValueError("width and height cannot exceed 2**32-1")
-
-        if alpha and transparent is not None:
-            raise ValueError(
-                "transparent colour not allowed with alpha channel")
-
-        if bytes_per_sample is not None:
-            warnings.warn('please use bitdepth instead of bytes_per_sample',
-                          DeprecationWarning)
-            if bytes_per_sample not in (0.125, 0.25, 0.5, 1, 2):
-                raise ValueError(
-                    "bytes per sample must be .125, .25, .5, 1, or 2")
-            bitdepth = int(8*bytes_per_sample)
-        del bytes_per_sample
-        if not isinteger(bitdepth) or bitdepth < 1 or 16 < bitdepth:
-            raise ValueError("bitdepth (%r) must be a postive integer <= 16" %
-              bitdepth)
-
-        self.rescale = None
-        if palette:
-            if bitdepth not in (1,2,4,8):
-                raise ValueError("with palette, bitdepth must be 1, 2, 4, or 8")
-            if transparent is not None:
-                raise ValueError("transparent and palette not compatible")
-            if alpha:
-                raise ValueError("alpha and palette not compatible")
-            if greyscale:
-                raise ValueError("greyscale and palette not compatible")
-        else:
-            # No palette, check for sBIT chunk generation.
-            if alpha or not greyscale:
-                if bitdepth not in (8,16):
-                    targetbitdepth = (8,16)[bitdepth > 8]
-                    self.rescale = (bitdepth, targetbitdepth)
-                    bitdepth = targetbitdepth
-                    del targetbitdepth
-            else:
-                assert greyscale
-                assert not alpha
-                if bitdepth not in (1,2,4,8,16):
-                    if bitdepth > 8:
-                        targetbitdepth = 16
-                    elif bitdepth == 3:
-                        targetbitdepth = 4
-                    else:
-                        assert bitdepth in (5,6,7)
-                        targetbitdepth = 8
-                    self.rescale = (bitdepth, targetbitdepth)
-                    bitdepth = targetbitdepth
-                    del targetbitdepth
-
-        if bitdepth < 8 and (alpha or not greyscale and not palette):
-            raise ValueError(
-              "bitdepth < 8 only permitted with greyscale or palette")
-        if bitdepth > 8 and palette:
-            raise ValueError(
-                "bit depth must be 8 or less for images with palette")
-
-        transparent = check_color(transparent, 'transparent')
-        background = check_color(background, 'background')
-
-        # It's important that the true boolean values (greyscale, alpha,
-        # colormap, interlace) are converted to bool because Iverson's
-        # convention is relied upon later on.
-        self.width = width
-        self.height = height
-        self.transparent = transparent
-        self.background = background
-        self.gamma = gamma
-        self.greyscale = bool(greyscale)
-        self.alpha = bool(alpha)
-        self.colormap = bool(palette)
-        self.bitdepth = int(bitdepth)
-        self.compression = compression
-        self.chunk_limit = chunk_limit
-        self.interlace = bool(interlace)
-        self.palette = check_palette(palette)
-
-        self.color_type = 4*self.alpha + 2*(not greyscale) + 1*self.colormap
-        assert self.color_type in (0,2,3,4,6)
-
-        self.color_planes = (3,1)[self.greyscale or self.colormap]
-        self.planes = self.color_planes + self.alpha
-        # :todo: fix for bitdepth < 8
-        self.psize = (self.bitdepth/8) * self.planes
-
-    def make_palette(self):
-        """Create the byte sequences for a ``PLTE`` and if necessary a
-        ``tRNS`` chunk.  Returned as a pair (*p*, *t*).  *t* will be
-        ``None`` if no ``tRNS`` chunk is necessary.
-        """
-
-        p = array('B')
-        t = array('B')
-
-        for x in self.palette:
-            p.extend(x[0:3])
-            if len(x) > 3:
-                t.append(x[3])
-        p = tostring(p)
-        t = tostring(t)
-        if t:
-            return p,t
-        return p,None
-
-    def write(self, outfile, rows):
-        """Write a PNG image to the output file.  `rows` should be
-        an iterable that yields each row in boxed row flat pixel format.
-        The rows should be the rows of the original image, so there
-        should be ``self.height`` rows of ``self.width * self.planes`` values.
-        If `interlace` is specified (when creating the instance), then
-        an interlaced PNG file will be written.  Supply the rows in the
-        normal image order; the interlacing is carried out internally.
-        
-        .. note ::
-
-          Interlacing will require the entire image to be in working memory.
-        """
-
-        if self.interlace:
-            fmt = 'BH'[self.bitdepth > 8]
-            a = array(fmt, itertools.chain(*rows))
-            return self.write_array(outfile, a)
-        else:
-            nrows = self.write_passes(outfile, rows)
-            if nrows != self.height:
-                raise ValueError(
-                  "rows supplied (%d) does not match height (%d)" %
-                  (nrows, self.height))
-
-    def write_passes(self, outfile, rows, packed=False):
-        """
-        Write a PNG image to the output file.
-
-        Most users are expected to find the :meth:`write` or
-        :meth:`write_array` method more convenient.
-        
-        The rows should be given to this method in the order that
-        they appear in the output file.  For straightlaced images,
-        this is the usual top to bottom ordering, but for interlaced
-        images the rows should have already been interlaced before
-        passing them to this function.
-
-        `rows` should be an iterable that yields each row.  When
-        `packed` is ``False`` the rows should be in boxed row flat pixel
-        format; when `packed` is ``True`` each row should be a packed
-        sequence of bytes.
-
-        """
-
-        # http://www.w3.org/TR/PNG/#5PNG-file-signature
-        outfile.write(_signature)
-
-        # http://www.w3.org/TR/PNG/#11IHDR
-        write_chunk(outfile, 'IHDR',
-                    struct.pack("!2I5B", self.width, self.height,
-                                self.bitdepth, self.color_type,
-                                0, 0, self.interlace))
-
-        # See :chunk:order
-        # http://www.w3.org/TR/PNG/#11gAMA
-        if self.gamma is not None:
-            write_chunk(outfile, 'gAMA',
-                        struct.pack("!L", int(round(self.gamma*1e5))))
-
-        # See :chunk:order
-        # http://www.w3.org/TR/PNG/#11sBIT
-        if self.rescale:
-            write_chunk(outfile, 'sBIT',
-                struct.pack('%dB' % self.planes,
-                            *[self.rescale[0]]*self.planes))
-        
-        # :chunk:order: Without a palette (PLTE chunk), ordering is
-        # relatively relaxed.  With one, gAMA chunk must precede PLTE
-        # chunk which must precede tRNS and bKGD.
-        # See http://www.w3.org/TR/PNG/#5ChunkOrdering
-        if self.palette:
-            p,t = self.make_palette()
-            write_chunk(outfile, 'PLTE', p)
-            if t:
-                # tRNS chunk is optional.  Only needed if palette entries
-                # have alpha.
-                write_chunk(outfile, 'tRNS', t)
-
-        # http://www.w3.org/TR/PNG/#11tRNS
-        if self.transparent is not None:
-            if self.greyscale:
-                write_chunk(outfile, 'tRNS',
-                            struct.pack("!1H", *self.transparent))
-            else:
-                write_chunk(outfile, 'tRNS',
-                            struct.pack("!3H", *self.transparent))
-
-        # http://www.w3.org/TR/PNG/#11bKGD
-        if self.background is not None:
-            if self.greyscale:
-                write_chunk(outfile, 'bKGD',
-                            struct.pack("!1H", *self.background))
-            else:
-                write_chunk(outfile, 'bKGD',
-                            struct.pack("!3H", *self.background))
-
-        # http://www.w3.org/TR/PNG/#11IDAT
-        if self.compression is not None:
-            compressor = zlib.compressobj(self.compression)
-        else:
-            compressor = zlib.compressobj()
-
-        # Choose an extend function based on the bitdepth.  The extend
-        # function packs/decomposes the pixel values into bytes and
-        # stuffs them onto the data array.
-        data = array('B')
-        if self.bitdepth == 8 or packed:
-            extend = data.extend
-        elif self.bitdepth == 16:
-            # Decompose into bytes
-            def extend(sl):
-                fmt = '!%dH' % len(sl)
-                data.extend(array('B', struct.pack(fmt, *sl)))
-        else:
-            # Pack into bytes
-            assert self.bitdepth < 8
-            # samples per byte
-            spb = int(8/self.bitdepth)
-            def extend(sl):
-                a = array('B', sl)
-                # Adding padding bytes so we can group into a whole
-                # number of spb-tuples.
-                l = float(len(a))
-                extra = math.ceil(l / float(spb))*spb - l
-                a.extend([0]*int(extra))
-                # Pack into bytes
-                l = group(a, spb)
-                l = map(lambda e: reduce(lambda x,y:
-                                           (x << self.bitdepth) + y, e), l)
-                data.extend(l)
-        if self.rescale:
-            oldextend = extend
-            factor = \
-              float(2**self.rescale[1]-1) / float(2**self.rescale[0]-1)
-            def extend(sl):
-                oldextend(map(lambda x: int(round(factor*x)), sl))
-
-        # Build the first row, testing mostly to see if we need to
-        # changed the extend function to cope with NumPy integer types
-        # (they cause our ordinary definition of extend to fail, so we
-        # wrap it).  See
-        # http://code.google.com/p/pypng/issues/detail?id=44
-        enumrows = enumerate(rows)
-        del rows
-
-        # First row's filter type.
-        data.append(0)
-        # :todo: Certain exceptions in the call to ``.next()`` or the
-        # following try would indicate no row data supplied.
-        # Should catch.
-        i,row = enumrows.next()
-        try:
-            # If this fails...
-            extend(row)
-        except:
-            # ... try a version that converts the values to int first.
-            # Not only does this work for the (slightly broken) NumPy
-            # types, there are probably lots of other, unknown, "nearly"
-            # int types it works for.
-            def wrapmapint(f):
-                return lambda sl: f(map(int, sl))
-            extend = wrapmapint(extend)
-            del wrapmapint
-            extend(row)
-
-        for i,row in enumrows:
-            # Add "None" filter type.  Currently, it's essential that
-            # this filter type be used for every scanline as we do not
-            # mark the first row of a reduced pass image; that means we
-            # could accidentally compute the wrong filtered scanline if
-            # we used "up", "average", or "paeth" on such a line.
-            data.append(0)
-            extend(row)
-            if len(data) > self.chunk_limit:
-                compressed = compressor.compress(tostring(data))
-                if len(compressed):
-                    # print >> sys.stderr, len(data), len(compressed)
-                    write_chunk(outfile, 'IDAT', compressed)
-                # Because of our very witty definition of ``extend``,
-                # above, we must re-use the same ``data`` object.  Hence
-                # we use ``del`` to empty this one, rather than create a
-                # fresh one (which would be my natural FP instinct).
-                del data[:]
-        if len(data):
-            compressed = compressor.compress(tostring(data))
-        else:
-            compressed = ''
-        flushed = compressor.flush()
-        if len(compressed) or len(flushed):
-            # print >> sys.stderr, len(data), len(compressed), len(flushed)
-            write_chunk(outfile, 'IDAT', compressed + flushed)
-        # http://www.w3.org/TR/PNG/#11IEND
-        write_chunk(outfile, 'IEND')
-        return i+1
-
-    def write_array(self, outfile, pixels):
-        """
-        Write an array in flat row flat pixel format as a PNG file on
-        the output file.  See also :meth:`write` method.
-        """
-
-        if self.interlace:
-            self.write_passes(outfile, self.array_scanlines_interlace(pixels))
-        else:
-            self.write_passes(outfile, self.array_scanlines(pixels))
-
-    def write_packed(self, outfile, rows):
-        """
-        Write PNG file to `outfile`.  The pixel data comes from `rows`
-        which should be in boxed row packed format.  Each row should be
-        a sequence of packed bytes.
-
-        Technically, this method does work for interlaced images but it
-        is best avoided.  For interlaced images, the rows should be
-        presented in the order that they appear in the file.
-
-        This method should not be used when the source image bit depth
-        is not one naturally supported by PNG; the bit depth should be
-        1, 2, 4, 8, or 16.
-        """
-
-        if self.rescale:
-            raise Error("write_packed method not suitable for bit depth %d" %
-              self.rescale[0])
-        return self.write_passes(outfile, rows, packed=True)
-
-    def convert_pnm(self, infile, outfile):
-        """
-        Convert a PNM file containing raw pixel data into a PNG file
-        with the parameters set in the writer object.  Works for
-        (binary) PGM, PPM, and PAM formats.
-        """
-
-        if self.interlace:
-            pixels = array('B')
-            pixels.fromfile(infile,
-                            (self.bitdepth/8) * self.color_planes *
-                            self.width * self.height)
-            self.write_passes(outfile, self.array_scanlines_interlace(pixels))
-        else:
-            self.write_passes(outfile, self.file_scanlines(infile))
-
-    def convert_ppm_and_pgm(self, ppmfile, pgmfile, outfile):
-        """
-        Convert a PPM and PGM file containing raw pixel data into a
-        PNG outfile with the parameters set in the writer object.
-        """
-        pixels = array('B')
-        pixels.fromfile(ppmfile,
-                        (self.bitdepth/8) * self.color_planes *
-                        self.width * self.height)
-        apixels = array('B')
-        apixels.fromfile(pgmfile,
-                         (self.bitdepth/8) *
-                         self.width * self.height)
-        pixels = interleave_planes(pixels, apixels,
-                                   (self.bitdepth/8) * self.color_planes,
-                                   (self.bitdepth/8))
-        if self.interlace:
-            self.write_passes(outfile, self.array_scanlines_interlace(pixels))
-        else:
-            self.write_passes(outfile, self.array_scanlines(pixels))
-
-    def file_scanlines(self, infile):
-        """
-        Generates boxed rows in flat pixel format, from the input file
-        `infile`.  It assumes that the input file is in a "Netpbm-like"
-        binary format, and is positioned at the beginning of the first
-        pixel.  The number of pixels to read is taken from the image
-        dimensions (`width`, `height`, `planes`) and the number of bytes
-        per value is implied by the image `bitdepth`.
-        """
-
-        # Values per row
-        vpr = self.width * self.planes
-        row_bytes = vpr
-        if self.bitdepth > 8:
-            assert self.bitdepth == 16
-            row_bytes *= 2
-            fmt = '>%dH' % vpr
-            def line():
-                return array('H', struct.unpack(fmt, infile.read(row_bytes)))
-        else:
-            def line():
-                scanline = array('B', infile.read(row_bytes))
-                return scanline
-        for y in range(self.height):
-            yield line()
-
-    def array_scanlines(self, pixels):
-        """
-        Generates boxed rows (flat pixels) from flat rows (flat pixels)
-        in an array.
-        """
-
-        # Values per row
-        vpr = self.width * self.planes
-        stop = 0
-        for y in range(self.height):
-            start = stop
-            stop = start + vpr
-            yield pixels[start:stop]
-
-    def array_scanlines_interlace(self, pixels):
-        """
-        Generator for interlaced scanlines from an array.  `pixels` is
-        the full source image in flat row flat pixel format.  The
-        generator yields each scanline of the reduced passes in turn, in
-        boxed row flat pixel format.
-        """
-
-        # http://www.w3.org/TR/PNG/#8InterlaceMethods
-        # Array type.
-        fmt = 'BH'[self.bitdepth > 8]
-        # Value per row
-        vpr = self.width * self.planes
-        for xstart, ystart, xstep, ystep in _adam7:
-            if xstart >= self.width:
-                continue
-            # Pixels per row (of reduced image)
-            ppr = int(math.ceil((self.width-xstart)/float(xstep)))
-            # number of values in reduced image row.
-            row_len = ppr*self.planes
-            for y in range(ystart, self.height, ystep):
-                if xstep == 1:
-                    offset = y * vpr
-                    yield pixels[offset:offset+vpr]
-                else:
-                    row = array(fmt)
-                    # There's no easier way to set the length of an array
-                    row.extend(pixels[0:row_len])
-                    offset = y * vpr + xstart * self.planes
-                    end_offset = (y+1) * vpr
-                    skip = self.planes * xstep
-                    for i in range(self.planes):
-                        row[i::self.planes] = \
-                            pixels[offset+i:end_offset:skip]
-                    yield row
-
-def write_chunk(outfile, tag, data=strtobytes('')):
-    """
-    Write a PNG chunk to the output file, including length and
-    checksum.
-    """
-
-    # http://www.w3.org/TR/PNG/#5Chunk-layout
-    outfile.write(struct.pack("!I", len(data)))
-    tag = strtobytes(tag)
-    outfile.write(tag)
-    outfile.write(data)
-    checksum = zlib.crc32(tag)
-    checksum = zlib.crc32(data, checksum)
-    checksum &= 2**32-1
-    outfile.write(struct.pack("!I", checksum))
-
-def write_chunks(out, chunks):
-    """Create a PNG file by writing out the chunks."""
-
-    out.write(_signature)
-    for chunk in chunks:
-        write_chunk(out, *chunk)
-
-def filter_scanline(type, line, fo, prev=None):
-    """Apply a scanline filter to a scanline.  `type` specifies the
-    filter type (0 to 4); `line` specifies the current (unfiltered)
-    scanline as a sequence of bytes; `prev` specifies the previous
-    (unfiltered) scanline as a sequence of bytes. `fo` specifies the
-    filter offset; normally this is size of a pixel in bytes (the number
-    of bytes per sample times the number of channels), but when this is
-    < 1 (for bit depths < 8) then the filter offset is 1.
-    """
-
-    assert 0 <= type < 5
-
-    # The output array.  Which, pathetically, we extend one-byte at a
-    # time (fortunately this is linear).
-    out = array('B', [type])
-
-    def sub():
-        ai = -fo
-        for x in line:
-            if ai >= 0:
-                x = (x - line[ai]) & 0xff
-            out.append(x)
-            ai += 1
-    def up():
-        for i,x in enumerate(line):
-            x = (x - prev[i]) & 0xff
-            out.append(x)
-    def average():
-        ai = -fo
-        for i,x in enumerate(line):
-            if ai >= 0:
-                x = (x - ((line[ai] + prev[i]) >> 1)) & 0xff
-            else:
-                x = (x - (prev[i] >> 1)) & 0xff
-            out.append(x)
-            ai += 1
-    def paeth():
-        # http://www.w3.org/TR/PNG/#9Filter-type-4-Paeth
-        ai = -fo # also used for ci
-        for i,x in enumerate(line):
-            a = 0
-            b = prev[i]
-            c = 0
-
-            if ai >= 0:
-                a = line[ai]
-                c = prev[ai]
-            p = a + b - c
-            pa = abs(p - a)
-            pb = abs(p - b)
-            pc = abs(p - c)
-            if pa <= pb and pa <= pc: Pr = a
-            elif pb <= pc: Pr = b
-            else: Pr = c
-
-            x = (x - Pr) & 0xff
-            out.append(x)
-            ai += 1
-
-    if not prev:
-        # We're on the first line.  Some of the filters can be reduced
-        # to simpler cases which makes handling the line "off the top"
-        # of the image simpler.  "up" becomes "none"; "paeth" becomes
-        # "left" (non-trivial, but true). "average" needs to be handled
-        # specially.
-        if type == 2: # "up"
-            return line # type = 0
-        elif type == 3:
-            prev = [0]*len(line)
-        elif type == 4: # "paeth"
-            type = 1
-    if type == 0:
-        out.extend(line)
-    elif type == 1:
-        sub()
-    elif type == 2:
-        up()
-    elif type == 3:
-        average()
-    else: # type == 4
-        paeth()
-    return out
-
-
-def from_array(a, mode=None, info={}):
-    """Create a PNG :class:`Image` object from a 2- or 3-dimensional array.
-    One application of this function is easy PIL-style saving:
-    ``png.from_array(pixels, 'L').save('foo.png')``.
-
-    .. note :
-
-      The use of the term *3-dimensional* is for marketing purposes
-      only.  It doesn't actually work.  Please bear with us.  Meanwhile
-      enjoy the complimentary snacks (on request) and please use a
-      2-dimensional array.
-    
-    Unless they are specified using the *info* parameter, the PNG's
-    height and width are taken from the array size.  For a 3 dimensional
-    array the first axis is the height; the second axis is the width;
-    and the third axis is the channel number.  Thus an RGB image that is
-    16 pixels high and 8 wide will use an array that is 16x8x3.  For 2
-    dimensional arrays the first axis is the height, but the second axis
-    is ``width*channels``, so an RGB image that is 16 pixels high and 8
-    wide will use a 2-dimensional array that is 16x24 (each row will be
-    8*3==24 sample values).
-
-    *mode* is a string that specifies the image colour format in a
-    PIL-style mode.  It can be:
-
-    ``'L'``
-      greyscale (1 channel)
-    ``'LA'``
-      greyscale with alpha (2 channel)
-    ``'RGB'``
-      colour image (3 channel)
-    ``'RGBA'``
-      colour image with alpha (4 channel)
-
-    The mode string can also specify the bit depth (overriding how this
-    function normally derives the bit depth, see below).  Appending
-    ``';16'`` to the mode will cause the PNG to be 16 bits per channel;
-    any decimal from 1 to 16 can be used to specify the bit depth.
-
-    When a 2-dimensional array is used *mode* determines how many
-    channels the image has, and so allows the width to be derived from
-    the second array dimension.
-
-    The array is expected to be a ``numpy`` array, but it can be any
-    suitable Python sequence.  For example, a list of lists can be used:
-    ``png.from_array([[0, 255, 0], [255, 0, 255]], 'L')``.  The exact
-    rules are: ``len(a)`` gives the first dimension, height;
-    ``len(a[0])`` gives the second dimension; ``len(a[0][0])`` gives the
-    third dimension, unless an exception is raised in which case a
-    2-dimensional array is assumed.  It's slightly more complicated than
-    that because an iterator of rows can be used, and it all still
-    works.  Using an iterator allows data to be streamed efficiently.
-
-    The bit depth of the PNG is normally taken from the array element's
-    datatype (but if *mode* specifies a bitdepth then that is used
-    instead).  The array element's datatype is determined in a way which
-    is supposed to work both for ``numpy`` arrays and for Python
-    ``array.array`` objects.  A 1 byte datatype will give a bit depth of
-    8, a 2 byte datatype will give a bit depth of 16.  If the datatype
-    does not have an implicit size, for example it is a plain Python
-    list of lists, as above, then a default of 8 is used.
-
-    The *info* parameter is a dictionary that can be used to specify
-    metadata (in the same style as the arguments to the
-    :class:``png.Writer`` class).  For this function the keys that are
-    useful are:
-    
-    height
-      overrides the height derived from the array dimensions and allows
-      *a* to be an iterable.
-    width
-      overrides the width derived from the array dimensions.
-    bitdepth
-      overrides the bit depth derived from the element datatype (but
-      must match *mode* if that also specifies a bit depth).
-
-    Generally anything specified in the
-    *info* dictionary will override any implicit choices that this
-    function would otherwise make, but must match any explicit ones.
-    For example, if the *info* dictionary has a ``greyscale`` key then
-    this must be true when mode is ``'L'`` or ``'LA'`` and false when
-    mode is ``'RGB'`` or ``'RGBA'``.
-    """
-
-    # We abuse the *info* parameter by modifying it.  Take a copy here.
-    # (Also typechecks *info* to some extent).
-    info = dict(info)
-
-    # Syntax check mode string.
-    bitdepth = None
-    try:
-        mode = mode.split(';')
-        if len(mode) not in (1,2):
-            raise Error()
-        if mode[0] not in ('L', 'LA', 'RGB', 'RGBA'):
-            raise Error()
-        if len(mode) == 2:
-            try:
-                bitdepth = int(mode[1])
-            except:
-                raise Error()
-    except Error:
-        raise Error("mode string should be 'RGB' or 'L;16' or similar.")
-    mode = mode[0]
-
-    # Get bitdepth from *mode* if possible.
-    if bitdepth:
-        if info.get('bitdepth') and bitdepth != info['bitdepth']:
-            raise Error("mode bitdepth (%d) should match info bitdepth (%d)." %
-              (bitdepth, info['bitdepth']))
-        info['bitdepth'] = bitdepth
-
-    # Fill in and/or check entries in *info*.
-    # Dimensions.
-    if 'size' in info:
-        # Check width, height, size all match where used.
-        for dimension,axis in [('width', 0), ('height', 1)]:
-            if dimension in info:
-                if info[dimension] != info['size'][axis]:
-                    raise Error(
-                      "info[%r] shhould match info['size'][%r]." %
-                      (dimension, axis))
-        info['width'],info['height'] = info['size']
-    if 'height' not in info:
-        try:
-            l = len(a)
-        except:
-            raise Error(
-              "len(a) does not work, supply info['height'] instead.")
-        info['height'] = l
-    # Colour format.
-    if 'greyscale' in info:
-        if bool(info['greyscale']) != ('L' in mode):
-            raise Error("info['greyscale'] should match mode.")
-    info['greyscale'] = 'L' in mode
-    if 'alpha' in info:
-        if bool(info['alpha']) != ('A' in mode):
-            raise Error("info['alpha'] should match mode.")
-    info['alpha'] = 'A' in mode
-
-    planes = len(mode)
-    if 'planes' in info:
-        if info['planes'] != planes:
-            raise Error("info['planes'] should match mode.")
-
-    # In order to work out whether we the array is 2D or 3D we need its
-    # first row, which requires that we take a copy of its iterator.
-    # We may also need the first row to derive width and bitdepth.
-    a,t = itertools.tee(a)
-    row = t.next()
-    del t
-    try:
-        row[0][0]
-        threed = True
-        testelement = row[0]
-    except:
-        threed = False
-        testelement = row
-    if 'width' not in info:
-        if threed:
-            width = len(row)
-        else:
-            width = len(row) // planes
-        info['width'] = width
-
-    # Not implemented yet
-    assert not threed
-
-    if 'bitdepth' not in info:
-        try:
-            dtype = testelement.dtype
-            # goto the "else:" clause.  Sorry.
-        except:
-            try:
-                # Try a Python array.array.
-                bitdepth = 8 * testelement.itemsize
-            except:
-                # We can't determine it from the array element's
-                # datatype, use a default of 8.
-                bitdepth = 8
-        else:
-            # If we got here without exception, we now assume that
-            # the array is a numpy array.
-            if dtype.kind == 'b':
-                bitdepth = 1
-            else:
-                bitdepth = 8 * dtype.itemsize
-        info['bitdepth'] = bitdepth
-
-    for thing in 'width height bitdepth greyscale alpha'.split():
-        assert thing in info
-    return Image(a, info)
-
-# So that refugee's from PIL feel more at home.  Not documented.
-fromarray = from_array
-
-class Image:
-    """A PNG image.
-    You can create an :class:`Image` object from an array of pixels by calling
-    :meth:`png.from_array`.  It can be saved to disk with the
-    :meth:`save` method."""
-    def __init__(self, rows, info):
-        """
-        .. note ::
-        
-          The constructor is not public.  Please do not call it.
-        """
-        
-        self.rows = rows
-        self.info = info
-
-    def save(self, file):
-        """Save the image to *file*.  If *file* looks like an open file
-        descriptor then it is used, otherwise it is treated as a
-        filename and a fresh file is opened.
-
-        In general, you can only call this method once; after it has
-        been called the first time and the PNG image has been saved, the
-        source data will have been streamed, and cannot be streamed
-        again.
-        """
-
-        w = Writer(**self.info)
-
-        try:
-            file.write
-            def close(): pass
-        except:
-            file = open(file, 'wb')
-            def close(): file.close()
-
-        try:
-            w.write(file, self.rows)
-        finally:
-            close()
-
-class _readable:
-    """
-    A simple file-like interface for strings and arrays.
-    """
-
-    def __init__(self, buf):
-        self.buf = buf
-        self.offset = 0
-
-    def read(self, n):
-        r = self.buf[self.offset:self.offset+n]
-        if isarray(r):
-            r = r.tostring()
-        self.offset += n
-        return r
-
-
-class Reader:
-    """
-    PNG decoder in pure Python.
-    """
-
-    def __init__(self, _guess=None, **kw):
-        """
-        Create a PNG decoder object.
-
-        The constructor expects exactly one keyword argument. If you
-        supply a positional argument instead, it will guess the input
-        type. You can choose among the following keyword arguments:
-
-        filename
-          Name of input file (a PNG file).
-        file
-          A file-like object (object with a read() method).
-        bytes
-          ``array`` or ``string`` with PNG data.
-
-        """
-        if ((_guess is not None and len(kw) != 0) or
-            (_guess is None and len(kw) != 1)):
-            raise TypeError("Reader() takes exactly 1 argument")
-
-        # Will be the first 8 bytes, later on.  See validate_signature.
-        self.signature = None
-        self.transparent = None
-        # A pair of (len,type) if a chunk has been read but its data and
-        # checksum have not (in other words the file position is just
-        # past the 4 bytes that specify the chunk type).  See preamble
-        # method for how this is used.
-        self.atchunk = None
-
-        if _guess is not None:
-            if isarray(_guess):
-                kw["bytes"] = _guess
-            elif isinstance(_guess, str):
-                kw["filename"] = _guess
-            elif isinstance(_guess, file):
-                kw["file"] = _guess
-
-        if "filename" in kw:
-            self.file = open(kw["filename"], "rb")
-        elif "file" in kw:
-            self.file = kw["file"]
-        elif "bytes" in kw:
-            self.file = _readable(kw["bytes"])
-        else:
-            raise TypeError("expecting filename, file or bytes array")
-
-
-    def chunk(self, seek=None, lenient=False):
-        """
-        Read the next PNG chunk from the input file; returns a
-        (*type*,*data*) tuple.  *type* is the chunk's type as a string
-        (all PNG chunk types are 4 characters long).  *data* is the
-        chunk's data content, as a string.
-
-        If the optional `seek` argument is
-        specified then it will keep reading chunks until it either runs
-        out of file or finds the type specified by the argument.  Note
-        that in general the order of chunks in PNGs is unspecified, so
-        using `seek` can cause you to miss chunks.
-
-        If the optional `lenient` argument evaluates to True,
-        checksum failures will raise warnings rather than exceptions.
-        """
-
-        self.validate_signature()
-
-        while True:
-            # http://www.w3.org/TR/PNG/#5Chunk-layout
-            if not self.atchunk:
-                self.atchunk = self.chunklentype()
-            length,type = self.atchunk
-            self.atchunk = None
-            data = self.file.read(length)
-            if len(data) != length:
-                raise ChunkError('Chunk %s too short for required %i octets.'
-                  % (type, length))
-            checksum = self.file.read(4)
-            if len(checksum) != 4:
-                raise ValueError('Chunk %s too short for checksum.', tag)
-            if seek and type != seek:
-                continue
-            verify = zlib.crc32(strtobytes(type))
-            verify = zlib.crc32(data, verify)
-            # Whether the output from zlib.crc32 is signed or not varies
-            # according to hideous implementation details, see
-            # http://bugs.python.org/issue1202 .
-            # We coerce it to be positive here (in a way which works on
-            # Python 2.3 and older).
-            verify &= 2**32 - 1
-            verify = struct.pack('!I', verify)
-            if checksum != verify:
-                # print repr(checksum)
-                (a, ) = struct.unpack('!I', checksum)
-                (b, ) = struct.unpack('!I', verify)
-                message = "Checksum error in %s chunk: 0x%08X != 0x%08X." % (type, a, b)
-                if lenient:
-                    warnings.warn(message, RuntimeWarning)
-                else:
-                    raise ChunkError(message)
-            return type, data
-
-    def chunks(self):
-        """Return an iterator that will yield each chunk as a
-        (*chunktype*, *content*) pair.
-        """
-
-        while True:
-            t,v = self.chunk()
-            yield t,v
-            if t == 'IEND':
-                break
-
-    def undo_filter(self, filter_type, scanline, previous):
-        """Undo the filter for a scanline.  `scanline` is a sequence of
-        bytes that does not include the initial filter type byte.
-        `previous` is decoded previous scanline (for straightlaced
-        images this is the previous pixel row, but for interlaced
-        images, it is the previous scanline in the reduced image, which
-        in general is not the previous pixel row in the final image).
-        When there is no previous scanline (the first row of a
-        straightlaced image, or the first row in one of the passes in an
-        interlaced image), then this argument should be ``None``.
-
-        The scanline will have the effects of filtering removed, and the
-        result will be returned as a fresh sequence of bytes.
-        """
-
-        # :todo: Would it be better to update scanline in place?
-        # Yes, with the Cython extension making the undo_filter fast,
-        # updating scanline inplace makes the code 3 times faster
-        # (reading 50 images of 800x800 went from 40s to 16s)
-        result = scanline
-
-        if filter_type == 0:
-            return result
-
-        if filter_type not in (1,2,3,4):
-            raise FormatError('Invalid PNG Filter Type.'
-              '  See http://www.w3.org/TR/2003/REC-PNG-20031110/#9Filters .')
-
-        # Filter unit.  The stride from one pixel to the corresponding
-        # byte from the previous previous.  Normally this is the pixel
-        # size in bytes, but when this is smaller than 1, the previous
-        # byte is used instead.
-        fu = max(1, self.psize)
-
-        # For the first line of a pass, synthesize a dummy previous
-        # line.  An alternative approach would be to observe that on the
-        # first line 'up' is the same as 'null', 'paeth' is the same
-        # as 'sub', with only 'average' requiring any special case.
-        if not previous:
-            previous = array('B', [0]*len(scanline))
-
-        def sub():
-            """Undo sub filter."""
-
-            ai = 0
-            # Loops starts at index fu.  Observe that the initial part
-            # of the result is already filled in correctly with
-            # scanline.
-            for i in range(fu, len(result)):
-                x = scanline[i]
-                a = result[ai]
-                result[i] = (x + a) & 0xff
-                ai += 1
-
-        def up():
-            """Undo up filter."""
-
-            for i in range(len(result)):
-                x = scanline[i]
-                b = previous[i]
-                result[i] = (x + b) & 0xff
-
-        def average():
-            """Undo average filter."""
-
-            ai = -fu
-            for i in range(len(result)):
-                x = scanline[i]
-                if ai < 0:
-                    a = 0
-                else:
-                    a = result[ai]
-                b = previous[i]
-                result[i] = (x + ((a + b) >> 1)) & 0xff
-                ai += 1
-
-        def paeth():
-            """Undo Paeth filter."""
-
-            # Also used for ci.
-            ai = -fu
-            for i in range(len(result)):
-                x = scanline[i]
-                if ai < 0:
-                    a = c = 0
-                else:
-                    a = result[ai]
-                    c = previous[ai]
-                b = previous[i]
-                p = a + b - c
-                pa = abs(p - a)
-                pb = abs(p - b)
-                pc = abs(p - c)
-                if pa <= pb and pa <= pc:
-                    pr = a
-                elif pb <= pc:
-                    pr = b
-                else:
-                    pr = c
-                result[i] = (x + pr) & 0xff
-                ai += 1
-
-        # Call appropriate filter algorithm.  Note that 0 has already
-        # been dealt with.
-        (None,
-         pngfilters.undo_filter_sub,
-         pngfilters.undo_filter_up,
-         pngfilters.undo_filter_average,
-         pngfilters.undo_filter_paeth)[filter_type](fu, scanline, previous, result)
-        return result
-
-    def deinterlace(self, raw):
-        """
-        Read raw pixel data, undo filters, deinterlace, and flatten.
-        Return in flat row flat pixel format.
-        """
-
-        # print >> sys.stderr, ("Reading interlaced, w=%s, r=%s, planes=%s," +
-        #     " bpp=%s") % (self.width, self.height, self.planes, self.bps)
-        # Values per row (of the target image)
-        vpr = self.width * self.planes
-
-        # Make a result array, and make it big enough.  Interleaving
-        # writes to the output array randomly (well, not quite), so the
-        # entire output array must be in memory.
-        fmt = 'BH'[self.bitdepth > 8]
-        a = array(fmt, [0]*vpr*self.height)
-        source_offset = 0
-
-        for xstart, ystart, xstep, ystep in _adam7:
-            # print >> sys.stderr, "Adam7: start=%s,%s step=%s,%s" % (
-            #     xstart, ystart, xstep, ystep)
-            if xstart >= self.width:
-                continue
-            # The previous (reconstructed) scanline.  None at the
-            # beginning of a pass to indicate that there is no previous
-            # line.
-            recon = None
-            # Pixels per row (reduced pass image)
-            ppr = int(math.ceil((self.width-xstart)/float(xstep)))
-            # Row size in bytes for this pass.
-            row_size = int(math.ceil(self.psize * ppr))
-            for y in range(ystart, self.height, ystep):
-                filter_type = raw[source_offset]
-                source_offset += 1
-                scanline = raw[source_offset:source_offset+row_size]
-                source_offset += row_size
-                recon = self.undo_filter(filter_type, scanline, recon)
-                # Convert so that there is one element per pixel value
-                flat = self.serialtoflat(recon, ppr)
-                if xstep == 1:
-                    assert xstart == 0
-                    offset = y * vpr
-                    a[offset:offset+vpr] = flat
-                else:
-                    offset = y * vpr + xstart * self.planes
-                    end_offset = (y+1) * vpr
-                    skip = self.planes * xstep
-                    for i in range(self.planes):
-                        a[offset+i:end_offset:skip] = \
-                            flat[i::self.planes]
-        return a
-
-    def iterboxed(self, rows):
-        """Iterator that yields each scanline in boxed row flat pixel
-        format.  `rows` should be an iterator that yields the bytes of
-        each row in turn.
-        """
-
-        def asvalues(raw):
-            """Convert a row of raw bytes into a flat row.  Result may
-            or may not share with argument"""
-
-            if self.bitdepth == 8:
-                return raw
-            if self.bitdepth == 16:
-                raw = tostring(raw)
-                return array('H', struct.unpack('!%dH' % (len(raw)//2), raw))
-            assert self.bitdepth < 8
-            width = self.width
-            # Samples per byte
-            spb = 8//self.bitdepth
-            out = array('B')
-            mask = 2**self.bitdepth - 1
-            shifts = map(self.bitdepth.__mul__, reversed(range(spb)))
-            for o in raw:
-                out.extend(map(lambda i: mask&(o>>i), shifts))
-            return out[:width]
-
-        return itertools.imap(asvalues, rows)
-
-    def serialtoflat(self, bytes, width=None):
-        """Convert serial format (byte stream) pixel data to flat row
-        flat pixel.
-        """
-
-        if self.bitdepth == 8:
-            return bytes
-        if self.bitdepth == 16:
-            bytes = tostring(bytes)
-            return array('H',
-              struct.unpack('!%dH' % (len(bytes)//2), bytes))
-        assert self.bitdepth < 8
-        if width is None:
-            width = self.width
-        # Samples per byte
-        spb = 8//self.bitdepth
-        out = array('B')
-        mask = 2**self.bitdepth - 1
-        shifts = map(self.bitdepth.__mul__, reversed(range(spb)))
-        l = width
-        for o in bytes:
-            out.extend([(mask&(o>>s)) for s in shifts][:l])
-            l -= spb
-            if l <= 0:
-                l = width
-        return out
-
-    def iterstraight(self, raw):
-        """Iterator that undoes the effect of filtering, and yields each
-        row in serialised format (as a sequence of bytes).  Assumes input
-        is straightlaced.  `raw` should be an iterable that yields the
-        raw bytes in chunks of arbitrary size."""
-
-        # length of row, in bytes
-        rb = self.row_bytes
-        a = array('B')
-        # The previous (reconstructed) scanline.  None indicates first
-        # line of image.
-        recon = None
-        for some in raw:
-            a.extend(some)
-            while len(a) >= rb + 1:
-                filter_type = a[0]
-                scanline = a[1:rb+1]
-                del a[:rb+1]
-                recon = self.undo_filter(filter_type, scanline, recon)
-                yield recon
-        if len(a) != 0:
-            # :file:format We get here with a file format error: when the
-            # available bytes (after decompressing) do not pack into exact
-            # rows.
-            raise FormatError(
-              'Wrong size for decompressed IDAT chunk.')
-        assert len(a) == 0
-
-    def validate_signature(self):
-        """If signature (header) has not been read then read and
-        validate it; otherwise do nothing.
-        """
-
-        if self.signature:
-            return
-        self.signature = self.file.read(8)
-        if self.signature != _signature:
-            raise FormatError("PNG file has invalid signature.")
-
-    def preamble(self, lenient=False):
-        """
-        Extract the image metadata by reading the initial part of the PNG
-        file up to the start of the ``IDAT`` chunk.  All the chunks that
-        precede the ``IDAT`` chunk are read and either processed for
-        metadata or discarded.
-
-        If the optional `lenient` argument evaluates to True,
-        checksum failures will raise warnings rather than exceptions.
-        """
-
-        self.validate_signature()
-
-        while True:
-            if not self.atchunk:
-                self.atchunk = self.chunklentype()
-                if self.atchunk is None:
-                    raise FormatError(
-                      'This PNG file has no IDAT chunks.')
-            if self.atchunk[1] == 'IDAT':
-                return
-            self.process_chunk(lenient=lenient)
-
-    def chunklentype(self):
-        """Reads just enough of the input to determine the next
-        chunk's length and type, returned as a (*length*, *type*) pair
-        where *type* is a string.  If there are no more chunks, ``None``
-        is returned.
-        """
-
-        x = self.file.read(8)
-        if not x:
-            return None
-        if len(x) != 8:
-            raise FormatError(
-              'End of file whilst reading chunk length and type.')
-        length,type = struct.unpack('!I4s', x)
-        type = bytestostr(type)
-        if length > 2**31-1:
-            raise FormatError('Chunk %s is too large: %d.' % (type,length))
-        return length,type
-
-    def process_chunk(self, lenient=False):
-        """Process the next chunk and its data.  This only processes the
-        following chunk types, all others are ignored: ``IHDR``,
-        ``PLTE``, ``bKGD``, ``tRNS``, ``gAMA``, ``sBIT``.
-
-        If the optional `lenient` argument evaluates to True,
-        checksum failures will raise warnings rather than exceptions.
-        """
-
-        type, data = self.chunk(lenient=lenient)
-        if type == 'IHDR':
-            # http://www.w3.org/TR/PNG/#11IHDR
-            if len(data) != 13:
-                raise FormatError('IHDR chunk has incorrect length.')
-            (self.width, self.height, self.bitdepth, self.color_type,
-             self.compression, self.filter,
-             self.interlace) = struct.unpack("!2I5B", data)
-
-            # Check that the header specifies only valid combinations.
-            if self.bitdepth not in (1,2,4,8,16):
-                raise Error("invalid bit depth %d" % self.bitdepth)
-            if self.color_type not in (0,2,3,4,6):
-                raise Error("invalid colour type %d" % self.color_type)
-            # Check indexed (palettized) images have 8 or fewer bits
-            # per pixel; check only indexed or greyscale images have
-            # fewer than 8 bits per pixel.
-            if ((self.color_type & 1 and self.bitdepth > 8) or
-                (self.bitdepth < 8 and self.color_type not in (0,3))):
-                raise FormatError("Illegal combination of bit depth (%d)"
-                  " and colour type (%d)."
-                  " See http://www.w3.org/TR/2003/REC-PNG-20031110/#table111 ."
-                  % (self.bitdepth, self.color_type))
-            if self.compression != 0:
-                raise Error("unknown compression method %d" % self.compression)
-            if self.filter != 0:
-                raise FormatError("Unknown filter method %d,"
-                  " see http://www.w3.org/TR/2003/REC-PNG-20031110/#9Filters ."
-                  % self.filter)
-            if self.interlace not in (0,1):
-                raise FormatError("Unknown interlace method %d,"
-                  " see http://www.w3.org/TR/2003/REC-PNG-20031110/#8InterlaceMethods ."
-                  % self.interlace)
-
-            # Derived values
-            # http://www.w3.org/TR/PNG/#6Colour-values
-            colormap =  bool(self.color_type & 1)
-            greyscale = not (self.color_type & 2)
-            alpha = bool(self.color_type & 4)
-            color_planes = (3,1)[greyscale or colormap]
-            planes = color_planes + alpha
-
-            self.colormap = colormap
-            self.greyscale = greyscale
-            self.alpha = alpha
-            self.color_planes = color_planes
-            self.planes = planes
-            self.psize = float(self.bitdepth)/float(8) * planes
-            if int(self.psize) == self.psize:
-                self.psize = int(self.psize)
-            self.row_bytes = int(math.ceil(self.width * self.psize))
-            # Stores PLTE chunk if present, and is used to check
-            # chunk ordering constraints.
-            self.plte = None
-            # Stores tRNS chunk if present, and is used to check chunk
-            # ordering constraints.
-            self.trns = None
-            # Stores sbit chunk if present.
-            self.sbit = None
-        elif type == 'PLTE':
-            # http://www.w3.org/TR/PNG/#11PLTE
-            if self.plte:
-                warnings.warn("Multiple PLTE chunks present.")
-            self.plte = data
-            if len(data) % 3 != 0:
-                raise FormatError(
-                  "PLTE chunk's length should be a multiple of 3.")
-            if len(data) > (2**self.bitdepth)*3:
-                raise FormatError("PLTE chunk is too long.")
-            if len(data) == 0:
-                raise FormatError("Empty PLTE is not allowed.")
-        elif type == 'bKGD':
-            try:
-                if self.colormap:
-                    if not self.plte:
-                        warnings.warn(
-                          "PLTE chunk is required before bKGD chunk.")
-                    self.background = struct.unpack('B', data)
-                else:
-                    self.background = struct.unpack("!%dH" % self.color_planes,
-                      data)
-            except struct.error:
-                raise FormatError("bKGD chunk has incorrect length.")
-        elif type == 'tRNS':
-            # http://www.w3.org/TR/PNG/#11tRNS
-            self.trns = data
-            if self.colormap:
-                if not self.plte:
-                    warnings.warn("PLTE chunk is required before tRNS chunk.")
-                else:
-                    if len(data) > len(self.plte)/3:
-                        # Was warning, but promoted to Error as it
-                        # would otherwise cause pain later on.
-                        raise FormatError("tRNS chunk is too long.")
-            else:
-                if self.alpha:
-                    raise FormatError(
-                      "tRNS chunk is not valid with colour type %d." %
-                      self.color_type)
-                try:
-                    self.transparent = \
-                        struct.unpack("!%dH" % self.color_planes, data)
-                except struct.error:
-                    raise FormatError("tRNS chunk has incorrect length.")
-        elif type == 'gAMA':
-            try:
-                self.gamma = struct.unpack("!L", data)[0] / 100000.0
-            except struct.error:
-                raise FormatError("gAMA chunk has incorrect length.")
-        elif type == 'sBIT':
-            self.sbit = data
-            if (self.colormap and len(data) != 3 or
-                not self.colormap and len(data) != self.planes):
-                raise FormatError("sBIT chunk has incorrect length.")
-
-    def read(self, lenient=False):
-        """
-        Read the PNG file and decode it.  Returns (`width`, `height`,
-        `pixels`, `metadata`).
-
-        May use excessive memory.
-
-        `pixels` are returned in boxed row flat pixel format.
-
-        If the optional `lenient` argument evaluates to True,
-        checksum failures will raise warnings rather than exceptions.
-        """
-
-        def iteridat():
-            """Iterator that yields all the ``IDAT`` chunks as strings."""
-            while True:
-                try:
-                    type, data = self.chunk(lenient=lenient)
-                except ValueError, e:
-                    raise ChunkError(e.args[0])
-                if type == 'IEND':
-                    # http://www.w3.org/TR/PNG/#11IEND
-                    break
-                if type != 'IDAT':
-                    continue
-                # type == 'IDAT'
-                # http://www.w3.org/TR/PNG/#11IDAT
-                if self.colormap and not self.plte:
-                    warnings.warn("PLTE chunk is required before IDAT chunk")
-                yield data
-
-        def iterdecomp(idat):
-            """Iterator that yields decompressed strings.  `idat` should
-            be an iterator that yields the ``IDAT`` chunk data.
-            """
-
-            # Currently, with no max_length paramter to decompress, this
-            # routine will do one yield per IDAT chunk.  So not very
-            # incremental.
-            d = zlib.decompressobj()
-            # Each IDAT chunk is passed to the decompressor, then any
-            # remaining state is decompressed out.
-            for data in idat:
-                # :todo: add a max_length argument here to limit output
-                # size.
-                yield array('B', d.decompress(data))
-            yield array('B', d.flush())
-
-        self.preamble(lenient=lenient)
-        raw = iterdecomp(iteridat())
-
-        if self.interlace:
-            raw = array('B', itertools.chain(*raw))
-            arraycode = 'BH'[self.bitdepth>8]
-            # Like :meth:`group` but producing an array.array object for
-            # each row.
-            pixels = itertools.imap(lambda *row: array(arraycode, row),
-                       *[iter(self.deinterlace(raw))]*self.width*self.planes)
-        else:
-            pixels = self.iterboxed(self.iterstraight(raw))
-        meta = dict()
-        for attr in 'greyscale alpha planes bitdepth interlace'.split():
-            meta[attr] = getattr(self, attr)
-        meta['size'] = (self.width, self.height)
-        for attr in 'gamma transparent background'.split():
-            a = getattr(self, attr, None)
-            if a is not None:
-                meta[attr] = a
-        if self.plte:
-            meta['palette'] = self.palette()
-        return self.width, self.height, pixels, meta
-
-
-    def read_flat(self):
-        """
-        Read a PNG file and decode it into flat row flat pixel format.
-        Returns (*width*, *height*, *pixels*, *metadata*).
-
-        May use excessive memory.
-
-        `pixels` are returned in flat row flat pixel format.
-
-        See also the :meth:`read` method which returns pixels in the
-        more stream-friendly boxed row flat pixel format.
-        """
-
-        x, y, pixel, meta = self.read()
-        arraycode = 'BH'[meta['bitdepth']>8]
-        pixel = array(arraycode, itertools.chain(*pixel))
-        return x, y, pixel, meta
-
-    def palette(self, alpha='natural'):
-        """Returns a palette that is a sequence of 3-tuples or 4-tuples,
-        synthesizing it from the ``PLTE`` and ``tRNS`` chunks.  These
-        chunks should have already been processed (for example, by
-        calling the :meth:`preamble` method).  All the tuples are the
-        same size: 3-tuples if there is no ``tRNS`` chunk, 4-tuples when
-        there is a ``tRNS`` chunk.  Assumes that the image is colour type
-        3 and therefore a ``PLTE`` chunk is required.
-
-        If the `alpha` argument is ``'force'`` then an alpha channel is
-        always added, forcing the result to be a sequence of 4-tuples.
-        """
-
-        if not self.plte:
-            raise FormatError(
-                "Required PLTE chunk is missing in colour type 3 image.")
-        plte = group(array('B', self.plte), 3)
-        if self.trns or alpha == 'force':
-            trns = array('B', self.trns or '')
-            trns.extend([255]*(len(plte)-len(trns)))
-            plte = map(operator.add, plte, group(trns, 1))
-        return plte
-
-    def asDirect(self):
-        """Returns the image data as a direct representation of an
-        ``x * y * planes`` array.  This method is intended to remove the
-        need for callers to deal with palettes and transparency
-        themselves.  Images with a palette (colour type 3)
-        are converted to RGB or RGBA; images with transparency (a
-        ``tRNS`` chunk) are converted to LA or RGBA as appropriate.
-        When returned in this format the pixel values represent the
-        colour value directly without needing to refer to palettes or
-        transparency information.
-
-        Like the :meth:`read` method this method returns a 4-tuple:
-
-        (*width*, *height*, *pixels*, *meta*)
-
-        This method normally returns pixel values with the bit depth
-        they have in the source image, but when the source PNG has an
-        ``sBIT`` chunk it is inspected and can reduce the bit depth of
-        the result pixels; pixel values will be reduced according to
-        the bit depth specified in the ``sBIT`` chunk (PNG nerds should
-        note a single result bit depth is used for all channels; the
-        maximum of the ones specified in the ``sBIT`` chunk.  An RGB565
-        image will be rescaled to 6-bit RGB666).
-
-        The *meta* dictionary that is returned reflects the `direct`
-        format and not the original source image.  For example, an RGB
-        source image with a ``tRNS`` chunk to represent a transparent
-        colour, will have ``planes=3`` and ``alpha=False`` for the
-        source image, but the *meta* dictionary returned by this method
-        will have ``planes=4`` and ``alpha=True`` because an alpha
-        channel is synthesized and added.
-
-        *pixels* is the pixel data in boxed row flat pixel format (just
-        like the :meth:`read` method).
-
-        All the other aspects of the image data are not changed.
-        """
-
-        self.preamble()
-
-        # Simple case, no conversion necessary.
-        if not self.colormap and not self.trns and not self.sbit:
-            return self.read()
-
-        x,y,pixels,meta = self.read()
-
-        if self.colormap:
-            meta['colormap'] = False
-            meta['alpha'] = bool(self.trns)
-            meta['bitdepth'] = 8
-            meta['planes'] = 3 + bool(self.trns)
-            plte = self.palette()
-            def iterpal(pixels):
-                for row in pixels:
-                    row = map(plte.__getitem__, row)
-                    yield array('B', itertools.chain(*row))
-            pixels = iterpal(pixels)
-        elif self.trns:
-            # It would be nice if there was some reasonable way of doing
-            # this without generating a whole load of intermediate tuples.
-            # But tuples does seem like the easiest way, with no other way
-            # clearly much simpler or much faster.  (Actually, the L to LA
-            # conversion could perhaps go faster (all those 1-tuples!), but
-            # I still wonder whether the code proliferation is worth it)
-            it = self.transparent
-            maxval = 2**meta['bitdepth']-1
-            planes = meta['planes']
-            meta['alpha'] = True
-            meta['planes'] += 1
-            typecode = 'BH'[meta['bitdepth']>8]
-            def itertrns(pixels):
-                for row in pixels:
-                    # For each row we group it into pixels, then form a
-                    # characterisation vector that says whether each pixel
-                    # is opaque or not.  Then we convert True/False to
-                    # 0/maxval (by multiplication), and add it as the extra
-                    # channel.
-                    row = group(row, planes)
-                    opa = map(it.__ne__, row)
-                    opa = map(maxval.__mul__, opa)
-                    opa = zip(opa) # convert to 1-tuples
-                    yield array(typecode,
-                      itertools.chain(*map(operator.add, row, opa)))
-            pixels = itertrns(pixels)
-        targetbitdepth = None
-        if self.sbit:
-            sbit = struct.unpack('%dB' % len(self.sbit), self.sbit)
-            targetbitdepth = max(sbit)
-            if targetbitdepth > meta['bitdepth']:
-                raise Error('sBIT chunk %r exceeds bitdepth %d' %
-                    (sbit,self.bitdepth))
-            if min(sbit) <= 0:
-                raise Error('sBIT chunk %r has a 0-entry' % sbit)
-            if targetbitdepth == meta['bitdepth']:
-                targetbitdepth = None
-        if targetbitdepth:
-            shift = meta['bitdepth'] - targetbitdepth
-            meta['bitdepth'] = targetbitdepth
-            def itershift(pixels):
-                for row in pixels:
-                    yield map(shift.__rrshift__, row)
-            pixels = itershift(pixels)
-        return x,y,pixels,meta
-
-    def asFloat(self, maxval=1.0):
-        """Return image pixels as per :meth:`asDirect` method, but scale
-        all pixel values to be floating point values between 0.0 and
-        *maxval*.
-        """
-
-        x,y,pixels,info = self.asDirect()
-        sourcemaxval = 2**info['bitdepth']-1
-        del info['bitdepth']
-        info['maxval'] = float(maxval)
-        factor = float(maxval)/float(sourcemaxval)
-        def iterfloat():
-            for row in pixels:
-                yield map(factor.__mul__, row)
-        return x,y,iterfloat(),info
-
-    def _as_rescale(self, get, targetbitdepth):
-        """Helper used by :meth:`asRGB8` and :meth:`asRGBA8`."""
-
-        width,height,pixels,meta = get()
-        maxval = 2**meta['bitdepth'] - 1
-        targetmaxval = 2**targetbitdepth - 1
-        factor = float(targetmaxval) / float(maxval)
-        meta['bitdepth'] = targetbitdepth
-        def iterscale():
-            for row in pixels:
-                yield map(lambda x: int(round(x*factor)), row)
-        if maxval == targetmaxval:
-            return width, height, pixels, meta
-        else:
-            return width, height, iterscale(), meta
-
-    def asRGB8(self):
-        """Return the image data as an RGB pixels with 8-bits per
-        sample.  This is like the :meth:`asRGB` method except that
-        this method additionally rescales the values so that they
-        are all between 0 and 255 (8-bit).  In the case where the
-        source image has a bit depth < 8 the transformation preserves
-        all the information; where the source image has bit depth
-        > 8, then rescaling to 8-bit values loses precision.  No
-        dithering is performed.  Like :meth:`asRGB`, an alpha channel
-        in the source image will raise an exception.
-
-        This function returns a 4-tuple:
-        (*width*, *height*, *pixels*, *metadata*).
-        *width*, *height*, *metadata* are as per the :meth:`read` method.
-        
-        *pixels* is the pixel data in boxed row flat pixel format.
-        """
-
-        return self._as_rescale(self.asRGB, 8)
-
-    def asRGBA8(self):
-        """Return the image data as RGBA pixels with 8-bits per
-        sample.  This method is similar to :meth:`asRGB8` and
-        :meth:`asRGBA`:  The result pixels have an alpha channel, *and*
-        values are rescaled to the range 0 to 255.  The alpha channel is
-        synthesized if necessary (with a small speed penalty).
-        """
-
-        return self._as_rescale(self.asRGBA, 8)
-
-    def asRGB(self):
-        """Return image as RGB pixels.  RGB colour images are passed
-        through unchanged; greyscales are expanded into RGB
-        triplets (there is a small speed overhead for doing this).
-
-        An alpha channel in the source image will raise an
-        exception.
-
-        The return values are as for the :meth:`read` method
-        except that the *metadata* reflect the returned pixels, not the
-        source image.  In particular, for this method
-        ``metadata['greyscale']`` will be ``False``.
-        """
-
-        width,height,pixels,meta = self.asDirect()
-        if meta['alpha']:
-            raise Error("will not convert image with alpha channel to RGB")
-        if not meta['greyscale']:
-            return width,height,pixels,meta
-        meta['greyscale'] = False
-        typecode = 'BH'[meta['bitdepth'] > 8]
-        def iterrgb():
-            for row in pixels:
-                a = array(typecode, [0]) * 3 * width
-                for i in range(3):
-                    a[i::3] = row
-                yield a
-        return width,height,iterrgb(),meta
-
-    def asRGBA(self):
-        """Return image as RGBA pixels.  Greyscales are expanded into
-        RGB triplets; an alpha channel is synthesized if necessary.
-        The return values are as for the :meth:`read` method
-        except that the *metadata* reflect the returned pixels, not the
-        source image.  In particular, for this method
-        ``metadata['greyscale']`` will be ``False``, and
-        ``metadata['alpha']`` will be ``True``.
-        """
-
-        width,height,pixels,meta = self.asDirect()
-        if meta['alpha'] and not meta['greyscale']:
-            return width,height,pixels,meta
-        typecode = 'BH'[meta['bitdepth'] > 8]
-        maxval = 2**meta['bitdepth'] - 1
-        maxbuffer = struct.pack('=' + typecode, maxval) * 4 * width
-        def newarray():
-            return array(typecode, maxbuffer)
-
-        if meta['alpha'] and meta['greyscale']:
-            # LA to RGBA
-            def convert():
-                for row in pixels:
-                    # Create a fresh target row, then copy L channel
-                    # into first three target channels, and A channel
-                    # into fourth channel.
-                    a = newarray()
-                    pngfilters.convert_la_to_rgba(row, a)
-                    yield a
-        elif meta['greyscale']:
-            # L to RGBA
-            def convert():
-                for row in pixels:
-                    a = newarray()
-                    pngfilters.convert_l_to_rgba(row, a)
-                    yield a
-        else:
-            assert not meta['alpha'] and not meta['greyscale']
-            # RGB to RGBA
-            def convert():
-                for row in pixels:
-                    a = newarray()
-                    pngfilters.convert_rgb_to_rgba(row, a)
-                    yield a
-        meta['alpha'] = True
-        meta['greyscale'] = False
-        return width,height,convert(),meta
-
-
-# === Legacy Version Support ===
-
-# :pyver:old:  PyPNG works on Python versions 2.3 and 2.2, but not
-# without some awkward problems.  Really PyPNG works on Python 2.4 (and
-# above); it works on Pythons 2.3 and 2.2 by virtue of fixing up
-# problems here.  It's a bit ugly (which is why it's hidden down here).
-#
-# Generally the strategy is one of pretending that we're running on
-# Python 2.4 (or above), and patching up the library support on earlier
-# versions so that it looks enough like Python 2.4.  When it comes to
-# Python 2.2 there is one thing we cannot patch: extended slices
-# http://www.python.org/doc/2.3/whatsnew/section-slices.html.
-# Instead we simply declare that features that are implemented using
-# extended slices will not work on Python 2.2.
-#
-# In order to work on Python 2.3 we fix up a recurring annoyance involving
-# the array type.  In Python 2.3 an array cannot be initialised with an
-# array, and it cannot be extended with a list (or other sequence).
-# Both of those are repeated issues in the code.  Whilst I would not
-# normally tolerate this sort of behaviour, here we "shim" a replacement
-# for array into place (and hope no-ones notices).  You never read this.
-#
-# In an amusing case of warty hacks on top of warty hacks... the array
-# shimming we try and do only works on Python 2.3 and above (you can't
-# subclass array.array in Python 2.2).  So to get it working on Python
-# 2.2 we go for something much simpler and (probably) way slower.
-try:
-    array('B').extend([])
-    array('B', array('B'))
-except:
-    # Expect to get here on Python 2.3
-    try:
-        class _array_shim(array):
-            true_array = array
-            def __new__(cls, typecode, init=None):
-                super_new = super(_array_shim, cls).__new__
-                it = super_new(cls, typecode)
-                if init is None:
-                    return it
-                it.extend(init)
-                return it
-            def extend(self, extension):
-                super_extend = super(_array_shim, self).extend
-                if isinstance(extension, self.true_array):
-                    return super_extend(extension)
-                if not isinstance(extension, (list, str)):
-                    # Convert to list.  Allows iterators to work.
-                    extension = list(extension)
-                return super_extend(self.true_array(self.typecode, extension))
-        array = _array_shim
-    except:
-        # Expect to get here on Python 2.2
-        def array(typecode, init=()):
-            if type(init) == str:
-                return map(ord, init)
-            return list(init)
-
-# Further hacks to get it limping along on Python 2.2
-try:
-    enumerate
-except:
-    def enumerate(seq):
-        i=0
-        for x in seq:
-            yield i,x
-            i += 1
-
-try:
-    reversed
-except:
-    def reversed(l):
-        l = list(l)
-        l.reverse()
-        for x in l:
-            yield x
-
-try:
-    itertools
-except:
-    class _dummy_itertools:
-        pass
-    itertools = _dummy_itertools()
-    def _itertools_imap(f, seq):
-        for x in seq:
-            yield f(x)
-    itertools.imap = _itertools_imap
-    def _itertools_chain(*iterables):
-        for it in iterables:
-            for element in it:
-                yield element
-    itertools.chain = _itertools_chain
-
-
-# === Support for users without Cython ===
-
-try:
-    pngfilters
-except:
-    class pngfilters(object):
-        def undo_filter_sub(filter_unit, scanline, previous, result):
-            """Undo sub filter."""
-
-            ai = 0
-            # Loops starts at index fu.  Observe that the initial part
-            # of the result is already filled in correctly with
-            # scanline.
-            for i in range(filter_unit, len(result)):
-                x = scanline[i]
-                a = result[ai]
-                result[i] = (x + a) & 0xff
-                ai += 1
-        undo_filter_sub = staticmethod(undo_filter_sub)
-
-        def undo_filter_up(filter_unit, scanline, previous, result):
-            """Undo up filter."""
-
-            for i in range(len(result)):
-                x = scanline[i]
-                b = previous[i]
-                result[i] = (x + b) & 0xff
-        undo_filter_up = staticmethod(undo_filter_up)
-
-        def undo_filter_average(filter_unit, scanline, previous, result):
-            """Undo up filter."""
-
-            ai = -filter_unit
-            for i in range(len(result)):
-                x = scanline[i]
-                if ai < 0:
-                    a = 0
-                else:
-                    a = result[ai]
-                b = previous[i]
-                result[i] = (x + ((a + b) >> 1)) & 0xff
-                ai += 1
-        undo_filter_average = staticmethod(undo_filter_average)
-
-        def undo_filter_paeth(filter_unit, scanline, previous, result):
-            """Undo Paeth filter."""
-
-            # Also used for ci.
-            ai = -filter_unit
-            for i in range(len(result)):
-                x = scanline[i]
-                if ai < 0:
-                    a = c = 0
-                else:
-                    a = result[ai]
-                    c = previous[ai]
-                b = previous[i]
-                p = a + b - c
-                pa = abs(p - a)
-                pb = abs(p - b)
-                pc = abs(p - c)
-                if pa <= pb and pa <= pc:
-                    pr = a
-                elif pb <= pc:
-                    pr = b
-                else:
-                    pr = c
-                result[i] = (x + pr) & 0xff
-                ai += 1
-        undo_filter_paeth = staticmethod(undo_filter_paeth)
-
-        def convert_la_to_rgba(row, result):
-            for i in range(3):
-                result[i::4] = row[0::2]
-            result[3::4] = row[1::2]
-        convert_la_to_rgba = staticmethod(convert_la_to_rgba)
-
-        def convert_l_to_rgba(row, result):
-            """Convert a grayscale image to RGBA. This method assumes the alpha
-            channel in result is already correctly initialized."""
-            for i in range(3):
-                result[i::4] = row
-        convert_l_to_rgba = staticmethod(convert_l_to_rgba)
-
-        def convert_rgb_to_rgba(row, result):
-            """Convert an RGB image to RGBA. This method assumes the alpha
-            channel in result is already correctly initialized."""
-            for i in range(3):
-                result[i::4] = row[i::3]
-        convert_rgb_to_rgba = staticmethod(convert_rgb_to_rgba)
-
-
-# === Internal Test Support ===
-
-# This section comprises the tests that are internally validated (as
-# opposed to tests which produce output files that are externally
-# validated).  Primarily they are unittests.
-
-# Note that it is difficult to internally validate the results of
-# writing a PNG file.  The only thing we can do is read it back in
-# again, which merely checks consistency, not that the PNG file we
-# produce is valid.
-
-# Run the tests from the command line:
-# python -c 'import png;png.test()'
-
-# (For an in-memory binary file IO object) We use BytesIO where
-# available, otherwise we use StringIO, but name it BytesIO.
-try:
-    from io import BytesIO
-except:
-    from StringIO import StringIO as BytesIO
-import tempfile
-# http://www.python.org/doc/2.4.4/lib/module-unittest.html
-import unittest
-
-
-def test():
-    unittest.main(__name__)
-
-def topngbytes(name, rows, x, y, **k):
-    """Convenience function for creating a PNG file "in memory" as a
-    string.  Creates a :class:`Writer` instance using the keyword arguments,
-    then passes `rows` to its :meth:`Writer.write` method.  The resulting
-    PNG file is returned as a string.  `name` is used to identify the file for
-    debugging.
-    """
-
-    import os
-
-    print name
-    f = BytesIO()
-    w = Writer(x, y, **k)
-    w.write(f, rows)
-    if os.environ.get('PYPNG_TEST_TMP'):
-        w = open(name, 'wb')
-        w.write(f.getvalue())
-        w.close()
-    return f.getvalue()
-
-def testWithIO(inp, out, f):
-    """Calls the function `f` with ``sys.stdin`` changed to `inp`
-    and ``sys.stdout`` changed to `out`.  They are restored when `f`
-    returns.  This function returns whatever `f` returns.
-    """
-
-    import os
-
-    try:
-        oldin,sys.stdin = sys.stdin,inp
-        oldout,sys.stdout = sys.stdout,out
-        x = f()
-    finally:
-        sys.stdin = oldin
-        sys.stdout = oldout
-    if os.environ.get('PYPNG_TEST_TMP') and hasattr(out,'getvalue'):
-        name = mycallersname()
-        if name:
-            w = open(name+'.png', 'wb')
-            w.write(out.getvalue())
-            w.close()
-    return x
-
-def mycallersname():
-    """Returns the name of the caller of the caller of this function
-    (hence the name of the caller of the function in which
-    "mycallersname()" textually appears).  Returns None if this cannot
-    be determined."""
-
-    # http://docs.python.org/library/inspect.html#the-interpreter-stack
-    import inspect
-
-    frame = inspect.currentframe()
-    if not frame:
-        return None
-    frame_,filename_,lineno_,funname,linelist_,listi_ = (
-      inspect.getouterframes(frame)[2])
-    return funname
-
-def seqtobytes(s):
-    """Convert a sequence of integers to a *bytes* instance.  Good for
-    plastering over Python 2 / Python 3 cracks.
-    """
-
-    return strtobytes(''.join(chr(x) for x in s))
-
-class Test(unittest.TestCase):
-    # This member is used by the superclass.  If we don't define a new
-    # class here then when we use self.assertRaises() and the PyPNG code
-    # raises an assertion then we get no proper traceback.  I can't work
-    # out why, but defining a new class here means we get a proper
-    # traceback.
-    class failureException(Exception):
-        pass
-
-    def helperLN(self, n):
-        mask = (1 << n) - 1
-        # Use small chunk_limit so that multiple chunk writing is
-        # tested.  Making it a test for Issue 20.
-        w = Writer(15, 17, greyscale=True, bitdepth=n, chunk_limit=99)
-        f = BytesIO()
-        w.write_array(f, array('B', map(mask.__and__, range(1, 256))))
-        r = Reader(bytes=f.getvalue())
-        x,y,pixels,meta = r.read()
-        self.assertEqual(x, 15)
-        self.assertEqual(y, 17)
-        self.assertEqual(list(itertools.chain(*pixels)),
-                         map(mask.__and__, range(1,256)))
-    def testL8(self):
-        return self.helperLN(8)
-    def testL4(self):
-        return self.helperLN(4)
-    def testL2(self):
-        "Also tests asRGB8."
-        w = Writer(1, 4, greyscale=True, bitdepth=2)
-        f = BytesIO()
-        w.write_array(f, array('B', range(4)))
-        r = Reader(bytes=f.getvalue())
-        x,y,pixels,meta = r.asRGB8()
-        self.assertEqual(x, 1)
-        self.assertEqual(y, 4)
-        for i,row in enumerate(pixels):
-            self.assertEqual(len(row), 3)
-            self.assertEqual(list(row), [0x55*i]*3)
-    def testP2(self):
-        "2-bit palette."
-        a = (255,255,255)
-        b = (200,120,120)
-        c = (50,99,50)
-        w = Writer(1, 4, bitdepth=2, palette=[a,b,c])
-        f = BytesIO()
-        w.write_array(f, array('B', (0,1,1,2)))
-        r = Reader(bytes=f.getvalue())
-        x,y,pixels,meta = r.asRGB8()
-        self.assertEqual(x, 1)
-        self.assertEqual(y, 4)
-        self.assertEqual(map(list, pixels), map(list, [a, b, b, c]))
-    def testPtrns(self):
-        "Test colour type 3 and tRNS chunk (and 4-bit palette)."
-        a = (50,99,50,50)
-        b = (200,120,120,80)
-        c = (255,255,255)
-        d = (200,120,120)
-        e = (50,99,50)
-        w = Writer(3, 3, bitdepth=4, palette=[a,b,c,d,e])
-        f = BytesIO()
-        w.write_array(f, array('B', (4, 3, 2, 3, 2, 0, 2, 0, 1)))
-        r = Reader(bytes=f.getvalue())
-        x,y,pixels,meta = r.asRGBA8()
-        self.assertEqual(x, 3)
-        self.assertEqual(y, 3)
-        c = c+(255,)
-        d = d+(255,)
-        e = e+(255,)
-        boxed = [(e,d,c),(d,c,a),(c,a,b)]
-        flat = map(lambda row: itertools.chain(*row), boxed)
-        self.assertEqual(map(list, pixels), map(list, flat))
-    def testRGBtoRGBA(self):
-        "asRGBA8() on colour type 2 source."""
-        # Test for Issue 26
-        r = Reader(bytes=_pngsuite['basn2c08'])
-        x,y,pixels,meta = r.asRGBA8()
-        # Test the pixels at row 9 columns 0 and 1.
-        row9 = list(pixels)[9]
-        self.assertEqual(list(row9[0:8]),
-                         [0xff, 0xdf, 0xff, 0xff, 0xff, 0xde, 0xff, 0xff])
-    def testLtoRGBA(self):
-        "asRGBA() on grey source."""
-        # Test for Issue 60
-        r = Reader(bytes=_pngsuite['basi0g08'])
-        x,y,pixels,meta = r.asRGBA()
-        row9 = list(list(pixels)[9])
-        self.assertEqual(row9[0:8],
-          [222, 222, 222, 255, 221, 221, 221, 255])
-    def testCtrns(self):
-        "Test colour type 2 and tRNS chunk."
-        # Test for Issue 25
-        r = Reader(bytes=_pngsuite['tbrn2c08'])
-        x,y,pixels,meta = r.asRGBA8()
-        # I just happen to know that the first pixel is transparent.
-        # In particular it should be #7f7f7f00
-        row0 = list(pixels)[0]
-        self.assertEqual(tuple(row0[0:4]), (0x7f, 0x7f, 0x7f, 0x00))
-    def testAdam7read(self):
-        """Adam7 interlace reading.
-        Specifically, test that for images in the PngSuite that
-        have both an interlaced and straightlaced pair that both
-        images from the pair produce the same array of pixels."""
-        for candidate in _pngsuite:
-            if not candidate.startswith('basn'):
-                continue
-            candi = candidate.replace('n', 'i')
-            if candi not in _pngsuite:
-                continue
-            print 'adam7 read', candidate
-            straight = Reader(bytes=_pngsuite[candidate])
-            adam7 = Reader(bytes=_pngsuite[candi])
-            # Just compare the pixels.  Ignore x,y (because they're
-            # likely to be correct?); metadata is ignored because the
-            # "interlace" member differs.  Lame.
-            straight = straight.read()[2]
-            adam7 = adam7.read()[2]
-            self.assertEqual(map(list, straight), map(list, adam7))
-    def testAdam7write(self):
-        """Adam7 interlace writing.
-        For each test image in the PngSuite, write an interlaced
-        and a straightlaced version.  Decode both, and compare results.
-        """
-        # Not such a great test, because the only way we can check what
-        # we have written is to read it back again.
-
-        for name,bytes in _pngsuite.items():
-            # Only certain colour types supported for this test.
-            if name[3:5] not in ['n0', 'n2', 'n4', 'n6']:
-                continue
-            it = Reader(bytes=bytes)
-            x,y,pixels,meta = it.read()
-            pngi = topngbytes('adam7wn'+name+'.png', pixels,
-              x=x, y=y, bitdepth=it.bitdepth,
-              greyscale=it.greyscale, alpha=it.alpha,
-              transparent=it.transparent,
-              interlace=False)
-            x,y,ps,meta = Reader(bytes=pngi).read()
-            it = Reader(bytes=bytes)
-            x,y,pixels,meta = it.read()
-            pngs = topngbytes('adam7wi'+name+'.png', pixels,
-              x=x, y=y, bitdepth=it.bitdepth,
-              greyscale=it.greyscale, alpha=it.alpha,
-              transparent=it.transparent,
-              interlace=True)
-            x,y,pi,meta = Reader(bytes=pngs).read()
-            self.assertEqual(map(list, ps), map(list, pi))
-    def testPGMin(self):
-        """Test that the command line tool can read PGM files."""
-        def do():
-            return _main(['testPGMin'])
-        s = BytesIO()
-        s.write(strtobytes('P5 2 2 3\n'))
-        s.write(strtobytes('\x00\x01\x02\x03'))
-        s.flush()
-        s.seek(0)
-        o = BytesIO()
-        testWithIO(s, o, do)
-        r = Reader(bytes=o.getvalue())
-        x,y,pixels,meta = r.read()
-        self.assertTrue(r.greyscale)
-        self.assertEqual(r.bitdepth, 2)
-    def testPAMin(self):
-        """Test that the command line tool can read PAM file."""
-        def do():
-            return _main(['testPAMin'])
-        s = BytesIO()
-        s.write(strtobytes('P7\nWIDTH 3\nHEIGHT 1\nDEPTH 4\nMAXVAL 255\n'
-                'TUPLTYPE RGB_ALPHA\nENDHDR\n'))
-        # The pixels in flat row flat pixel format
-        flat =  [255,0,0,255, 0,255,0,120, 0,0,255,30]
-        asbytes = seqtobytes(flat)
-        s.write(asbytes)
-        s.flush()
-        s.seek(0)
-        o = BytesIO()
-        testWithIO(s, o, do)
-        r = Reader(bytes=o.getvalue())
-        x,y,pixels,meta = r.read()
-        self.assertTrue(r.alpha)
-        self.assertTrue(not r.greyscale)
-        self.assertEqual(list(itertools.chain(*pixels)), flat)
-    def testLA4(self):
-        """Create an LA image with bitdepth 4."""
-        bytes = topngbytes('la4.png', [[5, 12]], 1, 1,
-          greyscale=True, alpha=True, bitdepth=4)
-        sbit = Reader(bytes=bytes).chunk('sBIT')[1]
-        self.assertEqual(sbit, strtobytes('\x04\x04'))
-    def testPal(self):
-        """Test that a palette PNG returns the palette in info."""
-        r = Reader(bytes=_pngsuite['basn3p04'])
-        x,y,pixels,info = r.read()
-        self.assertEqual(x, 32)
-        self.assertEqual(y, 32)
-        self.assertTrue('palette' in info)
-    def testPalWrite(self):
-        """Test metadata for paletted PNG can be passed from one PNG
-        to another."""
-        r = Reader(bytes=_pngsuite['basn3p04'])
-        x,y,pixels,info = r.read()
-        w = Writer(**info)
-        o = BytesIO()
-        w.write(o, pixels)
-        o.flush()
-        o.seek(0)
-        r = Reader(file=o)
-        _,_,_,again_info = r.read()
-        # Same palette
-        self.assertEqual(again_info['palette'], info['palette'])
-    def testPalExpand(self):
-        """Test that bitdepth can be used to fiddle with pallete image."""
-        r = Reader(bytes=_pngsuite['basn3p04'])
-        x,y,pixels,info = r.read()
-        pixels = [list(row) for row in pixels]
-        info['bitdepth'] = 8
-        w = Writer(**info)
-        o = BytesIO()
-        w.write(o, pixels)
-        o.flush()
-        o.seek(0)
-        r = Reader(file=o)
-        _,_,again_pixels,again_info = r.read()
-        # Same pixels
-        again_pixels = [list(row) for row in again_pixels]
-        self.assertEqual(again_pixels, pixels)
-
-    def testPNMsbit(self):
-        """Test that PNM files can generates sBIT chunk."""
-        def do():
-            return _main(['testPNMsbit'])
-        s = BytesIO()
-        s.write(strtobytes('P6 8 1 1\n'))
-        for pixel in range(8):
-            s.write(struct.pack('<I', (0x4081*pixel)&0x10101)[:3])
-        s.flush()
-        s.seek(0)
-        o = BytesIO()
-        testWithIO(s, o, do)
-        r = Reader(bytes=o.getvalue())
-        sbit = r.chunk('sBIT')[1]
-        self.assertEqual(sbit, strtobytes('\x01\x01\x01'))
-    def testLtrns0(self):
-        """Create greyscale image with tRNS chunk."""
-        return self.helperLtrns(0)
-    def testLtrns1(self):
-        """Using 1-tuple for transparent arg."""
-        return self.helperLtrns((0,))
-    def helperLtrns(self, transparent):
-        """Helper used by :meth:`testLtrns*`."""
-        pixels = zip([0x00, 0x38, 0x4c, 0x54, 0x5c, 0x40, 0x38, 0x00])
-        o = BytesIO()
-        w = Writer(8, 8, greyscale=True, bitdepth=1, transparent=transparent)
-        w.write_packed(o, pixels)
-        r = Reader(bytes=o.getvalue())
-        x,y,pixels,meta = r.asDirect()
-        self.assertTrue(meta['alpha'])
-        self.assertTrue(meta['greyscale'])
-        self.assertEqual(meta['bitdepth'], 1)
-    def testWinfo(self):
-        """Test the dictionary returned by a `read` method can be used
-        as args for :meth:`Writer`.
-        """
-        r = Reader(bytes=_pngsuite['basn2c16'])
-        info = r.read()[3]
-        w = Writer(**info)
-    def testPackedIter(self):
-        """Test iterator for row when using write_packed.
-
-        Indicative for Issue 47.
-        """
-        w = Writer(16, 2, greyscale=True, alpha=False, bitdepth=1)
-        o = BytesIO()
-        w.write_packed(o, [itertools.chain([0x0a], [0xaa]),
-                           itertools.chain([0x0f], [0xff])])
-        r = Reader(bytes=o.getvalue())
-        x,y,pixels,info = r.asDirect()
-        pixels = list(pixels)
-        self.assertEqual(len(pixels), 2)
-        self.assertEqual(len(pixels[0]), 16)
-    def testInterlacedArray(self):
-        """Test that reading an interlaced PNG yields each row as an
-        array."""
-        r = Reader(bytes=_pngsuite['basi0g08'])
-        list(r.read()[2])[0].tostring
-    def testTrnsArray(self):
-        """Test that reading a type 2 PNG with tRNS chunk yields each
-        row as an array (using asDirect)."""
-        r = Reader(bytes=_pngsuite['tbrn2c08'])
-        list(r.asDirect()[2])[0].tostring
-
-    # Invalid file format tests.  These construct various badly
-    # formatted PNG files, then feed them into a Reader.  When
-    # everything is working properly, we should get FormatError
-    # exceptions raised.
-    def testEmpty(self):
-        """Test empty file."""
-
-        r = Reader(bytes='')
-        self.assertRaises(FormatError, r.asDirect)
-    def testSigOnly(self):
-        """Test file containing just signature bytes."""
-
-        r = Reader(bytes=_signature)
-        self.assertRaises(FormatError, r.asDirect)
-    def testExtraPixels(self):
-        """Test file that contains too many pixels."""
-
-        def eachchunk(chunk):
-            if chunk[0] != 'IDAT':
-                return chunk
-            data = zlib.decompress(chunk[1])
-            data += strtobytes('\x00garbage')
-            data = zlib.compress(data)
-            chunk = (chunk[0], data)
-            return chunk
-        self.assertRaises(FormatError, self.helperFormat, eachchunk)
-    def testNotEnoughPixels(self):
-        def eachchunk(chunk):
-            if chunk[0] != 'IDAT':
-                return chunk
-            # Remove last byte.
-            data = zlib.decompress(chunk[1])
-            data = data[:-1]
-            data = zlib.compress(data)
-            return (chunk[0], data)
-        self.assertRaises(FormatError, self.helperFormat, eachchunk)
-    def helperFormat(self, f):
-        r = Reader(bytes=_pngsuite['basn0g01'])
-        o = BytesIO()
-        def newchunks():
-            for chunk in r.chunks():
-                yield f(chunk)
-        write_chunks(o, newchunks())
-        r = Reader(bytes=o.getvalue())
-        return list(r.asDirect()[2])
-    def testBadFilter(self):
-        def eachchunk(chunk):
-            if chunk[0] != 'IDAT':
-                return chunk
-            data = zlib.decompress(chunk[1])
-            # Corrupt the first filter byte
-            data = strtobytes('\x99') + data[1:]
-            data = zlib.compress(data)
-            return (chunk[0], data)
-        self.assertRaises(FormatError, self.helperFormat, eachchunk)
-
-    def testFlat(self):
-        """Test read_flat."""
-        import hashlib
-
-        r = Reader(bytes=_pngsuite['basn0g02'])
-        x,y,pixel,meta = r.read_flat()
-        d = hashlib.md5(seqtobytes(pixel)).digest()
-        self.assertEqual(_enhex(d), '255cd971ab8cd9e7275ff906e5041aa0')
-    def testfromarray(self):
-        img = from_array([[0, 0x33, 0x66], [0xff, 0xcc, 0x99]], 'L')
-        img.save('testfromarray.png')
-    def testfromarrayL16(self):
-        img = from_array(group(range(2**16), 256), 'L;16')
-        img.save('testL16.png')
-    def testfromarrayRGB(self):
-        img = from_array([[0,0,0, 0,0,1, 0,1,0, 0,1,1],
-                          [1,0,0, 1,0,1, 1,1,0, 1,1,1]], 'RGB;1')
-        o = BytesIO()
-        img.save(o)
-    def testfromarrayIter(self):
-        import itertools
-
-        i = itertools.islice(itertools.count(10), 20)
-        i = itertools.imap(lambda x: [x, x, x], i)
-        img = from_array(i, 'RGB;5', dict(height=20))
-        f = open('testiter.png', 'wb')
-        img.save(f)
-        f.close()
-
-    # numpy dependent tests.  These are skipped (with a message to
-    # sys.stderr) if numpy cannot be imported.
-    def testNumpyuint16(self):
-        """numpy uint16."""
-
-        try:
-            import numpy
-        except ImportError:
-            print >>sys.stderr, "skipping numpy test"
-            return
-
-        rows = [map(numpy.uint16, range(0,0x10000,0x5555))]
-        b = topngbytes('numpyuint16.png', rows, 4, 1,
-            greyscale=True, alpha=False, bitdepth=16)
-    def testNumpyuint8(self):
-        """numpy uint8."""
-
-        try:
-            import numpy
-        except ImportError:
-            print >>sys.stderr, "skipping numpy test"
-            return
-
-        rows = [map(numpy.uint8, range(0,0x100,0x55))]
-        b = topngbytes('numpyuint8.png', rows, 4, 1,
-            greyscale=True, alpha=False, bitdepth=8)
-    def testNumpybool(self):
-        """numpy bool."""
-
-        try:
-            import numpy
-        except ImportError:
-            print >>sys.stderr, "skipping numpy test"
-            return
-
-        rows = [map(numpy.bool, [0,1])]
-        b = topngbytes('numpybool.png', rows, 2, 1,
-            greyscale=True, alpha=False, bitdepth=1)
-    def testNumpyarray(self):
-        """numpy array."""
-        try:
-            import numpy
-        except ImportError:
-            print >>sys.stderr, "skipping numpy test"
-            return
-
-        pixels = numpy.array([[0,0x5555],[0x5555,0xaaaa]], numpy.uint16)
-        img = from_array(pixels, 'L')
-        img.save('testnumpyL16.png')
-
-    def paeth(self, x, a, b, c):
-        p = a + b - c
-        pa = abs(p - a)
-        pb = abs(p - b)
-        pc = abs(p - c)
-        if pa <= pb and pa <= pc:
-            pr = a
-        elif pb <= pc:
-            pr = b
-        else:
-            pr = c
-        return x - pr
-
-    # test filters and unfilters
-    def testFilterScanlineFirstLine(self):
-        fo = 3  # bytes per pixel
-        line = [30, 31, 32, 230, 231, 232]
-        out = filter_scanline(0, line, fo, None)  # none
-        self.assertEqual(list(out), [0, 30, 31, 32, 230, 231, 232])
-        out = filter_scanline(1, line, fo, None)  # sub
-        self.assertEqual(list(out), [1, 30, 31, 32, 200, 200, 200])
-        out = filter_scanline(2, line, fo, None)  # up
-        # TODO: All filtered scanlines start with a byte indicating the filter
-        # algorithm, except "up". Is this a bug? Should the expected output
-        # start with 2 here?
-        self.assertEqual(list(out), [30, 31, 32, 230, 231, 232])
-        out = filter_scanline(3, line, fo, None)  # average
-        self.assertEqual(list(out), [3, 30, 31, 32, 215, 216, 216])
-        out = filter_scanline(4, line, fo, None)  # paeth
-        self.assertEqual(list(out), [
-            4, self.paeth(30, 0, 0, 0), self.paeth(31, 0, 0, 0),
-            self.paeth(32, 0, 0, 0), self.paeth(230, 30, 0, 0),
-            self.paeth(231, 31, 0, 0), self.paeth(232, 32, 0, 0)
-            ])
-    def testFilterScanline(self):
-        prev = [20, 21, 22, 210, 211, 212]
-        line = [30, 32, 34, 230, 233, 236]
-        fo = 3
-        out = filter_scanline(0, line, fo, prev)  # none
-        self.assertEqual(list(out), [0, 30, 32, 34, 230, 233, 236])
-        out = filter_scanline(1, line, fo, prev)  # sub
-        self.assertEqual(list(out), [1, 30, 32, 34, 200, 201, 202])
-        out = filter_scanline(2, line, fo, prev)  # up
-        self.assertEqual(list(out), [2, 10, 11, 12, 20, 22, 24])
-        out = filter_scanline(3, line, fo, prev)  # average
-        self.assertEqual(list(out), [3, 20, 22, 23, 110, 112, 113])
-        out = filter_scanline(4, line, fo, prev)  # paeth
-        self.assertEqual(list(out), [
-            4, self.paeth(30, 0, 20, 0), self.paeth(32, 0, 21, 0),
-            self.paeth(34, 0, 22, 0), self.paeth(230, 30, 210, 20),
-            self.paeth(233, 32, 211, 21), self.paeth(236, 34, 212, 22)
-            ])
-    def testUnfilterScanline(self):
-        reader = Reader(bytes='')
-        reader.psize = 3
-        scanprev = array('B', [20, 21, 22, 210, 211, 212])
-        scanline = array('B', [30, 32, 34, 230, 233, 236])
-        def cp(a):
-            return array('B', a)
-
-        out = reader.undo_filter(0, cp(scanline), cp(scanprev))
-        self.assertEqual(list(out), list(scanline))  # none
-        out = reader.undo_filter(1, cp(scanline), cp(scanprev))
-        self.assertEqual(list(out), [30, 32, 34, 4, 9, 14])  # sub
-        out = reader.undo_filter(2, cp(scanline), cp(scanprev))
-        self.assertEqual(list(out), [50, 53, 56, 184, 188, 192])  # up
-        out = reader.undo_filter(3, cp(scanline), cp(scanprev))
-        self.assertEqual(list(out), [40, 42, 45, 99, 103, 108])  # average
-        out = reader.undo_filter(4, cp(scanline), cp(scanprev))
-        self.assertEqual(list(out), [50, 53, 56, 184, 188, 192])  # paeth
-    def testUnfilterScanlinePaeth(self):
-        # This tests more edge cases in the paeth unfilter
-        reader = Reader(bytes='')
-        reader.psize = 3
-        scanprev = array('B', [2, 0, 0, 0, 9, 11])
-        scanline = array('B', [6, 10, 9, 100, 101, 102])
-
-        out = reader.undo_filter(4, scanline, scanprev)
-        self.assertEqual(list(out), [8, 10, 9, 108, 111, 113])  # paeth
-    def testIterstraight(self):
-        def arraify(list_of_str):
-            return [array('B', s) for s in list_of_str]
-        reader = Reader(bytes='')
-        reader.row_bytes = 6
-        reader.psize = 3
-        rows = reader.iterstraight(arraify(['\x00abcdef', '\x00ghijkl']))
-        self.assertEqual(list(rows), arraify(['abcdef', 'ghijkl']))
-
-        rows = reader.iterstraight(arraify(['\x00abc', 'def\x00ghijkl']))
-        self.assertEqual(list(rows), arraify(['abcdef', 'ghijkl']))
-
-        rows = reader.iterstraight(arraify(['\x00abcdef\x00ghijkl']))
-        self.assertEqual(list(rows), arraify(['abcdef', 'ghijkl']))
-
-        rows = reader.iterstraight(arraify(['\x00abcdef\x00ghi', 'jkl']))
-        self.assertEqual(list(rows), arraify(['abcdef', 'ghijkl']))
-
-# === Command Line Support ===
-
-def _dehex(s):
-    """Liberally convert from hex string to binary string."""
-    import re
-    import binascii
-
-    # Remove all non-hexadecimal digits
-    s = re.sub(r'[^a-fA-F\d]', '', s)
-    # binscii.unhexlify works in Python 2 and Python 3 (unlike
-    # thing.decode('hex')).
-    return binascii.unhexlify(strtobytes(s))
-def _enhex(s):
-    """Convert from binary string (bytes) to hex string (str)."""
-
-    import binascii
-
-    return bytestostr(binascii.hexlify(s))
-
-# Copies of PngSuite test files taken
-# from http://www.schaik.com/pngsuite/pngsuite_bas_png.html
-# on 2009-02-19 by drj and converted to hex.
-# Some of these are not actually in PngSuite (but maybe they should
-# be?), they use the same naming scheme, but start with a capital
-# letter.
-_pngsuite = {
-  'basi0g01': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002001000000012c0677
-cf0000000467414d41000186a031e8965f0000009049444154789c2d8d310ec2
-300c45dfc682c415187a00a42e197ab81e83b127e00c5639001363a580d8582c
-65c910357c4b78b0bfbfdf4f70168c19e7acb970a3f2d1ded9695ce5bf5963df
-d92aaf4c9fd927ea449e6487df5b9c36e799b91bdf082b4d4bd4014fe4014b01
-ab7a17aee694d28d328a2d63837a70451e1648702d9a9ff4a11d2f7a51aa21e5
-a18c7ffd0094e3511d661822f20000000049454e44ae426082
-"""),
-  'basi0g02': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002002000000016ba60d
-1f0000000467414d41000186a031e8965f0000005149444154789c635062e860
-00e17286bb609c93c370ec189494960631366e4467b3ae675dcf10f521ea0303
-90c1ca006444e11643482064114a4852c710baea3f18c31918020c30410403a6
-0ac1a09239009c52804d85b6d97d0000000049454e44ae426082
-"""),
-  'basi0g04': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200400000001e4e6f8
-bf0000000467414d41000186a031e8965f000000ae49444154789c658e5111c2
-301044171c141c141c041c843a287510ea20d441c041c141c141c04191102454
-03994998cecd7edcecedbb9bdbc3b2c2b6457545fbc4bac1be437347f7c66a77
-3c23d60db15e88f5c5627338a5416c2e691a9b475a89cd27eda12895ae8dfdab
-43d61e590764f5c83a226b40d669bec307f93247701687723abf31ff83a2284b
-a5b4ae6b63ac6520ad730ca4ed7b06d20e030369bd6720ed383290360406d24e
-13811f2781eba9d34d07160000000049454e44ae426082
-"""),
-  'basi0g08': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200800000001211615
-be0000000467414d41000186a031e8965f000000b549444154789cb5905d0ac2
-3010849dbac81c42c47bf843cf253e8878b0aa17110f214bdca6be240f5d21a5
-94ced3e49bcd322c1624115515154998aa424822a82a5624a1aa8a8b24c58f99
-999908130989a04a00d76c2c09e76cf21adcb209393a6553577da17140a2c59e
-70ecbfa388dff1f03b82fb82bd07f05f7cb13f80bb07ad2fd60c011c3c588eef
-f1f4e03bbec7ce832dca927aea005e431b625796345307b019c845e6bfc3bb98
-769d84f9efb02ea6c00f9bb9ff45e81f9f280000000049454e44ae426082
-"""),
-  'basi0g16': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002010000000017186c9
-fd0000000467414d41000186a031e8965f000000e249444154789cb5913b0ec2
-301044c7490aa8f85d81c3e4301c8f53a4ca0da8902c8144b3920b4043111282
-23bc4956681a6bf5fc3c5a3ba0448912d91a4de2c38dd8e380231eede4c4f7a1
-4677700bec7bd9b1d344689315a3418d1a6efbe5b8305ba01f8ff4808c063e26
-c60d5c81edcf6c58c535e252839e93801b15c0a70d810ae0d306b205dc32b187
-272b64057e4720ff0502154034831520154034c3df81400510cdf0015c86e5cc
-5c79c639fddba9dcb5456b51d7980eb52d8e7d7fa620a75120d6064641a05120
-b606771a05626b401a05f1f589827cf0fe44c1f0bae0055698ee8914fffffe00
-00000049454e44ae426082
-"""),
-  'basi2c08': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002008020000018b1fdd
-350000000467414d41000186a031e8965f000000f249444154789cd59341aa04
-210c44abc07b78133d59d37333bd89d76868b566d10cf4675af8596431a11662
-7c5688919280e312257dd6a0a4cf1a01008ee312a5f3c69c37e6fcc3f47e6776
-a07f8bdaf5b40feed2d33e025e2ff4fe2d4a63e1a16d91180b736d8bc45854c5
-6d951863f4a7e0b66dcf09a900f3ffa2948d4091e53ca86c048a64390f662b50
-4a999660ced906182b9a01a8be00a56404a6ede182b1223b4025e32c4de34304
-63457680c93aada6c99b73865aab2fc094920d901a203f5ddfe1970d28456783
-26cffbafeffcd30654f46d119be4793f827387fc0d189d5bc4d69a3c23d45a7f
-db803146578337df4d0a3121fc3d330000000049454e44ae426082
-"""),
-  'basi2c16': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000201002000001db8f01
-760000000467414d41000186a031e8965f0000020a49444154789cd5962173e3
-3010853fcf1838cc61a1818185a53e56787fa13fa130852e3b5878b4b0b03081
-b97f7030070b53e6b057a0a8912bbb9163b9f109ececbc59bd7dcf2b45492409
-d66f00eb1dd83cb5497d65456aeb8e1040913b3b2c04504c936dd5a9c7e2c6eb
-b1b8f17a58e8d043da56f06f0f9f62e5217b6ba3a1b76f6c9e99e8696a2a72e2
-c4fb1e4d452e92ec9652b807486d12b6669be00db38d9114b0c1961e375461a5
-5f76682a85c367ad6f682ff53a9c2a353191764b78bb07d8ddc3c97c1950f391
-6745c7b9852c73c2f212605a466a502705c8338069c8b9e84efab941eb393a97
-d4c9fd63148314209f1c1d3434e847ead6380de291d6f26a25c1ebb5047f5f24
-d85c49f0f22cc1d34282c72709cab90477bf25b89d49f0f351822297e0ea9704
-f34c82bc94002448ede51866e5656aef5d7c6a385cb4d80e6a538ceba04e6df2
-480e9aa84ddedb413bb5c97b3838456df2d4fec2c7a706983e7474d085fae820
-a841776a83073838973ac0413fea2f1dc4a06e71108fda73109bdae48954ad60
-bf867aac3ce44c7c1589a711cf8a81df9b219679d96d1cec3d8bbbeaa2012626
-df8c7802eda201b2d2e0239b409868171fc104ba8b76f10b4da09f6817ffc609
-c413ede267fd1fbab46880c90f80eccf0013185eb48b47ba03df2bdaadef3181
-cb8976f18e13188768170f98c0f844bb78cb04c62ddac59d09fc3fa25dfc1da4
-14deb3df1344f70000000049454e44ae426082
-"""),
-  'basi3p08': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020080300000133a3ba
-500000000467414d41000186a031e8965f00000300504c5445224400f5ffed77
-ff77cbffff110a003a77002222ffff11ff110000222200ffac5566ff66ff6666
-ff01ff221200dcffffccff994444ff005555220000cbcbff44440055ff55cbcb
-00331a00ffecdcedffffe4ffcbffdcdc44ff446666ff330000442200ededff66
-6600ffa444ffffaaeded0000cbcbfefffffdfffeffff0133ff33552a000101ff
-8888ff00aaaa010100440000888800ffe4cbba5b0022ff22663200ffff99aaaa
-ff550000aaaa00cb630011ff11d4ffaa773a00ff4444dc6b0066000001ff0188
-4200ecffdc6bdc00ffdcba00333300ed00ed7300ffff88994a0011ffff770000
-ff8301ffbabafe7b00fffeff00cb00ff999922ffff880000ffff77008888ffdc
-ff1a33000000aa33ffff009900990000000001326600ffbaff44ffffffaaff00
-770000fefeaa00004a9900ffff66ff22220000998bff1155ffffff0101ff88ff
-005500001111fffffefffdfea4ff4466ffffff66ff003300ffff55ff77770000
-88ff44ff00110077ffff006666ffffed000100fff5ed1111ffffff44ff22ffff
-eded11110088ffff00007793ff2200dcdc3333fffe00febabaff99ffff333300
-63cb00baba00acff55ffffdcffff337bfe00ed00ed5555ffaaffffdcdcff5555
-00000066dcdc00dc00dc83ff017777fffefeffffffcbff5555777700fefe00cb
-00cb0000fe010200010000122200ffff220044449bff33ffd4aa0000559999ff
-999900ba00ba2a5500ffcbcbb4ff66ff9b33ffffbaaa00aa42880053aa00ffaa
-aa0000ed00babaffff1100fe00000044009999990099ffcc99ba000088008800
-dc00ff93220000dcfefffeaa5300770077020100cb0000000033ffedff00ba00
-ff3333edffedffc488bcff7700aa00660066002222dc0000ffcbffdcffdcff8b
-110000cb00010155005500880000002201ffffcbffcbed0000ff88884400445b
-ba00ffbc77ff99ff006600baffba00777773ed00fe00003300330000baff77ff
-004400aaffaafffefe000011220022c4ff8800eded99ff99ff55ff002200ffb4
-661100110a1100ff1111dcffbabaffff88ff88010001ff33ffb98ed362000002
-a249444154789c65d0695c0b001806f03711a9904a94d24dac63292949e5a810
-d244588a14ca5161d1a1323973252242d62157d12ae498c8124d25ca3a11398a
-16e55a3cdffab0ffe7f77d7fcff3528645349b584c3187824d9d19d4ec2e3523
-9eb0ae975cf8de02f2486d502191841b42967a1ad49e5ddc4265f69a899e26b5
-e9e468181baae3a71a41b95669da8df2ea3594c1b31046d7b17bfb86592e4cbe
-d89b23e8db0af6304d756e60a8f4ad378bdc2552ae5948df1d35b52143141533
-33bbbbababebeb3b3bc9c9c9c6c6c0c0d7b7b535323225a5aa8a02024a4bedec
-0a0a2a2bcdcd7d7cf2f3a9a9c9cdcdd8b8adcdd5b5ababa828298982824a4ab2
-b21212acadbdbc1414e2e24859b9a72730302f4f49292c4c57373c9c0a0b7372
-8c8c1c1c3a3a92936d6dfdfd293e3e26262a4a4eaea2424b4b5fbfbc9c323278
-3c0b0ba1303abaae8ecdeeed950d6669a9a7a7a141d4de9e9d5d5cdcd2229b94
-c572716132f97cb1d8db9bc3110864a39795d9db6b6a26267a7a9a98d4d6a6a7
-cb76090ef6f030354d4d75766e686030545464cb393a1a1ac6c68686eae8f8f9
-a9aa4644c8b66d6e1689dcdd2512a994cb35330b0991ad9f9b6b659596a6addd
-d8282fafae5e5323fb8f41d01f76c22fd8061be01bfc041a0323e1002c81cd30
-0b9ec027a0c930014ec035580fc3e112bc069a0b53e11c0c8095f00176c163a0
-e5301baec06a580677600ddc05ba0f13e120bc81a770133ec355a017300d4ec2
-0c7800bbe1219c02fa08f3e13c1c85dbb00a2ec05ea0dff00a6ec15a98027360
-070c047a06d7e1085c84f1b014f6c03fa0b33018b6c0211801ebe018fc00da0a
-6f61113c877eb01d4ec317a085700f26c130f80efbe132bc039a0733e106fc81
-f7f017f6c10aa0d1300a0ec374780943e1382c06fa0a9b60238c83473016cec0
-02f80f73fefe1072afc1e50000000049454e44ae426082
-"""),
-  'basi6a08': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200806000001047d4a
-620000000467414d41000186a031e8965f0000012049444154789cc595414ec3
-3010459fa541b8bbb26641b8069b861e8b4d12c1c112c1452a710a2a65d840d5
-949041fc481ec98ae27c7f3f8d27e3e4648047600fec0d1f390fbbe2633a31e2
-9389e4e4ea7bfdbf3d9a6b800ab89f1bd6b553cfcbb0679e960563d72e0a9293
-b7337b9f988cc67f5f0e186d20e808042f1c97054e1309da40d02d7e27f92e03
-6cbfc64df0fc3117a6210a1b6ad1a00df21c1abcf2a01944c7101b0cb568a001
-909c9cf9e399cf3d8d9d4660a875405d9a60d000b05e2de55e25780b7a5268e0
-622118e2399aab063a815808462f1ab86890fc2e03e48bb109ded7d26ce4bf59
-0db91bac0050747fec5015ce80da0e5700281be533f0ce6d5900b59bcb00ea6d
-200314cf801faab200ea752803a8d7a90c503a039f824a53f4694e7342000000
-0049454e44ae426082
-"""),
-  'basn0g01': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002001000000005b0147
-590000000467414d41000186a031e8965f0000005b49444154789c2dccb10903
-300c05d1ebd204b24a200b7a346f90153c82c18d0a61450751f1e08a2faaead2
-a4846ccea9255306e753345712e211b221bf4b263d1b427325255e8bdab29e6f
-6aca30692e9d29616ee96f3065f0bf1f1087492fd02f14c90000000049454e44
-ae426082
-"""),
-  'basn0g02': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002002000000001ca13d
-890000000467414d41000186a031e8965f0000001f49444154789c6360085df5
-1f8cf1308850c20053868f0133091f6390b90700bd497f818b0989a900000000
-49454e44ae426082
-"""),
-  # A version of basn0g04 dithered down to 3 bits.
-  'Basn0g03': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020040000000093e1c8
-2900000001734249540371d88211000000fd49444154789c6d90d18906210c84
-c356f22356b2889588604301b112112b11d94a96bb495cf7fe87f32d996f2689
-44741cc658e39c0b118f883e1f63cc89dafbc04c0f619d7d898396c54b875517
-83f3a2e7ac09a2074430e7f497f00f1138a5444f82839c5206b1f51053cca968
-63258821e7f2b5438aac16fbecc052b646e709de45cf18996b29648508728612
-952ca606a73566d44612b876845e9a347084ea4868d2907ff06be4436c4b41a3
-a3e1774285614c5affb40dbd931a526619d9fa18e4c2be420858de1df0e69893
-a0e3e5523461be448561001042b7d4a15309ce2c57aef2ba89d1c13794a109d7
-b5880aa27744fc5c4aecb5e7bcef5fe528ec6293a930690000000049454e44ae
-426082
-"""),
-  'basn0g04': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020040000000093e1c8
-290000000467414d41000186a031e8965f0000004849444154789c6360601014
-545232367671090d4d4b2b2f6720430095dbd1418e002a77e64c720450b9ab56
-912380caddbd9b1c0154ee9933e408a072efde25470095fbee1d1902001f14ee
-01eaff41fa0000000049454e44ae426082
-"""),
-  'basn0g08': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200800000000561125
-280000000467414d41000186a031e8965f0000004149444154789c6364602400
-1408c8b30c05058c0f0829f8f71f3f6079301c1430ca11906764a2795c0c0605
-8c8ff0cafeffcff887e67131181430cae0956564040050e5fe7135e2d8590000
-000049454e44ae426082
-"""),
-  'basn0g16': _dehex("""
-89504e470d0a1a0a0000000d49484452000000200000002010000000000681f9
-6b0000000467414d41000186a031e8965f0000005e49444154789cd5d2310ac0
-300c4351395bef7fc6dca093c0287b32d52a04a3d98f3f3880a7b857131363a0
-3a82601d089900dd82f640ca04e816dc06422640b7a03d903201ba05b7819009
-d02d680fa44c603f6f07ec4ff41938cf7f0016d84bd85fae2b9fd70000000049
-454e44ae426082
-"""),
-  'basn2c08': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200802000000fc18ed
-a30000000467414d41000186a031e8965f0000004849444154789cedd5c10900
-300c024085ec91fdb772133b442bf4a1f8cee12bb40d043b800a14f81ca0ede4
-7d4c784081020f4a871fc284071428f0a0743823a94081bb7077a3c00182b1f9
-5e0f40cf4b0000000049454e44ae426082
-"""),
-  'basn2c16': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000201002000000ac8831
-e00000000467414d41000186a031e8965f000000e549444154789cd596c10a83
-301044a7e0417fcb7eb7fdadf6961e06039286266693cc7a188645e43dd6a08f
-1042003e2fe09aef6472737e183d27335fcee2f35a77b702ebce742870a23397
-f3edf2705dd10160f3b2815fe8ecf2027974a6b0c03f74a6e4192843e75c6c03
-35e8ec3202f5e84c0181bbe8cca967a00d9df3491bb040671f2e6087ce1c2860
-8d1e05f8c7ee0f1d00b667e70df44467ef26d01fbd9bc028f42860f71d188bce
-fb8d3630039dbd59601e7ab3c06cf428507f0634d039afdc80123a7bb1801e7a
-b1802a7a14c89f016d74ce331bf080ce9e08f8414f04bca133bfe642fe5e07bb
-c4ec0000000049454e44ae426082
-"""),
-  'basn3p04': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200403000000815467
-c70000000467414d41000186a031e8965f000000037342495404040477f8b5a3
-0000002d504c54452200ff00ffff8800ff22ff000099ffff6600dd00ff77ff00
-ff000000ff99ddff00ff00bbffbb000044ff00ff44d2b049bd00000047494441
-54789c63e8e8080d3d7366d5aaf27263e377ef66ce64204300952b28488e002a
-d7c5851c0154eeddbbe408a07119c81140e52a29912380ca4d4b23470095bb7b
-37190200e0c4ead10f82057d0000000049454e44ae426082
-"""),
-  'basn6a08': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200806000000737a7a
-f40000000467414d41000186a031e8965f0000006f49444154789cedd6310a80
-300c46e12764684fa1f73f55048f21c4ddc545781d52e85028fc1f4d28d98a01
-305e7b7e9cffba33831d75054703ca06a8f90d58a0074e351e227d805c8254e3
-1bb0420f5cdc2e0079208892ffe2a00136a07b4007943c1004d900195036407f
-011bf00052201a9c160fb84c0000000049454e44ae426082
-"""),
-  'cs3n3p08': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020080300000044a48a
-c60000000467414d41000186a031e8965f0000000373424954030303a392a042
-00000054504c544592ff0000ff9200ffff00ff0000dbff00ff6dffb600006dff
-b6ff00ff9200dbff000049ffff2400ff000024ff0049ff0000ffdb00ff4900ff
-b6ffff0000ff2400b6ffffdb000092ffff6d000024ffff49006dff00df702b17
-0000004b49444154789c85cac70182000000b1b3625754b0edbfa72324ef7486
-184ed0177a437b680bcdd0031c0ed00ea21f74852ed00a1c9ed0086da0057487
-6ed0121cd6d004bda0013a421ff803224033e177f4ae260000000049454e44ae
-426082
-"""),
-  's09n3p02': _dehex("""
-89504e470d0a1a0a0000000d49484452000000090000000902030000009dffee
-830000000467414d41000186a031e8965f000000037342495404040477f8b5a3
-0000000c504c544500ff000077ffff00ffff7700ff5600640000001f49444154
-789c63600002fbff0c0c56ab19182ca381581a4283f82071200000696505c36a
-437f230000000049454e44ae426082
-"""),
-  'tbgn3p08': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020080300000044a48a
-c60000000467414d41000186a031e8965f00000207504c54457f7f7fafafafab
-abab110000222200737300999999510d00444400959500959595e6e600919191
-8d8d8d620d00898989666600b7b700911600000000730d007373736f6f6faaaa
-006b6b6b676767c41a00cccc0000f30000ef00d51e0055555567670000dd0051
-515100d1004d4d4de61e0038380000b700160d0d00ab00560d00090900009500
-009100008d003333332f2f2f2f2b2f2b2b000077007c7c001a05002b27000073
-002b2b2b006f00bb1600272727780d002323230055004d4d00cc1e00004d00cc
-1a000d00003c09006f6f00002f003811271111110d0d0d55554d090909001100
-4d0900050505000d00e2e200000900000500626200a6a6a6a2a2a29e9e9e8484
-00fb00fbd5d500801100800d00ea00ea555500a6a600e600e6f7f700e200e233
-0500888888d900d9848484c01a007777003c3c05c8c8008080804409007c7c7c
-bb00bbaa00aaa600a61e09056262629e009e9a009af322005e5e5e05050000ee
-005a5a5adddd00a616008d008d00e20016050027270088110078780000c40078
-00787300736f006f44444400aa00c81e004040406600663c3c3c090000550055
-1a1a00343434d91e000084004d004d007c004500453c3c00ea1e00222222113c
-113300331e1e1efb22001a1a1a004400afaf00270027003c001616161e001e0d
-160d2f2f00808000001e00d1d1001100110d000db7b7b7090009050005b3b3b3
-6d34c4230000000174524e530040e6d86600000001624b474402660b7c640000
-01f249444154789c6360c0048c8c58049100575f215ee92e6161ef109cd2a15e
-4b9645ce5d2c8f433aa4c24f3cbd4c98833b2314ab74a186f094b9c2c27571d2
-6a2a58e4253c5cda8559057a392363854db4d9d0641973660b0b0bb76bb16656
-06970997256877a07a95c75a1804b2fbcd128c80b482a0b0300f8a824276a9a8
-ec6e61612b3e57ee06fbf0009619d5fac846ac5c60ed20e754921625a2daadc6
-1967e29e97d2239c8aec7e61fdeca9cecebef54eb36c848517164514af16169e
-866444b2b0b7b55534c815cc2ec22d89cd1353800a8473100a4485852d924a6a
-412adc74e7ad1016ceed043267238c901716f633a812022998a4072267c4af02
-92127005c0f811b62830054935ce017b38bf0948cc5c09955f030a24617d9d46
-63371fd940b0827931cbfdf4956076ac018b592f72d45594a9b1f307f3261b1a
-084bc2ad50018b1900719ba6ba4ca325d0427d3f6161449486f981144cf3100e
-2a5f2a1ce8683e4ddf1b64275240c8438d98af0c729bbe07982b8a1c94201dc2
-b3174c9820bcc06201585ad81b25b64a2146384e3798290c05ad280a18c0a62e
-e898260c07fca80a24c076cc864b777131a00190cdfa3069035eccbc038c30e1
-3e88b46d16b6acc5380d6ac202511c392f4b789aa7b0b08718765990111606c2
-9e854c38e5191878fbe471e749b0112bb18902008dc473b2b2e8e72700000000
-49454e44ae426082
-"""),
-  'Tp2n3p08': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020080300000044a48a
-c60000000467414d41000186a031e8965f00000300504c544502ffff80ff05ff
-7f0703ff7f0180ff04ff00ffff06ff000880ff05ff7f07ffff06ff000804ff00
-0180ff02ffff03ff7f02ffff80ff0503ff7f0180ffff0008ff7f0704ff00ffff
-06ff000802ffffff7f0704ff0003ff7fffff0680ff050180ff04ff000180ffff
-0008ffff0603ff7f80ff05ff7f0702ffffff000880ff05ffff0603ff7f02ffff
-ff7f070180ff04ff00ffff06ff000880ff050180ffff7f0702ffff04ff0003ff
-7fff7f0704ff0003ff7f0180ffffff06ff000880ff0502ffffffff0603ff7fff
-7f0702ffff04ff000180ff80ff05ff0008ff7f07ffff0680ff0504ff00ff0008
-0180ff03ff7f02ffff02ffffffff0604ff0003ff7f0180ffff000880ff05ff7f
-0780ff05ff00080180ff02ffffff7f0703ff7fffff0604ff00ff7f07ff0008ff
-ff0680ff0504ff0002ffff0180ff03ff7fff0008ffff0680ff0504ff000180ff
-02ffff03ff7fff7f070180ff02ffff04ff00ffff06ff0008ff7f0780ff0503ff
-7fffff06ff0008ff7f0780ff0502ffff03ff7f0180ff04ff0002ffffff7f07ff
-ff0604ff0003ff7fff00080180ff80ff05ffff0603ff7f0180ffff000804ff00
-80ff0502ffffff7f0780ff05ffff0604ff000180ffff000802ffffff7f0703ff
-7fff0008ff7f070180ff03ff7f02ffff80ff05ffff0604ff00ff0008ffff0602
-ffff0180ff04ff0003ff7f80ff05ff7f070180ff04ff00ff7f0780ff0502ffff
-ff000803ff7fffff0602ffffff7f07ffff0680ff05ff000804ff0003ff7f0180
-ff02ffff0180ffff7f0703ff7fff000804ff0080ff05ffff0602ffff04ff00ff
-ff0603ff7fff7f070180ff80ff05ff000803ff7f0180ffff7f0702ffffff0008
-04ff00ffff0680ff0503ff7f0180ff04ff0080ff05ffff06ff000802ffffff7f
-0780ff05ff0008ff7f070180ff03ff7f04ff0002ffffffff0604ff00ff7f07ff
-000880ff05ffff060180ff02ffff03ff7f80ff05ffff0602ffff0180ff03ff7f
-04ff00ff7f07ff00080180ffff000880ff0502ffff04ff00ff7f0703ff7fffff
-06ff0008ffff0604ff00ff7f0780ff0502ffff03ff7f0180ffdeb83387000000
-f874524e53000000000000000008080808080808081010101010101010181818
-1818181818202020202020202029292929292929293131313131313131393939
-393939393941414141414141414a4a4a4a4a4a4a4a52525252525252525a5a5a
-5a5a5a5a5a62626262626262626a6a6a6a6a6a6a6a73737373737373737b7b7b
-7b7b7b7b7b83838383838383838b8b8b8b8b8b8b8b94949494949494949c9c9c
-9c9c9c9c9ca4a4a4a4a4a4a4a4acacacacacacacacb4b4b4b4b4b4b4b4bdbdbd
-bdbdbdbdbdc5c5c5c5c5c5c5c5cdcdcdcdcdcdcdcdd5d5d5d5d5d5d5d5dedede
-dededededee6e6e6e6e6e6e6e6eeeeeeeeeeeeeeeef6f6f6f6f6f6f6f6b98ac5
-ca0000012c49444154789c6360e7169150d230b475f7098d4ccc28a96ced9e32
-63c1da2d7b8e9fb97af3d1fb8f3f18e8a0808953544a4dd7c4c2c9233c2621bf
-b4aab17fdacce5ab36ee3a72eafaad87efbefea68702362e7159652d031b07cf
-c0b8a4cce28aa68e89f316aedfb4ffd0b92bf79fbcfcfe931e0a183904e55435
-8decdcbcc22292b3caaadb7b27cc5db67af3be63e72fdf78fce2d31f7a2860e5
-119356d037b374f10e8a4fc92eaa6fee99347fc9caad7b0f9ebd74f7c1db2fbf
-e8a180995f484645dbdccad12f38363dafbcb6a573faeca5ebb6ed3e7ce2c29d
-e76fbefda38702063e0149751d537b67ff80e8d4dcc29a86bea97316add9b0e3
-c0e96bf79ebdfafc971e0a587885e515f58cad5d7d43a2d2720aeadaba26cf5a
-bc62fbcea3272fde7efafac37f3a28000087c0fe101bc2f85f0000000049454e
-44ae426082
-"""),
-  'tbbn1g04': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020040000000093e1c8
-290000000467414d41000186a031e8965f0000000274524e530007e8f7589b00
-000002624b47440000aa8d23320000013e49444154789c55d1cd4b024118c7f1
-efbe6419045b6a48a72d352808b435284f9187ae9b098627a1573a19945beba5
-e8129e8222af11d81e3a4545742de8ef6af6d5762e0fbf0fc33c33f36085cb76
-bc4204778771b867260683ee57e13f0c922df5c719c2b3b6c6c25b2382cea4b9
-9f7d4f244370746ac71f4ca88e0f173a6496749af47de8e44ba8f3bf9bdfa98a
-0faf857a7dd95c7dc8d7c67c782c99727997f41eb2e3c1e554152465bb00fe8e
-b692d190b718d159f4c0a45c4435915a243c58a7a4312a7a57913f05747594c6
-46169866c57101e4d4ce4d511423119c419183a3530cc63db88559ae28e7342a
-1e9c8122b71139b8872d6e913153224bc1f35b60e4445bd4004e20ed6682c759
-1d9873b3da0fbf50137dc5c9bde84fdb2ec8bde1189e0448b63584735993c209
-7a601bd2710caceba6158797285b7f2084a2f82c57c01a0000000049454e44ae
-426082
-"""),
-  'tbrn2c08': _dehex("""
-89504e470d0a1a0a0000000d4948445200000020000000200802000000fc18ed
-a30000000467414d41000186a031e8965f0000000674524e53007f007f007f8a
-33334f00000006624b474400ff0000000033277cf3000004d649444154789cad
-965f68537714c73fd912d640235e692f34d0406fa0c1663481045ab060065514
-56660a295831607df0a1488715167060840a1614e6431e9cb34fd2c00a762c85
-f6a10f816650c13b0cf40612e1822ddc4863bd628a8924d23d6464f9d3665dd9
-f7e977ce3dbff3cd3939bfdfef6bb87dfb364782dbed065ebe7cd93acc78b4ec
-a228debd7bb7bfbfbfbbbbfb7f261045311a8d261209405194274f9ea4d3e916
-f15f1c3eb5dd6e4fa5fecce526239184a2b0b8486f6f617171b1f5ae4311381c
-8e57af5e5dbd7a351088150a78bd389d44222c2f93cdfe66b7db8f4ee07038b6
-b6b6bebf766d7e7e7e60a06432313b4ba984c3c1c4049a46b95c5a58583822c1
-dbb76f27272733d1b9df853c3030c0f232562b9108cf9eb1b888d7cbf030abab
-31abd5fa1f08dc6ef7e7cf9f1f3f7e1c8944745d4f1400c62c001313acad21cb
-b8dd2c2c603271eb1640341aad4c6d331aa7e8c48913a150a861307ecc11e964
-74899919bc5e14e56fffc404f1388502f178dceff7ef4bf0a5cfe7abb533998c
-e5f9ea2f1dd88c180d64cb94412df3dd57e83a6b3b3c7a84c98420100c72fd3a
-636348bae726379fe69e8e8d8dbd79f3a6558b0607079796965256479b918085
-7b02db12712b6181950233023f3f647494ee6e2e5ea45864cce5b8a7fe3acffc
-3aebb22c2bd5d20e22d0757d7b7bbbbdbd3d94a313bed1b0aa3cd069838b163a
-8d4c59585f677292d0b84d9a995bd337def3fe6bbe5e6001989b9b6bfe27ea08
-36373781542ab56573248b4c5bc843ac4048c7ab21aa24ca00534c25482828a3
-8c9ee67475bbaaaab22cb722c8e57240a150301a8d219de94e44534d7d90e885
-87acb0e2c4f9800731629b6c5ee14a35a6b9887d2a0032994cb9cf15dbe59650
-ff7b46a04c9a749e7cc5112214266cc65c31354d5b5d5d3d90209bcd5616a552
-a95c2e87f2a659bd9ee01c2cd73964e438f129a6aa9e582c363838b80f81d7eb
-5555b56a2a8ad2d9d7affd0409f8015c208013fea00177b873831b0282c964f2
-783c1e8fa7582cee5f81a669b5e6eeeeaee58e8559b0c233d8843c7c0b963a82
-34e94b5cb2396d7d7d7db22c8ba258fb0afd43f0e2c58b919191ba9de9b4d425
-118329b0c3323c8709d02041b52b4ea7f39de75d2a934a2693c0a953a76a93d4
-5d157ebf7f6565a5542a553df97c5e10045dd731c130b86113cc300cbd489224
-08422a952a140a95788fc763b1d41558d7a2d7af5f5fb870a1d6a3aaaacd6603
-18802da84c59015bd2e6897b745d9765b99a1df0f97c0daf74e36deaf7fbcd66
-73ad2797cb89a2c839880188a2e8743a8bc5a22ccbba5e376466b3b9bdbdbd21
-6123413a9d0e0402b51e4dd3bababa788eb022b85caeb6b6364551b6b7b76942
-43f7f727007a7a7a04a1ee8065b3595fde2768423299ac1ec6669c3973e65004
-c0f8f878ad69341a33994ced2969c0d0d0502412f9f8f163f3a7fd654b474787
-288ad53e74757535df6215b85cae60302849d2410aecc037f9f2e5cbd5b5c160
-680eb0dbede170381c0e7ff8f0a185be3b906068684892a4ca7a6f6faff69328
-8ad3d3d3f7efdfdfdbdbfb57e96868a14d0d0643381c96242997cbe5f3794010
-84603078fcf8f1d6496bd14a3aba5c2ea7d369341a5555b5582c8140e0fcf9f3
-1b1b1b87cf4eeb0a8063c78e45a3d19e9e1ebfdfdf5a831e844655d18093274f
-9e3d7bf6d3a74f3b3b3b47c80efc05ff7af28fefb70d9b0000000049454e44ae
-426082
-"""),
-  'basn6a16': _dehex("""
-89504e470d0a1a0a0000000d494844520000002000000020100600000023eaa6
-b70000000467414d41000186a031e8965f00000d2249444154789cdd995f6c1c
-d775c67ff38fb34b724d2ee55a8e4b04a0ac87049100cab4dbd8c6528902cb4d
-10881620592e52d4325ac0905bc98a94025e71fd622cb5065ac98a0c283050c0
-728a00b6e542a1d126885cd3298928891d9a0444037e904434951d4b90b84b2f
-c9dde1fcebc33977a95555348f411e16dfce9d3b77ee77eebde77ce78c95a669
-0ad07c17009a13edd898b87dfb1fcb7d2b4d1bff217f33df80deb1e6267df0ff
-c1e6e6dfafdf1f5a7fd30f9aef66b6d546dd355bf02c40662e3307f9725a96c6
-744c3031f83782f171c148dbc3bf1774f5dad1e79d6f095a3f54d4fbec5234ef
-d9a2f8d73afe4f14f57ef4f42def7b44f19060f06b45bddf1c5534d77fd922be
-2973a15a82e648661c6e3240aa3612ead952b604bde57458894f29deaf133bac
-13d2766f5227a4a3b8cf08da7adfd6fbd6bd8a4fe9dbb43d35e3dfa3f844fbf8
-9119bf4f7144094fb56333abf8a86063ca106f94b3a3b512343765e60082097f
-1bb86ba72439a653519b09f5cee1ce61c897d37eedf5553580ae60f4af8af33a
-b14fd400b6a0f34535c0434afc0b3a9f07147527a5fa7ca218ff56c74d74dc3f
-155cfd3325fc278acf2ae1cb4a539f5f9937c457263b0bd51234c732a300cdd1
-cc1840f0aaff54db0e4874ed5a9b5d6d27d4bb36746d80de72baa877ff4b275a
-d7895ed1897ea4139b5143fcbb1a62560da1ed9662aaed895ec78a91c18795b8
-5e07ab4af8ba128e95e682e0728bf8f2e5ae815a091a53d902ac1920d8e05f06
-589de8d8d66680789f4e454fb9d9ec66cd857af796ee2d902fa73fd5bba775a2
-153580ae44705ed0d37647d15697cb8f14bfa3e3e8fdf8031d47af571503357c
-f30d25acedcbbf135c9a35c49766ba07ab255859e8ec03684e66860182dff8f7
-0304bff6ff1c20fc81b7afdd00a71475539a536e36bb5973a19e3b923b02bde5
-e4efd4003ac170eb2d13fe274157afedbd82d6fb3a9a1e85e4551d47cf7078f8
-9671fe4289ebf5f2bf08d63f37c4eb4773c55a0996efeefa0ca011671d8060ca
-2f0004c7fcc300e166ef0240f825efe3361f106d57d423d0723f7acacd66376b
-2ed47b7a7a7a205f4ef4ac4691e0aad9aa0d41cf13741c3580a506487574ddca
-61a8c403c1863ebfbcac3475168b2de28b8b3d77544bb05ce92a02aceced3c0d
-d0cc65ea371b201cf1c601c24dde1c4078cedbdeb60322f50126a019bf6edc9b
-39e566b39b3517eaf97c3e0fbde5e4491d45bd74537145d155b476aa0176e868
-c6abebf30dbd5e525c54ac8e18e2d56abeb756827a3d970358a97416019a6f64
-f60004fdfe1580d5c98e618070cc1b05887eee7e0d209a70db7d8063029889b4
-c620ead78d7b33a7dc6c76b3e6427ddddbebde867c393aa7845e5403e8ca794a
-d0d6fb897af5f03525fe5782f5e7046bdaef468bf88d1debc6ab25583cd17310
-6079b9ab0ba059c914018245bf076075b5a303200c3c1f209a733701444fbbaf
-00c4134ebb016c5d0b23614c243701cdf875e3decce9349bddacb9505fbf7dfd
-76e82d87736a00f5d2b5ffd4b7dce2719a4d25ae717ee153c1abef18e257cfad
-7fa45682da48ef38c052b53b0fd06864b300c151ff08c0ea431de701a287dd5f
-004497dc7b01a253ee3e80b8c7f91c20f967fb6fdb7c80ada7d8683723614c24
-3701cdf875e3decc29379bddacb950ef3fd47f08f2e5a61ea4aa2a3eb757cd55
-13345efcfa59c12b2f19e2578ef77fb75a82854ffbee01a83f977b11a031931d
-040802df07082b5e11207cc17b1e209a770700e2df0a83e409fb7580f827c230
-99b06fd901fb058d6835dacd481813c94d40337eddb83773cacd66376b2ed437
-bebcf165e82d2f4e4beb7f3fa6e652c2d7ee10bc78c010bfb87fe3c95a09ae9f
-bd732740bd2fb700d0f865f64180e059ff044018ca0ca28a5b04883f701e0088
-bfec7c0c909cb71f0448c6ec518074b375012079d9dedf66004bcfbc51eb2dd1
-aadacd481813c94d40337eddb83773cacd66376b2ed487868686205fbe7c49ef
-5605a73f34c4a7a787eeab96e0da81bb4e022c15ba27019a5b339300e16bf286
-a8eae601e25866907cdf3e0890acb36f00245fb57f05904e59c300e92561946e
-b2e600d209ab7d07f04d458dfb46ad1bd16ab49b913026929b8066fcba716fe6
-949bcd6ed65ca8ef7e7cf7e3d05b7e7c8f217ee6cdddbb6a25a856f37980e0c7
-fe4e80a82623c48193014846ec7180f4acf518409aca0cd28a5504e03b32c374
-de1a00608a0240faaa327a4b19fe946fb6f90054dbb5f2333d022db56eb4966a
-3723614c243701cdf8f556bea8a7dc6c76b3e66bd46584ddbbcebc0990cf4b0f
-ff4070520c282338a7e26700ec725202b01e4bcf0258963c6f1d4d8f0030cb20
-805549c520930c03584fa522b676f11600ffc03fde3e1b3489a9c9054c9aa23b
-c08856a3dd8c843191dc0434e3d78d7b33a75c36fb993761f7ae5a69f72ef97f
-e6ad336fed7e1c60e8bee96980bbdebbb60da07b7069062033d9dc0ae03d296f
-70ab511ec071640676252902d833c916007b3e1900b0a6d2028035968e025861
-ea01581369fb11488c34d18cbc95989afccca42baad65ba2d5683723614c24d7
-8066fcbab8b7e96918baaf5aaa56219f975fb50a43f7c9bde90fa73f1c1a02d8
-78f2e27e803b77ca08b90519315b6fe400fc1392097a9eccc0ad444500e70199
-a1331f0f00d8934901c07e5d526ceb87c2d07e2579badd005a2b31a5089391b7
-1253358049535a6add8856dd0146c298482e01ede27ed878b256ba7600ee3a09
-c18fc1df09fe01084ec25defc1b56db0f1a4f4bd78e0e2818d2f0334e7330300
-7df7c888b917e50dd9c1c60c80efcb0cbc63e1f700bce7c31700dccbd1060027
-8add9b0de06c8e2f00d84962b7d7030e2a61538331b98051f92631bd253f336a
-dd8856a3dd44c25c390efddfad96ae9f853b77c25201ba27c533b8bdf28b6ad0
-3d084b33d2e7fa59099e9901b8f2d29597fa0f01848f78e70082117f1ca07b76
-6910209b9519f895a008d031bbba05c09d8f06005c5b18b8fba25300cea6780e
-c03e911c6ccf06d507b48a4fa606634a114609de929f9934c5a87511ad57cfc1
-fa476aa5854fa1ef1e3910b905686e85cc24c40138198915f133d2d6dc2a7dea
-7df2ccc2a752faf2cec1d577aebeb37e3b4034eeee0008dff3be0e6b923773b4
-7904c0ef9119767cb4fa1500ef1361e08e452500f71561e84cc4ed3e20fab6a2
-c905f40cb76a3026bf3319b91ac2e46792a6dcd801ebc6aba5da08f48ecb81c8
-bd088d5f42f6417191de93908c803d0e76199292b485af41b60e8d9c3c537f0e
-8211f0c7211a077707dc18b931b2ee6d80a4d7ae024491ebc24d4a708ff70680
-7f25e807e8785f1878e322d6ddaf453f0770ff2dfa769b01423dbbad72a391b6
-5a7c3235985629423372494cab55c8f7d64a8b27a0e7202c55a13b0f8d19c80e
-4ae9ca3f015115dc3ca467c17a4c7ee95970ab10e5a54ff0ac3cd39881ee5958
-1a84f03df0be0e492fd855a8d6aa35d10b4962dbb0a604a3d3ee5e80a8eee600
-a24977f8660378bf0bbf00e01d0a8fb7f980f04b8aa6ce6aca8d5a7533c52753
-839152c4e222f4dc512dd5eb90cbc981e8ea12cf90cd8a8bf47d89159e2741d3
-7124f65b96fcd254dae258fa84a13c13043246a32129574787e49eae2b49b86d
-c3e2e78b9ff7f4002415bb08907c66df0d103b4e0c104db90500ff70700c203a
-ee1e82dba4c3e16e256c0acca6ceaae9afd1f612d7eb472157ac95962bd05594
-7dd1598466053245088e827f44628657942a825b84e4fb601f84b4025611aca3
-901e01bb024911dc0a4445f08e41f83df02b10142173149ab71baf027611ea95
-7a257704201d14cd9af4d90b00f194530088cb4e09c0df1c5c0088f7393f6833
-c0aa3ac156655de3bca9b34ab9716906ba07aba5e5bba1eb3358d90b9da7c533
-64f6888bf47b60f521e8380fe10be03d2feac17900927560df40f4e48f805960
-50328d648bf4893f9067c217a0631656b7c898c122847bc07b03a2d3e0ee85e4
-33b0ef867450c4fad2ecd26cf7168074c0ba0c904cdac300c9cfec4701924df6
-1cdca61e10685c6f7d52d0caba1498972f43d740adb4b2009d7d7220b20e3473
-90a943d00ffe959bb6eac3e0fe42ea49ee00c45f06e76329b1dabf127d690d80
-5581b408f63c2403e0cc433c00ee658836803b0fd100747c04ab5f917704fd10
-d5c1cd41ec801343d207f602a403605d86e5f9e5f9ae0d00e994556833806685
-c931fb709b0f08b4e869bea5c827859549e82c544b8d29c816a0390999613920
-7e610d5727a16318c2003c1fa24be0de2b32caf92224e7c17e5004b6350c4c01
-05601218066b0ad28224e149019c086257ca315102de2712903bde97b8144d82
-3b2c6ac52d403c054e019249b087f53d0558995a99ea946c70cc927458b3c1ff
-550f30050df988d4284376b4566a8e416654cc921985e037e0df0fc131f00f4b
-acf0c6211c036f14a239703741740adc7da227edd7e56b833d0ae92549b4d357
-25dfb49ed2ff63908e6adf27d6d0dda7638d4154d2778daca17f58e61297c129
-41f233b01f5dc3740cac51688c35c6b22580f48224fee9b83502569a66b629f1
-09f3713473413e2666e7fe6f6c6efefdfafda1f56f6e06f93496d9d67cb7366a
-9964b6f92e64b689196ec6c604646fd3fe4771ff1bf03f65d8ecc3addbb5f300
-00000049454e44ae426082
-"""),
-}
-
-def read_pam_header(infile):
-    """
-    Read (the rest of a) PAM header.  `infile` should be positioned
-    immediately after the initial 'P7' line (at the beginning of the
-    second line).  Returns are as for `read_pnm_header`.
-    """
-    
-    # Unlike PBM, PGM, and PPM, we can read the header a line at a time.
-    header = dict()
-    while True:
-        l = infile.readline().strip()
-        if l == strtobytes('ENDHDR'):
-            break
-        if not l:
-            raise EOFError('PAM ended prematurely')
-        if l[0] == strtobytes('#'):
-            continue
-        l = l.split(None, 1)
-        if l[0] not in header:
-            header[l[0]] = l[1]
-        else:
-            header[l[0]] += strtobytes(' ') + l[1]
-
-    required = ['WIDTH', 'HEIGHT', 'DEPTH', 'MAXVAL']
-    required = [strtobytes(x) for x in required]
-    WIDTH,HEIGHT,DEPTH,MAXVAL = required
-    present = [x for x in required if x in header]
-    if len(present) != len(required):
-        raise Error('PAM file must specify WIDTH, HEIGHT, DEPTH, and MAXVAL')
-    width = int(header[WIDTH])
-    height = int(header[HEIGHT])
-    depth = int(header[DEPTH])
-    maxval = int(header[MAXVAL])
-    if (width <= 0 or
-        height <= 0 or
-        depth <= 0 or
-        maxval <= 0):
-        raise Error(
-          'WIDTH, HEIGHT, DEPTH, MAXVAL must all be positive integers')
-    return 'P7', width, height, depth, maxval
-
-def read_pnm_header(infile, supported=('P5','P6')):
-    """
-    Read a PNM header, returning (format,width,height,depth,maxval).
-    `width` and `height` are in pixels.  `depth` is the number of
-    channels in the image; for PBM and PGM it is synthesized as 1, for
-    PPM as 3; for PAM images it is read from the header.  `maxval` is
-    synthesized (as 1) for PBM images.
-    """
-
-    # Generally, see http://netpbm.sourceforge.net/doc/ppm.html
-    # and http://netpbm.sourceforge.net/doc/pam.html
-
-    supported = [strtobytes(x) for x in supported]
-
-    # Technically 'P7' must be followed by a newline, so by using
-    # rstrip() we are being liberal in what we accept.  I think this
-    # is acceptable.
-    type = infile.read(3).rstrip()
-    if type not in supported:
-        raise NotImplementedError('file format %s not supported' % type)
-    if type == strtobytes('P7'):
-        # PAM header parsing is completely different.
-        return read_pam_header(infile)
-    # Expected number of tokens in header (3 for P4, 4 for P6)
-    expected = 4
-    pbm = ('P1', 'P4')
-    if type in pbm:
-        expected = 3
-    header = [type]
-
-    # We have to read the rest of the header byte by byte because the
-    # final whitespace character (immediately following the MAXVAL in
-    # the case of P6) may not be a newline.  Of course all PNM files in
-    # the wild use a newline at this point, so it's tempting to use
-    # readline; but it would be wrong.
-    def getc():
-        c = infile.read(1)
-        if not c:
-            raise Error('premature EOF reading PNM header')
-        return c
-
-    c = getc()
-    while True:
-        # Skip whitespace that precedes a token.
-        while c.isspace():
-            c = getc()
-        # Skip comments.
-        while c == '#':
-            while c not in '\n\r':
-                c = getc()
-        if not c.isdigit():
-            raise Error('unexpected character %s found in header' % c)
-        # According to the specification it is legal to have comments
-        # that appear in the middle of a token.
-        # This is bonkers; I've never seen it; and it's a bit awkward to
-        # code good lexers in Python (no goto).  So we break on such
-        # cases.
-        token = strtobytes('')
-        while c.isdigit():
-            token += c
-            c = getc()
-        # Slight hack.  All "tokens" are decimal integers, so convert
-        # them here.
-        header.append(int(token))
-        if len(header) == expected:
-            break
-    # Skip comments (again)
-    while c == '#':
-        while c not in '\n\r':
-            c = getc()
-    if not c.isspace():
-        raise Error('expected header to end with whitespace, not %s' % c)
-
-    if type in pbm:
-        # synthesize a MAXVAL
-        header.append(1)
-    depth = (1,3)[type == strtobytes('P6')]
-    return header[0], header[1], header[2], depth, header[3]
-
-def write_pnm(file, width, height, pixels, meta):
-    """Write a Netpbm PNM/PAM file."""
-
-    bitdepth = meta['bitdepth']
-    maxval = 2**bitdepth - 1
-    # Rudely, the number of image planes can be used to determine
-    # whether we are L (PGM), LA (PAM), RGB (PPM), or RGBA (PAM).
-    planes = meta['planes']
-    # Can be an assert as long as we assume that pixels and meta came
-    # from a PNG file.
-    assert planes in (1,2,3,4)
-    if planes in (1,3):
-        if 1 == planes:
-            # PGM
-            # Could generate PBM if maxval is 1, but we don't (for one
-            # thing, we'd have to convert the data, not just blat it
-            # out).
-            fmt = 'P5'
-        else:
-            # PPM
-            fmt = 'P6'
-        file.write('%s %d %d %d\n' % (fmt, width, height, maxval))
-    if planes in (2,4):
-        # PAM
-        # See http://netpbm.sourceforge.net/doc/pam.html
-        if 2 == planes:
-            tupltype = 'GRAYSCALE_ALPHA'
-        else:
-            tupltype = 'RGB_ALPHA'
-        file.write('P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\n'
-                   'TUPLTYPE %s\nENDHDR\n' %
-                   (width, height, planes, maxval, tupltype))
-    # Values per row
-    vpr = planes * width
-    # struct format
-    fmt = '>%d' % vpr
-    if maxval > 0xff:
-        fmt = fmt + 'H'
-    else:
-        fmt = fmt + 'B'
-    for row in pixels:
-        file.write(struct.pack(fmt, *row))
-    file.flush()
-
-def color_triple(color):
-    """
-    Convert a command line colour value to a RGB triple of integers.
-    FIXME: Somewhere we need support for greyscale backgrounds etc.
-    """
-    if color.startswith('#') and len(color) == 4:
-        return (int(color[1], 16),
-                int(color[2], 16),
-                int(color[3], 16))
-    if color.startswith('#') and len(color) == 7:
-        return (int(color[1:3], 16),
-                int(color[3:5], 16),
-                int(color[5:7], 16))
-    elif color.startswith('#') and len(color) == 13:
-        return (int(color[1:5], 16),
-                int(color[5:9], 16),
-                int(color[9:13], 16))
-
-def _add_common_options(parser):
-    """Call *parser.add_option* for each of the options that are
-    common between this PNG--PNM conversion tool and the gen
-    tool.
-    """
-    parser.add_option("-i", "--interlace",
-                      default=False, action="store_true",
-                      help="create an interlaced PNG file (Adam7)")
-    parser.add_option("-t", "--transparent",
-                      action="store", type="string", metavar="#RRGGBB",
-                      help="mark the specified colour as transparent")
-    parser.add_option("-b", "--background",
-                      action="store", type="string", metavar="#RRGGBB",
-                      help="save the specified background colour")
-    parser.add_option("-g", "--gamma",
-                      action="store", type="float", metavar="value",
-                      help="save the specified gamma value")
-    parser.add_option("-c", "--compression",
-                      action="store", type="int", metavar="level",
-                      help="zlib compression level (0-9)")
-    return parser
-
-def _main(argv):
-    """
-    Run the PNG encoder with options from the command line.
-    """
-
-    # Parse command line arguments
-    from optparse import OptionParser
-    import re
-    version = '%prog ' + re.sub(r'( ?\$|URL: |Rev:)', '', __version__)
-    parser = OptionParser(version=version)
-    parser.set_usage("%prog [options] [imagefile]")
-    parser.add_option('-r', '--read-png', default=False,
-                      action='store_true',
-                      help='Read PNG, write PNM')
-    parser.add_option("-a", "--alpha",
-                      action="store", type="string", metavar="pgmfile",
-                      help="alpha channel transparency (RGBA)")
-    _add_common_options(parser)
-
-    (options, args) = parser.parse_args(args=argv[1:])
-
-    # Convert options
-    if options.transparent is not None:
-        options.transparent = color_triple(options.transparent)
-    if options.background is not None:
-        options.background = color_triple(options.background)
-
-    # Prepare input and output files
-    if len(args) == 0:
-        infilename = '-'
-        infile = sys.stdin
-    elif len(args) == 1:
-        infilename = args[0]
-        infile = open(infilename, 'rb')
-    else:
-        parser.error("more than one input file")
-    outfile = sys.stdout
-    if sys.platform == "win32":
-        import msvcrt, os
-        msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
-
-    if options.read_png:
-        # Encode PNG to PPM
-        png = Reader(file=infile)
-        width,height,pixels,meta = png.asDirect()
-        write_pnm(outfile, width, height, pixels, meta) 
-    else:
-        # Encode PNM to PNG
-        format, width, height, depth, maxval = \
-          read_pnm_header(infile, ('P5','P6','P7'))
-        # When it comes to the variety of input formats, we do something
-        # rather rude.  Observe that L, LA, RGB, RGBA are the 4 colour
-        # types supported by PNG and that they correspond to 1, 2, 3, 4
-        # channels respectively.  So we use the number of channels in
-        # the source image to determine which one we have.  We do not
-        # care about TUPLTYPE.
-        greyscale = depth <= 2
-        pamalpha = depth in (2,4)
-        supported = map(lambda x: 2**x-1, range(1,17))
-        try:
-            mi = supported.index(maxval)
-        except ValueError:
-            raise NotImplementedError(
-              'your maxval (%s) not in supported list %s' %
-              (maxval, str(supported)))
-        bitdepth = mi+1
-        writer = Writer(width, height,
-                        greyscale=greyscale,
-                        bitdepth=bitdepth,
-                        interlace=options.interlace,
-                        transparent=options.transparent,
-                        background=options.background,
-                        alpha=bool(pamalpha or options.alpha),
-                        gamma=options.gamma,
-                        compression=options.compression)
-        if options.alpha:
-            pgmfile = open(options.alpha, 'rb')
-            format, awidth, aheight, adepth, amaxval = \
-              read_pnm_header(pgmfile, 'P5')
-            if amaxval != '255':
-                raise NotImplementedError(
-                  'maxval %s not supported for alpha channel' % amaxval)
-            if (awidth, aheight) != (width, height):
-                raise ValueError("alpha channel image size mismatch"
-                                 " (%s has %sx%s but %s has %sx%s)"
-                                 % (infilename, width, height,
-                                    options.alpha, awidth, aheight))
-            writer.convert_ppm_and_pgm(infile, pgmfile, outfile)
-        else:
-            writer.convert_pnm(infile, outfile)
-
-
-if __name__ == '__main__':
-    try:
-        _main(sys.argv)
-    except Error, e:
-        print >>sys.stderr, e
diff --git a/catapult/telemetry/third_party/pyfakefs/README.chromium b/catapult/telemetry/third_party/pyfakefs/README.chromium
deleted file mode 100644
index 6b9dac7..0000000
--- a/catapult/telemetry/third_party/pyfakefs/README.chromium
+++ /dev/null
@@ -1,16 +0,0 @@
-Name: pyfakefs
-Short Name: pyfakefs
-URL: https://github.com/jmcgeheeiv/pyfakefs
-Version: 7e8e097c0165ba9d51fa9d34a0888d8ec082d15b (commit hash)
-License: Apache License 2.0
-License File: NOT_SHIPPED
-Security Critical: no
-
-Local modification: create a pyfakefs as a project folder & move pyfakefs to
-pyfakefs/pyfakefs since we don't want the project folder to be a module.
-
-Description:
-pyfakefs implements a fake file system that mocks the Python file system
-modules. Using pyfakefs, your tests operate on a fake file system in memory
-without touching the real disk. The software under test requires no modification
-to work with pyfakefs.
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/.travis.yml b/catapult/telemetry/third_party/pyfakefs/pyfakefs/.travis.yml
deleted file mode 100644
index bbd351b..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/.travis.yml
+++ /dev/null
@@ -1,29 +0,0 @@
-# Perform continuous integration testing with Travis CI.
-#
-# Copyright 2015 John McGehee. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-language: python
-python:
-  - "2.6"
-  - "2.7"
-  - "3.2"
-  - "3.3"
-  - "3.4"
-
-install:
-  - if [[ $TRAVIS_PYTHON_VERSION == 2.6 ]]; then pip install importlib unittest2; fi
-  - pip install -r requirements.txt
-
-script: ./all_tests.py
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/COPYING b/catapult/telemetry/third_party/pyfakefs/pyfakefs/COPYING
deleted file mode 100644
index 67db858..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/COPYING
+++ /dev/null
@@ -1,175 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/README.md b/catapult/telemetry/third_party/pyfakefs/pyfakefs/README.md
deleted file mode 100644
index ba3f5e5..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/README.md
+++ /dev/null
@@ -1,51 +0,0 @@
-# pyfakefs
-pyfakefs implements a fake file system that mocks the Python file system modules.
-Using pyfakefs, your tests operate on a fake file system in memory without
-touching the real disk.  The software under test requires no modification to
-work with pyfakefs.
-
-## Usage
-See the [usage tutorial](http://github.com/jmcgeheeiv/pyfakefs/wiki/Tutorial)
-for a concrete example of how to apply pyfakefs.
-
-## Continuous Integration
-pyfakefs is tested with Python 2.6 and above.  See [Travis-CI](http://travis-ci.org) for
-[pyfakefs continuous integration test results](https://travis-ci.org/jmcgeheeiv/pyfakefs)
-for each Python version.
-
-## Installation
-
-### Compatibility
-pyfakefs works with Python 2.6 and above.  pyfakefs has no dependencies beyond the Python
-standard library.
-
-### PyPi
-pyfakefs project is hosted on PyPi and can be installed:
-
-```bash
-pip install pyfakefs
-```
-
-## History
-pyfakefs.py was initially developed at Google by Mike Bland as a modest fake
-implementation of core Python modules.  It was introduced to all of Google
-in September 2006. Since then, it has been enhanced to extend its
-functionality and usefulness.  At Google alone, pyfakefs is used in over 2,000
-Python tests.
-
-pyfakefs was released to the public in 2011 as Google Code project
-[pyfakefs](http://code.google.com/p/pyfakefs/).
-
-Fork
-[jmcgeheeiv-pyfakefs](http://code.google.com/p/jmcgeheeiv-pyfakefs/)
-added a [usage tutorial](http://github.com/jmcgeheeiv/pyfakefs/wiki/Tutorial),
-direct support for [unittest](http://docs.python.org/2/library/unittest.html)
-and [doctest](http://docs.python.org/2/library/doctest.html).
-
-Fork
-[shiffdane-jmcgeheeiv-pyfakefs](http://code.google.com/p/shiffdane-jmcgeheeiv-pyfakefs/)
-added further corrections.
-
-After the [shutdown of Google Code was announced,](http://google-opensource.blogspot.com/2015/03/farewell-to-google-code.html)
-all three Google Code projects are merged together here on GitHub as pyfakefs.
-
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/__init__.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/__init__.py
deleted file mode 100755
index e69de29..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/all_tests.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/all_tests.py
deleted file mode 100755
index 1226362..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/all_tests.py
+++ /dev/null
@@ -1,47 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""A test suite that runs all tests for pyfakefs at once."""
-
-import unittest
-
-import fake_filesystem_glob_test
-import fake_filesystem_shutil_test
-import fake_filesystem_test
-import fake_filesystem_vs_real_test
-import fake_tempfile_test
-import fake_filesystem_unittest_test
-import example_test
-
-
-class AllTests(unittest.TestSuite):
-  """A test suite that runs all tests for pyfakefs at once."""
-
-  def suite(self):  # pylint: disable-msg=C6409
-    loader = unittest.defaultTestLoader
-    self.addTests([
-        loader.loadTestsFromModule(fake_filesystem_test),
-        loader.loadTestsFromModule(fake_filesystem_glob_test),
-        loader.loadTestsFromModule(fake_filesystem_shutil_test),
-        loader.loadTestsFromModule(fake_tempfile_test),
-        loader.loadTestsFromModule(fake_filesystem_vs_real_test),
-        loader.loadTestsFromModule(fake_filesystem_unittest_test),
-        loader.loadTestsFromModule(example_test),
-    ])
-    return self
-
-if __name__ == '__main__':
-  unittest.TextTestRunner(verbosity=2).run(AllTests().suite())
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/example.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/example.py
deleted file mode 100644
index 436e4cf..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/example.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# Copyright 2014 Altera Corporation. All Rights Reserved.
-# Author: John McGehee
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Example module that is tested in :py:class`pyfakefs.example_test.TestExample`.
-This demonstrates the usage of the
-:py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class.
-
-The modules related to file handling are bound to the respective fake modules:
-
->>> os     #doctest: +ELLIPSIS 
-<fake_filesystem.FakeOsModule object...>
->>> os.path     #doctest: +ELLIPSIS
-<fake_filesystem.FakePathModule object...>
->>> glob     #doctest: +ELLIPSIS
-<fake_filesystem_glob.FakeGlobModule object...>
->>> shutil     #doctest: +ELLIPSIS
-<fake_filesystem_shutil.FakeShutilModule object...>
-
-The `open()` built-in is bound to the fake `open()`:
-
->>> open     #doctest: +ELLIPSIS
-<fake_filesystem.FakeFileOpen object...>
-
-In Python 2 the `file()` built-in is also bound to the fake `open()`.  `file()`
-was eliminated in Python 3.
-"""
-
-import os
-import glob
-import shutil
-
-def create_file(path):
-    '''Create the specified file and add some content to it.  Use the `open()`
-    built in function.
-    
-    For example, the following file operations occur in the fake file system.
-    In the real file system, we would not even have permission to write `/test`:
-    
-    >>> os.path.isdir('/test')
-    False
-    >>> os.mkdir('/test')
-    >>> os.path.isdir('/test')
-    True
-    >>> os.path.exists('/test/file.txt')
-    False
-    >>> create_file('/test/file.txt')
-    >>> os.path.exists('/test/file.txt')
-    True
-    >>> with open('/test/file.txt') as f:
-    ...     f.readlines()
-    ["This is test file '/test/file.txt'.\\n", 'It was created using the open() function.\\n']
-    '''
-    with open(path, 'w') as f:
-        f.write("This is test file '{}'.\n".format(path))
-        f.write("It was created using the open() function.\n")
-
-def delete_file(path):
-    '''Delete the specified file.
-    
-    For example:
-        
-    >>> os.mkdir('/test')
-    >>> os.path.exists('/test/file.txt')
-    False
-    >>> create_file('/test/file.txt')
-    >>> os.path.exists('/test/file.txt')
-    True
-    >>> delete_file('/test/file.txt')
-    >>> os.path.exists('/test/file.txt')
-    False
-    '''
-    os.remove(path)
-    
-def path_exists(path):
-    '''Return True if the specified file exists.
-    
-    For example:
-        
-    >>> path_exists('/test')
-    False
-    >>> os.mkdir('/test')
-    >>> path_exists('/test')
-    True
-    >>>
-    >>> path_exists('/test/file.txt')
-    False
-    >>> create_file('/test/file.txt')
-    >>> path_exists('/test/file.txt')
-    True
-    '''
-    return os.path.exists(path)
-
-def get_glob(glob_path):
-    '''Return the list of paths matching the specified glob expression.
-    
-    For example:
-    
-    >>> os.mkdir('/test')
-    >>> create_file('/test/file1.txt')
-    >>> create_file('/test/file2.txt')
-    >>> get_glob('/test/file*.txt')
-    ['/test/file1.txt', '/test/file2.txt']
-    '''
-    return glob.glob(glob_path)
-
-def rm_tree(path):
-    '''Delete the specified file hierarchy.'''
-    shutil.rmtree(path)
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/example_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/example_test.py
deleted file mode 100644
index 4a46dd9..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/example_test.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2014 Altera Corporation. All Rights Reserved.
-# Author: John McGehee
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Test the :py:class`pyfakefs.example` module to demonstrate the usage of the
-:py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class.
-"""
-
-import os
-import sys
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-
-import fake_filesystem_unittest
-# The module under test is pyfakefs.example
-import example
-
-
-def load_tests(loader, tests, ignore):
-    '''Load the pyfakefs/example.py doctest tests into unittest.'''
-    return fake_filesystem_unittest.load_doctests(loader, tests, ignore, example)
-
-
-class TestExample(fake_filesystem_unittest.TestCase): # pylint: disable=R0904
-    '''Test the pyfakefs.example module.'''
-
-    def setUp(self):
-        '''Invoke the :py:class:`pyfakefs.fake_filesystem_unittest.TestCase`
-        `self.setUp()` method.  This defines:
-        
-        * Attribute `self.fs`, an instance of \
-          :py:class:`pyfakefs.fake_filesystem.FakeFilesystem`.  This is useful \
-          for creating test files.
-        * Attribute `self.stubs`, an instance of \
-          :py:class:`mox.stubout.StubOutForTesting`.  Use this if you need to
-          define additional stubs.
-        '''
-        self.setUpPyfakefs()
-
-    def tearDown(self):
-        # No longer need self.tearDownPyfakefs()
-        pass
-        
-    def test_create_file(self):
-        '''Test example.create_file()'''
-        # The os module has been replaced with the fake os module so all of the
-        # following occurs in the fake filesystem.
-        self.assertFalse(os.path.isdir('/test'))
-        os.mkdir('/test')
-        self.assertTrue(os.path.isdir('/test'))
-        
-        self.assertFalse(os.path.exists('/test/file.txt'))
-        example.create_file('/test/file.txt')
-        self.assertTrue(os.path.exists('/test/file.txt'))
-        
-    def test_delete_file(self):
-        '''Test example.delete_file()
-
-        `self.fs.CreateFile()` is convenient because it automatically creates
-        directories in the fake file system and allows you to specify the file
-        contents.
-        
-        You could also use `open()` or `file()`.
-        '''
-        self.fs.CreateFile('/test/full.txt',
-                           contents='First line\n'
-                                    'Second Line\n')
-        self.assertTrue(os.path.exists('/test/full.txt'))
-        example.delete_file('/test/full.txt')
-        self.assertFalse(os.path.exists('/test/full.txt'))
-
-    def test_file_exists(self):
-        '''Test example.path_exists()
-
-        `self.fs.CreateFile()` is convenient because it automatically creates
-        directories in the fake file system and allows you to specify the file
-        contents.
-        
-        You could also use `open()` or `file()` if you wanted.
-        '''
-        self.assertFalse(example.path_exists('/test/empty.txt'))          
-        self.fs.CreateFile('/test/empty.txt')
-        self.assertTrue(example.path_exists('/test/empty.txt'))              
-        
-    def test_get_globs(self):
-        '''Test example.get_glob()
-        
-        `self.fs.CreateDirectory()` creates directories.  However, you might
-        prefer the familiar `os.makedirs()`, which also works fine on the fake
-        file system.
-        '''
-        self.assertFalse(os.path.isdir('/test'))
-        self.fs.CreateDirectory('/test/dir1/dir2a')
-        self.assertTrue(os.path.isdir('/test/dir1/dir2a'))
-        # os.mkdirs() works, too.
-        os.makedirs('/test/dir1/dir2b')
-        self.assertTrue(os.path.isdir('/test/dir1/dir2b'))
-        
-        self.assertCountEqual(example.get_glob('/test/dir1/nonexistent*'),
-                              [])
-        self.assertCountEqual(example.get_glob('/test/dir1/dir*'),
-                              ['/test/dir1/dir2a', '/test/dir1/dir2b'])
-
-    def test_rm_tree(self):
-        '''Test example.rm_tree()
-        
-        `self.fs.CreateDirectory()` creates directories.  However, you might
-        prefer the familiar `os.makedirs()`, which also works fine on the fake
-        file system.
-        '''
-        self.fs.CreateDirectory('/test/dir1/dir2a')
-        # os.mkdirs() works, too.
-        os.makedirs('/test/dir1/dir2b')
-        self.assertTrue(os.path.isdir('/test/dir1/dir2b'))
-        self.assertTrue(os.path.isdir('/test/dir1/dir2a'))
-       
-        example.rm_tree('/test/dir1')
-        self.assertFalse(os.path.exists('/test/dir1'))
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem.py
deleted file mode 100644
index d390e66..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem.py
+++ /dev/null
@@ -1,2202 +0,0 @@
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# pylint: disable-msg=W0612,W0613,C6409
-
-"""A fake filesystem implementation for unit testing.
-
-Includes:
-  FakeFile:  Provides the appearance of a real file.
-  FakeDirectory: Provides the appearance of a real dir.
-  FakeFilesystem:  Provides the appearance of a real directory hierarchy.
-  FakeOsModule:  Uses FakeFilesystem to provide a fake os module replacement.
-  FakePathModule:  Faked os.path module replacement.
-  FakeFileOpen:  Faked file() and open() function replacements.
-
-Usage:
->>> import fake_filesystem
->>> filesystem = fake_filesystem.FakeFilesystem()
->>> os_module = fake_filesystem.FakeOsModule(filesystem)
->>> pathname = '/a/new/dir/new-file'
-
-Create a new file object, creating parent directory objects as needed:
->>> os_module.path.exists(pathname)
-False
->>> new_file = filesystem.CreateFile(pathname)
-
-File objects can't be overwritten:
->>> os_module.path.exists(pathname)
-True
->>> try:
-...   filesystem.CreateFile(pathname)
-... except IOError as e:
-...   assert e.errno == errno.EEXIST, 'unexpected errno: %d' % e.errno
-...   assert e.strerror == 'File already exists in fake filesystem'
-
-Remove a file object:
->>> filesystem.RemoveObject(pathname)
->>> os_module.path.exists(pathname)
-False
-
-Create a new file object at the previous path:
->>> beatles_file = filesystem.CreateFile(pathname,
-...     contents='Dear Prudence\\nWon\\'t you come out to play?\\n')
->>> os_module.path.exists(pathname)
-True
-
-Use the FakeFileOpen class to read fake file objects:
->>> file_module = fake_filesystem.FakeFileOpen(filesystem)
->>> for line in file_module(pathname):
-...     print line.rstrip()
-...
-Dear Prudence
-Won't you come out to play?
-
-File objects cannot be treated like directory objects:
->>> os_module.listdir(pathname)  #doctest: +NORMALIZE_WHITESPACE
-Traceback (most recent call last):
-  File "fake_filesystem.py", line 291, in listdir
-    raise OSError(errno.ENOTDIR,
-OSError: [Errno 20] Fake os module: not a directory: '/a/new/dir/new-file'
-
-The FakeOsModule can list fake directory objects:
->>> os_module.listdir(os_module.path.dirname(pathname))
-['new-file']
-
-The FakeOsModule also supports stat operations:
->>> import stat
->>> stat.S_ISREG(os_module.stat(pathname).st_mode)
-True
->>> stat.S_ISDIR(os_module.stat(os_module.path.dirname(pathname)).st_mode)
-True
-"""
-
-import errno
-import heapq
-import os
-import stat
-import sys
-import time
-import warnings
-try:
-  import cStringIO as io  # pylint: disable-msg=C6204
-except ImportError:
-  import io  # pylint: disable-msg=C6204
-
-__pychecker__ = 'no-reimportself'
-
-__version__ = '2.5'
-
-PERM_READ = 0o400      # Read permission bit.
-PERM_WRITE = 0o200     # Write permission bit.
-PERM_EXE = 0o100       # Write permission bit.
-PERM_DEF = 0o777       # Default permission bits.
-PERM_DEF_FILE = 0o666  # Default permission bits (regular file)
-PERM_ALL = 0o7777      # All permission bits.
-
-_OPEN_MODE_MAP = {
-    # mode name:(file must exist, need read, need write,
-    #            truncate [implies need write], append)
-    'r': (True, True, False, False, False),
-    'w': (False, False, True, True, False),
-    'a': (False, False, True, False, True),
-    'r+': (True, True, True, False, False),
-    'w+': (False, True, True, True, False),
-    'a+': (False, True, True, False, True),
-    }
-
-_MAX_LINK_DEPTH = 20
-
-FAKE_PATH_MODULE_DEPRECATION = ('Do not instantiate a FakePathModule directly; '
-                                'let FakeOsModule instantiate it.  See the '
-                                'FakeOsModule docstring for details.')
-
-
-class Error(Exception):
-  pass
-
-_is_windows = sys.platform.startswith('win')
-_is_cygwin = sys.platform == 'cygwin'
-
-if _is_windows:
-  # On Windows, raise WindowsError instead of OSError if available
-  OSError = WindowsError  # pylint: disable-msg=E0602,W0622
-
-
-class FakeLargeFileIoException(Error):
-  def __init__(self, file_path):
-    Error.__init__(self,
-                   'Read and write operations not supported for '
-                   'fake large file: %s' % file_path)
-
-
-def CopyModule(old):
-  """Recompiles and creates new module object."""
-  saved = sys.modules.pop(old.__name__, None)
-  new = __import__(old.__name__)
-  sys.modules[old.__name__] = saved
-  return new
-
-
-class FakeFile(object):
-  """Provides the appearance of a real file.
-
-     Attributes currently faked out:
-       st_mode: user-specified, otherwise S_IFREG
-       st_ctime: the time.time() timestamp when the file is created.
-       st_size: the size of the file
-
-     Other attributes needed by os.stat are assigned default value of None
-      these include: st_ino, st_dev, st_nlink, st_uid, st_gid, st_atime,
-      st_mtime
-  """
-
-  def __init__(self, name, st_mode=stat.S_IFREG | PERM_DEF_FILE,
-               contents=None):
-    """init.
-
-    Args:
-      name:  name of the file/directory, without parent path information
-      st_mode:  the stat.S_IF* constant representing the file type (i.e.
-        stat.S_IFREG, stat.SIFDIR)
-      contents:  the contents of the filesystem object; should be a string for
-        regular files, and a list of other FakeFile or FakeDirectory objects
-        for FakeDirectory objects
-    """
-    self.name = name
-    self.st_mode = st_mode
-    self.contents = contents
-    self.epoch = 0
-    self.st_ctime = int(time.time())
-    self.st_atime = self.st_ctime
-    self.st_mtime = self.st_ctime
-    if contents:
-      self.st_size = len(contents)
-    else:
-      self.st_size = 0
-    # Non faked features, write setter methods for fakeing them
-    self.st_ino = None
-    self.st_dev = None
-    self.st_nlink = None
-    self.st_uid = None
-    self.st_gid = None
-
-  def SetLargeFileSize(self, st_size):
-    """Sets the self.st_size attribute and replaces self.content with None.
-
-    Provided specifically to simulate very large files without regards
-    to their content (which wouldn't fit in memory)
-
-    Args:
-      st_size: The desired file size
-
-    Raises:
-      IOError: if the st_size is not a non-negative integer
-    """
-    # the st_size should be an positive integer value
-    if not isinstance(st_size, int) or st_size < 0:
-      raise IOError(errno.ENOSPC,
-                    'Fake file object: can not create non negative integer '
-                    'size=%r fake file' % st_size,
-                    self.name)
-
-    self.st_size = st_size
-    self.contents = None
-
-  def IsLargeFile(self):
-    """Return True if this file was initialized with size but no contents."""
-    return self.contents is None
-
-  def SetContents(self, contents):
-    """Sets the file contents and size.
-
-    Args:
-      contents: string, new content of file.
-    """
-    # convert a byte array to a string
-    if sys.version_info >= (3, 0) and isinstance(contents, bytes):
-      contents = ''.join(chr(i) for i in contents)
-    self.contents = contents
-    self.st_size = len(contents)
-    self.epoch += 1
-
-  def SetSize(self, st_size):
-    """Resizes file content, padding with nulls if new size exceeds the old.
-
-    Args:
-      st_size: The desired size for the file.
-
-    Raises:
-      IOError: if the st_size arg is not a non-negative integer
-    """
-
-    if not isinstance(st_size, int) or st_size < 0:
-      raise IOError(errno.ENOSPC,
-                    'Fake file object: can not create non negative integer '
-                    'size=%r fake file' % st_size,
-                    self.name)
-
-    current_size = len(self.contents)
-    if st_size < current_size:
-      self.contents = self.contents[:st_size]
-    else:
-      self.contents = '%s%s' % (self.contents, '\0' * (st_size - current_size))
-    self.st_size = len(self.contents)
-    self.epoch += 1
-
-  def SetATime(self, st_atime):
-    """Set the self.st_atime attribute.
-
-    Args:
-      st_atime: The desired atime.
-    """
-    self.st_atime = st_atime
-
-  def SetMTime(self, st_mtime):
-    """Set the self.st_mtime attribute.
-
-    Args:
-      st_mtime: The desired mtime.
-    """
-    self.st_mtime = st_mtime
-
-  def __str__(self):
-    return '%s(%o)' % (self.name, self.st_mode)
-
-  def SetIno(self, st_ino):
-    """Set the self.st_ino attribute.
-
-    Args:
-      st_ino: The desired inode.
-    """
-    self.st_ino = st_ino
-
-
-class FakeDirectory(FakeFile):
-  """Provides the appearance of a real dir."""
-
-  def __init__(self, name, perm_bits=PERM_DEF):
-    """init.
-
-    Args:
-      name:  name of the file/directory, without parent path information
-      perm_bits: permission bits. defaults to 0o777.
-    """
-    FakeFile.__init__(self, name, stat.S_IFDIR | perm_bits, {})
-
-  def AddEntry(self, pathname):
-    """Adds a child FakeFile to this directory.
-
-    Args:
-      pathname:  FakeFile instance to add as a child of this directory
-    """
-    self.contents[pathname.name] = pathname
-
-  def GetEntry(self, pathname_name):
-    """Retrieves the specified child file or directory.
-
-    Args:
-      pathname_name: basename of the child object to retrieve
-    Returns:
-      string, file contents
-    Raises:
-      KeyError: if no child exists by the specified name
-    """
-    return self.contents[pathname_name]
-
-  def RemoveEntry(self, pathname_name):
-    """Removes the specified child file or directory.
-
-    Args:
-      pathname_name: basename of the child object to remove
-
-    Raises:
-      KeyError: if no child exists by the specified name
-    """
-    del self.contents[pathname_name]
-
-  def __str__(self):
-    rc = super(FakeDirectory, self).__str__() + ':\n'
-    for item in self.contents:
-      item_desc = self.contents[item].__str__()
-      for line in item_desc.split('\n'):
-        if line:
-          rc = rc + '  ' + line + '\n'
-    return rc
-
-
-class FakeFilesystem(object):
-  """Provides the appearance of a real directory tree for unit testing."""
-
-  def __init__(self, path_separator=os.path.sep):
-    """init.
-
-    Args:
-      path_separator:  optional substitute for os.path.sep
-    """
-    self.path_separator = path_separator
-    self.root = FakeDirectory(self.path_separator)
-    self.cwd = self.root.name
-    # We can't query the current value without changing it:
-    self.umask = os.umask(0o22)
-    os.umask(self.umask)
-    # A list of open file objects. Their position in the list is their
-    # file descriptor number
-    self.open_files = []
-    # A heap containing all free positions in self.open_files list
-    self.free_fd_heap = []
-
-  def SetIno(self, path, st_ino):
-    """Set the self.st_ino attribute of file at 'path'.
-
-    Args:
-      path: Path to file.
-      st_ino: The desired inode.
-    """
-    self.GetObject(path).SetIno(st_ino)
-
-  def AddOpenFile(self, file_obj):
-    """Adds file_obj to the list of open files on the filesystem.
-
-    The position in the self.open_files array is the file descriptor number
-
-    Args:
-      file_obj:  file object to be added to open files list.
-
-    Returns:
-      File descriptor number for the file object.
-    """
-    if self.free_fd_heap:
-      open_fd = heapq.heappop(self.free_fd_heap)
-      self.open_files[open_fd] = file_obj
-      return open_fd
-
-    self.open_files.append(file_obj)
-    return len(self.open_files) - 1
-
-  def CloseOpenFile(self, file_obj):
-    """Removes file_obj from the list of open files on the filesystem.
-
-    Sets the entry in open_files to None.
-
-    Args:
-      file_obj:  file object to be removed to open files list.
-    """
-    self.open_files[file_obj.filedes] = None
-    heapq.heappush(self.free_fd_heap, file_obj.filedes)
-
-  def GetOpenFile(self, file_des):
-    """Returns an open file.
-
-    Args:
-      file_des:  file descriptor of the open file.
-
-    Raises:
-      OSError: an invalid file descriptor.
-      TypeError: filedes is not an integer.
-
-    Returns:
-      Open file object.
-    """
-    if not isinstance(file_des, int):
-      raise TypeError('an integer is required')
-    if (file_des >= len(self.open_files) or
-        self.open_files[file_des] is None):
-      raise OSError(errno.EBADF, 'Bad file descriptor', file_des)
-    return self.open_files[file_des]
-
-  def CollapsePath(self, path):
-    """Mimics os.path.normpath using the specified path_separator.
-
-    Mimics os.path.normpath using the path_separator that was specified
-    for this FakeFilesystem.  Normalizes the path, but unlike the method
-    NormalizePath, does not make it absolute.  Eliminates dot components
-    (. and ..) and combines repeated path separators (//).  Initial ..
-    components are left in place for relative paths.  If the result is an empty
-    path, '.' is returned instead.  Unlike the real os.path.normpath, this does
-    not replace '/' with '\\' on Windows.
-
-    Args:
-      path:  (str) The path to normalize.
-
-    Returns:
-      (str) A copy of path with empty components and dot components removed.
-    """
-    is_absolute_path = path.startswith(self.path_separator)
-    path_components = path.split(self.path_separator)
-    collapsed_path_components = []
-    for component in path_components:
-      if (not component) or (component == '.'):
-        continue
-      if component == '..':
-        if collapsed_path_components and (
-            collapsed_path_components[-1] != '..'):
-          # Remove an up-reference: directory/..
-          collapsed_path_components.pop()
-          continue
-        elif is_absolute_path:
-          # Ignore leading .. components if starting from the root directory.
-          continue
-      collapsed_path_components.append(component)
-    collapsed_path = self.path_separator.join(collapsed_path_components)
-    if is_absolute_path:
-      collapsed_path = self.path_separator + collapsed_path
-    return collapsed_path or '.'
-
-  def NormalizePath(self, path):
-    """Absolutize and minimalize the given path.
-
-    Forces all relative paths to be absolute, and normalizes the path to
-    eliminate dot and empty components.
-
-    Args:
-      path:  path to normalize
-
-    Returns:
-      The normalized path relative to the current working directory, or the root
-        directory if path is empty.
-    """
-    if not path:
-      path = self.path_separator
-    elif not path.startswith(self.path_separator):
-      # Prefix relative paths with cwd, if cwd is not root.
-      path = self.path_separator.join(
-          (self.cwd != self.root.name and self.cwd or '',
-           path))
-    if path == '.':
-      path = self.cwd
-    return self.CollapsePath(path)
-
-  def SplitPath(self, path):
-    """Mimics os.path.split using the specified path_separator.
-
-    Mimics os.path.split using the path_separator that was specified
-    for this FakeFilesystem.
-
-    Args:
-      path:  (str) The path to split.
-
-    Returns:
-      (str) A duple (pathname, basename) for which pathname does not
-          end with a slash, and basename does not contain a slash.
-    """
-    path_components = path.split(self.path_separator)
-    if not path_components:
-      return ('', '')
-    basename = path_components.pop()
-    if not path_components:
-      return ('', basename)
-    for component in path_components:
-      if component:
-        # The path is not the root; it contains a non-separator component.
-        # Strip all trailing separators.
-        while not path_components[-1]:
-          path_components.pop()
-        return (self.path_separator.join(path_components), basename)
-    # Root path.  Collapse all leading separators.
-    return (self.path_separator, basename)
-
-  def JoinPaths(self, *paths):
-    """Mimics os.path.join using the specified path_separator.
-
-    Mimics os.path.join using the path_separator that was specified
-    for this FakeFilesystem.
-
-    Args:
-      *paths:  (str) Zero or more paths to join.
-
-    Returns:
-      (str) The paths joined by the path separator, starting with the last
-          absolute path in paths.
-    """
-    if len(paths) == 1:
-      return paths[0]
-    joined_path_segments = []
-    for path_segment in paths:
-      if path_segment.startswith(self.path_separator):
-        # An absolute path
-        joined_path_segments = [path_segment]
-      else:
-        if (joined_path_segments and
-            not joined_path_segments[-1].endswith(self.path_separator)):
-          joined_path_segments.append(self.path_separator)
-        if path_segment:
-          joined_path_segments.append(path_segment)
-    return ''.join(joined_path_segments)
-
-  def GetPathComponents(self, path):
-    """Breaks the path into a list of component names.
-
-    Does not include the root directory as a component, as all paths
-    are considered relative to the root directory for the FakeFilesystem.
-    Callers should basically follow this pattern:
-
-      file_path = self.NormalizePath(file_path)
-      path_components = self.GetPathComponents(file_path)
-      current_dir = self.root
-      for component in path_components:
-        if component not in current_dir.contents:
-          raise IOError
-        DoStuffWithComponent(curent_dir, component)
-        current_dir = current_dir.GetEntry(component)
-
-    Args:
-      path:  path to tokenize
-
-    Returns:
-      The list of names split from path
-    """
-    if not path or path == self.root.name:
-      return []
-    path_components = path.split(self.path_separator)
-    assert path_components
-    if not path_components[0]:
-      # This is an absolute path.
-      path_components = path_components[1:]
-    return path_components
-
-  def Exists(self, file_path):
-    """True if a path points to an existing file system object.
-
-    Args:
-      file_path:  path to examine
-
-    Returns:
-      bool(if object exists)
-
-    Raises:
-      TypeError: if file_path is None
-    """
-    if file_path is None:
-      raise TypeError
-    if not file_path:
-      return False
-    try:
-      file_path = self.ResolvePath(file_path)
-    except IOError:
-      return False
-    if file_path == self.root.name:
-      return True
-    path_components = self.GetPathComponents(file_path)
-    current_dir = self.root
-    for component in path_components:
-      if component not in current_dir.contents:
-        return False
-      current_dir = current_dir.contents[component]
-    return True
-
-  def ResolvePath(self, file_path):
-    """Follow a path, resolving symlinks.
-
-    ResolvePath traverses the filesystem along the specified file path,
-    resolving file names and symbolic links until all elements of the path are
-    exhausted, or we reach a file which does not exist.  If all the elements
-    are not consumed, they just get appended to the path resolved so far.
-    This gives us the path which is as resolved as it can be, even if the file
-    does not exist.
-
-    This behavior mimics Unix semantics, and is best shown by example.  Given a
-    file system that looks like this:
-
-          /a/b/
-          /a/b/c -> /a/b2          c is a symlink to /a/b2
-          /a/b2/x
-          /a/c   -> ../d
-          /a/x   -> y
-     Then:
-          /a/b/x      =>  /a/b/x
-          /a/c        =>  /a/d
-          /a/x        =>  /a/y
-          /a/b/c/d/e  =>  /a/b2/d/e
-
-    Args:
-      file_path:  path to examine
-
-    Returns:
-      resolved_path (string) or None
-
-    Raises:
-      TypeError: if file_path is None
-      IOError: if file_path is '' or a part of the path doesn't exist
-    """
-
-    def _ComponentsToPath(component_folders):
-      return '%s%s' % (self.path_separator,
-                       self.path_separator.join(component_folders))
-
-    def _ValidRelativePath(file_path):
-      while file_path and '/..' in file_path:
-        file_path = file_path[:file_path.rfind('/..')]
-        if not self.Exists(self.NormalizePath(file_path)):
-          return False
-      return True
-
-    def _FollowLink(link_path_components, link):
-      """Follow a link w.r.t. a path resolved so far.
-
-      The component is either a real file, which is a no-op, or a symlink.
-      In the case of a symlink, we have to modify the path as built up so far
-        /a/b => ../c   should yield /a/../c (which will normalize to /a/c)
-        /a/b => x      should yield /a/x
-        /a/b => /x/y/z should yield /x/y/z
-      The modified path may land us in a new spot which is itself a
-      link, so we may repeat the process.
-
-      Args:
-        link_path_components: The resolved path built up to the link so far.
-        link: The link object itself.
-
-      Returns:
-        (string) the updated path resolved after following the link.
-
-      Raises:
-        IOError: if there are too many levels of symbolic link
-      """
-      link_path = link.contents
-      # For links to absolute paths, we want to throw out everything in the
-      # path built so far and replace with the link.  For relative links, we
-      # have to append the link to what we have so far,
-      if not link_path.startswith(self.path_separator):
-        # Relative path.  Append remainder of path to what we have processed
-        # so far, excluding the name of the link itself.
-        # /a/b => ../c   should yield /a/../c (which will normalize to /c)
-        # /a/b => d should yield a/d
-        components = link_path_components[:-1]
-        components.append(link_path)
-        link_path = self.path_separator.join(components)
-      # Don't call self.NormalizePath(), as we don't want to prepend self.cwd.
-      return self.CollapsePath(link_path)
-
-    if file_path is None:
-      # file.open(None) raises TypeError, so mimic that.
-      raise TypeError('Expected file system path string, received None')
-    if not file_path or not _ValidRelativePath(file_path):
-      # file.open('') raises IOError, so mimic that, and validate that all
-      # parts of a relative path exist.
-      raise IOError(errno.ENOENT,
-                    'No such file or directory: \'%s\'' % file_path)
-    file_path = self.NormalizePath(file_path)
-    if file_path == self.root.name:
-      return file_path
-
-    current_dir = self.root
-    path_components = self.GetPathComponents(file_path)
-
-    resolved_components = []
-    link_depth = 0
-    while path_components:
-      component = path_components.pop(0)
-      resolved_components.append(component)
-      if component not in current_dir.contents:
-        # The component of the path at this point does not actually exist in
-        # the folder.   We can't resolve the path any more.  It is legal to link
-        # to a file that does not yet exist, so rather than raise an error, we
-        # just append the remaining components to what return path we have built
-        # so far and return that.
-        resolved_components.extend(path_components)
-        break
-      current_dir = current_dir.contents[component]
-
-      # Resolve any possible symlinks in the current path component.
-      if stat.S_ISLNK(current_dir.st_mode):
-        # This link_depth check is not really meant to be an accurate check.
-        # It is just a quick hack to prevent us from looping forever on
-        # cycles.
-        link_depth += 1
-        if link_depth > _MAX_LINK_DEPTH:
-          raise IOError(errno.EMLINK,
-                        'Too many levels of symbolic links: \'%s\'' %
-                        _ComponentsToPath(resolved_components))
-        link_path = _FollowLink(resolved_components, current_dir)
-
-        # Following the link might result in the complete replacement of the
-        # current_dir, so we evaluate the entire resulting path.
-        target_components = self.GetPathComponents(link_path)
-        path_components = target_components + path_components
-        resolved_components = []
-        current_dir = self.root
-    return _ComponentsToPath(resolved_components)
-
-  def GetObjectFromNormalizedPath(self, file_path):
-    """Searches for the specified filesystem object within the fake filesystem.
-
-    Args:
-      file_path: specifies target FakeFile object to retrieve, with a
-          path that has already been normalized/resolved
-
-    Returns:
-      the FakeFile object corresponding to file_path
-
-    Raises:
-      IOError: if the object is not found
-    """
-    if file_path == self.root.name:
-      return self.root
-    path_components = self.GetPathComponents(file_path)
-    target_object = self.root
-    try:
-      for component in path_components:
-        if not isinstance(target_object, FakeDirectory):
-          raise IOError(errno.ENOENT,
-                        'No such file or directory in fake filesystem',
-                        file_path)
-        target_object = target_object.GetEntry(component)
-    except KeyError:
-      raise IOError(errno.ENOENT,
-                    'No such file or directory in fake filesystem',
-                    file_path)
-    return target_object
-
-  def GetObject(self, file_path):
-    """Searches for the specified filesystem object within the fake filesystem.
-
-    Args:
-      file_path: specifies target FakeFile object to retrieve
-
-    Returns:
-      the FakeFile object corresponding to file_path
-
-    Raises:
-      IOError: if the object is not found
-    """
-    file_path = self.NormalizePath(file_path)
-    return self.GetObjectFromNormalizedPath(file_path)
-
-  def ResolveObject(self, file_path):
-    """Searches for the specified filesystem object, resolving all links.
-
-    Args:
-      file_path: specifies target FakeFile object to retrieve
-
-    Returns:
-      the FakeFile object corresponding to file_path
-
-    Raises:
-      IOError: if the object is not found
-    """
-    return self.GetObjectFromNormalizedPath(self.ResolvePath(file_path))
-
-  def LResolveObject(self, path):
-    """Searches for the specified object, resolving only parent links.
-
-    This is analogous to the stat/lstat difference.  This resolves links *to*
-    the object but not of the final object itself.
-
-    Args:
-      path: specifies target FakeFile object to retrieve
-
-    Returns:
-      the FakeFile object corresponding to path
-
-    Raises:
-      IOError: if the object is not found
-    """
-    if path == self.root.name:
-      # The root directory will never be a link
-      return self.root
-    parent_directory, child_name = self.SplitPath(path)
-    if not parent_directory:
-      parent_directory = self.cwd
-    try:
-      parent_obj = self.ResolveObject(parent_directory)
-      assert parent_obj
-      if not isinstance(parent_obj, FakeDirectory):
-        raise IOError(errno.ENOENT,
-                      'No such file or directory in fake filesystem',
-                      path)
-      return parent_obj.GetEntry(child_name)
-    except KeyError:
-      raise IOError(errno.ENOENT,
-                    'No such file or directory in the fake filesystem',
-                    path)
-
-  def AddObject(self, file_path, file_object):
-    """Add a fake file or directory into the filesystem at file_path.
-
-    Args:
-      file_path: the path to the file to be added relative to self
-      file_object: file or directory to add
-
-    Raises:
-      IOError: if file_path does not correspond to a directory
-    """
-    try:
-      target_directory = self.GetObject(file_path)
-      target_directory.AddEntry(file_object)
-    except AttributeError:
-      raise IOError(errno.ENOTDIR,
-                    'Not a directory in the fake filesystem',
-                    file_path)
-
-  def RemoveObject(self, file_path):
-    """Remove an existing file or directory.
-
-    Args:
-      file_path: the path to the file relative to self
-
-    Raises:
-      IOError: if file_path does not correspond to an existing file, or if part
-        of the path refers to something other than a directory
-      OSError: if the directory is in use (eg, if it is '/')
-    """
-    if file_path == self.root.name:
-      raise OSError(errno.EBUSY, 'Fake device or resource busy',
-                    file_path)
-    try:
-      dirname, basename = self.SplitPath(file_path)
-      target_directory = self.GetObject(dirname)
-      target_directory.RemoveEntry(basename)
-    except KeyError:
-      raise IOError(errno.ENOENT,
-                    'No such file or directory in the fake filesystem',
-                    file_path)
-    except AttributeError:
-      raise IOError(errno.ENOTDIR,
-                    'Not a directory in the fake filesystem',
-                    file_path)
-
-  def CreateDirectory(self, directory_path, perm_bits=PERM_DEF, inode=None):
-    """Creates directory_path, and all the parent directories.
-
-    Helper method to set up your test faster
-
-    Args:
-      directory_path:  directory to create
-      perm_bits: permission bits
-      inode: inode of directory
-
-    Returns:
-      the newly created FakeDirectory object
-
-    Raises:
-      OSError:  if the directory already exists
-    """
-    directory_path = self.NormalizePath(directory_path)
-    if self.Exists(directory_path):
-      raise OSError(errno.EEXIST,
-                    'Directory exists in fake filesystem',
-                    directory_path)
-    path_components = self.GetPathComponents(directory_path)
-    current_dir = self.root
-
-    for component in path_components:
-      if component not in current_dir.contents:
-        new_dir = FakeDirectory(component, perm_bits)
-        current_dir.AddEntry(new_dir)
-        current_dir = new_dir
-      else:
-        current_dir = current_dir.contents[component]
-
-    current_dir.SetIno(inode)
-    return current_dir
-
-  def CreateFile(self, file_path, st_mode=stat.S_IFREG | PERM_DEF_FILE,
-                 contents='', st_size=None, create_missing_dirs=True,
-                 apply_umask=False, inode=None):
-    """Creates file_path, including all the parent directories along the way.
-
-    Helper method to set up your test faster.
-
-    Args:
-      file_path: path to the file to create
-      st_mode: the stat.S_IF constant representing the file type
-      contents: the contents of the file
-      st_size: file size; only valid if contents=None
-      create_missing_dirs: if True, auto create missing directories
-      apply_umask: whether or not the current umask must be applied on st_mode
-      inode: inode of the file
-
-    Returns:
-      the newly created FakeFile object
-
-    Raises:
-      IOError: if the file already exists
-      IOError: if the containing directory is required and missing
-    """
-    file_path = self.NormalizePath(file_path)
-    if self.Exists(file_path):
-      raise IOError(errno.EEXIST,
-                    'File already exists in fake filesystem',
-                    file_path)
-    parent_directory, new_file = self.SplitPath(file_path)
-    if not parent_directory:
-      parent_directory = self.cwd
-    if not self.Exists(parent_directory):
-      if not create_missing_dirs:
-        raise IOError(errno.ENOENT, 'No such fake directory', parent_directory)
-      self.CreateDirectory(parent_directory)
-    if apply_umask:
-      st_mode &= ~self.umask
-    file_object = FakeFile(new_file, st_mode, contents)
-    file_object.SetIno(inode)
-    self.AddObject(parent_directory, file_object)
-
-    # set the size if st_size is given
-    if not contents and st_size is not None:
-      try:
-        file_object.SetLargeFileSize(st_size)
-      except IOError:
-        self.RemoveObject(file_path)
-        raise
-
-    return file_object
-
-  def CreateLink(self, file_path, link_target):
-    """Creates the specified symlink, pointed at the specified link target.
-
-    Args:
-      file_path:  path to the symlink to create
-      link_target:  the target of the symlink
-
-    Returns:
-      the newly created FakeFile object
-
-    Raises:
-      IOError:  if the file already exists
-    """
-    resolved_file_path = self.ResolvePath(file_path)
-    return self.CreateFile(resolved_file_path, st_mode=stat.S_IFLNK | PERM_DEF,
-                           contents=link_target)
-
-  def __str__(self):
-    return str(self.root)
-
-
-class FakePathModule(object):
-  """Faked os.path module replacement.
-
-  FakePathModule should *only* be instantiated by FakeOsModule.  See the
-  FakeOsModule docstring for details.
-  """
-  _OS_PATH_COPY = CopyModule(os.path)
-
-  def __init__(self, filesystem, os_module=None):
-    """Init.
-
-    Args:
-      filesystem:  FakeFilesystem used to provide file system information
-      os_module: (deprecated) FakeOsModule to assign to self.os
-    """
-    self.filesystem = filesystem
-    self._os_path = self._OS_PATH_COPY
-    if os_module is None:
-      warnings.warn(FAKE_PATH_MODULE_DEPRECATION, DeprecationWarning,
-                    stacklevel=2)
-    self._os_path.os = self.os = os_module
-    self.sep = self.filesystem.path_separator
-
-  def exists(self, path):
-    """Determines whether the file object exists within the fake filesystem.
-
-    Args:
-      path:  path to the file object
-
-    Returns:
-      bool (if file exists)
-    """
-    return self.filesystem.Exists(path)
-
-  def lexists(self, path):
-    """Test whether a path exists.  Returns True for broken symbolic links.
-
-    Args:
-      path:  path to the symlnk object
-
-    Returns:
-      bool (if file exists)
-    """
-    return self.exists(path) or self.islink(path)
-
-  def getsize(self, path):
-    """Return the file object size in bytes.
-
-    Args:
-      path:  path to the file object
-
-    Returns:
-      file size in bytes
-    """
-    file_obj = self.filesystem.GetObject(path)
-    return file_obj.st_size
-
-  def _istype(self, path, st_flag):
-    """Helper function to implement isdir(), islink(), etc.
-
-    See the stat(2) man page for valid stat.S_I* flag values
-
-    Args:
-      path:  path to file to stat and test
-      st_flag:  the stat.S_I* flag checked for the file's st_mode
-
-    Returns:
-      boolean (the st_flag is set in path's st_mode)
-
-    Raises:
-      TypeError: if path is None
-    """
-    if path is None:
-      raise TypeError
-    try:
-      obj = self.filesystem.ResolveObject(path)
-      if obj:
-        return stat.S_IFMT(obj.st_mode) == st_flag
-    except IOError:
-      return False
-    return False
-
-  def isabs(self, path):
-    if self.filesystem.path_separator == os.path.sep:
-      # Pass through to os.path.isabs, which on Windows has special
-      # handling for a leading drive letter.
-      return self._os_path.isabs(path)
-    else:
-      return path.startswith(self.filesystem.path_separator)
-
-  def isdir(self, path):
-    """Determines if path identifies a directory."""
-    return self._istype(path, stat.S_IFDIR)
-
-  def isfile(self, path):
-    """Determines if path identifies a regular file."""
-    return self._istype(path, stat.S_IFREG)
-
-  def islink(self, path):
-    """Determines if path identifies a symbolic link.
-
-    Args:
-      path: path to filesystem object.
-
-    Returns:
-      boolean (the st_flag is set in path's st_mode)
-
-    Raises:
-      TypeError: if path is None
-    """
-    if path is None:
-      raise TypeError
-    try:
-      link_obj = self.filesystem.LResolveObject(path)
-      return stat.S_IFMT(link_obj.st_mode) == stat.S_IFLNK
-    except IOError:
-      return False
-    except KeyError:
-      return False
-    return False
-
-  def getmtime(self, path):
-    """Returns the mtime of the file."""
-    try:
-      file_obj = self.filesystem.GetObject(path)
-    except IOError as e:
-      raise OSError(errno.ENOENT, str(e))
-    return file_obj.st_mtime
-
-  def abspath(self, path):
-    """Return the absolute version of a path."""
-    if not self.isabs(path):
-      if sys.version_info < (3, 0) and isinstance(path, unicode):
-        cwd = self.os.getcwdu()
-      else:
-        cwd = self.os.getcwd()
-      path = self.join(cwd, path)
-    return self.normpath(path)
-
-  def join(self, *p):
-    """Returns the completed path with a separator of the parts."""
-    return self.filesystem.JoinPaths(*p)
-
-  def normpath(self, path):
-    """Normalize path, eliminating double slashes, etc."""
-    return self.filesystem.CollapsePath(path)
-
-  if _is_windows:
-
-    def relpath(self, path, start=None):
-      """ntpath.relpath() needs the cwd passed in the start argument."""
-      if start is None:
-        start = self.filesystem.cwd
-      path = self._os_path.relpath(path, start)
-      return path.replace(self._os_path.sep, self.filesystem.path_separator)
-
-    realpath = abspath
-
-  def __getattr__(self, name):
-    """Forwards any non-faked calls to os.path."""
-    return self._os_path.__dict__[name]
-
-
-class FakeOsModule(object):
-  """Uses FakeFilesystem to provide a fake os module replacement.
-
-  Do not create os.path separately from os, as there is a necessary circular
-  dependency between os and os.path to replicate the behavior of the standard
-  Python modules.  What you want to do is to just let FakeOsModule take care of
-  os.path setup itself.
-
-  # You always want to do this.
-  filesystem = fake_filesystem.FakeFilesystem()
-  my_os_module = fake_filesystem.FakeOsModule(filesystem)
-  """
-
-  def __init__(self, filesystem, os_path_module=None):
-    """Also exposes self.path (to fake os.path).
-
-    Args:
-      filesystem:  FakeFilesystem used to provide file system information
-      os_path_module: (deprecated) optional FakePathModule instance
-    """
-    self.filesystem = filesystem
-    self.sep = filesystem.path_separator
-    self._os_module = os
-    if os_path_module is None:
-      self.path = FakePathModule(self.filesystem, self)
-    else:
-      warnings.warn(FAKE_PATH_MODULE_DEPRECATION, DeprecationWarning,
-                    stacklevel=2)
-      self.path = os_path_module
-    if sys.version_info < (3, 0):
-      self.fdopen = self._fdopen_ver2
-    else:
-      self.fdopen = self._fdopen
-
-  def _fdopen(self, *args, **kwargs):
-    """Redirector to open() builtin function.
-
-    Args:
-      *args: pass through args
-      **kwargs: pass through kwargs
-
-    Returns:
-      File object corresponding to file_des.
-
-    Raises:
-      TypeError: if file descriptor is not an integer.
-    """
-    if not isinstance(args[0], int):
-      raise TypeError('an integer is required')
-    return FakeFileOpen(self.filesystem)(*args, **kwargs)
-
-  def _fdopen_ver2(self, file_des, mode='r', bufsize=None):
-    """Returns an open file object connected to the file descriptor file_des.
-
-    Args:
-      file_des: An integer file descriptor for the file object requested.
-      mode: additional file flags. Currently checks to see if the mode matches
-        the mode of the requested file object.
-      bufsize: ignored. (Used for signature compliance with __builtin__.fdopen)
-
-    Returns:
-      File object corresponding to file_des.
-
-    Raises:
-      OSError: if bad file descriptor or incompatible mode is given.
-      TypeError: if file descriptor is not an integer.
-    """
-    if not isinstance(file_des, int):
-      raise TypeError('an integer is required')
-
-    try:
-      return FakeFileOpen(self.filesystem).Call(file_des, mode=mode)
-    except IOError as e:
-      raise OSError(e)
-
-  def open(self, file_path, flags, mode=None):
-    """Returns the file descriptor for a FakeFile.
-
-    WARNING: This implementation only implements creating a file. Please fill
-    out the remainder for your needs.
-
-    Args:
-      file_path: the path to the file
-      flags: low-level bits to indicate io operation
-      mode: bits to define default permissions
-
-    Returns:
-      A file descriptor.
-
-    Raises:
-      OSError: if the path cannot be found
-      ValueError: if invalid mode is given
-      NotImplementedError: if an unsupported flag is passed in
-    """
-    if flags & os.O_CREAT:
-      fake_file = FakeFileOpen(self.filesystem)(file_path, 'w')
-      if mode:
-        self.chmod(file_path, mode)
-      return fake_file.fileno()
-    else:
-      raise NotImplementedError('FakeOsModule.open')
-
-  def close(self, file_des):
-    """Closes a file descriptor.
-
-    Args:
-      file_des: An integer file descriptor for the file object requested.
-
-    Raises:
-      OSError: bad file descriptor.
-      TypeError: if file descriptor is not an integer.
-    """
-    fh = self.filesystem.GetOpenFile(file_des)
-    fh.close()
-
-  def read(self, file_des, num_bytes):
-    """Reads number of bytes from a file descriptor, returns bytes read.
-
-    Args:
-      file_des: An integer file descriptor for the file object requested.
-      num_bytes: Number of bytes to read from file.
-
-    Returns:
-      Bytes read from file.
-
-    Raises:
-      OSError: bad file descriptor.
-      TypeError: if file descriptor is not an integer.
-    """
-    fh = self.filesystem.GetOpenFile(file_des)
-    return fh.read(num_bytes)
-
-  def write(self, file_des, contents):
-    """Writes string to file descriptor, returns number of bytes written.
-
-    Args:
-      file_des: An integer file descriptor for the file object requested.
-      contents: String of bytes to write to file.
-
-    Returns:
-      Number of bytes written.
-
-    Raises:
-      OSError: bad file descriptor.
-      TypeError: if file descriptor is not an integer.
-    """
-    fh = self.filesystem.GetOpenFile(file_des)
-    fh.write(contents)
-    fh.flush()
-    return len(contents)
-
-  def fstat(self, file_des):
-    """Returns the os.stat-like tuple for the FakeFile object of file_des.
-
-    Args:
-      file_des:  file descriptor of filesystem object to retrieve
-
-    Returns:
-      the os.stat_result object corresponding to entry_path
-
-    Raises:
-      OSError: if the filesystem object doesn't exist.
-    """
-    # stat should return the tuple representing return value of os.stat
-    stats = self.filesystem.GetOpenFile(file_des).GetObject()
-    st_obj = os.stat_result((stats.st_mode, stats.st_ino, stats.st_dev,
-                             stats.st_nlink, stats.st_uid, stats.st_gid,
-                             stats.st_size, stats.st_atime,
-                             stats.st_mtime, stats.st_ctime))
-    return st_obj
-
-  def _ConfirmDir(self, target_directory):
-    """Tests that the target is actually a directory, raising OSError if not.
-
-    Args:
-      target_directory:  path to the target directory within the fake
-        filesystem
-
-    Returns:
-      the FakeFile object corresponding to target_directory
-
-    Raises:
-      OSError:  if the target is not a directory
-    """
-    try:
-      directory = self.filesystem.GetObject(target_directory)
-    except IOError as e:
-      raise OSError(e.errno, e.strerror, target_directory)
-    if not directory.st_mode & stat.S_IFDIR:
-      raise OSError(errno.ENOTDIR,
-                    'Fake os module: not a directory',
-                    target_directory)
-    return directory
-
-  def umask(self, new_mask):
-    """Change the current umask.
-
-    Args:
-      new_mask: An integer.
-
-    Returns:
-      The old mask.
-
-    Raises:
-      TypeError: new_mask is of an invalid type.
-    """
-    if not isinstance(new_mask, int):
-      raise TypeError('an integer is required')
-    old_umask = self.filesystem.umask
-    self.filesystem.umask = new_mask
-    return old_umask
-
-  def chdir(self, target_directory):
-    """Change current working directory to target directory.
-
-    Args:
-      target_directory:  path to new current working directory
-
-    Raises:
-      OSError: if user lacks permission to enter the argument directory or if
-               the target is not a directory
-    """
-    target_directory = self.filesystem.ResolvePath(target_directory)
-    self._ConfirmDir(target_directory)
-    directory = self.filesystem.GetObject(target_directory)
-    # A full implementation would check permissions all the way up the tree.
-    if not directory.st_mode | PERM_EXE:
-      raise OSError(errno.EACCES, 'Fake os module: permission denied',
-                    directory)
-    self.filesystem.cwd = target_directory
-
-  def getcwd(self):
-    """Return current working directory."""
-    return self.filesystem.cwd
-
-  def getcwdu(self):
-    """Return current working directory. Deprecated in Python 3."""
-    if sys.version_info >= (3, 0):
-      raise AttributeError('no attribute getcwdu')
-    return unicode(self.filesystem.cwd)
-
-  def listdir(self, target_directory):
-    """Returns a sorted list of filenames in target_directory.
-
-    Args:
-      target_directory:  path to the target directory within the fake
-        filesystem
-
-    Returns:
-      a sorted list of file names within the target directory
-
-    Raises:
-      OSError:  if the target is not a directory
-    """
-    target_directory = self.filesystem.ResolvePath(target_directory)
-    directory = self._ConfirmDir(target_directory)
-    return sorted(directory.contents)
-
-  def _ClassifyDirectoryContents(self, root):
-    """Classify contents of a directory as files/directories.
-
-    Args:
-      root: (str) Directory to examine.
-
-    Returns:
-      (tuple) A tuple consisting of three values: the directory examined, a
-      list containing all of the directory entries, and a list containing all
-      of the non-directory entries.  (This is the same format as returned by
-      the os.walk generator.)
-
-    Raises:
-      Nothing on its own, but be ready to catch exceptions generated by
-      underlying mechanisms like os.listdir.
-    """
-    dirs = []
-    files = []
-    for entry in self.listdir(root):
-      if self.path.isdir(self.path.join(root, entry)):
-        dirs.append(entry)
-      else:
-        files.append(entry)
-    return (root, dirs, files)
-
-  def walk(self, top, topdown=True, onerror=None):
-    """Performs an os.walk operation over the fake filesystem.
-
-    Args:
-      top:  root directory from which to begin walk
-      topdown:  determines whether to return the tuples with the root as the
-        first entry (True) or as the last, after all the child directory
-        tuples (False)
-      onerror:  if not None, function which will be called to handle the
-        os.error instance provided when os.listdir() fails
-
-    Yields:
-      (path, directories, nondirectories) for top and each of its
-      subdirectories.  See the documentation for the builtin os module for
-      further details.
-    """
-    top = self.path.normpath(top)
-    try:
-      top_contents = self._ClassifyDirectoryContents(top)
-    except OSError as e:
-      top_contents = None
-      if onerror is not None:
-        onerror(e)
-
-    if top_contents is not None:
-      if topdown:
-        yield top_contents
-
-      for directory in top_contents[1]:
-        for contents in self.walk(self.path.join(top, directory),
-                                  topdown=topdown, onerror=onerror):
-          yield contents
-
-      if not topdown:
-        yield top_contents
-
-  def readlink(self, path):
-    """Reads the target of a symlink.
-
-    Args:
-      path:  symlink to read the target of
-
-    Returns:
-      the string representing the path to which the symbolic link points.
-
-    Raises:
-      TypeError: if path is None
-      OSError: (with errno=ENOENT) if path is not a valid path, or
-               (with errno=EINVAL) if path is valid, but is not a symlink
-    """
-    if path is None:
-      raise TypeError
-    try:
-      link_obj = self.filesystem.LResolveObject(path)
-    except IOError:
-      raise OSError(errno.ENOENT, 'Fake os module: path does not exist', path)
-    if stat.S_IFMT(link_obj.st_mode) != stat.S_IFLNK:
-      raise OSError(errno.EINVAL, 'Fake os module: not a symlink', path)
-    return link_obj.contents
-
-  def stat(self, entry_path):
-    """Returns the os.stat-like tuple for the FakeFile object of entry_path.
-
-    Args:
-      entry_path:  path to filesystem object to retrieve
-
-    Returns:
-      the os.stat_result object corresponding to entry_path
-
-    Raises:
-      OSError: if the filesystem object doesn't exist.
-    """
-    # stat should return the tuple representing return value of os.stat
-    try:
-      stats = self.filesystem.ResolveObject(entry_path)
-      st_obj = os.stat_result((stats.st_mode, stats.st_ino, stats.st_dev,
-                               stats.st_nlink, stats.st_uid, stats.st_gid,
-                               stats.st_size, stats.st_atime,
-                               stats.st_mtime, stats.st_ctime))
-      return st_obj
-    except IOError as io_error:
-      raise OSError(io_error.errno, io_error.strerror, entry_path)
-
-  def lstat(self, entry_path):
-    """Returns the os.stat-like tuple for entry_path, not following symlinks.
-
-    Args:
-      entry_path:  path to filesystem object to retrieve
-
-    Returns:
-      the os.stat_result object corresponding to entry_path
-
-    Raises:
-      OSError: if the filesystem object doesn't exist.
-    """
-    # stat should return the tuple representing return value of os.stat
-    try:
-      stats = self.filesystem.LResolveObject(entry_path)
-      st_obj = os.stat_result((stats.st_mode, stats.st_ino, stats.st_dev,
-                               stats.st_nlink, stats.st_uid, stats.st_gid,
-                               stats.st_size, stats.st_atime,
-                               stats.st_mtime, stats.st_ctime))
-      return st_obj
-    except IOError as io_error:
-      raise OSError(io_error.errno, io_error.strerror, entry_path)
-
-  def remove(self, path):
-    """Removes the FakeFile object representing the specified file."""
-    path = self.filesystem.NormalizePath(path)
-    if self.path.isdir(path) and not self.path.islink(path):
-      raise OSError(errno.EISDIR, "Is a directory: '%s'" % path)
-    try:
-      self.filesystem.RemoveObject(path)
-    except IOError as e:
-      raise OSError(e.errno, e.strerror, e.filename)
-
-  # As per the documentation unlink = remove.
-  unlink = remove
-
-  def rename(self, old_file, new_file):
-    """Adds a FakeFile object at new_file containing contents of old_file.
-
-    Also removes the FakeFile object for old_file, and replaces existing
-    new_file object, if one existed.
-
-    Args:
-      old_file:  path to filesystem object to rename
-      new_file:  path to where the filesystem object will live after this call
-
-    Raises:
-      OSError:  if old_file does not exist.
-      IOError:  if dirname(new_file) does not exist
-    """
-    old_file = self.filesystem.NormalizePath(old_file)
-    new_file = self.filesystem.NormalizePath(new_file)
-    if not self.filesystem.Exists(old_file):
-      raise OSError(errno.ENOENT,
-                    'Fake os object: can not rename nonexistent file '
-                    'with name',
-                    old_file)
-    if self.filesystem.Exists(new_file):
-      if old_file == new_file:
-        return None  # Nothing to do here.
-      else:
-        self.remove(new_file)
-    old_dir, old_name = self.path.split(old_file)
-    new_dir, new_name = self.path.split(new_file)
-    if not self.filesystem.Exists(new_dir):
-      raise IOError(errno.ENOENT, 'No such fake directory', new_dir)
-    old_dir_object = self.filesystem.ResolveObject(old_dir)
-    old_object = old_dir_object.GetEntry(old_name)
-    old_object_mtime = old_object.st_mtime
-    new_dir_object = self.filesystem.ResolveObject(new_dir)
-    if old_object.st_mode & stat.S_IFDIR:
-      old_object.name = new_name
-      new_dir_object.AddEntry(old_object)
-      old_dir_object.RemoveEntry(old_name)
-    else:
-      self.filesystem.CreateFile(new_file,
-                                 st_mode=old_object.st_mode,
-                                 contents=old_object.contents,
-                                 create_missing_dirs=False)
-      self.remove(old_file)
-    new_object = self.filesystem.GetObject(new_file)
-    new_object.SetMTime(old_object_mtime)
-    self.chown(new_file, old_object.st_uid, old_object.st_gid)
-
-  def rmdir(self, target_directory):
-    """Remove a leaf Fake directory.
-
-    Args:
-      target_directory: (str) Name of directory to remove.
-
-    Raises:
-      OSError: if target_directory does not exist or is not a directory,
-      or as per FakeFilesystem.RemoveObject. Cannot remove '.'.
-    """
-    if target_directory == '.':
-      raise OSError(errno.EINVAL, 'Invalid argument: \'.\'')
-    target_directory = self.filesystem.NormalizePath(target_directory)
-    if self._ConfirmDir(target_directory):
-      if self.listdir(target_directory):
-        raise OSError(errno.ENOTEMPTY, 'Fake Directory not empty',
-                      target_directory)
-      try:
-        self.filesystem.RemoveObject(target_directory)
-      except IOError as e:
-        raise OSError(e.errno, e.strerror, e.filename)
-
-  def removedirs(self, target_directory):
-    """Remove a leaf Fake directory and all empty intermediate ones."""
-    target_directory = self.filesystem.NormalizePath(target_directory)
-    directory = self._ConfirmDir(target_directory)
-    if directory.contents:
-      raise OSError(errno.ENOTEMPTY, 'Fake Directory not empty',
-                    self.path.basename(target_directory))
-    else:
-      self.rmdir(target_directory)
-    head, tail = self.path.split(target_directory)
-    if not tail:
-      head, tail = self.path.split(head)
-    while head and tail:
-      head_dir = self._ConfirmDir(head)
-      if head_dir.contents:
-        break
-      self.rmdir(head)
-      head, tail = self.path.split(head)
-
-  def mkdir(self, dir_name, mode=PERM_DEF):
-    """Create a leaf Fake directory.
-
-    Args:
-      dir_name: (str) Name of directory to create.  Relative paths are assumed
-        to be relative to '/'.
-      mode: (int) Mode to create directory with.  This argument defaults to
-        0o777.  The umask is applied to this mode.
-
-    Raises:
-      OSError: if the directory name is invalid or parent directory is read only
-      or as per FakeFilesystem.AddObject.
-    """
-    if dir_name.endswith(self.sep):
-      dir_name = dir_name[:-1]
-
-    parent_dir, _ = self.path.split(dir_name)
-    if parent_dir:
-      base_dir = self.path.normpath(parent_dir)
-      if parent_dir.endswith(self.sep + '..'):
-        base_dir, unused_dotdot, _ = parent_dir.partition(self.sep + '..')
-      if not self.filesystem.Exists(base_dir):
-        raise OSError(errno.ENOENT, 'No such fake directory', base_dir)
-
-    dir_name = self.filesystem.NormalizePath(dir_name)
-    if self.filesystem.Exists(dir_name):
-      raise OSError(errno.EEXIST, 'Fake object already exists', dir_name)
-    head, tail = self.path.split(dir_name)
-    directory_object = self.filesystem.GetObject(head)
-    if not directory_object.st_mode & PERM_WRITE:
-      raise OSError(errno.EACCES, 'Permission Denied', dir_name)
-
-    self.filesystem.AddObject(
-        head, FakeDirectory(tail, mode & ~self.filesystem.umask))
-
-  def makedirs(self, dir_name, mode=PERM_DEF):
-    """Create a leaf Fake directory + create any non-existent parent dirs.
-
-    Args:
-      dir_name: (str) Name of directory to create.
-      mode: (int) Mode to create directory (and any necessary parent
-        directories) with. This argument defaults to 0o777.  The umask is
-        applied to this mode.
-
-    Raises:
-      OSError: if the directory already exists or as per
-      FakeFilesystem.CreateDirectory
-    """
-    dir_name = self.filesystem.NormalizePath(dir_name)
-    path_components = self.filesystem.GetPathComponents(dir_name)
-
-    # Raise a permission denied error if the first existing directory is not
-    # writeable.
-    current_dir = self.filesystem.root
-    for component in path_components:
-      if component not in current_dir.contents:
-        if not current_dir.st_mode & PERM_WRITE:
-          raise OSError(errno.EACCES, 'Permission Denied', dir_name)
-        else:
-          break
-      else:
-        current_dir = current_dir.contents[component]
-
-    self.filesystem.CreateDirectory(dir_name, mode & ~self.filesystem.umask)
-
-  def access(self, path, mode):
-    """Check if a file exists and has the specified permissions.
-
-    Args:
-      path: (str) Path to the file.
-      mode: (int) Permissions represented as a bitwise-OR combination of
-          os.F_OK, os.R_OK, os.W_OK, and os.X_OK.
-    Returns:
-      boolean, True if file is accessible, False otherwise
-    """
-    try:
-      st = self.stat(path)
-    except OSError as os_error:
-      if os_error.errno == errno.ENOENT:
-        return False
-      raise
-    return (mode & ((st.st_mode >> 6) & 7)) == mode
-
-  def chmod(self, path, mode):
-    """Change the permissions of a file as encoded in integer mode.
-
-    Args:
-      path: (str) Path to the file.
-      mode: (int) Permissions
-    """
-    try:
-      file_object = self.filesystem.GetObject(path)
-    except IOError as io_error:
-      if io_error.errno == errno.ENOENT:
-        raise OSError(errno.ENOENT,
-                      'No such file or directory in fake filesystem',
-                      path)
-      raise
-    file_object.st_mode = ((file_object.st_mode & ~PERM_ALL) |
-                           (mode & PERM_ALL))
-    file_object.st_ctime = int(time.time())
-
-  def utime(self, path, times):
-    """Change the access and modified times of a file.
-
-    Args:
-      path: (str) Path to the file.
-      times: 2-tuple of numbers, of the form (atime, mtime) which is used to set
-          the access and modified times, respectively. If None, file's access
-          and modified times are set to the current time.
-
-    Raises:
-      TypeError: If anything other than integers is specified in passed tuple or
-          number of elements in the tuple is not equal to 2.
-    """
-    try:
-      file_object = self.filesystem.GetObject(path)
-    except IOError as io_error:
-      if io_error.errno == errno.ENOENT:
-        raise OSError(errno.ENOENT,
-                      'No such file or directory in fake filesystem',
-                      path)
-      raise
-    if times is None:
-      file_object.st_atime = int(time.time())
-      file_object.st_mtime = int(time.time())
-    else:
-      if len(times) != 2:
-        raise TypeError('utime() arg 2 must be a tuple (atime, mtime)')
-      for t in times:
-        if not isinstance(t, (int, float)):
-          raise TypeError('an integer is required')
-
-      file_object.st_atime = times[0]
-      file_object.st_mtime = times[1]
-
-  def chown(self, path, uid, gid):
-    """Set ownership of a faked file.
-
-    Args:
-      path: (str) Path to the file or directory.
-      uid: (int) Numeric uid to set the file or directory to.
-      gid: (int) Numeric gid to set the file or directory to.
-    """
-    try:
-      file_object = self.filesystem.GetObject(path)
-    except IOError as io_error:
-      if io_error.errno == errno.ENOENT:
-        raise OSError(errno.ENOENT,
-                      'No such file or directory in fake filesystem',
-                      path)
-      raise
-    if uid != -1:
-      file_object.st_uid = uid
-    if gid != -1:
-      file_object.st_gid = gid
-
-  def mknod(self, filename, mode=None, device=None):
-    """Create a filesystem node named 'filename'.
-
-    Does not support device special files or named pipes as the real os
-    module does.
-
-    Args:
-      filename: (str) Name of the file to create
-      mode: (int) permissions to use and type of file to be created.
-        Default permissions are 0o666.  Only the stat.S_IFREG file type
-        is supported by the fake implementation.  The umask is applied
-        to this mode.
-      device: not supported in fake implementation
-
-    Raises:
-      OSError: if called with unsupported options or the file can not be
-      created.
-    """
-    if mode is None:
-      mode = stat.S_IFREG | PERM_DEF_FILE
-    if device or not mode & stat.S_IFREG:
-      raise OSError(errno.EINVAL,
-                    'Fake os mknod implementation only supports '
-                    'regular files.')
-
-    head, tail = self.path.split(filename)
-    if not tail:
-      if self.filesystem.Exists(head):
-        raise OSError(errno.EEXIST, 'Fake filesystem: %s: %s' % (
-            os.strerror(errno.EEXIST), filename))
-      raise OSError(errno.ENOENT, 'Fake filesystem: %s: %s' % (
-          os.strerror(errno.ENOENT), filename))
-    if tail == '.' or tail == '..' or self.filesystem.Exists(filename):
-      raise OSError(errno.EEXIST, 'Fake fileystem: %s: %s' % (
-          os.strerror(errno.EEXIST), filename))
-    try:
-      self.filesystem.AddObject(head, FakeFile(tail,
-                                               mode & ~self.filesystem.umask))
-    except IOError:
-      raise OSError(errno.ENOTDIR, 'Fake filesystem: %s: %s' % (
-          os.strerror(errno.ENOTDIR), filename))
-
-  def symlink(self, link_target, path):
-    """Creates the specified symlink, pointed at the specified link target.
-
-    Args:
-      link_target:  the target of the symlink
-      path:  path to the symlink to create
-
-    Returns:
-      None
-
-    Raises:
-      IOError:  if the file already exists
-    """
-    self.filesystem.CreateLink(path, link_target)
-
-  # pylint: disable-msg=C6002
-  # TODO: Link doesn't behave like os.link, this needs to be fixed properly.
-  link = symlink
-
-  def __getattr__(self, name):
-    """Forwards any unfaked calls to the standard os module."""
-    return getattr(self._os_module, name)
-
-
-class FakeFileOpen(object):
-  """Faked file() and open() function replacements.
-
-  Returns FakeFile objects in a FakeFilesystem in place of the file()
-  or open() function.
-  """
-
-  def __init__(self, filesystem, delete_on_close=False):
-    """init.
-
-    Args:
-      filesystem:  FakeFilesystem used to provide file system information
-      delete_on_close:  optional boolean, deletes file on close()
-    """
-    self.filesystem = filesystem
-    self._delete_on_close = delete_on_close
-
-  def __call__(self, *args, **kwargs):
-    """Redirects calls to file() or open() to appropriate method."""
-    if sys.version_info < (3, 0):
-      return self._call_ver2(*args, **kwargs)
-    else:
-      return self.Call(*args, **kwargs)
-
-  def _call_ver2(self, file_path, mode='r', buffering=-1, flags=None):
-    """Limits args of open() or file() for Python 2.x versions."""
-    # Backwards compatibility, mode arg used to be named flags
-    mode = flags or mode
-    return self.Call(file_path, mode, buffering)
-
-  def Call(self, file_, mode='r', buffering=-1, encoding=None,
-           errors=None, newline=None, closefd=True, opener=None):
-    """Returns a StringIO object with the contents of the target file object.
-
-    Args:
-      file_: path to target file or a file descriptor
-      mode: additional file modes. All r/w/a r+/w+/a+ modes are supported.
-        't', and 'U' are ignored, e.g., 'wU' is treated as 'w'. 'b' sets
-        binary mode, no end of line translations in StringIO.
-      buffering: ignored. (Used for signature compliance with __builtin__.open)
-      encoding: ignored, strings have no encoding
-      errors: ignored, this relates to encoding
-      newline: controls universal newlines, passed to StringIO object
-      closefd: if a file descriptor rather than file name is passed, and set
-        to false, then the file descriptor is kept open when file is closed
-      opener: not supported
-
-    Returns:
-      a StringIO object containing the contents of the target file
-
-    Raises:
-      IOError: if the target object is a directory, the path is invalid or
-        permission is denied.
-    """
-    orig_modes = mode  # Save original mdoes for error messages.
-    # Binary mode for non 3.x or set by mode
-    binary = sys.version_info < (3, 0) or 'b' in mode
-    # Normalize modes. Ignore 't' and 'U'.
-    mode = mode.replace('t', '').replace('b', '')
-    mode = mode.replace('rU', 'r').replace('U', 'r')
-
-    if mode not in _OPEN_MODE_MAP:
-      raise IOError('Invalid mode: %r' % orig_modes)
-
-    must_exist, need_read, need_write, truncate, append = _OPEN_MODE_MAP[mode]
-
-    file_object = None
-    filedes = None
-    # opening a file descriptor
-    if isinstance(file_, int):
-      filedes = file_
-      file_object = self.filesystem.GetOpenFile(filedes).GetObject()
-      file_path = file_object.name
-    else:
-      file_path = file_
-      real_path = self.filesystem.ResolvePath(file_path)
-      if self.filesystem.Exists(file_path):
-        file_object = self.filesystem.GetObjectFromNormalizedPath(real_path)
-      closefd = True
-
-    if file_object:
-      if ((need_read and not file_object.st_mode & PERM_READ) or
-          (need_write and not file_object.st_mode & PERM_WRITE)):
-        raise IOError(errno.EACCES, 'Permission denied', file_path)
-      if need_write:
-        file_object.st_ctime = int(time.time())
-        if truncate:
-          file_object.SetContents('')
-    else:
-      if must_exist:
-        raise IOError(errno.ENOENT, 'No such file or directory', file_path)
-      file_object = self.filesystem.CreateFile(
-          real_path, create_missing_dirs=False, apply_umask=True)
-
-    if file_object.st_mode & stat.S_IFDIR:
-      raise IOError(errno.EISDIR, 'Fake file object: is a directory', file_path)
-
-    class FakeFileWrapper(object):
-      """Wrapper for a StringIO object for use by a FakeFile object.
-
-      If the wrapper has any data written to it, it will propagate to
-      the FakeFile object on close() or flush().
-      """
-      if sys.version_info < (3, 0):
-        _OPERATION_ERROR = IOError
-      else:
-        _OPERATION_ERROR = io.UnsupportedOperation
-
-      def __init__(self, file_object, update=False, read=False, append=False,
-                   delete_on_close=False, filesystem=None, newline=None,
-                   binary=True, closefd=True):
-        self._file_object = file_object
-        self._append = append
-        self._read = read
-        self._update = update
-        self._closefd = closefd
-        self._file_epoch = file_object.epoch
-        contents = file_object.contents
-        newline_arg = {} if binary else {'newline': newline}
-        io_class = io.StringIO
-        # For Python 3, files opened as binary only read/write byte contents.
-        if sys.version_info >= (3, 0) and binary:
-          io_class = io.BytesIO
-          if contents and isinstance(contents, str):
-            contents = bytes(contents, 'ascii')
-        if contents:
-          if update:
-            self._io = io_class(**newline_arg)
-            self._io.write(contents)
-            if not append:
-              self._io.seek(0)
-            else:
-              self._read_whence = 0
-              if read:
-                self._read_seek = 0
-              else:
-                self._read_seek = self._io.tell()
-          else:
-            self._io = io_class(contents, **newline_arg)
-        else:
-          self._io = io_class(**newline_arg)
-          self._read_whence = 0
-          self._read_seek = 0
-        if delete_on_close:
-          assert filesystem, 'delete_on_close=True requires filesystem='
-        self._filesystem = filesystem
-        self._delete_on_close = delete_on_close
-        # override, don't modify FakeFile.name, as FakeFilesystem expects
-        # it to be the file name only, no directories.
-        self.name = file_object.opened_as
-
-      def __enter__(self):
-        """To support usage of this fake file with the 'with' statement."""
-        return self
-
-      def __exit__(self, type, value, traceback):  # pylint: disable-msg=W0622
-        """To support usage of this fake file with the 'with' statement."""
-        self.close()
-
-      def GetObject(self):
-        """Returns FakeFile object that is wrapped by current class."""
-        return self._file_object
-
-      def fileno(self):
-        """Returns file descriptor of file object."""
-        return self.filedes
-
-      def close(self):
-        """File close."""
-        if self._update:
-          self._file_object.SetContents(self._io.getvalue())
-        if self._closefd:
-          self._filesystem.CloseOpenFile(self)
-        if self._delete_on_close:
-          self._filesystem.RemoveObject(self.name)
-
-      def flush(self):
-        """Flush file contents to 'disk'."""
-        if self._update:
-          self._file_object.SetContents(self._io.getvalue())
-          self._file_epoch = self._file_object.epoch
-
-      def seek(self, offset, whence=0):
-        """Move read/write pointer in 'file'."""
-        if not self._append:
-          self._io.seek(offset, whence)
-        else:
-          self._read_seek = offset
-          self._read_whence = whence
-
-      def tell(self):
-        """Return the file's current position.
-
-        Returns:
-          int, file's current position in bytes.
-        """
-        if not self._append:
-          return self._io.tell()
-        if self._read_whence:
-          write_seek = self._io.tell()
-          self._io.seek(self._read_seek, self._read_whence)
-          self._read_seek = self._io.tell()
-          self._read_whence = 0
-          self._io.seek(write_seek)
-        return self._read_seek
-
-      def _UpdateStringIO(self):
-        """Updates the StringIO with changes to the file object contents."""
-        if self._file_epoch == self._file_object.epoch:
-          return
-        whence = self._io.tell()
-        self._io.seek(0)
-        self._io.truncate()
-        self._io.write(self._file_object.contents)
-        self._io.seek(whence)
-        self._file_epoch = self._file_object.epoch
-
-      def _ReadWrappers(self, name):
-        """Wrap a StringIO attribute in a read wrapper.
-
-        Returns a read_wrapper which tracks our own read pointer since the
-        StringIO object has no concept of a different read and write pointer.
-
-        Args:
-          name: the name StringIO attribute to wrap.  Should be a read call.
-
-        Returns:
-          either a read_error or read_wrapper function.
-        """
-        io_attr = getattr(self._io, name)
-
-        def read_wrapper(*args, **kwargs):
-          """Wrap all read calls to the StringIO Object.
-
-          We do this to track the read pointer separate from the write
-          pointer.  Anything that wants to read from the StringIO object
-          while we're in append mode goes through this.
-
-          Args:
-            *args: pass through args
-            **kwargs: pass through kwargs
-          Returns:
-            Wrapped StringIO object method
-          """
-          self._io.seek(self._read_seek, self._read_whence)
-          ret_value = io_attr(*args, **kwargs)
-          self._read_seek = self._io.tell()
-          self._read_whence = 0
-          self._io.seek(0, 2)
-          return ret_value
-        return read_wrapper
-
-      def _OtherWrapper(self, name):
-        """Wrap a StringIO attribute in an other_wrapper.
-
-        Args:
-          name: the name of the StringIO attribute to wrap.
-
-        Returns:
-          other_wrapper which is described below.
-        """
-        io_attr = getattr(self._io, name)
-
-        def other_wrapper(*args, **kwargs):
-          """Wrap all other calls to the StringIO Object.
-
-          We do this to track changes to the write pointer.  Anything that
-          moves the write pointer in a file open for appending should move
-          the read pointer as well.
-
-          Args:
-            *args: pass through args
-            **kwargs: pass through kwargs
-          Returns:
-            Wrapped StringIO object method
-          """
-          write_seek = self._io.tell()
-          ret_value = io_attr(*args, **kwargs)
-          if write_seek != self._io.tell():
-            self._read_seek = self._io.tell()
-            self._read_whence = 0
-            self._file_object.st_size += (self._read_seek - write_seek)
-          return ret_value
-        return other_wrapper
-
-      def Size(self):
-        return self._file_object.st_size
-
-      def __getattr__(self, name):
-        if self._file_object.IsLargeFile():
-          raise FakeLargeFileIoException(file_path)
-
-        # errors on called method vs. open mode
-        if not self._read and name.startswith('read'):
-          def read_error(*args, **kwargs):
-            """Throw an error unless the argument is zero."""
-            if args and args[0] == 0:
-              return ''
-            raise self._OPERATION_ERROR('File is not open for reading.')
-          return read_error
-        if not self._update and (name.startswith('write')
-                                 or name == 'truncate'):
-          def write_error(*args, **kwargs):
-            """Throw an error."""
-            raise self._OPERATION_ERROR('File is not open for writing.')
-          return write_error
-
-        if name.startswith('read'):
-          self._UpdateStringIO()
-        if self._append:
-          if name.startswith('read'):
-            return self._ReadWrappers(name)
-          else:
-            return self._OtherWrapper(name)
-        return getattr(self._io, name)
-
-      def __iter__(self):
-        if not self._read:
-          raise self._OPERATION_ERROR('File is not open for reading')
-        return self._io.__iter__()
-
-    # if you print obj.name, the argument to open() must be printed. Not the
-    # abspath, not the filename, but the actual argument.
-    file_object.opened_as = file_path
-
-    fakefile = FakeFileWrapper(file_object,
-                               update=need_write,
-                               read=need_read,
-                               append=append,
-                               delete_on_close=self._delete_on_close,
-                               filesystem=self.filesystem,
-                               newline=newline,
-                               binary=binary,
-                               closefd=closefd)
-    if filedes is not None:
-      fakefile.filedes = filedes
-    else:
-      fakefile.filedes = self.filesystem.AddOpenFile(fakefile)
-    return fakefile
- 
-
-def _RunDoctest():
-  # pylint: disable-msg=C6204
-  import doctest
-  import fake_filesystem  # pylint: disable-msg=W0406
-  return doctest.testmod(fake_filesystem)
-
-
-if __name__ == '__main__':
-  _RunDoctest()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_glob.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_glob.py
deleted file mode 100755
index db387df..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_glob.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""A fake glob module implementation that uses fake_filesystem for unit tests.
-
-Includes:
-  FakeGlob: Uses a FakeFilesystem to provide a fake replacement for the
-    glob module.
-
-Usage:
->>> import fake_filesystem
->>> import fake_filesystem_glob
->>> filesystem = fake_filesystem.FakeFilesystem()
->>> glob_module = fake_filesystem_glob.FakeGlobModule(filesystem)
-
->>> file = filesystem.CreateFile('new-file')
->>> glob_module.glob('*')
-['new-file']
->>> glob_module.glob('???-file')
-['new-file']
-"""
-
-import fnmatch
-import glob
-import os
-
-import fake_filesystem
-
-
-class FakeGlobModule(object):
-  """Uses a FakeFilesystem to provide a fake replacement for glob module."""
-
-  def __init__(self, filesystem):
-    """Construct fake glob module using the fake filesystem.
-
-    Args:
-      filesystem:  FakeFilesystem used to provide file system information
-    """
-    self._glob_module = glob
-    self._os_module = fake_filesystem.FakeOsModule(filesystem)
-    self._path_module = self._os_module.path
-
-  def glob(self, pathname):  # pylint: disable-msg=C6409
-    """Return a list of paths matching a pathname pattern.
-
-    The pattern may contain shell-style wildcards a la fnmatch.
-
-    Args:
-      pathname: the pattern with which to find a list of paths
-
-    Returns:
-      List of strings matching the glob pattern.
-    """
-    if not self.has_magic(pathname):
-      if self._path_module.exists(pathname):
-        return [pathname]
-      else:
-        return []
-
-    dirname, basename = self._path_module.split(pathname)
-
-    if not dirname:
-      return self.glob1(self._path_module.curdir, basename)
-    elif self.has_magic(dirname):
-      path_list = self.glob(dirname)
-    else:
-      path_list = [dirname]
-
-    if not self.has_magic(basename):
-      result = []
-      for dirname in path_list:
-        if basename or self._path_module.isdir(dirname):
-          name = self._path_module.join(dirname, basename)
-          if self._path_module.exists(name):
-            result.append(name)
-    else:
-      result = []
-      for dirname in path_list:
-        sublist = self.glob1(dirname, basename)
-        for name in sublist:
-          result.append(self._path_module.join(dirname, name))
-
-    return result
-
-  def glob1(self, dirname, pattern):  # pylint: disable-msg=C6409
-    if not dirname:
-      dirname = self._path_module.curdir
-    try:
-      names = self._os_module.listdir(dirname)
-    except os.error:
-      return []
-    if pattern[0] != '.':
-      names = filter(lambda x: x[0] != '.', names)
-    return fnmatch.filter(names, pattern)
-
-  def __getattr__(self, name):
-    """Forwards any non-faked calls to the standard glob module."""
-    return getattr(self._glob_module, name)
-
-
-def _RunDoctest():
-  # pylint: disable-msg=C6111,C6204,W0406
-  import doctest
-  import fake_filesystem_glob
-  return doctest.testmod(fake_filesystem_glob)
-
-
-if __name__ == '__main__':
-  _RunDoctest()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_glob_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_glob_test.py
deleted file mode 100755
index b08f982..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_glob_test.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Test for fake_filesystem_glob."""
-
-import doctest
-import sys
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-
-import fake_filesystem
-import fake_filesystem_glob
-
-
-class FakeGlobUnitTest(unittest.TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.glob = fake_filesystem_glob.FakeGlobModule(self.filesystem)
-    directory = './xyzzy'
-    self.filesystem.CreateDirectory(directory)
-    self.filesystem.CreateDirectory('%s/subdir' % directory)
-    self.filesystem.CreateDirectory('%s/subdir2' % directory)
-    self.filesystem.CreateFile('%s/subfile' % directory)
-    self.filesystem.CreateFile('[Temp]')
-
-  def testGlobEmpty(self):
-    self.assertEqual(self.glob.glob(''), [])
-
-  def testGlobStar(self):
-    self.assertEqual(['/xyzzy/subdir', '/xyzzy/subdir2', '/xyzzy/subfile'],
-                     self.glob.glob('/xyzzy/*'))
-
-  def testGlobExact(self):
-    self.assertEqual(['/xyzzy'], self.glob.glob('/xyzzy'))
-    self.assertEqual(['/xyzzy/subfile'], self.glob.glob('/xyzzy/subfile'))
-
-  def testGlobQuestion(self):
-    self.assertEqual(['/xyzzy/subdir', '/xyzzy/subdir2', '/xyzzy/subfile'],
-                     self.glob.glob('/x?zz?/*'))
-
-  def testGlobNoMagic(self):
-    self.assertEqual(['/xyzzy'], self.glob.glob('/xyzzy'))
-    self.assertEqual(['/xyzzy/subdir'], self.glob.glob('/xyzzy/subdir'))
-
-  def testNonExistentPath(self):
-    self.assertEqual([], self.glob.glob('nonexistent'))
-
-  def testDocTest(self):
-    self.assertFalse(doctest.testmod(fake_filesystem_glob)[0])
-
-  def testMagicDir(self):
-    self.assertEqual(['/[Temp]'], self.glob.glob('/*emp*'))
-
-  def testRootGlob(self):
-    self.assertEqual(['[Temp]', 'xyzzy'], self.glob.glob('*'))
-
-  def testGlob1(self):
-    self.assertEqual(['[Temp]'], self.glob.glob1('/', '*Tem*'))
-
-  def testHasMagic(self):
-    self.assertTrue(self.glob.has_magic('['))
-    self.assertFalse(self.glob.has_magic('a'))
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_shutil.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_shutil.py
deleted file mode 100755
index 87aff44..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_shutil.py
+++ /dev/null
@@ -1,220 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# pylint: disable-msg=W0612,W0613,C6409
-
-"""A fake shutil module implementation that uses fake_filesystem for unit tests.
-
-Includes:
-  FakeShutil: Uses a FakeFilesystem to provide a fake replacement for the
-    shutil module.
-
-Usage:
->>> import fake_filesystem
->>> import fake_filesystem_shutil
->>> filesystem = fake_filesystem.FakeFilesystem()
->>> shutil_module = fake_filesystem_shutil.FakeShutilModule(filesystem)
-
-Copy a fake_filesystem directory tree:
->>> new_file = filesystem.CreateFile('/src/new-file')
->>> shutil_module.copytree('/src', '/dst')
->>> filesystem.Exists('/dst/new-file')
-True
-
-Remove a fake_filesystem directory tree:
->>> shutil_module.rmtree('/src')
->>> filesystem.Exists('/src/new-file')
-False
-"""
-
-import errno
-import os
-import shutil
-import stat
-
-__pychecker__ = 'no-reimportself'
-
-_PERM_WRITE = 0o200  # Write permission bit.
-_PERM_READ = 0o400   # Read permission bit.
-_PERM_ALL = 0o7777   # All permission bits.
-
-
-class FakeShutilModule(object):
-  """Uses a FakeFilesystem to provide a fake replacement for shutil module."""
-
-  def __init__(self, filesystem):
-    """Construct fake shutil module using the fake filesystem.
-
-    Args:
-      filesystem:  FakeFilesystem used to provide file system information
-    """
-    self.filesystem = filesystem
-    self._shutil_module = shutil
-
-  def rmtree(self, path, ignore_errors=False, onerror=None):
-    """Remove a directory and all its contents.
-
-    Args:
-      path: (str) Directory tree to remove.
-      ignore_errors: (bool) unimplemented
-      onerror: (func) unimplemented
-    """
-    self.filesystem.RemoveObject(path)
-
-  def copy(self, src, dst):
-    """Copy data and mode bits ("cp src dst").
-
-    Args:
-      src: (str) source file
-      dst: (str) destination, may be a directory
-    """
-    if self.filesystem.Exists(dst):
-      if stat.S_ISDIR(self.filesystem.GetObject(dst).st_mode):
-        dst = self.filesystem.JoinPaths(dst, os.path.basename(src))
-    self.copyfile(src, dst)
-    src_object = self.filesystem.GetObject(src)
-    dst_object = self.filesystem.GetObject(dst)
-    dst_object.st_mode = ((dst_object.st_mode & ~_PERM_ALL) |
-                          (src_object.st_mode & _PERM_ALL))
-
-  def copyfile(self, src, dst):
-    """Copy data from src to dst.
-
-    Args:
-      src: (str) source file
-      dst: (dst) destination file
-
-    Raises:
-      IOError: if the file can't be copied
-      shutil.Error: if the src and dst files are the same
-    """
-    src_file_object = self.filesystem.GetObject(src)
-    if not src_file_object.st_mode & _PERM_READ:
-      raise IOError(errno.EACCES, 'Permission denied', src)
-    if stat.S_ISDIR(src_file_object.st_mode):
-      raise IOError(errno.EISDIR, 'Is a directory', src)
-
-    dst_dir = os.path.dirname(dst)
-    if dst_dir:
-      if not self.filesystem.Exists(dst_dir):
-        raise IOError(errno.ENOTDIR, 'Not a directory', dst)
-      dst_dir_object = self.filesystem.GetObject(dst_dir)
-      if not dst_dir_object.st_mode & _PERM_WRITE:
-        raise IOError(errno.EACCES, 'Permission denied', dst_dir)
-
-    abspath_src = self.filesystem.NormalizePath(
-        self.filesystem.ResolvePath(src))
-    abspath_dst = self.filesystem.NormalizePath(
-        self.filesystem.ResolvePath(dst))
-    if abspath_src == abspath_dst:
-      raise shutil.Error('`%s` and `%s` are the same file' % (src, dst))
-
-    if self.filesystem.Exists(dst):
-      dst_file_object = self.filesystem.GetObject(dst)
-      if stat.S_ISDIR(dst_file_object.st_mode):
-        raise IOError(errno.EISDIR, 'Is a directory', dst)
-      if not dst_file_object.st_mode & _PERM_WRITE:
-        raise IOError(errno.EACCES, 'Permission denied', dst)
-      dst_file_object.SetContents(src_file_object.contents)
-
-    else:
-      self.filesystem.CreateFile(dst, contents=src_file_object.contents)
-
-  def copystat(self, src, dst):
-    """Copy all stat info (mode bits, atime, and mtime) from src to dst.
-
-    Args:
-      src: (str) source file
-      dst: (str) destination file
-    """
-    src_object = self.filesystem.GetObject(src)
-    dst_object = self.filesystem.GetObject(dst)
-    dst_object.st_mode = ((dst_object.st_mode & ~_PERM_ALL) |
-                          (src_object.st_mode & _PERM_ALL))
-    dst_object.st_uid = src_object.st_uid
-    dst_object.st_gid = src_object.st_gid
-    dst_object.st_atime = src_object.st_atime
-    dst_object.st_mtime = src_object.st_mtime
-
-  def copy2(self, src, dst):
-    """Copy data and all stat info ("cp -p src dst").
-
-    Args:
-      src: (str) source file
-      dst: (str) destination, may be a directory
-    """
-    if self.filesystem.Exists(dst):
-      if stat.S_ISDIR(self.filesystem.GetObject(dst).st_mode):
-        dst = self.filesystem.JoinPaths(dst, os.path.basename(src))
-    self.copyfile(src, dst)
-    self.copystat(src, dst)
-
-  def copytree(self, src, dst, symlinks=False):
-    """Recursively copy a directory tree.
-
-    Args:
-      src: (str) source directory
-      dst: (str) destination directory, must not already exist
-      symlinks: (bool) copy symlinks as symlinks instead of copying the
-                contents of the linked files. Currently unused.
-
-    Raises:
-      OSError: if src is missing or isn't a directory
-    """
-    self.filesystem.CreateDirectory(dst)
-    try:
-      directory = self.filesystem.GetObject(src)
-    except IOError as e:
-      raise OSError(e.errno, e.message)
-    if not stat.S_ISDIR(directory.st_mode):
-      raise OSError(errno.ENOTDIR,
-                    'Fake os module: %r not a directory' % src)
-    for name in directory.contents:
-      srcname = self.filesystem.JoinPaths(src, name)
-      dstname = self.filesystem.JoinPaths(dst, name)
-      src_mode = self.filesystem.GetObject(srcname).st_mode
-      if stat.S_ISDIR(src_mode):
-        self.copytree(srcname, dstname, symlinks)
-      else:
-        self.copy2(srcname, dstname)
-
-  def move(self, src, dst):
-    """Rename a file or directory.
-
-    Args:
-      src: (str) source file or directory
-      dst: (str) if the src is a directory, the dst must not already exist
-    """
-    if stat.S_ISDIR(self.filesystem.GetObject(src).st_mode):
-      self.copytree(src, dst, symlinks=True)
-    else:
-      self.copy2(src, dst)
-    self.filesystem.RemoveObject(src)
-
-  def __getattr__(self, name):
-    """Forwards any non-faked calls to the standard shutil module."""
-    return getattr(self._shutil_module, name)
-
-
-def _RunDoctest():
-  # pylint: disable-msg=C6111,C6204,W0406
-  import doctest
-  import fake_filesystem_shutil
-  return doctest.testmod(fake_filesystem_shutil)
-
-
-if __name__ == '__main__':
-  _RunDoctest()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_shutil_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_shutil_test.py
deleted file mode 100755
index 4f26518..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_shutil_test.py
+++ /dev/null
@@ -1,305 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unittest for fake_filesystem_shutil."""
-
-import stat
-import time
-import sys
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-
-import fake_filesystem
-import fake_filesystem_shutil
-
-
-class FakeShutilModuleTest(unittest.TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.shutil = fake_filesystem_shutil.FakeShutilModule(self.filesystem)
-
-  def testRmtree(self):
-    directory = 'xyzzy'
-    self.filesystem.CreateDirectory(directory)
-    self.filesystem.CreateDirectory('%s/subdir' % directory)
-    self.filesystem.CreateFile('%s/subfile' % directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.shutil.rmtree(directory)
-    self.assertFalse(self.filesystem.Exists(directory))
-
-  def testCopy(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    src_obj = self.filesystem.CreateFile(src_file)
-    src_obj.st_mode = ((src_obj.st_mode & ~0o7777) | 0o750)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.copy(src_file, dst_file)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    dst_obj = self.filesystem.GetObject(dst_file)
-    self.assertEqual(src_obj.st_mode, dst_obj.st_mode)
-
-  def testCopyDirectory(self):
-    src_file = 'xyzzy'
-    parent_directory = 'parent'
-    dst_file = '%s/%s' % (parent_directory, src_file)
-    src_obj = self.filesystem.CreateFile(src_file)
-    self.filesystem.CreateDirectory(parent_directory)
-    src_obj.st_mode = ((src_obj.st_mode & ~0o7777) | 0o750)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(parent_directory))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.copy(src_file, parent_directory)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    dst_obj = self.filesystem.GetObject(dst_file)
-    self.assertEqual(src_obj.st_mode, dst_obj.st_mode)
-
-  def testCopystat(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    src_obj = self.filesystem.CreateFile(src_file)
-    dst_obj = self.filesystem.CreateFile(dst_file)
-    src_obj.st_mode = ((src_obj.st_mode & ~0o7777) | 0o750)
-    src_obj.st_uid = 123
-    src_obj.st_gid = 123
-    src_obj.st_atime = time.time()
-    src_obj.st_mtime = time.time()
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.shutil.copystat(src_file, dst_file)
-    self.assertEqual(src_obj.st_mode, dst_obj.st_mode)
-    self.assertEqual(src_obj.st_uid, dst_obj.st_uid)
-    self.assertEqual(src_obj.st_gid, dst_obj.st_gid)
-    self.assertEqual(src_obj.st_atime, dst_obj.st_atime)
-    self.assertEqual(src_obj.st_mtime, dst_obj.st_mtime)
-
-  def testCopy2(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    src_obj = self.filesystem.CreateFile(src_file)
-    src_obj.st_mode = ((src_obj.st_mode & ~0o7777) | 0o750)
-    src_obj.st_uid = 123
-    src_obj.st_gid = 123
-    src_obj.st_atime = time.time()
-    src_obj.st_mtime = time.time()
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.copy2(src_file, dst_file)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    dst_obj = self.filesystem.GetObject(dst_file)
-    self.assertEqual(src_obj.st_mode, dst_obj.st_mode)
-    self.assertEqual(src_obj.st_uid, dst_obj.st_uid)
-    self.assertEqual(src_obj.st_gid, dst_obj.st_gid)
-    self.assertEqual(src_obj.st_atime, dst_obj.st_atime)
-    self.assertEqual(src_obj.st_mtime, dst_obj.st_mtime)
-
-  def testCopy2Directory(self):
-    src_file = 'xyzzy'
-    parent_directory = 'parent'
-    dst_file = '%s/%s' % (parent_directory, src_file)
-    src_obj = self.filesystem.CreateFile(src_file)
-    self.filesystem.CreateDirectory(parent_directory)
-    src_obj.st_mode = ((src_obj.st_mode & ~0o7777) | 0o750)
-    src_obj.st_uid = 123
-    src_obj.st_gid = 123
-    src_obj.st_atime = time.time()
-    src_obj.st_mtime = time.time()
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(parent_directory))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.copy2(src_file, parent_directory)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    dst_obj = self.filesystem.GetObject(dst_file)
-    self.assertEqual(src_obj.st_mode, dst_obj.st_mode)
-    self.assertEqual(src_obj.st_uid, dst_obj.st_uid)
-    self.assertEqual(src_obj.st_gid, dst_obj.st_gid)
-    self.assertEqual(src_obj.st_atime, dst_obj.st_atime)
-    self.assertEqual(src_obj.st_mtime, dst_obj.st_mtime)
-
-  def testCopytree(self):
-    src_directory = 'xyzzy'
-    dst_directory = 'xyzzy_copy'
-    self.filesystem.CreateDirectory(src_directory)
-    self.filesystem.CreateDirectory('%s/subdir' % src_directory)
-    self.filesystem.CreateFile('%s/subfile' % src_directory)
-    self.assertTrue(self.filesystem.Exists(src_directory))
-    self.assertFalse(self.filesystem.Exists(dst_directory))
-    self.shutil.copytree(src_directory, dst_directory)
-    self.assertTrue(self.filesystem.Exists(dst_directory))
-    self.assertTrue(self.filesystem.Exists('%s/subdir' % dst_directory))
-    self.assertTrue(self.filesystem.Exists('%s/subfile' % dst_directory))
-
-  def testCopytreeSrcIsFile(self):
-    src_file = 'xyzzy'
-    dst_directory = 'xyzzy_copy'
-    self.filesystem.CreateFile(src_file)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertFalse(self.filesystem.Exists(dst_directory))
-    self.assertRaises(OSError,
-                      self.shutil.copytree,
-                      src_file,
-                      dst_directory)
-
-  def testMoveFile(self):
-    src_file = 'original_xyzzy'
-    dst_file = 'moved_xyzzy'
-    self.filesystem.CreateFile(src_file)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.move(src_file, dst_file)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.assertFalse(self.filesystem.Exists(src_file))
-
-  def testMoveFileIntoDirectory(self):
-    src_file = 'xyzzy'
-    dst_directory = 'directory'
-    dst_file = '%s/%s' % (dst_directory, src_file)
-    self.filesystem.CreateFile(src_file)
-    self.filesystem.CreateDirectory(dst_directory)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.move(src_file, dst_directory)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.assertFalse(self.filesystem.Exists(src_file))
-
-  def testMoveDirectory(self):
-    src_directory = 'original_xyzzy'
-    dst_directory = 'moved_xyzzy'
-    self.filesystem.CreateDirectory(src_directory)
-    self.filesystem.CreateFile('%s/subfile' % src_directory)
-    self.filesystem.CreateDirectory('%s/subdir' % src_directory)
-    self.assertTrue(self.filesystem.Exists(src_directory))
-    self.assertFalse(self.filesystem.Exists(dst_directory))
-    self.shutil.move(src_directory, dst_directory)
-    self.assertTrue(self.filesystem.Exists(dst_directory))
-    self.assertTrue(self.filesystem.Exists('%s/subfile' % dst_directory))
-    self.assertTrue(self.filesystem.Exists('%s/subdir' % dst_directory))
-    self.assertFalse(self.filesystem.Exists(src_directory))
-
-
-class CopyFileTest(unittest.TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.shutil = fake_filesystem_shutil.FakeShutilModule(self.filesystem)
-
-  def testCommonCase(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    contents = 'contents of file'
-    self.filesystem.CreateFile(src_file, contents=contents)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertFalse(self.filesystem.Exists(dst_file))
-    self.shutil.copyfile(src_file, dst_file)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.assertEqual(contents, self.filesystem.GetObject(dst_file).contents)
-
-  def testRaisesIfSourceAndDestAreTheSameFile(self):
-    src_file = 'xyzzy'
-    dst_file = src_file
-    contents = 'contents of file'
-    self.filesystem.CreateFile(src_file, contents=contents)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertRaises(self.shutil.Error,
-                      self.shutil.copyfile, src_file, dst_file)
-
-  def testRaisesIfDestIsASymlinkToSrc(self):
-    src_file = '/tmp/foo'
-    dst_file = '/tmp/bar'
-    contents = 'contents of file'
-    self.filesystem.CreateFile(src_file, contents=contents)
-    self.filesystem.CreateLink(dst_file, src_file)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertRaises(self.shutil.Error,
-                      self.shutil.copyfile, src_file, dst_file)
-
-  def testSucceedsIfDestExistsAndIsWritable(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    src_contents = 'contents of source file'
-    dst_contents = 'contents of dest file'
-    self.filesystem.CreateFile(src_file, contents=src_contents)
-    self.filesystem.CreateFile(dst_file, contents=dst_contents)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.shutil.copyfile(src_file, dst_file)
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.assertEqual(src_contents,
-                     self.filesystem.GetObject(dst_file).contents)
-
-  def testRaisesIfDestExistsAndIsNotWritable(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    src_contents = 'contents of source file'
-    dst_contents = 'contents of dest file'
-    self.filesystem.CreateFile(src_file, contents=src_contents)
-    self.filesystem.CreateFile(dst_file,
-                               st_mode=stat.S_IFREG | 0o400,
-                               contents=dst_contents)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(dst_file))
-    self.assertRaises(IOError, self.shutil.copyfile, src_file, dst_file)
-
-  def testRaisesIfDestDirIsNotWritable(self):
-    src_file = 'xyzzy'
-    dst_dir = '/tmp/foo'
-    dst_file = '%s/%s' % (dst_dir, src_file)
-    src_contents = 'contents of source file'
-    self.filesystem.CreateFile(src_file, contents=src_contents)
-    self.filesystem.CreateDirectory(dst_dir, perm_bits=0o555)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(dst_dir))
-    self.assertRaises(IOError, self.shutil.copyfile, src_file, dst_file)
-
-  def testRaisesIfSrcDoesntExist(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    self.assertFalse(self.filesystem.Exists(src_file))
-    self.assertRaises(IOError, self.shutil.copyfile, src_file, dst_file)
-
-  def testRaisesIfSrcNotReadable(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    src_contents = 'contents of source file'
-    self.filesystem.CreateFile(src_file,
-                               st_mode=stat.S_IFREG | 0o000,
-                               contents=src_contents)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertRaises(IOError, self.shutil.copyfile, src_file, dst_file)
-
-  def testRaisesIfSrcIsADirectory(self):
-    src_file = 'xyzzy'
-    dst_file = 'xyzzy_copy'
-    self.filesystem.CreateDirectory(src_file)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertRaises(IOError, self.shutil.copyfile, src_file, dst_file)
-
-  def testRaisesIfDestIsADirectory(self):
-    src_file = 'xyzzy'
-    dst_dir = '/tmp/foo'
-    src_contents = 'contents of source file'
-    self.filesystem.CreateFile(src_file, contents=src_contents)
-    self.filesystem.CreateDirectory(dst_dir)
-    self.assertTrue(self.filesystem.Exists(src_file))
-    self.assertTrue(self.filesystem.Exists(dst_dir))
-    self.assertRaises(IOError, self.shutil.copyfile, src_file, dst_dir)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_test.py
deleted file mode 100644
index 54aa256..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_test.py
+++ /dev/null
@@ -1,2925 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unittest for fake_filesystem module."""
-
-import errno
-import os
-import re
-import stat
-import sys
-import time
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-
-import fake_filesystem
-
-
-def _GetDummyTime(start_time, increment):
-  def _DummyTime():
-    _DummyTime._curr_time += increment
-    return _DummyTime._curr_time
-  _DummyTime._curr_time = start_time - increment  # pylint: disable-msg=W0612
-  return _DummyTime
-
-
-class TestCase(unittest.TestCase):
-  is_windows = sys.platform.startswith('win')
-  is_cygwin = sys.platform == 'cygwin'
-
-  def assertModeEqual(self, expected, actual):
-    return self.assertEqual(stat.S_IMODE(expected), stat.S_IMODE(actual))
-
-
-class FakeDirectoryUnitTest(TestCase):
-  def setUp(self):
-    self.orig_time = time.time
-    time.time = _GetDummyTime(10, 1)
-    self.fake_file = fake_filesystem.FakeFile('foobar', contents='dummy_file')
-    self.fake_dir = fake_filesystem.FakeDirectory('somedir')
-
-  def tearDown(self):
-    time.time = self.orig_time
-
-  def testNewFileAndDirectory(self):
-    self.assertTrue(stat.S_IFREG & self.fake_file.st_mode)
-    self.assertTrue(stat.S_IFDIR & self.fake_dir.st_mode)
-    self.assertEqual({}, self.fake_dir.contents)
-    self.assertEqual(10, self.fake_file.st_ctime)
-
-  def testAddEntry(self):
-    self.fake_dir.AddEntry(self.fake_file)
-    self.assertEqual({'foobar': self.fake_file}, self.fake_dir.contents)
-
-  def testGetEntry(self):
-    self.fake_dir.AddEntry(self.fake_file)
-    self.assertEqual(self.fake_file, self.fake_dir.GetEntry('foobar'))
-
-  def testRemoveEntry(self):
-    self.fake_dir.AddEntry(self.fake_file)
-    self.assertEqual(self.fake_file, self.fake_dir.GetEntry('foobar'))
-    self.fake_dir.RemoveEntry('foobar')
-    self.assertRaises(KeyError, self.fake_dir.GetEntry, 'foobar')
-
-  def testShouldThrowIfSetSizeIsNotInteger(self):
-    self.assertRaises(IOError, self.fake_file.SetSize, 0.1)
-
-  def testShouldThrowIfSetSizeIsNegative(self):
-    self.assertRaises(IOError, self.fake_file.SetSize, -1)
-
-  def testProduceEmptyFileIfSetSizeIsZero(self):
-    self.fake_file.SetSize(0)
-    self.assertEqual('', self.fake_file.contents)
-
-  def testSetsContentEmptyIfSetSizeIsZero(self):
-    self.fake_file.SetSize(0)
-    self.assertEqual('', self.fake_file.contents)
-
-  def testTruncateFileIfSizeIsSmallerThanCurrentSize(self):
-    self.fake_file.SetSize(6)
-    self.assertEqual('dummy_', self.fake_file.contents)
-
-  def testLeaveFileUnchangedIfSizeIsEqualToCurrentSize(self):
-    self.fake_file.SetSize(10)
-    self.assertEqual('dummy_file', self.fake_file.contents)
-
-  def testPadsFileContentWithNullBytesIfSizeIsGreaterThanCurrentSize(self):
-    self.fake_file.SetSize(13)
-    self.assertEqual('dummy_file\0\0\0', self.fake_file.contents)
-
-  def testSetMTime(self):
-    self.assertEqual(10, self.fake_file.st_mtime)
-    self.fake_file.SetMTime(13)
-    self.assertEqual(13, self.fake_file.st_mtime)
-    self.fake_file.SetMTime(131)
-    self.assertEqual(131, self.fake_file.st_mtime)
-
-  def testFileInode(self):
-    filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    fake_os = fake_filesystem.FakeOsModule(filesystem)
-    file_path = 'some_file1'
-    filesystem.CreateFile(file_path, contents='contents here1', inode=42)
-    self.assertEqual(42, fake_os.stat(file_path)[stat.ST_INO])
-
-    file_obj = filesystem.GetObject(file_path)
-    file_obj.SetIno(43)
-    self.assertEqual(43, fake_os.stat(file_path)[stat.ST_INO])
-
-  def testDirectoryInode(self):
-    filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    fake_os = fake_filesystem.FakeOsModule(filesystem)
-    dirpath = 'testdir'
-    filesystem.CreateDirectory(dirpath, inode=42)
-    self.assertEqual(42, fake_os.stat(dirpath)[stat.ST_INO])
-
-    dir_obj = filesystem.GetObject(dirpath)
-    dir_obj.SetIno(43)
-    self.assertEqual(43, fake_os.stat(dirpath)[stat.ST_INO])
-
-
-class SetLargeFileSizeTest(FakeDirectoryUnitTest):
-
-  def testShouldThrowIfSizeIsNotInteger(self):
-    self.assertRaises(IOError, self.fake_file.SetLargeFileSize, 0.1)
-
-  def testShouldThrowIfSizeIsNegative(self):
-    self.assertRaises(IOError, self.fake_file.SetLargeFileSize, -1)
-
-  def testSetsContentNoneIfSizeIsNonNegativeInteger(self):
-    self.fake_file.SetLargeFileSize(1000000000)
-    self.assertEqual(None, self.fake_file.contents)
-    self.assertEqual(1000000000, self.fake_file.st_size)
-
-
-class NormalizePathTest(TestCase):
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.root_name = '/'
-
-  def testEmptyPathShouldGetNormalizedToRootPath(self):
-    self.assertEqual(self.root_name, self.filesystem.NormalizePath(''))
-
-  def testRootPathRemainsUnchanged(self):
-    self.assertEqual(self.root_name,
-                     self.filesystem.NormalizePath(self.root_name))
-
-  def testRelativePathForcedToCwd(self):
-    path = 'bar'
-    self.filesystem.cwd = '/foo'
-    self.assertEqual('/foo/bar', self.filesystem.NormalizePath(path))
-
-  def testAbsolutePathRemainsUnchanged(self):
-    path = '/foo/bar'
-    self.assertEqual(path, self.filesystem.NormalizePath(path))
-
-  def testDottedPathIsNormalized(self):
-    path = '/foo/..'
-    self.assertEqual('/', self.filesystem.NormalizePath(path))
-    path = 'foo/../bar'
-    self.assertEqual('/bar', self.filesystem.NormalizePath(path))
-
-  def testDotPathIsNormalized(self):
-    path = '.'
-    self.assertEqual('/', self.filesystem.NormalizePath(path))
-
-
-class GetPathComponentsTest(TestCase):
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.root_name = '/'
-
-  def testRootPathShouldReturnEmptyList(self):
-    self.assertEqual([], self.filesystem.GetPathComponents(self.root_name))
-
-  def testEmptyPathShouldReturnEmptyList(self):
-    self.assertEqual([], self.filesystem.GetPathComponents(''))
-
-  def testRelativePathWithOneComponentShouldReturnComponent(self):
-    self.assertEqual(['foo'], self.filesystem.GetPathComponents('foo'))
-
-  def testAbsolutePathWithOneComponentShouldReturnComponent(self):
-    self.assertEqual(['foo'], self.filesystem.GetPathComponents('/foo'))
-
-  def testTwoLevelRelativePathShouldReturnComponents(self):
-    self.assertEqual(['foo', 'bar'],
-                     self.filesystem.GetPathComponents('foo/bar'))
-
-  def testTwoLevelAbsolutePathShouldReturnComponents(self):
-    self.assertEqual(['foo', 'bar'],
-                     self.filesystem.GetPathComponents('/foo/bar'))
-
-
-class FakeFilesystemUnitTest(TestCase):
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.root_name = '/'
-    self.fake_file = fake_filesystem.FakeFile('foobar')
-    self.fake_child = fake_filesystem.FakeDirectory('foobaz')
-    self.fake_grandchild = fake_filesystem.FakeDirectory('quux')
-
-  def testNewFilesystem(self):
-    self.assertEqual('/', self.filesystem.path_separator)
-    self.assertTrue(stat.S_IFDIR & self.filesystem.root.st_mode)
-    self.assertEqual(self.root_name, self.filesystem.root.name)
-    self.assertEqual({}, self.filesystem.root.contents)
-
-  def testNoneRaisesTypeError(self):
-    self.assertRaises(TypeError, self.filesystem.Exists, None)
-
-  def testEmptyStringDoesNotExist(self):
-    self.assertFalse(self.filesystem.Exists(''))
-
-  def testExistsRoot(self):
-    self.assertTrue(self.filesystem.Exists(self.root_name))
-
-  def testExistsUnaddedFile(self):
-    self.assertFalse(self.filesystem.Exists(self.fake_file.name))
-
-  def testGetRootObject(self):
-    self.assertEqual(self.filesystem.root,
-                     self.filesystem.GetObject(self.root_name))
-
-  def testAddObjectToRoot(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.assertEqual({'foobar': self.fake_file}, self.filesystem.root.contents)
-
-  def testExistsAddedFile(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.assertTrue(self.filesystem.Exists(self.fake_file.name))
-
-  def testExistsRelativePath(self):
-    self.filesystem.CreateFile('/a/b/file_one')
-    self.filesystem.CreateFile('/a/c/file_two')
-    self.assertTrue(self.filesystem.Exists('a/b/../c/file_two'))
-    self.assertTrue(self.filesystem.Exists('/a/c/../b/file_one'))
-    self.assertTrue(self.filesystem.Exists('/a/c/../../a/b/file_one'))
-    self.assertFalse(self.filesystem.Exists('a/b/../z/d'))
-    self.assertFalse(self.filesystem.Exists('a/b/../z/../c/file_two'))
-    self.filesystem.cwd = '/a/c'
-    self.assertTrue(self.filesystem.Exists('../b/file_one'))
-    self.assertTrue(self.filesystem.Exists('../../a/b/file_one'))
-    self.assertTrue(self.filesystem.Exists('../../a/b/../../a/c/file_two'))
-    self.assertFalse(self.filesystem.Exists('../z/file_one'))
-    self.assertFalse(self.filesystem.Exists('../z/../c/file_two'))
-
-  def testGetObjectFromRoot(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.assertEqual(self.fake_file, self.filesystem.GetObject('foobar'))
-
-  def testGetNonexistentObjectFromRootError(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.assertEqual(self.fake_file, self.filesystem.GetObject('foobar'))
-    self.assertRaises(IOError, self.filesystem.GetObject,
-                      'some_bogus_filename')
-
-  def testRemoveObjectFromRoot(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.filesystem.RemoveObject(self.fake_file.name)
-    self.assertRaises(IOError, self.filesystem.GetObject, self.fake_file.name)
-
-  def testRemoveNonexistenObjectFromRootError(self):
-    self.assertRaises(IOError, self.filesystem.RemoveObject,
-                      'some_bogus_filename')
-
-  def testExistsRemovedFile(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.filesystem.RemoveObject(self.fake_file.name)
-    self.assertFalse(self.filesystem.Exists(self.fake_file.name))
-
-  def testAddObjectToChild(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_file)
-    self.assertEqual(
-        {self.fake_file.name: self.fake_file},
-        self.filesystem.root.GetEntry(self.fake_child.name).contents)
-
-  def testAddObjectToRegularFileError(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.assertRaises(IOError, self.filesystem.AddObject,
-                      self.fake_file.name, self.fake_file)
-
-  def testExistsFileAddedToChild(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_file)
-    path = self.filesystem.JoinPaths(self.fake_child.name,
-                                     self.fake_file.name)
-    self.assertTrue(self.filesystem.Exists(path))
-
-  def testGetObjectFromChild(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_file)
-    self.assertEqual(self.fake_file,
-                     self.filesystem.GetObject(
-                         self.filesystem.JoinPaths(self.fake_child.name,
-                                                   self.fake_file.name)))
-
-  def testGetNonexistentObjectFromChildError(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_file)
-    self.assertRaises(IOError, self.filesystem.GetObject,
-                      self.filesystem.JoinPaths(self.fake_child.name,
-                                                'some_bogus_filename'))
-
-  def testRemoveObjectFromChild(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_file)
-    target_path = self.filesystem.JoinPaths(self.fake_child.name,
-                                            self.fake_file.name)
-    self.filesystem.RemoveObject(target_path)
-    self.assertRaises(IOError, self.filesystem.GetObject, target_path)
-
-  def testRemoveObjectFromChildError(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.assertRaises(IOError, self.filesystem.RemoveObject,
-                      self.filesystem.JoinPaths(self.fake_child.name,
-                                                'some_bogus_filename'))
-
-  def testRemoveObjectFromNonDirectoryError(self):
-    self.filesystem.AddObject(self.root_name, self.fake_file)
-    self.assertRaises(
-        IOError, self.filesystem.RemoveObject,
-        self.filesystem.JoinPaths(
-            '%s' % self.fake_file.name,
-            'file_does_not_matter_since_parent_not_a_directory'))
-
-  def testExistsFileRemovedFromChild(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_file)
-    path = self.filesystem.JoinPaths(self.fake_child.name,
-                                     self.fake_file.name)
-    self.filesystem.RemoveObject(path)
-    self.assertFalse(self.filesystem.Exists(path))
-
-  def testOperateOnGrandchildDirectory(self):
-    self.filesystem.AddObject(self.root_name, self.fake_child)
-    self.filesystem.AddObject(self.fake_child.name, self.fake_grandchild)
-    grandchild_directory = self.filesystem.JoinPaths(self.fake_child.name,
-                                                     self.fake_grandchild.name)
-    grandchild_file = self.filesystem.JoinPaths(grandchild_directory,
-                                                self.fake_file.name)
-    self.assertRaises(IOError, self.filesystem.GetObject, grandchild_file)
-    self.filesystem.AddObject(grandchild_directory, self.fake_file)
-    self.assertEqual(self.fake_file,
-                     self.filesystem.GetObject(grandchild_file))
-    self.assertTrue(self.filesystem.Exists(grandchild_file))
-    self.filesystem.RemoveObject(grandchild_file)
-    self.assertRaises(IOError, self.filesystem.GetObject, grandchild_file)
-    self.assertFalse(self.filesystem.Exists(grandchild_file))
-
-  def testCreateDirectoryInRootDirectory(self):
-    path = 'foo'
-    self.filesystem.CreateDirectory(path)
-    new_dir = self.filesystem.GetObject(path)
-    self.assertEqual(os.path.basename(path), new_dir.name)
-    self.assertTrue(stat.S_IFDIR & new_dir.st_mode)
-
-  def testCreateDirectoryInRootDirectoryAlreadyExistsError(self):
-    path = 'foo'
-    self.filesystem.CreateDirectory(path)
-    self.assertRaises(OSError, self.filesystem.CreateDirectory, path)
-
-  def testCreateDirectory(self):
-    path = 'foo/bar/baz'
-    self.filesystem.CreateDirectory(path)
-    new_dir = self.filesystem.GetObject(path)
-    self.assertEqual(os.path.basename(path), new_dir.name)
-    self.assertTrue(stat.S_IFDIR & new_dir.st_mode)
-
-    # Create second directory to make sure first is OK.
-    path = '%s/quux' % path
-    self.filesystem.CreateDirectory(path)
-    new_dir = self.filesystem.GetObject(path)
-    self.assertEqual(os.path.basename(path), new_dir.name)
-    self.assertTrue(stat.S_IFDIR & new_dir.st_mode)
-
-  def testCreateDirectoryAlreadyExistsError(self):
-    path = 'foo/bar/baz'
-    self.filesystem.CreateDirectory(path)
-    self.assertRaises(OSError, self.filesystem.CreateDirectory, path)
-
-  def testCreateFileInCurrentDirectory(self):
-    path = 'foo'
-    contents = 'dummy data'
-    self.filesystem.CreateFile(path, contents=contents)
-    self.assertTrue(self.filesystem.Exists(path))
-    self.assertFalse(self.filesystem.Exists(os.path.dirname(path)))
-    path = './%s' % path
-    self.assertTrue(self.filesystem.Exists(os.path.dirname(path)))
-
-  def testCreateFileInRootDirectory(self):
-    path = '/foo'
-    contents = 'dummy data'
-    self.filesystem.CreateFile(path, contents=contents)
-    new_file = self.filesystem.GetObject(path)
-    self.assertTrue(self.filesystem.Exists(path))
-    self.assertTrue(self.filesystem.Exists(os.path.dirname(path)))
-    self.assertEqual(os.path.basename(path), new_file.name)
-    self.assertTrue(stat.S_IFREG & new_file.st_mode)
-    self.assertEqual(contents, new_file.contents)
-
-  def testCreateFileWithSizeButNoContentCreatesLargeFile(self):
-    path = 'large_foo_bar'
-    self.filesystem.CreateFile(path, st_size=100000000)
-    new_file = self.filesystem.GetObject(path)
-    self.assertEqual(None, new_file.contents)
-    self.assertEqual(100000000, new_file.st_size)
-
-  def testCreateFileInRootDirectoryAlreadyExistsError(self):
-    path = 'foo'
-    self.filesystem.CreateFile(path)
-    self.assertRaises(IOError, self.filesystem.CreateFile, path)
-
-  def testCreateFile(self):
-    path = 'foo/bar/baz'
-    retval = self.filesystem.CreateFile(path, contents='dummy_data')
-    self.assertTrue(self.filesystem.Exists(path))
-    self.assertTrue(self.filesystem.Exists(os.path.dirname(path)))
-    new_file = self.filesystem.GetObject(path)
-    self.assertEqual(os.path.basename(path), new_file.name)
-    self.assertTrue(stat.S_IFREG & new_file.st_mode)
-    self.assertEqual(new_file, retval)
-
-  def testCreateFileAlreadyExistsError(self):
-    path = 'foo/bar/baz'
-    self.filesystem.CreateFile(path, contents='dummy_data')
-    self.assertRaises(IOError, self.filesystem.CreateFile, path)
-
-  def testCreateLink(self):
-    path = 'foo/bar/baz'
-    target_path = 'foo/bar/quux'
-    new_file = self.filesystem.CreateLink(path, 'quux')
-    # Neither the path not the final target exists before we actually write to
-    # one of them, even though the link appears in the file system.
-    self.assertFalse(self.filesystem.Exists(path))
-    self.assertFalse(self.filesystem.Exists(target_path))
-    self.assertTrue(stat.S_IFLNK & new_file.st_mode)
-
-    # but once we write the linked to file, they both will exist.
-    self.filesystem.CreateFile(target_path)
-    self.assertTrue(self.filesystem.Exists(path))
-    self.assertTrue(self.filesystem.Exists(target_path))
-
-  def testResolveObject(self):
-    target_path = 'dir/target'
-    target_contents = '0123456789ABCDEF'
-    link_name = 'x'
-    self.filesystem.CreateDirectory('dir')
-    self.filesystem.CreateFile('dir/target', contents=target_contents)
-    self.filesystem.CreateLink(link_name, target_path)
-    obj = self.filesystem.ResolveObject(link_name)
-    self.assertEqual('target', obj.name)
-    self.assertEqual(target_contents, obj.contents)
-
-  def testLresolveObject(self):
-    target_path = 'dir/target'
-    target_contents = '0123456789ABCDEF'
-    link_name = 'x'
-    self.filesystem.CreateDirectory('dir')
-    self.filesystem.CreateFile('dir/target', contents=target_contents)
-    self.filesystem.CreateLink(link_name, target_path)
-    obj = self.filesystem.LResolveObject(link_name)
-    self.assertEqual(link_name, obj.name)
-    self.assertEqual(target_path, obj.contents)
-
-  def testDirectoryAccessOnFile(self):
-    self.filesystem.CreateFile('not_a_dir')
-    self.assertRaises(IOError, self.filesystem.ResolveObject, 'not_a_dir/foo')
-    self.assertRaises(IOError, self.filesystem.ResolveObject,
-                      'not_a_dir/foo/bar')
-    self.assertRaises(IOError, self.filesystem.LResolveObject, 'not_a_dir/foo')
-    self.assertRaises(IOError, self.filesystem.LResolveObject,
-                      'not_a_dir/foo/bar')
-
-
-class FakeOsModuleTest(TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-    self.rwx = self.os.R_OK | self.os.W_OK | self.os.X_OK
-    self.rw = self.os.R_OK | self.os.W_OK
-    self.orig_time = time.time
-    time.time = _GetDummyTime(200, 20)
-
-  def tearDown(self):
-    time.time = self.orig_time
-
-  def assertRaisesWithRegexpMatch(self, expected_exception, expected_regexp,
-                                  callable_obj, *args, **kwargs):
-    """Asserts that the message in a raised exception matches the given regexp.
-
-    Args:
-      expected_exception: Exception class expected to be raised.
-      expected_regexp: Regexp (re pattern object or string) expected to be
-        found in error message.
-      callable_obj: Function to be called.
-      *args: Extra args.
-      **kwargs: Extra kwargs.
-    """
-    try:
-      callable_obj(*args, **kwargs)
-    except expected_exception as err:
-      if isinstance(expected_regexp, str):
-        expected_regexp = re.compile(expected_regexp)
-      self.assertTrue(
-          expected_regexp.search(str(err)),
-          '"%s" does not match "%s"' % (expected_regexp.pattern, str(err)))
-    else:
-      self.fail(expected_exception.__name__ + ' not raised')
-
-  def testChdir(self):
-    """chdir should work on a directory."""
-    directory = '/foo'
-    self.filesystem.CreateDirectory(directory)
-    self.os.chdir(directory)
-
-  def testChdirFailsNonExist(self):
-    """chdir should raise OSError if the target does not exist."""
-    directory = '/no/such/directory'
-    self.assertRaises(OSError, self.os.chdir, directory)
-
-  def testChdirFailsNonDirectory(self):
-    """chdir should raies OSError if the target is not a directory."""
-    filename = '/foo/bar'
-    self.filesystem.CreateFile(filename)
-    self.assertRaises(OSError, self.os.chdir, filename)
-
-  def testConsecutiveChdir(self):
-    """Consecutive relative chdir calls should work."""
-    dir1 = 'foo'
-    dir2 = 'bar'
-    full_dirname = self.os.path.join(dir1, dir2)
-    self.filesystem.CreateDirectory(full_dirname)
-    self.os.chdir(dir1)
-    self.os.chdir(dir2)
-    self.assertEqual(self.os.getcwd(), self.os.path.sep + full_dirname)
-
-  def testBackwardsChdir(self):
-    """chdir into '..' should behave appropriately."""
-    rootdir = self.os.getcwd()
-    dirname = 'foo'
-    abs_dirname = self.os.path.abspath(dirname)
-    self.filesystem.CreateDirectory(dirname)
-    self.os.chdir(dirname)
-    self.assertEqual(abs_dirname, self.os.getcwd())
-    self.os.chdir('..')
-    self.assertEqual(rootdir, self.os.getcwd())
-    self.os.chdir(self.os.path.join(dirname, '..'))
-    self.assertEqual(rootdir, self.os.getcwd())
-
-  def testGetCwd(self):
-    dirname = '/foo/bar'
-    self.filesystem.CreateDirectory(dirname)
-    self.assertEqual(self.os.getcwd(), self.os.path.sep)
-    self.os.chdir(dirname)
-    self.assertEqual(self.os.getcwd(), dirname)
-
-  def testListdir(self):
-    directory = 'xyzzy/plugh'
-    files = ['foo', 'bar', 'baz']
-    for f in files:
-      self.filesystem.CreateFile('%s/%s' % (directory, f))
-    files.sort()
-    self.assertEqual(files, self.os.listdir(directory))
-
-  def testListdirOnSymlink(self):
-    directory = 'xyzzy'
-    files = ['foo', 'bar', 'baz']
-    for f in files:
-      self.filesystem.CreateFile('%s/%s' % (directory, f))
-    self.filesystem.CreateLink('symlink', 'xyzzy')
-    files.sort()
-    self.assertEqual(files, self.os.listdir('symlink'))
-
-  def testListdirError(self):
-    file_path = 'foo/bar/baz'
-    self.filesystem.CreateFile(file_path)
-    self.assertRaises(OSError, self.os.listdir, file_path)
-
-  def testExistsCurrentDir(self):
-    self.assertTrue(self.filesystem.Exists('.'))
-
-  def testListdirCurrent(self):
-    files = ['foo', 'bar', 'baz']
-    for f in files:
-      self.filesystem.CreateFile('%s' % f)
-    files.sort()
-    self.assertEqual(files, self.os.listdir('.'))
-
-  def testFdopen(self):
-    fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
-    file_path1 = 'some_file1'
-    self.filesystem.CreateFile(file_path1, contents='contents here1')
-    fake_file1 = fake_open(file_path1, 'r')
-    self.assertEqual(0, fake_file1.fileno())
-
-    self.assertFalse(self.os.fdopen(0) is fake_file1)
-
-    self.assertRaises(TypeError, self.os.fdopen, None)
-    self.assertRaises(TypeError, self.os.fdopen, 'a string')
-
-  def testOutOfRangeFdopen(self):
-    # We haven't created any files, so even 0 is out of range.
-    self.assertRaises(OSError, self.os.fdopen, 0)
-
-  def testClosedFileDescriptor(self):
-    fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
-    first_path = 'some_file1'
-    second_path = 'some_file2'
-    third_path = 'some_file3'
-    self.filesystem.CreateFile(first_path, contents='contents here1')
-    self.filesystem.CreateFile(second_path, contents='contents here2')
-    self.filesystem.CreateFile(third_path, contents='contents here3')
-
-    fake_file1 = fake_open(first_path, 'r')
-    fake_file2 = fake_open(second_path, 'r')
-    fake_file3 = fake_open(third_path, 'r')
-    self.assertEqual(0, fake_file1.fileno())
-    self.assertEqual(1, fake_file2.fileno())
-    self.assertEqual(2, fake_file3.fileno())
-
-    fileno2 = fake_file2.fileno()
-    self.os.close(fileno2)
-    self.assertRaises(OSError, self.os.close, fileno2)
-    self.assertEqual(0, fake_file1.fileno())
-    self.assertEqual(2, fake_file3.fileno())
-
-    self.assertFalse(self.os.fdopen(0) is fake_file1)
-    self.assertFalse(self.os.fdopen(2) is fake_file3)
-    self.assertRaises(OSError, self.os.fdopen, 1)
-
-  def testFdopenMode(self):
-    fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
-    file_path1 = 'some_file1'
-    self.filesystem.CreateFile(file_path1, contents='contents here1',
-                               st_mode=((stat.S_IFREG | 0o666) ^ stat.S_IWRITE))
-
-    fake_file1 = fake_open(file_path1, 'r')
-    self.assertEqual(0, fake_file1.fileno())
-    self.os.fdopen(0)
-    self.os.fdopen(0, mode='r')
-    exception = OSError if sys.version_info < (3, 0) else IOError
-    self.assertRaises(exception, self.os.fdopen, 0, 'w')
-
-  def testLowLevelOpenCreate(self):
-    file_path = 'file1'
-    # this is the low-level open, not FakeFileOpen
-    fileno = self.os.open(file_path, self.os.O_CREAT)
-    self.assertEqual(0, fileno)
-    self.assertTrue(self.os.path.exists(file_path))
-
-  def testLowLevelOpenCreateMode(self):
-    file_path = 'file1'
-    fileno = self.os.open(file_path, self.os.O_CREAT, 0o700)
-    self.assertEqual(0, fileno)
-    self.assertTrue(self.os.path.exists(file_path))
-    self.assertModeEqual(0o700, self.os.stat(file_path).st_mode)
-
-  def testLowLevelOpenCreateModeUnsupported(self):
-    file_path = 'file1'
-    fake_flag = 0b100000000000000000000000
-    self.assertRaises(NotImplementedError, self.os.open, file_path, fake_flag)
-
-  def testLowLevelWriteRead(self):
-    file_path = 'file1'
-    self.filesystem.CreateFile(file_path, contents='orig contents')
-    new_contents = '1234567890abcdef'
-    fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
-
-    fh = fake_open(file_path, 'w')
-    fileno = fh.fileno()
-
-    self.assertEqual(len(new_contents), self.os.write(fileno, new_contents))
-    self.assertEqual(new_contents,
-                     self.filesystem.GetObject(file_path).contents)
-    self.os.close(fileno)
-
-    fh = fake_open(file_path, 'r')
-    fileno = fh.fileno()
-    self.assertEqual('', self.os.read(fileno, 0))
-    self.assertEqual(new_contents[0:2], self.os.read(fileno, 2))
-    self.assertEqual(new_contents[2:10], self.os.read(fileno, 8))
-    self.assertEqual(new_contents[10:], self.os.read(fileno, 100))
-    self.assertEqual('', self.os.read(fileno, 10))
-    self.os.close(fileno)
-
-    self.assertRaises(OSError, self.os.write, fileno, new_contents)
-    self.assertRaises(OSError, self.os.read, fileno, 10)
-
-  def testFstat(self):
-    directory = 'xyzzy'
-    file_path = '%s/plugh' % directory
-    self.filesystem.CreateFile(file_path, contents='ABCDE')
-    fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
-    file_obj = fake_open(file_path)
-    fileno = file_obj.fileno()
-    self.assertTrue(stat.S_IFREG & self.os.fstat(fileno)[stat.ST_MODE])
-    self.assertTrue(stat.S_IFREG & self.os.fstat(fileno).st_mode)
-    self.assertEqual(5, self.os.fstat(fileno)[stat.ST_SIZE])
-
-  def testStat(self):
-    directory = 'xyzzy'
-    file_path = '%s/plugh' % directory
-    self.filesystem.CreateFile(file_path, contents='ABCDE')
-    self.assertTrue(stat.S_IFDIR & self.os.stat(directory)[stat.ST_MODE])
-    self.assertTrue(stat.S_IFREG & self.os.stat(file_path)[stat.ST_MODE])
-    self.assertTrue(stat.S_IFREG & self.os.stat(file_path).st_mode)
-    self.assertEqual(5, self.os.stat(file_path)[stat.ST_SIZE])
-
-  def testLstat(self):
-    directory = 'xyzzy'
-    base_name = 'plugh'
-    file_contents = 'frobozz'
-    # Just make sure we didn't accidentally make our test data meaningless.
-    self.assertNotEqual(len(base_name), len(file_contents))
-    file_path = '%s/%s' % (directory, base_name)
-    link_path = '%s/link' % directory
-    self.filesystem.CreateFile(file_path, contents=file_contents)
-    self.filesystem.CreateLink(link_path, base_name)
-    self.assertEqual(len(file_contents), self.os.lstat(file_path)[stat.ST_SIZE])
-    self.assertEqual(len(base_name), self.os.lstat(link_path)[stat.ST_SIZE])
-
-  def testStatNonExistentFile(self):
-    # set up
-    file_path = '/non/existent/file'
-    self.assertFalse(self.filesystem.Exists(file_path))
-    # actual tests
-    try:
-      # Use try-catch to check exception attributes.
-      self.os.stat(file_path)
-      self.fail('Exception is expected.')  # COV_NF_LINE
-    except OSError as os_error:
-      self.assertEqual(errno.ENOENT, os_error.errno)
-      self.assertEqual(file_path, os_error.filename)
-
-  def testReadlink(self):
-    link_path = 'foo/bar/baz'
-    target = 'tarJAY'
-    self.filesystem.CreateLink(link_path, target)
-    self.assertEqual(self.os.readlink(link_path), target)
-
-  def testReadlinkRaisesIfPathIsNotALink(self):
-    file_path = 'foo/bar/eleventyone'
-    self.filesystem.CreateFile(file_path)
-    self.assertRaises(OSError, self.os.readlink, file_path)
-
-  def testReadlinkRaisesIfPathDoesNotExist(self):
-    self.assertRaises(OSError, self.os.readlink, '/this/path/does/not/exist')
-
-  def testReadlinkRaisesIfPathIsNone(self):
-    self.assertRaises(TypeError, self.os.readlink, None)
-
-  def testReadlinkWithLinksInPath(self):
-    self.filesystem.CreateLink('/meyer/lemon/pie', 'yum')
-    self.filesystem.CreateLink('/geo/metro', '/meyer')
-    self.assertEqual('yum', self.os.readlink('/geo/metro/lemon/pie'))
-
-  def testReadlinkWithChainedLinksInPath(self):
-    self.filesystem.CreateLink('/eastern/european/wolfhounds/chase', 'cats')
-    self.filesystem.CreateLink('/russian', '/eastern/european')
-    self.filesystem.CreateLink('/dogs', '/russian/wolfhounds')
-    self.assertEqual('cats', self.os.readlink('/dogs/chase'))
-
-  def testRemoveDir(self):
-    directory = 'xyzzy'
-    dir_path = '/%s/plugh' % directory
-    self.filesystem.CreateDirectory(dir_path)
-    self.assertTrue(self.filesystem.Exists(dir_path))
-    self.assertRaises(OSError, self.os.remove, dir_path)
-    self.assertTrue(self.filesystem.Exists(dir_path))
-    self.os.chdir(directory)
-    self.assertRaises(OSError, self.os.remove, 'plugh')
-    self.assertTrue(self.filesystem.Exists(dir_path))
-    self.assertRaises(OSError, self.os.remove, '/plugh')
-
-  def testRemoveFile(self):
-    directory = 'zzy'
-    file_path = '%s/plugh' % directory
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.os.remove(file_path)
-    self.assertFalse(self.filesystem.Exists(file_path))
-
-  def testRemoveFileNoDirectory(self):
-    directory = 'zzy'
-    file_name = 'plugh'
-    file_path = '%s/%s' % (directory, file_name)
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.os.chdir(directory)
-    self.os.remove(file_name)
-    self.assertFalse(self.filesystem.Exists(file_path))
-
-  def testRemoveFileRelativePath(self):
-    original_dir = self.os.getcwd()
-    directory = 'zzy'
-    subdirectory = self.os.path.join(directory, directory)
-    file_name = 'plugh'
-    file_path = '%s/%s' % (directory, file_name)
-    file_path_relative = self.os.path.join('..', file_name)
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.filesystem.CreateDirectory(subdirectory)
-    self.assertTrue(self.filesystem.Exists(subdirectory))
-    self.os.chdir(subdirectory)
-    self.os.remove(file_path_relative)
-    self.assertFalse(self.filesystem.Exists(file_path_relative))
-    self.os.chdir(original_dir)
-    self.assertFalse(self.filesystem.Exists(file_path))
-
-  def testRemoveDirRaisesError(self):
-    directory = 'zzy'
-    self.filesystem.CreateDirectory(directory)
-    self.assertRaises(OSError,
-                      self.os.remove,
-                      directory)
-
-  def testRemoveSymlinkToDir(self):
-    directory = 'zzy'
-    link = 'link_to_dir'
-    self.filesystem.CreateDirectory(directory)
-    self.os.symlink(directory, link)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.assertTrue(self.filesystem.Exists(link))
-    self.os.remove(link)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.assertFalse(self.filesystem.Exists(link))
-
-  def testUnlink(self):
-    self.assertTrue(self.os.unlink == self.os.remove)
-
-  def testUnlinkRaisesIfNotExist(self):
-    file_path = '/file/does/not/exist'
-    self.assertFalse(self.filesystem.Exists(file_path))
-    self.assertRaises(OSError, self.os.unlink, file_path)
-
-  def testRenameToNonexistentFile(self):
-    """Can rename a file to an unused name."""
-    directory = 'xyzzy'
-    old_file_path = '%s/plugh_old' % directory
-    new_file_path = '%s/plugh_new' % directory
-    self.filesystem.CreateFile(old_file_path, contents='test contents')
-    self.assertTrue(self.filesystem.Exists(old_file_path))
-    self.assertFalse(self.filesystem.Exists(new_file_path))
-    self.os.rename(old_file_path, new_file_path)
-    self.assertFalse(self.filesystem.Exists(old_file_path))
-    self.assertTrue(self.filesystem.Exists(new_file_path))
-    self.assertEqual('test contents',
-                     self.filesystem.GetObject(new_file_path).contents)
-
-  def testRenameDirectory(self):
-    """Can rename a directory to an unused name."""
-    for old_path, new_path in [('wxyyw', 'xyzzy'), ('/abccb', 'cdeed')]:
-      self.filesystem.CreateFile('%s/plugh' % old_path, contents='test')
-      self.assertTrue(self.filesystem.Exists(old_path))
-      self.assertFalse(self.filesystem.Exists(new_path))
-      self.os.rename(old_path, new_path)
-      self.assertFalse(self.filesystem.Exists(old_path))
-      self.assertTrue(self.filesystem.Exists(new_path))
-      self.assertEqual(
-          'test', self.filesystem.GetObject('%s/plugh' % new_path).contents)
-
-  def testRenameToExistentFile(self):
-    """Can rename a file to a used name."""
-    directory = 'xyzzy'
-    old_file_path = '%s/plugh_old' % directory
-    new_file_path = '%s/plugh_new' % directory
-    self.filesystem.CreateFile(old_file_path, contents='test contents 1')
-    self.filesystem.CreateFile(new_file_path, contents='test contents 2')
-    self.assertTrue(self.filesystem.Exists(old_file_path))
-    self.assertTrue(self.filesystem.Exists(new_file_path))
-    self.os.rename(old_file_path, new_file_path)
-    self.assertFalse(self.filesystem.Exists(old_file_path))
-    self.assertTrue(self.filesystem.Exists(new_file_path))
-    self.assertEqual('test contents 1',
-                     self.filesystem.GetObject(new_file_path).contents)
-
-  def testRenameToNonexistentDir(self):
-    """Can rename a file to a name in a nonexistent dir."""
-    directory = 'xyzzy'
-    old_file_path = '%s/plugh_old' % directory
-    new_file_path = '%s/no_such_path/plugh_new' % directory
-    self.filesystem.CreateFile(old_file_path, contents='test contents')
-    self.assertTrue(self.filesystem.Exists(old_file_path))
-    self.assertFalse(self.filesystem.Exists(new_file_path))
-    self.assertRaises(IOError, self.os.rename, old_file_path, new_file_path)
-    self.assertTrue(self.filesystem.Exists(old_file_path))
-    self.assertFalse(self.filesystem.Exists(new_file_path))
-    self.assertEqual('test contents',
-                     self.filesystem.GetObject(old_file_path).contents)
-
-  def testRenameNonexistentFileShouldRaiseError(self):
-    """Can't rename a file that doesn't exist."""
-    self.assertRaises(OSError,
-                      self.os.rename,
-                      'nonexistent-foo',
-                      'doesn\'t-matter-bar')
-
-  def testRenameEmptyDir(self):
-    """Test a rename of an empty directory."""
-    directory = 'xyzzy'
-    before_dir = '%s/empty' % directory
-    after_dir = '%s/unused' % directory
-    self.filesystem.CreateDirectory(before_dir)
-    self.assertTrue(self.filesystem.Exists('%s/.' % before_dir))
-    self.assertFalse(self.filesystem.Exists(after_dir))
-    self.os.rename(before_dir, after_dir)
-    self.assertFalse(self.filesystem.Exists(before_dir))
-    self.assertTrue(self.filesystem.Exists('%s/.' % after_dir))
-
-  def testRenameDir(self):
-    """Test a rename of a directory."""
-    directory = 'xyzzy'
-    before_dir = '%s/before' % directory
-    before_file = '%s/before/file' % directory
-    after_dir = '%s/after' % directory
-    after_file = '%s/after/file' % directory
-    self.filesystem.CreateDirectory(before_dir)
-    self.filesystem.CreateFile(before_file, contents='payload')
-    self.assertTrue(self.filesystem.Exists(before_dir))
-    self.assertTrue(self.filesystem.Exists(before_file))
-    self.assertFalse(self.filesystem.Exists(after_dir))
-    self.assertFalse(self.filesystem.Exists(after_file))
-    self.os.rename(before_dir, after_dir)
-    self.assertFalse(self.filesystem.Exists(before_dir))
-    self.assertFalse(self.filesystem.Exists(before_file))
-    self.assertTrue(self.filesystem.Exists(after_dir))
-    self.assertTrue(self.filesystem.Exists(after_file))
-    self.assertEqual('payload',
-                     self.filesystem.GetObject(after_file).contents)
-
-  def testRenamePreservesStat(self):
-    """Test if rename preserves mtime."""
-    directory = 'xyzzy'
-    old_file_path = '%s/plugh_old' % directory
-    new_file_path = '%s/plugh_new' % directory
-    old_file = self.filesystem.CreateFile(old_file_path)
-    old_file.SetMTime(old_file.st_mtime - 3600)
-    self.os.chown(old_file_path, 200, 200)
-    self.os.chmod(old_file_path, 0o222)
-    new_file = self.filesystem.CreateFile(new_file_path)
-    self.assertNotEqual(new_file.st_mtime, old_file.st_mtime)
-    self.os.rename(old_file_path, new_file_path)
-    new_file = self.filesystem.GetObject(new_file_path)
-    self.assertEqual(new_file.st_mtime, old_file.st_mtime)
-    self.assertEqual(new_file.st_mode, old_file.st_mode)
-    self.assertEqual(new_file.st_uid, old_file.st_uid)
-    self.assertEqual(new_file.st_gid, old_file.st_gid)
-
-  def testRenameSameFilenames(self):
-    """Test renaming when old and new names are the same."""
-    directory = 'xyzzy'
-    file_contents = 'Spam eggs'
-    file_path = '%s/eggs' % directory
-    self.filesystem.CreateFile(file_path, contents=file_contents)
-    self.os.rename(file_path, file_path)
-    self.assertEqual(file_contents,
-                     self.filesystem.GetObject(file_path).contents)
-
-  def testRmdir(self):
-    """Can remove a directory."""
-    directory = 'xyzzy'
-    sub_dir = '/xyzzy/abccd'
-    other_dir = '/xyzzy/cdeed'
-    self.filesystem.CreateDirectory(directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.os.rmdir(directory)
-    self.assertFalse(self.filesystem.Exists(directory))
-    self.filesystem.CreateDirectory(sub_dir)
-    self.filesystem.CreateDirectory(other_dir)
-    self.os.chdir(sub_dir)
-    self.os.rmdir('../cdeed')
-    self.assertFalse(self.filesystem.Exists(other_dir))
-    self.os.chdir('..')
-    self.os.rmdir('abccd')
-    self.assertFalse(self.filesystem.Exists(sub_dir))
-
-  def testRmdirRaisesIfNotEmpty(self):
-    """Raises an exception if the target directory is not empty."""
-    directory = 'xyzzy'
-    file_path = '%s/plugh' % directory
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.assertRaises(OSError, self.os.rmdir, directory)
-
-  def testRmdirRaisesIfNotDirectory(self):
-    """Raises an exception if the target is not a directory."""
-    directory = 'xyzzy'
-    file_path = '%s/plugh' % directory
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.assertRaises(OSError, self.os.rmdir, file_path)
-    self.assertRaises(OSError, self.os.rmdir, '.')
-
-  def testRmdirRaisesIfNotExist(self):
-    """Raises an exception if the target does not exist."""
-    directory = 'xyzzy'
-    self.assertFalse(self.filesystem.Exists(directory))
-    self.assertRaises(OSError, self.os.rmdir, directory)
-
-  def RemovedirsCheck(self, directory):
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.os.removedirs(directory)
-    return not self.filesystem.Exists(directory)
-
-  def testRemovedirs(self):
-    data = ['test1', 'test1/test2', 'test1/extra', 'test1/test2/test3']
-    for directory in data:
-      self.filesystem.CreateDirectory(directory)
-      self.assertTrue(self.filesystem.Exists(directory))
-    self.assertRaises(OSError, self.RemovedirsCheck, data[0])
-    self.assertRaises(OSError, self.RemovedirsCheck, data[1])
-
-    self.assertTrue(self.RemovedirsCheck(data[3]))
-    self.assertTrue(self.filesystem.Exists(data[0]))
-    self.assertFalse(self.filesystem.Exists(data[1]))
-    self.assertTrue(self.filesystem.Exists(data[2]))
-
-    # Should raise because '/test1/extra' is all that is left, and
-    # removedirs('/test1/extra') will eventually try to rmdir('/').
-    self.assertRaises(OSError, self.RemovedirsCheck, data[2])
-
-    # However, it will still delete '/test1') in the process.
-    self.assertFalse(self.filesystem.Exists(data[0]))
-
-    self.filesystem.CreateDirectory('test1/test2')
-    # Add this to the root directory to avoid raising an exception.
-    self.filesystem.CreateDirectory('test3')
-    self.assertTrue(self.RemovedirsCheck('test1/test2'))
-    self.assertFalse(self.filesystem.Exists('test1/test2'))
-    self.assertFalse(self.filesystem.Exists('test1'))
-
-  def testRemovedirsRaisesIfRemovingRoot(self):
-    """Raises exception if asked to remove '/'."""
-    directory = '/'
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.assertRaises(OSError, self.os.removedirs, directory)
-
-  def testRemovedirsRaisesIfCascadeRemovingRoot(self):
-    """Raises exception if asked to remove '/' as part of a larger operation.
-
-    All of other directories should still be removed, though.
-    """
-    directory = '/foo/bar/'
-    self.filesystem.CreateDirectory(directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.assertRaises(OSError, self.os.removedirs, directory)
-    head, unused_tail = self.os.path.split(directory)
-    while head != '/':
-      self.assertFalse(self.filesystem.Exists(directory))
-      head, unused_tail = self.os.path.split(head)
-
-  def testRemovedirsWithTrailingSlash(self):
-    """removedirs works on directory names with trailing slashes."""
-    # separate this case from the removing-root-directory case
-    self.filesystem.CreateDirectory('/baz')
-    directory = '/foo/bar/'
-    self.filesystem.CreateDirectory(directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.os.removedirs(directory)
-    self.assertFalse(self.filesystem.Exists(directory))
-
-  def testMkdir(self):
-    """mkdir can create a relative directory."""
-    directory = 'xyzzy'
-    self.assertFalse(self.filesystem.Exists(directory))
-    self.os.mkdir(directory)
-    self.assertTrue(self.filesystem.Exists('/%s' % directory))
-    self.os.chdir(directory)
-    self.os.mkdir(directory)
-    self.assertTrue(self.filesystem.Exists('/%s/%s' % (directory, directory)))
-    self.os.chdir(directory)
-    self.os.mkdir('../abccb')
-    self.assertTrue(self.filesystem.Exists('/%s/abccb' % directory))
-
-  def testMkdirWithTrailingSlash(self):
-    """mkdir can create a directory named with a trailing slash."""
-    directory = '/foo/'
-    self.assertFalse(self.filesystem.Exists(directory))
-    self.os.mkdir(directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.assertTrue(self.filesystem.Exists('/foo'))
-
-  def testMkdirRaisesIfEmptyDirectoryName(self):
-    """mkdir raises exeption if creating directory named ''."""
-    directory = ''
-    self.assertRaises(OSError, self.os.mkdir, directory)
-
-  def testMkdirRaisesIfNoParent(self):
-    """mkdir raises exception if parent directory does not exist."""
-    parent = 'xyzzy'
-    directory = '%s/foo' % (parent,)
-    self.assertFalse(self.filesystem.Exists(parent))
-    self.assertRaises(Exception, self.os.mkdir, directory)
-
-  def testMkdirRaisesIfDirectoryExists(self):
-    """mkdir raises exception if directory already exists."""
-    directory = 'xyzzy'
-    self.filesystem.CreateDirectory(directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    self.assertRaises(Exception, self.os.mkdir, directory)
-
-  def testMkdirRaisesIfFileExists(self):
-    """mkdir raises exception if name already exists as a file."""
-    directory = 'xyzzy'
-    file_path = '%s/plugh' % directory
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.assertRaises(Exception, self.os.mkdir, file_path)
-
-  def testMkdirRaisesWithSlashDot(self):
-    """mkdir raises exception if mkdir foo/. (trailing /.)."""
-    self.assertRaises(Exception, self.os.mkdir, '/.')
-    directory = '/xyzzy/.'
-    self.assertRaises(Exception, self.os.mkdir, directory)
-    self.filesystem.CreateDirectory('/xyzzy')
-    self.assertRaises(Exception, self.os.mkdir, directory)
-
-  def testMkdirRaisesWithDoubleDots(self):
-    """mkdir raises exception if mkdir foo/foo2/../foo3."""
-    self.assertRaises(Exception, self.os.mkdir, '/..')
-    directory = '/xyzzy/dir1/dir2/../../dir3'
-    self.assertRaises(Exception, self.os.mkdir, directory)
-    self.filesystem.CreateDirectory('/xyzzy')
-    self.assertRaises(Exception, self.os.mkdir, directory)
-    self.filesystem.CreateDirectory('/xyzzy/dir1')
-    self.assertRaises(Exception, self.os.mkdir, directory)
-    self.filesystem.CreateDirectory('/xyzzy/dir1/dir2')
-    self.os.mkdir(directory)
-    self.assertTrue(self.filesystem.Exists(directory))
-    directory = '/xyzzy/dir1/..'
-    self.assertRaises(Exception, self.os.mkdir, directory)
-
-  def testMkdirRaisesIfParentIsReadOnly(self):
-    """mkdir raises exception if parent is read only."""
-    directory = '/a'
-    self.os.mkdir(directory)
-
-    # Change directory permissions to be read only.
-    self.os.chmod(directory, 0o400)
-
-    directory = '/a/b'
-    self.assertRaises(Exception, self.os.mkdir, directory)
-
-  def testMakedirs(self):
-    """makedirs can create a directory even in parent does not exist."""
-    parent = 'xyzzy'
-    directory = '%s/foo' % (parent,)
-    self.assertFalse(self.filesystem.Exists(parent))
-    self.os.makedirs(directory)
-    self.assertTrue(self.filesystem.Exists(parent))
-
-  def testMakedirsRaisesIfParentIsFile(self):
-    """makedirs raises exception if a parent component exists as a file."""
-    file_path = 'xyzzy'
-    directory = '%s/plugh' % file_path
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    self.assertRaises(Exception, self.os.makedirs, directory)
-
-  def testMakedirsRaisesIfAccessDenied(self):
-    """makedirs raises exception if access denied."""
-    directory = '/a'
-    self.os.mkdir(directory)
-
-    # Change directory permissions to be read only.
-    self.os.chmod(directory, 0o400)
-
-    directory = '/a/b'
-    self.assertRaises(Exception, self.os.makedirs, directory)
-
-  def _CreateTestFile(self, path):
-    self.filesystem.CreateFile(path)
-    self.assertTrue(self.filesystem.Exists(path))
-    st = self.os.stat(path)
-    self.assertEqual(0o666, stat.S_IMODE(st.st_mode))
-    self.assertTrue(st.st_mode & stat.S_IFREG)
-    self.assertFalse(st.st_mode & stat.S_IFDIR)
-
-  def _CreateTestDirectory(self, path):
-    self.filesystem.CreateDirectory(path)
-    self.assertTrue(self.filesystem.Exists(path))
-    st = self.os.stat(path)
-    self.assertEqual(0o777, stat.S_IMODE(st.st_mode))
-    self.assertFalse(st.st_mode & stat.S_IFREG)
-    self.assertTrue(st.st_mode & stat.S_IFDIR)
-
-  def testAccess700(self):
-    # set up
-    path = '/some_file'
-    self._CreateTestFile(path)
-    self.os.chmod(path, 0o700)
-    self.assertModeEqual(0o700, self.os.stat(path).st_mode)
-    # actual tests
-    self.assertTrue(self.os.access(path, self.os.F_OK))
-    self.assertTrue(self.os.access(path, self.os.R_OK))
-    self.assertTrue(self.os.access(path, self.os.W_OK))
-    self.assertTrue(self.os.access(path, self.os.X_OK))
-    self.assertTrue(self.os.access(path, self.rwx))
-
-  def testAccess600(self):
-    # set up
-    path = '/some_file'
-    self._CreateTestFile(path)
-    self.os.chmod(path, 0o600)
-    self.assertModeEqual(0o600, self.os.stat(path).st_mode)
-    # actual tests
-    self.assertTrue(self.os.access(path, self.os.F_OK))
-    self.assertTrue(self.os.access(path, self.os.R_OK))
-    self.assertTrue(self.os.access(path, self.os.W_OK))
-    self.assertFalse(self.os.access(path, self.os.X_OK))
-    self.assertFalse(self.os.access(path, self.rwx))
-    self.assertTrue(self.os.access(path, self.rw))
-
-  def testAccess400(self):
-    # set up
-    path = '/some_file'
-    self._CreateTestFile(path)
-    self.os.chmod(path, 0o400)
-    self.assertModeEqual(0o400, self.os.stat(path).st_mode)
-    # actual tests
-    self.assertTrue(self.os.access(path, self.os.F_OK))
-    self.assertTrue(self.os.access(path, self.os.R_OK))
-    self.assertFalse(self.os.access(path, self.os.W_OK))
-    self.assertFalse(self.os.access(path, self.os.X_OK))
-    self.assertFalse(self.os.access(path, self.rwx))
-    self.assertFalse(self.os.access(path, self.rw))
-
-  def testAccessNonExistentFile(self):
-    # set up
-    path = '/non/existent/file'
-    self.assertFalse(self.filesystem.Exists(path))
-    # actual tests
-    self.assertFalse(self.os.access(path, self.os.F_OK))
-    self.assertFalse(self.os.access(path, self.os.R_OK))
-    self.assertFalse(self.os.access(path, self.os.W_OK))
-    self.assertFalse(self.os.access(path, self.os.X_OK))
-    self.assertFalse(self.os.access(path, self.rwx))
-    self.assertFalse(self.os.access(path, self.rw))
-
-  def testChmod(self):
-    # set up
-    path = '/some_file'
-    self._CreateTestFile(path)
-    # actual tests
-    self.os.chmod(path, 0o6543)
-    st = self.os.stat(path)
-    self.assertModeEqual(0o6543, st.st_mode)
-    self.assertTrue(st.st_mode & stat.S_IFREG)
-    self.assertFalse(st.st_mode & stat.S_IFDIR)
-
-  def testChmodDir(self):
-    # set up
-    path = '/some_dir'
-    self._CreateTestDirectory(path)
-    # actual tests
-    self.os.chmod(path, 0o1234)
-    st = self.os.stat(path)
-    self.assertModeEqual(0o1234, st.st_mode)
-    self.assertFalse(st.st_mode & stat.S_IFREG)
-    self.assertTrue(st.st_mode & stat.S_IFDIR)
-
-  def testChmodNonExistent(self):
-    # set up
-    path = '/non/existent/file'
-    self.assertFalse(self.filesystem.Exists(path))
-    # actual tests
-    try:
-      # Use try-catch to check exception attributes.
-      self.os.chmod(path, 0o777)
-      self.fail('Exception is expected.')  # COV_NF_LINE
-    except OSError as os_error:
-      self.assertEqual(errno.ENOENT, os_error.errno)
-      self.assertEqual(path, os_error.filename)
-
-  def testChmodStCtime(self):
-    # set up
-    file_path = 'some_file'
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.filesystem.Exists(file_path))
-    st = self.os.stat(file_path)
-    self.assertEqual(200, st.st_ctime)
-    # tests
-    self.os.chmod(file_path, 0o765)
-    st = self.os.stat(file_path)
-    self.assertEqual(220, st.st_ctime)
-
-  def testUtimeSetsCurrentTimeIfArgsIsNone(self):
-    # set up
-    path = '/some_file'
-    self._CreateTestFile(path)
-    st = self.os.stat(path)
-    # 200 is the current time established in setUp().
-    self.assertEqual(200, st.st_atime)
-    self.assertEqual(200, st.st_mtime)
-    # actual tests
-    self.os.utime(path, None)
-    st = self.os.stat(path)
-    self.assertEqual(220, st.st_atime)
-    self.assertEqual(240, st.st_mtime)
-
-  def testUtimeSetsCurrentTimeIfArgsIsNoneWithFloats(self):
-    # set up
-    # time.time can report back floats, but it should be converted to ints
-    # since atime/ctime/mtime are all defined as seconds since epoch.
-    time.time = _GetDummyTime(200.0123, 20)
-    path = '/some_file'
-    self._CreateTestFile(path)
-    st = self.os.stat(path)
-    # 200 is the current time established above (if converted to int).
-    self.assertEqual(200, st.st_atime)
-    self.assertEqual(200, st.st_mtime)
-    # actual tests
-    self.os.utime(path, None)
-    st = self.os.stat(path)
-    self.assertEqual(220, st.st_atime)
-    self.assertEqual(240, st.st_mtime)
-
-  def testUtimeSetsSpecifiedTime(self):
-    # set up
-    path = '/some_file'
-    self._CreateTestFile(path)
-    st = self.os.stat(path)
-    # actual tests
-    self.os.utime(path, (1, 2))
-    st = self.os.stat(path)
-    self.assertEqual(1, st.st_atime)
-    self.assertEqual(2, st.st_mtime)
-
-  def testUtimeDir(self):
-    # set up
-    path = '/some_dir'
-    self._CreateTestDirectory(path)
-    # actual tests
-    self.os.utime(path, (1.0, 2.0))
-    st = self.os.stat(path)
-    self.assertEqual(1.0, st.st_atime)
-    self.assertEqual(2.0, st.st_mtime)
-
-  def testUtimeNonExistent(self):
-    # set up
-    path = '/non/existent/file'
-    self.assertFalse(self.filesystem.Exists(path))
-    # actual tests
-    try:
-      # Use try-catch to check exception attributes.
-      self.os.utime(path, (1, 2))
-      self.fail('Exception is expected.')  # COV_NF_LINE
-    except OSError as os_error:
-      self.assertEqual(errno.ENOENT, os_error.errno)
-      self.assertEqual(path, os_error.filename)
-
-  def testUtimeTupleArgIsOfIncorrectLength(self):
-    # set up
-    path = '/some_dir'
-    self._CreateTestDirectory(path)
-    # actual tests
-    self.assertRaisesWithRegexpMatch(
-        TypeError, r'utime\(\) arg 2 must be a tuple \(atime, mtime\)',
-        self.os.utime, path, (1, 2, 3))
-
-  def testUtimeTupleArgContainsIncorrectType(self):
-    # set up
-    path = '/some_dir'
-    self._CreateTestDirectory(path)
-    # actual tests
-    self.assertRaisesWithRegexpMatch(
-        TypeError, 'an integer is required',
-        self.os.utime, path, (1, 'str'))
-
-  def testChownExistingFile(self):
-    # set up
-    file_path = 'some_file'
-    self.filesystem.CreateFile(file_path)
-    # first set it make sure it's set
-    self.os.chown(file_path, 100, 100)
-    st = self.os.stat(file_path)
-    self.assertEqual(st[stat.ST_UID], 100)
-    self.assertEqual(st[stat.ST_GID], 100)
-    # we can make sure it changed
-    self.os.chown(file_path, 200, 200)
-    st = self.os.stat(file_path)
-    self.assertEqual(st[stat.ST_UID], 200)
-    self.assertEqual(st[stat.ST_GID], 200)
-    # setting a value to -1 leaves it unchanged
-    self.os.chown(file_path, -1, -1)
-    st = self.os.stat(file_path)
-    self.assertEqual(st[stat.ST_UID], 200)
-    self.assertEqual(st[stat.ST_GID], 200)
-
-  def testChownNonexistingFileShouldRaiseOsError(self):
-    file_path = 'some_file'
-    self.assertFalse(self.filesystem.Exists(file_path))
-    self.assertRaises(OSError, self.os.chown, file_path, 100, 100)
-
-  def testClassifyDirectoryContents(self):
-    """Directory classification should work correctly."""
-    root_directory = '/foo'
-    test_directories = ['bar1', 'baz2']
-    test_files = ['baz1', 'bar2', 'baz3']
-    self.filesystem.CreateDirectory(root_directory)
-    for directory in test_directories:
-      directory = self.os.path.join(root_directory, directory)
-      self.filesystem.CreateDirectory(directory)
-    for test_file in test_files:
-      test_file = self.os.path.join(root_directory, test_file)
-      self.filesystem.CreateFile(test_file)
-
-    test_directories.sort()
-    test_files.sort()
-    generator = self.os.walk(root_directory)
-    root, dirs, files = next(generator)
-    dirs.sort()
-    files.sort()
-    self.assertEqual(root_directory, root)
-    self.assertEqual(test_directories, dirs)
-    self.assertEqual(test_files, files)
-
-  def testClassifyDoesNotHideExceptions(self):
-    """_ClassifyDirectoryContents should not hide exceptions."""
-    directory = '/foo'
-    self.assertEqual(False, self.filesystem.Exists(directory))
-    self.assertRaises(OSError, self.os._ClassifyDirectoryContents, directory)
-
-  def testWalkTopDown(self):
-    """Walk down ordering is correct."""
-    self.filesystem.CreateFile('foo/1.txt')
-    self.filesystem.CreateFile('foo/bar1/2.txt')
-    self.filesystem.CreateFile('foo/bar1/baz/3.txt')
-    self.filesystem.CreateFile('foo/bar2/4.txt')
-    expected = [
-        ('foo', ['bar1', 'bar2'], ['1.txt']),
-        ('foo/bar1', ['baz'], ['2.txt']),
-        ('foo/bar1/baz', [], ['3.txt']),
-        ('foo/bar2', [], ['4.txt']),
-        ]
-    self.assertEqual(expected, [step for step in self.os.walk('foo')])
-
-  def testWalkBottomUp(self):
-    """Walk up ordering is correct."""
-    self.filesystem.CreateFile('foo/bar1/baz/1.txt')
-    self.filesystem.CreateFile('foo/bar1/2.txt')
-    self.filesystem.CreateFile('foo/bar2/3.txt')
-    self.filesystem.CreateFile('foo/4.txt')
-
-    expected = [
-        ('foo/bar1/baz', [], ['1.txt']),
-        ('foo/bar1', ['baz'], ['2.txt']),
-        ('foo/bar2', [], ['3.txt']),
-        ('foo', ['bar1', 'bar2'], ['4.txt']),
-        ]
-    self.assertEqual(expected,
-                     [step for step in self.os.walk('foo', topdown=False)])
-
-  def testWalkRaisesIfNonExistent(self):
-    """Raises an exception when attempting to walk non-existent directory."""
-    directory = '/foo/bar'
-    self.assertEqual(False, self.filesystem.Exists(directory))
-    generator = self.os.walk(directory)
-    self.assertRaises(StopIteration, next, generator)
-
-  def testWalkRaisesIfNotDirectory(self):
-    """Raises an exception when attempting to walk a non-directory."""
-    filename = '/foo/bar'
-    self.filesystem.CreateFile(filename)
-    generator = self.os.walk(filename)
-    self.assertRaises(StopIteration, next, generator)
-
-  def testMkNodeCanCreateAFile(self):
-    filename = 'foo'
-    self.assertFalse(self.filesystem.Exists(filename))
-    self.os.mknod(filename)
-    self.assertTrue(self.filesystem.Exists(filename))
-
-  def testMkNodeRaisesIfEmptyFileName(self):
-    filename = ''
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMkNodeRaisesIfParentDirDoesntExist(self):
-    parent = 'xyzzy'
-    filename = '%s/foo' % (parent,)
-    self.assertFalse(self.filesystem.Exists(parent))
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMkNodeRaisesIfFileExists(self):
-    filename = '/tmp/foo'
-    self.filesystem.CreateFile(filename)
-    self.assertTrue(self.filesystem.Exists(filename))
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMkNodeRaisesIfFilenameIsDot(self):
-    filename = '/tmp/.'
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMkNodeRaisesIfFilenameIsDoubleDot(self):
-    filename = '/tmp/..'
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMknodEmptyTailForExistingFileRaises(self):
-    filename = '/tmp/foo'
-    self.filesystem.CreateFile(filename)
-    self.assertTrue(self.filesystem.Exists(filename))
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMknodEmptyTailForNonexistentFileRaises(self):
-    filename = '/tmp/foo'
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMknodRaisesIfFilenameIsEmptyString(self):
-    filename = ''
-    self.assertRaises(OSError, self.os.mknod, filename)
-
-  def testMknodeRaisesIfUnsupportedOptions(self):
-    filename = 'abcde'
-    self.assertRaises(OSError, self.os.mknod, filename,
-                      mode=stat.S_IFCHR)
-
-  def testMknodeRaisesIfParentIsNotADirectory(self):
-    filename1 = '/tmp/foo'
-    self.filesystem.CreateFile(filename1)
-    self.assertTrue(self.filesystem.Exists(filename1))
-    filename2 = '/tmp/foo/bar'
-    self.assertRaises(OSError, self.os.mknod, filename2)
-
-  def ResetErrno(self):
-    """Reset the last seen errno."""
-    self.last_errno = False
-
-  def StoreErrno(self, os_error):
-    """Store the last errno we saw."""
-    self.last_errno = os_error.errno
-
-  def GetErrno(self):
-    """Return the last errno we saw."""
-    return self.last_errno
-
-  def testWalkCallsOnErrorIfNonExistent(self):
-    """Calls onerror with correct errno when walking non-existent directory."""
-    self.ResetErrno()
-    directory = '/foo/bar'
-    self.assertEqual(False, self.filesystem.Exists(directory))
-    # Calling os.walk on a non-existent directory should trigger a call to the
-    # onerror method.  We do not actually care what, if anything, is returned.
-    for unused_entry in self.os.walk(directory, onerror=self.StoreErrno):
-      pass
-    self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.ENOENT))
-
-  def testWalkCallsOnErrorIfNotDirectory(self):
-    """Calls onerror with correct errno when walking non-directory."""
-    self.ResetErrno()
-    filename = '/foo/bar'
-    self.filesystem.CreateFile(filename)
-    self.assertEqual(True, self.filesystem.Exists(filename))
-    # Calling os.walk on a file should trigger a call to the onerror method.
-    # We do not actually care what, if anything, is returned.
-    for unused_entry in self.os.walk(filename, onerror=self.StoreErrno):
-      pass
-    self.assertTrue(self.GetErrno() in (errno.ENOTDIR, errno.EACCES))
-
-  def testWalkSkipsRemovedDirectories(self):
-    """Caller can modify list of directories to visit while walking."""
-    root = '/foo'
-    visit = 'visit'
-    no_visit = 'no_visit'
-    self.filesystem.CreateFile('%s/bar' % (root,))
-    self.filesystem.CreateFile('%s/%s/1.txt' % (root, visit))
-    self.filesystem.CreateFile('%s/%s/2.txt' % (root, visit))
-    self.filesystem.CreateFile('%s/%s/3.txt' % (root, no_visit))
-    self.filesystem.CreateFile('%s/%s/4.txt' % (root, no_visit))
-
-    generator = self.os.walk('/foo')
-    root_contents = next(generator)
-    root_contents[1].remove(no_visit)
-
-    visited_visit_directory = False
-
-    for root, unused_dirs, unused_files in iter(generator):
-      self.assertEqual(False, root.endswith('/%s' % (no_visit)))
-      if root.endswith('/%s' % (visit)):
-        visited_visit_directory = True
-
-    self.assertEqual(True, visited_visit_directory)
-
-  def testSymlink(self):
-    file_path = 'foo/bar/baz'
-    self.os.symlink('bogus', file_path)
-    self.assertTrue(self.os.path.lexists(file_path))
-    self.assertFalse(self.os.path.exists(file_path))
-    self.filesystem.CreateFile('foo/bar/bogus')
-    self.assertTrue(self.os.path.lexists(file_path))
-    self.assertTrue(self.os.path.exists(file_path))
-
-  def testUMask(self):
-    umask = os.umask(0o22)
-    os.umask(umask)
-    self.assertEqual(umask, self.os.umask(0o22))
-
-  def testMkdirUmaskApplied(self):
-    """mkdir creates a directory with umask applied."""
-    self.os.umask(0o22)
-    self.os.mkdir('dir1')
-    self.assertModeEqual(0o755, self.os.stat('dir1').st_mode)
-    self.os.umask(0o67)
-    self.os.mkdir('dir2')
-    self.assertModeEqual(0o710, self.os.stat('dir2').st_mode)
-
-  def testMakedirsUmaskApplied(self):
-    """makedirs creates a directories with umask applied."""
-    self.os.umask(0o22)
-    self.os.makedirs('/p1/dir1')
-    self.assertModeEqual(0o755, self.os.stat('/p1').st_mode)
-    self.assertModeEqual(0o755, self.os.stat('/p1/dir1').st_mode)
-    self.os.umask(0o67)
-    self.os.makedirs('/p2/dir2')
-    self.assertModeEqual(0o710, self.os.stat('/p2').st_mode)
-    self.assertModeEqual(0o710, self.os.stat('/p2/dir2').st_mode)
-
-  def testMknodeUmaskApplied(self):
-    """mkdir creates a device with umask applied."""
-    self.os.umask(0o22)
-    self.os.mknod('nod1')
-    self.assertModeEqual(0o644, self.os.stat('nod1').st_mode)
-    self.os.umask(0o27)
-    self.os.mknod('nod2')
-    self.assertModeEqual(0o640, self.os.stat('nod2').st_mode)
-
-  def testOpenUmaskApplied(self):
-    """open creates a file with umask applied."""
-    fake_open = fake_filesystem.FakeFileOpen(self.filesystem)
-    self.os.umask(0o22)
-    fake_open('file1', 'w').close()
-    self.assertModeEqual(0o644, self.os.stat('file1').st_mode)
-    self.os.umask(0o27)
-    fake_open('file2', 'w').close()
-    self.assertModeEqual(0o640, self.os.stat('file2').st_mode)
-
-
-class StatPropagationTest(TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-    self.open = fake_filesystem.FakeFileOpen(self.filesystem)
-
-  def testFileSizeUpdatedViaClose(self):
-    """test that file size gets updated via close()."""
-    file_dir = 'xyzzy'
-    file_path = 'xyzzy/close'
-    content = 'This is a test.'
-    self.os.mkdir(file_dir)
-    fh = self.open(file_path, 'w')
-    self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual('', self.filesystem.GetObject(file_path).contents)
-    fh.write(content)
-    self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual('', self.filesystem.GetObject(file_path).contents)
-    fh.close()
-    self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual(content, self.filesystem.GetObject(file_path).contents)
-
-  def testFileSizeNotResetAfterClose(self):
-    file_dir = 'xyzzy'
-    file_path = 'xyzzy/close'
-    self.os.mkdir(file_dir)
-    size = 1234
-    # The file has size, but no content. When the file is opened for reading,
-    # its size should be preserved.
-    self.filesystem.CreateFile(file_path, st_size=size)
-    fh = self.open(file_path, 'r')
-    fh.close()
-    self.assertEqual(size, self.open(file_path, 'r').Size())
-
-  def testFileSizeAfterWrite(self):
-    file_path = 'test_file'
-    original_content = 'abcdef'
-    original_size = len(original_content)
-    self.filesystem.CreateFile(file_path, contents=original_content)
-    added_content = 'foo bar'
-    expected_size = original_size + len(added_content)
-    fh = self.open(file_path, 'a')
-    fh.write(added_content)
-    self.assertEqual(expected_size, fh.Size())
-    fh.close()
-    self.assertEqual(expected_size, self.open(file_path, 'r').Size())
-
-  def testLargeFileSizeAfterWrite(self):
-    file_path = 'test_file'
-    original_content = 'abcdef'
-    original_size = len(original_content)
-    self.filesystem.CreateFile(file_path, st_size=original_size)
-    added_content = 'foo bar'
-    fh = self.open(file_path, 'a')
-    # We can't use assertRaises, because the exception is thrown
-    # in __getattr__, so just saying 'fh.write' causes the exception.
-    try:
-      fh.write(added_content)
-    except fake_filesystem.FakeLargeFileIoException:
-      return
-    self.fail('Writing to a large file should not be allowed')
-
-  def testFileSizeUpdatedViaFlush(self):
-    """test that file size gets updated via flush()."""
-    file_dir = 'xyzzy'
-    file_name = 'flush'
-    file_path = self.os.path.join(file_dir, file_name)
-    content = 'This might be a test.'
-    self.os.mkdir(file_dir)
-    fh = self.open(file_path, 'w')
-    self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual('', self.filesystem.GetObject(file_path).contents)
-    fh.write(content)
-    self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual('', self.filesystem.GetObject(file_path).contents)
-    fh.flush()
-    self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual(content, self.filesystem.GetObject(file_path).contents)
-    fh.close()
-    self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual(content, self.filesystem.GetObject(file_path).contents)
-
-  def testFileSizeTruncation(self):
-    """test that file size gets updated via open()."""
-    file_dir = 'xyzzy'
-    file_path = 'xyzzy/truncation'
-    content = 'AAA content.'
-
-    # pre-create file with content
-    self.os.mkdir(file_dir)
-    fh = self.open(file_path, 'w')
-    fh.write(content)
-    fh.close()
-    self.assertEqual(len(content), self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual(content, self.filesystem.GetObject(file_path).contents)
-
-    # test file truncation
-    fh = self.open(file_path, 'w')
-    self.assertEqual(0, self.os.stat(file_path)[stat.ST_SIZE])
-    self.assertEqual('', self.filesystem.GetObject(file_path).contents)
-    fh.close()
-
-
-class OsPathInjectionRegressionTest(TestCase):
-  """Test faking os.path before calling os.walk.
-
-  Found when investigating a problem with
-  gws/tools/labrat/rat_utils_unittest, which was faking out os.path
-  before calling os.walk.
-  """
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.os_path = os.path
-    # The bug was that when os.path gets faked, the FakePathModule doesn't get
-    # called in self.os.walk().  FakePathModule now insists that it is created
-    # as part of FakeOsModule.
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-
-  def tearDown(self):
-    os.path = self.os_path
-
-  def testCreateTopLevelDirectory(self):
-    top_level_dir = '/x'
-    self.assertFalse(self.filesystem.Exists(top_level_dir))
-    self.filesystem.CreateDirectory(top_level_dir)
-    self.assertTrue(self.filesystem.Exists('/'))
-    self.assertTrue(self.filesystem.Exists(top_level_dir))
-    self.filesystem.CreateDirectory('%s/po' % top_level_dir)
-    self.filesystem.CreateFile('%s/po/control' % top_level_dir)
-    self.filesystem.CreateFile('%s/po/experiment' % top_level_dir)
-    self.filesystem.CreateDirectory('%s/gv' % top_level_dir)
-    self.filesystem.CreateFile('%s/gv/control' % top_level_dir)
-
-    expected = [
-        ('/', ['x'], []),
-        ('/x', ['gv', 'po'], []),
-        ('/x/gv', [], ['control']),
-        ('/x/po', [], ['control', 'experiment']),
-        ]
-    self.assertEqual(expected, [step for step in self.os.walk('/')])
-
-
-class FakePathModuleTest(TestCase):
-  def setUp(self):
-    self.orig_time = time.time
-    time.time = _GetDummyTime(10, 1)
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-    self.path = self.os.path
-
-  def tearDown(self):
-    time.time = self.orig_time
-
-  def testAbspath(self):
-    """abspath should return a consistent representation of a file."""
-    filename = 'foo'
-    abspath = '/%s' % filename
-    self.filesystem.CreateFile(abspath)
-    self.assertEqual(abspath, self.path.abspath(abspath))
-    self.assertEqual(abspath, self.path.abspath(filename))
-    self.assertEqual(abspath, self.path.abspath('../%s' % filename))
-
-  def testAbspathDealsWithRelativeNonRootPath(self):
-    """abspath should correctly handle relative paths from a non-/ directory.
-
-    This test is distinct from the basic functionality test because
-    fake_filesystem has historically been based in /.
-    """
-    filename = '/foo/bar/baz'
-    file_components = filename.split(self.path.sep)
-    basedir = '/%s' % (file_components[0],)
-    self.filesystem.CreateFile(filename)
-    self.os.chdir(basedir)
-    self.assertEqual(basedir, self.path.abspath(self.path.curdir))
-    self.assertEqual('/', self.path.abspath('..'))
-    self.assertEqual(self.path.join(basedir, file_components[1]),
-                     self.path.abspath(file_components[1]))
-
-  def testRelpath(self):
-    path_foo = '/path/to/foo'
-    path_bar = '/path/to/bar'
-    path_other = '/some/where/else'
-    self.assertRaises(ValueError, self.path.relpath, None)
-    self.assertRaises(ValueError, self.path.relpath, '')
-    self.assertEqual(path_foo[1:],
-                     self.path.relpath(path_foo))
-    self.assertEqual('../foo',
-                     self.path.relpath(path_foo, path_bar))
-    self.assertEqual('../../..%s' % path_other,
-                     self.path.relpath(path_other, path_bar))
-    self.assertEqual('.',
-                     self.path.relpath(path_bar, path_bar))
-
-  @unittest.skipIf(TestCase.is_windows, 'realpath does not follow symlinks in win32')
-  def testRealpathVsAbspath(self):
-    self.filesystem.CreateFile('/george/washington/bridge')
-    self.filesystem.CreateLink('/first/president', '/george/washington')
-    self.assertEqual('/first/president/bridge',
-                     self.os.path.abspath('/first/president/bridge'))
-    self.assertEqual('/george/washington/bridge',
-                     self.os.path.realpath('/first/president/bridge'))
-    self.os.chdir('/first/president')
-    self.assertEqual('/george/washington/bridge',
-                     self.os.path.realpath('bridge'))
-
-  def testExists(self):
-    file_path = 'foo/bar/baz'
-    self.filesystem.CreateFile(file_path)
-    self.assertTrue(self.path.exists(file_path))
-    self.assertFalse(self.path.exists('/some/other/bogus/path'))
-
-  def testLexists(self):
-    file_path = 'foo/bar/baz'
-    self.filesystem.CreateDirectory('foo/bar')
-    self.filesystem.CreateLink(file_path, 'bogus')
-    self.assertTrue(self.path.lexists(file_path))
-    self.assertFalse(self.path.exists(file_path))
-    self.filesystem.CreateFile('foo/bar/bogus')
-    self.assertTrue(self.path.exists(file_path))
-
-  def testDirname(self):
-    dirname = 'foo/bar'
-    self.assertEqual(dirname, self.path.dirname('%s/baz' % dirname))
-
-  def testJoin(self):
-    components = ['foo', 'bar', 'baz']
-    self.assertEqual('foo/bar/baz', self.path.join(*components))
-
-  def testExpandUser(self):
-    if self.is_windows:
-      self.assertEqual(self.path.expanduser('~'),
-                       self.os.environ['USERPROFILE'].replace('\\', '/'))
-    else:
-      self.assertEqual(self.path.expanduser('~'),
-                       self.os.environ['HOME'])
-
-  @unittest.skipIf(TestCase.is_windows or TestCase.is_cygwin,
-                   'only tested on unix systems')
-  def testExpandRoot(self):
-      self.assertEqual('/root', self.path.expanduser('~root'))
-
-  def testGetsizePathNonexistent(self):
-    file_path = 'foo/bar/baz'
-    self.assertRaises(IOError, self.path.getsize, file_path)
-
-  def testGetsizeFileEmpty(self):
-    file_path = 'foo/bar/baz'
-    self.filesystem.CreateFile(file_path)
-    self.assertEqual(0, self.path.getsize(file_path))
-
-  def testGetsizeFileNonZeroSize(self):
-    file_path = 'foo/bar/baz'
-    self.filesystem.CreateFile(file_path, contents='1234567')
-    self.assertEqual(7, self.path.getsize(file_path))
-
-  def testGetsizeDirEmpty(self):
-    # For directories, only require that the size is non-negative.
-    dir_path = 'foo/bar'
-    self.filesystem.CreateDirectory(dir_path)
-    size = self.path.getsize(dir_path)
-    self.assertFalse(int(size) < 0,
-                     'expected non-negative size; actual: %s' % size)
-
-  def testGetsizeDirNonZeroSize(self):
-    # For directories, only require that the size is non-negative.
-    dir_path = 'foo/bar'
-    self.filesystem.CreateFile(self.filesystem.JoinPaths(dir_path, 'baz'))
-    size = self.path.getsize(dir_path)
-    self.assertFalse(int(size) < 0,
-                     'expected non-negative size; actual: %s' % size)
-
-  def testIsdir(self):
-    self.filesystem.CreateFile('foo/bar')
-    self.assertTrue(self.path.isdir('foo'))
-    self.assertFalse(self.path.isdir('foo/bar'))
-    self.assertFalse(self.path.isdir('it_dont_exist'))
-
-  def testIsdirWithCwdChange(self):
-    self.filesystem.CreateFile('/foo/bar/baz')
-    self.assertTrue(self.path.isdir('/foo'))
-    self.assertTrue(self.path.isdir('/foo/bar'))
-    self.assertTrue(self.path.isdir('foo'))
-    self.assertTrue(self.path.isdir('foo/bar'))
-    self.filesystem.cwd = '/foo'
-    self.assertTrue(self.path.isdir('/foo'))
-    self.assertTrue(self.path.isdir('/foo/bar'))
-    self.assertTrue(self.path.isdir('bar'))
-
-  def testIsfile(self):
-    self.filesystem.CreateFile('foo/bar')
-    self.assertFalse(self.path.isfile('foo'))
-    self.assertTrue(self.path.isfile('foo/bar'))
-    self.assertFalse(self.path.isfile('it_dont_exist'))
-
-  def testGetMtime(self):
-    test_file = self.filesystem.CreateFile('foo/bar1.txt')
-    # The root directory ('', effectively '/') is created at time 10,
-    # the parent directory ('foo') at time 11, and the file at time 12.
-    self.assertEqual(12, test_file.st_mtime)
-    test_file.SetMTime(24)
-    self.assertEqual(24, self.path.getmtime('foo/bar1.txt'))
-
-  def testGetMtimeRaisesOSError(self):
-    self.assertFalse(self.path.exists('it_dont_exist'))
-    self.assertRaises(OSError, self.path.getmtime, 'it_dont_exist')
-
-  def testIslink(self):
-    self.filesystem.CreateDirectory('foo')
-    self.filesystem.CreateFile('foo/regular_file')
-    self.filesystem.CreateLink('foo/link_to_file', 'regular_file')
-    self.assertFalse(self.path.islink('foo'))
-
-    # An object can be both a link and a file or file, according to the
-    # comments in Python/Lib/posixpath.py.
-    self.assertTrue(self.path.islink('foo/link_to_file'))
-    self.assertTrue(self.path.isfile('foo/link_to_file'))
-
-    self.assertTrue(self.path.isfile('foo/regular_file'))
-    self.assertFalse(self.path.islink('foo/regular_file'))
-
-    self.assertFalse(self.path.islink('it_dont_exist'))
-
-  @unittest.skipIf(sys.version_info >= (3, 0) or TestCase.is_windows,
-                   'os.path.walk deprecrated in Python 3, cannot be properly '
-                   'tested in win32')
-  def testWalk(self):
-    self.filesystem.CreateFile('/foo/bar/baz')
-    self.filesystem.CreateFile('/foo/bar/xyzzy/plugh')
-    visited_nodes = []
-
-    def RecordVisitedNodes(visited, dirname, fnames):
-      visited.extend(((dirname, fname) for fname in fnames))
-
-    self.path.walk('/foo', RecordVisitedNodes, visited_nodes)
-    expected = [('/foo', 'bar'),
-                ('/foo/bar', 'baz'),
-                ('/foo/bar', 'xyzzy'),
-                ('/foo/bar/xyzzy', 'plugh')]
-    self.assertEqual(expected, visited_nodes)
-
-  @unittest.skipIf(sys.version_info >= (3, 0) or TestCase.is_windows,
-                   'os.path.walk deprecrated in Python 3, cannot be properly '
-                   'tested in win32')
-  def testWalkFromNonexistentTopDoesNotThrow(self):
-    visited_nodes = []
-
-    def RecordVisitedNodes(visited, dirname, fnames):
-      visited.extend(((dirname, fname) for fname in fnames))
-
-    self.path.walk('/foo', RecordVisitedNodes, visited_nodes)
-    self.assertEqual([], visited_nodes)
-
-
-class FakeFileOpenTestBase(TestCase):
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.file = fake_filesystem.FakeFileOpen(self.filesystem)
-    self.open = self.file
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-    self.orig_time = time.time
-    time.time = _GetDummyTime(100, 10)
-
-  def tearDown(self):
-    time.time = self.orig_time
-
-
-class FakeFileOpenTest(FakeFileOpenTestBase):
-  def testOpenNoParentDir(self):
-    """Expect raise when open'ing a file in a missing directory."""
-    file_path = 'foo/bar.txt'
-    self.assertRaises(IOError, self.file, file_path, 'w')
-
-  def testDeleteOnClose(self):
-    file_dir = 'boo'
-    file_path = 'boo/far'
-    self.os.mkdir(file_dir)
-    self.file = fake_filesystem.FakeFileOpen(self.filesystem,
-                                             delete_on_close=True)
-    fh = self.file(file_path, 'w')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fh.close()
-    self.assertFalse(self.filesystem.Exists(file_path))
-
-  def testNoDeleteOnCloseByDefault(self):
-    file_dir = 'boo'
-    file_path = 'boo/czar'
-    self.file = fake_filesystem.FakeFileOpen(self.filesystem)
-    self.os.mkdir(file_dir)
-    fh = self.file(file_path, 'w')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fh.close()
-    self.assertTrue(self.filesystem.Exists(file_path))
-
-  def testCompatibilityOfWithStatement(self):
-    self.file = fake_filesystem.FakeFileOpen(self.filesystem,
-                                             delete_on_close=True)
-    file_path = 'foo'
-    self.assertFalse(self.filesystem.Exists(file_path))
-    with self.file(file_path, 'w') as _:
-      self.assertTrue(self.filesystem.Exists(file_path))
-    # After the 'with' statement, the close() method should have been called.
-    self.assertFalse(self.filesystem.Exists(file_path))
-
-  def testOpenValidFile(self):
-    contents = [
-        'I am he as\n',
-        'you are he as\n',
-        'you are me and\n',
-        'we are all together\n'
-        ]
-    file_path = 'foo/bar.txt'
-    self.filesystem.CreateFile(file_path, contents=''.join(contents))
-    self.assertEqual(contents, self.file(file_path).readlines())
-
-  def testOpenValidArgs(self):
-    contents = [
-        "Bang bang Maxwell's silver hammer\n",
-        'Came down on her head',
-        ]
-    file_path = 'abbey_road/maxwell'
-    self.filesystem.CreateFile(file_path, contents=''.join(contents))
-    self.assertEqual(
-        contents, self.open(file_path, mode='r', buffering=1).readlines())
-    if sys.version_info >= (3, 0):
-      self.assertEqual(
-          contents, self.open(file_path, mode='r', buffering=1,
-                              encoding='utf-8', errors='strict', newline='\n',
-                              closefd=False, opener=False).readlines())
-
-  @unittest.skipIf(sys.version_info < (3, 0), 'only tested on 3.0 or greater')
-  def testOpenNewlineArg(self):
-    file_path = 'some_file'
-    file_contents = 'two\r\nlines'
-    self.filesystem.CreateFile(file_path, contents=file_contents)
-    fake_file = self.open(file_path, mode='r', newline=None)
-    self.assertEqual(['two\n', 'lines'], fake_file.readlines())
-    fake_file = self.open(file_path, mode='r', newline='')
-    self.assertEqual(['two\r\n', 'lines'], fake_file.readlines())
-    fake_file = self.open(file_path, mode='r', newline='\r')
-    self.assertEqual(['two\r', '\r', 'lines'], fake_file.readlines())
-    fake_file = self.open(file_path, mode='r', newline='\n')
-    self.assertEqual(['two\r\n', 'lines'], fake_file.readlines())
-    fake_file = self.open(file_path, mode='r', newline='\r\n')
-    self.assertEqual(['two\r\r\n', 'lines'], fake_file.readlines())
-
-  def testOpenValidFileWithCwd(self):
-    contents = [
-        'I am he as\n',
-        'you are he as\n',
-        'you are me and\n',
-        'we are all together\n'
-        ]
-    file_path = '/foo/bar.txt'
-    self.filesystem.CreateFile(file_path, contents=''.join(contents))
-    self.filesystem.cwd = '/foo'
-    self.assertEqual(contents, self.file(file_path).readlines())
-
-  def testIterateOverFile(self):
-    contents = [
-        "Bang bang Maxwell's silver hammer",
-        'Came down on her head',
-        ]
-    file_path = 'abbey_road/maxwell'
-    self.filesystem.CreateFile(file_path, contents='\n'.join(contents))
-    result = [line.rstrip() for line in self.file(file_path)]
-    self.assertEqual(contents, result)
-
-  def testOpenDirectoryError(self):
-    directory_path = 'foo/bar'
-    self.filesystem.CreateDirectory(directory_path)
-    self.assertRaises(IOError, self.file.__call__, directory_path)
-
-  def testCreateFileWithWrite(self):
-    contents = [
-        "Here comes the sun, little darlin'",
-        'Here comes the sun, and I say,',
-        "It's alright",
-        ]
-    file_dir = 'abbey_road'
-    file_path = 'abbey_road/here_comes_the_sun'
-    self.os.mkdir(file_dir)
-    fake_file = self.file(file_path, 'w')
-    for line in contents:
-      fake_file.write(line + '\n')
-    fake_file.close()
-    result = [line.rstrip() for line in self.file(file_path)]
-    self.assertEqual(contents, result)
-
-  def testCreateFileWithAppend(self):
-    contents = [
-        "Here comes the sun, little darlin'",
-        'Here comes the sun, and I say,',
-        "It's alright",
-        ]
-    file_dir = 'abbey_road'
-    file_path = 'abbey_road/here_comes_the_sun'
-    self.os.mkdir(file_dir)
-    fake_file = self.file(file_path, 'a')
-    for line in contents:
-      fake_file.write(line + '\n')
-    fake_file.close()
-    result = [line.rstrip() for line in self.file(file_path)]
-    self.assertEqual(contents, result)
-
-  def testOverwriteExistingFile(self):
-    file_path = 'overwrite/this/file'
-    self.filesystem.CreateFile(file_path, contents='To disappear')
-    new_contents = [
-        'Only these lines',
-        'should be in the file.',
-        ]
-    fake_file = self.file(file_path, 'w')
-    for line in new_contents:
-      fake_file.write(line + '\n')
-    fake_file.close()
-    result = [line.rstrip() for line in self.file(file_path)]
-    self.assertEqual(new_contents, result)
-
-  def testAppendExistingFile(self):
-    file_path = 'append/this/file'
-    contents = [
-        'Contents of original file'
-        'Appended contents',
-        ]
-    self.filesystem.CreateFile(file_path, contents=contents[0])
-    fake_file = self.file(file_path, 'a')
-    for line in contents[1:]:
-      fake_file.write(line + '\n')
-    fake_file.close()
-    result = [line.rstrip() for line in self.file(file_path)]
-    self.assertEqual(contents, result)
-
-  def testOpenWithWplus(self):
-    # set up
-    file_path = 'wplus_file'
-    self.filesystem.CreateFile(file_path, contents='old contents')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fake_file = self.file(file_path, 'r')
-    self.assertEqual('old contents', fake_file.read())
-    fake_file.close()
-    # actual tests
-    fake_file = self.file(file_path, 'w+')
-    fake_file.write('new contents')
-    fake_file.seek(0)
-    self.assertTrue('new contents', fake_file.read())
-    fake_file.close()
-
-  def testOpenWithWplusTruncation(self):
-    # set up
-    file_path = 'wplus_file'
-    self.filesystem.CreateFile(file_path, contents='old contents')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fake_file = self.file(file_path, 'r')
-    self.assertEqual('old contents', fake_file.read())
-    fake_file.close()
-    # actual tests
-    fake_file = self.file(file_path, 'w+')
-    fake_file.seek(0)
-    self.assertEqual('', fake_file.read())
-    fake_file.close()
-
-  def testOpenWithAppendFlag(self):
-    contents = [
-        'I am he as\n',
-        'you are he as\n',
-        'you are me and\n',
-        'we are all together\n'
-        ]
-    additional_contents = [
-        'These new lines\n',
-        'like you a lot.\n'
-        ]
-    file_path = 'append/this/file'
-    self.filesystem.CreateFile(file_path, contents=''.join(contents))
-    fake_file = self.file(file_path, 'a')
-    self.assertRaises(IOError, fake_file.read)
-    self.assertEqual('', fake_file.read(0))
-    self.assertEqual('', fake_file.readline(0))
-    self.assertEqual(len(''.join(contents)), fake_file.tell())
-    fake_file.seek(0)
-    self.assertEqual(0, fake_file.tell())
-    fake_file.writelines(additional_contents)
-    fake_file.close()
-    result = self.file(file_path).readlines()
-    self.assertEqual(contents + additional_contents, result)
-
-  def testAppendWithAplus(self):
-    # set up
-    file_path = 'aplus_file'
-    self.filesystem.CreateFile(file_path, contents='old contents')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fake_file = self.file(file_path, 'r')
-    self.assertEqual('old contents', fake_file.read())
-    fake_file.close()
-    # actual tests
-    fake_file = self.file(file_path, 'a+')
-    self.assertEqual(0, fake_file.tell())
-    fake_file.seek(6, 1)
-    fake_file.write('new contents')
-    self.assertEqual(24, fake_file.tell())
-    fake_file.seek(0)
-    self.assertEqual('old contentsnew contents', fake_file.read())
-    fake_file.close()
-
-  def testAppendWithAplusReadWithLoop(self):
-    # set up
-    file_path = 'aplus_file'
-    self.filesystem.CreateFile(file_path, contents='old contents')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fake_file = self.file(file_path, 'r')
-    self.assertEqual('old contents', fake_file.read())
-    fake_file.close()
-    # actual tests
-    fake_file = self.file(file_path, 'a+')
-    fake_file.seek(0)
-    fake_file.write('new contents')
-    fake_file.seek(0)
-    for line in fake_file:
-      self.assertEqual('old contentsnew contents', line)
-    fake_file.close()
-
-  def testReadEmptyFileWithAplus(self):
-    file_path = 'aplus_file'
-    fake_file = self.file(file_path, 'a+')
-    self.assertEqual('', fake_file.read())
-    fake_file.close()
-
-  def testReadWithRplus(self):
-    # set up
-    file_path = 'rplus_file'
-    self.filesystem.CreateFile(file_path, contents='old contents here')
-    self.assertTrue(self.filesystem.Exists(file_path))
-    fake_file = self.file(file_path, 'r')
-    self.assertEqual('old contents here', fake_file.read())
-    fake_file.close()
-    # actual tests
-    fake_file = self.file(file_path, 'r+')
-    self.assertEqual('old contents here', fake_file.read())
-    fake_file.seek(0)
-    fake_file.write('new contents')
-    fake_file.seek(0)
-    self.assertEqual('new contents here', fake_file.read())
-    fake_file.close()
-
-  def testOpenStCtime(self):
-    # set up
-    file_path = 'some_file'
-    self.assertFalse(self.filesystem.Exists(file_path))
-    # tests
-    fake_file = self.file(file_path, 'w')
-    fake_file.close()
-    st = self.os.stat(file_path)
-    self.assertEqual(100, st.st_ctime)
-
-    fake_file = self.file(file_path, 'w')
-    fake_file.close()
-    st = self.os.stat(file_path)
-    self.assertEqual(110, st.st_ctime)
-
-    fake_file = self.file(file_path, 'w+')
-    fake_file.close()
-    st = self.os.stat(file_path)
-    self.assertEqual(120, st.st_ctime)
-
-    fake_file = self.file(file_path, 'r')
-    fake_file.close()
-    st = self.os.stat(file_path)
-    self.assertEqual(120, st.st_ctime)
-
-  def _CreateWithPermission(self, file_path, perm_bits):
-    self.filesystem.CreateFile(file_path)
-    self.os.chmod(file_path, perm_bits)
-    st = self.os.stat(file_path)
-    self.assertModeEqual(perm_bits, st.st_mode)
-    self.assertTrue(st.st_mode & stat.S_IFREG)
-    self.assertFalse(st.st_mode & stat.S_IFDIR)
-
-  def testOpenFlags700(self):
-    # set up
-    file_path = 'target_file'
-    self._CreateWithPermission(file_path, 0o700)
-    # actual tests
-    self.file(file_path, 'r').close()
-    self.file(file_path, 'w').close()
-    self.file(file_path, 'w+').close()
-    self.assertRaises(IOError, self.file, file_path, 'INV')
-
-  def testOpenFlags400(self):
-    # set up
-    file_path = 'target_file'
-    self._CreateWithPermission(file_path, 0o400)
-    # actual tests
-    self.file(file_path, 'r').close()
-    self.assertRaises(IOError, self.file, file_path, 'w')
-    self.assertRaises(IOError, self.file, file_path, 'w+')
-
-  def testOpenFlags200(self):
-    # set up
-    file_path = 'target_file'
-    self._CreateWithPermission(file_path, 0o200)
-    # actual tests
-    self.assertRaises(IOError, self.file, file_path, 'r')
-    self.file(file_path, 'w').close()
-    self.assertRaises(IOError, self.file, file_path, 'w+')
-
-  def testOpenFlags100(self):
-    # set up
-    file_path = 'target_file'
-    self._CreateWithPermission(file_path, 0o100)
-    # actual tests 4
-    self.assertRaises(IOError, self.file, file_path, 'r')
-    self.assertRaises(IOError, self.file, file_path, 'w')
-    self.assertRaises(IOError, self.file, file_path, 'w+')
-
-  def testFollowLinkRead(self):
-    link_path = '/foo/bar/baz'
-    target = '/tarJAY'
-    target_contents = 'real baz contents'
-    self.filesystem.CreateFile(target, contents=target_contents)
-    self.filesystem.CreateLink(link_path, target)
-    self.assertEqual(target, self.os.readlink(link_path))
-    fh = self.open(link_path, 'r')
-    got_contents = fh.read()
-    fh.close()
-    self.assertEqual(target_contents, got_contents)
-
-  def testFollowLinkWrite(self):
-    link_path = '/foo/bar/TBD'
-    target = '/tarJAY'
-    target_contents = 'real baz contents'
-    self.filesystem.CreateLink(link_path, target)
-    self.assertFalse(self.filesystem.Exists(target))
-
-    fh = self.open(link_path, 'w')
-    fh.write(target_contents)
-    fh.close()
-    fh = self.open(target, 'r')
-    got_contents = fh.read()
-    fh.close()
-    self.assertEqual(target_contents, got_contents)
-
-  def testFollowIntraPathLinkWrite(self):
-    # Test a link in the middle of of a file path.
-    link_path = '/foo/build/local_machine/output/1'
-    target = '/tmp/output/1'
-    self.filesystem.CreateDirectory('/tmp/output')
-    self.filesystem.CreateLink('/foo/build/local_machine', '/tmp')
-    self.assertFalse(self.filesystem.Exists(link_path))
-    self.assertFalse(self.filesystem.Exists(target))
-
-    target_contents = 'real baz contents'
-    fh = self.open(link_path, 'w')
-    fh.write(target_contents)
-    fh.close()
-    fh = self.open(target, 'r')
-    got_contents = fh.read()
-    fh.close()
-    self.assertEqual(target_contents, got_contents)
-
-  def testFileDescriptorsForDifferentFiles(self):
-    first_path = 'some_file1'
-    second_path = 'some_file2'
-    third_path = 'some_file3'
-    self.filesystem.CreateFile(first_path, contents='contents here1')
-    self.filesystem.CreateFile(second_path, contents='contents here2')
-    self.filesystem.CreateFile(third_path, contents='contents here3')
-
-    fake_file1 = self.open(first_path, 'r')
-    fake_file2 = self.open(second_path, 'r')
-    fake_file3 = self.open(third_path, 'r')
-    self.assertEqual(0, fake_file1.fileno())
-    self.assertEqual(1, fake_file2.fileno())
-    self.assertEqual(2, fake_file3.fileno())
-
-  def testFileDescriptorsForTheSameFileAreDifferent(self):
-    first_path = 'some_file1'
-    second_path = 'some_file2'
-    self.filesystem.CreateFile(first_path, contents='contents here1')
-    self.filesystem.CreateFile(second_path, contents='contents here2')
-
-    fake_file1 = self.open(first_path, 'r')
-    fake_file2 = self.open(second_path, 'r')
-    fake_file1a = self.open(first_path, 'r')
-    self.assertEqual(0, fake_file1.fileno())
-    self.assertEqual(1, fake_file2.fileno())
-    self.assertEqual(2, fake_file1a.fileno())
-
-  def testReusedFileDescriptorsDoNotAffectOthers(self):
-    first_path = 'some_file1'
-    second_path = 'some_file2'
-    third_path = 'some_file3'
-    self.filesystem.CreateFile(first_path, contents='contents here1')
-    self.filesystem.CreateFile(second_path, contents='contents here2')
-    self.filesystem.CreateFile(third_path, contents='contents here3')
-
-    fake_file1 = self.open(first_path, 'r')
-    fake_file2 = self.open(second_path, 'r')
-    fake_file3 = self.open(third_path, 'r')
-    fake_file1a = self.open(first_path, 'r')
-    self.assertEqual(0, fake_file1.fileno())
-    self.assertEqual(1, fake_file2.fileno())
-    self.assertEqual(2, fake_file3.fileno())
-    self.assertEqual(3, fake_file1a.fileno())
-
-    fake_file1.close()
-    fake_file2.close()
-    fake_file2 = self.open(second_path, 'r')
-    fake_file1b = self.open(first_path, 'r')
-    self.assertEqual(0, fake_file2.fileno())
-    self.assertEqual(1, fake_file1b.fileno())
-    self.assertEqual(2, fake_file3.fileno())
-    self.assertEqual(3, fake_file1a.fileno())
-
-  def testIntertwinedReadWrite(self):
-    file_path = 'some_file'
-    self.filesystem.CreateFile(file_path)
-    with self.open(file_path, 'a') as writer:
-      with self.open(file_path, 'r') as reader:
-        writes = ['hello', 'world\n', 'somewhere\nover', 'the\n', 'rainbow']
-        reads = []
-        # when writes are flushes, they are piped to the reader
-        for write in writes:
-          writer.write(write)
-          writer.flush()
-          reads.append(reader.read())
-          reader.flush()
-        self.assertEqual(writes, reads)
-        writes = ['nothing', 'to\nsee', 'here']
-        reads = []
-        # when writes are not flushed, the reader doesn't read anything new
-        for write in writes:
-          writer.write(write)
-          reads.append(reader.read())
-        self.assertEqual(['' for _ in writes], reads)
-
-  def testOpenIoErrors(self):
-    file_path = 'some_file'
-    self.filesystem.CreateFile(file_path)
-
-    with self.open(file_path, 'a') as fh:
-      self.assertRaises(IOError, fh.read)
-      self.assertRaises(IOError, fh.readlines)
-    with self.open(file_path, 'w') as fh:
-      self.assertRaises(IOError, fh.read)
-      self.assertRaises(IOError, fh.readlines)
-    with self.open(file_path, 'r') as fh:
-      self.assertRaises(IOError, fh.truncate)
-      self.assertRaises(IOError, fh.write, 'contents')
-      self.assertRaises(IOError, fh.writelines, ['con', 'tents'])
-
-    def _IteratorOpen(file_path, mode):
-      for _ in self.open(file_path, mode):
-        pass
-    self.assertRaises(IOError, _IteratorOpen, file_path, 'w')
-    self.assertRaises(IOError, _IteratorOpen, file_path, 'a')
-
-
-class OpenWithFileDescriptorTest(FakeFileOpenTestBase):
-
-  @unittest.skipIf(sys.version_info < (3, 0), 'only tested on 3.0 or greater')
-  def testOpenWithFileDescriptor(self):
-    file_path = 'this/file'
-    self.filesystem.CreateFile(file_path)
-    fd = self.os.open(file_path, os.O_CREAT)
-    self.assertEqual(fd, self.open(fd, 'r').fileno())
-
-  @unittest.skipIf(sys.version_info < (3, 0), 'only tested on 3.0 or greater')
-  def testClosefdWithFileDescriptor(self):
-    file_path = 'this/file'
-    self.filesystem.CreateFile(file_path)
-    fd = self.os.open(file_path, os.O_CREAT)
-    fh = self.open(fd, 'r', closefd=False)
-    fh.close()
-    self.assertIsNotNone(self.filesystem.open_files[fd])
-    fh = self.open(fd, 'r', closefd=True)
-    fh.close()
-    self.assertIsNone(self.filesystem.open_files[fd])
-
-
-class OpenWithBinaryFlagsTest(TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.file = fake_filesystem.FakeFileOpen(self.filesystem)
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-    self.file_path = 'some_file'
-    self.file_contents = b'binary contents'
-    self.filesystem.CreateFile(self.file_path, contents=self.file_contents)
-
-  def OpenFakeFile(self, mode):
-    return self.file(self.file_path, mode=mode)
-
-  def OpenFileAndSeek(self, mode):
-    fake_file = self.file(self.file_path, mode=mode)
-    fake_file.seek(0, 2)
-    return fake_file
-
-  def WriteAndReopenFile(self, fake_file, mode='rb'):
-    fake_file.write(self.file_contents)
-    fake_file.close()
-    return self.file(self.file_path, mode=mode)
-
-  def testReadBinary(self):
-    fake_file = self.OpenFakeFile('rb')
-    self.assertEqual(self.file_contents, fake_file.read())
-
-  def testWriteBinary(self):
-    fake_file = self.OpenFileAndSeek('wb')
-    self.assertEqual(0, fake_file.tell())
-    fake_file = self.WriteAndReopenFile(fake_file, mode='rb')
-    self.assertEqual(self.file_contents, fake_file.read())
-    # reopen the file in text mode
-    fake_file = self.OpenFakeFile('wb')
-    fake_file = self.WriteAndReopenFile(fake_file, mode='r')
-    self.assertEqual(self.file_contents.decode('ascii'), fake_file.read())
-
-  def testWriteAndReadBinary(self):
-    fake_file = self.OpenFileAndSeek('w+b')
-    self.assertEqual(0, fake_file.tell())
-    fake_file = self.WriteAndReopenFile(fake_file, mode='rb')
-    self.assertEqual(self.file_contents, fake_file.read())
-
-
-class OpenWithIgnoredFlagsTest(TestCase):
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.file = fake_filesystem.FakeFileOpen(self.filesystem)
-    self.os = fake_filesystem.FakeOsModule(self.filesystem)
-    self.file_path = 'some_file'
-    self.read_contents = self.file_contents = 'two\r\nlines'
-    # For python 3.x, text file newlines are converted to \n
-    if sys.version_info >= (3, 0):
-      self.read_contents = 'two\nlines'
-    self.filesystem.CreateFile(self.file_path, contents=self.file_contents)
-    # It's resonable to assume the file exists at this point
-
-  def OpenFakeFile(self, mode):
-    return self.file(self.file_path, mode=mode)
-
-  def OpenFileAndSeek(self, mode):
-    fake_file = self.file(self.file_path, mode=mode)
-    fake_file.seek(0, 2)
-    return fake_file
-
-  def WriteAndReopenFile(self, fake_file, mode='r'):
-    fake_file.write(self.file_contents)
-    fake_file.close()
-    return self.file(self.file_path, mode=mode)
-
-  def testReadText(self):
-    fake_file = self.OpenFakeFile('rt')
-    self.assertEqual(self.read_contents, fake_file.read())
-
-  def testReadUniversalNewlines(self):
-    fake_file = self.OpenFakeFile('rU')
-    self.assertEqual(self.read_contents, fake_file.read())
-
-  def testUniversalNewlines(self):
-    fake_file = self.OpenFakeFile('U')
-    self.assertEqual(self.read_contents, fake_file.read())
-
-  def testWriteText(self):
-    fake_file = self.OpenFileAndSeek('wt')
-    self.assertEqual(0, fake_file.tell())
-    fake_file = self.WriteAndReopenFile(fake_file)
-    self.assertEqual(self.read_contents, fake_file.read())
-
-  def testWriteAndReadTextBinary(self):
-    fake_file = self.OpenFileAndSeek('w+bt')
-    self.assertEqual(0, fake_file.tell())
-    if sys.version_info >= (3, 0):
-      self.assertRaises(TypeError, fake_file.write, self.file_contents)
-    else:
-      fake_file = self.WriteAndReopenFile(fake_file, mode='rb')
-      self.assertEqual(self.file_contents, fake_file.read())
-
-
-class OpenWithInvalidFlagsTest(FakeFileOpenTestBase):
-
-  def testCapitalR(self):
-    self.assertRaises(IOError, self.file, 'some_file', 'R')
-
-  def testCapitalW(self):
-    self.assertRaises(IOError, self.file, 'some_file', 'W')
-
-  def testCapitalA(self):
-    self.assertRaises(IOError, self.file, 'some_file', 'A')
-
-  def testLowerU(self):
-    self.assertRaises(IOError, self.file, 'some_file', 'u')
-
-  def testLowerRw(self):
-    self.assertRaises(IOError, self.file, 'some_file', 'rw')
-
-
-class ResolvePathTest(FakeFileOpenTestBase):
-
-  def __WriteToFile(self, file_name):
-    fh = self.open(file_name, 'w')
-    fh.write('x')
-    fh.close()
-
-  def testNoneFilepathRaisesTypeError(self):
-    self.assertRaises(TypeError, self.open, None, 'w')
-
-  def testEmptyFilepathRaisesIOError(self):
-    self.assertRaises(IOError, self.open, '', 'w')
-
-  def testNormalPath(self):
-    self.__WriteToFile('foo')
-    self.assertTrue(self.filesystem.Exists('foo'))
-
-  def testLinkWithinSameDirectory(self):
-    final_target = '/foo/baz'
-    self.filesystem.CreateLink('/foo/bar', 'baz')
-    self.__WriteToFile('/foo/bar')
-    self.assertTrue(self.filesystem.Exists(final_target))
-    self.assertEqual(1, self.os.stat(final_target)[stat.ST_SIZE])
-
-  def testLinkToSubDirectory(self):
-    final_target = '/foo/baz/bip'
-    self.filesystem.CreateDirectory('/foo/baz')
-    self.filesystem.CreateLink('/foo/bar', 'baz/bip')
-    self.__WriteToFile('/foo/bar')
-    self.assertTrue(self.filesystem.Exists(final_target))
-    self.assertEqual(1, self.os.stat(final_target)[stat.ST_SIZE])
-    self.assertTrue(self.filesystem.Exists('/foo/baz'))
-    # Make sure that intermediate directory got created.
-    new_dir = self.filesystem.GetObject('/foo/baz')
-    self.assertTrue(stat.S_IFDIR & new_dir.st_mode)
-
-  def testLinkToParentDirectory(self):
-    final_target = '/baz/bip'
-    self.filesystem.CreateDirectory('/foo')
-    self.filesystem.CreateDirectory('/baz')
-    self.filesystem.CreateLink('/foo/bar', '../baz')
-    self.__WriteToFile('/foo/bar/bip')
-    self.assertTrue(self.filesystem.Exists(final_target))
-    self.assertEqual(1, self.os.stat(final_target)[stat.ST_SIZE])
-    self.assertTrue(self.filesystem.Exists('/foo/bar'))
-
-  def testLinkToAbsolutePath(self):
-    final_target = '/foo/baz/bip'
-    self.filesystem.CreateDirectory('/foo/baz')
-    self.filesystem.CreateLink('/foo/bar', final_target)
-    self.__WriteToFile('/foo/bar')
-    self.assertTrue(self.filesystem.Exists(final_target))
-
-  def testRelativeLinksWorkAfterChdir(self):
-    final_target = '/foo/baz/bip'
-    self.filesystem.CreateDirectory('/foo/baz')
-    self.filesystem.CreateLink('/foo/bar', './baz/bip')
-    self.assertEqual(final_target,
-                     self.filesystem.ResolvePath('/foo/bar'))
-
-    os_module = fake_filesystem.FakeOsModule(self.filesystem)
-    self.assertTrue(os_module.path.islink('/foo/bar'))
-    os_module.chdir('/foo')
-    self.assertEqual('/foo', os_module.getcwd())
-    self.assertTrue(os_module.path.islink('bar'))
-
-    self.assertEqual('/foo/baz/bip',
-                     self.filesystem.ResolvePath('bar'))
-
-    self.__WriteToFile('/foo/bar')
-    self.assertTrue(self.filesystem.Exists(final_target))
-
-  def testAbsoluteLinksWorkAfterChdir(self):
-    final_target = '/foo/baz/bip'
-    self.filesystem.CreateDirectory('/foo/baz')
-    self.filesystem.CreateLink('/foo/bar', final_target)
-    self.assertEqual(final_target,
-                     self.filesystem.ResolvePath('/foo/bar'))
-
-    os_module = fake_filesystem.FakeOsModule(self.filesystem)
-    self.assertTrue(os_module.path.islink('/foo/bar'))
-    os_module.chdir('/foo')
-    self.assertEqual('/foo', os_module.getcwd())
-    self.assertTrue(os_module.path.islink('bar'))
-
-    self.assertEqual('/foo/baz/bip',
-                     self.filesystem.ResolvePath('bar'))
-
-    self.__WriteToFile('/foo/bar')
-    self.assertTrue(self.filesystem.Exists(final_target))
-
-  def testChdirThroughRelativeLink(self):
-    self.filesystem.CreateDirectory('/x/foo')
-    self.filesystem.CreateDirectory('/x/bar')
-    self.filesystem.CreateLink('/x/foo/bar', '../bar')
-    self.assertEqual('/x/bar', self.filesystem.ResolvePath('/x/foo/bar'))
-
-    os_module = fake_filesystem.FakeOsModule(self.filesystem)
-    os_module.chdir('/x/foo')
-    self.assertEqual('/x/foo', os_module.getcwd())
-    self.assertEqual('/x/bar', self.filesystem.ResolvePath('bar'))
-
-    os_module.chdir('bar')
-    self.assertEqual('/x/bar', os_module.getcwd())
-
-  def testReadLinkToLink(self):
-    # Write into the final link target and read back from a file which will
-    # point to that.
-    self.filesystem.CreateLink('/foo/bar', 'link')
-    self.filesystem.CreateLink('/foo/link', 'baz')
-    self.__WriteToFile('/foo/baz')
-    fh = self.open('/foo/bar', 'r')
-    self.assertEqual('x', fh.read())
-
-  def testWriteLinkToLink(self):
-    final_target = '/foo/baz'
-    self.filesystem.CreateLink('/foo/bar', 'link')
-    self.filesystem.CreateLink('/foo/link', 'baz')
-    self.__WriteToFile('/foo/bar')
-    self.assertTrue(self.filesystem.Exists(final_target))
-
-  def testMultipleLinks(self):
-    final_target = '/a/link1/c/link2/e'
-    self.os.makedirs('/a/link1/c/link2')
-
-    self.filesystem.CreateLink('/a/b', 'link1')
-    self.assertEqual('/a/link1', self.filesystem.ResolvePath('/a/b'))
-    self.assertEqual('/a/link1/c', self.filesystem.ResolvePath('/a/b/c'))
-
-    self.filesystem.CreateLink('/a/link1/c/d', 'link2')
-    self.assertTrue(self.filesystem.Exists('/a/link1/c/d'))
-    self.assertTrue(self.filesystem.Exists('/a/b/c/d'))
-
-    final_target = '/a/link1/c/link2/e'
-    self.assertFalse(self.filesystem.Exists(final_target))
-    self.__WriteToFile('/a/b/c/d/e')
-    self.assertTrue(self.filesystem.Exists(final_target))
-
-  def testTooManyLinks(self):
-    self.filesystem.CreateLink('/a/loop', 'loop')
-    self.assertFalse(self.filesystem.Exists('/a/loop'))
-
-
-class PathManipulationTests(TestCase):
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='|')
-
-
-class CollapsePathPipeSeparatorTest(PathManipulationTests):
-  """Tests CollapsePath (mimics os.path.normpath) using | as path separator."""
-
-  def testEmptyPathBecomesDotPath(self):
-    self.assertEqual('.', self.filesystem.CollapsePath(''))
-
-  def testDotPathUnchanged(self):
-    self.assertEqual('.', self.filesystem.CollapsePath('.'))
-
-  def testSlashesAreNotCollapsed(self):
-    """Tests that '/' is not treated specially if the path separator is '|'.
-
-    In particular, multiple slashes should not be collapsed.
-    """
-    self.assertEqual('/', self.filesystem.CollapsePath('/'))
-    self.assertEqual('/////', self.filesystem.CollapsePath('/////'))
-
-  def testRootPath(self):
-    self.assertEqual('|', self.filesystem.CollapsePath('|'))
-
-  def testMultipleSeparatorsCollapsedIntoRootPath(self):
-    self.assertEqual('|', self.filesystem.CollapsePath('|||||'))
-
-  def testAllDotPathsRemovedButOne(self):
-    self.assertEqual('.', self.filesystem.CollapsePath('.|.|.|.'))
-
-  def testAllDotPathsRemovedIfAnotherPathComponentExists(self):
-    self.assertEqual('|', self.filesystem.CollapsePath('|.|.|.|'))
-    self.assertEqual('foo|bar', self.filesystem.CollapsePath('foo|.|.|.|bar'))
-
-  def testIgnoresUpLevelReferencesStartingFromRoot(self):
-    self.assertEqual('|', self.filesystem.CollapsePath('|..|..|..|'))
-    self.assertEqual('|', self.filesystem.CollapsePath('||..|.|..||'))
-    self.assertEqual(
-        '|', self.filesystem.CollapsePath('|..|..|foo|bar|..|..|'))
-
-  def testConservesUpLevelReferencesStartingFromCurrentDirectory(self):
-    self.assertEqual(
-        '..|..', self.filesystem.CollapsePath('..|foo|bar|..|..|..'))
-
-  def testCombineDotAndUpLevelReferencesInAbsolutePath(self):
-    self.assertEqual(
-        '|yes', self.filesystem.CollapsePath('|||||.|..|||yes|no|..|.|||'))
-
-  def testDotsInPathCollapsesToLastPath(self):
-    self.assertEqual(
-        'bar', self.filesystem.CollapsePath('foo|..|bar'))
-    self.assertEqual(
-        'bar', self.filesystem.CollapsePath('foo|..|yes|..|no|..|bar'))
-
-
-class SplitPathTest(PathManipulationTests):
-  """Tests SplitPath (which mimics os.path.split) using | as path separator."""
-
-  def testEmptyPath(self):
-    self.assertEqual(('', ''), self.filesystem.SplitPath(''))
-
-  def testNoSeparators(self):
-    self.assertEqual(('', 'ab'), self.filesystem.SplitPath('ab'))
-
-  def testSlashesDoNotSplit(self):
-    """Tests that '/' is not treated specially if the path separator is '|'."""
-    self.assertEqual(('', 'a/b'), self.filesystem.SplitPath('a/b'))
-
-  def testEliminateTrailingSeparatorsFromHead(self):
-    self.assertEqual(('a', 'b'), self.filesystem.SplitPath('a|b'))
-    self.assertEqual(('a', 'b'), self.filesystem.SplitPath('a|||b'))
-    self.assertEqual(('|a', 'b'), self.filesystem.SplitPath('|a||b'))
-    self.assertEqual(('a|b', 'c'), self.filesystem.SplitPath('a|b|c'))
-    self.assertEqual(('|a|b', 'c'), self.filesystem.SplitPath('|a|b|c'))
-
-  def testRootSeparatorIsNotStripped(self):
-    self.assertEqual(('|', ''), self.filesystem.SplitPath('|||'))
-    self.assertEqual(('|', 'a'), self.filesystem.SplitPath('|a'))
-    self.assertEqual(('|', 'a'), self.filesystem.SplitPath('|||a'))
-
-  def testEmptyTailIfPathEndsInSeparator(self):
-    self.assertEqual(('a|b', ''), self.filesystem.SplitPath('a|b|'))
-
-  def testEmptyPathComponentsArePreservedInHead(self):
-    self.assertEqual(('|a||b', 'c'), self.filesystem.SplitPath('|a||b||c'))
-
-
-class JoinPathTest(PathManipulationTests):
-  """Tests JoinPath (which mimics os.path.join) using | as path separator."""
-
-  def testOneEmptyComponent(self):
-    self.assertEqual('', self.filesystem.JoinPaths(''))
-
-  def testMultipleEmptyComponents(self):
-    self.assertEqual('', self.filesystem.JoinPaths('', '', ''))
-
-  def testSeparatorsNotStrippedFromSingleComponent(self):
-    self.assertEqual('||a||', self.filesystem.JoinPaths('||a||'))
-
-  def testOneSeparatorAddedBetweenComponents(self):
-    self.assertEqual('a|b|c|d', self.filesystem.JoinPaths('a', 'b', 'c', 'd'))
-
-  def testNoSeparatorAddedForComponentsEndingInSeparator(self):
-    self.assertEqual('a|b|c', self.filesystem.JoinPaths('a|', 'b|', 'c'))
-    self.assertEqual('a|||b|||c',
-                     self.filesystem.JoinPaths('a|||', 'b|||', 'c'))
-
-  def testComponentsPrecedingAbsoluteComponentAreIgnored(self):
-    self.assertEqual('|c|d', self.filesystem.JoinPaths('a', '|b', '|c', 'd'))
-
-  def testOneSeparatorAddedForTrailingEmptyComponents(self):
-    self.assertEqual('a|', self.filesystem.JoinPaths('a', ''))
-    self.assertEqual('a|', self.filesystem.JoinPaths('a', '', ''))
-
-  def testNoSeparatorAddedForLeadingEmptyComponents(self):
-    self.assertEqual('a', self.filesystem.JoinPaths('', 'a'))
-
-  def testInternalEmptyComponentsIgnored(self):
-    self.assertEqual('a|b', self.filesystem.JoinPaths('a', '', 'b'))
-    self.assertEqual('a|b|', self.filesystem.JoinPaths('a|', '', 'b|'))
-
-
-class PathSeparatorTest(TestCase):
-  def testOsPathSepMatchesFakeFilesystemSeparator(self):
-    filesystem = fake_filesystem.FakeFilesystem(path_separator='!')
-    fake_os = fake_filesystem.FakeOsModule(filesystem)
-    self.assertEqual('!', fake_os.sep)
-    self.assertEqual('!', fake_os.path.sep)
-
-
-if __name__ == '__main__':
-  main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_unittest.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_unittest.py
deleted file mode 100644
index 692fb2f..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_unittest.py
+++ /dev/null
@@ -1,226 +0,0 @@
-# Copyright 2014 Altera Corporation. All Rights Reserved.
-# Copyright 2015 John McGehee
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""A base class for unit tests using the :py:class:`pyfakefs` module.
-
-This class searches `sys.modules` for modules that import the `os`, `glob`,
-`shutil`, and `tempfile` modules.
-
-The `setUp()` method binds these modules to the corresponding fake
-modules from `pyfakefs`.  Further, the built in functions `file()` and
-`open()` are bound to fake functions.
-
-The `tearDownPyfakefs()` method returns the module bindings to their original
-state.
-
-It is expected that `setUp()` be invoked at the beginning of the derived
-class' `setUp()` method, and `tearDownPyfakefs()` be invoked at the end of the
-derived class' `tearDown()` method.
-
-During the test, everything uses the fake file system and modules.  This means
-that even in your test, you can use familiar functions like `open()` and
-`os.makedirs()` to manipulate the fake file system.
-
-This also means existing unit tests that use the real file system can be
-retrofitted to use `pyfakefs` by simply changing their base class from
-`:py:class`unittest.TestCase` to
-`:py:class`pyfakefs.fake_filesystem_unittest.TestCase`.
-"""
-
-import sys
-import unittest
-import doctest
-import fake_filesystem
-import fake_filesystem_glob
-import fake_filesystem_shutil
-import fake_tempfile
-if sys.version_info < (3,):
-    import __builtin__ as builtins
-else:
-    import builtins
-
-import mox3.stubout
-
-def load_doctests(loader, tests, ignore, module):
-    '''Load the doctest tests for the specified module into unittest.'''
-    _patcher = Patcher()
-    globs = _patcher.replaceGlobs(vars(module))
-    tests.addTests(doctest.DocTestSuite(module,
-                                        globs=globs,
-                                        setUp=_patcher.setUp,
-                                        tearDown=_patcher.tearDown))
-    return tests
-
-
-class TestCase(unittest.TestCase):
-    def __init__(self, methodName='runTest'):
-        super(TestCase, self).__init__(methodName)
-        self._stubber = Patcher()
-        
-    @property
-    def fs(self):
-        return self._stubber.fs
-    
-    @property
-    def patches(self):
-        return self._stubber.patches
-        
-    def setUpPyfakefs(self):
-        '''Bind the file-related modules to the :py:class:`pyfakefs` fake file
-        system instead of the real file system.  Also bind the fake `file()` and
-        `open()` functions.
-        
-        Invoke this at the beginning of the `setUp()` method in your unit test
-        class.
-        '''
-        self._stubber.setUp()
-        self.addCleanup(self._stubber.tearDown)
-
-    
-    def tearDownPyfakefs(self):
-        ''':meth:`pyfakefs.fake_filesystem_unittest.setUpPyfakefs` registers the
-        tear down procedure using :meth:`unittest.TestCase.addCleanup`.  Thus this
-        method is deprecated, and remains just for backward compatibility.
-        '''
-        pass
-
-class Patcher(object):
-    '''
-    Instantiate a stub creator to bind and un-bind the file-related modules to
-    the :py:mod:`pyfakefs` fake modules.
-    '''
-    SKIPMODULES = set([None, fake_filesystem, fake_filesystem_glob,
-                      fake_filesystem_shutil, fake_tempfile, sys])
-    '''Stub nothing that is imported within these modules.
-    `sys` is included to prevent `sys.path` from being stubbed with the fake
-    `os.path`.
-    '''
-    assert None in SKIPMODULES, "sys.modules contains 'None' values; must skip them."
-    
-    SKIPNAMES = set(['os', 'glob', 'path', 'shutil', 'tempfile'])
-        
-    def __init__(self):
-        # Attributes set by _findModules()
-        self._osModules = None
-        self._globModules = None
-        self._pathModules = None
-        self._shutilModules = None
-        self._tempfileModules = None
-        self._findModules()
-        assert None not in vars(self).values(), \
-                "_findModules() missed the initialization of an instance variable"
-        
-        # Attributes set by _refresh()
-        self._stubs = None
-        self.fs = None
-        self.fake_os = None
-        self.fake_glob = None
-        self.fake_path = None
-        self.fake_shutil = None
-        self.fake_tempfile_ = None
-        self.fake_open = None
-        # _isStale is set by tearDown(), reset by _refresh()
-        self._isStale = True
-        self._refresh()
-        assert None not in vars(self).values(), \
-                "_refresh() missed the initialization of an instance variable"
-        assert self._isStale == False, "_refresh() did not reset _isStale"
-        
-    def _findModules(self):
-        '''Find and cache all modules that import file system modules.
-        Later, `setUp()` will stub these with the fake file system
-        modules.
-        '''
-        self._osModules = set()
-        self._globModules = set()
-        self._pathModules = set()
-        self._shutilModules = set()
-        self._tempfileModules = set()
-        for name, module in set(sys.modules.items()):
-            if module in self.SKIPMODULES or name in self.SKIPNAMES:
-                continue
-            if 'os' in module.__dict__:
-                self._osModules.add(module)
-            if 'glob' in module.__dict__:
-                self._globModules.add(module)
-            if 'path' in module.__dict__:
-                self._pathModules.add(module)
-            if 'shutil' in module.__dict__:
-                self._shutilModules.add(module)
-            if 'tempfile' in module.__dict__:
-                self._tempfileModules.add(module)
-
-    def _refresh(self):
-        '''Renew the fake file system and set the _isStale flag to `False`.'''
-        if self._stubs is not None:
-            self._stubs.SmartUnsetAll()
-        self._stubs = mox3.stubout.StubOutForTesting()
-
-        self.fs = fake_filesystem.FakeFilesystem()
-        self.fake_os = fake_filesystem.FakeOsModule(self.fs)
-        self.fake_glob = fake_filesystem_glob.FakeGlobModule(self.fs)
-        self.fake_path = self.fake_os.path
-        self.fake_shutil = fake_filesystem_shutil.FakeShutilModule(self.fs)
-        self.fake_tempfile_ = fake_tempfile.FakeTempfileModule(self.fs)
-        self.fake_open = fake_filesystem.FakeFileOpen(self.fs)
-
-        self._isStale = False
-
-    def setUp(self, doctester=None):
-        '''Bind the file-related modules to the :py:mod:`pyfakefs` fake
-        modules real ones.  Also bind the fake `file()` and `open()` functions.
-        '''
-        if self._isStale:
-            self._refresh()
-        
-        if doctester is not None:
-            doctester.globs = self.replaceGlobs(doctester.globs)
-            
-        if sys.version_info < (3,):
-            # No file() in Python3
-            self._stubs.SmartSet(builtins, 'file', self.fake_open)
-        self._stubs.SmartSet(builtins, 'open', self.fake_open)
-        
-        for module in self._osModules:
-            self._stubs.SmartSet(module,  'os', self.fake_os)
-        for module in self._globModules:
-            self._stubs.SmartSet(module,  'glob', self.fake_glob)
-        for module in self._pathModules:
-            self._stubs.SmartSet(module,  'path', self.fake_path)
-        for module in self._shutilModules:
-            self._stubs.SmartSet(module,  'shutil', self.fake_shutil)
-        for module in self._tempfileModules:
-            self._stubs.SmartSet(module,  'tempfile', self.fake_tempfile_)
-    
-    def replaceGlobs(self, globs_):
-        globs = globs_.copy()
-        if self._isStale:
-            self._refresh()
-        if 'os' in globs:
-            globs['os'] = fake_filesystem.FakeOsModule(self.fs)
-        if 'glob' in globs:
-            globs['glob'] = fake_filesystem_glob.FakeGlobModule(self.fs)
-        if 'path' in globs:
-            globs['path'] =  fake_filesystem.FakePathModule(self.fs)
-        if 'shutil' in globs:
-            globs['shutil'] = fake_filesystem_shutil.FakeShutilModule(self.fs)
-        if 'tempfile' in globs:
-            globs['tempfile'] = fake_tempfile.FakeTempfileModule(self.fs)
-        return globs
-    
-    def tearDown(self, doctester=None):
-        '''Clear the fake filesystem bindings created by `setUp()`.'''
-        self._isStale = True
-        self._stubs.SmartUnsetAll()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_unittest_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_unittest_test.py
deleted file mode 100644
index 7d0ac70..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_unittest_test.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2014 Altera Corporation. All Rights Reserved.
-# Author: John McGehee
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""
-Test the :py:class`pyfakefs.fake_filesystem_unittest.TestCase` base class.
-"""
-
-import os
-import glob
-import shutil
-import tempfile
-import sys
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-import fake_filesystem_unittest
-import pytest
-
-class TestPyfakefsUnittest(fake_filesystem_unittest.TestCase): # pylint: disable=R0904
-    '''Test the pyfakefs.fake_filesystem_unittest.TestCase` base class.'''
-
-    def setUp(self):
-        '''Set up the fake file system'''
-        self.setUpPyfakefs()
-
-    def tearDown(self):
-        '''Tear down the fake file system'''
-        self.tearDownPyfakefs()
-
-    @unittest.skipIf(sys.version_info > (2,), "file() was removed in Python 3")
-    def test_file(self):
-        '''Fake `file()` function is bound'''
-        self.assertFalse(os.path.exists('/fake_file.txt'))
-        with file('/fake_file.txt', 'w') as f:
-            f.write("This test file was created using the file() function.\n")
-        self.assertTrue(self.fs.Exists('/fake_file.txt'))
-        with file('/fake_file.txt') as f:
-            content = f.read()
-        self.assertEqual(content,
-                         'This test file was created using the file() function.\n')
-            
-    def test_open(self):
-        '''Fake `open()` function is bound'''
-        self.assertFalse(os.path.exists('/fake_file.txt'))
-        with open('/fake_file.txt', 'w') as f:
-            f.write("This test file was created using the open() function.\n")
-        self.assertTrue(self.fs.Exists('/fake_file.txt'))
-        with open('/fake_file.txt') as f:
-            content = f.read()
-        self.assertEqual(content,
-                         'This test file was created using the open() function.\n')
-            
-    def test_os(self):
-        '''Fake os module is bound'''
-        self.assertFalse(self.fs.Exists('/test/dir1/dir2'))          
-        os.makedirs('/test/dir1/dir2')
-        self.assertTrue(self.fs.Exists('/test/dir1/dir2'))          
-        
-    def test_glob(self):
-        '''Fake glob module is bound'''
-        self.assertCountEqual(glob.glob('/test/dir1/dir*'),
-                              [])
-        self.fs.CreateDirectory('/test/dir1/dir2a')
-        self.assertCountEqual(glob.glob('/test/dir1/dir*'),
-                              ['/test/dir1/dir2a'])
-        self.fs.CreateDirectory('/test/dir1/dir2b')
-        self.assertCountEqual(glob.glob('/test/dir1/dir*'),
-                              ['/test/dir1/dir2a', '/test/dir1/dir2b'])
-
-    def test_shutil(self):
-        '''Fake shutil module is bound'''
-        self.fs.CreateDirectory('/test/dir1/dir2a')
-        self.fs.CreateDirectory('/test/dir1/dir2b')
-        self.assertTrue(self.fs.Exists('/test/dir1/dir2b'))
-        self.assertTrue(self.fs.Exists('/test/dir1/dir2a'))
-       
-        shutil.rmtree('/test/dir1')
-        self.assertFalse(self.fs.Exists('/test/dir1'))
-
-    def test_tempfile(self):
-        '''Fake tempfile module is bound'''
-        with tempfile.NamedTemporaryFile() as tf:
-            tf.write(b'Temporary file contents\n')
-            name = tf.name
-            self.assertTrue(self.fs.Exists(tf.name))
-    
-    def test_pytest(self):
-        '''Compatibility with the :py:module:`pytest` module.'''
-        pass
-                      
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_vs_real_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_vs_real_test.py
deleted file mode 100755
index 9da1bc8..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_filesystem_vs_real_test.py
+++ /dev/null
@@ -1,612 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#            http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Test that FakeFilesystem calls work identically to a real filesystem."""
-
-#pylint: disable-all
-
-import os #@UnusedImport
-import os.path
-import shutil
-import sys
-import tempfile
-import time
-import sys
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-
-import fake_filesystem
-
-
-def Sep(path):
-    """Converts slashes in the path to the architecture's path seperator."""
-    if isinstance(path, str):
-        return path.replace('/', os.sep)
-    return path
-
-
-class TestCase(unittest.TestCase):
-    is_windows = sys.platform.startswith('win')
-    is_cygwin = sys.platform == 'cygwin'
-    _FAKE_FS_BASE = Sep('/fakefs')
-
-
-class FakeFilesystemVsRealTest(TestCase):
-
-    def _Paths(self, path):
-        """For a given path, return paths in the real and fake filesystems."""
-        if not path:
-            return (None, None)
-        return (os.path.join(self.real_base, path),
-                        os.path.join(self.fake_base, path))
-
-    def _CreateTestFile(self, file_type, path, contents=None):
-        """Create a dir, file, or link in both the real fs and the fake."""
-        path = Sep(path)
-        self._created_files.append([file_type, path, contents])
-        real_path, fake_path = self._Paths(path)
-        if file_type == 'd':
-            os.mkdir(real_path)
-            self.fake_os.mkdir(fake_path)
-        if file_type == 'f':
-            fh = open(real_path, 'w')
-            fh.write(contents or '')
-            fh.close()
-            fh = self.fake_open(fake_path, 'w')
-            fh.write(contents or '')
-            fh.close()
-        # b for binary file
-        if file_type == 'b':
-            fh = open(real_path, 'wb')
-            fh.write(contents or '')
-            fh.close()
-            fh = self.fake_open(fake_path, 'wb')
-            fh.write(contents or '')
-            fh.close()
-        # l for symlink, h for hard link
-        if file_type in ('l', 'h'):
-            real_target, fake_target = (contents, contents)
-            # If it begins with '/', make it relative to the base.    You can't go
-            # creating files in / for the real file system.
-            if contents.startswith(os.sep):
-                real_target, fake_target = self._Paths(contents[1:])
-            if file_type == 'l':
-                os.symlink(real_target, real_path)
-                self.fake_os.symlink(fake_target, fake_path)
-            elif file_type == 'h':
-                os.link(real_target, real_path)
-                self.fake_os.link(fake_target, fake_path)
-
-    def setUp(self):
-        # Base paths in the real and test file systems.     We keep them different
-        # so that missing features in the fake don't fall through to the base
-        # operations and magically succeed.
-        tsname = 'fakefs.%s' % time.time()
-        # Fully expand the base_path - required on OS X.
-        self.real_base = os.path.realpath(
-                os.path.join(tempfile.gettempdir(), tsname))
-        os.chdir(tempfile.gettempdir())
-        if os.path.isdir(self.real_base):
-            shutil.rmtree(self.real_base)
-        os.mkdir(self.real_base)
-        self.fake_base = self._FAKE_FS_BASE
-
-        # Make sure we can write to the physical testing temp directory.
-        self.assertTrue(os.access(self.real_base, os.W_OK))
-
-        self.fake_filesystem = fake_filesystem.FakeFilesystem()
-        self.fake_filesystem.CreateDirectory(self.fake_base)
-        self.fake_os = fake_filesystem.FakeOsModule(self.fake_filesystem)
-        self.fake_open = fake_filesystem.FakeFileOpen(self.fake_filesystem)
-        self._created_files = []
-
-        os.chdir(self.real_base)
-        self.fake_os.chdir(self.fake_base)
-
-    def tearDown(self):
-        # We have to remove all the files from the real FS. Doing the same for the
-        # fake FS is optional, but doing it is an extra sanity check.
-        os.chdir(tempfile.gettempdir())
-        try:
-            rev_files = self._created_files[:]
-            rev_files.reverse()
-            for info in rev_files:
-                real_path, fake_path = self._Paths(info[1])
-                if info[0] == 'd':
-                    try:
-                        os.rmdir(real_path)
-                    except OSError as e:
-                        if 'Directory not empty' in e:
-                            self.fail('Real path %s not empty: %s : %s' % (
-                                    real_path, e, os.listdir(real_path)))
-                        else:
-                            raise
-                    self.fake_os.rmdir(fake_path)
-                if info[0] == 'f' or info[0] == 'l':
-                    os.remove(real_path)
-                    self.fake_os.remove(fake_path)
-        finally:
-            shutil.rmtree(self.real_base)
-
-    def _GetErrno(self, raised_error):
-        try:
-            return (raised_error and raised_error.errno) or None
-        except AttributeError:
-            return None
-
-    def _CompareBehaviors(self, method_name, path, real, fake,
-                                                method_returns_path=False):
-        """Invoke an os method in both real and fake contexts and compare results.
-
-        Invoke a real filesystem method with a path to a real file and invoke a fake
-        filesystem method with a path to a fake file and compare the results.    We
-        expect some calls to throw Exceptions, so we catch those and compare them.
-
-        Args:
-            method_name: Name of method being tested, for use in error messages.
-            path: potential path to a file in the real and fake file systems, passing
-                an empty tuple indicates that no arguments to pass to method.
-            real: built-in system library or method from the built-in system library
-                which takes a path as an arg and returns some value.
-            fake: fake_filsystem object or method from a fake_filesystem class
-                which takes a path as an arg and returns some value.
-            method_returns_path: True if the method returns a path, and thus we must
-                compensate for expected difference between real and fake.
-
-        Returns:
-            A description of the difference in behavior, or None.
-        """
-        # pylint: disable=C6403
-
-        def _ErrorClass(e):
-            return (e and e.__class__.__name__) or 'None'
-
-        real_value = None
-        fake_value = None
-        real_err = None
-        fake_err = None
-        method_call = '%s' % method_name
-        method_call += '()' if path == () else '(%s)' % path
-        # Catching Exception below gives a lint warning, but it's what we need.
-        try:
-            args = [] if path == () else [path]
-            real_method = real
-            if not callable(real):
-                real_method = getattr(real, method_name)
-            real_value = str(real_method(*args))
-        except Exception as e:    # pylint: disable-msg=W0703
-            real_err = e
-        try:
-            fake_method = fake
-            if not callable(fake):
-                fake_method = getattr(fake, method_name)
-            args = [] if path == () else [path]
-            fake_value = str(fake_method(*args))
-        except Exception as e:    # pylint: disable-msg=W0703
-            fake_err = e
-        # We only compare on the error class because the acutal error contents
-        # is almost always different because of the file paths.
-        if _ErrorClass(real_err) != _ErrorClass(fake_err):
-            if real_err is None:
-                return '%s: real version returned %s, fake raised %s' % (
-                        method_call, real_value, _ErrorClass(fake_err))
-            if fake_err is None:
-                return '%s: real version raised %s, fake returned %s' % (
-                        method_call, _ErrorClass(real_err), fake_value)
-            return '%s: real version raised %s, fake raised %s' % (
-                    method_call, _ErrorClass(real_err), _ErrorClass(fake_err))
-        real_errno = self._GetErrno(real_err)
-        fake_errno = self._GetErrno(fake_err)
-        if real_errno != fake_errno:
-            return '%s(%s): both raised %s, real errno %s, fake errno %s' % (
-                    method_name, path, _ErrorClass(real_err), real_errno, fake_errno)
-        # If the method is supposed to return a full path AND both values
-        # begin with the expected full path, then trim it off.
-        if method_returns_path:
-            if (real_value and fake_value
-                    and real_value.startswith(self.real_base)
-                    and fake_value.startswith(self.fake_base)):
-                real_value = real_value[len(self.real_base):]
-                fake_value = fake_value[len(self.fake_base):]
-        if real_value != fake_value:
-            return '%s: real return %s, fake returned %s' % (
-                    method_call, real_value, fake_value)
-        return None
-
-    def assertOsMethodBehaviorMatches(self, method_name, path,
-                                                                        method_returns_path=False):
-        """Invoke an os method in both real and fake contexts and compare.
-
-        For a given method name (from the os module) and a path, compare the
-        behavior of the system provided module against the fake_filesytem module.
-        We expect results and/or Exceptions raised to be identical.
-
-        Args:
-            method_name: Name of method being tested.
-            path: potential path to a file in the real and fake file systems.
-            method_returns_path: True if the method returns a path, and thus we must
-                compensate for expected difference between real and fake.
-
-        Returns:
-            A description of the difference in behavior, or None.
-        """
-        path = Sep(path)
-        return self._CompareBehaviors(method_name, path, os, self.fake_os,
-                                                                    method_returns_path)
-
-    def DiffOpenMethodBehavior(self, method_name, path, mode, data,
-                                                         method_returns_data=True):
-        """Invoke an open method in both real and fkae contexts and compare.
-
-        Args:
-            method_name: Name of method being tested.
-            path: potential path to a file in the real and fake file systems.
-            mode: how to open the file.
-            data: any data to pass to the method.
-            method_returns_data: True if a method returns some sort of data.
-
-        For a given method name (from builtin open) and a path, compare the
-        behavior of the system provided module against the fake_filesytem module.
-        We expect results and/or Exceptions raised to be identical.
-
-        Returns:
-            A description of the difference in behavior, or None.
-        """
-        with open(path, mode) as real_fh:
-            with self.fake_open(path, mode) as fake_fh:
-                return self._CompareBehaviors(method_name, data, real_fh, fake_fh,
-                                                                            method_returns_data)
-
-    def DiffOsPathMethodBehavior(self, method_name, path,
-                                                             method_returns_path=False):
-        """Invoke an os.path method in both real and fake contexts and compare.
-
-        For a given method name (from the os.path module) and a path, compare the
-        behavior of the system provided module against the fake_filesytem module.
-        We expect results and/or Exceptions raised to be identical.
-
-        Args:
-            method_name: Name of method being tested.
-            path: potential path to a file in the real and fake file systems.
-            method_returns_path: True if the method returns a path, and thus we must
-                compensate for expected difference between real and fake.
-
-        Returns:
-            A description of the difference in behavior, or None.
-        """
-        return self._CompareBehaviors(method_name, path, os.path, self.fake_os.path,
-                                                                    method_returns_path)
-
-    def assertOsPathMethodBehaviorMatches(self, method_name, path,
-                                                                                method_returns_path=False):
-        """Assert that an os.path behaves the same in both real and fake contexts.
-
-        Wraps DiffOsPathMethodBehavior, raising AssertionError if any differences
-        are reported.
-
-        Args:
-            method_name: Name of method being tested.
-            path: potential path to a file in the real and fake file systems.
-            method_returns_path: True if the method returns a path, and thus we must
-                compensate for expected difference between real and fake.
-
-        Raises:
-            AssertionError if there is any difference in behavior.
-        """
-        path = Sep(path)
-        diff = self.DiffOsPathMethodBehavior(method_name, path, method_returns_path)
-        if diff:
-            self.fail(diff)
-
-    def assertAllOsBehaviorsMatch(self, path):
-        path = Sep(path)
-        os_method_names = [] if self.is_windows else ['readlink']
-        os_method_names_no_args = ['getcwd']
-        if sys.version_info < (3, 0):
-            os_method_names_no_args.append('getcwdu')
-        os_path_method_names = ['isabs',
-                                                        'isdir',
-                                                        'isfile',
-                                                        'exists'
-                                                     ]
-        if not self.is_windows:
-            os_path_method_names.append('islink')
-            os_path_method_names.append('lexists')
-        wrapped_methods = [['access', self._AccessReal, self._AccessFake],
-                                             ['stat.size', self._StatSizeReal, self._StatSizeFake],
-                                             ['lstat.size', self._LstatSizeReal, self._LstatSizeFake]
-                                            ]
-
-        differences = []
-        for method_name in os_method_names:
-            diff = self.assertOsMethodBehaviorMatches(method_name, path)
-            if diff:
-                differences.append(diff)
-        for method_name in os_method_names_no_args:
-            diff = self.assertOsMethodBehaviorMatches(method_name, (),
-                                                                                                method_returns_path=True)
-            if diff:
-                differences.append(diff)
-        for method_name in os_path_method_names:
-            diff = self.DiffOsPathMethodBehavior(method_name, path)
-            if diff:
-                differences.append(diff)
-        for m in wrapped_methods:
-            diff = self._CompareBehaviors(m[0], path, m[1], m[2])
-            if diff:
-                differences.append(diff)
-        if differences:
-            self.fail('Behaviors do not match for %s:\n    %s' %
-                                (path, '\n    '.join(differences)))
-
-    def assertFileHandleBehaviorsMatch(self, path, mode, data):
-        path = Sep(path)
-        write_method_names = ['write', 'writelines']
-        read_method_names = ['read', 'readlines']
-        other_method_names = ['truncate', 'flush', 'close']
-        differences = []
-        for method_name in write_method_names:
-            diff = self.DiffOpenMethodBehavior(method_name, path, mode, data)
-            if diff:
-                differences.append(diff)
-        for method_name in read_method_names + other_method_names:
-            diff = self.DiffOpenMethodBehavior(method_name, path, mode, ())
-            if diff:
-                differences.append(diff)
-        if differences:
-            self.fail('Behaviors do not match for %s:\n    %s' %
-                                (path, '\n    '.join(differences)))
-
-    # Helpers for checks which are not straight method calls.
-
-    def _AccessReal(self, path):
-        return os.access(path, os.R_OK)
-
-    def _AccessFake(self, path):
-        return self.fake_os.access(path, os.R_OK)
-
-    def _StatSizeReal(self, path):
-        real_path, unused_fake_path = self._Paths(path)
-        # fake_filesystem.py does not implement stat().st_size for directories
-        if os.path.isdir(real_path):
-            return None
-        return os.stat(real_path).st_size
-
-    def _StatSizeFake(self, path):
-        unused_real_path, fake_path = self._Paths(path)
-        # fake_filesystem.py does not implement stat().st_size for directories
-        if self.fake_os.path.isdir(fake_path):
-            return None
-        return self.fake_os.stat(fake_path).st_size
-
-    def _LstatSizeReal(self, path):
-        real_path, unused_fake_path = self._Paths(path)
-        if os.path.isdir(real_path):
-            return None
-        size = os.lstat(real_path).st_size
-        # Account for the difference in the lengths of the absolute paths.
-        if os.path.islink(real_path):
-            if os.readlink(real_path).startswith(os.sep):
-                size -= len(self.real_base)
-        return size
-
-    def _LstatSizeFake(self, path):
-        unused_real_path, fake_path = self._Paths(path)
-        #size = 0
-        if self.fake_os.path.isdir(fake_path):
-            return None
-        size = self.fake_os.lstat(fake_path).st_size
-        # Account for the difference in the lengths of the absolute paths.
-        if self.fake_os.path.islink(fake_path):
-            if self.fake_os.readlink(fake_path).startswith(os.sep):
-                size -= len(self.fake_base)
-        return size
-
-    def testIsabs(self):
-        # We do not have to create any files for isabs.
-        self.assertOsPathMethodBehaviorMatches('isabs', None)
-        self.assertOsPathMethodBehaviorMatches('isabs', '')
-        self.assertOsPathMethodBehaviorMatches('isabs', '/')
-        self.assertOsPathMethodBehaviorMatches('isabs', '/a')
-        self.assertOsPathMethodBehaviorMatches('isabs', 'a')
-
-    def testNonePath(self):
-        self.assertAllOsBehaviorsMatch(None)
-
-    def testEmptyPath(self):
-        self.assertAllOsBehaviorsMatch('')
-
-    def testRootPath(self):
-        self.assertAllOsBehaviorsMatch('/')
-
-    def testNonExistantFile(self):
-        self.assertAllOsBehaviorsMatch('foo')
-
-    def testEmptyFile(self):
-        self._CreateTestFile('f', 'aFile')
-        self.assertAllOsBehaviorsMatch('aFile')
-
-    def testFileWithContents(self):
-        self._CreateTestFile('f', 'aFile', 'some contents')
-        self.assertAllOsBehaviorsMatch('aFile')
-
-    def testFileWithBinaryContents(self):
-        self._CreateTestFile('b', 'aFile', b'some contents')
-        self.assertAllOsBehaviorsMatch('aFile')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testSymLinkToEmptyFile(self):
-        self._CreateTestFile('f', 'aFile')
-        self._CreateTestFile('l', 'link_to_empty', 'aFile')
-        self.assertAllOsBehaviorsMatch('link_to_empty')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def TBD_testHardLinkToEmptyFile(self):
-        self._CreateTestFile('f', 'aFile')
-        self._CreateTestFile('h', 'link_to_empty', 'aFile')
-        self.assertAllOsBehaviorsMatch('link_to_empty')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testSymLinkToRealFile(self):
-        self._CreateTestFile('f', 'aFile', 'some contents')
-        self._CreateTestFile('l', 'link_to_file', 'aFile')
-        self.assertAllOsBehaviorsMatch('link_to_file')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def TBD_testHardLinkToRealFile(self):
-        self._CreateTestFile('f', 'aFile', 'some contents')
-        self._CreateTestFile('h', 'link_to_file', 'aFile')
-        self.assertAllOsBehaviorsMatch('link_to_file')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testBrokenSymLink(self):
-        self._CreateTestFile('l', 'broken_link', 'broken')
-        self._CreateTestFile('l', 'loop', '/a/loop')
-        self.assertAllOsBehaviorsMatch('broken_link')
-
-    def testFileInAFolder(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('f', 'a/b/file', 'contents')
-        self.assertAllOsBehaviorsMatch('a/b/file')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testAbsoluteSymLinkToFolder(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('f', 'a/b/file', 'contents')
-        self._CreateTestFile('l', 'a/link', '/a/b')
-        self.assertAllOsBehaviorsMatch('a/link/file')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testLinkToFolderAfterChdir(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('f', 'a/b/file', 'contents')
-        self._CreateTestFile('l', 'a/link', '/a/b')
-
-        real_dir, fake_dir = self._Paths('a/b')
-        os.chdir(real_dir)
-        self.fake_os.chdir(fake_dir)
-        self.assertAllOsBehaviorsMatch('file')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testRelativeSymLinkToFolder(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('f', 'a/b/file', 'contents')
-        self._CreateTestFile('l', 'a/link', 'b')
-        self.assertAllOsBehaviorsMatch('a/link/file')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testSymLinkToParent(self):
-        # Soft links on HFS+ / OS X behave differently.
-        if os.uname()[0] != 'Darwin':
-            self._CreateTestFile('d', 'a')
-            self._CreateTestFile('d', 'a/b')
-            self._CreateTestFile('l', 'a/b/c', '..')
-            self.assertAllOsBehaviorsMatch('a/b/c')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testPathThroughSymLinkToParent(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('f', 'a/target', 'contents')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('l', 'a/b/c', '..')
-        self.assertAllOsBehaviorsMatch('a/b/c/target')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testSymLinkToSiblingDirectory(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('d', 'a/sibling_of_b')
-        self._CreateTestFile('f', 'a/sibling_of_b/target', 'contents')
-        self._CreateTestFile('l', 'a/b/c', '../sibling_of_b')
-        self.assertAllOsBehaviorsMatch('a/b/c/target')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testSymLinkToSiblingDirectoryNonExistantFile(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('d', 'a/sibling_of_b')
-        self._CreateTestFile('f', 'a/sibling_of_b/target', 'contents')
-        self._CreateTestFile('l', 'a/b/c', '../sibling_of_b')
-        self.assertAllOsBehaviorsMatch('a/b/c/file_does_not_exist')
-
-    @unittest.skipIf(TestCase.is_windows, 'no symlink in Windows')
-    def testBrokenSymLinkToSiblingDirectory(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('d', 'a/sibling_of_b')
-        self._CreateTestFile('f', 'a/sibling_of_b/target', 'contents')
-        self._CreateTestFile('l', 'a/b/c', '../broken_sibling_of_b')
-        self.assertAllOsBehaviorsMatch('a/b/c/target')
-
-    def testRelativePath(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('d', 'a/sibling_of_b')
-        self._CreateTestFile('f', 'a/sibling_of_b/target', 'contents')
-        self.assertAllOsBehaviorsMatch('a/b/../sibling_of_b/target')
-
-    def testBrokenRelativePath(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('d', 'a/sibling_of_b')
-        self._CreateTestFile('f', 'a/sibling_of_b/target', 'contents')
-        self.assertAllOsBehaviorsMatch('a/b/../broken/target')
-
-    def testBadRelativePath(self):
-        self._CreateTestFile('d', 'a')
-        self._CreateTestFile('f', 'a/target', 'contents')
-        self._CreateTestFile('d', 'a/b')
-        self._CreateTestFile('d', 'a/sibling_of_b')
-        self._CreateTestFile('f', 'a/sibling_of_b/target', 'contents')
-        self.assertAllOsBehaviorsMatch('a/b/../broken/../target')
-
-    def testGetmtimeNonexistantPath(self):
-        self.assertOsPathMethodBehaviorMatches('getmtime', 'no/such/path')
-
-    def testBuiltinOpenModes(self):
-        self._CreateTestFile('f', 'read', 'some contents')
-        self._CreateTestFile('f', 'write', 'some contents')
-        self._CreateTestFile('f', 'append', 'some contents')
-        self.assertFileHandleBehaviorsMatch('read', 'r', 'other contents')
-        self.assertFileHandleBehaviorsMatch('write', 'w', 'other contents')
-        self.assertFileHandleBehaviorsMatch('append', 'a', 'other contents')
-        self._CreateTestFile('f', 'readplus', 'some contents')
-        self._CreateTestFile('f', 'writeplus', 'some contents')
-        self.assertFileHandleBehaviorsMatch('readplus', 'r+', 'other contents')
-        self.assertFileHandleBehaviorsMatch('writeplus', 'w+', 'other contents')
-        self._CreateTestFile('b', 'binaryread', b'some contents')
-        self._CreateTestFile('b', 'binarywrite', b'some contents')
-        self._CreateTestFile('b', 'binaryappend', b'some contents')
-        self.assertFileHandleBehaviorsMatch('binaryread', 'rb', b'other contents')
-        self.assertFileHandleBehaviorsMatch('binarywrite', 'wb', b'other contents')
-        self.assertFileHandleBehaviorsMatch('binaryappend', 'ab', b'other contents')
-        self.assertFileHandleBehaviorsMatch('read', 'rb', 'other contents')
-        self.assertFileHandleBehaviorsMatch('write', 'wb', 'other contents')
-        self.assertFileHandleBehaviorsMatch('append', 'ab', 'other contents')
-
-
-def main(unused_argv):
-    unittest.main()
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_tempfile.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_tempfile.py
deleted file mode 100644
index 090425d..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_tempfile.py
+++ /dev/null
@@ -1,312 +0,0 @@
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Fake tempfile module.
-
-Fake implementation of the python2.4.1 tempfile built-in module that works with
-a FakeFilesystem object.
-"""
-#pylint: disable-all
-
-import errno
-import logging
-import os
-import stat
-import tempfile
-
-import fake_filesystem
-
-try:
-  import StringIO as io  # pylint: disable-msg=C6204
-except ImportError:
-  import io  # pylint: disable-msg=C6204
-
-
-class FakeTempfileModule(object):
-  """Uses a FakeFilesystem to provide a mock for the tempfile 2.4.1 module.
-
-  Common usage:
-  filesystem = fake_filesystem.FakeFilesystem()
-  my_tempfile_module = mock_tempfile.FakeTempfileModule(filesystem)
-
-  See also: default keyword arguments for Dependency Injection on
-  http://go/tott-episode-12
-  """
-
-  def __init__(self, filesystem):
-    self._filesystem = filesystem
-    self._tempfile = tempfile
-    self.tempdir = None  # initialized by mktemp(), others
-    self._temp_prefix = 'tmp'
-    self._mktemp_retvals = []
-
-  # pylint: disable-msg=W0622
-  def _TempFilename(self, suffix='', prefix=None, dir=None):
-    """Create a temporary filename that does not exist.
-
-    This is a re-implementation of how tempfile creates random filenames,
-    and is probably different.
-
-    Does not modify self._filesystem, that's your job.
-
-    Output: self.tempdir is initialized if unset
-    Args:
-      suffix: filename suffix
-      prefix: filename prefix
-      dir: dir to put filename in
-    Returns:
-      string, temp filename that does not exist
-    """
-    if dir is None:
-      dir = self._filesystem.JoinPaths(self._filesystem.root.name, 'tmp')
-    filename = None
-    if prefix is None:
-      prefix = self._temp_prefix
-    while not filename or self._filesystem.Exists(filename):
-      # pylint: disable-msg=W0212
-      filename = self._filesystem.JoinPaths(dir, '%s%s%s' % (
-          prefix,
-          next(self._tempfile._RandomNameSequence()),
-          suffix))
-    return filename
-
-  # pylint: disable-msg=W0622,W0613
-  def TemporaryFile(self, mode='w+b', bufsize=-1,
-                    suffix='', prefix=None, dir=None):
-    """Return a file-like object deleted on close().
-
-    Python 2.4.1 tempfile.TemporaryFile.__doc__ =
-    >Return a file (or file-like) object that can be used as a temporary
-    >storage area. The file is created using mkstemp. It will be destroyed as
-    >soon as it is closed (including an implicit close when the object is
-    >garbage collected). Under Unix, the directory entry for the file is
-    >removed immediately after the file is created. Other platforms do not
-    >support this; your code should not rely on a temporary file created using
-    >this function having or not having a visible name in the file system.
-    >
-    >The mode parameter defaults to 'w+b' so that the file created can be read
-    >and written without being closed. Binary mode is used so that it behaves
-    >consistently on all platforms without regard for the data that is stored.
-    >bufsize defaults to -1, meaning that the operating system default is used.
-    >
-    >The dir, prefix and suffix parameters are passed to mkstemp()
-
-    Args:
-      mode: optional string, see above
-      bufsize: optional int, see above
-      suffix: optional string, see above
-      prefix: optional string, see above
-      dir: optional string, see above
-    Returns:
-      a file-like object.
-    """
-    # pylint: disable-msg=C6002
-    # TODO: prefix, suffix, bufsize, dir, mode unused?
-    # cannot be cStringIO due to .name requirement below
-    retval = io.StringIO()
-    retval.name = '<fdopen>'  # as seen on 2.4.3
-    return retval
-
-  # pylint: disable-msg=W0622,W0613
-  def NamedTemporaryFile(self, mode='w+b', bufsize=-1,
-                         suffix='', prefix=None, dir=None, delete=True):
-    """Return a file-like object with name that is deleted on close().
-
-    Python 2.4.1 tempfile.NamedTemporaryFile.__doc__ =
-    >This function operates exactly as TemporaryFile() does, except that
-    >the file is guaranteed to have a visible name in the file system. That
-    >name can be retrieved from the name member of the file object.
-
-    Args:
-      mode: optional string, see above
-      bufsize: optional int, see above
-      suffix: optional string, see above
-      prefix: optional string, see above
-      dir: optional string, see above
-      delete: optional bool, see above
-    Returns:
-      a file-like object including obj.name
-    """
-    # pylint: disable-msg=C6002
-    # TODO: bufsiz unused?
-    temp = self.mkstemp(suffix=suffix, prefix=prefix, dir=dir)
-    filename = temp[1]
-    mock_open = fake_filesystem.FakeFileOpen(
-        self._filesystem, delete_on_close=delete)
-    obj = mock_open(filename, mode)
-    obj.name = filename
-    return obj
-
-  # pylint: disable-msg=C6409
-  def mkstemp(self, suffix='', prefix=None, dir=None, text=False):
-    """Create temp file, returning a 2-tuple: (9999, filename).
-
-    Important: Returns 9999 instead of a real file descriptor!
-
-    Python 2.4.1 tempfile.mkstemp.__doc__ =
-    >mkstemp([suffix, [prefix, [dir, [text]]]])
-    >
-    >User-callable function to create and return a unique temporary file.
-    >The return value is a pair (fd, name) where fd is the file descriptor
-    >returned by os.open, and name is the filename.
-    >
-    >...[snip args]...
-    >
-    >The file is readable and writable only by the creating user ID.
-    >If the operating system uses permission bits to indicate whether
-    >a file is executable, the file is executable by no one. The file
-    >descriptor is not inherited by children of this process.
-    >
-    >Caller is responsible for deleting the file when done with it.
-
-    NOTE: if dir is unspecified, this call creates a directory.
-
-    Output: self.tempdir is initialized if unset
-    Args:
-      suffix: optional string, filename suffix
-      prefix: optional string, filename prefix
-      dir: optional string, directory for temp file; must exist before call
-      text: optional boolean, True = open file in text mode.
-          default False = open file in binary mode.
-    Returns:
-      2-tuple containing
-      [0] = int, file descriptor number for the file object
-      [1] = string, absolute pathname of a file
-    Raises:
-      OSError: when dir= is specified but does not exist
-    """
-    # pylint: disable-msg=C6002
-    # TODO: optional boolean text is unused?
-    # default dir affected by "global"
-    filename = self._TempEntryname(suffix, prefix, dir)
-    fh = self._filesystem.CreateFile(filename, st_mode=stat.S_IFREG|0o600)
-    fd = self._filesystem.AddOpenFile(fh)
-
-    self._mktemp_retvals.append(filename)
-    return (fd, filename)
-
-  # pylint: disable-msg=C6409
-  def mkdtemp(self, suffix='', prefix=None, dir=None):
-    """Create temp directory, returns string, absolute pathname.
-
-    Python 2.4.1 tempfile.mkdtemp.__doc__ =
-    >mkdtemp([suffix[, prefix[, dir]]])
-    >Creates a temporary directory in the most secure manner
-    >possible. [...]
-    >
-    >The user of mkdtemp() is responsible for deleting the temporary
-    >directory and its contents when done with it.
-    > [...]
-    >mkdtemp() returns the absolute pathname of the new directory. [...]
-
-    Args:
-      suffix: optional string, filename suffix
-      prefix: optional string, filename prefix
-      dir: optional string, directory for temp dir. Must exist before call
-    Returns:
-      string, directory name
-    """
-    dirname = self._TempEntryname(suffix, prefix, dir)
-    self._filesystem.CreateDirectory(dirname, perm_bits=0o700)
-
-    self._mktemp_retvals.append(dirname)
-    return dirname
-
-  def _TempEntryname(self, suffix, prefix, dir):
-    """Helper function for mk[ds]temp.
-
-    Args:
-      suffix: string, filename suffix
-      prefix: string, filename prefix
-      dir: string, directory for temp dir. Must exist before call
-    Returns:
-      string, entry name
-    """
-    # default dir affected by "global"
-    if dir is None:
-      call_mkdir = True
-      dir = self.gettempdir()
-    else:
-      call_mkdir = False
-
-    entryname = None
-    while not entryname or self._filesystem.Exists(entryname):
-      entryname = self._TempFilename(suffix=suffix, prefix=prefix, dir=dir)
-    if not call_mkdir:
-      # This is simplistic. A bad input of suffix=/f will cause tempfile
-      # to blow up, but this mock won't.  But that's already a broken
-      # corner case
-      parent_dir = os.path.dirname(entryname)
-      try:
-        self._filesystem.GetObject(parent_dir)
-      except IOError as err:
-        assert 'No such file or directory' in str(err)
-        # python -c 'import tempfile; tempfile.mkstemp(dir="/no/such/dr")'
-        # OSError: [Errno 2] No such file or directory: '/no/such/dr/tmpFBuqjO'
-        raise OSError(
-            errno.ENOENT,
-            'No such directory in mock filesystem',
-            parent_dir)
-    return entryname
-
-  # pylint: disable-msg=C6409
-  def gettempdir(self):
-    """Get default temp dir.  Sets default if unset."""
-    if self.tempdir:
-      return self.tempdir
-    # pylint: disable-msg=C6002
-    # TODO: environment variables TMPDIR TEMP TMP, or other dirs?
-    self.tempdir = '/tmp'
-    return self.tempdir
-
-  # pylint: disable-msg=C6409
-  def gettempprefix(self):
-    """Get temp filename prefix.
-
-    NOTE: This has no effect on py2.4
-
-    Returns:
-      string, prefix to use in temporary filenames
-    """
-    return self._temp_prefix
-
-  # pylint: disable-msg=C6409
-  def mktemp(self, suffix=''):
-    """mktemp is deprecated in 2.4.1, and is thus unimplemented."""
-    raise NotImplementedError
-
-  def _SetTemplate(self, template):
-    """Setter for 'template' property."""
-    self._temp_prefix = template
-    logging.error('tempfile.template= is a NOP in python2.4')
-
-  def __SetTemplate(self, template):
-    """Indirect setter for 'template' property."""
-    self._SetTemplate(template)
-
-  def __DeprecatedTemplate(self):
-    """template property implementation."""
-    raise NotImplementedError
-
-  # reading from template is deprecated, setting is ok.
-  template = property(__DeprecatedTemplate, __SetTemplate,
-                      doc="""Set the prefix for temp filenames""")
-
-  def FakeReturnedMktempValues(self):
-    """For validation purposes, mktemp()'s return values are stored."""
-    return self._mktemp_retvals
-
-  def FakeMktempReset(self):
-    """Clear the stored mktemp() values."""
-    self._mktemp_retvals = []
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_tempfile_test.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_tempfile_test.py
deleted file mode 100755
index e7dcb6c..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/fake_tempfile_test.py
+++ /dev/null
@@ -1,197 +0,0 @@
-#! /usr/bin/env python
-#
-# Copyright 2009 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Tests for the fake_tempfile module."""
-
-#pylint: disable-all
-
-import stat
-import sys
-if sys.version_info < (2, 7):
-    import unittest2 as unittest
-else:
-    import unittest
-
-try:
-  import StringIO as io  # pylint: disable-msg=C6204
-except ImportError:
-  import io  # pylint: disable-msg=C6204
-
-import fake_filesystem
-import fake_tempfile
-
-
-class FakeLogging(object):
-  """Fake logging object for testGettempprefix."""
-
-  def __init__(self, test_case):
-    self._message = None
-    self._test_case = test_case
-
-  # pylint: disable-msg=C6409
-  def error(self, message):
-    if self._message is not None:
-      self.FailOnMessage(message)
-    self._message = message
-
-  def FailOnMessage(self, message):
-    self._test_case.fail('Unexpected message received: %s' % message)
-
-  warn = FailOnMessage
-  info = FailOnMessage
-  debug = FailOnMessage
-  fatal = FailOnMessage
-
-  def message(self):
-    return self._message
-
-
-class FakeTempfileModuleTest(unittest.TestCase):
-  """Test the 'tempfile' module mock."""
-
-  def setUp(self):
-    self.filesystem = fake_filesystem.FakeFilesystem(path_separator='/')
-    self.tempfile = fake_tempfile.FakeTempfileModule(self.filesystem)
-    self.orig_logging = fake_tempfile.logging
-    self.fake_logging = FakeLogging(self)
-    fake_tempfile.logging = self.fake_logging
-
-  def tearDown(self):
-    fake_tempfile.logging = self.orig_logging
-
-  def testTempFilename(self):
-    # pylint: disable-msg=C6002
-    # TODO: test that tempdir is init'ed
-    filename_a = self.tempfile._TempFilename()
-    # expect /tmp/tmp######
-    self.assertTrue(filename_a.startswith('/tmp/tmp'))
-    self.assertLess(len('/tmp/tmpA'), len(filename_a))
-
-    # see that random part changes
-    filename_b = self.tempfile._TempFilename()
-    self.assertTrue(filename_b.startswith('/tmp/tmp'))
-    self.assertLess(len('/tmp/tmpB'), len(filename_a))
-    self.assertNotEqual(filename_a, filename_b)
-
-  def testTempFilenameSuffix(self):
-    """test tempfile._TempFilename(suffix=)."""
-    filename = self.tempfile._TempFilename(suffix='.suffix')
-    self.assertTrue(filename.startswith('/tmp/tmp'))
-    self.assertTrue(filename.endswith('.suffix'))
-    self.assertLess(len('/tmp/tmpX.suffix'), len(filename))
-
-  def testTempFilenamePrefix(self):
-    """test tempfile._TempFilename(prefix=)."""
-    filename = self.tempfile._TempFilename(prefix='prefix.')
-    self.assertTrue(filename.startswith('/tmp/prefix.'))
-    self.assertLess(len('/tmp/prefix.X'), len(filename))
-
-  def testTempFilenameDir(self):
-    """test tempfile._TempFilename(dir=)."""
-    filename = self.tempfile._TempFilename(dir='/dir')
-    self.assertTrue(filename.startswith('/dir/tmp'))
-    self.assertLess(len('/dir/tmpX'), len(filename))
-
-  def testTemporaryFile(self):
-    obj = self.tempfile.TemporaryFile()
-    self.assertEqual('<fdopen>', obj.name)
-    self.assertTrue(isinstance(obj, io.StringIO))
-
-  def testNamedTemporaryFile(self):
-    obj = self.tempfile.NamedTemporaryFile()
-    created_filenames = self.tempfile.FakeReturnedMktempValues()
-    self.assertEqual(created_filenames[0], obj.name)
-    self.assertTrue(self.filesystem.GetObject(obj.name))
-    obj.close()
-    self.assertRaises(IOError, self.filesystem.GetObject, obj.name)
-
-  def testNamedTemporaryFileNoDelete(self):
-    obj = self.tempfile.NamedTemporaryFile(delete=False)
-    obj.write(b'foo')
-    obj.close()
-    file_obj = self.filesystem.GetObject(obj.name)
-    self.assertEqual('foo', file_obj.contents)
-    obj = self.tempfile.NamedTemporaryFile(mode='w', delete=False)
-    obj.write('foo')
-    obj.close()
-    file_obj = self.filesystem.GetObject(obj.name)
-    self.assertEqual('foo', file_obj.contents)
-
-  def testMkstemp(self):
-    next_fd = len(self.filesystem.open_files)
-    temporary = self.tempfile.mkstemp()
-    self.assertEqual(2, len(temporary))
-    self.assertTrue(temporary[1].startswith('/tmp/tmp'))
-    created_filenames = self.tempfile.FakeReturnedMktempValues()
-    self.assertEqual(next_fd, temporary[0])
-    self.assertEqual(temporary[1], created_filenames[0])
-    self.assertTrue(self.filesystem.Exists(temporary[1]))
-    self.assertEqual(self.filesystem.GetObject(temporary[1]).st_mode,
-                     stat.S_IFREG|0o600)
-
-  def testMkstempDir(self):
-    """test tempfile.mkstemp(dir=)."""
-    # expect fail: /dir does not exist
-    self.assertRaises(OSError, self.tempfile.mkstemp, dir='/dir')
-    # expect pass: /dir exists
-    self.filesystem.CreateDirectory('/dir')
-    next_fd = len(self.filesystem.open_files)
-    temporary = self.tempfile.mkstemp(dir='/dir')
-    self.assertEqual(2, len(temporary))
-    self.assertEqual(next_fd, temporary[0])
-    self.assertTrue(temporary[1].startswith('/dir/tmp'))
-    created_filenames = self.tempfile.FakeReturnedMktempValues()
-    self.assertEqual(temporary[1], created_filenames[0])
-    self.assertTrue(self.filesystem.Exists(temporary[1]))
-    self.assertEqual(self.filesystem.GetObject(temporary[1]).st_mode,
-                     stat.S_IFREG|0o600)
-    # pylint: disable-msg=C6002
-    # TODO: add a test that /dir is actually writable.
-
-  def testMkdtemp(self):
-    dirname = self.tempfile.mkdtemp()
-    self.assertTrue(dirname)
-    created_filenames = self.tempfile.FakeReturnedMktempValues()
-    self.assertEqual(dirname, created_filenames[0])
-    self.assertTrue(self.filesystem.Exists(dirname))
-    self.assertEqual(self.filesystem.GetObject(dirname).st_mode,
-                     stat.S_IFDIR|0o700)
-
-  def testGettempdir(self):
-    self.assertEqual(None, self.tempfile.tempdir)
-    self.assertEqual('/tmp', self.tempfile.gettempdir())
-    self.assertEqual('/tmp', self.tempfile.tempdir)
-
-  def testGettempprefix(self):
-    """test tempfile.gettempprefix() and the tempfile.template setter."""
-    self.assertEqual('tmp', self.tempfile.gettempprefix())
-    # set and verify
-    self.tempfile.template = 'strung'
-    self.assertEqual('strung', self.tempfile.gettempprefix())
-    self.assertEqual('tempfile.template= is a NOP in python2.4',
-                     self.fake_logging.message())
-
-  def testMktemp(self):
-    self.assertRaises(NotImplementedError, self.tempfile.mktemp)
-
-  def testTemplateGet(self):
-    """verify tempfile.template still unimplemented."""
-    self.assertRaises(NotImplementedError, getattr,
-                      self.tempfile, 'template')
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/requirements.txt b/catapult/telemetry/third_party/pyfakefs/pyfakefs/requirements.txt
deleted file mode 100644
index ddd4287..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-wheel==0.23.0
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/setup.py b/catapult/telemetry/third_party/pyfakefs/pyfakefs/setup.py
deleted file mode 100644
index b1a2f11..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/setup.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#! /usr/bin/env python
-
-# Copyright 2009 Google Inc. All Rights Reserved.
-# Copyright 2014 Altera Corporation. All Rights Reserved.
-# Copyright 2014-2015 John McGehee
-# 
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-# 
-#     http://www.apache.org/licenses/LICENSE-2.0
-# 
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-from fake_filesystem import __version__
-
-import os
-
-
-NAME = 'pyfakefs'
-MODULES = ['fake_filesystem',
-           'fake_filesystem_glob',
-           'fake_filesystem_shutil',
-           'fake_tempfile',
-           'fake_filesystem_unittest']
-REQUIRES = ['mox3']
-DESCRIPTION = 'Fake file system for testing file operations without touching the real file system.'
-
-URL = "https://github.com/jmcgeheeiv/pyfakefs"
-
-readme = os.path.join(os.path.dirname(__file__), 'README.md')
-LONG_DESCRIPTION = open(readme).read()
-
-CLASSIFIERS = [
-    'Development Status :: 5 - Production/Stable',
-    'Environment :: Console',
-    'Intended Audience :: Developers',
-    'License :: OSI Approved :: Apache Software License',
-    'Programming Language :: Python',
-    'Programming Language :: Python :: 2.6',
-    'Programming Language :: Python :: 2.7',
-    'Programming Language :: Python :: 3.2',
-    'Programming Language :: Python :: 3.3',
-    'Programming Language :: Python :: 3.4',
-    'Operating System :: POSIX',
-    'Operating System :: MacOS',
-    'Operating System :: Microsoft :: Windows',
-    'Topic :: Software Development :: Libraries',
-    'Topic :: Software Development :: Libraries :: Python Modules',
-    'Topic :: Software Development :: Testing',
-    'Topic :: System :: Filesystems',
-]
-
-AUTHOR = 'Google and John McGehee'
-AUTHOR_EMAIL = 'github@johnnado,com'
-KEYWORDS = ("testing test file os shutil glob mocking unittest "
-            "fakes filesystem unit").split(' ')
-
-params = dict(
-    name=NAME,
-    version=__version__,
-    py_modules=MODULES,
-    install_requires=REQUIRES,
-
-    # metadata for upload to PyPI
-    author=AUTHOR,
-    author_email=AUTHOR_EMAIL,
-    description=DESCRIPTION,
-    long_description=LONG_DESCRIPTION,
-    keywords=KEYWORDS,
-    url=URL,
-    classifiers=CLASSIFIERS,
-)
-
-try:
-    from setuptools import setup
-except ImportError:
-    from distutils.core import setup
-else:
-    params['tests_require'] = ['unittest2']
-    params['test_suite'] = 'unittest2.collector'
-
-setup(**params) # pylint: disable = W0142
diff --git a/catapult/telemetry/third_party/pyfakefs/pyfakefs/tox.ini b/catapult/telemetry/third_party/pyfakefs/pyfakefs/tox.ini
deleted file mode 100644
index 0da79b7..0000000
--- a/catapult/telemetry/third_party/pyfakefs/pyfakefs/tox.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-[tox]
-envlist=py26,py27,py32,py33,pypy
-
-[testenv]
-commands=python all_tests.py
-
-[testenv:py26]
-deps=unittest2
diff --git a/catapult/telemetry/third_party/tsproxy/.gitignore b/catapult/telemetry/third_party/tsproxy/.gitignore
deleted file mode 100644
index 1dbc687..0000000
--- a/catapult/telemetry/third_party/tsproxy/.gitignore
+++ /dev/null
@@ -1,62 +0,0 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-env/
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
-*.egg-info/
-.installed.cfg
-*.egg
-
-# PyInstaller
-#  Usually these files are written by a python script from a template
-#  before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*,cover
-.hypothesis/
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
-
-#Ipython Notebook
-.ipynb_checkpoints
diff --git a/catapult/telemetry/third_party/tsproxy/LICENSE b/catapult/telemetry/third_party/tsproxy/LICENSE
deleted file mode 100644
index 8dada3e..0000000
--- a/catapult/telemetry/third_party/tsproxy/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "{}"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright {yyyy} {name of copyright owner}
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/catapult/telemetry/third_party/tsproxy/README.chromium b/catapult/telemetry/third_party/tsproxy/README.chromium
deleted file mode 100644
index 456cc23..0000000
--- a/catapult/telemetry/third_party/tsproxy/README.chromium
+++ /dev/null
@@ -1,13 +0,0 @@
-Name: tsproxy
-Short Name: tsproxy
-URL: https://github.com/WPO-Foundation/tsproxy
-Version: a2f578febcd79b751d948f615bbde8f6189fbeed (commit hash)
-License: Apache
-License File: NOT_SHIPPED
-Security Critical: no
-
-Local modification: no
-
-Description:
-tsproxy provides basic latency, download and upload traffic shaping while only
-requiring user-level access (no root permissions required)
diff --git a/catapult/telemetry/third_party/tsproxy/README.md b/catapult/telemetry/third_party/tsproxy/README.md
deleted file mode 100644
index 84cc3fa..0000000
--- a/catapult/telemetry/third_party/tsproxy/README.md
+++ /dev/null
@@ -1,62 +0,0 @@
-# tsproxy
-Traffic-shaping SOCKS5 proxy
-
-tsproxy provides basic latency, download and upload traffic shaping while only requiring user-level access (no root permissions required).  It should work for basic browser testing but for protocol-level work it does not provide a suitable replacement for something like dummynet or netem.
-
-tsproxy is monolithic and all of the functionality is in tsproxy.py.  It is written expecting Python 2.7.
-
-#Usage
-```bash
-$ python tsproxy.py --rtt=<latency> --inkbps=<download bandwidth> --outkbps=<upload bandwidth>
-```
-Hit `ctrl-C` (or send a `SIGINT`) to exit
-
-#Example
-```bash
-$ python tsproxy.py --rtt=200 --inkbps=1600 --outkbps=768
-```
-
-#Command-line Options
-
-
-| Option            | Alias    | Description                              |
-| ----------------- | -------- | ---------------------------------------- |
-| **`--rtt`**       | **`-r`** | Latency in milliseconds (full round trip, half of the latency gets applied to each direction). |
-| **`--inkbps`**    | **`-i`** | Download Bandwidth (in 1000 bits/s - Kbps). |
-| **`--outkbps`**   | **`-o`** | Upload Bandwidth (in 1000 bits/s - Kbps). |
-| **`--window`**    | **`-w`** | Emulated TCP initial congestion window (defaults to 10). |
-| **`--port`**      | **`-p`** | SOCKS 5 proxy port (defaults to port 1080). Specifying a port of 0 will use a randomly assigned port. |
-| **`--bind`**      | **`-b`** | Interface address to listen on (defaults to localhost). |
-| **`--desthost`**  | **`-d`** | Redirect all outbound connections to the specified host (name or IP). |
-| **`--mapports`**  | **`-m`** | Remap outbound ports. Comma-separated list of original:new with * as a wildcard. `--mapports '443:8443,*:8080'` |
-| **`--localhost`** | **`-l`** | Include connections already destined for localhost/127.0.0.1 in the host and port remapping. |
-| **`--verbose`**   | **`-v`** | Increase verbosity (specify multiple times for more). `-vvvv` for full debug output. |
-
-
-#Runtime Options
-The traffic shaping configuration can be changed dynamically at runtime by passing commands in through the console (or stdin).  Each command is on a line, terminated with an end-of-line (`\n`).
-
-
-* **`flush`** : Flush queued data out of the pipes.  Useful for clearing out any accumulated background data between tests.
-* **`set rtt <latency>`** : Change the connection latency. i.e. `set rtt 200\n` will change to a 200ms RTT.
-* **`set inkbps <bandwidth>`** : Change the download bandwidth. i.e. `set inkbps 5000\n` will change to a 5Mbps download connection.
-* **`set outkbps <bandwidth>`** : Change the upload bandwidth. i.e. `set outkbps 1000\n` will change to a 1Mbps upload connection.
-* **`set mapports <port mapping string>`** : Change the destination port mapping.
-* **`reset all`** : Disable all port mapping and traffic shaping
-* **`reset rtt`** : Set latency to 0
-* **`reset inkbps`** : Disable download traffic shaping
-* **`reset outkbps`** : Disable upload traffic shaping
-* **`reset mapports`** : Disable destination port mapping
-
-All bandwidth and latency changes also carry an implied flush and clear out any pending data.
-
-
-#Configuring Chrome to use tsproxy
-Add a --proxy-server command-line option.
-```bash
---proxy-server="socks://localhost:1080"
-```
-
-#Known Shortcomings/Issues
-* DNS lookups on OSX (and FreeBSD) will block each other when it comes to actually resolving.  DNS in Python on most platforms is allowed to run concurrently in threads (which tsproxy does) but on OSX and FreeBSD it is not thread-safe and there is a lock around the actual lookups.  For most cases this isn't an issue because the latency isn't added on the actual DNS lookup (it is from the browser perspective but it is added outside of the actual lookup). This is also not an issue when desthost is used to override the destination address since dns lookups will be disabled.
-* QUIC support. Chrome [doesn't currently support QUIC proxies](https://bugs.chromium.org/p/chromium/issues/detail?id=335275), and further work would be neccessary to correctly handle UDP traffic in tsproxy.
diff --git a/catapult/telemetry/third_party/tsproxy/tsproxy.py b/catapult/telemetry/third_party/tsproxy/tsproxy.py
deleted file mode 100644
index e4c0c27..0000000
--- a/catapult/telemetry/third_party/tsproxy/tsproxy.py
+++ /dev/null
@@ -1,776 +0,0 @@
-#!/usr/bin/python
-"""
-Copyright 2016 Google Inc. All Rights Reserved.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
-    http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-"""
-import asyncore
-import gc
-import logging
-import platform
-import Queue
-import re
-import signal
-import socket
-import sys
-import threading
-import time
-
-server = None
-in_pipe = None
-out_pipe = None
-must_exit = False
-options = None
-dest_addresses = None
-connections = {}
-dns_cache = {}
-port_mappings = None
-map_localhost = False
-needs_flush = False
-flush_pipes = False
-last_activity = None
-REMOVE_TCP_OVERHEAD = 1460.0 / 1500.0
-lock = threading.Lock()
-background_activity_count = 0
-
-
-def PrintMessage(msg):
-  # Print the message to stdout & flush to make sure that the message is not
-  # buffered when tsproxy is run as a subprocess.
-  print >> sys.stdout, msg
-  sys.stdout.flush()
-
-########################################################################################################################
-#   Traffic-shaping pipe (just passthrough for now)
-########################################################################################################################
-class TSPipe():
-  PIPE_IN = 0
-  PIPE_OUT = 1
-
-  def __init__(self, direction, latency, kbps):
-    self.direction = direction
-    self.latency = latency
-    self.kbps = kbps
-    self.queue = Queue.Queue()
-    self.last_tick = time.clock()
-    self.next_message = None
-    self.available_bytes = .0
-    self.peer = 'server'
-    if self.direction == self.PIPE_IN:
-      self.peer = 'client'
-
-  def SendMessage(self, message, main_thread = True):
-    global connections, in_pipe, out_pipe
-    message_sent = False
-    now = time.clock()
-    if message['message'] == 'closed':
-      message['time'] = now
-    else:
-      message['time'] = time.clock() + self.latency
-    message['size'] = .0
-    if 'data' in message:
-      message['size'] = float(len(message['data']))
-    try:
-      connection_id = message['connection']
-      # Send messages directly, bypassing the queues is throttling is disabled and we are on the main thread
-      if main_thread and connection_id in connections and self.peer in connections[connection_id]and self.latency == 0 and self.kbps == .0:
-        message_sent = self.SendPeerMessage(message)
-    except:
-      pass
-    if not message_sent:
-      try:
-        self.queue.put(message)
-      except:
-        pass
-
-  def SendPeerMessage(self, message):
-    global last_activity
-    last_activity = time.clock()
-    message_sent = False
-    connection_id = message['connection']
-    if connection_id in connections:
-      if self.peer in connections[connection_id]:
-        try:
-          connections[connection_id][self.peer].handle_message(message)
-          message_sent = True
-        except:
-          # Clean up any disconnected connections
-          try:
-            connections[connection_id]['server'].close()
-          except:
-            pass
-          try:
-            connections[connection_id]['client'].close()
-          except:
-            pass
-          del connections[connection_id]
-    return message_sent
-
-  def tick(self):
-    global connections
-    global flush_pipes
-    processed_messages = False
-    now = time.clock()
-    try:
-      if self.next_message is None:
-        self.next_message = self.queue.get_nowait()
-
-      # Accumulate bandwidth if an available packet/message was waiting since our last tick
-      if self.next_message is not None and self.kbps > .0 and self.next_message['time'] <= now:
-        elapsed = now - self.last_tick
-        accumulated_bytes = elapsed * self.kbps * 1000.0 / 8.0
-        self.available_bytes += accumulated_bytes
-
-      # process messages as long as the next message is sendable (latency or available bytes)
-      while (self.next_message is not None) and\
-          (flush_pipes or ((self.next_message['time'] <= now) and
-                          (self.kbps <= .0 or self.next_message['size'] <= self.available_bytes))):
-        self.queue.task_done()
-        processed_messages = True
-        if self.kbps > .0:
-          self.available_bytes -= self.next_message['size']
-        self.SendPeerMessage(self.next_message)
-        self.next_message = None
-        self.next_message = self.queue.get_nowait()
-    except:
-      pass
-
-    # Only accumulate bytes while we have messages that are ready to send
-    if self.next_message is None or self.next_message['time'] > now:
-      self.available_bytes = .0
-    self.last_tick = now
-
-    return processed_messages
-
-
-########################################################################################################################
-#   Threaded DNS resolver
-########################################################################################################################
-class AsyncDNS(threading.Thread):
-  def __init__(self, client_id, hostname, port, result_pipe):
-    threading.Thread.__init__(self)
-    self.hostname = hostname
-    self.port = port
-    self.client_id = client_id
-    self.result_pipe = result_pipe
-
-  def run(self):
-    global lock, background_activity_count
-    try:
-      logging.debug('[{0:d}] AsyncDNS - calling getaddrinfo for {1}:{2:d}'.format(self.client_id, self.hostname, self.port))
-      addresses = socket.getaddrinfo(self.hostname, self.port)
-      logging.info('[{0:d}] Resolving {1}:{2:d} Completed'.format(self.client_id, self.hostname, self.port))
-    except:
-      addresses = ()
-      logging.info('[{0:d}] Resolving {1}:{2:d} Failed'.format(self.client_id, self.hostname, self.port))
-    message = {'message': 'resolved', 'connection': self.client_id, 'addresses': addresses}
-    self.result_pipe.SendMessage(message, False)
-    lock.acquire()
-    if background_activity_count > 0:
-      background_activity_count -= 1
-    lock.release()
-    # open and close a local socket which will interrupt the long polling loop to process the message
-    s = socket.socket()
-    s.connect((server.ipaddr, server.port))
-    s.close()
-
-
-########################################################################################################################
-#   TCP Client
-########################################################################################################################
-class TCPConnection(asyncore.dispatcher):
-  STATE_ERROR = -1
-  STATE_IDLE = 0
-  STATE_RESOLVING = 1
-  STATE_CONNECTING = 2
-  STATE_CONNECTED = 3
-
-  def __init__(self, client_id):
-    global options
-    asyncore.dispatcher.__init__(self)
-    self.client_id = client_id
-    self.state = self.STATE_IDLE
-    self.buffer = ''
-    self.addr = None
-    self.dns_thread = None
-    self.hostname = None
-    self.port = None
-    self.needs_config = True
-    self.needs_close = False
-    self.is_localhost = False
-    self.did_resolve = False
-
-  def SendMessage(self, type, message):
-    message['message'] = type
-    message['connection'] = self.client_id
-    in_pipe.SendMessage(message)
-
-  def handle_message(self, message):
-    if message['message'] == 'data' and 'data' in message and len(message['data']):
-      self.buffer += message['data']
-      if self.state == self.STATE_CONNECTED:
-        self.handle_write()
-    elif message['message'] == 'resolve':
-      self.HandleResolve(message)
-    elif message['message'] == 'connect':
-      self.HandleConnect(message)
-    elif message['message'] == 'closed':
-      if len(self.buffer) == 0:
-        self.handle_close()
-      else:
-        self.needs_close = True
-
-  def handle_error(self):
-    logging.warning('[{0:d}] Error'.format(self.client_id))
-    if self.state == self.STATE_CONNECTING:
-      self.SendMessage('connected', {'success': False, 'address': self.addr})
-
-  def handle_close(self):
-    logging.info('[{0:d}] Server Connection Closed'.format(self.client_id))
-    self.state = self.STATE_ERROR
-    self.close()
-    try:
-      if self.client_id in connections:
-        if 'server' in connections[self.client_id]:
-          del connections[self.client_id]['server']
-        if 'client' in connections[self.client_id]:
-          self.SendMessage('closed', {})
-        else:
-          del connections[self.client_id]
-    except:
-      pass
-
-  def handle_connect(self):
-    if self.state == self.STATE_CONNECTING:
-      self.state = self.STATE_CONNECTED
-      self.SendMessage('connected', {'success': True, 'address': self.addr})
-      logging.info('[{0:d}] Connected'.format(self.client_id))
-    self.handle_write()
-
-  def writable(self):
-    if self.state == self.STATE_CONNECTING:
-      return True
-    return len(self.buffer) > 0
-
-  def handle_write(self):
-    if self.needs_config:
-      self.needs_config = False
-      self.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
-      self.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 128 * 1024)
-      self.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 128 * 1024)
-    if len(self.buffer) > 0:
-      sent = self.send(self.buffer)
-      logging.debug('[{0:d}] TCP => {1:d} byte(s)'.format(self.client_id, sent))
-      self.buffer = self.buffer[sent:]
-      if self.needs_close and len(self.buffer) == 0:
-        self.needs_close = False
-        self.handle_close()
-
-  def handle_read(self):
-    try:
-      while True:
-        data = self.recv(1460)
-        if data:
-          if self.state == self.STATE_CONNECTED:
-            logging.debug('[{0:d}] TCP <= {1:d} byte(s)'.format(self.client_id, len(data)))
-            self.SendMessage('data', {'data': data})
-        else:
-          return
-    except:
-      pass
-
-  def HandleResolve(self, message):
-    global in_pipe,  map_localhost, lock, background_activity_count
-    self.did_resolve = True
-    if 'hostname' in message:
-      self.hostname = message['hostname']
-    self.port = 0
-    if 'port' in message:
-      self.port = message['port']
-    logging.info('[{0:d}] Resolving {1}:{2:d}'.format(self.client_id, self.hostname, self.port))
-    if self.hostname == 'localhost':
-      self.hostname = '127.0.0.1'
-    if self.hostname == '127.0.0.1':
-      logging.info('[{0:d}] Connection to localhost detected'.format(self.client_id))
-      self.is_localhost = True
-    if (dest_addresses is not None) and (not self.is_localhost or map_localhost):
-      logging.info('[{0:d}] Resolving {1}:{2:d} to mapped address {3}'.format(self.client_id, self.hostname, self.port, dest_addresses))
-      self.SendMessage('resolved', {'addresses': dest_addresses})
-    else:
-      lock.acquire()
-      background_activity_count += 1
-      lock.release()
-      self.state = self.STATE_RESOLVING
-      self.dns_thread = AsyncDNS(self.client_id, self.hostname, self.port, in_pipe)
-      self.dns_thread.start()
-
-  def HandleConnect(self, message):
-    global map_localhost
-    if 'addresses' in message and len(message['addresses']):
-      self.state = self.STATE_CONNECTING
-      if not self.did_resolve and message['addresses'][0] == '127.0.0.1':
-        logging.info('[{0:d}] Connection to localhost detected'.format(self.client_id))
-        self.is_localhost = True
-      if (dest_addresses is not None) and (not self.is_localhost or map_localhost):
-        self.addr = dest_addresses[0]
-      else:
-        self.addr = message['addresses'][0]
-      self.create_socket(self.addr[0], socket.SOCK_STREAM)
-      addr = self.addr[4][0]
-      if not self.is_localhost or map_localhost:
-        port = GetDestPort(message['port'])
-      else:
-        port = message['port']
-      logging.info('[{0:d}] Connecting to {1}:{2:d}'.format(self.client_id, addr, port))
-      self.connect((addr, port))
-
-
-########################################################################################################################
-#   Socks5 Server
-########################################################################################################################
-class Socks5Server(asyncore.dispatcher):
-
-  def __init__(self, host, port):
-    asyncore.dispatcher.__init__(self)
-    self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
-    try:
-      #self.set_reuse_addr()
-      self.bind((host, port))
-      self.listen(socket.SOMAXCONN)
-      self.ipaddr, self.port = self.getsockname()
-      self.current_client_id = 0
-    except:
-      PrintMessage("Unable to listen on {0}:{1}. Is the port already in use?".format(host, port))
-      exit(1)
-
-  def handle_accept(self):
-    global connections
-    pair = self.accept()
-    if pair is not None:
-      sock, addr = pair
-      self.current_client_id += 1
-      logging.info('[{0:d}] Incoming connection from {1}'.format(self.current_client_id, repr(addr)))
-      connections[self.current_client_id] = {
-        'client' : Socks5Connection(sock, self.current_client_id),
-        'server' : None
-      }
-
-
-# Socks5 reference: https://en.wikipedia.org/wiki/SOCKS#SOCKS5
-class Socks5Connection(asyncore.dispatcher):
-  STATE_ERROR = -1
-  STATE_WAITING_FOR_HANDSHAKE = 0
-  STATE_WAITING_FOR_CONNECT_REQUEST = 1
-  STATE_RESOLVING = 2
-  STATE_CONNECTING = 3
-  STATE_CONNECTED = 4
-
-  def __init__(self, connected_socket, client_id):
-    global options
-    asyncore.dispatcher.__init__(self, connected_socket)
-    self.client_id = client_id
-    self.state = self.STATE_WAITING_FOR_HANDSHAKE
-    self.ip = None
-    self.addresses = None
-    self.hostname = None
-    self.port = None
-    self.requested_address = None
-    self.buffer = ''
-    self.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
-    self.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 128 * 1024)
-    self.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 128 * 1024)
-    self.needs_close = False
-
-  def SendMessage(self, type, message):
-    message['message'] = type
-    message['connection'] = self.client_id
-    out_pipe.SendMessage(message)
-
-  def handle_message(self, message):
-    if message['message'] == 'data' and 'data' in message and len(message['data']) > 0:
-      self.buffer += message['data']
-      if self.state == self.STATE_CONNECTED:
-        self.handle_write()
-    elif message['message'] == 'resolved':
-      self.HandleResolved(message)
-    elif message['message'] == 'connected':
-      self.HandleConnected(message)
-      self.handle_write()
-    elif message['message'] == 'closed':
-      if len(self.buffer) == 0:
-        logging.info('[{0:d}] Server connection close being processed, closing Browser connection'.format(self.client_id))
-        self.handle_close()
-      else:
-        logging.info('[{0:d}] Server connection close being processed, queuing browser connection close'.format(self.client_id))
-        self.needs_close = True
-
-  def writable(self):
-    return len(self.buffer) > 0
-
-  def handle_write(self):
-    if len(self.buffer) > 0:
-      sent = self.send(self.buffer)
-      logging.debug('[{0:d}] SOCKS <= {1:d} byte(s)'.format(self.client_id, sent))
-      self.buffer = self.buffer[sent:]
-      if self.needs_close and len(self.buffer) == 0:
-        logging.info('[{0:d}] queued browser connection close being processed, closing Browser connection'.format(self.client_id))
-        self.needs_close = False
-        self.handle_close()
-
-  def handle_read(self):
-    global connections
-    global dns_cache
-    try:
-      while True:
-        # Consume in up-to packet-sized chunks (TCP packet payload as 1460 bytes from 1500 byte ethernet frames)
-        data = self.recv(1460)
-        if data:
-          data_len = len(data)
-          if self.state == self.STATE_CONNECTED:
-            logging.debug('[{0:d}] SOCKS => {1:d} byte(s)'.format(self.client_id, data_len))
-            self.SendMessage('data', {'data': data})
-          elif self.state == self.STATE_WAITING_FOR_HANDSHAKE:
-            self.state = self.STATE_ERROR #default to an error state, set correctly if things work out
-            if data_len >= 2 and ord(data[0]) == 0x05:
-              supports_no_auth = False
-              auth_count = ord(data[1])
-              if data_len == auth_count + 2:
-                for i in range(auth_count):
-                  offset = i + 2
-                  if ord(data[offset]) == 0:
-                    supports_no_auth = True
-              if supports_no_auth:
-                # Respond with a message that "No Authentication" was agreed to
-                logging.info('[{0:d}] New Socks5 client'.format(self.client_id))
-                response = chr(0x05) + chr(0x00)
-                self.state = self.STATE_WAITING_FOR_CONNECT_REQUEST
-                self.buffer += response
-                self.handle_write()
-          elif self.state == self.STATE_WAITING_FOR_CONNECT_REQUEST:
-            self.state = self.STATE_ERROR #default to an error state, set correctly if things work out
-            if data_len >= 10 and ord(data[0]) == 0x05 and ord(data[2]) == 0x00:
-              if ord(data[1]) == 0x01: #TCP connection (only supported method for now)
-                connections[self.client_id]['server'] = TCPConnection(self.client_id)
-              self.requested_address = data[3:]
-              port_offset = 0
-              if ord(data[3]) == 0x01:
-                port_offset = 8
-                self.ip = '{0:d}.{1:d}.{2:d}.{3:d}'.format(ord(data[4]), ord(data[5]), ord(data[6]), ord(data[7]))
-              elif ord(data[3]) == 0x03:
-                name_len = ord(data[4])
-                if data_len >= 6 + name_len:
-                  port_offset = 5 + name_len
-                  self.hostname = data[5:5 + name_len]
-              elif ord(data[3]) == 0x04 and data_len >= 22:
-                port_offset = 20
-                self.ip = ''
-                for i in range(16):
-                  self.ip += '{0:02x}'.format(ord(data[4 + i]))
-                  if i % 2 and i < 15:
-                    self.ip += ':'
-              if port_offset and connections[self.client_id]['server'] is not None:
-                self.port = 256 * ord(data[port_offset]) + ord(data[port_offset + 1])
-                if self.port:
-                  if self.ip is None and self.hostname is not None:
-                    if self.hostname in dns_cache:
-                      self.state = self.STATE_CONNECTING
-                      self.addresses = dns_cache[self.hostname]
-                      self.SendMessage('connect', {'addresses': self.addresses, 'port': self.port})
-                    else:
-                      self.state = self.STATE_RESOLVING
-                      self.SendMessage('resolve', {'hostname': self.hostname, 'port': self.port})
-                  elif self.ip is not None:
-                    self.state = self.STATE_CONNECTING
-                    logging.debug('[{0:d}] Socks Connect - calling getaddrinfo for {1}:{2:d}'.format(self.client_id, self.ip, self.port))
-                    self.addresses = socket.getaddrinfo(self.ip, self.port)
-                    self.SendMessage('connect', {'addresses': self.addresses, 'port': self.port})
-        else:
-          return
-    except:
-      pass
-
-  def handle_close(self):
-    logging.info('[{0:d}] Browser Connection Closed by browser'.format(self.client_id))
-    self.state = self.STATE_ERROR
-    self.close()
-    try:
-      if self.client_id in connections:
-        if 'client' in connections[self.client_id]:
-          del connections[self.client_id]['client']
-        if 'server' in connections[self.client_id]:
-          self.SendMessage('closed', {})
-        else:
-          del connections[self.client_id]
-    except:
-      pass
-
-  def HandleResolved(self, message):
-    global dns_cache
-    if self.state == self.STATE_RESOLVING:
-      if 'addresses' in message and len(message['addresses']):
-        self.state = self.STATE_CONNECTING
-        self.addresses = message['addresses']
-        dns_cache[self.hostname] = self.addresses
-        logging.debug('[{0:d}] Resolved {1}, Connecting'.format(self.client_id, self.hostname))
-        self.SendMessage('connect', {'addresses': self.addresses, 'port': self.port})
-      else:
-        # Send host unreachable error
-        self.state = self.STATE_ERROR
-        self.buffer += chr(0x05) + chr(0x04) + self.requested_address
-        self.handle_write()
-
-  def HandleConnected(self, message):
-    if 'success' in message and self.state == self.STATE_CONNECTING:
-      response = chr(0x05)
-      if message['success']:
-        response += chr(0x00)
-        logging.debug('[{0:d}] Connected to {1}'.format(self.client_id, self.hostname))
-        self.state = self.STATE_CONNECTED
-      else:
-        response += chr(0x04)
-        self.state = self.STATE_ERROR
-      response += chr(0x00)
-      response += self.requested_address
-      self.buffer += response
-      self.handle_write()
-
-
-########################################################################################################################
-#   stdin command processor
-########################################################################################################################
-class CommandProcessor():
-  def __init__(self):
-    thread = threading.Thread(target = self.run, args=())
-    thread.daemon = True
-    thread.start()
-
-  def run(self):
-    global must_exit
-    while not must_exit:
-      for line in iter(sys.stdin.readline, ''):
-        self.ProcessCommand(line.strip())
-
-  def ProcessCommand(self, input):
-    global in_pipe
-    global out_pipe
-    global needs_flush
-    global REMOVE_TCP_OVERHEAD
-    global port_mappings
-    global server
-    if len(input):
-      ok = False
-      try:
-        command = input.split()
-        if len(command) and len(command[0]):
-          if command[0].lower() == 'flush':
-            ok = True
-          elif command[0].lower() == 'set' and len(command) >= 3:
-            if command[1].lower() == 'rtt' and len(command[2]):
-              rtt = float(command[2])
-              latency = rtt / 2000.0
-              in_pipe.latency = latency
-              out_pipe.latency = latency
-              ok = True
-            elif command[1].lower() == 'inkbps' and len(command[2]):
-              in_pipe.kbps = float(command[2]) * REMOVE_TCP_OVERHEAD
-              ok = True
-            elif command[1].lower() == 'outkbps' and len(command[2]):
-              out_pipe.kbps = float(command[2]) * REMOVE_TCP_OVERHEAD
-              ok = True
-            elif command[1].lower() == 'mapports' and len(command[2]):
-              SetPortMappings(command[2])
-              ok = True
-          elif command[0].lower() == 'reset' and len(command) >= 2:
-            if command[1].lower() == 'rtt' or command[1].lower() == 'all':
-              in_pipe.latency = 0
-              out_pipe.latency = 0
-              ok = True
-            if command[1].lower() == 'inkbps' or command[1].lower() == 'all':
-              in_pipe.kbps = 0
-              ok = True
-            if command[1].lower() == 'outkbps' or command[1].lower() == 'all':
-              out_pipe.kbps = 0
-              ok = True
-            if command[1].lower() == 'mapports' or command[1].lower() == 'all':
-              port_mappings = {}
-              ok = True
-
-          if ok:
-            needs_flush = True
-      except:
-        pass
-      if not ok:
-        PrintMessage('ERROR')
-      # open and close a local socket which will interrupt the long polling loop to process the flush
-      if needs_flush:
-        s = socket.socket()
-        s.connect((server.ipaddr, server.port))
-        s.close()
-
-
-########################################################################################################################
-#   Main Entry Point
-########################################################################################################################
-def main():
-  global server
-  global options
-  global in_pipe
-  global out_pipe
-  global dest_addresses
-  global port_mappings
-  global map_localhost
-  import argparse
-  global REMOVE_TCP_OVERHEAD
-  parser = argparse.ArgumentParser(description='Traffic-shaping socks5 proxy.',
-                                   prog='tsproxy')
-  parser.add_argument('-v', '--verbose', action='count', help="Increase verbosity (specify multiple times for more). -vvvv for full debug output.")
-  parser.add_argument('--logfile', help="Write log messages to given file instead of stdout.")
-  parser.add_argument('-b', '--bind', default='localhost', help="Server interface address (defaults to localhost).")
-  parser.add_argument('-p', '--port', type=int, default=1080, help="Server port (defaults to 1080, use 0 for randomly assigned).")
-  parser.add_argument('-r', '--rtt', type=float, default=.0, help="Round Trip Time Latency (in ms).")
-  parser.add_argument('-i', '--inkbps', type=float, default=.0, help="Download Bandwidth (in 1000 bits/s - Kbps).")
-  parser.add_argument('-o', '--outkbps', type=float, default=.0, help="Upload Bandwidth (in 1000 bits/s - Kbps).")
-  parser.add_argument('-w', '--window', type=int, default=10, help="Emulated TCP initial congestion window (defaults to 10).")
-  parser.add_argument('-d', '--desthost', help="Redirect all outbound connections to the specified host.")
-  parser.add_argument('-m', '--mapports', help="Remap outbound ports. Comma-separated list of original:new with * as a wildcard. --mapports '443:8443,*:8080'")
-  parser.add_argument('-l', '--localhost', action='store_true', default=False,
-                      help="Include connections already destined for localhost/127.0.0.1 in the host and port remapping.")
-  options = parser.parse_args()
-
-  # Set up logging
-  log_level = logging.CRITICAL
-  if options.verbose == 1:
-    log_level = logging.ERROR
-  elif options.verbose == 2:
-    log_level = logging.WARNING
-  elif options.verbose == 3:
-    log_level = logging.INFO
-  elif options.verbose >= 4:
-    log_level = logging.DEBUG
-  if options.logfile is not None:
-    logging.basicConfig(filename=options.logfile, level=log_level,
-                        format="%(asctime)s.%(msecs)03d - %(message)s", datefmt="%H:%M:%S")
-  else:
-    logging.basicConfig(level=log_level, format="%(asctime)s.%(msecs)03d - %(message)s", datefmt="%H:%M:%S")
-
-  # Parse any port mappings
-  if options.mapports:
-    SetPortMappings(options.mapports)
-
-  map_localhost = options.localhost
-
-  # Resolve the address for a rewrite destination host if one was specified
-  if options.desthost:
-    logging.debug('Startup - calling getaddrinfo for {0}:{1:d}'.format(options.desthost, GetDestPort(80)))
-    dest_addresses = socket.getaddrinfo(options.desthost, GetDestPort(80))
-
-  # Set up the pipes.  1/2 of the latency gets applied in each direction (and /1000 to convert to seconds)
-  in_pipe = TSPipe(TSPipe.PIPE_IN, options.rtt / 2000.0, options.inkbps * REMOVE_TCP_OVERHEAD)
-  out_pipe = TSPipe(TSPipe.PIPE_OUT, options.rtt / 2000.0, options.outkbps * REMOVE_TCP_OVERHEAD)
-
-  signal.signal(signal.SIGINT, signal_handler)
-  server = Socks5Server(options.bind, options.port)
-  command_processor = CommandProcessor()
-  PrintMessage('Started Socks5 proxy server on {0}:{1:d}\nHit Ctrl-C to exit.'.format(server.ipaddr, server.port))
-  run_loop()
-
-def signal_handler(signal, frame):
-  global server
-  global must_exit
-  logging.error('Exiting...')
-  must_exit = True
-  del server
-
-
-# Wrapper around the asyncore loop that lets us poll the in/out pipes every 1ms
-def run_loop():
-  global must_exit
-  global in_pipe
-  global out_pipe
-  global needs_flush
-  global flush_pipes
-  global last_activity
-  winmm = None
-
-  # increase the windows timer resolution to 1ms
-  if platform.system() == "Windows":
-    try:
-      import ctypes
-      winmm = ctypes.WinDLL('winmm')
-      winmm.timeBeginPeriod(1)
-    except:
-      pass
-
-  last_activity = time.clock()
-  last_check = time.clock()
-  # disable gc to avoid pauses during traffic shaping/proxying
-  gc.disable()
-  while not must_exit:
-    # Tick every 1ms if traffic-shaping is enabled and we have data or are doing background dns lookups, every 1 second otherwise
-    lock.acquire()
-    tick_interval = 0.001
-    if background_activity_count == 0:
-      if in_pipe.next_message is None and in_pipe.queue.empty() and out_pipe.next_message is None and out_pipe.queue.empty():
-        tick_interval = 1.0
-      elif in_pipe.kbps == .0 and in_pipe.latency == 0 and out_pipe.kbps == .0 and out_pipe.latency == 0:
-        tick_interval = 1.0
-    lock.release()
-    asyncore.poll(tick_interval, asyncore.socket_map)
-    if needs_flush:
-      flush_pipes = True
-      needs_flush = False
-    out_pipe.tick()
-    in_pipe.tick()
-    if flush_pipes:
-      PrintMessage('OK')
-      flush_pipes = False
-    # Every 500 ms check to see if it is a good time to do a gc
-    now = time.clock()
-    if now - last_check > 0.5:
-      last_check = now
-      # manually gc after 5 seconds of idle
-      if now - last_activity >= 5:
-        last_activity = now
-        logging.debug("Triggering manual GC")
-        gc.collect()
-
-  if winmm is not None:
-    winmm.timeEndPeriod(1)
-
-def GetDestPort(port):
-  global port_mappings
-  if port_mappings is not None:
-    src_port = str(port)
-    if src_port in port_mappings:
-      return port_mappings[src_port]
-    elif 'default' in port_mappings:
-      return port_mappings['default']
-  return port
-
-
-def SetPortMappings(map_string):
-  global port_mappings
-  port_mappings = {}
-  map_string = map_string.strip('\'" \t\r\n')
-  for pair in map_string.split(','):
-    (src, dest) = pair.split(':')
-    if src == '*':
-      port_mappings['default'] = int(dest)
-      logging.debug("Default port mapped to port {0}".format(dest))
-    else:
-      logging.debug("Port {0} mapped to port {1}".format(src, dest))
-      port_mappings[src] = int(dest)
-
-
-if '__main__' == __name__:
-  main()
diff --git a/catapult/telemetry/third_party/web-page-replay/.coveragerc b/catapult/telemetry/third_party/web-page-replay/.coveragerc
deleted file mode 100644
index 9e3b31a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/.coveragerc
+++ /dev/null
@@ -1,4 +0,0 @@
-[report]
-omit =
-  */python?.?/*
-  */third_party/*
diff --git a/catapult/telemetry/third_party/web-page-replay/.gitignore b/catapult/telemetry/third_party/web-page-replay/.gitignore
deleted file mode 100644
index 0d20b64..0000000
--- a/catapult/telemetry/third_party/web-page-replay/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-*.pyc
diff --git a/catapult/telemetry/third_party/web-page-replay/.travis.yml b/catapult/telemetry/third_party/web-page-replay/.travis.yml
deleted file mode 100644
index 23e151b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/.travis.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-language: python
-
-python:
- - "2.7"
-
-install:
- - pip install -r requirements.txt
- - pip install coveralls
-
-# traffic_shaper test requires sudo.
-sudo: required
-
-script:
- - sudo $(which coverage) run run_tests
-
-after_script:
- - coveralls
-
-notifications:
- email: false
diff --git a/catapult/telemetry/third_party/web-page-replay/COPYING b/catapult/telemetry/third_party/web-page-replay/COPYING
deleted file mode 100644
index d645695..0000000
--- a/catapult/telemetry/third_party/web-page-replay/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/catapult/telemetry/third_party/web-page-replay/PRESUBMIT.py b/catapult/telemetry/third_party/web-page-replay/PRESUBMIT.py
deleted file mode 100644
index 5948576..0000000
--- a/catapult/telemetry/third_party/web-page-replay/PRESUBMIT.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for changes affecting tools/perf/.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details about the presubmit API built into depot_tools.
-"""
-
-def _CommonChecks(input_api, output_api):
-  """Performs common checks, which includes running pylint."""
-  results = []
-  results.extend(input_api.canned_checks.RunPylint(
-        input_api, output_api, black_list=[], pylintrc='pylintrc'))
-  return results
-
-
-def CheckChangeOnUpload(input_api, output_api):
-  report = []
-  report.extend(_CommonChecks(input_api, output_api))
-  return report
-
-
-def CheckChangeOnCommit(input_api, output_api):
-  report = []
-  report.extend(_CommonChecks(input_api, output_api))
-  return report
diff --git a/catapult/telemetry/third_party/web-page-replay/README.chromium b/catapult/telemetry/third_party/web-page-replay/README.chromium
deleted file mode 100644
index 0a1b657..0000000
--- a/catapult/telemetry/third_party/web-page-replay/README.chromium
+++ /dev/null
@@ -1,14 +0,0 @@
-Name: chromite
-Short Name: webpagereplay
-URL: https://github.com/chromium/web-page-replay
-Version: 6cffdf1fb6c9a6d5dccbcc9cc18b8738a538eeba (commit hash)
-License: BSD
-License File: NOT_SHIPPED
-Security Critical: no
-
-Local modification: Remove webpagereplay/third_party/ipaddr/OWNERS to avoid
-PRESUBMIT complainings about non-standard OWNER format.
-
-Description:
-This contains webpagereplay used by telemetry for record & replay web requests &
-responses.
diff --git a/catapult/telemetry/third_party/web-page-replay/README.md b/catapult/telemetry/third_party/web-page-replay/README.md
deleted file mode 100644
index 28a3dc3..0000000
--- a/catapult/telemetry/third_party/web-page-replay/README.md
+++ /dev/null
@@ -1,28 +0,0 @@
-[![Build
-Status](https://travis-ci.org/chromium/web-page-replay.png)](https://travis-ci.org/chromium/web-page-replay)
-[![Coverage
-Status](https://coveralls.io/repos/chromium/web-page-replay/badge.svg)](https://coveralls.io/r/chromium/web-page-replay)
-
-# Web Page Replay
-Record live Web pages and use them for local performance testing!
-
-## How?
-Use local DNS and HTTP(S) proxies to captures your live traffic. Then
-use these captures in order to replay the same exact content, making
-sure that your tests get consistent results, that are not affected by
-the origin servers, the network, etc.
-
-## Tell me more
-Check out the [getting
-started](documentation/GettingStarted.md) guide or take a
-look at the [architecture
-diagram](documentation/WebPageReplayDiagram.png).
-
-Also see [Note about web-page-replay
-code](https://docs.google.com/document/d/1cehHn3Lig7UYw_7pqQJjkbPTV3kS11EYwjKO-6jT0c8)
-
-## I want to help
-If you find issues with the project, you can file issues on this repo.
-If you want to do more and contribute code to help the project evolve,
-check out our [contribution
-guidelines](documentation/Contributing.md).
diff --git a/catapult/telemetry/third_party/web-page-replay/adb_install_cert.py b/catapult/telemetry/third_party/web-page-replay/adb_install_cert.py
deleted file mode 100644
index 7d56df4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/adb_install_cert.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Installs certificate on phone with KitKat."""
-
-import argparse
-import logging
-import os
-import subprocess
-import sys
-
-KEYCODE_ENTER = '66'
-KEYCODE_TAB = '61'
-
-
-class CertInstallError(Exception):
-  pass
-
-
-class CertRemovalError(Exception):
-  pass
-
-
-class AdbShellError(subprocess.CalledProcessError):
-  pass
-
-
-_ANDROID_M_BUILD_VERSION = 23
-
-
-class AndroidCertInstaller(object):
-  """Certificate installer for phones with KitKat."""
-
-  def __init__(self, device_id, cert_name, cert_path, adb_path=None):
-    if not os.path.exists(cert_path):
-      raise ValueError('Not a valid certificate path')
-    self.adb_path = adb_path or 'adb'
-    self.android_cacerts_path = None
-    self.cert_name = cert_name
-    self.cert_path = cert_path
-    self.device_id = device_id
-    self.file_name = os.path.basename(self.cert_path)
-    self.reformatted_cert_fname = None
-    self.reformatted_cert_path = None
-
-  @staticmethod
-  def _run_cmd(cmd, dirname=None):
-    return subprocess.check_output(cmd, cwd=dirname)
-
-  def _get_adb_cmd(self, *args):
-    cmd = [self.adb_path]
-    if self.device_id:
-      cmd.extend(['-s', self.device_id])
-    cmd.extend(args)
-    return cmd
-
-  def _adb(self, *args):
-    """Runs the adb command."""
-    return self._run_cmd(self._get_adb_cmd(*args))
-
-  def _adb_shell(self, *args):
-    """Runs the adb shell command."""
-    # We are not using self._adb() because adb shell return 0 even if the
-    # command has failed. This method is taking care of checking the actual
-    # return code of the command line ran on the device.
-    RETURN_CODE_PREFIX = '%%%s%% ' % __file__
-    adb_cmd = self._get_adb_cmd('shell', '(%s); echo %s$?' % (
-        subprocess.list2cmdline(args), RETURN_CODE_PREFIX))
-    process = subprocess.Popen(adb_cmd, stdout=subprocess.PIPE)
-    adb_stdout, _ = process.communicate()
-    if process.returncode != 0:
-      raise subprocess.CalledProcessError(
-          cmd=adb_cmd, returncode=process.returncode, output=adb_stdout)
-    assert adb_stdout[-1] == '\n'
-    prefix_pos = adb_stdout.rfind(RETURN_CODE_PREFIX)
-    assert prefix_pos != -1, \
-        'Couldn\'t find "%s" at the end of the output of %s' % (
-            RETURN_CODE_PREFIX, subprocess.list2cmdline(adb_cmd))
-    returncode = int(adb_stdout[prefix_pos + len(RETURN_CODE_PREFIX):])
-    stdout = adb_stdout[:prefix_pos]
-    if returncode != 0:
-      raise AdbShellError(cmd=args, returncode=returncode, output=stdout)
-    return stdout
-
-  def _adb_su_shell(self, *args):
-    """Runs command as root."""
-    build_version_sdk = int(self._get_property('ro.build.version.sdk'))
-    if build_version_sdk >= _ANDROID_M_BUILD_VERSION:
-      cmd = ['su', '0']
-    else:
-      cmd = ['su', '-c']
-    cmd.extend(args)
-    return self._adb_shell(*cmd)
-
-  def _get_property(self, prop):
-    return self._adb_shell('getprop', prop).strip()
-
-  def check_device(self):
-    install_warning = False
-    if self._get_property('ro.product.device') != 'hammerhead':
-      logging.warning('Device is not hammerhead')
-      install_warning = True
-    if self._get_property('ro.build.version.release') != '4.4.2':
-      logging.warning('Version is not 4.4.2')
-      install_warning = True
-    if install_warning:
-      logging.warning('Certificate may not install properly')
-
-  def _input_key(self, key):
-    """Inputs a keyevent."""
-    self._adb_shell('input', 'keyevent', key)
-
-  def _input_text(self, text):
-    """Inputs text."""
-    self._adb_shell('input', 'text', text)
-
-  @staticmethod
-  def _remove(file_name):
-    """Deletes file."""
-    if os.path.exists(file_name):
-      os.remove(file_name)
-
-  def _format_hashed_cert(self):
-    """Makes a certificate file that follows the format of files in cacerts."""
-    self._remove(self.reformatted_cert_path)
-    contents = self._run_cmd(['openssl', 'x509', '-inform', 'PEM', '-text',
-                              '-in', self.cert_path])
-    description, begin_cert, cert_body = contents.rpartition('-----BEGIN '
-                                                             'CERTIFICATE')
-    contents = ''.join([begin_cert, cert_body, description])
-    with open(self.reformatted_cert_path, 'w') as cert_file:
-      cert_file.write(contents)
-
-  def _remove_cert_from_cacerts(self):
-    self._adb_su_shell('mount', '-o', 'remount,rw', '/system')
-    self._adb_su_shell('rm', '-f', self.android_cacerts_path)
-
-  def _is_cert_installed(self):
-    try:
-      return (self._adb_su_shell('ls', self.android_cacerts_path).strip() ==
-              self.android_cacerts_path)
-    except AdbShellError:
-      return False
-
-  def _generate_reformatted_cert_path(self):
-    # Determine OpenSSL version, string is of the form
-    # 'OpenSSL 0.9.8za 5 Jun 2014' .
-    openssl_version = self._run_cmd(['openssl', 'version']).split()
-
-    if len(openssl_version) < 2:
-      raise ValueError('Unexpected OpenSSL version string: ', openssl_version)
-
-    # subject_hash flag name changed as of OpenSSL version 1.0.0 .
-    is_old_openssl_version = openssl_version[1].startswith('0')
-    subject_hash_flag = (
-        '-subject_hash' if is_old_openssl_version else '-subject_hash_old')
-
-    output = self._run_cmd(['openssl', 'x509', '-inform', 'PEM',
-                            subject_hash_flag, '-in', self.cert_path],
-                           os.path.dirname(self.cert_path))
-    self.reformatted_cert_fname = output.partition('\n')[0].strip() + '.0'
-    self.reformatted_cert_path = os.path.join(os.path.dirname(self.cert_path),
-                                              self.reformatted_cert_fname)
-    self.android_cacerts_path = ('/system/etc/security/cacerts/%s' %
-                                 self.reformatted_cert_fname)
-
-  def remove_cert(self):
-    self._generate_reformatted_cert_path()
-
-    if self._is_cert_installed():
-      self._remove_cert_from_cacerts()
-
-    if self._is_cert_installed():
-      raise CertRemovalError('Cert Removal Failed')
-
-  def install_cert(self, overwrite_cert=False):
-    """Installs a certificate putting it in /system/etc/security/cacerts."""
-    self._generate_reformatted_cert_path()
-
-    if self._is_cert_installed():
-      if overwrite_cert:
-        self._remove_cert_from_cacerts()
-      else:
-        logging.info('cert is already installed')
-        return
-
-    self._format_hashed_cert()
-    self._adb('push', self.reformatted_cert_path, '/sdcard/')
-    self._remove(self.reformatted_cert_path)
-    self._adb_su_shell('mount', '-o', 'remount,rw', '/system')
-    self._adb_su_shell(
-        'cp', '/sdcard/%s' % self.reformatted_cert_fname,
-        '/system/etc/security/cacerts/%s' % self.reformatted_cert_fname)
-    self._adb_su_shell('chmod', '644', self.android_cacerts_path)
-    if not self._is_cert_installed():
-      raise CertInstallError('Cert Install Failed')
-
-  def install_cert_using_gui(self):
-    """Installs certificate on the device using adb commands."""
-    self.check_device()
-    # TODO(mruthven): Add a check to see if the certificate is already installed
-    # Install the certificate.
-    logging.info('Installing %s on %s', self.cert_path, self.device_id)
-    self._adb('push', self.cert_path, '/sdcard/')
-
-    # Start credential install intent.
-    self._adb_shell('am', 'start', '-W', '-a', 'android.credentials.INSTALL')
-
-    # Move to and click search button.
-    self._input_key(KEYCODE_TAB)
-    self._input_key(KEYCODE_TAB)
-    self._input_key(KEYCODE_ENTER)
-
-    # Search for certificate and click it.
-    # Search only works with lower case letters
-    self._input_text(self.file_name.lower())
-    self._input_key(KEYCODE_ENTER)
-
-    # These coordinates work for hammerhead devices.
-    self._adb_shell('input', 'tap', '300', '300')
-
-    # Name the certificate and click enter.
-    self._input_text(self.cert_name)
-    self._input_key(KEYCODE_TAB)
-    self._input_key(KEYCODE_TAB)
-    self._input_key(KEYCODE_TAB)
-    self._input_key(KEYCODE_ENTER)
-
-    # Remove the file.
-    self._adb_shell('rm', '/sdcard/' + self.file_name)
-
-
-def parse_args():
-  """Parses command line arguments."""
-  parser = argparse.ArgumentParser(description='Install cert on device.')
-  parser.add_argument(
-      '-n', '--cert-name', default='dummycert', help='certificate name')
-  parser.add_argument(
-      '--overwrite', default=False, action='store_true',
-      help='Overwrite certificate file if it is already installed')
-  parser.add_argument(
-      '--remove', default=False, action='store_true',
-      help='Remove certificate file if it is installed')
-  parser.add_argument(
-      '--device-id', help='device serial number')
-  parser.add_argument(
-      '--adb-path', help='adb binary path')
-  parser.add_argument(
-      'cert_path', help='Certificate file path')
-  return parser.parse_args()
-
-
-def main():
-  args = parse_args()
-  cert_installer = AndroidCertInstaller(args.device_id, args.cert_name,
-                                        args.cert_path, adb_path=args.adb_path)
-  if args.remove:
-    cert_installer.remove_cert()
-  else:
-    cert_installer.install_cert(args.overwrite)
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/catapult/telemetry/third_party/web-page-replay/certutils.py b/catapult/telemetry/third_party/web-page-replay/certutils.py
deleted file mode 100644
index 46c31a8..0000000
--- a/catapult/telemetry/third_party/web-page-replay/certutils.py
+++ /dev/null
@@ -1,289 +0,0 @@
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Routines to generate root and server certificates.
-
-Certificate Naming Conventions:
-  ca_cert:  crypto.X509 for the certificate authority (w/ both the pub &
-                priv keys)
-  cert:  a crypto.X509 certificate (w/ just the pub key)
-  cert_str:  a certificate string (w/ just the pub cert)
-  key:  a private crypto.PKey  (from ca or pem)
-  ca_cert_str:  a certificae authority string (w/ both the pub & priv certs)
-"""
-
-import logging
-import os
-import platform
-import socket
-import subprocess
-import time
-
-openssl_import_error = None
-
-Error = None
-SSL_METHOD = None
-SysCallError = None
-VERIFY_PEER = None
-ZeroReturnError = None
-FILETYPE_PEM = None
-
-try:
-  from OpenSSL import crypto, SSL
-
-  Error = SSL.Error
-  SSL_METHOD = SSL.SSLv23_METHOD
-  SysCallError = SSL.SysCallError
-  VERIFY_PEER = SSL.VERIFY_PEER
-  ZeroReturnError = SSL.ZeroReturnError
-  FILETYPE_PEM = crypto.FILETYPE_PEM
-except ImportError, e:
-  openssl_import_error = e
-
-
-def get_ssl_context(method=SSL_METHOD):
-  # One of: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or TLSv1_METHOD
-  if openssl_import_error:
-    raise openssl_import_error  # pylint: disable=raising-bad-type
-  return SSL.Context(method)
-
-
-class WrappedConnection(object):
-
-  def __init__(self, obj):
-    self._wrapped_obj = obj
-
-  def __getattr__(self, attr):
-    if attr in self.__dict__:
-      return getattr(self, attr)
-    return getattr(self._wrapped_obj, attr)
-
-  def recv(self, buflen=1024, flags=0):
-    try:
-      return self._wrapped_obj.recv(buflen, flags)
-    except SSL.SysCallError, e:
-      if e.args[1] == 'Unexpected EOF':
-        return ''
-      raise
-    except SSL.ZeroReturnError:
-      return ''
-
-
-def get_ssl_connection(context, connection):
-  return WrappedConnection(SSL.Connection(context, connection))
-
-
-def load_privatekey(key, filetype=FILETYPE_PEM):
-  """Loads obj private key object from string."""
-  return crypto.load_privatekey(filetype, key)
-
-
-def load_cert(cert_str, filetype=FILETYPE_PEM):
-  """Loads obj cert object from string."""
-  return crypto.load_certificate(filetype, cert_str)
-
-
-def _dump_privatekey(key, filetype=FILETYPE_PEM):
-  """Dumps obj private key object to string."""
-  return crypto.dump_privatekey(filetype, key)
-
-
-def _dump_cert(cert, filetype=FILETYPE_PEM):
-  """Dumps obj cert object to string."""
-  return crypto.dump_certificate(filetype, cert)
-
-
-def generate_dummy_ca_cert(subject='_WebPageReplayCert'):
-  """Generates dummy certificate authority.
-
-  Args:
-    subject: a string representing the desired root cert issuer
-  Returns:
-    A tuple of the public key and the private key strings for the root
-    certificate
-  """
-  if openssl_import_error:
-    raise openssl_import_error  # pylint: disable=raising-bad-type
-
-  key = crypto.PKey()
-  key.generate_key(crypto.TYPE_RSA, 1024)
-
-  ca_cert = crypto.X509()
-  ca_cert.set_serial_number(int(time.time()*10000))
-  ca_cert.set_version(2)
-  ca_cert.get_subject().CN = subject
-  ca_cert.get_subject().O = subject
-  ca_cert.gmtime_adj_notBefore(-60 * 60 * 24 * 365 * 2)
-  ca_cert.gmtime_adj_notAfter(60 * 60 * 24 * 365 * 2)
-  ca_cert.set_issuer(ca_cert.get_subject())
-  ca_cert.set_pubkey(key)
-  ca_cert.add_extensions([
-      crypto.X509Extension('basicConstraints', True, 'CA:TRUE'),
-      crypto.X509Extension('subjectAltName', False, 'DNS:' + subject),
-      crypto.X509Extension('nsCertType', True, 'sslCA'),
-      crypto.X509Extension('extendedKeyUsage', True,
-                           ('serverAuth,clientAuth,emailProtection,'
-                            'timeStamping,msCodeInd,msCodeCom,msCTLSign,'
-                            'msSGC,msEFS,nsSGC')),
-      crypto.X509Extension('keyUsage', False, 'keyCertSign, cRLSign'),
-      crypto.X509Extension('subjectKeyIdentifier', False, 'hash',
-                           subject=ca_cert),
-      ])
-  ca_cert.sign(key, 'sha256')
-  key_str = _dump_privatekey(key)
-  ca_cert_str = _dump_cert(ca_cert)
-  return ca_cert_str, key_str
-
-
-def get_host_cert(host, port=443):
-  """Contacts the host and returns its certificate."""
-  host_certs = []
-  def verify_cb(conn, cert, errnum, depth, ok):
-    host_certs.append(cert)
-    # Return True to indicates that the certificate was ok.
-    return True
-
-  context = SSL.Context(SSL.SSLv23_METHOD)
-  context.set_verify(SSL.VERIFY_PEER, verify_cb)  # Demand a certificate
-  s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-  connection = SSL.Connection(context, s)
-  try:
-    connection.connect((host, port))
-    connection.send('')
-  except SSL.SysCallError:
-    pass
-  except socket.gaierror:
-    logging.debug('Host name is not valid')
-  finally:
-    connection.shutdown()
-    connection.close()
-  if not host_certs:
-    logging.warning('Unable to get host certificate from %s:%s', host, port)
-    return ''
-  return _dump_cert(host_certs[-1])
-
-
-def write_dummy_ca_cert(ca_cert_str, key_str, cert_path):
-  """Writes four certificate files.
-
-  For example, if cert_path is "mycert.pem":
-      mycert.pem - CA plus private key
-      mycert-cert.pem - CA in PEM format
-      mycert-cert.cer - CA for Android
-      mycert-cert.p12 - CA in PKCS12 format for Windows devices
-  Args:
-    cert_path: path string such as "mycert.pem"
-    ca_cert_str: certificate string
-    key_str: private key string
-  """
-  dirname = os.path.dirname(cert_path)
-  if dirname and not os.path.exists(dirname):
-    os.makedirs(dirname)
-
-  root_path = os.path.splitext(cert_path)[0]
-  ca_cert_path = root_path + '-cert.pem'
-  android_cer_path = root_path + '-cert.cer'
-  windows_p12_path = root_path + '-cert.p12'
-
-  # Dump the CA plus private key
-  with open(cert_path, 'w') as f:
-    f.write(key_str)
-    f.write(ca_cert_str)
-
-  # Dump the certificate in PEM format
-  with open(ca_cert_path, 'w') as f:
-    f.write(ca_cert_str)
-
-  # Create a .cer file with the same contents for Android
-  with open(android_cer_path, 'w') as f:
-    f.write(ca_cert_str)
-
-  ca_cert = load_cert(ca_cert_str)
-  key = load_privatekey(key_str)
-  # Dump the certificate in PKCS12 format for Windows devices
-  with open(windows_p12_path, 'w') as f:
-    p12 = crypto.PKCS12()
-    p12.set_certificate(ca_cert)
-    p12.set_privatekey(key)
-    f.write(p12.export())
-
-
-def generate_cert(root_ca_cert_str, server_cert_str, server_host):
-  """Generates a cert_str with the sni field in server_cert_str signed by the
-  root_ca_cert_str.
-
-  Args:
-    root_ca_cert_str: PEM formatted string representing the root cert
-    server_cert_str: PEM formatted string representing cert
-    server_host: host name to use if there is no server_cert_str
-  Returns:
-    a PEM formatted certificate string
-  """
-  EXTENSION_WHITELIST = set(['subjectAltName'])
-
-  if openssl_import_error:
-    raise openssl_import_error  # pylint: disable=raising-bad-type
-
-  common_name = server_host
-  reused_extensions = []
-  if server_cert_str:
-    original_cert = load_cert(server_cert_str)
-    common_name = original_cert.get_subject().commonName
-    for i in xrange(original_cert.get_extension_count()):
-      original_cert_extension = original_cert.get_extension(i)
-      if original_cert_extension.get_short_name() in EXTENSION_WHITELIST:
-        reused_extensions.append(original_cert_extension)
-
-  ca_cert = load_cert(root_ca_cert_str)
-  ca_key = load_privatekey(root_ca_cert_str)
-
-  cert = crypto.X509()
-  cert.get_subject().CN = common_name
-  cert.gmtime_adj_notBefore(-60 * 60)
-  cert.gmtime_adj_notAfter(60 * 60 * 24 * 30)
-  cert.set_issuer(ca_cert.get_subject())
-  cert.set_serial_number(int(time.time()*10000))
-  cert.set_pubkey(ca_key)
-  cert.add_extensions(reused_extensions)
-  cert.sign(ca_key, 'sha256')
-
-  return _dump_cert(cert)
-
-
-def install_cert_in_nssdb(home_directory_path, certificate_path):
-  """Installs a certificate into the ~/.pki/nssdb database.
-
-  Args:
-    home_directory_path: Path of the home directory where to install
-    certificate_path: Path of a CA in PEM format
-  """
-  assert os.path.isdir(home_directory_path)
-  assert platform.system() == 'Linux', \
-      'SSL certification authority has only been tested for linux.'
-  if (os.path.abspath(home_directory_path) ==
-          os.path.abspath(os.environ['HOME'])):
-    raise Exception('Modifying $HOME/.pki/nssdb compromises your machine.')
-
-  cert_database_path = os.path.join(home_directory_path, '.pki', 'nssdb')
-  def certutil(args):
-    cmd = ['certutil', '--empty-password', '-d', 'sql:' + cert_database_path]
-    cmd.extend(args)
-    logging.info(subprocess.list2cmdline(cmd))
-    subprocess.check_call(cmd)
-
-  if not os.path.isdir(cert_database_path):
-    os.makedirs(cert_database_path)
-    certutil(['-N'])
-
-  certutil(['-A', '-t', 'PC,,', '-n', certificate_path, '-i', certificate_path])
diff --git a/catapult/telemetry/third_party/web-page-replay/certutils_test.py b/catapult/telemetry/third_party/web-page-replay/certutils_test.py
deleted file mode 100644
index de1ac2d..0000000
--- a/catapult/telemetry/third_party/web-page-replay/certutils_test.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Test routines to generate dummy certificates."""
-
-import BaseHTTPServer
-import os
-import shutil
-import ssl
-import tempfile
-import threading
-import unittest
-
-import certutils
-
-
-class Server(BaseHTTPServer.HTTPServer):
-
-  def __init__(self, https_root_ca_cert_path):
-    BaseHTTPServer.HTTPServer.__init__(
-        self, ('localhost', 0), BaseHTTPServer.BaseHTTPRequestHandler)
-    self.socket = ssl.wrap_socket(
-        self.socket, certfile=https_root_ca_cert_path, server_side=True,
-        do_handshake_on_connect=False)
-
-  def __enter__(self):
-    thread = threading.Thread(target=self.serve_forever)
-    thread.daemon = True
-    thread.start()
-    return self
-
-  def cleanup(self):
-    try:
-      self.shutdown()
-    except KeyboardInterrupt:
-      pass
-
-  def __exit__(self, type_, value_, traceback_):
-    self.cleanup()
-
-
-class CertutilsTest(unittest.TestCase):
-
-  def _check_cert_file(self, cert_file_path, cert_str, key_str=None):
-    cert_load = open(cert_file_path, 'r').read()
-    if key_str:
-      expected_cert = key_str + cert_str
-    else:
-      expected_cert = cert_str
-    self.assertEqual(expected_cert, cert_load)
-
-  def setUp(self):
-    self._temp_dir = tempfile.mkdtemp(prefix='certutils_', dir='/tmp')
-
-  def tearDown(self):
-    if self._temp_dir:
-      shutil.rmtree(self._temp_dir)
-
-  def test_generate_dummy_ca_cert(self):
-    subject = 'testSubject'
-    c, _ = certutils.generate_dummy_ca_cert(subject)
-    c = certutils.load_cert(c)
-    self.assertEqual(c.get_subject().commonName, subject)
-
-  def test_get_host_cert(self):
-    ca_cert_path = os.path.join(self._temp_dir, 'rootCA.pem')
-    issuer = 'testCA'
-    certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(issuer),
-                                  cert_path=ca_cert_path)
-
-    with Server(ca_cert_path) as server:
-      cert_str = certutils.get_host_cert('localhost', server.server_port)
-      cert = certutils.load_cert(cert_str)
-      self.assertEqual(issuer, cert.get_subject().commonName)
-
-  def test_get_host_cert_gives_empty_for_bad_host(self):
-    cert_str = certutils.get_host_cert('not_a_valid_host_name_2472341234234234')
-    self.assertEqual('', cert_str)
-
-  def test_write_dummy_ca_cert(self):
-    base_path = os.path.join(self._temp_dir, 'testCA')
-    ca_cert_path = base_path + '.pem'
-    cert_path = base_path + '-cert.pem'
-    ca_cert_android = base_path + '-cert.cer'
-    ca_cert_windows = base_path + '-cert.p12'
-
-    self.assertFalse(os.path.exists(ca_cert_path))
-    self.assertFalse(os.path.exists(cert_path))
-    self.assertFalse(os.path.exists(ca_cert_android))
-    self.assertFalse(os.path.exists(ca_cert_windows))
-    c, k = certutils.generate_dummy_ca_cert()
-    certutils.write_dummy_ca_cert(c, k, ca_cert_path)
-
-    self._check_cert_file(ca_cert_path, c, k)
-    self._check_cert_file(cert_path, c)
-    self._check_cert_file(ca_cert_android, c)
-    self.assertTrue(os.path.exists(ca_cert_windows))
-
-  def test_generate_cert(self):
-    ca_cert_path = os.path.join(self._temp_dir, 'testCA.pem')
-    issuer = 'testIssuer'
-    certutils.write_dummy_ca_cert(
-        *certutils.generate_dummy_ca_cert(issuer), cert_path=ca_cert_path)
-
-    with open(ca_cert_path, 'r') as root_file:
-      root_string = root_file.read()
-    subject = 'testSubject'
-    cert_string = certutils.generate_cert(
-        root_string, '', subject)
-    cert = certutils.load_cert(cert_string)
-    self.assertEqual(issuer, cert.get_issuer().commonName)
-    self.assertEqual(subject, cert.get_subject().commonName)
-
-    with open(ca_cert_path, 'r') as ca_cert_file:
-      ca_cert_str = ca_cert_file.read()
-    cert_string = certutils.generate_cert(ca_cert_str, cert_string,
-                                          'host')
-    cert = certutils.load_cert(cert_string)
-    self.assertEqual(issuer, cert.get_issuer().commonName)
-    self.assertEqual(subject, cert.get_subject().commonName)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/codereview.settings b/catapult/telemetry/third_party/web-page-replay/codereview.settings
deleted file mode 100644
index f0c2b12..0000000
--- a/catapult/telemetry/third_party/web-page-replay/codereview.settings
+++ /dev/null
@@ -1,3 +0,0 @@
-# This file is used by gcl to get repository specific information.
-CODE_REVIEW_SERVER: codereview.chromium.org
-PROJECT: web-page-replay
diff --git a/catapult/telemetry/third_party/web-page-replay/customhandlers.py b/catapult/telemetry/third_party/web-page-replay/customhandlers.py
deleted file mode 100644
index 14166af..0000000
--- a/catapult/telemetry/third_party/web-page-replay/customhandlers.py
+++ /dev/null
@@ -1,198 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Handle special HTTP requests.
-
-/web-page-replay-generate-[RESPONSE_CODE]
-  - Return the given RESPONSE_CODE.
-/web-page-replay-post-image-[FILENAME]
-  - Save the posted image to local disk.
-/web-page-replay-command-[record|replay|status]
-  - Optional. Enable by calling custom_handlers.add_server_manager_handler(...).
-  - Change the server mode to either record or replay.
-    + When switching to record, the http_archive is cleared.
-    + When switching to replay, the http_archive is maintained.
-"""
-
-import base64
-import httparchive
-import json
-import logging
-import os
-
-COMMON_URL_PREFIX = '/web-page-replay-'
-COMMAND_URL_PREFIX = COMMON_URL_PREFIX + 'command-'
-GENERATOR_URL_PREFIX = COMMON_URL_PREFIX + 'generate-'
-POST_IMAGE_URL_PREFIX = COMMON_URL_PREFIX + 'post-image-'
-IMAGE_DATA_PREFIX = 'data:image/png;base64,'
-
-
-def SimpleResponse(status):
-  """Return a ArchivedHttpResponse with |status| code and a simple text body."""
-  return httparchive.create_response(status)
-
-
-def JsonResponse(data):
-  """Return a ArchivedHttpResponse with |data| encoded as json in the body."""
-  status = 200
-  reason = 'OK'
-  headers = [('content-type', 'application/json')]
-  body = json.dumps(data)
-  return httparchive.create_response(status, reason, headers, body)
-
-
-class CustomHandlers(object):
-
-  def __init__(self, options, http_archive):
-    """Initialize CustomHandlers.
-
-    Args:
-      options: original options passed to the server.
-      http_archive: reference to the HttpArchive object.
-    """
-    self.server_manager = None
-    self.options = options
-    self.http_archive = http_archive
-    self.handlers = [
-        (GENERATOR_URL_PREFIX, self.get_generator_url_response_code)]
-    # screenshot_dir is a path to which screenshots are saved.
-    if options.screenshot_dir:
-      if not os.path.exists(options.screenshot_dir):
-        try:
-          os.makedirs(options.screenshot_dir)
-        except IOError:
-          logging.error('Unable to create screenshot dir: %s',
-                         options.screenshot_dir)
-          options.screenshot_dir = None
-      if options.screenshot_dir:
-        self.screenshot_dir = options.screenshot_dir
-        self.handlers.append(
-            (POST_IMAGE_URL_PREFIX, self.handle_possible_post_image))
-
-  def handle(self, request):
-    """Dispatches requests to matching handlers.
-
-    Args:
-      request: an http request
-    Returns:
-      ArchivedHttpResponse or None.
-    """
-    for prefix, handler in self.handlers:
-      if request.full_path.startswith(prefix):
-        return handler(request, request.full_path[len(prefix):])
-    return None
-
-  def get_generator_url_response_code(self, request, url_suffix):
-    """Parse special generator URLs for the embedded response code.
-
-    Args:
-      request: an ArchivedHttpRequest instance
-      url_suffix: string that is after the handler prefix (e.g. 304)
-    Returns:
-      On a match, an ArchivedHttpResponse.
-      Otherwise, None.
-    """
-    del request
-    try:
-      response_code = int(url_suffix)
-      return SimpleResponse(response_code)
-    except ValueError:
-      return None
-
-  def handle_possible_post_image(self, request, url_suffix):
-    """If sent, saves embedded image to local directory.
-
-    Expects a special url containing the filename. If sent, saves the base64
-    encoded request body as a PNG image locally. This feature is enabled by
-    passing in screenshot_dir to the initializer for this class.
-
-    Args:
-      request: an ArchivedHttpRequest instance
-      url_suffix: string that is after the handler prefix (e.g. 'foo.png')
-    Returns:
-      On a match, an ArchivedHttpResponse.
-      Otherwise, None.
-    """
-    basename = url_suffix
-    if not basename:
-      return None
-
-    data = request.request_body
-    if not data.startswith(IMAGE_DATA_PREFIX):
-      logging.error('Unexpected image format for: %s', basename)
-      return SimpleResponse(400)
-
-    data = data[len(IMAGE_DATA_PREFIX):]
-    png = base64.b64decode(data)
-    filename = os.path.join(self.screenshot_dir,
-                            '%s-%s.png' % (request.host, basename))
-    if not os.access(self.screenshot_dir, os.W_OK):
-      logging.error('Unable to write to: %s', filename)
-      return SimpleResponse(400)
-
-    with file(filename, 'w') as f:
-      f.write(png)
-    return SimpleResponse(200)
-
-  def add_server_manager_handler(self, server_manager):
-    """Add the ability to change the server mode (e.g. to record mode).
-    Args:
-      server_manager: a servermanager.ServerManager instance.
-    """
-    self.server_manager = server_manager
-    self.handlers.append(
-        (COMMAND_URL_PREFIX, self.handle_server_manager_command))
-
-  def handle_server_manager_command(self, request, url_suffix):
-    """Parse special URLs for the embedded server manager command.
-
-    Clients like webpagetest.org can use URLs of this form to change
-    the replay server from record mode to replay mode.
-
-    This handler is not in the default list of handlers. Call
-    add_server_manager_handler to add it.
-
-    In the future, this could be expanded to save or serve archive files.
-
-    Args:
-      request: an ArchivedHttpRequest instance
-      url_suffix: string that is after the handler prefix (e.g. 'record')
-    Returns:
-      On a match, an ArchivedHttpResponse.
-      Otherwise, None.
-    """
-    command = url_suffix
-    if command == 'record':
-      self.server_manager.SetRecordMode()
-      return SimpleResponse(200)
-    elif command == 'replay':
-      self.server_manager.SetReplayMode()
-      return SimpleResponse(200)
-    elif command == 'status':
-      status = {}
-      is_record_mode = self.server_manager.IsRecordMode()
-      status['is_record_mode'] = is_record_mode
-      status['options'] = json.loads(str(self.options))
-      archive_stats = self.http_archive.stats()
-      if archive_stats:
-        status['archive_stats'] = json.loads(archive_stats)
-      return JsonResponse(status)
-    elif command == 'exit':
-      self.server_manager.should_exit = True
-      return SimpleResponse(200)
-    elif command == 'log':
-      logging.info('log command: %s', str(request.request_body)[:1000000])
-      return SimpleResponse(200)
-    return None
diff --git a/catapult/telemetry/third_party/web-page-replay/daemonserver.py b/catapult/telemetry/third_party/web-page-replay/daemonserver.py
deleted file mode 100644
index 371c654..0000000
--- a/catapult/telemetry/third_party/web-page-replay/daemonserver.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import threading
-
-
-class DaemonServer(object):
-  """Base class which manages creation and cleanup of daemon style servers."""
-
-  def __enter__(self):
-    # TODO: Because of python's Global Interpreter Lock (GIL), the threads
-    # will run on the same CPU. Consider using processes instead because
-    # the components do not need to communicate with each other. On Linux,
-    # "taskset" could be used to assign each process to specific CPU/core.
-    # Of course, only bother with this if the processing speed is an issue.
-    # Some related discussion: http://stackoverflow.com/questions/990102/python-
-    # global-interpreter-lock-gil-workaround-on-multi-core-systems-using-tasks
-    thread = threading.Thread(target=self.serve_forever)
-    thread.daemon = True  # Python exits when no non-daemon threads are left.
-    thread.start()
-    return self
-
-  def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
-    self.cleanup()
diff --git a/catapult/telemetry/third_party/web-page-replay/deterministic.js b/catapult/telemetry/third_party/web-page-replay/deterministic.js
deleted file mode 100644
index 050af31..0000000
--- a/catapult/telemetry/third_party/web-page-replay/deterministic.js
+++ /dev/null
@@ -1,66 +0,0 @@
-'use strict';
-
-(function () {
-  var random_count = 0;
-  var random_count_threshold = 25;
-  var random_seed = 0.462;
-  Math.random = function() {
-    random_count++;
-    if (random_count > random_count_threshold){
-     random_seed += 0.1;
-     random_count = 1;
-    }
-    return (random_seed % 1);
-  };
-  if (typeof(crypto) == 'object' &&
-      typeof(crypto.getRandomValues) == 'function') {
-    crypto.getRandomValues = function(arr) {
-      var scale = Math.pow(256, arr.BYTES_PER_ELEMENT);
-      for (var i = 0; i < arr.length; i++) {
-        arr[i] = Math.floor(Math.random() * scale);
-      }
-      return arr;
-    };
-  }
-})();
-(function () {
-  var date_count = 0;
-  var date_count_threshold = 25;
-  var orig_date = Date;
-  // This should be replaced by web page replay by corresponding date
-  // (usually the date when the recording was done)
-  var time_seed = {{WPR_TIME_SEED_TIMESTAMP}};
-  Date = function() {
-    if (this instanceof Date) {
-      date_count++;
-      if (date_count > date_count_threshold){
-        time_seed += 50;
-        date_count = 1;
-      }
-      switch (arguments.length) {
-      case 0: return new orig_date(time_seed);
-      case 1: return new orig_date(arguments[0]);
-      default: return new orig_date(arguments[0], arguments[1],
-         arguments.length >= 3 ? arguments[2] : 1,
-         arguments.length >= 4 ? arguments[3] : 0,
-         arguments.length >= 5 ? arguments[4] : 0,
-         arguments.length >= 6 ? arguments[5] : 0,
-         arguments.length >= 7 ? arguments[6] : 0);
-      }
-    }
-    return new Date().toString();
-  };
-  Date.__proto__ = orig_date;
-  Date.prototype = orig_date.prototype;
-  Date.prototype.constructor = Date;
-  orig_date.now = function() {
-    return new Date().getTime();
-  };
-  orig_date.prototype.getTimezoneOffset = function() {
-    var dst2010Start = 1268560800000;
-    var dst2010End = 1289120400000;
-    if (this.getTime() >= dst2010Start && this.getTime() < dst2010End)
-      return 420;
-    return 480;
-  };
-})();
diff --git a/catapult/telemetry/third_party/web-page-replay/dnsproxy.py b/catapult/telemetry/third_party/web-page-replay/dnsproxy.py
deleted file mode 100644
index 171b996..0000000
--- a/catapult/telemetry/third_party/web-page-replay/dnsproxy.py
+++ /dev/null
@@ -1,300 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import daemonserver
-import errno
-import logging
-import socket
-import SocketServer
-import threading
-import time
-
-from third_party.dns import flags
-from third_party.dns import message
-from third_party.dns import rcode
-from third_party.dns import resolver
-from third_party.dns import rdatatype
-from third_party import ipaddr
-
-
-
-class DnsProxyException(Exception):
-  pass
-
-
-DEFAULT_DNS_PORT = 53
-
-
-class RealDnsLookup(object):
-  def __init__(self, name_servers, dns_forwarding, proxy_host, proxy_port):
-    if (proxy_host in name_servers and proxy_port == DEFAULT_DNS_PORT and
-        dns_forwarding):
-      raise DnsProxyException(
-          'Invalid nameserver: %s (causes an infinte loop)'.format(
-              proxy_host))
-    self.resolver = resolver.get_default_resolver()
-    self.resolver.nameservers = name_servers
-    self.dns_cache_lock = threading.Lock()
-    self.dns_cache = {}
-
-  @staticmethod
-  def _IsIPAddress(hostname):
-    try:
-      socket.inet_aton(hostname)
-      return True
-    except socket.error:
-      return False
-
-  def __call__(self, hostname, rdtype=rdatatype.A):
-    """Return real IP for a host.
-
-    Args:
-      host: a hostname ending with a period (e.g. "www.google.com.")
-      rdtype: the query type (1 for 'A', 28 for 'AAAA')
-    Returns:
-      the IP address as a string (e.g. "192.168.25.2")
-    """
-    if self._IsIPAddress(hostname):
-      return hostname
-    self.dns_cache_lock.acquire()
-    ip = self.dns_cache.get(hostname)
-    self.dns_cache_lock.release()
-    if ip:
-      return ip
-    try:
-      answers = self.resolver.query(hostname, rdtype)
-    except resolver.NXDOMAIN:
-      return None
-    except resolver.NoNameservers:
-      logging.debug('_real_dns_lookup(%s) -> No nameserver.',
-                    hostname)
-      return None
-    except (resolver.NoAnswer, resolver.Timeout) as ex:
-      logging.debug('_real_dns_lookup(%s) -> None (%s)',
-                    hostname, ex.__class__.__name__)
-      return None
-    if answers:
-      ip = str(answers[0])
-    self.dns_cache_lock.acquire()
-    self.dns_cache[hostname] = ip
-    self.dns_cache_lock.release()
-    return ip
-
-  def ClearCache(self):
-    """Clear the dns cache."""
-    self.dns_cache_lock.acquire()
-    self.dns_cache.clear()
-    self.dns_cache_lock.release()
-
-
-class ReplayDnsLookup(object):
-  """Resolve DNS requests to replay host."""
-  def __init__(self, replay_ip, filters=None):
-    self.replay_ip = replay_ip
-    self.filters = filters or []
-
-  def __call__(self, hostname):
-    ip = self.replay_ip
-    for f in self.filters:
-      ip = f(hostname, default_ip=ip)
-    return ip
-
-
-class PrivateIpFilter(object):
-  """Resolve private hosts to their real IPs and others to the Web proxy IP.
-
-  Hosts in the given http_archive will resolve to the Web proxy IP without
-  checking the real IP.
-
-  This only supports IPv4 lookups.
-  """
-  def __init__(self, real_dns_lookup, http_archive):
-    """Initialize PrivateIpDnsLookup.
-
-    Args:
-      real_dns_lookup: a function that resolves a host to an IP.
-      http_archive: an instance of a HttpArchive
-        Hosts is in the archive will always resolve to the web_proxy_ip
-    """
-    self.real_dns_lookup = real_dns_lookup
-    self.http_archive = http_archive
-    self.InitializeArchiveHosts()
-
-  def __call__(self, host, default_ip):
-    """Return real IPv4 for private hosts and Web proxy IP otherwise.
-
-    Args:
-      host: a hostname ending with a period (e.g. "www.google.com.")
-    Returns:
-      IP address as a string or None (if lookup fails)
-    """
-    ip = default_ip
-    if host not in self.archive_hosts:
-      real_ip = self.real_dns_lookup(host)
-      if real_ip:
-        if ipaddr.IPAddress(real_ip).is_private:
-          ip = real_ip
-      else:
-        ip = None
-    return ip
-
-  def InitializeArchiveHosts(self):
-    """Recompute the archive_hosts from the http_archive."""
-    self.archive_hosts = set('%s.' % req.host.split(':')[0]
-                             for req in self.http_archive)
-
-
-class DelayFilter(object):
-  """Add a delay to replayed lookups."""
-
-  def __init__(self, is_record_mode, delay_ms):
-    self.is_record_mode = is_record_mode
-    self.delay_ms = int(delay_ms)
-
-  def __call__(self, host, default_ip):
-    if not self.is_record_mode:
-      time.sleep(self.delay_ms * 1000.0)
-    return default_ip
-
-  def SetRecordMode(self):
-    self.is_record_mode = True
-
-  def SetReplayMode(self):
-    self.is_record_mode = False
-
-
-class UdpDnsHandler(SocketServer.DatagramRequestHandler):
-  """Resolve DNS queries to localhost.
-
-  Possible alternative implementation:
-  http://howl.play-bow.org/pipermail/dnspython-users/2010-February/000119.html
-  """
-
-  STANDARD_QUERY_OPERATION_CODE = 0
-
-  def handle(self):
-    """Handle a DNS query.
-
-    IPv6 requests (with rdtype AAAA) receive mismatched IPv4 responses
-    (with rdtype A). To properly support IPv6, the http proxy would
-    need both types of addresses. By default, Windows XP does not
-    support IPv6.
-    """
-    self.data = self.rfile.read()
-    self.transaction_id = self.data[0]
-    self.flags = self.data[1]
-    self.qa_counts = self.data[4:6]
-    self.domain = ''
-    operation_code = (ord(self.data[2]) >> 3) & 15
-    if operation_code == self.STANDARD_QUERY_OPERATION_CODE:
-      self.wire_domain = self.data[12:]
-      self.domain = self._domain(self.wire_domain)
-    else:
-      logging.debug("DNS request with non-zero operation code: %s",
-                    operation_code)
-    ip = self.server.dns_lookup(self.domain)
-    if ip is None:
-      logging.debug('dnsproxy: %s -> NXDOMAIN', self.domain)
-      response = self.get_dns_no_such_name_response()
-    else:
-      if ip == self.server.server_address[0]:
-        logging.debug('dnsproxy: %s -> %s (replay web proxy)', self.domain, ip)
-      else:
-        logging.debug('dnsproxy: %s -> %s', self.domain, ip)
-      response = self.get_dns_response(ip)
-    self.wfile.write(response)
-
-  @classmethod
-  def _domain(cls, wire_domain):
-    domain = ''
-    index = 0
-    length = ord(wire_domain[index])
-    while length:
-      domain += wire_domain[index + 1:index + length + 1] + '.'
-      index += length + 1
-      length = ord(wire_domain[index])
-    return domain
-
-  def get_dns_response(self, ip):
-    packet = ''
-    if self.domain:
-      packet = (
-          self.transaction_id +
-          self.flags +
-          '\x81\x80' +        # standard query response, no error
-          self.qa_counts * 2 + '\x00\x00\x00\x00' +  # Q&A counts
-          self.wire_domain +
-          '\xc0\x0c'          # pointer to domain name
-          '\x00\x01'          # resource record type ("A" host address)
-          '\x00\x01'          # class of the data
-          '\x00\x00\x00\x3c'  # ttl (seconds)
-          '\x00\x04' +        # resource data length (4 bytes for ip)
-          socket.inet_aton(ip)
-          )
-    return packet
-
-  def get_dns_no_such_name_response(self):
-    query_message = message.from_wire(self.data)
-    response_message = message.make_response(query_message)
-    response_message.flags |= flags.AA | flags.RA
-    response_message.set_rcode(rcode.NXDOMAIN)
-    return response_message.to_wire()
-
-
-class DnsProxyServer(SocketServer.ThreadingUDPServer,
-                     daemonserver.DaemonServer):
-  # Increase the request queue size. The default value, 5, is set in
-  # SocketServer.TCPServer (the parent of BaseHTTPServer.HTTPServer).
-  # Since we're intercepting many domains through this single server,
-  # it is quite possible to get more than 5 concurrent requests.
-  request_queue_size = 256
-
-  # Allow sockets to be reused. See
-  # http://svn.python.org/projects/python/trunk/Lib/SocketServer.py for more
-  # details.
-  allow_reuse_address = True
-
-  # Don't prevent python from exiting when there is thread activity.
-  daemon_threads = True
-
-  def __init__(self, host='', port=53, dns_lookup=None):
-    """Initialize DnsProxyServer.
-
-    Args:
-      host: a host string (name or IP) to bind the dns proxy and to which
-        DNS requests will be resolved.
-      port: an integer port on which to bind the proxy.
-      dns_lookup: a list of filters to apply to lookup.
-    """
-    try:
-      SocketServer.ThreadingUDPServer.__init__(
-          self, (host, port), UdpDnsHandler)
-    except socket.error, (error_number, msg):
-      if error_number == errno.EACCES:
-        raise DnsProxyException(
-            'Unable to bind DNS server on (%s:%s)' % (host, port))
-      raise
-    self.dns_lookup = dns_lookup or (lambda host: self.server_address[0])
-    self.server_port = self.server_address[1]
-    logging.warning('DNS server started on %s:%d', self.server_address[0],
-                                                   self.server_address[1])
-
-  def cleanup(self):
-    try:
-      self.shutdown()
-      self.server_close()
-    except KeyboardInterrupt, e:
-      pass
-    logging.info('Stopped DNS server')
diff --git a/catapult/telemetry/third_party/web-page-replay/documentation/Contributing.md b/catapult/telemetry/third_party/web-page-replay/documentation/Contributing.md
deleted file mode 100644
index 492649b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/documentation/Contributing.md
+++ /dev/null
@@ -1,41 +0,0 @@
-# Contributing
-
-1. Thanks for considering contributing to Web Page Replay. You're awesome!
-2. Style Guide - The source code of Web Page Replay follows the [Google
-Python Style
-Guide](http://google-styleguide.googlecode.com/svn/trunk/pyguide.html) so you should familiarize yourself with those
-guidelines. You may also wish to email web-page-replay-dev at
-googlegroups.com for advice on your change before starting.
-3. Get the code - Fork this repo and clone it locally.
-4. Get a review - All submissions, including submissions by project members,
-require review.
-
-## Using rietveld
-
-1. Make sure that you have a fork of the original repo.
-2. Make your changes.
-3. Commit your changes.
-4. Run 'yes "" |git cl config' (first time only).
-5. Run 'git cl upload'.
-6. Once the review is approved, run 'git cl land' to land your changes. This also
-pushes your change to your forked branch.
-7. Login your github account and make a pull request to merge the change from
-your forked branch to the original repo.
-
-## The fine print
-
-Before we can use your code you have to sign the [Google Individual
-Contributor License
-Agreement](http://code.google.com/legal/individual-cla-v1.0.html), which you can do online. This is mainly
-because you own the copyright to your changes, even after your
-contribution becomes part of our codebase, so we need your permission to
-use and distribute your code. We also need to be sure of various other
-things, for instance that you'll tell us if you know that your code
-infringes on other people's patents. You don't have to do this until
-after you've submitted your code for review and a member has approved
-it, but you will have to do it before we can put your code into our
-codebase.
-
-Contributions made by corporations are covered by a different agreement
-than the one above, the [Software Grant and Corporate Contributor License
-Agreement](http://code.google.com/legal/corporate-cla-v1.0.html).
diff --git a/catapult/telemetry/third_party/web-page-replay/documentation/GettingStarted.md b/catapult/telemetry/third_party/web-page-replay/documentation/GettingStarted.md
deleted file mode 100644
index 90790b4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/documentation/GettingStarted.md
+++ /dev/null
@@ -1,169 +0,0 @@
-# Prerequisites
-* A Mac running OS X 10.6 ("Snow Leopard") or Linux (tested with Ubuntu
-Lucid). Support for Windows is still experimental
-* [Python 2.6](http://www.python.org/download/releases/2.6.6/)
-
-# Install
-Only do this the first time.
-
-1. Open the Terminal application and download the source.
-```
-$ git clone https://github.com/chromium/web-page-replay.git
-```
-2. Move to the newly created directory.
-```
-$ cd web-page-replay
-```
-## Linux-specific install steps
-On Linux, Dummynet must be installed to simulate network conditions.
-
-1. For the Linux code, try downloading the [latest linux sources from Marta
-Carbone](http://info.iet.unipi.it/~marta/dummynet/). These are more up-to-date than what is found on the [Dummynet
-homepage](http://info.iet.unipi.it/~luigi/dummynet/).
-2. Build and install:
-```
-$ tar -C /tmp -xvzf ipfw3-20120119.tgz
-$ cd /tmp/ipfw3-20120119
-$ make
-[Ignore output like the following:]
-        echo "  ERROR: Kernel configuration is invalid.";\
-        echo "         include/generated/autoconf.h or
-include/config/auto.conf are missing.";\
-        echo "         Run 'make oldconfig && make prepare' on kernel
-src to fix it.";\
-[The lines will print without "echo" if there is an actual error.]
-$ sudo insmod dummynet2/ipfw_mod.ko
-$ sudo cp ipfw/ipfw /usr/local/sbin
-```
-3. To remove it later
-```
-$ sudo rmmod ipfw_mod.ko
-```
-## Windows-specific install steps
-*Windows support is experimental and not well tested.* On Windows XP, the
-Dummynet driver must be installed to simulate network conditions
-(Drivers for Windows Vista and Windows 7 are currently unavailable).
-
-1. Control Panel -> Network Connections -> Right-click adapter in use ->
-select Properties
-2. Click Install... -> Service -> Add... -> Have Disk...
-3. Browse... ->
-web-page-replay-read-only\third_party\ipfw_win32\netipfw.inf
-4. Click Open -> Ok -> Ok
-  - Accept any warnings for installing an unknown driver
-
-# Record
-First you must record the web page or pages that you wish to replay.
-
-1. Open the web browser you wish to use and clear its cache so that all
-resources will be requested from the network.
-2. Switch to the Terminal application and start the program in record mode.
-All HTTP requests performed on the machine while it is running will be
-saved into the archive.
-```
-$ sudo ./replay.py --record ~/archive.wpr
-```
-3. Load the web page or pages in the open web browser. Be sure to wait
-until each is fully loaded.
-4. Stop recording by killing the replay.py process with Ctrl+c. The archive
-will be saved to ~/archive.wpr.
-
-# Replay
-After you have created an archive, you may later replay it at any time.
-
-1. Start the program in replay mode with a previously recorded archive.
-```
-$ sudo ./replay.py ~/archive.wpr
-```
-2. Load recorded pages in a web browser. A 404 will be served for any pages
-or resources not in the recorded archive.
-3. Stop replaying by killing the replay.py process with Ctrl+c.
-
-## Network simulation examples
-During replay, you may simulate desired network conditions. This is
-useful for benchmarking.
-
-* 128KByte/s uplink bandwidth, 4Mbps/s downlink bandwidth with 100ms RTT
-time
-```
-$ sudo ./replay.py --up 128KByte/s --down 4Mbit/s --delay_ms=100 archive.wpr
-```
-* 1% packet loss rate
-```
-$ sudo ./replay.py --packet_loss_rate=0.01 ~/archive.wpr
-```
-
-## Using browser proxy settings
-You may choose to disable the forwarding of DNS requests to the local
-replay server. If DNS request forwarding is disabled, an external
-mechanism must be used to forward traffic to the replay server.
-
-* Disable DNS forwarding
-```
-$ ./replay.py --no-dns_forwarding --record ~/archive.wpr
-```
-* Forwarding traffic to replay server (via Google Chrome on linux)
-1. Go to Chrome Preferences -> Under the Hood -> Change Proxy Settings
-2. Under Manual Proxy configuration -> HTTP proxy, enter 127.0.0.1 for IP
-and the port that web page replay is configured to listen to (default
-80).
-
-Alternatively, traffic forwarding may also be configured via command
-line flags.
-```
-$ google-chrome --host-resolver-rules="MAP * 127.0.0.1:80,EXCLUDE localhost"
-```
-
-# HTTPS/SSL support
-By default, Web Page Replay, creates a self-signed certificate to serve
-SSL traffic. In order for it to work, browsers need to be configured to
-ignore certificate errors. Be aware that doing so opens a giant security
-hole.
-
-```
-$ google-chrome --ignore-certificate-errors
-```
-
-Firefox has [a configuration file for
-exceptions](https://developer.mozilla.org/En/Cert_override.txt). That requires listing
-each host that gets used. If you have a better solution, please add it
-to the comments below. IE and Safari options are also needed.
-
-To turn off SSL support, run replay.py with "--no-ssl".
-
-# Troubleshooting
-
-## Permission errors
-
-On Linux, either of the following two errors are permission problems:
-
-```
-python: can't open file './replay.py': [Errno 13] Permission denied
-```
-```
-Traceback (most recent call last):
-  File "./replay.py", line 50, in <module>
-    import dnsproxy
-  File "/home/slamm/p/wpr/dnsproxy.py", line 19, in <module>
-    import platformsettings
-ImportError: No module named platformsettings
-```
-This can happen if you checkout the files to an NFS directory. Either
-move the files to a local directory, or make them world
-readable/executable.
-
-## Unable to access auto mounted directories
-WPR can cause autofs to hang. On Ubuntu, the following command fixes it:
-
-```
-$ sudo restart autofs
-```
-
-# Help
-
-For full usage instructions and advanced options, see the program's
-help.
-
-```
-$ ./replay.py --help
-```
diff --git a/catapult/telemetry/third_party/web-page-replay/documentation/Rules.md b/catapult/telemetry/third_party/web-page-replay/documentation/Rules.md
deleted file mode 100644
index 3517635..0000000
--- a/catapult/telemetry/third_party/web-page-replay/documentation/Rules.md
+++ /dev/null
@@ -1,95 +0,0 @@
-WebPageReplay Rule Language
-===========================
-
-WebPageReplay rules allows developers to customize record/replay handling.
-
-Motiviation
------------
-
-Web sites often require custom replay logic, e.g.:
-
-  1. The recording uploads various metrics/logs to:
-
-        http://example.com/gen_204?emsg=foo
-
-     but, during replay, it uploads different parameters:
-
-        http://example.com/gen_204?emsg=bar
-
-     so (as-is) our replay fails.  We want "*/gen_204" to always respond
-     "HTTP 204 No Change".
-
-  2. The recording fetches data from one server:
-
-        http://mirrorA.example.com/stuff
-
-     but replay selects a different server:
-
-        http://mirrorB.example.com/stuff
-
-     which breaks replay.  We want "mirror*.example.com/stuff" to be equivalent.
-
-  3. The recorded URL + response contains a UID, e.g.:
-
-        http://example.com?q=foo  -->  "you sent foo."
-
-     but the replay asks for:
-
-        http://example.com?q=bar  -->  replay error!
-
-     We want it to reply "you sent bar."
-
-We could hack all the above rules into the code, but that can''t be (cleanly) extended or open sourced.
-
-Instead, we want a simple config file of "predicate --> action" rules.
-
-
-Format
-------
-
-The JSON-formatted rule file is specified on the command line:
-
-    replay.py ... --rules_path my_rules ...
-
-The rules file must contain an array of single-item objects, e.g.:
-
-    [{"comment": "ignore me"},
-     {"LogUrl": {"url": "example\\.com/logme.*"}},
-     {"LogUrl": {"url": "example\\.com/someotherpath"}}
-    ]
-
-All "comment" items are ignored and support arbitrary values, e.g., a string
-or commented-out rule(s).
-
-All other items must specify a string TYPE key and object ARGS value, e.g.:
-
-     {"LogUrl": {"url": "example\\.com/test", "stop": false}}
-
-The default TYPE package is "rules" and the default rule_parser
-"allowed_imports" is similarly restricted to only allow "rules" classes.
-
-The TYPE implementation class must match the Rule API defined in
-"rules/rule.py":
-
-  class Rule(object):
-    def IsType(self, rule_type_name): ...
-    def ApplyRule(self, return_value, request, response): ...
-
-The ARGS must match the rule-specific constructor, e.g.:
-
-    class LogUrl(rule.Rule):
-      def __init__(self, url, stop=False):
-        self._url_re = re.compile(url)
-        self._stop = stop
-      ...
-
-All rules of the same rule_type_name are chained together and applied in the
-same order as they appear in the input JSON file.
-
-
-Rules
--------
-
-### rules.LogUrl:
-
-If the url pattern matches then log the request URL.
diff --git a/catapult/telemetry/third_party/web-page-replay/documentation/WebPageReplayDiagram.png b/catapult/telemetry/third_party/web-page-replay/documentation/WebPageReplayDiagram.png
deleted file mode 100644
index fc98922..0000000
--- a/catapult/telemetry/third_party/web-page-replay/documentation/WebPageReplayDiagram.png
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/web-page-replay/exception_formatter.py b/catapult/telemetry/third_party/web-page-replay/exception_formatter.py
deleted file mode 100644
index 8ceb0d4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/exception_formatter.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import math
-import os
-import sys
-import traceback
-
-
-def PrintFormattedException(msg=None):
-  exception_class, exception, tb = sys.exc_info()
-
-  def _GetFinalFrame(tb_level):
-    while tb_level.tb_next:
-      tb_level = tb_level.tb_next
-    return tb_level.tb_frame
-
-  processed_tb = traceback.extract_tb(tb)
-  frame = _GetFinalFrame(tb)
-  exception_list = traceback.format_exception_only(exception_class, exception)
-  exception_string = '\n'.join(l.strip() for l in exception_list)
-
-  if msg:
-    print >> sys.stderr
-    print >> sys.stderr, msg
-
-  _PrintFormattedTrace(processed_tb, frame, exception_string)
-
-def PrintFormattedFrame(frame, exception_string=None):
-  _PrintFormattedTrace(traceback.extract_stack(frame), frame, exception_string)
-
-
-def _PrintFormattedTrace(processed_tb, frame, exception_string=None):
-  """Prints an Exception in a more useful format than the default.
-  """
-  print >> sys.stderr
-
-  # Format the traceback.
-  base_dir = os.path.dirname(__file__)
-  print >> sys.stderr, 'Traceback (most recent call last):'
-  for filename, line, function, text in processed_tb:
-    filename = os.path.abspath(filename)
-    if filename.startswith(base_dir):
-      filename = filename[len(base_dir)+1:]
-    print >> sys.stderr, '  %s at %s:%d' % (function, filename, line)
-    print >> sys.stderr, '    %s' % text
-
-  # Format the exception.
-  if exception_string:
-    print >> sys.stderr, exception_string
-
-  # Format the locals.
-  local_variables = [(variable, value) for variable, value in
-                     frame.f_locals.iteritems() if variable != 'self']
-  print >> sys.stderr
-  print >> sys.stderr, 'Locals:'
-  if local_variables:
-    longest_variable = max(len(v) for v, _ in local_variables)
-    for variable, value in sorted(local_variables):
-      value = repr(value)
-      possibly_truncated_value = _AbbreviateMiddleOfString(value, ' ... ', 1024)
-      truncation_indication = ''
-      if len(possibly_truncated_value) != len(value):
-        truncation_indication = ' (truncated)'
-      print >> sys.stderr, '  %s: %s%s' % (variable.ljust(longest_variable + 1),
-                                           possibly_truncated_value,
-                                           truncation_indication)
-  else:
-    print >> sys.stderr, '  No locals!'
-
-  print >> sys.stderr
-  sys.stderr.flush()
-
-
-def _AbbreviateMiddleOfString(target, middle, max_length):
-  if max_length < 0:
-    raise ValueError('Must provide positive max_length')
-  if len(middle) > max_length:
-    raise ValueError('middle must not be greater than max_length')
-
-  if len(target) <= max_length:
-    return target
-  half_length = (max_length - len(middle)) / 2.
-  return (target[:int(math.floor(half_length))] + middle +
-          target[-int(math.ceil(half_length)):])
diff --git a/catapult/telemetry/third_party/web-page-replay/httparchive.py b/catapult/telemetry/third_party/web-page-replay/httparchive.py
deleted file mode 100755
index bdfb66e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httparchive.py
+++ /dev/null
@@ -1,1081 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""View and edit HTTP Archives.
-
-To list all URLs in an archive:
-  $ ./httparchive.py ls archive.wpr
-
-To view the content of all URLs from example.com:
-  $ ./httparchive.py cat --host example.com archive.wpr
-
-To view the content of a particular URL:
-  $ ./httparchive.py cat --host www.example.com --full_path /foo archive.wpr
-
-To view the content of all URLs:
-  $ ./httparchive.py cat archive.wpr
-
-To edit a particular URL:
-  $ ./httparchive.py edit --host www.example.com --full_path /foo archive.wpr
-
-To print statistics of an archive:
-  $ ./httparchive.py stats archive.wpr
-
-To print statistics of a set of URLs:
-  $ ./httparchive.py stats --host www.example.com archive.wpr
-
-To merge multiple archives
-  $ ./httparchive.py merge --merged_file new.wpr archive1.wpr archive2.wpr ...
-"""
-
-import calendar
-import certutils
-import datetime
-import cPickle
-import difflib
-import email.utils
-import httplib
-import httpzlib
-import json
-import logging
-import optparse
-import os
-import StringIO
-import subprocess
-import sys
-import tempfile
-import time
-import urlparse
-from collections import defaultdict
-
-
-
-def LogRunTime(fn):
-  """Annotation which logs the run time of the function."""
-  def wrapped(self, *args, **kwargs):
-    start_time = time.time()
-    try:
-      return fn(self, *args, **kwargs)
-    finally:
-      run_time = (time.time() - start_time) * 1000.0
-      logging.debug('%s: %dms', fn.__name__, run_time)
-  return wrapped
-
-
-class HttpArchiveException(Exception):
-  """Base class for all exceptions in httparchive."""
-  pass
-
-
-class HttpArchive(dict):
-  """Dict with ArchivedHttpRequest keys and ArchivedHttpResponse values.
-
-  Attributes:
-    responses_by_host: dict of {hostname, {request: response}}. This must remain
-        in sync with the underlying dict of self. It is used as an optimization
-        so that get_requests() doesn't have to linearly search all requests in
-        the archive to find potential matches.
-  """
-
-  def __init__(self):  # pylint: disable=super-init-not-called
-    self.responses_by_host = defaultdict(dict)
-
-  def __setstate__(self, state):
-    """Influence how to unpickle.
-
-    Args:
-      state: a dictionary for __dict__
-    """
-    self.__dict__.update(state)
-    self.responses_by_host = defaultdict(dict)
-    for request in self:
-      self.responses_by_host[request.host][request] = self[request]
-
-  def __getstate__(self):
-    """Influence how to pickle.
-
-    Returns:
-      a dict to use for pickling
-    """
-    state = self.__dict__.copy()
-    del state['responses_by_host']
-    return state
-
-  def __setitem__(self, key, value):
-    super(HttpArchive, self).__setitem__(key, value)
-    if hasattr(self, 'responses_by_host'):
-      self.responses_by_host[key.host][key] = value
-
-  def __delitem__(self, key):
-    super(HttpArchive, self).__delitem__(key)
-    del self.responses_by_host[key.host][key]
-
-  def get(self, request, default=None):
-    """Return the archived response for a given request.
-
-    Does extra checking for handling some HTTP request headers.
-
-    Args:
-      request: instance of ArchivedHttpRequest
-      default: default value to return if request is not found
-
-    Returns:
-      Instance of ArchivedHttpResponse or default if no matching
-      response is found
-    """
-    if request in self:
-      return self[request]
-    return self.get_conditional_response(request, default)
-
-  def get_conditional_response(self, request, default):
-    """Get the response based on the conditional HTTP request headers.
-
-    Args:
-      request: an ArchivedHttpRequest representing the original request.
-      default: default ArchivedHttpResponse
-          original request with matched headers removed.
-
-    Returns:
-      an ArchivedHttpResponse with a status of 200, 302 (not modified), or
-          412 (precondition failed)
-    """
-    response = default
-    if request.is_conditional():
-      stripped_request = request.create_request_without_conditions()
-      if stripped_request in self:
-        response = self[stripped_request]
-        if response.status == 200:
-          status = self.get_conditional_status(request, response)
-          if status != 200:
-            response = create_response(status)
-    return response
-
-  def get_conditional_status(self, request, response):
-    status = 200
-    last_modified = email.utils.parsedate(
-        response.update_date(response.get_header('last-modified')))
-    response_etag = response.get_header('etag')
-    is_get_or_head = request.command.upper() in ('GET', 'HEAD')
-
-    match_value = request.headers.get('if-match', None)
-    if match_value:
-      if self.is_etag_match(match_value, response_etag):
-        status = 200
-      else:
-        status = 412  # precondition failed
-    none_match_value = request.headers.get('if-none-match', None)
-    if none_match_value:
-      if self.is_etag_match(none_match_value, response_etag):
-        status = 304
-      elif is_get_or_head:
-        status = 200
-      else:
-        status = 412
-    if is_get_or_head and last_modified:
-      for header in ('if-modified-since', 'if-unmodified-since'):
-        date = email.utils.parsedate(request.headers.get(header, None))
-        if date:
-          if ((header == 'if-modified-since' and last_modified > date) or
-              (header == 'if-unmodified-since' and last_modified < date)):
-            if status != 412:
-              status = 200
-          else:
-            status = 304  # not modified
-    return status
-
-  @staticmethod
-  def is_etag_match(request_etag, response_etag):
-    """Determines whether the entity tags of the request/response matches.
-
-    Args:
-      request_etag: the value string of the "if-(none)-match:"
-                    portion of the request header
-      response_etag: the etag value of the response
-
-    Returns:
-      True on match, False otherwise
-    """
-    response_etag = response_etag.strip('" ')
-    for etag in request_etag.split(','):
-      etag = etag.strip('" ')
-      if etag in ('*', response_etag):
-        return True
-    return False
-
-  def get_requests(self, command=None, host=None, full_path=None, is_ssl=None,
-                   use_query=True):
-    """Return a list of requests that match the given args."""
-    if host:
-      return [r for r in self.responses_by_host[host]
-              if r.matches(command, None, full_path, is_ssl,
-                           use_query=use_query)]
-    else:
-      return [r for r in self
-              if r.matches(command, host, full_path, is_ssl,
-                           use_query=use_query)]
-
-  def ls(self, command=None, host=None, full_path=None):
-    """List all URLs that match given params."""
-    return ''.join(sorted(
-        '%s\n' % r for r in self.get_requests(command, host, full_path)))
-
-  def cat(self, command=None, host=None, full_path=None):
-    """Print the contents of all URLs that match given params."""
-    out = StringIO.StringIO()
-    for request in self.get_requests(command, host, full_path):
-      print >>out, str(request)
-      print >>out, 'Untrimmed request headers:'
-      for k in request.headers:
-        print >>out, '    %s: %s' % (k, request.headers[k])
-      if request.request_body:
-        print >>out, request.request_body
-      print >>out, '---- Response Info', '-' * 51
-      response = self[request]
-      chunk_lengths = [len(x) for x in response.response_data]
-      print >>out, ('Status: %s\n'
-                    'Reason: %s\n'
-                    'Headers delay: %s\n'
-                    'Untrimmed response headers:') % (
-          response.status, response.reason, response.delays['headers'])
-      for k, v in response.original_headers:
-        print >>out, '    %s: %s' % (k, v)
-      print >>out, ('Chunk count: %s\n'
-                    'Chunk lengths: %s\n'
-                    'Chunk delays: %s') % (
-          len(chunk_lengths), chunk_lengths, response.delays['data'])
-      body = response.get_data_as_text()
-      print >>out, '---- Response Data', '-' * 51
-      if body:
-        print >>out, body
-      else:
-        print >>out, '[binary data]'
-      print >>out, '=' * 70
-    return out.getvalue()
-
-  def stats(self, command=None, host=None, full_path=None):
-    """Print stats about the archive for all URLs that match given params."""
-    matching_requests = self.get_requests(command, host, full_path)
-    if not matching_requests:
-      print 'Failed to find any requests matching given command, host, path.'
-      return
-
-    out = StringIO.StringIO()
-    stats = {
-        'Total': len(matching_requests),
-        'Domains': defaultdict(int),
-        'HTTP_response_code': defaultdict(int),
-        'content_type': defaultdict(int),
-        'Documents': defaultdict(int),
-        }
-
-    for request in matching_requests:
-      stats['Domains'][request.host] += 1
-      stats['HTTP_response_code'][self[request].status] += 1
-
-      content_type = self[request].get_header('content-type')
-      # Remove content type options for readability and higher level groupings.
-      str_content_type = str(content_type.split(';')[0]
-                            if content_type else None)
-      stats['content_type'][str_content_type] += 1
-
-      #  Documents are the main URL requested and not a referenced resource.
-      if str_content_type == 'text/html' and not 'referer' in request.headers:
-        stats['Documents'][request.host] += 1
-
-    print >>out, json.dumps(stats, indent=4)
-    return out.getvalue()
-
-  def merge(self, merged_archive=None, other_archives=None):
-    """Merge multiple archives into merged_archive by 'chaining' resources,
-    only resources that are not part of the accumlated archive are added"""
-    if not other_archives:
-      print 'No archives passed to merge'
-      return
-
-    # Note we already loaded 'replay_file'.
-    print 'Loaded %d responses' % len(self)
-
-    for archive in other_archives:
-      if not os.path.exists(archive):
-        print 'Error: Replay file "%s" does not exist' % archive
-        return
-
-      http_archive_other = HttpArchive.Load(archive)
-      print 'Loaded %d responses from %s' % (len(http_archive_other), archive)
-      for r in http_archive_other:
-        # Only resources that are not already part of the current archive
-        # get added.
-        if r not in self:
-          print '\t %s ' % r
-          self[r] = http_archive_other[r]
-    self.Persist('%s' % merged_archive)
-
-  def edit(self, command=None, host=None, full_path=None):
-    """Edits the single request which matches given params."""
-    editor = os.getenv('EDITOR')
-    if not editor:
-      print 'You must set the EDITOR environmental variable.'
-      return
-
-    matching_requests = self.get_requests(command, host, full_path)
-    if not matching_requests:
-      print ('Failed to find any requests matching given command, host, '
-             'full_path.')
-      return
-
-    if len(matching_requests) > 1:
-      print 'Found multiple matching requests. Please refine.'
-      print self.ls(command, host, full_path)
-
-    response = self[matching_requests[0]]
-    tmp_file = tempfile.NamedTemporaryFile(delete=False)
-    tmp_file.write(response.get_response_as_text())
-    tmp_file.close()
-    subprocess.check_call([editor, tmp_file.name])
-    response.set_response_from_text(''.join(open(tmp_file.name).readlines()))
-    os.remove(tmp_file.name)
-
-  def find_closest_request(self, request, use_path=False):
-    """Find the closest matching request in the archive to the given request.
-
-    Args:
-      request: an ArchivedHttpRequest
-      use_path: If True, closest matching request's path component must match.
-        (Note: this refers to the 'path' component within the URL, not the
-         'full path' which includes the query string component.)
-
-        If use_path=True, candidate will NOT match in example below
-        e.g. request   = GET www.test.com/a?p=1
-             candidate = GET www.test.com/b?p=1
-
-        Even if use_path=False, urls with same paths are always favored.
-        For example, candidate1 is considered a better match than candidate2.
-          request    = GET www.test.com/a?p=1&q=2&r=3
-          candidate1 = GET www.test.com/a?s=4
-          candidate2 = GET www.test.com/b?p=1&q=2&r=3
-
-    Returns:
-      If a close match is found, return the instance of ArchivedHttpRequest.
-      Otherwise, return None.
-    """
-    # Start with strictest constraints. This trims search space considerably.
-    requests = self.get_requests(request.command, request.host,
-                                 request.full_path, is_ssl=request.is_ssl,
-                                 use_query=True)
-    # Relax constraint: use_query if there is no match.
-    if not requests:
-      requests = self.get_requests(request.command, request.host,
-                                   request.full_path, is_ssl=request.is_ssl,
-                                   use_query=False)
-    # Relax constraint: full_path if there is no match and use_path=False.
-    if not requests and not use_path:
-      requests = self.get_requests(request.command, request.host,
-                                   None, is_ssl=request.is_ssl,
-                                   use_query=False)
-
-    if not requests:
-      return None
-
-    if len(requests) == 1:
-      return requests[0]
-
-    matcher = difflib.SequenceMatcher(b=request.cmp_seq)
-
-    # quick_ratio() is cheap to compute, but ratio() is expensive. So we call
-    # quick_ratio() on all requests, sort them descending, and then loop through
-    # until we find a candidate whose ratio() is >= the next quick_ratio().
-    # This works because quick_ratio() is guaranteed to be an upper bound on
-    # ratio().
-    candidates = []
-    for candidate in requests:
-      matcher.set_seq1(candidate.cmp_seq)
-      candidates.append((matcher.quick_ratio(), candidate))
-
-    candidates.sort(reverse=True, key=lambda c: c[0])
-
-    best_match = (0, None)
-    for i in xrange(len(candidates)):
-      matcher.set_seq1(candidates[i][1].cmp_seq)
-      best_match = max(best_match, (matcher.ratio(), candidates[i][1]))
-      if i + 1 < len(candidates) and best_match[0] >= candidates[i+1][0]:
-        break
-    return best_match[1]
-
-  def diff(self, request):
-    """Diff the given request to the closest matching request in the archive.
-
-    Args:
-      request: an ArchivedHttpRequest
-    Returns:
-      If a close match is found, return a textual diff between the requests.
-      Otherwise, return None.
-    """
-    request_lines = request.formatted_request.split('\n')
-    closest_request = self.find_closest_request(request)
-    if closest_request:
-      closest_request_lines = closest_request.formatted_request.split('\n')
-      return '\n'.join(difflib.ndiff(closest_request_lines, request_lines))
-    return None
-
-  def get_server_cert(self, host):
-    """Gets certificate from the server and stores it in archive"""
-    request = ArchivedHttpRequest('SERVER_CERT', host, '', None, {})
-    if request not in self:
-      self[request] = create_response(200, body=certutils.get_host_cert(host))
-    return self[request].response_data[0]
-
-  def get_certificate(self, host):
-    request = ArchivedHttpRequest('DUMMY_CERT', host, '', None, {})
-    if request not in self:
-      self[request] = create_response(200, body=self._generate_cert(host))
-    return self[request].response_data[0]
-
-  @classmethod
-  def AssertWritable(cls, filename):
-    """Raises an IOError if filename is not writable."""
-    persist_dir = os.path.dirname(os.path.abspath(filename))
-    if not os.path.exists(persist_dir):
-      raise IOError('Directory does not exist: %s' % persist_dir)
-    if os.path.exists(filename):
-      if not os.access(filename, os.W_OK):
-        raise IOError('Need write permission on file: %s' % filename)
-    elif not os.access(persist_dir, os.W_OK):
-      raise IOError('Need write permission on directory: %s' % persist_dir)
-
-  @classmethod
-  def Load(cls, filename):
-    """Load an instance from filename."""
-    return cPickle.load(open(filename, 'rb'))
-
-  def Persist(self, filename):
-    """Persist all state to filename."""
-    try:
-      original_checkinterval = sys.getcheckinterval()
-      sys.setcheckinterval(2**31-1)  # Lock out other threads so nothing can
-                                     # modify |self| during pickling.
-      pickled_self = cPickle.dumps(self, cPickle.HIGHEST_PROTOCOL)
-    finally:
-      sys.setcheckinterval(original_checkinterval)
-    with open(filename, 'wb') as f:
-      f.write(pickled_self)
-
-
-class ArchivedHttpRequest(object):
-  """Record all the state that goes into a request.
-
-  ArchivedHttpRequest instances are considered immutable so they can
-  serve as keys for HttpArchive instances.
-  (The immutability is not enforced.)
-
-  Upon creation, the headers are "trimmed" (i.e. edited or dropped)
-  and saved to self.trimmed_headers to allow requests to match in a wider
-  variety of playback situations (e.g. using different user agents).
-
-  For unpickling, 'trimmed_headers' is recreated from 'headers'. That
-  allows for changes to the trim function and can help with debugging.
-  """
-  CONDITIONAL_HEADERS = [
-      'if-none-match', 'if-match',
-      'if-modified-since', 'if-unmodified-since']
-
-  def __init__(self, command, host, full_path, request_body, headers,
-               is_ssl=False):
-    """Initialize an ArchivedHttpRequest.
-
-    Args:
-      command: a string (e.g. 'GET' or 'POST').
-      host: a host name (e.g. 'www.google.com').
-      full_path: a request path.  Includes everything after the host & port in
-          the URL (e.g. '/search?q=dogs').
-      request_body: a request body string for a POST or None.
-      headers: {key: value, ...} where key and value are strings.
-      is_ssl: a boolean which is True iff request is make via SSL.
-    """
-    self.command = command
-    self.host = host
-    self.full_path = full_path
-    parsed_url = urlparse.urlparse(full_path) if full_path else None
-    self.path = parsed_url.path if parsed_url else None
-    self.request_body = request_body
-    self.headers = headers
-    self.is_ssl = is_ssl
-    self.trimmed_headers = self._TrimHeaders(headers)
-    self.formatted_request = self._GetFormattedRequest()
-    self.cmp_seq = self._GetCmpSeq(parsed_url.query if parsed_url else None)
-
-  def __str__(self):
-    scheme = 'https' if self.is_ssl else 'http'
-    return '%s %s://%s%s %s' % (
-        self.command, scheme, self.host, self.full_path, self.trimmed_headers)
-
-  def __repr__(self):
-    return repr((self.command, self.host, self.full_path, self.request_body,
-                 self.trimmed_headers, self.is_ssl))
-
-  def __hash__(self):
-    """Return a integer hash to use for hashed collections including dict."""
-    return hash(repr(self))
-
-  def __eq__(self, other):
-    """Define the __eq__ method to match the hash behavior."""
-    return repr(self) == repr(other)
-
-  def __setstate__(self, state):
-    """Influence how to unpickle.
-
-    "headers" are the original request headers.
-    "trimmed_headers" are the trimmed headers used for matching requests
-    during replay.
-
-    Args:
-      state: a dictionary for __dict__
-    """
-    if 'full_headers' in state:
-      # Fix older version of archive.
-      state['headers'] = state['full_headers']
-      del state['full_headers']
-    if 'headers' not in state:
-      raise HttpArchiveException(
-          'Archived HTTP request is missing "headers". The HTTP archive is'
-          ' likely from a previous version and must be re-recorded.')
-    if 'path' in state:
-      # before, 'path' and 'path_without_query' were used and 'path' was
-      # pickled.  Now, 'path' has been renamed to 'full_path' and
-      # 'path_without_query' has been renamed to 'path'.  'full_path' is
-      # pickled, but 'path' is not.  If we see 'path' here it means we are
-      # dealing with an older archive.
-      state['full_path'] = state['path']
-      del state['path']
-    state['trimmed_headers'] = self._TrimHeaders(dict(state['headers']))
-    if 'is_ssl' not in state:
-      state['is_ssl'] = False
-    self.__dict__.update(state)
-    parsed_url = urlparse.urlparse(self.full_path)
-    self.path = parsed_url.path
-    self.formatted_request = self._GetFormattedRequest()
-    self.cmp_seq = self._GetCmpSeq(parsed_url.query)
-
-  def __getstate__(self):
-    """Influence how to pickle.
-
-    Returns:
-      a dict to use for pickling
-    """
-    state = self.__dict__.copy()
-    del state['trimmed_headers']
-    del state['path']
-    del state['formatted_request']
-    del state['cmp_seq']
-    return state
-
-  def _GetFormattedRequest(self):
-    """Format request to make diffs easier to read.
-
-    Returns:
-      A string consisting of the request. Example:
-      'GET www.example.com/path\nHeader-Key: header value\n'
-    """
-    parts = ['%s %s%s\n' % (self.command, self.host, self.full_path)]
-    if self.request_body:
-      parts.append('%s\n' % self.request_body)
-    for k, v in self.trimmed_headers:
-      k = '-'.join(x.capitalize() for x in k.split('-'))
-      parts.append('%s: %s\n' % (k, v))
-    return ''.join(parts)
-
-  def _GetCmpSeq(self, query=None):
-    """Compute a sequence out of query and header for difflib to compare.
-    For example:
-      [('q1', 'a1'), ('q2', 'a2'), ('k1', 'v1'), ('k2', 'v2')]
-    will be returned for a request with URL:
-      http://example.com/index.html?q1=a2&q2=a2
-    and header:
-      k1: v1
-      k2: v2
-
-    Args:
-      query: the query string in the URL.
-
-    Returns:
-      A sequence for difflib to compare.
-    """
-    if not query:
-      return self.trimmed_headers
-    return sorted(urlparse.parse_qsl(query)) + self.trimmed_headers
-
-  def matches(self, command=None, host=None, full_path=None, is_ssl=None,
-              use_query=True):
-    """Returns true iff the request matches all parameters.
-
-    Args:
-      command: a string (e.g. 'GET' or 'POST').
-      host: a host name (e.g. 'www.google.com').
-      full_path: a request path with query string (e.g. '/search?q=dogs')
-      is_ssl: whether the request is secure.
-      use_query:
-        If use_query is True, request matching uses both the hierarchical path
-        and query string component.
-        If use_query is False, request matching only uses the hierarchical path
-
-        e.g. req1 = GET www.test.com/index?aaaa
-             req2 = GET www.test.com/index?bbbb
-
-        If use_query is True, req1.matches(req2) evaluates to False
-        If use_query is False, req1.matches(req2) evaluates to True
-
-    Returns:
-      True iff the request matches all parameters
-    """
-    if command is not None and command != self.command:
-      return False
-    if is_ssl is not None and is_ssl != self.is_ssl:
-      return False
-    if host is not None and host != self.host:
-      return False
-    if full_path is None:
-      return True
-    if use_query:
-      return full_path == self.full_path
-    else:
-      return self.path == urlparse.urlparse(full_path).path
-
-  @classmethod
-  def _TrimHeaders(cls, headers):
-    """Removes headers that are known to cause problems during replay.
-
-    These headers are removed for the following reasons:
-    - accept: Causes problems with www.bing.com. During record, CSS is fetched
-              with *. During replay, it's text/css.
-    - accept-charset, accept-language, referer: vary between clients.
-    - cache-control:  sometimes sent from Chrome with 'max-age=0' as value.
-    - connection, method, scheme, url, version: Cause problems with spdy.
-    - cookie: Extremely sensitive to request/response order.
-    - keep-alive: Doesn't affect the content of the request, only some
-      transient state of the transport layer.
-    - user-agent: Changes with every Chrome version.
-    - proxy-connection: Sent for proxy requests.
-    - x-chrome-variations, x-client-data: Unique to each Chrome binary. Used by
-      Google to collect statistics about Chrome's enabled features.
-
-    Another variant to consider is dropping only the value from the header.
-    However, this is particularly bad for the cookie header, because the
-    presence of the cookie depends on the responses we've seen when the request
-    is made.
-
-    Args:
-      headers: {header_key: header_value, ...}
-
-    Returns:
-      [(header_key, header_value), ...]  # (with undesirable headers removed)
-    """
-    # TODO(tonyg): Strip sdch from the request headers because we can't
-    # guarantee that the dictionary will be recorded, so replay may not work.
-    if 'accept-encoding' in headers:
-      accept_encoding = headers['accept-encoding']
-      accept_encoding = accept_encoding.replace('sdch', '')
-      # Strip lzma so Opera's requests matches archives recorded using Chrome.
-      accept_encoding = accept_encoding.replace('lzma', '')
-      stripped_encodings = [e.strip() for e in accept_encoding.split(',')]
-      accept_encoding = ','.join(filter(bool, stripped_encodings))
-      headers['accept-encoding'] = accept_encoding
-    undesirable_keys = [
-        'accept', 'accept-charset', 'accept-language', 'cache-control',
-        'connection', 'cookie', 'keep-alive', 'method',
-        'referer', 'scheme', 'url', 'version', 'user-agent', 'proxy-connection',
-        'x-chrome-variations', 'x-client-data']
-    return sorted([(k, v) for k, v in headers.items()
-                   if k.lower() not in undesirable_keys])
-
-  def is_conditional(self):
-    """Return list of headers that match conditional headers."""
-    for header in self.CONDITIONAL_HEADERS:
-      if header in self.headers:
-        return True
-    return False
-
-  def create_request_without_conditions(self):
-    stripped_headers = dict((k, v) for k, v in self.headers.iteritems()
-                            if k.lower() not in self.CONDITIONAL_HEADERS)
-    return ArchivedHttpRequest(
-        self.command, self.host, self.full_path, self.request_body,
-        stripped_headers, self.is_ssl)
-
-class ArchivedHttpResponse(object):
-  """All the data needed to recreate all HTTP response.
-
-  Upon creation, the headers are "trimmed" (i.e. edited or dropped).
-  The original headers are saved to self.original_headers, while the
-  trimmed ones are used to allow responses to match in a wider variety
-  of playback situations.
-
-  For pickling, 'original_headers' are stored in the archive.  For unpickling
-  the headers are trimmed again. That allows for changes to the trim
-  function and can help with debugging.
-  """
-
-  # CHUNK_EDIT_SEPARATOR is used to edit and view text content.
-  # It is not sent in responses. It is added by get_data_as_text()
-  # and removed by set_data().
-  CHUNK_EDIT_SEPARATOR = '[WEB_PAGE_REPLAY_CHUNK_BOUNDARY]'
-
-  # DELAY_EDIT_SEPARATOR is used to edit and view server delays.
-  DELAY_EDIT_SEPARATOR = ('\n[WEB_PAGE_REPLAY_EDIT_ARCHIVE --- '
-                          'Delays are above. Response content is below.]\n')
-
-  # This date was used in deterministic.js prior to switching to recorded
-  # request time.  See https://github.com/chromium/web-page-replay/issues/71
-  # for details.
-  DEFAULT_REQUEST_TIME = datetime.datetime(2008, 2, 29, 2, 26, 8, 254000)
-
-  def __init__(self, version, status, reason, headers, response_data,
-               delays=None, request_time=None):
-    """Initialize an ArchivedHttpResponse.
-
-    Args:
-      version: HTTP protocol version used by server.
-          10 for HTTP/1.0, 11 for HTTP/1.1 (same as httplib).
-      status: Status code returned by server (e.g. 200).
-      reason: Reason phrase returned by server (e.g. "OK").
-      headers: list of (header, value) tuples.
-      response_data: list of content chunks.
-          Concatenating the chunks gives the complete contents
-          (i.e. the chunks do not have any lengths or delimiters).
-          Do not include the final, zero-length chunk that marks the end.
-      delays: dict of (ms) delays for 'connect', 'headers' and 'data'.
-          e.g. {'connect': 50, 'headers': 150, 'data': [0, 10, 10]}
-          connect - The time to connect to the server.
-            Each resource has a value because Replay's record mode captures it.
-            This includes the time for the SYN and SYN/ACK (1 rtt).
-          headers - The time elapsed between the TCP connect and the headers.
-            This typically includes all the server-time to generate a response.
-          data - If the response is chunked, these are the times for each chunk.
-    """
-    self.version = version
-    self.status = status
-    self.reason = reason
-    self.original_headers = headers
-    self.headers = self._TrimHeaders(headers)
-    self.response_data = response_data
-    self.delays = delays
-    self.fix_delays()
-    self.request_time = (
-        request_time or ArchivedHttpResponse.DEFAULT_REQUEST_TIME
-    )
-
-  def fix_delays(self):
-    """Initialize delays, or check the number of data delays."""
-    expected_num_delays = len(self.response_data)
-    if not self.delays:
-      self.delays = {
-          'connect': 0,
-          'headers': 0,
-          'data': [0] * expected_num_delays
-          }
-    else:
-      num_delays = len(self.delays['data'])
-      if num_delays != expected_num_delays:
-        raise HttpArchiveException(
-            'Server delay length mismatch: %d (expected %d): %s',
-            num_delays, expected_num_delays, self.delays['data'])
-
-  @classmethod
-  def _TrimHeaders(cls, headers):
-    """Removes headers that are known to cause problems during replay.
-
-    These headers are removed for the following reasons:
-    - content-security-policy: Causes problems with script injection.
-    """
-    undesirable_keys = ['content-security-policy']
-    return [(k, v) for k, v in headers if k.lower() not in undesirable_keys]
-
-  def __repr__(self):
-    return repr((self.version, self.status, self.reason, sorted(self.headers),
-                 self.response_data, self.request_time))
-
-  def __hash__(self):
-    """Return a integer hash to use for hashed collections including dict."""
-    return hash(repr(self))
-
-  def __eq__(self, other):
-    """Define the __eq__ method to match the hash behavior."""
-    return repr(self) == repr(other)
-
-  def __setstate__(self, state):
-    """Influence how to unpickle.
-
-    "original_headers" are the original request headers.
-    "headers" are the trimmed headers used for replaying responses.
-
-    Args:
-      state: a dictionary for __dict__
-    """
-    if 'server_delays' in state:
-      state['delays'] = {
-          'connect': 0,
-          'headers': 0,
-          'data': state['server_delays']
-          }
-      del state['server_delays']
-    elif 'delays' not in state:
-      state['delays'] = None
-    # Set to date that was hardcoded in deterministic.js originally.
-    state.setdefault('request_time', ArchivedHttpResponse.DEFAULT_REQUEST_TIME)
-    state['original_headers'] = state['headers']
-    state['headers'] = self._TrimHeaders(state['original_headers'])
-    self.__dict__.update(state)
-    self.fix_delays()
-
-  def __getstate__(self):
-    """Influence how to pickle.
-
-    Returns:
-      a dict to use for pickling
-    """
-    state = self.__dict__.copy()
-    state['headers'] = state['original_headers']
-    del state['original_headers']
-    return state
-
-  def get_header(self, key, default=None):
-    for k, v in self.headers:
-      if key.lower() == k.lower():
-        return v
-    return default
-
-  def set_header(self, key, value):
-    for i, (k, v) in enumerate(self.headers):
-      if key == k:
-        self.headers[i] = (key, value)
-        return
-    self.headers.append((key, value))
-
-  def remove_header(self, key):
-    for i, (k, v) in enumerate(self.headers):
-      if key.lower() == k.lower():
-        self.headers.pop(i)
-        return
-
-  @staticmethod
-  def _get_epoch_seconds(date_str):
-    """Return the epoch seconds of a date header.
-
-    Args:
-      date_str: a date string (e.g. "Thu, 01 Dec 1994 16:00:00 GMT")
-    Returns:
-      epoch seconds as a float
-    """
-    date_tuple = email.utils.parsedate(date_str)
-    if date_tuple:
-      return calendar.timegm(date_tuple)
-    return None
-
-  def update_date(self, date_str, now=None):
-    """Return an updated date based on its delta from the "Date" header.
-
-    For example, if |date_str| is one week later than the "Date" header,
-    then the returned date string is one week later than the current date.
-
-    Args:
-      date_str: a date string (e.g. "Thu, 01 Dec 1994 16:00:00 GMT")
-    Returns:
-      a date string
-    """
-    date_seconds = self._get_epoch_seconds(self.get_header('date'))
-    header_seconds = self._get_epoch_seconds(date_str)
-    if date_seconds and header_seconds:
-      updated_seconds = header_seconds + (now or time.time()) - date_seconds
-      return email.utils.formatdate(updated_seconds, usegmt=True)
-    return date_str
-
-  def is_gzip(self):
-    return self.get_header('content-encoding') == 'gzip'
-
-  def is_compressed(self):
-    return self.get_header('content-encoding') in ('gzip', 'deflate')
-
-  def is_chunked(self):
-    return self.get_header('transfer-encoding') == 'chunked'
-
-  def get_data_as_chunks(self):
-    """Return content as a list of strings, each corresponding to a chunk.
-
-    Uncompresses the chunks, if needed.
-    """
-    content_type = self.get_header('content-type')
-    if (not content_type or
-        not (content_type.startswith('text/') or
-             content_type == 'application/x-javascript' or
-             content_type.startswith('application/json'))):
-      return None
-    if self.is_compressed():
-      return httpzlib.uncompress_chunks(self.response_data, self.is_gzip())
-    else:
-      return self.response_data
-
-  def get_data_as_text(self):
-    """Return content as a single string.
-
-    Uncompresses and concatenates chunks with CHUNK_EDIT_SEPARATOR.
-    """
-    return self.CHUNK_EDIT_SEPARATOR.join(self.get_data_as_chunks())
-
-  def get_delays_as_text(self):
-    """Return delays as editable text."""
-    return json.dumps(self.delays, indent=2)
-
-  def get_response_as_text(self):
-    """Returns response content as a single string.
-
-    Server delays are separated on a per-chunk basis. Delays are in seconds.
-    Response content begins after DELAY_EDIT_SEPARATOR
-    """
-    data = self.get_data_as_text()
-    if data is None:
-      logging.warning('Data can not be represented as text.')
-      data = ''
-    delays = self.get_delays_as_text()
-    return self.DELAY_EDIT_SEPARATOR.join((delays, data))
-
-  def set_data_from_chunks(self, text_chunks):
-    """Inverse of get_data_as_chunks().
-
-    Compress, if needed.
-    """
-    if self.is_compressed():
-      self.response_data = httpzlib.compress_chunks(text_chunks, self.is_gzip())
-    else:
-      self.response_data = text_chunks
-    if not self.is_chunked():
-      content_length = sum(len(c) for c in self.response_data)
-      self.set_header('content-length', str(content_length))
-
-  def set_data(self, text):
-    """Inverse of get_data_as_text().
-
-    Split on CHUNK_EDIT_SEPARATOR and compress if needed.
-    """
-    self.set_data_from_chunks(text.split(self.CHUNK_EDIT_SEPARATOR))
-
-  def set_delays(self, delays_text):
-    """Inverse of get_delays_as_text().
-
-    Args:
-      delays_text: JSON encoded text such as the following:
-          {
-            connect: 80,
-            headers: 80,
-            data: [6, 55, 0]
-          }
-        Times are in milliseconds.
-        Each data delay corresponds with one response_data value.
-    """
-    try:
-      self.delays = json.loads(delays_text)
-    except (ValueError, KeyError) as e:
-      logging.critical('Unable to parse delays %s: %s', delays_text, e)
-    self.fix_delays()
-
-  def set_response_from_text(self, text):
-    """Inverse of get_response_as_text().
-
-    Modifies the state of the archive according to the textual representation.
-    """
-    try:
-      delays, data = text.split(self.DELAY_EDIT_SEPARATOR)
-    except ValueError:
-      logging.critical(
-          'Error parsing text representation. Skipping edits.')
-      return
-    self.set_delays(delays)
-    self.set_data(data)
-
-
-def create_response(status, reason=None, headers=None, body=None):
-  """Convenience method for creating simple ArchivedHttpResponse objects."""
-  if reason is None:
-    reason = httplib.responses.get(status, 'Unknown')
-  if headers is None:
-    headers = [('content-type', 'text/plain')]
-  if body is None:
-    body = "%s %s" % (status, reason)
-  return ArchivedHttpResponse(11, status, reason, headers, [body])
-
-
-def main():
-  class PlainHelpFormatter(optparse.IndentedHelpFormatter):
-    def format_description(self, description):
-      if description:
-        return description + '\n'
-      else:
-        return ''
-
-  option_parser = optparse.OptionParser(
-      usage='%prog [ls|cat|edit|stats|merge] [options] replay_file(s)',
-      formatter=PlainHelpFormatter(),
-      description=__doc__,
-      epilog='http://code.google.com/p/web-page-replay/')
-
-  option_parser.add_option('-c', '--command', default=None,
-      action='store',
-      type='string',
-      help='Only show URLs matching this command.')
-  option_parser.add_option('-o', '--host', default=None,
-      action='store',
-      type='string',
-      help='Only show URLs matching this host.')
-  option_parser.add_option('-p', '--full_path', default=None,
-      action='store',
-      type='string',
-      help='Only show URLs matching this full path.')
-  option_parser.add_option('-f', '--merged_file', default=None,
-        action='store',
-        type='string',
-        help='The output file to use when using the merge command.')
-
-  options, args = option_parser.parse_args()
-
-  # Merge command expects an umlimited number of archives.
-  if len(args) < 2:
-    print 'args: %s' % args
-    option_parser.error('Must specify a command and replay_file')
-
-  command = args[0]
-  replay_file = args[1]
-
-  if not os.path.exists(replay_file):
-    option_parser.error('Replay file "%s" does not exist' % replay_file)
-
-  http_archive = HttpArchive.Load(replay_file)
-  if command == 'ls':
-    print http_archive.ls(options.command, options.host, options.full_path)
-  elif command == 'cat':
-    print http_archive.cat(options.command, options.host, options.full_path)
-  elif command == 'stats':
-    print http_archive.stats(options.command, options.host, options.full_path)
-  elif command == 'merge':
-    if not options.merged_file:
-      print 'Error: Must specify a merged file name (use --merged_file)'
-      return
-    http_archive.merge(options.merged_file, args[2:])
-  elif command == 'edit':
-    http_archive.edit(options.command, options.host, options.full_path)
-    http_archive.Persist(replay_file)
-  else:
-    option_parser.error('Unknown command "%s"' % command)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/catapult/telemetry/third_party/web-page-replay/httparchive_test.py b/catapult/telemetry/third_party/web-page-replay/httparchive_test.py
deleted file mode 100755
index 12923d4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httparchive_test.py
+++ /dev/null
@@ -1,484 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2011 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import calendar
-import email.utils
-import httparchive
-import unittest
-
-
-def create_request(headers):
-  return httparchive.ArchivedHttpRequest(
-      'GET', 'www.test.com', '/', None, headers)
-
-def create_response(headers):
-  return httparchive.ArchivedHttpResponse(
-      11, 200, 'OK', headers, '')
-
-
-class HttpArchiveTest(unittest.TestCase):
-
-  REQUEST_HEADERS = {}
-  REQUEST = create_request(REQUEST_HEADERS)
-
-  # Used for if-(un)modified-since checks
-  DATE_PAST = 'Wed, 13 Jul 2011 03:58:08 GMT'
-  DATE_PRESENT = 'Wed, 20 Jul 2011 04:58:08 GMT'
-  DATE_FUTURE = 'Wed, 27 Jul 2011 05:58:08 GMT'
-  DATE_INVALID = 'This is an invalid date!!'
-
-  # etag values
-  ETAG_VALID = 'etag'
-  ETAG_INVALID = 'This is an invalid etag value!!'
-
-  RESPONSE_HEADERS = [('last-modified', DATE_PRESENT), ('etag', ETAG_VALID)]
-  RESPONSE = create_response(RESPONSE_HEADERS)
-
-  def setUp(self):
-    self.archive = httparchive.HttpArchive()
-    self.archive[self.REQUEST] = self.RESPONSE
-
-    # Also add an identical POST request for testing
-    request = httparchive.ArchivedHttpRequest(
-        'POST', 'www.test.com', '/', None, self.REQUEST_HEADERS)
-    self.archive[request] = self.RESPONSE
-
-  def tearDown(self):
-    pass
-
-  def test_init(self):
-    archive = httparchive.HttpArchive()
-    self.assertEqual(len(archive), 0)
-
-  def test_request__TrimHeaders(self):
-    request = httparchive.ArchivedHttpRequest
-    header1 = {'accept-encoding': 'gzip,deflate'}
-    self.assertEqual(request._TrimHeaders(header1),
-                     [(k, v) for k, v in header1.items()])
-
-    header2 = {'referer': 'www.google.com'}
-    self.assertEqual(request._TrimHeaders(header2), [])
-
-    header3 = {'referer': 'www.google.com', 'cookie': 'cookie_monster!',
-               'hello': 'world'}
-    self.assertEqual(request._TrimHeaders(header3), [('hello', 'world')])
-
-    # Tests that spaces and trailing comma get stripped.
-    header4 = {'accept-encoding': 'gzip, deflate,, '}
-    self.assertEqual(request._TrimHeaders(header4),
-                     [('accept-encoding', 'gzip,deflate')])
-
-    # Tests that 'lzma' gets stripped.
-    header5 = {'accept-encoding': 'gzip, deflate, lzma'}
-    self.assertEqual(request._TrimHeaders(header5),
-                     [('accept-encoding', 'gzip,deflate')])
-
-    # Tests that x-client-data gets stripped.
-    header6 = {'x-client-data': 'testdata'}
-    self.assertEqual(request._TrimHeaders(header6), [])
-
-  def test_matches(self):
-    headers = {}
-    request1 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/index.html?hello=world', None, headers)
-    request2 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/index.html?foo=bar', None, headers)
-
-    self.assert_(not request1.matches(
-        request2.command, request2.host, request2.full_path, use_query=True))
-    self.assert_(request1.matches(
-        request2.command, request2.host, request2.full_path, use_query=False))
-
-    self.assert_(request1.matches(
-        request2.command, request2.host, None, use_query=True))
-    self.assert_(request1.matches(
-        request2.command, None, request2.full_path, use_query=False))
-
-    empty_request = httparchive.ArchivedHttpRequest(
-        None, None, None, None, headers)
-    self.assert_(not empty_request.matches(
-        request2.command, request2.host, None, use_query=True))
-    self.assert_(not empty_request.matches(
-        request2.command, None, request2.full_path, use_query=False))
-
-  def setup_find_closest_request(self):
-    headers = {}
-    request1 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/a?hello=world', None, headers)
-    request2 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/a?foo=bar', None, headers)
-    request3 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/b?hello=world', None, headers)
-    request4 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/c?hello=world', None, headers)
-
-    archive = httparchive.HttpArchive()
-    # Add requests 2 and 3 and find closest match with request1
-    archive[request2] = self.RESPONSE
-    archive[request3] = self.RESPONSE
-
-    return archive, request1, request2, request3, request4
-
-  def test_find_closest_request(self):
-    archive, request1, request2, request3, request4 = (
-      self.setup_find_closest_request())
-
-    # Always favor requests with same paths, even if use_path=False.
-    self.assertEqual(
-        request2, archive.find_closest_request(request1, use_path=False))
-    # If we match strictly on path, request2 is the only match
-    self.assertEqual(
-        request2, archive.find_closest_request(request1, use_path=True))
-    # request4 can be matched with request3, if use_path=False
-    self.assertEqual(
-        request3, archive.find_closest_request(request4, use_path=False))
-    # ...but None, if use_path=True
-    self.assertEqual(
-        None, archive.find_closest_request(request4, use_path=True))
-
-  def test_find_closest_request_delete_simple(self):
-    archive, request1, request2, request3, request4 = (
-      self.setup_find_closest_request())
-
-    del archive[request3]
-    self.assertEqual(
-        request2, archive.find_closest_request(request1, use_path=False))
-    self.assertEqual(
-        request2, archive.find_closest_request(request1, use_path=True))
-
-  def test_find_closest_request_delete_complex(self):
-    archive, request1, request2, request3, request4 = (
-      self.setup_find_closest_request())
-
-    del archive[request2]
-    self.assertEqual(
-        request3, archive.find_closest_request(request1, use_path=False))
-    self.assertEqual(
-        None, archive.find_closest_request(request1, use_path=True))
-
-  def test_find_closest_request_timestamp(self):
-    headers = {}
-    request1 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/index.html?time=100000000&important=true',
-        None, headers)
-    request2 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/index.html?time=99999999&important=true',
-        None, headers)
-    request3 = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/index.html?time=10000000&important=false',
-        None, headers)
-    archive = httparchive.HttpArchive()
-    # Add requests 2 and 3 and find closest match with request1
-    archive[request2] = self.RESPONSE
-    archive[request3] = self.RESPONSE
-
-    # Although request3 is lexicographically closer, request2 is semantically
-    # more similar.
-    self.assertEqual(
-        request2, archive.find_closest_request(request1, use_path=True))
-
-  def test_get_cmp_seq(self):
-    # The order of key-value pairs in query and header respectively should not
-    # matter.
-    headers = {'k2': 'v2', 'k1': 'v1'}
-    request = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/a?c=d&a=b;e=f', None, headers)
-    self.assertEqual([('a', 'b'), ('c', 'd'), ('e', 'f'),
-                      ('k1', 'v1'), ('k2', 'v2')],
-                     request._GetCmpSeq('c=d&a=b;e=f'))
-
-  def test_get_simple(self):
-    request = self.REQUEST
-    response = self.RESPONSE
-    archive = self.archive
-
-    self.assertEqual(archive.get(request), response)
-
-    false_request_headers = {'foo': 'bar'}
-    false_request = create_request(false_request_headers)
-    self.assertEqual(archive.get(false_request, default=None), None)
-
-  def test_get_modified_headers(self):
-    request = self.REQUEST
-    response = self.RESPONSE
-    archive = self.archive
-    not_modified_response = httparchive.create_response(304)
-
-    # Fail check and return response again
-    request_headers = {'if-modified-since': self.DATE_PAST}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    # Succeed check and return 304 Not Modified
-    request_headers = {'if-modified-since': self.DATE_FUTURE}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    # Succeed check and return 304 Not Modified
-    request_headers = {'if-modified-since': self.DATE_PRESENT}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    # Invalid date, fail check and return response again
-    request_headers = {'if-modified-since': self.DATE_INVALID}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    # fail check since the request is not a GET or HEAD request (as per RFC)
-    request_headers = {'if-modified-since': self.DATE_FUTURE}
-    request = httparchive.ArchivedHttpRequest(
-        'POST', 'www.test.com', '/', None, request_headers)
-    self.assertEqual(archive.get(request), response)
-
-  def test_get_unmodified_headers(self):
-    request = self.REQUEST
-    response = self.RESPONSE
-    archive = self.archive
-    not_modified_response = httparchive.create_response(304)
-
-    # Succeed check
-    request_headers = {'if-unmodified-since': self.DATE_PAST}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    # Fail check
-    request_headers = {'if-unmodified-since': self.DATE_FUTURE}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    # Succeed check
-    request_headers = {'if-unmodified-since': self.DATE_PRESENT}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    # Fail check
-    request_headers = {'if-unmodified-since': self.DATE_INVALID}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    # Fail check since the request is not a GET or HEAD request (as per RFC)
-    request_headers = {'if-modified-since': self.DATE_PAST}
-    request = httparchive.ArchivedHttpRequest(
-        'POST', 'www.test.com', '/', None, request_headers)
-    self.assertEqual(archive.get(request), response)
-
-  def test_get_etags(self):
-    request = self.REQUEST
-    response = self.RESPONSE
-    archive = self.archive
-    not_modified_response = httparchive.create_response(304)
-    precondition_failed_response = httparchive.create_response(412)
-
-    # if-match headers
-    request_headers = {'if-match': self.ETAG_VALID}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    request_headers = {'if-match': self.ETAG_INVALID}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), precondition_failed_response)
-
-    # if-none-match headers
-    request_headers = {'if-none-match': self.ETAG_VALID}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    request_headers = {'if-none-match': self.ETAG_INVALID}
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-  def test_get_multiple_match_headers(self):
-    request = self.REQUEST
-    response = self.RESPONSE
-    archive = self.archive
-    not_modified_response = httparchive.create_response(304)
-    precondition_failed_response = httparchive.create_response(412)
-
-    # if-match headers
-    # If the request would, without the If-Match header field,
-    # result in anything other than a 2xx or 412 status,
-    # then the If-Match header MUST be ignored.
-
-    request_headers = {
-        'if-match': self.ETAG_VALID,
-        'if-modified-since': self.DATE_PAST,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    # Invalid etag, precondition failed
-    request_headers = {
-        'if-match': self.ETAG_INVALID,
-        'if-modified-since': self.DATE_PAST,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), precondition_failed_response)
-
-    # 304 response; ignore if-match header
-    request_headers = {
-        'if-match': self.ETAG_VALID,
-        'if-modified-since': self.DATE_FUTURE,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    # 304 response; ignore if-match header
-    request_headers = {
-        'if-match': self.ETAG_INVALID,
-        'if-modified-since': self.DATE_PRESENT,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    # Invalid etag, precondition failed
-    request_headers = {
-        'if-match': self.ETAG_INVALID,
-        'if-modified-since': self.DATE_INVALID,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), precondition_failed_response)
-
-  def test_get_multiple_none_match_headers(self):
-    request = self.REQUEST
-    response = self.RESPONSE
-    archive = self.archive
-    not_modified_response = httparchive.create_response(304)
-    precondition_failed_response = httparchive.create_response(412)
-
-    # if-none-match headers
-    # If the request would, without the If-None-Match header field,
-    # result in anything other than a 2xx or 304 status,
-    # then the If-None-Match header MUST be ignored.
-
-    request_headers = {
-        'if-none-match': self.ETAG_VALID,
-        'if-modified-since': self.DATE_PAST,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    request_headers = {
-        'if-none-match': self.ETAG_INVALID,
-        'if-modified-since': self.DATE_PAST,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-    # etag match, precondition failed
-    request_headers = {
-        'if-none-match': self.ETAG_VALID,
-        'if-modified-since': self.DATE_FUTURE,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    request_headers = {
-        'if-none-match': self.ETAG_INVALID,
-        'if-modified-since': self.DATE_PRESENT,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), not_modified_response)
-
-    request_headers = {
-        'if-none-match': self.ETAG_INVALID,
-        'if-modified-since': self.DATE_INVALID,
-    }
-    request = create_request(request_headers)
-    self.assertEqual(archive.get(request), response)
-
-  def test_response__TrimHeaders(self):
-    response = httparchive.ArchivedHttpResponse
-    header1 = [('access-control-allow-origin', '*'),
-               ('content-type', 'image/jpeg'),
-               ('content-length', 2878)]
-    self.assertEqual(response._TrimHeaders(header1), header1)
-
-    header2 = [('content-type', 'text/javascript; charset=utf-8'),
-               ('connection', 'keep-alive'),
-               ('cache-control', 'private, must-revalidate, max-age=0'),
-               ('content-encoding', 'gzip')]
-    self.assertEqual(response._TrimHeaders(header2), header2)
-
-    header3 = [('content-security-policy', """\
-default-src 'self' http://*.cnn.com:* https://*.cnn.com:* \
-*.cnn.net:* *.turner.com:* *.ugdturner.com:* *.vgtf.net:*; \
-script-src 'unsafe-inline' 'unsafe-eval' 'self' *; \
-style-src 'unsafe-inline' 'self' *; frame-src 'self' *; \
-object-src 'self' *; img-src 'self' * data:; media-src 'self' *; \
-font-src 'self' *; connect-src 'self' *"""),
-               ('access-control-allow-origin', '*'),
-               ('content-type', 'text/html; charset=utf-8'),
-               ('content-encoding', 'gzip')]
-    self.assertEqual(response._TrimHeaders(header3), [
-        ('access-control-allow-origin', '*'),
-        ('content-type', 'text/html; charset=utf-8'),
-        ('content-encoding', 'gzip')
-    ])
-
-    header4 = [('content-security-policy', """\
-default-src * data: blob:;script-src *.facebook.com *.fbcdn.net \
-*.facebook.net *.google-analytics.com *.virtualearth.net *.google.com \
-127.0.0.1:* *.spotilocal.com:* 'unsafe-inline' 'unsafe-eval' \
-fbstatic-a.akamaihd.net fbcdn-static-b-a.akamaihd.net *.atlassolutions.com \
-blob: chrome-extension://lifbcibllhkdhoafpjfnlhfpfgnpldfl \
-*.liverail.com;style-src * 'unsafe-inline' data:;connect-src *.facebook.com \
-*.fbcdn.net *.facebook.net *.spotilocal.com:* *.akamaihd.net \
-wss://*.facebook.com:* https://fb.scanandcleanlocal.com:* \
-*.atlassolutions.com attachment.fbsbx.com ws://localhost:* \
-blob: 127.0.0.1:* *.liverail.com""")]
-    self.assertEqual(response._TrimHeaders(header4), [])
-
-
-class ArchivedHttpResponse(unittest.TestCase):
-  PAST_DATE_A = 'Tue, 13 Jul 2010 03:47:07 GMT'
-  PAST_DATE_B = 'Tue, 13 Jul 2010 02:47:07 GMT'  # PAST_DATE_A -1 hour
-  PAST_DATE_C = 'Tue, 13 Jul 2010 04:47:07 GMT'  # PAST_DATE_A +1 hour
-  NOW_DATE_A = 'Wed, 20 Jul 2011 04:58:08 GMT'
-  NOW_DATE_B = 'Wed, 20 Jul 2011 03:58:08 GMT'  # NOW_DATE_A -1 hour
-  NOW_DATE_C = 'Wed, 20 Jul 2011 05:58:08 GMT'  # NOW_DATE_A +1 hour
-  NOW_SECONDS = calendar.timegm(email.utils.parsedate(NOW_DATE_A))
-
-  def setUp(self):
-    self.response = create_response([('date', self.PAST_DATE_A)])
-
-  def test_update_date_same_date(self):
-    self.assertEqual(
-        self.response.update_date(self.PAST_DATE_A, now=self.NOW_SECONDS),
-        self.NOW_DATE_A)
-
-  def test_update_date_before_date(self):
-    self.assertEqual(
-        self.response.update_date(self.PAST_DATE_B, now=self.NOW_SECONDS),
-        self.NOW_DATE_B)
-
-  def test_update_date_after_date(self):
-    self.assertEqual(
-        self.response.update_date(self.PAST_DATE_C, now=self.NOW_SECONDS),
-        self.NOW_DATE_C)
-
-  def test_update_date_bad_date_param(self):
-    self.assertEqual(
-        self.response.update_date('garbage date', now=self.NOW_SECONDS),
-        'garbage date')
-
-  def test_update_date_bad_date_header(self):
-    self.response.set_header('date', 'garbage date')
-    self.assertEqual(
-        self.response.update_date(self.PAST_DATE_B, now=self.NOW_SECONDS),
-        self.PAST_DATE_B)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/httpclient.py b/catapult/telemetry/third_party/web-page-replay/httpclient.py
deleted file mode 100644
index 5db5e50..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httpclient.py
+++ /dev/null
@@ -1,512 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Retrieve web resources over http."""
-
-import copy
-import datetime
-import httplib
-import logging
-import random
-import ssl
-import StringIO
-
-import httparchive
-import platformsettings
-import script_injector
-
-
-# PIL isn't always available, but we still want to be able to run without
-# the image scrambling functionality in this case.
-try:
-  import Image
-except ImportError:
-  Image = None
-
-TIMER = platformsettings.timer
-
-
-class HttpClientException(Exception):
-  """Base class for all exceptions in httpclient."""
-  pass
-
-
-def _InjectScripts(response, injector):
-  """Injects script generated by |injector| immediately after <head> or <html>.
-
-  Copies |response| if it is modified.
-
-  Args:
-    response: an ArchivedHttpResponse
-    injector: function which generates JavaScript string
-      based on recording time (e.g. "Math.random = function(){...}")
-  Returns:
-    an ArchivedHttpResponse
-  """
-  if type(response) == tuple:
-    logging.warn('tuple response: %s', response)
-  content_type = response.get_header('content-type')
-  if content_type and content_type.startswith('text/html'):
-    text_chunks = response.get_data_as_chunks()
-    text_chunks, just_injected = script_injector.InjectScript(
-        text_chunks, 'text/html', injector(response.request_time))
-    if just_injected:
-      response = copy.deepcopy(response)
-      response.set_data_from_chunks(text_chunks)
-  return response
-
-
-def _ScrambleImages(response):
-  """If the |response| is an image, attempt to scramble it.
-
-  Copies |response| if it is modified.
-
-  Args:
-    response: an ArchivedHttpResponse
-  Returns:
-    an ArchivedHttpResponse
-  """
-
-  assert Image, '--scramble_images requires the PIL module to be installed.'
-
-  content_type = response.get_header('content-type')
-  if content_type and content_type.startswith('image/'):
-    try:
-      image_data = response.response_data[0]
-      image_data.decode(encoding='base64')
-      im = Image.open(StringIO.StringIO(image_data))
-
-      pixel_data = list(im.getdata())
-      random.shuffle(pixel_data)
-
-      scrambled_image = im.copy()
-      scrambled_image.putdata(pixel_data)
-
-      output_image_io = StringIO.StringIO()
-      scrambled_image.save(output_image_io, im.format)
-      output_image_data = output_image_io.getvalue()
-      output_image_data.encode(encoding='base64')
-
-      response = copy.deepcopy(response)
-      response.set_data(output_image_data)
-    except Exception:
-      pass
-
-  return response
-
-
-class DetailedHTTPResponse(httplib.HTTPResponse):
-  """Preserve details relevant to replaying responses.
-
-  WARNING: This code uses attributes and methods of HTTPResponse
-  that are not part of the public interface.
-  """
-
-  def read_chunks(self):
-    """Return the response body content and timing data.
-
-    The returned chunks have the chunk size and CRLFs stripped off.
-    If the response was compressed, the returned data is still compressed.
-
-    Returns:
-      (chunks, delays)
-        chunks:
-          [response_body]                  # non-chunked responses
-          [chunk_1, chunk_2, ...]          # chunked responses
-        delays:
-          [0]                              # non-chunked responses
-          [chunk_1_first_byte_delay, ...]  # chunked responses
-
-      The delay for the first body item should be recorded by the caller.
-    """
-    buf = []
-    chunks = []
-    delays = []
-    if not self.chunked:
-      chunks.append(self.read())
-      delays.append(0)
-    else:
-      start = TIMER()
-      try:
-        while True:
-          line = self.fp.readline()
-          chunk_size = self._read_chunk_size(line)
-          if chunk_size is None:
-            raise httplib.IncompleteRead(''.join(chunks))
-          if chunk_size == 0:
-            break
-          delays.append(TIMER() - start)
-          chunks.append(self._safe_read(chunk_size))
-          self._safe_read(2)  # skip the CRLF at the end of the chunk
-          start = TIMER()
-
-        # Ignore any trailers.
-        while True:
-          line = self.fp.readline()
-          if not line or line == '\r\n':
-            break
-      finally:
-        self.close()
-    return chunks, delays
-
-  @classmethod
-  def _read_chunk_size(cls, line):
-    chunk_extensions_pos = line.find(';')
-    if chunk_extensions_pos != -1:
-      line = line[:chunk_extensions_pos]  # strip chunk-extensions
-    try:
-      chunk_size = int(line, 16)
-    except ValueError:
-      return None
-    return chunk_size
-
-
-class DetailedHTTPConnection(httplib.HTTPConnection):
-  """Preserve details relevant to replaying connections."""
-  response_class = DetailedHTTPResponse
-
-
-class DetailedHTTPSResponse(DetailedHTTPResponse):
-  """Preserve details relevant to replaying SSL responses."""
-  pass
-
-
-class DetailedHTTPSConnection(httplib.HTTPSConnection):
-  """Preserve details relevant to replaying SSL connections."""
-  response_class = DetailedHTTPSResponse
-
-  def __init__(self, host, port):
-    # https://www.python.org/dev/peps/pep-0476/#opting-out
-    if hasattr(ssl, '_create_unverified_context'):
-      httplib.HTTPSConnection.__init__(
-          self, host=host, port=port, context=ssl._create_unverified_context())
-    else:
-      httplib.HTTPSConnection.__init__(self, host=host, port=port)
-
-
-class RealHttpFetch(object):
-
-  def __init__(self, real_dns_lookup):
-    """Initialize RealHttpFetch.
-
-    Args:
-      real_dns_lookup: a function that resolves a host to an IP. RealHttpFetch
-        will resolve host name to the IP before making fetching request if this
-        is not None.
-    """
-    self._real_dns_lookup = real_dns_lookup
-
-  @staticmethod
-  def _GetHeaderNameValue(header):
-    """Parse the header line and return a name/value tuple.
-
-    Args:
-      header: a string for a header such as "Content-Length: 314".
-    Returns:
-      A tuple (header_name, header_value) on success or None if the header
-      is not in expected format. header_name is in lowercase.
-    """
-    i = header.find(':')
-    if i > 0:
-      return (header[:i].lower(), header[i+1:].strip())
-    return None
-
-  @staticmethod
-  def _ToTuples(headers):
-    """Parse headers and save them to a list of tuples.
-
-    This method takes HttpResponse.msg.headers as input and convert it
-    to a list of (header_name, header_value) tuples.
-    HttpResponse.msg.headers is a list of strings where each string
-    represents either a header or a continuation line of a header.
-    1. a normal header consists of two parts which are separated by colon :
-       "header_name:header_value..."
-    2. a continuation line is a string starting with whitespace
-       "[whitespace]continued_header_value..."
-    If a header is not in good shape or an unexpected continuation line is
-    seen, it will be ignored.
-
-    Should avoid using response.getheaders() directly
-    because response.getheaders() can't handle multiple headers
-    with the same name properly. Instead, parse the
-    response.msg.headers using this method to get all headers.
-
-    Args:
-      headers: an instance of HttpResponse.msg.headers.
-    Returns:
-      A list of tuples which looks like:
-      [(header_name, header_value), (header_name2, header_value2)...]
-    """
-    all_headers = []
-    for line in headers:
-      if line[0] in '\t ':
-        if not all_headers:
-          logging.warning(
-              'Unexpected response header continuation line [%s]', line)
-          continue
-        name, value = all_headers.pop()
-        value += '\n ' + line.strip()
-      else:
-        name_value = RealHttpFetch._GetHeaderNameValue(line)
-        if not name_value:
-          logging.warning(
-              'Response header in wrong format [%s]', line)
-          continue
-        name, value = name_value  # pylint: disable=unpacking-non-sequence
-      all_headers.append((name, value))
-    return all_headers
-
-  @staticmethod
-  def _get_request_host_port(request):
-    host_parts = request.host.split(':')
-    host = host_parts[0]
-    port = int(host_parts[1]) if len(host_parts) == 2 else None
-    return host, port
-
-  @staticmethod
-  def _get_system_proxy(is_ssl):
-    return platformsettings.get_system_proxy(is_ssl)
-
-  def _get_connection(self, request_host, request_port, is_ssl):
-    """Return a detailed connection object for host/port pair.
-
-    If a system proxy is defined (see platformsettings.py), it will be used.
-
-    Args:
-      request_host: a host string (e.g. "www.example.com").
-      request_port: a port integer (e.g. 8080) or None (for the default port).
-      is_ssl: True if HTTPS connection is needed.
-    Returns:
-      A DetailedHTTPSConnection or DetailedHTTPConnection instance.
-    """
-    connection_host = request_host
-    connection_port = request_port
-    system_proxy = self._get_system_proxy(is_ssl)
-    if system_proxy:
-      connection_host = system_proxy.host
-      connection_port = system_proxy.port
-
-    # Use an IP address because WPR may override DNS settings.
-    if self._real_dns_lookup:
-      connection_ip = self._real_dns_lookup(connection_host)
-      if not connection_ip:
-        logging.critical(
-            'Unable to find IP for host name: %s', connection_host)
-        return None
-      connection_host = connection_ip
-
-    if is_ssl:
-      connection = DetailedHTTPSConnection(connection_host, connection_port)
-      if system_proxy:
-        connection.set_tunnel(request_host, request_port)
-    else:
-      connection = DetailedHTTPConnection(connection_host, connection_port)
-    return connection
-
-  def __call__(self, request):
-    """Fetch an HTTP request.
-
-    Args:
-      request: an ArchivedHttpRequest
-    Returns:
-      an ArchivedHttpResponse
-    """
-    logging.debug('RealHttpFetch: %s %s', request.host, request.full_path)
-    request_host, request_port = self._get_request_host_port(request)
-    retries = 3
-    while True:
-      try:
-        request_time = datetime.datetime.utcnow()
-        connection = self._get_connection(
-            request_host, request_port, request.is_ssl)
-        connect_start = TIMER()
-        connection.connect()
-        connect_delay = int((TIMER() - connect_start) * 1000)
-        start = TIMER()
-        connection.request(
-            request.command,
-            request.full_path,
-            request.request_body,
-            request.headers)
-        response = connection.getresponse()
-        headers_delay = int((TIMER() - start) * 1000)
-
-        chunks, chunk_delays = response.read_chunks()
-        delays = {
-            'connect': connect_delay,
-            'headers': headers_delay,
-            'data': chunk_delays
-            }
-        archived_http_response = httparchive.ArchivedHttpResponse(
-            response.version,
-            response.status,
-            response.reason,
-            RealHttpFetch._ToTuples(response.msg.headers),
-            chunks,
-            delays,
-            request_time)
-        return archived_http_response
-      except Exception, e:
-        if retries:
-          retries -= 1
-          logging.warning('Retrying fetch %s: %s', request, repr(e))
-          continue
-        logging.critical('Could not fetch %s: %s', request, repr(e))
-        return None
-
-
-class RecordHttpArchiveFetch(object):
-  """Make real HTTP fetches and save responses in the given HttpArchive."""
-
-  def __init__(self, http_archive, injector):
-    """Initialize RecordHttpArchiveFetch.
-
-    Args:
-      http_archive: an instance of a HttpArchive
-      injector: script injector to inject scripts in all pages
-    """
-    self.http_archive = http_archive
-    # Do not resolve host name to IP when recording to avoid SSL3 handshake
-    # failure.
-    # See https://github.com/chromium/web-page-replay/issues/73 for details.
-    self.real_http_fetch = RealHttpFetch(real_dns_lookup=None)
-    self.injector = injector
-
-  def __call__(self, request):
-    """Fetch the request and return the response.
-
-    Args:
-      request: an ArchivedHttpRequest.
-    Returns:
-      an ArchivedHttpResponse
-    """
-    # If request is already in the archive, return the archived response.
-    if request in self.http_archive:
-      logging.debug('Repeated request found: %s', request)
-      response = self.http_archive[request]
-    else:
-      response = self.real_http_fetch(request)
-      if response is None:
-        return None
-      self.http_archive[request] = response
-    if self.injector:
-      response = _InjectScripts(response, self.injector)
-    logging.debug('Recorded: %s', request)
-    return response
-
-
-class ReplayHttpArchiveFetch(object):
-  """Serve responses from the given HttpArchive."""
-
-  def __init__(self, http_archive, real_dns_lookup, injector,
-               use_diff_on_unknown_requests=False,
-               use_closest_match=False, scramble_images=False):
-    """Initialize ReplayHttpArchiveFetch.
-
-    Args:
-      http_archive: an instance of a HttpArchive
-      real_dns_lookup: a function that resolves a host to an IP.
-      injector: script injector to inject scripts in all pages
-      use_diff_on_unknown_requests: If True, log unknown requests
-        with a diff to requests that look similar.
-      use_closest_match: If True, on replay mode, serve the closest match
-        in the archive instead of giving a 404.
-    """
-    self.http_archive = http_archive
-    self.injector = injector
-    self.use_diff_on_unknown_requests = use_diff_on_unknown_requests
-    self.use_closest_match = use_closest_match
-    self.scramble_images = scramble_images
-    self.real_http_fetch = RealHttpFetch(real_dns_lookup)
-
-  def __call__(self, request):
-    """Fetch the request and return the response.
-
-    Args:
-      request: an instance of an ArchivedHttpRequest.
-    Returns:
-      Instance of ArchivedHttpResponse (if found) or None
-    """
-    if request.host.startswith('127.0.0.1:'):
-      return self.real_http_fetch(request)
-
-    response = self.http_archive.get(request)
-
-    if self.use_closest_match and not response:
-      closest_request = self.http_archive.find_closest_request(
-          request, use_path=True)
-      if closest_request:
-        response = self.http_archive.get(closest_request)
-        if response:
-          logging.info('Request not found: %s\nUsing closest match: %s',
-                       request, closest_request)
-
-    if not response:
-      reason = str(request)
-      if self.use_diff_on_unknown_requests:
-        diff = self.http_archive.diff(request)
-        if diff:
-          reason += (
-              "\nNearest request diff "
-              "('-' for archived request, '+' for current request):\n%s" % diff)
-      logging.warning('Could not replay: %s', reason)
-    else:
-      if self.injector:
-        response = _InjectScripts(response, self.injector)
-      if self.scramble_images:
-        response = _ScrambleImages(response)
-    return response
-
-
-class ControllableHttpArchiveFetch(object):
-  """Controllable fetch function that can swap between record and replay."""
-
-  def __init__(self, http_archive, real_dns_lookup,
-               injector, use_diff_on_unknown_requests,
-               use_record_mode, use_closest_match, scramble_images):
-    """Initialize HttpArchiveFetch.
-
-    Args:
-      http_archive: an instance of a HttpArchive
-      real_dns_lookup: a function that resolves a host to an IP.
-      injector: function to inject scripts in all pages.
-        takes recording time as datetime.datetime object.
-      use_diff_on_unknown_requests: If True, log unknown requests
-        with a diff to requests that look similar.
-      use_record_mode: If True, start in server in record mode.
-      use_closest_match: If True, on replay mode, serve the closest match
-        in the archive instead of giving a 404.
-    """
-    self.http_archive = http_archive
-    self.record_fetch = RecordHttpArchiveFetch(http_archive, injector)
-    self.replay_fetch = ReplayHttpArchiveFetch(
-        http_archive, real_dns_lookup, injector,
-        use_diff_on_unknown_requests, use_closest_match, scramble_images)
-    if use_record_mode:
-      self.SetRecordMode()
-    else:
-      self.SetReplayMode()
-
-  def SetRecordMode(self):
-    self.fetch = self.record_fetch
-    self.is_record_mode = True
-
-  def SetReplayMode(self):
-    self.fetch = self.replay_fetch
-    self.is_record_mode = False
-
-  def __call__(self, *args, **kwargs):
-    """Forward calls to Replay/Record fetch functions depending on mode."""
-    return self.fetch(*args, **kwargs)
diff --git a/catapult/telemetry/third_party/web-page-replay/httpclient_test.py b/catapult/telemetry/third_party/web-page-replay/httpclient_test.py
deleted file mode 100644
index 709ce47..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httpclient_test.py
+++ /dev/null
@@ -1,284 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import mock
-import unittest
-
-import datetime
-import dnsproxy
-import httparchive
-import httpclient
-import platformsettings
-import script_injector
-import test_utils
-
-
-class RealHttpFetchTest(unittest.TestCase):
-
-  # Initialize test data
-  CONTENT_TYPE = 'content-type: image/x-icon'
-  COOKIE_1 = ('Set-Cookie: GMAIL_IMP=EXPIRED; '
-              'Expires=Thu, 12-Jul-2012 22:41:22 GMT; '
-              'Path=/mail; Secure')
-  COOKIE_2 = ('Set-Cookie: GMAIL_STAT_205a=EXPIRED; '
-              'Expires=Thu, 12-Jul-2012 22:42:24 GMT; '
-              'Path=/mail; Secure')
-  FIRST_LINE = 'fake-header: first line'
-  SECOND_LINE = ' second line'
-  THIRD_LINE = '\tthird line'
-  BAD_HEADER = 'this is a bad header'
-
-  def test__GetHeaderNameValueBasic(self):
-    """Test _GetHeaderNameValue with normal header."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    name_value = real_http_fetch._GetHeaderNameValue(self.CONTENT_TYPE)
-    self.assertEqual(name_value, ('content-type', 'image/x-icon'))
-
-  def test__GetHeaderNameValueLowercasesName(self):
-    """_GetHeaderNameValue lowercases header name."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    header = 'X-Google-Gfe-Backend-Request-Info: eid=1KMAUMeiK4eMiAL52YyMBg'
-    expected = ('x-google-gfe-backend-request-info',
-                'eid=1KMAUMeiK4eMiAL52YyMBg')
-    name_value = real_http_fetch._GetHeaderNameValue(header)
-    self.assertEqual(name_value, expected)
-
-  def test__GetHeaderNameValueBadLineGivesNone(self):
-    """_GetHeaderNameValue returns None for a header in wrong format."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    name_value = real_http_fetch._GetHeaderNameValue(self.BAD_HEADER)
-    self.assertIsNone(name_value)
-
-  def test__ToTuplesBasic(self):
-    """Test _ToTuples with normal input."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    headers = [self.CONTENT_TYPE, self.COOKIE_1, self.FIRST_LINE]
-    result = real_http_fetch._ToTuples(headers)
-    expected = [('content-type', 'image/x-icon'),
-                ('set-cookie', self.COOKIE_1[12:]),
-                ('fake-header', 'first line')]
-    self.assertEqual(result, expected)
-
-  def test__ToTuplesMultipleHeadersWithSameName(self):
-    """Test mulitple headers with the same name."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    headers = [self.CONTENT_TYPE, self.COOKIE_1, self.COOKIE_2, self.FIRST_LINE]
-    result = real_http_fetch._ToTuples(headers)
-    expected = [('content-type', 'image/x-icon'),
-                ('set-cookie', self.COOKIE_1[12:]),
-                ('set-cookie', self.COOKIE_2[12:]),
-                ('fake-header', 'first line')]
-    self.assertEqual(result, expected)
-
-  def test__ToTuplesAppendsContinuationLine(self):
-    """Test continuation line is handled."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    headers = [self.CONTENT_TYPE, self.COOKIE_1, self.FIRST_LINE,
-               self.SECOND_LINE, self.THIRD_LINE]
-    result = real_http_fetch._ToTuples(headers)
-    expected = [('content-type', 'image/x-icon'),
-                ('set-cookie', self.COOKIE_1[12:]),
-                ('fake-header', 'first line\n second line\n third line')]
-    self.assertEqual(result, expected)
-
-  def test__ToTuplesIgnoresBadHeader(self):
-    """Test bad header is ignored."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    bad_headers = [self.CONTENT_TYPE, self.BAD_HEADER, self.COOKIE_1]
-    expected = [('content-type', 'image/x-icon'),
-                ('set-cookie', self.COOKIE_1[12:])]
-    result = real_http_fetch._ToTuples(bad_headers)
-    self.assertEqual(result, expected)
-
-  def test__ToTuplesIgnoresMisplacedContinuationLine(self):
-    """Test misplaced continuation line is ignored."""
-
-    real_http_fetch = httpclient.RealHttpFetch
-    misplaced_headers = [self.THIRD_LINE, self.CONTENT_TYPE,
-                         self.COOKIE_1, self.FIRST_LINE, self.SECOND_LINE]
-    result = real_http_fetch._ToTuples(misplaced_headers)
-    expected = [('content-type', 'image/x-icon'),
-                ('set-cookie', self.COOKIE_1[12:]),
-                ('fake-header', 'first line\n second line')]
-    self.assertEqual(result, expected)
-
-
-class RealHttpFetchGetConnectionTest(unittest.TestCase):
-  """Test that a connection is made with request IP/port or proxy IP/port."""
-
-  def setUp(self):
-    def real_dns_lookup(host):
-      return {
-          'example.com': '127.127.127.127',
-          'proxy.com': '2.2.2.2',
-          }[host]
-    self.fetch = httpclient.RealHttpFetch(real_dns_lookup)
-    self.https_proxy = None
-    self.http_proxy = None
-    def get_proxy(is_ssl):
-      return self.https_proxy if is_ssl else self.http_proxy
-    self.fetch._get_system_proxy = get_proxy
-
-  def set_http_proxy(self, host, port):
-    self.http_proxy = platformsettings.SystemProxy(host, port)
-
-  def set_https_proxy(self, host, port):
-    self.https_proxy = platformsettings.SystemProxy(host, port)
-
-  def test_get_connection_without_proxy_connects_to_host_ip(self):
-    """HTTP connection with no proxy connects to host IP."""
-    self.set_http_proxy(host=None, port=None)
-    connection = self.fetch._get_connection('example.com', None, is_ssl=False)
-    self.assertEqual('127.127.127.127', connection.host)
-    self.assertEqual(80, connection.port)  # default HTTP port
-
-  def test_get_connection_without_proxy_uses_nondefault_request_port(self):
-    """HTTP connection with no proxy connects with request port."""
-    self.set_https_proxy(host=None, port=None)
-    connection = self.fetch._get_connection('example.com', 8888, is_ssl=False)
-    self.assertEqual('127.127.127.127', connection.host)
-    self.assertEqual(8888, connection.port)  # request HTTP port
-
-  def test_get_connection_with_proxy_uses_proxy_port(self):
-    """HTTP connection with proxy connects used proxy port."""
-    self.set_http_proxy(host='proxy.com', port=None)
-    connection = self.fetch._get_connection('example.com', 8888, is_ssl=False)
-    self.assertEqual('2.2.2.2', connection.host)  # proxy IP
-    self.assertEqual(80, connection.port)  # proxy port (default HTTP)
-
-  def test_ssl_get_connection_without_proxy_connects_to_host_ip(self):
-    """HTTPS (SSL) connection with no proxy connects to host IP."""
-    self.set_https_proxy(host=None, port=None)
-    connection = self.fetch._get_connection('example.com', None, is_ssl=True)
-    self.assertEqual('127.127.127.127', connection.host)
-    self.assertEqual(443, connection.port)  # default SSL port
-
-  def test_ssl_get_connection_with_proxy_connects_to_proxy_ip(self):
-    """HTTPS (SSL) connection with proxy connects to proxy IP."""
-    self.set_https_proxy(host='proxy.com', port=8443)
-    connection = self.fetch._get_connection('example.com', None, is_ssl=True)
-    self.assertEqual('2.2.2.2', connection.host)  # proxy IP
-    self.assertEqual(8443, connection.port)  # SSL proxy port
-
-  def test_ssl_get_connection_with_proxy_tunnels_to_host(self):
-    """HTTPS (SSL) connection with proxy tunnels to target host."""
-    self.set_https_proxy(host='proxy.com', port=8443)
-    connection = self.fetch._get_connection('example.com', 9443, is_ssl=True)
-    self.assertEqual('example.com', connection._tunnel_host)  # host name
-    self.assertEqual(9443, connection._tunnel_port)  # host port
-
-
-class ActualNetworkFetchTest(test_utils.RealNetworkFetchTest):
-
-  def testFetchNonSSLRequest(self):
-    real_dns_lookup = dnsproxy.RealDnsLookup(
-        name_servers=[platformsettings.get_original_primary_nameserver()],
-        dns_forwarding=False, proxy_host='127.0.0.1', proxy_port=5353)
-    fetch = httpclient.RealHttpFetch(real_dns_lookup)
-    request = httparchive.ArchivedHttpRequest(
-        command='GET', host='google.com', full_path='/search?q=dogs',
-        request_body=None, headers={}, is_ssl=False)
-    response = fetch(request)
-    self.assertIsNotNone(response)
-
-  def testFetchSSLRequest(self):
-    real_dns_lookup = dnsproxy.RealDnsLookup(
-        name_servers=[platformsettings.get_original_primary_nameserver()],
-        dns_forwarding=False, proxy_host='127.0.0.1', proxy_port=5353)
-    fetch = httpclient.RealHttpFetch(real_dns_lookup)
-    request = httparchive.ArchivedHttpRequest(
-        command='GET', host='google.com', full_path='/search?q=dogs',
-        request_body=None, headers={}, is_ssl=True)
-    response = fetch(request)
-    self.assertIsNotNone(response)
-
-
-class HttpArchiveFetchTest(unittest.TestCase):
-
-  TEST_REQUEST_TIME = datetime.datetime(2016, 11, 17, 1, 2, 3, 456)
-
-  def createTestResponse(self):
-    return httparchive.ArchivedHttpResponse(
-        11, 200, 'OK', [('content-type', 'text/html')],
-        ['<body>test</body>'],
-        request_time=HttpArchiveFetchTest.TEST_REQUEST_TIME)
-
-  def checkTestResponse(self, actual_response, archive, request):
-    self.assertEqual(actual_response, archive[request])
-    self.assertEqual(['<body>test</body>'], actual_response.response_data)
-    self.assertEqual(HttpArchiveFetchTest.TEST_REQUEST_TIME,
-                     actual_response.request_time)
-
-  @staticmethod
-  def dummy_injector(_):
-    return '<body>test</body>'
-
-
-class RecordHttpArchiveFetchTest(HttpArchiveFetchTest):
-
-  @mock.patch('httpclient.RealHttpFetch')
-  def testFetch(self, real_http_fetch):
-    http_fetch_instance = real_http_fetch.return_value
-    response = self.createTestResponse()
-    http_fetch_instance.return_value = response
-    archive = httparchive.HttpArchive()
-    fetch = httpclient.RecordHttpArchiveFetch(archive, self.dummy_injector)
-    request = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/', None, {})
-    self.checkTestResponse(fetch(request), archive, request)
-
-
-class ReplayHttpArchiveFetchTest(HttpArchiveFetchTest):
-
-  def testFetch(self):
-    request = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/', None, {})
-    response = self.createTestResponse()
-    archive = httparchive.HttpArchive()
-    archive[request] = response
-    fetch = httpclient.ReplayHttpArchiveFetch(
-        archive, None, self.dummy_injector)
-    self.checkTestResponse(fetch(request), archive, request)
-
-  @mock.patch('script_injector.util.resource_string')
-  @mock.patch('script_injector.util.resource_exists')
-  @mock.patch('script_injector.os.path.exists')
-  def testInjectedDate(self, os_path, util_exists, util_resource_string):
-    os_path.return_value = False
-    util_exists.return_value = True
-    util_resource_string.return_value = \
-        ["""var time_seed={}""".format(script_injector.TIME_SEED_MARKER)]
-    request = httparchive.ArchivedHttpRequest(
-        'GET', 'www.test.com', '/', None, {})
-    response = self.createTestResponse()
-    archive = httparchive.HttpArchive()
-    archive[request] = response
-
-    fetch = httpclient.ReplayHttpArchiveFetch(
-        archive, None, script_injector.GetScriptInjector("time_script.js"))
-    self.assertEqual(
-        ['<script>var time_seed=1479344523000</script><body>test</body>'],
-        fetch(request).response_data)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/httpproxy.py b/catapult/telemetry/third_party/web-page-replay/httpproxy.py
deleted file mode 100644
index 9a69aa9..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httpproxy.py
+++ /dev/null
@@ -1,446 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import BaseHTTPServer
-import certutils
-import collections
-import errno
-import logging
-import socket
-import SocketServer
-import ssl
-import sys
-import time
-import urlparse
-
-import daemonserver
-import httparchive
-import platformsettings
-import proxyshaper
-import sslproxy
-
-def _HandleSSLCertificateError():
-  """
-  This method is intended to be called from
-  BaseHTTPServer.HTTPServer.handle_error().
-  """
-  exc_type, exc_value, exc_traceback = sys.exc_info()
-  if isinstance(exc_value, ssl.SSLError):
-    return
-
-  raise
-
-
-class HttpProxyError(Exception):
-  """Module catch-all error."""
-  pass
-
-
-class HttpProxyServerError(HttpProxyError):
-  """Raised for errors like 'Address already in use'."""
-  pass
-
-
-class HttpArchiveHandler(BaseHTTPServer.BaseHTTPRequestHandler):
-  protocol_version = 'HTTP/1.1'  # override BaseHTTPServer setting
-
-  # Since we do lots of small wfile.write() calls, turn on buffering.
-  wbufsize = -1  # override StreamRequestHandler (a base class) setting
-
-  def setup(self):
-    """Override StreamRequestHandler method."""
-    BaseHTTPServer.BaseHTTPRequestHandler.setup(self)
-    if self.server.traffic_shaping_up_bps:
-      self.rfile = proxyshaper.RateLimitedFile(
-          self.server.get_active_request_count, self.rfile,
-          self.server.traffic_shaping_up_bps)
-    if self.server.traffic_shaping_down_bps:
-      self.wfile = proxyshaper.RateLimitedFile(
-          self.server.get_active_request_count, self.wfile,
-          self.server.traffic_shaping_down_bps)
-
-  # Make request handler logging match our logging format.
-  def log_request(self, code='-', size='-'):
-    pass
-
-  def log_error(self, format, *args):  # pylint:disable=redefined-builtin
-    logging.error(format, *args)
-
-  def log_message(self, format, *args):  # pylint:disable=redefined-builtin
-    logging.info(format, *args)
-
-  def read_request_body(self):
-    request_body = None
-    length = int(self.headers.get('content-length', 0)) or None
-    if length:
-      request_body = self.rfile.read(length)
-    return request_body
-
-  def get_header_dict(self):
-    return dict(self.headers.items())
-
-  def get_archived_http_request(self):
-    host = self.headers.get('host')
-    if host is None:
-      logging.error('Request without host header')
-      return None
-
-    parsed = urlparse.urlparse(self.path)
-    params = ';%s' % parsed.params if parsed.params else ''
-    query = '?%s' % parsed.query if parsed.query else ''
-    fragment = '#%s' % parsed.fragment if parsed.fragment else ''
-    full_path = '%s%s%s%s' % (parsed.path, params, query, fragment)
-
-    StubRequest = collections.namedtuple('StubRequest', ('host', 'full_path'))
-    request, response = StubRequest(host, full_path), None
-
-    self.server.log_url(request, response)
-
-    return httparchive.ArchivedHttpRequest(
-        self.command,
-        host,
-        full_path,
-        self.read_request_body(),
-        self.get_header_dict(),
-        self.server.is_ssl)
-
-  def send_archived_http_response(self, response):
-    try:
-      # We need to set the server name before we start the response.
-      is_chunked = response.is_chunked()
-      has_content_length = response.get_header('content-length') is not None
-      self.server_version = response.get_header('server', 'WebPageReplay')
-      self.sys_version = ''
-
-      if response.version == 10:
-        self.protocol_version = 'HTTP/1.0'
-
-      # If we don't have chunked encoding and there is no content length,
-      # we need to manually compute the content-length.
-      if not is_chunked and not has_content_length:
-        content_length = sum(len(c) for c in response.response_data)
-        response.headers.append(('content-length', str(content_length)))
-
-      is_replay = not self.server.http_archive_fetch.is_record_mode
-      if is_replay and self.server.traffic_shaping_delay_ms:
-        logging.debug('Using round trip delay: %sms',
-                      self.server.traffic_shaping_delay_ms)
-        time.sleep(self.server.traffic_shaping_delay_ms / 1000.0)
-      if is_replay and self.server.use_delays:
-        logging.debug('Using delays (ms): %s', response.delays)
-        time.sleep(response.delays['headers'] / 1000.0)
-        delays = response.delays['data']
-      else:
-        delays = [0] * len(response.response_data)
-      self.send_response(response.status, response.reason)
-      # TODO(mbelshe): This is lame - each write is a packet!
-      for header, value in response.headers:
-        if header in ('last-modified', 'expires'):
-          self.send_header(header, response.update_date(value))
-        elif header not in ('date', 'server'):
-          self.send_header(header, value)
-      self.end_headers()
-
-      for chunk, delay in zip(response.response_data, delays):
-        if delay:
-          self.wfile.flush()
-          time.sleep(delay / 1000.0)
-        if is_chunked:
-          # Write chunk length (hex) and data (e.g. "A\r\nTESSELATED\r\n").
-          self.wfile.write('%x\r\n%s\r\n' % (len(chunk), chunk))
-        else:
-          self.wfile.write(chunk)
-      if is_chunked:
-        self.wfile.write('0\r\n\r\n')  # write final, zero-length chunk.
-      self.wfile.flush()
-
-      # TODO(mbelshe): This connection close doesn't seem to work.
-      if response.version == 10:
-        self.close_connection = 1
-
-    except Exception, e:
-      logging.error('Error sending response for %s%s: %s',
-                    self.headers['host'], self.path, e)
-
-  def handle_one_request(self):
-    """Handle a single HTTP request.
-
-    This method overrides a method from BaseHTTPRequestHandler. When this
-    method returns, it must leave self.close_connection in the correct state.
-    If this method raises an exception, the state of self.close_connection
-    doesn't matter.
-    """
-    try:
-      self.raw_requestline = self.rfile.readline(65537)
-      self.do_parse_and_handle_one_request()
-    except socket.timeout, e:
-      # A read or a write timed out.  Discard this connection
-      self.log_error('Request timed out: %r', e)
-      self.close_connection = 1
-      return
-    except ssl.SSLError:
-      # There is insufficient information passed up the stack from OpenSSL to
-      # determine the true cause of the SSL error. This almost always happens
-      # because the client refuses to accept the self-signed certs of
-      # WebPageReplay.
-      self.close_connection = 1
-      return
-    except socket.error, e:
-      # Connection reset errors happen all the time due to the browser closing
-      # without terminating the connection properly.  They can be safely
-      # ignored.
-      if e[0] == errno.ECONNRESET:
-        self.close_connection = 1
-        return
-      raise
-
-
-  def do_parse_and_handle_one_request(self):
-    start_time = time.time()
-    self.server.num_active_requests += 1
-    request = None
-    try:
-      if len(self.raw_requestline) > 65536:
-        self.requestline = ''
-        self.request_version = ''
-        self.command = ''
-        self.send_error(414)
-        self.close_connection = 0
-        return
-      if not self.raw_requestline:
-        # This indicates that the socket has been closed by the client.
-        self.close_connection = 1
-        return
-
-      # self.parse_request() sets self.close_connection. There is no need to
-      # set the property after the method is executed, unless custom behavior
-      # is desired.
-      if not self.parse_request():
-        # An error code has been sent, just exit.
-        return
-
-      try:
-        response = None
-        request = self.get_archived_http_request()
-
-        if request is None:
-          self.send_error(500)
-          return
-        response = self.server.custom_handlers.handle(request)
-        if not response:
-          response = self.server.http_archive_fetch(request)
-          if (response and response.status == 200 and
-              self.server.allow_generate_304 and
-              request.command in set(['GET', 'HEAD']) and
-              (request.headers.get('if-modified-since', None) or
-               request.headers.get('if-none-match', None))):
-            # The WPR archive never get modified since it is not being recorded.
-            response = httparchive.create_response(
-                status=304, headers=response.headers)
-        if response:
-          self.send_archived_http_response(response)
-        else:
-          self.send_error(404)
-      finally:
-        self.wfile.flush()  # Actually send the response if not already done.
-    finally:
-      request_time_ms = (time.time() - start_time) * 1000.0
-      self.server.total_request_time += request_time_ms
-      if request:
-        if response:
-          logging.debug('Served: %s (%dms)', request, request_time_ms)
-        else:
-          logging.warning('Failed to find response for: %s (%dms)',
-                          request, request_time_ms)
-      self.server.num_active_requests -= 1
-
-  def send_error(self, status, body=None):
-    """Override the default send error with a version that doesn't unnecessarily
-    close the connection.
-    """
-    response = httparchive.create_response(status, body=body)
-    self.send_archived_http_response(response)
-
-
-class HttpProxyServer(SocketServer.ThreadingMixIn,
-                      BaseHTTPServer.HTTPServer,
-                      daemonserver.DaemonServer):
-  HANDLER = HttpArchiveHandler
-
-  # Increase the request queue size. The default value, 5, is set in
-  # SocketServer.TCPServer (the parent of BaseHTTPServer.HTTPServer).
-  # Since we're intercepting many domains through this single server,
-  # it is quite possible to get more than 5 concurrent requests.
-  request_queue_size = 256
-
-  # The number of simultaneous connections that the HTTP server supports. This
-  # is primarily limited by system limits such as RLIMIT_NOFILE.
-  connection_limit = 500
-
-  # Allow sockets to be reused. See
-  # http://svn.python.org/projects/python/trunk/Lib/SocketServer.py for more
-  # details.
-  allow_reuse_address = True
-
-  # Don't prevent python from exiting when there is thread activity.
-  daemon_threads = True
-
-  def __init__(self, http_archive_fetch, custom_handlers, rules,
-               host='localhost', port=80, use_delays=False, is_ssl=False,
-               protocol='HTTP', allow_generate_304=False,
-               down_bandwidth='0', up_bandwidth='0', delay_ms='0'):
-    """Start HTTP server.
-
-    Args:
-      rules: a rule_parser Rules.
-      host: a host string (name or IP) for the web proxy.
-      port: a port string (e.g. '80') for the web proxy.
-      use_delays: if True, add response data delays during replay.
-      is_ssl: True iff proxy is using SSL.
-      up_bandwidth: Upload bandwidth
-      down_bandwidth: Download bandwidth
-           Bandwidths measured in [K|M]{bit/s|Byte/s}. '0' means unlimited.
-      delay_ms: Propagation delay in milliseconds. '0' means no delay.
-    """
-    if platformsettings.SupportsFdLimitControl():
-      # BaseHTTPServer opens a new thread and two fds for each connection.
-      # Check that the process can open at least 1000 fds.
-      soft_limit, hard_limit = platformsettings.GetFdLimit()
-      # Add some wiggle room since there are probably fds not associated with
-      # connections.
-      wiggle_room = 100
-      desired_limit = 2 * HttpProxyServer.connection_limit + wiggle_room
-      if soft_limit < desired_limit:
-        assert desired_limit <= hard_limit, (
-            'The hard limit for number of open files per process is %s which '
-            'is lower than the desired limit of %s.' %
-            (hard_limit, desired_limit))
-        platformsettings.AdjustFdLimit(desired_limit, hard_limit)
-
-    try:
-      BaseHTTPServer.HTTPServer.__init__(self, (host, port), self.HANDLER)
-    except Exception, e:
-      raise HttpProxyServerError('Could not start HTTPServer on port %d: %s' %
-                                 (port, e))
-    self.http_archive_fetch = http_archive_fetch
-    self.custom_handlers = custom_handlers
-    self.use_delays = use_delays
-    self.is_ssl = is_ssl
-    self.traffic_shaping_down_bps = proxyshaper.GetBitsPerSecond(down_bandwidth)
-    self.traffic_shaping_up_bps = proxyshaper.GetBitsPerSecond(up_bandwidth)
-    self.traffic_shaping_delay_ms = int(delay_ms)
-    self.num_active_requests = 0
-    self.num_active_connections = 0
-    self.total_request_time = 0
-    self.protocol = protocol
-    self.allow_generate_304 = allow_generate_304
-    self.log_url = rules.Find('log_url')
-
-    # Note: This message may be scraped. Do not change it.
-    logging.warning(
-        '%s server started on %s:%d' % (self.protocol, self.server_address[0],
-                                        self.server_address[1]))
-
-  def cleanup(self):
-    try:
-      self.shutdown()
-      self.server_close()
-    except KeyboardInterrupt:
-      pass
-    logging.info('Stopped %s server. Total time processing requests: %dms',
-                 self.protocol, self.total_request_time)
-
-  def get_active_request_count(self):
-    return self.num_active_requests
-
-  def get_request(self):
-    self.num_active_connections += 1
-    if self.num_active_connections >= HttpProxyServer.connection_limit:
-      logging.error(
-          'Number of active connections (%s) surpasses the '
-          'supported limit of %s.' %
-          (self.num_active_connections, HttpProxyServer.connection_limit))
-    return BaseHTTPServer.HTTPServer.get_request(self)
-
-  def close_request(self, request):
-    BaseHTTPServer.HTTPServer.close_request(self, request)
-    self.num_active_connections -= 1
-
-
-class HttpsProxyServer(HttpProxyServer):
-  """SSL server that generates certs for each host."""
-
-  def __init__(self, http_archive_fetch, custom_handlers, rules,
-               https_root_ca_cert_path, **kwargs):
-    self.ca_cert_path = https_root_ca_cert_path
-    self.HANDLER = sslproxy.wrap_handler(HttpArchiveHandler)
-    HttpProxyServer.__init__(self, http_archive_fetch, custom_handlers, rules,
-                             is_ssl=True, protocol='HTTPS', **kwargs)
-    with open(self.ca_cert_path, 'r') as cert_file:
-      self._ca_cert_str = cert_file.read()
-    self._host_to_cert_map = {}
-    self._server_cert_to_cert_map = {}
-
-  def cleanup(self):
-    try:
-      self.shutdown()
-      self.server_close()
-    except KeyboardInterrupt:
-      pass
-
-  def get_certificate(self, host):
-    if host in self._host_to_cert_map:
-      return self._host_to_cert_map[host]
-
-    server_cert = self.http_archive_fetch.http_archive.get_server_cert(host)
-    if server_cert in self._server_cert_to_cert_map:
-      cert = self._server_cert_to_cert_map[server_cert]
-      self._host_to_cert_map[host] = cert
-      return cert
-
-    cert = certutils.generate_cert(self._ca_cert_str, server_cert, host)
-    self._server_cert_to_cert_map[server_cert] = cert
-    self._host_to_cert_map[host] = cert
-    return cert
-
-  def handle_error(self, request, client_address):
-    _HandleSSLCertificateError()
-
-
-class SingleCertHttpsProxyServer(HttpProxyServer):
-  """SSL server."""
-
-  def __init__(self, http_archive_fetch, custom_handlers, rules,
-               https_root_ca_cert_path, **kwargs):
-    HttpProxyServer.__init__(self, http_archive_fetch, custom_handlers, rules,
-                             is_ssl=True, protocol='HTTPS', **kwargs)
-    self.socket = ssl.wrap_socket(
-        self.socket, certfile=https_root_ca_cert_path, server_side=True,
-        do_handshake_on_connect=False)
-    # Ancestor class, DaemonServer, calls serve_forever() during its __init__.
-
-  def handle_error(self, request, client_address):
-    _HandleSSLCertificateError()
-
-
-class HttpToHttpsProxyServer(HttpProxyServer):
-  """Listens for HTTP requests but sends them to the target as HTTPS requests"""
-
-  def __init__(self, http_archive_fetch, custom_handlers, rules, **kwargs):
-    HttpProxyServer.__init__(self, http_archive_fetch, custom_handlers, rules,
-                             is_ssl=True, protocol='HTTP-to-HTTPS', **kwargs)
-
-  def handle_error(self, request, client_address):
-    _HandleSSLCertificateError()
diff --git a/catapult/telemetry/third_party/web-page-replay/httpproxy_test.py b/catapult/telemetry/third_party/web-page-replay/httpproxy_test.py
deleted file mode 100644
index ff34180..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httpproxy_test.py
+++ /dev/null
@@ -1,243 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import httparchive
-import httplib
-import httpproxy
-import threading
-import unittest
-import util
-
-
-class MockCustomResponseHandler(object):
-  def __init__(self, response):
-    """
-    Args:
-      response: An instance of ArchivedHttpResponse that is returned for each
-      request.
-    """
-    self._response = response
-
-  def handle(self, request):
-    del request
-    return self._response
-
-
-class MockHttpArchiveFetch(object):
-  def __init__(self, response):
-    """
-    Args:
-      response: An instance of ArchivedHttpResponse that is returned for each
-      request.
-    """
-    self.is_record_mode = False
-    self._response = response
-
-  def __call__(self, request):
-    del request # unused
-    return self._response
-
-
-class MockHttpArchiveHandler(httpproxy.HttpArchiveHandler):
-  def handle_one_request(self):
-    httpproxy.HttpArchiveHandler.handle_one_request(self)
-    HttpProxyTest.HANDLED_REQUEST_COUNT += 1
-
-
-class MockRules(object):
-  def Find(self, unused_rule_type_name):  # pylint: disable=unused-argument
-    return lambda unused_request, unused_response: None
-
-
-class HttpProxyTest(unittest.TestCase):
-  def setUp(self):
-    self.has_proxy_server_bound_port = False
-    self.has_proxy_server_started = False
-    self.allow_generate_304 = False
-    self.serve_response_by_http_archive = False
-
-  def set_up_proxy_server(self, response):
-    """
-    Args:
-      response: An instance of ArchivedHttpResponse that is returned for each
-      request.
-    """
-    HttpProxyTest.HANDLED_REQUEST_COUNT = 0
-    self.host = 'localhost'
-    self.port = 8889
-    custom_handlers = MockCustomResponseHandler(
-        response if not self.serve_response_by_http_archive else None)
-    rules = MockRules()
-    http_archive_fetch = MockHttpArchiveFetch(
-        response if self.serve_response_by_http_archive else None)
-    self.proxy_server = httpproxy.HttpProxyServer(
-        http_archive_fetch, custom_handlers, rules,
-        host=self.host, port=self.port,
-        allow_generate_304=self.allow_generate_304)
-    self.proxy_server.RequestHandlerClass = MockHttpArchiveHandler
-    self.has_proxy_server_bound_port = True
-
-  def tear_down_proxy_server(self):
-    if self.has_proxy_server_started:
-      self.proxy_server.shutdown()
-    if self.has_proxy_server_bound_port:
-      self.proxy_server.server_close()
-
-  def tearDown(self):
-    self.tear_down_proxy_server()
-
-  def serve_requests_forever(self):
-    self.has_proxy_server_started = True
-    self.proxy_server.serve_forever(poll_interval=0.01)
-
-  # Tests that handle_one_request does not leak threads, and does not try to
-  # re-handle connections that are finished.
-  def test_handle_one_request_closes_connection(self):
-    # By default, BaseHTTPServer.py treats all HTTP 1.1 requests as keep-alive.
-    # Intentionally use HTTP 1.0 to prevent this behavior.
-    response = httparchive.ArchivedHttpResponse(
-        version=10, status=200, reason="OK",
-        headers=[], response_data=["bat1"])
-    self.set_up_proxy_server(response)
-    t = threading.Thread(
-        target=HttpProxyTest.serve_requests_forever, args=(self,))
-    t.start()
-
-    initial_thread_count = threading.activeCount()
-
-    # Make a bunch of requests.
-    request_count = 10
-    for _ in range(request_count):
-      conn = httplib.HTTPConnection('localhost', 8889, timeout=10)
-      conn.request("GET", "/index.html")
-      res = conn.getresponse().read()
-      self.assertEqual(res, "bat1")
-      conn.close()
-
-    # Check to make sure that there is no leaked thread.
-    util.WaitFor(lambda: threading.activeCount() == initial_thread_count, 2)
-
-    self.assertEqual(request_count, HttpProxyTest.HANDLED_REQUEST_COUNT)
-
-
-  # Tests that keep-alive header works.
-  def test_keep_alive_header(self):
-    response = httparchive.ArchivedHttpResponse(
-        version=11, status=200, reason="OK",
-        headers=[("Connection", "keep-alive")], response_data=["bat1"])
-    self.set_up_proxy_server(response)
-    t = threading.Thread(
-        target=HttpProxyTest.serve_requests_forever, args=(self,))
-    t.start()
-
-    initial_thread_count = threading.activeCount()
-
-    # Make a bunch of requests.
-    request_count = 10
-    connections = []
-    for _ in range(request_count):
-      conn = httplib.HTTPConnection('localhost', 8889, timeout=10)
-      conn.request("GET", "/index.html", headers={"Connection": "keep-alive"})
-      res = conn.getresponse().read()
-      self.assertEqual(res, "bat1")
-      connections.append(conn)
-
-    # Repeat the same requests.
-    for conn in connections:
-      conn.request("GET", "/index.html", headers={"Connection": "keep-alive"})
-      res = conn.getresponse().read()
-      self.assertEqual(res, "bat1")
-
-    # Check that the right number of requests have been handled.
-    self.assertEqual(2 * request_count, HttpProxyTest.HANDLED_REQUEST_COUNT)
-
-    # Check to make sure that exactly "request_count" new threads are active.
-    self.assertEqual(
-        threading.activeCount(), initial_thread_count + request_count)
-
-    for conn in connections:
-      conn.close()
-
-    util.WaitFor(lambda: threading.activeCount() == initial_thread_count, 1)
-
-  # Test that opening 400 simultaneous connections does not cause httpproxy to
-  # hit a process fd limit. The default limit is 256 fds.
-  def test_max_fd(self):
-    response = httparchive.ArchivedHttpResponse(
-        version=11, status=200, reason="OK",
-        headers=[("Connection", "keep-alive")], response_data=["bat1"])
-    self.set_up_proxy_server(response)
-    t = threading.Thread(
-        target=HttpProxyTest.serve_requests_forever, args=(self,))
-    t.start()
-
-    # Make a bunch of requests.
-    request_count = 400
-    connections = []
-    for _ in range(request_count):
-      conn = httplib.HTTPConnection('localhost', 8889, timeout=10)
-      conn.request("GET", "/index.html", headers={"Connection": "keep-alive"})
-      res = conn.getresponse().read()
-      self.assertEqual(res, "bat1")
-      connections.append(conn)
-
-    # Check that the right number of requests have been handled.
-    self.assertEqual(request_count, HttpProxyTest.HANDLED_REQUEST_COUNT)
-
-    for conn in connections:
-      conn.close()
-
-  # Tests that conditional requests return 304.
-  def test_generate_304(self):
-    REQUEST_HEADERS = [
-        {},
-        {'If-Modified-Since': 'whatever'},
-        {'If-None-Match': 'whatever yet again'}]
-    RESPONSE_STATUSES = [200, 204, 304, 404]
-    for allow_generate_304 in [False, True]:
-      self.allow_generate_304 = allow_generate_304
-      for serve_response_by_http_archive in [False, True]:
-        self.serve_response_by_http_archive = serve_response_by_http_archive
-        for response_status in RESPONSE_STATUSES:
-          response = None
-          if response_status != 404:
-            response = httparchive.ArchivedHttpResponse(
-                version=11, status=response_status, reason="OK", headers=[],
-                response_data=["some content"])
-          self.set_up_proxy_server(response)
-          t = threading.Thread(
-              target=HttpProxyTest.serve_requests_forever, args=(self,))
-          t.start()
-          for method in ['GET', 'HEAD', 'POST']:
-            for headers in REQUEST_HEADERS:
-              connection = httplib.HTTPConnection('localhost', 8889, timeout=10)
-              connection.request(method, "/index.html", headers=headers)
-              response = connection.getresponse()
-              connection.close()
-              if (allow_generate_304 and
-                  serve_response_by_http_archive and
-                  method in ['GET', 'HEAD'] and
-                  headers and
-                  response_status == 200):
-                self.assertEqual(304, response.status)
-                self.assertEqual('', response.read())
-              else:
-                self.assertEqual(response_status, response.status)
-          self.tear_down_proxy_server()
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/httpzlib.py b/catapult/telemetry/third_party/web-page-replay/httpzlib.py
deleted file mode 100644
index b06cb29..0000000
--- a/catapult/telemetry/third_party/web-page-replay/httpzlib.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2011 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Apply gzip/deflate to separate chunks of data."""
-
-import struct
-import zlib
-
-GZIP_HEADER = (
-    '\037\213'             # magic header
-    '\010'                 # compression method
-    '\000'                 # flags (none)
-    '\000\000\000\000'     # packed time (use zero)
-    '\002'
-    '\377')
-
-
-def compress_chunks(uncompressed_chunks, use_gzip):
-  """Compress a list of data with gzip or deflate.
-
-  The returned chunks may be used with HTTP chunked encoding.
-
-  Args:
-    uncompressed_chunks: a list of strings
-       (e.g. ["this is the first chunk", "and the second"])
-    use_gzip: if True, compress with gzip. Otherwise, use deflate.
-
-  Returns:
-    [compressed_chunk_1, compressed_chunk_2, ...]
-  """
-  if use_gzip:
-    size = 0
-    crc = zlib.crc32("") & 0xffffffffL
-    compressor = zlib.compressobj(
-        6, zlib.DEFLATED, -zlib.MAX_WBITS, zlib.DEF_MEM_LEVEL, 0)
-  else:
-    compressor = zlib.compressobj()
-  compressed_chunks = []
-  last_index = len(uncompressed_chunks) - 1
-  for index, data in enumerate(uncompressed_chunks):
-    chunk = ''
-    if use_gzip:
-      size += len(data)
-      crc = zlib.crc32(data, crc) & 0xffffffffL
-      if index == 0:
-        chunk += GZIP_HEADER
-    chunk += compressor.compress(data)
-    if index < last_index:
-      chunk += compressor.flush(zlib.Z_SYNC_FLUSH)
-    else:
-      chunk += (compressor.flush(zlib.Z_FULL_FLUSH) +
-                compressor.flush())
-      if use_gzip:
-        chunk += (struct.pack("<L", long(crc)) +
-                  struct.pack("<L", long(size)))
-    compressed_chunks.append(chunk)
-  return compressed_chunks
-
-
-def uncompress_chunks(compressed_chunks, use_gzip):
-  """Uncompress a list of data compressed with gzip or deflate.
-
-  Args:
-    compressed_chunks: a list of compressed data
-    use_gzip: if True, uncompress with gzip. Otherwise, use deflate.
-
-  Returns:
-    [uncompressed_chunk_1, uncompressed_chunk_2, ...]
-  """
-  if use_gzip:
-    decompress = zlib.decompressobj(16 + zlib.MAX_WBITS).decompress
-  else:
-    decompress = zlib.decompressobj(-zlib.MAX_WBITS).decompress
-  return [decompress(c) for c in compressed_chunks]
diff --git a/catapult/telemetry/third_party/web-page-replay/mock-archive.txt b/catapult/telemetry/third_party/web-page-replay/mock-archive.txt
deleted file mode 100644
index a90bb03..0000000
--- a/catapult/telemetry/third_party/web-page-replay/mock-archive.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-GET%www.zappos.com%/%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.zappos.com')]
-GET%www.zappos.com%/css/print.20110525145237.css%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.zappos.com')]
-GET%www.zappos.com%/favicon.ico%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.zappos.com')]
-GET%www.zappos.com%/hydra/hydra.p.20110607.js%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.zappos.com')]
-GET%www.zappos.com%/imgs/shadebg.20110525145241.png%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.zappos.com')]
-GET%www.msn.com%/%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.msn.com')]
-GET%www.msn.com%/?euid=&userGroup=W:default&PM=z:1%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.msn.com'), ('x-requested-with', 'XMLHttpRequest')]
-GET%www.msn.com%/?euid=342%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.msn.com'), ('x-requested-with', 'XMLHttpRequest')]
-GET%www.amazon.com%/%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.amazon.com')]
-GET%www.google.com%/%%[('accept-encoding', 'gzip,deflate'), ('host', 'www.google.com')]
diff --git a/catapult/telemetry/third_party/web-page-replay/mockhttprequest.py b/catapult/telemetry/third_party/web-page-replay/mockhttprequest.py
deleted file mode 100644
index ac5df99..0000000
--- a/catapult/telemetry/third_party/web-page-replay/mockhttprequest.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Mock instance of ArchivedHttpRequest used for testing."""
-
-
-class ArchivedHttpRequest(object):
-  """Mock instance of ArchivedHttpRequest in HttpArchive."""
-
-  def __init__(self, command, host, path, request_body, headers):
-    """Initialize an ArchivedHttpRequest.
-
-    Args:
-      command: a string (e.g. 'GET' or 'POST').
-      host: a host name (e.g. 'www.google.com').
-      path: a request path (e.g. '/search?q=dogs').
-      request_body: a request body string for a POST or None.
-      headers: [(header1, value1), ...] list of tuples
-    """
-    self.command = command
-    self.host = host
-    self.path = path
-    self.request_body = request_body
-    self.headers = headers
-    self.trimmed_headers = headers
-
-  def __str__(self):
-    return '%s %s%s %s' % (self.command, self.host, self.path,
-                           self.trimmed_headers)
-
-  def __repr__(self):
-    return repr((self.command, self.host, self.path, self.request_body,
-                 self.trimmed_headers))
-
-  def __hash__(self):
-    """Return a integer hash to use for hashed collections including dict."""
-    return hash(repr(self))
-
-  def __eq__(self, other):
-    """Define the __eq__ method to match the hash behavior."""
-    return repr(self) == repr(other)
-
-  def matches(self, command=None, host=None, path=None):
-    """Returns true iff the request matches all parameters."""
-    return ((command is None or command == self.command) and
-            (host is None or host == self.host) and
-            (path is None or path == self.path))
diff --git a/catapult/telemetry/third_party/web-page-replay/net_configs.py b/catapult/telemetry/third_party/web-page-replay/net_configs.py
deleted file mode 100644
index 644358e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/net_configs.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Defines a list of common network speeds.
-
-These values come from http://www.webpagetest.org/
-
-See:
-https://sites.google.com/a/webpagetest.org/docs/other-resources/2011-fcc-broadband-data
-https://github.com/WPO-Foundation/webpagetest/blob/HEAD/www/settings/connectivity.ini.sample
-"""
-
-import collections
-
-
-NetConfig = collections.namedtuple('NetConfig', ['down', 'up', 'delay_ms'])
-
-
-# pylint: disable=bad-whitespace
-_NET_CONFIGS = {
-    'dialup': NetConfig(down=   '49Kbit/s', up=  '30Kbit/s', delay_ms= '120'),
-    '3g':     NetConfig(down= '1638Kbit/s', up= '768Kbit/s', delay_ms= '150'),
-    'dsl':    NetConfig(down= '1536Kbit/s', up= '384Kbit/s', delay_ms=  '50'),
-    'cable':  NetConfig(down=    '5Mbit/s', up=   '1Mbit/s', delay_ms=  '28'),
-    'fios':   NetConfig(down=   '20Mbit/s', up=   '5Mbit/s', delay_ms=   '4'),
-    }
-
-
-NET_CONFIG_NAMES = _NET_CONFIGS.keys()
-
-
-def GetNetConfig(key):
-  """Returns the NetConfig object corresponding to the given |key|."""
-  if key not in _NET_CONFIGS:
-    raise KeyError('No net config with key: %s' % key)
-  return _NET_CONFIGS[key]
diff --git a/catapult/telemetry/third_party/web-page-replay/platformsettings.py b/catapult/telemetry/third_party/web-page-replay/platformsettings.py
deleted file mode 100644
index 81cb56c..0000000
--- a/catapult/telemetry/third_party/web-page-replay/platformsettings.py
+++ /dev/null
@@ -1,794 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Provides cross-platform utility functions.
-
-Example:
-  import platformsettings
-  ip = platformsettings.get_server_ip_address()
-
-Functions with "_temporary_" in their name automatically clean-up upon
-termination (via the atexit module).
-
-For the full list of functions, see the bottom of the file.
-"""
-
-import atexit
-import distutils.spawn
-import distutils.version
-import fileinput
-import logging
-import os
-import platform
-import re
-import socket
-import stat
-import subprocess
-import sys
-import time
-import urlparse
-
-
-class PlatformSettingsError(Exception):
-  """Module catch-all error."""
-  pass
-
-
-class DnsReadError(PlatformSettingsError):
-  """Raised when unable to read DNS settings."""
-  pass
-
-
-class DnsUpdateError(PlatformSettingsError):
-  """Raised when unable to update DNS settings."""
-  pass
-
-
-class NotAdministratorError(PlatformSettingsError):
-  """Raised when not running as administrator."""
-  pass
-
-
-class CalledProcessError(PlatformSettingsError):
-  """Raised when a _check_output() process returns a non-zero exit status."""
-  def __init__(self, returncode, cmd):
-    super(CalledProcessError, self).__init__()
-    self.returncode = returncode
-    self.cmd = cmd
-
-  def __str__(self):
-    return 'Command "%s" returned non-zero exit status %d' % (
-        ' '.join(self.cmd), self.returncode)
-
-
-def FindExecutable(executable):
-  """Finds the given executable in PATH.
-
-  Since WPR may be invoked as sudo, meaning PATH is empty, we also hardcode a
-  few common paths.
-
-  Returns:
-    The fully qualified path with .exe appended if appropriate or None if it
-    doesn't exist.
-  """
-  return distutils.spawn.find_executable(executable,
-                                         os.pathsep.join([os.environ['PATH'],
-                                                          '/sbin',
-                                                          '/usr/bin',
-                                                          '/usr/sbin/',
-                                                          '/usr/local/sbin',
-                                                          ]))
-
-def HasSniSupport():
-  try:
-    import OpenSSL
-    return (distutils.version.StrictVersion(OpenSSL.__version__) >=
-            distutils.version.StrictVersion('0.13'))
-  except ImportError:
-    return False
-
-
-def SupportsFdLimitControl():
-  """Whether the platform supports changing the process fd limit."""
-  return os.name is 'posix'
-
-
-def GetFdLimit():
-  """Returns a tuple of (soft_limit, hard_limit)."""
-  import resource
-  return resource.getrlimit(resource.RLIMIT_NOFILE)
-
-
-def AdjustFdLimit(new_soft_limit, new_hard_limit):
-  """Sets a new soft and hard limit for max number of fds."""
-  import resource
-  resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft_limit, new_hard_limit))
-
-
-class SystemProxy(object):
-  """A host/port pair for a HTTP or HTTPS proxy configuration."""
-
-  def __init__(self, host, port):
-    """Initialize a SystemProxy instance.
-
-    Args:
-      host: a host name or IP address string (e.g. "example.com" or "1.1.1.1").
-      port: a port string or integer (e.g. "8888" or 8888).
-    """
-    self.host = host
-    self.port = int(port) if port else None
-
-  def __nonzero__(self):
-    """True if the host is set."""
-    return bool(self.host)
-
-  @classmethod
-  def from_url(cls, proxy_url):
-    """Create a SystemProxy instance.
-
-    If proxy_url is None, an empty string, or an invalid URL, the
-    SystemProxy instance with have None and None for the host and port
-    (no exception is raised).
-
-    Args:
-      proxy_url: a proxy url string such as "http://proxy.com:8888/".
-    Returns:
-      a System proxy instance.
-    """
-    if proxy_url:
-      parse_result = urlparse.urlparse(proxy_url)
-      return cls(parse_result.hostname, parse_result.port)
-    return cls(None, None)
-
-
-class _BasePlatformSettings(object):
-
-  def get_system_logging_handler(self):
-    """Return a handler for the logging module (optional)."""
-    return None
-
-  def rerun_as_administrator(self):
-    """If needed, rerun the program with administrative privileges.
-
-    Raises NotAdministratorError if unable to rerun.
-    """
-    pass
-
-  def timer(self):
-    """Return the current time in seconds as a floating point number."""
-    return time.time()
-
-  def get_server_ip_address(self, is_server_mode=False):
-    """Returns the IP address to use for dnsproxy and ipfw."""
-    if is_server_mode:
-      return socket.gethostbyname(socket.gethostname())
-    return '127.0.0.1'
-
-  def get_httpproxy_ip_address(self, is_server_mode=False):
-    """Returns the IP address to use for httpproxy."""
-    if is_server_mode:
-      return '0.0.0.0'
-    return '127.0.0.1'
-
-  def get_system_proxy(self, use_ssl):
-    """Returns the system HTTP(S) proxy host, port."""
-    del use_ssl
-    return SystemProxy(None, None)
-
-  def _ipfw_cmd(self):
-    raise NotImplementedError
-
-  def ipfw(self, *args):
-    ipfw_cmd = (self._ipfw_cmd(), ) + args
-    return self._check_output(*ipfw_cmd, elevate_privilege=True)
-
-  def has_ipfw(self):
-    try:
-      self.ipfw('list')
-      return True
-    except AssertionError as e:
-      logging.warning('Failed to start ipfw command. '
-                      'Error: %s' % e.message)
-      return False
-
-  def _get_cwnd(self):
-    return None
-
-  def _set_cwnd(self, args):
-    pass
-
-  def _elevate_privilege_for_cmd(self, args):
-    return args
-
-  def _check_output(self, *args, **kwargs):
-    """Run Popen(*args) and return its output as a byte string.
-
-    Python 2.7 has subprocess.check_output. This is essentially the same
-    except that, as a convenience, all the positional args are used as
-    command arguments and the |elevate_privilege| kwarg is supported.
-
-    Args:
-      *args: sequence of program arguments
-      elevate_privilege: Run the command with elevated privileges.
-    Raises:
-      CalledProcessError if the program returns non-zero exit status.
-    Returns:
-      output as a byte string.
-    """
-    command_args = [str(a) for a in args]
-
-    if os.path.sep not in command_args[0]:
-      qualified_command = FindExecutable(command_args[0])
-      assert qualified_command, 'Failed to find %s in path' % command_args[0]
-      command_args[0] = qualified_command
-
-    if kwargs.get('elevate_privilege'):
-      command_args = self._elevate_privilege_for_cmd(command_args)
-
-    logging.debug(' '.join(command_args))
-    process = subprocess.Popen(
-        command_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-    output = process.communicate()[0]
-    retcode = process.poll()
-    if retcode:
-      raise CalledProcessError(retcode, command_args)
-    return output
-
-  def set_temporary_tcp_init_cwnd(self, cwnd):
-    cwnd = int(cwnd)
-    original_cwnd = self._get_cwnd()
-    if original_cwnd is None:
-      raise PlatformSettingsError('Unable to get current tcp init_cwnd.')
-    if cwnd == original_cwnd:
-      logging.info('TCP init_cwnd already set to target value: %s', cwnd)
-    else:
-      self._set_cwnd(cwnd)
-      if self._get_cwnd() == cwnd:
-        logging.info('Changed cwnd to %s', cwnd)
-        atexit.register(self._set_cwnd, original_cwnd)
-      else:
-        logging.error('Unable to update cwnd to %s', cwnd)
-
-  def setup_temporary_loopback_config(self):
-    """Setup the loopback interface similar to real interface.
-
-    We use loopback for much of our testing, and on some systems, loopback
-    behaves differently from real interfaces.
-    """
-    logging.error('Platform does not support loopback configuration.')
-
-  def _save_primary_interface_properties(self):
-    self._orig_nameserver = self.get_original_primary_nameserver()
-
-  def _restore_primary_interface_properties(self):
-    self._set_primary_nameserver(self._orig_nameserver)
-
-  def _get_primary_nameserver(self):
-    raise NotImplementedError
-
-  def _set_primary_nameserver(self, _):
-    raise NotImplementedError
-
-  def get_original_primary_nameserver(self):
-    if not hasattr(self, '_original_nameserver'):
-      self._original_nameserver = self._get_primary_nameserver()
-      logging.info('Saved original primary DNS nameserver: %s',
-                   self._original_nameserver)
-    return self._original_nameserver
-
-  def set_temporary_primary_nameserver(self, nameserver):
-    self._save_primary_interface_properties()
-    self._set_primary_nameserver(nameserver)
-    if self._get_primary_nameserver() == nameserver:
-      logging.info('Changed temporary primary nameserver to %s', nameserver)
-      atexit.register(self._restore_primary_interface_properties)
-    else:
-      raise self._get_dns_update_error()
-
-
-class _PosixPlatformSettings(_BasePlatformSettings):
-
-  # pylint: disable=abstract-method
-  # Suppress lint check for _get_primary_nameserver & _set_primary_nameserver
-
-  def rerun_as_administrator(self):
-    """If needed, rerun the program with administrative privileges.
-
-    Raises NotAdministratorError if unable to rerun.
-    """
-    if os.geteuid() != 0:
-      logging.warn('Rerunning with sudo: %s', sys.argv)
-      os.execv('/usr/bin/sudo', ['--'] + sys.argv)
-
-  def _elevate_privilege_for_cmd(self, args):
-    def IsSetUID(path):
-      return (os.stat(path).st_mode & stat.S_ISUID) == stat.S_ISUID
-
-    def IsElevated():
-      p = subprocess.Popen(
-          ['sudo', '-nv'], stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-          stderr=subprocess.STDOUT)
-      stdout = p.communicate()[0]
-      # Some versions of sudo set the returncode based on whether sudo requires
-      # a password currently. Other versions return output when password is
-      # required and no output when the user is already authenticated.
-      return not p.returncode and not stdout
-
-    if not IsSetUID(args[0]):
-      args = ['sudo'] + args
-
-      if not IsElevated():
-        print 'WPR needs to run %s under sudo. Please authenticate.' % args[1]
-        subprocess.check_call(['sudo', '-v'])  # Synchronously authenticate.
-
-        prompt = ('Would you like to always allow %s to run without sudo '
-                  '(via `sudo chmod +s %s`)? (y/N)' % (args[1], args[1]))
-        if raw_input(prompt).lower() == 'y':
-          subprocess.check_call(['sudo', 'chmod', '+s', args[1]])
-    return args
-
-  def get_system_proxy(self, use_ssl):
-    """Returns the system HTTP(S) proxy host, port."""
-    proxy_url = os.environ.get('https_proxy' if use_ssl else 'http_proxy')
-    return SystemProxy.from_url(proxy_url)
-
-  def _ipfw_cmd(self):
-    return 'ipfw'
-
-  def _get_dns_update_error(self):
-    return DnsUpdateError('Did you run under sudo?')
-
-  def _sysctl(self, *args, **kwargs):
-    sysctl_args = [FindExecutable('sysctl')]
-    if kwargs.get('use_sudo'):
-      sysctl_args = self._elevate_privilege_for_cmd(sysctl_args)
-    sysctl_args.extend(str(a) for a in args)
-    sysctl = subprocess.Popen(
-        sysctl_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-    stdout = sysctl.communicate()[0]
-    return sysctl.returncode, stdout
-
-  def has_sysctl(self, name):
-    if not hasattr(self, 'has_sysctl_cache'):
-      self.has_sysctl_cache = {}
-    if name not in self.has_sysctl_cache:
-      self.has_sysctl_cache[name] = self._sysctl(name)[0] == 0
-    return self.has_sysctl_cache[name]
-
-  def set_sysctl(self, name, value):
-    rv = self._sysctl('%s=%s' % (name, value), use_sudo=True)[0]
-    if rv != 0:
-      logging.error('Unable to set sysctl %s: %s', name, rv)
-
-  def get_sysctl(self, name):
-    rv, value = self._sysctl('-n', name)
-    if rv == 0:
-      return value
-    else:
-      logging.error('Unable to get sysctl %s: %s', name, rv)
-      return None
-
-
-class _OsxPlatformSettings(_PosixPlatformSettings):
-  LOCAL_SLOWSTART_MIB_NAME = 'net.inet.tcp.local_slowstart_flightsize'
-
-  def _scutil(self, cmd):
-    scutil = subprocess.Popen([FindExecutable('scutil')],
-                               stdin=subprocess.PIPE, stdout=subprocess.PIPE)
-    return scutil.communicate(cmd)[0]
-
-  def _ifconfig(self, *args):
-    return self._check_output('ifconfig', *args, elevate_privilege=True)
-
-  def set_sysctl(self, name, value):
-    rv = self._sysctl('-w', '%s=%s' % (name, value), use_sudo=True)[0]
-    if rv != 0:
-      logging.error('Unable to set sysctl %s: %s', name, rv)
-
-  def _get_cwnd(self):
-    return int(self.get_sysctl(self.LOCAL_SLOWSTART_MIB_NAME))
-
-  def _set_cwnd(self, size):
-    self.set_sysctl(self.LOCAL_SLOWSTART_MIB_NAME, size)
-
-  def _get_loopback_mtu(self):
-    config = self._ifconfig('lo0')
-    match = re.search(r'\smtu\s+(\d+)', config)
-    return int(match.group(1)) if match else None
-
-  def setup_temporary_loopback_config(self):
-    """Configure loopback to temporarily use reasonably sized frames.
-
-    OS X uses jumbo frames by default (16KB).
-    """
-    TARGET_LOOPBACK_MTU = 1500
-    original_mtu = self._get_loopback_mtu()
-    if original_mtu is None:
-      logging.error('Unable to read loopback mtu. Setting left unchanged.')
-      return
-    if original_mtu == TARGET_LOOPBACK_MTU:
-      logging.debug('Loopback MTU already has target value: %d', original_mtu)
-    else:
-      self._ifconfig('lo0', 'mtu', TARGET_LOOPBACK_MTU)
-      if self._get_loopback_mtu() == TARGET_LOOPBACK_MTU:
-        logging.debug('Set loopback MTU to %d (was %d)',
-                      TARGET_LOOPBACK_MTU, original_mtu)
-        atexit.register(self._ifconfig, 'lo0', 'mtu', original_mtu)
-      else:
-        logging.error('Unable to change loopback MTU from %d to %d',
-                      original_mtu, TARGET_LOOPBACK_MTU)
-
-  def _get_dns_service_key(self):
-    output = self._scutil('show State:/Network/Global/IPv4')
-    lines = output.split('\n')
-    for line in lines:
-      key_value = line.split(' : ')
-      if key_value[0] == '  PrimaryService':
-        return 'State:/Network/Service/%s/DNS' % key_value[1]
-    raise DnsReadError('Unable to find DNS service key: %s', output)
-
-  def _get_primary_nameserver(self):
-    output = self._scutil('show %s' % self._get_dns_service_key())
-    match = re.search(
-        br'ServerAddresses\s+:\s+<array>\s+{\s+0\s+:\s+((\d{1,3}\.){3}\d{1,3})',
-        output)
-    if match:
-      return match.group(1)
-    else:
-      raise DnsReadError('Unable to find primary DNS server: %s', output)
-
-  def _set_primary_nameserver(self, dns):
-    command = '\n'.join([
-      'd.init',
-      'd.add ServerAddresses * %s' % dns,
-      'set %s' % self._get_dns_service_key()
-    ])
-    self._scutil(command)
-
-
-class _FreeBSDPlatformSettings(_PosixPlatformSettings):
-  """Partial implementation for FreeBSD.  Does not allow a DNS server to be
-  launched nor ipfw to be used.
-  """
-  RESOLV_CONF = '/etc/resolv.conf'
-
-  def _get_default_route_line(self):
-    raise NotImplementedError
-
-  def _set_cwnd(self, cwnd):
-    raise NotImplementedError
-
-  def _get_cwnd(self):
-    raise NotImplementedError
-
-  def setup_temporary_loopback_config(self):
-    raise NotImplementedError
-
-  def _write_resolve_conf(self, dns):
-    raise NotImplementedError
-
-  def _get_primary_nameserver(self):
-    try:
-      resolv_file = open(self.RESOLV_CONF)
-    except IOError:
-      raise DnsReadError()
-    for line in resolv_file:
-      if line.startswith('nameserver '):
-        return line.split()[1]
-    raise DnsReadError()
-
-  def _set_primary_nameserver(self, dns):
-    raise NotImplementedError
-
-
-class _LinuxPlatformSettings(_PosixPlatformSettings):
-  """The following thread recommends a way to update DNS on Linux:
-
-  http://ubuntuforums.org/showthread.php?t=337553
-
-         sudo cp /etc/dhcp3/dhclient.conf /etc/dhcp3/dhclient.conf.bak
-         sudo gedit /etc/dhcp3/dhclient.conf
-         #prepend domain-name-servers 127.0.0.1;
-         prepend domain-name-servers 208.67.222.222, 208.67.220.220;
-
-         prepend domain-name-servers 208.67.222.222, 208.67.220.220;
-         request subnet-mask, broadcast-address, time-offset, routers,
-             domain-name, domain-name-servers, host-name,
-             netbios-name-servers, netbios-scope;
-         #require subnet-mask, domain-name-servers;
-
-         sudo /etc/init.d/networking restart
-
-  The code below does not try to change dchp and does not restart networking.
-  Update this as needed to make it more robust on more systems.
-  """
-  RESOLV_CONF = '/etc/resolv.conf'
-  ROUTE_RE = re.compile('initcwnd (\d+)')
-  TCP_BASE_MSS = 'net.ipv4.tcp_base_mss'
-  TCP_MTU_PROBING = 'net.ipv4.tcp_mtu_probing'
-
-  def _get_default_route_line(self):
-    stdout = self._check_output('ip', 'route')
-    for line in stdout.split('\n'):
-      if line.startswith('default'):
-        return line
-    return None
-
-  def _set_cwnd(self, cwnd):
-    default_line = self._get_default_route_line()
-    self._check_output(
-        'ip', 'route', 'change', default_line, 'initcwnd', str(cwnd))
-
-  def _get_cwnd(self):
-    default_line = self._get_default_route_line()
-    m = self.ROUTE_RE.search(default_line)
-    if m:
-      return int(m.group(1))
-    # If 'initcwnd' wasn't found, then 0 means it's the system default.
-    return 0
-
-  def setup_temporary_loopback_config(self):
-    """Setup Linux to temporarily use reasonably sized frames.
-
-    Linux uses jumbo frames by default (16KB), using the combination
-    of MTU probing and a base MSS makes it use normal sized packets.
-
-    The reason this works is because tcp_base_mss is only used when MTU
-    probing is enabled.  And since we're using the max value, it will
-    always use the reasonable size.  This is relevant for server-side realism.
-    The client-side will vary depending on the client TCP stack config.
-    """
-    ENABLE_MTU_PROBING = 2
-    original_probing = self.get_sysctl(self.TCP_MTU_PROBING)
-    self.set_sysctl(self.TCP_MTU_PROBING, ENABLE_MTU_PROBING)
-    atexit.register(self.set_sysctl, self.TCP_MTU_PROBING, original_probing)
-
-    TCP_FULL_MSS = 1460
-    original_mss = self.get_sysctl(self.TCP_BASE_MSS)
-    self.set_sysctl(self.TCP_BASE_MSS, TCP_FULL_MSS)
-    atexit.register(self.set_sysctl, self.TCP_BASE_MSS, original_mss)
-
-  def _write_resolve_conf(self, dns):
-    is_first_nameserver_replaced = False
-    # The fileinput module uses sys.stdout as the edited file output.
-    for line in fileinput.input(self.RESOLV_CONF, inplace=1, backup='.bak'):
-      if line.startswith('nameserver ') and not is_first_nameserver_replaced:
-        print 'nameserver %s' % dns
-        is_first_nameserver_replaced = True
-      else:
-        print line,
-    if not is_first_nameserver_replaced:
-      raise DnsUpdateError('Could not find a suitable nameserver entry in %s' %
-                           self.RESOLV_CONF)
-
-  def _get_primary_nameserver(self):
-    try:
-      resolv_file = open(self.RESOLV_CONF)
-    except IOError:
-      raise DnsReadError()
-    for line in resolv_file:
-      if line.startswith('nameserver '):
-        return line.split()[1]
-    raise DnsReadError()
-
-  def _set_primary_nameserver(self, dns):
-    """Replace the first nameserver entry with the one given."""
-    try:
-      self._write_resolve_conf(dns)
-    except OSError, e:
-      if 'Permission denied' in e:
-        raise self._get_dns_update_error()
-      raise
-
-
-class _WindowsPlatformSettings(_BasePlatformSettings):
-
-  # pylint: disable=abstract-method
-  # Suppress lint check for _ipfw_cmd
-
-  def get_system_logging_handler(self):
-    """Return a handler for the logging module (optional).
-
-    For Windows, output can be viewed with DebugView.
-    http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx
-    """
-    import ctypes
-    output_debug_string = ctypes.windll.kernel32.OutputDebugStringA
-    output_debug_string.argtypes = [ctypes.c_char_p]
-    class DebugViewHandler(logging.Handler):
-      def emit(self, record):
-        output_debug_string('[wpr] ' + self.format(record))
-    return DebugViewHandler()
-
-  def rerun_as_administrator(self):
-    """If needed, rerun the program with administrative privileges.
-
-    Raises NotAdministratorError if unable to rerun.
-    """
-    import ctypes
-    if not ctypes.windll.shell32.IsUserAnAdmin():
-      raise NotAdministratorError('Rerun with administrator privileges.')
-      #os.execv('runas', sys.argv)  # TODO: replace needed Windows magic
-
-  def timer(self):
-    """Return the current time in seconds as a floating point number.
-
-    From time module documentation:
-       On Windows, this function [time.clock()] returns wall-clock
-       seconds elapsed since the first call to this function, as a
-       floating point number, based on the Win32 function
-       QueryPerformanceCounter(). The resolution is typically better
-       than one microsecond.
-    """
-    return time.clock()
-
-  def _arp(self, *args):
-    return self._check_output('arp', *args)
-
-  def _route(self, *args):
-    return self._check_output('route', *args)
-
-  def _ipconfig(self, *args):
-    return self._check_output('ipconfig', *args)
-
-  def _get_mac_address(self, ip):
-    """Return the MAC address for the given ip."""
-    ip_re = re.compile(r'^\s*IP(?:v4)? Address[ .]+:\s+([0-9.]+)')
-    for line in self._ipconfig('/all').splitlines():
-      if line[:1].isalnum():
-        current_ip = None
-        current_mac = None
-      elif ':' in line:
-        line = line.strip()
-        ip_match = ip_re.match(line)
-        if ip_match:
-          current_ip = ip_match.group(1)
-        elif line.startswith('Physical Address'):
-          current_mac = line.split(':', 1)[1].lstrip()
-        if current_ip == ip and current_mac:
-          return current_mac
-    return None
-
-  def setup_temporary_loopback_config(self):
-    """On Windows, temporarily route the server ip to itself."""
-    ip = self.get_server_ip_address()
-    mac_address = self._get_mac_address(ip)
-    if self.mac_address:
-      self._arp('-s', ip, self.mac_address)
-      self._route('add', ip, ip, 'mask', '255.255.255.255')
-      atexit.register(self._arp, '-d', ip)
-      atexit.register(self._route, 'delete', ip, ip, 'mask', '255.255.255.255')
-    else:
-      logging.warn('Unable to configure loopback: MAC address not found.')
-    # TODO(slamm): Configure cwnd, MTU size
-
-  def _get_dns_update_error(self):
-    return DnsUpdateError('Did you run as administrator?')
-
-  def _netsh_show_dns(self):
-    """Return DNS information:
-
-    Example output:
-        Configuration for interface "Local Area Connection 3"
-        DNS servers configured through DHCP:  None
-        Register with which suffix:           Primary only
-
-        Configuration for interface "Wireless Network Connection 2"
-        DNS servers configured through DHCP:  192.168.1.1
-        Register with which suffix:           Primary only
-    """
-    return self._check_output('netsh', 'interface', 'ip', 'show', 'dns')
-
-  def _netsh_set_dns(self, iface_name, addr):
-    """Modify DNS information on the primary interface."""
-    output = self._check_output('netsh', 'interface', 'ip', 'set', 'dns',
-                                iface_name, 'static', addr)
-
-  def _netsh_set_dns_dhcp(self, iface_name):
-    """Modify DNS information on the primary interface."""
-    output = self._check_output('netsh', 'interface', 'ip', 'set', 'dns',
-                                iface_name, 'dhcp')
-
-  def _get_interfaces_with_dns(self):
-    output = self._netsh_show_dns()
-    lines = output.split('\n')
-    iface_re = re.compile(r'^Configuration for interface \"(?P<name>.*)\"')
-    dns_re = re.compile(r'(?P<kind>.*):\s+(?P<dns>\d+\.\d+\.\d+\.\d+)')
-    iface_name = None
-    iface_dns = None
-    iface_kind = None
-    ifaces = []
-    for line in lines:
-      iface_match = iface_re.match(line)
-      if iface_match:
-        iface_name = iface_match.group('name')
-      dns_match = dns_re.match(line)
-      if dns_match:
-        iface_dns = dns_match.group('dns')
-        iface_dns_config = dns_match.group('kind').strip()
-        if iface_dns_config == "Statically Configured DNS Servers":
-          iface_kind = "static"
-        elif iface_dns_config == "DNS servers configured through DHCP":
-          iface_kind = "dhcp"
-      if iface_name and iface_dns and iface_kind:
-        ifaces.append((iface_dns, iface_name, iface_kind))
-        iface_name = None
-        iface_dns = None
-    return ifaces
-
-  def _save_primary_interface_properties(self):
-    # TODO(etienneb): On windows, an interface can have multiple DNS server
-    # configured. We should save/restore all of them.
-    ifaces = self._get_interfaces_with_dns()
-    self._primary_interfaces = ifaces
-
-  def _restore_primary_interface_properties(self):
-    for iface in self._primary_interfaces:
-      (iface_dns, iface_name, iface_kind) = iface
-      self._netsh_set_dns(iface_name, iface_dns)
-      if iface_kind == "dhcp":
-        self._netsh_set_dns_dhcp(iface_name)
-
-  def _get_primary_nameserver(self):
-    ifaces = self._get_interfaces_with_dns()
-    if not len(ifaces):
-      raise DnsUpdateError("Interface with valid DNS configured not found.")
-    (iface_dns, iface_name, iface_kind) = ifaces[0]
-    return iface_dns
-
-  def _set_primary_nameserver(self, dns):
-    for iface in self._primary_interfaces:
-      (iface_dns, iface_name, iface_kind) = iface
-      self._netsh_set_dns(iface_name, dns)
-
-
-class _WindowsXpPlatformSettings(_WindowsPlatformSettings):
-  def _ipfw_cmd(self):
-    return (r'third_party\ipfw_win32\ipfw.exe',)
-
-
-def _new_platform_settings(system, release):
-  """Make a new instance of PlatformSettings for the current system."""
-  if system == 'Darwin':
-    return _OsxPlatformSettings()
-  if system == 'Linux':
-    return _LinuxPlatformSettings()
-  if system == 'Windows' and release == 'XP':
-    return _WindowsXpPlatformSettings()
-  if system == 'Windows':
-    return _WindowsPlatformSettings()
-  if system == 'FreeBSD':
-    return _FreeBSDPlatformSettings()
-  raise NotImplementedError('Sorry %s %s is not supported.' % (system, release))
-
-
-# Create one instance of the platform-specific settings and
-# make the functions available at the module-level.
-_inst = _new_platform_settings(platform.system(), platform.release())
-
-get_system_logging_handler = _inst.get_system_logging_handler
-rerun_as_administrator = _inst.rerun_as_administrator
-timer = _inst.timer
-
-get_server_ip_address = _inst.get_server_ip_address
-get_httpproxy_ip_address = _inst.get_httpproxy_ip_address
-get_system_proxy = _inst.get_system_proxy
-ipfw = _inst.ipfw
-has_ipfw = _inst.has_ipfw
-set_temporary_tcp_init_cwnd = _inst.set_temporary_tcp_init_cwnd
-setup_temporary_loopback_config = _inst.setup_temporary_loopback_config
-
-get_original_primary_nameserver = _inst.get_original_primary_nameserver
-set_temporary_primary_nameserver = _inst.set_temporary_primary_nameserver
diff --git a/catapult/telemetry/third_party/web-page-replay/platformsettings_test.py b/catapult/telemetry/third_party/web-page-replay/platformsettings_test.py
deleted file mode 100755
index 3172f9b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/platformsettings_test.py
+++ /dev/null
@@ -1,248 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2011 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unit tests for platformsettings.
-
-Usage:
-$ ./platformsettings_test.py
-"""
-
-import unittest
-
-import platformsettings
-
-WINDOWS_7_IP = '172.11.25.170'
-WINDOWS_7_MAC = '00-1A-44-DA-88-C0'
-WINDOWS_7_IPCONFIG = """
-Windows IP Configuration
-
-   Host Name . . . . . . . . . . . . : THEHOST1-W
-   Primary Dns Suffix  . . . . . . . : something.example.com
-   Node Type . . . . . . . . . . . . : Hybrid
-   IP Routing Enabled. . . . . . . . : No
-   WINS Proxy Enabled. . . . . . . . : No
-   DNS Suffix Search List. . . . . . : example.com
-                                       another.example.com
-
-Ethernet adapter Local Area Connection:
-
-   Connection-specific DNS Suffix  . : somethingexample.com
-   Description . . . . . . . . . . . : Int PRO/1000 MT Network Connection
-   Physical Address. . . . . . . . . : %(mac_addr)s
-   DHCP Enabled. . . . . . . . . . . : Yes
-   Autoconfiguration Enabled . . . . : Yes
-   IPv6 Address. . . . . . . . . . . : 1234:0:1000:1200:839f:d256:3a6c:210(Preferred)
-   Temporary IPv6 Address. . . . . . : 2143:0:2100:1800:38f9:2d65:a3c6:120(Preferred)
-   Link-local IPv6 Address . . . . . : abcd::1234:1a33:b2cc:238%%18(Preferred)
-   IPv4 Address. . . . . . . . . . . : %(ip_addr)s(Preferred)
-   Subnet Mask . . . . . . . . . . . : 255.255.248.0
-   Lease Obtained. . . . . . . . . . : Thursday, April 28, 2011 9:40:22 PM
-   Lease Expires . . . . . . . . . . : Tuesday, May 10, 2011 12:15:48 PM
-   Default Gateway . . . . . . . . . : abcd::2:37ee:ef70:56%%18
-                                       172.11.25.254
-   DHCP Server . . . . . . . . . . . : 172.11.22.33
-   DNS Servers . . . . . . . . . . . : 8.8.4.4
-   NetBIOS over Tcpip. . . . . . . . : Enabled
-""" % {'ip_addr': WINDOWS_7_IP, 'mac_addr': WINDOWS_7_MAC}
-
-WINDOWS_XP_IP = '172.1.2.3'
-WINDOWS_XP_MAC = '00-34-B8-1F-FA-70'
-WINDOWS_XP_IPCONFIG = """
-Windows IP Configuration
-
-        Host Name . . . . . . . . . . . . : HOSTY-0
-        Primary Dns Suffix  . . . . . . . :
-        Node Type . . . . . . . . . . . . : Unknown
-        IP Routing Enabled. . . . . . . . : No
-        WINS Proxy Enabled. . . . . . . . : No
-        DNS Suffix Search List. . . . . . : example.com
-
-Ethernet adapter Local Area Connection 2:
-
-        Connection-specific DNS Suffix  . : example.com
-        Description . . . . . . . . . . . : Int Adapter (PILA8470B)
-        Physical Address. . . . . . . . . : %(mac_addr)s
-        Dhcp Enabled. . . . . . . . . . . : Yes
-        Autoconfiguration Enabled . . . . : Yes
-        IP Address. . . . . . . . . . . . : %(ip_addr)s
-        Subnet Mask . . . . . . . . . . . : 255.255.254.0
-        Default Gateway . . . . . . . . . : 172.1.2.254
-        DHCP Server . . . . . . . . . . . : 172.1.3.241
-        DNS Servers . . . . . . . . . . . : 172.1.3.241
-                                            8.8.8.8
-                                            8.8.4.4
-        Lease Obtained. . . . . . . . . . : Thursday, April 07, 2011 9:14:55 AM
-        Lease Expires . . . . . . . . . . : Thursday, April 07, 2011 1:14:55 PM
-""" % {'ip_addr': WINDOWS_XP_IP, 'mac_addr': WINDOWS_XP_MAC}
-
-
-# scutil show State:/Network/Global/IPv4
-OSX_IPV4_STATE = """
-<dictionary> {
-  PrimaryInterface : en1
-  PrimaryService : 8824452C-FED4-4C09-9256-40FB146739E0
-  Router : 192.168.1.1
-}
-"""
-
-# scutil show State:/Network/Service/[PRIMARY_SERVICE_KEY]/DNS
-OSX_DNS_STATE_LION = """
-<dictionary> {
-  DomainName : mtv.corp.google.com
-  SearchDomains : <array> {
-    0 : mtv.corp.google.com
-    1 : corp.google.com
-    2 : prod.google.com
-    3 : prodz.google.com
-    4 : google.com
-  }
-  ServerAddresses : <array> {
-    0 : 172.72.255.1
-    1 : 172.49.117.57
-    2 : 172.54.116.57
-  }
-}
-"""
-
-OSX_DNS_STATE_SNOW_LEOPARD = """
-<dictionary> {
-  ServerAddresses : <array> {
-    0 : 172.27.1.1
-    1 : 172.94.117.57
-    2 : 172.45.116.57
-  }
-  DomainName : mtv.corp.google.com
-  SearchDomains : <array> {
-    0 : mtv.corp.google.com
-    1 : corp.google.com
-    2 : prod.google.com
-    3 : prodz.google.com
-    4 : google.com
-  }
-}
-"""
-
-
-class SystemProxyTest(unittest.TestCase):
-
-  def test_basic(self):
-    system_proxy = platformsettings.SystemProxy(None, None)
-    self.assertEqual(None, system_proxy.host)
-    self.assertEqual(None, system_proxy.port)
-    self.assertFalse(system_proxy)
-
-  def test_from_url_empty(self):
-    system_proxy = platformsettings.SystemProxy.from_url('')
-    self.assertEqual(None, system_proxy.host)
-    self.assertEqual(None, system_proxy.port)
-    self.assertFalse(system_proxy)
-
-  def test_from_url_basic(self):
-    system_proxy = platformsettings.SystemProxy.from_url('http://pxy.com:8888/')
-    self.assertEqual('pxy.com', system_proxy.host)
-    self.assertEqual(8888, system_proxy.port)
-    self.assertTrue(system_proxy)
-
-  def test_from_url_no_port(self):
-    system_proxy = platformsettings.SystemProxy.from_url('http://pxy.com/')
-    self.assertEqual('pxy.com', system_proxy.host)
-    self.assertEqual(None, system_proxy.port)
-    self.assertTrue(system_proxy)
-
-  def test_from_url_empty_string(self):
-    system_proxy = platformsettings.SystemProxy.from_url('')
-    self.assertEqual(None, system_proxy.host)
-    self.assertEqual(None, system_proxy.port)
-    self.assertFalse(system_proxy)
-
-  def test_from_url_bad_string(self):
-    system_proxy = platformsettings.SystemProxy.from_url('foo:80')
-    self.assertEqual(None, system_proxy.host)
-    self.assertEqual(None, system_proxy.port)
-    self.assertFalse(system_proxy)
-
-
-class HasSniTest(unittest.TestCase):
-  def test_has_sni(self):
-    # Check that no exception is raised.
-    platformsettings.HasSniSupport()
-
-
-# pylint: disable=abstract-method
-class Win7Settings(platformsettings._WindowsPlatformSettings):
-  @classmethod
-  def _ipconfig(cls, *args):
-    if args == ('/all',):
-      return WINDOWS_7_IPCONFIG
-    raise RuntimeError
-
-class WinXpSettings(platformsettings._WindowsPlatformSettings):
-  @classmethod
-  def _ipconfig(cls, *args):
-    if args == ('/all',):
-      return WINDOWS_XP_IPCONFIG
-    raise RuntimeError
-
-
-class WindowsPlatformSettingsTest(unittest.TestCase):
-  def test_get_mac_address_xp(self):
-    self.assertEqual(WINDOWS_XP_MAC,
-                     WinXpSettings()._get_mac_address(WINDOWS_XP_IP))
-
-  def test_get_mac_address_7(self):
-    self.assertEqual(WINDOWS_7_MAC,
-                     Win7Settings()._get_mac_address(WINDOWS_7_IP))
-
-
-class OsxSettings(platformsettings._OsxPlatformSettings):
-  def __init__(self):
-    super(OsxSettings, self).__init__()
-    self.ipv4_state = OSX_IPV4_STATE
-    self.dns_state = None  # varies by test
-
-  def _scutil(self, cmd):
-    if cmd == 'show State:/Network/Global/IPv4':
-      return self.ipv4_state
-    elif cmd.startswith('show State:/Network/Service/'):
-      return self.dns_state
-    raise RuntimeError("Unrecognized cmd: %s", cmd)
-
-
-class OsxPlatformSettingsTest(unittest.TestCase):
-  def setUp(self):
-    self.settings = OsxSettings()
-
-  def test_get_primary_nameserver_lion(self):
-    self.settings.dns_state = OSX_DNS_STATE_LION
-    self.assertEqual('172.72.255.1', self.settings._get_primary_nameserver())
-
-  def test_get_primary_nameserver_snow_leopard(self):
-    self.settings.dns_state = OSX_DNS_STATE_SNOW_LEOPARD
-    self.assertEqual('172.27.1.1', self.settings._get_primary_nameserver())
-
-  def test_get_primary_nameserver_unexpected_ipv4_state_raises(self):
-    self.settings.ipv4_state = 'Some error'
-    self.settings.dns_state = OSX_DNS_STATE_SNOW_LEOPARD
-    self.assertRaises(platformsettings.DnsReadError,
-                      self.settings._get_primary_nameserver)
-
-  def test_get_primary_nameserver_unexpected_dns_state_raises(self):
-    self.settings.dns_state = 'Some other error'
-    self.assertRaises(platformsettings.DnsReadError,
-                      self.settings._get_primary_nameserver)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/proxyshaper.py b/catapult/telemetry/third_party/web-page-replay/proxyshaper.py
deleted file mode 100644
index 6c6976f..0000000
--- a/catapult/telemetry/third_party/web-page-replay/proxyshaper.py
+++ /dev/null
@@ -1,125 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Simulate network characteristics directly in Python.
-
-Allows running replay without dummynet.
-"""
-
-import logging
-import platformsettings
-import re
-import time
-
-
-TIMER = platformsettings.timer
-
-
-class ProxyShaperError(Exception):
-  """Module catch-all error."""
-  pass
-
-class BandwidthValueError(ProxyShaperError):
-  """Raised for unexpected dummynet-style bandwidth value."""
-  pass
-
-
-class RateLimitedFile(object):
-  """Wrap a file like object with rate limiting.
-
-  TODO(slamm): Simulate slow-start.
-      Each RateLimitedFile corresponds to one-direction of a
-      bidirectional socket. Slow-start can be added here (algorithm needed).
-      Will consider changing this class to take read and write files and
-      corresponding bit rates for each.
-  """
-  BYTES_PER_WRITE = 1460
-
-  def __init__(self, request_counter, f, bps):
-    """Initialize a RateLimiter.
-
-    Args:
-      request_counter: callable to see how many requests share the limit.
-      f: file-like object to wrap.
-      bps: an integer of bits per second.
-    """
-    self.request_counter = request_counter
-    self.original_file = f
-    self.bps = bps
-
-  def transfer_seconds(self, num_bytes):
-    """Seconds to read/write |num_bytes| with |self.bps|."""
-    return 8.0 * num_bytes / self.bps
-
-  def write(self, data):
-    num_bytes = len(data)
-    num_sent_bytes = 0
-    while num_sent_bytes < num_bytes:
-      num_write_bytes = min(self.BYTES_PER_WRITE, num_bytes - num_sent_bytes)
-      num_requests = self.request_counter()
-      wait = self.transfer_seconds(num_write_bytes) * num_requests
-      logging.debug('write sleep: %0.4fs (%d requests)', wait, num_requests)
-      time.sleep(wait)
-
-      self.original_file.write(
-          data[num_sent_bytes:num_sent_bytes + num_write_bytes])
-      num_sent_bytes += num_write_bytes
-
-  def _read(self, read_func, size):
-    start = TIMER()
-    data = read_func(size)
-    read_seconds = TIMER() - start
-    num_bytes = len(data)
-    num_requests = self.request_counter()
-    wait = self.transfer_seconds(num_bytes) * num_requests - read_seconds
-    if wait > 0:
-      logging.debug('read sleep: %0.4fs %d requests)', wait, num_requests)
-      time.sleep(wait)
-    return data
-
-  def readline(self, size=-1):
-    return self._read(self.original_file.readline, size)
-
-  def read(self, size=-1):
-    return self._read(self.original_file.read, size)
-
-  def __getattr__(self, name):
-    """Forward any non-overriden calls."""
-    return getattr(self.original_file, name)
-
-
-def GetBitsPerSecond(bandwidth):
-  """Return bits per second represented by dummynet bandwidth option.
-
-  See ipfw/dummynet.c:read_bandwidth for how it is really done.
-
-  Args:
-    bandwidth: a dummynet-style bandwidth specification (e.g. "10Kbit/s")
-  """
-  if bandwidth == '0':
-    return 0
-  bw_re = r'^(\d+)(?:([KM])?(bit|Byte)/s)?$'
-  match = re.match(bw_re, str(bandwidth))
-  if not match:
-    raise BandwidthValueError('Value, "%s", does not match regex: %s' % (
-        bandwidth, bw_re))
-  bw = int(match.group(1))
-  if match.group(2) == 'K':
-    bw *= 1000
-  if match.group(2) == 'M':
-    bw *= 1000000
-  if match.group(3) == 'Byte':
-    bw *= 8
-  return bw
diff --git a/catapult/telemetry/third_party/web-page-replay/proxyshaper_test.py b/catapult/telemetry/third_party/web-page-replay/proxyshaper_test.py
deleted file mode 100755
index 5c2e3ae..0000000
--- a/catapult/telemetry/third_party/web-page-replay/proxyshaper_test.py
+++ /dev/null
@@ -1,141 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unit tests for proxyshaper.
-
-Usage:
-$ ./proxyshaper_test.py
-"""
-
-import proxyshaper
-import StringIO
-import unittest
-
-
-# pylint: disable=bad-whitespace
-VALID_RATES = (
-    # input,       expected_bps
-    ( '384Kbit/s',   384000),
-    ('1536Kbit/s',  1536000),
-    (   '1Mbit/s',  1000000),
-    (   '5Mbit/s',  5000000),
-    (  '2MByte/s', 16000000),
-    (         '0',        0),
-    (         '5',        5),
-    (      384000,   384000),
-    )
-
-ERROR_RATES = (
-    '1536KBit/s',  # Older versions of dummynet used capital 'B' for bytes.
-    '1Mbyte/s',    # Require capital 'B' for bytes.
-    '5bps',
-    )
-
-
-class TimedTestCase(unittest.TestCase):
-  def assertValuesAlmostEqual(self, expected, actual, tolerance=0.05):
-    """Like the following with nicer default message:
-           assertTrue(expected <= actual + tolerance &&
-                      expected >= actual - tolerance)
-    """
-    delta = tolerance * expected
-    if actual > expected + delta or actual < expected - delta:
-      self.fail('%s is not equal to expected %s +/- %s%%' % (
-              actual, expected, 100 * tolerance))
-
-
-class RateLimitedFileTest(TimedTestCase):
-  def testReadLimitedBasic(self):
-    num_bytes = 1024
-    bps = 384000
-    request_counter = lambda: 1
-    f = StringIO.StringIO(' ' * num_bytes)
-    limited_f = proxyshaper.RateLimitedFile(request_counter, f, bps)
-    start = proxyshaper.TIMER()
-    self.assertEqual(num_bytes, len(limited_f.read()))
-    expected_ms = 8.0 * num_bytes / bps * 1000.0
-    actual_ms = (proxyshaper.TIMER() - start) * 1000.0
-    self.assertValuesAlmostEqual(expected_ms, actual_ms)
-
-  def testReadlineLimitedBasic(self):
-    num_bytes = 1024 * 8 + 512
-    bps = 384000
-    request_counter = lambda: 1
-    f = StringIO.StringIO(' ' * num_bytes)
-    limited_f = proxyshaper.RateLimitedFile(request_counter, f, bps)
-    start = proxyshaper.TIMER()
-    self.assertEqual(num_bytes, len(limited_f.readline()))
-    expected_ms = 8.0 * num_bytes / bps * 1000.0
-    actual_ms = (proxyshaper.TIMER() - start) * 1000.0
-    self.assertValuesAlmostEqual(expected_ms, actual_ms)
-
-  def testReadLimitedSlowedByMultipleRequests(self):
-    num_bytes = 1024
-    bps = 384000
-    request_count = 2
-    request_counter = lambda: request_count
-    f = StringIO.StringIO(' ' * num_bytes)
-    limited_f = proxyshaper.RateLimitedFile(request_counter, f, bps)
-    start = proxyshaper.TIMER()
-    num_read_bytes = limited_f.read()
-    self.assertEqual(num_bytes, len(num_read_bytes))
-    expected_ms = 8.0 * num_bytes / (bps / float(request_count)) * 1000.0
-    actual_ms = (proxyshaper.TIMER() - start) * 1000.0
-    self.assertValuesAlmostEqual(expected_ms, actual_ms)
-
-  def testWriteLimitedBasic(self):
-    num_bytes = 1024 * 10 + 350
-    bps = 384000
-    request_counter = lambda: 1
-    f = StringIO.StringIO()
-    limited_f = proxyshaper.RateLimitedFile(request_counter, f, bps)
-    start = proxyshaper.TIMER()
-    limited_f.write(' ' * num_bytes)
-    self.assertEqual(num_bytes, len(limited_f.getvalue()))
-    expected_ms = 8.0 * num_bytes / bps * 1000.0
-    actual_ms = (proxyshaper.TIMER() - start) * 1000.0
-    self.assertValuesAlmostEqual(expected_ms, actual_ms)
-
-  def testWriteLimitedSlowedByMultipleRequests(self):
-    num_bytes = 1024 * 10
-    bps = 384000
-    request_count = 2
-    request_counter = lambda: request_count
-    f = StringIO.StringIO(' ' * num_bytes)
-    limited_f = proxyshaper.RateLimitedFile(request_counter, f, bps)
-    start = proxyshaper.TIMER()
-    limited_f.write(' ' * num_bytes)
-    self.assertEqual(num_bytes, len(limited_f.getvalue()))
-    expected_ms = 8.0 * num_bytes / (bps / float(request_count)) * 1000.0
-    actual_ms = (proxyshaper.TIMER() - start) * 1000.0
-    self.assertValuesAlmostEqual(expected_ms, actual_ms)
-
-
-class GetBitsPerSecondTest(unittest.TestCase):
-  def testConvertsValidValues(self):
-    for dummynet_option, expected_bps in VALID_RATES:
-      bps = proxyshaper.GetBitsPerSecond(dummynet_option)
-      self.assertEqual(
-          expected_bps, bps, 'Unexpected result for %s: %s != %s' % (
-              dummynet_option, expected_bps, bps))
-
-  def testRaisesOnUnexpectedValues(self):
-    for dummynet_option in ERROR_RATES:
-      self.assertRaises(proxyshaper.BandwidthValueError,
-                        proxyshaper.GetBitsPerSecond, dummynet_option)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/pylintrc b/catapult/telemetry/third_party/web-page-replay/pylintrc
deleted file mode 100644
index 27c3925..0000000
--- a/catapult/telemetry/third_party/web-page-replay/pylintrc
+++ /dev/null
@@ -1,17 +0,0 @@
-[MESSAGES CONTROL]
-
-# Disable the message, report, category or checker with the given id(s).
-# TODO(wpr-owners): Reduce this list to as small as possible.
-disable=I0010,I0011,abstract-class-little-used,abstract-class-not-used,anomalous-backslash-in-string,bad-builtin,bad-context-manager,bad-continuation,bad-str-strip-call,broad-except,cell-var-from-loop,deprecated-lambda,deprecated-module,duplicate-code,eval-used,exec-used,fixme,function-redefined,global-statement,interface-not-implemented,invalid-name,locally-enabled,logging-not-lazy,missing-docstring,missing-final-newline,no-init,no-member,no-name-in-module,no-self-use,no-self-use,not-callable,star-args,too-few-public-methods,too-many-ancestors,too-many-arguments,too-many-branches,too-many-function-args,too-many-instance-attributes,too-many-lines,too-many-locals,too-many-public-methods,too-many-return-statements,too-many-statements,useless-else-on-loop,unused-variable,attribute-defined-outside-init,protected-access
-
-
-[REPORTS]
-
-# Don't write out full reports, just messages.
-reports=no
-
-
-[FORMAT]
-
-# We use two spaces for indents, instead of the usual four spaces or tab.
-indent-string='  '
diff --git a/catapult/telemetry/third_party/web-page-replay/replay.py b/catapult/telemetry/third_party/web-page-replay/replay.py
deleted file mode 100755
index f748ef7..0000000
--- a/catapult/telemetry/third_party/web-page-replay/replay.py
+++ /dev/null
@@ -1,563 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Replays web pages under simulated network conditions.
-
-Must be run as administrator (sudo).
-
-To record web pages:
-  1. Start the program in record mode.
-     $ sudo ./replay.py --record archive.wpr
-  2. Load the web pages you want to record in a web browser. It is important to
-     clear browser caches before this so that all subresources are requested
-     from the network.
-  3. Kill the process to stop recording.
-
-To replay web pages:
-  1. Start the program in replay mode with a previously recorded archive.
-     $ sudo ./replay.py archive.wpr
-  2. Load recorded pages in a web browser. A 404 will be served for any pages or
-     resources not in the recorded archive.
-
-Network simulation examples:
-  # 128KByte/s uplink bandwidth, 4Mbps/s downlink bandwidth with 100ms RTT time
-  $ sudo ./replay.py --up 128KByte/s --down 4Mbit/s --delay_ms=100 archive.wpr
-
-  # 1% packet loss rate
-  $ sudo ./replay.py --packet_loss_rate=0.01 archive.wpr
-"""
-
-import argparse
-import json
-import logging
-import os
-import socket
-import sys
-import traceback
-
-import customhandlers
-import dnsproxy
-import httparchive
-import httpclient
-import httpproxy
-import net_configs
-import platformsettings
-import rules_parser
-import script_injector
-import servermanager
-import trafficshaper
-
-if sys.version < '2.6':
-  print 'Need Python 2.6 or greater.'
-  sys.exit(1)
-
-
-def configure_logging(log_level_name, log_file_name=None):
-  """Configure logging level and format.
-
-  Args:
-    log_level_name: 'debug', 'info', 'warning', 'error', or 'critical'.
-    log_file_name: a file name
-  """
-  if logging.root.handlers:
-    logging.critical('A logging method (e.g. "logging.warn(...)")'
-                     ' was called before logging was configured.')
-  log_level = getattr(logging, log_level_name.upper())
-  log_format = (
-    '(%(levelname)s) %(asctime)s %(module)s.%(funcName)s:%(lineno)d  '
-    '%(message)s')
-
-
-  logging.basicConfig(level=log_level, format=log_format)
-  logger = logging.getLogger()
-  if log_file_name:
-    fh = logging.FileHandler(log_file_name)
-    fh.setLevel(log_level)
-    fh.setFormatter(logging.Formatter(log_format))
-    logger.addHandler(fh)
-  system_handler = platformsettings.get_system_logging_handler()
-  if system_handler:
-    logger.addHandler(system_handler)
-
-
-def AddDnsForward(server_manager, host):
-  """Forward DNS traffic."""
-  server_manager.Append(platformsettings.set_temporary_primary_nameserver, host)
-
-
-def AddDnsProxy(server_manager, options, host, port, real_dns_lookup,
-                http_archive):
-  dns_filters = []
-  if options.dns_private_passthrough:
-    private_filter = dnsproxy.PrivateIpFilter(real_dns_lookup, http_archive)
-    dns_filters.append(private_filter)
-    server_manager.AppendRecordCallback(private_filter.InitializeArchiveHosts)
-    server_manager.AppendReplayCallback(private_filter.InitializeArchiveHosts)
-  if options.shaping_dns:
-    delay_filter = dnsproxy.DelayFilter(options.record, **options.shaping_dns)
-    dns_filters.append(delay_filter)
-    server_manager.AppendRecordCallback(delay_filter.SetRecordMode)
-    server_manager.AppendReplayCallback(delay_filter.SetReplayMode)
-  server_manager.Append(dnsproxy.DnsProxyServer, host, port,
-                        dns_lookup=dnsproxy.ReplayDnsLookup(host, dns_filters))
-
-
-def AddWebProxy(server_manager, options, host, real_dns_lookup, http_archive):
-  if options.rules_path:
-    with open(options.rules_path) as file_obj:
-      allowed_imports = [
-          name.strip() for name in options.allowed_rule_imports.split(',')]
-      rules = rules_parser.Rules(file_obj, allowed_imports)
-    logging.info('Parsed %s rules:\n%s', options.rules_path, rules)
-  else:
-    rules = rules_parser.Rules()
-  injector = script_injector.GetScriptInjector(options.inject_scripts)
-  custom_handlers = customhandlers.CustomHandlers(options, http_archive)
-  custom_handlers.add_server_manager_handler(server_manager)
-  archive_fetch = httpclient.ControllableHttpArchiveFetch(
-      http_archive, real_dns_lookup,
-      injector,
-      options.diff_unknown_requests, options.record,
-      use_closest_match=options.use_closest_match,
-      scramble_images=options.scramble_images)
-  server_manager.AppendRecordCallback(archive_fetch.SetRecordMode)
-  server_manager.AppendReplayCallback(archive_fetch.SetReplayMode)
-  allow_generate_304 = not options.record
-  server_manager.Append(
-      httpproxy.HttpProxyServer,
-      archive_fetch, custom_handlers, rules,
-      host=host, port=options.port, use_delays=options.use_server_delay,
-      allow_generate_304=allow_generate_304,
-      **options.shaping_http)
-  if options.ssl:
-    if options.should_generate_certs:
-      server_manager.Append(
-          httpproxy.HttpsProxyServer, archive_fetch, custom_handlers, rules,
-          options.https_root_ca_cert_path, host=host, port=options.ssl_port,
-          allow_generate_304=allow_generate_304,
-          use_delays=options.use_server_delay, **options.shaping_http)
-    else:
-      server_manager.Append(
-          httpproxy.SingleCertHttpsProxyServer, archive_fetch,
-          custom_handlers, rules, options.https_root_ca_cert_path, host=host,
-          port=options.ssl_port, use_delays=options.use_server_delay,
-          allow_generate_304=allow_generate_304,
-          **options.shaping_http)
-  if options.http_to_https_port:
-    server_manager.Append(
-        httpproxy.HttpToHttpsProxyServer,
-        archive_fetch, custom_handlers, rules,
-        host=host, port=options.http_to_https_port,
-        use_delays=options.use_server_delay,
-        allow_generate_304=allow_generate_304,
-        **options.shaping_http)
-
-
-def AddTrafficShaper(server_manager, options, host):
-  if options.shaping_dummynet:
-    server_manager.AppendTrafficShaper(
-        trafficshaper.TrafficShaper, host=host,
-        use_loopback=not options.server_mode and host == '127.0.0.1',
-        **options.shaping_dummynet)
-
-
-class OptionsWrapper(object):
-  """Add checks, updates, and methods to option values.
-
-  Example:
-    options, args = arg_parser.parse_args()
-    options = OptionsWrapper(options, arg_parser)  # run checks and updates
-    if options.record and options.HasTrafficShaping():
-       [...]
-  """
-  _TRAFFICSHAPING_OPTIONS = {
-      'down', 'up', 'delay_ms', 'packet_loss_rate', 'init_cwnd', 'net'}
-  _CONFLICTING_OPTIONS = (
-      ('record', ('down', 'up', 'delay_ms', 'packet_loss_rate', 'net',
-                  'spdy', 'use_server_delay')),
-      ('append', ('down', 'up', 'delay_ms', 'packet_loss_rate', 'net',
-                  'use_server_delay')),  # same as --record
-      ('net', ('down', 'up', 'delay_ms')),
-      ('server', ('server_mode',)),
-  )
-
-  def __init__(self, options, parser):
-    self._options = options
-    self._parser = parser
-    self._nondefaults = set([
-        action.dest for action in parser._optionals._actions
-        if getattr(options, action.dest, action.default) is not action.default])
-    self._CheckConflicts()
-    self._CheckValidIp('host')
-    self._CheckFeatureSupport()
-    self._MassageValues()
-
-  def _CheckConflicts(self):
-    """Give an error if mutually exclusive options are used."""
-    for option, bad_options in self._CONFLICTING_OPTIONS:
-      if option in self._nondefaults:
-        for bad_option in bad_options:
-          if bad_option in self._nondefaults:
-            self._parser.error('Option --%s cannot be used with --%s.' %
-                                (bad_option, option))
-
-  def _CheckValidIp(self, name):
-    """Give an error if option |name| is not a valid IPv4 address."""
-    value = getattr(self._options, name)
-    if value:
-      try:
-        socket.inet_aton(value)
-      except Exception:
-        self._parser.error('Option --%s must be a valid IPv4 address.' % name)
-
-  def _CheckFeatureSupport(self):
-    if (self._options.should_generate_certs and
-        not platformsettings.HasSniSupport()):
-      self._parser.error('Option --should_generate_certs requires pyOpenSSL '
-                         '0.13 or greater for SNI support.')
-
-  def _ShapingKeywordArgs(self, shaping_key):
-    """Return the shaping keyword args for |shaping_key|.
-
-    Args:
-      shaping_key: one of 'dummynet', 'dns', 'http'.
-    Returns:
-      {}  # if shaping_key does not apply, or options have default values.
-      {k: v, ...}
-    """
-    kwargs = {}
-    def AddItemIfSet(d, kw_key, opt_key=None):
-      opt_key = opt_key or kw_key
-      if opt_key in self._nondefaults:
-        d[kw_key] = getattr(self, opt_key)
-    if ((self.shaping_type == 'proxy' and shaping_key in ('dns', 'http')) or
-        self.shaping_type == shaping_key):
-      AddItemIfSet(kwargs, 'delay_ms')
-      if shaping_key in ('dummynet', 'http'):
-        AddItemIfSet(kwargs, 'down_bandwidth', opt_key='down')
-        AddItemIfSet(kwargs, 'up_bandwidth', opt_key='up')
-        if shaping_key == 'dummynet':
-          AddItemIfSet(kwargs, 'packet_loss_rate')
-          AddItemIfSet(kwargs, 'init_cwnd')
-        elif self.shaping_type != 'none':
-          if 'packet_loss_rate' in self._nondefaults:
-            logging.warn('Shaping type, %s, ignores --packet_loss_rate=%s',
-                         self.shaping_type, self.packet_loss_rate)
-          if 'init_cwnd' in self._nondefaults:
-            logging.warn('Shaping type, %s, ignores --init_cwnd=%s',
-                         self.shaping_type, self.init_cwnd)
-    return kwargs
-
-  def _MassageValues(self):
-    """Set options that depend on the values of other options."""
-    if self.append and not self.record:
-      self._options.record = True
-    if self.net:
-      self._options.down, self._options.up, self._options.delay_ms = \
-          net_configs.GetNetConfig(self.net)
-      self._nondefaults.update(['down', 'up', 'delay_ms'])
-    if not self.ssl:
-      self._options.https_root_ca_cert_path = None
-    self.shaping_dns = self._ShapingKeywordArgs('dns')
-    self.shaping_http = self._ShapingKeywordArgs('http')
-    self.shaping_dummynet = self._ShapingKeywordArgs('dummynet')
-
-  def __getattr__(self, name):
-    """Make the original option values available."""
-    return getattr(self._options, name)
-
-  def __repr__(self):
-    """Return a json representation of the original options dictionary."""
-    return json.dumps(self._options.__dict__)
-
-  def IsRootRequired(self):
-    """Returns True iff the options require whole program root access."""
-    if self.server:
-      return True
-
-    def IsPrivilegedPort(port):
-      return port and port < 1024
-
-    if IsPrivilegedPort(self.port) or (self.ssl and
-                                       IsPrivilegedPort(self.ssl_port)):
-      return True
-
-    if self.dns_forwarding:
-      if IsPrivilegedPort(self.dns_port):
-        return True
-      if not self.server_mode and self.host == '127.0.0.1':
-        return True
-
-    return False
-
-
-def replay(options, replay_filename):
-  if options.record and sys.version_info < (2, 7, 9):
-    print ('Need Python 2.7.9 or greater for recording mode.\n'
-           'For instructions on how to upgrade Python on Ubuntu 14.04, see:\n'
-           'http://mbless.de/blog/2016/01/09/upgrade-to-python-2711-on-ubuntu-1404-lts.html\n')
-  if options.admin_check and options.IsRootRequired():
-    platformsettings.rerun_as_administrator()
-  configure_logging(options.log_level, options.log_file)
-  server_manager = servermanager.ServerManager(options.record)
-  if options.server:
-    AddDnsForward(server_manager, options.server)
-  else:
-    if options.record:
-      httparchive.HttpArchive.AssertWritable(replay_filename)
-      if options.append and os.path.exists(replay_filename):
-        http_archive = httparchive.HttpArchive.Load(replay_filename)
-        logging.info('Appending to %s (loaded %d existing responses)',
-                     replay_filename, len(http_archive))
-      else:
-        http_archive = httparchive.HttpArchive()
-    else:
-      http_archive = httparchive.HttpArchive.Load(replay_filename)
-      logging.info('Loaded %d responses from %s',
-                   len(http_archive), replay_filename)
-    server_manager.AppendRecordCallback(http_archive.clear)
-
-    ipfw_dns_host = None
-    if options.dns_forwarding or options.shaping_dummynet:
-      # compute the ip/host used for the DNS server and traffic shaping
-      ipfw_dns_host = options.host
-      if not ipfw_dns_host:
-        ipfw_dns_host = platformsettings.get_server_ip_address(
-            options.server_mode)
-
-    real_dns_lookup = dnsproxy.RealDnsLookup(
-        name_servers=[platformsettings.get_original_primary_nameserver()],
-        dns_forwarding=options.dns_forwarding,
-        proxy_host=ipfw_dns_host,
-        proxy_port=options.dns_port)
-    server_manager.AppendRecordCallback(real_dns_lookup.ClearCache)
-
-    if options.dns_forwarding:
-      if not options.server_mode and ipfw_dns_host == '127.0.0.1':
-        AddDnsForward(server_manager, ipfw_dns_host)
-      AddDnsProxy(server_manager, options, ipfw_dns_host, options.dns_port,
-                  real_dns_lookup, http_archive)
-    if options.ssl and options.https_root_ca_cert_path is None:
-      options.https_root_ca_cert_path = os.path.join(os.path.dirname(__file__),
-                                                     'wpr_cert.pem')
-    http_proxy_address = options.host
-    if not http_proxy_address:
-      http_proxy_address = platformsettings.get_httpproxy_ip_address(
-          options.server_mode)
-    AddWebProxy(server_manager, options, http_proxy_address, real_dns_lookup,
-                http_archive)
-    AddTrafficShaper(server_manager, options, ipfw_dns_host)
-
-  exit_status = 0
-  try:
-    server_manager.Run()
-  except KeyboardInterrupt:
-    logging.info('Shutting down.')
-  except (dnsproxy.DnsProxyException,
-          trafficshaper.TrafficShaperException,
-          platformsettings.NotAdministratorError,
-          platformsettings.DnsUpdateError) as e:
-    logging.critical('%s: %s', e.__class__.__name__, e)
-    exit_status = 1
-  except Exception:
-    logging.critical(traceback.format_exc())
-    exit_status = 2
-
-  if options.record:
-    http_archive.Persist(replay_filename)
-    logging.info('Saved %d responses to %s', len(http_archive), replay_filename)
-  return exit_status
-
-
-def GetParser():
-  arg_parser = argparse.ArgumentParser(
-      usage='%(prog)s [options] replay_file',
-      description=__doc__,
-      formatter_class=argparse.RawDescriptionHelpFormatter,
-      epilog='http://code.google.com/p/web-page-replay/')
-
-  arg_parser.add_argument('replay_filename', type=str, help='Replay file',
-                          nargs='?')
-
-  arg_parser.add_argument('-r', '--record', default=False,
-      action='store_true',
-      help='Download real responses and record them to replay_file')
-  arg_parser.add_argument('--append', default=False,
-      action='store_true',
-      help='Append responses to replay_file.')
-  arg_parser.add_argument('-l', '--log_level', default='debug',
-      action='store',
-      type=str,
-      choices=('debug', 'info', 'warning', 'error', 'critical'),
-      help='Minimum verbosity level to log')
-  arg_parser.add_argument('-f', '--log_file', default=None,
-      action='store',
-      type=str,
-      help='Log file to use in addition to writting logs to stderr.')
-
-  network_group = arg_parser.add_argument_group(
-      title='Network Simulation Options',
-      description=('These options configure the network simulation in '
-                   'replay mode'))
-  network_group.add_argument('-u', '--up', default='0',
-      action='store',
-      type=str,
-      help='Upload Bandwidth in [K|M]{bit/s|Byte/s}. Zero means unlimited.')
-  network_group.add_argument('-d', '--down', default='0',
-      action='store',
-      type=str,
-      help='Download Bandwidth in [K|M]{bit/s|Byte/s}. Zero means unlimited.')
-  network_group.add_argument('-m', '--delay_ms', default='0',
-      action='store',
-      type=str,
-      help='Propagation delay (latency) in milliseconds. Zero means no delay.')
-  network_group.add_argument('-p', '--packet_loss_rate', default='0',
-      action='store',
-      type=str,
-      help='Packet loss rate in range [0..1]. Zero means no loss.')
-  network_group.add_argument('-w', '--init_cwnd', default='0',
-      action='store',
-      type=str,
-      help='Set initial cwnd (linux only, requires kernel patch)')
-  network_group.add_argument('--net', default=None,
-      action='store',
-      type=str,
-      choices=net_configs.NET_CONFIG_NAMES,
-      help='Select a set of network options: %s.' % ', '.join(
-          net_configs.NET_CONFIG_NAMES))
-  network_group.add_argument('--shaping_type', default='dummynet',
-      action='store',
-      choices=('dummynet', 'proxy'),
-      help='When shaping is configured (i.e. --up, --down, etc.) decides '
-           'whether to use |dummynet| (default), or |proxy| servers.')
-
-  harness_group = arg_parser.add_argument_group(
-      title='Replay Harness Options',
-      description=('These advanced options configure various aspects '
-                   'of the replay harness'))
-  harness_group.add_argument('-S', '--server', default=None,
-      action='store',
-      type=str,
-      help='IP address of host running "replay.py --server_mode". '
-           'This only changes the primary DNS nameserver to use the given IP.')
-  harness_group.add_argument('-M', '--server_mode', default=False,
-      action='store_true',
-      help='Run replay DNS & http proxies, and trafficshaping on --port '
-           'without changing the primary DNS nameserver. '
-           'Other hosts may connect to this using "replay.py --server" '
-           'or by pointing their DNS to this server.')
-  harness_group.add_argument('-i', '--inject_scripts', default='deterministic.js',
-      action='store',
-      dest='inject_scripts',
-      help='A comma separated list of JavaScript sources to inject in all '
-           'pages. By default a script is injected that eliminates sources '
-           'of entropy such as Date() and Math.random() deterministic. '
-           'CAUTION: Without deterministic.js, many pages will not replay.')
-  harness_group.add_argument('-D', '--no-diff_unknown_requests', default=True,
-      action='store_false',
-      dest='diff_unknown_requests',
-      help='During replay, do not show a diff of unknown requests against '
-           'their nearest match in the archive.')
-  harness_group.add_argument('-C', '--use_closest_match', default=False,
-      action='store_true',
-      dest='use_closest_match',
-      help='During replay, if a request is not found, serve the closest match'
-           'in the archive instead of giving a 404.')
-  harness_group.add_argument('-U', '--use_server_delay', default=False,
-      action='store_true',
-      dest='use_server_delay',
-      help='During replay, simulate server delay by delaying response time to'
-           'requests.')
-  harness_group.add_argument('-I', '--screenshot_dir', default=None,
-      action='store',
-      type=str,
-      help='Save PNG images of the loaded page in the given directory.')
-  harness_group.add_argument('-P', '--no-dns_private_passthrough', default=True,
-      action='store_false',
-      dest='dns_private_passthrough',
-      help='Don\'t forward DNS requests that resolve to private network '
-           'addresses. CAUTION: With this option important services like '
-           'Kerberos will resolve to the HTTP proxy address.')
-  harness_group.add_argument('-x', '--no-dns_forwarding', default=True,
-      action='store_false',
-      dest='dns_forwarding',
-      help='Don\'t forward DNS requests to the local replay server. '
-           'CAUTION: With this option an external mechanism must be used to '
-           'forward traffic to the replay server.')
-  harness_group.add_argument('--host', default=None,
-      action='store',
-      type=str,
-      help='The IP address to bind all servers to. Defaults to 0.0.0.0 or '
-           '127.0.0.1, depending on --server_mode and platform.')
-  harness_group.add_argument('-o', '--port', default=80,
-      action='store',
-      type=int,
-      help='Port number to listen on.')
-  harness_group.add_argument('--ssl_port', default=443,
-      action='store',
-      type=int,
-      help='SSL port number to listen on.')
-  harness_group.add_argument('--http_to_https_port', default=None,
-      action='store',
-      type=int,
-      help='Port on which WPR will listen for HTTP requests that it will send '
-           'along as HTTPS requests.')
-  harness_group.add_argument('--dns_port', default=53,
-      action='store',
-      type=int,
-      help='DNS port number to listen on.')
-  harness_group.add_argument('-c', '--https_root_ca_cert_path', default=None,
-      action='store',
-      type=str,
-      help='Certificate file to use with SSL (gets auto-generated if needed).')
-  harness_group.add_argument('--no-ssl', default=True,
-      action='store_false',
-      dest='ssl',
-      help='Do not setup an SSL proxy.')
-  harness_group.add_argument('--should_generate_certs', default=False,
-      action='store_true',
-      help='Use OpenSSL to generate certificate files for requested hosts.')
-  harness_group.add_argument('--no-admin-check', default=True,
-      action='store_false',
-      dest='admin_check',
-      help='Do not check if administrator access is needed.')
-  harness_group.add_argument('--scramble_images', default=False,
-      action='store_true',
-      dest='scramble_images',
-      help='Scramble image responses.')
-  harness_group.add_argument('--rules_path', default=None,
-      action='store',
-      help='Path of file containing Python rules.')
-  harness_group.add_argument('--allowed_rule_imports', default='rules',
-      action='store',
-      help='A comma-separate list of allowed rule imports, or \'*\' to allow'
-           ' all packages.  Defaults to %(default)s.')
-  return arg_parser
-
-
-def main():
-  arg_parser = GetParser()
-  options = arg_parser.parse_args()
-  options = OptionsWrapper(options, arg_parser)
-
-  if options.server:
-    options.replay_filename = None
-  elif options.replay_filename is None:
-    arg_parser.error('Must specify a replay_file')
-  return replay(options, options.replay_filename)
-
-
-if __name__ == '__main__':
-  sys.exit(main())
diff --git a/catapult/telemetry/third_party/web-page-replay/replay_test.py b/catapult/telemetry/third_party/web-page-replay/replay_test.py
deleted file mode 100755
index fa7d8e1..0000000
--- a/catapult/telemetry/third_party/web-page-replay/replay_test.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unit tests for replay.
-
-Usage:
-$ ./replay_test.py
-"""
-
-import replay
-import unittest
-
-
-class MockOptions(dict):
-  """A dict with items that can be accessed as attributes."""
-  def __getattr__(self, name):
-    return self[name]
-
-
-class OptionsWrapperTest(unittest.TestCase):
-
-  def testNoTrafficShapingByDefault(self):
-    parser = replay.GetParser()
-    options = parser.parse_args([])
-    options = replay.OptionsWrapper(options, parser)
-    self.assertEqual({}, options.shaping_dns)
-    self.assertEqual({}, options.shaping_http)
-    self.assertEqual({}, options.shaping_dummynet)
-
-  def testShapingProxyWithoutOptionsGivesEmptySettings(self):
-    parser = replay.GetParser()
-    options = parser.parse_args(['--shaping=proxy'])
-    options = replay.OptionsWrapper(options, parser)
-    self.assertEqual({}, options.shaping_dns)
-    self.assertEqual({}, options.shaping_http)
-    self.assertEqual({}, options.shaping_dummynet)
-
-  def testShapingProxyWithNetOption(self):
-    parser = replay.GetParser()
-    options = parser.parse_args(['--shaping=proxy', '--net=cable'])
-    options = replay.OptionsWrapper(options, parser)
-    expected_http = {
-        'down_bandwidth': '5Mbit/s', 'delay_ms': '28', 'up_bandwidth': '1Mbit/s'
-        }
-    self.assertEqual({'delay_ms': '28'}, options.shaping_dns)
-    self.assertEqual(expected_http, options.shaping_http)
-    self.assertEqual({}, options.shaping_dummynet)
-
-  def testNetOptionUsesDummynetByDefault(self):
-    parser = replay.GetParser()
-    options = parser.parse_args(['--net=cable'])
-    options = replay.OptionsWrapper(options, parser)
-    expected_dummynet = {
-        'down_bandwidth': '5Mbit/s', 'delay_ms': '28', 'up_bandwidth': '1Mbit/s'
-        }
-    self.assertEqual({}, options.shaping_dns)
-    self.assertEqual({}, options.shaping_http)
-    self.assertEqual(expected_dummynet, options.shaping_dummynet)
-
-  def testPacketLossForDummynet(self):
-    parser = replay.GetParser()
-    options = parser.parse_args(['--packet_loss_rate=12'])
-    options = replay.OptionsWrapper(options, parser)
-    self.assertEqual({'packet_loss_rate': '12'}, options.shaping_dummynet)
-
-  def testIgnoredProxyShapingOptions(self):
-    parser = replay.GetParser()
-    options = parser.parse_args(
-        ['--packet_loss_rate=12', '--init_cwnd=10', '--shaping=proxy'])
-    options = replay.OptionsWrapper(options, parser)
-    self.assertEqual({}, options.shaping_dns)
-    self.assertEqual({}, options.shaping_http)
-    self.assertEqual({}, options.shaping_dummynet)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/requirements.txt b/catapult/telemetry/third_party/web-page-replay/requirements.txt
deleted file mode 100644
index 41b4fa1..0000000
--- a/catapult/telemetry/third_party/web-page-replay/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-pyOpenSSL==0.13
diff --git a/catapult/telemetry/third_party/web-page-replay/rules/__init__.py b/catapult/telemetry/third_party/web-page-replay/rules/__init__.py
deleted file mode 100644
index 3486216..0000000
--- a/catapult/telemetry/third_party/web-page-replay/rules/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-# Export rules for rules_parser access.
-from rules.log_url import LogUrl
diff --git a/catapult/telemetry/third_party/web-page-replay/rules/log_url.py b/catapult/telemetry/third_party/web-page-replay/rules/log_url.py
deleted file mode 100644
index 2f5ab21..0000000
--- a/catapult/telemetry/third_party/web-page-replay/rules/log_url.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import logging
-import re
-
-from rules import rule
-
-
-class LogUrl(rule.Rule):
-  """Logs the request URL."""
-
-  def __init__(self, url, stop=False):
-    r"""Initializes with a url pattern.
-
-    Args:
-      url: a string regex, e.g. r'example\.com/id=(\d{6})'.
-      stop:  boolean ApplyRule should_stop value, defaults to True.
-    """
-    self._url_re = re.compile(url)
-    self._stop = stop
-
-  def IsType(self, rule_type_name):
-    """Returns True if the name matches this rule."""
-    return rule_type_name == 'log_url'
-
-  def ApplyRule(self, return_value, request, response):
-    """Returns True if logged.
-
-    Args:
-      return_value: the prior log_url rule's return_value (if any).
-      request: the httparchive ArchivedHttpRequest.
-      response: the httparchive ArchivedHttpResponse.
-    Returns:
-      A (should_stop, return_value) tuple, e.g. (False, True).
-    """
-    del response  # unused.
-    url = '%s%s' % (request.host, request.full_path)
-    if not self._url_re.match(url):
-      return False, return_value
-
-    logging.debug('url: %s', url)
-    return self._stop, True
-
-  def __str__(self):
-    return _ToString(self, ('url', self._url_re.pattern),
-                     None if self._stop else ('stop', False))
-
-  def __repr__(self):
-    return str(self)
-
-
-def _ToString(obj, *items):
-  pkg = (obj.__module__[:obj.__module__.rfind('.') + 1]
-         if '.' in obj.__module__ else '')
-  clname = obj.__class__.__name__
-  args = [('%s=r\'%s\'' % item if isinstance(item[1], basestring)
-           else '%s=%s' % item) for item in items if item]
-  return '%s%s(%s)' % (pkg, clname, ', '.join(args))
diff --git a/catapult/telemetry/third_party/web-page-replay/rules/rule.py b/catapult/telemetry/third_party/web-page-replay/rules/rule.py
deleted file mode 100644
index 816b61b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/rules/rule.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-class Rule(object):
-  """An optional base class for rule implementations.
-
-  The rule_parser looks for the 'IsType' and 'ApplyRule' methods by name, so
-  rules are not strictly required to extend this class.
-  """
-
-  def IsType(self, rule_type_name):
-    """Returns True if the name matches this rule."""
-    raise NotImplementedError
-
-  def ApplyRule(self, return_value, request, response):
-    """Invokes this rule with the given args.
-
-    Args:
-      return_value: the prior rule's return_value (if any).
-      request: the httparchive ArchivedHttpRequest.
-      response: the httparchive ArchivedHttpResponse, which may be None.
-    Returns:
-      A (should_stop, return_value) tuple.  Typically the request and response
-        are treated as immutable, so it's the caller's job to apply the
-        return_value (e.g., set response fields).
-    """
-    raise NotImplementedError
diff --git a/catapult/telemetry/third_party/web-page-replay/rules_parser.py b/catapult/telemetry/third_party/web-page-replay/rules_parser.py
deleted file mode 100644
index 109db6d..0000000
--- a/catapult/telemetry/third_party/web-page-replay/rules_parser.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-r"""Rules parser.
-
-The input syntax is:
-  [{"comment": ignored_value},
-   {"rule_class_name1": {"arg1": value, "arg2": value, ...}},
-   {"rule_class_name2": {"arg1": value, "arg2": value, ...}},
-   ...]
-E.g.:
-  [{"comment": "this text is ignored"},
-   {"SendStatus": {"url": "example\\.com/ss.*", "status": 204}},
-   {"ModifyUrl": {"url": "(example\\.com)(/.*)", "new_url": "{1}"}}
-  ]
-"""
-
-import json
-import re
-
-
-class Error(Exception):
-  pass
-
-
-class Rules(object):
-
-  """A parsed sequence of Rule objects."""
-
-  def __init__(self, file_obj=None, allowed_imports=None):
-    """Initializes from the given file object.
-
-    Args:
-      file_obj: A file object.
-      allowed_imports: A set of strings, defaults to {'rules'}.
-        Use {'*'} to allow any import path.
-    """
-    if allowed_imports is None:
-      allowed_imports = {'rules'}
-    self._rules = [] if file_obj is None else _Load(file_obj, allowed_imports)
-
-  def Contains(self, rule_type_name):
-    """Returns true if any rule matches the given type name.
-
-    Args:
-      rule_type_name: a string.
-    Returns:
-      True if any rule matches, else False.
-    """
-    return any(rule for rule in self._rules if rule.IsType(rule_type_name))
-
-  def Find(self, rule_type_name):
-    """Returns a _Rule object containing all rules with the given type name.
-
-    Args:
-      rule_type_name: a string.
-    Returns:
-      A callable object that expects two arguments:
-        request: the httparchive ArchivedHttpRequest
-        response: the httparchive ArchivedHttpResponse
-      and returns the rule return_value of the first rule that returns
-      should_stop == True, or the last rule's return_value if all rules returns
-      should_stop == False.
-    """
-    matches = [rule for rule in self._rules if rule.IsType(rule_type_name)]
-    return _Rule(matches)
-
-  def __str__(self):
-    return _ToString(self._rules)
-
-  def __repr__(self):
-    return str(self)
-
-
-class _Rule(object):
-  """Calls a sequence of Rule objects until one returns should_stop."""
-
-  def __init__(self, rules):
-    self._rules = rules
-
-  def __call__(self, request, response):
-    """Calls the rules until one returns should_stop.
-
-    Args:
-      request: the httparchive ArchivedHttpRequest.
-      response: the httparchive ArchivedHttpResponse, which may be None.
-    Returns:
-      The rule return_value of the first rule that returns should_stop == True,
-      or the last rule's return_value if all rules return should_stop == False.
-    """
-    return_value = None
-    for rule in self._rules:
-      should_stop, return_value = rule.ApplyRule(
-          return_value, request, response)
-      if should_stop:
-        break
-    return return_value
-
-  def __str__(self):
-    return _ToString(self._rules)
-
-  def __repr__(self):
-    return str(self)
-
-
-def _ToString(rules):
-  """Formats a sequence of Rule objects into a string."""
-  return '[\n%s\n]' % '\n'.join('%s' % rule for rule in rules)
-
-
-def _Load(file_obj, allowed_imports):
-  """Parses and evaluates all rules in the given file.
-
-  Args:
-    file_obj: a file object.
-    allowed_imports: a sequence of strings, e.g.: {'rules'}.
-  Returns:
-    a list of rules.
-  """
-  rules = []
-  entries = json.load(file_obj)
-  if not isinstance(entries, list):
-    raise Error('Expecting a list, not %s', type(entries))
-  for i, entry in enumerate(entries):
-    if not isinstance(entry, dict):
-      raise Error('%s: Expecting a dict, not %s', i, type(entry))
-    if len(entry) != 1:
-      raise Error('%s: Expecting 1 item, not %d', i, len(entry))
-    name, args = next(entry.iteritems())
-    if not isinstance(name, basestring):
-      raise Error('%s: Expecting a string TYPE, not %s', i, type(name))
-    if not re.match(r'(\w+\.)*\w+$', name):
-      raise Error('%s: Expecting a classname TYPE, not %s', i, name)
-    if name == 'comment':
-      continue
-    if not isinstance(args, dict):
-      raise Error('%s: Expecting a dict ARGS, not %s', i, type(args))
-    fullname = str(name)
-    if '.' not in fullname:
-      fullname = 'rules.%s' % fullname
-
-    modulename, classname = fullname.rsplit('.', 1)
-    if '*' not in allowed_imports and modulename not in allowed_imports:
-      raise Error('%s: Package %r is not in allowed_imports', i, modulename)
-
-    module = __import__(modulename, fromlist=[classname])
-    clazz = getattr(module, classname)
-
-    missing = {s for s in ('IsType', 'ApplyRule') if not hasattr(clazz, s)}
-    if missing:
-      raise Error('%s: %s lacks %s', i, clazz.__name__, ' and '.join(missing))
-
-    rule = clazz(**args)
-
-    rules.append(rule)
-  return rules
diff --git a/catapult/telemetry/third_party/web-page-replay/rules_parser_test.py b/catapult/telemetry/third_party/web-page-replay/rules_parser_test.py
deleted file mode 100755
index bc20d80..0000000
--- a/catapult/telemetry/third_party/web-page-replay/rules_parser_test.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2015 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unit tests for rules_parser.  Usage: ./rules_parser_test.py"""
-
-import collections
-import logging
-from StringIO import StringIO
-import unittest
-
-import rules_parser
-
-
-class RuleParserTest(unittest.TestCase):
-
-  @classmethod
-  def setUpClass(cls):
-    if not logging.root.handlers:
-      logging.basicConfig(level=logging.DEBUG,  # Enable log_url stdout.
-                          format='%(asctime)s %(levelname)s %(message)s')
-
-  def testCall(self):
-    my_rules = rules_parser.Rules(StringIO(r'''
-        [{"comment": "ignore me"},
-         {"LogUrl": {"url": "example\\.com/ss.*"}},
-         {"LogUrl": {"url": "example\\.com/blah$"}}]'''))
-    log_url = my_rules.Find('log_url')
-    self.assertEquals(True, log_url(FakeRequest(full_path='/ss'), None))
-    self.assertEquals(True, log_url(FakeRequest(full_path='/ssxxxx'), None))
-    self.assertEquals(True, log_url(FakeRequest(full_path='/blah'), None))
-    self.assertEquals(None, log_url(FakeRequest(full_path='/blahxxx'), None))
-    self.assertEquals(None, log_url(FakeRequest(full_path='/'), None))
-
-  def testImport(self):
-    my_rules = rules_parser.Rules(StringIO(r'''
-        [{"rules.LogUrl": {"url": "example\\.com/ss.*"}}]'''))
-    self.assertTrue(my_rules.Contains('log_url'))
-
-  def testRaises(self):
-    input_pairs = [
-        'bad_json',
-        '123',
-        '{}',
-        '[42]',
-        '[{12:34}]',
-        '[{"a":"b","c":"d"}]',
-        '[{"bad+rule@name":{}}]',
-        '["unallowed.Path":{}]',
-        '["NoSuchRule":{}]',
-        '["LogUrl":"bad"]',
-        '["LogUrl":{}]',
-        '["LogUrl":{"url":123}]',
-        '["LogUrl":{"url":"", "bad_arg":123}]',
-    ]
-    for input_text in input_pairs:
-      self.assertRaises(Exception, rules_parser.Rules, StringIO(input_text))
-
-
-class FakeRequest(collections.namedtuple(
-    'FakeRequest', ('command', 'host', 'full_path', 'request_body',
-                    'headers', 'is_ssl'))):
-
-  def __new__(cls, command='GET', host='example.com', full_path='/',
-              request_body=None, headers=None, is_ssl=False):
-    return super(FakeRequest, cls).__new__(
-        cls, command, host, full_path, request_body, headers or {}, is_ssl)
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/run_tests b/catapult/telemetry/third_party/web-page-replay/run_tests
deleted file mode 100755
index 4f632d0..0000000
--- a/catapult/telemetry/third_party/web-page-replay/run_tests
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/usr/bin/env python
-import os
-import sys
-
-import test_runner
-
-_WPR_DIR = os.path.dirname(os.path.abspath(__file__))
-
-if __name__ == '__main__':
-  runner = test_runner.TestRunner()
-  runner.AddDirectory(_WPR_DIR)
-  sys.exit(runner.Main())
diff --git a/catapult/telemetry/third_party/web-page-replay/script_injector.py b/catapult/telemetry/third_party/web-page-replay/script_injector.py
deleted file mode 100644
index d845233..0000000
--- a/catapult/telemetry/third_party/web-page-replay/script_injector.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Inject javascript into html page source code."""
-
-import datetime
-import logging
-import os
-import re
-import util
-import third_party.jsmin as jsmin
-
-DOCTYPE_RE = re.compile(r'^.{,256}?(<!--.*-->)?.{,256}?<!doctype html>',
-                        re.IGNORECASE | re.DOTALL)
-HTML_RE = re.compile(r'^.{,256}?(<!--.*-->)?.{,256}?<html.*?>',
-                     re.IGNORECASE | re.DOTALL)
-HEAD_RE = re.compile(r'^.{,256}?(<!--.*-->)?.{,256}?<head.*?>',
-                     re.IGNORECASE | re.DOTALL)
-
-# Occurences of this marker in injected scripts will be replaced with
-# recording time in javascripts' Date().toValue() format.  This allows
-# to properly set deterministic date in JS code.  See
-# https://github.com/chromium/web-page-replay/issues/71 for details.
-TIME_SEED_MARKER = '{{WPR_TIME_SEED_TIMESTAMP}}'
-
-
-def GetScriptInjector(scripts):
-  """Loads |scripts| from disk and returns an injector of their content."""
-  lines = []
-  if scripts:
-    if not isinstance(scripts, list):
-      scripts = scripts.split(',')
-    for script in scripts:
-      if os.path.exists(script):
-        with open(script) as f:
-          lines.extend(f.read())
-      elif util.resource_exists(script):
-        lines.extend(util.resource_string(script))
-      else:
-        raise Exception('Script does not exist: %s', script)
-
-  script_template = jsmin.jsmin(''.join(lines), quote_chars="'\"`")
-  def injector(record_time):
-    delta = record_time - datetime.datetime(1970, 1, 1)
-    js_timestamp = \
-        int(delta.total_seconds()) * 1000 + delta.microseconds / 1000
-    return script_template.replace(TIME_SEED_MARKER, str(js_timestamp))
-  return injector
-
-
-def _IsHtmlContent(content):
-  content = content.strip()
-  return content.startswith('<') and content.endswith('>')
-
-
-def InjectScript(text_chunks, content_type, script_to_inject):
-  """Inject |script_to_inject| into |content| if |content_type| is 'text/html'.
-
-  Inject |script_to_inject| into |text_chunks| immediately after <head>,
-  <html> or <!doctype html>, if one of them is found. Otherwise, inject at
-  the beginning.
-
-  Returns:
-    text_chunks, already_injected
-    |text_chunks| is the new content if script is injected, otherwise
-      the original.  If the script was injected, exactly one chunk in
-      |text_chunks| will have changed.
-    |just_injected| indicates if |script_to_inject| was just injected in
-      the content.
-  """
-  if not content_type or content_type != 'text/html':
-    return text_chunks, False
-  content = "".join(text_chunks)
-  if not content or not _IsHtmlContent(content) or script_to_inject in content:
-    return text_chunks, False
-  for regexp in (HEAD_RE, HTML_RE, DOCTYPE_RE):
-    matchobj = regexp.search(content)
-    if matchobj:
-      pos = matchobj.end(0)
-      for i, chunk in enumerate(text_chunks):
-        if pos <= len(chunk):
-          result = text_chunks[:]
-          result[i] = '%s<script>%s</script>%s' % (chunk[0:pos],
-                                                   script_to_inject,
-                                                   chunk[pos:])
-          return result, True
-        pos -= len(chunk)
-  result = text_chunks[:]
-  result[0] = '<script>%s</script>%s' % (script_to_inject,
-                                         text_chunks[0])
-  logging.warning('Inject at the very beginning, because no tag of '
-                  '<head>, <html> or <!doctype html> is found.')
-  return result, True
diff --git a/catapult/telemetry/third_party/web-page-replay/script_injector_test.py b/catapult/telemetry/third_party/web-page-replay/script_injector_test.py
deleted file mode 100755
index 2a2ab50..0000000
--- a/catapult/telemetry/third_party/web-page-replay/script_injector_test.py
+++ /dev/null
@@ -1,148 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import datetime
-import httparchive
-import mock
-import script_injector
-import unittest
-
-
-LONG_COMMENT = '<!--' + 'comment,' * 200 + '-->'
-COMMENT_OR_NOT = ('', LONG_COMMENT)
-SCRIPT_TO_INJECT = 'var flag = 0;'
-EXPECTED_SCRIPT = '<script>' + SCRIPT_TO_INJECT + '</script>'
-TEXT_HTML = 'text/html'
-TEXT_CSS = 'text/css'
-APPLICATION = 'application/javascript'
-SEPARATOR = httparchive.ArchivedHttpResponse.CHUNK_EDIT_SEPARATOR
-SEPARATORS_OR_NOT = ('', SEPARATOR, SEPARATOR*3)
-
-TEMPLATE_HEAD = """\
-{boundary_at_start}\
-<!doc{boundary_in_doctype}type html>{boundary_after_doctype}\
-<ht{boundary_in_html}ml>{boundary_after_html}\
-<he{boundary_in_head}ad>{injection}{boundary_after_head}\
-</head></html>\
-"""
-TEMPLATE_HTML = """\
-{boundary_at_start}\
-<!doc{boundary_in_doctype}type html>{boundary_after_doctype}\
-<ht{boundary_in_html}ml>{injection}{boundary_after_html}\
-</html>\
-"""
-TEMPLATE_DOCTYPE = """\
-{boundary_at_start}\
-<!doc{boundary_in_doctype}type html>{injection}{boundary_after_doctype}\
-<body></body>\
-"""
-TEMPLATE_RAW = """\
-{boundary_at_start}\
-{injection}<body></body>\
-"""
-NORMAL_TEMPLATES = (TEMPLATE_HEAD, TEMPLATE_HTML,
-                    TEMPLATE_DOCTYPE, TEMPLATE_RAW)
-TEMPLATE_COMMENT = """\
-{comment_before_doctype}<!doctype html>{comment_after_doctype}\
-<html>{comment_after_html}<head>{injection}</head></html>\
-"""
-
-
-def _wrap_inject_script(source, application, script_to_inject):
-  text_chunks = source.split(SEPARATOR)
-  text_chunks, just_injected = script_injector.InjectScript(
-      text_chunks, application, script_to_inject)
-  result = SEPARATOR.join(text_chunks)
-  return result, just_injected
-
-
-class ScriptInjectorTest(unittest.TestCase):
-
-  def _assert_no_injection(self, source, application):
-    new_source, just_injected = _wrap_inject_script(
-        source, application, SCRIPT_TO_INJECT)
-    self.assertEqual(new_source, source)
-    self.assertFalse(just_injected)
-
-  def _assert_successful_injection(self, template):
-    source, just_injected = _wrap_inject_script(
-        template.format(injection=''), TEXT_HTML, SCRIPT_TO_INJECT)
-    self.assertEqual(source, template.format(injection=EXPECTED_SCRIPT))
-    self.assertTrue(just_injected)
-
-  def test_unsupported_content_type(self):
-    self._assert_no_injection('abc', TEXT_CSS)
-    self._assert_no_injection('abc', APPLICATION)
-
-  def test_empty_content_as_already_injected(self):
-    self._assert_no_injection('', TEXT_HTML)
-
-  def test_non_html_content_with_html_content_type(self):
-    self._assert_no_injection('{"test": 1"}', TEXT_HTML)
-
-  def test_already_injected(self):
-    parameters = {'injection': SCRIPT_TO_INJECT}
-    for template in NORMAL_TEMPLATES:
-      for parameters['boundary_at_start'] in SEPARATORS_OR_NOT:
-        for parameters['boundary_in_doctype'] in SEPARATORS_OR_NOT:
-          for parameters['boundary_after_doctype'] in SEPARATORS_OR_NOT:
-            for parameters['boundary_in_html'] in SEPARATORS_OR_NOT:
-              for parameters['boundary_after_html'] in SEPARATORS_OR_NOT:
-                for parameters['boundary_in_head'] in SEPARATORS_OR_NOT:
-                  for parameters['boundary_after_head'] in SEPARATORS_OR_NOT:
-                    source = template.format(**parameters)
-                    self._assert_no_injection(source, TEXT_HTML)
-
-  def test_normal(self):
-    parameters = {'injection': '{injection}'}
-    for template in NORMAL_TEMPLATES:
-      for parameters['boundary_at_start'] in SEPARATORS_OR_NOT:
-        for parameters['boundary_in_doctype'] in SEPARATORS_OR_NOT:
-          for parameters['boundary_after_doctype'] in SEPARATORS_OR_NOT:
-            for parameters['boundary_in_html'] in SEPARATORS_OR_NOT:
-              for parameters['boundary_after_html'] in SEPARATORS_OR_NOT:
-                for parameters['boundary_in_head'] in SEPARATORS_OR_NOT:
-                  for parameters['boundary_after_head'] in SEPARATORS_OR_NOT:
-                    template = template.format(**parameters)
-                    self._assert_successful_injection(template)
-
-  def test_comments(self):
-    parameters = {'injection': '{injection}'}
-    for parameters['comment_before_doctype'] in COMMENT_OR_NOT:
-      for parameters['comment_after_doctype'] in COMMENT_OR_NOT:
-        for parameters['comment_after_html'] in COMMENT_OR_NOT:
-          template = TEMPLATE_COMMENT.format(**parameters)
-          self._assert_successful_injection(template)
-
-  @mock.patch('script_injector.os.path.exists', return_value=True)
-  @mock.patch('script_injector.open',
-              mock.mock_open(read_data='var time_seed = 123;'))
-  def test_injection_function(self, _):
-    injector = script_injector.GetScriptInjector('to_inject.js')
-    self.assertEqual('var time_seed=123;',
-                     injector(datetime.datetime.utcnow()))
-
-  @mock.patch('script_injector.os.path.exists', return_value=True)
-  @mock.patch('script_injector.open',
-              mock.mock_open(
-                  read_data='var time_seed = {{WPR_TIME_SEED_TIMESTAMP}};'))
-  def test_time_seed_replacement(self, _):
-    date = datetime.datetime(2016, 11, 17)
-    injector = script_injector.GetScriptInjector('date.js')
-    self.assertEqual('var time_seed=1479340800000;', injector(date))
-
-
-if __name__ == '__main__':
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/servermanager.py b/catapult/telemetry/third_party/web-page-replay/servermanager.py
deleted file mode 100644
index 8bb9b3a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/servermanager.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2011 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Control "replay.py --server_mode" (e.g. switch from record to replay)."""
-
-import sys
-import time
-
-class ServerManager(object):
-  """Run servers until is removed or an exception is raised.
-
-  Servers start in the order they are appended and stop in the
-  opposite order. Servers are started by calling the initializer
-  passed to ServerManager.Append() and by calling __enter__(). Once an
-  server's initializer is called successfully, the __exit__() function
-  is guaranteed to be called when ServerManager.Run() completes.
-  """
-
-  def __init__(self, is_record_mode):
-    """Initialize a server manager."""
-    self.initializers = []
-    self.record_callbacks = []
-    self.replay_callbacks = []
-    self.traffic_shapers = []
-    self.is_record_mode = is_record_mode
-    self.should_exit = False
-
-  def Append(self, initializer, *init_args, **init_kwargs):
-    """Append a server to the end of the list to run.
-
-    Servers start in the order they are appended and stop in the
-    opposite order.
-
-    Args:
-      initializer: a function that returns a server instance.
-          A server needs to implement the with-statement interface.
-      init_args: positional arguments for the initializer.
-      init_args: keyword arguments for the initializer.
-    """
-    self.initializers.append((initializer, init_args, init_kwargs))
-
-  def AppendTrafficShaper(self, initializer, *init_args, **init_kwargs):
-    """Append a traffic shaper to the end of the list to run.
-
-    Args:
-      initializer: a function that returns a server instance.
-          A server needs to implement the with-statement interface.
-      init_args: positional arguments for the initializer.
-      init_args: keyword arguments for the initializer.
-    """
-    self.traffic_shapers.append((initializer, init_args, init_kwargs))
-
-  def AppendRecordCallback(self, func):
-    """Append a function to the list to call when switching to record mode.
-
-    Args:
-      func: a function that takes no arguments and returns no value.
-    """
-    self.record_callbacks.append(func)
-
-  def AppendReplayCallback(self, func):
-    """Append a function to the list to call when switching to replay mode.
-
-    Args:
-      func: a function that takes no arguments and returns no value.
-    """
-    self.replay_callbacks.append(func)
-
-  def IsRecordMode(self):
-    """Call all the functions that have been registered to enter replay mode."""
-    return self.is_record_mode
-
-  def SetRecordMode(self):
-    """Call all the functions that have been registered to enter record mode."""
-    self.is_record_mode = True
-    for record_func in self.record_callbacks:
-      record_func()
-
-  def SetReplayMode(self):
-    """Call all the functions that have been registered to enter replay mode."""
-    self.is_record_mode = False
-    for replay_func in self.replay_callbacks:
-      replay_func()
-
-  def Run(self):
-    """Create the servers and loop.
-
-    The loop quits if a server raises an exception.
-
-    Raises:
-      any exception raised by the servers
-    """
-    server_exits = []
-    server_ports = []
-    exception_info = (None, None, None)
-    try:
-      for initializer, init_args, init_kwargs in self.initializers:
-        server = initializer(*init_args, **init_kwargs)
-        if server:
-          server_exits.insert(0, server.__exit__)
-          server.__enter__()
-          if hasattr(server, 'server_port'):
-            server_ports.append(server.server_port)
-      for initializer, init_args, init_kwargs in self.traffic_shapers:
-        init_kwargs['ports'] = server_ports
-        shaper = initializer(*init_args, **init_kwargs)
-        if server:
-          server_exits.insert(0, shaper.__exit__)
-          shaper.__enter__()
-      while True:
-        time.sleep(1)
-        if self.should_exit:
-          break
-    except Exception:
-      exception_info = sys.exc_info()
-    finally:
-      for server_exit in server_exits:
-        try:
-          if server_exit(*exception_info):
-            exception_info = (None, None, None)
-        except Exception:
-          exception_info = sys.exc_info()
-      if exception_info != (None, None, None):
-        # pylint: disable=raising-bad-type
-        raise exception_info[0], exception_info[1], exception_info[2]
diff --git a/catapult/telemetry/third_party/web-page-replay/setup.py b/catapult/telemetry/third_party/web-page-replay/setup.py
deleted file mode 100644
index 4a177be..0000000
--- a/catapult/telemetry/third_party/web-page-replay/setup.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Creates a distributable python package.
-
-Creating new packages:
-  1. Generate the package, dist/webpagereplay-X.X.tar.gz:
-       python setup.py sdist
-  2. Upload the package file to the following:
-       http://code.google.com/p/web-page-replay/downloads/entry
-
-Installing packages:
-  $ easy_install http://web-page-replay.googlecode.com/files/webpagereplay-X.X.tar.gz
-  - The replay and httparchive commands are now on your PATH.
-"""
-
-import setuptools
-
-setuptools.setup(
-    name='webpagereplay',
-    version='1.1.2',
-    description='Record and replay web content',
-    author='Web Page Replay Project Authors',
-    author_email='web-page-replay-dev@googlegroups.com',
-    url='http://code.google.com/p/web-page-replay/',
-    license='Apache License 2.0',
-    install_requires=['dnspython>=1.8'],
-    packages=[
-        '',
-        'third_party',
-        'third_party.ipaddr'
-        ],
-    package_dir={'': '.'},
-    package_data={
-        '': ['*.js', '*.txt', 'COPYING', 'LICENSE'],
-        },
-    entry_points={
-        'console_scripts': [
-            'httparchive = httparchive:main',
-            'replay = replay:main',
-            ]
-        },
-    )
diff --git a/catapult/telemetry/third_party/web-page-replay/sslproxy.py b/catapult/telemetry/third_party/web-page-replay/sslproxy.py
deleted file mode 100755
index 06bb601..0000000
--- a/catapult/telemetry/third_party/web-page-replay/sslproxy.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Extends BaseHTTPRequestHandler with SSL certificate generation."""
-
-import logging
-import socket
-
-import certutils
-
-
-
-def _SetUpUsingDummyCert(handler):
-  """Sets up connection providing the certificate to the client.
-
-  This method handles Server Name Indication (SNI) using dummy certs.
-
-  Args:
-    handler: an instance of BaseHTTPServer.BaseHTTPRequestHandler that is used
-      by some instance of  BaseHTTPServer.HTTPServer.
-  """
-  # One of: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or TLSv1_METHOD
-  context = certutils.get_ssl_context()
-  def handle_servername(connection):
-    """A SNI callback that happens during do_handshake()."""
-    try:
-      host = connection.get_servername()
-      if host:
-        cert_str = (
-            handler.server.get_certificate(host))
-        new_context = certutils.get_ssl_context()
-        cert = certutils.load_cert(cert_str)
-        new_context.use_certificate(cert)
-        new_context.use_privatekey_file(handler.server.ca_cert_path)
-        connection.set_context(new_context)
-        return new_context
-      # else: fail with 'no shared cipher'
-    except Exception, e:
-      # Do not leak any exceptions or else openssl crashes.
-      logging.error('Exception in SNI handler: %s', e)
-
-  context.set_tlsext_servername_callback(handle_servername)
-  handler.connection = certutils.get_ssl_connection(context, handler.connection)
-  handler.connection.set_accept_state()
-  try:
-    handler.connection.do_handshake()
-  except certutils.Error, v:
-    host = handler.connection.get_servername()
-    if not host:
-      logging.error('Dropping request without SNI')
-      return ''
-    raise certutils.Error('SSL handshake error %s: %s' % (host, str(v)))
-
-  # Re-wrap the read/write streams with our new connection.
-  handler.rfile = socket._fileobject(handler.connection, 'rb', handler.rbufsize,
-                                  close=False)
-  handler.wfile = socket._fileobject(handler.connection, 'wb', handler.wbufsize,
-                                  close=False)
-
-
-def wrap_handler(handler_class):
-  """Wraps a BaseHTTPHandler with SSL MITM certificates."""
-  if certutils.openssl_import_error:
-    # pylint: disable=raising-bad-type
-    raise certutils.openssl_import_error
-
-  class WrappedHandler(handler_class):
-
-    def setup(self):
-      handler_class.setup(self)
-      _SetUpUsingDummyCert(self)
-
-    def finish(self):
-      handler_class.finish(self)
-      self.connection.shutdown()
-      self.connection.close()
-
-  return WrappedHandler
diff --git a/catapult/telemetry/third_party/web-page-replay/sslproxy_test.py b/catapult/telemetry/third_party/web-page-replay/sslproxy_test.py
deleted file mode 100644
index faea0bd..0000000
--- a/catapult/telemetry/third_party/web-page-replay/sslproxy_test.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# Copyright 2014 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Test routines to generate dummy certificates."""
-
-import BaseHTTPServer
-import shutil
-import signal
-import socket
-import tempfile
-import threading
-import time
-import unittest
-
-import certutils
-import sslproxy
-
-
-class Client(object):
-
-  def __init__(self, ca_cert_path, verify_cb, port, host_name='foo.com',
-               host='localhost'):
-    self.host_name = host_name
-    self.verify_cb = verify_cb
-    self.ca_cert_path = ca_cert_path
-    self.port = port
-    self.host_name = host_name
-    self.host = host
-    self.connection = None
-
-  def run_request(self):
-    context = certutils.get_ssl_context()
-    context.set_verify(certutils.VERIFY_PEER, self.verify_cb)  # Demand a cert
-    context.use_certificate_file(self.ca_cert_path)
-    context.load_verify_locations(self.ca_cert_path)
-
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    self.connection = certutils.get_ssl_connection(context, s)
-    self.connection.connect((self.host, self.port))
-    self.connection.set_tlsext_host_name(self.host_name)
-
-    try:
-      self.connection.send('\r\n\r\n')
-    finally:
-      self.connection.shutdown()
-      self.connection.close()
-
-
-class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
-  protocol_version = 'HTTP/1.1'  # override BaseHTTPServer setting
-
-  def handle_one_request(self):
-    """Handle a single HTTP request."""
-    self.raw_requestline = self.rfile.readline(65537)
-
-
-class WrappedErrorHandler(Handler):
-  """Wraps handler to verify expected sslproxy errors are being raised."""
-
-  def setup(self):
-    Handler.setup(self)
-    try:
-      sslproxy._SetUpUsingDummyCert(self)
-    except certutils.Error:
-      self.server.error_function = certutils.Error
-
-  def finish(self):
-    Handler.finish(self)
-    self.connection.shutdown()
-    self.connection.close()
-
-
-class DummyArchive(object):
-
-  def __init__(self):
-    pass
-
-
-class DummyFetch(object):
-
-  def __init__(self):
-    self.http_archive = DummyArchive()
-
-
-class Server(BaseHTTPServer.HTTPServer):
-  """SSL server."""
-
-  def __init__(self, ca_cert_path, use_error_handler=False, port=0,
-               host='localhost'):
-    self.ca_cert_path = ca_cert_path
-    with open(ca_cert_path, 'r') as ca_file:
-      self.ca_cert_str = ca_file.read()
-    self.http_archive_fetch = DummyFetch()
-    if use_error_handler:
-      self.HANDLER = WrappedErrorHandler
-    else:
-      self.HANDLER = sslproxy.wrap_handler(Handler)
-    try:
-      BaseHTTPServer.HTTPServer.__init__(self, (host, port), self.HANDLER)
-    except Exception, e:
-      raise RuntimeError('Could not start HTTPSServer on port %d: %s'
-                         % (port, e))
-
-  def __enter__(self):
-    thread = threading.Thread(target=self.serve_forever)
-    thread.daemon = True
-    thread.start()
-    return self
-
-  def cleanup(self):
-    try:
-      self.shutdown()
-    except KeyboardInterrupt:
-      pass
-
-  def __exit__(self, type_, value_, traceback_):
-    self.cleanup()
-
-  def get_certificate(self, host):
-    return certutils.generate_cert(self.ca_cert_str, '', host)
-
-
-class TestClient(unittest.TestCase):
-  _temp_dir = None
-
-  def setUp(self):
-    self._temp_dir = tempfile.mkdtemp(prefix='sslproxy_', dir='/tmp')
-    self.ca_cert_path = self._temp_dir + 'testCA.pem'
-    self.cert_path = self._temp_dir + 'testCA-cert.cer'
-    self.wrong_ca_cert_path = self._temp_dir + 'wrong.pem'
-    self.wrong_cert_path = self._temp_dir + 'wrong-cert.cer'
-
-    # Write both pem and cer files for certificates
-    certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(),
-                                  cert_path=self.ca_cert_path)
-    certutils.write_dummy_ca_cert(*certutils.generate_dummy_ca_cert(),
-                                  cert_path=self.ca_cert_path)
-
-  def tearDown(self):
-    if self._temp_dir:
-      shutil.rmtree(self._temp_dir)
-
-  def verify_cb(self, conn, cert, errnum, depth, ok):
-    """A callback that verifies the certificate authentication worked.
-
-    Args:
-      conn: Connection object
-      cert: x509 object
-      errnum: possible error number
-      depth: error depth
-      ok: 1 if the authentication worked 0 if it didnt.
-    Returns:
-      1 or 0 depending on if the verification worked
-    """
-    self.assertFalse(cert.has_expired())
-    self.assertGreater(time.strftime('%Y%m%d%H%M%SZ', time.gmtime()),
-                       cert.get_notBefore())
-    return ok
-
-  def test_no_host(self):
-    with Server(self.ca_cert_path) as server:
-      c = Client(self.cert_path, self.verify_cb, server.server_port, '')
-      self.assertRaises(certutils.Error, c.run_request)
-
-  def test_client_connection(self):
-    with Server(self.ca_cert_path) as server:
-      c = Client(self.cert_path, self.verify_cb, server.server_port, 'foo.com')
-      c.run_request()
-
-      c = Client(self.cert_path, self.verify_cb, server.server_port,
-                 'random.host')
-      c.run_request()
-
-  def test_wrong_cert(self):
-    with Server(self.ca_cert_path, True) as server:
-      c = Client(self.wrong_cert_path, self.verify_cb, server.server_port,
-                 'foo.com')
-      self.assertRaises(certutils.Error, c.run_request)
-
-
-if __name__ == '__main__':
-  signal.signal(signal.SIGINT, signal.SIG_DFL)  # Exit on Ctrl-C
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/test_runner.py b/catapult/telemetry/third_party/web-page-replay/test_runner.py
deleted file mode 100644
index c8ca89f..0000000
--- a/catapult/telemetry/third_party/web-page-replay/test_runner.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import unittest
-import sys
-import os
-import optparse
-
-__all__ = []
-
-def FilterSuite(suite, predicate):
-  new_suite = suite.__class__()
-
-  for x in suite:
-    if isinstance(x, unittest.TestSuite):
-      subsuite = FilterSuite(x, predicate)
-      if subsuite.countTestCases() == 0:
-        continue
-
-      new_suite.addTest(subsuite)
-      continue
-
-    assert isinstance(x, unittest.TestCase)
-    if predicate(x):
-      new_suite.addTest(x)
-
-  return new_suite
-
-class _TestLoader(unittest.TestLoader):
-  def __init__(self, *args):
-    super(_TestLoader, self).__init__(*args)
-    self.discover_calls = []
-
-  def loadTestsFromModule(self, module, use_load_tests=True):
-    if module.__file__ != __file__:
-      return super(_TestLoader, self).loadTestsFromModule(
-          module, use_load_tests)
-
-    suite = unittest.TestSuite()
-    for discover_args in self.discover_calls:
-      subsuite = self.discover(*discover_args)
-      suite.addTest(subsuite)
-    return suite
-
-class _RunnerImpl(unittest.TextTestRunner):
-  def __init__(self, filters):
-    super(_RunnerImpl, self).__init__(verbosity=2)
-    self.filters = filters
-
-  def ShouldTestRun(self, test):
-    return not self.filters or any(name in test.id() for name in self.filters)
-
-  def run(self, suite):
-    filtered_test = FilterSuite(suite, self.ShouldTestRun)
-    return super(_RunnerImpl, self).run(filtered_test)
-
-
-class TestRunner(object):
-  def __init__(self):
-    self._loader = _TestLoader()
-
-  def AddDirectory(self, dir_path, test_file_pattern="*test.py"):
-    assert os.path.isdir(dir_path)
-
-    self._loader.discover_calls.append((dir_path, test_file_pattern, dir_path))
-
-  def Main(self, argv=None):
-    if argv is None:
-      argv = sys.argv
-
-    parser = optparse.OptionParser()
-    options, args = parser.parse_args(argv[1:])
-
-    runner = _RunnerImpl(filters=args)
-    return unittest.main(module=__name__, argv=[sys.argv[0]],
-                         testLoader=self._loader,
-                         testRunner=runner)
diff --git a/catapult/telemetry/third_party/web-page-replay/test_utils.py b/catapult/telemetry/third_party/web-page-replay/test_utils.py
deleted file mode 100644
index b76750e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/test_utils.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2016 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import unittest
-import urllib2
-
-
-def _IsInternetOn():
-  try:
-    urllib2.urlopen('https://example.com', timeout=10)
-    return True
-  except urllib2.URLError as err:
-    return False
-
-
-class RealNetworkFetchTest(unittest.TestCase):
-  def setUp(self):
-    if not _IsInternetOn():
-      self.skipTest('No internet, skip test')
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/__init__.py b/catapult/telemetry/third_party/web-page-replay/third_party/__init__.py
deleted file mode 100644
index ea60fc8..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/__init__.py
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import sys
-
-try:
-    __file__
-except NameError:
-    __file__ = sys.argv[0]
-third_party_dir = os.path.dirname(os.path.abspath(__file__))
-ipaddr_dir = os.path.join(third_party_dir, "ipaddr")
-sys.path.append(ipaddr_dir)  # workaround for no __init__.py
-import ipaddr
-
-# Modules in dns/ import sibling modules by "import dns/xxx", but
-# some platform has dns/ in global site-packages directory so we need to raise
-# the precedence of local search path (crbug/493869).
-# The implementation here preloads all dns/ modules into this package so clients
-# don't need to worry about import path issue.
-# An easier solution might be modify dns/ modules to use relative path, but I
-# tried not to touch third_party lib for now.
-sys.path.insert(0, third_party_dir)
-from dns import __all__ as all_dns_modules
-all_dns_modules = ['dns.' + m for m in  all_dns_modules]
-map(__import__, all_dns_modules)
-sys.path.pop(0)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/LICENSE b/catapult/telemetry/third_party/web-page-replay/third_party/dns/LICENSE
deleted file mode 100644
index 633c18c..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/LICENSE
+++ /dev/null
@@ -1,14 +0,0 @@
-Copyright (C) 2001-2003 Nominum, Inc.
-
-Permission to use, copy, modify, and distribute this software and its
-documentation for any purpose with or without fee is hereby granted,
-provided that the above copyright notice and this permission notice
-appear in all copies.
-
-THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/README.web-page-replay b/catapult/telemetry/third_party/web-page-replay/third_party/dns/README.web-page-replay
deleted file mode 100644
index 6d445fe..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/README.web-page-replay
+++ /dev/null
@@ -1,12 +0,0 @@
-Name: A DNS toolkit for Python
-Short Name: dnspython
-URL: http://www.dnspython.org/
-Version: 1.8.0 (found in ./version.py)
-License: ISC
-License File: LICENSE
-
-Description:
-Used by Web Page Replay's dnsproxy module to create and handle dns queries.
-
-Local Modifications:
-None.
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/__init__.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/__init__.py
deleted file mode 100644
index 5ad5737..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/__init__.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright (C) 2003-2007, 2009 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""dnspython DNS toolkit"""
-
-__all__ = [
-    'dnssec',
-    'e164',
-    'edns',
-    'entropy',
-    'exception',
-    'flags',
-    'inet',
-    'ipv4',
-    'ipv6',
-    'message',
-    'name',
-    'namedict',
-    'node',
-    'opcode',
-    'query',
-    'rcode',
-    'rdata',
-    'rdataclass',
-    'rdataset',
-    'rdatatype',
-    'renderer',
-    'resolver',
-    'reversename',
-    'rrset',
-    'set',
-    'tokenizer',
-    'tsig',
-    'tsigkeyring',
-    'ttl',
-    'rdtypes',
-    'update',
-    'version',
-    'zone',
-]
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/dnssec.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/dnssec.py
deleted file mode 100644
index 54fd78d..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/dnssec.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright (C) 2003-2007, 2009 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Common DNSSEC-related functions and constants."""
-
-RSAMD5 = 1
-DH = 2
-DSA = 3
-ECC = 4
-RSASHA1 = 5
-DSANSEC3SHA1 = 6
-RSASHA1NSEC3SHA1 = 7
-RSASHA256 = 8
-RSASHA512 = 10
-INDIRECT = 252
-PRIVATEDNS = 253
-PRIVATEOID = 254
-
-_algorithm_by_text = {
-    'RSAMD5' : RSAMD5,
-    'DH' : DH,
-    'DSA' : DSA,
-    'ECC' : ECC,
-    'RSASHA1' : RSASHA1,
-    'DSANSEC3SHA1' : DSANSEC3SHA1,
-    'RSASHA1NSEC3SHA1' : RSASHA1NSEC3SHA1,
-    'RSASHA256' : RSASHA256,
-    'RSASHA512' : RSASHA512,
-    'INDIRECT' : INDIRECT,
-    'PRIVATEDNS' : PRIVATEDNS,
-    'PRIVATEOID' : PRIVATEOID,
-    }
-
-# We construct the inverse mapping programmatically to ensure that we
-# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
-# would cause the mapping not to be true inverse.
-
-_algorithm_by_value = dict([(y, x) for x, y in _algorithm_by_text.iteritems()])
-
-class UnknownAlgorithm(Exception):
-    """Raised if an algorithm is unknown."""
-    pass
-
-def algorithm_from_text(text):
-    """Convert text into a DNSSEC algorithm value
-    @rtype: int"""
-    
-    value = _algorithm_by_text.get(text.upper())
-    if value is None:
-        value = int(text)
-    return value
-
-def algorithm_to_text(value):
-    """Convert a DNSSEC algorithm value to text
-    @rtype: string"""
-    
-    text = _algorithm_by_value.get(value)
-    if text is None:
-        text = str(value)
-    return text
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/e164.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/e164.py
deleted file mode 100644
index d8f71ec..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/e164.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (C) 2006, 2007, 2009 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS E.164 helpers
-
-@var public_enum_domain: The DNS public ENUM domain, e164.arpa.
-@type public_enum_domain: dns.name.Name object
-"""
-
-import dns.exception
-import dns.name
-import dns.resolver
-
-public_enum_domain = dns.name.from_text('e164.arpa.')
-
-def from_e164(text, origin=public_enum_domain):
-    """Convert an E.164 number in textual form into a Name object whose
-    value is the ENUM domain name for that number.
-    @param text: an E.164 number in textual form.
-    @type text: str
-    @param origin: The domain in which the number should be constructed.
-    The default is e164.arpa.
-    @type: dns.name.Name object or None
-    @rtype: dns.name.Name object
-    """
-    parts = [d for d in text if d.isdigit()]
-    parts.reverse()
-    return dns.name.from_text('.'.join(parts), origin=origin)
-
-def to_e164(name, origin=public_enum_domain, want_plus_prefix=True):
-    """Convert an ENUM domain name into an E.164 number.
-    @param name: the ENUM domain name.
-    @type name: dns.name.Name object.
-    @param origin: A domain containing the ENUM domain name.  The
-    name is relativized to this domain before being converted to text.
-    @type: dns.name.Name object or None
-    @param want_plus_prefix: if True, add a '+' to the beginning of the
-    returned number.
-    @rtype: str
-    """
-    if not origin is None:
-        name = name.relativize(origin)
-    dlabels = [d for d in name.labels if (d.isdigit() and len(d) == 1)]
-    if len(dlabels) != len(name.labels):
-        raise dns.exception.SyntaxError('non-digit labels in ENUM domain name')
-    dlabels.reverse()
-    text = ''.join(dlabels)
-    if want_plus_prefix:
-        text = '+' + text
-    return text
-
-def query(number, domains, resolver=None):
-    """Look for NAPTR RRs for the specified number in the specified domains.
-
-    e.g. lookup('16505551212', ['e164.dnspython.org.', 'e164.arpa.'])
-    """
-    if resolver is None:
-        resolver = dns.resolver.get_default_resolver()
-    for domain in domains:
-        if isinstance(domain, (str, unicode)):
-            domain = dns.name.from_text(domain)
-        qname = dns.e164.from_e164(number, domain)
-        try:
-            return resolver.query(qname, 'NAPTR')
-        except dns.resolver.NXDOMAIN:
-            pass
-    raise dns.resolver.NXDOMAIN
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/edns.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/edns.py
deleted file mode 100644
index 1731ced..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/edns.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# Copyright (C) 2009 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""EDNS Options"""
-
-NSID = 3
-
-class Option(object):
-    """Base class for all EDNS option types.
-    """
-
-    def __init__(self, otype):
-        """Initialize an option.
-        @param rdtype: The rdata type
-        @type rdtype: int
-        """
-        self.otype = otype
-
-    def to_wire(self, file):
-        """Convert an option to wire format.
-        """
-        raise NotImplementedError
-
-    def from_wire(cls, otype, wire, current, olen):
-        """Build an EDNS option object from wire format
-
-        @param otype: The option type
-        @type otype: int
-        @param wire: The wire-format message
-        @type wire: string
-        @param current: The offet in wire of the beginning of the rdata.
-        @type current: int
-        @param olen: The length of the wire-format option data
-        @type olen: int
-        @rtype: dns.ends.Option instance"""
-        raise NotImplementedError
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        """Compare an ENDS option with another option of the same type.
-        Return < 0 if self < other, 0 if self == other, and > 0 if self > other.
-        """
-        raise NotImplementedError
-
-    def __eq__(self, other):
-        if not isinstance(other, Option):
-            return False
-        if self.otype != other.otype:
-            return False
-        return self._cmp(other) == 0
-
-    def __ne__(self, other):
-        if not isinstance(other, Option):
-            return False
-        if self.otype != other.otype:
-            return False
-        return self._cmp(other) != 0
-
-    def __lt__(self, other):
-        if not isinstance(other, Option) or \
-               self.otype != other.otype:
-            return NotImplemented
-        return self._cmp(other) < 0
-
-    def __le__(self, other):
-        if not isinstance(other, Option) or \
-               self.otype != other.otype:
-            return NotImplemented
-        return self._cmp(other) <= 0
-
-    def __ge__(self, other):
-        if not isinstance(other, Option) or \
-               self.otype != other.otype:
-            return NotImplemented
-        return self._cmp(other) >= 0
-
-    def __gt__(self, other):
-        if not isinstance(other, Option) or \
-               self.otype != other.otype:
-            return NotImplemented
-        return self._cmp(other) > 0
-
-
-class GenericOption(Option):
-    """Generate Rdata Class
-
-    This class is used for EDNS option types for which we have no better
-    implementation.
-    """
-
-    def __init__(self, otype, data):
-        super(GenericOption, self).__init__(otype)
-        self.data = data
-
-    def to_wire(self, file):
-        file.write(self.data)
-
-    def from_wire(cls, otype, wire, current, olen):
-        return cls(otype, wire[current : current + olen])
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-	return cmp(self.data, other.data)
-
-_type_to_class = {
-}
-
-def get_option_class(otype):
-    cls = _type_to_class.get(otype)
-    if cls is None:
-        cls = GenericOption
-    return cls
-
-def option_from_wire(otype, wire, current, olen):
-    """Build an EDNS option object from wire format
-
-    @param otype: The option type
-    @type otype: int
-    @param wire: The wire-format message
-    @type wire: string
-    @param current: The offet in wire of the beginning of the rdata.
-    @type current: int
-    @param olen: The length of the wire-format option data
-    @type olen: int
-    @rtype: dns.ends.Option instance"""
-
-    cls = get_option_class(otype)
-    return cls.from_wire(otype, wire, current, olen)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/entropy.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/entropy.py
deleted file mode 100644
index fd9d4f8..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/entropy.py
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (C) 2009 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import os
-import time
-try:
-    import threading as _threading
-except ImportError:
-    import dummy_threading as _threading
-
-class EntropyPool(object):
-    def __init__(self, seed=None):
-        self.pool_index = 0
-        self.digest = None
-        self.next_byte = 0
-        self.lock = _threading.Lock()
-        try:
-            import hashlib
-            self.hash = hashlib.sha1()
-            self.hash_len = 20
-        except:
-            try:
-                import sha
-                self.hash = sha.new()
-                self.hash_len = 20
-            except:
-                import md5
-                self.hash = md5.new()
-                self.hash_len = 16
-        self.pool = '\0' * self.hash_len
-        if not seed is None:
-            self.stir(seed)
-            self.seeded = True
-        else:
-            self.seeded = False
-
-    def stir(self, entropy, already_locked=False):
-        if not already_locked:
-            self.lock.acquire()
-        try:
-            bytes = [ord(c) for c in self.pool]
-            for c in entropy:
-                if self.pool_index == self.hash_len:
-                    self.pool_index = 0
-                b = ord(c) & 0xff
-                bytes[self.pool_index] ^= b
-                self.pool_index += 1
-            self.pool = ''.join([chr(c) for c in bytes])
-        finally:
-            if not already_locked:
-                self.lock.release()
-
-    def _maybe_seed(self):
-        if not self.seeded:
-            try:
-                seed = os.urandom(16)
-            except:
-                try:
-                    r = file('/dev/urandom', 'r', 0)
-                    try:
-                        seed = r.read(16)
-                    finally:
-                        r.close()
-                except:
-                    seed = str(time.time())
-            self.seeded = True
-            self.stir(seed, True)
-
-    def random_8(self):
-        self.lock.acquire()
-        self._maybe_seed()
-        try:
-            if self.digest is None or self.next_byte == self.hash_len:
-                self.hash.update(self.pool)
-                self.digest = self.hash.digest()
-                self.stir(self.digest, True)
-                self.next_byte = 0
-            value = ord(self.digest[self.next_byte])
-            self.next_byte += 1
-        finally:
-            self.lock.release()
-        return value
-
-    def random_16(self):
-        return self.random_8() * 256 + self.random_8()
-
-    def random_32(self):
-        return self.random_16() * 65536 + self.random_16()
-
-    def random_between(self, first, last):
-        size = last - first + 1
-        if size > 4294967296L:
-            raise ValueError('too big')
-        if size > 65536:
-            rand = self.random_32
-            max = 4294967295L
-        elif size > 256:
-            rand = self.random_16
-            max = 65535
-        else:
-            rand = self.random_8
-            max = 255
-	return (first + size * rand() // (max + 1))
-
-pool = EntropyPool()
-
-def random_16():
-    return pool.random_16()
-
-def between(first, last):
-    return pool.random_between(first, last)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/exception.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/exception.py
deleted file mode 100644
index c6d6570..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/exception.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Common DNS Exceptions."""
-
-class DNSException(Exception):
-    """Abstract base class shared by all dnspython exceptions."""
-    pass
-
-class FormError(DNSException):
-    """DNS message is malformed."""
-    pass
-
-class SyntaxError(DNSException):
-    """Text input is malformed."""
-    pass
-
-class UnexpectedEnd(SyntaxError):
-    """Raised if text input ends unexpectedly."""
-    pass
-
-class TooBig(DNSException):
-    """The message is too big."""
-    pass
-
-class Timeout(DNSException):
-    """The operation timed out."""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/flags.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/flags.py
deleted file mode 100644
index 17afdbc..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/flags.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Message Flags."""
-
-# Standard DNS flags
-
-QR = 0x8000
-AA = 0x0400
-TC = 0x0200
-RD = 0x0100
-RA = 0x0080
-AD = 0x0020
-CD = 0x0010
-
-# EDNS flags
-
-DO = 0x8000
-
-_by_text = {
-    'QR' : QR,
-    'AA' : AA,
-    'TC' : TC,
-    'RD' : RD,
-    'RA' : RA,
-    'AD' : AD,
-    'CD' : CD
-}
-
-_edns_by_text = {
-    'DO' : DO
-}
-
-
-# We construct the inverse mappings programmatically to ensure that we
-# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
-# would cause the mappings not to be true inverses.
-
-_by_value = dict([(y, x) for x, y in _by_text.iteritems()])
-
-_edns_by_value = dict([(y, x) for x, y in _edns_by_text.iteritems()])
-
-def _order_flags(table):
-    order = list(table.iteritems())
-    order.sort()
-    order.reverse()
-    return order
-
-_flags_order = _order_flags(_by_value)
-
-_edns_flags_order = _order_flags(_edns_by_value)
-
-def _from_text(text, table):
-    flags = 0
-    tokens = text.split()
-    for t in tokens:
-        flags = flags | table[t.upper()]
-    return flags
-
-def _to_text(flags, table, order):
-    text_flags = []
-    for k, v in order:
-        if flags & k != 0:
-            text_flags.append(v)
-    return ' '.join(text_flags)
-
-def from_text(text):
-    """Convert a space-separated list of flag text values into a flags
-    value.
-    @rtype: int"""
-
-    return _from_text(text, _by_text)
-
-def to_text(flags):
-    """Convert a flags value into a space-separated list of flag text
-    values.
-    @rtype: string"""
-
-    return _to_text(flags, _by_value, _flags_order)
-    
-
-def edns_from_text(text):
-    """Convert a space-separated list of EDNS flag text values into a EDNS
-    flags value.
-    @rtype: int"""
-
-    return _from_text(text, _edns_by_text)
-
-def edns_to_text(flags):
-    """Convert an EDNS flags value into a space-separated list of EDNS flag
-    text values.
-    @rtype: string"""
-
-    return _to_text(flags, _edns_by_value, _edns_flags_order)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/inet.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/inet.py
deleted file mode 100644
index 8a8f3e1..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/inet.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Generic Internet address helper functions."""
-
-import socket
-
-import dns.ipv4
-import dns.ipv6
-
-
-# We assume that AF_INET is always defined.
-
-AF_INET = socket.AF_INET
-
-# AF_INET6 might not be defined in the socket module, but we need it.
-# We'll try to use the socket module's value, and if it doesn't work,
-# we'll use our own value.
-
-try:
-    AF_INET6 = socket.AF_INET6
-except AttributeError:
-    AF_INET6 = 9999
-
-def inet_pton(family, text):
-    """Convert the textual form of a network address into its binary form.
-
-    @param family: the address family
-    @type family: int
-    @param text: the textual address
-    @type text: string
-    @raises NotImplementedError: the address family specified is not
-    implemented.
-    @rtype: string
-    """
-    
-    if family == AF_INET:
-        return dns.ipv4.inet_aton(text)
-    elif family == AF_INET6:
-        return dns.ipv6.inet_aton(text)
-    else:
-        raise NotImplementedError
-
-def inet_ntop(family, address):
-    """Convert the binary form of a network address into its textual form.
-
-    @param family: the address family
-    @type family: int
-    @param address: the binary address
-    @type address: string
-    @raises NotImplementedError: the address family specified is not
-    implemented.
-    @rtype: string
-    """
-    if family == AF_INET:
-        return dns.ipv4.inet_ntoa(address)
-    elif family == AF_INET6:
-        return dns.ipv6.inet_ntoa(address)
-    else:
-        raise NotImplementedError
-
-def af_for_address(text):
-    """Determine the address family of a textual-form network address.
-
-    @param text: the textual address
-    @type text: string
-    @raises ValueError: the address family cannot be determined from the input.
-    @rtype: int
-    """
-    try:
-        junk = dns.ipv4.inet_aton(text)
-        return AF_INET
-    except:
-        try:
-            junk = dns.ipv6.inet_aton(text)
-            return AF_INET6
-        except:
-            raise ValueError
-
-def is_multicast(text):
-    """Is the textual-form network address a multicast address?
-
-    @param text: the textual address
-    @raises ValueError: the address family cannot be determined from the input.
-    @rtype: bool
-    """
-    try:
-        first = ord(dns.ipv4.inet_aton(text)[0])
-        return (first >= 224 and first <= 239)
-    except:
-        try:
-            first = ord(dns.ipv6.inet_aton(text)[0])
-            return (first == 255)
-        except:
-            raise ValueError
-    
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/ipv4.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/ipv4.py
deleted file mode 100644
index 1569da5..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/ipv4.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""IPv4 helper functions."""
-
-import socket
-import sys
-
-if sys.hexversion < 0x02030000 or sys.platform == 'win32':
-    #
-    # Some versions of Python 2.2 have an inet_aton which rejects
-    # the valid IP address '255.255.255.255'.  It appears this
-    # problem is still present on the Win32 platform even in 2.3.
-    # We'll work around the problem.
-    #
-    def inet_aton(text):
-        if text == '255.255.255.255':
-            return '\xff' * 4
-        else:
-            return socket.inet_aton(text)
-else:
-    inet_aton = socket.inet_aton
-
-inet_ntoa = socket.inet_ntoa
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/ipv6.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/ipv6.py
deleted file mode 100644
index 33c6713..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/ipv6.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""IPv6 helper functions."""
-
-import re
-
-import dns.exception
-import dns.ipv4
-
-_leading_zero = re.compile(r'0+([0-9a-f]+)')
-
-def inet_ntoa(address):
-    """Convert a network format IPv6 address into text.
-
-    @param address: the binary address
-    @type address: string
-    @rtype: string
-    @raises ValueError: the address isn't 16 bytes long
-    """
-
-    if len(address) != 16:
-        raise ValueError("IPv6 addresses are 16 bytes long")
-    hex = address.encode('hex_codec')
-    chunks = []
-    i = 0
-    l = len(hex)
-    while i < l:
-        chunk = hex[i : i + 4]
-        # strip leading zeros.  we do this with an re instead of
-        # with lstrip() because lstrip() didn't support chars until
-        # python 2.2.2
-        m = _leading_zero.match(chunk)
-        if not m is None:
-            chunk = m.group(1)
-        chunks.append(chunk)
-        i += 4
-    #
-    # Compress the longest subsequence of 0-value chunks to ::
-    #
-    best_start = 0
-    best_len = 0
-    start = -1
-    last_was_zero = False
-    for i in xrange(8):
-        if chunks[i] != '0':
-            if last_was_zero:
-                end = i
-                current_len = end - start
-                if current_len > best_len:
-                    best_start = start
-                    best_len = current_len
-                last_was_zero = False
-        elif not last_was_zero:
-            start = i
-            last_was_zero = True
-    if last_was_zero:
-        end = 8
-        current_len = end - start
-        if current_len > best_len:
-            best_start = start
-            best_len = current_len
-    if best_len > 0:
-        if best_start == 0 and \
-           (best_len == 6 or
-            best_len == 5 and chunks[5] == 'ffff'):
-            # We have an embedded IPv4 address
-            if best_len == 6:
-                prefix = '::'
-            else:
-                prefix = '::ffff:'
-            hex = prefix + dns.ipv4.inet_ntoa(address[12:])
-        else:
-            hex = ':'.join(chunks[:best_start]) + '::' + \
-                  ':'.join(chunks[best_start + best_len:])
-    else:
-        hex = ':'.join(chunks)
-    return hex
-
-_v4_ending = re.compile(r'(.*):(\d+)\.(\d+)\.(\d+)\.(\d+)$')
-_colon_colon_start = re.compile(r'::.*')
-_colon_colon_end = re.compile(r'.*::$')
-
-def inet_aton(text):
-    """Convert a text format IPv6 address into network format.
-
-    @param text: the textual address
-    @type text: string
-    @rtype: string
-    @raises dns.exception.SyntaxError: the text was not properly formatted
-    """
-
-    #
-    # Our aim here is not something fast; we just want something that works.
-    #
-
-    if text == '::':
-        text = '0::'
-    #
-    # Get rid of the icky dot-quad syntax if we have it.
-    #
-    m = _v4_ending.match(text)
-    if not m is None:
-        text = "%s:%04x:%04x" % (m.group(1),
-                                 int(m.group(2)) * 256 + int(m.group(3)),
-                                 int(m.group(4)) * 256 + int(m.group(5)))
-    #
-    # Try to turn '::<whatever>' into ':<whatever>'; if no match try to
-    # turn '<whatever>::' into '<whatever>:'
-    #
-    m = _colon_colon_start.match(text)
-    if not m is None:
-        text = text[1:]
-    else:
-        m = _colon_colon_end.match(text)
-        if not m is None:
-            text = text[:-1]
-    #
-    # Now canonicalize into 8 chunks of 4 hex digits each
-    #
-    chunks = text.split(':')
-    l = len(chunks)
-    if l > 8:
-        raise dns.exception.SyntaxError
-    seen_empty = False
-    canonical = []
-    for c in chunks:
-        if c == '':
-            if seen_empty:
-                raise dns.exception.SyntaxError
-            seen_empty = True
-            for i in xrange(0, 8 - l + 1):
-                canonical.append('0000')
-        else:
-            lc = len(c)
-            if lc > 4:
-                raise dns.exception.SyntaxError
-            if lc != 4:
-                c = ('0' * (4 - lc)) + c
-            canonical.append(c)
-    if l < 8 and not seen_empty:
-        raise dns.exception.SyntaxError
-    text = ''.join(canonical)
-
-    #
-    # Finally we can go to binary.
-    #
-    try:
-        return text.decode('hex_codec')
-    except TypeError:
-        raise dns.exception.SyntaxError
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/message.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/message.py
deleted file mode 100644
index ba0ebf6..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/message.py
+++ /dev/null
@@ -1,1083 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Messages"""
-
-import cStringIO
-import random
-import struct
-import sys
-import time
-
-import dns.exception
-import dns.flags
-import dns.name
-import dns.opcode
-import dns.entropy
-import dns.rcode
-import dns.rdata
-import dns.rdataclass
-import dns.rdatatype
-import dns.rrset
-import dns.renderer
-import dns.tsig
-
-class ShortHeader(dns.exception.FormError):
-    """Raised if the DNS packet passed to from_wire() is too short."""
-    pass
-
-class TrailingJunk(dns.exception.FormError):
-    """Raised if the DNS packet passed to from_wire() has extra junk
-    at the end of it."""
-    pass
-
-class UnknownHeaderField(dns.exception.DNSException):
-    """Raised if a header field name is not recognized when converting from
-    text into a message."""
-    pass
-
-class BadEDNS(dns.exception.FormError):
-    """Raised if an OPT record occurs somewhere other than the start of
-    the additional data section."""
-    pass
-
-class BadTSIG(dns.exception.FormError):
-    """Raised if a TSIG record occurs somewhere other than the end of
-    the additional data section."""
-    pass
-
-class UnknownTSIGKey(dns.exception.DNSException):
-    """Raised if we got a TSIG but don't know the key."""
-    pass
-
-class Message(object):
-    """A DNS message.
-
-    @ivar id: The query id; the default is a randomly chosen id.
-    @type id: int
-    @ivar flags: The DNS flags of the message.  @see: RFC 1035 for an
-    explanation of these flags.
-    @type flags: int
-    @ivar question: The question section.
-    @type question: list of dns.rrset.RRset objects
-    @ivar answer: The answer section.
-    @type answer: list of dns.rrset.RRset objects
-    @ivar authority: The authority section.
-    @type authority: list of dns.rrset.RRset objects
-    @ivar additional: The additional data section.
-    @type additional: list of dns.rrset.RRset objects
-    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
-    @type edns: int
-    @ivar ednsflags: The EDNS flags
-    @type ednsflags: long
-    @ivar payload: The EDNS payload size.  The default is 0.
-    @type payload: int
-    @ivar options: The EDNS options
-    @type options: list of dns.edns.Option objects
-    @ivar request_payload: The associated request's EDNS payload size.
-    @type request_payload: int
-    @ivar keyring: The TSIG keyring to use.  The default is None.
-    @type keyring: dict
-    @ivar keyname: The TSIG keyname to use.  The default is None.
-    @type keyname: dns.name.Name object
-    @ivar keyalgorithm: The TSIG key algorithm to use.  The default is
-    dns.tsig.default_algorithm.
-    @type keyalgorithm: string
-    @ivar request_mac: The TSIG MAC of the request message associated with
-    this message; used when validating TSIG signatures.   @see: RFC 2845 for
-    more information on TSIG fields.
-    @type request_mac: string
-    @ivar fudge: TSIG time fudge; default is 300 seconds.
-    @type fudge: int
-    @ivar original_id: TSIG original id; defaults to the message's id
-    @type original_id: int
-    @ivar tsig_error: TSIG error code; default is 0.
-    @type tsig_error: int
-    @ivar other_data: TSIG other data.
-    @type other_data: string
-    @ivar mac: The TSIG MAC for this message.
-    @type mac: string
-    @ivar xfr: Is the message being used to contain the results of a DNS
-    zone transfer?  The default is False.
-    @type xfr: bool
-    @ivar origin: The origin of the zone in messages which are used for
-    zone transfers or for DNS dynamic updates.  The default is None.
-    @type origin: dns.name.Name object
-    @ivar tsig_ctx: The TSIG signature context associated with this
-    message.  The default is None.
-    @type tsig_ctx: hmac.HMAC object
-    @ivar had_tsig: Did the message decoded from wire format have a TSIG
-    signature?
-    @type had_tsig: bool
-    @ivar multi: Is this message part of a multi-message sequence?  The
-    default is false.  This variable is used when validating TSIG signatures
-    on messages which are part of a zone transfer.
-    @type multi: bool
-    @ivar first: Is this message standalone, or the first of a multi
-    message sequence?  This variable is used when validating TSIG signatures
-    on messages which are part of a zone transfer.
-    @type first: bool
-    @ivar index: An index of rrsets in the message.  The index key is
-    (section, name, rdclass, rdtype, covers, deleting).  Indexing can be
-    disabled by setting the index to None.
-    @type index: dict
-    """
-
-    def __init__(self, id=None):
-        if id is None:
-            self.id = dns.entropy.random_16()
-        else:
-            self.id = id
-        self.flags = 0
-        self.question = []
-        self.answer = []
-        self.authority = []
-        self.additional = []
-        self.edns = -1
-        self.ednsflags = 0
-        self.payload = 0
-        self.options = []
-        self.request_payload = 0
-        self.keyring = None
-        self.keyname = None
-        self.keyalgorithm = dns.tsig.default_algorithm
-        self.request_mac = ''
-        self.other_data = ''
-        self.tsig_error = 0
-        self.fudge = 300
-        self.original_id = self.id
-        self.mac = ''
-        self.xfr = False
-        self.origin = None
-        self.tsig_ctx = None
-        self.had_tsig = False
-        self.multi = False
-        self.first = True
-        self.index = {}
-
-    def __repr__(self):
-        return '<DNS message, ID ' + `self.id` + '>'
-
-    def __str__(self):
-        return self.to_text()
-
-    def to_text(self,  origin=None, relativize=True, **kw):
-        """Convert the message to text.
-
-        The I{origin}, I{relativize}, and any other keyword
-        arguments are passed to the rrset to_wire() method.
-
-        @rtype: string
-        """
-
-        s = cStringIO.StringIO()
-        print >> s, 'id %d' % self.id
-        print >> s, 'opcode %s' % \
-              dns.opcode.to_text(dns.opcode.from_flags(self.flags))
-        rc = dns.rcode.from_flags(self.flags, self.ednsflags)
-        print >> s, 'rcode %s' % dns.rcode.to_text(rc)
-        print >> s, 'flags %s' % dns.flags.to_text(self.flags)
-        if self.edns >= 0:
-            print >> s, 'edns %s' % self.edns
-            if self.ednsflags != 0:
-                print >> s, 'eflags %s' % \
-                      dns.flags.edns_to_text(self.ednsflags)
-            print >> s, 'payload', self.payload
-        is_update = dns.opcode.is_update(self.flags)
-        if is_update:
-            print >> s, ';ZONE'
-        else:
-            print >> s, ';QUESTION'
-        for rrset in self.question:
-            print >> s, rrset.to_text(origin, relativize, **kw)
-        if is_update:
-            print >> s, ';PREREQ'
-        else:
-            print >> s, ';ANSWER'
-        for rrset in self.answer:
-            print >> s, rrset.to_text(origin, relativize, **kw)
-        if is_update:
-            print >> s, ';UPDATE'
-        else:
-            print >> s, ';AUTHORITY'
-        for rrset in self.authority:
-            print >> s, rrset.to_text(origin, relativize, **kw)
-        print >> s, ';ADDITIONAL'
-        for rrset in self.additional:
-            print >> s, rrset.to_text(origin, relativize, **kw)
-        #
-        # We strip off the final \n so the caller can print the result without
-        # doing weird things to get around eccentricities in Python print
-        # formatting
-        #
-        return s.getvalue()[:-1]
-
-    def __eq__(self, other):
-        """Two messages are equal if they have the same content in the
-        header, question, answer, and authority sections.
-        @rtype: bool"""
-        if not isinstance(other, Message):
-            return False
-        if self.id != other.id:
-            return False
-        if self.flags != other.flags:
-            return False
-        for n in self.question:
-            if n not in other.question:
-                return False
-        for n in other.question:
-            if n not in self.question:
-                return False
-        for n in self.answer:
-            if n not in other.answer:
-                return False
-        for n in other.answer:
-            if n not in self.answer:
-                return False
-        for n in self.authority:
-            if n not in other.authority:
-                return False
-        for n in other.authority:
-            if n not in self.authority:
-                return False
-        return True
-
-    def __ne__(self, other):
-        """Are two messages not equal?
-        @rtype: bool"""
-        return not self.__eq__(other)
-
-    def is_response(self, other):
-        """Is other a response to self?
-        @rtype: bool"""
-        if other.flags & dns.flags.QR == 0 or \
-           self.id != other.id or \
-           dns.opcode.from_flags(self.flags) != \
-           dns.opcode.from_flags(other.flags):
-            return False
-        if dns.rcode.from_flags(other.flags, other.ednsflags) != \
-               dns.rcode.NOERROR:
-            return True
-        if dns.opcode.is_update(self.flags):
-            return True
-        for n in self.question:
-            if n not in other.question:
-                return False
-        for n in other.question:
-            if n not in self.question:
-                return False
-        return True
-
-    def section_number(self, section):
-        if section is self.question:
-            return 0
-        elif section is self.answer:
-            return 1
-        elif section is self.authority:
-            return 2
-        elif section is self.additional:
-            return 3
-        else:
-            raise ValueError('unknown section')
-
-    def find_rrset(self, section, name, rdclass, rdtype,
-                   covers=dns.rdatatype.NONE, deleting=None, create=False,
-                   force_unique=False):
-        """Find the RRset with the given attributes in the specified section.
-
-        @param section: the section of the message to look in, e.g.
-        self.answer.
-        @type section: list of dns.rrset.RRset objects
-        @param name: the name of the RRset
-        @type name: dns.name.Name object
-        @param rdclass: the class of the RRset
-        @type rdclass: int
-        @param rdtype: the type of the RRset
-        @type rdtype: int
-        @param covers: the covers value of the RRset
-        @type covers: int
-        @param deleting: the deleting value of the RRset
-        @type deleting: int
-        @param create: If True, create the RRset if it is not found.
-        The created RRset is appended to I{section}.
-        @type create: bool
-        @param force_unique: If True and create is also True, create a
-        new RRset regardless of whether a matching RRset exists already.
-        @type force_unique: bool
-        @raises KeyError: the RRset was not found and create was False
-        @rtype: dns.rrset.RRset object"""
-
-        key = (self.section_number(section),
-               name, rdclass, rdtype, covers, deleting)
-        if not force_unique:
-            if not self.index is None:
-                rrset = self.index.get(key)
-                if not rrset is None:
-                    return rrset
-            else:
-                for rrset in section:
-                    if rrset.match(name, rdclass, rdtype, covers, deleting):
-                        return rrset
-        if not create:
-            raise KeyError
-        rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting)
-        section.append(rrset)
-        if not self.index is None:
-            self.index[key] = rrset
-        return rrset
-
-    def get_rrset(self, section, name, rdclass, rdtype,
-                  covers=dns.rdatatype.NONE, deleting=None, create=False,
-                  force_unique=False):
-        """Get the RRset with the given attributes in the specified section.
-
-        If the RRset is not found, None is returned.
-
-        @param section: the section of the message to look in, e.g.
-        self.answer.
-        @type section: list of dns.rrset.RRset objects
-        @param name: the name of the RRset
-        @type name: dns.name.Name object
-        @param rdclass: the class of the RRset
-        @type rdclass: int
-        @param rdtype: the type of the RRset
-        @type rdtype: int
-        @param covers: the covers value of the RRset
-        @type covers: int
-        @param deleting: the deleting value of the RRset
-        @type deleting: int
-        @param create: If True, create the RRset if it is not found.
-        The created RRset is appended to I{section}.
-        @type create: bool
-        @param force_unique: If True and create is also True, create a
-        new RRset regardless of whether a matching RRset exists already.
-        @type force_unique: bool
-        @rtype: dns.rrset.RRset object or None"""
-
-        try:
-            rrset = self.find_rrset(section, name, rdclass, rdtype, covers,
-                                    deleting, create, force_unique)
-        except KeyError:
-            rrset = None
-        return rrset
-
-    def to_wire(self, origin=None, max_size=0, **kw):
-        """Return a string containing the message in DNS compressed wire
-        format.
-
-        Additional keyword arguments are passed to the rrset to_wire()
-        method.
-
-        @param origin: The origin to be appended to any relative names.
-        @type origin: dns.name.Name object
-        @param max_size: The maximum size of the wire format output; default
-        is 0, which means 'the message's request payload, if nonzero, or
-        65536'.
-        @type max_size: int
-        @raises dns.exception.TooBig: max_size was exceeded
-        @rtype: string
-        """
-
-        if max_size == 0:
-            if self.request_payload != 0:
-                max_size = self.request_payload
-            else:
-                max_size = 65535
-        if max_size < 512:
-            max_size = 512
-        elif max_size > 65535:
-            max_size = 65535
-        r = dns.renderer.Renderer(self.id, self.flags, max_size, origin)
-        for rrset in self.question:
-            r.add_question(rrset.name, rrset.rdtype, rrset.rdclass)
-        for rrset in self.answer:
-            r.add_rrset(dns.renderer.ANSWER, rrset, **kw)
-        for rrset in self.authority:
-            r.add_rrset(dns.renderer.AUTHORITY, rrset, **kw)
-        if self.edns >= 0:
-            r.add_edns(self.edns, self.ednsflags, self.payload, self.options)
-        for rrset in self.additional:
-            r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw)
-        r.write_header()
-        if not self.keyname is None:
-            r.add_tsig(self.keyname, self.keyring[self.keyname],
-                       self.fudge, self.original_id, self.tsig_error,
-                       self.other_data, self.request_mac,
-                       self.keyalgorithm)
-            self.mac = r.mac
-        return r.get_wire()
-
-    def use_tsig(self, keyring, keyname=None, fudge=300,
-                 original_id=None, tsig_error=0, other_data='',
-                 algorithm=dns.tsig.default_algorithm):
-        """When sending, a TSIG signature using the specified keyring
-        and keyname should be added.
-
-        @param keyring: The TSIG keyring to use; defaults to None.
-        @type keyring: dict
-        @param keyname: The name of the TSIG key to use; defaults to None.
-        The key must be defined in the keyring.  If a keyring is specified
-        but a keyname is not, then the key used will be the first key in the
-        keyring.  Note that the order of keys in a dictionary is not defined,
-        so applications should supply a keyname when a keyring is used, unless
-        they know the keyring contains only one key.
-        @type keyname: dns.name.Name or string
-        @param fudge: TSIG time fudge; default is 300 seconds.
-        @type fudge: int
-        @param original_id: TSIG original id; defaults to the message's id
-        @type original_id: int
-        @param tsig_error: TSIG error code; default is 0.
-        @type tsig_error: int
-        @param other_data: TSIG other data.
-        @type other_data: string
-        @param algorithm: The TSIG algorithm to use; defaults to
-        dns.tsig.default_algorithm
-        """
-
-        self.keyring = keyring
-        if keyname is None:
-            self.keyname = self.keyring.keys()[0]
-        else:
-            if isinstance(keyname, (str, unicode)):
-                keyname = dns.name.from_text(keyname)
-            self.keyname = keyname
-        self.keyalgorithm = algorithm
-        self.fudge = fudge
-        if original_id is None:
-            self.original_id = self.id
-        else:
-            self.original_id = original_id
-        self.tsig_error = tsig_error
-        self.other_data = other_data
-
-    def use_edns(self, edns=0, ednsflags=0, payload=1280, request_payload=None, options=None):
-        """Configure EDNS behavior.
-        @param edns: The EDNS level to use.  Specifying None, False, or -1
-        means 'do not use EDNS', and in this case the other parameters are
-        ignored.  Specifying True is equivalent to specifying 0, i.e. 'use
-        EDNS0'.
-        @type edns: int or bool or None
-        @param ednsflags: EDNS flag values.
-        @type ednsflags: int
-        @param payload: The EDNS sender's payload field, which is the maximum
-        size of UDP datagram the sender can handle.
-        @type payload: int
-        @param request_payload: The EDNS payload size to use when sending
-        this message.  If not specified, defaults to the value of payload.
-        @type request_payload: int or None
-        @param options: The EDNS options
-        @type options: None or list of dns.edns.Option objects
-        @see: RFC 2671
-        """
-        if edns is None or edns is False:
-            edns = -1
-        if edns is True:
-            edns = 0
-        if request_payload is None:
-            request_payload = payload
-        if edns < 0:
-            ednsflags = 0
-            payload = 0
-            request_payload = 0
-            options = []
-        else:
-            # make sure the EDNS version in ednsflags agrees with edns
-            ednsflags &= 0xFF00FFFFL
-            ednsflags |= (edns << 16)
-            if options is None:
-                options = []
-        self.edns = edns
-        self.ednsflags = ednsflags
-        self.payload = payload
-        self.options = options
-        self.request_payload = request_payload
-
-    def want_dnssec(self, wanted=True):
-        """Enable or disable 'DNSSEC desired' flag in requests.
-        @param wanted: Is DNSSEC desired?  If True, EDNS is enabled if
-        required, and then the DO bit is set.  If False, the DO bit is
-        cleared if EDNS is enabled.
-        @type wanted: bool
-        """
-        if wanted:
-            if self.edns < 0:
-                self.use_edns()
-            self.ednsflags |= dns.flags.DO
-        elif self.edns >= 0:
-            self.ednsflags &= ~dns.flags.DO
-
-    def rcode(self):
-        """Return the rcode.
-        @rtype: int
-        """
-        return dns.rcode.from_flags(self.flags, self.ednsflags)
-
-    def set_rcode(self, rcode):
-        """Set the rcode.
-        @param rcode: the rcode
-        @type rcode: int
-        """
-        (value, evalue) = dns.rcode.to_flags(rcode)
-        self.flags &= 0xFFF0
-        self.flags |= value
-        self.ednsflags &= 0x00FFFFFFL
-        self.ednsflags |= evalue
-        if self.ednsflags != 0 and self.edns < 0:
-            self.edns = 0
-
-    def opcode(self):
-        """Return the opcode.
-        @rtype: int
-        """
-        return dns.opcode.from_flags(self.flags)
-
-    def set_opcode(self, opcode):
-        """Set the opcode.
-        @param opcode: the opcode
-        @type opcode: int
-        """
-        self.flags &= 0x87FF
-        self.flags |= dns.opcode.to_flags(opcode)
-
-class _WireReader(object):
-    """Wire format reader.
-
-    @ivar wire: the wire-format message.
-    @type wire: string
-    @ivar message: The message object being built
-    @type message: dns.message.Message object
-    @ivar current: When building a message object from wire format, this
-    variable contains the offset from the beginning of wire of the next octet
-    to be read.
-    @type current: int
-    @ivar updating: Is the message a dynamic update?
-    @type updating: bool
-    @ivar one_rr_per_rrset: Put each RR into its own RRset?
-    @type one_rr_per_rrset: bool
-    @ivar zone_rdclass: The class of the zone in messages which are
-    DNS dynamic updates.
-    @type zone_rdclass: int
-    """
-
-    def __init__(self, wire, message, question_only=False,
-                 one_rr_per_rrset=False):
-        self.wire = wire
-        self.message = message
-        self.current = 0
-        self.updating = False
-        self.zone_rdclass = dns.rdataclass.IN
-        self.question_only = question_only
-        self.one_rr_per_rrset = one_rr_per_rrset
-
-    def _get_question(self, qcount):
-        """Read the next I{qcount} records from the wire data and add them to
-        the question section.
-        @param qcount: the number of questions in the message
-        @type qcount: int"""
-
-        if self.updating and qcount > 1:
-            raise dns.exception.FormError
-
-        for i in xrange(0, qcount):
-            (qname, used) = dns.name.from_wire(self.wire, self.current)
-            if not self.message.origin is None:
-                qname = qname.relativize(self.message.origin)
-            self.current = self.current + used
-            (rdtype, rdclass) = \
-                     struct.unpack('!HH',
-                                   self.wire[self.current:self.current + 4])
-            self.current = self.current + 4
-            self.message.find_rrset(self.message.question, qname,
-                                    rdclass, rdtype, create=True,
-                                    force_unique=True)
-            if self.updating:
-                self.zone_rdclass = rdclass
-
-    def _get_section(self, section, count):
-        """Read the next I{count} records from the wire data and add them to
-        the specified section.
-        @param section: the section of the message to which to add records
-        @type section: list of dns.rrset.RRset objects
-        @param count: the number of records to read
-        @type count: int"""
-
-        if self.updating or self.one_rr_per_rrset:
-            force_unique = True
-        else:
-            force_unique = False
-        seen_opt = False
-        for i in xrange(0, count):
-            rr_start = self.current
-            (name, used) = dns.name.from_wire(self.wire, self.current)
-            absolute_name = name
-            if not self.message.origin is None:
-                name = name.relativize(self.message.origin)
-            self.current = self.current + used
-            (rdtype, rdclass, ttl, rdlen) = \
-                     struct.unpack('!HHIH',
-                                   self.wire[self.current:self.current + 10])
-            self.current = self.current + 10
-            if rdtype == dns.rdatatype.OPT:
-                if not section is self.message.additional or seen_opt:
-                    raise BadEDNS
-                self.message.payload = rdclass
-                self.message.ednsflags = ttl
-                self.message.edns = (ttl & 0xff0000) >> 16
-                self.message.options = []
-                current = self.current
-                optslen = rdlen
-                while optslen > 0:
-                    (otype, olen) = \
-                            struct.unpack('!HH',
-                                          self.wire[current:current + 4])
-                    current = current + 4
-                    opt = dns.edns.option_from_wire(otype, self.wire, current, olen)
-                    self.message.options.append(opt)
-                    current = current + olen
-                    optslen = optslen - 4 - olen
-                seen_opt = True
-            elif rdtype == dns.rdatatype.TSIG:
-                if not (section is self.message.additional and
-                        i == (count - 1)):
-                    raise BadTSIG
-                if self.message.keyring is None:
-                    raise UnknownTSIGKey('got signed message without keyring')
-                secret = self.message.keyring.get(absolute_name)
-                if secret is None:
-                    raise UnknownTSIGKey("key '%s' unknown" % name)
-                self.message.tsig_ctx = \
-                                      dns.tsig.validate(self.wire,
-                                          absolute_name,
-                                          secret,
-                                          int(time.time()),
-                                          self.message.request_mac,
-                                          rr_start,
-                                          self.current,
-                                          rdlen,
-                                          self.message.tsig_ctx,
-                                          self.message.multi,
-                                          self.message.first)
-                self.message.had_tsig = True
-            else:
-                if ttl < 0:
-                    ttl = 0
-                if self.updating and \
-                   (rdclass == dns.rdataclass.ANY or
-                    rdclass == dns.rdataclass.NONE):
-                    deleting = rdclass
-                    rdclass = self.zone_rdclass
-                else:
-                    deleting = None
-                if deleting == dns.rdataclass.ANY or \
-                   (deleting == dns.rdataclass.NONE and \
-                    section == self.message.answer):
-                    covers = dns.rdatatype.NONE
-                    rd = None
-                else:
-                    rd = dns.rdata.from_wire(rdclass, rdtype, self.wire,
-                                             self.current, rdlen,
-                                             self.message.origin)
-                    covers = rd.covers()
-                if self.message.xfr and rdtype == dns.rdatatype.SOA:
-                    force_unique = True
-                rrset = self.message.find_rrset(section, name,
-                                                rdclass, rdtype, covers,
-                                                deleting, True, force_unique)
-                if not rd is None:
-                    rrset.add(rd, ttl)
-            self.current = self.current + rdlen
-
-    def read(self):
-        """Read a wire format DNS message and build a dns.message.Message
-        object."""
-
-        l = len(self.wire)
-        if l < 12:
-            raise ShortHeader
-        (self.message.id, self.message.flags, qcount, ancount,
-         aucount, adcount) = struct.unpack('!HHHHHH', self.wire[:12])
-        self.current = 12
-        if dns.opcode.is_update(self.message.flags):
-            self.updating = True
-        self._get_question(qcount)
-        if self.question_only:
-            return
-        self._get_section(self.message.answer, ancount)
-        self._get_section(self.message.authority, aucount)
-        self._get_section(self.message.additional, adcount)
-        if self.current != l:
-            raise TrailingJunk
-        if self.message.multi and self.message.tsig_ctx and \
-               not self.message.had_tsig:
-            self.message.tsig_ctx.update(self.wire)
-
-
-def from_wire(wire, keyring=None, request_mac='', xfr=False, origin=None,
-              tsig_ctx = None, multi = False, first = True,
-              question_only = False, one_rr_per_rrset = False):
-    """Convert a DNS wire format message into a message
-    object.
-
-    @param keyring: The keyring to use if the message is signed.
-    @type keyring: dict
-    @param request_mac: If the message is a response to a TSIG-signed request,
-    I{request_mac} should be set to the MAC of that request.
-    @type request_mac: string
-    @param xfr: Is this message part of a zone transfer?
-    @type xfr: bool
-    @param origin: If the message is part of a zone transfer, I{origin}
-    should be the origin name of the zone.
-    @type origin: dns.name.Name object
-    @param tsig_ctx: The ongoing TSIG context, used when validating zone
-    transfers.
-    @type tsig_ctx: hmac.HMAC object
-    @param multi: Is this message part of a multiple message sequence?
-    @type multi: bool
-    @param first: Is this message standalone, or the first of a multi
-    message sequence?
-    @type first: bool
-    @param question_only: Read only up to the end of the question section?
-    @type question_only: bool
-    @param one_rr_per_rrset: Put each RR into its own RRset
-    @type one_rr_per_rrset: bool
-    @raises ShortHeader: The message is less than 12 octets long.
-    @raises TrailingJunk: There were octets in the message past the end
-    of the proper DNS message.
-    @raises BadEDNS: An OPT record was in the wrong section, or occurred more
-    than once.
-    @raises BadTSIG: A TSIG record was not the last record of the additional
-    data section.
-    @rtype: dns.message.Message object"""
-
-    m = Message(id=0)
-    m.keyring = keyring
-    m.request_mac = request_mac
-    m.xfr = xfr
-    m.origin = origin
-    m.tsig_ctx = tsig_ctx
-    m.multi = multi
-    m.first = first
-
-    reader = _WireReader(wire, m, question_only, one_rr_per_rrset)
-    reader.read()
-
-    return m
-
-
-class _TextReader(object):
-    """Text format reader.
-
-    @ivar tok: the tokenizer
-    @type tok: dns.tokenizer.Tokenizer object
-    @ivar message: The message object being built
-    @type message: dns.message.Message object
-    @ivar updating: Is the message a dynamic update?
-    @type updating: bool
-    @ivar zone_rdclass: The class of the zone in messages which are
-    DNS dynamic updates.
-    @type zone_rdclass: int
-    @ivar last_name: The most recently read name when building a message object
-    from text format.
-    @type last_name: dns.name.Name object
-    """
-
-    def __init__(self, text, message):
-        self.message = message
-        self.tok = dns.tokenizer.Tokenizer(text)
-        self.last_name = None
-        self.zone_rdclass = dns.rdataclass.IN
-        self.updating = False
-
-    def _header_line(self, section):
-        """Process one line from the text format header section."""
-
-        token = self.tok.get()
-        what = token.value
-        if what == 'id':
-            self.message.id = self.tok.get_int()
-        elif what == 'flags':
-            while True:
-                token = self.tok.get()
-                if not token.is_identifier():
-                    self.tok.unget(token)
-                    break
-                self.message.flags = self.message.flags | \
-                                     dns.flags.from_text(token.value)
-            if dns.opcode.is_update(self.message.flags):
-                self.updating = True
-        elif what == 'edns':
-            self.message.edns = self.tok.get_int()
-            self.message.ednsflags = self.message.ednsflags | \
-                                     (self.message.edns << 16)
-        elif what == 'eflags':
-            if self.message.edns < 0:
-                self.message.edns = 0
-            while True:
-                token = self.tok.get()
-                if not token.is_identifier():
-                    self.tok.unget(token)
-                    break
-                self.message.ednsflags = self.message.ednsflags | \
-                              dns.flags.edns_from_text(token.value)
-        elif what == 'payload':
-            self.message.payload = self.tok.get_int()
-            if self.message.edns < 0:
-                self.message.edns = 0
-        elif what == 'opcode':
-            text = self.tok.get_string()
-            self.message.flags = self.message.flags | \
-                      dns.opcode.to_flags(dns.opcode.from_text(text))
-        elif what == 'rcode':
-            text = self.tok.get_string()
-            self.message.set_rcode(dns.rcode.from_text(text))
-        else:
-            raise UnknownHeaderField
-        self.tok.get_eol()
-
-    def _question_line(self, section):
-        """Process one line from the text format question section."""
-
-        token = self.tok.get(want_leading = True)
-        if not token.is_whitespace():
-            self.last_name = dns.name.from_text(token.value, None)
-        name = self.last_name
-        token = self.tok.get()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError
-        # Class
-        try:
-            rdclass = dns.rdataclass.from_text(token.value)
-            token = self.tok.get()
-            if not token.is_identifier():
-                raise dns.exception.SyntaxError
-        except dns.exception.SyntaxError:
-            raise dns.exception.SyntaxError
-        except:
-            rdclass = dns.rdataclass.IN
-        # Type
-        rdtype = dns.rdatatype.from_text(token.value)
-        self.message.find_rrset(self.message.question, name,
-                                rdclass, rdtype, create=True,
-                                force_unique=True)
-        if self.updating:
-            self.zone_rdclass = rdclass
-        self.tok.get_eol()
-
-    def _rr_line(self, section):
-        """Process one line from the text format answer, authority, or
-        additional data sections.
-        """
-
-        deleting = None
-        # Name
-        token = self.tok.get(want_leading = True)
-        if not token.is_whitespace():
-            self.last_name = dns.name.from_text(token.value, None)
-        name = self.last_name
-        token = self.tok.get()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError
-        # TTL
-        try:
-            ttl = int(token.value, 0)
-            token = self.tok.get()
-            if not token.is_identifier():
-                raise dns.exception.SyntaxError
-        except dns.exception.SyntaxError:
-            raise dns.exception.SyntaxError
-        except:
-            ttl = 0
-        # Class
-        try:
-            rdclass = dns.rdataclass.from_text(token.value)
-            token = self.tok.get()
-            if not token.is_identifier():
-                raise dns.exception.SyntaxError
-            if rdclass == dns.rdataclass.ANY or rdclass == dns.rdataclass.NONE:
-                deleting = rdclass
-                rdclass = self.zone_rdclass
-        except dns.exception.SyntaxError:
-            raise dns.exception.SyntaxError
-        except:
-            rdclass = dns.rdataclass.IN
-        # Type
-        rdtype = dns.rdatatype.from_text(token.value)
-        token = self.tok.get()
-        if not token.is_eol_or_eof():
-            self.tok.unget(token)
-            rd = dns.rdata.from_text(rdclass, rdtype, self.tok, None)
-            covers = rd.covers()
-        else:
-            rd = None
-            covers = dns.rdatatype.NONE
-        rrset = self.message.find_rrset(section, name,
-                                        rdclass, rdtype, covers,
-                                        deleting, True, self.updating)
-        if not rd is None:
-            rrset.add(rd, ttl)
-
-    def read(self):
-        """Read a text format DNS message and build a dns.message.Message
-        object."""
-
-        line_method = self._header_line
-        section = None
-        while 1:
-            token = self.tok.get(True, True)
-            if token.is_eol_or_eof():
-                break
-            if token.is_comment():
-                u = token.value.upper()
-                if u == 'HEADER':
-                    line_method = self._header_line
-                elif u == 'QUESTION' or u == 'ZONE':
-                    line_method = self._question_line
-                    section = self.message.question
-                elif u == 'ANSWER' or u == 'PREREQ':
-                    line_method = self._rr_line
-                    section = self.message.answer
-                elif u == 'AUTHORITY' or u == 'UPDATE':
-                    line_method = self._rr_line
-                    section = self.message.authority
-                elif u == 'ADDITIONAL':
-                    line_method = self._rr_line
-                    section = self.message.additional
-                self.tok.get_eol()
-                continue
-            self.tok.unget(token)
-            line_method(section)
-
-
-def from_text(text):
-    """Convert the text format message into a message object.
-
-    @param text: The text format message.
-    @type text: string
-    @raises UnknownHeaderField:
-    @raises dns.exception.SyntaxError:
-    @rtype: dns.message.Message object"""
-
-    # 'text' can also be a file, but we don't publish that fact
-    # since it's an implementation detail.  The official file
-    # interface is from_file().
-
-    m = Message()
-
-    reader = _TextReader(text, m)
-    reader.read()
-
-    return m
-
-def from_file(f):
-    """Read the next text format message from the specified file.
-
-    @param f: file or string.  If I{f} is a string, it is treated
-    as the name of a file to open.
-    @raises UnknownHeaderField:
-    @raises dns.exception.SyntaxError:
-    @rtype: dns.message.Message object"""
-
-    if sys.hexversion >= 0x02030000:
-        # allow Unicode filenames; turn on universal newline support
-        str_type = basestring
-        opts = 'rU'
-    else:
-        str_type = str
-        opts = 'r'
-    if isinstance(f, str_type):
-        f = file(f, opts)
-        want_close = True
-    else:
-        want_close = False
-
-    try:
-        m = from_text(f)
-    finally:
-        if want_close:
-            f.close()
-    return m
-
-def make_query(qname, rdtype, rdclass = dns.rdataclass.IN, use_edns=None,
-               want_dnssec=False):
-    """Make a query message.
-
-    The query name, type, and class may all be specified either
-    as objects of the appropriate type, or as strings.
-
-    The query will have a randomly choosen query id, and its DNS flags
-    will be set to dns.flags.RD.
-
-    @param qname: The query name.
-    @type qname: dns.name.Name object or string
-    @param rdtype: The desired rdata type.
-    @type rdtype: int
-    @param rdclass: The desired rdata class; the default is class IN.
-    @type rdclass: int
-    @param use_edns: The EDNS level to use; the default is None (no EDNS).
-    See the description of dns.message.Message.use_edns() for the possible
-    values for use_edns and their meanings.
-    @type use_edns: int or bool or None
-    @param want_dnssec: Should the query indicate that DNSSEC is desired?
-    @type want_dnssec: bool
-    @rtype: dns.message.Message object"""
-
-    if isinstance(qname, (str, unicode)):
-        qname = dns.name.from_text(qname)
-    if isinstance(rdtype, str):
-        rdtype = dns.rdatatype.from_text(rdtype)
-    if isinstance(rdclass, str):
-        rdclass = dns.rdataclass.from_text(rdclass)
-    m = Message()
-    m.flags |= dns.flags.RD
-    m.find_rrset(m.question, qname, rdclass, rdtype, create=True,
-                 force_unique=True)
-    m.use_edns(use_edns)
-    m.want_dnssec(want_dnssec)
-    return m
-
-def make_response(query, recursion_available=False, our_payload=8192):
-    """Make a message which is a response for the specified query.
-    The message returned is really a response skeleton; it has all
-    of the infrastructure required of a response, but none of the
-    content.
-
-    The response's question section is a shallow copy of the query's
-    question section, so the query's question RRsets should not be
-    changed.
-
-    @param query: the query to respond to
-    @type query: dns.message.Message object
-    @param recursion_available: should RA be set in the response?
-    @type recursion_available: bool
-    @param our_payload: payload size to advertise in EDNS responses; default
-    is 8192.
-    @type our_payload: int
-    @rtype: dns.message.Message object"""
-
-    if query.flags & dns.flags.QR:
-        raise dns.exception.FormError('specified query message is not a query')
-    response = dns.message.Message(query.id)
-    response.flags = dns.flags.QR | (query.flags & dns.flags.RD)
-    if recursion_available:
-        response.flags |= dns.flags.RA
-    response.set_opcode(query.opcode())
-    response.question = list(query.question)
-    if query.edns >= 0:
-        response.use_edns(0, 0, our_payload, query.payload)
-    if not query.keyname is None:
-        response.keyname = query.keyname
-        response.keyring = query.keyring
-        response.request_mac = query.mac
-    return response
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/name.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/name.py
deleted file mode 100644
index b54aa19..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/name.py
+++ /dev/null
@@ -1,700 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Names.
-
-@var root: The DNS root name.
-@type root: dns.name.Name object
-@var empty: The empty DNS name.
-@type empty: dns.name.Name object
-"""
-
-import cStringIO
-import struct
-import sys
-
-if sys.hexversion >= 0x02030000:
-    import encodings.idna
-
-import dns.exception
-
-NAMERELN_NONE = 0
-NAMERELN_SUPERDOMAIN = 1
-NAMERELN_SUBDOMAIN = 2
-NAMERELN_EQUAL = 3
-NAMERELN_COMMONANCESTOR = 4
-
-class EmptyLabel(dns.exception.SyntaxError):
-    """Raised if a label is empty."""
-    pass
-
-class BadEscape(dns.exception.SyntaxError):
-    """Raised if an escaped code in a text format name is invalid."""
-    pass
-
-class BadPointer(dns.exception.FormError):
-    """Raised if a compression pointer points forward instead of backward."""
-    pass
-
-class BadLabelType(dns.exception.FormError):
-    """Raised if the label type of a wire format name is unknown."""
-    pass
-
-class NeedAbsoluteNameOrOrigin(dns.exception.DNSException):
-    """Raised if an attempt is made to convert a non-absolute name to
-    wire when there is also a non-absolute (or missing) origin."""
-    pass
-
-class NameTooLong(dns.exception.FormError):
-    """Raised if a name is > 255 octets long."""
-    pass
-
-class LabelTooLong(dns.exception.SyntaxError):
-    """Raised if a label is > 63 octets long."""
-    pass
-
-class AbsoluteConcatenation(dns.exception.DNSException):
-    """Raised if an attempt is made to append anything other than the
-    empty name to an absolute name."""
-    pass
-
-class NoParent(dns.exception.DNSException):
-    """Raised if an attempt is made to get the parent of the root name
-    or the empty name."""
-    pass
-
-_escaped = {
-    '"' : True,
-    '(' : True,
-    ')' : True,
-    '.' : True,
-    ';' : True,
-    '\\' : True,
-    '@' : True,
-    '$' : True
-    }
-
-def _escapify(label):
-    """Escape the characters in label which need it.
-    @returns: the escaped string
-    @rtype: string"""
-    text = ''
-    for c in label:
-        if c in _escaped:
-            text += '\\' + c
-        elif ord(c) > 0x20 and ord(c) < 0x7F:
-            text += c
-        else:
-            text += '\\%03d' % ord(c)
-    return text
-
-def _validate_labels(labels):
-    """Check for empty labels in the middle of a label sequence,
-    labels that are too long, and for too many labels.
-    @raises NameTooLong: the name as a whole is too long
-    @raises LabelTooLong: an individual label is too long
-    @raises EmptyLabel: a label is empty (i.e. the root label) and appears
-    in a position other than the end of the label sequence"""
-
-    l = len(labels)
-    total = 0
-    i = -1
-    j = 0
-    for label in labels:
-        ll = len(label)
-        total += ll + 1
-        if ll > 63:
-            raise LabelTooLong
-        if i < 0 and label == '':
-            i = j
-        j += 1
-    if total > 255:
-        raise NameTooLong
-    if i >= 0 and i != l - 1:
-        raise EmptyLabel
-
-class Name(object):
-    """A DNS name.
-
-    The dns.name.Name class represents a DNS name as a tuple of labels.
-    Instances of the class are immutable.
-
-    @ivar labels: The tuple of labels in the name. Each label is a string of
-    up to 63 octets."""
-
-    __slots__ = ['labels']
-
-    def __init__(self, labels):
-        """Initialize a domain name from a list of labels.
-        @param labels: the labels
-        @type labels: any iterable whose values are strings
-        """
-
-        super(Name, self).__setattr__('labels', tuple(labels))
-        _validate_labels(self.labels)
-
-    def __setattr__(self, name, value):
-        raise TypeError("object doesn't support attribute assignment")
-
-    def is_absolute(self):
-        """Is the most significant label of this name the root label?
-        @rtype: bool
-        """
-
-        return len(self.labels) > 0 and self.labels[-1] == ''
-
-    def is_wild(self):
-        """Is this name wild?  (I.e. Is the least significant label '*'?)
-        @rtype: bool
-        """
-
-        return len(self.labels) > 0 and self.labels[0] == '*'
-
-    def __hash__(self):
-        """Return a case-insensitive hash of the name.
-        @rtype: int
-        """
-
-        h = 0L
-        for label in self.labels:
-            for c in label:
-                h += ( h << 3 ) + ord(c.lower())
-        return int(h % sys.maxint)
-
-    def fullcompare(self, other):
-        """Compare two names, returning a 3-tuple (relation, order, nlabels).
-
-        I{relation} describes the relation ship between the names,
-        and is one of: dns.name.NAMERELN_NONE,
-        dns.name.NAMERELN_SUPERDOMAIN, dns.name.NAMERELN_SUBDOMAIN,
-        dns.name.NAMERELN_EQUAL, or dns.name.NAMERELN_COMMONANCESTOR
-
-        I{order} is < 0 if self < other, > 0 if self > other, and ==
-        0 if self == other.  A relative name is always less than an
-        absolute name.  If both names have the same relativity, then
-        the DNSSEC order relation is used to order them.
-
-        I{nlabels} is the number of significant labels that the two names
-        have in common.
-        """
-
-        sabs = self.is_absolute()
-        oabs = other.is_absolute()
-        if sabs != oabs:
-            if sabs:
-                return (NAMERELN_NONE, 1, 0)
-            else:
-                return (NAMERELN_NONE, -1, 0)
-        l1 = len(self.labels)
-        l2 = len(other.labels)
-        ldiff = l1 - l2
-        if ldiff < 0:
-            l = l1
-        else:
-            l = l2
-
-        order = 0
-        nlabels = 0
-        namereln = NAMERELN_NONE
-        while l > 0:
-            l -= 1
-            l1 -= 1
-            l2 -= 1
-            label1 = self.labels[l1].lower()
-            label2 = other.labels[l2].lower()
-            if label1 < label2:
-                order = -1
-                if nlabels > 0:
-                    namereln = NAMERELN_COMMONANCESTOR
-                return (namereln, order, nlabels)
-            elif label1 > label2:
-                order = 1
-                if nlabels > 0:
-                    namereln = NAMERELN_COMMONANCESTOR
-                return (namereln, order, nlabels)
-            nlabels += 1
-        order = ldiff
-        if ldiff < 0:
-            namereln = NAMERELN_SUPERDOMAIN
-        elif ldiff > 0:
-            namereln = NAMERELN_SUBDOMAIN
-        else:
-            namereln = NAMERELN_EQUAL
-        return (namereln, order, nlabels)
-
-    def is_subdomain(self, other):
-        """Is self a subdomain of other?
-
-        The notion of subdomain includes equality.
-        @rtype: bool
-        """
-
-        (nr, o, nl) = self.fullcompare(other)
-        if nr == NAMERELN_SUBDOMAIN or nr == NAMERELN_EQUAL:
-            return True
-        return False
-
-    def is_superdomain(self, other):
-        """Is self a superdomain of other?
-
-        The notion of subdomain includes equality.
-        @rtype: bool
-        """
-
-        (nr, o, nl) = self.fullcompare(other)
-        if nr == NAMERELN_SUPERDOMAIN or nr == NAMERELN_EQUAL:
-            return True
-        return False
-
-    def canonicalize(self):
-        """Return a name which is equal to the current name, but is in
-        DNSSEC canonical form.
-        @rtype: dns.name.Name object
-        """
-
-        return Name([x.lower() for x in self.labels])
-
-    def __eq__(self, other):
-        if isinstance(other, Name):
-            return self.fullcompare(other)[1] == 0
-        else:
-            return False
-
-    def __ne__(self, other):
-        if isinstance(other, Name):
-            return self.fullcompare(other)[1] != 0
-        else:
-            return True
-
-    def __lt__(self, other):
-        if isinstance(other, Name):
-            return self.fullcompare(other)[1] < 0
-        else:
-            return NotImplemented
-
-    def __le__(self, other):
-        if isinstance(other, Name):
-            return self.fullcompare(other)[1] <= 0
-        else:
-            return NotImplemented
-
-    def __ge__(self, other):
-        if isinstance(other, Name):
-            return self.fullcompare(other)[1] >= 0
-        else:
-            return NotImplemented
-
-    def __gt__(self, other):
-        if isinstance(other, Name):
-            return self.fullcompare(other)[1] > 0
-        else:
-            return NotImplemented
-
-    def __repr__(self):
-        return '<DNS name ' + self.__str__() + '>'
-
-    def __str__(self):
-        return self.to_text(False)
-
-    def to_text(self, omit_final_dot = False):
-        """Convert name to text format.
-        @param omit_final_dot: If True, don't emit the final dot (denoting the
-        root label) for absolute names.  The default is False.
-        @rtype: string
-        """
-
-        if len(self.labels) == 0:
-            return '@'
-        if len(self.labels) == 1 and self.labels[0] == '':
-            return '.'
-        if omit_final_dot and self.is_absolute():
-            l = self.labels[:-1]
-        else:
-            l = self.labels
-        s = '.'.join(map(_escapify, l))
-        return s
-
-    def to_unicode(self, omit_final_dot = False):
-        """Convert name to Unicode text format.
-
-        IDN ACE lables are converted to Unicode.
-
-        @param omit_final_dot: If True, don't emit the final dot (denoting the
-        root label) for absolute names.  The default is False.
-        @rtype: string
-        """
-
-        if len(self.labels) == 0:
-            return u'@'
-        if len(self.labels) == 1 and self.labels[0] == '':
-            return u'.'
-        if omit_final_dot and self.is_absolute():
-            l = self.labels[:-1]
-        else:
-            l = self.labels
-        s = u'.'.join([encodings.idna.ToUnicode(_escapify(x)) for x in l])
-        return s
-
-    def to_digestable(self, origin=None):
-        """Convert name to a format suitable for digesting in hashes.
-
-        The name is canonicalized and converted to uncompressed wire format.
-
-        @param origin: If the name is relative and origin is not None, then
-        origin will be appended to it.
-        @type origin: dns.name.Name object
-        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
-        absolute.  If self is a relative name, then an origin must be supplied;
-        if it is missing, then this exception is raised
-        @rtype: string
-        """
-
-        if not self.is_absolute():
-            if origin is None or not origin.is_absolute():
-                raise NeedAbsoluteNameOrOrigin
-            labels = list(self.labels)
-            labels.extend(list(origin.labels))
-        else:
-            labels = self.labels
-        dlabels = ["%s%s" % (chr(len(x)), x.lower()) for x in labels]
-        return ''.join(dlabels)
-
-    def to_wire(self, file = None, compress = None, origin = None):
-        """Convert name to wire format, possibly compressing it.
-
-        @param file: the file where the name is emitted (typically
-        a cStringIO file).  If None, a string containing the wire name
-        will be returned.
-        @type file: file or None
-        @param compress: The compression table.  If None (the default) names
-        will not be compressed.
-        @type compress: dict
-        @param origin: If the name is relative and origin is not None, then
-        origin will be appended to it.
-        @type origin: dns.name.Name object
-        @raises NeedAbsoluteNameOrOrigin: All names in wire format are
-        absolute.  If self is a relative name, then an origin must be supplied;
-        if it is missing, then this exception is raised
-        """
-
-        if file is None:
-            file = cStringIO.StringIO()
-            want_return = True
-        else:
-            want_return = False
-
-        if not self.is_absolute():
-            if origin is None or not origin.is_absolute():
-                raise NeedAbsoluteNameOrOrigin
-            labels = list(self.labels)
-            labels.extend(list(origin.labels))
-        else:
-            labels = self.labels
-        i = 0
-        for label in labels:
-            n = Name(labels[i:])
-            i += 1
-            if not compress is None:
-                pos = compress.get(n)
-            else:
-                pos = None
-            if not pos is None:
-                value = 0xc000 + pos
-                s = struct.pack('!H', value)
-                file.write(s)
-                break
-            else:
-                if not compress is None and len(n) > 1:
-                    pos = file.tell()
-                    if pos < 0xc000:
-                        compress[n] = pos
-                l = len(label)
-                file.write(chr(l))
-                if l > 0:
-                    file.write(label)
-        if want_return:
-            return file.getvalue()
-
-    def __len__(self):
-        """The length of the name (in labels).
-        @rtype: int
-        """
-
-        return len(self.labels)
-
-    def __getitem__(self, index):
-        return self.labels[index]
-
-    def __getslice__(self, start, stop):
-        return self.labels[start:stop]
-
-    def __add__(self, other):
-        return self.concatenate(other)
-
-    def __sub__(self, other):
-        return self.relativize(other)
-
-    def split(self, depth):
-        """Split a name into a prefix and suffix at depth.
-
-        @param depth: the number of labels in the suffix
-        @type depth: int
-        @raises ValueError: the depth was not >= 0 and <= the length of the
-        name.
-        @returns: the tuple (prefix, suffix)
-        @rtype: tuple
-        """
-
-        l = len(self.labels)
-        if depth == 0:
-            return (self, dns.name.empty)
-        elif depth == l:
-            return (dns.name.empty, self)
-        elif depth < 0 or depth > l:
-            raise ValueError('depth must be >= 0 and <= the length of the name')
-        return (Name(self[: -depth]), Name(self[-depth :]))
-
-    def concatenate(self, other):
-        """Return a new name which is the concatenation of self and other.
-        @rtype: dns.name.Name object
-        @raises AbsoluteConcatenation: self is absolute and other is
-        not the empty name
-        """
-
-        if self.is_absolute() and len(other) > 0:
-            raise AbsoluteConcatenation
-        labels = list(self.labels)
-        labels.extend(list(other.labels))
-        return Name(labels)
-
-    def relativize(self, origin):
-        """If self is a subdomain of origin, return a new name which is self
-        relative to origin.  Otherwise return self.
-        @rtype: dns.name.Name object
-        """
-
-        if not origin is None and self.is_subdomain(origin):
-            return Name(self[: -len(origin)])
-        else:
-            return self
-
-    def derelativize(self, origin):
-        """If self is a relative name, return a new name which is the
-        concatenation of self and origin.  Otherwise return self.
-        @rtype: dns.name.Name object
-        """
-
-        if not self.is_absolute():
-            return self.concatenate(origin)
-        else:
-            return self
-
-    def choose_relativity(self, origin=None, relativize=True):
-        """Return a name with the relativity desired by the caller.  If
-        origin is None, then self is returned.  Otherwise, if
-        relativize is true the name is relativized, and if relativize is
-        false the name is derelativized.
-        @rtype: dns.name.Name object
-        """
-
-        if origin:
-            if relativize:
-                return self.relativize(origin)
-            else:
-                return self.derelativize(origin)
-        else:
-            return self
-
-    def parent(self):
-        """Return the parent of the name.
-        @rtype: dns.name.Name object
-        @raises NoParent: the name is either the root name or the empty name,
-        and thus has no parent.
-        """
-        if self == root or self == empty:
-            raise NoParent
-        return Name(self.labels[1:])
-
-root = Name([''])
-empty = Name([])
-
-def from_unicode(text, origin = root):
-    """Convert unicode text into a Name object.
-
-    Lables are encoded in IDN ACE form.
-
-    @rtype: dns.name.Name object
-    """
-
-    if not isinstance(text, unicode):
-        raise ValueError("input to from_unicode() must be a unicode string")
-    if not (origin is None or isinstance(origin, Name)):
-        raise ValueError("origin must be a Name or None")
-    labels = []
-    label = u''
-    escaping = False
-    edigits = 0
-    total = 0
-    if text == u'@':
-        text = u''
-    if text:
-        if text == u'.':
-            return Name([''])	# no Unicode "u" on this constant!
-        for c in text:
-            if escaping:
-                if edigits == 0:
-                    if c.isdigit():
-                        total = int(c)
-                        edigits += 1
-                    else:
-                        label += c
-                        escaping = False
-                else:
-                    if not c.isdigit():
-                        raise BadEscape
-                    total *= 10
-                    total += int(c)
-                    edigits += 1
-                    if edigits == 3:
-                        escaping = False
-                        label += chr(total)
-            elif c == u'.' or c == u'\u3002' or \
-                 c == u'\uff0e' or c == u'\uff61':
-                if len(label) == 0:
-                    raise EmptyLabel
-                labels.append(encodings.idna.ToASCII(label))
-                label = u''
-            elif c == u'\\':
-                escaping = True
-                edigits = 0
-                total = 0
-            else:
-                label += c
-        if escaping:
-            raise BadEscape
-        if len(label) > 0:
-            labels.append(encodings.idna.ToASCII(label))
-        else:
-            labels.append('')
-    if (len(labels) == 0 or labels[-1] != '') and not origin is None:
-        labels.extend(list(origin.labels))
-    return Name(labels)
-
-def from_text(text, origin = root):
-    """Convert text into a Name object.
-    @rtype: dns.name.Name object
-    """
-
-    if not isinstance(text, str):
-        if isinstance(text, unicode) and sys.hexversion >= 0x02030000:
-            return from_unicode(text, origin)
-        else:
-            raise ValueError("input to from_text() must be a string")
-    if not (origin is None or isinstance(origin, Name)):
-        raise ValueError("origin must be a Name or None")
-    labels = []
-    label = ''
-    escaping = False
-    edigits = 0
-    total = 0
-    if text == '@':
-        text = ''
-    if text:
-        if text == '.':
-            return Name([''])
-        for c in text:
-            if escaping:
-                if edigits == 0:
-                    if c.isdigit():
-                        total = int(c)
-                        edigits += 1
-                    else:
-                        label += c
-                        escaping = False
-                else:
-                    if not c.isdigit():
-                        raise BadEscape
-                    total *= 10
-                    total += int(c)
-                    edigits += 1
-                    if edigits == 3:
-                        escaping = False
-                        label += chr(total)
-            elif c == '.':
-                if len(label) == 0:
-                    raise EmptyLabel
-                labels.append(label)
-                label = ''
-            elif c == '\\':
-                escaping = True
-                edigits = 0
-                total = 0
-            else:
-                label += c
-        if escaping:
-            raise BadEscape
-        if len(label) > 0:
-            labels.append(label)
-        else:
-            labels.append('')
-    if (len(labels) == 0 or labels[-1] != '') and not origin is None:
-        labels.extend(list(origin.labels))
-    return Name(labels)
-
-def from_wire(message, current):
-    """Convert possibly compressed wire format into a Name.
-    @param message: the entire DNS message
-    @type message: string
-    @param current: the offset of the beginning of the name from the start
-    of the message
-    @type current: int
-    @raises dns.name.BadPointer: a compression pointer did not point backwards
-    in the message
-    @raises dns.name.BadLabelType: an invalid label type was encountered.
-    @returns: a tuple consisting of the name that was read and the number
-    of bytes of the wire format message which were consumed reading it
-    @rtype: (dns.name.Name object, int) tuple
-    """
-
-    if not isinstance(message, str):
-        raise ValueError("input to from_wire() must be a byte string")
-    labels = []
-    biggest_pointer = current
-    hops = 0
-    count = ord(message[current])
-    current += 1
-    cused = 1
-    while count != 0:
-        if count < 64:
-            labels.append(message[current : current + count])
-            current += count
-            if hops == 0:
-                cused += count
-        elif count >= 192:
-            current = (count & 0x3f) * 256 + ord(message[current])
-            if hops == 0:
-                cused += 1
-            if current >= biggest_pointer:
-                raise BadPointer
-            biggest_pointer = current
-            hops += 1
-        else:
-            raise BadLabelType
-        count = ord(message[current])
-        current += 1
-        if hops == 0:
-            cused += 1
-    labels.append('')
-    return (Name(labels), cused)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/namedict.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/namedict.py
deleted file mode 100644
index 54afb77..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/namedict.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS name dictionary"""
-
-import dns.name
-
-class NameDict(dict):
-
-    """A dictionary whose keys are dns.name.Name objects.
-    @ivar max_depth: the maximum depth of the keys that have ever been
-    added to the dictionary.
-    @type max_depth: int
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(NameDict, self).__init__(*args, **kwargs)
-        self.max_depth = 0
-
-    def __setitem__(self, key, value):
-        if not isinstance(key, dns.name.Name):
-            raise ValueError('NameDict key must be a name')
-        depth = len(key)
-        if depth > self.max_depth:
-            self.max_depth = depth
-        super(NameDict, self).__setitem__(key, value)
-
-    def get_deepest_match(self, name):
-        """Find the deepest match to I{name} in the dictionary.
-
-        The deepest match is the longest name in the dictionary which is
-        a superdomain of I{name}.
-
-        @param name: the name
-        @type name: dns.name.Name object
-        @rtype: (key, value) tuple
-        """
-
-        depth = len(name)
-        if depth > self.max_depth:
-            depth = self.max_depth
-        for i in xrange(-depth, 0):
-            n = dns.name.Name(name[i:])
-            if self.has_key(n):
-                return (n, self[n])
-        v = self[dns.name.empty]
-        return (dns.name.empty, v)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/node.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/node.py
deleted file mode 100644
index 07fff92..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/node.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS nodes.  A node is a set of rdatasets."""
-
-import StringIO
-
-import dns.rdataset
-import dns.rdatatype
-import dns.renderer
-
-class Node(object):
-    """A DNS node.
-    
-    A node is a set of rdatasets
-
-    @ivar rdatasets: the node's rdatasets
-    @type rdatasets: list of dns.rdataset.Rdataset objects"""
-
-    __slots__ = ['rdatasets']
-    
-    def __init__(self):
-        """Initialize a DNS node.
-        """
-        
-        self.rdatasets = [];
-
-    def to_text(self, name, **kw):
-        """Convert a node to text format.
-
-        Each rdataset at the node is printed.  Any keyword arguments
-        to this method are passed on to the rdataset's to_text() method.
-        @param name: the owner name of the rdatasets
-        @type name: dns.name.Name object
-        @rtype: string
-        """
-        
-        s = StringIO.StringIO()
-        for rds in self.rdatasets:
-            print >> s, rds.to_text(name, **kw)
-        return s.getvalue()[:-1]
-
-    def __repr__(self):
-        return '<DNS node ' + str(id(self)) + '>'
-    
-    def __eq__(self, other):
-        """Two nodes are equal if they have the same rdatasets.
-
-        @rtype: bool
-        """
-        #
-        # This is inefficient.  Good thing we don't need to do it much.
-        #
-        for rd in self.rdatasets:
-            if rd not in other.rdatasets:
-                return False
-        for rd in other.rdatasets:
-            if rd not in self.rdatasets:
-                return False
-        return True
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-        
-    def __len__(self):
-        return len(self.rdatasets)
-
-    def __iter__(self):
-        return iter(self.rdatasets)
-
-    def find_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE,
-                      create=False):
-        """Find an rdataset matching the specified properties in the
-        current node.
-
-        @param rdclass: The class of the rdataset
-        @type rdclass: int
-        @param rdtype: The type of the rdataset
-        @type rdtype: int
-        @param covers: The covered type.  Usually this value is
-        dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
-        dns.rdatatype.RRSIG, then the covers value will be the rdata
-        type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
-        types as if they were a family of
-        types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
-        easier to work with than if RRSIGs covering different rdata
-        types were aggregated into a single RRSIG rdataset.
-        @type covers: int
-        @param create: If True, create the rdataset if it is not found.
-        @type create: bool
-        @raises KeyError: An rdataset of the desired type and class does
-        not exist and I{create} is not True.
-        @rtype: dns.rdataset.Rdataset object
-        """
-
-        for rds in self.rdatasets:
-            if rds.match(rdclass, rdtype, covers):
-                return rds
-        if not create:
-            raise KeyError
-        rds = dns.rdataset.Rdataset(rdclass, rdtype)
-        self.rdatasets.append(rds)
-        return rds
-
-    def get_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE,
-                     create=False):
-        """Get an rdataset matching the specified properties in the
-        current node.
-
-        None is returned if an rdataset of the specified type and
-        class does not exist and I{create} is not True.
-
-        @param rdclass: The class of the rdataset
-        @type rdclass: int
-        @param rdtype: The type of the rdataset
-        @type rdtype: int
-        @param covers: The covered type.
-        @type covers: int
-        @param create: If True, create the rdataset if it is not found.
-        @type create: bool
-        @rtype: dns.rdataset.Rdataset object or None
-        """
-
-        try:
-            rds = self.find_rdataset(rdclass, rdtype, covers, create)
-        except KeyError:
-            rds = None
-        return rds
-
-    def delete_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE):
-        """Delete the rdataset matching the specified properties in the
-        current node.
-
-        If a matching rdataset does not exist, it is not an error.
-
-        @param rdclass: The class of the rdataset
-        @type rdclass: int
-        @param rdtype: The type of the rdataset
-        @type rdtype: int
-        @param covers: The covered type.
-        @type covers: int
-        """
-
-        rds = self.get_rdataset(rdclass, rdtype, covers)
-        if not rds is None:
-            self.rdatasets.remove(rds)
-
-    def replace_rdataset(self, replacement):
-        """Replace an rdataset.
-        
-        It is not an error if there is no rdataset matching I{replacement}.
-
-        Ownership of the I{replacement} object is transferred to the node;
-        in other words, this method does not store a copy of I{replacement}
-        at the node, it stores I{replacement} itself.
-        """
-
-        self.delete_rdataset(replacement.rdclass, replacement.rdtype,
-                             replacement.covers)
-        self.rdatasets.append(replacement)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/opcode.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/opcode.py
deleted file mode 100644
index 705bd09..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/opcode.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Opcodes."""
-
-import dns.exception
-
-QUERY = 0
-IQUERY = 1
-STATUS = 2
-NOTIFY = 4
-UPDATE = 5
-
-_by_text = {
-    'QUERY' : QUERY,
-    'IQUERY' : IQUERY,
-    'STATUS' : STATUS,
-    'NOTIFY' : NOTIFY,
-    'UPDATE' : UPDATE
-}
-
-# We construct the inverse mapping programmatically to ensure that we
-# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
-# would cause the mapping not to be true inverse.
-
-_by_value = dict([(y, x) for x, y in _by_text.iteritems()])
-
-
-class UnknownOpcode(dns.exception.DNSException):
-    """Raised if an opcode is unknown."""
-    pass
-
-def from_text(text):
-    """Convert text into an opcode.
-
-    @param text: the textual opcode
-    @type text: string
-    @raises UnknownOpcode: the opcode is unknown
-    @rtype: int
-    """
-
-    if text.isdigit():
-        value = int(text)
-        if value >= 0 and value <= 15:
-            return value
-    value = _by_text.get(text.upper())
-    if value is None:
-        raise UnknownOpcode
-    return value
-
-def from_flags(flags):
-    """Extract an opcode from DNS message flags.
-
-    @param flags: int
-    @rtype: int
-    """
-    
-    return (flags & 0x7800) >> 11
-
-def to_flags(value):
-    """Convert an opcode to a value suitable for ORing into DNS message
-    flags.
-    @rtype: int
-    """
-    
-    return (value << 11) & 0x7800
-    
-def to_text(value):
-    """Convert an opcode to text.
-
-    @param value: the opcdoe
-    @type value: int
-    @raises UnknownOpcode: the opcode is unknown
-    @rtype: string
-    """
-    
-    text = _by_value.get(value)
-    if text is None:
-        text = str(value)
-    return text
-
-def is_update(flags):
-    """True if the opcode in flags is UPDATE.
-
-    @param flags: DNS flags
-    @type flags: int
-    @rtype: bool
-    """
-    
-    if (from_flags(flags) == UPDATE):
-        return True
-    return False
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/query.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/query.py
deleted file mode 100644
index c023b14..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/query.py
+++ /dev/null
@@ -1,428 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Talk to a DNS server."""
-
-from __future__ import generators
-
-import errno
-import select
-import socket
-import struct
-import sys
-import time
-
-import dns.exception
-import dns.inet
-import dns.name
-import dns.message
-import dns.rdataclass
-import dns.rdatatype
-
-class UnexpectedSource(dns.exception.DNSException):
-    """Raised if a query response comes from an unexpected address or port."""
-    pass
-
-class BadResponse(dns.exception.FormError):
-    """Raised if a query response does not respond to the question asked."""
-    pass
-
-def _compute_expiration(timeout):
-    if timeout is None:
-        return None
-    else:
-        return time.time() + timeout
-
-def _wait_for(ir, iw, ix, expiration):
-    done = False
-    while not done:
-        if expiration is None:
-            timeout = None
-        else:
-            timeout = expiration - time.time()
-            if timeout <= 0.0:
-                raise dns.exception.Timeout
-        try:
-            if timeout is None:
-                (r, w, x) = select.select(ir, iw, ix)
-            else:
-                (r, w, x) = select.select(ir, iw, ix, timeout)
-        except select.error, e:
-            if e.args[0] != errno.EINTR:
-                raise e
-        done = True
-        if len(r) == 0 and len(w) == 0 and len(x) == 0:
-            raise dns.exception.Timeout
-
-def _wait_for_readable(s, expiration):
-    _wait_for([s], [], [s], expiration)
-
-def _wait_for_writable(s, expiration):
-    _wait_for([], [s], [s], expiration)
-
-def _addresses_equal(af, a1, a2):
-    # Convert the first value of the tuple, which is a textual format
-    # address into binary form, so that we are not confused by different
-    # textual representations of the same address
-    n1 = dns.inet.inet_pton(af, a1[0])
-    n2 = dns.inet.inet_pton(af, a2[0])
-    return n1 == n2 and a1[1:] == a2[1:]
-
-def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
-        ignore_unexpected=False, one_rr_per_rrset=False):
-    """Return the response obtained after sending a query via UDP.
-
-    @param q: the query
-    @type q: dns.message.Message
-    @param where: where to send the message
-    @type where: string containing an IPv4 or IPv6 address
-    @param timeout: The number of seconds to wait before the query times out.
-    If None, the default, wait forever.
-    @type timeout: float
-    @param port: The port to which to send the message.  The default is 53.
-    @type port: int
-    @param af: the address family to use.  The default is None, which
-    causes the address family to use to be inferred from the form of of where.
-    If the inference attempt fails, AF_INET is used.
-    @type af: int
-    @rtype: dns.message.Message object
-    @param source: source address.  The default is the IPv4 wildcard address.
-    @type source: string
-    @param source_port: The port from which to send the message.
-    The default is 0.
-    @type source_port: int
-    @param ignore_unexpected: If True, ignore responses from unexpected
-    sources.  The default is False.
-    @type ignore_unexpected: bool
-    @param one_rr_per_rrset: Put each RR into its own RRset
-    @type one_rr_per_rrset: bool
-    """
-
-    wire = q.to_wire()
-    if af is None:
-        try:
-            af = dns.inet.af_for_address(where)
-        except:
-            af = dns.inet.AF_INET
-    if af == dns.inet.AF_INET:
-        destination = (where, port)
-        if source is not None:
-            source = (source, source_port)
-    elif af == dns.inet.AF_INET6:
-        destination = (where, port, 0, 0)
-        if source is not None:
-            source = (source, source_port, 0, 0)
-    s = socket.socket(af, socket.SOCK_DGRAM, 0)
-    try:
-        expiration = _compute_expiration(timeout)
-        s.setblocking(0)
-        if source is not None:
-            s.bind(source)
-        _wait_for_writable(s, expiration)
-        s.sendto(wire, destination)
-        while 1:
-            _wait_for_readable(s, expiration)
-            (wire, from_address) = s.recvfrom(65535)
-            if _addresses_equal(af, from_address, destination) or \
-                    (dns.inet.is_multicast(where) and \
-                         from_address[1:] == destination[1:]):
-                break
-            if not ignore_unexpected:
-                raise UnexpectedSource('got a response from '
-                                       '%s instead of %s' % (from_address,
-                                                             destination))
-    finally:
-        s.close()
-    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
-                              one_rr_per_rrset=one_rr_per_rrset)
-    if not q.is_response(r):
-        raise BadResponse
-    return r
-
-def _net_read(sock, count, expiration):
-    """Read the specified number of bytes from sock.  Keep trying until we
-    either get the desired amount, or we hit EOF.
-    A Timeout exception will be raised if the operation is not completed
-    by the expiration time.
-    """
-    s = ''
-    while count > 0:
-        _wait_for_readable(sock, expiration)
-        n = sock.recv(count)
-        if n == '':
-            raise EOFError
-        count = count - len(n)
-        s = s + n
-    return s
-
-def _net_write(sock, data, expiration):
-    """Write the specified data to the socket.
-    A Timeout exception will be raised if the operation is not completed
-    by the expiration time.
-    """
-    current = 0
-    l = len(data)
-    while current < l:
-        _wait_for_writable(sock, expiration)
-        current += sock.send(data[current:])
-
-def _connect(s, address):
-    try:
-        s.connect(address)
-    except socket.error:
-        (ty, v) = sys.exc_info()[:2]
-        if v[0] != errno.EINPROGRESS and \
-               v[0] != errno.EWOULDBLOCK and \
-               v[0] != errno.EALREADY:
-            raise v
-
-def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0,
-        one_rr_per_rrset=False):
-    """Return the response obtained after sending a query via TCP.
-
-    @param q: the query
-    @type q: dns.message.Message object
-    @param where: where to send the message
-    @type where: string containing an IPv4 or IPv6 address
-    @param timeout: The number of seconds to wait before the query times out.
-    If None, the default, wait forever.
-    @type timeout: float
-    @param port: The port to which to send the message.  The default is 53.
-    @type port: int
-    @param af: the address family to use.  The default is None, which
-    causes the address family to use to be inferred from the form of of where.
-    If the inference attempt fails, AF_INET is used.
-    @type af: int
-    @rtype: dns.message.Message object
-    @param source: source address.  The default is the IPv4 wildcard address.
-    @type source: string
-    @param source_port: The port from which to send the message.
-    The default is 0.
-    @type source_port: int
-    @param one_rr_per_rrset: Put each RR into its own RRset
-    @type one_rr_per_rrset: bool
-    """
-
-    wire = q.to_wire()
-    if af is None:
-        try:
-            af = dns.inet.af_for_address(where)
-        except:
-            af = dns.inet.AF_INET
-    if af == dns.inet.AF_INET:
-        destination = (where, port)
-        if source is not None:
-            source = (source, source_port)
-    elif af == dns.inet.AF_INET6:
-        destination = (where, port, 0, 0)
-        if source is not None:
-            source = (source, source_port, 0, 0)
-    s = socket.socket(af, socket.SOCK_STREAM, 0)
-    try:
-        expiration = _compute_expiration(timeout)
-        s.setblocking(0)
-        if source is not None:
-            s.bind(source)
-        _connect(s, destination)
-
-        l = len(wire)
-
-        # copying the wire into tcpmsg is inefficient, but lets us
-        # avoid writev() or doing a short write that would get pushed
-        # onto the net
-        tcpmsg = struct.pack("!H", l) + wire
-        _net_write(s, tcpmsg, expiration)
-        ldata = _net_read(s, 2, expiration)
-        (l,) = struct.unpack("!H", ldata)
-        wire = _net_read(s, l, expiration)
-    finally:
-        s.close()
-    r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
-                              one_rr_per_rrset=one_rr_per_rrset)
-    if not q.is_response(r):
-        raise BadResponse
-    return r
-
-def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN,
-        timeout=None, port=53, keyring=None, keyname=None, relativize=True,
-        af=None, lifetime=None, source=None, source_port=0, serial=0,
-        use_udp=False, keyalgorithm=dns.tsig.default_algorithm):
-    """Return a generator for the responses to a zone transfer.
-
-    @param where: where to send the message
-    @type where: string containing an IPv4 or IPv6 address
-    @param zone: The name of the zone to transfer
-    @type zone: dns.name.Name object or string
-    @param rdtype: The type of zone transfer.  The default is
-    dns.rdatatype.AXFR.
-    @type rdtype: int or string
-    @param rdclass: The class of the zone transfer.  The default is
-    dns.rdatatype.IN.
-    @type rdclass: int or string
-    @param timeout: The number of seconds to wait for each response message.
-    If None, the default, wait forever.
-    @type timeout: float
-    @param port: The port to which to send the message.  The default is 53.
-    @type port: int
-    @param keyring: The TSIG keyring to use
-    @type keyring: dict
-    @param keyname: The name of the TSIG key to use
-    @type keyname: dns.name.Name object or string
-    @param relativize: If True, all names in the zone will be relativized to
-    the zone origin.  It is essential that the relativize setting matches
-    the one specified to dns.zone.from_xfr().
-    @type relativize: bool
-    @param af: the address family to use.  The default is None, which
-    causes the address family to use to be inferred from the form of of where.
-    If the inference attempt fails, AF_INET is used.
-    @type af: int
-    @param lifetime: The total number of seconds to spend doing the transfer.
-    If None, the default, then there is no limit on the time the transfer may
-    take.
-    @type lifetime: float
-    @rtype: generator of dns.message.Message objects.
-    @param source: source address.  The default is the IPv4 wildcard address.
-    @type source: string
-    @param source_port: The port from which to send the message.
-    The default is 0.
-    @type source_port: int
-    @param serial: The SOA serial number to use as the base for an IXFR diff
-    sequence (only meaningful if rdtype == dns.rdatatype.IXFR).
-    @type serial: int
-    @param use_udp: Use UDP (only meaningful for IXFR)
-    @type use_udp: bool
-    @param keyalgorithm: The TSIG algorithm to use; defaults to
-    dns.tsig.default_algorithm
-    @type keyalgorithm: string
-    """
-
-    if isinstance(zone, (str, unicode)):
-        zone = dns.name.from_text(zone)
-    if isinstance(rdtype, str):
-        rdtype = dns.rdatatype.from_text(rdtype)
-    q = dns.message.make_query(zone, rdtype, rdclass)
-    if rdtype == dns.rdatatype.IXFR:
-        rrset = dns.rrset.from_text(zone, 0, 'IN', 'SOA',
-                                    '. . %u 0 0 0 0' % serial)
-        q.authority.append(rrset)
-    if not keyring is None:
-        q.use_tsig(keyring, keyname, algorithm=keyalgorithm)
-    wire = q.to_wire()
-    if af is None:
-        try:
-            af = dns.inet.af_for_address(where)
-        except:
-            af = dns.inet.AF_INET
-    if af == dns.inet.AF_INET:
-        destination = (where, port)
-        if source is not None:
-            source = (source, source_port)
-    elif af == dns.inet.AF_INET6:
-        destination = (where, port, 0, 0)
-        if source is not None:
-            source = (source, source_port, 0, 0)
-    if use_udp:
-        if rdtype != dns.rdatatype.IXFR:
-            raise ValueError('cannot do a UDP AXFR')
-        s = socket.socket(af, socket.SOCK_DGRAM, 0)
-    else:
-        s = socket.socket(af, socket.SOCK_STREAM, 0)
-    s.setblocking(0)
-    if source is not None:
-        s.bind(source)
-    expiration = _compute_expiration(lifetime)
-    _connect(s, destination)
-    l = len(wire)
-    if use_udp:
-        _wait_for_writable(s, expiration)
-        s.send(wire)
-    else:
-        tcpmsg = struct.pack("!H", l) + wire
-        _net_write(s, tcpmsg, expiration)
-    done = False
-    soa_rrset = None
-    soa_count = 0
-    if relativize:
-        origin = zone
-        oname = dns.name.empty
-    else:
-        origin = None
-        oname = zone
-    tsig_ctx = None
-    first = True
-    while not done:
-        mexpiration = _compute_expiration(timeout)
-        if mexpiration is None or mexpiration > expiration:
-            mexpiration = expiration
-        if use_udp:
-            _wait_for_readable(s, expiration)
-            (wire, from_address) = s.recvfrom(65535)
-        else:
-            ldata = _net_read(s, 2, mexpiration)
-            (l,) = struct.unpack("!H", ldata)
-            wire = _net_read(s, l, mexpiration)
-        r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac,
-                                  xfr=True, origin=origin, tsig_ctx=tsig_ctx,
-                                  multi=True, first=first,
-                                  one_rr_per_rrset=(rdtype==dns.rdatatype.IXFR))
-        tsig_ctx = r.tsig_ctx
-        first = False
-        answer_index = 0
-        delete_mode = False
-        expecting_SOA = False
-        if soa_rrset is None:
-            if not r.answer or r.answer[0].name != oname:
-                raise dns.exception.FormError
-            rrset = r.answer[0]
-            if rrset.rdtype != dns.rdatatype.SOA:
-                raise dns.exception.FormError("first RRset is not an SOA")
-            answer_index = 1
-            soa_rrset = rrset.copy()
-            if rdtype == dns.rdatatype.IXFR:
-                if soa_rrset[0].serial == serial:
-                    #
-                    # We're already up-to-date.
-                    #
-                    done = True
-                else:
-                    expecting_SOA = True
-        #
-        # Process SOAs in the answer section (other than the initial
-        # SOA in the first message).
-        #
-        for rrset in r.answer[answer_index:]:
-            if done:
-                raise dns.exception.FormError("answers after final SOA")
-            if rrset.rdtype == dns.rdatatype.SOA and rrset.name == oname:
-                if expecting_SOA:
-                    if rrset[0].serial != serial:
-                        raise dns.exception.FormError("IXFR base serial mismatch")
-                    expecting_SOA = False
-                elif rdtype == dns.rdatatype.IXFR:
-                    delete_mode = not delete_mode
-                if rrset == soa_rrset and not delete_mode:
-                    done = True
-            elif expecting_SOA:
-                #
-                # We made an IXFR request and are expecting another
-                # SOA RR, but saw something else, so this must be an
-                # AXFR response.
-                #
-                rdtype = dns.rdatatype.AXFR
-                expecting_SOA = False
-        if done and q.keyring and not r.had_tsig:
-            raise dns.exception.FormError("missing TSIG")
-        yield r
-    s.close()
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rcode.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rcode.py
deleted file mode 100644
index c055f2e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rcode.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Result Codes."""
-
-import dns.exception
-
-NOERROR = 0
-FORMERR = 1
-SERVFAIL = 2
-NXDOMAIN = 3
-NOTIMP = 4
-REFUSED = 5
-YXDOMAIN = 6
-YXRRSET = 7
-NXRRSET = 8
-NOTAUTH = 9
-NOTZONE = 10
-BADVERS = 16
-
-_by_text = {
-    'NOERROR' : NOERROR,
-    'FORMERR' : FORMERR,
-    'SERVFAIL' : SERVFAIL,
-    'NXDOMAIN' : NXDOMAIN,
-    'NOTIMP' : NOTIMP,
-    'REFUSED' : REFUSED,
-    'YXDOMAIN' : YXDOMAIN,
-    'YXRRSET' : YXRRSET,
-    'NXRRSET' : NXRRSET,
-    'NOTAUTH' : NOTAUTH,
-    'NOTZONE' : NOTZONE,
-    'BADVERS' : BADVERS
-}
-
-# We construct the inverse mapping programmatically to ensure that we
-# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
-# would cause the mapping not to be a true inverse.
-
-_by_value = dict([(y, x) for x, y in _by_text.iteritems()])
-
-
-class UnknownRcode(dns.exception.DNSException):
-    """Raised if an rcode is unknown."""
-    pass
-
-def from_text(text):
-    """Convert text into an rcode.
-
-    @param text: the texual rcode
-    @type text: string
-    @raises UnknownRcode: the rcode is unknown
-    @rtype: int
-    """
-
-    if text.isdigit():
-        v = int(text)
-        if v >= 0 and v <= 4095:
-            return v
-    v = _by_text.get(text.upper())
-    if v is None:
-        raise UnknownRcode
-    return v
-
-def from_flags(flags, ednsflags):
-    """Return the rcode value encoded by flags and ednsflags.
-
-    @param flags: the DNS flags
-    @type flags: int
-    @param ednsflags: the EDNS flags
-    @type ednsflags: int
-    @raises ValueError: rcode is < 0 or > 4095
-    @rtype: int
-    """
-
-    value = (flags & 0x000f) | ((ednsflags >> 20) & 0xff0)
-    if value < 0 or value > 4095:
-        raise ValueError('rcode must be >= 0 and <= 4095')
-    return value
-
-def to_flags(value):
-    """Return a (flags, ednsflags) tuple which encodes the rcode.
-
-    @param value: the rcode
-    @type value: int
-    @raises ValueError: rcode is < 0 or > 4095
-    @rtype: (int, int) tuple
-    """
-
-    if value < 0 or value > 4095:
-        raise ValueError('rcode must be >= 0 and <= 4095')
-    v = value & 0xf
-    ev = long(value & 0xff0) << 20
-    return (v, ev)
-
-def to_text(value):
-    """Convert rcode into text.
-
-    @param value: the rcode
-    @type value: int
-    @rtype: string
-    """
-
-    text = _by_value.get(value)
-    if text is None:
-        text = str(value)
-    return text
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdata.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdata.py
deleted file mode 100644
index ce02686..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdata.py
+++ /dev/null
@@ -1,456 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS rdata.
-
-@var _rdata_modules: A dictionary mapping a (rdclass, rdtype) tuple to
-the module which implements that type.
-@type _rdata_modules: dict
-@var _module_prefix: The prefix to use when forming modules names.  The
-default is 'dns.rdtypes'.  Changing this value will break the library.
-@type _module_prefix: string
-@var _hex_chunk: At most this many octets that will be represented in each
-chunk of hexstring that _hexify() produces before whitespace occurs.
-@type _hex_chunk: int"""
-
-import cStringIO
-
-import dns.exception
-import dns.rdataclass
-import dns.rdatatype
-import dns.tokenizer
-
-_hex_chunksize = 32
-
-def _hexify(data, chunksize=None):
-    """Convert a binary string into its hex encoding, broken up into chunks
-    of I{chunksize} characters separated by a space.
-
-    @param data: the binary string
-    @type data: string
-    @param chunksize: the chunk size.  Default is L{dns.rdata._hex_chunksize}
-    @rtype: string
-    """
-
-    if chunksize is None:
-        chunksize = _hex_chunksize
-    hex = data.encode('hex_codec')
-    l = len(hex)
-    if l > chunksize:
-        chunks = []
-        i = 0
-        while i < l:
-            chunks.append(hex[i : i + chunksize])
-            i += chunksize
-        hex = ' '.join(chunks)
-    return hex
-
-_base64_chunksize = 32
-
-def _base64ify(data, chunksize=None):
-    """Convert a binary string into its base64 encoding, broken up into chunks
-    of I{chunksize} characters separated by a space.
-
-    @param data: the binary string
-    @type data: string
-    @param chunksize: the chunk size.  Default is
-    L{dns.rdata._base64_chunksize}
-    @rtype: string
-    """
-
-    if chunksize is None:
-        chunksize = _base64_chunksize
-    b64 = data.encode('base64_codec')
-    b64 = b64.replace('\n', '')
-    l = len(b64)
-    if l > chunksize:
-        chunks = []
-        i = 0
-        while i < l:
-            chunks.append(b64[i : i + chunksize])
-            i += chunksize
-        b64 = ' '.join(chunks)
-    return b64
-
-__escaped = {
-    '"' : True,
-    '\\' : True,
-    }
-
-def _escapify(qstring):
-    """Escape the characters in a quoted string which need it.
-
-    @param qstring: the string
-    @type qstring: string
-    @returns: the escaped string
-    @rtype: string
-    """
-
-    text = ''
-    for c in qstring:
-        if c in __escaped:
-            text += '\\' + c
-        elif ord(c) >= 0x20 and ord(c) < 0x7F:
-            text += c
-        else:
-            text += '\\%03d' % ord(c)
-    return text
-
-def _truncate_bitmap(what):
-    """Determine the index of greatest byte that isn't all zeros, and
-    return the bitmap that contains all the bytes less than that index.
-
-    @param what: a string of octets representing a bitmap.
-    @type what: string
-    @rtype: string
-    """
-
-    for i in xrange(len(what) - 1, -1, -1):
-        if what[i] != '\x00':
-            break
-    return ''.join(what[0 : i + 1])
-
-class Rdata(object):
-    """Base class for all DNS rdata types.
-    """
-
-    __slots__ = ['rdclass', 'rdtype']
-
-    def __init__(self, rdclass, rdtype):
-        """Initialize an rdata.
-        @param rdclass: The rdata class
-        @type rdclass: int
-        @param rdtype: The rdata type
-        @type rdtype: int
-        """
-
-        self.rdclass = rdclass
-        self.rdtype = rdtype
-
-    def covers(self):
-        """DNS SIG/RRSIG rdatas apply to a specific type; this type is
-        returned by the covers() function.  If the rdata type is not
-        SIG or RRSIG, dns.rdatatype.NONE is returned.  This is useful when
-        creating rdatasets, allowing the rdataset to contain only RRSIGs
-        of a particular type, e.g. RRSIG(NS).
-        @rtype: int
-        """
-
-        return dns.rdatatype.NONE
-
-    def extended_rdatatype(self):
-        """Return a 32-bit type value, the least significant 16 bits of
-        which are the ordinary DNS type, and the upper 16 bits of which are
-        the "covered" type, if any.
-        @rtype: int
-        """
-
-        return self.covers() << 16 | self.rdtype
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        """Convert an rdata to text format.
-        @rtype: string
-        """
-        raise NotImplementedError
-
-    def to_wire(self, file, compress = None, origin = None):
-        """Convert an rdata to wire format.
-        @rtype: string
-        """
-
-        raise NotImplementedError
-
-    def to_digestable(self, origin = None):
-        """Convert rdata to a format suitable for digesting in hashes.  This
-        is also the DNSSEC canonical form."""
-        f = cStringIO.StringIO()
-        self.to_wire(f, None, origin)
-        return f.getvalue()
-
-    def validate(self):
-        """Check that the current contents of the rdata's fields are
-        valid.  If you change an rdata by assigning to its fields,
-        it is a good idea to call validate() when you are done making
-        changes.
-        """
-        dns.rdata.from_text(self.rdclass, self.rdtype, self.to_text())
-
-    def __repr__(self):
-        covers = self.covers()
-        if covers == dns.rdatatype.NONE:
-            ctext = ''
-        else:
-            ctext = '(' + dns.rdatatype.to_text(covers) + ')'
-        return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + \
-               dns.rdatatype.to_text(self.rdtype) + ctext + ' rdata: ' + \
-               str(self) + '>'
-
-    def __str__(self):
-        return self.to_text()
-
-    def _cmp(self, other):
-        """Compare an rdata with another rdata of the same rdtype and
-        rdclass.  Return < 0 if self < other in the DNSSEC ordering,
-        0 if self == other, and > 0 if self > other.
-        """
-
-        raise NotImplementedError
-
-    def __eq__(self, other):
-        if not isinstance(other, Rdata):
-            return False
-        if self.rdclass != other.rdclass or \
-           self.rdtype != other.rdtype:
-            return False
-        return self._cmp(other) == 0
-
-    def __ne__(self, other):
-        if not isinstance(other, Rdata):
-            return True
-        if self.rdclass != other.rdclass or \
-           self.rdtype != other.rdtype:
-            return True
-        return self._cmp(other) != 0
-
-    def __lt__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
-            return NotImplemented
-        return self._cmp(other) < 0
-
-    def __le__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
-            return NotImplemented
-        return self._cmp(other) <= 0
-
-    def __ge__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
-            return NotImplemented
-        return self._cmp(other) >= 0
-
-    def __gt__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
-            return NotImplemented
-        return self._cmp(other) > 0
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        """Build an rdata object from text format.
-
-        @param rdclass: The rdata class
-        @type rdclass: int
-        @param rdtype: The rdata type
-        @type rdtype: int
-        @param tok: The tokenizer
-        @type tok: dns.tokenizer.Tokenizer
-        @param origin: The origin to use for relative names
-        @type origin: dns.name.Name
-        @param relativize: should names be relativized?
-        @type relativize: bool
-        @rtype: dns.rdata.Rdata instance
-        """
-
-        raise NotImplementedError
-
-    from_text = classmethod(from_text)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        """Build an rdata object from wire format
-
-        @param rdclass: The rdata class
-        @type rdclass: int
-        @param rdtype: The rdata type
-        @type rdtype: int
-        @param wire: The wire-format message
-        @type wire: string
-        @param current: The offet in wire of the beginning of the rdata.
-        @type current: int
-        @param rdlen: The length of the wire-format rdata
-        @type rdlen: int
-        @param origin: The origin to use for relative names
-        @type origin: dns.name.Name
-        @rtype: dns.rdata.Rdata instance
-        """
-
-        raise NotImplementedError
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        """Convert any domain names in the rdata to the specified
-        relativization.
-        """
-
-        pass
-
-
-class GenericRdata(Rdata):
-    """Generate Rdata Class
-
-    This class is used for rdata types for which we have no better
-    implementation.  It implements the DNS "unknown RRs" scheme.
-    """
-
-    __slots__ = ['data']
-
-    def __init__(self, rdclass, rdtype, data):
-        super(GenericRdata, self).__init__(rdclass, rdtype)
-        self.data = data
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return r'\# %d ' % len(self.data) + _hexify(self.data)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        token = tok.get()
-        if not token.is_identifier() or token.value != '\#':
-            raise dns.exception.SyntaxError(r'generic rdata does not start with \#')
-        length = tok.get_int()
-        chunks = []
-        while 1:
-            token = tok.get()
-            if token.is_eol_or_eof():
-                break
-            chunks.append(token.value)
-        hex = ''.join(chunks)
-        data = hex.decode('hex_codec')
-        if len(data) != length:
-            raise dns.exception.SyntaxError('generic rdata hex data has wrong length')
-        return cls(rdclass, rdtype, data)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        file.write(self.data)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        return cls(rdclass, rdtype, wire[current : current + rdlen])
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        return cmp(self.data, other.data)
-
-_rdata_modules = {}
-_module_prefix = 'dns.rdtypes'
-
-def get_rdata_class(rdclass, rdtype):
-
-    def import_module(name):
-        mod = __import__(name)
-        components = name.split('.')
-        for comp in components[1:]:
-            mod = getattr(mod, comp)
-        return mod
-
-    mod = _rdata_modules.get((rdclass, rdtype))
-    rdclass_text = dns.rdataclass.to_text(rdclass)
-    rdtype_text = dns.rdatatype.to_text(rdtype)
-    rdtype_text = rdtype_text.replace('-', '_')
-    if not mod:
-        mod = _rdata_modules.get((dns.rdatatype.ANY, rdtype))
-        if not mod:
-            try:
-                mod = import_module('.'.join([_module_prefix,
-                                              rdclass_text, rdtype_text]))
-                _rdata_modules[(rdclass, rdtype)] = mod
-            except ImportError:
-                try:
-                    mod = import_module('.'.join([_module_prefix,
-                                                  'ANY', rdtype_text]))
-                    _rdata_modules[(dns.rdataclass.ANY, rdtype)] = mod
-                except ImportError:
-                    mod = None
-    if mod:
-        cls = getattr(mod, rdtype_text)
-    else:
-        cls = GenericRdata
-    return cls
-
-def from_text(rdclass, rdtype, tok, origin = None, relativize = True):
-    """Build an rdata object from text format.
-
-    This function attempts to dynamically load a class which
-    implements the specified rdata class and type.  If there is no
-    class-and-type-specific implementation, the GenericRdata class
-    is used.
-
-    Once a class is chosen, its from_text() class method is called
-    with the parameters to this function.
-
-    @param rdclass: The rdata class
-    @type rdclass: int
-    @param rdtype: The rdata type
-    @type rdtype: int
-    @param tok: The tokenizer
-    @type tok: dns.tokenizer.Tokenizer
-    @param origin: The origin to use for relative names
-    @type origin: dns.name.Name
-    @param relativize: Should names be relativized?
-    @type relativize: bool
-    @rtype: dns.rdata.Rdata instance"""
-
-    if isinstance(tok, str):
-        tok = dns.tokenizer.Tokenizer(tok)
-    cls = get_rdata_class(rdclass, rdtype)
-    if cls != GenericRdata:
-        # peek at first token
-        token = tok.get()
-        tok.unget(token)
-        if token.is_identifier() and \
-           token.value == r'\#':
-            #
-            # Known type using the generic syntax.  Extract the
-            # wire form from the generic syntax, and then run
-            # from_wire on it.
-            #
-            rdata = GenericRdata.from_text(rdclass, rdtype, tok, origin,
-                                           relativize)
-            return from_wire(rdclass, rdtype, rdata.data, 0, len(rdata.data),
-                             origin)
-    return cls.from_text(rdclass, rdtype, tok, origin, relativize)
-
-def from_wire(rdclass, rdtype, wire, current, rdlen, origin = None):
-    """Build an rdata object from wire format
-
-    This function attempts to dynamically load a class which
-    implements the specified rdata class and type.  If there is no
-    class-and-type-specific implementation, the GenericRdata class
-    is used.
-
-    Once a class is chosen, its from_wire() class method is called
-    with the parameters to this function.
-
-    @param rdclass: The rdata class
-    @type rdclass: int
-    @param rdtype: The rdata type
-    @type rdtype: int
-    @param wire: The wire-format message
-    @type wire: string
-    @param current: The offet in wire of the beginning of the rdata.
-    @type current: int
-    @param rdlen: The length of the wire-format rdata
-    @type rdlen: int
-    @param origin: The origin to use for relative names
-    @type origin: dns.name.Name
-    @rtype: dns.rdata.Rdata instance"""
-
-    cls = get_rdata_class(rdclass, rdtype)
-    return cls.from_wire(rdclass, rdtype, wire, current, rdlen, origin)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdataclass.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdataclass.py
deleted file mode 100644
index 887fd1a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdataclass.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Rdata Classes.
-
-@var _by_text: The rdata class textual name to value mapping
-@type _by_text: dict
-@var _by_value: The rdata class value to textual name mapping
-@type _by_value: dict
-@var _metaclasses: If an rdataclass is a metaclass, there will be a mapping
-whose key is the rdatatype value and whose value is True in this dictionary.
-@type _metaclasses: dict"""
-
-import re
-
-import dns.exception
-
-RESERVED0 = 0
-IN = 1
-CH = 3
-HS = 4
-NONE = 254
-ANY = 255
-
-_by_text = {
-    'RESERVED0' : RESERVED0,
-    'IN' : IN,
-    'CH' : CH,
-    'HS' : HS,
-    'NONE' : NONE,
-    'ANY' : ANY
-    }
-
-# We construct the inverse mapping programmatically to ensure that we
-# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
-# would cause the mapping not to be true inverse.
-
-_by_value = dict([(y, x) for x, y in _by_text.iteritems()])
-
-# Now that we've built the inverse map, we can add class aliases to
-# the _by_text mapping.
-
-_by_text.update({
-    'INTERNET' : IN,
-    'CHAOS' : CH,
-    'HESIOD' : HS
-    })
-
-_metaclasses = {
-    NONE : True,
-    ANY : True
-    }
-
-_unknown_class_pattern = re.compile('CLASS([0-9]+)$', re.I);
-
-class UnknownRdataclass(dns.exception.DNSException):
-    """Raised when a class is unknown."""
-    pass
-
-def from_text(text):
-    """Convert text into a DNS rdata class value.
-    @param text: the text
-    @type text: string
-    @rtype: int
-    @raises dns.rdataclass.UnknownRdataClass: the class is unknown
-    @raises ValueError: the rdata class value is not >= 0 and <= 65535
-    """
-
-    value = _by_text.get(text.upper())
-    if value is None:
-        match = _unknown_class_pattern.match(text)
-        if match == None:
-            raise UnknownRdataclass
-        value = int(match.group(1))
-        if value < 0 or value > 65535:
-            raise ValueError("class must be between >= 0 and <= 65535")
-    return value
-
-def to_text(value):
-    """Convert a DNS rdata class to text.
-    @param value: the rdata class value
-    @type value: int
-    @rtype: string
-    @raises ValueError: the rdata class value is not >= 0 and <= 65535
-    """
-
-    if value < 0 or value > 65535:
-        raise ValueError("class must be between >= 0 and <= 65535")
-    text = _by_value.get(value)
-    if text is None:
-        text = 'CLASS' + `value`
-    return text
-
-def is_metaclass(rdclass):
-    """True if the class is a metaclass.
-    @param rdclass: the rdata class
-    @type rdclass: int
-    @rtype: bool"""
-
-    if _metaclasses.has_key(rdclass):
-        return True
-    return False
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdataset.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdataset.py
deleted file mode 100644
index 0af018b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdataset.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS rdatasets (an rdataset is a set of rdatas of a given type and class)"""
-
-import random
-import StringIO
-import struct
-
-import dns.exception
-import dns.rdatatype
-import dns.rdataclass
-import dns.rdata
-import dns.set
-
-# define SimpleSet here for backwards compatibility
-SimpleSet = dns.set.Set
-
-class DifferingCovers(dns.exception.DNSException):
-    """Raised if an attempt is made to add a SIG/RRSIG whose covered type
-    is not the same as that of the other rdatas in the rdataset."""
-    pass
-
-class IncompatibleTypes(dns.exception.DNSException):
-    """Raised if an attempt is made to add rdata of an incompatible type."""
-    pass
-
-class Rdataset(dns.set.Set):
-    """A DNS rdataset.
-
-    @ivar rdclass: The class of the rdataset
-    @type rdclass: int
-    @ivar rdtype: The type of the rdataset
-    @type rdtype: int
-    @ivar covers: The covered type.  Usually this value is
-    dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
-    dns.rdatatype.RRSIG, then the covers value will be the rdata
-    type the SIG/RRSIG covers.  The library treats the SIG and RRSIG
-    types as if they were a family of
-    types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA).  This makes RRSIGs much
-    easier to work with than if RRSIGs covering different rdata
-    types were aggregated into a single RRSIG rdataset.
-    @type covers: int
-    @ivar ttl: The DNS TTL (Time To Live) value
-    @type ttl: int
-    """
-
-    __slots__ = ['rdclass', 'rdtype', 'covers', 'ttl']
-
-    def __init__(self, rdclass, rdtype, covers=dns.rdatatype.NONE):
-        """Create a new rdataset of the specified class and type.
-
-        @see: the description of the class instance variables for the
-        meaning of I{rdclass} and I{rdtype}"""
-
-        super(Rdataset, self).__init__()
-        self.rdclass = rdclass
-        self.rdtype = rdtype
-        self.covers = covers
-        self.ttl = 0
-
-    def _clone(self):
-        obj = super(Rdataset, self)._clone()
-        obj.rdclass = self.rdclass
-        obj.rdtype = self.rdtype
-        obj.covers = self.covers
-        obj.ttl = self.ttl
-        return obj
-
-    def update_ttl(self, ttl):
-        """Set the TTL of the rdataset to be the lesser of the set's current
-        TTL or the specified TTL.  If the set contains no rdatas, set the TTL
-        to the specified TTL.
-        @param ttl: The TTL
-        @type ttl: int"""
-
-        if len(self) == 0:
-            self.ttl = ttl
-        elif ttl < self.ttl:
-            self.ttl = ttl
-
-    def add(self, rd, ttl=None):
-        """Add the specified rdata to the rdataset.
-
-        If the optional I{ttl} parameter is supplied, then
-        self.update_ttl(ttl) will be called prior to adding the rdata.
-
-        @param rd: The rdata
-        @type rd: dns.rdata.Rdata object
-        @param ttl: The TTL
-        @type ttl: int"""
-
-        #
-        # If we're adding a signature, do some special handling to
-        # check that the signature covers the same type as the
-        # other rdatas in this rdataset.  If this is the first rdata
-        # in the set, initialize the covers field.
-        #
-        if self.rdclass != rd.rdclass or self.rdtype != rd.rdtype:
-            raise IncompatibleTypes
-        if not ttl is None:
-            self.update_ttl(ttl)
-        if self.rdtype == dns.rdatatype.RRSIG or \
-           self.rdtype == dns.rdatatype.SIG:
-            covers = rd.covers()
-            if len(self) == 0 and self.covers == dns.rdatatype.NONE:
-                self.covers = covers
-            elif self.covers != covers:
-                raise DifferingCovers
-        if dns.rdatatype.is_singleton(rd.rdtype) and len(self) > 0:
-            self.clear()
-        super(Rdataset, self).add(rd)
-
-    def union_update(self, other):
-        self.update_ttl(other.ttl)
-        super(Rdataset, self).union_update(other)
-
-    def intersection_update(self, other):
-        self.update_ttl(other.ttl)
-        super(Rdataset, self).intersection_update(other)
-
-    def update(self, other):
-        """Add all rdatas in other to self.
-
-        @param other: The rdataset from which to update
-        @type other: dns.rdataset.Rdataset object"""
-
-        self.update_ttl(other.ttl)
-        super(Rdataset, self).update(other)
-
-    def __repr__(self):
-        if self.covers == 0:
-            ctext = ''
-        else:
-            ctext = '(' + dns.rdatatype.to_text(self.covers) + ')'
-        return '<DNS ' + dns.rdataclass.to_text(self.rdclass) + ' ' + \
-               dns.rdatatype.to_text(self.rdtype) + ctext + ' rdataset>'
-
-    def __str__(self):
-        return self.to_text()
-
-    def __eq__(self, other):
-        """Two rdatasets are equal if they have the same class, type, and
-        covers, and contain the same rdata.
-        @rtype: bool"""
-
-        if not isinstance(other, Rdataset):
-            return False
-        if self.rdclass != other.rdclass or \
-           self.rdtype != other.rdtype or \
-           self.covers != other.covers:
-            return False
-        return super(Rdataset, self).__eq__(other)
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def to_text(self, name=None, origin=None, relativize=True,
-                override_rdclass=None, **kw):
-        """Convert the rdataset into DNS master file format.
-
-        @see: L{dns.name.Name.choose_relativity} for more information
-        on how I{origin} and I{relativize} determine the way names
-        are emitted.
-
-        Any additional keyword arguments are passed on to the rdata
-        to_text() method.
-
-        @param name: If name is not None, emit a RRs with I{name} as
-        the owner name.
-        @type name: dns.name.Name object
-        @param origin: The origin for relative names, or None.
-        @type origin: dns.name.Name object
-        @param relativize: True if names should names be relativized
-        @type relativize: bool"""
-        if not name is None:
-            name = name.choose_relativity(origin, relativize)
-            ntext = str(name)
-            pad = ' '
-        else:
-            ntext = ''
-            pad = ''
-        s = StringIO.StringIO()
-        if not override_rdclass is None:
-            rdclass = override_rdclass
-        else:
-            rdclass = self.rdclass
-        if len(self) == 0:
-            #
-            # Empty rdatasets are used for the question section, and in
-            # some dynamic updates, so we don't need to print out the TTL
-            # (which is meaningless anyway).
-            #
-            print >> s, '%s%s%s %s' % (ntext, pad,
-                                       dns.rdataclass.to_text(rdclass),
-                                       dns.rdatatype.to_text(self.rdtype))
-        else:
-            for rd in self:
-                print >> s, '%s%s%d %s %s %s' % \
-                      (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass),
-                       dns.rdatatype.to_text(self.rdtype),
-                       rd.to_text(origin=origin, relativize=relativize, **kw))
-        #
-        # We strip off the final \n for the caller's convenience in printing
-        #
-        return s.getvalue()[:-1]
-
-    def to_wire(self, name, file, compress=None, origin=None,
-                override_rdclass=None, want_shuffle=True):
-        """Convert the rdataset to wire format.
-
-        @param name: The owner name of the RRset that will be emitted
-        @type name: dns.name.Name object
-        @param file: The file to which the wire format data will be appended
-        @type file: file
-        @param compress: The compression table to use; the default is None.
-        @type compress: dict
-        @param origin: The origin to be appended to any relative names when
-        they are emitted.  The default is None.
-        @returns: the number of records emitted
-        @rtype: int
-        """
-
-        if not override_rdclass is None:
-            rdclass =  override_rdclass
-            want_shuffle = False
-        else:
-            rdclass = self.rdclass
-        file.seek(0, 2)
-        if len(self) == 0:
-            name.to_wire(file, compress, origin)
-            stuff = struct.pack("!HHIH", self.rdtype, rdclass, 0, 0)
-            file.write(stuff)
-            return 1
-        else:
-            if want_shuffle:
-                l = list(self)
-                random.shuffle(l)
-            else:
-                l = self
-            for rd in l:
-                name.to_wire(file, compress, origin)
-                stuff = struct.pack("!HHIH", self.rdtype, rdclass,
-                                    self.ttl, 0)
-                file.write(stuff)
-                start = file.tell()
-                rd.to_wire(file, compress, origin)
-                end = file.tell()
-                assert end - start < 65536
-                file.seek(start - 2)
-                stuff = struct.pack("!H", end - start)
-                file.write(stuff)
-                file.seek(0, 2)
-            return len(self)
-
-    def match(self, rdclass, rdtype, covers):
-        """Returns True if this rdataset matches the specified class, type,
-        and covers"""
-        if self.rdclass == rdclass and \
-           self.rdtype == rdtype and \
-           self.covers == covers:
-            return True
-        return False
-
-def from_text_list(rdclass, rdtype, ttl, text_rdatas):
-    """Create an rdataset with the specified class, type, and TTL, and with
-    the specified list of rdatas in text format.
-
-    @rtype: dns.rdataset.Rdataset object
-    """
-
-    if isinstance(rdclass, str):
-        rdclass = dns.rdataclass.from_text(rdclass)
-    if isinstance(rdtype, str):
-        rdtype = dns.rdatatype.from_text(rdtype)
-    r = Rdataset(rdclass, rdtype)
-    r.update_ttl(ttl)
-    for t in text_rdatas:
-        rd = dns.rdata.from_text(r.rdclass, r.rdtype, t)
-        r.add(rd)
-    return r
-
-def from_text(rdclass, rdtype, ttl, *text_rdatas):
-    """Create an rdataset with the specified class, type, and TTL, and with
-    the specified rdatas in text format.
-
-    @rtype: dns.rdataset.Rdataset object
-    """
-
-    return from_text_list(rdclass, rdtype, ttl, text_rdatas)
-
-def from_rdata_list(ttl, rdatas):
-    """Create an rdataset with the specified TTL, and with
-    the specified list of rdata objects.
-
-    @rtype: dns.rdataset.Rdataset object
-    """
-
-    if len(rdatas) == 0:
-        raise ValueError("rdata list must not be empty")
-    r = None
-    for rd in rdatas:
-        if r is None:
-            r = Rdataset(rd.rdclass, rd.rdtype)
-            r.update_ttl(ttl)
-            first_time = False
-        r.add(rd)
-    return r
-
-def from_rdata(ttl, *rdatas):
-    """Create an rdataset with the specified TTL, and with
-    the specified rdata objects.
-
-    @rtype: dns.rdataset.Rdataset object
-    """
-
-    return from_rdata_list(ttl, rdatas)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdatatype.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdatatype.py
deleted file mode 100644
index 1a02b7d..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdatatype.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Rdata Types.
-
-@var _by_text: The rdata type textual name to value mapping
-@type _by_text: dict
-@var _by_value: The rdata type value to textual name mapping
-@type _by_value: dict
-@var _metatypes: If an rdatatype is a metatype, there will be a mapping
-whose key is the rdatatype value and whose value is True in this dictionary.
-@type _metatypes: dict
-@var _singletons: If an rdatatype is a singleton, there will be a mapping
-whose key is the rdatatype value and whose value is True in this dictionary.
-@type _singletons: dict"""
-
-import re
-
-import dns.exception
-
-NONE = 0
-A = 1
-NS = 2
-MD = 3
-MF = 4
-CNAME = 5
-SOA = 6
-MB = 7
-MG = 8
-MR = 9
-NULL = 10
-WKS = 11
-PTR = 12
-HINFO = 13
-MINFO = 14
-MX = 15
-TXT = 16
-RP = 17
-AFSDB = 18
-X25 = 19
-ISDN = 20
-RT = 21
-NSAP = 22
-NSAP_PTR = 23
-SIG = 24
-KEY = 25
-PX = 26
-GPOS = 27
-AAAA = 28
-LOC = 29
-NXT = 30
-SRV = 33
-NAPTR = 35
-KX = 36
-CERT = 37
-A6 = 38
-DNAME = 39
-OPT = 41
-APL = 42
-DS = 43
-SSHFP = 44
-IPSECKEY = 45
-RRSIG = 46
-NSEC = 47
-DNSKEY = 48
-DHCID = 49
-NSEC3 = 50
-NSEC3PARAM = 51
-HIP = 55
-SPF = 99
-UNSPEC = 103
-TKEY = 249
-TSIG = 250
-IXFR = 251
-AXFR = 252
-MAILB = 253
-MAILA = 254
-ANY = 255
-TA = 32768
-DLV = 32769
-
-_by_text = {
-    'NONE' : NONE,
-    'A' : A,
-    'NS' : NS,
-    'MD' : MD,
-    'MF' : MF,
-    'CNAME' : CNAME,
-    'SOA' : SOA,
-    'MB' : MB,
-    'MG' : MG,
-    'MR' : MR,
-    'NULL' : NULL,
-    'WKS' : WKS,
-    'PTR' : PTR,
-    'HINFO' : HINFO,
-    'MINFO' : MINFO,
-    'MX' : MX,
-    'TXT' : TXT,
-    'RP' : RP,
-    'AFSDB' : AFSDB,
-    'X25' : X25,
-    'ISDN' : ISDN,
-    'RT' : RT,
-    'NSAP' : NSAP,
-    'NSAP-PTR' : NSAP_PTR,
-    'SIG' : SIG,
-    'KEY' : KEY,
-    'PX' : PX,
-    'GPOS' : GPOS,
-    'AAAA' : AAAA,
-    'LOC' : LOC,
-    'NXT' : NXT,
-    'SRV' : SRV,
-    'NAPTR' : NAPTR,
-    'KX' : KX,
-    'CERT' : CERT,
-    'A6' : A6,
-    'DNAME' : DNAME,
-    'OPT' : OPT,
-    'APL' : APL,
-    'DS' : DS,
-    'SSHFP' : SSHFP,
-    'IPSECKEY' : IPSECKEY,
-    'RRSIG' : RRSIG,
-    'NSEC' : NSEC,
-    'DNSKEY' : DNSKEY,
-    'DHCID' : DHCID,
-    'NSEC3' : NSEC3,
-    'NSEC3PARAM' : NSEC3PARAM,
-    'HIP' : HIP,
-    'SPF' : SPF,
-    'UNSPEC' : UNSPEC,
-    'TKEY' : TKEY,
-    'TSIG' : TSIG,
-    'IXFR' : IXFR,
-    'AXFR' : AXFR,
-    'MAILB' : MAILB,
-    'MAILA' : MAILA,
-    'ANY' : ANY,
-    'TA' : TA,
-    'DLV' : DLV,
-    }
-
-# We construct the inverse mapping programmatically to ensure that we
-# cannot make any mistakes (e.g. omissions, cut-and-paste errors) that
-# would cause the mapping not to be true inverse.
-
-_by_value = dict([(y, x) for x, y in _by_text.iteritems()])
-
-
-_metatypes = {
-    OPT : True
-    }
-
-_singletons = {
-    SOA : True,
-    NXT : True,
-    DNAME : True,
-    NSEC : True,
-    # CNAME is technically a singleton, but we allow multiple CNAMEs.
-    }
-
-_unknown_type_pattern = re.compile('TYPE([0-9]+)$', re.I);
-
-class UnknownRdatatype(dns.exception.DNSException):
-    """Raised if a type is unknown."""
-    pass
-
-def from_text(text):
-    """Convert text into a DNS rdata type value.
-    @param text: the text
-    @type text: string
-    @raises dns.rdatatype.UnknownRdatatype: the type is unknown
-    @raises ValueError: the rdata type value is not >= 0 and <= 65535
-    @rtype: int"""
-
-    value = _by_text.get(text.upper())
-    if value is None:
-        match = _unknown_type_pattern.match(text)
-        if match == None:
-            raise UnknownRdatatype
-        value = int(match.group(1))
-        if value < 0 or value > 65535:
-            raise ValueError("type must be between >= 0 and <= 65535")
-    return value
-
-def to_text(value):
-    """Convert a DNS rdata type to text.
-    @param value: the rdata type value
-    @type value: int
-    @raises ValueError: the rdata type value is not >= 0 and <= 65535
-    @rtype: string"""
-
-    if value < 0 or value > 65535:
-        raise ValueError("type must be between >= 0 and <= 65535")
-    text = _by_value.get(value)
-    if text is None:
-        text = 'TYPE' + `value`
-    return text
-
-def is_metatype(rdtype):
-    """True if the type is a metatype.
-    @param rdtype: the type
-    @type rdtype: int
-    @rtype: bool"""
-
-    if rdtype >= TKEY and rdtype <= ANY or _metatypes.has_key(rdtype):
-        return True
-    return False
-
-def is_singleton(rdtype):
-    """True if the type is a singleton.
-    @param rdtype: the type
-    @type rdtype: int
-    @rtype: bool"""
-
-    if _singletons.has_key(rdtype):
-        return True
-    return False
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/AFSDB.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/AFSDB.py
deleted file mode 100644
index e8ca6f5..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/AFSDB.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.mxbase
-
-class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX):
-    """AFSDB record
-
-    @ivar subtype: the subtype value
-    @type subtype: int
-    @ivar hostname: the hostname name
-    @type hostname: dns.name.Name object"""
-
-    # Use the property mechanism to make "subtype" an alias for the
-    # "preference" attribute, and "hostname" an alias for the "exchange"
-    # attribute.
-    #
-    # This lets us inherit the UncompressedMX implementation but lets
-    # the caller use appropriate attribute names for the rdata type.
-    #
-    # We probably lose some performance vs. a cut-and-paste
-    # implementation, but this way we don't copy code, and that's
-    # good.
-
-    def get_subtype(self):
-        return self.preference
-
-    def set_subtype(self, subtype):
-        self.preference = subtype
-
-    subtype = property(get_subtype, set_subtype)
-
-    def get_hostname(self):
-        return self.exchange
-
-    def set_hostname(self, hostname):
-        self.exchange = hostname
-
-    hostname = property(get_hostname, set_hostname)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/CERT.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/CERT.py
deleted file mode 100644
index d270351..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/CERT.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-import struct
-
-import dns.exception
-import dns.dnssec
-import dns.rdata
-import dns.tokenizer
-
-_ctype_by_value = {
-    1 : 'PKIX',
-    2 : 'SPKI',
-    3 : 'PGP',
-    253 : 'URI',
-    254 : 'OID',
-    }
-
-_ctype_by_name = {
-    'PKIX' : 1,
-    'SPKI' : 2,
-    'PGP' : 3,
-    'URI' : 253,
-    'OID' : 254,
-    }
-
-def _ctype_from_text(what):
-    v = _ctype_by_name.get(what)
-    if not v is None:
-        return v
-    return int(what)
-
-def _ctype_to_text(what):
-    v = _ctype_by_value.get(what)
-    if not v is None:
-        return v
-    return str(what)
-
-class CERT(dns.rdata.Rdata):
-    """CERT record
-
-    @ivar certificate_type: certificate type
-    @type certificate_type: int
-    @ivar key_tag: key tag
-    @type key_tag: int
-    @ivar algorithm: algorithm
-    @type algorithm: int
-    @ivar certificate: the certificate or CRL
-    @type certificate: string
-    @see: RFC 2538"""
-
-    __slots__ = ['certificate_type', 'key_tag', 'algorithm', 'certificate']
-
-    def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm,
-                 certificate):
-        super(CERT, self).__init__(rdclass, rdtype)
-        self.certificate_type = certificate_type
-        self.key_tag = key_tag
-        self.algorithm = algorithm
-        self.certificate = certificate
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        certificate_type = _ctype_to_text(self.certificate_type)
-        return "%s %d %s %s" % (certificate_type, self.key_tag,
-                                dns.dnssec.algorithm_to_text(self.algorithm),
-                                dns.rdata._base64ify(self.certificate))
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        certificate_type = _ctype_from_text(tok.get_string())
-        key_tag = tok.get_uint16()
-        algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
-        if algorithm < 0 or algorithm > 255:
-            raise dns.exception.SyntaxError("bad algorithm type")
-        chunks = []
-        while 1:
-            t = tok.get().unescape()
-            if t.is_eol_or_eof():
-                break
-            if not t.is_identifier():
-                raise dns.exception.SyntaxError
-            chunks.append(t.value)
-        b64 = ''.join(chunks)
-        certificate = b64.decode('base64_codec')
-        return cls(rdclass, rdtype, certificate_type, key_tag,
-                   algorithm, certificate)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        prefix = struct.pack("!HHB", self.certificate_type, self.key_tag,
-                             self.algorithm)
-        file.write(prefix)
-        file.write(self.certificate)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        prefix = wire[current : current + 5]
-        current += 5
-        rdlen -= 5
-        if rdlen < 0:
-            raise dns.exception.FormError
-        (certificate_type, key_tag, algorithm) = struct.unpack("!HHB", prefix)
-        certificate = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, certificate_type, key_tag, algorithm,
-                   certificate)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        f = cStringIO.StringIO()
-        self.to_wire(f)
-        wire1 = f.getvalue()
-        f.seek(0)
-        f.truncate()
-        other.to_wire(f)
-        wire2 = f.getvalue()
-        f.close()
-
-        return cmp(wire1, wire2)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/CNAME.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/CNAME.py
deleted file mode 100644
index 7f5c4b3..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/CNAME.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.nsbase
-
-class CNAME(dns.rdtypes.nsbase.NSBase):
-    """CNAME record
-
-    Note: although CNAME is officially a singleton type, dnspython allows
-    non-singleton CNAME rdatasets because such sets have been commonly
-    used by BIND and other nameservers for load balancing."""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DLV.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DLV.py
deleted file mode 100644
index 07b9548..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DLV.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.dsbase
-
-class DLV(dns.rdtypes.dsbase.DSBase):
-    """DLV record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DNAME.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DNAME.py
deleted file mode 100644
index 99b5013..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DNAME.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.nsbase
-
-class DNAME(dns.rdtypes.nsbase.UncompressedNS):
-    """DNAME record"""
-    def to_digestable(self, origin = None):
-        return self.target.to_digestable(origin)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DNSKEY.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DNSKEY.py
deleted file mode 100644
index ad66ef0..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DNSKEY.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.keybase
-
-# flag constants
-SEP = 0x0001
-REVOKE = 0x0080
-ZONE = 0x0100
-
-class DNSKEY(dns.rdtypes.keybase.KEYBase):
-    """DNSKEY record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DS.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DS.py
deleted file mode 100644
index 3a06f44..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/DS.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.dsbase
-
-class DS(dns.rdtypes.dsbase.DSBase):
-    """DS record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/GPOS.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/GPOS.py
deleted file mode 100644
index 6f63cc0..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/GPOS.py
+++ /dev/null
@@ -1,156 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.tokenizer
-
-def _validate_float_string(what):
-    if what[0] == '-' or what[0] == '+':
-        what = what[1:]
-    if what.isdigit():
-        return
-    (left, right) = what.split('.')
-    if left == '' and right == '':
-        raise dns.exception.FormError
-    if not left == '' and not left.isdigit():
-        raise dns.exception.FormError
-    if not right == '' and not right.isdigit():
-        raise dns.exception.FormError
-    
-class GPOS(dns.rdata.Rdata):
-    """GPOS record
-
-    @ivar latitude: latitude
-    @type latitude: string
-    @ivar longitude: longitude
-    @type longitude: string
-    @ivar altitude: altitude
-    @type altitude: string
-    @see: RFC 1712"""
-
-    __slots__ = ['latitude', 'longitude', 'altitude']
-    
-    def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
-        super(GPOS, self).__init__(rdclass, rdtype)
-        if isinstance(latitude, float) or \
-           isinstance(latitude, int) or \
-           isinstance(latitude, long):
-            latitude = str(latitude)
-        if isinstance(longitude, float) or \
-           isinstance(longitude, int) or \
-           isinstance(longitude, long):
-            longitude = str(longitude)
-        if isinstance(altitude, float) or \
-           isinstance(altitude, int) or \
-           isinstance(altitude, long):
-            altitude = str(altitude)
-        _validate_float_string(latitude)
-        _validate_float_string(longitude)
-        _validate_float_string(altitude)
-        self.latitude = latitude
-        self.longitude = longitude
-        self.altitude = altitude
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '%s %s %s' % (self.latitude, self.longitude, self.altitude)
-        
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        latitude = tok.get_string()
-        longitude = tok.get_string()
-        altitude = tok.get_string()
-        tok.get_eol()
-        return cls(rdclass, rdtype, latitude, longitude, altitude)
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        l = len(self.latitude)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.latitude)
-        l = len(self.longitude)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.longitude)
-        l = len(self.altitude)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.altitude)
-        
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l > rdlen:
-            raise dns.exception.FormError
-        latitude = wire[current : current + l]
-        current += l
-        rdlen -= l
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l > rdlen:
-            raise dns.exception.FormError
-        longitude = wire[current : current + l]
-        current += l
-        rdlen -= l
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l != rdlen:
-            raise dns.exception.FormError
-        altitude = wire[current : current + l]
-        return cls(rdclass, rdtype, latitude, longitude, altitude)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        v = cmp(self.latitude, other.latitude)
-        if v == 0:
-            v = cmp(self.longitude, other.longitude)
-            if v == 0:
-                v = cmp(self.altitude, other.altitude)
-        return v
-
-    def _get_float_latitude(self):
-        return float(self.latitude)
-
-    def _set_float_latitude(self, value):
-        self.latitude = str(value)
-
-    float_latitude = property(_get_float_latitude, _set_float_latitude,
-                              doc="latitude as a floating point value")
-
-    def _get_float_longitude(self):
-        return float(self.longitude)
-
-    def _set_float_longitude(self, value):
-        self.longitude = str(value)
-
-    float_longitude = property(_get_float_longitude, _set_float_longitude,
-                               doc="longitude as a floating point value")
-
-    def _get_float_altitude(self):
-        return float(self.altitude)
-
-    def _set_float_altitude(self, value):
-        self.altitude = str(value)
-
-    float_altitude = property(_get_float_altitude, _set_float_altitude,
-                              doc="altitude as a floating point value")
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/HINFO.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/HINFO.py
deleted file mode 100644
index e592ad3..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/HINFO.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.tokenizer
-
-class HINFO(dns.rdata.Rdata):
-    """HINFO record
-
-    @ivar cpu: the CPU type
-    @type cpu: string
-    @ivar os: the OS type
-    @type os: string
-    @see: RFC 1035"""
-
-    __slots__ = ['cpu', 'os']
-    
-    def __init__(self, rdclass, rdtype, cpu, os):
-        super(HINFO, self).__init__(rdclass, rdtype)
-        self.cpu = cpu
-        self.os = os
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '"%s" "%s"' % (dns.rdata._escapify(self.cpu),
-                              dns.rdata._escapify(self.os))
-        
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        cpu = tok.get_string()
-        os = tok.get_string()
-        tok.get_eol()
-        return cls(rdclass, rdtype, cpu, os)
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        l = len(self.cpu)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.cpu)
-        l = len(self.os)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.os)
-        
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l > rdlen:
-            raise dns.exception.FormError
-        cpu = wire[current : current + l]
-        current += l
-        rdlen -= l
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l != rdlen:
-            raise dns.exception.FormError
-        os = wire[current : current + l]
-        return cls(rdclass, rdtype, cpu, os)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        v = cmp(self.cpu, other.cpu)
-        if v == 0:
-            v = cmp(self.os, other.os)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/HIP.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/HIP.py
deleted file mode 100644
index 8f96ae9..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/HIP.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# Copyright (C) 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-import string
-import struct
-
-import dns.exception
-import dns.rdata
-import dns.rdatatype
-
-class HIP(dns.rdata.Rdata):
-    """HIP record
-
-    @ivar hit: the host identity tag
-    @type hit: string
-    @ivar algorithm: the public key cryptographic algorithm
-    @type algorithm: int
-    @ivar key: the public key
-    @type key: string
-    @ivar servers: the rendezvous servers
-    @type servers: list of dns.name.Name objects
-    @see: RFC 5205"""
-
-    __slots__ = ['hit', 'algorithm', 'key', 'servers']
-
-    def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
-        super(HIP, self).__init__(rdclass, rdtype)
-        self.hit = hit
-        self.algorithm = algorithm
-        self.key = key
-        self.servers = servers
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        hit = self.hit.encode('hex-codec')
-        key = self.key.encode('base64-codec').replace('\n', '')
-        text = ''
-        servers = []
-        for server in self.servers:
-            servers.append(str(server.choose_relativity(origin, relativize)))
-        if len(servers) > 0:
-            text += (' ' + ' '.join(servers))
-        return '%u %s %s%s' % (self.algorithm, hit, key, text)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        algorithm = tok.get_uint8()
-        hit = tok.get_string().decode('hex-codec')
-        if len(hit) > 255:
-            raise dns.exception.SyntaxError("HIT too long")
-        key = tok.get_string().decode('base64-codec')
-        servers = []
-        while 1:
-            token = tok.get()
-            if token.is_eol_or_eof():
-                break
-            server = dns.name.from_text(token.value, origin)
-            server.choose_relativity(origin, relativize)
-            servers.append(server)
-        return cls(rdclass, rdtype, hit, algorithm, key, servers)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        lh = len(self.hit)
-        lk = len(self.key)
-        file.write(struct.pack("!BBH", lh, self.algorithm, lk))
-        file.write(self.hit)
-        file.write(self.key)
-        for server in self.servers:
-            server.to_wire(file, None, origin)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (lh, algorithm, lk) = struct.unpack('!BBH',
-                                            wire[current : current + 4])
-        current += 4
-        rdlen -= 4
-        hit = wire[current : current + lh]
-        current += lh
-        rdlen -= lh
-        key = wire[current : current + lk]
-        current += lk
-        rdlen -= lk
-        servers = []
-        while rdlen > 0:
-            (server, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                                 current)
-            current += cused
-            rdlen -= cused
-            if not origin is None:
-                server = server.relativize(origin)
-            servers.append(server)
-        return cls(rdclass, rdtype, hit, algorithm, key, servers)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        servers = []
-        for server in self.servers:
-            server = server.choose_relativity(origin, relativize)
-            servers.append(server)
-        self.servers = servers
-
-    def _cmp(self, other):
-        b1 = cStringIO.StringIO()
-        lh = len(self.hit)
-        lk = len(self.key)
-        b1.write(struct.pack("!BBH", lh, self.algorithm, lk))
-        b1.write(self.hit)
-        b1.write(self.key)
-        b2 = cStringIO.StringIO()
-        lh = len(other.hit)
-        lk = len(other.key)
-        b2.write(struct.pack("!BBH", lh, other.algorithm, lk))
-        b2.write(other.hit)
-        b2.write(other.key)
-        v = cmp(b1.getvalue(), b2.getvalue())
-        if v != 0:
-            return v
-        ls = len(self.servers)
-        lo = len(other.servers)
-        count = min(ls, lo)
-        i = 0
-        while i < count:
-            v = cmp(self.servers[i], other.servers[i])
-            if v != 0:
-                return v
-            i += 1
-        return ls - lo
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/ISDN.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/ISDN.py
deleted file mode 100644
index 424d3a9..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/ISDN.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.tokenizer
-
-class ISDN(dns.rdata.Rdata):
-    """ISDN record
-
-    @ivar address: the ISDN address
-    @type address: string
-    @ivar subaddress: the ISDN subaddress (or '' if not present)
-    @type subaddress: string
-    @see: RFC 1183"""
-
-    __slots__ = ['address', 'subaddress']
-
-    def __init__(self, rdclass, rdtype, address, subaddress):
-        super(ISDN, self).__init__(rdclass, rdtype)
-        self.address = address
-        self.subaddress = subaddress
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        if self.subaddress:
-            return '"%s" "%s"' % (dns.rdata._escapify(self.address),
-                                  dns.rdata._escapify(self.subaddress))
-        else:
-            return '"%s"' % dns.rdata._escapify(self.address)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_string()
-        t = tok.get()
-        if not t.is_eol_or_eof():
-            tok.unget(t)
-            subaddress = tok.get_string()
-        else:
-            tok.unget(t)
-            subaddress = ''
-        tok.get_eol()
-        return cls(rdclass, rdtype, address, subaddress)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        l = len(self.address)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.address)
-        l = len(self.subaddress)
-        if l > 0:
-            assert l < 256
-            byte = chr(l)
-            file.write(byte)
-            file.write(self.subaddress)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l > rdlen:
-            raise dns.exception.FormError
-        address = wire[current : current + l]
-        current += l
-        rdlen -= l
-        if rdlen > 0:
-            l = ord(wire[current])
-            current += 1
-            rdlen -= 1
-            if l != rdlen:
-                raise dns.exception.FormError
-            subaddress = wire[current : current + l]
-        else:
-            subaddress = ''
-        return cls(rdclass, rdtype, address, subaddress)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        v = cmp(self.address, other.address)
-        if v == 0:
-            v = cmp(self.subaddress, other.subaddress)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/KEY.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/KEY.py
deleted file mode 100644
index c8581ed..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/KEY.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.keybase
-
-class KEY(dns.rdtypes.keybase.KEYBase):
-    """KEY record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/LOC.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/LOC.py
deleted file mode 100644
index 518dd60..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/LOC.py
+++ /dev/null
@@ -1,334 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-import struct
-
-import dns.exception
-import dns.rdata
-
-_pows = (1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L,
-         100000000L, 1000000000L, 10000000000L)
-
-def _exponent_of(what, desc):
-    exp = None
-    for i in xrange(len(_pows)):
-        if what // _pows[i] == 0L:
-            exp = i - 1
-            break
-    if exp is None or exp < 0:
-        raise dns.exception.SyntaxError("%s value out of bounds" % desc)
-    return exp
-
-def _float_to_tuple(what):
-    if what < 0:
-        sign = -1
-        what *= -1
-    else:
-        sign = 1
-    what = long(round(what * 3600000))
-    degrees = int(what // 3600000)
-    what -= degrees * 3600000
-    minutes = int(what // 60000)
-    what -= minutes * 60000
-    seconds = int(what // 1000)
-    what -= int(seconds * 1000)
-    what = int(what)
-    return (degrees * sign, minutes, seconds, what)
-
-def _tuple_to_float(what):
-    if what[0] < 0:
-        sign = -1
-        value = float(what[0]) * -1
-    else:
-        sign = 1
-        value = float(what[0])
-    value += float(what[1]) / 60.0
-    value += float(what[2]) / 3600.0
-    value += float(what[3]) / 3600000.0
-    return sign * value
-
-def _encode_size(what, desc):
-    what = long(what);
-    exponent = _exponent_of(what, desc) & 0xF
-    base = what // pow(10, exponent) & 0xF
-    return base * 16 + exponent
-
-def _decode_size(what, desc):
-    exponent = what & 0x0F
-    if exponent > 9:
-        raise dns.exception.SyntaxError("bad %s exponent" % desc)
-    base = (what & 0xF0) >> 4
-    if base > 9:
-        raise dns.exception.SyntaxError("bad %s base" % desc)
-    return long(base) * pow(10, exponent)
-
-class LOC(dns.rdata.Rdata):
-    """LOC record
-
-    @ivar latitude: latitude
-    @type latitude: (int, int, int, int) tuple specifying the degrees, minutes,
-    seconds, and milliseconds of the coordinate.
-    @ivar longitude: longitude
-    @type longitude: (int, int, int, int) tuple specifying the degrees,
-    minutes, seconds, and milliseconds of the coordinate.
-    @ivar altitude: altitude
-    @type altitude: float
-    @ivar size: size of the sphere
-    @type size: float
-    @ivar horizontal_precision: horizontal precision
-    @type horizontal_precision: float
-    @ivar vertical_precision: vertical precision
-    @type vertical_precision: float
-    @see: RFC 1876"""
-
-    __slots__ = ['latitude', 'longitude', 'altitude', 'size',
-                 'horizontal_precision', 'vertical_precision']
-
-    def __init__(self, rdclass, rdtype, latitude, longitude, altitude,
-                 size=1.0, hprec=10000.0, vprec=10.0):
-        """Initialize a LOC record instance.
-
-        The parameters I{latitude} and I{longitude} may be either a 4-tuple
-        of integers specifying (degrees, minutes, seconds, milliseconds),
-        or they may be floating point values specifying the number of
-        degrees.  The other parameters are floats."""
-
-        super(LOC, self).__init__(rdclass, rdtype)
-        if isinstance(latitude, int) or isinstance(latitude, long):
-            latitude = float(latitude)
-        if isinstance(latitude, float):
-            latitude = _float_to_tuple(latitude)
-        self.latitude = latitude
-        if isinstance(longitude, int) or isinstance(longitude, long):
-            longitude = float(longitude)
-        if isinstance(longitude, float):
-            longitude = _float_to_tuple(longitude)
-        self.longitude = longitude
-        self.altitude = float(altitude)
-        self.size = float(size)
-        self.horizontal_precision = float(hprec)
-        self.vertical_precision = float(vprec)
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        if self.latitude[0] > 0:
-            lat_hemisphere = 'N'
-            lat_degrees = self.latitude[0]
-        else:
-            lat_hemisphere = 'S'
-            lat_degrees = -1 * self.latitude[0]
-        if self.longitude[0] > 0:
-            long_hemisphere = 'E'
-            long_degrees = self.longitude[0]
-        else:
-            long_hemisphere = 'W'
-            long_degrees = -1 * self.longitude[0]
-        text = "%d %d %d.%03d %s %d %d %d.%03d %s %0.2fm" % (
-            lat_degrees, self.latitude[1], self.latitude[2], self.latitude[3],
-            lat_hemisphere, long_degrees, self.longitude[1], self.longitude[2],
-            self.longitude[3], long_hemisphere, self.altitude / 100.0
-            )
-
-        if self.size != 1.0 or self.horizontal_precision != 10000.0 or \
-           self.vertical_precision != 10.0:
-            text += " %0.2fm %0.2fm %0.2fm" % (
-                self.size / 100.0, self.horizontal_precision / 100.0,
-                self.vertical_precision / 100.0
-            )
-        return text
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        latitude = [0, 0, 0, 0]
-        longitude = [0, 0, 0, 0]
-        size = 1.0
-        hprec = 10000.0
-        vprec = 10.0
-
-        latitude[0] = tok.get_int()
-        t = tok.get_string()
-        if t.isdigit():
-            latitude[1] = int(t)
-            t = tok.get_string()
-            if '.' in t:
-                (seconds, milliseconds) = t.split('.')
-                if not seconds.isdigit():
-                    raise dns.exception.SyntaxError('bad latitude seconds value')
-                latitude[2] = int(seconds)
-                if latitude[2] >= 60:
-                    raise dns.exception.SyntaxError('latitude seconds >= 60')
-                l = len(milliseconds)
-                if l == 0 or l > 3 or not milliseconds.isdigit():
-                    raise dns.exception.SyntaxError('bad latitude milliseconds value')
-                if l == 1:
-                    m = 100
-                elif l == 2:
-                    m = 10
-                else:
-                    m = 1
-                latitude[3] = m * int(milliseconds)
-                t = tok.get_string()
-            elif t.isdigit():
-                latitude[2] = int(t)
-                t = tok.get_string()
-        if t == 'S':
-            latitude[0] *= -1
-        elif t != 'N':
-            raise dns.exception.SyntaxError('bad latitude hemisphere value')
-
-        longitude[0] = tok.get_int()
-        t = tok.get_string()
-        if t.isdigit():
-            longitude[1] = int(t)
-            t = tok.get_string()
-            if '.' in t:
-                (seconds, milliseconds) = t.split('.')
-                if not seconds.isdigit():
-                    raise dns.exception.SyntaxError('bad longitude seconds value')
-                longitude[2] = int(seconds)
-                if longitude[2] >= 60:
-                    raise dns.exception.SyntaxError('longitude seconds >= 60')
-                l = len(milliseconds)
-                if l == 0 or l > 3 or not milliseconds.isdigit():
-                    raise dns.exception.SyntaxError('bad longitude milliseconds value')
-                if l == 1:
-                    m = 100
-                elif l == 2:
-                    m = 10
-                else:
-                    m = 1
-                longitude[3] = m * int(milliseconds)
-                t = tok.get_string()
-            elif t.isdigit():
-                longitude[2] = int(t)
-                t = tok.get_string()
-        if t == 'W':
-            longitude[0] *= -1
-        elif t != 'E':
-            raise dns.exception.SyntaxError('bad longitude hemisphere value')
-
-        t = tok.get_string()
-        if t[-1] == 'm':
-            t = t[0 : -1]
-        altitude = float(t) * 100.0	# m -> cm
-
-        token = tok.get().unescape()
-        if not token.is_eol_or_eof():
-            value = token.value
-            if value[-1] == 'm':
-                value = value[0 : -1]
-            size = float(value) * 100.0	# m -> cm
-            token = tok.get().unescape()
-            if not token.is_eol_or_eof():
-                value = token.value
-                if value[-1] == 'm':
-                    value = value[0 : -1]
-                hprec = float(value) * 100.0	# m -> cm
-                token = tok.get().unescape()
-                if not token.is_eol_or_eof():
-                    value = token.value
-                    if value[-1] == 'm':
-                        value = value[0 : -1]
-                        vprec = float(value) * 100.0	# m -> cm
-                        tok.get_eol()
-
-        return cls(rdclass, rdtype, latitude, longitude, altitude,
-                   size, hprec, vprec)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        if self.latitude[0] < 0:
-            sign = -1
-            degrees = long(-1 * self.latitude[0])
-        else:
-            sign = 1
-            degrees = long(self.latitude[0])
-        milliseconds = (degrees * 3600000 +
-                        self.latitude[1] * 60000 +
-                        self.latitude[2] * 1000 +
-                        self.latitude[3]) * sign
-        latitude = 0x80000000L + milliseconds
-        if self.longitude[0] < 0:
-            sign = -1
-            degrees = long(-1 * self.longitude[0])
-        else:
-            sign = 1
-            degrees = long(self.longitude[0])
-        milliseconds = (degrees * 3600000 +
-                        self.longitude[1] * 60000 +
-                        self.longitude[2] * 1000 +
-                        self.longitude[3]) * sign
-        longitude = 0x80000000L + milliseconds
-        altitude = long(self.altitude) + 10000000L
-        size = _encode_size(self.size, "size")
-        hprec = _encode_size(self.horizontal_precision, "horizontal precision")
-        vprec = _encode_size(self.vertical_precision, "vertical precision")
-        wire = struct.pack("!BBBBIII", 0, size, hprec, vprec, latitude,
-                           longitude, altitude)
-        file.write(wire)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (version, size, hprec, vprec, latitude, longitude, altitude) = \
-                  struct.unpack("!BBBBIII", wire[current : current + rdlen])
-        if latitude > 0x80000000L:
-            latitude = float(latitude - 0x80000000L) / 3600000
-        else:
-            latitude = -1 * float(0x80000000L - latitude) / 3600000
-        if latitude < -90.0 or latitude > 90.0:
-            raise dns.exception.FormError("bad latitude")
-        if longitude > 0x80000000L:
-            longitude = float(longitude - 0x80000000L) / 3600000
-        else:
-            longitude = -1 * float(0x80000000L - longitude) / 3600000
-        if longitude < -180.0 or longitude > 180.0:
-            raise dns.exception.FormError("bad longitude")
-        altitude = float(altitude) - 10000000.0
-        size = _decode_size(size, "size")
-        hprec = _decode_size(hprec, "horizontal precision")
-        vprec = _decode_size(vprec, "vertical precision")
-        return cls(rdclass, rdtype, latitude, longitude, altitude,
-                   size, hprec, vprec)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        f = cStringIO.StringIO()
-        self.to_wire(f)
-        wire1 = f.getvalue()
-        f.seek(0)
-        f.truncate()
-        other.to_wire(f)
-        wire2 = f.getvalue()
-        f.close()
-
-        return cmp(wire1, wire2)
-
-    def _get_float_latitude(self):
-        return _tuple_to_float(self.latitude)
-
-    def _set_float_latitude(self, value):
-        self.latitude = _float_to_tuple(value)
-
-    float_latitude = property(_get_float_latitude, _set_float_latitude,
-                              doc="latitude as a floating point value")
-
-    def _get_float_longitude(self):
-        return _tuple_to_float(self.longitude)
-
-    def _set_float_longitude(self, value):
-        self.longitude = _float_to_tuple(value)
-
-    float_longitude = property(_get_float_longitude, _set_float_longitude,
-                               doc="longitude as a floating point value")
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/MX.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/MX.py
deleted file mode 100644
index 9cad260..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/MX.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.mxbase
-
-class MX(dns.rdtypes.mxbase.MXBase):
-    """MX record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NS.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NS.py
deleted file mode 100644
index 4b03a3a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NS.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.nsbase
-
-class NS(dns.rdtypes.nsbase.NSBase):
-    """NS record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC.py
deleted file mode 100644
index 72859ce..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC.py
+++ /dev/null
@@ -1,141 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-
-import dns.exception
-import dns.rdata
-import dns.rdatatype
-import dns.name
-
-class NSEC(dns.rdata.Rdata):
-    """NSEC record
-
-    @ivar next: the next name
-    @type next: dns.name.Name object
-    @ivar windows: the windowed bitmap list
-    @type windows: list of (window number, string) tuples"""
-
-    __slots__ = ['next', 'windows']
-
-    def __init__(self, rdclass, rdtype, next, windows):
-        super(NSEC, self).__init__(rdclass, rdtype)
-        self.next = next
-        self.windows = windows
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        next = self.next.choose_relativity(origin, relativize)
-        text = ''
-        for (window, bitmap) in self.windows:
-            bits = []
-            for i in xrange(0, len(bitmap)):
-                byte = ord(bitmap[i])
-                for j in xrange(0, 8):
-                    if byte & (0x80 >> j):
-                        bits.append(dns.rdatatype.to_text(window * 256 + \
-                                                          i * 8 + j))
-            text += (' ' + ' '.join(bits))
-        return '%s%s' % (next, text)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        next = tok.get_name()
-        next = next.choose_relativity(origin, relativize)
-        rdtypes = []
-        while 1:
-            token = tok.get().unescape()
-            if token.is_eol_or_eof():
-                break
-            nrdtype = dns.rdatatype.from_text(token.value)
-            if nrdtype == 0:
-                raise dns.exception.SyntaxError("NSEC with bit 0")
-            if nrdtype > 65535:
-                raise dns.exception.SyntaxError("NSEC with bit > 65535")
-            rdtypes.append(nrdtype)
-        rdtypes.sort()
-        window = 0
-        octets = 0
-        prior_rdtype = 0
-        bitmap = ['\0'] * 32
-        windows = []
-        for nrdtype in rdtypes:
-            if nrdtype == prior_rdtype:
-                continue
-            prior_rdtype = nrdtype
-            new_window = nrdtype // 256
-            if new_window != window:
-                windows.append((window, ''.join(bitmap[0:octets])))
-                bitmap = ['\0'] * 32
-                window = new_window
-            offset = nrdtype % 256
-            byte = offset / 8
-            bit = offset % 8
-            octets = byte + 1
-            bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit))
-        windows.append((window, ''.join(bitmap[0:octets])))
-        return cls(rdclass, rdtype, next, windows)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        self.next.to_wire(file, None, origin)
-        for (window, bitmap) in self.windows:
-            file.write(chr(window))
-            file.write(chr(len(bitmap)))
-            file.write(bitmap)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (next, cused) = dns.name.from_wire(wire[: current + rdlen], current)
-        current += cused
-        rdlen -= cused
-        windows = []
-        while rdlen > 0:
-            if rdlen < 3:
-                raise dns.exception.FormError("NSEC too short")
-            window = ord(wire[current])
-            octets = ord(wire[current + 1])
-            if octets == 0 or octets > 32:
-                raise dns.exception.FormError("bad NSEC octets")
-            current += 2
-            rdlen -= 2
-            if rdlen < octets:
-                raise dns.exception.FormError("bad NSEC bitmap length")
-            bitmap = wire[current : current + octets]
-            current += octets
-            rdlen -= octets
-            windows.append((window, bitmap))
-        if not origin is None:
-            next = next.relativize(origin)
-        return cls(rdclass, rdtype, next, windows)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.next = self.next.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        v = cmp(self.next, other.next)
-        if v == 0:
-            b1 = cStringIO.StringIO()
-            for (window, bitmap) in self.windows:
-                b1.write(chr(window))
-                b1.write(chr(len(bitmap)))
-                b1.write(bitmap)
-            b2 = cStringIO.StringIO()
-            for (window, bitmap) in other.windows:
-                b2.write(chr(window))
-                b2.write(chr(len(bitmap)))
-                b2.write(bitmap)
-            v = cmp(b1.getvalue(), b2.getvalue())
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC3.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC3.py
deleted file mode 100644
index 932d7b4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC3.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import base64
-import cStringIO
-import string
-import struct
-
-import dns.exception
-import dns.rdata
-import dns.rdatatype
-
-b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV',
-                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
-b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
-                                     '0123456789ABCDEFGHIJKLMNOPQRSTUV')
-
-# hash algorithm constants
-SHA1 = 1
-
-# flag constants
-OPTOUT = 1
-
-class NSEC3(dns.rdata.Rdata):
-    """NSEC3 record
-
-    @ivar algorithm: the hash algorithm number
-    @type algorithm: int
-    @ivar flags: the flags
-    @type flags: int
-    @ivar iterations: the number of iterations
-    @type iterations: int
-    @ivar salt: the salt
-    @type salt: string
-    @ivar next: the next name hash
-    @type next: string
-    @ivar windows: the windowed bitmap list
-    @type windows: list of (window number, string) tuples"""
-
-    __slots__ = ['algorithm', 'flags', 'iterations', 'salt', 'next', 'windows']
-
-    def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt,
-                 next, windows):
-        super(NSEC3, self).__init__(rdclass, rdtype)
-        self.algorithm = algorithm
-        self.flags = flags
-        self.iterations = iterations
-        self.salt = salt
-        self.next = next
-        self.windows = windows
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        next = base64.b32encode(self.next).translate(b32_normal_to_hex).lower()
-        if self.salt == '':
-            salt = '-'
-        else:
-            salt = self.salt.encode('hex-codec')
-        text = ''
-        for (window, bitmap) in self.windows:
-            bits = []
-            for i in xrange(0, len(bitmap)):
-                byte = ord(bitmap[i])
-                for j in xrange(0, 8):
-                    if byte & (0x80 >> j):
-                        bits.append(dns.rdatatype.to_text(window * 256 + \
-                                                          i * 8 + j))
-            text += (' ' + ' '.join(bits))
-        return '%u %u %u %s %s%s' % (self.algorithm, self.flags, self.iterations,
-                                     salt, next, text)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        algorithm = tok.get_uint8()
-        flags = tok.get_uint8()
-        iterations = tok.get_uint16()
-        salt = tok.get_string()
-        if salt == '-':
-            salt = ''
-        else:
-            salt = salt.decode('hex-codec')
-        next = tok.get_string().upper().translate(b32_hex_to_normal)
-        next = base64.b32decode(next)
-        rdtypes = []
-        while 1:
-            token = tok.get().unescape()
-            if token.is_eol_or_eof():
-                break
-            nrdtype = dns.rdatatype.from_text(token.value)
-            if nrdtype == 0:
-                raise dns.exception.SyntaxError("NSEC3 with bit 0")
-            if nrdtype > 65535:
-                raise dns.exception.SyntaxError("NSEC3 with bit > 65535")
-            rdtypes.append(nrdtype)
-        rdtypes.sort()
-        window = 0
-        octets = 0
-        prior_rdtype = 0
-        bitmap = ['\0'] * 32
-        windows = []
-        for nrdtype in rdtypes:
-            if nrdtype == prior_rdtype:
-                continue
-            prior_rdtype = nrdtype
-            new_window = nrdtype // 256
-            if new_window != window:
-                windows.append((window, ''.join(bitmap[0:octets])))
-                bitmap = ['\0'] * 32
-                window = new_window
-            offset = nrdtype % 256
-            byte = offset / 8
-            bit = offset % 8
-            octets = byte + 1
-            bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit))
-        windows.append((window, ''.join(bitmap[0:octets])))
-        return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        l = len(self.salt)
-        file.write(struct.pack("!BBHB", self.algorithm, self.flags,
-                               self.iterations, l))
-        file.write(self.salt)
-        l = len(self.next)
-        file.write(struct.pack("!B", l))
-        file.write(self.next)
-        for (window, bitmap) in self.windows:
-            file.write(chr(window))
-            file.write(chr(len(bitmap)))
-            file.write(bitmap)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (algorithm, flags, iterations, slen) = struct.unpack('!BBHB',
-                                                             wire[current : current + 5])
-        current += 5
-        rdlen -= 5
-        salt = wire[current : current + slen]
-        current += slen
-        rdlen -= slen
-        (nlen, ) = struct.unpack('!B', wire[current])
-        current += 1
-        rdlen -= 1
-        next = wire[current : current + nlen]
-        current += nlen
-        rdlen -= nlen
-        windows = []
-        while rdlen > 0:
-            if rdlen < 3:
-                raise dns.exception.FormError("NSEC3 too short")
-            window = ord(wire[current])
-            octets = ord(wire[current + 1])
-            if octets == 0 or octets > 32:
-                raise dns.exception.FormError("bad NSEC3 octets")
-            current += 2
-            rdlen -= 2
-            if rdlen < octets:
-                raise dns.exception.FormError("bad NSEC3 bitmap length")
-            bitmap = wire[current : current + octets]
-            current += octets
-            rdlen -= octets
-            windows.append((window, bitmap))
-        return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        b1 = cStringIO.StringIO()
-        self.to_wire(b1)
-        b2 = cStringIO.StringIO()
-        other.to_wire(b2)
-        return cmp(b1.getvalue(), b2.getvalue())
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC3PARAM.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC3PARAM.py
deleted file mode 100644
index ec91e5e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NSEC3PARAM.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-import struct
-
-import dns.exception
-import dns.rdata
-
-class NSEC3PARAM(dns.rdata.Rdata):
-    """NSEC3PARAM record
-
-    @ivar algorithm: the hash algorithm number
-    @type algorithm: int
-    @ivar flags: the flags
-    @type flags: int
-    @ivar iterations: the number of iterations
-    @type iterations: int
-    @ivar salt: the salt
-    @type salt: string"""
-
-    __slots__ = ['algorithm', 'flags', 'iterations', 'salt']
-
-    def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt):
-        super(NSEC3PARAM, self).__init__(rdclass, rdtype)
-        self.algorithm = algorithm
-        self.flags = flags
-        self.iterations = iterations
-        self.salt = salt
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        if self.salt == '':
-            salt = '-'
-        else:
-            salt = self.salt.encode('hex-codec')
-        return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations, salt)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        algorithm = tok.get_uint8()
-        flags = tok.get_uint8()
-        iterations = tok.get_uint16()
-        salt = tok.get_string()
-        if salt == '-':
-            salt = ''
-        else:
-            salt = salt.decode('hex-codec')
-        return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        l = len(self.salt)
-        file.write(struct.pack("!BBHB", self.algorithm, self.flags,
-                               self.iterations, l))
-        file.write(self.salt)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (algorithm, flags, iterations, slen) = struct.unpack('!BBHB',
-                                                             wire[current : current + 5])
-        current += 5
-        rdlen -= 5
-        salt = wire[current : current + slen]
-        current += slen
-        rdlen -= slen
-        if rdlen != 0:
-            raise dns.exception.FormError
-        return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        b1 = cStringIO.StringIO()
-        self.to_wire(b1)
-        b2 = cStringIO.StringIO()
-        other.to_wire(b2)
-        return cmp(b1.getvalue(), b2.getvalue())
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NXT.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NXT.py
deleted file mode 100644
index 99ae9b9..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/NXT.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.rdatatype
-import dns.name
-
-class NXT(dns.rdata.Rdata):
-    """NXT record
-
-    @ivar next: the next name
-    @type next: dns.name.Name object
-    @ivar bitmap: the type bitmap
-    @type bitmap: string
-    @see: RFC 2535"""
-
-    __slots__ = ['next', 'bitmap']
-
-    def __init__(self, rdclass, rdtype, next, bitmap):
-        super(NXT, self).__init__(rdclass, rdtype)
-        self.next = next
-        self.bitmap = bitmap
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        next = self.next.choose_relativity(origin, relativize)
-        bits = []
-        for i in xrange(0, len(self.bitmap)):
-            byte = ord(self.bitmap[i])
-            for j in xrange(0, 8):
-                if byte & (0x80 >> j):
-                    bits.append(dns.rdatatype.to_text(i * 8 + j))
-        text = ' '.join(bits)
-        return '%s %s' % (next, text)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        next = tok.get_name()
-        next = next.choose_relativity(origin, relativize)
-        bitmap = ['\x00', '\x00', '\x00', '\x00',
-                  '\x00', '\x00', '\x00', '\x00',
-                  '\x00', '\x00', '\x00', '\x00',
-                  '\x00', '\x00', '\x00', '\x00' ]
-        while 1:
-            token = tok.get().unescape()
-            if token.is_eol_or_eof():
-                break
-            if token.value.isdigit():
-                nrdtype = int(token.value)
-            else:
-                nrdtype = dns.rdatatype.from_text(token.value)
-            if nrdtype == 0:
-                raise dns.exception.SyntaxError("NXT with bit 0")
-            if nrdtype > 127:
-                raise dns.exception.SyntaxError("NXT with bit > 127")
-            i = nrdtype // 8
-            bitmap[i] = chr(ord(bitmap[i]) | (0x80 >> (nrdtype % 8)))
-        bitmap = dns.rdata._truncate_bitmap(bitmap)
-        return cls(rdclass, rdtype, next, bitmap)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        self.next.to_wire(file, None, origin)
-        file.write(self.bitmap)
-
-    def to_digestable(self, origin = None):
-        return self.next.to_digestable(origin) + self.bitmap
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (next, cused) = dns.name.from_wire(wire[: current + rdlen], current)
-        current += cused
-        rdlen -= cused
-        bitmap = wire[current : current + rdlen]
-        if not origin is None:
-            next = next.relativize(origin)
-        return cls(rdclass, rdtype, next, bitmap)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.next = self.next.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        v = cmp(self.next, other.next)
-        if v == 0:
-            v = cmp(self.bitmap, other.bitmap)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/PTR.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/PTR.py
deleted file mode 100644
index 6c4b79e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/PTR.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.nsbase
-
-class PTR(dns.rdtypes.nsbase.NSBase):
-    """PTR record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RP.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RP.py
deleted file mode 100644
index 421ce8e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RP.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.name
-
-class RP(dns.rdata.Rdata):
-    """RP record
-
-    @ivar mbox: The responsible person's mailbox
-    @type mbox: dns.name.Name object
-    @ivar txt: The owner name of a node with TXT records, or the root name
-    if no TXT records are associated with this RP.
-    @type txt: dns.name.Name object
-    @see: RFC 1183"""
-
-    __slots__ = ['mbox', 'txt']
-
-    def __init__(self, rdclass, rdtype, mbox, txt):
-        super(RP, self).__init__(rdclass, rdtype)
-        self.mbox = mbox
-        self.txt = txt
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        mbox = self.mbox.choose_relativity(origin, relativize)
-        txt = self.txt.choose_relativity(origin, relativize)
-        return "%s %s" % (str(mbox), str(txt))
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        mbox = tok.get_name()
-        txt = tok.get_name()
-        mbox = mbox.choose_relativity(origin, relativize)
-        txt = txt.choose_relativity(origin, relativize)
-        tok.get_eol()
-        return cls(rdclass, rdtype, mbox, txt)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        self.mbox.to_wire(file, None, origin)
-        self.txt.to_wire(file, None, origin)
-
-    def to_digestable(self, origin = None):
-        return self.mbox.to_digestable(origin) + \
-            self.txt.to_digestable(origin)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (mbox, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                           current)
-        current += cused
-        rdlen -= cused
-        if rdlen <= 0:
-            raise dns.exception.FormError
-        (txt, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                          current)
-        if cused != rdlen:
-            raise dns.exception.FormError
-        if not origin is None:
-            mbox = mbox.relativize(origin)
-            txt = txt.relativize(origin)
-        return cls(rdclass, rdtype, mbox, txt)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.mbox = self.mbox.choose_relativity(origin, relativize)
-        self.txt = self.txt.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        v = cmp(self.mbox, other.mbox)
-        if v == 0:
-            v = cmp(self.txt, other.txt)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RRSIG.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RRSIG.py
deleted file mode 100644
index 0e4816f..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RRSIG.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.sigbase
-
-class RRSIG(dns.rdtypes.sigbase.SIGBase):
-    """RRSIG record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RT.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RT.py
deleted file mode 100644
index 1efd372..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/RT.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.mxbase
-
-class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX):
-    """RT record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SIG.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SIG.py
deleted file mode 100644
index 501e29c..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SIG.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.sigbase
-
-class SIG(dns.rdtypes.sigbase.SIGBase):
-    """SIG record"""
-    def to_digestable(self, origin = None):
-        return struct.pack('!HBBIIIH', self.type_covered,
-                           self.algorithm, self.labels,
-                           self.original_ttl, self.expiration,
-                           self.inception, self.key_tag) + \
-                           self.signer.to_digestable(origin) + \
-                           self.signature
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SOA.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SOA.py
deleted file mode 100644
index a25a35e..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SOA.py
+++ /dev/null
@@ -1,127 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.exception
-import dns.rdata
-import dns.name
-
-class SOA(dns.rdata.Rdata):
-    """SOA record
-
-    @ivar mname: the SOA MNAME (master name) field
-    @type mname: dns.name.Name object
-    @ivar rname: the SOA RNAME (responsible name) field
-    @type rname: dns.name.Name object
-    @ivar serial: The zone's serial number
-    @type serial: int
-    @ivar refresh: The zone's refresh value (in seconds)
-    @type refresh: int
-    @ivar retry: The zone's retry value (in seconds)
-    @type retry: int
-    @ivar expire: The zone's expiration value (in seconds)
-    @type expire: int
-    @ivar minimum: The zone's negative caching time (in seconds, called
-    "minimum" for historical reasons)
-    @type minimum: int
-    @see: RFC 1035"""
-
-    __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire',
-                 'minimum']
-    
-    def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
-                 expire, minimum):
-        super(SOA, self).__init__(rdclass, rdtype)
-        self.mname = mname
-        self.rname = rname
-        self.serial = serial
-        self.refresh = refresh
-        self.retry = retry
-        self.expire = expire
-        self.minimum = minimum
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        mname = self.mname.choose_relativity(origin, relativize)
-        rname = self.rname.choose_relativity(origin, relativize)
-        return '%s %s %d %d %d %d %d' % (
-            mname, rname, self.serial, self.refresh, self.retry,
-            self.expire, self.minimum )
-        
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        mname = tok.get_name()
-        rname = tok.get_name()
-        mname = mname.choose_relativity(origin, relativize)
-        rname = rname.choose_relativity(origin, relativize)
-        serial = tok.get_uint32()
-        refresh = tok.get_ttl()
-        retry = tok.get_ttl()
-        expire = tok.get_ttl()
-        minimum = tok.get_ttl()
-        tok.get_eol()
-        return cls(rdclass, rdtype, mname, rname, serial, refresh, retry,
-                   expire, minimum )
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        self.mname.to_wire(file, compress, origin)
-        self.rname.to_wire(file, compress, origin)
-        five_ints = struct.pack('!IIIII', self.serial, self.refresh,
-                                self.retry, self.expire, self.minimum)
-        file.write(five_ints)
-
-    def to_digestable(self, origin = None):
-        return self.mname.to_digestable(origin) + \
-            self.rname.to_digestable(origin) + \
-            struct.pack('!IIIII', self.serial, self.refresh,
-                        self.retry, self.expire, self.minimum)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
-        current += cused
-        rdlen -= cused
-        (rname, cused) = dns.name.from_wire(wire[: current + rdlen], current)
-        current += cused
-        rdlen -= cused
-        if rdlen != 20:
-            raise dns.exception.FormError
-        five_ints = struct.unpack('!IIIII',
-                                  wire[current : current + rdlen])
-        if not origin is None:
-            mname = mname.relativize(origin)
-            rname = rname.relativize(origin)
-        return cls(rdclass, rdtype, mname, rname,
-                   five_ints[0], five_ints[1], five_ints[2], five_ints[3],
-                   five_ints[4])
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.mname = self.mname.choose_relativity(origin, relativize)
-        self.rname = self.rname.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        v = cmp(self.mname, other.mname)
-        if v == 0:
-            v = cmp(self.rname, other.rname)
-            if v == 0:
-                self_ints = struct.pack('!IIIII', self.serial, self.refresh,
-                                        self.retry, self.expire, self.minimum)
-                other_ints = struct.pack('!IIIII', other.serial, other.refresh,
-                                         other.retry, other.expire,
-                                         other.minimum)
-                v = cmp(self_ints, other_ints)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SPF.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SPF.py
deleted file mode 100644
index 9b5a9a9..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SPF.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.txtbase
-
-class SPF(dns.rdtypes.txtbase.TXTBase):
-    """SPF record
-
-    @see: RFC 4408"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SSHFP.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SSHFP.py
deleted file mode 100644
index 162dda5..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/SSHFP.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright (C) 2005-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.rdata
-import dns.rdatatype
-
-class SSHFP(dns.rdata.Rdata):
-    """SSHFP record
-
-    @ivar algorithm: the algorithm
-    @type algorithm: int
-    @ivar fp_type: the digest type
-    @type fp_type: int
-    @ivar fingerprint: the fingerprint
-    @type fingerprint: string
-    @see: draft-ietf-secsh-dns-05.txt"""
-
-    __slots__ = ['algorithm', 'fp_type', 'fingerprint']
-    
-    def __init__(self, rdclass, rdtype, algorithm, fp_type,
-                 fingerprint):
-        super(SSHFP, self).__init__(rdclass, rdtype)
-        self.algorithm = algorithm
-        self.fp_type = fp_type
-        self.fingerprint = fingerprint
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '%d %d %s' % (self.algorithm,
-                             self.fp_type,
-                             dns.rdata._hexify(self.fingerprint,
-                                               chunksize=128))
-        
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        algorithm = tok.get_uint8()
-        fp_type = tok.get_uint8()
-        fingerprint = tok.get_string()
-        fingerprint = fingerprint.decode('hex_codec')
-        tok.get_eol()
-        return cls(rdclass, rdtype, algorithm, fp_type, fingerprint)
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        header = struct.pack("!BB", self.algorithm, self.fp_type)
-        file.write(header)
-        file.write(self.fingerprint)
-        
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        header = struct.unpack("!BB", wire[current : current + 2])
-        current += 2
-        rdlen -= 2
-        fingerprint = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, header[0], header[1], fingerprint)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        hs = struct.pack("!BB", self.algorithm, self.fp_type)
-        ho = struct.pack("!BB", other.algorithm, other.fp_type)
-        v = cmp(hs, ho)
-        if v == 0:
-            v = cmp(self.fingerprint, other.fingerprint)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/TXT.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/TXT.py
deleted file mode 100644
index 23f4f3b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/TXT.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.txtbase
-
-class TXT(dns.rdtypes.txtbase.TXTBase):
-    """TXT record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/X25.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/X25.py
deleted file mode 100644
index c3632f7..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/X25.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.tokenizer
-
-class X25(dns.rdata.Rdata):
-    """X25 record
-
-    @ivar address: the PSDN address
-    @type address: string
-    @see: RFC 1183"""
-
-    __slots__ = ['address']
-    
-    def __init__(self, rdclass, rdtype, address):
-        super(X25, self).__init__(rdclass, rdtype)
-        self.address = address
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '"%s"' % dns.rdata._escapify(self.address)
-        
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_string()
-        tok.get_eol()
-        return cls(rdclass, rdtype, address)
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        l = len(self.address)
-        assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.address)
-        
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        l = ord(wire[current])
-        current += 1
-        rdlen -= 1
-        if l != rdlen:
-            raise dns.exception.FormError
-        address = wire[current : current + l]
-        return cls(rdclass, rdtype, address)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        return cmp(self.address, other.address)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/__init__.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/__init__.py
deleted file mode 100644
index 0815dd5..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/ANY/__init__.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Class ANY (generic) rdata type classes."""
-
-__all__ = [
-    'AFSDB',
-    'CERT',
-    'CNAME',
-    'DLV',
-    'DNAME',
-    'DNSKEY',
-    'DS',
-    'GPOS',
-    'HINFO',
-    'HIP',
-    'ISDN',
-    'KEY',
-    'LOC',
-    'MX',
-    'NS',
-    'NSEC',
-    'NSEC3',
-    'NSEC3PARAM',
-    'NXT',
-    'PTR',
-    'RP',
-    'RRSIG',
-    'RT',
-    'SIG',
-    'SOA',
-    'SPF',
-    'SSHFP',
-    'TXT',
-    'X25',
-]
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/A.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/A.py
deleted file mode 100644
index e05f204..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/A.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.ipv4
-import dns.rdata
-import dns.tokenizer
-
-class A(dns.rdata.Rdata):
-    """A record.
-
-    @ivar address: an IPv4 address
-    @type address: string (in the standard "dotted quad" format)"""
-
-    __slots__ = ['address']
-
-    def __init__(self, rdclass, rdtype, address):
-        super(A, self).__init__(rdclass, rdtype)
-        # check that it's OK
-        junk = dns.ipv4.inet_aton(address)
-        self.address = address
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return self.address
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_identifier()
-        tok.get_eol()
-        return cls(rdclass, rdtype, address)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        file.write(dns.ipv4.inet_aton(self.address))
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        address = dns.ipv4.inet_ntoa(wire[current : current + rdlen])
-        return cls(rdclass, rdtype, address)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        sa = dns.ipv4.inet_aton(self.address)
-        oa = dns.ipv4.inet_aton(other.address)
-        return cmp(sa, oa)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/AAAA.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/AAAA.py
deleted file mode 100644
index 2d812d3..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/AAAA.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.inet
-import dns.rdata
-import dns.tokenizer
-
-class AAAA(dns.rdata.Rdata):
-    """AAAA record.
-
-    @ivar address: an IPv6 address
-    @type address: string (in the standard IPv6 format)"""
-
-    __slots__ = ['address']
-
-    def __init__(self, rdclass, rdtype, address):
-        super(AAAA, self).__init__(rdclass, rdtype)
-        # check that it's OK
-        junk = dns.inet.inet_pton(dns.inet.AF_INET6, address)
-        self.address = address
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return self.address
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_identifier()
-        tok.get_eol()
-        return cls(rdclass, rdtype, address)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.address))
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        address = dns.inet.inet_ntop(dns.inet.AF_INET6,
-                                     wire[current : current + rdlen])
-        return cls(rdclass, rdtype, address)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        sa = dns.inet.inet_pton(dns.inet.AF_INET6, self.address)
-        oa = dns.inet.inet_pton(dns.inet.AF_INET6, other.address)
-        return cmp(sa, oa)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/APL.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/APL.py
deleted file mode 100644
index 7412c02..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/APL.py
+++ /dev/null
@@ -1,170 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-import struct
-
-import dns.exception
-import dns.inet
-import dns.rdata
-import dns.tokenizer
-
-class APLItem(object):
-    """An APL list item.
-
-    @ivar family: the address family (IANA address family registry)
-    @type family: int
-    @ivar negation: is this item negated?
-    @type negation: bool
-    @ivar address: the address
-    @type address: string
-    @ivar prefix: the prefix length
-    @type prefix: int
-    """
-
-    __slots__ = ['family', 'negation', 'address', 'prefix']
-
-    def __init__(self, family, negation, address, prefix):
-        self.family = family
-        self.negation = negation
-        self.address = address
-        self.prefix = prefix
-
-    def __str__(self):
-        if self.negation:
-            return "!%d:%s/%s" % (self.family, self.address, self.prefix)
-        else:
-            return "%d:%s/%s" % (self.family, self.address, self.prefix)
-
-    def to_wire(self, file):
-        if self.family == 1:
-            address = dns.inet.inet_pton(dns.inet.AF_INET, self.address)
-        elif self.family == 2:
-            address = dns.inet.inet_pton(dns.inet.AF_INET6, self.address)
-        else:
-            address = self.address.decode('hex_codec')
-        #
-        # Truncate least significant zero bytes.
-        #
-        last = 0
-        for i in xrange(len(address) - 1, -1, -1):
-            if address[i] != chr(0):
-                last = i + 1
-                break
-        address = address[0 : last]
-        l = len(address)
-        assert l < 128
-        if self.negation:
-            l |= 0x80
-        header = struct.pack('!HBB', self.family, self.prefix, l)
-        file.write(header)
-        file.write(address)
-
-class APL(dns.rdata.Rdata):
-    """APL record.
-
-    @ivar items: a list of APL items
-    @type items: list of APL_Item
-    @see: RFC 3123"""
-
-    __slots__ = ['items']
-
-    def __init__(self, rdclass, rdtype, items):
-        super(APL, self).__init__(rdclass, rdtype)
-        self.items = items
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return ' '.join(map(lambda x: str(x), self.items))
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        items = []
-        while 1:
-            token = tok.get().unescape()
-            if token.is_eol_or_eof():
-                break
-            item = token.value
-            if item[0] == '!':
-                negation = True
-                item = item[1:]
-            else:
-                negation = False
-            (family, rest) = item.split(':', 1)
-            family = int(family)
-            (address, prefix) = rest.split('/', 1)
-            prefix = int(prefix)
-            item = APLItem(family, negation, address, prefix)
-            items.append(item)
-
-        return cls(rdclass, rdtype, items)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        for item in self.items:
-            item.to_wire(file)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        items = []
-        while 1:
-            if rdlen < 4:
-                raise dns.exception.FormError
-            header = struct.unpack('!HBB', wire[current : current + 4])
-            afdlen = header[2]
-            if afdlen > 127:
-                negation = True
-                afdlen -= 128
-            else:
-                negation = False
-            current += 4
-            rdlen -= 4
-            if rdlen < afdlen:
-                raise dns.exception.FormError
-            address = wire[current : current + afdlen]
-            l = len(address)
-            if header[0] == 1:
-                if l < 4:
-                    address += '\x00' * (4 - l)
-                address = dns.inet.inet_ntop(dns.inet.AF_INET, address)
-            elif header[0] == 2:
-                if l < 16:
-                    address += '\x00' * (16 - l)
-                address = dns.inet.inet_ntop(dns.inet.AF_INET6, address)
-            else:
-                #
-                # This isn't really right according to the RFC, but it
-                # seems better than throwing an exception
-                #
-                address = address.encode('hex_codec')
-            current += afdlen
-            rdlen -= afdlen
-            item = APLItem(header[0], negation, address, header[1])
-            items.append(item)
-            if rdlen == 0:
-                break
-        return cls(rdclass, rdtype, items)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        f = cStringIO.StringIO()
-        self.to_wire(f)
-        wire1 = f.getvalue()
-        f.seek(0)
-        f.truncate()
-        other.to_wire(f)
-        wire2 = f.getvalue()
-        f.close()
-
-        return cmp(wire1, wire2)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/DHCID.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/DHCID.py
deleted file mode 100644
index 2d35234..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/DHCID.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-
-class DHCID(dns.rdata.Rdata):
-    """DHCID record
-
-    @ivar data: the data (the content of the RR is opaque as far as the
-    DNS is concerned)
-    @type data: string
-    @see: RFC 4701"""
-
-    __slots__ = ['data']
-
-    def __init__(self, rdclass, rdtype, data):
-        super(DHCID, self).__init__(rdclass, rdtype)
-        self.data = data
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return dns.rdata._base64ify(self.data)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        chunks = []
-        while 1:
-            t = tok.get().unescape()
-            if t.is_eol_or_eof():
-                break
-            if not t.is_identifier():
-                raise dns.exception.SyntaxError
-            chunks.append(t.value)
-        b64 = ''.join(chunks)
-        data = b64.decode('base64_codec')
-        return cls(rdclass, rdtype, data)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        file.write(self.data)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        data = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, data)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        return cmp(self.data, other.data)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/IPSECKEY.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/IPSECKEY.py
deleted file mode 100644
index 9ab08d8..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/IPSECKEY.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import cStringIO
-import struct
-
-import dns.exception
-import dns.inet
-import dns.name
-
-class IPSECKEY(dns.rdata.Rdata):
-    """IPSECKEY record
-
-    @ivar precedence: the precedence for this key data
-    @type precedence: int
-    @ivar gateway_type: the gateway type
-    @type gateway_type: int
-    @ivar algorithm: the algorithm to use
-    @type algorithm: int
-    @ivar gateway: the public key
-    @type gateway: None, IPv4 address, IPV6 address, or domain name
-    @ivar key: the public key
-    @type key: string
-    @see: RFC 4025"""
-
-    __slots__ = ['precedence', 'gateway_type', 'algorithm', 'gateway', 'key']
-
-    def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm,
-                 gateway, key):
-        super(IPSECKEY, self).__init__(rdclass, rdtype)
-        if gateway_type == 0:
-            if gateway != '.' and not gateway is None:
-                raise SyntaxError('invalid gateway for gateway type 0')
-            gateway = None
-        elif gateway_type == 1:
-            # check that it's OK
-            junk = dns.inet.inet_pton(dns.inet.AF_INET, gateway)
-        elif gateway_type == 2:
-            # check that it's OK
-            junk = dns.inet.inet_pton(dns.inet.AF_INET6, gateway)
-        elif gateway_type == 3:
-            pass
-        else:
-            raise SyntaxError('invalid IPSECKEY gateway type: %d' % gateway_type)
-        self.precedence = precedence
-        self.gateway_type = gateway_type
-        self.algorithm = algorithm
-        self.gateway = gateway
-        self.key = key
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        if self.gateway_type == 0:
-            gateway = '.'
-        elif self.gateway_type == 1:
-            gateway = self.gateway
-        elif self.gateway_type == 2:
-            gateway = self.gateway
-        elif self.gateway_type == 3:
-            gateway = str(self.gateway.choose_relativity(origin, relativize))
-        else:
-            raise ValueError('invalid gateway type')
-        return '%d %d %d %s %s' % (self.precedence, self.gateway_type,
-                                   self.algorithm, gateway,
-                                   dns.rdata._base64ify(self.key))
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        precedence = tok.get_uint8()
-        gateway_type = tok.get_uint8()
-        algorithm = tok.get_uint8()
-        if gateway_type == 3:
-            gateway = tok.get_name().choose_relativity(origin, relativize)
-        else:
-            gateway = tok.get_string()
-        chunks = []
-        while 1:
-            t = tok.get().unescape()
-            if t.is_eol_or_eof():
-                break
-            if not t.is_identifier():
-                raise dns.exception.SyntaxError
-            chunks.append(t.value)
-        b64 = ''.join(chunks)
-        key = b64.decode('base64_codec')
-        return cls(rdclass, rdtype, precedence, gateway_type, algorithm,
-                   gateway, key)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        header = struct.pack("!BBB", self.precedence, self.gateway_type,
-                             self.algorithm)
-        file.write(header)
-        if self.gateway_type == 0:
-            pass
-        elif self.gateway_type == 1:
-            file.write(dns.inet.inet_pton(dns.inet.AF_INET, self.gateway))
-        elif self.gateway_type == 2:
-            file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.gateway))
-        elif self.gateway_type == 3:
-            self.gateway.to_wire(file, None, origin)
-        else:
-            raise ValueError('invalid gateway type')
-        file.write(self.key)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        if rdlen < 3:
-            raise dns.exception.FormError
-        header = struct.unpack('!BBB', wire[current : current + 3])
-        gateway_type = header[1]
-        current += 3
-        rdlen -= 3
-        if gateway_type == 0:
-            gateway = None
-        elif gateway_type == 1:
-            gateway = dns.inet.inet_ntop(dns.inet.AF_INET,
-                                         wire[current : current + 4])
-            current += 4
-            rdlen -= 4
-        elif gateway_type == 2:
-            gateway = dns.inet.inet_ntop(dns.inet.AF_INET6,
-                                         wire[current : current + 16])
-            current += 16
-            rdlen -= 16
-        elif gateway_type == 3:
-            (gateway, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                                  current)
-            current += cused
-            rdlen -= cused
-        else:
-            raise dns.exception.FormError('invalid IPSECKEY gateway type')
-        key = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, header[0], gateway_type, header[2],
-                   gateway, key)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        f = cStringIO.StringIO()
-        self.to_wire(f)
-        wire1 = f.getvalue()
-        f.seek(0)
-        f.truncate()
-        other.to_wire(f)
-        wire2 = f.getvalue()
-        f.close()
-
-        return cmp(wire1, wire2)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/KX.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/KX.py
deleted file mode 100644
index 4d8a3a7..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/KX.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.mxbase
-
-class KX(dns.rdtypes.mxbase.UncompressedMX):
-    """KX record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NAPTR.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NAPTR.py
deleted file mode 100644
index a3cca55..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NAPTR.py
+++ /dev/null
@@ -1,132 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.exception
-import dns.name
-import dns.rdata
-
-def _write_string(file, s):
-    l = len(s)
-    assert l < 256
-    byte = chr(l)
-    file.write(byte)
-    file.write(s)
-
-class NAPTR(dns.rdata.Rdata):
-    """NAPTR record
-
-    @ivar order: order
-    @type order: int
-    @ivar preference: preference
-    @type preference: int
-    @ivar flags: flags
-    @type flags: string
-    @ivar service: service
-    @type service: string
-    @ivar regexp: regular expression
-    @type regexp: string
-    @ivar replacement: replacement name
-    @type replacement: dns.name.Name object
-    @see: RFC 3403"""
-
-    __slots__ = ['order', 'preference', 'flags', 'service', 'regexp',
-                 'replacement']
-    
-    def __init__(self, rdclass, rdtype, order, preference, flags, service,
-                 regexp, replacement):
-        super(NAPTR, self).__init__(rdclass, rdtype)
-        self.order = order
-        self.preference = preference
-        self.flags = flags
-        self.service = service
-        self.regexp = regexp
-        self.replacement = replacement
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        replacement = self.replacement.choose_relativity(origin, relativize)
-        return '%d %d "%s" "%s" "%s" %s' % \
-               (self.order, self.preference,
-                dns.rdata._escapify(self.flags),
-                dns.rdata._escapify(self.service),
-                dns.rdata._escapify(self.regexp),
-                self.replacement)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        order = tok.get_uint16()
-        preference = tok.get_uint16()
-        flags = tok.get_string()
-        service = tok.get_string()
-        regexp = tok.get_string()
-        replacement = tok.get_name()
-        replacement = replacement.choose_relativity(origin, relativize)
-        tok.get_eol()
-        return cls(rdclass, rdtype, order, preference, flags, service,
-                   regexp, replacement)
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        two_ints = struct.pack("!HH", self.order, self.preference)
-        file.write(two_ints)
-        _write_string(file, self.flags)
-        _write_string(file, self.service)
-        _write_string(file, self.regexp)
-        self.replacement.to_wire(file, compress, origin)
-        
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (order, preference) = struct.unpack('!HH', wire[current : current + 4])
-        current += 4
-        rdlen -= 4
-        strings = []
-        for i in xrange(3):
-            l = ord(wire[current])
-            current += 1
-            rdlen -= 1
-            if l > rdlen or rdlen < 0:
-                raise dns.exception.FormError
-            s = wire[current : current + l]
-            current += l
-            rdlen -= l
-            strings.append(s)
-        (replacement, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                                  current)
-        if cused != rdlen:
-            raise dns.exception.FormError
-        if not origin is None:
-            replacement = replacement.relativize(origin)
-        return cls(rdclass, rdtype, order, preference, strings[0], strings[1],
-                   strings[2], replacement)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.replacement = self.replacement.choose_relativity(origin,
-                                                              relativize)
-        
-    def _cmp(self, other):
-        sp = struct.pack("!HH", self.order, self.preference)
-        op = struct.pack("!HH", other.order, other.preference)
-        v = cmp(sp, op)
-        if v == 0:
-            v = cmp(self.flags, other.flags)
-            if v == 0:
-                v = cmp(self.service, other.service)
-                if v == 0:
-                    v = cmp(self.regexp, other.regexp)
-                    if v == 0:
-                        v = cmp(self.replacement, other.replacement)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NSAP.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NSAP.py
deleted file mode 100644
index 22b9131..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NSAP.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.exception
-import dns.rdata
-import dns.tokenizer
-
-class NSAP(dns.rdata.Rdata):
-    """NSAP record.
-
-    @ivar address: a NASP
-    @type address: string
-    @see: RFC 1706"""
-
-    __slots__ = ['address']
-
-    def __init__(self, rdclass, rdtype, address):
-        super(NSAP, self).__init__(rdclass, rdtype)
-        self.address = address
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return "0x%s" % self.address.encode('hex_codec')
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_string()
-        t = tok.get_eol()
-        if address[0:2] != '0x':
-            raise dns.exception.SyntaxError('string does not start with 0x')
-        address = address[2:].replace('.', '')
-        if len(address) % 2 != 0:
-            raise dns.exception.SyntaxError('hexstring has odd length')
-        address = address.decode('hex_codec')
-        return cls(rdclass, rdtype, address)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        file.write(self.address)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        address = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, address)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        return cmp(self.address, other.address)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NSAP_PTR.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NSAP_PTR.py
deleted file mode 100644
index 6f591f4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/NSAP_PTR.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import dns.rdtypes.nsbase
-
-class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS):
-    """NSAP-PTR record"""
-    pass
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/PX.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/PX.py
deleted file mode 100644
index 0f11290..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/PX.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.exception
-import dns.rdata
-import dns.name
-
-class PX(dns.rdata.Rdata):
-    """PX record.
-
-    @ivar preference: the preference value
-    @type preference: int
-    @ivar map822: the map822 name
-    @type map822: dns.name.Name object
-    @ivar mapx400: the mapx400 name
-    @type mapx400: dns.name.Name object
-    @see: RFC 2163"""
-
-    __slots__ = ['preference', 'map822', 'mapx400']
-        
-    def __init__(self, rdclass, rdtype, preference, map822, mapx400):
-        super(PX, self).__init__(rdclass, rdtype)
-        self.preference = preference
-        self.map822 = map822
-        self.mapx400 = mapx400
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        map822 = self.map822.choose_relativity(origin, relativize)
-        mapx400 = self.mapx400.choose_relativity(origin, relativize)
-        return '%d %s %s' % (self.preference, map822, mapx400)
-        
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        preference = tok.get_uint16()
-        map822 = tok.get_name()
-        map822 = map822.choose_relativity(origin, relativize)
-        mapx400 = tok.get_name(None)
-        mapx400 = mapx400.choose_relativity(origin, relativize)
-        tok.get_eol()
-        return cls(rdclass, rdtype, preference, map822, mapx400)
-    
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        pref = struct.pack("!H", self.preference)
-        file.write(pref)
-        self.map822.to_wire(file, None, origin)
-        self.mapx400.to_wire(file, None, origin)
-        
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (preference, ) = struct.unpack('!H', wire[current : current + 2])
-        current += 2
-        rdlen -= 2
-        (map822, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                               current)
-        if cused > rdlen:
-            raise dns.exception.FormError
-        current += cused
-        rdlen -= cused
-        if not origin is None:
-            map822 = map822.relativize(origin)
-        (mapx400, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                              current)
-        if cused != rdlen:
-            raise dns.exception.FormError
-        if not origin is None:
-            mapx400 = mapx400.relativize(origin)
-        return cls(rdclass, rdtype, preference, map822, mapx400)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.map822 = self.map822.choose_relativity(origin, relativize)
-        self.mapx400 = self.mapx400.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        sp = struct.pack("!H", self.preference)
-        op = struct.pack("!H", other.preference)
-        v = cmp(sp, op)
-        if v == 0:
-            v = cmp(self.map822, other.map822)
-            if v == 0:
-                v = cmp(self.mapx400, other.mapx400)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/SRV.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/SRV.py
deleted file mode 100644
index c9c5823..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/SRV.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.exception
-import dns.rdata
-import dns.name
-
-class SRV(dns.rdata.Rdata):
-    """SRV record
-
-    @ivar priority: the priority
-    @type priority: int
-    @ivar weight: the weight
-    @type weight: int
-    @ivar port: the port of the service
-    @type port: int
-    @ivar target: the target host
-    @type target: dns.name.Name object
-    @see: RFC 2782"""
-
-    __slots__ = ['priority', 'weight', 'port', 'target']
-
-    def __init__(self, rdclass, rdtype, priority, weight, port, target):
-        super(SRV, self).__init__(rdclass, rdtype)
-        self.priority = priority
-        self.weight = weight
-        self.port = port
-        self.target = target
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        target = self.target.choose_relativity(origin, relativize)
-        return '%d %d %d %s' % (self.priority, self.weight, self.port,
-                                target)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        priority = tok.get_uint16()
-        weight = tok.get_uint16()
-        port = tok.get_uint16()
-        target = tok.get_name(None)
-        target = target.choose_relativity(origin, relativize)
-        tok.get_eol()
-        return cls(rdclass, rdtype, priority, weight, port, target)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        three_ints = struct.pack("!HHH", self.priority, self.weight, self.port)
-        file.write(three_ints)
-        self.target.to_wire(file, compress, origin)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (priority, weight, port) = struct.unpack('!HHH',
-                                                 wire[current : current + 6])
-        current += 6
-        rdlen -= 6
-        (target, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                             current)
-        if cused != rdlen:
-            raise dns.exception.FormError
-        if not origin is None:
-            target = target.relativize(origin)
-        return cls(rdclass, rdtype, priority, weight, port, target)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.target = self.target.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        sp = struct.pack("!HHH", self.priority, self.weight, self.port)
-        op = struct.pack("!HHH", other.priority, other.weight, other.port)
-        v = cmp(sp, op)
-        if v == 0:
-            v = cmp(self.target, other.target)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/WKS.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/WKS.py
deleted file mode 100644
index 85aafb3..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/WKS.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import socket
-import struct
-
-import dns.ipv4
-import dns.rdata
-
-_proto_tcp = socket.getprotobyname('tcp')
-_proto_udp = socket.getprotobyname('udp')
-
-class WKS(dns.rdata.Rdata):
-    """WKS record
-
-    @ivar address: the address
-    @type address: string
-    @ivar protocol: the protocol
-    @type protocol: int
-    @ivar bitmap: the bitmap
-    @type bitmap: string
-    @see: RFC 1035"""
-
-    __slots__ = ['address', 'protocol', 'bitmap']
-
-    def __init__(self, rdclass, rdtype, address, protocol, bitmap):
-        super(WKS, self).__init__(rdclass, rdtype)
-        self.address = address
-        self.protocol = protocol
-        self.bitmap = bitmap
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        bits = []
-        for i in xrange(0, len(self.bitmap)):
-            byte = ord(self.bitmap[i])
-            for j in xrange(0, 8):
-                if byte & (0x80 >> j):
-                    bits.append(str(i * 8 + j))
-        text = ' '.join(bits)
-        return '%s %d %s' % (self.address, self.protocol, text)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_string()
-        protocol = tok.get_string()
-        if protocol.isdigit():
-            protocol = int(protocol)
-        else:
-            protocol = socket.getprotobyname(protocol)
-        bitmap = []
-        while 1:
-            token = tok.get().unescape()
-            if token.is_eol_or_eof():
-                break
-            if token.value.isdigit():
-                serv = int(token.value)
-            else:
-                if protocol != _proto_udp and protocol != _proto_tcp:
-                    raise NotImplementedError("protocol must be TCP or UDP")
-                if protocol == _proto_udp:
-                    protocol_text = "udp"
-                else:
-                    protocol_text = "tcp"
-                serv = socket.getservbyname(token.value, protocol_text)
-            i = serv // 8
-            l = len(bitmap)
-            if l < i + 1:
-                for j in xrange(l, i + 1):
-                    bitmap.append('\x00')
-            bitmap[i] = chr(ord(bitmap[i]) | (0x80 >> (serv % 8)))
-        bitmap = dns.rdata._truncate_bitmap(bitmap)
-        return cls(rdclass, rdtype, address, protocol, bitmap)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        file.write(dns.ipv4.inet_aton(self.address))
-        protocol = struct.pack('!B', self.protocol)
-        file.write(protocol)
-        file.write(self.bitmap)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        address = dns.ipv4.inet_ntoa(wire[current : current + 4])
-        protocol, = struct.unpack('!B', wire[current + 4 : current + 5])
-        current += 5
-        rdlen -= 5
-        bitmap = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, address, protocol, bitmap)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        sa = dns.ipv4.inet_aton(self.address)
-        oa = dns.ipv4.inet_aton(other.address)
-        v = cmp(sa, oa)
-        if v == 0:
-            sp = struct.pack('!B', self.protocol)
-            op = struct.pack('!B', other.protocol)
-            v = cmp(sp, op)
-            if v == 0:
-                v = cmp(self.bitmap, other.bitmap)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/__init__.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/__init__.py
deleted file mode 100644
index ab93129..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/IN/__init__.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Class IN rdata type classes."""
-
-__all__ = [
-    'A',
-    'AAAA',
-    'APL',
-    'DHCID',
-    'KX',
-    'NAPTR',
-    'NSAP',
-    'NSAP_PTR',
-    'PX',
-    'SRV',
-    'WKS',
-]
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/__init__.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/__init__.py
deleted file mode 100644
index 13282be..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/__init__.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS rdata type classes"""
-
-__all__ = [
-    'ANY',
-    'IN',
-    'mxbase',
-    'nsbase',
-    'sigbase',
-    'keybase',
-]
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/dsbase.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/dsbase.py
deleted file mode 100644
index aa46403..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/dsbase.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# Copyright (C) 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.rdata
-import dns.rdatatype
-
-class DSBase(dns.rdata.Rdata):
-    """Base class for rdata that is like a DS record
-
-    @ivar key_tag: the key tag
-    @type key_tag: int
-    @ivar algorithm: the algorithm
-    @type algorithm: int
-    @ivar digest_type: the digest type
-    @type digest_type: int
-    @ivar digest: the digest
-    @type digest: int
-    @see: draft-ietf-dnsext-delegation-signer-14.txt"""
-
-    __slots__ = ['key_tag', 'algorithm', 'digest_type', 'digest']
-
-    def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type,
-                 digest):
-        super(DSBase, self).__init__(rdclass, rdtype)
-        self.key_tag = key_tag
-        self.algorithm = algorithm
-        self.digest_type = digest_type
-        self.digest = digest
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '%d %d %d %s' % (self.key_tag, self.algorithm,
-                                self.digest_type,
-                                dns.rdata._hexify(self.digest,
-                                                  chunksize=128))
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        key_tag = tok.get_uint16()
-        algorithm = tok.get_uint8()
-        digest_type = tok.get_uint8()
-        chunks = []
-        while 1:
-            t = tok.get().unescape()
-            if t.is_eol_or_eof():
-                break
-            if not t.is_identifier():
-                raise dns.exception.SyntaxError
-            chunks.append(t.value)
-        digest = ''.join(chunks)
-        digest = digest.decode('hex_codec')
-        return cls(rdclass, rdtype, key_tag, algorithm, digest_type,
-                   digest)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        header = struct.pack("!HBB", self.key_tag, self.algorithm,
-                             self.digest_type)
-        file.write(header)
-        file.write(self.digest)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        header = struct.unpack("!HBB", wire[current : current + 4])
-        current += 4
-        rdlen -= 4
-        digest = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, header[0], header[1], header[2], digest)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        hs = struct.pack("!HBB", self.key_tag, self.algorithm,
-                         self.digest_type)
-        ho = struct.pack("!HBB", other.key_tag, other.algorithm,
-                         other.digest_type)
-        v = cmp(hs, ho)
-        if v == 0:
-            v = cmp(self.digest, other.digest)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/keybase.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/keybase.py
deleted file mode 100644
index 75c9272..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/keybase.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import struct
-
-import dns.exception
-import dns.dnssec
-import dns.rdata
-
-_flags_from_text = {
-    'NOCONF': (0x4000, 0xC000),
-    'NOAUTH': (0x8000, 0xC000),
-    'NOKEY': (0xC000, 0xC000),
-    'FLAG2': (0x2000, 0x2000),
-    'EXTEND': (0x1000, 0x1000),
-    'FLAG4': (0x0800, 0x0800),
-    'FLAG5': (0x0400, 0x0400),
-    'USER': (0x0000, 0x0300),
-    'ZONE': (0x0100, 0x0300),
-    'HOST': (0x0200, 0x0300),
-    'NTYP3': (0x0300, 0x0300),
-    'FLAG8': (0x0080, 0x0080),
-    'FLAG9': (0x0040, 0x0040),
-    'FLAG10': (0x0020, 0x0020),
-    'FLAG11': (0x0010, 0x0010),
-    'SIG0': (0x0000, 0x000f),
-    'SIG1': (0x0001, 0x000f),
-    'SIG2': (0x0002, 0x000f),
-    'SIG3': (0x0003, 0x000f),
-    'SIG4': (0x0004, 0x000f),
-    'SIG5': (0x0005, 0x000f),
-    'SIG6': (0x0006, 0x000f),
-    'SIG7': (0x0007, 0x000f),
-    'SIG8': (0x0008, 0x000f),
-    'SIG9': (0x0009, 0x000f),
-    'SIG10': (0x000a, 0x000f),
-    'SIG11': (0x000b, 0x000f),
-    'SIG12': (0x000c, 0x000f),
-    'SIG13': (0x000d, 0x000f),
-    'SIG14': (0x000e, 0x000f),
-    'SIG15': (0x000f, 0x000f),
-    }
-
-_protocol_from_text = {
-    'NONE' : 0,
-    'TLS' : 1,
-    'EMAIL' : 2,
-    'DNSSEC' : 3,
-    'IPSEC' : 4,
-    'ALL' : 255,
-    }
-
-class KEYBase(dns.rdata.Rdata):
-    """KEY-like record base
-
-    @ivar flags: the key flags
-    @type flags: int
-    @ivar protocol: the protocol for which this key may be used
-    @type protocol: int
-    @ivar algorithm: the algorithm used for the key
-    @type algorithm: int
-    @ivar key: the public key
-    @type key: string"""
-
-    __slots__ = ['flags', 'protocol', 'algorithm', 'key']
-
-    def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key):
-        super(KEYBase, self).__init__(rdclass, rdtype)
-        self.flags = flags
-        self.protocol = protocol
-        self.algorithm = algorithm
-        self.key = key
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm,
-                                dns.rdata._base64ify(self.key))
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        flags = tok.get_string()
-        if flags.isdigit():
-            flags = int(flags)
-        else:
-            flag_names = flags.split('|')
-            flags = 0
-            for flag in flag_names:
-                v = _flags_from_text.get(flag)
-                if v is None:
-                    raise dns.exception.SyntaxError('unknown flag %s' % flag)
-                flags &= ~v[1]
-                flags |= v[0]
-        protocol = tok.get_string()
-        if protocol.isdigit():
-            protocol = int(protocol)
-        else:
-            protocol = _protocol_from_text.get(protocol)
-            if protocol is None:
-                raise dns.exception.SyntaxError('unknown protocol %s' % protocol)
-
-        algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
-        chunks = []
-        while 1:
-            t = tok.get().unescape()
-            if t.is_eol_or_eof():
-                break
-            if not t.is_identifier():
-                raise dns.exception.SyntaxError
-            chunks.append(t.value)
-        b64 = ''.join(chunks)
-        key = b64.decode('base64_codec')
-        return cls(rdclass, rdtype, flags, protocol, algorithm, key)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        header = struct.pack("!HBB", self.flags, self.protocol, self.algorithm)
-        file.write(header)
-        file.write(self.key)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        if rdlen < 4:
-            raise dns.exception.FormError
-        header = struct.unpack('!HBB', wire[current : current + 4])
-        current += 4
-        rdlen -= 4
-        key = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, header[0], header[1], header[2],
-                   key)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        hs = struct.pack("!HBB", self.flags, self.protocol, self.algorithm)
-        ho = struct.pack("!HBB", other.flags, other.protocol, other.algorithm)
-        v = cmp(hs, ho)
-        if v == 0:
-            v = cmp(self.key, other.key)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/mxbase.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/mxbase.py
deleted file mode 100644
index 5e3515b..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/mxbase.py
+++ /dev/null
@@ -1,105 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""MX-like base classes."""
-
-import cStringIO
-import struct
-
-import dns.exception
-import dns.rdata
-import dns.name
-
-class MXBase(dns.rdata.Rdata):
-    """Base class for rdata that is like an MX record.
-
-    @ivar preference: the preference value
-    @type preference: int
-    @ivar exchange: the exchange name
-    @type exchange: dns.name.Name object"""
-
-    __slots__ = ['preference', 'exchange']
-
-    def __init__(self, rdclass, rdtype, preference, exchange):
-        super(MXBase, self).__init__(rdclass, rdtype)
-        self.preference = preference
-        self.exchange = exchange
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        exchange = self.exchange.choose_relativity(origin, relativize)
-        return '%d %s' % (self.preference, exchange)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        preference = tok.get_uint16()
-        exchange = tok.get_name()
-        exchange = exchange.choose_relativity(origin, relativize)
-        tok.get_eol()
-        return cls(rdclass, rdtype, preference, exchange)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        pref = struct.pack("!H", self.preference)
-        file.write(pref)
-        self.exchange.to_wire(file, compress, origin)
-
-    def to_digestable(self, origin = None):
-        return struct.pack("!H", self.preference) + \
-            self.exchange.to_digestable(origin)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (preference, ) = struct.unpack('!H', wire[current : current + 2])
-        current += 2
-        rdlen -= 2
-        (exchange, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                               current)
-        if cused != rdlen:
-            raise dns.exception.FormError
-        if not origin is None:
-            exchange = exchange.relativize(origin)
-        return cls(rdclass, rdtype, preference, exchange)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.exchange = self.exchange.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        sp = struct.pack("!H", self.preference)
-        op = struct.pack("!H", other.preference)
-        v = cmp(sp, op)
-        if v == 0:
-            v = cmp(self.exchange, other.exchange)
-        return v
-
-class UncompressedMX(MXBase):
-    """Base class for rdata that is like an MX record, but whose name
-    is not compressed when converted to DNS wire format, and whose
-    digestable form is not downcased."""
-
-    def to_wire(self, file, compress = None, origin = None):
-        super(UncompressedMX, self).to_wire(file, None, origin)
-
-    def to_digestable(self, origin = None):
-        f = cStringIO.StringIO()
-        self.to_wire(f, None, origin)
-        return f.getvalue()
-
-class UncompressedDowncasingMX(MXBase):
-    """Base class for rdata that is like an MX record, but whose name
-    is not compressed when convert to DNS wire format."""
-
-    def to_wire(self, file, compress = None, origin = None):
-        super(UncompressedDowncasingMX, self).to_wire(file, None, origin)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/nsbase.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/nsbase.py
deleted file mode 100644
index 7cdb2a0..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/nsbase.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""NS-like base classes."""
-
-import cStringIO
-
-import dns.exception
-import dns.rdata
-import dns.name
-
-class NSBase(dns.rdata.Rdata):
-    """Base class for rdata that is like an NS record.
-
-    @ivar target: the target name of the rdata
-    @type target: dns.name.Name object"""
-
-    __slots__ = ['target']
-
-    def __init__(self, rdclass, rdtype, target):
-        super(NSBase, self).__init__(rdclass, rdtype)
-        self.target = target
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        target = self.target.choose_relativity(origin, relativize)
-        return str(target)
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        target = tok.get_name()
-        target = target.choose_relativity(origin, relativize)
-        tok.get_eol()
-        return cls(rdclass, rdtype, target)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        self.target.to_wire(file, compress, origin)
-
-    def to_digestable(self, origin = None):
-        return self.target.to_digestable(origin)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        (target, cused) = dns.name.from_wire(wire[: current + rdlen],
-                                             current)
-        if cused != rdlen:
-            raise dns.exception.FormError
-        if not origin is None:
-            target = target.relativize(origin)
-        return cls(rdclass, rdtype, target)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.target = self.target.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        return cmp(self.target, other.target)
-
-class UncompressedNS(NSBase):
-    """Base class for rdata that is like an NS record, but whose name
-    is not compressed when convert to DNS wire format, and whose
-    digestable form is not downcased."""
-
-    def to_wire(self, file, compress = None, origin = None):
-        super(UncompressedNS, self).to_wire(file, None, origin)
-
-    def to_digestable(self, origin = None):
-        f = cStringIO.StringIO()
-        self.to_wire(f, None, origin)
-        return f.getvalue()
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/sigbase.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/sigbase.py
deleted file mode 100644
index ccb6dd6..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/sigbase.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# Copyright (C) 2004-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-import calendar
-import struct
-import time
-
-import dns.dnssec
-import dns.exception
-import dns.rdata
-import dns.rdatatype
-
-class BadSigTime(dns.exception.DNSException):
-    """Raised when a SIG or RRSIG RR's time cannot be parsed."""
-    pass
-
-def sigtime_to_posixtime(what):
-    if len(what) != 14:
-        raise BadSigTime
-    year = int(what[0:4])
-    month = int(what[4:6])
-    day = int(what[6:8])
-    hour = int(what[8:10])
-    minute = int(what[10:12])
-    second = int(what[12:14])
-    return calendar.timegm((year, month, day, hour, minute, second,
-                            0, 0, 0))
-
-def posixtime_to_sigtime(what):
-    return time.strftime('%Y%m%d%H%M%S', time.gmtime(what))
-
-class SIGBase(dns.rdata.Rdata):
-    """SIG-like record base
-
-    @ivar type_covered: the rdata type this signature covers
-    @type type_covered: int
-    @ivar algorithm: the algorithm used for the sig
-    @type algorithm: int
-    @ivar labels: number of labels
-    @type labels: int
-    @ivar original_ttl: the original TTL
-    @type original_ttl: long
-    @ivar expiration: signature expiration time
-    @type expiration: long
-    @ivar inception: signature inception time
-    @type inception: long
-    @ivar key_tag: the key tag
-    @type key_tag: int
-    @ivar signer: the signer
-    @type signer: dns.name.Name object
-    @ivar signature: the signature
-    @type signature: string"""
-
-    __slots__ = ['type_covered', 'algorithm', 'labels', 'original_ttl',
-                 'expiration', 'inception', 'key_tag', 'signer',
-                 'signature']
-
-    def __init__(self, rdclass, rdtype, type_covered, algorithm, labels,
-                 original_ttl, expiration, inception, key_tag, signer,
-                 signature):
-        super(SIGBase, self).__init__(rdclass, rdtype)
-        self.type_covered = type_covered
-        self.algorithm = algorithm
-        self.labels = labels
-        self.original_ttl = original_ttl
-        self.expiration = expiration
-        self.inception = inception
-        self.key_tag = key_tag
-        self.signer = signer
-        self.signature = signature
-
-    def covers(self):
-        return self.type_covered
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        return '%s %d %d %d %s %s %d %s %s' % (
-            dns.rdatatype.to_text(self.type_covered),
-            self.algorithm,
-            self.labels,
-            self.original_ttl,
-            posixtime_to_sigtime(self.expiration),
-            posixtime_to_sigtime(self.inception),
-            self.key_tag,
-            self.signer,
-            dns.rdata._base64ify(self.signature)
-            )
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        type_covered = dns.rdatatype.from_text(tok.get_string())
-        algorithm = dns.dnssec.algorithm_from_text(tok.get_string())
-        labels = tok.get_int()
-        original_ttl = tok.get_ttl()
-        expiration = sigtime_to_posixtime(tok.get_string())
-        inception = sigtime_to_posixtime(tok.get_string())
-        key_tag = tok.get_int()
-        signer = tok.get_name()
-        signer = signer.choose_relativity(origin, relativize)
-        chunks = []
-        while 1:
-            t = tok.get().unescape()
-            if t.is_eol_or_eof():
-                break
-            if not t.is_identifier():
-                raise dns.exception.SyntaxError
-            chunks.append(t.value)
-        b64 = ''.join(chunks)
-        signature = b64.decode('base64_codec')
-        return cls(rdclass, rdtype, type_covered, algorithm, labels,
-                   original_ttl, expiration, inception, key_tag, signer,
-                   signature)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        header = struct.pack('!HBBIIIH', self.type_covered,
-                             self.algorithm, self.labels,
-                             self.original_ttl, self.expiration,
-                             self.inception, self.key_tag)
-        file.write(header)
-        self.signer.to_wire(file, None, origin)
-        file.write(self.signature)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        header = struct.unpack('!HBBIIIH', wire[current : current + 18])
-        current += 18
-        rdlen -= 18
-        (signer, cused) = dns.name.from_wire(wire[: current + rdlen], current)
-        current += cused
-        rdlen -= cused
-        if not origin is None:
-            signer = signer.relativize(origin)
-        signature = wire[current : current + rdlen]
-        return cls(rdclass, rdtype, header[0], header[1], header[2],
-                   header[3], header[4], header[5], header[6], signer,
-                   signature)
-
-    from_wire = classmethod(from_wire)
-
-    def choose_relativity(self, origin = None, relativize = True):
-        self.signer = self.signer.choose_relativity(origin, relativize)
-
-    def _cmp(self, other):
-        hs = struct.pack('!HBBIIIH', self.type_covered,
-                         self.algorithm, self.labels,
-                         self.original_ttl, self.expiration,
-                         self.inception, self.key_tag)
-        ho = struct.pack('!HBBIIIH', other.type_covered,
-                         other.algorithm, other.labels,
-                         other.original_ttl, other.expiration,
-                         other.inception, other.key_tag)
-        v = cmp(hs, ho)
-        if v == 0:
-            v = cmp(self.signer, other.signer)
-            if v == 0:
-                v = cmp(self.signature, other.signature)
-        return v
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/txtbase.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/txtbase.py
deleted file mode 100644
index 43db2a4..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rdtypes/txtbase.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""TXT-like base class."""
-
-import dns.exception
-import dns.rdata
-import dns.tokenizer
-
-class TXTBase(dns.rdata.Rdata):
-    """Base class for rdata that is like a TXT record
-
-    @ivar strings: the text strings
-    @type strings: list of string
-    @see: RFC 1035"""
-
-    __slots__ = ['strings']
-
-    def __init__(self, rdclass, rdtype, strings):
-        super(TXTBase, self).__init__(rdclass, rdtype)
-        if isinstance(strings, str):
-            strings = [ strings ]
-        self.strings = strings[:]
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        txt = ''
-        prefix = ''
-        for s in self.strings:
-            txt += '%s"%s"' % (prefix, dns.rdata._escapify(s))
-            prefix = ' '
-        return txt
-
-    def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        strings = []
-        while 1:
-            token = tok.get().unescape()
-            if token.is_eol_or_eof():
-                break
-            if not (token.is_quoted_string() or token.is_identifier()):
-                raise dns.exception.SyntaxError("expected a string")
-            if len(token.value) > 255:
-                raise dns.exception.SyntaxError("string too long")
-            strings.append(token.value)
-        if len(strings) == 0:
-            raise dns.exception.UnexpectedEnd
-        return cls(rdclass, rdtype, strings)
-
-    from_text = classmethod(from_text)
-
-    def to_wire(self, file, compress = None, origin = None):
-        for s in self.strings:
-            l = len(s)
-            assert l < 256
-            byte = chr(l)
-            file.write(byte)
-            file.write(s)
-
-    def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
-        strings = []
-        while rdlen > 0:
-            l = ord(wire[current])
-            current += 1
-            rdlen -= 1
-            if l > rdlen:
-                raise dns.exception.FormError
-            s = wire[current : current + l]
-            current += l
-            rdlen -= l
-            strings.append(s)
-        return cls(rdclass, rdtype, strings)
-
-    from_wire = classmethod(from_wire)
-
-    def _cmp(self, other):
-        return cmp(self.strings, other.strings)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/renderer.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/renderer.py
deleted file mode 100644
index bb0218a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/renderer.py
+++ /dev/null
@@ -1,324 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Help for building DNS wire format messages"""
-
-import cStringIO
-import struct
-import random
-import time
-
-import dns.exception
-import dns.tsig
-
-QUESTION = 0
-ANSWER = 1
-AUTHORITY = 2
-ADDITIONAL = 3
-
-class Renderer(object):
-    """Helper class for building DNS wire-format messages.
-
-    Most applications can use the higher-level L{dns.message.Message}
-    class and its to_wire() method to generate wire-format messages.
-    This class is for those applications which need finer control
-    over the generation of messages.
-
-    Typical use::
-
-        r = dns.renderer.Renderer(id=1, flags=0x80, max_size=512)
-        r.add_question(qname, qtype, qclass)
-        r.add_rrset(dns.renderer.ANSWER, rrset_1)
-        r.add_rrset(dns.renderer.ANSWER, rrset_2)
-        r.add_rrset(dns.renderer.AUTHORITY, ns_rrset)
-        r.add_edns(0, 0, 4096)
-        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_1)
-        r.add_rrset(dns.renderer.ADDTIONAL, ad_rrset_2)
-        r.write_header()
-        r.add_tsig(keyname, secret, 300, 1, 0, '', request_mac)
-        wire = r.get_wire()
-
-    @ivar output: where rendering is written
-    @type output: cStringIO.StringIO object
-    @ivar id: the message id
-    @type id: int
-    @ivar flags: the message flags
-    @type flags: int
-    @ivar max_size: the maximum size of the message
-    @type max_size: int
-    @ivar origin: the origin to use when rendering relative names
-    @type origin: dns.name.Name object
-    @ivar compress: the compression table
-    @type compress: dict
-    @ivar section: the section currently being rendered
-    @type section: int (dns.renderer.QUESTION, dns.renderer.ANSWER,
-    dns.renderer.AUTHORITY, or dns.renderer.ADDITIONAL)
-    @ivar counts: list of the number of RRs in each section
-    @type counts: int list of length 4
-    @ivar mac: the MAC of the rendered message (if TSIG was used)
-    @type mac: string
-    """
-
-    def __init__(self, id=None, flags=0, max_size=65535, origin=None):
-        """Initialize a new renderer.
-
-        @param id: the message id
-        @type id: int
-        @param flags: the DNS message flags
-        @type flags: int
-        @param max_size: the maximum message size; the default is 65535.
-        If rendering results in a message greater than I{max_size},
-        then L{dns.exception.TooBig} will be raised.
-        @type max_size: int
-        @param origin: the origin to use when rendering relative names
-        @type origin: dns.name.Namem or None.
-        """
-
-        self.output = cStringIO.StringIO()
-        if id is None:
-            self.id = random.randint(0, 65535)
-        else:
-            self.id = id
-        self.flags = flags
-        self.max_size = max_size
-        self.origin = origin
-        self.compress = {}
-        self.section = QUESTION
-        self.counts = [0, 0, 0, 0]
-        self.output.write('\x00' * 12)
-        self.mac = ''
-
-    def _rollback(self, where):
-        """Truncate the output buffer at offset I{where}, and remove any
-        compression table entries that pointed beyond the truncation
-        point.
-
-        @param where: the offset
-        @type where: int
-        """
-
-        self.output.seek(where)
-        self.output.truncate()
-        keys_to_delete = []
-        for k, v in self.compress.iteritems():
-            if v >= where:
-                keys_to_delete.append(k)
-        for k in keys_to_delete:
-            del self.compress[k]
-
-    def _set_section(self, section):
-        """Set the renderer's current section.
-
-        Sections must be rendered order: QUESTION, ANSWER, AUTHORITY,
-        ADDITIONAL.  Sections may be empty.
-
-        @param section: the section
-        @type section: int
-        @raises dns.exception.FormError: an attempt was made to set
-        a section value less than the current section.
-        """
-
-        if self.section != section:
-            if self.section > section:
-                raise dns.exception.FormError
-            self.section = section
-
-    def add_question(self, qname, rdtype, rdclass=dns.rdataclass.IN):
-        """Add a question to the message.
-
-        @param qname: the question name
-        @type qname: dns.name.Name
-        @param rdtype: the question rdata type
-        @type rdtype: int
-        @param rdclass: the question rdata class
-        @type rdclass: int
-        """
-
-        self._set_section(QUESTION)
-        before = self.output.tell()
-        qname.to_wire(self.output, self.compress, self.origin)
-        self.output.write(struct.pack("!HH", rdtype, rdclass))
-        after = self.output.tell()
-        if after >= self.max_size:
-            self._rollback(before)
-            raise dns.exception.TooBig
-        self.counts[QUESTION] += 1
-
-    def add_rrset(self, section, rrset, **kw):
-        """Add the rrset to the specified section.
-
-        Any keyword arguments are passed on to the rdataset's to_wire()
-        routine.
-
-        @param section: the section
-        @type section: int
-        @param rrset: the rrset
-        @type rrset: dns.rrset.RRset object
-        """
-
-        self._set_section(section)
-        before = self.output.tell()
-        n = rrset.to_wire(self.output, self.compress, self.origin, **kw)
-        after = self.output.tell()
-        if after >= self.max_size:
-            self._rollback(before)
-            raise dns.exception.TooBig
-        self.counts[section] += n
-
-    def add_rdataset(self, section, name, rdataset, **kw):
-        """Add the rdataset to the specified section, using the specified
-        name as the owner name.
-
-        Any keyword arguments are passed on to the rdataset's to_wire()
-        routine.
-
-        @param section: the section
-        @type section: int
-        @param name: the owner name
-        @type name: dns.name.Name object
-        @param rdataset: the rdataset
-        @type rdataset: dns.rdataset.Rdataset object
-        """
-
-        self._set_section(section)
-        before = self.output.tell()
-        n = rdataset.to_wire(name, self.output, self.compress, self.origin,
-                             **kw)
-        after = self.output.tell()
-        if after >= self.max_size:
-            self._rollback(before)
-            raise dns.exception.TooBig
-        self.counts[section] += n
-
-    def add_edns(self, edns, ednsflags, payload, options=None):
-        """Add an EDNS OPT record to the message.
-
-        @param edns: The EDNS level to use.
-        @type edns: int
-        @param ednsflags: EDNS flag values.
-        @type ednsflags: int
-        @param payload: The EDNS sender's payload field, which is the maximum
-        size of UDP datagram the sender can handle.
-        @type payload: int
-        @param options: The EDNS options list
-        @type options: list of dns.edns.Option instances
-        @see: RFC 2671
-        """
-
-        # make sure the EDNS version in ednsflags agrees with edns
-        ednsflags &= 0xFF00FFFFL
-        ednsflags |= (edns << 16)
-        self._set_section(ADDITIONAL)
-        before = self.output.tell()
-        self.output.write(struct.pack('!BHHIH', 0, dns.rdatatype.OPT, payload,
-                                      ednsflags, 0))
-        if not options is None:
-            lstart = self.output.tell()
-            for opt in options:
-                stuff = struct.pack("!HH", opt.otype, 0)
-                self.output.write(stuff)
-                start = self.output.tell()
-                opt.to_wire(self.output)
-                end = self.output.tell()
-                assert end - start < 65536
-                self.output.seek(start - 2)
-                stuff = struct.pack("!H", end - start)
-                self.output.write(stuff)
-                self.output.seek(0, 2)
-            lend = self.output.tell()
-            assert lend - lstart < 65536
-            self.output.seek(lstart - 2)
-            stuff = struct.pack("!H", lend - lstart)
-            self.output.write(stuff)
-            self.output.seek(0, 2)
-        after = self.output.tell()
-        if after >= self.max_size:
-            self._rollback(before)
-            raise dns.exception.TooBig
-        self.counts[ADDITIONAL] += 1
-
-    def add_tsig(self, keyname, secret, fudge, id, tsig_error, other_data,
-                 request_mac, algorithm=dns.tsig.default_algorithm):
-        """Add a TSIG signature to the message.
-
-        @param keyname: the TSIG key name
-        @type keyname: dns.name.Name object
-        @param secret: the secret to use
-        @type secret: string
-        @param fudge: TSIG time fudge
-        @type fudge: int
-        @param id: the message id to encode in the tsig signature
-        @type id: int
-        @param tsig_error: TSIG error code; default is 0.
-        @type tsig_error: int
-        @param other_data: TSIG other data.
-        @type other_data: string
-        @param request_mac: This message is a response to the request which
-        had the specified MAC.
-        @param algorithm: the TSIG algorithm to use
-        @type request_mac: string
-        """
-
-        self._set_section(ADDITIONAL)
-        before = self.output.tell()
-        s = self.output.getvalue()
-        (tsig_rdata, self.mac, ctx) = dns.tsig.sign(s,
-                                                    keyname,
-                                                    secret,
-                                                    int(time.time()),
-                                                    fudge,
-                                                    id,
-                                                    tsig_error,
-                                                    other_data,
-                                                    request_mac,
-                                                    algorithm=algorithm)
-        keyname.to_wire(self.output, self.compress, self.origin)
-        self.output.write(struct.pack('!HHIH', dns.rdatatype.TSIG,
-                                      dns.rdataclass.ANY, 0, 0))
-        rdata_start = self.output.tell()
-        self.output.write(tsig_rdata)
-        after = self.output.tell()
-        assert after - rdata_start < 65536
-        if after >= self.max_size:
-            self._rollback(before)
-            raise dns.exception.TooBig
-        self.output.seek(rdata_start - 2)
-        self.output.write(struct.pack('!H', after - rdata_start))
-        self.counts[ADDITIONAL] += 1
-        self.output.seek(10)
-        self.output.write(struct.pack('!H', self.counts[ADDITIONAL]))
-        self.output.seek(0, 2)
-
-    def write_header(self):
-        """Write the DNS message header.
-
-        Writing the DNS message header is done asfter all sections
-        have been rendered, but before the optional TSIG signature
-        is added.
-        """
-
-        self.output.seek(0)
-        self.output.write(struct.pack('!HHHHHH', self.id, self.flags,
-                                      self.counts[0], self.counts[1],
-                                      self.counts[2], self.counts[3]))
-        self.output.seek(0, 2)
-
-    def get_wire(self):
-        """Return the wire format message.
-
-        @rtype: string
-        """
-
-        return self.output.getvalue()
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/resolver.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/resolver.py
deleted file mode 100644
index 372d7d8..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/resolver.py
+++ /dev/null
@@ -1,761 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS stub resolver.
-
-@var default_resolver: The default resolver object
-@type default_resolver: dns.resolver.Resolver object"""
-
-import socket
-import sys
-import time
-
-import dns.exception
-import dns.message
-import dns.name
-import dns.query
-import dns.rcode
-import dns.rdataclass
-import dns.rdatatype
-
-if sys.platform == 'win32':
-    import _winreg
-
-class NXDOMAIN(dns.exception.DNSException):
-    """The query name does not exist."""
-    pass
-
-# The definition of the Timeout exception has moved from here to the
-# dns.exception module.  We keep dns.resolver.Timeout defined for
-# backwards compatibility.
-
-Timeout = dns.exception.Timeout
-
-class NoAnswer(dns.exception.DNSException):
-    """The response did not contain an answer to the question."""
-    pass
-
-class NoNameservers(dns.exception.DNSException):
-    """No non-broken nameservers are available to answer the query."""
-    pass
-
-class NotAbsolute(dns.exception.DNSException):
-    """Raised if an absolute domain name is required but a relative name
-    was provided."""
-    pass
-
-class NoRootSOA(dns.exception.DNSException):
-    """Raised if for some reason there is no SOA at the root name.
-    This should never happen!"""
-    pass
-
-
-class Answer(object):
-    """DNS stub resolver answer
-
-    Instances of this class bundle up the result of a successful DNS
-    resolution.
-
-    For convenience, the answer object implements much of the sequence
-    protocol, forwarding to its rrset.  E.g. "for a in answer" is
-    equivalent to "for a in answer.rrset", "answer[i]" is equivalent
-    to "answer.rrset[i]", and "answer[i:j]" is equivalent to
-    "answer.rrset[i:j]".
-
-    Note that CNAMEs or DNAMEs in the response may mean that answer
-    node's name might not be the query name.
-
-    @ivar qname: The query name
-    @type qname: dns.name.Name object
-    @ivar rdtype: The query type
-    @type rdtype: int
-    @ivar rdclass: The query class
-    @type rdclass: int
-    @ivar response: The response message
-    @type response: dns.message.Message object
-    @ivar rrset: The answer
-    @type rrset: dns.rrset.RRset object
-    @ivar expiration: The time when the answer expires
-    @type expiration: float (seconds since the epoch)
-    """
-    def __init__(self, qname, rdtype, rdclass, response):
-        self.qname = qname
-        self.rdtype = rdtype
-        self.rdclass = rdclass
-        self.response = response
-        min_ttl = -1
-        rrset = None
-        for count in xrange(0, 15):
-            try:
-                rrset = response.find_rrset(response.answer, qname,
-                                            rdclass, rdtype)
-                if min_ttl == -1 or rrset.ttl < min_ttl:
-                    min_ttl = rrset.ttl
-                break
-            except KeyError:
-                if rdtype != dns.rdatatype.CNAME:
-                    try:
-                        crrset = response.find_rrset(response.answer,
-                                                     qname,
-                                                     rdclass,
-                                                     dns.rdatatype.CNAME)
-                        if min_ttl == -1 or crrset.ttl < min_ttl:
-                            min_ttl = crrset.ttl
-                        for rd in crrset:
-                            qname = rd.target
-                            break
-                        continue
-                    except KeyError:
-                        raise NoAnswer
-                raise NoAnswer
-        if rrset is None:
-            raise NoAnswer
-        self.rrset = rrset
-        self.expiration = time.time() + min_ttl
-
-    def __getattr__(self, attr):
-        if attr == 'name':
-            return self.rrset.name
-        elif attr == 'ttl':
-            return self.rrset.ttl
-        elif attr == 'covers':
-            return self.rrset.covers
-        elif attr == 'rdclass':
-            return self.rrset.rdclass
-        elif attr == 'rdtype':
-            return self.rrset.rdtype
-        else:
-            raise AttributeError(attr)
-
-    def __len__(self):
-        return len(self.rrset)
-
-    def __iter__(self):
-        return iter(self.rrset)
-
-    def __getitem__(self, i):
-        return self.rrset[i]
-
-    def __delitem__(self, i):
-        del self.rrset[i]
-
-    def __getslice__(self, i, j):
-        return self.rrset[i:j]
-
-    def __delslice__(self, i, j):
-        del self.rrset[i:j]
-
-class Cache(object):
-    """Simple DNS answer cache.
-
-    @ivar data: A dictionary of cached data
-    @type data: dict
-    @ivar cleaning_interval: The number of seconds between cleanings.  The
-    default is 300 (5 minutes).
-    @type cleaning_interval: float
-    @ivar next_cleaning: The time the cache should next be cleaned (in seconds
-    since the epoch.)
-    @type next_cleaning: float
-    """
-
-    def __init__(self, cleaning_interval=300.0):
-        """Initialize a DNS cache.
-
-        @param cleaning_interval: the number of seconds between periodic
-        cleanings.  The default is 300.0
-        @type cleaning_interval: float.
-        """
-
-        self.data = {}
-        self.cleaning_interval = cleaning_interval
-        self.next_cleaning = time.time() + self.cleaning_interval
-
-    def maybe_clean(self):
-        """Clean the cache if it's time to do so."""
-
-        now = time.time()
-        if self.next_cleaning <= now:
-            keys_to_delete = []
-            for (k, v) in self.data.iteritems():
-                if v.expiration <= now:
-                    keys_to_delete.append(k)
-            for k in keys_to_delete:
-                del self.data[k]
-            now = time.time()
-            self.next_cleaning = now + self.cleaning_interval
-
-    def get(self, key):
-        """Get the answer associated with I{key}.  Returns None if
-        no answer is cached for the key.
-        @param key: the key
-        @type key: (dns.name.Name, int, int) tuple whose values are the
-        query name, rdtype, and rdclass.
-        @rtype: dns.resolver.Answer object or None
-        """
-
-        self.maybe_clean()
-        v = self.data.get(key)
-        if v is None or v.expiration <= time.time():
-            return None
-        return v
-
-    def put(self, key, value):
-        """Associate key and value in the cache.
-        @param key: the key
-        @type key: (dns.name.Name, int, int) tuple whose values are the
-        query name, rdtype, and rdclass.
-        @param value: The answer being cached
-        @type value: dns.resolver.Answer object
-        """
-
-        self.maybe_clean()
-        self.data[key] = value
-
-    def flush(self, key=None):
-        """Flush the cache.
-
-        If I{key} is specified, only that item is flushed.  Otherwise
-        the entire cache is flushed.
-
-        @param key: the key to flush
-        @type key: (dns.name.Name, int, int) tuple or None
-        """
-
-        if not key is None:
-            if self.data.has_key(key):
-                del self.data[key]
-        else:
-            self.data = {}
-            self.next_cleaning = time.time() + self.cleaning_interval
-
-class Resolver(object):
-    """DNS stub resolver
-
-    @ivar domain: The domain of this host
-    @type domain: dns.name.Name object
-    @ivar nameservers: A list of nameservers to query.  Each nameserver is
-    a string which contains the IP address of a nameserver.
-    @type nameservers: list of strings
-    @ivar search: The search list.  If the query name is a relative name,
-    the resolver will construct an absolute query name by appending the search
-    names one by one to the query name.
-    @type search: list of dns.name.Name objects
-    @ivar port: The port to which to send queries.  The default is 53.
-    @type port: int
-    @ivar timeout: The number of seconds to wait for a response from a
-    server, before timing out.
-    @type timeout: float
-    @ivar lifetime: The total number of seconds to spend trying to get an
-    answer to the question.  If the lifetime expires, a Timeout exception
-    will occur.
-    @type lifetime: float
-    @ivar keyring: The TSIG keyring to use.  The default is None.
-    @type keyring: dict
-    @ivar keyname: The TSIG keyname to use.  The default is None.
-    @type keyname: dns.name.Name object
-    @ivar keyalgorithm: The TSIG key algorithm to use.  The default is
-    dns.tsig.default_algorithm.
-    @type keyalgorithm: string
-    @ivar edns: The EDNS level to use.  The default is -1, no Edns.
-    @type edns: int
-    @ivar ednsflags: The EDNS flags
-    @type ednsflags: int
-    @ivar payload: The EDNS payload size.  The default is 0.
-    @type payload: int
-    @ivar cache: The cache to use.  The default is None.
-    @type cache: dns.resolver.Cache object
-    """
-    def __init__(self, filename='/etc/resolv.conf', configure=True):
-        """Initialize a resolver instance.
-
-        @param filename: The filename of a configuration file in
-        standard /etc/resolv.conf format.  This parameter is meaningful
-        only when I{configure} is true and the platform is POSIX.
-        @type filename: string or file object
-        @param configure: If True (the default), the resolver instance
-        is configured in the normal fashion for the operating system
-        the resolver is running on.  (I.e. a /etc/resolv.conf file on
-        POSIX systems and from the registry on Windows systems.)
-        @type configure: bool"""
-
-        self.reset()
-        if configure:
-            if sys.platform == 'win32':
-                self.read_registry()
-            elif filename:
-                self.read_resolv_conf(filename)
-
-    def reset(self):
-        """Reset all resolver configuration to the defaults."""
-        self.domain = \
-            dns.name.Name(dns.name.from_text(socket.gethostname())[1:])
-        if len(self.domain) == 0:
-            self.domain = dns.name.root
-        self.nameservers = []
-        self.search = []
-        self.port = 53
-        self.timeout = 2.0
-        self.lifetime = 30.0
-        self.keyring = None
-        self.keyname = None
-        self.keyalgorithm = dns.tsig.default_algorithm
-        self.edns = -1
-        self.ednsflags = 0
-        self.payload = 0
-        self.cache = None
-
-    def read_resolv_conf(self, f):
-        """Process f as a file in the /etc/resolv.conf format.  If f is
-        a string, it is used as the name of the file to open; otherwise it
-        is treated as the file itself."""
-        if isinstance(f, str) or isinstance(f, unicode):
-            try:
-                f = open(f, 'r')
-            except IOError:
-                # /etc/resolv.conf doesn't exist, can't be read, etc.
-                # We'll just use the default resolver configuration.
-                self.nameservers = ['127.0.0.1']
-                return
-            want_close = True
-        else:
-            want_close = False
-        try:
-            for l in f:
-                if len(l) == 0 or l[0] == '#' or l[0] == ';':
-                    continue
-                tokens = l.split()
-                if len(tokens) == 0:
-                    continue
-                if tokens[0] == 'nameserver':
-                    self.nameservers.append(tokens[1])
-                elif tokens[0] == 'domain':
-                    self.domain = dns.name.from_text(tokens[1])
-                elif tokens[0] == 'search':
-                    for suffix in tokens[1:]:
-                        self.search.append(dns.name.from_text(suffix))
-        finally:
-            if want_close:
-                f.close()
-        if len(self.nameservers) == 0:
-            self.nameservers.append('127.0.0.1')
-
-    def _determine_split_char(self, entry):
-        #
-        # The windows registry irritatingly changes the list element
-        # delimiter in between ' ' and ',' (and vice-versa) in various
-        # versions of windows.
-        #
-        if entry.find(' ') >= 0:
-            split_char = ' '
-        elif entry.find(',') >= 0:
-            split_char = ','
-        else:
-            # probably a singleton; treat as a space-separated list.
-            split_char = ' '
-        return split_char
-
-    def _config_win32_nameservers(self, nameservers):
-        """Configure a NameServer registry entry."""
-        # we call str() on nameservers to convert it from unicode to ascii
-        nameservers = str(nameservers)
-        split_char = self._determine_split_char(nameservers)
-        ns_list = nameservers.split(split_char)
-        for ns in ns_list:
-            if not ns in self.nameservers:
-                self.nameservers.append(ns)
-
-    def _config_win32_domain(self, domain):
-        """Configure a Domain registry entry."""
-        # we call str() on domain to convert it from unicode to ascii
-        self.domain = dns.name.from_text(str(domain))
-
-    def _config_win32_search(self, search):
-        """Configure a Search registry entry."""
-        # we call str() on search to convert it from unicode to ascii
-        search = str(search)
-        split_char = self._determine_split_char(search)
-        search_list = search.split(split_char)
-        for s in search_list:
-            if not s in self.search:
-                self.search.append(dns.name.from_text(s))
-
-    def _config_win32_fromkey(self, key):
-        """Extract DNS info from a registry key."""
-        try:
-            servers, rtype = _winreg.QueryValueEx(key, 'NameServer')
-        except WindowsError:
-            servers = None
-        if servers:
-            self._config_win32_nameservers(servers)
-            try:
-                dom, rtype = _winreg.QueryValueEx(key, 'Domain')
-                if dom:
-                    self._config_win32_domain(dom)
-            except WindowsError:
-                pass
-        else:
-            try:
-                servers, rtype = _winreg.QueryValueEx(key, 'DhcpNameServer')
-            except WindowsError:
-                servers = None
-            if servers:
-                self._config_win32_nameservers(servers)
-                try:
-                    dom, rtype = _winreg.QueryValueEx(key, 'DhcpDomain')
-                    if dom:
-                        self._config_win32_domain(dom)
-                except WindowsError:
-                    pass
-        try:
-            search, rtype = _winreg.QueryValueEx(key, 'SearchList')
-        except WindowsError:
-            search = None
-        if search:
-            self._config_win32_search(search)
-
-    def read_registry(self):
-        """Extract resolver configuration from the Windows registry."""
-        lm = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
-        want_scan = False
-        try:
-            try:
-                # XP, 2000
-                tcp_params = _winreg.OpenKey(lm,
-                                             r'SYSTEM\CurrentControlSet'
-                                             r'\Services\Tcpip\Parameters')
-                want_scan = True
-            except EnvironmentError:
-                # ME
-                tcp_params = _winreg.OpenKey(lm,
-                                             r'SYSTEM\CurrentControlSet'
-                                             r'\Services\VxD\MSTCP')
-            try:
-                self._config_win32_fromkey(tcp_params)
-            finally:
-                tcp_params.Close()
-            if want_scan:
-                interfaces = _winreg.OpenKey(lm,
-                                             r'SYSTEM\CurrentControlSet'
-                                             r'\Services\Tcpip\Parameters'
-                                             r'\Interfaces')
-                try:
-                    i = 0
-                    while True:
-                        try:
-                            guid = _winreg.EnumKey(interfaces, i)
-                            i += 1
-                            key = _winreg.OpenKey(interfaces, guid)
-                            if not self._win32_is_nic_enabled(lm, guid, key):
-                                continue
-                            try:
-                                self._config_win32_fromkey(key)
-                            finally:
-                                key.Close()
-                        except EnvironmentError:
-                            break
-                finally:
-                    interfaces.Close()
-        finally:
-            lm.Close()
-
-    def _win32_is_nic_enabled(self, lm, guid, interface_key):
-         # Look in the Windows Registry to determine whether the network
-         # interface corresponding to the given guid is enabled.
-         #
-         # (Code contributed by Paul Marks, thanks!)
-         #
-         try:
-             # This hard-coded location seems to be consistent, at least
-             # from Windows 2000 through Vista.
-             connection_key = _winreg.OpenKey(
-                 lm,
-                 r'SYSTEM\CurrentControlSet\Control\Network'
-                 r'\{4D36E972-E325-11CE-BFC1-08002BE10318}'
-                 r'\%s\Connection' % guid)
-
-             try:
-                 # The PnpInstanceID points to a key inside Enum
-                 (pnp_id, ttype) = _winreg.QueryValueEx(
-                     connection_key, 'PnpInstanceID')
-
-                 if ttype != _winreg.REG_SZ:
-                     raise ValueError
-
-                 device_key = _winreg.OpenKey(
-                     lm, r'SYSTEM\CurrentControlSet\Enum\%s' % pnp_id)
-
-                 try:
-                     # Get ConfigFlags for this device
-                     (flags, ttype) = _winreg.QueryValueEx(
-                         device_key, 'ConfigFlags')
-
-                     if ttype != _winreg.REG_DWORD:
-                         raise ValueError
-
-                     # Based on experimentation, bit 0x1 indicates that the
-                     # device is disabled.
-                     return not (flags & 0x1)
-
-                 finally:
-                     device_key.Close()
-             finally:
-                 connection_key.Close()
-         except (EnvironmentError, ValueError):
-             # Pre-vista, enabled interfaces seem to have a non-empty
-             # NTEContextList; this was how dnspython detected enabled
-             # nics before the code above was contributed.  We've retained
-             # the old method since we don't know if the code above works
-             # on Windows 95/98/ME.
-             try:
-                 (nte, ttype) = _winreg.QueryValueEx(interface_key,
-                                                     'NTEContextList')
-                 return nte is not None
-             except WindowsError:
-                 return False
-
-    def _compute_timeout(self, start):
-        now = time.time()
-        if now < start:
-            if start - now > 1:
-                # Time going backwards is bad.  Just give up.
-                raise Timeout
-            else:
-                # Time went backwards, but only a little.  This can
-                # happen, e.g. under vmware with older linux kernels.
-                # Pretend it didn't happen.
-                now = start
-        duration = now - start
-        if duration >= self.lifetime:
-            raise Timeout
-        return min(self.lifetime - duration, self.timeout)
-
-    def query(self, qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
-              tcp=False, source=None):
-        """Query nameservers to find the answer to the question.
-
-        The I{qname}, I{rdtype}, and I{rdclass} parameters may be objects
-        of the appropriate type, or strings that can be converted into objects
-        of the appropriate type.  E.g. For I{rdtype} the integer 2 and the
-        the string 'NS' both mean to query for records with DNS rdata type NS.
-
-        @param qname: the query name
-        @type qname: dns.name.Name object or string
-        @param rdtype: the query type
-        @type rdtype: int or string
-        @param rdclass: the query class
-        @type rdclass: int or string
-        @param tcp: use TCP to make the query (default is False).
-        @type tcp: bool
-        @param source: bind to this IP address (defaults to machine default IP).
-        @type source: IP address in dotted quad notation
-        @rtype: dns.resolver.Answer instance
-        @raises Timeout: no answers could be found in the specified lifetime
-        @raises NXDOMAIN: the query name does not exist
-        @raises NoAnswer: the response did not contain an answer
-        @raises NoNameservers: no non-broken nameservers are available to
-        answer the question."""
-
-        if isinstance(qname, (str, unicode)):
-            qname = dns.name.from_text(qname, None)
-        if isinstance(rdtype, str):
-            rdtype = dns.rdatatype.from_text(rdtype)
-        if isinstance(rdclass, str):
-            rdclass = dns.rdataclass.from_text(rdclass)
-        qnames_to_try = []
-        if qname.is_absolute():
-            qnames_to_try.append(qname)
-        else:
-            if len(qname) > 1:
-                qnames_to_try.append(qname.concatenate(dns.name.root))
-            if self.search:
-                for suffix in self.search:
-                    qnames_to_try.append(qname.concatenate(suffix))
-            else:
-                qnames_to_try.append(qname.concatenate(self.domain))
-        all_nxdomain = True
-        start = time.time()
-        for qname in qnames_to_try:
-            if self.cache:
-                answer = self.cache.get((qname, rdtype, rdclass))
-                if answer:
-                    return answer
-            request = dns.message.make_query(qname, rdtype, rdclass)
-            if not self.keyname is None:
-                request.use_tsig(self.keyring, self.keyname, self.keyalgorithm)
-            request.use_edns(self.edns, self.ednsflags, self.payload)
-            response = None
-            #
-            # make a copy of the servers list so we can alter it later.
-            #
-            nameservers = self.nameservers[:]
-            backoff = 0.10
-            while response is None:
-                if len(nameservers) == 0:
-                    raise NoNameservers
-                for nameserver in nameservers[:]:
-                    timeout = self._compute_timeout(start)
-                    try:
-                        if tcp:
-                            response = dns.query.tcp(request, nameserver,
-                                                     timeout, self.port,
-                                                     source=source)
-                        else:
-                            response = dns.query.udp(request, nameserver,
-                                                     timeout, self.port,
-                                                     source=source)
-                    except (socket.error, dns.exception.Timeout):
-                        #
-                        # Communication failure or timeout.  Go to the
-                        # next server
-                        #
-                        response = None
-                        continue
-                    except dns.query.UnexpectedSource:
-                        #
-                        # Who knows?  Keep going.
-                        #
-                        response = None
-                        continue
-                    except dns.exception.FormError:
-                        #
-                        # We don't understand what this server is
-                        # saying.  Take it out of the mix and
-                        # continue.
-                        #
-                        nameservers.remove(nameserver)
-                        response = None
-                        continue
-                    rcode = response.rcode()
-                    if rcode == dns.rcode.NOERROR or \
-                           rcode == dns.rcode.NXDOMAIN:
-                        break
-                    #
-                    # We got a response, but we're not happy with the
-                    # rcode in it.  Remove the server from the mix if
-                    # the rcode isn't SERVFAIL.
-                    #
-                    if rcode != dns.rcode.SERVFAIL:
-                        nameservers.remove(nameserver)
-                    response = None
-                if not response is None:
-                    break
-                #
-                # All nameservers failed!
-                #
-                if len(nameservers) > 0:
-                    #
-                    # But we still have servers to try.  Sleep a bit
-                    # so we don't pound them!
-                    #
-                    timeout = self._compute_timeout(start)
-                    sleep_time = min(timeout, backoff)
-                    backoff *= 2
-                    time.sleep(sleep_time)
-            if response.rcode() == dns.rcode.NXDOMAIN:
-                continue
-            all_nxdomain = False
-            break
-        if all_nxdomain:
-            raise NXDOMAIN
-        answer = Answer(qname, rdtype, rdclass, response)
-        if self.cache:
-            self.cache.put((qname, rdtype, rdclass), answer)
-        return answer
-
-    def use_tsig(self, keyring, keyname=None,
-                 algorithm=dns.tsig.default_algorithm):
-        """Add a TSIG signature to the query.
-
-        @param keyring: The TSIG keyring to use; defaults to None.
-        @type keyring: dict
-        @param keyname: The name of the TSIG key to use; defaults to None.
-        The key must be defined in the keyring.  If a keyring is specified
-        but a keyname is not, then the key used will be the first key in the
-        keyring.  Note that the order of keys in a dictionary is not defined,
-        so applications should supply a keyname when a keyring is used, unless
-        they know the keyring contains only one key.
-        @param algorithm: The TSIG key algorithm to use.  The default
-        is dns.tsig.default_algorithm.
-        @type algorithm: string"""
-        self.keyring = keyring
-        if keyname is None:
-            self.keyname = self.keyring.keys()[0]
-        else:
-            self.keyname = keyname
-        self.keyalgorithm = algorithm
-
-    def use_edns(self, edns, ednsflags, payload):
-        """Configure Edns.
-
-        @param edns: The EDNS level to use.  The default is -1, no Edns.
-        @type edns: int
-        @param ednsflags: The EDNS flags
-        @type ednsflags: int
-        @param payload: The EDNS payload size.  The default is 0.
-        @type payload: int"""
-
-        if edns is None:
-            edns = -1
-        self.edns = edns
-        self.ednsflags = ednsflags
-        self.payload = payload
-
-default_resolver = None
-
-def get_default_resolver():
-    """Get the default resolver, initializing it if necessary."""
-    global default_resolver
-    if default_resolver is None:
-        default_resolver = Resolver()
-    return default_resolver
-
-def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN,
-          tcp=False, source=None):
-    """Query nameservers to find the answer to the question.
-
-    This is a convenience function that uses the default resolver
-    object to make the query.
-    @see: L{dns.resolver.Resolver.query} for more information on the
-    parameters."""
-    return get_default_resolver().query(qname, rdtype, rdclass, tcp, source)
-
-def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None):
-    """Find the name of the zone which contains the specified name.
-
-    @param name: the query name
-    @type name: absolute dns.name.Name object or string
-    @param rdclass: The query class
-    @type rdclass: int
-    @param tcp: use TCP to make the query (default is False).
-    @type tcp: bool
-    @param resolver: the resolver to use
-    @type resolver: dns.resolver.Resolver object or None
-    @rtype: dns.name.Name"""
-
-    if isinstance(name, (str, unicode)):
-        name = dns.name.from_text(name, dns.name.root)
-    if resolver is None:
-        resolver = get_default_resolver()
-    if not name.is_absolute():
-        raise NotAbsolute(name)
-    while 1:
-        try:
-            answer = resolver.query(name, dns.rdatatype.SOA, rdclass, tcp)
-            return name
-        except (dns.resolver.NXDOMAIN, dns.resolver.NoAnswer):
-            try:
-                name = name.parent()
-            except dns.name.NoParent:
-                raise NoRootSOA
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/reversename.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/reversename.py
deleted file mode 100644
index 0a61b82..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/reversename.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright (C) 2006, 2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Reverse Map Names.
-
-@var ipv4_reverse_domain: The DNS IPv4 reverse-map domain, in-addr.arpa.
-@type ipv4_reverse_domain: dns.name.Name object
-@var ipv6_reverse_domain: The DNS IPv6 reverse-map domain, ip6.arpa.
-@type ipv6_reverse_domain: dns.name.Name object
-"""
-
-import dns.name
-import dns.ipv6
-import dns.ipv4
-
-ipv4_reverse_domain = dns.name.from_text('in-addr.arpa.')
-ipv6_reverse_domain = dns.name.from_text('ip6.arpa.')
-
-def from_address(text):
-    """Convert an IPv4 or IPv6 address in textual form into a Name object whose
-    value is the reverse-map domain name of the address.
-    @param text: an IPv4 or IPv6 address in textual form (e.g. '127.0.0.1',
-    '::1')
-    @type text: str
-    @rtype: dns.name.Name object
-    """
-    try:
-        parts = list(dns.ipv6.inet_aton(text).encode('hex_codec'))
-        origin = ipv6_reverse_domain
-    except:
-        parts = ['%d' % ord(byte) for byte in dns.ipv4.inet_aton(text)]
-        origin = ipv4_reverse_domain
-    parts.reverse()
-    return dns.name.from_text('.'.join(parts), origin=origin)
-
-def to_address(name):
-    """Convert a reverse map domain name into textual address form.
-    @param name: an IPv4 or IPv6 address in reverse-map form.
-    @type name: dns.name.Name object
-    @rtype: str
-    """
-    if name.is_subdomain(ipv4_reverse_domain):
-        name = name.relativize(ipv4_reverse_domain)
-        labels = list(name.labels)
-        labels.reverse()
-        text = '.'.join(labels)
-        # run through inet_aton() to check syntax and make pretty.
-        return dns.ipv4.inet_ntoa(dns.ipv4.inet_aton(text))
-    elif name.is_subdomain(ipv6_reverse_domain):
-        name = name.relativize(ipv6_reverse_domain)
-        labels = list(name.labels)
-        labels.reverse()
-        parts = []
-        i = 0
-        l = len(labels)
-        while i < l:
-            parts.append(''.join(labels[i:i+4]))
-            i += 4
-        text = ':'.join(parts)
-        # run through inet_aton() to check syntax and make pretty.
-        return dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(text))
-    else:
-        raise dns.exception.SyntaxError('unknown reverse-map address family')
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rrset.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/rrset.py
deleted file mode 100644
index 7f6c4af..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/rrset.py
+++ /dev/null
@@ -1,175 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS RRsets (an RRset is a named rdataset)"""
-
-import dns.name
-import dns.rdataset
-import dns.rdataclass
-import dns.renderer
-
-class RRset(dns.rdataset.Rdataset):
-    """A DNS RRset (named rdataset).
-
-    RRset inherits from Rdataset, and RRsets can be treated as
-    Rdatasets in most cases.  There are, however, a few notable
-    exceptions.  RRsets have different to_wire() and to_text() method
-    arguments, reflecting the fact that RRsets always have an owner
-    name.
-    """
-
-    __slots__ = ['name', 'deleting']
-
-    def __init__(self, name, rdclass, rdtype, covers=dns.rdatatype.NONE,
-                 deleting=None):
-        """Create a new RRset."""
-
-        super(RRset, self).__init__(rdclass, rdtype)
-        self.name = name
-        self.deleting = deleting
-
-    def _clone(self):
-        obj = super(RRset, self)._clone()
-        obj.name = self.name
-        obj.deleting = self.deleting
-        return obj
-
-    def __repr__(self):
-        if self.covers == 0:
-            ctext = ''
-        else:
-            ctext = '(' + dns.rdatatype.to_text(self.covers) + ')'
-        if not self.deleting is None:
-            dtext = ' delete=' + dns.rdataclass.to_text(self.deleting)
-        else:
-            dtext = ''
-        return '<DNS ' + str(self.name) + ' ' + \
-               dns.rdataclass.to_text(self.rdclass) + ' ' + \
-               dns.rdatatype.to_text(self.rdtype) + ctext + dtext + ' RRset>'
-
-    def __str__(self):
-        return self.to_text()
-
-    def __eq__(self, other):
-        """Two RRsets are equal if they have the same name and the same
-        rdataset
-
-        @rtype: bool"""
-        if not isinstance(other, RRset):
-            return False
-        if self.name != other.name:
-            return False
-        return super(RRset, self).__eq__(other)
-
-    def match(self, name, rdclass, rdtype, covers, deleting=None):
-        """Returns True if this rrset matches the specified class, type,
-        covers, and deletion state."""
-
-        if not super(RRset, self).match(rdclass, rdtype, covers):
-            return False
-        if self.name != name or self.deleting != deleting:
-            return False
-        return True
-
-    def to_text(self, origin=None, relativize=True, **kw):
-        """Convert the RRset into DNS master file format.
-
-        @see: L{dns.name.Name.choose_relativity} for more information
-        on how I{origin} and I{relativize} determine the way names
-        are emitted.
-
-        Any additional keyword arguments are passed on to the rdata
-        to_text() method.
-
-        @param origin: The origin for relative names, or None.
-        @type origin: dns.name.Name object
-        @param relativize: True if names should names be relativized
-        @type relativize: bool"""
-
-        return super(RRset, self).to_text(self.name, origin, relativize,
-                                          self.deleting, **kw)
-
-    def to_wire(self, file, compress=None, origin=None, **kw):
-        """Convert the RRset to wire format."""
-
-        return super(RRset, self).to_wire(self.name, file, compress, origin,
-                                          self.deleting, **kw)
-
-    def to_rdataset(self):
-        """Convert an RRset into an Rdataset.
-
-        @rtype: dns.rdataset.Rdataset object
-        """
-        return dns.rdataset.from_rdata_list(self.ttl, list(self))
-
-
-def from_text_list(name, ttl, rdclass, rdtype, text_rdatas):
-    """Create an RRset with the specified name, TTL, class, and type, and with
-    the specified list of rdatas in text format.
-
-    @rtype: dns.rrset.RRset object
-    """
-
-    if isinstance(name, (str, unicode)):
-        name = dns.name.from_text(name, None)
-    if isinstance(rdclass, str):
-        rdclass = dns.rdataclass.from_text(rdclass)
-    if isinstance(rdtype, str):
-        rdtype = dns.rdatatype.from_text(rdtype)
-    r = RRset(name, rdclass, rdtype)
-    r.update_ttl(ttl)
-    for t in text_rdatas:
-        rd = dns.rdata.from_text(r.rdclass, r.rdtype, t)
-        r.add(rd)
-    return r
-
-def from_text(name, ttl, rdclass, rdtype, *text_rdatas):
-    """Create an RRset with the specified name, TTL, class, and type and with
-    the specified rdatas in text format.
-
-    @rtype: dns.rrset.RRset object
-    """
-
-    return from_text_list(name, ttl, rdclass, rdtype, text_rdatas)
-
-def from_rdata_list(name, ttl, rdatas):
-    """Create an RRset with the specified name and TTL, and with
-    the specified list of rdata objects.
-
-    @rtype: dns.rrset.RRset object
-    """
-
-    if isinstance(name, (str, unicode)):
-        name = dns.name.from_text(name, None)
-
-    if len(rdatas) == 0:
-        raise ValueError("rdata list must not be empty")
-    r = None
-    for rd in rdatas:
-        if r is None:
-            r = RRset(name, rd.rdclass, rd.rdtype)
-            r.update_ttl(ttl)
-            first_time = False
-        r.add(rd)
-    return r
-
-def from_rdata(name, ttl, *rdatas):
-    """Create an RRset with the specified name and TTL, and with
-    the specified rdata objects.
-
-    @rtype: dns.rrset.RRset object
-    """
-
-    return from_rdata_list(name, ttl, rdatas)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/set.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/set.py
deleted file mode 100644
index 91f9fb8..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/set.py
+++ /dev/null
@@ -1,263 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""A simple Set class."""
-
-class Set(object):
-    """A simple set class.
-
-    Sets are not in Python until 2.3, and rdata are not immutable so
-    we cannot use sets.Set anyway.  This class implements subset of
-    the 2.3 Set interface using a list as the container.
-
-    @ivar items: A list of the items which are in the set
-    @type items: list"""
-
-    __slots__ = ['items']
-
-    def __init__(self, items=None):
-        """Initialize the set.
-
-        @param items: the initial set of items
-        @type items: any iterable or None
-        """
-
-        self.items = []
-        if not items is None:
-            for item in items:
-                self.add(item)
-
-    def __repr__(self):
-        return "dns.simpleset.Set(%s)" % repr(self.items)
-
-    def add(self, item):
-        """Add an item to the set."""
-        if not item in self.items:
-            self.items.append(item)
-
-    def remove(self, item):
-        """Remove an item from the set."""
-        self.items.remove(item)
-
-    def discard(self, item):
-        """Remove an item from the set if present."""
-        try:
-            self.items.remove(item)
-        except ValueError:
-            pass
-
-    def _clone(self):
-        """Make a (shallow) copy of the set.
-
-        There is a 'clone protocol' that subclasses of this class
-        should use.  To make a copy, first call your super's _clone()
-        method, and use the object returned as the new instance.  Then
-        make shallow copies of the attributes defined in the subclass.
-
-        This protocol allows us to write the set algorithms that
-        return new instances (e.g. union) once, and keep using them in
-        subclasses.
-        """
-
-        cls = self.__class__
-        obj = cls.__new__(cls)
-        obj.items = list(self.items)
-        return obj
-
-    def __copy__(self):
-        """Make a (shallow) copy of the set."""
-        return self._clone()
-
-    def copy(self):
-        """Make a (shallow) copy of the set."""
-        return self._clone()
-
-    def union_update(self, other):
-        """Update the set, adding any elements from other which are not
-        already in the set.
-        @param other: the collection of items with which to update the set
-        @type other: Set object
-        """
-        if not isinstance(other, Set):
-            raise ValueError('other must be a Set instance')
-        if self is other:
-            return
-        for item in other.items:
-            self.add(item)
-
-    def intersection_update(self, other):
-        """Update the set, removing any elements from other which are not
-        in both sets.
-        @param other: the collection of items with which to update the set
-        @type other: Set object
-        """
-        if not isinstance(other, Set):
-            raise ValueError('other must be a Set instance')
-        if self is other:
-            return
-        # we make a copy of the list so that we can remove items from
-        # the list without breaking the iterator.
-        for item in list(self.items):
-            if item not in other.items:
-                self.items.remove(item)
-
-    def difference_update(self, other):
-        """Update the set, removing any elements from other which are in
-        the set.
-        @param other: the collection of items with which to update the set
-        @type other: Set object
-        """
-        if not isinstance(other, Set):
-            raise ValueError('other must be a Set instance')
-        if self is other:
-            self.items = []
-        else:
-            for item in other.items:
-                self.discard(item)
-
-    def union(self, other):
-        """Return a new set which is the union of I{self} and I{other}.
-
-        @param other: the other set
-        @type other: Set object
-        @rtype: the same type as I{self}
-        """
-
-        obj = self._clone()
-        obj.union_update(other)
-        return obj
-
-    def intersection(self, other):
-        """Return a new set which is the intersection of I{self} and I{other}.
-
-        @param other: the other set
-        @type other: Set object
-        @rtype: the same type as I{self}
-        """
-
-        obj = self._clone()
-        obj.intersection_update(other)
-        return obj
-
-    def difference(self, other):
-        """Return a new set which I{self} - I{other}, i.e. the items
-        in I{self} which are not also in I{other}.
-
-        @param other: the other set
-        @type other: Set object
-        @rtype: the same type as I{self}
-        """
-
-        obj = self._clone()
-        obj.difference_update(other)
-        return obj
-
-    def __or__(self, other):
-        return self.union(other)
-
-    def __and__(self, other):
-        return self.intersection(other)
-
-    def __add__(self, other):
-        return self.union(other)
-
-    def __sub__(self, other):
-        return self.difference(other)
-
-    def __ior__(self, other):
-        self.union_update(other)
-        return self
-
-    def __iand__(self, other):
-        self.intersection_update(other)
-        return self
-
-    def __iadd__(self, other):
-        self.union_update(other)
-        return self
-
-    def __isub__(self, other):
-        self.difference_update(other)
-        return self
-
-    def update(self, other):
-        """Update the set, adding any elements from other which are not
-        already in the set.
-        @param other: the collection of items with which to update the set
-        @type other: any iterable type"""
-        for item in other:
-            self.add(item)
-
-    def clear(self):
-        """Make the set empty."""
-        self.items = []
-
-    def __eq__(self, other):
-        # Yes, this is inefficient but the sets we're dealing with are
-        # usually quite small, so it shouldn't hurt too much.
-        for item in self.items:
-            if not item in other.items:
-                return False
-        for item in other.items:
-            if not item in self.items:
-                return False
-        return True
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def __len__(self):
-        return len(self.items)
-
-    def __iter__(self):
-        return iter(self.items)
-
-    def __getitem__(self, i):
-        return self.items[i]
-
-    def __delitem__(self, i):
-        del self.items[i]
-
-    def __getslice__(self, i, j):
-        return self.items[i:j]
-
-    def __delslice__(self, i, j):
-        del self.items[i:j]
-
-    def issubset(self, other):
-        """Is I{self} a subset of I{other}?
-
-        @rtype: bool
-        """
-
-        if not isinstance(other, Set):
-            raise ValueError('other must be a Set instance')
-        for item in self.items:
-            if not item in other.items:
-                return False
-        return True
-
-    def issuperset(self, other):
-        """Is I{self} a superset of I{other}?
-
-        @rtype: bool
-        """
-
-        if not isinstance(other, Set):
-            raise ValueError('other must be a Set instance')
-        for item in other.items:
-            if not item in self.items:
-                return False
-        return True
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/tokenizer.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/tokenizer.py
deleted file mode 100644
index 4f68a2a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/tokenizer.py
+++ /dev/null
@@ -1,547 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""Tokenize DNS master file format"""
-
-import cStringIO
-import sys
-
-import dns.exception
-import dns.name
-import dns.ttl
-
-_DELIMITERS = {
-    ' ' : True,
-    '\t' : True,
-    '\n' : True,
-    ';' : True,
-    '(' : True,
-    ')' : True,
-    '"' : True }
-
-_QUOTING_DELIMITERS = { '"' : True }
-
-EOF = 0
-EOL = 1
-WHITESPACE = 2
-IDENTIFIER = 3
-QUOTED_STRING = 4
-COMMENT = 5
-DELIMITER = 6
-
-class UngetBufferFull(dns.exception.DNSException):
-    """Raised when an attempt is made to unget a token when the unget
-    buffer is full."""
-    pass
-
-class Token(object):
-    """A DNS master file format token.
-
-    @ivar ttype: The token type
-    @type ttype: int
-    @ivar value: The token value
-    @type value: string
-    @ivar has_escape: Does the token value contain escapes?
-    @type has_escape: bool
-    """
-
-    def __init__(self, ttype, value='', has_escape=False):
-        """Initialize a token instance.
-
-        @param ttype: The token type
-        @type ttype: int
-        @ivar value: The token value
-        @type value: string
-        @ivar has_escape: Does the token value contain escapes?
-        @type has_escape: bool
-        """
-        self.ttype = ttype
-        self.value = value
-        self.has_escape = has_escape
-
-    def is_eof(self):
-        return self.ttype == EOF
-
-    def is_eol(self):
-        return self.ttype == EOL
-
-    def is_whitespace(self):
-        return self.ttype == WHITESPACE
-
-    def is_identifier(self):
-        return self.ttype == IDENTIFIER
-
-    def is_quoted_string(self):
-        return self.ttype == QUOTED_STRING
-
-    def is_comment(self):
-        return self.ttype == COMMENT
-
-    def is_delimiter(self):
-        return self.ttype == DELIMITER
-
-    def is_eol_or_eof(self):
-        return (self.ttype == EOL or self.ttype == EOF)
-
-    def __eq__(self, other):
-        if not isinstance(other, Token):
-            return False
-        return (self.ttype == other.ttype and
-                self.value == other.value)
-
-    def __ne__(self, other):
-        if not isinstance(other, Token):
-            return True
-        return (self.ttype != other.ttype or
-                self.value != other.value)
-
-    def __str__(self):
-        return '%d "%s"' % (self.ttype, self.value)
-
-    def unescape(self):
-        if not self.has_escape:
-            return self
-        unescaped = ''
-        l = len(self.value)
-        i = 0
-        while i < l:
-            c = self.value[i]
-            i += 1
-            if c == '\\':
-                if i >= l:
-                    raise dns.exception.UnexpectedEnd
-                c = self.value[i]
-                i += 1
-                if c.isdigit():
-                    if i >= l:
-                        raise dns.exception.UnexpectedEnd
-                    c2 = self.value[i]
-                    i += 1
-                    if i >= l:
-                        raise dns.exception.UnexpectedEnd
-                    c3 = self.value[i]
-                    i += 1
-                    if not (c2.isdigit() and c3.isdigit()):
-                        raise dns.exception.SyntaxError
-                    c = chr(int(c) * 100 + int(c2) * 10 + int(c3))
-            unescaped += c
-        return Token(self.ttype, unescaped)
-
-    # compatibility for old-style tuple tokens
-
-    def __len__(self):
-        return 2
-
-    def __iter__(self):
-        return iter((self.ttype, self.value))
-
-    def __getitem__(self, i):
-        if i == 0:
-            return self.ttype
-        elif i == 1:
-            return self.value
-        else:
-            raise IndexError
-
-class Tokenizer(object):
-    """A DNS master file format tokenizer.
-
-    A token is a (type, value) tuple, where I{type} is an int, and
-    I{value} is a string.  The valid types are EOF, EOL, WHITESPACE,
-    IDENTIFIER, QUOTED_STRING, COMMENT, and DELIMITER.
-
-    @ivar file: The file to tokenize
-    @type file: file
-    @ivar ungotten_char: The most recently ungotten character, or None.
-    @type ungotten_char: string
-    @ivar ungotten_token: The most recently ungotten token, or None.
-    @type ungotten_token: (int, string) token tuple
-    @ivar multiline: The current multiline level.  This value is increased
-    by one every time a '(' delimiter is read, and decreased by one every time
-    a ')' delimiter is read.
-    @type multiline: int
-    @ivar quoting: This variable is true if the tokenizer is currently
-    reading a quoted string.
-    @type quoting: bool
-    @ivar eof: This variable is true if the tokenizer has encountered EOF.
-    @type eof: bool
-    @ivar delimiters: The current delimiter dictionary.
-    @type delimiters: dict
-    @ivar line_number: The current line number
-    @type line_number: int
-    @ivar filename: A filename that will be returned by the L{where} method.
-    @type filename: string
-    """
-
-    def __init__(self, f=sys.stdin, filename=None):
-        """Initialize a tokenizer instance.
-
-        @param f: The file to tokenize.  The default is sys.stdin.
-        This parameter may also be a string, in which case the tokenizer
-        will take its input from the contents of the string.
-        @type f: file or string
-        @param filename: the name of the filename that the L{where} method
-        will return.
-        @type filename: string
-        """
-
-        if isinstance(f, str):
-            f = cStringIO.StringIO(f)
-            if filename is None:
-                filename = '<string>'
-        else:
-            if filename is None:
-                if f is sys.stdin:
-                    filename = '<stdin>'
-                else:
-                    filename = '<file>'
-        self.file = f
-        self.ungotten_char = None
-        self.ungotten_token = None
-        self.multiline = 0
-        self.quoting = False
-        self.eof = False
-        self.delimiters = _DELIMITERS
-        self.line_number = 1
-        self.filename = filename
-
-    def _get_char(self):
-        """Read a character from input.
-        @rtype: string
-        """
-
-        if self.ungotten_char is None:
-            if self.eof:
-                c = ''
-            else:
-                c = self.file.read(1)
-                if c == '':
-                    self.eof = True
-                elif c == '\n':
-                    self.line_number += 1
-        else:
-            c = self.ungotten_char
-            self.ungotten_char = None
-        return c
-
-    def where(self):
-        """Return the current location in the input.
-
-        @rtype: (string, int) tuple.  The first item is the filename of
-        the input, the second is the current line number.
-        """
-
-        return (self.filename, self.line_number)
-
-    def _unget_char(self, c):
-        """Unget a character.
-
-        The unget buffer for characters is only one character large; it is
-        an error to try to unget a character when the unget buffer is not
-        empty.
-
-        @param c: the character to unget
-        @type c: string
-        @raises UngetBufferFull: there is already an ungotten char
-        """
-
-        if not self.ungotten_char is None:
-            raise UngetBufferFull
-        self.ungotten_char = c
-
-    def skip_whitespace(self):
-        """Consume input until a non-whitespace character is encountered.
-
-        The non-whitespace character is then ungotten, and the number of
-        whitespace characters consumed is returned.
-
-        If the tokenizer is in multiline mode, then newlines are whitespace.
-
-        @rtype: int
-        """
-
-        skipped = 0
-        while True:
-            c = self._get_char()
-            if c != ' ' and c != '\t':
-                if (c != '\n') or not self.multiline:
-                    self._unget_char(c)
-                    return skipped
-            skipped += 1
-
-    def get(self, want_leading = False, want_comment = False):
-        """Get the next token.
-
-        @param want_leading: If True, return a WHITESPACE token if the
-        first character read is whitespace.  The default is False.
-        @type want_leading: bool
-        @param want_comment: If True, return a COMMENT token if the
-        first token read is a comment.  The default is False.
-        @type want_comment: bool
-        @rtype: Token object
-        @raises dns.exception.UnexpectedEnd: input ended prematurely
-        @raises dns.exception.SyntaxError: input was badly formed
-        """
-
-        if not self.ungotten_token is None:
-            token = self.ungotten_token
-            self.ungotten_token = None
-            if token.is_whitespace():
-                if want_leading:
-                    return token
-            elif token.is_comment():
-                if want_comment:
-                    return token
-            else:
-                return token
-        skipped = self.skip_whitespace()
-        if want_leading and skipped > 0:
-            return Token(WHITESPACE, ' ')
-        token = ''
-        ttype = IDENTIFIER
-        has_escape = False
-        while True:
-            c = self._get_char()
-            if c == '' or c in self.delimiters:
-                if c == '' and self.quoting:
-                    raise dns.exception.UnexpectedEnd
-                if token == '' and ttype != QUOTED_STRING:
-                    if c == '(':
-                        self.multiline += 1
-                        self.skip_whitespace()
-                        continue
-                    elif c == ')':
-                        if not self.multiline > 0:
-                            raise dns.exception.SyntaxError
-                        self.multiline -= 1
-                        self.skip_whitespace()
-                        continue
-                    elif c == '"':
-                        if not self.quoting:
-                            self.quoting = True
-                            self.delimiters = _QUOTING_DELIMITERS
-                            ttype = QUOTED_STRING
-                            continue
-                        else:
-                            self.quoting = False
-                            self.delimiters = _DELIMITERS
-                            self.skip_whitespace()
-                            continue
-                    elif c == '\n':
-                        return Token(EOL, '\n')
-                    elif c == ';':
-                        while 1:
-                            c = self._get_char()
-                            if c == '\n' or c == '':
-                                break
-                            token += c
-                        if want_comment:
-                            self._unget_char(c)
-                            return Token(COMMENT, token)
-                        elif c == '':
-                            if self.multiline:
-                                raise dns.exception.SyntaxError('unbalanced parentheses')
-                            return Token(EOF)
-                        elif self.multiline:
-                            self.skip_whitespace()
-                            token = ''
-                            continue
-                        else:
-                            return Token(EOL, '\n')
-                    else:
-                        # This code exists in case we ever want a
-                        # delimiter to be returned.  It never produces
-                        # a token currently.
-                        token = c
-                        ttype = DELIMITER
-                else:
-                    self._unget_char(c)
-                break
-            elif self.quoting:
-                if c == '\\':
-                    c = self._get_char()
-                    if c == '':
-                        raise dns.exception.UnexpectedEnd
-                    if c.isdigit():
-                        c2 = self._get_char()
-                        if c2 == '':
-                            raise dns.exception.UnexpectedEnd
-                        c3 = self._get_char()
-                        if c == '':
-                            raise dns.exception.UnexpectedEnd
-                        if not (c2.isdigit() and c3.isdigit()):
-                            raise dns.exception.SyntaxError
-                        c = chr(int(c) * 100 + int(c2) * 10 + int(c3))
-                elif c == '\n':
-                    raise dns.exception.SyntaxError('newline in quoted string')
-            elif c == '\\':
-                #
-                # It's an escape.  Put it and the next character into
-                # the token; it will be checked later for goodness.
-                #
-                token += c
-                has_escape = True
-                c = self._get_char()
-                if c == '' or c == '\n':
-                    raise dns.exception.UnexpectedEnd
-            token += c
-        if token == '' and ttype != QUOTED_STRING:
-            if self.multiline:
-                raise dns.exception.SyntaxError('unbalanced parentheses')
-            ttype = EOF
-        return Token(ttype, token, has_escape)
-
-    def unget(self, token):
-        """Unget a token.
-
-        The unget buffer for tokens is only one token large; it is
-        an error to try to unget a token when the unget buffer is not
-        empty.
-
-        @param token: the token to unget
-        @type token: Token object
-        @raises UngetBufferFull: there is already an ungotten token
-        """
-
-        if not self.ungotten_token is None:
-            raise UngetBufferFull
-        self.ungotten_token = token
-
-    def next(self):
-        """Return the next item in an iteration.
-        @rtype: (int, string)
-        """
-
-        token = self.get()
-        if token.is_eof():
-            raise StopIteration
-        return token
-
-    def __iter__(self):
-        return self
-
-    # Helpers
-
-    def get_int(self):
-        """Read the next token and interpret it as an integer.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: int
-        """
-
-        token = self.get().unescape()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError('expecting an identifier')
-        if not token.value.isdigit():
-            raise dns.exception.SyntaxError('expecting an integer')
-        return int(token.value)
-
-    def get_uint8(self):
-        """Read the next token and interpret it as an 8-bit unsigned
-        integer.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: int
-        """
-
-        value = self.get_int()
-        if value < 0 or value > 255:
-            raise dns.exception.SyntaxError('%d is not an unsigned 8-bit integer' % value)
-        return value
-
-    def get_uint16(self):
-        """Read the next token and interpret it as a 16-bit unsigned
-        integer.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: int
-        """
-
-        value = self.get_int()
-        if value < 0 or value > 65535:
-            raise dns.exception.SyntaxError('%d is not an unsigned 16-bit integer' % value)
-        return value
-
-    def get_uint32(self):
-        """Read the next token and interpret it as a 32-bit unsigned
-        integer.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: int
-        """
-
-        token = self.get().unescape()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError('expecting an identifier')
-        if not token.value.isdigit():
-            raise dns.exception.SyntaxError('expecting an integer')
-        value = long(token.value)
-        if value < 0 or value > 4294967296L:
-            raise dns.exception.SyntaxError('%d is not an unsigned 32-bit integer' % value)
-        return value
-
-    def get_string(self, origin=None):
-        """Read the next token and interpret it as a string.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: string
-        """
-
-        token = self.get().unescape()
-        if not (token.is_identifier() or token.is_quoted_string()):
-            raise dns.exception.SyntaxError('expecting a string')
-        return token.value
-
-    def get_identifier(self, origin=None):
-        """Read the next token and raise an exception if it is not an identifier.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: string
-        """
-
-        token = self.get().unescape()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError('expecting an identifier')
-        return token.value
-
-    def get_name(self, origin=None):
-        """Read the next token and interpret it as a DNS name.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: dns.name.Name object"""
-
-        token = self.get()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError('expecting an identifier')
-        return dns.name.from_text(token.value, origin)
-
-    def get_eol(self):
-        """Read the next token and raise an exception if it isn't EOL or
-        EOF.
-
-        @raises dns.exception.SyntaxError:
-        @rtype: string
-        """
-
-        token = self.get()
-        if not token.is_eol_or_eof():
-            raise dns.exception.SyntaxError('expected EOL or EOF, got %d "%s"' % (token.ttype, token.value))
-        return token.value
-
-    def get_ttl(self):
-        token = self.get().unescape()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError('expecting an identifier')
-        return dns.ttl.from_text(token.value)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/tsig.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/tsig.py
deleted file mode 100644
index b4deeca..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/tsig.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright (C) 2001-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS TSIG support."""
-
-import hmac
-import struct
-
-import dns.exception
-import dns.rdataclass
-import dns.name
-
-class BadTime(dns.exception.DNSException):
-    """Raised if the current time is not within the TSIG's validity time."""
-    pass
-
-class BadSignature(dns.exception.DNSException):
-    """Raised if the TSIG signature fails to verify."""
-    pass
-
-class PeerError(dns.exception.DNSException):
-    """Base class for all TSIG errors generated by the remote peer"""
-    pass
-
-class PeerBadKey(PeerError):
-    """Raised if the peer didn't know the key we used"""
-    pass
-
-class PeerBadSignature(PeerError):
-    """Raised if the peer didn't like the signature we sent"""
-    pass
-
-class PeerBadTime(PeerError):
-    """Raised if the peer didn't like the time we sent"""
-    pass
-
-class PeerBadTruncation(PeerError):
-    """Raised if the peer didn't like amount of truncation in the TSIG we sent"""
-    pass
-
-default_algorithm = "HMAC-MD5.SIG-ALG.REG.INT"
-
-BADSIG = 16
-BADKEY = 17
-BADTIME = 18
-BADTRUNC = 22
-
-def sign(wire, keyname, secret, time, fudge, original_id, error,
-         other_data, request_mac, ctx=None, multi=False, first=True,
-         algorithm=default_algorithm):
-    """Return a (tsig_rdata, mac, ctx) tuple containing the HMAC TSIG rdata
-    for the input parameters, the HMAC MAC calculated by applying the
-    TSIG signature algorithm, and the TSIG digest context.
-    @rtype: (string, string, hmac.HMAC object)
-    @raises ValueError: I{other_data} is too long
-    @raises NotImplementedError: I{algorithm} is not supported
-    """
-
-    (algorithm_name, digestmod) = get_algorithm(algorithm)
-    if first:
-        ctx = hmac.new(secret, digestmod=digestmod)
-        ml = len(request_mac)
-        if ml > 0:
-            ctx.update(struct.pack('!H', ml))
-            ctx.update(request_mac)
-    id = struct.pack('!H', original_id)
-    ctx.update(id)
-    ctx.update(wire[2:])
-    if first:
-        ctx.update(keyname.to_digestable())
-        ctx.update(struct.pack('!H', dns.rdataclass.ANY))
-        ctx.update(struct.pack('!I', 0))
-    long_time = time + 0L
-    upper_time = (long_time >> 32) & 0xffffL
-    lower_time = long_time & 0xffffffffL
-    time_mac = struct.pack('!HIH', upper_time, lower_time, fudge)
-    pre_mac = algorithm_name + time_mac
-    ol = len(other_data)
-    if ol > 65535:
-        raise ValueError('TSIG Other Data is > 65535 bytes')
-    post_mac = struct.pack('!HH', error, ol) + other_data
-    if first:
-        ctx.update(pre_mac)
-        ctx.update(post_mac)
-    else:
-        ctx.update(time_mac)
-    mac = ctx.digest()
-    mpack = struct.pack('!H', len(mac))
-    tsig_rdata = pre_mac + mpack + mac + id + post_mac
-    if multi:
-        ctx = hmac.new(secret)
-        ml = len(mac)
-        ctx.update(struct.pack('!H', ml))
-        ctx.update(mac)
-    else:
-        ctx = None
-    return (tsig_rdata, mac, ctx)
-
-def hmac_md5(wire, keyname, secret, time, fudge, original_id, error,
-             other_data, request_mac, ctx=None, multi=False, first=True,
-             algorithm=default_algorithm):
-    return sign(wire, keyname, secret, time, fudge, original_id, error,
-                other_data, request_mac, ctx, multi, first, algorithm)
-
-def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata,
-             tsig_rdlen, ctx=None, multi=False, first=True):
-    """Validate the specified TSIG rdata against the other input parameters.
-
-    @raises FormError: The TSIG is badly formed.
-    @raises BadTime: There is too much time skew between the client and the
-    server.
-    @raises BadSignature: The TSIG signature did not validate
-    @rtype: hmac.HMAC object"""
-
-    (adcount,) = struct.unpack("!H", wire[10:12])
-    if adcount == 0:
-        raise dns.exception.FormError
-    adcount -= 1
-    new_wire = wire[0:10] + struct.pack("!H", adcount) + wire[12:tsig_start]
-    current = tsig_rdata
-    (aname, used) = dns.name.from_wire(wire, current)
-    current = current + used
-    (upper_time, lower_time, fudge, mac_size) = \
-                 struct.unpack("!HIHH", wire[current:current + 10])
-    time = ((upper_time + 0L) << 32) + (lower_time + 0L)
-    current += 10
-    mac = wire[current:current + mac_size]
-    current += mac_size
-    (original_id, error, other_size) = \
-                  struct.unpack("!HHH", wire[current:current + 6])
-    current += 6
-    other_data = wire[current:current + other_size]
-    current += other_size
-    if current != tsig_rdata + tsig_rdlen:
-        raise dns.exception.FormError
-    if error != 0:
-        if error == BADSIG:
-            raise PeerBadSignature
-        elif error == BADKEY:
-            raise PeerBadKey
-        elif error == BADTIME:
-            raise PeerBadTime
-        elif error == BADTRUNC:
-            raise PeerBadTruncation
-        else:
-            raise PeerError('unknown TSIG error code %d' % error)
-    time_low = time - fudge
-    time_high = time + fudge
-    if now < time_low or now > time_high:
-        raise BadTime
-    (junk, our_mac, ctx) = sign(new_wire, keyname, secret, time, fudge,
-                                original_id, error, other_data,
-                                request_mac, ctx, multi, first, aname)
-    if (our_mac != mac):
-        raise BadSignature
-    return ctx
-
-def get_algorithm(algorithm):
-    """Returns the wire format string and the hash module to use for the
-    specified TSIG algorithm
-
-    @rtype: (string, hash constructor)
-    @raises NotImplementedError: I{algorithm} is not supported
-    """
-
-    hashes = {}
-    try:
-        import hashlib
-        hashes[dns.name.from_text('hmac-sha224')] = hashlib.sha224
-        hashes[dns.name.from_text('hmac-sha256')] = hashlib.sha256
-        hashes[dns.name.from_text('hmac-sha384')] = hashlib.sha384
-        hashes[dns.name.from_text('hmac-sha512')] = hashlib.sha512
-        hashes[dns.name.from_text('hmac-sha1')] = hashlib.sha1
-        hashes[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] = hashlib.md5
-
-        import sys
-        if sys.hexversion < 0x02050000:
-            # hashlib doesn't conform to PEP 247: API for
-            # Cryptographic Hash Functions, which hmac before python
-            # 2.5 requires, so add the necessary items.
-            class HashlibWrapper:
-                def __init__(self, basehash):
-                    self.basehash = basehash
-                    self.digest_size = self.basehash().digest_size
-
-                def new(self, *args, **kwargs):
-                    return self.basehash(*args, **kwargs)
-
-            for name in hashes:
-                hashes[name] = HashlibWrapper(hashes[name])
-
-    except ImportError:
-        import md5, sha
-        hashes[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] =  md5.md5
-        hashes[dns.name.from_text('hmac-sha1')] = sha.sha
-
-    if isinstance(algorithm, (str, unicode)):
-        algorithm = dns.name.from_text(algorithm)
-
-    if algorithm in hashes:
-        return (algorithm.to_digestable(), hashes[algorithm])
-
-    raise NotImplementedError("TSIG algorithm " + str(algorithm) +
-                              " is not supported")
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/tsigkeyring.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/tsigkeyring.py
deleted file mode 100644
index cbd1a27..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/tsigkeyring.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""A place to store TSIG keys."""
-
-import base64
-
-import dns.name
-
-def from_text(textring):
-    """Convert a dictionary containing (textual DNS name, base64 secret) pairs
-    into a binary keyring which has (dns.name.Name, binary secret) pairs.
-    @rtype: dict"""
-    
-    keyring = {}
-    for keytext in textring:
-        keyname = dns.name.from_text(keytext)
-        secret = base64.decodestring(textring[keytext])
-        keyring[keyname] = secret
-    return keyring
-
-def to_text(keyring):
-    """Convert a dictionary containing (dns.name.Name, binary secret) pairs
-    into a text keyring which has (textual DNS name, base64 secret) pairs.
-    @rtype: dict"""
-    
-    textring = {}
-    for keyname in keyring:
-        keytext = dns.name.to_text(keyname)
-        secret = base64.encodestring(keyring[keyname])
-        textring[keytext] = secret
-    return textring
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/ttl.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/ttl.py
deleted file mode 100644
index f295300..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/ttl.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS TTL conversion."""
-
-import dns.exception
-
-class BadTTL(dns.exception.SyntaxError):
-    pass
-
-def from_text(text):
-    """Convert the text form of a TTL to an integer.
-
-    The BIND 8 units syntax for TTLs (e.g. '1w6d4h3m10s') is supported.
-
-    @param text: the textual TTL
-    @type text: string
-    @raises dns.ttl.BadTTL: the TTL is not well-formed
-    @rtype: int
-    """
-
-    if text.isdigit():
-        total = long(text)
-    else:
-        if not text[0].isdigit():
-            raise BadTTL
-        total = 0L
-        current = 0L
-        for c in text:
-            if c.isdigit():
-                current *= 10
-                current += long(c)
-            else:
-                c = c.lower()
-                if c == 'w':
-                    total += current * 604800L
-                elif c == 'd':
-                    total += current * 86400L
-                elif c == 'h':
-                    total += current * 3600L
-                elif c == 'm':
-                    total += current * 60L
-                elif c == 's':
-                    total += current
-                else:
-                    raise BadTTL("unknown unit '%s'" % c)
-                current = 0
-        if not current == 0:
-            raise BadTTL("trailing integer")
-    if total < 0L or total > 2147483647L:
-        raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)")
-    return total
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/update.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/update.py
deleted file mode 100644
index 7d42636..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/update.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Dynamic Update Support"""
-
-import dns.message
-import dns.name
-import dns.opcode
-import dns.rdata
-import dns.rdataclass
-import dns.rdataset
-
-class Update(dns.message.Message):
-    def __init__(self, zone, rdclass=dns.rdataclass.IN, keyring=None,
-                 keyname=None, keyalgorithm=dns.tsig.default_algorithm):
-        """Initialize a new DNS Update object.
-
-        @param zone: The zone which is being updated.
-        @type zone: A dns.name.Name or string
-        @param rdclass: The class of the zone; defaults to dns.rdataclass.IN.
-        @type rdclass: An int designating the class, or a string whose value
-        is the name of a class.
-        @param keyring: The TSIG keyring to use; defaults to None.
-        @type keyring: dict
-        @param keyname: The name of the TSIG key to use; defaults to None.
-        The key must be defined in the keyring.  If a keyring is specified
-        but a keyname is not, then the key used will be the first key in the
-        keyring.  Note that the order of keys in a dictionary is not defined,
-        so applications should supply a keyname when a keyring is used, unless
-        they know the keyring contains only one key.
-        @type keyname: dns.name.Name or string
-        @param keyalgorithm: The TSIG algorithm to use; defaults to
-        dns.tsig.default_algorithm
-        @type keyalgorithm: string
-        """
-        super(Update, self).__init__()
-        self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE)
-        if isinstance(zone, (str, unicode)):
-            zone = dns.name.from_text(zone)
-        self.origin = zone
-        if isinstance(rdclass, str):
-            rdclass = dns.rdataclass.from_text(rdclass)
-        self.zone_rdclass = rdclass
-        self.find_rrset(self.question, self.origin, rdclass, dns.rdatatype.SOA,
-                        create=True, force_unique=True)
-        if not keyring is None:
-            self.use_tsig(keyring, keyname, keyalgorithm)
-
-    def _add_rr(self, name, ttl, rd, deleting=None, section=None):
-        """Add a single RR to the update section."""
-
-        if section is None:
-            section = self.authority
-        covers = rd.covers()
-        rrset = self.find_rrset(section, name, self.zone_rdclass, rd.rdtype,
-                                covers, deleting, True, True)
-        rrset.add(rd, ttl)
-
-    def _add(self, replace, section, name, *args):
-        """Add records.  The first argument is the replace mode.  If
-        false, RRs are added to an existing RRset; if true, the RRset
-        is replaced with the specified contents.  The second
-        argument is the section to add to.  The third argument
-        is always a name.  The other arguments can be:
-
-                - rdataset...
-
-                - ttl, rdata...
-
-                - ttl, rdtype, string..."""
-
-        if isinstance(name, (str, unicode)):
-            name = dns.name.from_text(name, None)
-        if isinstance(args[0], dns.rdataset.Rdataset):
-            for rds in args:
-                if replace:
-                    self.delete(name, rds.rdtype)
-                for rd in rds:
-                    self._add_rr(name, rds.ttl, rd, section=section)
-        else:
-            args = list(args)
-            ttl = int(args.pop(0))
-            if isinstance(args[0], dns.rdata.Rdata):
-                if replace:
-                    self.delete(name, args[0].rdtype)
-                for rd in args:
-                    self._add_rr(name, ttl, rd, section=section)
-            else:
-                rdtype = args.pop(0)
-                if isinstance(rdtype, str):
-                    rdtype = dns.rdatatype.from_text(rdtype)
-                if replace:
-                    self.delete(name, rdtype)
-                for s in args:
-                    rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s,
-                                             self.origin)
-                    self._add_rr(name, ttl, rd, section=section)
-
-    def add(self, name, *args):
-        """Add records.  The first argument is always a name.  The other
-        arguments can be:
-
-                - rdataset...
-
-                - ttl, rdata...
-
-                - ttl, rdtype, string..."""
-        self._add(False, self.authority, name, *args)
-
-    def delete(self, name, *args):
-        """Delete records.  The first argument is always a name.  The other
-        arguments can be:
-
-                - I{nothing}
-
-                - rdataset...
-
-                - rdata...
-
-                - rdtype, [string...]"""
-
-        if isinstance(name, (str, unicode)):
-            name = dns.name.from_text(name, None)
-        if len(args) == 0:
-            rrset = self.find_rrset(self.authority, name, dns.rdataclass.ANY,
-                                    dns.rdatatype.ANY, dns.rdatatype.NONE,
-                                    dns.rdatatype.ANY, True, True)
-        elif isinstance(args[0], dns.rdataset.Rdataset):
-            for rds in args:
-                for rd in rds:
-                    self._add_rr(name, 0, rd, dns.rdataclass.NONE)
-        else:
-            args = list(args)
-            if isinstance(args[0], dns.rdata.Rdata):
-                for rd in args:
-                    self._add_rr(name, 0, rd, dns.rdataclass.NONE)
-            else:
-                rdtype = args.pop(0)
-                if isinstance(rdtype, str):
-                    rdtype = dns.rdatatype.from_text(rdtype)
-                if len(args) == 0:
-                    rrset = self.find_rrset(self.authority, name,
-                                            self.zone_rdclass, rdtype,
-                                            dns.rdatatype.NONE,
-                                            dns.rdataclass.ANY,
-                                            True, True)
-                else:
-                    for s in args:
-                        rd = dns.rdata.from_text(self.zone_rdclass, rdtype, s,
-                                                 self.origin)
-                        self._add_rr(name, 0, rd, dns.rdataclass.NONE)
-
-    def replace(self, name, *args):
-        """Replace records.  The first argument is always a name.  The other
-        arguments can be:
-
-                - rdataset...
-
-                - ttl, rdata...
-
-                - ttl, rdtype, string...
-
-        Note that if you want to replace the entire node, you should do
-        a delete of the name followed by one or more calls to add."""
-
-        self._add(True, self.authority, name, *args)
-
-    def present(self, name, *args):
-        """Require that an owner name (and optionally an rdata type,
-        or specific rdataset) exists as a prerequisite to the
-        execution of the update.  The first argument is always a name.
-        The other arguments can be:
-
-                - rdataset...
-
-                - rdata...
-
-                - rdtype, string..."""
-
-        if isinstance(name, (str, unicode)):
-            name = dns.name.from_text(name, None)
-        if len(args) == 0:
-            rrset = self.find_rrset(self.answer, name,
-                                    dns.rdataclass.ANY, dns.rdatatype.ANY,
-                                    dns.rdatatype.NONE, None,
-                                    True, True)
-        elif isinstance(args[0], dns.rdataset.Rdataset) or \
-             isinstance(args[0], dns.rdata.Rdata) or \
-             len(args) > 1:
-            if not isinstance(args[0], dns.rdataset.Rdataset):
-                # Add a 0 TTL
-                args = list(args)
-                args.insert(0, 0)
-            self._add(False, self.answer, name, *args)
-        else:
-            rdtype = args[0]
-            if isinstance(rdtype, str):
-                rdtype = dns.rdatatype.from_text(rdtype)
-            rrset = self.find_rrset(self.answer, name,
-                                    dns.rdataclass.ANY, rdtype,
-                                    dns.rdatatype.NONE, None,
-                                    True, True)
-
-    def absent(self, name, rdtype=None):
-        """Require that an owner name (and optionally an rdata type) does
-        not exist as a prerequisite to the execution of the update."""
-
-        if isinstance(name, (str, unicode)):
-            name = dns.name.from_text(name, None)
-        if rdtype is None:
-            rrset = self.find_rrset(self.answer, name,
-                                    dns.rdataclass.NONE, dns.rdatatype.ANY,
-                                    dns.rdatatype.NONE, None,
-                                    True, True)
-        else:
-            if isinstance(rdtype, str):
-                rdtype = dns.rdatatype.from_text(rdtype)
-            rrset = self.find_rrset(self.answer, name,
-                                    dns.rdataclass.NONE, rdtype,
-                                    dns.rdatatype.NONE, None,
-                                    True, True)
-
-    def to_wire(self, origin=None, max_size=65535):
-        """Return a string containing the update in DNS compressed wire
-        format.
-        @rtype: string"""
-        if origin is None:
-            origin = self.origin
-        return super(Update, self).to_wire(origin, max_size)
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/version.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/version.py
deleted file mode 100644
index 7a36775..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/version.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""dnspython release version information."""
-
-MAJOR = 1
-MINOR = 8
-MICRO = 0
-RELEASELEVEL = 0x0f
-SERIAL = 0
-
-if RELEASELEVEL == 0x0f:
-    version = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
-elif RELEASELEVEL == 0x00:
-    version = '%d.%d.%dx%d' % \
-              (MAJOR, MINOR, MICRO, SERIAL)
-else:
-    version = '%d.%d.%d%x%d' % \
-              (MAJOR, MINOR, MICRO, RELEASELEVEL, SERIAL)
-
-hexversion = MAJOR << 24 | MINOR << 16 | MICRO << 8 | RELEASELEVEL << 4 | \
-             SERIAL
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/dns/zone.py b/catapult/telemetry/third_party/web-page-replay/third_party/dns/zone.py
deleted file mode 100644
index 93c157d..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/dns/zone.py
+++ /dev/null
@@ -1,855 +0,0 @@
-# Copyright (C) 2003-2007, 2009, 2010 Nominum, Inc.
-#
-# Permission to use, copy, modify, and distribute this software and its
-# documentation for any purpose with or without fee is hereby granted,
-# provided that the above copyright notice and this permission notice
-# appear in all copies.
-#
-# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
-# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
-# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
-# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
-# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
-# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
-# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
-"""DNS Zones."""
-
-from __future__ import generators
-
-import sys
-
-import dns.exception
-import dns.name
-import dns.node
-import dns.rdataclass
-import dns.rdatatype
-import dns.rdata
-import dns.rrset
-import dns.tokenizer
-import dns.ttl
-
-class BadZone(dns.exception.DNSException):
-    """The zone is malformed."""
-    pass
-
-class NoSOA(BadZone):
-    """The zone has no SOA RR at its origin."""
-    pass
-
-class NoNS(BadZone):
-    """The zone has no NS RRset at its origin."""
-    pass
-
-class UnknownOrigin(BadZone):
-    """The zone's origin is unknown."""
-    pass
-
-class Zone(object):
-    """A DNS zone.
-
-    A Zone is a mapping from names to nodes.  The zone object may be
-    treated like a Python dictionary, e.g. zone[name] will retrieve
-    the node associated with that name.  The I{name} may be a
-    dns.name.Name object, or it may be a string.  In the either case,
-    if the name is relative it is treated as relative to the origin of
-    the zone.
-
-    @ivar rdclass: The zone's rdata class; the default is class IN.
-    @type rdclass: int
-    @ivar origin: The origin of the zone.
-    @type origin: dns.name.Name object
-    @ivar nodes: A dictionary mapping the names of nodes in the zone to the
-    nodes themselves.
-    @type nodes: dict
-    @ivar relativize: should names in the zone be relativized?
-    @type relativize: bool
-    @cvar node_factory: the factory used to create a new node
-    @type node_factory: class or callable
-    """
-
-    node_factory = dns.node.Node
-
-    __slots__ = ['rdclass', 'origin', 'nodes', 'relativize']
-
-    def __init__(self, origin, rdclass=dns.rdataclass.IN, relativize=True):
-        """Initialize a zone object.
-
-        @param origin: The origin of the zone.
-        @type origin: dns.name.Name object
-        @param rdclass: The zone's rdata class; the default is class IN.
-        @type rdclass: int"""
-
-        self.rdclass = rdclass
-        self.origin = origin
-        self.nodes = {}
-        self.relativize = relativize
-
-    def __eq__(self, other):
-        """Two zones are equal if they have the same origin, class, and
-        nodes.
-        @rtype: bool
-        """
-
-        if not isinstance(other, Zone):
-            return False
-        if self.rdclass != other.rdclass or \
-           self.origin != other.origin or \
-           self.nodes != other.nodes:
-            return False
-        return True
-
-    def __ne__(self, other):
-        """Are two zones not equal?
-        @rtype: bool
-        """
-
-        return not self.__eq__(other)
-
-    def _validate_name(self, name):
-        if isinstance(name, (str, unicode)):
-            name = dns.name.from_text(name, None)
-        elif not isinstance(name, dns.name.Name):
-            raise KeyError("name parameter must be convertable to a DNS name")
-        if name.is_absolute():
-            if not name.is_subdomain(self.origin):
-                raise KeyError("name parameter must be a subdomain of the zone origin")
-            if self.relativize:
-                name = name.relativize(self.origin)
-        return name
-
-    def __getitem__(self, key):
-        key = self._validate_name(key)
-        return self.nodes[key]
-
-    def __setitem__(self, key, value):
-        key = self._validate_name(key)
-        self.nodes[key] = value
-
-    def __delitem__(self, key):
-        key = self._validate_name(key)
-        del self.nodes[key]
-
-    def __iter__(self):
-        return self.nodes.iterkeys()
-
-    def iterkeys(self):
-        return self.nodes.iterkeys()
-
-    def keys(self):
-        return self.nodes.keys()
-
-    def itervalues(self):
-        return self.nodes.itervalues()
-
-    def values(self):
-        return self.nodes.values()
-
-    def iteritems(self):
-        return self.nodes.iteritems()
-
-    def items(self):
-        return self.nodes.items()
-
-    def get(self, key):
-        key = self._validate_name(key)
-        return self.nodes.get(key)
-
-    def __contains__(self, other):
-        return other in self.nodes
-
-    def find_node(self, name, create=False):
-        """Find a node in the zone, possibly creating it.
-
-        @param name: the name of the node to find
-        @type name: dns.name.Name object or string
-        @param create: should the node be created if it doesn't exist?
-        @type create: bool
-        @raises KeyError: the name is not known and create was not specified.
-        @rtype: dns.node.Node object
-        """
-
-        name = self._validate_name(name)
-        node = self.nodes.get(name)
-        if node is None:
-            if not create:
-                raise KeyError
-            node = self.node_factory()
-            self.nodes[name] = node
-        return node
-
-    def get_node(self, name, create=False):
-        """Get a node in the zone, possibly creating it.
-
-        This method is like L{find_node}, except it returns None instead
-        of raising an exception if the node does not exist and creation
-        has not been requested.
-
-        @param name: the name of the node to find
-        @type name: dns.name.Name object or string
-        @param create: should the node be created if it doesn't exist?
-        @type create: bool
-        @rtype: dns.node.Node object or None
-        """
-
-        try:
-            node = self.find_node(name, create)
-        except KeyError:
-            node = None
-        return node
-
-    def delete_node(self, name):
-        """Delete the specified node if it exists.
-
-        It is not an error if the node does not exist.
-        """
-
-        name = self._validate_name(name)
-        if self.nodes.has_key(name):
-            del self.nodes[name]
-
-    def find_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE,
-                      create=False):
-        """Look for rdata with the specified name and type in the zone,
-        and return an rdataset encapsulating it.
-
-        The I{name}, I{rdtype}, and I{covers} parameters may be
-        strings, in which case they will be converted to their proper
-        type.
-
-        The rdataset returned is not a copy; changes to it will change
-        the zone.
-
-        KeyError is raised if the name or type are not found.
-        Use L{get_rdataset} if you want to have None returned instead.
-
-        @param name: the owner name to look for
-        @type name: DNS.name.Name object or string
-        @param rdtype: the rdata type desired
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        @param create: should the node and rdataset be created if they do not
-        exist?
-        @type create: bool
-        @raises KeyError: the node or rdata could not be found
-        @rtype: dns.rrset.RRset object
-        """
-
-        name = self._validate_name(name)
-        if isinstance(rdtype, str):
-            rdtype = dns.rdatatype.from_text(rdtype)
-        if isinstance(covers, str):
-            covers = dns.rdatatype.from_text(covers)
-        node = self.find_node(name, create)
-        return node.find_rdataset(self.rdclass, rdtype, covers, create)
-
-    def get_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE,
-                     create=False):
-        """Look for rdata with the specified name and type in the zone,
-        and return an rdataset encapsulating it.
-
-        The I{name}, I{rdtype}, and I{covers} parameters may be
-        strings, in which case they will be converted to their proper
-        type.
-
-        The rdataset returned is not a copy; changes to it will change
-        the zone.
-
-        None is returned if the name or type are not found.
-        Use L{find_rdataset} if you want to have KeyError raised instead.
-
-        @param name: the owner name to look for
-        @type name: DNS.name.Name object or string
-        @param rdtype: the rdata type desired
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        @param create: should the node and rdataset be created if they do not
-        exist?
-        @type create: bool
-        @rtype: dns.rrset.RRset object
-        """
-
-        try:
-            rdataset = self.find_rdataset(name, rdtype, covers, create)
-        except KeyError:
-            rdataset = None
-        return rdataset
-
-    def delete_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE):
-        """Delete the rdataset matching I{rdtype} and I{covers}, if it
-        exists at the node specified by I{name}.
-
-        The I{name}, I{rdtype}, and I{covers} parameters may be
-        strings, in which case they will be converted to their proper
-        type.
-
-        It is not an error if the node does not exist, or if there is no
-        matching rdataset at the node.
-
-        If the node has no rdatasets after the deletion, it will itself
-        be deleted.
-
-        @param name: the owner name to look for
-        @type name: DNS.name.Name object or string
-        @param rdtype: the rdata type desired
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        """
-
-        name = self._validate_name(name)
-        if isinstance(rdtype, str):
-            rdtype = dns.rdatatype.from_text(rdtype)
-        if isinstance(covers, str):
-            covers = dns.rdatatype.from_text(covers)
-        node = self.get_node(name)
-        if not node is None:
-            node.delete_rdataset(self.rdclass, rdtype, covers)
-            if len(node) == 0:
-                self.delete_node(name)
-
-    def replace_rdataset(self, name, replacement):
-        """Replace an rdataset at name.
-
-        It is not an error if there is no rdataset matching I{replacement}.
-
-        Ownership of the I{replacement} object is transferred to the zone;
-        in other words, this method does not store a copy of I{replacement}
-        at the node, it stores I{replacement} itself.
-
-        If the I{name} node does not exist, it is created.
-
-        @param name: the owner name
-        @type name: DNS.name.Name object or string
-        @param replacement: the replacement rdataset
-        @type replacement: dns.rdataset.Rdataset
-        """
-
-        if replacement.rdclass != self.rdclass:
-            raise ValueError('replacement.rdclass != zone.rdclass')
-        node = self.find_node(name, True)
-        node.replace_rdataset(replacement)
-
-    def find_rrset(self, name, rdtype, covers=dns.rdatatype.NONE):
-        """Look for rdata with the specified name and type in the zone,
-        and return an RRset encapsulating it.
-
-        The I{name}, I{rdtype}, and I{covers} parameters may be
-        strings, in which case they will be converted to their proper
-        type.
-
-        This method is less efficient than the similar
-        L{find_rdataset} because it creates an RRset instead of
-        returning the matching rdataset.  It may be more convenient
-        for some uses since it returns an object which binds the owner
-        name to the rdata.
-
-        This method may not be used to create new nodes or rdatasets;
-        use L{find_rdataset} instead.
-
-        KeyError is raised if the name or type are not found.
-        Use L{get_rrset} if you want to have None returned instead.
-
-        @param name: the owner name to look for
-        @type name: DNS.name.Name object or string
-        @param rdtype: the rdata type desired
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        @raises KeyError: the node or rdata could not be found
-        @rtype: dns.rrset.RRset object
-        """
-
-        name = self._validate_name(name)
-        if isinstance(rdtype, str):
-            rdtype = dns.rdatatype.from_text(rdtype)
-        if isinstance(covers, str):
-            covers = dns.rdatatype.from_text(covers)
-        rdataset = self.nodes[name].find_rdataset(self.rdclass, rdtype, covers)
-        rrset = dns.rrset.RRset(name, self.rdclass, rdtype, covers)
-        rrset.update(rdataset)
-        return rrset
-
-    def get_rrset(self, name, rdtype, covers=dns.rdatatype.NONE):
-        """Look for rdata with the specified name and type in the zone,
-        and return an RRset encapsulating it.
-
-        The I{name}, I{rdtype}, and I{covers} parameters may be
-        strings, in which case they will be converted to their proper
-        type.
-
-        This method is less efficient than the similar L{get_rdataset}
-        because it creates an RRset instead of returning the matching
-        rdataset.  It may be more convenient for some uses since it
-        returns an object which binds the owner name to the rdata.
-
-        This method may not be used to create new nodes or rdatasets;
-        use L{find_rdataset} instead.
-
-        None is returned if the name or type are not found.
-        Use L{find_rrset} if you want to have KeyError raised instead.
-
-        @param name: the owner name to look for
-        @type name: DNS.name.Name object or string
-        @param rdtype: the rdata type desired
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        @rtype: dns.rrset.RRset object
-        """
-
-        try:
-            rrset = self.find_rrset(name, rdtype, covers)
-        except KeyError:
-            rrset = None
-        return rrset
-
-    def iterate_rdatasets(self, rdtype=dns.rdatatype.ANY,
-                          covers=dns.rdatatype.NONE):
-        """Return a generator which yields (name, rdataset) tuples for
-        all rdatasets in the zone which have the specified I{rdtype}
-        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
-        then all rdatasets will be matched.
-
-        @param rdtype: int or string
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        """
-
-        if isinstance(rdtype, str):
-            rdtype = dns.rdatatype.from_text(rdtype)
-        if isinstance(covers, str):
-            covers = dns.rdatatype.from_text(covers)
-        for (name, node) in self.iteritems():
-            for rds in node:
-                if rdtype == dns.rdatatype.ANY or \
-                   (rds.rdtype == rdtype and rds.covers == covers):
-                    yield (name, rds)
-
-    def iterate_rdatas(self, rdtype=dns.rdatatype.ANY,
-                       covers=dns.rdatatype.NONE):
-        """Return a generator which yields (name, ttl, rdata) tuples for
-        all rdatas in the zone which have the specified I{rdtype}
-        and I{covers}.  If I{rdtype} is dns.rdatatype.ANY, the default,
-        then all rdatas will be matched.
-
-        @param rdtype: int or string
-        @type rdtype: int or string
-        @param covers: the covered type (defaults to None)
-        @type covers: int or string
-        """
-
-        if isinstance(rdtype, str):
-            rdtype = dns.rdatatype.from_text(rdtype)
-        if isinstance(covers, str):
-            covers = dns.rdatatype.from_text(covers)
-        for (name, node) in self.iteritems():
-            for rds in node:
-                if rdtype == dns.rdatatype.ANY or \
-                   (rds.rdtype == rdtype and rds.covers == covers):
-                    for rdata in rds:
-                        yield (name, rds.ttl, rdata)
-
-    def to_file(self, f, sorted=True, relativize=True, nl=None):
-        """Write a zone to a file.
-
-        @param f: file or string.  If I{f} is a string, it is treated
-        as the name of a file to open.
-        @param sorted: if True, the file will be written with the
-        names sorted in DNSSEC order from least to greatest.  Otherwise
-        the names will be written in whatever order they happen to have
-        in the zone's dictionary.
-        @param relativize: if True, domain names in the output will be
-        relativized to the zone's origin (if possible).
-        @type relativize: bool
-        @param nl: The end of line string.  If not specified, the
-        output will use the platform's native end-of-line marker (i.e.
-        LF on POSIX, CRLF on Windows, CR on Macintosh).
-        @type nl: string or None
-        """
-
-        if sys.hexversion >= 0x02030000:
-            # allow Unicode filenames
-            str_type = basestring
-        else:
-            str_type = str
-        if nl is None:
-            opts = 'w'
-        else:
-            opts = 'wb'
-        if isinstance(f, str_type):
-            f = file(f, opts)
-            want_close = True
-        else:
-            want_close = False
-        try:
-            if sorted:
-                names = self.keys()
-                names.sort()
-            else:
-                names = self.iterkeys()
-            for n in names:
-                l = self[n].to_text(n, origin=self.origin,
-                                    relativize=relativize)
-                if nl is None:
-                    print >> f, l
-                else:
-                    f.write(l)
-                    f.write(nl)
-        finally:
-            if want_close:
-                f.close()
-
-    def check_origin(self):
-        """Do some simple checking of the zone's origin.
-
-        @raises dns.zone.NoSOA: there is no SOA RR
-        @raises dns.zone.NoNS: there is no NS RRset
-        @raises KeyError: there is no origin node
-        """
-        if self.relativize:
-            name = dns.name.empty
-        else:
-            name = self.origin
-        if self.get_rdataset(name, dns.rdatatype.SOA) is None:
-            raise NoSOA
-        if self.get_rdataset(name, dns.rdatatype.NS) is None:
-            raise NoNS
-
-
-class _MasterReader(object):
-    """Read a DNS master file
-
-    @ivar tok: The tokenizer
-    @type tok: dns.tokenizer.Tokenizer object
-    @ivar ttl: The default TTL
-    @type ttl: int
-    @ivar last_name: The last name read
-    @type last_name: dns.name.Name object
-    @ivar current_origin: The current origin
-    @type current_origin: dns.name.Name object
-    @ivar relativize: should names in the zone be relativized?
-    @type relativize: bool
-    @ivar zone: the zone
-    @type zone: dns.zone.Zone object
-    @ivar saved_state: saved reader state (used when processing $INCLUDE)
-    @type saved_state: list of (tokenizer, current_origin, last_name, file)
-    tuples.
-    @ivar current_file: the file object of the $INCLUDed file being parsed
-    (None if no $INCLUDE is active).
-    @ivar allow_include: is $INCLUDE allowed?
-    @type allow_include: bool
-    @ivar check_origin: should sanity checks of the origin node be done?
-    The default is True.
-    @type check_origin: bool
-    """
-
-    def __init__(self, tok, origin, rdclass, relativize, zone_factory=Zone,
-                 allow_include=False, check_origin=True):
-        if isinstance(origin, (str, unicode)):
-            origin = dns.name.from_text(origin)
-        self.tok = tok
-        self.current_origin = origin
-        self.relativize = relativize
-        self.ttl = 0
-        self.last_name = None
-        self.zone = zone_factory(origin, rdclass, relativize=relativize)
-        self.saved_state = []
-        self.current_file = None
-        self.allow_include = allow_include
-        self.check_origin = check_origin
-
-    def _eat_line(self):
-        while 1:
-            token = self.tok.get()
-            if token.is_eol_or_eof():
-                break
-
-    def _rr_line(self):
-        """Process one line from a DNS master file."""
-        # Name
-        if self.current_origin is None:
-            raise UnknownOrigin
-        token = self.tok.get(want_leading = True)
-        if not token.is_whitespace():
-            self.last_name = dns.name.from_text(token.value, self.current_origin)
-        else:
-            token = self.tok.get()
-            if token.is_eol_or_eof():
-                # treat leading WS followed by EOL/EOF as if they were EOL/EOF.
-                return
-            self.tok.unget(token)
-        name = self.last_name
-        if not name.is_subdomain(self.zone.origin):
-            self._eat_line()
-            return
-        if self.relativize:
-            name = name.relativize(self.zone.origin)
-        token = self.tok.get()
-        if not token.is_identifier():
-            raise dns.exception.SyntaxError
-        # TTL
-        try:
-            ttl = dns.ttl.from_text(token.value)
-            token = self.tok.get()
-            if not token.is_identifier():
-                raise dns.exception.SyntaxError
-        except dns.ttl.BadTTL:
-            ttl = self.ttl
-        # Class
-        try:
-            rdclass = dns.rdataclass.from_text(token.value)
-            token = self.tok.get()
-            if not token.is_identifier():
-                raise dns.exception.SyntaxError
-        except dns.exception.SyntaxError:
-            raise dns.exception.SyntaxError
-        except:
-            rdclass = self.zone.rdclass
-        if rdclass != self.zone.rdclass:
-            raise dns.exception.SyntaxError("RR class is not zone's class")
-        # Type
-        try:
-            rdtype = dns.rdatatype.from_text(token.value)
-        except:
-            raise dns.exception.SyntaxError("unknown rdatatype '%s'" % token.value)
-        n = self.zone.nodes.get(name)
-        if n is None:
-            n = self.zone.node_factory()
-            self.zone.nodes[name] = n
-        try:
-            rd = dns.rdata.from_text(rdclass, rdtype, self.tok,
-                                     self.current_origin, False)
-        except dns.exception.SyntaxError:
-            # Catch and reraise.
-            (ty, va) = sys.exc_info()[:2]
-            raise va
-        except:
-            # All exceptions that occur in the processing of rdata
-            # are treated as syntax errors.  This is not strictly
-            # correct, but it is correct almost all of the time.
-            # We convert them to syntax errors so that we can emit
-            # helpful filename:line info.
-            (ty, va) = sys.exc_info()[:2]
-            raise dns.exception.SyntaxError("caught exception %s: %s" % (str(ty), str(va)))
-
-        rd.choose_relativity(self.zone.origin, self.relativize)
-        covers = rd.covers()
-        rds = n.find_rdataset(rdclass, rdtype, covers, True)
-        rds.add(rd, ttl)
-
-    def read(self):
-        """Read a DNS master file and build a zone object.
-
-        @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
-        @raises dns.zone.NoNS: No NS RRset was found at the zone origin
-        """
-
-        try:
-            while 1:
-                token = self.tok.get(True, True).unescape()
-                if token.is_eof():
-                    if not self.current_file is None:
-                        self.current_file.close()
-                    if len(self.saved_state) > 0:
-                        (self.tok,
-                         self.current_origin,
-                         self.last_name,
-                         self.current_file,
-                         self.ttl) = self.saved_state.pop(-1)
-                        continue
-                    break
-                elif token.is_eol():
-                    continue
-                elif token.is_comment():
-                    self.tok.get_eol()
-                    continue
-                elif token.value[0] == '$':
-                    u = token.value.upper()
-                    if u == '$TTL':
-                        token = self.tok.get()
-                        if not token.is_identifier():
-                            raise dns.exception.SyntaxError("bad $TTL")
-                        self.ttl = dns.ttl.from_text(token.value)
-                        self.tok.get_eol()
-                    elif u == '$ORIGIN':
-                        self.current_origin = self.tok.get_name()
-                        self.tok.get_eol()
-                        if self.zone.origin is None:
-                            self.zone.origin = self.current_origin
-                    elif u == '$INCLUDE' and self.allow_include:
-                        token = self.tok.get()
-                        if not token.is_quoted_string():
-                            raise dns.exception.SyntaxError("bad filename in $INCLUDE")
-                        filename = token.value
-                        token = self.tok.get()
-                        if token.is_identifier():
-                            new_origin = dns.name.from_text(token.value, \
-                                                            self.current_origin)
-                            self.tok.get_eol()
-                        elif not token.is_eol_or_eof():
-                            raise dns.exception.SyntaxError("bad origin in $INCLUDE")
-                        else:
-                            new_origin = self.current_origin
-                        self.saved_state.append((self.tok,
-                                                 self.current_origin,
-                                                 self.last_name,
-                                                 self.current_file,
-                                                 self.ttl))
-                        self.current_file = file(filename, 'r')
-                        self.tok = dns.tokenizer.Tokenizer(self.current_file,
-                                                           filename)
-                        self.current_origin = new_origin
-                    else:
-                        raise dns.exception.SyntaxError("Unknown master file directive '" + u + "'")
-                    continue
-                self.tok.unget(token)
-                self._rr_line()
-        except dns.exception.SyntaxError, detail:
-            (filename, line_number) = self.tok.where()
-            if detail is None:
-                detail = "syntax error"
-            raise dns.exception.SyntaxError("%s:%d: %s" % (filename, line_number, detail))
-
-        # Now that we're done reading, do some basic checking of the zone.
-        if self.check_origin:
-            self.zone.check_origin()
-
-def from_text(text, origin = None, rdclass = dns.rdataclass.IN,
-              relativize = True, zone_factory=Zone, filename=None,
-              allow_include=False, check_origin=True):
-    """Build a zone object from a master file format string.
-
-    @param text: the master file format input
-    @type text: string.
-    @param origin: The origin of the zone; if not specified, the first
-    $ORIGIN statement in the master file will determine the origin of the
-    zone.
-    @type origin: dns.name.Name object or string
-    @param rdclass: The zone's rdata class; the default is class IN.
-    @type rdclass: int
-    @param relativize: should names be relativized?  The default is True
-    @type relativize: bool
-    @param zone_factory: The zone factory to use
-    @type zone_factory: function returning a Zone
-    @param filename: The filename to emit when describing where an error
-    occurred; the default is '<string>'.
-    @type filename: string
-    @param allow_include: is $INCLUDE allowed?
-    @type allow_include: bool
-    @param check_origin: should sanity checks of the origin node be done?
-    The default is True.
-    @type check_origin: bool
-    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
-    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
-    @rtype: dns.zone.Zone object
-    """
-
-    # 'text' can also be a file, but we don't publish that fact
-    # since it's an implementation detail.  The official file
-    # interface is from_file().
-
-    if filename is None:
-        filename = '<string>'
-    tok = dns.tokenizer.Tokenizer(text, filename)
-    reader = _MasterReader(tok, origin, rdclass, relativize, zone_factory,
-                           allow_include=allow_include,
-                           check_origin=check_origin)
-    reader.read()
-    return reader.zone
-
-def from_file(f, origin = None, rdclass = dns.rdataclass.IN,
-              relativize = True, zone_factory=Zone, filename=None,
-              allow_include=True, check_origin=True):
-    """Read a master file and build a zone object.
-
-    @param f: file or string.  If I{f} is a string, it is treated
-    as the name of a file to open.
-    @param origin: The origin of the zone; if not specified, the first
-    $ORIGIN statement in the master file will determine the origin of the
-    zone.
-    @type origin: dns.name.Name object or string
-    @param rdclass: The zone's rdata class; the default is class IN.
-    @type rdclass: int
-    @param relativize: should names be relativized?  The default is True
-    @type relativize: bool
-    @param zone_factory: The zone factory to use
-    @type zone_factory: function returning a Zone
-    @param filename: The filename to emit when describing where an error
-    occurred; the default is '<file>', or the value of I{f} if I{f} is a
-    string.
-    @type filename: string
-    @param allow_include: is $INCLUDE allowed?
-    @type allow_include: bool
-    @param check_origin: should sanity checks of the origin node be done?
-    The default is True.
-    @type check_origin: bool
-    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
-    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
-    @rtype: dns.zone.Zone object
-    """
-
-    if sys.hexversion >= 0x02030000:
-        # allow Unicode filenames; turn on universal newline support
-        str_type = basestring
-        opts = 'rU'
-    else:
-        str_type = str
-        opts = 'r'
-    if isinstance(f, str_type):
-        if filename is None:
-            filename = f
-        f = file(f, opts)
-        want_close = True
-    else:
-        if filename is None:
-            filename = '<file>'
-        want_close = False
-
-    try:
-        z = from_text(f, origin, rdclass, relativize, zone_factory,
-                      filename, allow_include, check_origin)
-    finally:
-        if want_close:
-            f.close()
-    return z
-
-def from_xfr(xfr, zone_factory=Zone, relativize=True):
-    """Convert the output of a zone transfer generator into a zone object.
-
-    @param xfr: The xfr generator
-    @type xfr: generator of dns.message.Message objects
-    @param relativize: should names be relativized?  The default is True.
-    It is essential that the relativize setting matches the one specified
-    to dns.query.xfr().
-    @type relativize: bool
-    @raises dns.zone.NoSOA: No SOA RR was found at the zone origin
-    @raises dns.zone.NoNS: No NS RRset was found at the zone origin
-    @rtype: dns.zone.Zone object
-    """
-
-    z = None
-    for r in xfr:
-        if z is None:
-            if relativize:
-                origin = r.origin
-            else:
-                origin = r.answer[0].name
-            rdclass = r.answer[0].rdclass
-            z = zone_factory(origin, rdclass, relativize=relativize)
-        for rrset in r.answer:
-            znode = z.nodes.get(rrset.name)
-            if not znode:
-                znode = z.node_factory()
-                z.nodes[rrset.name] = znode
-            zrds = znode.find_rdataset(rrset.rdclass, rrset.rdtype,
-                                       rrset.covers, True)
-            zrds.update_ttl(rrset.ttl)
-            for rd in rrset:
-                rd.choose_relativity(z.origin, relativize)
-                zrds.add(rd)
-    z.check_origin()
-    return z
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/COPYING b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/COPYING
deleted file mode 100644
index d645695..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/COPYING
+++ /dev/null
@@ -1,202 +0,0 @@
-
-                                 Apache License
-                           Version 2.0, January 2004
-                        http://www.apache.org/licenses/
-
-   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-   1. Definitions.
-
-      "License" shall mean the terms and conditions for use, reproduction,
-      and distribution as defined by Sections 1 through 9 of this document.
-
-      "Licensor" shall mean the copyright owner or entity authorized by
-      the copyright owner that is granting the License.
-
-      "Legal Entity" shall mean the union of the acting entity and all
-      other entities that control, are controlled by, or are under common
-      control with that entity. For the purposes of this definition,
-      "control" means (i) the power, direct or indirect, to cause the
-      direction or management of such entity, whether by contract or
-      otherwise, or (ii) ownership of fifty percent (50%) or more of the
-      outstanding shares, or (iii) beneficial ownership of such entity.
-
-      "You" (or "Your") shall mean an individual or Legal Entity
-      exercising permissions granted by this License.
-
-      "Source" form shall mean the preferred form for making modifications,
-      including but not limited to software source code, documentation
-      source, and configuration files.
-
-      "Object" form shall mean any form resulting from mechanical
-      transformation or translation of a Source form, including but
-      not limited to compiled object code, generated documentation,
-      and conversions to other media types.
-
-      "Work" shall mean the work of authorship, whether in Source or
-      Object form, made available under the License, as indicated by a
-      copyright notice that is included in or attached to the work
-      (an example is provided in the Appendix below).
-
-      "Derivative Works" shall mean any work, whether in Source or Object
-      form, that is based on (or derived from) the Work and for which the
-      editorial revisions, annotations, elaborations, or other modifications
-      represent, as a whole, an original work of authorship. For the purposes
-      of this License, Derivative Works shall not include works that remain
-      separable from, or merely link (or bind by name) to the interfaces of,
-      the Work and Derivative Works thereof.
-
-      "Contribution" shall mean any work of authorship, including
-      the original version of the Work and any modifications or additions
-      to that Work or Derivative Works thereof, that is intentionally
-      submitted to Licensor for inclusion in the Work by the copyright owner
-      or by an individual or Legal Entity authorized to submit on behalf of
-      the copyright owner. For the purposes of this definition, "submitted"
-      means any form of electronic, verbal, or written communication sent
-      to the Licensor or its representatives, including but not limited to
-      communication on electronic mailing lists, source code control systems,
-      and issue tracking systems that are managed by, or on behalf of, the
-      Licensor for the purpose of discussing and improving the Work, but
-      excluding communication that is conspicuously marked or otherwise
-      designated in writing by the copyright owner as "Not a Contribution."
-
-      "Contributor" shall mean Licensor and any individual or Legal Entity
-      on behalf of whom a Contribution has been received by Licensor and
-      subsequently incorporated within the Work.
-
-   2. Grant of Copyright License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      copyright license to reproduce, prepare Derivative Works of,
-      publicly display, publicly perform, sublicense, and distribute the
-      Work and such Derivative Works in Source or Object form.
-
-   3. Grant of Patent License. Subject to the terms and conditions of
-      this License, each Contributor hereby grants to You a perpetual,
-      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
-      (except as stated in this section) patent license to make, have made,
-      use, offer to sell, sell, import, and otherwise transfer the Work,
-      where such license applies only to those patent claims licensable
-      by such Contributor that are necessarily infringed by their
-      Contribution(s) alone or by combination of their Contribution(s)
-      with the Work to which such Contribution(s) was submitted. If You
-      institute patent litigation against any entity (including a
-      cross-claim or counterclaim in a lawsuit) alleging that the Work
-      or a Contribution incorporated within the Work constitutes direct
-      or contributory patent infringement, then any patent licenses
-      granted to You under this License for that Work shall terminate
-      as of the date such litigation is filed.
-
-   4. Redistribution. You may reproduce and distribute copies of the
-      Work or Derivative Works thereof in any medium, with or without
-      modifications, and in Source or Object form, provided that You
-      meet the following conditions:
-
-      (a) You must give any other recipients of the Work or
-          Derivative Works a copy of this License; and
-
-      (b) You must cause any modified files to carry prominent notices
-          stating that You changed the files; and
-
-      (c) You must retain, in the Source form of any Derivative Works
-          that You distribute, all copyright, patent, trademark, and
-          attribution notices from the Source form of the Work,
-          excluding those notices that do not pertain to any part of
-          the Derivative Works; and
-
-      (d) If the Work includes a "NOTICE" text file as part of its
-          distribution, then any Derivative Works that You distribute must
-          include a readable copy of the attribution notices contained
-          within such NOTICE file, excluding those notices that do not
-          pertain to any part of the Derivative Works, in at least one
-          of the following places: within a NOTICE text file distributed
-          as part of the Derivative Works; within the Source form or
-          documentation, if provided along with the Derivative Works; or,
-          within a display generated by the Derivative Works, if and
-          wherever such third-party notices normally appear. The contents
-          of the NOTICE file are for informational purposes only and
-          do not modify the License. You may add Your own attribution
-          notices within Derivative Works that You distribute, alongside
-          or as an addendum to the NOTICE text from the Work, provided
-          that such additional attribution notices cannot be construed
-          as modifying the License.
-
-      You may add Your own copyright statement to Your modifications and
-      may provide additional or different license terms and conditions
-      for use, reproduction, or distribution of Your modifications, or
-      for any such Derivative Works as a whole, provided Your use,
-      reproduction, and distribution of the Work otherwise complies with
-      the conditions stated in this License.
-
-   5. Submission of Contributions. Unless You explicitly state otherwise,
-      any Contribution intentionally submitted for inclusion in the Work
-      by You to the Licensor shall be under the terms and conditions of
-      this License, without any additional terms or conditions.
-      Notwithstanding the above, nothing herein shall supersede or modify
-      the terms of any separate license agreement you may have executed
-      with Licensor regarding such Contributions.
-
-   6. Trademarks. This License does not grant permission to use the trade
-      names, trademarks, service marks, or product names of the Licensor,
-      except as required for reasonable and customary use in describing the
-      origin of the Work and reproducing the content of the NOTICE file.
-
-   7. Disclaimer of Warranty. Unless required by applicable law or
-      agreed to in writing, Licensor provides the Work (and each
-      Contributor provides its Contributions) on an "AS IS" BASIS,
-      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-      implied, including, without limitation, any warranties or conditions
-      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
-      PARTICULAR PURPOSE. You are solely responsible for determining the
-      appropriateness of using or redistributing the Work and assume any
-      risks associated with Your exercise of permissions under this License.
-
-   8. Limitation of Liability. In no event and under no legal theory,
-      whether in tort (including negligence), contract, or otherwise,
-      unless required by applicable law (such as deliberate and grossly
-      negligent acts) or agreed to in writing, shall any Contributor be
-      liable to You for damages, including any direct, indirect, special,
-      incidental, or consequential damages of any character arising as a
-      result of this License or out of the use or inability to use the
-      Work (including but not limited to damages for loss of goodwill,
-      work stoppage, computer failure or malfunction, or any and all
-      other commercial damages or losses), even if such Contributor
-      has been advised of the possibility of such damages.
-
-   9. Accepting Warranty or Additional Liability. While redistributing
-      the Work or Derivative Works thereof, You may choose to offer,
-      and charge a fee for, acceptance of support, warranty, indemnity,
-      or other liability obligations and/or rights consistent with this
-      License. However, in accepting such obligations, You may act only
-      on Your own behalf and on Your sole responsibility, not on behalf
-      of any other Contributor, and only if You agree to indemnify,
-      defend, and hold each Contributor harmless for any liability
-      incurred by, or claims asserted against, such Contributor by reason
-      of your accepting any such warranty or additional liability.
-
-   END OF TERMS AND CONDITIONS
-
-   APPENDIX: How to apply the Apache License to your work.
-
-      To apply the Apache License to your work, attach the following
-      boilerplate notice, with the fields enclosed by brackets "[]"
-      replaced with your own identifying information. (Don't include
-      the brackets!)  The text should be enclosed in the appropriate
-      comment syntax for the file format. We also recommend that a
-      file or class name and description of purpose be included on the
-      same "printed page" as the copyright notice for easier
-      identification within third-party archives.
-
-   Copyright [yyyy] [name of copyright owner]
-
-   Licensed under the Apache License, Version 2.0 (the "License");
-   you may not use this file except in compliance with the License.
-   You may obtain a copy of the License at
-
-       http://www.apache.org/licenses/LICENSE-2.0
-
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/MANIFEST.in b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/MANIFEST.in
deleted file mode 100644
index f572804..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/MANIFEST.in
+++ /dev/null
@@ -1,3 +0,0 @@
-include COPYING
-include ipaddr_test.py
-include RELEASENOTES
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/README b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/README
deleted file mode 100644
index 1b54294..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/README
+++ /dev/null
@@ -1,8 +0,0 @@
-ipaddr.py is a library for working with IP addresses, both IPv4 and IPv6.
-It was developed by Google for internal use, and is now open source.
-
-Project home page: http://code.google.com/p/ipaddr-py/
-
-Please send contributions to ipaddr-py-dev@googlegroups.com.  Code should
-include unit tests and follow the Google Python style guide:
-http://code.google.com/p/soc/wiki/PythonStyleGuide
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/README.web-page-replay b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/README.web-page-replay
deleted file mode 100644
index 4b42084..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/README.web-page-replay
+++ /dev/null
@@ -1,12 +0,0 @@
-Name: An IPv4/IPv6 manipulation library in Python.
-Short Name: ipaddr-py
-URL: https://code.google.com/p/ipaddr-py/
-Version: 2.1.10 (ipaddr.__version__)
-License: Apache (v2.0)
-License File: COPYING
-
-Description:
-Used by Web Page Replay to check if an IP address is private.
-
-Local Modifications:
-Cherry picked revision 728996d6b1d4 to add license boilerplate to test-2to3.sh.
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/ipaddr.py b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/ipaddr.py
deleted file mode 100644
index ad27ae9..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/ipaddr.py
+++ /dev/null
@@ -1,1897 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2007 Google Inc.
-#  Licensed to PSF under a Contributor Agreement.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-
-"""A fast, lightweight IPv4/IPv6 manipulation library in Python.
-
-This library is used to create/poke/manipulate IPv4 and IPv6 addresses
-and networks.
-
-"""
-
-__version__ = '2.1.10'
-
-import struct
-
-IPV4LENGTH = 32
-IPV6LENGTH = 128
-
-
-class AddressValueError(ValueError):
-    """A Value Error related to the address."""
-
-
-class NetmaskValueError(ValueError):
-    """A Value Error related to the netmask."""
-
-
-def IPAddress(address, version=None):
-    """Take an IP string/int and return an object of the correct type.
-
-    Args:
-        address: A string or integer, the IP address.  Either IPv4 or
-          IPv6 addresses may be supplied; integers less than 2**32 will
-          be considered to be IPv4 by default.
-        version: An Integer, 4 or 6. If set, don't try to automatically
-          determine what the IP address type is. important for things
-          like IPAddress(1), which could be IPv4, '0.0.0.1',  or IPv6,
-          '::1'.
-
-    Returns:
-        An IPv4Address or IPv6Address object.
-
-    Raises:
-        ValueError: if the string passed isn't either a v4 or a v6
-          address.
-
-    """
-    if version:
-        if version == 4:
-            return IPv4Address(address)
-        elif version == 6:
-            return IPv6Address(address)
-
-    try:
-        return IPv4Address(address)
-    except (AddressValueError, NetmaskValueError):
-        pass
-
-    try:
-        return IPv6Address(address)
-    except (AddressValueError, NetmaskValueError):
-        pass
-
-    raise ValueError('%r does not appear to be an IPv4 or IPv6 address' %
-                     address)
-
-
-def IPNetwork(address, version=None, strict=False):
-    """Take an IP string/int and return an object of the correct type.
-
-    Args:
-        address: A string or integer, the IP address.  Either IPv4 or
-          IPv6 addresses may be supplied; integers less than 2**32 will
-          be considered to be IPv4 by default.
-        version: An Integer, if set, don't try to automatically
-          determine what the IP address type is. important for things
-          like IPNetwork(1), which could be IPv4, '0.0.0.1/32', or IPv6,
-          '::1/128'.
-
-    Returns:
-        An IPv4Network or IPv6Network object.
-
-    Raises:
-        ValueError: if the string passed isn't either a v4 or a v6
-          address. Or if a strict network was requested and a strict
-          network wasn't given.
-
-    """
-    if version:
-        if version == 4:
-            return IPv4Network(address, strict)
-        elif version == 6:
-            return IPv6Network(address, strict)
-
-    try:
-        return IPv4Network(address, strict)
-    except (AddressValueError, NetmaskValueError):
-        pass
-
-    try:
-        return IPv6Network(address, strict)
-    except (AddressValueError, NetmaskValueError):
-        pass
-
-    raise ValueError('%r does not appear to be an IPv4 or IPv6 network' %
-                     address)
-
-
-def v4_int_to_packed(address):
-    """The binary representation of this address.
-
-    Args:
-        address: An integer representation of an IPv4 IP address.
-
-    Returns:
-        The binary representation of this address.
-
-    Raises:
-        ValueError: If the integer is too large to be an IPv4 IP
-          address.
-    """
-    if address > _BaseV4._ALL_ONES:
-        raise ValueError('Address too large for IPv4')
-    return Bytes(struct.pack('!I', address))
-
-
-def v6_int_to_packed(address):
-    """The binary representation of this address.
-
-    Args:
-        address: An integer representation of an IPv4 IP address.
-
-    Returns:
-        The binary representation of this address.
-    """
-    return Bytes(struct.pack('!QQ', address >> 64, address & (2**64 - 1)))
-
-
-def _find_address_range(addresses):
-    """Find a sequence of addresses.
-
-    Args:
-        addresses: a list of IPv4 or IPv6 addresses.
-
-    Returns:
-        A tuple containing the first and last IP addresses in the sequence.
-
-    """
-    first = last = addresses[0]
-    for ip in addresses[1:]:
-        if ip._ip == last._ip + 1:
-            last = ip
-        else:
-            break
-    return (first, last)
-
-def _get_prefix_length(number1, number2, bits):
-    """Get the number of leading bits that are same for two numbers.
-
-    Args:
-        number1: an integer.
-        number2: another integer.
-        bits: the maximum number of bits to compare.
-
-    Returns:
-        The number of leading bits that are the same for two numbers.
-
-    """
-    for i in range(bits):
-        if number1 >> i == number2 >> i:
-            return bits - i
-    return 0
-
-def _count_righthand_zero_bits(number, bits):
-    """Count the number of zero bits on the right hand side.
-
-    Args:
-        number: an integer.
-        bits: maximum number of bits to count.
-
-    Returns:
-        The number of zero bits on the right hand side of the number.
-
-    """
-    if number == 0:
-        return bits
-    for i in range(bits):
-        if (number >> i) % 2:
-            return i
-
-def summarize_address_range(first, last):
-    """Summarize a network range given the first and last IP addresses.
-
-    Example:
-        >>> summarize_address_range(IPv4Address('1.1.1.0'),
-            IPv4Address('1.1.1.130'))
-        [IPv4Network('1.1.1.0/25'), IPv4Network('1.1.1.128/31'),
-        IPv4Network('1.1.1.130/32')]
-
-    Args:
-        first: the first IPv4Address or IPv6Address in the range.
-        last: the last IPv4Address or IPv6Address in the range.
-
-    Returns:
-        The address range collapsed to a list of IPv4Network's or
-        IPv6Network's.
-
-    Raise:
-        TypeError:
-            If the first and last objects are not IP addresses.
-            If the first and last objects are not the same version.
-        ValueError:
-            If the last object is not greater than the first.
-            If the version is not 4 or 6.
-
-    """
-    if not (isinstance(first, _BaseIP) and isinstance(last, _BaseIP)):
-        raise TypeError('first and last must be IP addresses, not networks')
-    if first.version != last.version:
-        raise TypeError("%s and %s are not of the same version" % (
-                str(first), str(last)))
-    if first > last:
-        raise ValueError('last IP address must be greater than first')
-
-    networks = []
-
-    if first.version == 4:
-        ip = IPv4Network
-    elif first.version == 6:
-        ip = IPv6Network
-    else:
-        raise ValueError('unknown IP version')
-
-    ip_bits = first._max_prefixlen
-    first_int = first._ip
-    last_int = last._ip
-    while first_int <= last_int:
-        nbits = _count_righthand_zero_bits(first_int, ip_bits)
-        current = None
-        while nbits >= 0:
-            addend = 2**nbits - 1
-            current = first_int + addend
-            nbits -= 1
-            if current <= last_int:
-                break
-        prefix = _get_prefix_length(first_int, current, ip_bits)
-        net = ip('%s/%d' % (str(first), prefix))
-        networks.append(net)
-        if current == ip._ALL_ONES:
-            break
-        first_int = current + 1
-        first = IPAddress(first_int, version=first._version)
-    return networks
-
-def _collapse_address_list_recursive(addresses):
-    """Loops through the addresses, collapsing concurrent netblocks.
-
-    Example:
-
-        ip1 = IPv4Network('1.1.0.0/24')
-        ip2 = IPv4Network('1.1.1.0/24')
-        ip3 = IPv4Network('1.1.2.0/24')
-        ip4 = IPv4Network('1.1.3.0/24')
-        ip5 = IPv4Network('1.1.4.0/24')
-        ip6 = IPv4Network('1.1.0.1/22')
-
-        _collapse_address_list_recursive([ip1, ip2, ip3, ip4, ip5, ip6]) ->
-          [IPv4Network('1.1.0.0/22'), IPv4Network('1.1.4.0/24')]
-
-        This shouldn't be called directly; it is called via
-          collapse_address_list([]).
-
-    Args:
-        addresses: A list of IPv4Network's or IPv6Network's
-
-    Returns:
-        A list of IPv4Network's or IPv6Network's depending on what we were
-        passed.
-
-    """
-    ret_array = []
-    optimized = False
-
-    for cur_addr in addresses:
-        if not ret_array:
-            ret_array.append(cur_addr)
-            continue
-        if cur_addr in ret_array[-1]:
-            optimized = True
-        elif cur_addr == ret_array[-1].supernet().subnet()[1]:
-            ret_array.append(ret_array.pop().supernet())
-            optimized = True
-        else:
-            ret_array.append(cur_addr)
-
-    if optimized:
-        return _collapse_address_list_recursive(ret_array)
-
-    return ret_array
-
-
-def collapse_address_list(addresses):
-    """Collapse a list of IP objects.
-
-    Example:
-        collapse_address_list([IPv4('1.1.0.0/24'), IPv4('1.1.1.0/24')]) ->
-          [IPv4('1.1.0.0/23')]
-
-    Args:
-        addresses: A list of IPv4Network or IPv6Network objects.
-
-    Returns:
-        A list of IPv4Network or IPv6Network objects depending on what we
-        were passed.
-
-    Raises:
-        TypeError: If passed a list of mixed version objects.
-
-    """
-    i = 0
-    addrs = []
-    ips = []
-    nets = []
-
-    # split IP addresses and networks
-    for ip in addresses:
-        if isinstance(ip, _BaseIP):
-            if ips and ips[-1]._version != ip._version:
-                raise TypeError("%s and %s are not of the same version" % (
-                        str(ip), str(ips[-1])))
-            ips.append(ip)
-        elif ip._prefixlen == ip._max_prefixlen:
-            if ips and ips[-1]._version != ip._version:
-                raise TypeError("%s and %s are not of the same version" % (
-                        str(ip), str(ips[-1])))
-            ips.append(ip.ip)
-        else:
-            if nets and nets[-1]._version != ip._version:
-                raise TypeError("%s and %s are not of the same version" % (
-                        str(ip), str(ips[-1])))
-            nets.append(ip)
-
-    # sort and dedup
-    ips = sorted(set(ips))
-    nets = sorted(set(nets))
-
-    while i < len(ips):
-        (first, last) = _find_address_range(ips[i:])
-        i = ips.index(last) + 1
-        addrs.extend(summarize_address_range(first, last))
-
-    return _collapse_address_list_recursive(sorted(
-        addrs + nets, key=_BaseNet._get_networks_key))
-
-# backwards compatibility
-CollapseAddrList = collapse_address_list
-
-# We need to distinguish between the string and packed-bytes representations
-# of an IP address.  For example, b'0::1' is the IPv4 address 48.58.58.49,
-# while '0::1' is an IPv6 address.
-#
-# In Python 3, the native 'bytes' type already provides this functionality,
-# so we use it directly.  For earlier implementations where bytes is not a
-# distinct type, we create a subclass of str to serve as a tag.
-#
-# Usage example (Python 2):
-#   ip = ipaddr.IPAddress(ipaddr.Bytes('xxxx'))
-#
-# Usage example (Python 3):
-#   ip = ipaddr.IPAddress(b'xxxx')
-try:
-    if bytes is str:
-        raise TypeError("bytes is not a distinct type")
-    Bytes = bytes
-except (NameError, TypeError):
-    class Bytes(str):
-        def __repr__(self):
-            return 'Bytes(%s)' % str.__repr__(self)
-
-def get_mixed_type_key(obj):
-    """Return a key suitable for sorting between networks and addresses.
-
-    Address and Network objects are not sortable by default; they're
-    fundamentally different so the expression
-
-        IPv4Address('1.1.1.1') <= IPv4Network('1.1.1.1/24')
-
-    doesn't make any sense.  There are some times however, where you may wish
-    to have ipaddr sort these for you anyway. If you need to do this, you
-    can use this function as the key= argument to sorted().
-
-    Args:
-      obj: either a Network or Address object.
-    Returns:
-      appropriate key.
-
-    """
-    if isinstance(obj, _BaseNet):
-        return obj._get_networks_key()
-    elif isinstance(obj, _BaseIP):
-        return obj._get_address_key()
-    return NotImplemented
-
-class _IPAddrBase(object):
-
-    """The mother class."""
-
-    def __index__(self):
-        return self._ip
-
-    def __int__(self):
-        return self._ip
-
-    def __hex__(self):
-        return hex(self._ip)
-
-    @property
-    def exploded(self):
-        """Return the longhand version of the IP address as a string."""
-        return self._explode_shorthand_ip_string()
-
-    @property
-    def compressed(self):
-        """Return the shorthand version of the IP address as a string."""
-        return str(self)
-
-
-class _BaseIP(_IPAddrBase):
-
-    """A generic IP object.
-
-    This IP class contains the version independent methods which are
-    used by single IP addresses.
-
-    """
-
-    def __eq__(self, other):
-        try:
-            return (self._ip == other._ip
-                    and self._version == other._version)
-        except AttributeError:
-            return NotImplemented
-
-    def __ne__(self, other):
-        eq = self.__eq__(other)
-        if eq is NotImplemented:
-            return NotImplemented
-        return not eq
-
-    def __le__(self, other):
-        gt = self.__gt__(other)
-        if gt is NotImplemented:
-            return NotImplemented
-        return not gt
-
-    def __ge__(self, other):
-        lt = self.__lt__(other)
-        if lt is NotImplemented:
-            return NotImplemented
-        return not lt
-
-    def __lt__(self, other):
-        if self._version != other._version:
-            raise TypeError('%s and %s are not of the same version' % (
-                    str(self), str(other)))
-        if not isinstance(other, _BaseIP):
-            raise TypeError('%s and %s are not of the same type' % (
-                    str(self), str(other)))
-        if self._ip != other._ip:
-            return self._ip < other._ip
-        return False
-
-    def __gt__(self, other):
-        if self._version != other._version:
-            raise TypeError('%s and %s are not of the same version' % (
-                    str(self), str(other)))
-        if not isinstance(other, _BaseIP):
-            raise TypeError('%s and %s are not of the same type' % (
-                    str(self), str(other)))
-        if self._ip != other._ip:
-            return self._ip > other._ip
-        return False
-
-    # Shorthand for Integer addition and subtraction. This is not
-    # meant to ever support addition/subtraction of addresses.
-    def __add__(self, other):
-        if not isinstance(other, int):
-            return NotImplemented
-        return IPAddress(int(self) + other, version=self._version)
-
-    def __sub__(self, other):
-        if not isinstance(other, int):
-            return NotImplemented
-        return IPAddress(int(self) - other, version=self._version)
-
-    def __repr__(self):
-        return '%s(%r)' % (self.__class__.__name__, str(self))
-
-    def __str__(self):
-        return  '%s' % self._string_from_ip_int(self._ip)
-
-    def __hash__(self):
-        return hash(hex(long(self._ip)))
-
-    def _get_address_key(self):
-        return (self._version, self)
-
-    @property
-    def version(self):
-        raise NotImplementedError('BaseIP has no version')
-
-
-class _BaseNet(_IPAddrBase):
-
-    """A generic IP object.
-
-    This IP class contains the version independent methods which are
-    used by networks.
-
-    """
-
-    def __init__(self, address):
-        self._cache = {}
-
-    def __repr__(self):
-        return '%s(%r)' % (self.__class__.__name__, str(self))
-
-    def iterhosts(self):
-        """Generate Iterator over usable hosts in a network.
-
-           This is like __iter__ except it doesn't return the network
-           or broadcast addresses.
-
-        """
-        cur = int(self.network) + 1
-        bcast = int(self.broadcast) - 1
-        while cur <= bcast:
-            cur += 1
-            yield IPAddress(cur - 1, version=self._version)
-
-    def __iter__(self):
-        cur = int(self.network)
-        bcast = int(self.broadcast)
-        while cur <= bcast:
-            cur += 1
-            yield IPAddress(cur - 1, version=self._version)
-
-    def __getitem__(self, n):
-        network = int(self.network)
-        broadcast = int(self.broadcast)
-        if n >= 0:
-            if network + n > broadcast:
-                raise IndexError
-            return IPAddress(network + n, version=self._version)
-        else:
-            n += 1
-            if broadcast + n < network:
-                raise IndexError
-            return IPAddress(broadcast + n, version=self._version)
-
-    def __lt__(self, other):
-        if self._version != other._version:
-            raise TypeError('%s and %s are not of the same version' % (
-                    str(self), str(other)))
-        if not isinstance(other, _BaseNet):
-            raise TypeError('%s and %s are not of the same type' % (
-                    str(self), str(other)))
-        if self.network != other.network:
-            return self.network < other.network
-        if self.netmask != other.netmask:
-            return self.netmask < other.netmask
-        return False
-
-    def __gt__(self, other):
-        if self._version != other._version:
-            raise TypeError('%s and %s are not of the same version' % (
-                    str(self), str(other)))
-        if not isinstance(other, _BaseNet):
-            raise TypeError('%s and %s are not of the same type' % (
-                    str(self), str(other)))
-        if self.network != other.network:
-            return self.network > other.network
-        if self.netmask != other.netmask:
-            return self.netmask > other.netmask
-        return False
-
-    def __le__(self, other):
-        gt = self.__gt__(other)
-        if gt is NotImplemented:
-            return NotImplemented
-        return not gt
-
-    def __ge__(self, other):
-        lt = self.__lt__(other)
-        if lt is NotImplemented:
-            return NotImplemented
-        return not lt
-
-    def __eq__(self, other):
-        try:
-            return (self._version == other._version
-                    and self.network == other.network
-                    and int(self.netmask) == int(other.netmask))
-        except AttributeError:
-            if isinstance(other, _BaseIP):
-                return (self._version == other._version
-                        and self._ip == other._ip)
-
-    def __ne__(self, other):
-        eq = self.__eq__(other)
-        if eq is NotImplemented:
-            return NotImplemented
-        return not eq
-
-    def __str__(self):
-        return  '%s/%s' % (str(self.ip),
-                           str(self._prefixlen))
-
-    def __hash__(self):
-        return hash(int(self.network) ^ int(self.netmask))
-
-    def __contains__(self, other):
-        # always false if one is v4 and the other is v6.
-        if self._version != other._version:
-          return False
-        # dealing with another network.
-        if isinstance(other, _BaseNet):
-            return (self.network <= other.network and
-                    self.broadcast >= other.broadcast)
-        # dealing with another address
-        else:
-            return (int(self.network) <= int(other._ip) <=
-                    int(self.broadcast))
-
-    def overlaps(self, other):
-        """Tell if self is partly contained in other."""
-        return self.network in other or self.broadcast in other or (
-            other.network in self or other.broadcast in self)
-
-    @property
-    def network(self):
-        x = self._cache.get('network')
-        if x is None:
-            x = IPAddress(self._ip & int(self.netmask), version=self._version)
-            self._cache['network'] = x
-        return x
-
-    @property
-    def broadcast(self):
-        x = self._cache.get('broadcast')
-        if x is None:
-            x = IPAddress(self._ip | int(self.hostmask), version=self._version)
-            self._cache['broadcast'] = x
-        return x
-
-    @property
-    def hostmask(self):
-        x = self._cache.get('hostmask')
-        if x is None:
-            x = IPAddress(int(self.netmask) ^ self._ALL_ONES,
-                          version=self._version)
-            self._cache['hostmask'] = x
-        return x
-
-    @property
-    def with_prefixlen(self):
-        return '%s/%d' % (str(self.ip), self._prefixlen)
-
-    @property
-    def with_netmask(self):
-        return '%s/%s' % (str(self.ip), str(self.netmask))
-
-    @property
-    def with_hostmask(self):
-        return '%s/%s' % (str(self.ip), str(self.hostmask))
-
-    @property
-    def numhosts(self):
-        """Number of hosts in the current subnet."""
-        return int(self.broadcast) - int(self.network) + 1
-
-    @property
-    def version(self):
-        raise NotImplementedError('BaseNet has no version')
-
-    @property
-    def prefixlen(self):
-        return self._prefixlen
-
-    def address_exclude(self, other):
-        """Remove an address from a larger block.
-
-        For example:
-
-            addr1 = IPNetwork('10.1.1.0/24')
-            addr2 = IPNetwork('10.1.1.0/26')
-            addr1.address_exclude(addr2) =
-                [IPNetwork('10.1.1.64/26'), IPNetwork('10.1.1.128/25')]
-
-        or IPv6:
-
-            addr1 = IPNetwork('::1/32')
-            addr2 = IPNetwork('::1/128')
-            addr1.address_exclude(addr2) = [IPNetwork('::0/128'),
-                IPNetwork('::2/127'),
-                IPNetwork('::4/126'),
-                IPNetwork('::8/125'),
-                ...
-                IPNetwork('0:0:8000::/33')]
-
-        Args:
-            other: An IPvXNetwork object of the same type.
-
-        Returns:
-            A sorted list of IPvXNetwork objects addresses which is self
-            minus other.
-
-        Raises:
-            TypeError: If self and other are of difffering address
-              versions, or if other is not a network object.
-            ValueError: If other is not completely contained by self.
-
-        """
-        if not self._version == other._version:
-            raise TypeError("%s and %s are not of the same version" % (
-                str(self), str(other)))
-
-        if not isinstance(other, _BaseNet):
-            raise TypeError("%s is not a network object" % str(other))
-
-        if other not in self:
-            raise ValueError('%s not contained in %s' % (str(other),
-                                                         str(self)))
-        if other == self:
-            return []
-
-        ret_addrs = []
-
-        # Make sure we're comparing the network of other.
-        other = IPNetwork('%s/%s' % (str(other.network), str(other.prefixlen)),
-                   version=other._version)
-
-        s1, s2 = self.subnet()
-        while s1 != other and s2 != other:
-            if other in s1:
-                ret_addrs.append(s2)
-                s1, s2 = s1.subnet()
-            elif other in s2:
-                ret_addrs.append(s1)
-                s1, s2 = s2.subnet()
-            else:
-                # If we got here, there's a bug somewhere.
-                assert True == False, ('Error performing exclusion: '
-                                       's1: %s s2: %s other: %s' %
-                                       (str(s1), str(s2), str(other)))
-        if s1 == other:
-            ret_addrs.append(s2)
-        elif s2 == other:
-            ret_addrs.append(s1)
-        else:
-            # If we got here, there's a bug somewhere.
-            assert True == False, ('Error performing exclusion: '
-                                   's1: %s s2: %s other: %s' %
-                                   (str(s1), str(s2), str(other)))
-
-        return sorted(ret_addrs, key=_BaseNet._get_networks_key)
-
-    def compare_networks(self, other):
-        """Compare two IP objects.
-
-        This is only concerned about the comparison of the integer
-        representation of the network addresses.  This means that the
-        host bits aren't considered at all in this method.  If you want
-        to compare host bits, you can easily enough do a
-        'HostA._ip < HostB._ip'
-
-        Args:
-            other: An IP object.
-
-        Returns:
-            If the IP versions of self and other are the same, returns:
-
-            -1 if self < other:
-              eg: IPv4('1.1.1.0/24') < IPv4('1.1.2.0/24')
-              IPv6('1080::200C:417A') < IPv6('1080::200B:417B')
-            0 if self == other
-              eg: IPv4('1.1.1.1/24') == IPv4('1.1.1.2/24')
-              IPv6('1080::200C:417A/96') == IPv6('1080::200C:417B/96')
-            1 if self > other
-              eg: IPv4('1.1.1.0/24') > IPv4('1.1.0.0/24')
-              IPv6('1080::1:200C:417A/112') >
-              IPv6('1080::0:200C:417A/112')
-
-            If the IP versions of self and other are different, returns:
-
-            -1 if self._version < other._version
-              eg: IPv4('10.0.0.1/24') < IPv6('::1/128')
-            1 if self._version > other._version
-              eg: IPv6('::1/128') > IPv4('255.255.255.0/24')
-
-        """
-        if self._version < other._version:
-            return -1
-        if self._version > other._version:
-            return 1
-        # self._version == other._version below here:
-        if self.network < other.network:
-            return -1
-        if self.network > other.network:
-            return 1
-        # self.network == other.network below here:
-        if self.netmask < other.netmask:
-            return -1
-        if self.netmask > other.netmask:
-            return 1
-        # self.network == other.network and self.netmask == other.netmask
-        return 0
-
-    def _get_networks_key(self):
-        """Network-only key function.
-
-        Returns an object that identifies this address' network and
-        netmask. This function is a suitable "key" argument for sorted()
-        and list.sort().
-
-        """
-        return (self._version, self.network, self.netmask)
-
-    def _ip_int_from_prefix(self, prefixlen=None):
-        """Turn the prefix length netmask into a int for comparison.
-
-        Args:
-            prefixlen: An integer, the prefix length.
-
-        Returns:
-            An integer.
-
-        """
-        if not prefixlen and prefixlen != 0:
-            prefixlen = self._prefixlen
-        return self._ALL_ONES ^ (self._ALL_ONES >> prefixlen)
-
-    def _prefix_from_ip_int(self, ip_int, mask=32):
-        """Return prefix length from the decimal netmask.
-
-        Args:
-            ip_int: An integer, the IP address.
-            mask: The netmask.  Defaults to 32.
-
-        Returns:
-            An integer, the prefix length.
-
-        """
-        while mask:
-            if ip_int & 1 == 1:
-                break
-            ip_int >>= 1
-            mask -= 1
-
-        return mask
-
-    def _ip_string_from_prefix(self, prefixlen=None):
-        """Turn a prefix length into a dotted decimal string.
-
-        Args:
-            prefixlen: An integer, the netmask prefix length.
-
-        Returns:
-            A string, the dotted decimal netmask string.
-
-        """
-        if not prefixlen:
-            prefixlen = self._prefixlen
-        return self._string_from_ip_int(self._ip_int_from_prefix(prefixlen))
-
-    def iter_subnets(self, prefixlen_diff=1, new_prefix=None):
-        """The subnets which join to make the current subnet.
-
-        In the case that self contains only one IP
-        (self._prefixlen == 32 for IPv4 or self._prefixlen == 128
-        for IPv6), return a list with just ourself.
-
-        Args:
-            prefixlen_diff: An integer, the amount the prefix length
-              should be increased by. This should not be set if
-              new_prefix is also set.
-            new_prefix: The desired new prefix length. This must be a
-              larger number (smaller prefix) than the existing prefix.
-              This should not be set if prefixlen_diff is also set.
-
-        Returns:
-            An iterator of IPv(4|6) objects.
-
-        Raises:
-            ValueError: The prefixlen_diff is too small or too large.
-                OR
-            prefixlen_diff and new_prefix are both set or new_prefix
-              is a smaller number than the current prefix (smaller
-              number means a larger network)
-
-        """
-        if self._prefixlen == self._max_prefixlen:
-            yield self
-            return
-
-        if new_prefix is not None:
-            if new_prefix < self._prefixlen:
-                raise ValueError('new prefix must be longer')
-            if prefixlen_diff != 1:
-                raise ValueError('cannot set prefixlen_diff and new_prefix')
-            prefixlen_diff = new_prefix - self._prefixlen
-
-        if prefixlen_diff < 0:
-            raise ValueError('prefix length diff must be > 0')
-        new_prefixlen = self._prefixlen + prefixlen_diff
-
-        if not self._is_valid_netmask(str(new_prefixlen)):
-            raise ValueError(
-                'prefix length diff %d is invalid for netblock %s' % (
-                    new_prefixlen, str(self)))
-
-        first = IPNetwork('%s/%s' % (str(self.network),
-                                     str(self._prefixlen + prefixlen_diff)),
-                         version=self._version)
-
-        yield first
-        current = first
-        while True:
-            broadcast = current.broadcast
-            if broadcast == self.broadcast:
-                return
-            new_addr = IPAddress(int(broadcast) + 1, version=self._version)
-            current = IPNetwork('%s/%s' % (str(new_addr), str(new_prefixlen)),
-                                version=self._version)
-
-            yield current
-
-    def masked(self):
-        """Return the network object with the host bits masked out."""
-        return IPNetwork('%s/%d' % (self.network, self._prefixlen),
-                         version=self._version)
-
-    def subnet(self, prefixlen_diff=1, new_prefix=None):
-        """Return a list of subnets, rather than an iterator."""
-        return list(self.iter_subnets(prefixlen_diff, new_prefix))
-
-    def supernet(self, prefixlen_diff=1, new_prefix=None):
-        """The supernet containing the current network.
-
-        Args:
-            prefixlen_diff: An integer, the amount the prefix length of
-              the network should be decreased by.  For example, given a
-              /24 network and a prefixlen_diff of 3, a supernet with a
-              /21 netmask is returned.
-
-        Returns:
-            An IPv4 network object.
-
-        Raises:
-            ValueError: If self.prefixlen - prefixlen_diff < 0. I.e., you have a
-              negative prefix length.
-                OR
-            If prefixlen_diff and new_prefix are both set or new_prefix is a
-              larger number than the current prefix (larger number means a
-              smaller network)
-
-        """
-        if self._prefixlen == 0:
-            return self
-
-        if new_prefix is not None:
-            if new_prefix > self._prefixlen:
-                raise ValueError('new prefix must be shorter')
-            if prefixlen_diff != 1:
-                raise ValueError('cannot set prefixlen_diff and new_prefix')
-            prefixlen_diff = self._prefixlen - new_prefix
-
-
-        if self.prefixlen - prefixlen_diff < 0:
-            raise ValueError(
-                'current prefixlen is %d, cannot have a prefixlen_diff of %d' %
-                (self.prefixlen, prefixlen_diff))
-        return IPNetwork('%s/%s' % (str(self.network),
-                                    str(self.prefixlen - prefixlen_diff)),
-                         version=self._version)
-
-    # backwards compatibility
-    Subnet = subnet
-    Supernet = supernet
-    AddressExclude = address_exclude
-    CompareNetworks = compare_networks
-    Contains = __contains__
-
-
-class _BaseV4(object):
-
-    """Base IPv4 object.
-
-    The following methods are used by IPv4 objects in both single IP
-    addresses and networks.
-
-    """
-
-    # Equivalent to 255.255.255.255 or 32 bits of 1's.
-    _ALL_ONES = (2**IPV4LENGTH) - 1
-    _DECIMAL_DIGITS = frozenset('0123456789')
-
-    def __init__(self, address):
-        self._version = 4
-        self._max_prefixlen = IPV4LENGTH
-
-    def _explode_shorthand_ip_string(self):
-        return str(self)
-
-    def _ip_int_from_string(self, ip_str):
-        """Turn the given IP string into an integer for comparison.
-
-        Args:
-            ip_str: A string, the IP ip_str.
-
-        Returns:
-            The IP ip_str as an integer.
-
-        Raises:
-            AddressValueError: if ip_str isn't a valid IPv4 Address.
-
-        """
-        octets = ip_str.split('.')
-        if len(octets) != 4:
-            raise AddressValueError(ip_str)
-
-        packed_ip = 0
-        for oc in octets:
-            try:
-                packed_ip = (packed_ip << 8) | self._parse_octet(oc)
-            except ValueError:
-                raise AddressValueError(ip_str)
-        return packed_ip
-
-    def _parse_octet(self, octet_str):
-        """Convert a decimal octet into an integer.
-
-        Args:
-            octet_str: A string, the number to parse.
-
-        Returns:
-            The octet as an integer.
-
-        Raises:
-            ValueError: if the octet isn't strictly a decimal from [0..255].
-
-        """
-        # Whitelist the characters, since int() allows a lot of bizarre stuff.
-        if not self._DECIMAL_DIGITS.issuperset(octet_str):
-            raise ValueError
-        octet_int = int(octet_str, 10)
-        # Disallow leading zeroes, because no clear standard exists on
-        # whether these should be interpreted as decimal or octal.
-        if octet_int > 255 or (octet_str[0] == '0' and len(octet_str) > 1):
-            raise ValueError
-        return octet_int
-
-    def _string_from_ip_int(self, ip_int):
-        """Turns a 32-bit integer into dotted decimal notation.
-
-        Args:
-            ip_int: An integer, the IP address.
-
-        Returns:
-            The IP address as a string in dotted decimal notation.
-
-        """
-        octets = []
-        for _ in xrange(4):
-            octets.insert(0, str(ip_int & 0xFF))
-            ip_int >>= 8
-        return '.'.join(octets)
-
-    @property
-    def max_prefixlen(self):
-        return self._max_prefixlen
-
-    @property
-    def packed(self):
-        """The binary representation of this address."""
-        return v4_int_to_packed(self._ip)
-
-    @property
-    def version(self):
-        return self._version
-
-    @property
-    def is_reserved(self):
-       """Test if the address is otherwise IETF reserved.
-
-        Returns:
-            A boolean, True if the address is within the
-            reserved IPv4 Network range.
-
-       """
-       return self in IPv4Network('240.0.0.0/4')
-
-    @property
-    def is_private(self):
-        """Test if this address is allocated for private networks.
-
-        Returns:
-            A boolean, True if the address is reserved per RFC 1918.
-
-        """
-        return (self in IPv4Network('10.0.0.0/8') or
-                self in IPv4Network('172.16.0.0/12') or
-                self in IPv4Network('192.168.0.0/16'))
-
-    @property
-    def is_multicast(self):
-        """Test if the address is reserved for multicast use.
-
-        Returns:
-            A boolean, True if the address is multicast.
-            See RFC 3171 for details.
-
-        """
-        return self in IPv4Network('224.0.0.0/4')
-
-    @property
-    def is_unspecified(self):
-        """Test if the address is unspecified.
-
-        Returns:
-            A boolean, True if this is the unspecified address as defined in
-            RFC 5735 3.
-
-        """
-        return self in IPv4Network('0.0.0.0')
-
-    @property
-    def is_loopback(self):
-        """Test if the address is a loopback address.
-
-        Returns:
-            A boolean, True if the address is a loopback per RFC 3330.
-
-        """
-        return self in IPv4Network('127.0.0.0/8')
-
-    @property
-    def is_link_local(self):
-        """Test if the address is reserved for link-local.
-
-        Returns:
-            A boolean, True if the address is link-local per RFC 3927.
-
-        """
-        return self in IPv4Network('169.254.0.0/16')
-
-
-class IPv4Address(_BaseV4, _BaseIP):
-
-    """Represent and manipulate single IPv4 Addresses."""
-
-    def __init__(self, address):
-
-        """
-        Args:
-            address: A string or integer representing the IP
-              '192.168.1.1'
-
-              Additionally, an integer can be passed, so
-              IPv4Address('192.168.1.1') == IPv4Address(3232235777).
-              or, more generally
-              IPv4Address(int(IPv4Address('192.168.1.1'))) ==
-                IPv4Address('192.168.1.1')
-
-        Raises:
-            AddressValueError: If ipaddr isn't a valid IPv4 address.
-
-        """
-        _BaseV4.__init__(self, address)
-
-        # Efficient constructor from integer.
-        if isinstance(address, (int, long)):
-            self._ip = address
-            if address < 0 or address > self._ALL_ONES:
-                raise AddressValueError(address)
-            return
-
-        # Constructing from a packed address
-        if isinstance(address, Bytes):
-            try:
-                self._ip, = struct.unpack('!I', address)
-            except struct.error:
-                raise AddressValueError(address)  # Wrong length.
-            return
-
-        # Assume input argument to be string or any object representation
-        # which converts into a formatted IP string.
-        addr_str = str(address)
-        self._ip = self._ip_int_from_string(addr_str)
-
-
-class IPv4Network(_BaseV4, _BaseNet):
-
-    """This class represents and manipulates 32-bit IPv4 networks.
-
-    Attributes: [examples for IPv4Network('1.2.3.4/27')]
-        ._ip: 16909060
-        .ip: IPv4Address('1.2.3.4')
-        .network: IPv4Address('1.2.3.0')
-        .hostmask: IPv4Address('0.0.0.31')
-        .broadcast: IPv4Address('1.2.3.31')
-        .netmask: IPv4Address('255.255.255.224')
-        .prefixlen: 27
-
-    """
-
-    # the valid octets for host and netmasks. only useful for IPv4.
-    _valid_mask_octets = set((255, 254, 252, 248, 240, 224, 192, 128, 0))
-
-    def __init__(self, address, strict=False):
-        """Instantiate a new IPv4 network object.
-
-        Args:
-            address: A string or integer representing the IP [& network].
-              '192.168.1.1/24'
-              '192.168.1.1/255.255.255.0'
-              '192.168.1.1/0.0.0.255'
-              are all functionally the same in IPv4. Similarly,
-              '192.168.1.1'
-              '192.168.1.1/255.255.255.255'
-              '192.168.1.1/32'
-              are also functionaly equivalent. That is to say, failing to
-              provide a subnetmask will create an object with a mask of /32.
-
-              If the mask (portion after the / in the argument) is given in
-              dotted quad form, it is treated as a netmask if it starts with a
-              non-zero field (e.g. /255.0.0.0 == /8) and as a hostmask if it
-              starts with a zero field (e.g. 0.255.255.255 == /8), with the
-              single exception of an all-zero mask which is treated as a
-              netmask == /0. If no mask is given, a default of /32 is used.
-
-              Additionally, an integer can be passed, so
-              IPv4Network('192.168.1.1') == IPv4Network(3232235777).
-              or, more generally
-              IPv4Network(int(IPv4Network('192.168.1.1'))) ==
-                IPv4Network('192.168.1.1')
-
-            strict: A boolean. If true, ensure that we have been passed
-              A true network address, eg, 192.168.1.0/24 and not an
-              IP address on a network, eg, 192.168.1.1/24.
-
-        Raises:
-            AddressValueError: If ipaddr isn't a valid IPv4 address.
-            NetmaskValueError: If the netmask isn't valid for
-              an IPv4 address.
-            ValueError: If strict was True and a network address was not
-              supplied.
-
-        """
-        _BaseNet.__init__(self, address)
-        _BaseV4.__init__(self, address)
-
-        # Constructing from an integer or packed bytes.
-        if isinstance(address, (int, long, Bytes)):
-            self.ip = IPv4Address(address)
-            self._ip = self.ip._ip
-            self._prefixlen = self._max_prefixlen
-            self.netmask = IPv4Address(self._ALL_ONES)
-            return
-
-        # Assume input argument to be string or any object representation
-        # which converts into a formatted IP prefix string.
-        addr = str(address).split('/')
-
-        if len(addr) > 2:
-            raise AddressValueError(address)
-
-        self._ip = self._ip_int_from_string(addr[0])
-        self.ip = IPv4Address(self._ip)
-
-        if len(addr) == 2:
-            mask = addr[1].split('.')
-            if len(mask) == 4:
-                # We have dotted decimal netmask.
-                if self._is_valid_netmask(addr[1]):
-                    self.netmask = IPv4Address(self._ip_int_from_string(
-                            addr[1]))
-                elif self._is_hostmask(addr[1]):
-                    self.netmask = IPv4Address(
-                        self._ip_int_from_string(addr[1]) ^ self._ALL_ONES)
-                else:
-                    raise NetmaskValueError('%s is not a valid netmask'
-                                                     % addr[1])
-
-                self._prefixlen = self._prefix_from_ip_int(int(self.netmask))
-            else:
-                # We have a netmask in prefix length form.
-                if not self._is_valid_netmask(addr[1]):
-                    raise NetmaskValueError(addr[1])
-                self._prefixlen = int(addr[1])
-                self.netmask = IPv4Address(self._ip_int_from_prefix(
-                    self._prefixlen))
-        else:
-            self._prefixlen = self._max_prefixlen
-            self.netmask = IPv4Address(self._ip_int_from_prefix(
-                self._prefixlen))
-        if strict:
-            if self.ip != self.network:
-                raise ValueError('%s has host bits set' %
-                                 self.ip)
-        if self._prefixlen == (self._max_prefixlen - 1):
-            self.iterhosts = self.__iter__
-
-    def _is_hostmask(self, ip_str):
-        """Test if the IP string is a hostmask (rather than a netmask).
-
-        Args:
-            ip_str: A string, the potential hostmask.
-
-        Returns:
-            A boolean, True if the IP string is a hostmask.
-
-        """
-        bits = ip_str.split('.')
-        try:
-            parts = [int(x) for x in bits if int(x) in self._valid_mask_octets]
-        except ValueError:
-            return False
-        if len(parts) != len(bits):
-            return False
-        if parts[0] < parts[-1]:
-            return True
-        return False
-
-    def _is_valid_netmask(self, netmask):
-        """Verify that the netmask is valid.
-
-        Args:
-            netmask: A string, either a prefix or dotted decimal
-              netmask.
-
-        Returns:
-            A boolean, True if the prefix represents a valid IPv4
-            netmask.
-
-        """
-        mask = netmask.split('.')
-        if len(mask) == 4:
-            if [x for x in mask if int(x) not in self._valid_mask_octets]:
-                return False
-            if [y for idx, y in enumerate(mask) if idx > 0 and
-                y > mask[idx - 1]]:
-                return False
-            return True
-        try:
-            netmask = int(netmask)
-        except ValueError:
-            return False
-        return 0 <= netmask <= self._max_prefixlen
-
-    # backwards compatibility
-    IsRFC1918 = lambda self: self.is_private
-    IsMulticast = lambda self: self.is_multicast
-    IsLoopback = lambda self: self.is_loopback
-    IsLinkLocal = lambda self: self.is_link_local
-
-
-class _BaseV6(object):
-
-    """Base IPv6 object.
-
-    The following methods are used by IPv6 objects in both single IP
-    addresses and networks.
-
-    """
-
-    _ALL_ONES = (2**IPV6LENGTH) - 1
-    _HEXTET_COUNT = 8
-    _HEX_DIGITS = frozenset('0123456789ABCDEFabcdef')
-
-    def __init__(self, address):
-        self._version = 6
-        self._max_prefixlen = IPV6LENGTH
-
-    def _ip_int_from_string(self, ip_str):
-        """Turn an IPv6 ip_str into an integer.
-
-        Args:
-            ip_str: A string, the IPv6 ip_str.
-
-        Returns:
-            A long, the IPv6 ip_str.
-
-        Raises:
-            AddressValueError: if ip_str isn't a valid IPv6 Address.
-
-        """
-        parts = ip_str.split(':')
-
-        # An IPv6 address needs at least 2 colons (3 parts).
-        if len(parts) < 3:
-            raise AddressValueError(ip_str)
-
-        # If the address has an IPv4-style suffix, convert it to hexadecimal.
-        if '.' in parts[-1]:
-            ipv4_int = IPv4Address(parts.pop())._ip
-            parts.append('%x' % ((ipv4_int >> 16) & 0xFFFF))
-            parts.append('%x' % (ipv4_int & 0xFFFF))
-
-        # An IPv6 address can't have more than 8 colons (9 parts).
-        if len(parts) > self._HEXTET_COUNT + 1:
-            raise AddressValueError(ip_str)
-
-        # Disregarding the endpoints, find '::' with nothing in between.
-        # This indicates that a run of zeroes has been skipped.
-        try:
-            skip_index, = (
-                [i for i in xrange(1, len(parts) - 1) if not parts[i]] or
-                [None])
-        except ValueError:
-            # Can't have more than one '::'
-            raise AddressValueError(ip_str)
-
-        # parts_hi is the number of parts to copy from above/before the '::'
-        # parts_lo is the number of parts to copy from below/after the '::'
-        if skip_index is not None:
-            # If we found a '::', then check if it also covers the endpoints.
-            parts_hi = skip_index
-            parts_lo = len(parts) - skip_index - 1
-            if not parts[0]:
-                parts_hi -= 1
-                if parts_hi:
-                    raise AddressValueError(ip_str)  # ^: requires ^::
-            if not parts[-1]:
-                parts_lo -= 1
-                if parts_lo:
-                    raise AddressValueError(ip_str)  # :$ requires ::$
-            parts_skipped = self._HEXTET_COUNT - (parts_hi + parts_lo)
-            if parts_skipped < 1:
-                raise AddressValueError(ip_str)
-        else:
-            # Otherwise, allocate the entire address to parts_hi.  The endpoints
-            # could still be empty, but _parse_hextet() will check for that.
-            if len(parts) != self._HEXTET_COUNT:
-                raise AddressValueError(ip_str)
-            parts_hi = len(parts)
-            parts_lo = 0
-            parts_skipped = 0
-
-        try:
-            # Now, parse the hextets into a 128-bit integer.
-            ip_int = 0L
-            for i in xrange(parts_hi):
-                ip_int <<= 16
-                ip_int |= self._parse_hextet(parts[i])
-            ip_int <<= 16 * parts_skipped
-            for i in xrange(-parts_lo, 0):
-                ip_int <<= 16
-                ip_int |= self._parse_hextet(parts[i])
-            return ip_int
-        except ValueError:
-            raise AddressValueError(ip_str)
-
-    def _parse_hextet(self, hextet_str):
-        """Convert an IPv6 hextet string into an integer.
-
-        Args:
-            hextet_str: A string, the number to parse.
-
-        Returns:
-            The hextet as an integer.
-
-        Raises:
-            ValueError: if the input isn't strictly a hex number from [0..FFFF].
-
-        """
-        # Whitelist the characters, since int() allows a lot of bizarre stuff.
-        if not self._HEX_DIGITS.issuperset(hextet_str):
-            raise ValueError
-        hextet_int = int(hextet_str, 16)
-        if hextet_int > 0xFFFF:
-            raise ValueError
-        return hextet_int
-
-    def _compress_hextets(self, hextets):
-        """Compresses a list of hextets.
-
-        Compresses a list of strings, replacing the longest continuous
-        sequence of "0" in the list with "" and adding empty strings at
-        the beginning or at the end of the string such that subsequently
-        calling ":".join(hextets) will produce the compressed version of
-        the IPv6 address.
-
-        Args:
-            hextets: A list of strings, the hextets to compress.
-
-        Returns:
-            A list of strings.
-
-        """
-        best_doublecolon_start = -1
-        best_doublecolon_len = 0
-        doublecolon_start = -1
-        doublecolon_len = 0
-        for index in range(len(hextets)):
-            if hextets[index] == '0':
-                doublecolon_len += 1
-                if doublecolon_start == -1:
-                    # Start of a sequence of zeros.
-                    doublecolon_start = index
-                if doublecolon_len > best_doublecolon_len:
-                    # This is the longest sequence of zeros so far.
-                    best_doublecolon_len = doublecolon_len
-                    best_doublecolon_start = doublecolon_start
-            else:
-                doublecolon_len = 0
-                doublecolon_start = -1
-
-        if best_doublecolon_len > 1:
-            best_doublecolon_end = (best_doublecolon_start +
-                                    best_doublecolon_len)
-            # For zeros at the end of the address.
-            if best_doublecolon_end == len(hextets):
-                hextets += ['']
-            hextets[best_doublecolon_start:best_doublecolon_end] = ['']
-            # For zeros at the beginning of the address.
-            if best_doublecolon_start == 0:
-                hextets = [''] + hextets
-
-        return hextets
-
-    def _string_from_ip_int(self, ip_int=None):
-        """Turns a 128-bit integer into hexadecimal notation.
-
-        Args:
-            ip_int: An integer, the IP address.
-
-        Returns:
-            A string, the hexadecimal representation of the address.
-
-        Raises:
-            ValueError: The address is bigger than 128 bits of all ones.
-
-        """
-        if not ip_int and ip_int != 0:
-            ip_int = int(self._ip)
-
-        if ip_int > self._ALL_ONES:
-            raise ValueError('IPv6 address is too large')
-
-        hex_str = '%032x' % ip_int
-        hextets = []
-        for x in range(0, 32, 4):
-            hextets.append('%x' % int(hex_str[x:x+4], 16))
-
-        hextets = self._compress_hextets(hextets)
-        return ':'.join(hextets)
-
-    def _explode_shorthand_ip_string(self):
-        """Expand a shortened IPv6 address.
-
-        Args:
-            ip_str: A string, the IPv6 address.
-
-        Returns:
-            A string, the expanded IPv6 address.
-
-        """
-        if isinstance(self, _BaseNet):
-            ip_str = str(self.ip)
-        else:
-            ip_str = str(self)
-
-        ip_int = self._ip_int_from_string(ip_str)
-        parts = []
-        for i in xrange(self._HEXTET_COUNT):
-            parts.append('%04x' % (ip_int & 0xFFFF))
-            ip_int >>= 16
-        parts.reverse()
-        if isinstance(self, _BaseNet):
-            return '%s/%d' % (':'.join(parts), self.prefixlen)
-        return ':'.join(parts)
-
-    @property
-    def max_prefixlen(self):
-        return self._max_prefixlen
-
-    @property
-    def packed(self):
-        """The binary representation of this address."""
-        return v6_int_to_packed(self._ip)
-
-    @property
-    def version(self):
-        return self._version
-
-    @property
-    def is_multicast(self):
-        """Test if the address is reserved for multicast use.
-
-        Returns:
-            A boolean, True if the address is a multicast address.
-            See RFC 2373 2.7 for details.
-
-        """
-        return self in IPv6Network('ff00::/8')
-
-    @property
-    def is_reserved(self):
-        """Test if the address is otherwise IETF reserved.
-
-        Returns:
-            A boolean, True if the address is within one of the
-            reserved IPv6 Network ranges.
-
-        """
-        return (self in IPv6Network('::/8') or
-                self in IPv6Network('100::/8') or
-                self in IPv6Network('200::/7') or
-                self in IPv6Network('400::/6') or
-                self in IPv6Network('800::/5') or
-                self in IPv6Network('1000::/4') or
-                self in IPv6Network('4000::/3') or
-                self in IPv6Network('6000::/3') or
-                self in IPv6Network('8000::/3') or
-                self in IPv6Network('A000::/3') or
-                self in IPv6Network('C000::/3') or
-                self in IPv6Network('E000::/4') or
-                self in IPv6Network('F000::/5') or
-                self in IPv6Network('F800::/6') or
-                self in IPv6Network('FE00::/9'))
-
-    @property
-    def is_unspecified(self):
-        """Test if the address is unspecified.
-
-        Returns:
-            A boolean, True if this is the unspecified address as defined in
-            RFC 2373 2.5.2.
-
-        """
-        return self._ip == 0 and getattr(self, '_prefixlen', 128) == 128
-
-    @property
-    def is_loopback(self):
-        """Test if the address is a loopback address.
-
-        Returns:
-            A boolean, True if the address is a loopback address as defined in
-            RFC 2373 2.5.3.
-
-        """
-        return self._ip == 1 and getattr(self, '_prefixlen', 128) == 128
-
-    @property
-    def is_link_local(self):
-        """Test if the address is reserved for link-local.
-
-        Returns:
-            A boolean, True if the address is reserved per RFC 4291.
-
-        """
-        return self in IPv6Network('fe80::/10')
-
-    @property
-    def is_site_local(self):
-        """Test if the address is reserved for site-local.
-
-        Note that the site-local address space has been deprecated by RFC 3879.
-        Use is_private to test if this address is in the space of unique local
-        addresses as defined by RFC 4193.
-
-        Returns:
-            A boolean, True if the address is reserved per RFC 3513 2.5.6.
-
-        """
-        return self in IPv6Network('fec0::/10')
-
-    @property
-    def is_private(self):
-        """Test if this address is allocated for private networks.
-
-        Returns:
-            A boolean, True if the address is reserved per RFC 4193.
-
-        """
-        return self in IPv6Network('fc00::/7')
-
-    @property
-    def ipv4_mapped(self):
-        """Return the IPv4 mapped address.
-
-        Returns:
-            If the IPv6 address is a v4 mapped address, return the
-            IPv4 mapped address. Return None otherwise.
-
-        """
-        if (self._ip >> 32) != 0xFFFF:
-            return None
-        return IPv4Address(self._ip & 0xFFFFFFFF)
-
-    @property
-    def teredo(self):
-        """Tuple of embedded teredo IPs.
-
-        Returns:
-            Tuple of the (server, client) IPs or None if the address
-            doesn't appear to be a teredo address (doesn't start with
-            2001::/32)
-
-        """
-        if (self._ip >> 96) != 0x20010000:
-            return None
-        return (IPv4Address((self._ip >> 64) & 0xFFFFFFFF),
-                IPv4Address(~self._ip & 0xFFFFFFFF))
-
-    @property
-    def sixtofour(self):
-        """Return the IPv4 6to4 embedded address.
-
-        Returns:
-            The IPv4 6to4-embedded address if present or None if the
-            address doesn't appear to contain a 6to4 embedded address.
-
-        """
-        if (self._ip >> 112) != 0x2002:
-            return None
-        return IPv4Address((self._ip >> 80) & 0xFFFFFFFF)
-
-
-class IPv6Address(_BaseV6, _BaseIP):
-
-    """Represent and manipulate single IPv6 Addresses.
-    """
-
-    def __init__(self, address):
-        """Instantiate a new IPv6 address object.
-
-        Args:
-            address: A string or integer representing the IP
-
-              Additionally, an integer can be passed, so
-              IPv6Address('2001:4860::') ==
-                IPv6Address(42541956101370907050197289607612071936L).
-              or, more generally
-              IPv6Address(IPv6Address('2001:4860::')._ip) ==
-                IPv6Address('2001:4860::')
-
-        Raises:
-            AddressValueError: If address isn't a valid IPv6 address.
-
-        """
-        _BaseV6.__init__(self, address)
-
-        # Efficient constructor from integer.
-        if isinstance(address, (int, long)):
-            self._ip = address
-            if address < 0 or address > self._ALL_ONES:
-                raise AddressValueError(address)
-            return
-
-        # Constructing from a packed address
-        if isinstance(address, Bytes):
-            try:
-                hi, lo = struct.unpack('!QQ', address)
-            except struct.error:
-                raise AddressValueError(address)  # Wrong length.
-            self._ip = (hi << 64) | lo
-            return
-
-        # Assume input argument to be string or any object representation
-        # which converts into a formatted IP string.
-        addr_str = str(address)
-        if not addr_str:
-            raise AddressValueError('')
-
-        self._ip = self._ip_int_from_string(addr_str)
-
-
-class IPv6Network(_BaseV6, _BaseNet):
-
-    """This class represents and manipulates 128-bit IPv6 networks.
-
-    Attributes: [examples for IPv6('2001:658:22A:CAFE:200::1/64')]
-        .ip: IPv6Address('2001:658:22a:cafe:200::1')
-        .network: IPv6Address('2001:658:22a:cafe::')
-        .hostmask: IPv6Address('::ffff:ffff:ffff:ffff')
-        .broadcast: IPv6Address('2001:658:22a:cafe:ffff:ffff:ffff:ffff')
-        .netmask: IPv6Address('ffff:ffff:ffff:ffff::')
-        .prefixlen: 64
-
-    """
-
-
-    def __init__(self, address, strict=False):
-        """Instantiate a new IPv6 Network object.
-
-        Args:
-            address: A string or integer representing the IPv6 network or the IP
-              and prefix/netmask.
-              '2001:4860::/128'
-              '2001:4860:0000:0000:0000:0000:0000:0000/128'
-              '2001:4860::'
-              are all functionally the same in IPv6.  That is to say,
-              failing to provide a subnetmask will create an object with
-              a mask of /128.
-
-              Additionally, an integer can be passed, so
-              IPv6Network('2001:4860::') ==
-                IPv6Network(42541956101370907050197289607612071936L).
-              or, more generally
-              IPv6Network(IPv6Network('2001:4860::')._ip) ==
-                IPv6Network('2001:4860::')
-
-            strict: A boolean. If true, ensure that we have been passed
-              A true network address, eg, 192.168.1.0/24 and not an
-              IP address on a network, eg, 192.168.1.1/24.
-
-        Raises:
-            AddressValueError: If address isn't a valid IPv6 address.
-            NetmaskValueError: If the netmask isn't valid for
-              an IPv6 address.
-            ValueError: If strict was True and a network address was not
-              supplied.
-
-        """
-        _BaseNet.__init__(self, address)
-        _BaseV6.__init__(self, address)
-
-        # Constructing from an integer or packed bytes.
-        if isinstance(address, (int, long, Bytes)):
-            self.ip = IPv6Address(address)
-            self._ip = self.ip._ip
-            self._prefixlen = self._max_prefixlen
-            self.netmask = IPv6Address(self._ALL_ONES)
-            return
-
-        # Assume input argument to be string or any object representation
-        # which converts into a formatted IP prefix string.
-        addr = str(address).split('/')
-
-        if len(addr) > 2:
-            raise AddressValueError(address)
-
-        self._ip = self._ip_int_from_string(addr[0])
-        self.ip = IPv6Address(self._ip)
-
-        if len(addr) == 2:
-            if self._is_valid_netmask(addr[1]):
-                self._prefixlen = int(addr[1])
-            else:
-                raise NetmaskValueError(addr[1])
-        else:
-            self._prefixlen = self._max_prefixlen
-
-        self.netmask = IPv6Address(self._ip_int_from_prefix(self._prefixlen))
-
-        if strict:
-            if self.ip != self.network:
-                raise ValueError('%s has host bits set' %
-                                 self.ip)
-        if self._prefixlen == (self._max_prefixlen - 1):
-            self.iterhosts = self.__iter__
-
-    def _is_valid_netmask(self, prefixlen):
-        """Verify that the netmask/prefixlen is valid.
-
-        Args:
-            prefixlen: A string, the netmask in prefix length format.
-
-        Returns:
-            A boolean, True if the prefix represents a valid IPv6
-            netmask.
-
-        """
-        try:
-            prefixlen = int(prefixlen)
-        except ValueError:
-            return False
-        return 0 <= prefixlen <= self._max_prefixlen
-
-    @property
-    def with_netmask(self):
-        return self.with_prefixlen
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/ipaddr_test.py b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/ipaddr_test.py
deleted file mode 100755
index 9446889..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/ipaddr_test.py
+++ /dev/null
@@ -1,1105 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2007 Google Inc.
-#  Licensed to PSF under a Contributor Agreement.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Unittest for ipaddr module."""
-
-
-import unittest
-import time
-import ipaddr
-
-# Compatibility function to cast str to bytes objects
-if issubclass(ipaddr.Bytes, str):
-    _cb = ipaddr.Bytes
-else:
-    _cb = lambda bytestr: bytes(bytestr, 'charmap')
-
-class IpaddrUnitTest(unittest.TestCase):
-
-    def setUp(self):
-        self.ipv4 = ipaddr.IPv4Network('1.2.3.4/24')
-        self.ipv4_hostmask = ipaddr.IPv4Network('10.0.0.1/0.255.255.255')
-        self.ipv6 = ipaddr.IPv6Network('2001:658:22a:cafe:200:0:0:1/64')
-
-    def tearDown(self):
-        del(self.ipv4)
-        del(self.ipv4_hostmask)
-        del(self.ipv6)
-        del(self)
-
-    def testRepr(self):
-        self.assertEqual("IPv4Network('1.2.3.4/32')",
-                         repr(ipaddr.IPv4Network('1.2.3.4')))
-        self.assertEqual("IPv6Network('::1/128')",
-                         repr(ipaddr.IPv6Network('::1')))
-
-    def testAutoMasking(self):
-        addr1 = ipaddr.IPv4Network('1.1.1.255/24')
-        addr1_masked = ipaddr.IPv4Network('1.1.1.0/24')
-        self.assertEqual(addr1_masked, addr1.masked())
-
-        addr2 = ipaddr.IPv6Network('2000:cafe::efac:100/96')
-        addr2_masked = ipaddr.IPv6Network('2000:cafe::/96')
-        self.assertEqual(addr2_masked, addr2.masked())
-
-    # issue57
-    def testAddressIntMath(self):
-        self.assertEqual(ipaddr.IPv4Address('1.1.1.1') + 255,
-                         ipaddr.IPv4Address('1.1.2.0'))
-        self.assertEqual(ipaddr.IPv4Address('1.1.1.1') - 256,
-                         ipaddr.IPv4Address('1.1.0.1'))
-        self.assertEqual(ipaddr.IPv6Address('::1') + (2**16 - 2),
-                         ipaddr.IPv6Address('::ffff'))
-        self.assertEqual(ipaddr.IPv6Address('::ffff') - (2**16 - 2),
-                         ipaddr.IPv6Address('::1'))
-
-    def testInvalidStrings(self):
-        def AssertInvalidIP(ip_str):
-            self.assertRaises(ValueError, ipaddr.IPAddress, ip_str)
-        AssertInvalidIP("")
-        AssertInvalidIP("016.016.016.016")
-        AssertInvalidIP("016.016.016")
-        AssertInvalidIP("016.016")
-        AssertInvalidIP("016")
-        AssertInvalidIP("000.000.000.000")
-        AssertInvalidIP("000")
-        AssertInvalidIP("0x0a.0x0a.0x0a.0x0a")
-        AssertInvalidIP("0x0a.0x0a.0x0a")
-        AssertInvalidIP("0x0a.0x0a")
-        AssertInvalidIP("0x0a")
-        AssertInvalidIP("42.42.42.42.42")
-        AssertInvalidIP("42.42.42")
-        AssertInvalidIP("42.42")
-        AssertInvalidIP("42")
-        AssertInvalidIP("42..42.42")
-        AssertInvalidIP("42..42.42.42")
-        AssertInvalidIP("42.42.42.42.")
-        AssertInvalidIP("42.42.42.42...")
-        AssertInvalidIP(".42.42.42.42")
-        AssertInvalidIP("...42.42.42.42")
-        AssertInvalidIP("42.42.42.-0")
-        AssertInvalidIP("42.42.42.+0")
-        AssertInvalidIP(".")
-        AssertInvalidIP("...")
-        AssertInvalidIP("bogus")
-        AssertInvalidIP("bogus.com")
-        AssertInvalidIP("192.168.0.1.com")
-        AssertInvalidIP("12345.67899.-54321.-98765")
-        AssertInvalidIP("257.0.0.0")
-        AssertInvalidIP("42.42.42.-42")
-        AssertInvalidIP("3ffe::1.net")
-        AssertInvalidIP("3ffe::1::1")
-        AssertInvalidIP("1::2::3::4:5")
-        AssertInvalidIP("::7:6:5:4:3:2:")
-        AssertInvalidIP(":6:5:4:3:2:1::")
-        AssertInvalidIP("2001::db:::1")
-        AssertInvalidIP("FEDC:9878")
-        AssertInvalidIP("+1.+2.+3.4")
-        AssertInvalidIP("1.2.3.4e0")
-        AssertInvalidIP("::7:6:5:4:3:2:1:0")
-        AssertInvalidIP("7:6:5:4:3:2:1:0::")
-        AssertInvalidIP("9:8:7:6:5:4:3::2:1")
-        AssertInvalidIP("0:1:2:3::4:5:6:7")
-        AssertInvalidIP("3ffe:0:0:0:0:0:0:0:1")
-        AssertInvalidIP("3ffe::10000")
-        AssertInvalidIP("3ffe::goog")
-        AssertInvalidIP("3ffe::-0")
-        AssertInvalidIP("3ffe::+0")
-        AssertInvalidIP("3ffe::-1")
-        AssertInvalidIP(":")
-        AssertInvalidIP(":::")
-        AssertInvalidIP("::1.2.3")
-        AssertInvalidIP("::1.2.3.4.5")
-        AssertInvalidIP("::1.2.3.4:")
-        AssertInvalidIP("1.2.3.4::")
-        AssertInvalidIP("2001:db8::1:")
-        AssertInvalidIP(":2001:db8::1")
-        AssertInvalidIP(":1:2:3:4:5:6:7")
-        AssertInvalidIP("1:2:3:4:5:6:7:")
-        AssertInvalidIP(":1:2:3:4:5:6:")
-        AssertInvalidIP("192.0.2.1/32")
-        AssertInvalidIP("2001:db8::1/128")
-
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network, '')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network,
-                          'google.com')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network,
-                          '::1.2.3.4')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network, '')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
-                          'google.com')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
-                          '1.2.3.4')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
-                          'cafe:cafe::/128/190')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
-                          '1234:axy::b')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Address,
-                          '1234:axy::b')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Address,
-                          '2001:db8:::1')
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Address,
-                          '2001:888888::1')
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv4Address(1)._ip_int_from_string,
-                          '1.a.2.3')
-        self.assertEqual(False, ipaddr.IPv4Network(1)._is_hostmask('1.a.2.3'))
-
-    def testGetNetwork(self):
-        self.assertEqual(int(self.ipv4.network), 16909056)
-        self.assertEqual(str(self.ipv4.network), '1.2.3.0')
-        self.assertEqual(str(self.ipv4_hostmask.network), '10.0.0.0')
-
-        self.assertEqual(int(self.ipv6.network),
-                         42540616829182469433403647294022090752)
-        self.assertEqual(str(self.ipv6.network),
-                         '2001:658:22a:cafe::')
-        self.assertEqual(str(self.ipv6.hostmask),
-                         '::ffff:ffff:ffff:ffff')
-
-    def testBadVersionComparison(self):
-        # These should always raise TypeError
-        v4addr = ipaddr.IPAddress('1.1.1.1')
-        v4net = ipaddr.IPNetwork('1.1.1.1')
-        v6addr = ipaddr.IPAddress('::1')
-        v6net = ipaddr.IPAddress('::1')
-
-        self.assertRaises(TypeError, v4addr.__lt__, v6addr)
-        self.assertRaises(TypeError, v4addr.__gt__, v6addr)
-        self.assertRaises(TypeError, v4net.__lt__, v6net)
-        self.assertRaises(TypeError, v4net.__gt__, v6net)
-
-        self.assertRaises(TypeError, v6addr.__lt__, v4addr)
-        self.assertRaises(TypeError, v6addr.__gt__, v4addr)
-        self.assertRaises(TypeError, v6net.__lt__, v4net)
-        self.assertRaises(TypeError, v6net.__gt__, v4net)
-
-    def testMixedTypeComparison(self):
-        v4addr = ipaddr.IPAddress('1.1.1.1')
-        v4net = ipaddr.IPNetwork('1.1.1.1/32')
-        v6addr = ipaddr.IPAddress('::1')
-        v6net = ipaddr.IPNetwork('::1/128')
-
-        self.assertFalse(v4net.__contains__(v6net))
-        self.assertFalse(v6net.__contains__(v4net))
-
-        self.assertRaises(TypeError, lambda: v4addr < v4net)
-        self.assertRaises(TypeError, lambda: v4addr > v4net)
-        self.assertRaises(TypeError, lambda: v4net < v4addr)
-        self.assertRaises(TypeError, lambda: v4net > v4addr)
-
-        self.assertRaises(TypeError, lambda: v6addr < v6net)
-        self.assertRaises(TypeError, lambda: v6addr > v6net)
-        self.assertRaises(TypeError, lambda: v6net < v6addr)
-        self.assertRaises(TypeError, lambda: v6net > v6addr)
-
-        # with get_mixed_type_key, you can sort addresses and network.
-        self.assertEqual([v4addr, v4net], sorted([v4net, v4addr],
-                                                 key=ipaddr.get_mixed_type_key))
-        self.assertEqual([v6addr, v6net], sorted([v6net, v6addr],
-                                                 key=ipaddr.get_mixed_type_key))
-
-    def testIpFromInt(self):
-        self.assertEqual(self.ipv4.ip, ipaddr.IPv4Network(16909060).ip)
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv4Network, 2**32)
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv4Network, -1)
-
-        ipv4 = ipaddr.IPNetwork('1.2.3.4')
-        ipv6 = ipaddr.IPNetwork('2001:658:22a:cafe:200:0:0:1')
-        self.assertEqual(ipv4, ipaddr.IPNetwork(int(ipv4)))
-        self.assertEqual(ipv6, ipaddr.IPNetwork(int(ipv6)))
-
-        v6_int = 42540616829182469433547762482097946625
-        self.assertEqual(self.ipv6.ip, ipaddr.IPv6Network(v6_int).ip)
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv6Network, 2**128)
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv6Network, -1)
-
-        self.assertEqual(ipaddr.IPNetwork(self.ipv4.ip).version, 4)
-        self.assertEqual(ipaddr.IPNetwork(self.ipv6.ip).version, 6)
-
-    def testIpFromPacked(self):
-        ip = ipaddr.IPNetwork
-
-        self.assertEqual(self.ipv4.ip,
-                         ip(_cb('\x01\x02\x03\x04')).ip)
-        self.assertEqual(ip('255.254.253.252'),
-                         ip(_cb('\xff\xfe\xfd\xfc')))
-        self.assertRaises(ValueError, ipaddr.IPNetwork, _cb('\x00' * 3))
-        self.assertRaises(ValueError, ipaddr.IPNetwork, _cb('\x00' * 5))
-        self.assertEqual(self.ipv6.ip,
-                         ip(_cb('\x20\x01\x06\x58\x02\x2a\xca\xfe'
-                           '\x02\x00\x00\x00\x00\x00\x00\x01')).ip)
-        self.assertEqual(ip('ffff:2:3:4:ffff::'),
-                         ip(_cb('\xff\xff\x00\x02\x00\x03\x00\x04' +
-                               '\xff\xff' + '\x00' * 6)))
-        self.assertEqual(ip('::'),
-                         ip(_cb('\x00' * 16)))
-        self.assertRaises(ValueError, ip, _cb('\x00' * 15))
-        self.assertRaises(ValueError, ip, _cb('\x00' * 17))
-
-    def testGetIp(self):
-        self.assertEqual(int(self.ipv4.ip), 16909060)
-        self.assertEqual(str(self.ipv4.ip), '1.2.3.4')
-        self.assertEqual(str(self.ipv4_hostmask.ip), '10.0.0.1')
-
-        self.assertEqual(int(self.ipv6.ip),
-                         42540616829182469433547762482097946625)
-        self.assertEqual(str(self.ipv6.ip),
-                         '2001:658:22a:cafe:200::1')
-
-    def testGetNetmask(self):
-        self.assertEqual(int(self.ipv4.netmask), 4294967040L)
-        self.assertEqual(str(self.ipv4.netmask), '255.255.255.0')
-        self.assertEqual(str(self.ipv4_hostmask.netmask), '255.0.0.0')
-        self.assertEqual(int(self.ipv6.netmask),
-                         340282366920938463444927863358058659840)
-        self.assertEqual(self.ipv6.prefixlen, 64)
-
-    def testZeroNetmask(self):
-        ipv4_zero_netmask = ipaddr.IPv4Network('1.2.3.4/0')
-        self.assertEqual(int(ipv4_zero_netmask.netmask), 0)
-        self.assertTrue(ipv4_zero_netmask._is_valid_netmask(str(0)))
-
-        ipv6_zero_netmask = ipaddr.IPv6Network('::1/0')
-        self.assertEqual(int(ipv6_zero_netmask.netmask), 0)
-        self.assertTrue(ipv6_zero_netmask._is_valid_netmask(str(0)))
-
-    def testGetBroadcast(self):
-        self.assertEqual(int(self.ipv4.broadcast), 16909311L)
-        self.assertEqual(str(self.ipv4.broadcast), '1.2.3.255')
-
-        self.assertEqual(int(self.ipv6.broadcast),
-                         42540616829182469451850391367731642367)
-        self.assertEqual(str(self.ipv6.broadcast),
-                         '2001:658:22a:cafe:ffff:ffff:ffff:ffff')
-
-    def testGetPrefixlen(self):
-        self.assertEqual(self.ipv4.prefixlen, 24)
-
-        self.assertEqual(self.ipv6.prefixlen, 64)
-
-    def testGetSupernet(self):
-        self.assertEqual(self.ipv4.supernet().prefixlen, 23)
-        self.assertEqual(str(self.ipv4.supernet().network), '1.2.2.0')
-        self.assertEqual(ipaddr.IPv4Network('0.0.0.0/0').supernet(),
-                         ipaddr.IPv4Network('0.0.0.0/0'))
-
-        self.assertEqual(self.ipv6.supernet().prefixlen, 63)
-        self.assertEqual(str(self.ipv6.supernet().network),
-                         '2001:658:22a:cafe::')
-        self.assertEqual(ipaddr.IPv6Network('::0/0').supernet(),
-                         ipaddr.IPv6Network('::0/0'))
-
-    def testGetSupernet3(self):
-        self.assertEqual(self.ipv4.supernet(3).prefixlen, 21)
-        self.assertEqual(str(self.ipv4.supernet(3).network), '1.2.0.0')
-
-        self.assertEqual(self.ipv6.supernet(3).prefixlen, 61)
-        self.assertEqual(str(self.ipv6.supernet(3).network),
-                         '2001:658:22a:caf8::')
-
-    def testGetSupernet4(self):
-        self.assertRaises(ValueError, self.ipv4.supernet, prefixlen_diff=2,
-                          new_prefix=1)
-        self.assertRaises(ValueError, self.ipv4.supernet, new_prefix=25)
-        self.assertEqual(self.ipv4.supernet(prefixlen_diff=2),
-                         self.ipv4.supernet(new_prefix=22))
-
-        self.assertRaises(ValueError, self.ipv6.supernet, prefixlen_diff=2,
-                          new_prefix=1)
-        self.assertRaises(ValueError, self.ipv6.supernet, new_prefix=65)
-        self.assertEqual(self.ipv6.supernet(prefixlen_diff=2),
-                         self.ipv6.supernet(new_prefix=62))
-
-    def testIterSubnets(self):
-        self.assertEqual(self.ipv4.subnet(), list(self.ipv4.iter_subnets()))
-        self.assertEqual(self.ipv6.subnet(), list(self.ipv6.iter_subnets()))
-
-    def testIterHosts(self):
-        self.assertEqual([ipaddr.IPv4Address('2.0.0.0'),
-                          ipaddr.IPv4Address('2.0.0.1')],
-                         list(ipaddr.IPNetwork('2.0.0.0/31').iterhosts()))
-
-    def testFancySubnetting(self):
-        self.assertEqual(sorted(self.ipv4.subnet(prefixlen_diff=3)),
-                         sorted(self.ipv4.subnet(new_prefix=27)))
-        self.assertRaises(ValueError, self.ipv4.subnet, new_prefix=23)
-        self.assertRaises(ValueError, self.ipv4.subnet,
-                          prefixlen_diff=3, new_prefix=27)
-        self.assertEqual(sorted(self.ipv6.subnet(prefixlen_diff=4)),
-                         sorted(self.ipv6.subnet(new_prefix=68)))
-        self.assertRaises(ValueError, self.ipv6.subnet, new_prefix=63)
-        self.assertRaises(ValueError, self.ipv6.subnet,
-                          prefixlen_diff=4, new_prefix=68)
-
-    def testGetSubnet(self):
-        self.assertEqual(self.ipv4.subnet()[0].prefixlen, 25)
-        self.assertEqual(str(self.ipv4.subnet()[0].network), '1.2.3.0')
-        self.assertEqual(str(self.ipv4.subnet()[1].network), '1.2.3.128')
-
-        self.assertEqual(self.ipv6.subnet()[0].prefixlen, 65)
-
-    def testGetSubnetForSingle32(self):
-        ip = ipaddr.IPv4Network('1.2.3.4/32')
-        subnets1 = [str(x) for x in ip.subnet()]
-        subnets2 = [str(x) for x in ip.subnet(2)]
-        self.assertEqual(subnets1, ['1.2.3.4/32'])
-        self.assertEqual(subnets1, subnets2)
-
-    def testGetSubnetForSingle128(self):
-        ip = ipaddr.IPv6Network('::1/128')
-        subnets1 = [str(x) for x in ip.subnet()]
-        subnets2 = [str(x) for x in ip.subnet(2)]
-        self.assertEqual(subnets1, ['::1/128'])
-        self.assertEqual(subnets1, subnets2)
-
-    def testSubnet2(self):
-        ips = [str(x) for x in self.ipv4.subnet(2)]
-        self.assertEqual(
-            ips,
-            ['1.2.3.0/26', '1.2.3.64/26', '1.2.3.128/26', '1.2.3.192/26'])
-
-        ipsv6 = [str(x) for x in self.ipv6.subnet(2)]
-        self.assertEqual(
-            ipsv6,
-            ['2001:658:22a:cafe::/66',
-             '2001:658:22a:cafe:4000::/66',
-             '2001:658:22a:cafe:8000::/66',
-             '2001:658:22a:cafe:c000::/66'])
-
-    def testSubnetFailsForLargeCidrDiff(self):
-        self.assertRaises(ValueError, self.ipv4.subnet, 9)
-        self.assertRaises(ValueError, self.ipv6.subnet, 65)
-
-    def testSupernetFailsForLargeCidrDiff(self):
-        self.assertRaises(ValueError, self.ipv4.supernet, 25)
-        self.assertRaises(ValueError, self.ipv6.supernet, 65)
-
-    def testSubnetFailsForNegativeCidrDiff(self):
-        self.assertRaises(ValueError, self.ipv4.subnet, -1)
-        self.assertRaises(ValueError, self.ipv6.subnet, -1)
-
-    def testGetNumHosts(self):
-        self.assertEqual(self.ipv4.numhosts, 256)
-        self.assertEqual(self.ipv4.subnet()[0].numhosts, 128)
-        self.assertEqual(self.ipv4.supernet().numhosts, 512)
-
-        self.assertEqual(self.ipv6.numhosts, 18446744073709551616)
-        self.assertEqual(self.ipv6.subnet()[0].numhosts, 9223372036854775808)
-        self.assertEqual(self.ipv6.supernet().numhosts, 36893488147419103232)
-
-    def testContains(self):
-        self.assertTrue(ipaddr.IPv4Network('1.2.3.128/25') in self.ipv4)
-        self.assertFalse(ipaddr.IPv4Network('1.2.4.1/24') in self.ipv4)
-        self.assertTrue(self.ipv4 in self.ipv4)
-        self.assertTrue(self.ipv6 in self.ipv6)
-        # We can test addresses and string as well.
-        addr1 = ipaddr.IPv4Address('1.2.3.37')
-        self.assertTrue(addr1 in self.ipv4)
-        # issue 61, bad network comparison on like-ip'd network objects
-        # with identical broadcast addresses.
-        self.assertFalse(ipaddr.IPv4Network('1.1.0.0/16').__contains__(
-                ipaddr.IPv4Network('1.0.0.0/15')))
-
-    def testBadAddress(self):
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv4Network,
-                          'poop')
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv4Network, '1.2.3.256')
-
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
-                          'poopv6')
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv4Network, '1.2.3.4/32/24')
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv4Network, '10/8')
-        self.assertRaises(ipaddr.AddressValueError,
-                          ipaddr.IPv6Network, '10/8')
-
-
-    def testBadNetMask(self):
-        self.assertRaises(ipaddr.NetmaskValueError,
-                          ipaddr.IPv4Network, '1.2.3.4/')
-        self.assertRaises(ipaddr.NetmaskValueError,
-                          ipaddr.IPv4Network, '1.2.3.4/33')
-        self.assertRaises(ipaddr.NetmaskValueError,
-                          ipaddr.IPv4Network, '1.2.3.4/254.254.255.256')
-        self.assertRaises(ipaddr.NetmaskValueError,
-                          ipaddr.IPv4Network, '1.1.1.1/240.255.0.0')
-        self.assertRaises(ipaddr.NetmaskValueError,
-                          ipaddr.IPv6Network, '::1/')
-        self.assertRaises(ipaddr.NetmaskValueError,
-                          ipaddr.IPv6Network, '::1/129')
-
-    def testNth(self):
-        self.assertEqual(str(self.ipv4[5]), '1.2.3.5')
-        self.assertRaises(IndexError, self.ipv4.__getitem__, 256)
-
-        self.assertEqual(str(self.ipv6[5]),
-                         '2001:658:22a:cafe::5')
-
-    def testGetitem(self):
-        # http://code.google.com/p/ipaddr-py/issues/detail?id=15
-        addr = ipaddr.IPv4Network('172.31.255.128/255.255.255.240')
-        self.assertEqual(28, addr.prefixlen)
-        addr_list = list(addr)
-        self.assertEqual('172.31.255.128', str(addr_list[0]))
-        self.assertEqual('172.31.255.128', str(addr[0]))
-        self.assertEqual('172.31.255.143', str(addr_list[-1]))
-        self.assertEqual('172.31.255.143', str(addr[-1]))
-        self.assertEqual(addr_list[-1], addr[-1])
-
-    def testEqual(self):
-        self.assertTrue(self.ipv4 == ipaddr.IPv4Network('1.2.3.4/24'))
-        self.assertFalse(self.ipv4 == ipaddr.IPv4Network('1.2.3.4/23'))
-        self.assertFalse(self.ipv4 == ipaddr.IPv6Network('::1.2.3.4/24'))
-        self.assertFalse(self.ipv4 == '')
-        self.assertFalse(self.ipv4 == [])
-        self.assertFalse(self.ipv4 == 2)
-        self.assertTrue(ipaddr.IPNetwork('1.1.1.1/32') ==
-                        ipaddr.IPAddress('1.1.1.1'))
-        self.assertTrue(ipaddr.IPNetwork('1.1.1.1/24') ==
-                        ipaddr.IPAddress('1.1.1.1'))
-        self.assertFalse(ipaddr.IPNetwork('1.1.1.0/24') ==
-                         ipaddr.IPAddress('1.1.1.1'))
-
-        self.assertTrue(self.ipv6 ==
-            ipaddr.IPv6Network('2001:658:22a:cafe:200::1/64'))
-        self.assertTrue(ipaddr.IPNetwork('::1/128') ==
-                        ipaddr.IPAddress('::1'))
-        self.assertTrue(ipaddr.IPNetwork('::1/127') ==
-                        ipaddr.IPAddress('::1'))
-        self.assertFalse(ipaddr.IPNetwork('::0/127') ==
-                         ipaddr.IPAddress('::1'))
-        self.assertFalse(self.ipv6 ==
-            ipaddr.IPv6Network('2001:658:22a:cafe:200::1/63'))
-        self.assertFalse(self.ipv6 == ipaddr.IPv4Network('1.2.3.4/23'))
-        self.assertFalse(self.ipv6 == '')
-        self.assertFalse(self.ipv6 == [])
-        self.assertFalse(self.ipv6 == 2)
-
-    def testNotEqual(self):
-        self.assertFalse(self.ipv4 != ipaddr.IPv4Network('1.2.3.4/24'))
-        self.assertTrue(self.ipv4 != ipaddr.IPv4Network('1.2.3.4/23'))
-        self.assertTrue(self.ipv4 != ipaddr.IPv6Network('::1.2.3.4/24'))
-        self.assertTrue(self.ipv4 != '')
-        self.assertTrue(self.ipv4 != [])
-        self.assertTrue(self.ipv4 != 2)
-
-        addr2 = ipaddr.IPAddress('2001:658:22a:cafe:200::1')
-        self.assertFalse(self.ipv6 !=
-            ipaddr.IPv6Network('2001:658:22a:cafe:200::1/64'))
-        self.assertTrue(self.ipv6 !=
-            ipaddr.IPv6Network('2001:658:22a:cafe:200::1/63'))
-        self.assertTrue(self.ipv6 != ipaddr.IPv4Network('1.2.3.4/23'))
-        self.assertTrue(self.ipv6 != '')
-        self.assertTrue(self.ipv6 != [])
-        self.assertTrue(self.ipv6 != 2)
-
-    def testSlash32Constructor(self):
-        self.assertEqual(str(ipaddr.IPv4Network('1.2.3.4/255.255.255.255')),
-                          '1.2.3.4/32')
-
-    def testSlash128Constructor(self):
-        self.assertEqual(str(ipaddr.IPv6Network('::1/128')),
-                                  '::1/128')
-
-    def testSlash0Constructor(self):
-        self.assertEqual(str(ipaddr.IPv4Network('1.2.3.4/0.0.0.0')),
-                          '1.2.3.4/0')
-
-    def testCollapsing(self):
-        # test only IP addresses including some duplicates
-        ip1 = ipaddr.IPv4Address('1.1.1.0')
-        ip2 = ipaddr.IPv4Address('1.1.1.1')
-        ip3 = ipaddr.IPv4Address('1.1.1.2')
-        ip4 = ipaddr.IPv4Address('1.1.1.3')
-        ip5 = ipaddr.IPv4Address('1.1.1.4')
-        ip6 = ipaddr.IPv4Address('1.1.1.0')
-        # check that addreses are subsumed properly.
-        collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3, ip4, ip5, ip6])
-        self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.1.0/30'),
-                                     ipaddr.IPv4Network('1.1.1.4/32')])
-
-        # test a mix of IP addresses and networks including some duplicates
-        ip1 = ipaddr.IPv4Address('1.1.1.0')
-        ip2 = ipaddr.IPv4Address('1.1.1.1')
-        ip3 = ipaddr.IPv4Address('1.1.1.2')
-        ip4 = ipaddr.IPv4Address('1.1.1.3')
-        ip5 = ipaddr.IPv4Network('1.1.1.4/30')
-        ip6 = ipaddr.IPv4Network('1.1.1.4/30')
-        # check that addreses are subsumed properly.
-        collapsed = ipaddr.collapse_address_list([ip5, ip1, ip2, ip3, ip4, ip6])
-        self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.1.0/29')])
-
-        # test only IP networks
-        ip1 = ipaddr.IPv4Network('1.1.0.0/24')
-        ip2 = ipaddr.IPv4Network('1.1.1.0/24')
-        ip3 = ipaddr.IPv4Network('1.1.2.0/24')
-        ip4 = ipaddr.IPv4Network('1.1.3.0/24')
-        ip5 = ipaddr.IPv4Network('1.1.4.0/24')
-        # stored in no particular order b/c we want CollapseAddr to call [].sort
-        ip6 = ipaddr.IPv4Network('1.1.0.0/22')
-        # check that addreses are subsumed properly.
-        collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3, ip4, ip5, ip6])
-        self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.0.0/22'),
-                                     ipaddr.IPv4Network('1.1.4.0/24')])
-
-        # test that two addresses are supernet'ed properly
-        collapsed = ipaddr.collapse_address_list([ip1, ip2])
-        self.assertEqual(collapsed, [ipaddr.IPv4Network('1.1.0.0/23')])
-
-        # test same IP networks
-        ip_same1 = ip_same2 = ipaddr.IPv4Network('1.1.1.1/32')
-        self.assertEqual(ipaddr.collapse_address_list([ip_same1, ip_same2]),
-                         [ip_same1])
-
-        # test same IP addresses
-        ip_same1 = ip_same2 = ipaddr.IPv4Address('1.1.1.1')
-        self.assertEqual(ipaddr.collapse_address_list([ip_same1, ip_same2]),
-                         [ipaddr.IPNetwork('1.1.1.1/32')])
-        ip1 = ipaddr.IPv6Network('::2001:1/100')
-        ip2 = ipaddr.IPv6Network('::2002:1/120')
-        ip3 = ipaddr.IPv6Network('::2001:1/96')
-        # test that ipv6 addresses are subsumed properly.
-        collapsed = ipaddr.collapse_address_list([ip1, ip2, ip3])
-        self.assertEqual(collapsed, [ip3])
-
-        # the toejam test
-        ip1 = ipaddr.IPAddress('1.1.1.1')
-        ip2 = ipaddr.IPAddress('::1')
-        self.assertRaises(TypeError, ipaddr.collapse_address_list,
-                          [ip1, ip2])
-
-    def testSummarizing(self):
-        #ip = ipaddr.IPAddress
-        #ipnet = ipaddr.IPNetwork
-        summarize = ipaddr.summarize_address_range
-        ip1 = ipaddr.IPAddress('1.1.1.0')
-        ip2 = ipaddr.IPAddress('1.1.1.255')
-        # test a /24 is sumamrized properly
-        self.assertEqual(summarize(ip1, ip2)[0], ipaddr.IPNetwork('1.1.1.0/24'))
-        # test an  IPv4 range that isn't on a network byte boundary
-        ip2 = ipaddr.IPAddress('1.1.1.8')
-        self.assertEqual(summarize(ip1, ip2), [ipaddr.IPNetwork('1.1.1.0/29'),
-                                               ipaddr.IPNetwork('1.1.1.8')])
-
-        ip1 = ipaddr.IPAddress('1::')
-        ip2 = ipaddr.IPAddress('1:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
-        # test a IPv6 is sumamrized properly
-        self.assertEqual(summarize(ip1, ip2)[0], ipaddr.IPNetwork('1::/16'))
-        # test an IPv6 range that isn't on a network byte boundary
-        ip2 = ipaddr.IPAddress('2::')
-        self.assertEqual(summarize(ip1, ip2), [ipaddr.IPNetwork('1::/16'),
-                                               ipaddr.IPNetwork('2::/128')])
-
-        # test exception raised when first is greater than last
-        self.assertRaises(ValueError, summarize, ipaddr.IPAddress('1.1.1.0'),
-            ipaddr.IPAddress('1.1.0.0'))
-        # test exception raised when first and last aren't IP addresses
-        self.assertRaises(TypeError, summarize,
-                          ipaddr.IPNetwork('1.1.1.0'),
-                          ipaddr.IPNetwork('1.1.0.0'))
-        self.assertRaises(TypeError, summarize,
-            ipaddr.IPNetwork('1.1.1.0'), ipaddr.IPNetwork('1.1.0.0'))
-        # test exception raised when first and last are not same version
-        self.assertRaises(TypeError, summarize, ipaddr.IPAddress('::'),
-            ipaddr.IPNetwork('1.1.0.0'))
-
-    def testAddressComparison(self):
-        self.assertTrue(ipaddr.IPAddress('1.1.1.1') <=
-                        ipaddr.IPAddress('1.1.1.1'))
-        self.assertTrue(ipaddr.IPAddress('1.1.1.1') <=
-                        ipaddr.IPAddress('1.1.1.2'))
-        self.assertTrue(ipaddr.IPAddress('::1') <= ipaddr.IPAddress('::1'))
-        self.assertTrue(ipaddr.IPAddress('::1') <= ipaddr.IPAddress('::2'))
-
-    def testNetworkComparison(self):
-        # ip1 and ip2 have the same network address
-        ip1 = ipaddr.IPv4Network('1.1.1.0/24')
-        ip2 = ipaddr.IPv4Network('1.1.1.1/24')
-        ip3 = ipaddr.IPv4Network('1.1.2.0/24')
-
-        self.assertTrue(ip1 < ip3)
-        self.assertTrue(ip3 > ip2)
-
-        self.assertEqual(ip1.compare_networks(ip2), 0)
-        self.assertTrue(ip1._get_networks_key() == ip2._get_networks_key())
-        self.assertEqual(ip1.compare_networks(ip3), -1)
-        self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
-
-        ip1 = ipaddr.IPv6Network('2001::2000/96')
-        ip2 = ipaddr.IPv6Network('2001::2001/96')
-        ip3 = ipaddr.IPv6Network('2001:ffff::2000/96')
-
-        self.assertTrue(ip1 < ip3)
-        self.assertTrue(ip3 > ip2)
-        self.assertEqual(ip1.compare_networks(ip2), 0)
-        self.assertTrue(ip1._get_networks_key() == ip2._get_networks_key())
-        self.assertEqual(ip1.compare_networks(ip3), -1)
-        self.assertTrue(ip1._get_networks_key() < ip3._get_networks_key())
-
-        # Test comparing different protocols.
-        # Should always raise a TypeError.
-        ipv6 = ipaddr.IPv6Network('::/0')
-        ipv4 = ipaddr.IPv4Network('0.0.0.0/0')
-        self.assertRaises(TypeError, ipv4.__lt__, ipv6)
-        self.assertRaises(TypeError, ipv4.__gt__, ipv6)
-        self.assertRaises(TypeError, ipv6.__lt__, ipv4)
-        self.assertRaises(TypeError, ipv6.__gt__, ipv4)
-
-        # Regression test for issue 19.
-        ip1 = ipaddr.IPNetwork('10.1.2.128/25')
-        self.assertFalse(ip1 < ip1)
-        self.assertFalse(ip1 > ip1)
-        ip2 = ipaddr.IPNetwork('10.1.3.0/24')
-        self.assertTrue(ip1 < ip2)
-        self.assertFalse(ip2 < ip1)
-        self.assertFalse(ip1 > ip2)
-        self.assertTrue(ip2 > ip1)
-        ip3 = ipaddr.IPNetwork('10.1.3.0/25')
-        self.assertTrue(ip2 < ip3)
-        self.assertFalse(ip3 < ip2)
-        self.assertFalse(ip2 > ip3)
-        self.assertTrue(ip3 > ip2)
-
-        # Regression test for issue 28.
-        ip1 = ipaddr.IPNetwork('10.10.10.0/31')
-        ip2 = ipaddr.IPNetwork('10.10.10.0')
-        ip3 = ipaddr.IPNetwork('10.10.10.2/31')
-        ip4 = ipaddr.IPNetwork('10.10.10.2')
-        sorted = [ip1, ip2, ip3, ip4]
-        unsorted = [ip2, ip4, ip1, ip3]
-        unsorted.sort()
-        self.assertEqual(sorted, unsorted)
-        unsorted = [ip4, ip1, ip3, ip2]
-        unsorted.sort()
-        self.assertEqual(sorted, unsorted)
-        self.assertRaises(TypeError, ip1.__lt__, ipaddr.IPAddress('10.10.10.0'))
-        self.assertRaises(TypeError, ip2.__lt__, ipaddr.IPAddress('10.10.10.0'))
-
-        # <=, >=
-        self.assertTrue(ipaddr.IPNetwork('1.1.1.1') <=
-                        ipaddr.IPNetwork('1.1.1.1'))
-        self.assertTrue(ipaddr.IPNetwork('1.1.1.1') <=
-                        ipaddr.IPNetwork('1.1.1.2'))
-        self.assertFalse(ipaddr.IPNetwork('1.1.1.2') <=
-                        ipaddr.IPNetwork('1.1.1.1'))
-        self.assertTrue(ipaddr.IPNetwork('::1') <= ipaddr.IPNetwork('::1'))
-        self.assertTrue(ipaddr.IPNetwork('::1') <= ipaddr.IPNetwork('::2'))
-        self.assertFalse(ipaddr.IPNetwork('::2') <= ipaddr.IPNetwork('::1'))
-
-    def testStrictNetworks(self):
-        self.assertRaises(ValueError, ipaddr.IPNetwork, '192.168.1.1/24',
-                          strict=True)
-        self.assertRaises(ValueError, ipaddr.IPNetwork, '::1/120', strict=True)
-
-    def testOverlaps(self):
-        other = ipaddr.IPv4Network('1.2.3.0/30')
-        other2 = ipaddr.IPv4Network('1.2.2.0/24')
-        other3 = ipaddr.IPv4Network('1.2.2.64/26')
-        self.assertTrue(self.ipv4.overlaps(other))
-        self.assertFalse(self.ipv4.overlaps(other2))
-        self.assertTrue(other2.overlaps(other3))
-
-    def testEmbeddedIpv4(self):
-        ipv4_string = '192.168.0.1'
-        ipv4 = ipaddr.IPv4Network(ipv4_string)
-        v4compat_ipv6 = ipaddr.IPv6Network('::%s' % ipv4_string)
-        self.assertEqual(int(v4compat_ipv6.ip), int(ipv4.ip))
-        v4mapped_ipv6 = ipaddr.IPv6Network('::ffff:%s' % ipv4_string)
-        self.assertNotEqual(v4mapped_ipv6.ip, ipv4.ip)
-        self.assertRaises(ipaddr.AddressValueError, ipaddr.IPv6Network,
-                          '2001:1.1.1.1:1.1.1.1')
-
-    # Issue 67: IPv6 with embedded IPv4 address not recognized.
-    def testIPv6AddressTooLarge(self):
-        # RFC4291 2.5.5.2
-        self.assertEqual(ipaddr.IPAddress('::FFFF:192.0.2.1'),
-                          ipaddr.IPAddress('::FFFF:c000:201'))
-        # RFC4291 2.2 (part 3) x::d.d.d.d 
-        self.assertEqual(ipaddr.IPAddress('FFFF::192.0.2.1'),
-                          ipaddr.IPAddress('FFFF::c000:201'))
-
-    def testIPVersion(self):
-        self.assertEqual(self.ipv4.version, 4)
-        self.assertEqual(self.ipv6.version, 6)
-
-    def testMaxPrefixLength(self):
-        self.assertEqual(self.ipv4.max_prefixlen, 32)
-        self.assertEqual(self.ipv6.max_prefixlen, 128)
-
-    def testPacked(self):
-        self.assertEqual(self.ipv4.packed,
-                         _cb('\x01\x02\x03\x04'))
-        self.assertEqual(ipaddr.IPv4Network('255.254.253.252').packed,
-                         _cb('\xff\xfe\xfd\xfc'))
-        self.assertEqual(self.ipv6.packed,
-                         _cb('\x20\x01\x06\x58\x02\x2a\xca\xfe'
-                             '\x02\x00\x00\x00\x00\x00\x00\x01'))
-        self.assertEqual(ipaddr.IPv6Network('ffff:2:3:4:ffff::').packed,
-                         _cb('\xff\xff\x00\x02\x00\x03\x00\x04\xff\xff'
-                            + '\x00' * 6))
-        self.assertEqual(ipaddr.IPv6Network('::1:0:0:0:0').packed,
-                         _cb('\x00' * 6 + '\x00\x01' + '\x00' * 8))
-
-    def testIpStrFromPrefixlen(self):
-        ipv4 = ipaddr.IPv4Network('1.2.3.4/24')
-        self.assertEqual(ipv4._ip_string_from_prefix(), '255.255.255.0')
-        self.assertEqual(ipv4._ip_string_from_prefix(28), '255.255.255.240')
-
-    def testIpType(self):
-        ipv4net = ipaddr.IPNetwork('1.2.3.4')
-        ipv4addr = ipaddr.IPAddress('1.2.3.4')
-        ipv6net = ipaddr.IPNetwork('::1.2.3.4')
-        ipv6addr = ipaddr.IPAddress('::1.2.3.4')
-        self.assertEqual(ipaddr.IPv4Network, type(ipv4net))
-        self.assertEqual(ipaddr.IPv4Address, type(ipv4addr))
-        self.assertEqual(ipaddr.IPv6Network, type(ipv6net))
-        self.assertEqual(ipaddr.IPv6Address, type(ipv6addr))
-
-    def testReservedIpv4(self):
-        # test networks
-        self.assertEqual(True, ipaddr.IPNetwork('224.1.1.1/31').is_multicast)
-        self.assertEqual(False, ipaddr.IPNetwork('240.0.0.0').is_multicast)
-
-        self.assertEqual(True, ipaddr.IPNetwork('192.168.1.1/17').is_private)
-        self.assertEqual(False, ipaddr.IPNetwork('192.169.0.0').is_private)
-        self.assertEqual(True, ipaddr.IPNetwork('10.255.255.255').is_private)
-        self.assertEqual(False, ipaddr.IPNetwork('11.0.0.0').is_private)
-        self.assertEqual(True, ipaddr.IPNetwork('172.31.255.255').is_private)
-        self.assertEqual(False, ipaddr.IPNetwork('172.32.0.0').is_private)
-
-        self.assertEqual(True,
-                          ipaddr.IPNetwork('169.254.100.200/24').is_link_local)
-        self.assertEqual(False,
-                          ipaddr.IPNetwork('169.255.100.200/24').is_link_local)
-
-        self.assertEqual(True,
-                          ipaddr.IPNetwork('127.100.200.254/32').is_loopback)
-        self.assertEqual(True, ipaddr.IPNetwork('127.42.0.0/16').is_loopback)
-        self.assertEqual(False, ipaddr.IPNetwork('128.0.0.0').is_loopback)
-
-        # test addresses
-        self.assertEqual(True, ipaddr.IPAddress('224.1.1.1').is_multicast)
-        self.assertEqual(False, ipaddr.IPAddress('240.0.0.0').is_multicast)
-
-        self.assertEqual(True, ipaddr.IPAddress('192.168.1.1').is_private)
-        self.assertEqual(False, ipaddr.IPAddress('192.169.0.0').is_private)
-        self.assertEqual(True, ipaddr.IPAddress('10.255.255.255').is_private)
-        self.assertEqual(False, ipaddr.IPAddress('11.0.0.0').is_private)
-        self.assertEqual(True, ipaddr.IPAddress('172.31.255.255').is_private)
-        self.assertEqual(False, ipaddr.IPAddress('172.32.0.0').is_private)
-
-        self.assertEqual(True,
-                          ipaddr.IPAddress('169.254.100.200').is_link_local)
-        self.assertEqual(False,
-                          ipaddr.IPAddress('169.255.100.200').is_link_local)
-
-        self.assertEqual(True,
-                          ipaddr.IPAddress('127.100.200.254').is_loopback)
-        self.assertEqual(True, ipaddr.IPAddress('127.42.0.0').is_loopback)
-        self.assertEqual(False, ipaddr.IPAddress('128.0.0.0').is_loopback)
-        self.assertEqual(True, ipaddr.IPNetwork('0.0.0.0').is_unspecified)
-
-    def testReservedIpv6(self):
-
-        self.assertEqual(True, ipaddr.IPNetwork('ffff::').is_multicast)
-        self.assertEqual(True, ipaddr.IPNetwork(2**128-1).is_multicast)
-        self.assertEqual(True, ipaddr.IPNetwork('ff00::').is_multicast)
-        self.assertEqual(False, ipaddr.IPNetwork('fdff::').is_multicast)
-
-        self.assertEqual(True, ipaddr.IPNetwork('fecf::').is_site_local)
-        self.assertEqual(True, ipaddr.IPNetwork(
-                'feff:ffff:ffff:ffff::').is_site_local)
-        self.assertEqual(False, ipaddr.IPNetwork('fbf:ffff::').is_site_local)
-        self.assertEqual(False, ipaddr.IPNetwork('ff00::').is_site_local)
-
-        self.assertEqual(True, ipaddr.IPNetwork('fc00::').is_private)
-        self.assertEqual(True, ipaddr.IPNetwork(
-                'fc00:ffff:ffff:ffff::').is_private)
-        self.assertEqual(False, ipaddr.IPNetwork('fbff:ffff::').is_private)
-        self.assertEqual(False, ipaddr.IPNetwork('fe00::').is_private)
-
-        self.assertEqual(True, ipaddr.IPNetwork('fea0::').is_link_local)
-        self.assertEqual(True, ipaddr.IPNetwork('febf:ffff::').is_link_local)
-        self.assertEqual(False, ipaddr.IPNetwork('fe7f:ffff::').is_link_local)
-        self.assertEqual(False, ipaddr.IPNetwork('fec0::').is_link_local)
-
-        self.assertEqual(True, ipaddr.IPNetwork('0:0::0:01').is_loopback)
-        self.assertEqual(False, ipaddr.IPNetwork('::1/127').is_loopback)
-        self.assertEqual(False, ipaddr.IPNetwork('::').is_loopback)
-        self.assertEqual(False, ipaddr.IPNetwork('::2').is_loopback)
-
-        self.assertEqual(True, ipaddr.IPNetwork('0::0').is_unspecified)
-        self.assertEqual(False, ipaddr.IPNetwork('::1').is_unspecified)
-        self.assertEqual(False, ipaddr.IPNetwork('::/127').is_unspecified)
-
-        # test addresses
-        self.assertEqual(True, ipaddr.IPAddress('ffff::').is_multicast)
-        self.assertEqual(True, ipaddr.IPAddress(2**128-1).is_multicast)
-        self.assertEqual(True, ipaddr.IPAddress('ff00::').is_multicast)
-        self.assertEqual(False, ipaddr.IPAddress('fdff::').is_multicast)
-
-        self.assertEqual(True, ipaddr.IPAddress('fecf::').is_site_local)
-        self.assertEqual(True, ipaddr.IPAddress(
-                'feff:ffff:ffff:ffff::').is_site_local)
-        self.assertEqual(False, ipaddr.IPAddress('fbf:ffff::').is_site_local)
-        self.assertEqual(False, ipaddr.IPAddress('ff00::').is_site_local)
-
-        self.assertEqual(True, ipaddr.IPAddress('fc00::').is_private)
-        self.assertEqual(True, ipaddr.IPAddress(
-                'fc00:ffff:ffff:ffff::').is_private)
-        self.assertEqual(False, ipaddr.IPAddress('fbff:ffff::').is_private)
-        self.assertEqual(False, ipaddr.IPAddress('fe00::').is_private)
-
-        self.assertEqual(True, ipaddr.IPAddress('fea0::').is_link_local)
-        self.assertEqual(True, ipaddr.IPAddress('febf:ffff::').is_link_local)
-        self.assertEqual(False, ipaddr.IPAddress('fe7f:ffff::').is_link_local)
-        self.assertEqual(False, ipaddr.IPAddress('fec0::').is_link_local)
-
-        self.assertEqual(True, ipaddr.IPAddress('0:0::0:01').is_loopback)
-        self.assertEqual(True, ipaddr.IPAddress('::1').is_loopback)
-        self.assertEqual(False, ipaddr.IPAddress('::2').is_loopback)
-
-        self.assertEqual(True, ipaddr.IPAddress('0::0').is_unspecified)
-        self.assertEqual(False, ipaddr.IPAddress('::1').is_unspecified)
-
-        # some generic IETF reserved addresses
-        self.assertEqual(True, ipaddr.IPAddress('100::').is_reserved)
-        self.assertEqual(True, ipaddr.IPNetwork('4000::1/128').is_reserved)
-
-    def testIpv4Mapped(self):
-        self.assertEqual(ipaddr.IPAddress('::ffff:192.168.1.1').ipv4_mapped,
-                         ipaddr.IPAddress('192.168.1.1'))
-        self.assertEqual(ipaddr.IPAddress('::c0a8:101').ipv4_mapped, None)
-        self.assertEqual(ipaddr.IPAddress('::ffff:c0a8:101').ipv4_mapped,
-                         ipaddr.IPAddress('192.168.1.1'))
-
-    def testAddrExclude(self):
-        addr1 = ipaddr.IPNetwork('10.1.1.0/24')
-        addr2 = ipaddr.IPNetwork('10.1.1.0/26')
-        addr3 = ipaddr.IPNetwork('10.2.1.0/24')
-        addr4 = ipaddr.IPAddress('10.1.1.0')
-        self.assertEqual(addr1.address_exclude(addr2),
-                         [ipaddr.IPNetwork('10.1.1.64/26'),
-                          ipaddr.IPNetwork('10.1.1.128/25')])
-        self.assertRaises(ValueError, addr1.address_exclude, addr3)
-        self.assertRaises(TypeError, addr1.address_exclude, addr4)
-        self.assertEqual(addr1.address_exclude(addr1), [])
-
-    def testHash(self):
-        self.assertEqual(hash(ipaddr.IPNetwork('10.1.1.0/24')),
-                          hash(ipaddr.IPNetwork('10.1.1.0/24')))
-        self.assertEqual(hash(ipaddr.IPAddress('10.1.1.0')),
-                          hash(ipaddr.IPAddress('10.1.1.0')))
-        # i70
-        self.assertEqual(hash(ipaddr.IPAddress('1.2.3.4')),
-                          hash(ipaddr.IPAddress(
-                    long(ipaddr.IPAddress('1.2.3.4')._ip))))
-        ip1 = ipaddr.IPAddress('10.1.1.0')
-        ip2 = ipaddr.IPAddress('1::')
-        dummy = {}
-        dummy[self.ipv4] = None
-        dummy[self.ipv6] = None
-        dummy[ip1] = None
-        dummy[ip2] = None
-        self.assertTrue(self.ipv4 in dummy)
-        self.assertTrue(ip2 in dummy)
-
-    def testCopyConstructor(self):
-        addr1 = ipaddr.IPNetwork('10.1.1.0/24')
-        addr2 = ipaddr.IPNetwork(addr1)
-        addr3 = ipaddr.IPNetwork('2001:658:22a:cafe:200::1/64')
-        addr4 = ipaddr.IPNetwork(addr3)
-        addr5 = ipaddr.IPv4Address('1.1.1.1')
-        addr6 = ipaddr.IPv6Address('2001:658:22a:cafe:200::1')
-
-        self.assertEqual(addr1, addr2)
-        self.assertEqual(addr3, addr4)
-        self.assertEqual(addr5, ipaddr.IPv4Address(addr5))
-        self.assertEqual(addr6, ipaddr.IPv6Address(addr6))
-
-    def testCompressIPv6Address(self):
-        test_addresses = {
-            '1:2:3:4:5:6:7:8': '1:2:3:4:5:6:7:8/128',
-            '2001:0:0:4:0:0:0:8': '2001:0:0:4::8/128',
-            '2001:0:0:4:5:6:7:8': '2001::4:5:6:7:8/128',
-            '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
-            '2001:0:3:4:5:6:7:8': '2001:0:3:4:5:6:7:8/128',
-            '0:0:3:0:0:0:0:ffff': '0:0:3::ffff/128',
-            '0:0:0:4:0:0:0:ffff': '::4:0:0:0:ffff/128',
-            '0:0:0:0:5:0:0:ffff': '::5:0:0:ffff/128',
-            '1:0:0:4:0:0:7:8': '1::4:0:0:7:8/128',
-            '0:0:0:0:0:0:0:0': '::/128',
-            '0:0:0:0:0:0:0:0/0': '::/0',
-            '0:0:0:0:0:0:0:1': '::1/128',
-            '2001:0658:022a:cafe:0000:0000:0000:0000/66':
-            '2001:658:22a:cafe::/66',
-            '::1.2.3.4': '::102:304/128',
-            '1:2:3:4:5:ffff:1.2.3.4': '1:2:3:4:5:ffff:102:304/128',
-            '::7:6:5:4:3:2:1': '0:7:6:5:4:3:2:1/128',
-            '::7:6:5:4:3:2:0': '0:7:6:5:4:3:2:0/128',
-            '7:6:5:4:3:2:1::': '7:6:5:4:3:2:1:0/128',
-            '0:6:5:4:3:2:1::': '0:6:5:4:3:2:1:0/128',
-            }
-        for uncompressed, compressed in test_addresses.items():
-            self.assertEqual(compressed, str(ipaddr.IPv6Network(uncompressed)))
-
-    def testExplodeShortHandIpStr(self):
-        addr1 = ipaddr.IPv6Network('2001::1')
-        addr2 = ipaddr.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
-        self.assertEqual('2001:0000:0000:0000:0000:0000:0000:0001/128',
-                         addr1.exploded)
-        self.assertEqual('0000:0000:0000:0000:0000:0000:0000:0001/128',
-                         ipaddr.IPv6Network('::1/128').exploded)
-        # issue 77
-        self.assertEqual('2001:0000:5ef5:79fd:0000:059d:a0e5:0ba1',
-                         addr2.exploded)
-
-    def testIntRepresentation(self):
-        self.assertEqual(16909060, int(self.ipv4))
-        self.assertEqual(42540616829182469433547762482097946625, int(self.ipv6))
-
-    def testHexRepresentation(self):
-        self.assertEqual(hex(0x1020304),
-                         hex(self.ipv4))
-
-        self.assertEqual(hex(0x20010658022ACAFE0200000000000001),
-                         hex(self.ipv6))
-
-    # backwards compatibility
-    def testBackwardsCompability(self):
-        self.assertEqual(ipaddr.CollapseAddrList(
-            [ipaddr.IPNetwork('1.1.0.0/24'), ipaddr.IPNetwork('1.1.1.0/24')]),
-                         [ipaddr.IPNetwork('1.1.0.0/23')])
-
-        self.assertEqual(ipaddr.IPNetwork('::42:0/112').AddressExclude(
-            ipaddr.IPNetwork('::42:8000/113')),
-                         [ipaddr.IPNetwork('::42:0/113')])
-
-        self.assertTrue(ipaddr.IPNetwork('1::/8').CompareNetworks(
-            ipaddr.IPNetwork('2::/9')) < 0)
-
-        self.assertEqual(ipaddr.IPNetwork('1::/16').Contains(
-            ipaddr.IPNetwork('2::/16')), False)
-
-        self.assertEqual(ipaddr.IPNetwork('0.0.0.0/0').Subnet(),
-                         [ipaddr.IPNetwork('0.0.0.0/1'),
-                          ipaddr.IPNetwork('128.0.0.0/1')])
-        self.assertEqual(ipaddr.IPNetwork('::/127').Subnet(),
-                         [ipaddr.IPNetwork('::/128'),
-                          ipaddr.IPNetwork('::1/128')])
-
-        self.assertEqual(ipaddr.IPNetwork('1.0.0.0/32').Supernet(),
-                         ipaddr.IPNetwork('1.0.0.0/31'))
-        self.assertEqual(ipaddr.IPNetwork('::/121').Supernet(),
-                         ipaddr.IPNetwork('::/120'))
-
-        self.assertEqual(ipaddr.IPNetwork('10.0.0.2').IsRFC1918(), True)
-        self.assertEqual(ipaddr.IPNetwork('10.0.0.0').IsMulticast(), False)
-        self.assertEqual(ipaddr.IPNetwork('127.255.255.255').IsLoopback(), True)
-        self.assertEqual(ipaddr.IPNetwork('169.255.255.255').IsLinkLocal(),
-                         False)
-
-    def testForceVersion(self):
-        self.assertEqual(ipaddr.IPNetwork(1).version, 4)
-        self.assertEqual(ipaddr.IPNetwork(1, version=6).version, 6)
-
-    def testWithStar(self):
-        self.assertEqual(str(self.ipv4.with_prefixlen), "1.2.3.4/24")
-        self.assertEqual(str(self.ipv4.with_netmask), "1.2.3.4/255.255.255.0")
-        self.assertEqual(str(self.ipv4.with_hostmask), "1.2.3.4/0.0.0.255")
-
-        self.assertEqual(str(self.ipv6.with_prefixlen),
-                         '2001:658:22a:cafe:200::1/64')
-        # rfc3513 sec 2.3 says that ipv6 only uses cidr notation for
-        # subnets
-        self.assertEqual(str(self.ipv6.with_netmask),
-                         '2001:658:22a:cafe:200::1/64')
-        # this probably don't make much sense, but it's included for
-        # compatibility with ipv4
-        self.assertEqual(str(self.ipv6.with_hostmask),
-                         '2001:658:22a:cafe:200::1/::ffff:ffff:ffff:ffff')
-
-    def testNetworkElementCaching(self):
-        # V4 - make sure we're empty
-        self.assertFalse(self.ipv4._cache.has_key('network'))
-        self.assertFalse(self.ipv4._cache.has_key('broadcast'))
-        self.assertFalse(self.ipv4._cache.has_key('hostmask'))
-
-        # V4 - populate and test
-        self.assertEqual(self.ipv4.network, ipaddr.IPv4Address('1.2.3.0'))
-        self.assertEqual(self.ipv4.broadcast, ipaddr.IPv4Address('1.2.3.255'))
-        self.assertEqual(self.ipv4.hostmask, ipaddr.IPv4Address('0.0.0.255'))
-
-        # V4 - check we're cached
-        self.assertTrue(self.ipv4._cache.has_key('network'))
-        self.assertTrue(self.ipv4._cache.has_key('broadcast'))
-        self.assertTrue(self.ipv4._cache.has_key('hostmask'))
-
-        # V6 - make sure we're empty
-        self.assertFalse(self.ipv6._cache.has_key('network'))
-        self.assertFalse(self.ipv6._cache.has_key('broadcast'))
-        self.assertFalse(self.ipv6._cache.has_key('hostmask'))
-
-        # V6 - populate and test
-        self.assertEqual(self.ipv6.network,
-                         ipaddr.IPv6Address('2001:658:22a:cafe::'))
-        self.assertEqual(self.ipv6.broadcast, ipaddr.IPv6Address(
-            '2001:658:22a:cafe:ffff:ffff:ffff:ffff'))
-        self.assertEqual(self.ipv6.hostmask,
-                         ipaddr.IPv6Address('::ffff:ffff:ffff:ffff'))
-
-        # V6 - check we're cached
-        self.assertTrue(self.ipv6._cache.has_key('network'))
-        self.assertTrue(self.ipv6._cache.has_key('broadcast'))
-        self.assertTrue(self.ipv6._cache.has_key('hostmask'))
-
-    def testTeredo(self):
-        # stolen from wikipedia
-        server = ipaddr.IPv4Address('65.54.227.120')
-        client = ipaddr.IPv4Address('192.0.2.45')
-        teredo_addr = '2001:0000:4136:e378:8000:63bf:3fff:fdd2'
-        self.assertEqual((server, client),
-                         ipaddr.IPAddress(teredo_addr).teredo)
-        bad_addr = '2000::4136:e378:8000:63bf:3fff:fdd2'
-        self.assertFalse(ipaddr.IPAddress(bad_addr).teredo)
-        bad_addr = '2001:0001:4136:e378:8000:63bf:3fff:fdd2'
-        self.assertFalse(ipaddr.IPAddress(bad_addr).teredo)
-
-        # i77
-        teredo_addr = ipaddr.IPv6Address('2001:0:5ef5:79fd:0:59d:a0e5:ba1')
-        self.assertEqual((ipaddr.IPv4Address('94.245.121.253'),
-                          ipaddr.IPv4Address('95.26.244.94')),
-                         teredo_addr.teredo)
-
-
-    def testsixtofour(self):
-        sixtofouraddr = ipaddr.IPAddress('2002:ac1d:2d64::1')
-        bad_addr = ipaddr.IPAddress('2000:ac1d:2d64::1')
-        self.assertEqual(ipaddr.IPv4Address('172.29.45.100'),
-                         sixtofouraddr.sixtofour)
-        self.assertFalse(bad_addr.sixtofour)
-
-
-if __name__ == '__main__':
-    unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/setup.py b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/setup.py
deleted file mode 100755
index 3356432..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/setup.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/python
-#
-# Copyright 2008 Google Inc.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from distutils.core import setup
-
-import ipaddr
-
-
-setup(name='ipaddr',
-      maintainer='Google',
-      maintainer_email='ipaddr-py-dev@googlegroups.com',
-      version=ipaddr.__version__,
-      url='http://code.google.com/p/ipaddr-py/',
-      license='Apache License, Version 2.0',
-      classifiers=[
-          'Development Status :: 5 - Production/Stable',
-          'Intended Audience :: Developers',
-          'License :: OSI Approved :: Apache Software License',
-          'Operating System :: OS Independent',
-          'Topic :: Internet',
-          'Topic :: Software Development :: Libraries',
-          'Topic :: System :: Networking'],
-      py_modules=['ipaddr'])
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/test-2to3.sh b/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/test-2to3.sh
deleted file mode 100755
index 5196083..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipaddr/test-2to3.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-#!/bin/sh
-# Copyright 2007 Google Inc.
-#  Licensed to PSF under a Contributor Agreement.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
-# implied. See the License for the specific language governing
-# permissions and limitations under the License.
-#
-# Converts the python2 ipaddr files to python3 and runs the unit tests
-# with both python versions.
-
-mkdir -p 2to3output && \
-cp -f *.py 2to3output && \
-( cd 2to3output && 2to3 . | patch -p0 ) && \
-py3version=$(python3 --version 2>&1) && \
-echo -e "\nTesting with ${py3version}" && \
-python3 2to3output/ipaddr_test.py && \
-rm -r 2to3output && \
-pyversion=$(python --version 2>&1) && \
-echo -e "\nTesting with ${pyversion}" && \
-./ipaddr_test.py
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/LICENSE b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/LICENSE
deleted file mode 100644
index c1df6fe..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/LICENSE
+++ /dev/null
@@ -1,25 +0,0 @@
-/*-
- * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa
- * All rights reserved
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/README.txt b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/README.txt
deleted file mode 100644
index 3dae853..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/README.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-This directory contains the binaries to install and use IPFW and
-DUMMYNET on a Windows Machine. The kernel part is an NDIS module,
-whereas the user interface is a command line program.
-
-1. INSTALL THE NDIS DRIVER
-
-- open the configuration panel for the network card in use
-  (either right click on the icon on the SYSTRAY, or go to
-  Control Panel -> Network and select one card)
-
-- click on Properties->Install->Service->Add
-- click on 'Driver Disk' and select 'netipfw.inf' in this folder
-- select 'ipfw+dummynet' which is the only service you should see
-- click accept on the warnings for the installation of an unknown
-  driver (roughly twice per existing network card)
-
-Now you are ready to use the emulator. To configure it, open a 'cmd'
-window and you can use the ipfw command from the command line.
-Otherwise click on the 'TESTME.bat' which is a batch program that
-runs various tests.
-
-2. UNINSTALL THE DRIVER
-
-- select a network card as above.
-- click on Properties
-- select 'ipfw+dummynet'
-- click on 'Remove'
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/README.web-page-replay b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/README.web-page-replay
deleted file mode 100644
index 8bf15c6..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/README.web-page-replay
+++ /dev/null
@@ -1,12 +0,0 @@
-Name: Windows XP NDIS module for Dummynet.
-Short Name: ipfw3
-URL: http://info.iet.unipi.it/~luigi/dummynet/
-Version: 20100322 v.3.0.0.2
-License: BSD
-License File: LICENSE
-
-Description:
-Used by Web Page Replay to simulate network delays and bandwidth throttling on Windows XP.
-
-Local Modifications:
-Dropped files: cyg-ipfw.exe, cygwin1.dll, testme.bat, wget.exe.
\ No newline at end of file
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/ipfw.exe b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/ipfw.exe
deleted file mode 100644
index 2ab5c3f..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/ipfw.exe
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/ipfw.sys b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/ipfw.sys
deleted file mode 100644
index d5e1b9f..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/ipfw.sys
+++ /dev/null
Binary files differ
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/netipfw.inf b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/netipfw.inf
deleted file mode 100644
index 11ec684..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/netipfw.inf
+++ /dev/null
@@ -1,79 +0,0 @@
-; version section
-[Version]
-Signature  = "$Windows NT$"
-Class      = NetService
-ClassGUID  = {4D36E974-E325-11CE-BFC1-08002BE10318}
-Provider   = %Unipi%
-DriverVer  = 26/02/2010,3.0.0.2
-
-; manufacturer section
-[Manufacturer]
-%Unipi% = UNIPI,NTx86
-
-; control flags section
-; optional, unused in netipfw.inf inf, used in netipfw_m.inf
-[ControlFlags]
-
-; models section
-[UNIPI] ; Win2k
-%Desc% = Ipfw.ndi, unipi_ipfw
-[UNIPI.NTx86] ;For WinXP and later
-%Desc% = Ipfw.ndi, unipi_ipfw
-
-; ddinstall section
-[Ipfw.ndi]
-AddReg          = Ipfw.ndi.AddReg, Ipfw.AddReg
-Characteristics = 0x4410 ;  NCF_FILTER | NCF_NDIS_PROTOCOL !--Filter Specific--!!
-CopyFiles       = Ipfw.Files.Sys
-CopyInf         = netipfw_m.inf
-
-; remove section
-[Ipfw.ndi.Remove]
-DelFiles = Ipfw.Files.Sys
-
-;ddinstall.services section
-[Ipfw.ndi.Services]
-AddService = Ipfw,,Ipfw.AddService
-
-[Ipfw.AddService]
-DisplayName    = %ServiceDesc%
-ServiceType    = 1 ;SERVICE_KERNEL_DRIVER
-StartType      = 3 ;SERVICE_DEMAND_START
-ErrorControl   = 1 ;SERVICE_ERROR_NORMAL
-ServiceBinary  = %12%\ipfw.sys
-AddReg         = Ipfw.AddService.AddReg
-
-[Ipfw.AddService.AddReg]
-
-;file copy related sections
-[SourceDisksNames]
-1=%DiskDescription%,"",,
-
-[SourceDisksFiles]
-ipfw.sys=1
-
-[DestinationDirs]
-DefaultDestDir = 12
-Ipfw.Files.Sys   = 12   ; %windir%\System32\drivers
-
-; ddinstall->copyfiles points here
-[Ipfw.Files.Sys]
-ipfw.sys,,,2
-
-; ddinstall->addreg points here
-[Ipfw.ndi.AddReg]
-HKR, Ndi,            HelpText,            , %HELP% ; this is displayed at the bottom of the General page of the Connection Properties dialog box
-HKR, Ndi,            FilterClass,         , failover
-HKR, Ndi,            FilterDeviceInfId,   , unipi_ipfwmp
-HKR, Ndi,            Service,             , Ipfw
-HKR, Ndi\Interfaces, UpperRange,          , noupper
-HKR, Ndi\Interfaces, LowerRange,          , nolower
-HKR, Ndi\Interfaces, FilterMediaTypes,    , "ethernet, tokenring, fddi, wan"
-
-;strings section
-[Strings]
-Unipi = "Unipi"
-DiskDescription = "Ipfw Driver Disk"
-Desc = "ipfw+dummynet"
-HELP = "This is ipfw and dummynet network emulator, developed by unipi.it"
-ServiceDesc = "ipfw service"
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/netipfw_m.inf b/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/netipfw_m.inf
deleted file mode 100644
index 864559f..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/ipfw_win32/netipfw_m.inf
+++ /dev/null
@@ -1,54 +0,0 @@
-; version section
-[Version]
-Signature  = "$Windows NT$"
-Class      = Net
-ClassGUID  = {4D36E972-E325-11CE-BFC1-08002BE10318}
-Provider   = %Unipi%
-DriverVer  = 26/02/2010,3.0.0.2
-
-; control flags section
-; optional, unused in netipfw.inf inf, used in netipfw_m.inf
-[ControlFlags]
-ExcludeFromSelect = unipi_ipfwmp
-
-; destinationdirs section, optional
-[DestinationDirs]
-DefaultDestDir=12
-; No files to copy 
-
-; manufacturer section
-[Manufacturer]
-%Unipi% = UNIPI,NTx86
-
-; models section
-[UNIPI] ; Win2k
-%Desc% = IpfwMP.ndi, unipi_ipfwmp
-[UNIPI.NTx86] ;For WinXP and later
-%Desc% = IpfwMP.ndi, unipi_ipfwmp
-
-; ddinstall section
-[IpfwMP.ndi]
-AddReg  = IpfwMP.ndi.AddReg
-Characteristics = 0x29 ;NCF_NOT_USER_REMOVABLE | NCF_VIRTUAL | NCF_HIDDEN
-
-; ddinstall->addreg points here
-[IpfwMP.ndi.AddReg]
-HKR, Ndi, Service,  0,  IpfwMP
-
-;ddinstall.services section
-[IpfwMP.ndi.Services]
-AddService = IpfwMP,0x2, IpfwMP.AddService
-
-[IpfwMP.AddService]
-ServiceType    = 1 ;SERVICE_KERNEL_DRIVER
-StartType      = 3 ;SERVICE_DEMAND_START
-ErrorControl   = 1 ;SERVICE_ERROR_NORMAL
-ServiceBinary  = %12%\ipfw.sys
-AddReg         = IpfwMP.AddService.AddReg
-
-[IpfwMP.AddService.AddReg]
-; None
-
-[Strings]
-Unipi = "Unipi"
-Desc = "Ipfw Miniport"
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/LICENSE.txt b/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/LICENSE.txt
deleted file mode 100644
index 193a853..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/LICENSE.txt
+++ /dev/null
@@ -1,23 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2013 Dave St.Germain
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/MANIFEST.in b/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/MANIFEST.in
deleted file mode 100644
index ab30e9a..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/MANIFEST.in
+++ /dev/null
@@ -1 +0,0 @@
-include *.txt
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/PKG-INFO b/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/PKG-INFO
deleted file mode 100644
index 66da942..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/PKG-INFO
+++ /dev/null
@@ -1,177 +0,0 @@
-Metadata-Version: 1.1
-Name: jsmin
-Version: 2.2.1
-Summary: JavaScript minifier.
-Home-page: https://bitbucket.org/dcs/jsmin/
-Author: Tikitu de Jager
-Author-email: tikitu+jsmin@logophile.org
-License: MIT License
-Description: =====
-        jsmin
-        =====
-        
-        JavaScript minifier.
-        
-        Usage
-        =====
-        
-        .. code:: python
-        
-         from jsmin import jsmin
-         with open('myfile.js') as js_file:
-             minified = jsmin(js_file.read())
-        
-        You can run it as a commandline tool also::
-        
-          python -m jsmin myfile.js
-        
-        NB: ``jsmin`` makes no attempt to be compatible with
-        `ECMAScript 6 / ES.next / Harmony <http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts>`_.
-        The current maintainer does not intend to add ES6-compatibility. If you would
-        like to take over maintenance and update ``jsmin`` for ES6, please contact
-        `Tikitu de Jager <mailto:tikitu+jsmin@logophile.org>`_. Pull requests are also
-        welcome, of course, but my time to review them is somewhat limited these days.
-        
-        If you're using ``jsmin`` on ES6 code, though, you might find the ``quote_chars``
-        parameter useful:
-        
-        .. code:: python
-        
-         from jsmin import jsmin
-         with open('myfile.js') as js_file:
-             minified = jsmin(js_file.read(), quote_chars="'\"`")
-        
-        
-        Where to get it
-        ===============
-        
-        * install the package `from pypi <https://pypi.python.org/pypi/jsmin/>`_
-        * get the latest release `from latest-release on github <https://github.com/tikitu/jsmin/tree/latest-release/jsmin>`_
-        * get the development version `from master on github <https://github.com/tikitu/jsmin/>`_
-        
-        Contributing
-        ============
-        
-        `Issues <https://github.com/tikitu/jsmin/issues>`_ and `Pull requests <https://github.com/tikitu/jsmin/pulls>`_
-        will be gratefully received on Github. The project used to be hosted
-        `on bitbucket <https://bitbucket.org/dcs/jsmin/>`_ and old issues can still be
-        found there.
-        
-        If possible, please make separate pull requests for tests and for code: tests will be added to the `latest-release` branch while code will go to `master`.
-        
-        Unless you request otherwise, your Github identity will be added to the contributor's list below; if you prefer a
-        different name feel free to add it in your pull request instead. (If you prefer not to be mentioned you'll have to let
-        the maintainer know somehow.)
-        
-        Build/test status
-        =================
-        
-        Both branches are tested with Travis: https://travis-ci.org/tikitu/jsmin
-        
-        The `latest-release` branch (the version on PyPI plus any new tests) is tested against CPython 2.6, 2.7, 3.2, and 3.3.
-        Currently:
-        
-        .. image:: https://travis-ci.org/tikitu/jsmin.png?branch=latest-release
-        
-        If that branch is failing that means there's a new test that fails on *the latest released version on pypi*, with no fix yet
-        released.
-        
-        The `master` branch (development version, might be ahead of latest released version) is tested against CPython 2.6, 2.7, 3.2, and
-        3.3. Currently:
-        
-        .. image:: https://travis-ci.org/tikitu/jsmin.png?branch=master
-        
-        If `master` is failing don't use it, but as long as `latest-release` is passing the pypi release should be ok.
-        
-        Contributors (chronological commit order)
-        =========================================
-        
-        * `Dave St.Germain <https://bitbucket.org/dcs>`_ (original author)
-        * `Hans weltar <https://bitbucket.org/hansweltar>`_
-        * `Tikitu de Jager <mailto:tikitu+jsmin@logophile.org>`_ (current maintainer)
-        * https://bitbucket.org/rennat
-        * `Nick Alexander <https://bitbucket.org/ncalexan>`_
-        * `Gennady Kovshenin <https://github.com/soulseekah>`_
-        * `Matt Molyneaux <https://github.com/moggers87>`_
-        
-        Changelog
-        =========
-        
-        v2.2.1 (2016-03-06) Tikitu de Jager
-        -----------------------------------
-        
-        - Fix #14: Infinite loop on `return x / 1;`
-        
-        v2.2.0 (2015-12-19) Tikitu de Jager
-        -----------------------------------
-        
-        - Merge #13: Preserve "loud comments" starting with `/*!`
-        
-          These are commonly used for copyright notices, and are preserved by various
-          other minifiers (e.g. YUI Compressor).
-        
-        v2.1.6 (2015-10-14) Tikitu de Jager
-        -----------------------------------
-        
-        - Fix #12: Newline following a regex literal should not be elided.
-        
-        v2.1.5 (2015-10-11) Tikitu de Jager
-        -----------------------------------
-        
-        - Fix #9: Premature end of statement caused by multi-line comment not
-          adding newline.
-        
-        - Fix #10: Removing multiline comment separating tokens must leave a space.
-        
-        - Refactor comment handling for maintainability.
-        
-        v2.1.4 (2015-08-23) Tikitu de Jager
-        -----------------------------------
-        
-        - Fix #6: regex literal matching comment was not correctly matched.
-        
-        - Refactor regex literal handling for robustness.
-        
-        v2.1.3 (2015-08-09) Tikitu de Jager
-        -----------------------------------
-        
-        - Reset issue numbering: issues live in github from now on.
-        
-        - Fix #1: regex literal was not recognised when occurring directly after `{`.
-        
-        v2.1.2 (2015-07-12) Tikitu de Jager
-        -----------------------------------
-        
-        - Issue numbers here and below refer to the bitbucket repository.
-        
-        - Fix #17: bug when JS starts with comment then literal regex.
-        
-        v2.1.1 (2015-02-14) Tikitu de Jager
-        -----------------------------------
-        
-        - Fix #16: bug returning a literal regex containing escaped forward-slashes.
-        
-        v2.1.0 (2014-12-24) Tikitu de Jager
-        -----------------------------------
-        
-        - First changelog entries; see README.rst for prior contributors.
-        
-        - Expose quote_chars parameter to provide just enough unofficial Harmony
-          support to be useful.
-        
-        
-Platform: UNKNOWN
-Classifier: Development Status :: 5 - Production/Stable
-Classifier: Environment :: Web Environment
-Classifier: Intended Audience :: Developers
-Classifier: License :: OSI Approved :: MIT License
-Classifier: Operating System :: OS Independent
-Classifier: Programming Language :: Python :: 2
-Classifier: Programming Language :: Python :: 2.6
-Classifier: Programming Language :: Python :: 2.7
-Classifier: Programming Language :: Python :: 3
-Classifier: Programming Language :: Python :: 3.2
-Classifier: Programming Language :: Python :: 3.3
-Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content
-Classifier: Topic :: Software Development :: Pre-processors
-Classifier: Topic :: Text Processing :: Filters
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/README.rst b/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/README.rst
deleted file mode 100644
index e7a5755..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/README.rst
+++ /dev/null
@@ -1,87 +0,0 @@
-=====
-jsmin
-=====
-
-JavaScript minifier.
-
-Usage
-=====
-
-.. code:: python
-
- from jsmin import jsmin
- with open('myfile.js') as js_file:
-     minified = jsmin(js_file.read())
-
-You can run it as a commandline tool also::
-
-  python -m jsmin myfile.js
-
-NB: ``jsmin`` makes no attempt to be compatible with
-`ECMAScript 6 / ES.next / Harmony <http://wiki.ecmascript.org/doku.php?id=harmony:specification_drafts>`_.
-The current maintainer does not intend to add ES6-compatibility. If you would
-like to take over maintenance and update ``jsmin`` for ES6, please contact
-`Tikitu de Jager <mailto:tikitu+jsmin@logophile.org>`_. Pull requests are also
-welcome, of course, but my time to review them is somewhat limited these days.
-
-If you're using ``jsmin`` on ES6 code, though, you might find the ``quote_chars``
-parameter useful:
-
-.. code:: python
-
- from jsmin import jsmin
- with open('myfile.js') as js_file:
-     minified = jsmin(js_file.read(), quote_chars="'\"`")
-
-
-Where to get it
-===============
-
-* install the package `from pypi <https://pypi.python.org/pypi/jsmin/>`_
-* get the latest release `from latest-release on github <https://github.com/tikitu/jsmin/tree/latest-release/jsmin>`_
-* get the development version `from master on github <https://github.com/tikitu/jsmin/>`_
-
-Contributing
-============
-
-`Issues <https://github.com/tikitu/jsmin/issues>`_ and `Pull requests <https://github.com/tikitu/jsmin/pulls>`_
-will be gratefully received on Github. The project used to be hosted
-`on bitbucket <https://bitbucket.org/dcs/jsmin/>`_ and old issues can still be
-found there.
-
-If possible, please make separate pull requests for tests and for code: tests will be added to the `latest-release` branch while code will go to `master`.
-
-Unless you request otherwise, your Github identity will be added to the contributor's list below; if you prefer a
-different name feel free to add it in your pull request instead. (If you prefer not to be mentioned you'll have to let
-the maintainer know somehow.)
-
-Build/test status
-=================
-
-Both branches are tested with Travis: https://travis-ci.org/tikitu/jsmin
-
-The `latest-release` branch (the version on PyPI plus any new tests) is tested against CPython 2.6, 2.7, 3.2, and 3.3.
-Currently:
-
-.. image:: https://travis-ci.org/tikitu/jsmin.png?branch=latest-release
-
-If that branch is failing that means there's a new test that fails on *the latest released version on pypi*, with no fix yet
-released.
-
-The `master` branch (development version, might be ahead of latest released version) is tested against CPython 2.6, 2.7, 3.2, and
-3.3. Currently:
-
-.. image:: https://travis-ci.org/tikitu/jsmin.png?branch=master
-
-If `master` is failing don't use it, but as long as `latest-release` is passing the pypi release should be ok.
-
-Contributors (chronological commit order)
-=========================================
-
-* `Dave St.Germain <https://bitbucket.org/dcs>`_ (original author)
-* `Hans weltar <https://bitbucket.org/hansweltar>`_
-* `Tikitu de Jager <mailto:tikitu+jsmin@logophile.org>`_ (current maintainer)
-* https://bitbucket.org/rennat
-* `Nick Alexander <https://bitbucket.org/ncalexan>`_
-* `Gennady Kovshenin <https://github.com/soulseekah>`_
-* `Matt Molyneaux <https://github.com/moggers87>`_
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/README.web-page-replay b/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/README.web-page-replay
deleted file mode 100644
index 96366fd..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/README.web-page-replay
+++ /dev/null
@@ -1,13 +0,0 @@
-Name: JavaScript minifier
-Short Name: jsmin
-URL: https://pypi.python.org/pypi/jsmin
-Version: 2.2.1
-License: MIT
-License File: LICENSE.txt
-
-Description:
-Used by Web Page Replay's script_injector module to minify injected JS scripts.
-
-Local Modifications:
-Remove jsmin/__main__.py & jsmin/test.py since they are not needed and contain
-no license header (https://github.com/tikitu/jsmin/issues/17).
diff --git a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/__init__.py b/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/__init__.py
deleted file mode 100644
index d2fdf8c..0000000
--- a/catapult/telemetry/third_party/web-page-replay/third_party/jsmin/__init__.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# This code is original from jsmin by Douglas Crockford, it was translated to
-# Python by Baruch Even. It was rewritten by Dave St.Germain for speed.
-#
-# The MIT License (MIT)
-# 
-# Copyright (c) 2013 Dave St.Germain
-# 
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-# 
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-# 
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-
-
-import sys
-is_3 = sys.version_info >= (3, 0)
-if is_3:
-    import io
-else:
-    import StringIO
-    try:
-        import cStringIO
-    except ImportError:
-        cStringIO = None
-
-
-__all__ = ['jsmin', 'JavascriptMinify']
-__version__ = '2.2.1'
-
-
-def jsmin(js, **kwargs):
-    """
-    returns a minified version of the javascript string
-    """
-    if not is_3:        
-        if cStringIO and not isinstance(js, unicode):
-            # strings can use cStringIO for a 3x performance
-            # improvement, but unicode (in python2) cannot
-            klass = cStringIO.StringIO
-        else:
-            klass = StringIO.StringIO
-    else:
-        klass = io.StringIO
-    ins = klass(js)
-    outs = klass()
-    JavascriptMinify(ins, outs, **kwargs).minify()
-    return outs.getvalue()
-
-
-class JavascriptMinify(object):
-    """
-    Minify an input stream of javascript, writing
-    to an output stream
-    """
-
-    def __init__(self, instream=None, outstream=None, quote_chars="'\""):
-        self.ins = instream
-        self.outs = outstream
-        self.quote_chars = quote_chars
-
-    def minify(self, instream=None, outstream=None):
-        if instream and outstream:
-            self.ins, self.outs = instream, outstream
-        
-        self.is_return = False
-        self.return_buf = ''
-        
-        def write(char):
-            # all of this is to support literal regular expressions.
-            # sigh
-            if char in 'return':
-                self.return_buf += char
-                self.is_return = self.return_buf == 'return'
-            else:
-                self.return_buf = ''
-                self.is_return = self.is_return and char < '!'
-            self.outs.write(char)
-            if self.is_return:
-                self.return_buf = ''
-
-        read = self.ins.read
-
-        space_strings = "abcdefghijklmnopqrstuvwxyz"\
-        "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_$\\"
-        self.space_strings = space_strings
-        starters, enders = '{[(+-', '}])+-/' + self.quote_chars
-        newlinestart_strings = starters + space_strings + self.quote_chars
-        newlineend_strings = enders + space_strings + self.quote_chars
-        self.newlinestart_strings = newlinestart_strings
-        self.newlineend_strings = newlineend_strings
-
-        do_newline = False
-        do_space = False
-        escape_slash_count = 0
-        in_quote = ''
-        quote_buf = []
-
-        previous = ';'
-        previous_non_space = ';'
-        next1 = read(1)
-
-        while next1:
-            next2 = read(1)
-            if in_quote:
-                quote_buf.append(next1)
-
-                if next1 == in_quote:
-                    numslashes = 0
-                    for c in reversed(quote_buf[:-1]):
-                        if c != '\\':
-                            break
-                        else:
-                            numslashes += 1
-                    if numslashes % 2 == 0:
-                        in_quote = ''
-                        write(''.join(quote_buf))
-            elif next1 in '\r\n':
-                next2, do_newline = self.newline(
-                    previous_non_space, next2, do_newline)
-            elif next1 < '!':
-                if (previous_non_space in space_strings \
-                    or previous_non_space > '~') \
-                    and (next2 in space_strings or next2 > '~'):
-                    do_space = True
-                elif previous_non_space in '-+' and next2 == previous_non_space:
-                    # protect against + ++ or - -- sequences
-                    do_space = True
-                elif self.is_return and next2 == '/':
-                    # returning a regex...
-                    write(' ')
-            elif next1 == '/':
-                if do_space:
-                    write(' ')
-                if next2 == '/':
-                    # Line comment: treat it as a newline, but skip it
-                    next2 = self.line_comment(next1, next2)
-                    next1 = '\n'
-                    next2, do_newline = self.newline(
-                        previous_non_space, next2, do_newline)
-                elif next2 == '*':
-                    self.block_comment(next1, next2)
-                    next2 = read(1)
-                    if previous_non_space in space_strings:
-                        do_space = True
-                    next1 = previous
-                else:
-                    if previous_non_space in '{(,=:[?!&|;' or self.is_return:
-                        self.regex_literal(next1, next2)
-                        # hackish: after regex literal next1 is still /
-                        # (it was the initial /, now it's the last /)
-                        next2 = read(1)
-                    else:
-                        write('/')
-            else:
-                if do_newline:
-                    write('\n')
-                    do_newline = False
-                    do_space = False
-                if do_space:
-                    do_space = False
-                    write(' ')
-
-                write(next1)
-                if next1 in self.quote_chars:
-                    in_quote = next1
-                    quote_buf = []
-
-            if next1 >= '!':
-                previous_non_space = next1
-
-            if next1 == '\\':
-                escape_slash_count += 1
-            else:
-                escape_slash_count = 0
-
-            previous = next1
-            next1 = next2
-
-    def regex_literal(self, next1, next2):
-        assert next1 == '/'  # otherwise we should not be called!
-
-        self.return_buf = ''
-
-        read = self.ins.read
-        write = self.outs.write
-
-        in_char_class = False
-
-        write('/')
-
-        next = next2
-        while next and (next != '/' or in_char_class):
-            write(next)
-            if next == '\\':
-                write(read(1))  # whatever is next is escaped
-            elif next == '[':
-                write(read(1))  # character class cannot be empty
-                in_char_class = True
-            elif next == ']':
-                in_char_class = False
-            next = read(1)
-
-        write('/')
-
-    def line_comment(self, next1, next2):
-        assert next1 == next2 == '/'
-
-        read = self.ins.read
-
-        while next1 and next1 not in '\r\n':
-            next1 = read(1)
-        while next1 and next1 in '\r\n':
-            next1 = read(1)
-
-        return next1
-
-    def block_comment(self, next1, next2):
-        assert next1 == '/'
-        assert next2 == '*'
-
-        read = self.ins.read
-
-        # Skip past first /* and avoid catching on /*/...*/
-        next1 = read(1)
-        next2 = read(1)
-
-        comment_buffer = '/*'
-        while next1 != '*' or next2 != '/':
-            comment_buffer += next1
-            next1 = next2
-            next2 = read(1)
-
-        if comment_buffer.startswith("/*!"):
-            # comment needs preserving
-            self.outs.write(comment_buffer)
-            self.outs.write("*/\n")
-
-
-    def newline(self, previous_non_space, next2, do_newline):
-        read = self.ins.read
-
-        if previous_non_space and (
-                        previous_non_space in self.newlineend_strings
-                        or previous_non_space > '~'):
-            while 1:
-                if next2 < '!':
-                    next2 = read(1)
-                    if not next2:
-                        break
-                else:
-                    if next2 in self.newlinestart_strings \
-                            or next2 > '~' or next2 == '/':
-                        do_newline = True
-                    break
-
-        return next2, do_newline
diff --git a/catapult/telemetry/third_party/web-page-replay/trafficshaper.py b/catapult/telemetry/third_party/web-page-replay/trafficshaper.py
deleted file mode 100644
index 0078218..0000000
--- a/catapult/telemetry/third_party/web-page-replay/trafficshaper.py
+++ /dev/null
@@ -1,186 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2010 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import logging
-import platformsettings
-import re
-
-
-# Mac has broken bandwitdh parsing, so double check the values.
-# On Mac OS X 10.6, "KBit/s" actually uses "KByte/s".
-BANDWIDTH_PATTERN = r'0|\d+[KM]?(bit|Byte)/s'
-
-
-class TrafficShaperException(Exception):
-  pass
-
-
-class BandwidthValueError(TrafficShaperException):
-  def __init__(self, value):  # pylint: disable=super-init-not-called
-    self.value = value
-
-  def __str__(self):
-    return 'Value, "%s", does not match regex: %s' % (
-        self.value, BANDWIDTH_PATTERN)
-
-
-class TrafficShaper(object):
-  """Manages network traffic shaping."""
-
-  # Pick webpagetest-compatible values (details: http://goo.gl/oghTg).
-  _UPLOAD_PIPE = '10'      # Enforces overall upload bandwidth.
-  _UPLOAD_QUEUE = '10'     # Shares upload bandwidth among source ports.
-  _UPLOAD_RULE = '5000'    # Specifies when the upload queue is used.
-  _DOWNLOAD_PIPE = '11'    # Enforces overall download bandwidth.
-  _DOWNLOAD_QUEUE = '11'   # Shares download bandwidth among destination ports.
-  _DOWNLOAD_RULE = '5100'  # Specifies when the download queue is used.
-  _QUEUE_SLOTS = 100       # Number of packets to queue.
-
-  _BANDWIDTH_RE = re.compile(BANDWIDTH_PATTERN)
-
-  def __init__(self,
-               dont_use=None,
-               host='127.0.0.1',
-               ports=None,
-               up_bandwidth='0',
-               down_bandwidth='0',
-               delay_ms='0',
-               packet_loss_rate='0',
-               init_cwnd='0',
-               use_loopback=True):
-    """Start shaping traffic.
-
-    Args:
-      host: a host string (name or IP) for the web proxy.
-      ports: a list of ports to shape traffic on.
-      up_bandwidth: Upload bandwidth
-      down_bandwidth: Download bandwidth
-           Bandwidths measured in [K|M]{bit/s|Byte/s}. '0' means unlimited.
-      delay_ms: Propagation delay in milliseconds. '0' means no delay.
-      packet_loss_rate: Packet loss rate in range [0..1]. '0' means no loss.
-      init_cwnd: the initial cwnd setting. '0' means no change.
-      use_loopback: True iff shaping is done on the loopback (or equiv) adapter.
-    """
-    assert dont_use is None  # Force args to be named.
-    self.host = host
-    self.ports = ports
-    self.up_bandwidth = up_bandwidth
-    self.down_bandwidth = down_bandwidth
-    self.delay_ms = delay_ms
-    self.packet_loss_rate = packet_loss_rate
-    self.init_cwnd = init_cwnd
-    self.use_loopback = use_loopback
-    if not self._BANDWIDTH_RE.match(self.up_bandwidth):
-      raise BandwidthValueError(self.up_bandwidth)
-    if not self._BANDWIDTH_RE.match(self.down_bandwidth):
-      raise BandwidthValueError(self.down_bandwidth)
-    self.is_shaping = False
-
-  def __enter__(self):
-    if self.use_loopback:
-      platformsettings.setup_temporary_loopback_config()
-    if self.init_cwnd != '0':
-      platformsettings.set_temporary_tcp_init_cwnd(self.init_cwnd)
-    try:
-      ipfw_list = platformsettings.ipfw('list')
-      if not ipfw_list.startswith('65535 '):
-        logging.warn('ipfw has existing rules:\n%s', ipfw_list)
-        self._delete_rules(ipfw_list)
-    except Exception:
-      pass
-    if (self.up_bandwidth == '0' and self.down_bandwidth == '0' and
-        self.delay_ms == '0' and self.packet_loss_rate == '0'):
-      logging.info('Skipped shaping traffic.')
-      return
-    if not self.ports:
-      raise TrafficShaperException('No ports on which to shape traffic.')
-
-    ports = ','.join(str(p) for p in self.ports)
-    half_delay_ms = int(self.delay_ms) / 2  # split over up/down links
-
-    try:
-      # Configure upload shaping.
-      platformsettings.ipfw(
-          'pipe', self._UPLOAD_PIPE,
-          'config',
-          'bw', self.up_bandwidth,
-          'delay', half_delay_ms,
-          )
-      platformsettings.ipfw(
-          'queue', self._UPLOAD_QUEUE,
-          'config',
-          'pipe', self._UPLOAD_PIPE,
-          'plr', self.packet_loss_rate,
-          'queue', self._QUEUE_SLOTS,
-          'mask', 'src-port', '0xffff',
-          )
-      platformsettings.ipfw(
-          'add', self._UPLOAD_RULE,
-          'queue', self._UPLOAD_QUEUE,
-          'ip',
-          'from', 'any',
-          'to', self.host,
-          self.use_loopback and 'out' or 'in',
-          'dst-port', ports,
-          )
-      self.is_shaping = True
-
-      # Configure download shaping.
-      platformsettings.ipfw(
-          'pipe', self._DOWNLOAD_PIPE,
-          'config',
-          'bw', self.down_bandwidth,
-          'delay', half_delay_ms,
-          )
-      platformsettings.ipfw(
-          'queue', self._DOWNLOAD_QUEUE,
-          'config',
-          'pipe', self._DOWNLOAD_PIPE,
-          'plr', self.packet_loss_rate,
-          'queue', self._QUEUE_SLOTS,
-          'mask', 'dst-port', '0xffff',
-          )
-      platformsettings.ipfw(
-          'add', self._DOWNLOAD_RULE,
-          'queue', self._DOWNLOAD_QUEUE,
-          'ip',
-          'from', self.host,
-          'to', 'any',
-          'out',
-          'src-port', ports,
-          )
-      logging.info('Started shaping traffic')
-    except Exception:
-      logging.error('Unable to shape traffic.')
-      raise
-
-  def __exit__(self, unused_exc_type, unused_exc_val, unused_exc_tb):
-    if self.is_shaping:
-      try:
-        self._delete_rules()
-        logging.info('Stopped shaping traffic')
-      except Exception:
-        logging.error('Unable to stop shaping traffic.')
-        raise
-
-  def _delete_rules(self, ipfw_list=None):
-    if ipfw_list is None:
-      ipfw_list = platformsettings.ipfw('list')
-    existing_rules = set(
-        r.split()[0].lstrip('0') for r in ipfw_list.splitlines())
-    delete_rules = [r for r in (self._DOWNLOAD_RULE, self._UPLOAD_RULE)
-                    if r in existing_rules]
-    if delete_rules:
-      platformsettings.ipfw('delete', *delete_rules)
diff --git a/catapult/telemetry/third_party/web-page-replay/trafficshaper_test.py b/catapult/telemetry/third_party/web-page-replay/trafficshaper_test.py
deleted file mode 100755
index 525446d..0000000
--- a/catapult/telemetry/third_party/web-page-replay/trafficshaper_test.py
+++ /dev/null
@@ -1,277 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2011 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""System integration test for traffic shaping.
-
-Usage:
-$ sudo ./trafficshaper_test.py
-"""
-
-import daemonserver
-import logging
-import platformsettings
-import socket
-import SocketServer
-import trafficshaper
-import unittest
-
-RESPONSE_SIZE_KEY = 'response-size:'
-TEST_DNS_PORT = 5555
-TEST_HTTP_PORT = 8888
-TIMER = platformsettings.timer
-
-
-def GetElapsedMs(start_time, end_time):
-  """Return milliseconds elapsed between |start_time| and |end_time|.
-
-  Args:
-    start_time: seconds as a float (or string representation of float).
-    end_time: seconds as a float (or string representation of float).
-  Return:
-    milliseconds elapsed as integer.
-  """
-  return int((float(end_time) - float(start_time)) * 1000)
-
-
-class TrafficShaperTest(unittest.TestCase):
-
-  def testBadBandwidthRaises(self):
-    self.assertRaises(trafficshaper.BandwidthValueError,
-                      trafficshaper.TrafficShaper,
-                      down_bandwidth='1KBit/s')
-
-
-class TimedUdpHandler(SocketServer.DatagramRequestHandler):
-  """UDP handler that returns the time when the request was handled."""
-
-  def handle(self):
-    data = self.rfile.read()
-    read_time = self.server.timer()
-    self.wfile.write(str(read_time))
-
-
-class TimedTcpHandler(SocketServer.StreamRequestHandler):
-  """Tcp handler that returns the time when the request was read.
-
-  It can respond with the number of bytes specified in the request.
-  The request looks like:
-    request_data -> RESPONSE_SIZE_KEY num_response_bytes '\n' ANY_DATA
-  """
-
-  def handle(self):
-    data = self.rfile.read()
-    read_time = self.server.timer()
-    contents = str(read_time)
-    if data.startswith(RESPONSE_SIZE_KEY):
-      num_response_bytes = int(data[len(RESPONSE_SIZE_KEY):data.index('\n')])
-      contents = '%s\n%s' % (contents,
-                             '\x00' * (num_response_bytes - len(contents) - 1))
-    self.wfile.write(contents)
-
-
-class TimedUdpServer(SocketServer.ThreadingUDPServer,
-                     daemonserver.DaemonServer):
-  """A simple UDP server similar to dnsproxy."""
-
-  # Override SocketServer.TcpServer setting to avoid intermittent errors.
-  allow_reuse_address = True
-
-  def __init__(self, host, port, timer=TIMER):
-    SocketServer.ThreadingUDPServer.__init__(
-        self, (host, port), TimedUdpHandler)
-    self.timer = timer
-
-  def cleanup(self):
-    pass
-
-
-class TimedTcpServer(SocketServer.ThreadingTCPServer,
-                     daemonserver.DaemonServer):
-  """A simple TCP server similar to httpproxy."""
-
-  # Override SocketServer.TcpServer setting to avoid intermittent errors.
-  allow_reuse_address = True
-
-  def __init__(self, host, port, timer=TIMER):
-    SocketServer.ThreadingTCPServer.__init__(
-        self, (host, port), TimedTcpHandler)
-    self.timer = timer
-
-  def cleanup(self):
-    try:
-      self.shutdown()
-    except KeyboardInterrupt, e:
-      pass
-
-
-class TcpTestSocketCreator(object):
-  """A TCP socket creator suitable for with-statement."""
-
-  def __init__(self, host, port, timeout=1.0):
-    self.address = (host, port)
-    self.timeout = timeout
-
-  def __enter__(self):
-    self.socket = socket.create_connection(self.address, timeout=self.timeout)
-    return self.socket
-
-  def __exit__(self, *args):
-    self.socket.close()
-
-
-class TimedTestCase(unittest.TestCase):
-  def assertValuesAlmostEqual(self, expected, actual, tolerance=0.05):
-    """Like the following with nicer default message:
-           assertTrue(expected <= actual + tolerance &&
-                      expected >= actual - tolerance)
-    """
-    delta = tolerance * expected
-    if actual > expected + delta or actual < expected - delta:
-      self.fail('%s is not equal to expected %s +/- %s%%' % (
-              actual, expected, 100 * tolerance))
-
-
-class TcpTrafficShaperTest(TimedTestCase):
-
-  def setUp(self):
-    self.host = platformsettings.get_server_ip_address()
-    self.port = TEST_HTTP_PORT
-    self.tcp_socket_creator = TcpTestSocketCreator(self.host, self.port)
-    self.timer = TIMER
-
-  def TrafficShaper(self, **kwargs):
-    return trafficshaper.TrafficShaper(
-        host=self.host, ports=(self.port,), **kwargs)
-
-  def GetTcpSendTimeMs(self, num_bytes):
-    """Return time in milliseconds to send |num_bytes|."""
-
-    with self.tcp_socket_creator as s:
-      start_time = self.timer()
-      request_data = '\x00' * num_bytes
-
-      s.sendall(request_data)
-      # TODO(slamm): Figure out why partial is shutdown needed to make it work.
-      s.shutdown(socket.SHUT_WR)
-      read_time = s.recv(1024)
-    return GetElapsedMs(start_time, read_time)
-
-  def GetTcpReceiveTimeMs(self, num_bytes):
-    """Return time in milliseconds to receive |num_bytes|."""
-
-    with self.tcp_socket_creator as s:
-      s.sendall('%s%s\n' % (RESPONSE_SIZE_KEY, num_bytes))
-      # TODO(slamm): Figure out why partial is shutdown needed to make it work.
-      s.shutdown(socket.SHUT_WR)
-      num_remaining_bytes = num_bytes
-      read_time = None
-      while num_remaining_bytes > 0:
-        response_data = s.recv(4096)
-        num_remaining_bytes -= len(response_data)
-        if not read_time:
-          read_time, padding = response_data.split('\n')
-    return GetElapsedMs(read_time, self.timer())
-
-  def testTcpConnectToIp(self):
-    """Verify that it takes |delay_ms| to establish a TCP connection."""
-    if not platformsettings.has_ipfw():
-      logging.warning('ipfw is not available in path. Skip the test')
-      return
-    with TimedTcpServer(self.host, self.port):
-      for delay_ms in (100, 175):
-        with self.TrafficShaper(delay_ms=delay_ms):
-          start_time = self.timer()
-          with self.tcp_socket_creator:
-            connect_time = GetElapsedMs(start_time, self.timer())
-        self.assertValuesAlmostEqual(delay_ms, connect_time, tolerance=0.12)
-
-  def testTcpUploadShaping(self):
-    """Verify that 'up' bandwidth is shaped on TCP connections."""
-    if not platformsettings.has_ipfw():
-      logging.warning('ipfw is not available in path. Skip the test')
-      return
-    num_bytes = 1024 * 100
-    bandwidth_kbits = 2000
-    expected_ms = 8.0 * num_bytes / bandwidth_kbits
-    with TimedTcpServer(self.host, self.port):
-      with self.TrafficShaper(up_bandwidth='%sKbit/s' % bandwidth_kbits):
-        self.assertValuesAlmostEqual(expected_ms, self.GetTcpSendTimeMs(num_bytes))
-
-  def testTcpDownloadShaping(self):
-    """Verify that 'down' bandwidth is shaped on TCP connections."""
-    if not platformsettings.has_ipfw():
-      logging.warning('ipfw is not available in path. Skip the test')
-      return
-    num_bytes = 1024 * 100
-    bandwidth_kbits = 2000
-    expected_ms = 8.0 * num_bytes / bandwidth_kbits
-    with TimedTcpServer(self.host, self.port):
-      with self.TrafficShaper(down_bandwidth='%sKbit/s' % bandwidth_kbits):
-        self.assertValuesAlmostEqual(expected_ms, self.GetTcpReceiveTimeMs(num_bytes))
-
-  def testTcpInterleavedDownloads(self):
-    # TODO(slamm): write tcp interleaved downloads test
-    pass
-
-
-class UdpTrafficShaperTest(TimedTestCase):
-
-  def setUp(self):
-    self.host = platformsettings.get_server_ip_address()
-    self.dns_port = TEST_DNS_PORT
-    self.timer = TIMER
-
-  def TrafficShaper(self, **kwargs):
-    return trafficshaper.TrafficShaper(
-        host=self.host, ports=(self.dns_port,), **kwargs)
-
-  def GetUdpSendReceiveTimesMs(self):
-    """Return time in milliseconds to send |num_bytes|."""
-    start_time = self.timer()
-    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
-    udp_socket.sendto('test data\n', (self.host, self.dns_port))
-    read_time = udp_socket.recv(1024)
-    return (GetElapsedMs(start_time, read_time),
-            GetElapsedMs(read_time, self.timer()))
-
-  def testUdpDelay(self):
-    if not platformsettings.has_ipfw():
-      logging.warning('ipfw is not available in path. Skip the test')
-      return
-    for delay_ms in (100, 170):
-      expected_ms = delay_ms / 2
-      with TimedUdpServer(self.host, self.dns_port):
-        with self.TrafficShaper(delay_ms=delay_ms):
-          send_ms, receive_ms = self.GetUdpSendReceiveTimesMs()
-          self.assertValuesAlmostEqual(expected_ms, send_ms, tolerance=0.10)
-          self.assertValuesAlmostEqual(expected_ms, receive_ms, tolerance=0.10)
-
-
-  def testUdpInterleavedDelay(self):
-    # TODO(slamm): write udp interleaved udp delay test
-    pass
-
-
-class TcpAndUdpTrafficShaperTest(TimedTestCase):
-  # TODO(slamm): Test concurrent TCP and UDP traffic
-  pass
-
-
-# TODO(slamm): Packet loss rate (try different ports)
-
-
-if __name__ == '__main__':
-  #logging.getLogger().setLevel(logging.DEBUG)
-  unittest.main()
diff --git a/catapult/telemetry/third_party/web-page-replay/util.py b/catapult/telemetry/third_party/web-page-replay/util.py
deleted file mode 100644
index 419d232..0000000
--- a/catapult/telemetry/third_party/web-page-replay/util.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2012 Google Inc. All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-"""Miscellaneous utility functions."""
-
-import inspect
-import logging
-import time
-
-try:
-  # pkg_resources (part of setuptools) is needed when WPR is
-  # distributed as a package. (Resources may need to be extracted from
-  # the package.)
-
-  import pkg_resources
-
-  def resource_exists(resource_name):
-    return pkg_resources.resource_exists(__name__, resource_name)
-
-  def resource_string(resource_name):
-    return pkg_resources.resource_string(__name__, resource_name)
-
-except ImportError:
-  # Import of pkg_resources failed, so fall back to getting resources
-  # from the file system.
-
-  import os
-
-  def _resource_path(resource_name):
-    _replay_dir = os.path.dirname(os.path.abspath(__file__))
-    return os.path.join(_replay_dir, resource_name)
-
-  def resource_exists(resource_name):
-    return os.path.exists(_resource_path(resource_name))
-
-  def resource_string(resource_name):
-    return open(_resource_path(resource_name)).read()
-
-
-class TimeoutException(Exception):
-  pass
-
-
-def WaitFor(condition, timeout):
-  """Waits for up to |timeout| secs for the function |condition| to return True.
-
-  Polling frequency is (elapsed_time / 10), with a min of .1s and max of 5s.
-
-  Returns:
-    Result of |condition| function (if present).
-  """
-  min_poll_interval = 0.1
-  max_poll_interval = 5
-  output_interval = 300
-
-  def GetConditionString():
-    if condition.__name__ == '<lambda>':
-      try:
-        return inspect.getsource(condition).strip()
-      except IOError:
-        pass
-    return condition.__name__
-
-  start_time = time.time()
-  last_output_time = start_time
-  while True:
-    res = condition()
-    if res:
-      return res
-    now = time.time()
-    elapsed_time = now - start_time
-    last_output_elapsed_time = now - last_output_time
-    if elapsed_time > timeout:
-      raise TimeoutException('Timed out while waiting %ds for %s.' %
-                                        (timeout, GetConditionString()))
-    if last_output_elapsed_time > output_interval:
-      logging.info('Continuing to wait %ds for %s. Elapsed: %ds.',
-                   timeout, GetConditionString(), elapsed_time)
-      last_output_time = time.time()
-    poll_interval = min(max(elapsed_time / 10., min_poll_interval),
-                        max_poll_interval)
-    time.sleep(poll_interval)
diff --git a/catapult/telemetry/third_party/web-page-replay/wpr_cert.pem b/catapult/telemetry/third_party/web-page-replay/wpr_cert.pem
deleted file mode 100644
index 773bfea..0000000
--- a/catapult/telemetry/third_party/web-page-replay/wpr_cert.pem
+++ /dev/null
@@ -1,31 +0,0 @@
------BEGIN PRIVATE KEY-----
-MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBALLOoY1ENN78dMvO
-33tSElddaaPFV4ooXJKbCqWsEurkKJjtoHxnri54rgNOLSU4O8aQytWE9zq6Ei/c
-qK7dl6UqZiZtwk4HVrBL786cVKlgpPkhcnG+EMdDxy/PyMD38jNtTNMJLiwbxiZq
-Mo3vjZ/4+1XLdNisAWTDLaWeXxmbAgMBAAECgYAadwLqScIZjvwqfkANnKQiUi0k
-lDzUsgyhllkJFGLoaUSo/eLXBvF851e6HYQJEj2msh+TYs7E3m16sAo3d4zOIdnz
-VwOF0SVuUveqJz6K1/k6nPxck+dPj8Mi+gBm3Fd0+0wcozjWaxhx3f462HCUb6b+
-ZpJRBsbyvzu6rn7iQQJBAOlWhtfL8r9+Kl0vxRD1XukaJwlxPv24JhfKOU4z8WlJ
-WX7Wr8ws+xKS+CtfFnjkf/iFJPpTb8jxpQyWMJzYZIkCQQDELE5hGnBFVQArMAOp
-VbwYordTrVY3AagO4tDJ6T3a7GEXE28ol16/i02+4FLd65vubL21IuX0exH/eRvZ
-Q4wDAkEAub/qyiEOFkjOWq5rd0uNiY0LJGYlWf7dPDT8l3ecJ09/0gv/mE76c9fR
-fV1N22EzSlhbjncbVuCenj11Z3aP2QJAILtfzJXzu63GHG6jfcKfYuDrg9u9Mepl
-1y4DNl1jg77DKG2Gs5gmKAGfVETrrrmcR/j+4lVTVyqdwym6+tJpbwJBAN3vixxc
-5N9pUMDfFnHrx/x9QPd0JgSAT21KSIB+PndlbD7QO6nwFhQNNcTYt2D4VWPVo1vg
-lOraHyFakb7NqEA=
------END PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIICWDCCAcGgAwIBAgIJAIt1sARz1phuMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
-BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
-aWRnaXRzIFB0eSBMdGQwHhcNMTIxMDIzMjA1NzA0WhcNMjIxMDIxMjA1NzA0WjBF
-MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
-ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB
-gQCyzqGNRDTe/HTLzt97UhJXXWmjxVeKKFySmwqlrBLq5CiY7aB8Z64ueK4DTi0l
-ODvGkMrVhPc6uhIv3Kiu3ZelKmYmbcJOB1awS+/OnFSpYKT5IXJxvhDHQ8cvz8jA
-9/IzbUzTCS4sG8YmajKN742f+PtVy3TYrAFkwy2lnl8ZmwIDAQABo1AwTjAdBgNV
-HQ4EFgQUyihF4Nbabk9aBDOOxMVDLRLiqMEwHwYDVR0jBBgwFoAUyihF4Nbabk9a
-BDOOxMVDLRLiqMEwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOBgQCIrYif
-q4YQ7A8zy8PB1wKOyMy50r7IokO8hplbjRwVCQwbLnRM74LPp84caEdwaCJvAaP9
-QWjVz6p3K2sK9iHaidQZ/9xqJPoZrYttQCcQUweaASp04Y9WwTA4EPeDZLgp4PgU
-SV/mvKRGimmce6LMxFlPiZio/IDiUNXVJ7j/sg==
------END CERTIFICATE-----
diff --git a/catapult/telemetry/third_party/websocket-client/.gitignore b/catapult/telemetry/third_party/websocket-client/.gitignore
deleted file mode 100644
index c7d73ad..0000000
--- a/catapult/telemetry/third_party/websocket-client/.gitignore
+++ /dev/null
@@ -1,8 +0,0 @@
-*.pyc
-*~
-*\#
-.\#*
-
-build
-dist
-websocket_client.egg-info
diff --git a/catapult/telemetry/third_party/websocket-client/ChangeLog b/catapult/telemetry/third_party/websocket-client/ChangeLog
deleted file mode 100644
index b26e153..0000000
--- a/catapult/telemetry/third_party/websocket-client/ChangeLog
+++ /dev/null
@@ -1,253 +0,0 @@
-ChangeLog
-============
-
-- 0.41.0
-
-  - move to repository to https://github.com/websocket-client/websocket-client.git
-  - _send_ping warning fails due to missing reference in _logging.__all__ (#294)
-
-- 0.40.0
-  - Fix opcode -> op_code (#286)
-
-- 0.39.0
-  - Shuffled around example code (#256)
-  - _send_ping graceful error handling (#262)
-  - Allow closing WebSocketApp with status/reason/timeout (#265)
-  - Support universal wheels (#267)
-  - _url: Added subnet IP address matching in no_proxy host detection (#270)
-  - fixed Incorrect encoding in continued messages python3 (#261)
-  - Pass headers for websocket handshake (#271)
-  - setup.py: Import `logging` before calling it. (#272)
-  - Implemented close code 1014 (#273)
-  - Support CA bundle specified by environment variable (#279)
-  - Response header values should not be converted to lower case (#264)
-
-- 0.38.0
-  - Exclude port 443 from host http header (#248)
-  - Cleanup code (#249)
-  - Modify a code block directive in README (#250)
-  - fixed ping/pong timeouet (#253)
-
-- 0.37.0
-  - fixed failure that `websocket.create_connection` does not accept `origin` as a parameter (#246 )
-
-- 0.36.0
-  - added support for using custom connection class (#235)
-  - use Named logger (#238)
-  - implement ping/pong timeout (#241)
-  - Corrects the syntax highlight code (#243)
-  - fixed failure to join thread before it is started (#242)
-
-- 0.35.0
-  - Prints timings in console (#217)
-  - use inspect.getfullargspec with Python 3.x (#219)
-  - Check that exception message is actually a string before trying for substring check (#224)
-  - Use pre-initialized stream socket (#226)
-  - fixed TypeError: cafile, capath and cadata cannot be all omitted (#227)
-
-- 0.34.0
-
-  - Change import style (#203)
-  - fix attribute error on the older python. (#215)
-
-- 0.33.0
-
-  - fixed timeout+ssl error handling bug  on python 2.7.10 (#190)
-  - add proxy support to wsdump.py (#194)
-  - use wsaccel if available (#193)
-  - add support for ssl cert chains to support client certs (#195)
-  - fix string formatting in exception (#196)
-  - fix typo in README.rst (#197)
-  - introduce on_data callback to pass data type. (#198)
-  - WebSocketBadStatusException for Handshake error (#199)
-  - set close timeout (#192)
-  - Map dict to headers list (#204)
-  - support client certification (#207)
-  - security improvement during handshake (#211)
-  - improve logging of error from callback (#212)
-
-- 0.32.0
-
-  - fix http proxy bug (#189)
-
-- 0.31.0
-
-  - Avoid deprecated BaseException.message (#180)
-  - Add travis builds (#182)
-  - fixed wsdump to work with piped input (#183)
-  - fixed output of wsdump.py with python3 (#185)
-  - add raw mode to wsdump.py (#186)
-
-- 0.30.0
-
-  - fixed if client is behind proxy (#169)
-  - support SNI for python 2.7.9+ and 3.2+ (#172)
-  - update Host HTTP header by user. (#171)
-  - fix typo for isEnabledFor (#173)
-  - can set verify_mode to CERT_NONE when check_hostname is enabled.(#175)
-  - make websockets iterable (#178)
-
-- 0.29.0
-
-  - fixed ssl socket bug
-
-- 0.28.0
-
-  - Fix erroneous argument shadowing(#168)
-
-- 0.27.0
-
-  - remove unittest2 requirements for python 2.6 (#156)
-  - fixed subprotocol case during header validation (#158)
-  - get response status and headers (#160)
-  - fix out-of-memory due to fragmentation when receiving a very large frame(#163)
-  - fix error if the payload data is nothing.(#166)
-  - refactoring.
-
-- 0.26.0
-
-  - all WebSocketException provide message string (#152)
-  - fixed tests fail when not connected to the network (#155)
-  - Add command line options and handle closed socket to wsdump.py (#153)
-
-- 0.25.0
-
-  - fixed for Python 2.6(#151)
-
-- 0.24.0
-
-  - Supporting http-basic auth in WebSocketApp (#143)
-  - fix failure of test.testInternalRecvStrict(#141)
-  - skip utf8 validation by skip_utf8_validation argument (#137)
-  - WebsocketProxyException will be raised if we got error about proxy.(#138)
-
-- 0.23.0
-
-  - Remove spurious print statement. (#135)
-
-- 0.22.0
-
-  - Fix not thread-safe of Websocket.close() (#120)
-  - Try to get proxy info from environment if not explicitly provided (#124)
-  - support proxy basic authentication. (#125)
-  - Fix NoneType exception at WebsocketApp.send (#126)
-  - not use proxy for localhost (#132)
-
-- 0.21.0
-
-  - Check for socket before attempting to close (#115)
-  - Enable turning off SSL verification in wsdump.py(#116)
-  - Enable to set subprotocol(#118)
-  - Better support for Autobahn test suite (http://autobahn.ws/testsuite) (#117)
-
-- v0.20.0
-
-  - fix typo.
-
-- v0.19.0
-
-  - suppress close event message(#107)
-  - detect socket connection state(#109)
-  - support for code and reason in on_close callback(#111)
-  - continuation frame handling seems suspicious(#113)
-
-- v0.18.0
-
-  -  allow override of match_hostname usage on ssl (#105)
-
-- v0.17.0
-
-  - can't set timeout on a standing websocket connection (#102)
-  - fixed local variable 'error' referenced before assignment (#102, #98)
-
-- v0.16.0
-
-  - lock some method for multithread. (#92)
-  - disable cert verification. (#89)
-
-- v0.15.0
-
-  - fixed exception when send a large message (#84)
-
-- v0.14.1
-
-  - fixed to work on Python2.6 (#83)
-
-- v0.14.0
-
-  - Support python 3(#73)
-  - Support IPv6(#77)
-  - Support explicit web proxy(#57)
-  - specify cookie in connect method option(#82)
-
-- v0.13.0
-
-  - MemoryError when receiving large amount of data (~60 MB) at once(ISSUE#59)
-  - Controlling fragmentation(ISSUE#55)
-  - server certificate validation(ISSUE#56)
-  - PyPI tarball is missing test_websocket.py(ISSUE#65)
-  - Payload length encoding bug(ISSUE#58)
-  - disable Nagle algorithm by default(ISSUE#41)
-  - Better event loop in WebSocketApp(ISSUE#63)
-  - Skip tests that require Internet access by default(ISSUE#66)
-
-- v0.12.0
-
-  - support keep alive for WebSocketApp(ISSUE#34)
-  - fix some SSL bugs(ISSUE#35, #36)
-  - fix "Timing out leaves websocket library in bad state"(ISSUE#37)
-  - fix "WebSocketApp.run_with_no_err() silently eats all exceptions"(ISSUE#38)
-  - WebSocketTimeoutException will be raised for ws/wss timeout(ISSUE#40)
-  - improve wsdump message(ISSUE#42)
-  - support fragmentation message(ISSUE#43)
-  - fix some bugs
-
-- v0.11.0
-
-  - Only log non-normal close status(ISSUE#31)
-  - Fix default Origin isn't URI(ISSUE#32)
-  - fileno support(ISSUE#33)
-
-- v0.10.0
-
-  - allow to set HTTP Header to WebSocketApp(ISSUE#27)
-  - fix typo in pydoc(ISSUE#28)
-  - Passing a socketopt flag to the websocket constructor(ISSUE#29)
-  - websocket.send fails with long data(ISSUE#30)
-
-
-- v0.9.0
-
-  - allow to set opcode in WebSocketApp.send(ISSUE#25)
-  - allow to modify Origin(ISSUE#26)
-
-- v0.8.0
-
-  - many bug fix
-  - some performance improvement
-
-- v0.7.0
-
-  - fixed problem to read long data.(ISSUE#12)
-  - fix buffer size boundary violation
-
-- v0.6.0
-
-  - Patches: UUID4, self.keep_running, mask_key (ISSUE#11)
-  - add wsdump.py tool
-
-- v0.5.2
-
-  - fix Echo App Demo Throw Error: 'NoneType' object has no attribute 'opcode  (ISSUE#10)
-
-- v0.5.1
-
-  - delete invalid print statement.
-
-- v0.5.0
-
-  - support hybi-13 protocol.
-
-- v0.4.1
-
-  - fix incorrect custom header order(ISSUE#1)
diff --git a/catapult/telemetry/third_party/websocket-client/LICENSE b/catapult/telemetry/third_party/websocket-client/LICENSE
deleted file mode 100644
index 31afd6d..0000000
--- a/catapult/telemetry/third_party/websocket-client/LICENSE
+++ /dev/null
@@ -1,165 +0,0 @@
-                  GNU LESSER GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
-  This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
-  0. Additional Definitions.
-
-  As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
-  "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
-  An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
-  A "Combined Work" is a work produced by combining or linking an
-Application with the Library.  The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
-  The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
-  The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
-  1. Exception to Section 3 of the GNU GPL.
-
-  You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
-  2. Conveying Modified Versions.
-
-  If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
-   a) under this License, provided that you make a good faith effort to
-   ensure that, in the event an Application does not supply the
-   function or data, the facility still operates, and performs
-   whatever part of its purpose remains meaningful, or
-
-   b) under the GNU GPL, with none of the additional permissions of
-   this License applicable to that copy.
-
-  3. Object Code Incorporating Material from Library Header Files.
-
-  The object code form of an Application may incorporate material from
-a header file that is part of the Library.  You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
-   a) Give prominent notice with each copy of the object code that the
-   Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the object code with a copy of the GNU GPL and this license
-   document.
-
-  4. Combined Works.
-
-  You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
-   a) Give prominent notice with each copy of the Combined Work that
-   the Library is used in it and that the Library and its use are
-   covered by this License.
-
-   b) Accompany the Combined Work with a copy of the GNU GPL and this license
-   document.
-
-   c) For a Combined Work that displays copyright notices during
-   execution, include the copyright notice for the Library among
-   these notices, as well as a reference directing the user to the
-   copies of the GNU GPL and this license document.
-
-   d) Do one of the following:
-
-       0) Convey the Minimal Corresponding Source under the terms of this
-       License, and the Corresponding Application Code in a form
-       suitable for, and under terms that permit, the user to
-       recombine or relink the Application with a modified version of
-       the Linked Version to produce a modified Combined Work, in the
-       manner specified by section 6 of the GNU GPL for conveying
-       Corresponding Source.
-
-       1) Use a suitable shared library mechanism for linking with the
-       Library.  A suitable mechanism is one that (a) uses at run time
-       a copy of the Library already present on the user's computer
-       system, and (b) will operate properly with a modified version
-       of the Library that is interface-compatible with the Linked
-       Version.
-
-   e) Provide Installation Information, but only if you would otherwise
-   be required to provide such information under section 6 of the
-   GNU GPL, and only to the extent that such information is
-   necessary to install and execute a modified version of the
-   Combined Work produced by recombining or relinking the
-   Application with a modified version of the Linked Version. (If
-   you use option 4d0, the Installation Information must accompany
-   the Minimal Corresponding Source and Corresponding Application
-   Code. If you use option 4d1, you must provide the Installation
-   Information in the manner specified by section 6 of the GNU GPL
-   for conveying Corresponding Source.)
-
-  5. Combined Libraries.
-
-  You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
-   a) Accompany the combined library with a copy of the same work based
-   on the Library, uncombined with any other library facilities,
-   conveyed under the terms of this License.
-
-   b) Give prominent notice with the combined library that part of it
-   is a work based on the Library, and explaining where to find the
-   accompanying uncombined form of the same work.
-
-  6. Revised Versions of the GNU Lesser General Public License.
-
-  The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
-  Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
-  If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/catapult/telemetry/third_party/websocket-client/MANIFEST.in b/catapult/telemetry/third_party/websocket-client/MANIFEST.in
deleted file mode 100644
index 9df2a36..0000000
--- a/catapult/telemetry/third_party/websocket-client/MANIFEST.in
+++ /dev/null
@@ -1,4 +0,0 @@
-include LICENSE
-include README.rst
-include ChangeLog
-recursive-include examples *
diff --git a/catapult/telemetry/third_party/websocket-client/README.chromium b/catapult/telemetry/third_party/websocket-client/README.chromium
deleted file mode 100644
index 47e8102..0000000
--- a/catapult/telemetry/third_party/websocket-client/README.chromium
+++ /dev/null
@@ -1,19 +0,0 @@
-Name: Python websocket-client
-Short Name: websocket-client
-URL: https://github.com/liris/websocket-client
-Version: 0.41.0
-Revision: 83419000cb50a732bf3fc479cb0a9be097af212a
-Date: Fri Feb 3rd 03:14:01 2017 EST
-License: LGPL-3.0
-License File: NOT_SHIPPED
-Security Critical: no
-
-Description:
-
-websocket-client module is WebSocket client for python. This provide the low
-level APIs for WebSocket. All APIs are the synchronous functions.
-
-Used by the python code in devtools-auto to communicate with a running Chrome instance.
-
-Local Modifications:
-None.
diff --git a/catapult/telemetry/third_party/websocket-client/README.rst b/catapult/telemetry/third_party/websocket-client/README.rst
deleted file mode 100644
index 22447a8..0000000
--- a/catapult/telemetry/third_party/websocket-client/README.rst
+++ /dev/null
@@ -1,260 +0,0 @@
-=================
-websocket-client
-=================
-
-**Our repository has moved to https://github.com/websocket-client/websocket-client**
-
-websocket-client module  is WebSocket client for python. This provide the low level APIs for WebSocket. All APIs are the synchronous functions.
-
-websocket-client supports only hybi-13.
-
-
-License
-============
-
- - LGPL
-
-Installation
-=============
-
-This module is tested on Python 2.7 and Python 3.x.
-
-Type "python setup.py install" or "pip install websocket-client" to install.
-
-.. CAUTION::
-
-  from v0.16.0, we can install by "pip install websocket-client" for python 3.
-
-This module depend on
-
- - six
- - backports.ssl_match_hostname for Python 2.x
-
-How about Python 3
-===========================
-
-Now, we support python 3 on  single source code from version 0.14.0. Thanks, @battlemidget and @ralphbean.
-
-HTTP Proxy
-=============
-
-Support websocket access via http proxy.
-The proxy server must allow "CONNECT" method to websocket port.
-Default squid setting is "ALLOWED TO CONNECT ONLY HTTPS PORT".
-
-Current implementation of websocket-client is using "CONNECT" method via proxy.
-
-
-example
-
-.. code:: python
-
-    import websocket
-    ws = websocket.WebSocket()
-    ws.connect("ws://example.com/websocket", http_proxy_host="proxy_host_name", http_proxy_port=3128)
-    :
-
-
-
-Examples
-========
-
-Long-lived connection
----------------------
-This example is similar to how WebSocket code looks in browsers using JavaScript.
-
-.. code:: python
-
-    import websocket
-    import thread
-    import time
-
-    def on_message(ws, message):
-        print message
-
-    def on_error(ws, error):
-        print error
-
-    def on_close(ws):
-        print "### closed ###"
-
-    def on_open(ws):
-        def run(*args):
-            for i in range(3):
-                time.sleep(1)
-                ws.send("Hello %d" % i)
-            time.sleep(1)
-            ws.close()
-            print "thread terminating..."
-        thread.start_new_thread(run, ())
-
-
-    if __name__ == "__main__":
-        websocket.enableTrace(True)
-        ws = websocket.WebSocketApp("ws://echo.websocket.org/",
-                                  on_message = on_message,
-                                  on_error = on_error,
-                                  on_close = on_close)
-        ws.on_open = on_open
-        ws.run_forever()
-
-
-Short-lived one-off send-receive
---------------------------------
-This is if you want to communicate a short message and disconnect immediately when done.
-
-.. code:: python
-
-    from websocket import create_connection
-    ws = create_connection("ws://echo.websocket.org/")
-    print "Sending 'Hello, World'..."
-    ws.send("Hello, World")
-    print "Sent"
-    print "Receiving..."
-    result =  ws.recv()
-    print "Received '%s'" % result
-    ws.close()
-
-If you want to customize socket options, set sockopt.
-
-sockopt example
-
-.. code:: python
-
-    from websocket import create_connection
-    ws = create_connection("ws://echo.websocket.org/",
-                            sockopt=((socket.IPPROTO_TCP, socket.TCP_NODELAY),))
-
-
-More advanced: Custom class
----------------------------
-You can also write your own class for the connection, if you want to handle the nitty-gritty details yourself.
-
-.. code:: python
-
-    from websocket import create_connection, WebSocket
-    class MyWebSocket(WebSocket):
-        def recv_frame(self):
-            frame = super().recv_frame()
-            print('yay! I got this frame: ', frame)
-            return frame
-
-    ws = create_connection("ws://echo.websocket.org/",
-                            sockopt=((socket.IPPROTO_TCP, socket.TCP_NODELAY),), class_=MyWebSocket)
-
-
-FAQ
-============
-
-How to disable ssl cert verification?
-----------------------------------------
-
-Please set sslopt to {"cert_reqs": ssl.CERT_NONE}.
-
-WebSocketApp sample
-
-.. code:: python
-
-    ws = websocket.WebSocketApp("wss://echo.websocket.org")
-    ws.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
-
-create_connection sample
-
-.. code:: python
-
-    ws = websocket.create_connection("wss://echo.websocket.org",
-      sslopt={"cert_reqs": ssl.CERT_NONE})
-
-WebSocket sample
-
-.. code:: python
-
-    ws = websocket.WebSocket(sslopt={"cert_reqs": ssl.CERT_NONE})
-    ws.connect("wss://echo.websocket.org")
-
-
-How to disable hostname verification.
-----------------------------------------
-
-Please set sslopt to {"check_hostname": False}.
-(since v0.18.0)
-
-WebSocketApp sample
-
-.. code:: python
-
-    ws = websocket.WebSocketApp("wss://echo.websocket.org")
-    ws.run_forever(sslopt={"check_hostname": False})
-
-create_connection sample
-
-.. code:: python
-
-    ws = websocket.create_connection("wss://echo.websocket.org",
-      sslopt={"check_hostname": False})
-
-WebSocket sample
-
-.. code:: python
-
-    ws = websocket.WebSocket(sslopt={"check_hostname": False})
-    ws.connect("wss://echo.websocket.org")
-
-
-How to enable `SNI <http://en.wikipedia.org/wiki/Server_Name_Indication>`_?
----------------------------------------------------------------------------
-
-SNI support is available for Python 2.7.9+ and 3.2+. It will be enabled automatically whenever possible.
-
-
-Sub Protocols.
-----------------------------------------
-
-The server needs to support sub protocols, please set the subprotocol like this.
-
-
-Subprotocol sample
-
-.. code:: python
-
-    ws = websocket.create_connection("ws://exapmle.com/websocket", subprotocols=["binary", "base64"])
-
-
-
-wsdump.py
-============
-
-wsdump.py is simple WebSocket test(debug) tool.
-
-sample for echo.websocket.org::
-
-  $ wsdump.py ws://echo.websocket.org/
-  Press Ctrl+C to quit
-  > Hello, WebSocket
-  < Hello, WebSocket
-  > How are you?
-  < How are you?
-
-Usage
----------
-
-usage::
-
-  wsdump.py [-h] [-v [VERBOSE]] ws_url
-
-WebSocket Simple Dump Tool
-
-positional arguments:
-  ws_url                websocket url. ex. ws://echo.websocket.org/
-
-optional arguments:
-  -h, --help                           show this help message and exit
-WebSocketApp
-  -v VERBOSE, --verbose VERBOSE    set verbose mode. If set to 1, show opcode. If set to 2, enable to trace websocket module
-
-example::
-
-  $ wsdump.py ws://echo.websocket.org/
-  $ wsdump.py ws://echo.websocket.org/ -v
-  $ wsdump.py ws://echo.websocket.org/ -vv
-
diff --git a/catapult/telemetry/third_party/websocket-client/bin/wsdump.py b/catapult/telemetry/third_party/websocket-client/bin/wsdump.py
deleted file mode 100755
index e06271c..0000000
--- a/catapult/telemetry/third_party/websocket-client/bin/wsdump.py
+++ /dev/null
@@ -1,200 +0,0 @@
-#!/usr/bin/env python
-
-import argparse
-import code
-import sys
-import threading
-import time
-
-import six
-from six.moves.urllib.parse import urlparse
-
-import websocket
-
-try:
-    import readline
-except ImportError:
-    pass
-
-
-def get_encoding():
-    encoding = getattr(sys.stdin, "encoding", "")
-    if not encoding:
-        return "utf-8"
-    else:
-        return encoding.lower()
-
-
-OPCODE_DATA = (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY)
-ENCODING = get_encoding()
-
-
-class VAction(argparse.Action):
-
-    def __call__(self, parser, args, values, option_string=None):
-        if values is None:
-            values = "1"
-        try:
-            values = int(values)
-        except ValueError:
-            values = values.count("v") + 1
-        setattr(args, self.dest, values)
-
-
-def parse_args():
-    parser = argparse.ArgumentParser(description="WebSocket Simple Dump Tool")
-    parser.add_argument("url", metavar="ws_url",
-                        help="websocket url. ex. ws://echo.websocket.org/")
-    parser.add_argument("-p", "--proxy",
-                        help="proxy url. ex. http://127.0.0.1:8080")
-    parser.add_argument("-v", "--verbose", default=0, nargs='?', action=VAction,
-                        dest="verbose",
-                        help="set verbose mode. If set to 1, show opcode. "
-                        "If set to 2, enable to trace  websocket module")
-    parser.add_argument("-n", "--nocert", action='store_true',
-                        help="Ignore invalid SSL cert")
-    parser.add_argument("-r", "--raw", action="store_true",
-                        help="raw output")
-    parser.add_argument("-s", "--subprotocols", nargs='*',
-                        help="Set subprotocols")
-    parser.add_argument("-o", "--origin",
-                        help="Set origin")
-    parser.add_argument("--eof-wait", default=0, type=int,
-                        help="wait time(second) after 'EOF' received.")
-    parser.add_argument("-t", "--text",
-                        help="Send initial text")
-    parser.add_argument("--timings", action="store_true",
-                        help="Print timings in seconds")
-    parser.add_argument("--headers",
-                        help="Set custom headers. Use ',' as separator")
-
-    return parser.parse_args()
-
-
-class RawInput:
-
-    def raw_input(self, prompt):
-        if six.PY3:
-            line = input(prompt)
-        else:
-            line = raw_input(prompt)
-
-        if ENCODING and ENCODING != "utf-8" and not isinstance(line, six.text_type):
-            line = line.decode(ENCODING).encode("utf-8")
-        elif isinstance(line, six.text_type):
-            line = line.encode("utf-8")
-
-        return line
-
-
-class InteractiveConsole(RawInput, code.InteractiveConsole):
-
-    def write(self, data):
-        sys.stdout.write("\033[2K\033[E")
-        # sys.stdout.write("\n")
-        sys.stdout.write("\033[34m< " + data + "\033[39m")
-        sys.stdout.write("\n> ")
-        sys.stdout.flush()
-
-    def read(self):
-        return self.raw_input("> ")
-
-
-class NonInteractive(RawInput):
-
-    def write(self, data):
-        sys.stdout.write(data)
-        sys.stdout.write("\n")
-        sys.stdout.flush()
-
-    def read(self):
-        return self.raw_input("")
-
-
-def main():
-    start_time = time.time()
-    args = parse_args()
-    if args.verbose > 1:
-        websocket.enableTrace(True)
-    options = {}
-    if args.proxy:
-        p = urlparse(args.proxy)
-        options["http_proxy_host"] = p.hostname
-        options["http_proxy_port"] = p.port
-    if args.origin:
-        options["origin"] = args.origin
-    if args.subprotocols:
-        options["subprotocols"] = args.subprotocols
-    opts = {}
-    if args.nocert:
-        opts = {"cert_reqs": websocket.ssl.CERT_NONE, "check_hostname": False}
-    if args.headers:
-        options['header'] = map(str.strip, args.headers.split(','))
-    ws = websocket.create_connection(args.url, sslopt=opts, **options)
-    if args.raw:
-        console = NonInteractive()
-    else:
-        console = InteractiveConsole()
-        print("Press Ctrl+C to quit")
-
-    def recv():
-        try:
-            frame = ws.recv_frame()
-        except websocket.WebSocketException:
-            return websocket.ABNF.OPCODE_CLOSE, None
-        if not frame:
-            raise websocket.WebSocketException("Not a valid frame %s" % frame)
-        elif frame.opcode in OPCODE_DATA:
-            return frame.opcode, frame.data
-        elif frame.opcode == websocket.ABNF.OPCODE_CLOSE:
-            ws.send_close()
-            return frame.opcode, None
-        elif frame.opcode == websocket.ABNF.OPCODE_PING:
-            ws.pong(frame.data)
-            return frame.opcode, frame.data
-
-        return frame.opcode, frame.data
-
-    def recv_ws():
-        while True:
-            opcode, data = recv()
-            msg = None
-            if six.PY3 and opcode == websocket.ABNF.OPCODE_TEXT and isinstance(data, bytes):
-                data = str(data, "utf-8")
-            if not args.verbose and opcode in OPCODE_DATA:
-                msg = data
-            elif args.verbose:
-                msg = "%s: %s" % (websocket.ABNF.OPCODE_MAP.get(opcode), data)
-
-            if msg is not None:
-                if args.timings:
-                    console.write(str(time.time() - start_time) + ": " + msg)
-                else:
-                    console.write(msg)
-
-            if opcode == websocket.ABNF.OPCODE_CLOSE:
-                break
-
-    thread = threading.Thread(target=recv_ws)
-    thread.daemon = True
-    thread.start()
-
-    if args.text:
-        ws.send(args.text)
-
-    while True:
-        try:
-            message = console.read()
-            ws.send(message)
-        except KeyboardInterrupt:
-            return
-        except EOFError:
-            time.sleep(args.eof_wait)
-            return
-
-
-if __name__ == "__main__":
-    try:
-        main()
-    except Exception as e:
-        print(e)
diff --git a/catapult/telemetry/third_party/websocket-client/compliance/README.md b/catapult/telemetry/third_party/websocket-client/compliance/README.md
deleted file mode 100644
index 5cef404..0000000
--- a/catapult/telemetry/third_party/websocket-client/compliance/README.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# Autobahn Testsuite
-
-General information and installation instructions are available at http://autobahn.ws/testsuite .
-
-## Running the test suite
-
-
-  $ wstest -m fuzzingserver
-  $ python test_fuzzingclient.py
-
-
diff --git a/catapult/telemetry/third_party/websocket-client/compliance/fuzzingserver.json b/catapult/telemetry/third_party/websocket-client/compliance/fuzzingserver.json
deleted file mode 100644
index 6d4f4c0..0000000
--- a/catapult/telemetry/third_party/websocket-client/compliance/fuzzingserver.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-"url": "ws://localhost:8642",
-"options": {"failByDrop": false},
-"outdir": "./reports/clients",
-"webport": 8080,
-"cases": ["*"],
-"exclude-cases": [],
-"exclude-agent-cases": {}
-}
diff --git a/catapult/telemetry/third_party/websocket-client/compliance/test_fuzzingclient.py b/catapult/telemetry/third_party/websocket-client/compliance/test_fuzzingclient.py
deleted file mode 100644
index f4b0ff1..0000000
--- a/catapult/telemetry/third_party/websocket-client/compliance/test_fuzzingclient.py
+++ /dev/null
@@ -1,43 +0,0 @@
-#!/usr/bin/env python
-
-import json
-import traceback
-
-import websocket
-
-SERVER = 'ws://127.0.0.1:8642'
-AGENT = 'py-websockets-client'
-
-
-ws = websocket.create_connection(SERVER + "/getCaseCount")
-count = json.loads(ws.recv())
-ws.close()
-
-
-for case in range(1, count+1):
-    url = SERVER + '/runCase?case={0}&agent={1}'.format(case, AGENT)
-    status = websocket.STATUS_NORMAL
-    try:
-        ws = websocket.create_connection(url)
-        while True:
-            opcode, msg = ws.recv_data()
-            if opcode == websocket.ABNF.OPCODE_TEXT:
-                msg.decode("utf-8")
-            if opcode  in (websocket.ABNF.OPCODE_TEXT, websocket.ABNF.OPCODE_BINARY):
-                ws.send(msg, opcode)
-    except UnicodeDecodeError:
-        # this case is ok.
-        status = websocket.STATUS_PROTOCOL_ERROR
-    except websocket.WebSocketProtocolException:
-        status = websocket.STATUS_PROTOCOL_ERROR
-    except websocket.WebSocketPayloadException:
-        status = websocket.STATUS_INVALID_PAYLOAD
-    except Exception as e:
-        # status = websocket.STATUS_PROTOCOL_ERROR
-        print(traceback.format_exc())
-    finally:
-        ws.close(status)
-
-print("Ran {} test cases.".format(case))
-url = SERVER + '/updateReports?agent={0}'.format(AGENT)
-ws = websocket.create_connection(url)
diff --git a/catapult/telemetry/third_party/websocket-client/examples/echo_client.py b/catapult/telemetry/third_party/websocket-client/examples/echo_client.py
deleted file mode 100644
index 7a74461..0000000
--- a/catapult/telemetry/third_party/websocket-client/examples/echo_client.py
+++ /dev/null
@@ -1,13 +0,0 @@
-from __future__ import print_function
-import websocket
-
-if __name__ == "__main__":
-    websocket.enableTrace(True)
-    ws = websocket.create_connection("ws://echo.websocket.org/")
-    print("Sending 'Hello, World'...")
-    ws.send("Hello, World")
-    print("Sent")
-    print("Receiving...")
-    result = ws.recv()
-    print("Received '%s'" % result)
-    ws.close()
diff --git a/catapult/telemetry/third_party/websocket-client/examples/echoapp_client.py b/catapult/telemetry/third_party/websocket-client/examples/echoapp_client.py
deleted file mode 100644
index c15b35f..0000000
--- a/catapult/telemetry/third_party/websocket-client/examples/echoapp_client.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import websocket
-try:
-    import thread
-except ImportError:  # TODO use Threading instead of _thread in python3
-    import _thread as thread
-import time
-import sys
-
-
-def on_message(ws, message):
-    print(message)
-
-
-def on_error(ws, error):
-    print(error)
-
-
-def on_close(ws):
-    print("### closed ###")
-
-
-def on_open(ws):
-    def run(*args):
-        for i in range(3):
-            # send the message, then wait
-            # so thread doesn't exit and socket
-            # isn't closed
-            ws.send("Hello %d" % i)
-            time.sleep(1)
-
-        time.sleep(1)
-        ws.close()
-        print("Thread terminating...")
-
-    thread.start_new_thread(run, ())
-
-if __name__ == "__main__":
-    websocket.enableTrace(True)
-    if len(sys.argv) < 2:
-        host = "ws://echo.websocket.org/"
-    else:
-        host = sys.argv[1]
-    ws = websocket.WebSocketApp(host,
-                                on_message=on_message,
-                                on_error=on_error,
-                                on_close=on_close)
-    ws.on_open = on_open
-    ws.run_forever()
diff --git a/catapult/telemetry/third_party/websocket-client/setup.cfg b/catapult/telemetry/third_party/websocket-client/setup.cfg
deleted file mode 100644
index 50ee459..0000000
--- a/catapult/telemetry/third_party/websocket-client/setup.cfg
+++ /dev/null
@@ -1,7 +0,0 @@
-[egg_info]
-tag_build = 
-tag_date = 0
-tag_svn_revision = 0
-
-[bdist_wheel]
-universal = 1
diff --git a/catapult/telemetry/third_party/websocket-client/setup.py b/catapult/telemetry/third_party/websocket-client/setup.py
deleted file mode 100644
index 38527a9..0000000
--- a/catapult/telemetry/third_party/websocket-client/setup.py
+++ /dev/null
@@ -1,70 +0,0 @@
-import sys
-
-from setuptools import setup
-import pkg_resources
-
-VERSION = "0.41.0"
-NAME = "websocket_client"
-
-install_requires = ["six"]
-tests_require = []
-
-if sys.version_info[0] == 2 and sys.version_info[1] < 7:
-        tests_require.append('unittest2==0.8.0')
-
-insecure_pythons = '2.4, 2.5, 2.6' + ', '.join("2.7.{pv}".format(pv=pv) for pv in range(10))
-
-extras_require = {
-    ':python_version in "{ips}"'.format(ips=insecure_pythons):
-        ['backports.ssl_match_hostname'],
-    ':python_version in "2.4, 2.5, 2.6"': ['argparse'],
-}
-
-try:
-    if 'bdist_wheel' not in sys.argv:
-        for key, value in extras_require.items():
-            if key.startswith(':') and pkg_resources.evaluate_marker(key[1:]):
-                install_requires.extend(value)
-except Exception:
-    import logging
-    logging.getLogger(__name__).exception(
-        'Something went wrong calculating platform specific dependencies, so '
-        "you're getting them all!"
-    )
-    for key, value in extras_require.items():
-        if key.startswith(':'):
-            install_requires.extend(value)
-
-setup(
-    name=NAME,
-    version=VERSION,
-    description="WebSocket client for python. hybi13 is supported.",
-    long_description=open("README.rst").read(),
-    author="liris",
-    author_email="liris.pp@gmail.com",
-    license="LGPL",
-    url="https://github.com/websocket-client/websocket-client.git",
-    classifiers=[
-        "Development Status :: 4 - Beta",
-        "License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)",
-        "Programming Language :: Python",
-        "Programming Language :: Python :: 2",
-        "Programming Language :: Python :: 3",
-        "Operating System :: MacOS :: MacOS X",
-        "Operating System :: POSIX",
-        "Operating System :: Microsoft :: Windows",
-        "Topic :: Internet",
-        "Topic :: Software Development :: Libraries :: Python Modules",
-        "Intended Audience :: Developers",
-    ],
-    keywords='websockets',
-    scripts=["bin/wsdump.py"],
-    install_requires=install_requires,
-    packages=["websocket", "websocket.tests"],
-    package_data={
-        'websocket.tests': ['data/*.txt'],
-        'websocket': ["cacert.pem"]
-    },
-    tests_require=tests_require,
-    test_suite="websocket.tests.test_websocket",
-)
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/__init__.py b/catapult/telemetry/third_party/websocket-client/websocket/__init__.py
deleted file mode 100644
index a4f9374..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/__init__.py
+++ /dev/null
@@ -1,29 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-from ._abnf import *
-from ._app import WebSocketApp
-from ._core import *
-from ._exceptions import *
-from ._logging import *
-from ._socket import *
-
-__version__ = "0.41.0"
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_abnf.py b/catapult/telemetry/third_party/websocket-client/websocket/_abnf.py
deleted file mode 100644
index eb07536..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_abnf.py
+++ /dev/null
@@ -1,422 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-import array
-import os
-import struct
-
-import six
-
-from ._exceptions import *
-from ._utils import validate_utf8
-
-try:
-    # If wsaccel is available we use compiled routines to mask data.
-    from wsaccel.xormask import XorMaskerSimple
-
-    def _mask(_m, _d):
-        return XorMaskerSimple(_m).process(_d)
-
-except ImportError:
-    # wsaccel is not available, we rely on python implementations.
-    def _mask(_m, _d):
-        for i in range(len(_d)):
-            _d[i] ^= _m[i % 4]
-
-        if six.PY3:
-            return _d.tobytes()
-        else:
-            return _d.tostring()
-
-__all__ = [
-    'ABNF', 'continuous_frame', 'frame_buffer',
-    'STATUS_NORMAL',
-    'STATUS_GOING_AWAY',
-    'STATUS_PROTOCOL_ERROR',
-    'STATUS_UNSUPPORTED_DATA_TYPE',
-    'STATUS_STATUS_NOT_AVAILABLE',
-    'STATUS_ABNORMAL_CLOSED',
-    'STATUS_INVALID_PAYLOAD',
-    'STATUS_POLICY_VIOLATION',
-    'STATUS_MESSAGE_TOO_BIG',
-    'STATUS_INVALID_EXTENSION',
-    'STATUS_UNEXPECTED_CONDITION',
-    'STATUS_BAD_GATEWAY',
-    'STATUS_TLS_HANDSHAKE_ERROR',
-]
-
-# closing frame status codes.
-STATUS_NORMAL = 1000
-STATUS_GOING_AWAY = 1001
-STATUS_PROTOCOL_ERROR = 1002
-STATUS_UNSUPPORTED_DATA_TYPE = 1003
-STATUS_STATUS_NOT_AVAILABLE = 1005
-STATUS_ABNORMAL_CLOSED = 1006
-STATUS_INVALID_PAYLOAD = 1007
-STATUS_POLICY_VIOLATION = 1008
-STATUS_MESSAGE_TOO_BIG = 1009
-STATUS_INVALID_EXTENSION = 1010
-STATUS_UNEXPECTED_CONDITION = 1011
-STATUS_BAD_GATEWAY = 1014
-STATUS_TLS_HANDSHAKE_ERROR = 1015
-
-VALID_CLOSE_STATUS = (
-    STATUS_NORMAL,
-    STATUS_GOING_AWAY,
-    STATUS_PROTOCOL_ERROR,
-    STATUS_UNSUPPORTED_DATA_TYPE,
-    STATUS_INVALID_PAYLOAD,
-    STATUS_POLICY_VIOLATION,
-    STATUS_MESSAGE_TOO_BIG,
-    STATUS_INVALID_EXTENSION,
-    STATUS_UNEXPECTED_CONDITION,
-    STATUS_BAD_GATEWAY,
-)
-
-
-class ABNF(object):
-    """
-    ABNF frame class.
-    see http://tools.ietf.org/html/rfc5234
-    and http://tools.ietf.org/html/rfc6455#section-5.2
-    """
-
-    # operation code values.
-    OPCODE_CONT = 0x0
-    OPCODE_TEXT = 0x1
-    OPCODE_BINARY = 0x2
-    OPCODE_CLOSE = 0x8
-    OPCODE_PING = 0x9
-    OPCODE_PONG = 0xa
-
-    # available operation code value tuple
-    OPCODES = (OPCODE_CONT, OPCODE_TEXT, OPCODE_BINARY, OPCODE_CLOSE,
-               OPCODE_PING, OPCODE_PONG)
-
-    # opcode human readable string
-    OPCODE_MAP = {
-        OPCODE_CONT: "cont",
-        OPCODE_TEXT: "text",
-        OPCODE_BINARY: "binary",
-        OPCODE_CLOSE: "close",
-        OPCODE_PING: "ping",
-        OPCODE_PONG: "pong"
-    }
-
-    # data length threshold.
-    LENGTH_7 = 0x7e
-    LENGTH_16 = 1 << 16
-    LENGTH_63 = 1 << 63
-
-    def __init__(self, fin=0, rsv1=0, rsv2=0, rsv3=0,
-                 opcode=OPCODE_TEXT, mask=1, data=""):
-        """
-        Constructor for ABNF.
-        please check RFC for arguments.
-        """
-        self.fin = fin
-        self.rsv1 = rsv1
-        self.rsv2 = rsv2
-        self.rsv3 = rsv3
-        self.opcode = opcode
-        self.mask = mask
-        if data is None:
-            data = ""
-        self.data = data
-        self.get_mask_key = os.urandom
-
-    def validate(self, skip_utf8_validation=False):
-        """
-        validate the ABNF frame.
-        skip_utf8_validation: skip utf8 validation.
-        """
-        if self.rsv1 or self.rsv2 or self.rsv3:
-            raise WebSocketProtocolException("rsv is not implemented, yet")
-
-        if self.opcode not in ABNF.OPCODES:
-            raise WebSocketProtocolException("Invalid opcode %r", self.opcode)
-
-        if self.opcode == ABNF.OPCODE_PING and not self.fin:
-            raise WebSocketProtocolException("Invalid ping frame.")
-
-        if self.opcode == ABNF.OPCODE_CLOSE:
-            l = len(self.data)
-            if not l:
-                return
-            if l == 1 or l >= 126:
-                raise WebSocketProtocolException("Invalid close frame.")
-            if l > 2 and not skip_utf8_validation and not validate_utf8(self.data[2:]):
-                raise WebSocketProtocolException("Invalid close frame.")
-
-            code = 256 * \
-                six.byte2int(self.data[0:1]) + six.byte2int(self.data[1:2])
-            if not self._is_valid_close_status(code):
-                raise WebSocketProtocolException("Invalid close opcode.")
-
-    @staticmethod
-    def _is_valid_close_status(code):
-        return code in VALID_CLOSE_STATUS or (3000 <= code < 5000)
-
-    def __str__(self):
-        return "fin=" + str(self.fin) \
-            + " opcode=" + str(self.opcode) \
-            + " data=" + str(self.data)
-
-    @staticmethod
-    def create_frame(data, opcode, fin=1):
-        """
-        create frame to send text, binary and other data.
-
-        data: data to send. This is string value(byte array).
-            if opcode is OPCODE_TEXT and this value is unicode,
-            data value is converted into unicode string, automatically.
-
-        opcode: operation code. please see OPCODE_XXX.
-
-        fin: fin flag. if set to 0, create continue fragmentation.
-        """
-        if opcode == ABNF.OPCODE_TEXT and isinstance(data, six.text_type):
-            data = data.encode("utf-8")
-        # mask must be set if send data from client
-        return ABNF(fin, 0, 0, 0, opcode, 1, data)
-
-    def format(self):
-        """
-        format this object to string(byte array) to send data to server.
-        """
-        if any(x not in (0, 1) for x in [self.fin, self.rsv1, self.rsv2, self.rsv3]):
-            raise ValueError("not 0 or 1")
-        if self.opcode not in ABNF.OPCODES:
-            raise ValueError("Invalid OPCODE")
-        length = len(self.data)
-        if length >= ABNF.LENGTH_63:
-            raise ValueError("data is too long")
-
-        frame_header = chr(self.fin << 7
-                           | self.rsv1 << 6 | self.rsv2 << 5 | self.rsv3 << 4
-                           | self.opcode)
-        if length < ABNF.LENGTH_7:
-            frame_header += chr(self.mask << 7 | length)
-            frame_header = six.b(frame_header)
-        elif length < ABNF.LENGTH_16:
-            frame_header += chr(self.mask << 7 | 0x7e)
-            frame_header = six.b(frame_header)
-            frame_header += struct.pack("!H", length)
-        else:
-            frame_header += chr(self.mask << 7 | 0x7f)
-            frame_header = six.b(frame_header)
-            frame_header += struct.pack("!Q", length)
-
-        if not self.mask:
-            return frame_header + self.data
-        else:
-            mask_key = self.get_mask_key(4)
-            return frame_header + self._get_masked(mask_key)
-
-    def _get_masked(self, mask_key):
-        s = ABNF.mask(mask_key, self.data)
-
-        if isinstance(mask_key, six.text_type):
-            mask_key = mask_key.encode('utf-8')
-
-        return mask_key + s
-
-    @staticmethod
-    def mask(mask_key, data):
-        """
-        mask or unmask data. Just do xor for each byte
-
-        mask_key: 4 byte string(byte).
-
-        data: data to mask/unmask.
-        """
-        if data is None:
-            data = ""
-
-        if isinstance(mask_key, six.text_type):
-            mask_key = six.b(mask_key)
-
-        if isinstance(data, six.text_type):
-            data = six.b(data)
-
-        _m = array.array("B", mask_key)
-        _d = array.array("B", data)
-        return _mask(_m, _d)
-
-
-class frame_buffer(object):
-    _HEADER_MASK_INDEX = 5
-    _HEADER_LENGTH_INDEX = 6
-
-    def __init__(self, recv_fn, skip_utf8_validation):
-        self.recv = recv_fn
-        self.skip_utf8_validation = skip_utf8_validation
-        # Buffers over the packets from the layer beneath until desired amount
-        # bytes of bytes are received.
-        self.recv_buffer = []
-        self.clear()
-
-    def clear(self):
-        self.header = None
-        self.length = None
-        self.mask = None
-
-    def has_received_header(self):
-        return self.header is None
-
-    def recv_header(self):
-        header = self.recv_strict(2)
-        b1 = header[0]
-
-        if six.PY2:
-            b1 = ord(b1)
-
-        fin = b1 >> 7 & 1
-        rsv1 = b1 >> 6 & 1
-        rsv2 = b1 >> 5 & 1
-        rsv3 = b1 >> 4 & 1
-        opcode = b1 & 0xf
-        b2 = header[1]
-
-        if six.PY2:
-            b2 = ord(b2)
-
-        has_mask = b2 >> 7 & 1
-        length_bits = b2 & 0x7f
-
-        self.header = (fin, rsv1, rsv2, rsv3, opcode, has_mask, length_bits)
-
-    def has_mask(self):
-        if not self.header:
-            return False
-        return self.header[frame_buffer._HEADER_MASK_INDEX]
-
-    def has_received_length(self):
-        return self.length is None
-
-    def recv_length(self):
-        bits = self.header[frame_buffer._HEADER_LENGTH_INDEX]
-        length_bits = bits & 0x7f
-        if length_bits == 0x7e:
-            v = self.recv_strict(2)
-            self.length = struct.unpack("!H", v)[0]
-        elif length_bits == 0x7f:
-            v = self.recv_strict(8)
-            self.length = struct.unpack("!Q", v)[0]
-        else:
-            self.length = length_bits
-
-    def has_received_mask(self):
-        return self.mask is None
-
-    def recv_mask(self):
-        self.mask = self.recv_strict(4) if self.has_mask() else ""
-
-    def recv_frame(self):
-        # Header
-        if self.has_received_header():
-            self.recv_header()
-        (fin, rsv1, rsv2, rsv3, opcode, has_mask, _) = self.header
-
-        # Frame length
-        if self.has_received_length():
-            self.recv_length()
-        length = self.length
-
-        # Mask
-        if self.has_received_mask():
-            self.recv_mask()
-        mask = self.mask
-
-        # Payload
-        payload = self.recv_strict(length)
-        if has_mask:
-            payload = ABNF.mask(mask, payload)
-
-        # Reset for next frame
-        self.clear()
-
-        frame = ABNF(fin, rsv1, rsv2, rsv3, opcode, has_mask, payload)
-        frame.validate(self.skip_utf8_validation)
-
-        return frame
-
-    def recv_strict(self, bufsize):
-        shortage = bufsize - sum(len(x) for x in self.recv_buffer)
-        while shortage > 0:
-            # Limit buffer size that we pass to socket.recv() to avoid
-            # fragmenting the heap -- the number of bytes recv() actually
-            # reads is limited by socket buffer and is relatively small,
-            # yet passing large numbers repeatedly causes lots of large
-            # buffers allocated and then shrunk, which results in
-            # fragmentation.
-            bytes_ = self.recv(min(16384, shortage))
-            self.recv_buffer.append(bytes_)
-            shortage -= len(bytes_)
-
-        unified = six.b("").join(self.recv_buffer)
-
-        if shortage == 0:
-            self.recv_buffer = []
-            return unified
-        else:
-            self.recv_buffer = [unified[bufsize:]]
-            return unified[:bufsize]
-
-
-class continuous_frame(object):
-
-    def __init__(self, fire_cont_frame, skip_utf8_validation):
-        self.fire_cont_frame = fire_cont_frame
-        self.skip_utf8_validation = skip_utf8_validation
-        self.cont_data = None
-        self.recving_frames = None
-
-    def validate(self, frame):
-        if not self.recving_frames and frame.opcode == ABNF.OPCODE_CONT:
-            raise WebSocketProtocolException("Illegal frame")
-        if self.recving_frames and \
-                frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY):
-            raise WebSocketProtocolException("Illegal frame")
-
-    def add(self, frame):
-        if self.cont_data:
-            self.cont_data[1] += frame.data
-        else:
-            if frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY):
-                self.recving_frames = frame.opcode
-            self.cont_data = [frame.opcode, frame.data]
-
-        if frame.fin:
-            self.recving_frames = None
-
-    def is_fire(self, frame):
-        return frame.fin or self.fire_cont_frame
-
-    def extract(self, frame):
-        data = self.cont_data
-        self.cont_data = None
-        frame.data = data[1]
-        if not self.fire_cont_frame and data[0] == ABNF.OPCODE_TEXT and not self.skip_utf8_validation and not validate_utf8(frame.data):
-            raise WebSocketPayloadException(
-                "cannot decode: " + repr(frame.data))
-
-        return [data[0], frame]
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_app.py b/catapult/telemetry/third_party/websocket-client/websocket/_app.py
deleted file mode 100644
index 655f456..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_app.py
+++ /dev/null
@@ -1,273 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-
-"""
-WebSocketApp provides higher level APIs.
-"""
-import select
-import sys
-import threading
-import time
-import traceback
-
-import six
-
-from ._abnf import ABNF
-from ._core import WebSocket, getdefaulttimeout
-from ._exceptions import *
-from ._logging import *
-
-__all__ = ["WebSocketApp"]
-
-
-class WebSocketApp(object):
-    """
-    Higher level of APIs are provided.
-    The interface is like JavaScript WebSocket object.
-    """
-
-    def __init__(self, url, header=None,
-                 on_open=None, on_message=None, on_error=None,
-                 on_close=None, on_ping=None, on_pong=None,
-                 on_cont_message=None,
-                 keep_running=True, get_mask_key=None, cookie=None,
-                 subprotocols=None,
-                 on_data=None):
-        """
-        url: websocket url.
-        header: custom header for websocket handshake.
-        on_open: callable object which is called at opening websocket.
-          this function has one argument. The argument is this class object.
-        on_message: callable object which is called when received data.
-         on_message has 2 arguments.
-         The 1st argument is this class object.
-         The 2nd argument is utf-8 string which we get from the server.
-        on_error: callable object which is called when we get error.
-         on_error has 2 arguments.
-         The 1st argument is this class object.
-         The 2nd argument is exception object.
-        on_close: callable object which is called when closed the connection.
-         this function has one argument. The argument is this class object.
-        on_cont_message: callback object which is called when receive continued
-         frame data.
-         on_cont_message has 3 arguments.
-         The 1st argument is this class object.
-         The 2nd argument is utf-8 string which we get from the server.
-         The 3rd argument is continue flag. if 0, the data continue
-         to next frame data
-        on_data: callback object which is called when a message received.
-          This is called before on_message or on_cont_message,
-          and then on_message or on_cont_message is called.
-          on_data has 4 argument.
-          The 1st argument is this class object.
-          The 2nd argument is utf-8 string which we get from the server.
-          The 3rd argument is data type. ABNF.OPCODE_TEXT or ABNF.OPCODE_BINARY will be came.
-          The 4th argument is continue flag. if 0, the data continue
-        keep_running: a boolean flag indicating whether the app's main loop
-          should keep running, defaults to True
-        get_mask_key: a callable to produce new mask keys,
-          see the WebSocket.set_mask_key's docstring for more information
-        subprotocols: array of available sub protocols. default is None.
-        """
-        self.url = url
-        self.header = header if header is not None else []
-        self.cookie = cookie
-        self.on_open = on_open
-        self.on_message = on_message
-        self.on_data = on_data
-        self.on_error = on_error
-        self.on_close = on_close
-        self.on_ping = on_ping
-        self.on_pong = on_pong
-        self.on_cont_message = on_cont_message
-        self.keep_running = keep_running
-        self.get_mask_key = get_mask_key
-        self.sock = None
-        self.last_ping_tm = 0
-        self.last_pong_tm = 0
-        self.subprotocols = subprotocols
-
-    def send(self, data, opcode=ABNF.OPCODE_TEXT):
-        """
-        send message.
-        data: message to send. If you set opcode to OPCODE_TEXT,
-              data must be utf-8 string or unicode.
-        opcode: operation code of data. default is OPCODE_TEXT.
-        """
-
-        if not self.sock or self.sock.send(data, opcode) == 0:
-            raise WebSocketConnectionClosedException(
-                "Connection is already closed.")
-
-    def close(self, **kwargs):
-        """
-        close websocket connection.
-        """
-        self.keep_running = False
-        if self.sock:
-            self.sock.close(**kwargs)
-
-    def _send_ping(self, interval, event):
-        while not event.wait(interval):
-            self.last_ping_tm = time.time()
-            if self.sock:
-                try:
-                    self.sock.ping()
-                except Exception as ex:
-                    warning("send_ping routine terminated: {}".format(ex))
-                    break
-
-    def run_forever(self, sockopt=None, sslopt=None,
-                    ping_interval=0, ping_timeout=None,
-                    http_proxy_host=None, http_proxy_port=None,
-                    http_no_proxy=None, http_proxy_auth=None,
-                    skip_utf8_validation=False,
-                    host=None, origin=None):
-        """
-        run event loop for WebSocket framework.
-        This loop is infinite loop and is alive during websocket is available.
-        sockopt: values for socket.setsockopt.
-            sockopt must be tuple
-            and each element is argument of sock.setsockopt.
-        sslopt: ssl socket optional dict.
-        ping_interval: automatically send "ping" command
-            every specified period(second)
-            if set to 0, not send automatically.
-        ping_timeout: timeout(second) if the pong message is not received.
-        http_proxy_host: http proxy host name.
-        http_proxy_port: http proxy port. If not set, set to 80.
-        http_no_proxy: host names, which doesn't use proxy.
-        skip_utf8_validation: skip utf8 validation.
-        host: update host header.
-        origin: update origin header.
-        """
-
-        if not ping_timeout or ping_timeout <= 0:
-            ping_timeout = None
-        if ping_timeout and ping_interval and ping_interval <= ping_timeout:
-            raise WebSocketException("Ensure ping_interval > ping_timeout")
-        if sockopt is None:
-            sockopt = []
-        if sslopt is None:
-            sslopt = {}
-        if self.sock:
-            raise WebSocketException("socket is already opened")
-        thread = None
-        close_frame = None
-
-        try:
-            self.sock = WebSocket(
-                self.get_mask_key, sockopt=sockopt, sslopt=sslopt,
-                fire_cont_frame=self.on_cont_message and True or False,
-                skip_utf8_validation=skip_utf8_validation)
-            self.sock.settimeout(getdefaulttimeout())
-            self.sock.connect(
-                self.url, header=self.header, cookie=self.cookie,
-                http_proxy_host=http_proxy_host,
-                http_proxy_port=http_proxy_port, http_no_proxy=http_no_proxy,
-                http_proxy_auth=http_proxy_auth, subprotocols=self.subprotocols,
-                host=host, origin=origin)
-            self._callback(self.on_open)
-
-            if ping_interval:
-                event = threading.Event()
-                thread = threading.Thread(
-                    target=self._send_ping, args=(ping_interval, event))
-                thread.setDaemon(True)
-                thread.start()
-
-            while self.sock.connected:
-                r, w, e = select.select(
-                    (self.sock.sock, ), (), (), ping_timeout)
-                if not self.keep_running:
-                    break
-
-                if r:
-                    op_code, frame = self.sock.recv_data_frame(True)
-                    if op_code == ABNF.OPCODE_CLOSE:
-                        close_frame = frame
-                        break
-                    elif op_code == ABNF.OPCODE_PING:
-                        self._callback(self.on_ping, frame.data)
-                    elif op_code == ABNF.OPCODE_PONG:
-                        self.last_pong_tm = time.time()
-                        self._callback(self.on_pong, frame.data)
-                    elif op_code == ABNF.OPCODE_CONT and self.on_cont_message:
-                        self._callback(self.on_data, data,
-                                       frame.opcode, frame.fin)
-                        self._callback(self.on_cont_message,
-                                       frame.data, frame.fin)
-                    else:
-                        data = frame.data
-                        if six.PY3 and op_code == ABNF.OPCODE_TEXT:
-                            data = data.decode("utf-8")
-                        self._callback(self.on_data, data, frame.opcode, True)
-                        self._callback(self.on_message, data)
-
-                if ping_timeout and self.last_ping_tm \
-                        and time.time() - self.last_ping_tm > ping_timeout \
-                        and self.last_ping_tm - self.last_pong_tm > ping_timeout:
-                    raise WebSocketTimeoutException("ping/pong timed out")
-        except (Exception, KeyboardInterrupt, SystemExit) as e:
-            self._callback(self.on_error, e)
-            if isinstance(e, SystemExit):
-                # propagate SystemExit further
-                raise
-        finally:
-            if thread and thread.isAlive():
-                event.set()
-                thread.join()
-                self.keep_running = False
-            self.sock.close()
-            close_args = self._get_close_args(
-                close_frame.data if close_frame else None)
-            self._callback(self.on_close, *close_args)
-            self.sock = None
-
-    def _get_close_args(self, data):
-        """ this functions extracts the code, reason from the close body
-        if they exists, and if the self.on_close except three arguments """
-        import inspect
-        # if the on_close callback is "old", just return empty list
-        if sys.version_info < (3, 0):
-            if not self.on_close or len(inspect.getargspec(self.on_close).args) != 3:
-                return []
-        else:
-            if not self.on_close or len(inspect.getfullargspec(self.on_close).args) != 3:
-                return []
-
-        if data and len(data) >= 2:
-            code = 256 * six.byte2int(data[0:1]) + six.byte2int(data[1:2])
-            reason = data[2:].decode('utf-8')
-            return [code, reason]
-
-        return [None, None]
-
-    def _callback(self, callback, *args):
-        if callback:
-            try:
-                callback(self, *args)
-            except Exception as e:
-                error("error from callback {}: {}".format(callback, e))
-                if isEnabledForDebug():
-                    _, _, tb = sys.exc_info()
-                    traceback.print_tb(tb)
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_core.py b/catapult/telemetry/third_party/websocket-client/websocket/_core.py
deleted file mode 100644
index adcdb6b..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_core.py
+++ /dev/null
@@ -1,488 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-from __future__ import print_function
-
-import socket
-import struct
-import threading
-
-import six
-
-# websocket modules
-from ._abnf import *
-from ._exceptions import *
-from ._handshake import *
-from ._http import *
-from ._logging import *
-from ._socket import *
-from ._utils import *
-
-__all__ = ['WebSocket', 'create_connection']
-
-"""
-websocket python client.
-=========================
-
-This version support only hybi-13.
-Please see http://tools.ietf.org/html/rfc6455 for protocol.
-"""
-
-
-class WebSocket(object):
-    """
-    Low level WebSocket interface.
-    This class is based on
-      The WebSocket protocol draft-hixie-thewebsocketprotocol-76
-      http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
-
-    We can connect to the websocket server and send/receive data.
-    The following example is an echo client.
-
-    >>> import websocket
-    >>> ws = websocket.WebSocket()
-    >>> ws.connect("ws://echo.websocket.org")
-    >>> ws.send("Hello, Server")
-    >>> ws.recv()
-    'Hello, Server'
-    >>> ws.close()
-
-    get_mask_key: a callable to produce new mask keys, see the set_mask_key
-      function's docstring for more details
-    sockopt: values for socket.setsockopt.
-        sockopt must be tuple and each element is argument of sock.setsockopt.
-    sslopt: dict object for ssl socket option.
-    fire_cont_frame: fire recv event for each cont frame. default is False
-    enable_multithread: if set to True, lock send method.
-    skip_utf8_validation: skip utf8 validation.
-    """
-
-    def __init__(self, get_mask_key=None, sockopt=None, sslopt=None,
-                 fire_cont_frame=False, enable_multithread=False,
-                 skip_utf8_validation=False, **_):
-        """
-        Initialize WebSocket object.
-        """
-        self.sock_opt = sock_opt(sockopt, sslopt)
-        self.handshake_response = None
-        self.sock = None
-
-        self.connected = False
-        self.get_mask_key = get_mask_key
-        # These buffer over the build-up of a single frame.
-        self.frame_buffer = frame_buffer(self._recv, skip_utf8_validation)
-        self.cont_frame = continuous_frame(
-            fire_cont_frame, skip_utf8_validation)
-
-        if enable_multithread:
-            self.lock = threading.Lock()
-        else:
-            self.lock = NoLock()
-
-    def __iter__(self):
-        """
-        Allow iteration over websocket, implying sequential `recv` executions.
-        """
-        while True:
-            yield self.recv()
-
-    def __next__(self):
-        return self.recv()
-
-    def next(self):
-        return self.__next__()
-
-    def fileno(self):
-        return self.sock.fileno()
-
-    def set_mask_key(self, func):
-        """
-        set function to create musk key. You can customize mask key generator.
-        Mainly, this is for testing purpose.
-
-        func: callable object. the func takes 1 argument as integer.
-              The argument means length of mask key.
-              This func must return string(byte array),
-              which length is argument specified.
-        """
-        self.get_mask_key = func
-
-    def gettimeout(self):
-        """
-        Get the websocket timeout(second).
-        """
-        return self.sock_opt.timeout
-
-    def settimeout(self, timeout):
-        """
-        Set the timeout to the websocket.
-
-        timeout: timeout time(second).
-        """
-        self.sock_opt.timeout = timeout
-        if self.sock:
-            self.sock.settimeout(timeout)
-
-    timeout = property(gettimeout, settimeout)
-
-    def getsubprotocol(self):
-        """
-        get subprotocol
-        """
-        if self.handshake_response:
-            return self.handshake_response.subprotocol
-        else:
-            return None
-
-    subprotocol = property(getsubprotocol)
-
-    def getstatus(self):
-        """
-        get handshake status
-        """
-        if self.handshake_response:
-            return self.handshake_response.status
-        else:
-            return None
-
-    status = property(getstatus)
-
-    def getheaders(self):
-        """
-        get handshake response header
-        """
-        if self.handshake_response:
-            return self.handshake_response.headers
-        else:
-            return None
-
-    headers = property(getheaders)
-
-    def connect(self, url, **options):
-        """
-        Connect to url. url is websocket url scheme.
-        ie. ws://host:port/resource
-        You can customize using 'options'.
-        If you set "header" list object, you can set your own custom header.
-
-        >>> ws = WebSocket()
-        >>> ws.connect("ws://echo.websocket.org/",
-                ...     header=["User-Agent: MyProgram",
-                ...             "x-custom: header"])
-
-        timeout: socket timeout time. This value is integer.
-                 if you set None for this value,
-                 it means "use default_timeout value"
-
-        options: "header" -> custom http header list or dict.
-                 "cookie" -> cookie value.
-                 "origin" -> custom origin url.
-                 "host"   -> custom host header string.
-                 "http_proxy_host" - http proxy host name.
-                 "http_proxy_port" - http proxy port. If not set, set to 80.
-                 "http_no_proxy"   - host names, which doesn't use proxy.
-                 "http_proxy_auth" - http proxy auth information.
-                                     tuple of username and password.
-                                     default is None
-                 "subprotocols" - array of available sub protocols.
-                                  default is None.
-                 "socket" - pre-initialized stream socket.
-
-        """
-        self.sock, addrs = connect(url, self.sock_opt, proxy_info(**options),
-                                   options.pop('socket', None))
-
-        try:
-            self.handshake_response = handshake(self.sock, *addrs, **options)
-            self.connected = True
-        except:
-            if self.sock:
-                self.sock.close()
-                self.sock = None
-            raise
-
-    def send(self, payload, opcode=ABNF.OPCODE_TEXT):
-        """
-        Send the data as string.
-
-        payload: Payload must be utf-8 string or unicode,
-                  if the opcode is OPCODE_TEXT.
-                  Otherwise, it must be string(byte array)
-
-        opcode: operation code to send. Please see OPCODE_XXX.
-        """
-
-        frame = ABNF.create_frame(payload, opcode)
-        return self.send_frame(frame)
-
-    def send_frame(self, frame):
-        """
-        Send the data frame.
-
-        frame: frame data created  by ABNF.create_frame
-
-        >>> ws = create_connection("ws://echo.websocket.org/")
-        >>> frame = ABNF.create_frame("Hello", ABNF.OPCODE_TEXT)
-        >>> ws.send_frame(frame)
-        >>> cont_frame = ABNF.create_frame("My name is ", ABNF.OPCODE_CONT, 0)
-        >>> ws.send_frame(frame)
-        >>> cont_frame = ABNF.create_frame("Foo Bar", ABNF.OPCODE_CONT, 1)
-        >>> ws.send_frame(frame)
-
-        """
-        if self.get_mask_key:
-            frame.get_mask_key = self.get_mask_key
-        data = frame.format()
-        length = len(data)
-        trace("send: " + repr(data))
-
-        with self.lock:
-            while data:
-                l = self._send(data)
-                data = data[l:]
-
-        return length
-
-    def send_binary(self, payload):
-        return self.send(payload, ABNF.OPCODE_BINARY)
-
-    def ping(self, payload=""):
-        """
-        send ping data.
-
-        payload: data payload to send server.
-        """
-        if isinstance(payload, six.text_type):
-            payload = payload.encode("utf-8")
-        self.send(payload, ABNF.OPCODE_PING)
-
-    def pong(self, payload):
-        """
-        send pong data.
-
-        payload: data payload to send server.
-        """
-        if isinstance(payload, six.text_type):
-            payload = payload.encode("utf-8")
-        self.send(payload, ABNF.OPCODE_PONG)
-
-    def recv(self):
-        """
-        Receive string data(byte array) from the server.
-
-        return value: string(byte array) value.
-        """
-        opcode, data = self.recv_data()
-        if six.PY3 and opcode == ABNF.OPCODE_TEXT:
-            return data.decode("utf-8")
-        elif opcode == ABNF.OPCODE_TEXT or opcode == ABNF.OPCODE_BINARY:
-            return data
-        else:
-            return ''
-
-    def recv_data(self, control_frame=False):
-        """
-        Receive data with operation code.
-
-        control_frame: a boolean flag indicating whether to return control frame
-        data, defaults to False
-
-        return  value: tuple of operation code and string(byte array) value.
-        """
-        opcode, frame = self.recv_data_frame(control_frame)
-        return opcode, frame.data
-
-    def recv_data_frame(self, control_frame=False):
-        """
-        Receive data with operation code.
-
-        control_frame: a boolean flag indicating whether to return control frame
-        data, defaults to False
-
-        return  value: tuple of operation code and string(byte array) value.
-        """
-        while True:
-            frame = self.recv_frame()
-            if not frame:
-                # handle error:
-                # 'NoneType' object has no attribute 'opcode'
-                raise WebSocketProtocolException(
-                    "Not a valid frame %s" % frame)
-            elif frame.opcode in (ABNF.OPCODE_TEXT, ABNF.OPCODE_BINARY, ABNF.OPCODE_CONT):
-                self.cont_frame.validate(frame)
-                self.cont_frame.add(frame)
-
-                if self.cont_frame.is_fire(frame):
-                    return self.cont_frame.extract(frame)
-
-            elif frame.opcode == ABNF.OPCODE_CLOSE:
-                self.send_close()
-                return frame.opcode, frame
-            elif frame.opcode == ABNF.OPCODE_PING:
-                if len(frame.data) < 126:
-                    self.pong(frame.data)
-                else:
-                    raise WebSocketProtocolException(
-                        "Ping message is too long")
-                if control_frame:
-                    return frame.opcode, frame
-            elif frame.opcode == ABNF.OPCODE_PONG:
-                if control_frame:
-                    return frame.opcode, frame
-
-    def recv_frame(self):
-        """
-        receive data as frame from server.
-
-        return value: ABNF frame object.
-        """
-        return self.frame_buffer.recv_frame()
-
-    def send_close(self, status=STATUS_NORMAL, reason=six.b("")):
-        """
-        send close data to the server.
-
-        status: status code to send. see STATUS_XXX.
-
-        reason: the reason to close. This must be string or bytes.
-        """
-        if status < 0 or status >= ABNF.LENGTH_16:
-            raise ValueError("code is invalid range")
-        self.connected = False
-        self.send(struct.pack('!H', status) + reason, ABNF.OPCODE_CLOSE)
-
-    def close(self, status=STATUS_NORMAL, reason=six.b(""), timeout=3):
-        """
-        Close Websocket object
-
-        status: status code to send. see STATUS_XXX.
-
-        reason: the reason to close. This must be string.
-
-        timeout: timeout until receive a close frame.
-            If None, it will wait forever until receive a close frame.
-        """
-        if self.connected:
-            if status < 0 or status >= ABNF.LENGTH_16:
-                raise ValueError("code is invalid range")
-
-            try:
-                self.connected = False
-                self.send(struct.pack('!H', status) +
-                          reason, ABNF.OPCODE_CLOSE)
-                sock_timeout = self.sock.gettimeout()
-                self.sock.settimeout(timeout)
-                try:
-                    frame = self.recv_frame()
-                    if isEnabledForError():
-                        recv_status = struct.unpack("!H", frame.data)[0]
-                        if recv_status != STATUS_NORMAL:
-                            error("close status: " + repr(recv_status))
-                except:
-                    pass
-                self.sock.settimeout(sock_timeout)
-                self.sock.shutdown(socket.SHUT_RDWR)
-            except:
-                pass
-
-        self.shutdown()
-
-    def abort(self):
-        """
-        Low-level asynchronous abort, wakes up other threads that are waiting in recv_*
-        """
-        if self.connected:
-            self.sock.shutdown(socket.SHUT_RDWR)
-
-    def shutdown(self):
-        """close socket, immediately."""
-        if self.sock:
-            self.sock.close()
-            self.sock = None
-            self.connected = False
-
-    def _send(self, data):
-        return send(self.sock, data)
-
-    def _recv(self, bufsize):
-        try:
-            return recv(self.sock, bufsize)
-        except WebSocketConnectionClosedException:
-            if self.sock:
-                self.sock.close()
-            self.sock = None
-            self.connected = False
-            raise
-
-
-def create_connection(url, timeout=None, class_=WebSocket, **options):
-    """
-    connect to url and return websocket object.
-
-    Connect to url and return the WebSocket object.
-    Passing optional timeout parameter will set the timeout on the socket.
-    If no timeout is supplied,
-    the global default timeout setting returned by getdefauttimeout() is used.
-    You can customize using 'options'.
-    If you set "header" list object, you can set your own custom header.
-
-    >>> conn = create_connection("ws://echo.websocket.org/",
-         ...     header=["User-Agent: MyProgram",
-         ...             "x-custom: header"])
-
-
-    timeout: socket timeout time. This value is integer.
-             if you set None for this value,
-             it means "use default_timeout value"
-
-    class_: class to instantiate when creating the connection. It has to implement
-            settimeout and connect. It's __init__ should be compatible with
-            WebSocket.__init__, i.e. accept all of it's kwargs.
-    options: "header" -> custom http header list or dict.
-             "cookie" -> cookie value.
-             "origin" -> custom origin url.
-             "host"   -> custom host header string.
-             "http_proxy_host" - http proxy host name.
-             "http_proxy_port" - http proxy port. If not set, set to 80.
-             "http_no_proxy"   - host names, which doesn't use proxy.
-             "http_proxy_auth" - http proxy auth information.
-                                    tuple of username and password.
-                                    default is None
-             "enable_multithread" -> enable lock for multithread.
-             "sockopt" -> socket options
-             "sslopt" -> ssl option
-             "subprotocols" - array of available sub protocols.
-                              default is None.
-             "skip_utf8_validation" - skip utf8 validation.
-             "socket" - pre-initialized stream socket.
-    """
-    sockopt = options.pop("sockopt", [])
-    sslopt = options.pop("sslopt", {})
-    fire_cont_frame = options.pop("fire_cont_frame", False)
-    enable_multithread = options.pop("enable_multithread", False)
-    skip_utf8_validation = options.pop("skip_utf8_validation", False)
-    websock = class_(sockopt=sockopt, sslopt=sslopt,
-                     fire_cont_frame=fire_cont_frame,
-                     enable_multithread=enable_multithread,
-                     skip_utf8_validation=skip_utf8_validation, **options)
-    websock.settimeout(timeout if timeout is not None else getdefaulttimeout())
-    websock.connect(url, **options)
-    return websock
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_exceptions.py b/catapult/telemetry/third_party/websocket-client/websocket/_exceptions.py
deleted file mode 100644
index 9d1a3bc..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_exceptions.py
+++ /dev/null
@@ -1,80 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-
-
-"""
-define websocket exceptions
-"""
-
-
-class WebSocketException(Exception):
-    """
-    websocket exception class.
-    """
-    pass
-
-
-class WebSocketProtocolException(WebSocketException):
-    """
-    If the websocket protocol is invalid, this exception will be raised.
-    """
-    pass
-
-
-class WebSocketPayloadException(WebSocketException):
-    """
-    If the websocket payload is invalid, this exception will be raised.
-    """
-    pass
-
-
-class WebSocketConnectionClosedException(WebSocketException):
-    """
-    If remote host closed the connection or some network error happened,
-    this exception will be raised.
-    """
-    pass
-
-
-class WebSocketTimeoutException(WebSocketException):
-    """
-    WebSocketTimeoutException will be raised at socket timeout during read/write data.
-    """
-    pass
-
-
-class WebSocketProxyException(WebSocketException):
-    """
-    WebSocketProxyException will be raised when proxy error occurred.
-    """
-    pass
-
-
-class WebSocketBadStatusException(WebSocketException):
-    """
-    WebSocketBadStatusException will be raised when we get bad handshake status code.
-    """
-
-    def __init__(self, message, status_code):
-        super(WebSocketBadStatusException, self).__init__(
-            message % status_code)
-        self.status_code = status_code
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_handshake.py b/catapult/telemetry/third_party/websocket-client/websocket/_handshake.py
deleted file mode 100644
index f2c5352..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_handshake.py
+++ /dev/null
@@ -1,167 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-import hashlib
-import hmac
-import os
-
-import six
-
-from ._exceptions import *
-from ._http import *
-from ._logging import *
-from ._socket import *
-
-if six.PY3:
-    from base64 import encodebytes as base64encode
-else:
-    from base64 import encodestring as base64encode
-
-__all__ = ["handshake_response", "handshake"]
-
-if hasattr(hmac, "compare_digest"):
-    compare_digest = hmac.compare_digest
-else:
-    def compare_digest(s1, s2):
-        return s1 == s2
-
-# websocket supported version.
-VERSION = 13
-
-
-class handshake_response(object):
-
-    def __init__(self, status, headers, subprotocol):
-        self.status = status
-        self.headers = headers
-        self.subprotocol = subprotocol
-
-
-def handshake(sock, hostname, port, resource, **options):
-    headers, key = _get_handshake_headers(resource, hostname, port, options)
-
-    header_str = "\r\n".join(headers)
-    send(sock, header_str)
-    dump("request header", header_str)
-
-    status, resp = _get_resp_headers(sock)
-    success, subproto = _validate(resp, key, options.get("subprotocols"))
-    if not success:
-        raise WebSocketException("Invalid WebSocket Header")
-
-    return handshake_response(status, resp, subproto)
-
-
-def _get_handshake_headers(resource, host, port, options):
-    headers = [
-        "GET %s HTTP/1.1" % resource,
-        "Upgrade: websocket",
-        "Connection: Upgrade"
-    ]
-    if port == 80 or port == 443:
-        hostport = host
-    else:
-        hostport = "%s:%d" % (host, port)
-
-    if "host" in options and options["host"]:
-        headers.append("Host: %s" % options["host"])
-    else:
-        headers.append("Host: %s" % hostport)
-
-    if "origin" in options and options["origin"]:
-        headers.append("Origin: %s" % options["origin"])
-    else:
-        headers.append("Origin: http://%s" % hostport)
-
-    key = _create_sec_websocket_key()
-    headers.append("Sec-WebSocket-Key: %s" % key)
-    headers.append("Sec-WebSocket-Version: %s" % VERSION)
-
-    subprotocols = options.get("subprotocols")
-    if subprotocols:
-        headers.append("Sec-WebSocket-Protocol: %s" % ",".join(subprotocols))
-
-    if "header" in options:
-        header = options["header"]
-        if isinstance(header, dict):
-            header = map(": ".join, header.items())
-        headers.extend(header)
-
-    cookie = options.get("cookie", None)
-
-    if cookie:
-        headers.append("Cookie: %s" % cookie)
-
-    headers.append("")
-    headers.append("")
-
-    return headers, key
-
-
-def _get_resp_headers(sock, success_status=101):
-    status, resp_headers = read_headers(sock)
-    if status != success_status:
-        raise WebSocketBadStatusException("Handshake status %d", status)
-    return status, resp_headers
-
-_HEADERS_TO_CHECK = {
-    "upgrade": "websocket",
-    "connection": "upgrade",
-}
-
-
-def _validate(headers, key, subprotocols):
-    subproto = None
-    for k, v in _HEADERS_TO_CHECK.items():
-        r = headers.get(k, None)
-        if not r:
-            return False, None
-        r = r.lower()
-        if v != r:
-            return False, None
-
-    if subprotocols:
-        subproto = headers.get("sec-websocket-protocol", None).lower()
-        if not subproto or subproto not in [s.lower() for s in subprotocols]:
-            error("Invalid subprotocol: " + str(subprotocols))
-            return False, None
-
-    result = headers.get("sec-websocket-accept", None)
-    if not result:
-        return False, None
-    result = result.lower()
-
-    if isinstance(result, six.text_type):
-        result = result.encode('utf-8')
-
-    value = (key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").encode('utf-8')
-    hashed = base64encode(hashlib.sha1(value).digest()).strip().lower()
-    success = compare_digest(hashed, result)
-
-    if success:
-        return True, subproto
-    else:
-        return False, None
-
-
-def _create_sec_websocket_key():
-    randomness = os.urandom(16)
-    return base64encode(randomness).decode('utf-8').strip()
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_http.py b/catapult/telemetry/third_party/websocket-client/websocket/_http.py
deleted file mode 100644
index de1efdc..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_http.py
+++ /dev/null
@@ -1,242 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-import errno
-import os
-import socket
-import sys
-
-import six
-
-from ._exceptions import *
-from ._logging import *
-from ._socket import*
-from ._ssl_compat import *
-from ._url import *
-
-if six.PY3:
-    from base64 import encodebytes as base64encode
-else:
-    from base64 import encodestring as base64encode
-
-__all__ = ["proxy_info", "connect", "read_headers"]
-
-
-class proxy_info(object):
-
-    def __init__(self, **options):
-        self.host = options.get("http_proxy_host", None)
-        if self.host:
-            self.port = options.get("http_proxy_port", 0)
-            self.auth = options.get("http_proxy_auth", None)
-            self.no_proxy = options.get("http_no_proxy", None)
-        else:
-            self.port = 0
-            self.auth = None
-            self.no_proxy = None
-
-
-def connect(url, options, proxy, socket):
-    hostname, port, resource, is_secure = parse_url(url)
-
-    if socket:
-        return socket, (hostname, port, resource)
-
-    addrinfo_list, need_tunnel, auth = _get_addrinfo_list(
-        hostname, port, is_secure, proxy)
-    if not addrinfo_list:
-        raise WebSocketException(
-            "Host not found.: " + hostname + ":" + str(port))
-
-    sock = None
-    try:
-        sock = _open_socket(addrinfo_list, options.sockopt, options.timeout)
-        if need_tunnel:
-            sock = _tunnel(sock, hostname, port, auth)
-
-        if is_secure:
-            if HAVE_SSL:
-                sock = _ssl_socket(sock, options.sslopt, hostname)
-            else:
-                raise WebSocketException("SSL not available.")
-
-        return sock, (hostname, port, resource)
-    except:
-        if sock:
-            sock.close()
-        raise
-
-
-def _get_addrinfo_list(hostname, port, is_secure, proxy):
-    phost, pport, pauth = get_proxy_info(
-        hostname, is_secure, proxy.host, proxy.port, proxy.auth, proxy.no_proxy)
-    if not phost:
-        addrinfo_list = socket.getaddrinfo(
-            hostname, port, 0, 0, socket.SOL_TCP)
-        return addrinfo_list, False, None
-    else:
-        pport = pport and pport or 80
-        addrinfo_list = socket.getaddrinfo(phost, pport, 0, 0, socket.SOL_TCP)
-        return addrinfo_list, True, pauth
-
-
-def _open_socket(addrinfo_list, sockopt, timeout):
-    err = None
-    for addrinfo in addrinfo_list:
-        family = addrinfo[0]
-        sock = socket.socket(family)
-        sock.settimeout(timeout)
-        for opts in DEFAULT_SOCKET_OPTION:
-            sock.setsockopt(*opts)
-        for opts in sockopt:
-            sock.setsockopt(*opts)
-
-        address = addrinfo[4]
-        try:
-            sock.connect(address)
-        except socket.error as error:
-            error.remote_ip = str(address[0])
-            if error.errno in (errno.ECONNREFUSED, ):
-                err = error
-                continue
-            else:
-                raise
-        else:
-            break
-    else:
-        raise err
-
-    return sock
-
-
-def _can_use_sni():
-    return six.PY2 and sys.version_info >= (2, 7, 9) or sys.version_info >= (3, 2)
-
-
-def _wrap_sni_socket(sock, sslopt, hostname, check_hostname):
-    context = ssl.SSLContext(sslopt.get('ssl_version', ssl.PROTOCOL_SSLv23))
-
-    if sslopt.get('cert_reqs', ssl.CERT_NONE) != ssl.CERT_NONE:
-        context.load_verify_locations(cafile=sslopt.get('ca_certs', None))
-    if sslopt.get('certfile', None):
-        context.load_cert_chain(
-            sslopt['certfile'],
-            sslopt.get('keyfile', None),
-            sslopt.get('password', None),
-        )
-    # see
-    # https://github.com/liris/websocket-client/commit/b96a2e8fa765753e82eea531adb19716b52ca3ca#commitcomment-10803153
-    context.verify_mode = sslopt['cert_reqs']
-    if HAVE_CONTEXT_CHECK_HOSTNAME:
-        context.check_hostname = check_hostname
-    if 'ciphers' in sslopt:
-        context.set_ciphers(sslopt['ciphers'])
-    if 'cert_chain' in sslopt:
-        certfile, keyfile, password = sslopt['cert_chain']
-        context.load_cert_chain(certfile, keyfile, password)
-
-    return context.wrap_socket(
-        sock,
-        do_handshake_on_connect=sslopt.get('do_handshake_on_connect', True),
-        suppress_ragged_eofs=sslopt.get('suppress_ragged_eofs', True),
-        server_hostname=hostname,
-    )
-
-
-def _ssl_socket(sock, user_sslopt, hostname):
-    sslopt = dict(cert_reqs=ssl.CERT_REQUIRED)
-    sslopt.update(user_sslopt)
-
-    if os.environ.get('WEBSOCKET_CLIENT_CA_BUNDLE'):
-        certPath = os.environ.get('WEBSOCKET_CLIENT_CA_BUNDLE')
-    else:
-        certPath = os.path.join(
-            os.path.dirname(__file__), "cacert.pem")
-    if os.path.isfile(certPath) and user_sslopt.get('ca_certs', None) is None:
-        sslopt['ca_certs'] = certPath
-    check_hostname = sslopt["cert_reqs"] != ssl.CERT_NONE and sslopt.pop(
-        'check_hostname', True)
-
-    if _can_use_sni():
-        sock = _wrap_sni_socket(sock, sslopt, hostname, check_hostname)
-    else:
-        sslopt.pop('check_hostname', True)
-        sock = ssl.wrap_socket(sock, **sslopt)
-
-    if not HAVE_CONTEXT_CHECK_HOSTNAME and check_hostname:
-        match_hostname(sock.getpeercert(), hostname)
-
-    return sock
-
-
-def _tunnel(sock, host, port, auth):
-    debug("Connecting proxy...")
-    connect_header = "CONNECT %s:%d HTTP/1.0\r\n" % (host, port)
-    # TODO: support digest auth.
-    if auth and auth[0]:
-        auth_str = auth[0]
-        if auth[1]:
-            auth_str += ":" + auth[1]
-        encoded_str = base64encode(auth_str.encode()).strip().decode()
-        connect_header += "Proxy-Authorization: Basic %s\r\n" % encoded_str
-    connect_header += "\r\n"
-    dump("request header", connect_header)
-
-    send(sock, connect_header)
-
-    try:
-        status, resp_headers = read_headers(sock)
-    except Exception as e:
-        raise WebSocketProxyException(str(e))
-
-    if status != 200:
-        raise WebSocketProxyException(
-            "failed CONNECT via proxy status: %r" % status)
-
-    return sock
-
-
-def read_headers(sock):
-    status = None
-    headers = {}
-    trace("--- response header ---")
-
-    while True:
-        line = recv_line(sock)
-        line = line.decode('utf-8').strip()
-        if not line:
-            break
-        trace(line)
-        if not status:
-
-            status_info = line.split(" ", 2)
-            status = int(status_info[1])
-        else:
-            kv = line.split(":", 1)
-            if len(kv) == 2:
-                key, value = kv
-                headers[key.lower()] = value.strip()
-            else:
-                raise WebSocketException("Invalid header")
-
-    trace("-----------------------")
-
-    return status, headers
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_logging.py b/catapult/telemetry/third_party/websocket-client/websocket/_logging.py
deleted file mode 100644
index d406db6..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_logging.py
+++ /dev/null
@@ -1,74 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-import logging
-
-_logger = logging.getLogger('websocket')
-_traceEnabled = False
-
-__all__ = ["enableTrace", "dump", "error", "warning", "debug", "trace",
-           "isEnabledForError", "isEnabledForDebug"]
-
-
-def enableTrace(traceable):
-    """
-    turn on/off the traceability.
-
-    traceable: boolean value. if set True, traceability is enabled.
-    """
-    global _traceEnabled
-    _traceEnabled = traceable
-    if traceable:
-        if not _logger.handlers:
-            _logger.addHandler(logging.StreamHandler())
-        _logger.setLevel(logging.DEBUG)
-
-
-def dump(title, message):
-    if _traceEnabled:
-        _logger.debug("--- " + title + " ---")
-        _logger.debug(message)
-        _logger.debug("-----------------------")
-
-
-def error(msg):
-    _logger.error(msg)
-
-
-def warning(msg):
-    _logger.warning(msg)
-
-
-def debug(msg):
-    _logger.debug(msg)
-
-
-def trace(msg):
-    if _traceEnabled:
-        _logger.debug(msg)
-
-
-def isEnabledForError():
-    return _logger.isEnabledFor(logging.ERROR)
-
-
-def isEnabledForDebug():
-    return _logger.isEnabledFor(logging.DEBUG)
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_socket.py b/catapult/telemetry/third_party/websocket-client/websocket/_socket.py
deleted file mode 100644
index e2e1dd2..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_socket.py
+++ /dev/null
@@ -1,125 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1335  USA
-
-"""
-import socket
-
-import six
-
-from ._exceptions import *
-from ._ssl_compat import *
-from ._utils import *
-
-DEFAULT_SOCKET_OPTION = [(socket.SOL_TCP, socket.TCP_NODELAY, 1)]
-if hasattr(socket, "SO_KEEPALIVE"):
-    DEFAULT_SOCKET_OPTION.append((socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1))
-if hasattr(socket, "TCP_KEEPIDLE"):
-    DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPIDLE, 30))
-if hasattr(socket, "TCP_KEEPINTVL"):
-    DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPINTVL, 10))
-if hasattr(socket, "TCP_KEEPCNT"):
-    DEFAULT_SOCKET_OPTION.append((socket.SOL_TCP, socket.TCP_KEEPCNT, 3))
-
-_default_timeout = None
-
-__all__ = ["DEFAULT_SOCKET_OPTION", "sock_opt", "setdefaulttimeout", "getdefaulttimeout",
-           "recv", "recv_line", "send"]
-
-
-class sock_opt(object):
-
-    def __init__(self, sockopt, sslopt):
-        if sockopt is None:
-            sockopt = []
-        if sslopt is None:
-            sslopt = {}
-        self.sockopt = sockopt
-        self.sslopt = sslopt
-        self.timeout = None
-
-
-def setdefaulttimeout(timeout):
-    """
-    Set the global timeout setting to connect.
-
-    timeout: default socket timeout time. This value is second.
-    """
-    global _default_timeout
-    _default_timeout = timeout
-
-
-def getdefaulttimeout():
-    """
-    Return the global timeout setting(second) to connect.
-    """
-    return _default_timeout
-
-
-def recv(sock, bufsize):
-    if not sock:
-        raise WebSocketConnectionClosedException("socket is already closed.")
-
-    try:
-        bytes_ = sock.recv(bufsize)
-    except socket.timeout as e:
-        message = extract_err_message(e)
-        raise WebSocketTimeoutException(message)
-    except SSLError as e:
-        message = extract_err_message(e)
-        if message == "The read operation timed out":
-            raise WebSocketTimeoutException(message)
-        else:
-            raise
-
-    if not bytes_:
-        raise WebSocketConnectionClosedException(
-            "Connection is already closed.")
-
-    return bytes_
-
-
-def recv_line(sock):
-    line = []
-    while True:
-        c = recv(sock, 1)
-        line.append(c)
-        if c == six.b("\n"):
-            break
-    return six.b("").join(line)
-
-
-def send(sock, data):
-    if isinstance(data, six.text_type):
-        data = data.encode('utf-8')
-
-    if not sock:
-        raise WebSocketConnectionClosedException("socket is already closed.")
-
-    try:
-        return sock.send(data)
-    except socket.timeout as e:
-        message = extract_err_message(e)
-        raise WebSocketTimeoutException(message)
-    except Exception as e:
-        message = extract_err_message(e)
-        if isinstance(message, str) and "timed out" in message:
-            raise WebSocketTimeoutException(message)
-        else:
-            raise
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_ssl_compat.py b/catapult/telemetry/third_party/websocket-client/websocket/_ssl_compat.py
deleted file mode 100644
index 0304816..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_ssl_compat.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1335  USA
-
-"""
-__all__ = ["HAVE_SSL", "ssl", "SSLError"]
-
-try:
-    import ssl
-    from ssl import SSLError
-    if hasattr(ssl, 'SSLContext') and hasattr(ssl.SSLContext, 'check_hostname'):
-        HAVE_CONTEXT_CHECK_HOSTNAME = True
-    else:
-        HAVE_CONTEXT_CHECK_HOSTNAME = False
-        if hasattr(ssl, "match_hostname"):
-            from ssl import match_hostname
-        else:
-            from backports.ssl_match_hostname import match_hostname
-        __all__.append("match_hostname")
-    __all__.append("HAVE_CONTEXT_CHECK_HOSTNAME")
-
-    HAVE_SSL = True
-except ImportError:
-    # dummy class of SSLError for ssl none-support environment.
-    class SSLError(Exception):
-        pass
-
-    HAVE_SSL = False
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_url.py b/catapult/telemetry/third_party/websocket-client/websocket/_url.py
deleted file mode 100644
index f7bdf34..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_url.py
+++ /dev/null
@@ -1,160 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA  02110-1335  USA
-
-"""
-
-import os
-import socket
-import struct
-
-from six.moves.urllib.parse import urlparse
-
-
-__all__ = ["parse_url", "get_proxy_info"]
-
-
-def parse_url(url):
-    """
-    parse url and the result is tuple of
-    (hostname, port, resource path and the flag of secure mode)
-
-    url: url string.
-    """
-    if ":" not in url:
-        raise ValueError("url is invalid")
-
-    scheme, url = url.split(":", 1)
-
-    parsed = urlparse(url, scheme="ws")
-    if parsed.hostname:
-        hostname = parsed.hostname
-    else:
-        raise ValueError("hostname is invalid")
-    port = 0
-    if parsed.port:
-        port = parsed.port
-
-    is_secure = False
-    if scheme == "ws":
-        if not port:
-            port = 80
-    elif scheme == "wss":
-        is_secure = True
-        if not port:
-            port = 443
-    else:
-        raise ValueError("scheme %s is invalid" % scheme)
-
-    if parsed.path:
-        resource = parsed.path
-    else:
-        resource = "/"
-
-    if parsed.query:
-        resource += "?" + parsed.query
-
-    return hostname, port, resource, is_secure
-
-
-DEFAULT_NO_PROXY_HOST = ["localhost", "127.0.0.1"]
-
-
-def _is_ip_address(addr):
-    try:
-        socket.inet_aton(addr)
-    except socket.error:
-        return False
-    else:
-        return True
-
-
-def _is_subnet_address(hostname):
-    try:
-        addr, netmask = hostname.split("/")
-        return _is_ip_address(addr) and 0 <= int(netmask) < 32
-    except ValueError:
-        return False
-
-
-def _is_address_in_network(ip, net):
-    ipaddr = struct.unpack('I', socket.inet_aton(ip))[0]
-    netaddr, bits = net.split('/')
-    netmask = struct.unpack('I', socket.inet_aton(netaddr))[0] & ((2 << int(bits) - 1) - 1)
-    return ipaddr & netmask == netmask
-
-
-def _is_no_proxy_host(hostname, no_proxy):
-    if not no_proxy:
-        v = os.environ.get("no_proxy", "").replace(" ", "")
-        no_proxy = v.split(",")
-    if not no_proxy:
-        no_proxy = DEFAULT_NO_PROXY_HOST
-
-    if hostname in no_proxy:
-        return True
-    elif _is_ip_address(hostname):
-        return any([_is_address_in_network(hostname, subnet) for subnet in no_proxy if _is_subnet_address(subnet)])
-
-    return False
-
-
-def get_proxy_info(
-        hostname, is_secure, proxy_host=None, proxy_port=0, proxy_auth=None,
-        no_proxy=None):
-    """
-    try to retrieve proxy host and port from environment
-    if not provided in options.
-    result is (proxy_host, proxy_port, proxy_auth).
-    proxy_auth is tuple of username and password
-     of proxy authentication information.
-
-    hostname: websocket server name.
-
-    is_secure:  is the connection secure? (wss)
-                looks for "https_proxy" in env
-                before falling back to "http_proxy"
-
-    options:    "http_proxy_host" - http proxy host name.
-                "http_proxy_port" - http proxy port.
-                "http_no_proxy"   - host names, which doesn't use proxy.
-                "http_proxy_auth" - http proxy auth information.
-                                    tuple of username and password.
-                                    default is None
-    """
-    if _is_no_proxy_host(hostname, no_proxy):
-        return None, 0, None
-
-    if proxy_host:
-        port = proxy_port
-        auth = proxy_auth
-        return proxy_host, port, auth
-
-    env_keys = ["http_proxy"]
-    if is_secure:
-        env_keys.insert(0, "https_proxy")
-
-    for key in env_keys:
-        value = os.environ.get(key, None)
-        if value:
-            proxy = urlparse(value)
-            auth = (proxy.username, proxy.password) if proxy.username else None
-            return proxy.hostname, proxy.port, auth
-
-    return None, 0, None
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/_utils.py b/catapult/telemetry/third_party/websocket-client/websocket/_utils.py
deleted file mode 100644
index 399fb89..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/_utils.py
+++ /dev/null
@@ -1,105 +0,0 @@
-"""
-websocket - WebSocket client library for Python
-
-Copyright (C) 2010 Hiroki Ohtani(liris)
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Lesser General Public
-    License as published by the Free Software Foundation; either
-    version 2.1 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Lesser General Public License for more details.
-
-    You should have received a copy of the GNU Lesser General Public
-    License along with this library; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1335  USA
-
-"""
-import six
-
-__all__ = ["NoLock", "validate_utf8", "extract_err_message"]
-
-
-class NoLock(object):
-
-    def __enter__(self):
-        pass
-
-    def __exit__(self, exc_type, exc_value, traceback):
-        pass
-
-try:
-    # If wsaccel is available we use compiled routines to validate UTF-8
-    # strings.
-    from wsaccel.utf8validator import Utf8Validator
-
-    def _validate_utf8(utfbytes):
-        return Utf8Validator().validate(utfbytes)[0]
-
-except ImportError:
-    # UTF-8 validator
-    # python implementation of http://bjoern.hoehrmann.de/utf-8/decoder/dfa/
-
-    _UTF8_ACCEPT = 0
-    _UTF8_REJECT = 12
-
-    _UTF8D = [
-        # The first part of the table maps bytes to character classes that
-        # to reduce the size of the transition table and create bitmasks.
-        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
-        7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-        8,8,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
-        10,3,3,3,3,3,3,3,3,3,3,3,3,4,3,3, 11,6,6,6,5,8,8,8,8,8,8,8,8,8,8,8,
-
-        # The second part is a transition table that maps a combination
-        # of a state of the automaton and a character class to a state.
-        0,12,24,36,60,96,84,12,12,12,48,72, 12,12,12,12,12,12,12,12,12,12,12,12,
-        12, 0,12,12,12,12,12, 0,12, 0,12,12, 12,24,12,12,12,12,12,24,12,24,12,12,
-        12,12,12,12,12,12,12,24,12,12,12,12, 12,24,12,12,12,12,12,12,12,24,12,12,
-        12,12,12,12,12,12,12,36,12,36,12,12, 12,36,12,12,12,12,12,36,12,36,12,12,
-        12,36,12,12,12,12,12,12,12,12,12,12, ]
-
-    def _decode(state, codep, ch):
-        tp = _UTF8D[ch]
-
-        codep = (ch & 0x3f) | (codep << 6) if (
-            state != _UTF8_ACCEPT) else (0xff >> tp) & ch
-        state = _UTF8D[256 + state + tp]
-
-        return state, codep
-
-    def _validate_utf8(utfbytes):
-        state = _UTF8_ACCEPT
-        codep = 0
-        for i in utfbytes:
-            if six.PY2:
-                i = ord(i)
-            state, codep = _decode(state, codep, i)
-            if state == _UTF8_REJECT:
-                return False
-
-        return True
-
-
-def validate_utf8(utfbytes):
-    """
-    validate utf8 byte string.
-    utfbytes: utf byte string to check.
-    return value: if valid utf8 string, return true. Otherwise, return false.
-    """
-    return _validate_utf8(utfbytes)
-
-
-def extract_err_message(exception):
-    if exception.args:
-        return exception.args[0]
-    else:
-        return None
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/cacert.pem b/catapult/telemetry/third_party/websocket-client/websocket/cacert.pem
deleted file mode 100644
index e908bb6..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/cacert.pem
+++ /dev/null
@@ -1,4966 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-# Issuer: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc.
-# Subject: CN=GTE CyberTrust Global Root O=GTE Corporation OU=GTE CyberTrust Solutions, Inc.
-# Label: "GTE CyberTrust Global Root"
-# Serial: 421
-# MD5 Fingerprint: ca:3d:d3:68:f1:03:5c:d0:32:fa:b8:2b:59:e8:5a:db
-# SHA1 Fingerprint: 97:81:79:50:d8:1c:96:70:cc:34:d8:09:cf:79:44:31:36:7e:f4:74
-# SHA256 Fingerprint: a5:31:25:18:8d:21:10:aa:96:4b:02:c7:b7:c6:da:32:03:17:08:94:e5:fb:71:ff:fb:66:67:d5:e6:81:0a:36
------BEGIN CERTIFICATE-----
-MIICWjCCAcMCAgGlMA0GCSqGSIb3DQEBBAUAMHUxCzAJBgNVBAYTAlVTMRgwFgYD
-VQQKEw9HVEUgQ29ycG9yYXRpb24xJzAlBgNVBAsTHkdURSBDeWJlclRydXN0IFNv
-bHV0aW9ucywgSW5jLjEjMCEGA1UEAxMaR1RFIEN5YmVyVHJ1c3QgR2xvYmFsIFJv
-b3QwHhcNOTgwODEzMDAyOTAwWhcNMTgwODEzMjM1OTAwWjB1MQswCQYDVQQGEwJV
-UzEYMBYGA1UEChMPR1RFIENvcnBvcmF0aW9uMScwJQYDVQQLEx5HVEUgQ3liZXJU
-cnVzdCBTb2x1dGlvbnMsIEluYy4xIzAhBgNVBAMTGkdURSBDeWJlclRydXN0IEds
-b2JhbCBSb290MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCVD6C28FCc6HrH
-iM3dFw4usJTQGz0O9pTAipTHBsiQl8i4ZBp6fmw8U+E3KHNgf7KXUwefU/ltWJTS
-r41tiGeA5u2ylc9yMcqlHHK6XALnZELn+aks1joNrI1CqiQBOeacPwGFVw1Yh0X4
-04Wqk2kmhXBIgD8SFcd5tB8FLztimQIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAG3r
-GwnpXtlR22ciYaQqPEh346B8pt5zohQDhT37qw4wxYMWM4ETCJ57NE7fQMh017l9
-3PR2VX2bY1QY6fDq81yx2YtCHrnAlU66+tXifPVoYb+O7AWXX1uw16OFNMQkpw0P
-lZPvy5TYnh+dXIVtx6quTx8itc2VrbqnzPmrC3p/
------END CERTIFICATE-----
-
-# Issuer: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Subject: CN=Thawte Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Label: "Thawte Server CA"
-# Serial: 1
-# MD5 Fingerprint: c5:70:c4:a2:ed:53:78:0c:c8:10:53:81:64:cb:d0:1d
-# SHA1 Fingerprint: 23:e5:94:94:51:95:f2:41:48:03:b4:d5:64:d2:a3:a3:f5:d8:8b:8c
-# SHA256 Fingerprint: b4:41:0b:73:e2:e6:ea:ca:47:fb:c4:2f:8f:a4:01:8a:f4:38:1d:c5:4c:fa:a8:44:50:46:1e:ed:09:45:4d:e9
------BEGIN CERTIFICATE-----
-MIIDEzCCAnygAwIBAgIBATANBgkqhkiG9w0BAQQFADCBxDELMAkGA1UEBhMCWkEx
-FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
-VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
-biBTZXJ2aWNlcyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEm
-MCQGCSqGSIb3DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wHhcNOTYwODAx
-MDAwMDAwWhcNMjAxMjMxMjM1OTU5WjCBxDELMAkGA1UEBhMCWkExFTATBgNVBAgT
-DFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYDVQQKExRUaGF3
-dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNl
-cyBEaXZpc2lvbjEZMBcGA1UEAxMQVGhhd3RlIFNlcnZlciBDQTEmMCQGCSqGSIb3
-DQEJARYXc2VydmVyLWNlcnRzQHRoYXd0ZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQAD
-gY0AMIGJAoGBANOkUG7I/1Zr5s9dtuoMaHVHoqrC2oQl/Kj0R1HahbUgdJSGHg91
-yekIYfUGbTBuFRkC6VLAYttNmZ7iagxEOM3+vuNkCXDF/rFrKbYvScg71CcEJRCX
-L+eQbcAoQpnXTEPew/UhbVSfXcNY4cDk2VuwuNy0e982OsK1ZiIS1ocNAgMBAAGj
-EzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEEBQADgYEAB/pMaVz7lcxG
-7oWDTSEwjsrZqG9JGubaUeNgcGyEYRGhGshIPllDfU+VPaGLtwtimHp1it2ITk6e
-QNuozDJ0uW8NxuOzRAvZim+aKZuZGCg70eNAKJpaPNW15yAbi8qkq43pUdniTCxZ
-qdq5snUb9kLy78fyGPmJvKP/iiMucEc=
------END CERTIFICATE-----
-
-# Issuer: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Subject: CN=Thawte Premium Server CA O=Thawte Consulting cc OU=Certification Services Division
-# Label: "Thawte Premium Server CA"
-# Serial: 1
-# MD5 Fingerprint: 06:9f:69:79:16:66:90:02:1b:8c:8c:a2:c3:07:6f:3a
-# SHA1 Fingerprint: 62:7f:8d:78:27:65:63:99:d2:7d:7f:90:44:c9:fe:b3:f3:3e:fa:9a
-# SHA256 Fingerprint: ab:70:36:36:5c:71:54:aa:29:c2:c2:9f:5d:41:91:16:3b:16:2a:22:25:01:13:57:d5:6d:07:ff:a7:bc:1f:72
------BEGIN CERTIFICATE-----
-MIIDJzCCApCgAwIBAgIBATANBgkqhkiG9w0BAQQFADCBzjELMAkGA1UEBhMCWkEx
-FTATBgNVBAgTDFdlc3Rlcm4gQ2FwZTESMBAGA1UEBxMJQ2FwZSBUb3duMR0wGwYD
-VQQKExRUaGF3dGUgQ29uc3VsdGluZyBjYzEoMCYGA1UECxMfQ2VydGlmaWNhdGlv
-biBTZXJ2aWNlcyBEaXZpc2lvbjEhMB8GA1UEAxMYVGhhd3RlIFByZW1pdW0gU2Vy
-dmVyIENBMSgwJgYJKoZIhvcNAQkBFhlwcmVtaXVtLXNlcnZlckB0aGF3dGUuY29t
-MB4XDTk2MDgwMTAwMDAwMFoXDTIwMTIzMTIzNTk1OVowgc4xCzAJBgNVBAYTAlpB
-MRUwEwYDVQQIEwxXZXN0ZXJuIENhcGUxEjAQBgNVBAcTCUNhcGUgVG93bjEdMBsG
-A1UEChMUVGhhd3RlIENvbnN1bHRpbmcgY2MxKDAmBgNVBAsTH0NlcnRpZmljYXRp
-b24gU2VydmljZXMgRGl2aXNpb24xITAfBgNVBAMTGFRoYXd0ZSBQcmVtaXVtIFNl
-cnZlciBDQTEoMCYGCSqGSIb3DQEJARYZcHJlbWl1bS1zZXJ2ZXJAdGhhd3RlLmNv
-bTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA0jY2aovXwlue2oFBYo847kkE
-VdbQ7xwblRZH7xhINTpS9CtqBo87L+pW46+GjZ4X9560ZXUCTe/LCaIhUdib0GfQ
-ug2SBhRz1JPLlyoAnFxODLz6FVL88kRu2hFKbgifLy3j+ao6hnO2RlNYyIkFvYMR
-uHM/qgeN9EJN50CdHDcCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG
-9w0BAQQFAAOBgQAmSCwWwlj66BZ0DKqqX1Q/8tfJeGBeXm43YyJ3Nn6yF8Q0ufUI
-hfzJATj/Tb7yFkJD57taRvvBxhEf8UqwKEbJw8RCfbz6q1lu1bdRiBHjpIUZa4JM
-pAwSremkrj/xw0llmozFyD4lt5SZu5IycQfwhl7tUCemDaYj+bvLpgcUQg==
------END CERTIFICATE-----
-
-# Issuer: O=Equifax OU=Equifax Secure Certificate Authority
-# Subject: O=Equifax OU=Equifax Secure Certificate Authority
-# Label: "Equifax Secure CA"
-# Serial: 903804111
-# MD5 Fingerprint: 67:cb:9d:c0:13:24:8a:82:9b:b2:17:1e:d1:1b:ec:d4
-# SHA1 Fingerprint: d2:32:09:ad:23:d3:14:23:21:74:e4:0d:7f:9d:62:13:97:86:63:3a
-# SHA256 Fingerprint: 08:29:7a:40:47:db:a2:36:80:c7:31:db:6e:31:76:53:ca:78:48:e1:be:bd:3a:0b:01:79:a7:07:f9:2c:f1:78
------BEGIN CERTIFICATE-----
-MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV
-UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy
-dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1
-MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx
-dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B
-AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f
-BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A
-cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC
-AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ
-MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm
-aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw
-ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj
-IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF
-MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA
-A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y
-7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh
-1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4
------END CERTIFICATE-----
-
-# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Label: "Verisign Class 3 Public Primary Certification Authority"
-# Serial: 149843929435818692848040365716851702463
-# MD5 Fingerprint: 10:fc:63:5d:f6:26:3e:0d:f3:25:be:5f:79:cd:67:67
-# SHA1 Fingerprint: 74:2c:31:92:e6:07:e4:24:eb:45:49:54:2b:e1:bb:c5:3e:61:74:e2
-# SHA256 Fingerprint: e7:68:56:34:ef:ac:f6:9a:ce:93:9a:6b:25:5b:7b:4f:ab:ef:42:93:5b:50:a2:65:ac:b5:cb:60:27:e4:4e:70
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEHC65B0Q2Sk0tjjKewPMur8wDQYJKoZIhvcNAQECBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMTIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBAgUAA4GBALtMEivPLCYATxQT3ab7/AoRhIzzKBxnki98tsX63/Do
-lbwdj2wsqFHMc9ikwFPwTtYmwHYBV4GSXiHx0bH/59AhWM1pF+NEHJwZRDmJXNyc
-AA9WjQKZ7aKQRUzkuxCkPfAyAw7xzvjoyVGM5mKf5p/AfbdynMk2OmufTqj/ZA1k
------END CERTIFICATE-----
-
-# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network
-# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority - G2/(c) 1998 VeriSign, Inc. - For authorized use only/VeriSign Trust Network
-# Label: "Verisign Class 3 Public Primary Certification Authority - G2"
-# Serial: 167285380242319648451154478808036881606
-# MD5 Fingerprint: a2:33:9b:4c:74:78:73:d4:6c:e7:c1:f3:8d:cb:5c:e9
-# SHA1 Fingerprint: 85:37:1c:a6:e5:50:14:3d:ce:28:03:47:1b:de:3a:09:e8:f8:77:0f
-# SHA256 Fingerprint: 83:ce:3c:12:29:68:8a:59:3d:48:5f:81:97:3c:0f:91:95:43:1e:da:37:cc:5e:36:43:0e:79:c7:a8:88:63:8b
------BEGIN CERTIFICATE-----
-MIIDAjCCAmsCEH3Z/gfPqB63EHln+6eJNMYwDQYJKoZIhvcNAQEFBQAwgcExCzAJ
-BgNVBAYTAlVTMRcwFQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xh
-c3MgMyBQdWJsaWMgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcy
-MTowOAYDVQQLEzEoYykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3Jp
-emVkIHVzZSBvbmx5MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMB4X
-DTk4MDUxODAwMDAwMFoXDTI4MDgwMTIzNTk1OVowgcExCzAJBgNVBAYTAlVTMRcw
-FQYDVQQKEw5WZXJpU2lnbiwgSW5jLjE8MDoGA1UECxMzQ2xhc3MgMyBQdWJsaWMg
-UHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAtIEcyMTowOAYDVQQLEzEo
-YykgMTk5OCBWZXJpU2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5
-MR8wHQYDVQQLExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMIGfMA0GCSqGSIb3DQEB
-AQUAA4GNADCBiQKBgQDMXtERXVxp0KvTuWpMmR9ZmDCOFoUgRm1HP9SFIIThbbP4
-pO0M8RcPO/mn+SXXwc+EY/J8Y8+iR/LGWzOOZEAEaMGAuWQcRXfH2G71lSk8UOg0
-13gfqLptQ5GVj0VXXn7F+8qkBOvqlzdUMG+7AUcyM83cV5tkaWH4mx0ciU9cZwID
-AQABMA0GCSqGSIb3DQEBBQUAA4GBAFFNzb5cy5gZnBWyATl4Lk0PZ3BwmcYQWpSk
-U01UbSuvDV1Ai2TT1+7eVmGSX6bEHRBhNtMsJzzoKQm5EWR0zLVznxxIqbxhAe7i
-F6YM40AIOw7n60RzKprxaZLvcRTDOaxxp5EJb+RxBrO6WVcmeQD2+A2iMzAo1KpY
-oJ2daZH9
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
-# Subject: CN=GlobalSign Root CA O=GlobalSign nv-sa OU=Root CA
-# Label: "GlobalSign Root CA"
-# Serial: 4835703278459707669005204
-# MD5 Fingerprint: 3e:45:52:15:09:51:92:e1:b7:5d:37:9f:b1:87:29:8a
-# SHA1 Fingerprint: b1:bc:96:8b:d4:f4:9d:62:2a:a8:9a:81:f2:15:01:52:a4:1d:82:9c
-# SHA256 Fingerprint: eb:d4:10:40:e4:bb:3e:c7:42:c9:e3:81:d3:1e:f2:a4:1a:48:b6:68:5c:96:e7:ce:f3:c1:df:6c:d4:33:1c:99
------BEGIN CERTIFICATE-----
-MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkG
-A1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jv
-b3QgQ0ExGzAZBgNVBAMTEkdsb2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAw
-MDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i
-YWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJHbG9iYWxT
-aWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDaDuaZ
-jc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavp
-xy0Sy6scTHAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp
-1Wrjsok6Vjk4bwY8iGlbKk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdG
-snUOhugZitVtbNV4FpWi6cgKOOvyJBNPc1STE4U6G7weNLWLBYy5d4ux2x8gkasJ
-U26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrXgzT/LCrBbBlDSgeF59N8
-9iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0B
-AQUFAAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOz
-yj1hTdNGCbM+w6DjY1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE
-38NflNUVyRRBnMRddWQVDf9VMOyGj/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymP
-AbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhHhm4qxFYxldBniYUr+WymXUad
-DKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveCX4XSQRjbgbME
-HMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A==
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
-# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R2
-# Label: "GlobalSign Root CA - R2"
-# Serial: 4835703278459682885658125
-# MD5 Fingerprint: 94:14:77:7e:3e:5e:fd:8f:30:bd:41:b0:cf:e7:d0:30
-# SHA1 Fingerprint: 75:e0:ab:b6:13:85:12:27:1c:04:f8:5f:dd:de:38:e4:b7:24:2e:fe
-# SHA256 Fingerprint: ca:42:dd:41:74:5f:d0:b8:1e:b9:02:36:2c:f9:d8:bf:71:9d:a1:bd:1b:1e:fc:94:6f:5b:4c:99:f4:2c:1b:9e
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgILBAAAAAABD4Ym5g0wDQYJKoZIhvcNAQEFBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjIxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDYxMjE1MDgwMDAwWhcNMjExMjE1
-MDgwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMjETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAKbPJA6+Lm8omUVCxKs+IVSbC9N/hHD6ErPL
-v4dfxn+G07IwXNb9rfF73OX4YJYJkhD10FPe+3t+c4isUoh7SqbKSaZeqKeMWhG8
-eoLrvozps6yWJQeXSpkqBy+0Hne/ig+1AnwblrjFuTosvNYSuetZfeLQBoZfXklq
-tTleiDTsvHgMCJiEbKjNS7SgfQx5TfC4LcshytVsW33hoCmEofnTlEnLJGKRILzd
-C9XZzPnqJworc5HGnRusyMvo4KD0L5CLTfuwNhv2GXqF4G3yYROIXJ/gkwpRl4pa
-zq+r1feqCapgvdzZX99yqWATXgAByUr6P6TqBwMhAo6CygPCm48CAwEAAaOBnDCB
-mTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUm+IH
-V2ccHsBqBt5ZtJot39wZhi4wNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2NybC5n
-bG9iYWxzaWduLm5ldC9yb290LXIyLmNybDAfBgNVHSMEGDAWgBSb4gdXZxwewGoG
-3lm0mi3f3BmGLjANBgkqhkiG9w0BAQUFAAOCAQEAmYFThxxol4aR7OBKuEQLq4Gs
-J0/WwbgcQ3izDJr86iw8bmEbTUsp9Z8FHSbBuOmDAGJFtqkIk7mpM0sYmsL4h4hO
-291xNBrBVNpGP+DTKqttVCL1OmLNIG+6KYnX3ZHu01yiPqFbQfXf5WRDLenVOavS
-ot+3i9DAgBkcRcAtjOj4LaR0VknFBbVPFd5uRHg5h6h+u/N5GJG79G+dwfCMNYxd
-AfvDbbnvRG15RjF+Cv6pgsH/76tuIMRQyV+dTZsXjAzlAcmgQWpzU/qlULRuJQ/7
-TBj0/VLZjmmx6BEP3ojY+x1J96relc8geMJgEtslQIxq/H5COEBkEveegeGTLg==
------END CERTIFICATE-----
-
-# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority
-# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 1 Policy Validation Authority
-# Label: "ValiCert Class 1 VA"
-# Serial: 1
-# MD5 Fingerprint: 65:58:ab:15:ad:57:6c:1e:a8:a7:b5:69:ac:bf:ff:eb
-# SHA1 Fingerprint: e5:df:74:3c:b6:01:c4:9b:98:43:dc:ab:8c:e8:6a:81:10:9f:e4:8e
-# SHA256 Fingerprint: f4:c1:49:55:1a:30:13:a3:5b:c7:bf:fe:17:a7:f3:44:9b:c1:ab:5b:5a:0a:e7:4b:06:c2:3b:90:00:4c:01:04
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNTIyMjM0OFoXDTE5MDYy
-NTIyMjM0OFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDEgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYWYJ6ibiWuqYvaG9Y
-LqdUHAZu9OqNSLwxlBfw8068srg1knaw0KWlAdcAAxIiGQj4/xEjm84H9b9pGib+
-TunRf50sQB1ZaG6m+FiwnRqP0z/x3BkGgagO4DrdyFNFCQbmD3DD+kCmDuJWBQ8Y
-TfwggtFzVXSNdnKgHZ0dwN0/cQIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFBoPUn0
-LBwGlN+VYH+Wexf+T3GtZMjdd9LvWVXoP+iOBSoh8gfStadS/pyxtuJbdxdA6nLW
-I8sogTLDAHkY7FkXicnGah5xyf23dKUlRWnFSKsZ4UWKJWsZ7uW7EvV/96aNUcPw
-nXS3qT6gpf+2SQMT2iLM7XGCK5nPOrf1LXLI
------END CERTIFICATE-----
-
-# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority
-# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 2 Policy Validation Authority
-# Label: "ValiCert Class 2 VA"
-# Serial: 1
-# MD5 Fingerprint: a9:23:75:9b:ba:49:36:6e:31:c2:db:f2:e7:66:ba:87
-# SHA1 Fingerprint: 31:7a:2a:d0:7f:2b:33:5e:f5:a1:c3:4e:4b:57:e8:b7:d8:f1:fc:a6
-# SHA256 Fingerprint: 58:d0:17:27:9c:d4:dc:63:ab:dd:b1:96:a6:c9:90:6c:30:c4:e0:87:83:ea:e8:c1:60:99:54:d6:93:55:59:6b
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMTk1NFoXDTE5MDYy
-NjAwMTk1NFowgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDIgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDOOnHK5avIWZJV16vY
-dA757tn2VUdZZUcOBVXc65g2PFxTXdMwzzjsvUGJ7SVCCSRrCl6zfN1SLUzm1NZ9
-WlmpZdRJEy0kTRxQb7XBhVQ7/nHk01xC+YDgkRoKWzk2Z/M/VXwbP7RfZHM047QS
-v4dk+NoS/zcnwbNDu+97bi5p9wIDAQABMA0GCSqGSIb3DQEBBQUAA4GBADt/UG9v
-UJSZSWI4OB9L+KXIPqeCgfYrx+jFzug6EILLGACOTb2oWH+heQC1u+mNr0HZDzTu
-IYEZoDJJKPTEjlbVUjP9UNV+mWwD5MlM/Mtsq2azSiGM5bUMMj4QssxsodyamEwC
-W/POuZ6lcg5Ktz885hZo+L7tdEy8W9ViH0Pd
------END CERTIFICATE-----
-
-# Issuer: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority
-# Subject: CN=http://www.valicert.com/ O=ValiCert, Inc. OU=ValiCert Class 3 Policy Validation Authority
-# Label: "RSA Root Certificate 1"
-# Serial: 1
-# MD5 Fingerprint: a2:6f:53:b7:ee:40:db:4a:68:e7:fa:18:d9:10:4b:72
-# SHA1 Fingerprint: 69:bd:8c:f4:9c:d3:00:fb:59:2e:17:93:ca:55:6a:f3:ec:aa:35:fb
-# SHA256 Fingerprint: bc:23:f9:8a:31:3c:b9:2d:e3:bb:fc:3a:5a:9f:44:61:ac:39:49:4c:4a:e1:5a:9e:9d:f1:31:e9:9b:73:01:9a
------BEGIN CERTIFICATE-----
-MIIC5zCCAlACAQEwDQYJKoZIhvcNAQEFBQAwgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0
-IFZhbGlkYXRpb24gTmV0d29yazEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAz
-BgNVBAsTLFZhbGlDZXJ0IENsYXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9y
-aXR5MSEwHwYDVQQDExhodHRwOi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG
-9w0BCQEWEWluZm9AdmFsaWNlcnQuY29tMB4XDTk5MDYyNjAwMjIzM1oXDTE5MDYy
-NjAwMjIzM1owgbsxJDAiBgNVBAcTG1ZhbGlDZXJ0IFZhbGlkYXRpb24gTmV0d29y
-azEXMBUGA1UEChMOVmFsaUNlcnQsIEluYy4xNTAzBgNVBAsTLFZhbGlDZXJ0IENs
-YXNzIDMgUG9saWN5IFZhbGlkYXRpb24gQXV0aG9yaXR5MSEwHwYDVQQDExhodHRw
-Oi8vd3d3LnZhbGljZXJ0LmNvbS8xIDAeBgkqhkiG9w0BCQEWEWluZm9AdmFsaWNl
-cnQuY29tMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDjmFGWHOjVsQaBalfD
-cnWTq8+epvzzFlLWLU2fNUSoLgRNB0mKOCn1dzfnt6td3zZxFJmP3MKS8edgkpfs
-2Ejcv8ECIMYkpChMMFp2bbFc893enhBxoYjHW5tBbcqwuI4V7q0zK89HBFx1cQqY
-JJgpp0lZpd34t0NiYfPT4tBVPwIDAQABMA0GCSqGSIb3DQEBBQUAA4GBAFa7AliE
-Zwgs3x/be0kz9dNnnfS0ChCzycUs4pJqcXgn8nCDQtM+z6lU9PHYkhaM0QTLS6vJ
-n0WuPIqpsHEzXcjFV9+vqDWzf4mH6eglkrh/hXqu1rweN1gqZ8mRzyqBPu3GOd/A
-PhmcGcwTTYJBtYze4D1gCCAPRX5ron+jjBXu
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Label: "Verisign Class 3 Public Primary Certification Authority - G3"
-# Serial: 206684696279472310254277870180966723415
-# MD5 Fingerprint: cd:68:b6:a7:c7:c4:ce:75:e0:1d:4f:57:44:61:92:09
-# SHA1 Fingerprint: 13:2d:0d:45:53:4b:69:97:cd:b2:d5:c3:39:e2:55:76:60:9b:5c:c6
-# SHA256 Fingerprint: eb:04:cf:5e:b1:f3:9a:fa:76:2f:2b:b1:20:f2:96:cb:a5:20:c1:b9:7d:b1:58:95:65:b8:1c:b9:a1:7b:72:44
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQCbfgZJoz5iudXukEhxKe9XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
-cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
-LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
-aWduIENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
-VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
-aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
-bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
-IENsYXNzIDMgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMu6nFL8eB8aHm8b
-N3O9+MlrlBIwT/A2R/XQkQr1F8ilYcEWQE37imGQ5XYgwREGfassbqb1EUGO+i2t
-KmFZpGcmTNDovFJbcCAEWNF6yaRpvIMXZK0Fi7zQWM6NjPXr8EJJC52XJ2cybuGu
-kxUccLwgTS8Y3pKI6GyFVxEa6X7jJhFUokWWVYPKMIno3Nij7SqAP395ZVc+FSBm
-CC+Vk7+qRy+oRpfwEuL+wgorUeZ25rdGt+INpsyow0xZVYnm6FNcHOqd8GIWC6fJ
-Xwzw3sJ2zq/3avL6QaaiMxTJ5Xpj055iN9WFZZ4O5lMkdBteHRJTW8cs54NJOxWu
-imi5V5cCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAERSWwauSCPc/L8my/uRan2Te
-2yFPhpk0djZX3dAVL8WtfxUfN2JzPtTnX84XA9s1+ivbrmAJXx5fj267Cz3qWhMe
-DGBvtcC1IyIuBwvLqXTLR7sdwdela8wv0kL9Sd2nic9TutoAWii/gt/4uhMdUIaC
-/Y4wjylGsB49Ndo4YhYYSq3mtlFs3q9i6wHQHiT+eo8SGhJouPtmmRQURVyu565p
-F4ErWjfJXir0xuKhXFSbplQAz/DxwceYMBo7Nhbbo27q/a2ywtrvAkcTisDxszGt
-TxzhT5yvDwyd93gN2PQ1VoDat20Xj50egWTh/sVFuq1ruQp6Tk9LhO5L8X3dEQ==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 4 Public Primary Certification Authority - G3 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 1999 VeriSign, Inc. - For authorized use only
-# Label: "Verisign Class 4 Public Primary Certification Authority - G3"
-# Serial: 314531972711909413743075096039378935511
-# MD5 Fingerprint: db:c8:f2:27:2e:b1:ea:6a:29:23:5d:fe:56:3e:33:df
-# SHA1 Fingerprint: c8:ec:8c:87:92:69:cb:4b:ab:39:e9:8d:7e:57:67:f3:14:95:73:9d
-# SHA256 Fingerprint: e3:89:36:0d:0f:db:ae:b3:d2:50:58:4b:47:30:31:4e:22:2f:39:c1:56:a0:20:14:4e:8d:96:05:61:79:15:06
------BEGIN CERTIFICATE-----
-MIIEGjCCAwICEQDsoKeLbnVqAc/EfMwvlF7XMA0GCSqGSIb3DQEBBQUAMIHKMQsw
-CQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZl
-cmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWdu
-LCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlT
-aWduIENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
-dHkgLSBHMzAeFw05OTEwMDEwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMIHKMQswCQYD
-VQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlT
-aWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IFZlcmlTaWduLCBJ
-bmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAMTPFZlcmlTaWdu
-IENsYXNzIDQgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK3LpRFpxlmr8Y+1
-GQ9Wzsy1HyDkniYlS+BzZYlZ3tCD5PUPtbut8XzoIfzk6AzufEUiGXaStBO3IFsJ
-+mGuqPKljYXCKtbeZjbSmwL0qJJgfJxptI8kHtCGUvYynEFYHiK9zUVilQhu0Gbd
-U6LM8BDcVHOLBKFGMzNcF0C5nk3T875Vg+ixiY5afJqWIpA7iCXy0lOIAgwLePLm
-NxdLMEYH5IBtptiWLugs+BGzOA1mppvqySNb247i8xOOGlktqgLw7KSHZtzBP/XY
-ufTsgsbSPZUd5cBPhMnZo0QoBmrXRazwa2rvTl/4EYIeOGM0ZlDUPpNz+jDDZq3/
-ky2X7wMCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAj/ola09b5KROJ1WrIhVZPMq1
-CtRK26vdoV9TxaBXOcLORyu+OshWv8LZJxA6sQU8wHcxuzrTBXttmhwwjIDLk5Mq
-g6sFUYICABFna/OIYUdfA5PVWw3g8dShMjWFsjrbsIKr0csKvE+MW8VLADsfKoKm
-fjaF3H48ZwC15DtS4KjrXRX5xm3wrR0OhbepmnMUWluPQSjA1egtTaRezarZ7c7c
-2NU8Qh0XwRJdRTjDOPP8hS6DRkiy1yBfkjaP53kPmF6Z6PDQpLv1U70qzlmwr25/
-bLvSHgCwIe34QWKCudiyxLtGUPMxxY8BqHTr9Xgn2uf3ZkPznoM+IKrDNWCRzg==
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Subject: CN=Entrust.net Secure Server Certification Authority O=Entrust.net OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Label: "Entrust.net Secure Server CA"
-# Serial: 927650371
-# MD5 Fingerprint: df:f2:80:73:cc:f1:e6:61:73:fc:f5:42:e9:c5:7c:ee
-# SHA1 Fingerprint: 99:a6:9b:e6:1a:fe:88:6b:4d:2b:82:00:7c:b8:54:fc:31:7e:15:39
-# SHA256 Fingerprint: 62:f2:40:27:8c:56:4c:4d:d8:bf:7d:9d:4f:6f:36:6e:a8:94:d2:2f:5f:34:d9:89:a9:83:ac:ec:2f:ff:ed:50
------BEGIN CERTIFICATE-----
-MIIE2DCCBEGgAwIBAgIEN0rSQzANBgkqhkiG9w0BAQUFADCBwzELMAkGA1UEBhMC
-VVMxFDASBgNVBAoTC0VudHJ1c3QubmV0MTswOQYDVQQLEzJ3d3cuZW50cnVzdC5u
-ZXQvQ1BTIGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxpYWIuKTElMCMGA1UECxMc
-KGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDE6MDgGA1UEAxMxRW50cnVzdC5u
-ZXQgU2VjdXJlIFNlcnZlciBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw05OTA1
-MjUxNjA5NDBaFw0xOTA1MjUxNjM5NDBaMIHDMQswCQYDVQQGEwJVUzEUMBIGA1UE
-ChMLRW50cnVzdC5uZXQxOzA5BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5j
-b3JwLiBieSByZWYuIChsaW1pdHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBF
-bnRydXN0Lm5ldCBMaW1pdGVkMTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUg
-U2VydmVyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGdMA0GCSqGSIb3DQEBAQUA
-A4GLADCBhwKBgQDNKIM0VBuJ8w+vN5Ex/68xYMmo6LIQaO2f55M28Qpku0f1BBc/
-I0dNxScZgSYMVHINiC3ZH5oSn7yzcdOAGT9HZnuMNSjSuQrfJNqc1lB5gXpa0zf3
-wkrYKZImZNHkmGw6AIr1NJtl+O3jEP/9uElY3KDegjlrgbEWGWG5VLbmQwIBA6OC
-AdcwggHTMBEGCWCGSAGG+EIBAQQEAwIABzCCARkGA1UdHwSCARAwggEMMIHeoIHb
-oIHYpIHVMIHSMQswCQYDVQQGEwJVUzEUMBIGA1UEChMLRW50cnVzdC5uZXQxOzA5
-BgNVBAsTMnd3dy5lbnRydXN0Lm5ldC9DUFMgaW5jb3JwLiBieSByZWYuIChsaW1p
-dHMgbGlhYi4pMSUwIwYDVQQLExwoYykgMTk5OSBFbnRydXN0Lm5ldCBMaW1pdGVk
-MTowOAYDVQQDEzFFbnRydXN0Lm5ldCBTZWN1cmUgU2VydmVyIENlcnRpZmljYXRp
-b24gQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMCmgJ6AlhiNodHRwOi8vd3d3LmVu
-dHJ1c3QubmV0L0NSTC9uZXQxLmNybDArBgNVHRAEJDAigA8xOTk5MDUyNTE2MDk0
-MFqBDzIwMTkwNTI1MTYwOTQwWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAU8Bdi
-E1U9s/8KAGv7UISX8+1i0BowHQYDVR0OBBYEFPAXYhNVPbP/CgBr+1CEl/PtYtAa
-MAwGA1UdEwQFMAMBAf8wGQYJKoZIhvZ9B0EABAwwChsEVjQuMAMCBJAwDQYJKoZI
-hvcNAQEFBQADgYEAkNwwAvpkdMKnCqV8IY00F6j7Rw7/JXyNEwr75Ji174z4xRAN
-95K+8cPV1ZVqBLssziY2ZcgxxufuP+NXdYR6Ee9GTxj005i7qIcyunL2POI9n9cd
-2cNgQ4xYDiKWL2KjLB+6rQXvqzJ4h6BUcxm1XAX5Uj5tLUUL9wqT6u0G+bI=
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Subject: CN=Entrust.net Certification Authority (2048) O=Entrust.net OU=www.entrust.net/CPS_2048 incorp. by ref. (limits liab.)/(c) 1999 Entrust.net Limited
-# Label: "Entrust.net Premium 2048 Secure Server CA"
-# Serial: 946069240
-# MD5 Fingerprint: ee:29:31:bc:32:7e:9a:e6:e8:b5:f7:51:b4:34:71:90
-# SHA1 Fingerprint: 50:30:06:09:1d:97:d4:f5:ae:39:f7:cb:e7:92:7d:7d:65:2d:34:31
-# SHA256 Fingerprint: 6d:c4:71:72:e0:1c:bc:b0:bf:62:58:0d:89:5f:e2:b8:ac:9a:d4:f8:73:80:1e:0c:10:b9:c8:37:d2:1e:b1:77
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIEOGPe+DANBgkqhkiG9w0BAQUFADCBtDEUMBIGA1UEChML
-RW50cnVzdC5uZXQxQDA+BgNVBAsUN3d3dy5lbnRydXN0Lm5ldC9DUFNfMjA0OCBp
-bmNvcnAuIGJ5IHJlZi4gKGxpbWl0cyBsaWFiLikxJTAjBgNVBAsTHChjKSAxOTk5
-IEVudHJ1c3QubmV0IExpbWl0ZWQxMzAxBgNVBAMTKkVudHJ1c3QubmV0IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5ICgyMDQ4KTAeFw05OTEyMjQxNzUwNTFaFw0yOTA3
-MjQxNDE1MTJaMIG0MRQwEgYDVQQKEwtFbnRydXN0Lm5ldDFAMD4GA1UECxQ3d3d3
-LmVudHJ1c3QubmV0L0NQU18yMDQ4IGluY29ycC4gYnkgcmVmLiAobGltaXRzIGxp
-YWIuKTElMCMGA1UECxMcKGMpIDE5OTkgRW50cnVzdC5uZXQgTGltaXRlZDEzMDEG
-A1UEAxMqRW50cnVzdC5uZXQgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgKDIwNDgp
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArU1LqRKGsuqjIAcVFmQq
-K0vRvwtKTY7tgHalZ7d4QMBzQshowNtTK91euHaYNZOLGp18EzoOH1u3Hs/lJBQe
-sYGpjX24zGtLA/ECDNyrpUAkAH90lKGdCCmziAv1h3edVc3kw37XamSrhRSGlVuX
-MlBvPci6Zgzj/L24ScF2iUkZ/cCovYmjZy/Gn7xxGWC4LeksyZB2ZnuU4q941mVT
-XTzWnLLPKQP5L6RQstRIzgUyVYr9smRMDuSYB3Xbf9+5CFVghTAp+XtIpGmG4zU/
-HoZdenoVve8AjhUiVBcAkCaTvA5JaJG/+EfTnZVCwQ5N328mz8MYIWJmQ3DW1cAH
-4QIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV
-HQ4EFgQUVeSB0RGAvtiJuQijMfmhJAkWuXAwDQYJKoZIhvcNAQEFBQADggEBADub
-j1abMOdTmXx6eadNl9cZlZD7Bh/KM3xGY4+WZiT6QBshJ8rmcnPyT/4xmf3IDExo
-U8aAghOY+rat2l098c5u9hURlIIM7j+VrxGrD9cv3h8Dj1csHsm7mhpElesYT6Yf
-zX1XEC+bBAlahLVu2B064dae0Wx5XnkcFMXj0EyTO2U87d89vqbllRrDtRnDvV5b
-u/8j72gZyxKTJ1wDLW8w0B62GqzeWvfRqqgnpv55gcR5mTNXuhKwqeBCbJPKVt7+
-bYQLCIt+jerXmCHG8+c8eS9enNFMFY3h7CI3zJpDC5fcgJCNs2ebb0gIFVbPv/Er
-fF6adulZkMV8gzURZVE=
------END CERTIFICATE-----
-
-# Issuer: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
-# Subject: CN=Baltimore CyberTrust Root O=Baltimore OU=CyberTrust
-# Label: "Baltimore CyberTrust Root"
-# Serial: 33554617
-# MD5 Fingerprint: ac:b6:94:a5:9c:17:e0:d7:91:52:9b:b1:97:06:a6:e4
-# SHA1 Fingerprint: d4:de:20:d0:5e:66:fc:53:fe:1a:50:88:2c:78:db:28:52:ca:e4:74
-# SHA256 Fingerprint: 16:af:57:a9:f6:76:b0:ab:12:60:95:aa:5e:ba:de:f2:2a:b3:11:19:d6:44:ac:95:cd:4b:93:db:f3:f2:6a:eb
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
-RTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJlclRydXN0MSIwIAYD
-VQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTAwMDUxMjE4NDYwMFoX
-DTI1MDUxMjIzNTkwMFowWjELMAkGA1UEBhMCSUUxEjAQBgNVBAoTCUJhbHRpbW9y
-ZTETMBEGA1UECxMKQ3liZXJUcnVzdDEiMCAGA1UEAxMZQmFsdGltb3JlIEN5YmVy
-VHJ1c3QgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKMEuyKr
-mD1X6CZymrV51Cni4eiVgLGw41uOKymaZN+hXe2wCQVt2yguzmKiYv60iNoS6zjr
-IZ3AQSsBUnuId9Mcj8e6uYi1agnnc+gRQKfRzMpijS3ljwumUNKoUMMo6vWrJYeK
-mpYcqWe4PwzV9/lSEy/CG9VwcPCPwBLKBsua4dnKM3p31vjsufFoREJIE9LAwqSu
-XmD+tqYF/LTdB1kC1FkYmGP1pWPgkAx9XbIGevOF6uvUA65ehD5f/xXtabz5OTZy
-dc93Uk3zyZAsuT3lySNTPx8kmCFcB5kpvcY67Oduhjprl3RjM71oGDHweI12v/ye
-jl0qhqdNkNwnGjkCAwEAAaNFMEMwHQYDVR0OBBYEFOWdWTCCR1jMrPoIVDaGezq1
-BE3wMBIGA1UdEwEB/wQIMAYBAf8CAQMwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3
-DQEBBQUAA4IBAQCFDF2O5G9RaEIFoN27TyclhAO992T9Ldcw46QQF+vaKSm2eT92
-9hkTI7gQCvlYpNRhcL0EYWoSihfVCr3FvDB81ukMJY2GQE/szKN+OMY3EU/t3Wgx
-jkzSswF07r51XgdIGn9w/xZchMB5hbgF/X++ZRGjD8ACtPhSNzkE1akxehi/oCr0
-Epn3o0WC4zxe9Z2etciefC7IpJ5OCBRLbf1wbWsaY71k5h+3zvDyny67G7fyUIhz
-ksLi4xaNmjICq44Y3ekQEe5+NauQrz4wlHrQMz2nZQ/1/I6eYs9HRCwBXbsdtTLS
-R9I4LtD+gdwyah617jzV/OeBHRnDJELqYzmp
------END CERTIFICATE-----
-
-# Issuer: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
-# Subject: CN=Equifax Secure Global eBusiness CA-1 O=Equifax Secure Inc.
-# Label: "Equifax Secure Global eBusiness CA"
-# Serial: 1
-# MD5 Fingerprint: 8f:5d:77:06:27:c4:98:3c:5b:93:78:e7:d7:7d:9b:cc
-# SHA1 Fingerprint: 7e:78:4a:10:1c:82:65:cc:2d:e1:f1:6d:47:b4:40:ca:d9:0a:19:45
-# SHA256 Fingerprint: 5f:0b:62:ea:b5:e3:53:ea:65:21:65:16:58:fb:b6:53:59:f4:43:28:0a:4a:fb:d1:04:d7:7d:10:f9:f0:4c:07
------BEGIN CERTIFICATE-----
-MIICkDCCAfmgAwIBAgIBATANBgkqhkiG9w0BAQQFADBaMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEtMCsGA1UEAxMkRXF1aWZheCBT
-ZWN1cmUgR2xvYmFsIGVCdXNpbmVzcyBDQS0xMB4XDTk5MDYyMTA0MDAwMFoXDTIw
-MDYyMTA0MDAwMFowWjELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0VxdWlmYXggU2Vj
-dXJlIEluYy4xLTArBgNVBAMTJEVxdWlmYXggU2VjdXJlIEdsb2JhbCBlQnVzaW5l
-c3MgQ0EtMTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAuucXkAJlsTRVPEnC
-UdXfp9E3j9HngXNBUmCbnaEXJnitx7HoJpQytd4zjTov2/KaelpzmKNc6fuKcxtc
-58O/gGzNqfTWK8D3+ZmqY6KxRwIP1ORROhI8bIpaVIRw28HFkM9yRcuoWcDNM50/
-o5brhTMhHD4ePmBudpxnhcXIw2ECAwEAAaNmMGQwEQYJYIZIAYb4QgEBBAQDAgAH
-MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUvqigdHJQa0S3ySPY+6j/s1dr
-aGwwHQYDVR0OBBYEFL6ooHRyUGtEt8kj2Puo/7NXa2hsMA0GCSqGSIb3DQEBBAUA
-A4GBADDiAVGqx+pf2rnQZQ8w1j7aDRRJbpGTJxQx78T3LUX47Me/okENI7SS+RkA
-Z70Br83gcfxaz2TE4JaY0KNA4gGK7ycH8WUBikQtBmV1UsCGECAhX2xrD2yuCRyv
-8qIYNMR1pHMc8Y3c7635s3a0kr/clRAevsvIO1qEYBlWlKlV
------END CERTIFICATE-----
-
-# Issuer: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc.
-# Subject: CN=Equifax Secure eBusiness CA-1 O=Equifax Secure Inc.
-# Label: "Equifax Secure eBusiness CA 1"
-# Serial: 4
-# MD5 Fingerprint: 64:9c:ef:2e:44:fc:c6:8f:52:07:d0:51:73:8f:cb:3d
-# SHA1 Fingerprint: da:40:18:8b:91:89:a3:ed:ee:ae:da:97:fe:2f:9d:f5:b7:d1:8a:41
-# SHA256 Fingerprint: cf:56:ff:46:a4:a1:86:10:9d:d9:65:84:b5:ee:b5:8a:51:0c:42:75:b0:e5:f9:4f:40:bb:ae:86:5e:19:f6:73
------BEGIN CERTIFICATE-----
-MIICgjCCAeugAwIBAgIBBDANBgkqhkiG9w0BAQQFADBTMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5jLjEmMCQGA1UEAxMdRXF1aWZheCBT
-ZWN1cmUgZUJ1c2luZXNzIENBLTEwHhcNOTkwNjIxMDQwMDAwWhcNMjAwNjIxMDQw
-MDAwWjBTMQswCQYDVQQGEwJVUzEcMBoGA1UEChMTRXF1aWZheCBTZWN1cmUgSW5j
-LjEmMCQGA1UEAxMdRXF1aWZheCBTZWN1cmUgZUJ1c2luZXNzIENBLTEwgZ8wDQYJ
-KoZIhvcNAQEBBQADgY0AMIGJAoGBAM4vGbwXt3fek6lfWg0XTzQaDJj0ItlZ1MRo
-RvC0NcWFAyDGr0WlIVFFQesWWDYyb+JQYmT5/VGcqiTZ9J2DKocKIdMSODRsjQBu
-WqDZQu4aIZX5UkxVWsUPOE9G+m34LjXWHXzr4vCwdYDIqROsvojvOm6rXyo4YgKw
-Env+j6YDAgMBAAGjZjBkMBEGCWCGSAGG+EIBAQQEAwIABzAPBgNVHRMBAf8EBTAD
-AQH/MB8GA1UdIwQYMBaAFEp4MlIR21kWNl7fwRQ2QGpHfEyhMB0GA1UdDgQWBBRK
-eDJSEdtZFjZe38EUNkBqR3xMoTANBgkqhkiG9w0BAQQFAAOBgQB1W6ibAxHm6VZM
-zfmpTMANmvPMZWnmJXbMWbfWVMMdzZmsGd20hdXgPfxiIKeES1hl8eL5lSE/9dR+
-WB5Hh1Q+WKG1tfgq73HnvMP2sUlG4tega+VWeponmHxGYhTnyfxuAxJ5gDgdSIKN
-/Bf+KpYrtWKmpj29f5JZzVoqgrI3eQ==
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Subject: CN=AddTrust Class 1 CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Label: "AddTrust Low-Value Services Root"
-# Serial: 1
-# MD5 Fingerprint: 1e:42:95:02:33:92:6b:b9:5f:c0:7f:da:d6:b2:4b:fc
-# SHA1 Fingerprint: cc:ab:0e:a0:4c:23:01:d6:69:7b:dd:37:9f:cd:12:eb:24:e3:94:9d
-# SHA256 Fingerprint: 8c:72:09:27:9a:c0:4e:27:5e:16:d0:7f:d3:b7:75:e8:01:54:b5:96:80:46:e3:1f:52:dd:25:76:63:24:e9:a7
------BEGIN CERTIFICATE-----
-MIIEGDCCAwCgAwIBAgIBATANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwHhcNMDAwNTMw
-MTAzODMxWhcNMjAwNTMwMTAzODMxWjBlMQswCQYDVQQGEwJTRTEUMBIGA1UEChML
-QWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYD
-VQQDExhBZGRUcnVzdCBDbGFzcyAxIENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUA
-A4IBDwAwggEKAoIBAQCWltQhSWDia+hBBwzexODcEyPNwTXH+9ZOEQpnXvUGW2ul
-CDtbKRY654eyNAbFvAWlA3yCyykQruGIgb3WntP+LVbBFc7jJp0VLhD7Bo8wBN6n
-tGO0/7Gcrjyvd7ZWxbWroulpOj0OM3kyP3CCkplhbY0wCI9xP6ZIVxn4JdxLZlyl
-dI+Yrsj5wAYi56xz36Uu+1LcsRVlIPo1Zmne3yzxbrww2ywkEtvrNTVokMsAsJch
-PXQhI2U0K7t4WaPW4XY5mqRJjox0r26kmqPZm9I4XJuiGMx1I4S+6+JNM3GOGvDC
-+Mcdoq0Dlyz4zyXG9rgkMbFjXZJ/Y/AlyVMuH79NAgMBAAGjgdIwgc8wHQYDVR0O
-BBYEFJWxtPCUtr3H2tERCSG+wa9J/RB7MAsGA1UdDwQEAwIBBjAPBgNVHRMBAf8E
-BTADAQH/MIGPBgNVHSMEgYcwgYSAFJWxtPCUtr3H2tERCSG+wa9J/RB7oWmkZzBl
-MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFk
-ZFRydXN0IFRUUCBOZXR3b3JrMSEwHwYDVQQDExhBZGRUcnVzdCBDbGFzcyAxIENB
-IFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBACxtZBsfzQ3duQH6lmM0MkhHma6X
-7f1yFqZzR1r0693p9db7RcwpiURdv0Y5PejuvE1Uhh4dbOMXJ0PhiVYrqW9yTkkz
-43J8KiOavD7/KCrto/8cI7pDVwlnTUtiBi34/2ydYB7YHEt9tTEv2dB8Xfjea4MY
-eDdXL+gzB2ffHsdrKpV2ro9Xo/D0UrSpUwjP4E/TelOL/bscVjby/rK25Xa71SJl
-pz/+0WatC7xrmYbvP33zGDLKe8bjq2RGlfgmadlVg3sslgf/WSxEo8bl6ancoWOA
-WiFeIc9TVPC6b4nbqKqVz4vjccweGyBECMB6tkD9xOQ14R0WHNC8K47Wcdk=
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
-# Subject: CN=AddTrust External CA Root O=AddTrust AB OU=AddTrust External TTP Network
-# Label: "AddTrust External Root"
-# Serial: 1
-# MD5 Fingerprint: 1d:35:54:04:85:78:b0:3f:42:42:4d:bf:20:73:0a:3f
-# SHA1 Fingerprint: 02:fa:f3:e2:91:43:54:68:60:78:57:69:4d:f5:e4:5b:68:85:18:68
-# SHA256 Fingerprint: 68:7f:a4:51:38:22:78:ff:f0:c8:b1:1f:8d:43:d5:76:67:1c:6e:b2:bc:ea:b4:13:fb:83:d9:65:d0:6d:2f:f2
------BEGIN CERTIFICATE-----
-MIIENjCCAx6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBvMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFs
-IFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290
-MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowbzELMAkGA1UEBhMCU0Ux
-FDASBgNVBAoTC0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5h
-bCBUVFAgTmV0d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9v
-dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvt
-H7xsD821+iO2zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9
-uMq/NzgtHj6RQa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzX
-mk6vBbOmcZSccbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LX
-a0Tkx63ubUFfclpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzN
-E0S3ySvdQwAl+mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0
-WicCAwEAAaOB3DCB2TAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
-VR0PBAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wgZkGA1UdIwSBkTCBjoAUrb2YejS0
-Jvf6xCZU7wO94CTLVBqhc6RxMG8xCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtBZGRU
-cnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3QgRXh0ZXJuYWwgVFRQIE5ldHdvcmsx
-IjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFsIENBIFJvb3SCAQEwDQYJKoZIhvcN
-AQEFBQADggEBALCb4IUlwtYj4g+WBpKdQZic2YR5gdkeWxQHIzZlj7DYd7usQWxH
-YINRsPkyPef89iYTx4AWpb9a/IfPeHmJIZriTAcKhjW88t5RxNKWt9x+Tu5w/Rw5
-6wwCURQtjr0W4MHfRnXnJK3s9EK0hZNwEGe6nQY1ShjTK3rMUUKhemPR5ruhxSvC
-Nr4TDea9Y355e6cJDUCrat2PisP29owaQgVR1EX1n6diIWgVIEM8med8vSTYqZEX
-c4g/VhsxOBi0cQ+azcgOno4uG+GMmIPLHzHxREzGBHNJdmAPx/i9F4BrLunMTA5a
-mnkPIAou1Z5jJh5VkpTYghdae9C8x49OhgQ=
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Subject: CN=AddTrust Public CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Label: "AddTrust Public Services Root"
-# Serial: 1
-# MD5 Fingerprint: c1:62:3e:23:c5:82:73:9c:03:59:4b:2b:e9:77:49:7f
-# SHA1 Fingerprint: 2a:b6:28:48:5e:78:fb:f3:ad:9e:79:10:dd:6b:df:99:72:2c:96:e5
-# SHA256 Fingerprint: 07:91:ca:07:49:b2:07:82:aa:d3:c7:d7:bd:0c:df:c9:48:58:35:84:3e:b2:d7:99:60:09:ce:43:ab:6c:69:27
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIBATANBgkqhkiG9w0BAQUFADBkMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSAwHgYDVQQDExdBZGRUcnVzdCBQdWJsaWMgQ0EgUm9vdDAeFw0wMDA1MzAx
-MDQxNTBaFw0yMDA1MzAxMDQxNTBaMGQxCzAJBgNVBAYTAlNFMRQwEgYDVQQKEwtB
-ZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIDAeBgNV
-BAMTF0FkZFRydXN0IFB1YmxpYyBDQSBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOC
-AQ8AMIIBCgKCAQEA6Rowj4OIFMEg2Dybjxt+A3S72mnTRqX4jsIMEZBRpS9mVEBV
-6tsfSlbunyNu9DnLoblv8n75XYcmYZ4c+OLspoH4IcUkzBEMP9smcnrHAZcHF/nX
-GCwwfQ56HmIexkvA/X1id9NEHif2P0tEs7c42TkfYNVRknMDtABp4/MUTu7R3AnP
-dzRGULD4EfL+OHn3Bzn+UZKXC1sIXzSGAa2Il+tmzV7R/9x98oTaunet3IAIx6eH
-1lWfl2royBFkuucZKT8Rs3iQhCBSWxHveNCD9tVIkNAwHM+A+WD+eeSI8t0A65RF
-62WUaUC6wNW0uLp9BBGo6zEFlpROWCGOn9Bg/QIDAQABo4HRMIHOMB0GA1UdDgQW
-BBSBPjfYkrAfd59ctKtzquf2NGAv+jALBgNVHQ8EBAMCAQYwDwYDVR0TAQH/BAUw
-AwEB/zCBjgYDVR0jBIGGMIGDgBSBPjfYkrAfd59ctKtzquf2NGAv+qFopGYwZDEL
-MAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQLExRBZGRU
-cnVzdCBUVFAgTmV0d29yazEgMB4GA1UEAxMXQWRkVHJ1c3QgUHVibGljIENBIFJv
-b3SCAQEwDQYJKoZIhvcNAQEFBQADggEBAAP3FUr4JNojVhaTdt02KLmuG7jD8WS6
-IBh4lSknVwW8fCr0uVFV2ocC3g8WFzH4qnkuCRO7r7IgGRLlk/lL+YPoRNWyQSW/
-iHVv/xD8SlTQX/D67zZzfRs2RcYhbbQVuE7PnFylPVoAjgbjPGsye/Kf8Lb93/Ao
-GEjwxrzQvzSAlsJKsW2Ox5BF3i9nrEUEo3rcVZLJR2bYGozH7ZxOmuASu7VqTITh
-4SINhwBk/ox9Yjllpu9CtoAlEmEBqCQTcAARJl/6NVDFSMwGR+gn2HCNX2TmoUQm
-XiLsks3/QppEIW1cxeMiHV9HEufOX1362KqxMy3ZdvJOOjMMK7MtkAY=
------END CERTIFICATE-----
-
-# Issuer: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Subject: CN=AddTrust Qualified CA Root O=AddTrust AB OU=AddTrust TTP Network
-# Label: "AddTrust Qualified Certificates Root"
-# Serial: 1
-# MD5 Fingerprint: 27:ec:39:47:cd:da:5a:af:e2:9a:01:65:21:a9:4c:bb
-# SHA1 Fingerprint: 4d:23:78:ec:91:95:39:b5:00:7f:75:8f:03:3b:21:1e:c5:4d:8b:cf
-# SHA256 Fingerprint: 80:95:21:08:05:db:4b:bc:35:5e:44:28:d8:fd:6e:c2:cd:e3:ab:5f:b9:7a:99:42:98:8e:b8:f4:dc:d0:60:16
------BEGIN CERTIFICATE-----
-MIIEHjCCAwagAwIBAgIBATANBgkqhkiG9w0BAQUFADBnMQswCQYDVQQGEwJTRTEU
-MBIGA1UEChMLQWRkVHJ1c3QgQUIxHTAbBgNVBAsTFEFkZFRydXN0IFRUUCBOZXR3
-b3JrMSMwIQYDVQQDExpBZGRUcnVzdCBRdWFsaWZpZWQgQ0EgUm9vdDAeFw0wMDA1
-MzAxMDQ0NTBaFw0yMDA1MzAxMDQ0NTBaMGcxCzAJBgNVBAYTAlNFMRQwEgYDVQQK
-EwtBZGRUcnVzdCBBQjEdMBsGA1UECxMUQWRkVHJ1c3QgVFRQIE5ldHdvcmsxIzAh
-BgNVBAMTGkFkZFRydXN0IFF1YWxpZmllZCBDQSBSb290MIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA5B6a/twJWoekn0e+EV+vhDTbYjx5eLfpMLXsDBwq
-xBb/4Oxx64r1EW7tTw2R0hIYLUkVAcKkIhPHEWT/IhKauY5cLwjPcWqzZwFZ8V1G
-87B4pfYOQnrjfxvM0PC3KP0q6p6zsLkEqv32x7SxuCqg+1jxGaBvcCV+PmlKfw8i
-2O+tCBGaKZnhqkRFmhJePp1tUvznoD1oL/BLcHwTOK28FSXx1s6rosAx1i+f4P8U
-WfyEk9mHfExUE+uf0S0R+Bg6Ot4l2ffTQO2kBhLEO+GRwVY18BTcZTYJbqukB8c1
-0cIDMzZbdSZtQvESa0NvS3GU+jQd7RNuyoB/mC9suWXY6QIDAQABo4HUMIHRMB0G
-A1UdDgQWBBQ5lYtii1zJ1IC6WA+XPxUIQ8yYpzALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zCBkQYDVR0jBIGJMIGGgBQ5lYtii1zJ1IC6WA+XPxUIQ8yYp6Fr
-pGkwZzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRydXN0IEFCMR0wGwYDVQQL
-ExRBZGRUcnVzdCBUVFAgTmV0d29yazEjMCEGA1UEAxMaQWRkVHJ1c3QgUXVhbGlm
-aWVkIENBIFJvb3SCAQEwDQYJKoZIhvcNAQEFBQADggEBABmrder4i2VhlRO6aQTv
-hsoToMeqT2QbPxj2qC0sVY8FtzDqQmodwCVRLae/DLPt7wh/bDxGGuoYQ992zPlm
-hpwsaPXpF/gxsxjE1kh9I0xowX67ARRvxdlu3rsEQmr49lx95dr6h+sNNVJn0J6X
-dgWTP5XHAeZpVTh/EGGZyeNfpso+gmNIquIISD6q8rKFYqa0p9m9N5xotS1WfbC3
-P6CxB9bpT9zeRXEwMn8bLgn5v1Kh7sKAPgZcLlVAwRv1cEWw3F369nJad9Jjzc9Y
-iQBCYz95OdBEsIJuQRno3eDBiFrRHnGTHyQwdOUeqN48Jzd/g66ed8/wMLH/S5no
-xqE=
------END CERTIFICATE-----
-
-# Issuer: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
-# Subject: CN=Entrust Root Certification Authority O=Entrust, Inc. OU=www.entrust.net/CPS is incorporated by reference/(c) 2006 Entrust, Inc.
-# Label: "Entrust Root Certification Authority"
-# Serial: 1164660820
-# MD5 Fingerprint: d6:a5:c3:ed:5d:dd:3e:00:c1:3d:87:92:1f:1d:3f:e4
-# SHA1 Fingerprint: b3:1e:b1:b7:40:e3:6c:84:02:da:dc:37:d4:4d:f5:d4:67:49:52:f9
-# SHA256 Fingerprint: 73:c1:76:43:4f:1b:c6:d5:ad:f4:5b:0e:76:e7:27:28:7c:8d:e5:76:16:c1:e6:e6:14:1a:2b:2c:bc:7d:8e:4c
------BEGIN CERTIFICATE-----
-MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMC
-VVMxFjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0
-Lm5ldC9DUFMgaXMgaW5jb3Jwb3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMW
-KGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsGA1UEAxMkRW50cnVzdCBSb290IENl
-cnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0MloXDTI2MTEyNzIw
-NTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMuMTkw
-NwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSBy
-ZWZlcmVuY2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNV
-BAMTJEVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJ
-KoZIhvcNAQEBBQADggEPADCCAQoCggEBALaVtkNC+sZtKm9I35RMOVcF7sN5EUFo
-Nu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYszA9u3g3s+IIRe7bJWKKf4
-4LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOwwCj0Yzfv9
-KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGI
-rb68j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi
-94DkZfs0Nw4pgHBNrziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOB
-sDCBrTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAi
-gA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1MzQyWjAfBgNVHSMEGDAWgBRo
-kORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DHhmak8fdLQ/uE
-vW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA
-A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9t
-O1KzKtvn1ISMY/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6Zua
-AGAT/3B+XxFNSRuzFVJ7yVTav52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP
-9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTSW3iDVuycNsMm4hH2Z0kdkquM++v/
-eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0tHuu2guQOHXvgR1m
-0vdXcDazv/wor3ElhVsT/h5/WrQ8
------END CERTIFICATE-----
-
-# Issuer: O=RSA Security Inc OU=RSA Security 2048 V3
-# Subject: O=RSA Security Inc OU=RSA Security 2048 V3
-# Label: "RSA Security 2048 v3"
-# Serial: 13297492616345471454730593562152402946
-# MD5 Fingerprint: 77:0d:19:b1:21:fd:00:42:9c:3e:0c:a5:dd:0b:02:8e
-# SHA1 Fingerprint: 25:01:90:19:cf:fb:d9:99:1c:b7:68:25:74:8d:94:5f:30:93:95:42
-# SHA256 Fingerprint: af:8b:67:62:a1:e5:28:22:81:61:a9:5d:5c:55:9e:e2:66:27:8f:75:d7:9e:83:01:89:a5:03:50:6a:bd:6b:4c
------BEGIN CERTIFICATE-----
-MIIDYTCCAkmgAwIBAgIQCgEBAQAAAnwAAAAKAAAAAjANBgkqhkiG9w0BAQUFADA6
-MRkwFwYDVQQKExBSU0EgU2VjdXJpdHkgSW5jMR0wGwYDVQQLExRSU0EgU2VjdXJp
-dHkgMjA0OCBWMzAeFw0wMTAyMjIyMDM5MjNaFw0yNjAyMjIyMDM5MjNaMDoxGTAX
-BgNVBAoTEFJTQSBTZWN1cml0eSBJbmMxHTAbBgNVBAsTFFJTQSBTZWN1cml0eSAy
-MDQ4IFYzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAt49VcdKA3Xtp
-eafwGFAyPGJn9gqVB93mG/Oe2dJBVGutn3y+Gc37RqtBaB4Y6lXIL5F4iSj7Jylg
-/9+PjDvJSZu1pJTOAeo+tWN7fyb9Gd3AIb2E0S1PRsNO3Ng3OTsor8udGuorryGl
-wSMiuLgbWhOHV4PR8CDn6E8jQrAApX2J6elhc5SYcSa8LWrg903w8bYqODGBDSnh
-AMFRD0xS+ARaqn1y07iHKrtjEAMqs6FPDVpeRrc9DvV07Jmf+T0kgYim3WBU6JU2
-PcYJk5qjEoAAVZkZR73QpXzDuvsf9/UP+Ky5tfQ3mBMY3oVbtwyCO4dvlTlYMNpu
-AWgXIszACwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIB
-BjAfBgNVHSMEGDAWgBQHw1EwpKrpRa41JPr/JCwz0LGdjDAdBgNVHQ4EFgQUB8NR
-MKSq6UWuNST6/yQsM9CxnYwwDQYJKoZIhvcNAQEFBQADggEBAF8+hnZuuDU8TjYc
-HnmYv/3VEhF5Ug7uMYm83X/50cYVIeiKAVQNOvtUudZj1LGqlk2iQk3UUx+LEN5/
-Zb5gEydxiKRz44Rj0aRV4VCT5hsOedBnvEbIvz8XDZXmxpBp3ue0L96VfdASPz0+
-f00/FGj1EVDVwfSQpQgdMWD/YIwjVAqv/qFuxdF6Kmh4zx6CCiC0H63lhbJqaHVO
-rSU3lIW+vaHU6rcMSzyd6BIA8F+sDeGscGNz9395nzIlQnQFgCi/vcEkllgVsRch
-6YlL2weIZ/QVrXA+L02FO8K32/6YaCOJ4XQP3vTFhGMpG8zLB8kApKnXwiJPZ9d3
-7CAFYd4=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Global CA O=GeoTrust Inc.
-# Subject: CN=GeoTrust Global CA O=GeoTrust Inc.
-# Label: "GeoTrust Global CA"
-# Serial: 144470
-# MD5 Fingerprint: f7:75:ab:29:fb:51:4e:b7:77:5e:ff:05:3c:99:8e:f5
-# SHA1 Fingerprint: de:28:f4:a4:ff:e5:b9:2f:a3:c5:03:d1:a3:49:a7:f9:96:2a:82:12
-# SHA256 Fingerprint: ff:85:6a:2d:25:1d:cd:88:d3:66:56:f4:50:12:67:98:cf:ab:aa:de:40:79:9c:72:2d:e4:d2:b5:db:36:a7:3a
------BEGIN CERTIFICATE-----
-MIIDVDCCAjygAwIBAgIDAjRWMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
-MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
-YWwgQ0EwHhcNMDIwNTIxMDQwMDAwWhcNMjIwNTIxMDQwMDAwWjBCMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEbMBkGA1UEAxMSR2VvVHJ1c3Qg
-R2xvYmFsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2swYYzD9
-9BcjGlZ+W988bDjkcbd4kdS8odhM+KhDtgPpTSEHCIjaWC9mOSm9BXiLnTjoBbdq
-fnGk5sRgprDvgOSJKA+eJdbtg/OtppHHmMlCGDUUna2YRpIuT8rxh0PBFpVXLVDv
-iS2Aelet8u5fa9IAjbkU+BQVNdnARqN7csiRv8lVK83Qlz6cJmTM386DGXHKTubU
-1XupGc1V3sjs0l44U+VcT4wt/lAjNvxm5suOpDkZALeVAjmRCw7+OC7RHQWa9k0+
-bw8HHa8sHo9gOeL6NlMTOdReJivbPagUvTLrGAMoUgRx5aszPeE4uwc2hGKceeoW
-MPRfwCvocWvk+QIDAQABo1MwUTAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTA
-ephojYn7qwVkDBF9qn1luMrMTjAfBgNVHSMEGDAWgBTAephojYn7qwVkDBF9qn1l
-uMrMTjANBgkqhkiG9w0BAQUFAAOCAQEANeMpauUvXVSOKVCUn5kaFOSPeCpilKIn
-Z57QzxpeR+nBsqTP3UEaBU6bS+5Kb1VSsyShNwrrZHYqLizz/Tt1kL/6cdjHPTfS
-tQWVYrmm3ok9Nns4d0iXrKYgjy6myQzCsplFAMfOEVEiIuCl6rYVSAlk6l5PdPcF
-PseKUgzbFbS9bZvlxrFUaKnjaZC2mqUPuLk/IH2uSrW4nOQdtqvmlKXBx4Ot2/Un
-hw4EbNX/3aBd7YdStysVAq45pmp06drE57xNNB6pXE0zX5IJL4hmXXeXxx12E6nV
-5fEWCRE11azbJHFwLJhWC9kXtNHjUStedejV0NxPNO3CBWaAocvmMw==
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
-# Subject: CN=GeoTrust Global CA 2 O=GeoTrust Inc.
-# Label: "GeoTrust Global CA 2"
-# Serial: 1
-# MD5 Fingerprint: 0e:40:a7:6c:de:03:5d:8f:d1:0f:e4:d1:8d:f9:6c:a9
-# SHA1 Fingerprint: a9:e9:78:08:14:37:58:88:f2:05:19:b0:6d:2b:0d:2b:60:16:90:7d
-# SHA256 Fingerprint: ca:2d:82:a0:86:77:07:2f:8a:b6:76:4f:f0:35:67:6c:fe:3e:5e:32:5e:01:21:72:df:3f:92:09:6d:b7:9b:85
------BEGIN CERTIFICATE-----
-MIIDZjCCAk6gAwIBAgIBATANBgkqhkiG9w0BAQUFADBEMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3QgR2xvYmFs
-IENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMTkwMzA0MDUwMDAwWjBEMQswCQYDVQQG
-EwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEdMBsGA1UEAxMUR2VvVHJ1c3Qg
-R2xvYmFsIENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDvPE1A
-PRDfO1MA4Wf+lGAVPoWI8YkNkMgoI5kF6CsgncbzYEbYwbLVjDHZ3CB5JIG/NTL8
-Y2nbsSpr7iFY8gjpeMtvy/wWUsiRxP89c96xPqfCfWbB9X5SJBri1WeR0IIQ13hL
-TytCOb1kLUCgsBDTOEhGiKEMuzozKmKY+wCdE1l/bztyqu6mD4b5BWHqZ38MN5aL
-5mkWRxHCJ1kDs6ZgwiFAVvqgx306E+PsV8ez1q6diYD3Aecs9pYrEw15LNnA5IZ7
-S4wMcoKK+xfNAGw6EzywhIdLFnopsk/bHdQL82Y3vdj2V7teJHq4PIu5+pIaGoSe
-2HSPqht/XvT+RSIhAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE
-FHE4NvICMVNHK266ZUapEBVYIAUJMB8GA1UdIwQYMBaAFHE4NvICMVNHK266ZUap
-EBVYIAUJMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQUFAAOCAQEAA/e1K6td
-EPx7srJerJsOflN4WT5CBP51o62sgU7XAotexC3IUnbHLB/8gTKY0UvGkpMzNTEv
-/NgdRN3ggX+d6YvhZJFiCzkIjKx0nVnZellSlxG5FntvRdOW2TF9AjYPnDtuzywN
-A0ZF66D0f0hExghAzN4bcLUprbqLOzRldRtxIR0sFAqwlpW41uryZfspuk/qkZN0
-abby/+Ea0AzRdoXLiiW9l14sbxWZJue2Kf8i7MkCx1YAzUm5s2x7UwQa4qjJqhIF
-I8LO57sEAszAR6LkxCkvW0VXiVHuPOtSCP8HNR6fNWpHSlaY0VqFH4z1Ir+rzoPz
-4iIprn2DQKi6bA==
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Universal CA O=GeoTrust Inc.
-# Subject: CN=GeoTrust Universal CA O=GeoTrust Inc.
-# Label: "GeoTrust Universal CA"
-# Serial: 1
-# MD5 Fingerprint: 92:65:58:8b:a2:1a:31:72:73:68:5c:b4:a5:7a:07:48
-# SHA1 Fingerprint: e6:21:f3:35:43:79:05:9a:4b:68:30:9d:8a:2f:74:22:15:87:ec:79
-# SHA256 Fingerprint: a0:45:9b:9f:63:b2:25:59:f5:fa:5d:4c:6d:b3:f9:f7:2f:f1:93:42:03:35:78:f0:73:bf:1d:1b:46:cb:b9:12
------BEGIN CERTIFICATE-----
-MIIFaDCCA1CgAwIBAgIBATANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEeMBwGA1UEAxMVR2VvVHJ1c3QgVW5pdmVy
-c2FsIENBMB4XDTA0MDMwNDA1MDAwMFoXDTI5MDMwNDA1MDAwMFowRTELMAkGA1UE
-BhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xHjAcBgNVBAMTFUdlb1RydXN0
-IFVuaXZlcnNhbCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKYV
-VaCjxuAfjJ0hUNfBvitbtaSeodlyWL0AG0y/YckUHUWCq8YdgNY96xCcOq9tJPi8
-cQGeBvV8Xx7BDlXKg5pZMK4ZyzBIle0iN430SppyZj6tlcDgFgDgEB8rMQ7XlFTT
-QjOgNB0eRXbdT8oYN+yFFXoZCPzVx5zw8qkuEKmS5j1YPakWaDwvdSEYfyh3peFh
-F7em6fgemdtzbvQKoiFs7tqqhZJmr/Z6a4LauiIINQ/PQvE1+mrufislzDoR5G2v
-c7J2Ha3QsnhnGqQ5HFELZ1aD/ThdDc7d8Lsrlh/eezJS/R27tQahsiFepdaVaH/w
-mZ7cRQg+59IJDTWU3YBOU5fXtQlEIGQWFwMCTFMNaN7VqnJNk22CDtucvc+081xd
-VHppCZbW2xHBjXWotM85yM48vCR85mLK4b19p71XZQvk/iXttmkQ3CgaRr0BHdCX
-teGYO8A3ZNY9lO4L4fUorgtWv3GLIylBjobFS1J72HGrH4oVpjuDWtdYAVHGTEHZ
-f9hBZ3KiKN9gg6meyHv8U3NyWfWTehd2Ds735VzZC1U0oqpbtWpU5xPKV+yXbfRe
-Bi9Fi1jUIxaS5BZuKGNZMN9QAZxjiRqf2xeUgnA3wySemkfWWspOqGmJch+RbNt+
-nhutxx9z3SxPGWX9f5NAEC7S8O08ni4oPmkmM8V7AgMBAAGjYzBhMA8GA1UdEwEB
-/wQFMAMBAf8wHQYDVR0OBBYEFNq7LqqwDLiIJlF0XG0D08DYj3rWMB8GA1UdIwQY
-MBaAFNq7LqqwDLiIJlF0XG0D08DYj3rWMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG
-9w0BAQUFAAOCAgEAMXjmx7XfuJRAyXHEqDXsRh3ChfMoWIawC/yOsjmPRFWrZIRc
-aanQmjg8+uUfNeVE44B5lGiku8SfPeE0zTBGi1QrlaXv9z+ZhP015s8xxtxqv6fX
-IwjhmF7DWgh2qaavdy+3YL1ERmrvl/9zlcGO6JP7/TG37FcREUWbMPEaiDnBTzyn
-ANXH/KttgCJwpQzgXQQpAvvLoJHRfNbDflDVnVi+QTjruXU8FdmbyUqDWcDaU/0z
-uzYYm4UPFd3uLax2k7nZAY1IEKj79TiG8dsKxr2EoyNB3tZ3b4XUhRxQ4K5RirqN
-Pnbiucon8l+f725ZDQbYKxek0nxru18UGkiPGkzns0ccjkxFKyDuSN/n3QmOGKja
-QI2SJhFTYXNd673nxE0pN2HrrDktZy4W1vUAg4WhzH92xH3kt0tm7wNFYGm2DFKW
-koRepqO1pD4r2czYG0eq8kTaT/kD6PAUyz/zg97QwVTjt+gKN02LIFkDMBmhLMi9
-ER/frslKxfMnZmaGrGiR/9nmUxwPi1xpZQomyB40w11Re9epnAahNt3ViZS82eQt
-DF4JbAiXfKM9fJP/P6EUp8+1Xevb2xzEdt+Iub1FBZUbrvxGakyvSOPOrg/Sfuvm
-bJxPgWp6ZKy7PtXny3YuxadIwVyQD8vIP/rmMuGNG2+k5o7Y+SlIis5z/iw=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
-# Subject: CN=GeoTrust Universal CA 2 O=GeoTrust Inc.
-# Label: "GeoTrust Universal CA 2"
-# Serial: 1
-# MD5 Fingerprint: 34:fc:b8:d0:36:db:9e:14:b3:c2:f2:db:8f:e4:94:c7
-# SHA1 Fingerprint: 37:9a:19:7b:41:85:45:35:0c:a6:03:69:f3:3c:2e:af:47:4f:20:79
-# SHA256 Fingerprint: a0:23:4f:3b:c8:52:7c:a5:62:8e:ec:81:ad:5d:69:89:5d:a5:68:0d:c9:1d:1c:b8:47:7f:33:f8:78:b9:5b:0b
------BEGIN CERTIFICATE-----
-MIIFbDCCA1SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBHMQswCQYDVQQGEwJVUzEW
-MBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1c3QgVW5pdmVy
-c2FsIENBIDIwHhcNMDQwMzA0MDUwMDAwWhcNMjkwMzA0MDUwMDAwWjBHMQswCQYD
-VQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjEgMB4GA1UEAxMXR2VvVHJ1
-c3QgVW5pdmVyc2FsIENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
-AQCzVFLByT7y2dyxUxpZKeexw0Uo5dfR7cXFS6GqdHtXr0om/Nj1XqduGdt0DE81
-WzILAePb63p3NeqqWuDW6KFXlPCQo3RWlEQwAx5cTiuFJnSCegx2oG9NzkEtoBUG
-FF+3Qs17j1hhNNwqCPkuwwGmIkQcTAeC5lvO0Ep8BNMZcyfwqph/Lq9O64ceJHdq
-XbboW0W63MOhBW9Wjo8QJqVJwy7XQYci4E+GymC16qFjwAGXEHm9ADwSbSsVsaxL
-se4YuU6W3Nx2/zu+z18DwPw76L5GG//aQMJS9/7jOvdqdzXQ2o3rXhhqMcceujwb
-KNZrVMaqW9eiLBsZzKIC9ptZvTdrhrVtgrrY6slWvKk2WP0+GfPtDCapkzj4T8Fd
-IgbQl+rhrcZV4IErKIM6+vR7IVEAvlI4zs1meaj0gVbi0IMJR1FbUGrP20gaXT73
-y/Zl92zxlfgCOzJWgjl6W70viRu/obTo/3+NjN8D8WBOWBFM66M/ECuDmgFz2ZRt
-hAAnZqzwcEAJQpKtT5MNYQlRJNiS1QuUYbKHsu3/mjX/hVTK7URDrBs8FmtISgoc
-QIgfksILAAX/8sgCSqSqqcyZlpwvWOB94b67B9xfBHJcMTTD7F8t4D1kkCLm0ey4
-Lt1ZrtmhN79UNdxzMk+MBB4zsslG8dhcyFVQyWi9qLo2CQIDAQABo2MwYTAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAfBgNV
-HSMEGDAWgBR281Xh+qQ2+/CfXGJx7Tz0RzgQKzAOBgNVHQ8BAf8EBAMCAYYwDQYJ
-KoZIhvcNAQEFBQADggIBAGbBxiPz2eAubl/oz66wsCVNK/g7WJtAJDday6sWSf+z
-dXkzoS9tcBc0kf5nfo/sm+VegqlVHy/c1FEHEv6sFj4sNcZj/NwQ6w2jqtB8zNHQ
-L1EuxBRa3ugZ4T7GzKQp5y6EqgYweHZUcyiYWTjgAA1i00J9IZ+uPTqM1fp3DRgr
-Fg5fNuH8KrUwJM/gYwx7WBr+mbpCErGR9Hxo4sjoryzqyX6uuyo9DRXcNJW2GHSo
-ag/HtPQTxORb7QrSpJdMKu0vbBKJPfEncKpqA1Ihn0CoZ1Dy81of398j9tx4TuaY
-T1U6U+Pv8vSfx3zYWK8pIpe44L2RLrB27FcRz+8pRPPphXpgY+RdM4kX2TGq2tbz
-GDVyz4crL2MjhF2EjD9XoIj8mZEoJmmZ1I+XRL6O1UixpCgp8RW04eWe3fiPpm8m
-1wk8OhwRDqZsN/etRIcsKMfYdIKz0G9KV7s1KSegi+ghp4dkNl3M2Basx7InQJJV
-OCiNUW7dFGdTbHFcJoRNdVq2fmBWqU2t+5sel/MN2dKXVHfaPRK34B7vCAas+YWH
-6aLcr34YEoP9VhdBLtUpgn2Z9DH2canPLAEnpQW5qrJITirvn5NSUZU8UnOOVkwX
-QMAJKOSLakhT2+zNVVXxxvjpoixMptEmX36vWkzaH6byHCx+rgIW0lbQL1dTR+iS
------END CERTIFICATE-----
-
-# Issuer: CN=America Online Root Certification Authority 1 O=America Online Inc.
-# Subject: CN=America Online Root Certification Authority 1 O=America Online Inc.
-# Label: "America Online Root Certification Authority 1"
-# Serial: 1
-# MD5 Fingerprint: 14:f1:08:ad:9d:fa:64:e2:89:e7:1c:cf:a8:ad:7d:5e
-# SHA1 Fingerprint: 39:21:c1:15:c1:5d:0e:ca:5c:cb:5b:c4:f0:7d:21:d8:05:0b:56:6a
-# SHA256 Fingerprint: 77:40:73:12:c6:3a:15:3d:5b:c0:0b:4e:51:75:9c:df:da:c2:37:dc:2a:33:b6:79:46:e9:8e:9b:fa:68:0a:e3
------BEGIN CERTIFICATE-----
-MIIDpDCCAoygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
-bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAxMB4XDTAyMDUyODA2
-MDAwMFoXDTM3MTExOTIwNDMwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
-ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAKgv6KRpBgNHw+kqmP8ZonCaxlCyfqXfaE0bfA+2l2h9LaaLl+lk
-hsmj76CGv2BlnEtUiMJIxUo5vxTjWVXlGbR0yLQFOVwWpeKVBeASrlmLojNoWBym
-1BW32J/X3HGrfpq/m44zDyL9Hy7nBzbvYjnF3cu6JRQj3gzGPTzOggjmZj7aUTsW
-OqMFf6Dch9Wc/HKpoH145LcxVR5lu9RhsCFg7RAycsWSJR74kEoYeEfffjA3PlAb
-2xzTa5qGUwew76wGePiEmf4hjUyAtgyC9mZweRrTT6PP8c9GsEsPPt2IYriMqQko
-O3rHl+Ee5fSfwMCuJKDIodkP1nsmgmkyPacCAwEAAaNjMGEwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUAK3Zo/Z59m50qX8zPYEX10zPM94wHwYDVR0jBBgwFoAU
-AK3Zo/Z59m50qX8zPYEX10zPM94wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB
-BQUAA4IBAQB8itEfGDeC4Liwo+1WlchiYZwFos3CYiZhzRAW18y0ZTTQEYqtqKkF
-Zu90821fnZmv9ov761KyBZiibyrFVL0lvV+uyIbqRizBs73B6UlwGBaXCBOMIOAb
-LjpHyx7kADCVW/RFo8AasAFOq73AI25jP4BKxQft3OJvx8Fi8eNy1gTIdGcL+oir
-oQHIb/AUr9KZzVGTfu0uOMe9zkZQPXLjeSWdm4grECDdpbgyn43gKd8hdIaC2y+C
-MMbHNYaz+ZZfRtsMRf3zUMNvxsNIrUam4SdHCh0Om7bCd39j8uB9Gr784N/Xx6ds
-sPmuujz9dLQR6FgNgLzTqIA6me11zEZ7
------END CERTIFICATE-----
-
-# Issuer: CN=America Online Root Certification Authority 2 O=America Online Inc.
-# Subject: CN=America Online Root Certification Authority 2 O=America Online Inc.
-# Label: "America Online Root Certification Authority 2"
-# Serial: 1
-# MD5 Fingerprint: d6:ed:3c:ca:e2:66:0f:af:10:43:0d:77:9b:04:09:bf
-# SHA1 Fingerprint: 85:b5:ff:67:9b:0c:79:96:1f:c8:6e:44:22:00:46:13:db:17:92:84
-# SHA256 Fingerprint: 7d:3b:46:5a:60:14:e5:26:c0:af:fc:ee:21:27:d2:31:17:27:ad:81:1c:26:84:2d:00:6a:f3:73:06:cc:80:bd
------BEGIN CERTIFICATE-----
-MIIFpDCCA4ygAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEc
-MBoGA1UEChMTQW1lcmljYSBPbmxpbmUgSW5jLjE2MDQGA1UEAxMtQW1lcmljYSBP
-bmxpbmUgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAyMB4XDTAyMDUyODA2
-MDAwMFoXDTM3MDkyOTE0MDgwMFowYzELMAkGA1UEBhMCVVMxHDAaBgNVBAoTE0Ft
-ZXJpY2EgT25saW5lIEluYy4xNjA0BgNVBAMTLUFtZXJpY2EgT25saW5lIFJvb3Qg
-Q2VydGlmaWNhdGlvbiBBdXRob3JpdHkgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAMxBRR3pPU0Q9oyxQcngXssNt79Hc9PwVU3dxgz6sWYFas14tNwC
-206B89enfHG8dWOgXeMHDEjsJcQDIPT/DjsS/5uN4cbVG7RtIuOx238hZK+GvFci
-KtZHgVdEglZTvYYUAQv8f3SkWq7xuhG1m1hagLQ3eAkzfDJHA1zEpYNI9FdWboE2
-JxhP7JsowtS013wMPgwr38oE18aO6lhOqKSlGBxsRZijQdEt0sdtjRnxrXm3gT+9
-BoInLRBYBbV4Bbkv2wxrkJB+FFk4u5QkE+XRnRTf04JNRvCAOVIyD+OEsnpD8l7e
-Xz8d3eOyG6ChKiMDbi4BFYdcpnV1x5dhvt6G3NRI270qv0pV2uh9UPu0gBe4lL8B
-PeraunzgWGcXuVjgiIZGZ2ydEEdYMtA1fHkqkKJaEBEjNa0vzORKW6fIJ/KD3l67
-Xnfn6KVuY8INXWHQjNJsWiEOyiijzirplcdIz5ZvHZIlyMbGwcEMBawmxNJ10uEq
-Z8A9W6Wa6897GqidFEXlD6CaZd4vKL3Ob5Rmg0gp2OpljK+T2WSfVVcmv2/LNzGZ
-o2C7HK2JNDJiuEMhBnIMoVxtRsX6Kc8w3onccVvdtjc+31D1uAclJuW8tf48ArO3
-+L5DwYcRlJ4jbBeKuIonDFRH8KmzwICMoCfrHRnjB453cMor9H124HhnAgMBAAGj
-YzBhMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFE1FwWg4u3OpaaEg5+31IqEj
-FNeeMB8GA1UdIwQYMBaAFE1FwWg4u3OpaaEg5+31IqEjFNeeMA4GA1UdDwEB/wQE
-AwIBhjANBgkqhkiG9w0BAQUFAAOCAgEAZ2sGuV9FOypLM7PmG2tZTiLMubekJcmn
-xPBUlgtk87FYT15R/LKXeydlwuXK5w0MJXti4/qftIe3RUavg6WXSIylvfEWK5t2
-LHo1YGwRgJfMqZJS5ivmae2p+DYtLHe/YUjRYwu5W1LtGLBDQiKmsXeu3mnFzccc
-obGlHBD7GL4acN3Bkku+KVqdPzW+5X1R+FXgJXUjhx5c3LqdsKyzadsXg8n33gy8
-CNyRnqjQ1xU3c6U1uPx+xURABsPr+CKAXEfOAuMRn0T//ZoyzH1kUQ7rVyZ2OuMe
-IjzCpjbdGe+n/BLzJsBZMYVMnNjP36TMzCmT/5RtdlwTCJfy7aULTd3oyWgOZtMA
-DjMSW7yV5TKQqLPGbIOtd+6Lfn6xqavT4fG2wLHqiMDn05DpKJKUe2h7lyoKZy2F
-AjgQ5ANh1NolNscIWC2hp1GvMApJ9aZphwctREZ2jirlmjvXGKL8nDgQzMY70rUX
-Om/9riW99XJZZLF0KjhfGEzfz3EEWjbUvy+ZnOjZurGV5gJLIaFb1cFPj65pbVPb
-AZO1XB4Y3WRayhgoPmMEEf0cjQAPuDffZ4qdZqkCapH/E8ovXYO8h5Ns3CRRFgQl
-Zvqz2cK6Kb6aSDiCmfS/O0oxGfm/jiEzFMpPVF/7zvuPcX/9XhmgD0uRuMRUvAaw
-RY8mkaKO/qk=
------END CERTIFICATE-----
-
-# Issuer: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
-# Subject: CN=Visa eCommerce Root O=VISA OU=Visa International Service Association
-# Label: "Visa eCommerce Root"
-# Serial: 25952180776285836048024890241505565794
-# MD5 Fingerprint: fc:11:b8:d8:08:93:30:00:6d:23:f9:7e:eb:52:1e:02
-# SHA1 Fingerprint: 70:17:9b:86:8c:00:a4:fa:60:91:52:22:3f:9f:3e:32:bd:e0:05:62
-# SHA256 Fingerprint: 69:fa:c9:bd:55:fb:0a:c7:8d:53:bb:ee:5c:f1:d5:97:98:9f:d0:aa:ab:20:a2:51:51:bd:f1:73:3e:e7:d1:22
------BEGIN CERTIFICATE-----
-MIIDojCCAoqgAwIBAgIQE4Y1TR0/BvLB+WUF1ZAcYjANBgkqhkiG9w0BAQUFADBr
-MQswCQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRl
-cm5hdGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNv
-bW1lcmNlIFJvb3QwHhcNMDIwNjI2MDIxODM2WhcNMjIwNjI0MDAxNjEyWjBrMQsw
-CQYDVQQGEwJVUzENMAsGA1UEChMEVklTQTEvMC0GA1UECxMmVmlzYSBJbnRlcm5h
-dGlvbmFsIFNlcnZpY2UgQXNzb2NpYXRpb24xHDAaBgNVBAMTE1Zpc2EgZUNvbW1l
-cmNlIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvV95WHm6h
-2mCxlCfLF9sHP4CFT8icttD0b0/Pmdjh28JIXDqsOTPHH2qLJj0rNfVIsZHBAk4E
-lpF7sDPwsRROEW+1QK8bRaVK7362rPKgH1g/EkZgPI2h4H3PVz4zHvtH8aoVlwdV
-ZqW1LS7YgFmypw23RuwhY/81q6UCzyr0TP579ZRdhE2o8mCP2w4lPJ9zcc+U30rq
-299yOIzzlr3xF7zSujtFWsan9sYXiwGd/BmoKoMWuDpI/k4+oKsGGelT84ATB+0t
-vz8KPFUgOSwsAGl0lUq8ILKpeeUYiZGo3BxN77t+Nwtd/jmliFKMAGzsGHxBvfaL
-dXe6YJ2E5/4tAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD
-AgEGMB0GA1UdDgQWBBQVOIMPPyw/cDMezUb+B4wg4NfDtzANBgkqhkiG9w0BAQUF
-AAOCAQEAX/FBfXxcCLkr4NWSR/pnXKUTwwMhmytMiUbPWU3J/qVAtmPN3XEolWcR
-zCSs00Rsca4BIGsDoo8Ytyk6feUWYFN4PMCvFYP3j1IzJL1kk5fui/fbGKhtcbP3
-LBfQdCVp9/5rPJS+TUtBjE7ic9DjkCJzQ83z7+pzzkWKsKZJ/0x9nXGIxHYdkFsd
-7v3M9+79YKWxehZx0RbQfBI8bGmX265fOZpwLwU8GUYEmSA20GBuYQa7FkKMcPcw
-++DbZqMAAb3mLNqRX6BGi01qnD093QVG/na/oAo85ADmJ7f/hC3euiInlhBx6yLt
-398znM/jra6O1I7mT1GvFpLgXPYHDw==
------END CERTIFICATE-----
-
-# Issuer: CN=Certum CA O=Unizeto Sp. z o.o.
-# Subject: CN=Certum CA O=Unizeto Sp. z o.o.
-# Label: "Certum Root CA"
-# Serial: 65568
-# MD5 Fingerprint: 2c:8f:9f:66:1d:18:90:b1:47:26:9d:8e:86:82:8c:a9
-# SHA1 Fingerprint: 62:52:dc:40:f7:11:43:a2:2f:de:9e:f7:34:8e:06:42:51:b1:81:18
-# SHA256 Fingerprint: d8:e0:fe:bc:1d:b2:e3:8d:00:94:0f:37:d2:7d:41:34:4d:99:3e:73:4b:99:d5:65:6d:97:78:d4:d8:14:36:24
------BEGIN CERTIFICATE-----
-MIIDDDCCAfSgAwIBAgIDAQAgMA0GCSqGSIb3DQEBBQUAMD4xCzAJBgNVBAYTAlBM
-MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
-QTAeFw0wMjA2MTExMDQ2MzlaFw0yNzA2MTExMDQ2MzlaMD4xCzAJBgNVBAYTAlBM
-MRswGQYDVQQKExJVbml6ZXRvIFNwLiB6IG8uby4xEjAQBgNVBAMTCUNlcnR1bSBD
-QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAM6xwS7TT3zNJc4YPk/E
-jG+AanPIW1H4m9LcuwBcsaD8dQPugfCI7iNS6eYVM42sLQnFdvkrOYCJ5JdLkKWo
-ePhzQ3ukYbDYWMzhbGZ+nPMJXlVjhNWo7/OxLjBos8Q82KxujZlakE403Daaj4GI
-ULdtlkIJ89eVgw1BS7Bqa/j8D35in2fE7SZfECYPCE/wpFcozo+47UX2bu4lXapu
-Ob7kky/ZR6By6/qmW6/KUz/iDsaWVhFu9+lmqSbYf5VT7QqFiLpPKaVCjF62/IUg
-AKpoC6EahQGcxEZjgoi2IrHu/qpGWX7PNSzVttpd90gzFFS269lvzs2I1qsb2pY7
-HVkCAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEA
-uI3O7+cUus/usESSbLQ5PqKEbq24IXfS1HeCh+YgQYHu4vgRt2PRFze+GXYkHAQa
-TOs9qmdvLdTN/mUxcMUbpgIKumB7bVjCmkn+YzILa+M6wKyrO7Do0wlRjBCDxjTg
-xSvgGrZgFCdsMneMvLJymM/NzD+5yCRCFNZX/OYmQ6kd5YCQzgNUKD73P9P4Te1q
-CjqTE5s7FCMTY5w/0YcneeVMUeMBrYVdGjux1XMQpNPyvG5k9VpWkKjHDkx0Dy5x
-O/fIR/RpbxXyEV6DHpx8Uq79AtoSqFlnGNu8cN2bsWntgM6JQEhqDjXKKWYVIZQs
-6GAqm4VKQPNriiTsBhYscw==
------END CERTIFICATE-----
-
-# Issuer: CN=AAA Certificate Services O=Comodo CA Limited
-# Subject: CN=AAA Certificate Services O=Comodo CA Limited
-# Label: "Comodo AAA Services root"
-# Serial: 1
-# MD5 Fingerprint: 49:79:04:b0:eb:87:19:ac:47:b0:bc:11:51:9b:74:d0
-# SHA1 Fingerprint: d1:eb:23:a4:6d:17:d6:8f:d9:25:64:c2:f1:f1:60:17:64:d8:e3:49
-# SHA256 Fingerprint: d7:a7:a0:fb:5d:7e:27:31:d7:71:e9:48:4e:bc:de:f7:1d:5f:0c:3e:0a:29:48:78:2b:c8:3e:e0:ea:69:9e:f4
------BEGIN CERTIFICATE-----
-MIIEMjCCAxqgAwIBAgIBATANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEhMB8GA1UEAwwYQUFBIENlcnRpZmlj
-YXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVowezEL
-MAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
-BwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMM
-GEFBQSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAL5AnfRu4ep2hxxNRUSOvkbIgwadwSr+GB+O5AL686tdUIoWMQua
-BtDFcCLNSS1UY8y2bmhGC1Pqy0wkwLxyTurxFa70VJoSCsN6sjNg4tqJVfMiWPPe
-3M/vg4aijJRPn2jymJBGhCfHdr/jzDUsi14HZGWCwEiwqJH5YZ92IFCokcdmtet4
-YgNW8IoaE+oxox6gmf049vYnMlhvB/VruPsUK6+3qszWY19zjNoFmag4qMsXeDZR
-rOme9Hg6jc8P2ULimAyrL58OAd7vn5lJ8S3frHRNG5i1R8XlKdH5kBjHYpy+g8cm
-ez6KJcfA3Z3mNWgQIJ2P2N7Sw4ScDV7oL8kCAwEAAaOBwDCBvTAdBgNVHQ4EFgQU
-oBEKIz6W8Qfs4q8p74Klf9AwpLQwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQF
-MAMBAf8wewYDVR0fBHQwcjA4oDagNIYyaHR0cDovL2NybC5jb21vZG9jYS5jb20v
-QUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNqA0oDKGMGh0dHA6Ly9jcmwuY29t
-b2RvLm5ldC9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2VzLmNybDANBgkqhkiG9w0BAQUF
-AAOCAQEACFb8AvCb6P+k+tZ7xkSAzk/ExfYAWMymtrwUSWgEdujm7l3sAg9g1o1Q
-GE8mTgHj5rCl7r+8dFRBv/38ErjHT1r0iWAFf2C3BUrz9vHCv8S5dIa2LX1rzNLz
-Rt0vxuBqw8M0Ayx9lt1awg6nCpnBBYurDC/zXDrPbDdVCYfeU0BsWO/8tqtlbgT2
-G9w84FoVxp7Z8VlIMCFlA2zs6SFz7JsDoeA3raAVGI/6ugLOpyypEBMs1OUIJqsi
-l2D4kF501KKaU73yqWjgom7C12yxow+ev+to51byrvLjKzg6CYG1a4XXvi3tPxq3
-smPi9WIsgtRqAEFQ8TmDn5XpNpaYbg==
------END CERTIFICATE-----
-
-# Issuer: CN=Secure Certificate Services O=Comodo CA Limited
-# Subject: CN=Secure Certificate Services O=Comodo CA Limited
-# Label: "Comodo Secure Services root"
-# Serial: 1
-# MD5 Fingerprint: d3:d9:bd:ae:9f:ac:67:24:b3:c8:1b:52:e1:b9:a9:bd
-# SHA1 Fingerprint: 4a:65:d5:f4:1d:ef:39:b8:b8:90:4a:4a:d3:64:81:33:cf:c7:a1:d1
-# SHA256 Fingerprint: bd:81:ce:3b:4f:65:91:d1:1a:67:b5:fc:7a:47:fd:ef:25:52:1b:f9:aa:4e:18:b9:e3:df:2e:34:a7:80:3b:e8
------BEGIN CERTIFICATE-----
-MIIEPzCCAyegAwIBAgIBATANBgkqhkiG9w0BAQUFADB+MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDEkMCIGA1UEAwwbU2VjdXJlIENlcnRp
-ZmljYXRlIFNlcnZpY2VzMB4XDTA0MDEwMTAwMDAwMFoXDTI4MTIzMTIzNTk1OVow
-fjELMAkGA1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBwwHU2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxJDAiBgNV
-BAMMG1NlY3VyZSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAMBxM4KK0HDrc4eCQNUd5MvJDkKQ+d40uaG6EfQlhfPM
-cm3ye5drswfxdySRXyWP9nQ95IDC+DwN879A6vfIUtFyb+/Iq0G4bi4XKpVpDM3S
-HpR7LZQdqnXXs5jLrLxkU0C8j6ysNstcrbvd4JQX7NFc0L/vpZXJkMWwrPsbQ996
-CF23uPJAGysnnlDOXmWCiIxe004MeuoIkbY2qitC++rCoznl2yY4rYsK7hljxxwk
-3wN42ubqwUcaCwtGCd0C/N7Lh1/XMGNooa7cMqG6vv5Eq2i2pRcV/b3Vp6ea5EQz
-6YiO/O1R65NxTq0B50SOqy3LqP4BSUjwwN3HaNiS/j0CAwEAAaOBxzCBxDAdBgNV
-HQ4EFgQUPNiTiMLAggnMAZkGkyDpnnAJY08wDgYDVR0PAQH/BAQDAgEGMA8GA1Ud
-EwEB/wQFMAMBAf8wgYEGA1UdHwR6MHgwO6A5oDeGNWh0dHA6Ly9jcmwuY29tb2Rv
-Y2EuY29tL1NlY3VyZUNlcnRpZmljYXRlU2VydmljZXMuY3JsMDmgN6A1hjNodHRw
-Oi8vY3JsLmNvbW9kby5uZXQvU2VjdXJlQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmww
-DQYJKoZIhvcNAQEFBQADggEBAIcBbSMdflsXfcFhMs+P5/OKlFlm4J4oqF7Tt/Q0
-5qo5spcWxYJvMqTpjOev/e/C6LlLqqP05tqNZSH7uoDrJiiFGv45jN5bBAS0VPmj
-Z55B+glSzAVIqMk/IQQezkhr/IXownuvf7fM+F86/TXGDe+X3EyrEeFryzHRbPtI
-gKvcnDe4IRRLDXE97IMzbtFuMhbsmMcWi1mmNKsFVy2T96oTy9IT4rcuO81rUBcJ
-aD61JlfutuC23bkpgHl9j6PwpCikFcSF9CfUa7/lXORlAnZUtOM3ZiTTGWHIUhDl
-izeauan5Hb/qmZJhlv8BzaFfDbxxvA6sCx1HRR3B7Hzs/Sk=
------END CERTIFICATE-----
-
-# Issuer: CN=Trusted Certificate Services O=Comodo CA Limited
-# Subject: CN=Trusted Certificate Services O=Comodo CA Limited
-# Label: "Comodo Trusted Services root"
-# Serial: 1
-# MD5 Fingerprint: 91:1b:3f:6e:cd:9e:ab:ee:07:fe:1f:71:d2:b3:61:27
-# SHA1 Fingerprint: e1:9f:e3:0e:8b:84:60:9e:80:9b:17:0d:72:a8:c5:ba:6e:14:09:bd
-# SHA256 Fingerprint: 3f:06:e5:56:81:d4:96:f5:be:16:9e:b5:38:9f:9f:2b:8f:f6:1e:17:08:df:68:81:72:48:49:cd:5d:27:cb:69
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIBATANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJHQjEb
-MBkGA1UECAwSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHDAdTYWxmb3JkMRow
-GAYDVQQKDBFDb21vZG8gQ0EgTGltaXRlZDElMCMGA1UEAwwcVHJ1c3RlZCBDZXJ0
-aWZpY2F0ZSBTZXJ2aWNlczAeFw0wNDAxMDEwMDAwMDBaFw0yODEyMzEyMzU5NTla
-MH8xCzAJBgNVBAYTAkdCMRswGQYDVQQIDBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO
-BgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoMEUNvbW9kbyBDQSBMaW1pdGVkMSUwIwYD
-VQQDDBxUcnVzdGVkIENlcnRpZmljYXRlIFNlcnZpY2VzMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA33FvNlhTWvI2VFeAxHQIIO0Yfyod5jWaHiWsnOWW
-fnJSoBVC21ndZHoa0Lh73TkVvFVIxO06AOoxEbrycXQaZ7jPM8yoMa+j49d/vzMt
-TGo87IvDktJTdyR0nAducPy9C1t2ul/y/9c3S0pgePfw+spwtOpZqqPOSC+pw7IL
-fhdyFgymBwwbOM/JYrc/oJOlh0Hyt3BAd9i+FHzjqMB6juljatEPmsbS9Is6FARW
-1O24zG71++IsWL1/T2sr92AkWCTOJu80kTrV44HQsvAEAtdbtz6SrGsSivnkBbA7
-kUlcsutT6vifR4buv5XAwAaf0lteERv0xwQ1KdJVXOTt6wIDAQABo4HJMIHGMB0G
-A1UdDgQWBBTFe1i97doladL3WRaoszLAeydb9DAOBgNVHQ8BAf8EBAMCAQYwDwYD
-VR0TAQH/BAUwAwEB/zCBgwYDVR0fBHwwejA8oDqgOIY2aHR0cDovL2NybC5jb21v
-ZG9jYS5jb20vVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMuY3JsMDqgOKA2hjRo
-dHRwOi8vY3JsLmNvbW9kby5uZXQvVHJ1c3RlZENlcnRpZmljYXRlU2VydmljZXMu
-Y3JsMA0GCSqGSIb3DQEBBQUAA4IBAQDIk4E7ibSvuIQSTI3S8NtwuleGFTQQuS9/
-HrCoiWChisJ3DFBKmwCL2Iv0QeLQg4pKHBQGsKNoBXAxMKdTmw7pSqBYaWcOrp32
-pSxBvzwGa+RZzG0Q8ZZvH9/0BAKkn0U+yNj6NkZEUD+Cl5EfKNsYEYwq5GWDVxIS
-jBc/lDb+XbDABHcTuPQV1T84zJQ6VdCsmPW6AF/ghhmBeC8owH7TzEIK9a5QoNE+
-xqFx7D+gIIxmOom0jtTYsU0lR+4viMi14QVFwL4Ucd56/Y57fU0IlqUSc/Atyjcn
-dBInTMu2l+nZrghtWjlA3QVHdWpaIbOjGM9O9y5Xt5hwXsjEeLBi
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
-# Subject: CN=QuoVadis Root Certification Authority O=QuoVadis Limited OU=Root Certification Authority
-# Label: "QuoVadis Root CA"
-# Serial: 985026699
-# MD5 Fingerprint: 27:de:36:fe:72:b7:00:03:00:9d:f4:f0:1e:6c:04:24
-# SHA1 Fingerprint: de:3f:40:bd:50:93:d3:9b:6c:60:f6:da:bc:07:62:01:00:89:76:c9
-# SHA256 Fingerprint: a4:5e:de:3b:bb:f0:9c:8a:e1:5c:72:ef:c0:72:68:d6:93:a2:1c:99:6f:d5:1e:67:ca:07:94:60:fd:6d:88:73
------BEGIN CERTIFICATE-----
-MIIF0DCCBLigAwIBAgIEOrZQizANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wMTAzMTkxODMzMzNaFw0yMTAzMTcxODMz
-MzNaMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMSUw
-IwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYDVQQDEyVR
-dW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv2G1lVO6V/z68mcLOhrfEYBklbTRvM16z/Yp
-li4kVEAkOPcahdxYTMukJ0KX0J+DisPkBgNbAKVRHnAEdOLB1Dqr1607BxgFjv2D
-rOpm2RgbaIr1VxqYuvXtdj182d6UajtLF8HVj71lODqV0D1VNk7feVcxKh7YWWVJ
-WCCYfqtffp/p1k3sg3Spx2zY7ilKhSoGFPlU5tPaZQeLYzcS19Dsw3sgQUSj7cug
-F+FxZc4dZjH3dgEZyH0DWLaVSR2mEiboxgx24ONmy+pdpibu5cxfvWenAScOospU
-xbF6lR1xHkopigPcakXBpBlebzbNw6Kwt/5cOOJSvPhEQ+aQuwIDAQABo4ICUjCC
-Ak4wPQYIKwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwczovL29jc3AucXVv
-dmFkaXNvZmZzaG9yZS5jb20wDwYDVR0TAQH/BAUwAwEB/zCCARoGA1UdIASCAREw
-ggENMIIBCQYJKwYBBAG+WAABMIH7MIHUBggrBgEFBQcCAjCBxxqBxFJlbGlhbmNl
-IG9uIHRoZSBRdW9WYWRpcyBSb290IENlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBh
-c3N1bWVzIGFjY2VwdGFuY2Ugb2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFy
-ZCB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRpb24gcHJh
-Y3RpY2VzLCBhbmQgdGhlIFF1b1ZhZGlzIENlcnRpZmljYXRlIFBvbGljeS4wIgYI
-KwYBBQUHAgEWFmh0dHA6Ly93d3cucXVvdmFkaXMuYm0wHQYDVR0OBBYEFItLbe3T
-KbkGGew5Oanwl4Rqy+/fMIGuBgNVHSMEgaYwgaOAFItLbe3TKbkGGew5Oanwl4Rq
-y+/foYGEpIGBMH8xCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
-dGVkMSUwIwYDVQQLExxSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MS4wLAYD
-VQQDEyVRdW9WYWRpcyBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggQ6tlCL
-MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOCAQEAitQUtf70mpKnGdSk
-fnIYj9lofFIk3WdvOXrEql494liwTXCYhGHoG+NpGA7O+0dQoE7/8CQfvbLO9Sf8
-7C9TqnN7Az10buYWnuulLsS/VidQK2K6vkscPFVcQR0kvoIgR13VRH56FmjffU1R
-cHhXHTMe/QKZnAzNCgVPx7uOpHX6Sm2xgI4JVrmcGmD+XcHXetwReNDWXcG31a0y
-mQM6isxUJTkxgXsTIlG6Rmyhu576BGxJJnSP0nPrzDCi5upZIof4l/UO/erMkqQW
-xFIY6iHOsfHmhIHluqmGKPJDWl0Snawe2ajlCmqnf6CHKc/yiU3U7MXi5nrQNiOK
-SnQ2+Q==
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 2 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 2 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 2"
-# Serial: 1289
-# MD5 Fingerprint: 5e:39:7b:dd:f8:ba:ec:82:e9:ac:62:ba:0c:54:00:2b
-# SHA1 Fingerprint: ca:3a:fb:cf:12:40:36:4b:44:b2:16:20:88:80:48:39:19:93:7c:f7
-# SHA256 Fingerprint: 85:a0:dd:7d:d7:20:ad:b7:ff:05:f8:3d:54:2b:20:9d:c7:ff:45:28:f7:d6:77:b1:83:89:fe:a5:e5:c4:9e:86
------BEGIN CERTIFICATE-----
-MIIFtzCCA5+gAwIBAgICBQkwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
-GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
-b3QgQ0EgMjAeFw0wNjExMjQxODI3MDBaFw0zMTExMjQxODIzMzNaMEUxCzAJBgNV
-BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
-YWRpcyBSb290IENBIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCa
-GMpLlA0ALa8DKYrwD4HIrkwZhR0In6spRIXzL4GtMh6QRr+jhiYaHv5+HBg6XJxg
-Fyo6dIMzMH1hVBHL7avg5tKifvVrbxi3Cgst/ek+7wrGsxDp3MJGF/hd/aTa/55J
-WpzmM+Yklvc/ulsrHHo1wtZn/qtmUIttKGAr79dgw8eTvI02kfN/+NsRE8Scd3bB
-rrcCaoF6qUWD4gXmuVbBlDePSHFjIuwXZQeVikvfj8ZaCuWw419eaxGrDPmF60Tp
-+ARz8un+XJiM9XOva7R+zdRcAitMOeGylZUtQofX1bOQQ7dsE/He3fbE+Ik/0XX1
-ksOR1YqI0JDs3G3eicJlcZaLDQP9nL9bFqyS2+r+eXyt66/3FsvbzSUr5R/7mp/i
-Ucw6UwxI5g69ybR2BlLmEROFcmMDBOAENisgGQLodKcftslWZvB1JdxnwQ5hYIiz
-PtGo/KPaHbDRsSNU30R2be1B2MGyIrZTHN81Hdyhdyox5C315eXbyOD/5YDXC2Og
-/zOhD7osFRXql7PSorW+8oyWHhqPHWykYTe5hnMz15eWniN9gqRMgeKh0bpnX5UH
-oycR7hYQe7xFSkyyBNKr79X9DFHOUGoIMfmR2gyPZFwDwzqLID9ujWc9Otb+fVuI
-yV77zGHcizN300QyNQliBJIWENieJ0f7OyHj+OsdWwIDAQABo4GwMIGtMA8GA1Ud
-EwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBQahGK8SEwzJQTU7tD2
-A8QZRtGUazBuBgNVHSMEZzBlgBQahGK8SEwzJQTU7tD2A8QZRtGUa6FJpEcwRTEL
-MAkGA1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMT
-ElF1b1ZhZGlzIFJvb3QgQ0EgMoICBQkwDQYJKoZIhvcNAQEFBQADggIBAD4KFk2f
-BluornFdLwUvZ+YTRYPENvbzwCYMDbVHZF34tHLJRqUDGCdViXh9duqWNIAXINzn
-g/iN/Ae42l9NLmeyhP3ZRPx3UIHmfLTJDQtyU/h2BwdBR5YM++CCJpNVjP4iH2Bl
-fF/nJrP3MpCYUNQ3cVX2kiF495V5+vgtJodmVjB3pjd4M1IQWK4/YY7yarHvGH5K
-WWPKjaJW1acvvFYfzznB4vsKqBUsfU16Y8Zsl0Q80m/DShcK+JDSV6IZUaUtl0Ha
-B0+pUNqQjZRG4T7wlP0QADj1O+hA4bRuVhogzG9Yje0uRY/W6ZM/57Es3zrWIozc
-hLsib9D45MY56QSIPMO661V6bYCZJPVsAfv4l7CUW+v90m/xd2gNNWQjrLhVoQPR
-TUIZ3Ph1WVaj+ahJefivDrkRoHy3au000LYmYjgahwz46P0u05B/B5EqHdZ+XIWD
-mbA4CD/pXvk1B+TJYm5Xf6dQlfe6yJvmjqIBxdZmv3lh8zwc4bmCXF2gw+nYSL0Z
-ohEUGW6yhhtoPkg3Goi3XZZenMfvJ2II4pEZXNLxId26F0KCl3GBUzGpn/Z9Yr9y
-4aOTHcyKJloJONDO1w2AFrR4pTqHTI2KpdVGl/IsELm8VCLAAVBpQ570su9t+Oza
-8eOx79+Rj1QqCyXBJhnEUhAFZdWCEOrCMc0u
------END CERTIFICATE-----
-
-# Issuer: CN=QuoVadis Root CA 3 O=QuoVadis Limited
-# Subject: CN=QuoVadis Root CA 3 O=QuoVadis Limited
-# Label: "QuoVadis Root CA 3"
-# Serial: 1478
-# MD5 Fingerprint: 31:85:3c:62:94:97:63:b9:aa:fd:89:4e:af:6f:e0:cf
-# SHA1 Fingerprint: 1f:49:14:f7:d8:74:95:1d:dd:ae:02:c0:be:fd:3a:2d:82:75:51:85
-# SHA256 Fingerprint: 18:f1:fc:7f:20:5d:f8:ad:dd:eb:7f:e0:07:dd:57:e3:af:37:5a:9c:4d:8d:73:54:6b:f4:f1:fe:d1:e1:8d:35
------BEGIN CERTIFICATE-----
-MIIGnTCCBIWgAwIBAgICBcYwDQYJKoZIhvcNAQEFBQAwRTELMAkGA1UEBhMCQk0x
-GTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxGzAZBgNVBAMTElF1b1ZhZGlzIFJv
-b3QgQ0EgMzAeFw0wNjExMjQxOTExMjNaFw0zMTExMjQxOTA2NDRaMEUxCzAJBgNV
-BAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMRswGQYDVQQDExJRdW9W
-YWRpcyBSb290IENBIDMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDM
-V0IWVJzmmNPTTe7+7cefQzlKZbPoFog02w1ZkXTPkrgEQK0CSzGrvI2RaNggDhoB
-4hp7Thdd4oq3P5kazethq8Jlph+3t723j/z9cI8LoGe+AaJZz3HmDyl2/7FWeUUr
-H556VOijKTVopAFPD6QuN+8bv+OPEKhyq1hX51SGyMnzW9os2l2ObjyjPtr7guXd
-8lyyBTNvijbO0BNO/79KDDRMpsMhvVAEVeuxu537RR5kFd5VAYwCdrXLoT9Cabwv
-vWhDFlaJKjdhkf2mrk7AyxRllDdLkgbvBNDInIjbC3uBr7E9KsRlOni27tyAsdLT
-mZw67mtaa7ONt9XOnMK+pUsvFrGeaDsGb659n/je7Mwpp5ijJUMv7/FfJuGITfhe
-btfZFG4ZM2mnO4SJk8RTVROhUXhA+LjJou57ulJCg54U7QVSWllWp5f8nT8KKdjc
-T5EOE7zelaTfi5m+rJsziO+1ga8bxiJTyPbH7pcUsMV8eFLI8M5ud2CEpukqdiDt
-WAEXMJPpGovgc2PZapKUSU60rUqFxKMiMPwJ7Wgic6aIDFUhWMXhOp8q3crhkODZ
-c6tsgLjoC2SToJyMGf+z0gzskSaHirOi4XCPLArlzW1oUevaPwV/izLmE1xr/l9A
-4iLItLRkT9a6fUg+qGkM17uGcclzuD87nSVL2v9A6wIDAQABo4IBlTCCAZEwDwYD
-VR0TAQH/BAUwAwEB/zCB4QYDVR0gBIHZMIHWMIHTBgkrBgEEAb5YAAMwgcUwgZMG
-CCsGAQUFBwICMIGGGoGDQW55IHVzZSBvZiB0aGlzIENlcnRpZmljYXRlIGNvbnN0
-aXR1dGVzIGFjY2VwdGFuY2Ugb2YgdGhlIFF1b1ZhZGlzIFJvb3QgQ0EgMyBDZXJ0
-aWZpY2F0ZSBQb2xpY3kgLyBDZXJ0aWZpY2F0aW9uIFByYWN0aWNlIFN0YXRlbWVu
-dC4wLQYIKwYBBQUHAgEWIWh0dHA6Ly93d3cucXVvdmFkaXNnbG9iYWwuY29tL2Nw
-czALBgNVHQ8EBAMCAQYwHQYDVR0OBBYEFPLAE+CCQz777i9nMpY1XNu4ywLQMG4G
-A1UdIwRnMGWAFPLAE+CCQz777i9nMpY1XNu4ywLQoUmkRzBFMQswCQYDVQQGEwJC
-TTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEbMBkGA1UEAxMSUXVvVmFkaXMg
-Um9vdCBDQSAzggIFxjANBgkqhkiG9w0BAQUFAAOCAgEAT62gLEz6wPJv92ZVqyM0
-7ucp2sNbtrCD2dDQ4iH782CnO11gUyeim/YIIirnv6By5ZwkajGxkHon24QRiSem
-d1o417+shvzuXYO8BsbRd2sPbSQvS3pspweWyuOEn62Iix2rFo1bZhfZFvSLgNLd
-+LJ2w/w4E6oM3kJpK27zPOuAJ9v1pkQNn1pVWQvVDVJIxa6f8i+AxeoyUDUSly7B
-4f/xI4hROJ/yZlZ25w9Rl6VSDE1JUZU2Pb+iSwwQHYaZTKrzchGT5Or2m9qoXadN
-t54CrnMAyNojA+j56hl0YgCUyyIgvpSnWbWCar6ZeXqp8kokUvd0/bpO5qgdAm6x
-DYBEwa7TIzdfu4V8K5Iu6H6li92Z4b8nby1dqnuH/grdS/yO9SbkbnBCbjPsMZ57
-k8HkyWkaPcBrTiJt7qtYTcbQQcEr6k8Sh17rRdhs9ZgC06DYVYoGmRmioHfRMJ6s
-zHXug/WwYjnPbFfiTNKRCw51KBuav/0aQ/HKd/s7j2G4aSgWQgRecCocIdiP4b0j
-Wy10QJLZYxkNc91pvGJHvOB0K7Lrfb5BG7XARsWhIstfTsEokt4YutUqKLsRixeT
-mJlglFwjz1onl14LBQaTNx47aTbrqZ5hHY8y2o4M1nQ+ewkk2gF3R8Q7zTSMmfXK
-4SVhM7JZG+Ju1zdXtg2pEto=
------END CERTIFICATE-----
-
-# Issuer: O=SECOM Trust.net OU=Security Communication RootCA1
-# Subject: O=SECOM Trust.net OU=Security Communication RootCA1
-# Label: "Security Communication Root CA"
-# Serial: 0
-# MD5 Fingerprint: f1:bc:63:6a:54:e0:b5:27:f5:cd:e7:1a:e3:4d:6e:4a
-# SHA1 Fingerprint: 36:b1:2b:49:f9:81:9e:d7:4c:9e:bc:38:0f:c6:56:8f:5d:ac:b2:f7
-# SHA256 Fingerprint: e7:5e:72:ed:9f:56:0e:ec:6e:b4:80:00:73:a4:3f:c3:ad:19:19:5a:39:22:82:01:78:95:97:4a:99:02:6b:6c
------BEGIN CERTIFICATE-----
-MIIDWjCCAkKgAwIBAgIBADANBgkqhkiG9w0BAQUFADBQMQswCQYDVQQGEwJKUDEY
-MBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYDVQQLEx5TZWN1cml0eSBDb21t
-dW5pY2F0aW9uIFJvb3RDQTEwHhcNMDMwOTMwMDQyMDQ5WhcNMjMwOTMwMDQyMDQ5
-WjBQMQswCQYDVQQGEwJKUDEYMBYGA1UEChMPU0VDT00gVHJ1c3QubmV0MScwJQYD
-VQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQCzs/5/022x7xZ8V6UMbXaKL0u/ZPtM7orw8yl8
-9f/uKuDp6bpbZCKamm8sOiZpUQWZJtzVHGpxxpp9Hp3dfGzGjGdnSj74cbAZJ6kJ
-DKaVv0uMDPpVmDvY6CKhS3E4eayXkmmziX7qIWgGmBSWh9JhNrxtJ1aeV+7AwFb9
-Ms+k2Y7CI9eNqPPYJayX5HA49LY6tJ07lyZDo6G8SVlyTCMwhwFY9k6+HGhWZq/N
-QV3Is00qVUarH9oe4kA92819uZKAnDfdDJZkndwi92SL32HeFZRSFaB9UslLqCHJ
-xrHty8OVYNEP8Ktw+N/LTX7s1vqr2b1/VPKl6Xn62dZ2JChzAgMBAAGjPzA9MB0G
-A1UdDgQWBBSgc0mZaNyFW2XjmygvV5+9M7wHSDALBgNVHQ8EBAMCAQYwDwYDVR0T
-AQH/BAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAQEAaECpqLvkT115swW1F7NgE+vG
-kl3g0dNq/vu+m22/xwVtWSDEHPC32oRYAmP6SBbvT6UL90qY8j+eG61Ha2POCEfr
-Uj94nK9NrvjVT8+amCoQQTlSxN3Zmw7vkwGusi7KaEIkQmywszo+zenaSMQVy+n5
-Bw+SUEmK3TGXX8npN6o7WWWXlDLJs58+OmJYxUmtYg5xpTKqL8aJdkNAExNnPaJU
-JRDL8Try2frbSVa7pv6nQTXD4IhhyYjH3zYQIphZ6rBK+1YWc26sTfcioU+tHXot
-RSflMMFe8toTyyVCUZVHA4xsIcx0Qu1T/zOLjw9XARYvz6buyXAiFL39vmwLAw==
------END CERTIFICATE-----
-
-# Issuer: CN=Sonera Class2 CA O=Sonera
-# Subject: CN=Sonera Class2 CA O=Sonera
-# Label: "Sonera Class 2 Root CA"
-# Serial: 29
-# MD5 Fingerprint: a3:ec:75:0f:2e:88:df:fa:48:01:4e:0b:5c:48:6f:fb
-# SHA1 Fingerprint: 37:f7:6d:e6:07:7c:90:c5:b1:3e:93:1a:b7:41:10:b4:f2:e4:9a:27
-# SHA256 Fingerprint: 79:08:b4:03:14:c1:38:10:0b:51:8d:07:35:80:7f:fb:fc:f8:51:8a:00:95:33:71:05:ba:38:6b:15:3d:d9:27
------BEGIN CERTIFICATE-----
-MIIDIDCCAgigAwIBAgIBHTANBgkqhkiG9w0BAQUFADA5MQswCQYDVQQGEwJGSTEP
-MA0GA1UEChMGU29uZXJhMRkwFwYDVQQDExBTb25lcmEgQ2xhc3MyIENBMB4XDTAx
-MDQwNjA3Mjk0MFoXDTIxMDQwNjA3Mjk0MFowOTELMAkGA1UEBhMCRkkxDzANBgNV
-BAoTBlNvbmVyYTEZMBcGA1UEAxMQU29uZXJhIENsYXNzMiBDQTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJAXSjWdyvANlsdE+hY3/Ei9vX+ALTU74W+o
-Z6m/AxxNjG8yR9VBaKQTBME1DJqEQ/xcHf+Js+gXGM2RX/uJ4+q/Tl18GybTdXnt
-5oTjV+WtKcT0OijnpXuENmmz/V52vaMtmdOQTiMofRhj8VQ7Jp12W5dCsv+u8E7s
-3TmVToMGf+dJQMjFAbJUWmYdPfz56TwKnoG4cPABi+QjVHzIrviQHgCWctRUz2Ej
-vOr7nQKV0ba5cTppCD8PtOFCx4j1P5iop7oc4HFx71hXgVB6XGt0Rg6DA5jDjqhu
-8nYybieDwnPz3BjotJPqdURrBGAgcVeHnfO+oJAjPYok4doh28MCAwEAAaMzMDEw
-DwYDVR0TAQH/BAUwAwEB/zARBgNVHQ4ECgQISqCqWITTXjwwCwYDVR0PBAQDAgEG
-MA0GCSqGSIb3DQEBBQUAA4IBAQBazof5FnIVV0sd2ZvnoiYw7JNn39Yt0jSv9zil
-zqsWuasvfDXLrNAPtEwr/IDva4yRXzZ299uzGxnq9LIR/WFxRL8oszodv7ND6J+/
-3DEIcbCdjdY0RzKQxmUk96BKfARzjzlvF4xytb1LyHr4e4PDKE6cCepnP7JnBBvD
-FNr450kkkdAdavphOe9r5yF1BgfYErQhIHBCcYHaPJo2vqZbDWpsmh+Re/n570K6
-Tk6ezAyNlNzZRZxe7EJQY670XcSxEtzKO6gunRRaBXW37Ndj4ro1tgQIkejanZz2
-ZrUYrAqmVCY0M9IbwdR/GjqOC6oybtv8TyWf2TLHllpwrN9M
------END CERTIFICATE-----
-
-# Issuer: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden
-# Subject: CN=Staat der Nederlanden Root CA O=Staat der Nederlanden
-# Label: "Staat der Nederlanden Root CA"
-# Serial: 10000010
-# MD5 Fingerprint: 60:84:7c:5a:ce:db:0c:d4:cb:a7:e9:fe:02:c6:a9:c0
-# SHA1 Fingerprint: 10:1d:fa:3f:d5:0b:cb:bb:9b:b5:60:0c:19:55:a4:1a:f4:73:3a:04
-# SHA256 Fingerprint: d4:1d:82:9e:8c:16:59:82:2a:f9:3f:ce:62:bf:fc:de:26:4f:c8:4e:8b:95:0c:5f:f2:75:d0:52:35:46:95:a3
------BEGIN CERTIFICATE-----
-MIIDujCCAqKgAwIBAgIEAJiWijANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJO
-TDEeMBwGA1UEChMVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSYwJAYDVQQDEx1TdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQTAeFw0wMjEyMTcwOTIzNDlaFw0xNTEy
-MTYwOTE1MzhaMFUxCzAJBgNVBAYTAk5MMR4wHAYDVQQKExVTdGFhdCBkZXIgTmVk
-ZXJsYW5kZW4xJjAkBgNVBAMTHVN0YWF0IGRlciBOZWRlcmxhbmRlbiBSb290IENB
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAmNK1URF6gaYUmHFtvszn
-ExvWJw56s2oYHLZhWtVhCb/ekBPHZ+7d89rFDBKeNVU+LCeIQGv33N0iYfXCxw71
-9tV2U02PjLwYdjeFnejKScfST5gTCaI+Ioicf9byEGW07l8Y1Rfj+MX94p2i71MO
-hXeiD+EwR+4A5zN9RGcaC1Hoi6CeUJhoNFIfLm0B8mBF8jHrqTFoKbt6QZ7GGX+U
-tFE5A3+y3qcym7RHjm+0Sq7lr7HcsBthvJly3uSJt3omXdozSVtSnA71iq3DuD3o
-BmrC1SoLbHuEvVYFy4ZlkuxEK7COudxwC0barbxjiDn622r+I/q85Ej0ZytqERAh
-SQIDAQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wTwYDVR0gBEgwRjBEBgRVHSAAMDww
-OgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cucGtpb3ZlcmhlaWQubmwvcG9saWNpZXMv
-cm9vdC1wb2xpY3kwDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSofeu8Y6R0E3QA
-7Jbg0zTBLL9s+DANBgkqhkiG9w0BAQUFAAOCAQEABYSHVXQ2YcG70dTGFagTtJ+k
-/rvuFbQvBgwp8qiSpGEN/KtcCFtREytNwiphyPgJWPwtArI5fZlmgb9uXJVFIGzm
-eafR2Bwp/MIgJ1HI8XxdNGdphREwxgDS1/PTfLbwMVcoEoJz6TMvplW0C5GUR5z6
-u3pCMuiufi3IvKwUv9kP2Vv8wfl6leF9fpb8cbDCTMjfRTTJzg3ynGQI0DvDKcWy
-7ZAEwbEpkcUwb8GpcjPM/l0WFywRaed+/sWDCN+83CI6LiBpIzlWYGeQiy52OfsR
-iJf2fL1LuCAWZwWN4jvBcj+UlTfHXbme2JOhF4//DGYVwSR8MnwDHTuhWEUykw==
------END CERTIFICATE-----
-
-# Issuer: O=TDC Internet OU=TDC Internet Root CA
-# Subject: O=TDC Internet OU=TDC Internet Root CA
-# Label: "TDC Internet Root CA"
-# Serial: 986490188
-# MD5 Fingerprint: 91:f4:03:55:20:a1:f8:63:2c:62:de:ac:fb:61:1c:8e
-# SHA1 Fingerprint: 21:fc:bd:8e:7f:6c:af:05:1b:d1:b3:43:ec:a8:e7:61:47:f2:0f:8a
-# SHA256 Fingerprint: 48:98:c6:88:8c:0c:ff:b0:d3:e3:1a:ca:8a:37:d4:e3:51:5f:f7:46:d0:26:35:d8:66:46:cf:a0:a3:18:5a:e7
------BEGIN CERTIFICATE-----
-MIIEKzCCAxOgAwIBAgIEOsylTDANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJE
-SzEVMBMGA1UEChMMVERDIEludGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQg
-Um9vdCBDQTAeFw0wMTA0MDUxNjMzMTdaFw0yMTA0MDUxNzAzMTdaMEMxCzAJBgNV
-BAYTAkRLMRUwEwYDVQQKEwxUREMgSW50ZXJuZXQxHTAbBgNVBAsTFFREQyBJbnRl
-cm5ldCBSb290IENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxLhA
-vJHVYx/XmaCLDEAedLdInUaMArLgJF/wGROnN4NrXceO+YQwzho7+vvOi20jxsNu
-Zp+Jpd/gQlBn+h9sHvTQBda/ytZO5GhgbEaqHF1j4QeGDmUApy6mcca8uYGoOn0a
-0vnRrEvLznWv3Hv6gXPU/Lq9QYjUdLP5Xjg6PEOo0pVOd20TDJ2PeAG3WiAfAzc1
-4izbSysseLlJ28TQx5yc5IogCSEWVmb/Bexb4/DPqyQkXsN/cHoSxNK1EKC2IeGN
-eGlVRGn1ypYcNIUXJXfi9i8nmHj9eQY6otZaQ8H/7AQ77hPv01ha/5Lr7K7a8jcD
-R0G2l8ktCkEiu7vmpwIDAQABo4IBJTCCASEwEQYJYIZIAYb4QgEBBAQDAgAHMGUG
-A1UdHwReMFwwWqBYoFakVDBSMQswCQYDVQQGEwJESzEVMBMGA1UEChMMVERDIElu
-dGVybmV0MR0wGwYDVQQLExRUREMgSW50ZXJuZXQgUm9vdCBDQTENMAsGA1UEAxME
-Q1JMMTArBgNVHRAEJDAigA8yMDAxMDQwNTE2MzMxN1qBDzIwMjEwNDA1MTcwMzE3
-WjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUbGQBx/2FbazI2p5QCIUItTxWqFAw
-HQYDVR0OBBYEFGxkAcf9hW2syNqeUAiFCLU8VqhQMAwGA1UdEwQFMAMBAf8wHQYJ
-KoZIhvZ9B0EABBAwDhsIVjUuMDo0LjADAgSQMA0GCSqGSIb3DQEBBQUAA4IBAQBO
-Q8zR3R0QGwZ/t6T609lN+yOfI1Rb5osvBCiLtSdtiaHsmGnc540mgwV5dOy0uaOX
-wTUA/RXaOYE6lTGQ3pfphqiZdwzlWqCE/xIWrG64jcN7ksKsLtB9KOy282A4aW8+
-2ARVPp7MVdK6/rtHBNcK2RYKNCn1WBPVT8+PVkuzHu7TmHnaCB4Mb7j4Fifvwm89
-9qNLPg7kbWzbO0ESm70NRyN/PErQr8Cv9u8btRXE64PECV90i9kR+8JWsTz4cMo0
-jUNAE4z9mQNUecYu6oah9jrUCbz0vGbMPVjQV0kK7iXiQe4T+Zs4NNEA9X7nlB38
-aQNiuJkFBT1reBK9sG9l
------END CERTIFICATE-----
-
-# Issuer: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com
-# Subject: CN=UTN - DATACorp SGC O=The USERTRUST Network OU=http://www.usertrust.com
-# Label: "UTN DATACorp SGC Root CA"
-# Serial: 91374294542884689855167577680241077609
-# MD5 Fingerprint: b3:a5:3e:77:21:6d:ac:4a:c0:c9:fb:d5:41:3d:ca:06
-# SHA1 Fingerprint: 58:11:9f:0e:12:82:87:ea:50:fd:d9:87:45:6f:4f:78:dc:fa:d6:d4
-# SHA256 Fingerprint: 85:fb:2f:91:dd:12:27:5a:01:45:b6:36:53:4f:84:02:4a:d6:8b:69:b8:ee:88:68:4f:f7:11:37:58:05:b3:48
------BEGIN CERTIFICATE-----
-MIIEXjCCA0agAwIBAgIQRL4Mi1AAIbQR0ypoBqmtaTANBgkqhkiG9w0BAQUFADCB
-kzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xGzAZBgNVBAMTElVUTiAtIERBVEFDb3Jw
-IFNHQzAeFw05OTA2MjQxODU3MjFaFw0xOTA2MjQxOTA2MzBaMIGTMQswCQYDVQQG
-EwJVUzELMAkGA1UECBMCVVQxFzAVBgNVBAcTDlNhbHQgTGFrZSBDaXR5MR4wHAYD
-VQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxITAfBgNVBAsTGGh0dHA6Ly93d3cu
-dXNlcnRydXN0LmNvbTEbMBkGA1UEAxMSVVROIC0gREFUQUNvcnAgU0dDMIIBIjAN
-BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3+5YEKIrblXEjr8uRgnn4AgPLit6
-E5Qbvfa2gI5lBZMAHryv4g+OGQ0SR+ysraP6LnD43m77VkIVni5c7yPeIbkFdicZ
-D0/Ww5y0vpQZY/KmEQrrU0icvvIpOxboGqBMpsn0GFlowHDyUwDAXlCCpVZvNvlK
-4ESGoE1O1kduSUrLZ9emxAW5jh70/P/N5zbgnAVssjMiFdC04MwXwLLA9P4yPykq
-lXvY8qdOD1R8oQ2AswkDwf9c3V6aPryuvEeKaq5xyh+xKrhfQgUL7EYw0XILyulW
-bfXv33i+Ybqypa4ETLyorGkVl73v67SMvzX41MPRKA5cOp9wGDMgd8SirwIDAQAB
-o4GrMIGoMAsGA1UdDwQEAwIBxjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRT
-MtGzz3/64PGgXYVOktKeRR20TzA9BgNVHR8ENjA0MDKgMKAuhixodHRwOi8vY3Js
-LnVzZXJ0cnVzdC5jb20vVVROLURBVEFDb3JwU0dDLmNybDAqBgNVHSUEIzAhBggr
-BgEFBQcDAQYKKwYBBAGCNwoDAwYJYIZIAYb4QgQBMA0GCSqGSIb3DQEBBQUAA4IB
-AQAnNZcAiosovcYzMB4p/OL31ZjUQLtgyr+rFywJNn9Q+kHcrpY6CiM+iVnJowft
-Gzet/Hy+UUla3joKVAgWRcKZsYfNjGjgaQPpxE6YsjuMFrMOoAyYUJuTqXAJyCyj
-j98C5OBxOvG0I3KgqgHf35g+FFCgMSa9KOlaMCZ1+XtgHI3zzVAmbQQnmt/VDUVH
-KWss5nbZqSl9Mt3JNjy9rjXxEZ4du5A/EkdOjtd+D2JzHVImOBwYSf0wdJrE5SIv
-2MCN7ZF6TACPcn9d2t0bi0Vr591pl6jFVkwPDPafepE39peC4N1xaf92P2BNPM/3
-mfnGV/TJVTl4uix5yaaIK/QI
------END CERTIFICATE-----
-
-# Issuer: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
-# Subject: CN=UTN-USERFirst-Hardware O=The USERTRUST Network OU=http://www.usertrust.com
-# Label: "UTN USERFirst Hardware Root CA"
-# Serial: 91374294542884704022267039221184531197
-# MD5 Fingerprint: 4c:56:41:e5:0d:bb:2b:e8:ca:a3:ed:18:08:ad:43:39
-# SHA1 Fingerprint: 04:83:ed:33:99:ac:36:08:05:87:22:ed:bc:5e:46:00:e3:be:f9:d7
-# SHA256 Fingerprint: 6e:a5:47:41:d0:04:66:7e:ed:1b:48:16:63:4a:a3:a7:9e:6e:4b:96:95:0f:82:79:da:fc:8d:9b:d8:81:21:37
------BEGIN CERTIFICATE-----
-MIIEdDCCA1ygAwIBAgIQRL4Mi1AAJLQR0zYq/mUK/TANBgkqhkiG9w0BAQUFADCB
-lzELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2Ug
-Q2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExho
-dHRwOi8vd3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3Qt
-SGFyZHdhcmUwHhcNOTkwNzA5MTgxMDQyWhcNMTkwNzA5MTgxOTIyWjCBlzELMAkG
-A1UEBhMCVVMxCzAJBgNVBAgTAlVUMRcwFQYDVQQHEw5TYWx0IExha2UgQ2l0eTEe
-MBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMSEwHwYDVQQLExhodHRwOi8v
-d3d3LnVzZXJ0cnVzdC5jb20xHzAdBgNVBAMTFlVUTi1VU0VSRmlyc3QtSGFyZHdh
-cmUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCx98M4P7Sof885glFn
-0G2f0v9Y8+efK+wNiVSZuTiZFvfgIXlIwrthdBKWHTxqctU8EGc6Oe0rE81m65UJ
-M6Rsl7HoxuzBdXmcRl6Nq9Bq/bkqVRcQVLMZ8Jr28bFdtqdt++BxF2uiiPsA3/4a
-MXcMmgF6sTLjKwEHOG7DpV4jvEWbe1DByTCP2+UretNb+zNAHqDVmBe8i4fDidNd
-oI6yqqr2jmmIBsX6iSHzCJ1pLgkzmykNRg+MzEk0sGlRvfkGzWitZky8PqxhvQqI
-DsjfPe58BEydCl5rkdbux+0ojatNh4lz0G6k0B4WixThdkQDf2Os5M1JnMWS9Ksy
-oUhbAgMBAAGjgbkwgbYwCwYDVR0PBAQDAgHGMA8GA1UdEwEB/wQFMAMBAf8wHQYD
-VR0OBBYEFKFyXyYbKJhDlV0HN9WFlp1L0sNFMEQGA1UdHwQ9MDswOaA3oDWGM2h0
-dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VVE4tVVNFUkZpcnN0LUhhcmR3YXJlLmNy
-bDAxBgNVHSUEKjAoBggrBgEFBQcDAQYIKwYBBQUHAwUGCCsGAQUFBwMGBggrBgEF
-BQcDBzANBgkqhkiG9w0BAQUFAAOCAQEARxkP3nTGmZev/K0oXnWO6y1n7k57K9cM
-//bey1WiCuFMVGWTYGufEpytXoMs61quwOQt9ABjHbjAbPLPSbtNk28Gpgoiskli
-CE7/yMgUsogWXecB5BKV5UU0s4tpvc+0hY91UZ59Ojg6FEgSxvunOxqNDYJAB+gE
-CJChicsZUN/KHAG8HQQZexB2lzvukJDKxA4fFm517zP4029bHpbj4HR3dHuKom4t
-3XbWOTCC8KucUvIqx69JXn7HaOWCgchqJ/kniCrVWFCVH/A7HFe7fRQ5YiuayZSS
-KqMiDP+JJn1fIytH1xUdqWqeUQ0qUZ6B+dQ7XnASfxAynB67nfhmqA==
------END CERTIFICATE-----
-
-# Issuer: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Subject: CN=Chambers of Commerce Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Label: "Camerfirma Chambers of Commerce Root"
-# Serial: 0
-# MD5 Fingerprint: b0:01:ee:14:d9:af:29:18:94:76:8e:f1:69:33:2a:84
-# SHA1 Fingerprint: 6e:3a:55:a4:19:0c:19:5c:93:84:3c:c0:db:72:2e:31:30:61:f0:b1
-# SHA256 Fingerprint: 0c:25:8a:12:a5:67:4a:ef:25:f2:8b:a7:dc:fa:ec:ee:a3:48:e5:41:e6:f5:cc:4e:e6:3b:71:b3:61:60:6a:c3
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBADANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEiMCAGA1UEAxMZQ2hhbWJlcnMg
-b2YgQ29tbWVyY2UgUm9vdDAeFw0wMzA5MzAxNjEzNDNaFw0zNzA5MzAxNjEzNDRa
-MH8xCzAJBgNVBAYTAkVVMScwJQYDVQQKEx5BQyBDYW1lcmZpcm1hIFNBIENJRiBB
-ODI3NDMyODcxIzAhBgNVBAsTGmh0dHA6Ly93d3cuY2hhbWJlcnNpZ24ub3JnMSIw
-IAYDVQQDExlDaGFtYmVycyBvZiBDb21tZXJjZSBSb290MIIBIDANBgkqhkiG9w0B
-AQEFAAOCAQ0AMIIBCAKCAQEAtzZV5aVdGDDg2olUkfzIx1L4L1DZ77F1c2VHfRtb
-unXF/KGIJPov7coISjlUxFF6tdpg6jg8gbLL8bvZkSM/SAFwdakFKq0fcfPJVD0d
-BmpAPrMMhe5cG3nCYsS4No41XQEMIwRHNaqbYE6gZj3LJgqcQKH0XZi/caulAGgq
-7YN6D6IUtdQis4CwPAxaUWktWBiP7Zme8a7ileb2R6jWDA+wWFjbw2Y3npuRVDM3
-0pQcakjJyfKl2qUMI/cjDpwyVV5xnIQFUZot/eZOKjRa3spAN2cMVCFVd9oKDMyX
-roDclDZK9D7ONhMeU+SsTjoF7Nuucpw4i9A5O4kKPnf+dQIBA6OCAUQwggFAMBIG
-A1UdEwEB/wQIMAYBAf8CAQwwPAYDVR0fBDUwMzAxoC+gLYYraHR0cDovL2NybC5j
-aGFtYmVyc2lnbi5vcmcvY2hhbWJlcnNyb290LmNybDAdBgNVHQ4EFgQU45T1sU3p
-26EpW1eLTXYGduHRooowDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIA
-BzAnBgNVHREEIDAegRxjaGFtYmVyc3Jvb3RAY2hhbWJlcnNpZ24ub3JnMCcGA1Ud
-EgQgMB6BHGNoYW1iZXJzcm9vdEBjaGFtYmVyc2lnbi5vcmcwWAYDVR0gBFEwTzBN
-BgsrBgEEAYGHLgoDATA+MDwGCCsGAQUFBwIBFjBodHRwOi8vY3BzLmNoYW1iZXJz
-aWduLm9yZy9jcHMvY2hhbWJlcnNyb290Lmh0bWwwDQYJKoZIhvcNAQEFBQADggEB
-AAxBl8IahsAifJ/7kPMa0QOx7xP5IV8EnNrJpY0nbJaHkb5BkAFyk+cefV/2icZd
-p0AJPaxJRUXcLo0waLIJuvvDL8y6C98/d3tGfToSJI6WjzwFCm/SlCgdbQzALogi
-1djPHRPH8EjX1wWnz8dHnjs8NMiAT9QUu/wNUPf6s+xCX6ndbcj0dc97wXImsQEc
-XCz9ek60AcUFV7nnPKoF2YjpB0ZBzu9Bga5Y34OirsrXdx/nADydb47kMgkdTXg0
-eDQ8lJsm7U9xxhl6vSAiSFr+S30Dt+dYvsYyTnQeaN2oaFuzPu5ifdmA6Ap1erfu
-tGWaIZDgqtCYvDi1czyL+Nw=
------END CERTIFICATE-----
-
-# Issuer: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Subject: CN=Global Chambersign Root O=AC Camerfirma SA CIF A82743287 OU=http://www.chambersign.org
-# Label: "Camerfirma Global Chambersign Root"
-# Serial: 0
-# MD5 Fingerprint: c5:e6:7b:bf:06:d0:4f:43:ed:c4:7a:65:8a:fb:6b:19
-# SHA1 Fingerprint: 33:9b:6b:14:50:24:9b:55:7a:01:87:72:84:d9:e0:2f:c3:d2:d8:e9
-# SHA256 Fingerprint: ef:3c:b4:17:fc:8e:bf:6f:97:87:6c:9e:4e:ce:39:de:1e:a5:fe:64:91:41:d1:02:8b:7d:11:c0:b2:29:8c:ed
------BEGIN CERTIFICATE-----
-MIIExTCCA62gAwIBAgIBADANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJFVTEn
-MCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgyNzQzMjg3MSMwIQYDVQQL
-ExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4GA1UEAxMXR2xvYmFsIENo
-YW1iZXJzaWduIFJvb3QwHhcNMDMwOTMwMTYxNDE4WhcNMzcwOTMwMTYxNDE4WjB9
-MQswCQYDVQQGEwJFVTEnMCUGA1UEChMeQUMgQ2FtZXJmaXJtYSBTQSBDSUYgQTgy
-NzQzMjg3MSMwIQYDVQQLExpodHRwOi8vd3d3LmNoYW1iZXJzaWduLm9yZzEgMB4G
-A1UEAxMXR2xvYmFsIENoYW1iZXJzaWduIFJvb3QwggEgMA0GCSqGSIb3DQEBAQUA
-A4IBDQAwggEIAoIBAQCicKLQn0KuWxfH2H3PFIP8T8mhtxOviteePgQKkotgVvq0
-Mi+ITaFgCPS3CU6gSS9J1tPfnZdan5QEcOw/Wdm3zGaLmFIoCQLfxS+EjXqXd7/s
-QJ0lcqu1PzKY+7e3/HKE5TWH+VX6ox8Oby4o3Wmg2UIQxvi1RMLQQ3/bvOSiPGpV
-eAp3qdjqGTK3L/5cPxvusZjsyq16aUXjlg9V9ubtdepl6DJWk0aJqCWKZQbua795
-B9Dxt6/tLE2Su8CoX6dnfQTyFQhwrJLWfQTSM/tMtgsL+xrJxI0DqX5c8lCrEqWh
-z0hQpe/SyBoT+rB/sYIcd2oPX9wLlY/vQ37mRQklAgEDo4IBUDCCAUwwEgYDVR0T
-AQH/BAgwBgEB/wIBDDA/BgNVHR8EODA2MDSgMqAwhi5odHRwOi8vY3JsLmNoYW1i
-ZXJzaWduLm9yZy9jaGFtYmVyc2lnbnJvb3QuY3JsMB0GA1UdDgQWBBRDnDafsJ4w
-TcbOX60Qq+UDpfqpFDAOBgNVHQ8BAf8EBAMCAQYwEQYJYIZIAYb4QgEBBAQDAgAH
-MCoGA1UdEQQjMCGBH2NoYW1iZXJzaWducm9vdEBjaGFtYmVyc2lnbi5vcmcwKgYD
-VR0SBCMwIYEfY2hhbWJlcnNpZ25yb290QGNoYW1iZXJzaWduLm9yZzBbBgNVHSAE
-VDBSMFAGCysGAQQBgYcuCgEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly9jcHMuY2hh
-bWJlcnNpZ24ub3JnL2Nwcy9jaGFtYmVyc2lnbnJvb3QuaHRtbDANBgkqhkiG9w0B
-AQUFAAOCAQEAPDtwkfkEVCeR4e3t/mh/YV3lQWVPMvEYBZRqHN4fcNs+ezICNLUM
-bKGKfKX0j//U2K0X1S0E0T9YgOKBWYi+wONGkyT+kL0mojAt6JcmVzWJdJYY9hXi
-ryQZVgICsroPFOrGimbBhkVVi76SvpykBMdJPJ7oKXqJ1/6v/2j1pReQvayZzKWG
-VwlnRtvWFsJG8eSpUPWP0ZIV018+xgBJOm5YstHRJw0lyDL4IBHNfTIzSJRUTN3c
-ecQwn+uOuFW114hcxWokPbLTBQNRxgfvzBRydD1ucs4YKIxKoHflCStFREest2d/
-AYoFWpO+ocH/+OcOZ6RHSXZddZAa9SaP8A==
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Subject: CN=NetLock Kozjegyzoi (Class A) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Label: "NetLock Notary (Class A) Root"
-# Serial: 259
-# MD5 Fingerprint: 86:38:6d:5e:49:63:6c:85:5c:db:6d:dc:94:b7:d0:f7
-# SHA1 Fingerprint: ac:ed:5f:65:53:fd:25:ce:01:5f:1f:7a:48:3b:6a:74:9f:61:78:c6
-# SHA256 Fingerprint: 7f:12:cd:5f:7e:5e:29:0e:c7:d8:51:79:d5:b7:2c:20:a5:be:75:08:ff:db:5b:f8:1a:b9:68:4a:7f:c9:f6:67
------BEGIN CERTIFICATE-----
-MIIGfTCCBWWgAwIBAgICAQMwDQYJKoZIhvcNAQEEBQAwga8xCzAJBgNVBAYTAkhV
-MRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMe
-TmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0
-dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBLb3pqZWd5em9pIChDbGFzcyBB
-KSBUYW51c2l0dmFueWtpYWRvMB4XDTk5MDIyNDIzMTQ0N1oXDTE5MDIxOTIzMTQ0
-N1owga8xCzAJBgNVBAYTAkhVMRAwDgYDVQQIEwdIdW5nYXJ5MREwDwYDVQQHEwhC
-dWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9uc2FnaSBLZnQu
-MRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE2MDQGA1UEAxMtTmV0TG9jayBL
-b3pqZWd5em9pIChDbGFzcyBBKSBUYW51c2l0dmFueWtpYWRvMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvHSMD7tM9DceqQWC2ObhbHDqeLVu0ThEDaiD
-zl3S1tWBxdRL51uUcCbbO51qTGL3cfNk1mE7PetzozfZz+qMkjvN9wfcZnSX9EUi
-3fRc4L9t875lM+QVOr/bmJBVOMTtplVjC7B4BPTjbsE/jvxReB+SnoPC/tmwqcm8
-WgD/qaiYdPv2LD4VOQ22BFWoDpggQrOxJa1+mm9dU7GrDPzr4PN6s6iz/0b2Y6LY
-Oph7tqyF/7AlT3Rj5xMHpQqPBffAZG9+pyeAlt7ULoZgx2srXnN7F+eRP2QM2Esi
-NCubMvJIH5+hCoR64sKtlz2O1cH5VqNQ6ca0+pii7pXmKgOM3wIDAQABo4ICnzCC
-ApswDgYDVR0PAQH/BAQDAgAGMBIGA1UdEwEB/wQIMAYBAf8CAQQwEQYJYIZIAYb4
-QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1GSUdZRUxFTSEgRXplbiB0
-YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFub3MgU3pvbGdhbHRhdGFz
-aSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBhbGFwamFuIGtlc3p1bHQu
-IEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExvY2sgS2Z0LiB0ZXJtZWtm
-ZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGlnaXRhbGlzIGFsYWlyYXMg
-ZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0IGVsbGVub3J6ZXNpIGVs
-amFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJhc2EgbWVndGFsYWxoYXRv
-IGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGphbiBhIGh0dHBzOi8vd3d3
-Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJoZXRvIGF6IGVsbGVub3J6
-ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBPUlRBTlQhIFRoZSBpc3N1
-YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmljYXRlIGlzIHN1YmplY3Qg
-dG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5uZXRs
-b2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNAbmV0bG9jay5uZXQuMA0G
-CSqGSIb3DQEBBAUAA4IBAQBIJEb3ulZv+sgoA0BO5TE5ayZrU3/b39/zcT0mwBQO
-xmd7I6gMc90Bu8bKbjc5VdXHjFYgDigKDtIqpLBJUsY4B/6+CgmM0ZjPytoUMaFP
-0jn8DxEsQ8Pdq5PHVT5HfBgaANzze9jyf1JsIPQLX2lS9O74silg6+NJMSEN1rUQ
-QeJBCWziGppWS3cC9qCbmieH6FUpccKQn0V4GuEVZD3QDtigdp+uxdAu6tYPVuxk
-f1qbFFgBJ34TUMdrKuZoPL9coAob4Q566eKAw+np9v1sEZ7Q5SgnK1QyQhSCdeZK
-8CtmdWOMovsEPoMOmzbwGOQmIMOM8CgHrTwXZoi1/baI
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Uzleti (Class B) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Subject: CN=NetLock Uzleti (Class B) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Label: "NetLock Business (Class B) Root"
-# Serial: 105
-# MD5 Fingerprint: 39:16:aa:b9:6a:41:e1:14:69:df:9e:6c:3b:72:dc:b6
-# SHA1 Fingerprint: 87:9f:4b:ee:05:df:98:58:3b:e3:60:d6:33:e7:0d:3f:fe:98:71:af
-# SHA256 Fingerprint: 39:df:7b:68:2b:7b:93:8f:84:71:54:81:cc:de:8d:60:d8:f2:2e:c5:98:87:7d:0a:aa:c1:2b:59:18:2b:03:12
------BEGIN CERTIFICATE-----
-MIIFSzCCBLSgAwIBAgIBaTANBgkqhkiG9w0BAQQFADCBmTELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTIwMAYDVQQD
-EylOZXRMb2NrIFV6bGV0aSAoQ2xhc3MgQikgVGFudXNpdHZhbnlraWFkbzAeFw05
-OTAyMjUxNDEwMjJaFw0xOTAyMjAxNDEwMjJaMIGZMQswCQYDVQQGEwJIVTERMA8G
-A1UEBxMIQnVkYXBlc3QxJzAlBgNVBAoTHk5ldExvY2sgSGFsb3phdGJpenRvbnNh
-Z2kgS2Z0LjEaMBgGA1UECxMRVGFudXNpdHZhbnlraWFkb2sxMjAwBgNVBAMTKU5l
-dExvY2sgVXpsZXRpIChDbGFzcyBCKSBUYW51c2l0dmFueWtpYWRvMIGfMA0GCSqG
-SIb3DQEBAQUAA4GNADCBiQKBgQCx6gTsIKAjwo84YM/HRrPVG/77uZmeBNwcf4xK
-gZjupNTKihe5In+DCnVMm8Bp2GQ5o+2So/1bXHQawEfKOml2mrriRBf8TKPV/riX
-iK+IA4kfpPIEPsgHC+b5sy96YhQJRhTKZPWLgLViqNhr1nGTLbO/CVRY7QbrqHvc
-Q7GhaQIDAQABo4ICnzCCApswEgYDVR0TAQH/BAgwBgEB/wIBBDAOBgNVHQ8BAf8E
-BAMCAAYwEQYJYIZIAYb4QgEBBAQDAgAHMIICYAYJYIZIAYb4QgENBIICURaCAk1G
-SUdZRUxFTSEgRXplbiB0YW51c2l0dmFueSBhIE5ldExvY2sgS2Z0LiBBbHRhbGFu
-b3MgU3pvbGdhbHRhdGFzaSBGZWx0ZXRlbGVpYmVuIGxlaXJ0IGVsamFyYXNvayBh
-bGFwamFuIGtlc3p1bHQuIEEgaGl0ZWxlc2l0ZXMgZm9seWFtYXRhdCBhIE5ldExv
-Y2sgS2Z0LiB0ZXJtZWtmZWxlbG9zc2VnLWJpenRvc2l0YXNhIHZlZGkuIEEgZGln
-aXRhbGlzIGFsYWlyYXMgZWxmb2dhZGFzYW5hayBmZWx0ZXRlbGUgYXogZWxvaXJ0
-IGVsbGVub3J6ZXNpIGVsamFyYXMgbWVndGV0ZWxlLiBBeiBlbGphcmFzIGxlaXJh
-c2EgbWVndGFsYWxoYXRvIGEgTmV0TG9jayBLZnQuIEludGVybmV0IGhvbmxhcGph
-biBhIGh0dHBzOi8vd3d3Lm5ldGxvY2submV0L2RvY3MgY2ltZW4gdmFneSBrZXJo
-ZXRvIGF6IGVsbGVub3J6ZXNAbmV0bG9jay5uZXQgZS1tYWlsIGNpbWVuLiBJTVBP
-UlRBTlQhIFRoZSBpc3N1YW5jZSBhbmQgdGhlIHVzZSBvZiB0aGlzIGNlcnRpZmlj
-YXRlIGlzIHN1YmplY3QgdG8gdGhlIE5ldExvY2sgQ1BTIGF2YWlsYWJsZSBhdCBo
-dHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIG9yIGJ5IGUtbWFpbCBhdCBjcHNA
-bmV0bG9jay5uZXQuMA0GCSqGSIb3DQEBBAUAA4GBAATbrowXr/gOkDFOzT4JwG06
-sPgzTEdM43WIEJessDgVkcYplswhwG08pXTP2IKlOcNl40JwuyKQ433bNXbhoLXa
-n3BukxowOR0w2y7jfLKRstE3Kfq51hdcR0/jHTjrn9V7lagonhVK0dHQKwCXoOKS
-NitjrFgBazMpUIaD8QFI
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Expressz (Class C) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Subject: CN=NetLock Expressz (Class C) Tanusitvanykiado O=NetLock Halozatbiztonsagi Kft. OU=Tanusitvanykiadok
-# Label: "NetLock Express (Class C) Root"
-# Serial: 104
-# MD5 Fingerprint: 4f:eb:f1:f0:70:c2:80:63:5d:58:9f:da:12:3c:a9:c4
-# SHA1 Fingerprint: e3:92:51:2f:0a:cf:f5:05:df:f6:de:06:7f:75:37:e1:65:ea:57:4b
-# SHA256 Fingerprint: 0b:5e:ed:4e:84:64:03:cf:55:e0:65:84:84:40:ed:2a:82:75:8b:f5:b9:aa:1f:25:3d:46:13:cf:a0:80:ff:3f
------BEGIN CERTIFICATE-----
-MIIFTzCCBLigAwIBAgIBaDANBgkqhkiG9w0BAQQFADCBmzELMAkGA1UEBhMCSFUx
-ETAPBgNVBAcTCEJ1ZGFwZXN0MScwJQYDVQQKEx5OZXRMb2NrIEhhbG96YXRiaXp0
-b25zYWdpIEtmdC4xGjAYBgNVBAsTEVRhbnVzaXR2YW55a2lhZG9rMTQwMgYDVQQD
-EytOZXRMb2NrIEV4cHJlc3N6IChDbGFzcyBDKSBUYW51c2l0dmFueWtpYWRvMB4X
-DTk5MDIyNTE0MDgxMVoXDTE5MDIyMDE0MDgxMVowgZsxCzAJBgNVBAYTAkhVMREw
-DwYDVQQHEwhCdWRhcGVzdDEnMCUGA1UEChMeTmV0TG9jayBIYWxvemF0Yml6dG9u
-c2FnaSBLZnQuMRowGAYDVQQLExFUYW51c2l0dmFueWtpYWRvazE0MDIGA1UEAxMr
-TmV0TG9jayBFeHByZXNzeiAoQ2xhc3MgQykgVGFudXNpdHZhbnlraWFkbzCBnzAN
-BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA6+ywbGGKIyWvYCDj2Z/8kwvbXY2wobNA
-OoLO/XXgeDIDhlqGlZHtU/qdQPzm6N3ZW3oDvV3zOwzDUXmbrVWg6dADEK8KuhRC
-2VImESLH0iDMgqSaqf64gXadarfSNnU+sYYJ9m5tfk63euyucYT2BDMIJTLrdKwW
-RMbkQJMdf60CAwEAAaOCAp8wggKbMBIGA1UdEwEB/wQIMAYBAf8CAQQwDgYDVR0P
-AQH/BAQDAgAGMBEGCWCGSAGG+EIBAQQEAwIABzCCAmAGCWCGSAGG+EIBDQSCAlEW
-ggJNRklHWUVMRU0hIEV6ZW4gdGFudXNpdHZhbnkgYSBOZXRMb2NrIEtmdC4gQWx0
-YWxhbm9zIFN6b2xnYWx0YXRhc2kgRmVsdGV0ZWxlaWJlbiBsZWlydCBlbGphcmFz
-b2sgYWxhcGphbiBrZXN6dWx0LiBBIGhpdGVsZXNpdGVzIGZvbHlhbWF0YXQgYSBO
-ZXRMb2NrIEtmdC4gdGVybWVrZmVsZWxvc3NlZy1iaXp0b3NpdGFzYSB2ZWRpLiBB
-IGRpZ2l0YWxpcyBhbGFpcmFzIGVsZm9nYWRhc2FuYWsgZmVsdGV0ZWxlIGF6IGVs
-b2lydCBlbGxlbm9yemVzaSBlbGphcmFzIG1lZ3RldGVsZS4gQXogZWxqYXJhcyBs
-ZWlyYXNhIG1lZ3RhbGFsaGF0byBhIE5ldExvY2sgS2Z0LiBJbnRlcm5ldCBob25s
-YXBqYW4gYSBodHRwczovL3d3dy5uZXRsb2NrLm5ldC9kb2NzIGNpbWVuIHZhZ3kg
-a2VyaGV0byBheiBlbGxlbm9yemVzQG5ldGxvY2submV0IGUtbWFpbCBjaW1lbi4g
-SU1QT1JUQU5UISBUaGUgaXNzdWFuY2UgYW5kIHRoZSB1c2Ugb2YgdGhpcyBjZXJ0
-aWZpY2F0ZSBpcyBzdWJqZWN0IHRvIHRoZSBOZXRMb2NrIENQUyBhdmFpbGFibGUg
-YXQgaHR0cHM6Ly93d3cubmV0bG9jay5uZXQvZG9jcyBvciBieSBlLW1haWwgYXQg
-Y3BzQG5ldGxvY2submV0LjANBgkqhkiG9w0BAQQFAAOBgQAQrX/XDDKACtiG8XmY
-ta3UzbM2xJZIwVzNmtkFLp++UOv0JhQQLdRmF/iewSf98e3ke0ugbLWrmldwpu2g
-pO0u9f38vf5NNwgMvOOWgyL1SRt/Syu0VMGAfJlOHdCM7tCs5ZL6dVb+ZKATj7i4
-Fp1hBWeAyNDYpQcCNJgEjTME1A==
------END CERTIFICATE-----
-
-# Issuer: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
-# Subject: CN=XRamp Global Certification Authority O=XRamp Security Services Inc OU=www.xrampsecurity.com
-# Label: "XRamp Global CA Root"
-# Serial: 107108908803651509692980124233745014957
-# MD5 Fingerprint: a1:0b:44:b3:ca:10:d8:00:6e:9d:0f:d8:0f:92:0a:d1
-# SHA1 Fingerprint: b8:01:86:d1:eb:9c:86:a5:41:04:cf:30:54:f3:4c:52:b7:e5:58:c6
-# SHA256 Fingerprint: ce:cd:dc:90:50:99:d8:da:df:c5:b1:d2:09:b7:37:cb:e2:c1:8c:fb:2c:10:c0:ff:0b:cf:0d:32:86:fc:1a:a2
------BEGIN CERTIFICATE-----
-MIIEMDCCAxigAwIBAgIQUJRs7Bjq1ZxN1ZfvdY+grTANBgkqhkiG9w0BAQUFADCB
-gjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3dy54cmFtcHNlY3VyaXR5LmNvbTEk
-MCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2VydmljZXMgSW5jMS0wKwYDVQQDEyRY
-UmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQxMTAxMTcx
-NDA0WhcNMzUwMTAxMDUzNzE5WjCBgjELMAkGA1UEBhMCVVMxHjAcBgNVBAsTFXd3
-dy54cmFtcHNlY3VyaXR5LmNvbTEkMCIGA1UEChMbWFJhbXAgU2VjdXJpdHkgU2Vy
-dmljZXMgSW5jMS0wKwYDVQQDEyRYUmFtcCBHbG9iYWwgQ2VydGlmaWNhdGlvbiBB
-dXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCYJB69FbS6
-38eMpSe2OAtp87ZOqCwuIR1cRN8hXX4jdP5efrRKt6atH67gBhbim1vZZ3RrXYCP
-KZ2GG9mcDZhtdhAoWORlsH9KmHmf4MMxfoArtYzAQDsRhtDLooY2YKTVMIJt2W7Q
-DxIEM5dfT2Fa8OT5kavnHTu86M/0ay00fOJIYRyO82FEzG+gSqmUsE3a56k0enI4
-qEHMPJQRfevIpoy3hsvKMzvZPTeL+3o+hiznc9cKV6xkmxnr9A8ECIqsAxcZZPRa
-JSKNNCyy9mgdEm3Tih4U2sSPpuIjhdV6Db1q4Ons7Be7QhtnqiXtRYMh/MHJfNVi
-PvryxS3T/dRlAgMBAAGjgZ8wgZwwEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0P
-BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMZPoj0GY4QJnM5i5ASs
-jVy16bYbMDYGA1UdHwQvMC0wK6ApoCeGJWh0dHA6Ly9jcmwueHJhbXBzZWN1cml0
-eS5jb20vWEdDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQEwDQYJKoZIhvcNAQEFBQAD
-ggEBAJEVOQMBG2f7Shz5CmBbodpNl2L5JFMn14JkTpAuw0kbK5rc/Kh4ZzXxHfAR
-vbdI4xD2Dd8/0sm2qlWkSLoC295ZLhVbO50WfUfXN+pfTXYSNrsf16GBBEYgoyxt
-qZ4Bfj8pzgCT3/3JknOJiWSe5yvkHJEs0rnOfc5vMZnT5r7SHpDwCRR5XCOrTdLa
-IR9NmXmd4c8nnxCbHIgNsIpkQTG4DmyQJKSbXHGPurt+HBvbaoAPIbzp26a3QPSy
-i6mx5O+aGtA9aZnuqCij4Tyz8LIRnM98QObd50N9otg6tamN8jSZxNQQ4Qb9CYQQ
-O+7ETPTsJ3xCwnR8gooJybQDJbw=
------END CERTIFICATE-----
-
-# Issuer: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
-# Subject: O=The Go Daddy Group, Inc. OU=Go Daddy Class 2 Certification Authority
-# Label: "Go Daddy Class 2 CA"
-# Serial: 0
-# MD5 Fingerprint: 91:de:06:25:ab:da:fd:32:17:0c:bb:25:17:2a:84:67
-# SHA1 Fingerprint: 27:96:ba:e6:3f:18:01:e2:77:26:1b:a0:d7:77:70:02:8f:20:ee:e4
-# SHA256 Fingerprint: c3:84:6b:f2:4b:9e:93:ca:64:27:4c:0e:c6:7c:1e:cc:5e:02:4f:fc:ac:d2:d7:40:19:35:0e:81:fe:54:6a:e4
------BEGIN CERTIFICATE-----
-MIIEADCCAuigAwIBAgIBADANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJVUzEh
-MB8GA1UEChMYVGhlIEdvIERhZGR5IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBE
-YWRkeSBDbGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA0MDYyOTE3
-MDYyMFoXDTM0MDYyOTE3MDYyMFowYzELMAkGA1UEBhMCVVMxITAfBgNVBAoTGFRo
-ZSBHbyBEYWRkeSBHcm91cCwgSW5jLjExMC8GA1UECxMoR28gRGFkZHkgQ2xhc3Mg
-MiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASAwDQYJKoZIhvcNAQEBBQADggEN
-ADCCAQgCggEBAN6d1+pXGEmhW+vXX0iG6r7d/+TvZxz0ZWizV3GgXne77ZtJ6XCA
-PVYYYwhv2vLM0D9/AlQiVBDYsoHUwHU9S3/Hd8M+eKsaA7Ugay9qK7HFiH7Eux6w
-wdhFJ2+qN1j3hybX2C32qRe3H3I2TqYXP2WYktsqbl2i/ojgC95/5Y0V4evLOtXi
-EqITLdiOr18SPaAIBQi2XKVlOARFmR6jYGB0xUGlcmIbYsUfb18aQr4CUWWoriMY
-avx4A6lNf4DD+qta/KFApMoZFv6yyO9ecw3ud72a9nmYvLEHZ6IVDd2gWMZEewo+
-YihfukEHU1jPEX44dMX4/7VpkI+EdOqXG68CAQOjgcAwgb0wHQYDVR0OBBYEFNLE
-sNKR1EwRcbNhyz2h/t2oatTjMIGNBgNVHSMEgYUwgYKAFNLEsNKR1EwRcbNhyz2h
-/t2oatTjoWekZTBjMQswCQYDVQQGEwJVUzEhMB8GA1UEChMYVGhlIEdvIERhZGR5
-IEdyb3VwLCBJbmMuMTEwLwYDVQQLEyhHbyBEYWRkeSBDbGFzcyAyIENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADJL87LKPpH8EsahB4yOd6AzBhRckB4Y9wimPQoZ+YeAEW5p5JYXMP80kWNy
-OO7MHAGjHZQopDH2esRU1/blMVgDoszOYtuURXO1v0XJJLXVggKtI3lpjbi2Tc7P
-TMozI+gciKqdi0FuFskg5YmezTvacPd+mSYgFFQlq25zheabIZ0KbIIOqPjCDPoQ
-HmyW74cNxA9hi63ugyuV+I6ShHI56yDqg+2DzZduCLzrTia2cyvk0/ZM/iZx4mER
-dEr/VxqHD3VILs9RaRegAhJhldXRQLIQTO7ErBBDpqWeCtWVYpoNz4iCxTIM5Cuf
-ReYNnyicsbkqWletNw+vHX/bvZ8=
------END CERTIFICATE-----
-
-# Issuer: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
-# Subject: O=Starfield Technologies, Inc. OU=Starfield Class 2 Certification Authority
-# Label: "Starfield Class 2 CA"
-# Serial: 0
-# MD5 Fingerprint: 32:4a:4b:bb:c8:63:69:9b:be:74:9a:c6:dd:1d:46:24
-# SHA1 Fingerprint: ad:7e:1c:28:b0:64:ef:8f:60:03:40:20:14:c3:d0:e3:37:0e:b5:8a
-# SHA256 Fingerprint: 14:65:fa:20:53:97:b8:76:fa:a6:f0:a9:95:8e:55:90:e4:0f:cc:7f:aa:4f:b7:c2:c8:67:75:21:fb:5f:b6:58
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl
-MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp
-U3RhcmZpZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDQw
-NjI5MTczOTE2WhcNMzQwNjI5MTczOTE2WjBoMQswCQYDVQQGEwJVUzElMCMGA1UE
-ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMpU3RhcmZp
-ZWxkIENsYXNzIDIgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEgMA0GCSqGSIb3
-DQEBAQUAA4IBDQAwggEIAoIBAQC3Msj+6XGmBIWtDBFk385N78gDGIc/oav7PKaf
-8MOh2tTYbitTkPskpD6E8J7oX+zlJ0T1KKY/e97gKvDIr1MvnsoFAZMej2YcOadN
-+lq2cwQlZut3f+dZxkqZJRRU6ybH838Z1TBwj6+wRir/resp7defqgSHo9T5iaU0
-X9tDkYI22WY8sbi5gv2cOj4QyDvvBmVmepsZGD3/cVE8MC5fvj13c7JdBmzDI1aa
-K4UmkhynArPkPw2vCHmCuDY96pzTNbO8acr1zJ3o/WSNF4Azbl5KXZnJHoe0nRrA
-1W4TNSNe35tfPe/W93bC6j67eA0cQmdrBNj41tpvi/JEoAGrAgEDo4HFMIHCMB0G
-A1UdDgQWBBS/X7fRzt0fhvRbVazc1xDCDqmI5zCBkgYDVR0jBIGKMIGHgBS/X7fR
-zt0fhvRbVazc1xDCDqmI56FspGowaDELMAkGA1UEBhMCVVMxJTAjBgNVBAoTHFN0
-YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAsTKVN0YXJmaWVsZCBD
-bGFzcyAyIENlcnRpZmljYXRpb24gQXV0aG9yaXR5ggEAMAwGA1UdEwQFMAMBAf8w
-DQYJKoZIhvcNAQEFBQADggEBAAWdP4id0ckaVaGsafPzWdqbAYcaT1epoXkJKtv3
-L7IezMdeatiDh6GX70k1PncGQVhiv45YuApnP+yz3SFmH8lU+nLMPUxA2IGvd56D
-eruix/U0F47ZEUD0/CwqTRV/p2JdLiXTAAsgGh1o+Re49L2L7ShZ3U0WixeDyLJl
-xy16paq8U4Zt3VekyvggQQto8PT7dL5WXXp59fkdheMtlb71cZBDzI0fmgAKhynp
-VSJYACPq4xJDKVtHCN2MQWplBqjlIapBtJUhlbl90TSrE9atvNziPTnNvT51cKEY
-WQPJIrSPnNVeKtelttQKbfi3QBFGmh95DmK/D5fs4C8fF5Q=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Label: "StartCom Certification Authority"
-# Serial: 1
-# MD5 Fingerprint: 22:4d:8f:8a:fc:f7:35:c2:bb:57:34:90:7b:8b:22:16
-# SHA1 Fingerprint: 3e:2b:f7:f2:03:1b:96:f3:8c:e6:c4:d8:a8:5d:3e:2d:58:47:6a:0f
-# SHA256 Fingerprint: c7:66:a9:be:f2:d4:07:1c:86:3a:31:aa:49:20:e8:13:b2:d1:98:60:8c:b7:b7:cf:e2:11:43:b8:36:df:09:ea
------BEGIN CERTIFICATE-----
-MIIHyTCCBbGgAwIBAgIBATANBgkqhkiG9w0BAQUFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM2WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICUjCCAk4wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAa4wHQYDVR0OBBYE
-FE4L7xqkQFulF2mHMMo0aEPQQa7yMGQGA1UdHwRdMFswLKAqoCiGJmh0dHA6Ly9j
-ZXJ0LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMCugKaAnhiVodHRwOi8vY3Js
-LnN0YXJ0Y29tLm9yZy9zZnNjYS1jcmwuY3JsMIIBXQYDVR0gBIIBVDCCAVAwggFM
-BgsrBgEEAYG1NwEBATCCATswLwYIKwYBBQUHAgEWI2h0dHA6Ly9jZXJ0LnN0YXJ0
-Y29tLm9yZy9wb2xpY3kucGRmMDUGCCsGAQUFBwIBFilodHRwOi8vY2VydC5zdGFy
-dGNvbS5vcmcvaW50ZXJtZWRpYXRlLnBkZjCB0AYIKwYBBQUHAgIwgcMwJxYgU3Rh
-cnQgQ29tbWVyY2lhbCAoU3RhcnRDb20pIEx0ZC4wAwIBARqBl0xpbWl0ZWQgTGlh
-YmlsaXR5LCByZWFkIHRoZSBzZWN0aW9uICpMZWdhbCBMaW1pdGF0aW9ucyogb2Yg
-dGhlIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFBvbGljeSBhdmFp
-bGFibGUgYXQgaHR0cDovL2NlcnQuc3RhcnRjb20ub3JnL3BvbGljeS5wZGYwEQYJ
-YIZIAYb4QgEBBAQDAgAHMDgGCWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNT
-TCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTANBgkqhkiG9w0BAQUFAAOCAgEAFmyZ
-9GYMNPXQhV59CuzaEE44HF7fpiUFS5Eyweg78T3dRAlbB0mKKctmArexmvclmAk8
-jhvh3TaHK0u7aNM5Zj2gJsfyOZEdUauCe37Vzlrk4gNXcGmXCPleWKYK34wGmkUW
-FjgKXlf2Ysd6AgXmvB618p70qSmD+LIU424oh0TDkBreOKk8rENNZEXO3SipXPJz
-ewT4F+irsfMuXGRuczE6Eri8sxHkfY+BUZo7jYn0TZNmezwD7dOaHZrzZVD1oNB1
-ny+v8OqCQ5j4aZyJecRDjkZy42Q2Eq/3JR44iZB3fsNrarnDy0RLrHiQi+fHLB5L
-EUTINFInzQpdn4XBidUaePKVEFMy3YCEZnXZtWgo+2EuvoSoOMCZEoalHmdkrQYu
-L6lwhceWD3yJZfWOQ1QOq92lgDmUYMA0yZZwLKMS9R9Ie70cfmu3nZD0Ijuu+Pwq
-yvqCUqDvr0tVk+vBtfAii6w0TiYiBKGHLHVKt+V9E9e4DGTANtLJL4YSjCMJwRuC
-O3NJo2pXh5Tl1njFmUNj403gdy3hZZlyaQQaRwnmDwFWJPsfvw55qVguucQJAX6V
-um0ABj6y6koQOdjQK/W/7HW/lwLFCRsI3FU34oH7N4RDYiDK51ZLZer+bMEkkySh
-NOsF/5oirpt9P/FlUQqmMGqz9IgcgA38corog14=
------END CERTIFICATE-----
-
-# Issuer: O=Government Root Certification Authority
-# Subject: O=Government Root Certification Authority
-# Label: "Taiwan GRCA"
-# Serial: 42023070807708724159991140556527066870
-# MD5 Fingerprint: 37:85:44:53:32:45:1f:20:f0:f3:95:e1:25:c4:43:4e
-# SHA1 Fingerprint: f4:8b:11:bf:de:ab:be:94:54:20:71:e6:41:de:6b:be:88:2b:40:b9
-# SHA256 Fingerprint: 76:00:29:5e:ef:e8:5b:9e:1f:d6:24:db:76:06:2a:aa:ae:59:81:8a:54:d2:77:4c:d4:c0:b2:c0:11:31:e1:b3
------BEGIN CERTIFICATE-----
-MIIFcjCCA1qgAwIBAgIQH51ZWtcvwgZEpYAIaeNe9jANBgkqhkiG9w0BAQUFADA/
-MQswCQYDVQQGEwJUVzEwMC4GA1UECgwnR292ZXJubWVudCBSb290IENlcnRpZmlj
-YXRpb24gQXV0aG9yaXR5MB4XDTAyMTIwNTEzMjMzM1oXDTMyMTIwNTEzMjMzM1ow
-PzELMAkGA1UEBhMCVFcxMDAuBgNVBAoMJ0dvdmVybm1lbnQgUm9vdCBDZXJ0aWZp
-Y2F0aW9uIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB
-AJoluOzMonWoe/fOW1mKydGGEghU7Jzy50b2iPN86aXfTEc2pBsBHH8eV4qNw8XR
-IePaJD9IK/ufLqGU5ywck9G/GwGHU5nOp/UKIXZ3/6m3xnOUT0b3EEk3+qhZSV1q
-gQdW8or5BtD3cCJNtLdBuTK4sfCxw5w/cP1T3YGq2GN49thTbqGsaoQkclSGxtKy
-yhwOeYHWtXBiCAEuTk8O1RGvqa/lmr/czIdtJuTJV6L7lvnM4T9TjGxMfptTCAts
-F/tnyMKtsc2AtJfcdgEWFelq16TheEfOhtX7MfP6Mb40qij7cEwdScevLJ1tZqa2
-jWR+tSBqnTuBto9AAGdLiYa4zGX+FVPpBMHWXx1E1wovJ5pGfaENda1UhhXcSTvx
-ls4Pm6Dso3pdvtUqdULle96ltqqvKKyskKw4t9VoNSZ63Pc78/1Fm9G7Q3hub/FC
-VGqY8A2tl+lSXunVanLeavcbYBT0peS2cWeqH+riTcFCQP5nRhc4L0c/cZyu5SHK
-YS1tB6iEfC3uUSXxY5Ce/eFXiGvviiNtsea9P63RPZYLhY3Naye7twWb7LuRqQoH
-EgKXTiCQ8P8NHuJBO9NAOueNXdpm5AKwB1KYXA6OM5zCppX7VRluTI6uSw+9wThN
-Xo+EHWbNxWCWtFJaBYmOlXqYwZE8lSOyDvR5tMl8wUohAgMBAAGjajBoMB0GA1Ud
-DgQWBBTMzO/MKWCkO7GStjz6MmKPrCUVOzAMBgNVHRMEBTADAQH/MDkGBGcqBwAE
-MTAvMC0CAQAwCQYFKw4DAhoFADAHBgVnKgMAAAQUA5vwIhP/lSg209yewDL7MTqK
-UWUwDQYJKoZIhvcNAQEFBQADggIBAECASvomyc5eMN1PhnR2WPWus4MzeKR6dBcZ
-TulStbngCnRiqmjKeKBMmo4sIy7VahIkv9Ro04rQ2JyftB8M3jh+Vzj8jeJPXgyf
-qzvS/3WXy6TjZwj/5cAWtUgBfen5Cv8b5Wppv3ghqMKnI6mGq3ZW6A4M9hPdKmaK
-ZEk9GhiHkASfQlK3T8v+R0F2Ne//AHY2RTKbxkaFXeIksB7jSJaYV0eUVXoPQbFE
-JPPB/hprv4j9wabak2BegUqZIJxIZhm1AHlUD7gsL0u8qV1bYH+Mh6XgUmMqvtg7
-hUAV/h62ZT/FS9p+tXo1KaMuephgIqP0fSdOLeq0dDzpD6QzDxARvBMB1uUO07+1
-EqLhRSPAzAhuYbeJq4PjJB7mXQfnHyA+z2fI56wwbSdLaG5LKlwCCDTb+HbkZ6Mm
-nD+iMsJKxYEYMRBWqoTvLQr/uB930r+lWKBi5NdLkXWNiYCYfm3LU05er/ayl4WX
-udpVBrkk7tfGOB5jGxI7leFYrPLfhNVfmS8NVVvmONsuP3LpSIXLuykTjx44Vbnz
-ssQwmSNOXfJIoRIM3BKQCZBUkQM8R+XVyWXgt0t97EfTsws+rZ7QdAAO671RrcDe
-LMDDav7v3Aun+kbfYNucpllQdSNpc5Oy+fwC00fmcc4QAu4njIT/rEUNE1yDMuAl
-pYYsfPQS
------END CERTIFICATE-----
-
-# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
-# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
-# Label: "Firmaprofesional Root CA"
-# Serial: 1
-# MD5 Fingerprint: 11:92:79:40:3c:b1:83:40:e5:ab:66:4a:67:92:80:df
-# SHA1 Fingerprint: a9:62:8f:4b:98:a9:1b:48:35:ba:d2:c1:46:32:86:bb:66:64:6a:8c
-# SHA256 Fingerprint: c1:cf:0b:52:09:64:35:e3:f1:b7:1d:aa:ec:45:5a:23:11:c8:40:4f:55:83:a9:e2:13:c6:9d:85:7d:94:33:05
------BEGIN CERTIFICATE-----
-MIIEVzCCAz+gAwIBAgIBATANBgkqhkiG9w0BAQUFADCBnTELMAkGA1UEBhMCRVMx
-IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1
-dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
-MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w
-HhcNMDExMDI0MjIwMDAwWhcNMTMxMDI0MjIwMDAwWjCBnTELMAkGA1UEBhMCRVMx
-IjAgBgNVBAcTGUMvIE11bnRhbmVyIDI0NCBCYXJjZWxvbmExQjBABgNVBAMTOUF1
-dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2
-MjYzNDA2ODEmMCQGCSqGSIb3DQEJARYXY2FAZmlybWFwcm9mZXNpb25hbC5jb20w
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDnIwNvbyOlXnjOlSztlB5u
-Cp4Bx+ow0Syd3Tfom5h5VtP8c9/Qit5Vj1H5WuretXDE7aTt/6MNbg9kUDGvASdY
-rv5sp0ovFy3Tc9UTHI9ZpTQsHVQERc1ouKDAA6XPhUJHlShbz++AbOCQl4oBPB3z
-hxAwJkh91/zpnZFx/0GaqUC1N5wpIE8fUuOgfRNtVLcK3ulqTgesrBlf3H5idPay
-BQC6haD9HThuy1q7hryUZzM1gywfI834yJFxzJeL764P3CkDG8A563DtwW4O2GcL
-iam8NeTvtjS0pbbELaW+0MOUJEjb35bTALVmGotmBQ/dPz/LP6pemkr4tErvlTcb
-AgMBAAGjgZ8wgZwwKgYDVR0RBCMwIYYfaHR0cDovL3d3dy5maXJtYXByb2Zlc2lv
-bmFsLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEBMCsGA1UdEAQkMCKADzIwMDExMDI0
-MjIwMDAwWoEPMjAxMzEwMjQyMjAwMDBaMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
-FgQUMwugZtHq2s7eYpMEKFK1FH84aLcwDQYJKoZIhvcNAQEFBQADggEBAEdz/o0n
-VPD11HecJ3lXV7cVVuzH2Fi3AQL0M+2TUIiefEaxvT8Ub/GzR0iLjJcG1+p+o1wq
-u00vR+L4OQbJnC4xGgN49Lw4xiKLMzHwFgQEffl25EvXwOaD7FnMP97/T2u3Z36m
-hoEyIwOdyPdfwUpgpZKpsaSgYMN4h7Mi8yrrW6ntBas3D7Hi05V2Y1Z0jFhyGzfl
-ZKG+TQyTmAyX9odtsz/ny4Cm7YjHX1BiAuiZdBbQ5rQ58SfLyEDW44YQqSMSkuBp
-QWOnryULwMWSyx6Yo1q6xTMPoJcB3X/ge9YGVM+h4k0460tQtcsm9MracEpqoeJ5
-quGnM/b9Sh/22WA=
------END CERTIFICATE-----
-
-# Issuer: CN=Wells Fargo Root Certificate Authority O=Wells Fargo OU=Wells Fargo Certification Authority
-# Subject: CN=Wells Fargo Root Certificate Authority O=Wells Fargo OU=Wells Fargo Certification Authority
-# Label: "Wells Fargo Root CA"
-# Serial: 971282334
-# MD5 Fingerprint: 20:0b:4a:7a:88:a7:a9:42:86:8a:5f:74:56:7b:88:05
-# SHA1 Fingerprint: 93:e6:ab:22:03:03:b5:23:28:dc:da:56:9e:ba:e4:d1:d1:cc:fb:65
-# SHA256 Fingerprint: 03:45:8b:6a:be:ec:c2:14:95:3d:97:14:9a:f4:53:91:69:1d:e9:f9:cd:cc:26:47:86:3a:3d:67:c9:5c:24:3b
------BEGIN CERTIFICATE-----
-MIID5TCCAs2gAwIBAgIEOeSXnjANBgkqhkiG9w0BAQUFADCBgjELMAkGA1UEBhMC
-VVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSwwKgYDVQQLEyNXZWxscyBGYXJnbyBD
-ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0GA1UEAxMmV2VsbHMgRmFyZ28gUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDAxMDExMTY0MTI4WhcNMjEwMTE0
-MTY0MTI4WjCBgjELMAkGA1UEBhMCVVMxFDASBgNVBAoTC1dlbGxzIEZhcmdvMSww
-KgYDVQQLEyNXZWxscyBGYXJnbyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEvMC0G
-A1UEAxMmV2VsbHMgRmFyZ28gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVqDM7Jvk0/82bfuUER84A4n13
-5zHCLielTWi5MbqNQ1mXx3Oqfz1cQJ4F5aHiidlMuD+b+Qy0yGIZLEWukR5zcUHE
-SxP9cMIlrCL1dQu3U+SlK93OvRw6esP3E48mVJwWa2uv+9iWsWCaSOAlIiR5NM4O
-JgALTqv9i86C1y8IcGjBqAr5dE8Hq6T54oN+J3N0Prj5OEL8pahbSCOz6+MlsoCu
-ltQKnMJ4msZoGK43YjdeUXWoWGPAUe5AeH6orxqg4bB4nVCMe+ez/I4jsNtlAHCE
-AQgAFG5Uhpq6zPk3EPbg3oQtnaSFN9OH4xXQwReQfhkhahKpdv0SAulPIV4XAgMB
-AAGjYTBfMA8GA1UdEwEB/wQFMAMBAf8wTAYDVR0gBEUwQzBBBgtghkgBhvt7hwcB
-CzAyMDAGCCsGAQUFBwIBFiRodHRwOi8vd3d3LndlbGxzZmFyZ28uY29tL2NlcnRw
-b2xpY3kwDQYJKoZIhvcNAQEFBQADggEBANIn3ZwKdyu7IvICtUpKkfnRLb7kuxpo
-7w6kAOnu5+/u9vnldKTC2FJYxHT7zmu1Oyl5GFrvm+0fazbuSCUlFLZWohDo7qd/
-0D+j0MNdJu4HzMPBJCGHHt8qElNvQRbn7a6U+oxy+hNH8Dx+rn0ROhPs7fpvcmR7
-nX1/Jv16+yWt6j4pf0zjAFcysLPp7VMX2YuyFA4w6OXVE8Zkr8QA1dhYJPz1j+zx
-x32l2w8n0cbyQIjmH/ZhqPRCyLk306m+LFZ4wnKbWV01QIroTmMatukgalHizqSQ
-33ZwmVxwQ023tqcZZE6St8WRPH9IFmV7Fv3L/PvZ1dZPIWU7Sn9Ho/s=
------END CERTIFICATE-----
-
-# Issuer: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
-# Subject: CN=Swisscom Root CA 1 O=Swisscom OU=Digital Certificate Services
-# Label: "Swisscom Root CA 1"
-# Serial: 122348795730808398873664200247279986742
-# MD5 Fingerprint: f8:38:7c:77:88:df:2c:16:68:2e:c2:e2:52:4b:b8:f9
-# SHA1 Fingerprint: 5f:3a:fc:0a:8b:64:f6:86:67:34:74:df:7e:a9:a2:fe:f9:fa:7a:51
-# SHA256 Fingerprint: 21:db:20:12:36:60:bb:2e:d4:18:20:5d:a1:1e:e7:a8:5a:65:e2:bc:6e:55:b5:af:7e:78:99:c8:a2:66:d9:2e
------BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQXAuFXAvnWUHfV8w/f52oNjANBgkqhkiG9w0BAQUFADBk
-MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
-Q0EgMTAeFw0wNTA4MTgxMjA2MjBaFw0yNTA4MTgyMjA2MjBaMGQxCzAJBgNVBAYT
-AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
-Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAxMIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0LmwqAzZuz8h+BvVM5OAFmUgdbI9
-m2BtRsiMMW8Xw/qabFbtPMWRV8PNq5ZJkCoZSx6jbVfd8StiKHVFXqrWW/oLJdih
-FvkcxC7mlSpnzNApbjyFNDhhSbEAn9Y6cV9Nbc5fuankiX9qUvrKm/LcqfmdmUc/
-TilftKaNXXsLmREDA/7n29uj/x2lzZAeAR81sH8A25Bvxn570e56eqeqDFdvpG3F
-EzuwpdntMhy0XmeLVNxzh+XTF3xmUHJd1BpYwdnP2IkCb6dJtDZd0KTeByy2dbco
-kdaXvij1mB7qWybJvbCXc9qukSbraMH5ORXWZ0sKbU/Lz7DkQnGMU3nn7uHbHaBu
-HYwadzVcFh4rUx80i9Fs/PJnB3r1re3WmquhsUvhzDdf/X/NTa64H5xD+SpYVUNF
-vJbNcA78yeNmuk6NO4HLFWR7uZToXTNShXEuT46iBhFRyePLoW4xCGQMwtI89Tbo
-19AOeCMgkckkKmUpWyL3Ic6DXqTz3kvTaI9GdVyDCW4pa8RwjPWd1yAv/0bSKzjC
-L3UcPX7ape8eYIVpQtPM+GP+HkM5haa2Y0EQs3MevNP6yn0WR+Kn1dCjigoIlmJW
-bjTb2QK5MHXjBNLnj8KwEUAKrNVxAmKLMb7dxiNYMUJDLXT5xp6mig/p/r+D5kNX
-JLrvRjSq1xIBOO0CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
-FDASBgdghXQBUwABBgdghXQBUwABMBIGA1UdEwEB/wQIMAYBAf8CAQcwHwYDVR0j
-BBgwFoAUAyUv3m+CATpcLNwroWm1Z9SM0/0wHQYDVR0OBBYEFAMlL95vggE6XCzc
-K6FptWfUjNP9MA0GCSqGSIb3DQEBBQUAA4ICAQA1EMvspgQNDQ/NwNurqPKIlwzf
-ky9NfEBWMXrrpA9gzXrzvsMnjgM+pN0S734edAY8PzHyHHuRMSG08NBsl9Tpl7Ik
-Vh5WwzW9iAUPWxAaZOHHgjD5Mq2eUCzneAXQMbFamIp1TpBcahQq4FJHgmDmHtqB
-sfsUC1rxn9KVuj7QG9YVHaO+htXbD8BJZLsuUBlL0iT43R4HVtA4oJVwIHaM190e
-3p9xxCPvgxNcoyQVTSlAPGrEqdi3pkSlDfTgnXceQHAm/NrZNuR55LU/vJtlvrsR
-ls/bxig5OgjOR1tTWsWZ/l2p3e9M1MalrQLmjAcSHm8D0W+go/MpvRLHUKKwf4ip
-mXeascClOS5cfGniLLDqN2qk4Vrh9VDlg++luyqI54zb/W1elxmofmZ1a3Hqv7HH
-b6D0jqTsNFFbjCYDcKF31QESVwA12yPeDooomf2xEG9L/zgtYE4snOtnta1J7ksf
-rK/7DZBaZmBwXarNeNQk7shBoJMBkpxqnvy5JMWzFYJ+vq6VK+uxwNrjAWALXmms
-hFZhvnEX/h0TD/7Gh0Xp/jKgGg0TpJRVcaUWi7rKibCyx/yP2FS1k2Kdzs9Z+z0Y
-zirLNRWCXf9UIltxUvu3yf5gmwBBZPCqKuy2QkPOiWaByIufOVQDJdMWNY6E0F/6
-MBr1mmz0DlP5OlvRHA==
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Assured ID Root CA O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Assured ID Root CA"
-# Serial: 17154717934120587862167794914071425081
-# MD5 Fingerprint: 87:ce:0b:7b:2a:0e:49:00:e1:58:71:9b:37:a8:93:72
-# SHA1 Fingerprint: 05:63:b8:63:0d:62:d7:5a:bb:c8:ab:1e:4b:df:b5:a8:99:b2:4d:43
-# SHA256 Fingerprint: 3e:90:99:b5:01:5e:8f:48:6c:00:bc:ea:9d:11:1e:e7:21:fa:ba:35:5a:89:bc:f1:df:69:56:1e:3d:c6:32:5c
------BEGIN CERTIFICATE-----
-MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBl
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJv
-b3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQswCQYDVQQG
-EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
-cnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwggEi
-MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7c
-JpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYP
-mDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+
-wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4
-VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1roV9Iq4/
-AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whfGHdPAgMB
-AAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQW
-BBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYun
-pyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRC
-dWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTf
-fwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+fT8r87cm
-NW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5QZ7dsvfPx
-H2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe
-+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g==
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert Global Root CA O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert Global Root CA"
-# Serial: 10944719598952040374951832963794454346
-# MD5 Fingerprint: 79:e4:a9:84:0d:7d:3a:96:d7:c0:4f:e2:43:4c:89:2e
-# SHA1 Fingerprint: a8:98:5d:3a:65:e5:e5:c4:b2:d7:d6:6d:40:c6:dd:2f:b1:9c:54:36
-# SHA256 Fingerprint: 43:48:a0:e9:44:4c:78:cb:26:5e:05:8d:5e:89:44:b4:d8:4f:96:62:bd:26:db:25:7f:89:34:a4:43:c7:01:61
------BEGIN CERTIFICATE-----
-MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
-QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
-MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
-b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
-9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
-CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
-nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
-43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
-T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
-gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
-BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
-TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
-DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
-hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
-06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
-PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
-YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
-CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
------END CERTIFICATE-----
-
-# Issuer: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
-# Subject: CN=DigiCert High Assurance EV Root CA O=DigiCert Inc OU=www.digicert.com
-# Label: "DigiCert High Assurance EV Root CA"
-# Serial: 3553400076410547919724730734378100087
-# MD5 Fingerprint: d4:74:de:57:5c:39:b2:d3:9c:85:83:c5:c0:65:49:8a
-# SHA1 Fingerprint: 5f:b7:ee:06:33:e2:59:db:ad:0c:4c:9a:e6:d3:8f:1a:61:c7:dc:25
-# SHA256 Fingerprint: 74:31:e5:f4:c3:c1:ce:46:90:77:4f:0b:61:e0:54:40:88:3b:a9:a0:1e:d0:0b:a6:ab:d7:80:6e:d3:b1:18:cf
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs
-MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
-d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j
-ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3
-LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug
-RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm
-+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW
-PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM
-xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB
-Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3
-hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg
-EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA
-FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec
-nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z
-eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF
-hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2
-Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe
-vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep
-+OkuE6N36B9K
------END CERTIFICATE-----
-
-# Issuer: CN=Class 2 Primary CA O=Certplus
-# Subject: CN=Class 2 Primary CA O=Certplus
-# Label: "Certplus Class 2 Primary CA"
-# Serial: 177770208045934040241468760488327595043
-# MD5 Fingerprint: 88:2c:8c:52:b8:a2:3c:f3:f7:bb:03:ea:ae:ac:42:0b
-# SHA1 Fingerprint: 74:20:74:41:72:9c:dd:92:ec:79:31:d8:23:10:8d:c2:81:92:e2:bb
-# SHA256 Fingerprint: 0f:99:3c:8a:ef:97:ba:af:56:87:14:0e:d5:9a:d1:82:1b:b4:af:ac:f0:aa:9a:58:b5:d5:7a:33:8a:3a:fb:cb
------BEGIN CERTIFICATE-----
-MIIDkjCCAnqgAwIBAgIRAIW9S/PY2uNp9pTXX8OlRCMwDQYJKoZIhvcNAQEFBQAw
-PTELMAkGA1UEBhMCRlIxETAPBgNVBAoTCENlcnRwbHVzMRswGQYDVQQDExJDbGFz
-cyAyIFByaW1hcnkgQ0EwHhcNOTkwNzA3MTcwNTAwWhcNMTkwNzA2MjM1OTU5WjA9
-MQswCQYDVQQGEwJGUjERMA8GA1UEChMIQ2VydHBsdXMxGzAZBgNVBAMTEkNsYXNz
-IDIgUHJpbWFyeSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANxQ
-ltAS+DXSCHh6tlJw/W/uz7kRy1134ezpfgSN1sxvc0NXYKwzCkTsA18cgCSR5aiR
-VhKC9+Ar9NuuYS6JEI1rbLqzAr3VNsVINyPi8Fo3UjMXEuLRYE2+L0ER4/YXJQyL
-kcAbmXuZVg2v7tK8R1fjeUl7NIknJITesezpWE7+Tt9avkGtrAjFGA7v0lPubNCd
-EgETjdyAYveVqUSISnFOYFWe2yMZeVYHDD9jC1yw4r5+FfyUM1hBOHTE4Y+L3yas
-H7WLO7dDWWuwJKZtkIvEcupdM5i3y95ee++U8Rs+yskhwcWYAqqi9lt3m/V+llU0
-HGdpwPFC40es/CgcZlUCAwEAAaOBjDCBiTAPBgNVHRMECDAGAQH/AgEKMAsGA1Ud
-DwQEAwIBBjAdBgNVHQ4EFgQU43Mt38sOKAze3bOkynm4jrvoMIkwEQYJYIZIAYb4
-QgEBBAQDAgEGMDcGA1UdHwQwMC4wLKAqoCiGJmh0dHA6Ly93d3cuY2VydHBsdXMu
-Y29tL0NSTC9jbGFzczIuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQCnVM+IRBnL39R/
-AN9WM2K191EBkOvDP9GIROkkXe/nFL0gt5o8AP5tn9uQ3Nf0YtaLcF3n5QRIqWh8
-yfFC82x/xXp8HVGIutIKPidd3i1RTtMTZGnkLuPT55sJmabglZvOGtd/vjzOUrMR
-FcEPF80Du5wlFbqidon8BvEY0JNLDnyCt6X09l/+7UCmnYR0ObncHoUW2ikbhiMA
-ybuJfm6AiB4vFLQDJKgybwOaRywwvlbGp0ICcBvqQNi6BQNwB6SW//1IMwrh3KWB
-kJtN3X3n57LNXMhqlfil9o3EXXgIvnsG1knPGTZQIy4I5p4FTUcY1Rbpsda2ENW7
-l7+ijrRU
------END CERTIFICATE-----
-
-# Issuer: CN=DST Root CA X3 O=Digital Signature Trust Co.
-# Subject: CN=DST Root CA X3 O=Digital Signature Trust Co.
-# Label: "DST Root CA X3"
-# Serial: 91299735575339953335919266965803778155
-# MD5 Fingerprint: 41:03:52:dc:0f:f7:50:1b:16:f0:02:8e:ba:6f:45:c5
-# SHA1 Fingerprint: da:c9:02:4f:54:d8:f6:df:94:93:5f:b1:73:26:38:ca:6a:d7:7c:13
-# SHA256 Fingerprint: 06:87:26:03:31:a7:24:03:d9:09:f1:05:e6:9b:cf:0d:32:e1:bd:24:93:ff:c6:d9:20:6d:11:bc:d6:77:07:39
------BEGIN CERTIFICATE-----
-MIIDSjCCAjKgAwIBAgIQRK+wgNajJ7qJMDmGLvhAazANBgkqhkiG9w0BAQUFADA/
-MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT
-DkRTVCBSb290IENBIFgzMB4XDTAwMDkzMDIxMTIxOVoXDTIxMDkzMDE0MDExNVow
-PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD
-Ew5EU1QgUm9vdCBDQSBYMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AN+v6ZdQCINXtMxiZfaQguzH0yxrMMpb7NnDfcdAwRgUi+DoM3ZJKuM/IUmTrE4O
-rz5Iy2Xu/NMhD2XSKtkyj4zl93ewEnu1lcCJo6m67XMuegwGMoOifooUMM0RoOEq
-OLl5CjH9UL2AZd+3UWODyOKIYepLYYHsUmu5ouJLGiifSKOeDNoJjj4XLh7dIN9b
-xiqKqy69cK3FCxolkHRyxXtqqzTWMIn/5WgTe1QLyNau7Fqckh49ZLOMxt+/yUFw
-7BZy1SbsOFU5Q9D8/RhcQPGX69Wam40dutolucbY38EVAjqr2m7xPi71XAicPNaD
-aeQQmxkqtilX4+U9m5/wAl0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFMSnsaR7LHH62+FLkHX/xBVghYkQMA0GCSqG
-SIb3DQEBBQUAA4IBAQCjGiybFwBcqR7uKGY3Or+Dxz9LwwmglSBd49lZRNI+DT69
-ikugdB/OEIKcdBodfpga3csTS7MgROSR6cz8faXbauX+5v3gTt23ADq1cEmv8uXr
-AvHRAosZy5Q6XkjEGB5YGV8eAlrwDPGxrancWYaLbumR9YbK+rlmM6pZW87ipxZz
-R8srzJmwN0jP41ZL9c8PDHIyh8bwRLtTcm1D9SZImlJnt1ir/md2cXjbDaJWFBM5
-JDGFoqgCWjBH4d1QB7wCCZAA62RjYJsWvIjJEubSfZGL+T0yjWW06XyxV3bqxbYo
-Ob8VZRzI9neWagqNdwvYkQsEjgfbKbYK7p2CNTUQ
------END CERTIFICATE-----
-
-# Issuer: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
-# Subject: CN=DST ACES CA X6 O=Digital Signature Trust OU=DST ACES
-# Label: "DST ACES CA X6"
-# Serial: 17771143917277623872238992636097467865
-# MD5 Fingerprint: 21:d8:4c:82:2b:99:09:33:a2:eb:14:24:8d:8e:5f:e8
-# SHA1 Fingerprint: 40:54:da:6f:1c:3f:40:74:ac:ed:0f:ec:cd:db:79:d1:53:fb:90:1d
-# SHA256 Fingerprint: 76:7c:95:5a:76:41:2c:89:af:68:8e:90:a1:c7:0f:55:6c:fd:6b:60:25:db:ea:10:41:6d:7e:b6:83:1f:8c:40
------BEGIN CERTIFICATE-----
-MIIECTCCAvGgAwIBAgIQDV6ZCtadt3js2AdWO4YV2TANBgkqhkiG9w0BAQUFADBb
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3Qx
-ETAPBgNVBAsTCERTVCBBQ0VTMRcwFQYDVQQDEw5EU1QgQUNFUyBDQSBYNjAeFw0w
-MzExMjAyMTE5NThaFw0xNzExMjAyMTE5NThaMFsxCzAJBgNVBAYTAlVTMSAwHgYD
-VQQKExdEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdDERMA8GA1UECxMIRFNUIEFDRVMx
-FzAVBgNVBAMTDkRTVCBBQ0VTIENBIFg2MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAuT31LMmU3HWKlV1j6IR3dma5WZFcRt2SPp/5DgO0PWGSvSMmtWPu
-ktKe1jzIDZBfZIGxqAgNTNj50wUoUrQBJcWVHAx+PhCEdc/BGZFjz+iokYi5Q1K7
-gLFViYsx+tC3dr5BPTCapCIlF3PoHuLTrCq9Wzgh1SpL11V94zpVvddtawJXa+ZH
-fAjIgrrep4c9oW24MFbCswKBXy314powGCi4ZtPLAZZv6opFVdbgnf9nKxcCpk4a
-ahELfrd755jWjHZvwTvbUJN+5dCOHze4vbrGn2zpfDPyMjwmR/onJALJfh1biEIT
-ajV8fTXpLmaRcpPVMibEdPVTo7NdmvYJywIDAQABo4HIMIHFMA8GA1UdEwEB/wQF
-MAMBAf8wDgYDVR0PAQH/BAQDAgHGMB8GA1UdEQQYMBaBFHBraS1vcHNAdHJ1c3Rk
-c3QuY29tMGIGA1UdIARbMFkwVwYKYIZIAWUDAgEBATBJMEcGCCsGAQUFBwIBFjto
-dHRwOi8vd3d3LnRydXN0ZHN0LmNvbS9jZXJ0aWZpY2F0ZXMvcG9saWN5L0FDRVMt
-aW5kZXguaHRtbDAdBgNVHQ4EFgQUCXIGThhDD+XWzMNqizF7eI+og7gwDQYJKoZI
-hvcNAQEFBQADggEBAKPYjtay284F5zLNAdMEA+V25FYrnJmQ6AgwbN99Pe7lv7Uk
-QIRJ4dEorsTCOlMwiPH1d25Ryvr/ma8kXxug/fKshMrfqfBfBC6tFr8hlxCBPeP/
-h40y3JTlR4peahPJlJU90u7INJXQgNStMgiAVDzgvVJT11J8smk/f3rPanTK+gQq
-nExaBqXpIK1FZg9p8d2/6eMyi/rgwYZNcjwu2JN4Cir42NInPRmJX1p7ijvMDNpR
-rscL9yuwNwXsvFcj4jjSm2jzVhKIT0J8uDHEtdvkyCE06UgRNe76x5JXxZ805Mf2
-9w4LTJxoeHtxMcfrHuBnQfO3oKfN5XozNmr6mis=
------END CERTIFICATE-----
-
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=(c) 2005 TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş.
-# Label: "TURKTRUST Certificate Services Provider Root 1"
-# Serial: 1
-# MD5 Fingerprint: f1:6a:22:18:c9:cd:df:ce:82:1d:1d:b7:78:5c:a9:a5
-# SHA1 Fingerprint: 79:98:a3:08:e1:4d:65:85:e6:c2:1e:15:3a:71:9f:ba:5a:d3:4a:d9
-# SHA256 Fingerprint: 44:04:e3:3b:5e:14:0d:cf:99:80:51:fd:fc:80:28:c7:c8:16:15:c5:ee:73:7b:11:1b:58:82:33:a9:b5:35:a0
------BEGIN CERTIFICATE-----
-MIID+zCCAuOgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBtzE/MD0GA1UEAww2VMOc
-UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMQswCQYDVQQGDAJUUjEPMA0GA1UEBwwGQU5LQVJBMVYwVAYDVQQKDE0oYykg
-MjAwNSBUw5xSS1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8
-dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWeLjAeFw0wNTA1MTMxMDI3MTdaFw0xNTAz
-MjIxMDI3MTdaMIG3MT8wPQYDVQQDDDZUw5xSS1RSVVNUIEVsZWt0cm9uaWsgU2Vy
-dGlmaWthIEhpem1ldCBTYcSfbGF5xLFjxLFzxLExCzAJBgNVBAYMAlRSMQ8wDQYD
-VQQHDAZBTktBUkExVjBUBgNVBAoMTShjKSAyMDA1IFTDnFJLVFJVU1QgQmlsZ2kg
-xLBsZXRpxZ9pbSB2ZSBCaWxpxZ9pbSBHw7x2ZW5sacSfaSBIaXptZXRsZXJpIEEu
-xZ4uMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAylIF1mMD2Bxf3dJ7
-XfIMYGFbazt0K3gNfUW9InTojAPBxhEqPZW8qZSwu5GXyGl8hMW0kWxsE2qkVa2k
-heiVfrMArwDCBRj1cJ02i67L5BuBf5OI+2pVu32Fks66WJ/bMsW9Xe8iSi9BB35J
-YbOG7E6mQW6EvAPs9TscyB/C7qju6hJKjRTP8wrgUDn5CDX4EVmt5yLqS8oUBt5C
-urKZ8y1UiBAG6uEaPj1nH/vO+3yC6BFdSsG5FOpU2WabfIl9BJpiyelSPJ6c79L1
-JuTm5Rh8i27fbMx4W09ysstcP4wFjdFMjK2Sx+F4f2VsSQZQLJ4ywtdKxnWKWU51
-b0dewQIDAQABoxAwDjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQAV
-9VX/N5aAWSGk/KEVTCD21F/aAyT8z5Aa9CEKmu46sWrv7/hg0Uw2ZkUd82YCdAR7
-kjCo3gp2D++Vbr3JN+YaDayJSFvMgzbC9UZcWYJWtNX+I7TYVBxEq8Sn5RTOPEFh
-fEPmzcSBCYsk+1Ql1haolgxnB2+zUEfjHCQo3SqYpGH+2+oSN7wBGjSFvW5P55Fy
-B0SFHljKVETd96y5y4khctuPwGkplyqjrhgjlxxBKot8KsF8kOipKMDTkcatKIdA
-aLX/7KfS0zgYnNN9aV3wxqUeJBujR/xpB2jn5Jq07Q+hh4cCzofSSE7hvP/L8XKS
-RGQDJereW26fyfJOrN3H
------END CERTIFICATE-----
-
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Kasım 2005
-# Label: "TURKTRUST Certificate Services Provider Root 2"
-# Serial: 1
-# MD5 Fingerprint: 37:a5:6e:d4:b1:25:84:97:b7:fd:56:15:7a:f9:a2:00
-# SHA1 Fingerprint: b4:35:d4:e1:11:9d:1c:66:90:a7:49:eb:b3:94:bd:63:7b:a7:82:b7
-# SHA256 Fingerprint: c4:70:cf:54:7e:23:02:b9:77:fb:29:dd:71:a8:9a:7b:6c:1f:60:77:7b:03:29:f5:60:17:f3:28:bf:4f:6b:e6
------BEGIN CERTIFICATE-----
-MIIEPDCCAySgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvjE/MD0GA1UEAww2VMOc
-UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xS
-S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
-SGl6bWV0bGVyaSBBLsWeLiAoYykgS2FzxLFtIDIwMDUwHhcNMDUxMTA3MTAwNzU3
-WhcNMTUwOTE2MTAwNzU3WjCBvjE/MD0GA1UEAww2VMOcUktUUlVTVCBFbGVrdHJv
-bmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxMQswCQYDVQQGEwJU
-UjEPMA0GA1UEBwwGQW5rYXJhMV0wWwYDVQQKDFRUw5xSS1RSVVNUIEJpbGdpIMSw
-bGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kgSGl6bWV0bGVyaSBBLsWe
-LiAoYykgS2FzxLFtIDIwMDUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCpNn7DkUNMwxmYCMjHWHtPFoylzkkBH3MOrHUTpvqeLCDe2JAOCtFp0if7qnef
-J1Il4std2NiDUBd9irWCPwSOtNXwSadktx4uXyCcUHVPr+G1QRT0mJKIx+XlZEdh
-R3n9wFHxwZnn3M5q+6+1ATDcRhzviuyV79z/rxAc653YsKpqhRgNF8k+v/Gb0AmJ
-Qv2gQrSdiVFVKc8bcLyEVK3BEx+Y9C52YItdP5qtygy/p1Zbj3e41Z55SZI/4PGX
-JHpsmxcPbe9TmJEr5A++WXkHeLuXlfSfadRYhwqp48y2WBmfJiGxxFmNskF1wK1p
-zpwACPI2/z7woQ8arBT9pmAPAgMBAAGjQzBBMB0GA1UdDgQWBBTZN7NOBf3Zz58S
-Fq62iS/rJTqIHDAPBgNVHQ8BAf8EBQMDBwYAMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
-KoZIhvcNAQEFBQADggEBAHJglrfJ3NgpXiOFX7KzLXb7iNcX/nttRbj2hWyfIvwq
-ECLsqrkw9qtY1jkQMZkpAL2JZkH7dN6RwRgLn7Vhy506vvWolKMiVW4XSf/SKfE4
-Jl3vpao6+XF75tpYHdN0wgH6PmlYX63LaL4ULptswLbcoCb6dxriJNoaN+BnrdFz
-gw2lGh1uEpJ+hGIAF728JRhX8tepb1mIvDS3LoV4nZbcFMMsilKbloxSZj2GFotH
-uFEJjOp9zYhys2AzsfAKRO8P9Qk3iCQOLGsgOqL6EfJANZxEaGM7rDNvY7wsu/LS
-y3Z9fYjYHcgFHW68lKlmjHdxx/qR+i9Rnuk5UrbnBEI=
------END CERTIFICATE-----
-
-# Issuer: CN=SwissSign Gold CA - G2 O=SwissSign AG
-# Subject: CN=SwissSign Gold CA - G2 O=SwissSign AG
-# Label: "SwissSign Gold CA - G2"
-# Serial: 13492815561806991280
-# MD5 Fingerprint: 24:77:d9:a8:91:d1:3b:fa:88:2d:c2:ff:f8:cd:33:93
-# SHA1 Fingerprint: d8:c5:38:8a:b7:30:1b:1b:6e:d4:7a:e6:45:25:3a:6f:9f:1a:27:61
-# SHA256 Fingerprint: 62:dd:0b:e9:b9:f5:0a:16:3e:a0:f8:e7:5c:05:3b:1e:ca:57:ea:55:c8:68:8f:64:7c:68:81:f2:c8:35:7b:95
------BEGIN CERTIFICATE-----
-MIIFujCCA6KgAwIBAgIJALtAHEP1Xk+wMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
-BAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxHzAdBgNVBAMTFlN3aXNzU2ln
-biBHb2xkIENBIC0gRzIwHhcNMDYxMDI1MDgzMDM1WhcNMzYxMDI1MDgzMDM1WjBF
-MQswCQYDVQQGEwJDSDEVMBMGA1UEChMMU3dpc3NTaWduIEFHMR8wHQYDVQQDExZT
-d2lzc1NpZ24gR29sZCBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
-CgKCAgEAr+TufoskDhJuqVAtFkQ7kpJcyrhdhJJCEyq8ZVeCQD5XJM1QiyUqt2/8
-76LQwB8CJEoTlo8jE+YoWACjR8cGp4QjK7u9lit/VcyLwVcfDmJlD909Vopz2q5+
-bbqBHH5CjCA12UNNhPqE21Is8w4ndwtrvxEvcnifLtg+5hg3Wipy+dpikJKVyh+c
-6bM8K8vzARO/Ws/BtQpgvd21mWRTuKCWs2/iJneRjOBiEAKfNA+k1ZIzUd6+jbqE
-emA8atufK+ze3gE/bk3lUIbLtK/tREDFylqM2tIrfKjuvqblCqoOpd8FUrdVxyJd
-MmqXl2MT28nbeTZ7hTpKxVKJ+STnnXepgv9VHKVxaSvRAiTysybUa9oEVeXBCsdt
-MDeQKuSeFDNeFhdVxVu1yzSJkvGdJo+hB9TGsnhQ2wwMC3wLjEHXuendjIj3o02y
-MszYF9rNt85mndT9Xv+9lz4pded+p2JYryU0pUHHPbwNUMoDAw8IWh+Vc3hiv69y
-FGkOpeUDDniOJihC8AcLYiAQZzlG+qkDzAQ4embvIIO1jEpWjpEA/I5cgt6IoMPi
-aG59je883WX0XaxR7ySArqpWl2/5rX3aYT+YdzylkbYcjCbaZaIJbcHiVOO5ykxM
-gI93e2CaHt+28kgeDrpOVG2Y4OGiGqJ3UM/EY5LsRxmd6+ZrzsECAwEAAaOBrDCB
-qTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWyV7
-lqRlUX64OfPAeGZe6Drn8O4wHwYDVR0jBBgwFoAUWyV7lqRlUX64OfPAeGZe6Drn
-8O4wRgYDVR0gBD8wPTA7BglghXQBWQECAQEwLjAsBggrBgEFBQcCARYgaHR0cDov
-L3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIBACe6
-45R88a7A3hfm5djV9VSwg/S7zV4Fe0+fdWavPOhWfvxyeDgD2StiGwC5+OlgzczO
-UYrHUDFu4Up+GC9pWbY9ZIEr44OE5iKHjn3g7gKZYbge9LgriBIWhMIxkziWMaa5
-O1M/wySTVltpkuzFwbs4AOPsF6m43Md8AYOfMke6UiI0HTJ6CVanfCU2qT1L2sCC
-bwq7EsiHSycR+R4tx5M/nttfJmtS2S6K8RTGRI0Vqbe/vd6mGu6uLftIdxf+u+yv
-GPUqUfA5hJeVbG4bwyvEdGB5JbAKJ9/fXtI5z0V9QkvfsywexcZdylU6oJxpmo/a
-77KwPJ+HbBIrZXAVUjEaJM9vMSNQH4xPjyPDdEFjHFWoFN0+4FFQz/EbMFYOkrCC
-hdiDyyJkvC24JdVUorgG6q2SpCSgwYa1ShNqR88uC1aVVMvOmttqtKay20EIhid3
-92qgQmwLOM7XdVAyksLfKzAiSNDVQTglXaTpXZ/GlHXQRf0wl0OPkKsKx4ZzYEpp
-Ld6leNcG2mqeSz53OiATIgHQv2ieY2BrNU0LbbqhPcCT4H8js1WtciVORvnSFu+w
-ZMEBnunKoGqYDs/YYPIvSbjkQuE4NRb0yG5P94FW6LqjviOvrv1vA+ACOzB2+htt
-Qc8Bsem4yWb02ybzOqR08kkkW8mw0FfB+j564ZfJ
------END CERTIFICATE-----
-
-# Issuer: CN=SwissSign Silver CA - G2 O=SwissSign AG
-# Subject: CN=SwissSign Silver CA - G2 O=SwissSign AG
-# Label: "SwissSign Silver CA - G2"
-# Serial: 5700383053117599563
-# MD5 Fingerprint: e0:06:a1:c9:7d:cf:c9:fc:0d:c0:56:75:96:d8:62:13
-# SHA1 Fingerprint: 9b:aa:e5:9f:56:ee:21:cb:43:5a:be:25:93:df:a7:f0:40:d1:1d:cb
-# SHA256 Fingerprint: be:6c:4d:a2:bb:b9:ba:59:b6:f3:93:97:68:37:42:46:c3:c0:05:99:3f:a9:8f:02:0d:1d:ed:be:d4:8a:81:d5
------BEGIN CERTIFICATE-----
-MIIFvTCCA6WgAwIBAgIITxvUL1S7L0swDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UE
-BhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMYU3dpc3NTaWdu
-IFNpbHZlciBDQSAtIEcyMB4XDTA2MTAyNTA4MzI0NloXDTM2MTAyNTA4MzI0Nlow
-RzELMAkGA1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzEhMB8GA1UEAxMY
-U3dpc3NTaWduIFNpbHZlciBDQSAtIEcyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
-MIICCgKCAgEAxPGHf9N4Mfc4yfjDmUO8x/e8N+dOcbpLj6VzHVxumK4DV644N0Mv
-Fz0fyM5oEMF4rhkDKxD6LHmD9ui5aLlV8gREpzn5/ASLHvGiTSf5YXu6t+WiE7br
-YT7QbNHm+/pe7R20nqA1W6GSy/BJkv6FCgU+5tkL4k+73JU3/JHpMjUi0R86TieF
-nbAVlDLaYQ1HTWBCrpJH6INaUFjpiou5XaHc3ZlKHzZnu0jkg7Y360g6rw9njxcH
-6ATK72oxh9TAtvmUcXtnZLi2kUpCe2UuMGoM9ZDulebyzYLs2aFK7PayS+VFheZt
-eJMELpyCbTapxDFkH4aDCyr0NQp4yVXPQbBH6TCfmb5hqAaEuSh6XzjZG6k4sIN/
-c8HDO0gqgg8hm7jMqDXDhBuDsz6+pJVpATqJAHgE2cn0mRmrVn5bi4Y5FZGkECwJ
-MoBgs5PAKrYYC51+jUnyEEp/+dVGLxmSo5mnJqy7jDzmDrxHB9xzUfFwZC8I+bRH
-HTBsROopN4WSaGa8gzj+ezku01DwH/teYLappvonQfGbGHLy9YR0SslnxFSuSGTf
-jNFusB3hB48IHpmccelM2KX3RxIfdNFRnobzwqIjQAtz20um53MGjMGg6cFZrEb6
-5i/4z3GcRm25xBWNOHkDRUjvxF3XCO6HOSKGsg0PWEP3calILv3q1h8CAwEAAaOB
-rDCBqTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU
-F6DNweRBtjpbO8tFnb0cwpj6hlgwHwYDVR0jBBgwFoAUF6DNweRBtjpbO8tFnb0c
-wpj6hlgwRgYDVR0gBD8wPTA7BglghXQBWQEDAQEwLjAsBggrBgEFBQcCARYgaHR0
-cDovL3JlcG9zaXRvcnkuc3dpc3NzaWduLmNvbS8wDQYJKoZIhvcNAQEFBQADggIB
-AHPGgeAn0i0P4JUw4ppBf1AsX19iYamGamkYDHRJ1l2E6kFSGG9YrVBWIGrGvShp
-WJHckRE1qTodvBqlYJ7YH39FkWnZfrt4csEGDyrOj4VwYaygzQu4OSlWhDJOhrs9
-xCrZ1x9y7v5RoSJBsXECYxqCsGKrXlcSH9/L3XWgwF15kIwb4FDm3jH+mHtwX6WQ
-2K34ArZv02DdQEsixT2tOnqfGhpHkXkzuoLcMmkDlm4fS/Bx/uNncqCxv1yL5PqZ
-IseEuRuNI5c/7SXgz2W79WEE790eslpBIlqhn10s6FvJbakMDHiqYMZWjwFaDGi8
-aRl5xB9+lwW/xekkUV7U1UtT7dkjWjYDZaPBA61BMPNGG4WQr2W11bHkFlt4dR2X
-em1ZqSqPe97Dh4kQmUlzeMg9vVE1dCrV8X5pGyq7O70luJpaPXJhkGaH7gzWTdQR
-dAtq/gsD/KNVV4n+SsuuWxcFyPKNIzFTONItaj+CuY0IavdeQXRuwxF+B6wpYJE/
-OMpXEA29MC/HpeZBoNquBYeaoKRlbEwJDIm6uNO5wJOKMPqN5ZprFQFOZ6raYlY+
-hAhm0sQ2fac+EPyI4NSA5QC9qvNOBqN6avlicuMJT+ubDgEj8Z+7fNzcbBGXJbLy
-tGMU0gYqZ4yD9c7qB9iaah7s5Aq7KkzrCWA5zspi2C5u
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
-# Subject: CN=GeoTrust Primary Certification Authority O=GeoTrust Inc.
-# Label: "GeoTrust Primary Certification Authority"
-# Serial: 32798226551256963324313806436981982369
-# MD5 Fingerprint: 02:26:c3:01:5e:08:30:37:43:a9:d0:7d:cf:37:e6:bf
-# SHA1 Fingerprint: 32:3c:11:8e:1b:f7:b8:b6:52:54:e2:e2:10:0d:d6:02:90:37:f0:96
-# SHA256 Fingerprint: 37:d5:10:06:c5:12:ea:ab:62:64:21:f1:ec:8c:92:01:3f:c5:f8:2a:e9:8e:e5:33:eb:46:19:b8:de:b4:d0:6c
------BEGIN CERTIFICATE-----
-MIIDfDCCAmSgAwIBAgIQGKy1av1pthU6Y2yv2vrEoTANBgkqhkiG9w0BAQUFADBY
-MQswCQYDVQQGEwJVUzEWMBQGA1UEChMNR2VvVHJ1c3QgSW5jLjExMC8GA1UEAxMo
-R2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEx
-MjcwMDAwMDBaFw0zNjA3MTYyMzU5NTlaMFgxCzAJBgNVBAYTAlVTMRYwFAYDVQQK
-Ew1HZW9UcnVzdCBJbmMuMTEwLwYDVQQDEyhHZW9UcnVzdCBQcmltYXJ5IENlcnRp
-ZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAvrgVe//UfH1nrYNke8hCUy3f9oQIIGHWAVlqnEQRr+92/ZV+zmEwu3qDXwK9
-AWbK7hWNb6EwnL2hhZ6UOvNWiAAxz9juapYC2e0DjPt1befquFUWBRaa9OBesYjA
-ZIVcFU2Ix7e64HXprQU9nceJSOC7KMgD4TCTZF5SwFlwIjVXiIrxlQqD17wxcwE0
-7e9GceBrAqg1cmuXm2bgyxx5X9gaBGgeRwLmnWDiNpcB3841kt++Z8dtd1k7j53W
-kBWUvEI0EME5+bEnPn7WinXFsq+W06Lem+SYvn3h6YGttm/81w7a4DSwDRp35+MI
-mO9Y+pyEtzavwt+s0vQQBnBxNQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQULNVQQZcVi/CPNmFbSvtr2ZnJM5IwDQYJ
-KoZIhvcNAQEFBQADggEBAFpwfyzdtzRP9YZRqSa+S7iq8XEN3GHHoOo0Hnp3DwQ1
-6CePbJC/kRYkRj5KTs4rFtULUh38H2eiAkUxT87z+gOneZ1TatnaYzr4gNfTmeGl
-4b7UVXGYNTq+k+qurUKykG/g/CFNNWMziUnWm07Kx+dOCQD32sfvmWKZd7aVIl6K
-oKv0uHiYyjgZmclynnjNS6yvGaBzEi38wkG6gZHaFloxt/m0cYASSJlyc1pZU8Fj
-UjPtp8nSOQJw+uCxQmYpqptR7TBUIhRf2asdweSU8Pj1K/fqynhG1riR/aYNKxoU
-AT6A8EKglQdebc3MS6RFjasS6LPeWuWgfOgPIh1a6Vk=
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA O=thawte, Inc. OU=Certification Services Division/(c) 2006 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA"
-# Serial: 69529181992039203566298953787712940909
-# MD5 Fingerprint: 8c:ca:dc:0b:22:ce:f5:be:72:ac:41:1a:11:a8:d8:12
-# SHA1 Fingerprint: 91:c6:d6:ee:3e:8a:c8:63:84:e5:48:c2:99:29:5c:75:6c:81:7b:81
-# SHA256 Fingerprint: 8d:72:2f:81:a9:c1:13:c0:79:1d:f1:36:a2:96:6d:b2:6c:95:0a:97:1d:b4:6b:41:99:f4:ea:54:b7:8b:fb:9f
------BEGIN CERTIFICATE-----
-MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB
-qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV
-BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw
-NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j
-LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG
-A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl
-IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs
-W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta
-3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk
-6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6
-Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J
-NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA
-MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP
-r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU
-DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz
-YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX
-xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2
-/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/
-LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7
-jVaMaA==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G5 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2006 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Class 3 Public Primary Certification Authority - G5"
-# Serial: 33037644167568058970164719475676101450
-# MD5 Fingerprint: cb:17:e4:31:67:3e:e2:09:fe:45:57:93:f3:0a:fa:1c
-# SHA1 Fingerprint: 4e:b6:d5:78:49:9b:1c:cf:5f:58:1e:ad:56:be:3d:9b:67:44:a5:e5
-# SHA256 Fingerprint: 9a:cf:ab:7e:43:c8:d8:80:d0:6b:26:2a:94:de:ee:e4:b4:65:99:89:c3:d0:ca:f1:9b:af:64:05:e4:1a:b7:df
------BEGIN CERTIFICATE-----
-MIIE0zCCA7ugAwIBAgIQGNrRniZ96LtKIVjNzGs7SjANBgkqhkiG9w0BAQUFADCB
-yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW
-ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5IC0gRzUwHhcNMDYxMTA4MDAwMDAwWhcNMzYwNzE2MjM1OTU5WjCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvJAgIKXo1
-nmAMqudLO07cfLw8RRy7K+D+KQL5VwijZIUVJ/XxrcgxiV0i6CqqpkKzj/i5Vbex
-t0uz/o9+B1fs70PbZmIVYc9gDaTY3vjgw2IIPVQT60nKWVSFJuUrjxuf6/WhkcIz
-SdhDY2pSS9KP6HBRTdGJaXvHcPaz3BJ023tdS1bTlr8Vd6Gw9KIl8q8ckmcY5fQG
-BO+QueQA5N06tRn/Arr0PO7gi+s3i+z016zy9vA9r911kTMZHRxAy3QkGSGT2RT+
-rCpSx4/VBEnkjWNHiDxpg8v+R70rfk/Fla4OndTRQ8Bnc+MUCH7lP59zuDMKz10/
-NIeWiu5T6CUVAgMBAAGjgbIwga8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8E
-BAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJaW1hZ2UvZ2lmMCEwHzAH
-BgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYjaHR0cDovL2xvZ28udmVy
-aXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFH/TZafC3ey78DAJ80M5+gKv
-MzEzMA0GCSqGSIb3DQEBBQUAA4IBAQCTJEowX2LP2BqYLz3q3JktvXf2pXkiOOzE
-p6B4Eq1iDkVwZMXnl2YtmAl+X6/WzChl8gGqCBpH3vn5fJJaCGkgDdk+bW48DW7Y
-5gaRQBi5+MHt39tBquCWIMnNZBU4gcmU7qKEKQsTb47bDN0lAtukixlE0kF6BWlK
-WE9gyn6CagsCqiUXObXbf+eEZSqVir2G3l6BFoMtEMze/aiCKm0oHw0LxOXnGiYZ
-4fQRbxC1lfznQgUy286dUV4otp6F01vvpX1FQHKOtw5rDgb7MzVIcbidJ4vEZV8N
-hnacRHr2lVz2XTIIM6RUthg/aFzyQkqFOFSDX9HoLPKsEdao7WNq
------END CERTIFICATE-----
-
-# Issuer: CN=SecureTrust CA O=SecureTrust Corporation
-# Subject: CN=SecureTrust CA O=SecureTrust Corporation
-# Label: "SecureTrust CA"
-# Serial: 17199774589125277788362757014266862032
-# MD5 Fingerprint: dc:32:c3:a7:6d:25:57:c7:68:09:9d:ea:2d:a9:a2:d1
-# SHA1 Fingerprint: 87:82:c6:c3:04:35:3b:cf:d2:96:92:d2:59:3e:7d:44:d9:34:ff:11
-# SHA256 Fingerprint: f1:c1:b5:0a:e5:a2:0d:d8:03:0e:c9:f6:bc:24:82:3d:d3:67:b5:25:57:59:b4:e7:1b:61:fc:e9:f7:37:5d:73
------BEGIN CERTIFICATE-----
-MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBI
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-FzAVBgNVBAMTDlNlY3VyZVRydXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIz
-MTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAeBgNVBAoTF1NlY3VyZVRydXN0IENv
-cnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQXOZEz
-Zum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO
-0gMdA+9tDWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIao
-wW8xQmxSPmjL8xk037uHGFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj
-7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b01k/unK8RCSc43Oz969XL0Imnal0ugBS
-8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmHursCAwEAAaOBnTCBmjAT
-BgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB
-/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCeg
-JYYjaHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGC
-NxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt3
-6Z3q059c4EVlew3KW+JwULKUBRSuSceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/
-3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHfmbx8IVQr5Fiiu1cprp6poxkm
-D5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZnMUFdAvnZyPS
-CPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR
-3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE=
------END CERTIFICATE-----
-
-# Issuer: CN=Secure Global CA O=SecureTrust Corporation
-# Subject: CN=Secure Global CA O=SecureTrust Corporation
-# Label: "Secure Global CA"
-# Serial: 9751836167731051554232119481456978597
-# MD5 Fingerprint: cf:f4:27:0d:d4:ed:dc:65:16:49:6d:3d:da:bf:6e:de
-# SHA1 Fingerprint: 3a:44:73:5a:e5:81:90:1f:24:86:61:46:1e:3b:9c:c4:5f:f5:3a:1b
-# SHA256 Fingerprint: 42:00:f5:04:3a:c8:59:0e:bb:52:7d:20:9e:d1:50:30:29:fb:cb:d4:1c:a1:b5:06:ec:27:f1:5a:de:7d:ac:69
------BEGIN CERTIFICATE-----
-MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBK
-MQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24x
-GTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkx
-MjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3Qg
-Q29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwgQ0EwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jxYDiJ
-iQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa
-/FHtaMbQbqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJ
-jnIFHovdRIWCQtBJwB1g8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnI
-HmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYVHDGA76oYa8J719rO+TMg1fW9ajMtgQT7
-sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi0XPnj3pDAgMBAAGjgZ0w
-gZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQF
-MAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCsw
-KaAnoCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsG
-AQQBgjcVAQQDAgEAMA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0L
-URYD7xh8yOOvaliTFGCRsoTciE6+OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXO
-H0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cnCDpOGR86p1hcF895P4vkp9Mm
-I50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/53CYNv6ZHdAbY
-iNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc
-f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW
------END CERTIFICATE-----
-
-# Issuer: CN=COMODO Certification Authority O=COMODO CA Limited
-# Subject: CN=COMODO Certification Authority O=COMODO CA Limited
-# Label: "COMODO Certification Authority"
-# Serial: 104350513648249232941998508985834464573
-# MD5 Fingerprint: 5c:48:dc:f7:42:72:ec:56:94:6d:1c:cc:71:35:80:75
-# SHA1 Fingerprint: 66:31:bf:9e:f7:4f:9e:b6:c9:d5:a6:0c:ba:6a:be:d1:f7:bd:ef:7b
-# SHA256 Fingerprint: 0c:2c:d6:3d:f7:80:6f:a3:99:ed:e8:09:11:6b:57:5b:f8:79:89:f0:65:18:f9:80:8c:86:05:03:17:8b:af:66
------BEGIN CERTIFICATE-----
-MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCB
-gTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G
-A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNV
-BAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNjEyMDEwMDAw
-MDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl
-YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P
-RE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0
-aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3
-UcEbVASY06m/weaKXTuH+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI
-2GqGd0S7WWaXUF601CxwRM/aN5VCaTwwxHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8
-Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV4EajcNxo2f8ESIl33rXp
-+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA1KGzqSX+
-DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5O
-nKVIrLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW
-/zAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6g
-PKA6hjhodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9u
-QXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOCAQEAPpiem/Yb6dc5t3iuHXIY
-SdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CPOGEIqB6BCsAv
-IC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/
-RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4
-zJVSk/BwJVmcIGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5dd
-BA6+C4OmF4O5MBKgxTMVBbkN+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IB
-ZQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
-# Subject: CN=Network Solutions Certificate Authority O=Network Solutions L.L.C.
-# Label: "Network Solutions Certificate Authority"
-# Serial: 116697915152937497490437556386812487904
-# MD5 Fingerprint: d3:f3:a6:16:c0:fa:6b:1d:59:b1:2d:96:4d:0e:11:2e
-# SHA1 Fingerprint: 74:f8:a3:c3:ef:e7:b3:90:06:4b:83:90:3c:21:64:60:20:e5:df:ce
-# SHA256 Fingerprint: 15:f0:ba:00:a3:ac:7a:f3:ac:88:4c:07:2b:10:11:a0:77:bd:77:c0:97:f4:01:64:b2:f8:59:8a:bd:83:86:0c
------BEGIN CERTIFICATE-----
-MIID5jCCAs6gAwIBAgIQV8szb8JcFuZHFhfjkDFo4DANBgkqhkiG9w0BAQUFADBi
-MQswCQYDVQQGEwJVUzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMu
-MTAwLgYDVQQDEydOZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3Jp
-dHkwHhcNMDYxMjAxMDAwMDAwWhcNMjkxMjMxMjM1OTU5WjBiMQswCQYDVQQGEwJV
-UzEhMB8GA1UEChMYTmV0d29yayBTb2x1dGlvbnMgTC5MLkMuMTAwLgYDVQQDEydO
-ZXR3b3JrIFNvbHV0aW9ucyBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDkvH6SMG3G2I4rC7xGzuAnlt7e+foS0zwz
-c7MEL7xxjOWftiJgPl9dzgn/ggwbmlFQGiaJ3dVhXRncEg8tCqJDXRfQNJIg6nPP
-OCwGJgl6cvf6UDL4wpPTaaIjzkGxzOTVHzbRijr4jGPiFFlp7Q3Tf2vouAPlT2rl
-mGNpSAW+Lv8ztumXWWn4Zxmuk2GWRBXTcrA/vGp97Eh/jcOrqnErU2lBUzS1sLnF
-BgrEsEX1QV1uiUV7PTsmjHTC5dLRfbIR1PtYMiKagMnc/Qzpf14Dl847ABSHJ3A4
-qY5usyd2mFHgBeMhqxrVhSI8KbWaFsWAqPS7azCPL0YCorEMIuDTAgMBAAGjgZcw
-gZQwHQYDVR0OBBYEFCEwyfsA106Y2oeqKtCnLrFAMadMMA4GA1UdDwEB/wQEAwIB
-BjAPBgNVHRMBAf8EBTADAQH/MFIGA1UdHwRLMEkwR6BFoEOGQWh0dHA6Ly9jcmwu
-bmV0c29sc3NsLmNvbS9OZXR3b3JrU29sdXRpb25zQ2VydGlmaWNhdGVBdXRob3Jp
-dHkuY3JsMA0GCSqGSIb3DQEBBQUAA4IBAQC7rkvnt1frf6ott3NHhWrB5KUd5Oc8
-6fRZZXe1eltajSU24HqXLjjAV2CDmAaDn7l2em5Q4LqILPxFzBiwmZVRDuwduIj/
-h1AcgsLj4DKAv6ALR8jDMe+ZZzKATxcheQxpXN5eNK4CtSbqUN9/GGUsyfJj4akH
-/nxxH2szJGoeBfcFaMBqEssuXmHLrijTfsK0ZpEmXzwuJF/LWA/rKOyvEZbz3Htv
-wKeI8lN3s2Berq4o2jUsbzRF0ybh3uxbTydrFny9RAQYgrOJeRcQcT16ohZO9QHN
-pGxlaKFJdlxDydi8NmdspZS11My5vWo1ViHe2MPr+8ukYEywVaCge1ey
------END CERTIFICATE-----
-
-# Issuer: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
-# Subject: CN=WellsSecure Public Root Certificate Authority O=Wells Fargo WellsSecure OU=Wells Fargo Bank NA
-# Label: "WellsSecure Public Root Certificate Authority"
-# Serial: 1
-# MD5 Fingerprint: 15:ac:a5:c2:92:2d:79:bc:e8:7f:cb:67:ed:02:cf:36
-# SHA1 Fingerprint: e7:b4:f6:9d:61:ec:90:69:db:7e:90:a7:40:1a:3c:f4:7d:4f:e8:ee
-# SHA256 Fingerprint: a7:12:72:ae:aa:a3:cf:e8:72:7f:7f:b3:9f:0f:b3:d1:e5:42:6e:90:60:b0:6e:e6:f1:3e:9a:3c:58:33:cd:43
------BEGIN CERTIFICATE-----
-MIIEvTCCA6WgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBhTELMAkGA1UEBhMCVVMx
-IDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxs
-cyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9v
-dCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMDcxMjEzMTcwNzU0WhcNMjIxMjE0
-MDAwNzU0WjCBhTELMAkGA1UEBhMCVVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdl
-bGxzU2VjdXJlMRwwGgYDVQQLDBNXZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQD
-DC1XZWxsc1NlY3VyZSBQdWJsaWMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkw
-ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDub7S9eeKPCCGeOARBJe+r
-WxxTkqxtnt3CxC5FlAM1iGd0V+PfjLindo8796jE2yljDpFoNoqXjopxaAkH5OjU
-Dk/41itMpBb570OYj7OeUt9tkTmPOL13i0Nj67eT/DBMHAGTthP796EfvyXhdDcs
-HqRePGj4S78NuR4uNuip5Kf4D8uCdXw1LSLWwr8L87T8bJVhHlfXBIEyg1J55oNj
-z7fLY4sR4r1e6/aN7ZVyKLSsEmLpSjPmgzKuBXWVvYSV2ypcm44uDLiBK0HmOFaf
-SZtsdvqKXfcBeYF8wYNABf5x/Qw/zE5gCQ5lRxAvAcAFP4/4s0HvWkJ+We/Slwxl
-AgMBAAGjggE0MIIBMDAPBgNVHRMBAf8EBTADAQH/MDkGA1UdHwQyMDAwLqAsoCqG
-KGh0dHA6Ly9jcmwucGtpLndlbGxzZmFyZ28uY29tL3dzcHJjYS5jcmwwDgYDVR0P
-AQH/BAQDAgHGMB0GA1UdDgQWBBQmlRkQ2eihl5H/3BnZtQQ+0nMKajCBsgYDVR0j
-BIGqMIGngBQmlRkQ2eihl5H/3BnZtQQ+0nMKaqGBi6SBiDCBhTELMAkGA1UEBhMC
-VVMxIDAeBgNVBAoMF1dlbGxzIEZhcmdvIFdlbGxzU2VjdXJlMRwwGgYDVQQLDBNX
-ZWxscyBGYXJnbyBCYW5rIE5BMTYwNAYDVQQDDC1XZWxsc1NlY3VyZSBQdWJsaWMg
-Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHmCAQEwDQYJKoZIhvcNAQEFBQADggEB
-ALkVsUSRzCPIK0134/iaeycNzXK7mQDKfGYZUMbVmO2rvwNa5U3lHshPcZeG1eMd
-/ZDJPHV3V3p9+N701NX3leZ0bh08rnyd2wIDBSxxSyU+B+NemvVmFymIGjifz6pB
-A4SXa5M4esowRBskRDPQ5NHcKDj0E0M1NSljqHyita04pO2t/caaH/+Xc/77szWn
-k4bGdpEA5qxRFsQnMlzbc9qlk1eOPm01JghZ1edE13YgY+esE2fDbbFwRnzVlhE9
-iW9dqKHrjQrawx0zbKPqZxmamX9LPYNRKh3KL4YMon4QLSvUFpULB6ouFJJJtylv
-2G0xffX8oRAHh84vWdw+WNs=
------END CERTIFICATE-----
-
-# Issuer: CN=COMODO ECC Certification Authority O=COMODO CA Limited
-# Subject: CN=COMODO ECC Certification Authority O=COMODO CA Limited
-# Label: "COMODO ECC Certification Authority"
-# Serial: 41578283867086692638256921589707938090
-# MD5 Fingerprint: 7c:62:ff:74:9d:31:53:5e:68:4a:d5:78:aa:1e:bf:23
-# SHA1 Fingerprint: 9f:74:4e:9f:2b:4d:ba:ec:0f:31:2c:50:b6:56:3b:8e:2d:93:c3:11
-# SHA256 Fingerprint: 17:93:92:7a:06:14:54:97:89:ad:ce:2f:8f:34:f7:f0:b6:6d:0f:3a:e3:a3:b8:4d:21:ec:15:db:ba:4f:ad:c7
------BEGIN CERTIFICATE-----
-MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTEL
-MAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UE
-BxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMT
-IkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwMzA2MDAw
-MDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy
-ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N
-T0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlv
-biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSR
-FtSrYpn1PlILBs5BAH+X4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0J
-cfRK9ChQtP6IHG4/bC8vCVlbpVsLM5niwz2J+Wos77LTBumjQjBAMB0GA1UdDgQW
-BBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/
-BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VGFAkK+qDm
-fQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdv
-GDeAU/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY=
------END CERTIFICATE-----
-
-# Issuer: CN=IGC/A O=PM/SGDN OU=DCSSI
-# Subject: CN=IGC/A O=PM/SGDN OU=DCSSI
-# Label: "IGC/A"
-# Serial: 245102874772
-# MD5 Fingerprint: 0c:7f:dd:6a:f4:2a:b9:c8:9b:bd:20:7e:a9:db:5c:37
-# SHA1 Fingerprint: 60:d6:89:74:b5:c2:65:9e:8a:0f:c1:88:7c:88:d2:46:69:1b:18:2c
-# SHA256 Fingerprint: b9:be:a7:86:0a:96:2e:a3:61:1d:ab:97:ab:6d:a3:e2:1c:10:68:b9:7d:55:57:5e:d0:e1:12:79:c1:1c:89:32
------BEGIN CERTIFICATE-----
-MIIEAjCCAuqgAwIBAgIFORFFEJQwDQYJKoZIhvcNAQEFBQAwgYUxCzAJBgNVBAYT
-AkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQ
-TS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG
-9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMB4XDTAyMTIxMzE0MjkyM1oXDTIw
-MTAxNzE0MjkyMlowgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAM
-BgNVBAcTBVBhcmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEO
-MAwGA1UEAxMFSUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2
-LmZyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsh/R0GLFMzvABIaI
-s9z4iPf930Pfeo2aSVz2TqrMHLmh6yeJ8kbpO0px1R2OLc/mratjUMdUC24SyZA2
-xtgv2pGqaMVy/hcKshd+ebUyiHDKcMCWSo7kVc0dJ5S/znIq7Fz5cyD+vfcuiWe4
-u0dzEvfRNWk68gq5rv9GQkaiv6GFGvm/5P9JhfejcIYyHF2fYPepraX/z9E0+X1b
-F8bc1g4oa8Ld8fUzaJ1O/Id8NhLWo4DoQw1VYZTqZDdH6nfK0LJYBcNdfrGoRpAx
-Vs5wKpayMLh35nnAvSk7/ZR3TL0gzUEl4C7HG7vupARB0l2tEmqKm0f7yd1GQOGd
-PDPQtQIDAQABo3cwdTAPBgNVHRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBRjAVBgNV
-HSAEDjAMMAoGCCqBegF5AQEBMB0GA1UdDgQWBBSjBS8YYFDCiQrdKyFP/45OqDAx
-NjAfBgNVHSMEGDAWgBSjBS8YYFDCiQrdKyFP/45OqDAxNjANBgkqhkiG9w0BAQUF
-AAOCAQEABdwm2Pp3FURo/C9mOnTgXeQp/wYHE4RKq89toB9RlPhJy3Q2FLwV3duJ
-L92PoF189RLrn544pEfMs5bZvpwlqwN+Mw+VgQ39FuCIvjfwbF3QMZsyK10XZZOY
-YLxuj7GoPB7ZHPOpJkL5ZB3C55L29B5aqhlSXa/oovdgoPaN8In1buAKBQGVyYsg
-Crpa/JosPL3Dt8ldeCUFP1YUmwza+zpI/pdpXsoQhvdOlgQITeywvl3cO45Pwf2a
-NjSaTFR+FwNIlQgRHAdvhQh+XU3Endv7rs6y0bO4g2wdsrN58dhwmX7wEwLOXt1R
-0982gaEbeC9xs/FZTEYYKKuF0mBWWg==
------END CERTIFICATE-----
-
-# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
-# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication EV RootCA1
-# Label: "Security Communication EV RootCA1"
-# Serial: 0
-# MD5 Fingerprint: 22:2d:a6:01:ea:7c:0a:f7:f0:6c:56:43:3f:77:76:d3
-# SHA1 Fingerprint: fe:b8:c4:32:dc:f9:76:9a:ce:ae:3d:d8:90:8f:fd:28:86:65:64:7d
-# SHA256 Fingerprint: a2:2d:ba:68:1e:97:37:6e:2d:39:7d:72:8a:ae:3a:9b:62:96:b9:fd:ba:60:bc:2e:11:f6:47:f2:c6:75:fb:37
------BEGIN CERTIFICATE-----
-MIIDfTCCAmWgAwIBAgIBADANBgkqhkiG9w0BAQUFADBgMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEqMCgGA1UECxMh
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBFViBSb290Q0ExMB4XDTA3MDYwNjAyMTIz
-MloXDTM3MDYwNjAyMTIzMlowYDELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09N
-IFRydXN0IFN5c3RlbXMgQ08uLExURC4xKjAoBgNVBAsTIVNlY3VyaXR5IENvbW11
-bmljYXRpb24gRVYgUm9vdENBMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBALx/7FebJOD+nLpCeamIivqA4PUHKUPqjgo0No0c+qe1OXj/l3X3L+SqawSE
-RMqm4miO/VVQYg+kcQ7OBzgtQoVQrTyWb4vVog7P3kmJPdZkLjjlHmy1V4qe70gO
-zXppFodEtZDkBp2uoQSXWHnvIEqCa4wiv+wfD+mEce3xDuS4GBPMVjZd0ZoeUWs5
-bmB2iDQL87PRsJ3KYeJkHcFGB7hj3R4zZbOOCVVSPbW9/wfrrWFVGCypaZhKqkDF
-MxRldAD5kd6vA0jFQFTcD4SQaCDFkpbcLuUCRarAX1T4bepJz11sS6/vmsJWXMY1
-VkJqMF/Cq/biPT+zyRGPMUzXn0kCAwEAAaNCMEAwHQYDVR0OBBYEFDVK9U2vP9eC
-OKyrcWUXdYydVZPmMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQCoh+ns+EBnXcPBZsdAS5f8hxOQWsTvoMpfi7ent/HW
-tWS3irO4G8za+6xmiEHO6Pzk2x6Ipu0nUBsCMCRGef4Eh3CXQHPRwMFXGZpppSeZ
-q51ihPZRwSzJIxXYKLerJRO1RuGGAv8mjMSIkh1W/hln8lXkgKNrnKt34VFxDSDb
-EJrbvXZ5B3eZKK2aXtqxT0QsNY6llsf9g/BYxnnWmHyojf6GPgcWkuF75x3sM3Z+
-Qi5KhfmRiWiEA4Glm5q+4zfFVKtWOxgtQaQM+ELbmaDgcm+7XeEWT1MKZPlO9L9O
-VL14bIjqv5wTJMJwaaJ/D8g8rQjJsJhAoyrniIPtd490
------END CERTIFICATE-----
-
-# Issuer: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
-# Subject: CN=OISTE WISeKey Global Root GA CA O=WISeKey OU=Copyright (c) 2005/OISTE Foundation Endorsed
-# Label: "OISTE WISeKey Global Root GA CA"
-# Serial: 86718877871133159090080555911823548314
-# MD5 Fingerprint: bc:6c:51:33:a7:e9:d3:66:63:54:15:72:1b:21:92:93
-# SHA1 Fingerprint: 59:22:a1:e1:5a:ea:16:35:21:f8:98:39:6a:46:46:b0:44:1b:0f:a9
-# SHA256 Fingerprint: 41:c9:23:86:6a:b4:ca:d6:b7:ad:57:80:81:58:2e:02:07:97:a6:cb:df:4f:ff:78:ce:83:96:b3:89:37:d7:f5
------BEGIN CERTIFICATE-----
-MIID8TCCAtmgAwIBAgIQQT1yx/RrH4FDffHSKFTfmjANBgkqhkiG9w0BAQUFADCB
-ijELMAkGA1UEBhMCQ0gxEDAOBgNVBAoTB1dJU2VLZXkxGzAZBgNVBAsTEkNvcHly
-aWdodCAoYykgMjAwNTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl
-ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQSBDQTAeFw0w
-NTEyMTExNjAzNDRaFw0zNzEyMTExNjA5NTFaMIGKMQswCQYDVQQGEwJDSDEQMA4G
-A1UEChMHV0lTZUtleTEbMBkGA1UECxMSQ29weXJpZ2h0IChjKSAyMDA1MSIwIAYD
-VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBX
-SVNlS2V5IEdsb2JhbCBSb290IEdBIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAy0+zAJs9Nt350UlqaxBJH+zYK7LG+DKBKUOVTJoZIyEVRd7jyBxR
-VVuuk+g3/ytr6dTqvirdqFEr12bDYVxgAsj1znJ7O7jyTmUIms2kahnBAbtzptf2
-w93NvKSLtZlhuAGio9RN1AU9ka34tAhxZK9w8RxrfvbDd50kc3vkDIzh2TbhmYsF
-mQvtRTEJysIA2/dyoJaqlYfQjse2YXMNdmaM3Bu0Y6Kff5MTMPGhJ9vZ/yxViJGg
-4E8HsChWjBgbl0SOid3gF27nKu+POQoxhILYQBRJLnpB5Kf+42TMwVlxSywhp1t9
-4B3RLoGbw9ho972WG6xwsRYUC9tguSYBBQIDAQABo1EwTzALBgNVHQ8EBAMCAYYw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUswN+rja8sHnR3JQmthG+IbJphpQw
-EAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZIhvcNAQEFBQADggEBAEuh/wuHbrP5wUOx
-SPMowB0uyQlB+pQAHKSkq0lPjz0e701vvbyk9vImMMkQyh2I+3QZH4VFvbBsUfk2
-ftv1TDI6QU9bR8/oCy22xBmddMVHxjtqD6wU2zz0c5ypBd8A3HR4+vg1YFkCExh8
-vPtNsCBtQ7tgMHpnM1zFmdH4LTlSc/uMqpclXHLZCB6rTjzjgTGfA6b7wP4piFXa
-hNVQA7bihKOmNqoROgHhGEvWRGizPflTdISzRpFGlgC3gCy24eMQ4tui5yiPAZZi
-Fj4A4xylNoEYokxSdsARo27mHbrjWr42U8U+dY+GaSlYU7Wcu2+fXMUY7N0v4ZjJ
-/L7fCg0=
------END CERTIFICATE-----
-
-# Issuer: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
-# Subject: CN=Microsec e-Szigno Root CA O=Microsec Ltd. OU=e-Szigno CA
-# Label: "Microsec e-Szigno Root CA"
-# Serial: 272122594155480254301341951808045322001
-# MD5 Fingerprint: f0:96:b6:2f:c5:10:d5:67:8e:83:25:32:e8:5e:2e:e5
-# SHA1 Fingerprint: 23:88:c9:d3:71:cc:9e:96:3d:ff:7d:3c:a7:ce:fc:d6:25:ec:19:0d
-# SHA256 Fingerprint: 32:7a:3d:76:1a:ba:de:a0:34:eb:99:84:06:27:5c:b1:a4:77:6e:fd:ae:2f:df:6d:01:68:ea:1c:4f:55:67:d0
------BEGIN CERTIFICATE-----
-MIIHqDCCBpCgAwIBAgIRAMy4579OKRr9otxmpRwsDxEwDQYJKoZIhvcNAQEFBQAw
-cjELMAkGA1UEBhMCSFUxETAPBgNVBAcTCEJ1ZGFwZXN0MRYwFAYDVQQKEw1NaWNy
-b3NlYyBMdGQuMRQwEgYDVQQLEwtlLVN6aWdubyBDQTEiMCAGA1UEAxMZTWljcm9z
-ZWMgZS1Temlnbm8gUm9vdCBDQTAeFw0wNTA0MDYxMjI4NDRaFw0xNzA0MDYxMjI4
-NDRaMHIxCzAJBgNVBAYTAkhVMREwDwYDVQQHEwhCdWRhcGVzdDEWMBQGA1UEChMN
-TWljcm9zZWMgTHRkLjEUMBIGA1UECxMLZS1Temlnbm8gQ0ExIjAgBgNVBAMTGU1p
-Y3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQDtyADVgXvNOABHzNuEwSFpLHSQDCHZU4ftPkNEU6+r+ICbPHiN1I2u
-uO/TEdyB5s87lozWbxXGd36hL+BfkrYn13aaHUM86tnsL+4582pnS4uCzyL4ZVX+
-LMsvfUh6PXX5qqAnu3jCBspRwn5mS6/NoqdNAoI/gqyFxuEPkEeZlApxcpMqyabA
-vjxWTHOSJ/FrtfX9/DAFYJLG65Z+AZHCabEeHXtTRbjcQR/Ji3HWVBTji1R4P770
-Yjtb9aPs1ZJ04nQw7wHb4dSrmZsqa/i9phyGI0Jf7Enemotb9HI6QMVJPqW+jqpx
-62z69Rrkav17fVVA71hu5tnVvCSrwe+3AgMBAAGjggQ3MIIEMzBnBggrBgEFBQcB
-AQRbMFkwKAYIKwYBBQUHMAGGHGh0dHBzOi8vcmNhLmUtc3ppZ25vLmh1L29jc3Aw
-LQYIKwYBBQUHMAKGIWh0dHA6Ly93d3cuZS1zemlnbm8uaHUvUm9vdENBLmNydDAP
-BgNVHRMBAf8EBTADAQH/MIIBcwYDVR0gBIIBajCCAWYwggFiBgwrBgEEAYGoGAIB
-AQEwggFQMCgGCCsGAQUFBwIBFhxodHRwOi8vd3d3LmUtc3ppZ25vLmh1L1NaU1ov
-MIIBIgYIKwYBBQUHAgIwggEUHoIBEABBACAAdABhAG4A+gBzAO0AdAB2AOEAbgB5
-ACAA6QByAHQAZQBsAG0AZQB6AOkAcwDpAGgAZQB6ACAA6QBzACAAZQBsAGYAbwBn
-AGEAZADhAHMA4QBoAG8AegAgAGEAIABTAHoAbwBsAGcA4QBsAHQAYQB0APMAIABT
-AHoAbwBsAGcA4QBsAHQAYQB0AOEAcwBpACAAUwB6AGEAYgDhAGwAeQB6AGEAdABh
-ACAAcwB6AGUAcgBpAG4AdAAgAGsAZQBsAGwAIABlAGwAagDhAHIAbgBpADoAIABo
-AHQAdABwADoALwAvAHcAdwB3AC4AZQAtAHMAegBpAGcAbgBvAC4AaAB1AC8AUwBa
-AFMAWgAvMIHIBgNVHR8EgcAwgb0wgbqggbeggbSGIWh0dHA6Ly93d3cuZS1zemln
-bm8uaHUvUm9vdENBLmNybIaBjmxkYXA6Ly9sZGFwLmUtc3ppZ25vLmh1L0NOPU1p
-Y3Jvc2VjJTIwZS1Temlnbm8lMjBSb290JTIwQ0EsT1U9ZS1Temlnbm8lMjBDQSxP
-PU1pY3Jvc2VjJTIwTHRkLixMPUJ1ZGFwZXN0LEM9SFU/Y2VydGlmaWNhdGVSZXZv
-Y2F0aW9uTGlzdDtiaW5hcnkwDgYDVR0PAQH/BAQDAgEGMIGWBgNVHREEgY4wgYuB
-EGluZm9AZS1zemlnbm8uaHWkdzB1MSMwIQYDVQQDDBpNaWNyb3NlYyBlLVN6aWdu
-w7MgUm9vdCBDQTEWMBQGA1UECwwNZS1TemlnbsOzIEhTWjEWMBQGA1UEChMNTWlj
-cm9zZWMgS2Z0LjERMA8GA1UEBxMIQnVkYXBlc3QxCzAJBgNVBAYTAkhVMIGsBgNV
-HSMEgaQwgaGAFMegSXUWYYTbMUuE0vE3QJDvTtz3oXakdDByMQswCQYDVQQGEwJI
-VTERMA8GA1UEBxMIQnVkYXBlc3QxFjAUBgNVBAoTDU1pY3Jvc2VjIEx0ZC4xFDAS
-BgNVBAsTC2UtU3ppZ25vIENBMSIwIAYDVQQDExlNaWNyb3NlYyBlLVN6aWdubyBS
-b290IENBghEAzLjnv04pGv2i3GalHCwPETAdBgNVHQ4EFgQUx6BJdRZhhNsxS4TS
-8TdAkO9O3PcwDQYJKoZIhvcNAQEFBQADggEBANMTnGZjWS7KXHAM/IO8VbH0jgds
-ZifOwTsgqRy7RlRw7lrMoHfqaEQn6/Ip3Xep1fvj1KcExJW4C+FEaGAHQzAxQmHl
-7tnlJNUb3+FKG6qfx1/4ehHqE5MAyopYse7tDk2016g2JnzgOsHVV4Lxdbb9iV/a
-86g4nzUGCM4ilb7N1fy+W955a9x6qWVmvrElWl/tftOsRm1M9DKHtCAE4Gx4sHfR
-hUZLphK3dehKyVZs15KrnfVJONJPU+NVkBHbmJbGSfI+9J8b4PeI3CVimUTYc78/
-MPMMNz7UwiiAc7EBt51alhQBS6kRnSlqLtBdgcDPsiBDxwPgN05dCtxZICU=
------END CERTIFICATE-----
-
-# Issuer: CN=Certigna O=Dhimyotis
-# Subject: CN=Certigna O=Dhimyotis
-# Label: "Certigna"
-# Serial: 18364802974209362175
-# MD5 Fingerprint: ab:57:a6:5b:7d:42:82:19:b5:d8:58:26:28:5e:fd:ff
-# SHA1 Fingerprint: b1:2e:13:63:45:86:a4:6f:1a:b2:60:68:37:58:2d:c4:ac:fd:94:97
-# SHA256 Fingerprint: e3:b6:a2:db:2e:d7:ce:48:84:2f:7a:c5:32:41:c7:b7:1d:54:14:4b:fb:40:c1:1f:3f:1d:0b:42:f5:ee:a1:2d
------BEGIN CERTIFICATE-----
-MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNV
-BAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4X
-DTA3MDYyOTE1MTMwNVoXDTI3MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQ
-BgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwIQ2VydGlnbmEwggEiMA0GCSqGSIb3
-DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7qXOEm7RFHYeGifBZ4
-QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyHGxny
-gQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbw
-zBfsV1/pogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q
-130yGLMLLGq/jj8UEYkgDncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2
-JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKfIrjxwo1p3Po6WAbfAgMBAAGjgbwwgbkw
-DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQtCRZvgHyUtVF9lo53BEw
-ZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJBgNVBAYT
-AkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzj
-AQ/JSP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG
-9w0BAQUFAAOCAQEAhQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8h
-bV6lUmPOEvjvKtpv6zf+EwLHyzs+ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFnc
-fca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1kluPBS1xp81HlDQwY9qcEQCYsuu
-HWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY1gkIl2PlwS6w
-t0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw
-WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg==
------END CERTIFICATE-----
-
-# Issuer: CN=AC Raíz Certicámara S.A. O=Sociedad Cameral de Certificación Digital - Certicámara S.A.
-# Subject: CN=AC Raíz Certicámara S.A. O=Sociedad Cameral de Certificación Digital - Certicámara S.A.
-# Label: "AC Ra\xC3\xADz Certic\xC3\xA1mara S.A."
-# Serial: 38908203973182606954752843738508300
-# MD5 Fingerprint: 93:2a:3e:f6:fd:23:69:0d:71:20:d4:2b:47:99:2b:a6
-# SHA1 Fingerprint: cb:a1:c5:f8:b0:e3:5e:b8:b9:45:12:d3:f9:34:a2:e9:06:10:d3:36
-# SHA256 Fingerprint: a6:c5:1e:0d:a5:ca:0a:93:09:d2:e4:c0:e4:0c:2a:f9:10:7a:ae:82:03:85:7f:e1:98:e3:e7:69:e3:43:08:5c
------BEGIN CERTIFICATE-----
-MIIGZjCCBE6gAwIBAgIPB35Sk3vgFeNX8GmMy+wMMA0GCSqGSIb3DQEBBQUAMHsx
-CzAJBgNVBAYTAkNPMUcwRQYDVQQKDD5Tb2NpZWRhZCBDYW1lcmFsIGRlIENlcnRp
-ZmljYWNpw7NuIERpZ2l0YWwgLSBDZXJ0aWPDoW1hcmEgUy5BLjEjMCEGA1UEAwwa
-QUMgUmHDrXogQ2VydGljw6FtYXJhIFMuQS4wHhcNMDYxMTI3MjA0NjI5WhcNMzAw
-NDAyMjE0MjAyWjB7MQswCQYDVQQGEwJDTzFHMEUGA1UECgw+U29jaWVkYWQgQ2Ft
-ZXJhbCBkZSBDZXJ0aWZpY2FjacOzbiBEaWdpdGFsIC0gQ2VydGljw6FtYXJhIFMu
-QS4xIzAhBgNVBAMMGkFDIFJhw616IENlcnRpY8OhbWFyYSBTLkEuMIICIjANBgkq
-hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq2uJo1PMSCMI+8PPUZYILrgIem08kBeG
-qentLhM0R7LQcNzJPNCNyu5LF6vQhbCnIwTLqKL85XXbQMpiiY9QngE9JlsYhBzL
-fDe3fezTf3MZsGqy2IiKLUV0qPezuMDU2s0iiXRNWhU5cxh0T7XrmafBHoi0wpOQ
-Y5fzp6cSsgkiBzPZkc0OnB8OIMfuuzONj8LSWKdf/WU34ojC2I+GdV75LaeHM/J4
-Ny+LvB2GNzmxlPLYvEqcgxhaBvzz1NS6jBUJJfD5to0EfhcSM2tXSExP2yYe68yQ
-54v5aHxwD6Mq0Do43zeX4lvegGHTgNiRg0JaTASJaBE8rF9ogEHMYELODVoqDA+b
-MMCm8Ibbq0nXl21Ii/kDwFJnmxL3wvIumGVC2daa49AZMQyth9VXAnow6IYm+48j
-ilSH5L887uvDdUhfHjlvgWJsxS3EF1QZtzeNnDeRyPYL1epjb4OsOMLzP96a++Ej
-YfDIJss2yKHzMI+ko6Kh3VOz3vCaMh+DkXkwwakfU5tTohVTP92dsxA7SH2JD/zt
-A/X7JWR1DhcZDY8AFmd5ekD8LVkH2ZD6mq093ICK5lw1omdMEWux+IBkAC1vImHF
-rEsm5VoQgpukg3s0956JkSCXjrdCx2bD0Omk1vUgjcTDlaxECp1bczwmPS9KvqfJ
-pxAe+59QafMCAwEAAaOB5jCB4zAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQU0QnQ6dfOeXRU+Tows/RtLAMDG2gwgaAGA1UdIASBmDCB
-lTCBkgYEVR0gADCBiTArBggrBgEFBQcCARYfaHR0cDovL3d3dy5jZXJ0aWNhbWFy
-YS5jb20vZHBjLzBaBggrBgEFBQcCAjBOGkxMaW1pdGFjaW9uZXMgZGUgZ2FyYW50
-7WFzIGRlIGVzdGUgY2VydGlmaWNhZG8gc2UgcHVlZGVuIGVuY29udHJhciBlbiBs
-YSBEUEMuMA0GCSqGSIb3DQEBBQUAA4ICAQBclLW4RZFNjmEfAygPU3zmpFmps4p6
-xbD/CHwso3EcIRNnoZUSQDWDg4902zNc8El2CoFS3UnUmjIz75uny3XlesuXEpBc
-unvFm9+7OSPI/5jOCk0iAUgHforA1SBClETvv3eiiWdIG0ADBaGJ7M9i4z0ldma/
-Jre7Ir5v/zlXdLp6yQGVwZVR6Kss+LGGIOk/yzVb0hfpKv6DExdA7ohiZVvVO2Dp
-ezy4ydV/NgIlqmjCMRW3MGXrfx1IebHPOeJCgBbT9ZMj/EyXyVo3bHwi2ErN0o42
-gzmRkBDI8ck1fj+404HGIGQatlDCIaR43NAvO2STdPCWkPHv+wlaNECW8DYSwaN0
-jJN+Qd53i+yG2dIPPy3RzECiiWZIHiCznCNZc6lEc7wkeZBWN7PGKX6jD/EpOe9+
-XCgycDWs2rjIdWb8m0w5R44bb5tNAlQiM+9hup4phO9OSzNHdpdqy35f/RWmnkJD
-W2ZaiogN9xa5P1FlK2Zqi9E4UqLWRhH6/JocdJ6PlwsCT2TG9WjTSy3/pDceiz+/
-RL5hRqGEPQgnTIEgd4kI6mdAXmwIUV80WoyWaM3X94nCHNMyAK9Sy9NgWyo6R35r
-MDOhYil/SrnhLecUIw4OGEfhefwVVdCx/CVxY3UzHCMrr1zZ7Ud3YA47Dx7SwNxk
-BYn8eNZcLCZDqQ==
------END CERTIFICATE-----
-
-# Issuer: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA
-# Subject: CN=TC TrustCenter Class 2 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 2 CA
-# Label: "TC TrustCenter Class 2 CA II"
-# Serial: 941389028203453866782103406992443
-# MD5 Fingerprint: ce:78:33:5c:59:78:01:6e:18:ea:b9:36:a0:b9:2e:23
-# SHA1 Fingerprint: ae:50:83:ed:7c:f4:5c:bc:8f:61:c6:21:fe:68:5d:79:42:21:15:6e
-# SHA256 Fingerprint: e6:b8:f8:76:64:85:f8:07:ae:7f:8d:ac:16:70:46:1f:07:c0:a1:3e:ef:3a:1f:f7:17:53:8d:7a:ba:d3:91:b4
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOLmoAAQACH9dSISwRXDswDQYJKoZIhvcNAQEFBQAwdjEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
-BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDIgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
-Q2VudGVyIENsYXNzIDIgQ0EgSUkwHhcNMDYwMTEyMTQzODQzWhcNMjUxMjMxMjI1
-OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
-SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQTElMCMGA1UEAxMc
-VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMiBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAKuAh5uO8MN8h9foJIIRszzdQ2Lu+MNF2ujhoF/RKrLqk2jf
-tMjWQ+nEdVl//OEd+DFwIxuInie5e/060smp6RQvkL4DUsFJzfb95AhmC1eKokKg
-uNV/aVyQMrKXDcpK3EY+AlWJU+MaWss2xgdW94zPEfRMuzBwBJWl9jmM/XOBCH2J
-XjIeIqkiRUuwZi4wzJ9l/fzLganx4Duvo4bRierERXlQXa7pIXSSTYtZgo+U4+lK
-8edJsBTj9WLL1XK9H7nSn6DNqPoByNkN39r8R52zyFTfSUrxIan+GE7uSNQZu+99
-5OKdy1u2bv/jzVrndIIFuoAlOMvkaZ6vQaoahPUCAwEAAaOCATQwggEwMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTjq1RMgKHbVkO3
-kUrL84J6E1wIqzCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
-dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18yX2NhX0lJLmNybIaBn2xkYXA6
-Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
-JTIwMiUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
-Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEAjNfffu4bgBCzg/XbEeprS6iS
-GNn3Bzn1LL4GdXpoUxUc6krtXvwjshOg0wn/9vYua0Fxec3ibf2uWWuFHbhOIprt
-ZjluS5TmVfwLG4t3wVMTZonZKNaL80VKY7f9ewthXbhtvsPcW3nS7Yblok2+XnR8
-au0WOB9/WIFaGusyiC2y8zl3gK9etmF1KdsjTYjKUCjLhdLTEKJZbtOTVAB6okaV
-hgWcqRmY5TFyDADiZ9lA4CQze28suVyrZZ0srHbqNZn1l7kPJOzHdiEoZa5X6AeI
-dUpWoNIFOqTmjZKILPPy4cHGYdtBxceb9w4aUUXCYWvcZCcXjFq32nQozZfkvQ==
------END CERTIFICATE-----
-
-# Issuer: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA
-# Subject: CN=TC TrustCenter Class 3 CA II O=TC TrustCenter GmbH OU=TC TrustCenter Class 3 CA
-# Label: "TC TrustCenter Class 3 CA II"
-# Serial: 1506523511417715638772220530020799
-# MD5 Fingerprint: 56:5f:aa:80:61:12:17:f6:67:21:e6:2b:6d:61:56:8e
-# SHA1 Fingerprint: 80:25:ef:f4:6e:70:c8:d4:72:24:65:84:fe:40:3b:8a:8d:6a:db:f5
-# SHA256 Fingerprint: 8d:a0:84:fc:f9:9c:e0:77:22:f8:9b:32:05:93:98:06:fa:5c:b8:11:e1:c8:13:f6:a1:08:c7:d3:36:b3:40:8e
------BEGIN CERTIFICATE-----
-MIIEqjCCA5KgAwIBAgIOSkcAAQAC5aBd1j8AUb8wDQYJKoZIhvcNAQEFBQAwdjEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxIjAgBgNV
-BAsTGVRDIFRydXN0Q2VudGVyIENsYXNzIDMgQ0ExJTAjBgNVBAMTHFRDIFRydXN0
-Q2VudGVyIENsYXNzIDMgQ0EgSUkwHhcNMDYwMTEyMTQ0MTU3WhcNMjUxMjMxMjI1
-OTU5WjB2MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIgR21i
-SDEiMCAGA1UECxMZVEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQTElMCMGA1UEAxMc
-VEMgVHJ1c3RDZW50ZXIgQ2xhc3MgMyBDQSBJSTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBALTgu1G7OVyLBMVMeRwjhjEQY0NVJz/GRcekPewJDRoeIMJW
-Ht4bNwcwIi9v8Qbxq63WyKthoy9DxLCyLfzDlml7forkzMA5EpBCYMnMNWju2l+Q
-Vl/NHE1bWEnrDgFPZPosPIlY2C8u4rBo6SI7dYnWRBpl8huXJh0obazovVkdKyT2
-1oQDZogkAHhg8fir/gKya/si+zXmFtGt9i4S5Po1auUZuV3bOx4a+9P/FRQI2Alq
-ukWdFHlgfa9Aigdzs5OW03Q0jTo3Kd5c7PXuLjHCINy+8U9/I1LZW+Jk2ZyqBwi1
-Rb3R0DHBq1SfqdLDYmAD8bs5SpJKPQq5ncWg/jcCAwEAAaOCATQwggEwMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTUovyfs8PYA9NX
-XAek0CSnwPIA1DCB7QYDVR0fBIHlMIHiMIHfoIHcoIHZhjVodHRwOi8vd3d3LnRy
-dXN0Y2VudGVyLmRlL2NybC92Mi90Y19jbGFzc18zX2NhX0lJLmNybIaBn2xkYXA6
-Ly93d3cudHJ1c3RjZW50ZXIuZGUvQ049VEMlMjBUcnVzdENlbnRlciUyMENsYXNz
-JTIwMyUyMENBJTIwSUksTz1UQyUyMFRydXN0Q2VudGVyJTIwR21iSCxPVT1yb290
-Y2VydHMsREM9dHJ1c3RjZW50ZXIsREM9ZGU/Y2VydGlmaWNhdGVSZXZvY2F0aW9u
-TGlzdD9iYXNlPzANBgkqhkiG9w0BAQUFAAOCAQEANmDkcPcGIEPZIxpC8vijsrlN
-irTzwppVMXzEO2eatN9NDoqTSheLG43KieHPOh6sHfGcMrSOWXaiQYUlN6AT0PV8
-TtXqluJucsG7Kv5sbviRmEb8yRtXW+rIGjs/sFGYPAfaLFkB2otE6OF0/ado3VS6
-g0bsyEa1+K+XwDsJHI/OcpY9M1ZwvJbL2NV9IJqDnxrcOfHFcqMRA/07QlIp2+gB
-95tejNaNhk4Z+rwcvsUhpYeeeC422wlxo3I0+GzjBgnyXlal092Y+tTmBvTwtiBj
-S+opvaqCZh77gaqnN60TGOaSw4HBM7uIHqHn4rS9MWwOUT1v+5ZWgOI2F9Hc5A==
------END CERTIFICATE-----
-
-# Issuer: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
-# Subject: CN=TC TrustCenter Universal CA I O=TC TrustCenter GmbH OU=TC TrustCenter Universal CA
-# Label: "TC TrustCenter Universal CA I"
-# Serial: 601024842042189035295619584734726
-# MD5 Fingerprint: 45:e1:a5:72:c5:a9:36:64:40:9e:f5:e4:58:84:67:8c
-# SHA1 Fingerprint: 6b:2f:34:ad:89:58:be:62:fd:b0:6b:5c:ce:bb:9d:d9:4f:4e:39:f3
-# SHA256 Fingerprint: eb:f3:c0:2a:87:89:b1:fb:7d:51:19:95:d6:63:b7:29:06:d9:13:ce:0d:5e:10:56:8a:8a:77:e2:58:61:67:e7
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIOHaIAAQAC7LdggHiNtgYwDQYJKoZIhvcNAQEFBQAweTEL
-MAkGA1UEBhMCREUxHDAaBgNVBAoTE1RDIFRydXN0Q2VudGVyIEdtYkgxJDAiBgNV
-BAsTG1RDIFRydXN0Q2VudGVyIFVuaXZlcnNhbCBDQTEmMCQGA1UEAxMdVEMgVHJ1
-c3RDZW50ZXIgVW5pdmVyc2FsIENBIEkwHhcNMDYwMzIyMTU1NDI4WhcNMjUxMjMx
-MjI1OTU5WjB5MQswCQYDVQQGEwJERTEcMBoGA1UEChMTVEMgVHJ1c3RDZW50ZXIg
-R21iSDEkMCIGA1UECxMbVEMgVHJ1c3RDZW50ZXIgVW5pdmVyc2FsIENBMSYwJAYD
-VQQDEx1UQyBUcnVzdENlbnRlciBVbml2ZXJzYWwgQ0EgSTCCASIwDQYJKoZIhvcN
-AQEBBQADggEPADCCAQoCggEBAKR3I5ZEr5D0MacQ9CaHnPM42Q9e3s9B6DGtxnSR
-JJZ4Hgmgm5qVSkr1YnwCqMqs+1oEdjneX/H5s7/zA1hV0qq34wQi0fiU2iIIAI3T
-fCZdzHd55yx4Oagmcw6iXSVphU9VDprvxrlE4Vc93x9UIuVvZaozhDrzznq+VZeu
-jRIPFDPiUHDDSYcTvFHe15gSWu86gzOSBnWLknwSaHtwag+1m7Z3W0hZneTvWq3z
-wZ7U10VOylY0Ibw+F1tvdwxIAUMpsN0/lm7mlaoMwCC2/T42J5zjXM9OgdwZu5GQ
-fezmlwQek8wiSdeXhrYTCjxDI3d+8NzmzSQfO4ObNDqDNOMCAwEAAaNjMGEwHwYD
-VR0jBBgwFoAUkqR1LKSevoFE63n8isWVpesQdXMwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFJKkdSyknr6BROt5/IrFlaXrEHVzMA0G
-CSqGSIb3DQEBBQUAA4IBAQAo0uCG1eb4e/CX3CJrO5UUVg8RMKWaTzqwOuAGy2X1
-7caXJ/4l8lfmXpWMPmRgFVp/Lw0BxbFg/UU1z/CyvwbZ71q+s2IhtNerNXxTPqYn
-8aEt2hojnczd7Dwtnic0XQ/CNnm8yUpiLe1r2X1BQ3y2qsrtYbE3ghUJGooWMNjs
-ydZHcnhLEEYUjl8Or+zHL6sQ17bxbuyGssLoDZJz3KL0Dzq/YSMQiZxIQG5wALPT
-ujdEWBF6AmqI8Dc08BnprNRlc/ZpjGSUOnmFKbAWKwyCPwacx/0QK54PLLae4xW/
-2TYcuiUaUj0a7CIMHOCkoj3w6DnPgcB77V0fb8XQC9eY
------END CERTIFICATE-----
-
-# Issuer: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
-# Subject: CN=Deutsche Telekom Root CA 2 O=Deutsche Telekom AG OU=T-TeleSec Trust Center
-# Label: "Deutsche Telekom Root CA 2"
-# Serial: 38
-# MD5 Fingerprint: 74:01:4a:91:b1:08:c4:58:ce:47:cd:f0:dd:11:53:08
-# SHA1 Fingerprint: 85:a4:08:c0:9c:19:3e:5d:51:58:7d:cd:d6:13:30:fd:8c:de:37:bf
-# SHA256 Fingerprint: b6:19:1a:50:d0:c3:97:7f:7d:a9:9b:cd:aa:c8:6a:22:7d:ae:b9:67:9e:c7:0b:a3:b0:c9:d9:22:71:c1:70:d3
------BEGIN CERTIFICATE-----
-MIIDnzCCAoegAwIBAgIBJjANBgkqhkiG9w0BAQUFADBxMQswCQYDVQQGEwJERTEc
-MBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxlU2Vj
-IFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290IENB
-IDIwHhcNOTkwNzA5MTIxMTAwWhcNMTkwNzA5MjM1OTAwWjBxMQswCQYDVQQGEwJE
-RTEcMBoGA1UEChMTRGV1dHNjaGUgVGVsZWtvbSBBRzEfMB0GA1UECxMWVC1UZWxl
-U2VjIFRydXN0IENlbnRlcjEjMCEGA1UEAxMaRGV1dHNjaGUgVGVsZWtvbSBSb290
-IENBIDIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrC6M14IspFLEU
-ha88EOQ5bzVdSq7d6mGNlUn0b2SjGmBmpKlAIoTZ1KXleJMOaAGtuU1cOs7TuKhC
-QN/Po7qCWWqSG6wcmtoIKyUn+WkjR/Hg6yx6m/UTAtB+NHzCnjwAWav12gz1Mjwr
-rFDa1sPeg5TKqAyZMg4ISFZbavva4VhYAUlfckE8FQYBjl2tqriTtM2e66foai1S
-NNs671x1Udrb8zH57nGYMsRUFUQM+ZtV7a3fGAigo4aKSe5TBY8ZTNXeWHmb0moc
-QqvF1afPaA+W5OFhmHZhyJF81j4A4pFQh+GdCuatl9Idxjp9y7zaAzTVjlsB9WoH
-txa2bkp/AgMBAAGjQjBAMB0GA1UdDgQWBBQxw3kbuvVT1xfgiXotF2wKsyudMzAP
-BgNVHRMECDAGAQH/AgEFMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
-AQEAlGRZrTlk5ynrE/5aw4sTV8gEJPB0d8Bg42f76Ymmg7+Wgnxu1MM9756Abrsp
-tJh6sTtU6zkXR34ajgv8HzFZMQSyzhfzLMdiNlXiItiJVbSYSKpk+tYcNthEeFpa
-IzpXl/V6ME+un2pMSyuOoAPjPuCp1NJ70rOo4nI8rZ7/gFnkm0W09juwzTkZmDLl
-6iFhkOQxIY40sfcvNUqFENrnijchvllj4PKFiDFT1FQUhXB59C4Gdyd1Lx+4ivn+
-xbrYNuSD7Odlt79jWvNGr4GUN9RBjNYj1h7P9WgbRGOiWrqnNVmh5XAFmw4jV5mU
-Cm26OWMohpLzGITY+9HPBVZkVw==
------END CERTIFICATE-----
-
-# Issuer: CN=ComSign Secured CA O=ComSign
-# Subject: CN=ComSign Secured CA O=ComSign
-# Label: "ComSign Secured CA"
-# Serial: 264725503855295744117309814499492384489
-# MD5 Fingerprint: 40:01:25:06:8d:21:43:6a:0e:43:00:9c:e7:43:f3:d5
-# SHA1 Fingerprint: f9:cd:0e:2c:da:76:24:c1:8f:bd:f0:f0:ab:b6:45:b8:f7:fe:d5:7a
-# SHA256 Fingerprint: 50:79:41:c7:44:60:a0:b4:70:86:22:0d:4e:99:32:57:2a:b5:d1:b5:bb:cb:89:80:ab:1c:b1:76:51:a8:44:d2
------BEGIN CERTIFICATE-----
-MIIDqzCCApOgAwIBAgIRAMcoRwmzuGxFjB36JPU2TukwDQYJKoZIhvcNAQEFBQAw
-PDEbMBkGA1UEAxMSQ29tU2lnbiBTZWN1cmVkIENBMRAwDgYDVQQKEwdDb21TaWdu
-MQswCQYDVQQGEwJJTDAeFw0wNDAzMjQxMTM3MjBaFw0yOTAzMTYxNTA0NTZaMDwx
-GzAZBgNVBAMTEkNvbVNpZ24gU2VjdXJlZCBDQTEQMA4GA1UEChMHQ29tU2lnbjEL
-MAkGA1UEBhMCSUwwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGtWhf
-HZQVw6QIVS3joFd67+l0Kru5fFdJGhFeTymHDEjWaueP1H5XJLkGieQcPOqs49oh
-gHMhCu95mGwfCP+hUH3ymBvJVG8+pSjsIQQPRbsHPaHA+iqYHU4Gk/v1iDurX8sW
-v+bznkqH7Rnqwp9D5PGBpX8QTz7RSmKtUxvLg/8HZaWSLWapW7ha9B20IZFKF3ue
-Mv5WJDmyVIRD9YTC2LxBkMyd1mja6YJQqTtoz7VdApRgFrFD2UNd3V2Hbuq7s8lr
-9gOUCXDeFhF6K+h2j0kQmHe5Y1yLM5d19guMsqtb3nQgJT/j8xH5h2iGNXHDHYwt
-6+UarA9z1YJZQIDTAgMBAAGjgacwgaQwDAYDVR0TBAUwAwEB/zBEBgNVHR8EPTA7
-MDmgN6A1hjNodHRwOi8vZmVkaXIuY29tc2lnbi5jby5pbC9jcmwvQ29tU2lnblNl
-Y3VyZWRDQS5jcmwwDgYDVR0PAQH/BAQDAgGGMB8GA1UdIwQYMBaAFMFL7XC29z58
-ADsAj8c+DkWfHl3sMB0GA1UdDgQWBBTBS+1wtvc+fAA7AI/HPg5Fnx5d7DANBgkq
-hkiG9w0BAQUFAAOCAQEAFs/ukhNQq3sUnjO2QiBq1BW9Cav8cujvR3qQrFHBZE7p
-iL1DRYHjZiM/EoZNGeQFsOY3wo3aBijJD4mkU6l1P7CW+6tMM1X5eCZGbxs2mPtC
-dsGCuY7e+0X5YxtiOzkGynd6qDwJz2w2PQ8KRUtpFhpFfTMDZflScZAmlaxMDPWL
-kz/MdXSFmLr/YnpNH4n+rr2UAJm/EaXc4HnFFgt9AmEd6oX5AhVP51qJThRv4zdL
-hfXBPGHg/QVBspJ/wx2g0K5SZGBrGMYmnNj1ZOQ2GmKfig8+/21OGVZOIJFsnzQz
-OjRXUDpvgV4GxvU+fE6OK85lBi5d0ipTdF7Tbieejw==
------END CERTIFICATE-----
-
-# Issuer: CN=Cybertrust Global Root O=Cybertrust, Inc
-# Subject: CN=Cybertrust Global Root O=Cybertrust, Inc
-# Label: "Cybertrust Global Root"
-# Serial: 4835703278459682877484360
-# MD5 Fingerprint: 72:e4:4a:87:e3:69:40:80:77:ea:bc:e3:f4:ff:f0:e1
-# SHA1 Fingerprint: 5f:43:e5:b1:bf:f8:78:8c:ac:1c:c7:ca:4a:9a:c6:22:2b:cc:34:c6
-# SHA256 Fingerprint: 96:0a:df:00:63:e9:63:56:75:0c:29:65:dd:0a:08:67:da:0b:9c:bd:6e:77:71:4a:ea:fb:23:49:ab:39:3d:a3
------BEGIN CERTIFICATE-----
-MIIDoTCCAomgAwIBAgILBAAAAAABD4WqLUgwDQYJKoZIhvcNAQEFBQAwOzEYMBYG
-A1UEChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2Jh
-bCBSb290MB4XDTA2MTIxNTA4MDAwMFoXDTIxMTIxNTA4MDAwMFowOzEYMBYGA1UE
-ChMPQ3liZXJ0cnVzdCwgSW5jMR8wHQYDVQQDExZDeWJlcnRydXN0IEdsb2JhbCBS
-b290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+Mi8vRRQZhP/8NN5
-7CPytxrHjoXxEnOmGaoQ25yiZXRadz5RfVb23CO21O1fWLE3TdVJDm71aofW0ozS
-J8bi/zafmGWgE07GKmSb1ZASzxQG9Dvj1Ci+6A74q05IlG2OlTEQXO2iLb3VOm2y
-HLtgwEZLAfVJrn5GitB0jaEMAs7u/OePuGtm839EAL9mJRQr3RAwHQeWP032a7iP
-t3sMpTjr3kfb1V05/Iin89cqdPHoWqI7n1C6poxFNcJQZZXcY4Lv3b93TZxiyWNz
-FtApD0mpSPCzqrdsxacwOUBdrsTiXSZT8M4cIwhhqJQZugRiQOwfOHB3EgZxpzAY
-XSUnpQIDAQABo4GlMIGiMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/
-MB0GA1UdDgQWBBS2CHsNesysIEyGVjJez6tuhS1wVzA/BgNVHR8EODA2MDSgMqAw
-hi5odHRwOi8vd3d3Mi5wdWJsaWMtdHJ1c3QuY29tL2NybC9jdC9jdHJvb3QuY3Js
-MB8GA1UdIwQYMBaAFLYIew16zKwgTIZWMl7Pq26FLXBXMA0GCSqGSIb3DQEBBQUA
-A4IBAQBW7wojoFROlZfJ+InaRcHUowAl9B8Tq7ejhVhpwjCt2BWKLePJzYFa+HMj
-Wqd8BfP9IjsO0QbE2zZMcwSO5bAi5MXzLqXZI+O4Tkogp24CJJ8iYGd7ix1yCcUx
-XOl5n4BHPa2hCwcUPUf/A2kaDAtE52Mlp3+yybh2hO0j9n0Hq0V+09+zv+mKts2o
-omcrUtW3ZfA5TGOgkXmTUg9U3YO7n9GPp1Nzw8v/MOx8BLjYRB+TX3EJIrduPuoc
-A06dGiBh+4E37F78CkWr1+cXVdCg6mCbpvbjjFspwgZgFJ0tl0ypkxWdYcQBX0jW
-WL1WMRJOEcgh4LMRkWXbtKaIOM5V
------END CERTIFICATE-----
-
-# Issuer: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
-# Subject: O=Chunghwa Telecom Co., Ltd. OU=ePKI Root Certification Authority
-# Label: "ePKI Root Certification Authority"
-# Serial: 28956088682735189655030529057352760477
-# MD5 Fingerprint: 1b:2e:00:ca:26:06:90:3d:ad:fe:6f:15:68:d3:6b:b3
-# SHA1 Fingerprint: 67:65:0d:f1:7e:8e:7e:5b:82:40:a4:f4:56:4b:cf:e2:3d:69:c6:f0
-# SHA256 Fingerprint: c0:a6:f4:dc:63:a2:4b:fd:cf:54:ef:2a:6a:08:2a:0a:72:de:35:80:3e:2f:f5:ff:52:7a:e5:d8:72:06:df:d5
------BEGIN CERTIFICATE-----
-MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBe
-MQswCQYDVQQGEwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0
-ZC4xKjAoBgNVBAsMIWVQS0kgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMxMjdaMF4xCzAJBgNVBAYTAlRXMSMw
-IQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEqMCgGA1UECwwhZVBL
-SSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEF
-AAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAH
-SyZbCUNsIZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAh
-ijHyl3SJCRImHJ7K2RKilTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3X
-DZoTM1PRYfl61dd4s5oz9wCGzh1NlDivqOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1
-TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX12ruOzjjK9SXDrkb5wdJ
-fzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0OWQqraffA
-sgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uU
-WH1+ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLS
-nT0IFaUQAS2zMnaolQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pH
-dmX2Os+PYhcZewoozRrSgx4hxyy/vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJip
-NiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXiZo1jDiVN1Rmy5nk3pyKdVDEC
-AwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/QkqiMAwGA1UdEwQF
-MAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH
-ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGB
-uvl2ICO1J2B01GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6Yl
-PwZpVnPDimZI+ymBV3QGypzqKOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkP
-JXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdVxrsStZf0X4OFunHB2WyBEXYKCrC/
-gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEPNXubrjlpC2JgQCA2
-j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+rGNm6
-5ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUB
-o2M3IUxExJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS
-/jQ6fbjpKdx2qcgw+BRxgMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2z
-Gp1iro2C6pSe3VkQw63d4k3jMdXH7OjysP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTE
-W9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmODBCEIZ43ygknQW/2xzQ+D
-hNQ+IIX3Sj0rnP0qCglN6oH4EZw=
------END CERTIFICATE-----
-
-# Issuer: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
-# Subject: CN=TÜBİTAK UEKAE Kök Sertifika Hizmet Sağlayıcısı - Sürüm 3 O=Türkiye Bilimsel ve Teknolojik Araştırma Kurumu - TÜBİTAK OU=Ulusal Elektronik ve Kriptoloji Araştırma Enstitüsü - UEKAE/Kamu Sertifikasyon Merkezi
-# Label: "T\xc3\x9c\x42\xC4\xB0TAK UEKAE K\xC3\xB6k Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1 - S\xC3\xBCr\xC3\xBCm 3"
-# Serial: 17
-# MD5 Fingerprint: ed:41:f5:8c:50:c5:2b:9c:73:e6:ee:6c:eb:c2:a8:26
-# SHA1 Fingerprint: 1b:4b:39:61:26:27:6b:64:91:a2:68:6d:d7:02:43:21:2d:1f:1d:96
-# SHA256 Fingerprint: e4:c7:34:30:d7:a5:b5:09:25:df:43:37:0a:0d:21:6e:9a:79:b9:d6:db:83:73:a0:c6:9e:b1:cc:31:c7:c5:2a
------BEGIN CERTIFICATE-----
-MIIFFzCCA/+gAwIBAgIBETANBgkqhkiG9w0BAQUFADCCASsxCzAJBgNVBAYTAlRS
-MRgwFgYDVQQHDA9HZWJ6ZSAtIEtvY2FlbGkxRzBFBgNVBAoMPlTDvHJraXllIEJp
-bGltc2VsIHZlIFRla25vbG9qaWsgQXJhxZ90xLFybWEgS3VydW11IC0gVMOcQsSw
-VEFLMUgwRgYDVQQLDD9VbHVzYWwgRWxla3Ryb25payB2ZSBLcmlwdG9sb2ppIEFy
-YcWfdMSxcm1hIEVuc3RpdMO8c8O8IC0gVUVLQUUxIzAhBgNVBAsMGkthbXUgU2Vy
-dGlmaWthc3lvbiBNZXJrZXppMUowSAYDVQQDDEFUw5xCxLBUQUsgVUVLQUUgS8O2
-ayBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsSAtIFPDvHLDvG0gMzAe
-Fw0wNzA4MjQxMTM3MDdaFw0xNzA4MjExMTM3MDdaMIIBKzELMAkGA1UEBhMCVFIx
-GDAWBgNVBAcMD0dlYnplIC0gS29jYWVsaTFHMEUGA1UECgw+VMO8cmtpeWUgQmls
-aW1zZWwgdmUgVGVrbm9sb2ppayBBcmHFn3TEsXJtYSBLdXJ1bXUgLSBUw5xCxLBU
-QUsxSDBGBgNVBAsMP1VsdXNhbCBFbGVrdHJvbmlrIHZlIEtyaXB0b2xvamkgQXJh
-xZ90xLFybWEgRW5zdGl0w7xzw7wgLSBVRUtBRTEjMCEGA1UECwwaS2FtdSBTZXJ0
-aWZpa2FzeW9uIE1lcmtlemkxSjBIBgNVBAMMQVTDnELEsFRBSyBVRUtBRSBLw7Zr
-IFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sxc8SxIC0gU8O8csO8bSAzMIIB
-IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAim1L/xCIOsP2fpTo6iBkcK4h
-gb46ezzb8R1Sf1n68yJMlaCQvEhOEav7t7WNeoMojCZG2E6VQIdhn8WebYGHV2yK
-O7Rm6sxA/OOqbLLLAdsyv9Lrhc+hDVXDWzhXcLh1xnnRFDDtG1hba+818qEhTsXO
-fJlfbLm4IpNQp81McGq+agV/E5wrHur+R84EpW+sky58K5+eeROR6Oqeyjh1jmKw
-lZMq5d/pXpduIF9fhHpEORlAHLpVK/swsoHvhOPc7Jg4OQOFCKlUAwUp8MmPi+oL
-hmUZEdPpCSPeaJMDyTYcIW7OjGbxmTDY17PDHfiBLqi9ggtm/oLL4eAagsNAgQID
-AQABo0IwQDAdBgNVHQ4EFgQUvYiHyY/2pAoLquvF/pEjnatKijIwDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAB18+kmP
-NOm3JpIWmgV050vQbTlswyb2zrgxvMTfvCr4N5EY3ATIZJkrGG2AA1nJrvhY0D7t
-wyOfaTyGOBye79oneNGEN3GKPEs5z35FBtYt2IpNeBLWrcLTy9LQQfMmNkqblWwM
-7uXRQydmwYj3erMgbOqwaSvHIOgMA8RBBZniP+Rr+KCGgceExh/VS4ESshYhLBOh
-gLJeDEoTniDYYkCrkOpkSi+sDQESeUWoL4cZaMjihccwsnX5OD+ywJO0a+IDRM5n
-oN+J1q2MdqMTw5RhK2vZbMEHCiIHhWyFJEapvj+LeISCfiQMnf2BN+MlqO02TpUs
-yZyQ2uypQjyttgI=
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327
-# Subject: CN=Buypass Class 2 CA 1 O=Buypass AS-983163327
-# Label: "Buypass Class 2 CA 1"
-# Serial: 1
-# MD5 Fingerprint: b8:08:9a:f0:03:cc:1b:0d:c8:6c:0b:76:a1:75:64:23
-# SHA1 Fingerprint: a0:a1:ab:90:c9:fc:84:7b:3b:12:61:e8:97:7d:5f:d3:22:61:d3:cc
-# SHA256 Fingerprint: 0f:4e:9c:dd:26:4b:02:55:50:d1:70:80:63:40:21:4f:e9:44:34:c9:b0:2f:69:7e:c7:10:fc:5f:ea:fb:5e:38
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBATANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
-Q2xhc3MgMiBDQSAxMB4XDTA2MTAxMzEwMjUwOVoXDTE2MTAxMzEwMjUwOVowSzEL
-MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
-VQQDDBRCdXlwYXNzIENsYXNzIDIgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAIs8B0XY9t/mx8q6jUPFR42wWsE425KEHK8T1A9vNkYgxC7McXA0
-ojTTNy7Y3Tp3L8DrKehc0rWpkTSHIln+zNvnma+WwajHQN2lFYxuyHyXA8vmIPLX
-l18xoS830r7uvqmtqEyeIWZDO6i88wmjONVZJMHCR3axiFyCO7srpgTXjAePzdVB
-HfCuuCkslFJgNJQ72uA40Z0zPhX0kzLFANq1KWYOOngPIVJfAuWSeyXTkh4vFZ2B
-5J2O6O+JzhRMVB0cgRJNcKi+EAUXfh/RuFdV7c27UsKwHnjCTTZoy1YmwVLBvXb3
-WNVyfh9EdrsAiR0WnVE1703CVu9r4Iw7DekCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUP42aWYv8e3uco684sDntkHGA1sgwDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQAVGn4TirnoB6NLJzKyQJHyIdFkhb5jatLP
-gcIV1Xp+DCmsNx4cfHZSldq1fyOhKXdlyTKdqC5Wq2B2zha0jX94wNWZUYN/Xtm+
-DKhQ7SLHrQVMdvvt7h5HZPb3J31cKA9FxVxiXqaakZG3Uxcu3K1gnZZkOb1naLKu
-BctN518fV4bVIJwo+28TOPX2EZL2fZleHwzoq0QkKXJAPTZSr4xYkHPB7GEseaHs
-h7U/2k3ZIQAw3pDaDtMaSKk+hQsUi4y8QZ5q9w5wwDX3OaJdZtB7WZ+oRxKaJyOk
-LY4ng5IgodcVf/EuGO70SH8vf/GhGLWhC5SgYiAynB321O+/TIho
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327
-# Subject: CN=Buypass Class 3 CA 1 O=Buypass AS-983163327
-# Label: "Buypass Class 3 CA 1"
-# Serial: 2
-# MD5 Fingerprint: df:3c:73:59:81:e7:39:50:81:04:4c:34:a2:cb:b3:7b
-# SHA1 Fingerprint: 61:57:3a:11:df:0e:d8:7e:d5:92:65:22:ea:d0:56:d7:44:b3:23:71
-# SHA256 Fingerprint: b7:b1:2b:17:1f:82:1d:aa:99:0c:d0:fe:50:87:b1:28:44:8b:a8:e5:18:4f:84:c5:1e:02:b5:c8:fb:96:2b:24
------BEGIN CERTIFICATE-----
-MIIDUzCCAjugAwIBAgIBAjANBgkqhkiG9w0BAQUFADBLMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxHTAbBgNVBAMMFEJ1eXBhc3Mg
-Q2xhc3MgMyBDQSAxMB4XDTA1MDUwOTE0MTMwM1oXDTE1MDUwOTE0MTMwM1owSzEL
-MAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MR0wGwYD
-VQQDDBRCdXlwYXNzIENsYXNzIDMgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEP
-ADCCAQoCggEBAKSO13TZKWTeXx+HgJHqTjnmGcZEC4DVC69TB4sSveZn8AKxifZg
-isRbsELRwCGoy+Gb72RRtqfPFfV0gGgEkKBYouZ0plNTVUhjP5JW3SROjvi6K//z
-NIqeKNc0n6wv1g/xpC+9UrJJhW05NfBEMJNGJPO251P7vGGvqaMU+8IXF4Rs4HyI
-+MkcVyzwPX6UvCWThOiaAJpFBUJXgPROztmuOfbIUxAMZTpHe2DC1vqRycZxbL2R
-hzyRhkmr8w+gbCZ2Xhysm3HljbybIR6c1jh+JIAVMYKWsUnTYjdbiAwKYjT+p0h+
-mbEwi5A3lRyoH6UsjfRVyNvdWQrCrXig9IsCAwEAAaNCMEAwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUOBTmyPCppAP0Tj4io1vy1uCtQHQwDgYDVR0PAQH/BAQD
-AgEGMA0GCSqGSIb3DQEBBQUAA4IBAQABZ6OMySU9E2NdFm/soT4JXJEVKirZgCFP
-Bdy7pYmrEzMqnji3jG8CcmPHc3ceCQa6Oyh7pEfJYWsICCD8igWKH7y6xsL+z27s
-EzNxZy5p+qksP2bAEllNC1QCkoS72xLvg3BweMhT+t/Gxv/ciC8HwEmdMldg0/L2
-mSlf56oBzKwzqBwKu5HEA6BvtjT5htOzdlSY9EqBs1OdTUDs5XcTRa9bqh/YL0yC
-e/4qxFi7T/ye/QNlGioOw6UgFpRreaaiErS7GqQjel/wroQk5PMr+4okoyeYZdow
-dXb8GZHo2+ubPzK/QJcHJrrM85SFSnonk8+QQtS4Wxam58tAA915
------END CERTIFICATE-----
-
-# Issuer: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş.
-# Subject: CN=EBG Elektronik Sertifika Hizmet Sağlayıcısı O=EBG Bilişim Teknolojileri ve Hizmetleri A.Ş.
-# Label: "EBG Elektronik Sertifika Hizmet Sa\xC4\x9Flay\xc4\xb1\x63\xc4\xb1s\xc4\xb1"
-# Serial: 5525761995591021570
-# MD5 Fingerprint: 2c:20:26:9d:cb:1a:4a:00:85:b5:b7:5a:ae:c2:01:37
-# SHA1 Fingerprint: 8c:96:ba:eb:dd:2b:07:07:48:ee:30:32:66:a0:f3:98:6e:7c:ae:58
-# SHA256 Fingerprint: 35:ae:5b:dd:d8:f7:ae:63:5c:ff:ba:56:82:a8:f0:0b:95:f4:84:62:c7:10:8e:e9:a0:e5:29:2b:07:4a:af:b2
------BEGIN CERTIFICATE-----
-MIIF5zCCA8+gAwIBAgIITK9zQhyOdAIwDQYJKoZIhvcNAQEFBQAwgYAxODA2BgNV
-BAMML0VCRyBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMTcwNQYDVQQKDC5FQkcgQmlsacWfaW0gVGVrbm9sb2ppbGVyaSB2ZSBIaXpt
-ZXRsZXJpIEEuxZ4uMQswCQYDVQQGEwJUUjAeFw0wNjA4MTcwMDIxMDlaFw0xNjA4
-MTQwMDMxMDlaMIGAMTgwNgYDVQQDDC9FQkcgRWxla3Ryb25payBTZXJ0aWZpa2Eg
-SGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTE3MDUGA1UECgwuRUJHIEJpbGnFn2ltIFRl
-a25vbG9qaWxlcmkgdmUgSGl6bWV0bGVyaSBBLsWeLjELMAkGA1UEBhMCVFIwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDuoIRh0DpqZhAy2DE4f6en5f2h
-4fuXd7hxlugTlkaDT7byX3JWbhNgpQGR4lvFzVcfd2NR/y8927k/qqk153nQ9dAk
-tiHq6yOU/im/+4mRDGSaBUorzAzu8T2bgmmkTPiab+ci2hC6X5L8GCcKqKpE+i4s
-tPtGmggDg3KriORqcsnlZR9uKg+ds+g75AxuetpX/dfreYteIAbTdgtsApWjluTL
-dlHRKJ2hGvxEok3MenaoDT2/F08iiFD9rrbskFBKW5+VQarKD7JK/oCZTqNGFav4
-c0JqwmZ2sQomFd2TkuzbqV9UIlKRcF0T6kjsbgNs2d1s/OsNA/+mgxKb8amTD8Um
-TDGyY5lhcucqZJnSuOl14nypqZoaqsNW2xCaPINStnuWt6yHd6i58mcLlEOzrz5z
-+kI2sSXFCjEmN1ZnuqMLfdb3ic1nobc6HmZP9qBVFCVMLDMNpkGMvQQxahByCp0O
-Lna9XvNRiYuoP1Vzv9s6xiQFlpJIqkuNKgPlV5EQ9GooFW5Hd4RcUXSfGenmHmMW
-OeMRFeNYGkS9y8RsZteEBt8w9DeiQyJ50hBs37vmExH8nYQKE3vwO9D8owrXieqW
-fo1IhR5kX9tUoqzVegJ5a9KK8GfaZXINFHDk6Y54jzJ0fFfy1tb0Nokb+Clsi7n2
-l9GkLqq+CxnCRelwXQIDAJ3Zo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB
-/wQEAwIBBjAdBgNVHQ4EFgQU587GT/wWZ5b6SqMHwQSny2re2kcwHwYDVR0jBBgw
-FoAU587GT/wWZ5b6SqMHwQSny2re2kcwDQYJKoZIhvcNAQEFBQADggIBAJuYml2+
-8ygjdsZs93/mQJ7ANtyVDR2tFcU22NU57/IeIl6zgrRdu0waypIN30ckHrMk2pGI
-6YNw3ZPX6bqz3xZaPt7gyPvT/Wwp+BVGoGgmzJNSroIBk5DKd8pNSe/iWtkqvTDO
-TLKBtjDOWU/aWR1qeqRFsIImgYZ29fUQALjuswnoT4cCB64kXPBfrAowzIpAoHME
-wfuJJPaaHFy3PApnNgUIMbOv2AFoKuB4j3TeuFGkjGwgPaL7s9QJ/XvCgKqTbCmY
-Iai7FvOpEl90tYeY8pUm3zTvilORiF0alKM/fCL414i6poyWqD1SNGKfAB5UVUJn
-xk1Gj7sURT0KlhaOEKGXmdXTMIXM3rRyt7yKPBgpaP3ccQfuJDlq+u2lrDgv+R4Q
-DgZxGhBM/nV+/x5XOULK1+EVoVZVWRvRo68R2E7DpSvvkL/A7IITW43WciyTTo9q
-Kd+FPNMN4KIYEsxVL0e3p5sC/kH2iExt2qkBR4NkJ2IQgtYSe14DHzSpyZH+r11t
-hie3I6p1GMog57AP14kOpmciY/SDQSsGS7tY1dHXt7kQY9iJSrSq3RZj9W6+YKH4
-7ejWkE8axsWgKdOnIaj1Wjz3x0miIZpKlVIglnKaZsv30oZDfCK+lvm9AahH3eU7
-QPl1K5srRmSGjR70j/sHd9DqSaIcjVIUpgqT
------END CERTIFICATE-----
-
-# Issuer: O=certSIGN OU=certSIGN ROOT CA
-# Subject: O=certSIGN OU=certSIGN ROOT CA
-# Label: "certSIGN ROOT CA"
-# Serial: 35210227249154
-# MD5 Fingerprint: 18:98:c0:d6:e9:3a:fc:f9:b0:f5:0c:f7:4b:01:44:17
-# SHA1 Fingerprint: fa:b7:ee:36:97:26:62:fb:2d:b0:2a:f6:bf:03:fd:e8:7c:4b:2f:9b
-# SHA256 Fingerprint: ea:a9:62:c4:fa:4a:6b:af:eb:e4:15:19:6d:35:1c:cd:88:8d:4f:53:f3:fa:8a:e6:d7:c4:66:a9:4e:60:42:bb
------BEGIN CERTIFICATE-----
-MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYT
-AlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBD
-QTAeFw0wNjA3MDQxNzIwMDRaFw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJP
-MREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTCC
-ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7IJUqOtdu0KBuqV5Do
-0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHHrfAQ
-UySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5d
-RdY4zTW2ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQ
-OA7+j0xbm0bqQfWwCHTD0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwv
-JoIQ4uNllAoEwF73XVv4EOLQunpL+943AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08C
-AwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAcYwHQYDVR0O
-BBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IBAQA+0hyJ
-LjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecY
-MnQ8SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ
-44gx+FkagQnIl6Z0x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6I
-Jd1hJyMctTEHBDa0GpC9oHRxUIltvBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNw
-i/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7NzTogVZ96edhBiIL5VaZVDADlN
-9u6wWk5JRFRYX0KD
------END CERTIFICATE-----
-
-# Issuer: CN=CNNIC ROOT O=CNNIC
-# Subject: CN=CNNIC ROOT O=CNNIC
-# Label: "CNNIC ROOT"
-# Serial: 1228079105
-# MD5 Fingerprint: 21:bc:82:ab:49:c4:13:3b:4b:b2:2b:5c:6b:90:9c:19
-# SHA1 Fingerprint: 8b:af:4c:9b:1d:f0:2a:92:f7:da:12:8e:b9:1b:ac:f4:98:60:4b:6f
-# SHA256 Fingerprint: e2:83:93:77:3d:a8:45:a6:79:f2:08:0c:c7:fb:44:a3:b7:a1:c3:79:2c:b7:eb:77:29:fd:cb:6a:8d:99:ae:a7
------BEGIN CERTIFICATE-----
-MIIDVTCCAj2gAwIBAgIESTMAATANBgkqhkiG9w0BAQUFADAyMQswCQYDVQQGEwJD
-TjEOMAwGA1UEChMFQ05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwHhcNMDcwNDE2
-MDcwOTE0WhcNMjcwNDE2MDcwOTE0WjAyMQswCQYDVQQGEwJDTjEOMAwGA1UEChMF
-Q05OSUMxEzARBgNVBAMTCkNOTklDIFJPT1QwggEiMA0GCSqGSIb3DQEBAQUAA4IB
-DwAwggEKAoIBAQDTNfc/c3et6FtzF8LRb+1VvG7q6KR5smzDo+/hn7E7SIX1mlwh
-IhAsxYLO2uOabjfhhyzcuQxauohV3/2q2x8x6gHx3zkBwRP9SFIhxFXf2tizVHa6
-dLG3fdfA6PZZxU3Iva0fFNrfWEQlMhkqx35+jq44sDB7R3IJMfAw28Mbdim7aXZO
-V/kbZKKTVrdvmW7bCgScEeOAH8tjlBAKqeFkgjH5jCftppkA9nCTGPihNIaj3XrC
-GHn2emU1z5DrvTOTn1OrczvmmzQgLx3vqR1jGqCA2wMv+SYahtKNu6m+UjqHZ0gN
-v7Sg2Ca+I19zN38m5pIEo3/PIKe38zrKy5nLAgMBAAGjczBxMBEGCWCGSAGG+EIB
-AQQEAwIABzAfBgNVHSMEGDAWgBRl8jGtKvf33VKWCscCwQ7vptU7ETAPBgNVHRMB
-Af8EBTADAQH/MAsGA1UdDwQEAwIB/jAdBgNVHQ4EFgQUZfIxrSr3991SlgrHAsEO
-76bVOxEwDQYJKoZIhvcNAQEFBQADggEBAEs17szkrr/Dbq2flTtLP1se31cpolnK
-OOK5Gv+e5m4y3R6u6jW39ZORTtpC4cMXYFDy0VwmuYK36m3knITnA3kXr5g9lNvH
-ugDnuL8BV8F3RTIMO/G0HAiw/VGgod2aHRM2mm23xzy54cXZF/qD1T0VoDy7Hgvi
-yJA/qIYM/PmLXoXLT1tLYhFHxUV8BS9BsZ4QaRuZluBVeftOhpm4lNqGOGqTo+fL
-buXf6iFViZx9fX+Y9QCJ7uOEwFyWtcVG6kbghVW2G8kS1sHNzYDzAgE8yGnLRUhj
-2JTQ7IUOO04RZfSCjKY9ri4ilAnIXOo8gV0WKgOXFlUJ24pBgp5mmxE=
------END CERTIFICATE-----
-
-# Issuer: O=Japanese Government OU=ApplicationCA
-# Subject: O=Japanese Government OU=ApplicationCA
-# Label: "ApplicationCA - Japanese Government"
-# Serial: 49
-# MD5 Fingerprint: 7e:23:4e:5b:a7:a5:b4:25:e9:00:07:74:11:62:ae:d6
-# SHA1 Fingerprint: 7f:8a:b0:cf:d0:51:87:6a:66:f3:36:0f:47:c8:8d:8c:d3:35:fc:74
-# SHA256 Fingerprint: 2d:47:43:7d:e1:79:51:21:5a:12:f3:c5:8e:51:c7:29:a5:80:26:ef:1f:cc:0a:5f:b3:d9:dc:01:2f:60:0d:19
------BEGIN CERTIFICATE-----
-MIIDoDCCAoigAwIBAgIBMTANBgkqhkiG9w0BAQUFADBDMQswCQYDVQQGEwJKUDEc
-MBoGA1UEChMTSmFwYW5lc2UgR292ZXJubWVudDEWMBQGA1UECxMNQXBwbGljYXRp
-b25DQTAeFw0wNzEyMTIxNTAwMDBaFw0xNzEyMTIxNTAwMDBaMEMxCzAJBgNVBAYT
-AkpQMRwwGgYDVQQKExNKYXBhbmVzZSBHb3Zlcm5tZW50MRYwFAYDVQQLEw1BcHBs
-aWNhdGlvbkNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp23gdE6H
-j6UG3mii24aZS2QNcfAKBZuOquHMLtJqO8F6tJdhjYq+xpqcBrSGUeQ3DnR4fl+K
-f5Sk10cI/VBaVuRorChzoHvpfxiSQE8tnfWuREhzNgaeZCw7NCPbXCbkcXmP1G55
-IrmTwcrNwVbtiGrXoDkhBFcsovW8R0FPXjQilbUfKW1eSvNNcr5BViCH/OlQR9cw
-FO5cjFW6WY2H/CPek9AEjP3vbb3QesmlOmpyM8ZKDQUXKi17safY1vC+9D/qDiht
-QWEjdnjDuGWk81quzMKq2edY3rZ+nYVunyoKb58DKTCXKB28t89UKU5RMfkntigm
-/qJj5kEW8DOYRwIDAQABo4GeMIGbMB0GA1UdDgQWBBRUWssmP3HMlEYNllPqa0jQ
-k/5CdTAOBgNVHQ8BAf8EBAMCAQYwWQYDVR0RBFIwUKROMEwxCzAJBgNVBAYTAkpQ
-MRgwFgYDVQQKDA/ml6XmnKzlm73mlL/lupwxIzAhBgNVBAsMGuOCouODl+ODquOC
-seODvOOCt+ODp+ODs0NBMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQAD
-ggEBADlqRHZ3ODrso2dGD/mLBqj7apAxzn7s2tGJfHrrLgy9mTLnsCTWw//1sogJ
-hyzjVOGjprIIC8CFqMjSnHH2HZ9g/DgzE+Ge3Atf2hZQKXsvcJEPmbo0NI2VdMV+
-eKlmXb3KIXdCEKxmJj3ekav9FfBv7WxfEPjzFvYDio+nEhEMy/0/ecGc/WLuo89U
-DNErXxc+4z6/wCs+CZv+iKZ+tJIX/COUgb1up8WMwusRRdv4QcmWdupwX3kSa+Sj
-B1oF7ydJzyGfikwJcGapJsErEU4z0g781mzSDjJkaP+tBXhfAx2o45CsJOAPQKdL
-rosot4LKGAfmt1t06SAZf7IbiVQ=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
-# Subject: CN=GeoTrust Primary Certification Authority - G3 O=GeoTrust Inc. OU=(c) 2008 GeoTrust Inc. - For authorized use only
-# Label: "GeoTrust Primary Certification Authority - G3"
-# Serial: 28809105769928564313984085209975885599
-# MD5 Fingerprint: b5:e8:34:36:c9:10:44:58:48:70:6d:2e:83:d4:b8:05
-# SHA1 Fingerprint: 03:9e:ed:b8:0b:e7:a0:3c:69:53:89:3b:20:d2:d9:32:3a:4c:2a:fd
-# SHA256 Fingerprint: b4:78:b8:12:25:0d:f8:78:63:5c:2a:a7:ec:7d:15:5e:aa:62:5e:e8:29:16:e2:cd:29:43:61:88:6c:d1:fb:d4
------BEGIN CERTIFICATE-----
-MIID/jCCAuagAwIBAgIQFaxulBmyeUtB9iepwxgPHzANBgkqhkiG9w0BAQsFADCB
-mDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsT
-MChjKSAyMDA4IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25s
-eTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhv
-cml0eSAtIEczMB4XDTA4MDQwMjAwMDAwMFoXDTM3MTIwMTIzNTk1OVowgZgxCzAJ
-BgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykg
-MjAwOCBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0
-BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkg
-LSBHMzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANziXmJYHTNXOTIz
-+uvLh4yn1ErdBojqZI4xmKU4kB6Yzy5jK/BGvESyiaHAKAxJcCGVn2TAppMSAmUm
-hsalifD614SgcK9PGpc/BkTVyetyEH3kMSj7HGHmKAdEc5IiaacDiGydY8hS2pgn
-5whMcD60yRLBxWeDXTPzAxHsatBT4tG6NmCUgLthY2xbF37fQJQeqw3CIShwiP/W
-JmxsYAQlTlV+fe+/lEjetx3dcI0FX4ilm/LC7urRQEFtYjgdVgbFA0dRIBn8exAL
-DmKudlW/X3e+PkkBUz2YJQN2JFodtNuJ6nnltrM7P7pMKEF/BqxqjsHQ9gUdfeZC
-huOl1UcCAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw
-HQYDVR0OBBYEFMR5yo6hTgMdHNxr2zFblD4/MH8tMA0GCSqGSIb3DQEBCwUAA4IB
-AQAtxRPPVoB7eni9n64smefv2t+UXglpp+duaIy9cr5HqQ6XErhK8WTTOd8lNNTB
-zU6B8A8ExCSzNJbGpqow32hhc9f5joWJ7w5elShKKiePEI4ufIbEAp7aDHdlDkQN
-kv39sxY2+hENHYwOB4lqKVb3cvTdFZx3NWZXqxNT2I7BQMXXExZacse3aQHEerGD
-AWh9jUGhlBjBJVz88P6DAod8DQ3PLghcSkANPuyBYeYk28rgDi0Hsj5W3I31QYUH
-SJsMC8tJP33st/3LjWeJGqvtux6jAAgIFyqCXDFdRootD4abdNlF+9RAsXqqaC2G
-spki4cErx5z481+oghLrGREt
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA - G2 O=thawte, Inc. OU=(c) 2007 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA - G2"
-# Serial: 71758320672825410020661621085256472406
-# MD5 Fingerprint: 74:9d:ea:60:24:c4:fd:22:53:3e:cc:3a:72:d9:29:4f
-# SHA1 Fingerprint: aa:db:bc:22:23:8f:c4:01:a1:27:bb:38:dd:f4:1d:db:08:9e:f0:12
-# SHA256 Fingerprint: a4:31:0d:50:af:18:a6:44:71:90:37:2a:86:af:af:8b:95:1f:fb:43:1d:83:7f:1e:56:88:b4:59:71:ed:15:57
------BEGIN CERTIFICATE-----
-MIICiDCCAg2gAwIBAgIQNfwmXNmET8k9Jj1Xm67XVjAKBggqhkjOPQQDAzCBhDEL
-MAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjE4MDYGA1UECxMvKGMp
-IDIwMDcgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAi
-BgNVBAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMjAeFw0wNzExMDUwMDAw
-MDBaFw0zODAxMTgyMzU5NTlaMIGEMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhh
-d3RlLCBJbmMuMTgwNgYDVQQLEy8oYykgMjAwNyB0aGF3dGUsIEluYy4gLSBGb3Ig
-YXV0aG9yaXplZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9v
-dCBDQSAtIEcyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEotWcgnuVnfFSeIf+iha/
-BebfowJPDQfGAFG6DAJSLSKkQjnE/o/qycG+1E3/n3qe4rF8mq2nhglzh9HnmuN6
-papu+7qzcMBniKI11KOasf2twu8x+qi58/sIxpHR+ymVo0IwQDAPBgNVHRMBAf8E
-BTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUmtgAMADna3+FGO6Lts6K
-DPgR4bswCgYIKoZIzj0EAwMDaQAwZgIxAN344FdHW6fmCsO99YCKlzUNG4k8VIZ3
-KMqh9HneteY4sPBlcIx/AlTCv//YoT7ZzwIxAMSNlPzcU9LcnXgWHxUzI1NS41ox
-XZ3Krr0TKUQNJ1uo52icEvdYPy5yAlejj6EULg==
------END CERTIFICATE-----
-
-# Issuer: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
-# Subject: CN=thawte Primary Root CA - G3 O=thawte, Inc. OU=Certification Services Division/(c) 2008 thawte, Inc. - For authorized use only
-# Label: "thawte Primary Root CA - G3"
-# Serial: 127614157056681299805556476275995414779
-# MD5 Fingerprint: fb:1b:5d:43:8a:94:cd:44:c6:76:f2:43:4b:47:e7:31
-# SHA1 Fingerprint: f1:8b:53:8d:1b:e9:03:b6:a6:f0:56:43:5b:17:15:89:ca:f3:6b:f2
-# SHA256 Fingerprint: 4b:03:f4:58:07:ad:70:f2:1b:fc:2c:ae:71:c9:fd:e4:60:4c:06:4c:f5:ff:b6:86:ba:e5:db:aa:d7:fd:d3:4c
------BEGIN CERTIFICATE-----
-MIIEKjCCAxKgAwIBAgIQYAGXt0an6rS0mtZLL/eQ+zANBgkqhkiG9w0BAQsFADCB
-rjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf
-Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw
-MDggdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxJDAiBgNV
-BAMTG3RoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EgLSBHMzAeFw0wODA0MDIwMDAwMDBa
-Fw0zNzEyMDEyMzU5NTlaMIGuMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMdGhhd3Rl
-LCBJbmMuMSgwJgYDVQQLEx9DZXJ0aWZpY2F0aW9uIFNlcnZpY2VzIERpdmlzaW9u
-MTgwNgYDVQQLEy8oYykgMjAwOCB0aGF3dGUsIEluYy4gLSBGb3IgYXV0aG9yaXpl
-ZCB1c2Ugb25seTEkMCIGA1UEAxMbdGhhd3RlIFByaW1hcnkgUm9vdCBDQSAtIEcz
-MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsr8nLPvb2FvdeHsbnndm
-gcs+vHyu86YnmjSjaDFxODNi5PNxZnmxqWWjpYvVj2AtP0LMqmsywCPLLEHd5N/8
-YZzic7IilRFDGF/Eth9XbAoFWCLINkw6fKXRz4aviKdEAhN0cXMKQlkC+BsUa0Lf
-b1+6a4KinVvnSr0eAXLbS3ToO39/fR8EtCab4LRarEc9VbjXsCZSKAExQGbY2SS9
-9irY7CFJXJv2eul/VTV+lmuNk5Mny5K76qxAwJ/C+IDPXfRa3M50hqY+bAtTyr2S
-zhkGcuYMXDhpxwTWvGzOW/b3aJzcJRVIiKHpqfiYnODz1TEoYRFsZ5aNOZnLwkUk
-OQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV
-HQ4EFgQUrWyqlGCc7eT/+j4KdCtjA/e2Wb8wDQYJKoZIhvcNAQELBQADggEBABpA
-2JVlrAmSicY59BDlqQ5mU1143vokkbvnRFHfxhY0Cu9qRFHqKweKA3rD6z8KLFIW
-oCtDuSWQP3CpMyVtRRooOyfPqsMpQhvfO0zAMzRbQYi/aytlryjvsvXDqmbOe1bu
-t8jLZ8HJnBoYuMTDSQPxYA5QzUbF83d597YV4Djbxy8ooAw/dyZ02SUS2jHaGh7c
-KUGRIjxpp7sC8rZcJwOJ9Abqm+RyguOhCcHpABnTPtRwa7pxpqpYrvS76Wy274fM
-m7v/OeZWYdMKp8RcTGB7BXcmer/YB1IsYvdwY9k5vG8cwnncdimvzsUsZAReiDZu
-MdRAGmI0Nj81Aa6sY6A=
------END CERTIFICATE-----
-
-# Issuer: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
-# Subject: CN=GeoTrust Primary Certification Authority - G2 O=GeoTrust Inc. OU=(c) 2007 GeoTrust Inc. - For authorized use only
-# Label: "GeoTrust Primary Certification Authority - G2"
-# Serial: 80682863203381065782177908751794619243
-# MD5 Fingerprint: 01:5e:d8:6b:bd:6f:3d:8e:a1:31:f8:12:e0:98:73:6a
-# SHA1 Fingerprint: 8d:17:84:d5:37:f3:03:7d:ec:70:fe:57:8b:51:9a:99:e6:10:d7:b0
-# SHA256 Fingerprint: 5e:db:7a:c4:3b:82:a0:6a:87:61:e8:d7:be:49:79:eb:f2:61:1f:7d:d7:9b:f9:1c:1c:6b:56:6a:21:9e:d7:66
------BEGIN CERTIFICATE-----
-MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL
-MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj
-KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2
-MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
-eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV
-BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw
-NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV
-BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH
-MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL
-So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal
-tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG
-CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT
-qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz
-rD6ogRLQy7rQkgu2npaqBA+K
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Universal Root Certification Authority O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2008 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Universal Root Certification Authority"
-# Serial: 85209574734084581917763752644031726877
-# MD5 Fingerprint: 8e:ad:b5:01:aa:4d:81:e4:8c:1d:d1:e1:14:00:95:19
-# SHA1 Fingerprint: 36:79:ca:35:66:87:72:30:4d:30:a5:fb:87:3b:0f:a7:7b:b7:0d:54
-# SHA256 Fingerprint: 23:99:56:11:27:a5:71:25:de:8c:ef:ea:61:0d:df:2f:a0:78:b5:c8:06:7f:4e:82:82:90:bf:b8:60:e8:4b:3c
------BEGIN CERTIFICATE-----
-MIIEuTCCA6GgAwIBAgIQQBrEZCGzEyEDDrvkEhrFHTANBgkqhkiG9w0BAQsFADCB
-vTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL
-ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwOCBWZXJp
-U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MTgwNgYDVQQDEy9W
-ZXJpU2lnbiBVbml2ZXJzYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAe
-Fw0wODA0MDIwMDAwMDBaFw0zNzEyMDEyMzU5NTlaMIG9MQswCQYDVQQGEwJVUzEX
-MBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdBgNVBAsTFlZlcmlTaWduIFRydXN0
-IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAyMDA4IFZlcmlTaWduLCBJbmMuIC0gRm9y
-IGF1dGhvcml6ZWQgdXNlIG9ubHkxODA2BgNVBAMTL1ZlcmlTaWduIFVuaXZlcnNh
-bCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIIBIjANBgkqhkiG9w0BAQEF
-AAOCAQ8AMIIBCgKCAQEAx2E3XrEBNNti1xWb/1hajCMj1mCOkdeQmIN65lgZOIzF
-9uVkhbSicfvtvbnazU0AtMgtc6XHaXGVHzk8skQHnOgO+k1KxCHfKWGPMiJhgsWH
-H26MfF8WIFFE0XBPV+rjHOPMee5Y2A7Cs0WTwCznmhcrewA3ekEzeOEz4vMQGn+H
-LL729fdC4uW/h2KJXwBL38Xd5HVEMkE6HnFuacsLdUYI0crSK5XQz/u5QGtkjFdN
-/BMReYTtXlT2NJ8IAfMQJQYXStrxHXpma5hgZqTZ79IugvHw7wnqRMkVauIDbjPT
-rJ9VAMf2CGqUuV/c4DPxhGD5WycRtPwW8rtWaoAljQIDAQABo4GyMIGvMA8GA1Ud
-EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMG0GCCsGAQUFBwEMBGEwX6FdoFsw
-WTBXMFUWCWltYWdlL2dpZjAhMB8wBwYFKw4DAhoEFI/l0xqGrI2Oa8PPgGrUSBgs
-exkuMCUWI2h0dHA6Ly9sb2dvLnZlcmlzaWduLmNvbS92c2xvZ28uZ2lmMB0GA1Ud
-DgQWBBS2d/ppSEefUxLVwuoHMnYH0ZcHGTANBgkqhkiG9w0BAQsFAAOCAQEASvj4
-sAPmLGd75JR3Y8xuTPl9Dg3cyLk1uXBPY/ok+myDjEedO2Pzmvl2MpWRsXe8rJq+
-seQxIcaBlVZaDrHC1LGmWazxY8u4TB1ZkErvkBYoH1quEPuBUDgMbMzxPcP1Y+Oz
-4yHJJDnp/RVmRvQbEdBNc6N9Rvk97ahfYtTxP/jgdFcrGJ2BtMQo2pSXpXDrrB2+
-BxHw1dvd5Yzw1TKwg+ZX4o+/vqGqvz0dtdQ46tewXDpPaj+PwGZsY6rp2aQW9IHR
-lRQOfc2VNNnSj3BzgXucfr2YYdhFh5iQxeuGMMY1v/D/w1WIg0vvBZIGcfK4mJO3
-7M2CYfE45k+XmCpajQ==
------END CERTIFICATE-----
-
-# Issuer: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
-# Subject: CN=VeriSign Class 3 Public Primary Certification Authority - G4 O=VeriSign, Inc. OU=VeriSign Trust Network/(c) 2007 VeriSign, Inc. - For authorized use only
-# Label: "VeriSign Class 3 Public Primary Certification Authority - G4"
-# Serial: 63143484348153506665311985501458640051
-# MD5 Fingerprint: 3a:52:e1:e7:fd:6f:3a:e3:6f:f3:6f:99:1b:f9:22:41
-# SHA1 Fingerprint: 22:d5:d8:df:8f:02:31:d1:8d:f7:9d:b7:cf:8a:2d:64:c9:3f:6c:3a
-# SHA256 Fingerprint: 69:dd:d7:ea:90:bb:57:c9:3e:13:5d:c8:5e:a6:fc:d5:48:0b:60:32:39:bd:c4:54:fc:75:8b:2a:26:cf:7f:79
------BEGIN CERTIFICATE-----
-MIIDhDCCAwqgAwIBAgIQL4D+I4wOIg9IZxIokYesszAKBggqhkjOPQQDAzCByjEL
-MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW
-ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2ln
-biwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJp
-U2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9y
-aXR5IC0gRzQwHhcNMDcxMTA1MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCByjELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZWZXJp
-U2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNyBWZXJpU2lnbiwg
-SW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxWZXJpU2ln
-biBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5
-IC0gRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAASnVnp8Utpkmw4tXNherJI9/gHm
-GUo9FANL+mAnINmDiWn6VMaaGF5VKmTeBvaNSjutEDxlPZCIBIngMGGzrl0Bp3ve
-fLK+ymVhAIau2o970ImtTR1ZmkGxvEeA3J5iw/mjgbIwga8wDwYDVR0TAQH/BAUw
-AwEB/zAOBgNVHQ8BAf8EBAMCAQYwbQYIKwYBBQUHAQwEYTBfoV2gWzBZMFcwVRYJ
-aW1hZ2UvZ2lmMCEwHzAHBgUrDgMCGgQUj+XTGoasjY5rw8+AatRIGCx7GS4wJRYj
-aHR0cDovL2xvZ28udmVyaXNpZ24uY29tL3ZzbG9nby5naWYwHQYDVR0OBBYEFLMW
-kf3upm7ktS5Jj4d4gYDs5bG1MAoGCCqGSM49BAMDA2gAMGUCMGYhDBgmYFo4e1ZC
-4Kf8NoRRkSAsdk1DPcQdhCPQrNZ8NQbOzWm9kA3bbEhCHQ6qQgIxAJw9SDkjOVga
-FRJZap7v1VmyHVIsmXHNxynfGyphe3HR3vPA5Q06Sqotp9iGKt0uEA==
------END CERTIFICATE-----
-
-# Issuer: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
-# Subject: CN=NetLock Arany (Class Gold) Főtanúsítvány O=NetLock Kft. OU=Tanúsítványkiadók (Certification Services)
-# Label: "NetLock Arany (Class Gold) Főtanúsítvány"
-# Serial: 80544274841616
-# MD5 Fingerprint: c5:a1:b7:ff:73:dd:d6:d7:34:32:18:df:fc:3c:ad:88
-# SHA1 Fingerprint: 06:08:3f:59:3f:15:a1:04:a0:69:a4:6b:a9:03:d0:06:b7:97:09:91
-# SHA256 Fingerprint: 6c:61:da:c3:a2:de:f0:31:50:6b:e0:36:d2:a6:fe:40:19:94:fb:d1:3d:f9:c8:d4:66:59:92:74:c4:46:ec:98
------BEGIN CERTIFICATE-----
-MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQG
-EwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3
-MDUGA1UECwwuVGFuw7pzw610dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNl
-cnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBBcmFueSAoQ2xhc3MgR29sZCkgRsWR
-dGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgxMjA2MTUwODIxWjCB
-pzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxOZXRM
-b2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlm
-aWNhdGlvbiBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNz
-IEdvbGQpIEbFkXRhbsO6c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
-MIIBCgKCAQEAxCRec75LbRTDofTjl5Bu0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrT
-lF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw/HpYzY6b7cNGbIRwXdrz
-AZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAkH3B5r9s5
-VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRG
-ILdwfzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2
-BJtr+UBdADTHLpl1neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAG
-AQH/AgEEMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2M
-U9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwWqZw8UQCgwBEIBaeZ5m8BiFRh
-bvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTtaYtOUZcTh5m2C
-+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC
-bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2F
-uLjbvrW5KfnaNwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2
-XjG4Kvte9nHfRCaexOYNkbQudZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E=
------END CERTIFICATE-----
-
-# Issuer: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
-# Subject: CN=Staat der Nederlanden Root CA - G2 O=Staat der Nederlanden
-# Label: "Staat der Nederlanden Root CA - G2"
-# Serial: 10000012
-# MD5 Fingerprint: 7c:a5:0f:f8:5b:9a:7d:6d:30:ae:54:5a:e3:42:a2:8a
-# SHA1 Fingerprint: 59:af:82:79:91:86:c7:b4:75:07:cb:cf:03:57:46:eb:04:dd:b7:16
-# SHA256 Fingerprint: 66:8c:83:94:7d:a6:3b:72:4b:ec:e1:74:3c:31:a0:e6:ae:d0:db:8e:c5:b3:1b:e3:77:bb:78:4f:91:b6:71:6f
------BEGIN CERTIFICATE-----
-MIIFyjCCA7KgAwIBAgIEAJiWjDANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJO
-TDEeMBwGA1UECgwVU3RhYXQgZGVyIE5lZGVybGFuZGVuMSswKQYDVQQDDCJTdGFh
-dCBkZXIgTmVkZXJsYW5kZW4gUm9vdCBDQSAtIEcyMB4XDTA4MDMyNjExMTgxN1oX
-DTIwMDMyNTExMDMxMFowWjELMAkGA1UEBhMCTkwxHjAcBgNVBAoMFVN0YWF0IGRl
-ciBOZWRlcmxhbmRlbjErMCkGA1UEAwwiU3RhYXQgZGVyIE5lZGVybGFuZGVuIFJv
-b3QgQ0EgLSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMVZ5291
-qj5LnLW4rJ4L5PnZyqtdj7U5EILXr1HgO+EASGrP2uEGQxGZqhQlEq0i6ABtQ8Sp
-uOUfiUtnvWFI7/3S4GCI5bkYYCjDdyutsDeqN95kWSpGV+RLufg3fNU254DBtvPU
-Z5uW6M7XxgpT0GtJlvOjCwV3SPcl5XCsMBQgJeN/dVrlSPhOewMHBPqCYYdu8DvE
-pMfQ9XQ+pV0aCPKbJdL2rAQmPlU6Yiile7Iwr/g3wtG61jj99O9JMDeZJiFIhQGp
-5Rbn3JBV3w/oOM2ZNyFPXfUib2rFEhZgF1XyZWampzCROME4HYYEhLoaJXhena/M
-UGDWE4dS7WMfbWV9whUYdMrhfmQpjHLYFhN9C0lK8SgbIHRrxT3dsKpICT0ugpTN
-GmXZK4iambwYfp/ufWZ8Pr2UuIHOzZgweMFvZ9C+X+Bo7d7iscksWXiSqt8rYGPy
-5V6548r6f1CGPqI0GAwJaCgRHOThuVw+R7oyPxjMW4T182t0xHJ04eOLoEq9jWYv
-6q012iDTiIJh8BIitrzQ1aTsr1SIJSQ8p22xcik/Plemf1WvbibG/ufMQFxRRIEK
-eN5KzlW/HdXZt1bv8Hb/C3m1r737qWmRRpdogBQ2HbN/uymYNqUg+oJgYjOk7Na6
-B6duxc8UpufWkjTYgfX8HV2qXB72o007uPc5AgMBAAGjgZcwgZQwDwYDVR0TAQH/
-BAUwAwEB/zBSBgNVHSAESzBJMEcGBFUdIAAwPzA9BggrBgEFBQcCARYxaHR0cDov
-L3d3dy5wa2lvdmVyaGVpZC5ubC9wb2xpY2llcy9yb290LXBvbGljeS1HMjAOBgNV
-HQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJFoMocVHYnitfGsNig0jQt8YojrMA0GCSqG
-SIb3DQEBCwUAA4ICAQCoQUpnKpKBglBu4dfYszk78wIVCVBR7y29JHuIhjv5tLyS
-CZa59sCrI2AGeYwRTlHSeYAz+51IvuxBQ4EffkdAHOV6CMqqi3WtFMTC6GY8ggen
-5ieCWxjmD27ZUD6KQhgpxrRW/FYQoAUXvQwjf/ST7ZwaUb7dRUG/kSS0H4zpX897
-IZmflZ85OkYcbPnNe5yQzSipx6lVu6xiNGI1E0sUOlWDuYaNkqbG9AclVMwWVxJK
-gnjIFNkXgiYtXSAfea7+1HAWFpWD2DU5/1JddRwWxRNVz0fMdWVSSt7wsKfkCpYL
-+63C4iWEst3kvX5ZbJvw8NjnyvLplzh+ib7M+zkXYT9y2zqR2GUBGR2tUKRXCnxL
-vJxxcypFURmFzI79R6d0lR2o0a9OF7FpJsKqeFdbxU2n5Z4FF5TKsl+gSRiNNOkm
-bEgeqmiSBeGCc1qb3AdbCG19ndeNIdn8FCCqwkXfP+cAslHkwvgFuXkajDTznlvk
-N1trSt8sV4pAWja63XVECDdCcAz+3F4hoKOKwJCcaNpQ5kUQR3i2TtJlycM33+FC
-Y7BXN0Ute4qcvwXqZVUz9zkQxSgqIXobisQk+T8VyJoVIPVVYpbtbZNQvOSqeK3Z
-ywplh6ZmwcSBo3c6WB4L7oOLnR7SUqTMHW+wmG2UMbX4cQrcufx9MmDm66+KAQ==
------END CERTIFICATE-----
-
-# Issuer: CN=CA Disig O=Disig a.s.
-# Subject: CN=CA Disig O=Disig a.s.
-# Label: "CA Disig"
-# Serial: 1
-# MD5 Fingerprint: 3f:45:96:39:e2:50:87:f7:bb:fe:98:0c:3c:20:98:e6
-# SHA1 Fingerprint: 2a:c8:d5:8b:57:ce:bf:2f:49:af:f2:fc:76:8f:51:14:62:90:7a:41
-# SHA256 Fingerprint: 92:bf:51:19:ab:ec:ca:d0:b1:33:2d:c4:e1:d0:5f:ba:75:b5:67:90:44:ee:0c:a2:6e:93:1f:74:4f:2f:33:cf
------BEGIN CERTIFICATE-----
-MIIEDzCCAvegAwIBAgIBATANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQGEwJTSzET
-MBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcgYS5zLjERMA8GA1UE
-AxMIQ0EgRGlzaWcwHhcNMDYwMzIyMDEzOTM0WhcNMTYwMzIyMDEzOTM0WjBKMQsw
-CQYDVQQGEwJTSzETMBEGA1UEBxMKQnJhdGlzbGF2YTETMBEGA1UEChMKRGlzaWcg
-YS5zLjERMA8GA1UEAxMIQ0EgRGlzaWcwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
-ggEKAoIBAQCS9jHBfYj9mQGp2HvycXXxMcbzdWb6UShGhJd4NLxs/LxFWYgmGErE
-Nx+hSkS943EE9UQX4j/8SFhvXJ56CbpRNyIjZkMhsDxkovhqFQ4/61HhVKndBpnX
-mjxUizkDPw/Fzsbrg3ICqB9x8y34dQjbYkzo+s7552oftms1grrijxaSfQUMbEYD
-XcDtab86wYqg6I7ZuUUohwjstMoVvoLdtUSLLa2GDGhibYVW8qwUYzrG0ZmsNHhW
-S8+2rT+MitcE5eN4TPWGqvWP+j1scaMtymfraHtuM6kMgiioTGohQBUgDCZbg8Kp
-FhXAJIJdKxatymP2dACw30PEEGBWZ2NFAgMBAAGjgf8wgfwwDwYDVR0TAQH/BAUw
-AwEB/zAdBgNVHQ4EFgQUjbJJaJ1yCCW5wCf1UJNWSEZx+Y8wDgYDVR0PAQH/BAQD
-AgEGMDYGA1UdEQQvMC2BE2Nhb3BlcmF0b3JAZGlzaWcuc2uGFmh0dHA6Ly93d3cu
-ZGlzaWcuc2svY2EwZgYDVR0fBF8wXTAtoCugKYYnaHR0cDovL3d3dy5kaXNpZy5z
-ay9jYS9jcmwvY2FfZGlzaWcuY3JsMCygKqAohiZodHRwOi8vY2EuZGlzaWcuc2sv
-Y2EvY3JsL2NhX2Rpc2lnLmNybDAaBgNVHSAEEzARMA8GDSuBHpGT5goAAAABAQEw
-DQYJKoZIhvcNAQEFBQADggEBAF00dGFMrzvY/59tWDYcPQuBDRIrRhCA/ec8J9B6
-yKm2fnQwM6M6int0wHl5QpNt/7EpFIKrIYwvF/k/Ji/1WcbvgAa3mkkp7M5+cTxq
-EEHA9tOasnxakZzArFvITV734VP/Q3f8nktnbNfzg9Gg4H8l37iYC5oyOGwwoPP/
-CBUz91BKez6jPiCp3C9WgArtQVCwyfTssuMmRAAOb54GvCKWU3BlxFAKRmukLyeB
-EicTXxChds6KezfqwzlhA5WYOudsiCUI/HloDYd9Yvi0X/vF2Ey9WLw/Q1vUHgFN
-PGO+I++MzVpQuGhU+QqZMxEA4Z7CRneC9VkGjCFMhwnN5ag=
------END CERTIFICATE-----
-
-# Issuer: CN=Juur-SK O=AS Sertifitseerimiskeskus
-# Subject: CN=Juur-SK O=AS Sertifitseerimiskeskus
-# Label: "Juur-SK"
-# Serial: 999181308
-# MD5 Fingerprint: aa:8e:5d:d9:f8:db:0a:58:b7:8d:26:87:6c:82:35:55
-# SHA1 Fingerprint: 40:9d:4b:d9:17:b5:5c:27:b6:9b:64:cb:98:22:44:0d:cd:09:b8:89
-# SHA256 Fingerprint: ec:c3:e9:c3:40:75:03:be:e0:91:aa:95:2f:41:34:8f:f8:8b:aa:86:3b:22:64:be:fa:c8:07:90:15:74:e9:39
------BEGIN CERTIFICATE-----
-MIIE5jCCA86gAwIBAgIEO45L/DANBgkqhkiG9w0BAQUFADBdMRgwFgYJKoZIhvcN
-AQkBFglwa2lAc2suZWUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKExlBUyBTZXJ0aWZp
-dHNlZXJpbWlza2Vza3VzMRAwDgYDVQQDEwdKdXVyLVNLMB4XDTAxMDgzMDE0MjMw
-MVoXDTE2MDgyNjE0MjMwMVowXTEYMBYGCSqGSIb3DQEJARYJcGtpQHNrLmVlMQsw
-CQYDVQQGEwJFRTEiMCAGA1UEChMZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1czEQ
-MA4GA1UEAxMHSnV1ci1TSzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
-AIFxNj4zB9bjMI0TfncyRsvPGbJgMUaXhvSYRqTCZUXP00B841oiqBB4M8yIsdOB
-SvZiF3tfTQou0M+LI+5PAk676w7KvRhj6IAcjeEcjT3g/1tf6mTll+g/mX8MCgkz
-ABpTpyHhOEvWgxutr2TC+Rx6jGZITWYfGAriPrsfB2WThbkasLnE+w0R9vXW+RvH
-LCu3GFH+4Hv2qEivbDtPL+/40UceJlfwUR0zlv/vWT3aTdEVNMfqPxZIe5EcgEMP
-PbgFPtGzlc3Yyg/CQ2fbt5PgIoIuvvVoKIO5wTtpeyDaTpxt4brNj3pssAki14sL
-2xzVWiZbDcDq5WDQn/413z8CAwEAAaOCAawwggGoMA8GA1UdEwEB/wQFMAMBAf8w
-ggEWBgNVHSAEggENMIIBCTCCAQUGCisGAQQBzh8BAQEwgfYwgdAGCCsGAQUFBwIC
-MIHDHoHAAFMAZQBlACAAcwBlAHIAdABpAGYAaQBrAGEAYQB0ACAAbwBuACAAdgDk
-AGwAagBhAHMAdABhAHQAdQBkACAAQQBTAC0AaQBzACAAUwBlAHIAdABpAGYAaQB0
-AHMAZQBlAHIAaQBtAGkAcwBrAGUAcwBrAHUAcwAgAGEAbABhAG0ALQBTAEsAIABz
-AGUAcgB0AGkAZgBpAGsAYQBhAHQAaQBkAGUAIABrAGkAbgBuAGkAdABhAG0AaQBz
-AGUAawBzMCEGCCsGAQUFBwIBFhVodHRwOi8vd3d3LnNrLmVlL2Nwcy8wKwYDVR0f
-BCQwIjAgoB6gHIYaaHR0cDovL3d3dy5zay5lZS9qdXVyL2NybC8wHQYDVR0OBBYE
-FASqekej5ImvGs8KQKcYP2/v6X2+MB8GA1UdIwQYMBaAFASqekej5ImvGs8KQKcY
-P2/v6X2+MA4GA1UdDwEB/wQEAwIB5jANBgkqhkiG9w0BAQUFAAOCAQEAe8EYlFOi
-CfP+JmeaUOTDBS8rNXiRTHyoERF5TElZrMj3hWVcRrs7EKACr81Ptcw2Kuxd/u+g
-kcm2k298gFTsxwhwDY77guwqYHhpNjbRxZyLabVAyJRld/JXIWY7zoVAtjNjGr95
-HvxcHdMdkxuLDF2FvZkwMhgJkVLpfKG6/2SSmuz+Ne6ML678IIbsSt4beDI3poHS
-na9aEhbKmVv8b20OxaAehsmR0FyYgl9jDIpaq9iVpszLita/ZEuOyoqysOkhMp6q
-qIWYNIE5ITuoOlIyPfZrN4YGWhWY3PARZv40ILcD9EEQfTmEeZZyY7aWAuVrua0Z
-TbvGRNs2yyqcjg==
------END CERTIFICATE-----
-
-# Issuer: CN=Hongkong Post Root CA 1 O=Hongkong Post
-# Subject: CN=Hongkong Post Root CA 1 O=Hongkong Post
-# Label: "Hongkong Post Root CA 1"
-# Serial: 1000
-# MD5 Fingerprint: a8:0d:6f:39:78:b9:43:6d:77:42:6d:98:5a:cc:23:ca
-# SHA1 Fingerprint: d6:da:a8:20:8d:09:d2:15:4d:24:b5:2f:cb:34:6e:b2:58:b2:8a:58
-# SHA256 Fingerprint: f9:e6:7d:33:6c:51:00:2a:c0:54:c6:32:02:2d:66:dd:a2:e7:e3:ff:f1:0a:d0:61:ed:31:d8:bb:b4:10:cf:b2
------BEGIN CERTIFICATE-----
-MIIDMDCCAhigAwIBAgICA+gwDQYJKoZIhvcNAQEFBQAwRzELMAkGA1UEBhMCSEsx
-FjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdrb25nIFBvc3Qg
-Um9vdCBDQSAxMB4XDTAzMDUxNTA1MTMxNFoXDTIzMDUxNTA0NTIyOVowRzELMAkG
-A1UEBhMCSEsxFjAUBgNVBAoTDUhvbmdrb25nIFBvc3QxIDAeBgNVBAMTF0hvbmdr
-b25nIFBvc3QgUm9vdCBDQSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEArP84tulmAknjorThkPlAj3n54r15/gK97iSSHSL22oVyaf7XPwnU3ZG1ApzQ
-jVrhVcNQhrkpJsLj2aDxaQMoIIBFIi1WpztUlVYiWR8o3x8gPW2iNr4joLFutbEn
-PzlTCeqrauh0ssJlXI6/fMN4hM2eFvz1Lk8gKgifd/PFHsSaUmYeSF7jEAaPIpjh
-ZY4bXSNmO7ilMlHIhqqhqZ5/dpTCpmy3QfDVyAY45tQM4vM7TG1QjMSDJ8EThFk9
-nnV0ttgCXjqQesBCNnLsak3c78QA3xMYV18meMjWCnl3v/evt3a5pQuEF10Q6m/h
-q5URX208o1xNg1vysxmKgIsLhwIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgED
-MA4GA1UdDwEB/wQEAwIBxjANBgkqhkiG9w0BAQUFAAOCAQEADkbVPK7ih9legYsC
-mEEIjEy82tvuJxuC52pF7BaLT4Wg87JwvVqWuspube5Gi27nKi6Wsxkz67SfqLI3
-7piol7Yutmcn1KZJ/RyTZXaeQi/cImyaT/JaFTmxcdcrUehtHJjA2Sr0oYJ71clB
-oiMBdDhViw+5LmeiIAQ32pwL0xch4I+XeTRvhEgCIDMb5jREn5Fw9IBehEPCKdJs
-EhTkYY2sEJCehFC78JZvRZ+K88psT/oROhUVRsPNH4NbLUES7VBnQRM9IauUiqpO
-fMGx+6fWtScvl6tu4B3i0RwsH0Ti/L6RoZz71ilTc4afU9hDDl3WY4JxHYB0yvbi
-AmvZWg==
------END CERTIFICATE-----
-
-# Issuer: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
-# Subject: CN=SecureSign RootCA11 O=Japan Certification Services, Inc.
-# Label: "SecureSign RootCA11"
-# Serial: 1
-# MD5 Fingerprint: b7:52:74:e2:92:b4:80:93:f2:75:e4:cc:d7:f2:ea:26
-# SHA1 Fingerprint: 3b:c4:9f:48:f8:f3:73:a0:9c:1e:bd:f8:5b:b1:c3:65:c7:d8:11:b3
-# SHA256 Fingerprint: bf:0f:ee:fb:9e:3a:58:1a:d5:f9:e9:db:75:89:98:57:43:d2:61:08:5c:4d:31:4f:6f:5d:72:59:aa:42:16:12
------BEGIN CERTIFICATE-----
-MIIDbTCCAlWgAwIBAgIBATANBgkqhkiG9w0BAQUFADBYMQswCQYDVQQGEwJKUDEr
-MCkGA1UEChMiSmFwYW4gQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcywgSW5jLjEcMBoG
-A1UEAxMTU2VjdXJlU2lnbiBSb290Q0ExMTAeFw0wOTA0MDgwNDU2NDdaFw0yOTA0
-MDgwNDU2NDdaMFgxCzAJBgNVBAYTAkpQMSswKQYDVQQKEyJKYXBhbiBDZXJ0aWZp
-Y2F0aW9uIFNlcnZpY2VzLCBJbmMuMRwwGgYDVQQDExNTZWN1cmVTaWduIFJvb3RD
-QTExMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA/XeqpRyQBTvLTJsz
-i1oURaTnkBbR31fSIRCkF/3frNYfp+TbfPfs37gD2pRY/V1yfIw/XwFndBWW4wI8
-h9uuywGOwvNmxoVF9ALGOrVisq/6nL+k5tSAMJjzDbaTj6nU2DbysPyKyiyhFTOV
-MdrAG/LuYpmGYz+/3ZMqg6h2uRMft85OQoWPIucuGvKVCbIFtUROd6EgvanyTgp9
-UK31BQ1FT0Zx/Sg+U/sE2C3XZR1KG/rPO7AxmjVuyIsG0wCR8pQIZUyxNAYAeoni
-8McDWc/V1uinMrPmmECGxc0nEovMe863ETxiYAcjPitAbpSACW22s293bzUIUPsC
-h8U+iQIDAQABo0IwQDAdBgNVHQ4EFgQUW/hNT7KlhtQ60vFjmqC+CfZXt94wDgYD
-VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEB
-AKChOBZmLqdWHyGcBvod7bkixTgm2E5P7KN/ed5GIaGHd48HCJqypMWvDzKYC3xm
-KbabfSVSSUOrTC4rbnpwrxYO4wJs+0LmGJ1F2FXI6Dvd5+H0LgscNFxsWEr7jIhQ
-X5Ucv+2rIrVls4W6ng+4reV6G4pQOh29Dbx7VFALuUKvVaAYga1lme++5Jy/xIWr
-QbJUb9wlze144o4MjQlJ3WN7WmmWAiGovVJZ6X01y8hSyn+B/tlr0/cR7SXf+Of5
-pPpyl4RTDaXQMhhRdlkUbA/r7F+AjHVDg8OFmP9Mni0N5HeDk061lgeLKBObjBmN
-QSdJQO7e5iNEOdyhIta6A/I=
------END CERTIFICATE-----
-
-# Issuer: CN=ACEDICOM Root O=EDICOM OU=PKI
-# Subject: CN=ACEDICOM Root O=EDICOM OU=PKI
-# Label: "ACEDICOM Root"
-# Serial: 7029493972724711941
-# MD5 Fingerprint: 42:81:a0:e2:1c:e3:55:10:de:55:89:42:65:96:22:e6
-# SHA1 Fingerprint: e0:b4:32:2e:b2:f6:a5:68:b6:54:53:84:48:18:4a:50:36:87:43:84
-# SHA256 Fingerprint: 03:95:0f:b4:9a:53:1f:3e:19:91:94:23:98:df:a9:e0:ea:32:d7:ba:1c:dd:9b:c8:5d:b5:7e:d9:40:0b:43:4a
------BEGIN CERTIFICATE-----
-MIIFtTCCA52gAwIBAgIIYY3HhjsBggUwDQYJKoZIhvcNAQEFBQAwRDEWMBQGA1UE
-AwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZFRElDT00x
-CzAJBgNVBAYTAkVTMB4XDTA4MDQxODE2MjQyMloXDTI4MDQxMzE2MjQyMlowRDEW
-MBQGA1UEAwwNQUNFRElDT00gUm9vdDEMMAoGA1UECwwDUEtJMQ8wDQYDVQQKDAZF
-RElDT00xCzAJBgNVBAYTAkVTMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
-AgEA/5KV4WgGdrQsyFhIyv2AVClVYyT/kGWbEHV7w2rbYgIB8hiGtXxaOLHkWLn7
-09gtn70yN78sFW2+tfQh0hOR2QetAQXW8713zl9CgQr5auODAKgrLlUTY4HKRxx7
-XBZXehuDYAQ6PmXDzQHe3qTWDLqO3tkE7hdWIpuPY/1NFgu3e3eM+SW10W2ZEi5P
-Grjm6gSSrj0RuVFCPYewMYWveVqc/udOXpJPQ/yrOq2lEiZmueIM15jO1FillUAK
-t0SdE3QrwqXrIhWYENiLxQSfHY9g5QYbm8+5eaA9oiM/Qj9r+hwDezCNzmzAv+Yb
-X79nuIQZ1RXve8uQNjFiybwCq0Zfm/4aaJQ0PZCOrfbkHQl/Sog4P75n/TSW9R28
-MHTLOO7VbKvU/PQAtwBbhTIWdjPp2KOZnQUAqhbm84F9b32qhm2tFXTTxKJxqvQU
-fecyuB+81fFOvW8XAjnXDpVCOscAPukmYxHqC9FK/xidstd7LzrZlvvoHpKuE1XI
-2Sf23EgbsCTBheN3nZqk8wwRHQ3ItBTutYJXCb8gWH8vIiPYcMt5bMlL8qkqyPyH
-K9caUPgn6C9D4zq92Fdx/c6mUlv53U3t5fZvie27k5x2IXXwkkwp9y+cAS7+UEae
-ZAwUswdbxcJzbPEHXEUkFDWug/FqTYl6+rPYLWbwNof1K1MCAwEAAaOBqjCBpzAP
-BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKaz4SsrSbbXc6GqlPUB53NlTKxQ
-MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUprPhKytJttdzoaqU9QHnc2VMrFAw
-RAYDVR0gBD0wOzA5BgRVHSAAMDEwLwYIKwYBBQUHAgEWI2h0dHA6Ly9hY2VkaWNv
-bS5lZGljb21ncm91cC5jb20vZG9jMA0GCSqGSIb3DQEBBQUAA4ICAQDOLAtSUWIm
-fQwng4/F9tqgaHtPkl7qpHMyEVNEskTLnewPeUKzEKbHDZ3Ltvo/Onzqv4hTGzz3
-gvoFNTPhNahXwOf9jU8/kzJPeGYDdwdY6ZXIfj7QeQCM8htRM5u8lOk6e25SLTKe
-I6RF+7YuE7CLGLHdztUdp0J/Vb77W7tH1PwkzQSulgUV1qzOMPPKC8W64iLgpq0i
-5ALudBF/TP94HTXa5gI06xgSYXcGCRZj6hitoocf8seACQl1ThCojz2GuHURwCRi
-ipZ7SkXp7FnFvmuD5uHorLUwHv4FB4D54SMNUI8FmP8sX+g7tq3PgbUhh8oIKiMn
-MCArz+2UW6yyetLHKKGKC5tNSixthT8Jcjxn4tncB7rrZXtaAWPWkFtPF2Y9fwsZ
-o5NjEFIqnxQWWOLcpfShFosOkYuByptZ+thrkQdlVV9SH686+5DdaaVbnG0OLLb6
-zqylfDJKZ0DcMDQj3dcEI2bw/FWAp/tmGYI1Z2JwOV5vx+qQQEQIHriy1tvuWacN
-GHk0vFQYXlPKNFHtRQrmjseCNj6nOGOpMCwXEGCSn1WHElkQwg9naRHMTh5+Spqt
-r0CodaxWkHS4oJyleW/c6RrIaQXpuvoDs3zk4E7Czp3otkYNbn5XOmeUwssfnHdK
-Z05phkOTOPu220+DkdRgfks+KzgHVZhepA==
------END CERTIFICATE-----
-
-# Issuer: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Subject: O=VeriSign, Inc. OU=Class 3 Public Primary Certification Authority
-# Label: "Verisign Class 3 Public Primary Certification Authority"
-# Serial: 80507572722862485515306429940691309246
-# MD5 Fingerprint: ef:5a:f1:33:ef:f1:cd:bb:51:02:ee:12:14:4b:96:c4
-# SHA1 Fingerprint: a1:db:63:93:91:6f:17:e4:18:55:09:40:04:15:c7:02:40:b0:ae:6b
-# SHA256 Fingerprint: a4:b6:b3:99:6f:c2:f3:06:b3:fd:86:81:bd:63:41:3d:8c:50:09:cc:4f:a3:29:c2:cc:f0:e2:fa:1b:14:03:05
------BEGIN CERTIFICATE-----
-MIICPDCCAaUCEDyRMcsf9tAbDpq40ES/Er4wDQYJKoZIhvcNAQEFBQAwXzELMAkG
-A1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFz
-cyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTk2
-MDEyOTAwMDAwMFoXDTI4MDgwMjIzNTk1OVowXzELMAkGA1UEBhMCVVMxFzAVBgNV
-BAoTDlZlcmlTaWduLCBJbmMuMTcwNQYDVQQLEy5DbGFzcyAzIFB1YmxpYyBQcmlt
-YXJ5IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIGfMA0GCSqGSIb3DQEBAQUAA4GN
-ADCBiQKBgQDJXFme8huKARS0EN8EQNvjV69qRUCPhAwL0TPZ2RHP7gJYHyX3KqhE
-BarsAx94f56TuZoAqiN91qyFomNFx3InzPRMxnVx0jnvT0Lwdd8KkMaOIG+YD/is
-I19wKTakyYbnsZogy1Olhec9vn2a/iRFM9x2Fe0PonFkTGUugWhFpwIDAQABMA0G
-CSqGSIb3DQEBBQUAA4GBABByUqkFFBkyCEHwxWsKzH4PIRnN5GfcX6kb5sroc50i
-2JhucwNhkcV8sEVAbkSdjbCxlnRhLQ2pRdKkkirWmnWXbj9T/UWZYB2oK0z5XqcJ
-2HUw19JlYD1n1khVdWk/kfVIC0dpImmClr7JyDiGSnoscxlIaU5rfGW/D/xwzoiQ
------END CERTIFICATE-----
-
-# Issuer: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
-# Subject: CN=Microsec e-Szigno Root CA 2009 O=Microsec Ltd.
-# Label: "Microsec e-Szigno Root CA 2009"
-# Serial: 14014712776195784473
-# MD5 Fingerprint: f8:49:f4:03:bc:44:2d:83:be:48:69:7d:29:64:fc:b1
-# SHA1 Fingerprint: 89:df:74:fe:5c:f4:0f:4a:80:f9:e3:37:7d:54:da:91:e1:01:31:8e
-# SHA256 Fingerprint: 3c:5f:81:fe:a5:fa:b8:2c:64:bf:a2:ea:ec:af:cd:e8:e0:77:fc:86:20:a7:ca:e5:37:16:3d:f3:6e:db:f3:78
------BEGIN CERTIFICATE-----
-MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYD
-VQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0
-ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0G
-CSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTAeFw0wOTA2MTYxMTMwMThaFw0y
-OTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UEBwwIQnVkYXBlc3Qx
-FjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUtU3pp
-Z25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o
-dTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvP
-kd6mJviZpWNwrZuuyjNAfW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tc
-cbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG0IMZfcChEhyVbUr02MelTTMuhTlAdX4U
-fIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKApxn1ntxVUwOXewdI/5n7
-N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm1HxdrtbC
-xkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1
-+rUCAwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0G
-A1UdDgQWBBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPM
-Pcu1SCOhGnqmKrs0aDAbBgNVHREEFDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqG
-SIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0olZMEyL/azXm4Q5DwpL7v8u8h
-mLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfXI/OMn74dseGk
-ddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775
-tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c
-2Pm2G2JwCz02yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5t
-HMN1Rq41Bab2XD0h7lbwyYIiLXpUq3DDfSJlgnCW
------END CERTIFICATE-----
-
-# Issuer: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S.
-# Subject: CN=e-Guven Kok Elektronik Sertifika Hizmet Saglayicisi O=Elektronik Bilgi Guvenligi A.S.
-# Label: "E-Guven Kok Elektronik Sertifika Hizmet Saglayicisi"
-# Serial: 91184789765598910059173000485363494069
-# MD5 Fingerprint: 3d:41:29:cb:1e:aa:11:74:cd:5d:b0:62:af:b0:43:5b
-# SHA1 Fingerprint: dd:e1:d2:a9:01:80:2e:1d:87:5e:84:b3:80:7e:4b:b1:fd:99:41:34
-# SHA256 Fingerprint: e6:09:07:84:65:a4:19:78:0c:b6:ac:4c:1c:0b:fb:46:53:d9:d9:cc:6e:b3:94:6e:b7:f3:d6:99:97:ba:d5:98
------BEGIN CERTIFICATE-----
-MIIDtjCCAp6gAwIBAgIQRJmNPMADJ72cdpW56tustTANBgkqhkiG9w0BAQUFADB1
-MQswCQYDVQQGEwJUUjEoMCYGA1UEChMfRWxla3Ryb25payBCaWxnaSBHdXZlbmxp
-Z2kgQS5TLjE8MDoGA1UEAxMzZS1HdXZlbiBLb2sgRWxla3Ryb25payBTZXJ0aWZp
-a2EgSGl6bWV0IFNhZ2xheWljaXNpMB4XDTA3MDEwNDExMzI0OFoXDTE3MDEwNDEx
-MzI0OFowdTELMAkGA1UEBhMCVFIxKDAmBgNVBAoTH0VsZWt0cm9uaWsgQmlsZ2kg
-R3V2ZW5saWdpIEEuUy4xPDA6BgNVBAMTM2UtR3V2ZW4gS29rIEVsZWt0cm9uaWsg
-U2VydGlmaWthIEhpem1ldCBTYWdsYXlpY2lzaTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMMSIJ6wXgBljU5Gu4Bc6SwGl9XzcslwuedLZYDBS75+PNdU
-MZTe1RK6UxYC6lhj71vY8+0qGqpxSKPcEC1fX+tcS5yWCEIlKBHMilpiAVDV6wlT
-L/jDj/6z/P2douNffb7tC+Bg62nsM+3YjfsSSYMAyYuXjDtzKjKzEve5TfL0TW3H
-5tYmNwjy2f1rXKPlSFxYvEK+A1qBuhw1DADT9SN+cTAIJjjcJRFHLfO6IxClv7wC
-90Nex/6wN1CZew+TzuZDLMN+DfIcQ2Zgy2ExR4ejT669VmxMvLz4Bcpk9Ok0oSy1
-c+HCPujIyTQlCFzz7abHlJ+tiEMl1+E5YP6sOVkCAwEAAaNCMEAwDgYDVR0PAQH/
-BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFJ/uRLOU1fqRTy7ZVZoE
-VtstxNulMA0GCSqGSIb3DQEBBQUAA4IBAQB/X7lTW2M9dTLn+sR0GstG30ZpHFLP
-qk/CaOv/gKlR6D1id4k9CnU58W5dF4dvaAXBlGzZXd/aslnLpRCKysw5zZ/rTt5S
-/wzw9JKp8mxTq5vSR6AfdPebmvEvFZ96ZDAYBzwqD2fK/A+JYZ1lpTzlvBNbCNvj
-/+27BrtqBrF6T2XGgv0enIu1De5Iu7i9qgi0+6N8y5/NkHZchpZ4Vwpm+Vganf2X
-KWDeEaaQHBkc7gGWIjQ0LpH5t8Qn0Xvmv/uARFoW5evg1Ao4vOSR49XrXMGs3xtq
-fJ7lddK2l4fbzIcrQzqECK+rPNv3PGYxhrCdU3nt+CPeQuMtgvEP5fqX
------END CERTIFICATE-----
-
-# Issuer: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
-# Subject: CN=GlobalSign O=GlobalSign OU=GlobalSign Root CA - R3
-# Label: "GlobalSign Root CA - R3"
-# Serial: 4835703278459759426209954
-# MD5 Fingerprint: c5:df:b8:49:ca:05:13:55:ee:2d:ba:1a:c3:3e:b0:28
-# SHA1 Fingerprint: d6:9b:56:11:48:f0:1c:77:c5:45:78:c1:09:26:df:5b:85:69:76:ad
-# SHA256 Fingerprint: cb:b5:22:d7:b7:f1:27:ad:6a:01:13:86:5b:df:1c:d4:10:2e:7d:07:59:af:63:5a:7c:f4:72:0d:c9:63:c5:3b
------BEGIN CERTIFICATE-----
-MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4G
-A1UECxMXR2xvYmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNp
-Z24xEzARBgNVBAMTCkdsb2JhbFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4
-MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSMzETMBEG
-A1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2lnbjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWtiHL8
-RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsT
-gHeMCOFJ0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmm
-KPZpO/bLyCiR5Z2KYVc3rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zd
-QQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjlOCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZ
-XriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2xmmFghcCAwEAAaNCMEAw
-DgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFI/wS3+o
-LkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZU
-RUm7lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMp
-jjM5RcOO5LlXbKr8EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK
-6fBdRoyV3XpYKBovHd7NADdBj+1EbddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQX
-mcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18YIvDQVETI53O9zJrlAGomecs
-Mx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7rkpeDMdmztcpH
-WD9f
------END CERTIFICATE-----
-
-# Issuer: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
-# Subject: CN=Autoridad de Certificacion Firmaprofesional CIF A62634068
-# Label: "Autoridad de Certificacion Firmaprofesional CIF A62634068"
-# Serial: 6047274297262753887
-# MD5 Fingerprint: 73:3a:74:7a:ec:bb:a3:96:a6:c2:e4:e2:c8:9b:c0:c3
-# SHA1 Fingerprint: ae:c5:fb:3f:c8:e1:bf:c4:e5:4f:03:07:5a:9a:e8:00:b7:f7:b6:fa
-# SHA256 Fingerprint: 04:04:80:28:bf:1f:28:64:d4:8f:9a:d4:d8:32:94:36:6a:82:88:56:55:3f:3b:14:30:3f:90:14:7f:5d:40:ef
------BEGIN CERTIFICATE-----
-MIIGFDCCA/ygAwIBAgIIU+w77vuySF8wDQYJKoZIhvcNAQEFBQAwUTELMAkGA1UE
-BhMCRVMxQjBABgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1h
-cHJvZmVzaW9uYWwgQ0lGIEE2MjYzNDA2ODAeFw0wOTA1MjAwODM4MTVaFw0zMDEy
-MzEwODM4MTVaMFExCzAJBgNVBAYTAkVTMUIwQAYDVQQDDDlBdXRvcmlkYWQgZGUg
-Q2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBBNjI2MzQwNjgwggIi
-MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDDUtd9
-thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQM
-cas9UX4PB99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefG
-L9ItWY16Ck6WaVICqjaY7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15i
-NA9wBj4gGFrO93IbJWyTdBSTo3OxDqqHECNZXyAFGUftaI6SEspd/NYrspI8IM/h
-X68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyIplD9amML9ZMWGxmPsu2b
-m8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctXMbScyJCy
-Z/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirja
-EbsXLZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/T
-KI8xWVvTyQKmtFLKbpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF
-6NkBiDkal4ZkQdU7hwxu+g/GvUgUvzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVh
-OSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMBIGA1UdEwEB/wQIMAYBAf8CAQEwDgYD
-VR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRlzeurNR4APn7VdMActHNHDhpkLzCBpgYD
-VR0gBIGeMIGbMIGYBgRVHSAAMIGPMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3LmZp
-cm1hcHJvZmVzaW9uYWwuY29tL2NwczBcBggrBgEFBQcCAjBQHk4AUABhAHMAZQBv
-ACAAZABlACAAbABhACAAQgBvAG4AYQBuAG8AdgBhACAANAA3ACAAQgBhAHIAYwBl
-AGwAbwBuAGEAIAAwADgAMAAxADcwDQYJKoZIhvcNAQEFBQADggIBABd9oPm03cXF
-661LJLWhAqvdpYhKsg9VSytXjDvlMd3+xDLx51tkljYyGOylMnfX40S2wBEqgLk9
-am58m9Ot/MPWo+ZkKXzR4Tgegiv/J2Wv+xYVxC5xhOW1//qkR71kMrv2JYSiJ0L1
-ILDCExARzRAVukKQKtJE4ZYm6zFIEv0q2skGz3QeqUvVhyj5eTSSPi5E6PaPT481
-PyWzOdxjKpBrIF/EUhJOlywqrJ2X3kjyo2bbwtKDlaZmp54lD+kLM5FlClrD2VQS
-3a/DTg4fJl4N3LON7NWBcN7STyQF82xO9UxJZo3R/9ILJUFI/lGExkKvgATP0H5k
-SeTy36LssUzAKh3ntLFlosS88Zj0qnAHY7S42jtM+kAiMFsRpvAFDsYCA0irhpuF
-3dvd6qJ2gHN99ZwExEWN57kci57q13XRcrHedUTnQn3iV2t93Jm8PYMo6oCTjcVM
-ZcFwgbg4/EMxsvYDNEeyrPsiBsse3RdHHF9mudMaotoRsaS8I8nkvof/uZS2+F0g
-StRf571oe2XyFR7SOqkt6dhrJKyXWERHrVkY8SFlcN7ONGCoQPHzPKTDKCOM/icz
-Q0CgFzzr6juwcqajuUpLXhZI9LK8yIySxZ2frHI2vDSANGupi5LAuBft7HZT9SQB
-jLMi6Et8Vcad+qMUu2WFbm5PEn4KPJ2V
------END CERTIFICATE-----
-
-# Issuer: CN=Izenpe.com O=IZENPE S.A.
-# Subject: CN=Izenpe.com O=IZENPE S.A.
-# Label: "Izenpe.com"
-# Serial: 917563065490389241595536686991402621
-# MD5 Fingerprint: a6:b0:cd:85:80:da:5c:50:34:a3:39:90:2f:55:67:73
-# SHA1 Fingerprint: 2f:78:3d:25:52:18:a7:4a:65:39:71:b5:2c:a2:9c:45:15:6f:e9:19
-# SHA256 Fingerprint: 25:30:cc:8e:98:32:15:02:ba:d9:6f:9b:1f:ba:1b:09:9e:2d:29:9e:0f:45:48:bb:91:4f:36:3b:c0:d4:53:1f
------BEGIN CERTIFICATE-----
-MIIF8TCCA9mgAwIBAgIQALC3WhZIX7/hy/WL1xnmfTANBgkqhkiG9w0BAQsFADA4
-MQswCQYDVQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6
-ZW5wZS5jb20wHhcNMDcxMjEzMTMwODI4WhcNMzcxMjEzMDgyNzI1WjA4MQswCQYD
-VQQGEwJFUzEUMBIGA1UECgwLSVpFTlBFIFMuQS4xEzARBgNVBAMMCkl6ZW5wZS5j
-b20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDJ03rKDx6sp4boFmVq
-scIbRTJxldn+EFvMr+eleQGPicPK8lVx93e+d5TzcqQsRNiekpsUOqHnJJAKClaO
-xdgmlOHZSOEtPtoKct2jmRXagaKH9HtuJneJWK3W6wyyQXpzbm3benhB6QiIEn6H
-LmYRY2xU+zydcsC8Lv/Ct90NduM61/e0aL6i9eOBbsFGb12N4E3GVFWJGjMxCrFX
-uaOKmMPsOzTFlUFpfnXCPCDFYbpRR6AgkJOhkEvzTnyFRVSa0QUmQbC1TR0zvsQD
-yCV8wXDbO/QJLVQnSKwv4cSsPsjLkkxTOTcj7NMB+eAJRE1NZMDhDVqHIrytG6P+
-JrUV86f8hBnp7KGItERphIPzidF0BqnMC9bC3ieFUCbKF7jJeodWLBoBHmy+E60Q
-rLUk9TiRodZL2vG70t5HtfG8gfZZa88ZU+mNFctKy6lvROUbQc/hhqfK0GqfvEyN
-BjNaooXlkDWgYlwWTvDjovoDGrQscbNYLN57C9saD+veIR8GdwYDsMnvmfzAuU8L
-hij+0rnq49qlw0dpEuDb8PYZi+17cNcC1u2HGCgsBCRMd+RIihrGO5rUD8r6ddIB
-QFqNeb+Lz0vPqhbBleStTIo+F5HUsWLlguWABKQDfo2/2n+iD5dPDNMN+9fR5XJ+
-HMh3/1uaD7euBUbl8agW7EekFwIDAQABo4H2MIHzMIGwBgNVHREEgagwgaWBD2lu
-Zm9AaXplbnBlLmNvbaSBkTCBjjFHMEUGA1UECgw+SVpFTlBFIFMuQS4gLSBDSUYg
-QTAxMzM3MjYwLVJNZXJjLlZpdG9yaWEtR2FzdGVpeiBUMTA1NSBGNjIgUzgxQzBB
-BgNVBAkMOkF2ZGEgZGVsIE1lZGl0ZXJyYW5lbyBFdG9yYmlkZWEgMTQgLSAwMTAx
-MCBWaXRvcmlhLUdhc3RlaXowDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC
-AQYwHQYDVR0OBBYEFB0cZQ6o8iV7tJHP5LGx5r1VdGwFMA0GCSqGSIb3DQEBCwUA
-A4ICAQB4pgwWSp9MiDrAyw6lFn2fuUhfGI8NYjb2zRlrrKvV9pF9rnHzP7MOeIWb
-laQnIUdCSnxIOvVFfLMMjlF4rJUT3sb9fbgakEyrkgPH7UIBzg/YsfqikuFgba56
-awmqxinuaElnMIAkejEWOVt+8Rwu3WwJrfIxwYJOubv5vr8qhT/AQKM6WfxZSzwo
-JNu0FXWuDYi6LnPAvViH5ULy617uHjAimcs30cQhbIHsvm0m5hzkQiCeR7Csg1lw
-LDXWrzY0tM07+DKo7+N4ifuNRSzanLh+QBxh5z6ikixL8s36mLYp//Pye6kfLqCT
-VyvehQP5aTfLnnhqBbTFMXiJ7HqnheG5ezzevh55hM6fcA5ZwjUukCox2eRFekGk
-LhObNA5me0mrZJfQRsN5nXJQY6aYWwa9SG3YOYNw6DXwBdGqvOPbyALqfP2C2sJb
-UjWumDqtujWTI6cfSN01RpiyEGjkpTHCClguGYEQyVB1/OpaFs4R1+7vUIgtYf8/
-QnMFlEPVjjxOAToZpR9GTnfQXeWBIiGH/pR9hNiTrdZoQ0iy2+tzJOeRf1SktoA+
-naM8THLCV8Sg1Mw4J87VBp6iSNnpn86CcDaTmjvfliHjWbcM2pE38P1ZWrOZyGls
-QyYBNWNgVYkDOnXYukrZVP/u3oDYLdE41V4tC5h9Pmzb/CaIxw==
------END CERTIFICATE-----
-
-# Issuer: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
-# Subject: CN=Chambers of Commerce Root - 2008 O=AC Camerfirma S.A.
-# Label: "Chambers of Commerce Root - 2008"
-# Serial: 11806822484801597146
-# MD5 Fingerprint: 5e:80:9e:84:5a:0e:65:0b:17:02:f3:55:18:2a:3e:d7
-# SHA1 Fingerprint: 78:6a:74:ac:76:ab:14:7f:9c:6a:30:50:ba:9e:a8:7e:fe:9a:ce:3c
-# SHA256 Fingerprint: 06:3e:4a:fa:c4:91:df:d3:32:f3:08:9b:85:42:e9:46:17:d8:93:d7:fe:94:4e:10:a7:93:7e:e2:9d:96:93:c0
------BEGIN CERTIFICATE-----
-MIIHTzCCBTegAwIBAgIJAKPaQn6ksa7aMA0GCSqGSIb3DQEBBQUAMIGuMQswCQYD
-VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
-IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
-MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xKTAnBgNVBAMTIENoYW1iZXJz
-IG9mIENvbW1lcmNlIFJvb3QgLSAyMDA4MB4XDTA4MDgwMTEyMjk1MFoXDTM4MDcz
-MTEyMjk1MFowga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpNYWRyaWQgKHNlZSBj
-dXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29tL2FkZHJlc3MpMRIw
-EAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVyZmlybWEgUy5BLjEp
-MCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAtIDIwMDgwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCvAMtwNyuAWko6bHiUfaN/Gh/2NdW9
-28sNRHI+JrKQUrpjOyhYb6WzbZSm891kDFX29ufyIiKAXuFixrYp4YFs8r/lfTJq
-VKAyGVn+H4vXPWCGhSRv4xGzdz4gljUha7MI2XAuZPeEklPWDrCQiorjh40G072Q
-DuKZoRuGDtqaCrsLYVAGUvGef3bsyw/QHg3PmTA9HMRFEFis1tPo1+XqxQEHd9ZR
-5gN/ikilTWh1uem8nk4ZcfUyS5xtYBkL+8ydddy/Js2Pk3g5eXNeJQ7KXOt3EgfL
-ZEFHcpOrUMPrCXZkNNI5t3YRCQ12RcSprj1qr7V9ZS+UWBDsXHyvfuK2GNnQm05a
-Sd+pZgvMPMZ4fKecHePOjlO+Bd5gD2vlGts/4+EhySnB8esHnFIbAURRPHsl18Tl
-UlRdJQfKFiC4reRB7noI/plvg6aRArBsNlVq5331lubKgdaX8ZSD6e2wsWsSaR6s
-+12pxZjptFtYer49okQ6Y1nUCyXeG0+95QGezdIp1Z8XGQpvvwyQ0wlf2eOKNcx5
-Wk0ZN5K3xMGtr/R5JJqyAQuxr1yW84Ay+1w9mPGgP0revq+ULtlVmhduYJ1jbLhj
-ya6BXBg14JC7vjxPNyK5fuvPnnchpj04gftI2jE9K+OJ9dC1vX7gUMQSibMjmhAx
-hduub+84Mxh2EQIDAQABo4IBbDCCAWgwEgYDVR0TAQH/BAgwBgEB/wIBDDAdBgNV
-HQ4EFgQU+SSsD7K1+HnA+mCIG8TZTQKeFxkwgeMGA1UdIwSB2zCB2IAU+SSsD7K1
-+HnA+mCIG8TZTQKeFxmhgbSkgbEwga4xCzAJBgNVBAYTAkVVMUMwQQYDVQQHEzpN
-YWRyaWQgKHNlZSBjdXJyZW50IGFkZHJlc3MgYXQgd3d3LmNhbWVyZmlybWEuY29t
-L2FkZHJlc3MpMRIwEAYDVQQFEwlBODI3NDMyODcxGzAZBgNVBAoTEkFDIENhbWVy
-ZmlybWEgUy5BLjEpMCcGA1UEAxMgQ2hhbWJlcnMgb2YgQ29tbWVyY2UgUm9vdCAt
-IDIwMDiCCQCj2kJ+pLGu2jAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRV
-HSAAMCowKAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20w
-DQYJKoZIhvcNAQEFBQADggIBAJASryI1wqM58C7e6bXpeHxIvj99RZJe6dqxGfwW
-PJ+0W2aeaufDuV2I6A+tzyMP3iU6XsxPpcG1Lawk0lgH3qLPaYRgM+gQDROpI9CF
-5Y57pp49chNyM/WqfcZjHwj0/gF/JM8rLFQJ3uIrbZLGOU8W6jx+ekbURWpGqOt1
-glanq6B8aBMz9p0w8G8nOSQjKpD9kCk18pPfNKXG9/jvjA9iSnyu0/VU+I22mlaH
-FoI6M6taIgj3grrqLuBHmrS1RaMFO9ncLkVAO+rcf+g769HsJtg1pDDFOqxXnrN2
-pSB7+R5KBWIBpih1YJeSDW4+TTdDDZIVnBgizVGZoCkaPF+KMjNbMMeJL0eYD6MD
-xvbxrN8y8NmBGuScvfaAFPDRLLmF9dijscilIeUcE5fuDr3fKanvNFNb0+RqE4QG
-tjICxFKuItLcsiFCGtpA8CnJ7AoMXOLQusxI0zcKzBIKinmwPQN/aUv0NCB9szTq
-jktk9T79syNnFQ0EuPAtwQlRPLJsFfClI9eDdOTlLsn+mCdCxqvGnrDQWzilm1De
-fhiYtUU79nm06PcaewaD+9CL2rvHvRirCG88gGtAPxkZumWK5r7VXNM21+9AUiRg
-OGcEMeyP84LG3rlV8zsxkVrctQgVrXYlCg17LofiDKYGvCYQbTed7N14jHyAxfDZ
-d0jQ
------END CERTIFICATE-----
-
-# Issuer: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
-# Subject: CN=Global Chambersign Root - 2008 O=AC Camerfirma S.A.
-# Label: "Global Chambersign Root - 2008"
-# Serial: 14541511773111788494
-# MD5 Fingerprint: 9e:80:ff:78:01:0c:2e:c1:36:bd:fe:96:90:6e:08:f3
-# SHA1 Fingerprint: 4a:bd:ee:ec:95:0d:35:9c:89:ae:c7:52:a1:2c:5b:29:f6:d6:aa:0c
-# SHA256 Fingerprint: 13:63:35:43:93:34:a7:69:80:16:a0:d3:24:de:72:28:4e:07:9d:7b:52:20:bb:8f:bd:74:78:16:ee:be:ba:ca
------BEGIN CERTIFICATE-----
-MIIHSTCCBTGgAwIBAgIJAMnN0+nVfSPOMA0GCSqGSIb3DQEBBQUAMIGsMQswCQYD
-VQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3VycmVudCBhZGRyZXNzIGF0
-IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAGA1UEBRMJQTgyNzQzMjg3
-MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAlBgNVBAMTHkdsb2JhbCBD
-aGFtYmVyc2lnbiBSb290IC0gMjAwODAeFw0wODA4MDExMjMxNDBaFw0zODA3MzEx
-MjMxNDBaMIGsMQswCQYDVQQGEwJFVTFDMEEGA1UEBxM6TWFkcmlkIChzZWUgY3Vy
-cmVudCBhZGRyZXNzIGF0IHd3dy5jYW1lcmZpcm1hLmNvbS9hZGRyZXNzKTESMBAG
-A1UEBRMJQTgyNzQzMjg3MRswGQYDVQQKExJBQyBDYW1lcmZpcm1hIFMuQS4xJzAl
-BgNVBAMTHkdsb2JhbCBDaGFtYmVyc2lnbiBSb290IC0gMjAwODCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBAMDfVtPkOpt2RbQT2//BthmLN0EYlVJH6xed
-KYiONWwGMi5HYvNJBL99RDaxccy9Wglz1dmFRP+RVyXfXjaOcNFccUMd2drvXNL7
-G706tcuto8xEpw2uIRU/uXpbknXYpBI4iRmKt4DS4jJvVpyR1ogQC7N0ZJJ0YPP2
-zxhPYLIj0Mc7zmFLmY/CDNBAspjcDahOo7kKrmCgrUVSY7pmvWjg+b4aqIG7HkF4
-ddPB/gBVsIdU6CeQNR1MM62X/JcumIS/LMmjv9GYERTtY/jKmIhYF5ntRQOXfjyG
-HoiMvvKRhI9lNNgATH23MRdaKXoKGCQwoze1eqkBfSbW+Q6OWfH9GzO1KTsXO0G2
-Id3UwD2ln58fQ1DJu7xsepeY7s2MH/ucUa6LcL0nn3HAa6x9kGbo1106DbDVwo3V
-yJ2dwW3Q0L9R5OP4wzg2rtandeavhENdk5IMagfeOx2YItaswTXbo6Al/3K1dh3e
-beksZixShNBFks4c5eUzHdwHU1SjqoI7mjcv3N2gZOnm3b2u/GSFHTynyQbehP9r
-6GsaPMWis0L7iwk+XwhSx2LE1AVxv8Rk5Pihg+g+EpuoHtQ2TS9x9o0o9oOpE9Jh
-wZG7SMA0j0GMS0zbaRL/UJScIINZc+18ofLx/d33SdNDWKBWY8o9PeU1VlnpDsog
-zCtLkykPAgMBAAGjggFqMIIBZjASBgNVHRMBAf8ECDAGAQH/AgEMMB0GA1UdDgQW
-BBS5CcqcHtvTbDprru1U8VuTBjUuXjCB4QYDVR0jBIHZMIHWgBS5CcqcHtvTbDpr
-ru1U8VuTBjUuXqGBsqSBrzCBrDELMAkGA1UEBhMCRVUxQzBBBgNVBAcTOk1hZHJp
-ZCAoc2VlIGN1cnJlbnQgYWRkcmVzcyBhdCB3d3cuY2FtZXJmaXJtYS5jb20vYWRk
-cmVzcykxEjAQBgNVBAUTCUE4Mjc0MzI4NzEbMBkGA1UEChMSQUMgQ2FtZXJmaXJt
-YSBTLkEuMScwJQYDVQQDEx5HbG9iYWwgQ2hhbWJlcnNpZ24gUm9vdCAtIDIwMDiC
-CQDJzdPp1X0jzjAOBgNVHQ8BAf8EBAMCAQYwPQYDVR0gBDYwNDAyBgRVHSAAMCow
-KAYIKwYBBQUHAgEWHGh0dHA6Ly9wb2xpY3kuY2FtZXJmaXJtYS5jb20wDQYJKoZI
-hvcNAQEFBQADggIBAICIf3DekijZBZRG/5BXqfEv3xoNa/p8DhxJJHkn2EaqbylZ
-UohwEurdPfWbU1Rv4WCiqAm57OtZfMY18dwY6fFn5a+6ReAJ3spED8IXDneRRXoz
-X1+WLGiLwUePmJs9wOzL9dWCkoQ10b42OFZyMVtHLaoXpGNR6woBrX/sdZ7LoR/x
-fxKxueRkf2fWIyr0uDldmOghp+G9PUIadJpwr2hsUF1Jz//7Dl3mLEfXgTpZALVz
-a2Mg9jFFCDkO9HB+QHBaP9BrQql0PSgvAm11cpUJjUhjxsYjV5KTXjXBjfkK9yyd
-Yhz2rXzdpjEetrHHfoUm+qRqtdpjMNHvkzeyZi99Bffnt0uYlDXA2TopwZ2yUDMd
-SqlapskD7+3056huirRXhOukP9DuqqqHW2Pok+JrqNS4cnhrG+055F3Lm6qH1U9O
-AP7Zap88MQ8oAgF9mOinsKJknnn4SPIVqczmyETrP3iZ8ntxPjzxmKfFGBI/5rso
-M0LpRQp8bfKGeS/Fghl9CYl8slR2iK7ewfPM4W7bMdaTrpmg7yVqc5iJWzouE4ge
-v8CSlDQb4ye3ix5vQv/n6TebUB0tovkC7stYWDpxvGjjqsGvHCgfotwjZT+B6q6Z
-09gwzxMNTxXJhLynSC34MCN32EZLeW32jO06f2ARePTpm67VVMB0gNELQp/B
------END CERTIFICATE-----
-
-# Issuer: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
-# Subject: CN=Go Daddy Root Certificate Authority - G2 O=GoDaddy.com, Inc.
-# Label: "Go Daddy Root Certificate Authority - G2"
-# Serial: 0
-# MD5 Fingerprint: 80:3a:bc:22:c1:e6:fb:8d:9b:3b:27:4a:32:1b:9a:01
-# SHA1 Fingerprint: 47:be:ab:c9:22:ea:e8:0e:78:78:34:62:a7:9f:45:c2:54:fd:e6:8b
-# SHA256 Fingerprint: 45:14:0b:32:47:eb:9c:c8:c5:b4:f0:d7:b5:30:91:f7:32:92:08:9e:6e:5a:63:e2:74:9d:d3:ac:a9:19:8e:da
------BEGIN CERTIFICATE-----
-MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT
-EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp
-ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIz
-NTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH
-EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8GA1UE
-AxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIw
-DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKD
-E6bFIEMBO4Tx5oVJnyfq9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH
-/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD+qK+ihVqf94Lw7YZFAXK6sOoBJQ7Rnwy
-DfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutdfMh8+7ArU6SSYmlRJQVh
-GkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMlNAJWJwGR
-tDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEA
-AaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE
-FDqahQcQZyi27/a9BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmX
-WWcDYfF+OwYxdS2hII5PZYe096acvNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu
-9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r5N9ss4UXnT3ZJE95kTXWXwTr
-gIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYVN8Gb5DKj7Tjo
-2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO
-LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI
-4uJEvlz36hz1
------END CERTIFICATE-----
-
-# Issuer: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Subject: CN=Starfield Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Label: "Starfield Root Certificate Authority - G2"
-# Serial: 0
-# MD5 Fingerprint: d6:39:81:c6:52:7e:96:69:fc:fc:ca:66:ed:05:f2:96
-# SHA1 Fingerprint: b5:1c:06:7c:ee:2b:0c:3d:f8:55:ab:2d:92:f4:fe:39:d4:e7:0f:0e
-# SHA256 Fingerprint: 2c:e1:cb:0b:f9:d2:f9:e1:02:99:3f:be:21:51:52:c3:b2:dd:0c:ab:de:1c:68:e5:31:9b:83:91:54:db:b7:f5
------BEGIN CERTIFICATE-----
-MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVs
-ZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAw
-MFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6
-b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQgVGVj
-aG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZp
-Y2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAL3twQP89o/8ArFvW59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMg
-nLRJdzIpVv257IzdIvpy3Cdhl+72WoTsbhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1
-HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNkN3mSwOxGXn/hbVNMYq/N
-Hwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7NfZTD4p7dN
-dloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0
-HZbUJtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO
-BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0G
-CSqGSIb3DQEBCwUAA4IBAQARWfolTwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjU
-sHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx4mcujJUDJi5DnUox9g61DLu3
-4jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUwF5okxBDgBPfg
-8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K
-pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1
-mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0
------END CERTIFICATE-----
-
-# Issuer: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Subject: CN=Starfield Services Root Certificate Authority - G2 O=Starfield Technologies, Inc.
-# Label: "Starfield Services Root Certificate Authority - G2"
-# Serial: 0
-# MD5 Fingerprint: 17:35:74:af:7b:61:1c:eb:f4:f9:3c:e2:ee:40:f9:a2
-# SHA1 Fingerprint: 92:5a:8f:8d:2c:6d:04:e0:66:5f:59:6a:ff:22:d8:63:e8:25:6f:3f
-# SHA256 Fingerprint: 56:8d:69:05:a2:c8:87:08:a4:b3:02:51:90:ed:cf:ed:b1:97:4a:60:6a:13:c6:e5:29:0f:cb:2a:e6:3e:da:b5
------BEGIN CERTIFICATE-----
-MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMx
-EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT
-HFN0YXJmaWVsZCBUZWNobm9sb2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVs
-ZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5
-MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNVBAYTAlVTMRAwDgYD
-VQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFy
-ZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2Vy
-dmljZXMgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20p
-OsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm2
-8xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4PahHQUw2eeBGg6345AWh1K
-Ts9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLPLJGmpufe
-hRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk
-6mFBrMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAw
-DwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+q
-AdcwKziIorhtSpzyEZGDMA0GCSqGSIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMI
-bw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPPE95Dz+I0swSdHynVv/heyNXB
-ve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTyxQGjhdByPq1z
-qwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd
-iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn
-0q23KXB56jzaYyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCN
-sSi6
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Commercial O=AffirmTrust
-# Subject: CN=AffirmTrust Commercial O=AffirmTrust
-# Label: "AffirmTrust Commercial"
-# Serial: 8608355977964138876
-# MD5 Fingerprint: 82:92:ba:5b:ef:cd:8a:6f:a6:3d:55:f9:84:f6:d6:b7
-# SHA1 Fingerprint: f9:b5:b6:32:45:5f:9c:be:ec:57:5f:80:dc:e9:6e:2c:c7:b2:78:b7
-# SHA256 Fingerprint: 03:76:ab:1d:54:c5:f9:80:3c:e4:b2:e2:01:a0:ee:7e:ef:7b:57:b6:36:e8:a9:3c:9b:8d:48:60:c9:6f:5f:a7
------BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBDb21tZXJjaWFsMB4XDTEwMDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6EqdbDuKP
-Hx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yr
-ba0F8PrVC8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPAL
-MeIrJmqbTFeurCA+ukV6BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1
-yHp52UKqK39c/s4mT6NmgTWvRLpUHhwwMmWd5jyTXlBOeuM61G7MGvv50jeuJCqr
-VwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNVHQ4EFgQUnZPGU4teyq8/
-nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYG
-XUPGhi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNj
-vbz4YYCanrHOQnDiqX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivt
-Z8SOyUOyXGsViQK8YvxO8rUzqrJv0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9g
-N53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0khsUlHRUe072o0EclNmsxZt9YC
-nlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8=
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Networking O=AffirmTrust
-# Subject: CN=AffirmTrust Networking O=AffirmTrust
-# Label: "AffirmTrust Networking"
-# Serial: 8957382827206547757
-# MD5 Fingerprint: 42:65:ca:be:01:9a:9a:4c:a9:8c:41:49:cd:c0:d5:7f
-# SHA1 Fingerprint: 29:36:21:02:8b:20:ed:02:f5:66:c5:32:d1:d6:ed:90:9f:45:00:2f
-# SHA256 Fingerprint: 0a:81:ec:5a:92:97:77:f1:45:90:4a:f3:8d:5d:50:9f:66:b5:e2:c5:8f:cd:b5:31:05:8b:0e:17:f3:f0:b4:1b
------BEGIN CERTIFICATE-----
-MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVz
-dCBOZXR3b3JraW5nMB4XDTEwMDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDEL
-MAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZp
-cm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
-AQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SEHi3y
-YJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbua
-kCNrmreIdIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRL
-QESxG9fhwoXA3hA/Pe24/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp
-6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gbh+0t+nvujArjqWaJGctB+d1ENmHP4ndG
-yH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNVHQ4EFgQUBx/S55zawm6i
-QLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJ
-KoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfO
-tDIuUFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzu
-QY0x2+c06lkh1QF612S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZ
-Lgo/bNjR9eUJtGxUAArgFU2HdW23WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4u
-olu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9/ZFvgrG+CJPbFEfxojfHRZ48
-x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s=
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Premium O=AffirmTrust
-# Subject: CN=AffirmTrust Premium O=AffirmTrust
-# Label: "AffirmTrust Premium"
-# Serial: 7893706540734352110
-# MD5 Fingerprint: c4:5d:0e:48:b6:ac:28:30:4e:0a:bc:f9:38:16:87:57
-# SHA1 Fingerprint: d8:a6:33:2c:e0:03:6f:b1:85:f6:63:4f:7d:6a:06:65:26:32:28:27
-# SHA256 Fingerprint: 70:a7:3f:7f:37:6b:60:07:42:48:90:45:34:b1:14:82:d5:bf:0e:69:8e:cc:49:8d:f5:25:77:eb:f2:e9:3b:9a
------BEGIN CERTIFICATE-----
-MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UE
-BhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVz
-dCBQcmVtaXVtMB4XDTEwMDEyOTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkG
-A1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1U
-cnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxBLf
-qV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtnBKAQ
-JG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ
-+jjeRFcV5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrS
-s8PhaJyJ+HoAVt70VZVs+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5
-HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmdGPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d7
-70O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5Rp9EixAqnOEhss/n/fauG
-V+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NIS+LI+H+S
-qHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S
-5u046uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4Ia
-C1nEWTJ3s7xgaVY5/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TX
-OwF0lkLgAOIua+rF7nKsu7/+6qqo+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYE
-FJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/
-BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByvMiPIs0laUZx2
-KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg
-Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B
-8OWycvpEgjNC6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQ
-MKSOyARiqcTtNd56l+0OOF6SL5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc
-0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK+4w1IX2COPKpVJEZNZOUbWo6xbLQ
-u4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmVBtWVyuEklut89pMF
-u+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFgIxpH
-YoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8
-GKa1qF60g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaO
-RtGdFNrHF+QFlozEJLUbzxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6e
-KeC2uAloGRwYQw==
------END CERTIFICATE-----
-
-# Issuer: CN=AffirmTrust Premium ECC O=AffirmTrust
-# Subject: CN=AffirmTrust Premium ECC O=AffirmTrust
-# Label: "AffirmTrust Premium ECC"
-# Serial: 8401224907861490260
-# MD5 Fingerprint: 64:b0:09:55:cf:b1:d5:99:e2:be:13:ab:a6:5d:ea:4d
-# SHA1 Fingerprint: b8:23:6b:00:2f:1d:16:86:53:01:55:6c:11:a4:37:ca:eb:ff:c3:bb
-# SHA256 Fingerprint: bd:71:fd:f6:da:97:e4:cf:62:d1:64:7a:dd:25:81:b0:7d:79:ad:f8:39:7e:b4:ec:ba:9c:5e:84:88:82:14:23
------BEGIN CERTIFICATE-----
-MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMC
-VVMxFDASBgNVBAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQ
-cmVtaXVtIEVDQzAeFw0xMDAxMjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJ
-BgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1UcnVzdDEgMB4GA1UEAwwXQWZmaXJt
-VHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQNMF4bFZ0D
-0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQN8O9
-ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0G
-A1UdDgQWBBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4G
-A1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/Vs
-aobgxCd05DhT1wV/GzTjxi+zygk8N53X57hG8f2h4nECMEJZh0PUUd+60wkyWs6I
-flc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKMeQ==
------END CERTIFICATE-----
-
-# Issuer: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
-# Subject: CN=Certum Trusted Network CA O=Unizeto Technologies S.A. OU=Certum Certification Authority
-# Label: "Certum Trusted Network CA"
-# Serial: 279744
-# MD5 Fingerprint: d5:e9:81:40:c5:18:69:fc:46:2c:89:75:62:0f:aa:78
-# SHA1 Fingerprint: 07:e0:32:e0:20:b7:2c:3f:19:2f:06:28:a2:59:3a:19:a7:0f:06:9e
-# SHA256 Fingerprint: 5c:58:46:8d:55:f5:8e:49:7e:74:39:82:d2:b5:00:10:b6:d1:65:37:4a:cf:83:a7:d4:a3:2d:b7:68:c4:40:8e
------BEGIN CERTIFICATE-----
-MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBM
-MSIwIAYDVQQKExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5D
-ZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBU
-cnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIyMTIwNzM3WhcNMjkxMjMxMTIwNzM3
-WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMg
-Uy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSIw
-IAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0B
-AQEFAAOCAQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rH
-UV+rpDKmYYe2bg+G0jACl/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LM
-TXPb865Px1bVWqeWifrzq2jUI4ZZJ88JJ7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVU
-BBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4fOQtf/WsX+sWn7Et0brM
-kUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0cvW0QM8x
-AcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNV
-HQ8BAf8EBAMCAQYwDQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15y
-sHhE49wcrwn9I0j6vSrEuVUEtRCjjSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfL
-I9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1mS1FhIrlQgnXdAIv94nYmem8
-J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5ajZt3hrvJBW8qY
-VoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI
-03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw=
------END CERTIFICATE-----
-
-# Issuer: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
-# Subject: CN=Certinomis - Autorité Racine O=Certinomis OU=0002 433998903
-# Label: "Certinomis - Autorité Racine"
-# Serial: 1
-# MD5 Fingerprint: 7f:30:78:8c:03:e3:ca:c9:0a:e2:c9:ea:1e:aa:55:1a
-# SHA1 Fingerprint: 2e:14:da:ec:28:f0:fa:1e:8e:38:9a:4e:ab:eb:26:c0:0a:d3:83:c3
-# SHA256 Fingerprint: fc:bf:e2:88:62:06:f7:2b:27:59:3c:8b:07:02:97:e1:2d:76:9e:d1:0e:d7:93:07:05:a8:09:8e:ff:c1:4d:17
------BEGIN CERTIFICATE-----
-MIIFnDCCA4SgAwIBAgIBATANBgkqhkiG9w0BAQUFADBjMQswCQYDVQQGEwJGUjET
-MBEGA1UEChMKQ2VydGlub21pczEXMBUGA1UECxMOMDAwMiA0MzM5OTg5MDMxJjAk
-BgNVBAMMHUNlcnRpbm9taXMgLSBBdXRvcml0w6kgUmFjaW5lMB4XDTA4MDkxNzA4
-Mjg1OVoXDTI4MDkxNzA4Mjg1OVowYzELMAkGA1UEBhMCRlIxEzARBgNVBAoTCkNl
-cnRpbm9taXMxFzAVBgNVBAsTDjAwMDIgNDMzOTk4OTAzMSYwJAYDVQQDDB1DZXJ0
-aW5vbWlzIC0gQXV0b3JpdMOpIFJhY2luZTCCAiIwDQYJKoZIhvcNAQEBBQADggIP
-ADCCAgoCggIBAJ2Fn4bT46/HsmtuM+Cet0I0VZ35gb5j2CN2DpdUzZlMGvE5x4jY
-F1AMnmHawE5V3udauHpOd4cN5bjr+p5eex7Ezyh0x5P1FMYiKAT5kcOrJ3NqDi5N
-8y4oH3DfVS9O7cdxbwlyLu3VMpfQ8Vh30WC8Tl7bmoT2R2FFK/ZQpn9qcSdIhDWe
-rP5pqZ56XjUl+rSnSTV3lqc2W+HN3yNw2F1MpQiD8aYkOBOo7C+ooWfHpi2GR+6K
-/OybDnT0K0kCe5B1jPyZOQE51kqJ5Z52qz6WKDgmi92NjMD2AR5vpTESOH2VwnHu
-7XSu5DaiQ3XV8QCb4uTXzEIDS3h65X27uK4uIJPT5GHfceF2Z5c/tt9qc1pkIuVC
-28+BA5PY9OMQ4HL2AHCs8MF6DwV/zzRpRbWT5BnbUhYjBYkOjUjkJW+zeL9i9Qf6
-lSTClrLooyPCXQP8w9PlfMl1I9f09bze5N/NgL+RiH2nE7Q5uiy6vdFrzPOlKO1E
-nn1So2+WLhl+HPNbxxaOu2B9d2ZHVIIAEWBsMsGoOBvrbpgT1u449fCfDu/+MYHB
-0iSVL1N6aaLwD4ZFjliCK0wi1F6g530mJ0jfJUaNSih8hp75mxpZuWW/Bd22Ql09
-5gBIgl4g9xGC3srYn+Y3RyYe63j3YcNBZFgCQfna4NH4+ej9Uji29YnfAgMBAAGj
-WzBZMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBQN
-jLZh2kS40RR9w759XkjwzspqsDAXBgNVHSAEEDAOMAwGCiqBegFWAgIAAQEwDQYJ
-KoZIhvcNAQEFBQADggIBACQ+YAZ+He86PtvqrxyaLAEL9MW12Ukx9F1BjYkMTv9s
-ov3/4gbIOZ/xWqndIlgVqIrTseYyCYIDbNc/CMf4uboAbbnW/FIyXaR/pDGUu7ZM
-OH8oMDX/nyNTt7buFHAAQCvaR6s0fl6nVjBhK4tDrP22iCj1a7Y+YEq6QpA0Z43q
-619FVDsXrIvkxmUP7tCMXWY5zjKn2BCXwH40nJ+U8/aGH88bc62UeYdocMMzpXDn
-2NU4lG9jeeu/Cg4I58UvD0KgKxRA/yHgBcUn4YQRE7rWhh1BCxMjidPJC+iKunqj
-o3M3NYB9Ergzd0A4wPpeMNLytqOx1qKVl4GbUu1pTP+A5FPbVFsDbVRfsbjvJL1v
-nxHDx2TCDyhihWZeGnuyt++uNckZM6i4J9szVb9o4XVIRFb7zdNIu0eJOqxp9YDG
-5ERQL1TEqkPFMTFYvZbF6nVsmnWxTfj3l/+WFvKXTej28xH5On2KOG4Ey+HTRRWq
-pdEdnV1j6CTmNhTih60bWfVEm/vXd3wfAXBioSAaosUaKPQhA+4u2cGA6rnZgtZb
-dsLLO7XSAPCjDuGtbkD326C00EauFddEwk01+dIL8hf2rGbVJLJP0RyZwG71fet0
-BLj5TXcJ17TPBzAJ8bgAVtkXFhYKK4bfjwEZGuW7gmP/vgt2Fl43N+bYdJeimUV5
------END CERTIFICATE-----
-
-# Issuer: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA
-# Subject: CN=Root CA Generalitat Valenciana O=Generalitat Valenciana OU=PKIGVA
-# Label: "Root CA Generalitat Valenciana"
-# Serial: 994436456
-# MD5 Fingerprint: 2c:8c:17:5e:b1:54:ab:93:17:b5:36:5a:db:d1:c6:f2
-# SHA1 Fingerprint: a0:73:e5:c5:bd:43:61:0d:86:4c:21:13:0a:85:58:57:cc:9c:ea:46
-# SHA256 Fingerprint: 8c:4e:df:d0:43:48:f3:22:96:9e:7e:29:a4:cd:4d:ca:00:46:55:06:1c:16:e1:b0:76:42:2e:f3:42:ad:63:0e
------BEGIN CERTIFICATE-----
-MIIGizCCBXOgAwIBAgIEO0XlaDANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJF
-UzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJ
-R1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwHhcN
-MDEwNzA2MTYyMjQ3WhcNMjEwNzAxMTUyMjQ3WjBoMQswCQYDVQQGEwJFUzEfMB0G
-A1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0GA1UECxMGUEtJR1ZBMScw
-JQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVuY2lhbmEwggEiMA0GCSqG
-SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDGKqtXETcvIorKA3Qdyu0togu8M1JAJke+
-WmmmO3I2F0zo37i7L3bhQEZ0ZQKQUgi0/6iMweDHiVYQOTPvaLRfX9ptI6GJXiKj
-SgbwJ/BXufjpTjJ3Cj9BZPPrZe52/lSqfR0grvPXdMIKX/UIKFIIzFVd0g/bmoGl
-u6GzwZTNVOAydTGRGmKy3nXiz0+J2ZGQD0EbtFpKd71ng+CT516nDOeB0/RSrFOy
-A8dEJvt55cs0YFAQexvba9dHq198aMpunUEDEO5rmXteJajCq+TA81yc477OMUxk
-Hl6AovWDfgzWyoxVjr7gvkkHD6MkQXpYHYTqWBLI4bft75PelAgxAgMBAAGjggM7
-MIIDNzAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnBr
-aS5ndmEuZXMwEgYDVR0TAQH/BAgwBgEB/wIBAjCCAjQGA1UdIASCAiswggInMIIC
-IwYKKwYBBAG/VQIBADCCAhMwggHoBggrBgEFBQcCAjCCAdoeggHWAEEAdQB0AG8A
-cgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEAYwBpAPMAbgAgAFIA
-YQDtAHoAIABkAGUAIABsAGEAIABHAGUAbgBlAHIAYQBsAGkAdABhAHQAIABWAGEA
-bABlAG4AYwBpAGEAbgBhAC4ADQAKAEwAYQAgAEQAZQBjAGwAYQByAGEAYwBpAPMA
-bgAgAGQAZQAgAFAAcgDhAGMAdABpAGMAYQBzACAAZABlACAAQwBlAHIAdABpAGYA
-aQBjAGEAYwBpAPMAbgAgAHEAdQBlACAAcgBpAGcAZQAgAGUAbAAgAGYAdQBuAGMA
-aQBvAG4AYQBtAGkAZQBuAHQAbwAgAGQAZQAgAGwAYQAgAHAAcgBlAHMAZQBuAHQA
-ZQAgAEEAdQB0AG8AcgBpAGQAYQBkACAAZABlACAAQwBlAHIAdABpAGYAaQBjAGEA
-YwBpAPMAbgAgAHMAZQAgAGUAbgBjAHUAZQBuAHQAcgBhACAAZQBuACAAbABhACAA
-ZABpAHIAZQBjAGMAaQDzAG4AIAB3AGUAYgAgAGgAdAB0AHAAOgAvAC8AdwB3AHcA
-LgBwAGsAaQAuAGcAdgBhAC4AZQBzAC8AYwBwAHMwJQYIKwYBBQUHAgEWGWh0dHA6
-Ly93d3cucGtpLmd2YS5lcy9jcHMwHQYDVR0OBBYEFHs100DSHHgZZu90ECjcPk+y
-eAT8MIGVBgNVHSMEgY0wgYqAFHs100DSHHgZZu90ECjcPk+yeAT8oWykajBoMQsw
-CQYDVQQGEwJFUzEfMB0GA1UEChMWR2VuZXJhbGl0YXQgVmFsZW5jaWFuYTEPMA0G
-A1UECxMGUEtJR1ZBMScwJQYDVQQDEx5Sb290IENBIEdlbmVyYWxpdGF0IFZhbGVu
-Y2lhbmGCBDtF5WgwDQYJKoZIhvcNAQEFBQADggEBACRhTvW1yEICKrNcda3Fbcrn
-lD+laJWIwVTAEGmiEi8YPyVQqHxK6sYJ2fR1xkDar1CdPaUWu20xxsdzCkj+IHLt
-b8zog2EWRpABlUt9jppSCS/2bxzkoXHPjCpaF3ODR00PNvsETUlR4hTJZGH71BTg
-9J63NI8KJr2XXPR5OkowGcytT6CYirQxlyric21+eLj4iIlPsSKRZEv1UN4D2+XF
-ducTZnV+ZfsBn5OHiJ35Rld8TWCvmHMTI6QgkYH60GFmuH3Rr9ZvHmw96RH9qfmC
-IoaZM3Fa6hlXPZHNqcCjbgcTpsnt+GijnsNacgmHKNHEc8RzGF9QdRYxn7fofMM=
------END CERTIFICATE-----
-
-# Issuer: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03
-# Subject: CN=A-Trust-nQual-03 O=A-Trust Ges. f. Sicherheitssysteme im elektr. Datenverkehr GmbH OU=A-Trust-nQual-03
-# Label: "A-Trust-nQual-03"
-# Serial: 93214
-# MD5 Fingerprint: 49:63:ae:27:f4:d5:95:3d:d8:db:24:86:b8:9c:07:53
-# SHA1 Fingerprint: d3:c0:63:f2:19:ed:07:3e:34:ad:5d:75:0b:32:76:29:ff:d5:9a:f2
-# SHA256 Fingerprint: 79:3c:bf:45:59:b9:fd:e3:8a:b2:2d:f1:68:69:f6:98:81:ae:14:c4:b0:13:9a:c7:88:a7:8a:1a:fc:ca:02:fb
------BEGIN CERTIFICATE-----
-MIIDzzCCAregAwIBAgIDAWweMA0GCSqGSIb3DQEBBQUAMIGNMQswCQYDVQQGEwJB
-VDFIMEYGA1UECgw/QS1UcnVzdCBHZXMuIGYuIFNpY2hlcmhlaXRzc3lzdGVtZSBp
-bSBlbGVrdHIuIERhdGVudmVya2VociBHbWJIMRkwFwYDVQQLDBBBLVRydXN0LW5R
-dWFsLTAzMRkwFwYDVQQDDBBBLVRydXN0LW5RdWFsLTAzMB4XDTA1MDgxNzIyMDAw
-MFoXDTE1MDgxNzIyMDAwMFowgY0xCzAJBgNVBAYTAkFUMUgwRgYDVQQKDD9BLVRy
-dXN0IEdlcy4gZi4gU2ljaGVyaGVpdHNzeXN0ZW1lIGltIGVsZWt0ci4gRGF0ZW52
-ZXJrZWhyIEdtYkgxGTAXBgNVBAsMEEEtVHJ1c3QtblF1YWwtMDMxGTAXBgNVBAMM
-EEEtVHJ1c3QtblF1YWwtMDMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCtPWFuA/OQO8BBC4SAzewqo51ru27CQoT3URThoKgtUaNR8t4j8DRE/5TrzAUj
-lUC5B3ilJfYKvUWG6Nm9wASOhURh73+nyfrBJcyFLGM/BWBzSQXgYHiVEEvc+RFZ
-znF/QJuKqiTfC0Li21a8StKlDJu3Qz7dg9MmEALP6iPESU7l0+m0iKsMrmKS1GWH
-2WrX9IWf5DMiJaXlyDO6w8dB3F/GaswADm0yqLaHNgBid5seHzTLkDx4iHQF63n1
-k3Flyp3HaxgtPVxO59X4PzF9j4fsCiIvI+n+u33J4PTs63zEsMMtYrWacdaxaujs
-2e3Vcuy+VwHOBVWf3tFgiBCzAgMBAAGjNjA0MA8GA1UdEwEB/wQFMAMBAf8wEQYD
-VR0OBAoECERqlWdVeRFPMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQUFAAOC
-AQEAVdRU0VlIXLOThaq/Yy/kgM40ozRiPvbY7meIMQQDbwvUB/tOdQ/TLtPAF8fG
-KOwGDREkDg6lXb+MshOWcdzUzg4NCmgybLlBMRmrsQd7TZjTXLDR8KdCoLXEjq/+
-8T/0709GAHbrAvv5ndJAlseIOrifEXnzgGWovR/TeIGgUUw3tKZdJXDRZslo+S4R
-FGjxVJgIrCaSD96JntT6s3kr0qN51OyLrIdTaEJMUVF0HhsnLuP1Hyl0Te2v9+GS
-mYHovjrHF1D2t8b8m7CKa9aIA5GPBnc6hQLdmNVDeD/GMBWsm2vLV7eJUYs66MmE
-DNuxUCAKGkq6ahq97BvIxYSazQ==
------END CERTIFICATE-----
-
-# Issuer: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
-# Subject: CN=TWCA Root Certification Authority O=TAIWAN-CA OU=Root CA
-# Label: "TWCA Root Certification Authority"
-# Serial: 1
-# MD5 Fingerprint: aa:08:8f:f6:f9:7b:b7:f2:b1:a7:1e:9b:ea:ea:bd:79
-# SHA1 Fingerprint: cf:9e:87:6d:d3:eb:fc:42:26:97:a3:b5:a3:7a:a0:76:a9:06:23:48
-# SHA256 Fingerprint: bf:d8:8f:e1:10:1c:41:ae:3e:80:1b:f8:be:56:35:0e:e9:ba:d1:a6:b9:bd:51:5e:dc:5c:6d:5b:87:11:ac:44
------BEGIN CERTIFICATE-----
-MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzES
-MBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFU
-V0NBIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMz
-WhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJVEFJV0FO
-LUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
-AQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFE
-AcK0HMMxQhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HH
-K3XLfJ+utdGdIzdjp9xCoi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeX
-RfwZVzsrb+RH9JlF/h3x+JejiB03HFyP4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/z
-rX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1ry+UPizgN7gr8/g+YnzAx
-3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV
-HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkq
-hkiG9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeC
-MErJk/9q56YAf4lCmtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdls
-XebQ79NqZp4VKIV66IIArB6nCWlWQtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62D
-lhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVYT0bf+215WfKEIlKuD8z7fDvn
-aspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocnyYh0igzyXxfkZ
-YiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw==
------END CERTIFICATE-----
-
-# Issuer: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
-# Subject: O=SECOM Trust Systems CO.,LTD. OU=Security Communication RootCA2
-# Label: "Security Communication RootCA2"
-# Serial: 0
-# MD5 Fingerprint: 6c:39:7d:a4:0e:55:59:b2:3f:d6:41:b1:12:50:de:43
-# SHA1 Fingerprint: 5f:3b:8c:f2:f8:10:b3:7d:78:b4:ce:ec:19:19:c3:73:34:b9:c7:74
-# SHA256 Fingerprint: 51:3b:2c:ec:b8:10:d4:cd:e5:dd:85:39:1a:df:c6:c2:dd:60:d8:7b:b7:36:d2:b5:21:48:4a:a4:7a:0e:be:f6
------BEGIN CERTIFICATE-----
-MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDEl
-MCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMe
-U2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoX
-DTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRy
-dXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3VyaXR5IENvbW11bmlj
-YXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANAV
-OVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGr
-zbl+dp+++T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVM
-VAX3NuRFg3sUZdbcDE3R3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQ
-hNBqyjoGADdH5H5XTz+L62e4iKrFvlNVspHEfbmwhRkGeC7bYRr6hfVKkaHnFtWO
-ojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1KEOtOghY6rCcMU/Gt1SSw
-awNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8QIH4D5cs
-OPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3
-DQEBCwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpF
-coJxDjrSzG+ntKEju/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXc
-okgfGT+Ok+vx+hfuzU7jBBJV1uXk3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8
-t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6qtnRGEmyR7jTV7JqR50S+kDFy
-1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29mvVXIwAHIRc/
-SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03
------END CERTIFICATE-----
-
-# Issuer: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
-# Subject: CN=Hellenic Academic and Research Institutions RootCA 2011 O=Hellenic Academic and Research Institutions Cert. Authority
-# Label: "Hellenic Academic and Research Institutions RootCA 2011"
-# Serial: 0
-# MD5 Fingerprint: 73:9f:4c:4b:73:5b:79:e9:fa:ba:1c:ef:6e:cb:d5:c9
-# SHA1 Fingerprint: fe:45:65:9b:79:03:5b:98:a1:61:b5:51:2e:ac:da:58:09:48:22:4d
-# SHA256 Fingerprint: bc:10:4f:15:a4:8b:e7:09:dc:a5:42:a7:e1:d4:b9:df:6f:05:45:27:e8:02:ea:a9:2d:59:54:44:25:8a:fe:71
------BEGIN CERTIFICATE-----
-MIIEMTCCAxmgAwIBAgIBADANBgkqhkiG9w0BAQUFADCBlTELMAkGA1UEBhMCR1Ix
-RDBCBgNVBAoTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1
-dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUAwPgYDVQQDEzdIZWxsZW5pYyBBY2FkZW1p
-YyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIFJvb3RDQSAyMDExMB4XDTExMTIw
-NjEzNDk1MloXDTMxMTIwMTEzNDk1MlowgZUxCzAJBgNVBAYTAkdSMUQwQgYDVQQK
-EztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIENl
-cnQuIEF1dGhvcml0eTFAMD4GA1UEAxM3SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJl
-c2VhcmNoIEluc3RpdHV0aW9ucyBSb290Q0EgMjAxMTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBAKlTAOMupvaO+mDYLZU++CwqVE7NuYRhlFhPjz2L5EPz
-dYmNUeTDN9KKiE15HrcS3UN4SoqS5tdI1Q+kOilENbgH9mgdVc04UfCMJDGFr4PJ
-fel3r+0ae50X+bOdOFAPplp5kYCvN66m0zH7tSYJnTxa71HFK9+WXesyHgLacEns
-bgzImjeN9/E2YEsmLIKe0HjzDQ9jpFEw4fkrJxIH2Oq9GGKYsFk3fb7u8yBRQlqD
-75O6aRXxYp2fmTmCobd0LovUxQt7L/DICto9eQqakxylKHJzkUOap9FNhYS5qXSP
-FEDH3N6sQWRstBmbAmNtJGSPRLIl6s5ddAxjMlyNh+UCAwEAAaOBiTCBhjAPBgNV
-HRMBAf8EBTADAQH/MAsGA1UdDwQEAwIBBjAdBgNVHQ4EFgQUppFC/RNhSiOeCKQp
-5dgTBCPuQSUwRwYDVR0eBEAwPqA8MAWCAy5ncjAFggMuZXUwBoIELmVkdTAGggQu
-b3JnMAWBAy5ncjAFgQMuZXUwBoEELmVkdTAGgQQub3JnMA0GCSqGSIb3DQEBBQUA
-A4IBAQAf73lB4XtuP7KMhjdCSk4cNx6NZrokgclPEg8hwAOXhiVtXdMiKahsog2p
-6z0GW5k6x8zDmjR/qw7IThzh+uTczQ2+vyT+bOdrwg3IBp5OjWEopmr95fZi6hg8
-TqBTnbI6nOulnJEWtk2C4AwFSKls9cz4y51JtPACpf1wA+2KIaWuE4ZJwzNzvoc7
-dIsXRSZMFpGD/md9zU1jZ/rzAxKWeAaNsWftjj++n08C9bMJL/NMh98qy5V8Acys
-Nnq/onN694/BtZqhFLKPM58N7yLcZnuEvUUXBj08yrl3NI/K6s8/MT7jiOOASSXI
-l7WdmplNsDz4SgCbZN2fOUvRJ9e4
------END CERTIFICATE-----
-
-# Issuer: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
-# Subject: CN=Actalis Authentication Root CA O=Actalis S.p.A./03358520967
-# Label: "Actalis Authentication Root CA"
-# Serial: 6271844772424770508
-# MD5 Fingerprint: 69:c1:0d:4f:07:a3:1b:c3:fe:56:3d:04:bc:11:f6:a6
-# SHA1 Fingerprint: f3:73:b3:87:06:5a:28:84:8a:f2:f3:4a:ce:19:2b:dd:c7:8e:9c:ac
-# SHA256 Fingerprint: 55:92:60:84:ec:96:3a:64:b9:6e:2a:be:01:ce:0b:a8:6a:64:fb:fe:bc:c7:aa:b5:af:c1:55:b3:7f:d7:60:66
------BEGIN CERTIFICATE-----
-MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UE
-BhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8w
-MzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290
-IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDkyMjExMjIwMlowazELMAkGA1UEBhMC
-SVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1
-ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENB
-MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNv
-UTufClrJwkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX
-4ay8IMKx4INRimlNAJZaby/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9
-KK3giq0itFZljoZUj5NDKd45RnijMCO6zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/
-gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1fYVEiVRvjRuPjPdA1Yprb
-rxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2oxgkg4YQ
-51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2F
-be8lEfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxe
-KF+w6D9Fz8+vm2/7hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4F
-v6MGn8i1zeQf1xcGDXqVdFUNaBr8EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbn
-fpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5jF66CyCU3nuDuP/jVo23Eek7
-jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLYiDrIn3hm7Ynz
-ezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt
-ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQAL
-e3KHwGCmSUyIWOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70
-jsNjLiNmsGe+b7bAEzlgqqI0JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDz
-WochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKxK3JCaKygvU5a2hi/a5iB0P2avl4V
-SM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+Xlff1ANATIGk0k9j
-pwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC4yyX
-X04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+Ok
-fcvHlXHo2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7R
-K4X9p2jIugErsWx0Hbhzlefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btU
-ZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXemOR/qnuOf0GZvBeyqdn6/axag67XH/JJU
-LysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9vwGYT7JZVEc+NHt4bVaT
-LnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg==
------END CERTIFICATE-----
-
-# Issuer: O=Trustis Limited OU=Trustis FPS Root CA
-# Subject: O=Trustis Limited OU=Trustis FPS Root CA
-# Label: "Trustis FPS Root CA"
-# Serial: 36053640375399034304724988975563710553
-# MD5 Fingerprint: 30:c9:e7:1e:6b:e6:14:eb:65:b2:16:69:20:31:67:4d
-# SHA1 Fingerprint: 3b:c0:38:0b:33:c3:f6:a6:0c:86:15:22:93:d9:df:f5:4b:81:c0:04
-# SHA256 Fingerprint: c1:b4:82:99:ab:a5:20:8f:e9:63:0a:ce:55:ca:68:a0:3e:da:5a:51:9c:88:02:a0:d3:a6:73:be:8f:8e:55:7d
------BEGIN CERTIFICATE-----
-MIIDZzCCAk+gAwIBAgIQGx+ttiD5JNM2a/fH8YygWTANBgkqhkiG9w0BAQUFADBF
-MQswCQYDVQQGEwJHQjEYMBYGA1UEChMPVHJ1c3RpcyBMaW1pdGVkMRwwGgYDVQQL
-ExNUcnVzdGlzIEZQUyBSb290IENBMB4XDTAzMTIyMzEyMTQwNloXDTI0MDEyMTEx
-MzY1NFowRTELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1RydXN0aXMgTGltaXRlZDEc
-MBoGA1UECxMTVHJ1c3RpcyBGUFMgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
-ggEPADCCAQoCggEBAMVQe547NdDfxIzNjpvto8A2mfRC6qc+gIMPpqdZh8mQRUN+
-AOqGeSoDvT03mYlmt+WKVoaTnGhLaASMk5MCPjDSNzoiYYkchU59j9WvezX2fihH
-iTHcDnlkH5nSW7r+f2C/revnPDgpai/lkQtV/+xvWNUtyd5MZnGPDNcE2gfmHhjj
-vSkCqPoc4Vu5g6hBSLwacY3nYuUtsuvffM/bq1rKMfFMIvMFE/eC+XN5DL7XSxzA
-0RU8k0Fk0ea+IxciAIleH2ulrG6nS4zto3Lmr2NNL4XSFDWaLk6M6jKYKIahkQlB
-OrTh4/L68MkKokHdqeMDx4gVOxzUGpTXn2RZEm0CAwEAAaNTMFEwDwYDVR0TAQH/
-BAUwAwEB/zAfBgNVHSMEGDAWgBS6+nEleYtXQSUhhgtx67JkDoshZzAdBgNVHQ4E
-FgQUuvpxJXmLV0ElIYYLceuyZA6LIWcwDQYJKoZIhvcNAQEFBQADggEBAH5Y//01
-GX2cGE+esCu8jowU/yyg2kdbw++BLa8F6nRIW/M+TgfHbcWzk88iNVy2P3UnXwmW
-zaD+vkAMXBJV+JOCyinpXj9WV4s4NvdFGkwozZ5BuO1WTISkQMi4sKUraXAEasP4
-1BIy+Q7DsdwyhEQsb8tGD+pmQQ9P8Vilpg0ND2HepZ5dfWWhPBfnqFVO76DH7cZE
-f1T1o+CP8HxVIo8ptoGj4W1OLBuAZ+ytIJ8MYmHVl/9D7S3B2l0pKoU/rGXuhg8F
-jZBf3+6f9L/uHfuY5H+QK4R4EA5sSVPvFVtlRkpdr7r7OnIdzfYliB6XzCGcKQEN
-ZetX2fNXlrtIzYE=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Subject: CN=StartCom Certification Authority O=StartCom Ltd. OU=Secure Digital Certificate Signing
-# Label: "StartCom Certification Authority"
-# Serial: 45
-# MD5 Fingerprint: c9:3b:0d:84:41:fc:a4:76:79:23:08:57:de:10:19:16
-# SHA1 Fingerprint: a3:f1:33:3f:e2:42:bf:cf:c5:d1:4e:8f:39:42:98:40:68:10:d1:a0
-# SHA256 Fingerprint: e1:78:90:ee:09:a3:fb:f4:f4:8b:9c:41:4a:17:d6:37:b7:a5:06:47:e9:bc:75:23:22:72:7f:cc:17:42:a9:11
------BEGIN CERTIFICATE-----
-MIIHhzCCBW+gAwIBAgIBLTANBgkqhkiG9w0BAQsFADB9MQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERpZ2l0YWwg
-Q2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3RhcnRDb20gQ2VydGlmaWNh
-dGlvbiBBdXRob3JpdHkwHhcNMDYwOTE3MTk0NjM3WhcNMzYwOTE3MTk0NjM2WjB9
-MQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi
-U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzEpMCcGA1UEAxMgU3Rh
-cnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUA
-A4ICDwAwggIKAoICAQDBiNsJvGxGfHiflXu1M5DycmLWwTYgIiRezul38kMKogZk
-pMyONvg45iPwbm2xPN1yo4UcodM9tDMr0y+v/uqwQVlntsQGfQqedIXWeUyAN3rf
-OQVSWff0G0ZDpNKFhdLDcfN1YjS6LIp/Ho/u7TTQEceWzVI9ujPW3U3eCztKS5/C
-Ji/6tRYccjV3yjxd5srhJosaNnZcAdt0FCX+7bWgiA/deMotHweXMAEtcnn6RtYT
-Kqi5pquDSR3l8u/d5AGOGAqPY1MWhWKpDhk6zLVmpsJrdAfkK+F2PrRt2PZE4XNi
-HzvEvqBTViVsUQn3qqvKv3b9bZvzndu/PWa8DFaqr5hIlTpL36dYUNk4dalb6kMM
-Av+Z6+hsTXBbKWWc3apdzK8BMewM69KN6Oqce+Zu9ydmDBpI125C4z/eIT574Q1w
-+2OqqGwaVLRcJXrJosmLFqa7LH4XXgVNWG4SHQHuEhANxjJ/GP/89PrNbpHoNkm+
-Gkhpi8KWTRoSsmkXwQqQ1vp5Iki/untp+HDH+no32NgN0nZPV/+Qt+OR0t3vwmC3
-Zzrd/qqc8NSLf3Iizsafl7b4r4qgEKjZ+xjGtrVcUjyJthkqcwEKDwOzEmDyei+B
-26Nu/yYwl/WL3YlXtq09s68rxbd2AvCl1iuahhQqcvbjM4xdCUsT37uMdBNSSwID
-AQABo4ICEDCCAgwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYD
-VR0OBBYEFE4L7xqkQFulF2mHMMo0aEPQQa7yMB8GA1UdIwQYMBaAFE4L7xqkQFul
-F2mHMMo0aEPQQa7yMIIBWgYDVR0gBIIBUTCCAU0wggFJBgsrBgEEAYG1NwEBATCC
-ATgwLgYIKwYBBQUHAgEWImh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5w
-ZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93d3cuc3RhcnRzc2wuY29tL2ludGVybWVk
-aWF0ZS5wZGYwgc8GCCsGAQUFBwICMIHCMCcWIFN0YXJ0IENvbW1lcmNpYWwgKFN0
-YXJ0Q29tKSBMdGQuMAMCAQEagZZMaW1pdGVkIExpYWJpbGl0eSwgcmVhZCB0aGUg
-c2VjdGlvbiAqTGVnYWwgTGltaXRhdGlvbnMqIG9mIHRoZSBTdGFydENvbSBDZXJ0
-aWZpY2F0aW9uIEF1dGhvcml0eSBQb2xpY3kgYXZhaWxhYmxlIGF0IGh0dHA6Ly93
-d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwEQYJYIZIAYb4QgEBBAQDAgAHMDgG
-CWCGSAGG+EIBDQQrFilTdGFydENvbSBGcmVlIFNTTCBDZXJ0aWZpY2F0aW9uIEF1
-dGhvcml0eTANBgkqhkiG9w0BAQsFAAOCAgEAjo/n3JR5fPGFf59Jb2vKXfuM/gTF
-wWLRfUKKvFO3lANmMD+x5wqnUCBVJX92ehQN6wQOQOY+2IirByeDqXWmN3PH/UvS
-Ta0XQMhGvjt/UfzDtgUx3M2FIk5xt/JxXrAaxrqTi3iSSoX4eA+D/i+tLPfkpLst
-0OcNOrg+zvZ49q5HJMqjNTbOx8aHmNrs++myziebiMMEofYLWWivydsQD032ZGNc
-pRJvkrKTlMeIFw6Ttn5ii5B/q06f/ON1FE8qMt9bDeD1e5MNq6HPh+GlBEXoPBKl
-CcWw0bdT82AUuoVpaiF8H3VhFyAXe2w7QSlc4axa0c2Mm+tgHRns9+Ww2vl5GKVF
-P0lDV9LdJNUso/2RjSe15esUBppMeyG7Oq0wBhjA2MFrLH9ZXF2RsXAiV+uKa0hK
-1Q8p7MZAwC+ITGgBF3f0JBlPvfrhsiAhS90a2Cl9qrjeVOwhVYBsHvUwyKMQ5bLm
-KhQxw4UtjJixhlpPiVktucf3HMiKf8CdBUrmQk9io20ppB+Fq9vlgcitKj1MXVuE
-JnHEhV5xJMqlG2zYYdMa4FTbzrqpMrUi9nNBCV24F10OD5mQ1kfabwo6YigUZ4LZ
-8dCAWZvLMdibD4x3TrVoivJs9iQOLWxwxXPR3hTQcY+203sC9uO41Alua551hDnm
-fyWl8kgAwKQB2j8=
------END CERTIFICATE-----
-
-# Issuer: CN=StartCom Certification Authority G2 O=StartCom Ltd.
-# Subject: CN=StartCom Certification Authority G2 O=StartCom Ltd.
-# Label: "StartCom Certification Authority G2"
-# Serial: 59
-# MD5 Fingerprint: 78:4b:fb:9e:64:82:0a:d3:b8:4c:62:f3:64:f2:90:64
-# SHA1 Fingerprint: 31:f1:fd:68:22:63:20:ee:c6:3b:3f:9d:ea:4a:3e:53:7c:7c:39:17
-# SHA256 Fingerprint: c7:ba:65:67:de:93:a7:98:ae:1f:aa:79:1e:71:2d:37:8f:ae:1f:93:c4:39:7f:ea:44:1b:b7:cb:e6:fd:59:95
------BEGIN CERTIFICATE-----
-MIIFYzCCA0ugAwIBAgIBOzANBgkqhkiG9w0BAQsFADBTMQswCQYDVQQGEwJJTDEW
-MBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoGA1UEAxMjU3RhcnRDb20gQ2VydGlm
-aWNhdGlvbiBBdXRob3JpdHkgRzIwHhcNMTAwMTAxMDEwMDAxWhcNMzkxMjMxMjM1
-OTAxWjBTMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjEsMCoG
-A1UEAxMjU3RhcnRDb20gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgRzIwggIiMA0G
-CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2iTZbB7cgNr2Cu+EWIAOVeq8Oo1XJ
-JZlKxdBWQYeQTSFgpBSHO839sj60ZwNq7eEPS8CRhXBF4EKe3ikj1AENoBB5uNsD
-vfOpL9HG4A/LnooUCri99lZi8cVytjIl2bLzvWXFDSxu1ZJvGIsAQRSCb0AgJnoo
-D/Uefyf3lLE3PbfHkffiAez9lInhzG7TNtYKGXmu1zSCZf98Qru23QumNK9LYP5/
-Q0kGi4xDuFby2X8hQxfqp0iVAXV16iulQ5XqFYSdCI0mblWbq9zSOdIxHWDirMxW
-RST1HFSr7obdljKF+ExP6JV2tgXdNiNnvP8V4so75qbsO+wmETRIjfaAKxojAuuK
-HDp2KntWFhxyKrOq42ClAJ8Em+JvHhRYW6Vsi1g8w7pOOlz34ZYrPu8HvKTlXcxN
-nw3h3Kq74W4a7I/htkxNeXJdFzULHdfBR9qWJODQcqhaX2YtENwvKhOuJv4KHBnM
-0D4LnMgJLvlblnpHnOl68wVQdJVznjAJ85eCXuaPOQgeWeU1FEIT/wCc976qUM/i
-UUjXuG+v+E5+M5iSFGI6dWPPe/regjupuznixL0sAA7IF6wT700ljtizkC+p2il9
-Ha90OrInwMEePnWjFqmveiJdnxMaz6eg6+OGCtP95paV1yPIN93EfKo2rJgaErHg
-TuixO/XWb/Ew1wIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQE
-AwIBBjAdBgNVHQ4EFgQUS8W0QGutHLOlHGVuRjaJhwUMDrYwDQYJKoZIhvcNAQEL
-BQADggIBAHNXPyzVlTJ+N9uWkusZXn5T50HsEbZH77Xe7XRcxfGOSeD8bpkTzZ+K
-2s06Ctg6Wgk/XzTQLwPSZh0avZyQN8gMjgdalEVGKua+etqhqaRpEpKwfTbURIfX
-UfEpY9Z1zRbkJ4kd+MIySP3bmdCPX1R0zKxnNBFi2QwKN4fRoxdIjtIXHfbX/dtl
-6/2o1PXWT6RbdejF0mCy2wl+JYt7ulKSnj7oxXehPOBKc2thz4bcQ///If4jXSRK
-9dNtD2IEBVeC2m6kMyV5Sy5UGYvMLD0w6dEG/+gyRr61M3Z3qAFdlsHB1b6uJcDJ
-HgoJIIihDsnzb02CVAAgp9KP5DlUFy6NHrgbuxu9mk47EDTcnIhT76IxW1hPkWLI
-wpqazRVdOKnWvvgTtZ8SafJQYqz7Fzf07rh1Z2AQ+4NQ+US1dZxAF7L+/XldblhY
-XzD8AK6vM8EOTmy6p6ahfzLbOOCxchcKK5HsamMm7YnUeMx0HgX4a/6ManY5Ka5l
-IxKVCCIcl85bBu4M4ru8H0ST9tg4RQUh7eStqxK2A6RCLi3ECToDZ2mEmuFZkIoo
-hdVddLHRDiBYmxOlsGOm7XtH/UVVMKTumtTm4ofvmMkyghEpIrwACjFeLQ/Ajulr
-so8uBtjRkcfGEvRM/TAXw8HaOFvjqermobp573PYtlNXLfbQ4ddI
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
-# Subject: CN=Buypass Class 2 Root CA O=Buypass AS-983163327
-# Label: "Buypass Class 2 Root CA"
-# Serial: 2
-# MD5 Fingerprint: 46:a7:d2:fe:45:fb:64:5a:a8:59:90:9b:78:44:9b:29
-# SHA1 Fingerprint: 49:0a:75:74:de:87:0a:47:fe:58:ee:f6:c7:6b:eb:c6:0b:12:40:99
-# SHA256 Fingerprint: 9a:11:40:25:19:7c:5b:b9:5d:94:e6:3d:55:cd:43:79:08:47:b6:46:b2:3c:df:11:ad:a4:a0:0e:ff:15:fb:48
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
-Q2xhc3MgMiBSb290IENBMB4XDTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1ow
-TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
-HgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
-BQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1g1Lr
-6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPV
-L4O2fuPn9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC91
-1K2GScuVr1QGbNgGE41b/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHx
-MlAQTn/0hpPshNOOvEu/XAFOBz3cFIqUCqTqc/sLUegTBxj6DvEr0VQVfTzh97QZ
-QmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeffawrbD02TTqigzXsu8lkB
-arcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgIzRFo1clr
-Us3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLi
-FRhnBkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRS
-P/TizPJhk9H9Z2vXUq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN
-9SG9dKpN6nIDSdvHXx1iY8f93ZHsM+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxP
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFMmAd+BikoL1Rpzz
-uvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAU18h
-9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s
-A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3t
-OluwlN5E40EIosHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo
-+fsicdl9sz1Gv7SEr5AcD48Saq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7
-KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYdDnkM/crqJIByw5c/8nerQyIKx+u2
-DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWDLfJ6v9r9jv6ly0Us
-H8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0oyLQ
-I+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK7
-5t98biGCwWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h
-3PFaTWwyI0PurKju7koSCTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPz
-Y11aWOIv4x3kqdbQCtCev9eBCfHJxyYNrJgWVqA=
------END CERTIFICATE-----
-
-# Issuer: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
-# Subject: CN=Buypass Class 3 Root CA O=Buypass AS-983163327
-# Label: "Buypass Class 3 Root CA"
-# Serial: 2
-# MD5 Fingerprint: 3d:3b:18:9e:2c:64:5a:e8:d5:88:ce:0e:f9:37:c2:ec
-# SHA1 Fingerprint: da:fa:f7:fa:66:84:ec:06:8f:14:50:bd:c7:c2:81:a5:bc:a9:64:57
-# SHA256 Fingerprint: ed:f7:eb:bc:a2:7a:2a:38:4d:38:7b:7d:40:10:c6:66:e2:ed:b4:84:3e:4c:29:b4:ae:1d:5b:93:32:e6:b2:4d
------BEGIN CERTIFICATE-----
-MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEd
-MBsGA1UECgwUQnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3Mg
-Q2xhc3MgMyBSb290IENBMB4XDTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFow
-TjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1eXBhc3MgQVMtOTgzMTYzMzI3MSAw
-HgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEB
-BQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRHsJ8Y
-ZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3E
-N3coTRiR5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9
-tznDDgFHmV0ST9tD+leh7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX
-0DJq1l1sDPGzbjniazEuOQAnFN44wOwZZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c
-/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH2xc519woe2v1n/MuwU8X
-KhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV/afmiSTY
-zIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvS
-O1UQRwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D
-34xFMFbG02SrZvPAXpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgP
-K9Dx2hzLabjKSWJtyNBjYt1gD1iqj6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3
-AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFEe4zf/lb+74suwv
-Tg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAACAj
-QTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV
-cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXS
-IGrs/CIBKM+GuIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2
-HJLw5QY33KbmkJs4j1xrG0aGQ0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsa
-O5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8ZORK15FTAaggiG6cX0S5y2CBNOxv
-033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2KSb12tjE8nVhz36u
-dmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz6MkE
-kbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg41
-3OEMXbugUZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvD
-u79leNKGef9JOxqDDPDeeOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq
-4/g7u9xN12TyUb7mqqta6THuBrxzvxNiCp/HuZc=
------END CERTIFICATE-----
-
-# Issuer: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
-# Subject: CN=T-TeleSec GlobalRoot Class 3 O=T-Systems Enterprise Services GmbH OU=T-Systems Trust Center
-# Label: "T-TeleSec GlobalRoot Class 3"
-# Serial: 1
-# MD5 Fingerprint: ca:fb:40:a8:4e:39:92:8a:1d:fe:8e:2f:c4:27:ea:ef
-# SHA1 Fingerprint: 55:a6:72:3e:cb:f2:ec:cd:c3:23:74:70:19:9d:2a:be:11:e3:81:d1
-# SHA256 Fingerprint: fd:73:da:d3:1c:64:4f:f1:b4:3b:ef:0c:cd:da:96:71:0b:9c:d9:87:5e:ca:7e:31:70:7a:f3:e9:6d:52:2b:bd
------BEGIN CERTIFICATE-----
-MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUx
-KzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAd
-BgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNl
-YyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgxMDAxMTAyOTU2WhcNMzMxMDAxMjM1
-OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lzdGVtcyBFbnRlcnBy
-aXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBDZW50
-ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0G
-CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN
-8ELg63iIVl6bmlQdTQyK9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/
-RLyTPWGrTs0NvvAgJ1gORH8EGoel15YUNpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4
-hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZFiP0Zf3WHHx+xGwpzJFu5
-ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W0eDrXltM
-EnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGj
-QjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1
-A/d2O2GCahKqGFPrAyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOy
-WL6ukK2YJ5f+AbGwUgC4TeQbIXQbfsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ
-1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzTucpH9sry9uetuUg/vBa3wW30
-6gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7hP0HHRwA11fXT
-91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml
-e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4p
-TpPDpFQUWw==
------END CERTIFICATE-----
-
-# Issuer: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
-# Subject: CN=EE Certification Centre Root CA O=AS Sertifitseerimiskeskus
-# Label: "EE Certification Centre Root CA"
-# Serial: 112324828676200291871926431888494945866
-# MD5 Fingerprint: 43:5e:88:d4:7d:1a:4a:7e:fd:84:2e:52:eb:01:d4:6f
-# SHA1 Fingerprint: c9:a8:b9:e7:55:80:5e:58:e3:53:77:a7:25:eb:af:c3:7b:27:cc:d7
-# SHA256 Fingerprint: 3e:84:ba:43:42:90:85:16:e7:75:73:c0:99:2f:09:79:ca:08:4e:46:85:68:1f:f1:95:cc:ba:8a:22:9b:8a:76
------BEGIN CERTIFICATE-----
-MIIEAzCCAuugAwIBAgIQVID5oHPtPwBMyonY43HmSjANBgkqhkiG9w0BAQUFADB1
-MQswCQYDVQQGEwJFRTEiMCAGA1UECgwZQVMgU2VydGlmaXRzZWVyaW1pc2tlc2t1
-czEoMCYGA1UEAwwfRUUgQ2VydGlmaWNhdGlvbiBDZW50cmUgUm9vdCBDQTEYMBYG
-CSqGSIb3DQEJARYJcGtpQHNrLmVlMCIYDzIwMTAxMDMwMTAxMDMwWhgPMjAzMDEy
-MTcyMzU5NTlaMHUxCzAJBgNVBAYTAkVFMSIwIAYDVQQKDBlBUyBTZXJ0aWZpdHNl
-ZXJpbWlza2Vza3VzMSgwJgYDVQQDDB9FRSBDZXJ0aWZpY2F0aW9uIENlbnRyZSBS
-b290IENBMRgwFgYJKoZIhvcNAQkBFglwa2lAc2suZWUwggEiMA0GCSqGSIb3DQEB
-AQUAA4IBDwAwggEKAoIBAQDIIMDs4MVLqwd4lfNE7vsLDP90jmG7sWLqI9iroWUy
-euuOF0+W2Ap7kaJjbMeMTC55v6kF/GlclY1i+blw7cNRfdCT5mzrMEvhvH2/UpvO
-bntl8jixwKIy72KyaOBhU8E2lf/slLo2rpwcpzIP5Xy0xm90/XsY6KxX7QYgSzIw
-WFv9zajmofxwvI6Sc9uXp3whrj3B9UiHbCe9nyV0gVWw93X2PaRka9ZP585ArQ/d
-MtO8ihJTmMmJ+xAdTX7Nfh9WDSFwhfYggx/2uh8Ej+p3iDXE/+pOoYtNP2MbRMNE
-1CV2yreN1x5KZmTNXMWcg+HCCIia7E6j8T4cLNlsHaFLAgMBAAGjgYowgYcwDwYD
-VR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBLyWj7qVhy/
-zQas8fElyalL1BSZMEUGA1UdJQQ+MDwGCCsGAQUFBwMCBggrBgEFBQcDAQYIKwYB
-BQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCAYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF
-BQADggEBAHv25MANqhlHt01Xo/6tu7Fq1Q+e2+RjxY6hUFaTlrg4wCQiZrxTFGGV
-v9DHKpY5P30osxBAIWrEr7BSdxjhlthWXePdNl4dp1BUoMUq5KqMlIpPnTX/dqQG
-E5Gion0ARD9V04I8GtVbvFZMIi5GQ4okQC3zErg7cBqklrkar4dBGmoYDQZPxz5u
-uSlNDUmJEYcyW+ZLBMjkXOZ0c5RdFpgTlf7727FE5TpwrDdr5rMzcijJs1eg9gIW
-iAYLtqZLICjU3j2LrTcFU3T+bsy8QxdxXvnFzBqpYe73dgzzcvRyrc9yAjYHR8/v
-GVCJYMzpJJUPwssd8m92kMfMdcGWxZ0=
------END CERTIFICATE-----
-
-# Issuer: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
-# Subject: CN=TÜRKTRUST Elektronik Sertifika Hizmet Sağlayıcısı O=TÜRKTRUST Bilgi İletişim ve Bilişim Güvenliği Hizmetleri A.Ş. (c) Aralık 2007
-# Label: "TURKTRUST Certificate Services Provider Root 2007"
-# Serial: 1
-# MD5 Fingerprint: 2b:70:20:56:86:82:a0:18:c8:07:53:12:28:70:21:72
-# SHA1 Fingerprint: f1:7f:6f:b6:31:dc:99:e3:a3:c8:7f:fe:1c:f1:81:10:88:d9:60:33
-# SHA256 Fingerprint: 97:8c:d9:66:f2:fa:a0:7b:a7:aa:95:00:d9:c0:2e:9d:77:f2:cd:ad:a6:ad:6b:a7:4a:f4:b9:1c:66:59:3c:50
------BEGIN CERTIFICATE-----
-MIIEPTCCAyWgAwIBAgIBATANBgkqhkiG9w0BAQUFADCBvzE/MD0GA1UEAww2VMOc
-UktUUlVTVCBFbGVrdHJvbmlrIFNlcnRpZmlrYSBIaXptZXQgU2HEn2xhecSxY8Sx
-c8SxMQswCQYDVQQGEwJUUjEPMA0GA1UEBwwGQW5rYXJhMV4wXAYDVQQKDFVUw5xS
-S1RSVVNUIEJpbGdpIMSwbGV0acWfaW0gdmUgQmlsacWfaW0gR8O8dmVubGnEn2kg
-SGl6bWV0bGVyaSBBLsWeLiAoYykgQXJhbMSxayAyMDA3MB4XDTA3MTIyNTE4Mzcx
-OVoXDTE3MTIyMjE4MzcxOVowgb8xPzA9BgNVBAMMNlTDnFJLVFJVU1QgRWxla3Ry
-b25payBTZXJ0aWZpa2EgSGl6bWV0IFNhxJ9sYXnEsWPEsXPEsTELMAkGA1UEBhMC
-VFIxDzANBgNVBAcMBkFua2FyYTFeMFwGA1UECgxVVMOcUktUUlVTVCBCaWxnaSDE
-sGxldGnFn2ltIHZlIEJpbGnFn2ltIEfDvHZlbmxpxJ9pIEhpem1ldGxlcmkgQS7F
-ni4gKGMpIEFyYWzEsWsgMjAwNzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
-ggEBAKu3PgqMyKVYFeaK7yc9SrToJdPNM8Ig3BnuiD9NYvDdE3ePYakqtdTyuTFY
-KTsvP2qcb3N2Je40IIDu6rfwxArNK4aUyeNgsURSsloptJGXg9i3phQvKUmi8wUG
-+7RP2qFsmmaf8EMJyupyj+sA1zU511YXRxcw9L6/P8JorzZAwan0qafoEGsIiveG
-HtyaKhUG9qPw9ODHFNRRf8+0222vR5YXm3dx2KdxnSQM9pQ/hTEST7ruToK4uT6P
-IzdezKKqdfcYbwnTrqdUKDT74eA7YH2gvnmJhsifLfkKS8RQouf9eRbHegsYz85M
-733WB2+Y8a+xwXrXgTW4qhe04MsCAwEAAaNCMEAwHQYDVR0OBBYEFCnFkKslrxHk
-Yb+j/4hhkeYO/pyBMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0G
-CSqGSIb3DQEBBQUAA4IBAQAQDdr4Ouwo0RSVgrESLFF6QSU2TJ/sPx+EnWVUXKgW
-AkD6bho3hO9ynYYKVZ1WKKxmLNA6VpM0ByWtCLCPyA8JWcqdmBzlVPi5RX9ql2+I
-aE1KBiY3iAIOtsbWcpnOa3faYjGkVh+uX4132l32iPwa2Z61gfAyuOOI0JzzaqC5
-mxRZNTZPz/OOXl0XrRWV2N2y1RVuAE6zS89mlOTgzbUF2mNXi+WzqtvALhyQRNsa
-XRik7r4EW5nVcV9VZWRi1aKbBFmGyGJ353yCRWo9F7/snXUMrqNvWtMvmDb08PUZ
-qxFdyKbjKlhqQgnDvZImZjINXQhVdP+MmNAKpoRq0Tl9
------END CERTIFICATE-----
-
-# Issuer: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
-# Subject: CN=D-TRUST Root Class 3 CA 2 2009 O=D-Trust GmbH
-# Label: "D-TRUST Root Class 3 CA 2 2009"
-# Serial: 623603
-# MD5 Fingerprint: cd:e0:25:69:8d:47:ac:9c:89:35:90:f7:fd:51:3d:2f
-# SHA1 Fingerprint: 58:e8:ab:b0:36:15:33:fb:80:f7:9b:1b:6d:29:d3:ff:8d:5f:00:f0
-# SHA256 Fingerprint: 49:e7:a4:42:ac:f0:ea:62:87:05:00:54:b5:25:64:b6:50:e4:f4:9e:42:e3:48:d6:aa:38:e0:39:e9:57:b1:c1
------BEGIN CERTIFICATE-----
-MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgMjAwOTAeFw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NTha
-ME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxJzAlBgNVBAMM
-HkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIwDQYJKoZIhvcNAQEB
-BQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOADER03
-UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42
-tSHKXzlABF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9R
-ySPocq60vFYJfxLLHLGvKZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsM
-lFqVlNpQmvH/pStmMaTJOKDfHR+4CS7zp+hnUquVH+BGPtikw8paxTGA6Eian5Rp
-/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUCAwEAAaOCARowggEWMA8G
-A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ4PGEMA4G
-A1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVj
-dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUy
-MENBJTIwMiUyMDIwMDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRl
-cmV2b2NhdGlvbmxpc3QwQ6BBoD+GPWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3Js
-L2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAwOS5jcmwwDQYJKoZIhvcNAQEL
-BQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm2H6NMLVwMeni
-acfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0
-o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4K
-zCUqNQT4YJEVdT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8
-PIWmawomDeCTmGCufsYkl4phX5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3Y
-Johw1+qRzT65ysCQblrGXnRl11z+o+I=
------END CERTIFICATE-----
-
-# Issuer: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
-# Subject: CN=D-TRUST Root Class 3 CA 2 EV 2009 O=D-Trust GmbH
-# Label: "D-TRUST Root Class 3 CA 2 EV 2009"
-# Serial: 623604
-# MD5 Fingerprint: aa:c6:43:2c:5e:2d:cd:c4:34:c0:50:4f:11:02:4f:b6
-# SHA1 Fingerprint: 96:c9:1b:0b:95:b4:10:98:42:fa:d0:d8:22:79:fe:60:fa:b9:16:83
-# SHA256 Fingerprint: ee:c5:49:6b:98:8c:e9:86:25:b9:34:09:2e:ec:29:08:be:d0:b0:f3:16:c2:d4:73:0c:84:ea:f1:f3:d3:48:81
------BEGIN CERTIFICATE-----
-MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRF
-MRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBD
-bGFzcyAzIENBIDIgRVYgMjAwOTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUw
-NDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxELVRydXN0IEdtYkgxKjAoBgNV
-BAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAwOTCCASIwDQYJKoZI
-hvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfSegpn
-ljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM0
-3TP1YtHhzRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6Z
-qQTMFexgaDbtCHu39b+T7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lR
-p75mpoo6Kr3HGrHhFPC+Oh25z1uxav60sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8
-HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure3511H3a6UCAwEAAaOCASQw
-ggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyvcop9Ntea
-HNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFw
-Oi8vZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xh
-c3MlMjAzJTIwQ0ElMjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1E
-RT9jZXJ0aWZpY2F0ZXJldm9jYXRpb25saXN0MEagRKBChkBodHRwOi8vd3d3LmQt
-dHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xhc3NfM19jYV8yX2V2XzIwMDku
-Y3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+PPoeUSbrh/Yp
-3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05
-nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNF
-CSuGdXzfX2lXANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7na
-xpeG0ILD5EJt/rDiZE4OJudANCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqX
-KVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVvw9y4AyHqnxbxLFS1
------END CERTIFICATE-----
-
-# Issuer: CN=Autoridad de Certificacion Raiz del Estado Venezolano O=Sistema Nacional de Certificacion Electronica OU=Superintendencia de Servicios de Certificacion Electronica
-# Subject: CN=PSCProcert O=Sistema Nacional de Certificacion Electronica OU=Proveedor de Certificados PROCERT
-# Label: "PSCProcert"
-# Serial: 11
-# MD5 Fingerprint: e6:24:e9:12:01:ae:0c:de:8e:85:c4:ce:a3:12:dd:ec
-# SHA1 Fingerprint: 70:c1:8d:74:b4:28:81:0a:e4:fd:a5:75:d7:01:9f:99:b0:3d:50:74
-# SHA256 Fingerprint: 3c:fc:3c:14:d1:f6:84:ff:17:e3:8c:43:ca:44:0c:00:b9:67:ec:93:3e:8b:fe:06:4c:a1:d7:2c:90:f2:ad:b0
------BEGIN CERTIFICATE-----
-MIIJhjCCB26gAwIBAgIBCzANBgkqhkiG9w0BAQsFADCCAR4xPjA8BgNVBAMTNUF1
-dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIFJhaXogZGVsIEVzdGFkbyBWZW5lem9s
-YW5vMQswCQYDVQQGEwJWRTEQMA4GA1UEBxMHQ2FyYWNhczEZMBcGA1UECBMQRGlz
-dHJpdG8gQ2FwaXRhbDE2MDQGA1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0
-aWZpY2FjaW9uIEVsZWN0cm9uaWNhMUMwQQYDVQQLEzpTdXBlcmludGVuZGVuY2lh
-IGRlIFNlcnZpY2lvcyBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9uaWNhMSUwIwYJ
-KoZIhvcNAQkBFhZhY3JhaXpAc3VzY2VydGUuZ29iLnZlMB4XDTEwMTIyODE2NTEw
-MFoXDTIwMTIyNTIzNTk1OVowgdExJjAkBgkqhkiG9w0BCQEWF2NvbnRhY3RvQHBy
-b2NlcnQubmV0LnZlMQ8wDQYDVQQHEwZDaGFjYW8xEDAOBgNVBAgTB01pcmFuZGEx
-KjAoBgNVBAsTIVByb3ZlZWRvciBkZSBDZXJ0aWZpY2Fkb3MgUFJPQ0VSVDE2MDQG
-A1UEChMtU2lzdGVtYSBOYWNpb25hbCBkZSBDZXJ0aWZpY2FjaW9uIEVsZWN0cm9u
-aWNhMQswCQYDVQQGEwJWRTETMBEGA1UEAxMKUFNDUHJvY2VydDCCAiIwDQYJKoZI
-hvcNAQEBBQADggIPADCCAgoCggIBANW39KOUM6FGqVVhSQ2oh3NekS1wwQYalNo9
-7BVCwfWMrmoX8Yqt/ICV6oNEolt6Vc5Pp6XVurgfoCfAUFM+jbnADrgV3NZs+J74
-BCXfgI8Qhd19L3uA3VcAZCP4bsm+lU/hdezgfl6VzbHvvnpC2Mks0+saGiKLt38G
-ieU89RLAu9MLmV+QfI4tL3czkkohRqipCKzx9hEC2ZUWno0vluYC3XXCFCpa1sl9
-JcLB/KpnheLsvtF8PPqv1W7/U0HU9TI4seJfxPmOEO8GqQKJ/+MMbpfg353bIdD0
-PghpbNjU5Db4g7ayNo+c7zo3Fn2/omnXO1ty0K+qP1xmk6wKImG20qCZyFSTXai2
-0b1dCl53lKItwIKOvMoDKjSuc/HUtQy9vmebVOvh+qBa7Dh+PsHMosdEMXXqP+UH
-0quhJZb25uSgXTcYOWEAM11G1ADEtMo88aKjPvM6/2kwLkDd9p+cJsmWN63nOaK/
-6mnbVSKVUyqUtd+tFjiBdWbjxywbk5yqjKPK2Ww8F22c3HxT4CAnQzb5EuE8XL1m
-v6JpIzi4mWCZDlZTOpx+FIywBm/xhnaQr/2v/pDGj59/i5IjnOcVdo/Vi5QTcmn7
-K2FjiO/mpF7moxdqWEfLcU8UC17IAggmosvpr2uKGcfLFFb14dq12fy/czja+eev
-bqQ34gcnAgMBAAGjggMXMIIDEzASBgNVHRMBAf8ECDAGAQH/AgEBMDcGA1UdEgQw
-MC6CD3N1c2NlcnRlLmdvYi52ZaAbBgVghl4CAqASDBBSSUYtRy0yMDAwNDAzNi0w
-MB0GA1UdDgQWBBRBDxk4qpl/Qguk1yeYVKIXTC1RVDCCAVAGA1UdIwSCAUcwggFD
-gBStuyIdxuDSAaj9dlBSk+2YwU2u06GCASakggEiMIIBHjE+MDwGA1UEAxM1QXV0
-b3JpZGFkIGRlIENlcnRpZmljYWNpb24gUmFpeiBkZWwgRXN0YWRvIFZlbmV6b2xh
-bm8xCzAJBgNVBAYTAlZFMRAwDgYDVQQHEwdDYXJhY2FzMRkwFwYDVQQIExBEaXN0
-cml0byBDYXBpdGFsMTYwNAYDVQQKEy1TaXN0ZW1hIE5hY2lvbmFsIGRlIENlcnRp
-ZmljYWNpb24gRWxlY3Ryb25pY2ExQzBBBgNVBAsTOlN1cGVyaW50ZW5kZW5jaWEg
-ZGUgU2VydmljaW9zIGRlIENlcnRpZmljYWNpb24gRWxlY3Ryb25pY2ExJTAjBgkq
-hkiG9w0BCQEWFmFjcmFpekBzdXNjZXJ0ZS5nb2IudmWCAQowDgYDVR0PAQH/BAQD
-AgEGME0GA1UdEQRGMESCDnByb2NlcnQubmV0LnZloBUGBWCGXgIBoAwMClBTQy0w
-MDAwMDKgGwYFYIZeAgKgEgwQUklGLUotMzE2MzUzNzMtNzB2BgNVHR8EbzBtMEag
-RKBChkBodHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9sY3IvQ0VSVElGSUNBRE8t
-UkFJWi1TSEEzODRDUkxERVIuY3JsMCOgIaAfhh1sZGFwOi8vYWNyYWl6LnN1c2Nl
-cnRlLmdvYi52ZTA3BggrBgEFBQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly9v
-Y3NwLnN1c2NlcnRlLmdvYi52ZTBBBgNVHSAEOjA4MDYGBmCGXgMBAjAsMCoGCCsG
-AQUFBwIBFh5odHRwOi8vd3d3LnN1c2NlcnRlLmdvYi52ZS9kcGMwDQYJKoZIhvcN
-AQELBQADggIBACtZ6yKZu4SqT96QxtGGcSOeSwORR3C7wJJg7ODU523G0+1ng3dS
-1fLld6c2suNUvtm7CpsR72H0xpkzmfWvADmNg7+mvTV+LFwxNG9s2/NkAZiqlCxB
-3RWGymspThbASfzXg0gTB1GEMVKIu4YXx2sviiCtxQuPcD4quxtxj7mkoP3Yldmv
-Wb8lK5jpY5MvYB7Eqvh39YtsL+1+LrVPQA3uvFd359m21D+VJzog1eWuq2w1n8Gh
-HVnchIHuTQfiSLaeS5UtQbHh6N5+LwUeaO6/u5BlOsju6rEYNxxik6SgMexxbJHm
-pHmJWhSnFFAFTKQAVzAswbVhltw+HoSvOULP5dAssSS830DD7X9jSr3hTxJkhpXz
-sOfIt+FTvZLm8wyWuevo5pLtp4EJFAv8lXrPj9Y0TzYS3F7RNHXGRoAvlQSMx4bE
-qCaJqD8Zm4G7UaRKhqsLEQ+xrmNTbSjq3TNWOByyrYDT13K9mmyZY+gAu0F2Bbdb
-mRiKw7gSXFbPVgx96OLP7bx0R/vu0xdOIk9W/1DzLuY5poLWccret9W6aAjtmcz9
-opLLabid+Qqkpj5PkygqYWwHJgD/ll9ohri4zspV4KuxPX+Y1zMOWj3YeMLEYC/H
-YvBhkdI4sPaeVdtAgAUSM84dkpvRabP/v/GSCmE1P93+hvS84Bpxs2Km
------END CERTIFICATE-----
-
-# Issuer: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
-# Subject: CN=China Internet Network Information Center EV Certificates Root O=China Internet Network Information Center
-# Label: "China Internet Network Information Center EV Certificates Root"
-# Serial: 1218379777
-# MD5 Fingerprint: 55:5d:63:00:97:bd:6a:97:f5:67:ab:4b:fb:6e:63:15
-# SHA1 Fingerprint: 4f:99:aa:93:fb:2b:d1:37:26:a1:99:4a:ce:7f:f0:05:f2:93:5d:1e
-# SHA256 Fingerprint: 1c:01:c6:f4:db:b2:fe:fc:22:55:8b:2b:ca:32:56:3f:49:84:4a:cf:c3:2b:7b:e4:b0:ff:59:9f:9e:8c:7a:f7
------BEGIN CERTIFICATE-----
-MIID9zCCAt+gAwIBAgIESJ8AATANBgkqhkiG9w0BAQUFADCBijELMAkGA1UEBhMC
-Q04xMjAwBgNVBAoMKUNoaW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24g
-Q2VudGVyMUcwRQYDVQQDDD5DaGluYSBJbnRlcm5ldCBOZXR3b3JrIEluZm9ybWF0
-aW9uIENlbnRlciBFViBDZXJ0aWZpY2F0ZXMgUm9vdDAeFw0xMDA4MzEwNzExMjVa
-Fw0zMDA4MzEwNzExMjVaMIGKMQswCQYDVQQGEwJDTjEyMDAGA1UECgwpQ2hpbmEg
-SW50ZXJuZXQgTmV0d29yayBJbmZvcm1hdGlvbiBDZW50ZXIxRzBFBgNVBAMMPkNo
-aW5hIEludGVybmV0IE5ldHdvcmsgSW5mb3JtYXRpb24gQ2VudGVyIEVWIENlcnRp
-ZmljYXRlcyBSb290MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm35z
-7r07eKpkQ0H1UN+U8i6yjUqORlTSIRLIOTJCBumD1Z9S7eVnAztUwYyZmczpwA//
-DdmEEbK40ctb3B75aDFk4Zv6dOtouSCV98YPjUesWgbdYavi7NifFy2cyjw1l1Vx
-zUOFsUcW9SxTgHbP0wBkvUCZ3czY28Sf1hNfQYOL+Q2HklY0bBoQCxfVWhyXWIQ8
-hBouXJE0bhlffxdpxWXvayHG1VA6v2G5BY3vbzQ6sm8UY78WO5upKv23KzhmBsUs
-4qpnHkWnjQRmQvaPK++IIGmPMowUc9orhpFjIpryp9vOiYurXccUwVswah+xt54u
-gQEC7c+WXmPbqOY4twIDAQABo2MwYTAfBgNVHSMEGDAWgBR8cks5x8DbYqVPm6oY
-NJKiyoOCWTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4E
-FgQUfHJLOcfA22KlT5uqGDSSosqDglkwDQYJKoZIhvcNAQEFBQADggEBACrDx0M3
-j92tpLIM7twUbY8opJhJywyA6vPtI2Z1fcXTIWd50XPFtQO3WKwMVC/GVhMPMdoG
-52U7HW8228gd+f2ABsqjPWYWqJ1MFn3AlUa1UeTiH9fqBk1jjZaM7+czV0I664zB
-echNdn3e9rG3geCg+aF4RhcaVpjwTj2rHO3sOdwHSPdj/gauwqRcalsyiMXHM4Ws
-ZkJHwlgkmeHlPuV1LI5D1l08eB6olYIpUNHRFrrvwb562bTYzB5MRuF3sTGrvSrI
-zo9uoV1/A3U05K2JRVRevq4opbs/eHnrc7MKDf2+yfdWrPa37S+bISnHOLaVxATy
-wy39FCqQmbkHzJ8=
------END CERTIFICATE-----
-
-# Issuer: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
-# Subject: CN=Swisscom Root CA 2 O=Swisscom OU=Digital Certificate Services
-# Label: "Swisscom Root CA 2"
-# Serial: 40698052477090394928831521023204026294
-# MD5 Fingerprint: 5b:04:69:ec:a5:83:94:63:18:a7:86:d0:e4:f2:6e:19
-# SHA1 Fingerprint: 77:47:4f:c6:30:e4:0f:4c:47:64:3f:84:ba:b8:c6:95:4a:8a:41:ec
-# SHA256 Fingerprint: f0:9b:12:2c:71:14:f4:a0:9b:d4:ea:4f:4a:99:d5:58:b4:6e:4c:25:cd:81:14:0d:29:c0:56:13:91:4c:38:41
------BEGIN CERTIFICATE-----
-MIIF2TCCA8GgAwIBAgIQHp4o6Ejy5e/DfEoeWhhntjANBgkqhkiG9w0BAQsFADBk
-MQswCQYDVQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0
-YWwgQ2VydGlmaWNhdGUgU2VydmljZXMxGzAZBgNVBAMTElN3aXNzY29tIFJvb3Qg
-Q0EgMjAeFw0xMTA2MjQwODM4MTRaFw0zMTA2MjUwNzM4MTRaMGQxCzAJBgNVBAYT
-AmNoMREwDwYDVQQKEwhTd2lzc2NvbTElMCMGA1UECxMcRGlnaXRhbCBDZXJ0aWZp
-Y2F0ZSBTZXJ2aWNlczEbMBkGA1UEAxMSU3dpc3Njb20gUm9vdCBDQSAyMIICIjAN
-BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlUJOhJ1R5tMJ6HJaI2nbeHCOFvEr
-jw0DzpPMLgAIe6szjPTpQOYXTKueuEcUMncy3SgM3hhLX3af+Dk7/E6J2HzFZ++r
-0rk0X2s682Q2zsKwzxNoysjL67XiPS4h3+os1OD5cJZM/2pYmLcX5BtS5X4HAB1f
-2uY+lQS3aYg5oUFgJWFLlTloYhyxCwWJwDaCFCE/rtuh/bxvHGCGtlOUSbkrRsVP
-ACu/obvLP+DHVxxX6NZp+MEkUp2IVd3Chy50I9AU/SpHWrumnf2U5NGKpV+GY3aF
-y6//SSj8gO1MedK75MDvAe5QQQg1I3ArqRa0jG6F6bYRzzHdUyYb3y1aSgJA/MTA
-tukxGggo5WDDH8SQjhBiYEQN7Aq+VRhxLKX0srwVYv8c474d2h5Xszx+zYIdkeNL
-6yxSNLCK/RJOlrDrcH+eOfdmQrGrrFLadkBXeyq96G4DsguAhYidDMfCd7Camlf0
-uPoTXGiTOmekl9AbmbeGMktg2M7v0Ax/lZ9vh0+Hio5fCHyqW/xavqGRn1V9TrAL
-acywlKinh/LTSlDcX3KwFnUey7QYYpqwpzmqm59m2I2mbJYV4+by+PGDYmy7Velh
-k6M99bFXi08jsJvllGov34zflVEpYKELKeRcVVi3qPyZ7iVNTA6z00yPhOgpD/0Q
-VAKFyPnlw4vP5w8CAwEAAaOBhjCBgzAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0hBBYw
-FDASBgdghXQBUwIBBgdghXQBUwIBMBIGA1UdEwEB/wQIMAYBAf8CAQcwHQYDVR0O
-BBYEFE0mICKJS9PVpAqhb97iEoHF8TwuMB8GA1UdIwQYMBaAFE0mICKJS9PVpAqh
-b97iEoHF8TwuMA0GCSqGSIb3DQEBCwUAA4ICAQAyCrKkG8t9voJXiblqf/P0wS4R
-fbgZPnm3qKhyN2abGu2sEzsOv2LwnN+ee6FTSA5BesogpxcbtnjsQJHzQq0Qw1zv
-/2BZf82Fo4s9SBwlAjxnffUy6S8w5X2lejjQ82YqZh6NM4OKb3xuqFp1mrjX2lhI
-REeoTPpMSQpKwhI3qEAMw8jh0FcNlzKVxzqfl9NX+Ave5XLzo9v/tdhZsnPdTSpx
-srpJ9csc1fV5yJmz/MFMdOO0vSk3FQQoHt5FRnDsr7p4DooqzgB53MBfGWcsa0vv
-aGgLQ+OswWIJ76bdZWGgr4RVSJFSHMYlkSrQwSIjYVmvRRGFHQEkNI/Ps/8XciAT
-woCqISxxOQ7Qj1zB09GOInJGTB2Wrk9xseEFKZZZ9LuedT3PDTcNYtsmjGOpI99n
-Bjx8Oto0QuFmtEYE3saWmA9LSHokMnWRn6z3aOkquVVlzl1h0ydw2Df+n7mvoC5W
-t6NlUe07qxS/TFED6F+KBZvuim6c779o+sjaC+NCydAXFJy3SuCvkychVSa1ZC+N
-8f+mQAWFBVzKBxlcCxMoTFh/wqXvRdpg065lYZ1Tg3TCrvJcwhbtkj6EPnNgiLx2
-9CzP0H1907he0ZESEOnN3col49XtmS++dYFLJPlFRpTJKSFTnCZFqhMX5OfNeOI5
-wSsSnqaeG8XmDtkx2Q==
------END CERTIFICATE-----
-
-# Issuer: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
-# Subject: CN=Swisscom Root EV CA 2 O=Swisscom OU=Digital Certificate Services
-# Label: "Swisscom Root EV CA 2"
-# Serial: 322973295377129385374608406479535262296
-# MD5 Fingerprint: 7b:30:34:9f:dd:0a:4b:6b:35:ca:31:51:28:5d:ae:ec
-# SHA1 Fingerprint: e7:a1:90:29:d3:d5:52:dc:0d:0f:c6:92:d3:ea:88:0d:15:2e:1a:6b
-# SHA256 Fingerprint: d9:5f:ea:3c:a4:ee:dc:e7:4c:d7:6e:75:fc:6d:1f:f6:2c:44:1f:0f:a8:bc:77:f0:34:b1:9e:5d:b2:58:01:5d
------BEGIN CERTIFICATE-----
-MIIF4DCCA8igAwIBAgIRAPL6ZOJ0Y9ON/RAdBB92ylgwDQYJKoZIhvcNAQELBQAw
-ZzELMAkGA1UEBhMCY2gxETAPBgNVBAoTCFN3aXNzY29tMSUwIwYDVQQLExxEaWdp
-dGFsIENlcnRpZmljYXRlIFNlcnZpY2VzMR4wHAYDVQQDExVTd2lzc2NvbSBSb290
-IEVWIENBIDIwHhcNMTEwNjI0MDk0NTA4WhcNMzEwNjI1MDg0NTA4WjBnMQswCQYD
-VQQGEwJjaDERMA8GA1UEChMIU3dpc3Njb20xJTAjBgNVBAsTHERpZ2l0YWwgQ2Vy
-dGlmaWNhdGUgU2VydmljZXMxHjAcBgNVBAMTFVN3aXNzY29tIFJvb3QgRVYgQ0Eg
-MjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMT3HS9X6lds93BdY7Bx
-UglgRCgzo3pOCvrY6myLURYaVa5UJsTMRQdBTxB5f3HSek4/OE6zAMaVylvNwSqD
-1ycfMQ4jFrclyxy0uYAyXhqdk/HoPGAsp15XGVhRXrwsVgu42O+LgrQ8uMIkqBPH
-oCE2G3pXKSinLr9xJZDzRINpUKTk4RtiGZQJo/PDvO/0vezbE53PnUgJUmfANykR
-HvvSEaeFGHR55E+FFOtSN+KxRdjMDUN/rhPSays/p8LiqG12W0OfvrSdsyaGOx9/
-5fLoZigWJdBLlzin5M8J0TbDC77aO0RYjb7xnglrPvMyxyuHxuxenPaHZa0zKcQv
-idm5y8kDnftslFGXEBuGCxobP/YCfnvUxVFkKJ3106yDgYjTdLRZncHrYTNaRdHL
-OdAGalNgHa/2+2m8atwBz735j9m9W8E6X47aD0upm50qKGsaCnw8qyIL5XctcfaC
-NYGu+HuB5ur+rPQam3Rc6I8k9l2dRsQs0h4rIWqDJ2dVSqTjyDKXZpBy2uPUZC5f
-46Fq9mDU5zXNysRojddxyNMkM3OxbPlq4SjbX8Y96L5V5jcb7STZDxmPX2MYWFCB
-UWVv8p9+agTnNCRxunZLWB4ZvRVgRaoMEkABnRDixzgHcgplwLa7JSnaFp6LNYth
-7eVxV4O1PHGf40+/fh6Bn0GXAgMBAAGjgYYwgYMwDgYDVR0PAQH/BAQDAgGGMB0G
-A1UdIQQWMBQwEgYHYIV0AVMCAgYHYIV0AVMCAjASBgNVHRMBAf8ECDAGAQH/AgED
-MB0GA1UdDgQWBBRF2aWBbj2ITY1x0kbBbkUe88SAnTAfBgNVHSMEGDAWgBRF2aWB
-bj2ITY1x0kbBbkUe88SAnTANBgkqhkiG9w0BAQsFAAOCAgEAlDpzBp9SSzBc1P6x
-XCX5145v9Ydkn+0UjrgEjihLj6p7jjm02Vj2e6E1CqGdivdj5eu9OYLU43otb98T
-PLr+flaYC/NUn81ETm484T4VvwYmneTwkLbUwp4wLh/vx3rEUMfqe9pQy3omywC0
-Wqu1kx+AiYQElY2NfwmTv9SoqORjbdlk5LgpWgi/UOGED1V7XwgiG/W9mR4U9s70
-WBCCswo9GcG/W6uqmdjyMb3lOGbcWAXH7WMaLgqXfIeTK7KK4/HsGOV1timH59yL
-Gn602MnTihdsfSlEvoqq9X46Lmgxk7lq2prg2+kupYTNHAq4Sgj5nPFhJpiTt3tm
-7JFe3VE/23MPrQRYCd0EApUKPtN236YQHoA96M2kZNEzx5LH4k5E4wnJTsJdhw4S
-nr8PyQUQ3nqjsTzyP6WqJ3mtMX0f/fwZacXduT98zca0wjAefm6S139hdlqP65VN
-vBFuIXxZN5nQBrz5Bm0yFqXZaajh3DyAHmBR3NdUIR7KYndP+tiPsys6DXhyyWhB
-WkdKwqPrGtcKqzwyVcgKEZzfdNbwQBUdyLmPtTbFr/giuMod89a2GQ+fYWVq6nTI
-fI/DT11lgh/ZDYnadXL77/FHZxOzyNEZiCcmmpl5fx7kLD977vHeTYuWl8PVP3wb
-I+2ksx0WckNLIOFZfsLorSa/ovc=
------END CERTIFICATE-----
-
-# Issuer: CN=CA Disig Root R1 O=Disig a.s.
-# Subject: CN=CA Disig Root R1 O=Disig a.s.
-# Label: "CA Disig Root R1"
-# Serial: 14052245610670616104
-# MD5 Fingerprint: be:ec:11:93:9a:f5:69:21:bc:d7:c1:c0:67:89:cc:2a
-# SHA1 Fingerprint: 8e:1c:74:f8:a6:20:b9:e5:8a:f4:61:fa:ec:2b:47:56:51:1a:52:c6
-# SHA256 Fingerprint: f9:6f:23:f4:c3:e7:9c:07:7a:46:98:8d:5a:f5:90:06:76:a0:f0:39:cb:64:5d:d1:75:49:b2:16:c8:24:40:ce
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAMMDmu5QkG4oMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIxMB4XDTEyMDcxOTA5MDY1NloXDTQy
-MDcxOTA5MDY1NlowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjEw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqw3j33Jijp1pedxiy3QRk
-D2P9m5YJgNXoqqXinCaUOuiZc4yd39ffg/N4T0Dhf9Kn0uXKE5Pn7cZ3Xza1lK/o
-OI7bm+V8u8yN63Vz4STN5qctGS7Y1oprFOsIYgrY3LMATcMjfF9DCCMyEtztDK3A
-fQ+lekLZWnDZv6fXARz2m6uOt0qGeKAeVjGu74IKgEH3G8muqzIm1Cxr7X1r5OJe
-IgpFy4QxTaz+29FHuvlglzmxZcfe+5nkCiKxLU3lSCZpq+Kq8/v8kiky6bM+TR8n
-oc2OuRf7JT7JbvN32g0S9l3HuzYQ1VTW8+DiR0jm3hTaYVKvJrT1cU/J19IG32PK
-/yHoWQbgCNWEFVP3Q+V8xaCJmGtzxmjOZd69fwX3se72V6FglcXM6pM6vpmumwKj
-rckWtc7dXpl4fho5frLABaTAgqWjR56M6ly2vGfb5ipN0gTco65F97yLnByn1tUD
-3AjLLhbKXEAz6GfDLuemROoRRRw1ZS0eRWEkG4IupZ0zXWX4Qfkuy5Q/H6MMMSRE
-7cderVC6xkGbrPAXZcD4XW9boAo0PO7X6oifmPmvTiT6l7Jkdtqr9O3jw2Dv1fkC
-yC2fg69naQanMVXVz0tv/wQFx1isXxYb5dKj6zHbHzMVTdDypVP1y+E9Tmgt2BLd
-qvLmTZtJ5cUoobqwWsagtQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUiQq0OJMa5qvum5EY+fU8PjXQ04IwDQYJKoZI
-hvcNAQEFBQADggIBADKL9p1Kyb4U5YysOMo6CdQbzoaz3evUuii+Eq5FLAR0rBNR
-xVgYZk2C2tXck8An4b58n1KeElb21Zyp9HWc+jcSjxyT7Ff+Bw+r1RL3D65hXlaA
-SfX8MPWbTx9BLxyE04nH4toCdu0Jz2zBuByDHBb6lM19oMgY0sidbvW9adRtPTXo
-HqJPYNcHKfyyo6SdbhWSVhlMCrDpfNIZTUJG7L399ldb3Zh+pE3McgODWF3vkzpB
-emOqfDqo9ayk0d2iLbYq/J8BjuIQscTK5GfbVSUZP/3oNn6z4eGBrxEWi1CXYBmC
-AMBrTXO40RMHPuq2MU/wQppt4hF05ZSsjYSVPCGvxdpHyN85YmLLW1AL14FABZyb
-7bq2ix4Eb5YgOe2kfSnbSM6C3NQCjR0EMVrHS/BsYVLXtFHCgWzN4funodKSds+x
-DzdYpPJScWc/DIh4gInByLUfkmO+p3qKViwaqKactV2zY9ATIKHrkWzQjX2v3wvk
-F7mGnjixlAxYjOBVqjtjbZqJYLhkKpLGN/R+Q0O3c+gB53+XD9fyexn9GtePyfqF
-a3qdnom2piiZk4hA9z7NUaPK6u95RyG1/jLix8NRb76AdPCkwzryT+lf3xkK8jsT
-Q6wxpLPn6/wY1gGp8yqPNg7rtLG8t0zJa7+h89n07eLw4+1knj0vllJPgFOL
------END CERTIFICATE-----
-
-# Issuer: CN=CA Disig Root R2 O=Disig a.s.
-# Subject: CN=CA Disig Root R2 O=Disig a.s.
-# Label: "CA Disig Root R2"
-# Serial: 10572350602393338211
-# MD5 Fingerprint: 26:01:fb:d8:27:a7:17:9a:45:54:38:1a:43:01:3b:03
-# SHA1 Fingerprint: b5:61:eb:ea:a4:de:e4:25:4b:69:1a:98:a5:57:47:c2:34:c7:d9:71
-# SHA256 Fingerprint: e2:3d:4a:03:6d:7b:70:e9:f5:95:b1:42:20:79:d2:b9:1e:df:bb:1f:b6:51:a0:63:3e:aa:8a:9d:c5:f8:07:03
------BEGIN CERTIFICATE-----
-MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNV
-BAYTAlNLMRMwEQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMu
-MRkwFwYDVQQDExBDQSBEaXNpZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQy
-MDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sxEzARBgNVBAcTCkJyYXRpc2xhdmEx
-EzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERpc2lnIFJvb3QgUjIw
-ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbCw3Oe
-NcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNH
-PWSb6WiaxswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3I
-x2ymrdMxp7zo5eFm1tL7A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbe
-QTg06ov80egEFGEtQX6sx3dOy1FU+16SGBsEWmjGycT6txOgmLcRK7fWV8x8nhfR
-yyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqVg8NTEQxzHQuyRpDRQjrO
-QG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa5Beny912
-H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJ
-QfYEkoopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUD
-i/ZnWejBBhG93c+AAk9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORs
-nLMOPReisjQS1n6yqEm70XooQL6iFh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1
-rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud
-DwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5uQu0wDQYJKoZI
-hvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM
-tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqf
-GopTpti72TVVsRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkb
-lvdhuDvEK7Z4bLQjb/D907JedR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka
-+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W81k/BfDxujRNt+3vrMNDcTa/F1bal
-TFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjxmHHEt38OFdAlab0i
-nSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01utI3
-gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18Dr
-G5gPcFw0sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3Os
-zMOl6W8KjptlwlCFtaOgUxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8x
-L4ysEr3vQCj8KWefshNPZiTEUxnpHikV7+ZtsH8tZ/3zbBt1RqPlShfppNcL
------END CERTIFICATE-----
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/tests/__init__.py b/catapult/telemetry/third_party/websocket-client/websocket/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/tests/__init__.py
+++ /dev/null
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/tests/data/header01.txt b/catapult/telemetry/third_party/websocket-client/websocket/tests/data/header01.txt
deleted file mode 100644
index d44d24c..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/tests/data/header01.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HTTP/1.1 101 WebSocket Protocol Handshake
-Connection: Upgrade 
-Upgrade: WebSocket
-Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0=
-some_header: something
-
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/tests/data/header02.txt b/catapult/telemetry/third_party/websocket-client/websocket/tests/data/header02.txt
deleted file mode 100644
index f481de9..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/tests/data/header02.txt
+++ /dev/null
@@ -1,6 +0,0 @@
-HTTP/1.1 101 WebSocket Protocol Handshake
-Connection: Upgrade
-Upgrade WebSocket
-Sec-WebSocket-Accept: Kxep+hNu9n51529fGidYu7a3wO0=
-some_header: something
-
diff --git a/catapult/telemetry/third_party/websocket-client/websocket/tests/test_websocket.py b/catapult/telemetry/third_party/websocket-client/websocket/tests/test_websocket.py
deleted file mode 100644
index 8a8de52..0000000
--- a/catapult/telemetry/third_party/websocket-client/websocket/tests/test_websocket.py
+++ /dev/null
@@ -1,660 +0,0 @@
-# -*- coding: utf-8 -*-
-#
-
-import sys
-sys.path[0:0] = [""]
-
-import os
-import os.path
-import socket
-
-import six
-
-# websocket-client
-import websocket as ws
-from websocket._handshake import _create_sec_websocket_key, \
-    _validate as _validate_header
-from websocket._http import read_headers
-from websocket._url import get_proxy_info, parse_url
-from websocket._utils import validate_utf8
-
-if six.PY3:
-    from base64 import decodebytes as base64decode
-else:
-    from base64 import decodestring as base64decode
-
-if sys.version_info[0] == 2 and sys.version_info[1] < 7:
-    import unittest2 as unittest
-else:
-    import unittest
-
-try:
-    from ssl import SSLError
-except ImportError:
-    # dummy class of SSLError for ssl none-support environment.
-    class SSLError(Exception):
-        pass
-
-# Skip test to access the internet.
-TEST_WITH_INTERNET = os.environ.get('TEST_WITH_INTERNET', '0') == '1'
-
-# Skip Secure WebSocket test.
-TEST_SECURE_WS = True
-TRACEABLE = False
-
-
-def create_mask_key(_):
-    return "abcd"
-
-
-class SockMock(object):
-    def __init__(self):
-        self.data = []
-        self.sent = []
-
-    def add_packet(self, data):
-        self.data.append(data)
-
-    def recv(self, bufsize):
-        if self.data:
-            e = self.data.pop(0)
-            if isinstance(e, Exception):
-                raise e
-            if len(e) > bufsize:
-                self.data.insert(0, e[bufsize:])
-            return e[:bufsize]
-
-    def send(self, data):
-        self.sent.append(data)
-        return len(data)
-
-    def close(self):
-        pass
-
-
-class HeaderSockMock(SockMock):
-
-    def __init__(self, fname):
-        SockMock.__init__(self)
-        path = os.path.join(os.path.dirname(__file__), fname)
-        with open(path, "rb") as f:
-            self.add_packet(f.read())
-
-
-class WebSocketTest(unittest.TestCase):
-    def setUp(self):
-        ws.enableTrace(TRACEABLE)
-
-    def tearDown(self):
-        pass
-
-    def testDefaultTimeout(self):
-        self.assertEqual(ws.getdefaulttimeout(), None)
-        ws.setdefaulttimeout(10)
-        self.assertEqual(ws.getdefaulttimeout(), 10)
-        ws.setdefaulttimeout(None)
-
-    def testParseUrl(self):
-        p = parse_url("ws://www.example.com/r")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 80)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://www.example.com/r/")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 80)
-        self.assertEqual(p[2], "/r/")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://www.example.com/")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 80)
-        self.assertEqual(p[2], "/")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://www.example.com")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 80)
-        self.assertEqual(p[2], "/")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://www.example.com:8080/r")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://www.example.com:8080/")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://www.example.com:8080")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("wss://www.example.com:8080/r")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], True)
-
-        p = parse_url("wss://www.example.com:8080/r?key=value")
-        self.assertEqual(p[0], "www.example.com")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/r?key=value")
-        self.assertEqual(p[3], True)
-
-        self.assertRaises(ValueError, parse_url, "http://www.example.com/r")
-
-        if sys.version_info[0] == 2 and sys.version_info[1] < 7:
-            return
-
-        p = parse_url("ws://[2a03:4000:123:83::3]/r")
-        self.assertEqual(p[0], "2a03:4000:123:83::3")
-        self.assertEqual(p[1], 80)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("ws://[2a03:4000:123:83::3]:8080/r")
-        self.assertEqual(p[0], "2a03:4000:123:83::3")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], False)
-
-        p = parse_url("wss://[2a03:4000:123:83::3]/r")
-        self.assertEqual(p[0], "2a03:4000:123:83::3")
-        self.assertEqual(p[1], 443)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], True)
-
-        p = parse_url("wss://[2a03:4000:123:83::3]:8080/r")
-        self.assertEqual(p[0], "2a03:4000:123:83::3")
-        self.assertEqual(p[1], 8080)
-        self.assertEqual(p[2], "/r")
-        self.assertEqual(p[3], True)
-
-    def testWSKey(self):
-        key = _create_sec_websocket_key()
-        self.assertTrue(key != 24)
-        self.assertTrue(six.u("¥n") not in key)
-
-    def testWsUtils(self):
-        key = "c6b8hTg4EeGb2gQMztV1/g=="
-        required_header = {
-            "upgrade": "websocket",
-            "connection": "upgrade",
-            "sec-websocket-accept": "Kxep+hNu9n51529fGidYu7a3wO0=",
-            }
-        self.assertEqual(_validate_header(required_header, key, None), (True, None))
-
-        header = required_header.copy()
-        header["upgrade"] = "http"
-        self.assertEqual(_validate_header(header, key, None), (False, None))
-        del header["upgrade"]
-        self.assertEqual(_validate_header(header, key, None), (False, None))
-
-        header = required_header.copy()
-        header["connection"] = "something"
-        self.assertEqual(_validate_header(header, key, None), (False, None))
-        del header["connection"]
-        self.assertEqual(_validate_header(header, key, None), (False, None))
-
-        header = required_header.copy()
-        header["sec-websocket-accept"] = "something"
-        self.assertEqual(_validate_header(header, key, None), (False, None))
-        del header["sec-websocket-accept"]
-        self.assertEqual(_validate_header(header, key, None), (False, None))
-
-        header = required_header.copy()
-        header["sec-websocket-protocol"] = "sub1"
-        self.assertEqual(_validate_header(header, key, ["sub1", "sub2"]), (True, "sub1"))
-        self.assertEqual(_validate_header(header, key, ["sub2", "sub3"]), (False, None))
-
-        header = required_header.copy()
-        header["sec-websocket-protocol"] = "sUb1"
-        self.assertEqual(_validate_header(header, key, ["Sub1", "suB2"]), (True, "sub1"))
-
-
-    def testReadHeader(self):
-        status, header = read_headers(HeaderSockMock("data/header01.txt"))
-        self.assertEqual(status, 101)
-        self.assertEqual(header["connection"], "Upgrade")
-
-        HeaderSockMock("data/header02.txt")
-        self.assertRaises(ws.WebSocketException, read_headers, HeaderSockMock("data/header02.txt"))
-
-    def testSend(self):
-        # TODO: add longer frame data
-        sock = ws.WebSocket()
-        sock.set_mask_key(create_mask_key)
-        s = sock.sock = HeaderSockMock("data/header01.txt")
-        sock.send("Hello")
-        self.assertEqual(s.sent[0], six.b("\x81\x85abcd)\x07\x0f\x08\x0e"))
-
-        sock.send("こんにちは")
-        self.assertEqual(s.sent[1], six.b("\x81\x8fabcd\x82\xe3\xf0\x87\xe3\xf1\x80\xe5\xca\x81\xe2\xc5\x82\xe3\xcc"))
-
-        sock.send(u"こんにちは")
-        self.assertEqual(s.sent[1], six.b("\x81\x8fabcd\x82\xe3\xf0\x87\xe3\xf1\x80\xe5\xca\x81\xe2\xc5\x82\xe3\xcc"))
-
-        sock.send("x" * 127)
-
-    def testRecv(self):
-        # TODO: add longer frame data
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        something = six.b("\x81\x8fabcd\x82\xe3\xf0\x87\xe3\xf1\x80\xe5\xca\x81\xe2\xc5\x82\xe3\xcc")
-        s.add_packet(something)
-        data = sock.recv()
-        self.assertEqual(data, "こんにちは")
-
-        s.add_packet(six.b("\x81\x85abcd)\x07\x0f\x08\x0e"))
-        data = sock.recv()
-        self.assertEqual(data, "Hello")
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testIter(self):
-        count = 2
-        for _ in ws.create_connection('ws://stream.meetup.com/2/rsvps'):
-            count -= 1
-            if count == 0:
-                break
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testNext(self):
-        sock = ws.create_connection('ws://stream.meetup.com/2/rsvps')
-        self.assertEqual(str, type(next(sock)))
-
-    def testInternalRecvStrict(self):
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        s.add_packet(six.b("foo"))
-        s.add_packet(socket.timeout())
-        s.add_packet(six.b("bar"))
-        # s.add_packet(SSLError("The read operation timed out"))
-        s.add_packet(six.b("baz"))
-        with self.assertRaises(ws.WebSocketTimeoutException):
-            sock.frame_buffer.recv_strict(9)
-        # if six.PY2:
-        #     with self.assertRaises(ws.WebSocketTimeoutException):
-        #         data = sock._recv_strict(9)
-        # else:
-        #     with self.assertRaises(SSLError):
-        #         data = sock._recv_strict(9)
-        data = sock.frame_buffer.recv_strict(9)
-        self.assertEqual(data, six.b("foobarbaz"))
-        with self.assertRaises(ws.WebSocketConnectionClosedException):
-            sock.frame_buffer.recv_strict(1)
-
-    def testRecvTimeout(self):
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        s.add_packet(six.b("\x81"))
-        s.add_packet(socket.timeout())
-        s.add_packet(six.b("\x8dabcd\x29\x07\x0f\x08\x0e"))
-        s.add_packet(socket.timeout())
-        s.add_packet(six.b("\x4e\x43\x33\x0e\x10\x0f\x00\x40"))
-        with self.assertRaises(ws.WebSocketTimeoutException):
-            sock.recv()
-        with self.assertRaises(ws.WebSocketTimeoutException):
-            sock.recv()
-        data = sock.recv()
-        self.assertEqual(data, "Hello, World!")
-        with self.assertRaises(ws.WebSocketConnectionClosedException):
-            sock.recv()
-
-    def testRecvWithSimpleFragmentation(self):
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        # OPCODE=TEXT, FIN=0, MSG="Brevity is "
-        s.add_packet(six.b("\x01\x8babcd#\x10\x06\x12\x08\x16\x1aD\x08\x11C"))
-        # OPCODE=CONT, FIN=1, MSG="the soul of wit"
-        s.add_packet(six.b("\x80\x8fabcd\x15\n\x06D\x12\r\x16\x08A\r\x05D\x16\x0b\x17"))
-        data = sock.recv()
-        self.assertEqual(data, "Brevity is the soul of wit")
-        with self.assertRaises(ws.WebSocketConnectionClosedException):
-            sock.recv()
-
-    def testRecvWithFireEventOfFragmentation(self):
-        sock = ws.WebSocket(fire_cont_frame=True)
-        s = sock.sock = SockMock()
-        # OPCODE=TEXT, FIN=0, MSG="Brevity is "
-        s.add_packet(six.b("\x01\x8babcd#\x10\x06\x12\x08\x16\x1aD\x08\x11C"))
-        # OPCODE=CONT, FIN=0, MSG="Brevity is "
-        s.add_packet(six.b("\x00\x8babcd#\x10\x06\x12\x08\x16\x1aD\x08\x11C"))
-        # OPCODE=CONT, FIN=1, MSG="the soul of wit"
-        s.add_packet(six.b("\x80\x8fabcd\x15\n\x06D\x12\r\x16\x08A\r\x05D\x16\x0b\x17"))
-
-        _, data = sock.recv_data()
-        self.assertEqual(data, six.b("Brevity is "))
-        _, data = sock.recv_data()
-        self.assertEqual(data, six.b("Brevity is "))
-        _, data = sock.recv_data()
-        self.assertEqual(data, six.b("the soul of wit"))
-
-        # OPCODE=CONT, FIN=0, MSG="Brevity is "
-        s.add_packet(six.b("\x80\x8babcd#\x10\x06\x12\x08\x16\x1aD\x08\x11C"))
-
-        with self.assertRaises(ws.WebSocketException):
-            sock.recv_data()
-
-        with self.assertRaises(ws.WebSocketConnectionClosedException):
-            sock.recv()
-
-    def testClose(self):
-        sock = ws.WebSocket()
-        sock.sock = SockMock()
-        sock.connected = True
-        sock.close()
-        self.assertEqual(sock.connected, False)
-
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        sock.connected = True
-        s.add_packet(six.b('\x88\x80\x17\x98p\x84'))
-        sock.recv()
-        self.assertEqual(sock.connected, False)
-
-    def testRecvContFragmentation(self):
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        # OPCODE=CONT, FIN=1, MSG="the soul of wit"
-        s.add_packet(six.b("\x80\x8fabcd\x15\n\x06D\x12\r\x16\x08A\r\x05D\x16\x0b\x17"))
-        self.assertRaises(ws.WebSocketException, sock.recv)
-
-    def testRecvWithProlongedFragmentation(self):
-        sock = ws.WebSocket()
-        s = sock.sock = SockMock()
-        # OPCODE=TEXT, FIN=0, MSG="Once more unto the breach, "
-        s.add_packet(six.b("\x01\x9babcd.\x0c\x00\x01A\x0f\x0c\x16\x04B\x16\n\x15"
-                           "\rC\x10\t\x07C\x06\x13\x07\x02\x07\tNC"))
-        # OPCODE=CONT, FIN=0, MSG="dear friends, "
-        s.add_packet(six.b("\x00\x8eabcd\x05\x07\x02\x16A\x04\x11\r\x04\x0c\x07"
-                           "\x17MB"))
-        # OPCODE=CONT, FIN=1, MSG="once more"
-        s.add_packet(six.b("\x80\x89abcd\x0e\x0c\x00\x01A\x0f\x0c\x16\x04"))
-        data = sock.recv()
-        self.assertEqual(
-            data,
-            "Once more unto the breach, dear friends, once more")
-        with self.assertRaises(ws.WebSocketConnectionClosedException):
-            sock.recv()
-
-    def testRecvWithFragmentationAndControlFrame(self):
-        sock = ws.WebSocket()
-        sock.set_mask_key(create_mask_key)
-        s = sock.sock = SockMock()
-        # OPCODE=TEXT, FIN=0, MSG="Too much "
-        s.add_packet(six.b("\x01\x89abcd5\r\x0cD\x0c\x17\x00\x0cA"))
-        # OPCODE=PING, FIN=1, MSG="Please PONG this"
-        s.add_packet(six.b("\x89\x90abcd1\x0e\x06\x05\x12\x07C4.,$D\x15\n\n\x17"))
-        # OPCODE=CONT, FIN=1, MSG="of a good thing"
-        s.add_packet(six.b("\x80\x8fabcd\x0e\x04C\x05A\x05\x0c\x0b\x05B\x17\x0c"
-                           "\x08\x0c\x04"))
-        data = sock.recv()
-        self.assertEqual(data, "Too much of a good thing")
-        with self.assertRaises(ws.WebSocketConnectionClosedException):
-            sock.recv()
-        self.assertEqual(
-            s.sent[0],
-            six.b("\x8a\x90abcd1\x0e\x06\x05\x12\x07C4.,$D\x15\n\n\x17"))
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testWebSocket(self):
-        s = ws.create_connection("ws://echo.websocket.org/")
-        self.assertNotEqual(s, None)
-        s.send("Hello, World")
-        result = s.recv()
-        self.assertEqual(result, "Hello, World")
-
-        s.send(u"こにゃにゃちは、世界")
-        result = s.recv()
-        self.assertEqual(result, "こにゃにゃちは、世界")
-        s.close()
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testPingPong(self):
-        s = ws.create_connection("ws://echo.websocket.org/")
-        self.assertNotEqual(s, None)
-        s.ping("Hello")
-        s.pong("Hi")
-        s.close()
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    @unittest.skipUnless(TEST_SECURE_WS, "wss://echo.websocket.org doesn't work well.")
-    def testSecureWebSocket(self):
-        if 1:
-            import ssl
-            s = ws.create_connection("wss://echo.websocket.org/")
-            self.assertNotEqual(s, None)
-            self.assertTrue(isinstance(s.sock, ssl.SSLSocket))
-            s.send("Hello, World")
-            result = s.recv()
-            self.assertEqual(result, "Hello, World")
-            s.send(u"こにゃにゃちは、世界")
-            result = s.recv()
-            self.assertEqual(result, "こにゃにゃちは、世界")
-            s.close()
-        #except:
-        #    pass
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testWebSocketWihtCustomHeader(self):
-        s = ws.create_connection("ws://echo.websocket.org/",
-                                 headers={"User-Agent": "PythonWebsocketClient"})
-        self.assertNotEqual(s, None)
-        s.send("Hello, World")
-        result = s.recv()
-        self.assertEqual(result, "Hello, World")
-        s.close()
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testAfterClose(self):
-        s = ws.create_connection("ws://echo.websocket.org/")
-        self.assertNotEqual(s, None)
-        s.close()
-        self.assertRaises(ws.WebSocketConnectionClosedException, s.send, "Hello")
-        self.assertRaises(ws.WebSocketConnectionClosedException, s.recv)
-
-    def testNonce(self):
-        """ WebSocket key should be a random 16-byte nonce.
-        """
-        key = _create_sec_websocket_key()
-        nonce = base64decode(key.encode("utf-8"))
-        self.assertEqual(16, len(nonce))
-
-
-class WebSocketAppTest(unittest.TestCase):
-
-    class NotSetYet(object):
-        """ A marker class for signalling that a value hasn't been set yet.
-        """
-
-    def setUp(self):
-        ws.enableTrace(TRACEABLE)
-
-        WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
-        WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
-        WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
-
-    def tearDown(self):
-        WebSocketAppTest.keep_running_open = WebSocketAppTest.NotSetYet()
-        WebSocketAppTest.keep_running_close = WebSocketAppTest.NotSetYet()
-        WebSocketAppTest.get_mask_key_id = WebSocketAppTest.NotSetYet()
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testKeepRunning(self):
-        """ A WebSocketApp should keep running as long as its self.keep_running
-        is not False (in the boolean context).
-        """
-
-        def on_open(self, *args, **kwargs):
-            """ Set the keep_running flag for later inspection and immediately
-            close the connection.
-            """
-            WebSocketAppTest.keep_running_open = self.keep_running
-
-            self.close()
-
-        def on_close(self, *args, **kwargs):
-            """ Set the keep_running flag for the test to use.
-            """
-            WebSocketAppTest.keep_running_close = self.keep_running
-
-        app = ws.WebSocketApp('ws://echo.websocket.org/', on_open=on_open, on_close=on_close)
-        app.run_forever()
-
-        self.assertFalse(isinstance(WebSocketAppTest.keep_running_open,
-                                    WebSocketAppTest.NotSetYet))
-
-        self.assertFalse(isinstance(WebSocketAppTest.keep_running_close,
-                                    WebSocketAppTest.NotSetYet))
-
-        self.assertEqual(True, WebSocketAppTest.keep_running_open)
-        self.assertEqual(False, WebSocketAppTest.keep_running_close)
-
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testSockMaskKey(self):
-        """ A WebSocketApp should forward the received mask_key function down
-        to the actual socket.
-        """
-
-        def my_mask_key_func():
-            pass
-
-        def on_open(self, *args, **kwargs):
-            """ Set the value so the test can use it later on and immediately
-            close the connection.
-            """
-            WebSocketAppTest.get_mask_key_id = id(self.get_mask_key)
-            self.close()
-
-        app = ws.WebSocketApp('ws://echo.websocket.org/', on_open=on_open, get_mask_key=my_mask_key_func)
-        app.run_forever()
-
-        # Note: We can't use 'is' for comparing the functions directly, need to use 'id'.
-        self.assertEqual(WebSocketAppTest.get_mask_key_id, id(my_mask_key_func))
-
-
-class SockOptTest(unittest.TestCase):
-    @unittest.skipUnless(TEST_WITH_INTERNET, "Internet-requiring tests are disabled")
-    def testSockOpt(self):
-        sockopt = ((socket.IPPROTO_TCP, socket.TCP_NODELAY, 1),)
-        s = ws.create_connection("ws://echo.websocket.org", sockopt=sockopt)
-        self.assertNotEqual(s.sock.getsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY), 0)
-        s.close()
-
-class UtilsTest(unittest.TestCase):
-    def testUtf8Validator(self):
-        state = validate_utf8(six.b('\xf0\x90\x80\x80'))
-        self.assertEqual(state, True)
-        state = validate_utf8(six.b('\xce\xba\xe1\xbd\xb9\xcf\x83\xce\xbc\xce\xb5\xed\xa0\x80edited'))
-        self.assertEqual(state, False)
-        state = validate_utf8(six.b(''))
-        self.assertEqual(state, True)
-
-class ProxyInfoTest(unittest.TestCase):
-    def setUp(self):
-        self.http_proxy = os.environ.get("http_proxy", None)
-        self.https_proxy = os.environ.get("https_proxy", None)
-        if "http_proxy" in os.environ:
-            del os.environ["http_proxy"]
-        if "https_proxy" in os.environ:
-            del os.environ["https_proxy"]
-
-    def tearDown(self):
-        if self.http_proxy:
-            os.environ["http_proxy"] = self.http_proxy
-        elif "http_proxy" in os.environ:
-            del os.environ["http_proxy"]
-
-        if self.https_proxy:
-            os.environ["https_proxy"] = self.https_proxy
-        elif "https_proxy" in os.environ:
-            del os.environ["https_proxy"]
-
-
-    def testProxyFromArgs(self):
-        self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost"), ("localhost", 0, None))
-        self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost", proxy_port=3128), ("localhost", 3128, None))
-        self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost"), ("localhost", 0, None))
-        self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128), ("localhost", 3128, None))
-
-        self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost", proxy_auth=("a", "b")),
-            ("localhost", 0, ("a", "b")))
-        self.assertEqual(get_proxy_info("echo.websocket.org", False, proxy_host="localhost", proxy_port=3128, proxy_auth=("a", "b")),
-            ("localhost", 3128, ("a", "b")))
-        self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_auth=("a", "b")),
-            ("localhost", 0, ("a", "b")))
-        self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128, proxy_auth=("a", "b")),
-            ("localhost", 3128, ("a", "b")))
-
-        self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128, no_proxy=["example.com"], proxy_auth=("a", "b")),
-            ("localhost", 3128, ("a", "b")))
-        self.assertEqual(get_proxy_info("echo.websocket.org", True, proxy_host="localhost", proxy_port=3128, no_proxy=["echo.websocket.org"], proxy_auth=("a", "b")),
-            (None, 0, None))
-
-
-    def testProxyFromEnv(self):
-        os.environ["http_proxy"] = "http://localhost/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, None))
-        os.environ["http_proxy"] = "http://localhost:3128/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, None))
-
-        os.environ["http_proxy"] = "http://localhost/"
-        os.environ["https_proxy"] = "http://localhost2/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, None))
-        os.environ["http_proxy"] = "http://localhost:3128/"
-        os.environ["https_proxy"] = "http://localhost2:3128/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, None))
-
-        os.environ["http_proxy"] = "http://localhost/"
-        os.environ["https_proxy"] = "http://localhost2/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", None, None))
-        os.environ["http_proxy"] = "http://localhost:3128/"
-        os.environ["https_proxy"] = "http://localhost2:3128/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, None))
-
-
-        os.environ["http_proxy"] = "http://a:b@localhost/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, ("a", "b")))
-        os.environ["http_proxy"] = "http://a:b@localhost:3128/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, ("a", "b")))
-
-        os.environ["http_proxy"] = "http://a:b@localhost/"
-        os.environ["https_proxy"] = "http://a:b@localhost2/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", None, ("a", "b")))
-        os.environ["http_proxy"] = "http://a:b@localhost:3128/"
-        os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", False), ("localhost", 3128, ("a", "b")))
-
-        os.environ["http_proxy"] = "http://a:b@localhost/"
-        os.environ["https_proxy"] = "http://a:b@localhost2/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", None, ("a", "b")))
-        os.environ["http_proxy"] = "http://a:b@localhost:3128/"
-        os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
-        self.assertEqual(get_proxy_info("echo.websocket.org", True), ("localhost2", 3128, ("a", "b")))
-
-        os.environ["http_proxy"] = "http://a:b@localhost/"
-        os.environ["https_proxy"] = "http://a:b@localhost2/"
-        os.environ["no_proxy"] = "example1.com,example2.com"
-        self.assertEqual(get_proxy_info("example.1.com", True), ("localhost2", None, ("a", "b")))
-        os.environ["http_proxy"] = "http://a:b@localhost:3128/"
-        os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
-        os.environ["no_proxy"] = "example1.com,example2.com, echo.websocket.org"
-        self.assertEqual(get_proxy_info("echo.websocket.org", True), (None, 0, None))
-
-        os.environ["http_proxy"] = "http://a:b@localhost:3128/"
-        os.environ["https_proxy"] = "http://a:b@localhost2:3128/"
-        os.environ["no_proxy"] = "127.0.0.0/8, 192.168.0.0/16"
-        self.assertEqual(get_proxy_info("127.0.0.1", False), (None, 0, None))
-        self.assertEqual(get_proxy_info("192.168.1.1", False), (None, 0, None))
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/catapult/telemetry/update_docs b/catapult/telemetry/update_docs
deleted file mode 100755
index f2f92ac..0000000
--- a/catapult/telemetry/update_docs
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import os
-import sys
-
-from build import update_docs
-
-if __name__ == '__main__':
-  sys.exit(update_docs.Main(sys.argv[1:]))
diff --git a/catapult/telemetry/validate_binary_dependencies b/catapult/telemetry/validate_binary_dependencies
deleted file mode 100755
index dbcd7e4..0000000
--- a/catapult/telemetry/validate_binary_dependencies
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-import argparse
-import json
-import os
-import sys
-
-from telemetry.core import util
-
-sys.path.insert(1, os.path.abspath(os.path.join(
-    util.GetCatapultDir(), 'common', 'py_utils')))
-sys.path.insert(1, os.path.abspath(os.path.join(
-    util.GetCatapultDir(), 'dependency_manager')))
-from py_utils import cloud_storage
-import dependency_manager
-
-
-def ValidateCloudStorageDependencies(file_path):
-  base_config = dependency_manager.BaseConfig(file_path)
-  cloud_storage_deps_not_exist = []
-  for dep_info in base_config.IterDependencyInfo():
-    if dep_info.has_cloud_storage_info:
-      if not dep_info.cloud_storage_info.DependencyExistsInCloudStorage():
-        print >> sys.stderr, (
-          '%s does not exist in cloud storage' % dep_info.cloud_storage_info)
-        cloud_storage_deps_not_exist = True
-      else:
-        print >> sys.stdout, (
-          '%s passes cloud storage validation' % dep_info.dependency)
-
-  if cloud_storage_deps_not_exist:
-    raise Exception(
-        "Some dependencies specify cloud storage locations that don't exist.")
-
-
-def Main(args):
-  parser = argparse.ArgumentParser(
-      description='Validate the dependencies in a binary dependency json file')
-  parser.add_argument('file_path', type=str,
-                      help='The path to binary dependency json file')
-  options = parser.parse_args(args)
-  ValidateCloudStorageDependencies(options.file_path)
-  return 0
-
-
-if __name__ == '__main__':
-  sys.exit(Main(sys.argv[1:]))
diff --git a/catapult/telemetry/third_party/pyserial/LICENSE.txt b/catapult/third_party/pyserial/LICENSE.txt
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/LICENSE.txt
rename to catapult/third_party/pyserial/LICENSE.txt
diff --git a/catapult/telemetry/third_party/pyserial/README.chromium b/catapult/third_party/pyserial/README.chromium
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/README.chromium
rename to catapult/third_party/pyserial/README.chromium
diff --git a/catapult/telemetry/third_party/pyserial/linux-product_info.patch b/catapult/third_party/pyserial/linux-product_info.patch
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/linux-product_info.patch
rename to catapult/third_party/pyserial/linux-product_info.patch
diff --git a/catapult/telemetry/third_party/pyserial/serial/__init__.py b/catapult/third_party/pyserial/serial/__init__.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/__init__.py
rename to catapult/third_party/pyserial/serial/__init__.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/rfc2217.py b/catapult/third_party/pyserial/serial/rfc2217.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/rfc2217.py
rename to catapult/third_party/pyserial/serial/rfc2217.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/serialcli.py b/catapult/third_party/pyserial/serial/serialcli.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/serialcli.py
rename to catapult/third_party/pyserial/serial/serialcli.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/serialjava.py b/catapult/third_party/pyserial/serial/serialjava.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/serialjava.py
rename to catapult/third_party/pyserial/serial/serialjava.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/serialposix.py b/catapult/third_party/pyserial/serial/serialposix.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/serialposix.py
rename to catapult/third_party/pyserial/serial/serialposix.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/serialutil.py b/catapult/third_party/pyserial/serial/serialutil.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/serialutil.py
rename to catapult/third_party/pyserial/serial/serialutil.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/serialwin32.py b/catapult/third_party/pyserial/serial/serialwin32.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/serialwin32.py
rename to catapult/third_party/pyserial/serial/serialwin32.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/sermsdos.py b/catapult/third_party/pyserial/serial/sermsdos.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/sermsdos.py
rename to catapult/third_party/pyserial/serial/sermsdos.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/__init__.py b/catapult/third_party/pyserial/serial/tools/__init__.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/__init__.py
rename to catapult/third_party/pyserial/serial/tools/__init__.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/list_ports.py b/catapult/third_party/pyserial/serial/tools/list_ports.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/list_ports.py
rename to catapult/third_party/pyserial/serial/tools/list_ports.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/list_ports_linux.py b/catapult/third_party/pyserial/serial/tools/list_ports_linux.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/list_ports_linux.py
rename to catapult/third_party/pyserial/serial/tools/list_ports_linux.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/list_ports_osx.py b/catapult/third_party/pyserial/serial/tools/list_ports_osx.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/list_ports_osx.py
rename to catapult/third_party/pyserial/serial/tools/list_ports_osx.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/list_ports_posix.py b/catapult/third_party/pyserial/serial/tools/list_ports_posix.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/list_ports_posix.py
rename to catapult/third_party/pyserial/serial/tools/list_ports_posix.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/list_ports_windows.py b/catapult/third_party/pyserial/serial/tools/list_ports_windows.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/list_ports_windows.py
rename to catapult/third_party/pyserial/serial/tools/list_ports_windows.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/tools/miniterm.py b/catapult/third_party/pyserial/serial/tools/miniterm.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/tools/miniterm.py
rename to catapult/third_party/pyserial/serial/tools/miniterm.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/urlhandler/__init__.py b/catapult/third_party/pyserial/serial/urlhandler/__init__.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/urlhandler/__init__.py
rename to catapult/third_party/pyserial/serial/urlhandler/__init__.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_hwgrep.py b/catapult/third_party/pyserial/serial/urlhandler/protocol_hwgrep.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_hwgrep.py
rename to catapult/third_party/pyserial/serial/urlhandler/protocol_hwgrep.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_loop.py b/catapult/third_party/pyserial/serial/urlhandler/protocol_loop.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_loop.py
rename to catapult/third_party/pyserial/serial/urlhandler/protocol_loop.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_rfc2217.py b/catapult/third_party/pyserial/serial/urlhandler/protocol_rfc2217.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_rfc2217.py
rename to catapult/third_party/pyserial/serial/urlhandler/protocol_rfc2217.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_socket.py b/catapult/third_party/pyserial/serial/urlhandler/protocol_socket.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/urlhandler/protocol_socket.py
rename to catapult/third_party/pyserial/serial/urlhandler/protocol_socket.py
diff --git a/catapult/telemetry/third_party/pyserial/serial/win32.py b/catapult/third_party/pyserial/serial/win32.py
similarity index 100%
rename from catapult/telemetry/third_party/pyserial/serial/win32.py
rename to catapult/third_party/pyserial/serial/win32.py
diff --git a/catapult/third_party/zipfile/LICENSE b/catapult/third_party/zipfile/LICENSE
new file mode 100644
index 0000000..84a3337
--- /dev/null
+++ b/catapult/third_party/zipfile/LICENSE
@@ -0,0 +1,255 @@
+A. HISTORY OF THE SOFTWARE
+==========================
+
+Python was created in the early 1990s by Guido van Rossum at Stichting
+Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands
+as a successor of a language called ABC.  Guido remains Python's
+principal author, although it includes many contributions from others.
+
+In 1995, Guido continued his work on Python at the Corporation for
+National Research Initiatives (CNRI, see http://www.cnri.reston.va.us)
+in Reston, Virginia where he released several versions of the
+software.
+
+In May 2000, Guido and the Python core development team moved to
+BeOpen.com to form the BeOpen PythonLabs team.  In October of the same
+year, the PythonLabs team moved to Digital Creations (now Zope
+Corporation, see http://www.zope.com).  In 2001, the Python Software
+Foundation (PSF, see http://www.python.org/psf/) was formed, a
+non-profit organization created specifically to own Python-related
+Intellectual Property.  Zope Corporation is a sponsoring member of
+the PSF.
+
+All Python releases are Open Source (see http://www.opensource.org for
+the Open Source Definition).  Historically, most, but not all, Python
+releases have also been GPL-compatible; the table below summarizes
+the various releases.
+
+    Release         Derived     Year        Owner       GPL-
+                    from                                compatible? (1)
+
+    0.9.0 thru 1.2              1991-1995   CWI         yes
+    1.3 thru 1.5.2  1.2         1995-1999   CNRI        yes
+    1.6             1.5.2       2000        CNRI        no
+    2.0             1.6         2000        BeOpen.com  no
+    1.6.1           1.6         2001        CNRI        yes (2)
+    2.1             2.0+1.6.1   2001        PSF         no
+    2.0.1           2.0+1.6.1   2001        PSF         yes
+    2.1.1           2.1+2.0.1   2001        PSF         yes
+    2.1.2           2.1.1       2002        PSF         yes
+    2.1.3           2.1.2       2002        PSF         yes
+    2.2 and above   2.1.1       2001-now    PSF         yes
+
+Footnotes:
+
+(1) GPL-compatible doesn't mean that we're distributing Python under
+    the GPL.  All Python licenses, unlike the GPL, let you distribute
+    a modified version without making your changes open source.  The
+    GPL-compatible licenses make it possible to combine Python with
+    other software that is released under the GPL; the others don't.
+
+(2) According to Richard Stallman, 1.6.1 is not GPL-compatible,
+    because its license has a choice of law clause.  According to
+    CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1
+    is "not incompatible" with the GPL.
+
+Thanks to the many outside volunteers who have worked under Guido's
+direction to make these releases possible.
+
+
+B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON
+===============================================================
+
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014, 2015, 2016 Python Software Foundation; All Rights
+Reserved" are retained in Python alone or in any derivative version prepared by
+Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis.  PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee.  This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis.  BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions.  Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee.  This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party.  As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee.  Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement.  This Agreement together with
+Python 1.6.1 may be located on the Internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013.  This
+Agreement may also be obtained from a proxy server on the Internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis.  CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED.  BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement.  Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee.  This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+        ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands.  All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/catapult/third_party/zipfile/README.chromium b/catapult/third_party/zipfile/README.chromium
new file mode 100644
index 0000000..f45d3cf
--- /dev/null
+++ b/catapult/third_party/zipfile/README.chromium
@@ -0,0 +1,16 @@
+Name: Python zipfile module
+Short Name: zipfile
+URL: https://github.com/python/cpython/blob/master/Lib/zipfile.py
+Version: 2.7.13
+License: Python
+License File: NOT_SHIPPED
+Security Critical: no
+
+Description:
+This is a copy of the zipfile module from Python 2.7.13. This snapshot was
+taken to workaround a bug in older Python versions such as 2.7.3. See
+<https://bugs.python.org/issue6972> and specifically the fix at
+<https://hg.python.org/cpython/rev/0c5fa35c9f12#l3.11>.
+
+Local Modifications:
+Renamed zipfile.py to zipfile_2_7_13.py to avoid conflicting with system copy.
diff --git a/catapult/third_party/zipfile/zipfile_2_7_13.py b/catapult/third_party/zipfile/zipfile_2_7_13.py
new file mode 100644
index 0000000..1d10650
--- /dev/null
+++ b/catapult/third_party/zipfile/zipfile_2_7_13.py
@@ -0,0 +1,1543 @@
+"""
+Read and write ZIP files.
+"""
+import struct, os, time, sys, shutil
+import binascii, cStringIO, stat
+import io
+import re
+import string
+
+try:
+    import zlib # We may need its compression method
+    crc32 = zlib.crc32
+except ImportError:
+    zlib = None
+    crc32 = binascii.crc32
+
+__all__ = ["BadZipfile", "error", "ZIP_STORED", "ZIP_DEFLATED", "is_zipfile",
+           "ZipInfo", "ZipFile", "PyZipFile", "LargeZipFile" ]
+
+class BadZipfile(Exception):
+    pass
+
+
+class LargeZipFile(Exception):
+    """
+    Raised when writing a zipfile, the zipfile requires ZIP64 extensions
+    and those extensions are disabled.
+    """
+
+error = BadZipfile      # The exception raised by this module
+
+ZIP64_LIMIT = (1 << 31) - 1
+ZIP_FILECOUNT_LIMIT = (1 << 16) - 1
+ZIP_MAX_COMMENT = (1 << 16) - 1
+
+# constants for Zip file compression methods
+ZIP_STORED = 0
+ZIP_DEFLATED = 8
+# Other ZIP compression methods not supported
+
+# Below are some formats and associated data for reading/writing headers using
+# the struct module.  The names and structures of headers/records are those used
+# in the PKWARE description of the ZIP file format:
+#     http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+# (URL valid as of January 2008)
+
+# The "end of central directory" structure, magic number, size, and indices
+# (section V.I in the format document)
+structEndArchive = "<4s4H2LH"
+stringEndArchive = "PK\005\006"
+sizeEndCentDir = struct.calcsize(structEndArchive)
+
+_ECD_SIGNATURE = 0
+_ECD_DISK_NUMBER = 1
+_ECD_DISK_START = 2
+_ECD_ENTRIES_THIS_DISK = 3
+_ECD_ENTRIES_TOTAL = 4
+_ECD_SIZE = 5
+_ECD_OFFSET = 6
+_ECD_COMMENT_SIZE = 7
+# These last two indices are not part of the structure as defined in the
+# spec, but they are used internally by this module as a convenience
+_ECD_COMMENT = 8
+_ECD_LOCATION = 9
+
+# The "central directory" structure, magic number, size, and indices
+# of entries in the structure (section V.F in the format document)
+structCentralDir = "<4s4B4HL2L5H2L"
+stringCentralDir = "PK\001\002"
+sizeCentralDir = struct.calcsize(structCentralDir)
+
+# indexes of entries in the central directory structure
+_CD_SIGNATURE = 0
+_CD_CREATE_VERSION = 1
+_CD_CREATE_SYSTEM = 2
+_CD_EXTRACT_VERSION = 3
+_CD_EXTRACT_SYSTEM = 4
+_CD_FLAG_BITS = 5
+_CD_COMPRESS_TYPE = 6
+_CD_TIME = 7
+_CD_DATE = 8
+_CD_CRC = 9
+_CD_COMPRESSED_SIZE = 10
+_CD_UNCOMPRESSED_SIZE = 11
+_CD_FILENAME_LENGTH = 12
+_CD_EXTRA_FIELD_LENGTH = 13
+_CD_COMMENT_LENGTH = 14
+_CD_DISK_NUMBER_START = 15
+_CD_INTERNAL_FILE_ATTRIBUTES = 16
+_CD_EXTERNAL_FILE_ATTRIBUTES = 17
+_CD_LOCAL_HEADER_OFFSET = 18
+
+# The "local file header" structure, magic number, size, and indices
+# (section V.A in the format document)
+structFileHeader = "<4s2B4HL2L2H"
+stringFileHeader = "PK\003\004"
+sizeFileHeader = struct.calcsize(structFileHeader)
+
+_FH_SIGNATURE = 0
+_FH_EXTRACT_VERSION = 1
+_FH_EXTRACT_SYSTEM = 2
+_FH_GENERAL_PURPOSE_FLAG_BITS = 3
+_FH_COMPRESSION_METHOD = 4
+_FH_LAST_MOD_TIME = 5
+_FH_LAST_MOD_DATE = 6
+_FH_CRC = 7
+_FH_COMPRESSED_SIZE = 8
+_FH_UNCOMPRESSED_SIZE = 9
+_FH_FILENAME_LENGTH = 10
+_FH_EXTRA_FIELD_LENGTH = 11
+
+# The "Zip64 end of central directory locator" structure, magic number, and size
+structEndArchive64Locator = "<4sLQL"
+stringEndArchive64Locator = "PK\x06\x07"
+sizeEndCentDir64Locator = struct.calcsize(structEndArchive64Locator)
+
+# The "Zip64 end of central directory" record, magic number, size, and indices
+# (section V.G in the format document)
+structEndArchive64 = "<4sQ2H2L4Q"
+stringEndArchive64 = "PK\x06\x06"
+sizeEndCentDir64 = struct.calcsize(structEndArchive64)
+
+_CD64_SIGNATURE = 0
+_CD64_DIRECTORY_RECSIZE = 1
+_CD64_CREATE_VERSION = 2
+_CD64_EXTRACT_VERSION = 3
+_CD64_DISK_NUMBER = 4
+_CD64_DISK_NUMBER_START = 5
+_CD64_NUMBER_ENTRIES_THIS_DISK = 6
+_CD64_NUMBER_ENTRIES_TOTAL = 7
+_CD64_DIRECTORY_SIZE = 8
+_CD64_OFFSET_START_CENTDIR = 9
+
+def _check_zipfile(fp):
+    try:
+        if _EndRecData(fp):
+            return True         # file has correct magic number
+    except IOError:
+        pass
+    return False
+
+def is_zipfile(filename):
+    """Quickly see if a file is a ZIP file by checking the magic number.
+
+    The filename argument may be a file or file-like object too.
+    """
+    result = False
+    try:
+        if hasattr(filename, "read"):
+            result = _check_zipfile(fp=filename)
+        else:
+            with open(filename, "rb") as fp:
+                result = _check_zipfile(fp)
+    except IOError:
+        pass
+    return result
+
+def _EndRecData64(fpin, offset, endrec):
+    """
+    Read the ZIP64 end-of-archive records and use that to update endrec
+    """
+    try:
+        fpin.seek(offset - sizeEndCentDir64Locator, 2)
+    except IOError:
+        # If the seek fails, the file is not large enough to contain a ZIP64
+        # end-of-archive record, so just return the end record we were given.
+        return endrec
+
+    data = fpin.read(sizeEndCentDir64Locator)
+    if len(data) != sizeEndCentDir64Locator:
+        return endrec
+    sig, diskno, reloff, disks = struct.unpack(structEndArchive64Locator, data)
+    if sig != stringEndArchive64Locator:
+        return endrec
+
+    if diskno != 0 or disks != 1:
+        raise BadZipfile("zipfiles that span multiple disks are not supported")
+
+    # Assume no 'zip64 extensible data'
+    fpin.seek(offset - sizeEndCentDir64Locator - sizeEndCentDir64, 2)
+    data = fpin.read(sizeEndCentDir64)
+    if len(data) != sizeEndCentDir64:
+        return endrec
+    sig, sz, create_version, read_version, disk_num, disk_dir, \
+            dircount, dircount2, dirsize, diroffset = \
+            struct.unpack(structEndArchive64, data)
+    if sig != stringEndArchive64:
+        return endrec
+
+    # Update the original endrec using data from the ZIP64 record
+    endrec[_ECD_SIGNATURE] = sig
+    endrec[_ECD_DISK_NUMBER] = disk_num
+    endrec[_ECD_DISK_START] = disk_dir
+    endrec[_ECD_ENTRIES_THIS_DISK] = dircount
+    endrec[_ECD_ENTRIES_TOTAL] = dircount2
+    endrec[_ECD_SIZE] = dirsize
+    endrec[_ECD_OFFSET] = diroffset
+    return endrec
+
+
+def _EndRecData(fpin):
+    """Return data from the "End of Central Directory" record, or None.
+
+    The data is a list of the nine items in the ZIP "End of central dir"
+    record followed by a tenth item, the file seek offset of this record."""
+
+    # Determine file size
+    fpin.seek(0, 2)
+    filesize = fpin.tell()
+
+    # Check to see if this is ZIP file with no archive comment (the
+    # "end of central directory" structure should be the last item in the
+    # file if this is the case).
+    try:
+        fpin.seek(-sizeEndCentDir, 2)
+    except IOError:
+        return None
+    data = fpin.read()
+    if (len(data) == sizeEndCentDir and
+        data[0:4] == stringEndArchive and
+        data[-2:] == b"\000\000"):
+        # the signature is correct and there's no comment, unpack structure
+        endrec = struct.unpack(structEndArchive, data)
+        endrec=list(endrec)
+
+        # Append a blank comment and record start offset
+        endrec.append("")
+        endrec.append(filesize - sizeEndCentDir)
+
+        # Try to read the "Zip64 end of central directory" structure
+        return _EndRecData64(fpin, -sizeEndCentDir, endrec)
+
+    # Either this is not a ZIP file, or it is a ZIP file with an archive
+    # comment.  Search the end of the file for the "end of central directory"
+    # record signature. The comment is the last item in the ZIP file and may be
+    # up to 64K long.  It is assumed that the "end of central directory" magic
+    # number does not appear in the comment.
+    maxCommentStart = max(filesize - (1 << 16) - sizeEndCentDir, 0)
+    fpin.seek(maxCommentStart, 0)
+    data = fpin.read()
+    start = data.rfind(stringEndArchive)
+    if start >= 0:
+        # found the magic number; attempt to unpack and interpret
+        recData = data[start:start+sizeEndCentDir]
+        if len(recData) != sizeEndCentDir:
+            # Zip file is corrupted.
+            return None
+        endrec = list(struct.unpack(structEndArchive, recData))
+        commentSize = endrec[_ECD_COMMENT_SIZE] #as claimed by the zip file
+        comment = data[start+sizeEndCentDir:start+sizeEndCentDir+commentSize]
+        endrec.append(comment)
+        endrec.append(maxCommentStart + start)
+
+        # Try to read the "Zip64 end of central directory" structure
+        return _EndRecData64(fpin, maxCommentStart + start - filesize,
+                             endrec)
+
+    # Unable to find a valid end of central directory structure
+    return None
+
+
+class ZipInfo (object):
+    """Class with attributes describing each file in the ZIP archive."""
+
+    __slots__ = (
+            'orig_filename',
+            'filename',
+            'date_time',
+            'compress_type',
+            'comment',
+            'extra',
+            'create_system',
+            'create_version',
+            'extract_version',
+            'reserved',
+            'flag_bits',
+            'volume',
+            'internal_attr',
+            'external_attr',
+            'header_offset',
+            'CRC',
+            'compress_size',
+            'file_size',
+            '_raw_time',
+        )
+
+    def __init__(self, filename="NoName", date_time=(1980,1,1,0,0,0)):
+        self.orig_filename = filename   # Original file name in archive
+
+        # Terminate the file name at the first null byte.  Null bytes in file
+        # names are used as tricks by viruses in archives.
+        null_byte = filename.find(chr(0))
+        if null_byte >= 0:
+            filename = filename[0:null_byte]
+        # This is used to ensure paths in generated ZIP files always use
+        # forward slashes as the directory separator, as required by the
+        # ZIP format specification.
+        if os.sep != "/" and os.sep in filename:
+            filename = filename.replace(os.sep, "/")
+
+        self.filename = filename        # Normalized file name
+        self.date_time = date_time      # year, month, day, hour, min, sec
+
+        if date_time[0] < 1980:
+            raise ValueError('ZIP does not support timestamps before 1980')
+
+        # Standard values:
+        self.compress_type = ZIP_STORED # Type of compression for the file
+        self.comment = ""               # Comment for each file
+        self.extra = ""                 # ZIP extra data
+        if sys.platform == 'win32':
+            self.create_system = 0          # System which created ZIP archive
+        else:
+            # Assume everything else is unix-y
+            self.create_system = 3          # System which created ZIP archive
+        self.create_version = 20        # Version which created ZIP archive
+        self.extract_version = 20       # Version needed to extract archive
+        self.reserved = 0               # Must be zero
+        self.flag_bits = 0              # ZIP flag bits
+        self.volume = 0                 # Volume number of file header
+        self.internal_attr = 0          # Internal attributes
+        self.external_attr = 0          # External file attributes
+        # Other attributes are set by class ZipFile:
+        # header_offset         Byte offset to the file header
+        # CRC                   CRC-32 of the uncompressed file
+        # compress_size         Size of the compressed file
+        # file_size             Size of the uncompressed file
+
+    def FileHeader(self, zip64=None):
+        """Return the per-file header as a string."""
+        dt = self.date_time
+        dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
+        dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
+        if self.flag_bits & 0x08:
+            # Set these to zero because we write them after the file data
+            CRC = compress_size = file_size = 0
+        else:
+            CRC = self.CRC
+            compress_size = self.compress_size
+            file_size = self.file_size
+
+        extra = self.extra
+
+        if zip64 is None:
+            zip64 = file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT
+        if zip64:
+            fmt = '<HHQQ'
+            extra = extra + struct.pack(fmt,
+                    1, struct.calcsize(fmt)-4, file_size, compress_size)
+        if file_size > ZIP64_LIMIT or compress_size > ZIP64_LIMIT:
+            if not zip64:
+                raise LargeZipFile("Filesize would require ZIP64 extensions")
+            # File is larger than what fits into a 4 byte integer,
+            # fall back to the ZIP64 extension
+            file_size = 0xffffffff
+            compress_size = 0xffffffff
+            self.extract_version = max(45, self.extract_version)
+            self.create_version = max(45, self.extract_version)
+
+        filename, flag_bits = self._encodeFilenameFlags()
+        header = struct.pack(structFileHeader, stringFileHeader,
+                 self.extract_version, self.reserved, flag_bits,
+                 self.compress_type, dostime, dosdate, CRC,
+                 compress_size, file_size,
+                 len(filename), len(extra))
+        return header + filename + extra
+
+    def _encodeFilenameFlags(self):
+        if isinstance(self.filename, unicode):
+            try:
+                return self.filename.encode('ascii'), self.flag_bits
+            except UnicodeEncodeError:
+                return self.filename.encode('utf-8'), self.flag_bits | 0x800
+        else:
+            return self.filename, self.flag_bits
+
+    def _decodeFilename(self):
+        if self.flag_bits & 0x800:
+            return self.filename.decode('utf-8')
+        else:
+            return self.filename
+
+    def _decodeExtra(self):
+        # Try to decode the extra field.
+        extra = self.extra
+        unpack = struct.unpack
+        while len(extra) >= 4:
+            tp, ln = unpack('<HH', extra[:4])
+            if tp == 1:
+                if ln >= 24:
+                    counts = unpack('<QQQ', extra[4:28])
+                elif ln == 16:
+                    counts = unpack('<QQ', extra[4:20])
+                elif ln == 8:
+                    counts = unpack('<Q', extra[4:12])
+                elif ln == 0:
+                    counts = ()
+                else:
+                    raise RuntimeError, "Corrupt extra field %s"%(ln,)
+
+                idx = 0
+
+                # ZIP64 extension (large files and/or large archives)
+                if self.file_size in (0xffffffffffffffffL, 0xffffffffL):
+                    self.file_size = counts[idx]
+                    idx += 1
+
+                if self.compress_size == 0xFFFFFFFFL:
+                    self.compress_size = counts[idx]
+                    idx += 1
+
+                if self.header_offset == 0xffffffffL:
+                    old = self.header_offset
+                    self.header_offset = counts[idx]
+                    idx+=1
+
+            extra = extra[ln+4:]
+
+
+class _ZipDecrypter:
+    """Class to handle decryption of files stored within a ZIP archive.
+
+    ZIP supports a password-based form of encryption. Even though known
+    plaintext attacks have been found against it, it is still useful
+    to be able to get data out of such a file.
+
+    Usage:
+        zd = _ZipDecrypter(mypwd)
+        plain_char = zd(cypher_char)
+        plain_text = map(zd, cypher_text)
+    """
+
+    def _GenerateCRCTable():
+        """Generate a CRC-32 table.
+
+        ZIP encryption uses the CRC32 one-byte primitive for scrambling some
+        internal keys. We noticed that a direct implementation is faster than
+        relying on binascii.crc32().
+        """
+        poly = 0xedb88320
+        table = [0] * 256
+        for i in range(256):
+            crc = i
+            for j in range(8):
+                if crc & 1:
+                    crc = ((crc >> 1) & 0x7FFFFFFF) ^ poly
+                else:
+                    crc = ((crc >> 1) & 0x7FFFFFFF)
+            table[i] = crc
+        return table
+    crctable = _GenerateCRCTable()
+
+    def _crc32(self, ch, crc):
+        """Compute the CRC32 primitive on one byte."""
+        return ((crc >> 8) & 0xffffff) ^ self.crctable[(crc ^ ord(ch)) & 0xff]
+
+    def __init__(self, pwd):
+        self.key0 = 305419896
+        self.key1 = 591751049
+        self.key2 = 878082192
+        for p in pwd:
+            self._UpdateKeys(p)
+
+    def _UpdateKeys(self, c):
+        self.key0 = self._crc32(c, self.key0)
+        self.key1 = (self.key1 + (self.key0 & 255)) & 4294967295
+        self.key1 = (self.key1 * 134775813 + 1) & 4294967295
+        self.key2 = self._crc32(chr((self.key1 >> 24) & 255), self.key2)
+
+    def __call__(self, c):
+        """Decrypt a single character."""
+        c = ord(c)
+        k = self.key2 | 2
+        c = c ^ (((k * (k^1)) >> 8) & 255)
+        c = chr(c)
+        self._UpdateKeys(c)
+        return c
+
+
+compressor_names = {
+    0: 'store',
+    1: 'shrink',
+    2: 'reduce',
+    3: 'reduce',
+    4: 'reduce',
+    5: 'reduce',
+    6: 'implode',
+    7: 'tokenize',
+    8: 'deflate',
+    9: 'deflate64',
+    10: 'implode',
+    12: 'bzip2',
+    14: 'lzma',
+    18: 'terse',
+    19: 'lz77',
+    97: 'wavpack',
+    98: 'ppmd',
+}
+
+
+class ZipExtFile(io.BufferedIOBase):
+    """File-like object for reading an archive member.
+       Is returned by ZipFile.open().
+    """
+
+    # Max size supported by decompressor.
+    MAX_N = 1 << 31 - 1
+
+    # Read from compressed files in 4k blocks.
+    MIN_READ_SIZE = 4096
+
+    # Search for universal newlines or line chunks.
+    PATTERN = re.compile(r'^(?P<chunk>[^\r\n]+)|(?P<newline>\n|\r\n?)')
+
+    def __init__(self, fileobj, mode, zipinfo, decrypter=None,
+            close_fileobj=False):
+        self._fileobj = fileobj
+        self._decrypter = decrypter
+        self._close_fileobj = close_fileobj
+
+        self._compress_type = zipinfo.compress_type
+        self._compress_size = zipinfo.compress_size
+        self._compress_left = zipinfo.compress_size
+
+        if self._compress_type == ZIP_DEFLATED:
+            self._decompressor = zlib.decompressobj(-15)
+        elif self._compress_type != ZIP_STORED:
+            descr = compressor_names.get(self._compress_type)
+            if descr:
+                raise NotImplementedError("compression type %d (%s)" % (self._compress_type, descr))
+            else:
+                raise NotImplementedError("compression type %d" % (self._compress_type,))
+        self._unconsumed = ''
+
+        self._readbuffer = ''
+        self._offset = 0
+
+        self._universal = 'U' in mode
+        self.newlines = None
+
+        # Adjust read size for encrypted files since the first 12 bytes
+        # are for the encryption/password information.
+        if self._decrypter is not None:
+            self._compress_left -= 12
+
+        self.mode = mode
+        self.name = zipinfo.filename
+
+        if hasattr(zipinfo, 'CRC'):
+            self._expected_crc = zipinfo.CRC
+            self._running_crc = crc32(b'') & 0xffffffff
+        else:
+            self._expected_crc = None
+
+    def readline(self, limit=-1):
+        """Read and return a line from the stream.
+
+        If limit is specified, at most limit bytes will be read.
+        """
+
+        if not self._universal and limit < 0:
+            # Shortcut common case - newline found in buffer.
+            i = self._readbuffer.find('\n', self._offset) + 1
+            if i > 0:
+                line = self._readbuffer[self._offset: i]
+                self._offset = i
+                return line
+
+        if not self._universal:
+            return io.BufferedIOBase.readline(self, limit)
+
+        line = ''
+        while limit < 0 or len(line) < limit:
+            readahead = self.peek(2)
+            if readahead == '':
+                return line
+
+            #
+            # Search for universal newlines or line chunks.
+            #
+            # The pattern returns either a line chunk or a newline, but not
+            # both. Combined with peek(2), we are assured that the sequence
+            # '\r\n' is always retrieved completely and never split into
+            # separate newlines - '\r', '\n' due to coincidental readaheads.
+            #
+            match = self.PATTERN.search(readahead)
+            newline = match.group('newline')
+            if newline is not None:
+                if self.newlines is None:
+                    self.newlines = []
+                if newline not in self.newlines:
+                    self.newlines.append(newline)
+                self._offset += len(newline)
+                return line + '\n'
+
+            chunk = match.group('chunk')
+            if limit >= 0:
+                chunk = chunk[: limit - len(line)]
+
+            self._offset += len(chunk)
+            line += chunk
+
+        return line
+
+    def peek(self, n=1):
+        """Returns buffered bytes without advancing the position."""
+        if n > len(self._readbuffer) - self._offset:
+            chunk = self.read(n)
+            if len(chunk) > self._offset:
+                self._readbuffer = chunk + self._readbuffer[self._offset:]
+                self._offset = 0
+            else:
+                self._offset -= len(chunk)
+
+        # Return up to 512 bytes to reduce allocation overhead for tight loops.
+        return self._readbuffer[self._offset: self._offset + 512]
+
+    def readable(self):
+        return True
+
+    def read(self, n=-1):
+        """Read and return up to n bytes.
+        If the argument is omitted, None, or negative, data is read and returned until EOF is reached..
+        """
+        buf = ''
+        if n is None:
+            n = -1
+        while True:
+            if n < 0:
+                data = self.read1(n)
+            elif n > len(buf):
+                data = self.read1(n - len(buf))
+            else:
+                return buf
+            if len(data) == 0:
+                return buf
+            buf += data
+
+    def _update_crc(self, newdata, eof):
+        # Update the CRC using the given data.
+        if self._expected_crc is None:
+            # No need to compute the CRC if we don't have a reference value
+            return
+        self._running_crc = crc32(newdata, self._running_crc) & 0xffffffff
+        # Check the CRC if we're at the end of the file
+        if eof and self._running_crc != self._expected_crc:
+            raise BadZipfile("Bad CRC-32 for file %r" % self.name)
+
+    def read1(self, n):
+        """Read up to n bytes with at most one read() system call."""
+
+        # Simplify algorithm (branching) by transforming negative n to large n.
+        if n < 0 or n is None:
+            n = self.MAX_N
+
+        # Bytes available in read buffer.
+        len_readbuffer = len(self._readbuffer) - self._offset
+
+        # Read from file.
+        if self._compress_left > 0 and n > len_readbuffer + len(self._unconsumed):
+            nbytes = n - len_readbuffer - len(self._unconsumed)
+            nbytes = max(nbytes, self.MIN_READ_SIZE)
+            nbytes = min(nbytes, self._compress_left)
+
+            data = self._fileobj.read(nbytes)
+            self._compress_left -= len(data)
+
+            if data and self._decrypter is not None:
+                data = ''.join(map(self._decrypter, data))
+
+            if self._compress_type == ZIP_STORED:
+                self._update_crc(data, eof=(self._compress_left==0))
+                self._readbuffer = self._readbuffer[self._offset:] + data
+                self._offset = 0
+            else:
+                # Prepare deflated bytes for decompression.
+                self._unconsumed += data
+
+        # Handle unconsumed data.
+        if (len(self._unconsumed) > 0 and n > len_readbuffer and
+            self._compress_type == ZIP_DEFLATED):
+            data = self._decompressor.decompress(
+                self._unconsumed,
+                max(n - len_readbuffer, self.MIN_READ_SIZE)
+            )
+
+            self._unconsumed = self._decompressor.unconsumed_tail
+            eof = len(self._unconsumed) == 0 and self._compress_left == 0
+            if eof:
+                data += self._decompressor.flush()
+
+            self._update_crc(data, eof=eof)
+            self._readbuffer = self._readbuffer[self._offset:] + data
+            self._offset = 0
+
+        # Read from buffer.
+        data = self._readbuffer[self._offset: self._offset + n]
+        self._offset += len(data)
+        return data
+
+    def close(self):
+        try :
+            if self._close_fileobj:
+                self._fileobj.close()
+        finally:
+            super(ZipExtFile, self).close()
+
+
+class ZipFile(object):
+    """ Class with methods to open, read, write, close, list zip files.
+
+    z = ZipFile(file, mode="r", compression=ZIP_STORED, allowZip64=False)
+
+    file: Either the path to the file, or a file-like object.
+          If it is a path, the file will be opened and closed by ZipFile.
+    mode: The mode can be either read "r", write "w" or append "a".
+    compression: ZIP_STORED (no compression) or ZIP_DEFLATED (requires zlib).
+    allowZip64: if True ZipFile will create files with ZIP64 extensions when
+                needed, otherwise it will raise an exception when this would
+                be necessary.
+
+    """
+
+    fp = None                   # Set here since __del__ checks it
+
+    def __init__(self, file, mode="r", compression=ZIP_STORED, allowZip64=False):
+        """Open the ZIP file with mode read "r", write "w" or append "a"."""
+        if mode not in ("r", "w", "a"):
+            raise RuntimeError('ZipFile() requires mode "r", "w", or "a"')
+
+        if compression == ZIP_STORED:
+            pass
+        elif compression == ZIP_DEFLATED:
+            if not zlib:
+                raise RuntimeError,\
+                      "Compression requires the (missing) zlib module"
+        else:
+            raise RuntimeError, "That compression method is not supported"
+
+        self._allowZip64 = allowZip64
+        self._didModify = False
+        self.debug = 0  # Level of printing: 0 through 3
+        self.NameToInfo = {}    # Find file info given name
+        self.filelist = []      # List of ZipInfo instances for archive
+        self.compression = compression  # Method of compression
+        self.mode = key = mode.replace('b', '')[0]
+        self.pwd = None
+        self._comment = ''
+
+        # Check if we were passed a file-like object
+        if isinstance(file, basestring):
+            self._filePassed = 0
+            self.filename = file
+            modeDict = {'r' : 'rb', 'w': 'wb', 'a' : 'r+b'}
+            try:
+                self.fp = open(file, modeDict[mode])
+            except IOError:
+                if mode == 'a':
+                    mode = key = 'w'
+                    self.fp = open(file, modeDict[mode])
+                else:
+                    raise
+        else:
+            self._filePassed = 1
+            self.fp = file
+            self.filename = getattr(file, 'name', None)
+
+        try:
+            if key == 'r':
+                self._RealGetContents()
+            elif key == 'w':
+                # set the modified flag so central directory gets written
+                # even if no files are added to the archive
+                self._didModify = True
+                self._start_disk = self.fp.tell()
+            elif key == 'a':
+                try:
+                    # See if file is a zip file
+                    self._RealGetContents()
+                    # seek to start of directory and overwrite
+                    self.fp.seek(self.start_dir, 0)
+                except BadZipfile:
+                    # file is not a zip file, just append
+                    self.fp.seek(0, 2)
+
+                    # set the modified flag so central directory gets written
+                    # even if no files are added to the archive
+                    self._didModify = True
+                    self._start_disk = self.fp.tell()
+            else:
+                raise RuntimeError('Mode must be "r", "w" or "a"')
+        except:
+            fp = self.fp
+            self.fp = None
+            if not self._filePassed:
+                fp.close()
+            raise
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, type, value, traceback):
+        self.close()
+
+    def _RealGetContents(self):
+        """Read in the table of contents for the ZIP file."""
+        fp = self.fp
+        try:
+            endrec = _EndRecData(fp)
+        except IOError:
+            raise BadZipfile("File is not a zip file")
+        if not endrec:
+            raise BadZipfile, "File is not a zip file"
+        if self.debug > 1:
+            print endrec
+        size_cd = endrec[_ECD_SIZE]             # bytes in central directory
+        offset_cd = endrec[_ECD_OFFSET]         # offset of central directory
+        self._comment = endrec[_ECD_COMMENT]    # archive comment
+
+        # self._start_disk:  Position of the start of ZIP archive
+        # It is zero, unless ZIP was concatenated to another file
+        self._start_disk = endrec[_ECD_LOCATION] - size_cd - offset_cd
+        if endrec[_ECD_SIGNATURE] == stringEndArchive64:
+            # If Zip64 extension structures are present, account for them
+            self._start_disk -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
+
+        if self.debug > 2:
+            inferred = self._start_disk + offset_cd
+            print "given, inferred, offset", offset_cd, inferred, self._start_disk
+        # self.start_dir:  Position of start of central directory
+        self.start_dir = offset_cd + self._start_disk
+        fp.seek(self.start_dir, 0)
+        data = fp.read(size_cd)
+        fp = cStringIO.StringIO(data)
+        total = 0
+        while total < size_cd:
+            centdir = fp.read(sizeCentralDir)
+            if len(centdir) != sizeCentralDir:
+                raise BadZipfile("Truncated central directory")
+            centdir = struct.unpack(structCentralDir, centdir)
+            if centdir[_CD_SIGNATURE] != stringCentralDir:
+                raise BadZipfile("Bad magic number for central directory")
+            if self.debug > 2:
+                print centdir
+            filename = fp.read(centdir[_CD_FILENAME_LENGTH])
+            # Create ZipInfo instance to store file information
+            x = ZipInfo(filename)
+            x.extra = fp.read(centdir[_CD_EXTRA_FIELD_LENGTH])
+            x.comment = fp.read(centdir[_CD_COMMENT_LENGTH])
+            x.header_offset = centdir[_CD_LOCAL_HEADER_OFFSET]
+            (x.create_version, x.create_system, x.extract_version, x.reserved,
+                x.flag_bits, x.compress_type, t, d,
+                x.CRC, x.compress_size, x.file_size) = centdir[1:12]
+            x.volume, x.internal_attr, x.external_attr = centdir[15:18]
+            # Convert date/time code to (year, month, day, hour, min, sec)
+            x._raw_time = t
+            x.date_time = ( (d>>9)+1980, (d>>5)&0xF, d&0x1F,
+                                     t>>11, (t>>5)&0x3F, (t&0x1F) * 2 )
+
+            x._decodeExtra()
+            x.header_offset = x.header_offset + self._start_disk
+            x.filename = x._decodeFilename()
+            self.filelist.append(x)
+            self.NameToInfo[x.filename] = x
+
+            # update total bytes read from central directory
+            total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH]
+                     + centdir[_CD_EXTRA_FIELD_LENGTH]
+                     + centdir[_CD_COMMENT_LENGTH])
+
+            if self.debug > 2:
+                print "total", total
+
+
+    def namelist(self):
+        """Return a list of file names in the archive."""
+        l = []
+        for data in self.filelist:
+            l.append(data.filename)
+        return l
+
+    def infolist(self):
+        """Return a list of class ZipInfo instances for files in the
+        archive."""
+        return self.filelist
+
+    def printdir(self):
+        """Print a table of contents for the zip file."""
+        print "%-46s %19s %12s" % ("File Name", "Modified    ", "Size")
+        for zinfo in self.filelist:
+            date = "%d-%02d-%02d %02d:%02d:%02d" % zinfo.date_time[:6]
+            print "%-46s %s %12d" % (zinfo.filename, date, zinfo.file_size)
+
+    def testzip(self):
+        """Read all the files and check the CRC."""
+        chunk_size = 2 ** 20
+        for zinfo in self.filelist:
+            try:
+                # Read by chunks, to avoid an OverflowError or a
+                # MemoryError with very large embedded files.
+                with self.open(zinfo.filename, "r") as f:
+                    while f.read(chunk_size):     # Check CRC-32
+                        pass
+            except BadZipfile:
+                return zinfo.filename
+
+    def getinfo(self, name):
+        """Return the instance of ZipInfo given 'name'."""
+        info = self.NameToInfo.get(name)
+        if info is None:
+            raise KeyError(
+                'There is no item named %r in the archive' % name)
+
+        return info
+
+    def setpassword(self, pwd):
+        """Set default password for encrypted files."""
+        self.pwd = pwd
+
+    @property
+    def comment(self):
+        """The comment text associated with the ZIP file."""
+        return self._comment
+
+    @comment.setter
+    def comment(self, comment):
+        # check for valid comment length
+        if len(comment) > ZIP_MAX_COMMENT:
+            import warnings
+            warnings.warn('Archive comment is too long; truncating to %d bytes'
+                          % ZIP_MAX_COMMENT, stacklevel=2)
+            comment = comment[:ZIP_MAX_COMMENT]
+        self._comment = comment
+        self._didModify = True
+
+    def read(self, name, pwd=None):
+        """Return file bytes (as a string) for name."""
+        return self.open(name, "r", pwd).read()
+
+    def open(self, name, mode="r", pwd=None):
+        """Return file-like object for 'name'."""
+        if mode not in ("r", "U", "rU"):
+            raise RuntimeError, 'open() requires mode "r", "U", or "rU"'
+        if not self.fp:
+            raise RuntimeError, \
+                  "Attempt to read ZIP archive that was already closed"
+
+        # Only open a new file for instances where we were not
+        # given a file object in the constructor
+        if self._filePassed:
+            zef_file = self.fp
+            should_close = False
+        else:
+            zef_file = open(self.filename, 'rb')
+            should_close = True
+
+        try:
+            # Make sure we have an info object
+            if isinstance(name, ZipInfo):
+                # 'name' is already an info object
+                zinfo = name
+            else:
+                # Get info object for name
+                zinfo = self.getinfo(name)
+
+            zef_file.seek(zinfo.header_offset, 0)
+
+            # Skip the file header:
+            fheader = zef_file.read(sizeFileHeader)
+            if len(fheader) != sizeFileHeader:
+                raise BadZipfile("Truncated file header")
+            fheader = struct.unpack(structFileHeader, fheader)
+            if fheader[_FH_SIGNATURE] != stringFileHeader:
+                raise BadZipfile("Bad magic number for file header")
+
+            fname = zef_file.read(fheader[_FH_FILENAME_LENGTH])
+            if fheader[_FH_EXTRA_FIELD_LENGTH]:
+                zef_file.read(fheader[_FH_EXTRA_FIELD_LENGTH])
+
+            if fname != zinfo.orig_filename:
+                raise BadZipfile, \
+                        'File name in directory "%s" and header "%s" differ.' % (
+                            zinfo.orig_filename, fname)
+
+            # check for encrypted flag & handle password
+            is_encrypted = zinfo.flag_bits & 0x1
+            zd = None
+            if is_encrypted:
+                if not pwd:
+                    pwd = self.pwd
+                if not pwd:
+                    raise RuntimeError, "File %s is encrypted, " \
+                        "password required for extraction" % name
+
+                zd = _ZipDecrypter(pwd)
+                # The first 12 bytes in the cypher stream is an encryption header
+                #  used to strengthen the algorithm. The first 11 bytes are
+                #  completely random, while the 12th contains the MSB of the CRC,
+                #  or the MSB of the file time depending on the header type
+                #  and is used to check the correctness of the password.
+                bytes = zef_file.read(12)
+                h = map(zd, bytes[0:12])
+                if zinfo.flag_bits & 0x8:
+                    # compare against the file type from extended local headers
+                    check_byte = (zinfo._raw_time >> 8) & 0xff
+                else:
+                    # compare against the CRC otherwise
+                    check_byte = (zinfo.CRC >> 24) & 0xff
+                if ord(h[11]) != check_byte:
+                    raise RuntimeError("Bad password for file", name)
+
+            return ZipExtFile(zef_file, mode, zinfo, zd,
+                    close_fileobj=should_close)
+        except:
+            if should_close:
+                zef_file.close()
+            raise
+
+    def extract(self, member, path=None, pwd=None):
+        """Extract a member from the archive to the current working directory,
+           using its full name. Its file information is extracted as accurately
+           as possible. `member' may be a filename or a ZipInfo object. You can
+           specify a different directory using `path'.
+        """
+        if not isinstance(member, ZipInfo):
+            member = self.getinfo(member)
+
+        if path is None:
+            path = os.getcwd()
+
+        return self._extract_member(member, path, pwd)
+
+    def extractall(self, path=None, members=None, pwd=None):
+        """Extract all members from the archive to the current working
+           directory. `path' specifies a different directory to extract to.
+           `members' is optional and must be a subset of the list returned
+           by namelist().
+        """
+        if members is None:
+            members = self.namelist()
+
+        for zipinfo in members:
+            self.extract(zipinfo, path, pwd)
+
+    def _extract_member(self, member, targetpath, pwd):
+        """Extract the ZipInfo object 'member' to a physical
+           file on the path targetpath.
+        """
+        # build the destination pathname, replacing
+        # forward slashes to platform specific separators.
+        arcname = member.filename.replace('/', os.path.sep)
+
+        if os.path.altsep:
+            arcname = arcname.replace(os.path.altsep, os.path.sep)
+        # interpret absolute pathname as relative, remove drive letter or
+        # UNC path, redundant separators, "." and ".." components.
+        arcname = os.path.splitdrive(arcname)[1]
+        arcname = os.path.sep.join(x for x in arcname.split(os.path.sep)
+                    if x not in ('', os.path.curdir, os.path.pardir))
+        if os.path.sep == '\\':
+            # filter illegal characters on Windows
+            illegal = ':<>|"?*'
+            if isinstance(arcname, unicode):
+                table = {ord(c): ord('_') for c in illegal}
+            else:
+                table = string.maketrans(illegal, '_' * len(illegal))
+            arcname = arcname.translate(table)
+            # remove trailing dots
+            arcname = (x.rstrip('.') for x in arcname.split(os.path.sep))
+            arcname = os.path.sep.join(x for x in arcname if x)
+
+        targetpath = os.path.join(targetpath, arcname)
+        targetpath = os.path.normpath(targetpath)
+
+        # Create all upper directories if necessary.
+        upperdirs = os.path.dirname(targetpath)
+        if upperdirs and not os.path.exists(upperdirs):
+            os.makedirs(upperdirs)
+
+        if member.filename[-1] == '/':
+            if not os.path.isdir(targetpath):
+                os.mkdir(targetpath)
+            return targetpath
+
+        with self.open(member, pwd=pwd) as source, \
+             file(targetpath, "wb") as target:
+            shutil.copyfileobj(source, target)
+
+        return targetpath
+
+    def _writecheck(self, zinfo):
+        """Check for errors before writing a file to the archive."""
+        if zinfo.filename in self.NameToInfo:
+            import warnings
+            warnings.warn('Duplicate name: %r' % zinfo.filename, stacklevel=3)
+        if self.mode not in ("w", "a"):
+            raise RuntimeError, 'write() requires mode "w" or "a"'
+        if not self.fp:
+            raise RuntimeError, \
+                  "Attempt to write ZIP archive that was already closed"
+        if zinfo.compress_type == ZIP_DEFLATED and not zlib:
+            raise RuntimeError, \
+                  "Compression requires the (missing) zlib module"
+        if zinfo.compress_type not in (ZIP_STORED, ZIP_DEFLATED):
+            raise RuntimeError, \
+                  "That compression method is not supported"
+        if not self._allowZip64:
+            requires_zip64 = None
+            if len(self.filelist) >= ZIP_FILECOUNT_LIMIT:
+                requires_zip64 = "Files count"
+            elif zinfo.file_size > ZIP64_LIMIT:
+                requires_zip64 = "Filesize"
+            elif zinfo.header_offset > ZIP64_LIMIT:
+                requires_zip64 = "Zipfile size"
+            if requires_zip64:
+                raise LargeZipFile(requires_zip64 +
+                                   " would require ZIP64 extensions")
+
+    def write(self, filename, arcname=None, compress_type=None):
+        """Put the bytes from filename into the archive under the name
+        arcname."""
+        if not self.fp:
+            raise RuntimeError(
+                  "Attempt to write to ZIP archive that was already closed")
+
+        st = os.stat(filename)
+        isdir = stat.S_ISDIR(st.st_mode)
+        mtime = time.localtime(st.st_mtime)
+        date_time = mtime[0:6]
+        # Create ZipInfo instance to store file information
+        if arcname is None:
+            arcname = filename
+        arcname = os.path.normpath(os.path.splitdrive(arcname)[1])
+        while arcname[0] in (os.sep, os.altsep):
+            arcname = arcname[1:]
+        if isdir:
+            arcname += '/'
+        zinfo = ZipInfo(arcname, date_time)
+        zinfo.external_attr = (st[0] & 0xFFFF) << 16L      # Unix attributes
+        if isdir:
+            zinfo.compress_type = ZIP_STORED
+        elif compress_type is None:
+            zinfo.compress_type = self.compression
+        else:
+            zinfo.compress_type = compress_type
+
+        zinfo.file_size = st.st_size
+        zinfo.flag_bits = 0x00
+        zinfo.header_offset = self.fp.tell()    # Start of header bytes
+
+        self._writecheck(zinfo)
+        self._didModify = True
+
+        if isdir:
+            zinfo.file_size = 0
+            zinfo.compress_size = 0
+            zinfo.CRC = 0
+            zinfo.external_attr |= 0x10  # MS-DOS directory flag
+            self.filelist.append(zinfo)
+            self.NameToInfo[zinfo.filename] = zinfo
+            self.fp.write(zinfo.FileHeader(False))
+            return
+
+        with open(filename, "rb") as fp:
+            # Must overwrite CRC and sizes with correct data later
+            zinfo.CRC = CRC = 0
+            zinfo.compress_size = compress_size = 0
+            # Compressed size can be larger than uncompressed size
+            zip64 = self._allowZip64 and \
+                    zinfo.file_size * 1.05 > ZIP64_LIMIT
+            self.fp.write(zinfo.FileHeader(zip64))
+            if zinfo.compress_type == ZIP_DEFLATED:
+                cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
+                     zlib.DEFLATED, -15)
+            else:
+                cmpr = None
+            file_size = 0
+            while 1:
+                buf = fp.read(1024 * 8)
+                if not buf:
+                    break
+                file_size = file_size + len(buf)
+                CRC = crc32(buf, CRC) & 0xffffffff
+                if cmpr:
+                    buf = cmpr.compress(buf)
+                    compress_size = compress_size + len(buf)
+                self.fp.write(buf)
+        if cmpr:
+            buf = cmpr.flush()
+            compress_size = compress_size + len(buf)
+            self.fp.write(buf)
+            zinfo.compress_size = compress_size
+        else:
+            zinfo.compress_size = file_size
+        zinfo.CRC = CRC
+        zinfo.file_size = file_size
+        if not zip64 and self._allowZip64:
+            if file_size > ZIP64_LIMIT:
+                raise RuntimeError('File size has increased during compressing')
+            if compress_size > ZIP64_LIMIT:
+                raise RuntimeError('Compressed size larger than uncompressed size')
+        # Seek backwards and write file header (which will now include
+        # correct CRC and file sizes)
+        position = self.fp.tell() # Preserve current position in file
+        self.fp.seek(zinfo.header_offset, 0)
+        self.fp.write(zinfo.FileHeader(zip64))
+        self.fp.seek(position, 0)
+        self.filelist.append(zinfo)
+        self.NameToInfo[zinfo.filename] = zinfo
+
+    def writestr(self, zinfo_or_arcname, bytes, compress_type=None):
+        """Write a file into the archive.  The contents is the string
+        'bytes'.  'zinfo_or_arcname' is either a ZipInfo instance or
+        the name of the file in the archive."""
+        if not isinstance(zinfo_or_arcname, ZipInfo):
+            zinfo = ZipInfo(filename=zinfo_or_arcname,
+                            date_time=time.localtime(time.time())[:6])
+
+            zinfo.compress_type = self.compression
+            if zinfo.filename[-1] == '/':
+                zinfo.external_attr = 0o40775 << 16   # drwxrwxr-x
+                zinfo.external_attr |= 0x10           # MS-DOS directory flag
+            else:
+                zinfo.external_attr = 0o600 << 16     # ?rw-------
+        else:
+            zinfo = zinfo_or_arcname
+
+        if not self.fp:
+            raise RuntimeError(
+                  "Attempt to write to ZIP archive that was already closed")
+
+        if compress_type is not None:
+            zinfo.compress_type = compress_type
+
+        zinfo.file_size = len(bytes)            # Uncompressed size
+        zinfo.header_offset = self.fp.tell()    # Start of header bytes
+        self._writecheck(zinfo)
+        self._didModify = True
+        zinfo.CRC = crc32(bytes) & 0xffffffff       # CRC-32 checksum
+        if zinfo.compress_type == ZIP_DEFLATED:
+            co = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION,
+                 zlib.DEFLATED, -15)
+            bytes = co.compress(bytes) + co.flush()
+            zinfo.compress_size = len(bytes)    # Compressed size
+        else:
+            zinfo.compress_size = zinfo.file_size
+        zip64 = zinfo.file_size > ZIP64_LIMIT or \
+                zinfo.compress_size > ZIP64_LIMIT
+        if zip64 and not self._allowZip64:
+            raise LargeZipFile("Filesize would require ZIP64 extensions")
+        self.fp.write(zinfo.FileHeader(zip64))
+        self.fp.write(bytes)
+        if zinfo.flag_bits & 0x08:
+            # Write CRC and file sizes after the file data
+            fmt = '<LQQ' if zip64 else '<LLL'
+            self.fp.write(struct.pack(fmt, zinfo.CRC, zinfo.compress_size,
+                  zinfo.file_size))
+        self.fp.flush()
+        self.filelist.append(zinfo)
+        self.NameToInfo[zinfo.filename] = zinfo
+
+    def __del__(self):
+        """Call the "close()" method in case the user forgot."""
+        self.close()
+
+    def close(self):
+        """Close the file, and for mode "w" and "a" write the ending
+        records."""
+        if self.fp is None:
+            return
+
+        try:
+            if self.mode in ("w", "a") and self._didModify: # write ending records
+                pos1 = self.fp.tell()
+                for zinfo in self.filelist:         # write central directory
+                    dt = zinfo.date_time
+                    dosdate = (dt[0] - 1980) << 9 | dt[1] << 5 | dt[2]
+                    dostime = dt[3] << 11 | dt[4] << 5 | (dt[5] // 2)
+                    extra = []
+                    if zinfo.file_size > ZIP64_LIMIT \
+                            or zinfo.compress_size > ZIP64_LIMIT:
+                        extra.append(zinfo.file_size)
+                        extra.append(zinfo.compress_size)
+                        file_size = 0xffffffff
+                        compress_size = 0xffffffff
+                    else:
+                        file_size = zinfo.file_size
+                        compress_size = zinfo.compress_size
+
+                    header_offset = zinfo.header_offset - self._start_disk
+                    if header_offset > ZIP64_LIMIT:
+                        extra.append(header_offset)
+                        header_offset = 0xffffffffL
+
+                    extra_data = zinfo.extra
+                    if extra:
+                        # Append a ZIP64 field to the extra's
+                        extra_data = struct.pack(
+                                '<HH' + 'Q'*len(extra),
+                                1, 8*len(extra), *extra) + extra_data
+
+                        extract_version = max(45, zinfo.extract_version)
+                        create_version = max(45, zinfo.create_version)
+                    else:
+                        extract_version = zinfo.extract_version
+                        create_version = zinfo.create_version
+
+                    try:
+                        filename, flag_bits = zinfo._encodeFilenameFlags()
+                        centdir = struct.pack(structCentralDir,
+                        stringCentralDir, create_version,
+                        zinfo.create_system, extract_version, zinfo.reserved,
+                        flag_bits, zinfo.compress_type, dostime, dosdate,
+                        zinfo.CRC, compress_size, file_size,
+                        len(filename), len(extra_data), len(zinfo.comment),
+                        0, zinfo.internal_attr, zinfo.external_attr,
+                        header_offset)
+                    except DeprecationWarning:
+                        print >>sys.stderr, (structCentralDir,
+                        stringCentralDir, create_version,
+                        zinfo.create_system, extract_version, zinfo.reserved,
+                        zinfo.flag_bits, zinfo.compress_type, dostime, dosdate,
+                        zinfo.CRC, compress_size, file_size,
+                        len(zinfo.filename), len(extra_data), len(zinfo.comment),
+                        0, zinfo.internal_attr, zinfo.external_attr,
+                        header_offset)
+                        raise
+                    self.fp.write(centdir)
+                    self.fp.write(filename)
+                    self.fp.write(extra_data)
+                    self.fp.write(zinfo.comment)
+
+                pos2 = self.fp.tell()
+                # Write end-of-zip-archive record
+                centDirCount = len(self.filelist)
+                centDirSize = pos2 - pos1
+                centDirOffset = pos1 - self._start_disk
+                requires_zip64 = None
+                if centDirCount > ZIP_FILECOUNT_LIMIT:
+                    requires_zip64 = "Files count"
+                elif centDirOffset > ZIP64_LIMIT:
+                    requires_zip64 = "Central directory offset"
+                elif centDirSize > ZIP64_LIMIT:
+                    requires_zip64 = "Central directory size"
+                if requires_zip64:
+                    # Need to write the ZIP64 end-of-archive records
+                    if not self._allowZip64:
+                        raise LargeZipFile(requires_zip64 +
+                                           " would require ZIP64 extensions")
+                    zip64endrec = struct.pack(
+                            structEndArchive64, stringEndArchive64,
+                            44, 45, 45, 0, 0, centDirCount, centDirCount,
+                            centDirSize, centDirOffset)
+                    self.fp.write(zip64endrec)
+
+                    zip64locrec = struct.pack(
+                            structEndArchive64Locator,
+                            stringEndArchive64Locator, 0, pos2, 1)
+                    self.fp.write(zip64locrec)
+                    centDirCount = min(centDirCount, 0xFFFF)
+                    centDirSize = min(centDirSize, 0xFFFFFFFF)
+                    centDirOffset = min(centDirOffset, 0xFFFFFFFF)
+
+                endrec = struct.pack(structEndArchive, stringEndArchive,
+                                    0, 0, centDirCount, centDirCount,
+                                    centDirSize, centDirOffset, len(self._comment))
+                self.fp.write(endrec)
+                self.fp.write(self._comment)
+                self.fp.flush()
+        finally:
+            fp = self.fp
+            self.fp = None
+            if not self._filePassed:
+                fp.close()
+
+
+class PyZipFile(ZipFile):
+    """Class to create ZIP archives with Python library files and packages."""
+
+    def writepy(self, pathname, basename = ""):
+        """Add all files from "pathname" to the ZIP archive.
+
+        If pathname is a package directory, search the directory and
+        all package subdirectories recursively for all *.py and enter
+        the modules into the archive.  If pathname is a plain
+        directory, listdir *.py and enter all modules.  Else, pathname
+        must be a Python *.py file and the module will be put into the
+        archive.  Added modules are always module.pyo or module.pyc.
+        This method will compile the module.py into module.pyc if
+        necessary.
+        """
+        dir, name = os.path.split(pathname)
+        if os.path.isdir(pathname):
+            initname = os.path.join(pathname, "__init__.py")
+            if os.path.isfile(initname):
+                # This is a package directory, add it
+                if basename:
+                    basename = "%s/%s" % (basename, name)
+                else:
+                    basename = name
+                if self.debug:
+                    print "Adding package in", pathname, "as", basename
+                fname, arcname = self._get_codename(initname[0:-3], basename)
+                if self.debug:
+                    print "Adding", arcname
+                self.write(fname, arcname)
+                dirlist = os.listdir(pathname)
+                dirlist.remove("__init__.py")
+                # Add all *.py files and package subdirectories
+                for filename in dirlist:
+                    path = os.path.join(pathname, filename)
+                    root, ext = os.path.splitext(filename)
+                    if os.path.isdir(path):
+                        if os.path.isfile(os.path.join(path, "__init__.py")):
+                            # This is a package directory, add it
+                            self.writepy(path, basename)  # Recursive call
+                    elif ext == ".py":
+                        fname, arcname = self._get_codename(path[0:-3],
+                                         basename)
+                        if self.debug:
+                            print "Adding", arcname
+                        self.write(fname, arcname)
+            else:
+                # This is NOT a package directory, add its files at top level
+                if self.debug:
+                    print "Adding files from directory", pathname
+                for filename in os.listdir(pathname):
+                    path = os.path.join(pathname, filename)
+                    root, ext = os.path.splitext(filename)
+                    if ext == ".py":
+                        fname, arcname = self._get_codename(path[0:-3],
+                                         basename)
+                        if self.debug:
+                            print "Adding", arcname
+                        self.write(fname, arcname)
+        else:
+            if pathname[-3:] != ".py":
+                raise RuntimeError, \
+                      'Files added with writepy() must end with ".py"'
+            fname, arcname = self._get_codename(pathname[0:-3], basename)
+            if self.debug:
+                print "Adding file", arcname
+            self.write(fname, arcname)
+
+    def _get_codename(self, pathname, basename):
+        """Return (filename, archivename) for the path.
+
+        Given a module name path, return the correct file path and
+        archive name, compiling if necessary.  For example, given
+        /python/lib/string, return (/python/lib/string.pyc, string).
+        """
+        file_py  = pathname + ".py"
+        file_pyc = pathname + ".pyc"
+        file_pyo = pathname + ".pyo"
+        if os.path.isfile(file_pyo) and \
+                            os.stat(file_pyo).st_mtime >= os.stat(file_py).st_mtime:
+            fname = file_pyo    # Use .pyo file
+        elif not os.path.isfile(file_pyc) or \
+             os.stat(file_pyc).st_mtime < os.stat(file_py).st_mtime:
+            import py_compile
+            if self.debug:
+                print "Compiling", file_py
+            try:
+                py_compile.compile(file_py, file_pyc, None, True)
+            except py_compile.PyCompileError,err:
+                print err.msg
+            fname = file_pyc
+        else:
+            fname = file_pyc
+        archivename = os.path.split(fname)[1]
+        if basename:
+            archivename = "%s/%s" % (basename, archivename)
+        return (fname, archivename)
+
+
+def main(args = None):
+    import textwrap
+    USAGE=textwrap.dedent("""\
+        Usage:
+            zipfile.py -l zipfile.zip        # Show listing of a zipfile
+            zipfile.py -t zipfile.zip        # Test if a zipfile is valid
+            zipfile.py -e zipfile.zip target # Extract zipfile into target dir
+            zipfile.py -c zipfile.zip src ... # Create zipfile from sources
+        """)
+    if args is None:
+        args = sys.argv[1:]
+
+    if not args or args[0] not in ('-l', '-c', '-e', '-t'):
+        print USAGE
+        sys.exit(1)
+
+    if args[0] == '-l':
+        if len(args) != 2:
+            print USAGE
+            sys.exit(1)
+        with ZipFile(args[1], 'r') as zf:
+            zf.printdir()
+
+    elif args[0] == '-t':
+        if len(args) != 2:
+            print USAGE
+            sys.exit(1)
+        with ZipFile(args[1], 'r') as zf:
+            badfile = zf.testzip()
+        if badfile:
+            print("The following enclosed file is corrupted: {!r}".format(badfile))
+        print "Done testing"
+
+    elif args[0] == '-e':
+        if len(args) != 3:
+            print USAGE
+            sys.exit(1)
+
+        with ZipFile(args[1], 'r') as zf:
+            zf.extractall(args[2])
+
+    elif args[0] == '-c':
+        if len(args) < 3:
+            print USAGE
+            sys.exit(1)
+
+        def addToZip(zf, path, zippath):
+            if os.path.isfile(path):
+                zf.write(path, zippath, ZIP_DEFLATED)
+            elif os.path.isdir(path):
+                if zippath:
+                    zf.write(path, zippath)
+                for nm in os.listdir(path):
+                    addToZip(zf,
+                            os.path.join(path, nm), os.path.join(zippath, nm))
+            # else: ignore
+
+        with ZipFile(args[1], 'w', allowZip64=True) as zf:
+            for path in args[2:]:
+                zippath = os.path.basename(path)
+                if not zippath:
+                    zippath = os.path.basename(os.path.dirname(path))
+                if zippath in ('', os.curdir, os.pardir):
+                    zippath = ''
+                addToZip(zf, path, zippath)
+
+if __name__ == "__main__":
+    main()
diff --git a/catapult/tracing/tracing/__init__.py b/catapult/tracing/tracing/__init__.py
new file mode 100644
index 0000000..76063aa
--- /dev/null
+++ b/catapult/tracing/tracing/__init__.py
@@ -0,0 +1,6 @@
+# Copyright (c) 2016 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import tracing_project
+tracing_project.UpdateSysPathIfNeeded()
diff --git a/catapult/tracing/tracing/trace_data/__init__.py b/catapult/tracing/tracing/trace_data/__init__.py
new file mode 100644
index 0000000..bdb1f26
--- /dev/null
+++ b/catapult/tracing/tracing/trace_data/__init__.py
@@ -0,0 +1,4 @@
+# Copyright 2017 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
diff --git a/catapult/tracing/tracing/trace_data/trace_data.py b/catapult/tracing/tracing/trace_data/trace_data.py
new file mode 100644
index 0000000..e6a62ff
--- /dev/null
+++ b/catapult/tracing/tracing/trace_data/trace_data.py
@@ -0,0 +1,339 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import copy
+import json
+import logging
+import os
+import shutil
+import subprocess
+import tempfile
+
+
+_TRACING_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),
+                            os.path.pardir, os.path.pardir)
+_TRACE2HTML_PATH = os.path.join(_TRACING_DIR, 'bin', 'trace2html')
+
+
+class NonSerializableTraceData(Exception):
+  """Raised when raw trace data cannot be serialized to TraceData."""
+  pass
+
+
+class TraceDataPart(object):
+  """TraceData can have a variety of events.
+
+  These are called "parts" and are accessed by the following fixed field names.
+  """
+  def __init__(self, raw_field_name):
+    self._raw_field_name = raw_field_name
+
+  def __repr__(self):
+    return 'TraceDataPart("%s")' % self._raw_field_name
+
+  @property
+  def raw_field_name(self):
+    return self._raw_field_name
+
+  def __eq__(self, other):
+    return self.raw_field_name == other.raw_field_name
+
+  def __hash__(self):
+    return hash(self.raw_field_name)
+
+
+ANDROID_PROCESS_DATA_PART = TraceDataPart('androidProcessDump')
+ATRACE_PART = TraceDataPart('systemTraceEvents')
+BATTOR_TRACE_PART = TraceDataPart('powerTraceAsString')
+CHROME_TRACE_PART = TraceDataPart('traceEvents')
+CPU_TRACE_DATA = TraceDataPart('cpuSnapshots')
+INSPECTOR_TRACE_PART = TraceDataPart('inspectorTimelineEvents')
+SURFACE_FLINGER_PART = TraceDataPart('surfaceFlinger')
+TAB_ID_PART = TraceDataPart('tabIds')
+TELEMETRY_PART = TraceDataPart('telemetry')
+WALT_TRACE_PART = TraceDataPart('waltTraceEvents')
+
+ALL_TRACE_PARTS = {ANDROID_PROCESS_DATA_PART,
+                   ATRACE_PART,
+                   BATTOR_TRACE_PART,
+                   CHROME_TRACE_PART,
+                   CPU_TRACE_DATA,
+                   INSPECTOR_TRACE_PART,
+                   SURFACE_FLINGER_PART,
+                   TAB_ID_PART,
+                   TELEMETRY_PART}
+
+ALL_TRACE_PARTS_RAW_NAMES = set(k.raw_field_name for k in ALL_TRACE_PARTS)
+
+def _HasTraceFor(part, raw):
+  assert isinstance(part, TraceDataPart)
+  if part.raw_field_name not in raw:
+    return False
+  return len(raw[part.raw_field_name]) > 0
+
+
+def _GetFilePathForTrace(trace, dir_path):
+  """ Return path to a file that contains |trace|.
+
+  Note: if |trace| is an instance of TraceFileHandle, this reuses the trace path
+  that the trace file handle holds. Otherwise, it creates a new trace file
+  in |dir_path| directory.
+  """
+  if isinstance(trace, TraceFileHandle):
+    return trace.file_path
+  with tempfile.NamedTemporaryFile(mode='w', dir=dir_path, delete=False) as fp:
+    if isinstance(trace, basestring):
+      fp.write(trace)
+    elif isinstance(trace, dict) or isinstance(trace, list):
+      json.dump(trace, fp)
+    else:
+      raise TypeError('Trace is of unknown type.')
+    return fp.name
+
+
+class TraceData(object):
+  """ TraceData holds a collection of traces from multiple sources.
+
+  A TraceData can have multiple active parts. Each part represents traces
+  collected from a different trace agent.
+  """
+  def __init__(self):
+    """Creates TraceData from the given data."""
+    self._raw_data = {}
+    self._events_are_safely_mutable = False
+
+  def _SetFromBuilder(self, d):
+    self._raw_data = d
+    self._events_are_safely_mutable = True
+
+  @property
+  def events_are_safely_mutable(self):
+    """Returns true if the events in this value are completely sealed.
+
+    Some importers want to take complex fields out of the TraceData and add
+    them to the model, changing them subtly as they do so. If the TraceData
+    was constructed with data that is shared with something outside the trace
+    data, for instance a test harness, then this mutation is unexpected. But,
+    if the values are sealed, then mutating the events is a lot faster.
+
+    We know if events are sealed if the value came from a string, or if the
+    value came from a TraceDataBuilder.
+    """
+    return self._events_are_safely_mutable
+
+  @property
+  def active_parts(self):
+    return {p for p in ALL_TRACE_PARTS if p.raw_field_name in self._raw_data}
+
+  def HasTracesFor(self, part):
+    return _HasTraceFor(part, self._raw_data)
+
+  def GetTracesFor(self, part):
+    """ Return the list of traces for |part| in string or dictionary forms.
+
+    Note: since this API return the traces that can be directly accessed in
+    memory, it may require lots of memory usage as some of the trace can be
+    very big.
+    For references, we have cases where Telemetry is OOM'ed because the memory
+    required for processing the trace in Python is too big (crbug.com/672097).
+    """
+    assert isinstance(part, TraceDataPart)
+    if not self.HasTracesFor(part):
+      return []
+    traces_list = self._raw_data[part.raw_field_name]
+    # Since this API return the traces in memory form, and since the memory
+    # bottleneck of Telemetry is for keeping trace in memory, there is no uses
+    # in keeping the on-disk form of tracing beyond this point. Hence we convert
+    # all traces for part of form TraceFileHandle to the JSON form.
+    for i, data in enumerate(traces_list):
+      if isinstance(data, TraceFileHandle):
+        traces_list[i] = data.AsTraceData()
+    return traces_list
+
+  def GetTraceFor(self, part):
+    assert isinstance(part, TraceDataPart)
+    traces = self.GetTracesFor(part)
+    assert len(traces) == 1
+    return traces[0]
+
+  def CleanUpAllTraces(self):
+    """ Remove all the traces that this has handles to.
+
+    Those include traces stored in memory & on disk. After invoking this,
+    one can no longer uses this object for collecting the traces.
+    """
+    for traces_list in self._raw_data.itervalues():
+      for trace in traces_list:
+        if isinstance(trace, TraceFileHandle):
+          trace.Clean()
+    self._raw_data = {}
+
+  def Serialize(self, file_path, trace_title=''):
+    """Serializes the trace result to |file_path|.
+
+    """
+    if not self._raw_data:
+      logging.warning('No traces to convert to html.')
+      return
+    temp_dir = tempfile.mkdtemp()
+    trace_files = []
+    try:
+      trace_size_data = {}
+      for part, traces_list in self._raw_data.iteritems():
+        for trace in traces_list:
+          path = _GetFilePathForTrace(trace, temp_dir)
+          trace_size_data.setdefault(part, 0)
+          trace_size_data[part] += os.path.getsize(path)
+          trace_files.append(path)
+      logging.info('Trace sizes in bytes: %s', trace_size_data)
+
+      cmd = (['python', _TRACE2HTML_PATH] + trace_files +
+             ['--output', file_path] + ['--title', trace_title])
+      subprocess.check_output(cmd)
+    finally:
+      shutil.rmtree(temp_dir)
+
+
+class TraceFileHandle(object):
+  """A trace file handle object allows storing trace data on disk.
+
+  TraceFileHandle API allows one to collect traces from Chrome into disk instead
+  of keeping them in memory. This is important for keeping memory usage of
+  Telemetry low to avoid OOM (see:
+  https://github.com/catapult-project/catapult/issues/3119).
+
+  The fact that this uses a file underneath to store tracing data means the
+  callsite is repsonsible for discarding the file when they no longer need the
+  tracing data. Call TraceFileHandle.Clean when you done using this object.
+  """
+  def __init__(self):
+    self._backing_file = None
+    self._file_path = None
+    self._trace_data = None
+
+  def Open(self):
+    assert not self._backing_file and not self._file_path
+    self._backing_file = tempfile.NamedTemporaryFile(delete=False, mode='a')
+
+  def AppendTraceData(self, partial_trace_data):
+    assert isinstance(partial_trace_data, basestring)
+    self._backing_file.write(partial_trace_data)
+
+  @property
+  def file_path(self):
+    assert self._file_path, (
+        'Either the handle need to be closed first or this handle is cleaned')
+    return self._file_path
+
+  def Close(self):
+    assert self._backing_file
+    self._backing_file.close()
+    self._file_path = self._backing_file.name
+    self._backing_file = None
+
+  def AsTraceData(self):
+    """Get the object form of trace data that this handle manages.
+
+    *Warning: this can have large memory footprint if the trace data is big.
+
+    Since this requires the in-memory form of the trace, it is no longer useful
+    to still keep the backing file underneath, invoking this will also discard
+    the file to avoid the risk of leaking the backing trace file.
+    """
+    if self._trace_data:
+      return self._trace_data
+    assert self._file_path
+    with open(self._file_path) as f:
+      self._trace_data = json.load(f)
+    self.Clean()
+    return self._trace_data
+
+  def Clean(self):
+    """Remove the backing file used for storing trace on disk.
+
+    This should be called when and only when you no longer need to use
+    TraceFileHandle.
+    """
+    assert self._file_path
+    os.remove(self._file_path)
+    self._file_path = None
+
+
+class TraceDataBuilder(object):
+  """TraceDataBuilder helps build up a trace from multiple trace agents.
+
+  TraceData is supposed to be immutable, but it is useful during recording to
+  have a mutable version. That is TraceDataBuilder.
+  """
+  def __init__(self):
+    self._raw_data = {}
+
+  def AsData(self):
+    if self._raw_data == None:
+      raise Exception('Can only AsData once')
+    data = TraceData()
+    data._SetFromBuilder(self._raw_data)
+    self._raw_data = None
+    return data
+
+  def AddTraceFor(self, part, trace):
+    assert isinstance(part, TraceDataPart), part
+    if part == CHROME_TRACE_PART:
+      assert (isinstance(trace, dict) or
+              isinstance(trace, list) or
+              isinstance(trace, TraceFileHandle))
+    else:
+      assert (isinstance(trace, basestring) or
+              isinstance(trace, dict) or
+              isinstance(trace, list))
+
+    if self._raw_data == None:
+      raise Exception('Already called AsData() on this builder.')
+
+    self._raw_data.setdefault(part.raw_field_name, [])
+    self._raw_data[part.raw_field_name].append(trace)
+
+  def HasTracesFor(self, part):
+    return _HasTraceFor(part, self._raw_data)
+
+
+def CreateTraceDataFromRawData(raw_data):
+  """Convenient method for creating a TraceData object from |raw_data|.
+     This is mostly used for testing.
+
+     Args:
+        raw_data can be:
+            + A dictionary that repsents multiple trace parts. Keys of the
+            dictionary must always contain 'traceEvents', as chrome trace
+            must always present.
+            + A list that represents Chrome trace events.
+            + JSON string of either above.
+
+  """
+  raw_data = copy.deepcopy(raw_data)
+  if isinstance(raw_data, basestring):
+    json_data = json.loads(raw_data)
+  else:
+    json_data = raw_data
+
+  b = TraceDataBuilder()
+  if not json_data:
+    return b.AsData()
+  if isinstance(json_data, dict):
+    assert 'traceEvents' in json_data, 'Only raw chrome trace is supported'
+    trace_parts_keys = []
+    for k in json_data:
+      if k != 'traceEvents' and k in ALL_TRACE_PARTS_RAW_NAMES:
+        trace_parts_keys.append(k)
+        b.AddTraceFor(TraceDataPart(k), json_data[k])
+    # Delete the data for extra keys to form trace data for Chrome part only.
+    for k in trace_parts_keys:
+      del json_data[k]
+    b.AddTraceFor(CHROME_TRACE_PART, json_data)
+  elif isinstance(json_data, list):
+    b.AddTraceFor(CHROME_TRACE_PART, {'traceEvents': json_data})
+  else:
+    raise NonSerializableTraceData('Unrecognized data format.')
+  return b.AsData()
+
diff --git a/catapult/tracing/tracing/trace_data/trace_data_unittest.py b/catapult/tracing/tracing/trace_data/trace_data_unittest.py
new file mode 100644
index 0000000..b065b4f
--- /dev/null
+++ b/catapult/tracing/tracing/trace_data/trace_data_unittest.py
@@ -0,0 +1,103 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import datetime
+import exceptions
+import os
+import shutil
+import tempfile
+import unittest
+
+from tracing.trace_data import trace_data
+from tracing_build import html2trace
+
+
+class TraceDataTest(unittest.TestCase):
+  def testSerialize(self):
+    test_dir = tempfile.mkdtemp()
+    trace_path = os.path.join(test_dir, 'test_trace.json')
+    try:
+      ri = trace_data.CreateTraceDataFromRawData({'traceEvents': [1, 2, 3]})
+      ri.Serialize(trace_path)
+      with open(trace_path) as f:
+        json_traces = html2trace.ReadTracesFromHTMLFilePath(f)
+      self.assertEqual(json_traces, [{'traceEvents': [1, 2, 3]}])
+    finally:
+      shutil.rmtree(test_dir)
+
+  def testEmptyArrayValue(self):
+    # We can import empty lists and empty string.
+    d = trace_data.CreateTraceDataFromRawData([])
+    self.assertFalse(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
+
+  def testInvalidTrace(self):
+    with self.assertRaises(AssertionError):
+      trace_data.CreateTraceDataFromRawData({'hello': 1})
+
+  def testListForm(self):
+    d = trace_data.CreateTraceDataFromRawData([{'ph': 'B'}])
+    self.assertTrue(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
+    events = d.GetTracesFor(trace_data.CHROME_TRACE_PART)[0].get(
+        'traceEvents', [])
+    self.assertEquals(1, len(events))
+
+  def testStringForm(self):
+    d = trace_data.CreateTraceDataFromRawData('[{"ph": "B"}]')
+    self.assertTrue(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
+    events = d.GetTracesFor(trace_data.CHROME_TRACE_PART)[0].get(
+        'traceEvents', [])
+    self.assertEquals(1, len(events))
+
+
+class TraceDataBuilderTest(unittest.TestCase):
+  def testBasicChrome(self):
+    builder = trace_data.TraceDataBuilder()
+    builder.AddTraceFor(trace_data.CHROME_TRACE_PART,
+                        {'traceEvents': [1, 2, 3]})
+    builder.AddTraceFor(trace_data.TAB_ID_PART, ['tab-7'])
+    builder.AddTraceFor(trace_data.BATTOR_TRACE_PART, 'battor data here')
+
+    d = builder.AsData()
+    self.assertTrue(d.HasTracesFor(trace_data.CHROME_TRACE_PART))
+    self.assertTrue(d.HasTracesFor(trace_data.TAB_ID_PART))
+    self.assertTrue(d.HasTracesFor(trace_data.BATTOR_TRACE_PART))
+
+    self.assertRaises(Exception, builder.AsData)
+
+  def testSetTraceFor(self):
+    telemetry_trace = {
+        'traceEvents': [1, 2, 3],
+        'metadata': {
+            'field1': 'value1'
+        }
+    }
+
+    builder = trace_data.TraceDataBuilder()
+    builder.AddTraceFor(trace_data.TELEMETRY_PART, telemetry_trace)
+    d = builder.AsData()
+
+    self.assertEqual(d.GetTracesFor(trace_data.TELEMETRY_PART),
+                     [telemetry_trace])
+
+  def testSetTraceForRaisesWithInvalidPart(self):
+    builder = trace_data.TraceDataBuilder()
+
+    self.assertRaises(exceptions.AssertionError,
+                      lambda: builder.AddTraceFor('not_a_trace_part', {}))
+
+  def testSetTraceForRaisesWithInvalidTrace(self):
+    builder = trace_data.TraceDataBuilder()
+
+    self.assertRaises(
+        exceptions.AssertionError,
+        lambda: builder.AddTraceFor(trace_data.TELEMETRY_PART,
+                                    datetime.time.min))
+
+  def testSetTraceForRaisesAfterAsData(self):
+    builder = trace_data.TraceDataBuilder()
+    builder.AsData()
+
+    self.assertRaises(
+        exceptions.Exception,
+        lambda: builder.AddTraceFor(trace_data.TELEMETRY_PART, {}))
diff --git a/catapult/tracing/tracing_project.py b/catapult/tracing/tracing_project.py
new file mode 100644
index 0000000..3bdcb4e
--- /dev/null
+++ b/catapult/tracing/tracing_project.py
@@ -0,0 +1,196 @@
+# Copyright (c) 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import sys
+import os
+import re
+
+
+def _AddToPathIfNeeded(path):
+  if path not in sys.path:
+    sys.path.insert(0, path)
+
+
+def UpdateSysPathIfNeeded():
+  p = TracingProject()
+  _AddToPathIfNeeded(p.catapult_path)
+  _AddToPathIfNeeded(p.py_vulcanize_path)
+  _AddToPathIfNeeded(p.vinn_path)
+
+  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'WebOb'))
+  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'Paste'))
+  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'six'))
+  _AddToPathIfNeeded(os.path.join(p.catapult_third_party_path, 'webapp2'))
+
+
+def _FindAllFilesRecursive(source_paths):
+  assert isinstance(source_paths, list)
+  all_filenames = set()
+  for source_path in source_paths:
+    for dirpath, _, filenames in os.walk(source_path):
+      for f in filenames:
+        if f.startswith('.'):
+          continue
+        x = os.path.abspath(os.path.join(dirpath, f))
+        all_filenames.add(x)
+  return all_filenames
+
+def _IsFilenameATest(x):
+  if x.endswith('_test.js'):
+    return True
+
+  if x.endswith('_test.html'):
+    return True
+
+  if x.endswith('_unittest.js'):
+    return True
+
+  if x.endswith('_unittest.html'):
+    return True
+
+  # TODO(nduca): Add content test?
+  return False
+
+
+class TracingProject(object):
+  catapult_path = os.path.abspath(
+      os.path.join(os.path.dirname(__file__), os.path.pardir))
+
+  tracing_root_path = os.path.join(catapult_path, 'tracing')
+  trace_processor_root_path = os.path.join(catapult_path, 'trace_processor')
+  tracing_src_path = os.path.join(tracing_root_path, 'tracing')
+  extras_path = os.path.join(tracing_src_path, 'extras')
+  ui_extras_path = os.path.join(tracing_src_path, 'ui', 'extras')
+
+  catapult_third_party_path = os.path.join(catapult_path, 'third_party')
+  polymer_path = os.path.join(catapult_third_party_path, 'polymer')
+
+  tracing_third_party_path = os.path.join(tracing_root_path, 'third_party')
+  py_vulcanize_path = os.path.join(catapult_third_party_path, 'py_vulcanize')
+  vinn_path = os.path.join(catapult_third_party_path, 'vinn')
+
+  jszip_path = os.path.join(tracing_third_party_path, 'jszip')
+
+  glmatrix_path = os.path.join(
+      tracing_third_party_path, 'gl-matrix', 'dist')
+
+  mannwhitneyu_path = os.path.join(
+      tracing_third_party_path, 'mannwhitneyu')
+
+  ui_path = os.path.join(tracing_src_path, 'ui')
+  d3_path = os.path.join(tracing_third_party_path, 'd3')
+  chai_path = os.path.join(tracing_third_party_path, 'chai')
+  mocha_path = os.path.join(tracing_third_party_path, 'mocha')
+  oboe_path = os.path.join(tracing_third_party_path, 'oboe')
+
+  mre_path = os.path.join(tracing_src_path, 'mre')
+
+  metrics_path = os.path.join(tracing_src_path, 'metrics')
+  diagnostics_path = os.path.join(tracing_src_path, 'value', 'diagnostics')
+
+  value_ui_path = os.path.join(tracing_src_path, 'value', 'ui')
+  metrics_ui_path = os.path.join(tracing_src_path, 'metrics', 'ui')
+
+  test_data_path = os.path.join(tracing_root_path, 'test_data')
+  skp_data_path = os.path.join(tracing_root_path, 'skp_data')
+
+  rjsmin_path = os.path.join(
+      tracing_third_party_path, 'tvcm', 'third_party', 'rjsmin')
+  rcssmin_path = os.path.join(
+      tracing_third_party_path, 'tvcm', 'third_party', 'rcssmin')
+
+  def __init__(self):
+    self.source_paths = []
+    self.source_paths.append(self.tracing_root_path)
+    self.source_paths.append(self.polymer_path)
+    self.source_paths.append(self.tracing_third_party_path)
+    self.source_paths.append(self.mre_path)
+    self.source_paths.append(self.jszip_path)
+    self.source_paths.append(self.glmatrix_path)
+    self.source_paths.append(self.mannwhitneyu_path)
+    self.source_paths.append(self.d3_path)
+    self.source_paths.append(self.chai_path)
+    self.source_paths.append(self.mocha_path)
+    self.source_paths.append(self.oboe_path)
+
+  def CreateVulcanizer(self):
+    from py_vulcanize import project as project_module
+    return project_module.Project(self.source_paths)
+
+  def IsD8CompatibleFile(self, filename):
+    if filename.startswith(self.ui_path):
+      return False
+
+    if filename.startswith(self.value_ui_path):
+      return False
+
+    if filename.startswith(self.metrics_ui_path):
+      return False
+
+    return True
+
+  def FindAllTestModuleRelPaths(self, pred=None):
+    if pred is None:
+      pred = lambda x: True
+
+    all_filenames = _FindAllFilesRecursive([self.tracing_src_path])
+    test_module_filenames = [x for x in all_filenames if
+                             _IsFilenameATest(x) and pred(x)]
+    test_module_filenames.sort()
+
+    return [os.path.relpath(x, self.tracing_root_path)
+            for x in test_module_filenames]
+
+  def FindAllMetricsModuleRelPaths(self):
+    all_filenames = _FindAllFilesRecursive([self.tracing_src_path])
+    all_metrics_module_filenames = []
+    for x in all_filenames:
+      if x.startswith(self.metrics_path) and not _IsFilenameATest(x):
+        all_metrics_module_filenames.append(x)
+    all_metrics_module_filenames.sort()
+    return [os.path.relpath(x, self.tracing_root_path)
+            for x in all_metrics_module_filenames]
+
+  def FindAllDiagnosticsModuleRelPaths(self):
+    all_filenames = _FindAllFilesRecursive([self.tracing_src_path])
+    all_diagnostics_module_filenames = []
+    for x in all_filenames:
+      if x.startswith(self.diagnostics_path) and not _IsFilenameATest(x):
+        all_diagnostics_module_filenames.append(x)
+    all_diagnostics_module_filenames.sort()
+    return [os.path.relpath(x, self.tracing_root_path)
+            for x in all_diagnostics_module_filenames]
+
+  def FindAllD8TestModuleRelPaths(self):
+    return self.FindAllTestModuleRelPaths(pred=self.IsD8CompatibleFile)
+
+  def GetConfigNames(self):
+    config_files = [
+        os.path.join(self.ui_extras_path, x)
+        for x in os.listdir(self.ui_extras_path)
+        if x.endswith('_config.html')
+    ]
+
+    config_files = [x for x in config_files if os.path.isfile(x)]
+
+    config_basenames = [os.path.basename(x) for x in config_files]
+    config_names = [re.match('(.+)_config.html$', x).group(1)
+                    for x in config_basenames]
+    return config_names
+
+  def GetDefaultConfigName(self):
+    assert 'full' in self.GetConfigNames()
+    return 'full'
+
+  def AddConfigNameOptionToParser(self, parser):
+    choices = self.GetConfigNames()
+    parser.add_argument(
+        '--config', dest='config_name',
+        choices=choices, default=self.GetDefaultConfigName(),
+        help='Picks a browser config. Valid choices: %s' % ', '.join(choices))
+    return choices
+
+  def GetModuleNameForConfigName(self, config_name):
+    return 'tracing.ui.extras.%s_config' % config_name
+
diff --git a/update.py b/update.py
index 36def2c..e54ffbe 100755
--- a/update.py
+++ b/update.py
@@ -1,9 +1,26 @@
 #!/usr/bin/env python
 
-import codecs, httplib, json, optparse, os, urllib, shutil, subprocess, sys
+import optparse
+import os
+import shutil
+import subprocess
+import sys
 
 upstream_git = 'https://github.com/catapult-project/catapult.git'
-PACKAGE_DIRS = ['common', 'dependency_manager', 'devil', 'systrace', 'third_party/pyserial']
+PACKAGE_DIRS = [
+    'common',
+    'dependency_manager',
+    'devil',
+    'systrace',
+    'third_party/pyserial',
+    'third_party/zipfile',
+    'tracing/tracing/trace_data',
+]
+PACKAGE_FILES = [
+    'tracing/tracing/__init__.py',
+    'tracing/tracing_project.py',
+]
+IGNORE_PATTERNS = ['OWNERS'] # doesn't make sense to sync owners files
 
 script_dir = os.path.dirname(os.path.abspath(sys.argv[0]))
 catapult_src_dir = os.path.join(script_dir, 'catapult-upstream')
@@ -16,7 +33,7 @@
                   help='skip minification')
 options, args = parser.parse_args()
 
-# Update the source if needed.
+## Update the source if needed.
 if options.local_dir is None:
   # Remove the old source tree.
   shutil.rmtree(catapult_src_dir, True)
@@ -50,14 +67,28 @@
   catapult_src_dir = options.local_dir
 
 
-# Update systrace_trace_viewer.html
+## Update systrace_trace_viewer.html
 systrace_dir = os.path.join(catapult_src_dir, 'systrace', 'systrace')
 sys.path.append(systrace_dir)
 import update_systrace_trace_viewer
 update_systrace_trace_viewer.update(no_auto_update=True, no_min=options.no_min)
 
-# Package the result
+## Package the result
 shutil.rmtree(catapult_dst_dir)
+
 for d in PACKAGE_DIRS:
-  shutil.copytree(os.path.join(catapult_src_dir, d),
-    os.path.join(catapult_dst_dir, d))
+  src = os.path.join(catapult_src_dir, d)
+  dst = os.path.join(catapult_dst_dir, d)
+
+  # make parent dir by creating dst + ancestors, and deleting dst
+  if not os.path.isdir(dst):
+    os.makedirs(dst)
+  shutil.rmtree(dst)
+
+  # copy tree
+  shutil.copytree(src, dst, ignore=shutil.ignore_patterns(*IGNORE_PATTERNS))
+
+for f in PACKAGE_FILES:
+  src = os.path.join(catapult_src_dir, f)
+  dst = os.path.join(catapult_dst_dir, f)
+  shutil.copy(src, dst)